123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- package wechat
- import (
- "encoding/json"
- "eta/eta_mini_ht_api/common/component/config"
- logger "eta/eta_mini_ht_api/common/component/log"
- "eta/eta_mini_ht_api/common/component/wechat/we_http"
- "eta/eta_mini_ht_api/common/contants"
- "eta/eta_mini_ht_api/common/exception"
- "eta/eta_mini_ht_api/common/utils/client"
- "fmt"
- "io"
- "net/url"
- "sync"
- )
- const (
- baseURL = "https://api.weixin.qq.com"
- codeAPI = "/sns/jscode2session"
- )
- const (
- // WeChatServerError 微信服务器错误时返回返回消息
- )
- var (
- wechatClient *Client
- once sync.Once
- )
- type Client struct {
- // HTTP请求客户端
- client *client.HttpClient
- // 小程序后台配置: 小程序ID
- appid string
- // 小程序后台配置: 小程序密钥
- secret string
- }
- func GetInstance() *Client {
- once.Do(func() {
- wechatConf, ok := config.GetConfig(contants.WECHAT).(*config.WechatConfig)
- if !ok {
- // 处理错误情况,比如记录日志或返回错误信息
- logger.Info("加载wechat配置失败")
- return // 或者采取其他适当的错误处理措施
- }
- // 默认配置
- wechatClient = NewClient(wechatConf.GetAppid(), wechatConf.GetSecret(), WithHttpClient(client.DefaultClient()))
- })
- return wechatClient
- }
- // AccessTokenGetter 用户自定义获取access_token的方法
- type AccessTokenGetter func(appid, secret string) (token string, expireIn uint)
- // NewClient 初始化客户端并用自定义配置替换默认配置
- func NewClient(appid, secret string, opts ...func(*Client)) *Client {
- cli := &Client{
- appid: appid,
- secret: secret,
- }
- // 执行额外的配置函数
- for _, fn := range opts {
- fn(cli)
- }
- return cli
- }
- // WithHttpClient 自定义 HTTP Client
- func WithHttpClient(hc *client.HttpClient) func(*Client) {
- return func(cli *Client) {
- cli.client = hc
- }
- }
- type loginResponse struct {
- we_http.BaseResponse
- we_http.LoginResponse
- }
- // Login 小程序登录
- func (cli *Client) Login(code string) (wxUser WxUser, err error) {
- if code == "" {
- err = exception.New(exception.WeChatCodeEmpty)
- return
- }
- api, err := code2url(cli.appid, cli.secret, code)
- if err != nil {
- err = exception.New(exception.WeChatIllegalRequest)
- return
- }
- //请求微信接口
- res, err := cli.client.Get(api)
- if err != nil || res.StatusCode != 200 {
- if res != nil {
- logger.Error("获取微信用户信息失败:%v", res.Status)
- } else {
- logger.Error("获取微信用户信息失败:%v", err)
- }
- err = exception.New(exception.WeChatServerError)
- return
- }
- defer func(Body io.ReadCloser) {
- Body.Close()
- }(res.Body)
- var data loginResponse
- err = json.NewDecoder(res.Body).Decode(&data)
- if err != nil {
- logger.Error("解析微信应答失败:%v", err)
- err = exception.New(exception.WeChatResponseError)
- return
- }
- if data.Errcode != 0 {
- logger.Error("获取用户信息失败:%v", data.Errmsg)
- err = exception.New(exception.WechatUserInfoFailed)
- return
- }
- wxUser = WxUser{
- OpenId: data.LoginResponse.OpenID,
- UnionId: data.LoginResponse.UnionID,
- }
- return
- }
- type WxUser struct {
- OpenId string
- UnionId string
- }
- // 拼接 获取 session_key 的 URL
- func code2url(appID, secret, code string) (string, error) {
- url, err := url.Parse(baseURL + codeAPI)
- if err != nil {
- return "", err
- }
- query := url.Query()
- query.Set("appid", appID)
- query.Set("secret", secret)
- query.Set("js_code", code)
- query.Set("grant_type", "authorization_code")
- url.RawQuery = query.Encode()
- return url.String(), nil
- }
- type WxUserInfo struct {
- OpenId string `json:"openid"`
- AccessToken string `json:"access_token"`
- RefreshToken string `json:"refresh_token"`
- Scope string `json:"scope"`
- ErrCode int
- ErrMsg string
- }
- // Login 小程序登录
- func (cli *Client) GzhLogin(code string) (wxUser WxUser, err error) {
- if code == "" {
- err = exception.New(exception.WeChatCodeEmpty)
- return
- }
- api, err := code2url(cli.appid, cli.secret, code)
- if err != nil {
- err = exception.New(exception.WeChatIllegalRequest)
- return
- }
- //请求微信接口
- res, err := cli.client.Get(api)
- defer func(Body io.ReadCloser) {
- Body.Close()
- }(res.Body)
- if err != nil || res.StatusCode != 200 {
- logger.Error("获取微信用户信息失败:%v", res.Status)
- err = exception.New(exception.WeChatServerError)
- return
- }
- var data loginResponse
- err = json.NewDecoder(res.Body).Decode(&data)
- if err != nil {
- logger.Error("解析微信应答失败:%v", err)
- err = exception.New(exception.WeChatResponseError)
- return
- }
- fmt.Println(data)
- if data.Errcode != 0 {
- logger.Error("获取用户信息失败:%v", data.Errmsg)
- err = exception.New(exception.WechatUserInfoFailed)
- return
- }
- wxUser = WxUser{
- OpenId: data.LoginResponse.OpenID,
- UnionId: data.LoginResponse.UnionID,
- }
- return
- }
|