109 lines
2.8 KiB
Go
109 lines
2.8 KiB
Go
package operation
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"fmt"
|
|
"game/common/model"
|
|
"game/common/model/user"
|
|
"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
|
|
*model.TableOp[user.User]
|
|
}
|
|
|
|
// 玩家表
|
|
func NewUserOp() *UserOp {
|
|
return &UserOp{
|
|
db: UserDB,
|
|
userRedis: UserRedis,
|
|
TableOp: model.NewTableOp[user.User](UserDB, UserRedis),
|
|
}
|
|
}
|
|
|
|
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) {
|
|
us, code := s.FindCondition(map[string]any{"account_id": accountId})
|
|
if code != pb.ErrCode_OK {
|
|
// db中没有则创建玩家
|
|
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
|
|
}
|
|
}
|
|
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
|
|
}
|
|
// 建立索引
|
|
_ = s.userRedis.Set(context.Background(), s.redisKey(us.AccountId), us.ID, model.TableExpire).Err()
|
|
return us, pb.ErrCode_OK
|
|
}
|