Explorar o código

fix 承保规则增加或者关系条件添加

liub hai 3 meses
pai
achega
d080840663

+ 3 - 5
commons/src/main/java/com/jzg/commons/entity/dto/AgreementRulesAddParam.java

@@ -2,13 +2,9 @@ package com.jzg.commons.entity.dto;
 
 import com.jzg.commons.entity.po.PtlAgreementUndwrtRulesAttrLink;
 import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
-import jakarta.validation.constraints.Size;
 import lombok.Data;
 
-import java.time.LocalDateTime;
-import java.util.Date;
 import java.util.List;
 
 @Schema(description = "承保规则新增dto")
@@ -26,6 +22,8 @@ public class AgreementRulesAddParam {
     private String endTime;
 
     @Schema(description = "规则属性")
-    @NotEmpty(message = "规则属性不能为空")
     private List<PtlAgreementUndwrtRulesAttrLink> rulesAttrList;
+
+    @Schema(description = "规则属性分组(多条规则)")
+    private List<RulesGroupParam> rulesGroups;
 }

+ 8 - 5
commons/src/main/java/com/jzg/commons/entity/dto/AgreementRulesEditParam.java

@@ -2,7 +2,6 @@ package com.jzg.commons.entity.dto;
 
 import com.jzg.commons.entity.po.PtlAgreementUndwrtRulesAttrLink;
 import io.swagger.v3.oas.annotations.media.Schema;
-import jakarta.validation.constraints.NotEmpty;
 import jakarta.validation.constraints.NotNull;
 import lombok.Data;
 
@@ -12,10 +11,12 @@ import java.util.List;
 @Data
 public class AgreementRulesEditParam {
 
-    @NotNull(message = "承保规则id不能为空")
-    @Schema(description = "承保规则id")
+    @Schema(description = "承保规则id(单条模式)")
     private String id;
 
+    @Schema(description = "父规则ID(批量模式)")
+    private String parentId;
+
     @Schema(description = "协议id")
     @NotNull(message = "协议id不能为空")
     private String agreementId;
@@ -26,7 +27,9 @@ public class AgreementRulesEditParam {
     @Schema(description = "生效截止时间")
     private String endTime;
 
-    @Schema(description = "规则属性")
-    @NotEmpty(message = "规则属性不能为空")
+    @Schema(description = "规则属性(单条模式)")
     private List<PtlAgreementUndwrtRulesAttrLink> rulesAttrList;
+
+    @Schema(description = "规则属性分组(批量模式)")
+    private List<RulesGroupParam> rulesGroups;
 }

+ 22 - 0
commons/src/main/java/com/jzg/commons/entity/dto/RulesGroupParam.java

@@ -0,0 +1,22 @@
+package com.jzg.commons.entity.dto;
+
+import com.jzg.commons.entity.po.PtlAgreementUndwrtRulesAttr;
+import com.jzg.commons.entity.po.PtlAgreementUndwrtRulesAttrLink;
+import io.swagger.v3.oas.annotations.media.Schema;
+import jakarta.validation.constraints.NotEmpty;
+import lombok.Data;
+
+import java.util.List;
+
+@Schema(description = "规则属性分组")
+@Data
+public class RulesGroupParam {
+
+    @Schema(description = "并且规则属性")
+    @NotEmpty(message = "规则属性不能为空")
+    private List<PtlAgreementUndwrtRulesAttrLink> rulesAttrList;
+
+    @Schema(description = "费用属性")
+    private List<PtlAgreementUndwrtRulesAttr>  costsAttrLinks;
+
+}

+ 4 - 0
commons/src/main/java/com/jzg/commons/entity/po/PtlAgreementUndwrtRules.java

@@ -33,6 +33,10 @@ public class PtlAgreementUndwrtRules extends BaseModel {
     @Schema(description = "规则描述")
     private String ruleDescription;
 
+    /** 父规则ID */
+    @Schema(description = "父规则ID")
+    private String parentId;
+
     /** 显示顺序 */
     @Schema(description = "显示顺序")
     private Integer orderNum;

+ 8 - 0
commons/src/main/java/com/jzg/commons/entity/vo/AgreementRulesVo.java

@@ -1,6 +1,7 @@
 package com.jzg.commons.entity.vo;
 
 import com.jzg.commons.core.base.BaseModel;
+import com.jzg.commons.entity.dto.RulesGroupParam;
 import com.jzg.commons.entity.po.PtlAgreementUndwrtRulesAttr;
 import io.swagger.v3.oas.annotations.media.Schema;
 import lombok.Data;
@@ -32,6 +33,10 @@ public class AgreementRulesVo extends BaseModel {
     @Schema(description = "规则描述")
     private String ruleDescription;
 
+    /** 父规则ID */
+    @Schema(description = "父规则ID")
+    private String parentId;
+
     /** 显示顺序 */
     @Schema(description = "显示顺序")
     private Integer orderNum;
@@ -42,4 +47,7 @@ public class AgreementRulesVo extends BaseModel {
     @Schema(description = "费用列表")
     private List<CostListVo> costVoList;
 
+    @Schema(description = "规则属性分组(多条规则)")
+    private List<RulesGroupParam> rulesGroups;
+
 }

+ 7 - 0
tenant/organization/src/main/java/com/jzg/organization/controller/AgreementRulesController.java

@@ -67,6 +67,13 @@ public class AgreementRulesController extends BaseController {
         return HttpResult.ok(agreementRulesService.deleteById(id)? "删除成功":"删除失败");
     }
 
+    @Operation(summary = "根据父ID查询规则列表")
+    @GetMapping("/rulesListByParentId")
+    public HttpResult<List<AgreementRulesVo>> rulesListByParentId(String parentId) {
+        List<AgreementRulesVo> rulesVos = agreementRulesService.queryListByParentId(parentId);
+        return HttpResult.ok(rulesVos);
+    }
+
     @Operation(summary = "获取承保规则明细")
     @GetMapping("getRuleInfo")
     public HttpResult getRuleInfo(String ruleId){

+ 8 - 0
tenant/organization/src/main/java/com/jzg/organization/mapper/PtlAgreementUndwrtRulesMapper.java

@@ -22,6 +22,14 @@ public interface PtlAgreementUndwrtRulesMapper extends BaseMapper<PtlAgreementUn
      * @return List<AgreementRulesVo>
      */
     List<AgreementRulesVo> queryList(@Param("agreementId") String agreementId);
+
+    /**
+     * 根据父ID查询规则列表
+     *
+     * @param parentId 父规则ID
+     * @return List<AgreementRulesVo>
+     */
+    List<AgreementRulesVo> queryListByParentId(@Param("parentId") String parentId);
 }
 
 

+ 8 - 0
tenant/organization/src/main/java/com/jzg/organization/service/PtlAgreementUndwrtRulesService.java

@@ -45,6 +45,14 @@ public interface PtlAgreementUndwrtRulesService extends IService<PtlAgreementUnd
      */
     AgreementRulesVo rulesGet(String ruleId);
 
+    /**
+     * 根据父ID查询规则列表
+     *
+     * @param parentId 父规则ID
+     * @return List<AgreementRulesVo> 协议规则列表
+     */
+    List<AgreementRulesVo> queryListByParentId(String parentId);
+
     /**
      * 删除承保规则
      * @param id

+ 193 - 23
tenant/organization/src/main/java/com/jzg/organization/service/impl/PtlAgreementUndwrtRulesServiceImpl.java

@@ -7,6 +7,7 @@ import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.jzg.commons.entity.dto.AgreementRulesAddParam;
 import com.jzg.commons.entity.dto.AgreementRulesEditParam;
 import com.jzg.commons.entity.dto.CostAgreementParam;
+import com.jzg.commons.entity.dto.RulesGroupParam;
 import com.jzg.commons.entity.po.PtlAgreementUndwrtRules;
 import com.jzg.commons.entity.po.PtlAgreementUndwrtRulesAttr;
 import com.jzg.commons.entity.po.PtlAgreementUndwrtRulesAttrLink;
@@ -31,6 +32,8 @@ import org.springframework.transaction.annotation.Transactional;
 import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
@@ -93,12 +96,49 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
                     rulesVo.setCostVoList(costVos);
                 }
             }
+            // 相同parentId的规则合并为一条,ruleDescription以","拼接
+            rulesVos = mergeByParentId(rulesVos);
         }
         return rulesVos;
     }
 
     /**
-     * 承保规则新增
+     * 将相同parentId的规则合并为一条,ruleDescription以","拼接
+     */
+    private List<AgreementRulesVo> mergeByParentId(List<AgreementRulesVo> rulesVos) {
+        List<AgreementRulesVo> result = new ArrayList<>();
+        Map<String, List<AgreementRulesVo>> groupMap = new LinkedHashMap<>();
+
+        for (AgreementRulesVo vo : rulesVos) {
+            String parentId = vo.getParentId();
+            if (parentId != null && !parentId.isEmpty()) {
+                groupMap.computeIfAbsent(parentId, k -> new ArrayList<>()).add(vo);
+            } else {
+                result.add(vo);
+            }
+        }
+
+        for (List<AgreementRulesVo> group : groupMap.values()) {
+            if (group.size() == 1) {
+                result.add(group.get(0));
+            } else {
+                AgreementRulesVo merged = group.get(0);
+                String joinedDesc = group.stream()
+                        .map(AgreementRulesVo::getRuleDescription)
+                        .filter(desc -> desc != null && !desc.isEmpty())
+                        .collect(Collectors.joining(","));
+                merged.setRuleDescription(joinedDesc);
+                result.add(merged);
+            }
+        }
+
+        result.sort(Comparator.comparing(AgreementRulesVo::getOrderNum,
+                Comparator.nullsLast(Comparator.naturalOrder())));
+        return result;
+    }
+
+    /**
+     * 承保规则新增(支持批量多条规则属性集合)
      *
      * @param param 要添加的承保规则
      * @return boolean 添加是否成功
@@ -107,29 +147,46 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
     @Transactional(rollbackFor = Exception.class)
     public boolean rulesAdd(AgreementRulesAddParam param) {
         log.info("添加承保规则:承保明细param=[{}]", JSONUtil.toJsonStr(param));
+
         // 根据协议id获取最大的序号
         LambdaQueryWrapper<PtlAgreementUndwrtRules> queryWrapper = new LambdaQueryWrapper<>();
         queryWrapper.eq(PtlAgreementUndwrtRules::getAgreementId, param.getAgreementId())
                 .eq(PtlAgreementUndwrtRules::getIsDelete, 0);
         queryWrapper.orderByDesc(PtlAgreementUndwrtRules::getOrderNum);
-        queryWrapper.last("LIMIT 1"); // 只取一个结果
+        queryWrapper.last("LIMIT 1");
         PtlAgreementUndwrtRules maxRules = baseMapper.selectOne(queryWrapper);
-        PtlAgreementUndwrtRules rules = new PtlAgreementUndwrtRules();
-        rules.setId(IdGenerate.nextId());
-        rules.setOrderNum(Objects.nonNull(maxRules) ? maxRules.getOrderNum() + 1 : 1);
-        rules.setStartTime(param.getStartTime());
-        rules.setEndTime(param.getEndTime());
-        rules.setAgreementId(param.getAgreementId());
+        int startOrderNum = Objects.nonNull(maxRules) ? maxRules.getOrderNum() + 1 : 1;
 
-        //遍历承保规则属性
         List<PtlAgreementUndwrtRulesAttr> undwrtRulesAttrList = agreementUndwrtRulesAttrService.getUndwrtRulesAttrList();
+
+        // 批量模式:存在 rulesGroups 时
+        if (CollUtil.isNotEmpty(param.getRulesGroups())) {
+            String parentId = IdGenerate.nextId();
+            List<RulesGroupParam> groups = param.getRulesGroups();
+            for (int i = 0; i < groups.size(); i++) {
+                RulesGroupParam group = groups.get(i);
+                PtlAgreementUndwrtRules rules = buildRulesRecord(param, parentId, startOrderNum + i);
+
+                List<PtlAgreementUndwrtRulesAttrLink> andAttrLinks = processAndAttrs(group.getRulesAttrList(), undwrtRulesAttrList, rules.getId());
+
+                if (CollUtil.isNotEmpty(andAttrLinks)) {
+                    agreementUndwrtRulesAttrLinkMapper.insert(andAttrLinks);
+                }
+
+                rules.setRuleDescription(buildDesc(andAttrLinks, undwrtRulesAttrList));
+                baseMapper.insert(rules);
+            }
+            return true;
+        }
+
+        // 兼容旧的单条规则模式
+        PtlAgreementUndwrtRules rules = buildRulesRecord(param, null, startOrderNum);
         List<PtlAgreementUndwrtRulesAttrLink> rulesAttrList = param.getRulesAttrList();
         List<PtlAgreementUndwrtRulesAttrLink> costsAttrLink = new ArrayList<>();
         rulesAttrList.forEach(attr -> {
-
-            //判断空值
             if(Objects.isNull(attr.getMin()) && Objects.isNull(attr.getMax()) && Objects.isNull(attr.getMinArray())){
-                PtlAgreementUndwrtRulesAttr ptlAgreementUndwrtRulesAttr = undwrtRulesAttrList.stream().filter(x -> x.getAttrCode().equals(attr.getAttrCode())).findFirst().orElse(null);
+                PtlAgreementUndwrtRulesAttr ptlAgreementUndwrtRulesAttr = undwrtRulesAttrList.stream()
+                        .filter(x -> x.getAttrCode().equals(attr.getAttrCode())).findFirst().orElse(null);
                 throw new SystemException(ptlAgreementUndwrtRulesAttr.getAttrName() + "规则不能为空,请修改");
             }
             if (null != attr.getMin() ||  null != attr.getMax()) {
@@ -139,15 +196,98 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
             }
         });
         agreementUndwrtRulesAttrLinkMapper.insert(costsAttrLink);
-        //获取费用属性
         rules.setRuleDescription(buildDesc(costsAttrLink, undwrtRulesAttrList));
         baseMapper.insert(rules);
         baseMapper.updateById(rules);
         return true;
     }
 
+    /**
+     * 构建规则的公共字段
+     */
+    private PtlAgreementUndwrtRules buildRulesRecord(AgreementRulesAddParam param, String parentId, int orderNum) {
+        PtlAgreementUndwrtRules rules = new PtlAgreementUndwrtRules();
+        rules.setId(IdGenerate.nextId());
+        rules.setOrderNum(orderNum);
+        rules.setStartTime(param.getStartTime());
+        rules.setEndTime(param.getEndTime());
+        rules.setAgreementId(param.getAgreementId());
+        rules.setParentId(parentId);
+        return rules;
+    }
+
+    /**
+     * 处理并且规则属性
+     */
+    private List<PtlAgreementUndwrtRulesAttrLink> processAndAttrs(List<PtlAgreementUndwrtRulesAttrLink> attrs,
+                                                                    List<PtlAgreementUndwrtRulesAttr> attrMetaList,
+                                                                    String rulesId) {
+        List<PtlAgreementUndwrtRulesAttrLink> result = new ArrayList<>();
+        if (CollUtil.isEmpty(attrs)) {
+            return result;
+        }
+        attrs.forEach(attr -> {
+            if (Objects.isNull(attr.getMin()) && Objects.isNull(attr.getMax()) && Objects.isNull(attr.getMinArray())) {
+                PtlAgreementUndwrtRulesAttr meta = attrMetaList.stream()
+                        .filter(x -> x.getAttrCode().equals(attr.getAttrCode())).findFirst().orElse(null);
+                throw new SystemException(meta.getAttrName() + "规则不能为空,请修改");
+            }
+            if (null != attr.getMin() || null != attr.getMax()) {
+                attr.setRulesId(rulesId);
+                attr.setId(null);
+                result.add(attr);
+            }
+        });
+        return result;
+    }
+
     @Override
+    @Transactional(rollbackFor = Exception.class)
     public boolean rulesEdit(AgreementRulesEditParam param) {
+        log.info("修改承保规则:承保明细param=[{}]", JSONUtil.toJsonStr(param));
+
+        List<PtlAgreementUndwrtRulesAttr> undwrtRulesAttrList = agreementUndwrtRulesAttrService.getUndwrtRulesAttrList();
+
+        // 批量模式:存在 rulesGroups 时
+        if (CollUtil.isNotEmpty(param.getRulesGroups())) {
+            String parentId = param.getParentId();
+            if (parentId == null || parentId.isEmpty()) {
+                throw new SystemException("批量模式下父规则ID不能为空");
+            }
+
+            // 删除旧的所有子规则及其关联属性
+            List<AgreementRulesVo> oldRules = baseMapper.queryListByParentId(parentId);
+            if (CollUtil.isNotEmpty(oldRules)) {
+                for (AgreementRulesVo oldRule : oldRules) {
+                    agreementUndwrtRulesAttrLinkService.remove(new LambdaQueryWrapper<PtlAgreementUndwrtRulesAttrLink>()
+                            .eq(PtlAgreementUndwrtRulesAttrLink::getRulesId, oldRule.getId()));
+                    baseMapper.deleteById(oldRule.getId());
+                }
+            }
+
+            // 重新创建子规则
+            List<RulesGroupParam> groups = param.getRulesGroups();
+            for (int i = 0; i < groups.size(); i++) {
+                RulesGroupParam group = groups.get(i);
+                PtlAgreementUndwrtRules rules = new PtlAgreementUndwrtRules();
+                rules.setId(IdGenerate.nextId());
+                rules.setOrderNum(i + 1);
+                rules.setStartTime(param.getStartTime());
+                rules.setEndTime(param.getEndTime());
+                rules.setAgreementId(param.getAgreementId());
+                rules.setParentId(parentId);
+
+                List<PtlAgreementUndwrtRulesAttrLink> andAttrLinks = processAndAttrs(group.getRulesAttrList(), undwrtRulesAttrList, rules.getId());
+                if (CollUtil.isNotEmpty(andAttrLinks)) {
+                    agreementUndwrtRulesAttrLinkMapper.insert(andAttrLinks);
+                }
+                rules.setRuleDescription(buildDesc(andAttrLinks, undwrtRulesAttrList));
+                baseMapper.insert(rules);
+            }
+            return true;
+        }
+
+        // 兼容旧的单条规则模式
         PtlAgreementUndwrtRules rules = new PtlAgreementUndwrtRules();
         BeanUtils.copyProperties(param, rules);
 
@@ -155,7 +295,7 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
         agreementUndwrtRulesAttrLinkService.remove(new LambdaQueryWrapper<PtlAgreementUndwrtRulesAttrLink>()
                 .eq(PtlAgreementUndwrtRulesAttrLink::getRulesId, param.getId()));
 
-        List<PtlAgreementUndwrtRulesAttr> attrList = agreementUndwrtRulesAttrService.getUndwrtRulesAttrList();
+        List<PtlAgreementUndwrtRulesAttr> attrList = undwrtRulesAttrList;
         //再添加属性值
         List<PtlAgreementUndwrtRulesAttrLink> costsAttrLinks = param.getRulesAttrList();
         List<PtlAgreementUndwrtRulesAttrLink> costsAttrLink = new ArrayList<>();
@@ -194,16 +334,42 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
         PtlAgreementUndwrtRules rules = baseMapper.selectById(ruleId);
         AgreementRulesVo rulesVo = new AgreementRulesVo();
         BeanUtils.copyProperties(rules, rulesVo);
-        List<PtlAgreementUndwrtRulesAttrLink> linkList = agreementUndwrtRulesAttrLinkService.queryLinkList(ruleId);
-        // 获取费用因子属性
+
+        // 获取费用因子属性(公共逻辑,仅查询一次)
         List<PtlAgreementUndwrtRulesAttr> attrList = agreementUndwrtRulesAttrService.getUndwrtRulesAttrList();
         Map<String, PtlAgreementUndwrtRulesAttr> attrMap = attrList.stream()
                 .collect(Collectors.toMap(PtlAgreementUndwrtRulesAttr::getAttrCode, attr -> attr));
+
+        // 如果存在parentId,查询该parentId下的所有子规则并组装groups
+        if (rules.getParentId() != null && !rules.getParentId().isEmpty()) {
+            List<AgreementRulesVo> childRules = baseMapper.queryListByParentId(rules.getParentId());
+            List<RulesGroupParam> groups = new ArrayList<>();
+            for (AgreementRulesVo child : childRules) {
+                List<PtlAgreementUndwrtRulesAttrLink> linkList = agreementUndwrtRulesAttrLinkService.queryLinkList(child.getId());
+                RulesGroupParam group = new RulesGroupParam();
+                group.setRulesAttrList(linkList);
+                group.setCostsAttrLinks(enrichAttrLinks(linkList, attrMap));
+                groups.add(group);
+            }
+            rulesVo.setRulesGroups(groups);
+            return rulesVo;
+        }
+
+        // 单条规则模式
+        List<PtlAgreementUndwrtRulesAttrLink> linkList = agreementUndwrtRulesAttrLinkService.queryLinkList(ruleId);
+        rulesVo.setCostsAttrLinks(enrichAttrLinks(linkList, attrMap));
+        return rulesVo;
+    }
+
+    /**
+     * 将属性链接丰富为完整的属性对象
+     */
+    private List<PtlAgreementUndwrtRulesAttr> enrichAttrLinks(List<PtlAgreementUndwrtRulesAttrLink> linkList,
+                                                               Map<String, PtlAgreementUndwrtRulesAttr> attrMap) {
         List<PtlAgreementUndwrtRulesAttr> newAttrList = new ArrayList<>();
         linkList.forEach(link -> {
-            if(attrMap.containsKey(link.getAttrCode())) {
-                PtlAgreementUndwrtRulesAttr attr= attrMap.get(link.getAttrCode());
-                //处理多选和下拉
+            if (attrMap.containsKey(link.getAttrCode())) {
+                PtlAgreementUndwrtRulesAttr attr = attrMap.get(link.getAttrCode());
                 if ("checkbox".equals(attr.getAttrType()) || "select".equals(attr.getAttrType()) || "inputTag".equals(attr.getAttrType())) {
                     if (null != link.getMin()) {
                         attr.setId(link.getId());
@@ -211,7 +377,7 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
                         attr.setMax(link.getMax());
                         attr.setOperator(link.getOperator());
                     }
-                }else{
+                } else {
                     attr.setId(link.getId());
                     attr.setMin(link.getMin());
                     attr.setMax(link.getMax());
@@ -219,10 +385,14 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
                 }
                 newAttrList.add(attr);
             }
-
         });
-        rulesVo.setCostsAttrLinks(newAttrList);
-        return rulesVo;
+        return newAttrList;
+    }
+
+    @Override
+    public List<AgreementRulesVo> queryListByParentId(String parentId) {
+        log.info("根据父ID查询协议承保规则列表。 parentId=[{}]", parentId);
+        return baseMapper.queryListByParentId(parentId);
     }
 
     @Override

+ 12 - 1
tenant/organization/src/main/resources/mapper/PtlAgreementUndwrtRulesMapper.xml

@@ -8,6 +8,7 @@
             <id property="id" column="id" jdbcType="VARCHAR"/>
             <result property="agreementId" column="agreement_id" jdbcType="VARCHAR"/>
             <result property="ruleDescription" column="rule_description" jdbcType="VARCHAR"/>
+            <result property="parentId" column="parent_id" jdbcType="VARCHAR"/>
             <result property="orderNum" column="order_num" jdbcType="INTEGER"/>
             <result property="createBy" column="create_by" jdbcType="VARCHAR"/>
             <result property="createTime" column="create_time" jdbcType="TIMESTAMP"/>
@@ -17,7 +18,7 @@
     </resultMap>
 
     <sql id="Base_Column_List">
-        paur.id,paur.agreement_id,paur.rule_description,
+        paur.id,paur.agreement_id,paur.rule_description,paur.parent_id,
         paur.order_num,paur.create_by,paur.create_time,
         paur.update_by,paur.update_time,paur.is_delete
     </sql>
@@ -32,4 +33,14 @@
         </where>
         ORDER BY paur.order_num ASC
     </select>
+
+    <select id="queryListByParentId" resultType="com.jzg.commons.entity.vo.AgreementRulesVo">
+        SELECT <include refid="Base_Column_List"/>
+        FROM ptl_agreement_undwrt_rules paur
+        <where>
+            paur.is_delete = 0
+            AND paur.parent_id = #{parentId}
+        </where>
+        ORDER BY paur.order_num ASC
+    </select>
 </mapper>

+ 347 - 0
协议承保规则接口对接文档.md

@@ -0,0 +1,347 @@
+# 协议承保规则接口对接文档
+
+---
+
+## 一、新增承保规则
+
+**接口路径**:`POST /agreementRules/rulesAdd`
+
+### 请求参数
+
+| 字段名 | 类型 | 必填 | 描述 |
+|---|---|---|---|
+| `agreementId` | String | 是 | 协议ID |
+| `startTime` | String | 否 | 生效开始时间 |
+| `endTime` | String | 否 | 生效截止时间 |
+| `rulesAttrList` | Array\<PtlAgreementUndwrtRulesAttrLink\> | 是 | 并且规则属性(AND 逻辑,单条规则模式) |
+| `rulesGroups` | Array\<RulesGroupParam\> | 否 | **【新增】** 规则属性分组(批量多条规则模式) |
+
+#### 两种模式说明
+
+- **单条规则模式**:使用 `rulesAttrList`,创建一条规则,`parentId` 为空
+- **批量规则模式**:使用 `rulesGroups`,一次创建多条规则,共享同一个 `parentId`,按分组顺序生成 `orderNum`
+- 两种模式互斥,优先使用 `rulesGroups` 批量模式
+
+### RulesGroupParam 结构
+
+| 字段名 | 类型 | 必填 | 描述 |
+|---|---|---|---|
+| `rulesAttrList` | Array\<PtlAgreementUndwrtRulesAttrLink\> | 是 | 该组规则属性(AND 逻辑) |
+
+### PtlAgreementUndwrtRulesAttrLink 结构
+
+| 字段 | 类型 | 描述 |
+|---|---|---|
+| `attrId` | String | 协议属性ID |
+| `attrCode` | String | 协议属性编码 |
+| `min` | String | 左操作数(单选/输入值,数组时逗号分隔) |
+| `operator` | String | 运算符:1.范围 2.小于 3.小于等于 4.大于 5.大于等于 |
+| `max` | String | 右操作数(范围值上限) |
+| `minArray` | String[] | 左操作数数组(用于 checkbox/select/inputTag,非数据库字段) |
+
+### 请求体示例
+
+#### 单条规则模式
+
+```json
+{
+    "agreementId": "123456",
+    "startTime": "2026-01-01",
+    "endTime": "2026-12-31",
+    "rulesAttrList": [
+        {
+            "attrCode": "VehicleAge",
+            "min": "0",
+            "max": "5",
+            "operator": "1"
+        },
+        {
+            "attrCode": "LicenseArea",
+            "min": "BJ,SH",
+            "operator": "1"
+        }
+    ]
+}
+```
+
+#### 批量规则模式
+
+```json
+{
+    "agreementId": "123456",
+    "startTime": "2026-01-01",
+    "endTime": "2026-12-31",
+    "rulesGroups": [
+        {
+            "rulesAttrList": [
+                {
+                    "attrCode": "VehicleAge",
+                    "min": "0",
+                    "max": "5",
+                    "operator": "1"
+                }
+            ]
+        },
+        {
+            "rulesAttrList": [
+                {
+                    "attrCode": "LicenseArea",
+                    "min": "BJ,SH",
+                    "operator": "1"
+                },
+                {
+                    "attrCode": "Brand",
+                    "min": "AUDI,BMW",
+                    "operator": "1"
+                }
+            ]
+        }
+    ]
+}
+```
+
+### 响应
+
+```json
+{
+    "code": 200,
+    "msg": "添加承保规则成功"
+}
+```
+
+---
+
+## 二、修改承保规则
+
+**接口路径**:`POST /agreementRules/rulesEdit`
+
+### 请求参数
+
+| 字段名 | 类型 | 必填 | 描述 |
+|---|---|---|---|
+| `id` | String | 是 | 承保规则ID |
+| `agreementId` | String | 是 | 协议ID |
+| `startTime` | String | 否 | 生效开始时间 |
+| `endTime` | String | 否 | 生效截止时间 |
+| `rulesAttrList` | Array\<PtlAgreementUndwrtRulesAttrLink\> | 是 | 并且规则属性(AND 逻辑) |
+
+### 请求体示例
+
+```json
+{
+    "id": "987654",
+    "agreementId": "123456",
+    "startTime": "2026-01-01",
+    "endTime": "2026-12-31",
+    "rulesAttrList": [
+        {
+            "attrCode": "VehicleAge",
+            "min": "0",
+            "max": "5",
+            "operator": "1"
+        }
+    ]
+}
+```
+
+> **修改逻辑**:先删除该规则下的所有旧属性关联数据,再重新插入新的规则属性。
+
+### 响应
+
+```json
+{
+    "code": 200,
+    "msg": "修改承保规则成功"
+}
+```
+
+---
+
+## 三、承保规则列表查询
+
+**接口路径**:`GET /agreementRules/rulesList`
+
+### 请求参数
+
+| 参数 | 类型 | 必填 | 描述 |
+|---|---|---|---|
+| `agreementId` | String | 是 | 协议ID |
+
+### 响应字段
+
+| 字段 | 类型 | 描述 |
+|---|---|---|
+| `id` | String | 主键 |
+| `agreementId` | String | 协议ID |
+| `startTime` | String | 生效开始时间 |
+| `endTime` | String | 生效截止时间 |
+| `ruleDescription` | String | 规则描述文字 |
+| `parentId` | String | **【新增】** 父规则ID(批量模式时共用) |
+| `orderNum` | Integer | 显示顺序 |
+| `costsAttrLinks` | Array | 规则属性详情 |
+| `costVoList` | Array | 关联费用列表 |
+
+### 响应示例
+
+```json
+{
+    "code": 200,
+    "data": [
+        {
+            "id": "987654",
+            "agreementId": "123456",
+            "startTime": "2026-01-01",
+            "endTime": "2026-12-31",
+            "ruleDescription": "车龄范围值0到5,",
+            "parentId": "1792000000000000001",
+            "orderNum": 1,
+            "costsAttrLinks": [],
+            "costVoList": []
+        },
+        {
+            "id": "987655",
+            "agreementId": "123456",
+            "startTime": "2026-01-01",
+            "endTime": "2026-12-31",
+            "ruleDescription": "上牌城市为北京市,上海市,品牌为奥迪,宝马,",
+            "parentId": "1792000000000000001",
+            "orderNum": 2,
+            "costsAttrLinks": [],
+            "costVoList": []
+        }
+    ]
+}
+```
+
+---
+
+## 四、获取承保规则详情
+
+**接口路径**:`GET /agreementRules/rulesGet`
+
+### 请求参数
+
+| 参数 | 类型 | 必填 | 描述 |
+|---|---|---|---|
+| `ruleId` | String | 是 | 承保规则ID |
+
+### 响应
+
+与列表接口返回结构一致,包含 `parentId` 字段。
+
+---
+
+## 五、根据父ID查询规则列表【新增】
+
+**接口路径**:`GET /agreementRules/rulesListByParentId`
+
+### 请求参数
+
+| 参数 | 类型 | 必填 | 描述 |
+|---|---|---|---|
+| `parentId` | String | 是 | 父规则ID |
+
+### 功能说明
+
+当使用批量规则模式(`rulesGroups`)新增规则时,同批次的所有子规则共享同一个 `parentId`。调用此接口可根据 `parentId` 查询该批次下的所有子规则列表。
+
+### 响应字段
+
+与 `rulesList` 接口返回结构一致。
+
+### 响应示例
+
+```json
+{
+    "code": 200,
+    "data": [
+        {
+            "id": "987654",
+            "agreementId": "123456",
+            "startTime": "2026-01-01",
+            "endTime": "2026-12-31",
+            "ruleDescription": "车龄范围值0到5,",
+            "parentId": "1792000000000000001",
+            "orderNum": 1,
+            "costsAttrLinks": [],
+            "costVoList": []
+        },
+        {
+            "id": "987655",
+            "agreementId": "123456",
+            "startTime": "2026-01-01",
+            "endTime": "2026-12-31",
+            "ruleDescription": "上牌城市为北京市,上海市,",
+            "parentId": "1792000000000000001",
+            "orderNum": 2,
+            "costsAttrLinks": [],
+            "costVoList": []
+        }
+    ]
+}
+```
+
+---
+
+## 六、删除承保规则
+
+**接口路径**:`DELETE /agreementRules/rulesDelete`
+
+### 请求参数
+
+| 参数 | 类型 | 必填 | 描述 |
+|---|---|---|---|
+| `id` | String | 是 | 承保规则ID |
+
+### 响应
+
+```json
+{
+    "code": 200,
+    "data": "删除成功"
+}
+```
+
+---
+
+## 七、获取承保规则明细
+
+**接口路径**:`GET /agreementRules/getRuleInfo`
+
+### 请求参数
+
+| 参数 | 类型 | 必填 | 描述 |
+|---|---|---|---|
+| `ruleId` | String | 是 | 承保规则ID |
+
+### 响应
+
+返回该规则下所有属性关联明细列表。
+
+---
+
+## 变更总结
+
+| 接口 | 变更点 | 变更内容 |
+|---|---|---|
+| `POST /rulesAdd` | 请求参数新增 | `rulesGroups`(批量规则分组),支持一次创建多条规则 |
+| `POST /rulesAdd` | 逻辑变更 | 批量模式下所有子规则共享同一 `parentId`,按分组顺序生成 `orderNum` |
+| `GET /rulesList` | 返回值新增 | `parentId`(父规则ID) |
+| `GET /rulesGet` | 返回值新增 | `parentId`(父规则ID) |
+| `GET /rulesListByParentId` | **新增接口** | 根据父ID查询子规则列表 |
+
+### 业务逻辑说明
+
+- **单条模式**:使用 `rulesAttrList` 创建一条规则,`parentId` 为 `null`
+- **批量模式**:使用 `rulesGroups` 一次创建多条规则,系统生成统一 `parentId` 关联同一批次的所有子规则
+- 批量模式与单条模式互斥,优先处理 `rulesGroups`
+- 通过 `rulesListByParentId` 接口可按 `parentId` 查询同批次的所有子规则
+- 修改接口仅支持对单条规则进行编辑
+
+### 数据库变更说明
+
+`ptl_agreement_undwrt_rules` 表需新增字段:
+
+```sql
+ALTER TABLE ptl_agreement_undwrt_rules ADD COLUMN parent_id VARCHAR(64) DEFAULT NULL COMMENT '父规则ID';
+```