feat(mes): 新增物料批次属性配置前端组件
1. 新增 MdItemBatchConfigForm 组件,根据 itemOrProduct 区分 ITEM/PRODUCT 展示不同 checkbox 2. 嵌入 MdItemForm 的"批次属性"tab,仅 batchFlag 开启时显示 3. API 文件放置于 batchConfig/index.ts 子目录 4. 使用 MesItemOrProductEnum 常量替代硬编码字符串 5. MdItemForm 变量名语义优化:itemTypeList → itemTypeTree,itemTypeFlatList → itemTypeList 6. 布局优化:采用 CSS Grid 一行 5 个,checkbox label 模式(☑ 文字)pull/871/MERGE
parent
3d103f1f46
commit
15dd4dce76
|
|
@ -0,0 +1,34 @@
|
||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
// MES 物料批次属性配置 VO
|
||||||
|
export interface MdItemBatchConfigVO {
|
||||||
|
id?: number // 编号
|
||||||
|
itemId: number // 物料编号
|
||||||
|
produceDateFlag: boolean // 批次属性-生产日期
|
||||||
|
expireDateFlag: boolean // 批次属性-有效期
|
||||||
|
receiptDateFlag: boolean // 批次属性-入库日期
|
||||||
|
vendorFlag: boolean // 批次属性-供应商
|
||||||
|
clientFlag: boolean // 批次属性-客户
|
||||||
|
salesOrderCodeFlag: boolean // 批次属性-销售订单编号
|
||||||
|
purchaseOrderCodeFlag: boolean // 批次属性-采购订单编号
|
||||||
|
workorderFlag: boolean // 批次属性-生产工单
|
||||||
|
taskFlag: boolean // 批次属性-生产任务
|
||||||
|
workstationFlag: boolean // 批次属性-工位
|
||||||
|
toolFlag: boolean // 批次属性-工具
|
||||||
|
moldFlag: boolean // 批次属性-模具
|
||||||
|
lotNumberFlag: boolean // 批次属性-生产批号
|
||||||
|
qualityStatusFlag: boolean // 批次属性-质量状态
|
||||||
|
}
|
||||||
|
|
||||||
|
// MES 物料批次属性配置 API
|
||||||
|
export const MdItemBatchConfigApi = {
|
||||||
|
// 根据物料编号获取批次属性配置
|
||||||
|
getBatchConfigByItemId: async (itemId: number) => {
|
||||||
|
return await request.get({ url: `/mes/md/item-batch-config/get-by-item-id?itemId=` + itemId })
|
||||||
|
},
|
||||||
|
|
||||||
|
// 保存批次属性配置(新增或更新)
|
||||||
|
saveBatchConfig: async (data: MdItemBatchConfigVO) => {
|
||||||
|
return await request.post({ url: `/mes/md/item-batch-config/save`, data })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,122 @@
|
||||||
|
<!-- MES 物料批次属性配置 -->
|
||||||
|
<template>
|
||||||
|
<el-form ref="formRef" :model="formData" v-loading="loading">
|
||||||
|
<div class="flex justify-end mb-10px">
|
||||||
|
<el-button type="primary" size="small" @click="handleSave" :loading="loading">保存批次属性</el-button>
|
||||||
|
</div>
|
||||||
|
<div class="batch-config-grid">
|
||||||
|
<!-- 通用属性(ITEM 和 PRODUCT 都可见) -->
|
||||||
|
<el-checkbox v-model="formData.produceDateFlag">生产日期</el-checkbox>
|
||||||
|
<el-checkbox v-model="formData.qualityStatusFlag">质量状态</el-checkbox>
|
||||||
|
|
||||||
|
<!-- ITEM(原材料)特有属性 -->
|
||||||
|
<template v-if="itemOrProduct === MesItemOrProductEnum.ITEM.value">
|
||||||
|
<el-checkbox v-model="formData.vendorFlag">供应商</el-checkbox>
|
||||||
|
<el-checkbox v-model="formData.purchaseOrderCodeFlag">采购订单编号</el-checkbox>
|
||||||
|
<el-checkbox v-model="formData.lotNumberFlag">生产批号</el-checkbox>
|
||||||
|
<el-checkbox v-model="formData.expireDateFlag">有效期</el-checkbox>
|
||||||
|
<el-checkbox v-model="formData.receiptDateFlag">入库日期</el-checkbox>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<!-- PRODUCT(产品)特有属性 -->
|
||||||
|
<template v-if="itemOrProduct === MesItemOrProductEnum.PRODUCT.value">
|
||||||
|
<el-checkbox v-model="formData.clientFlag">客户</el-checkbox>
|
||||||
|
<el-checkbox v-model="formData.salesOrderCodeFlag">销售订单编号</el-checkbox>
|
||||||
|
<el-checkbox v-model="formData.workorderFlag">生产工单</el-checkbox>
|
||||||
|
<el-checkbox v-model="formData.taskFlag">生产任务</el-checkbox>
|
||||||
|
<el-checkbox v-model="formData.workstationFlag">工位</el-checkbox>
|
||||||
|
<el-checkbox v-model="formData.toolFlag">工具</el-checkbox>
|
||||||
|
<el-checkbox v-model="formData.moldFlag">模具</el-checkbox>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</el-form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { MdItemBatchConfigApi, MdItemBatchConfigVO } from '@/api/mes/md/item/batchConfig'
|
||||||
|
import { MesItemOrProductEnum } from '@/views/mes/utils/constants'
|
||||||
|
|
||||||
|
defineOptions({ name: 'MdItemBatchConfigForm' })
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
itemId: number
|
||||||
|
itemOrProduct: string // 'ITEM' | 'PRODUCT'
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const message = useMessage()
|
||||||
|
const loading = ref(false)
|
||||||
|
const formRef = ref()
|
||||||
|
const formData = ref<MdItemBatchConfigVO>({
|
||||||
|
itemId: props.itemId,
|
||||||
|
produceDateFlag: false,
|
||||||
|
expireDateFlag: false,
|
||||||
|
receiptDateFlag: false,
|
||||||
|
vendorFlag: false,
|
||||||
|
clientFlag: false,
|
||||||
|
salesOrderCodeFlag: false,
|
||||||
|
purchaseOrderCodeFlag: false,
|
||||||
|
workorderFlag: false,
|
||||||
|
taskFlag: false,
|
||||||
|
workstationFlag: false,
|
||||||
|
toolFlag: false,
|
||||||
|
moldFlag: false,
|
||||||
|
lotNumberFlag: false,
|
||||||
|
qualityStatusFlag: false
|
||||||
|
})
|
||||||
|
|
||||||
|
/** 加载已有配置 */
|
||||||
|
const loadData = async () => {
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
const data = await MdItemBatchConfigApi.getBatchConfigByItemId(props.itemId)
|
||||||
|
if (data) {
|
||||||
|
formData.value = { ...formData.value, ...data }
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 保存 */
|
||||||
|
const handleSave = async () => {
|
||||||
|
// 校验至少选中一个属性
|
||||||
|
const hasAny =
|
||||||
|
formData.value.produceDateFlag ||
|
||||||
|
formData.value.expireDateFlag ||
|
||||||
|
formData.value.receiptDateFlag ||
|
||||||
|
formData.value.vendorFlag ||
|
||||||
|
formData.value.clientFlag ||
|
||||||
|
formData.value.salesOrderCodeFlag ||
|
||||||
|
formData.value.purchaseOrderCodeFlag ||
|
||||||
|
formData.value.workorderFlag ||
|
||||||
|
formData.value.taskFlag ||
|
||||||
|
formData.value.workstationFlag ||
|
||||||
|
formData.value.toolFlag ||
|
||||||
|
formData.value.moldFlag ||
|
||||||
|
formData.value.lotNumberFlag ||
|
||||||
|
formData.value.qualityStatusFlag
|
||||||
|
if (!hasAny) {
|
||||||
|
message.warning('至少选择一个批次属性')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
loading.value = true
|
||||||
|
try {
|
||||||
|
formData.value.itemId = props.itemId
|
||||||
|
await MdItemBatchConfigApi.saveBatchConfig(formData.value)
|
||||||
|
message.success('保存成功')
|
||||||
|
} finally {
|
||||||
|
loading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => loadData())
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.batch-config-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(5, 1fr);
|
||||||
|
gap: 0 20px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -46,7 +46,7 @@
|
||||||
<el-form-item label="物料分类" prop="itemTypeId">
|
<el-form-item label="物料分类" prop="itemTypeId">
|
||||||
<el-tree-select
|
<el-tree-select
|
||||||
v-model="formData.itemTypeId"
|
v-model="formData.itemTypeId"
|
||||||
:data="itemTypeList"
|
:data="itemTypeTree"
|
||||||
:props="defaultProps"
|
:props="defaultProps"
|
||||||
check-strictly
|
check-strictly
|
||||||
default-expand-all
|
default-expand-all
|
||||||
|
|
@ -118,9 +118,8 @@
|
||||||
<el-tab-pane label="BOM 组成" name="bom" lazy>
|
<el-tab-pane label="BOM 组成" name="bom" lazy>
|
||||||
<el-empty description="BOM 组成(待实现)" />
|
<el-empty description="BOM 组成(待实现)" />
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- TODO @芋艿:批次属性,等批次模块实现后对接 -->
|
<el-tab-pane label="批次属性" name="batch" lazy v-if="formData.batchFlag">
|
||||||
<el-tab-pane label="批次属性" name="batch" lazy>
|
<MdItemBatchConfigForm :itemId="formData.id!" :itemOrProduct="currentItemOrProduct" />
|
||||||
<el-empty description="批次属性(待实现)" />
|
|
||||||
</el-tab-pane>
|
</el-tab-pane>
|
||||||
<!-- TODO @芋艿:替代品,等替代品模块实现后对接 -->
|
<!-- TODO @芋艿:替代品,等替代品模块实现后对接 -->
|
||||||
<el-tab-pane label="替代品" name="substitute" lazy>
|
<el-tab-pane label="替代品" name="substitute" lazy>
|
||||||
|
|
@ -145,6 +144,7 @@ import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
import { generateRandomStr } from '@/utils'
|
import { generateRandomStr } from '@/utils'
|
||||||
import { MdItemApi, MdItemVO } from '@/api/mes/md/item'
|
import { MdItemApi, MdItemVO } from '@/api/mes/md/item'
|
||||||
import { MdItemTypeApi, MdItemTypeVO } from '@/api/mes/md/item/type'
|
import { MdItemTypeApi, MdItemTypeVO } from '@/api/mes/md/item/type'
|
||||||
|
import MdItemBatchConfigForm from './MdItemBatchConfigForm.vue'
|
||||||
import { MdUnitMeasureApi, MdUnitMeasureVO } from '@/api/mes/md/unitmeasure'
|
import { MdUnitMeasureApi, MdUnitMeasureVO } from '@/api/mes/md/unitmeasure'
|
||||||
import { CommonStatusEnum } from '@/utils/constants'
|
import { CommonStatusEnum } from '@/utils/constants'
|
||||||
import { defaultProps, handleTree } from '@/utils/tree'
|
import { defaultProps, handleTree } from '@/utils/tree'
|
||||||
|
|
@ -183,9 +183,19 @@ const formRules = reactive({
|
||||||
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
|
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
|
||||||
})
|
})
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
const itemTypeList = ref<MdItemTypeVO[]>([]) // 物料分类列表
|
const itemTypeTree = ref<MdItemTypeVO[]>([]) // 物料分类树
|
||||||
|
const itemTypeList = ref<MdItemTypeVO[]>([]) // 物料分类列表(扁平)
|
||||||
const unitMeasureList = ref<MdUnitMeasureVO[]>([]) // 计量单位列表
|
const unitMeasureList = ref<MdUnitMeasureVO[]>([]) // 计量单位列表
|
||||||
|
|
||||||
|
/** 当前物料的「物料/产品」标识 */
|
||||||
|
const currentItemOrProduct = computed(() => {
|
||||||
|
if (!formData.value.itemTypeId) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
const itemType = itemTypeList.value.find((t) => t.id === formData.value.itemTypeId)
|
||||||
|
return itemType?.itemOrProduct || ''
|
||||||
|
})
|
||||||
|
|
||||||
/** 生成物料编码 */
|
/** 生成物料编码 */
|
||||||
const generateCode = () => {
|
const generateCode = () => {
|
||||||
// TODO @芋艿:后续对接后端编码生成接口
|
// TODO @芋艿:后续对接后端编码生成接口
|
||||||
|
|
@ -209,8 +219,8 @@ const open = async (type: string, id?: number) => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 物料分类
|
// 物料分类
|
||||||
const categoryData = await MdItemTypeApi.getItemTypeSimpleList()
|
itemTypeList.value = await MdItemTypeApi.getItemTypeSimpleList()
|
||||||
itemTypeList.value = handleTree(categoryData, 'id', 'parentId')
|
itemTypeTree.value = handleTree(itemTypeList.value)
|
||||||
// 计量单位
|
// 计量单位
|
||||||
unitMeasureList.value = await MdUnitMeasureApi.getUnitMeasureSimpleList()
|
unitMeasureList.value = await MdUnitMeasureApi.getUnitMeasureSimpleList()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue