功能完善
This commit is contained in:
@@ -7,7 +7,8 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
@MapperScan({
|
||||
"com.nbport.zgwl.mapper",
|
||||
"com.nbport.zgwl.partner.mapper",
|
||||
"com.nbport.zgwl.manifest.mapper"
|
||||
"com.nbport.zgwl.manifest.mapper",
|
||||
"com.nbport.zgwl.contractlaunch.mapper"
|
||||
})
|
||||
@SpringBootApplication
|
||||
public class ZgwlEndApplication {
|
||||
|
||||
+268
@@ -0,0 +1,268 @@
|
||||
package com.nbport.zgwl.contractlaunch.controller;
|
||||
|
||||
import com.nbport.zgwl.common.PageResult;
|
||||
import com.nbport.zgwl.common.R;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchApproveDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchArchiveDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchQueryDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchSealDto;
|
||||
import com.nbport.zgwl.contractlaunch.service.ContractLaunchService;
|
||||
import com.nbport.zgwl.contractlaunch.utils.ContractLaunchConstants;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import org.springframework.web.bind.annotation.DeleteMapping;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.PutMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 合同发起 Controller
|
||||
*
|
||||
* 这里除了正常 CRUD,还额外提供了几类“测试按钮”接口:
|
||||
* 1. 模拟法务审批通过 / 驳回
|
||||
* 2. 模拟合同采集
|
||||
* 3. 合同归档
|
||||
* 4. 回写签章结果
|
||||
*
|
||||
* 这些测试接口在法务系统不可用期间便于你完整演示流程,
|
||||
* 后续接入真实系统后,保留或删除都很方便。
|
||||
*/
|
||||
@RestController
|
||||
@RequiredArgsConstructor
|
||||
@RequestMapping(ContractLaunchConstants.REQUEST_PREFIX)
|
||||
public class ContractLaunchController {
|
||||
|
||||
private final ContractLaunchService contractLaunchService;
|
||||
|
||||
/**
|
||||
* 分页查询合同列表。
|
||||
*
|
||||
* 支持按合同名称、合同编号、合同类型、状态、创建时间范围过滤。
|
||||
* 返回结果附带合同方摘要、文件列表、履行计划(不含日志,列表页日志量大)。
|
||||
*
|
||||
* 对应前端功能:合同列表页
|
||||
*
|
||||
* 请求体 ContractLaunchQueryDto 字段:
|
||||
* contractName - 合同名称(模糊)
|
||||
* contractCode - 合同编号
|
||||
* contractType - 合同类型
|
||||
* status - 状态(draft/reviewing/rejected/pending_sign/signing/...)
|
||||
* dateStart - 创建时间范围-开始(yyyy-MM-dd)
|
||||
* dateEnd - 创建时间范围-结束(yyyy-MM-dd)
|
||||
*/
|
||||
@PostMapping("/list")
|
||||
public R<PageResult<ContractLaunchDto>> queryList(@RequestBody ContractLaunchQueryDto queryDto) {
|
||||
return R.success(contractLaunchService.queryPage(queryDto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询合同详情(含所有子表数据)。
|
||||
*
|
||||
* 返回合同基本信息 + 合同方列表 + 文件列表 + 履行计划 + 操作日志。
|
||||
*
|
||||
* 对应前端功能:合同详情页 / 编辑页面回显
|
||||
*/
|
||||
@GetMapping("/{id}")
|
||||
public R<ContractLaunchDto> getDetail(@PathVariable("id") Long id) {
|
||||
return R.success(contractLaunchService.getDetail(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建合同草稿。
|
||||
*
|
||||
* 流程:生成 contractSysId(CLS-xxx)和 contractCode → 保存主表 → 保存子表(合同方/文件/履行计划)→ 记录操作日志
|
||||
* 状态变为:draft(草稿)
|
||||
*
|
||||
* 必填校验项:合同名称、合同类型、合同类型编码、计价方式、币种、签订方式、合同期限类型、至少一个甲方+乙方
|
||||
*
|
||||
* 对应前端功能:新建合同 → 保存草稿
|
||||
*/
|
||||
@PostMapping
|
||||
public R<ContractLaunchDto> createDraft(@RequestBody ContractLaunchDto contract) {
|
||||
return R.success(contractLaunchService.createDraft(contract));
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑合同草稿。
|
||||
*
|
||||
* 仅 draft(草稿)或 rejected(已驳回)状态允许编辑。
|
||||
* 逻辑:先删子表旧数据,再以当前数据重新插入(替换式更新)。
|
||||
* 保留原有的 contractSysId、contractCode、创建人/创建时间 不变。
|
||||
*
|
||||
* 对应前端功能:编辑草稿 → 保存
|
||||
*/
|
||||
@PutMapping
|
||||
public R<ContractLaunchDto> updateDraft(@RequestBody ContractLaunchDto contract) {
|
||||
return R.success(contractLaunchService.updateDraft(contract));
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交法务审批。
|
||||
*
|
||||
* 状态流转:draft/rejected → reviewing
|
||||
* 调用结算平台 pushContract 接口将合同数据推送给法务系统开始审批流程。
|
||||
* 目前法务接口不可用,仅做状态变更 + 记录日志(TODO:联调时打开 settlementPushService.pushContract 调用)。
|
||||
*
|
||||
* 推送法务的报文包含:合同基本字段 + contractOpposites(相对方) + contractKxPlans(履行计划) + 附件等
|
||||
*
|
||||
* 对应前端功能:提交审批按钮
|
||||
*/
|
||||
@PostMapping("/{id}/submit")
|
||||
public R<ContractLaunchDto> submitToLaw(@PathVariable("id") Long id) {
|
||||
return R.success(contractLaunchService.submitToLaw(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 【测试按钮】模拟法务审批通过。
|
||||
*
|
||||
* 状态流转:reviewing → pending_sign(待签署)
|
||||
* 生成模拟的 lawContractCode 和 lawContractId 记录到合同上,以便后续流程使用。
|
||||
* 可在请求体中传入 approveMessage(审批意见)、lawContractCode、lawContractId 覆盖自动生成的值。
|
||||
*
|
||||
* 真实场景下,此方法应由法务系统的回调接口替代(见 lawApproveCallback)。
|
||||
*
|
||||
* 对应前端功能:测试按钮 → 模拟审批通过
|
||||
*/
|
||||
@PostMapping("/{id}/mock-approve")
|
||||
public R<ContractLaunchDto> mockApprove(@PathVariable("id") Long id,
|
||||
@RequestBody(required = false) ContractLaunchApproveDto approveDto) {
|
||||
return R.success(contractLaunchService.mockApprove(id, approveDto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 【测试按钮】模拟法务审批驳回。
|
||||
*
|
||||
* 状态流转:reviewing → rejected(已驳回)
|
||||
* 可在请求体中传入 approveMessage(驳回原因)。
|
||||
* 驳回后合同可再次编辑和提交。
|
||||
*
|
||||
* 对应前端功能:测试按钮 → 模拟驳回
|
||||
*/
|
||||
@PostMapping("/{id}/mock-reject")
|
||||
public R<ContractLaunchDto> mockReject(@PathVariable("id") Long id,
|
||||
@RequestBody(required = false) ContractLaunchApproveDto approveDto) {
|
||||
return R.success(contractLaunchService.mockReject(id, approveDto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 法务审批结果回调入口(供法务系统调用)。
|
||||
*
|
||||
* submitToLaw 时推给法务的 pushUrl 默认指向此接口:POST /contract/launch/callback/law/approve
|
||||
* 法务审批完成后,会往 pushUrl POST 审批结果。
|
||||
*
|
||||
* 当前法务接口不可用,但此回调接口已预先实现,可接受测试请求验证流程。
|
||||
* 请求体使用 Map 接收以兼容不同版本的字段名,内部通过 getFirstText 按多个 key 依次尝试提取。
|
||||
*
|
||||
* 识别合同方式:从报文中取 contractSysId 定位到本系统的合同
|
||||
* 判断通过/驳回:从 approveStatus/status/result 等多个字段名中取值判断
|
||||
*
|
||||
* 状态流转:reviewing → pending_sign(通过) / rejected(驳回)
|
||||
*
|
||||
* 对应前端功能:法务系统审批完成后自动回调(目前用法务系统暂未对接)
|
||||
*/
|
||||
@PostMapping("/callback/law/approve")
|
||||
public R<ContractLaunchDto> lawApproveCallback(@RequestBody Map<String, Object> callbackPayload) {
|
||||
return R.success(contractLaunchService.handleLawApproveCallback(callbackPayload));
|
||||
}
|
||||
|
||||
/**
|
||||
* 签署发起回调(浙江CA安全签调用)。
|
||||
*
|
||||
* 在浙江CA安全签平台创建签署合同后,回写 sealContractId 到本系统合同。
|
||||
* 状态流转:pending_sign → signing(签署中)
|
||||
*
|
||||
* 请求体 ContractLaunchSealDto 字段:
|
||||
* sealContractId - 签章平台生成的合同ID(必填)
|
||||
* sealContractStatus - 签署状态(1:签署中)
|
||||
*
|
||||
* 对应前端功能:调起浙江CA签署后,回写签章合同ID
|
||||
*/
|
||||
@PostMapping("/{id}/seal/save")
|
||||
public R<ContractLaunchDto> saveSealInfo(@PathVariable("id") Long id,
|
||||
@RequestBody ContractLaunchSealDto sealDto) {
|
||||
return R.success(contractLaunchService.saveSealInfo(id, sealDto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 签署完成回调(浙江CA安全签/线下签署完成后调用)。
|
||||
*
|
||||
* 所有签署方完成签署后,将签署完成的合同文件信息回写。
|
||||
* 状态流转:signing → pending_collect(待采集)
|
||||
*
|
||||
* 请求体 ContractLaunchSealDto 字段:
|
||||
* sealContractStatus - 签署状态(2:签署完成)
|
||||
* signedFileName - 签署完成后的文件名
|
||||
* signedFilePath - 签署文件存储路径
|
||||
* signedFileType - 文件类型
|
||||
* signedFileSize - 文件大小
|
||||
* signedOfflineReason - 线下签署原因(如果未在线签署)
|
||||
*
|
||||
* 签署文件会自动保存到 file 子表(fileCategory = "signed"),先删旧签署文件再插入新的。
|
||||
*
|
||||
* 对应前端功能:签署完成 → 回写签署结果
|
||||
*/
|
||||
@PostMapping("/{id}/seal/finish")
|
||||
public R<ContractLaunchDto> finishSeal(@PathVariable("id") Long id,
|
||||
@RequestBody ContractLaunchSealDto sealDto) {
|
||||
return R.success(contractLaunchService.markSealCompleted(id, sealDto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 【测试按钮】模拟合同采集。
|
||||
*
|
||||
* 合同签署完成后,调用数据采集 V3.0 的 collectContract 接口将合同信息推送到法务系统存档。
|
||||
* 目前法务接口不可用,仅做状态变更 + 记录日志(TODO:联调时打开 dataCollectionPushService.collectContract 调用)。
|
||||
*
|
||||
* 状态流转:pending_collect → pending_archive(待归档)
|
||||
*
|
||||
* 推送数据采集的报文包含:合同基本字段 + 用印信息(c_seal)+ 签订信息(c_sign)+ 附件等
|
||||
*
|
||||
* 对应前端功能:测试按钮 → 模拟采集
|
||||
*/
|
||||
@PostMapping("/{id}/mock-collect")
|
||||
public R<ContractLaunchDto> mockCollect(@PathVariable("id") Long id) {
|
||||
return R.success(contractLaunchService.mockCollect(id));
|
||||
}
|
||||
|
||||
/**
|
||||
* 合同归档。
|
||||
*
|
||||
* 合同全生命周期最后一步,状态变为 completed(已完成)。
|
||||
* 同时将归档信息推送到法务系统存档(TODO:联调时打开 settlementPushService.pushArchive 调用)。
|
||||
*
|
||||
* 请求体 ContractLaunchArchiveDto 字段:
|
||||
* archiveKeeper - 档案保管人手机号
|
||||
* archiveKeeperUnit - 档案保管单位名称
|
||||
* archiveKeeperUnitCode - 档案保管单位编码
|
||||
* archiveFiles - 归档附件列表
|
||||
*
|
||||
* 归档附件自动保存到 file 子表(fileCategory = "archive")。
|
||||
*
|
||||
* 对应前端功能:归档按钮 → 合同完结
|
||||
*/
|
||||
@PostMapping("/{id}/archive")
|
||||
public R<ContractLaunchDto> archive(@PathVariable("id") Long id,
|
||||
@RequestBody(required = false) ContractLaunchArchiveDto archiveDto) {
|
||||
return R.success(contractLaunchService.archive(id, archiveDto));
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除合同草稿(逻辑删除)。
|
||||
*
|
||||
* 仅 draft(草稿)或 rejected(已驳回)状态允许删除。
|
||||
* 逻辑:设置 isDeleted = 'Y',不物理删除数据。
|
||||
*
|
||||
* 对应前端功能:删除草稿按钮
|
||||
*/
|
||||
@DeleteMapping("/{id}")
|
||||
public R<String> deleteDraft(@PathVariable("id") Long id) {
|
||||
contractLaunchService.deleteDraft(id);
|
||||
return R.success("删除成功");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.nbport.zgwl.contractlaunch.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 模拟审批 / 驳回参数
|
||||
*
|
||||
* 当前法务接口不可用,通过「测试按钮」手动审批时携带此参数。
|
||||
* 真实联调后,此 DTO 可由法务回调接口的报文替代。
|
||||
*/
|
||||
@Data
|
||||
public class ContractLaunchApproveDto implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 审批意见 */
|
||||
private String approveMessage;
|
||||
|
||||
/**
|
||||
* 法务回调返回的合同编号。
|
||||
* 模拟时自动生成,真实联调时由法务系统返回。
|
||||
*/
|
||||
private String lawContractCode;
|
||||
|
||||
/**
|
||||
* 法务回调返回的合同ID。
|
||||
* 模拟时自动生成,真实联调时由法务系统返回。
|
||||
*/
|
||||
private String lawContractId;
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.nbport.zgwl.contractlaunch.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 合同归档参数
|
||||
*/
|
||||
@Data
|
||||
public class ContractLaunchArchiveDto implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 档案保管人手机号 */
|
||||
private String archiveKeeper;
|
||||
|
||||
/** 档案保管单位名称 */
|
||||
private String archiveKeeperUnit;
|
||||
|
||||
/** 档案保管单位编码 */
|
||||
private String archiveKeeperUnitCode;
|
||||
|
||||
/** 归档附件列表(纸质或电子档案材料) */
|
||||
private List<ContractLaunchFileDto> archiveFiles = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,359 @@
|
||||
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;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 合同发起主对象
|
||||
*
|
||||
* 这里尽量把前后端会直接用到的字段都放在一个 DTO 里,
|
||||
* 方便你后续排查和修改,不做过深的分层。
|
||||
*/
|
||||
@Data
|
||||
public class ContractLaunchDto implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
// ==================== 主键与编号 ====================
|
||||
|
||||
/** 主键ID */
|
||||
private Long id;
|
||||
|
||||
/** 合同系统唯一编码(本系统生成,格式 CLS-时间戳-随机数) */
|
||||
private String contractSysId;
|
||||
|
||||
/** 业务合同编号(如 MM-20260522-1234,前端可手动输入,不传则自动生成) */
|
||||
private String contractCode;
|
||||
|
||||
/** 法务系统生成的合同编号(审批通过后法务返回) */
|
||||
private String lawContractCode;
|
||||
|
||||
/** 法务系统返回的合同ID(审批通过后法务返回) */
|
||||
private String lawContractId;
|
||||
|
||||
// ==================== 合同基本信息 ====================
|
||||
|
||||
/** 合同名称 */
|
||||
private String contractName;
|
||||
|
||||
/** 合同类型中文名(如 买卖合同、服务合同) */
|
||||
private String contractType;
|
||||
|
||||
/** 合同类型编码(如 MM/GY/ZL,见文档附录字典) */
|
||||
private String contractTypeCode;
|
||||
|
||||
/** 合同来源(ECP:结算平台, DSSP:大宗平台) */
|
||||
private String contractSource;
|
||||
|
||||
/** 创建方式(template:从模板创建, manual:手动创建) */
|
||||
private String creationMode;
|
||||
|
||||
/** 选择的模板ID */
|
||||
private Long templateId;
|
||||
|
||||
/** 选择的模板编号 */
|
||||
private String templateCode;
|
||||
|
||||
/** 选择的模板名称 */
|
||||
private String templateName;
|
||||
|
||||
// ==================== 流程状态 ====================
|
||||
|
||||
/**
|
||||
* 合同状态流转:
|
||||
* draft → reviewing → (approved→pending_sign / rejected)
|
||||
* pending_sign → signing → pending_collect → pending_archive → completed
|
||||
*/
|
||||
private String status;
|
||||
|
||||
/** 审批状态(pending:待审批, approved:已通过, rejected:已驳回) */
|
||||
private String approveStatus;
|
||||
|
||||
/** 审批意见/消息 */
|
||||
private String approveMessage;
|
||||
|
||||
// ==================== 签章状态 ====================
|
||||
|
||||
/** 签章平台合同ID(浙江CA安全签创建后返回) */
|
||||
private String sealContractId;
|
||||
|
||||
/** 签章状态(1:签署中, 2:签署完成, 3:签署失败, null:未发起) */
|
||||
private Integer sealContractStatus;
|
||||
|
||||
// ==================== 金额与币种 ====================
|
||||
|
||||
/** 合同标的额(元) */
|
||||
private Double contractAmount;
|
||||
|
||||
/** 币种(RMB/USD/HKD/EUR/IDR) */
|
||||
private String currencyName;
|
||||
|
||||
/** 合同期限类型(0:固定期限, 1:无固定期限) */
|
||||
private String contractPeriodType;
|
||||
|
||||
/** 期限说明(无固定期限时必填) */
|
||||
private String periodExplain;
|
||||
|
||||
/** 合同开始日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private LocalDateTime effectiveStart;
|
||||
|
||||
/** 合同结束日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd", timezone = "GMT+8")
|
||||
private LocalDateTime effectiveEnd;
|
||||
|
||||
/** 付款方式 */
|
||||
private String paymentMethod;
|
||||
|
||||
/** 合同主要内容 */
|
||||
private String primaryContent;
|
||||
|
||||
/** 金额说明(计价方式为无金额时填写) */
|
||||
private String amountExplain;
|
||||
|
||||
/** 计价方式(0:无金额, 1:固定总价, 2:预估总价, 3:无法预估总价, 4:固定单价) */
|
||||
private String valuationMode;
|
||||
|
||||
// ==================== 签署相关 ====================
|
||||
|
||||
/** 签订方式(GZ:公章, HTZYZ:合同专用章, 等) */
|
||||
private String sealType;
|
||||
|
||||
/** 文本来源(standardText:推荐文本, exampleText:示范文本, draftBySelf:自行起草, otherText:对方文本) */
|
||||
private String textSource;
|
||||
|
||||
/** 授权方式(当签订方式为"公章/合同专用章+被授权人签字"时必填) */
|
||||
private String mandateType;
|
||||
|
||||
/** 货类 */
|
||||
private String cargoType;
|
||||
|
||||
/** 协助部门名称 */
|
||||
private String assistDepartmentName;
|
||||
|
||||
/** 执行人账号(手机号) */
|
||||
private String executorAccount;
|
||||
|
||||
/** 创建人手机号 */
|
||||
private String creatorPhone;
|
||||
|
||||
/** 二级单位合同编码 */
|
||||
private String selfCode;
|
||||
|
||||
/** 补录主合同编码(用于关联主合同,多个用逗号分割) */
|
||||
private String mainContractCode;
|
||||
|
||||
/**
|
||||
* 签约主体编码,推送法务字段 signingSubjectCode。
|
||||
* 与 orgId 分开保存,避免被当前登录人的组织ID覆盖。
|
||||
*/
|
||||
private String signingSubjectCode;
|
||||
|
||||
/**
|
||||
* 固定期间日期类型,推送法务字段 dateType:0-年,1-月,2-日
|
||||
*/
|
||||
private String dateType;
|
||||
|
||||
// ==================== 业务标识 ====================
|
||||
|
||||
/** 是否补录合同(1:补录, 2:非补录) */
|
||||
private Integer isAddit;
|
||||
|
||||
/** 签署方式(0:纸质合同, 1:电子合同,默认1) */
|
||||
private String isElectron;
|
||||
|
||||
/** 收支方向(1:付款, 2:收款, 3:收支双向, 0:无) */
|
||||
private String paymentDirection;
|
||||
|
||||
/**
|
||||
* 回调推送地址,法务审批完成后回调本系统使用。
|
||||
* 真实地址后续可以由配置文件统一生成。
|
||||
*/
|
||||
private String pushUrl;
|
||||
|
||||
/** 是否重大合同(1:是, 0:否) */
|
||||
private Integer isMajorContract;
|
||||
|
||||
/** 是否公开招标(1:是, 0:否) */
|
||||
private Integer isOpenBidding;
|
||||
|
||||
/** 是否列入当年预算(1:是, 0:否) */
|
||||
private Integer isYearBudget;
|
||||
|
||||
/** 是否共享(1:是, 0:否) */
|
||||
private String isShare;
|
||||
|
||||
/** 签约主体是否涉外(1:是, 0:否) */
|
||||
private String contractNature;
|
||||
|
||||
/** 签约主体是否涉港澳台(1:是, 0:否) */
|
||||
private String isSgat;
|
||||
|
||||
/** 是否正常 */
|
||||
private String isNormal;
|
||||
|
||||
/** 是否终止 */
|
||||
private String isTerminated;
|
||||
|
||||
/** 是否单方协议(Y/N) */
|
||||
private String isSingleAgreement;
|
||||
|
||||
/** 招标编号 */
|
||||
private String biddingNo;
|
||||
|
||||
/** 公开招标说明 */
|
||||
private String openBiddingRemark;
|
||||
|
||||
/** 签订依据说明 */
|
||||
private String contractGistRemark;
|
||||
|
||||
/**
|
||||
* 额外金额类型,多个用逗号拼接:DJ-定金,YJ-押金,YFK-预付款,BZJ-保证金
|
||||
*/
|
||||
private String ewAmountType;
|
||||
|
||||
/** 定金金额 */
|
||||
private Double djAmount;
|
||||
|
||||
/** 押金金额 */
|
||||
private Double yjAmount;
|
||||
|
||||
/** 预付款金额 */
|
||||
private Double yfkAmount;
|
||||
|
||||
/** 保证金金额 */
|
||||
private Double bzjAmount;
|
||||
|
||||
/** 正文/摘要 */
|
||||
private String bodySummary;
|
||||
|
||||
// ==================== 文件信息 ====================
|
||||
|
||||
/** 合同正文文件名 */
|
||||
private String contractTextFileName;
|
||||
|
||||
/** 合同正文文件路径 */
|
||||
private String contractTextFilePath;
|
||||
|
||||
/** 合同正文文件类型 */
|
||||
private String contractTextFileType;
|
||||
|
||||
/** 合同正文文件大小(字节) */
|
||||
private Long contractTextFileSize;
|
||||
|
||||
// ==================== 签署完成信息 ====================
|
||||
|
||||
/** 签署完成后的合同文件名 */
|
||||
private String signedFileName;
|
||||
|
||||
/** 签署完成后的合同文件路径 */
|
||||
private String signedFilePath;
|
||||
|
||||
/** 签署完成后的合同文件类型 */
|
||||
private String signedFileType;
|
||||
|
||||
/** 签署完成后的合同文件大小(字节) */
|
||||
private Long signedFileSize;
|
||||
|
||||
/** 未在线签署的原因(线下签署时填写) */
|
||||
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 activeDate;
|
||||
|
||||
/** 归档日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime archiveDate;
|
||||
|
||||
/** 档案保管人手机号 */
|
||||
private String archiveKeeper;
|
||||
|
||||
/** 档案保管单位 */
|
||||
private String archiveKeeperUnit;
|
||||
|
||||
/** 档案保管单位编码 */
|
||||
private String archiveKeeperUnitCode;
|
||||
|
||||
// ==================== 业务扩展字段(财务提醒) ====================
|
||||
|
||||
/** 开票时间(用于账单开票提醒,提前3天提醒) */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime invoiceDate;
|
||||
|
||||
/** 收款时间(用于应收账款提醒,提前3天提醒) */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime receiveDate;
|
||||
|
||||
/** 提前提醒天数 */
|
||||
private Integer remindDays;
|
||||
|
||||
// ==================== 创建信息 ====================
|
||||
|
||||
/** 发起人 */
|
||||
private String initiator;
|
||||
|
||||
/** 发起人部门 */
|
||||
private String initiatorDept;
|
||||
|
||||
/** 公司名称(当前登录人所在公司) */
|
||||
private String companyName;
|
||||
|
||||
/** 公司/组织编码 */
|
||||
private String orgId;
|
||||
|
||||
/** 查询范围(personal:个人, company:公司, admin:管理员) */
|
||||
private String queryScope;
|
||||
|
||||
/** 创建人 */
|
||||
private String createBy;
|
||||
|
||||
/** 创建时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime createTime;
|
||||
|
||||
/** 更新人 */
|
||||
private String updateBy;
|
||||
|
||||
/** 更新时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime updateTime;
|
||||
|
||||
/** 删除标记(N:未删除, Y:已删除) */
|
||||
private String isDeleted;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
|
||||
// ==================== 子表数据(非数据库字段) ====================
|
||||
|
||||
/**
|
||||
* 前端表格直接展示用的相对方摘要
|
||||
*/
|
||||
private String counterpartySummary;
|
||||
|
||||
/** 合同方列表(甲方/乙方/丙方等) */
|
||||
private List<ContractLaunchPartyDto> partyList = new ArrayList<>();
|
||||
|
||||
/** 附件文件列表(正文/签订依据/其他附件/签署文件/归档文件) */
|
||||
private List<ContractLaunchFileDto> fileList = new ArrayList<>();
|
||||
|
||||
/** 履行计划列表 */
|
||||
private List<ContractLaunchPlanDto> performancePlans = new ArrayList<>();
|
||||
|
||||
/** 操作日志列表 */
|
||||
private List<ContractLaunchLogDto> logList = new ArrayList<>();
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.nbport.zgwl.contractlaunch.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 合同文件信息
|
||||
*/
|
||||
@Data
|
||||
public class ContractLaunchFileDto implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键ID */
|
||||
private Long id;
|
||||
|
||||
/** 关联合同主表 ID */
|
||||
private Long contractId;
|
||||
|
||||
/** 文件分类:body-正文, gist-签订依据, other-其他附件, signed-签署文件, archive-归档文件 */
|
||||
private String fileCategory;
|
||||
|
||||
/** 文件名 */
|
||||
private String fileName;
|
||||
|
||||
/** 文件路径(上传到法务系统后返回的 path,或本系统存储路径) */
|
||||
private String filePath;
|
||||
|
||||
/** 文件类型(docx/pdf 等) */
|
||||
private String fileType;
|
||||
|
||||
/** 文件大小(字节) */
|
||||
private Long fileSize;
|
||||
|
||||
/** 排序号 */
|
||||
private Integer sortOrder;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 合同操作日志
|
||||
*/
|
||||
@Data
|
||||
public class ContractLaunchLogDto implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键ID */
|
||||
private Long id;
|
||||
|
||||
/** 关联合同主表 ID */
|
||||
private Long contractId;
|
||||
|
||||
/** 操作类型(save/submit/approve/reject/seal_start/seal_finish/collect/archive/delete) */
|
||||
private String actionType;
|
||||
|
||||
/** 操作名称(中文描述,如"保存草稿"、"提交法务") */
|
||||
private String actionName;
|
||||
|
||||
/** 操作状态(success/failed/pending) */
|
||||
private String actionStatus;
|
||||
|
||||
/** 操作人姓名 */
|
||||
private String operatorName;
|
||||
|
||||
/** 操作人手机号 */
|
||||
private String operatorPhone;
|
||||
|
||||
/** 操作时间 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime actionTime;
|
||||
|
||||
/** 操作内容描述 */
|
||||
private String actionContent;
|
||||
|
||||
/** 回调/操作的原始报文(JSON 文本存储,用于追溯) */
|
||||
private String callbackPayload;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
package com.nbport.zgwl.contractlaunch.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 合同方信息
|
||||
*/
|
||||
@Data
|
||||
public class ContractLaunchPartyDto implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键ID */
|
||||
private Long id;
|
||||
|
||||
/** 关联合同主表 ID */
|
||||
private Long contractId;
|
||||
|
||||
/** 角色编码(A:甲方/我方, B:乙方/相对方, C:丙方 等) */
|
||||
private String roleCode;
|
||||
|
||||
/** 角色名称(甲方/乙方/丙方) */
|
||||
private String roleName;
|
||||
|
||||
/** 排序号 */
|
||||
private Integer sortOrder;
|
||||
|
||||
/** 关联相对方主表 ID(partner 模块的 customerSysid) */
|
||||
private Long partnerId;
|
||||
|
||||
/** 法务系统的相对方ID(jtId,采集后返回) */
|
||||
private String oppositeId;
|
||||
|
||||
/** 公司全称 */
|
||||
private String companyName;
|
||||
|
||||
/** 公司类型(client/supplier/Partner/clientAndSup/other) */
|
||||
private String companyType;
|
||||
|
||||
/** 相对方性质(1:境内组织,2:境内个人,3:境外组织,4:境外个人) */
|
||||
private String oppositeCharacter;
|
||||
|
||||
/** 联系人姓名 */
|
||||
private String contactName;
|
||||
|
||||
/** 联系人电话 */
|
||||
private String contactPhone;
|
||||
|
||||
/** 联系人邮箱 */
|
||||
private String contactEmail;
|
||||
|
||||
/** 联系地址 */
|
||||
private String contactAddress;
|
||||
|
||||
/** 注册地址 */
|
||||
private String registeredAddress;
|
||||
|
||||
/** 法定代表人 */
|
||||
private String legalRepresentative;
|
||||
|
||||
/** 统一社会信用代码 */
|
||||
private String creditCode;
|
||||
|
||||
/** 开户银行 */
|
||||
private String bankName;
|
||||
|
||||
/** 银行账户 */
|
||||
private String bankAccount;
|
||||
|
||||
/** 自然人证件类型 */
|
||||
private String naturalPersonIdType;
|
||||
|
||||
/** 自然人证件号码 */
|
||||
private String naturalPersonIdNumber;
|
||||
|
||||
/** 是否集团内(Y/N) */
|
||||
private String isGroupInternal;
|
||||
|
||||
/** 是否涉港澳台(Y/N) */
|
||||
private String isHongKongMacaoTaiwan;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
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;
|
||||
|
||||
/**
|
||||
* 履行计划
|
||||
*
|
||||
* 对应结算平台推送合同接口的 contractKxPlans 字段。
|
||||
* 与法务接口文档中的款项计划一一映射。
|
||||
*/
|
||||
@Data
|
||||
public class ContractLaunchPlanDto implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 主键ID */
|
||||
private Long id;
|
||||
|
||||
/** 关联合同主表 ID */
|
||||
private Long contractId;
|
||||
|
||||
/** 履行事项(如:第一笔付款) */
|
||||
private String planMatter;
|
||||
|
||||
/** 履约条件(如:达到xx条件) */
|
||||
private String planWhere;
|
||||
|
||||
/** 节点日期 */
|
||||
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
private LocalDateTime planTime;
|
||||
|
||||
/** 提前提醒天数 */
|
||||
private Integer planDay;
|
||||
|
||||
/** 款项金额 */
|
||||
private Double planMoney;
|
||||
|
||||
/**
|
||||
* 所属主体编码,推送法务字段 planSubjectCode。
|
||||
*/
|
||||
private String planSubjectCode;
|
||||
|
||||
/**
|
||||
* 所属主体名称,推送法务字段 planSubjectName。
|
||||
*/
|
||||
private String planSubjectName;
|
||||
|
||||
/** 备注 */
|
||||
private String planDetail;
|
||||
|
||||
/** 履行状态(0:待履行, 1:已履行, 2:逾期) */
|
||||
private String planStatus;
|
||||
|
||||
/** 备注 */
|
||||
private String remark;
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.nbport.zgwl.contractlaunch.dto;
|
||||
|
||||
import com.nbport.zgwl.dto.BasePageDto;
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 合同发起列表查询参数
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
public class ContractLaunchQueryDto extends BasePageDto implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 合同名称(模糊搜索) */
|
||||
private String contractName;
|
||||
|
||||
/** 合同编号 */
|
||||
private String contractCode;
|
||||
|
||||
/** 合同类型 */
|
||||
private String contractType;
|
||||
|
||||
/** 状态(draft/reviewing/rejected/pending_sign/signing/pending_collect/pending_archive/completed) */
|
||||
private String status;
|
||||
|
||||
/** 创建时间范围-开始 yyyy-MM-dd */
|
||||
private String dateStart;
|
||||
|
||||
/** 创建时间范围-结束 yyyy-MM-dd */
|
||||
private String dateEnd;
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package com.nbport.zgwl.contractlaunch.dto;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 签章回写参数
|
||||
*
|
||||
* 签署完成后,浙江CA安全签平台通过回调通知我方,
|
||||
* 我方把签署结果回写到合同的 seal_* 字段。
|
||||
*/
|
||||
@Data
|
||||
public class ContractLaunchSealDto implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 签章平台生成的合同ID(用于后续查询签署进度) */
|
||||
private String sealContractId;
|
||||
|
||||
/** 签章状态(1:签署中, 2:签署完成, 3:签署失败) */
|
||||
private Integer sealContractStatus;
|
||||
|
||||
/** 签署完成后的合同文件名 */
|
||||
private String signedFileName;
|
||||
|
||||
/** 签署完成后的合同文件路径(我方存储) */
|
||||
private String signedFilePath;
|
||||
|
||||
/** 签署完成后的合同文件类型 */
|
||||
private String signedFileType;
|
||||
|
||||
/** 签署完成后的合同文件大小 */
|
||||
private Long signedFileSize;
|
||||
|
||||
/** 未在线签署的原因(线下签署时填写) */
|
||||
private String signedOfflineReason;
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
package com.nbport.zgwl.contractlaunch.mapper;
|
||||
|
||||
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchFileDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchLogDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchPartyDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchPlanDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchQueryDto;
|
||||
import org.apache.ibatis.annotations.Param;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public interface ContractLaunchMapper {
|
||||
|
||||
/** 获取主表序列(Oracle 主键生成) */
|
||||
Long selectMainSeqNextVal();
|
||||
|
||||
/** 获取合同方表序列 */
|
||||
Long selectPartySeqNextVal();
|
||||
|
||||
/** 获取文件表序列 */
|
||||
Long selectFileSeqNextVal();
|
||||
|
||||
/** 获取履行计划表序列 */
|
||||
Long selectPlanSeqNextVal();
|
||||
|
||||
/** 获取日志表序列 */
|
||||
Long selectLogSeqNextVal();
|
||||
|
||||
/** 分页查询合同列表 */
|
||||
IPage<ContractLaunchDto> selectContractPage(Page<ContractLaunchDto> page, @Param("query") ContractLaunchQueryDto queryDto);
|
||||
|
||||
/** 根据主键查询合同 */
|
||||
ContractLaunchDto selectContractById(@Param("id") Long id);
|
||||
|
||||
/** 根据 contractSysId 查询合同(法务回调时用于定位) */
|
||||
ContractLaunchDto selectContractByContractSysId(@Param("contractSysId") String contractSysId);
|
||||
|
||||
/** 新增合同 */
|
||||
int insertContract(ContractLaunchDto contract);
|
||||
|
||||
/** 修改合同 */
|
||||
int updateContract(ContractLaunchDto contract);
|
||||
|
||||
/** 逻辑删除合同 */
|
||||
int deleteContract(@Param("id") Long id, @Param("updateBy") String updateBy);
|
||||
|
||||
/** 批量插入合同方 */
|
||||
int batchInsertParty(@Param("list") List<ContractLaunchPartyDto> list,
|
||||
@Param("createBy") String createBy,
|
||||
@Param("updateBy") String updateBy);
|
||||
|
||||
/** 批量插入文件 */
|
||||
int batchInsertFile(@Param("list") List<ContractLaunchFileDto> list,
|
||||
@Param("createBy") String createBy,
|
||||
@Param("updateBy") String updateBy);
|
||||
|
||||
/** 批量插入履行计划 */
|
||||
int batchInsertPlan(@Param("list") List<ContractLaunchPlanDto> list,
|
||||
@Param("createBy") String createBy,
|
||||
@Param("updateBy") String updateBy);
|
||||
|
||||
/** 插入单条操作日志 */
|
||||
int insertLog(ContractLaunchLogDto logDto);
|
||||
|
||||
/** 删除合同下的所有合同方(逻辑删除) */
|
||||
int deletePartyByContractId(@Param("contractId") Long contractId,
|
||||
@Param("updateBy") String updateBy);
|
||||
|
||||
/** 删除合同下的所有文件(逻辑删除) */
|
||||
int deleteFileByContractId(@Param("contractId") Long contractId,
|
||||
@Param("updateBy") String updateBy);
|
||||
|
||||
/** 按分类删除合同下的文件(如重新上传正文时只删正文,不删其他附件) */
|
||||
int deleteFileByContractIdAndCategory(@Param("contractId") Long contractId,
|
||||
@Param("fileCategory") String fileCategory,
|
||||
@Param("updateBy") String updateBy);
|
||||
|
||||
/** 删除合同下的所有履行计划(逻辑删除) */
|
||||
int deletePlanByContractId(@Param("contractId") Long contractId,
|
||||
@Param("updateBy") String updateBy);
|
||||
|
||||
/** 批量查询合同方(按 contractIds) */
|
||||
List<ContractLaunchPartyDto> selectPartyByContractIds(@Param("contractIds") List<Long> contractIds);
|
||||
|
||||
/** 批量查询文件(按 contractIds) */
|
||||
List<ContractLaunchFileDto> selectFileByContractIds(@Param("contractIds") List<Long> contractIds);
|
||||
|
||||
/** 批量查询履行计划(按 contractIds) */
|
||||
List<ContractLaunchPlanDto> selectPlanByContractIds(@Param("contractIds") List<Long> contractIds);
|
||||
|
||||
/** 批量查询操作日志(按 contractIds) */
|
||||
List<ContractLaunchLogDto> selectLogByContractIds(@Param("contractIds") List<Long> contractIds);
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
package com.nbport.zgwl.contractlaunch.service;
|
||||
|
||||
import com.nbport.zgwl.common.PageResult;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchApproveDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchArchiveDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchQueryDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchSealDto;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public interface ContractLaunchService {
|
||||
|
||||
/** 分页查询合同列表 */
|
||||
PageResult<ContractLaunchDto> queryPage(ContractLaunchQueryDto queryDto);
|
||||
|
||||
/** 查询合同详情(含合同方/文件/履行计划/日志) */
|
||||
ContractLaunchDto getDetail(Long id);
|
||||
|
||||
/** 创建合同草稿 */
|
||||
ContractLaunchDto createDraft(ContractLaunchDto contract);
|
||||
|
||||
/** 编辑合同草稿 */
|
||||
ContractLaunchDto updateDraft(ContractLaunchDto contract);
|
||||
|
||||
/** 提交法务审批(调用结算平台 pushContract 接口) */
|
||||
ContractLaunchDto submitToLaw(Long id);
|
||||
|
||||
/** 模拟审批通过(测试按钮,TODO:替换为真实法务回调) */
|
||||
ContractLaunchDto mockApprove(Long id, ContractLaunchApproveDto approveDto);
|
||||
|
||||
/** 模拟审批驳回(测试按钮,TODO:替换为真实法务回调) */
|
||||
ContractLaunchDto mockReject(Long id, ContractLaunchApproveDto approveDto);
|
||||
|
||||
/** 接收法务审批回调(处理审批结果,更新合同状态) */
|
||||
ContractLaunchDto handleLawApproveCallback(Map<String, Object> callbackPayload);
|
||||
|
||||
/** 回写签章信息(签署发起时调用,记录 sealContractId) */
|
||||
ContractLaunchDto saveSealInfo(Long id, ContractLaunchSealDto sealDto);
|
||||
|
||||
/** 签署完成回调(回写签署文件路径,状态变更为待采集) */
|
||||
ContractLaunchDto markSealCompleted(Long id, ContractLaunchSealDto sealDto);
|
||||
|
||||
/** 模拟合同采集(调用数据采集 collectContract 接口,TODO:替换为真实调用) */
|
||||
ContractLaunchDto mockCollect(Long id);
|
||||
|
||||
/** 合同归档(状态变更为已完成,TODO:同时推送归档到法务) */
|
||||
ContractLaunchDto archive(Long id, ContractLaunchArchiveDto archiveDto);
|
||||
|
||||
/** 删除草稿(仅 draft/rejected 状态允许) */
|
||||
void deleteDraft(Long id);
|
||||
}
|
||||
@@ -0,0 +1,937 @@
|
||||
package com.nbport.zgwl.contractlaunch.service;
|
||||
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
import com.nbport.zgwl.common.PageResult;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchApproveDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchArchiveDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchFileDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchLogDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchPartyDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchPlanDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchQueryDto;
|
||||
import com.nbport.zgwl.contractlaunch.dto.ContractLaunchSealDto;
|
||||
import com.nbport.zgwl.contractlaunch.mapper.ContractLaunchMapper;
|
||||
import com.nbport.zgwl.contractlaunch.utils.ContractLaunchCodeUtils;
|
||||
import com.nbport.zgwl.contractlaunch.utils.ContractLaunchConstants;
|
||||
import com.nbport.zgwl.contractpush.dto.PushPayloadDTO;
|
||||
import com.nbport.zgwl.contractpush.service.DataCollectionPushService;
|
||||
import com.nbport.zgwl.contractpush.service.SettlementPushService;
|
||||
import com.nbport.zgwl.entity.SysUserEntity;
|
||||
import com.nbport.zgwl.exception.ServiceException;
|
||||
import com.nbport.zgwl.utils.AdminSecurityManage;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 合同发起主服务
|
||||
*
|
||||
* 这里尽量把核心流程都写在一个 Service 里,
|
||||
* 方便你后续自己看和改,不额外再拆很多 handler。
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
@RequiredArgsConstructor
|
||||
public class ContractLaunchServiceImpl implements ContractLaunchService {
|
||||
|
||||
private final ContractLaunchMapper contractLaunchMapper;
|
||||
private final AdminSecurityManage adminSecurityManage;
|
||||
private final SettlementPushService settlementPushService;
|
||||
private final DataCollectionPushService dataCollectionPushService;
|
||||
|
||||
/** 分页查询,附带合同方/文件/履行计划(列表页不查日志) */
|
||||
@Override
|
||||
public PageResult<ContractLaunchDto> queryPage(ContractLaunchQueryDto queryDto) {
|
||||
Page<ContractLaunchDto> page = new Page<>(queryDto.getPageNo(), queryDto.getPageSize());
|
||||
Page<ContractLaunchDto> resultPage = (Page<ContractLaunchDto>) contractLaunchMapper.selectContractPage(page, queryDto);
|
||||
PageResult<ContractLaunchDto> pageResult = new PageResult<>(resultPage);
|
||||
fillChildren(pageResult.getData(), false);
|
||||
return pageResult;
|
||||
}
|
||||
|
||||
/** 查询详情,含日志 */
|
||||
@Override
|
||||
public ContractLaunchDto getDetail(Long id) {
|
||||
ContractLaunchDto contract = contractLaunchMapper.selectContractById(id);
|
||||
if (contract == null) {
|
||||
throw new ServiceException("合同不存在");
|
||||
}
|
||||
fillChildren(Collections.singletonList(contract), true);
|
||||
return contract;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建合同草稿。
|
||||
*
|
||||
* 完整流程:
|
||||
* 1. 获取当前登录用户信息
|
||||
* 2. 数据清洗(normalizeContract:去空格、补默认值)
|
||||
* 3. 数据校验(validateDraft:必填项检查)
|
||||
* 4. 生成主键ID 和 contractSysId(CLS-时间戳)、contractCode(类型编码-日期-随机数)
|
||||
* 5. 填充创建人/创建时间/公司/部门/状态 draft
|
||||
* 6. 保存主表 + 子表(合同方/文件/履行计划)
|
||||
* 7. 记录操作日志
|
||||
*
|
||||
* 注意:此时仅在本系统保存,未推送到法务系统。
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ContractLaunchDto createDraft(ContractLaunchDto contract) {
|
||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||
normalizeContract(contract);
|
||||
validateDraft(contract);
|
||||
|
||||
LocalDateTime now = LocalDateTime.now();
|
||||
contract.setId(contractLaunchMapper.selectMainSeqNextVal());
|
||||
contract.setContractSysId(ContractLaunchCodeUtils.buildContractSysId());
|
||||
if (contract.getContractCode() == null || contract.getContractCode().isBlank()) {
|
||||
contract.setContractCode(ContractLaunchCodeUtils.buildContractCode(contract.getContractTypeCode()));
|
||||
}
|
||||
contract.setContractSource(contract.getContractSource() == null || contract.getContractSource().isBlank() ? "ECP" : contract.getContractSource());
|
||||
contract.setStatus(ContractLaunchConstants.STATUS_DRAFT);
|
||||
contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_PENDING);
|
||||
contract.setInitiator(currentUser.getUsername());
|
||||
contract.setInitiatorDept(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getOrgName());
|
||||
contract.setCompanyName(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getOrgName());
|
||||
contract.setOrgId(currentUser.getSysOrgEntity() == null ? "" : currentUser.getSysOrgEntity().getId());
|
||||
contract.setCreatorPhone(currentUser.getMobilePhone());
|
||||
contract.setCreateBy(currentUser.getUsername());
|
||||
contract.setCreateTime(now);
|
||||
contract.setUpdateBy(currentUser.getUsername());
|
||||
contract.setUpdateTime(now);
|
||||
contract.setIsDeleted(ContractLaunchConstants.IS_DELETED_NO);
|
||||
contract.setQueryScope("personal");
|
||||
contractLaunchMapper.insertContract(contract);
|
||||
saveChildren(contract, currentUser.getUsername());
|
||||
insertLog(contract.getId(), ContractLaunchConstants.ACTION_SAVE, "保存草稿", ContractLaunchConstants.ACTION_STATUS_SUCCESS, "合同草稿创建成功", null, currentUser);
|
||||
return getDetail(contract.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 编辑合同草稿。
|
||||
*
|
||||
* 仅 draft(草稿)或 rejected(已驳回)可编辑。
|
||||
* 采用替换式更新:先删子表(合同方/文件/履行计划)旧数据,再以当前数据重新插入。
|
||||
* 保留以下字段不变:contractSysId、contractCode、lawContractCode、lawContractId、
|
||||
* 状态、审批状态、发起人、公司、orgId、创建人/创建时间。
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ContractLaunchDto updateDraft(ContractLaunchDto contract) {
|
||||
if (contract.getId() == null) {
|
||||
throw new ServiceException("修改时 id 不能为空");
|
||||
}
|
||||
ContractLaunchDto dbContract = getDetail(contract.getId());
|
||||
if (!canEdit(dbContract.getStatus())) {
|
||||
throw new ServiceException("当前状态不允许编辑");
|
||||
}
|
||||
|
||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||
normalizeContract(contract);
|
||||
validateDraft(contract);
|
||||
contract.setContractSysId(dbContract.getContractSysId());
|
||||
contract.setContractCode(dbContract.getContractCode());
|
||||
contract.setLawContractCode(dbContract.getLawContractCode());
|
||||
contract.setLawContractId(dbContract.getLawContractId());
|
||||
contract.setStatus(dbContract.getStatus());
|
||||
contract.setApproveStatus(dbContract.getApproveStatus());
|
||||
contract.setInitiator(dbContract.getInitiator());
|
||||
contract.setInitiatorDept(dbContract.getInitiatorDept());
|
||||
contract.setCompanyName(dbContract.getCompanyName());
|
||||
contract.setOrgId(dbContract.getOrgId());
|
||||
contract.setCreatorPhone(dbContract.getCreatorPhone());
|
||||
contract.setCreateBy(dbContract.getCreateBy());
|
||||
contract.setCreateTime(dbContract.getCreateTime());
|
||||
contract.setUpdateBy(currentUser.getUsername());
|
||||
contract.setUpdateTime(LocalDateTime.now());
|
||||
contract.setIsDeleted(ContractLaunchConstants.IS_DELETED_NO);
|
||||
contractLaunchMapper.updateContract(contract);
|
||||
replaceChildren(contract, currentUser.getUsername());
|
||||
insertLog(contract.getId(), ContractLaunchConstants.ACTION_SAVE, "编辑草稿", ContractLaunchConstants.ACTION_STATUS_SUCCESS, "合同草稿修改成功", null, currentUser);
|
||||
return getDetail(contract.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 提交法务审批。
|
||||
*
|
||||
* 状态流转:draft/rejected → reviewing(待审批)
|
||||
*
|
||||
* 主要做两件事:
|
||||
* 1. 更新合同状态为 reviewing
|
||||
* 2. 构建结算平台 pushContract 接口的完整报文(含合同方、履行计划、附件等)
|
||||
* 3. 记录提交日志(日志中保存了完整的推送报文,方便排查)
|
||||
*
|
||||
* TODO(真实联调时打开):
|
||||
* PushPayloadDTO requestDTO = new PushPayloadDTO();
|
||||
* requestDTO.setPayload(settlementPayload);
|
||||
* settlementPushService.pushContract(requestDTO);
|
||||
*
|
||||
* 法务审批完成后会通过 pushUrl 回调本系统的 /callback/law/approve 接口。
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ContractLaunchDto submitToLaw(Long id) {
|
||||
ContractLaunchDto contract = getDetail(id);
|
||||
if (!canSubmit(contract.getStatus())) {
|
||||
throw new ServiceException("当前状态不允许提交法务");
|
||||
}
|
||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||
contract.setStatus(ContractLaunchConstants.STATUS_REVIEWING);
|
||||
contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_PENDING);
|
||||
contract.setApproveMessage("已提交法务,等待审批");
|
||||
contract.setUpdateBy(currentUser.getUsername());
|
||||
contract.setUpdateTime(LocalDateTime.now());
|
||||
contractLaunchMapper.updateContract(contract);
|
||||
|
||||
Map<String, Object> settlementPayload = buildSettlementPushPayload(contract);
|
||||
insertLog(id, ContractLaunchConstants.ACTION_SUBMIT, "提交法务", ContractLaunchConstants.ACTION_STATUS_PENDING, "合同已提交法务接口,当前先保留 mock 流程", settlementPayload, currentUser);
|
||||
|
||||
// TODO: 法务接口当前不可用,真实联调时打开下面调用即可
|
||||
// PushPayloadDTO requestDTO = new PushPayloadDTO();
|
||||
// requestDTO.setPayload(settlementPayload);
|
||||
// Map<String, Object> response = settlementPushService.pushContract(requestDTO);
|
||||
|
||||
return getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【测试按钮】模拟法务审批通过。
|
||||
*
|
||||
* 状态流转:reviewing → pending_sign(待签署)
|
||||
*
|
||||
* 模拟法务系统返回 lawContractCode 和 lawContractId,供后续签署流程使用。
|
||||
* 如果 approveDto 中传入了值则使用传入值,否则自动生成模拟值:
|
||||
* - lawContractCode = "LAW-" + 合同类型编码-日期-随机数
|
||||
* - lawContractId = "LAWID-" + 合同ID
|
||||
*
|
||||
* 真实场景下此逻辑由法务回调接口 handleLawApproveCallback 替代。
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ContractLaunchDto mockApprove(Long id, ContractLaunchApproveDto approveDto) {
|
||||
ContractLaunchDto contract = getDetail(id);
|
||||
if (!ContractLaunchConstants.STATUS_REVIEWING.equals(contract.getStatus())) {
|
||||
throw new ServiceException("仅审批中的合同可模拟通过");
|
||||
}
|
||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||
contract.setStatus(ContractLaunchConstants.STATUS_PENDING_SIGN);
|
||||
contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_APPROVED);
|
||||
contract.setApproveMessage(approveDto == null || approveDto.getApproveMessage() == null || approveDto.getApproveMessage().isBlank()
|
||||
? "法务审批通过(测试按钮模拟)"
|
||||
: approveDto.getApproveMessage());
|
||||
contract.setLawContractCode(approveDto == null || approveDto.getLawContractCode() == null || approveDto.getLawContractCode().isBlank()
|
||||
? "LAW-" + ContractLaunchCodeUtils.buildContractCode(contract.getContractTypeCode())
|
||||
: approveDto.getLawContractCode());
|
||||
contract.setLawContractId(approveDto == null || approveDto.getLawContractId() == null || approveDto.getLawContractId().isBlank()
|
||||
? "LAWID-" + id
|
||||
: approveDto.getLawContractId());
|
||||
contract.setUpdateBy(currentUser.getUsername());
|
||||
contract.setUpdateTime(LocalDateTime.now());
|
||||
contractLaunchMapper.updateContract(contract);
|
||||
insertLog(id, ContractLaunchConstants.ACTION_APPROVE, "模拟审批通过", ContractLaunchConstants.ACTION_STATUS_SUCCESS, contract.getApproveMessage(), approveDto, currentUser);
|
||||
return getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【测试按钮】模拟法务审批驳回。
|
||||
*
|
||||
* 状态流转:reviewing → rejected(已驳回)
|
||||
* 驳回后合同回到草稿状态,可以再次编辑后重新提交。
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ContractLaunchDto mockReject(Long id, ContractLaunchApproveDto approveDto) {
|
||||
ContractLaunchDto contract = getDetail(id);
|
||||
if (!ContractLaunchConstants.STATUS_REVIEWING.equals(contract.getStatus())) {
|
||||
throw new ServiceException("仅审批中的合同可模拟驳回");
|
||||
}
|
||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||
contract.setStatus(ContractLaunchConstants.STATUS_REJECTED);
|
||||
contract.setApproveStatus(ContractLaunchConstants.APPROVE_STATUS_REJECTED);
|
||||
contract.setApproveMessage(approveDto == null || approveDto.getApproveMessage() == null || approveDto.getApproveMessage().isBlank()
|
||||
? "法务审批驳回(测试按钮模拟)"
|
||||
: approveDto.getApproveMessage());
|
||||
contract.setUpdateBy(currentUser.getUsername());
|
||||
contract.setUpdateTime(LocalDateTime.now());
|
||||
contractLaunchMapper.updateContract(contract);
|
||||
insertLog(id, ContractLaunchConstants.ACTION_REJECT, "模拟审批驳回", ContractLaunchConstants.ACTION_STATUS_SUCCESS, contract.getApproveMessage(), approveDto, currentUser);
|
||||
return getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 接收法务审批回调。
|
||||
*
|
||||
* 法务系统审批完成后,通过 pushUrl POST 审批结果到本接口。
|
||||
*
|
||||
* 处理逻辑:
|
||||
* 1. 从回调报文中提取 contractSysId 定位到本系统合同
|
||||
* 2. 判断审批结果(通过/驳回)
|
||||
* - 通过:status → pending_sign(待签署),记录法务返回的合同编号和合同ID
|
||||
* - 驳回:status → rejected(已驳回),记录驳回原因
|
||||
* 3. 记录操作日志
|
||||
*
|
||||
* 兼容设计:
|
||||
* - 使用 getFirstText 按多个 key 依次尝试提取字段(如 approveStatus/status/result)
|
||||
* - 审批通过状态兼容:1/true/success/approved/pass/agree/审批通过
|
||||
* - 合同编号兼容:lawContractCode/contractCode/htCode/code
|
||||
* - 合同ID兼容:lawContractId/contractId/id/businessId
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ContractLaunchDto handleLawApproveCallback(Map<String, Object> callbackPayload) {
|
||||
ContractLaunchDto contract = getContractByLawCallback(callbackPayload);
|
||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||
|
||||
boolean approved = isLawCallbackApproved(callbackPayload);
|
||||
contract.setApproveStatus(approved
|
||||
? ContractLaunchConstants.APPROVE_STATUS_APPROVED
|
||||
: ContractLaunchConstants.APPROVE_STATUS_REJECTED);
|
||||
contract.setStatus(approved
|
||||
? ContractLaunchConstants.STATUS_PENDING_SIGN
|
||||
: ContractLaunchConstants.STATUS_REJECTED);
|
||||
contract.setApproveMessage(getFirstText(callbackPayload,
|
||||
"approveMessage", "message", "msg", "opinion", "remark"));
|
||||
|
||||
String lawContractCode = getFirstText(callbackPayload,
|
||||
"lawContractCode", "contractCode", "htCode", "code");
|
||||
String lawContractId = getFirstText(callbackPayload,
|
||||
"lawContractId", "contractId", "id", "businessId");
|
||||
if (lawContractCode != null && !lawContractCode.isBlank()) {
|
||||
contract.setLawContractCode(lawContractCode);
|
||||
}
|
||||
if (lawContractId != null && !lawContractId.isBlank()) {
|
||||
contract.setLawContractId(lawContractId);
|
||||
}
|
||||
|
||||
contract.setUpdateBy(currentUser.getUsername());
|
||||
contract.setUpdateTime(LocalDateTime.now());
|
||||
contractLaunchMapper.updateContract(contract);
|
||||
insertLog(
|
||||
contract.getId(),
|
||||
approved ? ContractLaunchConstants.ACTION_APPROVE : ContractLaunchConstants.ACTION_REJECT,
|
||||
approved ? "法务审批回调通过" : "法务审批回调驳回",
|
||||
ContractLaunchConstants.ACTION_STATUS_SUCCESS,
|
||||
contract.getApproveMessage(),
|
||||
callbackPayload,
|
||||
currentUser
|
||||
);
|
||||
return getDetail(contract.getId());
|
||||
}
|
||||
|
||||
/**
|
||||
* 回写签章信息(签署发起时调用)。
|
||||
*
|
||||
* 浙江CA安全签平台创建签署合同后,回调此方法回写 sealContractId。
|
||||
* 状态流转:pending_sign → signing(签署中)
|
||||
*
|
||||
* sealContractId 由浙江CA安全签平台生成,后续通过此 ID 查询签署进度。
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ContractLaunchDto saveSealInfo(Long id, ContractLaunchSealDto sealDto) {
|
||||
ContractLaunchDto contract = getDetail(id);
|
||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||
contract.setSealContractId(sealDto.getSealContractId());
|
||||
contract.setSealContractStatus(sealDto.getSealContractStatus());
|
||||
contract.setStatus(ContractLaunchConstants.STATUS_SIGNING);
|
||||
contract.setUpdateBy(currentUser.getUsername());
|
||||
contract.setUpdateTime(LocalDateTime.now());
|
||||
contractLaunchMapper.updateContract(contract);
|
||||
insertLog(id, ContractLaunchConstants.ACTION_SEAL_START, "开始签署", ContractLaunchConstants.ACTION_STATUS_SUCCESS, "签章平台合同已创建", sealDto, currentUser);
|
||||
return getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 签署完成回调。
|
||||
*
|
||||
* 所有签署方签署完成后(或在浙江CA签署完成、或线下签署后手动上传),
|
||||
* 回写签署完成的合同文件信息。
|
||||
*
|
||||
* 状态流转:signing → pending_collect(待采集)
|
||||
*
|
||||
* 执行步骤:
|
||||
* 1. 回写 signedFileName/signedFilePath/signedFileType/signedFileSize
|
||||
* 2. 如果有线下签署原因(signedOfflineReason),一并保存
|
||||
* 3. 将签署文件保存到 file 子表(fileCategory = "signed")
|
||||
* 4. 记录操作日志
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ContractLaunchDto markSealCompleted(Long id, ContractLaunchSealDto sealDto) {
|
||||
ContractLaunchDto contract = getDetail(id);
|
||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||
contract.setSealContractId(sealDto.getSealContractId() == null || sealDto.getSealContractId().isBlank() ? contract.getSealContractId() : sealDto.getSealContractId());
|
||||
contract.setSealContractStatus(sealDto.getSealContractStatus());
|
||||
contract.setSignedFileName(sealDto.getSignedFileName());
|
||||
contract.setSignedFilePath(sealDto.getSignedFilePath());
|
||||
contract.setSignedFileType(sealDto.getSignedFileType());
|
||||
contract.setSignedFileSize(sealDto.getSignedFileSize());
|
||||
contract.setSignedOfflineReason(sealDto.getSignedOfflineReason());
|
||||
contract.setStatus(ContractLaunchConstants.STATUS_PENDING_COLLECT);
|
||||
contract.setUpdateBy(currentUser.getUsername());
|
||||
contract.setUpdateTime(LocalDateTime.now());
|
||||
contractLaunchMapper.updateContract(contract);
|
||||
saveSignedFile(id, sealDto, currentUser.getUsername());
|
||||
insertLog(id, ContractLaunchConstants.ACTION_SEAL_FINISH, "签署完成", ContractLaunchConstants.ACTION_STATUS_SUCCESS, "合同签署已完成,待采集", sealDto, currentUser);
|
||||
return getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 【测试按钮】模拟合同采集。
|
||||
*
|
||||
* 合同签署完成后,将合同最新信息(含用印信息和签订信息)推送到法务系统。
|
||||
*
|
||||
* 状态流转:pending_collect → pending_archive(待归档)
|
||||
*
|
||||
* 构建数据采集 V3.0 collectContract 接口的报文,包含:
|
||||
* - 合同基本字段(c_name, c_code, c_type 等)
|
||||
* - 用印信息 c_seal(签章类型、签章日期等)
|
||||
* - 签订信息 c_sign(签署日期、生效日期、签署附件等)
|
||||
* - 履行计划 c_lxPlan
|
||||
* - 附件(正文 c_zw / 其他 c_attachs / 签署文件 c_signAttachs)
|
||||
*
|
||||
* TODO(真实联调时打开):
|
||||
* PushPayloadDTO requestDTO = new PushPayloadDTO();
|
||||
* requestDTO.setPayload(payload);
|
||||
* dataCollectionPushService.collectContract(requestDTO);
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ContractLaunchDto mockCollect(Long id) {
|
||||
ContractLaunchDto contract = getDetail(id);
|
||||
if (!ContractLaunchConstants.STATUS_PENDING_COLLECT.equals(contract.getStatus())) {
|
||||
throw new ServiceException("当前状态不允许执行采集");
|
||||
}
|
||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||
Map<String, Object> payload = buildDataCollectionContractPayload(contract);
|
||||
insertLog(id, ContractLaunchConstants.ACTION_COLLECT, "模拟合同采集", ContractLaunchConstants.ACTION_STATUS_PENDING, "合同采集接口当前先注释,使用测试按钮流转", payload, currentUser);
|
||||
|
||||
// TODO: 法务接口当前不可用,真实联调时打开下面调用即可
|
||||
// PushPayloadDTO requestDTO = new PushPayloadDTO();
|
||||
// requestDTO.setPayload(payload);
|
||||
// dataCollectionPushService.collectContract(requestDTO);
|
||||
|
||||
contract.setStatus(ContractLaunchConstants.STATUS_PENDING_ARCHIVE);
|
||||
contract.setUpdateBy(currentUser.getUsername());
|
||||
contract.setUpdateTime(LocalDateTime.now());
|
||||
contractLaunchMapper.updateContract(contract);
|
||||
return getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 合同归档。
|
||||
*
|
||||
* 合同全生命周期最后一步。将归档信息(保管人、保管单位、归档附件)保存到合同,
|
||||
* 同时推送到法务系统存档。
|
||||
*
|
||||
* 状态流转:pending_archive → completed(已完成)
|
||||
*
|
||||
* 执行步骤:
|
||||
* 1. 填写归档日期、保管人信息
|
||||
* 2. 保存归档附件到 file 子表(fileCategory = "archive")
|
||||
* 3. 构建归档报文 pushArchive 接口的 payload
|
||||
* 4. 记录操作日志
|
||||
*
|
||||
* TODO(真实联调时打开):
|
||||
* settlementPushService.pushArchive(requestDTO)
|
||||
* dataCollectionPushService.collectContractArchive(requestDTO)
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public ContractLaunchDto archive(Long id, ContractLaunchArchiveDto archiveDto) {
|
||||
ContractLaunchDto contract = getDetail(id);
|
||||
if (!ContractLaunchConstants.STATUS_PENDING_ARCHIVE.equals(contract.getStatus())) {
|
||||
throw new ServiceException("当前状态不允许归档");
|
||||
}
|
||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||
contract.setArchiveDate(LocalDateTime.now());
|
||||
contract.setArchiveKeeper(archiveDto == null ? null : archiveDto.getArchiveKeeper());
|
||||
contract.setArchiveKeeperUnit(archiveDto == null ? null : archiveDto.getArchiveKeeperUnit());
|
||||
contract.setArchiveKeeperUnitCode(archiveDto == null ? null : archiveDto.getArchiveKeeperUnitCode());
|
||||
contract.setStatus(ContractLaunchConstants.STATUS_COMPLETED);
|
||||
contract.setUpdateBy(currentUser.getUsername());
|
||||
contract.setUpdateTime(LocalDateTime.now());
|
||||
contractLaunchMapper.updateContract(contract);
|
||||
|
||||
if (archiveDto != null && archiveDto.getArchiveFiles() != null && !archiveDto.getArchiveFiles().isEmpty()) {
|
||||
for (ContractLaunchFileDto fileDto : archiveDto.getArchiveFiles()) {
|
||||
fileDto.setId(contractLaunchMapper.selectFileSeqNextVal());
|
||||
fileDto.setContractId(id);
|
||||
fileDto.setFileCategory(ContractLaunchConstants.FILE_CATEGORY_ARCHIVE);
|
||||
}
|
||||
contractLaunchMapper.batchInsertFile(archiveDto.getArchiveFiles(), currentUser.getUsername(), currentUser.getUsername());
|
||||
}
|
||||
|
||||
Map<String, Object> payload = buildArchivePayload(contract, archiveDto);
|
||||
insertLog(id, ContractLaunchConstants.ACTION_ARCHIVE, "合同归档", ContractLaunchConstants.ACTION_STATUS_PENDING, "合同归档接口当前先注释,使用测试按钮流转", payload, currentUser);
|
||||
|
||||
// TODO: 法务接口当前不可用,真实联调时打开下面调用即可
|
||||
// PushPayloadDTO requestDTO = new PushPayloadDTO();
|
||||
// requestDTO.setPayload(payload);
|
||||
// settlementPushService.pushArchive(requestDTO);
|
||||
// dataCollectionPushService.collectContractArchive(requestDTO);
|
||||
|
||||
return getDetail(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* 删除合同草稿(逻辑删除)。
|
||||
*
|
||||
* 仅 draft(草稿)或 rejected(已驳回)状态允许删除。
|
||||
* 设置 isDeleted = 'Y',不物理删除数据。
|
||||
* 已提交法务审批或进行中的合同不允许删除。
|
||||
*/
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public void deleteDraft(Long id) {
|
||||
ContractLaunchDto contract = getDetail(id);
|
||||
if (!canDelete(contract.getStatus())) {
|
||||
throw new ServiceException("仅草稿或驳回状态允许删除");
|
||||
}
|
||||
SysUserEntity currentUser = adminSecurityManage.getUser();
|
||||
contractLaunchMapper.deleteContract(id, currentUser.getUsername());
|
||||
insertLog(id, ContractLaunchConstants.ACTION_DELETE, "删除合同", ContractLaunchConstants.ACTION_STATUS_SUCCESS, "合同已逻辑删除", null, currentUser);
|
||||
}
|
||||
|
||||
/**
|
||||
* 批量填充子表数据(合同方/文件/履行计划/日志)。
|
||||
*
|
||||
* 一次性查完所有子表再按 contractId 分组赋值,避免 N+1 查询。
|
||||
* includeLogs: 列表页不查日志(日志数据量大),详情页才查。
|
||||
*/
|
||||
private void fillChildren(List<ContractLaunchDto> list, boolean includeLogs) {
|
||||
if (list == null || list.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<Long> ids = list.stream().map(ContractLaunchDto::getId).filter(Objects::nonNull).collect(Collectors.toList());
|
||||
if (ids.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
Map<Long, List<ContractLaunchPartyDto>> partyMap = contractLaunchMapper.selectPartyByContractIds(ids).stream()
|
||||
.collect(Collectors.groupingBy(ContractLaunchPartyDto::getContractId));
|
||||
Map<Long, List<ContractLaunchFileDto>> fileMap = contractLaunchMapper.selectFileByContractIds(ids).stream()
|
||||
.collect(Collectors.groupingBy(ContractLaunchFileDto::getContractId));
|
||||
Map<Long, List<ContractLaunchPlanDto>> planMap = contractLaunchMapper.selectPlanByContractIds(ids).stream()
|
||||
.collect(Collectors.groupingBy(ContractLaunchPlanDto::getContractId));
|
||||
Map<Long, List<ContractLaunchLogDto>> logMap = includeLogs
|
||||
? contractLaunchMapper.selectLogByContractIds(ids).stream().collect(Collectors.groupingBy(ContractLaunchLogDto::getContractId))
|
||||
: Collections.emptyMap();
|
||||
|
||||
list.forEach(item -> {
|
||||
item.setPartyList(new ArrayList<>(partyMap.getOrDefault(item.getId(), Collections.emptyList())));
|
||||
item.setFileList(new ArrayList<>(fileMap.getOrDefault(item.getId(), Collections.emptyList())));
|
||||
item.setPerformancePlans(new ArrayList<>(planMap.getOrDefault(item.getId(), Collections.emptyList())));
|
||||
item.setLogList(new ArrayList<>(logMap.getOrDefault(item.getId(), Collections.emptyList())));
|
||||
item.setCounterpartySummary(
|
||||
item.getPartyList().stream()
|
||||
.filter(party -> !"A".equalsIgnoreCase(party.getRoleCode()))
|
||||
.map(ContractLaunchPartyDto::getCompanyName)
|
||||
.filter(name -> name != null && !name.isBlank())
|
||||
.collect(Collectors.joining(";"))
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/** 保存子表数据(合同方/文件/履行计划,插入前生成主键 ID) */
|
||||
private void saveChildren(ContractLaunchDto contract, String operator) {
|
||||
if (contract.getPartyList() != null) {
|
||||
for (int i = 0; i < contract.getPartyList().size(); i++) {
|
||||
ContractLaunchPartyDto party = contract.getPartyList().get(i);
|
||||
party.setId(contractLaunchMapper.selectPartySeqNextVal());
|
||||
party.setContractId(contract.getId());
|
||||
party.setSortOrder(i + 1);
|
||||
}
|
||||
if (!contract.getPartyList().isEmpty()) {
|
||||
contractLaunchMapper.batchInsertParty(contract.getPartyList(), operator, operator);
|
||||
}
|
||||
}
|
||||
if (contract.getFileList() != null) {
|
||||
for (int i = 0; i < contract.getFileList().size(); i++) {
|
||||
ContractLaunchFileDto file = contract.getFileList().get(i);
|
||||
file.setId(contractLaunchMapper.selectFileSeqNextVal());
|
||||
file.setContractId(contract.getId());
|
||||
file.setSortOrder(i + 1);
|
||||
}
|
||||
if (!contract.getFileList().isEmpty()) {
|
||||
contractLaunchMapper.batchInsertFile(contract.getFileList(), operator, operator);
|
||||
}
|
||||
}
|
||||
if (contract.getPerformancePlans() != null) {
|
||||
for (ContractLaunchPlanDto plan : contract.getPerformancePlans()) {
|
||||
plan.setId(contractLaunchMapper.selectPlanSeqNextVal());
|
||||
plan.setContractId(contract.getId());
|
||||
if (plan.getPlanStatus() == null || plan.getPlanStatus().isBlank()) {
|
||||
plan.setPlanStatus("0");
|
||||
}
|
||||
}
|
||||
if (!contract.getPerformancePlans().isEmpty()) {
|
||||
contractLaunchMapper.batchInsertPlan(contract.getPerformancePlans(), operator, operator);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 替换子表数据(先删旧数据,再保存新数据) */
|
||||
private void replaceChildren(ContractLaunchDto contract, String operator) {
|
||||
contractLaunchMapper.deletePartyByContractId(contract.getId(), operator);
|
||||
contractLaunchMapper.deleteFileByContractId(contract.getId(), operator);
|
||||
contractLaunchMapper.deletePlanByContractId(contract.getId(), operator);
|
||||
saveChildren(contract, operator);
|
||||
}
|
||||
|
||||
/** 保存签署文件到 file 子表(先删旧签署文件,再插入新的) */
|
||||
private void saveSignedFile(Long contractId, ContractLaunchSealDto sealDto, String operator) {
|
||||
if (sealDto.getSignedFilePath() == null || sealDto.getSignedFilePath().isBlank()) {
|
||||
return;
|
||||
}
|
||||
contractLaunchMapper.deleteFileByContractIdAndCategory(contractId, ContractLaunchConstants.FILE_CATEGORY_SIGNED, operator);
|
||||
ContractLaunchFileDto fileDto = new ContractLaunchFileDto();
|
||||
fileDto.setId(contractLaunchMapper.selectFileSeqNextVal());
|
||||
fileDto.setContractId(contractId);
|
||||
fileDto.setFileCategory(ContractLaunchConstants.FILE_CATEGORY_SIGNED);
|
||||
fileDto.setFileName(sealDto.getSignedFileName() == null || sealDto.getSignedFileName().isBlank()
|
||||
? "已签署合同文件"
|
||||
: sealDto.getSignedFileName());
|
||||
fileDto.setFilePath(sealDto.getSignedFilePath());
|
||||
fileDto.setFileType(sealDto.getSignedFileType());
|
||||
fileDto.setFileSize(sealDto.getSignedFileSize());
|
||||
fileDto.setSortOrder(1);
|
||||
contractLaunchMapper.batchInsertFile(Collections.singletonList(fileDto), operator, operator);
|
||||
}
|
||||
|
||||
/** 写入操作日志 */
|
||||
private void insertLog(Long contractId, String actionType, String actionName, String actionStatus, String actionContent, Object payload, SysUserEntity currentUser) {
|
||||
ContractLaunchLogDto logDto = new ContractLaunchLogDto();
|
||||
logDto.setId(contractLaunchMapper.selectLogSeqNextVal());
|
||||
logDto.setContractId(contractId);
|
||||
logDto.setActionType(actionType);
|
||||
logDto.setActionName(actionName);
|
||||
logDto.setActionStatus(actionStatus);
|
||||
logDto.setOperatorName(currentUser.getUsername());
|
||||
logDto.setOperatorPhone(currentUser.getMobilePhone());
|
||||
logDto.setActionTime(LocalDateTime.now());
|
||||
logDto.setActionContent(actionContent);
|
||||
logDto.setCallbackPayload(payload == null ? null : JSON.toJSONString(payload));
|
||||
contractLaunchMapper.insertLog(logDto);
|
||||
}
|
||||
|
||||
/** 数据清洗:去空格、补默认值 */
|
||||
private void normalizeContract(ContractLaunchDto contract) {
|
||||
if (contract == null) {
|
||||
throw new ServiceException("合同数据不能为空");
|
||||
}
|
||||
contract.setContractName(trim(contract.getContractName()));
|
||||
contract.setContractCode(trim(contract.getContractCode()));
|
||||
contract.setContractType(trim(contract.getContractType()));
|
||||
contract.setContractTypeCode(trim(contract.getContractTypeCode()));
|
||||
contract.setPaymentMethod(trim(contract.getPaymentMethod()));
|
||||
contract.setPrimaryContent(trim(contract.getPrimaryContent()));
|
||||
contract.setAmountExplain(trim(contract.getAmountExplain()));
|
||||
contract.setAssistDepartmentName(trim(contract.getAssistDepartmentName()));
|
||||
contract.setExecutorAccount(trim(contract.getExecutorAccount()));
|
||||
contract.setPeriodExplain(trim(contract.getPeriodExplain()));
|
||||
contract.setContractGistRemark(trim(contract.getContractGistRemark()));
|
||||
contract.setBodySummary(trim(contract.getBodySummary()));
|
||||
contract.setSigningSubjectCode(trim(contract.getSigningSubjectCode()));
|
||||
contract.setDateType(trim(contract.getDateType()));
|
||||
contract.setPushUrl(trim(contract.getPushUrl()));
|
||||
contract.setEwAmountType(trim(contract.getEwAmountType()));
|
||||
if (contract.getDateType() == null || contract.getDateType().isBlank()) {
|
||||
contract.setDateType("0");
|
||||
}
|
||||
if (contract.getTextSource() == null || contract.getTextSource().isBlank()) {
|
||||
contract.setTextSource("standardText");
|
||||
}
|
||||
if (contract.getIsElectron() == null || contract.getIsElectron().isBlank()) {
|
||||
contract.setIsElectron("1");
|
||||
}
|
||||
if (contract.getPaymentDirection() == null || contract.getPaymentDirection().isBlank()) {
|
||||
contract.setPaymentDirection("0");
|
||||
}
|
||||
if (contract.getPushUrl() == null || contract.getPushUrl().isBlank()) {
|
||||
contract.setPushUrl("/contract/launch/callback/law/approve");
|
||||
}
|
||||
if (contract.getPartyList() == null) {
|
||||
contract.setPartyList(new ArrayList<>());
|
||||
}
|
||||
if (contract.getFileList() == null) {
|
||||
contract.setFileList(new ArrayList<>());
|
||||
}
|
||||
if (contract.getPerformancePlans() == null) {
|
||||
contract.setPerformancePlans(new ArrayList<>());
|
||||
}
|
||||
}
|
||||
|
||||
/** 校验草稿必填项 */
|
||||
private void validateDraft(ContractLaunchDto contract) {
|
||||
if (contract.getContractName() == null || contract.getContractName().isBlank()) {
|
||||
throw new ServiceException("合同名称不能为空");
|
||||
}
|
||||
if (contract.getContractTypeCode() == null || contract.getContractTypeCode().isBlank()) {
|
||||
throw new ServiceException("合同类型编码不能为空");
|
||||
}
|
||||
if (contract.getContractType() == null || contract.getContractType().isBlank()) {
|
||||
throw new ServiceException("合同类型不能为空");
|
||||
}
|
||||
if (contract.getValuationMode() == null || contract.getValuationMode().isBlank()) {
|
||||
throw new ServiceException("计价方式不能为空");
|
||||
}
|
||||
if (contract.getCurrencyName() == null || contract.getCurrencyName().isBlank()) {
|
||||
throw new ServiceException("币种不能为空");
|
||||
}
|
||||
if (contract.getSealType() == null || contract.getSealType().isBlank()) {
|
||||
throw new ServiceException("签订方式不能为空");
|
||||
}
|
||||
if (contract.getContractPeriodType() == null || contract.getContractPeriodType().isBlank()) {
|
||||
throw new ServiceException("合同期限类型不能为空");
|
||||
}
|
||||
if ("0".equals(contract.getContractPeriodType())
|
||||
&& (contract.getEffectiveStart() == null || contract.getEffectiveEnd() == null)) {
|
||||
throw new ServiceException("固定期限合同必须填写开始和结束时间");
|
||||
}
|
||||
if ("1".equals(contract.getContractPeriodType())
|
||||
&& (contract.getPeriodExplain() == null || contract.getPeriodExplain().isBlank())) {
|
||||
throw new ServiceException("无固定期限合同必须填写期限说明");
|
||||
}
|
||||
if (contract.getPartyList() == null || contract.getPartyList().isEmpty()) {
|
||||
throw new ServiceException("至少需要维护一个合同方");
|
||||
}
|
||||
boolean hasPartyA = contract.getPartyList().stream().anyMatch(item -> "A".equalsIgnoreCase(item.getRoleCode()));
|
||||
boolean hasCounterparty = contract.getPartyList().stream().anyMatch(item -> !"A".equalsIgnoreCase(item.getRoleCode()));
|
||||
if (!hasPartyA) {
|
||||
throw new ServiceException("必须维护我方信息");
|
||||
}
|
||||
if (!hasCounterparty) {
|
||||
throw new ServiceException("至少维护一个相对方");
|
||||
}
|
||||
}
|
||||
|
||||
private boolean canEdit(String status) {
|
||||
return ContractLaunchConstants.STATUS_DRAFT.equals(status) || ContractLaunchConstants.STATUS_REJECTED.equals(status);
|
||||
}
|
||||
|
||||
private boolean canSubmit(String status) {
|
||||
return ContractLaunchConstants.STATUS_DRAFT.equals(status) || ContractLaunchConstants.STATUS_REJECTED.equals(status);
|
||||
}
|
||||
|
||||
private boolean canDelete(String status) {
|
||||
return ContractLaunchConstants.STATUS_DRAFT.equals(status) || ContractLaunchConstants.STATUS_REJECTED.equals(status);
|
||||
}
|
||||
|
||||
/** 通过法务回调报文查找对应合同(先取 contractSysId 再查库) */
|
||||
private ContractLaunchDto getContractByLawCallback(Map<String, Object> payload) {
|
||||
if (payload == null || payload.isEmpty()) {
|
||||
throw new ServiceException("法务回调报文不能为空");
|
||||
}
|
||||
String contractSysId = getFirstText(payload, "contractSysId", "businessNo", "thirdContractId");
|
||||
if (contractSysId == null || contractSysId.isBlank()) {
|
||||
throw new ServiceException("法务回调缺少 contractSysId,无法定位合同");
|
||||
}
|
||||
ContractLaunchDto contract = contractLaunchMapper.selectContractByContractSysId(contractSysId);
|
||||
if (contract == null) {
|
||||
throw new ServiceException("未找到法务回调对应的合同:" + contractSysId);
|
||||
}
|
||||
fillChildren(Collections.singletonList(contract), true);
|
||||
return contract;
|
||||
}
|
||||
|
||||
/** 判断法务回调是否审批通过(兼容多种字段名和值) */
|
||||
private boolean isLawCallbackApproved(Map<String, Object> payload) {
|
||||
String status = getFirstText(payload, "approveStatus", "status", "result", "auditStatus");
|
||||
if (status == null || status.isBlank()) {
|
||||
return true;
|
||||
}
|
||||
String normalized = status.trim().toLowerCase();
|
||||
return normalized.equals("1")
|
||||
|| normalized.equals("true")
|
||||
|| normalized.equals("success")
|
||||
|| normalized.equals("approved")
|
||||
|| normalized.equals("pass")
|
||||
|| normalized.equals("agree")
|
||||
|| normalized.equals("通过")
|
||||
|| normalized.equals("审批通过");
|
||||
}
|
||||
|
||||
/** 从回调报文中提取指定 key 的文本值(多个 key 依次尝试,取第一个非空) */
|
||||
private String getFirstText(Map<String, Object> payload, String... keys) {
|
||||
if (payload == null) {
|
||||
return null;
|
||||
}
|
||||
for (String key : keys) {
|
||||
Object value = payload.get(key);
|
||||
if (value == null) {
|
||||
continue;
|
||||
}
|
||||
String text = String.valueOf(value).trim();
|
||||
if (!text.isBlank()) {
|
||||
return text;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/** 构建结算平台推送合同报文(pushContract 接口的 payload) */
|
||||
private Map<String, Object> buildSettlementPushPayload(ContractLaunchDto contract) {
|
||||
Map<String, Object> payload = new LinkedHashMap<>();
|
||||
payload.put("contractSource", contract.getContractSource());
|
||||
payload.put("isAddit", contract.getIsAddit() == null ? 2 : contract.getIsAddit());
|
||||
payload.put("operate", "create");
|
||||
payload.put("mainContractCode", contract.getMainContractCode());
|
||||
payload.put("periodExplain", contract.getPeriodExplain());
|
||||
payload.put("valuationMode", contract.getValuationMode());
|
||||
payload.put("isMajorContract", contract.getIsMajorContract() == null ? 0 : contract.getIsMajorContract());
|
||||
payload.put("sealType", contract.getSealType());
|
||||
payload.put("creatorPhone", contract.getCreatorPhone());
|
||||
payload.put("dateType", contract.getDateType());
|
||||
payload.put("currencyName", contract.getCurrencyName());
|
||||
payload.put("contractGistRemark", contract.getContractGistRemark());
|
||||
payload.put("contractSysId", contract.getContractSysId());
|
||||
payload.put("selfCode", contract.getSelfCode());
|
||||
payload.put("contractName", contract.getContractName());
|
||||
payload.put("startTime", contract.getEffectiveStart());
|
||||
payload.put("endTime", contract.getEffectiveEnd());
|
||||
payload.put("amountExplain", contract.getAmountExplain());
|
||||
payload.put("isText", contract.getTextSource());
|
||||
payload.put("primaryContent", contract.getPrimaryContent());
|
||||
payload.put("isElectron", contract.getIsElectron());
|
||||
payload.put("paymentDirection", contract.getPaymentDirection());
|
||||
payload.put("contractTypeCode", contract.getContractTypeCode());
|
||||
payload.put("bodySummary", contract.getBodySummary());
|
||||
payload.put("signingSubjectCode",
|
||||
contract.getSigningSubjectCode() == null || contract.getSigningSubjectCode().isBlank()
|
||||
? contract.getOrgId()
|
||||
: contract.getSigningSubjectCode());
|
||||
payload.put("executorAccount", contract.getExecutorAccount());
|
||||
payload.put("contractPeriod", contract.getContractPeriodType());
|
||||
payload.put("contractAmount", contract.getContractAmount());
|
||||
payload.put("isSgat", contract.getIsSgat());
|
||||
payload.put("isOpenBidding", contract.getIsOpenBidding() == null ? 0 : contract.getIsOpenBidding());
|
||||
payload.put("pushUrl", contract.getPushUrl());
|
||||
payload.put("isYearBudget", contract.getIsYearBudget() == null ? 0 : contract.getIsYearBudget());
|
||||
payload.put("isShare", contract.getIsShare());
|
||||
payload.put("assistDepartmentName", contract.getAssistDepartmentName());
|
||||
payload.put("contractNature", contract.getContractNature());
|
||||
payload.put("contractCode", contract.getContractCode());
|
||||
payload.put("ewAmountType", contract.getEwAmountType());
|
||||
payload.put("djAmount", contract.getDjAmount());
|
||||
payload.put("yjAmount", contract.getYjAmount());
|
||||
payload.put("yfkAmount", contract.getYfkAmount());
|
||||
payload.put("bzjAmount", contract.getBzjAmount());
|
||||
payload.put("contractOpposites", contract.getPartyList().stream()
|
||||
.filter(item -> !"A".equalsIgnoreCase(item.getRoleCode()))
|
||||
.map(item -> {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("oppCharacter", "2".equals(item.getOppositeCharacter()) ? "ZZR" : "QY");
|
||||
map.put("credirCode", item.getCreditCode());
|
||||
map.put("idCard", item.getNaturalPersonIdNumber());
|
||||
map.put("oppositeName", item.getCompanyName());
|
||||
return map;
|
||||
}).collect(Collectors.toList()));
|
||||
payload.put("contractKxPlans", contract.getPerformancePlans().stream().map(plan -> {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("planWhere", plan.getPlanWhere());
|
||||
map.put("planMoney", plan.getPlanMoney());
|
||||
map.put("planDetail", plan.getPlanDetail());
|
||||
map.put("planTime", plan.getPlanTime());
|
||||
map.put("planMatter", plan.getPlanMatter());
|
||||
map.put("planDay", plan.getPlanDay());
|
||||
map.put("planSubjectCode", plan.getPlanSubjectCode());
|
||||
map.put("planSubjectName", plan.getPlanSubjectName());
|
||||
return map;
|
||||
}).collect(Collectors.toList()));
|
||||
payload.put("contractText", buildFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_BODY));
|
||||
payload.put("otherAttach", buildFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_OTHER));
|
||||
payload.put("contractGistFile", buildFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_GIST));
|
||||
return payload;
|
||||
}
|
||||
|
||||
/** 构建数据采集合同报文(collectContract 接口的 payload) */
|
||||
private Map<String, Object> buildDataCollectionContractPayload(ContractLaunchDto contract) {
|
||||
Map<String, Object> payload = new LinkedHashMap<>();
|
||||
payload.put("c_name", contract.getContractName());
|
||||
payload.put("c_code", contract.getLawContractCode() == null || contract.getLawContractCode().isBlank() ? contract.getContractCode() : contract.getLawContractCode());
|
||||
payload.put("c_weNames", contract.getCompanyName());
|
||||
payload.put("c_oppositeNames", contract.getCounterpartySummary());
|
||||
payload.put("c_textSource", contract.getTextSource());
|
||||
payload.put("c_mainContent", contract.getPrimaryContent());
|
||||
payload.put("c_direction", contract.getPaymentDirection());
|
||||
payload.put("c_method", contract.getValuationMode());
|
||||
payload.put("c_subjectAMT", contract.getContractAmount());
|
||||
payload.put("c_currency", contract.getCurrencyName());
|
||||
payload.put("c_amountExplain", contract.getAmountExplain());
|
||||
payload.put("c_type", contract.getContractTypeCode());
|
||||
payload.put("c_termType", contract.getContractPeriodType());
|
||||
payload.put("c_termExplain", contract.getPeriodExplain());
|
||||
payload.put("c_termStart", contract.getEffectiveStart());
|
||||
payload.put("c_termEnd", contract.getEffectiveEnd());
|
||||
payload.put("c_qyztGAT", contract.getIsSgat());
|
||||
payload.put("c_executor", contract.getExecutorAccount());
|
||||
payload.put("c_openBidding", contract.getIsOpenBidding());
|
||||
payload.put("c_currentBudget", contract.getIsYearBudget());
|
||||
payload.put("c_major", contract.getIsMajorContract());
|
||||
payload.put("c_signMethod", contract.getSealType());
|
||||
payload.put("c_creator", contract.getInitiator());
|
||||
payload.put("c_creatorPhone", contract.getCreatorPhone());
|
||||
payload.put("c_createDept", contract.getInitiatorDept());
|
||||
payload.put("c_zw", buildFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_BODY));
|
||||
payload.put("c_attachs", buildFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_OTHER));
|
||||
payload.put("c_signAttachs", buildFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_SIGNED));
|
||||
payload.put("c_lxPlan", contract.getPerformancePlans());
|
||||
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_date", contract.getSignDate());
|
||||
payload.put("c_seal", seal);
|
||||
Map<String, Object> sign = new LinkedHashMap<>();
|
||||
sign.put("sign_isSign", "1");
|
||||
sign.put("sign_date", contract.getSignDate());
|
||||
sign.put("sign_activeDate", contract.getActiveDate());
|
||||
sign.put("sign_attachs", buildFilePayloadList(contract, ContractLaunchConstants.FILE_CATEGORY_SIGNED));
|
||||
sign.put("sign_executor", contract.getExecutorAccount());
|
||||
payload.put("c_sign", sign);
|
||||
return payload;
|
||||
}
|
||||
|
||||
/** 构建归档报文(pushArchive 接口的 payload) */
|
||||
private Map<String, Object> buildArchivePayload(ContractLaunchDto contract, ContractLaunchArchiveDto archiveDto) {
|
||||
Map<String, Object> payload = new LinkedHashMap<>();
|
||||
payload.put("contractCode", contract.getLawContractCode());
|
||||
payload.put("contractSysId", contract.getContractSysId());
|
||||
payload.put("Keeper", archiveDto == null ? null : archiveDto.getArchiveKeeper());
|
||||
payload.put("KeeperUnit", archiveDto == null ? null : archiveDto.getArchiveKeeperUnit());
|
||||
payload.put("KeeperUnitCode", archiveDto == null ? null : archiveDto.getArchiveKeeperUnitCode());
|
||||
payload.put("archivePapers", List.of());
|
||||
payload.put("archiveEles", (archiveDto == null || archiveDto.getArchiveFiles() == null) ? List.of() : archiveDto.getArchiveFiles());
|
||||
return payload;
|
||||
}
|
||||
|
||||
/** 按 fileCategory 提取文件列表,转为法务接口要求的附件格式 */
|
||||
private List<Map<String, Object>> buildFilePayloadList(ContractLaunchDto contract, String fileCategory) {
|
||||
return contract.getFileList().stream()
|
||||
.filter(item -> fileCategory.equals(item.getFileCategory()))
|
||||
.map(item -> {
|
||||
Map<String, Object> map = new LinkedHashMap<>();
|
||||
map.put("fileName", item.getFileName());
|
||||
map.put("filePath", item.getFilePath());
|
||||
map.put("fileSize", item.getFileSize());
|
||||
map.put("fileType", item.getFileType());
|
||||
return map;
|
||||
}).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
private String trim(String value) {
|
||||
return value == null ? null : value.trim();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
package com.nbport.zgwl.contractlaunch.utils;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.concurrent.ThreadLocalRandom;
|
||||
|
||||
/**
|
||||
* 合同编号工具
|
||||
*
|
||||
* contractSysId:本系统合同唯一标识,格式 CLS-yyyyMMddHHmmss-随机4位
|
||||
* contractCode:业务合同编号,格式 合同类型编码-yyyyMMdd-随机4位(如 MM-20260522-1234)
|
||||
*/
|
||||
public final class ContractLaunchCodeUtils {
|
||||
|
||||
private ContractLaunchCodeUtils() {
|
||||
}
|
||||
|
||||
/** 生成合同系统唯一编码(CLS-时间戳-随机4位) */
|
||||
public static String buildContractSysId() {
|
||||
return "CLS-" + formatNow("yyyyMMddHHmmss") + "-" + randomDigits(4);
|
||||
}
|
||||
|
||||
/** 生成业务合同编号(合同类型编码-日期-随机4位,如 MM-20260522-1234) */
|
||||
public static String buildContractCode(String contractTypeCode) {
|
||||
String typeCode = contractTypeCode == null || contractTypeCode.isBlank()
|
||||
? "QT"
|
||||
: contractTypeCode;
|
||||
return typeCode + "-" + formatNow("yyyyMMdd") + "-" + randomDigits(4);
|
||||
}
|
||||
|
||||
private static String formatNow(String pattern) {
|
||||
return new SimpleDateFormat(pattern).format(new Date());
|
||||
}
|
||||
|
||||
private static String randomDigits(int length) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
builder.append(ThreadLocalRandom.current().nextInt(10));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package com.nbport.zgwl.contractlaunch.utils;
|
||||
|
||||
/**
|
||||
* 合同发起模块常量
|
||||
*
|
||||
* 这里把状态值集中放一起,方便你后续改状态文案或补真实流程。
|
||||
*/
|
||||
public final class ContractLaunchConstants {
|
||||
|
||||
private ContractLaunchConstants() {
|
||||
}
|
||||
|
||||
public static final String REQUEST_PREFIX = "/contract/launch";
|
||||
|
||||
public static final String STATUS_DRAFT = "draft";
|
||||
public static final String STATUS_REVIEWING = "reviewing";
|
||||
public static final String STATUS_REJECTED = "rejected";
|
||||
public static final String STATUS_PENDING_SIGN = "pending_sign";
|
||||
public static final String STATUS_SIGNING = "signing";
|
||||
public static final String STATUS_PENDING_COLLECT = "pending_collect";
|
||||
public static final String STATUS_PENDING_ARCHIVE = "pending_archive";
|
||||
public static final String STATUS_COMPLETED = "completed";
|
||||
public static final String STATUS_TERMINATED = "terminated";
|
||||
|
||||
public static final String APPROVE_STATUS_PENDING = "pending";
|
||||
public static final String APPROVE_STATUS_APPROVED = "approved";
|
||||
public static final String APPROVE_STATUS_REJECTED = "rejected";
|
||||
|
||||
public static final String FILE_CATEGORY_BODY = "body";
|
||||
public static final String FILE_CATEGORY_OTHER = "other";
|
||||
public static final String FILE_CATEGORY_GIST = "gist";
|
||||
public static final String FILE_CATEGORY_SIGNED = "signed";
|
||||
public static final String FILE_CATEGORY_ARCHIVE = "archive";
|
||||
|
||||
public static final String ACTION_SAVE = "save";
|
||||
public static final String ACTION_SUBMIT = "submit";
|
||||
public static final String ACTION_APPROVE = "approve";
|
||||
public static final String ACTION_REJECT = "reject";
|
||||
public static final String ACTION_SEAL_START = "seal_start";
|
||||
public static final String ACTION_SEAL_FINISH = "seal_finish";
|
||||
public static final String ACTION_COLLECT = "collect";
|
||||
public static final String ACTION_ARCHIVE = "archive";
|
||||
public static final String ACTION_DELETE = "delete";
|
||||
|
||||
public static final String ACTION_STATUS_SUCCESS = "success";
|
||||
public static final String ACTION_STATUS_FAILED = "failed";
|
||||
public static final String ACTION_STATUS_PENDING = "pending";
|
||||
|
||||
public static final String IS_DELETED_NO = "N";
|
||||
public static final String IS_DELETED_YES = "Y";
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
package com.nbport.zgwl.entity;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.io.Serial;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 组织信息
|
||||
*
|
||||
* 当前项目里先作为一个简单对象使用,
|
||||
* 后续接入真实权限系统时,可以直接替换成真实组织实体。
|
||||
*/
|
||||
@Data
|
||||
public class SysOrgEntity implements Serializable {
|
||||
|
||||
@Serial
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
/** 组织ID */
|
||||
private String id;
|
||||
|
||||
/** 组织名称 */
|
||||
private String orgName;
|
||||
}
|
||||
@@ -28,4 +28,12 @@ public class SysUserEntity extends BaseEntity<SysUserEntity> {
|
||||
|
||||
@TableField("email")
|
||||
private String email;
|
||||
|
||||
/**
|
||||
* 当前登录人的所属组织
|
||||
*
|
||||
* 这里不映射数据库字段,只用于业务代码里取组织信息。
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private SysOrgEntity sysOrgEntity;
|
||||
}
|
||||
|
||||
@@ -16,6 +16,38 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
public final class ManifestCodeUtils {
|
||||
|
||||
private static final Map<String, String> CONTRACT_TYPE_CODE_MAP = Map.ofEntries(
|
||||
Map.entry("MM", "MM"),
|
||||
Map.entry("GY", "GY"),
|
||||
Map.entry("ZY", "ZY"),
|
||||
Map.entry("JK", "JK"),
|
||||
Map.entry("BZ", "BZ"),
|
||||
Map.entry("ZL", "ZL"),
|
||||
Map.entry("RZ", "RZ"),
|
||||
Map.entry("BL", "BL"),
|
||||
Map.entry("CL", "CL"),
|
||||
Map.entry("GC", "GC"),
|
||||
Map.entry("YS", "YS"),
|
||||
Map.entry("JS", "JS"),
|
||||
Map.entry("BG", "BG"),
|
||||
Map.entry("CC", "CC"),
|
||||
Map.entry("WT", "WT"),
|
||||
Map.entry("WY", "WY"),
|
||||
Map.entry("HJ", "HJ"),
|
||||
Map.entry("ZJ", "ZJ"),
|
||||
Map.entry("HH", "HH"),
|
||||
Map.entry("YG", "YG"),
|
||||
Map.entry("YW", "YW"),
|
||||
Map.entry("QT", "QT"),
|
||||
Map.entry("YWBFP", "YWBFP"),
|
||||
Map.entry("YWBFS", "YWBFS"),
|
||||
Map.entry("YWIOP", "YWIOP"),
|
||||
Map.entry("YWIOS", "YWIOS"),
|
||||
Map.entry("YWDOP", "YWDOP"),
|
||||
Map.entry("YWDOS", "YWDOS"),
|
||||
Map.entry("YWBCP", "YWBCP"),
|
||||
Map.entry("YWBCS", "YWBCS"),
|
||||
Map.entry("YWOTP", "YWOTP"),
|
||||
Map.entry("YWOTS", "YWOTS"),
|
||||
Map.entry("买卖合同", "MM"),
|
||||
Map.entry("采购合同", "CG"),
|
||||
Map.entry("销售合同", "XS"),
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
package com.nbport.zgwl.utils;
|
||||
|
||||
import com.nbport.zgwl.entity.SysOrgEntity;
|
||||
import com.nbport.zgwl.entity.SysUserEntity;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 登录用户获取组件
|
||||
*
|
||||
* 当前系统还没有真正接入统一认证,
|
||||
* 所以这里先返回一个 mock 用户,便于业务代码先跑通。
|
||||
* 后续接入真实系统时,直接把这里替换成真正的登录态获取逻辑即可。
|
||||
*/
|
||||
@Component
|
||||
public class AdminSecurityManage {
|
||||
|
||||
public SysUserEntity getUser() {
|
||||
SysOrgEntity orgEntity = new SysOrgEntity();
|
||||
orgEntity.setId("ORG001");
|
||||
orgEntity.setOrgName("浙港物流平台有限公司");
|
||||
|
||||
SysUserEntity user = new SysUserEntity();
|
||||
user.setId(1L);
|
||||
user.setUsername("admin");
|
||||
user.setMobilePhone("13800000000");
|
||||
user.setEmail("admin@test.com");
|
||||
user.setSysOrgEntity(orgEntity);
|
||||
return user;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,532 @@
|
||||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||
<mapper namespace="com.nbport.zgwl.contractlaunch.mapper.ContractLaunchMapper">
|
||||
|
||||
<resultMap id="ContractLaunchResult" type="com.nbport.zgwl.contractlaunch.dto.ContractLaunchDto">
|
||||
<id property="id" column="ID"/>
|
||||
<result property="contractSysId" column="CONTRACT_SYS_ID"/>
|
||||
<result property="contractCode" column="CONTRACT_CODE"/>
|
||||
<result property="lawContractCode" column="LAW_CONTRACT_CODE"/>
|
||||
<result property="lawContractId" column="LAW_CONTRACT_ID"/>
|
||||
<result property="contractName" column="CONTRACT_NAME"/>
|
||||
<result property="contractType" column="CONTRACT_TYPE"/>
|
||||
<result property="contractTypeCode" column="CONTRACT_TYPE_CODE"/>
|
||||
<result property="contractSource" column="CONTRACT_SOURCE"/>
|
||||
<result property="creationMode" column="CREATION_MODE"/>
|
||||
<result property="templateId" column="TEMPLATE_ID"/>
|
||||
<result property="templateCode" column="TEMPLATE_CODE"/>
|
||||
<result property="templateName" column="TEMPLATE_NAME"/>
|
||||
<result property="status" column="STATUS"/>
|
||||
<result property="approveStatus" column="APPROVE_STATUS"/>
|
||||
<result property="approveMessage" column="APPROVE_MESSAGE"/>
|
||||
<result property="sealContractId" column="SEAL_CONTRACT_ID"/>
|
||||
<result property="sealContractStatus" column="SEAL_CONTRACT_STATUS"/>
|
||||
<result property="contractAmount" column="CONTRACT_AMOUNT"/>
|
||||
<result property="currencyName" column="CURRENCY_NAME"/>
|
||||
<result property="contractPeriodType" column="CONTRACT_PERIOD_TYPE"/>
|
||||
<result property="periodExplain" column="PERIOD_EXPLAIN"/>
|
||||
<result property="effectiveStart" column="EFFECTIVE_START"/>
|
||||
<result property="effectiveEnd" column="EFFECTIVE_END"/>
|
||||
<result property="paymentMethod" column="PAYMENT_METHOD"/>
|
||||
<result property="primaryContent" column="PRIMARY_CONTENT"/>
|
||||
<result property="amountExplain" column="AMOUNT_EXPLAIN"/>
|
||||
<result property="valuationMode" column="VALUATION_MODE"/>
|
||||
<result property="sealType" column="SEAL_TYPE"/>
|
||||
<result property="textSource" column="TEXT_SOURCE"/>
|
||||
<result property="mandateType" column="MANDATE_TYPE"/>
|
||||
<result property="cargoType" column="CARGO_TYPE"/>
|
||||
<result property="assistDepartmentName" column="ASSIST_DEPARTMENT_NAME"/>
|
||||
<result property="executorAccount" column="EXECUTOR_ACCOUNT"/>
|
||||
<result property="creatorPhone" column="CREATOR_PHONE"/>
|
||||
<result property="selfCode" column="SELF_CODE"/>
|
||||
<result property="mainContractCode" column="MAIN_CONTRACT_CODE"/>
|
||||
<result property="signingSubjectCode" column="SIGNING_SUBJECT_CODE"/>
|
||||
<result property="dateType" column="DATE_TYPE"/>
|
||||
<result property="isAddit" column="IS_ADDIT"/>
|
||||
<result property="isElectron" column="IS_ELECTRON"/>
|
||||
<result property="paymentDirection" column="PAYMENT_DIRECTION"/>
|
||||
<result property="pushUrl" column="PUSH_URL"/>
|
||||
<result property="isMajorContract" column="IS_MAJOR_CONTRACT"/>
|
||||
<result property="isOpenBidding" column="IS_OPEN_BIDDING"/>
|
||||
<result property="isYearBudget" column="IS_YEAR_BUDGET"/>
|
||||
<result property="isShare" column="IS_SHARE"/>
|
||||
<result property="contractNature" column="CONTRACT_NATURE"/>
|
||||
<result property="isSgat" column="IS_SGAT"/>
|
||||
<result property="isNormal" column="IS_NORMAL"/>
|
||||
<result property="isTerminated" column="IS_TERMINATED"/>
|
||||
<result property="isSingleAgreement" column="IS_SINGLE_AGREEMENT"/>
|
||||
<result property="biddingNo" column="BIDDING_NO"/>
|
||||
<result property="openBiddingRemark" column="OPEN_BIDDING_REMARK"/>
|
||||
<result property="contractGistRemark" column="CONTRACT_GIST_REMARK"/>
|
||||
<result property="ewAmountType" column="EW_AMOUNT_TYPE"/>
|
||||
<result property="djAmount" column="DJ_AMOUNT"/>
|
||||
<result property="yjAmount" column="YJ_AMOUNT"/>
|
||||
<result property="yfkAmount" column="YFK_AMOUNT"/>
|
||||
<result property="bzjAmount" column="BZJ_AMOUNT"/>
|
||||
<result property="bodySummary" column="BODY_SUMMARY"/>
|
||||
<result property="contractTextFileName" column="CONTRACT_TEXT_FILE_NAME"/>
|
||||
<result property="contractTextFilePath" column="CONTRACT_TEXT_FILE_PATH"/>
|
||||
<result property="contractTextFileType" column="CONTRACT_TEXT_FILE_TYPE"/>
|
||||
<result property="contractTextFileSize" column="CONTRACT_TEXT_FILE_SIZE"/>
|
||||
<result property="signedFileName" column="SIGNED_FILE_NAME"/>
|
||||
<result property="signedFilePath" column="SIGNED_FILE_PATH"/>
|
||||
<result property="signedFileType" column="SIGNED_FILE_TYPE"/>
|
||||
<result property="signedFileSize" column="SIGNED_FILE_SIZE"/>
|
||||
<result property="signedOfflineReason" column="SIGNED_OFFLINE_REASON"/>
|
||||
<result property="signDate" column="SIGN_DATE"/>
|
||||
<result property="activeDate" column="ACTIVE_DATE"/>
|
||||
<result property="archiveDate" column="ARCHIVE_DATE"/>
|
||||
<result property="archiveKeeper" column="ARCHIVE_KEEPER"/>
|
||||
<result property="archiveKeeperUnit" column="ARCHIVE_KEEPER_UNIT"/>
|
||||
<result property="archiveKeeperUnitCode" column="ARCHIVE_KEEPER_UNIT_CODE"/>
|
||||
<result property="invoiceDate" column="INVOICE_DATE"/>
|
||||
<result property="receiveDate" column="RECEIVE_DATE"/>
|
||||
<result property="remindDays" column="REMIND_DAYS"/>
|
||||
<result property="initiator" column="INITIATOR"/>
|
||||
<result property="initiatorDept" column="INITIATOR_DEPT"/>
|
||||
<result property="companyName" column="COMPANY_NAME"/>
|
||||
<result property="orgId" column="ORG_ID"/>
|
||||
<result property="queryScope" column="QUERY_SCOPE"/>
|
||||
<result property="createBy" column="CREATE_BY"/>
|
||||
<result property="createTime" column="CREATE_TIME"/>
|
||||
<result property="updateBy" column="UPDATE_BY"/>
|
||||
<result property="updateTime" column="UPDATE_TIME"/>
|
||||
<result property="isDeleted" column="IS_DELETED"/>
|
||||
<result property="remark" column="REMARK"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="PartyResult" type="com.nbport.zgwl.contractlaunch.dto.ContractLaunchPartyDto">
|
||||
<id property="id" column="ID"/>
|
||||
<result property="contractId" column="CONTRACT_ID"/>
|
||||
<result property="roleCode" column="ROLE_CODE"/>
|
||||
<result property="roleName" column="ROLE_NAME"/>
|
||||
<result property="sortOrder" column="SORT_ORDER"/>
|
||||
<result property="partnerId" column="PARTNER_ID"/>
|
||||
<result property="oppositeId" column="OPPOSITE_ID"/>
|
||||
<result property="companyName" column="COMPANY_NAME"/>
|
||||
<result property="companyType" column="COMPANY_TYPE"/>
|
||||
<result property="oppositeCharacter" column="OPPOSITE_CHARACTER"/>
|
||||
<result property="contactName" column="CONTACT_NAME"/>
|
||||
<result property="contactPhone" column="CONTACT_PHONE"/>
|
||||
<result property="contactEmail" column="CONTACT_EMAIL"/>
|
||||
<result property="contactAddress" column="CONTACT_ADDRESS"/>
|
||||
<result property="registeredAddress" column="REGISTERED_ADDRESS"/>
|
||||
<result property="legalRepresentative" column="LEGAL_REPRESENTATIVE"/>
|
||||
<result property="creditCode" column="CREDIT_CODE"/>
|
||||
<result property="bankName" column="BANK_NAME"/>
|
||||
<result property="bankAccount" column="BANK_ACCOUNT"/>
|
||||
<result property="naturalPersonIdType" column="NATURAL_PERSON_ID_TYPE"/>
|
||||
<result property="naturalPersonIdNumber" column="NATURAL_PERSON_ID_NUMBER"/>
|
||||
<result property="isGroupInternal" column="IS_GROUP_INTERNAL"/>
|
||||
<result property="isHongKongMacaoTaiwan" column="IS_HONG_KONG_MACAO_TAIWAN"/>
|
||||
<result property="remark" column="REMARK"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="FileResult" type="com.nbport.zgwl.contractlaunch.dto.ContractLaunchFileDto">
|
||||
<id property="id" column="ID"/>
|
||||
<result property="contractId" column="CONTRACT_ID"/>
|
||||
<result property="fileCategory" column="FILE_CATEGORY"/>
|
||||
<result property="fileName" column="FILE_NAME"/>
|
||||
<result property="filePath" column="FILE_PATH"/>
|
||||
<result property="fileType" column="FILE_TYPE"/>
|
||||
<result property="fileSize" column="FILE_SIZE"/>
|
||||
<result property="sortOrder" column="SORT_ORDER"/>
|
||||
<result property="remark" column="REMARK"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="PlanResult" type="com.nbport.zgwl.contractlaunch.dto.ContractLaunchPlanDto">
|
||||
<id property="id" column="ID"/>
|
||||
<result property="contractId" column="CONTRACT_ID"/>
|
||||
<result property="planMatter" column="PLAN_MATTER"/>
|
||||
<result property="planWhere" column="PLAN_WHERE"/>
|
||||
<result property="planTime" column="PLAN_TIME"/>
|
||||
<result property="planDay" column="PLAN_DAY"/>
|
||||
<result property="planMoney" column="PLAN_MONEY"/>
|
||||
<result property="planSubjectCode" column="PLAN_SUBJECT_CODE"/>
|
||||
<result property="planSubjectName" column="PLAN_SUBJECT_NAME"/>
|
||||
<result property="planDetail" column="PLAN_DETAIL"/>
|
||||
<result property="planStatus" column="PLAN_STATUS"/>
|
||||
<result property="remark" column="REMARK"/>
|
||||
</resultMap>
|
||||
|
||||
<resultMap id="LogResult" type="com.nbport.zgwl.contractlaunch.dto.ContractLaunchLogDto">
|
||||
<id property="id" column="ID"/>
|
||||
<result property="contractId" column="CONTRACT_ID"/>
|
||||
<result property="actionType" column="ACTION_TYPE"/>
|
||||
<result property="actionName" column="ACTION_NAME"/>
|
||||
<result property="actionStatus" column="ACTION_STATUS"/>
|
||||
<result property="operatorName" column="OPERATOR_NAME"/>
|
||||
<result property="operatorPhone" column="OPERATOR_PHONE"/>
|
||||
<result property="actionTime" column="ACTION_TIME"/>
|
||||
<result property="actionContent" column="ACTION_CONTENT"/>
|
||||
<result property="callbackPayload" column="CALLBACK_PAYLOAD"/>
|
||||
<result property="remark" column="REMARK"/>
|
||||
</resultMap>
|
||||
|
||||
<sql id="mainColumns">
|
||||
select ID, CONTRACT_SYS_ID, CONTRACT_CODE, LAW_CONTRACT_CODE, LAW_CONTRACT_ID,
|
||||
CONTRACT_NAME, CONTRACT_TYPE, CONTRACT_TYPE_CODE, CONTRACT_SOURCE, CREATION_MODE,
|
||||
TEMPLATE_ID, TEMPLATE_CODE, TEMPLATE_NAME, STATUS, APPROVE_STATUS, APPROVE_MESSAGE,
|
||||
SEAL_CONTRACT_ID, SEAL_CONTRACT_STATUS, CONTRACT_AMOUNT, CURRENCY_NAME,
|
||||
CONTRACT_PERIOD_TYPE, PERIOD_EXPLAIN, EFFECTIVE_START, EFFECTIVE_END,
|
||||
PAYMENT_METHOD, PRIMARY_CONTENT, AMOUNT_EXPLAIN, VALUATION_MODE, SEAL_TYPE,
|
||||
TEXT_SOURCE, MANDATE_TYPE, CARGO_TYPE, ASSIST_DEPARTMENT_NAME, EXECUTOR_ACCOUNT,
|
||||
CREATOR_PHONE, SELF_CODE, MAIN_CONTRACT_CODE, SIGNING_SUBJECT_CODE, DATE_TYPE, IS_ADDIT, IS_ELECTRON,
|
||||
PAYMENT_DIRECTION, PUSH_URL, IS_MAJOR_CONTRACT, IS_OPEN_BIDDING, IS_YEAR_BUDGET, IS_SHARE,
|
||||
CONTRACT_NATURE, IS_SGAT, IS_NORMAL, IS_TERMINATED, IS_SINGLE_AGREEMENT,
|
||||
BIDDING_NO, OPEN_BIDDING_REMARK, CONTRACT_GIST_REMARK,
|
||||
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_OFFLINE_REASON,
|
||||
SIGN_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
|
||||
from SEAL_CONTRACT_LAUNCH_MAIN
|
||||
</sql>
|
||||
|
||||
<select id="selectMainSeqNextVal" resultType="java.lang.Long">
|
||||
select SEQ_SEAL_CONTRACT_LAUNCH_MAIN.NEXTVAL from dual
|
||||
</select>
|
||||
<select id="selectPartySeqNextVal" resultType="java.lang.Long">
|
||||
select SEQ_SEAL_CONTRACT_LAUNCH_PARTY.NEXTVAL from dual
|
||||
</select>
|
||||
<select id="selectFileSeqNextVal" resultType="java.lang.Long">
|
||||
select SEQ_SEAL_CONTRACT_LAUNCH_FILE.NEXTVAL from dual
|
||||
</select>
|
||||
<select id="selectPlanSeqNextVal" resultType="java.lang.Long">
|
||||
select SEQ_SEAL_CONTRACT_LAUNCH_PLAN.NEXTVAL from dual
|
||||
</select>
|
||||
<select id="selectLogSeqNextVal" resultType="java.lang.Long">
|
||||
select SEQ_SEAL_CONTRACT_LAUNCH_LOG.NEXTVAL from dual
|
||||
</select>
|
||||
|
||||
<select id="selectContractPage" resultMap="ContractLaunchResult">
|
||||
<include refid="mainColumns"/>
|
||||
<where>
|
||||
IS_DELETED = 'N'
|
||||
<if test="query.contractName != null and query.contractName != ''">
|
||||
and CONTRACT_NAME like CONCAT(CONCAT('%', #{query.contractName}), '%')
|
||||
</if>
|
||||
<if test="query.contractCode != null and query.contractCode != ''">
|
||||
and CONTRACT_CODE like CONCAT(CONCAT('%', #{query.contractCode}), '%')
|
||||
</if>
|
||||
<if test="query.contractType != null and query.contractType != ''">
|
||||
and CONTRACT_TYPE = #{query.contractType}
|
||||
</if>
|
||||
<if test="query.status != null and query.status != ''">
|
||||
and STATUS = #{query.status}
|
||||
</if>
|
||||
<if test="query.dateStart != null and query.dateStart != ''">
|
||||
and CREATE_TIME >= TO_DATE(#{query.dateStart} || ' 00:00:00', 'YYYY-MM-DD HH24:MI:SS')
|
||||
</if>
|
||||
<if test="query.dateEnd != null and query.dateEnd != ''">
|
||||
and CREATE_TIME <= TO_DATE(#{query.dateEnd} || ' 23:59:59', 'YYYY-MM-DD HH24:MI:SS')
|
||||
</if>
|
||||
</where>
|
||||
order by CREATE_TIME desc, ID desc
|
||||
</select>
|
||||
|
||||
<select id="selectContractById" resultMap="ContractLaunchResult">
|
||||
<include refid="mainColumns"/>
|
||||
where ID = #{id}
|
||||
and IS_DELETED = 'N'
|
||||
</select>
|
||||
|
||||
<select id="selectContractByContractSysId" resultMap="ContractLaunchResult">
|
||||
<include refid="mainColumns"/>
|
||||
where CONTRACT_SYS_ID = #{contractSysId}
|
||||
and IS_DELETED = 'N'
|
||||
</select>
|
||||
|
||||
<insert id="insertContract" parameterType="com.nbport.zgwl.contractlaunch.dto.ContractLaunchDto">
|
||||
insert into SEAL_CONTRACT_LAUNCH_MAIN (
|
||||
ID, CONTRACT_SYS_ID, CONTRACT_CODE, LAW_CONTRACT_CODE, LAW_CONTRACT_ID,
|
||||
CONTRACT_NAME, CONTRACT_TYPE, CONTRACT_TYPE_CODE, CONTRACT_SOURCE, CREATION_MODE,
|
||||
TEMPLATE_ID, TEMPLATE_CODE, TEMPLATE_NAME, STATUS, APPROVE_STATUS, APPROVE_MESSAGE,
|
||||
SEAL_CONTRACT_ID, SEAL_CONTRACT_STATUS, CONTRACT_AMOUNT, CURRENCY_NAME,
|
||||
CONTRACT_PERIOD_TYPE, PERIOD_EXPLAIN, EFFECTIVE_START, EFFECTIVE_END,
|
||||
PAYMENT_METHOD, PRIMARY_CONTENT, AMOUNT_EXPLAIN, VALUATION_MODE, SEAL_TYPE,
|
||||
TEXT_SOURCE, MANDATE_TYPE, CARGO_TYPE, ASSIST_DEPARTMENT_NAME, EXECUTOR_ACCOUNT,
|
||||
CREATOR_PHONE, SELF_CODE, MAIN_CONTRACT_CODE, SIGNING_SUBJECT_CODE, DATE_TYPE, IS_ADDIT, IS_ELECTRON,
|
||||
PAYMENT_DIRECTION, PUSH_URL, IS_MAJOR_CONTRACT, IS_OPEN_BIDDING, IS_YEAR_BUDGET, IS_SHARE,
|
||||
CONTRACT_NATURE, IS_SGAT, IS_NORMAL, IS_TERMINATED, IS_SINGLE_AGREEMENT,
|
||||
BIDDING_NO, OPEN_BIDDING_REMARK, CONTRACT_GIST_REMARK,
|
||||
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_OFFLINE_REASON,
|
||||
SIGN_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
|
||||
) values (
|
||||
#{id}, #{contractSysId}, #{contractCode}, #{lawContractCode}, #{lawContractId},
|
||||
#{contractName}, #{contractType}, #{contractTypeCode}, #{contractSource}, #{creationMode},
|
||||
#{templateId}, #{templateCode}, #{templateName}, #{status}, #{approveStatus}, #{approveMessage},
|
||||
#{sealContractId}, #{sealContractStatus}, #{contractAmount}, #{currencyName},
|
||||
#{contractPeriodType}, #{periodExplain}, #{effectiveStart}, #{effectiveEnd},
|
||||
#{paymentMethod}, #{primaryContent}, #{amountExplain}, #{valuationMode}, #{sealType},
|
||||
#{textSource}, #{mandateType}, #{cargoType}, #{assistDepartmentName}, #{executorAccount},
|
||||
#{creatorPhone}, #{selfCode}, #{mainContractCode}, #{signingSubjectCode}, #{dateType}, #{isAddit}, #{isElectron},
|
||||
#{paymentDirection}, #{pushUrl}, #{isMajorContract}, #{isOpenBidding}, #{isYearBudget}, #{isShare},
|
||||
#{contractNature}, #{isSgat}, #{isNormal}, #{isTerminated}, #{isSingleAgreement},
|
||||
#{biddingNo}, #{openBiddingRemark}, #{contractGistRemark},
|
||||
#{ewAmountType}, #{djAmount}, #{yjAmount}, #{yfkAmount}, #{bzjAmount}, #{bodySummary},
|
||||
#{contractTextFileName}, #{contractTextFilePath}, #{contractTextFileType}, #{contractTextFileSize},
|
||||
#{signedFileName}, #{signedFilePath}, #{signedFileType}, #{signedFileSize}, #{signedOfflineReason},
|
||||
#{signDate}, #{activeDate}, #{archiveDate}, #{archiveKeeper}, #{archiveKeeperUnit},
|
||||
#{archiveKeeperUnitCode}, #{invoiceDate}, #{receiveDate}, #{remindDays},
|
||||
#{initiator}, #{initiatorDept}, #{companyName}, #{orgId}, #{queryScope},
|
||||
#{createBy}, #{createTime}, #{updateBy}, #{updateTime}, #{isDeleted}, #{remark}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="updateContract" parameterType="com.nbport.zgwl.contractlaunch.dto.ContractLaunchDto">
|
||||
update SEAL_CONTRACT_LAUNCH_MAIN
|
||||
<trim prefix="set" suffixOverrides=",">
|
||||
LAW_CONTRACT_CODE = #{lawContractCode},
|
||||
LAW_CONTRACT_ID = #{lawContractId},
|
||||
CONTRACT_NAME = #{contractName},
|
||||
CONTRACT_TYPE = #{contractType},
|
||||
CONTRACT_TYPE_CODE = #{contractTypeCode},
|
||||
CONTRACT_SOURCE = #{contractSource},
|
||||
CREATION_MODE = #{creationMode},
|
||||
TEMPLATE_ID = #{templateId},
|
||||
TEMPLATE_CODE = #{templateCode},
|
||||
TEMPLATE_NAME = #{templateName},
|
||||
STATUS = #{status},
|
||||
APPROVE_STATUS = #{approveStatus},
|
||||
APPROVE_MESSAGE = #{approveMessage},
|
||||
SEAL_CONTRACT_ID = #{sealContractId},
|
||||
SEAL_CONTRACT_STATUS = #{sealContractStatus},
|
||||
CONTRACT_AMOUNT = #{contractAmount},
|
||||
CURRENCY_NAME = #{currencyName},
|
||||
CONTRACT_PERIOD_TYPE = #{contractPeriodType},
|
||||
PERIOD_EXPLAIN = #{periodExplain},
|
||||
EFFECTIVE_START = #{effectiveStart},
|
||||
EFFECTIVE_END = #{effectiveEnd},
|
||||
PAYMENT_METHOD = #{paymentMethod},
|
||||
PRIMARY_CONTENT = #{primaryContent},
|
||||
AMOUNT_EXPLAIN = #{amountExplain},
|
||||
VALUATION_MODE = #{valuationMode},
|
||||
SEAL_TYPE = #{sealType},
|
||||
TEXT_SOURCE = #{textSource},
|
||||
MANDATE_TYPE = #{mandateType},
|
||||
CARGO_TYPE = #{cargoType},
|
||||
ASSIST_DEPARTMENT_NAME = #{assistDepartmentName},
|
||||
EXECUTOR_ACCOUNT = #{executorAccount},
|
||||
CREATOR_PHONE = #{creatorPhone},
|
||||
SELF_CODE = #{selfCode},
|
||||
MAIN_CONTRACT_CODE = #{mainContractCode},
|
||||
SIGNING_SUBJECT_CODE = #{signingSubjectCode},
|
||||
DATE_TYPE = #{dateType},
|
||||
IS_ADDIT = #{isAddit},
|
||||
IS_ELECTRON = #{isElectron},
|
||||
PAYMENT_DIRECTION = #{paymentDirection},
|
||||
PUSH_URL = #{pushUrl},
|
||||
IS_MAJOR_CONTRACT = #{isMajorContract},
|
||||
IS_OPEN_BIDDING = #{isOpenBidding},
|
||||
IS_YEAR_BUDGET = #{isYearBudget},
|
||||
IS_SHARE = #{isShare},
|
||||
CONTRACT_NATURE = #{contractNature},
|
||||
IS_SGAT = #{isSgat},
|
||||
IS_NORMAL = #{isNormal},
|
||||
IS_TERMINATED = #{isTerminated},
|
||||
IS_SINGLE_AGREEMENT = #{isSingleAgreement},
|
||||
BIDDING_NO = #{biddingNo},
|
||||
OPEN_BIDDING_REMARK = #{openBiddingRemark},
|
||||
CONTRACT_GIST_REMARK = #{contractGistRemark},
|
||||
EW_AMOUNT_TYPE = #{ewAmountType},
|
||||
DJ_AMOUNT = #{djAmount},
|
||||
YJ_AMOUNT = #{yjAmount},
|
||||
YFK_AMOUNT = #{yfkAmount},
|
||||
BZJ_AMOUNT = #{bzjAmount},
|
||||
BODY_SUMMARY = #{bodySummary},
|
||||
CONTRACT_TEXT_FILE_NAME = #{contractTextFileName},
|
||||
CONTRACT_TEXT_FILE_PATH = #{contractTextFilePath},
|
||||
CONTRACT_TEXT_FILE_TYPE = #{contractTextFileType},
|
||||
CONTRACT_TEXT_FILE_SIZE = #{contractTextFileSize},
|
||||
SIGNED_FILE_NAME = #{signedFileName},
|
||||
SIGNED_FILE_PATH = #{signedFilePath},
|
||||
SIGNED_FILE_TYPE = #{signedFileType},
|
||||
SIGNED_FILE_SIZE = #{signedFileSize},
|
||||
SIGNED_OFFLINE_REASON = #{signedOfflineReason},
|
||||
SIGN_DATE = #{signDate},
|
||||
ACTIVE_DATE = #{activeDate},
|
||||
ARCHIVE_DATE = #{archiveDate},
|
||||
ARCHIVE_KEEPER = #{archiveKeeper},
|
||||
ARCHIVE_KEEPER_UNIT = #{archiveKeeperUnit},
|
||||
ARCHIVE_KEEPER_UNIT_CODE = #{archiveKeeperUnitCode},
|
||||
INVOICE_DATE = #{invoiceDate},
|
||||
RECEIVE_DATE = #{receiveDate},
|
||||
REMIND_DAYS = #{remindDays},
|
||||
INITIATOR = #{initiator},
|
||||
INITIATOR_DEPT = #{initiatorDept},
|
||||
COMPANY_NAME = #{companyName},
|
||||
ORG_ID = #{orgId},
|
||||
QUERY_SCOPE = #{queryScope},
|
||||
UPDATE_BY = #{updateBy},
|
||||
UPDATE_TIME = #{updateTime},
|
||||
IS_DELETED = #{isDeleted},
|
||||
REMARK = #{remark},
|
||||
</trim>
|
||||
where ID = #{id}
|
||||
and IS_DELETED = 'N'
|
||||
</update>
|
||||
|
||||
<update id="deleteContract">
|
||||
update SEAL_CONTRACT_LAUNCH_MAIN
|
||||
set IS_DELETED = 'Y',
|
||||
UPDATE_BY = #{updateBy},
|
||||
UPDATE_TIME = SYSDATE
|
||||
where ID = #{id}
|
||||
and IS_DELETED = 'N'
|
||||
</update>
|
||||
|
||||
<insert id="batchInsertParty">
|
||||
INSERT ALL
|
||||
<foreach collection="list" item="item">
|
||||
INTO SEAL_CONTRACT_LAUNCH_PARTY (
|
||||
ID, CONTRACT_ID, ROLE_CODE, ROLE_NAME, SORT_ORDER, PARTNER_ID, OPPOSITE_ID,
|
||||
COMPANY_NAME, COMPANY_TYPE, OPPOSITE_CHARACTER, CONTACT_NAME, CONTACT_PHONE,
|
||||
CONTACT_EMAIL, CONTACT_ADDRESS, REGISTERED_ADDRESS, LEGAL_REPRESENTATIVE,
|
||||
CREDIT_CODE, BANK_NAME, BANK_ACCOUNT, NATURAL_PERSON_ID_TYPE, NATURAL_PERSON_ID_NUMBER,
|
||||
IS_GROUP_INTERNAL, IS_HONG_KONG_MACAO_TAIWAN, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, IS_DELETED, REMARK
|
||||
) VALUES (
|
||||
#{item.id}, #{item.contractId}, #{item.roleCode}, #{item.roleName}, #{item.sortOrder}, #{item.partnerId}, #{item.oppositeId},
|
||||
#{item.companyName}, #{item.companyType}, #{item.oppositeCharacter}, #{item.contactName}, #{item.contactPhone},
|
||||
#{item.contactEmail}, #{item.contactAddress}, #{item.registeredAddress}, #{item.legalRepresentative},
|
||||
#{item.creditCode}, #{item.bankName}, #{item.bankAccount}, #{item.naturalPersonIdType}, #{item.naturalPersonIdNumber},
|
||||
#{item.isGroupInternal}, #{item.isHongKongMacaoTaiwan}, #{createBy}, SYSDATE, #{updateBy}, SYSDATE, 'N', #{item.remark}
|
||||
)
|
||||
</foreach>
|
||||
SELECT 1 FROM DUAL
|
||||
</insert>
|
||||
|
||||
<insert id="batchInsertFile">
|
||||
INSERT ALL
|
||||
<foreach collection="list" item="item">
|
||||
INTO SEAL_CONTRACT_LAUNCH_FILE (
|
||||
ID, CONTRACT_ID, FILE_CATEGORY, FILE_NAME, FILE_PATH, FILE_TYPE, FILE_SIZE,
|
||||
SORT_ORDER, CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, IS_DELETED, REMARK
|
||||
) VALUES (
|
||||
#{item.id}, #{item.contractId}, #{item.fileCategory}, #{item.fileName}, #{item.filePath}, #{item.fileType}, #{item.fileSize},
|
||||
#{item.sortOrder}, #{createBy}, SYSDATE, #{updateBy}, SYSDATE, 'N', #{item.remark}
|
||||
)
|
||||
</foreach>
|
||||
SELECT 1 FROM DUAL
|
||||
</insert>
|
||||
|
||||
<insert id="batchInsertPlan">
|
||||
INSERT ALL
|
||||
<foreach collection="list" item="item">
|
||||
INTO SEAL_CONTRACT_LAUNCH_PLAN (
|
||||
ID, CONTRACT_ID, PLAN_MATTER, PLAN_WHERE, PLAN_TIME, PLAN_DAY, PLAN_MONEY,
|
||||
PLAN_SUBJECT_CODE, PLAN_SUBJECT_NAME, PLAN_DETAIL, PLAN_STATUS,
|
||||
CREATE_BY, CREATE_TIME, UPDATE_BY, UPDATE_TIME, IS_DELETED, REMARK
|
||||
) VALUES (
|
||||
#{item.id}, #{item.contractId}, #{item.planMatter}, #{item.planWhere}, #{item.planTime}, #{item.planDay}, #{item.planMoney},
|
||||
#{item.planSubjectCode}, #{item.planSubjectName}, #{item.planDetail}, #{item.planStatus},
|
||||
#{createBy}, SYSDATE, #{updateBy}, SYSDATE, 'N', #{item.remark}
|
||||
)
|
||||
</foreach>
|
||||
SELECT 1 FROM DUAL
|
||||
</insert>
|
||||
|
||||
<insert id="insertLog" parameterType="com.nbport.zgwl.contractlaunch.dto.ContractLaunchLogDto">
|
||||
insert into SEAL_CONTRACT_LAUNCH_LOG (
|
||||
ID, CONTRACT_ID, ACTION_TYPE, ACTION_NAME, ACTION_STATUS, OPERATOR_NAME, OPERATOR_PHONE,
|
||||
ACTION_TIME, ACTION_CONTENT, CALLBACK_PAYLOAD, REMARK
|
||||
) values (
|
||||
#{id}, #{contractId}, #{actionType}, #{actionName}, #{actionStatus}, #{operatorName}, #{operatorPhone},
|
||||
#{actionTime}, #{actionContent}, #{callbackPayload}, #{remark}
|
||||
)
|
||||
</insert>
|
||||
|
||||
<update id="deletePartyByContractId">
|
||||
update SEAL_CONTRACT_LAUNCH_PARTY
|
||||
set IS_DELETED = 'Y',
|
||||
UPDATE_BY = #{updateBy},
|
||||
UPDATE_TIME = SYSDATE
|
||||
where CONTRACT_ID = #{contractId}
|
||||
and IS_DELETED = 'N'
|
||||
</update>
|
||||
|
||||
<update id="deleteFileByContractId">
|
||||
update SEAL_CONTRACT_LAUNCH_FILE
|
||||
set IS_DELETED = 'Y',
|
||||
UPDATE_BY = #{updateBy},
|
||||
UPDATE_TIME = SYSDATE
|
||||
where CONTRACT_ID = #{contractId}
|
||||
and IS_DELETED = 'N'
|
||||
</update>
|
||||
|
||||
<update id="deleteFileByContractIdAndCategory">
|
||||
update SEAL_CONTRACT_LAUNCH_FILE
|
||||
set IS_DELETED = 'Y',
|
||||
UPDATE_BY = #{updateBy},
|
||||
UPDATE_TIME = SYSDATE
|
||||
where CONTRACT_ID = #{contractId}
|
||||
and FILE_CATEGORY = #{fileCategory}
|
||||
and IS_DELETED = 'N'
|
||||
</update>
|
||||
|
||||
<update id="deletePlanByContractId">
|
||||
update SEAL_CONTRACT_LAUNCH_PLAN
|
||||
set IS_DELETED = 'Y',
|
||||
UPDATE_BY = #{updateBy},
|
||||
UPDATE_TIME = SYSDATE
|
||||
where CONTRACT_ID = #{contractId}
|
||||
and IS_DELETED = 'N'
|
||||
</update>
|
||||
|
||||
<select id="selectPartyByContractIds" resultMap="PartyResult">
|
||||
select ID, CONTRACT_ID, ROLE_CODE, ROLE_NAME, SORT_ORDER, PARTNER_ID, OPPOSITE_ID,
|
||||
COMPANY_NAME, COMPANY_TYPE, OPPOSITE_CHARACTER, CONTACT_NAME, CONTACT_PHONE,
|
||||
CONTACT_EMAIL, CONTACT_ADDRESS, REGISTERED_ADDRESS, LEGAL_REPRESENTATIVE,
|
||||
CREDIT_CODE, BANK_NAME, BANK_ACCOUNT, NATURAL_PERSON_ID_TYPE, NATURAL_PERSON_ID_NUMBER,
|
||||
IS_GROUP_INTERNAL, IS_HONG_KONG_MACAO_TAIWAN, REMARK
|
||||
from SEAL_CONTRACT_LAUNCH_PARTY
|
||||
where IS_DELETED = 'N'
|
||||
and CONTRACT_ID in
|
||||
<foreach collection="contractIds" item="contractId" open="(" separator="," close=")">
|
||||
#{contractId}
|
||||
</foreach>
|
||||
order by CONTRACT_ID asc, SORT_ORDER asc, ID asc
|
||||
</select>
|
||||
|
||||
<select id="selectFileByContractIds" resultMap="FileResult">
|
||||
select ID, CONTRACT_ID, FILE_CATEGORY, FILE_NAME, FILE_PATH, FILE_TYPE, FILE_SIZE, SORT_ORDER, REMARK
|
||||
from SEAL_CONTRACT_LAUNCH_FILE
|
||||
where IS_DELETED = 'N'
|
||||
and CONTRACT_ID in
|
||||
<foreach collection="contractIds" item="contractId" open="(" separator="," close=")">
|
||||
#{contractId}
|
||||
</foreach>
|
||||
order by CONTRACT_ID asc, SORT_ORDER asc, ID asc
|
||||
</select>
|
||||
|
||||
<select id="selectPlanByContractIds" resultMap="PlanResult">
|
||||
select ID, CONTRACT_ID, PLAN_MATTER, PLAN_WHERE, PLAN_TIME, PLAN_DAY, PLAN_MONEY,
|
||||
PLAN_SUBJECT_CODE, PLAN_SUBJECT_NAME, PLAN_DETAIL, PLAN_STATUS, REMARK
|
||||
from SEAL_CONTRACT_LAUNCH_PLAN
|
||||
where IS_DELETED = 'N'
|
||||
and CONTRACT_ID in
|
||||
<foreach collection="contractIds" item="contractId" open="(" separator="," close=")">
|
||||
#{contractId}
|
||||
</foreach>
|
||||
order by CONTRACT_ID asc, PLAN_TIME asc, ID asc
|
||||
</select>
|
||||
|
||||
<select id="selectLogByContractIds" resultMap="LogResult">
|
||||
select ID, CONTRACT_ID, ACTION_TYPE, ACTION_NAME, ACTION_STATUS, OPERATOR_NAME, OPERATOR_PHONE,
|
||||
ACTION_TIME, ACTION_CONTENT, CALLBACK_PAYLOAD, REMARK
|
||||
from SEAL_CONTRACT_LAUNCH_LOG
|
||||
where CONTRACT_ID in
|
||||
<foreach collection="contractIds" item="contractId" open="(" separator="," close=")">
|
||||
#{contractId}
|
||||
</foreach>
|
||||
order by CONTRACT_ID asc, ACTION_TIME desc, ID desc
|
||||
</select>
|
||||
|
||||
</mapper>
|
||||
@@ -30,7 +30,7 @@
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectTemplateColumns">
|
||||
select id, template_code, template_name, source, contract_type, self_party_role,
|
||||
select id, template_code, template_name, source, contract_type,
|
||||
version, status, variable_count, description, usage_tip,
|
||||
template_file_name, template_file_path,
|
||||
publish_org_ids_json, publish_org_names_json, variable_mappings_json,
|
||||
@@ -73,7 +73,7 @@
|
||||
<insert id="insertTemplate" parameterType="com.nbport.zgwl.manifest.dto.ContractTemplateDto">
|
||||
insert into contract_template_manage
|
||||
(
|
||||
id, template_code, template_name, source, contract_type, self_party_role,
|
||||
id, template_code, template_name, source, contract_type,
|
||||
version, status, variable_count, description, usage_tip,
|
||||
template_file_name, template_file_path,
|
||||
publish_org_ids_json, publish_org_names_json, variable_mappings_json,
|
||||
|
||||
@@ -12,8 +12,14 @@
|
||||
|
||||
<resultMap id="PartnerManageResult" type="com.nbport.zgwl.partner.dto.PartnerManageDto">
|
||||
<id property="customerSysid" column="CUSTOMER_SYSID"/>
|
||||
<result property="customerRegno" column="CUSTOMER_REGNO"/>
|
||||
<result property="customerNo" column="CUSTOMER_NO"/>
|
||||
<result property="customerNameC" column="CUSTOMER_NAME_C"/>
|
||||
<result property="customerTaxno" column="CUSTOMER_TAXNO"/>
|
||||
<result property="customerAddress" column="CUSTOMER_ADDRESS"/>
|
||||
<result property="officephone" column="OFFICEPHONE"/>
|
||||
<result property="customerBank" column="CUSTOMER_BANK"/>
|
||||
<result property="customerBankaccount" column="CUSTOMER_BANKACCOUNT"/>
|
||||
<result property="customerRegaddr" column="CUSTOMER_REGADDR"/>
|
||||
<result property="emailAddress" column="EMAIL_ADDRESS"/>
|
||||
<result property="oppositeId" column="OPPOSITE_ID"/>
|
||||
@@ -60,7 +66,8 @@
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectPartnerColumns">
|
||||
select CUSTOMER_SYSID, CUSTOMER_NAME_C, CUSTOMER_TAXNO, CUSTOMER_REGADDR,
|
||||
select CUSTOMER_SYSID, CUSTOMER_REGNO, CUSTOMER_NO, CUSTOMER_NAME_C, CUSTOMER_TAXNO,
|
||||
CUSTOMER_ADDRESS, OFFICEPHONE, CUSTOMER_BANK, CUSTOMER_BANKACCOUNT, CUSTOMER_REGADDR,
|
||||
EMAIL_ADDRESS, OPPOSITE_ID, OPPOSITE_CHARACTER, GAT_FLAG, GROUP_FLAG,
|
||||
COUNTRY, COUNTRY_NAME, LEGAL_PERSON_NAME, CERTIFICATE_TYPE,
|
||||
CERTIFICATE_NUM, TIN_CODE, REGISTERED_CAPITAL, REG_CAPITAL,
|
||||
|
||||
Reference in New Issue
Block a user