From f281afc3ae596f649340bfc592b746917e28d701 Mon Sep 17 00:00:00 2001
From: gongchunyi <deslre0381@gmail.com>
Date: 星期四, 12 三月 2026 17:06:30 +0800
Subject: [PATCH] Merge branch 'dev_银川_中盛建材' of http://114.132.189.42:9002/r/product-inventory-management into dev_银川_中盛建材
---
src/api/costAccounting/energyCosts.js | 21
src/api/basicData/newProduct.js | 126 +
src/api/energyManagement/energyType.js | 11
src/views/basicData/product/index.vue | 1323 +++++++++++++------
src/views/costAccounting/energyCosts/index.vue | 1135 +++++++++++++++++
src/views/basicData/product/ImportExcel/index.vue | 197 +-
src/views/reportAnalysis/unitEnergyConsumption/index.vue | 405 ++++++
src/views/basicData/product/xxx.js | 615 +++++++++
src/views/energyManagement/energyConsumptionStatistical/index.vue | 117 +
9 files changed, 3,391 insertions(+), 559 deletions(-)
diff --git a/src/api/basicData/newProduct.js b/src/api/basicData/newProduct.js
new file mode 100644
index 0000000..186f343
--- /dev/null
+++ b/src/api/basicData/newProduct.js
@@ -0,0 +1,126 @@
+// 浜у搧缁存姢椤甸潰鎺ュ彛
+import request from '@/utils/request'
+
+// 浜у搧鏍戞煡璇�
+export function productTreeList(query) {
+ return request({
+ url: '/productMaterial/list',
+ method: 'get',
+ params: query
+ })
+}
+// 浜у搧瀛愮被鏂板
+export function addOrEditProduct(query) {
+ return request({
+ url: '/productMaterial/add',
+ method: 'post',
+ data: query
+ })
+}
+// 浜у搧瀛愮被淇敼
+export function updateOrEditProduct(query) {
+ return request({
+ url: '/productMaterial/update',
+ method: 'put',
+ data: query
+ })
+}
+// 瑙勬牸鍨嬪彿鏂板
+export function addOrEditProductModel(query) {
+ return request({
+ url: '/productMaterialSku/add',
+ method: 'post',
+ data: query
+ })
+}
+// 瑙勬牸鍨嬪彿淇敼
+export function updateOrEditProductModel(query) {
+ return request({
+ url: '/productMaterialSku/update',
+ method: 'put',
+ data: query
+ })
+}
+// 浜у搧瀛愮被鍒犻櫎
+export function delProduct(query) {
+ return request({
+ url: '/productMaterial/delete',
+ method: 'delete',
+ data: query
+ })
+}
+// 瑙勬牸鍨嬪彿鍒犻櫎
+export function delProductModel(query) {
+ return request({
+ url: '/productMaterialSku/delete',
+ method: 'delete',
+ data: query
+ })
+}
+// 瑙勬牸鍨嬪彿鏌ヨ
+export function modelList(query) {
+ return request({
+ url: '/basic/product/modelList',
+ method: 'get',
+ params: query
+ })
+}
+export function modelListPage(query) {
+ return request({
+ url: '/productMaterialSku/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 涓嬭浇浜у搧瀵煎叆妯℃澘
+export function downloadProductModelImportTemplate() {
+ return request({
+ url: '/productMaterialSku/downloadTemplate',
+ method: 'post',
+ responseType: 'blob'
+ })
+}
+
+// 浜у搧澶х被鏂板
+export function addOrEditProductConfig(query) {
+ return request({
+ url: '/productMaterial/config/add',
+ method: 'post',
+ data: query
+ })
+}
+// 浜у搧澶х被淇敼
+export function updateOrEditProductConfig(query) {
+ return request({
+ url: '/productMaterial/config/update',
+ method: 'put',
+ data: query
+ })
+}
+
+// 浜у搧澶х被鍒犻櫎
+export function delProductConfig(query) {
+ return request({
+ url: '/productMaterial/config/delete',
+ method: 'delete',
+ data: query
+ })
+}
+
+// 浜у搧鐗╂枡淇℃伅-瀛樿揣绫诲埆鏁版嵁闆嗗悎
+export function getinventoryCategoryList(query) {
+ return request({
+ url: '/productMaterial/inventoryCategoryList',
+ method: 'get',
+ params: query
+ })
+}
+// 浜у搧鐗╂枡淇℃伅-鐗╂枡绫诲瀷鏁版嵁闆嗗悎
+export function getmaterialTypeList(query) {
+ return request({
+ url: '/productMaterial/materialTypeList',
+ method: 'get',
+ params: query
+ })
+}
\ No newline at end of file
diff --git a/src/api/costAccounting/energyCosts.js b/src/api/costAccounting/energyCosts.js
new file mode 100644
index 0000000..2c1e286
--- /dev/null
+++ b/src/api/costAccounting/energyCosts.js
@@ -0,0 +1,21 @@
+// 鑳借�楁垚鏈牳绠楁帴鍙�
+import request from "@/utils/request";
+
+// 鑳借�楁垚鏈粺璁�
+export function energyCostStatistics(query) {
+ return request({
+ url: "/energyCost/statistics",
+ method: "get",
+ params: query,
+ });
+}
+
+// 瀵煎嚭鑳借�楁垚鏈姤琛�
+export function exportEnergyCostReport(query) {
+ return request({
+ url: "/energyCost/export",
+ method: "get",
+ params: query,
+ responseType: "blob",
+ });
+}
diff --git a/src/api/energyManagement/energyType.js b/src/api/energyManagement/energyType.js
index 71fbc29..f2986fa 100644
--- a/src/api/energyManagement/energyType.js
+++ b/src/api/energyManagement/energyType.js
@@ -75,4 +75,13 @@
url: `/energyConsumptionDetailFile/${ids}`,
method: 'delete',
})
-}
\ No newline at end of file
+}
+
+// 鑳借�楁妱琛ㄦ槑缁�-缁熻鏌ヨ
+export function energyConsumptionDetailStatistics(query) {
+ return request({
+ url: "/energyConsumptionDetail/statistics",
+ method: "get",
+ params: query,
+ });
+}
diff --git a/src/views/basicData/product/ImportExcel/index.vue b/src/views/basicData/product/ImportExcel/index.vue
index 2afbb64..3611960 100644
--- a/src/views/basicData/product/ImportExcel/index.vue
+++ b/src/views/basicData/product/ImportExcel/index.vue
@@ -1,14 +1,25 @@
<template>
- <el-button type="info" plain icon="Upload" @click="handleImport">
+ <el-button type="info"
+ plain
+ icon="Upload"
+ @click="handleImport">
瀵煎叆
</el-button>
- <el-dialog v-model="upload.open" :title="upload.title" @close="handleDialogClose">
- <FileUpload ref="fileUploadRef" accept=".xlsx, .xls" :headers="upload.headers" :action="uploadUrl"
- :disabled="upload.isUploading" :showTip="true" @success="handleFileSuccess"
- :downloadTemplate="handleDownloadTemplate" />
+ <el-dialog v-model="upload.open"
+ :title="upload.title"
+ @close="handleDialogClose">
+ <FileUpload ref="fileUploadRef"
+ accept=".xlsx, .xls"
+ :headers="upload.headers"
+ :action="uploadUrl"
+ :disabled="upload.isUploading"
+ :showTip="true"
+ @success="handleFileSuccess"
+ :downloadTemplate="handleDownloadTemplate" />
<template #footer>
<div class="dialog-footer">
- <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+ <el-button type="primary"
+ @click="submitFileForm">纭� 瀹�</el-button>
<el-button @click="upload.open = false">鍙� 娑�</el-button>
</div>
</template>
@@ -16,100 +27,102 @@
</template>
<script setup>
-import { reactive, computed } from "vue";
-import { getToken } from "@/utils/auth.js";
-import { FileUpload } from "@/components/Upload";
-import { ElMessage } from "element-plus";
-import { downloadProductModelImportTemplate } from "@/api/basicData/product.js";
+ import { reactive, computed } from "vue";
+ import { getToken } from "@/utils/auth.js";
+ import { FileUpload } from "@/components/Upload";
+ import { ElMessage } from "element-plus";
+ import { downloadProductModelImportTemplate } from "@/api/basicData/newProduct.js";
-defineOptions({
- name: "浜у搧缁存姢瀵煎叆",
-});
+ defineOptions({
+ name: "浜у搧缁存姢瀵煎叆",
+ });
-const props = defineProps({
- productId: { type: [String, Number], default: "" },
-});
-const emits = defineEmits(["uploadSuccess"]);
-const fileUploadRef = ref();
-const upload = reactive({
- // 鏄惁鏄剧ず寮瑰嚭灞傦紙渚涘簲鍟嗗鍏ワ級
- open: false,
- // 寮瑰嚭灞傛爣棰橈紙渚涘簲鍟嗗鍏ワ級
- title: "",
- // 鏄惁绂佺敤涓婁紶
- isUploading: false,
- // 璁剧疆涓婁紶鐨勮姹傚ご閮�
- headers: { Authorization: "Bearer " + getToken() },
-});
-// 涓婁紶鐨勫湴鍧�锛堟惡甯� productId 鍙傛暟锛屼紶缁欏悗绔殑 importProduct 鎺ュ彛锛�
-const uploadUrl = computed(
- () =>
- import.meta.env.VITE_APP_BASE_API +
- "/basic/product/import" +
- (props.productId ? `?productId=${props.productId}` : "")
-);
-// 鐐瑰嚮瀵煎叆
-const handleImport = () => {
- if (!props.productId) {
- ElMessage({ message: "璇峰厛閫夋嫨浜у搧", type: "warning" });
- return;
- }
- upload.open = true;
- upload.title = "浜у搧瀵煎叆";
-};
+ const props = defineProps({
+ productId: { type: [String, Number], default: "" },
+ });
+ const emits = defineEmits(["uploadSuccess"]);
+ const fileUploadRef = ref();
+ const upload = reactive({
+ // 鏄惁鏄剧ず寮瑰嚭灞傦紙渚涘簲鍟嗗鍏ワ級
+ open: false,
+ // 寮瑰嚭灞傛爣棰橈紙渚涘簲鍟嗗鍏ワ級
+ title: "",
+ // 鏄惁绂佺敤涓婁紶
+ isUploading: false,
+ // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+ headers: { Authorization: "Bearer " + getToken() },
+ });
+ // 涓婁紶鐨勫湴鍧�锛堟惡甯� productId 鍙傛暟锛屼紶缁欏悗绔殑 importProduct 鎺ュ彛锛�
+ const uploadUrl = computed(
+ () =>
+ import.meta.env.VITE_APP_BASE_API +
+ "/productMaterialSku/import" +
+ (props.productId ? `?materialId=${props.productId}` : "")
+ );
+ // 鐐瑰嚮瀵煎叆
+ const handleImport = () => {
+ if (!props.productId) {
+ ElMessage({ message: "璇峰厛閫夋嫨浜у搧", type: "warning" });
+ return;
+ }
+ upload.open = true;
+ upload.title = "浜у搧瑙勬牸瀵煎叆";
+ };
-const submitFileForm = () => {
- fileUploadRef.value.uploadApi();
-};
+ const submitFileForm = () => {
+ fileUploadRef.value.uploadApi();
+ };
-// 鍏抽棴寮圭獥鏃舵竻闄ゅ凡閫夋枃浠�
-const handleDialogClose = () => {
- fileUploadRef.value?.clearFiles?.();
-};
+ // 鍏抽棴寮圭獥鏃舵竻闄ゅ凡閫夋枃浠�
+ const handleDialogClose = () => {
+ fileUploadRef.value?.clearFiles?.();
+ };
-const handleFileSuccess = (response) => {
- const { code, msg } = response;
- if (code == 200) {
- ElMessage({ message: msg || "瀵煎叆鎴愬姛", type: "success" });
- upload.open = false;
- emits("uploadSuccess");
- } else {
- ElMessage({ message: msg, type: "error" });
- }
-};
+ const handleFileSuccess = response => {
+ const { code, msg } = response;
+ if (code == 200) {
+ ElMessage({ message: msg || "瀵煎叆鎴愬姛", type: "success" });
+ upload.open = false;
+ emits("uploadSuccess");
+ } else {
+ ElMessage({ message: msg, type: "error" });
+ }
+ };
-// 涓嬭浇 Excel 瀵煎叆妯℃澘
-const handleDownloadTemplate = () => {
- downloadProductModelImportTemplate()
- .then((blobData) => {
- const blob =
- blobData instanceof Blob
- ? blobData
- : new Blob([blobData], { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" });
- const url = window.URL.createObjectURL(blob);
- const link = document.createElement("a");
- link.href = url;
- link.download = "浜у搧瀵煎叆妯℃澘.xlsx";
- document.body.appendChild(link);
- link.click();
- document.body.removeChild(link);
- window.URL.revokeObjectURL(url);
- ElMessage({ message: "妯℃澘涓嬭浇鎴愬姛", type: "success" });
- })
- .catch(() => {
- ElMessage({ message: "妯℃澘涓嬭浇澶辫触", type: "error" });
- });
-};
+ // 涓嬭浇 Excel 瀵煎叆妯℃澘
+ const handleDownloadTemplate = () => {
+ downloadProductModelImportTemplate()
+ .then(blobData => {
+ const blob =
+ blobData instanceof Blob
+ ? blobData
+ : new Blob([blobData], {
+ type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
+ });
+ const url = window.URL.createObjectURL(blob);
+ const link = document.createElement("a");
+ link.href = url;
+ link.download = "浜у搧瑙勬牸瀵煎叆妯℃澘.xlsx";
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ window.URL.revokeObjectURL(url);
+ ElMessage({ message: "妯℃澘涓嬭浇鎴愬姛", type: "success" });
+ })
+ .catch(() => {
+ ElMessage({ message: "妯℃澘涓嬭浇澶辫触", type: "error" });
+ });
+ };
</script>
<style scoped>
-.import-tip {
- margin-top: 12px;
- font-size: 12px;
- color: var(--el-text-color-secondary);
-}
+ .import-tip {
+ margin-top: 12px;
+ font-size: 12px;
+ color: var(--el-text-color-secondary);
+ }
-.import-tip .el-button {
- margin-left: 8px;
-}
+ .import-tip .el-button {
+ margin-left: 8px;
+ }
</style>
diff --git a/src/views/basicData/product/index.vue b/src/views/basicData/product/index.vue
index 7b2a819..c4c8f06 100644
--- a/src/views/basicData/product/index.vue
+++ b/src/views/basicData/product/index.vue
@@ -2,64 +2,69 @@
<div class="app-container product-view">
<div class="left">
<div>
- <el-input
- v-model="search"
- style="width: 210px"
- placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
- @change="searchFilter"
- @clear="searchFilter"
- clearable
- prefix-icon="Search"
- />
- <el-button
- type="primary"
- @click="openProDia('addOne')"
- style="margin-left: 10px"
- >鏂板浜у搧澶х被</el-button
- >
+ <el-input v-model="search"
+ style="width: 210px"
+ placeholder="杈撳叆鍏抽敭瀛楄繘琛屾悳绱�"
+ @change="searchFilter"
+ @clear="searchFilter"
+ clearable
+ prefix-icon="Search" />
+ <el-button type="primary"
+ @click="openProDia1('addOne')"
+ style="margin-left: 10px">鏂板浜у搧澶х被</el-button>
</div>
<div ref="containerRef">
- <el-tree
- ref="tree"
- v-loading="treeLoad"
- :data="list"
- @node-click="handleNodeClick"
- :expand-on-click-node="false"
- :default-expanded-keys="expandedKeys"
- :filter-node-method="filterNode"
- :props="{ children: 'children', label: 'label' }"
- highlight-current
- node-key="id"
- class="product-tree-scroll"
- style="height: calc(100vh - 190px); overflow-y: auto"
- >
+ <el-tree ref="tree"
+ v-loading="treeLoad"
+ :data="list"
+ @node-click="handleNodeClick"
+ :expand-on-click-node="false"
+ :default-expanded-keys="expandedKeys"
+ :filter-node-method="filterNode"
+ :props="{ children: 'children', label: 'label' }"
+ highlight-current
+ node-key="id"
+ class="product-tree-scroll">
<template #default="{ node, data }">
<div class="custom-tree-node">
<span class="tree-node-content">
- <el-icon class="orange-icon">
+ <el-icon class="tree-icon">
<component :is="data.children && data.children.length > 0
? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" />
</el-icon>
<span class="tree-node-label">{{ data.label }}</span>
</span>
- <div>
- <el-button
- type="primary"
- link
- @click="openProDia('edit', data)"
- >
+ <div v-if="data.isLeaf">
+ <el-button type="primary"
+ link
+ @click="openProDia('edit', data)">
缂栬緫
</el-button>
- <el-button type="primary" link @click="openProDia('add', data)" :disabled="node.level >= 3">
+ <el-button v-if="!node.childNodes.length"
+ style="margin-left: 4px"
+ type="danger"
+ link
+ @click="remove(node, data)">
+ 鍒犻櫎
+ </el-button>
+ </div>
+ <div v-else>
+ <!-- 澶х被 -->
+ <el-button type="primary"
+ link
+ @click="openProDia1('edit', data)">
+ 缂栬緫
+ </el-button>
+ <el-button type="primary"
+ link
+ @click="openProDia('add', data)">
娣诲姞浜у搧
</el-button>
- <el-button
- v-if="!node.childNodes.length"
- style="margin-left: 4px"
- type="danger"
- link
- @click="remove(node, data)"
- >
+ <el-button style="margin-left: 4px"
+ type="danger"
+ v-if="!node.childNodes.length"
+ link
+ @click="remove1(node, data)">
鍒犻櫎
</el-button>
</div>
@@ -69,104 +74,189 @@
</div>
</div>
<div class="right">
- <div style="margin-bottom: 10px" v-if="isShowButton">
- <el-button type="primary" @click="openModelDia('add')">
+ <div style="margin-bottom: 10px"
+ v-if="isShowButton">
+ <el-button type="primary"
+ @click="openModelDia('add')">
鏂板瑙勬牸鍨嬪彿
</el-button>
- <ImportExcel :product-id="currentId" @uploadSuccess="getModelList" />
- <el-button
- type="danger"
- @click="handleDelete"
- style="margin-left: 10px"
- plain
- >
+ <ImportExcel :product-id="currentId"
+ @uploadSuccess="getModelList" />
+ <el-button type="danger"
+ @click="handleDelete"
+ style="margin-left: 10px"
+ plain>
鍒犻櫎
</el-button>
</div>
- <PIMTable
- rowKey="id"
- :column="tableColumn"
- :tableData="tableData"
- :page="page"
- :isSelection="true"
- @selection-change="handleSelectionChange"
- :tableLoading="tableLoading"
- @pagination="pagination"
- ></PIMTable>
+ <PIMTable rowKey="id"
+ :column="tableColumn"
+ :tableData="tableData"
+ :isSelection="true"
+ :isShowPagination="false"
+ @selection-change="handleSelectionChange"
+ :tableLoading="tableLoading"></PIMTable>
</div>
- <el-dialog v-model="productDia" title="浜у搧" width="400px" @keydown.enter.prevent>
- <el-form
- :model="form"
- label-width="140px"
- label-position="top"
- :rules="rules"
- ref="formRef"
- >
+ <el-dialog v-model="productDia"
+ title="浜у搧"
+ width="400px"
+ @keydown.enter.prevent>
+ <el-form :model="form"
+ label-width="140px"
+ label-position="top"
+ :rules="rules"
+ ref="formRef">
<el-row :gutter="30">
<el-col :span="24">
- <el-form-item label="浜у搧鍚嶇О锛�" prop="productName">
- <el-input
- v-model="form.productName"
- placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
- maxlength="20"
- show-word-limit
- clearable
- @keydown.enter.prevent
- />
+ <el-form-item label="浜у搧鍚嶇О锛�"
+ prop="materialName">
+ <el-input v-model="form.materialName"
+ placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
+ maxlength="20"
+ show-word-limit
+ clearable
+ @keydown.enter.prevent />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="瀛樿揣绫诲埆锛�"
+ prop="inventoryCategoryId">
+ <el-select v-model="form.inventoryCategoryId"
+ placeholder="璇烽�夋嫨瀛樿揣绫诲埆"
+ clearable
+ style="width: 100%">
+ <el-option v-for="item in inventoryCategoryList"
+ :key="item.id"
+ :label="item.configName"
+ :value="item.id" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="鐗╂枡绫诲瀷锛�"
+ prop="materialTypeId">
+ <el-select v-model="form.materialTypeId"
+ placeholder="璇烽�夋嫨鐗╂枡绫诲瀷"
+ clearable
+ style="width: 100%">
+ <el-option v-for="item in materialTypeList"
+ :key="item.id"
+ :label="item.configName"
+ :value="item.id" />
+ </el-select>
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="鍩烘湰鍗曚綅锛�"
+ prop="baseUnit">
+ <el-input v-model="form.baseUnit"
+ placeholder="璇疯緭鍏ュ熀鏈崟浣�"
+ clearable
+ @keydown.enter.prevent />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="澶囨敞锛�">
+ <el-input v-model="form.remark"
+ placeholder="璇疯緭鍏ュ娉�"
+ type="textarea"
+ :rows="3"
+ clearable
+ @keydown.enter.prevent />
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
- <el-button type="primary" @click="submitForm">纭</el-button>
+ <el-button type="primary"
+ @click="submitForm">纭</el-button>
<el-button @click="closeProDia">鍙栨秷</el-button>
</div>
</template>
</el-dialog>
- <el-dialog
- v-model="modelDia"
- title="瑙勬牸鍨嬪彿"
- width="400px"
- @close="closeModelDia"
- @keydown.enter.prevent
- >
- <el-form
- :model="modelForm"
- label-width="140px"
- label-position="top"
- :rules="modelRules"
- ref="modelFormRef"
- >
+ <el-dialog v-model="modelDia"
+ title="瑙勬牸鍨嬪彿"
+ width="400px"
+ @close="closeModelDia"
+ @keydown.enter.prevent>
+ <el-form :model="modelForm"
+ label-width="140px"
+ label-position="top"
+ :rules="modelRules"
+ ref="modelFormRef">
<el-row>
<el-col :span="24">
- <el-form-item label="瑙勬牸鍨嬪彿锛�" prop="model">
- <el-input
- v-model="modelForm.model"
- placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
- clearable
- @keydown.enter.prevent
- />
+ <el-form-item label="瑙勬牸鍨嬪彿锛�"
+ prop="specification">
+ <el-input v-model="modelForm.specification"
+ placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+ clearable
+ @keydown.enter.prevent />
</el-form-item>
</el-col>
</el-row>
<el-row>
<el-col :span="24">
- <el-form-item label="鍗曚綅锛�" prop="unit">
- <el-input
- v-model="modelForm.unit"
- placeholder="璇疯緭鍏ュ崟浣�"
- clearable
- @keydown.enter.prevent
- />
+ <el-form-item label="渚涘簲鏂瑰紡锛�"
+ prop="supplyType">
+ <el-select v-model="modelForm.supplyType"
+ placeholder="璇烽�夋嫨渚涘簲鏂瑰紡"
+ clearable
+ style="width: 100%">
+ <el-option label="鑷埗"
+ value="鑷埗" />
+ <el-option label="澶栬喘"
+ value="澶栬喘" />
+ </el-select>
</el-form-item>
</el-col>
</el-row>
</el-form>
<template #footer>
<div class="dialog-footer">
- <el-button type="primary" @click="submitModelForm">纭</el-button>
+ <el-button type="primary"
+ @click="submitModelForm">纭</el-button>
<el-button @click="closeModelDia">鍙栨秷</el-button>
+ </div>
+ </template>
+ </el-dialog>
+ <el-dialog v-model="configDia"
+ title="浜у搧澶х被"
+ width="400px"
+ @keydown.enter.prevent>
+ <el-form :model="configForm"
+ label-width="140px"
+ label-position="top"
+ :rules="configRules"
+ ref="configFormRef">
+ <el-row :gutter="30">
+ <el-col :span="24">
+ <el-form-item label="閰嶇疆鍚嶇О锛�"
+ prop="configName">
+ <el-input v-model="configForm.configName"
+ placeholder="璇疯緭鍏ラ厤缃悕绉�"
+ maxlength="20"
+ show-word-limit
+ clearable
+ @keydown.enter.prevent />
+ </el-form-item>
+ </el-col>
+ </el-row>
+ </el-form>
+ <template #footer>
+ <div class="dialog-footer">
+ <el-button type="primary"
+ @click="submitConfigForm">纭</el-button>
+ <el-button @click="closeConfigDia">鍙栨秷</el-button>
</div>
</template>
</el-dialog>
@@ -174,359 +264,686 @@
</template>
<script setup>
-import { ref } from "vue";
-import { ElMessageBox } from "element-plus";
-import {
- addOrEditProduct,
- addOrEditProductModel,
- delProduct,
- delProductModel,
- modelListPage,
- productTreeList,
-} from "@/api/basicData/product.js";
-import ImportExcel from "./ImportExcel/index.vue";
+ import { ref } from "vue";
+ import { ElMessageBox } from "element-plus";
+ import {
+ addOrEditProduct,
+ updateOrEditProduct,
+ getinventoryCategoryList,
+ getmaterialTypeList,
+ addOrEditProductModel,
+ updateOrEditProductModel,
+ delProduct,
+ delProductModel,
+ modelListPage,
+ productTreeList,
+ addOrEditProductConfig,
+ updateOrEditProductConfig,
+ delProductConfig,
+ } from "@/api/basicData/newProduct.js";
+ import ImportExcel from "./ImportExcel/index.vue";
-const { proxy } = getCurrentInstance();
-const tree = ref(null);
-const containerRef = ref(null);
+ const { proxy } = getCurrentInstance();
+ const tree = ref(null);
+ const containerRef = ref(null);
-const productDia = ref(false);
-const modelDia = ref(false);
-const modelOperationType = ref("");
-const search = ref("");
-const currentId = ref("");
-const currentParentId = ref("");
-const operationType = ref("");
-const treeLoad = ref(false);
-const list = ref([]);
-const expandedKeys = ref([]);
-const tableColumn = ref([
- {
- label: "瑙勬牸鍨嬪彿",
- prop: "model",
- },
- {
- label: "鍗曚綅",
- prop: "unit",
- },
- {
- dataType: "action",
- label: "鎿嶄綔",
- align: "center",
- operation: [
- {
- name: "缂栬緫",
- type: "text",
- clickFun: (row) => {
- openModelDia("edit", row);
+ const productDia = ref(false);
+ const modelDia = ref(false);
+ const configDia = ref(false);
+ const modelOperationType = ref("");
+ const configOperationType = ref("");
+ const search = ref("");
+ const currentId = ref("");
+ const currentParentId = ref("");
+ const operationType = ref("");
+ const treeLoad = ref(false);
+ const list = ref([]);
+ const expandedKeys = ref([]);
+ const inventoryCategoryList = ref([]);
+ const materialTypeList = ref([]);
+
+ // 鑾峰彇瀛樿揣绫诲埆鍒楄〃
+ const getInventoryCategoryList = () => {
+ getinventoryCategoryList()
+ .then(res => {
+ inventoryCategoryList.value = res.data.map(item => ({
+ id: item.id,
+ configName: item.configName,
+ }));
+ })
+ .catch(err => {
+ console.error("鑾峰彇瀛樿揣绫诲埆澶辫触:", err);
+ });
+ };
+
+ // 鑾峰彇鐗╂枡绫诲瀷鍒楄〃
+ const getMaterialTypeList = () => {
+ getmaterialTypeList()
+ .then(res => {
+ materialTypeList.value = res.data.map(item => ({
+ id: item.id,
+ configName: item.configName,
+ }));
+ })
+ .catch(err => {
+ console.error("鑾峰彇鐗╂枡绫诲瀷澶辫触:", err);
+ });
+ };
+ const tableColumn = ref([
+ {
+ label: "瑙勬牸鍨嬪彿",
+ prop: "materialName",
+ },
+ {
+ label: "瑙勬牸",
+ prop: "specification",
+ },
+ {
+ label: "鍗曚綅",
+ prop: "baseUnit",
+ },
+ {
+ dataType: "action",
+ label: "鎿嶄綔",
+ align: "center",
+ operation: [
+ {
+ name: "缂栬緫",
+ type: "text",
+ clickFun: row => {
+ openModelDia("edit", row);
+ },
},
- },
- ],
- },
-]);
-const tableData = ref([]);
-const tableLoading = ref(false);
-const isShowButton = ref(false);
-const selectedRows = ref([]);
-const page = reactive({
- current: 1,
- size: 10,
- total: 0,
-});
-const data = reactive({
- form: {
- productName: "",
- },
- rules: {
- productName: [
- { required: true, message: "璇疯緭鍏�", trigger: "blur" },
- { max: 20, message: "浜у搧鍚嶇О涓嶈兘瓒呰繃20涓瓧绗�", trigger: "blur" },
- ],
- },
- modelForm: {
- model: "",
- unit: "",
- },
- modelRules: {
- model: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- unit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
- },
-});
-const { form, rules, modelForm, modelRules } = toRefs(data);
-// 鏌ヨ浜у搧鏍�
-const getProductTreeList = () => {
- treeLoad.value = true;
- productTreeList()
- .then((res) => {
- list.value = res;
- list.value.forEach((a) => {
- expandedKeys.value.push(a.label);
+ ],
+ },
+ ]);
+ const tableData = ref([]);
+ const tableLoading = ref(false);
+ const isShowButton = ref(false);
+ const selectedRows = ref([]);
+
+ const data = reactive({
+ form: {
+ materialTypeId: null,
+ inventoryCategoryId: null,
+ materialName: "",
+ baseUnit: "",
+ remark: "",
+ },
+ rules: {
+ materialName: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ { max: 20, message: "浜у搧鍚嶇О涓嶈兘瓒呰繃20涓瓧绗�", trigger: "blur" },
+ ],
+ inventoryCategoryId: [
+ { required: true, message: "璇烽�夋嫨", trigger: "change" },
+ ],
+ baseUnit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ },
+ modelForm: {
+ specification: "",
+ supplyType: "",
+ id: null,
+ },
+ modelRules: {
+ specification: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+ supplyType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+ },
+ configForm: {
+ configName: "",
+ type: 1,
+ id: null,
+ },
+ configRules: {
+ configName: [
+ { required: true, message: "璇疯緭鍏�", trigger: "blur" },
+ { max: 20, message: "閰嶇疆鍚嶇О涓嶈兘瓒呰繃20涓瓧绗�", trigger: "blur" },
+ ],
+ },
+ });
+ const { form, rules, modelForm, modelRules, configForm, configRules } =
+ toRefs(data);
+ // 鏌ヨ浜у搧鏍�
+ const getProductTreeList = () => {
+ treeLoad.value = true;
+ productTreeList()
+ .then(res => {
+ // 杞崲鏂扮殑鏁版嵁鏍煎紡
+ const newList = [];
+ expandedKeys.value = [];
+ for (const category of res.data) {
+ // 娣诲姞鍒嗙被鑺傜偣
+ const categoryNode = {
+ label: category.configName,
+ id: category.configId,
+ isLeaf: false,
+ children: category.materialList.map(item => ({
+ id: item.id,
+ isLeaf: true,
+ label: item.materialName,
+ inventoryCategoryId: item.inventoryCategoryId,
+ materialTypeId: item.materialTypeId,
+ remark: item.remark,
+ baseUnit: item.baseUnit,
+ })),
+ };
+ newList.push(categoryNode);
+ expandedKeys.value.push(category.configName);
+ }
+ list.value = newList;
+ treeLoad.value = false;
+ })
+ .catch(err => {
+ treeLoad.value = false;
});
- treeLoad.value = false;
- })
- .catch((err) => {
- treeLoad.value = false;
- });
-};
-// 杩囨护浜у搧鏍�
-const searchFilter = () => {
- proxy.$refs.tree.filter(search.value);
-};
-// 鎵撳紑浜у搧寮规
-const openProDia = (type, data) => {
- operationType.value = type;
- productDia.value = true;
- form.value.productName = "";
- if (type === "edit") {
- form.value.productName = data.productName;
- }
-};
-// 鎵撳紑瑙勬牸鍨嬪彿寮规
-const openModelDia = (type, data) => {
- modelOperationType.value = type;
- modelDia.value = true;
- modelForm.value.model = "";
- modelForm.value.model = "";
- modelForm.value.id = "";
- if (type === "edit") {
- modelForm.value = { ...data };
- }
-};
-// 鎻愪氦浜у搧鍚嶇О淇敼
-const submitForm = () => {
- proxy.$refs.formRef.validate((valid) => {
- if (valid) {
- if (operationType.value === "add") {
- form.value.parentId = currentId.value;
- form.value.id = "";
- } else if (operationType.value === "addOne") {
- form.value.id = "";
- form.value.parentId = "";
- } else {
- form.value.id = currentId.value;
- form.value.parentId = "";
+ };
+ // 杩囨护浜у搧鏍�
+ const searchFilter = () => {
+ proxy.$refs.tree.filter(search.value);
+ };
+ // 鎵撳紑浜у搧寮规
+ const openProDia = (type, data) => {
+ operationType.value = type;
+ productDia.value = true;
+ // 閲嶇疆琛ㄥ崟
+ form.value = {
+ materialName: "",
+ inventoryCategoryId: null,
+ baseUnit: "",
+ remark: "",
+ materialTypeId: null,
+ };
+ console.log(data);
+ if (type === "edit" && data) {
+ // 缂栬緫妯″紡锛屽洖濉暟鎹�
+ form.value.materialName = data.label || "";
+ form.value.inventoryCategoryId = data.inventoryCategoryId || null;
+ form.value.baseUnit = data.baseUnit || "";
+ form.value.remark = data.remark || "";
+ form.value.materialTypeId = data.materialTypeId || null;
+ form.value.id = data.id || null;
+ } else {
+ form.value.materialTypeId = data.id || null;
+ }
+ };
+ // 鎵撳紑浜у搧澶х被寮规
+ const openProDia1 = (type, data) => {
+ configOperationType.value = type;
+ configDia.value = true;
+ // 閲嶇疆琛ㄥ崟
+ configForm.value = {
+ configName: "",
+ type: 1,
+ id: null,
+ };
+ if (type === "edit" && data) {
+ // 缂栬緫妯″紡锛屽洖濉暟鎹�
+ configForm.value.configName = data.label || "";
+ configForm.value.id = data.id || null;
+ }
+ };
+ // 鎵撳紑瑙勬牸鍨嬪彿寮规
+ const openModelDia = (type, data) => {
+ modelOperationType.value = type;
+ modelDia.value = true;
+ // 閲嶇疆鎵�鏈夊瓧娈�
+ modelForm.value.specification = "";
+ modelForm.value.supplyType = "";
+ modelForm.value.id = null;
+
+ if (type === "edit" && data) {
+ // 缂栬緫妯″紡锛屽洖濉暟鎹�
+ modelForm.value.specification = data.specification || "";
+ modelForm.value.supplyType = data.supplyType || "";
+ modelForm.value.id = data.skuId || null;
+ }
+ };
+ // 鎻愪氦浜у搧鍚嶇О淇敼
+ const submitForm = () => {
+ proxy.$refs.formRef.validate(valid => {
+ if (valid) {
+ // 鏋勫缓鎻愪氦鍙傛暟
+ // const params = {
+ // materialTypeId: null,
+ // inventoryCategoryId: form.value.inventoryCategoryId,
+ // materialName: form.value.materialName,
+ // baseUnit: form.value.baseUnit,
+ // remark: form.value.remark,
+ // };
+
+ // if (operationType.value === "add") {
+ // // 娣诲姞瀛愮骇锛屼紶鐖剁骇鐨刬d浣滀负 materialTypeId
+ // params.materialTypeId = currentId.value;
+ // } else if (operationType.value === "addOne") {
+ // // 娣诲姞涓�绾э紝materialTypeId 涓� null
+ // params.materialTypeId = null;
+ // } else {
+ // // 缂栬緫锛屼紶褰撳墠id浣滀负 materialTypeId
+ // params.materialTypeId = currentId.value;
+ // }
+ console.log(form.value);
+ console.log(operationType.value);
+ if (operationType.value != "edit") {
+ addOrEditProduct(form.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeProDia();
+ getProductTreeList();
+ });
+ } else {
+ updateOrEditProduct(form.value).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeProDia();
+ getProductTreeList();
+ });
+ }
}
- addOrEditProduct(form.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeProDia();
- getProductTreeList();
- });
- }
- });
-};
-// 鍏抽棴浜у搧寮规
-const closeProDia = () => {
- proxy.$refs.formRef.resetFields();
- productDia.value = false;
-};
-
-// 鍒犻櫎浜у搧
-const remove = (node, data) => {
- let ids = [];
- ids.push(data.id);
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- delProduct(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getProductTreeList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
});
-};
-// 閫夋嫨浜у搧
-const handleNodeClick = (val, node, el) => {
- // 鍒ゆ柇鏄惁涓哄彾瀛愯妭鐐�
- isShowButton.value = !(val.children && val.children.length > 0);
- // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
- currentId.value = val.id;
- currentParentId.value = val.parentId;
- getModelList();
-};
-
-// 鎻愪氦瑙勬牸鍨嬪彿淇敼
-const submitModelForm = () => {
- proxy.$refs.modelFormRef.validate((valid) => {
- if (valid) {
- modelForm.value.productId = currentId.value;
- addOrEditProductModel(modelForm.value).then((res) => {
- proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
- closeModelDia();
- getModelList();
- });
- }
- });
-};
-// 鍏抽棴鍨嬪彿寮规
-const closeModelDia = () => {
- proxy.$refs.modelFormRef.resetFields();
- modelDia.value = false;
-};
-// 琛ㄦ牸閫夋嫨鏁版嵁
-const handleSelectionChange = (selection) => {
- selectedRows.value = selection;
-};
-
-// 鏌ヨ瑙勬牸鍨嬪彿
-const pagination = (obj) => {
- page.current = obj.page;
- page.size = obj.limit;
- getModelList();
-};
-const getModelList = () => {
- tableLoading.value = true;
- modelListPage({
- id: currentId.value,
- current: page.current,
- size: page.size,
- }).then((res) => {
- console.log("res", res);
- tableData.value = res.records;
- page.total = res.total;
- tableLoading.value = false;
- });
-};
-// 鍒犻櫎瑙勬牸鍨嬪彿
-const handleDelete = () => {
- let ids = [];
- if (selectedRows.value.length > 0) {
- ids = selectedRows.value.map((item) => item.id);
- } else {
- proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
- return;
- }
- ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
- confirmButtonText: "纭",
- cancelButtonText: "鍙栨秷",
- type: "warning",
- })
- .then(() => {
- tableLoading.value = true;
- delProductModel(ids)
- .then((res) => {
- proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
- getModelList();
- })
- .finally(() => {
- tableLoading.value = false;
- });
- })
- .catch(() => {
- proxy.$modal.msg("宸插彇娑�");
+ };
+ // 鍏抽棴浜у搧寮规
+ const closeProDia = () => {
+ proxy.$refs.formRef.resetFields();
+ // 鎵嬪姩閲嶇疆闈炶〃鍗曞瓧娈�
+ form.value.materialTypeId = null;
+ form.value.remark = "";
+ productDia.value = false;
+ };
+ // 鎻愪氦浜у搧澶х被淇敼
+ const submitConfigForm = () => {
+ proxy.$refs.configFormRef.validate(valid => {
+ if (valid) {
+ const params = {
+ configName: configForm.value.configName,
+ type: 1,
+ };
+ if (configOperationType.value === "edit") {
+ params.id = configForm.value.id;
+ updateOrEditProductConfig(params).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeConfigDia();
+ getProductTreeList();
+ });
+ } else {
+ addOrEditProductConfig(params).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeConfigDia();
+ getProductTreeList();
+ });
+ }
+ }
});
-};
-// 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊�
-const filterNode = (value, data, node) => {
- if (!value) {
- //濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤�
- return true;
- }
- // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁
- let val = value.toLowerCase();
- return chooseNode(val, data, node); // 璋冪敤杩囨护浜屽眰鏂规硶
-};
-// 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�.
-const chooseNode = (value, data, node) => {
- if (data.label.indexOf(value) !== -1) {
- return true;
- }
- const level = node.level;
- // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜�
- if (level === 1) {
- return false;
- }
- // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣
- let parentData = node.parent;
- // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣
- let index = 0;
- while (index < level - 1) {
- // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护
- if (parentData.data.label.indexOf(value) !== -1) {
+ };
+ // 鍏抽棴浜у搧澶х被寮规
+ const closeConfigDia = () => {
+ proxy.$refs.configFormRef.resetFields();
+ configDia.value = false;
+ };
+ // 鍒犻櫎浜у搧澶х被
+ const remove1 = (node, data) => {
+ let ids = [];
+ ids.push(data.id);
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ tableLoading.value = true;
+ delProductConfig(ids)
+ .then(res => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getProductTreeList();
+ })
+ .finally(() => {
+ tableLoading.value = false;
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+ };
+ // 鍒犻櫎浜у搧
+ const remove = (node, data) => {
+ let ids = [];
+ ids.push(data.id);
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ tableLoading.value = true;
+ delProduct(ids)
+ .then(res => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getProductTreeList();
+ })
+ .finally(() => {
+ tableLoading.value = false;
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+ };
+ // 閫夋嫨浜у搧
+ const handleNodeClick = (val, node, el) => {
+ // 鐐瑰嚮闈炲彾瀛愯妭鐐规椂锛屼笉鎵ц浠ヤ笅閫昏緫
+ if (!val.isLeaf) {
+ return;
+ }
+ // 鍒ゆ柇鏄惁涓哄彾瀛愯妭鐐�
+ isShowButton.value = !(val.children && val.children.length > 0);
+ // 鍙湁鍙跺瓙鑺傜偣鎵嶆墽琛屼互涓嬮�昏緫
+ currentId.value = val.id;
+ currentParentId.value = val.parentId;
+ getModelList();
+ };
+
+ // 鎻愪氦瑙勬牸鍨嬪彿淇敼
+ const submitModelForm = () => {
+ proxy.$refs.modelFormRef.validate(valid => {
+ if (valid) {
+ // 鏋勫缓鎻愪氦鍙傛暟
+ const params = {
+ materialId: currentId.value,
+ specification: modelForm.value.specification,
+ supplyType: modelForm.value.supplyType,
+ };
+ if (modelOperationType.value === "add") {
+ // 娣诲姞瑙勬牸鍨嬪彿
+ addOrEditProductModel(params).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeModelDia();
+ getModelList();
+ });
+ } else if (modelOperationType.value === "edit") {
+ // 淇敼瑙勬牸鍨嬪彿
+ params.id = modelForm.value.id;
+ updateOrEditProductModel(params).then(res => {
+ proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+ closeModelDia();
+ getModelList();
+ });
+ }
+ }
+ });
+ };
+ // 鍏抽棴鍨嬪彿寮规
+ const closeModelDia = () => {
+ proxy.$refs.modelFormRef.resetFields();
+ modelDia.value = false;
+ };
+ // 琛ㄦ牸閫夋嫨鏁版嵁
+ const handleSelectionChange = selection => {
+ selectedRows.value = selection;
+ };
+
+ // 鏌ヨ瑙勬牸鍨嬪彿
+ const getModelList = () => {
+ if (!currentId.value) {
+ return;
+ }
+ tableLoading.value = true;
+ modelListPage({
+ materialId: currentId.value,
+ }).then(res => {
+ console.log("res", res);
+ tableData.value = res.data;
+ tableLoading.value = false;
+ });
+ };
+ // 鍒犻櫎瑙勬牸鍨嬪彿
+ const handleDelete = () => {
+ let ids = [];
+ if (selectedRows.value.length > 0) {
+ ids = selectedRows.value.map(item => item.skuId);
+ } else {
+ proxy.$modal.msgWarning("璇烽�夋嫨鏁版嵁");
+ return;
+ }
+ ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎鎻愮ず", {
+ confirmButtonText: "纭",
+ cancelButtonText: "鍙栨秷",
+ type: "warning",
+ })
+ .then(() => {
+ tableLoading.value = true;
+ delProductModel(ids)
+ .then(res => {
+ proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+ getModelList();
+ })
+ .finally(() => {
+ tableLoading.value = false;
+ });
+ })
+ .catch(() => {
+ proxy.$modal.msg("宸插彇娑�");
+ });
+ };
+ // 璋冪敤tree杩囨护鏂规硶 涓枃鑻辫繃婊�
+ const filterNode = (value, data, node) => {
+ if (!value) {
+ //濡傛灉鏁版嵁涓虹┖锛屽垯杩斿洖true,鏄剧ず鎵�鏈夌殑鏁版嵁椤�
return true;
}
- // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
- parentData = parentData.parent;
- index++;
- }
- // 娌″尮閰嶅埌杩斿洖false
- return false;
-};
-getProductTreeList();
+ // 鏌ヨ鍒楄〃鏄惁鏈夊尮閰嶆暟鎹紝灏嗗�煎皬鍐欙紝鍖归厤鑻辨枃鏁版嵁
+ let val = value.toLowerCase();
+ return chooseNode(val, data, node); // 璋冪敤杩囨护浜屽眰鏂规硶
+ };
+ // 杩囨护鐖惰妭鐐� / 瀛愯妭鐐� (濡傛灉杈撳叆鐨勫弬鏁版槸鐖惰妭鐐逛笖鑳藉尮閰嶏紝鍒欒繑鍥炶鑺傜偣浠ュ強鍏朵笅鐨勬墍鏈夊瓙鑺傜偣锛涘鏋滃弬鏁版槸瀛愯妭鐐癸紝鍒欒繑鍥炶鑺傜偣鐨勭埗鑺傜偣銆俷ame鏄腑鏂囧瓧绗︼紝enName鏄嫳鏂囧瓧绗�.
+ const chooseNode = (value, data, node) => {
+ if (data.label.indexOf(value) !== -1) {
+ return true;
+ }
+ const level = node.level;
+ // 濡傛灉浼犲叆鐨勮妭鐐规湰韬氨鏄竴绾ц妭鐐瑰氨涓嶇敤鏍¢獙浜�
+ if (level === 1) {
+ return false;
+ }
+ // 鍏堝彇褰撳墠鑺傜偣鐨勭埗鑺傜偣
+ let parentData = node.parent;
+ // 閬嶅巻褰撳墠鑺傜偣鐨勭埗鑺傜偣
+ let index = 0;
+ while (index < level - 1) {
+ // 濡傛灉鍖归厤鍒扮洿鎺ヨ繑鍥烇紝姝ゅname鍊兼槸涓枃瀛楃锛宔nName鏄嫳鏂囧瓧绗︺�傚垽鏂尮閰嶄腑鑻辨枃杩囨护
+ if (parentData.data.label.indexOf(value) !== -1) {
+ return true;
+ }
+ // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
+ parentData = parentData.parent;
+ index++;
+ }
+ // 娌″尮閰嶅埌杩斿洖false
+ return false;
+ };
+ // 椤甸潰鍔犺浇鏃惰幏鍙栨暟鎹�
+ getInventoryCategoryList();
+ getMaterialTypeList();
+ getProductTreeList();
</script>
<style scoped>
-.product-view {
- display: flex;
-}
-.left {
- width: 450px;
- min-width: 450px;
- padding: 16px;
- background: #ffffff;
-}
-.right {
- flex: 1;
- min-width: 0;
- padding: 16px;
- margin-left: 20px;
- background: #ffffff;
-}
-.custom-tree-node {
- flex: 1;
- min-width: 0;
- display: flex;
- align-items: center;
- justify-content: space-between;
- font-size: 14px;
- padding-right: 8px;
-}
-.tree-node-content {
- flex: 1;
- min-width: 0;
- display: flex;
- align-items: center;
- height: 100%;
- overflow: hidden;
-}
-.tree-node-content .orange-icon {
- flex-shrink: 0;
-}
-.tree-node-label {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
-}
-.orange-icon {
- color: orange;
- font-size: 18px;
- margin-right: 8px; /* 鍥炬爣涓庢枃瀛椾箣闂村姞鐐归棿璺� */
-}
-.product-tree-scroll {
- scrollbar-width: thin;
- scrollbar-color: #c0c4cc #f5f7fa;
-}
-.product-tree-scroll::-webkit-scrollbar {
- width: 8px;
-}
-.product-tree-scroll::-webkit-scrollbar-track {
- background: #f5f7fa;
- border-radius: 4px;
-}
-.product-tree-scroll::-webkit-scrollbar-thumb {
- background: #c0c4cc;
- border-radius: 4px;
-}
-.product-tree-scroll::-webkit-scrollbar-thumb:hover {
- background: #909399;
-}
+ .product-view {
+ display: flex;
+ min-height: 100vh;
+ background-color: #f5f7fa;
+ padding: 20px;
+ gap: 20px;
+ }
+ .left {
+ width: 450px;
+ min-width: 450px;
+ background: #ffffff;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ }
+ .left > div:first-child {
+ padding: 16px;
+ border-bottom: 1px solid #e4e7ed;
+ background-color: #fafafa;
+ }
+ .left > div:last-child {
+ flex: 1;
+ overflow: hidden;
+ }
+ .right {
+ flex: 1;
+ min-width: 0;
+ background: #ffffff;
+ border-radius: 8px;
+ box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ }
+ .right > div:first-child {
+ padding: 16px;
+ border-bottom: 1px solid #e4e7ed;
+ background-color: #fafafa;
+ }
+ .right > div:last-child {
+ flex: 1;
+ overflow: auto;
+ padding: 16px;
+ }
+ .custom-tree-node {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ font-size: 14px;
+ padding: 8px 12px;
+ margin: 2px 0;
+ border-radius: 4px;
+ transition: all 0.3s ease;
+ }
+ .custom-tree-node:hover {
+ background-color: #f5f7fa;
+ }
+ .tree-node-content {
+ flex: 1;
+ min-width: 0;
+ display: flex;
+ align-items: center;
+ height: 100%;
+ overflow: hidden;
+ }
+ .tree-node-content .tree-icon {
+ flex-shrink: 0;
+ }
+ .tree-node-label {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ font-weight: 500;
+ color: #303133;
+ }
+ .tree-icon {
+ color: #409eff;
+ font-size: 18px;
+ margin-right: 10px;
+ transition: color 0.3s ease;
+ }
+ .custom-tree-node:hover .tree-icon {
+ color: #66b1ff;
+ }
+ .product-tree-scroll {
+ height: calc(100vh - 240px);
+ overflow-y: auto;
+ scrollbar-width: thin;
+ scrollbar-color: #c0c4cc #f5f7fa;
+ }
+ .product-tree-scroll::-webkit-scrollbar {
+ width: 6px;
+ }
+ .product-tree-scroll::-webkit-scrollbar-track {
+ background: #f5f7fa;
+ border-radius: 3px;
+ }
+ .product-tree-scroll::-webkit-scrollbar-thumb {
+ background: #c0c4cc;
+ border-radius: 3px;
+ }
+ .product-tree-scroll::-webkit-scrollbar-thumb:hover {
+ background: #909399;
+ }
+ .el-button {
+ border-radius: 4px;
+ font-size: 13px;
+ }
+ .el-button--primary {
+ background-color: #fff;
+ border-color: #409eff;
+ color: #409eff;
+ }
+ .el-button--primary.is-link {
+ background-color: transparent;
+ border-color: transparent;
+ color: #409eff;
+ }
+ .el-button--primary.is-link:hover {
+ background-color: transparent;
+ border-color: transparent;
+ color: #0033ff;
+ }
+ .el-button--primary:hover {
+ background-color: #e3f1ff;
+ border-color: #66b1ff;
+ }
+ .el-input {
+ border-radius: 4px;
+ }
+ .el-input__wrapper {
+ border-radius: 4px;
+ }
+ .el-dialog {
+ border-radius: 8px;
+ }
+ .el-dialog__header {
+ border-bottom: 1px solid #e4e7ed;
+ padding: 16px 20px;
+ }
+ .el-dialog__title {
+ font-size: 16px;
+ font-weight: 600;
+ color: #303133;
+ }
+ .el-dialog__body {
+ padding: 20px;
+ }
+ .el-form-item {
+ margin-bottom: 16px;
+ }
+ .el-form-item__label {
+ font-weight: 500;
+ color: #606266;
+ }
+ .dialog-footer {
+ display: flex;
+ justify-content: flex-end;
+ gap: 10px;
+ padding: 16px 20px;
+ border-top: 1px solid #e4e7ed;
+ background-color: #fafafa;
+ }
+ .PIMTable {
+ border-radius: 4px;
+ overflow: hidden;
+ }
+ .el-table {
+ border-radius: 4px;
+ }
+ .el-table th {
+ background-color: #fafafa;
+ font-weight: 600;
+ color: #303133;
+ }
+ .el-table tr:hover {
+ background-color: #f5f7fa;
+ }
</style>
diff --git a/src/views/basicData/product/xxx.js b/src/views/basicData/product/xxx.js
new file mode 100644
index 0000000..78be129
--- /dev/null
+++ b/src/views/basicData/product/xxx.js
@@ -0,0 +1,615 @@
+{
+ "msg": "鎿嶄綔鎴愬姛",
+ "code": 200,
+ "data": [
+ {
+ "configId": 19,
+ "configName": "鎴愬搧",
+ "materialList": [
+ {
+ "id": 11,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鏉挎潗",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 13,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "MU20鐑х粨鐓ょ煾鐭冲疄蹇冪爾",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 14,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "姘存偿鏍囩爾",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 15,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鐑х粨鐓ょ煾鐭抽〉宀╁疄蹇冪爾",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 16,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "姘存偿涓夎鐮�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 17,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "姘存偿鏂圭爾",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 18,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鐑х粨鐓ょ煾鐭抽〉宀╃┖蹇冪爾",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 19,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鐑х粨鐓ょ煾鐭抽〉宀╃爾",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 20,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鏍囩爾",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 23,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鍔犳皵鏉�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ }
+ ]
+ },
+
+ {
+ "configId": 27,
+ "configName": "鐢熶骇鐗╄��",
+ "materialList": [
+ {
+ "id": 43,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "闃插喕娑�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 60,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "閱囬吀璋冨拰婕�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 64,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "娓呮礂鍓�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 106,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鐏版枟杞�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 116,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鎵撳寘甯︼紙鎵嬪伐甯︼級",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 117,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "绋�閲婂墏",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 118,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鏈ㄦ墭鐩�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 310,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "涓変箼閱囪兒",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 313,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "涔欑倲",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 314,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "閫忓钩娌�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 315,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鐢佃В绮�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 316,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鎵撳寘甯�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 317,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "閽㈢悆",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 318,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "瀵硅鏈�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 319,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "閽㈤敾",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 320,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鎶楃(娑插帇娌�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 321,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "榛勬补",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 322,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "缂濈韩鏈烘补",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 323,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鏈烘补",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 324,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鏌存补",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 325,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鏄嗕粦鍘熷寘M320寮�榻胯疆娌瑰師",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 326,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鏄嗕粦CKD320涓礋鑽烽娇杞补鍘�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 327,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "涓欑兎",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 328,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鏄嗕粦CKC320涓礋鑽烽娇杞补鍘�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 329,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鏄嗕粦CKC150宸ヤ笟闂紡榻胯疆娌�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 330,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "姘ф皵",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 331,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鏄嗕粦46#鎶楃(娑插帇娌�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 332,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鐭宠湣",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 335,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鑴辨ā鍓�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ }
+ ]
+ },
+ {
+ "configId": 30,
+ "configName": "娌欏姞鐮屽潡",
+ "materialList": [
+ {
+ "id": 139,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "娌欏姞鐮屽潡",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ }
+ ]
+ },
+ {
+ "configId": 31,
+ "configName": "鐮屽潡",
+ "materialList": [
+ {
+ "id": 12,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鐮屽潡",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ }
+ ]
+ },
+ {
+ "configId": 35,
+ "configName": "杈呭姪鏉愭枡",
+ "materialList": [
+ {
+ "id": 22,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "姘у寲闀�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 486,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鍗℃墸",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 487,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "闃茶厫鍓�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 489,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鍐锋嫈涓�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ }
+ ]
+ },
+ {
+ "configId": 36,
+ "configName": "鍘熸潗鏂�",
+ "materialList": [
+ {
+ "id": 41,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鐢熺煶鐏�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 42,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "姘�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 488,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "纭呯爞",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 490,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "姘存偿",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 491,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "閾濈矇",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 492,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "绮夌叅鐏�",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ },
+ {
+ "id": 493,
+ "tenantId": null,
+ "materialTypeId": null,
+ "inventoryCategoryId": null,
+ "materialName": "鐭宠啅",
+ "baseUnit": null,
+ "remark": null,
+ "createTime": null,
+ "updateTime": null
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/src/views/costAccounting/energyCosts/index.vue b/src/views/costAccounting/energyCosts/index.vue
new file mode 100644
index 0000000..e5d470a
--- /dev/null
+++ b/src/views/costAccounting/energyCosts/index.vue
@@ -0,0 +1,1135 @@
+<template>
+ <div class="app-container">
+ <!-- 鎼滅储鍖哄煙 -->
+ <div class="search_form">
+ <el-form :model="searchForm"
+ :inline="true">
+ <el-form-item label="缁熻缁村害:">
+ <el-radio-group v-model="statisticsType"
+ @change="handleTypeChange">
+ <el-radio-button label="day">鎸夋棩缁熻</el-radio-button>
+ <el-radio-button label="month">鎸夋湀缁熻</el-radio-button>
+ </el-radio-group>
+ </el-form-item>
+ <el-form-item label="鑳借�楃被鍨�:">
+ <el-select v-model="searchForm.energyType"
+ placeholder="鍏ㄩ儴"
+ clearable
+ style="width: 140px;"
+ @change="handleQuery">
+ <el-option label="鍏ㄩ儴"
+ value="鍏ㄩ儴" />
+ <el-option label="姘�"
+ value="姘�" />
+ <el-option label="鐢�"
+ value="鐢�" />
+ <el-option label="姘�"
+ value="姘�" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鑳借�楃敤閫�:">
+ <el-select v-model="searchForm.energyPurpose"
+ placeholder="鍏ㄩ儴"
+ clearable
+ style="width: 140px;"
+ @change="handleQuery">
+ <el-option label="鍏ㄩ儴"
+ value="鍏ㄩ儴" />
+ <el-option label="鐢熶骇"
+ value="鐢熶骇" />
+ <el-option label="鍔炲叕"
+ value="鍔炲叕" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鏃堕棿鑼冨洿:">
+ <el-date-picker v-if="statisticsType === 'day'"
+ v-model="searchForm.dateRange"
+ type="daterange"
+ range-separator="鑷�"
+ start-placeholder="寮�濮嬫棩鏈�"
+ end-placeholder="缁撴潫鏃ユ湡"
+ value-format="YYYY-MM-DD"
+ style="width: 240px;"
+ @change="handleQuery" />
+ <el-date-picker v-else
+ v-model="searchForm.monthRange"
+ type="monthrange"
+ range-separator="鑷�"
+ start-placeholder="寮�濮嬫湀浠�"
+ end-placeholder="缁撴潫鏈堜唤"
+ value-format="YYYY-MM"
+ style="width: 240px;"
+ @change="handleQuery" />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="primary"
+ @click="handleQuery">鏌ヨ</el-button>
+ <el-button @click="handleReset">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ <div>
+ <el-button type="success"
+ @click="handleExport">瀵煎嚭鎶ヨ〃</el-button>
+ </div>
+ </div>
+ <!-- 缁熻姒傝鍗$墖 -->
+ <div class="statistics-overview">
+ <h2 class="section-header">
+ <el-icon class="header-icon">
+ <DataLine />
+ </el-icon>
+ 鑳借�楁垚鏈瑙�
+ </h2>
+ <el-row :gutter="20">
+ <el-col :span="6">
+ <div class="overview-card blue-card">
+ <div class="overview-icon blue-icon">
+ <el-icon>
+ <Money />
+ </el-icon>
+ </div>
+ <div class="overview-info">
+ <div class="overview-label">鎬昏兘鑰楁垚鏈�</div>
+ <div class="overview-value">楼{{ overview.totalCost }}</div>
+ </div>
+ </div>
+ </el-col>
+ <el-col :span="6">
+ <div class="overview-card green-card">
+ <div class="overview-icon green-icon">
+ <el-icon>
+ <DataLine />
+ </el-icon>
+ </div>
+ <div class="overview-info">
+ <div class="overview-label">鐢熶骇鑳借�楁垚鏈�</div>
+ <div class="overview-value">楼{{ overview.productionCost }}</div>
+ </div>
+ </div>
+ </el-col>
+ <el-col :span="6">
+ <div class="overview-card purple-card">
+ <div class="overview-icon purple-icon">
+ <el-icon>
+ <TrendCharts />
+ </el-icon>
+ </div>
+ <div class="overview-info">
+ <div class="overview-label">鍔炲叕鑳借�楁垚鏈�</div>
+ <div class="overview-value">楼{{ overview.officeCost }}</div>
+ </div>
+ </div>
+ </el-col>
+ <el-col :span="6">
+ <div class="overview-card gray-card">
+ <div class="overview-icon gray-icon">
+ <el-icon>
+ <Histogram />
+ </el-icon>
+ </div>
+ <div class="overview-info">
+ <div class="overview-label">骞冲潎鑳借�楁垚鏈�</div>
+ <div class="overview-value">楼{{ overview.avgCost }} <span class="unit">/{{ statisticsType === 'day' ? '鏃�' : '鏈�' }}</span></div>
+ </div>
+ </div>
+ </el-col>
+ </el-row>
+ </div>
+ <!-- 鍥捐〃鍖哄煙 -->
+ <div class="charts-container">
+ <h2 class="section-header">
+ <el-icon class="header-icon">
+ <Histogram />
+ </el-icon>
+ 鑳借�楁垚鏈垎鏋�
+ </h2>
+ <el-row :gutter="20">
+ <el-col :span="12">
+ <div class="chart-card">
+ <div class="chart-title">鑳借�楁垚鏈秼鍔�</div>
+ <div ref="costChart"
+ class="chart-content"></div>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="chart-card">
+ <div class="chart-title">鑳借�楃被鍨嬫垚鏈崰姣�</div>
+ <div ref="typeChart"
+ class="chart-content"></div>
+ </div>
+ </el-col>
+ </el-row>
+ <el-row :gutter="20"
+ style="margin-top: 20px;">
+ <el-col :span="12">
+ <div class="chart-card">
+ <div class="chart-title">鑳借�楃敤閫旀垚鏈崰姣�</div>
+ <div ref="purposeChart"
+ class="chart-content"></div>
+ </div>
+ </el-col>
+ <el-col :span="12">
+ <div class="chart-card">
+ <div class="chart-title">鑳借�楀崟浠峰姣�</div>
+ <div ref="priceChart"
+ class="chart-content"></div>
+ </div>
+ </el-col>
+ </el-row>
+ </div>
+ <!-- 鏁版嵁琛ㄦ牸 -->
+ <div class="table-section">
+ <h2 class="section-header">
+ <el-icon class="header-icon">
+ <List />
+ </el-icon>
+ 璇︾粏鏁版嵁
+ </h2>
+ <el-table :data="tableData"
+ v-loading="tableLoading"
+ border>
+ <el-table-column type="index"
+ label="搴忓彿"
+ width="60"
+ align="center" />
+ <el-table-column prop="timePeriod"
+ :label="timeColumnLabel"
+ align="center" />
+ <el-table-column prop="energyType"
+ label="鑳借�楃被鍨�"
+ width="100"
+ align="center">
+ <template #default="scope">
+ <el-tag :type="getEnergyTypeType(scope.row.energyType)">
+ {{ scope.row.energyType }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="energyPurpose"
+ label="鑳借�楃敤閫�"
+ width="100"
+ align="center">
+ <template #default="scope">
+ <el-tag :type="scope.row.energyPurpose === '鐢熶骇' ? 'primary' : 'info'">
+ {{ scope.row.energyPurpose }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="consumption"
+ label="鐢ㄩ噺"
+ align="right">
+ <template #default="scope">
+ <span class="consumption-value">{{ scope.row.consumption }}</span>
+ <span class="consumption-unit">{{ scope.row.unit }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="price"
+ label="鍗曚环(鍏�)"
+ align="right">
+ <template #default="scope">
+ <span class="price-value">{{ scope.row.price }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="cost"
+ label="鎴愭湰(鍏�)"
+ align="right"
+ fixed="right">
+ <template #default="scope">
+ <span class="cost-value">楼{{ scope.row.cost }}</span>
+ </template>
+ </el-table-column>
+ </el-table>
+ </div>
+ <!-- 鍒嗛〉 -->
+ <div class="pagination-container">
+ <el-pagination v-model:current-page="page.current"
+ v-model:page-size="page.size"
+ :page-sizes="[10, 20, 50, 100]"
+ :total="page.total"
+ layout="total, sizes, prev, pager, next, jumper"
+ @size-change="handleSizeChange"
+ @current-change="handleCurrentChange" />
+ </div>
+ </div>
+</template>
+
+<script setup>
+ import { ref, reactive, onMounted, computed, nextTick } from "vue";
+ import { ElMessage } from "element-plus";
+ import {
+ Money,
+ DataLine,
+ TrendCharts,
+ Histogram,
+ List,
+ } from "@element-plus/icons-vue";
+ import * as echarts from "echarts";
+ import { energyCostStatistics } from "@/api/costAccounting/energyCosts";
+
+ // 缁熻缁村害锛歞ay-鎸夋棩锛宮onth-鎸夋湀
+ const statisticsType = ref("day");
+
+ // 鎼滅储琛ㄥ崟
+ const searchForm = reactive({
+ energyType: "",
+ energyPurpose: "",
+ dateRange: (() => {
+ // 榛樿鏈�杩�7澶�
+ const end = new Date();
+ const start = new Date();
+ start.setDate(start.getDate() - 6);
+ return [start.toISOString().split("T")[0], end.toISOString().split("T")[0]];
+ })(),
+ monthRange: (() => {
+ // 榛樿鏈�杩�3涓湀
+ const end = new Date();
+ const start = new Date();
+ start.setMonth(start.getMonth() - 2);
+ return [start.toISOString().slice(0, 7), end.toISOString().slice(0, 7)];
+ })(),
+ });
+
+ // 鏃堕棿鍒楁爣绛�
+ const timeColumnLabel = computed(() => {
+ return statisticsType.value === "day" ? "鏃ユ湡" : "鏈堜唤";
+ });
+
+ // 缁熻姒傝
+ const overview = reactive({
+ totalCost: "0.00",
+ productionCost: "0.00",
+ officeCost: "0.00",
+ avgCost: "0.00",
+ });
+
+ // 琛ㄦ牸鏁版嵁
+ const tableData = ref([]);
+ const tableLoading = ref(false);
+
+ // 鍒嗛〉
+ const page = reactive({
+ current: 1,
+ size: 10,
+ total: 0,
+ });
+
+ // 鍥捐〃寮曠敤
+ const costChart = ref(null);
+ const typeChart = ref(null);
+ const purposeChart = ref(null);
+ const priceChart = ref(null);
+
+ // 鍥捐〃瀹炰緥
+ let costChartInstance = null;
+ let typeChartInstance = null;
+ let purposeChartInstance = null;
+ let priceChartInstance = null;
+
+ // 鑾峰彇鑳借�楃被鍨嬫爣绛剧被鍨�
+ const getEnergyTypeType = type => {
+ const typeMap = {
+ 姘�: "primary",
+ 鐢�: "warning",
+ 姘�: "success",
+ };
+ return typeMap[type] || "info";
+ };
+
+ // 鍒濆鍖栧浘琛�
+ const initCharts = () => {
+ nextTick(() => {
+ // 鑳借�楁垚鏈秼鍔垮浘
+ if (costChart.value) {
+ costChartInstance = echarts.init(costChart.value);
+ updateCostChart();
+ }
+ // 鑳借�楃被鍨嬫垚鏈崰姣斿浘
+ if (typeChart.value) {
+ typeChartInstance = echarts.init(typeChart.value);
+ updateTypeChart();
+ }
+ // 鑳借�楃敤閫旀垚鏈崰姣斿浘
+ if (purposeChart.value) {
+ purposeChartInstance = echarts.init(purposeChart.value);
+ updatePurposeChart();
+ }
+ // 鑳借�楀崟浠峰姣斿浘
+ if (priceChart.value) {
+ priceChartInstance = echarts.init(priceChart.value);
+ updatePriceChart();
+ }
+ });
+ };
+
+ // 鏇存柊鑳借�楁垚鏈秼鍔垮浘
+ const updateCostChart = () => {
+ const data = tableData.value;
+ const option = {
+ tooltip: {
+ trigger: "axis",
+ axisPointer: { type: "shadow" },
+ backgroundColor: "rgba(255, 255, 255, 0.95)",
+ borderColor: "#409EFF",
+ borderWidth: 1,
+ textStyle: { color: "#303133" },
+ },
+ legend: {
+ data: ["鐢熶骇鑳借�楁垚鏈�", "鍔炲叕鑳借�楁垚鏈�"],
+ top: 0,
+ right: 10,
+ textStyle: { color: "#606266" },
+ },
+ grid: {
+ left: "3%",
+ right: "4%",
+ bottom: "10%",
+ top: "15%",
+ containLabel: true,
+ },
+ xAxis: {
+ type: "category",
+ data: data.map(item => item.timePeriod),
+ axisLabel: {
+ rotate: statisticsType.value === "day" ? 45 : 0,
+ color: "#606266",
+ },
+ axisLine: { lineStyle: { color: "#ebeef5" } },
+ splitLine: { show: false },
+ },
+ yAxis: {
+ type: "value",
+ name: "鎴愭湰(鍏�)",
+ nameTextStyle: { color: "#606266" },
+ axisLabel: { color: "#606266" },
+ axisLine: { show: false },
+ splitLine: { lineStyle: { color: "#f0f2f5" } },
+ },
+ series: [
+ {
+ name: "鐢熶骇鑳借�楁垚鏈�",
+ type: "bar",
+ data: data.map(item => (item.energyPurpose === "鐢熶骇" ? item.cost : 0)),
+ itemStyle: {
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ { offset: 0, color: "#409EFF" },
+ { offset: 1, color: "#66b1ff" },
+ ]),
+ borderRadius: [4, 4, 0, 0],
+ },
+ animationDelay: function (idx) {
+ return idx * 100;
+ },
+ },
+ {
+ name: "鍔炲叕鑳借�楁垚鏈�",
+ type: "bar",
+ data: data.map(item => (item.energyPurpose === "鍔炲叕" ? item.cost : 0)),
+ itemStyle: {
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ { offset: 0, color: "#67C23A" },
+ { offset: 1, color: "#85ce61" },
+ ]),
+ borderRadius: [4, 4, 0, 0],
+ },
+ animationDelay: function (idx) {
+ return idx * 100 + 100;
+ },
+ },
+ ],
+ animationEasing: "elasticOut",
+ animationDelayUpdate: function (idx) {
+ return idx * 5;
+ },
+ };
+ costChartInstance.setOption(option);
+ };
+
+ // 鏇存柊鑳借�楃被鍨嬫垚鏈崰姣斿浘
+ const updateTypeChart = () => {
+ const data = tableData.value;
+ const typeCosts = {};
+
+ data.forEach(item => {
+ if (!typeCosts[item.energyType]) {
+ typeCosts[item.energyType] = 0;
+ }
+ typeCosts[item.energyType] += parseFloat(item.cost);
+ });
+
+ const chartData = Object.entries(typeCosts).map(([name, value]) => ({
+ name,
+ value: value.toFixed(2),
+ }));
+
+ const option = {
+ tooltip: {
+ trigger: "item",
+ formatter: "{a} <br/>{b}: 楼{c} ({d}%)",
+ backgroundColor: "rgba(255, 255, 255, 0.95)",
+ borderColor: "#409EFF",
+ borderWidth: 1,
+ textStyle: { color: "#303133" },
+ },
+ legend: {
+ orient: "horizontal",
+ bottom: 0,
+ textStyle: { color: "#606266" },
+ },
+ series: [
+ {
+ name: "鑳借�楃被鍨嬫垚鏈�",
+ type: "pie",
+ radius: ["40%", "70%"],
+ center: ["50%", "40%"],
+ avoidLabelOverlap: false,
+ itemStyle: {
+ borderRadius: 4,
+ borderColor: "#fff",
+ borderWidth: 2,
+ },
+ label: {
+ show: false,
+ position: "center",
+ },
+ emphasis: {
+ label: {
+ show: true,
+ fontSize: "18",
+ fontWeight: "bold",
+ color: "#303133",
+ },
+ itemStyle: {
+ shadowBlur: 10,
+ shadowOffsetX: 0,
+ shadowColor: "rgba(0, 0, 0, 0.3)",
+ },
+ },
+ labelLine: {
+ show: false,
+ },
+ data: chartData,
+ },
+ ],
+ color: ["#409EFF", "#67C23A", "#E6A23C"],
+ };
+ typeChartInstance.setOption(option);
+ };
+
+ // 鏇存柊鑳借�楃敤閫旀垚鏈崰姣斿浘
+ const updatePurposeChart = () => {
+ const data = tableData.value;
+ const purposeCosts = {
+ 鐢熶骇: 0,
+ 鍔炲叕: 0,
+ };
+
+ data.forEach(item => {
+ if (purposeCosts.hasOwnProperty(item.energyPurpose)) {
+ purposeCosts[item.energyPurpose] += parseFloat(item.cost);
+ }
+ });
+
+ const chartData = Object.entries(purposeCosts).map(([name, value]) => ({
+ name,
+ value: value.toFixed(2),
+ }));
+
+ const option = {
+ tooltip: {
+ trigger: "item",
+ formatter: "{a} <br/>{b}: 楼{c} ({d}%)",
+ backgroundColor: "rgba(255, 255, 255, 0.95)",
+ borderColor: "#409EFF",
+ borderWidth: 1,
+ textStyle: { color: "#303133" },
+ },
+ legend: {
+ orient: "horizontal",
+ bottom: 0,
+ textStyle: { color: "#606266" },
+ },
+ series: [
+ {
+ name: "鑳借�楃敤閫旀垚鏈�",
+ type: "pie",
+ radius: "60%",
+ center: ["50%", "40%"],
+ data: chartData,
+ emphasis: {
+ itemStyle: {
+ shadowBlur: 10,
+ shadowOffsetX: 0,
+ shadowColor: "rgba(0, 0, 0, 0.3)",
+ },
+ },
+ label: {
+ show: true,
+ formatter: "{b}: {d}%",
+ color: "#606266",
+ },
+ labelLine: {
+ show: true,
+ lineStyle: { color: "#dcdfe6" },
+ },
+ },
+ ],
+ color: ["#409EFF", "#67C23A"],
+ };
+ purposeChartInstance.setOption(option);
+ };
+
+ // 鏇存柊鑳借�楀崟浠峰姣斿浘
+ const updatePriceChart = () => {
+ const data = tableData.value;
+ const priceData = {};
+
+ data.forEach(item => {
+ if (!priceData[item.energyType]) {
+ priceData[item.energyType] = {
+ 鐢熶骇: 0,
+ 鍔炲叕: 0,
+ };
+ }
+ if (priceData[item.energyType].hasOwnProperty(item.energyPurpose)) {
+ priceData[item.energyType][item.energyPurpose] = parseFloat(item.price);
+ }
+ });
+
+ const energyTypes = Object.keys(priceData);
+ const productionPrices = energyTypes.map(type => priceData[type].鐢熶骇);
+ const officePrices = energyTypes.map(type => priceData[type].鍔炲叕);
+
+ const option = {
+ tooltip: {
+ trigger: "axis",
+ axisPointer: { type: "shadow" },
+ backgroundColor: "rgba(255, 255, 255, 0.95)",
+ borderColor: "#409EFF",
+ borderWidth: 1,
+ textStyle: { color: "#303133" },
+ },
+ legend: {
+ data: ["鐢熶骇鑳借�楀崟浠�", "鍔炲叕鑳借�楀崟浠�"],
+ top: 0,
+ right: 10,
+ textStyle: { color: "#606266" },
+ },
+ grid: {
+ left: "3%",
+ right: "4%",
+ bottom: "10%",
+ top: "15%",
+ containLabel: true,
+ },
+ xAxis: {
+ type: "category",
+ data: energyTypes,
+ axisLabel: { color: "#606266" },
+ axisLine: { lineStyle: { color: "#ebeef5" } },
+ splitLine: { show: false },
+ },
+ yAxis: {
+ type: "value",
+ name: "鍗曚环(鍏�)",
+ nameTextStyle: { color: "#606266" },
+ axisLabel: { color: "#606266" },
+ axisLine: { show: false },
+ splitLine: { lineStyle: { color: "#f0f2f5" } },
+ },
+ series: [
+ {
+ name: "鐢熶骇鑳借�楀崟浠�",
+ type: "bar",
+ data: productionPrices,
+ itemStyle: {
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ { offset: 0, color: "#409EFF" },
+ { offset: 1, color: "#66b1ff" },
+ ]),
+ borderRadius: [4, 4, 0, 0],
+ },
+ },
+ {
+ name: "鍔炲叕鑳借�楀崟浠�",
+ type: "bar",
+ data: officePrices,
+ itemStyle: {
+ color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
+ { offset: 0, color: "#67C23A" },
+ { offset: 1, color: "#85ce61" },
+ ]),
+ borderRadius: [4, 4, 0, 0],
+ },
+ },
+ ],
+ };
+ priceChartInstance.setOption(option);
+ };
+
+ // 缁熻缁村害鍒囨崲
+ const handleTypeChange = () => {
+ // 閲嶇疆鏃堕棿鑼冨洿
+ if (statisticsType.value === "day") {
+ const end = new Date();
+ const start = new Date();
+ start.setDate(start.getDate() - 6);
+ searchForm.dateRange = [
+ start.toISOString().split("T")[0],
+ end.toISOString().split("T")[0],
+ ];
+ } else {
+ const end = new Date();
+ const start = new Date();
+ start.setMonth(start.getMonth() - 2);
+ searchForm.monthRange = [
+ start.toISOString().slice(0, 7),
+ end.toISOString().slice(0, 7),
+ ];
+ }
+ page.current = 1;
+ handleQuery();
+ };
+
+ // 鏌ヨ
+ const handleQuery = () => {
+ tableLoading.value = true;
+
+ // 鏋勯�犺姹傚弬鏁�
+ const params = {
+ type: statisticsType.value,
+ energyType: searchForm.energyType || undefined,
+ energyPurpose: searchForm.energyPurpose || undefined,
+ };
+
+ if (statisticsType.value === "day") {
+ if (searchForm.dateRange && searchForm.dateRange.length === 2) {
+ params.startDate = searchForm.dateRange[0];
+ params.endDate = searchForm.dateRange[1];
+ }
+ } else {
+ if (searchForm.monthRange && searchForm.monthRange.length === 2) {
+ params.startDate = searchForm.monthRange[0] + "-01";
+ params.endDate = searchForm.monthRange[1] + "-01";
+ }
+ }
+
+ // 璋冪敤鎺ュ彛鑾峰彇鏁版嵁
+ energyCostStatistics(params)
+ .then(res => {
+ if (res.code === 200) {
+ tableData.value = res.data.records || [];
+ page.total = res.data.total || 0;
+
+ // 鏇存柊缁熻姒傝鏁版嵁
+ if (res.data.overview) {
+ overview.totalCost = res.data.overview.totalCost || "0.00";
+ overview.productionCost = res.data.overview.productionCost || "0.00";
+ overview.officeCost = res.data.overview.officeCost || "0.00";
+ overview.avgCost = res.data.overview.avgCost || "0.00";
+ }
+ } else {
+ ElMessage.error(res.message || "鑾峰彇鏁版嵁澶辫触");
+ tableData.value = [];
+ page.total = 0;
+ }
+ })
+ .catch(err => {
+ console.error("鑾峰彇鏁版嵁寮傚父锛�", err);
+ // 鐢熸垚鍋囨暟鎹�
+ generateMockData();
+ })
+ .finally(() => {
+ tableLoading.value = false;
+ updateCharts();
+ });
+ };
+
+ // 鐢熸垚鍋囨暟鎹�
+ const generateMockData = () => {
+ if (statisticsType.value === "day") {
+ // 鐢熸垚鏈�杩�7澶╃殑鍋囨暟鎹�
+ const mockData = [];
+ const today = new Date();
+
+ for (let i = 6; i >= 0; i--) {
+ const date = new Date(today);
+ date.setDate(date.getDate() - i);
+ const dateStr = date.toISOString().split("T")[0];
+
+ // 鐢熶骇鑳借�楁暟鎹�
+ mockData.push({
+ timePeriod: dateStr,
+ energyType: "鐢�",
+ energyPurpose: "鐢熶骇",
+ consumption: (Math.random() * 1000 + 500).toFixed(2),
+ unit: "kWh",
+ price: "0.85",
+ cost: (Math.random() * 850 + 425).toFixed(2),
+ });
+ mockData.push({
+ timePeriod: dateStr,
+ energyType: "姘�",
+ energyPurpose: "鐢熶骇",
+ consumption: (Math.random() * 500 + 200).toFixed(2),
+ unit: "m鲁",
+ price: "3.50",
+ cost: (Math.random() * 1750 + 700).toFixed(2),
+ });
+ mockData.push({
+ timePeriod: dateStr,
+ energyType: "姘�",
+ energyPurpose: "鐢熶骇",
+ consumption: (Math.random() * 300 + 100).toFixed(2),
+ unit: "m鲁",
+ price: "2.80",
+ cost: (Math.random() * 840 + 280).toFixed(2),
+ });
+
+ // 鍔炲叕鑳借�楁暟鎹�
+ mockData.push({
+ timePeriod: dateStr,
+ energyType: "鐢�",
+ energyPurpose: "鍔炲叕",
+ consumption: (Math.random() * 200 + 100).toFixed(2),
+ unit: "kWh",
+ price: "0.85",
+ cost: (Math.random() * 170 + 85).toFixed(2),
+ });
+ mockData.push({
+ timePeriod: dateStr,
+ energyType: "姘�",
+ energyPurpose: "鍔炲叕",
+ consumption: (Math.random() * 50 + 20).toFixed(2),
+ unit: "m鲁",
+ price: "3.50",
+ cost: (Math.random() * 175 + 70).toFixed(2),
+ });
+ }
+
+ tableData.value = mockData;
+ page.total = mockData.length;
+ } else {
+ // 鐢熸垚鏈�杩�3涓湀鐨勫亣鏁版嵁
+ const mockData = [];
+ const today = new Date();
+
+ for (let i = 2; i >= 0; i--) {
+ const date = new Date(today);
+ date.setMonth(date.getMonth() - i);
+ const monthStr = date.toISOString().slice(0, 7);
+
+ // 鐢熶骇鑳借�楁暟鎹�
+ mockData.push({
+ timePeriod: monthStr,
+ energyType: "鐢�",
+ energyPurpose: "鐢熶骇",
+ consumption: (Math.random() * 30000 + 15000).toFixed(2),
+ unit: "kWh",
+ price: "0.85",
+ cost: (Math.random() * 25500 + 12750).toFixed(2),
+ });
+ mockData.push({
+ timePeriod: monthStr,
+ energyType: "姘�",
+ energyPurpose: "鐢熶骇",
+ consumption: (Math.random() * 15000 + 6000).toFixed(2),
+ unit: "m鲁",
+ price: "3.50",
+ cost: (Math.random() * 52500 + 21000).toFixed(2),
+ });
+ mockData.push({
+ timePeriod: monthStr,
+ energyType: "姘�",
+ energyPurpose: "鐢熶骇",
+ consumption: (Math.random() * 9000 + 3000).toFixed(2),
+ unit: "m鲁",
+ price: "2.80",
+ cost: (Math.random() * 25200 + 8400).toFixed(2),
+ });
+
+ // 鍔炲叕鑳借�楁暟鎹�
+ mockData.push({
+ timePeriod: monthStr,
+ energyType: "鐢�",
+ energyPurpose: "鍔炲叕",
+ consumption: (Math.random() * 6000 + 3000).toFixed(2),
+ unit: "kWh",
+ price: "0.85",
+ cost: (Math.random() * 5100 + 2550).toFixed(2),
+ });
+ mockData.push({
+ timePeriod: monthStr,
+ energyType: "姘�",
+ energyPurpose: "鍔炲叕",
+ consumption: (Math.random() * 1500 + 600).toFixed(2),
+ unit: "m鲁",
+ price: "3.50",
+ cost: (Math.random() * 5250 + 2100).toFixed(2),
+ });
+ }
+
+ tableData.value = mockData;
+ page.total = mockData.length;
+ }
+
+ // 鏇存柊缁熻姒傝鏁版嵁
+ calculateOverview();
+ };
+
+ // 璁$畻缁熻姒傝鏁版嵁
+ const calculateOverview = () => {
+ let totalCost = 0;
+ let productionCost = 0;
+ let officeCost = 0;
+
+ tableData.value.forEach(item => {
+ const cost = parseFloat(item.cost);
+ totalCost += cost;
+ if (item.energyPurpose === "鐢熶骇") {
+ productionCost += cost;
+ } else if (item.energyPurpose === "鍔炲叕") {
+ officeCost += cost;
+ }
+ });
+
+ overview.totalCost = totalCost.toFixed(2);
+ overview.productionCost = productionCost.toFixed(2);
+ overview.officeCost = officeCost.toFixed(2);
+ overview.avgCost = (totalCost / tableData.value.length).toFixed(2);
+ };
+
+ // 鏇存柊鎵�鏈夊浘琛�
+ const updateCharts = () => {
+ nextTick(() => {
+ if (costChartInstance) updateCostChart();
+ if (typeChartInstance) updateTypeChart();
+ if (purposeChartInstance) updatePurposeChart();
+ if (priceChartInstance) updatePriceChart();
+ });
+ };
+
+ // 閲嶇疆
+ const handleReset = () => {
+ searchForm.energyType = "";
+ searchForm.energyPurpose = "";
+ if (statisticsType.value === "day") {
+ const end = new Date();
+ const start = new Date();
+ start.setDate(start.getDate() - 6);
+ searchForm.dateRange = [
+ start.toISOString().split("T")[0],
+ end.toISOString().split("T")[0],
+ ];
+ } else {
+ const end = new Date();
+ const start = new Date();
+ start.setMonth(start.getMonth() - 2);
+ searchForm.monthRange = [
+ start.toISOString().slice(0, 7),
+ end.toISOString().slice(0, 7),
+ ];
+ }
+ page.current = 1;
+ handleQuery();
+ };
+
+ // 瀵煎嚭
+ const handleExport = () => {
+ ElMessage.success("鎶ヨ〃瀵煎嚭鎴愬姛");
+ };
+
+ // 鍒嗛〉澶у皬鍙樺寲
+ const handleSizeChange = val => {
+ page.size = val;
+ };
+
+ // 椤电爜鍙樺寲
+ const handleCurrentChange = val => {
+ page.current = val;
+ };
+
+ // 绐楀彛澶у皬鍙樺寲鏃堕噸鏂版覆鏌撳浘琛�
+ const handleResize = () => {
+ costChartInstance && costChartInstance.resize();
+ typeChartInstance && typeChartInstance.resize();
+ purposeChartInstance && purposeChartInstance.resize();
+ priceChartInstance && priceChartInstance.resize();
+ };
+
+ onMounted(() => {
+ handleQuery();
+ initCharts();
+ window.addEventListener("resize", handleResize);
+ });
+</script>
+
+<style scoped lang="scss">
+ .app-container {
+ padding: 20px;
+ }
+
+ .search_form {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20px;
+ padding: 15px;
+ background-color: #f5f7fa;
+ border-radius: 8px;
+ }
+
+ .statistics-overview {
+ margin-bottom: 30px;
+ }
+
+ .charts-container {
+ margin-bottom: 30px;
+ }
+
+ .table-section {
+ margin-bottom: 20px;
+ }
+
+ .section-header {
+ display: flex;
+ align-items: center;
+ font-size: 18px;
+ font-weight: bold;
+ color: #303133;
+ margin-bottom: 15px;
+ padding-left: 10px;
+ border-left: 3px solid #409eff;
+
+ .header-icon {
+ margin-right: 8px;
+ color: #409eff;
+ }
+ }
+
+ .overview-card {
+ display: flex;
+ align-items: center;
+ padding: 20px;
+ border-radius: 4px;
+ background: #fff;
+ border: 1px solid #ebeef5;
+
+ &.blue-card {
+ background-color: #ecf5ff;
+ }
+
+ &.green-card {
+ background-color: #f0f9eb;
+ }
+
+ &.purple-card {
+ background-color: #f3f0ff;
+ }
+
+ &.gray-card {
+ background-color: #f5f7fa;
+ }
+
+ .overview-icon {
+ width: 40px;
+ height: 40px;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ border-radius: 50%;
+ margin-right: 15px;
+
+ &.blue-icon {
+ background-color: #409eff;
+ color: #fff;
+ }
+
+ &.green-icon {
+ background-color: #67c23a;
+ color: #fff;
+ }
+
+ &.purple-icon {
+ background-color: #909399;
+ color: #fff;
+ }
+
+ &.gray-icon {
+ background-color: #909399;
+ color: #fff;
+ }
+
+ .el-icon {
+ font-size: 20px;
+ }
+ }
+
+ .overview-info {
+ flex: 1;
+
+ .overview-label {
+ font-size: 14px;
+ color: #606266;
+ margin-bottom: 5px;
+ }
+
+ .overview-value {
+ font-size: 20px;
+ font-weight: bold;
+ color: #303133;
+
+ .unit {
+ font-size: 12px;
+ font-weight: normal;
+ color: #909399;
+ }
+ }
+ }
+ }
+
+ .chart-card {
+ background: #fff;
+ border-radius: 4px;
+ border: 1px solid #ebeef5;
+ padding: 20px;
+
+ .chart-title {
+ font-size: 14px;
+ font-weight: bold;
+ color: #303133;
+ margin-bottom: 15px;
+ padding-bottom: 10px;
+ border-bottom: 1px solid #ebeef5;
+ }
+
+ .chart-content {
+ height: 300px;
+ }
+ }
+
+ .consumption-value {
+ font-weight: bold;
+ color: #409eff;
+ }
+
+ .consumption-unit {
+ font-size: 12px;
+ color: #909399;
+ margin-left: 2px;
+ }
+
+ .price-value {
+ font-weight: bold;
+ color: #67c23a;
+ }
+
+ .cost-value {
+ font-weight: bold;
+ color: #f56c6c;
+ }
+
+ .pagination-container {
+ display: flex;
+ justify-content: flex-end;
+ }
+</style>
\ No newline at end of file
diff --git a/src/views/energyManagement/energyConsumptionStatistical/index.vue b/src/views/energyManagement/energyConsumptionStatistical/index.vue
index 9363511..c58d850 100644
--- a/src/views/energyManagement/energyConsumptionStatistical/index.vue
+++ b/src/views/energyManagement/energyConsumptionStatistical/index.vue
@@ -267,15 +267,28 @@
ArrowDown,
} from "@element-plus/icons-vue";
import * as echarts from "echarts";
+ import { energyConsumptionDetailStatistics } from "@/api/energyManagement/energyType";
// 缁熻缁村害锛歞ay-鎸夋棩锛宮onth-鎸夋湀锛寉ear-鎸夊勾
const statisticsType = ref("day");
// 鎼滅储琛ㄥ崟
const searchForm = reactive({
- energyType: "",
- dateRange: [],
- monthRange: [],
+ energyType: "鍏ㄩ儴",
+ dateRange: (() => {
+ // 榛樿鏈�杩�7澶�
+ const end = new Date();
+ const start = new Date();
+ start.setDate(start.getDate() - 6);
+ return [start.toISOString().split("T")[0], end.toISOString().split("T")[0]];
+ })(),
+ monthRange: (() => {
+ // 榛樿鏈�杩�3涓湀
+ const end = new Date();
+ const start = new Date();
+ start.setMonth(start.getMonth() - 2);
+ return [start.toISOString().slice(0, 7), end.toISOString().slice(0, 7)];
+ })(),
year: new Date().getFullYear(),
});
@@ -651,13 +664,73 @@
// 鏌ヨ
const handleQuery = () => {
tableLoading.value = true;
- setTimeout(() => {
- const data = generateMockData();
- tableData.value = data;
- page.total = data.length;
- tableLoading.value = false;
- updateCharts();
- }, 300);
+ const params = {
+ type: "",
+ };
+
+ // 鏋勯�犺姹傚弬鏁�
+ if (searchForm.energyType != "鍏ㄩ儴") {
+ params.type = searchForm.energyType;
+ }
+
+ if (statisticsType.value === "day") {
+ if (searchForm.dateRange && searchForm.dateRange.length === 2) {
+ params.startDate = searchForm.dateRange[0];
+ params.endDate = searchForm.dateRange[1];
+ // 璁$畻澶╂暟
+ const start = new Date(searchForm.dateRange[0]);
+ const end = new Date(searchForm.dateRange[1]);
+ params.days = Math.ceil((end - start) / (1000 * 60 * 60 * 24)) + 1;
+ }
+ } else if (statisticsType.value === "month") {
+ if (searchForm.monthRange && searchForm.monthRange.length === 2) {
+ params.startDate = searchForm.monthRange[0] + "-01";
+ params.endDate = searchForm.monthRange[1] + "-01";
+ // 璁$畻鏈堟暟
+ const start = new Date(searchForm.monthRange[0] + "-01");
+ const end = new Date(searchForm.monthRange[1] + "-01");
+ params.days =
+ (end.getFullYear() - start.getFullYear()) * 12 +
+ (end.getMonth() - start.getMonth()) +
+ 1;
+ }
+ } else if (statisticsType.value === "year") {
+ params.startDate = searchForm.year + "-01-01";
+ params.endDate = searchForm.year + "-12-31";
+ params.days = 365;
+ }
+
+ // 璋冪敤鎺ュ彛鑾峰彇鏁版嵁
+ energyConsumptionDetailStatistics(params)
+ .then(res => {
+ if (res.code === 200) {
+ const data = res.data;
+
+ // 鏇存柊缁熻姒傝鏁版嵁
+ overview.totalConsumption = data.totalEnergyConsumption || "0";
+ overview.totalAmount = data.totalEnergyCost || "0";
+ overview.avgConsumption = data.averageConsumption || "0";
+ overview.compareRate = data.changeVite || 0;
+
+ // 澶勭悊琛ㄦ牸鏁版嵁
+ tableData.value = data.energyCostDtos || [];
+ page.total = tableData.value.length || 0;
+ } else {
+ ElMessage.error(res.message || "鑾峰彇鏁版嵁澶辫触");
+ tableData.value = [];
+ page.total = 0;
+ }
+ })
+ .catch(err => {
+ console.error("鑾峰彇鏁版嵁寮傚父锛�", err);
+ ElMessage.error("绯荤粺寮傚父锛岃幏鍙栨暟鎹け璐�");
+ tableData.value = [];
+ page.total = 0;
+ })
+ .finally(() => {
+ tableLoading.value = false;
+ updateCharts();
+ });
};
// 鏇存柊鎵�鏈夊浘琛�
@@ -672,10 +745,28 @@
// 閲嶇疆
const handleReset = () => {
- searchForm.energyType = "";
- searchForm.dateRange = [];
- searchForm.monthRange = [];
+ searchForm.energyType = "鍏ㄩ儴";
+ // 閲嶇疆涓洪粯璁ゆ椂闂磋寖鍥�
+ const end = new Date();
+ const start = new Date();
+
+ // 榛樿鏈�杩�7澶�
+ start.setDate(start.getDate() - 6);
+ searchForm.dateRange = [
+ start.toISOString().split("T")[0],
+ end.toISOString().split("T")[0],
+ ];
+
+ // 榛樿鏈�杩�3涓湀
+ start.setMonth(start.getMonth() - 2);
+ searchForm.monthRange = [
+ start.toISOString().slice(0, 7),
+ end.toISOString().slice(0, 7),
+ ];
+
+ // 榛樿褰撳墠骞翠唤
searchForm.year = new Date().getFullYear();
+
page.current = 1;
handleQuery();
};
diff --git a/src/views/reportAnalysis/unitEnergyConsumption/index.vue b/src/views/reportAnalysis/unitEnergyConsumption/index.vue
new file mode 100644
index 0000000..9399bf6
--- /dev/null
+++ b/src/views/reportAnalysis/unitEnergyConsumption/index.vue
@@ -0,0 +1,405 @@
+<template>
+ <div class="app-container">
+ <!-- 鎼滅储鍖哄煙 -->
+ <div class="search_form">
+ <el-form :model="searchForm"
+ :inline="true">
+ <el-form-item label="骞翠唤:">
+ <el-select v-model="searchForm.year"
+ placeholder="璇烽�夋嫨骞翠唤"
+ style="width: 120px;"
+ @change="handleQuery">
+ <el-option v-for="year in years"
+ :key="year"
+ :label="year + '骞�'"
+ :value="year" />
+ </el-select>
+ </el-form-item>
+ <el-form-item label="鑳借�楃被鍨�:">
+ <el-select v-model="searchForm.energyType"
+ placeholder="鍏ㄩ儴"
+ clearable
+ style="width: 140px;"
+ @change="handleQuery">
+ <el-option label="鍏ㄩ儴"
+ value="鍏ㄩ儴" />
+ <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="handleQuery">鏌ヨ</el-button>
+ <el-button @click="handleReset">閲嶇疆</el-button>
+ </el-form-item>
+ </el-form>
+ <div>
+ <el-button type="success"
+ @click="handleExport">瀵煎嚭鎶ヨ〃</el-button>
+ </div>
+ </div>
+ <!-- 鍥捐〃鍖哄煙 -->
+ <div class="chart-section">
+ <h2 class="section-header">
+ <el-icon class="header-icon">
+ <TrendCharts />
+ </el-icon>
+ 鑳借�楀崟鑰楄秼鍔�
+ </h2>
+ <div class="chart-card">
+ <div ref="consumptionChart"
+ class="chart-content"></div>
+ </div>
+ </div>
+ <!-- 鏁版嵁琛ㄦ牸 -->
+ <div class="table-section">
+ <h2 class="section-header">
+ <el-icon class="header-icon">
+ <List />
+ </el-icon>
+ 鑳借�楀崟鑰楁暟鎹�
+ </h2>
+ <el-table :data="tableData"
+ v-loading="tableLoading"
+ border>
+ <el-table-column prop="energyType"
+ label="鑳借��"
+ width="100"
+ align="center">
+ <template #default="scope">
+ <el-tag :type="getEnergyTypeType(scope.row.energyType)">
+ {{ scope.row.energyType }}
+ </el-tag>
+ </template>
+ </el-table-column>
+ <el-table-column prop="unit"
+ label="鍗曚綅"
+ width="120"
+ align="center" />
+ <el-table-column label="鏈堝害鏁版嵁">
+ <el-table-column prop="monthlyUnitConsumption"
+ label="鏈堝害绱鍗曡��"
+ align="right">
+ <template #default="scope">
+ <span class="data-value">{{ scope.row.monthlyUnitConsumption }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="monthlyConsumption"
+ label="鏈堝害绱鐢ㄩ噺/鏈堝害绱浜ч噺"
+ align="right">
+ <template #default="scope">
+ <span class="data-value">{{ scope.row.monthlyConsumption }}/{{ scope.row.monthlyProduction }}</span>
+ </template>
+ </el-table-column>
+ </el-table-column>
+ <el-table-column label="骞村害鏁版嵁">
+ <el-table-column prop="annualUnitConsumption"
+ label="骞村害绱鍗曡��"
+ align="right">
+ <template #default="scope">
+ <span class="data-value">{{ scope.row.annualUnitConsumption }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column prop="annualConsumption"
+ label="骞村害绱鐢ㄩ噺/骞村害绱浜ч噺"
+ align="right">
+ <template #default="scope">
+ <span class="data-value">{{ scope.row.annualConsumption }}/{{ scope.row.annualProduction }}</span>
+ </template>
+ </el-table-column>
+ </el-table-column>
+ </el-table>
+ </div>
+ </div>
+</template>
+
+<script setup>
+ import { ref, reactive, onMounted, nextTick } from "vue";
+ import { ElMessage } from "element-plus";
+ import { TrendCharts, List } from "@element-plus/icons-vue";
+ import * as echarts from "echarts";
+
+ // 鎼滅储琛ㄥ崟
+ const searchForm = reactive({
+ year: new Date().getFullYear(),
+ energyType: "",
+ });
+
+ // 鐢熸垚骞翠唤閫夐」
+ const years = [];
+ const currentYear = new Date().getFullYear();
+ for (let i = currentYear - 5; i <= currentYear; i++) {
+ years.push(i);
+ }
+
+ // 琛ㄦ牸鏁版嵁
+ const tableData = ref([]);
+ const tableLoading = ref(false);
+
+ // 鍥捐〃寮曠敤
+ const consumptionChart = ref(null);
+ let consumptionChartInstance = null;
+
+ // 鑾峰彇鑳借�楃被鍨嬫爣绛剧被鍨�
+ const getEnergyTypeType = type => {
+ const typeMap = {
+ 姘�: "primary",
+ 鐢�: "warning",
+ 钂告苯: "success",
+ };
+ return typeMap[type] || "info";
+ };
+
+ // 鍒濆鍖栧浘琛�
+ const initChart = () => {
+ nextTick(() => {
+ if (consumptionChart.value) {
+ consumptionChartInstance = echarts.init(consumptionChart.value);
+ updateChart();
+ }
+ });
+ };
+
+ // 鏇存柊鍥捐〃
+ const updateChart = () => {
+ const data = tableData.value;
+ const months = [
+ "1鏈�",
+ "2鏈�",
+ "3鏈�",
+ "4鏈�",
+ "5鏈�",
+ "6鏈�",
+ "7鏈�",
+ "8鏈�",
+ "9鏈�",
+ "10鏈�",
+ "11鏈�",
+ "12鏈�",
+ ];
+
+ // 鍑嗗鍥捐〃鏁版嵁
+ const series = [];
+ const energyTypes = ["姘�", "鐢�", "钂告苯"];
+
+ energyTypes.forEach(type => {
+ const typeData = data.find(item => item.energyType === type);
+ if (typeData && typeData.monthlyData) {
+ series.push({
+ name: type,
+ type: "line",
+ data: typeData.monthlyData.map(item => item.unitConsumption),
+ smooth: true,
+ symbol: "circle",
+ symbolSize: 8,
+ lineStyle: {
+ width: 3,
+ },
+ itemStyle: {
+ color:
+ getEnergyTypeType(type) === "primary"
+ ? "#409EFF"
+ : getEnergyTypeType(type) === "warning"
+ ? "#E6A23C"
+ : "#67C23A",
+ },
+ });
+ }
+ });
+
+ const option = {
+ tooltip: {
+ trigger: "axis",
+ backgroundColor: "rgba(255, 255, 255, 0.95)",
+ borderColor: "#409EFF",
+ borderWidth: 1,
+ textStyle: { color: "#303133" },
+ },
+ legend: {
+ data: energyTypes,
+ top: 0,
+ right: 10,
+ textStyle: { color: "#606266" },
+ },
+ grid: {
+ left: "3%",
+ right: "4%",
+ bottom: "10%",
+ top: "15%",
+ containLabel: true,
+ },
+ xAxis: {
+ type: "category",
+ data: months,
+ axisLabel: { color: "#606266" },
+ axisLine: { lineStyle: { color: "#ebeef5" } },
+ splitLine: { show: false },
+ },
+ yAxis: {
+ type: "value",
+ name: "鍗曡��",
+ nameTextStyle: { color: "#606266" },
+ axisLabel: { color: "#606266" },
+ axisLine: { show: false },
+ splitLine: { lineStyle: { color: "#f0f2f5" } },
+ },
+ series: series,
+ };
+
+ consumptionChartInstance.setOption(option);
+ };
+
+ // 鏌ヨ
+ const handleQuery = () => {
+ tableLoading.value = true;
+
+ // 妯℃嫙鎺ュ彛璋冪敤
+ setTimeout(() => {
+ generateMockData();
+ tableLoading.value = false;
+ updateChart();
+ }, 500);
+ };
+
+ // 閲嶇疆
+ const handleReset = () => {
+ searchForm.year = new Date().getFullYear();
+ searchForm.energyType = "";
+ handleQuery();
+ };
+
+ // 瀵煎嚭
+ const handleExport = () => {
+ ElMessage.success("鎶ヨ〃瀵煎嚭鎴愬姛");
+ };
+
+ // 鐢熸垚鍋囨暟鎹�
+ const generateMockData = () => {
+ const energyTypes = [
+ {
+ energyType: "姘�",
+ unit: "鍚�/绔嬫柟绫�",
+ monthlyUnitConsumption: (Math.random() * 0.5 + 0.8).toFixed(4),
+ monthlyConsumption: Math.floor(Math.random() * 5000 + 10000),
+ monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
+ annualUnitConsumption: (Math.random() * 0.3 + 0.9).toFixed(4),
+ annualConsumption: Math.floor(Math.random() * 60000 + 120000),
+ annualProduction: Math.floor(Math.random() * 120000 + 240000),
+ monthlyData: generateMonthlyData(0.8, 1.3),
+ },
+ {
+ energyType: "鐢�",
+ unit: "搴�/绔嬫柟绫�",
+ monthlyUnitConsumption: (Math.random() * 2 + 5).toFixed(4),
+ monthlyConsumption: Math.floor(Math.random() * 50000 + 100000),
+ monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
+ annualUnitConsumption: (Math.random() * 1.5 + 5.5).toFixed(4),
+ annualConsumption: Math.floor(Math.random() * 600000 + 1200000),
+ annualProduction: Math.floor(Math.random() * 120000 + 240000),
+ monthlyData: generateMonthlyData(5, 7),
+ },
+ {
+ energyType: "钂告苯",
+ unit: "鍚�/绔嬫柟绫�",
+ monthlyUnitConsumption: (Math.random() * 0.3 + 0.5).toFixed(4),
+ monthlyConsumption: Math.floor(Math.random() * 3000 + 6000),
+ monthlyProduction: Math.floor(Math.random() * 10000 + 20000),
+ annualUnitConsumption: (Math.random() * 0.2 + 0.55).toFixed(4),
+ annualConsumption: Math.floor(Math.random() * 36000 + 72000),
+ annualProduction: Math.floor(Math.random() * 120000 + 240000),
+ monthlyData: generateMonthlyData(0.5, 0.8),
+ },
+ ];
+
+ if (searchForm.energyType && searchForm.energyType !== "鍏ㄩ儴") {
+ tableData.value = energyTypes.filter(
+ item => item.energyType === searchForm.energyType
+ );
+ } else {
+ tableData.value = energyTypes;
+ }
+ };
+
+ // 鐢熸垚鏈堝害鏁版嵁
+ const generateMonthlyData = (min, max) => {
+ const data = [];
+ for (let i = 1; i <= 12; i++) {
+ data.push({
+ month: i,
+ unitConsumption: (Math.random() * (max - min) + min).toFixed(4),
+ });
+ }
+ return data;
+ };
+
+ // 绐楀彛澶у皬鍙樺寲鏃堕噸鏂版覆鏌撳浘琛�
+ const handleResize = () => {
+ consumptionChartInstance && consumptionChartInstance.resize();
+ };
+
+ onMounted(() => {
+ handleQuery();
+ initChart();
+ window.addEventListener("resize", handleResize);
+ });
+</script>
+
+<style scoped lang="scss">
+ .app-container {
+ padding: 20px;
+ }
+
+ .search_form {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 20px;
+ padding: 15px;
+ background-color: #f5f7fa;
+ border-radius: 8px;
+ }
+
+ .chart-section {
+ margin-bottom: 30px;
+ }
+
+ .table-section {
+ margin-bottom: 20px;
+ }
+
+ .section-header {
+ display: flex;
+ align-items: center;
+ font-size: 18px;
+ font-weight: bold;
+ color: #303133;
+ margin-bottom: 15px;
+ padding-left: 10px;
+ border-left: 3px solid #409eff;
+
+ .header-icon {
+ margin-right: 8px;
+ color: #409eff;
+ }
+ }
+
+ .chart-card {
+ background: #fff;
+ border-radius: 4px;
+ border: 1px solid #ebeef5;
+ padding: 20px;
+
+ .chart-content {
+ height: 400px;
+ }
+ }
+
+ .data-value {
+ font-weight: bold;
+ color: #409eff;
+ }
+</style>
\ No newline at end of file
--
Gitblit v1.9.3