This commit is contained in:
2025-09-05 22:43:48 +08:00
parent 4e6fe9a456
commit 89cf5f0d57
6 changed files with 354 additions and 29 deletions
@@ -3,6 +3,7 @@ package user
import (
"github.com/flipped-aurora/gin-vue-admin/server/global"
"github.com/flipped-aurora/gin-vue-admin/server/model/common/response"
systemReq "github.com/flipped-aurora/gin-vue-admin/server/model/system/request"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model/request"
wechatResponse "github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/model/response"
"github.com/flipped-aurora/gin-vue-admin/server/plugin/wechat-integration/service"
@@ -22,25 +23,33 @@ var miniService = service.ServiceGroupApp.MiniService
// @Accept json
// @Produce json
// @Param data body request.MiniLoginRequest true "登录参数"
// @Success 200 {object} response.Response{data=response.MiniLoginResponse} "登录成功"
// @Success 200 {object} wechatResponse.Response{data=wechatResponse.MiniLoginResponse} "登录成功"
// @Router /wechat/user/mini/login [post]
func (w *MiniUserApi) Login(c *gin.Context) {
var req request.MiniLoginRequest
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
c.JSON(200, wechatResponse.ErrorResponseWithMsg(wechatResponse.ERROR_PARAM_INVALID, err.Error()))
return
}
if req.Code == "" {
response.FailWithMessage("code不能为空", c)
c.JSON(200, wechatResponse.ErrorResponse(wechatResponse.ERROR_PARAM_MISSING))
return
}
user, err := miniService.Code2Session(req.Code)
if err != nil {
global.GVA_LOG.Error("小程序登录失败!", zap.Error(err))
response.FailWithMessage("登录失败: "+err.Error(), c)
// 根据错误类型返回不同的错误码
if err.Error() == "获取用户 OpenID 失败" {
c.JSON(200, wechatResponse.ErrorResponse(wechatResponse.ERROR_WX_OPENID_EMPTY))
} else if err.Error() == "微信小程序 Code2Session 失败" {
c.JSON(200, wechatResponse.ErrorResponse(wechatResponse.ERROR_WX_SESSION_FAILED))
} else {
c.JSON(200, wechatResponse.ErrorResponseWithMsg(wechatResponse.ERROR_WX_CODE_INVALID, err.Error()))
}
return
}
@@ -48,7 +57,7 @@ func (w *MiniUserApi) Login(c *gin.Context) {
token, _, err := utils.AppUserLoginToken(user)
if err != nil {
global.GVA_LOG.Error("生成token失败!", zap.Error(err))
response.FailWithMessage("登录失败: "+err.Error(), c)
c.JSON(200, wechatResponse.ErrorResponseWithMsg(wechatResponse.ERROR_INTERNAL, "生成token失败"))
return
}
@@ -58,33 +67,65 @@ func (w *MiniUserApi) Login(c *gin.Context) {
Token: token,
}
response.OkWithDetailed(resp, "登录成功", c)
c.JSON(200, wechatResponse.SuccessResponseWithMsg(resp, "登录成功"))
}
// GetUserInfo 获取用户信息
// @Tags WechatMiniUser
// @Summary 获取用户信息
// @Description 获取小程序用户信息
// @Description 获取当前登录用户的详细信息
// @Accept json
// @Produce json
// @Param openid query string true "用户openid"
// @Success 200 {object} response.Response{data=model.WechatMiniUser} "获取成功"
// @Router /wechat/user/mini/userinfo [get]
// @Success 200 {object} wechatResponse.Response{data=wechatResponse.MiniUserInfoResponse} "获取成功"
// @Router /user/wechat/mini/userinfo [get]
func (w *MiniUserApi) GetUserInfo(c *gin.Context) {
openid := c.Query("openid")
// 从JWT token中获取用户信息
claims, exists := c.Get("user_claims")
if !exists {
c.JSON(200, wechatResponse.ErrorResponse(wechatResponse.ERROR_UNAUTHORIZED))
return
}
userClaims, ok := claims.(*systemReq.AppUserClaims)
if !ok {
c.JSON(200, wechatResponse.ErrorResponse(wechatResponse.ERROR_TOKEN_INVALID))
return
}
openid := userClaims.AppBaseClaims.OpenID
if openid == "" {
response.FailWithMessage("openid不能为空", c)
c.JSON(200, wechatResponse.ErrorResponse(wechatResponse.ERROR_WX_OPENID_EMPTY))
return
}
user, err := miniService.GetUserInfo(openid)
if err != nil {
global.GVA_LOG.Error("获取用户信息失败!", zap.Error(err))
response.FailWithMessage("获取失败: "+err.Error(), c)
if err.Error() == "用户不存在" {
c.JSON(200, wechatResponse.ErrorResponse(wechatResponse.ERROR_USER_NOT_FOUND))
} else {
c.JSON(200, wechatResponse.ErrorResponseWithMsg(wechatResponse.ERROR_INTERNAL, err.Error()))
}
return
}
response.OkWithData(user, c)
// 构造响应数据
resp := wechatResponse.MiniUserInfoResponse{
ID: user.ID,
OpenID: user.OpenID,
UnionID: user.UnionID,
NickName: user.Nickname,
Avatar: user.AvatarURL,
Phone: user.Phone,
Gender: user.Gender,
City: user.City,
Province: user.Province,
Country: user.Country,
CreateTime: user.CreatedAt.Format("2006-01-02 15:04:05"),
UpdateTime: user.UpdatedAt.Format("2006-01-02 15:04:05"),
}
c.JSON(200, wechatResponse.SuccessResponseWithMsg(resp, "获取成功"))
}
// UpdateUserInfo 更新用户信息
@@ -151,6 +192,59 @@ func (w *MiniUserApi) BindPhone(c *gin.Context) {
response.OkWithDetailed(user, "绑定成功", c)
}
// UpdatePhoneNumber 更新用户手机号
// @Tags WechatMiniUser
// @Summary 更新用户手机号
// @Description 通过微信手机号授权更新用户手机号
// @Accept json
// @Produce json
// @Param data body request.WxPhoneLoginRequest true "手机号授权参数"
// @Success 200 {object} response.Response{data=string} "更新成功"
// @Router /user/wechat/mini/phone-update [post]
func (w *MiniUserApi) UpdatePhoneNumber(c *gin.Context) {
var req request.WxPhoneLoginRequest
err := c.ShouldBindJSON(&req)
if err != nil {
response.FailWithMessage(err.Error(), c)
return
}
if req.EncryptedData == "" || req.IV == "" {
response.FailWithMessage("encryptedData和iv不能为空", c)
return
}
// 从 JWT token 中获取用户信息
claims, exists := c.Get("user_claims")
if !exists {
response.FailWithMessage("获取用户信息失败", c)
return
}
// 获取当前用户的信息
userClaims, ok := claims.(*systemReq.AppUserClaims)
if !ok {
response.FailWithMessage("用户信息格式错误", c)
return
}
// 直接从 claims 中获取 openid
openid := userClaims.AppBaseClaims.OpenID
if openid == "" {
response.FailWithMessage("用户 OpenID 不存在", c)
return
}
phoneNumber, err := miniService.UpdatePhoneByEncryption(openid, req.EncryptedData, req.IV)
if err != nil {
global.GVA_LOG.Error("更新手机号失败!", zap.Error(err))
response.FailWithMessage("更新失败: "+err.Error(), c)
return
}
response.OkWithDetailed(phoneNumber, "手机号更新成功", c)
}
// CheckUnionID 检查UnionID是否存在(为APP登录预留)
// @Tags WechatMiniUser
// @Summary 检查UnionID