397 lines
12 KiB
Go
397 lines
12 KiB
Go
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)
|
|
}
|