feat: 合同变更记录对齐项目变更,自动生成变更内容并记录变更字段

This commit is contained in:
刘泉佳
2026-10-28 15:01:49 +08:00
parent 5c4f9ba6f4
commit 857a32f29c
@@ -67,6 +67,7 @@ import java.util.Objects;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* 合同管理 服务实现类
@@ -1279,11 +1280,12 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
record.put("handlerUserId", AuthUtil.getUserId());
record.put("handlerUserName", AuthUtil.getUserName());
record.put("changeType", changeType);
record.put("changeContent", TransportBusinessSupport.trimToNull(contractManage.getChangeContent()));
record.put("changeContent", resolveChangeRecordContent(contractManage, beforeData, afterData));
record.put("changeReason", TransportBusinessSupport.trimToNull(changeReason));
record.put("status", status);
record.put("statusName", statusName);
if (beforeData != null && afterData != null) {
record.put("changedFields", new ArrayList<>(beforeData.keySet()));
record.put("beforeData", beforeData);
record.put("afterData", afterData);
}
@@ -1291,6 +1293,54 @@ public class ContractManageServiceImpl extends BaseServiceImpl<ContractManageMap
contractManage.setChangeRecordJson(JsonUtil.toJson(records));
}
/**
* 变更记录内容:有前后快照时生成「将【字段】由【旧值】变更为【新值】」对比文本(与项目变更记录一致),
* 无快照(创建/回调等)时沿用填写的变更内容
*/
private String resolveChangeRecordContent(ContractManage contractManage, Map<String, Object> beforeData,
Map<String, Object> afterData) {
if (beforeData == null || afterData == null || beforeData.isEmpty()) {
return TransportBusinessSupport.trimToNull(contractManage.getChangeContent());
}
return beforeData.entrySet().stream()
.map(entry -> "将【" + contractChangeFieldLabel(entry.getKey()) + "】由【" + formatChangeRecordValue(entry.getValue())
+ "】变更为【" + formatChangeRecordValue(afterData.get(entry.getKey())) + "】")
.collect(Collectors.joining("、"));
}
/**
* 合同变更快照字段中文名(change_record_json 展示用,与前端变更字段标签一致)
*/
private static final Map<String, String> CONTRACT_CHANGE_FIELD_LABELS = Map.ofEntries(
Map.entry("contractNo", "合同编号"), Map.entry("contractName", "合同名称"),
Map.entry("partyB", "乙方"), Map.entry("startDate", "开始日期"),
Map.entry("endDate", "结束日期"), Map.entry("contractFormat", "合同格式"),
Map.entry("settlementMode", "结算方式"), Map.entry("legalSealFlag", "是否需要加盖法人章"),
Map.entry("copyCount", "一式份数"), Map.entry("settlementCurrency", "结算币种"),
Map.entry("invoiceCycle", "开票周期(天)"), Map.entry("paymentDays", "回款账期(天)"),
Map.entry("contractAmount", "合同金额"), Map.entry("templateFlag", "是否范本"),
Map.entry("originalContractNo", "原件合同编号"), Map.entry("electronicSealFlag", "是否电子章"),
Map.entry("mainContent", "合同主要内容"), Map.entry("remark", "其他事项说明"),
Map.entry("feeGenerationMode", "费用生成模式"), Map.entry("billingPlanJson", "计费方案"),
Map.entry("settlementRuleJson", "结算生成规则"), Map.entry("preSettlementConfigJson", "预结算配置"),
Map.entry("formalSettlementConfigJson", "正式结算配置"), Map.entry("paymentRatioJson", "付款比例设置"),
Map.entry("contractFileJson", "合同主文件"), Map.entry("attachmentsJson", "其它附件"),
Map.entry("changeAttachmentsJson", "变更附件")
);
private String contractChangeFieldLabel(String field) {
return CONTRACT_CHANGE_FIELD_LABELS.getOrDefault(field, field);
}
private String formatChangeRecordValue(Object value) {
if (value == null || (value instanceof String text && text.isBlank())) {
return "空";
}
String text = String.valueOf(value);
// 计费方案/附件等长 JSON 文本截断,保证变更内容可读
return text.length() > 100 ? text.substring(0, 100) + "…" : text;
}
private Map<String, Object> buildContractChangeSnapshot(ContractManage contractManage) {
Map<String, Object> data = new LinkedHashMap<>();
data.put("contractNo", contractManage.getContractNo());