package quick_recharge import ( "bytes" "crypto/aes" "crypto/cipher" "crypto/md5" "encoding/base64" "encoding/hex" "fmt" "git.rosy.net.cn/baseapi/platformapi" "git.rosy.net.cn/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 }