Files
2025-08-03 00:11:15 +08:00

283 lines
7.6 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
})
}