fix
This commit is contained in:
@@ -119,13 +119,3 @@ func ProcessQYGL23T7Request(ctx context.Context, params []byte, deps *processors
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// createStatusResponse 创建状态响应
|
||||
func createStatusResponse(status int) []byte {
|
||||
response := map[string]interface{}{
|
||||
"status": status,
|
||||
}
|
||||
|
||||
respBytes, _ := json.Marshal(response)
|
||||
return respBytes
|
||||
}
|
||||
|
||||
@@ -24,6 +24,26 @@ func ProcessQYGL5CMPRequest(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
|
||||
// 第一步:企业信息验证 - 调用天眼查API
|
||||
_, err := verifyEnterpriseInfo(ctx, paramsDto, deps)
|
||||
if err != nil {
|
||||
// 企业信息验证失败,只返回简单的状态码
|
||||
return createStatusResponse(1), nil
|
||||
}
|
||||
|
||||
// 企业信息验证通过,继续个人信息验证
|
||||
_, err = verifyPersonalInfo(ctx, paramsDto, deps)
|
||||
if err != nil {
|
||||
// 个人信息验证失败,只返回简单的状态码
|
||||
return createStatusResponse(1), nil
|
||||
}
|
||||
|
||||
// 两个验证都通过,只返回成功状态码
|
||||
return createStatusResponse(0), nil
|
||||
}
|
||||
|
||||
// verifyEnterpriseInfo 验证企业信息
|
||||
func verifyEnterpriseInfo(ctx context.Context, paramsDto dto.QYGL5CMPReq, deps *processors.ProcessorDependencies) (map[string]interface{}, error) {
|
||||
// 构建API调用参数
|
||||
apiParams := map[string]string{
|
||||
"code": paramsDto.EntCode,
|
||||
@@ -39,45 +59,41 @@ func ProcessQYGL5CMPRequest(ctx context.Context, params []byte, deps *processors
|
||||
|
||||
// 检查天眼查API调用是否成功
|
||||
if !response.Success {
|
||||
// 天眼查API调用失败,返回企业信息校验不通过
|
||||
return createStatusResponsess(1), nil
|
||||
return nil, fmt.Errorf("天眼查API调用失败")
|
||||
}
|
||||
|
||||
// 解析天眼查响应数据
|
||||
if response.Data == nil {
|
||||
// 天眼查响应数据为空,返回企业信息校验不通过
|
||||
return createStatusResponsess(1), nil
|
||||
return nil, fmt.Errorf("天眼查响应数据为空")
|
||||
}
|
||||
|
||||
// 将response.Data转换为JSON字符串,然后使用gjson解析
|
||||
dataBytes, err := json.Marshal(response.Data)
|
||||
if err != nil {
|
||||
// 数据序列化失败,返回企业信息校验不通过
|
||||
return createStatusResponsess(1), nil
|
||||
return nil, fmt.Errorf("数据序列化失败")
|
||||
}
|
||||
|
||||
// 使用gjson解析嵌套的data.result.data字段
|
||||
result := gjson.GetBytes(dataBytes, "result")
|
||||
if !result.Exists() {
|
||||
// 字段不存在,返回企业信息校验不通过
|
||||
return createStatusResponsess(1), nil
|
||||
return nil, fmt.Errorf("result字段不存在")
|
||||
}
|
||||
|
||||
// 检查data.result.data是否等于1
|
||||
if result.Int() != 1 {
|
||||
// 不等于1,返回企业信息校验不通过
|
||||
return createStatusResponsess(1), nil
|
||||
return nil, fmt.Errorf("企业信息验证不通过")
|
||||
}
|
||||
|
||||
// 天眼查三要素验证通过,继续调用星维身份证三要素验证
|
||||
if err := json.Unmarshal(params, ¶msDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, err)
|
||||
}
|
||||
|
||||
if err := deps.Validator.ValidateStruct(paramsDto); err != nil {
|
||||
return nil, errors.Join(processors.ErrInvalidParam, err)
|
||||
}
|
||||
// 构建天眼查API返回的数据结构
|
||||
return map[string]interface{}{
|
||||
"success": response.Success,
|
||||
"message": response.Message,
|
||||
"data": response.Data,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// verifyPersonalInfo 验证个人信息并返回API数据
|
||||
func verifyPersonalInfo(ctx context.Context, paramsDto dto.QYGL5CMPReq, deps *processors.ProcessorDependencies) (map[string]interface{}, error) {
|
||||
// 构建请求数据,将项目规范的字段名转换为 XingweiService 需要的字段名
|
||||
reqData := map[string]interface{}{
|
||||
"name": paramsDto.LegalPerson,
|
||||
@@ -89,6 +105,7 @@ func ProcessQYGL5CMPRequest(ctx context.Context, params []byte, deps *processors
|
||||
projectID := "CDJ-1100244702166183936"
|
||||
respBytes, err := deps.XingweiService.CallAPI(ctx, projectID, reqData)
|
||||
if err != nil {
|
||||
// 个人信息验证失败,返回错误状态
|
||||
if errors.Is(err, xingwei.ErrNotFound) {
|
||||
return nil, errors.Join(processors.ErrNotFound, err)
|
||||
} else if errors.Is(err, xingwei.ErrDatasource) {
|
||||
@@ -106,42 +123,6 @@ func ProcessQYGL5CMPRequest(ctx context.Context, params []byte, deps *processors
|
||||
return nil, errors.Join(processors.ErrSystem, fmt.Errorf("解析星维API响应失败: %w", err))
|
||||
}
|
||||
|
||||
// 构建天眼查API返回的数据结构
|
||||
tianYanChaData := map[string]interface{}{
|
||||
"success": response.Success,
|
||||
"message": response.Message,
|
||||
"data": response.Data,
|
||||
}
|
||||
|
||||
// 解析status响应(将JSON字节解析为对象)
|
||||
statusBytes := createStatusResponsess(0) // 验证通过,status为0
|
||||
var statusData map[string]interface{}
|
||||
if err := json.Unmarshal(statusBytes, &statusData); err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, fmt.Errorf("解析status响应失败: %w", err))
|
||||
}
|
||||
|
||||
// 合并两个API的返回数据
|
||||
mergedData := map[string]interface{}{
|
||||
"Personal Information": xingweiData, // 星维API返回的数据
|
||||
"Enterprise Information": tianYanChaData, // 天眼查API返回的数据
|
||||
"status": statusData, // 解析后的status对象
|
||||
}
|
||||
|
||||
// 将合并后的数据序列化为JSON
|
||||
mergedBytes, err := json.Marshal(mergedData)
|
||||
if err != nil {
|
||||
return nil, errors.Join(processors.ErrSystem, fmt.Errorf("合并数据序列化失败: %w", err))
|
||||
}
|
||||
|
||||
return mergedBytes, nil
|
||||
|
||||
}
|
||||
|
||||
// createStatusResponsess 创建状态响应
|
||||
func createStatusResponsess(status int) []byte {
|
||||
response := map[string]interface{}{
|
||||
"status": status,
|
||||
}
|
||||
respBytes, _ := json.Marshal(response)
|
||||
return respBytes
|
||||
// 返回星维API的全部数据
|
||||
return xingweiData, nil
|
||||
}
|
||||
|
||||
12
internal/domains/api/services/processors/qygl/utils.go
Normal file
12
internal/domains/api/services/processors/qygl/utils.go
Normal file
@@ -0,0 +1,12 @@
|
||||
package qygl
|
||||
|
||||
import "encoding/json"
|
||||
|
||||
// createStatusResponse 创建状态响应
|
||||
func createStatusResponse(status int) []byte {
|
||||
response := map[string]interface{}{
|
||||
"status": status,
|
||||
}
|
||||
respBytes, _ := json.Marshal(response)
|
||||
return respBytes
|
||||
}
|
||||
@@ -71,7 +71,7 @@ func (s *EnterpriseInfoSubmitRecordService) Save(ctx context.Context, enterprise
|
||||
return s.repositories.Create(ctx, enterpriseInfoSubmitRecord)
|
||||
}
|
||||
|
||||
// ValidateWithWestdex 调用QYGL23T7处理器验证企业信息
|
||||
// ValidateWithWestdex 调用QYGL5CMP处理器验证企业信息
|
||||
func (s *EnterpriseInfoSubmitRecordService) ValidateWithWestdex(ctx context.Context, info *value_objects.EnterpriseInfo) error {
|
||||
if info == nil {
|
||||
return errors.New("企业信息不能为空")
|
||||
@@ -89,12 +89,13 @@ func (s *EnterpriseInfoSubmitRecordService) ValidateWithWestdex(ctx context.Cont
|
||||
// return nil
|
||||
// }
|
||||
|
||||
// 构建QYGL23T7请求参数
|
||||
reqDto := dto.QYGL23T7Req{
|
||||
// 构建QYGL5CMP请求参数
|
||||
reqDto := dto.QYGL5CMPReq{
|
||||
EntName: info.CompanyName,
|
||||
LegalPerson: info.LegalPersonName,
|
||||
EntCode: info.UnifiedSocialCode,
|
||||
IDCard: info.LegalPersonID,
|
||||
MobileNo: info.LegalPersonPhone,
|
||||
}
|
||||
|
||||
// 序列化请求参数
|
||||
|
||||
@@ -10,12 +10,13 @@ import (
|
||||
|
||||
// Subscription 订阅实体
|
||||
type Subscription struct {
|
||||
ID string `gorm:"primaryKey;type:varchar(36)" comment:"订阅ID"`
|
||||
UserID string `gorm:"type:varchar(36);not null;index" comment:"用户ID"`
|
||||
ProductID string `gorm:"type:varchar(36);not null;index" comment:"产品ID"`
|
||||
Price decimal.Decimal `gorm:"type:decimal(10,2);not null" comment:"订阅价格"`
|
||||
APIUsed int64 `gorm:"default:0" comment:"已使用API调用次数"`
|
||||
Version int64 `gorm:"default:1" comment:"乐观锁版本号"`
|
||||
ID string `gorm:"primaryKey;type:varchar(36)" comment:"订阅ID"`
|
||||
UserID string `gorm:"type:varchar(36);not null;index" comment:"用户ID"`
|
||||
ProductID string `gorm:"type:varchar(36);not null;index" comment:"产品ID"`
|
||||
Price decimal.Decimal `gorm:"type:decimal(10,2);not null" comment:"订阅价格"`
|
||||
UIComponentPrice decimal.Decimal `gorm:"type:decimal(10,2);not null;default:0" comment:"UI组件价格(组合包使用)"`
|
||||
APIUsed int64 `gorm:"default:0" comment:"已使用API调用次数"`
|
||||
Version int64 `gorm:"default:1" comment:"乐观锁版本号"`
|
||||
|
||||
// 关联关系
|
||||
Product *Product `gorm:"foreignKey:ProductID" comment:"产品"`
|
||||
|
||||
@@ -9,22 +9,23 @@ import (
|
||||
|
||||
// UIComponent UI组件实体
|
||||
type UIComponent struct {
|
||||
ID string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"组件ID"`
|
||||
ComponentCode string `gorm:"type:varchar(50);not null;uniqueIndex" json:"component_code" comment:"组件编码"`
|
||||
ComponentName string `gorm:"type:varchar(100);not null" json:"component_name" comment:"组件名称"`
|
||||
Description string `gorm:"type:text" json:"description" comment:"组件描述"`
|
||||
FilePath *string `gorm:"type:varchar(500)" json:"file_path" comment:"组件文件路径"`
|
||||
FileHash *string `gorm:"type:varchar(64)" json:"file_hash" comment:"文件哈希值"`
|
||||
FileSize *int64 `gorm:"type:bigint" json:"file_size" comment:"文件大小"`
|
||||
FileType *string `gorm:"type:varchar(50)" json:"file_type" comment:"文件类型"`
|
||||
FolderPath *string `gorm:"type:varchar(500)" json:"folder_path" comment:"组件文件夹路径"`
|
||||
IsExtracted bool `gorm:"default:false" json:"is_extracted" comment:"是否已解压"`
|
||||
Version string `gorm:"type:varchar(20)" json:"version" comment:"组件版本"`
|
||||
IsActive bool `gorm:"default:true" json:"is_active" comment:"是否启用"`
|
||||
SortOrder int `gorm:"default:0" json:"sort_order" comment:"排序"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at" comment:"创建时间"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at" comment:"更新时间"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at" comment:"软删除时间"`
|
||||
ID string `gorm:"primaryKey;type:varchar(36)" json:"id" comment:"组件ID"`
|
||||
ComponentCode string `gorm:"type:varchar(50);not null;uniqueIndex" json:"component_code" comment:"组件编码"`
|
||||
ComponentName string `gorm:"type:varchar(100);not null" json:"component_name" comment:"组件名称"`
|
||||
Description string `gorm:"type:text" json:"description" comment:"组件描述"`
|
||||
FilePath *string `gorm:"type:varchar(500)" json:"file_path" comment:"组件文件路径"`
|
||||
FileHash *string `gorm:"type:varchar(64)" json:"file_hash" comment:"文件哈希值"`
|
||||
FileSize *int64 `gorm:"type:bigint" json:"file_size" comment:"文件大小"`
|
||||
FileType *string `gorm:"type:varchar(50)" json:"file_type" comment:"文件类型"`
|
||||
FolderPath *string `gorm:"type:varchar(500)" json:"folder_path" comment:"组件文件夹路径"`
|
||||
IsExtracted bool `gorm:"default:false" json:"is_extracted" comment:"是否已解压"`
|
||||
FileUploadTime *time.Time `gorm:"type:timestamp" json:"file_upload_time" comment:"文件上传时间"`
|
||||
Version string `gorm:"type:varchar(20)" json:"version" comment:"组件版本"`
|
||||
IsActive bool `gorm:"default:true" json:"is_active" comment:"是否启用"`
|
||||
SortOrder int `gorm:"default:0" json:"sort_order" comment:"排序"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at" comment:"创建时间"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at" comment:"更新时间"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"deleted_at" comment:"软删除时间"`
|
||||
}
|
||||
|
||||
func (UIComponent) TableName() string {
|
||||
|
||||
@@ -104,9 +104,10 @@ func (s *ProductSubscriptionService) CreateSubscription(ctx context.Context, use
|
||||
|
||||
// 创建订阅
|
||||
subscription := &entities.Subscription{
|
||||
UserID: userID,
|
||||
ProductID: productID,
|
||||
Price: product.Price,
|
||||
UserID: userID,
|
||||
ProductID: productID,
|
||||
Price: product.Price,
|
||||
UIComponentPrice: product.UIComponentPrice,
|
||||
}
|
||||
|
||||
createdSubscription, err := s.subscriptionRepo.Create(ctx, *subscription)
|
||||
@@ -253,7 +254,7 @@ func (s *ProductSubscriptionService) IncrementSubscriptionAPIUsage(ctx context.C
|
||||
// GetSubscriptionStats 获取订阅统计信息
|
||||
func (s *ProductSubscriptionService) GetSubscriptionStats(ctx context.Context) (map[string]interface{}, error) {
|
||||
stats := make(map[string]interface{})
|
||||
|
||||
|
||||
// 获取总订阅数
|
||||
totalSubscriptions, err := s.subscriptionRepo.Count(ctx, interfaces.CountOptions{})
|
||||
if err != nil {
|
||||
@@ -261,7 +262,7 @@ func (s *ProductSubscriptionService) GetSubscriptionStats(ctx context.Context) (
|
||||
return nil, fmt.Errorf("获取订阅总数失败: %w", err)
|
||||
}
|
||||
stats["total_subscriptions"] = totalSubscriptions
|
||||
|
||||
|
||||
// 获取总收入
|
||||
totalRevenue, err := s.subscriptionRepo.GetTotalRevenue(ctx)
|
||||
if err != nil {
|
||||
@@ -269,30 +270,30 @@ func (s *ProductSubscriptionService) GetSubscriptionStats(ctx context.Context) (
|
||||
return nil, fmt.Errorf("获取总收入失败: %w", err)
|
||||
}
|
||||
stats["total_revenue"] = totalRevenue
|
||||
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
// GetUserSubscriptionStats 获取用户订阅统计信息
|
||||
func (s *ProductSubscriptionService) GetUserSubscriptionStats(ctx context.Context, userID string) (map[string]interface{}, error) {
|
||||
stats := make(map[string]interface{})
|
||||
|
||||
|
||||
// 获取用户订阅数
|
||||
userSubscriptions, err := s.subscriptionRepo.FindByUserID(ctx, userID)
|
||||
if err != nil {
|
||||
s.logger.Error("获取用户订阅失败", zap.Error(err))
|
||||
return nil, fmt.Errorf("获取用户订阅失败: %w", err)
|
||||
}
|
||||
|
||||
|
||||
// 计算用户总收入
|
||||
var totalRevenue float64
|
||||
for _, subscription := range userSubscriptions {
|
||||
totalRevenue += subscription.Price.InexactFloat64()
|
||||
}
|
||||
|
||||
|
||||
stats["total_subscriptions"] = int64(len(userSubscriptions))
|
||||
stats["total_revenue"] = totalRevenue
|
||||
|
||||
|
||||
return stats, nil
|
||||
}
|
||||
|
||||
@@ -303,20 +304,47 @@ func (s *ProductSubscriptionService) UpdateSubscriptionPrice(ctx context.Context
|
||||
if err != nil {
|
||||
return fmt.Errorf("订阅不存在: %w", err)
|
||||
}
|
||||
|
||||
|
||||
// 更新价格
|
||||
subscription.Price = decimal.NewFromFloat(newPrice)
|
||||
subscription.Version++ // 增加版本号
|
||||
|
||||
|
||||
// 保存更新
|
||||
if err := s.subscriptionRepo.Update(ctx, subscription); err != nil {
|
||||
s.logger.Error("更新订阅价格失败", zap.Error(err))
|
||||
return fmt.Errorf("更新订阅价格失败: %w", err)
|
||||
}
|
||||
|
||||
|
||||
s.logger.Info("订阅价格更新成功",
|
||||
zap.String("subscription_id", subscriptionID),
|
||||
zap.Float64("new_price", newPrice))
|
||||
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// UpdateSubscriptionPriceWithUIComponent 更新订阅价格和UI组件价格
|
||||
func (s *ProductSubscriptionService) UpdateSubscriptionPriceWithUIComponent(ctx context.Context, subscriptionID string, newPrice float64, newUIComponentPrice float64) error {
|
||||
// 获取订阅
|
||||
subscription, err := s.subscriptionRepo.GetByID(ctx, subscriptionID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("订阅不存在: %w", err)
|
||||
}
|
||||
|
||||
// 更新价格
|
||||
subscription.Price = decimal.NewFromFloat(newPrice)
|
||||
subscription.UIComponentPrice = decimal.NewFromFloat(newUIComponentPrice)
|
||||
subscription.Version++ // 增加版本号
|
||||
|
||||
// 保存更新
|
||||
if err := s.subscriptionRepo.Update(ctx, subscription); err != nil {
|
||||
s.logger.Error("更新订阅价格失败", zap.Error(err))
|
||||
return fmt.Errorf("更新订阅价格失败: %w", err)
|
||||
}
|
||||
|
||||
s.logger.Info("订阅价格更新成功",
|
||||
zap.String("subscription_id", subscriptionID),
|
||||
zap.Float64("new_price", newPrice),
|
||||
zap.Float64("new_ui_component_price", newUIComponentPrice))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user