82 lines
2.0 KiB
Go
82 lines
2.0 KiB
Go
package applet
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"time"
|
|
|
|
"management/internal/config"
|
|
"management/internal/pkg/fetcher"
|
|
"management/internal/pkg/redis"
|
|
)
|
|
|
|
// var appletLoginErrs = map[int]string{
|
|
// -1: "系统繁忙",
|
|
// 40029: "js_code无效",
|
|
// 45011: "API调用太频繁,请稍候再试",
|
|
// 40226: "高风险等级用户,小程序登录拦截",
|
|
// }
|
|
|
|
type AppletLoginResponse struct {
|
|
OpenID string `json:"openid"`
|
|
SessionKey string `json:"session_key"`
|
|
UnionID string `json:"unionid"`
|
|
ErrCode int `json:"errcode"`
|
|
ErrMsg string `json:"errmsg"`
|
|
}
|
|
|
|
func AppletLogin(code string) (*AppletLoginResponse, error) {
|
|
url := fmt.Sprintf("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
|
|
config.File.Applet.AppID, config.File.Applet.AppSecret, code)
|
|
response, status, err := fetcher.Get(url, time.Second*3)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if status != 200 {
|
|
return nil, errors.New("请求失败")
|
|
}
|
|
|
|
var res AppletLoginResponse
|
|
err = json.Unmarshal(response, &res)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &res, nil
|
|
}
|
|
|
|
type accessTokenResponse struct {
|
|
AccessToken string `json:"access_token"`
|
|
ExpiresIn int `json:"expires_in"`
|
|
}
|
|
|
|
func GetAccessToken(ctx context.Context) (string, error) {
|
|
key := "token:" + config.File.Applet.AppID
|
|
token, err := redis.Get(ctx, key)
|
|
if err == nil && len(token) > 0 {
|
|
return token, nil
|
|
}
|
|
|
|
url := fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",
|
|
config.File.Applet.AppID, config.File.Applet.AppSecret)
|
|
response, status, err := fetcher.Get(url, time.Second*3)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
if status != 200 {
|
|
return "", errors.New("获取access token失败")
|
|
}
|
|
|
|
var res accessTokenResponse
|
|
err = json.Unmarshal(response, &res)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
redis.Set(ctx, key, res.AccessToken, time.Duration(res.ExpiresIn-100)*time.Second)
|
|
return res.AccessToken, nil
|
|
}
|