From 7b60f24e07f54634503e5b37e6ca5f85d4ad743f Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 07 八月 2026 15:41:39 +0800
Subject: [PATCH] 天津_建诚恒商贸 1.备件管理-新增独立备件出库功能入口,支持直接完成备件领用出库操作。 2.设备保养-支持按日期分组折叠展示,分组条目可展开查看明细;单条明细行末尾增加【保养完成】操作按钮,可单独办结单条保养任务;折叠汇总状态下,新增【一键保养完成】批量操作按钮,快速办结当前分组全部保养项。 3.设备巡检-按日期分组折叠展示,分组支持展开查看明细;每条巡检明细后增设【巡检完成】按钮,支持单独办结单条巡检记录;分组折叠未展开状态下,提供【一键巡检完成】批量操作,统一办结该分组下所有巡检任务。 4.增值税对比-优化数据展示逻辑,列表展示各订单增值税明细;页面右侧新增柱状可视化图表,直观对比进销项增值税数据。 5.管理驾驶舱-指标修改:将顶部「销售产品数」调整为「销售订单数」;时间筛选:页面左上角新增日期范围下拉筛选控件,所有统计指标标注当前筛选时段;

---
 src/views/equipmentManagement/spareParts/index.vue |  147 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 146 insertions(+), 1 deletions(-)

diff --git a/src/views/equipmentManagement/spareParts/index.vue b/src/views/equipmentManagement/spareParts/index.vue
index b8cb086..131e1d5 100644
--- a/src/views/equipmentManagement/spareParts/index.vue
+++ b/src/views/equipmentManagement/spareParts/index.vue
@@ -105,6 +105,7 @@
               <el-select v-model="usageQuery.sourceType" placeholder="璇烽�夋嫨" clearable style="width: 200px">
                 <el-option label="缁翠慨" :value="0" />
                 <el-option label="淇濆吇" :value="1" />
+                <el-option label="鐩存帴鍑哄簱" :value="2" />
               </el-select>
             </el-form-item>
             <el-form-item>
@@ -112,6 +113,9 @@
               <el-button @click="resetUsageQuery">閲嶇疆</el-button>
             </el-form-item>
           </el-form>
+          <div>
+            <el-button type="primary" @click="openRequisitionDialog">鐩存帴鍑哄簱</el-button>
+          </div>
         </div>
 				<div class="table_list">
 					<PIMTable
@@ -126,6 +130,60 @@
 				</div>
       </el-tab-pane>
     </el-tabs>
+
+    <!-- 鐩存帴鍑哄簱寮圭獥 -->
+    <el-dialog title="鐩存帴鍑哄簱" v-model="requisitionDialogVisible" width="500px">
+      <el-form :model="requisitionForm" :rules="requisitionRules" ref="requisitionFormRef" label-width="100px">
+        <el-form-item label="璁惧閫夋嫨" prop="deviceLedgerId">
+          <el-select
+            v-model="requisitionForm.deviceLedgerId"
+            placeholder="璇烽�夋嫨璁惧"
+            filterable
+            clearable
+            style="width: 100%"
+          >
+            <el-option
+              v-for="item in requisitionDeviceOptions"
+              :key="item.id"
+              :label="item.deviceName"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="澶囦欢閫夋嫨" prop="sparePartsId">
+          <el-select
+            v-model="requisitionForm.sparePartsId"
+            placeholder="璇烽�夋嫨澶囦欢"
+            filterable
+            clearable
+            style="width: 100%"
+            @change="onRequisitionSparePartChange"
+          >
+            <el-option
+              v-for="item in requisitionSparePartsOptions"
+              :key="item.id"
+              :label="`${item.name}锛堝簱瀛�: ${item.quantity}锛塦"
+              :value="item.id"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="棰嗙敤鏁伴噺" prop="quantity">
+          <el-input-number
+            v-model="requisitionForm.quantity"
+            :min="1"
+            :max="selectedSparePartMaxQty"
+            style="width: 100%"
+          />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input v-model="requisitionForm.remark" placeholder="璇疯緭鍏ュ娉�" />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button type="primary" @click="submitRequisition" :loading="requisitionLoading">纭畾</el-button>
+        <el-button @click="requisitionDialogVisible = false">鍙栨秷</el-button>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
@@ -135,7 +193,7 @@
 import { getSparePartsList, addSparePart, editSparePart, delSparePart } from "@/api/equipmentManagement/spareParts";
 import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
 import PIMTable from "@/components/PIMTable/PIMTable.vue";
-import { getSparePartsUsagePage } from "@/api/equipmentManagement/sparePartsUsage";
+import { getSparePartsUsagePage, outboundSpareParts } from "@/api/equipmentManagement/sparePartsUsage";
 
 // 鍔犺浇鐘舵��
 const loading = ref(false);
@@ -511,6 +569,93 @@
   }
 };
 
+// 鐩存帴鍑哄簱
+const requisitionDialogVisible = ref(false);
+const requisitionLoading = ref(false);
+const requisitionFormRef = ref(null);
+const requisitionDeviceOptions = ref([]);
+const requisitionSparePartsOptions = ref([]);
+const selectedSparePartMaxQty = ref(1);
+const requisitionForm = reactive({
+  deviceLedgerId: null,
+  sparePartsId: null,
+  quantity: 1,
+  remark: '',
+});
+const requisitionRules = {
+  sparePartsId: [{ required: true, message: '璇烽�夋嫨澶囦欢', trigger: 'change' }],
+  quantity: [{ required: true, message: '璇疯緭鍏ラ鐢ㄦ暟閲�', trigger: 'blur' }],
+};
+
+const loadRequisitionOptions = async () => {
+  try {
+    const [deviceRes, spareRes] = await Promise.all([
+      getDeviceLedger(),
+      getSparePartsList({ current: 1, size: 9999 }),
+    ]);
+    requisitionDeviceOptions.value = deviceRes.data || [];
+    requisitionSparePartsOptions.value = spareRes.data?.records || [];
+  } catch (e) {
+    ElMessage.error('鍔犺浇閫夐」澶辫触');
+  }
+};
+
+const openRequisitionDialog = async () => {
+  requisitionForm.deviceLedgerId = null;
+  requisitionForm.sparePartsId = null;
+  requisitionForm.quantity = 1;
+  requisitionForm.remark = '';
+  selectedSparePartMaxQty.value = 1;
+  await loadRequisitionOptions();
+  requisitionDialogVisible.value = true;
+};
+
+const onRequisitionSparePartChange = (val) => {
+  const selected = requisitionSparePartsOptions.value.find(item => item.id === val);
+  selectedSparePartMaxQty.value = selected ? selected.quantity : 1;
+  if (requisitionForm.quantity > selectedSparePartMaxQty.value) {
+    requisitionForm.quantity = selectedSparePartMaxQty.value;
+  }
+};
+
+const submitRequisition = async () => {
+  if (!requisitionFormRef.value) return;
+  try {
+    await requisitionFormRef.value.validate();
+  } catch {
+    return;
+  }
+  if (requisitionForm.quantity <= 0) {
+    ElMessage.warning('棰嗙敤鏁伴噺蹇呴』澶т簬0');
+    return;
+  }
+  const selected = requisitionSparePartsOptions.value.find(item => item.id === requisitionForm.sparePartsId);
+  if (selected && requisitionForm.quantity > selected.quantity) {
+    ElMessage.warning(`搴撳瓨涓嶈冻锛屽綋鍓嶅簱瀛樹负 ${selected.quantity}`);
+    return;
+  }
+  requisitionLoading.value = true;
+  try {
+    const res = await outboundSpareParts({
+      deviceLedgerId: requisitionForm.deviceLedgerId || undefined,
+      sparePartsId: requisitionForm.sparePartsId,
+      quantity: requisitionForm.quantity,
+      remark: requisitionForm.remark || undefined,
+    });
+    if (res.code === 200) {
+      ElMessage.success('棰嗙敤鎴愬姛');
+      requisitionDialogVisible.value = false;
+      fetchUsageData();
+    } else {
+      ElMessage.error(res.msg || '棰嗙敤澶辫触');
+    }
+  } catch {
+    ElMessage.error('棰嗙敤澶辫触');
+  } finally {
+    requisitionLoading.value = false;
+  }
+};
+
 // 缁勪欢鎸傝浇鏃惰幏鍙栧垪琛ㄦ暟鎹�
 onMounted(() => {
   fetchListData();

--
Gitblit v1.9.3