jssdk.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. package jssdk
  2. import (
  3. "dashoo.cn/opms_libary/plugin/wechat/context"
  4. "encoding/json"
  5. "fmt"
  6. "github.com/gogf/gf/frame/g"
  7. "github.com/gogf/gf/os/gtime"
  8. "github.com/gogf/gf/util/grand"
  9. "time"
  10. )
  11. const getTicketURL = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=%s&type=jsapi"
  12. // Js struct
  13. type Js struct {
  14. *context.Context
  15. }
  16. // Config 返回给用户jssdk配置信息
  17. type Config struct {
  18. AppID string `json:"app_id"`
  19. Timestamp int64 `json:"timestamp"`
  20. NonceStr string `json:"nonce_str"`
  21. Signature string `json:"signature"`
  22. }
  23. //ToMap wx.config中的配置
  24. func (c *Config) ToMap() (cfg map[string]interface{}) {
  25. cfg = make(map[string]interface{})
  26. cfg["appId"] = c.AppID
  27. cfg["timestamp"] = c.Timestamp
  28. cfg["nonceStr"] = c.NonceStr
  29. cfg["signature"] = c.Signature
  30. return
  31. }
  32. // resTicket 请求jsapi_tikcet返回结果
  33. type resTicket struct {
  34. context.WxError
  35. Ticket string `json:"ticket"`
  36. ExpiresIn int64 `json:"expires_in"`
  37. }
  38. //NewJs init
  39. func NewJs(context *context.Context) *Js {
  40. js := new(Js)
  41. js.Context = context
  42. return js
  43. }
  44. //GetConfig 获取jssdk需要的配置参数
  45. //uri 为当前网页地址
  46. func (js *Js) GetConfig(url string) (config *Config, err error) {
  47. config = new(Config)
  48. var ticketStr string
  49. ticketStr, err = js.GetTicket()
  50. if err != nil {
  51. return
  52. }
  53. nonceStr := grand.S(16, false)
  54. timestamp := gtime.Now().Unix()
  55. str := fmt.Sprintf("jsapi_ticket=%s&noncestr=%s&timestamp=%d&url=%s", ticketStr, nonceStr, timestamp, url)
  56. sigStr := context.Sign(str)
  57. config.AppID = js.AppID
  58. config.NonceStr = nonceStr
  59. config.Timestamp = timestamp
  60. config.Signature = sigStr
  61. return
  62. }
  63. //GetTicket 获取jsapi_tocket
  64. func (js *Js) GetTicket() (ticketStr string, err error) {
  65. js.GetJsAPITicketLock().Lock()
  66. defer js.GetJsAPITicketLock().Unlock()
  67. //先从cache中取
  68. jsAPITicketCacheKey := fmt.Sprintf("jsapi_ticket_%s", js.AppID)
  69. val, _ := js.Cache.Get(jsAPITicketCacheKey)
  70. if val != nil {
  71. ticketStr = val.(string)
  72. return
  73. }
  74. var ticket resTicket
  75. ticket, err = js.getTicketFromServer()
  76. if err != nil {
  77. return
  78. }
  79. ticketStr = ticket.Ticket
  80. return
  81. }
  82. //getTicketFromServer 强制从服务器中获取ticket
  83. func (js *Js) getTicketFromServer() (ticket resTicket, err error) {
  84. var accessToken string
  85. accessToken, err = js.GetAccessToken()
  86. if err != nil {
  87. return
  88. }
  89. var response []byte
  90. url := fmt.Sprintf(getTicketURL, accessToken)
  91. response = g.Client().GetBytes(url)
  92. err = json.Unmarshal(response, &ticket)
  93. if err != nil {
  94. return
  95. }
  96. if ticket.Code != 0 {
  97. err = fmt.Errorf("getTicket Error : errcode=%d , errmsg=%s", ticket.Code, ticket.Msg)
  98. return
  99. }
  100. jsAPITicketCacheKey := fmt.Sprintf("jsapi_ticket_%s", js.AppID)
  101. expires := ticket.ExpiresIn - 1500
  102. err = js.Cache.Set(jsAPITicketCacheKey, ticket.Ticket, time.Duration(expires)*time.Second)
  103. return
  104. }