243 lines
4.3 KiB
Go
243 lines
4.3 KiB
Go
|
package gopay
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"encoding/xml"
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"net/url"
|
||
|
"sort"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/go-pay/gopay/pkg/util"
|
||
|
)
|
||
|
|
||
|
type BodyMap map[string]interface{}
|
||
|
|
||
|
type xmlMapMarshal struct {
|
||
|
XMLName xml.Name
|
||
|
Value interface{} `xml:",cdata"`
|
||
|
}
|
||
|
|
||
|
type xmlMapUnmarshal struct {
|
||
|
XMLName xml.Name
|
||
|
Value string `xml:",cdata"`
|
||
|
}
|
||
|
|
||
|
// 设置参数
|
||
|
func (bm BodyMap) Set(key string, value interface{}) BodyMap {
|
||
|
bm[key] = value
|
||
|
return bm
|
||
|
}
|
||
|
|
||
|
func (bm BodyMap) SetBodyMap(key string, value func(b BodyMap)) BodyMap {
|
||
|
_bm := make(BodyMap)
|
||
|
value(_bm)
|
||
|
bm[key] = _bm
|
||
|
return bm
|
||
|
}
|
||
|
|
||
|
// 设置 FormFile
|
||
|
func (bm BodyMap) SetFormFile(key string, file *util.File) BodyMap {
|
||
|
bm[key] = file
|
||
|
return bm
|
||
|
}
|
||
|
|
||
|
// 获取参数,同 GetString()
|
||
|
func (bm BodyMap) Get(key string) string {
|
||
|
return bm.GetString(key)
|
||
|
}
|
||
|
|
||
|
// 获取参数转换string
|
||
|
func (bm BodyMap) GetString(key string) string {
|
||
|
if bm == nil {
|
||
|
return NULL
|
||
|
}
|
||
|
value, ok := bm[key]
|
||
|
if !ok {
|
||
|
return NULL
|
||
|
}
|
||
|
v, ok := value.(string)
|
||
|
if !ok {
|
||
|
return convertToString(value)
|
||
|
}
|
||
|
return v
|
||
|
}
|
||
|
|
||
|
// 获取原始参数
|
||
|
func (bm BodyMap) GetInterface(key string) interface{} {
|
||
|
if bm == nil {
|
||
|
return nil
|
||
|
}
|
||
|
return bm[key]
|
||
|
}
|
||
|
|
||
|
// 删除参数
|
||
|
func (bm BodyMap) Remove(key string) {
|
||
|
delete(bm, key)
|
||
|
}
|
||
|
|
||
|
// 置空BodyMap
|
||
|
func (bm BodyMap) Reset() {
|
||
|
for k := range bm {
|
||
|
delete(bm, k)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (bm BodyMap) JsonBody() (jb string) {
|
||
|
bs, err := json.Marshal(bm)
|
||
|
if err != nil {
|
||
|
return ""
|
||
|
}
|
||
|
jb = string(bs)
|
||
|
return jb
|
||
|
}
|
||
|
|
||
|
// Unmarshal to struct or slice point
|
||
|
func (bm BodyMap) Unmarshal(ptr interface{}) (err error) {
|
||
|
bs, err := json.Marshal(bm)
|
||
|
if err != nil {
|
||
|
return err
|
||
|
}
|
||
|
return json.Unmarshal(bs, ptr)
|
||
|
}
|
||
|
|
||
|
func (bm BodyMap) MarshalXML(e *xml.Encoder, start xml.StartElement) (err error) {
|
||
|
if len(bm) == 0 {
|
||
|
return nil
|
||
|
}
|
||
|
start.Name = xml.Name{Space: NULL, Local: "xml"}
|
||
|
if err = e.EncodeToken(start); err != nil {
|
||
|
return
|
||
|
}
|
||
|
for k := range bm {
|
||
|
if v := bm.GetString(k); v != NULL {
|
||
|
_ = e.Encode(xmlMapMarshal{XMLName: xml.Name{Local: k}, Value: v})
|
||
|
}
|
||
|
}
|
||
|
return e.EncodeToken(start.End())
|
||
|
}
|
||
|
|
||
|
func (bm *BodyMap) UnmarshalXML(d *xml.Decoder, start xml.StartElement) (err error) {
|
||
|
for {
|
||
|
var e xmlMapUnmarshal
|
||
|
err = d.Decode(&e)
|
||
|
if err != nil {
|
||
|
if err == io.EOF {
|
||
|
return nil
|
||
|
}
|
||
|
return err
|
||
|
}
|
||
|
bm.Set(e.XMLName.Local, e.Value)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// ("bar=baz&foo=quux") sorted by key.
|
||
|
func (bm BodyMap) EncodeWeChatSignParams(apiKey string) string {
|
||
|
if bm == nil {
|
||
|
return NULL
|
||
|
}
|
||
|
var (
|
||
|
buf strings.Builder
|
||
|
keyList []string
|
||
|
)
|
||
|
for k := range bm {
|
||
|
keyList = append(keyList, k)
|
||
|
}
|
||
|
sort.Strings(keyList)
|
||
|
for _, k := range keyList {
|
||
|
if v := bm.GetString(k); v != NULL {
|
||
|
buf.WriteString(k)
|
||
|
buf.WriteByte('=')
|
||
|
buf.WriteString(v)
|
||
|
buf.WriteByte('&')
|
||
|
}
|
||
|
}
|
||
|
buf.WriteString("key")
|
||
|
buf.WriteByte('=')
|
||
|
buf.WriteString(apiKey)
|
||
|
return buf.String()
|
||
|
}
|
||
|
|
||
|
// ("bar=baz&foo=quux") sorted by key.
|
||
|
func (bm BodyMap) EncodeAliPaySignParams() string {
|
||
|
if bm == nil {
|
||
|
return NULL
|
||
|
}
|
||
|
var (
|
||
|
buf strings.Builder
|
||
|
keyList []string
|
||
|
)
|
||
|
for k := range bm {
|
||
|
keyList = append(keyList, k)
|
||
|
}
|
||
|
sort.Strings(keyList)
|
||
|
for _, k := range keyList {
|
||
|
if v := bm.GetString(k); v != NULL {
|
||
|
buf.WriteString(k)
|
||
|
buf.WriteByte('=')
|
||
|
buf.WriteString(v)
|
||
|
buf.WriteByte('&')
|
||
|
}
|
||
|
}
|
||
|
if buf.Len() <= 0 {
|
||
|
return NULL
|
||
|
}
|
||
|
return buf.String()[:buf.Len()-1]
|
||
|
}
|
||
|
|
||
|
// ("bar=baz&foo=quux") sorted by key.
|
||
|
func (bm BodyMap) EncodeURLParams() string {
|
||
|
if bm == nil {
|
||
|
return NULL
|
||
|
}
|
||
|
var (
|
||
|
buf strings.Builder
|
||
|
keys []string
|
||
|
)
|
||
|
for k := range bm {
|
||
|
keys = append(keys, k)
|
||
|
}
|
||
|
sort.Strings(keys)
|
||
|
for _, k := range keys {
|
||
|
if v := bm.GetString(k); v != NULL {
|
||
|
buf.WriteString(url.QueryEscape(k))
|
||
|
buf.WriteByte('=')
|
||
|
buf.WriteString(url.QueryEscape(v))
|
||
|
buf.WriteByte('&')
|
||
|
}
|
||
|
}
|
||
|
if buf.Len() <= 0 {
|
||
|
return NULL
|
||
|
}
|
||
|
return buf.String()[:buf.Len()-1]
|
||
|
}
|
||
|
|
||
|
func (bm BodyMap) CheckEmptyError(keys ...string) error {
|
||
|
var emptyKeys []string
|
||
|
for _, k := range keys {
|
||
|
if v := bm.GetString(k); v == NULL {
|
||
|
emptyKeys = append(emptyKeys, k)
|
||
|
}
|
||
|
}
|
||
|
if len(emptyKeys) > 0 {
|
||
|
return fmt.Errorf("[%w], %v", MissParamErr, strings.Join(emptyKeys, ", "))
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
func convertToString(v interface{}) (str string) {
|
||
|
if v == nil {
|
||
|
return NULL
|
||
|
}
|
||
|
var (
|
||
|
bs []byte
|
||
|
err error
|
||
|
)
|
||
|
if bs, err = json.Marshal(v); err != nil {
|
||
|
return NULL
|
||
|
}
|
||
|
str = string(bs)
|
||
|
return
|
||
|
}
|