| | |
| | | <template> |
| | | <el-dialog v-model="dialogVisible" |
| | | title="补料" |
| | | width="1200px" |
| | | width="1400px" |
| | | @close="handleClose"> |
| | | <el-table v-loading="loading" |
| | | :data="tableData" |
| | |
| | | <el-table-column label="计量单位" |
| | | prop="unit" |
| | | width="100" /> |
| | | <el-table-column label="库存数量" |
| | | min-width="120"> |
| | | <template #default="{ row }"> |
| | | <span :class="{ 'text-danger': isStockInsufficient(row) }"> |
| | | {{ row.stockQuantity ?? '-' }} |
| | | </span> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="需求数量" |
| | | prop="demandedQuantity" |
| | | width="100" /> |
| | |
| | | :step="1" |
| | | controls-position="right" |
| | | placeholder="输入补料数量" |
| | | style="width: 100%;" /> |
| | | style="width: 100%;" |
| | | :class="{ 'is-stock-insufficient': isStockInsufficient(row) }" /> |
| | | </template> |
| | | </el-table-column> |
| | | <el-table-column label="补料原因" |
| | |
| | | </el-table> |
| | | <template #footer> |
| | | <span class="dialog-footer"> |
| | | <el-button v-if="hasInsufficientStock" |
| | | type="warning" |
| | | @click="openPurchaseRequestDialog">采购申请</el-button> |
| | | <el-button type="primary" |
| | | :loading="submitting" |
| | | @click="handleSubmit">确 定</el-button> |
| | |
| | | </span> |
| | | </template> |
| | | </el-dialog> |
| | | <PurchaseRequestDialog v-model="purchaseRequestDialogVisible" |
| | | :insufficient-items="insufficientStockItems" |
| | | :order-row="props.orderRow" |
| | | @saved="handlePurchaseRequestSaved" /> |
| | | </template> |
| | | |
| | | <script setup> |
| | | import { computed, ref, watch } from "vue"; |
| | | import { ElMessage } from "element-plus"; |
| | | import PurchaseRequestDialog from "./PurchaseRequestDialog.vue"; |
| | | import { |
| | | listMaterialPickingDetail, |
| | | updateMaterialPickingLedger, |
| | | listMaterialPickingBom, |
| | | } from "@/api/productionManagement/productionOrder.js"; |
| | | |
| | | const props = defineProps({ |
| | |
| | | const loading = ref(false); |
| | | const submitting = ref(false); |
| | | const tableData = ref([]); |
| | | const purchaseRequestDialogVisible = ref(false); |
| | | |
| | | // 判断库存是否不足 |
| | | const isStockInsufficient = (row) => { |
| | | const stockQuantity = Number(row.stockQuantity ?? 0); |
| | | const supplementQty = Number(row.newSupplementQty ?? 0); |
| | | return supplementQty > 0 && stockQuantity > 0 && supplementQty > stockQuantity; |
| | | }; |
| | | |
| | | // 库存不足的行 |
| | | const insufficientStockItems = computed(() => { |
| | | return tableData.value.filter(row => isStockInsufficient(row)); |
| | | }); |
| | | |
| | | // 是否有库存不足 |
| | | const hasInsufficientStock = computed(() => { |
| | | return insufficientStockItems.value.length > 0; |
| | | }); |
| | | |
| | | const loadData = async () => { |
| | | if (!props.orderRow?.id) return; |
| | | loading.value = true; |
| | | try { |
| | | // 获取物料明细 |
| | | const res = await listMaterialPickingDetail(props.orderRow.id); |
| | | // 获取库存数量 |
| | | const bomRes = await listMaterialPickingBom(props.orderRow.id); |
| | | const bomList = Array.isArray(bomRes?.data) |
| | | ? bomRes.data |
| | | : bomRes?.data?.records || []; |
| | | // 创建库存数量映射 |
| | | const stockMap = new Map(); |
| | | bomList.forEach(item => { |
| | | const key = item.materialModelId || item.productModelId; |
| | | if (key) { |
| | | stockMap.set(key, item.stockQuantity ?? item.stockQty ?? 0); |
| | | } |
| | | }); |
| | | // 合并库存数据 |
| | | tableData.value = (res.data || []).map(item => ({ |
| | | ...item, |
| | | newSupplementQty: 0, |
| | | newSupplementReason: "", |
| | | stockQuantity: stockMap.get(item.productModelId) ?? null, |
| | | })); |
| | | } catch (e) { |
| | | console.error("获取物料明细失败:", e); |
| | |
| | | submitting.value = false; |
| | | } |
| | | }; |
| | | |
| | | // 打开采购申请对话框 |
| | | const openPurchaseRequestDialog = () => { |
| | | purchaseRequestDialogVisible.value = true; |
| | | }; |
| | | |
| | | // 采购申请保存回调 |
| | | const handlePurchaseRequestSaved = () => { |
| | | // 采购申请保存成功后刷新数据 |
| | | loadData(); |
| | | }; |
| | | </script> |
| | | |
| | | <style scoped lang="scss"> |
| | | .text-danger { |
| | | color: #f56c6c; |
| | | font-weight: bold; |
| | | } |
| | | |
| | | :deep(.is-stock-insufficient) { |
| | | .el-input__wrapper { |
| | | box-shadow: 0 0 0 1px #f56c6c inset; |
| | | } |
| | | } |
| | | </style> |