micro-account/pkg/common/wechat/wechat.go
2025-02-20 16:18:23 +08:00

340 lines
7.8 KiB
Go

package wechat
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"github.com/fonchain_enterprise/micro-account/pkg/cache"
"github.com/fonchain_enterprise/micro-account/pkg/common/redis_key"
"io/ioutil"
"net/http"
"time"
)
type Wechat struct {
Appid string
AppSecret string
}
type OpenIDInfo struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token"`
Openid string `json:"openid"`
Scope string `json:"scope"`
IsSnapshotuser int `json:"is_snapshotuser"`
Unionid string `json:"unionid"`
Errmsg string `json:"errmsg"`
Errcode int `json:"errcode"`
}
type PhoneRes struct {
PhoneInfo *PhoneInfo `json:"phone_info"`
Errmsg string `json:"errmsg"`
Errcode int `json:"errcode"`
}
type CommonRes struct {
Errmsg string `json:"errmsg"`
Errcode int `json:"errcode"`
}
type PhoneInfo struct {
PhoneNumber string `json:"phoneNumber"`
PurePhoneNumber string `json:"purePhoneNumber"`
Errcode int `json:"errcode"`
}
type BoxOpenId struct {
Openid string `json:"openid"`
Errmsg string `json:"errmsg"`
Errcode int `json:"errcode"`
}
type BoxAccessToken struct {
AccessToken string `json:"access_token"`
ExpiresIn int `json:"expires_in"`
RefreshToken string `json:"refresh_token"`
Errmsg string `json:"errmsg"`
Errcode int `json:"errcode"`
}
func GetOpenID(appID, appSecret, code string) (openInfo *OpenIDInfo, err error) {
var openIDInfo *OpenIDInfo
str := "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
url := fmt.Sprintf(str, appID, appSecret, code)
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
return nil, err
}
body, err := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
if resp.StatusCode != 200 {
fmt.Printf("请求失败%d\n", resp.StatusCode)
return nil, errors.New(fmt.Sprintf("请求失败%d", resp.StatusCode))
}
fmt.Println("返回数据是", string(body))
err = json.Unmarshal(body, &openInfo)
if err != nil {
fmt.Println(err)
return nil, err
}
fmt.Println(openIDInfo)
return
}
func GetBoxPhone(appID, appSecret, code string) (string, error) {
accessToken, err := GetBoxAccessToken(appID, appSecret)
if err != nil {
return "", err
}
openInfo, err := getBoxPhone(accessToken, code)
fmt.Println("提示设呢么", openInfo, err)
if err != nil {
return "", err
}
fmt.Println("123123--123", openInfo)
fmt.Println(openInfo.Errmsg)
fmt.Println(openInfo.Errcode)
if openInfo.Errcode != 40001 && openInfo.PhoneInfo != nil {
return openInfo.PhoneInfo.PurePhoneNumber, nil
}
fmt.Println("不顶用")
cache.RedisClient.Del(redis_key.GetBoxAccessToken(appID))
return getBoxPhoneAgain(appID, appSecret, code)
}
func getBoxPhoneAgain(appID, appSecret, code string) (string, error) {
accessToken, err := GetBoxAccessToken(appID, appSecret)
if err != nil {
return "", err
}
openInfo, err := getBoxPhone(accessToken, code)
fmt.Println("提示设呢么", openInfo, err)
if err != nil {
return "", err
}
fmt.Println("123123--123", openInfo)
fmt.Println(openInfo.Errmsg)
fmt.Println(openInfo.Errcode)
if openInfo.Errcode != 40001 && openInfo.PhoneInfo != nil {
return openInfo.PhoneInfo.PurePhoneNumber, nil
}
return "", errors.New(openInfo.Errmsg)
}
// GetBoxOpenID 获取小程序的openid
func GetBoxOpenID(appID, appSecret, code string) (string, error) {
/*
accessToken, err := GetBoxAccessToken(appID, appSecret)
if err != nil {
return "", err
}
*/
openInfo, err := getLoginOpenIdByCode(appID, appSecret, code)
fmt.Println("提示设呢么", openInfo, err)
if err != nil {
return "", err
}
return openInfo, nil
//cache.RedisClient.Del(redis_key.GetBoxAccessToken(appID))
//return getBoxOpenIDAgain(appID, appSecret, code)
}
func getBoxOpenIDAgain(appID, appSecret, code string) (string, error) {
accessToken, err := GetBoxAccessToken(appID, appSecret)
if err != nil {
return "", err
}
openInfo, err := getOpenIdByCode(accessToken, code)
if err != nil {
return "", err
}
if openInfo.Errcode != 0 {
return "", errors.New(openInfo.Errmsg)
}
return openInfo.Openid, nil
}
func getLoginOpenIdByCode(appId, appSecret, code string) (string, error) {
str := "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
url := fmt.Sprintf(str, appId, appSecret, code)
resp, err := http.Get(url)
if err != nil {
return "", err
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if resp.StatusCode != 200 {
fmt.Printf("请求失败%d\n", resp.StatusCode)
return "", errors.New(fmt.Sprintf("请求失败%d", resp.StatusCode))
}
fmt.Println("2--返回数据是", string(body))
var openInfo OpenIDInfo
err = json.Unmarshal(body, &openInfo)
if err != nil {
fmt.Println(err)
return "", err
}
if openInfo.Errcode != 0 {
return "", errors.New(openInfo.Errmsg)
}
return openInfo.Openid, err
}
func getOpenIdByCode(accessToken, code string) (openInfo *OpenIDInfo, err error) {
url := "https://api.weixin.qq.com/wxa/getpluginopenpid?access_token=" + accessToken
// 创建要发送的数据
data := []byte(fmt.Sprintf(`{"code": "%s"}`, code))
fmt.Println("1-------------", string(data))
fmt.Println("1-------------", accessToken)
// 发送POST请求
resp, err := http.Post(url, "application/json", bytes.NewBuffer(data))
if err != nil {
fmt.Println("发送请求失败:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if resp.StatusCode != 200 {
fmt.Printf("请求失败%d\n", resp.StatusCode)
return nil, errors.New(fmt.Sprintf("请求失败%d", resp.StatusCode))
}
fmt.Println("2--返回数据是", string(body))
err = json.Unmarshal(body, &openInfo)
if err != nil {
fmt.Println(err)
return nil, err
}
return openInfo, err
}
// getBoxPhone 获取手机号
func getBoxPhone(accessToken, code string) (res *PhoneRes, err error) {
url := "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + accessToken
// 创建要发送的数据
data := []byte(fmt.Sprintf(`{"code": "%s"}`, code))
// 发送POST请求
resp, err := http.Post(url, "application/json", bytes.NewBuffer(data))
if err != nil {
fmt.Println("发送请求失败:", err)
return
}
defer resp.Body.Close()
body, err := ioutil.ReadAll(resp.Body)
if resp.StatusCode != 200 {
fmt.Printf("请求失败%d\n", resp.StatusCode)
return nil, errors.New(fmt.Sprintf("请求失败%d", resp.StatusCode))
}
fmt.Println("2--返回数据是", string(body))
err = json.Unmarshal(body, &res)
if err != nil {
fmt.Println(err)
return nil, err
}
return res, err
}
func GetBoxAccessToken(appID, appSecret string) (string, error) {
accessToken := cache.RedisClient.Get(redis_key.GetBoxAccessToken(appID)).Val()
if accessToken != "" {
return accessToken, nil
}
var openIDInfo *BoxAccessToken
str := "https://api.weixin.qq.com/cgi-bin/token?appid=%s&secret=%s&grant_type=client_credential"
url := fmt.Sprintf(str, appID, appSecret)
resp, err := http.Get(url)
if err != nil {
return "", err
}
body, err := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
if resp.StatusCode != 200 {
fmt.Printf("请求失败%d\n", resp.StatusCode)
return "", errors.New(fmt.Sprintf("请求失败%d", resp.StatusCode))
}
fmt.Println("返回数据是", string(body))
err = json.Unmarshal(body, &openIDInfo)
if err != nil {
fmt.Println(err)
return "", err
}
//记录下
fmt.Println("123123123", redis_key.GetBoxAccessToken(appID), openIDInfo.AccessToken)
fmt.Println(redis_key.GetBoxAccessToken(appID), openIDInfo.AccessToken)
cache.RedisClient.Set(redis_key.GetBoxAccessToken(appID), openIDInfo.AccessToken, 6000*time.Second)
return openIDInfo.AccessToken, nil
}