131 lines
4.3 KiB
Go
131 lines
4.3 KiB
Go
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)
|
||
}
|