编辑 | blame | 历史 | 原始文档

合同模块产品字段变更

变更说明

合同模块的产品来源从 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 计量单位名称

注意事项

  1. 物料必须先启用:只能选择状态为"启用"的 MDM 物料
  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 |

响应示例(节选):

{
  "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 核对后手工处理。