187 lines
6.1 KiB
Go
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, "")
|
|
}
|