feat(mes): 新增入库单行级联删除功能

实现了根据入库单编号删除所有相关行的功能,增强了数据管理的灵活性和一致性。
pull/871/MERGE
YunaiV 2026-03-31 09:01:57 +08:00
parent 76f47a476b
commit 4de57ee672
4 changed files with 136 additions and 117 deletions

View File

@ -11,9 +11,6 @@ export interface WmMiscReceiptLineVO {
warehouseId: number warehouseId: number
locationId: number locationId: number
areaId: number areaId: number
productionDate: string
expireDate: string
lotNumber: string
remark: string remark: string
createTime: string createTime: string
} }

View File

@ -7,6 +7,7 @@
:rules="formRules" :rules="formRules"
label-width="110px" label-width="110px"
v-loading="formLoading" v-loading="formLoading"
:disabled="isDetail"
> >
<el-row> <el-row>
<el-col :span="8"> <el-col :span="8">
@ -17,7 +18,7 @@
:disabled="isHeaderReadonly" :disabled="isHeaderReadonly"
> >
<template #append> <template #append>
<el-button @click="generateCode"> </el-button> <el-button @click="generateCode" :disabled="isHeaderReadonly"> 生成 </el-button>
</template> </template>
</el-input> </el-input>
</el-form-item> </el-form-item>
@ -101,10 +102,21 @@
<MiscReceiptLineList :receipt-id="formData.id" :form-type="formType" /> <MiscReceiptLineList :receipt-id="formData.id" :form-type="formType" />
</template> </template>
<template #footer> <template #footer>
<el-button v-if="isUpdate" @click="submitForm" type="primary" :disabled="formLoading"> <el-button v-if="isEditable" @click="submitForm" type="primary" :disabled="formLoading">
</el-button> </el-button>
<el-button @click="dialogVisible = false"> </el-button> <el-button
v-if="isEditable && formData.status === MesWmMiscReceiptStatusEnum.PREPARE"
@click="handleSubmit"
type="warning"
:disabled="formLoading"
>
</el-button>
<el-button v-if="isFinish" @click="handleFinish" type="success" :disabled="formLoading">
执行入库
</el-button>
<el-button @click="dialogVisible = false"> </el-button>
</template> </template>
</Dialog> </Dialog>
</template> </template>
@ -114,19 +126,35 @@ import { generateRandomStr } from '@/utils'
import { DICT_TYPE, getIntDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import { WmMiscReceiptApi, WmMiscReceiptVO } from '@/api/mes/wm/miscreceipt' import { WmMiscReceiptApi, WmMiscReceiptVO } from '@/api/mes/wm/miscreceipt'
import MiscReceiptLineList from './MiscReceiptLineList.vue' import MiscReceiptLineList from './MiscReceiptLineList.vue'
import { MesWmMiscReceiptStatusEnum } from '@/views/mes/utils/constants'
defineOptions({ name: 'MiscReceiptForm' }) defineOptions({ name: 'MiscReceiptForm' })
const emit = defineEmits(['success'])
const message = useMessage() const message = useMessage()
const dialogVisible = ref(false) const dialogVisible = ref(false)
const formLoading = ref(false) const formLoading = ref(false)
const formType = ref<string>('create') // create / update / detail const formType = ref<string>('create') // create / update / finish / detail
const isEditable = computed(() => ['create', 'update'].includes(formType.value))
const isFinish = computed(() => formType.value === 'finish')
const isDetail = computed(() => ['detail', 'finish'].includes(formType.value))
const isHeaderReadonly = computed(() => ['detail', 'finish'].includes(formType.value))
const dialogTitle = computed(() => {
const titles: Record<string, string> = {
create: '新增杂项入库单',
update: '编辑杂项入库单',
finish: '执行入库',
detail: '杂项入库单详情'
}
return titles[formType.value] || formType.value
})
const formData = ref({ const formData = ref({
id: undefined as number | undefined, id: undefined as number | undefined,
code: undefined, code: undefined,
name: undefined, name: undefined,
type: undefined, type: undefined,
status: undefined as number | undefined,
sourceDocId: undefined, sourceDocId: undefined,
sourceDocCode: undefined, sourceDocCode: undefined,
sourceDocType: undefined, sourceDocType: undefined,
@ -140,17 +168,7 @@ const formRules = reactive({
receiptDate: [{ required: true, message: '入库日期不能为空', trigger: 'blur' }] receiptDate: [{ required: true, message: '入库日期不能为空', trigger: 'blur' }]
}) })
const formRef = ref() const formRef = ref()
const originalFormData = ref<string>('') //
const isUpdate = computed(() => ['create', 'update'].includes(formType.value))
const isHeaderReadonly = computed(() => formType.value === 'detail')
const dialogTitle = computed(() => {
const titles = {
create: '新增杂项入库单',
update: '编辑杂项入库单',
detail: '杂项入库单详情'
}
return titles[formType.value] || formType.value
})
/** 生成入库单编号 */ /** 生成入库单编号 */
const generateCode = () => { const generateCode = () => {
@ -170,11 +188,12 @@ const open = async (type: string, id?: number) => {
formLoading.value = false formLoading.value = false
} }
} }
//
originalFormData.value = JSON.stringify(formData.value)
} }
defineExpose({ open }) defineExpose({ open })
/** 提交表单 */ /** 保存表单create/update 模式) */
const emit = defineEmits(['success'])
const submitForm = async () => { const submitForm = async () => {
await formRef.value.validate() await formRef.value.validate()
formLoading.value = true formLoading.value = true
@ -184,17 +203,57 @@ const submitForm = async () => {
const res = await WmMiscReceiptApi.createMiscReceipt(data) const res = await WmMiscReceiptApi.createMiscReceipt(data)
message.success('新增成功') message.success('新增成功')
formData.value.id = res formData.value.id = res
formData.value.status = MesWmMiscReceiptStatusEnum.PREPARE
formType.value = 'update' formType.value = 'update'
} else { } else {
await WmMiscReceiptApi.updateMiscReceipt(data) await WmMiscReceiptApi.updateMiscReceipt(data)
message.success('修改成功') message.success('修改成功')
} }
//
originalFormData.value = JSON.stringify(formData.value)
emit('success') emit('success')
} finally { } finally {
formLoading.value = false formLoading.value = false
} }
} }
/** 提交操作:表单修改过则先保存,再提交 */
const handleSubmit = async () => {
await formRef.value.validate()
try {
await message.confirm('确认提交该杂项入库单?【提交后将不能修改】')
formLoading.value = true
// 1.
if (JSON.stringify(formData.value) !== originalFormData.value) {
const data = formData.value as unknown as WmMiscReceiptVO
await WmMiscReceiptApi.updateMiscReceipt(data)
}
// 2.
await WmMiscReceiptApi.submitMiscReceipt(formData.value.id!)
message.success('提交成功')
dialogVisible.value = false
emit('success')
} catch {
} finally {
formLoading.value = false
}
}
/** 执行入库 */
const handleFinish = async () => {
try {
await message.confirm('确认执行入库?执行后将更新库存台账。')
formLoading.value = true
await WmMiscReceiptApi.finishMiscReceipt(formData.value.id!)
message.success('入库成功')
dialogVisible.value = false
emit('success')
} catch {
} finally {
formLoading.value = false
}
}
/** 重置表单 */ /** 重置表单 */
const resetForm = () => { const resetForm = () => {
formData.value = { formData.value = {
@ -202,6 +261,7 @@ const resetForm = () => {
code: undefined, code: undefined,
name: undefined, name: undefined,
type: undefined, type: undefined,
status: undefined,
sourceDocId: undefined, sourceDocId: undefined,
sourceDocCode: undefined, sourceDocCode: undefined,
sourceDocType: undefined, sourceDocType: undefined,

View File

@ -1,7 +1,7 @@
<!-- MES 杂项入库单行列表子组件 --> <!-- MES 杂项入库单行列表子组件 -->
<template> <template>
<div> <div>
<el-button v-if="isUpdate" type="primary" plain @click="openForm('create')" class="mb-10px"> <el-button v-if="isEditable" type="primary" plain @click="openForm('create')" class="mb-10px">
<Icon icon="ep:plus" class="mr-5px" /> 添加物料 <Icon icon="ep:plus" class="mr-5px" /> 添加物料
</el-button> </el-button>
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" border> <el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" border>
@ -14,7 +14,7 @@
<el-table-column label="仓库" align="center" prop="warehouseName" min-width="100" /> <el-table-column label="仓库" align="center" prop="warehouseName" min-width="100" />
<el-table-column label="库区" align="center" prop="locationName" min-width="100" /> <el-table-column label="库区" align="center" prop="locationName" min-width="100" />
<el-table-column label="库位" align="center" prop="areaName" min-width="100" /> <el-table-column label="库位" align="center" prop="areaName" min-width="100" />
<el-table-column v-if="isUpdate" label="操作" align="center" width="160" fixed="right"> <el-table-column v-if="isEditable" label="操作" align="center" width="160" fixed="right">
<template #default="scope"> <template #default="scope">
<el-button link type="primary" @click="openForm('update', scope.row.id)"> <el-button link type="primary" @click="openForm('update', scope.row.id)">
编辑 编辑
@ -114,24 +114,46 @@ import WmWarehouseAreaSelect from '@/views/mes/wm/warehouse/components/WmWarehou
defineOptions({ name: 'MiscReceiptLineList' }) defineOptions({ name: 'MiscReceiptLineList' })
const props = defineProps<{
receiptId: number
formType: string
}>()
const message = useMessage() const message = useMessage()
const props = defineProps({ const isEditable = computed(() => ['create', 'update'].includes(props.formType))
receiptId: {
type: Number,
required: true
},
formType: {
type: String,
required: true
}
})
// ==================== ====================
const loading = ref(false) const loading = ref(false)
const list = ref<WmMiscReceiptLineVO[]>([]) const list = ref<WmMiscReceiptLineVO[]>([])
/** 查询行列表 */
const getList = async () => {
loading.value = true
try {
list.value = await WmMiscReceiptLineApi.getMiscReceiptLineListByReceiptId(props.receiptId)
} finally {
loading.value = false
}
}
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
await message.delConfirm()
await WmMiscReceiptLineApi.deleteMiscReceiptLine(id)
message.success('删除成功')
await getList()
} catch {}
}
// ==================== / ====================
const dialogVisible = ref(false) const dialogVisible = ref(false)
const formLoading = ref(false) const formLoading = ref(false)
const lineFormType = ref<string>('create') const lineFormType = ref<string>('create')
const dialogTitle = computed(() => {
return lineFormType.value === 'create' ? '添加物料' : '编辑物料'
})
const formData = ref({ const formData = ref({
id: undefined as number | undefined, id: undefined as number | undefined,
receiptId: props.receiptId, receiptId: props.receiptId,
@ -153,21 +175,6 @@ const formRules = reactive({
}) })
const formRef = ref() const formRef = ref()
const isUpdate = computed(() => ['create', 'update'].includes(props.formType))
const dialogTitle = computed(() => {
return lineFormType.value === 'create' ? '添加物料' : '编辑物料'
})
/** 查询列表 */
const getList = async () => {
loading.value = true
try {
list.value = await WmMiscReceiptLineApi.getMiscReceiptLineListByReceiptId(props.receiptId)
} finally {
loading.value = false
}
}
/** 仓库变化时,清空库区和库位 */ /** 仓库变化时,清空库区和库位 */
const handleWarehouseChange = () => { const handleWarehouseChange = () => {
formData.value.locationId = undefined formData.value.locationId = undefined
@ -179,7 +186,7 @@ const handleLocationChange = () => {
formData.value.areaId = undefined formData.value.areaId = undefined
} }
/** 打开表单 */ /** 打开表单弹窗 */
const openForm = async (type: string, id?: number) => { const openForm = async (type: string, id?: number) => {
dialogVisible.value = true dialogVisible.value = true
lineFormType.value = type lineFormType.value = type
@ -214,16 +221,6 @@ const submitForm = async () => {
} }
} }
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
await message.delConfirm()
await WmMiscReceiptLineApi.deleteMiscReceiptLine(id)
message.success('删除成功')
await getList()
} catch {}
}
/** 重置表单 */ /** 重置表单 */
const resetForm = () => { const resetForm = () => {
formData.value = { formData.value = {
@ -240,6 +237,7 @@ const resetForm = () => {
formRef.value?.resetFields() formRef.value?.resetFields()
} }
/** 初始化 */
onMounted(() => { onMounted(() => {
getList() getList()
}) })

View File

@ -92,7 +92,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">
<el-table-column label="入库单编号" align="center" prop="code" min-width="160" /> <el-table-column label="入库单编号" align="center" prop="code" min-width="160">
<template #default="scope">
<el-button link type="primary" @click="openForm('detail', scope.row.id)">
{{ scope.row.code }}
</el-button>
</template>
</el-table-column>
<el-table-column label="入库单名称" align="center" prop="name" min-width="150" /> <el-table-column label="入库单名称" align="center" prop="name" min-width="150" />
<el-table-column label="杂项类型" align="center" prop="type" min-width="100"> <el-table-column label="杂项类型" align="center" prop="type" min-width="100">
<template #default="scope"> <template #default="scope">
@ -114,7 +120,7 @@
</el-table-column> </el-table-column>
<el-table-column label="操作" align="center" width="240" fixed="right"> <el-table-column label="操作" align="center" width="240" fixed="right">
<template #default="scope"> <template #default="scope">
<!-- 草稿编辑提交删除 --> <!-- 草稿编辑删除 -->
<el-button <el-button
link link
type="primary" type="primary"
@ -124,15 +130,6 @@
> >
编辑 编辑
</el-button> </el-button>
<el-button
link
type="warning"
@click="handleSubmit(scope.row.id)"
v-hasPermi="['mes:wm:misc-receipt:submit']"
v-if="scope.row.status === MesWmMiscReceiptStatusEnum.PREPARE"
>
提交
</el-button>
<el-button <el-button
link link
type="danger" type="danger"
@ -145,8 +142,8 @@
<!-- 已审批执行入库取消 --> <!-- 已审批执行入库取消 -->
<el-button <el-button
link link
type="primary" type="success"
@click="handleFinish(scope.row.id)" @click="openForm('finish', scope.row.id)"
v-hasPermi="['mes:wm:misc-receipt:finish']" v-hasPermi="['mes:wm:misc-receipt:finish']"
v-if="scope.row.status === MesWmMiscReceiptStatusEnum.APPROVED" v-if="scope.row.status === MesWmMiscReceiptStatusEnum.APPROVED"
> >
@ -161,20 +158,6 @@
> >
取消 取消
</el-button> </el-button>
<!-- 已完成/已取消查看详情 -->
<el-button
link
type="primary"
@click="openForm('detail', scope.row.id)"
v-hasPermi="['mes:wm:misc-receipt:query']"
v-if="
[MesWmMiscReceiptStatusEnum.FINISHED, MesWmMiscReceiptStatusEnum.CANCELED].includes(
scope.row.status
)
"
>
详情
</el-button>
</template> </template>
</el-table-column> </el-table-column>
</el-table> </el-table>
@ -191,7 +174,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { dateFormatter2 } from '@/utils/formatTime' import { dateFormatter2 } from '@/utils/formatTime'
import { DICT_TYPE, getIntDictOptions, getStrDictOptions } from '@/utils/dict' import { DICT_TYPE, getIntDictOptions } from '@/utils/dict'
import download from '@/utils/download' import download from '@/utils/download'
import { WmMiscReceiptApi, WmMiscReceiptVO } from '@/api/mes/wm/miscreceipt' import { WmMiscReceiptApi, WmMiscReceiptVO } from '@/api/mes/wm/miscreceipt'
import MiscReceiptForm from './MiscReceiptForm.vue' import MiscReceiptForm from './MiscReceiptForm.vue'
@ -247,36 +230,6 @@ const openForm = (type: string, id?: number) => {
formRef.value.open(type, id) formRef.value.open(type, id)
} }
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
await message.delConfirm()
await WmMiscReceiptApi.deleteMiscReceipt(id)
message.success(t('common.delSuccess'))
await getList()
} catch {}
}
/** 提交按钮操作 */
const handleSubmit = async (id: number) => {
try {
await message.confirm('确认提交该杂项入库单吗?')
await WmMiscReceiptApi.submitMiscReceipt(id)
message.success('提交成功')
await getList()
} catch {}
}
/** 执行入库按钮操作 */
const handleFinish = async (id: number) => {
try {
await message.confirm('确认执行入库吗?')
await WmMiscReceiptApi.finishMiscReceipt(id)
message.success('入库成功')
await getList()
} catch {}
}
/** 取消按钮操作 */ /** 取消按钮操作 */
const handleCancel = async (id: number) => { const handleCancel = async (id: number) => {
try { try {
@ -287,6 +240,16 @@ const handleCancel = async (id: number) => {
} catch {} } catch {}
} }
/** 删除按钮操作 */
const handleDelete = async (id: number) => {
try {
await message.delConfirm()
await WmMiscReceiptApi.deleteMiscReceipt(id)
message.success(t('common.delSuccess'))
await getList()
} catch {}
}
/** 导出按钮操作 */ /** 导出按钮操作 */
const handleExport = async () => { const handleExport = async () => {
try { try {
@ -300,6 +263,7 @@ const handleExport = async () => {
} }
} }
/** 初始化 */
onMounted(() => { onMounted(() => {
getList() getList()
}) })