|
|
@@ -10,8 +10,8 @@ import (
|
|
|
"crypto/x509"
|
|
|
"encoding/base64"
|
|
|
"encoding/hex"
|
|
|
- "encoding/json"
|
|
|
"encoding/pem"
|
|
|
+ "errors"
|
|
|
"fmt"
|
|
|
"io"
|
|
|
"mime/multipart"
|
|
|
@@ -24,104 +24,50 @@ import (
|
|
|
"strings"
|
|
|
"time"
|
|
|
|
|
|
- "github.com/fatih/structs"
|
|
|
+ "github.com/bytedance/sonic"
|
|
|
+ "github.com/bytedance/sonic/encoder"
|
|
|
)
|
|
|
|
|
|
func APIPost[T1 APIReqData, T2 APIRspData](req APIReq[T1], apiPort APIURL) (rsp *APIRsp[T2], err error) {
|
|
|
apiUrl := config.SerCfg.AsignCfg.Url + string(apiPort)
|
|
|
|
|
|
var rspBody []byte
|
|
|
- if len(req.Datas) > 0 {
|
|
|
- // 切片入参
|
|
|
- reqArray := make([]map[string]interface{}, 0)
|
|
|
- for _, item := range req.Datas {
|
|
|
- reqArray = append(reqArray, structs.Map(item))
|
|
|
- }
|
|
|
- logger.GetLogger().Info("调用接口 "+apiUrl+" 请求, request:", reqArray)
|
|
|
- rspBody, err = httpPost_Array(apiUrl, reqArray)
|
|
|
- } else {
|
|
|
- // 对象入参
|
|
|
- reqMap := structs.Map(req.Data)
|
|
|
- logger.GetLogger().Info("调用接口 "+apiUrl+" 请求, request:", reqMap)
|
|
|
- rspBody, err = httpPost(apiUrl, reqMap)
|
|
|
- }
|
|
|
-
|
|
|
+ rspBody, err = httpPost(apiUrl, req.Data)
|
|
|
if err != nil {
|
|
|
- logger.GetLogger().Error("调用接口 "+apiUrl+" 错误, error:", err.Error())
|
|
|
return
|
|
|
}
|
|
|
rspStr := string(rspBody)
|
|
|
if len(rspStr) == 0 {
|
|
|
logger.GetLogger().Error("调用接口 " + apiUrl + " 错误, response为空")
|
|
|
+ err = errors.New("调用接口返回内容为空")
|
|
|
return
|
|
|
}
|
|
|
- logger.GetLogger().Info("调用接口 "+apiUrl+" 返回, response:", rspStr)
|
|
|
rsp = new(APIRsp[T2])
|
|
|
- err = json.Unmarshal(rspBody, rsp)
|
|
|
+ err = sonic.Unmarshal(rspBody, rsp)
|
|
|
|
|
|
return
|
|
|
}
|
|
|
|
|
|
-func httpPost(apiUrl string, bizData map[string]interface{}) (rspBody []byte, err error) {
|
|
|
+func httpPost(apiUrl string, bizData ...interface{}) (rspBody []byte, err error) {
|
|
|
appId := config.SerCfg.AsignCfg.AppId
|
|
|
privateKey := fmt.Sprintf("-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----", config.SerCfg.AsignCfg.PrivateKey)
|
|
|
|
|
|
// fuck asign dev.
|
|
|
timestamp := strconv.Itoa(int(time.Now().UnixMilli() + 10000*60))
|
|
|
|
|
|
- // 签名
|
|
|
- sortedData := sortMapByKey(bizData)
|
|
|
- signature, err := getSignature(sortedData, appId, timestamp, privateKey)
|
|
|
- if err != nil {
|
|
|
- logger.GetLogger().Errorf("签名失败:" + err.Error())
|
|
|
- return
|
|
|
+ // 排序key
|
|
|
+ var b []byte
|
|
|
+ if len(bizData) == 1 {
|
|
|
+ b, err = encoder.Encode(bizData[0], encoder.SortMapKeys)
|
|
|
+ } else {
|
|
|
+ b, err = encoder.Encode(bizData, encoder.SortMapKeys)
|
|
|
}
|
|
|
-
|
|
|
- // 构建form-data请求参数
|
|
|
- var requestBody bytes.Buffer
|
|
|
- multipartWriter := multipart.NewWriter(&requestBody)
|
|
|
- multipartWriter.WriteField("appId", appId)
|
|
|
- multipartWriter.WriteField("timestamp", timestamp)
|
|
|
- multipartWriter.WriteField("bizData", sortedData)
|
|
|
- multipartWriter.Close()
|
|
|
- // 构建请求
|
|
|
- req, err := http.NewRequest("POST", apiUrl, &requestBody)
|
|
|
- // 设置请求头
|
|
|
- req.Header.Set("sign", signature)
|
|
|
- req.Header.Set("timestamp", timestamp)
|
|
|
- req.Header.Set("Content-Type", multipartWriter.FormDataContentType())
|
|
|
-
|
|
|
- // 调用接口
|
|
|
- client := &http.Client{}
|
|
|
- rsp, err := client.Do(req)
|
|
|
if err != nil {
|
|
|
- logger.GetLogger().Errorf("调用接口失败:" + err.Error())
|
|
|
+ logger.GetLogger().Errorf("处理入参排序失败:" + err.Error())
|
|
|
return
|
|
|
}
|
|
|
- defer rsp.Body.Close()
|
|
|
- rspBody, err = io.ReadAll(rsp.Body)
|
|
|
-
|
|
|
- return
|
|
|
-}
|
|
|
-
|
|
|
-// bizData入参为数组
|
|
|
-func httpPost_Array(apiUrl string, bizData []map[string]interface{}) (rspBody []byte, err error) {
|
|
|
- appId := config.SerCfg.AsignCfg.AppId
|
|
|
- privateKey := fmt.Sprintf("-----BEGIN PRIVATE KEY-----\n%s\n-----END PRIVATE KEY-----", config.SerCfg.AsignCfg.PrivateKey)
|
|
|
-
|
|
|
- // fuck asign dev.
|
|
|
- timestamp := strconv.Itoa(int(time.Now().UnixMilli() + 10000*60))
|
|
|
-
|
|
|
+ sortedData := string(b)
|
|
|
// 签名
|
|
|
- sortedData := "["
|
|
|
- for i, item := range bizData {
|
|
|
- if i > 0 {
|
|
|
- sortedData += ","
|
|
|
- }
|
|
|
- sortedData += sortMapByKey(item)
|
|
|
- }
|
|
|
- sortedData += "]"
|
|
|
-
|
|
|
signature, err := getSignature(sortedData, appId, timestamp, privateKey)
|
|
|
if err != nil {
|
|
|
logger.GetLogger().Errorf("签名失败:" + err.Error())
|
|
|
@@ -143,14 +89,16 @@ func httpPost_Array(apiUrl string, bizData []map[string]interface{}) (rspBody []
|
|
|
req.Header.Set("Content-Type", multipartWriter.FormDataContentType())
|
|
|
|
|
|
// 调用接口
|
|
|
+ logger.GetLogger().Info("调用接口 "+apiUrl+" 请求, request:", sortedData)
|
|
|
client := &http.Client{}
|
|
|
rsp, err := client.Do(req)
|
|
|
if err != nil {
|
|
|
- logger.GetLogger().Errorf("调用接口失败:" + err.Error())
|
|
|
+ logger.GetLogger().Error("调用接口 "+apiUrl+" 错误, error:", err.Error())
|
|
|
return
|
|
|
}
|
|
|
defer rsp.Body.Close()
|
|
|
rspBody, err = io.ReadAll(rsp.Body)
|
|
|
+ logger.GetLogger().Info("调用接口 "+apiUrl+" 返回, response:", string(rspBody))
|
|
|
|
|
|
return
|
|
|
}
|
|
|
@@ -198,7 +146,6 @@ func getSignature(sortedData string, appId, timestamp, privateKey string) (signa
|
|
|
// 使用私钥进行签名
|
|
|
sign, err := rsa.SignPKCS1v15(rand.Reader, privateKey10, crypto.SHA1, sum)
|
|
|
if err != nil {
|
|
|
- fmt.Println("Error signing:", err)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
@@ -209,8 +156,8 @@ func getSignature(sortedData string, appId, timestamp, privateKey string) (signa
|
|
|
return
|
|
|
}
|
|
|
|
|
|
-// sortMapByKey 按key排序map返回string
|
|
|
-func sortMapByKey(data map[string]interface{}) (sortedData string) {
|
|
|
+// SortMapByKey 按key排序map返回string -- 已经不使用的方法
|
|
|
+func SortMapByKey(data map[string]interface{}) (sortedData string) {
|
|
|
keys := make([]string, 0, len(data))
|
|
|
for k := range data {
|
|
|
keys = append(keys, k)
|
|
|
@@ -228,7 +175,7 @@ func sortMapByKey(data map[string]interface{}) (sortedData string) {
|
|
|
case *string:
|
|
|
sortedData += fmt.Sprintf(`"%s":"%s"`, k, *(data[k].(*string)))
|
|
|
case *map[string]interface{}:
|
|
|
- sortedData += fmt.Sprintf(`"%s":%s`, k, sortMapByKey(*(data[k].(*map[string]interface{}))))
|
|
|
+ sortedData += fmt.Sprintf(`"%s":%s`, k, SortMapByKey(*(data[k].(*map[string]interface{}))))
|
|
|
case *[]interface{}:
|
|
|
list := data[k].([]interface{})
|
|
|
sortedData += fmt.Sprintf(`"%s":[`, k)
|
|
|
@@ -236,7 +183,7 @@ func sortMapByKey(data map[string]interface{}) (sortedData string) {
|
|
|
if j > 0 {
|
|
|
sortedData += ","
|
|
|
}
|
|
|
- sortedData += sortMapByKey(item.(map[string]interface{}))
|
|
|
+ sortedData += SortMapByKey(item.(map[string]interface{}))
|
|
|
}
|
|
|
sortedData += "]"
|
|
|
default:
|
|
|
@@ -247,7 +194,7 @@ func sortMapByKey(data map[string]interface{}) (sortedData string) {
|
|
|
case string:
|
|
|
sortedData += fmt.Sprintf(`"%s":"%s"`, k, data[k].(string))
|
|
|
case map[string]interface{}:
|
|
|
- sortedData += fmt.Sprintf(`"%s":%s`, k, sortMapByKey(data[k].(map[string]interface{})))
|
|
|
+ sortedData += fmt.Sprintf(`"%s":%s`, k, SortMapByKey(data[k].(map[string]interface{})))
|
|
|
case []interface{}:
|
|
|
list := data[k].([]interface{})
|
|
|
sortedData += fmt.Sprintf(`"%s":[`, k)
|
|
|
@@ -255,7 +202,7 @@ func sortMapByKey(data map[string]interface{}) (sortedData string) {
|
|
|
if j > 0 {
|
|
|
sortedData += ","
|
|
|
}
|
|
|
- sortedData += sortMapByKey(item.(map[string]interface{}))
|
|
|
+ sortedData += SortMapByKey(item.(map[string]interface{}))
|
|
|
}
|
|
|
sortedData += "]"
|
|
|
default:
|