123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114 |
- package youngee_talent_service
- import (
- "bytes"
- "encoding/json"
- "errors"
- "fmt"
- "io/ioutil"
- "net/http"
- "strings"
- "youngmini_server/app/model/talent_model"
- "github.com/gogf/gf/encoding/gjson"
- "github.com/gogf/gf/frame/g"
- "github.com/gogf/gf/net/ghttp"
- )
- const (
- accessTokenUrlFormat = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
- qrCodeUrlFormat = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s"
- wxAccesssTokenKey = "wx_access_token"
- )
- // getAndCacheWxAccessToken 获取并缓存微信的access token
- func getAndCacheWxAccessToken() (string, error) {
- appId := g.Config().GetString("miniapp.appid")
- secret := g.Config().GetString("miniapp.appsecret")
- url := fmt.Sprintf(accessTokenUrlFormat, appId, secret)
- resp, err := http.Get(url)
- if err != nil {
- return "", errors.New("request access token failed")
- }
- defer resp.Body.Close()
- // 解析微信服务端返回的信息
- var accessTokenRes talent_model.WxAccessTokenResponse
- decoder := json.NewDecoder(resp.Body)
- if err = decoder.Decode(&accessTokenRes); err != nil {
- return "", errors.New("decode wx response failed")
- }
- if accessTokenRes.Errcode != 0 {
- return "", errors.New("request access token failed")
- }
- // 缓存获取的access token,比微信返回的有效时间短5分钟失效
- _, err = g.Redis().Do("SETEX", wxAccesssTokenKey, accessTokenRes.ExpiresIn-300, accessTokenRes.AccessToken)
- return accessTokenRes.AccessToken, nil
- }
- func RequestShareInfo(r *ghttp.Request) *TalentHttpResult {
- var requestArg *talent_model.ShareRequest
- if err := r.ParseForm(&requestArg); err != nil {
- return &TalentHttpResult{Code: -1, Msg: "param error"}
- }
- // 获取access_token
- var accessToken string
- accessTokenVar, err := g.Redis().DoVar("GET", "wx_access_token")
- if err != nil {
- return &TalentHttpResult{Code: -2, Msg: "get access token from cache err"}
- }
- if accessTokenVar.IsEmpty() {
- // 如果没有缓存的access token 则获取并缓存
- accessToken, err = getAndCacheWxAccessToken()
- } else {
- // 取缓存的access token
- accessToken = accessTokenVar.String()
- }
- qrRequest := talent_model.WxQrCodeRequest{
- Scene: requestArg.Scene,
- Page: requestArg.Page,
- Width: 430,
- CheckPath: false,
- EnvVersion: "release",
- }
- jsonBody, err := gjson.Encode(qrRequest)
- if err != nil {
- return &TalentHttpResult{Code: -3, Msg: ""}
- }
- qrCodeUrl := fmt.Sprintf(qrCodeUrlFormat, accessToken)
- resp, err := http.Post(qrCodeUrl, "application/json; charset=utf8", bytes.NewReader(jsonBody))
- if err != nil {
- return &TalentHttpResult{Code: -4, Msg: "request from wx server failed"}
- }
- defer resp.Body.Close()
- var qrcodeBytes []byte
- switch header := resp.Header.Get("content-Type"); {
- case strings.HasPrefix(header, "application/json"):
- // 如果返回的是json结构,说明发生错误
- var qrResponse *talent_model.WxQrCodeResponse
- decoder := json.NewDecoder(resp.Body)
- if err = decoder.Decode(&qrResponse); err != nil {
- return &TalentHttpResult{Code: -5, Msg: "request qrcode failed"}
- }
- return &TalentHttpResult{Code: -6, Msg: "wx request error", Data: qrResponse}
- case strings.HasPrefix(header, "image"):
- qrcodeBytes, err = ioutil.ReadAll(resp.Body)
- if err != nil {
- return &TalentHttpResult{Code: -6, Msg: "read resp body error"}
- }
- }
- return &TalentHttpResult{Code: 0, Msg: "success", Data: qrcodeBytes}
- }
|