蛋蛋星球-制度模式
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.

276 lines
4.9 KiB

  1. package gopay
  2. import (
  3. "encoding/json"
  4. "encoding/xml"
  5. "fmt"
  6. "io"
  7. "net/url"
  8. "sort"
  9. "strings"
  10. )
  11. type BodyMap map[string]any
  12. type xmlMapMarshal struct {
  13. XMLName xml.Name
  14. Value any `xml:",cdata"`
  15. }
  16. type xmlMapUnmarshal struct {
  17. XMLName xml.Name
  18. Value string `xml:",cdata"`
  19. }
  20. type File struct {
  21. Name string `json:"name"`
  22. Content []byte `json:"content"`
  23. }
  24. // 设置参数
  25. func (bm BodyMap) Set(key string, value any) BodyMap {
  26. bm[key] = value
  27. return bm
  28. }
  29. func (bm BodyMap) SetBodyMap(key string, value func(b BodyMap)) BodyMap {
  30. _bm := make(BodyMap)
  31. value(_bm)
  32. bm[key] = _bm
  33. return bm
  34. }
  35. func (bm BodyMap) SetSlice(key string, value func(b BodyMap)) BodyMap {
  36. _bm := make(BodyMap)
  37. value(_bm)
  38. bm[key] = _bm
  39. return bm
  40. }
  41. // 设置 FormFile
  42. func (bm BodyMap) SetFormFile(key string, file *File) BodyMap {
  43. bm[key] = file
  44. return bm
  45. }
  46. // 获取参数,同 GetString()
  47. func (bm BodyMap) Get(key string) string {
  48. return bm.GetString(key)
  49. }
  50. // 获取参数转换string
  51. func (bm BodyMap) GetString(key string) string {
  52. if bm == nil {
  53. return NULL
  54. }
  55. value, ok := bm[key]
  56. if !ok {
  57. return NULL
  58. }
  59. v, ok := value.(string)
  60. if !ok {
  61. return convertToString(value)
  62. }
  63. return v
  64. }
  65. // Deprecated
  66. // 推荐使用 GetAny()
  67. func (bm BodyMap) GetInterface(key string) any {
  68. if bm == nil {
  69. return nil
  70. }
  71. return bm[key]
  72. }
  73. // 获取原始参数
  74. func (bm BodyMap) GetAny(key string) any {
  75. if bm == nil {
  76. return nil
  77. }
  78. return bm[key]
  79. }
  80. // 删除参数
  81. func (bm BodyMap) Remove(key string) {
  82. delete(bm, key)
  83. }
  84. // 置空BodyMap
  85. func (bm BodyMap) Reset() {
  86. for k := range bm {
  87. delete(bm, k)
  88. }
  89. }
  90. func (bm BodyMap) JsonBody() (jb string) {
  91. bs, err := json.Marshal(bm)
  92. if err != nil {
  93. return ""
  94. }
  95. jb = string(bs)
  96. return jb
  97. }
  98. // Unmarshal to struct or slice point
  99. func (bm BodyMap) Unmarshal(ptr any) (err error) {
  100. bs, err := json.Marshal(bm)
  101. if err != nil {
  102. return err
  103. }
  104. return json.Unmarshal(bs, ptr)
  105. }
  106. func (bm BodyMap) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
  107. if len(bm) == 0 {
  108. return nil
  109. }
  110. start.Name = xml.Name{Space: NULL, Local: "xml"}
  111. if err = e.EncodeToken(start); err != nil {
  112. return
  113. }
  114. for k := range bm {
  115. if v := bm.GetString(k); v != NULL {
  116. _ = e.Encode(xmlMapMarshal{XMLName: xml.Name{Local: k}, Value: v})
  117. }
  118. }
  119. return e.EncodeToken(start.End())
  120. }
  121. func (bm *BodyMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
  122. for {
  123. var e xmlMapUnmarshal
  124. err = d.Decode(&e)
  125. if err != nil {
  126. if err == io.EOF {
  127. return nil
  128. }
  129. return err
  130. }
  131. bm.Set(e.XMLName.Local, e.Value)
  132. }
  133. }
  134. // ("bar=baz&foo=quux") sorted by key.
  135. func (bm BodyMap) EncodeWeChatSignParams(apiKey string) string {
  136. if bm == nil {
  137. return NULL
  138. }
  139. var (
  140. buf strings.Builder
  141. keyList []string
  142. )
  143. for k := range bm {
  144. keyList = append(keyList, k)
  145. }
  146. sort.Strings(keyList)
  147. for _, k := range keyList {
  148. if v := bm.GetString(k); v != NULL {
  149. buf.WriteString(k)
  150. buf.WriteByte('=')
  151. buf.WriteString(v)
  152. buf.WriteByte('&')
  153. }
  154. }
  155. buf.WriteString("key")
  156. buf.WriteByte('=')
  157. buf.WriteString(apiKey)
  158. return buf.String()
  159. }
  160. // ("bar=baz&foo=quux") sorted by key.
  161. func (bm BodyMap) EncodeAliPaySignParams() string {
  162. if bm == nil {
  163. return NULL
  164. }
  165. var (
  166. buf strings.Builder
  167. keyList []string
  168. )
  169. for k := range bm {
  170. keyList = append(keyList, k)
  171. }
  172. sort.Strings(keyList)
  173. for _, k := range keyList {
  174. if v := bm.GetString(k); v != NULL {
  175. buf.WriteString(k)
  176. buf.WriteByte('=')
  177. buf.WriteString(v)
  178. buf.WriteByte('&')
  179. }
  180. }
  181. if buf.Len() <= 0 {
  182. return NULL
  183. }
  184. return buf.String()[:buf.Len()-1]
  185. }
  186. // ("bar=baz&foo=quux") sorted by key.
  187. func (bm BodyMap) EncodeURLParams() string {
  188. if bm == nil {
  189. return NULL
  190. }
  191. var (
  192. buf strings.Builder
  193. keys []string
  194. )
  195. for k := range bm {
  196. keys = append(keys, k)
  197. }
  198. sort.Strings(keys)
  199. for _, k := range keys {
  200. if v := bm.GetString(k); v != NULL {
  201. buf.WriteString(url.QueryEscape(k))
  202. buf.WriteByte('=')
  203. buf.WriteString(url.QueryEscape(v))
  204. buf.WriteByte('&')
  205. }
  206. }
  207. if buf.Len() <= 0 {
  208. return NULL
  209. }
  210. return buf.String()[:buf.Len()-1]
  211. }
  212. func (bm BodyMap) CheckEmptyError(keys ...string) error {
  213. var emptyKeys []string
  214. for _, k := range keys {
  215. if v := bm.GetString(k); v == NULL {
  216. emptyKeys = append(emptyKeys, k)
  217. }
  218. }
  219. if len(emptyKeys) > 0 {
  220. return fmt.Errorf("[%w], %v", MissParamErr, strings.Join(emptyKeys, ", "))
  221. }
  222. return nil
  223. }
  224. func (bm BodyMap) CheckNotAllEmptyError(keys ...string) error {
  225. var emptyKeys []string
  226. for _, k := range keys {
  227. if v := bm.GetString(k); v == NULL {
  228. emptyKeys = append(emptyKeys, k)
  229. }
  230. }
  231. // if all key is empty, return error
  232. if len(emptyKeys) == len(keys) {
  233. return fmt.Errorf("[%w], %v", MissParamErr, strings.Join(emptyKeys, ", "))
  234. }
  235. return nil
  236. }
  237. func convertToString(v any) (str string) {
  238. if v == nil {
  239. return NULL
  240. }
  241. var (
  242. bs []byte
  243. err error
  244. )
  245. if bs, err = json.Marshal(v); err != nil {
  246. return NULL
  247. }
  248. str = string(bs)
  249. return
  250. }