body_map.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. package gopay
  2. import (
  3. "encoding/json"
  4. "encoding/xml"
  5. "errors"
  6. "io"
  7. "sort"
  8. "strings"
  9. "sync"
  10. )
  11. type BodyMap map[string]interface{}
  12. var mu sync.RWMutex
  13. // 设置参数
  14. func (bm BodyMap) Set(key string, value interface{}) {
  15. mu.Lock()
  16. bm[key] = value
  17. mu.Unlock()
  18. }
  19. // 获取参数
  20. func (bm BodyMap) Get(key string) string {
  21. if bm == nil {
  22. return NULL
  23. }
  24. mu.RLock()
  25. defer mu.RUnlock()
  26. value, ok := bm[key]
  27. if !ok {
  28. return NULL
  29. }
  30. v, ok := value.(string)
  31. if !ok {
  32. return convertToString(value)
  33. }
  34. return v
  35. }
  36. func convertToString(v interface{}) (str string) {
  37. if v == nil {
  38. return NULL
  39. }
  40. var (
  41. bs []byte
  42. err error
  43. )
  44. if bs, err = json.Marshal(v); err != nil {
  45. return NULL
  46. }
  47. str = string(bs)
  48. return
  49. }
  50. // 删除参数
  51. func (bm BodyMap) Remove(key string) {
  52. mu.Lock()
  53. delete(bm, key)
  54. mu.Unlock()
  55. }
  56. type xmlMapMarshal struct {
  57. XMLName xml.Name
  58. Value interface{} `xml:",cdata"`
  59. }
  60. type xmlMapUnmarshal struct {
  61. XMLName xml.Name
  62. Value string `xml:",cdata"`
  63. }
  64. func (bm BodyMap) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
  65. if len(bm) == 0 {
  66. return nil
  67. }
  68. start.Name = xml.Name{NULL, "xml"}
  69. if err = e.EncodeToken(start); err != nil {
  70. return
  71. }
  72. for k := range bm {
  73. if v := bm.Get(k); v != NULL {
  74. e.Encode(xmlMapMarshal{XMLName: xml.Name{Local: k}, Value: v})
  75. }
  76. }
  77. return e.EncodeToken(start.End())
  78. }
  79. func (bm *BodyMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
  80. for {
  81. var e xmlMapUnmarshal
  82. err = d.Decode(&e)
  83. if err != nil {
  84. if err == io.EOF {
  85. return nil
  86. }
  87. return err
  88. }
  89. bm.Set(e.XMLName.Local, e.Value)
  90. }
  91. }
  92. // ("bar=baz&foo=quux") sorted by key.
  93. func (bm BodyMap) EncodeWeChatSignParams(apiKey string) string {
  94. var (
  95. buf strings.Builder
  96. keyList []string
  97. )
  98. mu.RLock()
  99. for k := range bm {
  100. keyList = append(keyList, k)
  101. }
  102. sort.Strings(keyList)
  103. mu.RUnlock()
  104. for _, k := range keyList {
  105. if v := bm.Get(k); v != NULL {
  106. buf.WriteString(k)
  107. buf.WriteByte('=')
  108. buf.WriteString(v)
  109. buf.WriteByte('&')
  110. }
  111. }
  112. buf.WriteString("key")
  113. buf.WriteByte('=')
  114. buf.WriteString(apiKey)
  115. return buf.String()
  116. }
  117. // ("bar=baz&foo=quux") sorted by key.
  118. func (bm BodyMap) EncodeAliPaySignParams() string {
  119. var (
  120. buf strings.Builder
  121. keyList []string
  122. )
  123. mu.RLock()
  124. for k := range bm {
  125. keyList = append(keyList, k)
  126. }
  127. sort.Strings(keyList)
  128. mu.RUnlock()
  129. for _, k := range keyList {
  130. if v := bm.Get(k); v != NULL {
  131. buf.WriteString(k)
  132. buf.WriteByte('=')
  133. buf.WriteString(v)
  134. buf.WriteByte('&')
  135. }
  136. }
  137. if buf.Len() <= 0 {
  138. return NULL
  139. }
  140. return buf.String()[:buf.Len()-1]
  141. }
  142. func (bm BodyMap) EncodeGetParams() string {
  143. var (
  144. buf strings.Builder
  145. )
  146. for k, _ := range bm {
  147. if v := bm.Get(k); v != NULL {
  148. buf.WriteString(k)
  149. buf.WriteByte('=')
  150. buf.WriteString(v)
  151. buf.WriteByte('&')
  152. }
  153. }
  154. if buf.Len() <= 0 {
  155. return NULL
  156. }
  157. return buf.String()[:buf.Len()-1]
  158. }
  159. func (bm BodyMap) CheckEmptyError(keys ...string) error {
  160. var emptyKeys []string
  161. for _, k := range keys {
  162. if v := bm.Get(k); v == NULL {
  163. emptyKeys = append(emptyKeys, k)
  164. }
  165. }
  166. if len(emptyKeys) > 0 {
  167. return errors.New(strings.Join(emptyKeys, ", ") + " : cannot be empty")
  168. }
  169. return nil
  170. }