docs/contract_product_field_change.md
@@ -151,7 +151,7 @@
<!-- 产品明细表格 -->
<el-table-column prop="itemCode" label="物料编码" />
<el-table-column prop="itemName" label="物料名称" />
<el-table-column prop="itemBarCode" label="物料条码" />
<el-table-column prop="barCode" label="物料条码" />
<el-table-column prop="itemUnitName" label="单位" />
<el-table-column prop="itemPrice" label="原价" />
<el-table-column prop="contractPrice" label="合同价" />
@@ -209,3 +209,105 @@
2. **价格可修改**:`contractPrice` 默认等于物料原价,但可以手动修改
3. **过渡期**:后端暂时兼容 `productId` 和 `sellingPrice` 字段,但后续会移除兼容逻辑
4. **其他模块同步修改**:销售报价单也使用 MDM 物料,字段与合同一致
---
# 2026-09-24 增量:合同产品明细显示字段补全 + 删除合同级联清理明细
## 一、显示字段补全
### 背景
合同详情接口此前未解析产品明细的计量单位名称,条码字段名与前端列绑定不一致,导致以下位置 **单位列、物料条码列恒为空**(商机接口一直正常返回,本次对齐商机做法):
- 合同详情 →「产品」页签(`ProductDetailsList` 共用组件)
- 合同审批页 → 产品明细表
- 编辑合同弹窗 → 产品表格(已保存行次的规格型号同样为空)
### 涉及的接口
| 方法 | 路径 | 说明 |
|------|------|------|
| GET | /crm/contract/get | 获得合同详情(含产品明细),本次变更仅影响此接口 |
> `/crm/contract/page`、`/crm/contract/page-by-customer`、`/crm/contract/page-by-business`、导出 Excel 均**不含**产品明细,不受影响。
### 响应字段变更(data.products[])
| 字段 | 类型 | 变更 | 说明 |
|------|------|------|------|
| itemUnitName | String | 补全取值 | 计量单位名称,按 `itemUnitId` 解析(如「米」「个」),此前恒为 null |
| barCode | String | **字段更名** | 物料条码,原字段名 `itemBarCode` 改为 `barCode`,与商机接口及前端产品明细列表列绑定(field: 'barCode')一致 |
| itemSpecification | String | 新增 | 规格型号,取自 MDM 物料,与商机接口一致 |
| itemBarCode | - | 已移除 | 前端如有引用请改用 `barCode` |
**响应示例(节选):**
```json
{
  "code": 0,
  "data": {
    "id": 19,
    "no": "WTJC2025120501",
    "products": [
      {
        "id": 42,
        "itemId": 38,
        "itemCode": "PHC300AB70-4.5",
        "itemName": "PHC300AB70-4.5",
        "barCode": null,
        "itemSpecification": null,
        "itemUnitId": 3,
        "itemUnitName": "米",
        "itemPrice": 68.000000,
        "contractPrice": 68.000000,
        "count": 179208.000000,
        "totalPrice": 12186144.000000
      }
    ]
  }
}
```
### 字段展示规则
| 字段 | 展示位置 | 说明 |
|------|----------|------|
| itemUnitName | 合同详情产品页签、审批页产品表、编辑弹窗产品表 | 单位列,取值 MDM 计量单位名称 |
| barCode | 合同详情产品页签(物料条码列) | 与商机产品列表列绑定字段一致 |
| itemSpecification | 编辑弹窗产品表格 | 详情页产品页签无此列 |
### 业务规则说明
| 场景 | 规则 |
|------|------|
| 单位名称来源 | 由 MDM 计量单位表按产品明细的 itemUnitId 解析;导入的合同,itemUnitId 取自物料主数据的计量单位 |
| 条码取值 | 取自 MDM 物料档案的条码;物料未维护条码时为空,属正常 |
| 规格型号取值 | 取自 MDM 物料档案的规格型号;未维护时为空 |
| 编辑合同后保存 | 产品明细回传时 barCode / itemSpecification / itemUnitName 属于展示字段,后端不落库,由接口每次按 itemId / itemUnitId 实时解析,不影响保存结果 |
### 注意事项
- 本次为**响应字段名变更**(itemBarCode → barCode)。前端类型声明 `CrmContractApi.ContractProduct.itemBarCode` 建议同步改为 `barCode`(仅类型声明,运行时不读该字段,不改也不报错)。
- 前端页面代码**无需改动**:单位列、条码列、规格型号列绑定字段已与本次返回一致。
- 合同「产品」页签、审批页产品表复用同一列定义,修复后三处同时生效。
---
## 二、删除合同级联清理产品明细
### 背景
`DELETE /crm/contract/delete` 此前只删除合同主表、报价单引用与数据权限,**未删除 `crm_contract_product` 产品明细**,导致删除合同后明细成为孤儿数据(表内 deleted=0 但合同已不存在)。
### 变更后行为
| 操作 | 影响数据 |
|------|----------|
| 删除合同 | 合同主表(逻辑删除)+ 产品明细(逻辑删除)+ 报价单引用解除 + 数据权限删除 |
### 注意事项
- 级联删除为**逻辑删除**(deleted=1),与合同主表口径一致,历史数据仍可追溯。
- 合同已被回款引用时依旧禁止删除(原有校验不变)。
- 历史遗留的孤儿明细(本次修复前删除产生的)不会自动清理,如需清理请按 contract_id 核对后手工处理。