body_map.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. package gopay
  2. import (
  3. "encoding/json"
  4. "encoding/xml"
  5. "io"
  6. "reflect"
  7. "sort"
  8. "strings"
  9. )
  10. type BodyMap map[string]interface{}
  11. // 设置参数
  12. func (bm BodyMap) Set(key string, value interface{}) {
  13. bm[key] = value
  14. }
  15. // 获取参数
  16. func (bm BodyMap) Get(key string) string {
  17. if bm == nil {
  18. return null
  19. }
  20. var (
  21. value interface{}
  22. ok bool
  23. v string
  24. )
  25. if value, ok = bm[key]; !ok {
  26. return null
  27. }
  28. if v, ok = value.(string); ok {
  29. return v
  30. }
  31. return convertToString(value)
  32. }
  33. func convertToString(v interface{}) (str string) {
  34. if v == nil {
  35. return null
  36. }
  37. var (
  38. bs []byte
  39. err error
  40. )
  41. if bs, err = json.Marshal(v); err != nil {
  42. return null
  43. }
  44. str = string(bs)
  45. return
  46. }
  47. // 删除参数
  48. func (bm BodyMap) Remove(key string) {
  49. delete(bm, key)
  50. }
  51. type xmlMapEntry struct {
  52. XMLName xml.Name
  53. Value string `xml:",chardata"`
  54. }
  55. func (bm BodyMap) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
  56. if len(bm) == 0 {
  57. return nil
  58. }
  59. var (
  60. value string
  61. vKind reflect.Kind
  62. )
  63. if err = e.EncodeToken(start); err != nil {
  64. return
  65. }
  66. for k, v := range bm {
  67. vKind = reflect.ValueOf(v).Kind()
  68. switch vKind {
  69. case reflect.String:
  70. value = v.(string)
  71. case reflect.Int:
  72. value = Int2String(v.(int))
  73. case reflect.Int64:
  74. value = Int642String(v.(int64))
  75. case reflect.Float32:
  76. value = Float32ToString(v.(float32))
  77. case reflect.Float64:
  78. value = Float64ToString(v.(float64))
  79. default:
  80. value = ""
  81. }
  82. e.Encode(xmlMapEntry{XMLName: xml.Name{Local: k}, Value: value})
  83. }
  84. return e.EncodeToken(start.End())
  85. }
  86. func (bm *BodyMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
  87. for {
  88. var e xmlMapEntry
  89. err = d.Decode(&e)
  90. if err == io.EOF {
  91. break
  92. } else if err != nil {
  93. return
  94. }
  95. bm.Set(e.XMLName.Local, e.Value)
  96. }
  97. return
  98. }
  99. // ("bar=baz&foo=quux") sorted by key.
  100. func (bm BodyMap) EncodeWeChatSignParams(apiKey string) string {
  101. var (
  102. buf strings.Builder
  103. keyList []string
  104. )
  105. for k := range bm {
  106. keyList = append(keyList, k)
  107. }
  108. sort.Strings(keyList)
  109. for _, k := range keyList {
  110. if v := bm.Get(k); v != null {
  111. buf.WriteString(k)
  112. buf.WriteByte('=')
  113. buf.WriteString(v)
  114. buf.WriteByte('&')
  115. }
  116. }
  117. buf.WriteString("key")
  118. buf.WriteByte('=')
  119. buf.WriteString(apiKey)
  120. return buf.String()
  121. }
  122. // ("bar=baz&foo=quux") sorted by key.
  123. func (bm BodyMap) EncodeAliPaySignParams() string {
  124. var (
  125. buf strings.Builder
  126. keyList []string
  127. )
  128. keyList = make([]string, 0, len(bm))
  129. for k := range bm {
  130. keyList = append(keyList, k)
  131. }
  132. sort.Strings(keyList)
  133. for _, k := range keyList {
  134. if v := bm.Get(k); v != null {
  135. buf.WriteString(k)
  136. buf.WriteByte('=')
  137. buf.WriteString(v)
  138. buf.WriteByte('&')
  139. }
  140. }
  141. return buf.String()[:buf.Len()-1]
  142. }