输入文件:
- 租赁任务考核_2026年{1,2,3}月.xlsx (考核源数据)
- {1,2}月.xlsx (客户盈亏表)
- 车辆里程考核与奖金发放规则(V.1.2).docx
输出文件:
- 里程任务考核_{1,2,3}月核算.xlsx (月度核算结果)
- 里程任务考核_Q1汇总.xlsx (含车辆台账)
- 3月客户盈亏表(待填写).xlsx (模版)
.claude_memory: 项目记忆(规则/偏好/架构/测试车辆)
.claude_plans: 历次计划文件
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
21 KiB
21 KiB
车辆租赁合同模块实施计划
Context(背景)
为什么需要这个变更
车辆租赁业务是 OneOS 系统的核心业务模块,需要管理与客户签订的车辆租赁合同,包括合同信息、车辆订单、服务项目、被授权人、审批流程等。该模块需要与 BPM 工作流引擎深度集成,实现合同的审批流转。
问题或需求
- 业务需求:管理车辆租赁合同的全生命周期(创建→审批→执行→到期→续签/终止)
- 审批流程:4级审批(业务部主管→事业部主管→财务部→法务部)
- 复杂关联:合同关联客户、车辆、服务项目、被授权人、附件等多个实体
- 特殊业务:续签合同、转正式合同、变更为三方合同、新增车辆等
- 状态管理:审批状态 × 合同状态的复杂状态机
预期结果
构建一个完整的车辆租赁合同管理模块,支持合同的 CRUD、审批流程、特殊业务操作,并与现有的客户管理、车辆管理、BPM 工作流模块无缝集成。
架构设计
整体架构
Controller (REST API)
↓
Service (业务逻辑)
↓
├── Mapper (数据访问)
├── BpmProcessInstanceApi (流程启动)
└── FileApi (附件上传)
↓
BpmProcessInstanceStatusEventListener (流程状态监听)
↓
Service (更新合同状态)
模块结构
yudao-module-asset/yudao-module-asset-server/
├── controller/admin/contract/
│ └── ContractController.java
├── service/contract/
│ ├── ContractService.java
│ ├── ContractServiceImpl.java
│ └── listener/
│ └── ContractBpmListener.java
├── dal/
│ ├── dataobject/contract/
│ │ ├── ContractDO.java
│ │ ├── ContractVehicleDO.java
│ │ ├── ContractVehicleServiceDO.java
│ │ ├── ContractAuthorizedDO.java
│ │ ├── ContractAttachmentDO.java
│ │ └── ContractChangeHistoryDO.java
│ └── mysql/contract/
│ ├── ContractMapper.java
│ ├── ContractVehicleMapper.java
│ ├── ContractVehicleServiceMapper.java
│ ├── ContractAuthorizedMapper.java
│ ├── ContractAttachmentMapper.java
│ └── ContractChangeHistoryMapper.java
├── controller/admin/contract/vo/
│ ├── ContractBaseVO.java
│ ├── ContractSaveReqVO.java
│ ├── ContractRespVO.java
│ ├── ContractPageReqVO.java
│ ├── ContractDetailRespVO.java
│ ├── ContractVehicleVO.java
│ ├── ContractVehicleServiceVO.java
│ └── ContractAuthorizedVO.java
├── convert/contract/
│ └── ContractConvert.java
└── enums/
├── ContractTypeEnum.java
├── ContractApprovalStatusEnum.java
└── ContractStatusEnum.java
数据库表设计
1. asset_contract(合同主表)
CREATE TABLE `asset_contract` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
-- 合同基本信息
`contract_code` VARCHAR(50) NOT NULL COMMENT '合同编码',
`contract_type` TINYINT NOT NULL DEFAULT 1 COMMENT '合同类型(1=试用 2=正式)',
`project_name` VARCHAR(200) NOT NULL COMMENT '项目名称',
`start_date` DATE NOT NULL COMMENT '生效日期',
`end_date` DATE NOT NULL COMMENT '结束日期',
`payment_method` VARCHAR(50) COMMENT '付款方式',
`payment_cycle` VARCHAR(50) COMMENT '付款周期',
`signing_company` VARCHAR(200) COMMENT '签约公司(乙方)',
`delivery_province` VARCHAR(50) COMMENT '交车省份',
`delivery_city` VARCHAR(50) COMMENT '交车城市',
`delivery_location` VARCHAR(255) COMMENT '交车地点',
`remark` VARCHAR(1000) COMMENT '备注',
-- 甲方客户信息(关联 asset_customer)
`customer_id` BIGINT NOT NULL COMMENT '客户ID',
`customer_name` VARCHAR(200) NOT NULL COMMENT '客户名称(冗余)',
-- 丙方客户信息(三方合同,可选)
`third_party_enabled` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否三方合同',
`third_party_customer_id` BIGINT COMMENT '丙方客户ID',
`third_party_name` VARCHAR(200) COMMENT '丙方名称',
-- 业务信息
`business_dept_id` BIGINT NOT NULL COMMENT '业务部门ID',
`business_manager_id` BIGINT NOT NULL COMMENT '业务负责人ID',
-- 审批状态
`approval_status` TINYINT NOT NULL DEFAULT 0 COMMENT '审批状态(0=草稿 1=审批中 2=审批通过 3=审批拒绝 4=已撤回)',
`bpm_instance_id` VARCHAR(64) COMMENT 'BPM流程实例ID',
-- 合同状态
`contract_status` TINYINT NOT NULL DEFAULT 0 COMMENT '合同状态(0=草稿 1=待生效 2=进行中 3=已到期 4=已终止 5=已续签)',
`effective_time` DATETIME COMMENT '实际生效时间',
`terminate_time` DATETIME COMMENT '终止时间',
`terminate_reason` VARCHAR(500) COMMENT '终止原因',
-- 续签信息
`renewed_contract_id` BIGINT COMMENT '续签后的新合同ID',
`original_contract_id` BIGINT COMMENT '原合同ID(如果是续签合同)',
-- 系统字段
`creator` VARCHAR(64) DEFAULT '' COMMENT '创建者',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_contract_code` (`contract_code`, `deleted`),
INDEX `idx_customer_id` (`customer_id`),
INDEX `idx_approval_status` (`approval_status`),
INDEX `idx_contract_status` (`contract_status`),
INDEX `idx_business_dept` (`business_dept_id`),
INDEX `idx_start_date` (`start_date`),
INDEX `idx_end_date` (`end_date`),
INDEX `idx_create_time` (`create_time`),
INDEX `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='车辆租赁合同表';
2. asset_contract_vehicle(车辆租赁订单)
CREATE TABLE `asset_contract_vehicle` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`contract_id` BIGINT NOT NULL COMMENT '合同ID',
`vehicle_id` BIGINT COMMENT '车辆ID(关联 asset_vehicle_base)',
`brand` VARCHAR(100) NOT NULL COMMENT '品牌',
`model` VARCHAR(100) NOT NULL COMMENT '型号',
`plate_no` VARCHAR(20) COMMENT '车牌号',
`vin` VARCHAR(50) COMMENT 'VIN码',
`month_rent` DECIMAL(10,2) NOT NULL COMMENT '月租金(元)',
`deposit` DECIMAL(10,2) NOT NULL COMMENT '保证金(元)',
`vehicle_status` TINYINT DEFAULT 0 COMMENT '车辆状态(0=待交车 1=已交车 2=已退车)',
`actual_delivery_time` DATETIME COMMENT '实际交车时间',
`delivery_person` VARCHAR(50) COMMENT '交车人',
`remark` VARCHAR(500) COMMENT '备注',
`creator` VARCHAR(64) DEFAULT '' COMMENT '创建者',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`),
INDEX `idx_contract_id` (`contract_id`),
INDEX `idx_vehicle_id` (`vehicle_id`),
INDEX `idx_plate_no` (`plate_no`),
INDEX `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='合同车辆租赁订单表';
3. asset_contract_vehicle_service(服务项目)
CREATE TABLE `asset_contract_vehicle_service` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`contract_vehicle_id` BIGINT NOT NULL COMMENT '合同车辆ID',
`service_name` VARCHAR(100) NOT NULL COMMENT '服务项目名称',
`service_fee` DECIMAL(10,2) NOT NULL COMMENT '服务费用(元)',
`effective_date` DATE COMMENT '生效日期',
`creator` VARCHAR(64) DEFAULT '' COMMENT '创建者',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`),
INDEX `idx_contract_vehicle_id` (`contract_vehicle_id`),
INDEX `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='合同车辆服务项目表';
4. asset_contract_authorized(被授权人)
CREATE TABLE `asset_contract_authorized` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`contract_id` BIGINT NOT NULL COMMENT '合同ID',
`name` VARCHAR(50) NOT NULL COMMENT '姓名',
`phone` VARCHAR(20) NOT NULL COMMENT '电话',
`id_card` VARCHAR(18) NOT NULL COMMENT '身份证号',
`creator` VARCHAR(64) DEFAULT '' COMMENT '创建者',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`),
INDEX `idx_contract_id` (`contract_id`),
INDEX `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='合同被授权人表';
5. asset_contract_attachment(合同附件)
CREATE TABLE `asset_contract_attachment` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`contract_id` BIGINT NOT NULL COMMENT '合同ID',
`attachment_type` TINYINT NOT NULL COMMENT '附件类型(1=合同原件 2=盖章合同)',
`file_id` BIGINT NOT NULL COMMENT '文件ID(关联 infra_file)',
`file_name` VARCHAR(255) NOT NULL COMMENT '文件名称',
`file_url` VARCHAR(500) NOT NULL COMMENT '文件URL',
`file_size` BIGINT COMMENT '文件大小(字节)',
`upload_time` DATETIME NOT NULL COMMENT '上传时间',
`uploader` VARCHAR(64) COMMENT '上传人',
`creator` VARCHAR(64) DEFAULT '' COMMENT '创建者',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`updater` VARCHAR(64) DEFAULT '' COMMENT '更新者',
`update_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`),
INDEX `idx_contract_id` (`contract_id`),
INDEX `idx_file_id` (`file_id`),
INDEX `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='合同附件表';
6. asset_contract_change_history(变更历史)
CREATE TABLE `asset_contract_change_history` (
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`contract_id` BIGINT NOT NULL COMMENT '合同ID',
`change_type` VARCHAR(50) NOT NULL COMMENT '变更类型(保存/提交审批/审批通过/审批驳回/撤回/终止/续签/转正式/变更三方/新增车辆等)',
`change_content` VARCHAR(1000) COMMENT '变更内容',
`operator` VARCHAR(64) NOT NULL COMMENT '操作人',
`operate_time` DATETIME NOT NULL COMMENT '操作时间',
`creator` VARCHAR(64) DEFAULT '' COMMENT '创建者',
`create_time` DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`deleted` BIT(1) NOT NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` BIGINT NOT NULL DEFAULT 0 COMMENT '租户编号',
PRIMARY KEY (`id`),
INDEX `idx_contract_id` (`contract_id`),
INDEX `idx_operate_time` (`operate_time`),
INDEX `idx_tenant_id` (`tenant_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='合同变更历史表';
BPM 集成方案
流程定义
- 流程定义 Key:
rental_contract_approval - 流程名称: 车辆租赁合同审批
- 审批节点:
- 业务部主管审批
- 事业部主管审批
- 财务部审批
- 法务部审批(上传盖章合同)
流程变量
Map<String, Object> variables = new HashMap<>();
variables.put("contractId", contractId);
variables.put("contractCode", contractCode);
variables.put("contractType", contractType);
variables.put("customerName", customerName);
variables.put("projectName", projectName);
variables.put("totalAmount", totalAmount);
variables.put("businessDeptId", businessDeptId);
variables.put("businessManagerId", businessManagerId);
候选人策略
- 业务部主管: 根据
businessDeptId动态分配(部门主管角色) - 事业部主管: 固定角色
BUSINESS_DIRECTOR - 财务部: 财务部角色
FINANCE_DEPT - 法务部: 法务部角色
LEGAL_DEPT
事件监听器
@Component
public class ContractBpmListener {
@Resource
private ContractService contractService;
@EventListener
public void onProcessInstanceStatusChange(BpmProcessInstanceStatusEvent event) {
// 只处理租赁合同审批流程
if (!"rental_contract_approval".equals(event.getProcessDefinitionKey())) {
return;
}
Long contractId = Long.parseLong(event.getBusinessKey());
switch (event.getStatus()) {
case APPROVE: // 审批通过
contractService.handleApprovalApproved(contractId, event.getResult());
break;
case REJECT: // 审批驳回
contractService.handleApprovalRejected(contractId, event.getResult());
break;
case CANCEL: // 取消/撤回
contractService.handleApprovalCancelled(contractId);
break;
}
}
}
API 接口设计
基础 CRUD 接口
POST /asset/contract/create - 创建合同
PUT /asset/contract/update - 更新合同
DELETE /asset/contract/delete - 删除合同
GET /asset/contract/get - 获取合同详情
GET /asset/contract/page - 分页查询合同
审批相关接口
POST /asset/contract/submit - 提交审批
POST /asset/contract/withdraw - 撤回合同
GET /asset/contract/approval-history - 审批历史
特殊业务接口
POST /asset/contract/terminate - 终止合同
POST /asset/contract/renew - 续签合同
POST /asset/contract/convert-formal - 转正式合同
POST /asset/contract/convert-tripartite - 变更为三方合同
POST /asset/contract/add-vehicle - 新增车辆
查询接口
GET /asset/contract/change-history - 变更历史
GET /asset/contract/vehicle/list - 合同车辆列表
GET /asset/contract/authorized/list - 被授权人列表
GET /asset/contract/attachment/list - 合同附件列表
状态机设计
审批状态(approval_status)
0 - 草稿(DRAFT)
1 - 审批中(APPROVING)
2 - 审批通过(APPROVED)
3 - 审批拒绝(REJECTED)
4 - 已撤回(WITHDRAWN)
合同状态(contract_status)
0 - 草稿(DRAFT)
1 - 待生效(PENDING)
2 - 进行中(IN_PROGRESS)
3 - 已到期(EXPIRED)
4 - 已终止(TERMINATED)
5 - 已续签(RENEWED)
状态流转规则
审批状态流转:
草稿 → 审批中 → 审批通过
↓ ↓
已撤回 审批拒绝
合同状态流转:
草稿 → 待生效 → 进行中 → 已到期 → 已续签
↓
已终止
状态与操作关系矩阵
| 操作 | 草稿 | 审批中 | 审批通过 | 审批拒绝 | 已撤回 |
|---|---|---|---|---|---|
| 编辑 | ✓ | ✗ | ✗ | ✓ | ✓ |
| 删除 | ✓ | ✗ | ✗ | ✓ | ✓ |
| 提交审批 | ✓ | ✗ | ✗ | ✓ | ✓ |
| 撤回 | ✗ | ✓ | ✗ | ✗ | ✗ |
| 终止 | ✗ | ✗ | ✓ | ✗ | ✗ |
| 续签 | ✗ | ✗ | ✓ | ✗ | ✗ |
| 转正式 | ✗ | ✗ | ✓ | ✗ | ✗ |
| 变更三方 | ✗ | ✗ | ✓ | ✗ | ✗ |
| 新增车辆 | ✗ | ✗ | ✓ | ✗ | ✗ |
实现分阶段计划
阶段1:基础合同管理(不含审批)
目标: 实现合同的基础 CRUD 功能
关键文件:
- 数据库表创建脚本
- DO 类(6个)
- Mapper 接口(6个)
- VO 类(8个)
- Convert 接口
- Service 接口和实现
- Controller
- 枚举类(3个)
功能清单:
- ✓ 创建合同(包含车辆订单、服务项目、被授权人)
- ✓ 更新合同
- ✓ 删除合同
- ✓ 查询合同详情
- ✓ 分页查询合同列表
- ✓ 查询变更历史
验证方式:
- 使用 Postman 测试所有 CRUD 接口
- 验证数据库数据正确性
- 验证多表关联查询
阶段2:BPM 审批集成
目标: 集成 Flowable 工作流引擎,实现审批流程
关键文件:
- BPM 流程定义文件(BPMN 2.0 XML)
- ContractBpmListener.java(事件监听器)
- 审批相关 Service 方法
- 审批相关 Controller 接口
功能清单:
- ✓ 提交审批(启动 BPM 流程)
- ✓ 撤回审批
- ✓ 监听审批结果(通过/驳回)
- ✓ 更新合同审批状态
- ✓ 查询审批历史
验证方式:
- 创建合同并提交审批
- 在 BPM 管理界面审批
- 验证合同状态自动更新
- 验证审批历史记录
阶段3:特殊业务流程
目标: 实现续签、转正式、变更三方、新增车辆等特殊业务
关键文件:
- 特殊业务 Service 方法
- 特殊业务 Controller 接口
- 特殊业务 VO 类
功能清单:
- ✓ 终止合同
- ✓ 续签合同(创建新合同,关联原合同)
- ✓ 转正式合同(试用→正式)
- ✓ 变更为三方合同(增加丙方客户)
- ✓ 新增车辆(合同执行中新增车辆)
验证方式:
- 测试每个特殊业务流程
- 验证数据关联正确性
- 验证状态流转正确性
关键文件清单
数据库脚本
/Users/kkfluous/Projects/ai-coding/ln-oneos/oneos-backend/yudao-module-asset/sql/mysql/contract.sql
DO 类
ContractDO.java- 合同主表ContractVehicleDO.java- 车辆订单ContractVehicleServiceDO.java- 服务项目ContractAuthorizedDO.java- 被授权人ContractAttachmentDO.java- 合同附件ContractChangeHistoryDO.java- 变更历史
Mapper 接口
ContractMapper.javaContractVehicleMapper.javaContractVehicleServiceMapper.javaContractAuthorizedMapper.javaContractAttachmentMapper.javaContractChangeHistoryMapper.java
VO 类
ContractBaseVO.java- 基础 VOContractSaveReqVO.java- 创建/更新请求 VOContractRespVO.java- 响应 VOContractPageReqVO.java- 分页查询请求 VOContractDetailRespVO.java- 详情响应 VOContractVehicleVO.java- 车辆订单 VOContractVehicleServiceVO.java- 服务项目 VOContractAuthorizedVO.java- 被授权人 VO
Service
ContractService.java- Service 接口ContractServiceImpl.java- Service 实现ContractBpmListener.java- BPM 事件监听器
Controller
ContractController.java- REST API 控制器
Convert
ContractConvert.java- MapStruct 转换器
枚举类
ContractTypeEnum.java- 合同类型枚举ContractApprovalStatusEnum.java- 审批状态枚举ContractStatusEnum.java- 合同状态枚举
BPM 流程定义
rental_contract_approval.bpmn20.xml- 租赁合同审批流程定义
注意事项
- 数据一致性: 合同、车辆订单、服务项目、被授权人等多表操作需要使用事务
- 状态校验: 每个操作前需要校验当前状态是否允许该操作
- 权限控制: 使用
@PreAuthorize控制接口权限 - 多租户: 所有表都包含
tenant_id字段,自动过滤 - 软删除: 使用
deleted字段实现软删除 - 审计字段: 自动记录
creator、create_time、updater、update_time - BPM 集成: 流程实例 ID 需要保存到合同表,便于查询审批状态
- 文件上传: 使用
FileApi上传附件,保存文件 ID 和 URL - 变更历史: 每次重要操作都需要记录变更历史
- 合同编码: 自动生成,格式:HT-YYYY-NNN(HT=合同,YYYY=年份,NNN=序号)
时间估算
-
阶段1: 基础合同管理 - 2天
- 数据库表设计和创建 - 4小时
- DO/Mapper/VO/Convert - 4小时
- Service 实现 - 6小时
- Controller 实现 - 2小时
- 测试验证 - 2小时
-
阶段2: BPM 审批集成 - 1天
- BPM 流程定义 - 2小时
- 事件监听器 - 2小时
- 审批相关接口 - 2小时
- 测试验证 - 2小时
-
阶段3: 特殊业务流程 - 1天
- 续签/转正式/变更三方 - 4小时
- 新增车辆/终止合同 - 2小时
- 测试验证 - 2小时
总计:约 4 天