Files

283 lines
7.6 KiB
Go
Raw Permalink Normal View History

2025-08-03 00:11:15 +08:00
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,
})
}