wxshare.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package youngee_talent_service
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "errors"
  6. "fmt"
  7. "io/ioutil"
  8. "net/http"
  9. "strings"
  10. "youngmini_server/app/model/youngee_talent_model"
  11. "github.com/gogf/gf/encoding/gjson"
  12. "github.com/gogf/gf/frame/g"
  13. "github.com/gogf/gf/net/ghttp"
  14. )
  15. const (
  16. //获取调用微信小程序接口的access_token 7200s有效期
  17. accessTokenUrlFormat = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
  18. //获取小程序码
  19. qrCodeUrlFormat = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s"
  20. wxAccesssTokenKey = "wx_access_token"
  21. )
  22. // getAndCacheWxAccessToken 获取分享的微信二维码。如果没有token,则获取并且缓存获取并缓存微信的access token
  23. func getAndCacheWxAccessToken() (string, error) {
  24. appId := g.Config().GetString("miniapp.appid")
  25. secret := g.Config().GetString("miniapp.appsecret")
  26. //获取access_token的网址
  27. url := fmt.Sprintf(accessTokenUrlFormat, appId, secret)
  28. resp, err := http.Get(url)
  29. if err != nil {
  30. return "", errors.New("request access token failed")
  31. }
  32. defer resp.Body.Close()
  33. // 解析微信服务端返回的信息
  34. var accessTokenRes youngee_talent_model.WxAccessTokenResponse
  35. decoder := json.NewDecoder(resp.Body)
  36. if err = decoder.Decode(&accessTokenRes); err != nil {
  37. return "", errors.New("decode wx response failed")
  38. }
  39. if accessTokenRes.Errcode != 0 {
  40. return "", errors.New("request access token failed")
  41. }
  42. // 缓存获取的access token,比微信返回的有效时间短5分钟失效 SETEX key expiretime value
  43. _, err = g.Redis().Do("SETEX", wxAccesssTokenKey, accessTokenRes.ExpiresIn-300, accessTokenRes.AccessToken)
  44. return accessTokenRes.AccessToken, nil
  45. }
  46. func RequestShareInfo(r *ghttp.Request) *TalentHttpResult {
  47. fmt.Println("*****into******")
  48. var requestArg *youngee_talent_model.ShareRequest
  49. if err := r.ParseForm(&requestArg); err != nil {
  50. return &TalentHttpResult{Code: -1, Msg: "param error"}
  51. }
  52. // 获取access_token
  53. var accessToken string
  54. //DoVar:是一个 gredis 的方法,用于执行 Redis 命令并返回一个 gvar.Var 类型的值,这个类型可以方便地进行各种类型转换。
  55. accessTokenVar, err := g.Redis().DoVar("GET", "wx_access_token")
  56. if err != nil {
  57. return &TalentHttpResult{Code: -2, Msg: "get access token from cache err"}
  58. }
  59. if accessTokenVar.IsEmpty() {
  60. // 如果没有缓存的access token 则获取并缓存
  61. accessToken, err = getAndCacheWxAccessToken()
  62. } else {
  63. // 取缓存的access token
  64. accessToken = accessTokenVar.String()
  65. }
  66. accessToken = accessTokenVar.String()
  67. fmt.Println("*****wx_access_token******", accessToken)
  68. qrRequest := youngee_talent_model.WxQrCodeRequest{
  69. Scene: requestArg.Scene,
  70. Page: requestArg.Page,
  71. Width: 430,
  72. CheckPath: false,
  73. EnvVersion: "release",
  74. }
  75. jsonBody, err := gjson.Encode(qrRequest)
  76. if err != nil {
  77. return &TalentHttpResult{Code: -3, Msg: ""}
  78. }
  79. qrCodeUrl := fmt.Sprintf(qrCodeUrlFormat, accessToken)
  80. resp, err := http.Post(qrCodeUrl, "application/json; charset=utf8", bytes.NewReader(jsonBody))
  81. if err != nil {
  82. return &TalentHttpResult{Code: -4, Msg: "request from wx server failed"}
  83. }
  84. defer resp.Body.Close()
  85. var qrcodeBytes []byte
  86. switch header := resp.Header.Get("content-Type"); {
  87. case strings.HasPrefix(header, "application/json"):
  88. // 如果返回的是json结构,说明发生错误
  89. var qrResponse *youngee_talent_model.WxQrCodeResponse
  90. decoder := json.NewDecoder(resp.Body)
  91. if err = decoder.Decode(&qrResponse); err != nil {
  92. return &TalentHttpResult{Code: -5, Msg: "request qrcode failed"}
  93. }
  94. return &TalentHttpResult{Code: -6, Msg: "wx request error", Data: qrResponse}
  95. case strings.HasPrefix(header, "image"):
  96. qrcodeBytes, err = ioutil.ReadAll(resp.Body)
  97. if err != nil {
  98. return &TalentHttpResult{Code: -6, Msg: "read resp body error"}
  99. }
  100. }
  101. return &TalentHttpResult{Code: 0, Msg: "success", Data: qrcodeBytes}
  102. }