| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859 |
- // IdentityRepo 登录身份仓储(t_identity,一人多登录方式,(type,identifier,appid) 唯一·v1.2)。
- //
- // 平台级访问(同 user_repo.go 包注释):不继承 scope.BaseRepo,裸 *gorm.DB。
- // 登录主链路的核心查询:按 (type, identifier, appid) 唯一定位 → 取 canonical_user_id → 再查 user。
- // v1.2:唯一键从 (type,identifier) 扩为 (type,identifier,appid)——非微信类型 appid 恒 "",
- // 微信类型 appid 必填(per-appid 唯一,P0-07 M5 实测同 appid 同 openid 重复=0)。
- package repository
- import (
- "context"
- "gorm.io/gorm"
- "yuansiwei/unified-backend/internal/identity/model"
- )
- // IdentityRepo 登录身份仓储。
- type IdentityRepo struct {
- db *gorm.DB
- }
- // NewIdentityRepo 构造登录身份仓储。
- //
- // 入参:db *gorm.DB:数据库句柄(必填)。
- // 出参:*IdentityRepo:就绪仓储。
- func NewIdentityRepo(db *gorm.DB) *IdentityRepo {
- return &IdentityRepo{db: db}
- }
- // GetByTypeIdentifierAppID 按 (type, identifier, appid) 唯一键取登录身份记录(v1.2)。
- //
- // 入参:
- // - ctx context.Context:请求上下文。
- // - typ string:身份类型(model.IdentityType* 之一:phone/email/wechat/username/legacy_academic/legacy_teaching)。
- // - identifier string:归一后的标识值(phone 11 位 / email 小写 / wechat open_id / username 原值)。
- // - appid string:来源 appid(v1.2 进唯一键;非微信类型恒 "",微信类型必填)。
- //
- // 出参:
- // - *model.Identity:身份记录(含 CanonicalUserID,供 Service 再查 user)。
- // - error:
- // - errors.ErrNotFound:该 (type, identifier, appid) 无身份记录(登录"账号不存在"路径之一,防枚举统一文案);
- // - errors.ErrDBError:DB 异常。
- //
- // 归一纪律(调用方责任):
- // - email 必须小写、phone 必须 11 位数字、wechat 必须 open_id 原值——Repository 不做归一,
- // 归一发生在 Service 入参处理(与旧系统数据归一规则一致,见 P0-02 盘点)。
- // - 非微信类型 appid 必须传 ""(对齐 DDL NOT NULL DEFAULT '');微信类型 appid 必须传实际值。
- //
- // 实现说明:用 model(&model.Identity{}) 显式指定实体(GORM 自动映射表名 t_identity,TableName() 已锁定),
- // Where 用 (type, identifier, appid) 三列联合条件 + First 取单条(UNIQUE 键保证最多 1 条,无需 Limit 但 First 自带取一)。
- func (r *IdentityRepo) GetByTypeIdentifierAppID(ctx context.Context, typ, identifier, appid string) (*model.Identity, error) {
- var it model.Identity
- if err := r.db.WithContext(ctx).
- Where("type = ? AND identifier = ? AND appid = ?", typ, identifier, appid).
- First(&it).Error; err != nil {
- return nil, mapGormErr(err)
- }
- return &it, nil
- }
|