# 车辆租赁合同模块实施计划

## Context（背景）

### 为什么需要这个变更
车辆租赁业务是 OneOS 系统的核心业务模块，需要管理与客户签订的车辆租赁合同，包括合同信息、车辆订单、服务项目、被授权人、审批流程等。该模块需要与 BPM 工作流引擎深度集成，实现合同的审批流转。

### 问题或需求
1. **业务需求**：管理车辆租赁合同的全生命周期（创建→审批→执行→到期→续签/终止）
2. **审批流程**：4级审批（业务部主管→事业部主管→财务部→法务部）
3. **复杂关联**：合同关联客户、车辆、服务项目、被授权人、附件等多个实体
4. **特殊业务**：续签合同、转正式合同、变更为三方合同、新增车辆等
5. **状态管理**：审批状态 × 合同状态的复杂状态机

### 预期结果
构建一个完整的车辆租赁合同管理模块，支持合同的 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（合同主表）

```sql
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（车辆租赁订单）

```sql
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（服务项目）

```sql
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（被授权人）

```sql
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（合同附件）

```sql
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（变更历史）

```sql
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`
- **流程名称**: 车辆租赁合同审批
- **审批节点**:
  1. 业务部主管审批
  2. 事业部主管审批
  3. 财务部审批
  4. 法务部审批（上传盖章合同）

### 流程变量
```java
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`

### 事件监听器
```java
@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 功能

**关键文件**:
1. 数据库表创建脚本
2. DO 类（6个）
3. Mapper 接口（6个）
4. VO 类（8个）
5. Convert 接口
6. Service 接口和实现
7. Controller
8. 枚举类（3个）

**功能清单**:
- ✓ 创建合同（包含车辆订单、服务项目、被授权人）
- ✓ 更新合同
- ✓ 删除合同
- ✓ 查询合同详情
- ✓ 分页查询合同列表
- ✓ 查询变更历史

**验证方式**:
- 使用 Postman 测试所有 CRUD 接口
- 验证数据库数据正确性
- 验证多表关联查询

### 阶段2：BPM 审批集成

**目标**: 集成 Flowable 工作流引擎，实现审批流程

**关键文件**:
1. BPM 流程定义文件（BPMN 2.0 XML）
2. ContractBpmListener.java（事件监听器）
3. 审批相关 Service 方法
4. 审批相关 Controller 接口

**功能清单**:
- ✓ 提交审批（启动 BPM 流程）
- ✓ 撤回审批
- ✓ 监听审批结果（通过/驳回）
- ✓ 更新合同审批状态
- ✓ 查询审批历史

**验证方式**:
- 创建合同并提交审批
- 在 BPM 管理界面审批
- 验证合同状态自动更新
- 验证审批历史记录

### 阶段3：特殊业务流程

**目标**: 实现续签、转正式、变更三方、新增车辆等特殊业务

**关键文件**:
1. 特殊业务 Service 方法
2. 特殊业务 Controller 接口
3. 特殊业务 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.java`
- `ContractVehicleMapper.java`
- `ContractVehicleServiceMapper.java`
- `ContractAuthorizedMapper.java`
- `ContractAttachmentMapper.java`
- `ContractChangeHistoryMapper.java`

### VO 类
- `ContractBaseVO.java` - 基础 VO
- `ContractSaveReqVO.java` - 创建/更新请求 VO
- `ContractRespVO.java` - 响应 VO
- `ContractPageReqVO.java` - 分页查询请求 VO
- `ContractDetailRespVO.java` - 详情响应 VO
- `ContractVehicleVO.java` - 车辆订单 VO
- `ContractVehicleServiceVO.java` - 服务项目 VO
- `ContractAuthorizedVO.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` - 租赁合同审批流程定义

---

## 注意事项

1. **数据一致性**: 合同、车辆订单、服务项目、被授权人等多表操作需要使用事务
2. **状态校验**: 每个操作前需要校验当前状态是否允许该操作
3. **权限控制**: 使用 `@PreAuthorize` 控制接口权限
4. **多租户**: 所有表都包含 `tenant_id` 字段，自动过滤
5. **软删除**: 使用 `deleted` 字段实现软删除
6. **审计字段**: 自动记录 `creator`、`create_time`、`updater`、`update_time`
7. **BPM 集成**: 流程实例 ID 需要保存到合同表，便于查询审批状态
8. **文件上传**: 使用 `FileApi` 上传附件，保存文件 ID 和 URL
9. **变更历史**: 每次重要操作都需要记录变更历史
10. **合同编码**: 自动生成，格式：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 天**
