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/go-redis/redis/v8" "gorm.io/gorm" "strconv" ) type UserAccountOp struct { db *gorm.DB accountRedis *redis.Client accountOp *model.TableOp[user.UserAccount] } func NewUserAccountOp() *UserAccountOp { return &UserAccountOp{ db: UserDB, accountRedis: AccountRedis, accountOp: model.NewTableOp[user.UserAccount](UserDB, AccountRedis), } } func (s *UserAccountOp) redisKey(username string) string { return fmt.Sprintf("username:%s", username) } func (s *UserAccountOp) GetUserAccount(username string) (*user.UserAccount, pb.ErrCode) { sUid, err := s.accountRedis.Get(context.Background(), s.redisKey(username)).Result() if err != nil { if errors.Is(err, redis.Nil) { var us user.UserAccount err = s.db.Where("username = ?", username).First(&us).Error if err != nil { log.ErrorF("find user:%v err:%v", username, err) return nil, pb.ErrCode_SystemErr } } else { log.ErrorF("find user:%v err:%v", username, err) return nil, pb.ErrCode_SystemErr } } uid, _ := strconv.ParseInt(sUid, 10, 64) if uid < 0 { log.ErrorF("get user account:%v failed, uid is: %d", username, uid) return nil, pb.ErrCode_SystemErr } return s.accountOp.Find(uint(uid)) } // 创建用户 func (s *UserAccountOp) CreateUserAccount(us *user.UserAccount) (*user.UserAccount, pb.ErrCode) { // 密码加密 hashedPassword, err := utils.Password(us.Password) if err != nil { log.ErrorF("username :%v generate password err:%v", us.Username, err) return nil, pb.ErrCode_SystemErr } us.Password = hashedPassword var code pb.ErrCode us, code = s.accountOp.Create(us) if code != pb.ErrCode_OK { return nil, code } s.accountRedis.Set(context.Background(), s.redisKey(us.Username), us.ID, model.TableExpire) return us, pb.ErrCode_OK } // 更新密码 func (s *UserAccountOp) UpdateUserPassword(us *user.UserAccount) (*user.UserAccount, pb.ErrCode) { // 密码加密 hashedPassword, err := utils.Password(us.Password) if err != nil { log.ErrorF("username :%v generate password err:%v", us.Username, err) return nil, pb.ErrCode_SystemErr } var code pb.ErrCode us, code = s.accountOp.Update(us.ID, map[string]any{"password": hashedPassword}) if code != pb.ErrCode_OK { s.accountRedis.Expire(context.Background(), s.redisKey(us.Username), model.TableExpire) } return us, code } //// 记录登录日志 //func (s *UserAccountOp) recordLoginLog(userID uint, ip, deviceID string, success bool, failReason string) { // logEntry := user.UserLoginLog{ // PlayerID: userID, // LoginIP: ip, // DeviceInfo: deviceID, // LoginResult: success, // FailReason: failReason, // } // // if err := s.logDb.Create(&logEntry).Error; err != nil { // log.ErrorF("记录登录日志失败: %v", err) // } //} // //// 生成JWT令牌(简化版) //func generateToken(userID uint, username string) (string, error) { // _ = userID // _ = username // // 这里应该使用JWT库生成实际令牌 // // 简化实现,实际项目中请使用安全的JWT实现 // return "generated-token-placeholder", nil //}