From 19fea1ca914ecfe301a2bca44c798202a06e84d7 Mon Sep 17 00:00:00 2001 From: mayiming <1627832236@qq.com> Date: Sun, 10 Aug 2025 02:10:01 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E7=94=A8=E6=88=B7=E7=99=BB?= =?UTF-8?q?=E5=BD=95=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- controllers/user/userLogin.go | 116 ++++++++++++++++++++++++++++++++++ model/usermodel/loginmodel.go | 26 ++++++++ 2 files changed, 142 insertions(+) create mode 100644 controllers/user/userLogin.go create mode 100644 model/usermodel/loginmodel.go diff --git a/controllers/user/userLogin.go b/controllers/user/userLogin.go new file mode 100644 index 0000000..acc9a96 --- /dev/null +++ b/controllers/user/userLogin.go @@ -0,0 +1,116 @@ +package user + +import ( + "encoding/json" + "fmt" + "github.com/gin-gonic/gin" + "net/http" + "net/url" + "time" + "toutoukan/config" + "toutoukan/init/databaseInit" + "toutoukan/model/usermodel" + "toutoukan/utill" +) + +const wxLoginURL = "https://api.weixin.qq.com/sns/jscode2session" + +func UserLogin(c *gin.Context) { + fmt.Println("Request Body:", c.Request.Body) + var req usermodel.WxLoginM + if err := c.ShouldBindJSON(&req); err != nil { + c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) + } + fmt.Println("req:123") + fmt.Println(req.EncryptedData) + fmt.Println(req.Code) + fmt.Println(req.Iv) + fmt.Println("使用的appid:", config.Conf.WxID) + fmt.Println("使用的secret:", config.Conf.Wxsecret) + //----------------发送验证请求 + params := url.Values{} + params.Add("appid", config.Conf.WxID) + params.Add("secret", config.Conf.Wxsecret) + params.Add("js_code", req.Code) + params.Add("grant_type", "authorization_code") + requestURL := fmt.Sprintf("%s?%s", wxLoginURL, params.Encode()) + fmt.Println("微信接口请求URL:", requestURL) + + resp, err := http.Get(fmt.Sprintf("%s?%s", wxLoginURL, params.Encode())) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "调用微信登录接口失败: " + err.Error()}) + return + } + fmt.Println("微信登录返回结果:", resp.Body) + defer resp.Body.Close() + + // 解析微信返回结果 + var wxResp usermodel.WxLoginResponse + if err := json.NewDecoder(resp.Body).Decode(&wxResp); err != nil { + c.JSON(http.StatusInternalServerError, gin.H{"error": "解析微信登录响应失败: " + err.Error(), "code": "10026"}) + return + } + + // 检查微信返回的错误 + if wxResp.ErrCode != 0 { + c.JSON(http.StatusBadRequest, gin.H{ // http.StatusBadRequest 对应 400 + "error": fmt.Sprintf("微信登录失败: %s (错误码: %d)", wxResp.ErrCode, wxResp.ErrMsg), + "code": "10027", + }) + return + } + + // 到这里登录验证成功,获取到了openid和session_key + // 可以在这里进行后续处理,如: + // 1. 根据openid查询或创建用户 + // 2. 生成自定义登录态(如token)返回给客户端 + // 3. (可选)使用session_key、encryptedData和iv解密用户信息 + + openid := wxResp.OpenID + ctx := c.Request.Context() // 获取请求上下文,用于控制数据库操作超时 + + // 1. 查询用户是否存在 + var exists bool + query := "SELECT EXISTS(SELECT 1 FROM user_info WHERE uid = ? LIMIT 1)" + err = databaseInit.UserDB.QueryRowContext(ctx, query, openid).Scan(&exists) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "error": "查询用户存在性失败: " + err.Error(), + "code": "10029", + }) + return + } + + // 2. 如果用户不存在,插入新用户 + if !exists { + now := time.Now() + insertSQL := ` + INSERT INTO user_info ( + uid, gender,createdtime, updatedtime + ) VALUES (?, ?, ?,?) + ` + _, err := databaseInit.UserDB.ExecContext( + ctx, + insertSQL, + openid, // uid(使用微信 openid) + 2, + now, // createdtime + now, // updatedtime + ) + if err != nil { + c.JSON(http.StatusInternalServerError, gin.H{ + "error": "插入新用户失败: " + err.Error(), + "code": "10029", + }) + return + } + } + + token, err := utill.GenerateJWTAndStore(openid) + if err != nil { + c.JSON(500, gin.H{"error": "生成令牌失败", "code": "10036"}) + return + } + + c.JSON(http.StatusOK, gin.H{"result": "success", "error": nil, "code": "20001", "token": token}) +} diff --git a/model/usermodel/loginmodel.go b/model/usermodel/loginmodel.go new file mode 100644 index 0000000..b6b76e1 --- /dev/null +++ b/model/usermodel/loginmodel.go @@ -0,0 +1,26 @@ +package usermodel + +type LoginM struct { + Username string `json:"username"` + Password string `json:"password"` + Email string `json:"email"` +} + +type LoginRequest struct { + Username string `json:"username" binding:"required"` + Password string `json:"password" binding:"required"` + Email string `json:"email" binding:"required"` +} +type WxLoginM struct { + EncryptedData string `json:"encryptedData"` + Iv string `json:"iv"` + Code string `json:"code"` +} + +type WxLoginResponse struct { + OpenID string `json:"openid"` // 用户唯一标识 + SessionKey string `json:"session_key"` // 会话密钥 + UnionID string `json:"unionid"` // 用户在开放平台的唯一标识符(可选) + ErrCode int `json:"errcode"` // 错误码 + ErrMsg string `json:"errmsg"` // 错误信息 +}