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-tree-select
|
||||
v-model="formData.itemTypeId"
|
||||
:data="itemTypeList"
|
||||
:data="itemTypeTree"
|
||||
:props="defaultProps"
|
||||
check-strictly
|
||||
default-expand-all
|
||||
|
|
@ -118,9 +118,8 @@
|
|||
<el-tab-pane label="BOM 组成" name="bom" lazy>
|
||||
<el-empty description="BOM 组成(待实现)" />
|
||||
</el-tab-pane>
|
||||
<!-- TODO @芋艿:批次属性,等批次模块实现后对接 -->
|
||||
<el-tab-pane label="批次属性" name="batch" lazy>
|
||||
<el-empty description="批次属性(待实现)" />
|
||||
<el-tab-pane label="批次属性" name="batch" lazy v-if="formData.batchFlag">
|
||||
<MdItemBatchConfigForm :itemId="formData.id!" :itemOrProduct="currentItemOrProduct" />
|
||||
</el-tab-pane>
|
||||
<!-- TODO @芋艿:替代品,等替代品模块实现后对接 -->
|
||||
<el-tab-pane label="替代品" name="substitute" lazy>
|
||||
|
|
@ -145,6 +144,7 @@ import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
|||
import { generateRandomStr } from '@/utils'
|
||||
import { MdItemApi, MdItemVO } from '@/api/mes/md/item'
|
||||
import { MdItemTypeApi, MdItemTypeVO } from '@/api/mes/md/item/type'
|
||||
import MdItemBatchConfigForm from './MdItemBatchConfigForm.vue'
|
||||
import { MdUnitMeasureApi, MdUnitMeasureVO } from '@/api/mes/md/unitmeasure'
|
||||
import { CommonStatusEnum } from '@/utils/constants'
|
||||
import { defaultProps, handleTree } from '@/utils/tree'
|
||||
|
|
@ -183,9 +183,19 @@ const formRules = reactive({
|
|||
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
|
||||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
const itemTypeList = ref<MdItemTypeVO[]>([]) // 物料分类列表
|
||||
const itemTypeTree = ref<MdItemTypeVO[]>([]) // 物料分类树
|
||||
const itemTypeList = ref<MdItemTypeVO[]>([]) // 物料分类列表(扁平)
|
||||
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 = () => {
|
||||
// TODO @芋艿:后续对接后端编码生成接口
|
||||
|
|
@ -209,8 +219,8 @@ const open = async (type: string, id?: number) => {
|
|||
}
|
||||
}
|
||||
// 物料分类
|
||||
const categoryData = await MdItemTypeApi.getItemTypeSimpleList()
|
||||
itemTypeList.value = handleTree(categoryData, 'id', 'parentId')
|
||||
itemTypeList.value = await MdItemTypeApi.getItemTypeSimpleList()
|
||||
itemTypeTree.value = handleTree(itemTypeList.value)
|
||||
// 计量单位
|
||||
unitMeasureList.value = await MdUnitMeasureApi.getUnitMeasureSimpleList()
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue