game/server/db/operation/userAccount.go

115 lines
3.2 KiB
Go
Raw Normal View History

2025-06-02 01:07:35 +08:00
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
//}