package model //import ( // "errors" // "github.com/fox/fox/log" // "golang.org/x/crypto/bcrypt" // "gorm.io/gorm" // "time" //) // //const ( // AccountNormal = 1 // 正常 // AccountFrozen = 2 // 冻结 // AccountBanned = 3 // 封禁 //) // //// 玩家账户表 //type UserAccount struct { // gorm.Model // Username string `gorm:"type:varchar(32);uniqueIndex;not null"` // 用户名 // Password string `gorm:"type:varchar(255);not null"` // 密码哈希 // Email string `gorm:"type:varchar(100)"` // 邮箱(可选) // Phone string `gorm:"type:varchar(20)"` // 手机号(可选) // DeviceID string `gorm:"type:varchar(64);index"` // 设备ID // LastLoginIP string `gorm:"type:varchar(45)"` // 最后登录IP(支持IPv6) // LastLoginTime time.Time // 最后登录时间 // Status int `gorm:"type:tinyint;default:1"` // 账号状态 1-正常 2-冻结 3-封禁 // RegisterIP string `gorm:"type:varchar(45)"` // 注册IP // RegisterTime time.Time `gorm:"type:TIMESTAMP;default:CURRENT_TIMESTAMP"` // 注册时间 //} // //// 玩家登录记录表 //type UserLoginLog struct { // gorm.Model // PlayerID uint `gorm:"index"` // 关联玩家ID // LoginIP string `gorm:"type:varchar(45);not null"` // 登录IP // LoginTime time.Time `gorm:"type:TIMESTAMP;default:CURRENT_TIMESTAMP"` // 登录时间 // DeviceInfo string `gorm:"type:varchar(255)"` // 设备信息(JSON格式) // LoginResult bool // 登录结果 true-成功 false-失败 // FailReason string `gorm:"type:varchar(100)"` // 失败原因 //} // //type UserLoginOp struct { // db *gorm.DB // logDb *gorm.DB //} // //func NewUserLoginOp() *UserLoginOp { // return &UserLoginOp{db: UserDB, logDb: LogDB} //} // //var ( // ErrUserOrPassword = errors.New("user or password was error") // ErrAccountFrozen = errors.New("account frozen") // ErrAccountBanned = errors.New("account banned") //) // //func (s *UserLoginOp) Login(username, password, ip, deviceID string) (*UserAccount, error) { // var user UserAccount // err := s.db.Where("username = ?", username).First(&user).Error // if err != nil { // return nil, err // } // // 验证密码 // if err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(password)); err != nil { // s.recordLoginLog(user.ID, ip, deviceID, false, ErrUserOrPassword.Error()) // return nil, ErrUserOrPassword // } // // 检查账号状态 // switch user.Status { // case AccountNormal: // // case AccountFrozen: // s.recordLoginLog(user.ID, ip, deviceID, false, ErrAccountFrozen.Error()) // return nil, ErrAccountFrozen // case AccountBanned: // s.recordLoginLog(user.ID, ip, deviceID, false, ErrAccountBanned.Error()) // return nil, ErrAccountBanned // } // // 更新最后登录信息 // user.LastLoginIP = ip // user.LastLoginTime = time.Now() // _ = s.db.Save(&user).Error // // // 记录成功登录日志 // s.recordLoginLog(user.ID, ip, deviceID, true, "") // // // 6. 生成访问令牌 // token, err := generateToken(user.ID, user.Username) // if err != nil { // return nil, err // } // user.Password = token // return &user, err //} // //// 注册新用户 //func (s *UserLoginOp) RegisterNewUser(username, password, ip, deviceID string) (*UserAccount, error) { // // 密码加密 // hashedPassword, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost) // if err != nil { // return nil, err // } // user := UserAccount{ // Username: username, // Password: string(hashedPassword), // DeviceID: deviceID, // RegisterIP: ip, // Status: 1, // LastLoginIP: ip, // LastLoginTime: time.Now(), // } // // if err := s.db.Create(&user).Error; err != nil { // return nil, err // } // // s.recordLoginLog(user.ID, ip, deviceID, true, "") // // // 生成访问令牌 // token, err := generateToken(user.ID, user.Username) // if err != nil { // return nil, err // } // user.Password = token // // return &user, nil //} // //// 记录登录日志 //func (s *UserLoginOp) recordLoginLog(userID uint, ip, deviceID string, success bool, failReason string) { // logEntry := 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 //}