From b6bf928d53681a459c47a05a482f1f9a1c90ca63 Mon Sep 17 00:00:00 2001
From: spring <2396852758@qq.com>
Date: 星期三, 01 四月 2026 17:36:46 +0800
Subject: [PATCH] fix: 添加备件领用记录
---
src/views/equipmentManagement/spareParts/index.vue | 273 ++++++++++++++++++++++++++++++++-------------
src/api/equipmentManagement/sparePartsUsage.js | 36 ++++++
2 files changed, 231 insertions(+), 78 deletions(-)
diff --git a/src/api/equipmentManagement/sparePartsUsage.js b/src/api/equipmentManagement/sparePartsUsage.js
new file mode 100644
index 0000000..9fca9d3
--- /dev/null
+++ b/src/api/equipmentManagement/sparePartsUsage.js
@@ -0,0 +1,36 @@
+import request from "@/utils/request";
+
+/**
+ * 澶囦欢棰嗙敤璁板綍 - 鍒嗛〉鏌ヨ
+ * params: { current, size, sparePartId?, sparePartName?, source?, deviceId?, startTime?, endTime? }
+ */
+export const getSparePartsUsagePage = (params) => {
+ return request({
+ url: "/sparePartsUsage/listPage",
+ method: "get",
+ params,
+ });
+};
+
+/**
+ * 澶囦欢棰嗙敤璁板綍 - 鏂板
+ * data 绀轰緥锛�
+ * {
+ * source: "repair" | "upkeep" | "manual",
+ * sourceId?: number | string,
+ * deviceId?: number | string,
+ * deviceName?: string,
+ * operatorId?: number | string,
+ * operator?: string,
+ * useTime?: string, // YYYY-MM-DD HH:mm:ss
+ * items: [{ sparePartId: number|string, qty: number }]
+ * }
+ */
+export const addSparePartsUsage = (data) => {
+ return request({
+ url: "/sparePartsUsage/add",
+ method: "post",
+ data,
+ });
+};
+
diff --git a/src/views/equipmentManagement/spareParts/index.vue b/src/views/equipmentManagement/spareParts/index.vue
index 68e0f6e..ed75b60 100644
--- a/src/views/equipmentManagement/spareParts/index.vue
+++ b/src/views/equipmentManagement/spareParts/index.vue
@@ -1,83 +1,123 @@
<template>
<div class="spare-part-category">
- <div class="search_form">
- <el-form :inline="true" :model="queryParams" class="search-form">
- <el-form-item label="澶囦欢鍚嶇О">
- <el-input
- v-model="queryParams.name"
- placeholder="璇疯緭鍏ュ浠跺悕绉�"
- clearable
- style="width: 240px"
- />
- </el-form-item>
- <el-form-item>
- <el-button type="primary" @click="handleQuery">鏌ヨ</el-button>
- <el-button @click="resetQuery">閲嶇疆</el-button>
- </el-form-item>
- </el-form>
- <div>
- <el-button type="primary" @click="addCategory" >鏂板</el-button>
- </div>
- </div>
- <PIMTable
- rowKey="id"
- :column="columns"
- :tableData="renderTableData"
- :tableLoading="loading"
- :page="pagination"
- :isShowPagination="true"
- @pagination="handleSizeChange"
- >
- <template #status="{ row }">
- <el-tag type="success" size="small">{{ row.status }}</el-tag>
- </template>
- </PIMTable>
- <el-dialog title="鍒嗙被绠$悊" v-model="dialogVisible" width="60%">
- <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
- <el-form-item label="璁惧" prop="deviceLedgerIds">
- <el-select
- v-model="form.deviceLedgerIds"
- placeholder="璇烽�夋嫨璁惧"
- filterable
- default-first-option
- :reserve-keyword="false"
- multiple
- style="width: 100%"
- >
- <el-option
- v-for="(item, index) in deviceOptions"
- :key="index"
- :label="item.deviceName"
- :value="item.id"
- ></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="澶囦欢鍚嶇О" prop="name">
- <el-input v-model="form.name"></el-input>
- </el-form-item>
- <el-form-item label="澶囦欢缂栧彿" prop="sparePartsNo">
- <el-input v-model="form.sparePartsNo"></el-input>
- </el-form-item>
- <el-form-item label="鏁伴噺" prop="quantity">
- <el-input type="number" v-model="form.quantity"></el-input>
- </el-form-item>
- <el-form-item label="鐘舵��" prop="status">
- <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��">
- <el-option label="姝e父" value="姝e父"></el-option>
- <el-option label="绂佺敤" value="绂佺敤"></el-option>
- </el-select>
- </el-form-item>
- <el-form-item label="鎻忚堪" prop="description">
- <el-input v-model="form.description"></el-input>
- </el-form-item>
- </el-form>
- <template #footer>
- <span class="dialog-footer">
- <el-button @click="dialogVisible = false" :disabled="formLoading">鍙栨秷</el-button>
- <el-button type="primary" @click="submitForm" :loading="formLoading">纭畾</el-button>
- </span>
- </template>
- </el-dialog>
+ <el-tabs v-model="activeTab" @tab-change="handleTabChange">
+ <el-tab-pane label="澶囦欢鍒楄〃" name="list">
+ <div class="search_form">
+ <el-form :inline="true" :model="queryParams" class="search-form">
+ <el-form-item label="澶囦欢鍚嶇О">
+ <el-input
+ v-model="queryParams.name"
+ placeholder="璇疯緭鍏ュ浠跺悕绉�"
+ clearable
+ style="width: 240px"
+ />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleQuery">鏌ヨ</el-button>
+ <el-button @click="resetQuery">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ <div>
+ <el-button type="primary" @click="addCategory">鏂板</el-button>
+ </div>
+ </div>
+ <PIMTable
+ rowKey="id"
+ :column="columns"
+ :tableData="renderTableData"
+ :tableLoading="loading"
+ :page="pagination"
+ :isShowPagination="true"
+ @pagination="handleSizeChange"
+ >
+ <template #status="{ row }">
+ <el-tag type="success" size="small">{{ row.status }}</el-tag>
+ </template>
+ </PIMTable>
+ <el-dialog title="鍒嗙被绠$悊" v-model="dialogVisible" width="60%">
+ <el-form :model="form" :rules="rules" ref="formRef" label-width="100px">
+ <el-form-item label="璁惧" prop="deviceLedgerIds">
+ <el-select
+ v-model="form.deviceLedgerIds"
+ placeholder="璇烽�夋嫨璁惧"
+ filterable
+ default-first-option
+ :reserve-keyword="false"
+ multiple
+ style="width: 100%"
+ >
+ <el-option
+ v-for="(item, index) in deviceOptions"
+ :key="index"
+ :label="item.deviceName"
+ :value="item.id"
+ ></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="澶囦欢鍚嶇О" prop="name">
+ <el-input v-model="form.name"></el-input>
+ </el-form-item>
+ <el-form-item label="澶囦欢缂栧彿" prop="sparePartsNo">
+ <el-input v-model="form.sparePartsNo"></el-input>
+ </el-form-item>
+ <el-form-item label="鏁伴噺" prop="quantity">
+ <el-input type="number" v-model="form.quantity"></el-input>
+ </el-form-item>
+ <el-form-item label="鐘舵��" prop="status">
+ <el-select v-model="form.status" placeholder="璇烽�夋嫨鐘舵��">
+ <el-option label="姝e父" value="姝e父"></el-option>
+ <el-option label="绂佺敤" value="绂佺敤"></el-option>
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鎻忚堪" prop="description">
+ <el-input v-model="form.description"></el-input>
+ </el-form-item>
+ </el-form>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button @click="dialogVisible = false" :disabled="formLoading">鍙栨秷</el-button>
+ <el-button type="primary" @click="submitForm" :loading="formLoading">纭畾</el-button>
+ </span>
+ </template>
+ </el-dialog>
+ </el-tab-pane>
+
+ <el-tab-pane label="澶囦欢棰嗙敤璁板綍" name="usage">
+ <div class="search_form">
+ <el-form :inline="true" :model="usageQuery" class="search-form">
+ <el-form-item label="澶囦欢鍚嶇О">
+ <el-input
+ v-model="usageQuery.sparePartName"
+ placeholder="璇疯緭鍏ュ浠跺悕绉�"
+ clearable
+ style="width: 240px"
+ />
+ </el-form-item>
+ <el-form-item label="鏉ユ簮">
+ <el-select v-model="usageQuery.source" placeholder="璇烽�夋嫨" clearable style="width: 200px">
+ <el-option label="缁翠慨" value="缁翠慨" />
+ <el-option label="淇濆吇" value="淇濆吇" />
+ <el-option label="鎵嬪伐" value="鎵嬪伐" />
+ </el-select>
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary" @click="handleUsageQuery">鏌ヨ</el-button>
+ <el-button @click="resetUsageQuery">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ </div>
+
+ <PIMTable
+ rowKey="rowKey"
+ :column="usageColumns"
+ :tableData="usageTableData"
+ :tableLoading="usageLoading"
+ :page="usagePagination"
+ :isShowPagination="true"
+ @pagination="handleUsagePageChange"
+ />
+ </el-tab-pane>
+ </el-tabs>
</div>
</template>
@@ -87,10 +127,12 @@
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";
// 鍔犺浇鐘舵��
const loading = ref(false);
const formLoading = ref(false);
+const activeTab = ref("list");
// 瀵硅瘽妗嗘樉绀虹姸鎬�
const dialogVisible = ref(false);
// 缂栬緫 ID
@@ -115,6 +157,35 @@
size: 10,
total: 0
});
+
+// 澶囦欢棰嗙敤璁板綍
+const usageLoading = ref(false);
+const usageQuery = reactive({
+ sparePartName: "",
+ source: "",
+});
+const usagePagination = reactive({
+ current: 1,
+ size: 10,
+ total: 0,
+});
+const usageTableData = ref([]);
+const usageColumns = ref([
+ { label: "鏉ユ簮", prop: "sourceText" },
+ { label: "鍗曟嵁/璁板綍ID", prop: "sourceId" },
+ { label: "璁惧鍚嶇О", prop: "deviceName" },
+ { label: "澶囦欢鍚嶇О", prop: "sparePartName" },
+ { label: "棰嗙敤鏁伴噺", prop: "qty" },
+ { label: "鎿嶄綔浜�", prop: "operator" },
+ { label: "鏃堕棿", prop: "useTime" },
+]);
+
+const handleTabChange = async (name) => {
+ if (name === "usage") {
+ usagePagination.current = 1;
+ await fetchUsageData();
+ }
+};
// 琛ㄥ崟鏁版嵁
const form = reactive({
id:'',
@@ -252,6 +323,52 @@
}
}
+const fetchUsageData = async () => {
+ usageLoading.value = true;
+ try {
+ const res = await getSparePartsUsagePage({
+ current: usagePagination.current,
+ size: usagePagination.size,
+ sparePartName: usageQuery.sparePartName || undefined,
+ source: usageQuery.source || undefined,
+ });
+ if (res?.code === 200) {
+ const records = res?.data?.records || [];
+ usagePagination.total = res?.data?.total || 0;
+ usageTableData.value = records.map((r, idx) => ({
+ rowKey: r.id ?? `${usagePagination.current}-${idx}`,
+ ...r,
+ sourceText:
+ r.source === "缁翠慨" ? "缁翠慨" :
+ r.source === "淇濆吇" ? "淇濆吇" :
+ r.source === "鎵嬪伐" ? "鎵嬪伐" :
+ (r.source || "-"),
+ }));
+ } else {
+ usagePagination.total = 0;
+ usageTableData.value = [];
+ }
+ } finally {
+ usageLoading.value = false;
+ }
+};
+
+const handleUsageQuery = () => {
+ usagePagination.current = 1;
+ fetchUsageData();
+};
+const resetUsageQuery = () => {
+ usageQuery.sparePartName = "";
+ usageQuery.source = "";
+ usagePagination.current = 1;
+ fetchUsageData();
+};
+const handleUsagePageChange = (obj) => {
+ usagePagination.current = obj.page;
+ usagePagination.size = obj.limit;
+ fetchUsageData();
+};
+
// 鏌ヨ
const handleQuery = () => {
pagination.current = 1;
--
Gitblit v1.9.3