package shared import ( "context" "database/sql" "errors" "fmt" "strconv" "strings" ) var ErrInvalidUserIdentityFilter = errors.New("invalid user identity filter") // ResolveExactUserID 把后台输入框里的用户身份解析成 owner service 使用的内部 user_id。 // 查询条件复用统一身份 SQL:精确长 ID、当前展示号、默认短号、active 靓号优先,昵称只做最后的模糊兜底。 func ResolveExactUserID(ctx context.Context, db *sql.DB, appCode string, keyword string, nowMs int64) (int64, bool, error) { keyword = strings.TrimSpace(keyword) if keyword == "" || db == nil { return 0, false, nil } matchSQL, matchArgs := UserIdentityExactSQL("u", "u.user_id", keyword, nowMs) orderSQL, orderArgs := UserIdentityExactOrderSQL("u", "u.user_id", keyword, nowMs) args := append([]any{appCode}, matchArgs...) args = append(args, orderArgs...) row := db.QueryRowContext(ctx, ` SELECT u.user_id FROM users u WHERE u.app_code = ? AND `+matchSQL+` ORDER BY `+orderSQL+`, u.user_id DESC LIMIT 1`, args..., ) var userID int64 if err := row.Scan(&userID); err != nil { if errors.Is(err, sql.ErrNoRows) { return 0, false, nil } return 0, false, err } return userID, true, nil } // ResolveExactUserIDOrNumericFallback 用于列表 owner 在 wallet/activity 等下游服务的场景。 // 下游只认内部 user_id,后台先按短号/靓号解析;解析不到时只接受正整数长 ID,兼容用户资料缺失的历史事实记录。 func ResolveExactUserIDOrNumericFallback(ctx context.Context, db *sql.DB, appCode string, keyword string, nowMs int64) (int64, bool, error) { keyword = strings.TrimSpace(keyword) if keyword == "" { return 0, false, nil } if db != nil { userID, matched, err := ResolveExactUserID(ctx, db, appCode, keyword, nowMs) if err != nil || matched { return userID, matched, err } } userID, err := strconv.ParseInt(keyword, 10, 64) if err != nil || userID <= 0 { return 0, true, fmt.Errorf("%w: %s", ErrInvalidUserIdentityFilter, keyword) } return userID, true, nil }