一物一码
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

135 lines
3.2 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. fmt.Println(str)
  47. get, err := CurlPost("https://api.weixin.qq.com/cgi-bin/menu/create?access_token="+token, str, nil)
  48. return string(get), err
  49. }
  50. func UploadWxImg(token string, args md.WechatParam) (string, error) {
  51. str := SerializeStr(args)
  52. str = strings.ReplaceAll(str, "\\u0026", "&")
  53. fmt.Println(str)
  54. get, err := CurlPost("https://api.weixin.qq.com/cgi-bin/material/add_material?access_token"+token+"&type=image", str, nil)
  55. return string(get), err
  56. }
  57. func PostFile(fieldname, filename, uri string) ([]byte, error) {
  58. fields := []MultipartFormField{
  59. {
  60. IsFile: true,
  61. Fieldname: fieldname,
  62. Filename: filename,
  63. },
  64. }
  65. return PostMultipartForm(fields, uri)
  66. }
  67. //MultipartFormField 保存文件或其他字段信息
  68. type MultipartFormField struct {
  69. IsFile bool
  70. Fieldname string
  71. Value []byte
  72. Filename string
  73. }
  74. //PostMultipartForm 上传文件或其他多个字段
  75. func PostMultipartForm(fields []MultipartFormField, uri string) (respBody []byte, err error) {
  76. bodyBuf := &bytes.Buffer{}
  77. bodyWriter := multipart.NewWriter(bodyBuf)
  78. for _, field := range fields {
  79. if field.IsFile {
  80. fileWriter, e := bodyWriter.CreateFormFile(field.Fieldname, field.Filename)
  81. if e != nil {
  82. err = fmt.Errorf("error writing to buffer , err=%v", e)
  83. return
  84. }
  85. fh, e := os.Open(field.Filename)
  86. if e != nil {
  87. err = fmt.Errorf("error opening file , err=%v", e)
  88. return
  89. }
  90. defer fh.Close()
  91. if _, err = io.Copy(fileWriter, fh); err != nil {
  92. return
  93. }
  94. } else {
  95. partWriter, e := bodyWriter.CreateFormField(field.Fieldname)
  96. if e != nil {
  97. err = e
  98. return
  99. }
  100. valueReader := bytes.NewReader(field.Value)
  101. if _, err = io.Copy(partWriter, valueReader); err != nil {
  102. return
  103. }
  104. }
  105. }
  106. contentType := bodyWriter.FormDataContentType()
  107. bodyWriter.Close()
  108. resp, e := http.Post(uri, contentType, bodyBuf)
  109. if e != nil {
  110. err = e
  111. return
  112. }
  113. defer resp.Body.Close()
  114. if resp.StatusCode != http.StatusOK {
  115. return nil, err
  116. }
  117. respBody, err = ioutil.ReadAll(resp.Body)
  118. return
  119. }