package service import ( "bytes" "encoding/json" "fmt" "io" "net/http" "time" "ycc-server/app/main/api/internal/config" "ycc-server/pkg/lzkit/crypto" "github.com/pkg/errors" ) // TianyuanResp 天远API通用响应结构 type TianyuanResp struct { Code int `json:"code"` Message string `json:"message"` Data string `json:"data"` // 加密后的数据 TransactionID string `json:"transaction_id"` // 交易ID } // TianyuanService 天远数据服务 type TianyuanService struct { config config.TianyuanConfig } // NewTianyuanService 是一个构造函数,用于初始化 TianyuanService func NewTianyuanService(c config.Config) *TianyuanService { return &TianyuanService{ config: c.TianyuanConfig, } } // Request 通用API请求方法 func (t *TianyuanService) Request(interfaceName string, params map[string]interface{}) (resp []byte, err error) { // 构造请求URL reqUrl := fmt.Sprintf("%s/%s", t.config.ApiUrl, interfaceName) // 将参数转换为JSON字符串 paramsJSON, err := json.Marshal(params) if err != nil { return nil, err } // 对参数进行AES加密 encryptedData, err := crypto.TianyuanEncrypt(paramsJSON, t.config.Key) if err != nil { return nil, err } // 构造请求数据 reqData := map[string]interface{}{ "data": encryptedData, } jsonData, marshalErr := json.Marshal(reqData) if marshalErr != nil { return nil, marshalErr } // 创建HTTP POST请求 req, newRequestErr := http.NewRequest("POST", reqUrl, bytes.NewBuffer(jsonData)) if newRequestErr != nil { return nil, newRequestErr } // 设置请求头 req.Header.Set("Content-Type", "application/json") req.Header.Set("Access-Id", t.config.AccessId) // 发送请求 client := &http.Client{ Timeout: 20 * time.Second, // 默认20秒超时 } httpResp, clientDoErr := client.Do(req) if clientDoErr != nil { return nil, clientDoErr } defer func(Body io.ReadCloser) { closeErr := Body.Close() if closeErr != nil { // 记录日志,但不中断程序 } }(httpResp.Body) // 检查请求是否成功 if httpResp.StatusCode == 200 { // 读取响应体 bodyBytes, ReadErr := io.ReadAll(httpResp.Body) if ReadErr != nil { return nil, ReadErr } // 解析响应 var tianyuanResp TianyuanResp UnmarshalErr := json.Unmarshal(bodyBytes, &tianyuanResp) if UnmarshalErr != nil { return nil, UnmarshalErr } if tianyuanResp.Code != 0 { return nil, errors.New(tianyuanResp.Message) } // 解密响应数据 if tianyuanResp.Data != "" { decryptedData, DecryptErr := crypto.TianyuanDecrypt(tianyuanResp.Data, t.config.Key) if DecryptErr != nil { return nil, DecryptErr } return decryptedData, nil } return bodyBytes, nil } return nil, fmt.Errorf("天远API请求失败Code: %d", httpResp.StatusCode) }