109 lines
2.8 KiB
Go
Raw Normal View History

2025-06-06 00:09:10 +08:00
package operation
import (
"context"
"errors"
"fmt"
"game/common/model/user"
2025-06-20 23:29:59 +08:00
"game/common/modelOperator"
2025-06-06 00:09:10 +08:00
"game/common/proto/pb"
"game/common/utils"
"github.com/fox/fox/log"
"github.com/fox/fox/xrand"
"github.com/go-redis/redis/v8"
"github.com/google/uuid"
"gorm.io/gorm"
"strconv"
)
type UserOp struct {
db *gorm.DB
userRedis *redis.Client
2025-06-20 23:29:59 +08:00
*modelOperator.TableOp[user.User]
2025-06-06 00:09:10 +08:00
}
// 玩家表
func NewUserOp() *UserOp {
return &UserOp{
db: UserDB,
userRedis: UserRedis,
2025-06-20 23:29:59 +08:00
TableOp: modelOperator.NewTableOp[user.User](UserDB, UserRedis),
2025-06-06 00:09:10 +08:00
}
}
func (s *UserOp) redisKey(accountId int64) string {
return fmt.Sprintf("account_id:%v", accountId)
}
func (s *UserOp) GetUserByAccountId(accountId int64) (*user.User, pb.ErrCode) {
sUid, err := s.userRedis.Get(context.Background(), s.redisKey(accountId)).Result()
if err != nil {
if errors.Is(err, redis.Nil) {
2025-06-16 00:50:42 +08:00
us, code := s.FindCondition(map[string]any{"account_id": accountId})
if code != pb.ErrCode_OK {
2025-06-06 00:09:10 +08:00
// db中没有则创建玩家
2025-06-16 00:50:42 +08:00
if us, code = s.createUserAccountId(accountId); code == pb.ErrCode_OK {
_, _ = NewUserResourcesOp().Create(&user.UserResources{UID: us.ID})
return us, pb.ErrCode_OK
} else {
log.DebugF("create user by account id:%v", accountId)
return nil, pb.ErrCode_SystemErr
}
2025-06-06 00:09:10 +08:00
}
return us, pb.ErrCode_OK
} else {
log.ErrorF("find user by account id:%v err:%v", accountId, err)
return nil, pb.ErrCode_SystemErr
}
}
uid, _ := strconv.ParseInt(sUid, 10, 64)
if uid < 0 {
log.ErrorF("get user failed, account id:%d, uid:%v", accountId, sUid)
return nil, pb.ErrCode_SystemErr
}
return s.Find(uid)
}
func (s *UserOp) generateUniqueNickname(db *gorm.DB) (string, error) {
// 基础昵称模板
baseNick := "用户_" + uuid.New().String()[:8]
nickname := baseNick
// 检查是否唯一,不唯一则追加随机字符
for i := 0; i < 5; i++ { // 最多尝试5次
var count int64
err := db.Model(&user.User{}).Where("nickname = ?", nickname).Count(&count).Error
if err != nil {
return "", err
}
if count == 0 {
return nickname, nil
}
nickname = baseNick + xrand.RandomString(2) // 追加2位随机字符
}
return "", fmt.Errorf("无法生成唯一昵称")
}
// 创建用户
func (s *UserOp) createUserAccountId(accountId int64) (*user.User, pb.ErrCode) {
nickname, err := s.generateUniqueNickname(s.db)
if err != nil {
log.ErrorF("generate unique nickname err:%v", err)
return nil, pb.ErrCode_SystemErr
}
us := &user.User{
AccountId: accountId,
Nickname: nickname,
}
var code pb.ErrCode
us, code = s.Create(us)
log.DebugF("create user:%v", utils.JsonMarshal(us))
if code != pb.ErrCode_OK {
return nil, code
}
// 建立索引
2025-06-20 23:29:59 +08:00
_ = s.userRedis.Set(context.Background(), s.redisKey(us.AccountId), us.ID, modelOperator.TableExpire).Err()
2025-06-06 00:09:10 +08:00
return us, pb.ErrCode_OK
}