一物一码
Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
 
 
 
 
 
 

136 linhas
3.3 KiB

  1. package utils
  2. import (
  3. "applet/app/md"
  4. "bytes"
  5. "crypto/sha1"
  6. "encoding/hex"
  7. "fmt"
  8. "io"
  9. "io/ioutil"
  10. "mime/multipart"
  11. "net/http"
  12. "os"
  13. "sort"
  14. "strings"
  15. )
  16. // CheckSignature 微信公众号签名检查
  17. func CheckSignature(signature, timestamp, nonce, token string) bool {
  18. arr := []string{timestamp, nonce, token}
  19. // 字典序排序
  20. sort.Strings(arr)
  21. n := len(timestamp) + len(nonce) + len(token)
  22. var b strings.Builder
  23. b.Grow(n)
  24. for i := 0; i < len(arr); i++ {
  25. b.WriteString(arr[i])
  26. }
  27. return Sha1(b.String()) == signature
  28. }
  29. // 进行Sha1编码
  30. func Sha1(str string) string {
  31. h := sha1.New()
  32. h.Write([]byte(str))
  33. return hex.EncodeToString(h.Sum(nil))
  34. }
  35. func GetWechatToken(appid, secret string) (string, error) {
  36. get, err := CurlGet("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid="+appid+"&secret="+secret, nil)
  37. return string(get), err
  38. }
  39. func GetWechatSelfMenu(token string) (string, error) {
  40. get, err := CurlGet("https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token="+token, nil)
  41. return string(get), err
  42. }
  43. func SetWechatSelfMenu(token string, args md.WechatParam) (string, error) {
  44. str := SerializeStr(args)
  45. str = strings.ReplaceAll(str, "\\u0026", "&")
  46. str = strings.ReplaceAll(str, "\\&", "&")
  47. fmt.Println(str)
  48. get, err := CurlPost("https://api.weixin.qq.com/cgi-bin/menu/create?access_token="+token, str, nil)
  49. return string(get), err
  50. }
  51. func UploadWxImg(token string, args md.WechatParam) (string, error) {
  52. str := SerializeStr(args)
  53. str = strings.ReplaceAll(str, "\\u0026", "&")
  54. fmt.Println(str)
  55. get, err := CurlPost("https://api.weixin.qq.com/cgi-bin/material/add_material?access_token"+token+"&type=image", str, nil)
  56. return string(get), err
  57. }
  58. func PostFile(fieldname, filename, uri string) ([]byte, error) {
  59. fields := []MultipartFormField{
  60. {
  61. IsFile: true,
  62. Fieldname: fieldname,
  63. Filename: filename,
  64. },
  65. }
  66. return PostMultipartForm(fields, uri)
  67. }
  68. //MultipartFormField 保存文件或其他字段信息
  69. type MultipartFormField struct {
  70. IsFile bool
  71. Fieldname string
  72. Value []byte
  73. Filename string
  74. }
  75. //PostMultipartForm 上传文件或其他多个字段
  76. func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte, err error) {
  77. bodyBuf := &bytes.Buffer{}
  78. bodyWriter := multipart.NewWriter(bodyBuf)
  79. for _, field := range fields {
  80. if field.IsFile {
  81. fileWriter, e := bodyWriter.CreateFormFile(field.Fieldname, field.Filename)
  82. if e != nil {
  83. err = fmt.Errorf("error writing to buffer , err=%v", e)
  84. return
  85. }
  86. fh, e := os.Open(field.Filename)
  87. if e != nil {
  88. err = fmt.Errorf("error opening file , err=%v", e)
  89. return
  90. }
  91. defer fh.Close()
  92. if _, err = io.Copy(fileWriter, fh); err != nil {
  93. return
  94. }
  95. } else {
  96. partWriter, e := bodyWriter.CreateFormField(field.Fieldname)
  97. if e != nil {
  98. err = e
  99. return
  100. }
  101. valueReader := bytes.NewReader(field.Value)
  102. if _, err = io.Copy(partWriter, valueReader); err != nil {
  103. return
  104. }
  105. }
  106. }
  107. contentType := bodyWriter.FormDataContentType()
  108. bodyWriter.Close()
  109. resp, e := http.Post(uri, contentType, bodyBuf)
  110. if e != nil {
  111. err = e
  112. return
  113. }
  114. defer resp.Body.Close()
  115. if resp.StatusCode != http.StatusOK {
  116. return nil, err
  117. }
  118. respBody, err = ioutil.ReadAll(resp.Body)
  119. return
  120. }