src/api/basicData/productModel.js
@@ -6,4 +6,12 @@ method: 'get', params: query }) } export function productModelListByUrl(url, query) { return request({ url, method: 'get', params: query }) } src/api/productionManagement/workOrder.js
@@ -37,7 +37,7 @@ // 工单-当前工序物料台账 export function listWorkOrderMaterialLedger(query) { return request({ url: "/productWorkOrder/material/list", url: "/productOrderMaterial/reportMaterials", method: "get", params: query, }); @@ -69,3 +69,12 @@ params: query, }); } // 工单-领用(提交实际领用数量) export function pickWorkOrderMaterial(data) { return request({ url: "/productWorkOrder/material/pick", method: "post", data, }); } src/views/basicData/product/ProductSelectDialog.vue
@@ -1,12 +1,12 @@ <template> <el-dialog v-model="visible" title="选择产品" width="900px" destroy-on-close :close-on-click-modal="false"> <el-form :inline="true" :model="query" class="mb-2"> <el-form-item label="产品大类"> <el-input v-model="query.productName" placeholder="输入产品大类" clearable @keyup.enter="onSearch" /> <el-form-item label="产品名称"> <el-input v-model="query.productName" placeholder="输入产品名称" clearable @keyup.enter="onSearch" /> </el-form-item> <el-form-item label="型号名称"> <el-input v-model="query.model" placeholder="输入型号名称" clearable @keyup.enter="onSearch" /> <el-form-item label="产品型号"> <el-input v-model="query.model" placeholder="输入产品型号" clearable @keyup.enter="onSearch" /> </el-form-item> <el-form-item> @@ -20,8 +20,8 @@ @selection-change="handleSelectionChange" @select="handleSelect"> <el-table-column type="selection" width="55" /> <el-table-column type="index" label="序号" width="60" /> <el-table-column prop="productName" label="产品大类" min-width="160" /> <el-table-column prop="model" label="型号名称" min-width="200" /> <el-table-column prop="productName" label="产品名称" min-width="160" /> <el-table-column prop="model" label="产品型号" min-width="200" /> <el-table-column prop="unit" label="单位" min-width="160" /> </el-table> @@ -43,7 +43,7 @@ <script setup lang="ts"> import { computed, onMounted, reactive, ref, watch, nextTick } from "vue"; import { ElMessage } from "element-plus"; import { productModelList } from '@/api/basicData/productModel' import { productModelList, productModelListByUrl } from '@/api/basicData/productModel' export type ProductRow = { id: number; @@ -56,6 +56,7 @@ modelValue: boolean; single?: boolean; // 是否只能选择一个,默认false(可选择多个) topProductParentId?: number; // 一级产品id requestUrl?: string; // 自定义查询接口 }>(); const emit = defineEmits(['update:modelValue', 'confirm']); @@ -155,15 +156,19 @@ loading.value = true; try { multipleSelection.value = []; // 翻页/搜索后清空选择更符合预期 const res: any = await productModelList({ const params = { productName: query.productName.trim(), model: query.model.trim(), current: page.pageNum, size: page.pageSize, topProductParentId: props.topProductParentId, }); tableData.value = res.records; total.value = res.total; }; const res: any = props.requestUrl ? await productModelListByUrl(props.requestUrl, params) : await productModelList(params); const records = res?.records || res?.data?.records || res?.data || []; tableData.value = Array.isArray(records) ? records : []; total.value = Number(res?.total ?? res?.data?.total ?? tableData.value.length); } finally { loading.value = false; } src/views/productionManagement/processRoute/index.vue
@@ -171,6 +171,7 @@ path: '/productionManagement/processRouteItem', query: { id: row.id, bomId: row.bomId, processRouteCode: row.processRouteCode || '', productName: row.productName || '', model: row.model || '', src/views/productionManagement/processRoute/processRouteItem/index.vue
@@ -47,7 +47,13 @@ </div> </div> </el-card> <div class="section-title" style="margin-bottom: 10px;">产品结构</div> <ProductStructureDetail class="product-structure-panel" style="margin-bottom: 20px;" embedded :bom-id="route.query.bomId" /> <!-- 表格视图 --> <div v-if="viewMode === 'table'" class="section-header"> <div class="section-title">工艺路线项目列表</div> @@ -231,7 +237,7 @@ </template> <script setup> import { ref, computed, getCurrentInstance, onMounted, onUnmounted, nextTick } from "vue"; import { ref, computed, getCurrentInstance, onMounted, onUnmounted, nextTick, defineAsyncComponent } from "vue"; import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; import { findProcessRouteItemList, addOrUpdateProcessRouteItem, sortProcessRouteItem, batchDeleteProcessRouteItem } from "@/api/productionManagement/processRouteItem.js"; import { findProductProcessRouteItemList, deleteRouteItem, addRouteItem, addOrUpdateProductProcessRouteItem, sortRouteItem } from "@/api/productionManagement/productProcessRoute.js"; @@ -242,6 +248,7 @@ const route = useRoute() const { proxy } = getCurrentInstance() || {}; const ProductStructureDetail = defineAsyncComponent(() => import("@/views/productionManagement/productStructure/Detail/index.vue")); const routeId = computed(() => route.query.id); const orderId = computed(() => route.query.orderId); @@ -841,6 +848,10 @@ align-items: center; } .product-structure-panel { margin: 12px 0 20px; } /* 工艺路线信息卡片样式 */ .route-info-card { margin-bottom: 20px; src/views/productionManagement/productStructure/Detail/index.vue
@@ -1,6 +1,6 @@ <template> <div class="app-container"> <PageHeader content="产品结构详情"> <div :class="embedded ? 'embedded-container' : 'app-container'"> <PageHeader v-if="!embedded" content="产品结构详情"> <template #right-button> <el-button v-if="!dataValue.isEdit && !isOrderPage" type="primary" @@ -119,7 +119,7 @@ </el-form-item> </template> </el-table-column> <el-table-column label="操作" <el-table-column v-if="!embedded" label="操作" fixed="right" width="200"> <template #default="{ row, $index }"> @@ -174,6 +174,18 @@ const ProductSelectDialog = defineAsyncComponent( () => import("@/views/basicData/product/ProductSelectDialog.vue") ); const props = defineProps({ embedded: { type: Boolean, default: false, }, // 显式指定BOM主键(用于嵌入到“工艺路线项目”等页面时,路由 query.id 不是 bomId 的情况) bomId: { type: [String, Number], default: undefined, }, }); const embedded = computed(() => props.embedded); const emit = defineEmits(["update:router"]); const form = ref(); @@ -181,7 +193,8 @@ const router = useRouter(); const routeId = computed({ get() { return route.query.id; // 优先使用外部传入的 bomId,其次使用路由的 bomId,最后回退到路由的 id(兼容原页面) return props.bomId ?? route.query.bomId ?? route.query.id; }, set(val) { @@ -227,29 +240,27 @@ }; const fetchData = async () => { if (isOrderPage.value) { // 订单情况:使用订单的产品结构接口 const { data } = await listProcessBom({ orderId: routeOrderId.value }); dataValue.dataList = (data as any) || []; } else { // 非订单情况:使用原来的接口 const { data } = await queryList(routeId.value); dataValue.dataList = (data as any) || []; // 为所有项及其子项设置name属性 const setNameRecursively = (items: any[]) => { items.forEach((item: any) => { item.tempId = item.id; item.processName = dataValue.processOptions.find(option => option.id === item.processId) ?.name || ""; if (item.children && item.children.length > 0) { setNameRecursively(item.children); } }); }; setNameRecursively(dataValue.dataList); console.log(dataValue.dataList, "dataValue.dataList"); const setNameRecursively = (items: any[]) => { items.forEach((item: any) => { item.tempId = item.tempId || item.id || new Date().getTime() + Math.random(); item.processName = dataValue.processOptions.find(option => option.id === item.processId)?.name || item.processName || ""; if (item.children && item.children.length > 0) { setNameRecursively(item.children); } }); }; // 统一使用 BOM 查询产品结构:/productStructure/listBybomId/{bomId} // 说明:订单页也会从路由/父组件带入 bomId(route.query.bomId 或 props.bomId) const bomId = routeId.value; if (!bomId) { dataValue.dataList = []; return; } const { data } = await queryList(bomId); dataValue.dataList = (data as any) || []; setNameRecursively(dataValue.dataList); }; const fetchProcessOptions = async () => { @@ -518,4 +529,11 @@ await fetchProcessOptions(); await fetchData(); }); </script> </script> <style scoped> .embedded-container { padding: 0; margin: 0; } </style> src/views/productionManagement/productionOrder/components/MaterialDetailDialog.vue
@@ -36,8 +36,9 @@ <el-dialog v-model="supplementRecordDialogVisible" title="补料记录" width="800px"> <el-table v-loading="supplementRecordLoading" :data="supplementRecordTableData" border row-key="id"> <el-table-column label="补料数量" prop="supplementQty" min-width="120" /> <el-table-column label="补料时间" prop="supplementTime" min-width="180" /> <el-table-column label="备注" prop="remark" min-width="200" /> <el-table-column label="补料人" prop="supplementUserName" min-width="120" /> <el-table-column label="补料日期" prop="supplementTime" min-width="160" /> <el-table-column label="补料原因" prop="supplementReason" min-width="200" /> </el-table> <template #footer> <span class="dialog-footer"> @@ -88,8 +89,10 @@ const supplementRecordTableData = ref([]); const returnSummaryDialogVisible = ref(false); const returnSummaryList = ref([]); const calcReturnQty = item => Number(item.pickQty || 0) + Number(item.supplementQty || 0) - Number(item.actualQty || 0); const canOpenReturnSummary = computed(() => materialDetailTableData.value.some(item => Number(item.returnQty || 0) > 0) materialDetailTableData.value.some(item => calcReturnQty(item) > 0) ); const loadDetailList = async () => { @@ -133,6 +136,8 @@ const buildReturnSummary = () => { const map = new Map(); materialDetailTableData.value.forEach(item => { const returnQty = calcReturnQty(item); if (returnQty <= 0) return; const key = `${item.materialModelId || ""}_${item.materialName || ""}_${item.materialModel || ""}_${item.unit || ""}`; const old = map.get(key) || { summaryKey: key, @@ -141,7 +146,7 @@ unit: item.unit || "", returnQtyTotal: 0, }; old.returnQtyTotal += Number(item.returnQty || 0); old.returnQtyTotal += returnQty; map.set(key, old); }); return Array.from(map.values()); @@ -149,7 +154,7 @@ const openReturnSummaryDialog = async () => { if (!canOpenReturnSummary.value) { ElMessage.warning("退料数量大于0时才能退料确认"); ElMessage.warning("退料数量=领用数量+补料数量-实际数量,且需大于0"); return; } returnSummaryList.value = buildReturnSummary(); src/views/productionManagement/productionOrder/components/MaterialLedgerDialog.vue
@@ -7,21 +7,24 @@ <el-table v-loading="materialTableLoading" :data="materialTableData" border row-key="tempId"> <el-table-column label="工序名称" min-width="180"> <template #default="{ row }"> <span v-if="row.bom === true">{{ row.processName || "-" }}</span> <el-select v-model="row.processId" v-else v-model="row.processName" placeholder="请选择工序" clearable filterable style="width: 100%;" @change="val => handleProcessChange(row, val)" @change="val => handleProcessNameChange(row, val)" > <el-option v-for="item in processOptions" :key="item.id" :label="item.name" :value="item.id" /> <el-option v-for="item in processOptions" :key="item.id" :label="item.name" :value="item.name" /> </el-select> </template> </el-table-column> <el-table-column label="原料名称" min-width="160"> <template #default="{ row }"> <el-button type="primary" link @click="openMaterialProductSelect(row)"> <span v-if="row.bom === true">{{ row.materialName || "-" }}</span> <el-button v-else type="primary" link @click="openMaterialProductSelect(row)"> {{ row.materialName || "选择原料" }} </el-button> </template> @@ -33,7 +36,9 @@ </el-table-column> <el-table-column label="需求数量" min-width="120"> <template #default="{ row }"> <span v-if="row.bom === true">{{ row.requiredQty ?? "-" }}</span> <el-input-number v-else v-model="row.requiredQty" :min="0" :precision="3" @@ -62,8 +67,8 @@ </template> </el-table-column> <el-table-column label="操作" width="90" fixed="right"> <template #default="{ $index }"> <el-button type="danger" link @click="handleDeleteMaterialRow($index)">删除</el-button> <template #default="{ $index, row }"> <el-button v-if="row.bom !== true" type="danger" link @click="handleDeleteMaterialRow($index)">删除</el-button> </template> </el-table-column> </el-table> @@ -79,15 +84,21 @@ v-model="materialProductDialogVisible" @confirm="handleMaterialProductConfirm" single request-url="/stockInventory/rawMaterials" /> </div> </template> <script setup> import { computed, ref, watch } from "vue"; import { ElMessage } from "element-plus"; import ProductSelectDialog from "@/views/basicData/product/ProductSelectDialog.vue"; import { processList } from "@/api/productionManagement/productionProcess.js"; import { listMaterialPickingLedger, saveMaterialPickingLedger } from "@/api/productionManagement/productionOrder.js"; import { findProductProcessRouteItemList } from "@/api/productionManagement/productProcessRoute.js"; import { listMaterialPickingDetail, listMaterialPickingLedger, saveMaterialPickingLedger, } from "@/api/productionManagement/productionOrder.js"; const props = defineProps({ modelValue: { type: Boolean, default: false }, @@ -112,7 +123,9 @@ tempId: row.id || `temp_${++materialTempId}`, id: row.id, processId: row.processId, productProcessId: row.productProcessId || row.processId, processName: row.processName || "", bom: row.bom === true, materialModelId: row.materialModelId, materialName: row.materialName || "", materialModel: row.materialModel || "", @@ -122,9 +135,23 @@ }); const getProcessOptions = async () => { if (processOptions.value.length > 0) return; const res = await processList({}); processOptions.value = res.data || []; if (!props.orderRow?.id) return; const res = await findProductProcessRouteItemList({ orderId: props.orderRow.id }); const routeList = Array.isArray(res?.data) ? res.data : res?.data?.records || []; const processMap = new Map(); routeList.forEach(item => { const processId = item.processId; const processName = item.processName; if (!processId || !processName) return; const key = `${processId}_${processName}`; if (!processMap.has(key)) { processMap.set(key, { id: processId, name: processName, }); } }); processOptions.value = Array.from(processMap.values()); }; const loadMaterialData = async () => { @@ -133,8 +160,19 @@ materialTableData.value = []; await getProcessOptions(); try { const res = await listMaterialPickingLedger({ orderId: props.orderRow.id }); materialTableData.value = (res.data || []).map(item => createMaterialRow(item)); const detailRes = await listMaterialPickingDetail({ orderId: props.orderRow.id }); const detailList = Array.isArray(detailRes?.data) ? detailRes.data : detailRes?.data?.records || []; if (detailList.length > 0) { materialTableData.value = detailList.map(item => createMaterialRow(item)); return; } const ledgerRes = await listMaterialPickingLedger({ orderId: props.orderRow.id }); const ledgerList = Array.isArray(ledgerRes?.data) ? ledgerRes.data : ledgerRes?.data?.records || []; materialTableData.value = ledgerList.map(item => createMaterialRow(item)); } finally { materialTableLoading.value = false; } @@ -162,9 +200,9 @@ materialTableData.value.splice(index, 1); }; const handleProcessChange = (row, processId) => { const process = processOptions.value.find(item => item.id === processId); row.processName = process?.name || ""; const handleProcessNameChange = (row, processName) => { const process = processOptions.value.find(item => item.name === processName); row.productProcessId = process?.id; }; const handleRequiredQtyChange = (row, val) => { @@ -186,37 +224,56 @@ if (index < 0 || !materialTableData.value[index]) return; const product = products[0]; const row = materialTableData.value[index]; row.materialModelId = product.id; row.materialName = product.productName || ""; row.materialModel = product.model || ""; row.unit = product.unit || ""; row.materialModelId = product.materialModelId || product.modelId || product.id; row.materialName = product.materialName || product.productName || product.name || ""; row.materialModel = product.materialModel || product.model || ""; row.unit = product.unit || product.measureUnit || ""; currentMaterialSelectRowIndex.value = -1; materialProductDialogVisible.value = false; }; const validateMaterialRows = () => { if (materialTableData.value.length === 0) return false; return !materialTableData.value.find( if (materialTableData.value.length === 0) { return { valid: false, message: "请先新增领料数据" }; } const invalidNewRow = materialTableData.value.find( item => item.bom !== true && (!item.processName || !item.materialName) ); if (invalidNewRow) { return { valid: false, message: "新增行的工序名称和原料名称为必填项" }; } const invalidRow = materialTableData.value.find( item => !item.processId || !item.materialModelId || !item.processName || !item.materialName || item.requiredQty === null || item.requiredQty === undefined || item.pickQty === null || item.pickQty === undefined ); if (invalidRow) { return { valid: false, message: "请完善工序、原料和数量后再保存" }; } return { valid: true, message: "" }; }; const handleMaterialSave = async () => { if (!props.orderRow?.id || !validateMaterialRows()) return; if (!props.orderRow?.id) return; const validateResult = validateMaterialRows(); if (!validateResult.valid) { ElMessage.warning(validateResult.message); return; } materialSaving.value = true; try { await saveMaterialPickingLedger({ orderId: props.orderRow.id, items: materialTableData.value.map(item => ({ id: item.id, processId: item.processId, processId: item.processName, productProcessId: item.productProcessId, processName: item.processName, bom: item.bom === true, materialModelId: item.materialModelId, materialName: item.materialName, materialModel: item.materialModel, src/views/productionManagement/productionOrder/index.vue
@@ -48,7 +48,7 @@ @click="handleQuery">搜索</el-button> </el-form-item> </el-form> <div> <div class="action-buttons"> <el-button type="primary" @click="isShowNewModal = true">新增</el-button> <el-button type="danger" @click="handleDelete">删除</el-button> <el-button @click="handleOut">导出</el-button> @@ -224,13 +224,13 @@ openBindRouteDialog(row); }, }, { name: "产品结构", type: "text", clickFun: row => { showProductStructure(row); }, }, // { // name: "产品结构", // type: "text", // clickFun: row => { // showProductStructure(row); // }, // }, { name: "领料", type: "text", @@ -421,6 +421,7 @@ path: "/productionManagement/processRouteItem", query: { id: data.id, bomId: data.bomId, processRouteCode: data.processRouteCode || "", productName: data.productName || "", model: data.model || "", @@ -504,6 +505,12 @@ align-items: start; } .action-buttons { display: flex; flex-wrap: nowrap; gap: 8px; } :deep(.yellow) { background-color: #FAF0DE; } src/views/productionManagement/workOrderManagement/components/MaterialDialog.vue
@@ -11,18 +11,33 @@ <el-table-column label="原料名称" prop="materialName" min-width="140" /> <el-table-column label="原料型号" prop="materialModel" min-width="140" /> <el-table-column label="计量单位" prop="unit" min-width="100" /> <el-table-column label="领用数量" prop="pickQty" min-width="100" /> <el-table-column label="线边仓数量" prop="pickQty" min-width="100" /> <el-table-column label="补料数量" prop="supplementQty" min-width="100" /> <el-table-column label="退料数量" prop="returnQty" min-width="100" /> <el-table-column label="实际数量" prop="actualQty" min-width="100" /> <el-table-column label="操作" align="center" fixed="right" width="220"> <el-table-column label="实际数量" min-width="140"> <template #default="{ row }"> <el-input-number v-model="row.actualQty" :min="0" :precision="3" :step="1" controls-position="right" style="width: 100%;" /> </template> </el-table-column> <el-table-column label="操作" align="center" fixed="right" width="180"> <template #default="{ row }"> <el-button type="primary" link @click="openSupplementDialog(row)">补料</el-button> <el-button type="warning" link @click="openReturnDialog(row)">退料</el-button> <el-button type="info" link @click="openSupplementRecordDialog(row)">补料记录</el-button> </template> </el-table-column> </el-table> <template #footer> <span class="dialog-footer"> <el-button type="primary" :loading="pickSubmitting" @click="handleSubmitPick">领用</el-button> <el-button @click="dialogVisible = false">取消</el-button> </span> </template> </el-dialog> <FormDialog @@ -60,31 +75,6 @@ </template> </FormDialog> <FormDialog v-model="returnDialogVisible" title="退料" width="500px" @confirm="handleSubmitReturn" > <el-form ref="returnFormRef" :model="returnForm" :rules="returnRules" label-width="120px"> <el-form-item label="退料数量" prop="returnQty"> <el-input-number v-model="returnForm.returnQty" :min="0.001" :precision="3" :step="1" style="width: 100%;" /> </el-form-item> </el-form> <template #footer> <span class="dialog-footer"> <el-button type="primary" :loading="returnSubmitting" @click="handleSubmitReturn">确定</el-button> <el-button @click="returnDialogVisible = false">取消</el-button> </span> </template> </FormDialog> <el-dialog v-model="supplementRecordDialogVisible" title="补料记录" width="900px"> <el-table v-loading="supplementRecordLoading" :data="supplementRecordTableData" border row-key="id"> <el-table-column label="补料数量" prop="supplementQty" min-width="100" /> @@ -108,8 +98,8 @@ import { listWorkOrderMaterialLedger, addWorkOrderMaterialSupplement, addWorkOrderMaterialReturn, listWorkOrderMaterialSupplementRecord, pickWorkOrderMaterial, } from "@/api/productionManagement/workOrder.js"; const props = defineProps({ @@ -134,6 +124,7 @@ const materialTableData = ref([]); const currentMaterialRow = ref(null); const currentMaterialOrderRow = ref(null); const pickSubmitting = ref(false); const supplementDialogVisible = ref(false); const supplementSubmitting = ref(false); @@ -141,13 +132,6 @@ const supplementForm = reactive({ supplementQty: null, supplementReason: "", }); const returnDialogVisible = ref(false); const returnSubmitting = ref(false); const returnFormRef = ref(null); const returnForm = reactive({ returnQty: null, }); const supplementRecordDialogVisible = ref(false); @@ -158,10 +142,6 @@ supplementQty: [{ required: true, message: "请输入补料数量", trigger: "blur" }], supplementReason: [{ required: true, message: "请输入补料原因", trigger: "blur" }], }; const returnRules = { returnQty: [{ required: true, message: "请输入退料数量", trigger: "blur" }], }; const loadMaterialTable = async row => { if (!row?.id) return; currentMaterialOrderRow.value = row; @@ -234,49 +214,6 @@ }); }; const openReturnDialog = row => { currentMaterialRow.value = row; returnForm.returnQty = null; returnDialogVisible.value = true; nextTick(() => { returnFormRef.value?.clearValidate(); }); }; const handleSubmitReturn = () => { returnFormRef.value?.validate(async valid => { if (!valid || !currentMaterialRow.value?.id) { ElMessage.warning("缺少物料明细ID"); return; } const returnQty = Number(returnForm.returnQty); const minQty = Number(currentMaterialRow.value.pickQty || 0) + Number(currentMaterialRow.value.supplementQty || 0); if (returnQty < minQty) { ElMessage.warning(`退料数量不能低于领用数量+补料数量(${minQty})`); return; } returnSubmitting.value = true; try { await addWorkOrderMaterialReturn({ materialLedgerId: currentMaterialRow.value.id, returnQty, workOrderId: currentMaterialOrderRow.value?.id, }); returnDialogVisible.value = false; await loadMaterialTable(currentMaterialOrderRow.value); ElMessage.success("退料成功"); emit("refresh"); } catch (e) { console.error("退料失败", e); ElMessage.error("退料失败"); } finally { returnSubmitting.value = false; } }); }; const openSupplementRecordDialog = async row => { supplementRecordDialogVisible.value = true; supplementRecordLoading.value = true; @@ -293,4 +230,49 @@ supplementRecordLoading.value = false; } }; const validatePickRows = () => { if (materialTableData.value.length === 0) { return { valid: false, message: "暂无可领用物料" }; } const invalidRow = materialTableData.value.find(item => item.actualQty === null || item.actualQty === undefined || item.actualQty === ""); if (invalidRow) { return { valid: false, message: "请填写实际数量后再领用" }; } const exceedRow = materialTableData.value.find(item => { const maxQty = Number(item.pickQty || 0) + Number(item.supplementQty || 0); return Number(item.actualQty || 0) > maxQty; }); if (exceedRow) { return { valid: false, message: "实际数量不能大于领用数量+补料数量" }; } return { valid: true, message: "" }; }; const handleSubmitPick = async () => { if (!currentMaterialOrderRow.value?.id) return; const validateResult = validatePickRows(); if (!validateResult.valid) { ElMessage.warning(validateResult.message); return; } pickSubmitting.value = true; try { await pickWorkOrderMaterial({ workOrderId: currentMaterialOrderRow.value.id, items: materialTableData.value.map(item => ({ materialLedgerId: item.id, actualQty: Number(item.actualQty || 0), })), }); ElMessage.success("领用成功"); await loadMaterialTable(currentMaterialOrderRow.value); emit("refresh"); } catch (e) { console.error("领用失败", e); ElMessage.error("领用失败"); } finally { pickSubmitting.value = false; } }; </script> src/views/productionManagement/workOrderManagement/index.vue
@@ -289,17 +289,17 @@ }, }, { name: "物料", clickFun: row => { openMaterialDialog(row); }, }, { name: "报工", clickFun: row => { showReportDialog(row); }, disabled: row => row.planQuantity <= 0, }, { name: "物料", clickFun: row => { openMaterialDialog(row); }, }, ], },