package mapping import ( consts "cid/consts/mapping" dao "cid/dao/mapping" dto "cid/model/dto/mapping" entity "cid/model/entity/mapping" "context" "errors" "github.com/gogf/gf/v2/frame/g" "github.com/gogf/gf/v2/util/gconv" ) type dataMappingService struct{} // DataMapping 数据映射服务 var DataMapping = new(dataMappingService) // Create 创建数据映射 func (s *dataMappingService) Create(ctx context.Context, req *dto.CreateDataMappingReq) (res *dto.CreateDataMappingRes, err error) { // 检查接口是否存在 // TODO: 这里需要调用data层的ApiInterface服务,暂时跳过 // 检查同一接口下目标字段是否重复 existing, err := dao.DataMapping.GetByInterfaceIdAndTargetField(ctx, req.InterfaceId, req.TargetField) if err == nil && existing != nil { return nil, errors.New("该接口下目标字段已存在") } // 插入数据库 id, err := dao.DataMapping.Insert(ctx, req) if err != nil { return } res = &dto.CreateDataMappingRes{ Id: id, } return } // BatchCreate 批量创建数据映射 func (s *dataMappingService) BatchCreate(ctx context.Context, req *dto.BatchCreateDataMappingReq) (res *dto.BatchCreateDataMappingRes, err error) { var ids []int64 successCount := 0 failedCount := 0 for _, mappingReq := range req.Mappings { // 设置平台和接口ID mappingReq.PlatformId = req.PlatformId mappingReq.InterfaceId = req.InterfaceId createRes, err := s.Create(ctx, &mappingReq) if err != nil { failedCount++ g.Log().Error(ctx, "批量创建映射失败", g.Map{ "sourceField": mappingReq.SourceField, "targetField": mappingReq.TargetField, "error": err.Error(), }) } else { successCount++ ids = append(ids, createRes.Id) } } return &dto.BatchCreateDataMappingRes{ SuccessCount: successCount, FailedCount: failedCount, Ids: ids, }, nil } // List 获取数据映射列表 func (s *dataMappingService) List(ctx context.Context, req *dto.ListDataMappingReq) (res *dto.ListDataMappingRes, err error) { mappingList, total, err := dao.DataMapping.List(ctx, req) if err != nil { return } // 获取平台和接口ID列表 platformIds := make([]int64, 0) interfaceIds := make([]int64, 0) for _, item := range mappingList { if item.PlatformId > 0 { platformIds = append(platformIds, item.PlatformId) } if item.InterfaceId > 0 { interfaceIds = append(interfaceIds, item.InterfaceId) } } // TODO: 批量获取平台和接口信息(需要调用data层服务) platformMap := make(map[int64]string) interfaceMap := make(map[int64]string) // 组装响应数据 list := make([]dto.DataMappingItem, 0, len(mappingList)) for _, item := range mappingList { platformName := "" if name, ok := platformMap[item.PlatformId]; ok { platformName = name } interfaceName := "" if name, ok := interfaceMap[item.InterfaceId]; ok { interfaceName = name } list = append(list, dto.DataMappingItem{ Id: item.Id, PlatformId: item.PlatformId, PlatformName: platformName, InterfaceId: item.InterfaceId, InterfaceName: interfaceName, SourceField: item.SourceField, TargetField: item.TargetField, FieldType: item.FieldType, DefaultValue: item.DefaultValue, TransformRule: item.TransformRule, Priority: item.Priority, Status: item.Status, StatusName: s.getStatusName(item.Status), CreatedAt: item.CreatedAt.Unix(), UpdatedAt: item.UpdatedAt.Unix(), }) } res = &dto.ListDataMappingRes{ List: list, Total: total, } return } // GetOne 获取单个数据映射 func (s *dataMappingService) GetOne(ctx context.Context, req *dto.GetDataMappingReq) (res *dto.GetDataMappingRes, err error) { mapping, err := dao.DataMapping.GetOne(ctx, req) if err != nil { return } // TODO: 获取平台和接口名称 platformName := "" interfaceName := "" return &dto.GetDataMappingRes{ DataMapping: mapping, PlatformName: platformName, InterfaceName: interfaceName, }, nil } // Update 更新数据映射 func (s *dataMappingService) Update(ctx context.Context, req *dto.UpdateDataMappingReq) (err error) { // 检查映射是否存在 exist, err := dao.DataMapping.GetOne(ctx, &dto.GetDataMappingReq{Id: req.Id}) if err != nil || exist == nil { return errors.New("映射不存在") } // 如果修改了目标字段,检查是否重复 if req.TargetField != "" && req.TargetField != exist.TargetField { interfaceId := req.InterfaceId if interfaceId == 0 { interfaceId = exist.InterfaceId } existing, err := dao.DataMapping.GetByInterfaceIdAndTargetField(ctx, interfaceId, req.TargetField) if err == nil && existing != nil && existing.Id != req.Id { return errors.New("该接口下目标字段已存在") } } _, err = dao.DataMapping.Update(ctx, req) return } // Delete 删除数据映射 func (s *dataMappingService) Delete(ctx context.Context, req *dto.DeleteDataMappingReq) (err error) { _, err = dao.DataMapping.Delete(ctx, req) return } // Execute 执行数据映射 func (s *dataMappingService) Execute(ctx context.Context, req *dto.ExecuteDataMappingReq) (res *dto.ExecuteDataMappingRes, err error) { // 获取接口的所有映射规则 mappings, err := dao.DataMapping.GetByInterfaceId(ctx, req.InterfaceId) if err != nil { return nil, err } if len(mappings) == 0 { return &dto.ExecuteDataMappingRes{ TargetData: map[string]interface{}{}, AppliedRules: []string{}, }, nil } // 初始化目标数据 targetData := make(map[string]interface{}) appliedRules := make([]string, 0) // 遍历映射规则进行转换 for _, mapping := range mappings { if mapping.Status != consts.MappingStatusActive { continue } // 获取源数据值 sourceValue, exists := req.SourceData[mapping.SourceField] // 应用转换规则 targetValue := s.applyTransformRule(ctx, sourceValue, exists, mapping) // 设置目标数据 targetData[mapping.TargetField] = targetValue appliedRules = append(appliedRules, gconv.String(mapping.SourceField)+" -> "+gconv.String(mapping.TargetField)) } return &dto.ExecuteDataMappingRes{ TargetData: targetData, AppliedRules: appliedRules, }, nil } // applyTransformRule 应用转换规则 func (s *dataMappingService) applyTransformRule(ctx context.Context, sourceValue interface{}, exists bool, mapping entity.DataMapping) interface{} { // 如果源字段不存在,使用默认值 if !exists { if mapping.DefaultValue != "" { return mapping.DefaultValue } return nil } // 如果没有转换规则,直接返回源值 if mapping.TransformRule == nil || len(mapping.TransformRule) == 0 { return sourceValue } // 获取转换类型 transformType := "" if t, ok := mapping.TransformRule["type"].(string); ok { transformType = t } // 根据转换类型应用不同的转换逻辑 switch consts.TransformType(transformType) { case consts.TransformTypeFixed: // 固定值 if v, ok := mapping.TransformRule["rule"].(string); ok { return v } case consts.TransformTypeMapping: // 值映射 if mappingMap, ok := mapping.TransformRule["mappingMap"].(map[string]interface{}); ok { if sourceKey := gconv.String(sourceValue); sourceKey != "" { if v, ok := mappingMap[sourceKey]; ok { return v } } } case consts.TransformTypeRegex: // 正则转换 if regex, ok := mapping.TransformRule["regex"].(string); ok { // TODO: 实现正则替换逻辑 g.Log().Warning(ctx, "正则转换暂未实现", g.Map{ "regex": regex, "sourceValue": sourceValue, }) } case consts.TransformTypeFunction: // 函数转换 if functionName, ok := mapping.TransformRule["functionName"].(string); ok { // TODO: 实现函数调用逻辑 g.Log().Warning(ctx, "函数转换暂未实现", g.Map{ "function": functionName, "sourceValue": sourceValue, }) } case consts.TransformTypeScript: // 脚本转换 if script, ok := mapping.TransformRule["script"].(string); ok { // TODO: 实现脚本执行逻辑 g.Log().Warning(ctx, "脚本转换暂未实现", g.Map{ "script": script, "sourceValue": sourceValue, }) } } // 默认返回源值 return sourceValue } // getStatusName 获取状态名称 func (s *dataMappingService) getStatusName(status consts.MappingStatus) string { statusNames := map[consts.MappingStatus]string{ consts.MappingStatusActive: "启用", consts.MappingStatusInactive: "停用", } if name, ok := statusNames[status]; ok { return name } return string(status) }