diff --git a/common/common-botp/src/main/java/apelet/common/botp/model/constant/SplitMergeStrategyEnum.java b/common/common-botp/src/main/java/apelet/common/botp/model/constant/SplitMergeStrategyEnum.java new file mode 100644 index 0000000..2fc86d9 --- /dev/null +++ b/common/common-botp/src/main/java/apelet/common/botp/model/constant/SplitMergeStrategyEnum.java @@ -0,0 +1,99 @@ +package apelet.common.botp.model.constant; + +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 分单/合并策略枚举。 + * + *
对应 convert_rule.split_merge_strategy,落库为 varchar 的 "1"/"2"/"3",默认按「一对一」处理。
+ * + * @author admin + * @since 2024-01-18 + */ +public enum SplitMergeStrategyEnum { + + /** + * 一对一:一条源单对应一条目标单。 + */ + ONE_TO_ONE("1", "一对一"), + + /** + * 多对一:多条源单合并为一条目标单。 + */ + MANY_TO_ONE("2", "多对一"), + + /** + * 按规则分组合并:按分单字段分组后分别合并。 + */ + GROUP_BY_RULE("3", "按规则分组合并"); + + @Getter + private final String code; + + @Getter + private final String description; + + private static final Map供保存校验等场景使用:需要区分「未配置」与「配置了非法值」时,用本方法。
+ * + * @param code 分单策略编码。 + * @return 枚举对象;不是已知编码时返回 null。 + */ + public static SplitMergeStrategyEnum parse(String code) { + return StringUtils.isBlank(code) ? null : ENUM_MAP.get(code.trim()); + } + + /** + * 生成可选值说明,用于错误提示。 + * + * @return 形如「1-一对一 2-多对一 3-按规则分组合并」。 + */ + public static String validOptions() { + return Arrays.stream(values()) + .map(e -> e.getCode() + "-" + e.getDescription()) + .collect(Collectors.joining(" ")); + } +} diff --git a/common/common-botp/src/main/java/apelet/common/botp/model/constant/ValueMethodEnum.java b/common/common-botp/src/main/java/apelet/common/botp/model/constant/ValueMethodEnum.java new file mode 100644 index 0000000..2695141 --- /dev/null +++ b/common/common-botp/src/main/java/apelet/common/botp/model/constant/ValueMethodEnum.java @@ -0,0 +1,105 @@ +package apelet.common.botp.model.constant; + +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; + +import java.util.Arrays; +import java.util.Map; +import java.util.Optional; +import java.util.stream.Collectors; + +/** + * 字段取值方式枚举。 + * + *对应 convert_fieldmapping_entry.value_method,落库为 varchar 的 "1"/"2"/"3"/"4"。
+ * + * @author admin + * @since 2024-01-18 + */ +public enum ValueMethodEnum { + + /** + * 映射:取源单同名字段的值。 + */ + MAPPING("1", "映射"), + + /** + * 常量:直接使用配置的固定值。 + */ + CONSTANT("2", "常量"), + + /** + * 计算公式:按配置的公式表达式计算。 + */ + EXPRESSION("3", "计算公式"), + + /** + * 按条件取值 + */ + CONDITION("4", "按条件取值") + ; + + @Getter + private final String code; + + @Getter + private final String description; + + private static final Map供保存校验等场景使用:需要区分「未配置」与「配置了非法值」时,用本方法。
+ * + * @param code 取值方式编码。 + * @return 枚举对象;不是已知编码时返回 null。 + */ + public static ValueMethodEnum parse(String code) { + return StringUtils.isBlank(code) ? null : ENUM_MAP.get(code.trim()); + } + + /** + * 生成可选值说明,用于错误提示。 + * + * @return 形如「1-映射 2-常量 3-计算公式 4-按条件取值」。 + */ + public static String validOptions() { + return Arrays.stream(values()) + .map(e -> e.getCode() + "-" + e.getDescription()) + .collect(Collectors.joining(" ")); + } +} diff --git a/common/common-botp/src/main/java/apelet/common/botp/service/impl/ConvertRuleServiceImpl.java b/common/common-botp/src/main/java/apelet/common/botp/service/impl/ConvertRuleServiceImpl.java index 9deb952..a1c93b4 100644 --- a/common/common-botp/src/main/java/apelet/common/botp/service/impl/ConvertRuleServiceImpl.java +++ b/common/common-botp/src/main/java/apelet/common/botp/service/impl/ConvertRuleServiceImpl.java @@ -5,6 +5,8 @@ import apelet.common.botp.dao.ConvertPluginEntryMapper; import apelet.common.botp.dao.ConvertRuleMapper; import apelet.common.botp.dto.*; import apelet.common.botp.model.*; +import apelet.common.botp.model.constant.SplitMergeStrategyEnum; +import apelet.common.botp.model.constant.ValueMethodEnum; import apelet.common.botp.service.*; import apelet.common.botp.service.execute.BotpService; import apelet.common.botp.service.execute.entity.BillData; @@ -13,6 +15,7 @@ import apelet.common.botp.util.Constant; import apelet.common.core.base.dao.BaseDaoMapper; import apelet.common.core.base.service.BaseService; import apelet.common.core.constant.GlobalDeletedFlag; +import apelet.common.core.exception.MyRuntimeException; import apelet.common.core.object.*; import apelet.common.generator.dao.OnlFormHeadMapper; import apelet.common.generator.model.OnlFormField; @@ -31,6 +34,7 @@ import org.jetbrains.annotations.NotNull; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; import java.util.*; import java.util.stream.Collectors; @@ -99,11 +103,14 @@ public class ConvertRuleServiceImpl extends BaseService集中校验转换规则本身与其字段映射分录,任一不通过即抛出 {@link MyRuntimeException} 阻止保存。
+ * + * @param convertRule 待保存的转换规则。 + */ + private void validateBeforeSave(ConvertRule convertRule) { + validateSplitMergeStrategy(convertRule); + validateFieldmappingValueMethod(convertRule); + } + + /** + * 校验分单策略配置。 + * + *分单策略为空时按「一对一」处理(与字段默认值一致);配置了非法值时阻止保存; + * 选择「按规则分组合并」时必须配置分单字段。
+ * + * @param convertRule 待保存的转换规则。 + */ + private void validateSplitMergeStrategy(ConvertRule convertRule) { + String splitMergeStrategy = convertRule.getSplitMergeStrategy(); + if (StringUtils.isBlank(splitMergeStrategy)) { + // 未配置按默认值「一对一」处理,与 SplitMergeStrategyEnum.ofNullable 保持一致 + return; + } + SplitMergeStrategyEnum strategy = SplitMergeStrategyEnum.parse(splitMergeStrategy); + if (strategy == null) { + throw new MyRuntimeException("分单策略未知:" + splitMergeStrategy + + ",可选值为 " + SplitMergeStrategyEnum.validOptions()); + } + if (strategy == SplitMergeStrategyEnum.GROUP_BY_RULE + && StringUtils.isBlank(convertRule.getGroupByField())) { + throw new MyRuntimeException("分单策略为「" + SplitMergeStrategyEnum.GROUP_BY_RULE.getDescription() + + "」时必须配置分单字段,可选值为 " + SplitMergeStrategyEnum.validOptions()); + } + } + + /** + * 校验字段映射分录的取值方式。 + * + *取值方式为空或不在 {@link ValueMethodEnum} 允许范围内时,直接抛出异常阻止保存, + * 并在异常信息中定位到具体的分录行(第几行、源字段、目标字段),便于前端定位问题。
+ * + * @param convertRule 待保存的转换规则,含字段映射分录。 + */ + private void validateFieldmappingValueMethod(ConvertRule convertRule) { + List