package dict import ( consts "cid/consts/dict" "cid/dao/dict" dto "cid/model/dto/dict" entity "cid/model/entity/dict" "context" "errors" "fmt" "time" "gitea.com/red-future/common/beans" ) type fieldMappingConfigService struct{} // FieldMappingConfig 字段映射配置服务 var FieldMappingConfig = new(fieldMappingConfigService) // Create 创建字段映射配置 func (s *fieldMappingConfigService) Create(ctx context.Context, req *dto.CreateFieldMappingConfigReq) (res *dto.CreateFieldMappingConfigRes, err error) { // 验证必填字段 if err = s.validateRequiredFields(req); err != nil { return nil, err } // 检查重复配置 exists, err := dict.FieldMappingConfig.CheckDuplicate(ctx, req.VendorName, req.ApiName, req.SourceField, req.TargetField, 0) if err != nil { return nil, errors.New("检查配置重复性失败") } if exists { return nil, errors.New("相同厂商、接口、源字段和目标字段的配置已存在") } // 验证转换参数 if err = s.validateTransformParams(req.TransformType, req.TransformParams); err != nil { return nil, fmt.Errorf("转换参数验证失败: %v", err) } // 验证业务域 if req.BusinessDomain != "" && !s.isValidBusinessDomain(req.BusinessDomain) { return nil, errors.New("无效的业务域") } // 验证生效时间和失效时间 if req.EffectiveDate != nil && req.ExpiryDate != nil && req.EffectiveDate.After(*req.ExpiryDate) { return nil, errors.New("生效时间不能晚于失效时间") } // 插入数据库 id, err := dict.FieldMappingConfig.Insert(ctx, req) if err != nil { return nil, errors.New("创建配置失败") } res = &dto.CreateFieldMappingConfigRes{ Id: id, } return } // List 获取字段映射配置列表 func (s *fieldMappingConfigService) List(ctx context.Context, req *dto.ListFieldMappingConfigReq) (res *dto.ListFieldMappingConfigRes, err error) { configs, total, err := dict.FieldMappingConfig.List(ctx, req) if err != nil { return nil, errors.New("查询配置列表失败") } // 组装响应数据 list := make([]dto.FieldMappingConfigItem, 0, len(configs)) for _, item := range configs { list = append(list, dto.FieldMappingConfigItem{ Id: item.Id, ConfigName: item.ConfigName, VendorName: item.VendorName, ApiName: item.ApiName, ApiVersion: item.ApiVersion, SourceField: item.SourceField, TargetField: item.TargetField, TargetFieldType: item.TargetFieldType, TransformType: item.TransformType, TransformTypeName: s.getTransformTypeName(item.TransformType), IsActive: item.IsActive, Priority: item.Priority, BusinessDomain: item.BusinessDomain, BusinessDomainName: s.getBusinessDomainName(item.BusinessDomain), FieldGroup: item.FieldGroup, ConfigVersion: item.ConfigVersion, CreatedBy: item.CreatedBy, CreatedTime: item.CreatedTime, UpdatedBy: item.UpdatedBy, UpdatedTime: item.UpdatedTime, }) } res = &dto.ListFieldMappingConfigRes{ List: list, Total: total, } return } // GetOne 获取单个字段映射配置 func (s *fieldMappingConfigService) GetOne(ctx context.Context, req *dto.GetFieldMappingConfigReq) (res *dto.GetFieldMappingConfigRes, err error) { config, err := dict.FieldMappingConfig.GetOne(ctx, req) if err != nil { return nil, errors.New("获取配置详情失败") } if config == nil { return nil, errors.New("配置不存在") } return &dto.GetFieldMappingConfigRes{ FieldMappingConfig: config, TransformTypeName: s.getTransformTypeName(config.TransformType), BusinessDomainName: s.getBusinessDomainName(config.BusinessDomain), }, nil } // Update 更新字段映射配置 func (s *fieldMappingConfigService) Update(ctx context.Context, req *dto.UpdateFieldMappingConfigReq) (err error) { // 检查配置是否存在 exist, err := dict.FieldMappingConfig.GetOne(ctx, &dto.GetFieldMappingConfigReq{Id: req.Id}) if err != nil || exist == nil { return errors.New("配置不存在") } // 如果修改了关键字段,检查重复性 if (req.VendorName != "" && req.VendorName != exist.VendorName) || (req.ApiName != "" && req.ApiName != exist.ApiName) || (req.SourceField != "" && req.SourceField != exist.SourceField) || (req.TargetField != "" && req.TargetField != exist.TargetField) { vendorName := req.VendorName if vendorName == "" { vendorName = exist.VendorName } apiName := req.ApiName if apiName == "" { apiName = exist.ApiName } sourceField := req.SourceField if sourceField == "" { sourceField = exist.SourceField } targetField := req.TargetField if targetField == "" { targetField = exist.TargetField } exists, err := dict.FieldMappingConfig.CheckDuplicate(ctx, vendorName, apiName, sourceField, targetField, req.Id) if err != nil { return errors.New("检查配置重复性失败") } if exists { return errors.New("相同厂商、接口、源字段和目标字段的配置已存在") } } // 验证转换参数 if req.TransformType != "" && req.TransformParams != nil { if err = s.validateTransformParams(req.TransformType, req.TransformParams); err != nil { return fmt.Errorf("转换参数验证失败: %v", err) } } // 验证生效时间和失效时间 if req.EffectiveDate != nil && req.ExpiryDate != nil && req.EffectiveDate.After(*req.ExpiryDate) { return errors.New("生效时间不能晚于失效时间") } // 更新数据库 _, err = dict.FieldMappingConfig.Update(ctx, req) if err != nil { return errors.New("更新配置失败") } return nil } // UpdateStatus 更新字段映射配置状态 func (s *fieldMappingConfigService) UpdateStatus(ctx context.Context, req *dto.UpdateFieldMappingConfigStatusReq) (err error) { _, err = dict.FieldMappingConfig.UpdateStatus(ctx, req.Id, req.IsActive) if err != nil { return errors.New("更新配置状态失败") } return nil } // Delete 删除字段映射配置 func (s *fieldMappingConfigService) Delete(ctx context.Context, req *dto.DeleteFieldMappingConfigReq) (err error) { _, err = dict.FieldMappingConfig.Delete(ctx, req) if err != nil { return errors.New("删除配置失败") } return nil } // QueryByVendorApi 根据厂商和接口查询字段映射 func (s *fieldMappingConfigService) QueryByVendorApi(ctx context.Context, req *dto.QueryFieldMappingByVendorApiReq) (res *dto.QueryFieldMappingByVendorApiRes, err error) { configs, err := dict.FieldMappingConfig.GetByVendorAndApi(ctx, req.VendorName, req.ApiName, req.ApiVersion, req.IsActive) if err != nil { return nil, errors.New("查询字段映射配置失败") } // 过滤掉已过期的配置 var validConfigs []*entity.FieldMappingConfig now := time.Now() for _, config := range configs { if (config.EffectiveDate == nil || !config.EffectiveDate.After(now)) && (config.ExpiryDate == nil || config.ExpiryDate.After(now)) { validConfigs = append(validConfigs, config) } } res = &dto.QueryFieldMappingByVendorApiRes{ List: validConfigs, } return } // Validate 验证字段映射配置 func (s *fieldMappingConfigService) Validate(ctx context.Context, req *dto.ValidateFieldMappingReq) (res *dto.ValidateFieldMappingRes, err error) { ctx = context.WithValue(ctx, "user", &beans.User{UserName: "admin"}) res = &dto.ValidateFieldMappingRes{ IsValid: false, } // 验证基本配置 if req.ConfigName == "" || req.VendorName == "" || req.ApiName == "" || req.SourceField == "" || req.TargetField == "" { res.Error = "配置名称、厂商名称、接口名称、源字段和目标字段不能为空" return } // 检查重复配置 exists, err := dict.FieldMappingConfig.CheckDuplicate(ctx, req.VendorName, req.ApiName, req.SourceField, req.TargetField, 0) if err != nil { res.Error = "检查配置重复性失败" return } if exists { res.Error = "相同厂商、接口、源字段和目标字段的配置已存在" return } // 如果有测试值,尝试转换 if req.TestValue != nil { // 这里可以实现具体的转换逻辑 // 例如:根据转换类型和参数进行值转换 res.TransformedValue = req.TestValue res.Warnings = []string{"转换逻辑需要根据具体业务实现"} } res.IsValid = true return } // validateRequiredFields 验证必填字段 func (s *fieldMappingConfigService) validateRequiredFields(req *dto.CreateFieldMappingConfigReq) error { if req.ConfigName == "" { return errors.New("配置名称不能为空") } if req.VendorName == "" { return errors.New("厂商名称不能为空") } if req.ApiName == "" { return errors.New("接口名称不能为空") } if req.SourceField == "" { return errors.New("源字段不能为空") } if req.TargetField == "" { return errors.New("目标字段不能为空") } if req.TargetFieldType == "" { return errors.New("目标字段类型不能为空") } return nil } // validateRequiredFieldsForBatch 批量创建的字段验证 func (s *fieldMappingConfigService) validateRequiredFieldsForBatch(config *dto.BatchFieldMappingConfigItem) error { if config.ConfigName == "" { return errors.New("配置名称不能为空") } if config.VendorName == "" { return errors.New("厂商名称不能为空") } if config.ApiName == "" { return errors.New("接口名称不能为空") } if config.SourceField == "" { return errors.New("源字段不能为空") } if config.TargetField == "" { return errors.New("目标字段不能为空") } if config.TargetFieldType == "" { return errors.New("目标字段类型不能为空") } return nil } // validateTransformParams 验证转换参数 func (s *fieldMappingConfigService) validateTransformParams(transformType string, params map[string]interface{}) error { if params == nil { return nil } switch transformType { case consts.TransformTypeFormatDate: if _, ok := params["source_format"]; !ok { return errors.New("日期格式化转换需要source_format参数") } if _, ok := params["target_format"]; !ok { return errors.New("日期格式化转换需要target_format参数") } case consts.TransformTypeMapValue: if len(params) == 0 { return errors.New("值映射转换需要映射规则参数") } case consts.TransformTypeConcat: if _, ok := params["fields"]; !ok { return errors.New("拼接转换需要fields参数") } case consts.TransformTypeRegex: if _, ok := params["pattern"]; !ok { return errors.New("正则提取转换需要pattern参数") } } return nil } // isValidBusinessDomain 验证业务域是否有效 func (s *fieldMappingConfigService) isValidBusinessDomain(domain string) bool { validDomains := []string{ consts.BusinessDomainUser, consts.BusinessDomainOrder, consts.BusinessDomainProduct, consts.BusinessDomainPayment, } for _, valid := range validDomains { if domain == valid { return true } } return false } // getTransformTypeName 获取转换类型名称 func (s *fieldMappingConfigService) getTransformTypeName(transformType string) string { typeNames := map[string]string{ consts.TransformTypeDirect: "直接映射", consts.TransformTypeFormatDate: "日期格式化", consts.TransformTypeMapValue: "值映射", consts.TransformTypeConcat: "拼接", consts.TransformTypeCalc: "计算", consts.TransformTypeRegex: "正则提取", } if name, ok := typeNames[transformType]; ok { return name } return transformType } // getBusinessDomainName 获取业务域名称 func (s *fieldMappingConfigService) getBusinessDomainName(domain string) string { domainNames := map[string]string{ consts.BusinessDomainUser: "用户", consts.BusinessDomainOrder: "订单", consts.BusinessDomainProduct: "商品", consts.BusinessDomainPayment: "支付", } if name, ok := domainNames[domain]; ok { return name } return domain } // GetActiveConfigsByBusinessDomain 根据业务域获取启用的配置 func (s *fieldMappingConfigService) GetActiveConfigsByBusinessDomain(ctx context.Context, businessDomain string) ([]entity.FieldMappingConfig, error) { return dict.FieldMappingConfig.GetActiveConfigsByBusinessDomain(ctx, businessDomain) } // GetFieldGroupsByVendorApi 获取指定厂商接口的字段分组 func (s *fieldMappingConfigService) GetFieldGroupsByVendorApi(ctx context.Context, vendorName, apiName string) ([]string, error) { return dict.FieldMappingConfig.GetFieldGroupsByVendorApi(ctx, vendorName, apiName) } // CleanExpiredConfigs 清理过期配置 func (s *fieldMappingConfigService) CleanExpiredConfigs(ctx context.Context) (int64, error) { return dict.FieldMappingConfig.DeleteExpiredConfigs(ctx) }