相对方确认签署

This commit is contained in:
2026-07-01 13:00:06 +08:00
parent 9964b79e54
commit 4433646003
3 changed files with 63 additions and 33 deletions
@@ -337,17 +337,21 @@ public class ContractLaunchController {
/**
* 相对方确认已签署完成。
*
* 请求体:{"companyName": "四川德鑫矿业资源有限公司"}
* 请求体:{"partyId": 123}
* 后端自动获取当前登录用户信息写入确认记录。
*/
@PostMapping("/{id}/counterparty-confirm")
public R<Map<String, Object>> confirmCounterparty(@PathVariable("id") Long id,
@RequestBody Map<String, String> body) {
String companyName = body.get("companyName");
if (companyName == null || companyName.isBlank()) {
return R.error("companyName 不能为空");
String partyIdValue = body.get("partyId");
if (partyIdValue == null || partyIdValue.isBlank()) {
return R.error("partyId 不能为空");
}
try {
return R.success(contractLaunchService.confirmCounterparty(id, Long.valueOf(partyIdValue)));
} catch (NumberFormatException ex) {
return R.error("partyId 格式不正确");
}
return R.success(contractLaunchService.confirmCounterparty(id, companyName));
}
/**
@@ -63,7 +63,7 @@ public interface ContractLaunchService {
Map<String, Object> getCounterpartyConfirmFiltered(Long id);
/** 相对方确认已签署完成 */
Map<String, Object> confirmCounterparty(Long id, String companyName);
Map<String, Object> confirmCounterparty(Long id, Long partyId);
/** 模拟合同采集(调用数据采集 collectContract 接口,TODO:替换为真实调用) */
ContractLaunchDto mockCollect(Long id);
@@ -612,58 +612,61 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
@Override
public Map<String, Object> getCounterpartyConfirmFiltered(Long id) {
Map<String, Object> all = getCounterpartyConfirmMap(id);
SysUserEntity currentUser = adminSecurityManage.getUser();
boolean canManageAll = authManager.isUserCanAccessSys(currentUser.getId(), SysEnum.MANAGE);
if (canManageAll) {
return all;
}
// business 用户只返回自己组织对应的相对方确认状态
ContractLaunchDto contract = getDetail(id);
Map<String, Object> all = getCounterpartyConfirmMap(id);
List<Map<String, Object>> items = new ArrayList<>();
String userOrgId = currentUser.getSysOrgEntity() == null ? "" : String.valueOf(currentUser.getSysOrgEntity().getId());
String userOrgName = currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getOrgName();
Map<String, Object> filtered = new LinkedHashMap<>();
if (contract.getPartyList() != null) {
contract.getPartyList().stream()
.filter(this::isOppositeParty)
.filter(p -> userOrgId.equals(p.getOppositeId())
|| userOrgId.equals(p.getSubjectCode())
|| userOrgName.equals(p.getCompanyName()))
.forEach(p -> {
String name = p.getCompanyName();
filtered.put(name, all.getOrDefault(name, new LinkedHashMap<>()));
});
.filter(p -> canManageAll || userOrgId.equals(trim(p.getSubjectCode())))
.forEach(p -> items.add(buildCounterpartyConfirmViewItem(p, all)));
}
return filtered;
Map<String, Object> result = new LinkedHashMap<>();
result.put("items", items);
return result;
}
@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, Object> confirmCounterparty(Long id, String companyName) {
public Map<String, Object> confirmCounterparty(Long id, Long partyId) {
ContractLaunchDto contract = getDetail(id);
SysUserEntity currentUser = adminSecurityManage.getUser();
String orgName = currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getOrgName();
String userOrgId = currentUser.getSysOrgEntity() == null ? "" : String.valueOf(currentUser.getSysOrgEntity().getId());
String username = currentUser.getUsername();
String mobile = currentUser.getMobilePhone();
if (partyId == null) {
throw new ServiceException("partyId 不能为空");
}
ContractLaunchPartyDto targetParty = contract.getPartyList() == null ? null : contract.getPartyList().stream()
.filter(this::isOppositeParty)
.filter(p -> Objects.equals(p.getId(), partyId))
.findFirst()
.orElse(null);
if (targetParty == null) {
throw new ServiceException("相对方不存在");
}
// 权限校验:business 用户只能确认自己组织对应的相对方
boolean canManageAll = authManager.isUserCanAccessSys(currentUser.getId(), SysEnum.MANAGE);
if (!canManageAll) {
String userOrgId = currentUser.getSysOrgEntity() == null ? "" : String.valueOf(currentUser.getSysOrgEntity().getId());
boolean matched = (contract.getPartyList() != null) && contract.getPartyList().stream()
.filter(this::isOppositeParty)
.anyMatch(p -> companyName.equals(p.getCompanyName())
&& (userOrgId.equals(p.getOppositeId()) || userOrgId.equals(p.getSubjectCode())));
if (!matched) {
if (!userOrgId.equals(trim(targetParty.getSubjectCode()))) {
throw new ServiceException("只能确认本组织对应的相对方");
}
}
Map<String, Object> confirmMap = getCounterpartyConfirmMap(id);
String confirmKey = buildCounterpartyConfirmKey(targetParty);
Map<String, Object> entry = new LinkedHashMap<>();
entry.put("confirmed", true);
boolean isSelf = companyName.equals(orgName);
entry.put("partyId", targetParty.getId());
entry.put("partnerId", targetParty.getPartnerId());
entry.put("companyName", targetParty.getCompanyName());
entry.put("subjectCode", targetParty.getSubjectCode());
boolean isSelf = userOrgId.equals(trim(targetParty.getSubjectCode()));
entry.put("method", isSelf ? "self" : "manual");
entry.put("confirmedBy", username);
entry.put("confirmedMobile", mobile);
@@ -671,13 +674,13 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
if (!isSelf) {
entry.put("remark", "非本组织相对方,由 " + username + " 代为确认");
}
confirmMap.put(companyName, entry);
confirmMap.put(confirmKey, entry);
contract.setCounterpartyConfirmJson(JsonUtils.toJson(confirmMap));
contract.setUpdateBy(username);
contract.setUpdateTime(LocalDateTime.now());
contractLaunchMapper.updateContract(contract);
return confirmMap;
return getCounterpartyConfirmFiltered(id);
}
/**
@@ -2176,6 +2179,29 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
return value == null ? null : value.trim();
}
private String buildCounterpartyConfirmKey(ContractLaunchPartyDto party) {
if (party == null || party.getId() == null) {
return "";
}
return "party_" + party.getId();
}
private Map<String, Object> buildCounterpartyConfirmViewItem(ContractLaunchPartyDto party, Map<String, Object> allConfirmMap) {
Map<String, Object> item = new LinkedHashMap<>();
item.put("partyId", party.getId());
item.put("partnerId", party.getPartnerId());
item.put("companyName", party.getCompanyName());
item.put("subjectCode", party.getSubjectCode());
item.put("oppositeId", party.getOppositeId());
Object state = allConfirmMap.get(buildCounterpartyConfirmKey(party));
if (state instanceof Map<?, ?> stateMap) {
item.putAll((Map<? extends String, ?>) stateMap);
} else {
item.put("confirmed", false);
}
return item;
}
private void applyQueryScope(ContractLaunchQueryDto queryDto, SysUserEntity currentUser) {
ContractLaunchQueryDto scopeQuery = buildScopeQuery(currentUser);
queryDto.setQueryScope(scopeQuery.getQueryScope());