code.go 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. // Package code 小程序二维码
  2. package code
  3. import (
  4. "encoding/json"
  5. "errors"
  6. "net/http"
  7. "strings"
  8. "github.com/sqeven/weapp"
  9. "github.com/sqeven/weapp/util"
  10. )
  11. const (
  12. appCodeAPI = "/wxa/getwxacode"
  13. unlimitedAppCodeAPI = "/wxa/getwxacodeunlimit"
  14. QRCodeAPI = "/cgi-bin/wxaapp/createwxaqrcode"
  15. )
  16. // QRCoder 小程序码参数
  17. type QRCoder struct {
  18. Page string `json:"page,omitempty"`
  19. // path 识别二维码后进入小程序的页面链接
  20. Path string `json:"path,omitempty"`
  21. // width 图片宽度
  22. Width int `json:"width,omitempty"`
  23. // scene 参数数据
  24. Scene string `json:"scene,omitempty"`
  25. // autoColor 自动配置线条颜色,如果颜色依然是黑色,则说明不建议配置主色调
  26. AutoColor bool `json:"auto_color,omitempty"`
  27. // lineColor AutoColor 为 false 时生效,使用 rgb 设置颜色 例如 {"r":"xxx","g":"xxx","b":"xxx"},十进制表示
  28. LineColor Color `json:"line_color,omitempty"`
  29. // isHyaline 是否需要透明底色
  30. IsHyaline bool `json:"is_hyaline,omitempty"`
  31. }
  32. // Color QRCode color
  33. type Color struct {
  34. R string `json:"r"`
  35. G string `json:"g"`
  36. B string `json:"b"`
  37. }
  38. // AppCode 获取小程序码
  39. // 可接受path参数较长 生成个数受限 永久有效 适用于需要的码数量较少的业务场景
  40. //
  41. // @token 微信access_token
  42. func (code QRCoder) AppCode(token string) (*http.Response, error) {
  43. body, err := json.Marshal(code)
  44. if err != nil {
  45. return nil, err
  46. }
  47. return fetchCode(appCodeAPI, string(body), token)
  48. }
  49. // UnlimitedAppCode 获取小程序码
  50. // 可接受页面参数较短 生成个数不受限 适用于需要的码数量极多的业务场景
  51. // 根路径前不要填加'/' 不能携带参数(参数请放在scene字段里)
  52. //
  53. // @token 微信access_token
  54. func (code QRCoder) UnlimitedAppCode(token string) (*http.Response, error) {
  55. body, err := json.Marshal(code)
  56. if err != nil {
  57. return nil, err
  58. }
  59. return fetchCode(unlimitedAppCodeAPI, string(body), token)
  60. }
  61. // QRCode 获取小程序二维码
  62. // 可接受path参数较长,生成个数受限 永久有效 适用于需要的码数量较少的业务场景
  63. //
  64. // @token 微信access_token
  65. func (code QRCoder) QRCode(token string) (*http.Response, error) {
  66. body, err := json.Marshal(code)
  67. if err != nil {
  68. return nil, err
  69. }
  70. return fetchCode(QRCodeAPI, string(body), token)
  71. }
  72. // 向微信服务器获取二维码
  73. // 返回 HTTP 请求实例
  74. func fetchCode(path, body, token string) (res *http.Response, err error) {
  75. api, err := util.TokenAPI(weapp.BaseURL+path, token)
  76. if err != nil {
  77. return
  78. }
  79. res, err = http.Post(api, "application/json", strings.NewReader(body))
  80. if err != nil {
  81. return
  82. }
  83. switch header := res.Header.Get("Content-Type"); {
  84. case strings.HasPrefix(header, "application/json"): // 返回错误信息
  85. var data weapp.Response
  86. if err = json.NewDecoder(res.Body).Decode(&data); err != nil {
  87. return
  88. }
  89. return res, errors.New(data.Errmsg)
  90. case header == "image/jpeg": // 返回文件
  91. return res, nil
  92. default:
  93. err = errors.New("unknown response header: " + header)
  94. return
  95. }
  96. }