|
@@ -3,6 +3,7 @@ package com.jzg.organization.service.impl;
|
|
|
import cn.hutool.core.collection.CollUtil;
|
|
import cn.hutool.core.collection.CollUtil;
|
|
|
import cn.hutool.json.JSONUtil;
|
|
import cn.hutool.json.JSONUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import com.jzg.commons.entity.dto.AgreementRulesAddParam;
|
|
import com.jzg.commons.entity.dto.AgreementRulesAddParam;
|
|
|
import com.jzg.commons.entity.dto.AgreementRulesEditParam;
|
|
import com.jzg.commons.entity.dto.AgreementRulesEditParam;
|
|
@@ -184,7 +185,10 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
|
|
|
agreementUndwrtRulesAttrLinkMapper.insert(andAttrLinks);
|
|
agreementUndwrtRulesAttrLinkMapper.insert(andAttrLinks);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- rules.setRuleDescription(buildDesc(andAttrLinks, undwrtRulesAttrList));
|
|
|
|
|
|
|
+ // andAttrLinks 为空时不设置 ruleDescription,避免 updateById 覆盖已有数据
|
|
|
|
|
+ if (CollUtil.isNotEmpty(andAttrLinks)) {
|
|
|
|
|
+ rules.setRuleDescription(buildDesc(andAttrLinks, undwrtRulesAttrList));
|
|
|
|
|
+ }
|
|
|
baseMapper.insert(rules);
|
|
baseMapper.insert(rules);
|
|
|
}
|
|
}
|
|
|
return true;
|
|
return true;
|
|
@@ -244,7 +248,8 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
|
|
|
.filter(x -> x.getAttrCode().equals(attr.getAttrCode())).findFirst().orElse(null);
|
|
.filter(x -> x.getAttrCode().equals(attr.getAttrCode())).findFirst().orElse(null);
|
|
|
throw new SystemException(meta.getAttrName() + "规则不能为空,请修改");
|
|
throw new SystemException(meta.getAttrName() + "规则不能为空,请修改");
|
|
|
}
|
|
}
|
|
|
- if (null != attr.getMin() || null != attr.getMax()) {
|
|
|
|
|
|
|
+ // 支持 min/max 和 minArray 类型的属性值
|
|
|
|
|
+ if (null != attr.getMin() || null != attr.getMax() || null != attr.getMinArray()) {
|
|
|
attr.setRulesId(rulesId);
|
|
attr.setRulesId(rulesId);
|
|
|
attr.setId(null);
|
|
attr.setId(null);
|
|
|
result.add(attr);
|
|
result.add(attr);
|
|
@@ -253,6 +258,45 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
|
+ * 差异合并属性链接:更新已存在的、新增不存在的、删除旧的多余的
|
|
|
|
|
+ * 避免全删全插导致逻辑删除堆积大量垃圾数据
|
|
|
|
|
+ */
|
|
|
|
|
+ private void mergeAttrLinks(List<PtlAgreementUndwrtRulesAttrLink> oldLinks,
|
|
|
|
|
+ List<PtlAgreementUndwrtRulesAttrLink> newLinks) {
|
|
|
|
|
+ // 旧链接 attrCode -> link 映射
|
|
|
|
|
+ Map<String, PtlAgreementUndwrtRulesAttrLink> oldMap = new LinkedHashMap<>();
|
|
|
|
|
+ if (CollUtil.isNotEmpty(oldLinks)) {
|
|
|
|
|
+ for (PtlAgreementUndwrtRulesAttrLink link : oldLinks) {
|
|
|
|
|
+ oldMap.put(link.getAttrCode(), link);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 合并新链接
|
|
|
|
|
+ Set<String> keepAttrCodes = new HashSet<>();
|
|
|
|
|
+ if (CollUtil.isNotEmpty(newLinks)) {
|
|
|
|
|
+ for (PtlAgreementUndwrtRulesAttrLink newLink : newLinks) {
|
|
|
|
|
+ keepAttrCodes.add(newLink.getAttrCode());
|
|
|
|
|
+ PtlAgreementUndwrtRulesAttrLink oldLink = oldMap.get(newLink.getAttrCode());
|
|
|
|
|
+ if (oldLink != null) {
|
|
|
|
|
+ // 已存在:复用旧ID更新
|
|
|
|
|
+ newLink.setId(oldLink.getId());
|
|
|
|
|
+ agreementUndwrtRulesAttrLinkMapper.updateById(newLink);
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 不存在:插入新记录
|
|
|
|
|
+ agreementUndwrtRulesAttrLinkMapper.insert(newLink);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 删除旧链接中新请求里不存在的
|
|
|
|
|
+ if (CollUtil.isNotEmpty(oldLinks)) {
|
|
|
|
|
+ for (PtlAgreementUndwrtRulesAttrLink oldLink : oldLinks) {
|
|
|
|
|
+ if (!keepAttrCodes.contains(oldLink.getAttrCode())) {
|
|
|
|
|
+ agreementUndwrtRulesAttrLinkMapper.deleteById(oldLink.getId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
@Override
|
|
@Override
|
|
|
@Transactional(rollbackFor = Exception.class)
|
|
@Transactional(rollbackFor = Exception.class)
|
|
|
public boolean rulesEdit(AgreementRulesEditParam param) {
|
|
public boolean rulesEdit(AgreementRulesEditParam param) {
|
|
@@ -267,52 +311,113 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
|
|
|
throw new SystemException("批量模式下父规则ID不能为空");
|
|
throw new SystemException("批量模式下父规则ID不能为空");
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // 查询协议下所有规则,计算最大orderNum(排除当前parentId下的旧规则)
|
|
|
|
|
+ List<AgreementRulesVo> allRules = baseMapper.queryList(param.getAgreementId());
|
|
|
|
|
+ int maxOrderNum = 0;
|
|
|
|
|
+ if (CollUtil.isNotEmpty(allRules)) {
|
|
|
|
|
+ maxOrderNum = allRules.stream()
|
|
|
|
|
+ .filter(r -> !parentId.equals(r.getParentId()))
|
|
|
|
|
+ .mapToInt(r -> r.getOrderNum() != null ? r.getOrderNum() : 0)
|
|
|
|
|
+ .max().orElse(0);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
// 查询旧的所有子规则(按order_num升序,与新增顺序一致)
|
|
// 查询旧的所有子规则(按order_num升序,与新增顺序一致)
|
|
|
List<AgreementRulesVo> oldRules = baseMapper.queryListByParentId(parentId);
|
|
List<AgreementRulesVo> oldRules = baseMapper.queryListByParentId(parentId);
|
|
|
int oldSize = CollUtil.isNotEmpty(oldRules) ? oldRules.size() : 0;
|
|
int oldSize = CollUtil.isNotEmpty(oldRules) ? oldRules.size() : 0;
|
|
|
List<RulesGroupParam> groups = param.getRulesGroups();
|
|
List<RulesGroupParam> groups = param.getRulesGroups();
|
|
|
|
|
|
|
|
- // 1. 按索引匹配:已有规则复用ID做UPDATE,多出的做INSERT
|
|
|
|
|
|
|
+ // 判断前端是否传了规则ID(用于精确匹配),否则回退索引匹配
|
|
|
|
|
+ boolean hasRuleIds = groups.stream().anyMatch(g -> g.getId() != null && !g.getId().isEmpty());
|
|
|
|
|
+ Map<String, AgreementRulesVo> oldRuleMap = new LinkedHashMap<>();
|
|
|
|
|
+ if (hasRuleIds && CollUtil.isNotEmpty(oldRules)) {
|
|
|
|
|
+ for (AgreementRulesVo vo : oldRules) {
|
|
|
|
|
+ oldRuleMap.put(vo.getId(), vo);
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ Set<String> matchedOldIds = new HashSet<>();
|
|
|
|
|
+
|
|
|
for (int i = 0; i < groups.size(); i++) {
|
|
for (int i = 0; i < groups.size(); i++) {
|
|
|
RulesGroupParam group = groups.get(i);
|
|
RulesGroupParam group = groups.get(i);
|
|
|
- boolean isExisting = i < oldSize;
|
|
|
|
|
- // 复用已有规则ID,保持cover_rule_id引用不失效
|
|
|
|
|
- String ruleId = isExisting ? oldRules.get(i).getId() : IdGenerate.nextId();
|
|
|
|
|
-
|
|
|
|
|
- // 已有规则需先清除旧的属性关联
|
|
|
|
|
- if (isExisting) {
|
|
|
|
|
- agreementUndwrtRulesAttrLinkService.remove(new LambdaQueryWrapper<PtlAgreementUndwrtRulesAttrLink>()
|
|
|
|
|
- .eq(PtlAgreementUndwrtRulesAttrLink::getRulesId, ruleId));
|
|
|
|
|
|
|
+ String ruleId;
|
|
|
|
|
+ boolean isExisting;
|
|
|
|
|
+ String oldRuleDescription = null;
|
|
|
|
|
+
|
|
|
|
|
+ if (hasRuleIds) {
|
|
|
|
|
+ // ID模式:精确匹配
|
|
|
|
|
+ ruleId = group.getId();
|
|
|
|
|
+ isExisting = ruleId != null && !ruleId.isEmpty() && oldRuleMap.containsKey(ruleId);
|
|
|
|
|
+ if (isExisting) {
|
|
|
|
|
+ matchedOldIds.add(ruleId);
|
|
|
|
|
+ oldRuleDescription = oldRuleMap.get(ruleId).getRuleDescription();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ruleId = IdGenerate.nextId();
|
|
|
|
|
+ }
|
|
|
|
|
+ } else {
|
|
|
|
|
+ // 索引模式:回退到按顺序匹配
|
|
|
|
|
+ isExisting = i < oldSize;
|
|
|
|
|
+ if (isExisting) {
|
|
|
|
|
+ AgreementRulesVo oldVo = oldRules.get(i);
|
|
|
|
|
+ ruleId = oldVo.getId();
|
|
|
|
|
+ matchedOldIds.add(ruleId);
|
|
|
|
|
+ oldRuleDescription = oldVo.getRuleDescription();
|
|
|
|
|
+ } else {
|
|
|
|
|
+ ruleId = IdGenerate.nextId();
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
List<PtlAgreementUndwrtRulesAttrLink> andAttrLinks = processAndAttrs(group.getRulesAttrList(), undwrtRulesAttrList, ruleId);
|
|
List<PtlAgreementUndwrtRulesAttrLink> andAttrLinks = processAndAttrs(group.getRulesAttrList(), undwrtRulesAttrList, ruleId);
|
|
|
- if (CollUtil.isNotEmpty(andAttrLinks)) {
|
|
|
|
|
|
|
+
|
|
|
|
|
+ // 已有规则做差异比较更新,避免全删全插产生垃圾数据
|
|
|
|
|
+ if (isExisting) {
|
|
|
|
|
+ List<PtlAgreementUndwrtRulesAttrLink> oldLinks = agreementUndwrtRulesAttrLinkService.list(
|
|
|
|
|
+ new LambdaQueryWrapper<PtlAgreementUndwrtRulesAttrLink>()
|
|
|
|
|
+ .eq(PtlAgreementUndwrtRulesAttrLink::getRulesId, ruleId));
|
|
|
|
|
+ mergeAttrLinks(oldLinks, andAttrLinks);
|
|
|
|
|
+ } else if (CollUtil.isNotEmpty(andAttrLinks)) {
|
|
|
agreementUndwrtRulesAttrLinkMapper.insert(andAttrLinks);
|
|
agreementUndwrtRulesAttrLinkMapper.insert(andAttrLinks);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- PtlAgreementUndwrtRules rules = new PtlAgreementUndwrtRules();
|
|
|
|
|
- rules.setId(ruleId);
|
|
|
|
|
- rules.setOrderNum(i + 1);
|
|
|
|
|
- rules.setStartTime(param.getStartTime());
|
|
|
|
|
- rules.setEndTime(param.getEndTime());
|
|
|
|
|
- rules.setAgreementId(param.getAgreementId());
|
|
|
|
|
- rules.setParentId(parentId);
|
|
|
|
|
- rules.setRuleDescription(buildDesc(andAttrLinks, undwrtRulesAttrList));
|
|
|
|
|
|
|
+ String inputDesc = group.getInputDescription() != null ? group.getInputDescription() : param.getInputDescription();
|
|
|
|
|
+ int currentOrderNum = maxOrderNum + i + 1;
|
|
|
|
|
+ // ruleDescription:有新的属性链接则重新生成,否则保留旧值
|
|
|
|
|
+ String ruleDescription = CollUtil.isNotEmpty(andAttrLinks)
|
|
|
|
|
+ ? buildDesc(andAttrLinks, undwrtRulesAttrList)
|
|
|
|
|
+ : oldRuleDescription;
|
|
|
|
|
|
|
|
if (isExisting) {
|
|
if (isExisting) {
|
|
|
- baseMapper.updateById(rules);
|
|
|
|
|
|
|
+ // 使用 LambdaUpdateWrapper 显式指定更新字段,避免 updateById 将 null 字段写入 SQL
|
|
|
|
|
+ LambdaUpdateWrapper<PtlAgreementUndwrtRules> updateWrapper = new LambdaUpdateWrapper<>();
|
|
|
|
|
+ updateWrapper.eq(PtlAgreementUndwrtRules::getId, ruleId)
|
|
|
|
|
+ .set(PtlAgreementUndwrtRules::getOrderNum, currentOrderNum)
|
|
|
|
|
+ .set(PtlAgreementUndwrtRules::getStartTime, param.getStartTime())
|
|
|
|
|
+ .set(PtlAgreementUndwrtRules::getEndTime, param.getEndTime())
|
|
|
|
|
+ .set(PtlAgreementUndwrtRules::getAgreementId, param.getAgreementId())
|
|
|
|
|
+ .set(PtlAgreementUndwrtRules::getParentId, parentId)
|
|
|
|
|
+ .set(PtlAgreementUndwrtRules::getInputDescription, inputDesc)
|
|
|
|
|
+ .set(PtlAgreementUndwrtRules::getRuleDescription, ruleDescription);
|
|
|
|
|
+ baseMapper.update(null, updateWrapper);
|
|
|
} else {
|
|
} else {
|
|
|
|
|
+ PtlAgreementUndwrtRules rules = new PtlAgreementUndwrtRules();
|
|
|
|
|
+ rules.setId(ruleId);
|
|
|
|
|
+ rules.setOrderNum(currentOrderNum);
|
|
|
|
|
+ rules.setStartTime(param.getStartTime());
|
|
|
|
|
+ rules.setEndTime(param.getEndTime());
|
|
|
|
|
+ rules.setAgreementId(param.getAgreementId());
|
|
|
|
|
+ rules.setParentId(parentId);
|
|
|
|
|
+ rules.setInputDescription(inputDesc);
|
|
|
|
|
+ rules.setRuleDescription(ruleDescription);
|
|
|
baseMapper.insert(rules);
|
|
baseMapper.insert(rules);
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
- // 2. 删除多余的旧规则(新规则数量 < 旧规则数量时才触发)
|
|
|
|
|
- if (oldSize > groups.size()) {
|
|
|
|
|
- for (int i = groups.size(); i < oldSize; i++) {
|
|
|
|
|
- AgreementRulesVo oldRule = oldRules.get(i);
|
|
|
|
|
- agreementUndwrtRulesAttrLinkService.remove(new LambdaQueryWrapper<PtlAgreementUndwrtRulesAttrLink>()
|
|
|
|
|
- .eq(PtlAgreementUndwrtRulesAttrLink::getRulesId, oldRule.getId()));
|
|
|
|
|
- baseMapper.deleteById(oldRule.getId());
|
|
|
|
|
|
|
+ // 2. 删除未被匹配的旧规则(本次请求中不存在对应group的旧规则)
|
|
|
|
|
+ if (CollUtil.isNotEmpty(oldRules)) {
|
|
|
|
|
+ for (AgreementRulesVo oldRule : oldRules) {
|
|
|
|
|
+ if (!matchedOldIds.contains(oldRule.getId())) {
|
|
|
|
|
+ agreementUndwrtRulesAttrLinkService.remove(new LambdaQueryWrapper<PtlAgreementUndwrtRulesAttrLink>()
|
|
|
|
|
+ .eq(PtlAgreementUndwrtRulesAttrLink::getRulesId, oldRule.getId()));
|
|
|
|
|
+ baseMapper.deleteById(oldRule.getId());
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -323,9 +428,10 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
|
|
|
PtlAgreementUndwrtRules rules = new PtlAgreementUndwrtRules();
|
|
PtlAgreementUndwrtRules rules = new PtlAgreementUndwrtRules();
|
|
|
BeanUtils.copyProperties(param, rules);
|
|
BeanUtils.copyProperties(param, rules);
|
|
|
|
|
|
|
|
- // 删除费用因子
|
|
|
|
|
- agreementUndwrtRulesAttrLinkService.remove(new LambdaQueryWrapper<PtlAgreementUndwrtRulesAttrLink>()
|
|
|
|
|
- .eq(PtlAgreementUndwrtRulesAttrLink::getRulesId, param.getId()));
|
|
|
|
|
|
|
+ // 查询旧的属性链接,做差异合并而非全删全插
|
|
|
|
|
+ List<PtlAgreementUndwrtRulesAttrLink> oldLinks = agreementUndwrtRulesAttrLinkService.list(
|
|
|
|
|
+ new LambdaQueryWrapper<PtlAgreementUndwrtRulesAttrLink>()
|
|
|
|
|
+ .eq(PtlAgreementUndwrtRulesAttrLink::getRulesId, param.getId()));
|
|
|
|
|
|
|
|
List<PtlAgreementUndwrtRulesAttr> attrList = undwrtRulesAttrList;
|
|
List<PtlAgreementUndwrtRulesAttr> attrList = undwrtRulesAttrList;
|
|
|
//再添加属性值
|
|
//再添加属性值
|
|
@@ -353,7 +459,7 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
|
|
|
}
|
|
}
|
|
|
costsAttrLink.add(link);
|
|
costsAttrLink.add(link);
|
|
|
});
|
|
});
|
|
|
- agreementUndwrtRulesAttrLinkService.saveBatch(costsAttrLink);
|
|
|
|
|
|
|
+ mergeAttrLinks(oldLinks, costsAttrLink);
|
|
|
rules.setStartTime(param.getStartTime());
|
|
rules.setStartTime(param.getStartTime());
|
|
|
rules.setEndTime(param.getEndTime());
|
|
rules.setEndTime(param.getEndTime());
|
|
|
rules.setRuleDescription(buildDesc(costsAttrLink, attrList));
|
|
rules.setRuleDescription(buildDesc(costsAttrLink, attrList));
|
|
@@ -554,6 +660,7 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
|
|
|
if (null != link.getMin()) {
|
|
if (null != link.getMin()) {
|
|
|
attr.setId(link.getId());
|
|
attr.setId(link.getId());
|
|
|
attr.setMinArray(link.getMin().split(","));
|
|
attr.setMinArray(link.getMin().split(","));
|
|
|
|
|
+ attr.setMin(link.getMin());
|
|
|
attr.setMax(link.getMax());
|
|
attr.setMax(link.getMax());
|
|
|
attr.setOperator(link.getOperator());
|
|
attr.setOperator(link.getOperator());
|
|
|
}
|
|
}
|
|
@@ -577,10 +684,30 @@ public class PtlAgreementUndwrtRulesServiceImpl extends ServiceImpl<PtlAgreement
|
|
|
|
|
|
|
|
@Override
|
|
@Override
|
|
|
public boolean deleteById(String id) {
|
|
public boolean deleteById(String id) {
|
|
|
|
|
+ // 查询当前规则的parentId
|
|
|
|
|
+ PtlAgreementUndwrtRules currentRule = baseMapper.selectById(id);
|
|
|
|
|
+ if (currentRule == null) {
|
|
|
|
|
+ return false;
|
|
|
|
|
+ }
|
|
|
|
|
+ // 收集需要删除的规则ID(同一parentId下的所有规则)
|
|
|
|
|
+ List<String> deleteRuleIds = new ArrayList<>();
|
|
|
|
|
+ deleteRuleIds.add(id);
|
|
|
|
|
+ if (currentRule.getParentId() != null && !currentRule.getParentId().isEmpty()) {
|
|
|
|
|
+ List<AgreementRulesVo> siblingRules = baseMapper.queryListByParentId(currentRule.getParentId());
|
|
|
|
|
+ if (CollUtil.isNotEmpty(siblingRules)) {
|
|
|
|
|
+ for (AgreementRulesVo vo : siblingRules) {
|
|
|
|
|
+ if (!id.equals(vo.getId())) {
|
|
|
|
|
+ deleteRuleIds.add(vo.getId());
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ // 删除所有关联的attr_link
|
|
|
agreementUndwrtRulesAttrLinkService.remove(
|
|
agreementUndwrtRulesAttrLinkService.remove(
|
|
|
new LambdaQueryWrapper<PtlAgreementUndwrtRulesAttrLink>()
|
|
new LambdaQueryWrapper<PtlAgreementUndwrtRulesAttrLink>()
|
|
|
- .eq(PtlAgreementUndwrtRulesAttrLink::getRulesId, id));
|
|
|
|
|
- return baseMapper.deleteById(id) > 0;
|
|
|
|
|
|
|
+ .in(PtlAgreementUndwrtRulesAttrLink::getRulesId, deleteRuleIds));
|
|
|
|
|
+ // 批量删除规则
|
|
|
|
|
+ return baseMapper.deleteBatchIds(deleteRuleIds) > 0;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
/**
|