package westdex import ( "bytes" "encoding/json" "errors" "fmt" "io" "net/http" "strconv" "time" "tyapi-server/internal/shared/crypto" ) var ( ErrDatasource = errors.New("数据源异常") ErrSystem = errors.New("系统异常") ) type WestResp struct { Message string `json:"message"` Code string `json:"code"` Data string `json:"data"` ID string `json:"id"` ErrorCode *int `json:"error_code"` Reason string `json:"reason"` } type G05HZ01WestResp struct { Message string `json:"message"` Code string `json:"code"` Data json.RawMessage `json:"data"` ID string `json:"id"` ErrorCode *int `json:"error_code"` Reason string `json:"reason"` } type WestConfig struct { Url string Key string SecretId string SecretSecondId string } type WestDexService struct { config WestConfig } // NewWestDexService 是一个构造函数,用于初始化 WestDexService func NewWestDexService(url, key, secretId, secretSecondId string) *WestDexService { return &WestDexService{ config: WestConfig{ Url: url, Key: key, SecretId: secretId, SecretSecondId: secretSecondId, }, } } // CallAPI 调用西部数据的 API func (w *WestDexService) CallAPI(code string, reqData map[string]interface{}) (resp []byte, err error) { // 生成当前的13位时间戳 timestamp := strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10) // 构造请求URL reqUrl := fmt.Sprintf("%s/%s/%s?timestamp=%s", w.config.Url, w.config.SecretId, code, timestamp) jsonData, marshalErr := json.Marshal(reqData) if marshalErr != nil { return nil, fmt.Errorf("%w: %s", ErrSystem, marshalErr.Error()) } // 创建HTTP POST请求 req, newRequestErr := http.NewRequest("POST", reqUrl, bytes.NewBuffer(jsonData)) if newRequestErr != nil { return nil, fmt.Errorf("%w: %s", ErrSystem, newRequestErr.Error()) } // 设置请求头 req.Header.Set("Content-Type", "application/json") // 发送请求 client := &http.Client{} httpResp, clientDoErr := client.Do(req) if clientDoErr != nil { return nil, fmt.Errorf("%w: %s", ErrSystem, clientDoErr.Error()) } 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, fmt.Errorf("%w: %s", ErrSystem, ReadErr.Error()) } // 手动调用 json.Unmarshal 触发自定义的 UnmarshalJSON 方法 var westDexResp WestResp UnmarshalErr := json.Unmarshal(bodyBytes, &westDexResp) if UnmarshalErr != nil { return nil, UnmarshalErr } if westDexResp.Code != "00000" && westDexResp.Code != "200" && westDexResp.Code != "0" { if westDexResp.Data == "" { return nil, fmt.Errorf("%w: %s", ErrSystem, westDexResp.Message) } decryptedData, DecryptErr := crypto.WestDexDecrypt(westDexResp.Data, w.config.Key) if DecryptErr != nil { return nil, fmt.Errorf("%w: %s", ErrSystem, DecryptErr.Error()) } return decryptedData, fmt.Errorf("%w: %s", ErrDatasource, westDexResp.Message) } if westDexResp.Data == "" { return nil, fmt.Errorf("%w: %s", ErrSystem, westDexResp.Message) } decryptedData, DecryptErr := crypto.WestDexDecrypt(westDexResp.Data, w.config.Key) if DecryptErr != nil { return nil, fmt.Errorf("%w: %s", ErrSystem, DecryptErr.Error()) } return decryptedData, nil } return nil, fmt.Errorf("%w: 西部请求失败Code: %d", ErrSystem, httpResp.StatusCode) } // G05HZ01CallAPI 调用西部数据的 G05HZ01 API func (w *WestDexService) G05HZ01CallAPI(code string, reqData map[string]interface{}) (resp []byte, err error) { // 生成当前的13位时间戳 timestamp := strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10) // 构造请求URL reqUrl := fmt.Sprintf("%s/%s/%s?timestamp=%s", w.config.Url, w.config.SecretSecondId, code, timestamp) jsonData, marshalErr := json.Marshal(reqData) if marshalErr != nil { return nil, fmt.Errorf("%w: %s", ErrSystem, marshalErr.Error()) } // 创建HTTP POST请求 req, newRequestErr := http.NewRequest("POST", reqUrl, bytes.NewBuffer(jsonData)) if newRequestErr != nil { return nil, fmt.Errorf("%w: %s", ErrSystem, newRequestErr.Error()) } // 设置请求头 req.Header.Set("Content-Type", "application/json") // 发送请求 client := &http.Client{} httpResp, clientDoErr := client.Do(req) if clientDoErr != nil { return nil, fmt.Errorf("%w: %s", ErrSystem, clientDoErr.Error()) } 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, fmt.Errorf("%w: %s", ErrSystem, ReadErr.Error()) } var westDexResp G05HZ01WestResp UnmarshalErr := json.Unmarshal(bodyBytes, &westDexResp) if UnmarshalErr != nil { return nil, fmt.Errorf("%w: %s", ErrSystem, UnmarshalErr.Error()) } if westDexResp.Code != "0000" { if westDexResp.Data == nil { return nil, fmt.Errorf("%w: %s", ErrSystem, westDexResp.Message) } else { return westDexResp.Data, fmt.Errorf("%w: %s", ErrSystem, string(westDexResp.Data)) } } if westDexResp.Data == nil { return nil, fmt.Errorf("%w: %s", ErrSystem, westDexResp.Message) } return westDexResp.Data, nil } else { return nil, fmt.Errorf("%w: 西部请求失败Code: %d", ErrSystem, httpResp.StatusCode) } } func (w *WestDexService) Encrypt(data string) (string, error) { encryptedValue, err := crypto.WestDexEncrypt(data, w.config.Key) if err != nil { return "", ErrSystem } return encryptedValue, nil } func (w *WestDexService) Md5Encrypt(data string) string { return Md5Encrypt(data) } func (w *WestDexService) GetConfig() WestConfig { return w.config }