From 73d112ddc9bdfeb7eaaf3b7308cfb4dbeb470c89 Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 07 八月 2026 17:28:10 +0800
Subject: [PATCH] 天津_意博凯信 1.备件管理-新增独立备件出库功能入口,支持直接完成备件领用出库操作。 2.设备保养-支持按日期分组折叠展示,分组条目可展开查看明细;单条明细行末尾增加【保养完成】操作按钮,可单独办结单条保养任务;折叠汇总状态下,新增【一键保养完成】批量操作按钮,快速办结当前分组全部保养项。 3.设备巡检-按日期分组折叠展示,分组支持展开查看明细;每条巡检明细后增设【巡检完成】按钮,支持单独办结单条巡检记录;分组折叠未展开状态下,提供【一键巡检完成】批量操作,统一办结该分组下所有巡检任务。 4.增值税对比-优化数据展示逻辑,列表展示各订单增值税明细;页面右侧新增柱状可视化图表,直观对比进销项增值税数据。 5.管理驾驶舱-指标修改:将顶部「销售产品数」调整为「销售订单数」;时间筛选:页面左上角新增日期范围下拉筛选控件,所有统计指标标注当前筛选时段;
---
src/views/equipmentManagement/spareParts/index.vue | 931 +++++++++++++++++++++++++++++++++------------------------
1 files changed, 535 insertions(+), 396 deletions(-)
diff --git a/src/views/equipmentManagement/spareParts/index.vue b/src/views/equipmentManagement/spareParts/index.vue
index 8abe35d..c25736f 100644
--- a/src/views/equipmentManagement/spareParts/index.vue
+++ b/src/views/equipmentManagement/spareParts/index.vue
@@ -1,26 +1,26 @@
<template>
- <div class="spare-part-category">
- <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>
+ <div class="spare-part-category">
+ <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>
<div class="table_list">
<PIMTable
rowKey="id"
@@ -36,83 +36,87 @@
</template>
</PIMTable>
</div>
-
- <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-item label="浠锋牸" prop="price">
- <el-input-number
- v-model="form.price"
- placeholder="璇疯緭鍏ヤ环鏍�"
- :min="0"
- :step="0.01"
- :precision="2"
- style="width: 100%"
- ></el-input-number>
- </el-form-item>
- </el-form>
- <template #footer>
+
+ <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-item label="浠锋牸" prop="price">
+ <el-input-number
+ v-model="form.price"
+ placeholder="璇疯緭鍏ヤ环鏍�"
+ :min="0"
+ :step="0.01"
+ :precision="2"
+ style="width: 100%"
+ ></el-input-number>
+ </el-form-item>
+ </el-form>
+ <template #footer>
<span class="dialog-footer">
<el-button type="primary" @click="submitForm" :loading="formLoading">纭畾</el-button>
<el-button @click="dialogVisible = false" :disabled="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.sparePartsName" placeholder="璇疯緭鍏ュ浠跺悕绉�" clearable style="width: 240px" />
- </el-form-item>
- <el-form-item label="鏉ユ簮">
- <el-select v-model="usageQuery.sourceType" placeholder="璇烽�夋嫨" clearable style="width: 200px">
- <el-option label="缁翠慨" :value="0" />
- <el-option label="淇濆吇" :value="1" />
- </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>
+ </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.sparePartsName" placeholder="璇疯緭鍏ュ浠跺悕绉�" clearable style="width: 240px" />
+ </el-form-item>
+ <el-form-item label="鏉ユ簮">
+ <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>
+ <el-button type="primary" @click="handleUsageQuery">鏌ヨ</el-button>
+ <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
rowKey="rowKey"
@@ -124,9 +128,63 @@
@pagination="handleUsagePageChange"
/>
</div>
- </el-tab-pane>
- </el-tabs>
- </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>
<script setup>
@@ -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);
@@ -157,375 +215,456 @@
const formRef = ref(null);
// 鏌ヨ鍙傛暟
const queryParams = reactive({
- name: ''
+ name: ''
});
// 鍒嗛〉鍙傛暟
const pagination = reactive({
- current: 1,
- size: 10,
- total: 0
+ current: 1,
+ size: 10,
+ total: 0
});
// 澶囦欢棰嗙敤璁板綍
const usageLoading = ref(false);
const usageQuery = reactive({
- sparePartsName: "",
- sourceType: "",
+ sparePartsName: "",
+ sourceType: "",
});
const usagePagination = reactive({
- current: 1,
- size: 10,
- total: 0,
+ current: 1,
+ size: 10,
+ total: 0,
});
const usageTableData = ref([]);
const usageColumns = ref([
- { label: "鏉ユ簮", prop: "sourceText" },
- { label: "鍗曟嵁/璁板綍ID", prop: "sourceId" },
- { label: "璁惧鍚嶇О", prop: "deviceName" },
- { label: "澶囦欢鍚嶇О", prop: "sparePartsName" },
- { label: "棰嗙敤鏁伴噺", prop: "quantity" },
- { label: "鎿嶄綔浜�", prop: "operator" },
- { label: "鏃堕棿", prop: "createTime" },
+ { label: "鏉ユ簮", prop: "sourceText" },
+ { label: "鍗曟嵁/璁板綍ID", prop: "sourceId" },
+ { label: "璁惧鍚嶇О", prop: "deviceName" },
+ { label: "澶囦欢鍚嶇О", prop: "sparePartsName" },
+ { label: "棰嗙敤鏁伴噺", prop: "quantity" },
+ { label: "鎿嶄綔浜�", prop: "operator" },
+ { label: "鏃堕棿", prop: "createTime" },
]);
const handleTabChange = async (name) => {
- if (name === "usage") {
- usagePagination.current = 1;
- await fetchUsageData();
- }
+ if (name === "usage") {
+ usagePagination.current = 1;
+ await fetchUsageData();
+ }
};
const columns = ref([
- {
- label: "璁惧鍚嶇О",
- prop: "deviceNameStr",
- },
- {
- label: "澶囦欢鍚嶇О",
- prop: "name",
- },
- {
- label: "澶囦欢缂栧彿",
- prop: "sparePartsNo",
- },
- {
- label: "鐘舵��",
- prop: "status",
- slot: "status",
- dataType: "slot",
- },
- {
- label: "浠锋牸",
- prop: "price",
- },
- {
- label: "鏁伴噺",
- prop: "quantity",
- },
- {
- label: "鎻忚堪",
- prop: "description",
- },
- {
- label: "鎿嶄綔",
- prop: "operation",
- width: 150,
- fixed: 'right',
- align: "center",
- dataType: "action",
- operation: [
- {
- name: "缂栬緫",
- clickFun: (row) => {
- editCategory(row)
- },
- },
- {
- name: "鍒犻櫎",
- clickFun: (row) => {
- deleteCategory(row.id)
- },
- },
- ],
- },
+ {
+ label: "璁惧鍚嶇О",
+ prop: "deviceNameStr",
+ },
+ {
+ label: "澶囦欢鍚嶇О",
+ prop: "name",
+ },
+ {
+ label: "澶囦欢缂栧彿",
+ prop: "sparePartsNo",
+ },
+ {
+ label: "鐘舵��",
+ prop: "status",
+ slot: "status",
+ dataType: "slot",
+ },
+ {
+ label: "浠锋牸",
+ prop: "price",
+ },
+ {
+ label: "鏁伴噺",
+ prop: "quantity",
+ },
+ {
+ label: "鎻忚堪",
+ prop: "description",
+ },
+ {
+ label: "鎿嶄綔",
+ prop: "operation",
+ width: 150,
+ fixed: 'right',
+ align: "center",
+ dataType: "action",
+ operation: [
+ {
+ name: "缂栬緫",
+ clickFun: (row) => {
+ editCategory(row)
+ },
+ },
+ {
+ name: "鍒犻櫎",
+ clickFun: (row) => {
+ deleteCategory(row.id)
+ },
+ },
+ ],
+ },
]);
// 琛ㄥ崟鏁版嵁
const form = reactive({
- id:'',
- name: '',
- sparePartsNo: '',
- status: '',
- description: '',
- deviceLedgerIds: [],
- price: null
+ id:'',
+ name: '',
+ sparePartsNo: '',
+ status: '',
+ description: '',
+ deviceLedgerIds: [],
+ price: null
});
// 琛ㄥ崟楠岃瘉瑙勫垯
const rules = reactive({
- name: [
- { required: true, message: '璇疯緭鍏ュ浠跺悕绉�', trigger: 'blur' }
- ],
- sparePartsNo: [
- { required: true, message: '璇疯緭鍏ュ浠剁紪鍙�', trigger: 'blur' }
- ],
- quantity:[
- { required: true, message: '璇疯緭鍏ユ暟閲�', trigger: 'blur' }
- ],
- status: [
- { required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }
- ],
- deviceLedgerIds: [
- {
- required: true,
- message: '璇烽�夋嫨璁惧',
- trigger: 'change',
- validator: (rule, value, callback) => {
- if (operationType.value === 'add' && (!value || value.length === 0)) {
- callback(new Error('璇烽�夋嫨璁惧'));
- } else {
- callback();
- }
- }
- }
- ]
+ name: [
+ { required: true, message: '璇疯緭鍏ュ浠跺悕绉�', trigger: 'blur' }
+ ],
+ sparePartsNo: [
+ { required: true, message: '璇疯緭鍏ュ浠剁紪鍙�', trigger: 'blur' }
+ ],
+ quantity:[
+ { required: true, message: '璇疯緭鍏ユ暟閲�', trigger: 'blur' }
+ ],
+ status: [
+ { required: true, message: '璇烽�夋嫨鐘舵��', trigger: 'change' }
+ ],
+ deviceLedgerIds: [
+ {
+ required: true,
+ message: '璇烽�夋嫨璁惧',
+ trigger: 'change',
+ validator: (rule, value, callback) => {
+ if (operationType.value === 'add' && (!value || value.length === 0)) {
+ callback(new Error('璇烽�夋嫨璁惧'));
+ } else {
+ callback();
+ }
+ }
+ }
+ ]
});
// 鑾峰彇缂╄繘閲�
const getIndentation = (row) => {
- // 杩欓噷绠�鍗曡繑鍥� 20锛屽彲鏍规嵁瀹為檯闇�姹傚疄鐜板眰绾х缉杩涢�昏緫
- return 20;
+ // 杩欓噷绠�鍗曡繑鍥� 20锛屽彲鏍规嵁瀹為檯闇�姹傚疄鐜板眰绾х缉杩涢�昏緫
+ return 20;
};
// 瀹氫箟 buildTree 鍑芥暟
const buildTree = (flatData) => {
- const map = {};
- const result = [];
- if(flatData){
- return result;
- }
- flatData.forEach(item => {
- map[item.id] = { ...item, children: [] };
- });
- flatData.forEach(item => {
- if (item.parentId === null || !map[item.parentId]) {
- result.push(map[item.id]);
- } else {
- map[item.parentId].children.push(map[item.id]);
- }
- });
- return result;
+ const map = {};
+ const result = [];
+ if(flatData){
+ return result;
+ }
+ flatData.forEach(item => {
+ map[item.id] = { ...item, children: [] };
+ });
+ flatData.forEach(item => {
+ if (item.parentId === null || !map[item.parentId]) {
+ result.push(map[item.id]);
+ } else {
+ map[item.parentId].children.push(map[item.id]);
+ }
+ });
+ return result;
};
// 鑾峰彇鍒楄〃鏁版嵁
const fetchListData = async () => {
- loading.value = true;
- try {
- const params = {
- current: pagination.current,
- size: pagination.size
- };
- if (queryParams.name) {
- params.name = queryParams.name;
- }
- const res = await getSparePartsList(params);
- if (res.code === 200) {
- renderTableData.value = res.data.records || [];
- categories.value = res.data.records || [];
- pagination.total = res.data.total || 0;
- }
- } catch (error) {
+ loading.value = true;
+ try {
+ const params = {
+ current: pagination.current,
+ size: pagination.size
+ };
+ if (queryParams.name) {
+ params.name = queryParams.name;
+ }
+ const res = await getSparePartsList(params);
+ if (res.code === 200) {
+ renderTableData.value = res.data.records || [];
+ categories.value = res.data.records || [];
+ pagination.total = res.data.total || 0;
+ }
+ } catch (error) {
loading.value = false;
- } finally {
- loading.value = false;
- }
+ } finally {
+ loading.value = false;
+ }
}
const fetchUsageData = async () => {
- usageLoading.value = true;
- try {
- const res = await getSparePartsUsagePage({
- current: usagePagination.current,
- size: usagePagination.size,
- sparePartsName: usageQuery.sparePartsName || undefined,
- sourceType: usageQuery.sourceType || 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.sourceText === "" ? "-" : r.sourceText,
- }));
- } else {
- usagePagination.total = 0;
- usageTableData.value = [];
- }
- } finally {
- usageLoading.value = false;
- }
+ usageLoading.value = true;
+ try {
+ const res = await getSparePartsUsagePage({
+ current: usagePagination.current,
+ size: usagePagination.size,
+ sparePartsName: usageQuery.sparePartsName || undefined,
+ sourceType: usageQuery.sourceType || 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.sourceText === "" ? "-" : r.sourceText,
+ }));
+ } else {
+ usagePagination.total = 0;
+ usageTableData.value = [];
+ }
+ } finally {
+ usageLoading.value = false;
+ }
};
const handleUsageQuery = () => {
- usagePagination.current = 1;
- fetchUsageData();
+ usagePagination.current = 1;
+ fetchUsageData();
};
const resetUsageQuery = () => {
- usageQuery.sparePartsName = "";
- usageQuery.sourceType = "";
- usagePagination.current = 1;
- fetchUsageData();
+ usageQuery.sparePartsName = "";
+ usageQuery.sourceType = "";
+ usagePagination.current = 1;
+ fetchUsageData();
};
const handleUsagePageChange = (obj) => {
- usagePagination.current = obj.page;
- usagePagination.size = obj.limit;
- fetchUsageData();
+ usagePagination.current = obj.page;
+ usagePagination.size = obj.limit;
+ fetchUsageData();
};
// 鏌ヨ
const handleQuery = () => {
- pagination.current = 1;
- fetchListData();
+ pagination.current = 1;
+ fetchListData();
}
// 閲嶇疆鏌ヨ
const resetQuery = () => {
- queryParams.name = '';
- pagination.current = 1;
- fetchListData();
+ queryParams.name = '';
+ pagination.current = 1;
+ fetchListData();
}
-// 鍒嗛〉澶у皬鏀瑰彉
-const handleSizeChange = (size) => {
- pagination.size = size;
- pagination.current = 1;
- fetchListData();
-}
-
-// 褰撳墠椤垫敼鍙�
-const handleCurrentChange = (current) => {
- pagination.current = current;
- fetchListData();
+// 鍒嗛〉鍙樺寲
+const handleSizeChange = ({ page, limit }) => {
+ pagination.current = page;
+ pagination.size = limit;
+ fetchListData();
}
// 鍔犺浇璁惧鍒楄〃锛堝湪鎵撳紑寮规鏃惰皟鐢級
const loadDeviceName = async () => {
- try {
- const { data } = await getDeviceLedger();
- deviceOptions.value = data || [];
- } catch (error) {
- ElMessage.error('鑾峰彇璁惧鍒楄〃澶辫触');
- }
+ try {
+ const { data } = await getDeviceLedger();
+ deviceOptions.value = data || [];
+ } catch (error) {
+ ElMessage.error('鑾峰彇璁惧鍒楄〃澶辫触');
+ }
};
// 鏂板鍒嗙被
const addCategory = async () => {
- await loadDeviceName();
- form.id = '';
- form.name = '';
- form.sparePartsNo = '';
- form.status = '';
- form.description = '';
- form.deviceLedgerIds = [];
- form.quantity = undefined;
- form.price = null;
- operationType.value = 'add'
- dialogVisible.value = true;
+ await loadDeviceName();
+ form.id = '';
+ form.name = '';
+ form.sparePartsNo = '';
+ form.status = '';
+ form.description = '';
+ form.deviceLedgerIds = [];
+ form.quantity = undefined;
+ form.price = null;
+ operationType.value = 'add'
+ dialogVisible.value = true;
};
// 缂栬緫鍒嗙被
const editCategory = async (row) => {
- await loadDeviceName();
- Object.assign(form, row);
- // 濡傛灉鍚庣杩斿洖鐨勬槸 deviceIds 瀛楃涓诧紝闇�瑕佽浆鎹负鏁扮粍
- if (row.deviceIds && typeof row.deviceIds === 'string') {
- // 纭繚ID绫诲瀷涓庤澶囬�夐」涓殑ID绫诲瀷涓�鑷�
- const deviceIdsArray = row.deviceIds.split(',').map(id => id.trim()).filter(id => id);
- // 濡傛灉璁惧閫夐」涓殑ID鏄暟瀛楃被鍨嬶紝鍒欒浆鎹负鏁板瓧
- if (deviceOptions.value.length > 0 && typeof deviceOptions.value[0].id === 'number') {
- form.deviceLedgerIds = deviceIdsArray.map(id => Number(id)).filter(id => !isNaN(id));
- } else {
- form.deviceLedgerIds = deviceIdsArray;
- }
- } else if (row.deviceIds && Array.isArray(row.deviceIds)) {
- form.deviceLedgerIds = row.deviceIds;
- } else {
- form.deviceLedgerIds = [];
- }
- operationType.value = 'edit'
- dialogVisible.value = true;
+ await loadDeviceName();
+ Object.assign(form, row);
+ // 濡傛灉鍚庣杩斿洖鐨勬槸 deviceIds 瀛楃涓诧紝闇�瑕佽浆鎹负鏁扮粍
+ if (row.deviceIds && typeof row.deviceIds === 'string') {
+ // 纭繚ID绫诲瀷涓庤澶囬�夐」涓殑ID绫诲瀷涓�鑷�
+ const deviceIdsArray = row.deviceIds.split(',').map(id => id.trim()).filter(id => id);
+ // 濡傛灉璁惧閫夐」涓殑ID鏄暟瀛楃被鍨嬶紝鍒欒浆鎹负鏁板瓧
+ if (deviceOptions.value.length > 0 && typeof deviceOptions.value[0].id === 'number') {
+ form.deviceLedgerIds = deviceIdsArray.map(id => Number(id)).filter(id => !isNaN(id));
+ } else {
+ form.deviceLedgerIds = deviceIdsArray;
+ }
+ } else if (row.deviceIds && Array.isArray(row.deviceIds)) {
+ form.deviceLedgerIds = row.deviceIds;
+ } else {
+ form.deviceLedgerIds = [];
+ }
+ operationType.value = 'edit'
+ dialogVisible.value = true;
};
// 鍒犻櫎鍒嗙被
const deleteCategory = async (id) => {
- try {
- await ElMessageBox.confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ュ垎绫伙紝鏄惁缁х画?', '鎻愮ず', {
- confirmButtonText: '纭畾',
- cancelButtonText: '鍙栨秷',
- type: 'warning'
- });
- loading.value = true;
- const res = await delSparePart(id);
- if (res.code === 200) {
- ElMessage.success('鍒犻櫎鎴愬姛');
- fetchListData();
- } else {
- ElMessage.error(res.message || '鍒犻櫎澶辫触');
- }
- } catch (error) {
- if (error !== 'cancel') {
- ElMessage.error('鍒犻櫎澶辫触');
- }
- } finally {
- loading.value = false;
- }
+ try {
+ await ElMessageBox.confirm('姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ュ垎绫伙紝鏄惁缁х画?', '鎻愮ず', {
+ confirmButtonText: '纭畾',
+ cancelButtonText: '鍙栨秷',
+ type: 'warning'
+ });
+ loading.value = true;
+ const res = await delSparePart(id);
+ if (res.code === 200) {
+ ElMessage.success('鍒犻櫎鎴愬姛');
+ fetchListData();
+ } else {
+ ElMessage.error(res.message || '鍒犻櫎澶辫触');
+ }
+ } catch (error) {
+ if (error !== 'cancel') {
+ ElMessage.error('鍒犻櫎澶辫触');
+ }
+ } finally {
+ loading.value = false;
+ }
};
// 鎻愪氦琛ㄥ崟
const submitForm = async () => {
- if (!formRef.value) return;
- try {
- await formRef.value.validate();
- formLoading.value = true;
-
- // 鏋勫缓鎻愪氦鏁版嵁
- const submitData = {
- ...form,
- deviceIds: form.deviceLedgerIds && form.deviceLedgerIds.length > 0
- ? form.deviceLedgerIds.join(',')
- : ''
- };
-
- // 鍒犻櫎涓嶉渶瑕佺殑瀛楁
- delete submitData.deviceLedgerIds;
-
- if (operationType.value === 'edit') {
- let res = await editSparePart(submitData);
- if (res.code === 200) {
- ElMessage.success('缂栬緫鎴愬姛');
- dialogVisible.value = false;
- fetchListData();
- }
- } else {
- let res = await addSparePart(submitData);
- if (res.code === 200) {
- ElMessage.success('鏂板鎴愬姛');
- dialogVisible.value = false;
- fetchListData();
- }
- }
- } catch (error) {
- ElMessage.error('璇峰~鍐欏畬鏁磋〃鍗曚俊鎭�');
- } finally {
- formLoading.value = false;
- }
+ if (!formRef.value) return;
+ try {
+ await formRef.value.validate();
+ formLoading.value = true;
+
+ // 鏋勫缓鎻愪氦鏁版嵁
+ const submitData = {
+ ...form,
+ deviceIds: form.deviceLedgerIds && form.deviceLedgerIds.length > 0
+ ? form.deviceLedgerIds.join(',')
+ : ''
+ };
+
+ // 鍒犻櫎涓嶉渶瑕佺殑瀛楁
+ delete submitData.deviceLedgerIds;
+
+ if (operationType.value === 'edit') {
+ let res = await editSparePart(submitData);
+ if (res.code === 200) {
+ ElMessage.success('缂栬緫鎴愬姛');
+ dialogVisible.value = false;
+ fetchListData();
+ }
+ } else {
+ let res = await addSparePart(submitData);
+ if (res.code === 200) {
+ ElMessage.success('鏂板鎴愬姛');
+ dialogVisible.value = false;
+ fetchListData();
+ }
+ }
+ } catch (error) {
+ ElMessage.error('璇峰~鍐欏畬鏁磋〃鍗曚俊鎭�');
+ } finally {
+ formLoading.value = false;
+ }
+};
+
+// 鐩存帴鍑哄簱
+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();
+ fetchListData();
});
</script>
<style scoped>
.spare-part-category {
- padding: 20px;
+ padding: 20px;
}
.search_form {
display: flex;
@@ -533,38 +672,38 @@
justify-content: space-between;
}
.table_list {
- margin-top: unset;
+ margin-top: unset;
}
.pagination-container {
- margin-top: 20px;
- display: flex;
- justify-content: flex-end;
+ margin-top: 20px;
+ display: flex;
+ justify-content: flex-end;
}
.el-table__header-wrapper th {
- background-color: #f5f7fa;
- font-weight: 600;
+ background-color: #f5f7fa;
+ font-weight: 600;
}
.el-table__row:hover > td {
- background-color: #fafafa;
+ background-color: #fafafa;
}
/* 鎸夐挳缁勬牱寮� */
.actions > div {
- display: flex;
- gap: 10px;
+ display: flex;
+ gap: 10px;
}
/* 纭繚琛ㄦ牸涓殑鎿嶄綔鎸夐挳涓嶄細琚埅鏂� */
.el-table-column--fixed-right .el-button {
- margin: 0 2px;
+ margin: 0 2px;
}
/* 鏍戝舰鑺傜偣鍐呭鏍峰紡 */
.nested-tree .el-tree-node__expand-icon {
- font-size: 12px;
- margin-right: 4px;
+ font-size: 12px;
+ margin-right: 4px;
}
</style>
\ No newline at end of file
--
Gitblit v1.9.3