package shared import ( "fmt" "strings" ) type UserIdentityFilter struct { UserID string DisplayUserID string Username string } func (filter UserIdentityFilter) IsEmpty() bool { return strings.TrimSpace(filter.UserID) == "" && strings.TrimSpace(filter.DisplayUserID) == "" && strings.TrimSpace(filter.Username) == "" } func UserIdentityKeywordSQL(userAlias string, userIDExpr string, keyword string, nowMs int64) (string, []any) { keyword = strings.TrimSpace(keyword) if keyword == "" { return "1 = 1", nil } like := "%" + keyword + "%" // 后台表格里的用户搜索统一覆盖长 user_id、当前展示号、默认短号、昵称和 active 靓号租约。 // 靓号不能只依赖 users.current_display_user_id;历史修复、本地导入或过期恢复可能让 users 快照和租约审计表短暂不一致。 return fmt.Sprintf(`(CAST(%[2]s AS CHAR) LIKE ? OR %[1]s.current_display_user_id LIKE ? OR %[1]s.default_display_user_id LIKE ? OR %[1]s.username LIKE ? OR %[3]s)`, userAlias, userIDExpr, ActivePrettyDisplayIDSQL(userAlias, "LIKE ?")), []any{ like, like, like, like, nowMs, like, } } func UserIdentityFieldsSQL(userAlias string, userIDExpr string, filter UserIdentityFilter, nowMs int64) (string, []any) { clauses := make([]string, 0, 3) args := make([]any, 0, 8) if userID := strings.TrimSpace(filter.UserID); userID != "" { clauses = append(clauses, fmt.Sprintf("CAST(%s AS CHAR) = ?", userIDExpr)) args = append(args, userID) } if displayUserID := strings.TrimSpace(filter.DisplayUserID); displayUserID != "" { displaySQL, displayArgs := UserDisplayIDSQL(userAlias, displayUserID, nowMs) clauses = append(clauses, displaySQL) args = append(args, displayArgs...) } if username := strings.TrimSpace(filter.Username); username != "" { clauses = append(clauses, userAlias+".username LIKE ?") args = append(args, "%"+username+"%") } if len(clauses) == 0 { return "1 = 1", nil } // 字段拆分后每个输入都是一个明确约束;同时输入多个字段时取交集,防止短 ID 和昵称互相扩大结果集。 return "(" + strings.Join(clauses, " AND ") + ")", args } func UserIdentityExactSQL(userAlias string, userIDExpr string, keyword string, nowMs int64) (string, []any) { keyword = strings.TrimSpace(keyword) if keyword == "" { return "1 = 1", nil } like := "%" + keyword + "%" // 单用户解析先做精确 user_id/短号/靓号命中,再允许昵称模糊兜底,避免运营输入靓号时被当成普通昵称查询。 return fmt.Sprintf(`(CAST(%[2]s AS CHAR) = ? OR %[1]s.current_display_user_id = ? OR %[1]s.default_display_user_id = ? OR %[3]s OR %[1]s.username LIKE ?)`, userAlias, userIDExpr, ActivePrettyDisplayIDSQL(userAlias, "= ?")), []any{ keyword, keyword, keyword, nowMs, keyword, like, } } func UserIdentityExactOrderSQL(userAlias string, userIDExpr string, keyword string, nowMs int64) (string, []any) { keyword = strings.TrimSpace(keyword) return fmt.Sprintf(`CASE WHEN CAST(%[2]s AS CHAR) = ? THEN 0 WHEN %[1]s.current_display_user_id = ? THEN 1 WHEN %[1]s.default_display_user_id = ? THEN 2 WHEN %[3]s THEN 3 ELSE 4 END`, userAlias, userIDExpr, ActivePrettyDisplayIDSQL(userAlias, "= ?")), []any{ keyword, keyword, keyword, nowMs, keyword, } } func UserDisplayIDSQL(userAlias string, displayUserID string, nowMs int64) (string, []any) { displayUserID = strings.TrimSpace(displayUserID) if displayUserID == "" { return "1 = 1", nil } // 精确短号筛选同样覆盖默认短号、当前展示号和 active 靓号,避免换靓号后只能按其中一种号码查到记录。 return fmt.Sprintf(`(%[1]s.current_display_user_id = ? OR %[1]s.default_display_user_id = ? OR %[2]s)`, userAlias, ActivePrettyDisplayIDSQL(userAlias, "= ?")), []any{ displayUserID, displayUserID, nowMs, displayUserID, } } func ActivePrettyDisplayIDSQL(userAlias string, displayPredicate string) string { return fmt.Sprintf(`EXISTS ( SELECT 1 FROM pretty_display_user_id_leases lease WHERE lease.app_code = %[1]s.app_code AND lease.user_id = %[1]s.user_id AND lease.status = 'active' AND (COALESCE(lease.expires_at_ms, 0) = 0 OR lease.expires_at_ms > ?) AND lease.display_user_id %[2]s LIMIT 1 )`, userAlias, displayPredicate) }