Files
baseapi/platformapi/lakala/lakala_token.go
邹宗楠 0599a21bce 1
2025-06-24 13:50:29 +08:00

237 lines
6.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package lakala
import (
"bytes"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"fmt"
"git.rosy.net.cn/baseapi/utils"
"github.com/tjfoc/gmsm/sm4"
"io"
"io/ioutil"
"math/big"
"mime/multipart"
"net/http"
"strings"
"time"
)
// IncomingToken 进件api,token获取
func (a *API) IncomingToken() (comingToken string, expiresIn int64, err error) {
result, err := a.AccessAPI(IncomingUrlTest, TokenActive, http.MethodPost, "", map[string]interface{}{
"grant_type": "client_credentials",
"client_id": a.clientId,
"client_secret": a.clientSecret,
})
if err != nil {
return "", 0, err
}
expiresIn, err = utils.TryInterface2Int64(result["expires_in"])
if err != nil {
return "", 0, err
}
a.incomingToken = result["access_token"].(string)
a.incomingExpire = time.Now().Unix() + expiresIn
return a.incomingToken, a.incomingExpire, nil
}
// ModifiedToken 更新token获取
func (a *API) ModifiedToken(userName string, password string) (modifiedToken string, modifiedExpire int64, err error) {
result, err := a.AccessAPI(IncomingUrlTest, TokenActive, http.MethodPost, "", map[string]interface{}{
"grant_type": "password",
"username": userName,
"password": password,
})
if err != nil {
return "", 0, err
}
modifiedExpire, err = utils.TryInterface2Int64(result["expires_in"])
if err != nil {
return "", 0, err
}
a.modifiedToken = result["access_token"].(string)
a.modifiedExpire = time.Now().Unix() + modifiedExpire
return a.modifiedToken, a.modifiedExpire, nil
}
// FileUpload 文件上传下载 filePath:文件url,由于controller:swagger不支持文件类型
func (a *API) FileUpload(filePath, imgType, sourcechnl, isOcr string) (*UploadImgResp, error) {
client := &http.Client{}
// 获取问价
resp, err := client.Get(filePath)
if err != nil {
return nil, err
}
imgData, _ := ioutil.ReadAll(resp.Body)
defer resp.Body.Close()
// 创建一个缓冲区来构建 multipart 请求
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
// 添加文件到 multipart 请求
part, err := writer.CreateFormFile("file", filePath)
if err != nil {
return nil, err
}
_, err = io.Copy(part, strings.NewReader(string(imgData)))
if err != nil {
return nil, err
}
// 添加其他表单字段
writer.WriteField("imgType", imgType)
writer.WriteField("sourcechnl", sourcechnl)
writer.WriteField("isOcr", isOcr)
// 关闭 writer
err = writer.Close()
if err != nil {
return nil, err
}
// 创建 HTTP 请求
req, err := http.NewRequest("POST", fmt.Sprintf("%s/%s", BaseTestUrl, FileUpload), body)
if err != nil {
return nil, err
}
// 设置 Content-Type 头
req.Header.Set("Content-Type", writer.FormDataContentType())
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", a.incomingToken))
// 发送请求
resp, err = client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
// 读取响应
data, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil, err
}
img := &UploadImgResp{}
json.Unmarshal(data, img)
return img, err
}
type UploadImgResp struct {
BatchNo interface{} `json:"batchNo"` // 批量号
Status string `json:"status"` // 00 成功, 01 正在处理中, 02 失败
Url string `json:"url"` // 拉卡拉文件地址
ShowUrl string `json:"showUrl"` // 拉卡拉文件url
Result interface{} `json:"result"` //
}
// signParamRSA 支付签名
func (a *API) signParamRSA(params map[string]interface{}, RSAPrivate string) (sig string, err error) {
block, _ := pem.Decode([]byte(RSAPrivate))
private, err := x509.ParsePKCS8PrivateKey(block.Bytes)
if err != nil {
return "", err
}
// 签名参数
body, err := json.Marshal(params)
if err != nil {
return "", err
}
//bodyData := base64.StdEncoding.EncodeToString(body)
nonceStr := GenerateSecureRandomString(12)
timeStamp := utils.Int64ToStr(time.Now().Unix())
context := fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n", a.appID, a.serialNo, timeStamp, nonceStr, string(body))
// 进行rsa加密签名
hashed := sha256.Sum256([]byte(context))
signedData, err := rsa.SignPKCS1v15(rand.Reader, private.(*rsa.PrivateKey), crypto.SHA256, hashed[:])
if err != nil {
return "", err
}
signData := base64.StdEncoding.EncodeToString(signedData)
authorization := fmt.Sprintf(`LKLAPI-SHA256withRSA appid="%s",serial_no="%s",timestamp="%s",nonce_str="%s",signature="%s"`, a.appID, a.serialNo, timeStamp, nonceStr, signData)
return authorization, nil
}
// GenerateSecureRandomString 获取随机字符串
func GenerateSecureRandomString(length int) string {
charset := "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
bytes := make([]byte, length)
charSetSize := big.NewInt(int64(len(charset)))
for i := range bytes {
num, _ := rand.Int(rand.Reader, charSetSize)
bytes[i] = charset[num.Int64()]
}
return string(bytes)
}
func GetOrderNumber(length int) string {
charset := "0123456789"
bytes := make([]byte, length)
charSetSize := big.NewInt(int64(len(charset)))
for i := range bytes {
num, _ := rand.Int(rand.Reader, charSetSize)
bytes[i] = charset[num.Int64()]
}
return utils.Time2TimeStrByFormat(time.Now(), TimeFormat) + string(bytes)
}
func SM4ECBEncrypt(plaintext, key []byte) ([]byte, error) {
if len(key) != sm4.BlockSize {
return nil, fmt.Errorf("SM4 密钥长度必须为 %d 字节", sm4.BlockSize)
}
// 补位处理 (PKCS5Padding)
paddedText := PKCS5Padding(plaintext, sm4.BlockSize)
// ECB 模式加密
ciphertext := make([]byte, len(paddedText))
for i := 0; i < len(paddedText); i += sm4.BlockSize {
block := paddedText[i : i+sm4.BlockSize]
encryptedBlock, err := sm4.Sm4Ecb(key, block, true) // true 表示加密
if err != nil {
return nil, err
}
copy(ciphertext[i:], encryptedBlock)
}
return ciphertext, nil
}
// PKCS5Padding 填充(与 PKCS7Padding 对于 128位分组等价
func PKCS5Padding(data []byte, blockSize int) []byte {
padding := blockSize - len(data)%blockSize
padtext := bytes.Repeat([]byte{byte(padding)}, padding)
return append(data, padtext...)
}
type CallBackResult struct {
Code string `json:"code"`
Message string `json:"message"`
}
// CallBackResultInfo 失败回调返回
func CallBackResultInfo(err error) *CallBackResult {
if err == nil {
return &CallBackResult{
Code: "SUCCESS",
Message: "执行成功",
}
}
return &CallBackResult{
Code: "400",
Message: err.Error(),
}
}