6.1 KiB
合同管理 — 03 DDL 差异清单(步骤 4/5)
日期:2026-05-31
对比源:CRM 权威docs/sql/sx.sqlvs 门户基线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 |