# 签约功能生命周期详解 - 第三部分 ## 4. 实体类层 (Entity/Model) ### 4.1 合同实体 ```java @Data @Table(name = "t_contract") public class Contract implements Serializable { /** * 合同ID */ @Id private String contractId; /** * 合同名称 */ private String contractName; /** * 合同类型 */ @Enumerated(EnumType.STRING) private ContractType contractType; /** * 合同状态 */ @Enumerated(EnumType.STRING) private ContractStatus contractStatus; /** * 甲方企业ID */ private String partyAId; /** * 甲方企业名称 */ private String partyAName; /** * 乙方企业ID */ private String partyBId; /** * 乙方企业名称 */ private String partyBName; /** * 合同金额 */ private BigDecimal contractAmount; /** * 合同期限(天) */ private Integer contractPeriod; /** * 开始日期 */ private Date startDate; /** * 结束日期 */ private Date endDate; /** * 合同描述 */ private String description; /** * 合同文件ID */ private String contractFileId; /** * 已签署合同文件ID */ private String signedContractFileId; /** * 创建用户 */ private String createUser; /** * 创建时间 */ private Date createTime; /** * 更新用户 */ private String updateUser; /** * 更新时间 */ private Date updateTime; } ``` ### 4.2 合同签署任务实体 ```java @Data @Table(name = "t_contract_sign_task") public class ContractSignTask implements Serializable { /** * 任务ID */ @Id private String taskId; /** * 合同ID */ private String contractId; /** * 企业ID */ private String enterpriseId; /** * 企业名称 */ private String enterpriseName; /** * 签署状态 */ @Enumerated(EnumType.STRING) private SignStatus signStatus; /** * 签署人姓名 */ private String signerName; /** * 签署人职位 */ private String signerPosition; /** * 签署方法 */ @Enumerated(EnumType.STRING) private SignMethod signMethod; /** * 数字签名 */ private String signature; /** * 签署时间 */ private Date signTime; /** * 创建时间 */ private Date createTime; /** * 更新时间 */ private Date updateTime; } ``` ### 4.3 合同操作日志实体 ```java @Data @Table(name = "t_contract_log") public class ContractLog implements Serializable { /** * 日志ID */ @Id private String logId; /** * 合同ID */ private String contractId; /** * 操作类型 */ @Enumerated(EnumType.STRING) private ContractOperationType operationType; /** * 操作描述 */ private String operationDesc; /** * 操作用户 */ private String operationUser; /** * 操作时间 */ private Date operationTime; /** * IP地址 */ private String ip; } ``` ### 4.4 枚举类 #### 4.4.1 合同状态枚举 ```java /** * 合同状态枚举 */ public enum ContractStatus { /** * 草稿 */ DRAFT, /** * 待签署 */ PENDING_SIGNING, /** * 已签署 */ SIGNED, /** * 已完成 */ COMPLETED, /** * 已取消 */ CANCELED, /** * 已过期 */ EXPIRED } ``` #### 4.4.2 合同类型枚举 ```java /** * 合同类型枚举 */ public enum ContractType { /** * 采购合同 */ PURCHASE, /** * 销售合同 */ SALES, /** * 融资合同 */ FINANCING, /** * 一般合同 */ GENERAL } ``` #### 4.4.3 签署状态枚举 ```java /** * 签署状态枚举 */ public enum SignStatus { /** * 待签署 */ PENDING, /** * 已签署 */ SIGNED, /** * 已拒绝 */ REJECTED } ``` #### 4.4.4 签署方法枚举 ```java /** * 签署方法枚举 */ public enum SignMethod { /** * 数字签名 */ DIGITAL_SIGNATURE, /** * 电子签章 */ ELECTRONIC_SEAL, /** * 手写签名 */ HANDWRITTEN } ``` #### 4.4.5 合同操作类型枚举 ```java /** * 合同操作类型枚举 */ public enum ContractOperationType { /** * 创建 */ CREATE, /** * 提交签署 */ SUBMIT, /** * 签署 */ SIGN, /** * 拒绝签署 */ REJECT, /** * 取消 */ CANCEL, /** * 完成 */ COMPLETE, /** * 下载 */ DOWNLOAD, /** * 查看 */ VIEW } ``` ## 5. 异常处理 ### 5.1 合同业务异常 ```java public class ContractBusinessException extends BusinessException { /** * 合同不存在 */ public static final int CONTRACT_NOT_FOUND = 4001; /** * 合同状态错误 */ public static final int CONTRACT_STATUS_ERROR = 4002; /** * 无权操作 */ public static final int NO_PERMISSION = 4003; /** * 签署信息错误 */ public static final int SIGN_INFO_ERROR = 4004; /** * 签署任务不存在 */ public static final int SIGN_TASK_NOT_FOUND = 4005; /** * 构造函数 * * @param code 错误码 * @param message 错误信息 */ public ContractBusinessException(int code, String message) { super(code, message); } } ``` ### 5.2 合同异常处理器 ```java @RestControllerAdvice @Slf4j public class ContractExceptionHandler { /** * 处理合同业务异常 */ @ExceptionHandler(ContractBusinessException.class) public ApiResult handleContractBusinessException(ContractBusinessException ex) { log.warn("合同业务异常: {}", ex.getMessage()); return ApiResult.failed(ex.getCode(), ex.getMessage()); } /** * 处理合同文件异常 */ @ExceptionHandler(ContractFileException.class) public ApiResult handleContractFileException(ContractFileException ex) { log.error("合同文件处理异常", ex); return ApiResult.failed(ex.getCode(), ex.getMessage()); } } ``` ## 6. 缓存层 ### 6.1 合同缓存服务 ```java @Service @RequiredArgsConstructor @Slf4j public class ContractCacheServiceImpl implements ContractCacheService { private final RedisTemplate redisTemplate; private static final String CONTRACT_CACHE_KEY_PREFIX = "contract:detail:"; private static final long CONTRACT_CACHE_EXPIRE_TIME = 3600L; // 一小时 @Override public void cacheContract(Contract contract) { if (contract == null) { return; } String key = CONTRACT_CACHE_KEY_PREFIX + contract.getContractId(); redisTemplate.opsForValue().set(key, contract, CONTRACT_CACHE_EXPIRE_TIME, TimeUnit.SECONDS); log.debug("缓存合同信息, ID: {}", contract.getContractId()); } @Override public Contract getContractFromCache(String contractId) { String key = CONTRACT_CACHE_KEY_PREFIX + contractId; Object cachedContract = redisTemplate.opsForValue().get(key); if (cachedContract instanceof Contract) { log.debug("从缓存获取合同信息, ID: {}", contractId); return (Contract) cachedContract; } return null; } @Override public void removeContractCache(String contractId) { String key = CONTRACT_CACHE_KEY_PREFIX + contractId; redisTemplate.delete(key); log.debug("移除合同缓存, ID: {}", contractId); } } ``` ## 7. 完整签约流程时序 ``` ┌──────────┐ ┌───────────────┐ ┌─────────────┐ ┌──────────┐ ┌───────────┐ ┌─────────┐ │ 客户端 │ │ 控制器层 │ │ 服务层 │ │ 数据访问层│ │ 文件服务 │ │ 缓存层 │ └────┬─────┘ └───────┬───────┘ └──────┬──────┘ └────┬─────┘ └─────┬─────┘ └────┬────┘ │ │ │ │ │ │ │ 1.创建合同请求 │ │ │ │ │ │──────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │ 2.调用创建合同服务 │ │ │ │ │ │────────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │ 3.校验企业信息 │ │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ │ 4.返回校验结果 │ │ │ │ │ │<────────────────│ │ │ │ │ │ │ │ │ │ │ │ 5.保存合同基本信息 │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ │ 6.生成合同文件 │ │ │ │ │ │──────────────────────────────────>│ │ │ │ │ │ │ │ │ │ │ 7.返回文件ID │ │ │ │ │ │<──────────────────────────────────│ │ │ │ │ │ │ │ │ │ │ 8.更新合同文件ID│ │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ │ 9.缓存合同信息 │ │ │ │ │ │──────────────────────────────────────────────────>│ │ │ │ │ │ │ │ │ 10.返回创建结果 │ │ │ │ │ │<────────────────────│ │ │ │ │ │ │ │ │ │ │ 11.返回合同ID和下载链接 │ │ │ │ │<──────────────────│ │ │ │ │ │ │ │ │ │ │ │ 12.提交合同签署请求 │ │ │ │ │──────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │ 13.调用提交签署服务 │ │ │ │ │ │────────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │ 14.查询合同信息 │ │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ │ 15.更新合同状态 │ │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ │ 16.创建签署任务 │ │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ 17.返回提交结果 │ │ │ │ │ │<────────────────────│ │ │ │ │ │ │ │ │ │ │ 18.返回签署链接 │ │ │ │ │ │<──────────────────│ │ │ │ │ │ │ │ │ │ │ │ 19.甲方签署请求 │ │ │ │ │ │──────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │ 20.调用签署服务 │ │ │ │ │ │────────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │ 21.验证签署权限 │ │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ │ 22.创建数字签名 │ │ │ │ │ │──────────────────────────────────>│ │ │ │ │ │ │ │ │ │ │ 23.更新签署状态 │ │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ 24.返回签署结果 │ │ │ │ │ │<────────────────────│ │ │ │ │ │ │ │ │ │ │ 25.返回甲方签署成功 │ │ │ │ │<──────────────────│ │ │ │ │ │ │ │ │ │ │ │ 26.乙方签署请求 │ │ │ │ │ │──────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │ 27.调用签署服务 │ │ │ │ │ │────────────────────>│ │ │ │ │ │ │ │ │ │ │ │ │ 28.验证签署权限 │ │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ │ 29.创建数字签名 │ │ │ │ │ │──────────────────────────────────>│ │ │ │ │ │ │ │ │ │ │ 30.更新签署状态 │ │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ │ 31.检查是否全部签署 │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ │ 32.更新合同为已签署 │ │ │ │ │────────────────>│ │ │ │ │ │ │ │ │ │ │ │ 33.生成签署版合同 │ │ │ │ │──────────────────────────────────>│ │ │ │ │ │ │ │ │ │ 34.返回签署结果 │ │ │ │ │ │<────────────────────│ │ │ │ │ │ │ │ │ │ │ 35.返回合同签署完成 │ │ │ │ │<──────────────────│ │ │ │ │ │ │ │ │ │ │ ``` ## 8. 安全控制 ### 8.1 合同接口授权配置 ```java @Configuration @EnableWebSecurity @EnableMethodSecurity @RequiredArgsConstructor public class ContractSecurityConfig { /** * 配置合同相关接口的安全规则 */ @Bean public SecurityFilterChain contractFilterChain(HttpSecurity http) throws Exception { http .authorizeHttpRequests(authorize -> authorize // 创建合同接口,企业用户可访问 .requestMatchers(HttpMethod.POST, "/api/v1/contract/create").hasRole("ENTERPRISE") // 提交签署接口,企业用户可访问 .requestMatchers(HttpMethod.POST, "/api/v1/contract/*/submit").hasRole("ENTERPRISE") // 签署合同接口,企业用户可访问 .requestMatchers(HttpMethod.POST, "/api/v1/contract/*/sign").hasRole("ENTERPRISE") // 查询合同详情,企业用户和银行用户可访问 .requestMatchers(HttpMethod.GET, "/api/v1/contract/*").hasAnyRole("ENTERPRISE", "BANK") // 查询合同列表,企业用户和银行用户可访问 .requestMatchers(HttpMethod.GET, "/api/v1/contract/list").hasAnyRole("ENTERPRISE", "BANK") // 下载合同文件,企业用户和银行用户可访问 .requestMatchers(HttpMethod.GET, "/api/v1/contract/download/**").hasAnyRole("ENTERPRISE", "BANK") ); return http.build(); } } ``` ## 9. 完整签约功能总结 电子合同签署功能是供应链金融平台中的核心功能之一,为供应链参与方提供了便捷、高效、合法的合同签署方式。本文档详细描述了从合同创建到最终签署的完整生命周期,包括: 1. **控制器层**:负责接收HTTP请求,进行初步参数校验,调用服务层处理业务逻辑,并将处理结果返回给客户端。 2. **服务层**:包含核心业务逻辑,如合同创建、提交签署、签署处理等。 3. **数据访问层**:负责与数据库交互,提供数据持久化服务。 4. **实体类层**:定义了系统中的核心数据模型,如合同、签署任务等。 5. **异常处理**:统一处理业务异常,提供友好的错误信息。 6. **缓存层**:优化系统性能,减少数据库访问。 7. **安全控制**:确保接口安全可控,防止未授权访问。 整个签约流程基于数字签名技术,确保了合同的法律效力和防篡改性。同时,系统通过完善的日志记录和状态追踪,保证了合同处理过程的透明性和可追溯性。