合同模块产品字段变更
变更说明
合同模块的产品来源从 CRM 产品 改为 MDM 物料,涉及字段名称变更。
数据库变更 SQL
-- =============================================
-- 合同产品表字段变更
-- =============================================
-- 1. 删除旧字段(如果有数据请先备份)
ALTER TABLE `crm_contract_product` DROP COLUMN `product_id`;
ALTER TABLE `crm_contract_product` DROP COLUMN `product_price`;
-- 2. 如果新字段不存在,则添加(根据实际情况判断是否需要执行)
-- ALTER TABLE `crm_contract_product` ADD COLUMN `item_id` bigint DEFAULT NULL COMMENT 'MDM物料编号' AFTER `contract_id`;
-- ALTER TABLE `crm_contract_product` ADD COLUMN `item_unit_id` bigint DEFAULT NULL COMMENT '计量单位编号' AFTER `item_id`;
-- ALTER TABLE `crm_contract_product` ADD COLUMN `item_price` decimal(24,6) DEFAULT NULL COMMENT '物料原价' AFTER `item_unit_id`;
涉及页面
API 变更
1. 创建/更新合同接口
| 方法 |
路径 |
说明 |
| POST |
/crm/contract/create |
创建合同 |
| PUT |
/crm/contract/update |
更新合同 |
2. 请求参数变更(products 字段)
旧字段(已废弃)
| 参数 |
类型 |
必填 |
说明 |
| productId |
Long |
是 |
CRM 产品编号 |
| productPrice |
BigDecimal |
否 |
产品价格 |
| sellingPrice |
BigDecimal |
否 |
销售价(用作合同价) |
新字段
| 参数 |
类型 |
必填 |
说明 |
| itemId |
Long |
是 |
MDM 物料编号 |
| itemPrice |
BigDecimal |
是 |
物料原价 |
| contractPrice |
BigDecimal |
是 |
合同价格 |
| count |
Integer |
是 |
数量 |
3. 请求示例
旧格式(不再支持):
{
"name": "合同名称",
"customerId": 1,
"products": [
{
"productId": 4,
"sellingPrice": 1111,
"count": 10
}
]
}
新格式:
{
"name": "合同名称",
"customerId": 1,
"products": [
{
"itemId": 4,
"itemPrice": 1000,
"contractPrice": 1111,
"count": 10
}
]
}
响应变更
合同详情接口响应
| 方法 |
路径 |
说明 |
| GET |
/crm/contract/get |
获取合同详情 |
产品明细字段变更
| 旧字段 |
新字段 |
说明 |
| productId |
itemId |
MDM 物料编号 |
| productName |
itemName |
物料名称 |
| productNo |
itemCode |
物料编码 |
| productUnit |
itemUnitName |
计量单位名称 |
| productPrice |
itemPrice |
物料原价 |
| - | itemBarCode | 物料条码(新增) |
前端修改点
1. 物料选择组件
将 CRM 产品选择器 改为 MDM 物料选择器。
<!-- 旧:CRM 产品选择器 -->
<CrmProductSelect v-model="product.productId" />
<!-- 新:MDM 物料选择器 -->
<MdmItemSelect v-model="product.itemId" @change="handleItemChange" />
2. 物料选择回调
methods: {
handleItemChange(item) {
// 选择物料后自动填充价格信息
this.product.itemId = item.id
this.product.itemPrice = item.salesPrice // 物料原价
this.product.contractPrice = item.salesPrice // 合同价格(默认等于原价,可修改)
}
}
3. 表格列字段修改
<!-- 产品明细表格 -->
<el-table-column prop="itemCode" label="物料编码" />
<el-table-column prop="itemName" 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="合同价" />
<el-table-column prop="count" label="数量" />
4. data 数据修改
// 产品明细数据结构
product: {
itemId: null, // MDM 物料编号
itemPrice: null, // 物料原价
contractPrice: null, // 合同价格
count: null // 数量
}
MDM 物料选择器 API
获取物料列表
| 方法 |
路径 |
说明 |
| GET |
/mdm/item/page |
分页查询物料 |
请求参数:
| 参数 |
类型 |
必填 |
说明 |
| code |
String |
否 |
物料编码 |
| name |
String |
否 |
物料名称 |
| barCode |
String |
否 |
物料条码 |
| status |
Integer |
否 |
状态(0启用 1禁用),传 0 |
响应字段:
| 字段 |
类型 |
说明 |
| id |
Long |
物料编号(即 itemId) |
| code |
String |
物料编码 |
| name |
String |
物料名称 |
| barCode |
String |
物料条码 |
| salesPrice |
BigDecimal |
销售价 |
| unitMeasureId |
Long |
计量单位编号 |
| unitMeasureName |
String |
计量单位名称 |
注意事项
- 物料必须先启用:只能选择状态为"启用"的 MDM 物料
- 价格可修改:
contractPrice 默认等于物料原价,但可以手动修改
- 过渡期:后端暂时兼容
productId 和 sellingPrice 字段,但后续会移除兼容逻辑
- 其他模块同步修改:销售报价单也使用 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 |
响应示例(节选):
{
"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 核对后手工处理。