158 lines
6.1 KiB
Markdown
158 lines
6.1 KiB
Markdown
# 合同管理 — 03 DDL 差异清单(步骤 4/5)
|
||
|
||
> **日期**:2026-05-31
|
||
> **对比源**:CRM 权威 `docs/sql/sx.sql` vs 门户基线 `docs/sql/shanxia2.0.sql`
|
||
> **增量脚本**:`docs/sql/incremental_crm_contract_rewrite.sql`
|
||
> **ORM**:`backend/app/models/crm_models.py`(步骤 15+ 须同步 `CrmContractProductPriceTier`)
|
||
|
||
---
|
||
|
||
## 1. 表级差异总览
|
||
|
||
| 表 | sx.sql (CRM) | shanxia2.0.sql | 结论 |
|
||
|----|--------------|----------------|------|
|
||
| `crm_contract` | ✅ | ✅ | 业务字段基本齐全;**缺部分列表索引** |
|
||
| `crm_contract_approval` | ✅ | ✅ | 已按门户公共字段对齐 |
|
||
| `crm_contract_change` | ✅ | ✅ | 已对齐 |
|
||
| `crm_contract_product` | ✅ | ✅ | 已对齐(无 `version`,可接受) |
|
||
| `crm_contract_template` | ✅ | ✅ | 门户 `uk_template_no` 含 `tenant_no`,更合理 |
|
||
| `crm_contract_product_price_tier` | ✅ | ❌ **整表缺失** | **必须新建**(框架合同提交审批) |
|
||
|
||
共 **6** 张合同相关表;门户缺 **1** 张整表。
|
||
|
||
---
|
||
|
||
## 2. 门户 vs CRM 建模约定(不需改回 CRM)
|
||
|
||
移植 Python 时 **保持门户约定**,不做 bigint 回退:
|
||
|
||
| 维度 | CRM (`sx.sql`) | 门户 (`shanxia2.0.sql`) |
|
||
|------|----------------|---------------------------|
|
||
| 主键 | `bigint AUTO_INCREMENT` | `varchar(64)` UUID |
|
||
| 租户 | `tenant_id` varchar(20) | `tenant_no` varchar(64) |
|
||
| 部门 | `create_dept` bigint | `create_dept_id` varchar(64) |
|
||
| 乐观锁 | `version` int | `version_no` int(仅 `crm_contract`) |
|
||
| 公共字段 | 无 `order_num` | `order_num` + 标准审计字段 |
|
||
| 软删 | `del_flag` tinyint | `del_flag` smallint |
|
||
|
||
外键 ID 列在门户均为 `varchar(64)`,与 Java `Long` 不同 — API 层用 string 传输。
|
||
|
||
---
|
||
|
||
## 3. `crm_contract` 字段对比
|
||
|
||
### 3.1 业务字段
|
||
|
||
| 字段 | sx | shanxia2.0 | 说明 |
|
||
|------|----|------------|------|
|
||
| 主体/金额/日期/状态/甲乙方/模板/供方/结算 | ✅ | ✅ | 已对齐 |
|
||
| `template_content` | longtext | longtext | ✅ |
|
||
| `settlement_clause_drafts` | longtext | longtext | ✅ |
|
||
| `supplier_id` | bigint | varchar(64) | ✅ 类型差异见 §2 |
|
||
| `attachment_files` | varchar(1000) | varchar(2000) | 门户更大,保留 |
|
||
| `owner_user_id` | NOT NULL | nullable | 门户允许空;Java 新增时会填当前用户 |
|
||
| `remark` | varchar(500) | varchar(512) | 细微差异,保留门户 |
|
||
|
||
**sx 与门户均无**(前端 VO 有、Java 可能写 remark):`execute_start_date`、`expected_end_date`、`actual_end_date`、`execute_remark`、`complete_remark`、`invalid_remark` — 当前 **不落库** 或走 `remark`;重写后端时与 Java 行为一致即可(Java ServiceImpl 的 finish/start 主要改 status)。
|
||
|
||
### 3.2 索引差异(门户缺失 → 建议补)
|
||
|
||
| 索引 | sx | shanxia2.0 | 用途 |
|
||
|------|----|------------|------|
|
||
| `uk_contract_no_del_flag` (contract_no, del_flag) | ✅ | ❌ | 编号唯一(门户应加 **tenant_no**) |
|
||
| `idx_owner_user_id` | ✅ | ❌ | Tab「我的合同」 |
|
||
| `idx_status` | ✅ | ❌ | Tab executing/finished/invalid |
|
||
| `idx_sign_date` | ✅ | ❌ | 签订日期筛选 |
|
||
| `idx_end_date` | ✅ | ❌ | 到期提醒 C21 |
|
||
| `idx_create_time` | ✅ | ❌ | 默认排序 create_time DESC |
|
||
|
||
门户已有:`idx_customer_id`、`idx_tenant`、`idx_opportunity_id`、`idx_quote_id`、`idx_supplier_id`、`idx_parent_contract_id`、`idx_approval_status`、`idx_performance_status`、`idx_contract_nature`。
|
||
|
||
---
|
||
|
||
## 4. `crm_contract_approval`
|
||
|
||
| 项 | sx | shanxia2.0 |
|
||
|----|----|------------|
|
||
| 审批字段 step/result/is_current 等 | ✅ | ✅ |
|
||
| `version` | ✅ | ❌ | 非必须 |
|
||
| 索引 | 与门户一致 | ✅ | |
|
||
|
||
**无需 ALTER**(表已存在且满足 §10 审批流)。
|
||
|
||
---
|
||
|
||
## 5. `crm_contract_product`
|
||
|
||
| 项 | sx | shanxia2.0 |
|
||
|----|----|------------|
|
||
| 产品/交付字段 | ✅ | ✅ |
|
||
| `idx_delivery_status` | ✅ | ✅ |
|
||
| `version` | ✅ | ❌ | 可接受 |
|
||
|
||
**无需 ALTER**。
|
||
|
||
---
|
||
|
||
## 6. `crm_contract_change` / `crm_contract_template`
|
||
|
||
与 sx 业务字段一致;门户已含 `tenant_no` + 公共字段。模板表唯一键门户为 `(template_no, tenant_no)`,优于 sx 单字段唯一。
|
||
|
||
**无需 ALTER**。
|
||
|
||
---
|
||
|
||
## 7. `crm_contract_product_price_tier`(缺失 — 阻塞框架合同)
|
||
|
||
### sx 最终结构(含 CRM 增量脚本)
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|------|------|------|
|
||
| `id` | bigint → **门户 varchar(64)** | 主键 |
|
||
| `contract_id` | FK 合同 | |
|
||
| `contract_product_id` | FK 合同产品 | |
|
||
| `start_date` / `end_date` | date | 调价区间 |
|
||
| `price` | decimal(15,2) | 含税单价 |
|
||
| `letter_oss_ids` | varchar(4000) | JSON 数组,**多张调价函** |
|
||
| `letter_oss_id` | bigint nullable | 废弃字段,兼容只读 |
|
||
| `sort` | int | |
|
||
| + 门户公共字段 | | `tenant_no`…`del_flag` |
|
||
|
||
Java `validateFrameworkContractForSubmitApproval` 校验 **letter_oss_ids**(见 `02-business-logic.md` §10.5)。
|
||
|
||
### ORM 状态
|
||
|
||
`crm_models.py` **尚无** `CrmContractProductPriceTier` — 步骤 15 与 DDL 同步新增。
|
||
|
||
---
|
||
|
||
## 8. 增量脚本内容摘要
|
||
|
||
文件:`docs/sql/incremental_crm_contract_rewrite.sql`
|
||
|
||
| 序号 | 操作 |
|
||
|------|------|
|
||
| S1 | `CREATE TABLE crm_contract_product_price_tier`(门户字段规范) |
|
||
| S2 | `crm_contract` 补索引:`idx_status`、`idx_owner_user_id`、`idx_sign_date`、`idx_end_date`、`idx_create_time` |
|
||
| S3 | `crm_contract` 唯一约束:`uk_contract_tenant_no (contract_no, tenant_no)` — 租户内全局唯一(含软删不复用);历史曾为 `uk_contract_tenant_no_del` |
|
||
|
||
**执行顺序**:测试库手动执行 → 验证 → 步骤 15 更新 ORM → 后端实现 tier CRUD。
|
||
|
||
---
|
||
|
||
## 9. 部署检查清单
|
||
|
||
- [ ] 在目标库执行 `incremental_crm_contract_rewrite.sql`
|
||
- [ ] 确认 `SHOW INDEX FROM crm_contract` 含 §3.2 索引
|
||
- [ ] 确认 `crm_contract_product_price_tier` 存在
|
||
- [ ] 更新 `shanxia2.0.sql` 全量快照(可选,下次全量导出时合并)
|
||
- [ ] `crm_models.py` 增加 `CrmContractProductPriceTier`(步骤 15)
|
||
|
||
---
|
||
|
||
## 变更记录
|
||
|
||
| 日期 | 说明 |
|
||
|------|------|
|
||
| 2026-05-31 | 步骤 4/5:sx vs shanxia2.0 六表对比 + 增量 SQL |
|