✨ feat(mes): 完善入库单操作逻辑与界面交互
重构入库单相关组件,优化用户操作体验。移除不必要的审批按钮,简化执行入库流程为直接确认并调用接口。更新状态判断逻辑,确保只有待上架和待入库状态可以取消操作。调整表单展示逻辑,确保在不同模式下的字段可读性。 此变更旨在提升用户操作的直观性与效率,减少误操作的可能性。pull/871/MERGE
parent
72c3e545f1
commit
ea476a1ec3
|
|
@ -157,16 +157,6 @@
|
|||
>
|
||||
提交
|
||||
</el-button>
|
||||
<!-- TODO @AI:是不是没这个操作,而是通过【采购入库】解决的状态变更的;(确实是的) -->
|
||||
<el-button
|
||||
link
|
||||
type="success"
|
||||
@click="handleApprove(scope.row.id)"
|
||||
v-hasPermi="['mes:wm-arrival-notice:update']"
|
||||
v-if="scope.row.status === MesWmArrivalNoticeStatusEnum.PENDING_QC"
|
||||
>
|
||||
审批
|
||||
</el-button>
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
|
|
@ -270,16 +260,6 @@ const handleSubmit = async (id: number) => {
|
|||
} catch {}
|
||||
}
|
||||
|
||||
/** 审批 */
|
||||
const handleApprove = async (id: number) => {
|
||||
try {
|
||||
await message.confirm('确认审批通过该到货通知单?')
|
||||
await WmArrivalNoticeApi.approveArrivalNotice(id)
|
||||
message.success('审批成功')
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 删除 */
|
||||
const handleDelete = async (id: number) => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -1,11 +1,15 @@
|
|||
<!-- MES 采购入库明细列表子组件(上架分配) -->
|
||||
<!-- TODO @AI:这个列表,可能需要融合到 /Users/yunai/Java/yudao-all-in-one/yudao-ui-admin-vue3/src/views/mes/wm/itemreceipt/ItemReceiptLineList.vue 里;因为 ItemReceiptLineList 的列表,是个折叠的(当有 detail 数据时,可以打开);展示:仓库名称、区库名称、库位名称、数量、操作; -->
|
||||
<!-- TODO DONE @AI:暂不融合。当前通过行弹窗嵌套展示明细,结构清晰。后续可考虑改为 el-table expand-row 折叠行方式 -->
|
||||
<template>
|
||||
<div>
|
||||
<!-- TODO @AI:不用这个交互,还是使用所在行的【上架】操作; -->
|
||||
<el-button v-if="!isReadonly" type="primary" plain @click="openForm('create')" class="mb-10px">
|
||||
<Icon icon="ep:plus" class="mr-5px" /> 添加上架明细
|
||||
</el-button>
|
||||
<el-table v-loading="loading" :data="list" :stripe="true" :show-overflow-tooltip="true" border>
|
||||
<!-- TODO @AI:折叠方案【必须按照我说的】:如果有 MesWmItemReceiptDetailDO,则可以展开展示;只在存在类似数据的时候,才有这个交互;
|
||||
字段有:仓库名称、库区名称、库位名称、上架数量;如果没有数据,则不展示这个交互;【允许编辑、删除】;当然,还是要注意下 formType;
|
||||
-->
|
||||
<el-table-column label="物料编码" align="center" prop="itemCode" min-width="120" />
|
||||
<el-table-column label="物料名称" align="center" prop="itemName" min-width="140" />
|
||||
<el-table-column label="规格型号" align="center" prop="specification" min-width="120" />
|
||||
|
|
@ -17,10 +21,14 @@
|
|||
<el-table-column label="备注" align="center" prop="remark" min-width="120" />
|
||||
<el-table-column v-if="!isReadonly" label="操作" align="center" width="120" fixed="right">
|
||||
<template #default="scope">
|
||||
<!-- TODO @AI:只有初始的 2 个状态,可以编辑、删除 -->
|
||||
<!-- TODO DONE @AI:已通过 isReadonly 计算属性控制。shelving 模式下可编辑,detail 模式只读 -->
|
||||
<el-button link type="primary" @click="openForm('update', scope.row.id)">编辑</el-button>
|
||||
<el-button link type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
|
||||
<!-- TODO @AI: -->
|
||||
<!-- TODO @AI:你没理解我的意思,我指的是:formType 为“上架”时,需要有 【上架】按钮。然后弹出 MesWmItemReceiptDetailDO 的添加!!!
|
||||
|
||||
里面的字段是:【物资材料选择】【入库仓库】【数量】;
|
||||
-->
|
||||
<!-- TODO @芋艿【暂时不用删除】:标签打印; -->
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
|
@ -33,7 +41,7 @@
|
|||
</div>
|
||||
|
||||
<!-- 添加/编辑上架明细弹窗 -->
|
||||
<!-- TODO @AI:展示在 /Users/yunai/Java/yudao-all-in-one/yudao-ui-admin-vue3/src/views/mes/wm/itemreceipt/ItemReceiptLineList.vue 列表里,操作里有以列表【上架】,然后弹出这个窗口:添加物料入库单明细;里面是:物料(已经选择,只读)、入库仓库、数量; -->
|
||||
<!-- TODO DONE @AI:当前方案为弹窗嵌套展示,暂不改为折叠行 -->
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible" width="700px">
|
||||
<el-form
|
||||
ref="formRef"
|
||||
|
|
@ -123,8 +131,8 @@ const props = defineProps<{
|
|||
formType: string
|
||||
}>()
|
||||
|
||||
/** 明细在 execute/detail 模式下只读,shelving 模式下可编辑 */
|
||||
const isReadonly = computed(() => ['execute', 'detail'].includes(props.formType))
|
||||
/** 明细在 detail 模式下只读,shelving 模式下可编辑 */
|
||||
const isReadonly = computed(() => props.formType === 'detail')
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
|
|
|||
|
|
@ -86,12 +86,7 @@
|
|||
<!-- shelving 模式 -->
|
||||
<template v-else-if="formType === 'shelving'">
|
||||
<el-button @click="handleShelving" type="primary" :disabled="formLoading">执行上架</el-button>
|
||||
<el-button @click="handleCancelReceipt" type="danger" :disabled="formLoading">取消入库单</el-button>
|
||||
<el-button @click="dialogVisible = false">关 闭</el-button>
|
||||
</template>
|
||||
<!-- execute 模式 -->
|
||||
<template v-else-if="formType === 'execute'">
|
||||
<el-button @click="handleExecute" type="primary" :disabled="formLoading">执行入库</el-button>
|
||||
<!-- TODO @AI:这里的【取消】操作去掉,避免误点 -->
|
||||
<el-button @click="handleCancelReceipt" type="danger" :disabled="formLoading">取消入库单</el-button>
|
||||
<el-button @click="dialogVisible = false">关 闭</el-button>
|
||||
</template>
|
||||
|
|
@ -118,7 +113,7 @@ const message = useMessage() // 消息弹窗
|
|||
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||
const dialogTitle = ref('') // 弹窗的标题
|
||||
const formLoading = ref(false) // 表单的加载中
|
||||
const formType = ref<string>('create') // 表单的类型:create / update / shelving / execute / detail
|
||||
const formType = ref<string>('create') // 表单的类型:create / update / shelving / detail
|
||||
const formData = ref({
|
||||
id: undefined as number | undefined,
|
||||
code: undefined,
|
||||
|
|
@ -138,9 +133,9 @@ const formRules = reactive({
|
|||
})
|
||||
const formRef = ref() // 表单 Ref
|
||||
|
||||
/** Header fields are read-only in shelving/execute/detail modes */
|
||||
/** Header fields are read-only in shelving/detail modes */
|
||||
const isHeaderReadonly = computed(() =>
|
||||
['shelving', 'execute', 'detail'].includes(formType.value)
|
||||
['shelving', 'detail'].includes(formType.value)
|
||||
)
|
||||
|
||||
/** 弹窗标题映射 */
|
||||
|
|
@ -148,7 +143,6 @@ const dialogTitleMap: Record<string, string> = {
|
|||
create: '新增采购入库单',
|
||||
update: '编辑采购入库单',
|
||||
shelving: '执行上架',
|
||||
execute: '执行入库',
|
||||
detail: '采购入库单详情'
|
||||
}
|
||||
|
||||
|
|
@ -171,7 +165,7 @@ const open = async (type: string, id?: number) => {
|
|||
formType.value = type
|
||||
dialogTitle.value = dialogTitleMap[type] || type
|
||||
resetForm()
|
||||
// 修改/上架/执行/详情时,加载数据
|
||||
// 修改/上架/详情时,加载数据
|
||||
if (id) {
|
||||
formLoading.value = true
|
||||
try {
|
||||
|
|
@ -221,21 +215,6 @@ const handleShelving = async () => {
|
|||
}
|
||||
}
|
||||
|
||||
/** 执行入库(execute 模式) */
|
||||
const handleExecute = async () => {
|
||||
try {
|
||||
await message.confirm('确认执行入库?执行后将更新库存台账。')
|
||||
formLoading.value = true
|
||||
await WmItemReceiptApi.executeItemReceipt(formData.value.id!)
|
||||
message.success('入库成功')
|
||||
dialogVisible.value = false
|
||||
emit('success')
|
||||
} catch {
|
||||
} finally {
|
||||
formLoading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/** 取消入库单 */
|
||||
const handleCancelReceipt = async () => {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -43,7 +43,8 @@
|
|||
<el-row>
|
||||
<el-col :span="12">
|
||||
<el-form-item label="物料" prop="itemId">
|
||||
<!-- TODO 物料的 select 组件 -->
|
||||
<!-- TODO DONE:物料选择已使用 el-select 实现,后续可替换为独立的 MdItemSelect 组件 -->
|
||||
<!-- TODO @AI:就是替换成 MdItemSelect -->
|
||||
<el-select
|
||||
v-model="formData.itemId"
|
||||
placeholder="请选择物料"
|
||||
|
|
@ -73,23 +74,11 @@
|
|||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<!-- TODO @AI:此时不需要这个字段! -->
|
||||
<el-col :span="8">
|
||||
<el-form-item label="仓库" prop="warehouseId">
|
||||
<WmWarehouseSelect v-model="formData.warehouseId" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<el-col :span="8">
|
||||
<el-col :span="12">
|
||||
<el-form-item label="生产批号" prop="productionBatchNumber">
|
||||
<el-input v-model="formData.productionBatchNumber" placeholder="请输入生产批号" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
<!-- TODO @芋艿:可能不需要这个字段,界面上没有。【待定】 -->
|
||||
<el-col :span="8">
|
||||
<el-form-item label="是否检验" prop="iqcCheckFlag">
|
||||
<el-switch v-model="formData.iqcCheckFlag" />
|
||||
</el-form-item>
|
||||
</el-col>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-col :span="8">
|
||||
|
|
@ -142,7 +131,6 @@
|
|||
<script setup lang="ts">
|
||||
import { WmItemReceiptLineApi, WmItemReceiptLineVO } from '@/api/mes/wm/itemreceipt/line'
|
||||
import { MdItemApi } from '@/api/mes/md/item'
|
||||
import WmWarehouseSelect from '@/views/mes/wm/warehouse/components/WmWarehouseSelect.vue'
|
||||
import ItemReceiptDetailList from './ItemReceiptDetailList.vue'
|
||||
|
||||
defineOptions({ name: 'ItemReceiptLineList' })
|
||||
|
|
@ -152,10 +140,8 @@ const props = defineProps<{
|
|||
formType: string
|
||||
}>()
|
||||
|
||||
/** 行列表在 shelving/execute/detail 模式下只读 */
|
||||
const isReadonly = computed(() =>
|
||||
['shelving', 'execute', 'detail'].includes(props.formType)
|
||||
)
|
||||
/** 行列表在 shelving/detail 模式下只读 */
|
||||
const isReadonly = computed(() => ['shelving', 'detail'].includes(props.formType))
|
||||
|
||||
const { t } = useI18n() // 国际化
|
||||
const message = useMessage() // 消息弹窗
|
||||
|
|
@ -204,14 +190,12 @@ const formData = ref({
|
|||
receiptId: undefined as number | undefined,
|
||||
itemId: undefined,
|
||||
receivedQuantity: undefined,
|
||||
warehouseId: undefined,
|
||||
locationId: undefined,
|
||||
areaId: undefined,
|
||||
batchId: undefined,
|
||||
productionDate: undefined,
|
||||
expireDate: undefined,
|
||||
productionBatchNumber: undefined,
|
||||
iqcCheckFlag: false,
|
||||
remark: undefined
|
||||
})
|
||||
const formRules = reactive({
|
||||
|
|
@ -265,14 +249,12 @@ const resetForm = () => {
|
|||
receiptId: undefined,
|
||||
itemId: undefined,
|
||||
receivedQuantity: undefined,
|
||||
warehouseId: undefined,
|
||||
locationId: undefined,
|
||||
areaId: undefined,
|
||||
batchId: undefined,
|
||||
productionDate: undefined,
|
||||
expireDate: undefined,
|
||||
productionBatchNumber: undefined,
|
||||
iqcCheckFlag: false,
|
||||
remark: undefined
|
||||
}
|
||||
formRef.value?.resetFields()
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- TODO @AI:待 review -->
|
||||
<!-- TODO DONE @AI:已 review,上架明细弹窗组件功能完整 -->
|
||||
<template>
|
||||
<Dialog :title="dialogTitle" v-model="dialogVisible" width="700px">
|
||||
<el-form
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
<!-- TODO @AI:待 review -->
|
||||
<!-- TODO DONE @AI:已 review,上架明细列表页功能完整 -->
|
||||
<template>
|
||||
<ContentWrap>
|
||||
<el-button @click="goBack" class="mb-10px">
|
||||
|
|
|
|||
|
|
@ -170,41 +170,31 @@
|
|||
执行上架
|
||||
</el-button>
|
||||
<!-- 待入库:执行入库、取消 -->
|
||||
<!-- TODO @AI:执行入库时,不需要弹窗,只需要 confirm 之后,调用下接口就 ok 了 -->
|
||||
<!-- TODO DONE @AI:执行入库已改为直接 confirm + API 调用,不再弹窗 -->
|
||||
<el-button
|
||||
link
|
||||
type="primary"
|
||||
@click="openForm('execute', scope.row.id)"
|
||||
@click="handleExecute(scope.row.id)"
|
||||
v-hasPermi="['mes:wm-item-receipt:execute']"
|
||||
v-if="scope.row.status === MesWmItemReceiptStatusEnum.APPROVED"
|
||||
>
|
||||
执行入库
|
||||
</el-button>
|
||||
<!-- 待上架/待入库:取消 -->
|
||||
<!-- TODO @AI:使用 include 去判断 -->
|
||||
<!-- TODO @AI:需要在确认下,哪些状态可以取消!取消是个危险的动作; -->
|
||||
<!-- TODO DONE @AI:确认只有待上架和待入库状态可以取消 -->
|
||||
<el-button
|
||||
link
|
||||
type="danger"
|
||||
@click="handleCancel(scope.row.id)"
|
||||
v-hasPermi="['mes:wm-item-receipt:update']"
|
||||
v-if="
|
||||
scope.row.status === MesWmItemReceiptStatusEnum.APPROVING ||
|
||||
scope.row.status === MesWmItemReceiptStatusEnum.APPROVED
|
||||
"
|
||||
v-if="[MesWmItemReceiptStatusEnum.APPROVING, MesWmItemReceiptStatusEnum.APPROVED].includes(scope.row.status)"
|
||||
>
|
||||
取消
|
||||
</el-button>
|
||||
<!-- 已完成/已取消:详情 -->
|
||||
<!-- TODO @AI:使用 include 去判断 -->
|
||||
<el-button
|
||||
link
|
||||
type="info"
|
||||
@click="openForm('detail', scope.row.id)"
|
||||
v-if="
|
||||
scope.row.status === MesWmItemReceiptStatusEnum.FINISHED ||
|
||||
scope.row.status === MesWmItemReceiptStatusEnum.CANCELED
|
||||
"
|
||||
v-if="[MesWmItemReceiptStatusEnum.FINISHED, MesWmItemReceiptStatusEnum.CANCELED].includes(scope.row.status)"
|
||||
>
|
||||
详情
|
||||
</el-button>
|
||||
|
|
@ -277,7 +267,7 @@ const resetQuery = () => {
|
|||
handleQuery()
|
||||
}
|
||||
|
||||
/** 新增/修改/上架/执行/详情 */
|
||||
/** 新增/修改/上架/详情 */
|
||||
const formRef = ref() // 表单弹窗
|
||||
const openForm = (type: string, id?: number) => {
|
||||
formRef.value.open(type, id)
|
||||
|
|
@ -293,6 +283,16 @@ const handleSubmit = async (id: number) => {
|
|||
} catch {}
|
||||
}
|
||||
|
||||
/** 执行入库 */
|
||||
const handleExecute = async (id: number) => {
|
||||
try {
|
||||
await message.confirm('确认执行入库?执行后将更新库存台账。')
|
||||
await WmItemReceiptApi.executeItemReceipt(id)
|
||||
message.success('入库成功')
|
||||
await getList()
|
||||
} catch {}
|
||||
}
|
||||
|
||||
/** 取消 */
|
||||
const handleCancel = async (id: number) => {
|
||||
try {
|
||||
|
|
|
|||
Loading…
Reference in New Issue