Files
web_hghl_server/app/api/authapi/auth.go
T
2026-10-26 16:28:14 +08:00

187 lines
6.1 KiB
Go

package authapi
import (
"videoweb/app/service/authser"
"videoweb/app/service/wordsfilterser"
"videoweb/pub/common"
"videoweb/pub/common/enum/consts"
"videoweb/pub/common/srvdef"
"videoweb/pub/pubdef"
"github.com/gin-gonic/gin"
)
// extractUA 从 gin context 中提取 UA 中间件解析到的设备/系统信息
func extractUA(ctx *gin.Context) authser.UAInfo {
return authser.UAInfo{
Device: ctx.GetString(consts.CtxDevType),
SysType: pubdef.SysType(ctx.GetString(consts.CtxSysType)),
AppVer: ctx.GetString(consts.CtxVersion),
IP: ctx.ClientIP(),
}
}
type guestLoginReq struct {
DevID string `json:"devID"` // 设备 ID(首选)
Mac string `json:"mac"` // 设备 MAC 地址(备用)
DeviceId string `json:"deviceId"` // 设备 ID 第二版本(备用)
}
type registerReq struct {
AccountNo string `json:"accountNo" binding:"required"` // 账号
Password string `json:"password" binding:"required"` // 明文密码
AgentInviteCode string `json:"agentInviteCode"` // 邀请人的邀请码(可选)
}
type loginReq struct {
Account string `json:"account" binding:"required"` // 账号
Password string `json:"password" binding:"required"` // 明文密码
}
type updateProfileReq struct {
AccountNo string `json:"accountNo" binding:"required"` // 账号(必填,用于定位用户)
Avatar *string `json:"avatar"` // 新头像 URL(可选)
NikeName *string `json:"nikeName"` // 昵称
OldPassword *string `json:"oldPassword"` // 旧密码明文(修改密码时必填)
NewPassword *string `json:"newPassword"` // 新密码明文(修改密码时必填)
}
// GuestLogin 游客登录/自动注册
// @Tags 用户认证
// @Summary 游客登录
// @Description 按设备 ID 查找已有游客账号,找不到则自动注册。若请求携带有效 token 则优先复用该用户。
// @Accept json
// @Produce json
// @Param param body guestLoginReq true "设备信息"
// @Success 200 {object} authser.LoginResp "登录成功"
// @Failure 400 {string} string "失败"
// @Router /api/app/login/guest [POST]
func GuestLogin(ctx *gin.Context) {
var req guestLoginReq
_ = ctx.ShouldBind(&req)
// 若设备信息为空,尝试从 UA 中间件补充 DevID
if req.DevID == "" {
req.DevID = ctx.GetString(consts.CtxDevId)
}
currentUserId := common.GetUserId(ctx)
resp, serr := authser.GuestLogin(ctx, &authser.GuestLoginReq{
DevID: req.DevID,
Mac: req.Mac,
DeviceId: req.DeviceId,
UA: extractUA(ctx),
}, currentUserId)
if serr != nil {
common.ServerJSON(ctx, serr.Code, serr.Tips)
return
}
common.ServerJSON(ctx, srvdef.Success, resp)
}
// Register 账号注册(游客升级 or 直接注册)
// @Tags 用户认证
// @Summary 注册
// @Description 已登录游客传入账号密码完成升级;未登录用户直接注册新账号。
// @Accept json
// @Produce json
// @Param param body registerReq true "注册参数"
// @Success 200 {object} authser.LoginResp "注册成功,返回 token 及用户基本信息"
// @Failure 400 {string} string "失败"
// @Router /api/app/auth/register [POST]
func Register(ctx *gin.Context) {
var req registerReq
if err := ctx.ShouldBind(&req); err != nil {
common.ServerJSON(ctx, srvdef.ErrParamError, nil)
return
}
currentUserId := common.GetUserId(ctx)
resp, serr := authser.Register(ctx, req.AccountNo, req.Password, req.AgentInviteCode, currentUserId, extractUA(ctx))
if serr != nil {
common.ServerJSON(ctx, serr.Code, serr.Tips)
return
}
common.ServerJSON(ctx, srvdef.Success, resp)
}
// Login 用户登录
// @Tags 用户认证
// @Summary 登录
// @Description 账号均可作为登录凭证
// @Accept json
// @Produce json
// @Param param body loginReq true "登录参数"
// @Success 200 {object} authser.LoginResp "登录成功,返回 token 及用户基本信息"
// @Failure 400 {string} string "失败"
// @Router /api/app/auth/login [POST]
func Login(ctx *gin.Context) {
var req loginReq
if err := ctx.ShouldBind(&req); err != nil {
common.ServerJSON(ctx, srvdef.ErrParamError, nil)
return
}
resp, serr := authser.Login(ctx, req.Account, req.Password, extractUA(ctx))
if serr != nil {
common.ServerJSON(ctx, serr.Code, serr.Tips)
return
}
common.ServerJSON(ctx, srvdef.Success, resp)
}
// GetInfo 获取当前登录用户信息
// @Tags 用户认证
// @Summary 获取当前登录用户信息
// @Description 根据当前登录 token 查询用户基础信息
// @Accept json
// @Produce json
// @Success 200 {object} authser.UserInfoResp "成功"
// @Failure 400 {string} string "失败"
// @Router /api/app/auth/getInfo [get]
func GetInfo(ctx *gin.Context) {
userId := common.GetUserId(ctx)
if userId <= 0 {
common.ServerJSON(ctx, srvdef.InvalidToken, nil)
return
}
resp, serr := authser.GetInfo(ctx, userId)
if serr != nil {
common.ServerJSON(ctx, serr.Code, serr.Tips)
return
}
common.ServerJSON(ctx, srvdef.Success, resp)
}
// UpdateProfile 修改用户资料
// @Tags 用户认证
// @Summary 修改用户资料(头像 / 密码,可任意组合)
// @Description 账号必填;avatar、oldPassword+newPassword 均为可选,至少提供一项。修改密码时旧密码和新密码必须同时提供。
// @Accept json
// @Produce json
// @Param param body updateProfileReq true "修改资料参数"
// @Success 200 {string} string "成功"
// @Failure 400 {string} string "失败"
// @Router /api/app/auth/profile [POST]
func UpdateProfile(ctx *gin.Context) {
var req updateProfileReq
if err := ctx.ShouldBind(&req); err != nil {
common.ServerJSON(ctx, srvdef.ErrParamError, nil)
return
}
if req.NikeName != nil && !wordsfilterser.Validate(*req.NikeName) {
common.ServerJSON(ctx, srvdef.ErrContainIllegalWord, "包含非法字符")
return
}
serr := authser.UpdateProfile(ctx, &authser.UpdateProfileReq{
AccountNo: req.AccountNo,
Avatar: req.Avatar,
NikeName: req.NikeName,
OldPassword: req.OldPassword,
NewPassword: req.NewPassword,
})
if serr != nil {
common.ServerJSON(ctx, serr.Code, serr.Tips)
return
}
common.ServerJSON(ctx, srvdef.Success, "")
}