views/mdm/item/index.vue)views/mdm/item/ItemForm.vue)views/mdm/item/detail.vue)| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /mdm/item/page | 物料分页查询 |
| GET | /mdm/item/list | 物料列表查询 |
| GET | /mdm/item/get | 获取物料详情 |
| POST | /mdm/item/create | 创建物料 |
| PUT | /mdm/item/update | 更新物料 |
| DELETE | /mdm/item/delete | 删除物料 |
| PUT | /mdm/item/update-status | 更新物料状态 |
请求参数(物料查询):
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| code | String | 否 | 物料编码 |
| name | String | 否 | 物料名称 |
| categoryId | Long | 否 | 分类ID |
| itemType | Integer | 否 | 物料类型(1:原料,2:半成品,3:成品,4:辅料) |
| status | Integer | 否 | 状态 |
响应:
{
"code": 200,
"data": {
"list": [
{
"id": 1,
"code": "M001",
"name": "物料名称",
"barCode": "条码",
"specification": "规格型号",
"categoryId": 10,
"categoryName": "分类名称",
"unitMeasureId": 1,
"unitMeasureName": "单位名称",
"brandId": 1,
"brandName": "品牌名称",
"itemType": 1,
"status": 0,
"purchasePrice": 100.00,
"salesPrice": 150.00,
"costPrice": 80.00,
"safetyStock": 50.00,
"minStock": 20.00,
"maxStock": 200.00,
"isBatchManaged": true,
"expiryDay": 365,
"remark": "备注"
}
],
"total": 100
}
}
1. 物料列表页面结构:
<template>
<ContentWrap>
<!-- 搜索区域 -->
<el-form :model="queryParams" ref="queryFormRef" :inline="true">
<el-form-item label="物料编码" prop="code">
<el-input v-model="queryParams.code" placeholder="请输入物料编码" />
</el-form-item>
<el-form-item label="物料名称" prop="name">
<el-input v-model="queryParams.name" placeholder="请输入物料名称" />
</el-form-item>
<el-form-item label="物料分类" prop="categoryId">
<el-tree-select v-model="queryParams.categoryId" :data="categoryTree" />
</el-form-item>
<el-form-item label="物料类型" prop="itemType">
<el-select v-model="queryParams.itemType" placeholder="请选择物料类型">
<el-option label="原料" :value="1" />
<el-option label="半成品" :value="2" />
<el-option label="成品" :value="3" />
<el-option label="辅料" :value="4" />
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" @click="handleQuery">搜索</el-button>
<el-button @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
<!-- 操作按钮 -->
<el-row :gutter="10" class="mb8">
<el-col :span="1.5">
<el-button type="primary" plain @click="handleCreate">新增</el-button>
</el-col>
<el-col :span="1.5">
<el-button type="success" plain @click="handleExport">导出</el-button>
</el-col>
</el-row>
<!-- 表格 -->
<el-table v-loading="loading" :data="list">
<el-table-column label="物料编码" prop="code" width="120" />
<el-table-column label="物料名称" prop="name" width="180" />
<el-table-column label="规格型号" prop="specification" width="150" />
<el-table-column label="分类" prop="categoryName" width="100" />
<el-table-column label="单位" prop="unitMeasureName" width="80" />
<el-table-column label="物料类型" prop="itemType" width="80">
<template #default="{ row }">
<dict-tag :type="DICT_TYPE.MDM_ITEM_TYPE" :value="row.itemType" />
</template>
</el-table-column>
<el-table-column label="采购价" prop="purchasePrice" width="100" />
<el-table-column label="销售价" prop="salesPrice" width="100" />
<el-table-column label="批次管理" prop="isBatchManaged" width="80">
<template #default="{ row }">
<el-tag v-if="row.isBatchManaged" type="success">是</el-tag>
<el-tag v-else type="info">否</el-tag>
</template>
</el-table-column>
<el-table-column label="状态" prop="status" width="80">
<template #default="{ row }">
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="row.status" />
</template>
</el-table-column>
<el-table-column label="操作" width="180" fixed="right">
<template #default="{ row }">
<el-button link type="primary" @click="handleUpdate(row)">编辑</el-button>
<el-button link type="danger" @click="handleDelete(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
<!-- 分页 -->
<Pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNo" v-model:limit="queryParams.pageSize" @pagination="getList" />
</ContentWrap>
</template>
2. 物料表单弹窗:
<el-dialog v-model="dialogVisible" title="物料信息" width="800px">
<el-form ref="formRef" :model="formData" :rules="formRules" label-width="120px">
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物料编码" prop="code">
<el-input v-model="formData.code" placeholder="请输入物料编码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料名称" prop="name">
<el-input v-model="formData.name" placeholder="请输入物料名称" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="条码" prop="barCode">
<el-input v-model="formData.barCode" placeholder="请输入条码" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="规格型号" prop="specification">
<el-input v-model="formData.specification" placeholder="请输入规格型号" />
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="物料分类" prop="categoryId">
<el-tree-select v-model="formData.categoryId" :data="categoryTree" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="计量单位" prop="unitMeasureId">
<el-select v-model="formData.unitMeasureId" placeholder="请选择单位">
<el-option v-for="unit in unitList" :key="unit.id" :label="unit.name" :value="unit.id" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="品牌" prop="brandId">
<el-select v-model="formData.brandId" placeholder="请选择品牌">
<el-option v-for="brand in brandList" :key="brand.id" :label="brand.name" :value="brand.id" />
</el-select>
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="物料类型" prop="itemType">
<el-select v-model="formData.itemType" placeholder="请选择物料类型">
<el-option label="原料" :value="1" />
<el-option label="半成品" :value="2" />
<el-option label="成品" :value="3" />
<el-option label="辅料" :value="4" />
</el-select>
</el-form-item>
</el-col>
</el-row>
<!-- 价格信息 -->
<el-row :gutter="20">
<el-col :span="8">
<el-form-item label="采购价" prop="purchasePrice">
<el-input-number v-model="formData.purchasePrice" :precision="2" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="销售价" prop="salesPrice">
<el-input-number v-model="formData.salesPrice" :precision="2" />
</el-form-item>
</el-col>
<el-col :span="8">
<el-form-item label="成本价" prop="costPrice">
<el-input-number v-model="formData.costPrice" :precision="2" />
</el-form-item>
</el-col>
</el-row>
<!-- 库存管理 -->
<el-row :gutter="20">
<el-col :span="12">
<el-form-item label="安全库存" prop="safetyStock">
<el-input-number v-model="formData.safetyStock" :precision="2" />
</el-form-item>
</el-col>
<el-col :span="12">
<el-form-item label="批次管理" prop="isBatchManaged">
<el-switch v-model="formData.isBatchManaged" />
</el-form-item>
</el-col>
</el-row>
<el-form-item label="备注" prop="remark">
<el-input v-model="formData.remark" type="textarea" :rows="3" />
</el-form-item>
</el-form>
<template #footer>
<el-button @click="dialogVisible = false">取消</el-button>
<el-button type="primary" @click="submitForm">确定</el-button>
</template>
</el-dialog>
3. 数据定义:
<script setup>
import { ref, reactive, onMounted } from 'vue'
import * as ItemApi from '@/api/mdm/item'
const loading = ref(false)
const list = ref([])
const total = ref(0)
const queryParams = reactive({
pageNo: 1,
pageSize: 10,
code: '',
name: '',
categoryId: null,
itemType: null,
status: null
})
const dialogVisible = ref(false)
const formData = ref({
id: undefined,
code: '',
name: '',
barCode: '',
specification: '',
categoryId: null,
unitMeasureId: null,
brandId: null,
itemType: 1,
purchasePrice: null,
salesPrice: null,
costPrice: null,
safetyStock: null,
isBatchManaged: false,
remark: ''
})
const getList = async () => {
loading.value = true
try {
const data = await ItemApi.getItemPage(queryParams)
list.value = data.list
total.value = data.total
} finally {
loading.value = false
}
}
const handleCreate = () => {
formData.value = { ...initialFormData }
dialogVisible.value = true
}
const handleUpdate = (row) => {
formData.value = { ...row }
dialogVisible.value = true
}
const submitForm = async () => {
await formRef.value.validate()
if (formData.value.id) {
await ItemApi.updateItem(formData.value)
} else {
await ItemApi.createItem(formData.value)
}
dialogVisible.value = false
getList()
}
onMounted(() => {
getList()
})
</script>
views/mdm/category/index.vue)| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /mdm/category/list | 分类列表查询 |
| GET | /mdm/category/get | 获取分类详情 |
| POST | /mdm/category/create | 创建分类 |
| PUT | /mdm/category/update | 更新分类 |
| DELETE | /mdm/category/delete | 删除分类 |
views/mdm/unit/index.vue)| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /mdm/unit/page | 单位分页查询 |
| GET | /mdm/unit/list | 单位列表查询 |
| POST | /mdm/unit/create | 创建单位 |
| PUT | /mdm/unit/update | 更新单位 |
| DELETE | /mdm/unit/delete | 删除单位 |
views/mdm/brand/index.vue)| 方法 | 路径 | 说明 |
|---|---|---|
| GET | /mdm/brand/page | 品牌分页查询 |
| GET | /mdm/brand/list | 品牌列表查询 |
| POST | /mdm/brand/create | 创建品牌 |
| PUT | /mdm/brand/update | 更新品牌 |
| DELETE | /mdm/brand/delete | 删除品牌 |
原页面:views/erp/product/index.vue
修改点:
1. API 接口从 /erp/product/* 改为调用 /mdm/item/*
2. 数据字段映射调整(productId → itemId)
3. 增加物料类型筛选(原料/半成品/成品/辅料)
注意事项:
- ERP 产品页面数据来源从 MDM 物料获取
- 保留 ERP 特有字段(采购价、销售价、最低价)的编辑能力
原页面:views/mes/md/item/index.vue
修改点:
1. API 接口从 /mes/md-item/* 改为调用 /mdm/item/*
2. 数据字段映射调整(itemTypeId → categoryId)
3. 批次配置从独立页面改为物料详情页子模块
注意事项:
- MES 物料页面数据来源从 MDM 物料获取
- 批次属性配置保留在 MDM 模块管理
原页面:views/wms/item/index.vue
修改点:
1. API 接口从 /wms/item/* 改为调用 /mdm/item/*
2. SKU 管理改为物料详情页子模块
3. 库存查询改用统一接口 /wms/stock/*
注意事项:
- WMS 商品页面数据来源从 MDM 物料获取
- SKU 作为物料的规格属性管理
| 字典类型 | 字典值 | 说明 |
|---|---|---|
| MDM_ITEM_TYPE | 1 | 原料 |
| MDM_ITEM_TYPE | 2 | 半成品 |
| MDM_ITEM_TYPE | 3 | 成品 |
| MDM_ITEM_TYPE | 4 | 辅料 |
| STOCK_BIZ_TYPE | 10 | 采购入库 |
| STOCK_BIZ_TYPE | 20 | 销售出库 |
| STOCK_BIZ_TYPE | 30 | 生产入库 |
| STOCK_BIZ_TYPE | 40 | 生产领料 |
| STOCK_BIZ_TYPE | 50 | 生产退料 |
| STOCK_BIZ_TYPE | 60 | 采购退货出库 |
| STOCK_BIZ_TYPE | 70 | 销售退货入库 |
| STOCK_BIZ_TYPE | 80 | 调拨入库 |
| STOCK_BIZ_TYPE | 90 | 调拨出库 |
| STOCK_BIZ_TYPE | 100 | 盘盈入库 |
| STOCK_BIZ_TYPE | 110 | 盘亏出库 |
// 新增路由
{
path: '/mdm',
component: Layout,
name: 'MDM',
meta: { title: '主数据管理', icon: 'ep:goods' },
children: [
{
path: 'item',
name: 'MdmItem',
component: () => import('@/views/mdm/item/index.vue'),
meta: { title: '物料管理' }
},
{
path: 'category',
name: 'MdmCategory',
component: () => import('@/views/mdm/category/index.vue'),
meta: { title: '物料分类' }
},
{
path: 'unit',
name: 'MdmUnit',
component: () => import('@/views/mdm/unit/index.vue'),
meta: { title: '计量单位' }
},
{
path: 'brand',
name: 'MdmBrand',
component: () => import('@/views/mdm/brand/index.vue'),
meta: { title: '品牌管理' }
},
{
path: 'warehouse',
name: 'MdmWarehouse',
component: () => import('@/views/mdm/warehouse/index.vue'),
meta: { title: '仓库管理' }
}
]
}
api/mdm/item.js, api/mdm/category.js 等)productId → itemId文档版本: v1.0
创建日期: 2026-06-29
作者: Claude Code