You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

151 lines
4.2 KiB

4 years ago
package vend
import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"io/ioutil"
"net/http"
"recook/internal/back"
"recook/internal/dbc"
"recook/internal/define"
"recook/internal/model/vend"
"recook/tools"
"time"
)
const WxMiniUserOpenIDUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=%v&secret=%v&js_code=%v&grant_type=authorization_code"
type miniLoginParam struct {
AuthCode string `json:"auth_code" validator:"required"`
}
type openidResp struct {
OpenID string `json:"openid" validate:"required"`
UnionId string `json:"unionId" validate:"required"`
SessionKey string `json:"session_key"`
ErrMsg string `json:"errmsg"`
}
//通过小程序登录
func LoginByMiniProgram(c *gin.Context) {
var p miniLoginParam
if err := tools.Params(&p, c); err != nil {
back.Fail(c, err.Error())
return
}
response, err := http.Get(fmt.Sprintf(WxMiniUserOpenIDUrl, define.WxMiniProgramAppID, define.WxMiniProgramAppSecret, p.AuthCode))
if err != nil {
back.Err(c, err.Error())
return
}
defer func() { _ = response.Body.Close() }()
body, err := ioutil.ReadAll(response.Body)
if err != nil {
back.Fail(c, err.Error())
return
}
var resp openidResp
if err = json.Unmarshal(body, &resp); err != nil {
back.Fail(c, err.Error())
return
}
if len(resp.ErrMsg) > 0 {
back.Fail(c, "微信授权失败"+resp.ErrMsg)
return
}
//将openid信息插入到数据库
var gysUsersThird vend.GysUsersThird
dbc.DB.First(&gysUsersThird, "`type` = ? and code=?", vend.GysUsersThirdTypeWxApp, resp.OpenID)
if gysUsersThird.Id <= 0 {
gysUsersThird.Code = resp.OpenID
gysUsersThird.Type = vend.GysUsersThirdTypeWxApp
dbc.DB.Create(&gysUsersThird)
}
var sessionId = tools.MD5(resp.OpenID)
dbc.Rds.Set(fmt.Sprintf("wxapp:session_key:%v:%v", define.WxMiniProgramAppID, resp.OpenID), resp.SessionKey, time.Hour*24)
if gysUsersThird.UserId > 0 {
// 缓存session_key 1天
dbc.Rds.Set(fmt.Sprintf("wxapp:login:gys:%v:gysid", gysUsersThird.UserId), sessionId, time.Hour*24)
}
//下面返回的信息,会在以后的请求头中。
back.Suc(c, "", gin.H{
"session_id": sessionId,
"gys_id": gysUsersThird.UserId,
"openId": resp.OpenID,
})
return
}
type argsCrypto struct {
EncryptedData string `json:"encryptedData" form:"encryptedData"`
Iv string `json:"iv" form:"iv"`
OpenId string `json:"openId" form:"openId"`
}
type UserPhone struct {
CountryCode string `json:"countryCode"`
PhoneNumber string `json:"phoneNumber"`
PurePhoneNumber string `json:"purePhoneNumber"`
Watermark struct {
Appid string `json:"appid"`
Timestamp int64 `json:"timestamp"`
} `json:"watermark"`
}
// @Style 设置手机号
func Phone(c *gin.Context) {
args := argsCrypto{}
if err := tools.Params(&args, c); err != nil {
back.Fail(c, err.Error())
return
}
gysUserThird := vend.GysUsersThird{}
dbc.DB.First(&gysUserThird, "`type` = ? and code = ?", vend.GysUsersThirdTypeWxApp, args.OpenId)
if gysUserThird.UserId > 0 {
back.Suc(c, "操作成功", gin.H{
"gys_id": gysUserThird.UserId,
})
return
}
sessionKey := dbc.Rds.Get(fmt.Sprintf("wxapp:session_key:%v:%v", define.WxMiniProgramAppID, args.OpenId)).Val()
decodeString, _ := base64.StdEncoding.DecodeString(args.EncryptedData)
key, _ := base64.StdEncoding.DecodeString(sessionKey)
iv, _ := base64.StdEncoding.DecodeString(args.Iv)
jsonData, _ := tools.AesCBCDncrypt(decodeString, key, iv)
userPhone := UserPhone{}
json.Unmarshal(jsonData, &userPhone)
if userPhone.Watermark.Appid != define.WxMiniProgramAppID {
back.Fail(c, "登录超时")
return
}
vendData := vend.GysUsers{}
dbc.DB.First(&vendData, "username = ?", userPhone.PhoneNumber)
if vendData.ID <= 0 {
vendData.Username = userPhone.PhoneNumber
vendData.Password = tools.RandStr(6, "0123456789")
dbc.DB.Create(&vendData)
if vendData.ID <= 0 {
back.Fail(c, "网络异常")
return
}
}
dbc.DB.Model(&gysUserThird).Updates(&vend.GysUsersThird{
UserId: vendData.ID,
})
// 缓存session_key 1天
var sessionId = tools.MD5(args.OpenId)
dbc.Rds.Set(fmt.Sprintf("wxapp:login:gys:%v:gysid", vendData.ID), sessionId, time.Hour*24)
back.Suc(c, "操作成功", gin.H{
"gys_id": vendData.ID,
})
}