package service import ( "crypto/rand" "fmt" "math/big" "github.com/sundynix/pets-be/internal/model" ) // 新用户默认昵称的前缀。微信登录拿不到昵称(要用户主动授权), // 全都叫「微信用户」的话,社区里一屏全是同名,后台也没法区分。 var nickPrefixes = []string{ "铲屎官", "猫奴", "狗子家长", "毛孩子家长", "养宠新手", "肉垫爱好者", "撸猫达人", "遛狗选手", "猫窝管理员", "狗窝管理员", } // UniqueNickname 生成一个库里没有的昵称,形如「铲屎官12138」。 // 5 位数字 × 10 个前缀 = 百万级空间,撞了就重试;连撞 20 次说明 // 随机源出问题了,退回带更长数字的形式,绝不返回空。 func (s *Service) UniqueNickname() string { for i := 0; i < 20; i++ { name := fmt.Sprintf("%s%05d", pick(nickPrefixes), randInt(100000)) var count int64 if err := s.db.Model(&model.User{}).Where("nickname = ?", name).Count(&count).Error; err != nil { return name // 查不了就直接用,重名也比登录失败强 } if count == 0 { return name } } return fmt.Sprintf("%s%09d", pick(nickPrefixes), randInt(1000000000)) } func pick(list []string) string { return list[randInt(int64(len(list)))] } func randInt(n int64) int64 { v, err := rand.Int(rand.Reader, big.NewInt(n)) if err != nil { return 0 } return v.Int64() }