package auth import ( "nl-video-api/internal/consts" "nl-video-api/internal/model/entity" "nl-video-api/utility/crypto" "nl-video-api/utility/jwt" "nl-video-api/utility/response" "time" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/net/ghttp" ) type cAuth struct{} var Auth = cAuth{} // LoginReq 登录请求 type LoginReq struct { Username string `json:"username" v:"required#用户名不能为空"` Password string `json:"password" v:"required#密码不能为空"` } // RegisterReq 注册请求 type RegisterReq struct { Username string `json:"username" v:"required|length:3,20#用户名不能为空|用户名长度为3-20位"` Phone string `json:"phone" v:"required|phone#手机号不能为空|手机号格式错误"` Password string `json:"password" v:"required|length:6,20#密码不能为空|密码长度为6-20位"` Code string `json:"code" v:"required#验证码不能为空"` } // UpdateProfileReq 更新资料请求 type UpdateProfileReq struct { Nickname string `json:"nickname" v:"length:1,20#昵称长度为1-20位"` Avatar string `json:"avatar" v:"url#头像格式错误"` Gender int `json:"gender" v:"in:0,1,2#性别参数错误"` Birthday string `json:"birthday" v:"date#生日格式错误"` } // Login 用户登录 func (c *cAuth) Login(r *ghttp.Request) { var req LoginReq if err := r.Parse(&req); err != nil { response.Error(r, response.CodeInvalidParam, err.Error()) return } // 查询用户 var user entity.NlUser err := g.DB().Model("nl_user").Where("username = ? OR phone = ?", req.Username, req.Username).Scan(&user) if err != nil || user.Id == 0 { response.Error(r, response.CodeError, "用户名或密码错误") return } // 验证密码 if !crypto.CheckPassword(req.Password, user.Password) { response.Error(r, response.CodeError, "用户名或密码错误") return } // 检查用户状态 if user.Status != consts.UserStatusNormal { response.Error(r, response.CodeError, "账号已被禁用") return } // 生成Token token, err := jwt.GenerateToken(user.Id, user.Username, consts.UserTypeUser) if err != nil { response.Error(r, response.CodeServerError, "Token生成失败") return } // 更新最后登录信息 now := int(time.Now().Unix()) clientIP := r.GetClientIp() // 将IPv6地址::1转换为IPv4地址127.0.0.1,或者使用IP地址的哈希值 if clientIP == "::1" { clientIP = "127.0.0.1" } g.DB().Model("nl_user").Where("id", user.Id).Update(g.Map{ "last_login_time": now, "last_login_ip": clientIP, "login_count": g.DB().Raw("login_count + 1"), }) // 格式化用户信息返回 userMap := g.Map{ "id": user.Id, "username": user.Username, "nick_name": user.NickName, "avatar": user.Avatar, "phone": user.Phone, "email": user.Email, "gender": user.Gender, "vip_level": user.VipLevel, "vip_expire_time": response.FormatTimestamp(user.VipExpireTime), "balance": user.Balance, "points": user.Points, "status": user.Status, "last_login_time": response.FormatTimestamp(now), "created_at": response.FormatTimestamp(user.CreatedAt), "updated_at": response.FormatTimestamp(user.UpdatedAt), } response.Success(r, g.Map{ "token": token, "user": userMap, }) } // Register 用户注册 func (c *cAuth) Register(r *ghttp.Request) { var req RegisterReq if err := r.Parse(&req); err != nil { response.Error(r, response.CodeInvalidParam, err.Error()) return } // 验证验证码(这里简化处理,实际应该验证短信验证码) if req.Code != "123456" { response.Error(r, response.CodeError, "验证码错误") return } // 检查用户名是否存在 count, _ := g.DB().Model("nl_user").Where("username", req.Username).Count() if count > 0 { response.Error(r, response.CodeError, "用户名已存在") return } // 检查手机号是否存在 count, _ = g.DB().Model("nl_user").Where("phone", req.Phone).Count() if count > 0 { response.Error(r, response.CodeError, "手机号已注册") return } // 加密密码 hashedPassword, err := crypto.HashPassword(req.Password) if err != nil { response.Error(r, response.CodeServerError, "密码加密失败") return } // 创建用户 now := int(time.Now().Unix()) userId, err := g.DB().Model("nl_user").InsertAndGetId(g.Map{ "username": req.Username, "nick_name": req.Username, "phone": req.Phone, "password": hashedPassword, "vip_level": consts.VipLevelNormal, "status": consts.UserStatusNormal, "created_at": now, "updated_at": now, }) if err != nil { response.Error(r, response.CodeServerError, "注册失败") return } // 生成Token token, err := jwt.GenerateToken(uint(userId), req.Username, consts.UserTypeUser) if err != nil { response.Error(r, response.CodeServerError, "Token生成失败") return } response.Success(r, g.Map{ "token": token, "user_id": userId, "message": "注册成功", }) } // Profile 获取用户信息 func (c *cAuth) Profile(r *ghttp.Request) { userId := r.GetCtxVar("user_id").Uint() var user entity.NlUser err := g.DB().Model("nl_user").Where("id", userId).Scan(&user) if err != nil { response.Error(r, response.CodeServerError, "获取用户信息失败") return } // 格式化用户信息返回 userMap := g.Map{ "id": user.Id, "username": user.Username, "nick_name": user.NickName, "avatar": user.Avatar, "phone": user.Phone, "email": user.Email, "gender": user.Gender, "birthday": user.Birthday, "vip_level": user.VipLevel, "vip_expire_time": response.FormatTimestamp(user.VipExpireTime), "balance": user.Balance, "points": user.Points, "status": user.Status, "last_login_time": response.FormatTimestamp(user.LastLoginTime), "login_count": user.LoginCount, "desc": user.Desc, "created_at": response.FormatTimestamp(user.CreatedAt), "updated_at": response.FormatTimestamp(user.UpdatedAt), } response.Success(r, userMap) } // UpdateProfile 更新用户信息 func (c *cAuth) UpdateProfile(r *ghttp.Request) { var req UpdateProfileReq if err := r.Parse(&req); err != nil { response.Error(r, response.CodeInvalidParam, err.Error()) return } userId := r.GetCtxVar("user_id").Uint() // 构建更新数据 updateData := g.Map{ "updated_at": int(time.Now().Unix()), } if req.Nickname != "" { updateData["nickname"] = req.Nickname } if req.Avatar != "" { updateData["avatar"] = req.Avatar } if req.Gender > 0 { updateData["gender"] = req.Gender } if req.Birthday != "" { updateData["birthday"] = req.Birthday } // 更新用户信息 _, err := g.DB().Model("nl_user").Where("id", userId).Update(updateData) if err != nil { response.Error(r, response.CodeServerError, "更新失败") return } response.Success(r, g.Map{ "message": "更新成功", }) } // Logout 用户登出 func (c *cAuth) Logout(r *ghttp.Request) { // 这里可以将token加入黑名单,简化处理直接返回成功 response.Success(r, g.Map{ "message": "登出成功", }) } // RefreshToken 刷新Token func (c *cAuth) RefreshToken(r *ghttp.Request) { authHeader := r.Header.Get("Authorization") if authHeader == "" { response.Error(r, response.CodeUnauthorized, "请提供认证令牌") return } tokenString := authHeader[7:] // 去掉 "Bearer " newToken, err := jwt.RefreshToken(tokenString) if err != nil { response.Error(r, response.CodeTokenInvalid, "Token刷新失败") return } response.Success(r, g.Map{ "token": newToken, }) }