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.

142 lines
3.0 KiB

package request
import (
"crypto/rand"
"encoding/base64"
"encoding/hex"
"encoding/json"
"errors"
"git.oa00.com/go/otosaas/config"
"github.com/google/uuid"
"github.com/tjfoc/gmsm/sm4"
"io"
"log"
"net/http"
"strconv"
"strings"
"time"
)
const (
POST = "POST"
GET = "GET"
)
var client = &http.Client{}
// Request @Title 请求
func Request(method, url, data string, headers ...map[string]string) ([]byte, error) {
reqest, err := http.NewRequest(method, url, strings.NewReader(data))
if err != nil {
return nil, err
}
if len(headers) > 0 {
for key, value := range headers[0] {
reqest.Header.Add(key, value)
}
}
response, err := client.Do(reqest)
if err != nil {
return nil, err
}
defer response.Body.Close()
result, err := io.ReadAll(response.Body)
if err != nil {
return nil, err
}
return result, nil
}
// Encrypt @Title 加密
func Encrypt(data string) (string, error) {
bytes, err := sm4.Sm4Ecb(config.SdkConfig.Sm4Secret, []byte(data), true)
if err != nil {
return "", err
}
return hex.EncodeToString(bytes), nil
}
// Decrypt @Title 解密
func Decrypt(data string) (string, error) {
decodeString, err := hex.DecodeString(data)
if err != nil {
return "", err
}
bytes, err := sm4.Sm4Ecb(config.SdkConfig.Sm4Secret, decodeString, false)
if err != nil {
return "", err
}
return string(bytes), nil
}
// Sign @Title 签名
func Sign(data, timeStamp string) (sign string, err error) {
signData, err := config.SdkConfig.PrivateKey.Sign(rand.Reader, []byte(config.SdkConfig.AppSecret+timeStamp+data), nil)
if err != nil {
return sign, err
}
return base64.StdEncoding.EncodeToString(signData), nil
}
type response struct {
Code int `json:"code"`
Message string `json:"message"`
BizData string `json:"bizData"`
Sign string `json:"sign"`
}
// Exec 调用接口
func Exec(action string, data interface{}, resObj interface{}) error {
// 加密
marshal, _ := json.Marshal(&data)
log.Println(string(marshal))
encrypt, err := Encrypt(string(marshal))
if err != nil {
log.Println(err)
return err
}
// 签名
timeStamp := strconv.FormatInt(time.Now().UnixMilli(), 10)
sign, err := Sign(encrypt, timeStamp)
if err != nil {
log.Println(err)
return err
}
bytes, _ := json.Marshal(map[string]string{
"bizData": encrypt,
"sign": sign,
})
// 调用接口
result, err := Request(POST, config.SdkConfig.Url+action, string(bytes), map[string]string{
"Content-Type": "application/json",
"appKey": config.SdkConfig.AppKey,
"timeStamp": timeStamp,
"version": "1.0",
"requestId": uuid.New().String(),
})
if err != nil {
log.Println(err)
return err
}
log.Println(string(result))
resp := response{}
if err = json.Unmarshal(result, &resp); err != nil {
log.Println(err)
return err
}
if resp.Code == 0 {
decrypt, err := Decrypt(resp.BizData)
if err != nil {
log.Println(err)
return err
}
log.Println(decrypt)
return json.Unmarshal([]byte(decrypt), &resObj)
} else {
return errors.New(resp.Message)
}
}