用印时间

This commit is contained in:
2026-06-08 14:32:18 +08:00
parent 211f9bc01d
commit 6ea3bc6f6f
6 changed files with 145 additions and 6 deletions
@@ -287,6 +287,10 @@ public class ContractLaunchDto implements Serializable {
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime signDate;
/** 用印时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime sealDate;
/** 用印数量,默认为1 */
private Integer sealQuantity;
@@ -1,9 +1,11 @@
package com.nbport.zgwl.contractlaunch.dto;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.Data;
import java.io.Serial;
import java.io.Serializable;
import java.time.LocalDateTime;
/**
* 签章回写参数
@@ -40,4 +42,16 @@ public class ContractLaunchSealDto implements Serializable {
private String signedFileUrl;
private String signedOfflineReason;
/** 签订日期 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime signDate;
/** 用印时间 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime sealDate;
/** 合同生效日期 */
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private LocalDateTime activeDate;
}
@@ -396,6 +396,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
public ContractLaunchDto markSealCompleted(Long id, ContractLaunchSealDto sealDto) {
ContractLaunchDto contract = getDetail(id);
SysUserEntity currentUser = adminSecurityManage.getUser();
LocalDateTime completedTime = LocalDateTime.now();
contract.setSealContractId(sealDto.getSealContractId() == null || sealDto.getSealContractId().isBlank() ? contract.getSealContractId() : sealDto.getSealContractId());
contract.setSealContractStatus(sealDto.getSealContractStatus());
contract.setSignedFileName(sealDto.getSignedFileName());
@@ -406,9 +407,13 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
contract.setSignedFileType(sealDto.getSignedFileType());
contract.setSignedFileSize(sealDto.getSignedFileSize());
contract.setSignedOfflineReason(sealDto.getSignedOfflineReason());
contract.setSignDate(firstNonNull(sealDto.getSignDate(), contract.getSignDate(), completedTime));
contract.setSealDate(firstNonNull(sealDto.getSealDate(), contract.getSealDate(), contract.getSignDate()));
contract.setActiveDate(firstNonNull(sealDto.getActiveDate(), contract.getActiveDate()));
validateSignCompletion(contract);
contract.setStatus(ContractLaunchConstants.STATUS_PENDING_COLLECT);
contract.setUpdateBy(currentUser.getUsername());
contract.setUpdateTime(LocalDateTime.now());
contract.setUpdateTime(completedTime);
contractLaunchMapper.updateContract(contract);
saveSignedFile(id, sealDto, currentUser.getUsername());
insertLog(id, ContractLaunchConstants.ACTION_SEAL_FINISH, "签署完成", ContractLaunchConstants.ACTION_STATUS_SUCCESS, "合同签署已完成,待采集", sealDto, currentUser);
@@ -441,6 +446,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
if (!ContractLaunchConstants.STATUS_PENDING_COLLECT.equals(contract.getStatus())) {
throw new ServiceException("当前状态不允许执行采集");
}
validateCollectionReady(contract);
SysUserEntity currentUser = adminSecurityManage.getUser();
Map<String, Object> payload = buildDataCollectionContractPayload(contract);
insertLog(id, ContractLaunchConstants.ACTION_COLLECT, "模拟合同采集", ContractLaunchConstants.ACTION_STATUS_PENDING, "合同采集接口当前先注释,使用测试按钮流转", payload, currentUser);
@@ -654,6 +660,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
target.setContractTextFileType(source.getContractTextFileType());
target.setContractTextFileSize(source.getContractTextFileSize());
target.setSignDate(source.getSignDate());
target.setSealDate(source.getSealDate());
target.setActiveDate(source.getActiveDate());
target.setInvoiceDate(source.getInvoiceDate());
target.setReceiveDate(source.getReceiveDate());
@@ -975,6 +982,10 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
&& (contract.getPeriodExplain() == null || contract.getPeriodExplain().isBlank())) {
throw new ServiceException("无固定期限合同必须填写期限说明");
}
if (contract.getActiveDate() == null) {
throw new ServiceException("合同生效日期不能为空");
}
validateActiveDateWithinTerm(contract);
if (contract.getPartyList() == null || contract.getPartyList().isEmpty()) {
throw new ServiceException("至少需要维护一个合同方");
}
@@ -1000,6 +1011,7 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
&& !item.getFilePath().isBlank()))) {
throw new ServiceException("当前签订方式必须上传授权委托书附件");
}
validatePerformancePlans(contract, false);
}
private boolean canEdit(String status) {
@@ -1208,14 +1220,14 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
// payload.put("c_zw", buildCollectionFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_BODY));
// payload.put("c_attachs", buildCollectionFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_OTHER));
// payload.put("c_signAttachs", buildCollectionFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_GIST));
payload.put("c_lxPlan", contract.getPerformancePlans());
payload.put("c_lxPlan", buildCollectionPlanPayloadList(contract));
// 用印信息
Map<String, Object> seal = new LinkedHashMap<>();
seal.put("seal_isSeal", "1");
seal.put("seal_approveSame", "1");
seal.put("seal_type", contract.getSealType());
seal.put("seal_quantity", contract.getSealQuantity() == null ? "1" : String.valueOf(contract.getSealQuantity()));
seal.put("seal_date", contract.getSignDate());
seal.put("seal_date", contract.getSealDate());
payload.put("c_seal", seal);
// 签订信息
Map<String, Object> sign = new LinkedHashMap<>();
@@ -1230,6 +1242,23 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
return payload;
}
private List<Map<String, Object>> buildCollectionPlanPayloadList(ContractLaunchDto contract) {
boolean amountRequired = isPlanAmountRequired(contract.getValuationMode());
return contract.getPerformancePlans().stream().map(plan -> {
Map<String, Object> map = new LinkedHashMap<>();
map.put("lx_id", plan.getId() == null ? null : String.valueOf(plan.getId()));
map.put("lx_item", plan.getPlanMatter());
map.put("lx_condition", plan.getPlanWhere());
map.put("lx_nodeDate", plan.getPlanTime());
map.put("lx_remindDays", plan.getPlanDay() == null ? null : String.valueOf(plan.getPlanDay()));
if (amountRequired && plan.getPlanMoney() != null) {
map.put("lx_amount", plan.getPlanMoney());
}
map.put("lx_remarks", plan.getPlanDetail());
return map;
}).collect(Collectors.toList());
}
private boolean requiresAuthAttachment(String sealType) {
return "GZBSQRQZ".equals(sealType) || "HTZYZBSQRQZ".equals(sealType);
}
@@ -1339,6 +1368,80 @@ public class ContractLaunchServiceImpl implements ContractLaunchService {
return path != null && (path.startsWith("http://") || path.startsWith("https://"));
}
private void validateSignCompletion(ContractLaunchDto contract) {
if (contract.getSignDate() == null) {
throw new ServiceException("签订日期不能为空");
}
if (contract.getSealDate() == null) {
throw new ServiceException("用印时间不能为空");
}
if (contract.getActiveDate() == null) {
throw new ServiceException("合同生效日期不能为空");
}
validateActiveDateWithinTerm(contract);
}
private void validateCollectionReady(ContractLaunchDto contract) {
validateSignCompletion(contract);
validatePerformancePlans(contract, true);
}
private void validatePerformancePlans(ContractLaunchDto contract, boolean requirePlanId) {
if (contract.getPerformancePlans() == null || contract.getPerformancePlans().isEmpty()) {
throw new ServiceException("履行计划不能为空");
}
boolean amountRequired = isPlanAmountRequired(contract.getValuationMode());
for (ContractLaunchPlanDto plan : contract.getPerformancePlans()) {
if (requirePlanId && plan.getId() == null) {
throw new ServiceException("履行计划ID不能为空");
}
if (plan.getPlanMatter() == null || plan.getPlanMatter().isBlank()) {
throw new ServiceException("履行计划的履行事项不能为空");
}
if (plan.getPlanWhere() == null || plan.getPlanWhere().isBlank()) {
throw new ServiceException("履行计划的履约条件不能为空");
}
if (plan.getPlanTime() == null) {
throw new ServiceException("履行计划的节点日期不能为空");
}
if (plan.getPlanDay() == null) {
throw new ServiceException("履行计划的提前提醒天数不能为空");
}
if (amountRequired && plan.getPlanMoney() == null) {
throw new ServiceException("履行计划的款项金额不能为空");
}
}
}
private boolean isPlanAmountRequired(String valuationMode) {
return !"0".equals(valuationMode) && !"3".equals(valuationMode);
}
private void validateActiveDateWithinTerm(ContractLaunchDto contract) {
if (contract.getActiveDate() == null || !"0".equals(contract.getContractPeriodType())) {
return;
}
if (contract.getEffectiveStart() != null && contract.getActiveDate().isBefore(contract.getEffectiveStart())) {
throw new ServiceException("合同生效日期不能早于合同开始日期");
}
if (contract.getEffectiveEnd() != null && contract.getActiveDate().isAfter(contract.getEffectiveEnd())) {
throw new ServiceException("合同生效日期不能晚于合同结束日期");
}
}
@SafeVarargs
private final <T> T firstNonNull(T... values) {
if (values == null) {
return null;
}
for (T value : values) {
if (value != null) {
return value;
}
}
return null;
}
private String trim(String value) {
return value == null ? null : value.trim();
}
@@ -79,6 +79,7 @@
<result property="signedFileUrl" column="SIGNED_FILE_URL"/>
<result property="signedOfflineReason" column="SIGNED_OFFLINE_REASON"/>
<result property="signDate" column="SIGN_DATE"/>
<result property="sealDate" column="SEAL_DATE"/>
<result property="activeDate" column="ACTIVE_DATE"/>
<result property="archiveDate" column="ARCHIVE_DATE"/>
<result property="archiveKeeper" column="ARCHIVE_KEEPER"/>
@@ -184,7 +185,7 @@
EW_AMOUNT_TYPE, DJ_AMOUNT, YJ_AMOUNT, YFK_AMOUNT, BZJ_AMOUNT, BODY_SUMMARY,
CONTRACT_TEXT_FILE_NAME, CONTRACT_TEXT_FILE_PATH, CONTRACT_TEXT_FILE_TYPE, CONTRACT_TEXT_FILE_SIZE,
SIGNED_FILE_NAME, SIGNED_FILE_PATH, SIGNED_FILE_TYPE, SIGNED_FILE_SIZE, SIGNED_FILE_URL, SIGNED_OFFLINE_REASON,
SIGN_DATE, ACTIVE_DATE, ARCHIVE_DATE, ARCHIVE_KEEPER, ARCHIVE_KEEPER_UNIT,
SIGN_DATE, SEAL_DATE, ACTIVE_DATE, ARCHIVE_DATE, ARCHIVE_KEEPER, ARCHIVE_KEEPER_UNIT,
ARCHIVE_KEEPER_UNIT_CODE, INVOICE_DATE, RECEIVE_DATE, REMIND_DAYS,
INITIATOR, INITIATOR_DEPT, COMPANY_NAME, ORG_ID, QUERY_SCOPE,
CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, IS_DELETED, REMARK
@@ -262,7 +263,7 @@
TEMPLATE_FIELD_VALUES_JSON,
CONTRACT_TEXT_FILE_NAME, CONTRACT_TEXT_FILE_PATH, CONTRACT_TEXT_FILE_TYPE, CONTRACT_TEXT_FILE_SIZE,
SIGNED_FILE_NAME, SIGNED_FILE_PATH, SIGNED_FILE_TYPE, SIGNED_FILE_SIZE, SIGNED_FILE_URL, SIGNED_OFFLINE_REASON,
SIGN_DATE, ACTIVE_DATE, ARCHIVE_DATE, ARCHIVE_KEEPER, ARCHIVE_KEEPER_UNIT,
SIGN_DATE, SEAL_DATE, ACTIVE_DATE, ARCHIVE_DATE, ARCHIVE_KEEPER, ARCHIVE_KEEPER_UNIT,
ARCHIVE_KEEPER_UNIT_CODE, INVOICE_DATE, RECEIVE_DATE, REMIND_DAYS,
INITIATOR, INITIATOR_DEPT, COMPANY_NAME, ORG_ID, QUERY_SCOPE,
CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, IS_DELETED, REMARK
@@ -282,7 +283,7 @@
#{templateFieldValuesJson},
#{contractTextFileName}, #{contractTextFilePath}, #{contractTextFileType}, #{contractTextFileSize},
#{signedFileName}, #{signedFilePath}, #{signedFileType}, #{signedFileSize}, #{signedFileUrl}, #{signedOfflineReason},
#{signDate}, #{activeDate}, #{archiveDate}, #{archiveKeeper}, #{archiveKeeperUnit},
#{signDate}, #{sealDate}, #{activeDate}, #{archiveDate}, #{archiveKeeper}, #{archiveKeeperUnit},
#{archiveKeeperUnitCode}, #{invoiceDate}, #{receiveDate}, #{remindDays},
#{initiator}, #{initiatorDept}, #{companyName}, #{orgId}, #{queryScope},
#{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{isDeleted}, #{remark}
@@ -365,6 +366,7 @@
SIGNED_FILE_URL = #{signedFileUrl},
SIGNED_OFFLINE_REASON = #{signedOfflineReason},
SIGN_DATE = #{signDate},
SEAL_DATE = #{sealDate},
ACTIVE_DATE = #{activeDate},
ARCHIVE_DATE = #{archiveDate},
ARCHIVE_KEEPER = #{archiveKeeper},