Files
tyapi-server/internal/infrastructure/external/alicloud/alicloud_service.go

143 lines
3.8 KiB
Go
Raw Normal View History

2025-08-04 17:16:38 +08:00
package alicloud
import (
2026-03-21 18:36:42 +08:00
"crypto/md5"
2025-08-04 17:16:38 +08:00
"errors"
"fmt"
"io"
"net/http"
"net/url"
"strings"
2025-11-02 20:33:28 +08:00
"time"
2026-03-21 18:36:42 +08:00
"tyapi-server/internal/shared/external_logger"
2025-08-04 17:16:38 +08:00
)
var (
ErrDatasource = errors.New("数据源异常")
ErrSystem = errors.New("系统异常")
)
// AlicloudConfig 阿里云配置
type AlicloudConfig struct {
Host string
AppCode string
}
// AlicloudService 阿里云服务
type AlicloudService struct {
config AlicloudConfig
2026-03-21 18:36:42 +08:00
logger *external_logger.ExternalServiceLogger
2025-08-04 17:16:38 +08:00
}
// NewAlicloudService 创建阿里云服务实例
2026-03-21 18:36:42 +08:00
func NewAlicloudService(host, appCode string, logger ...*external_logger.ExternalServiceLogger) *AlicloudService {
var serviceLogger *external_logger.ExternalServiceLogger
if len(logger) > 0 {
serviceLogger = logger[0]
}
2025-08-04 17:16:38 +08:00
return &AlicloudService{
config: AlicloudConfig{
Host: host,
AppCode: appCode,
},
2026-03-21 18:36:42 +08:00
logger: serviceLogger,
2025-08-04 17:16:38 +08:00
}
}
2026-03-21 18:36:42 +08:00
// generateRequestID 生成请求ID
func (a *AlicloudService) generateRequestID() string {
timestamp := time.Now().UnixNano()
hash := md5.Sum([]byte(fmt.Sprintf("%d_%s", timestamp, a.config.Host)))
return fmt.Sprintf("alicloud_%x", hash[:8])
}
2025-08-04 17:16:38 +08:00
// CallAPI 调用阿里云API的通用方法
// path: API路径如 "api-mall/api/id_card/check"
// params: 请求参数
func (a *AlicloudService) CallAPI(path string, params map[string]interface{}) (respBytes []byte, err error) {
2026-03-21 18:36:42 +08:00
startTime := time.Now()
requestID := a.generateRequestID()
transactionID := ""
2025-08-04 17:16:38 +08:00
// 构建请求URL
reqURL := a.config.Host + "/" + path
2026-03-21 18:36:42 +08:00
// 记录请求日志
if a.logger != nil {
a.logger.LogRequest(requestID, transactionID, path, reqURL)
}
2025-08-04 17:16:38 +08:00
// 构建请求参数
formData := url.Values{}
for key, value := range params {
formData.Set(key, fmt.Sprintf("%v", value))
}
// 创建HTTP请求
req, err := http.NewRequest("POST", reqURL, strings.NewReader(formData.Encode()))
if err != nil {
2026-03-21 18:36:42 +08:00
if a.logger != nil {
a.logger.LogError(requestID, transactionID, path, errors.Join(ErrSystem, err), params)
}
2025-08-04 17:16:38 +08:00
return nil, fmt.Errorf("%w: %s", ErrSystem, err.Error())
}
// 设置请求头
req.Header.Set("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8")
req.Header.Set("Authorization", "APPCODE "+a.config.AppCode)
2025-11-02 20:33:28 +08:00
// 发送请求超时时间设置为60秒
client := &http.Client{
Timeout: 60 * time.Second,
}
2025-08-04 17:16:38 +08:00
resp, err := client.Do(req)
if err != nil {
2025-11-02 20:33:28 +08:00
// 检查是否是超时错误
isTimeout := false
if netErr, ok := err.(interface{ Timeout() bool }); ok && netErr.Timeout() {
isTimeout = true
} else if errStr := err.Error();
errStr == "context deadline exceeded" ||
errStr == "timeout" ||
errStr == "Client.Timeout exceeded" ||
errStr == "net/http: request canceled" {
isTimeout = true
}
if isTimeout {
2026-03-21 18:36:42 +08:00
if a.logger != nil {
a.logger.LogError(requestID, transactionID, path, errors.Join(ErrDatasource, fmt.Errorf("API请求超时: %s", err.Error())), params)
}
2025-11-02 20:33:28 +08:00
return nil, fmt.Errorf("%w: API请求超时: %s", ErrDatasource, err.Error())
}
2026-03-21 18:36:42 +08:00
if a.logger != nil {
a.logger.LogError(requestID, transactionID, path, errors.Join(ErrSystem, err), params)
}
2025-08-04 17:16:38 +08:00
return nil, fmt.Errorf("%w: %s", ErrSystem, err.Error())
}
defer resp.Body.Close()
// 读取响应体
body, err := io.ReadAll(resp.Body)
if err != nil {
2026-03-21 18:36:42 +08:00
if a.logger != nil {
a.logger.LogError(requestID, transactionID, path, errors.Join(ErrSystem, err), params)
}
2025-08-04 17:16:38 +08:00
return nil, fmt.Errorf("%w: %s", ErrSystem, err.Error())
}
2026-03-21 18:36:42 +08:00
// 记录响应日志(不记录具体响应数据)
if a.logger != nil {
duration := time.Since(startTime)
a.logger.LogResponse(requestID, transactionID, path, resp.StatusCode, duration)
}
2025-08-04 17:16:38 +08:00
// 直接返回原始响应body让调用方自己处理
return body, nil
}
// GetConfig 获取配置信息
func (a *AlicloudService) GetConfig() AlicloudConfig {
return a.config
}