2026-04-30 02:30:32 +08:00

266 lines
8.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package user
import (
"regexp"
"strings"
)
const (
// RegionStatusActive 表示区域映射参与国家到区域的实时解析。
RegionStatusActive = "active"
// RegionStatusDisabled 表示区域停止解析并释放 active 国家归属。
RegionStatusDisabled = "disabled"
// RegionRebuildTaskStatusPending 表示历史用户区域快照等待后台重算。
RegionRebuildTaskStatusPending = "pending"
// RegionRebuildTaskStatusRunning 表示任务已被某个 user-service 节点 claim。
RegionRebuildTaskStatusRunning = "running"
// RegionRebuildTaskStatusCompleted 表示该 country 下历史用户已经按任务 revision 重算完成。
RegionRebuildTaskStatusCompleted = "completed"
// RegionRebuildTaskStatusSkipped 表示任务 revision 已过期,不能覆盖更新映射。
RegionRebuildTaskStatusSkipped = "skipped"
// RegionRebuildTaskStatusFailed 表示任务处理失败,等待人工或后续重试策略处理。
RegionRebuildTaskStatusFailed = "failed"
)
var (
countryCodePattern = regexp.MustCompile(`^[A-Z]{2,3}$`)
isoAlpha3Pattern = regexp.MustCompile(`^[A-Z]{3}$`)
isoNumericPattern = regexp.MustCompile(`^[0-9]{3}$`)
phoneCountryCodePattern = regexp.MustCompile(`^\+[1-9][0-9]{0,2}$`)
shortRegionCodePattern = regexp.MustCompile(`^[A-Za-z0-9_]{2,32}$`)
descriptiveRegionCodePattern = regexp.MustCompile(`^[A-Za-z0-9][A-Za-z0-9 _-]{1,63}$`)
)
// Country 是国家主数据enabled 是唯一可用性开关,外部只提交 CountryCode。
type Country struct {
CountryID int64
CountryName string
CountryCode string
ISOAlpha3 string
ISONumeric string
CountryDisplayName string
PhoneCountryCode string
Flag string
Enabled bool
SortOrder int32
CreatedByUserID int64
UpdatedByUserID int64
CreatedAtMs int64
UpdatedAtMs int64
}
// Region 是业务区域主数据Countries 只放 active 国家码快照。
type Region struct {
RegionID int64
RegionCode string
Name string
Status string
Countries []string
SortOrder int32
CreatedByUserID int64
UpdatedByUserID int64
CreatedAtMs int64
UpdatedAtMs int64
}
// RegionCountryMapping 表示一个 active 或历史国家到区域归属记录。
type RegionCountryMapping struct {
RegionID int64
CountryCode string
Status string
CreatedAtMs int64
UpdatedAtMs int64
}
// RegionChangeLog 是管理端区域配置审计,不记录用户隐私资料。
type RegionChangeLog struct {
RegionID int64
Operation string
BeforeJSON string
AfterJSON string
OperatorUserID int64
RequestID string
CreatedAtMs int64
}
// UserRegionRebuildTask 表示按国家分页刷新 users.region_id 的后台任务。
type UserRegionRebuildTask struct {
TaskID int64
RegionID int64
CountryCode string
TargetRegionID int64
MappingRevision int64
Status string
CursorUserID int64
LockedBy string
LockedUntilMs int64
AttemptCount int32
ErrorMessage string
CreatedAtMs int64
UpdatedAtMs int64
}
// RegionRebuildProcessResult 描述单次 worker 处理结果,便于测试和日志输出。
type RegionRebuildProcessResult struct {
TaskID int64
CountryCode string
TargetRegionID int64
Status string
ProcessedUsers int
CursorUserID int64
NoTask bool
}
// CountryFilter 描述国家管理列表过滤条件;国家只支持 enabled 维度过滤。
type CountryFilter struct {
Enabled *bool
}
// RegionFilter 描述区域管理列表过滤条件。
type RegionFilter struct {
Status string
}
// CreateCountryCommand 描述创建国家主数据的事务输入。
type CreateCountryCommand struct {
CountryName string
CountryCode string
ISOAlpha3 string
ISONumeric string
CountryDisplayName string
PhoneCountryCode string
Flag string
Enabled bool
SortOrder int32
OperatorUserID int64
RequestID string
NowMs int64
}
// UpdateCountryCommand 描述修改国家展示字段的事务输入CountryCode 创建后不可变。
type UpdateCountryCommand struct {
CountryID int64
CountryName string
ISOAlpha3 string
ISONumeric string
CountryDisplayName string
PhoneCountryCode string
Flag string
SortOrder int32
OperatorUserID int64
RequestID string
NowMs int64
}
// DisableCountryCommand 描述关闭 App 国家选择入口的事务输入。
type DisableCountryCommand struct {
CountryID int64
OperatorUserID int64
RequestID string
NowMs int64
}
// EnableCountryCommand 描述开放国家给 App 注册页和用户改国家链路的事务输入。
type EnableCountryCommand struct {
CountryID int64
OperatorUserID int64
RequestID string
NowMs int64
}
// CreateRegionCommand 描述创建区域及其 active 国家列表的事务输入。
type CreateRegionCommand struct {
RegionCode string
Name string
Countries []string
SortOrder int32
OperatorUserID int64
RequestID string
NowMs int64
}
// UpdateRegionCommand 描述修改区域展示字段的事务输入,不修改 countries。
type UpdateRegionCommand struct {
RegionID int64
RegionCode string
Name string
SortOrder int32
OperatorUserID int64
RequestID string
NowMs int64
}
// ReplaceRegionCountriesCommand 描述原子替换区域 active 国家归属的事务输入。
type ReplaceRegionCountriesCommand struct {
RegionID int64
Countries []string
OperatorUserID int64
RequestID string
NowMs int64
}
// DisableRegionCommand 描述停用区域并释放 active 国家归属的事务输入。
type DisableRegionCommand struct {
RegionID int64
OperatorUserID int64
RequestID string
NowMs int64
}
// NormalizeCountryCode 统一客户端和管理端提交的国家码形态。
func NormalizeCountryCode(code string) string {
return strings.ToUpper(strings.TrimSpace(code))
}
// ValidCountryCode 校验本系统允许的两到三位大写英文国家码。
func ValidCountryCode(code string) bool {
return countryCodePattern.MatchString(code)
}
// NormalizeISOAlpha3 统一 ISO alpha-3 辅助展示字段形态;空值表示未配置。
func NormalizeISOAlpha3(code string) string {
return strings.ToUpper(strings.TrimSpace(code))
}
// ValidISOAlpha3 校验非空 ISO alpha-3 或明确 user-assigned 三字码。
func ValidISOAlpha3(code string) bool {
return code == "" || isoAlpha3Pattern.MatchString(code)
}
// NormalizeISONumeric 统一 ISO numeric/M49 字符串形态,不能转整数以免破坏前导零。
func NormalizeISONumeric(code string) string {
return strings.TrimSpace(code)
}
// ValidISONumeric 校验非空 numeric 必须是三位数字字符串。
func ValidISONumeric(code string) bool {
return code == "" || isoNumericPattern.MatchString(code)
}
// NormalizePhoneCountryCode 统一 E.164 国家呼叫码字段,空值表示无可用电话元数据。
func NormalizePhoneCountryCode(code string) string {
return strings.TrimSpace(code)
}
// ValidPhoneCountryCode 校验国家呼叫码,不做唯一性假设,因为多个国家可以共享 +1。
func ValidPhoneCountryCode(code string) bool {
return code == "" || phoneCountryCodePattern.MatchString(code)
}
// NormalizeRegionCode 统一区域业务编码形态。
func NormalizeRegionCode(code string) string {
code = strings.TrimSpace(code)
if shortRegionCodePattern.MatchString(code) {
// 手工业务短码继续统一大写;导入的 subregion 描述码保留原始大小写和空格。
return strings.ToUpper(code)
}
return strings.Join(strings.Fields(code), " ")
}
// ValidRegionCode 校验区域编码,避免自由文本进入唯一键和审计口径。
func ValidRegionCode(code string) bool {
return shortRegionCodePattern.MatchString(code) || descriptiveRegionCodePattern.MatchString(code)
}