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"
|
2025-06-02 21:34:39 +08:00
|
|
|
|
"game/common/serialization"
|
2025-06-02 01:07:35 +08:00
|
|
|
|
"game/common/utils"
|
|
|
|
|
"github.com/fox/fox/log"
|
|
|
|
|
"github.com/go-redis/redis/v8"
|
|
|
|
|
"gorm.io/gorm"
|
|
|
|
|
"strconv"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
type UserAccountOp struct {
|
2025-06-02 21:34:39 +08:00
|
|
|
|
logDb *gorm.DB
|
2025-06-02 01:07:35 +08:00
|
|
|
|
db *gorm.DB
|
|
|
|
|
accountRedis *redis.Client
|
|
|
|
|
accountOp *model.TableOp[user.UserAccount]
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func NewUserAccountOp() *UserAccountOp {
|
|
|
|
|
return &UserAccountOp{
|
2025-06-02 21:34:39 +08:00
|
|
|
|
logDb: LogDB,
|
2025-06-02 01:07:35 +08:00
|
|
|
|
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) {
|
2025-06-02 21:34:39 +08:00
|
|
|
|
us := &user.UserAccount{}
|
|
|
|
|
err = s.db.Where("username = ?", username).First(us).Error
|
2025-06-02 01:07:35 +08:00
|
|
|
|
if err != nil {
|
2025-06-05 00:05:09 +08:00
|
|
|
|
log.DebugF("find user:%v err:%v", username, err)
|
2025-06-02 01:07:35 +08:00
|
|
|
|
return nil, pb.ErrCode_SystemErr
|
|
|
|
|
}
|
2025-06-02 21:34:39 +08:00
|
|
|
|
// 从db中查到后写入redis,并建立索引
|
|
|
|
|
if us.Username != "" && us.ID > 0 {
|
|
|
|
|
_, _ = s.accountOp.Update(us.ID, serialization.StructToMap(us))
|
|
|
|
|
_ = s.accountRedis.Set(context.Background(), s.redisKey(username), us.ID, model.TableExpire).Err()
|
|
|
|
|
}
|
|
|
|
|
return us, pb.ErrCode_OK
|
2025-06-02 01:07:35 +08:00
|
|
|
|
} 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
|
|
|
|
|
}
|
2025-06-06 00:09:10 +08:00
|
|
|
|
return s.accountOp.Find(uid)
|
2025-06-02 01:07:35 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 创建用户
|
|
|
|
|
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)
|
2025-06-04 01:56:38 +08:00
|
|
|
|
log.DebugF("create user:%v", utils.JsonMarshal(us))
|
2025-06-02 01:07:35 +08:00
|
|
|
|
if code != pb.ErrCode_OK {
|
|
|
|
|
return nil, code
|
|
|
|
|
}
|
2025-06-02 21:34:39 +08:00
|
|
|
|
// 建立索引
|
|
|
|
|
_ = s.accountRedis.Set(context.Background(), s.redisKey(us.Username), us.ID, model.TableExpire).Err()
|
2025-06-02 01:07:35 +08:00
|
|
|
|
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 {
|
2025-06-02 21:34:39 +08:00
|
|
|
|
_ = s.accountRedis.Expire(context.Background(), s.redisKey(us.Username), model.TableExpire).Err()
|
2025-06-02 01:07:35 +08:00
|
|
|
|
}
|
|
|
|
|
return us, code
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-02 21:34:39 +08:00
|
|
|
|
// 记录登录日志
|
|
|
|
|
func (s *UserAccountOp) RecordLoginLog(logEntry *user.UserLoginLog) {
|
|
|
|
|
if err := s.logDb.Create(&logEntry).Error; err != nil {
|
|
|
|
|
log.ErrorF("记录登录日志失败: %v", err)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-06-02 01:07:35 +08:00
|
|
|
|
//
|
|
|
|
|
//// 生成JWT令牌(简化版)
|
|
|
|
|
//func generateToken(userID uint, username string) (string, error) {
|
|
|
|
|
// _ = userID
|
|
|
|
|
// _ = username
|
|
|
|
|
// // 这里应该使用JWT库生成实际令牌
|
|
|
|
|
// // 简化实现,实际项目中请使用安全的JWT实现
|
|
|
|
|
// return "generated-token-placeholder", nil
|
|
|
|
|
//}
|