Files
lckt-server/api/v1/app/user.go
2025-07-20 03:07:42 +08:00

273 lines
7.8 KiB
Go

package app
import (
"errors"
"fmt"
"git.echol.cn/loser/lckt/global"
"git.echol.cn/loser/lckt/model/app"
r "git.echol.cn/loser/lckt/model/common/response"
"git.echol.cn/loser/lckt/model/user/request"
"git.echol.cn/loser/lckt/utils"
"git.echol.cn/loser/lckt/utils/user_jwt"
"git.echol.cn/loser/lckt/utils/wechat"
"github.com/gin-gonic/gin"
"github.com/redis/go-redis/v9"
"go.uber.org/zap"
"time"
)
type AppUserApi struct{}
// SendCode 发送验证码
func (*AppUserApi) SendCode(ctx *gin.Context) {
var p request.SendCodeReq
if err := ctx.ShouldBind(&p); err != nil {
r.FailWithMessage(err.Error(), ctx)
global.GVA_LOG.Error("参数错误,发送验证码失败", zap.Error(err))
return
}
if err := userService.SendCode(p); err != nil {
r.FailWithMessage("发送验证码失败", ctx)
return
}
r.OkWithMessage("发送验证码成功", ctx)
}
// Login 用户登录
func (*AppUserApi) Login(ctx *gin.Context) {
var p request.CodeLoginReq
if err := ctx.ShouldBind(&p); err != nil {
r.FailWithMessage(err.Error(), ctx)
global.GVA_LOG.Error("参数错误,登录失败", zap.Error(err))
return
}
if result, _ := global.GVA_REDIS.Get(ctx, fmt.Sprintf("VerifyCode:%s", p.Phone)).Result(); result != p.Code {
global.GVA_LOG.Error("验证码错误", zap.String("phone", p.Phone))
r.FailWithMessage("验证码错误", ctx)
return
}
user, err := appUserService.Login(p)
if err != nil {
r.FailWithMessage("登录失败", ctx)
return
}
// 生成token
token, claims, err := user_jwt.LoginToken(user)
if err != nil {
global.GVA_LOG.Error("获取token失败!", zap.Error(err))
r.FailWithMessage("获取token失败", ctx)
return
}
if _, err = global.GVA_REDIS.Get(ctx, user.Phone).Result(); errors.Is(err, redis.Nil) {
// 此处过期时间等于jwt过期时间
dr, err := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
if err != nil {
return
}
timer := dr
if err := global.GVA_REDIS.Set(ctx, user.Phone, token, timer).Err(); err != nil {
global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
r.FailWithMessage("设置登录状态失败", ctx)
return
}
user_jwt.SetToken(ctx, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
r.OkWithDetailed(gin.H{
"User": user,
"Token": token,
"ExpiresAt": claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
}, "登录成功", ctx)
} else if err != nil {
global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
r.FailWithMessage("设置登录状态失败", ctx)
}
}
// WechatLogin 微信登录
func (*AppUserApi) WechatLogin(ctx *gin.Context) {
var p request.CodeLoginReq
if err := ctx.ShouldBind(&p); err != nil {
r.FailWithMessage(err.Error(), ctx)
global.GVA_LOG.Error("参数错误,登录失败", zap.Error(err))
return
}
//Todo 待完善微信登录
info := wechat.GetUserInfo(p.Code)
if info == nil {
r.FailWithMessage("获取用户信息失败", ctx)
return
}
user, err := appUserService.WechatLogin(info)
if err != nil {
r.FailWithMessage("登录失败", ctx)
return
}
// 生成token
token, claims, err := user_jwt.LoginToken(user)
if err != nil {
global.GVA_LOG.Error("获取token失败!", zap.Error(err))
r.FailWithMessage("获取token失败", ctx)
return
}
if _, err = global.GVA_REDIS.Get(ctx, user.Phone).Result(); errors.Is(err, redis.Nil) {
// 此处过期时间等于jwt过期时间
dr, err := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
if err != nil {
return
}
timer := dr
if err := global.GVA_REDIS.Set(ctx, user.Phone, token, timer).Err(); err != nil {
global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
r.FailWithMessage("设置登录状态失败", ctx)
return
}
user_jwt.SetToken(ctx, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
r.OkWithDetailed(gin.H{
"User": user,
"Token": token,
"ExpiresAt": claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
}, "登录成功", ctx)
}
}
// GetUserInfo 获取用户信息
func (*AppUserApi) GetUserInfo(ctx *gin.Context) {
id := user_jwt.GetUserID(ctx)
if id == 0 {
global.GVA_LOG.Error("获取用户ID失败")
r.FailWithMessage("获取用户ID失败", ctx)
return
}
user, err := appUserService.GetUserInfo(id)
if err != nil {
global.GVA_LOG.Error("获取用户信息失败", zap.Error(err))
r.FailWithMessage("获取用户信息失败", ctx)
return
}
r.OkWithDetailed(user, "获取用户信息成功", ctx)
}
// PwdLogin 密码登录
func (*AppUserApi) PwdLogin(ctx *gin.Context) {
var p request.PwdLoginReq
if err := ctx.ShouldBind(&p); err != nil {
r.FailWithMessage(err.Error(), ctx)
global.GVA_LOG.Error("参数错误,登录失败", zap.Error(err))
return
}
user, err := appUserService.PwdLogin(p)
if err != nil {
r.FailWithMessage("手机号或密码错误!", ctx)
return
}
// 生成token
token, claims, err := user_jwt.LoginToken(user)
if err != nil {
global.GVA_LOG.Error("获取token失败!", zap.Error(err))
r.FailWithMessage("获取token失败", ctx)
return
}
// 此处过期时间等于jwt过期时间
dr, err := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
if err != nil {
return
}
timer := dr
if err := global.GVA_REDIS.Set(ctx, user.Phone, token, timer).Err(); err != nil {
global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
r.FailWithMessage("设置登录状态失败", ctx)
return
}
user_jwt.SetToken(ctx, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
r.OkWithDetailed(gin.H{
"User": user,
"Token": token,
"ExpiresAt": claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
}, "登录成功", ctx)
}
// Register 用户手机注册
func (a *AppUserApi) Register(context *gin.Context) {
var p request.RegisterReq
if err := context.ShouldBind(&p); err != nil {
r.FailWithMessage(err.Error(), context)
global.GVA_LOG.Error("参数错误,注册失败", zap.Error(err))
return
}
if result, _ := global.GVA_REDIS.Get(context, fmt.Sprintf("VerifyCode:%s", p.Phone)).Result(); result != p.Code {
global.GVA_LOG.Error("验证码错误", zap.String("phone", p.Phone))
r.FailWithMessage("验证码错误", context)
return
}
user, err := appUserService.Register(p)
if err != nil {
global.GVA_LOG.Error("注册失败", zap.Error(err))
r.FailWithMessage("注册失败", context)
return
}
// 生成token
token, claims, err := user_jwt.LoginToken(user)
if err != nil {
global.GVA_LOG.Error("获取token失败!", zap.Error(err))
r.FailWithMessage("获取token失败", context)
return
}
// 此处过期时间等于jwt过期时间
dr, err := utils.ParseDuration(global.GVA_CONFIG.JWT.ExpiresTime)
if err != nil {
return
}
timer := dr
if err := global.GVA_REDIS.Set(context, user.Phone, token, timer).Err(); err != nil {
global.GVA_LOG.Error("设置登录状态失败!", zap.Error(err))
r.FailWithMessage("设置登录状态失败", context)
return
}
user_jwt.SetToken(context, token, int(claims.RegisteredClaims.ExpiresAt.Unix()-time.Now().Unix()))
r.OkWithDetailed(gin.H{
"User": user,
"Token": token,
"ExpiresAt": claims.RegisteredClaims.ExpiresAt.Unix() * 1000,
}, "注册成功", context)
}
// ApplyTeacher 申请成为教师
func (a *AppUserApi) ApplyTeacher(context *gin.Context) {
var p app.TeacherApply
if err := context.ShouldBind(&p); err != nil {
r.FailWithMessage(err.Error(), context)
global.GVA_LOG.Error("参数错误,申请失败", zap.Error(err))
return
}
id := user_jwt.GetUserID(context)
if id == 0 {
global.GVA_LOG.Error("获取用户ID失败")
r.FailWithMessage("获取用户ID失败", context)
return
}
p.UserId = id
if err := appUserService.ApplyTeacher(p); err != nil {
global.GVA_LOG.Error("申请失败", zap.Error(err))
r.FailWithMessage("申请失败", context)
return
}
r.OkWithMessage("申请成功", context)
}