相对方修改

This commit is contained in:
2026-06-09 14:12:09 +08:00
parent ef7f559490
commit e54ee065ee
3 changed files with 156 additions and 29 deletions
@@ -20,12 +20,15 @@ public class ContractLaunchPartyDto implements Serializable {
/** 关联合同主表 ID */ /** 关联合同主表 ID */
private Long contractId; private Long contractId;
/** 角色编码(A:甲方/我方, B:乙方/相对方, C:丙方 等 */ /** 角色编码(OUR:我方主体, OPPOSITE:相对方 */
private String roleCode; private String roleCode;
/** 角色名称(甲方/乙方/丙方) */ /** 角色名称(我方/相对方) */
private String roleName; private String roleName;
/** 主体编码(前端传值,当前不单独落库,用于拼接 signingSubjectCode/c_weNames */
private String subjectCode;
/** 排序号 */ /** 排序号 */
private Integer sortOrder; private Integer sortOrder;
@@ -217,13 +217,25 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
throw new ServiceException("当前状态不允许提交法务"); throw new ServiceException("当前状态不允许提交法务");
} }
SysUserEntity currentUser = adminSecurityManage.getUser(); SysUserEntity currentUser = adminSecurityManage.getUser();
boolean singleAgreement = isSingleAgreement(contract);
contract.setStatus(ContractLaunchConstants.STATUS_REVIEWING); contract.setStatus(ContractLaunchConstants.STATUS_REVIEWING);
contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_PENDING); contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_PENDING);
contract.setApproveMessage("已提交法务,等待审批"); contract.setApproveMessage(singleAgreement ? "已提交内部审批,等待审批" : "已提交法务,等待审批");
contract.setUpdateBy(currentUser.getUsername()); contract.setUpdateBy(currentUser.getUsername());
contract.setUpdateTime(LocalDateTime.now()); contract.setUpdateTime(LocalDateTime.now());
contractLaunchMapper.updateContract(contract); contractLaunchMapper.updateContract(contract);
if (singleAgreement) {
Map<String, Object> approvalPayload = new LinkedHashMap<>();
approvalPayload.put("approvalType", "internal");
approvalPayload.put("isSingleAgreement", contract.getIsSingleAgreement());
approvalPayload.put("contractSysId", contract.getContractSysId());
approvalPayload.put("contractName", contract.getContractName());
approvalPayload.put("partyList", contract.getPartyList());
insertLog(id, ContractLaunchConstants.ACTION_SUBMIT, "提交内部审批", ContractLaunchConstants.ACTION_STATUS_PENDING, "单方协议已提交内部审批,未推送法务", approvalPayload, currentUser);
return getDetail(id);
}
Map<String, Object> settlementPayload = buildSettlementPushPayload(contract); Map<String, Object> settlementPayload = buildSettlementPushPayload(contract);
log.info("结算参数 JSON{}", JsonUtils.toJson(settlementPayload)); log.info("结算参数 JSON{}", JsonUtils.toJson(settlementPayload));
insertLog(id, ContractLaunchConstants.ACTION_SUBMIT, "提交法务", ContractLaunchConstants.ACTION_STATUS_PENDING, "合同已提交法务接口,当前先保留 mock 流程", settlementPayload, currentUser); insertLog(id, ContractLaunchConstants.ACTION_SUBMIT, "提交法务", ContractLaunchConstants.ACTION_STATUS_PENDING, "合同已提交法务接口,当前先保留 mock 流程", settlementPayload, currentUser);
@@ -256,21 +268,24 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
throw new ServiceException("仅审批中的合同可模拟通过"); throw new ServiceException("仅审批中的合同可模拟通过");
} }
SysUserEntity currentUser = adminSecurityManage.getUser(); SysUserEntity currentUser = adminSecurityManage.getUser();
boolean singleAgreement = isSingleAgreement(contract);
contract.setStatus(ContractLaunchConstants.STATUS_PENDING_SIGN); contract.setStatus(ContractLaunchConstants.STATUS_PENDING_SIGN);
contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_APPROVED); contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_APPROVED);
contract.setApproveMessage(approveDto == null || approveDto.getApproveMessage() == null || approveDto.getApproveMessage().isBlank() contract.setApproveMessage(approveDto == null || approveDto.getApproveMessage() == null || approveDto.getApproveMessage().isBlank()
? "法务审批通过(测试按钮模拟)" ? (singleAgreement ? "内部审批通过(测试按钮模拟)" : "法务审批通过(测试按钮模拟)")
: approveDto.getApproveMessage()); : approveDto.getApproveMessage());
if (!singleAgreement) {
contract.setLawContractCode(approveDto == null || approveDto.getLawContractCode() == null || approveDto.getLawContractCode().isBlank() contract.setLawContractCode(approveDto == null || approveDto.getLawContractCode() == null || approveDto.getLawContractCode().isBlank()
? "LAW-" + ContractLaunchCodeUtils.buildContractCode(contract.getContractTypeCode()) ? "LAW-" + ContractLaunchCodeUtils.buildContractCode(contract.getContractTypeCode())
: approveDto.getLawContractCode()); : approveDto.getLawContractCode());
contract.setLawContractId(approveDto == null || approveDto.getLawContractId() == null || approveDto.getLawContractId().isBlank() contract.setLawContractId(approveDto == null || approveDto.getLawContractId() == null || approveDto.getLawContractId().isBlank()
? "LAWID-" + id ? "LAWID-" + id
: approveDto.getLawContractId()); : approveDto.getLawContractId());
}
contract.setUpdateBy(currentUser.getUsername()); contract.setUpdateBy(currentUser.getUsername());
contract.setUpdateTime(LocalDateTime.now()); contract.setUpdateTime(LocalDateTime.now());
contractLaunchMapper.updateContract(contract); contractLaunchMapper.updateContract(contract);
insertLog(id, ContractLaunchConstants.ACTION_APPROVE, "模拟审批通过", ContractLaunchConstants.ACTION_STATUS_SUCCESS, contract.getApproveMessage(), approveDto, currentUser); insertLog(id, ContractLaunchConstants.ACTION_APPROVE, singleAgreement ? "模拟内部审批通过" : "模拟审批通过", ContractLaunchConstants.ACTION_STATUS_SUCCESS, contract.getApproveMessage(), approveDto, currentUser);
return getDetail(id); return getDetail(id);
} }
@@ -288,15 +303,16 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
throw new ServiceException("仅审批中的合同可模拟驳回"); throw new ServiceException("仅审批中的合同可模拟驳回");
} }
SysUserEntity currentUser = adminSecurityManage.getUser(); SysUserEntity currentUser = adminSecurityManage.getUser();
boolean singleAgreement = isSingleAgreement(contract);
contract.setStatus(ContractLaunchConstants.STATUS_REJECTED); contract.setStatus(ContractLaunchConstants.STATUS_REJECTED);
contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_REJECTED); contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_REJECTED);
contract.setApproveMessage(approveDto == null || approveDto.getApproveMessage() == null || approveDto.getApproveMessage().isBlank() contract.setApproveMessage(approveDto == null || approveDto.getApproveMessage() == null || approveDto.getApproveMessage().isBlank()
? "法务审批驳回(测试按钮模拟)" ? (singleAgreement ? "内部审批驳回(测试按钮模拟)" : "法务审批驳回(测试按钮模拟)")
: approveDto.getApproveMessage()); : approveDto.getApproveMessage());
contract.setUpdateBy(currentUser.getUsername()); contract.setUpdateBy(currentUser.getUsername());
contract.setUpdateTime(LocalDateTime.now()); contract.setUpdateTime(LocalDateTime.now());
contractLaunchMapper.updateContract(contract); contractLaunchMapper.updateContract(contract);
insertLog(id, ContractLaunchConstants.ACTION_REJECT, "模拟审批驳回", ContractLaunchConstants.ACTION_STATUS_SUCCESS, contract.getApproveMessage(), approveDto, currentUser); insertLog(id, ContractLaunchConstants.ACTION_REJECT, singleAgreement ? "模拟内部审批驳回" : "模拟审批驳回", ContractLaunchConstants.ACTION_STATUS_SUCCESS, contract.getApproveMessage(), approveDto, currentUser);
return getDetail(id); return getDetail(id);
} }
@@ -810,6 +826,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
list.forEach(item -> { list.forEach(item -> {
item.setPartyList(new ArrayList<>(partyMap.getOrDefault(item.getId(), Collections.emptyList()))); item.setPartyList(new ArrayList<>(partyMap.getOrDefault(item.getId(), Collections.emptyList())));
enrichOurPartySubjectCodes(item);
List<ContractLaunchFileDto> contractFiles = new ArrayList<>(fileMap.getOrDefault(item.getId(), Collections.emptyList())); List<ContractLaunchFileDto> contractFiles = new ArrayList<>(fileMap.getOrDefault(item.getId(), Collections.emptyList()));
item.setFileList(contractFiles); item.setFileList(contractFiles);
item.setPerformancePlans(new ArrayList<>(planMap.getOrDefault(item.getId(), Collections.emptyList()))); item.setPerformancePlans(new ArrayList<>(planMap.getOrDefault(item.getId(), Collections.emptyList())));
@@ -823,7 +840,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
item.setLogList(new ArrayList<>(logMap.getOrDefault(item.getId(), Collections.emptyList()))); item.setLogList(new ArrayList<>(logMap.getOrDefault(item.getId(), Collections.emptyList())));
item.setCounterpartySummary( item.setCounterpartySummary(
item.getPartyList().stream() item.getPartyList().stream()
.filter(party -> !"A".equalsIgnoreCase(party.getRoleCode())) .filter(this::isOppositeParty)
.map(ContractLaunchPartyDto::getCompanyName) .map(ContractLaunchPartyDto::getCompanyName)
.filter(name -> name != null && !name.isBlank()) .filter(name -> name != null && !name.isBlank())
.collect(Collectors.joining("")) .collect(Collectors.joining(""))
@@ -831,6 +848,33 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
}); });
} }
private void enrichOurPartySubjectCodes(ContractLaunchDto contract) {
if (contract == null || contract.getPartyList() == null || contract.getPartyList().isEmpty()) {
return;
}
List<String> subjectCodes = String.valueOf(contract.getSigningSubjectCode() == null ? "" : contract.getSigningSubjectCode())
.split(",").length == 0 ? List.of() : java.util.Arrays.stream(String.valueOf(contract.getSigningSubjectCode() == null ? "" : contract.getSigningSubjectCode()).split(","))
.map(String::trim)
.filter(item -> !item.isBlank())
.collect(Collectors.toList());
int ourIndex = 0;
for (ContractLaunchPartyDto party : contract.getPartyList()) {
if (!isOurParty(party)) {
continue;
}
if (party.getSubjectCode() != null && !party.getSubjectCode().isBlank()) {
ourIndex++;
continue;
}
if (subjectCodes.size() == 1) {
party.setSubjectCode(subjectCodes.get(0));
} else if (ourIndex < subjectCodes.size()) {
party.setSubjectCode(subjectCodes.get(ourIndex));
}
ourIndex++;
}
}
/** 保存子表数据(合同方/文件/履行计划,插入前生成主键 ID) */ /** 保存子表数据(合同方/文件/履行计划,插入前生成主键 ID) */
private void saveChildren(ContractLaunchDto contract, String operator) { private void saveChildren(ContractLaunchDto contract, String operator) {
if (contract.getPartyList() != null) { if (contract.getPartyList() != null) {
@@ -967,6 +1011,77 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
if (contract.getPerformancePlans() == null) { if (contract.getPerformancePlans() == null) {
contract.setPerformancePlans(new ArrayList<>()); contract.setPerformancePlans(new ArrayList<>());
} }
normalizePartyList(contract);
contract.setSigningSubjectCode(resolveSigningSubjectCodes(contract));
}
private void normalizePartyList(ContractLaunchDto contract) {
if (contract == null || contract.getPartyList() == null) {
return;
}
List<ContractLaunchPartyDto> normalized = contract.getPartyList().stream()
.filter(Objects::nonNull)
.filter(item -> item.getCompanyName() != null && !item.getCompanyName().isBlank())
.peek(item -> {
String roleCode = trim(item.getRoleCode());
if (roleCode == null || roleCode.isBlank()) {
roleCode = "OPPOSITE";
}
item.setRoleCode(roleCode.toUpperCase());
if (isOurParty(item)) {
item.setRoleName("我方");
} else if (isOppositeParty(item)) {
item.setRoleName("相对方");
}
item.setSubjectCode(trim(item.getSubjectCode()));
item.setCompanyName(trim(item.getCompanyName()));
item.setCreditCode(trim(item.getCreditCode()));
item.setOppositeId(trim(item.getOppositeId()));
item.setContactName(trim(item.getContactName()));
item.setContactPhone(trim(item.getContactPhone()));
item.setContactEmail(trim(item.getContactEmail()));
item.setRegisteredAddress(trim(item.getRegisteredAddress()));
item.setContactAddress(trim(item.getContactAddress()));
item.setLegalRepresentative(trim(item.getLegalRepresentative()));
item.setBankName(trim(item.getBankName()));
item.setBankAccount(trim(item.getBankAccount()));
})
.collect(Collectors.toList());
contract.setPartyList(normalized);
}
private boolean isOurParty(ContractLaunchPartyDto party) {
return party != null && "OUR".equalsIgnoreCase(trim(party.getRoleCode()));
}
private boolean isOppositeParty(ContractLaunchPartyDto party) {
return party != null && "OPPOSITE".equalsIgnoreCase(trim(party.getRoleCode()));
}
private boolean isSingleAgreement(ContractLaunchDto contract) {
String value = contract == null ? null : trim(contract.getIsSingleAgreement());
return "1".equals(value) || "Y".equalsIgnoreCase(value) || "true".equalsIgnoreCase(value);
}
private String resolveSigningSubjectCodes(ContractLaunchDto contract) {
if (contract == null) {
return null;
}
List<String> subjectCodes = contract.getPartyList() == null ? List.of() : contract.getPartyList().stream()
.filter(this::isOurParty)
.map(ContractLaunchPartyDto::getSubjectCode)
.filter(Objects::nonNull)
.map(String::trim)
.filter(item -> !item.isBlank())
.distinct()
.collect(Collectors.toList());
if (!subjectCodes.isEmpty()) {
return String.join(",", subjectCodes);
}
if (contract.getSigningSubjectCode() != null && !contract.getSigningSubjectCode().isBlank()) {
return trim(contract.getSigningSubjectCode());
}
return trim(contract.getOrgId());
} }
/** 校验草稿必填项 */ /** 校验草稿必填项 */
@@ -1013,12 +1128,26 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
if ("2".equals(contract.getValuationMode()) && contract.getEstimatedAmount() == null) { if ("2".equals(contract.getValuationMode()) && contract.getEstimatedAmount() == null) {
throw new ServiceException("预估总价合同必须填写预估金额"); throw new ServiceException("预估总价合同必须填写预估金额");
} }
boolean hasPartyA = contract.getPartyList().stream().anyMatch(item -> "A".equalsIgnoreCase(item.getRoleCode())); boolean hasOurParty = contract.getPartyList().stream().anyMatch(this::isOurParty);
boolean hasCounterparty = contract.getPartyList().stream().anyMatch(item -> !"A".equalsIgnoreCase(item.getRoleCode())); boolean hasCounterparty = contract.getPartyList().stream().anyMatch(this::isOppositeParty);
if (!hasPartyA) { if (!hasOurParty) {
throw new ServiceException("必须维护我方信息"); throw new ServiceException("必须维护我方信息");
} }
if (!hasCounterparty) { String currentOrgId = trim(adminSecurityManage.getUser() == null || adminSecurityManage.getUser().getSysOrgEntity() == null
? null
: adminSecurityManage.getUser().getSysOrgEntity().getId());
if (currentOrgId != null && !currentOrgId.isBlank()) {
boolean containsCurrentOrg = contract.getPartyList().stream()
.filter(this::isOurParty)
.map(ContractLaunchPartyDto::getSubjectCode)
.filter(Objects::nonNull)
.map(String::trim)
.anyMatch(currentOrgId::equals);
if (!containsCurrentOrg) {
throw new ServiceException("我方主体中必须包含当前登录主体");
}
}
if (!isSingleAgreement(contract) && !hasCounterparty) {
throw new ServiceException("至少维护一个相对方"); throw new ServiceException("至少维护一个相对方");
} }
if (Integer.valueOf(1).equals(contract.getIsOpenBidding()) if (Integer.valueOf(1).equals(contract.getIsOpenBidding())
@@ -1109,10 +1238,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
payload.put("paymentDirection", contract.getPaymentDirection()); payload.put("paymentDirection", contract.getPaymentDirection());
payload.put("contractTypeCode", contract.getContractTypeCode()); payload.put("contractTypeCode", contract.getContractTypeCode());
payload.put("bodySummary", contract.getBodySummary()); payload.put("bodySummary", contract.getBodySummary());
payload.put("signingSubjectCode", payload.put("signingSubjectCode", resolveSigningSubjectCodes(contract));
contract.getSigningSubjectCode() == null || contract.getSigningSubjectCode().isBlank()
? contract.getOrgId()
: contract.getSigningSubjectCode());
payload.put("executorAccount", contract.getExecutorAccount()); payload.put("executorAccount", contract.getExecutorAccount());
payload.put("contractPeriod", contract.getContractPeriodType()); payload.put("contractPeriod", contract.getContractPeriodType());
payload.put("contractAmount", contract.getContractAmount()); payload.put("contractAmount", contract.getContractAmount());
@@ -1130,7 +1256,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
payload.put("yfkAmount", contract.getYfkAmount()); payload.put("yfkAmount", contract.getYfkAmount());
payload.put("bzjAmount", contract.getBzjAmount()); payload.put("bzjAmount", contract.getBzjAmount());
payload.put("contractOpposites", contract.getPartyList().stream() payload.put("contractOpposites", contract.getPartyList().stream()
.filter(item -> !"A".equalsIgnoreCase(item.getRoleCode())) .filter(this::isOppositeParty)
.map(item -> { .map(item -> {
Map<String, Object> map = new LinkedHashMap<>(); Map<String, Object> map = new LinkedHashMap<>();
map.put("oppCharacter", "2".equals(item.getOppositeCharacter()) ? "ZZR" : "QY"); map.put("oppCharacter", "2".equals(item.getOppositeCharacter()) ? "ZZR" : "QY");
@@ -1163,12 +1289,9 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
Map<String, Object> payload = new LinkedHashMap<>(); Map<String, Object> payload = new LinkedHashMap<>();
payload.put("c_name", contract.getContractName()); payload.put("c_name", contract.getContractName());
payload.put("c_code", contract.getLawContractCode() == null || contract.getLawContractCode().isBlank() ? contract.getContractCode() : contract.getLawContractCode()); payload.put("c_code", contract.getLawContractCode() == null || contract.getLawContractCode().isBlank() ? contract.getContractCode() : contract.getLawContractCode());
// TODO: c_weNames 传机构编码,当前用 signingSubjectCode(签约主体编码),若为空则用 orgId payload.put("c_weNames", resolveSigningSubjectCodes(contract));
payload.put("c_weNames", contract.getSigningSubjectCode() != null && !contract.getSigningSubjectCode().isBlank()
? contract.getSigningSubjectCode()
: contract.getOrgId());
payload.put("c_oppositeNames", contract.getPartyList().stream() payload.put("c_oppositeNames", contract.getPartyList().stream()
.filter(item -> !"A".equalsIgnoreCase(item.getRoleCode())) .filter(this::isOppositeParty)
.map(item -> item.getOppositeId() != null && !item.getOppositeId().isBlank() .map(item -> item.getOppositeId() != null && !item.getOppositeId().isBlank()
? item.getOppositeId() ? item.getOppositeId()
: item.getPartnerId() == null ? null : String.valueOf(item.getPartnerId())) : item.getPartnerId() == null ? null : String.valueOf(item.getPartnerId()))
@@ -22,6 +22,7 @@
<result property="customerBankaccount" column="CUSTOMER_BANKACCOUNT"/> <result property="customerBankaccount" column="CUSTOMER_BANKACCOUNT"/>
<result property="customerRegaddr" column="CUSTOMER_REGADDR"/> <result property="customerRegaddr" column="CUSTOMER_REGADDR"/>
<result property="emailAddress" column="EMAIL_ADDRESS"/> <result property="emailAddress" column="EMAIL_ADDRESS"/>
<result property="orgId" column="ORG_ID"/>
<result property="oppositeId" column="OPPOSITE_ID"/> <result property="oppositeId" column="OPPOSITE_ID"/>
<result property="oppositeCharacter" column="OPPOSITE_CHARACTER"/> <result property="oppositeCharacter" column="OPPOSITE_CHARACTER"/>
<result property="gatFlag" column="GAT_FLAG"/> <result property="gatFlag" column="GAT_FLAG"/>
@@ -68,7 +69,7 @@
<sql id="selectPartnerColumns"> <sql id="selectPartnerColumns">
select CUSTOMER_SYSID, CUSTOMER_REGNO, CUSTOMER_NO, CUSTOMER_NAME_C, CUSTOMER_TAXNO, select CUSTOMER_SYSID, CUSTOMER_REGNO, CUSTOMER_NO, CUSTOMER_NAME_C, CUSTOMER_TAXNO,
CUSTOMER_ADDRESS, OFFICEPHONE, CUSTOMER_BANK, CUSTOMER_BANKACCOUNT, CUSTOMER_REGADDR, CUSTOMER_ADDRESS, OFFICEPHONE, CUSTOMER_BANK, CUSTOMER_BANKACCOUNT, CUSTOMER_REGADDR,
EMAIL_ADDRESS, OPPOSITE_ID, OPPOSITE_CHARACTER, GAT_FLAG, GROUP_FLAG, EMAIL_ADDRESS, ORG_ID, OPPOSITE_ID, OPPOSITE_CHARACTER, GAT_FLAG, GROUP_FLAG,
COUNTRY, COUNTRY_NAME, LEGAL_PERSON_NAME, CERTIFICATE_TYPE, COUNTRY, COUNTRY_NAME, LEGAL_PERSON_NAME, CERTIFICATE_TYPE,
CERTIFICATE_NUM, TIN_CODE, REGISTERED_CAPITAL, REG_CAPITAL, CERTIFICATE_NUM, TIN_CODE, REGISTERED_CAPITAL, REG_CAPITAL,
OPPOSITE_CODE, OPPOSITE_STATUS, IS_SGAT, IS_JTN, OPPOSITE_CODE, OPPOSITE_STATUS, IS_SGAT, IS_JTN,