// Package user 定义 user-service 的用户主数据、展示短号和临时靓号领域模型。 package user import "regexp" // Status 是用户主状态,业务服务只应该依赖这里的稳定语义。 type Status string const ( // StatusActive 表示用户可以正常登录和参与业务。 StatusActive Status = "active" // StatusDisabled 表示用户被平台禁用。 StatusDisabled Status = "disabled" // StatusBanned 表示用户被封禁。 StatusBanned Status = "banned" ) // DisplayUserIDStatus 表达短号历史记录状态。 type DisplayUserIDStatus string const ( // DisplayUserIDStatusActive 表示当前可被普通业务解析的短号归属。 DisplayUserIDStatusActive DisplayUserIDStatus = "active" // DisplayUserIDStatusHeld 表示默认短号仍归用户所有,但被临时靓号覆盖。 DisplayUserIDStatusHeld DisplayUserIDStatus = "held" // DisplayUserIDStatusExpired 表示临时靓号租约已经到期。 DisplayUserIDStatusExpired DisplayUserIDStatus = "expired" // DisplayUserIDStatusReleased 表示短号曾经属于用户,但已经释放。 DisplayUserIDStatusReleased DisplayUserIDStatus = "released" // DisplayUserIDStatusReserved 表示短号被系统预留,不能被普通用户占用。 DisplayUserIDStatusReserved DisplayUserIDStatus = "reserved" // DisplayUserIDStatusBlocked 表示短号被运营阻断,不能分配。 DisplayUserIDStatusBlocked DisplayUserIDStatus = "blocked" ) // DisplayUserIDKind 表达当前展示号来源。 type DisplayUserIDKind string const ( // DisplayUserIDKindDefault 表示当前展示号来自用户永久默认短号。 DisplayUserIDKindDefault DisplayUserIDKind = "default" // DisplayUserIDKindPretty 表示当前展示号来自有效临时靓号租约。 DisplayUserIDKindPretty DisplayUserIDKind = "pretty" ) // PrettyLeaseStatus 表达临时靓号租约生命周期。 type PrettyLeaseStatus string const ( // PrettyLeaseStatusActive 表示租约当前覆盖用户展示号。 PrettyLeaseStatusActive PrettyLeaseStatus = "active" // PrettyLeaseStatusExpired 表示租约已按到期流程恢复默认短号。 PrettyLeaseStatusExpired PrettyLeaseStatus = "expired" // PrettyLeaseStatusCancelled 表示租约被业务主动取消。 PrettyLeaseStatusCancelled PrettyLeaseStatus = "cancelled" // PrettyLeaseStatusRefunded 表示租约被退款终止。 PrettyLeaseStatusRefunded PrettyLeaseStatus = "refunded" ) // displayUserIDPattern 限制短号为 6 到 11 位非 0 开头数字。 var displayUserIDPattern = regexp.MustCompile(`^[1-9][0-9]{5,10}$`) // User 是 user-service 的主数据实体。 // 首版只保留全局身份和状态,不包含资料、关系链或房间内临时态。 type User struct { // UserID 是系统内部不可变用户 ID。 UserID int64 // DefaultDisplayUserID 是用户永久默认短号。 DefaultDisplayUserID string // CurrentDisplayUserID 是当前对外展示短号,可能被有效靓号覆盖。 CurrentDisplayUserID string // CurrentDisplayUserIDKind 表示当前展示号来源。 CurrentDisplayUserIDKind DisplayUserIDKind // CurrentDisplayUserIDExpiresAtMs 是当前靓号过期时间,默认短号为 0。 CurrentDisplayUserIDExpiresAtMs int64 // Status 控制登录和业务可用性。 Status Status // CreatedAtMs 是用户创建时间。 CreatedAtMs int64 // UpdatedAtMs 是用户主记录更新时间。 UpdatedAtMs int64 } // Identity 是 user_id 与当前 active display_user_id 的绑定投影。 type Identity struct { // UserID 是短号归属用户。 UserID int64 // DisplayUserID 是当前 active 短号。 DisplayUserID string // DefaultDisplayUserID 是永久默认短号。 DefaultDisplayUserID string // DisplayUserIDKind 表示 DisplayUserID 来源。 DisplayUserIDKind DisplayUserIDKind // DisplayUserIDExpiresAtMs 是 active 靓号过期时间。 DisplayUserIDExpiresAtMs int64 // Status 是短号记录状态。 Status DisplayUserIDStatus } // DisplayUserIDChangeCommand 描述短号变更的事务输入。 type DisplayUserIDChangeCommand struct { // UserID 是要修改默认短号的用户。 UserID int64 // NewDisplayUserID 是新的默认短号。 NewDisplayUserID string // Reason 是审计原因。 Reason string // OperatorUserID 是操作者,用户自助修改时等于 UserID。 OperatorUserID int64 // RequestID 是入口请求 ID,写入变更日志。 RequestID string // ChangedAtMs 是本次变更时间。 ChangedAtMs int64 // CooldownMs 是默认短号修改冷却期。 CooldownMs int64 } // PrettyDisplayUserIDLease 是临时靓号覆盖关系的事实记录。 type PrettyDisplayUserIDLease struct { // LeaseID 是临时靓号租约主键。 LeaseID string // DisplayUserID 是租约覆盖的靓号。 DisplayUserID string // UserID 是租约所属用户。 UserID int64 // Status 是租约生命周期状态。 Status PrettyLeaseStatus // StartsAtMs 是租约开始时间。 StartsAtMs int64 // ExpiresAtMs 是租约过期时间。 ExpiresAtMs int64 // PaymentReceiptID 是外部支付回执。 PaymentReceiptID string // Source 标识租约来源,例如 payment。 Source string // CreatedAtMs 是租约创建时间。 CreatedAtMs int64 // UpdatedAtMs 是租约更新时间。 UpdatedAtMs int64 } // PrettyDisplayUserIDCommand 描述申请临时靓号的事务输入。 type PrettyDisplayUserIDCommand struct { // LeaseID 是本次申请生成的租约 ID。 LeaseID string // UserID 是申请用户。 UserID int64 // PrettyDisplayID 是申请覆盖的靓号。 PrettyDisplayID string // LeaseDurationMs 是租期长度。 LeaseDurationMs int64 // PaymentReceiptID 是已完成支付的账务回执。 PaymentReceiptID string // Source 是申请来源。 Source string // RequestID 是入口请求 ID。 RequestID string // OperatorUserID 是操作者。 OperatorUserID int64 // NowMs 是事务时间。 NowMs int64 } // ExpirePrettyDisplayUserIDCommand 描述靓号过期恢复的事务输入。 type ExpirePrettyDisplayUserIDCommand struct { // UserID 是需要恢复默认短号的用户。 UserID int64 // LeaseID 可选;传入时必须匹配当前 active lease。 LeaseID string // RequestID 是触发过期的请求或任务 ID。 RequestID string // NowMs 是过期事务时间。 NowMs int64 } // CanLogin 判断用户状态是否允许签发新会话。 func (u User) CanLogin() bool { // 只有 active 用户允许签发新 session,disabled/banned 都必须阻断登录。 return u.Status == StatusActive } // DisplayUserIDExpired 判断当前展示号快照是否已经因为靓号到期而失效。 func (u User) DisplayUserIDExpired(nowMs int64) bool { // 只有 pretty 展示号有过期语义,默认短号永不过期。 return u.CurrentDisplayUserIDKind == DisplayUserIDKindPretty && u.CurrentDisplayUserIDExpiresAtMs > 0 && u.CurrentDisplayUserIDExpiresAtMs <= nowMs } // EffectiveIdentity 把用户当前展示号快照转换成对外身份投影。 func (u User) EffectiveIdentity() Identity { // Identity 是对外短号投影,不暴露 users 表内部状态之外的资料字段。 return Identity{ UserID: u.UserID, DisplayUserID: u.CurrentDisplayUserID, DefaultDisplayUserID: u.DefaultDisplayUserID, DisplayUserIDKind: u.CurrentDisplayUserIDKind, DisplayUserIDExpiresAtMs: u.CurrentDisplayUserIDExpiresAtMs, Status: DisplayUserIDStatusActive, } } // NormalizeDisplayUserIDState 补齐老测试数据或迁移窗口中的默认短号字段。 func (u User) NormalizeDisplayUserIDState() User { if u.DefaultDisplayUserID == "" { // 兼容旧测试或迁移窗口中只有 current_display_user_id 的用户。 u.DefaultDisplayUserID = u.CurrentDisplayUserID } if u.CurrentDisplayUserID == "" { // 当前展示号缺失时回退到默认短号,避免返回空短号。 u.CurrentDisplayUserID = u.DefaultDisplayUserID } if u.CurrentDisplayUserIDKind == "" { // 未写 kind 的老数据按默认短号处理。 u.CurrentDisplayUserIDKind = DisplayUserIDKindDefault } if u.CurrentDisplayUserIDKind == DisplayUserIDKindDefault { // 默认短号没有过期时间,清理脏数据中的 expires_at。 u.CurrentDisplayUserIDExpiresAtMs = 0 } return u } // ValidDisplayUserID 校验短号格式。 func ValidDisplayUserID(value string) bool { // 格式校验只判断形态,唯一性和可用性由 repository 事务决定。 return displayUserIDPattern.MatchString(value) }