171 lines
4.4 KiB
Go
171 lines
4.4 KiB
Go
package quick_recharge
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/aes"
|
|
"crypto/cipher"
|
|
"crypto/md5"
|
|
"encoding/base64"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"gitrosy.jxc4.com/baseapi/platformapi"
|
|
"gitrosy.jxc4.com/baseapi/utils"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
type API struct {
|
|
platformapi.APICookie
|
|
appKey string
|
|
userID string
|
|
client *http.Client
|
|
config *platformapi.APIConfig
|
|
}
|
|
|
|
func New(appKey, userId string, config ...*platformapi.APIConfig) *API {
|
|
curConfig := platformapi.DefAPIConfig
|
|
if len(config) > 0 {
|
|
curConfig = *config[0]
|
|
}
|
|
return &API{
|
|
appKey: appKey,
|
|
userID: userId,
|
|
client: &http.Client{Timeout: curConfig.ClientTimeout},
|
|
config: &curConfig,
|
|
}
|
|
}
|
|
|
|
// AccessInfo 发送请求
|
|
func (a *API) AccessInfo(baseUrl, url, requestMethods string, resultKey string, param map[string]interface{}) (retVal map[string]interface{}, err error) {
|
|
err = platformapi.AccessPlatformAPIWithRetry(a.client,
|
|
func() *http.Request {
|
|
var request *http.Request
|
|
if requestMethods == http.MethodPost {
|
|
fullURL := utils.GenerateGetURL(baseUrl, url, nil)
|
|
// 获取json结构体的参数体
|
|
request, _ = http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(param).Encode()))
|
|
request.Header.Add("Content-Type", "application/x-www-form-urlencoded")
|
|
} else {
|
|
request, _ = http.NewRequest(http.MethodGet, utils.GenerateGetURL(baseUrl, url, param), nil)
|
|
}
|
|
|
|
return request
|
|
},
|
|
a.config,
|
|
func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
|
|
if jsonResult1 == nil {
|
|
return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
|
|
}
|
|
retVal = jsonResult1
|
|
if jsonResult1["code"] == nil {
|
|
return platformapi.ErrLevelGeneralFail, fmt.Errorf("返回结果格式不正常")
|
|
}
|
|
code := int(utils.MustInterface2Int64(jsonResult1["code"]))
|
|
if code == ResponseCodeSuccess {
|
|
if resultKey == "" {
|
|
retVal = jsonResult1
|
|
} else {
|
|
retVal, _ = jsonResult1[resultKey].(map[string]interface{})
|
|
}
|
|
return platformapi.ErrLevelSuccess, nil
|
|
}
|
|
newErr := utils.NewErrorIntCode(jsonResult1["msg"].(string), code)
|
|
return platformapi.ErrLevelCodeIsNotOK, newErr
|
|
})
|
|
return retVal, err
|
|
}
|
|
|
|
// AESEncrypt 加密函数
|
|
func AESEncrypt(plaintext, key []byte) (string, error) {
|
|
block, err := aes.NewCipher(key)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
blockSize := block.BlockSize()
|
|
paddedPlaintext := PKCS7Padding(plaintext, blockSize)
|
|
ciphertext := make([]byte, len(paddedPlaintext))
|
|
|
|
blockMode := cipher.NewCBCEncrypter(block, key[:blockSize])
|
|
blockMode.CryptBlocks(ciphertext, paddedPlaintext)
|
|
|
|
return base64.StdEncoding.EncodeToString(ciphertext), nil
|
|
}
|
|
|
|
// AESDecrypt 解密函数
|
|
func AESDecrypt(ciphertext, key []byte) (string, error) {
|
|
decodedCiphertext, err := base64.StdEncoding.DecodeString(string(ciphertext))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
block, err := aes.NewCipher(key)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
blockSize := block.BlockSize()
|
|
plaintext := make([]byte, len(decodedCiphertext))
|
|
blockMode := cipher.NewCBCDecrypter(block, key[:blockSize])
|
|
blockMode.CryptBlocks(plaintext, decodedCiphertext)
|
|
|
|
unpaddedPlaintext, err := PKCS7UnPadding(plaintext)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return string(unpaddedPlaintext), nil
|
|
}
|
|
|
|
// Md5Sign 签名
|
|
func (a *API) Md5Sign(signKey string, param ...string) string {
|
|
md5Data := signKey
|
|
|
|
for _, v := range param {
|
|
if ContainsChinese(v) {
|
|
md5Data += url.QueryEscape(v)
|
|
} else {
|
|
md5Data += v
|
|
}
|
|
}
|
|
|
|
lowerStr := strings.ToLower(md5Data)
|
|
harsher := md5.New()
|
|
harsher.Write([]byte(lowerStr))
|
|
hash := harsher.Sum(nil)
|
|
|
|
return hex.EncodeToString(hash)
|
|
}
|
|
|
|
// ContainsChinese 参数化是否包含中文
|
|
func ContainsChinese(s string) bool {
|
|
for _, v := range s {
|
|
if unicode.Is(unicode.Han, v) {
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
// PKCS7Padding 填充方法
|
|
func PKCS7Padding(ciphertext []byte, blockSize int) []byte {
|
|
padding := blockSize - len(ciphertext)%blockSize
|
|
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
|
|
return append(ciphertext, padtext...)
|
|
}
|
|
|
|
// PKCS7UnPadding 移除填充
|
|
func PKCS7UnPadding(origData []byte) ([]byte, error) {
|
|
length := len(origData)
|
|
if length == 0 {
|
|
return nil, fmt.Errorf("invalid encrypted data")
|
|
}
|
|
unpadding := int(origData[length-1])
|
|
if unpadding > length || unpadding <= 0 {
|
|
return nil, fmt.Errorf("invalid encrypted data")
|
|
}
|
|
return origData[:(length - unpadding)], nil
|
|
}
|