✨ feat(mes): 添加物料产品状态更新功能,优化物料分类选择器
parent
3860970490
commit
db6a9aeabe
|
|
@ -47,6 +47,11 @@ export const MdItemApi = {
|
||||||
return await request.put({ url: `/mes/md/item/update`, data })
|
return await request.put({ url: `/mes/md/item/update`, data })
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// 修改物料产品状态
|
||||||
|
updateItemStatus: async (id: number, status: number) => {
|
||||||
|
return await request.put({ url: `/mes/md/item/update-status`, params: { id, status } })
|
||||||
|
},
|
||||||
|
|
||||||
// 删除物料产品
|
// 删除物料产品
|
||||||
deleteItem: async (id: number) => {
|
deleteItem: async (id: number) => {
|
||||||
return await request.delete({ url: `/mes/md/item/delete?id=` + id })
|
return await request.delete({ url: `/mes/md/item/delete?id=` + id })
|
||||||
|
|
|
||||||
|
|
@ -37,22 +37,12 @@
|
||||||
</el-col>
|
</el-col>
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="物料分类" prop="itemTypeId">
|
<el-form-item label="物料分类" prop="itemTypeId">
|
||||||
<!-- TODO @AI:在 /Users/yunai/Java/yudao-all-in-one/yudao-ui-admin-vue3/src/views/mes/md/item/type 增加一个物料的 select;注意,只允许选择子节点; -->
|
<MdItemTypeSelect v-model="formData.itemTypeId" />
|
||||||
<el-tree-select
|
|
||||||
v-model="formData.itemTypeId"
|
|
||||||
:data="itemTypeTree"
|
|
||||||
:props="defaultProps"
|
|
||||||
check-strictly
|
|
||||||
default-expand-all
|
|
||||||
placeholder="请选择物料分类"
|
|
||||||
class="w-1/1"
|
|
||||||
/>
|
|
||||||
</el-form-item>
|
</el-form-item>
|
||||||
</el-col>
|
</el-col>
|
||||||
<!-- TODO @AI:1)新建时,默认为【禁用】后端设置;2)这里只负责展示,后端的 save vo 不要接收该参数; -->
|
|
||||||
<el-col :span="8">
|
<el-col :span="8">
|
||||||
<el-form-item label="状态" prop="status">
|
<el-form-item label="状态" prop="status">
|
||||||
<el-radio-group v-model="formData.status">
|
<el-radio-group v-model="formData.status" disabled>
|
||||||
<el-radio
|
<el-radio
|
||||||
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
v-for="dict in getIntDictOptions(DICT_TYPE.COMMON_STATUS)"
|
||||||
:key="dict.value"
|
:key="dict.value"
|
||||||
|
|
@ -135,15 +125,14 @@
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
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 { AutoCodeRecordApi } from '@/api/mes/md/autocode/record'
|
import { AutoCodeRecordApi } from '@/api/mes/md/autocode/record'
|
||||||
import MdItemBatchConfigForm from './MdItemBatchConfigForm.vue'
|
import MdItemBatchConfigForm from './MdItemBatchConfigForm.vue'
|
||||||
import MdProductBomForm from './MdProductBomForm.vue'
|
import MdProductBomForm from './MdProductBomForm.vue'
|
||||||
import MdProductSopForm from './MdProductSopForm.vue'
|
import MdProductSopForm from './MdProductSopForm.vue'
|
||||||
import MdProductSipForm from './MdProductSipForm.vue'
|
import MdProductSipForm from './MdProductSipForm.vue'
|
||||||
import MdUnitMeasureSelect from '@/views/mes/md/unitmeasure/components/MdUnitMeasureSelect.vue'
|
import MdUnitMeasureSelect from '@/views/mes/md/unitmeasure/components/MdUnitMeasureSelect.vue'
|
||||||
|
import MdItemTypeSelect from '@/views/mes/md/item/type/components/MdItemTypeSelect.vue'
|
||||||
import { CommonStatusEnum } from '@/utils/constants'
|
import { CommonStatusEnum } from '@/utils/constants'
|
||||||
import { defaultProps, handleTree } from '@/utils/tree'
|
|
||||||
import { MesAutoCodeRuleCode } from '@/views/mes/utils/constants'
|
import { MesAutoCodeRuleCode } from '@/views/mes/utils/constants'
|
||||||
|
|
||||||
/** MES 物料产品 表单 */
|
/** MES 物料产品 表单 */
|
||||||
|
|
@ -153,8 +142,11 @@ const { t } = useI18n() // 国际化
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
const dialogVisible = ref(false) // 弹窗的是否展示
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
// TODO @AI:标题对齐下,使用 compute ,然后有新增物料/产品;修改物料/产品;查看物料/产品;
|
const dialogTitle = computed(() => {
|
||||||
const dialogTitle = ref('') // 弹窗的标题
|
if (formType.value === 'create') return '新增物料/产品'
|
||||||
|
if (formType.value === 'update') return '修改物料/产品'
|
||||||
|
return '查看物料/产品'
|
||||||
|
}) // 弹窗标题
|
||||||
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
const activeTab = ref('bom') // 当前激活的 Tab
|
const activeTab = ref('bom') // 当前激活的 Tab
|
||||||
|
|
@ -171,7 +163,8 @@ const formData = ref({
|
||||||
maxStock: 0,
|
maxStock: 0,
|
||||||
highValue: false,
|
highValue: false,
|
||||||
batchFlag: true,
|
batchFlag: true,
|
||||||
remark: undefined
|
remark: undefined,
|
||||||
|
itemOrProduct: undefined
|
||||||
})
|
})
|
||||||
const formRules = reactive({
|
const formRules = reactive({
|
||||||
code: [{ required: true, message: '物料编码不能为空', trigger: 'blur' }],
|
code: [{ required: true, message: '物料编码不能为空', trigger: 'blur' }],
|
||||||
|
|
@ -181,17 +174,7 @@ const formRules = reactive({
|
||||||
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
|
status: [{ required: true, message: '状态不能为空', trigger: 'blur' }]
|
||||||
})
|
})
|
||||||
const formRef = ref() // 表单 Ref
|
const formRef = ref() // 表单 Ref
|
||||||
const itemTypeTree = ref<MdItemTypeVO[]>([]) // 物料分类树
|
const currentItemOrProduct = computed(() => formData.value.itemOrProduct || '') // 物料/产品的标签
|
||||||
const itemTypeList = ref<MdItemTypeVO[]>([]) // 物料分类列表(扁平)
|
|
||||||
|
|
||||||
/** 当前物料的「物料/产品」标识 */
|
|
||||||
const currentItemOrProduct = computed(() => {
|
|
||||||
if (!formData.value.itemTypeId) {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
const itemType = itemTypeList.value.find((t) => t.id === formData.value.itemTypeId)
|
|
||||||
return itemType?.itemOrProduct || ''
|
|
||||||
})
|
|
||||||
|
|
||||||
/** 生成物料编码 */
|
/** 生成物料编码 */
|
||||||
const generateCode = async () => {
|
const generateCode = async () => {
|
||||||
|
|
@ -201,7 +184,6 @@ const generateCode = async () => {
|
||||||
/** 打开弹窗 */
|
/** 打开弹窗 */
|
||||||
const open = async (type: string, id?: number) => {
|
const open = async (type: string, id?: number) => {
|
||||||
dialogVisible.value = true
|
dialogVisible.value = true
|
||||||
dialogTitle.value = t('action.' + type)
|
|
||||||
formType.value = type
|
formType.value = type
|
||||||
activeTab.value = 'bom'
|
activeTab.value = 'bom'
|
||||||
resetForm()
|
resetForm()
|
||||||
|
|
@ -214,9 +196,6 @@ const open = async (type: string, id?: number) => {
|
||||||
formLoading.value = false
|
formLoading.value = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// 物料分类
|
|
||||||
itemTypeList.value = await MdItemTypeApi.getItemTypeSimpleList()
|
|
||||||
itemTypeTree.value = handleTree(itemTypeList.value)
|
|
||||||
}
|
}
|
||||||
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
|
@ -236,7 +215,6 @@ const submitForm = async () => {
|
||||||
await MdItemApi.updateItem(data)
|
await MdItemApi.updateItem(data)
|
||||||
message.success(t('common.updateSuccess'))
|
message.success(t('common.updateSuccess'))
|
||||||
}
|
}
|
||||||
// TODO @AI:【对齐】应该都不需要自动关闭;用户按需添加;
|
|
||||||
dialogVisible.value = false
|
dialogVisible.value = false
|
||||||
// 发送操作成功的事件
|
// 发送操作成功的事件
|
||||||
emit('success')
|
emit('success')
|
||||||
|
|
@ -260,7 +238,8 @@ const resetForm = () => {
|
||||||
maxStock: 0,
|
maxStock: 0,
|
||||||
highValue: false,
|
highValue: false,
|
||||||
batchFlag: true,
|
batchFlag: true,
|
||||||
remark: undefined
|
remark: undefined,
|
||||||
|
itemOrProduct: undefined
|
||||||
}
|
}
|
||||||
formRef.value?.resetFields()
|
formRef.value?.resetFields()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -89,8 +89,13 @@
|
||||||
<!-- 列表 -->
|
<!-- 列表 -->
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true">
|
||||||
<!-- TODO @AI:增加点击进入详情;formType = detail 这种; -->
|
<el-table-column label="物料编码" align="center" prop="code">
|
||||||
<el-table-column label="物料编码" align="center" prop="code" />
|
<template #default="scope">
|
||||||
|
<el-link type="primary" @click="openForm('detail', scope.row.id)">
|
||||||
|
{{ scope.row.code }}
|
||||||
|
</el-link>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
<el-table-column label="物料名称" align="center" prop="name" />
|
<el-table-column label="物料名称" align="center" prop="name" />
|
||||||
<el-table-column label="规格型号" align="center" prop="specification" />
|
<el-table-column label="规格型号" align="center" prop="specification" />
|
||||||
<el-table-column label="单位" align="center" prop="unitMeasureName" />
|
<el-table-column label="单位" align="center" prop="unitMeasureName" />
|
||||||
|
|
@ -105,10 +110,15 @@
|
||||||
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.safeStockFlag" />
|
<dict-tag :type="DICT_TYPE.INFRA_BOOLEAN_STRING" :value="scope.row.safeStockFlag" />
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<!-- TODO @AI:status 改成 switch 单独一个开关; -->
|
<el-table-column label="状态" align="center" prop="status" width="80">
|
||||||
<el-table-column label="状态" align="center" prop="status">
|
|
||||||
<template #default="scope">
|
<template #default="scope">
|
||||||
<dict-tag :type="DICT_TYPE.COMMON_STATUS" :value="scope.row.status" />
|
<el-switch
|
||||||
|
v-model="scope.row.status"
|
||||||
|
:active-value="0"
|
||||||
|
:inactive-value="1"
|
||||||
|
@change="handleStatusChange(scope.row)"
|
||||||
|
:disabled="!checkPermi(['mes:md-item:update'])"
|
||||||
|
/>
|
||||||
</template>
|
</template>
|
||||||
</el-table-column>
|
</el-table-column>
|
||||||
<el-table-column
|
<el-table-column
|
||||||
|
|
@ -169,8 +179,10 @@
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
import { getIntDictOptions, DICT_TYPE } from '@/utils/dict'
|
||||||
|
import { checkPermi } from '@/utils/permission'
|
||||||
import { dateFormatter } from '@/utils/formatTime'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
import download from '@/utils/download'
|
import download from '@/utils/download'
|
||||||
|
import { CommonStatusEnum } from '@/utils/constants'
|
||||||
import { MdItemApi, MdItemVO } from '@/api/mes/md/item'
|
import { MdItemApi, MdItemVO } from '@/api/mes/md/item'
|
||||||
import MdItemForm from './MdItemForm.vue'
|
import MdItemForm from './MdItemForm.vue'
|
||||||
import MdItemImportForm from './MdItemImportForm.vue'
|
import MdItemImportForm from './MdItemImportForm.vue'
|
||||||
|
|
@ -234,6 +246,23 @@ const openForm = (type: string, id?: number) => {
|
||||||
formRef.value.open(type, id)
|
formRef.value.open(type, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** 切换物料状态 */
|
||||||
|
const handleStatusChange = async (row: MdItemVO) => {
|
||||||
|
try {
|
||||||
|
// 修改状态的二次确认
|
||||||
|
const text = row.status === CommonStatusEnum.ENABLE ? '启用' : '停用'
|
||||||
|
await message.confirm('确认要"' + text + '""' + row.name + '"物料吗?')
|
||||||
|
// 发起修改状态
|
||||||
|
await MdItemApi.updateItemStatus(row.id, row.status)
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {
|
||||||
|
// 取消后,恢复按钮
|
||||||
|
row.status =
|
||||||
|
row.status === CommonStatusEnum.ENABLE ? CommonStatusEnum.DISABLE : CommonStatusEnum.ENABLE
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/** 删除按钮操作 */
|
/** 删除按钮操作 */
|
||||||
const handleDelete = async (id: number) => {
|
const handleDelete = async (id: number) => {
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
<!-- MES 物料分类选择器:树形下拉,只允许选择叶节点 -->
|
||||||
|
<template>
|
||||||
|
<el-tree-select
|
||||||
|
v-model="selectValue"
|
||||||
|
:data="treeData"
|
||||||
|
:props="defaultProps"
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:disabled="disabled"
|
||||||
|
check-strictly
|
||||||
|
default-expand-all
|
||||||
|
filterable
|
||||||
|
class="!w-1/1"
|
||||||
|
@change="handleChange"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { MdItemTypeApi, MdItemTypeVO } from '@/api/mes/md/item/type'
|
||||||
|
import { defaultProps, handleTree } from '@/utils/tree'
|
||||||
|
|
||||||
|
defineOptions({ name: 'MdItemTypeSelect' })
|
||||||
|
|
||||||
|
const props = withDefaults(
|
||||||
|
defineProps<{
|
||||||
|
modelValue?: number
|
||||||
|
disabled?: boolean
|
||||||
|
placeholder?: string
|
||||||
|
}>(),
|
||||||
|
{
|
||||||
|
disabled: false,
|
||||||
|
placeholder: '请选择物料分类'
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
const emit = defineEmits<{
|
||||||
|
'update:modelValue': [value: number | undefined]
|
||||||
|
change: [item: MdItemTypeVO | undefined]
|
||||||
|
}>()
|
||||||
|
|
||||||
|
const allList = ref<MdItemTypeVO[]>([])
|
||||||
|
const treeData = ref<any[]>([])
|
||||||
|
|
||||||
|
const selectValue = computed({
|
||||||
|
get: () => props.modelValue,
|
||||||
|
set: (val) => emit('update:modelValue', val)
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleChange = (val: number | undefined) => {
|
||||||
|
const item = allList.value.find((o) => o.id === val)
|
||||||
|
emit('change', item)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(async () => {
|
||||||
|
allList.value = await MdItemTypeApi.getItemTypeSimpleList()
|
||||||
|
treeData.value = handleTree(allList.value)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
Loading…
Reference in New Issue