148 lines
3.9 KiB
Go
148 lines
3.9 KiB
Go
package wx
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"io"
|
||
"mini_server/internal/config"
|
||
"mini_server/internal/dao"
|
||
"mini_server/internal/middleware/jwt"
|
||
"mini_server/internal/server/help"
|
||
"mini_server/internal/server/httpreply"
|
||
"mini_server/internal/server/user"
|
||
"net/http"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/sirupsen/logrus"
|
||
)
|
||
|
||
type LoginRequest struct {
|
||
Code string `json:"code" binding:"min=1"` // 临时会话登录code
|
||
}
|
||
|
||
type LoginReply struct {
|
||
Token string `json:"token"` // 返回登录成功的jwt token
|
||
UserInfo *user.UserInfo `json:"user_info"`
|
||
}
|
||
|
||
// 微信服务器,返回的数据结构
|
||
type WxHttpReply struct {
|
||
Errcode int32 `json:"errcode"` // 错误码
|
||
Errmsg string `json:"errmsg"` // 错误信息
|
||
OpenId string `json:"openid"` // 用户唯一标识
|
||
// Unionid string `json:"unionid"` // 用户在开放平台的唯一标识符,在满足 UnionID 下发条件的情况下会返回,详见微信 UnionID
|
||
SessionKey string `json:"session_key"` // 会话密钥
|
||
}
|
||
|
||
func WxLogin(c *gin.Context) {
|
||
reply := httpreply.NewDefaultReplyData()
|
||
defer httpreply.Reply(c, reply)
|
||
|
||
//解析请求参数
|
||
var request LoginRequest
|
||
if err := c.ShouldBindJSON(&request); err != nil {
|
||
reply.Status = http.StatusBadRequest
|
||
reply.Message = fmt.Sprintf("invalid json data, err:%v", err)
|
||
return
|
||
}
|
||
logrus.Tracef("微信登录,请求参数:%v", request)
|
||
|
||
// 从微信查询openId
|
||
openId, err := get_wx_login_open_id(request.Code)
|
||
if err != nil {
|
||
logrus.Errorf("请求微信获取OpenId失败,err:%v", err)
|
||
reply.Status = http.StatusServiceUnavailable
|
||
reply.Message = "第三方服务错误"
|
||
return
|
||
}
|
||
|
||
// 首先查询,是否存在
|
||
data, err := dao.User_WX_Query(openId)
|
||
if err != nil {
|
||
logrus.Errorf("微信登录,数据库查询失败,err:%v", err)
|
||
reply.Status = http.StatusInternalServerError
|
||
reply.Message = "用户查询失败"
|
||
return
|
||
}
|
||
|
||
if data == nil { // 用户不存在,则需要添加创建
|
||
|
||
default_wx_username, err := get_default_wx_username()
|
||
if err != nil {
|
||
logrus.Errorf("生成微信默认用户名失败,err:%v", err)
|
||
reply.Status = http.StatusInternalServerError
|
||
reply.Message = "生成微信默认用户名失败"
|
||
return
|
||
}
|
||
|
||
data = &dao.User{
|
||
AvatarId: "",
|
||
OpenId: openId,
|
||
Username: default_wx_username, // 默认名称
|
||
Persona: "{}",
|
||
Tags: "{}",
|
||
}
|
||
|
||
if _, err = dao.User_WX_Insert(data); err != nil {
|
||
logrus.Errorf("微信登录,数据库用户添加失败,err:%v", err)
|
||
reply.Status = http.StatusInternalServerError
|
||
reply.Message = "用户添加失败"
|
||
return
|
||
}
|
||
}
|
||
|
||
// 生成token
|
||
token, err := jwt.CreateToken(data)
|
||
if err != nil {
|
||
logrus.Errorf("微信登录,生成token失败,err:%v", err)
|
||
reply.Status = http.StatusInternalServerError
|
||
reply.Message = "token生成失败"
|
||
return
|
||
}
|
||
|
||
// 返回用户信息
|
||
var info user.UserInfo
|
||
user.Copy_User_Info(data, &info)
|
||
loginReply := LoginReply{
|
||
Token: token,
|
||
UserInfo: &info,
|
||
}
|
||
reply.Data = &loginReply
|
||
logrus.Tracef("微信登录成功,应答:%v", reply)
|
||
}
|
||
|
||
func get_wx_login_open_id(code string) (string, error) {
|
||
//接口请求url拼接
|
||
url := config.WeiXin.AppUrl(code)
|
||
|
||
// 转发请求到微信接口
|
||
resp, err := http.Get(url)
|
||
if err != nil {
|
||
return "", fmt.Errorf("请求微信登录接口失败,err:%v", err)
|
||
}
|
||
defer resp.Body.Close()
|
||
|
||
// 读取数据
|
||
body, err := io.ReadAll(resp.Body)
|
||
if err != nil {
|
||
return "", fmt.Errorf("读取微信登录应答数据失败,err:%v", err)
|
||
}
|
||
|
||
// 解码数据并赋值给返回的respData
|
||
respData := new(WxHttpReply)
|
||
json.Unmarshal(body, &respData)
|
||
|
||
openId := respData.OpenId
|
||
// 检测openid是否为空
|
||
if openId == "" {
|
||
return "", fmt.Errorf("读取微信登录应答数据openId为空")
|
||
}
|
||
return openId, nil
|
||
}
|
||
|
||
// 注册时返回随机名称
|
||
func get_default_wx_username() (string, error) {
|
||
id := help.GetUniqueIdEachSecond()
|
||
return "微信用户" + id, nil
|
||
}
|