81 lines
3.5 KiB
Go
81 lines
3.5 KiB
Go
package user
|
||
|
||
import (
|
||
"context"
|
||
|
||
"hyapp/pkg/appcode"
|
||
"hyapp/pkg/xerr"
|
||
userdomain "hyapp/services/user-service/internal/domain/user"
|
||
)
|
||
|
||
// GetUserIdentity 按 user_id 查询当前 active 短号。
|
||
func (s *Service) GetUserIdentity(ctx context.Context, userID int64) (userdomain.Identity, error) {
|
||
if userID <= 0 {
|
||
// user_id 是 identity 查询的硬条件。
|
||
return userdomain.Identity{}, xerr.New(xerr.InvalidArgument, "user_id is required")
|
||
}
|
||
if s.identityRepository == nil {
|
||
// 短号相关能力需要 identity repository,不能从 users 主表临时拼。
|
||
return userdomain.Identity{}, xerr.New(xerr.Unavailable, "identity repository is not configured")
|
||
}
|
||
|
||
identity, err := s.identityRepository.GetUserIdentity(ctx, userID)
|
||
if err != nil {
|
||
return userdomain.Identity{}, err
|
||
}
|
||
if identity.DisplayUserIDKind == userdomain.DisplayUserIDKindPretty && identity.DisplayUserIDExpiresAtMs > 0 && identity.DisplayUserIDExpiresAtMs <= s.now().UnixMilli() {
|
||
// identity 查询发现靓号过期时同步恢复默认短号,避免继续返回过期展示号。
|
||
return s.identityRepository.ExpirePrettyDisplayUserID(ctx, userdomain.ExpirePrettyDisplayUserIDCommand{
|
||
AppCode: appcode.FromContext(ctx),
|
||
UserID: userID,
|
||
RequestID: "",
|
||
NowMs: s.now().UnixMilli(),
|
||
})
|
||
}
|
||
|
||
return identity, nil
|
||
}
|
||
|
||
// ResolveDisplayUserID 把短号解析成系统 user_id。
|
||
func (s *Service) ResolveDisplayUserID(ctx context.Context, displayUserID string) (userdomain.Identity, error) {
|
||
if !userdomain.ValidDisplayUserID(displayUserID) {
|
||
// 格式错误和未找到使用不同 reason,便于客户端区分输入问题和占用状态。
|
||
return userdomain.Identity{}, xerr.New(xerr.DisplayUserIDInvalid, "display_user_id format is invalid")
|
||
}
|
||
if s.identityRepository == nil {
|
||
// 解析短号必须走 identity repository,确保靓号过期语义生效。
|
||
return userdomain.Identity{}, xerr.New(xerr.Unavailable, "identity repository is not configured")
|
||
}
|
||
|
||
// repository 会按 nowMs 触发懒过期,过期靓号不继续解析。
|
||
return s.identityRepository.ResolveDisplayUserID(ctx, displayUserID, s.now().UnixMilli())
|
||
}
|
||
|
||
// ChangeDisplayUserID 修改用户默认短号,并由 repository 在事务内维护当前展示快照和审计。
|
||
func (s *Service) ChangeDisplayUserID(ctx context.Context, userID int64, newDisplayUserID string, reason string, operatorUserID int64, requestID string) (userdomain.Identity, error) {
|
||
if userID <= 0 {
|
||
// 修改短号必须绑定明确用户。
|
||
return userdomain.Identity{}, xerr.New(xerr.InvalidArgument, "user_id is required")
|
||
}
|
||
if !userdomain.ValidDisplayUserID(newDisplayUserID) {
|
||
// 不合法短号不会进入 repository 事务。
|
||
return userdomain.Identity{}, xerr.New(xerr.DisplayUserIDInvalid, "display_user_id format is invalid")
|
||
}
|
||
if s.identityRepository == nil {
|
||
// 没有 identity repository 时无法维护旧短号释放和变更日志。
|
||
return userdomain.Identity{}, xerr.New(xerr.Unavailable, "identity repository is not configured")
|
||
}
|
||
|
||
// 冷却期和可用性检查在 repository 事务内完成,避免并发抢占。
|
||
return s.identityRepository.ChangeDisplayUserID(ctx, userdomain.DisplayUserIDChangeCommand{
|
||
AppCode: appcode.FromContext(ctx),
|
||
UserID: userID,
|
||
NewDisplayUserID: newDisplayUserID,
|
||
Reason: reason,
|
||
OperatorUserID: operatorUserID,
|
||
RequestID: requestID,
|
||
ChangedAtMs: s.now().UnixMilli(),
|
||
CooldownMs: s.displayUserIDCooldown.Milliseconds(),
|
||
})
|
||
}
|