package model import ( "sync/atomic" ) // 用户等级:按「累计获得积分」(User.TotalPoints)定级,消费不减经验。 // 等级体系(数量/阈值/颜色)由管理员在后台配置,持久化于 site_settings 的 levels_config 键; // 进程内持有一份原子快照供 LevelOf 纯算术计算,配置保存时刷新,无需重启。 // LevelDef 单级配置:Threshold 为该级累计积分下限(Lv1 恒为 0),Color 为展示色板 key type LevelDef struct { Threshold int `json:"threshold"` Color string `json:"color"` } const ( // MinLevelCount / MaxLevelCount 等级数量边界(前端 CSS 变量按 MaxLevelCount 档固定下发) MinLevelCount = 2 MaxLevelCount = 12 ) // DefaultLevelDefs 默认 7 级(与历史硬编码阶梯一致),缺行/配置非法时回落 func DefaultLevelDefs() []LevelDef { return []LevelDef{ {Threshold: 0, Color: "neutral"}, {Threshold: 50, Color: "info"}, {Threshold: 200, Color: "teal"}, {Threshold: 500, Color: "ok"}, {Threshold: 1200, Color: "accent"}, {Threshold: 3000, Color: "purple"}, {Threshold: 8000, Color: "gold"}, } } // levelSnapshot 当前生效的等级配置([]LevelDef) var levelSnapshot atomic.Value func init() { levelSnapshot.Store(DefaultLevelDefs()) } // ValidLevelDefs 结构校验:数量 2–12、阈值非负且严格递增、首级为 0(色板合法性由 service 层校验) func ValidLevelDefs(defs []LevelDef) bool { if len(defs) < MinLevelCount || len(defs) > MaxLevelCount { return false } if defs[0].Threshold != 0 { return false } for i, d := range defs { if d.Threshold < 0 { return false } if i > 0 && d.Threshold <= defs[i-1].Threshold { return false } } return true } // ApplyLevelDefs 刷新进程内等级快照;非法/空配置回落默认表 func ApplyLevelDefs(defs []LevelDef) { if !ValidLevelDefs(defs) { defs = DefaultLevelDefs() } levelSnapshot.Store(append([]LevelDef(nil), defs...)) } // LevelDefs 当前生效的等级配置 func LevelDefs() []LevelDef { if v, ok := levelSnapshot.Load().([]LevelDef); ok && len(v) > 0 { return v } return DefaultLevelDefs() } // LevelOf 由累计获得积分计算等级,恒返回 1..len(当前配置) func LevelOf(totalPoints int) int { defs := LevelDefs() level := 1 for i := 1; i < len(defs); i++ { if totalPoints >= defs[i].Threshold { level = i + 1 } else { break } } return level }