Files
tyapi-server/internal/application/api/api_application_service.go

683 lines
22 KiB
Go
Raw Normal View History

2025-07-28 01:46:39 +08:00
package api
import (
"context"
2025-08-18 14:13:16 +08:00
"encoding/json"
2025-07-28 01:46:39 +08:00
"errors"
"tyapi-server/internal/application/api/commands"
"tyapi-server/internal/application/api/dto"
2025-07-28 23:44:01 +08:00
"tyapi-server/internal/application/api/utils"
2025-07-28 01:46:39 +08:00
"tyapi-server/internal/config"
entities "tyapi-server/internal/domains/api/entities"
"tyapi-server/internal/domains/api/repositories"
"tyapi-server/internal/domains/api/services"
"tyapi-server/internal/domains/api/services/processors"
finance_services "tyapi-server/internal/domains/finance/services"
product_services "tyapi-server/internal/domains/product/services"
2025-08-02 02:54:21 +08:00
user_repositories "tyapi-server/internal/domains/user/repositories"
2025-07-28 01:46:39 +08:00
"tyapi-server/internal/shared/crypto"
"tyapi-server/internal/shared/database"
"tyapi-server/internal/shared/interfaces"
"go.uber.org/zap"
)
type ApiApplicationService interface {
CallApi(ctx context.Context, cmd *commands.ApiCallCommand) (string, string, error)
// 获取用户API密钥
GetUserApiKeys(ctx context.Context, userID string) (*dto.ApiKeysResponse, error)
// 用户白名单管理
GetUserWhiteList(ctx context.Context, userID string) (*dto.WhiteListListResponse, error)
AddWhiteListIP(ctx context.Context, userID string, ipAddress string) error
DeleteWhiteListIP(ctx context.Context, userID string, ipAddress string) error
// 获取用户API调用记录
GetUserApiCalls(ctx context.Context, userID string, filters map[string]interface{}, options interfaces.ListOptions) (*dto.ApiCallListResponse, error)
2025-08-04 22:02:09 +08:00
2025-08-02 02:54:21 +08:00
// 管理端API调用记录
GetAdminApiCalls(ctx context.Context, filters map[string]interface{}, options interfaces.ListOptions) (*dto.ApiCallListResponse, error)
2025-08-18 14:13:16 +08:00
// 加密参数接口
EncryptParams(ctx context.Context, userID string, cmd *commands.EncryptCommand) (string, error)
2025-08-27 22:19:19 +08:00
2025-08-18 14:13:16 +08:00
// 解密参数接口
DecryptParams(ctx context.Context, userID string, cmd *commands.DecryptCommand) (map[string]interface{}, error)
2025-08-27 22:19:19 +08:00
// 获取表单配置
GetFormConfig(ctx context.Context, apiCode string) (*dto.FormConfigResponse, error)
2025-07-28 01:46:39 +08:00
}
type ApiApplicationServiceImpl struct {
apiCallService services.ApiCallAggregateService
apiUserService services.ApiUserAggregateService
apiRequestService *services.ApiRequestService
2025-08-27 22:19:19 +08:00
formConfigService services.FormConfigService
2025-07-28 01:46:39 +08:00
apiCallRepository repositories.ApiCallRepository
walletService finance_services.WalletAggregateService
2025-08-04 22:02:09 +08:00
contractInfoService user_repositories.ContractInfoRepository
2025-07-28 01:46:39 +08:00
productManagementService *product_services.ProductManagementService
productSubscriptionService *product_services.ProductSubscriptionService
2025-08-02 02:54:21 +08:00
userRepo user_repositories.UserRepository
2025-07-28 01:46:39 +08:00
txManager *database.TransactionManager
config *config.Config
logger *zap.Logger
}
2025-08-27 22:19:19 +08:00
func NewApiApplicationService(apiCallService services.ApiCallAggregateService, apiUserService services.ApiUserAggregateService, apiRequestService *services.ApiRequestService, formConfigService services.FormConfigService, apiCallRepository repositories.ApiCallRepository, walletService finance_services.WalletAggregateService, productManagementService *product_services.ProductManagementService, productSubscriptionService *product_services.ProductSubscriptionService, userRepo user_repositories.UserRepository, txManager *database.TransactionManager, config *config.Config, logger *zap.Logger, contractInfoService user_repositories.ContractInfoRepository) ApiApplicationService {
return &ApiApplicationServiceImpl{apiCallService: apiCallService, apiUserService: apiUserService, apiRequestService: apiRequestService, formConfigService: formConfigService, apiCallRepository: apiCallRepository, walletService: walletService, productManagementService: productManagementService, productSubscriptionService: productSubscriptionService, userRepo: userRepo, txManager: txManager, config: config, logger: logger, contractInfoService: contractInfoService}
2025-07-28 01:46:39 +08:00
}
// CallApi 应用服务层统一入口
func (s *ApiApplicationServiceImpl) CallApi(ctx context.Context, cmd *commands.ApiCallCommand) (string, string, error) {
// 在事务外创建ApiCall
apiCall, err := s.apiCallService.CreateApiCall(cmd.AccessId, cmd.Data, cmd.ClientIP)
if err != nil {
s.logger.Error("创建ApiCall失败", zap.Error(err))
return "", "", ErrSystem
}
transactionId := apiCall.TransactionId
// 先保存初始状态
err = s.apiCallService.SaveApiCall(ctx, apiCall)
if err != nil {
s.logger.Error("保存ApiCall初始状态失败", zap.Error(err))
return "", "", ErrSystem
}
var encryptedResponse string
var businessError error
// 在事务中执行业务逻辑
err = s.txManager.ExecuteInTx(ctx, func(txCtx context.Context) error {
// 1. 查ApiUser
apiUser, err := s.apiUserService.LoadApiUserByAccessId(txCtx, cmd.AccessId)
if err != nil {
s.logger.Error("查ApiUser失败", zap.Error(err))
businessError = ErrInvalidAccessId
return ErrInvalidAccessId
}
2025-07-28 23:44:01 +08:00
// 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
2025-07-28 01:46:39 +08:00
// 加入UserId
apiCall.UserId = &apiUser.UserId
if apiUser.IsFrozen() {
s.logger.Error("账户已冻结", zap.String("userId", apiUser.UserId))
businessError = ErrFrozenAccount
return ErrFrozenAccount
}
2025-08-18 14:13:16 +08:00
// 在开发环境或调试模式下跳过IP白名单校验
if s.config.App.IsDevelopment() || cmd.Options.IsDebug {
2025-08-27 22:19:19 +08:00
s.logger.Info("跳过IP白名单校验",
zap.String("userId", apiUser.UserId),
2025-08-18 14:13:16 +08:00
zap.String("ip", cmd.ClientIP),
zap.Bool("isDevelopment", s.config.App.IsDevelopment()),
zap.Bool("isDebug", cmd.Options.IsDebug))
2025-07-28 01:46:39 +08:00
} else {
if !apiUser.IsWhiteListed(cmd.ClientIP) {
s.logger.Error("IP不在白名单内", zap.String("userId", apiUser.UserId), zap.String("ip", cmd.ClientIP))
businessError = ErrInvalidIP
return ErrInvalidIP
}
}
// 2. 查钱包
wallet, err := s.walletService.LoadWalletByUserId(txCtx, apiUser.UserId)
if err != nil {
s.logger.Error("查钱包失败", zap.Error(err))
businessError = ErrSystem
return ErrSystem
}
if wallet.IsArrears() {
s.logger.Error("账户已欠费", zap.String("userId", apiUser.UserId))
businessError = ErrArrears
return ErrArrears
}
// 4. 查订阅
subscription, err := s.productSubscriptionService.GetUserSubscribedProduct(txCtx, apiUser.UserId, product.ID)
if err != nil {
s.logger.Error("查订阅失败", zap.Error(err))
businessError = ErrSystem
return ErrSystem
}
if subscription == nil {
s.logger.Error("用户未订阅该产品", zap.String("userId", apiUser.UserId), zap.String("productId", product.ID))
businessError = ErrNotSubscribed
return ErrNotSubscribed
}
if !product.IsValid() {
s.logger.Error("产品已停用", zap.String("productId", product.ID))
businessError = ErrProductDisabled
return ErrProductDisabled
}
// 5. 解密参数
requestParams, err := crypto.AesDecrypt(cmd.Data, apiUser.SecretKey)
if err != nil {
s.logger.Error("解密参数失败", zap.Error(err))
businessError = ErrDecryptFail
return ErrDecryptFail
}
// 6. 调用API
2025-08-04 22:02:09 +08:00
// 查询用户的合同信息获取合同编号
contractCode := "" // 默认空字符串
contractInfo, err := s.contractInfoService.FindByUserID(txCtx, apiUser.UserId)
if err == nil && len(contractInfo) > 0 {
contractCode = contractInfo[0].ContractCode
} else {
s.logger.Error("查合同信息失败", zap.Error(err))
businessError = ErrSystem
return ErrSystem
}
// 创建CallContext传递合同编号
callContext := &processors.CallContext{
ContractCode: contractCode,
}
2025-08-27 22:19:19 +08:00
// 将transactionId放入ctx中供外部服务使用
ctxWithTransactionId := context.WithValue(txCtx, "transaction_id", transactionId)
2025-08-27 22:19:19 +08:00
response, err := s.apiRequestService.PreprocessRequestApi(ctxWithTransactionId, cmd.ApiName, requestParams, &cmd.Options, callContext)
2025-07-28 01:46:39 +08:00
if err != nil {
if errors.Is(err, processors.ErrDatasource) {
s.logger.Error("调用API失败", zap.Error(err))
businessError = ErrSystem
return ErrSystem
} else if errors.Is(err, processors.ErrInvalidParam) {
s.logger.Error("调用API失败", zap.Error(err))
businessError = ErrInvalidParam
return ErrInvalidParam
} else if errors.Is(err, processors.ErrNotFound) {
s.logger.Error("调用API失败", zap.Error(err))
businessError = ErrQueryEmpty
return ErrQueryEmpty
} else {
s.logger.Error("调用API失败", zap.Error(err))
businessError = ErrSystem
return ErrSystem
}
}
// 7. 加密响应
encryptedResponse, err = crypto.AesEncrypt(response, apiUser.SecretKey)
if err != nil {
s.logger.Error("加密响应失败", zap.Error(err))
businessError = ErrSystem
return ErrSystem
}
2025-07-28 23:44:01 +08:00
// apiCall.ResponseData = &encryptedResponse
2025-07-28 01:46:39 +08:00
2025-07-31 15:41:00 +08:00
// 8. 更新订阅使用次数(使用乐观锁)
// err = s.productSubscriptionService.IncrementSubscriptionAPIUsage(txCtx, subscription.ID, 1)
// if err != nil {
// s.logger.Error("更新订阅使用次数失败", zap.Error(err))
// businessError = ErrSystem
// return ErrSystem
// }
2025-07-28 01:46:39 +08:00
// 9. 扣钱
err = s.walletService.Deduct(txCtx, apiUser.UserId, subscription.Price, apiCall.ID, transactionId, product.ID)
if err != nil {
s.logger.Error("扣钱失败", zap.Error(err))
businessError = ErrSystem
return ErrSystem
}
apiCall.Cost = &subscription.Price
// 10. 标记成功
2025-07-28 23:44:01 +08:00
apiCall.MarkSuccess(subscription.Price)
2025-07-28 01:46:39 +08:00
return nil
})
// 根据事务结果更新ApiCall状态
if err != nil {
// 事务失败根据错误类型标记ApiCall
if businessError != nil {
// 使用业务错误类型
switch businessError {
case ErrInvalidAccessId:
apiCall.MarkFailed(entities.ApiCallErrorInvalidAccess, err.Error())
case ErrFrozenAccount:
apiCall.MarkFailed(entities.ApiCallErrorFrozenAccount, "")
case ErrInvalidIP:
apiCall.MarkFailed(entities.ApiCallErrorInvalidIP, "")
case ErrArrears:
apiCall.MarkFailed(entities.ApiCallErrorArrears, "")
case ErrProductNotFound:
apiCall.MarkFailed(entities.ApiCallErrorProductNotFound, err.Error())
case ErrProductDisabled:
apiCall.MarkFailed(entities.ApiCallErrorProductDisabled, "")
case ErrNotSubscribed:
apiCall.MarkFailed(entities.ApiCallErrorNotSubscribed, "")
case ErrDecryptFail:
apiCall.MarkFailed(entities.ApiCallErrorDecryptFail, err.Error())
case ErrInvalidParam:
apiCall.MarkFailed(entities.ApiCallErrorInvalidParam, err.Error())
case ErrQueryEmpty:
apiCall.MarkFailed(entities.ApiCallErrorQueryEmpty, "")
default:
apiCall.MarkFailed(entities.ApiCallErrorSystem, err.Error())
}
} else {
// 系统错误
apiCall.MarkFailed(entities.ApiCallErrorSystem, err.Error())
}
}
// 保存最终状态
err = s.apiCallService.SaveApiCall(ctx, apiCall)
if err != nil {
s.logger.Error("保存ApiCall最终状态失败", zap.Error(err))
// 即使保存失败,也返回业务结果
}
if businessError != nil {
return transactionId, "", businessError
}
return transactionId, encryptedResponse, nil
}
// GetUserApiKeys 获取用户API密钥
func (s *ApiApplicationServiceImpl) GetUserApiKeys(ctx context.Context, userID string) (*dto.ApiKeysResponse, error) {
apiUser, err := s.apiUserService.LoadApiUserByUserId(ctx, userID)
if err != nil {
return nil, err
}
return &dto.ApiKeysResponse{
ID: apiUser.ID,
UserID: apiUser.UserId,
AccessID: apiUser.AccessId,
SecretKey: apiUser.SecretKey,
Status: apiUser.Status,
CreatedAt: apiUser.CreatedAt,
UpdatedAt: apiUser.UpdatedAt,
}, nil
}
// GetUserWhiteList 获取用户白名单列表
func (s *ApiApplicationServiceImpl) GetUserWhiteList(ctx context.Context, userID string) (*dto.WhiteListListResponse, error) {
apiUser, err := s.apiUserService.LoadApiUserByUserId(ctx, userID)
if err != nil {
return nil, err
}
// 确保WhiteList不为nil
if apiUser.WhiteList == nil {
apiUser.WhiteList = []string{}
}
// 将白名单字符串数组转换为响应格式
var items []dto.WhiteListResponse
for _, ip := range apiUser.WhiteList {
items = append(items, dto.WhiteListResponse{
ID: apiUser.ID, // 使用API用户ID作为标识
UserID: apiUser.UserId,
IPAddress: ip,
CreatedAt: apiUser.CreatedAt, // 使用API用户创建时间
})
}
return &dto.WhiteListListResponse{
Items: items,
Total: len(items),
}, nil
}
// AddWhiteListIP 添加白名单IP
func (s *ApiApplicationServiceImpl) AddWhiteListIP(ctx context.Context, userID string, ipAddress string) error {
apiUser, err := s.apiUserService.LoadApiUserByUserId(ctx, userID)
if err != nil {
return err
}
// 确保WhiteList不为nil
if apiUser.WhiteList == nil {
apiUser.WhiteList = []string{}
}
// 使用实体的领域方法添加IP到白名单
err = apiUser.AddToWhiteList(ipAddress)
if err != nil {
return err
}
// 保存更新
err = s.apiUserService.SaveApiUser(ctx, apiUser)
if err != nil {
return err
}
return nil
}
// DeleteWhiteListIP 删除白名单IP
func (s *ApiApplicationServiceImpl) DeleteWhiteListIP(ctx context.Context, userID string, ipAddress string) error {
apiUser, err := s.apiUserService.LoadApiUserByUserId(ctx, userID)
if err != nil {
return err
}
// 确保WhiteList不为nil
if apiUser.WhiteList == nil {
apiUser.WhiteList = []string{}
}
// 使用实体的领域方法删除IP
err = apiUser.RemoveFromWhiteList(ipAddress)
if err != nil {
return err
}
// 保存更新
err = s.apiUserService.SaveApiUser(ctx, apiUser)
if err != nil {
return err
}
return nil
}
// GetUserApiCalls 获取用户API调用记录
func (s *ApiApplicationServiceImpl) GetUserApiCalls(ctx context.Context, userID string, filters map[string]interface{}, options interfaces.ListOptions) (*dto.ApiCallListResponse, error) {
// 查询API调用记录包含产品名称
productNameMap, calls, total, err := s.apiCallRepository.ListByUserIdWithFiltersAndProductName(ctx, userID, filters, options)
if err != nil {
s.logger.Error("查询API调用记录失败", zap.Error(err), zap.String("userID", userID))
return nil, err
}
// 转换为响应DTO
var items []dto.ApiCallRecordResponse
for _, call := range calls {
item := dto.ApiCallRecordResponse{
ID: call.ID,
AccessId: call.AccessId,
UserId: *call.UserId,
TransactionId: call.TransactionId,
ClientIp: call.ClientIp,
Status: call.Status,
StartAt: call.StartAt.Format("2006-01-02 15:04:05"),
CreatedAt: call.CreatedAt.Format("2006-01-02 15:04:05"),
UpdatedAt: call.UpdatedAt.Format("2006-01-02 15:04:05"),
}
// 处理可选字段
if call.ProductId != nil {
item.ProductId = call.ProductId
}
// 从映射中获取产品名称
if productName, exists := productNameMap[call.ID]; exists {
item.ProductName = &productName
}
if call.EndAt != nil {
endAt := call.EndAt.Format("2006-01-02 15:04:05")
item.EndAt = &endAt
}
if call.Cost != nil {
cost := call.Cost.String()
item.Cost = &cost
}
if call.ErrorType != nil {
item.ErrorType = call.ErrorType
}
if call.ErrorMsg != nil {
item.ErrorMsg = call.ErrorMsg
2025-07-28 23:44:01 +08:00
// 添加翻译后的错误信息
item.TranslatedErrorMsg = utils.TranslateErrorMsg(call.ErrorType, call.ErrorMsg)
2025-07-28 01:46:39 +08:00
}
items = append(items, item)
}
return &dto.ApiCallListResponse{
Items: items,
Total: total,
Page: options.Page,
Size: options.PageSize,
}, nil
}
2025-08-02 02:54:21 +08:00
// GetAdminApiCalls 获取管理端API调用记录
func (s *ApiApplicationServiceImpl) GetAdminApiCalls(ctx context.Context, filters map[string]interface{}, options interfaces.ListOptions) (*dto.ApiCallListResponse, error) {
// 查询API调用记录包含产品名称
productNameMap, calls, total, err := s.apiCallRepository.ListWithFiltersAndProductName(ctx, filters, options)
if err != nil {
s.logger.Error("查询API调用记录失败", zap.Error(err))
return nil, err
}
// 转换为响应DTO
var items []dto.ApiCallRecordResponse
for _, call := range calls {
2025-08-29 16:14:36 +08:00
// 基础字段安全检查
if call.ID == "" {
s.logger.Warn("跳过无效的API调用记录ID为空")
continue
}
2025-08-02 02:54:21 +08:00
item := dto.ApiCallRecordResponse{
ID: call.ID,
AccessId: call.AccessId,
TransactionId: call.TransactionId,
ClientIp: call.ClientIp,
Status: call.Status,
2025-08-29 16:14:36 +08:00
}
// 安全设置用户ID
if call.UserId != nil && *call.UserId != "" {
item.UserId = *call.UserId
} else {
item.UserId = "未知用户"
}
// 安全设置时间字段
if !call.StartAt.IsZero() {
item.StartAt = call.StartAt.Format("2006-01-02 15:04:05")
} else {
item.StartAt = "未知时间"
}
if !call.CreatedAt.IsZero() {
item.CreatedAt = call.CreatedAt.Format("2006-01-02 15:04:05")
} else {
item.CreatedAt = "未知时间"
}
if !call.UpdatedAt.IsZero() {
item.UpdatedAt = call.UpdatedAt.Format("2006-01-02 15:04:05")
} else {
item.UpdatedAt = "未知时间"
2025-08-02 02:54:21 +08:00
}
// 处理可选字段
2025-08-29 16:14:36 +08:00
if call.ProductId != nil && *call.ProductId != "" {
2025-08-02 02:54:21 +08:00
item.ProductId = call.ProductId
}
2025-09-01 18:29:59 +08:00
2025-08-02 02:54:21 +08:00
// 从映射中获取产品名称
2025-08-29 16:14:36 +08:00
if productName, exists := productNameMap[call.ID]; exists && productName != "" {
2025-08-02 02:54:21 +08:00
item.ProductName = &productName
}
2025-09-01 18:29:59 +08:00
2025-08-29 16:14:36 +08:00
// 安全设置结束时间
if call.EndAt != nil && !call.EndAt.IsZero() {
2025-08-02 02:54:21 +08:00
endAt := call.EndAt.Format("2006-01-02 15:04:05")
item.EndAt = &endAt
}
2025-09-01 18:29:59 +08:00
2025-08-29 16:14:36 +08:00
// 安全设置费用
2025-08-02 02:54:21 +08:00
if call.Cost != nil {
cost := call.Cost.String()
2025-08-29 16:14:36 +08:00
if cost != "" {
item.Cost = &cost
}
2025-08-02 02:54:21 +08:00
}
2025-09-01 18:29:59 +08:00
2025-08-29 16:14:36 +08:00
// 安全设置错误类型
if call.ErrorType != nil && *call.ErrorType != "" {
2025-08-02 02:54:21 +08:00
item.ErrorType = call.ErrorType
}
2025-09-01 18:29:59 +08:00
2025-08-29 16:14:36 +08:00
// 安全设置错误信息
if call.ErrorMsg != nil && *call.ErrorMsg != "" {
2025-08-02 02:54:21 +08:00
item.ErrorMsg = call.ErrorMsg
// 添加翻译后的错误信息
2025-08-29 16:14:36 +08:00
if call.ErrorType != nil && *call.ErrorType != "" {
item.TranslatedErrorMsg = utils.TranslateErrorMsg(call.ErrorType, call.ErrorMsg)
}
2025-08-02 02:54:21 +08:00
}
2025-08-29 16:14:36 +08:00
// 获取用户信息和企业名称(增强空指针防护)
if call.UserId != nil && *call.UserId != "" {
2025-08-02 02:54:21 +08:00
user, err := s.userRepo.GetByIDWithEnterpriseInfo(ctx, *call.UserId)
2025-08-29 16:14:36 +08:00
if err == nil && user.ID != "" {
2025-08-02 02:54:21 +08:00
companyName := "未知企业"
2025-09-01 18:29:59 +08:00
2025-08-29 16:14:36 +08:00
// 安全获取企业名称
if user.EnterpriseInfo != nil && user.EnterpriseInfo.CompanyName != "" {
2025-08-02 02:54:21 +08:00
companyName = user.EnterpriseInfo.CompanyName
}
2025-09-01 18:29:59 +08:00
2025-08-02 02:54:21 +08:00
item.CompanyName = &companyName
2025-09-01 18:29:59 +08:00
2025-08-29 16:14:36 +08:00
// 安全构建用户响应
2025-08-02 02:54:21 +08:00
item.User = &dto.UserSimpleResponse{
ID: user.ID,
CompanyName: companyName,
Phone: user.Phone,
}
2025-09-01 18:29:59 +08:00
2025-08-29 16:14:36 +08:00
// 验证用户数据的完整性
if user.Phone == "" {
2025-09-01 18:29:59 +08:00
s.logger.Warn("用户手机号为空",
2025-08-29 16:14:36 +08:00
zap.String("user_id", user.ID),
zap.String("call_id", call.ID))
item.User.Phone = "未知手机号"
}
} else {
// 用户查询失败或用户数据不完整时的处理
if err != nil {
2025-09-01 18:29:59 +08:00
s.logger.Warn("获取用户信息失败",
2025-08-29 16:14:36 +08:00
zap.String("user_id", *call.UserId),
zap.String("call_id", call.ID),
zap.Error(err))
} else if user.ID == "" {
2025-09-01 18:29:59 +08:00
s.logger.Warn("用户ID为空",
2025-08-29 16:14:36 +08:00
zap.String("call_user_id", *call.UserId),
zap.String("call_id", call.ID))
}
2025-09-01 18:29:59 +08:00
2025-08-29 16:14:36 +08:00
// 设置默认值
defaultCompanyName := "未知企业"
item.CompanyName = &defaultCompanyName
item.User = &dto.UserSimpleResponse{
ID: "未知用户",
CompanyName: defaultCompanyName,
Phone: "未知手机号",
}
}
} else {
// 用户ID为空时的处理
defaultCompanyName := "未知企业"
item.CompanyName = &defaultCompanyName
item.User = &dto.UserSimpleResponse{
ID: "未知用户",
CompanyName: defaultCompanyName,
Phone: "未知手机号",
2025-08-02 02:54:21 +08:00
}
}
items = append(items, item)
}
return &dto.ApiCallListResponse{
Items: items,
Total: total,
Page: options.Page,
Size: options.PageSize,
}, nil
}
2025-08-18 14:13:16 +08:00
// EncryptParams 加密参数
func (s *ApiApplicationServiceImpl) EncryptParams(ctx context.Context, userID string, cmd *commands.EncryptCommand) (string, error) {
// 1. 将数据转换为JSON字节数组
jsonData, err := json.Marshal(cmd.Data)
if err != nil {
s.logger.Error("序列化参数失败", zap.Error(err))
return "", err
}
2025-08-27 22:19:19 +08:00
2025-08-18 14:13:16 +08:00
// 2. 使用前端传来的SecretKey进行加密
encryptedData, err := crypto.AesEncrypt(jsonData, cmd.SecretKey)
if err != nil {
s.logger.Error("加密参数失败", zap.Error(err))
return "", err
}
return encryptedData, nil
}
// DecryptParams 解密参数
func (s *ApiApplicationServiceImpl) DecryptParams(ctx context.Context, userID string, cmd *commands.DecryptCommand) (map[string]interface{}, error) {
// 1. 使用前端传来的SecretKey进行解密
decryptedData, err := crypto.AesDecrypt(cmd.EncryptedData, cmd.SecretKey)
if err != nil {
s.logger.Error("解密参数失败", zap.Error(err))
return nil, err
}
2025-08-27 22:19:19 +08:00
2025-08-18 14:13:16 +08:00
// 2. 将解密后的JSON字节数组转换为map
var result map[string]interface{}
err = json.Unmarshal(decryptedData, &result)
if err != nil {
s.logger.Error("反序列化解密数据失败", zap.Error(err))
return nil, err
}
return result, nil
}
2025-08-27 22:19:19 +08:00
// GetFormConfig 获取指定API的表单配置
func (s *ApiApplicationServiceImpl) GetFormConfig(ctx context.Context, apiCode string) (*dto.FormConfigResponse, error) {
// 调用领域服务获取表单配置
config, err := s.formConfigService.GetFormConfig(apiCode)
if err != nil {
s.logger.Error("获取表单配置失败", zap.String("api_code", apiCode), zap.Error(err))
return nil, err
}
if config == nil {
return nil, nil
}
// 转换为应用层DTO
response := &dto.FormConfigResponse{
ApiCode: config.ApiCode,
Fields: make([]dto.FormField, len(config.Fields)),
}
for i, field := range config.Fields {
response.Fields[i] = dto.FormField{
Name: field.Name,
Label: field.Label,
Type: field.Type,
Required: field.Required,
Validation: field.Validation,
Description: field.Description,
Example: field.Example,
Placeholder: field.Placeholder,
}
}
return response, nil
}