2026-05-12 09:53:20 +08:00

54 lines
1.9 KiB
Go

package identity
import (
"context"
"database/sql"
"hyapp/pkg/appcode"
"hyapp/pkg/xerr"
userdomain "hyapp/services/user-service/internal/domain/user"
)
func (r *Repository) assertDisplayUserIDAvailable(ctx context.Context, tx *sql.Tx, displayUserID string, userID int64, allowSameOwner bool) error {
// FOR UPDATE 锁住目标短号记录,避免并发抢占同一个 display_user_id。
var existingUserID int64
err := tx.QueryRowContext(ctx, `
SELECT user_id
FROM user_display_user_ids
WHERE app_code = ? AND display_user_id = ? AND status IN (?, ?, ?, ?)
FOR UPDATE
`, appcode.FromContext(ctx), displayUserID, string(userdomain.DisplayUserIDStatusActive), string(userdomain.DisplayUserIDStatusHeld), string(userdomain.DisplayUserIDStatusReserved), string(userdomain.DisplayUserIDStatusBlocked)).Scan(&existingUserID)
if err == sql.ErrNoRows {
// 没有 active/held/reserved/blocked 记录时可用。
return nil
}
if err != nil {
return err
}
if allowSameOwner && existingUserID == userID {
// 默认短号修改允许同用户幂等检查通过。
return nil
}
return xerr.New(xerr.DisplayUserIDExists, "display_user_id already exists")
}
func (r *Repository) assertChangeCooldown(ctx context.Context, tx *sql.Tx, command userdomain.DisplayUserIDChangeCommand) error {
// 冷却期只统计默认短号修改,不统计靓号 apply/expire。
var lastChangedAt sql.Null[int64]
err := tx.QueryRowContext(ctx, `
SELECT MAX(created_at_ms)
FROM display_user_id_change_logs
WHERE app_code = ? AND user_id = ? AND change_type = ?
`, appcode.Normalize(command.AppCode), command.UserID, "default_change").Scan(&lastChangedAt)
if err != nil {
return err
}
if lastChangedAt.Valid && command.ChangedAtMs-lastChangedAt.V < command.CooldownMs {
// 仍在冷却期内时拒绝修改默认短号。
return xerr.New(xerr.DisplayUserIDCooldown, "display_user_id change is cooling down")
}
return nil
}