2026-04-25 13:21:39 +08:00

174 lines
5.9 KiB
Go

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"
)
var displayUserIDPattern = regexp.MustCompile(`^[1-9][0-9]{5,10}$`)
// User 是 user-service 的主数据实体。
// 首版只保留全局身份和状态,不包含资料、关系链或房间内临时态。
type User struct {
UserID int64
DefaultDisplayUserID string
CurrentDisplayUserID string
CurrentDisplayUserIDKind DisplayUserIDKind
CurrentDisplayUserIDExpiresAtMs int64
Status Status
CreatedAtMs int64
UpdatedAtMs int64
}
// Identity 是 user_id 与当前 active display_user_id 的绑定投影。
type Identity struct {
UserID int64
DisplayUserID string
DefaultDisplayUserID string
DisplayUserIDKind DisplayUserIDKind
DisplayUserIDExpiresAtMs int64
Status DisplayUserIDStatus
}
// DisplayUserIDChangeCommand 描述短号变更的事务输入。
type DisplayUserIDChangeCommand struct {
UserID int64
NewDisplayUserID string
Reason string
OperatorUserID int64
RequestID string
ChangedAtMs int64
CooldownMs int64
}
// PrettyDisplayUserIDLease 是临时靓号覆盖关系的事实记录。
type PrettyDisplayUserIDLease struct {
LeaseID string
DisplayUserID string
UserID int64
Status PrettyLeaseStatus
StartsAtMs int64
ExpiresAtMs int64
PaymentReceiptID string
Source string
CreatedAtMs int64
UpdatedAtMs int64
}
// PrettyDisplayUserIDCommand 描述申请临时靓号的事务输入。
type PrettyDisplayUserIDCommand struct {
LeaseID string
UserID int64
PrettyDisplayID string
LeaseDurationMs int64
PaymentReceiptID string
Source string
RequestID string
OperatorUserID int64
NowMs int64
}
// ExpirePrettyDisplayUserIDCommand 描述靓号过期恢复的事务输入。
type ExpirePrettyDisplayUserIDCommand struct {
UserID int64
LeaseID string
RequestID string
NowMs int64
}
// CanLogin 判断用户状态是否允许签发新会话。
func (u User) CanLogin() bool {
return u.Status == StatusActive
}
// DisplayUserIDExpired 判断当前展示号快照是否已经因为靓号到期而失效。
func (u User) DisplayUserIDExpired(nowMs int64) bool {
return u.CurrentDisplayUserIDKind == DisplayUserIDKindPretty && u.CurrentDisplayUserIDExpiresAtMs > 0 && u.CurrentDisplayUserIDExpiresAtMs <= nowMs
}
// EffectiveIdentity 把用户当前展示号快照转换成对外身份投影。
func (u User) EffectiveIdentity() Identity {
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 == "" {
u.DefaultDisplayUserID = u.CurrentDisplayUserID
}
if u.CurrentDisplayUserID == "" {
u.CurrentDisplayUserID = u.DefaultDisplayUserID
}
if u.CurrentDisplayUserIDKind == "" {
u.CurrentDisplayUserIDKind = DisplayUserIDKindDefault
}
if u.CurrentDisplayUserIDKind == DisplayUserIDKindDefault {
u.CurrentDisplayUserIDExpiresAtMs = 0
}
return u
}
// ValidDisplayUserID 校验短号格式。
func ValidDisplayUserID(value string) bool {
return displayUserIDPattern.MatchString(value)
}