fix
This commit is contained in:
@@ -5,6 +5,7 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"tyapi-server/internal/application/api/commands"
|
"tyapi-server/internal/application/api/commands"
|
||||||
"tyapi-server/internal/application/api/dto"
|
"tyapi-server/internal/application/api/dto"
|
||||||
|
"tyapi-server/internal/application/api/utils"
|
||||||
"tyapi-server/internal/config"
|
"tyapi-server/internal/config"
|
||||||
entities "tyapi-server/internal/domains/api/entities"
|
entities "tyapi-server/internal/domains/api/entities"
|
||||||
"tyapi-server/internal/domains/api/repositories"
|
"tyapi-server/internal/domains/api/repositories"
|
||||||
@@ -80,6 +81,14 @@ func (s *ApiApplicationServiceImpl) CallApi(ctx context.Context, cmd *commands.A
|
|||||||
businessError = ErrInvalidAccessId
|
businessError = ErrInvalidAccessId
|
||||||
return ErrInvalidAccessId
|
return ErrInvalidAccessId
|
||||||
}
|
}
|
||||||
|
// 3. 查产品
|
||||||
|
product, err := s.productManagementService.GetProductByCode(txCtx, cmd.ApiName)
|
||||||
|
if err != nil {
|
||||||
|
s.logger.Error("查产品失败", zap.Error(err))
|
||||||
|
businessError = ErrProductNotFound
|
||||||
|
return ErrProductNotFound
|
||||||
|
}
|
||||||
|
apiCall.ProductId = &product.ID
|
||||||
// 加入UserId
|
// 加入UserId
|
||||||
apiCall.UserId = &apiUser.UserId
|
apiCall.UserId = &apiUser.UserId
|
||||||
if apiUser.IsFrozen() {
|
if apiUser.IsFrozen() {
|
||||||
@@ -109,14 +118,6 @@ func (s *ApiApplicationServiceImpl) CallApi(ctx context.Context, cmd *commands.A
|
|||||||
businessError = ErrArrears
|
businessError = ErrArrears
|
||||||
return ErrArrears
|
return ErrArrears
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. 查产品
|
|
||||||
product, err := s.productManagementService.GetProductByCode(txCtx, cmd.ApiName)
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Error("查产品失败", zap.Error(err))
|
|
||||||
businessError = ErrProductNotFound
|
|
||||||
return ErrProductNotFound
|
|
||||||
}
|
|
||||||
// 4. 查订阅
|
// 4. 查订阅
|
||||||
subscription, err := s.productSubscriptionService.GetUserSubscribedProduct(txCtx, apiUser.UserId, product.ID)
|
subscription, err := s.productSubscriptionService.GetUserSubscribedProduct(txCtx, apiUser.UserId, product.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -129,7 +130,6 @@ func (s *ApiApplicationServiceImpl) CallApi(ctx context.Context, cmd *commands.A
|
|||||||
businessError = ErrNotSubscribed
|
businessError = ErrNotSubscribed
|
||||||
return ErrNotSubscribed
|
return ErrNotSubscribed
|
||||||
}
|
}
|
||||||
apiCall.ProductId = &product.ID
|
|
||||||
if !product.IsValid() {
|
if !product.IsValid() {
|
||||||
s.logger.Error("产品已停用", zap.String("productId", product.ID))
|
s.logger.Error("产品已停用", zap.String("productId", product.ID))
|
||||||
businessError = ErrProductDisabled
|
businessError = ErrProductDisabled
|
||||||
@@ -172,7 +172,7 @@ func (s *ApiApplicationServiceImpl) CallApi(ctx context.Context, cmd *commands.A
|
|||||||
businessError = ErrSystem
|
businessError = ErrSystem
|
||||||
return ErrSystem
|
return ErrSystem
|
||||||
}
|
}
|
||||||
apiCall.ResponseData = &encryptedResponse
|
// apiCall.ResponseData = &encryptedResponse
|
||||||
|
|
||||||
// 8. 更新订阅使用次数
|
// 8. 更新订阅使用次数
|
||||||
subscription.IncrementAPIUsage(1)
|
subscription.IncrementAPIUsage(1)
|
||||||
@@ -193,7 +193,7 @@ func (s *ApiApplicationServiceImpl) CallApi(ctx context.Context, cmd *commands.A
|
|||||||
apiCall.Cost = &subscription.Price
|
apiCall.Cost = &subscription.Price
|
||||||
|
|
||||||
// 10. 标记成功
|
// 10. 标记成功
|
||||||
apiCall.MarkSuccess(encryptedResponse, subscription.Price)
|
apiCall.MarkSuccess(subscription.Price)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -392,6 +392,8 @@ func (s *ApiApplicationServiceImpl) GetUserApiCalls(ctx context.Context, userID
|
|||||||
}
|
}
|
||||||
if call.ErrorMsg != nil {
|
if call.ErrorMsg != nil {
|
||||||
item.ErrorMsg = call.ErrorMsg
|
item.ErrorMsg = call.ErrorMsg
|
||||||
|
// 添加翻译后的错误信息
|
||||||
|
item.TranslatedErrorMsg = utils.TranslateErrorMsg(call.ErrorType, call.ErrorMsg)
|
||||||
}
|
}
|
||||||
|
|
||||||
items = append(items, item)
|
items = append(items, item)
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ type ApiCallRecordResponse struct {
|
|||||||
Cost *string `json:"cost,omitempty"`
|
Cost *string `json:"cost,omitempty"`
|
||||||
ErrorType *string `json:"error_type,omitempty"`
|
ErrorType *string `json:"error_type,omitempty"`
|
||||||
ErrorMsg *string `json:"error_msg,omitempty"`
|
ErrorMsg *string `json:"error_msg,omitempty"`
|
||||||
|
TranslatedErrorMsg *string `json:"translated_error_msg,omitempty"`
|
||||||
CreatedAt string `json:"created_at"`
|
CreatedAt string `json:"created_at"`
|
||||||
UpdatedAt string `json:"updated_at"`
|
UpdatedAt string `json:"updated_at"`
|
||||||
}
|
}
|
||||||
@@ -87,4 +88,6 @@ func NewErrorResponse(code int, message, transactionId string) *ApiCallResponse
|
|||||||
TransactionId: transactionId,
|
TransactionId: transactionId,
|
||||||
Data: "",
|
Data: "",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
40
internal/application/api/utils/error_translator.go
Normal file
40
internal/application/api/utils/error_translator.go
Normal file
@@ -0,0 +1,40 @@
|
|||||||
|
package utils
|
||||||
|
|
||||||
|
// TranslateErrorMsg 翻译错误信息
|
||||||
|
func TranslateErrorMsg(errorType, errorMsg *string) *string {
|
||||||
|
if errorType == nil || errorMsg == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// 错误类型到中文描述的映射
|
||||||
|
errorTypeTranslations := map[string]string{
|
||||||
|
"invalid_access": "无效的访问凭证",
|
||||||
|
"frozen_account": "账户已被冻结",
|
||||||
|
"invalid_ip": "IP地址未授权",
|
||||||
|
"arrears": "账户余额不足",
|
||||||
|
"not_subscribed": "未订阅该产品",
|
||||||
|
"product_not_found": "产品不存在",
|
||||||
|
"product_disabled": "产品已停用",
|
||||||
|
"system_error": "系统内部错误",
|
||||||
|
"datasource_error": "数据源异常",
|
||||||
|
"invalid_param": "参数校验失败",
|
||||||
|
"decrypt_fail": "参数解密失败",
|
||||||
|
"query_empty": "查询结果为空",
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取错误类型的中文描述
|
||||||
|
translatedType, exists := errorTypeTranslations[*errorType]
|
||||||
|
if !exists {
|
||||||
|
// 如果没有找到对应的翻译,返回原始错误信息
|
||||||
|
return errorMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
// 构建翻译后的错误信息
|
||||||
|
translatedMsg := translatedType
|
||||||
|
if *errorMsg != "" && *errorMsg != *errorType {
|
||||||
|
// 如果原始错误信息不是错误类型本身,则组合显示
|
||||||
|
translatedMsg = translatedType + ":" + *errorMsg
|
||||||
|
}
|
||||||
|
|
||||||
|
return &translatedMsg
|
||||||
|
}
|
||||||
@@ -94,17 +94,16 @@ func NewApiCall(accessId, requestParams, clientIp string) (*ApiCall, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// MarkSuccess 标记为成功
|
// MarkSuccess 标记为成功
|
||||||
func (a *ApiCall) MarkSuccess(responseData string, cost decimal.Decimal) error {
|
func (a *ApiCall) MarkSuccess(cost decimal.Decimal) error {
|
||||||
// 校验除ErrorMsg和ErrorType外所有字段不能为空
|
// 校验除ErrorMsg和ErrorType外所有字段不能为空
|
||||||
if a.ID == "" || a.AccessId == "" || a.TransactionId == "" || a.RequestParams == "" || a.Status == "" || a.StartAt.IsZero() {
|
if a.ID == "" || a.AccessId == "" || a.TransactionId == "" || a.RequestParams == "" || a.Status == "" || a.StartAt.IsZero() {
|
||||||
return errors.New("ApiCall字段不能为空(除ErrorMsg和ErrorType)")
|
return errors.New("ApiCall字段不能为空(除ErrorMsg和ErrorType)")
|
||||||
}
|
}
|
||||||
// 可选字段也要有值
|
// 可选字段也要有值
|
||||||
if a.UserId == nil || a.ProductId == nil || responseData == "" {
|
if a.UserId == nil || a.ProductId == nil {
|
||||||
return errors.New("ApiCall标记成功时UserId、ProductId、ResponseData不能为空")
|
return errors.New("ApiCall标记成功时UserId、ProductId不能为空")
|
||||||
}
|
}
|
||||||
a.Status = ApiCallStatusSuccess
|
a.Status = ApiCallStatusSuccess
|
||||||
a.ResponseData = &responseData
|
|
||||||
endAt := time.Now()
|
endAt := time.Now()
|
||||||
a.EndAt = &endAt
|
a.EndAt = &endAt
|
||||||
a.Cost = &cost
|
a.Cost = &cost
|
||||||
|
|||||||
@@ -11,19 +11,19 @@ type ApiCallRepository interface {
|
|||||||
Update(ctx context.Context, call *entities.ApiCall) error
|
Update(ctx context.Context, call *entities.ApiCall) error
|
||||||
FindById(ctx context.Context, id string) (*entities.ApiCall, error)
|
FindById(ctx context.Context, id string) (*entities.ApiCall, error)
|
||||||
FindByUserId(ctx context.Context, userId string, limit, offset int) ([]*entities.ApiCall, error)
|
FindByUserId(ctx context.Context, userId string, limit, offset int) ([]*entities.ApiCall, error)
|
||||||
|
|
||||||
// 新增:分页查询用户API调用记录
|
// 新增:分页查询用户API调用记录
|
||||||
ListByUserId(ctx context.Context, userId string, options interfaces.ListOptions) ([]*entities.ApiCall, int64, error)
|
ListByUserId(ctx context.Context, userId string, options interfaces.ListOptions) ([]*entities.ApiCall, int64, error)
|
||||||
|
|
||||||
// 新增:根据条件筛选API调用记录
|
// 新增:根据条件筛选API调用记录
|
||||||
ListByUserIdWithFilters(ctx context.Context, userId string, filters map[string]interface{}, options interfaces.ListOptions) ([]*entities.ApiCall, int64, error)
|
ListByUserIdWithFilters(ctx context.Context, userId string, filters map[string]interface{}, options interfaces.ListOptions) ([]*entities.ApiCall, int64, error)
|
||||||
|
|
||||||
// 新增:根据条件筛选API调用记录(包含产品名称)
|
// 新增:根据条件筛选API调用记录(包含产品名称)
|
||||||
ListByUserIdWithFiltersAndProductName(ctx context.Context, userId string, filters map[string]interface{}, options interfaces.ListOptions) (map[string]string, []*entities.ApiCall, int64, error)
|
ListByUserIdWithFiltersAndProductName(ctx context.Context, userId string, filters map[string]interface{}, options interfaces.ListOptions) (map[string]string, []*entities.ApiCall, int64, error)
|
||||||
|
|
||||||
// 新增:统计用户API调用次数
|
// 新增:统计用户API调用次数
|
||||||
CountByUserId(ctx context.Context, userId string) (int64, error)
|
CountByUserId(ctx context.Context, userId string) (int64, error)
|
||||||
|
|
||||||
// 新增:根据TransactionID查询
|
// 新增:根据TransactionID查询
|
||||||
FindByTransactionId(ctx context.Context, transactionId string) (*entities.ApiCall, error)
|
FindByTransactionId(ctx context.Context, transactionId string) (*entities.ApiCall, error)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -282,12 +282,12 @@ func (h *ApiHandler) GetUserApiCalls(c *gin.Context) {
|
|||||||
if transactionId := c.Query("transaction_id"); transactionId != "" {
|
if transactionId := c.Query("transaction_id"); transactionId != "" {
|
||||||
filters["transaction_id"] = transactionId
|
filters["transaction_id"] = transactionId
|
||||||
}
|
}
|
||||||
|
|
||||||
// 产品名称筛选
|
// 产品名称筛选
|
||||||
if productName := c.Query("product_name"); productName != "" {
|
if productName := c.Query("product_name"); productName != "" {
|
||||||
filters["product_name"] = productName
|
filters["product_name"] = productName
|
||||||
}
|
}
|
||||||
|
|
||||||
// 状态筛选
|
// 状态筛选
|
||||||
if status := c.Query("status"); status != "" {
|
if status := c.Query("status"); status != "" {
|
||||||
filters["status"] = status
|
filters["status"] = status
|
||||||
|
|||||||
Reference in New Issue
Block a user