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