| | |
| | | v-model:visible="isShowNewModal" |
| | | type="qualified" |
| | | @completed="handleQuery" /> |
| | | |
| | | <!-- 查看投入弹框 --> |
| | | <el-dialog v-model="inputDialogVisible" |
| | | title="投入" |
| | | width="1000px"> |
| | | <PIMTable |
| | | rowKey="id" |
| | | :column="inputTableColumn" |
| | | :tableData="inputTableData" |
| | | :page="inputPage" |
| | | :tableLoading="inputTableLoading" |
| | | @pagination="handleInputPagination" |
| | | /> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="primary" @click="inputDialogVisible = false">关闭</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | <!-- 领料弹框 --> |
| | | <el-dialog v-model="pickingDialogVisible" |
| | | title="工单领料" |
| | | width="1200px" |
| | | :close-on-click-modal="false"> |
| | | |
| | | <el-table |
| | | :data="pickingTableData" |
| | | border |
| | | size="small" |
| | | @selection-change="handlePickingSelectionChange" |
| | | :header-cell-style="{ background: '#f5f7fa' }" |
| | | show-summary |
| | | :summary-method="summarizePickingTable" |
| | | > |
| | | <el-table-column type="selection" width="50" align="center" /> |
| | | <el-table-column label="产品名称" prop="productName" min-width="120" /> |
| | | <el-table-column label="图纸编号" prop="model" min-width="100" /> |
| | | <el-table-column label="单位用量" prop="unitQuantity" min-width="100" align="center" /> |
| | | <el-table-column label="单位" prop="unit" min-width="100" align="center" /> |
| | | <el-table-column label="需求数量" prop="demandedQuantity" min-width="100" align="center" /> |
| | | <el-table-column label="已领料数量" prop="completedQuantity" min-width="100" align="center" /> |
| | | <el-table-column label="未领料数量" prop="unpickedQuantity" min-width="100" align="center" /> |
| | | <el-table-column label="领料数量" min-width="180" align="center" prop="quantity"> |
| | | <template #default="{ row }"> |
| | | <el-input-number |
| | | v-model="row.quantity" |
| | | :min="0" |
| | | :max="row.unpickedQuantity" |
| | | :precision="0" |
| | | size="small" |
| | | style="width: 160px" |
| | | @change="(val) => handlePickingQuantityChange(val, row)" |
| | | /> |
| | | </template> |
| | | </el-table-column> |
| | | </el-table> |
| | | <div class="picking-footer-info"> |
| | | <span>已选 {{ pickingSelectedRows.length }} 条</span> |
| | | <span>{{ pickingTableData.length }} 条记录</span> |
| | | </div> |
| | | <template #footer> |
| | | <div class="dialog-footer"> |
| | | <el-button type="success" @click="handlePickingNext">确认</el-button> |
| | | <el-button @click="pickingDialogVisible = false">取消</el-button> |
| | | </div> |
| | | </template> |
| | | </el-dialog> |
| | | |
| | | </div> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { onMounted, ref } from "vue"; |
| | | import { onMounted, ref, computed } from "vue"; |
| | | import { ElMessageBox } from "element-plus"; |
| | | import { Setting } from '@element-plus/icons-vue'; |
| | | import dayjs from "dayjs"; |
| | | import { useRouter } from "vue-router"; |
| | | import { |
| | |
| | | listProcessBom, delProductOrder, startOrPause, |
| | | } from "@/api/productionManagement/productionOrder.js"; |
| | | import { listMain as getOrderProcessRouteMain } from "@/api/productionManagement/productProcessRoute.js"; |
| | | import { productionProductInputListPage } from "@/api/productionManagement/productionProductInput.js"; |
| | | import { listPage as listProductStructureRecord, pick as pickMaterial } from "@/api/productionManagement/productStructureRecord.js"; |
| | | |
| | | import {fileDel} from "@/api/financialManagement/revenueManagement.js"; |
| | | import PIMTable from "@/components/PIMTable/PIMTable.vue"; |
| | | const NewProductOrder = defineAsyncComponent(() => import("@/views/productionManagement/productionOrder/New.vue")); |
| | |
| | | label: "操作", |
| | | align: "center", |
| | | fixed: "right", |
| | | width: 240, |
| | | width: 360, |
| | | operation: [ |
| | | { |
| | | name: "开始", |
| | | type: "text", |
| | | type: "success", |
| | | showHide: row => row.status === '待生产', |
| | | clickFun: row => { |
| | | handleStartOrPause(row); |
| | |
| | | }, |
| | | { |
| | | name: "暂停", |
| | | type: "text", |
| | | type: "danger", |
| | | showHide: row => row.status === '生产中', |
| | | clickFun: row => { |
| | | handleStartOrPause(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "领料", |
| | | type: "success", |
| | | clickFun: row => { |
| | | showPickingDialog(row); |
| | | }, |
| | | }, |
| | | { |
| | |
| | | showProductStructure(row); |
| | | }, |
| | | }, |
| | | { |
| | | name: "查看投入", |
| | | type: "text", |
| | | clickFun: row => { |
| | | showInputDialog(row); |
| | | }, |
| | | }, |
| | | ], |
| | | }, |
| | | ]); |
| | |
| | | total: 0, |
| | | }); |
| | | const selectedRows = ref([]); |
| | | |
| | | // 查看投入相关 |
| | | const inputDialogVisible = ref(false); |
| | | const inputTableData = ref([]); |
| | | const inputTableLoading = ref(false); |
| | | const inputCurrentRow = ref(null); |
| | | const inputPage = reactive({ |
| | | current: 1, |
| | | size: 100, |
| | | total: 0, |
| | | }); |
| | | const inputTableColumn = ref([ |
| | | { |
| | | label: '投入产品名称', |
| | | prop: 'productName', |
| | | }, |
| | | { |
| | | label: '图纸编号', |
| | | prop: 'model' |
| | | }, |
| | | { |
| | | label: '投入数量', |
| | | prop: 'quantity', |
| | | }, |
| | | { |
| | | label: '单位', |
| | | prop: 'unit', |
| | | }, |
| | | ]); |
| | | |
| | | // 领料相关 |
| | | const pickingDialogVisible = ref(false); |
| | | const pickingTableData = ref([]); |
| | | const pickingSelectedRows = ref([]); |
| | | const pickingForm = reactive({ |
| | | orderId: null, |
| | | }); |
| | | |
| | | const data = reactive({ |
| | | searchForm: { |
| | |
| | | |
| | | const handleConfirmRoute = () => {}; |
| | | |
| | | // 显示查看投入弹框 |
| | | const showInputDialog = (row) => { |
| | | inputCurrentRow.value = row; |
| | | inputDialogVisible.value = true; |
| | | inputPage.current = 1; |
| | | inputPage.total = 0; |
| | | fetchInputData(); |
| | | }; |
| | | |
| | | // 查看投入分页 |
| | | const handleInputPagination = (obj) => { |
| | | inputPage.current = obj.page; |
| | | inputPage.size = obj.limit; |
| | | fetchInputData(); |
| | | }; |
| | | |
| | | // 获取投入数据 |
| | | const fetchInputData = () => { |
| | | inputTableLoading.value = true; |
| | | const params = { productOrderId: inputCurrentRow.value.id, ...inputPage }; |
| | | productionProductInputListPage(params) |
| | | .then(res => { |
| | | inputTableLoading.value = false; |
| | | inputTableData.value = res.data.records; |
| | | inputPage.total = res.data.total; |
| | | }) |
| | | .catch(err => { |
| | | inputTableLoading.value = false; |
| | | console.error("获取投入数据失败:", err); |
| | | }); |
| | | }; |
| | | |
| | | // 显示领料弹框 |
| | | const showPickingDialog = async (row) => { |
| | | pickingForm.orderId = row.id; |
| | | pickingDialogVisible.value = true; |
| | | pickingTableData.value = []; |
| | | |
| | | // 获取物料清单数据 |
| | | try { |
| | | const res = await listProductStructureRecord({ productOrderId: row.id }); |
| | | const materials = res.data?.records || []; |
| | | pickingTableData.value = materials.map(item => ({ |
| | | ...item, |
| | | quantity: 0, |
| | | unpickedQuantity: (item.demandedQuantity || 0) - (item.pickedQuantity || 0), |
| | | })); |
| | | } catch (e) { |
| | | console.error("获取物料清单失败:", e); |
| | | proxy.$modal.msgError("获取物料清单失败"); |
| | | } |
| | | }; |
| | | |
| | | // 领料表格选择变化 |
| | | const handlePickingSelectionChange = (selection) => { |
| | | pickingSelectedRows.value = selection; |
| | | }; |
| | | |
| | | // 领料数量变化处理 |
| | | const handlePickingQuantityChange = (val, row) => { |
| | | if (val > row.unpickedQuantity) { |
| | | proxy.$modal.msgWarning("领料数量不能超过未领料数量"); |
| | | row.quantity = row.unpickedQuantity; |
| | | } |
| | | }; |
| | | |
| | | // 确认领料 |
| | | const handlePickingNext = async () => { |
| | | if (pickingSelectedRows.value.length === 0) { |
| | | proxy.$modal.msgWarning("请选择要领料的物料"); |
| | | return; |
| | | } |
| | | // 校验领料数量 |
| | | for (const row of pickingSelectedRows.value) { |
| | | if (row.quantity > row.unpickedQuantity) { |
| | | proxy.$modal.msgWarning(`${row.productName} 的领料数量不能超过未领料数量`); |
| | | return; |
| | | } |
| | | if (row.quantity <= 0) { |
| | | proxy.$modal.msgWarning(`${row.productName} 的领料数量必须大于0`); |
| | | return; |
| | | } |
| | | } |
| | | |
| | | // 提交领料数据 |
| | | try { |
| | | const pickData = pickingSelectedRows.value.map(row => ({ |
| | | productOrderId: row.productOrderId, |
| | | productStructureRecordId: row.id, |
| | | productModelId: row.productModelId, |
| | | quantity: row.quantity, |
| | | })); |
| | | await pickMaterial(pickData); |
| | | proxy.$modal.msgSuccess("领料成功"); |
| | | pickingDialogVisible.value = false; |
| | | } catch (e) { |
| | | console.error("领料失败:", e); |
| | | proxy.$modal.msgError("领料失败"); |
| | | } |
| | | }; |
| | | |
| | | // 领料表格合计方法 |
| | | const summarizePickingTable = (param) => { |
| | | return proxy.summarizeTable(param, [ |
| | | "quantity", |
| | | "unpickedQuantity", |
| | | "inventoryQuantity", |
| | | "demandedQuantity", |
| | | ]); |
| | | }; |
| | | |
| | | onMounted(() => { |
| | | getList(); |
| | | }); |
| | |
| | | :deep(.purple){ |
| | | background-color: #F4DEFA; |
| | | } |
| | | |
| | | .picking-footer-info { |
| | | display: flex; |
| | | justify-content: space-between; |
| | | padding: 10px; |
| | | font-size: 14px; |
| | | color: #606266; |
| | | } |
| | | |
| | | </style> |