From 5067cad099f9e3ec0a006a5913c28850f5a13391 Mon Sep 17 00:00:00 2001
From: zouyu <2723363702@qq.com>
Date: 星期五, 14 十一月 2025 15:04:11 +0800
Subject: [PATCH] Merge branch 'dev_7004' into dev_tide

---
 src/views/qualityManagement/rawMaterialInspection/index.vue                      |   30 
 src/views/inventoryManagement/stockWarning/index.vue                             |    1 
 src/views/system/user/authRole.vue                                               |    2 
 src/views/qualityManagement/finalInspection/index.vue                            |  142 
 src/views/monitor/logininfor/index.vue                                           |    2 
 src/views/monitor/operlog/index.vue                                              |    2 
 src/views/qualityManagement/processInspection/index.vue                          |  137 
 src/views/salesManagement/invoiceLedger/index.vue                                |    8 
 src/views/procurementManagement/invoiceEntry/indexOld.vue                        |    3 
 src/views/inventoryManagement/receiptManagement/index.vue                        |    3 
 src/views/energyManagement/energyPower/components/formDia.vue                    |   55 
 src/views/inventoryManagement/stockManagement/index.vue                          |    2 
 src/views/monitor/job/log.vue                                                    |    2 
 src/views/equipmentManagement/ledger/index.vue                                   |   25 
 src/views/inventoryManagement/dispatchLog/index.vue                              |    7 
 src/views/personnelManagement/onboarding/index.vue                               |   66 
 src/views/collaborativeApproval/meetingBoard/index.vue                           |  498 ++
 src/views/reportAnalysis/projectProfit/index.vue                                 |   11 
 src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue                  |    4 
 src/views/financialManagement/revenueManagement/index.vue                        |    2 
 .env.development                                                                 |    4 
 src/views/collaborativeApproval/warningSystem/index.vue                          |  307 +
 src/views/energyManagement/waterManagement/components/formDia.vue                |   62 
 src/views/tool/gen/index.vue                                                     |    1 
 src/views/collaborativeApproval/approvalProcess/fileList.vue                     |   43 
 public/HYSNico.ico                                                               |    0 
 src/views/collaborativeApproval/noticeManagement/index.vue                       |  705 +++
 src/views/procurementManagement/procurementInvoiceLedger/index.vue               |   18 
 src/views/system/role/index.vue                                                  |    2 
 src/views/collaborativeApproval/approvalProcess/index4.vue                       |   22 
 src/views/procurementManagement/invoiceEntry/index.vue                           |    4 
 src/views/salesManagement/receiptPaymentLedger/index.vue                         |    2 
 src/views/collaborativeApproval/approvalProcess/index.vue                        |   32 
 src/views/collaborativeApproval/approvalProcess/index3.vue                       |   22 
 src/views/procurementManagement/paymentEntry/index.vue                           |   47 
 src/views/salesManagement/salesLedger/index.vue                                  |   18 
 src/views/system/menu/index.vue                                                  |    1 
 src/views/system/dict/data.vue                                                   |    2 
 src/views/tool/gen/editTable.vue                                                 |    2 
 src/views/tool/gen/importTable.vue                                               |    2 
 src/views/salesManagement/salesLedger/fileList.vue                               |    2 
 src/api/collaborativeApproval/rpaManagement.js                                   |   77 
 src/views/collaborativeApproval/knowledgeBase/index.vue                          |  848 +++
 src/views/collaborativeApproval/attendanceManagement/index.vue                   |  714 +++
 src/views/chatHome/chatHomeIndex/MobileChat.vue                                  |    2 
 src/views/energyManagement/energyPeriodTime/index.vue                            |  444 +
 src/views/salesManagement/receiptPayment/index.vue                               |   32 
 src/views/system/dept/index.vue                                                  |   37 
 src/views/collaborativeApproval/approvalProcess/index1.vue                       |   22 
 src/components/PIMTable/PIMTable.vue                                             |    1 
 src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue       |   82 
 src/views/equipmentManagement/iotMonitor/indexWD.vue                             |  317 +
 src/views/salesManagement/invoiceRegistration/index.vue                          |   25 
 src/assets/indexViews/HYSNLogo.png                                               |    0 
 src/api/collaborativeApproval/noticeManagement.js                                |   69 
 src/views/collaborativeApproval/notificationManagement/index.vue                 | 1187 +++++
 src/views/collaborativeApproval/rpaManagement/index.vue                          |  400 +
 src/views/energyManagement/energyCockpit/index.vue                               | 1380 ++++++
 src/views/index.vue                                                              |   51 
 src/views/equipmentManagement/measurementEquipment/components/formDia.vue        |   34 
 src/views/energyManagement/meterCollection/index.vue                             |  556 ++
 src/views/personnelManagement/contractManagement/index.vue                       |  160 
 src/views/equipmentManagement/ledger/Form.vue                                    |    6 
 src/views/basicData/customerFile/index.vue                                       |   37 
 src/views/system/role/authUser.vue                                               |    2 
 index.html                                                                       |    2 
 src/views/equipmentManagement/upkeep/index.vue                                   |    8 
 src/views/qualityManagement/processInspection/components/formDia.vue             |   97 
 src/views/personnelManagement/onboarding/components/formDia.vue                  |   23 
 src/views/productionManagement/operationScheduling/components/formDia.vue        |    2 
 src/views/equipmentManagement/repair/Modal/MaintainModal.vue                     |    4 
 src/views/energyManagement/energyArea/index.vue                                  |  511 ++
 src/views/system/post/index.vue                                                  |    2 
 src/views/inventoryManagement/issueManagement/index.vue                          |    2 
 src/views/productionManagement/safetyMonitoring/index.vue                        |  873 +++
 src/views/energyManagement/gasManagement/index.vue                               |  624 ++
 src/router/index.js                                                              |   29 
 src/views/financialManagement/expenseManagement/index.vue                        |    2 
 src/views/procurementManagement/procurementLedger/index.vue                      |  428 +
 src/views/equipmentManagement/measurementEquipment/index.vue                     |   14 
 src/views/productionManagement/productionReporting/index.vue                     |    1 
 src/main.js                                                                      |    2 
 src/views/qualityManagement/rawMaterialInspection/components/formDia.vue         |   42 
 src/views/qualityManagement/processInspection/components/filesDia.vue            |   23 
 .env.production                                                                  |    4 
 src/views/system/notice/index.vue                                                |    2 
 src/views/system/dict/index.vue                                                  |    2 
 bin/build.bat                                                                    |   22 
 src/views/procurementManagement/paymentHistory/index.vue                         |    4 
 src/views/system/config/index.vue                                                |    2 
 src/views/equipmentManagement/iotMonitor/index.vue                               |  317 +
 src/api/energyManagement/index.js                                                |  115 
 .env.staging                                                                     |    4 
 src/views/equipmentManagement/measurementEquipment/filesDia.vue                  |  202 
 src/views/collaborativeApproval/approvalProcess/index2.vue                       |   22 
 src/views/system/role/selectUser.vue                                             |    2 
 src/assets/indexViews/HYSNView.png                                               |    0 
 src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue       |   13 
 src/views/energyManagement/waterManagement/index.vue                             |   20 
 src/views/monitor/job/index.vue                                                  |    2 
 src/views/demo/fakePage/index.vue                                                |  248 +
 src/views/qualityManagement/finalInspection/components/formDia.vue               |   79 
 src/views/equipmentManagement/repair/index.vue                                   |    8 
 src/views/monitor/online/index.vue                                               |    1 
 src/views/qualityManagement/rawMaterialInspection/components/filesDia.vue        |   23 
 src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue |   34 
 src/views/procurementManagement/paymentLedger/index.vue                          |    1 
 src/views/system/user/index.vue                                                  |    1 
 src/views/login.vue                                                              |    6 
 src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue            |    2 
 package.json                                                                     |    2 
 src/views/personnelManagement/contractManagement/filesDia.vue                    |  202 
 src/api/energyManagement/waterManagement.js                                      |   14 
 src/views/energyManagement/dynamicEnergySaving/index.vue                         |  659 ++
 114 files changed, 13,050 insertions(+), 435 deletions(-)

diff --git a/.env.development b/.env.development
index b5f6a61..1a63995 100644
--- a/.env.development
+++ b/.env.development
@@ -1,8 +1,8 @@
 # 椤甸潰鏍囬
-VITE_APP_TITLE = MIS绯荤粺锛堢鐞嗕俊鎭郴缁燂級
+VITE_APP_TITLE = 鑺浜戯紙绠$悊淇℃伅绯荤粺锛�
 
 # 寮�鍙戠幆澧冮厤缃�
 VITE_APP_ENV = 'development'
 
-# MIS绯荤粺锛堢鐞嗕俊鎭郴缁燂級/寮�鍙戠幆澧�
+# 鑺浜戯紙绠$悊淇℃伅绯荤粺锛�/寮�鍙戠幆澧�
 VITE_APP_BASE_API = '/dev-api'
diff --git a/.env.production b/.env.production
index 3796379..3521d24 100644
--- a/.env.production
+++ b/.env.production
@@ -1,10 +1,10 @@
 # 椤甸潰鏍囬
-VITE_APP_TITLE = MIS绯荤粺锛堢鐞嗕俊鎭郴缁燂級
+VITE_APP_TITLE = 鑺浜戯紙绠$悊淇℃伅绯荤粺锛�
 
 # 鐢熶骇鐜閰嶇疆
 VITE_APP_ENV = 'production'
 
-# MIS绯荤粺锛堢鐞嗕俊鎭郴缁燂級/鐢熶骇鐜
+# 鑺浜戯紙绠$悊淇℃伅绯荤粺锛�/鐢熶骇鐜
 VITE_APP_BASE_API = '/prod-api'
 
 # 鏄惁鍦ㄦ墦鍖呮椂寮�鍚帇缂╋紝鏀寔 gzip 鍜� brotli
diff --git a/.env.staging b/.env.staging
index f759f9a..468abb3 100644
--- a/.env.staging
+++ b/.env.staging
@@ -1,10 +1,10 @@
 # 椤甸潰鏍囬
-VITE_APP_TITLE = MIS绯荤粺锛堢鐞嗕俊鎭郴缁燂級
+VITE_APP_TITLE = 鑺浜戯紙绠$悊淇℃伅绯荤粺锛�
 
 # 鐢熶骇鐜閰嶇疆
 VITE_APP_ENV = 'staging'
 
-# MIS绯荤粺锛堢鐞嗕俊鎭郴缁燂級/鐢熶骇鐜
+# 鑺浜戯紙绠$悊淇℃伅绯荤粺锛�/鐢熶骇鐜
 VITE_APP_BASE_API = '/stage-api'
 
 # 鏄惁鍦ㄦ墦鍖呮椂寮�鍚帇缂╋紝鏀寔 gzip 鍜� brotli
diff --git a/bin/build.bat b/bin/build.bat
index 8868727..a4cc0df 100644
--- a/bin/build.bat
+++ b/bin/build.bat
@@ -1,12 +1,12 @@
-@echo off
-echo.
-echo [信息] 打包Web工程,生成dist文件。
-echo.
-
-%~d0
-cd %~dp0
-
-cd ..
-yarn build:prod
-
+@echo off
+echo.
+echo [锟斤拷息] 锟斤拷锟絎eb锟斤拷锟教o拷锟斤拷锟斤拷dist锟侥硷拷锟斤拷
+echo.
+
+%~d0
+cd %~dp0
+
+cd ..
+yarn build:prod
+
 pause
\ No newline at end of file
diff --git a/index.html b/index.html
index 879c6c5..c72b2b8 100644
--- a/index.html
+++ b/index.html
@@ -7,7 +7,7 @@
   <meta name="renderer" content="webkit">
   <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
   <link rel="icon" href="/favicon.ico">
-  <title>MIS绯荤粺锛堢鐞嗕俊鎭郴缁燂級</title>
+  <title>鑺浜戯紙绠$悊淇℃伅绯荤粺锛�</title>
   <!--[if lt IE 11]><script>window.location.href='/html/ie.html';</script><![endif]-->
   <style>
     html,
diff --git a/package.json b/package.json
index 3fd8e3d..2ffdd34 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,7 @@
 {
   "name": "ruoyi",
   "version": "3.8.9",
-  "description": "MES",
+  "description": "MIS绯荤粺锛堢鐞嗕俊鎭郴缁燂級",
   "author": "鑻ヤ緷",
   "license": "MIT",
   "type": "module",
diff --git a/public/HYSNico.ico b/public/HYSNico.ico
new file mode 100644
index 0000000..70148cc
--- /dev/null
+++ b/public/HYSNico.ico
Binary files differ
diff --git a/src/api/collaborativeApproval/noticeManagement.js b/src/api/collaborativeApproval/noticeManagement.js
new file mode 100644
index 0000000..fa1caec
--- /dev/null
+++ b/src/api/collaborativeApproval/noticeManagement.js
@@ -0,0 +1,69 @@
+import request from '@/utils/request'
+
+// 鏌ヨ鍏憡鍒楄〃
+export function listNotice(query) {
+  return request({
+    url: '/collaborativeApproval/notice/list',
+    method: 'get',
+    params: query
+  })
+}
+
+// 鏌ヨ鍏憡璇︾粏
+export function getNotice(noticeId) {
+  return request({
+    url: '/collaborativeApproval/notice/' + noticeId,
+    method: 'get'
+  })
+}
+
+// 鏂板鍏憡
+export function addNotice(data) {
+  return request({
+    url: '/collaborativeApproval/notice',
+    method: 'post',
+    data: data
+  })
+}
+
+// 淇敼鍏憡
+export function updateNotice(data) {
+  return request({
+    url: '/collaborativeApproval/notice',
+    method: 'put',
+    data: data
+  })
+}
+
+// 鍒犻櫎鍏憡
+export function delNotice(noticeId) {
+  return request({
+    url: '/collaborativeApproval/notice/' + noticeId,
+    method: 'delete'
+  })
+}
+
+// 鎵归噺鍒犻櫎鍏憡
+export function delNoticeBatch(noticeIds) {
+  return request({
+    url: '/collaborativeApproval/notice/batch',
+    method: 'delete',
+    data: noticeIds
+  })
+}
+
+// 鍙戝竷鍏憡
+export function publishNotice(noticeId) {
+  return request({
+    url: '/collaborativeApproval/notice/publish/' + noticeId,
+    method: 'put'
+  })
+}
+
+// 涓嬬嚎鍏憡
+export function offlineNotice(noticeId) {
+  return request({
+    url: '/collaborativeApproval/notice/offline/' + noticeId,
+    method: 'put'
+  })
+}
diff --git a/src/api/collaborativeApproval/rpaManagement.js b/src/api/collaborativeApproval/rpaManagement.js
new file mode 100644
index 0000000..6fc3368
--- /dev/null
+++ b/src/api/collaborativeApproval/rpaManagement.js
@@ -0,0 +1,77 @@
+import request from "@/utils/request";
+
+// 鏌ヨRPA鍒楄〃
+export function listRpa(query) {
+  return request({
+    url: "/collaborativeApproval/rpa/list",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鏌ヨRPA璇︾粏
+export function getRpa(rpaId) {
+  return request({
+    url: "/collaborativeApproval/rpa/" + rpaId,
+    method: "get",
+  });
+}
+
+// 鏂板RPA
+export function addRpa(data) {
+  return request({
+    url: "/collaborativeApproval/rpa",
+    method: "post",
+    data: data,
+  });
+}
+
+// 淇敼RPA
+export function updateRpa(data) {
+  return request({
+    url: "/collaborativeApproval/rpa",
+    method: "put",
+    data: data,
+  });
+}
+
+// 鍒犻櫎RPA
+export function delRpa(rpaId) {
+  return request({
+    url: "/collaborativeApproval/rpa/" + rpaId,
+    method: "delete",
+  });
+}
+
+// 鎵归噺鍒犻櫎RPA
+export function delRpaBatch(rpaIds) {
+  return request({
+    url: "/collaborativeApproval/rpa/batch",
+    method: "delete",
+    data: rpaIds,
+  });
+}
+
+// 鍚姩RPA
+export function startRpa(rpaId) {
+  return request({
+    url: "/collaborativeApproval/rpa/start/" + rpaId,
+    method: "post",
+  });
+}
+
+// 鍋滄RPA
+export function stopRpa(rpaId) {
+  return request({
+    url: "/collaborativeApproval/rpa/stop/" + rpaId,
+    method: "post",
+  });
+}
+
+// 鑾峰彇RPA鐘舵��
+export function getRpaStatus(rpaId) {
+  return request({
+    url: "/collaborativeApproval/rpa/status/" + rpaId,
+    method: "get",
+  });
+}
diff --git a/src/api/energyManagement/index.js b/src/api/energyManagement/index.js
index 4c061e6..f2c5494 100644
--- a/src/api/energyManagement/index.js
+++ b/src/api/energyManagement/index.js
@@ -4,47 +4,124 @@
 // 璁惧鑳借��-鍒嗛〉鏌ヨ
 export function equipmentEnergyListPage(query) {
   return request({
-    url: '/equipmentEnergyConsumption/listPage',
-    method: 'get',
+    url: "/equipmentEnergyConsumption/listPage",
+    method: "get",
     params: query,
-  })
+  });
 }
 // -鑳芥簮瓒嬪娍-鍒嗛〉鏌ヨ
 export function listPageByTrend(query) {
   return request({
-    url: '/equipmentEnergyConsumption/listPageByTrend',
-    method: 'get',
+    url: "/equipmentEnergyConsumption/listPageByTrend",
+    method: "get",
     params: query,
-  })
+  });
 }
+// 鍖哄煙-鍒嗛〉鏌ヨ
+export function areaListPage(query) {
+  return request({
+    url: "/electricityConsumptionArea/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
+// 鍖哄煙-鏍�
+export function areaListTree(query) {
+  return request({
+    url: "/electricityConsumptionArea/list",
+    method: "get",
+    params: query,
+  });
+}
+// 鏃堕棿鍛ㄦ湡-鍒嗛〉鏌ヨ
+export function periodListPage(query) {
+  return request({
+    url: "/energyPeriod/listPage",
+    method: "get",
+    params: query,
+  });
+}
+
 // 璁惧鑳借��-鍒犻櫎
 export function equipmentEnergyDelete(query) {
   return request({
-    url: '/equipmentEnergyConsumption/delete',
-    method: 'delete',
+    url: "/equipmentEnergyConsumption/delete",
+    method: "delete",
     data: query,
-  })
+  });
 }
+// 鍖哄煙-鍒犻櫎
+export function areaDelete(query) {
+  return request({
+    url: "/electricityConsumptionArea/delete",
+    method: "delete",
+    data: query,
+  });
+}
+// 鏃堕棿鍛ㄦ湡-鍒犻櫎
+export function periodDelete(query) {
+  return request({
+    url: "/energyPeriod/delete",
+    method: "delete",
+    data: query,
+  });
+}
+
 // 璁惧鑳借��-鏂板
 export function equipmentEnergyAdd(query) {
   return request({
-    url: '/equipmentEnergyConsumption/add',
-    method: 'post',
+    url: "/equipmentEnergyConsumption/add",
+    method: "post",
     data: query,
-  })
+  });
+}
+// 鍖哄煙-鏂板
+export function areaAdd(query) {
+  return request({
+    url: "/electricityConsumptionArea/add",
+    method: "post",
+    data: query,
+  });
+}
+
+// 鏃堕棿鍛ㄦ湡-鏂板
+export function periodAdd(query) {
+  return request({
+    url: "/energyPeriod/add",
+    method: "post",
+    data: query,
+  });
 }
 // 璁惧鑳借��-淇敼
 export function equipmentEnergyUpdate(query) {
   return request({
-    url: '/equipmentEnergyConsumption/update',
-    method: 'post',
+    url: "/equipmentEnergyConsumption/update",
+    method: "post",
     data: query,
-  })
+  });
 }
+//鍖哄煙-淇敼
+export function areaUpdate(query) {
+  return request({
+    url: "/electricityConsumptionArea/update",
+    method: "post",
+    data: query,
+  });
+}
+// 鏃堕棿鍛ㄦ湡-淇敼
+export function periodUpdate(query) {
+  return request({
+    url: "/energyPeriod/update",
+    method: "post",
+    data: query,
+  });
+}
+
 // 璁惧涓嬫媺妗嗘煡璇�
 export function deviceList(query) {
   return request({
-    url: '/equipmentEnergyConsumption/deviceList',
-    method: 'get',
-  })
-}
\ No newline at end of file
+    url: "/equipmentEnergyConsumption/deviceList",
+    method: "get",
+  });
+}
diff --git a/src/api/energyManagement/waterManagement.js b/src/api/energyManagement/waterManagement.js
index aef7465..6dbf115 100644
--- a/src/api/energyManagement/waterManagement.js
+++ b/src/api/energyManagement/waterManagement.js
@@ -4,7 +4,7 @@
 // 鐢ㄦ按璁惧-鍒嗛〉鏌ヨ
 export function waterEquipmentListPage(query) {
   return request({
-    url: '/waterEquipmentConsumption/listPage',
+    url: '/waterRecord/listPage',
     method: 'get',
     params: query,
   })
@@ -13,7 +13,7 @@
 // 鐢ㄦ按瓒嬪娍-鍒嗛〉鏌ヨ
 export function listPageByWaterTrend(query) {
   return request({
-    url: '/waterEquipmentConsumption/listPageByTrend',
+    url: '/waterRecord/listPageByTrend',
     method: 'get',
     params: query,
   })
@@ -22,7 +22,7 @@
 // 鐢ㄦ按璁惧-鍒犻櫎
 export function waterEquipmentDelete(query) {
   return request({
-    url: '/waterEquipmentConsumption/delete',
+    url: '/waterRecord/delete',
     method: 'delete',
     data: query,
   })
@@ -31,7 +31,7 @@
 // 鐢ㄦ按璁惧-鏂板
 export function waterEquipmentAdd(query) {
   return request({
-    url: '/waterEquipmentConsumption/add',
+    url: '/waterRecord/add',
     method: 'post',
     data: query,
   })
@@ -40,7 +40,7 @@
 // 鐢ㄦ按璁惧-淇敼
 export function waterEquipmentUpdate(query) {
   return request({
-    url: '/waterEquipmentConsumption/update',
+    url: '/waterRecord/update',
     method: 'post',
     data: query,
   })
@@ -49,8 +49,9 @@
 // 鐢ㄦ按璁惧涓嬫媺妗嗘煡璇�
 export function waterDeviceList(query) {
   return request({
-    url: '/waterEquipmentConsumption/deviceList',
+    url: '/device/ledger/page',
     method: 'get',
+    params: query,
   })
 }
 
@@ -89,3 +90,4 @@
     data: query,
   })
 }
+
diff --git a/src/assets/indexViews/HYSNLogo.png b/src/assets/indexViews/HYSNLogo.png
new file mode 100644
index 0000000..70148cc
--- /dev/null
+++ b/src/assets/indexViews/HYSNLogo.png
Binary files differ
diff --git a/src/assets/indexViews/HYSNView.png b/src/assets/indexViews/HYSNView.png
new file mode 100644
index 0000000..ccd5fcc
--- /dev/null
+++ b/src/assets/indexViews/HYSNView.png
Binary files differ
diff --git a/src/components/PIMTable/PIMTable.vue b/src/components/PIMTable/PIMTable.vue
index 955173d..a89aa96 100644
--- a/src/components/PIMTable/PIMTable.vue
+++ b/src/components/PIMTable/PIMTable.vue
@@ -15,6 +15,7 @@
     :expand-row-keys="expandRowKeys"
     :show-summary="isShowSummary"
     :summary-method="summaryMethod"
+    stripe
     @row-click="rowClick"
     @current-change="currentChange"
     @selection-change="handleSelectionChange"
diff --git a/src/main.js b/src/main.js
index 00205af..ef6b2a4 100644
--- a/src/main.js
+++ b/src/main.js
@@ -76,7 +76,7 @@
 app.config.globalProperties.addDateRange = addDateRange;
 app.config.globalProperties.selectDictLabel = selectDictLabel;
 app.config.globalProperties.selectDictLabels = selectDictLabels;
-app.config.globalProperties.javaApi = "http://114.132.189.42:8099";
+app.config.globalProperties.javaApi = "http://114.132.189.42:7004";
 app.config.globalProperties.HaveJson = (val) => {
   return JSON.parse(JSON.stringify(val));
 };
diff --git a/src/router/index.js b/src/router/index.js
index b37fa51..d190347 100644
--- a/src/router/index.js
+++ b/src/router/index.js
@@ -77,20 +77,6 @@
     ]
   },
   {
-    path: '/main/MobileChat',
-    component: Layout,
-    redirect: '',
-    hidden: true,
-    children: [
-      {
-        path: '',
-        component: () => import('@/views/chatHome/chatHomeIndex/MobileChat'),
-        name: 'MobileChat',
-        meta: { title: 'AI瀵硅瘽', icon: 'dashboard', affix: true}
-      }
-    ]
-  },
-  {
     path: '/user',
     component: Layout,
     hidden: true,
@@ -123,6 +109,21 @@
     ]
   },
   {
+    path: '/main/MobileChat',
+    component: Layout,
+    redirect: '',
+    hidden: true,
+    permissions: ['MobileChat:edit'],
+    children: [
+      {
+        path: '',
+        component: () => import('@/views/chatHome/chatHomeIndex/MobileChat'),
+        name: 'MobileChat',
+        meta: { title: 'AI瀵硅瘽', activeMenu: '/chatHome/chatHomeIndex'}
+      }
+    ]
+  },
+  {
     path: '/system/role-auth',
     component: Layout,
     hidden: true,
diff --git a/src/views/basicData/customerFile/index.vue b/src/views/basicData/customerFile/index.vue
index a706616..8043d1a 100644
--- a/src/views/basicData/customerFile/index.vue
+++ b/src/views/basicData/customerFile/index.vue
@@ -92,25 +92,6 @@
             </el-form-item>
           </el-col>
         </el-row>
-        <el-row :gutter="30" v-for="(contact, index) in formYYs.contactList" :key="index">
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴浜猴細" prop="contactPerson">
-              <el-input v-model="contact.contactPerson" placeholder="璇疯緭鍏�" clearable  />
-            </el-form-item>
-          </el-col>
-          <el-col :span="12">
-            <el-form-item label="鑱旂郴鐢佃瘽锛�" prop="contactPhone">
-              <div style="display: flex; align-items: center;width: 100%;">
-                <el-input v-model="contact.contactPhone" placeholder="璇疯緭鍏�" clearable />
-                <el-button   @click="removeContact(index)" type="danger" circle style="margin-left: 5px;">
-                  <el-icon><Close /></el-icon>
-                </el-button>
-              </div>
-            </el-form-item>
-          </el-col>
-        </el-row>
-        <el-button @click="addNewContact" style="margin-bottom: 10px;">+ 鏂板鑱旂郴浜�</el-button>
-
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="閾惰鍩烘湰鎴凤細" prop="basicBankAccount">
@@ -142,6 +123,24 @@
             </el-form-item>
           </el-col>
         </el-row>
+				<el-row :gutter="30" v-for="(contact, index) in formYYs.contactList" :key="index">
+					<el-col :span="12">
+						<el-form-item label="鑱旂郴浜猴細" prop="contactPerson">
+							<el-input v-model="contact.contactPerson" placeholder="璇疯緭鍏�" clearable  />
+						</el-form-item>
+					</el-col>
+					<el-col :span="12">
+						<el-form-item label="鑱旂郴鐢佃瘽锛�" prop="contactPhone">
+							<div style="display: flex; align-items: center;width: 100%;">
+								<el-input v-model="contact.contactPhone" placeholder="璇疯緭鍏�" clearable />
+								<el-button   @click="removeContact(index)" type="danger" circle style="margin-left: 5px;">
+									<el-icon><Close /></el-icon>
+								</el-button>
+							</div>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-button @click="addNewContact" style="margin-bottom: 10px;">+ 鏂板鑱旂郴浜�</el-button>
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="缁存姢浜猴細" prop="maintainer">
diff --git a/src/views/chatHome/chatHomeIndex/MobileChat.vue b/src/views/chatHome/chatHomeIndex/MobileChat.vue
index f8bc625..5b06e76 100644
--- a/src/views/chatHome/chatHomeIndex/MobileChat.vue
+++ b/src/views/chatHome/chatHomeIndex/MobileChat.vue
@@ -203,7 +203,7 @@
   }
   chatList.value.push(replyMsg)
   scrollBottom()
-
+  loading.value = false
   // 濡傛灉鏈夋煡璇㈠叧閿瓧锛屽垯妯℃嫙娴佸紡杈撳嚭
   if (route.query.keyWord) {
     simulateStreamingOutput(replyMsg, route.query.keyWord)
diff --git a/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue b/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
index 3aa58c5..83585a1 100644
--- a/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
+++ b/src/views/collaborativeApproval/approvalProcess/components/infoFormDia.vue
@@ -112,6 +112,23 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
+              <el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
+                         :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
+                         :on-success="handleUploadSuccess" :on-remove="handleRemove">
+                <el-button type="primary" v-if="operationType !== 'view'">涓婁紶</el-button>
+                <template #tip v-if="operationType !== 'view'">
+                  <div class="el-upload__tip">
+                    鏂囦欢鏍煎紡鏀寔
+                    doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
+                  </div>
+                </template>
+              </el-upload>
+            </el-form-item>
+          </el-col>
+        </el-row>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -130,7 +147,11 @@
   approveProcessUpdate,
   getDept
 } from "@/api/collaborativeApproval/approvalProcess.js";
+import {
+  delLedgerFile,
+} from "@/api/salesManagement/salesLedger.js";
 import {userListNoPageByTenantId} from "@/api/system/user.js";
+import { getToken } from "@/utils/auth";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 import useUserStore from "@/store/modules/user";
@@ -138,6 +159,13 @@
 
 const dialogFormVisible = ref(false);
 const operationType = ref('')
+const fileList = ref([]);
+const upload = reactive({
+  // 涓婁紶鐨勫湴鍧�
+  url: import.meta.env.VITE_APP_BASE_API + "/file/upload",
+  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+  headers: { Authorization: "Bearer " + getToken() },
+});
 const data = reactive({
   form: {
     approveTime: "",
@@ -146,6 +174,7 @@
 		approveDeptId: "",
     approveReason: "",
     checkResult: "",
+    tempFileIds: [],
     approverList: [] // 鏂板瀛楁锛屽瓨鍌ㄦ墍鏈夎妭鐐圭殑瀹℃壒浜篿d
   },
   rules: {
@@ -160,6 +189,12 @@
 const { form, rules } = toRefs(data);
 const productOptions = ref([]);
 const currentApproveStatus = ref(0)
+const props = defineProps({
+  approveType: {
+    type: [Number, String],
+    default: 0
+  }
+})
 
 // 瀹℃壒浜鸿妭鐐圭浉鍏�
 const approverNodes = ref([
@@ -176,6 +211,7 @@
 
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
+  console.log('openDialog', type, row)
   operationType.value = type;
   dialogFormVisible.value = true;
 	userListNoPageByTenantId().then((res) => {
@@ -192,6 +228,8 @@
   // 鑾峰彇褰撳墠鐢ㄦ埛淇℃伅骞惰缃儴闂↖D
   form.value.approveDeptId = userStore.currentDeptId
   if (operationType.value === 'edit') {
+    fileList.value = row.commonFileList
+    form.value.tempFileIds = fileList.value.map(file => file.id)
 		currentApproveStatus.value = row.approveStatus
     approveProcessGetInfo({id: row.approveId,approveReason: '1'}).then(res => {
 			form.value = {...res.data}
@@ -233,6 +271,7 @@
 const submitForm = () => {
   // 鏀堕泦鎵�鏈夎妭鐐圭殑瀹℃壒浜篿d
   form.value.approveUserIds = approverNodes.value.map(node => node.userId).join(',')
+  form.value.approveType = props.approveType
   // 瀹℃壒浜哄繀濉牎楠�
   const hasEmptyApprover = approverNodes.value.some(node => !node.userId)
   if (hasEmptyApprover) {
@@ -257,6 +296,7 @@
 }
 // 鍏抽棴寮规
 const closeDia = () => {
+  fileList.value = []
   proxy.resetForm("formRef");
   dialogFormVisible.value = false;
   emit('close')
@@ -269,6 +309,48 @@
   const day = String(today.getDate()).padStart(2, "0");
   return `${year}-${month}-${day}`;
 }
+
+// 涓婁紶鍓嶆牎妫�
+function handleBeforeUpload(file) {
+  // 鏍℃鏂囦欢澶у皬
+  // if (file.size > 1024 * 1024 * 10) {
+  //   proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
+  //   return false;
+  // }
+  proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
+  return true;
+}
+// 涓婁紶澶辫触
+function handleUploadError(err) {
+  proxy.$modal.msgError("涓婁紶鏂囦欢澶辫触");
+  proxy.$modal.closeLoading();
+}
+// 涓婁紶鎴愬姛鍥炶皟
+function handleUploadSuccess(res, file, uploadFiles) {
+  proxy.$modal.closeLoading();
+  if (res.code === 200) {
+    // 纭繚 tempFileIds 瀛樺湪涓斾负鏁扮粍
+    if (!form.value.tempFileIds) {
+      form.value.tempFileIds = [];
+    }
+    form.value.tempFileIds.push(res.data.tempId);
+    proxy.$modal.msgSuccess("涓婁紶鎴愬姛");
+  } else {
+    proxy.$modal.msgError(res.msg);
+    proxy.$refs.fileUpload.handleRemove(file);
+  }
+}
+// 绉婚櫎鏂囦欢
+function handleRemove(file) {
+  if (operationType.value === "edit") {
+    let ids = [];
+    ids.push(file.id);
+    delLedgerFile(ids).then((res) => {
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+    });
+  }
+}
+
 defineExpose({
   openDialog,
 });
diff --git a/src/views/collaborativeApproval/approvalProcess/fileList.vue b/src/views/collaborativeApproval/approvalProcess/fileList.vue
new file mode 100644
index 0000000..e9e3b87
--- /dev/null
+++ b/src/views/collaborativeApproval/approvalProcess/fileList.vue
@@ -0,0 +1,43 @@
+<template>
+  <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
+    <el-table :data="tableData" border height="40vh" stripe>
+      <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="400" show-overflow-tooltip />
+      <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center">
+        <template #default="scope">
+          <el-button link type="primary" size="small" @click="downLoadFile(scope.row)">涓嬭浇</el-button>
+          <el-button link type="primary" size="small" @click="lookFile(scope.row)">棰勮</el-button>
+        </template>
+      </el-table-column>
+    </el-table>
+  </el-dialog>
+  <filePreview ref="filePreviewRef" />
+</template>
+
+<script setup>
+import { ref } from 'vue'
+import filePreview from '@/components/filePreview/index.vue'
+
+const dialogVisible = ref(false)
+const tableData = ref([])
+const { proxy } = getCurrentInstance();
+const filePreviewRef = ref()
+const handleClose = () => {
+  dialogVisible.value = false
+}
+const open = (list) => {
+  dialogVisible.value = true
+  tableData.value = list
+}
+const downLoadFile = (row) => {
+  proxy.$download.name(row.url);
+
+}
+const lookFile = (row) => {
+  filePreviewRef.value.open(row.url)
+}
+defineExpose({
+  open
+})
+</script>
+
+<style></style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/approvalProcess/index.vue b/src/views/collaborativeApproval/approvalProcess/index.vue
index 79f358b..c3b713e 100644
--- a/src/views/collaborativeApproval/approvalProcess/index.vue
+++ b/src/views/collaborativeApproval/approvalProcess/index.vue
@@ -42,12 +42,14 @@
           :total="page.total"
       ></PIMTable>
     </div>
-    <info-form-dia ref="infoFormDia" @close="handleQuery"></info-form-dia>
+    <info-form-dia ref="infoFormDia" @close="handleQuery" :approveType="approveType"></info-form-dia>
     <approval-dia ref="approvalDia" @close="handleQuery"></approval-dia>
+    <FileList ref="fileListRef" />
   </div>
 </template>
 
 <script setup>
+import FileList from "./fileList.vue";
 import { Search } from "@element-plus/icons-vue";
 import {onMounted, ref} from "vue";
 import {ElMessageBox} from "element-plus";
@@ -55,6 +57,15 @@
 import ApprovalDia from "@/views/collaborativeApproval/approvalProcess/components/approvalDia.vue";
 import {approveProcessDelete, approveProcessListPage} from "@/api/collaborativeApproval/approvalProcess.js";
 import useUserStore from "@/store/modules/user";
+
+// 瀹氫箟缁勪欢鎺ユ敹鐨刾rops
+const props = defineProps({
+  approveType: {
+    type: [Number, String],
+    default: 0
+  }
+});
+
 const userStore = useUserStore();
 
 
@@ -116,11 +127,12 @@
   {
     label: "鐢宠浜�",
     prop: "approveUserName",
+    width: 120
   },
   {
     label: "鐢宠鏃ユ湡",
     prop: "approveTime",
-		width: 120
+		width: 200
   },
   {
     label: "缁撴潫鏃ユ湡",
@@ -137,7 +149,7 @@
     label: "鎿嶄綔",
     align: "center",
     fixed: "right",
-    width: 150,
+    width: 230,
     operation: [
       {
         name: "缂栬緫",
@@ -162,6 +174,13 @@
           openApprovalDia('view', row);
         },
       },
+      {
+        name: "闄勪欢",
+        type: "text",
+        clickFun: (row) => {
+          downLoadFile(row);
+        },
+      },
     ],
   },
 ]);
@@ -183,6 +202,11 @@
   page.current = 1;
   getList();
 };
+const fileListRef = ref(null)
+const downLoadFile = (row) => {
+  fileListRef.value.open(row.commonFileList)
+
+}
 const pagination = (obj) => {
   page.current = obj.page;
   page.size = obj.limit;
@@ -190,7 +214,7 @@
 };
 const getList = () => {
   tableLoading.value = true;
-  approveProcessListPage({...page, ...searchForm.value,}).then(res => {
+  approveProcessListPage({...page, ...searchForm.value,approveType:props.approveType}).then(res => {
     tableLoading.value = false;
     tableData.value = res.data.records
     page.total = res.data.total;
diff --git a/src/views/collaborativeApproval/approvalProcess/index1.vue b/src/views/collaborativeApproval/approvalProcess/index1.vue
new file mode 100644
index 0000000..c46c68a
--- /dev/null
+++ b/src/views/collaborativeApproval/approvalProcess/index1.vue
@@ -0,0 +1,22 @@
+<template>
+  <div class="container">
+    <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+    <ApprovalProcessIndex :approveType="1" />
+  </div>
+</template>
+
+<script setup>
+import ApprovalProcessIndex from './index.vue'
+
+// 瀹氫箟缁勪欢鍚嶇О
+defineOptions({
+  name: 'ApprovalProcessIndex1'
+})
+</script>
+
+<style scoped>
+.container {
+  width: 100%;
+  height: 100%;
+}
+</style>
diff --git a/src/views/collaborativeApproval/approvalProcess/index2.vue b/src/views/collaborativeApproval/approvalProcess/index2.vue
new file mode 100644
index 0000000..7c15c3e
--- /dev/null
+++ b/src/views/collaborativeApproval/approvalProcess/index2.vue
@@ -0,0 +1,22 @@
+<template>
+  <div class="container">
+    <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+    <ApprovalProcessIndex :approveType="2" />
+  </div>
+</template>
+
+<script setup>
+import ApprovalProcessIndex from './index.vue'
+
+// 瀹氫箟缁勪欢鍚嶇О
+defineOptions({
+  name: 'ApprovalProcessIndex1'
+})
+</script>
+
+<style scoped>
+.container {
+  width: 100%;
+  height: 100%;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/approvalProcess/index3.vue b/src/views/collaborativeApproval/approvalProcess/index3.vue
new file mode 100644
index 0000000..3afb6f5
--- /dev/null
+++ b/src/views/collaborativeApproval/approvalProcess/index3.vue
@@ -0,0 +1,22 @@
+<template>
+  <div class="container">
+    <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+    <ApprovalProcessIndex :approveType="3" />
+  </div>
+</template>
+
+<script setup>
+import ApprovalProcessIndex from './index.vue'
+
+// 瀹氫箟缁勪欢鍚嶇О
+defineOptions({
+  name: 'ApprovalProcessIndex1'
+})
+</script>
+
+<style scoped>
+.container {
+  width: 100%;
+  height: 100%;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/approvalProcess/index4.vue b/src/views/collaborativeApproval/approvalProcess/index4.vue
new file mode 100644
index 0000000..77236af
--- /dev/null
+++ b/src/views/collaborativeApproval/approvalProcess/index4.vue
@@ -0,0 +1,22 @@
+<template>
+  <div class="container">
+    <!-- 寮曞叆index.vue缁勪欢骞朵紶閫掑弬鏁� -->
+    <ApprovalProcessIndex :approveType="4" />
+  </div>
+</template>
+
+<script setup>
+import ApprovalProcessIndex from './index.vue'
+
+// 瀹氫箟缁勪欢鍚嶇О
+defineOptions({
+  name: 'ApprovalProcessIndex1'
+})
+</script>
+
+<style scoped>
+.container {
+  width: 100%;
+  height: 100%;
+}
+</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/attendanceManagement/index.vue b/src/views/collaborativeApproval/attendanceManagement/index.vue
new file mode 100644
index 0000000..8db29fc
--- /dev/null
+++ b/src/views/collaborativeApproval/attendanceManagement/index.vue
@@ -0,0 +1,714 @@
+<template>
+  <div class="app-container">
+    <el-tabs v-model="activeTab" type="border-card">
+      <!-- 鍋囨湡璁剧疆 -->
+      <el-tab-pane label="鍋囨湡璁剧疆" name="holiday">
+        <div class="tab-content">
+          <el-button type="primary" @click="openDialog('holiday', 'add')">鏂板鍋囨湡</el-button>
+          
+          <el-table :data="holidayData" border style="width: 100%; margin-top: 20px;" stripe>
+            <el-table-column prop="name" label="鍋囨湡鍚嶇О" />
+            <el-table-column prop="type" label="鍋囨湡绫诲瀷">
+              <template #default="scope">
+                <el-tag :type="getTagType(scope.row.type)">{{ getTypeLabel(scope.row.type) }}</el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="startDate" label="寮�濮嬫棩鏈�"  />
+            <el-table-column prop="endDate" label="缁撴潫鏃ユ湡"  />
+            <el-table-column prop="days" label="澶╂暟"  align="center" />
+            <el-table-column prop="status" label="鐘舵��" >
+              <template #default="scope">
+                <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
+                  {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column label="鎿嶄綔" fixed="right">
+              <template #default="scope">
+                <el-button type="primary" size="small" @click="openDialog('holiday', 'edit', scope.row)">缂栬緫</el-button>
+                <el-button type="danger" size="small" @click="deleteItem('holiday', scope.row)">鍒犻櫎</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </el-tab-pane>
+
+      <!-- 骞村亣璁剧疆 -->
+      <el-tab-pane label="骞村亣璁剧疆" name="annual">
+        <div class="tab-content">
+          <el-button type="primary" @click="openDialog('annual', 'add')">鏂板骞村亣瑙勫垯</el-button>
+          
+          <el-table :data="annualData" border style="width: 100%; margin-top: 20px;" stripe>
+            <el-table-column prop="employeeType" label="鍛樺伐绫诲瀷"/>
+            <el-table-column prop="workYears" label="宸ヤ綔骞撮檺" />
+            <el-table-column prop="annualDays" label="骞村亣澶╂暟" align="center" />
+            <el-table-column prop="maxCarryOver" label="鏈�澶х粨杞ぉ鏁�" align="center" />
+            <el-table-column prop="status" label="鐘舵��">
+              <template #default="scope">
+                <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
+                  {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column label="鎿嶄綔" fixed="right">
+              <template #default="scope">
+                <el-button type="primary" size="small" @click="openDialog('annual', 'edit', scope.row)">缂栬緫</el-button>
+                <el-button type="danger" size="small" @click="deleteItem('annual', scope.row)">鍒犻櫎</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </el-tab-pane>
+
+      <!-- 鍔犵彮璁剧疆 -->
+      <el-tab-pane label="鍔犵彮璁剧疆" name="overtime">
+        <div class="tab-content">
+          <el-button type="primary" @click="openDialog('overtime', 'add')">鏂板鍔犵彮瑙勫垯</el-button>
+          
+          <el-table :data="overtimeData" border style="width: 100%; margin-top: 20px;" stripe>
+            <el-table-column prop="name" label="瑙勫垯鍚嶇О" />
+            <el-table-column prop="type" label="鍔犵彮绫诲瀷" >
+              <template #default="scope">
+                <el-tag :type="getTagType(scope.row.type)">{{ getTypeLabel(scope.row.type) }}</el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="startTime" label="寮�濮嬫椂闂�"  />
+            <el-table-column prop="endTime" label="缁撴潫鏃堕棿"  />
+            <el-table-column prop="rate" label="鍊嶇巼" align="center" />
+            <el-table-column prop="status" label="鐘舵��" >
+              <template #default="scope">
+                <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
+                  {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column label="鎿嶄綔" fixed="right">
+              <template #default="scope">
+                <el-button type="primary" size="small" @click="openDialog('overtime', 'edit', scope.row)">缂栬緫</el-button>
+                <el-button type="danger" size="small" @click="deleteItem('overtime', scope.row)">鍒犻櫎</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </el-tab-pane>
+
+      <!-- 涓婄彮鏃堕棿璁剧疆 -->
+      <el-tab-pane label="涓婄彮鏃堕棿璁剧疆" name="worktime">
+        <div class="tab-content">
+          <el-button type="primary" @click="openDialog('worktime', 'add')">鏂板鏃堕棿娈�</el-button>
+          
+          <el-table :data="worktimeData" border style="width: 100%; margin-top: 20px;" stripe>
+            <el-table-column prop="name" label="鏃堕棿娈靛悕绉�"  />
+            <el-table-column prop="startTime" label="涓婄彮鏃堕棿"/>
+            <el-table-column prop="endTime" label="涓嬬彮鏃堕棿" />
+            <el-table-column prop="flexibleStart" label="寮规�т笂鐝�">
+              <template #default="scope">
+                <el-tag :type="scope.row.flexibleStart ? 'success' : 'info'">
+                  {{ scope.row.flexibleStart ? '鏄�' : '鍚�' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column prop="flexibleMinutes" label="寮规�ф椂闂�(鍒嗛挓)" width="120" align="center" />
+            <el-table-column prop="status" label="鐘舵��" >
+              <template #default="scope">
+                <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
+                  {{ scope.row.status === 'active' ? '鍚敤' : '鍋滅敤' }}
+                </el-tag>
+              </template>
+            </el-table-column>
+            <el-table-column label="鎿嶄綔" fixed="right">
+              <template #default="scope">
+                <el-button type="primary" size="small" @click="openDialog('worktime', 'edit', scope.row)">缂栬緫</el-button>
+                <el-button type="danger" size="small" @click="deleteItem('worktime', scope.row)">鍒犻櫎</el-button>
+              </template>
+            </el-table-column>
+          </el-table>
+        </div>
+      </el-tab-pane>
+    </el-tabs>
+
+    <!-- 閫氱敤寮圭獥 -->
+    <el-dialog v-model="dialogVisible" :title="dialogTitle" width="600px">
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
+        <el-form-item label="鍚嶇О" prop="name" v-if="currentType !== 'annual'">
+          <el-input v-model="form.name" placeholder="璇疯緭鍏ュ悕绉�" />
+        </el-form-item>
+        
+        <el-form-item label="绫诲瀷" prop="type" v-if="currentType === 'holiday' || currentType === 'overtime'">
+          <el-select v-model="form.type" placeholder="璇烽�夋嫨绫诲瀷" style="width: 100%">
+            <el-option 
+              v-for="option in getTypeOptions()" 
+              :key="option.value" 
+              :label="option.label" 
+              :value="option.value" 
+            />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="鍛樺伐绫诲瀷" prop="employeeType" v-if="currentType === 'annual'">
+          <el-select v-model="form.employeeType" placeholder="璇烽�夋嫨鍛樺伐绫诲瀷" style="width: 100%">
+            <el-option label="姝e紡鍛樺伐" value="regular" />
+            <el-option label="璇曠敤鏈熷憳宸�" value="probation" />
+            <el-option label="瀹炰範鐢�" value="intern" />
+          </el-select>
+        </el-form-item>
+
+        <el-form-item label="宸ヤ綔骞撮檺" prop="workYears" v-if="currentType === 'annual'">
+          <el-input v-model="form.workYears" placeholder="濡傦細1-3骞淬��3-5骞寸瓑" />
+        </el-form-item>
+
+        <el-form-item label="骞村亣澶╂暟" prop="annualDays" v-if="currentType === 'annual'">
+          <el-input-number v-model="form.annualDays" :min="0" :max="365" style="width: 100%" />
+        </el-form-item>
+
+        <el-form-item label="鏈�澶х粨杞ぉ鏁�" prop="maxCarryOver" v-if="currentType === 'annual'">
+          <el-input-number v-model="form.maxCarryOver" :min="0" :max="30" style="width: 100%" />
+        </el-form-item>
+
+                          <el-form-item label="鏃ユ湡鑼冨洿" prop="dateRange" v-if="currentType === 'holiday'">
+           <el-date-picker
+             v-model="form.dateRange"
+             type="daterange"
+             range-separator="鑷�"
+             start-placeholder="寮�濮嬫棩鏈�"
+             end-placeholder="缁撴潫鏃ユ湡"
+             style="width: 100%"
+             @change="calculateDays"
+           />
+         </el-form-item>
+
+        <el-form-item label="澶╂暟" prop="days" v-if="currentType === 'holiday'">
+          <el-input-number v-model="form.days" :min="0" style="width: 100%" />
+        </el-form-item>
+
+                 <el-form-item label="寮�濮嬫椂闂�" prop="startTime" v-if="currentType === 'overtime'">
+           <el-time-picker
+             v-model="form.startTime"
+             placeholder="寮�濮嬫椂闂�"
+             format="HH:mm"
+             value-format="HH:mm"
+             style="width: 100%"
+             @change="validateTimeField('startTime')"
+           />
+         </el-form-item>
+         
+         <el-form-item label="缁撴潫鏃堕棿" prop="endTime" v-if="currentType === 'overtime'">
+           <el-time-picker
+             v-model="form.endTime"
+             placeholder="缁撴潫鏃堕棿"
+             format="HH:mm"
+             value-format="HH:mm"
+             style="width: 100%"
+             @change="validateTimeField('endTime')"
+           />
+         </el-form-item>
+
+        <el-form-item label="鍊嶇巼" prop="rate" v-if="currentType === 'overtime'">
+          <el-input-number v-model="form.rate" :min="1" :max="3" :step="0.5" style="width: 100%" />
+        </el-form-item>
+
+                 <el-form-item label="涓婄彮鏃堕棿" prop="workStartTime" v-if="currentType === 'worktime'">
+           <el-time-picker
+             v-model="form.workStartTime"
+             placeholder="涓婄彮鏃堕棿"
+             format="HH:mm"
+             value-format="HH:mm"
+             style="width: 100%"
+             @change="validateTimeField('workStartTime')"
+           />
+         </el-form-item>
+
+         <el-form-item label="涓嬬彮鏃堕棿" prop="workEndTime" v-if="currentType === 'worktime'">
+           <el-time-picker
+             v-model="form.workEndTime"
+             placeholder="涓嬬彮鏃堕棿"
+             format="HH:mm"
+             value-format="HH:mm"
+             style="width: 100%"
+             @change="validateTimeField('workEndTime')"
+           />
+         </el-form-item>
+
+        <el-form-item label="寮规�т笂鐝�" prop="flexibleStart" v-if="currentType === 'worktime'">
+          <el-switch v-model="form.flexibleStart" />
+        </el-form-item>
+
+        <el-form-item label="寮规�ф椂闂�(鍒嗛挓)" prop="flexibleMinutes" v-if="currentType === 'worktime' && form.flexibleStart">
+          <el-input-number v-model="form.flexibleMinutes" :min="0" :max="120" style="width: 100%" />
+        </el-form-item>
+
+                 <el-form-item label="鐘舵��" prop="status">
+           <el-radio-group v-model="form.status">
+             <el-radio value="active">鍚敤</el-radio>
+             <el-radio value="inactive">鍋滅敤</el-radio>
+           </el-radio-group>
+         </el-form-item>
+      </el-form>
+      
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="submitForm">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, onUnmounted } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+
+// 褰撳墠婵�娲荤殑鏍囩椤�
+const activeTab = ref('holiday')
+
+// 寮圭獥鐩稿叧
+const dialogVisible = ref(false)
+const dialogTitle = ref('')
+const currentType = ref('')
+const currentAction = ref('')
+const currentEditId = ref('')
+const formRef = ref()
+
+// 琛ㄥ崟鏁版嵁
+const form = reactive({
+  name: '',
+  type: '',
+  dateRange: [],
+  days: 0,
+  employeeType: '',
+  workYears: '',
+  annualDays: 0,
+  maxCarryOver: 0,
+  startTime: '', // 鍔犵彮寮�濮嬫椂闂�
+  endTime: '',   // 鍔犵彮缁撴潫鏃堕棿
+  workStartTime: '', // 涓婄彮鏃堕棿
+  workEndTime: '',   // 涓嬬彮鏃堕棿
+  rate: 1.5,
+  flexibleStart: false,
+  flexibleMinutes: 30,
+  status: 'active'
+})
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const rules = {
+  name: [{ required: true, message: '璇疯緭鍏ュ悕绉�', trigger: 'blur' }],
+  type: [{ required: true, message: '璇烽�夋嫨绫诲瀷', trigger: 'change' }],
+  dateRange: [{ required: true, message: '璇烽�夋嫨鏃ユ湡鑼冨洿', trigger: 'change' }],
+  days: [{ required: true, message: '璇疯緭鍏ュぉ鏁�', trigger: 'blur' }],
+  employeeType: [{ required: true, message: '璇烽�夋嫨鍛樺伐绫诲瀷', trigger: 'change' }],
+  workYears: [{ required: true, message: '璇疯緭鍏ュ伐浣滃勾闄�', trigger: 'blur' }],
+  annualDays: [{ required: true, message: '璇疯緭鍏ュ勾鍋囧ぉ鏁�', trigger: 'blur' }],
+  maxCarryOver: [{ required: true, message: '璇疯緭鍏ユ渶澶х粨杞ぉ鏁�', trigger: 'blur' }],
+  startTime: [{ 
+    required: true, 
+    message: '璇烽�夋嫨寮�濮嬫椂闂�', 
+    trigger: 'change',
+    validator: (rule, value, callback) => {
+      if (!value) {
+        callback(new Error('璇烽�夋嫨寮�濮嬫椂闂�'))
+      } else {
+        callback()
+      }
+    }
+  }],
+  endTime: [{ 
+    required: true, 
+    message: '璇烽�夋嫨缁撴潫鏃堕棿', 
+    trigger: 'change',
+    validator: (rule, value, callback) => {
+      if (!value) {
+        callback(new Error('璇烽�夋嫨缁撴潫鏃堕棿'))
+      } else {
+        callback()
+      }
+    }
+  }],
+  workStartTime: [{ 
+    required: true, 
+    message: '璇烽�夋嫨涓婄彮鏃堕棿', 
+    trigger: 'change',
+    validator: (rule, value, callback) => {
+      if (!value) {
+        callback(new Error('璇烽�夋嫨涓婄彮鏃堕棿'))
+      } else {
+        callback()
+      }
+    }
+  }],
+  workEndTime: [{ 
+    required: true, 
+    message: '璇烽�夋嫨涓嬬彮鏃堕棿', 
+    trigger: 'change',
+    validator: (rule, value, callback) => {
+      if (!value) {
+        callback(new Error('璇烽�夋嫨涓嬬彮鏃堕棿'))
+      } else {
+        callback()
+      }
+    }
+  }],
+  rate: [{ required: true, message: '璇疯緭鍏ュ�嶇巼', trigger: 'blur' }]
+}
+
+// 妯℃嫙鏁版嵁
+const holidayData = ref([
+  { id: '1', name: '鏄ヨ妭', type: 'legal', startDate: '2024-02-10', endDate: '2024-02-17', days: 8, status: 'active' },
+  { id: '2', name: '娓呮槑鑺�', type: 'legal', startDate: '2024-04-05', endDate: '2024-04-05', days: 1, status: 'active' },
+  { id: '3', name: '鍔冲姩鑺�', type: 'legal', startDate: '2024-05-01', endDate: '2024-05-05', days: 5, status: 'active' }
+])
+
+const annualData = ref([
+  { id: '1', employeeType: 'regular', workYears: '1-3骞�', annualDays: 5, maxCarryOver: 2, status: 'active' },
+  { id: '2', employeeType: 'regular', workYears: '3-5骞�', annualDays: 10, maxCarryOver: 5, status: 'active' },
+  { id: '3', employeeType: 'regular', workYears: '5骞翠互涓�', annualDays: 15, maxCarryOver: 10, status: 'active' }
+])
+
+const overtimeData = ref([
+  { id: '1', name: '宸ヤ綔鏃ュ姞鐝�', type: 'weekday', startTime: '18:00', endTime: '22:00', rate: 1.5, status: 'active' },
+  { id: '2', name: '鍛ㄦ湯鍔犵彮', type: 'weekend', startTime: '09:00', endTime: '18:00', rate: 2.0, status: 'active' },
+  { id: '3', name: '娣卞鍔犵彮', type: 'night', startTime: '22:00', endTime: '06:00', rate: 2.5, status: 'active' }
+])
+
+const worktimeData = ref([
+  { id: '1', name: '鏍囧噯宸ヤ綔鏃堕棿', startTime: '09:00', endTime: '18:00', flexibleStart: true, flexibleMinutes: 30, status: 'active' },
+  { id: '2', name: '鏃╃彮鏃堕棿', startTime: '08:00', endTime: '17:00', flexibleStart: false, flexibleMinutes: 0, status: 'active' },
+  { id: '3', name: '鏅氱彮鏃堕棿', startTime: '14:00', endTime: '23:00', flexibleStart: false, flexibleMinutes: 0, status: 'active' }
+])
+
+// 宸ュ叿鍑芥暟
+const getTagType = (type) => {
+  const tagMap = {
+    legal: 'success', adjustment: 'warning', special: 'info', company: 'primary',
+    weekday: 'primary', weekend: 'warning', holiday: 'danger', night: 'info'
+  }
+  return tagMap[type] || 'info'
+}
+
+const getTypeLabel = (type) => {
+  const labelMap = {
+    legal: '娉曞畾鑺傚亣鏃�', adjustment: '璋冧紤鏃�', special: '鐗规畩鍋囨湡', company: '鍏徃鍋囨湡',
+    weekday: '宸ヤ綔鏃ュ姞鐝�', weekend: '鍛ㄦ湯鍔犵彮', holiday: '鑺傚亣鏃ュ姞鐝�', night: '娣卞鍔犵彮'
+  }
+  return labelMap[type] || type
+}
+
+const getTypeOptions = () => {
+  if (currentType.value === 'holiday') {
+    return [
+      { label: '娉曞畾鑺傚亣鏃�', value: 'legal' },
+      { label: '璋冧紤鏃�', value: 'adjustment' },
+      { label: '鐗规畩鍋囨湡', value: 'special' },
+      { label: '鍏徃鍋囨湡', value: 'company' }
+    ]
+  } else if (currentType.value === 'overtime') {
+    return [
+      { label: '宸ヤ綔鏃ュ姞鐝�', value: 'weekday' },
+      { label: '鍛ㄦ湯鍔犵彮', value: 'weekend' },
+      { label: '鑺傚亣鏃ュ姞鐝�', value: 'holiday' },
+      { label: '娣卞鍔犵彮', value: 'night' }
+    ]
+  }
+  return []
+}
+
+// 璁$畻鍋囨湡澶╂暟
+const calculateDays = () => {
+  try {
+    if (form.dateRange && form.dateRange.length === 2 && form.dateRange[0] && form.dateRange[1]) {
+      const start = new Date(form.dateRange[0])
+      const end = new Date(form.dateRange[1])
+      
+      if (isNaN(start.getTime()) || isNaN(end.getTime())) {
+        console.warn('鏃犳晥鐨勬棩鏈熸牸寮�')
+        return
+      }
+      
+      const diffTime = Math.abs(end - start)
+      const diffDays = Math.ceil(diffTime / (1000 * 60 * 60 * 24)) + 1
+      form.days = diffDays
+    }
+  } catch (error) {
+    console.error('璁$畻澶╂暟澶辫触:', error)
+  }
+}
+
+// 楠岃瘉鏃堕棿鏍煎紡
+const validateTime = (time) => {
+  if (!time) return ''
+  if (typeof time === 'string') return time
+  if (time instanceof Date) {
+    return time.toTimeString().slice(0, 5)
+  }
+  return ''
+}
+
+// 楠岃瘉鏃堕棿瀛楁
+const validateTimeField = (fieldName) => {
+  try {
+    const value = form[fieldName]
+    if (value && typeof value === 'object' && value.hour !== undefined) {
+      // 濡傛灉鏄椂闂村璞★紝杞崲涓哄瓧绗︿覆鏍煎紡
+      const hours = value.hour.toString().padStart(2, '0')
+      const minutes = value.minute.toString().padStart(2, '0')
+      form[fieldName] = `${hours}:${minutes}`
+    }
+  } catch (error) {
+    console.error(`楠岃瘉鏃堕棿瀛楁 ${fieldName} 澶辫触:`, error)
+    form[fieldName] = ''
+  }
+}
+
+// 鎵撳紑寮圭獥
+const openDialog = (type, action, row = null) => {
+  try {
+    currentType.value = type
+    currentAction.value = action
+    
+    if (action === 'add') {
+      dialogTitle.value = `鏂板${getTypeName(type)}`
+      currentEditId.value = ''
+      resetForm()
+    } else if (action === 'edit' && row) {
+      dialogTitle.value = `缂栬緫${getTypeName(type)}`
+      currentEditId.value = row.id
+      fillForm(row)
+    }
+    
+    dialogVisible.value = true
+  } catch (error) {
+    console.error('鎵撳紑寮圭獥澶辫触:', error)
+    ElMessage.error('鎵撳紑寮圭獥澶辫触锛岃閲嶈瘯')
+  }
+}
+
+const getTypeName = (type) => {
+  const nameMap = {
+    holiday: '鍋囨湡',
+    annual: '骞村亣瑙勫垯',
+    overtime: '鍔犵彮瑙勫垯',
+    worktime: '鏃堕棿娈�'
+  }
+  return nameMap[type] || ''
+}
+
+const resetForm = () => {
+  Object.assign(form, {
+    name: '',
+    type: '',
+    dateRange: [],
+    days: 0,
+    employeeType: '',
+    workYears: '',
+    annualDays: 0,
+    maxCarryOver: 0,
+    startTime: '',
+    endTime: '',
+    workStartTime: '',
+    workEndTime: '',
+    rate: 1.5,
+    flexibleStart: false,
+    flexibleMinutes: 30,
+    status: 'active'
+  })
+}
+
+const fillForm = (row) => {
+  if (currentType.value === 'holiday') {
+    Object.assign(form, {
+      name: row.name,
+      type: row.type,
+      dateRange: [new Date(row.startDate), new Date(row.endDate)],
+      days: row.days,
+      status: row.status
+    })
+  } else if (currentType.value === 'annual') {
+    Object.assign(form, {
+      employeeType: row.employeeType,
+      workYears: row.workYears,
+      annualDays: row.annualDays,
+      maxCarryOver: row.maxCarryOver,
+      status: row.status
+    })
+  } else if (currentType.value === 'overtime') {
+    Object.assign(form, {
+      name: row.name,
+      type: row.type,
+      startTime: row.startTime || '',
+      endTime: row.endTime || '',
+      rate: row.rate,
+      status: row.status
+    })
+  } else if (currentType.value === 'worktime') {
+    Object.assign(form, {
+      name: row.name,
+      workStartTime: row.startTime || '',
+      workEndTime: row.endTime || '',
+      flexibleStart: row.flexibleStart,
+      flexibleMinutes: row.flexibleMinutes,
+      status: row.status
+    })
+  }
+}
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = async () => {
+  try {
+    if (!formRef.value) {
+      ElMessage.error('琛ㄥ崟寮曠敤涓嶅瓨鍦�')
+      return
+    }
+    
+    await formRef.value.validate()
+    
+    if (currentAction.value === 'add') {
+      addItem()
+    } else if (currentAction.value === 'edit') {
+      editItem()
+    }
+    
+    dialogVisible.value = false
+    ElMessage.success('鎿嶄綔鎴愬姛')
+  } catch (error) {
+    console.error('琛ㄥ崟楠岃瘉澶辫触:', error)
+    ElMessage.error('琛ㄥ崟楠岃瘉澶辫触锛岃妫�鏌ヨ緭鍏�')
+  }
+}
+
+const addItem = () => {
+  const newItem = { ...form, id: Date.now().toString() }
+  
+  if (currentType.value === 'holiday') {
+    newItem.startDate = form.dateRange[0].toISOString().split('T')[0]
+    newItem.endDate = form.dateRange[1].toISOString().split('T')[0]
+    holidayData.value.push(newItem)
+  } else if (currentType.value === 'annual') {
+    annualData.value.push(newItem)
+  } else if (currentType.value === 'overtime') {
+    newItem.startTime = form.startTime || ''
+    newItem.endTime = form.endTime || ''
+    overtimeData.value.push(newItem)
+  } else if (currentType.value === 'worktime') {
+    newItem.startTime = form.workStartTime || ''
+    newItem.endTime = form.workEndTime || ''
+    worktimeData.value.push(newItem)
+  }
+}
+
+const editItem = () => {
+  let dataArray
+  let index
+  
+  if (currentType.value === 'holiday') {
+    dataArray = holidayData.value
+    index = dataArray.findIndex(item => item.id === currentEditId.value)
+    if (index > -1) {
+      dataArray[index] = { 
+        ...dataArray[index],
+        name: form.name,
+        type: form.type,
+        startDate: form.dateRange[0].toISOString().split('T')[0],
+        endDate: form.dateRange[1].toISOString().split('T')[0],
+        days: form.days,
+        status: form.status
+      }
+    }
+  } else if (currentType.value === 'annual') {
+    dataArray = annualData.value
+    index = dataArray.findIndex(item => item.id === currentEditId.value)
+    if (index > -1) {
+      dataArray[index] = { 
+        ...dataArray[index],
+        employeeType: form.employeeType,
+        workYears: form.workYears,
+        annualDays: form.annualDays,
+        maxCarryOver: form.maxCarryOver,
+        status: form.status
+      }
+    }
+  } else if (currentType.value === 'overtime') {
+    dataArray = overtimeData.value
+    index = dataArray.findIndex(item => item.id === currentEditId.value)
+    if (index > -1) {
+      dataArray[index] = { 
+        ...dataArray[index],
+        name: form.name,
+        type: form.type,
+        startTime: form.startTime || '',
+        endTime: form.endTime || '',
+        rate: form.rate,
+        status: form.status
+      }
+    }
+  } else if (currentType.value === 'worktime') {
+    dataArray = worktimeData.value
+    index = dataArray.findIndex(item => item.id === currentEditId.value)
+    if (index > -1) {
+      dataArray[index] = { 
+        ...dataArray[index],
+        name: form.name,
+        startTime: form.workStartTime || '',
+        endTime: form.workEndTime || '',
+        flexibleStart: form.flexibleStart,
+        flexibleMinutes: form.flexibleMinutes,
+        status: form.status
+      }
+    }
+  }
+}
+
+// 鍒犻櫎椤圭洰
+const deleteItem = (type, row) => {
+  ElMessageBox.confirm('纭畾瑕佸垹闄よ繖涓」鐩悧锛�', '鎻愮ず', {
+    confirmButtonText: '纭畾',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning'
+  }).then(() => {
+    let dataArray
+    if (type === 'holiday') dataArray = holidayData.value
+    else if (type === 'annual') dataArray = annualData.value
+    else if (type === 'overtime') dataArray = overtimeData.value
+    else if (type === 'worktime') dataArray = worktimeData.value
+    
+    const index = dataArray.findIndex(item => item.id === row.id)
+    if (index > -1) {
+      dataArray.splice(index, 1)
+      ElMessage.success('鍒犻櫎鎴愬姛')
+    }
+  })
+}
+
+onMounted(() => {
+  console.log('鑰冨嫟绠$悊椤甸潰鍔犺浇瀹屾垚')
+})
+
+onUnmounted(() => {
+  // 娓呯悊宸ヤ綔
+  dialogVisible.value = false
+  currentType.value = ''
+  currentAction.value = ''
+  currentEditId.value = ''
+})
+</script>
+
+<style scoped>
+.app-container {
+  padding: 20px;
+}
+
+.tab-content {
+  padding: 20px 0;
+}
+
+.dialog-footer {
+  text-align: right;
+}
+
+:deep(.el-tabs__content) {
+  padding: 20px;
+}
+
+:deep(.el-form-item) {
+  margin-bottom: 20px;
+}
+</style>
diff --git a/src/views/collaborativeApproval/knowledgeBase/index.vue b/src/views/collaborativeApproval/knowledgeBase/index.vue
new file mode 100644
index 0000000..f944859
--- /dev/null
+++ b/src/views/collaborativeApproval/knowledgeBase/index.vue
@@ -0,0 +1,848 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <div>
+        <span class="search_title">鐭ヨ瘑鏍囬锛�</span>
+        <el-input
+          v-model="searchForm.title"
+          style="width: 240px"
+          placeholder="璇疯緭鍏ョ煡璇嗘爣棰樻悳绱�"
+          @change="handleQuery"
+          clearable
+          :prefix-icon="Search"
+        />
+        <span class="search_title ml10">鐭ヨ瘑绫诲瀷锛�</span>
+        <el-select v-model="searchForm.type" clearable @change="handleQuery" style="width: 240px">
+          <el-option label="鍚堝悓鐗规壒" :value="'contract'" />
+          <el-option label="瀹℃壒妗堜緥" :value="'approval'" />
+          <el-option label="瑙e喅鏂规" :value="'solution'" />
+          <el-option label="缁忛獙鎬荤粨" :value="'experience'" />
+          <el-option label="鎿嶄綔鎸囧崡" :value="'guide'" />
+        </el-select>
+        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">
+          鎼滅储
+        </el-button>
+      </div>
+      <div>
+        <el-button type="primary" @click="openForm('add')">鏂板鐭ヨ瘑</el-button>
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+      </div>
+    </div>
+    
+    <div class="table_list">
+      <PIMTable
+        rowKey="id"
+        :column="tableColumn"
+        :tableData="tableData"
+        :page="page"
+        :isSelection="true"
+        @selection-change="handleSelectionChange"
+        :tableLoading="tableLoading"
+        @pagination="pagination"
+        :total="page.total"
+      ></PIMTable>
+    </div>
+
+    <!-- 鏂板/缂栬緫鐭ヨ瘑寮圭獥 -->
+    <el-dialog
+      v-model="dialogVisible"
+      :title="dialogTitle"
+      width="800px"
+      :close-on-click-modal="false"
+    >
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鐭ヨ瘑鏍囬" prop="title">
+              <el-input v-model="form.title" placeholder="璇疯緭鍏ョ煡璇嗘爣棰�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐭ヨ瘑绫诲瀷" prop="type">
+              <el-select v-model="form.type" placeholder="璇烽�夋嫨鐭ヨ瘑绫诲瀷" style="width: 100%">
+                <el-option label="鍚堝悓鐗规壒" value="contract" />
+                <el-option label="瀹℃壒妗堜緥" value="approval" />
+                <el-option label="瑙e喅鏂规" value="solution" />
+                <el-option label="缁忛獙鎬荤粨" value="experience" />
+                <el-option label="鎿嶄綔鎸囧崡" value="guide" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閫傜敤鍦烘櫙" prop="scenario">
+              <el-input v-model="form.scenario" placeholder="璇疯緭鍏ラ�傜敤鍦烘櫙" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瑙e喅鏁堢巼" prop="efficiency">
+              <el-select v-model="form.efficiency" placeholder="璇烽�夋嫨瑙e喅鏁堢巼" style="width: 100%">
+                <el-option label="鏄捐憲鎻愬崌" value="high" />
+                <el-option label="涓�鑸彁鍗�" value="medium" />
+                <el-option label="杞诲井鎻愬崌" value="low" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="闂鎻忚堪" prop="problem">
+          <el-input
+            v-model="form.problem"
+            type="textarea"
+            :rows="3"
+            placeholder="璇锋弿杩伴亣鍒扮殑闂"
+          />
+        </el-form-item>
+        <el-form-item label="瑙e喅鏂规" prop="solution">
+          <el-input
+            v-model="form.solution"
+            type="textarea"
+            :rows="4"
+            placeholder="璇疯缁嗘弿杩拌В鍐虫柟妗�"
+          />
+        </el-form-item>
+        <el-form-item label="鍏抽敭瑕佺偣" prop="keyPoints">
+          <el-input
+            v-model="form.keyPoints"
+            type="textarea"
+            :rows="3"
+            placeholder="璇疯緭鍏ュ叧閿鐐癸紝鐢ㄩ�楀彿鍒嗛殧"
+          />
+        </el-form-item>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鍒涘缓浜�" prop="creator">
+              <el-input v-model="form.creator" placeholder="璇疯緭鍏ュ垱寤轰汉" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="浣跨敤娆℃暟" prop="usageCount">
+              <el-input-number v-model="form.usageCount" :min="0" style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="submitForm">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 鏌ョ湅鐭ヨ瘑璇︽儏寮圭獥 -->
+    <el-dialog
+      v-model="viewDialogVisible"
+      title="鐭ヨ瘑璇︽儏"
+      width="900px"
+      :close-on-click-modal="false"
+    >
+      <div class="knowledge-detail">
+        <el-descriptions :column="2" border>
+          <el-descriptions-item label="鐭ヨ瘑鏍囬" :span="2">
+            <span class="detail-title">{{ currentKnowledge.title }}</span>
+          </el-descriptions-item>
+          <el-descriptions-item label="鐭ヨ瘑绫诲瀷">
+            <el-tag :type="getTypeTagType(currentKnowledge.type)">
+              {{ getTypeLabel(currentKnowledge.type) }}
+            </el-tag>
+          </el-descriptions-item>
+          <el-descriptions-item label="閫傜敤鍦烘櫙">
+            {{ currentKnowledge.scenario }}
+          </el-descriptions-item>
+          <el-descriptions-item label="瑙e喅鏁堢巼">
+            <el-tag :type="getEfficiencyTagType(currentKnowledge.efficiency)">
+              {{ getEfficiencyLabel(currentKnowledge.efficiency) }}
+            </el-tag>
+          </el-descriptions-item>
+          <el-descriptions-item label="浣跨敤娆℃暟">
+            <el-tag type="info">{{ currentKnowledge.usageCount }} 娆�</el-tag>
+          </el-descriptions-item>
+          <el-descriptions-item label="鍒涘缓浜�">
+            {{ currentKnowledge.creator }}
+          </el-descriptions-item>
+          <el-descriptions-item label="鍒涘缓鏃堕棿">
+            {{ currentKnowledge.createTime }}
+          </el-descriptions-item>
+        </el-descriptions>
+
+        <div class="detail-section">
+          <h4>闂鎻忚堪</h4>
+          <div class="detail-content">{{ currentKnowledge.problem }}</div>
+        </div>
+
+        <div class="detail-section">
+          <h4>瑙e喅鏂规</h4>
+          <div class="detail-content">{{ currentKnowledge.solution }}</div>
+        </div>
+
+        <div class="detail-section">
+          <h4>鍏抽敭瑕佺偣</h4>
+          <div class="key-points">
+            <el-tag
+              v-for="(point, index) in currentKnowledge.keyPoints.split(',')"
+              :key="index"
+              type="success"
+              style="margin-right: 8px; margin-bottom: 8px;"
+            >
+              {{ point.trim() }}
+            </el-tag>
+          </div>
+        </div>
+
+        <div class="detail-section">
+          <h4>浣跨敤缁熻</h4>
+          <div class="usage-stats">
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <div class="stat-item">
+                  <div class="stat-number">{{ currentKnowledge.usageCount }}</div>
+                  <div class="stat-label">浣跨敤娆℃暟</div>
+                </div>
+              </el-col>
+              <el-col :span="8">
+                <div class="stat-item">
+                  <div class="stat-number">{{ getEfficiencyScore(currentKnowledge.efficiency) }}%</div>
+                  <div class="stat-label">鏁堢巼鎻愬崌</div>
+                </div>
+              </el-col>
+              <el-col :span="8">
+                <div class="stat-item">
+                  <div class="stat-number">{{ getTimeSaved(currentKnowledge.efficiency) }}</div>
+                  <div class="stat-label">骞冲潎鑺傜渷鏃堕棿</div>
+                </div>
+              </el-col>
+            </el-row>
+          </div>
+        </div>
+      </div>
+
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="viewDialogVisible = false">鍏抽棴</el-button>
+          <el-button type="primary" @click="copyKnowledge">澶嶅埗鐭ヨ瘑</el-button>
+          <el-button type="success" @click="markAsFavorite">鏀惰棌</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { Search } from "@element-plus/icons-vue";
+import { onMounted, ref, reactive, toRefs } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import PIMTable from "@/components/PIMTable/PIMTable.vue";
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const rules = {
+  title: [
+    { required: true, message: "璇疯緭鍏ョ煡璇嗘爣棰�", trigger: "blur" }
+  ],
+  type: [
+    { required: true, message: "璇烽�夋嫨鐭ヨ瘑绫诲瀷", trigger: "change" }
+  ],
+  problem: [
+    { required: true, message: "璇锋弿杩伴亣鍒扮殑闂", trigger: "blur" }
+  ],
+  solution: [
+    { required: true, message: "璇疯缁嗘弿杩拌В鍐虫柟妗�", trigger: "blur" }
+  ]
+};
+
+// 鍝嶅簲寮忔暟鎹�
+const data = reactive({
+  searchForm: {
+    title: "",
+    type: "",
+  },
+  tableLoading: false,
+  page: {
+    current: 1,
+    size: 100,
+    total: 0,
+  },
+  tableData: [],
+  selectedIds: [],
+  form: {
+    title: "",
+    type: "",
+    scenario: "",
+    efficiency: "medium",
+    problem: "",
+    solution: "",
+    keyPoints: "",
+    creator: "",
+    usageCount: 0
+  },
+  dialogVisible: false,
+  dialogTitle: "",
+  dialogType: "add",
+  viewDialogVisible: false,
+  currentKnowledge: {}
+});
+
+const { 
+  searchForm, 
+  tableLoading, 
+  page, 
+  tableData, 
+  selectedIds,
+  form,
+  dialogVisible,
+  dialogTitle,
+  dialogType,
+  viewDialogVisible,
+  currentKnowledge
+} = toRefs(data);
+
+// 琛ㄥ崟寮曠敤
+const formRef = ref();
+
+// 琛ㄦ牸鍒楅厤缃�
+const tableColumn = ref([
+  {
+    label: "鐭ヨ瘑鏍囬",
+    prop: "title",
+    showOverflowTooltip: true,
+  },
+  {
+    label: "鐭ヨ瘑绫诲瀷",
+    prop: "type",
+    dataType: "tag",
+    formatData: (params) => {
+      const typeMap = {
+        contract: "鍚堝悓鐗规壒",
+        approval: "瀹℃壒妗堜緥",
+        solution: "瑙e喅鏂规",
+        experience: "缁忛獙鎬荤粨",
+        guide: "鎿嶄綔鎸囧崡"
+      };
+      return typeMap[params] || params;
+    },
+    formatType: (params) => {
+      const typeMap = {
+        contract: "success",
+        approval: "warning",
+        solution: "primary",
+        experience: "info",
+        guide: "danger"
+      };
+      return typeMap[params] || "info";
+    }
+  },
+  {
+    label: "閫傜敤鍦烘櫙",
+    prop: "scenario",
+    width: 150,
+    showOverflowTooltip: true,
+  },
+  {
+    label: "瑙e喅鏁堢巼",
+    prop: "efficiency",
+    dataType: "tag",
+    formatData: (params) => {
+      const efficiencyMap = {
+        high: "鏄捐憲鎻愬崌",
+        medium: "涓�鑸彁鍗�",
+        low: "杞诲井鎻愬崌"
+      };
+      return efficiencyMap[params] || params;
+    },
+    formatType: (params) => {
+      const typeMap = {
+        high: "success",
+        medium: "warning",
+        low: "info"
+      };
+      return typeMap[params] || "info";
+    }
+  },
+  {
+    label: "浣跨敤娆℃暟",
+    prop: "usageCount",
+    width: 100,
+    align: "center"
+  },
+  {
+    label: "鍒涘缓浜�",
+    prop: "creator",
+    width: 120,
+  },
+  {
+    label: "鍒涘缓鏃堕棿",
+    prop: "createTime",
+    width: 180,
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: "right",
+    width: 200,
+    operation: [
+      {
+        name: "缂栬緫",
+        type: "text",
+        clickFun: (row) => {
+          openForm("edit", row);
+        }
+      },
+      {
+        name: "鏌ョ湅",
+        type: "text",
+        clickFun: (row) => {
+          viewKnowledge(row);
+        }
+      }
+    ]
+  }
+]);
+
+// 妯℃嫙鏁版嵁
+let mockData = [
+  {
+    id: "1",
+    title: "鐗规畩鍚堝悓瀹℃壒娴佺▼浼樺寲鏂规",
+    type: "contract",
+    scenario: "澶ч鍚堝悓蹇�熷鎵�",
+    efficiency: "high",
+    problem: "澶ч鍚堝悓瀹℃壒娴佺▼澶嶆潅锛屽鎵规椂闂撮暱锛屽奖鍝嶄笟鍔¤繘灞�",
+    solution: "寤虹珛缁胯壊閫氶亾锛屽绗﹀悎鏉′欢鐨勫悎鍚岄噰鐢ㄧ畝鍖栧鎵规祦绋嬶紝鐢遍儴闂ㄨ礋璐d汉鐩存帴瀹℃壒锛屽钩鍧囧鎵规椂闂翠粠3澶╃缉鐭嚦1澶�",
+    keyPoints: "缁胯壊閫氶亾鏉′欢,绠�鍖栨祦绋�,瀹℃壒鏉冮檺,鏃堕棿鎺у埗",
+    creator: "寮犵粡鐞�",
+    usageCount: 15,
+    createTime: "2024-01-15 10:30:00"
+  },
+  {
+    id: "2",
+    title: "璺ㄩ儴闂ㄥ崗浣滃鎵圭粡楠屾�荤粨",
+    type: "experience",
+    scenario: "澶氶儴闂ㄥ崗浣滈」鐩�",
+    efficiency: "medium",
+    problem: "璺ㄩ儴闂ㄩ」鐩鎵规椂锛屽悇閮ㄩ棬鎰忚涓嶇粺涓�锛屽鎵硅繘搴︾紦鎱�",
+    solution: "寤虹珛椤圭洰鍗忚皟鏈哄埗锛屾寚瀹氶」鐩礋璐d汉锛屽畾鏈熷彫寮�鍗忚皟浼氳锛岀粺涓�鍚勬柟鎰忚鍚庡啀杩涜瀹℃壒",
+    keyPoints: "椤圭洰鍗忚皟,瀹氭湡浼氳,缁熶竴鎰忚,璐熻矗浜哄埗搴�",
+    creator: "鏉庝富绠�",
+    usageCount: 8,
+    createTime: "2024-01-14 15:20:00"
+  },
+  {
+    id: "3",
+    title: "绱ф�ラ噰璐鎵规搷浣滄寚鍗�",
+    type: "guide",
+    scenario: "绱ф�ラ噰璐渶姹�",
+    efficiency: "high",
+    problem: "绱ф�ラ噰璐椂瀹℃壒娴佺▼澶嶆潅锛屾棤娉曟弧瓒崇揣鎬ラ渶姹�",
+    solution: "鍒跺畾绱ф�ラ噰璐鎵规爣鍑嗭紝鏄庣‘绱ф�ョ▼搴﹀垎绾э紝涓嶅悓绾у埆閲囩敤涓嶅悓瀹℃壒娴佺▼锛岀‘淇濈揣鎬ラ渶姹傚緱鍒板強鏃跺鐞�",
+    keyPoints: "绱ф�ュ垎绾�,鏍囧噯鍒跺畾,娴佺▼绠�鍖�,鍙婃椂澶勭悊",
+    creator: "鐜嬩笓鍛�",
+    usageCount: 12,
+    createTime: "2024-01-13 09:15:00"
+  }
+];
+
+// 鐭ヨ瘑鏍囬妯℃澘
+const titleTemplates = [
+  "{type}瀹℃壒娴佺▼浼樺寲鏂规",
+  "{scenario}澶勭悊缁忛獙鎬荤粨",
+  "{type}鐗规畩鎯呭喌澶勭悊鎸囧崡",
+  "{scenario}蹇�熷鎵规柟妗�",
+  "{type}鏍囧噯鍖栨搷浣滄祦绋�",
+  "{scenario}闂瑙e喅鏂规",
+  "{type}鏈�浣冲疄璺垫�荤粨",
+  "{scenario}鏁堢巼鎻愬崌鏂规"
+];
+
+// 鐭ヨ瘑绫诲瀷閰嶇疆
+const knowledgeTypes = [
+  { type: "contract", label: "鍚堝悓鐗规壒", efficiency: "high" },
+  { type: "approval", label: "瀹℃壒妗堜緥", efficiency: "medium" },
+  { type: "solution", label: "瑙e喅鏂规", efficiency: "high" },
+  { type: "experience", label: "缁忛獙鎬荤粨", efficiency: "medium" },
+  { type: "guide", label: "鎿嶄綔鎸囧崡", efficiency: "low" }
+];
+
+// 鍦烘櫙鍒楄〃
+const scenarios = ["澶ч鍚堝悓瀹℃壒", "璺ㄩ儴闂ㄥ崗浣�", "绱ф�ラ噰璐�", "鐗规畩鐢宠", "娴佺▼浼樺寲", "闂澶勭悊", "鏍囧噯鍖栧缓璁�", "鏁堢巼鎻愬崌"];
+
+// 鑷姩鐢熸垚鏂版暟鎹�
+const generateNewData = () => {
+  const newId = (mockData.length + 1).toString();
+  const now = new Date();
+  const randomType = knowledgeTypes[Math.floor(Math.random() * knowledgeTypes.length)];
+  const randomScenario = scenarios[Math.floor(Math.random() * scenarios.length)];
+  
+  // 鐢熸垚闅忔満鏍囬
+  let title = titleTemplates[Math.floor(Math.random() * titleTemplates.length)];
+  title = title
+    .replace('{type}', randomType.label)
+    .replace('{scenario}', randomScenario);
+  
+  const newKnowledge = {
+    id: newId,
+    title: title,
+    type: randomType.type,
+    scenario: randomScenario,
+    efficiency: randomType.efficiency,
+    problem: `鍦�${randomScenario}杩囩▼涓亣鍒扮殑闂鎻忚堪...`,
+    solution: `閽堝${randomScenario}鐨勮В鍐虫柟妗堝拰鎿嶄綔姝ラ...`,
+    keyPoints: "鍏抽敭瑕佺偣1,鍏抽敭瑕佺偣2,鍏抽敭瑕佺偣3,鍏抽敭瑕佺偣4",
+    creator: ["寮犵粡鐞�", "鏉庝富绠�", "鐜嬩笓鍛�", "鍒樻�荤洃"][Math.floor(Math.random() * 4)],
+    usageCount: Math.floor(Math.random() * 20) + 1,
+    createTime: now.toLocaleString()
+  };
+  
+  // 娣诲姞鍒版暟鎹紑澶�
+  mockData.unshift(newKnowledge);
+  
+  // 淇濇寔鏁版嵁閲忓湪鍚堢悊鑼冨洿鍐咃紙鏈�澶氫繚鐣�30鏉★級
+  if (mockData.length > 30) {
+    mockData = mockData.slice(0, 30);
+  }
+  
+  console.log(`[${new Date().toLocaleString()}] 鑷姩鐢熸垚鏂扮煡璇�: ${title}`);
+};
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+  getList();
+  startAutoRefresh();
+});
+
+// 寮�濮嬭嚜鍔ㄥ埛鏂�
+const startAutoRefresh = () => {
+  setInterval(() => {
+    generateNewData();
+    getList();
+  }, 600000); // 10鍒嗛挓鍒锋柊涓�娆� (10 * 60 * 1000 = 600000ms)
+};
+
+// 鏌ヨ鏁版嵁
+const handleQuery = () => {
+  page.value.current = 1;
+  getList();
+};
+
+const getList = () => {
+  tableLoading.value = true;
+  
+  setTimeout(() => {
+    let filteredData = [...mockData];
+    
+    if (searchForm.value.title) {
+      filteredData = filteredData.filter(item => 
+        item.title.toLowerCase().includes(searchForm.value.title.toLowerCase())
+      );
+    }
+    
+    if (searchForm.value.type) {
+      filteredData = filteredData.filter(item => item.type === searchForm.value.type);
+    }
+    
+    tableData.value = filteredData;
+    page.value.total = filteredData.length;
+    tableLoading.value = false;
+  }, 500);
+};
+
+// 鍒嗛〉澶勭悊
+const pagination = (obj) => {
+  page.value.current = obj.page;
+  page.value.size = obj.limit;
+  handleQuery();
+};
+
+// 閫夋嫨鍙樺寲澶勭悊
+const handleSelectionChange = (selection) => {
+  selectedIds.value = selection.map(item => item.id);
+};
+
+// 鎵撳紑琛ㄥ崟
+const openForm = (type, row = null) => {
+  dialogType.value = type;
+  if (type === "add") {
+    dialogTitle.value = "鏂板鐭ヨ瘑";
+    // 閲嶇疆琛ㄥ崟
+    Object.assign(form.value, {
+      title: "",
+      type: "",
+      scenario: "",
+      efficiency: "medium",
+      problem: "",
+      solution: "",
+      keyPoints: "",
+      creator: "",
+      usageCount: 0
+    });
+  } else if (type === "edit" && row) {
+    dialogTitle.value = "缂栬緫鐭ヨ瘑";
+    Object.assign(form.value, {
+      title: row.title,
+      type: row.type,
+      scenario: row.scenario,
+      efficiency: row.efficiency,
+      problem: row.problem,
+      solution: row.solution,
+      keyPoints: row.keyPoints,
+      creator: row.creator,
+      usageCount: row.usageCount
+    });
+  }
+  dialogVisible.value = true;
+};
+
+// 鏌ョ湅鐭ヨ瘑璇︽儏
+const viewKnowledge = (row) => {
+  currentKnowledge.value = { ...row };
+  viewDialogVisible.value = true;
+};
+
+// 鑾峰彇绫诲瀷鏍囩绫诲瀷
+const getTypeTagType = (type) => {
+  const typeMap = {
+    contract: "success",
+    approval: "warning",
+    solution: "primary",
+    experience: "info",
+    guide: "danger"
+  };
+  return typeMap[type] || "info";
+};
+
+// 鑾峰彇绫诲瀷鏍囩鏂囨湰
+const getTypeLabel = (type) => {
+  const typeMap = {
+    contract: "鍚堝悓鐗规壒",
+    approval: "瀹℃壒妗堜緥",
+    solution: "瑙e喅鏂规",
+    experience: "缁忛獙鎬荤粨",
+    guide: "鎿嶄綔鎸囧崡"
+  };
+  return typeMap[type] || type;
+};
+
+// 鑾峰彇鏁堢巼鏍囩绫诲瀷
+const getEfficiencyTagType = (efficiency) => {
+  const typeMap = {
+    high: "success",
+    medium: "warning",
+    low: "info"
+  };
+  return typeMap[efficiency] || "info";
+};
+
+// 鑾峰彇鏁堢巼鏍囩鏂囨湰
+const getEfficiencyLabel = (efficiency) => {
+  const efficiencyMap = {
+    high: "鏄捐憲鎻愬崌",
+    medium: "涓�鑸彁鍗�",
+    low: "杞诲井鎻愬崌"
+  };
+  return efficiencyMap[efficiency] || efficiency;
+};
+
+// 鑾峰彇鏁堢巼鎻愬崌鐧惧垎姣�
+const getEfficiencyScore = (efficiency) => {
+  const scoreMap = {
+    high: 40,
+    medium: 25,
+    low: 15
+  };
+  return scoreMap[efficiency] || 0;
+};
+
+// 鑾峰彇骞冲潎鑺傜渷鏃堕棿
+const getTimeSaved = (efficiency) => {
+  const timeMap = {
+    high: "2-3澶�",
+    medium: "1-2澶�",
+    low: "0.5-1澶�"
+  };
+  return timeMap[efficiency] || "鏈煡";
+};
+
+// 澶嶅埗鐭ヨ瘑
+const copyKnowledge = () => {
+  const knowledgeText = `
+鐭ヨ瘑鏍囬锛�${currentKnowledge.value.title}
+鐭ヨ瘑绫诲瀷锛�${getTypeLabel(currentKnowledge.value.type)}
+閫傜敤鍦烘櫙锛�${currentKnowledge.value.scenario}
+闂鎻忚堪锛�${currentKnowledge.value.problem}
+瑙e喅鏂规锛�${currentKnowledge.value.solution}
+鍏抽敭瑕佺偣锛�${currentKnowledge.value.keyPoints}
+鍒涘缓浜猴細${currentKnowledge.value.creator}
+  `.trim();
+  
+  // 澶嶅埗鍒板壀璐存澘
+  navigator.clipboard.writeText(knowledgeText).then(() => {
+    ElMessage.success("鐭ヨ瘑鍐呭宸插鍒跺埌鍓创鏉�");
+  }).catch(() => {
+    ElMessage.error("澶嶅埗澶辫触锛岃鎵嬪姩澶嶅埗");
+  });
+};
+
+// 鏀惰棌鐭ヨ瘑
+const markAsFavorite = () => {
+  // 澧炲姞浣跨敤娆℃暟
+  const index = mockData.findIndex(item => item.id === currentKnowledge.value.id);
+  if (index !== -1) {
+    mockData[index].usageCount += 1;
+    currentKnowledge.value.usageCount += 1;
+  }
+  
+  ElMessage.success("宸叉敹钘忥紝浣跨敤娆℃暟+1");
+};
+
+// 鎻愪氦鐭ヨ瘑琛ㄥ崟
+const submitForm = async () => {
+  try {
+    await formRef.value.validate();
+    
+    if (dialogType.value === "add") {
+      // 鏂板鐭ヨ瘑
+      const newKnowledge = {
+        id: (mockData.length + 1).toString(),
+        title: form.value.title,
+        type: form.value.type,
+        scenario: form.value.scenario,
+        efficiency: form.value.efficiency,
+        problem: form.value.problem,
+        solution: form.value.solution,
+        keyPoints: form.value.keyPoints,
+        creator: form.value.creator,
+        usageCount: form.value.usageCount,
+        createTime: new Date().toLocaleString()
+      };
+      
+      mockData.unshift(newKnowledge);
+      ElMessage.success("鐭ヨ瘑鍒涘缓鎴愬姛");
+    } else {
+      // 缂栬緫鐭ヨ瘑
+      const index = mockData.findIndex(item => item.id === selectedIds.value[0]);
+      if (index !== -1) {
+        Object.assign(mockData[index], {
+          title: form.value.title,
+          type: form.value.type,
+          scenario: form.value.scenario,
+          efficiency: form.value.efficiency,
+          problem: form.value.problem,
+          solution: form.value.solution,
+          keyPoints: form.value.keyPoints,
+          creator: form.value.creator,
+          usageCount: form.value.usageCount
+        });
+        ElMessage.success("鐭ヨ瘑鏇存柊鎴愬姛");
+      }
+    }
+    
+    dialogVisible.value = false;
+    getList();
+  } catch (error) {
+    console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+  }
+};
+
+// 鍒犻櫎鐭ヨ瘑
+const handleDelete = () => {
+  if (selectedIds.value.length === 0) {
+    ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑鐭ヨ瘑");
+    return;
+  }
+  
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    // 浠巑ockData涓垹闄ら�変腑鐨勯」
+    selectedIds.value.forEach(id => {
+      const index = mockData.findIndex(item => item.id === id);
+      if (index !== -1) {
+        mockData.splice(index, 1);
+      }
+    });
+    
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    selectedIds.value = [];
+    getList();
+  }).catch(() => {
+    // 鐢ㄦ埛鍙栨秷
+  });
+};
+</script>
+
+<style scoped>
+.auto-refresh-info {
+  margin-bottom: 15px;
+}
+
+.auto-refresh-info .el-alert {
+  border-radius: 8px;
+}
+
+.dialog-footer {
+  text-align: right;
+}
+
+.knowledge-detail {
+  padding: 20px 0;
+}
+
+.detail-title {
+  font-size: 18px;
+  font-weight: bold;
+  color: #303133;
+}
+
+.detail-section {
+  margin-top: 24px;
+}
+
+.detail-section h4 {
+  margin: 0 0 12px 0;
+  font-size: 16px;
+  font-weight: 600;
+  color: #303133;
+  border-left: 4px solid #409eff;
+  padding-left: 12px;
+}
+
+.detail-content {
+  background: #f8f9fa;
+  padding: 16px;
+  border-radius: 6px;
+  line-height: 1.6;
+  color: #606266;
+  white-space: pre-wrap;
+}
+
+.key-points {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 8px;
+}
+
+.usage-stats {
+  margin-top: 16px;
+}
+
+.stat-item {
+  text-align: center;
+  padding: 20px;
+  background: #f8f9fa;
+  border-radius: 8px;
+}
+
+.stat-number {
+  font-size: 24px;
+  font-weight: bold;
+  color: #409eff;
+  margin-bottom: 8px;
+}
+
+.stat-label {
+  font-size: 14px;
+  color: #909399;
+}
+</style>
diff --git a/src/views/collaborativeApproval/meetingBoard/index.vue b/src/views/collaborativeApproval/meetingBoard/index.vue
new file mode 100644
index 0000000..63c74f9
--- /dev/null
+++ b/src/views/collaborativeApproval/meetingBoard/index.vue
@@ -0,0 +1,498 @@
+<template>
+  <div class="app-container">
+    <!-- 椤甸潰鏍囬 -->
+    <div class="page-header">
+      <h2>浼氳鐪嬫澘</h2>
+<!--      <el-button type="primary" @click="createMeeting">鍒涘缓浼氳</el-button>-->
+    </div>
+
+    <!-- 浼氳缁熻鍗$墖 -->
+    <div class="stats-cards">
+      <el-card class="stat-card">
+        <div class="stat-content">
+          <div class="stat-number">{{ stats.total }}</div>
+          <div class="stat-label">鎬讳細璁暟</div>
+        </div>
+      </el-card>
+      <el-card class="stat-card">
+        <div class="stat-content">
+          <div class="stat-number">{{ stats.ongoing }}</div>
+          <div class="stat-label">杩涜涓�</div>
+        </div>
+      </el-card>
+      <el-card class="stat-card">
+        <div class="stat-content">
+          <div class="stat-number">{{ stats.completed }}</div>
+          <div class="stat-label">宸插畬鎴�</div>
+        </div>
+      </el-card>
+      <el-card class="stat-card">
+        <div class="stat-content">
+          <div class="stat-number">{{ stats.upcoming }}</div>
+          <div class="stat-label">鍗冲皢寮�濮�</div>
+        </div>
+      </el-card>
+    </div>
+
+    <!-- 浼氳鍒楄〃 -->
+    <div class="meeting-list">
+      <el-card v-for="meeting in meetings" :key="meeting.id" class="meeting-card">
+        <div class="meeting-header">
+          <div class="meeting-title">
+            <h3>{{ meeting.title }}</h3>
+            <el-tag :type="getStatusType(meeting.status)" size="small">
+              {{ getStatusText(meeting.status) }}
+            </el-tag>
+          </div>
+          <div class="meeting-time">
+            <el-icon><Clock /></el-icon>
+            {{ formatTime(meeting.startTime) }} - {{ formatTime(meeting.endTime) }}
+          </div>
+        </div>
+        
+        <div class="meeting-info">
+          <div class="info-item">
+            <el-icon><Location /></el-icon>
+            <span>{{ meeting.location }}</span>
+          </div>
+          <div class="info-item">
+            <el-icon><User /></el-icon>
+            <span>涓绘寔浜�: {{ meeting.host }}</span>
+          </div>
+          <div class="info-item">
+            <el-icon><UserFilled /></el-icon>
+            <span>鍙備細浜烘暟: {{ meeting.participants.length }}浜�</span>
+          </div>
+        </div>
+
+        <div class="meeting-agenda">
+          <h4>璁▼瀹夋帓</h4>
+          <div class="agenda-list">
+            <div 
+              v-for="(agenda, index) in meeting.agenda" 
+              :key="index"
+              class="agenda-item"
+              :class="{ 'active': agenda.status === 'active', 'completed': agenda.status === 'completed' }"
+            >
+              <span class="agenda-time">{{ agenda.time }}</span>
+              <span class="agenda-content">{{ agenda.content }}</span>
+              <el-tag 
+                :type="getAgendaStatusType(agenda.status)" 
+                size="small"
+              >
+                {{ getAgendaStatusText(agenda.status) }}
+              </el-tag>
+            </div>
+          </div>
+        </div>
+
+<!--        <div class="meeting-actions">-->
+<!--          <el-button type="primary" size="small" @click="joinMeeting(meeting)">-->
+<!--            鍔犲叆浼氳-->
+<!--          </el-button>-->
+<!--          <el-button type="info" size="small" @click="viewDetails(meeting)">-->
+<!--            鏌ョ湅璇︽儏-->
+<!--          </el-button>-->
+<!--          <el-button type="warning" size="small" @click="editMeeting(meeting)">-->
+<!--            缂栬緫-->
+<!--          </el-button>-->
+<!--        </div>-->
+      </el-card>
+    </div>
+
+    <!-- 鍒涘缓浼氳瀵硅瘽妗� -->
+    <el-dialog v-model="dialogVisible" title="鍒涘缓浼氳" width="600px">
+      <el-form :model="meetingForm" label-width="100px">
+        <el-form-item label="浼氳鏍囬">
+          <el-input v-model="meetingForm.title" placeholder="璇疯緭鍏ヤ細璁爣棰�" />
+        </el-form-item>
+        <el-form-item label="浼氳鏃堕棿">
+          <el-date-picker
+            v-model="meetingForm.timeRange"
+            type="datetimerange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫椂闂�"
+            end-placeholder="缁撴潫鏃堕棿"
+            format="YYYY-MM-DD HH:mm"
+            value-format="YYYY-MM-DD HH:mm:ss"
+          />
+        </el-form-item>
+        <el-form-item label="浼氳鍦扮偣">
+          <el-input v-model="meetingForm.location" placeholder="璇疯緭鍏ヤ細璁湴鐐�" />
+        </el-form-item>
+        <el-form-item label="涓绘寔浜�">
+          <el-input v-model="meetingForm.host" placeholder="璇疯緭鍏ヤ富鎸佷汉濮撳悕" />
+        </el-form-item>
+        <el-form-item label="浼氳鎻忚堪">
+          <el-input
+            v-model="meetingForm.description"
+            type="textarea"
+            :rows="3"
+            placeholder="璇疯緭鍏ヤ細璁弿杩�"
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="submitMeeting">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted } from 'vue'
+import { ElMessage } from 'element-plus'
+import { Clock, Location, User, UserFilled } from '@element-plus/icons-vue'
+
+// 缁熻鏁版嵁
+const stats = reactive({
+  total: 12,
+  ongoing: 3,
+  completed: 7,
+  upcoming: 2
+})
+
+// 浼氳鏁版嵁
+const meetings = ref([
+  {
+    id: 1,
+    title: '浜у搧寮�鍙戝懆浼�',
+    status: 'ongoing',
+    startTime: '2024-01-15 09:00:00',
+    endTime: '2024-01-15 10:30:00',
+    location: '浼氳瀹',
+    host: '寮犵粡鐞�',
+    participants: ['寮犵粡鐞�', '鏉庡伐绋嬪笀', '鐜嬭璁″笀', '璧垫祴璇曞憳'],
+    agenda: [
+      { time: '09:00-09:15', content: '涓婂懆宸ヤ綔鎬荤粨', status: 'completed' },
+      { time: '09:15-09:45', content: '鏈懆寮�鍙戣鍒�', status: 'active' },
+      { time: '09:45-10:00', content: '鎶�鏈毦鐐硅璁�', status: 'pending' },
+      { time: '10:00-10:30', content: '闂鍙嶉涓庤В鍐�', status: 'pending' }
+    ]
+  },
+  {
+    id: 2,
+    title: '瀹㈡埛闇�姹傝瘎瀹′細',
+    status: 'upcoming',
+    startTime: '2024-01-15 14:00:00',
+    endTime: '2024-01-15 15:00:00',
+    location: '绾夸笂浼氳',
+    host: '闄堟�荤洃',
+    participants: ['闄堟�荤洃', '鍒樹骇鍝佺粡鐞�', '瀛欏鎴风粡鐞�', '瀹㈡埛浠h〃'],
+    agenda: [
+      { time: '14:00-14:20', content: '闇�姹傝儗鏅粙缁�', status: 'pending' },
+      { time: '14:20-14:40', content: '鍔熻兘闇�姹傚垎鏋�', status: 'pending' },
+      { time: '14:40-15:00', content: '鎶�鏈彲琛屾�ц瘎浼�', status: 'pending' }
+    ]
+  },
+  {
+    id: 3,
+    title: '鍥㈤槦寤鸿娲诲姩',
+    status: 'completed',
+    startTime: '2024-01-14 16:00:00',
+    endTime: '2024-01-14 18:00:00',
+    location: '鍏徃澶у巺',
+    host: '浜轰簨閮�',
+    participants: ['鍏ㄤ綋鍛樺伐'],
+    agenda: [
+      { time: '16:00-16:30', content: '鍥㈤槦娓告垙', status: 'completed' },
+      { time: '16:30-17:00', content: '缁忛獙鍒嗕韩', status: 'completed' },
+      { time: '17:00-18:00', content: '鑷敱浜ゆ祦', status: 'completed' }
+    ]
+  }
+])
+
+// 瀵硅瘽妗嗙浉鍏�
+const dialogVisible = ref(false)
+const meetingForm = reactive({
+  title: '',
+  timeRange: [],
+  location: '',
+  host: '',
+  description: ''
+})
+
+// 鑾峰彇鐘舵�佺被鍨�
+const getStatusType = (status) => {
+  const statusMap = {
+    'ongoing': 'success',
+    'upcoming': 'warning',
+    'completed': 'info'
+  }
+  return statusMap[status] || 'info'
+}
+
+// 鑾峰彇鐘舵�佹枃鏈�
+const getStatusText = (status) => {
+  const statusMap = {
+    'ongoing': '杩涜涓�',
+    'upcoming': '鍗冲皢寮�濮�',
+    'completed': '宸插畬鎴�'
+  }
+  return statusMap[status] || '鏈煡'
+}
+
+// 鑾峰彇璁▼鐘舵�佺被鍨�
+const getAgendaStatusType = (status) => {
+  const statusMap = {
+    'completed': 'success',
+    'active': 'warning',
+    'pending': 'info'
+  }
+  return statusMap[status] || 'info'
+}
+
+// 鑾峰彇璁▼鐘舵�佹枃鏈�
+const getAgendaStatusText = (status) => {
+  const statusMap = {
+    'completed': '宸插畬鎴�',
+    'active': '杩涜涓�',
+    'pending': '寰呭紑濮�'
+  }
+  return statusMap[status] || '鏈煡'
+}
+
+// 鏍煎紡鍖栨椂闂�
+const formatTime = (timeStr) => {
+  const date = new Date(timeStr)
+  return date.toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' })
+}
+
+// 鍒涘缓浼氳
+const createMeeting = () => {
+  dialogVisible.value = true
+  // 閲嶇疆琛ㄥ崟
+  Object.assign(meetingForm, {
+    title: '',
+    timeRange: [],
+    location: '',
+    host: '',
+    description: ''
+  })
+}
+
+// 鎻愪氦浼氳
+const submitMeeting = () => {
+  if (!meetingForm.title || !meetingForm.timeRange.length || !meetingForm.location || !meetingForm.host) {
+    ElMessage.warning('璇峰~鍐欏畬鏁寸殑浼氳淇℃伅')
+    return
+  }
+  
+  // 鍒涘缓鏂颁細璁�
+  const newMeeting = {
+    id: Date.now(),
+    title: meetingForm.title,
+    status: 'upcoming',
+    startTime: meetingForm.timeRange[0],
+    endTime: meetingForm.timeRange[1],
+    location: meetingForm.location,
+    host: meetingForm.host,
+    participants: [meetingForm.host],
+    agenda: [
+      { time: '寰呭畾', content: '璁▼寰呭畾', status: 'pending' }
+    ]
+  }
+  
+  meetings.value.unshift(newMeeting)
+  stats.total++
+  stats.upcoming++
+  
+  ElMessage.success('浼氳鍒涘缓鎴愬姛')
+  dialogVisible.value = false
+}
+
+// 鍔犲叆浼氳
+const joinMeeting = (meeting) => {
+  ElMessage.success(`宸插姞鍏ヤ細璁細${meeting.title}`)
+}
+
+// 鏌ョ湅璇︽儏
+const viewDetails = (meeting) => {
+  ElMessage.info(`鏌ョ湅浼氳璇︽儏锛�${meeting.title}`)
+}
+
+// 缂栬緫浼氳
+const editMeeting = (meeting) => {
+  ElMessage.info(`缂栬緫浼氳锛�${meeting.title}`)
+}
+
+onMounted(() => {
+  console.log('浼氳鐪嬫澘椤甸潰鍔犺浇瀹屾垚')
+})
+</script>
+
+<style scoped>
+.app-container {
+  padding: 20px;
+}
+
+.page-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+}
+
+.page-header h2 {
+  margin: 0;
+  color: #303133;
+}
+
+.stats-cards {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+  gap: 20px;
+  margin-bottom: 30px;
+}
+
+.stat-card {
+  text-align: center;
+}
+
+.stat-content {
+  padding: 10px;
+}
+
+.stat-number {
+  font-size: 32px;
+  font-weight: bold;
+  color: #409eff;
+  margin-bottom: 8px;
+}
+
+.stat-label {
+  font-size: 14px;
+  color: #606266;
+}
+
+.meeting-list {
+  display: grid;
+  gap: 20px;
+}
+
+.meeting-card {
+  border-radius: 8px;
+}
+
+.meeting-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  margin-bottom: 15px;
+}
+
+.meeting-title {
+  display: flex;
+  align-items: center;
+  gap: 10px;
+}
+
+.meeting-title h3 {
+  margin: 0;
+  color: #303133;
+}
+
+.meeting-time {
+  display: flex;
+  align-items: center;
+  gap: 5px;
+  color: #606266;
+  font-size: 14px;
+}
+
+.meeting-info {
+  display: flex;
+  gap: 20px;
+  margin-bottom: 20px;
+  flex-wrap: wrap;
+}
+
+.info-item {
+  display: flex;
+  align-items: center;
+  gap: 5px;
+  color: #606266;
+  font-size: 14px;
+}
+
+.meeting-agenda {
+  margin-bottom: 20px;
+}
+
+.meeting-agenda h4 {
+  margin: 0 0 15px 0;
+  color: #303133;
+  font-size: 16px;
+}
+
+.agenda-list {
+  display: flex;
+  flex-direction: column;
+  gap: 10px;
+}
+
+.agenda-item {
+  display: flex;
+  align-items: center;
+  gap: 15px;
+  padding: 10px;
+  border-radius: 6px;
+  background-color: #f5f7fa;
+}
+
+.agenda-item.active {
+  background-color: #fdf6ec;
+  border-left: 3px solid #e6a23c;
+}
+
+.agenda-item.completed {
+  background-color: #f0f9ff;
+  border-left: 3px solid #409eff;
+}
+
+.agenda-time {
+  font-weight: bold;
+  color: #606266;
+  min-width: 80px;
+}
+
+.agenda-content {
+  flex: 1;
+  color: #303133;
+}
+
+.meeting-actions {
+  display: flex;
+  gap: 10px;
+  justify-content: flex-end;
+}
+
+.dialog-footer {
+  display: flex;
+  justify-content: flex-end;
+  gap: 10px;
+}
+
+@media (max-width: 768px) {
+  .stats-cards {
+    grid-template-columns: repeat(2, 1fr);
+  }
+  
+  .meeting-header {
+    flex-direction: column;
+    gap: 10px;
+  }
+  
+  .meeting-info {
+    flex-direction: column;
+    gap: 10px;
+  }
+  
+  .meeting-actions {
+    flex-direction: column;
+  }
+}
+</style>
\ No newline at end of file
diff --git a/src/views/collaborativeApproval/noticeManagement/index.vue b/src/views/collaborativeApproval/noticeManagement/index.vue
new file mode 100644
index 0000000..daa4cd7
--- /dev/null
+++ b/src/views/collaborativeApproval/noticeManagement/index.vue
@@ -0,0 +1,705 @@
+<template>
+  <div class="app-container">
+    <!-- 鎼滅储琛ㄥ崟 -->
+    <div class="search_form">
+      <div>
+        <span class="search_title">鍏憡鏍囬锛�</span>
+        <el-input
+          v-model="searchForm.noticeTitle"
+          style="width: 240px"
+          placeholder="璇疯緭鍏ュ叕鍛婃爣棰樻悳绱�"
+          @change="handleQuery"
+          clearable
+          :prefix-icon="Search"
+        />
+        <span class="search_title ml10">鍏憡绫诲瀷锛�</span>
+        <el-select v-model="searchForm.noticeType" clearable @change="handleQuery" style="width: 240px">
+          <el-option label="鏀惧亣閫氱煡" value="1" />
+          <el-option label="璁惧缁翠慨閫氱煡" value="2" />
+        </el-select>
+        <span class="search_title ml10">鐘舵�侊細</span>
+        <el-select v-model="searchForm.status" clearable @change="handleQuery" style="width: 240px">
+          <el-option label="鑽夌" value="0" />
+          <el-option label="宸插彂甯�" value="1" />
+          <el-option label="宸蹭笅绾�" value="2" />
+        </el-select>
+        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button>
+        <el-button @click="resetQuery" style="margin-left: 10px">閲嶇疆</el-button>
+      </div>
+      <div>
+        <el-button type="primary" @click="openForm('add')">鏂板鍏憡</el-button>
+        <el-button type="danger" plain @click="handleDelete" :disabled="!selectedIds.length">鍒犻櫎</el-button>
+      </div>
+    </div>
+
+    <!-- 閫氱煡鍏憡鏉� -->
+    <div class="notice-board">
+      <!-- 鏀惧亣閫氱煡鍖哄煙 -->
+      <div class="notice-section" v-if="holidayNotices.length > 0">
+        <div class="section-header">
+          <h3>馃搮 鏀惧亣閫氱煡</h3>
+          <span class="section-count">{{ holidayNotices.length }}鏉�</span>
+        </div>
+        <div class="notice-cards">
+          <div 
+            v-for="notice in holidayNotices" 
+            :key="notice.id"
+            class="notice-card holiday-card"
+            :class="{ 'urgent': notice.priority === '3' }"
+          >
+            <div class="card-header">
+              <div class="card-title">
+                <el-icon class="holiday-icon"><Calendar /></el-icon>
+                {{ notice.noticeTitle }}
+              </div>
+              <div class="card-actions">
+                <el-button link type="primary" @click="handleEdit(notice)">缂栬緫</el-button>
+                <el-button link type="danger" @click="handleDelete(notice.id)">鍒犻櫎</el-button>
+              </div>
+            </div>
+            <div class="card-content">
+              <p>{{ notice.noticeContent }}</p>
+            </div>
+            <div class="card-footer">
+              <div class="card-meta">
+                <span class="priority" :class="'priority-' + notice.priority">
+                  {{ getPriorityText(notice.priority) }}
+                </span>
+                <span class="status" :class="'status-' + notice.status">
+                  {{ getStatusText(notice.status) }}
+                </span>
+              </div>
+              <div class="card-info">
+                <span class="creator">{{ notice.createBy }}</span>
+                <span class="time">{{ notice.createTime }}</span>
+              </div>
+            </div>
+            <div class="card-remark" v-if="notice.remark">
+              <el-icon><InfoFilled /></el-icon>
+              <span>{{ notice.remark }}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 璁惧缁翠慨閫氱煡鍖哄煙 -->
+      <div class="notice-section" v-if="maintenanceNotices.length > 0">
+        <div class="section-header">
+          <h3>馃敡 璁惧缁翠慨閫氱煡</h3>
+          <span class="section-count">{{ maintenanceNotices.length }}鏉�</span>
+        </div>
+        <div class="notice-cards">
+          <div 
+            v-for="notice in maintenanceNotices" 
+            :key="notice.id"
+            class="notice-card maintenance-card"
+            :class="{ 'urgent': notice.priority === '3' }"
+          >
+            <div class="card-header">
+              <div class="card-title">
+                <el-icon class="maintenance-icon"><Tools /></el-icon>
+                {{ notice.noticeTitle }}
+              </div>
+              <div class="card-actions">
+                <el-button link type="primary" @click="handleEdit(notice)">缂栬緫</el-button>
+                <el-button link type="danger" @click="handleDelete(notice.id)">鍒犻櫎</el-button>
+              </div>
+            </div>
+            <div class="card-content">
+              <p>{{ notice.noticeContent }}</p>
+            </div>
+            <div class="card-footer">
+              <div class="card-meta">
+                <span class="priority" :class="'priority-' + notice.priority">
+                  {{ getPriorityText(notice.priority) }}
+                </span>
+                <span class="status" :class="'status-' + notice.status">
+                  {{ getStatusText(notice.status) }}
+                </span>
+              </div>
+              <div class="card-info">
+                <span class="creator">{{ notice.createBy }}</span>
+                <span class="time">{{ notice.createTime }}</span>
+              </div>
+            </div>
+            <div class="card-remark" v-if="notice.remark">
+              <el-icon><InfoFilled /></el-icon>
+              <span>{{ notice.remark }}</span>
+            </div>
+          </div>
+        </div>
+      </div>
+
+      <!-- 绌虹姸鎬� -->
+      <div class="empty-state" v-if="filteredNotices.length === 0">
+        <el-empty description="鏆傛棤閫氱煡鍏憡" />
+      </div>
+    </div>
+
+    <!-- 鏂板/缂栬緫瀵硅瘽妗� -->
+    <el-dialog 
+      :title="dialogTitle" 
+      v-model="dialogVisible" 
+      width="800px" 
+      append-to-body
+      @close="resetForm"
+    >
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="100px">
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鍏憡鏍囬" prop="noticeTitle">
+              <el-input v-model="form.noticeTitle" placeholder="璇疯緭鍏ュ叕鍛婃爣棰�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍏憡绫诲瀷" prop="noticeType">
+              <el-select v-model="form.noticeType" placeholder="璇烽�夋嫨鍏憡绫诲瀷" style="width: 100%">
+                <el-option label="鏀惧亣閫氱煡" value="1" />
+                <el-option label="璁惧缁翠慨閫氱煡" value="2" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="12">
+            <el-form-item label="鐘舵��">
+              <el-radio-group v-model="form.status">
+                <el-radio value="0">鑽夌</el-radio>
+                <el-radio value="1">宸插彂甯�</el-radio>
+                <el-radio value="2">宸蹭笅绾�</el-radio>
+              </el-radio-group>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="浼樺厛绾�">
+              <el-select v-model="form.priority" placeholder="璇烽�夋嫨浼樺厛绾�" style="width: 100%">
+                <el-option label="鏅��" value="1" />
+                <el-option label="閲嶈" value="2" />
+                <el-option label="绱ф��" value="3" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="鍏憡鍐呭" prop="noticeContent">
+              <el-input
+                v-model="form.noticeContent"
+                type="textarea"
+                :rows="6"
+                placeholder="璇疯緭鍏ュ叕鍛婂唴瀹�"
+                maxlength="500"
+                show-word-limit
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row>
+          <el-col :span="24">
+            <el-form-item label="澶囨敞">
+              <el-input
+                v-model="form.remark"
+                type="textarea"
+                :rows="3"
+                placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+                maxlength="200"
+                show-word-limit
+              />
+            </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 @click="dialogVisible = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { Search, Calendar, Tools, InfoFilled } from "@element-plus/icons-vue";
+import { onMounted, ref, reactive, toRefs, computed } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import useUserStore from "@/store/modules/user";
+
+const userStore = useUserStore();
+
+// 鍝嶅簲寮忔暟鎹�
+const data = reactive({
+  searchForm: {
+    noticeTitle: "",
+    noticeType: "",
+    status: "",
+  },
+  form: {
+    id: undefined,
+    noticeTitle: "",
+    noticeType: "",
+    noticeContent: "",
+    status: "0",
+    priority: "1",
+    remark: "",
+    createBy: "",
+    createTime: "",
+  },
+  rules: {
+    noticeTitle: [
+      { required: true, message: "鍏憡鏍囬涓嶈兘涓虹┖", trigger: "blur" }
+    ],
+    noticeType: [
+      { required: true, message: "璇烽�夋嫨鍏憡绫诲瀷", trigger: "change" }
+    ],
+    noticeContent: [
+      { required: true, message: "鍏憡鍐呭涓嶈兘涓虹┖", trigger: "blur" }
+    ]
+  }
+});
+
+const { searchForm, form, rules } = toRefs(data);
+
+// 椤甸潰鐘舵��
+const dialogVisible = ref(false);
+const dialogTitle = ref("");
+const selectedIds = ref([]);
+const formRef = ref();
+
+// 妯℃嫙鏁版嵁 - 鏍规嵁娉曞畾鑺傚亣鏃ヨ璁�
+const mockData = [
+  {
+    id: 1,
+    noticeTitle: "2024骞存槬鑺傛斁鍋囬�氱煡",
+    noticeType: "1",
+    priority: "2",
+    status: "1",
+    noticeContent: "鏍规嵁鍥藉姟闄㈠姙鍏巺閫氱煡锛�2024骞存槬鑺傛斁鍋囧畨鎺掑涓嬶細2鏈�10鏃ワ紙鍒濅竴锛夎嚦2鏈�17鏃ワ紙鍒濆叓锛夋斁鍋囪皟浼戯紝鍏�8澶┿��2鏈�4鏃ワ紙鏄熸湡鏃ワ級銆�2鏈�18鏃ワ紙鏄熸湡鏃ワ級涓婄彮銆傝鍚勯儴闂ㄦ彁鍓嶅仛濂藉伐浣滃畨鎺掋��",
+    remark: "鏀惧亣鏈熼棿璇蜂繚鎸佹墜鏈虹晠閫氾紝濡傛湁绱ф�ヤ簨鍔″強鏃惰仈绯�",
+    createBy: "浜轰簨閮�",
+    createTime: "2024-01-15 10:30:00"
+  },
+  {
+    id: 2,
+    noticeTitle: "2024骞存竻鏄庤妭鏀惧亣閫氱煡",
+    noticeType: "1",
+    priority: "1",
+    status: "1",
+    noticeContent: "鏍规嵁鍥藉姟闄㈠姙鍏巺閫氱煡锛�2024骞存竻鏄庤妭鏀惧亣瀹夋帓濡備笅锛�4鏈�4鏃ワ紙鏄熸湡鍥涳級鑷�4鏈�6鏃ワ紙鏄熸湡鍏級鏀惧亣璋冧紤锛屽叡3澶┿��4鏈�7鏃ワ紙鏄熸湡鏃ワ級涓婄彮銆�",
+    remark: "璇峰悇閮ㄩ棬鍋氬ソ鍊肩彮瀹夋帓锛岀‘淇濊妭鏃ユ湡闂村悇椤瑰伐浣滄甯歌繍杞�",
+    createBy: "琛屾斂閮�",
+    createTime: "2024-01-14 14:20:00"
+  },
+  {
+    id: 3,
+    noticeTitle: "2024骞村姵鍔ㄨ妭鏀惧亣閫氱煡",
+    noticeType: "1",
+    priority: "1",
+    status: "1",
+    noticeContent: "鏍规嵁鍥藉姟闄㈠姙鍏巺閫氱煡锛�2024骞村姵鍔ㄨ妭鏀惧亣瀹夋帓濡備笅锛�5鏈�1鏃ワ紙鏄熸湡涓夛級鑷�5鏈�5鏃ワ紙鏄熸湡鏃ワ級鏀惧亣璋冧紤锛屽叡5澶┿��4鏈�28鏃ワ紙鏄熸湡鏃ワ級銆�5鏈�11鏃ワ紙鏄熸湡鍏級涓婄彮銆�",
+    remark: "鏀惧亣鍓嶈鍏抽棴鐢垫簮锛岄攣濂介棬绐楋紝娉ㄦ剰瀹夊叏",
+    createBy: "琛屾斂閮�",
+    createTime: "2024-01-13 09:15:00"
+  },
+  {
+    id: 4,
+    noticeTitle: "2024骞寸鍗堣妭鏀惧亣閫氱煡",
+    noticeType: "1",
+    priority: "1",
+    status: "1",
+    noticeContent: "鏍规嵁鍥藉姟闄㈠姙鍏巺閫氱煡锛�2024骞寸鍗堣妭鏀惧亣瀹夋帓濡備笅锛�6鏈�8鏃ワ紙鏄熸湡鍏級鑷�6鏈�10鏃ワ紙鏄熸湡涓�锛夋斁鍋囪皟浼戯紝鍏�3澶┿��6鏈�11鏃ワ紙鏄熸湡浜岋級涓婄彮銆�",
+    remark: "绁濆ぇ瀹剁鍗堣妭蹇箰锛岄槚瀹跺垢绂忥紒",
+    createBy: "琛屾斂閮�",
+    createTime: "2024-01-12 16:30:00"
+  },
+  {
+    id: 5,
+    noticeTitle: "2024骞翠腑绉嬭妭鏀惧亣閫氱煡",
+    noticeType: "1",
+    priority: "1",
+    status: "1",
+    noticeContent: "鏍规嵁鍥藉姟闄㈠姙鍏巺閫氱煡锛�2024骞翠腑绉嬭妭鏀惧亣瀹夋帓濡備笅锛�9鏈�15鏃ワ紙鏄熸湡鏃ワ級鑷�9鏈�17鏃ワ紙鏄熸湡浜岋級鏀惧亣璋冧紤锛屽叡3澶┿��9鏈�14鏃ワ紙鏄熸湡鍏級涓婄彮銆�",
+    remark: "涓浣宠妭锛岀澶у鍥㈠渾缇庢弧锛屽垢绂忓畨搴凤紒",
+    createBy: "琛屾斂閮�",
+    createTime: "2024-01-11 11:20:00"
+  },
+  {
+    id: 6,
+    noticeTitle: "2024骞村浗搴嗚妭鏀惧亣閫氱煡",
+    noticeType: "1",
+    priority: "2",
+    status: "1",
+    noticeContent: "鏍规嵁鍥藉姟闄㈠姙鍏巺閫氱煡锛�2024骞村浗搴嗚妭鏀惧亣瀹夋帓濡備笅锛�10鏈�1鏃ワ紙鏄熸湡浜岋級鑷�10鏈�7鏃ワ紙鏄熸湡涓�锛夋斁鍋囪皟浼戯紝鍏�7澶┿��9鏈�29鏃ワ紙鏄熸湡鏃ワ級銆�10鏈�12鏃ワ紙鏄熸湡鍏級涓婄彮銆�",
+    remark: "鍥藉簡鏈熼棿璇峰悇閮ㄩ棬鍋氬ソ鍊肩彮瀹夋帓锛岀‘淇濆畨鍏ㄧǔ瀹�",
+    createBy: "琛屾斂閮�",
+    createTime: "2024-01-10 15:45:00"
+  },
+  {
+    id: 7,
+    noticeTitle: "A杞﹂棿鐢熶骇绾垮勾搴︽淇�氱煡",
+    noticeType: "2",
+    priority: "2",
+    status: "1",
+    noticeContent: "A杞﹂棿鐢熶骇绾垮皢浜�2024骞�1鏈�20鏃ワ紙鍛ㄥ叚锛夎繘琛屽勾搴︽淇淮鎶わ紝棰勮鍋滃伐8灏忔椂銆傛淇唴瀹瑰寘鎷細璁惧娓呮磥銆佹鼎婊戜繚鍏汇�佸畨鍏ㄨ缃鏌ョ瓑銆傝鐢熶骇閮ㄩ棬鎻愬墠璋冩暣鐢熶骇璁″垝銆�",
+    remark: "缁翠慨鏈熼棿璇风浉鍏充汉鍛橀厤鍚堬紝纭繚妫�淇伐浣滃畨鍏ㄩ『鍒╄繘琛�",
+    createBy: "璁惧閮�",
+    createTime: "2024-01-14 14:20:00"
+  },
+  {
+    id: 8,
+    noticeTitle: "B杞﹂棿璁惧棰勯槻鎬х淮鎶ら�氱煡",
+    noticeType: "2",
+    priority: "1",
+    status: "1",
+    noticeContent: "B杞﹂棿鍏抽敭璁惧灏嗕簬2024骞�1鏈�25鏃ヨ繘琛岄闃叉�х淮鎶わ紝棰勮鍋滃伐4灏忔椂銆傜淮鎶ゅ唴瀹瑰寘鎷細璁惧妫�鏌ャ�侀浂浠舵洿鎹€�佹�ц兘娴嬭瘯绛夈�傝鐩稿叧閮ㄩ棬閰嶅悎銆�",
+    remark: "缁存姢瀹屾垚鍚庡皢杩涜璇曡繍琛岋紝纭繚璁惧姝e父杩愯",
+    createBy: "璁惧閮�",
+    createTime: "2024-01-13 09:15:00"
+  }
+];
+
+// 璁$畻灞炴��
+const filteredNotices = computed(() => {
+  let filtered = [...mockData];
+  
+  if (searchForm.value.noticeTitle) {
+    filtered = filtered.filter(item => 
+      item.noticeTitle.includes(searchForm.value.noticeTitle)
+    );
+  }
+  if (searchForm.value.noticeType) {
+    filtered = filtered.filter(item => 
+      item.noticeType === searchForm.value.noticeType
+    );
+  }
+  if (searchForm.value.status !== "") {
+    filtered = filtered.filter(item => 
+      item.status === searchForm.value.status
+    );
+  }
+  
+  return filtered;
+});
+
+const holidayNotices = computed(() => {
+  return filteredNotices.value.filter(notice => notice.noticeType === "1");
+});
+
+const maintenanceNotices = computed(() => {
+  return filteredNotices.value.filter(notice => notice.noticeType === "2");
+});
+
+// 鏂规硶瀹氫箟
+const handleQuery = () => {
+  // 鎼滅储鍔熻兘淇濇寔涓嶅彉锛屼絾鏁版嵁閫氳繃璁$畻灞炴�ц嚜鍔ㄨ繃婊�
+};
+
+const resetQuery = () => {
+  searchForm.value = {
+    noticeTitle: "",
+    noticeType: "",
+    status: ""
+  };
+};
+
+const getPriorityText = (priority) => {
+  const priorityMap = { "1": "鏅��", "2": "閲嶈", "3": "绱ф��" };
+  return priorityMap[priority] || "鏅��";
+};
+
+const getStatusText = (status) => {
+  const statusMap = { "0": "鑽夌", "1": "宸插彂甯�", "2": "宸蹭笅绾�" };
+  return statusMap[status] || "鏈煡";
+};
+
+const openForm = (type) => {
+  if (type === 'add') {
+    dialogTitle.value = "鏂板鍏憡";
+    form.value = {
+      id: undefined,
+      noticeTitle: "",
+      noticeType: "",
+      noticeContent: "",
+      status: "0",
+      priority: "1",
+      remark: "",
+      createBy: userStore.name || "褰撳墠鐢ㄦ埛",
+      createTime: new Date().toLocaleString()
+    };
+  }
+  dialogVisible.value = true;
+};
+
+const handleEdit = (row) => {
+  dialogTitle.value = "缂栬緫鍏憡";
+  form.value = { ...row };
+  dialogVisible.value = true;
+};
+
+const handleSelectionChange = (selection) => {
+  selectedIds.value = selection.map(item => item.id);
+};
+
+const handleDelete = (id) => {
+  ElMessageBox.confirm(
+    "纭鍒犻櫎杩欐潯鍏憡鍚楋紵",
+    "鎻愮ず",
+    {
+      confirmButtonText: "纭畾",
+      cancelButtonText: "鍙栨秷",
+      type: "warning"
+    }
+  ).then(() => {
+    const index = mockData.findIndex(item => item.id === id);
+    if (index > -1) {
+      mockData.splice(index, 1);
+      ElMessage.success("鍒犻櫎鎴愬姛");
+    }
+  });
+};
+
+const submitForm = () => {
+  formRef.value.validate((valid) => {
+    if (valid) {
+      if (form.value.id) {
+        // 缂栬緫妯″紡
+        const index = mockData.findIndex(item => item.id === form.value.id);
+        if (index > -1) {
+          mockData[index] = { ...form.value };
+        }
+        ElMessage.success("淇敼鎴愬姛");
+      } else {
+        // 鏂板妯″紡
+        const newId = Math.max(...mockData.map(item => item.id)) + 1;
+        const newNotice = {
+          ...form.value,
+          id: newId,
+          createTime: new Date().toLocaleString()
+        };
+        mockData.unshift(newNotice);
+        ElMessage.success("鏂板鎴愬姛");
+      }
+      dialogVisible.value = false;
+    }
+  });
+};
+
+const resetForm = () => {
+  formRef.value?.resetFields();
+};
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+  // 椤甸潰鍔犺浇瀹屾垚
+});
+</script>
+
+<style scoped>
+.search_form {
+  background: #fff;
+  padding: 20px;
+  margin-bottom: 20px;
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.search_title {
+  font-weight: 500;
+  color: #333;
+  margin-right: 8px;
+}
+
+.ml10 {
+  margin-left: 10px;
+}
+
+.notice-board {
+  background: #f5f7fa;
+  padding: 20px;
+  border-radius: 8px;
+}
+
+.notice-section {
+  margin-bottom: 30px;
+}
+
+.section-header {
+  display: flex;
+  align-items: center;
+  margin-bottom: 20px;
+  padding: 0 10px;
+}
+
+.section-header h3 {
+  margin: 0;
+  color: #303133;
+  font-size: 18px;
+  font-weight: 600;
+}
+
+.section-count {
+  margin-left: 10px;
+  background: #409eff;
+  color: white;
+  padding: 2px 8px;
+  border-radius: 12px;
+  font-size: 12px;
+}
+
+.notice-cards {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, minmax(400px, 1fr));
+  gap: 20px;
+}
+
+.notice-card {
+  background: white;
+  border-radius: 12px;
+  padding: 20px;
+  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.1);
+  transition: all 0.3s ease;
+  border-left: 4px solid transparent;
+}
+
+.notice-card:hover {
+  transform: translateY(-2px);
+  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.15);
+}
+
+.holiday-card {
+  border-left-color: #67c23a;
+}
+
+.maintenance-card {
+  border-left-color: #e6a23c;
+}
+
+.urgent {
+  border-left-color: #f56c6c;
+  background: linear-gradient(135deg, #fff5f5 0%, #ffffff 100%);
+}
+
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: flex-start;
+  margin-bottom: 15px;
+}
+
+.card-title {
+  display: flex;
+  align-items: center;
+  font-size: 16px;
+  font-weight: 600;
+  color: #303133;
+  flex: 1;
+}
+
+.holiday-icon {
+  color: #67c23a;
+  margin-right: 8px;
+  font-size: 18px;
+}
+
+.maintenance-icon {
+  color: #e6a23c;
+  margin-right: 8px;
+  font-size: 18px;
+}
+
+.card-actions {
+  display: flex;
+  gap: 8px;
+}
+
+.card-content {
+  margin-bottom: 15px;
+}
+
+.card-content p {
+  margin: 0;
+  color: #606266;
+  line-height: 1.6;
+  font-size: 14px;
+}
+
+.card-footer {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 10px;
+}
+
+.card-meta {
+  display: flex;
+  gap: 8px;
+}
+
+.priority, .status {
+  padding: 2px 8px;
+  border-radius: 12px;
+  font-size: 12px;
+  font-weight: 500;
+}
+
+.priority-1 { background: #f0f9ff; color: #0369a1; }
+.priority-2 { background: #fef3c7; color: #d97706; }
+.priority-3 { background: #fef2f2; color: #dc2626; }
+
+.status-0 { background: #f3f4f6; color: #6b7280; }
+.status-1 { background: #d1fae5; color: #059669; }
+.status-2 { background: #fef3c7; color: #d97706; }
+
+.card-info {
+  display: flex;
+  flex-direction: column;
+  align-items: flex-end;
+  font-size: 12px;
+  color: #909399;
+}
+
+.creator {
+  font-weight: 500;
+  margin-bottom: 2px;
+}
+
+.card-remark {
+  display: flex;
+  align-items: center;
+  gap: 6px;
+  padding: 8px 12px;
+  background: #f8f9fa;
+  border-radius: 6px;
+  font-size: 12px;
+  color: #606266;
+  border-left: 3px solid #409eff;
+}
+
+.empty-state {
+  text-align: center;
+  padding: 60px 20px;
+}
+
+.dialog-footer {
+  text-align: right;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 768px) {
+  .notice-cards {
+    grid-template-columns: 1fr;
+  }
+  
+  .search_form {
+    flex-direction: column;
+    gap: 15px;
+  }
+  
+  .search_form > div {
+    width: 100%;
+  }
+}
+</style>
diff --git a/src/views/collaborativeApproval/notificationManagement/index.vue b/src/views/collaborativeApproval/notificationManagement/index.vue
new file mode 100644
index 0000000..288acf1
--- /dev/null
+++ b/src/views/collaborativeApproval/notificationManagement/index.vue
@@ -0,0 +1,1187 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <div>
+        <span class="search_title">閫氱煡鏍囬锛�</span>
+        <el-input
+          v-model="searchForm.title"
+          style="width: 240px"
+          placeholder="璇疯緭鍏ラ�氱煡鏍囬鎼滅储"
+          @change="handleQuery"
+          clearable
+          :prefix-icon="Search"
+        />
+        <span class="search_title ml10">閫氱煡绫诲瀷锛�</span>
+        <el-select v-model="searchForm.type" clearable @change="handleQuery" style="width: 240px">
+          <el-option label="鏀惧亣閫氱煡" :value="'holiday'" />
+          <el-option label="澶勭綒閫氱煡" :value="'penalty'" />
+          <el-option label="寮�浼氶�氱煡" :value="'meeting'" />
+          <el-option label="涓存椂閫氱煡" :value="'temporary'" />
+          <el-option label="姝e紡閫氱煡" :value="'formal'" />
+        </el-select>
+        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">
+          鎼滅储
+        </el-button>
+      </div>
+      <div>
+        <el-button type="primary" @click="openForm('add')">鏂板閫氱煡</el-button>
+        <el-button type="success" @click="openMeetingDialog">鍦ㄧ嚎浼氳</el-button>
+        <el-button type="warning" @click="openFileShareDialog">鏂囦欢鍏变韩</el-button>
+        <!-- <el-button type="info" @click="refreshEmployees">鍒锋柊鍛樺伐</el-button> -->
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+      </div>
+    </div>
+    <div class="table_list">
+      <PIMTable
+        rowKey="id"
+        :column="tableColumn"
+        :tableData="tableData"
+        :page="page"
+        :isSelection="true"
+        @selection-change="handleSelectionChange"
+        :tableLoading="tableLoading"
+        @pagination="pagination"
+        :total="page.total"
+      ></PIMTable>
+    </div>
+
+    <!-- 鏂板/缂栬緫閫氱煡寮圭獥 -->
+    <el-dialog
+      v-model="dialogVisible"
+      :title="dialogTitle"
+      width="800px"
+      :close-on-click-modal="false"
+    >
+      <el-form ref="formRef" :model="form" :rules="rules" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閫氱煡鏍囬" prop="title">
+              <el-input v-model="form.title" placeholder="璇疯緭鍏ラ�氱煡鏍囬" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="閫氱煡绫诲瀷" prop="type">
+              <el-select v-model="form.type" placeholder="璇烽�夋嫨閫氱煡绫诲瀷" style="width: 100%">
+                <el-option label="鏀惧亣閫氱煡" value="holiday" />
+                <el-option label="澶勭綒閫氱煡" value="penalty" />
+                <el-option label="寮�浼氶�氱煡" value="meeting" />
+                <el-option label="涓存椂閫氱煡" value="temporary" />
+                <el-option label="姝e紡閫氱煡" value="formal" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="浼樺厛绾�" prop="priority">
+              <el-select v-model="form.priority" placeholder="璇烽�夋嫨浼樺厛绾�" style="width: 100%">
+                <el-option label="鏅��" value="low" />
+                <el-option label="閲嶈" value="medium" />
+                <el-option label="绱ф��" value="high" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鏈夋晥鏈熻嚦" prop="expireDate">
+              <el-date-picker
+                v-model="form.expireDate"
+                type="date"
+                placeholder="璇烽�夋嫨鏈夋晥鏈�"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="鎺ユ敹閮ㄩ棬" prop="departments">
+          <el-select
+            v-model="form.departments"
+            multiple
+            placeholder="璇烽�夋嫨鎺ユ敹閮ㄩ棬"
+            style="width: 100%"
+          >
+            <el-option
+              v-for="dept in departments"
+              :key="dept"
+              :label="dept"
+              :value="dept"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鍚屾鏂瑰紡" prop="syncMethods">
+          <el-checkbox-group v-model="form.syncMethods">
+            <el-checkbox
+              v-for="method in syncMethods"
+              :key="method.value"
+              :label="method.value"
+            >
+              {{ method.label }}
+            </el-checkbox>
+          </el-checkbox-group>
+        </el-form-item>
+        <el-form-item label="閫氱煡鍐呭" prop="content">
+          <el-input
+            v-model="form.content"
+            type="textarea"
+            :rows="4"
+            placeholder="璇疯緭鍏ラ�氱煡鍐呭"
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="submitForm">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 鍦ㄧ嚎浼氳寮圭獥 -->
+    <el-dialog
+      v-model="meetingDialogVisible"
+      title="鍒涘缓鍦ㄧ嚎浼氳"
+      width="700px"
+      :close-on-click-modal="false"
+    >
+      <el-form ref="meetingFormRef" :model="meetingForm" :rules="meetingRules" label-width="120px">
+        <el-form-item label="浼氳鏍囬" prop="title">
+          <el-input v-model="meetingForm.title" placeholder="璇疯緭鍏ヤ細璁爣棰�" />
+        </el-form-item>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="寮�濮嬫椂闂�" prop="startTime">
+              <el-date-picker
+                v-model="meetingForm.startTime"
+                type="datetime"
+                placeholder="璇烽�夋嫨寮�濮嬫椂闂�"
+                style="width: 100%"
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="浼氳鏃堕暱" prop="duration">
+              <el-input-number
+                v-model="meetingForm.duration"
+                :min="15"
+                :max="480"
+                :step="15"
+                style="width: 100%"
+              />
+              <span style="margin-left: 10px">鍒嗛挓</span>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-form-item label="浼氳骞冲彴" prop="platform">
+          <el-select v-model="meetingForm.platform" placeholder="璇烽�夋嫨浼氳骞冲彴" style="width: 100%">
+            <el-option
+              v-for="platform in meetingPlatforms"
+              :key="platform.value"
+              :label="platform.label"
+              :value="platform.value"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鍙備細浜哄憳" prop="participants">
+          <el-select
+            v-model="meetingForm.participants"
+            multiple
+            filterable
+            remote
+            :remote-method="filterEmployees"
+            :loading="employeesLoading"
+            placeholder="璇烽�夋嫨鍙備細浜哄憳"
+            style="width: 100%"
+          >
+            <el-option-group
+              v-for="group in employeeGroups"
+              :key="group.label"
+              :label="group.label"
+            >
+                             <el-option
+                 v-for="employee in group.options"
+                 :key="employee.value"
+                 :label="`${employee.label} (${employee.dept})`"
+                 :value="employee.value"
+               >
+                 <div style="display: flex; justify-content: space-between; align-items: center;">
+                   <div>
+                     <div style="font-weight: 500;">{{ employee.label }}</div>
+                     <div style="color: #909399; font-size: 12px;">{{ employee.dept }}</div>
+                   </div>
+                   <div style="text-align: right; font-size: 12px; color: #909399;">
+                     <div v-if="employee.phone">{{ employee.phone }}</div>
+                     <div v-if="employee.email">{{ employee.email }}</div>
+                   </div>
+                 </div>
+               </el-option>
+            </el-option-group>
+          </el-select>
+          <div style="margin-top: 8px; color: #909399; font-size: 12px;">
+            宸查�夋嫨 {{ meetingForm.participants.length }} 浜�
+          </div>
+          <!-- 宸查�夋嫨浜哄憳璇︽儏 -->
+          <div v-if="meetingForm.participants.length > 0" style="margin-top: 10px;">
+            <el-tag
+              v-for="participantId in meetingForm.participants"
+              :key="participantId"
+              closable
+              @close="removeParticipant(participantId)"
+              style="margin-right: 8px; margin-bottom: 8px;"
+            >
+              {{ getEmployeeName(participantId) }}
+            </el-tag>
+          </div>
+        </el-form-item>
+        <el-form-item label="浼氳鎻忚堪" prop="description">
+          <el-input
+            v-model="meetingForm.description"
+            type="textarea"
+            :rows="3"
+            placeholder="璇疯緭鍏ヤ細璁弿杩�"
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="meetingDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="createMeeting">鍒涘缓浼氳</el-button>
+        </span>
+      </template>
+    </el-dialog>
+
+    <!-- 鏂囦欢鍏变韩寮圭獥 -->
+    <el-dialog
+      v-model="fileShareDialogVisible"
+      title="鏂囦欢鍏变韩"
+      width="700px"
+      :close-on-click-modal="false"
+    >
+      <el-form ref="fileShareFormRef" :model="fileShareForm" :rules="fileShareRules" label-width="120px">
+        <el-form-item label="鍏变韩鏍囬" prop="title">
+          <el-input v-model="fileShareForm.title" placeholder="璇疯緭鍏ュ叡浜爣棰�" />
+        </el-form-item>
+        <el-form-item label="鍏变韩鎻忚堪" prop="description">
+          <el-input
+            v-model="fileShareForm.description"
+            type="textarea"
+            :rows="3"
+            placeholder="璇疯緭鍏ュ叡浜弿杩�"
+          />
+        </el-form-item>
+        <el-form-item label="鎺ユ敹閮ㄩ棬" prop="departments">
+          <el-select
+            v-model="fileShareForm.departments"
+            multiple
+            placeholder="璇烽�夋嫨鎺ユ敹閮ㄩ棬"
+            style="width: 100%"
+          >
+            <el-option
+              v-for="dept in departments"
+              :key="dept"
+              :label="dept"
+              :value="dept"
+            />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="涓婁紶鏂囦欢" prop="files">
+          <el-upload
+            ref="uploadRef"
+            :auto-upload="false"
+            :on-change="handleFileChange"
+            :on-remove="removeFile"
+            :file-list="fileList"
+            multiple
+            :limit="10"
+            accept=".doc,.docx,.pdf,.xls,.xlsx,.ppt,.pptx,.txt,.jpg,.jpeg,.png,.gif"
+          >
+            <el-button type="primary">閫夋嫨鏂囦欢</el-button>
+            <template #tip>
+              <div class="el-upload__tip">
+                鏀寔涓婁紶鏂囨。銆佸浘鐗囩瓑鏍煎紡锛屽崟涓枃浠朵笉瓒呰繃10MB锛屾渶澶�10涓枃浠�
+              </div>
+            </template>
+          </el-upload>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="fileShareDialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="shareFiles">鍏变韩鏂囦欢</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { Search } from "@element-plus/icons-vue";
+import { onMounted, ref, reactive, toRefs, computed } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import PIMTable from "@/components/PIMTable/PIMTable.vue";
+import { userListNoPageByTenantId } from "@/api/system/user.js";
+import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const rules = {
+  title: [
+    { required: true, message: "璇疯緭鍏ラ�氱煡鏍囬", trigger: "blur" }
+  ],
+  type: [
+    { required: true, message: "璇烽�夋嫨閫氱煡绫诲瀷", trigger: "change" }
+  ],
+  content: [
+    { required: true, message: "璇疯緭鍏ラ�氱煡鍐呭", trigger: "blur" }
+  ]
+};
+
+const meetingRules = {
+  title: [
+    { required: true, message: "璇疯緭鍏ヤ細璁爣棰�", trigger: "blur" }
+  ],
+  startTime: [
+    { required: true, message: "璇烽�夋嫨浼氳寮�濮嬫椂闂�", trigger: "change" }
+  ],
+  participants: [
+    { required: true, message: "璇烽�夋嫨鍙備細浜哄憳", trigger: "change" }
+  ]
+};
+
+const fileShareRules = {
+  title: [
+    { required: true, message: "璇疯緭鍏ュ叡浜爣棰�", trigger: "blur" }
+  ],
+  description: [
+    { required: true, message: "璇疯緭鍏ュ叡浜弿杩�", trigger: "blur" }
+  ]
+};
+
+// 鍝嶅簲寮忔暟鎹�
+const data = reactive({
+  searchForm: {
+    title: "",
+    type: "",
+    status: "",
+  },
+  tableLoading: false,
+  page: {
+    current: 1,
+    size: 100,
+    total: 0,
+  },
+  tableData: [],
+  selectedIds: [],
+  // 鏂板閫氱煡鐩稿叧
+  form: {
+    title: "",
+    type: "",
+    priority: "medium",
+    content: "",
+    departments: [],
+    expireDate: "",
+    syncMethods: []
+  },
+  dialogVisible: false,
+  dialogTitle: "",
+  dialogType: "add",
+  // 鍦ㄧ嚎浼氳鐩稿叧
+  meetingDialogVisible: false,
+  meetingForm: {
+    title: "",
+    startTime: "",
+    duration: 60,
+    participants: [],
+    description: "",
+    platform: "wechat"
+  },
+  // 鏂囦欢鍏变韩鐩稿叧
+  fileShareDialogVisible: false,
+  fileShareForm: {
+    title: "",
+    description: "",
+    departments: [],
+    files: []
+  },
+  fileList: []
+});
+
+const { 
+  searchForm, 
+  tableLoading, 
+  page, 
+  tableData, 
+  selectedIds,
+  form,
+  dialogVisible,
+  dialogTitle,
+  dialogType,
+  meetingDialogVisible,
+  meetingForm,
+  fileShareDialogVisible,
+  fileShareForm,
+  fileList
+} = toRefs(data);
+
+// 琛ㄥ崟寮曠敤
+const formRef = ref();
+const meetingFormRef = ref();
+const fileShareFormRef = ref();
+
+// 琛ㄦ牸鍒楅厤缃�
+const tableColumn = ref([
+  {
+    label: "閫氱煡鏍囬",
+    prop: "title",
+    showOverflowTooltip: true,
+  },
+  {
+    label: "閫氱煡绫诲瀷",
+    prop: "type",
+    dataType: "tag",
+    formatData: (params) => {
+      const typeMap = {
+        holiday: "鏀惧亣閫氱煡",
+        penalty: "澶勭綒閫氱煡",
+        meeting: "寮�浼氶�氱煡",
+        temporary: "涓存椂閫氱煡",
+        formal: "姝e紡閫氱煡"
+      };
+      return typeMap[params] || params;
+    },
+    formatType: (params) => {
+      const typeMap = {
+        holiday: "success",
+        penalty: "danger",
+        meeting: "warning",
+        temporary: "info",
+        formal: "primary"
+      };
+      return typeMap[params] || "info";
+    }
+  },
+  {
+    label: "浼樺厛绾�",
+    prop: "priority",
+    dataType: "tag",
+    formatData: (params) => {
+      const priorityMap = {
+        low: "鏅��",
+        medium: "閲嶈",
+        high: "绱ф��"
+      };
+      return priorityMap[params] || params;
+    },
+    formatType: (params) => {
+      const typeMap = {
+        low: "info",
+        medium: "warning",
+        high: "danger"
+      };
+      return typeMap[params] || "info";
+    }
+  },
+  {
+    label: "鐘舵��",
+    prop: "status",
+    dataType: "tag",
+    formatData: (params) => {
+      const statusMap = {
+        draft: "鑽夌",
+        published: "宸插彂甯�",
+        expired: "宸茶繃鏈�"
+      };
+      return statusMap[params] || params;
+    },
+    formatType: (params) => {
+      const typeMap = {
+        draft: "info",
+        published: "success",
+        expired: "danger"
+      };
+      return typeMap[params] || "info";
+    }
+  },
+  {
+    label: "鎺ユ敹閮ㄩ棬",
+    prop: "departments",
+    width: 150,
+    showOverflowTooltip: true,
+    formatData: (params) => {
+      if (!params || params.length === 0) return "鍏ㄩ儴閮ㄩ棬";
+      return params.join(", ");
+    }
+  },
+  {
+    label: "鏈夋晥鏈熻嚦",
+    prop: "expireDate",
+    width: 150,
+    formatData: (params) => {
+      if (!params) return "姘镐箙鏈夋晥";
+      return params;
+    }
+  },
+  {
+    label: "鍒涘缓鏃堕棿",
+    prop: "createTime",
+    width: 180,
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: "right",
+    width: 280,
+    operation: [
+      {
+        name: "缂栬緫",
+        type: "text",
+        clickFun: (row) => {
+          openForm("edit", row);
+        }
+      },
+      {
+        name: "鍙戝竷",
+        type: "text",
+        clickFun: (row) => {
+          publishNotification(row);
+        },
+        // disabled: (row) => row.status === "published"
+      },
+      {
+        name: "鎾ゅ洖",
+        type: "text",
+        clickFun: (row) => {
+          revokeNotification(row);
+        },
+        // disabled: (row) => row.status !== "published"
+      }
+    ]
+  }
+]);
+
+// 妯℃嫙鏁版嵁
+let mockData = [
+  {
+    id: "1",
+    title: "2024骞存槬鑺傛斁鍋囬�氱煡",
+    type: "holiday",
+    priority: "high",
+    status: "published",
+    content: "鏍规嵁鍥藉瑙勫畾锛岀粨鍚堝叕鍙稿疄闄呮儏鍐碉紝鐜板皢2024骞存槬鑺傛斁鍋囧畨鎺掗�氱煡濡備笅...",
+    departments: ["鎶�鏈儴", "閿�鍞儴", "浜轰簨閮�", "璐㈠姟閮�", "杩愯惀閮�", "甯傚満閮�", "瀹㈡湇閮�"],
+    expireDate: "2024-02-15",
+    syncMethods: ["wechat", "dingtalk", "email"],
+    createTime: "2024-01-15 10:30:00"
+  },
+  {
+    id: "2",
+    title: "鎶�鏈儴鍛ㄤ緥浼氶�氱煡",
+    type: "meeting",
+    priority: "medium",
+    status: "published",
+    content: "鎶�鏈儴瀹氫簬姣忓懆浜斾笅鍗�2鐐瑰彫寮�鍛ㄤ緥浼氾紝璇峰悇浣嶅悓浜嬪噯鏃跺弬鍔�...",
+    departments: ["鎶�鏈儴"],
+    expireDate: "2024-01-20",
+    syncMethods: ["wechat", "dingtalk"],
+    createTime: "2024-01-14 15:20:00"
+  },
+  {
+    id: "3",
+    title: "鍛樺伐琛屼负瑙勮寖澶勭綒閫氱煡",
+    type: "penalty",
+    priority: "high",
+    status: "draft",
+    content: "涓虹淮鎶ゅ叕鍙告甯哥З搴忥紝瑙勮寖鍛樺伐琛屼负锛岀幇瀵硅繚鍙嶅叕鍙歌瀹氱殑琛屼负杩涜澶勭綒...",
+    departments: ["浜轰簨閮�", "鎶�鏈儴", "閿�鍞儴"],
+    expireDate: "2024-02-13",
+    syncMethods: ["wechat", "email"],
+    createTime: "2024-01-13 09:15:00"
+  }
+];
+
+// 閫氱煡鏍囬妯℃澘
+const titleTemplates = [
+  "鍏充簬{year}骞磠holiday}鏀惧亣瀹夋帓鐨勯�氱煡",
+  "{dept}閮ㄩ棬{meeting}浼氳閫氱煡",
+  "鍛樺伐{behavior}琛屼负瑙勮寖鎻愰啋",
+  "{company}閲嶈浜嬮」閫氱煡",
+  "{dept}閮ㄩ棬宸ヤ綔瀹夋帓閫氱煡",
+  "鍏充簬{project}椤圭洰杩涘害鐨勯�氱煡",
+  "{dept}閮ㄩ棬浜哄憳璋冩暣閫氱煡",
+  "鍏徃{policy}鏀跨瓥鏇存柊閫氱煡"
+];
+
+// 閫氱煡绫诲瀷閰嶇疆
+const notificationTypes = [
+  { type: "holiday", label: "鏀惧亣閫氱煡", priority: "high" },
+  { type: "meeting", label: "寮�浼氶�氱煡", priority: "medium" },
+  { type: "penalty", label: "澶勭綒閫氱煡", priority: "high" },
+  { type: "temporary", label: "涓存椂閫氱煡", priority: "low" },
+  { type: "formal", label: "姝e紡閫氱煡", priority: "medium" }
+];
+
+// 閮ㄩ棬鍒楄〃
+const departments = ["鎶�鏈儴", "閿�鍞儴", "浜轰簨閮�", "璐㈠姟閮�", "杩愯惀閮�", "甯傚満閮�", "瀹㈡湇閮�"];
+
+// 浜哄憳鍒楄〃
+const employees = ref([]);
+const employeesLoading = ref(false);
+
+// 鑾峰彇鍦ㄨ亴鍛樺伐鍒楄〃
+const getEmployeesList = async () => {
+  try {
+    employeesLoading.value = true;
+    // 浼樺厛浣跨敤绯荤粺鐢ㄦ埛鎺ュ彛锛堟寜绉熸埛鑾峰彇锛�
+    const userResponse = await userListNoPageByTenantId();
+    
+    if (userResponse.data) {
+      employees.value = userResponse.data.map(user => ({
+        label: user.nickName || user.userName || '鏈煡濮撳悕',
+        value: user.userId || user.id,
+        dept: user.dept?.deptName || '鏈煡閮ㄩ棬',
+        phone: user.phonenumber || '',
+        email: user.email || '',
+        status: user.status || '0'
+      })).filter(user => user.status === '0'); // 鍙樉绀烘甯哥姸鎬佺殑鐢ㄦ埛
+    } else {
+      // 濡傛灉绯荤粺鐢ㄦ埛鎺ュ彛澶辫触锛屼娇鐢ㄥ憳宸ュ彴璐︽帴鍙�
+      const response = await staffOnJobListPage({ 
+        pageNum: 1, 
+        pageSize: 1000, 
+        staffState: 1 // 鍦ㄨ亴鐘舵��
+      });
+      
+      if (response.data && response.data.records) {
+        employees.value = response.data.records.map(employee => ({
+          label: employee.staffName || employee.name || '鏈煡濮撳悕',
+          value: employee.staffNo || employee.id || employee.staffId,
+          dept: employee.deptName || employee.department || '鏈煡閮ㄩ棬',
+          phone: employee.phone || employee.mobile || '',
+          email: employee.email || '',
+          status: '0'
+        }));
+      }
+    }
+  } catch (error) {
+    console.error('鑾峰彇鍛樺伐鍒楄〃澶辫触:', error);
+    // 濡傛灉鎺ュ彛閮藉け璐ワ紝浣跨敤榛樿鏁版嵁
+    employees.value = [
+      { label: "寮犱笁", value: "001", dept: "鎶�鏈儴", phone: "13800138001", email: "zhangsan@company.com", status: "0" },
+      { label: "鏉庡洓", value: "002", dept: "閿�鍞儴", phone: "13800138002", email: "lisi@company.com", status: "0" },
+      { label: "鐜嬩簲", value: "003", dept: "浜轰簨閮�", phone: "13800138003", email: "wangwu@company.com", status: "0" }
+    ];
+  } finally {
+    employeesLoading.value = false;
+  }
+};
+
+// 鍛樺伐鍒嗙粍
+const employeeGroups = computed(() => {
+  const groups = {};
+  employees.value.forEach(employee => {
+    const dept = employee.dept || '鍏朵粬閮ㄩ棬';
+    if (!groups[dept]) {
+      groups[dept] = [];
+    }
+    groups[dept].push(employee);
+  });
+  
+  // 鎸夐儴闂ㄥ悕绉版帓搴忥紝纭繚鏄剧ず椤哄簭涓�鑷�
+  return Object.keys(groups)
+    .sort()
+    .map(dept => ({
+      label: dept,
+      options: groups[dept].sort((a, b) => a.label.localeCompare(b.label, 'zh-CN'))
+    }));
+});
+
+// 杩囨护鍛樺伐锛堣繙绋嬫悳绱級
+const filterEmployees = (query) => {
+  if (query !== '') {
+    const lowerQuery = query.toLowerCase();
+    return employees.value.filter(employee => 
+      employee.label.toLowerCase().includes(lowerQuery) ||
+      employee.dept.toLowerCase().includes(lowerQuery) ||
+      (employee.phone && employee.phone.includes(query)) ||
+      (employee.email && employee.email.toLowerCase().includes(lowerQuery))
+    );
+  } else {
+    return employees.value;
+  }
+};
+
+// 鍒锋柊鍛樺伐鍒楄〃
+const refreshEmployees = async () => {
+  ElMessage.info("姝e湪鍒锋柊鍛樺伐鍒楄〃...");
+  await getEmployeesList();
+  
+  // 缁熻鍚勯儴闂ㄤ汉鏁�
+  const deptStats = {};
+  employees.value.forEach(emp => {
+    const dept = emp.dept || '鍏朵粬閮ㄩ棬';
+    deptStats[dept] = (deptStats[dept] || 0) + 1;
+  });
+  
+  const deptInfo = Object.entries(deptStats)
+    .map(([dept, count]) => `${dept}: ${count}浜篳)
+    .join(', ');
+  
+  ElMessage.success(`鍛樺伐鍒楄〃鍒锋柊瀹屾垚锛屽叡 ${employees.value.length} 浜� (${deptInfo})`);
+};
+
+// 鑾峰彇鍛樺伐濮撳悕
+const getEmployeeName = (employeeId) => {
+  const employee = employees.value.find(emp => emp.value === employeeId);
+  return employee ? employee.label : '鏈煡浜哄憳';
+};
+
+// 鑾峰彇鍛樺伐璇︾粏淇℃伅
+const getEmployeeInfo = (employeeId) => {
+  const employee = employees.value.find(emp => emp.value === employeeId);
+  if (!employee) return null;
+  
+  return {
+    name: employee.label,
+    dept: employee.dept,
+    phone: employee.phone,
+    email: employee.email
+  };
+};
+
+// 绉婚櫎鍙備細浜哄憳
+const removeParticipant = (participantId) => {
+  const index = meetingForm.value.participants.indexOf(participantId);
+  if (index > -1) {
+    meetingForm.value.participants.splice(index, 1);
+  }
+};
+
+// 鍚屾鏂瑰紡閫夐」
+const syncMethods = [
+  { label: "浼佷笟寰俊", value: "wechat" },
+  { label: "閽夐拤", value: "dingtalk" },
+  { label: "閭欢", value: "email" },
+  { label: "鐭俊", value: "sms" }
+];
+
+// 浼氳骞冲彴閫夐」
+const meetingPlatforms = [
+  { label: "浼佷笟寰俊浼氳", value: "wechat" },
+  { label: "閽夐拤浼氳", value: "dingtalk" },
+  { label: "鑵捐浼氳", value: "tencent" },
+  { label: "Zoom", value: "zoom" }
+];
+
+// 鑷姩鐢熸垚鏂版暟鎹�
+const generateNewData = () => {
+  const newId = (mockData.length + 1).toString();
+  const now = new Date();
+  const randomType = notificationTypes[Math.floor(Math.random() * notificationTypes.length)];
+  const randomDept = departments[Math.floor(Math.random() * departments.length)];
+  
+  // 鐢熸垚闅忔満鏍囬
+  let title = titleTemplates[Math.floor(Math.random() * titleTemplates.length)];
+  title = title
+    .replace('{year}', now.getFullYear())
+    .replace('{holiday}', ['鏄ヨ妭', '鍥藉簡', '涓', '鍏冩棪'][Math.floor(Math.random() * 4)])
+    .replace('{dept}', randomDept)
+    .replace('{meeting}', ['鍛ㄤ緥浼�', '鏈堝害鎬荤粨', '椤圭洰璇勫', '鍩硅浼氳'][Math.floor(Math.random() * 4)])
+    .replace('{behavior}', ['鑰冨嫟', '鐫�瑁�', '宸ヤ綔鎬佸害', '鍥㈤槦鍗忎綔'][Math.floor(Math.random() * 4)])
+    .replace('{company}', ['鍏徃', '闆嗗洟', '鎬婚儴'][Math.floor(Math.random() * 4)])
+    .replace('{project}', ['鏁板瓧鍖栬浆鍨�', '浜у搧鍗囩骇', '甯傚満鎷撳睍', '浜烘墠鍩瑰吇'][Math.floor(Math.random() * 4)])
+    .replace('{policy}', ['鑰冨嫟', '钖叕', '绂忓埄', '鏅嬪崌'][Math.floor(Math.random() * 4)]);
+  
+  // 闅忔満鐘舵��
+  const statuses = ['draft', 'published'];
+  const randomStatus = statuses[Math.floor(Math.random() * statuses.length)];
+  
+  // 闅忔満浼樺厛绾�
+  const priorities = ['low', 'medium', 'high'];
+  const randomPriority = priorities[Math.floor(Math.random() * priorities.length)];
+  
+  const newNotification = {
+    id: newId,
+    title: title,
+    type: randomType.type,
+    priority: randomPriority,
+    status: randomStatus,
+    content: `杩欐槸${title}鐨勮缁嗗唴瀹癸紝璇风浉鍏充汉鍛樻敞鎰忔煡鐪�...`,
+    departments: [randomDept],
+    expireDate: new Date(now.getTime() + 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0], // 30澶╁悗杩囨湡
+    syncMethods: ["wechat", "dingtalk"],
+    createTime: now.toLocaleString()
+  };
+  
+  // 娣诲姞鍒版暟鎹紑澶�
+  mockData.unshift(newNotification);
+  
+  // 淇濇寔鏁版嵁閲忓湪鍚堢悊鑼冨洿鍐咃紙鏈�澶氫繚鐣�20鏉★級
+  if (mockData.length > 20) {
+    mockData = mockData.slice(0, 20);
+  }
+  
+  console.log(`[${new Date().toLocaleString()}] 鑷姩鐢熸垚鏂伴�氱煡: ${title}`);
+};
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+  getList();
+  getEmployeesList(); // 鑾峰彇鍛樺伐鍒楄〃
+  startAutoRefresh();
+});
+
+// 寮�濮嬭嚜鍔ㄥ埛鏂�
+const startAutoRefresh = () => {
+  setInterval(() => {
+    generateNewData();
+    getList();
+  }, 600000); // 10鍒嗛挓鍒锋柊涓�娆� (10 * 60 * 1000 = 600000ms)
+};
+
+// 鏌ヨ鏁版嵁
+const handleQuery = () => {
+  page.value.current = 1;
+  getList();
+};
+
+const getList = () => {
+  tableLoading.value = true;
+  
+  setTimeout(() => {
+    let filteredData = [...mockData];
+    
+    if (searchForm.value.title) {
+      filteredData = filteredData.filter(item => 
+        item.title.toLowerCase().includes(searchForm.value.title.toLowerCase())
+      );
+    }
+    
+    if (searchForm.value.type) {
+      filteredData = filteredData.filter(item => item.type === searchForm.value.type);
+    }
+    
+    tableData.value = filteredData;
+    page.value.total = filteredData.length;
+    tableLoading.value = false;
+  }, 500);
+};
+
+// 鍒嗛〉澶勭悊
+const pagination = (obj) => {
+  page.value.current = obj.page;
+  page.value.size = obj.limit;
+  handleQuery();
+};
+
+// 閫夋嫨鍙樺寲澶勭悊
+const handleSelectionChange = (selection) => {
+  selectedIds.value = selection.map(item => item.id);
+};
+
+// 鎵撳紑琛ㄥ崟
+const openForm = (type, row = null) => {
+  dialogType.value = type;
+  if (type === "add") {
+    dialogTitle.value = "鏂板閫氱煡";
+    // 閲嶇疆琛ㄥ崟
+    Object.assign(form.value, {
+      title: "",
+      type: "",
+      priority: "medium",
+      content: "",
+      departments: [],
+      expireDate: "",
+      syncMethods: []
+    });
+  } else if (type === "edit" && row) {
+    dialogTitle.value = "缂栬緫閫氱煡";
+    Object.assign(form.value, {
+      title: row.title,
+      type: row.type,
+      priority: row.priority,
+      content: row.content || "",
+      departments: row.departments || [],
+      expireDate: row.expireDate || "",
+      syncMethods: row.syncMethods || []
+    });
+  }
+  dialogVisible.value = true;
+};
+
+// 鎵撳紑鍦ㄧ嚎浼氳寮圭獥
+const openMeetingDialog = () => {
+  // 閲嶇疆琛ㄥ崟
+  Object.assign(meetingForm.value, {
+    title: "",
+    startTime: "",
+    duration: 60,
+    participants: [],
+    description: "",
+    platform: "wechat"
+  });
+  meetingDialogVisible.value = true;
+};
+
+// 鎵撳紑鏂囦欢鍏变韩寮圭獥
+const openFileShareDialog = () => {
+  // 閲嶇疆琛ㄥ崟
+  Object.assign(fileShareForm.value, {
+    title: "",
+    description: "",
+    departments: [],
+    files: []
+  });
+  fileList.value = [];
+  fileShareDialogVisible.value = true;
+};
+
+// 鎵嬪姩鍒锋柊鏁版嵁
+const manualRefresh = () => {
+  generateNewData();
+  getList();
+  ElMessage.success("鎵嬪姩鍒锋柊瀹屾垚锛屽凡鐢熸垚鏂伴�氱煡");
+};
+
+// 鎻愪氦閫氱煡琛ㄥ崟
+const submitForm = async () => {
+  try {
+    await formRef.value.validate();
+    
+    if (dialogType.value === "add") {
+      // 鏂板閫氱煡
+      const newNotification = {
+        id: (mockData.length + 1).toString(),
+        title: form.value.title,
+        type: form.value.type,
+        priority: form.value.priority,
+        status: "draft",
+        content: form.value.content,
+        departments: form.value.departments,
+        expireDate: form.value.expireDate,
+        syncMethods: form.value.syncMethods,
+        createTime: new Date().toLocaleString()
+      };
+      
+      mockData.unshift(newNotification);
+      ElMessage.success("閫氱煡鍒涘缓鎴愬姛");
+    } else {
+      // 缂栬緫閫氱煡
+      const index = mockData.findIndex(item => item.id === selectedIds.value[0]);
+      if (index !== -1) {
+        Object.assign(mockData[index], {
+          title: form.value.title,
+          type: form.value.type,
+          priority: form.value.priority,
+          content: form.value.content,
+          departments: form.value.departments,
+          expireDate: form.value.expireDate,
+          syncMethods: form.value.syncMethods
+        });
+        ElMessage.success("閫氱煡鏇存柊鎴愬姛");
+      }
+    }
+    
+    dialogVisible.value = false;
+    getList();
+  } catch (error) {
+    console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+  }
+};
+
+// 鍒涘缓浼氳
+const createMeeting = async () => {
+  try {
+    await meetingFormRef.value.validate();
+    
+    // 妯℃嫙鍒涘缓浼氳
+    const meetingInfo = {
+      title: meetingForm.value.title,
+      startTime: meetingForm.value.startTime,
+      duration: meetingForm.value.duration,
+      participants: meetingForm.value.participants,
+      description: meetingForm.value.description,
+      platform: meetingForm.value.platform,
+      meetingId: `MTG${Date.now()}`
+    };
+    
+    // 妯℃嫙鍙戦�佸埌浼佷笟寰俊/閽夐拤
+    const platformName = meetingPlatforms.find(p => p.value === meetingForm.value.platform)?.label || "鏈煡骞冲彴";
+    
+    ElMessage.success(`浼氳鍒涘缓鎴愬姛锛佷細璁甀D: ${meetingInfo.meetingId}锛屽皢閫氳繃${platformName}鍙戦�侀�氱煡`);
+    meetingDialogVisible.value = false;
+    
+         // 鑾峰彇鍙備細浜哄憳淇℃伅
+     const participantNames = meetingForm.value.participants.map(participantId => {
+       const employee = employees.value.find(emp => emp.value === participantId);
+       return employee ? employee.label : '鏈煡浜哄憳';
+     }).join('銆�');
+     
+     // 鑾峰彇鍙備細浜哄憳璇︾粏淇℃伅
+     const participantDetails = meetingForm.value.participants.map(participantId => {
+       const employee = employees.value.find(emp => emp.value === participantId);
+       return employee ? {
+         name: employee.label,
+         dept: employee.dept,
+         phone: employee.phone,
+         email: employee.email
+       } : null;
+     }).filter(Boolean);
+    
+    // 灏嗕細璁俊鎭坊鍔犲埌閫氱煡鍒楄〃
+    const meetingNotification = {
+      id: (mockData.length + 1).toString(),
+      title: `[浼氳閫氱煡] ${meetingInfo.title}`,
+      type: "meeting",
+      priority: "high",
+      status: "published",
+             content: `浼氳鏃堕棿: ${meetingInfo.startTime}锛屾椂闀�: ${meetingInfo.duration}鍒嗛挓锛屽钩鍙�: ${meetingPlatforms.find(p => p.value === meetingForm.value.platform)?.label || "鏈煡骞冲彴"}锛屽弬浼氫汉鍛�: ${participantNames}锛屽叡${participantDetails.length}浜篳,
+      departments: [],
+      expireDate: "",
+      syncMethods: [meetingForm.value.platform],
+      createTime: new Date().toLocaleString()
+    };
+    
+    mockData.unshift(meetingNotification);
+    getList();
+  } catch (error) {
+    console.error("浼氳琛ㄥ崟楠岃瘉澶辫触:", error);
+  }
+};
+
+// 鏂囦欢涓婁紶澶勭悊
+const handleFileChange = (file) => {
+  const isLt10M = file.size / 1024 / 1024 < 10;
+  if (!isLt10M) {
+    ElMessage.error("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃 10MB!");
+    return false;
+  }
+  
+  const fileInfo = {
+    name: file.name,
+    size: file.size,
+    type: file.type,
+    uid: file.uid
+  };
+  
+  fileList.value.push(fileInfo);
+  fileShareForm.value.files.push(fileInfo);
+  return false; // 闃绘鑷姩涓婁紶
+};
+
+// 绉婚櫎鏂囦欢
+const removeFile = (file) => {
+  const index = fileList.value.findIndex(item => item.uid === file.uid);
+  if (index !== -1) {
+    const index2 = fileShareForm.value.files.findIndex(item => item.uid === file.uid);
+    if (index2 !== -1) {
+      fileShareForm.value.files.splice(index2, 1);
+    }
+    fileList.value.splice(index, 1);
+  }
+};
+
+// 鍏变韩鏂囦欢
+const shareFiles = async () => {
+  try {
+    await fileShareFormRef.value.validate();
+    
+    if (fileShareForm.value.files.length === 0) {
+      ElMessage.warning("璇疯嚦灏戦�夋嫨涓�涓枃浠�");
+      return;
+    }
+    
+    // 妯℃嫙鏂囦欢鍏变韩
+    const shareInfo = {
+      title: fileShareForm.value.title,
+      description: fileShareForm.value.description,
+      departments: fileShareForm.value.departments,
+      files: fileShareForm.value.files,
+      shareId: `FILE${Date.now()}`
+    };
+    
+    ElMessage.success(`鏂囦欢鍏变韩鎴愬姛锛佸叡浜獻D: ${shareInfo.shareId}锛屽凡閫氱煡鐩稿叧閮ㄩ棬`);
+    fileShareDialogVisible.value = false;
+    
+    // 灏嗘枃浠跺叡浜俊鎭坊鍔犲埌閫氱煡鍒楄〃
+    const fileShareNotification = {
+      id: (mockData.length + 1).toString(),
+      title: `[鏂囦欢鍏变韩] ${shareInfo.title}`,
+      type: "temporary",
+      priority: "medium",
+      status: "published",
+      content: `鍏变韩鎻忚堪: ${shareInfo.description}锛屾枃浠舵暟閲�: ${shareInfo.files.length}涓猔,
+      departments: shareInfo.departments,
+      expireDate: "",
+      syncMethods: ["wechat", "dingtalk"],
+      createTime: new Date().toLocaleString()
+    };
+    
+    mockData.unshift(fileShareNotification);
+    getList();
+  } catch (error) {
+    console.error("鏂囦欢鍏变韩琛ㄥ崟楠岃瘉澶辫触:", error);
+  }
+};
+
+// 鍙戝竷閫氱煡
+const publishNotification = (row) => {
+  row.status = "published";
+  ElMessage.success("閫氱煡鍙戝竷鎴愬姛");
+  getList();
+};
+
+// 鎾ゅ洖閫氱煡
+const revokeNotification = (row) => {
+  row.status = "draft";
+  ElMessage.success("閫氱煡宸叉挙鍥�");
+  getList();
+};
+
+// 鍒犻櫎閫氱煡
+const handleDelete = () => {
+  if (selectedIds.value.length === 0) {
+    ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑閫氱煡");
+    return;
+  }
+  
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    selectedIds.value = [];
+    getList();
+  }).catch(() => {
+    // 鐢ㄦ埛鍙栨秷
+  });
+};
+</script>
+
+<style scoped>
+.auto-refresh-info {
+  margin-bottom: 15px;
+}
+
+.auto-refresh-info .el-alert {
+  border-radius: 8px;
+}
+
+.dialog-footer {
+  text-align: right;
+}
+
+.el-upload__tip {
+  color: #909399;
+  font-size: 12px;
+  margin-top: 8px;
+}
+
+.el-checkbox-group {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 10px;
+}
+
+.el-checkbox {
+  margin-right: 0;
+}
+</style>
diff --git a/src/views/collaborativeApproval/rpaManagement/index.vue b/src/views/collaborativeApproval/rpaManagement/index.vue
new file mode 100644
index 0000000..51cef73
--- /dev/null
+++ b/src/views/collaborativeApproval/rpaManagement/index.vue
@@ -0,0 +1,400 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <div>
+        <span class="search_title">绋嬪簭鍚嶏細</span>
+        <el-input
+          v-model="searchForm.programName"
+          style="width: 240px"
+          placeholder="璇疯緭鍏ョ▼搴忓悕鎼滅储"
+          @change="handleQuery"
+          clearable
+          :prefix-icon="Search"
+        />
+        <span class="search_title ml10">鎵ц鐘舵�侊細</span>
+        <el-select v-model="searchForm.status" clearable @change="handleQuery" style="width: 240px">
+          <el-option label="杩愯涓�" :value="'running'" />
+          <el-option label="宸插仠姝�" :value="'stopped'" />
+          <el-option label="寮傚父" :value="'error'" />
+        </el-select>
+        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">
+          鎼滅储
+        </el-button>
+      </div>
+      <div>
+        <el-button type="primary" @click="openForm('add')">鏂板</el-button>
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+      </div>
+    </div>
+    <div class="table_list">
+      <PIMTable
+        rowKey="id"
+        :column="tableColumn"
+        :tableData="tableData"
+        :page="page"
+        :isSelection="true"
+        @selection-change="handleSelectionChange"
+        :tableLoading="tableLoading"
+        @pagination="pagination"
+        :total="page.total"
+      ></PIMTable>
+    </div>
+
+    <!-- RPA琛ㄥ崟寮圭獥 -->
+    <el-dialog
+      v-model="dialogVisible"
+      :title="dialogTitle"
+      width="500px"
+      :close-on-click-modal="false"
+    >
+      <el-form
+        ref="formRef"
+        :model="form"
+        :rules="rules"
+        label-width="100px"
+      >
+        <el-form-item label="绋嬪簭鍚�" prop="programName">
+          <el-input
+            v-model="form.programName"
+            placeholder="璇疯緭鍏ョ▼搴忓悕"
+            clearable
+          />
+        </el-form-item>
+        <el-form-item label="鎵ц鐘舵��" prop="status">
+          <el-select v-model="form.status" placeholder="璇烽�夋嫨鎵ц鐘舵��" style="width: 100%">
+            <el-option label="杩愯涓�" value="running" />
+            <el-option label="宸插仠姝�" value="stopped" />
+            <el-option label="寮傚父" value="error" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鎻忚堪" prop="description">
+          <el-input
+            v-model="form.description"
+            type="textarea"
+            :rows="3"
+            placeholder="璇疯緭鍏PA绋嬪簭鎻忚堪"
+            clearable
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <span class="dialog-footer">
+          <el-button @click="dialogVisible = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="submitForm">纭畾</el-button>
+        </span>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { Search } from "@element-plus/icons-vue";
+import { onMounted, ref, reactive, toRefs } from "vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import PIMTable from "@/components/PIMTable/PIMTable.vue";
+
+// 鍝嶅簲寮忔暟鎹�
+const data = reactive({
+  searchForm: {
+    programName: "",
+    status: "",
+  },
+  form: {
+    id: "",
+    programName: "",
+    status: "stopped",
+    description: "",
+    createTime: "",
+  },
+  dialogVisible: false,
+  dialogTitle: "",
+  dialogType: "add",
+  selectedIds: [],
+  tableLoading: false,
+  page: {
+    current: 1,
+    size: 100,
+    total: 0,
+  },
+  tableData: [],
+});
+
+const { searchForm, form, dialogVisible, dialogTitle, dialogType, selectedIds, tableLoading, page, tableData } = toRefs(data);
+
+// 琛ㄥ崟寮曠敤
+const formRef = ref();
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const rules = {
+  programName: [
+    { required: true, message: "璇疯緭鍏ョ▼搴忓悕", trigger: "blur" }
+  ],
+  status: [
+    { required: true, message: "璇烽�夋嫨鎵ц鐘舵��", trigger: "change" }
+  ]
+};
+
+// 琛ㄦ牸鍒楅厤缃�
+const tableColumn = ref([
+  {
+    label: "绋嬪簭鍚�",
+    prop: "programName",
+    // width: 200,
+  },
+  {
+    label: "鎵ц鐘舵��",
+    prop: "status",
+    dataType: "tag",
+    // width: 120,
+    formatData: (params) => {
+      const statusMap = {
+        running: "杩愯涓�",
+        stopped: "宸插仠姝�",
+        error: "寮傚父"
+      };
+      return statusMap[params] || params;
+    },
+    formatType: (params) => {
+      const typeMap = {
+        running: "success",
+        stopped: "info",
+        error: "danger"
+      };
+      return typeMap[params] || "info";
+    }
+  },
+  {
+    label: "鎻忚堪",
+    prop: "description",
+    // width: 300,
+    showOverflowTooltip: true,
+  },
+  {
+    label: "鍒涘缓鏃堕棿",
+    prop: "createTime",
+    // width: 180,
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    fixed: "right",
+    width: 230,
+    operation: [
+      {
+        name: "缂栬緫",
+        type: "text",
+        clickFun: (row) => {
+          openForm("edit", row);
+        }
+      },
+      {
+        name: "寮�濮�",
+        type: "text",
+        clickFun: (row) => {
+          handleStart(row);
+        },
+        disabled: (row) => row.status !== 'stopped'
+      },
+      {
+        name: "鍋滄",
+        type: "text",
+        clickFun: (row) => {
+          handleStop(row);
+        },
+        disabled: (row) => row.status === 'stopped'
+      }
+    ]
+  }
+]);
+
+// 妯℃嫙鏁版嵁
+const mockData = [
+  {
+    id: "1",
+    programName: "璁㈠崟澶勭悊RPA",
+    status: "running",
+    description: "鑷姩澶勭悊瀹㈡埛璁㈠崟锛屽寘鎷獙璇併�佸垎閰嶅拰纭",
+    createTime: "2024-01-15 10:30:00"
+  },
+  {
+    id: "2",
+    programName: "搴撳瓨鍚屾RPA",
+    status: "stopped",
+    description: "鍚屾澶氫釜浠撳簱鐨勫簱瀛樻暟鎹紝纭繚鏁版嵁涓�鑷存��",
+    createTime: "2024-01-14 15:20:00"
+  },
+  {
+    id: "3",
+    programName: "鎶ヨ〃鐢熸垚RPA",
+    status: "error",
+    description: "鑷姩鐢熸垚姣忔棩閿�鍞姤琛ㄥ拰搴撳瓨鎶ヨ〃",
+    createTime: "2024-01-13 09:15:00"
+  }
+];
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+  getList();
+});
+
+// 鏌ヨ鏁版嵁
+const handleQuery = () => {
+  page.value.current = 1;
+  getList();
+};
+
+const getList = () => {
+  tableLoading.value = true;
+  
+  // 妯℃嫙API璋冪敤寤惰繜
+  setTimeout(() => {
+    let filteredData = [...mockData];
+    
+    // 鏍规嵁鎼滅储鏉′欢杩囨护鏁版嵁
+    if (searchForm.value.programName) {
+      filteredData = filteredData.filter(item => 
+        item.programName.toLowerCase().includes(searchForm.value.programName.toLowerCase())
+      );
+    }
+    
+    if (searchForm.value.status) {
+      filteredData = filteredData.filter(item => item.status === searchForm.value.status);
+    }
+    
+    tableData.value = filteredData;
+    page.value.total = filteredData.length;
+    tableLoading.value = false;
+  }, 500);
+};
+
+// 鍒嗛〉澶勭悊
+const pagination = (obj) => {
+  page.value.current = obj.page;
+  page.value.size = obj.limit;
+  handleQuery();
+};
+
+// 閫夋嫨鍙樺寲澶勭悊
+const handleSelectionChange = (selection) => {
+  selectedIds.value = selection.map(item => item.id);
+};
+
+// 鎵撳紑琛ㄥ崟
+const openForm = (type, row) => {
+  dialogType.value = type;
+  dialogVisible.value = true;
+  
+  if (type === "add") {
+    dialogTitle.value = "娣诲姞RPA";
+    form.value = {
+      id: "",
+      programName: "",
+      status: "stopped",
+      description: "",
+      createTime: "",
+    };
+  } else {
+    dialogTitle.value = "缂栬緫RPA";
+    form.value = { ...row };
+  }
+};
+
+// 鎻愪氦琛ㄥ崟
+const submitForm = async () => {
+  if (!formRef.value) return;
+  
+  try {
+    await formRef.value.validate();
+    
+    if (dialogType.value === "add") {
+      // 娣诲姞鏂癛PA
+      const newRPA = {
+        id: Date.now().toString(),
+        programName: form.value.programName,
+        status: form.value.status,
+        description: form.value.description,
+        createTime: new Date().toLocaleString(),
+      };
+      
+      mockData.unshift(newRPA);
+      ElMessage.success("RPA娣诲姞鎴愬姛");
+    } else {
+      // 缂栬緫RPA
+      const index = mockData.findIndex(item => item.id === form.value.id);
+      if (index !== -1) {
+        mockData[index] = { ...form.value };
+        ElMessage.success("RPA鏇存柊鎴愬姛");
+      }
+    }
+    
+    dialogVisible.value = false;
+    getList();
+  } catch (error) {
+    console.error("琛ㄥ崟楠岃瘉澶辫触:", error);
+  }
+};
+
+// 寮�濮婻PA
+const handleStart = (row) => {
+  ElMessageBox.confirm(`纭畾瑕佸惎鍔≧PA绋嬪簭"${row.programName}"鍚楋紵`, "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    row.status = "running";
+    ElMessage.success("RPA鍚姩鎴愬姛");
+    getList();
+  }).catch(() => {
+    // 鐢ㄦ埛鍙栨秷
+  });
+};
+
+// 鍋滄RPA
+const handleStop = (row) => {
+  ElMessageBox.confirm(`纭畾瑕佸仠姝PA绋嬪簭"${row.programName}"鍚楋紵`, "鎻愮ず", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    row.status = "stopped";
+    ElMessage.success("RPA鍋滄鎴愬姛");
+    getList();
+  }).catch(() => {
+    // 鐢ㄦ埛鍙栨秷
+  });
+};
+
+// 鍒犻櫎RPA
+const handleDelete = () => {
+  let ids = [];
+  if (selectedIds.value.length > 0) {
+    ids = selectedIds.value.map((item) => item.id);
+  } else {
+    ElMessage.warning("璇烽�夋嫨瑕佸垹闄ょ殑RPA");
+    return;
+  }
+  
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚垹闄わ紝鏄惁纭鍒犻櫎锛�", "鍒犻櫎", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(() => {
+    // 浠庢ā鎷熸暟鎹腑鍒犻櫎閫変腑鐨勯」
+    ids.forEach(id => {
+      const index = mockData.findIndex(item => item.id === id);
+      if (index !== -1) {
+        mockData.splice(index, 1);
+      }
+    });
+    
+    ElMessage.success("鍒犻櫎鎴愬姛");
+    selectedIds.value = [];
+    getList();
+  }).catch(() => {
+    // 鐢ㄦ埛鍙栨秷
+  });
+};
+</script>
+
+<style scoped></style>
diff --git a/src/views/collaborativeApproval/warningSystem/index.vue b/src/views/collaborativeApproval/warningSystem/index.vue
new file mode 100644
index 0000000..b04c583
--- /dev/null
+++ b/src/views/collaborativeApproval/warningSystem/index.vue
@@ -0,0 +1,307 @@
+<template>
+  <div class="warning-system">
+    <h2>棰勮鑱斿姩鏈哄埗</h2>
+    
+    <!-- 缁熻鍗$墖 -->
+    <div class="stats">
+      <div class="stat-card red">
+        <span class="number">2</span>
+        <span class="label">绾㈣壊棰勮</span>
+      </div>
+      <div class="stat-card orange">
+        <span class="number">1</span>
+        <span class="label">姗欒壊棰勮</span>
+      </div>
+      <div class="stat-card yellow">
+        <span class="number">1</span>
+        <span class="label">榛勮壊棰勮</span>
+      </div>
+      <div class="stat-card green">
+        <span class="number">1</span>
+        <span class="label">缁胯壊棰勮</span>
+      </div>
+    </div>
+
+    <!-- 棰勮鍒楄〃 -->
+    <div class="warning-list">
+      <h3>棰勮鍒楄〃</h3>
+      <table>
+        <thead>
+          <tr>
+            <th>缂栧彿</th>
+            <th>鏍囬</th>
+            <th>绫诲瀷</th>
+            <th>绛夌骇</th>
+            <th>鐘舵��</th>
+            <th>璐d换浜�</th>
+            <th>鎿嶄綔</th>
+          </tr>
+        </thead>
+        <tbody>
+          <tr v-for="warning in warnings" :key="warning.id">
+            <td>{{ warning.id }}</td>
+            <td>{{ warning.title }}</td>
+            <td>{{ warning.type }}</td>
+            <td>
+              <span :class="['level-tag', warning.level]">
+                {{ warning.levelText }}
+              </span>
+            </td>
+            <td>
+              <span :class="['status-tag', warning.status]">
+                {{ warning.statusText }}
+              </span>
+            </td>
+            <td>{{ warning.responsible }}</td>
+            <td>
+              <button @click="viewDetail(warning)">鏌ョ湅璇︽儏</button>
+            </td>
+          </tr>
+        </tbody>
+      </table>
+    </div>
+
+    <!-- 璇︽儏瀵硅瘽妗� -->
+    <div v-if="showDetail" class="modal">
+      <div class="modal-content">
+        <h3>棰勮璇︽儏</h3>
+        <div v-if="currentWarning">
+          <p><strong>缂栧彿锛�</strong>{{ currentWarning.id }}</p>
+          <p><strong>鏍囬锛�</strong>{{ currentWarning.title }}</p>
+          <p><strong>绫诲瀷锛�</strong>{{ currentWarning.type }}</p>
+          <p><strong>绛夌骇锛�</strong>{{ currentWarning.levelText }}</p>
+          <p><strong>鎻忚堪锛�</strong>{{ currentWarning.description }}</p>
+          <p><strong>褰卞搷锛�</strong>{{ currentWarning.impact }}</p>
+          <p><strong>寤鸿锛�</strong>{{ currentWarning.suggestions }}</p>
+        </div>
+        <button @click="showDetail = false">鍏抽棴</button>
+      </div>
+    </div>
+  </div>
+</template>
+
+<script>
+export default {
+  name: 'WarningSystem',
+  data() {
+    return {
+      showDetail: false,
+      currentWarning: null,
+      warnings: [
+        {
+          id: 'W001',
+          title: '椤圭洰棰勭畻瓒呮敮棰勮',
+          type: '璐㈠姟棰勮',
+          level: 'red',
+          levelText: '绾㈣壊棰勮',
+          status: 'pending',
+          statusText: '寰呭鐞�',
+          responsible: '寮犵粡鐞�',
+          description: 'A椤圭洰棰勭畻鎵ц鐜囧凡杈�95%锛岄璁″皢瓒呭嚭棰勭畻鑼冨洿銆�',
+          impact: '褰卞搷椤圭洰鏁翠綋璐㈠姟鎸囨爣锛屽彲鑳藉鑷撮」鐩簭鎹�',
+          suggestions: '鏆傚仠闈炲繀瑕佹敮鍑猴紝浼樺寲璧勬簮閰嶇疆锛岀敵璇烽绠楄皟鏁�'
+        },
+        {
+          id: 'W002',
+          title: '鍚堝悓鍒版湡棰勮',
+          type: '鍚堣棰勮',
+          level: 'orange',
+          levelText: '姗欒壊棰勮',
+          status: 'processing',
+          statusText: '澶勭悊涓�',
+          responsible: '鏉庝富绠�',
+          description: '涓庝緵搴斿晢B鐨勫悎鍚屽皢浜�2024骞�1鏈�25鏃ュ埌鏈熴��',
+          impact: '褰卞搷渚涘簲閾剧ǔ瀹氭�э紝鍙兘瀵艰嚧鏈嶅姟涓柇',
+          suggestions: '璇勪及渚涘簲鍟嗚〃鐜帮紝鍑嗗缁鏉愭枡锛屽埗瀹氬閫夋柟妗�'
+        },
+        {
+          id: 'W003',
+          title: '璁惧缁存姢棰勮',
+          type: '杩愯惀棰勮',
+          level: 'yellow',
+          levelText: '榛勮壊棰勮',
+          status: 'pending',
+          statusText: '寰呭鐞�',
+          responsible: '鐜嬪伐绋嬪笀',
+          description: '鐢熶骇绾胯澶嘋宸茶繍琛�8000灏忔椂锛屾帴杩戠淮鎶ゅ懆鏈熴��',
+          impact: '鍙兘褰卞搷鐢熶骇鏁堢巼鍜屼骇鍝佽川閲�',
+          suggestions: '瀹夋帓缁存姢鏃堕棿锛屽噯澶囧浠讹紝鍒跺畾缁存姢璁″垝'
+        },
+        {
+          id: 'W004',
+          title: '浜哄憳閰嶇疆棰勮',
+          type: '杩愯惀棰勮',
+          level: 'green',
+          levelText: '缁胯壊棰勮',
+          status: 'resolved',
+          statusText: '宸茶В鍐�',
+          responsible: '璧礖R',
+          description: '鎶�鏈儴闂ㄤ汉鍛橀厤缃厖瓒筹紝椤圭洰杩涘害姝e父銆�',
+          impact: '鏃犺礋闈㈠奖鍝�',
+          suggestions: '缁х画鐩戞帶浜哄憳閰嶇疆鎯呭喌'
+        },
+        {
+          id: 'W005',
+          title: '璐ㄩ噺浜嬫晠棰勮',
+          type: '杩愯惀棰勮',
+          level: 'red',
+          levelText: '绾㈣壊棰勮',
+          status: 'pending',
+          statusText: '寰呭鐞�',
+          responsible: '闄堟�荤洃',
+          description: '浜у搧D鍦ㄥ鎴风幇鍦哄嚭鐜拌川閲忛棶棰樸��',
+          impact: '褰卞搷瀹㈡埛婊℃剰搴︼紝鍙兘閫犳垚缁忔祹鎹熷け',
+          suggestions: '绔嬪嵆鍙洖闂浜у搧锛屽垎鏋愬師鍥狅紝鍒跺畾鏀硅繘鎺柦'
+        }
+      ]
+    }
+  },
+  methods: {
+    viewDetail(warning) {
+      this.currentWarning = warning
+      this.showDetail = true
+    }
+  }
+}
+</script>
+
+<style scoped>
+.warning-system {
+  padding: 20px;
+  max-width: 1200px;
+  margin: 0 auto;
+}
+
+h2 {
+  color: #333;
+  margin-bottom: 30px;
+}
+
+.stats {
+  display: grid;
+  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+  gap: 20px;
+  margin-bottom: 30px;
+}
+
+.stat-card {
+  padding: 20px;
+  border-radius: 8px;
+  color: white;
+  text-align: center;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+}
+
+.stat-card.red { background: linear-gradient(135deg, #ff6b6b, #ee5a52); }
+.stat-card.orange { background: linear-gradient(135deg, #ffa726, #ff9800); }
+.stat-card.yellow { background: linear-gradient(135deg, #ffd54f, #ffc107); }
+.stat-card.green { background: linear-gradient(135deg, #66bb6a, #4caf50); }
+
+.stat-card .number {
+  display: block;
+  font-size: 32px;
+  font-weight: bold;
+  margin-bottom: 8px;
+}
+
+.stat-card .label {
+  font-size: 14px;
+  opacity: 0.9;
+}
+
+.warning-list h3 {
+  margin-bottom: 20px;
+  color: #333;
+}
+
+table {
+  width: 100%;
+  border-collapse: collapse;
+  background: white;
+  border-radius: 8px;
+  overflow: hidden;
+  box-shadow: 0 2px 8px rgba(0,0,0,0.1);
+}
+
+th, td {
+  padding: 12px;
+  text-align: left;
+  border-bottom: 1px solid #eee;
+}
+
+th {
+  background: #f8f9fa;
+  font-weight: 600;
+  color: #333;
+}
+
+.level-tag, .status-tag {
+  padding: 4px 8px;
+  border-radius: 4px;
+  font-size: 12px;
+  color: white;
+}
+
+.level-tag.red { background: #f56c6c; }
+.level-tag.orange { background: #e6a23c; }
+.level-tag.yellow { background: #e6a23c; }
+.level-tag.green { background: #67c23a; }
+
+.status-tag.pending { background: #f56c6c; }
+.status-tag.processing { background: #e6a23c; }
+.status-tag.resolved { background: #67c23a; }
+
+button {
+  padding: 6px 12px;
+  margin: 0 4px;
+  border: none;
+  border-radius: 4px;
+  cursor: pointer;
+  font-size: 12px;
+  background: #409eff;
+  color: white;
+}
+
+.modal {
+  position: fixed;
+  top: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  background: rgba(0,0,0,0.5);
+  display: flex;
+  align-items: center;
+  justify-content: center;
+}
+
+.modal-content {
+  background: white;
+  padding: 30px;
+  border-radius: 8px;
+  max-width: 600px;
+  width: 90%;
+  max-height: 80vh;
+  overflow-y: auto;
+}
+
+.modal-content h3 {
+  margin-bottom: 20px;
+  color: #333;
+}
+
+.modal-content p {
+  margin-bottom: 15px;
+  line-height: 1.6;
+}
+
+.modal-content strong {
+  color: #333;
+}
+
+.modal-content button {
+  background: #409eff;
+  color: white;
+  padding: 10px 20px;
+  font-size: 14px;
+}
+</style>
diff --git a/src/views/demo/fakePage/index.vue b/src/views/demo/fakePage/index.vue
new file mode 100644
index 0000000..7ef8b89
--- /dev/null
+++ b/src/views/demo/fakePage/index.vue
@@ -0,0 +1,248 @@
+<template>
+  <div class="app-container">
+    <el-card shadow="never">
+      <div class="toolbar">
+        <el-input
+          v-model="query.keyword"
+          placeholder="鎼滅储鍚嶇О/绫诲埆"
+          clearable
+          style="width: 240px"
+          @keyup.enter="handleSearch"
+        />
+        <el-select
+          v-model="query.status"
+          placeholder="鐘舵��"
+          clearable
+          style="width: 140px; margin-left: 12px"
+        >
+          <el-option label="鍚敤" value="鍚敤" />
+          <el-option label="鍋滅敤" value="鍋滅敤" />
+        </el-select>
+        <el-button type="primary" style="margin-left: 12px" @click="handleSearch">鏌ヨ</el-button>
+        <el-button @click="resetQuery">閲嶇疆</el-button>
+        <el-button type="success" plain style="float: right" @click="openCreate">鏂板</el-button>
+      </div>
+
+      <el-table :data="pagedList" border style="width: 100%" height="480" stripe>
+        <el-table-column prop="id" label="缂栧彿" width="90" sortable />
+        <el-table-column prop="name" label="鍚嶇О" min-width="140" />
+        <el-table-column prop="category" label="绫诲埆" width="120" />
+        <el-table-column prop="stock" label="搴撳瓨" width="100" sortable />
+        <el-table-column prop="price" label="鍗曚环(楼)" width="120">
+          <template #default="scope">{{ formatPrice(scope.row.price) }}</template>
+        </el-table-column>
+        <el-table-column label="鐘舵��" width="120">
+          <template #default="scope">
+            <el-tag :type="scope.row.status === '鍚敤' ? 'success' : 'info'">{{ scope.row.status }}</el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="updatedAt" label="鏇存柊鏃堕棿" min-width="160" />
+        <el-table-column label="鎿嶄綔" width="180" fixed="right">
+          <template #default="scope">
+            <el-button link type="primary" @click="openEdit(scope.row)">缂栬緫</el-button>
+            <el-button link type="danger" @click="handleDelete(scope.row)">鍒犻櫎</el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+
+      <div class="pagination">
+        <el-pagination
+          background
+          layout="total, sizes, prev, pager, next, jumper"
+          :total="filteredList.length"
+          :page-sizes="[5, 10, 20, 50]"
+          :page-size="pager.pageSize"
+          :current-page="pager.pageNum"
+          @size-change="handleSizeChange"
+          @current-change="handleCurrentChange"
+        />
+      </div>
+    </el-card>
+
+    <el-dialog v-model="dialogVisible" :title="isEdit ? '缂栬緫' : '鏂板'" width="520px">
+      <el-form :model="form" :rules="rules" ref="formRef" label-width="90px">
+        <el-form-item label="鍚嶇О" prop="name">
+          <el-input v-model="form.name" placeholder="璇疯緭鍏ュ悕绉�" />
+        </el-form-item>
+        <el-form-item label="绫诲埆" prop="category">
+          <el-select v-model="form.category" placeholder="璇烽�夋嫨绫诲埆" style="width: 100%">
+            <el-option label="鍘熸枡" value="鍘熸枡" />
+            <el-option label="鍗婃垚鍝�" value="鍗婃垚鍝�" />
+            <el-option label="鎴愬搧" value="鎴愬搧" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="搴撳瓨" prop="stock">
+          <el-input v-model.number="form.stock" type="number" min="0" />
+        </el-form-item>
+        <el-form-item label="鍗曚环(楼)" prop="price">
+          <el-input v-model.number="form.price" type="number" min="0" step="0.01" />
+        </el-form-item>
+        <el-form-item label="鐘舵��" prop="status">
+          <el-radio-group v-model="form.status">
+            <el-radio label="鍚敤">鍚敤</el-radio>
+            <el-radio label="鍋滅敤">鍋滅敤</el-radio>
+          </el-radio-group>
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <el-button @click="dialogVisible = false">鍙� 娑�</el-button>
+        <el-button type="primary" @click="submitForm">纭� 瀹�</el-button>
+      </template>
+    </el-dialog>
+  </div>
+  
+</template>
+
+<script setup>
+import { ref, reactive, computed, nextTick } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+
+defineOptions({ name: 'FakePage' })
+
+const query = reactive({
+  keyword: '',
+  status: ''
+})
+
+const pager = reactive({
+  pageNum: 1,
+  pageSize: 10
+})
+
+const allList = ref(generateMockData())
+
+const filteredList = computed(() => {
+  const keyword = (query.keyword || '').trim()
+  const status = query.status
+  return allList.value.filter(item => {
+    const hitKeyword = !keyword || item.name.includes(keyword) || item.category.includes(keyword)
+    const hitStatus = !status || item.status === status
+    return hitKeyword && hitStatus
+  })
+})
+
+const pagedList = computed(() => {
+  const start = (pager.pageNum - 1) * pager.pageSize
+  const end = start + pager.pageSize
+  return filteredList.value.slice(start, end)
+})
+
+function handleSearch() {
+  pager.pageNum = 1
+}
+
+function resetQuery() {
+  query.keyword = ''
+  query.status = ''
+  pager.pageNum = 1
+}
+
+function handleSizeChange(size) {
+  pager.pageSize = size
+  pager.pageNum = 1
+}
+
+function handleCurrentChange(page) {
+  pager.pageNum = page
+}
+
+function formatPrice(val) {
+  return Number(val || 0).toFixed(2)
+}
+
+// 鏂板/缂栬緫
+const dialogVisible = ref(false)
+const isEdit = ref(false)
+const formRef = ref()
+const form = reactive({ id: null, name: '', category: '', stock: 0, price: 0, status: '鍚敤' })
+
+const rules = {
+  name: [{ required: true, message: '璇疯緭鍏ュ悕绉�', trigger: 'blur' }],
+  category: [{ required: true, message: '璇烽�夋嫨绫诲埆', trigger: 'change' }],
+  stock: [{ required: true, message: '璇疯緭鍏ュ簱瀛�', trigger: 'blur' }],
+  price: [{ required: true, message: '璇疯緭鍏ュ崟浠�', trigger: 'blur' }]
+}
+
+function openCreate() {
+  isEdit.value = false
+  Object.assign(form, { id: null, name: '', category: '', stock: 0, price: 0, status: '鍚敤' })
+  dialogVisible.value = true
+  nextTick(() => formRef.value?.clearValidate?.())
+}
+
+function openEdit(row) {
+  isEdit.value = true
+  Object.assign(form, JSON.parse(JSON.stringify(row)))
+  dialogVisible.value = true
+  nextTick(() => formRef.value?.clearValidate?.())
+}
+
+function submitForm() {
+  formRef.value?.validate?.((valid) => {
+    if (!valid) return
+    if (isEdit.value) {
+      const index = allList.value.findIndex(x => x.id === form.id)
+      if (index > -1) {
+        allList.value[index] = { ...form, updatedAt: nowString() }
+        ElMessage.success('宸蹭繚瀛�')
+      }
+    } else {
+      const newId = Date.now()
+      allList.value.unshift({ ...form, id: newId, updatedAt: nowString() })
+      ElMessage.success('宸叉柊澧�')
+    }
+    dialogVisible.value = false
+  })
+}
+
+function handleDelete(row) {
+  ElMessageBox.confirm(`纭鍒犻櫎銆�${row.name}銆戝悧锛焋, '鎻愮ず', { type: 'warning' })
+    .then(() => {
+      allList.value = allList.value.filter(x => x.id !== row.id)
+      ElMessage.success('宸插垹闄�')
+    })
+    .catch(() => {})
+}
+
+function generateMockData() {
+  const categories = ['鍘熸枡', '鍗婃垚鍝�', '鎴愬搧']
+  const statusOptions = ['鍚敤', '鍋滅敤']
+  const list = []
+  for (let i = 1; i <= 36; i++) {
+    list.push({
+      id: i,
+      name: `鐗╂枡-${i.toString().padStart(3, '0')}`,
+      category: categories[i % categories.length],
+      stock: Math.floor(Math.random() * 1000),
+      price: (Math.random() * 500 + 10).toFixed(2),
+      status: statusOptions[i % 2],
+      updatedAt: nowString()
+    })
+  }
+  return list
+}
+
+function nowString() {
+  const d = new Date()
+  const yyyy = d.getFullYear()
+  const MM = String(d.getMonth() + 1).padStart(2, '0')
+  const dd = String(d.getDate()).padStart(2, '0')
+  const hh = String(d.getHours()).padStart(2, '0')
+  const mm = String(d.getMinutes()).padStart(2, '0')
+  const ss = String(d.getSeconds()).padStart(2, '0')
+  return `${yyyy}-${MM}-${dd} ${hh}:${mm}:${ss}`
+}
+</script>
+
+<style scoped>
+.toolbar {
+  margin-bottom: 12px;
+}
+.pagination {
+  margin-top: 12px;
+  text-align: right;
+}
+</style>
+
+
+
diff --git a/src/views/energyManagement/dynamicEnergySaving/index.vue b/src/views/energyManagement/dynamicEnergySaving/index.vue
new file mode 100644
index 0000000..2666e0f
--- /dev/null
+++ b/src/views/energyManagement/dynamicEnergySaving/index.vue
@@ -0,0 +1,659 @@
+<template>
+  <div class="app-container">
+    <!-- 杈圭紭璁$畻鐘舵�佺洃鎺� -->
+    <el-row :gutter="20" class="status-section">
+      <el-col :span="8">
+        <el-card class="status-card">
+          <div class="status-item">
+            <div class="status-icon">
+              <el-icon><Monitor /></el-icon>
+            </div>
+            <div class="status-info">
+              <div class="status-title">杈圭紭鏈嶅姟鍣ㄧ姸鎬�</div>
+              <div class="status-value" :class="edgeServerStatus.status">
+                {{ edgeServerStatus.status === 'online' ? '鍦ㄧ嚎' : '绂荤嚎' }}
+              </div>
+              <div class="status-detail">鏈�鍚庡績璺�: {{ formatTime(edgeServerStatus.lastHeartbeat) }}</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="8">
+        <el-card class="status-card">
+          <div class="status-item">
+            <div class="status-icon">
+              <el-icon><Cpu /></el-icon>
+            </div>
+            <div class="status-info">
+              <div class="status-title">妯″瀷杩愯鐘舵��</div>
+              <div class="status-value" :class="modelStatus.status">
+                {{ modelStatus.status === 'running' ? '杩愯涓�' : '宸插仠姝�' }}
+              </div>
+              <div class="status-detail">杩愯妯″瀷: {{ modelStatus.modelCount }}涓�</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+      <el-col :span="8">
+        <el-card class="status-card">
+          <div class="status-item">
+            <div class="status-icon">
+              <el-icon><TrendCharts /></el-icon>
+            </div>
+            <div class="status-info">
+              <div class="status-title">鑺傝兘鏁堟灉</div>
+              <div class="status-value success">{{ energySavingRate.toFixed(1) }}%</div>
+              <div class="status-detail">绱鑺傝兘: {{ totalEnergySaved.toFixed(1) }}kWh</div>
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+
+    <!-- 娉ㄦ按娉甸鐜囦紭鍖栨帶鍒� -->
+    <el-card class="control-section">
+      <template #header>
+        <span>娉ㄦ按娉甸鐜囦紭鍖栨帶鍒�</span>
+      </template>
+      
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <div class="pump-control">
+            <h4>瀹炴椂鍙傛暟鐩戞帶</h4>
+            <el-form label-width="120px">
+              <el-form-item label="鍦板眰鍘嬪姏 (MPa)">
+                <el-input v-model="pumpData.formationPressure" readonly>
+                  <template #append>MPa</template>
+                </el-input>
+              </el-form-item>
+              <el-form-item label="褰撳墠娉甸�� (Hz)">
+                <el-input v-model="pumpData.currentFrequency" readonly>
+                  <template #append>Hz</template>
+                </el-input>
+              </el-form-item>
+              <el-form-item label="浼樺寲鍚庢车閫� (Hz)">
+                <el-input v-model="pumpData.optimizedFrequency" readonly>
+                  <template #append>Hz</template>
+                </el-input>
+              </el-form-item>
+              <el-form-item label="鑳借�楅檷浣�">
+                <el-progress 
+                  :percentage="pumpData.energyReduction" 
+                  :color="getProgressColor"
+                  :format="format => `${format}%`"
+                />
+              </el-form-item>
+              <el-form-item label="娴侀噺 (m鲁/h)">
+                <el-input v-model="pumpData.flowRate" readonly>
+                  <template #append>m鲁/h</template>
+                </el-input>
+              </el-form-item>
+              <el-form-item label="鍔熺巼 (kW)">
+                <el-input v-model="pumpData.power" readonly>
+                  <template #append>kW</template>
+                </el-input>
+              </el-form-item>
+            </el-form>
+          </div>
+        </el-col>
+        
+        <el-col :span="12">
+          <div class="pump-chart">
+            <h4>棰戠巼浼樺寲瓒嬪娍</h4>
+            <div ref="frequencyChart" style="height: 300px;"></div>
+          </div>
+        </el-col>
+      </el-row>
+      
+      <el-row :gutter="20" class="control-buttons">
+        <el-col :span="24">
+          <el-button 
+            type="primary" 
+            :disabled="!canControl"
+            @click="applyOptimization"
+          >
+            搴旂敤浼樺寲璁剧疆
+          </el-button>
+          <el-button 
+            type="warning" 
+            :disabled="!canControl"
+            @click="emergencyStop"
+          >
+            绱ф�ュ仠姝�
+          </el-button>
+          <el-button 
+            type="info" 
+            @click="showOptimizationHistory"
+          >
+            浼樺寲鍘嗗彶
+          </el-button>
+          <el-button 
+            type="success" 
+            @click="toggleAutoRefresh"
+          >
+            {{ autoRefreshStatus ? '鍋滄鑷姩鍒锋柊' : '寮�鍚嚜鍔ㄥ埛鏂�' }}
+          </el-button>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 杈圭紭璁$畻妯″瀷閰嶇疆 -->
+    <el-card class="model-section">
+      <template #header>
+        <span>杈圭紭璁$畻妯″瀷閰嶇疆</span>
+      </template>
+      
+      <el-table :data="modelConfigs" style="width: 100%" stripe>
+        <el-table-column prop="modelName" label="妯″瀷鍚嶇О" />
+        <el-table-column prop="version" label="鐗堟湰" />
+        <el-table-column prop="status" label="鐘舵��">
+          <template #default="scope">
+            <el-tag :type="scope.row.status === 'active' ? 'success' : 'info'">
+              {{ scope.row.status === 'active' ? '婵�娲�' : '寰呮満' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+        <el-table-column prop="accuracy" label="鍑嗙‘鐜�" />
+        <el-table-column prop="lastUpdate" label="鏈�鍚庢洿鏂�" />
+        <el-table-column label="鎿嶄綔">
+          <template #default="scope">
+            <el-button 
+              size="small" 
+              @click="updateModel(scope.row)"
+            >
+              鏇存柊妯″瀷
+            </el-button>
+            <el-button 
+              size="small" 
+              type="danger" 
+              @click="deleteModel(scope.row)"
+            >
+              鍒犻櫎
+            </el-button>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-card>
+
+    <!-- 鑳借�楀垎鏋愬浘琛� -->
+    <el-card class="analysis-section">
+      <template #header>
+        <span>鑳借�楀垎鏋�</span>
+      </template>
+      
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <div ref="energyChart" style="height: 400px;"></div>
+        </el-col>
+        <el-col :span="12">
+          <div ref="savingChart" style="height: 400px;"></div>
+        </el-col>
+      </el-row>
+    </el-card>
+
+    <!-- 浼樺寲鍘嗗彶瀵硅瘽妗� -->
+    <el-dialog v-model="historyDialogVisible" title="浼樺寲鍘嗗彶璁板綍" width="80%">
+      <el-table :data="optimizationHistory" style="width: 100%" stripe>
+        <el-table-column prop="timestamp" label="鏃堕棿" />
+        <el-table-column prop="formationPressure" label="鍦板眰鍘嬪姏 (MPa)" />
+        <el-table-column prop="oldFrequency" label="鍘熼鐜� (Hz)" />
+        <el-table-column prop="newFrequency" label="鏂伴鐜� (Hz)" />
+        <el-table-column prop="energySaved" label="鑺傝兘 (kWh)" />
+        <el-table-column prop="status" label="鐘舵��">
+          <template #default="scope">
+            <el-tag :type="scope.row.status === 'success' ? 'success' : 'warning'">
+              {{ scope.row.status === 'success' ? '鎴愬姛' : '澶辫触' }}
+            </el-tag>
+          </template>
+        </el-table-column>
+      </el-table>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, onMounted, onUnmounted, computed } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { Monitor, Cpu, TrendCharts } from '@element-plus/icons-vue'
+import * as echarts from 'echarts'
+
+// 鍝嶅簲寮忔暟鎹�
+const edgeServerStatus = ref({ status: 'online', lastHeartbeat: Date.now() })
+const modelStatus = ref({ status: 'running', modelCount: 3 })
+const energySavingRate = ref(15.8)
+const totalEnergySaved = ref(1250.5)
+const pumpData = ref({
+  formationPressure: 25.6,
+  currentFrequency: 45.2,
+  optimizedFrequency: 42.1,
+  energyReduction: 23,
+  flowRate: 180.5,
+  power: 85.3
+})
+
+const modelConfigs = ref([
+  {
+    modelName: '娉ㄦ按娉甸鐜囦紭鍖栨ā鍨�',
+    version: 'v2.1.0',
+    status: 'active',
+    accuracy: '94.2%',
+    lastUpdate: '2024-01-15 14:30:00'
+  },
+  {
+    modelName: '鍦板眰鍘嬪姏棰勬祴妯″瀷',
+    version: 'v1.8.5',
+    status: 'active',
+    accuracy: '91.7%',
+    lastUpdate: '2024-01-14 09:15:00'
+  },
+  {
+    modelName: '鑳借�楀垎鏋愭ā鍨�',
+    version: 'v2.0.3',
+    status: 'standby',
+    accuracy: '89.3%',
+    lastUpdate: '2024-01-13 16:45:00'
+  }
+])
+
+const historyDialogVisible = ref(false)
+const optimizationHistory = ref([])
+
+// 鍥捐〃寮曠敤
+const frequencyChart = ref(null)
+const energyChart = ref(null)
+const savingChart = ref(null)
+
+// 鑷姩鍒锋柊鐩稿叧
+const autoRefreshStatus = ref(true)
+const autoRefreshTimer = ref(null)
+const chartInstances = ref([])
+
+// 璁$畻灞炴��
+const canControl = computed(() => {
+  return edgeServerStatus.value.status === 'online' && modelStatus.value.status === 'running'
+})
+
+const getProgressColor = computed(() => {
+  return (percentage) => {
+    if (percentage < 20) return '#909399'
+    if (percentage < 40) return '#E6A23C'
+    if (percentage < 60) return '#409EFF'
+    return '#67C23A'
+  }
+})
+
+// 鐢熸垚妯℃嫙鏁版嵁
+const generateMockData = () => {
+  // 鐢熸垚闅忔満鍦板眰鍘嬪姏 (20-30 MPa)
+  const formationPressure = 20 + Math.random() * 10
+  
+  // 鏍规嵁鍦板眰鍘嬪姏璁$畻浼樺寲棰戠巼
+  const baseFrequency = 40 + (formationPressure - 25) * 2
+  const currentFrequency = baseFrequency + (Math.random() - 0.5) * 4
+  const optimizedFrequency = Math.max(35, baseFrequency - Math.random() * 3)
+  
+  // 璁$畻鑳借�楅檷浣�
+  const energyReduction = Math.round((currentFrequency - optimizedFrequency) / currentFrequency * 100)
+  
+  // 璁$畻娴侀噺鍜屽姛鐜�
+  const flowRate = 150 + Math.random() * 60
+  const power = 70 + Math.random() * 30
+  
+  // 鏇存柊娉垫暟鎹�
+  pumpData.value = {
+    formationPressure: parseFloat(formationPressure.toFixed(1)),
+    currentFrequency: parseFloat(currentFrequency.toFixed(1)),
+    optimizedFrequency: parseFloat(optimizedFrequency.toFixed(1)),
+    energyReduction: Math.min(energyReduction, 35),
+    flowRate: parseFloat(flowRate.toFixed(1)),
+    power: parseFloat(power.toFixed(1))
+  }
+  
+  // 鏇存柊鑺傝兘鏁堟灉
+  energySavingRate.value = 12 + Math.random() * 8
+  totalEnergySaved.value += Math.random() * 2
+  
+  // 鏇存柊杈圭紭鏈嶅姟鍣ㄧ姸鎬�
+  edgeServerStatus.value.lastHeartbeat = Date.now()
+  
+  // 闅忔満鏇存柊妯″瀷鐘舵��
+  if (Math.random() > 0.95) {
+    modelStatus.value.modelCount = Math.max(1, modelStatus.value.modelCount + (Math.random() > 0.5 ? 1 : -1))
+  }
+  
+  // 娣诲姞浼樺寲鍘嗗彶璁板綍
+  if (Math.random() > 0.7) {
+    addOptimizationHistory()
+  }
+  
+  // 鏇存柊鍥捐〃鏁版嵁
+  updateCharts()
+}
+
+// 娣诲姞浼樺寲鍘嗗彶璁板綍
+const addOptimizationHistory = () => {
+  const timestamp = new Date().toLocaleString()
+  const record = {
+    timestamp,
+    formationPressure: pumpData.value.formationPressure,
+    oldFrequency: pumpData.value.currentFrequency,
+    newFrequency: pumpData.value.optimizedFrequency,
+    energySaved: parseFloat((Math.random() * 5 + 1).toFixed(2)),
+    status: Math.random() > 0.1 ? 'success' : 'failed'
+  }
+  
+  optimizationHistory.value.unshift(record)
+  
+  // 淇濇寔鏈�澶�100鏉¤褰�
+  if (optimizationHistory.value.length > 100) {
+    optimizationHistory.value = optimizationHistory.value.slice(0, 100)
+  }
+}
+
+// 鏇存柊鍥捐〃鏁版嵁
+const updateCharts = () => {
+  chartInstances.value.forEach(instance => {
+    if (instance && instance.setOption) {
+      // 杩欓噷鍙互鏇存柊鍥捐〃鏁版嵁
+      // 涓轰簡绠�鍖栵紝鎴戜滑鍙槸閲嶆柊鍒濆鍖栧浘琛�
+    }
+  })
+}
+
+// 鏂规硶
+const refreshData = () => {
+  generateMockData()
+  ElMessage.success('鏁版嵁鍒锋柊鎴愬姛')
+}
+
+const applyOptimization = async () => {
+  try {
+    await ElMessageBox.confirm('纭畾瑕佸簲鐢ㄥ綋鍓嶇殑浼樺寲璁剧疆鍚楋紵', '纭鎿嶄綔', {
+      confirmButtonText: '纭畾',
+      cancelButtonText: '鍙栨秷',
+      type: 'warning'
+    })
+    
+    // 搴旂敤浼樺寲璁剧疆
+    pumpData.value.currentFrequency = pumpData.value.optimizedFrequency
+    ElMessage.success('浼樺寲璁剧疆搴旂敤鎴愬姛')
+    refreshData()
+  } catch (error) {
+    if (error !== 'cancel') {
+      ElMessage.error('搴旂敤浼樺寲璁剧疆澶辫触')
+    }
+  }
+}
+
+const emergencyStop = async () => {
+  try {
+    await ElMessageBox.confirm('纭畾瑕佺揣鎬ュ仠姝㈡墍鏈夋敞姘存车鍚楋紵', '绱ф�ユ搷浣�', {
+      confirmButtonText: '纭畾',
+      cancelButtonText: '鍙栨秷',
+      type: 'error'
+    })
+    
+    // 鎵ц绱ф�ュ仠姝㈤�昏緫
+    pumpData.value.currentFrequency = 0
+    pumpData.value.optimizedFrequency = 0
+    ElMessage.success('绱ф�ュ仠姝㈡墽琛屾垚鍔�')
+  } catch (error) {
+    if (error !== 'cancel') {
+      ElMessage.error('绱ф�ュ仠姝㈡墽琛屽け璐�')
+    }
+  }
+}
+
+const showOptimizationHistory = () => {
+  historyDialogVisible.value = true
+}
+
+const updateModel = (model) => {
+  ElMessage.info(`鏇存柊妯″瀷: ${model.modelName}`)
+}
+
+const deleteModel = async (model) => {
+  try {
+    await ElMessageBox.confirm(`纭畾瑕佸垹闄ゆā鍨� ${model.modelName} 鍚楋紵`, '纭鍒犻櫎', {
+      confirmButtonText: '纭畾',
+      cancelButtonText: '鍙栨秷',
+      type: 'warning'
+    })
+    
+    const index = modelConfigs.value.findIndex(m => m.modelName === model.modelName)
+    if (index > -1) {
+      modelConfigs.value.splice(index, 1)
+      ElMessage.success('妯″瀷鍒犻櫎鎴愬姛')
+    }
+  } catch (error) {
+    if (error !== 'cancel') {
+      ElMessage.error('妯″瀷鍒犻櫎澶辫触')
+    }
+  }
+}
+
+const toggleAutoRefresh = () => {
+  autoRefreshStatus.value = !autoRefreshStatus.value
+  if (autoRefreshStatus.value) {
+    startAutoRefresh()
+    ElMessage.success('鑷姩鍒锋柊宸插紑鍚�')
+  } else {
+    stopAutoRefresh()
+    ElMessage.info('鑷姩鍒锋柊宸插叧闂�')
+  }
+}
+
+const startAutoRefresh = () => {
+  stopAutoRefresh() // 鍏堝仠姝箣鍓嶇殑瀹氭椂鍣�
+  autoRefreshTimer.value = setInterval(() => {
+    generateMockData()
+  }, 60000) // 1鍒嗛挓 = 60000姣
+}
+
+const stopAutoRefresh = () => {
+  if (autoRefreshTimer.value) {
+    clearInterval(autoRefreshTimer.value)
+    autoRefreshTimer.value = null
+  }
+}
+
+const formatTime = (timestamp) => {
+  return new Date(timestamp).toLocaleTimeString()
+}
+
+// 鍒濆鍖栧浘琛�
+const initCharts = () => {
+  // 棰戠巼浼樺寲瓒嬪娍鍥�
+  const frequencyChartInstance = echarts.init(frequencyChart.value)
+  const frequencyOption = {
+    title: { text: '娉甸鐜囦紭鍖栬秼鍔�' },
+    tooltip: { trigger: 'axis' },
+    legend: { data: ['褰撳墠棰戠巼', '浼樺寲棰戠巼', '鍦板眰鍘嬪姏'] },
+    xAxis: { type: 'category', data: ['00:00', '04:00', '08:00', '12:00', '16:00', '20:00'] },
+    yAxis: [
+      { type: 'value', name: '棰戠巼 (Hz)' },
+      { type: 'value', name: '鍘嬪姏 (MPa)' }
+    ],
+    series: [
+      {
+        name: '褰撳墠棰戠巼',
+        type: 'line',
+        data: [45.2, 44.8, 45.5, 45.1, 44.9, 45.2]
+      },
+      {
+        name: '浼樺寲棰戠巼',
+        type: 'line',
+        data: [42.1, 41.8, 42.3, 41.9, 41.7, 42.1]
+      },
+      {
+        name: '鍦板眰鍘嬪姏',
+        type: 'line',
+        yAxisIndex: 1,
+        data: [25.6, 25.8, 26.1, 25.9, 25.7, 25.6]
+      }
+    ]
+  }
+  frequencyChartInstance.setOption(frequencyOption)
+  chartInstances.value.push(frequencyChartInstance)
+
+  // 鑳借�楀垎鏋愬浘
+  const energyChartInstance = echarts.init(energyChart.value)
+  const energyOption = {
+    title: { text: '鏃ヨ兘鑰楀姣�' },
+    tooltip: { trigger: 'item' },
+    legend: { orient: 'vertical', left: 'left',top: 'center' },
+    series: [
+      {
+        name: '鑳借�楀垎甯�',
+        type: 'pie',
+        radius: '50%',
+        data: [
+          { value: 45, name: '娉ㄦ按娉�' },
+          { value: 25, name: '鐓ф槑绯荤粺' },
+          { value: 20, name: '閫氶绯荤粺' },
+          { value: 10, name: '鍏朵粬璁惧' }
+        ]
+      }
+    ]
+  }
+  energyChartInstance.setOption(energyOption)
+  chartInstances.value.push(energyChartInstance)
+
+  // 鑺傝兘鏁堟灉鍥�
+  const savingChartInstance = echarts.init(savingChart.value)
+  const savingOption = {
+    title: { text: '鑺傝兘鏁堟灉瓒嬪娍' },
+    tooltip: { trigger: 'axis' },
+    xAxis: { type: 'category', data: ['鍛ㄤ竴', '鍛ㄤ簩', '鍛ㄤ笁', '鍛ㄥ洓', '鍛ㄤ簲', '鍛ㄥ叚', '鍛ㄦ棩'] },
+    yAxis: { type: 'value', name: '鑺傝兘鐜� (%)' },
+    series: [
+      {
+        name: '鑺傝兘鐜�',
+        type: 'bar',
+        data: [12.5, 15.2, 18.7, 16.3, 19.1, 17.8, 15.8]
+      }
+    ]
+  }
+  savingChartInstance.setOption(savingOption)
+  chartInstances.value.push(savingChartInstance)
+}
+
+// 鐢熸垚鍒濆鍘嗗彶鏁版嵁
+const generateInitialHistory = () => {
+  for (let i = 0; i < 20; i++) {
+    const timestamp = new Date(Date.now() - i * 3600000).toLocaleString()
+    const record = {
+      timestamp,
+      formationPressure: parseFloat((20 + Math.random() * 10).toFixed(1)),
+      oldFrequency: parseFloat((40 + Math.random() * 10).toFixed(1)),
+      newFrequency: parseFloat((35 + Math.random() * 8).toFixed(1)),
+      energySaved: parseFloat((Math.random() * 5 + 1).toFixed(2)),
+      status: Math.random() > 0.1 ? 'success' : 'failed'
+    }
+    optimizationHistory.value.push(record)
+  }
+}
+
+// 鐢熷懡鍛ㄦ湡
+onMounted(() => {
+  initCharts()
+  generateInitialHistory()
+  refreshData()
+  if (autoRefreshStatus.value) {
+    startAutoRefresh()
+  }
+})
+
+onUnmounted(() => {
+  stopAutoRefresh()
+  chartInstances.value.forEach(instance => {
+    if (instance && instance.dispose) {
+      instance.dispose()
+    }
+  })
+})
+</script>
+
+<style scoped>
+.app-container {
+  padding: 20px;
+}
+
+
+
+.status-section {
+  margin-bottom: 20px;
+}
+
+.status-card {
+  height: 140px;
+}
+
+.status-item {
+  display: flex;
+  align-items: center;
+  height: 100%;
+}
+
+.status-icon {
+  font-size: 48px;
+  margin-right: 20px;
+  color: #409EFF;
+}
+
+.status-info {
+  flex: 1;
+}
+
+.status-title {
+  font-size: 14px;
+  color: #909399;
+  margin-bottom: 8px;
+}
+
+.status-value {
+  font-size: 24px;
+  font-weight: bold;
+  margin-bottom: 8px;
+}
+
+.status-detail {
+  font-size: 12px;
+  color: #909399;
+}
+
+.status-value.online,
+.status-value.running {
+  color: #67C23A;
+}
+
+.status-value.offline,
+.status-value.stopped {
+  color: #F56C6C;
+}
+
+.status-value.success {
+  color: #67C23A;
+}
+
+.control-section,
+.model-section,
+.analysis-section {
+  margin-bottom: 20px;
+}
+
+.pump-control h4,
+.pump-chart h4 {
+  margin-bottom: 20px;
+  color: #303133;
+}
+
+.control-buttons {
+  margin-top: 20px;
+  text-align: center;
+}
+
+.control-buttons .el-button {
+  margin: 0 10px;
+}
+</style>
diff --git a/src/views/energyManagement/energyArea/index.vue b/src/views/energyManagement/energyArea/index.vue
new file mode 100644
index 0000000..63feff8
--- /dev/null
+++ b/src/views/energyManagement/energyArea/index.vue
@@ -0,0 +1,511 @@
+<template>
+  <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
+        >
+      </div>
+      <div ref="containerRef">
+        <el-tree
+          ref="tree"
+          v-loading="treeLoad"
+          :data="list"
+          @node-click="handleNodeClick"
+          :expand-on-click-node="false"
+          default-expand-all
+          :default-expanded-keys="expandedKeys"
+          :draggable="true"
+          :filter-node-method="filterNode"
+          :props="{ children: 'children', label: 'label' }"
+          highlight-current
+          node-key="id"
+          style="
+            height: calc(100vh - 190px);
+            overflow-y: scroll;
+            scrollbar-width: none;
+            margin-top: 10px;
+          "
+        >
+          <template #default="{ node, data }">
+            <div class="custom-tree-node">
+              <span class="tree-node-content">
+                <el-icon class="orange-icon">
+                  <component :is="data.children && data.children.length > 0
+                  ? node.expanded ? 'FolderOpened' : 'Folder' : 'Tickets'" />
+                </el-icon>
+                {{ data.label }}
+              </span>
+              <div>
+                <el-button
+                  type="primary"
+                  link
+                  @click="openProDia('edit', data)"
+                >
+                  缂栬緫
+                </el-button>
+                <el-button type="primary" link @click="openModelDia('add','', data.id)">
+                  娣诲姞瀛愬尯鍩�
+                </el-button>
+                <el-button
+                  v-if="!node.childNodes.length"
+                  style="margin-left: 4px"
+                  type="danger"
+                  link
+                  @click="remove(node, data)"
+                >
+                  鍒犻櫎
+                </el-button>
+              </div>
+            </div>
+          </template>
+        </el-tree>
+      </div>
+    </div>
+    <div class="right">
+      <div style="margin-bottom: 10px" v-if="isShowButton">
+        <el-button type="primary" @click="openModelDia('add')">
+          鏂板瀛愬尯鍩�
+        </el-button>
+        <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>
+    </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-row :gutter="30">
+          <el-col :span="24">
+            <el-form-item label="鍖哄煙鍚嶇О锛�" prop="areaName">
+              <el-input
+                v-model="form.areaName"
+                placeholder="璇疯緭鍏ヤ骇鍝佸悕绉�"
+                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 @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-form-item label="鐖跺尯鍩燂細" prop="fuId">
+        <el-cascader v-model="modelForm.fuId" :options="list" :props="{
+          value: 'id',
+          label: 'label',
+          children: 'children',
+          checkStrictly: true,
+        }" />
+        </el-form-item>
+        <el-form-item label="鍖哄煙绫诲瀷锛�" prop="areaType">
+          <el-select v-model="modelForm.areaType" placeholder="璇烽�夋嫨">
+            <el-option v-for="item in area_type" :key="item.value" :label="item.label" :value="item.value" />
+          </el-select>
+        </el-form-item>
+        <el-form-item label="鍖哄煙鍚嶇О锛�" prop="areaName">
+          <el-input
+            v-model="modelForm.areaName"
+            placeholder="璇疯緭鍏ュ崟浣�"
+            clearable
+            @keydown.enter.prevent
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitModelForm">纭</el-button>
+          <el-button @click="closeModelDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref } from "vue";
+import { ElMessageBox } from "element-plus";
+import {
+  areaAdd,
+  areaDelete,
+  areaListPage,
+  areaListTree,
+} from "@/api/energyManagement/index.js";
+
+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 {area_type} = proxy.useDict("area_type")
+const tableColumn = ref([
+  {
+    label: "鍖哄煙鍚嶇О",
+    prop: "areaName",
+  },
+  {
+    label: "鍖哄煙绫诲瀷",
+    prop: "areaType",
+    dataType: "tag",
+    formatData: (row) => {
+      return area_type.value.find(item => item.value == row)?.label;
+    }
+  },
+  {
+    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: {
+    areaName: "",
+  },
+  rules: {
+    areaName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+  },
+  modelForm: {
+    areaName: "",
+    fuId: "",
+  },
+  modelRules: {
+    areaName: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    fuId: [{ required: true, message: "璇疯緭鍏�", trigger: "change" }],
+  },
+});
+const { form, rules, modelForm, modelRules } = toRefs(data);
+
+// 鏌ヨ浜у搧鏍�
+const getProductTreeList = () => {
+  treeLoad.value = true;
+  areaListTree()
+    .then((res) => {
+      list.value = res;
+      list.value.forEach((a) => {
+        expandedKeys.value.push(a.label);
+      });
+      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.areaName = "";
+  if (type === "edit") {
+    form.value.areaName = data.areaName;
+  }
+};
+// 鎵撳紑瑙勬牸鍨嬪彿寮规
+const openModelDia = (type, data,fatherId) => {
+  modelOperationType.value = type;
+  modelDia.value = true;
+  modelForm.value.fuId = "";
+  modelForm.value.areaType = "";
+  modelForm.value.areaName = "";
+  modelForm.value.id = "";
+  modelForm.value.fuId = fatherId;
+  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 = "";
+      }
+      areaAdd(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;
+      areaDelete(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(true);
+};
+
+// 鎻愪氦瑙勬牸鍨嬪彿淇敼
+const submitModelForm = () => {
+  proxy.$refs.modelFormRef.validate((valid) => {
+    if (valid) {
+      modelForm.value.fuId = currentId.value;
+      areaAdd(modelForm.value).then((res) => {
+        proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+        closeModelDia();
+        getModelList();
+        getProductTreeList();
+      });
+    }
+  });
+};
+// 鍏抽棴鍨嬪彿寮规
+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 = (val = false) => {
+  tableLoading.value = true;
+  let obj = {
+    id: currentId.value,
+    fuId:currentId.value,
+    current: page.current,
+    size: page.size
+  }
+  if(val){
+    delete obj.id;
+  }else{
+    delete obj.fuId
+  }
+  areaListPage(obj).then((res) => {
+    console.log("res", res);
+    tableData.value = res.data.records;
+    page.total = res.data.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;
+      areaDelete(ids)
+        .then((res) => {
+          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+          getModelList();     
+          getProductTreeList();
+        })
+        .finally(() => {
+          tableLoading.value = false;
+        });
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
+// 璋冪敤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) {
+      return true;
+    }
+    // 鍚﹀垯鐨勮瘽鍐嶅線涓婁竴灞傚仛鍖归厤
+    parentData = parentData.parent;
+    index++;
+  }
+  // 娌″尮閰嶅埌杩斿洖false
+  return false;
+};
+getProductTreeList();
+</script>
+
+<style scoped>
+.product-view {
+  display: flex;
+}
+.left {
+  width: 380px;
+  padding: 16px;
+  background: #ffffff;
+}
+.right {
+  width: calc(100% - 380px);
+  padding: 16px;
+  margin-left: 20px;
+  background: #ffffff;
+}
+.custom-tree-node {
+  flex: 1;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  font-size: 14px;
+  padding-right: 8px;
+}
+.tree-node-content {
+  display: flex;
+  align-items: center; /* 鍨傜洿灞呬腑 */
+  height: 100%;
+}
+.orange-icon {
+  color: orange;
+  font-size: 18px;
+  margin-right: 8px; /* 鍥炬爣涓庢枃瀛椾箣闂村姞鐐归棿璺� */
+}
+</style>
diff --git a/src/views/energyManagement/energyCockpit/index.vue b/src/views/energyManagement/energyCockpit/index.vue
new file mode 100644
index 0000000..9281e37
--- /dev/null
+++ b/src/views/energyManagement/energyCockpit/index.vue
@@ -0,0 +1,1380 @@
+<template>
+  <div class="app-container">
+    <!-- 椤甸潰鏍囬 -->
+    <div class="page-header">
+      <h2>鑳芥簮椹鹃┒鑸�</h2>
+      <div class="header-info">
+        <span class="update-time">鏈�鍚庢洿鏂帮細{{ lastUpdateTime }}</span>
+        <el-button type="primary" size="small" @click="refreshData">
+          <el-icon><Refresh /></el-icon>
+          鍒锋柊鏁版嵁
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 瀹炴椂鑳借�楃洃鎺� -->
+    <div class="real-time-monitor">
+      <el-row :gutter="20">
+        <el-col :span="8">
+          <el-card class="monitor-card">
+            <template #header>
+              <div class="card-header">
+                <span>鐢靛姏娑堣��</span>
+                <el-tag type="success" size="small">瀹炴椂</el-tag>
+              </div>
+            </template>
+            <div class="monitor-content">
+              <div class="monitor-value">
+                <span class="value">{{ electricityConsumption }}</span>
+                <span class="unit">kW路h</span>
+              </div>
+              <div class="monitor-trend">
+                <span class="trend-label">瓒嬪娍锛�</span>
+                <el-tag :type="getTrendType(electricityTrend)" size="small">
+                  {{ electricityTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(electricityTrend) }}%
+                </el-tag>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="8">
+          <el-card class="monitor-card">
+            <template #header>
+              <div class="card-header">
+                <span>姘存秷鑰�</span>
+                <el-tag type="primary" size="small">瀹炴椂</el-tag>
+              </div>
+            </template>
+            <div class="monitor-content">
+              <div class="monitor-value">
+                <span class="value">{{ waterConsumption }}</span>
+                <span class="unit">m鲁</span>
+              </div>
+              <div class="monitor-trend">
+                <span class="trend-label">瓒嬪娍锛�</span>
+                <el-tag :type="getTrendType(waterTrend)" size="small">
+                  {{ waterTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(waterTrend) }}%
+                </el-tag>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="8">
+          <el-card class="monitor-card">
+            <template #header>
+              <div class="card-header">
+                <span>姘斾綋娑堣��</span>
+                <el-tag type="warning" size="small">瀹炴椂</el-tag>
+              </div>
+            </template>
+            <div class="monitor-content">
+              <div class="monitor-value">
+                <span class="value">{{ gasConsumption }}</span>
+                <span class="unit">m鲁</span>
+              </div>
+              <div class="monitor-trend">
+                <span class="trend-label">瓒嬪娍锛�</span>
+                <el-tag :type="getTrendType(gasTrend)" size="small">
+                  {{ gasTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(gasTrend) }}%
+                </el-tag>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 鑳借�楄秼鍔垮垎鏋� -->
+    <div class="trend-analysis">
+      <el-card>
+        <template #header>
+          <div class="card-header">
+            <span>鑳借�楄秼鍔垮垎鏋�</span>
+            <div class="time-selector">
+              <el-radio-group v-model="trendTimeUnit" @change="handleTrendTimeChange">
+                <el-radio value="hour">灏忔椂</el-radio>
+                <el-radio value="day">鏃�</el-radio>
+                <el-radio value="week">鍛�</el-radio>
+                <el-radio value="month">鏈�</el-radio>
+                <el-radio value="year">骞�</el-radio>
+              </el-radio-group>
+            </div>
+          </div>
+        </template>
+        <div class="chart-container">
+          <div ref="trendChart" style="width: 100%; height: 400px;"></div>
+        </div>
+      </el-card>
+    </div>
+
+    <!-- 鑳借�楃粺璁′笌鎺掑悕 -->
+    <div class="statistics-ranking">
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-card class="statistics-card">
+            <template #header>
+              <div class="card-header">
+                <span class="card-title">鑳借�楃粺璁℃姤琛�</span>
+                <div class="header-actions">
+                  <el-select v-model="statisticsPeriod" @change="handleStatisticsChange" size="small" style="width: 100px;">
+                    <el-option label="鏃ョ粺璁�" value="day" />
+                    <el-option label="鍛ㄧ粺璁�" value="week" />
+                    <el-option label="鏈堢粺璁�" value="month" />
+                    <el-option label="骞寸粺璁�" value="year" />
+                  </el-select>
+                </div>
+              </div>
+            </template>
+            <div class="statistics-content">
+              <div class="statistics-item">
+                <span class="label">鎬昏兘鑰楋細</span>
+                <span class="value">{{ totalEnergyConsumption }} kW路h</span>
+              </div>
+              <div class="statistics-item">
+                <span class="label">鍚屾瘮锛�</span>
+                <span class="value" :class="getComparisonClass(yearOverYear)">
+                  {{ yearOverYear > 0 ? '+' : '' }}{{ yearOverYear }}%
+                </span>
+              </div>
+              <div class="statistics-item">
+                <span class="label">鐜瘮锛�</span>
+                <span class="value" :class="getComparisonClass(monthOverMonth)">
+                  {{ monthOverMonth > 0 ? '+' : '' }}{{ monthOverMonth }}%
+                </span>
+              </div>
+              <div class="statistics-item">
+                <span class="label">鑺傝兘鐜囷細</span>
+                <span class="value success">{{ energySavingRate }}%</span>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card class="ranking-card">
+            <template #header>
+              <div class="card-header">
+                <span class="card-title">鑳借�楁帓鍚�</span>
+                <el-select v-model="rankingType" @change="handleRankingChange" size="small" style="width: 120px;">
+                  <el-option label="閮ㄩ棬鎺掑悕" value="department" />
+                  <el-option label="杞﹂棿鎺掑悕" value="workshop" />
+                  <el-option label="璁惧鎺掑悕" value="equipment" />
+                </el-select>
+              </div>
+            </template>
+            <div class="ranking-list">
+              <div v-for="(item, index) in rankingList" :key="index" class="ranking-item">
+                <div class="ranking-number" :class="getRankingClass(index + 1)">{{ index + 1 }}</div>
+                <div class="ranking-info">
+                  <div class="ranking-name">{{ item.name }}</div>
+                  <div class="ranking-value">{{ item.value }} kW路h</div>
+                </div>
+                <div class="ranking-trend">
+                  <el-tag :type="getTrendType(item.trend)" size="small">
+                    {{ item.trend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(item.trend) }}%
+                  </el-tag>
+                </div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 寮傚父鍒嗘瀽涓庢櫤鑳芥帶鍒� -->
+    <div class="analysis-control">
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-card class="abnormal-card">
+            <template #header>
+              <div class="card-header">
+                <span class="card-title">寮傚父鍒嗘瀽</span>
+                <el-tag type="danger" size="small">{{ abnormalCount }}涓紓甯�</el-tag>
+              </div>
+            </template>
+            <div class="abnormal-list">
+              <div v-for="(item, index) in abnormalList" :key="index" class="abnormal-item">
+                <div class="abnormal-icon">
+                  <el-icon :color="getAbnormalColor(item.level)">
+                    <Warning v-if="item.level === 'warning'" />
+                    <CircleClose v-else />
+                  </el-icon>
+                </div>
+                <div class="abnormal-content">
+                  <div class="abnormal-title">{{ item.title }}</div>
+                  <div class="abnormal-desc">{{ item.description }}</div>
+                  <div class="abnormal-time">{{ item.time }}</div>
+                </div>
+                <div class="abnormal-action">
+                  <el-button link size="small" @click="handleAbnormal(item)">澶勭悊</el-button>
+                </div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card class="control-card">
+            <template #header>
+              <div class="card-header">
+                <span class="card-title">鏅鸿兘鎺у埗绯荤粺</span>
+                <el-switch v-model="autoControlEnabled" @change="handleAutoControlChange" />
+              </div>
+            </template>
+            <div class="control-content">
+              <div class="control-item">
+                <span class="label">宄拌胺骞崇數浠风鐞嗭細</span>
+                <el-tag :type="getPriceType(currentPriceType)" size="small">
+                  {{ getPriceTypeText(currentPriceType) }}
+                </el-tag>
+              </div>
+              <div class="control-item">
+                <span class="label">璐熻嵎棰勬祴锛�</span>
+                <span class="value">{{ loadForecast }} kW</span>
+              </div>
+              <div class="control-item">
+                <span class="label">鑷姩鍚仠锛�</span>
+                <el-tag :type="autoStartStop ? 'success' : 'info'" size="small">
+                  {{ autoStartStop ? '宸插惎鐢�' : '宸茬鐢�' }}
+                </el-tag>
+              </div>
+              <div class="control-item">
+                <span class="label">鏅鸿兘璋冭妭锛�</span>
+                <el-progress :percentage="intelligentAdjustment" :color="getProgressColor" />
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 鐜繚鎸囨爣 -->
+    <div class="environmental-indicators">
+      <el-card>
+        <template #header>
+          <div class="card-header">
+            <span>鐜繚鎸囨爣鐩戞帶</span>
+          </div>
+        </template>
+        <el-row :gutter="20">
+          <el-col :span="8">
+            <div class="indicator-item">
+              <div class="indicator-title">纰虫帓鏀鹃噺</div>
+              <div class="indicator-value">{{ carbonEmission }} kg</div>
+              <div class="indicator-trend">
+                <span>鍚屾瘮锛�</span>
+                <span :class="getComparisonClass(carbonEmissionTrend)">
+                  {{ carbonEmissionTrend > 0 ? '+' : '' }}{{ carbonEmissionTrend }}%
+                </span>
+              </div>
+            </div>
+          </el-col>
+          <el-col :span="8">
+            <div class="indicator-item">
+              <div class="indicator-title">鐜繚杈炬爣鐜�</div>
+              <div class="indicator-value">{{ environmentalCompliance }}%</div>
+              <div class="indicator-trend">
+                <span>鐩爣锛�</span>
+                <span class="success">95%</span>
+              </div>
+            </div>
+          </el-col>
+          <el-col :span="8">
+            <div class="indicator-item">
+              <div class="indicator-title">缁胯壊鑳芥簮鍗犳瘮</div>
+              <div class="indicator-value">{{ greenEnergyRatio }}%</div>
+              <div class="indicator-trend">
+                <span>鐩爣锛�</span>
+                <span class="success">30%</span>
+              </div>
+            </div>
+          </el-col>
+        </el-row>
+      </el-card>
+    </div>
+
+    <!-- 澶氱淮搴︽姤琛� -->
+    <div class="multi-dimensional-reports">
+      <el-card>
+        <template #header>
+          <div class="card-header">
+            <span>澶氱淮搴︽姤琛�</span>
+          </div>
+        </template>
+        <div class="report-filters">
+          <el-row :gutter="20">
+            <el-col :span="6">
+              <el-form-item label="鏃堕棿缁村害">
+                <el-select v-model="reportTimeDimension" placeholder="閫夋嫨鏃堕棿缁村害">
+                  <el-option label="灏忔椂" value="hour" />
+                  <el-option label="鏃�" value="day" />
+                  <el-option label="鍛�" value="week" />
+                  <el-option label="鏈�" value="month" />
+                  <el-option label="骞�" value="year" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="閮ㄩ棬缁村害">
+                <el-select v-model="reportDepartmentDimension" placeholder="閫夋嫨閮ㄩ棬">
+                  <el-option label="鍏ㄩ儴閮ㄩ棬" value="all" />
+                  <el-option label="鐢熶骇閮�" value="production" />
+                  <el-option label="鎶�鏈儴" value="technology" />
+                  <el-option label="琛屾斂閮�" value="administration" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item label="璁惧缁村害">
+                <el-select v-model="reportEquipmentDimension" placeholder="閫夋嫨璁惧绫诲瀷">
+                  <el-option label="鍏ㄩ儴璁惧" value="all" />
+                  <el-option label="鐢靛姏璁惧" value="electricity" />
+                  <el-option label="姘村鐞嗚澶�" value="water" />
+                  <el-option label="姘斾綋璁惧" value="gas" />
+                </el-select>
+              </el-form-item>
+            </el-col>
+            <el-col :span="6">
+              <el-form-item>
+                <el-button type="primary" @click="generateReport">鐢熸垚鎶ヨ〃</el-button>
+              </el-form-item>
+            </el-col>
+          </el-row>
+        </div>
+        <div class="report-preview">
+          <div class="report-data">
+            <el-row :gutter="20">
+              <el-col :span="8">
+                <div class="data-card">
+                  <div class="data-title">鐢靛姏娑堣��</div>
+                  <div class="data-value">{{ reportData.electricity }} kW路h</div>
+                  <div class="data-trend">
+                    <span :class="getTrendClass(reportData.electricityTrend)">
+                      {{ reportData.electricityTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(reportData.electricityTrend) }}%
+                    </span>
+                  </div>
+                </div>
+              </el-col>
+              <el-col :span="8">
+                <div class="data-card">
+                  <div class="data-title">姘存秷鑰�</div>
+                  <div class="data-value">{{ reportData.water }} m鲁</div>
+                  <div class="data-trend">
+                    <span :class="getTrendClass(reportData.waterTrend)">
+                      {{ reportData.waterTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(reportData.waterTrend) }}%
+                    </span>
+                  </div>
+                </div>
+              </el-col>
+              <el-col :span="8">
+                <div class="data-card">
+                  <div class="data-title">姘斾綋娑堣��</div>
+                  <div class="data-value">{{ reportData.gas }} m鲁</div>
+                  <div class="data-trend">
+                    <span :class="getTrendClass(reportData.gasTrend)">
+                      {{ reportData.gasTrend > 0 ? '鈫�' : '鈫�' }} {{ Math.abs(reportData.gasTrend) }}%
+                    </span>
+                  </div>
+                </div>
+              </el-col>
+            </el-row>
+            
+            <div class="report-chart">
+              <div class="chart-title">鑳借�楄秼鍔垮浘</div>
+              <div class="chart-bars">
+                <div v-for="(item, index) in reportData.chartData" :key="index" class="chart-bar">
+                  <div class="bar-label">{{ item.label }}</div>
+                  <div class="bar-container">
+                    <div class="bar-fill" :style="{ height: item.percentage + '%', backgroundColor: item.color }"></div>
+                  </div>
+                  <div class="bar-value">{{ item.value }}</div>
+                </div>
+              </div>
+            </div>
+            
+            <div class="report-summary">
+              <div class="summary-item">
+                <span class="summary-label">鎬昏兘鑰楋細</span>
+                <span class="summary-value">{{ reportData.totalEnergy }} kW路h</span>
+              </div>
+              <div class="summary-item">
+                <span class="summary-label">骞冲潎鑳借�楋細</span>
+                <span class="summary-value">{{ reportData.averageEnergy }} kW路h</span>
+              </div>
+              <div class="summary-item">
+                <span class="summary-label">鑳借�楁晥鐜囷細</span>
+                <span class="summary-value">{{ reportData.efficiency }}%</span>
+              </div>
+            </div>
+          </div>
+        </div>
+      </el-card>
+    </div>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, onUnmounted, nextTick } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import * as echarts from 'echarts'
+import { 
+  Refresh, 
+  Download, 
+  Warning, 
+  CircleClose, 
+  Document, 
+  Edit, 
+  Bell
+} from '@element-plus/icons-vue'
+
+// 鍝嶅簲寮忔暟鎹�
+const lastUpdateTime = ref('')
+const electricityConsumption = ref(0)
+const waterConsumption = ref(0)
+const gasConsumption = ref(0)
+const electricityTrend = ref(0)
+const waterTrend = ref(0)
+const gasTrend = ref(0)
+
+// 瓒嬪娍鍒嗘瀽
+const trendTimeUnit = ref('day')
+const trendChart = ref(null)
+let chartInstance = null
+
+// 缁熻鎶ヨ〃
+const statisticsPeriod = ref('month')
+const totalEnergyConsumption = ref(0)
+const yearOverYear = ref(0)
+const monthOverMonth = ref(0)
+const energySavingRate = ref(0)
+
+// 鑳借�楁帓鍚�
+const rankingType = ref('department')
+const rankingList = ref([])
+
+// 寮傚父鍒嗘瀽
+const abnormalCount = ref(0)
+const abnormalList = ref([])
+
+// 鏅鸿兘鎺у埗
+const autoControlEnabled = ref(true)
+const currentPriceType = ref('peak')
+const loadForecast = ref(0)
+const autoStartStop = ref(true)
+const intelligentAdjustment = ref(0)
+
+// 鐜繚鎸囨爣
+const carbonEmission = ref(0)
+const carbonEmissionTrend = ref(0)
+const environmentalCompliance = ref(0)
+const greenEnergyRatio = ref(0)
+
+// 澶氱淮搴︽姤琛�
+const reportTimeDimension = ref('month')
+const reportDepartmentDimension = ref('all')
+const reportEquipmentDimension = ref('all')
+const reportData = ref({
+  electricity: 0,
+  water: 0,
+  gas: 0,
+  electricityTrend: 0,
+  waterTrend: 0,
+  gasTrend: 0,
+  totalEnergy: 0,
+  averageEnergy: 0,
+  efficiency: 0,
+  chartData: []
+})
+
+// 瀹氭椂鍣�
+let updateTimer = null
+
+// 鑾峰彇瓒嬪娍绫诲瀷鏍峰紡
+const getTrendType = (trend) => {
+  if (trend > 0) return 'danger'
+  if (trend < 0) return 'success'
+  return 'info'
+}
+
+// 鑾峰彇瀵规瘮绫诲瀷鏍峰紡
+const getComparisonClass = (value) => {
+  if (value > 0) return 'danger'
+  if (value < 0) return 'success'
+  return 'info'
+}
+
+// 鑾峰彇鎺掑悕鏍峰紡
+const getRankingClass = (rank) => {
+  if (rank === 1) return 'ranking-first'
+  if (rank === 2) return 'ranking-second'
+  if (rank === 3) return 'ranking-third'
+  return 'ranking-normal'
+}
+
+// 鑾峰彇寮傚父棰滆壊
+const getAbnormalColor = (level) => {
+  return level === 'warning' ? '#E6A23C' : '#F56C6C'
+}
+
+// 鑾峰彇鐢典环绫诲瀷鏍峰紡
+const getPriceType = (type) => {
+  const typeMap = {
+    peak: 'danger',
+    normal: 'warning',
+    valley: 'success'
+  }
+  return typeMap[type] || 'info'
+}
+
+// 鑾峰彇鐢典环绫诲瀷鏂囨湰
+const getPriceTypeText = (type) => {
+  const typeMap = {
+    peak: '宄版椂',
+    normal: '骞虫椂',
+    valley: '璋锋椂'
+  }
+  return typeMap[type] || '鏈煡'
+}
+
+// 鑾峰彇杩涘害鏉¢鑹�
+const getProgressColor = (percentage) => {
+  if (percentage < 50) return '#67C23A'
+  if (percentage < 80) return '#E6A23C'
+  return '#F56C6C'
+}
+
+// 鑾峰彇瓒嬪娍鏍峰紡
+const getTrendClass = (trend) => {
+  if (trend > 0) return 'trend-up'
+  if (trend < 0) return 'trend-down'
+  return 'trend-stable'
+}
+
+// 妯℃嫙鏁版嵁鐢熸垚
+const generateMockData = () => {
+  // 瀹炴椂鑳借�楁暟鎹�
+  electricityConsumption.value = Math.floor(Math.random() * 1000) + 2000
+  waterConsumption.value = Math.floor(Math.random() * 100) + 150
+  gasConsumption.value = Math.floor(Math.random() * 50) + 80
+  
+  // 瓒嬪娍鏁版嵁
+  electricityTrend.value = (Math.random() * 20 - 10).toFixed(1)
+  waterTrend.value = (Math.random() * 15 - 7.5).toFixed(1)
+  gasTrend.value = (Math.random() * 12 - 6).toFixed(1)
+  
+  // 缁熻鏁版嵁
+  totalEnergyConsumption.value = Math.floor(Math.random() * 50000) + 100000
+  yearOverYear.value = (Math.random() * 20 - 10).toFixed(1)
+  monthOverMonth.value = (Math.random() * 15 - 7.5).toFixed(1)
+  energySavingRate.value = (Math.random() * 10 + 5).toFixed(1)
+  
+  // 鎺掑悕鏁版嵁
+  rankingList.value = [
+    { name: '鐢熶骇杞﹂棿A', value: Math.floor(Math.random() * 5000) + 10000, trend: (Math.random() * 20 - 10).toFixed(1) },
+    { name: '鐢熶骇杞﹂棿B', value: Math.floor(Math.random() * 4000) + 8000, trend: (Math.random() * 20 - 10).toFixed(1) },
+    { name: '鎶�鏈爺鍙戦儴', value: Math.floor(Math.random() * 3000) + 6000, trend: (Math.random() * 20 - 10).toFixed(1) },
+    { name: '琛屾斂鍔炲叕鍖�', value: Math.floor(Math.random() * 2000) + 4000, trend: (Math.random() * 20 - 10).toFixed(1) },
+    { name: '鍚庡嫟淇濋殰鍖�', value: Math.floor(Math.random() * 1500) + 3000, trend: (Math.random() * 20 - 10).toFixed(1) }
+  ].sort((a, b) => b.value - a.value)
+  
+  // 寮傚父鏁版嵁
+  abnormalCount.value = Math.floor(Math.random() * 5) + 1
+  abnormalList.value = [
+    { level: 'warning', title: '鐢靛姏璐熻嵎杩囬珮', description: '鐢熶骇杞﹂棿A鐢靛姏璐熻嵎杈惧埌85%锛屽缓璁鏌ヨ澶囪繍琛岀姸鎬�', time: '2鍒嗛挓鍓�' },
+    { level: 'error', title: '姘村帇寮傚父', description: '姘村鐞嗚澶囧帇鍔涘紓甯革紝褰撳墠鍘嬪姏0.3MPa锛屼綆浜庢甯歌寖鍥�', time: '5鍒嗛挓鍓�' }
+  ]
+  
+  // 鏅鸿兘鎺у埗鏁版嵁
+  loadForecast.value = Math.floor(Math.random() * 500) + 1500
+  intelligentAdjustment.value = Math.floor(Math.random() * 30) + 60
+  
+  // 鐜繚鎸囨爣
+  carbonEmission.value = Math.floor(Math.random() * 1000) + 5000
+  carbonEmissionTrend.value = (Math.random() * 15 - 7.5).toFixed(1)
+  environmentalCompliance.value = (Math.random() * 5 + 95).toFixed(1)
+  greenEnergyRatio.value = (Math.random() * 10 + 25).toFixed(1)
+  
+  // 鏇存柊鏈�鍚庢洿鏂版椂闂�
+  lastUpdateTime.value = new Date().toLocaleString()
+  
+  // 鍚屾椂鏇存柊鎶ヨ〃鏁版嵁
+  generateReportData()
+}
+
+// 鍒濆鍖栬秼鍔垮浘琛�
+const initTrendChart = () => {
+  if (chartInstance) {
+    chartInstance.dispose()
+  }
+  
+  chartInstance = echarts.init(trendChart.value)
+  
+  const option = {
+    title: {
+      text: '鑳借�楄秼鍔垮垎鏋�',
+      left: 'center'
+    },
+    tooltip: {
+      trigger: 'axis'
+    },
+    legend: {
+      data: ['鐢靛姏', '姘�', '姘斾綋'],
+      bottom: 10
+    },
+    xAxis: {
+      type: 'category',
+      data: generateTimeData()
+    },
+    yAxis: {
+      type: 'value',
+      name: '娑堣�楅噺'
+    },
+    series: [
+      {
+        name: '鐢靛姏',
+        type: 'line',
+        data: generateSeriesData(),
+        smooth: true
+      },
+      {
+        name: '姘�',
+        type: 'line',
+        data: generateSeriesData(),
+        smooth: true
+      },
+      {
+        name: '姘斾綋',
+        type: 'line',
+        data: generateSeriesData(),
+        smooth: true
+      }
+    ]
+  }
+  
+  chartInstance.setOption(option)
+}
+
+// 鐢熸垚鏃堕棿鏁版嵁
+const generateTimeData = () => {
+  const data = []
+  const now = new Date()
+  
+  switch (trendTimeUnit.value) {
+    case 'hour':
+      for (let i = 23; i >= 0; i--) {
+        const time = new Date(now.getTime() - i * 60 * 60 * 1000)
+        data.unshift(time.getHours() + ':00')
+      }
+      break
+    case 'day':
+      for (let i = 29; i >= 0; i--) {
+        const time = new Date(now.getTime() - i * 24 * 60 * 60 * 1000)
+        data.unshift(time.getDate() + '鏃�')
+      }
+      break
+    case 'week':
+      for (let i = 11; i >= 0; i--) {
+        data.unshift(`绗�${12 - i}鍛╜)
+      }
+      break
+    case 'month':
+      for (let i = 11; i >= 0; i--) {
+        const month = (12 - i) % 12 || 12
+        data.unshift(`${month}鏈坄)
+      }
+      break
+    case 'year':
+      for (let i = 4; i >= 0; i--) {
+        const year = new Date().getFullYear() - i
+        data.unshift(`${year}骞碻)
+      }
+      break
+  }
+  
+  return data
+}
+
+// 鐢熸垚绯诲垪鏁版嵁
+const generateSeriesData = () => {
+  const data = []
+  const count = trendTimeUnit.value === 'hour' ? 24 : 
+                trendTimeUnit.value === 'day' ? 30 : 
+                trendTimeUnit.value === 'week' ? 12 : 
+                trendTimeUnit.value === 'month' ? 12 : 5
+  
+  for (let i = 0; i < count; i++) {
+    data.push(Math.floor(Math.random() * 1000) + 500)
+  }
+  
+  return data
+}
+
+// 澶勭悊瓒嬪娍鏃堕棿鍙樺寲
+const handleTrendTimeChange = () => {
+  nextTick(() => {
+    initTrendChart()
+  })
+}
+
+// 澶勭悊缁熻鍛ㄦ湡鍙樺寲
+const handleStatisticsChange = () => {
+  generateMockData()
+}
+
+// 澶勭悊鎺掑悕绫诲瀷鍙樺寲
+const handleRankingChange = () => {
+  // 鏍规嵁绫诲瀷閲嶆柊鐢熸垚鎺掑悕鏁版嵁
+  generateMockData()
+}
+
+// 澶勭悊鑷姩鎺у埗鍙樺寲
+const handleAutoControlChange = (value) => {
+  ElMessage.success(`鏅鸿兘鎺у埗绯荤粺宸�${value ? '鍚敤' : '绂佺敤'}`)
+}
+
+// 澶勭悊寮傚父
+const handleAbnormal = (item) => {
+  ElMessage.info(`姝e湪澶勭悊寮傚父锛�${item.title}`)
+}
+
+// 鍒锋柊鏁版嵁
+const refreshData = () => {
+  generateMockData()
+  if (chartInstance) {
+    initTrendChart()
+  }
+  ElMessage.success('鏁版嵁宸插埛鏂�')
+}
+
+// 瀵煎嚭缁熻
+const exportStatistics = () => {
+  ElMessage.success('缁熻鏁版嵁瀵煎嚭鎴愬姛')
+}
+
+// 瀵煎嚭鐜繚鎶ュ憡
+const exportEnvironmentalReport = () => {
+  ElMessage.success('鐜繚鎶ュ憡瀵煎嚭鎴愬姛')
+}
+
+// 鐢熸垚鑷畾涔夋姤琛�
+const generateCustomReport = () => {
+  ElMessage.info('鑷畾涔夋姤琛ㄥ姛鑳藉紑鍙戜腑...')
+}
+
+// 璁㈤槄鎶ヨ〃
+const subscribeReport = () => {
+  ElMessage.info('鎶ヨ〃璁㈤槄鍔熻兘寮�鍙戜腑...')
+}
+
+// 鐢熸垚鎶ヨ〃鏁版嵁
+const generateReportData = () => {
+  // 鐢熸垚鍩虹鏁版嵁
+  reportData.value.electricity = Math.floor(Math.random() * 5000) + 8000
+  reportData.value.water = Math.floor(Math.random() * 200) + 300
+  reportData.value.gas = Math.floor(Math.random() * 100) + 150
+  
+  // 鐢熸垚瓒嬪娍鏁版嵁
+  reportData.value.electricityTrend = (Math.random() * 20 - 10).toFixed(1)
+  reportData.value.waterTrend = (Math.random() * 15 - 7.5).toFixed(1)
+  reportData.value.gasTrend = (Math.random() * 12 - 6).toFixed(1)
+  
+  // 璁$畻鎬昏兘鑰楀拰骞冲潎鑳借��
+  reportData.value.totalEnergy = reportData.value.electricity + reportData.value.water * 0.1 + reportData.value.gas * 0.05
+  reportData.value.averageEnergy = Math.floor(reportData.value.totalEnergy / 3)
+  reportData.value.efficiency = (Math.random() * 20 + 80).toFixed(1)
+  
+  // 鐢熸垚鍥捐〃鏁版嵁
+  const labels = ['鍛ㄤ竴', '鍛ㄤ簩', '鍛ㄤ笁', '鍛ㄥ洓', '鍛ㄤ簲', '鍛ㄥ叚', '鍛ㄦ棩']
+  const colors = ['#409eff', '#67c23a', '#e6a23c', '#f56c6c', '#909399', '#9c27b0', '#ff9800']
+  
+  reportData.value.chartData = labels.map((label, index) => ({
+    label,
+    value: Math.floor(Math.random() * 1000) + 500,
+    percentage: Math.floor(Math.random() * 40) + 30,
+    color: colors[index]
+  }))
+}
+
+// 鐢熸垚鎶ヨ〃
+const generateReport = () => {
+  generateReportData()
+  ElMessage.success('鎶ヨ〃鐢熸垚鎴愬姛')
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+// 鍚姩瀹氭椂鏇存柊
+const startAutoUpdate = () => {
+  updateTimer = setInterval(() => {
+    generateMockData()
+    if (chartInstance) {
+      initTrendChart()
+    }
+  }, 60000) // 姣忓垎閽熸洿鏂颁竴娆�
+}
+
+// 鍋滄瀹氭椂鏇存柊
+const stopAutoUpdate = () => {
+  if (updateTimer) {
+    clearInterval(updateTimer)
+    updateTimer = null
+  }
+}
+
+// 缁勪欢鎸傝浇
+onMounted(() => {
+  generateMockData()
+  nextTick(() => {
+    initTrendChart()
+  })
+  startAutoUpdate()
+})
+
+// 缁勪欢鍗歌浇
+onUnmounted(() => {
+  stopAutoUpdate()
+  if (chartInstance) {
+    chartInstance.dispose()
+  }
+})
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+  padding: 12px;
+  background: #f5f5f5;
+  min-height: 100vh;
+}
+
+.page-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 12px;
+  padding: 16px;
+  background: white;
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+  h2 {
+    margin: 0;
+    color: #303133;
+    font-size: 22px;
+  }
+
+  .header-info {
+    display: flex;
+    align-items: center;
+    gap: 12px;
+
+    .update-time {
+      color: #909399;
+      font-size: 14px;
+    }
+  }
+}
+
+.real-time-monitor {
+  margin-bottom: 12px;
+
+  .monitor-card {
+    .monitor-content {
+      text-align: center;
+      padding: 16px 0;
+
+      .monitor-value {
+        margin-bottom: 12px;
+
+        .value {
+          font-size: 28px;
+          font-weight: bold;
+          color: #409eff;
+        }
+
+        .unit {
+          font-size: 14px;
+          color: #909399;
+          margin-left: 4px;
+        }
+      }
+
+      .monitor-trend {
+        .trend-label {
+          font-size: 14px;
+          color: #606266;
+          margin-right: 6px;
+        }
+      }
+    }
+  }
+}
+
+.trend-analysis {
+  margin-bottom: 12px;
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .time-selector {
+      .el-radio-group {
+        .el-radio {
+          margin-right: 4px;
+        }
+      }
+    }
+  }
+
+  .chart-container {
+    padding: 16px 0;
+  }
+}
+
+.statistics-ranking {
+  margin-bottom: 12px;
+
+  .statistics-card, .ranking-card {
+    height: 100%;
+    box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
+    border-radius: 8px;
+    transition: all 0.3s ease;
+
+    &:hover {
+      transform: translateY(-2px);
+      box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
+    }
+  }
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 12px 16px;
+    border-bottom: 1px solid #f0f0f0;
+    background: #fafafa;
+
+    .card-title {
+      font-size: 15px;
+      font-weight: 600;
+      color: #303133;
+    }
+
+    .header-actions {
+      display: flex;
+      gap: 8px;
+      align-items: center;
+    }
+  }
+
+  .statistics-content {
+    padding: 16px;
+
+    .statistics-item {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 12px;
+      padding: 10px 12px;
+      background: #f8f9fa;
+      border-radius: 6px;
+      transition: background-color 0.3s ease;
+
+      &:hover {
+        background: #e9ecef;
+      }
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+
+      .label {
+        color: #606266;
+        font-size: 14px;
+        font-weight: 500;
+      }
+
+      .value {
+        font-weight: bold;
+        font-size: 15px;
+
+        &.success {
+          color: #67c23a;
+        }
+      }
+    }
+  }
+
+  .ranking-list {
+    padding: 16px;
+
+    .ranking-item {
+      display: flex;
+      align-items: center;
+      padding: 12px;
+      margin-bottom: 6px;
+      background: #f8f9fa;
+      border-radius: 6px;
+      transition: all 0.3s ease;
+
+      &:hover {
+        background: #e9ecef;
+        transform: translateX(4px);
+      }
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+
+      .ranking-number {
+        width: 32px;
+        height: 32px;
+        border-radius: 50%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        font-weight: bold;
+        font-size: 14px;
+        margin-right: 12px;
+        box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+        &.ranking-first {
+          background: linear-gradient(135deg, #ffd700 0%, #ffed4e 100%);
+          color: #fff;
+        }
+
+        &.ranking-second {
+          background: linear-gradient(135deg, #c0c0c0 0%, #d4d4d4 100%);
+          color: #fff;
+        }
+
+        &.ranking-third {
+          background: linear-gradient(135deg, #cd7f32 0%, #daa520 100%);
+          color: #fff;
+        }
+
+        &.ranking-normal {
+          background: linear-gradient(135deg, #f5f5f5 0%, #e9ecef 100%);
+          color: #909399;
+        }
+      }
+
+      .ranking-info {
+        flex: 1;
+
+        .ranking-name {
+          font-weight: 600;
+          color: #303133;
+          margin-bottom: 4px;
+          font-size: 14px;
+        }
+
+        .ranking-value {
+          color: #606266;
+          font-size: 13px;
+          font-weight: 500;
+        }
+      }
+
+      .ranking-trend {
+        margin-left: 12px;
+      }
+    }
+  }
+}
+
+.analysis-control {
+  margin-bottom: 20px;
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+  }
+
+  .abnormal-list {
+    .abnormal-item {
+      display: flex;
+      align-items: flex-start;
+      padding: 15px 0;
+      border-bottom: 1px solid #f0f0f0;
+
+      &:last-child {
+        border-bottom: none;
+      }
+
+      .abnormal-icon {
+        margin-right: 15px;
+        margin-top: 2px;
+      }
+
+      .abnormal-content {
+        flex: 1;
+
+        .abnormal-title {
+          font-weight: bold;
+          color: #303133;
+          margin-bottom: 5px;
+        }
+
+        .abnormal-desc {
+          color: #606266;
+          font-size: 14px;
+          margin-bottom: 5px;
+        }
+
+        .abnormal-time {
+          color: #909399;
+          font-size: 12px;
+        }
+      }
+
+      .abnormal-action {
+        margin-left: 15px;
+      }
+    }
+  }
+
+  .control-content {
+    .control-item {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      margin-bottom: 20px;
+
+      &:last-child {
+        margin-bottom: 0;
+      }
+
+      .label {
+        color: #606266;
+        font-size: 14px;
+      }
+
+      .value {
+        font-weight: bold;
+        color: #303133;
+      }
+    }
+  }
+}
+
+.environmental-indicators {
+  margin-bottom: 20px;
+
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .header-actions {
+      display: flex;
+      gap: 10px;
+    }
+  }
+
+  .indicator-item {
+    text-align: center;
+    padding: 20px 0;
+
+    .indicator-title {
+      color: #606266;
+      font-size: 14px;
+      margin-bottom: 10px;
+    }
+
+    .indicator-value {
+      font-size: 24px;
+      font-weight: bold;
+      color: #409eff;
+      margin-bottom: 10px;
+    }
+
+    .indicator-trend {
+      font-size: 12px;
+      color: #909399;
+
+      .success {
+        color: #67c23a;
+      }
+    }
+  }
+}
+
+.multi-dimensional-reports {
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .header-actions {
+      display: flex;
+      gap: 10px;
+    }
+  }
+
+  .report-filters {
+    padding: 20px 0;
+    border-bottom: 1px solid #f0f0f0;
+    margin-bottom: 20px;
+  }
+
+  .report-preview {
+    .report-data {
+      padding: 20px 0;
+
+      .data-card {
+        text-align: center;
+        padding: 16px;
+        background: #f8f9fa;
+        border-radius: 8px;
+        margin-bottom: 16px;
+
+        .data-title {
+          color: #606266;
+          font-size: 14px;
+          margin-bottom: 8px;
+        }
+
+        .data-value {
+          font-size: 20px;
+          font-weight: bold;
+          color: #303133;
+          margin-bottom: 8px;
+        }
+
+        .data-trend {
+          font-size: 12px;
+
+          .trend-up {
+            color: #f56c6c;
+          }
+
+          .trend-down {
+            color: #67c23a;
+          }
+
+          .trend-stable {
+            color: #909399;
+          }
+        }
+      }
+
+      .report-chart {
+        margin: 20px 0;
+        padding: 20px;
+        background: #f8f9fa;
+        border-radius: 8px;
+
+        .chart-title {
+          text-align: center;
+          font-size: 16px;
+          font-weight: 600;
+          color: #303133;
+          margin-bottom: 16px;
+        }
+
+        .chart-bars {
+          display: flex;
+          justify-content: space-around;
+          align-items: flex-end;
+          height: 120px;
+
+          .chart-bar {
+            text-align: center;
+            flex: 1;
+            margin: 0 8px;
+
+            .bar-label {
+              font-size: 12px;
+              color: #606266;
+              margin-bottom: 8px;
+            }
+
+            .bar-container {
+              height: 80px;
+              background: #e9ecef;
+              border-radius: 4px;
+              position: relative;
+              margin-bottom: 8px;
+            }
+
+            .bar-fill {
+              position: absolute;
+              bottom: 0;
+              left: 0;
+              right: 0;
+              border-radius: 4px;
+              transition: height 0.3s ease;
+            }
+
+            .bar-value {
+              font-size: 12px;
+              color: #303133;
+              font-weight: 500;
+            }
+          }
+        }
+      }
+
+      .report-summary {
+        display: flex;
+        justify-content: space-around;
+        padding: 20px;
+        background: #f8f9fa;
+        border-radius: 8px;
+
+        .summary-item {
+          text-align: center;
+
+          .summary-label {
+            display: block;
+            color: #606266;
+            font-size: 14px;
+            margin-bottom: 8px;
+          }
+
+          .summary-value {
+            font-size: 18px;
+            font-weight: bold;
+            color: #303133;
+          }
+        }
+      }
+    }
+  }
+}
+
+// 閫氱敤鏍峰紡
+.card-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+}
+
+.success {
+  color: #67c23a;
+}
+
+.danger {
+  color: #f56c6c;
+}
+
+.warning {
+  color: #e6a23c;
+}
+
+.info {
+  color: #909399;
+}
+</style>
diff --git a/src/views/energyManagement/energyPeriodTime/index.vue b/src/views/energyManagement/energyPeriodTime/index.vue
new file mode 100644
index 0000000..0c94322
--- /dev/null
+++ b/src/views/energyManagement/energyPeriodTime/index.vue
@@ -0,0 +1,444 @@
+<template>
+  <div class="app-container">
+    <div class="search_form">
+      <div>
+        <span class="search_title">鏃ユ湡锛�</span>
+		<!-- <el-time-picker
+			style="width: 240px;margin-right: 10px"
+			v-model="searchForm.startTime"
+			value-format="HH:mm:ss"
+			format="HH:mm:ss"
+			type="time"
+			placeholder="璇烽�夋嫨寮�濮嬫椂闂�"
+			clearable
+		/> -->
+		<el-date-picker
+			v-model="searchForm.date"
+			type="date"
+			placeholder="璇烽�夋嫨鏃ユ湡"
+			:size="size"
+		/>
+        <!-- <el-time-picker
+            v-model="searchForm.timeRange"
+            is-range
+            arrow-control
+            range-separator="To"
+            start-placeholder="閫夋嫨缁撴潫鏃堕棿"
+            end-placeholder="閫夋嫨缁撴潫鏃堕棿"
+        /> -->
+        <span class="search_title">鐢典环锛堝厓/搴︼級锛�</span>
+        <el-input
+            v-model="searchForm.price"
+            style="width: 240px"
+            placeholder="璇疯緭鍏ョ數浠�"
+            @change="handleQuery"
+            clearable
+            :prefix-icon="Search"
+        />
+        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+        >鎼滅储</el-button>
+		<el-button @click="resetFilters">閲嶇疆</el-button>
+      </div>
+      <div>
+        <el-button type="primary" @click="openForm('add')">鏂板</el-button>
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+      </div>
+    </div>
+    <div class="table_list">
+      <PIMTable
+          rowKey="id"
+          :column="tableColumn"
+          :tableData="tableData"
+          :page="page"
+          :isSelection="true"
+          @selection-change="handleSelectionChange"
+          :tableLoading="tableLoading"
+          @pagination="pagination"
+      ></PIMTable>
+    </div>
+    <el-dialog
+        v-model="dialogFormVisible"
+        title="鐢ㄧ數鏃舵绠$悊"
+        width="70%"
+        @close="closeDia"
+    >
+      <el-form
+          :model="form"
+          label-width="140px"
+          label-position="top"
+          :rules="rules"
+          ref="formRef"
+      >
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="鏃ユ湡锛�" prop="date">
+              <el-date-picker
+                  style="width: 100%"
+                  v-model="form.date"
+                  value-format="YYYY-MM-DD"
+                  format="YYYY-MM-DD"
+                  type="date"
+                  placeholder="璇烽�夋嫨鏃ユ湡"
+                  clearable
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鐢典环锛堝厓/搴︼級锛�" prop="price">
+              <el-input
+                  v-model="form.price"
+                  placeholder="璇疯緭鍏ョ數浠�"
+                  clearable
+                  type="number"
+                  step="0.01"
+                  min="0"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+         <el-col :span="12">
+           <el-form-item label="宄版锛�" prop="peak">
+             <el-input
+                 v-model="form.peak"
+                 placeholder="璇疯緭鍏ュ嘲娈�"
+                 clearable
+                 type="number"
+                 step="0.01"
+                 min="0"
+             />
+           </el-form-item>
+         </el-col>
+          <el-col :span="12">
+            <el-form-item label="璋锋锛�" prop="valley">
+              <el-input
+                  v-model="form.valley"
+                  placeholder="璇疯緭鍏ヨ胺娈�"
+                  clearable
+                  type="number"
+                  step="0.01"
+                  min="0"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="30">
+         <el-col :span="12">
+           <el-form-item label="骞虫锛�" prop="flat">
+             <el-input
+                 v-model="form.flat"
+                 placeholder="璇疯緭鍏ュ钩娈�"
+                 clearable
+                 type="number"
+                 step="0.01"
+                 min="0"
+             />
+           </el-form-item>
+         </el-col>
+          <el-col :span="12">
+            <el-form-item label="灏栨锛�" prop="sharp">
+              <el-input
+                  v-model="form.sharp"
+                  placeholder="璇疯緭鍏ュ皷娈�"
+                  clearable
+                  type="number"
+                  step="0.01"
+                  min="0"
+              />
+            </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 @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+<script setup>
+import {Search} from "@element-plus/icons-vue";
+import {onMounted, ref} from "vue";
+import {ElMessageBox} from "element-plus";
+import {getToken} from "@/utils/auth.js";
+import {periodListPage,periodDelete,periodAdd,periodUpdate} from "@/api/energyManagement/index.js";
+const { proxy } = getCurrentInstance();
+
+const data = reactive({
+	searchForm: {
+		date: "",
+		price: ""
+	},
+	form: {
+		date: "",
+    	price: "",
+		peak: "",
+		valley: "",
+		flat: "",
+		sharp: ""
+	}
+});
+const { searchForm,form } = toRefs(data);
+const page = ref({
+  current: 1,
+  size: 10,
+  total: 0
+});
+const dialogFormVisible = ref(false);
+const selectedRows = ref([]);
+const operationType = ref('');
+const tableData = ref([]);
+const emit = defineEmits(['close'])
+const tableLoading = ref(false);
+const tableColumn = ref([
+	// {
+	// 	label: "鏃舵鍚嶇О",
+	// 	prop: "timeName",
+	// 	width: 200,
+	// },
+	{
+		label: "鏃ユ湡",
+		prop: "date",
+		width: 200,
+	},
+	{
+		label: "鐢典环锛堝厓/搴︼級",
+		prop: "price",
+		width: 200,
+	},
+		{
+		label: "宄版",
+		prop: "peak",
+	},
+	{
+		label: "璋锋",
+		prop: "valley",
+	},
+	{
+		label: "骞虫",
+		prop: "flat",
+	},
+	{
+		label: "灏栨",
+		prop: "sharp",
+	},
+	{
+		dataType: "action",
+		label: "鎿嶄綔",
+		align: "center",
+		fixed: 'right',
+		operation: [
+			{
+				name: "缂栬緫",
+				type: "text",
+				clickFun: (row) => {
+					openForm("edit", row);
+				},
+			},
+		],
+	},
+]);
+
+
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+	selectedRows.value = selection;
+};
+const formDia = ref()
+const upload = reactive({
+	// 鏄惁鏄剧ず寮瑰嚭灞傦紙瀹㈡埛瀵煎叆锛�
+	open: false,
+	// 寮瑰嚭灞傛爣棰橈紙瀹㈡埛瀵煎叆锛�
+	title: "",
+	// 鏄惁绂佺敤涓婁紶
+	isUploading: false,
+	// 璁剧疆涓婁紶鐨勮姹傚ご閮�
+	headers: { Authorization: "Bearer " + getToken() },
+	// 涓婁紶鐨勫湴鍧�
+	url: import.meta.env.VITE_APP_BASE_API + "/equipmentEnergyConsumption/importData",
+	// 鏂囦欢涓婁紶鍓嶇殑鍥炶皟
+	beforeUpload: (file) => {
+		console.log('鏂囦欢鍗冲皢涓婁紶', file);
+		// 鍙互鍦ㄦ澶勫仛鏂囦欢绫诲瀷鎴栧ぇ灏忔牎楠�
+		const isValid = file.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' || file.name.endsWith('.xlsx') || file.name.endsWith('.xls');
+		if (!isValid) {
+			proxy.$modal.msgError("鍙兘涓婁紶 Excel 鏂囦欢");
+		}
+		return isValid;
+	},
+	// 鏂囦欢鐘舵�佹敼鍙樻椂鐨勫洖璋�
+	onChange: (file, fileList) => {
+		console.log('鏂囦欢鐘舵�佹敼鍙�', file, fileList);
+	},
+	// 鏂囦欢涓婁紶鎴愬姛鏃剁殑鍥炶皟
+	onSuccess: (response, file, fileList) => {
+		console.log('涓婁紶鎴愬姛', response, file, fileList);
+		if(response.code === 200){
+			proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+		}else if(response.code === 500){
+			ElMessageBox.error(response.msg);
+		}else{
+			ElMessageBox.warning(response.msg);
+		}
+	},
+	// 鏂囦欢涓婁紶澶辫触鏃剁殑鍥炶皟
+	onError: (error, file, fileList) => {
+		console.error('涓婁紶澶辫触', error, file, fileList);
+		ElMessageBox.error("鏂囦欢涓婁紶澶辫触");
+	},
+	// 鏂囦欢涓婁紶杩涘害鍥炶皟
+	onProgress: (event, file, fileList) => {
+		console.log('涓婁紶涓�...', event.percent);
+	}
+});
+
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+	page.current = 1;
+	getList();
+};
+//閲嶇疆
+const resetFilters = () => {
+	searchForm.value = {
+		date: "",
+		price: ""
+	};
+  getList();
+
+};
+const pagination = (obj) => {
+	page.current = obj.page;
+	page.size = obj.limit;
+	getList();
+};
+const getList = () => {
+	tableLoading.value = true;
+	periodListPage({ ...searchForm, ...page.value }).then((res) => {
+			tableLoading.value = false;
+			if (res && res.data) {
+				tableData.value = res.data.records || [];
+				page.total = res.data.total || 0;
+			} else {
+				tableData.value = [];
+				page.total = 0;
+				ElMessageBox.warning('鏈幏鍙栧埌鏁版嵁');
+			}
+		})
+		.catch((err) => {
+			tableLoading.value = false;
+			console.error('鏁版嵁鍔犺浇澶辫触:', err);
+			ElMessageBox.error('鏁版嵁鍔犺浇澶辫触锛岃閲嶈瘯');
+		});
+};
+// 鎵撳紑寮规
+const openDialog = (type, row) => {
+  operationType.value = type;
+  dialogFormVisible.value = true;
+	// form.value.maintainer = userStore.nickName;
+	// form.value.maintenanceTime = getCurrentDate();
+	form.value = {}
+	proxy.resetForm("formRef");
+	periodListPage().then((res) => {
+		codeList.value = res.data;
+	});
+	if (type === "edit") {
+		form.value = {...row}
+	}
+}
+// 鎵撳紑寮规
+const openForm = (type, row) => {
+	openDialog(type, row)
+};
+// 鎻愪氦琛ㄥ崟
+const submitForm = () => {
+	proxy.$refs["formRef"].validate(valid => {
+		if (valid) {
+			if (operationType.value === "add") {
+				periodAdd(form.value).then(response => {
+					proxy.$modal.msgSuccess("鏂板鎴愬姛")
+					closeDia()
+					getList()
+				})
+			} else {
+				periodUpdate(form.value).then(response => {
+					proxy.$modal.msgSuccess("淇敼鎴愬姛")
+					closeDia()
+					getList()
+				})
+			}
+		}
+	})
+}
+// 鍏抽棴寮规
+const closeDia = () => {
+	proxy.resetForm("formRef");
+	dialogFormVisible.value = false;
+	emit('close')
+};
+/** 瀵煎叆鎸夐挳鎿嶄綔 */
+function handleImport() {
+	upload.title = "璁惧鑳借��";
+	upload.open = true;
+	// 娓呯┖涓婃涓婁紶鐨勬枃浠跺垪琛�
+	nextTick(() => {
+		proxy.$refs["uploadRef"]?.clearFiles();
+	});
+}
+function importTemplate() {
+	proxy.download(
+		"/equipmentEnergyConsumption/export",
+		{},
+		'璁惧鑳借�楀鍏ユā鐗�.xlsx'
+	);
+}
+/** 鎻愪氦涓婁紶鏂囦欢 */
+function submitFileForm() {
+	proxy.$refs["uploadRef"].submit();
+}
+
+/** 寮规鍏抽棴鏃舵竻绌烘枃浠跺垪琛� */
+function handleDialogClose() {
+	nextTick(() => {
+		proxy.$refs["uploadRef"]?.clearFiles();
+	});
+}
+
+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;
+		periodDelete(ids)
+			.then((res) => {
+				proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+				getList();
+			})
+			.finally(() => {
+				tableLoading.value = false;
+			});
+	})
+	.catch(() => {
+		proxy.$modal.msg("宸插彇娑�");
+	});
+};
+onMounted(() => {
+	getList();
+});
+</script>
+
+<style scoped>
+
+</style>
diff --git a/src/views/energyManagement/energyPower/components/formDia.vue b/src/views/energyManagement/energyPower/components/formDia.vue
index 30f1c36..518a254 100644
--- a/src/views/energyManagement/energyPower/components/formDia.vue
+++ b/src/views/energyManagement/energyPower/components/formDia.vue
@@ -35,6 +35,25 @@
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
+						<el-form-item label="鐢ㄧ數娑堣�楀尯鍩燂細" prop="electricityConsumptionAreaId">
+							<el-cascader
+								v-model="form.electricityConsumptionAreaId"
+								:options="areaList"
+								:props="{
+									value: 'id',
+									label: 'label',
+									children: 'children',
+									checkStrictly: true,
+								}"
+								placeholder="璇烽�夋嫨鍖哄煙"
+								clearable
+								style="width: 100%"
+							/>
+						</el-form-item>
+					</el-col>
+				</el-row>
+				<el-row :gutter="30">
+					<el-col :span="12">
 						<el-form-item label="姣忔棩闄愬埗鐢甸噺锛�" prop="everyNum">
 							<el-input
 								v-model="form.everyNum"
@@ -43,8 +62,6 @@
 							/>
 						</el-form-item>
 					</el-col>
-				</el-row>
-				<el-row :gutter="30">
 					<el-col :span="12">
 						<el-form-item label="棰濆畾鍔熺巼锛�" prop="powerRating">
 							<el-input
@@ -54,6 +71,8 @@
 							/>
 						</el-form-item>
 					</el-col>
+				</el-row>
+				<el-row :gutter="30">
 					<el-col :span="12">
 						<el-form-item label="瀹為檯鍔熺巼锛�" prop="powerActual">
 							<el-input
@@ -63,8 +82,6 @@
 							/>
 						</el-form-item>
 					</el-col>
-				</el-row>
-				<el-row :gutter="30">
 					<el-col :span="12">
 						<el-form-item label="杩愯鏃堕棿锛�" prop="runDate">
 							<el-date-picker
@@ -78,6 +95,8 @@
 							/>
 						</el-form-item>
 					</el-col>
+				</el-row>
+				<el-row :gutter="30">
 					<el-col :span="12">
 						<el-form-item label="褰撴棩鐢ㄧ數閲忥細" prop="dayNum">
 							<el-input
@@ -102,7 +121,7 @@
 <script setup>
 import {ref} from "vue";
 import useUserStore from "@/store/modules/user.js";
-import {deviceList, equipmentEnergyAdd, equipmentEnergyUpdate} from "@/api/energyManagement/index.js";
+import {deviceList, equipmentEnergyAdd, equipmentEnergyUpdate, areaListTree} from "@/api/energyManagement/index.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 const dialogFormVisible = ref(false);
@@ -118,6 +137,7 @@
 		powerActual: "",
 		runDate: "",
 		dayNum: "",
+		electricityConsumptionAreaId: "",
 	},
 	rules: {
 		code: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
@@ -126,10 +146,12 @@
 		powerRating: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
 		powerActual: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
 		dayNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+		electricityConsumptionAreaId: [{ required: true, message: "璇烽�夋嫨鍖哄煙", trigger: "change" }],
 	},
 })
 const { form, rules } = toRefs(data);
 const codeList = ref([])
+const areaList = ref([])
 
 // 鎵撳紑寮规
 const openDialog = (type, row) => {
@@ -139,11 +161,24 @@
 	// form.value.maintenanceTime = getCurrentDate();
 	form.value = {}
 	proxy.resetForm("formRef");
+	
+	// 鑾峰彇璁惧鍒楄〃
 	deviceList().then((res) => {
 		codeList.value = res.data;
 	});
+	
+	// 鑾峰彇鍖哄煙鍒楄〃
+	areaListTree().then((res) => {
+		areaList.value = res;
+		console.log("areaList", res);
+	});
+	
 	if (type === "edit") {
 		form.value = {...row}
+		// 缂栬緫鏃讹紝灏嗗崟涓狪D杞崲涓烘暟缁勬牸寮忕敤浜庡洖鏄�
+		if (row.electricityConsumptionAreaId) {
+			form.value.electricityConsumptionAreaId = [row.electricityConsumptionAreaId];
+		}
 	}
 }
 const setName = (code) => {
@@ -156,13 +191,19 @@
 const submitForm = () => {
 	proxy.$refs["formRef"].validate(valid => {
 		if (valid) {
+			// 鎻愪氦鍓嶅鐞� electricityConsumptionAreaId锛屽彇鏁扮粍鐨勬渶鍚庝竴涓��
+			const submitData = { ...form.value };
+			if (Array.isArray(submitData.electricityConsumptionAreaId) && submitData.electricityConsumptionAreaId.length > 0) {
+				submitData.electricityConsumptionAreaId = submitData.electricityConsumptionAreaId[submitData.electricityConsumptionAreaId.length - 1];
+			}
+			
 			if (operationType.value === "add") {
-				equipmentEnergyAdd(form.value).then(response => {
+				equipmentEnergyAdd(submitData).then(response => {
 					proxy.$modal.msgSuccess("鏂板鎴愬姛")
 					closeDia()
 				})
 			} else {
-				equipmentEnergyUpdate(form.value).then(response => {
+				equipmentEnergyUpdate(submitData).then(response => {
 					proxy.$modal.msgSuccess("淇敼鎴愬姛")
 					closeDia()
 				})
diff --git a/src/views/energyManagement/gasManagement/index.vue b/src/views/energyManagement/gasManagement/index.vue
new file mode 100644
index 0000000..59ca9f7
--- /dev/null
+++ b/src/views/energyManagement/gasManagement/index.vue
@@ -0,0 +1,624 @@
+<template>
+  <div class="app-container">
+    <!-- 椤甸潰鏍囬 -->
+    <div class="page-header">
+      <h2>鐢ㄦ皵绠$悊绯荤粺</h2>
+      <div class="header-info">
+        <span class="update-time">鏈�鍚庢洿鏂帮細{{ lastUpdateTime }}</span>
+        <el-button type="primary" size="small" @click="refreshData">
+          <el-icon><Refresh /></el-icon>
+          鍒锋柊鏁版嵁
+        </el-button>
+      </div>
+    </div>
+
+    <!-- 缁熻鍗$墖鍖哄煙 -->
+    <div class="stats-cards">
+      <el-row :gutter="20">
+        <el-col :span="6">
+          <el-card class="stat-card">
+            <div class="stat-content">
+              <div class="stat-icon gas-device">
+                <el-icon size="32"><Box /></el-icon>
+              </div>
+              <div class="stat-info">
+                <div class="stat-value">{{ totalDevices }}</div>
+                <div class="stat-label">鍦ㄧ敤璁惧</div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="6">
+          <el-card class="stat-card">
+            <div class="stat-content">
+              <div class="stat-icon daily-consumption">
+                <el-icon size="32"><TrendCharts /></el-icon>
+              </div>
+              <div class="stat-info">
+                <div class="stat-value">{{ dailyConsumption }} m鲁</div>
+                <div class="stat-label">鏃ヨ�楅噺</div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="6">
+          <el-card class="stat-card">
+            <div class="stat-content">
+              <div class="stat-icon monthly-consumption">
+                <el-icon size="32"><DataLine /></el-icon>
+              </div>
+              <div class="stat-info">
+                <div class="stat-value">{{ monthlyConsumption }} m鲁</div>
+                <div class="stat-label">鏈堣�楅噺</div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="6">
+          <el-card class="stat-card">
+            <div class="stat-content">
+              <div class="stat-icon gas-price">
+                <el-icon size="32"><Money /></el-icon>
+              </div>
+              <div class="stat-info">
+                <div class="stat-value">楼{{ gasUnitPrice }}</div>
+                <div class="stat-label">姘斾綋鍗曚环</div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 璐圭敤缁熻鍖哄煙 -->
+    <div class="cost-stats">
+      <el-row :gutter="20">
+        <el-col :span="12">
+          <el-card class="cost-card">
+            <template #header>
+              <div class="card-header">
+                <span>鏃ヨ垂鐢ㄧ粺璁�</span>
+                <el-tag type="success" size="small">浠婃棩</el-tag>
+              </div>
+            </template>
+            <div class="cost-content">
+              <div class="cost-main">
+                <span class="cost-amount">楼{{ dailyTotalCost.toFixed(2) }}</span>
+                <span class="cost-unit">鍏�</span>
+              </div>
+              <div class="cost-details">
+                <div class="cost-item">
+                  <span>娑堣�楅噺锛�</span>
+                  <span>{{ dailyConsumption }} m鲁</span>
+                </div>
+                <div class="cost-item">
+                  <span>鍗曚环锛�</span>
+                  <span>楼{{ gasUnitPrice }}/m鲁</span>
+                </div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+        <el-col :span="12">
+          <el-card class="cost-card">
+            <template #header>
+              <div class="card-header">
+                <span>鏈堣垂鐢ㄧ粺璁�</span>
+                <el-tag type="primary" size="small">鏈湀</el-tag>
+              </div>
+            </template>
+            <div class="cost-content">
+              <div class="cost-main">
+                <span class="cost-amount">楼{{ monthlyTotalCost.toFixed(2) }}</span>
+                <span class="cost-unit">鍏�</span>
+              </div>
+              <div class="cost-details">
+                <div class="cost-item">
+                  <span>娑堣�楅噺锛�</span>
+                  <span>{{ monthlyConsumption }} m鲁</span>
+                </div>
+                <div class="cost-item">
+                  <span>骞冲潎鍗曚环锛�</span>
+                  <span>楼{{ gasUnitPrice }}/m鲁</span>
+                </div>
+              </div>
+            </div>
+          </el-card>
+        </el-col>
+      </el-row>
+    </div>
+
+    <!-- 璁惧鍒楄〃鍖哄煙 -->
+    <div class="device-section">
+      <el-card>
+        <template #header>
+                     <div class="card-header">
+             <span>璁惧鐩戞帶</span>
+             <div class="header-actions">
+               <el-button type="primary" size="small" @click="addDevice">
+                 <el-icon><Plus /></el-icon>
+                 娣诲姞璁惧
+               </el-button>
+             </div>
+           </div>
+        </template>
+        
+        <el-table :data="deviceList" border style="width: 100%" v-loading="tableLoading" stripe>
+          <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+          <el-table-column label="璁惧缂栧彿" prop="deviceCode" width="120" show-overflow-tooltip />
+          <el-table-column label="璁惧鍚嶇О" prop="deviceName" width="150" show-overflow-tooltip />
+          <el-table-column label="璁惧绫诲瀷" prop="deviceType" width="120" show-overflow-tooltip />
+          <el-table-column label="瑙勬牸鍨嬪彿" prop="specification" width="150" show-overflow-tooltip />
+          <el-table-column label="褰撳墠鍘嬪姏(MPa)" prop="currentPressure" width="130" show-overflow-tooltip>
+            <template #default="scope">
+              <span :class="getPressureClass(scope.row.currentPressure)">
+                {{ scope.row.currentPressure }}
+              </span>
+            </template>
+          </el-table-column>
+          <el-table-column label="褰撳墠娓╁害(鈩�)" prop="currentTemperature" width="130" show-overflow-tooltip>
+            <template #default="scope">
+              <span :class="getTemperatureClass(scope.row.currentTemperature)">
+                {{ scope.row.currentTemperature }}
+              </span>
+            </template>
+          </el-table-column>
+          <el-table-column label="姘斾綋娴撳害(ppm)" prop="gasConcentration" width="140" show-overflow-tooltip>
+            <template #default="scope">
+              <span :class="getConcentrationClass(scope.row.gasConcentration)">
+                {{ scope.row.gasConcentration }}
+              </span>
+            </template>
+          </el-table-column>
+          <el-table-column label="杩愯鐘舵��" prop="status" width="100" show-overflow-tooltip>
+            <template #default="scope">
+              <el-tag :type="getStatusType(scope.row.status)" size="small">
+                {{ getStatusText(scope.row.status) }}
+              </el-tag>
+            </template>
+          </el-table-column>
+          <el-table-column label="鏈�鍚庢洿鏂�" prop="lastUpdate" width="160" show-overflow-tooltip />
+                     <el-table-column label="鎿嶄綔" align="center" width="100" fixed="right">
+             <template #default="scope">
+               <el-button link size="small" @click="editDevice(scope.row)">
+                 缂栬緫
+               </el-button>
+             </template>
+           </el-table-column>
+        </el-table>
+      </el-card>
+    </div>
+
+    <!-- 娣诲姞/缂栬緫璁惧寮圭獥 -->
+    <el-dialog v-model="deviceDialogVisible" :title="dialogTitle" width="600px">
+      <el-form :model="deviceForm" :rules="deviceRules" ref="deviceFormRef" label-width="120px">
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="璁惧缂栧彿" prop="deviceCode">
+              <el-input v-model="deviceForm.deviceCode" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="璁惧鍚嶇О" prop="deviceName">
+              <el-input v-model="deviceForm.deviceName" placeholder="璇疯緭鍏ヨ澶囧悕绉�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="璁惧绫诲瀷" prop="deviceType">
+              <el-select v-model="deviceForm.deviceType" placeholder="璇烽�夋嫨璁惧绫诲瀷" style="width: 100%">
+                <el-option label="娑插寲姘斿偍缃�" value="娑插寲姘斿偍缃�" />
+                <el-option label="鍘嬬缉姘斿偍缃�" value="鍘嬬缉姘斿偍缃�" />
+                <el-option label="澶╃劧姘斿偍缃�" value="澶╃劧姘斿偍缃�" />
+                <el-option label="姘ф皵鍌ㄧ綈" value="姘ф皵鍌ㄧ綈" />
+                <el-option label="鍏朵粬" value="鍏朵粬" />
+              </el-select>
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瑙勬牸鍨嬪彿" prop="specification">
+              <el-input v-model="deviceForm.specification" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="璁捐鍘嬪姏(MPa)" prop="designPressure">
+              <el-input-number v-model="deviceForm.designPressure" :min="0" :precision="2" style="width: 100%" />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="瀹圭Н(m鲁)" prop="volume">
+              <el-input-number v-model="deviceForm.volume" :min="0" :precision="2" style="width: 100%" />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <el-button @click="deviceDialogVisible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="saveDevice">淇濆瓨</el-button>
+      </template>
+    </el-dialog>
+  </div>
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, onUnmounted } from 'vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import { 
+  Refresh, 
+  Box, 
+  TrendCharts, 
+  DataLine, 
+  Money, 
+  Plus
+} from '@element-plus/icons-vue'
+
+// 鍝嶅簲寮忔暟鎹�
+const lastUpdateTime = ref('')
+const totalDevices = ref(0)
+const dailyConsumption = ref(0)
+const monthlyConsumption = ref(0)
+const gasUnitPrice = ref(0)
+const dailyTotalCost = ref(0)
+const monthlyTotalCost = ref(0)
+const deviceList = ref([])
+const tableLoading = ref(false)
+const deviceDialogVisible = ref(false)
+const dialogTitle = ref('')
+const deviceFormRef = ref()
+
+// 璁惧琛ㄥ崟鏁版嵁
+const deviceForm = reactive({
+  deviceCode: '',
+  deviceName: '',
+  deviceType: '',
+  specification: '',
+  designPressure: 0,
+  volume: 0
+})
+
+// 琛ㄥ崟楠岃瘉瑙勫垯
+const deviceRules = {
+  deviceCode: [{ required: true, message: '璇疯緭鍏ヨ澶囩紪鍙�', trigger: 'blur' }],
+  deviceName: [{ required: true, message: '璇疯緭鍏ヨ澶囧悕绉�', trigger: 'blur' }],
+  deviceType: [{ required: true, message: '璇烽�夋嫨璁惧绫诲瀷', trigger: 'change' }],
+  specification: [{ required: true, message: '璇疯緭鍏ヨ鏍煎瀷鍙�', trigger: 'blur' }],
+  designPressure: [{ required: true, message: '璇疯緭鍏ヨ璁″帇鍔�', trigger: 'blur' }],
+  volume: [{ required: true, message: '璇疯緭鍏ュ绉�', trigger: 'blur' }]
+}
+
+// 瀹氭椂鍣�
+let updateTimer = null
+
+// 妯℃嫙鏁版嵁鐢熸垚
+const generateMockData = () => {
+  // 鏇存柊缁熻鏁版嵁
+  totalDevices.value = Math.floor(Math.random() * 10) + 15 // 15-25鍙拌澶�
+  dailyConsumption.value = Math.floor(Math.random() * 100) + 200 // 200-300 m鲁
+  monthlyConsumption.value = Math.floor(Math.random() * 2000) + 5000 // 5000-7000 m鲁
+  gasUnitPrice.value = (Math.random() * 2 + 3).toFixed(2) // 3-5鍏�/m鲁
+  
+  // 璁$畻璐圭敤
+  dailyTotalCost.value = dailyConsumption.value * gasUnitPrice.value
+  monthlyTotalCost.value = monthlyConsumption.value * gasUnitPrice.value
+  
+  // 鏇存柊璁惧鍒楄〃鏁版嵁
+  deviceList.value = Array.from({ length: totalDevices.value }, (_, index) => ({
+    id: index + 1,
+    deviceCode: `GT${String(index + 1).padStart(3, '0')}`,
+    deviceName: `鍌ㄦ皵缃�${index + 1}`,
+    deviceType: ['娑插寲姘斿偍缃�', '鍘嬬缉姘斿偍缃�', '澶╃劧姘斿偍缃�', '姘ф皵鍌ㄧ綈'][Math.floor(Math.random() * 4)],
+    specification: `${Math.floor(Math.random() * 50) + 50}m鲁`,
+    currentPressure: (Math.random() * 2 + 0.5).toFixed(2),
+    currentTemperature: (Math.random() * 20 + 15).toFixed(1),
+    gasConcentration: (Math.random() * 10).toFixed(2),
+    status: ['running', 'stopped', 'warning', 'error'][Math.floor(Math.random() * 4)],
+    lastUpdate: new Date().toLocaleString()
+  }))
+  
+  // 鏇存柊鏈�鍚庢洿鏂版椂闂�
+  lastUpdateTime.value = new Date().toLocaleString()
+}
+
+// 鑾峰彇鍘嬪姏鐘舵�佹牱寮�
+const getPressureClass = (pressure) => {
+  const p = parseFloat(pressure)
+  if (p < 0.8) return 'pressure-low'
+  if (p > 1.5) return 'pressure-high'
+  return 'pressure-normal'
+}
+
+// 鑾峰彇娓╁害鐘舵�佹牱寮�
+const getTemperatureClass = (temperature) => {
+  const t = parseFloat(temperature)
+  if (t < 10 || t > 35) return 'temperature-warning'
+  return 'temperature-normal'
+}
+
+// 鑾峰彇娴撳害鐘舵�佹牱寮�
+const getConcentrationClass = (concentration) => {
+  const c = parseFloat(concentration)
+  if (c > 5) return 'concentration-warning'
+  return 'concentration-normal'
+}
+
+// 鑾峰彇鐘舵�佺被鍨�
+const getStatusType = (status) => {
+  const statusMap = {
+    running: 'success',
+    stopped: 'info',
+    warning: 'warning',
+    error: 'danger'
+  }
+  return statusMap[status] || 'info'
+}
+
+// 鑾峰彇鐘舵�佹枃鏈�
+const getStatusText = (status) => {
+  const statusMap = {
+    running: '杩愯涓�',
+    stopped: '宸插仠姝�',
+    warning: '璀﹀憡',
+    error: '鏁呴殰'
+  }
+  return statusMap[status] || '鏈煡'
+}
+
+// 鍒锋柊鏁版嵁
+const refreshData = () => {
+  generateMockData()
+  ElMessage.success('鏁版嵁宸插埛鏂�')
+}
+
+// 娣诲姞璁惧
+const addDevice = () => {
+  dialogTitle.value = '娣诲姞璁惧'
+  Object.keys(deviceForm).forEach(key => {
+    deviceForm[key] = key === 'designPressure' || key === 'volume' ? 0 : ''
+  })
+  deviceDialogVisible.value = true
+}
+
+// 缂栬緫璁惧
+const editDevice = (row) => {
+  dialogTitle.value = '缂栬緫璁惧'
+  Object.keys(deviceForm).forEach(key => {
+    if (row[key] !== undefined) {
+      deviceForm[key] = row[key]
+    }
+  })
+  deviceDialogVisible.value = true
+}
+
+
+
+// 淇濆瓨璁惧
+const saveDevice = () => {
+  deviceFormRef.value.validate((valid) => {
+    if (valid) {
+      ElMessage.success('淇濆瓨鎴愬姛')
+      deviceDialogVisible.value = false
+      refreshData()
+    }
+  })
+}
+
+
+
+// 鍚姩瀹氭椂鏇存柊
+const startAutoUpdate = () => {
+  updateTimer = setInterval(() => {
+    generateMockData()
+  }, 60000) // 姣忓垎閽熸洿鏂颁竴娆�
+}
+
+// 鍋滄瀹氭椂鏇存柊
+const stopAutoUpdate = () => {
+  if (updateTimer) {
+    clearInterval(updateTimer)
+    updateTimer = null
+  }
+}
+
+// 缁勪欢鎸傝浇
+onMounted(() => {
+  generateMockData()
+  startAutoUpdate()
+})
+
+// 缁勪欢鍗歌浇
+onUnmounted(() => {
+  stopAutoUpdate()
+})
+</script>
+
+<style lang="scss" scoped>
+.app-container {
+  padding: 20px;
+  background: #f5f5f5;
+  min-height: 100vh;
+}
+
+.page-header {
+  display: flex;
+  justify-content: space-between;
+  align-items: center;
+  margin-bottom: 20px;
+  padding: 20px;
+  background: white;
+  border-radius: 8px;
+  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+
+  h2 {
+    margin: 0;
+    color: #303133;
+    font-size: 24px;
+  }
+
+  .header-info {
+    display: flex;
+    align-items: center;
+    gap: 15px;
+
+    .update-time {
+      color: #909399;
+      font-size: 14px;
+    }
+  }
+}
+
+.stats-cards {
+  margin-bottom: 20px;
+
+  .stat-card {
+    .stat-content {
+      display: flex;
+      align-items: center;
+      padding: 10px;
+
+      .stat-icon {
+        width: 60px;
+        height: 60px;
+        border-radius: 50%;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        margin-right: 15px;
+
+        &.gas-device {
+          background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
+          color: white;
+        }
+
+        &.daily-consumption {
+          background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
+          color: white;
+        }
+
+        &.monthly-consumption {
+          background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
+          color: white;
+        }
+
+        &.gas-price {
+          background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
+          color: white;
+        }
+      }
+
+      .stat-info {
+        .stat-value {
+          font-size: 24px;
+          font-weight: bold;
+          color: #303133;
+          line-height: 1;
+        }
+
+        .stat-label {
+          font-size: 14px;
+          color: #909399;
+          margin-top: 5px;
+        }
+      }
+    }
+  }
+}
+
+.cost-stats {
+  margin-bottom: 20px;
+
+  .cost-card {
+    .card-header {
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+    }
+
+    .cost-content {
+      text-align: center;
+      padding: 20px 0;
+
+      .cost-main {
+        margin-bottom: 15px;
+
+        .cost-amount {
+          font-size: 36px;
+          font-weight: bold;
+          color: #409eff;
+        }
+
+        .cost-unit {
+          font-size: 16px;
+          color: #909399;
+          margin-left: 5px;
+        }
+      }
+
+      .cost-details {
+        .cost-item {
+          display: flex;
+          justify-content: space-between;
+          margin-bottom: 8px;
+          font-size: 14px;
+          color: #606266;
+
+          &:last-child {
+            margin-bottom: 0;
+          }
+        }
+      }
+    }
+  }
+}
+
+.device-section {
+  .card-header {
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+
+    .header-actions {
+      display: flex;
+      gap: 10px;
+    }
+  }
+}
+
+// 鐘舵�佹牱寮�
+.pressure-low {
+  color: #e6a23c;
+  font-weight: bold;
+}
+
+.pressure-normal {
+  color: #67c23a;
+  font-weight: bold;
+}
+
+.pressure-high {
+  color: #f56c6c;
+  font-weight: bold;
+}
+
+.temperature-normal {
+  color: #67c23a;
+  font-weight: bold;
+}
+
+.temperature-warning {
+  color: #e6a23c;
+  font-weight: bold;
+}
+
+.concentration-normal {
+  color: #67c23a;
+  font-weight: bold;
+}
+
+.concentration-warning {
+  color: #f56c6c;
+  font-weight: bold;
+}
+</style>
diff --git a/src/views/energyManagement/meterCollection/index.vue b/src/views/energyManagement/meterCollection/index.vue
new file mode 100644
index 0000000..8b2636b
--- /dev/null
+++ b/src/views/energyManagement/meterCollection/index.vue
@@ -0,0 +1,556 @@
+<template>
+  <div class="app-container">
+    <el-card class="box-card">
+      <div slot="header" class="clearfix">
+        <span>鐢佃〃閲囬泦绠$悊</span>
+        <el-button style="float: right; padding: 3px 0" link @click="refreshData">
+          <i class="el-icon-refresh"></i> 鍒锋柊
+        </el-button>
+      </div>
+      
+             <!-- 娴嬭瘯鎸夐挳 -->
+       <el-row :gutter="20" style="margin-bottom: 15px;">
+         <el-col :span="24">
+           <el-button @click="addTestData" type="primary" size="small">娣诲姞娴嬭瘯鏁版嵁</el-button>
+           <el-button @click="clearData" type="danger" size="small">娓呯┖鏁版嵁</el-button>
+           <el-button @click="testChart" type="success" size="small">娴嬭瘯鍥捐〃</el-button>
+         </el-col>
+       </el-row>
+
+       <!-- 鎼滅储鍖哄煙 -->
+       <el-row :gutter="20" class="search-row">
+        <el-col :span="6">
+          <el-input
+            v-model="searchForm.meterNo"
+            placeholder="璇疯緭鍏ョ數琛ㄧ紪鍙�"
+            clearable
+            @keyup.enter.native="handleSearch"
+          >
+            <i slot="prefix" class="el-input__icon el-icon-search"></i>
+          </el-input>
+        </el-col>
+        <el-col :span="6">
+          <el-select v-model="searchForm.location" placeholder="璇烽�夋嫨浣嶇疆" clearable>
+            <el-option label="鐢熶骇杞﹂棿A" value="杞﹂棿A"></el-option>
+            <el-option label="鐢熶骇杞﹂棿B" value="杞﹂棿B"></el-option>
+            <el-option label="鍔炲叕鍖哄煙" value="鍔炲叕鍖�"></el-option>
+            <el-option label="閰嶇數瀹�" value="閰嶇數瀹�"></el-option>
+          </el-select>
+        </el-col>
+        <el-col :span="6">
+          <el-date-picker
+            v-model="searchForm.dateRange"
+            type="daterange"
+            range-separator="鑷�"
+            start-placeholder="寮�濮嬫棩鏈�"
+            end-placeholder="缁撴潫鏃ユ湡"
+            format="yyyy-MM-dd"
+            value-format="yyyy-MM-dd"
+          />
+        </el-col>
+        <el-col :span="6">
+          <el-button type="primary" @click="handleSearch">鎼滅储</el-button>
+          <el-button @click="resetSearch">閲嶇疆</el-button>
+        </el-col>
+      </el-row>
+
+      <!-- 鐢佃〃鍒楄〃 -->
+      <el-table
+        :data="meterList"
+        style="width: 100%"
+        v-loading="loading"
+        border
+        stripe
+        height="calc(100vh - 22em)"
+      >
+        <el-table-column prop="meterNo" label="鐢佃〃缂栧彿" width="120" />
+        <el-table-column prop="location" label="瀹夎浣嶇疆" width="120" />
+        <el-table-column prop="meterType" label="鐢佃〃绫诲瀷" width="120" />
+        <el-table-column prop="voltage" label="鐢靛帇绛夌骇" width="100" />
+        <el-table-column prop="currentReading" label="褰撳墠璇绘暟(kWh)" width="140" />
+        <el-table-column prop="lastReading" label="涓婃璇绘暟(kWh)" width="140" />
+        <el-table-column prop="consumption" label="鐢ㄧ數閲�(kWh)" width="120" />
+        <el-table-column prop="power" label="鍔熺巼(kW)" width="100" />
+        <el-table-column prop="powerFactor" label="鍔熺巼鍥犳暟" width="100" />
+                          <el-table-column prop="status" label="鐘舵��" width="80">
+           <template #default="scope">
+             <el-tag :type="scope.row.status === '姝e父' ? 'success' : 'danger'">
+               {{ scope.row.status }}
+             </el-tag>
+           </template>
+         </el-table-column>
+         <el-table-column prop="lastUpdateTime" label="鏈�鍚庢洿鏂版椂闂�" width="160" />
+         <el-table-column label="鎿嶄綔" width="180" fixed="right" align="center">
+           <template #default="scope">
+             <el-button link @click="viewDetails(scope.row)">
+               鏌ョ湅璇︽儏
+             </el-button>
+             <el-button link @click="manualCollection(scope.row)">
+               鎵嬪姩閲囬泦
+             </el-button>
+           </template>
+         </el-table-column>
+      </el-table>
+      <!-- 鍒嗛〉 -->
+			<pagination
+				:total="pagination.total"
+				layout="total, sizes, prev, pager, next, jumper"
+				:page="pagination.currentPage"
+				:limit="pagination.pageSize"
+				@pagination="handleCurrentChange"
+			/>
+    </el-card>
+
+              <!-- 璇︽儏瀵硅瘽妗� -->
+      <el-dialog 
+        title="鐢佃〃璇︽儏" 
+        v-model="detailDialogVisible" 
+        width="60%"
+        @opened="onDialogOpened"
+      >
+       <el-row :gutter="20">
+         <el-col :span="12">
+           <div class="detail-item">
+             <label>鐢佃〃缂栧彿:</label>
+             <span>{{ currentMeter.meterNo }}</span>
+           </div>
+         </el-col>
+         <el-col :span="12">
+           <div class="detail-item">
+             <label>瀹夎浣嶇疆:</label>
+             <span>{{ currentMeter.location }}</span>
+           </div>
+         </el-col>
+         <el-col :span="12">
+           <div class="detail-item">
+             <label>鐢佃〃绫诲瀷:</label>
+             <span>{{ currentMeter.meterType }}</span>
+           </div>
+         </el-col>
+         <el-col :span="12">
+           <div class="detail-item">
+             <label>鐢靛帇绛夌骇:</label>
+             <span>{{ currentMeter.voltage }}</span>
+           </div>
+         </el-col>
+         <el-col :span="12">
+           <div class="detail-item">
+             <label>褰撳墠璇绘暟:</label>
+             <span>{{ currentMeter.currentReading }} kWh</span>
+           </div>
+         </el-col>
+         <el-col :span="12">
+           <div class="detail-item">
+             <label>涓婃璇绘暟:</label>
+             <span>{{ currentMeter.lastReading }} kWh</span>
+           </div>
+         </el-col>
+         <el-col :span="12">
+           <div class="detail-item">
+             <label>鐢ㄧ數閲�:</label>
+             <span>{{ currentMeter.consumption }} kWh</span>
+           </div>
+         </el-col>
+         <el-col :span="12">
+           <div class="detail-item">
+             <label>鍔熺巼:</label>
+             <span>{{ currentMeter.power }} kW</span>
+           </div>
+         </el-col>
+         <el-col :span="12">
+           <div class="detail-item">
+             <label>鍔熺巼鍥犳暟:</label>
+             <span>{{ currentMeter.powerFactor }}</span>
+           </div>
+         </el-col>
+         <el-col :span="12">
+           <div class="detail-item">
+             <label>鐘舵��:</label>
+             <el-tag :type="currentMeter.status === '姝e父' ? 'success' : 'danger'">
+               {{ currentMeter.status }}
+             </el-tag>
+           </div>
+         </el-col>
+         <el-col :span="12">
+           <div class="detail-item">
+             <label>鏈�鍚庢洿鏂版椂闂�:</label>
+             <span>{{ currentMeter.lastUpdateTime }}</span>
+           </div>
+         </el-col>
+       </el-row>
+      
+      <!-- 鐢ㄧ數瓒嬪娍鍥� -->
+      <div style="margin-top: 20px;">
+        <h4>24灏忔椂鐢ㄧ數瓒嬪娍</h4>
+        <div ref="chartContainer" style="height: 300px;"></div>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+
+export default {
+  name: 'MeterCollection',
+  data() {
+    return {
+      loading: false,
+      searchForm: {
+        meterNo: '',
+        location: '',
+        dateRange: []
+      },
+      meterList: [],
+      pagination: {
+        currentPage: 1,
+        pageSize: 10,
+        total: 0
+      },
+      detailDialogVisible: false,
+      currentMeter: {},
+      chart: null
+    }
+  },
+  created() {
+    // 绔嬪嵆鐢熸垚涓�浜涙祴璇曟暟鎹�
+    this.meterList = [
+      {
+        id: 1,
+        meterNo: 'M001',
+        location: '杞﹂棿A',
+        meterType: '鏅鸿兘鐢佃〃',
+        voltage: '380V',
+        currentReading: 8500,
+        lastReading: 8400,
+        consumption: 100,
+        power: '75.5',
+        powerFactor: '0.85',
+        status: '姝e父',
+        lastUpdateTime: '2024-01-15 10:30:00'
+      },
+      {
+        id: 2,
+        meterNo: 'M002',
+        location: '杞﹂棿B',
+        meterType: '澶氬姛鑳界數琛�',
+        voltage: '220V',
+        currentReading: 6200,
+        lastReading: 6100,
+        consumption: 100,
+        power: '45.2',
+        powerFactor: '0.92',
+        status: '姝e父',
+        lastUpdateTime: '2024-01-15 10:25:00'
+      }
+    ]
+    this.pagination.total = this.meterList.length
+  },
+  mounted() {
+    // 寤惰繜涓�鐐规椂闂村啀璋冪敤锛岀‘淇滵OM宸茬粡娓叉煋
+    this.$nextTick(() => {
+      this.getMeterList()
+    })
+  },
+  watch: {
+    meterList: {
+      handler(newVal) {
+        console.log('meterList鏁版嵁鍙樺寲:', newVal)
+      },
+      deep: true,
+      immediate: true
+    }
+  },
+  methods: {
+    // 鑾峰彇鐢佃〃鍒楄〃
+    getMeterList() {
+      this.loading = true
+      // 妯℃嫙API璋冪敤
+      setTimeout(() => {
+        const mockData = this.generateMockData()
+        this.meterList = mockData
+        this.pagination.total = this.meterList.length
+        this.loading = false
+      }, 500)
+    },
+
+    // 鐢熸垚妯℃嫙鏁版嵁
+    generateMockData() {
+      const locations = ['杞﹂棿A', '杞﹂棿B', '鍔炲叕鍖�', '閰嶇數瀹�']
+      const meterTypes = ['鏅鸿兘鐢佃〃', '澶氬姛鑳界數琛�', '鏅�氱數琛�']
+      const voltages = ['220V', '380V', '10kV']
+      const statuses = ['姝e父', '寮傚父']
+      
+      const data = []
+      for (let i = 1; i <= 25; i++) {
+        const currentReading = Math.floor(Math.random() * 10000) + 5000
+        const lastReading = currentReading - Math.floor(Math.random() * 100) - 10
+        const consumption = currentReading - lastReading
+        const power = Math.random() * 100 + 20
+        const powerFactor = (Math.random() * 0.3 + 0.7).toFixed(2)
+        
+        data.push({
+          id: i,
+          meterNo: `M${String(i).padStart(3, '0')}`,
+          location: locations[Math.floor(Math.random() * locations.length)],
+          meterType: meterTypes[Math.floor(Math.random() * meterTypes.length)],
+          voltage: voltages[Math.floor(Math.random() * voltages.length)],
+          currentReading: currentReading,
+          lastReading: lastReading,
+          consumption: consumption,
+          power: power.toFixed(2),
+          powerFactor: powerFactor,
+          status: statuses[Math.floor(Math.random() * statuses.length)],
+          lastUpdateTime: this.formatDate(new Date(Date.now() - Math.random() * 86400000))
+        })
+      }
+      return data
+    },
+
+    // 鏍煎紡鍖栨棩鏈�
+    formatDate(date) {
+      const year = date.getFullYear()
+      const month = String(date.getMonth() + 1).padStart(2, '0')
+      const day = String(date.getDate()).padStart(2, '0')
+      const hours = String(date.getHours()).padStart(2, '0')
+      const minutes = String(date.getMinutes()).padStart(2, '0')
+      return `${year}-${month}-${day} ${hours}:${minutes}`
+    },
+
+    // 鎼滅储
+    handleSearch() {
+      this.pagination.currentPage = 1
+      this.getMeterList()
+    },
+
+    // 閲嶇疆鎼滅储
+    resetSearch() {
+      this.searchForm = {
+        meterNo: '',
+        location: '',
+        dateRange: []
+      }
+      this.handleSearch()
+    },
+
+    // 鏌ョ湅璇︽儏
+    viewDetails(row) {
+      this.currentMeter = row
+      this.detailDialogVisible = true
+    },
+
+    // 瀵硅瘽妗嗘墦寮�鍚庡垵濮嬪寲鍥捐〃
+    onDialogOpened() {
+      this.$nextTick(() => {
+        setTimeout(() => {
+          this.initChart()
+        }, 100)
+      })
+    },
+
+    // 鎵嬪姩閲囬泦
+    manualCollection(row) {
+      this.$message.success(`姝e湪閲囬泦鐢佃〃 ${row.meterNo} 鐨勬暟鎹�...`)
+      // 妯℃嫙閲囬泦杩囩▼
+      setTimeout(() => {
+        row.currentReading = Math.floor(Math.random() * 100) + row.currentReading
+        row.lastUpdateTime = this.formatDate(new Date())
+        this.$message.success('鏁版嵁閲囬泦瀹屾垚')
+      }, 1000)
+    },
+
+    // 鍒锋柊鏁版嵁
+    refreshData() {
+      this.getMeterList()
+      this.$message.success('鏁版嵁宸插埛鏂�')
+    },
+
+    // 娣诲姞娴嬭瘯鏁版嵁
+    addTestData() {
+      const testData = {
+        id: Date.now(),
+        meterNo: `M${String(this.meterList.length + 1).padStart(3, '0')}`,
+        location: '娴嬭瘯浣嶇疆',
+        meterType: '娴嬭瘯鐢佃〃',
+        voltage: '220V',
+        currentReading: Math.floor(Math.random() * 10000) + 1000,
+        lastReading: Math.floor(Math.random() * 5000) + 500,
+        consumption: Math.floor(Math.random() * 100) + 10,
+        power: (Math.random() * 100 + 10).toFixed(2),
+        powerFactor: (Math.random() * 0.3 + 0.7).toFixed(2),
+        status: '姝e父',
+        lastUpdateTime: this.formatDate(new Date())
+      }
+      this.meterList.push(testData)
+      this.pagination.total = this.meterList.length
+      this.$message.success('娴嬭瘯鏁版嵁宸叉坊鍔�')
+    },
+
+    // 娓呯┖鏁版嵁
+    clearData() {
+      this.meterList = []
+      this.pagination.total = 0
+      this.$message.success('鏁版嵁宸叉竻绌�')
+    },
+
+    // 娴嬭瘯鍥捐〃
+    testChart() {
+      this.$message.info('鍥捐〃娴嬭瘯鍔熻兘')
+      // 鍒涘缓涓�涓祴璇曞璇濇鏉ユ祴璇曞浘琛�
+      this.currentMeter = {
+        meterNo: 'TEST001',
+        location: '娴嬭瘯浣嶇疆',
+        meterType: '娴嬭瘯鐢佃〃',
+        voltage: '220V',
+        currentReading: 1000,
+        lastReading: 900,
+        consumption: 100,
+        power: '50.0',
+        powerFactor: '0.85',
+        status: '姝e父',
+        lastUpdateTime: '2024-01-15 12:00:00'
+      }
+      this.detailDialogVisible = true
+    },
+
+    // 鍒嗛〉澶у皬鏀瑰彉
+    handleSizeChange(val) {
+      this.pagination.pageSize = val
+      this.getMeterList()
+    },
+
+    // 褰撳墠椤垫敼鍙�
+    handleCurrentChange(val) {
+      this.pagination.pageSize = val.limit
+      this.pagination.currentPage = val.page
+      this.getMeterList()
+    },
+
+    // 鍒濆鍖栧浘琛�
+    initChart() {
+      try {
+        if (this.chart) {
+          this.chart.dispose()
+          this.chart = null
+        }
+        
+        // 纭繚DOM鍏冪礌瀛樺湪
+        if (!this.$refs.chartContainer) {
+          console.error('鍥捐〃瀹瑰櫒涓嶅瓨鍦紝绛夊緟DOM鏇存柊...')
+          // 濡傛灉瀹瑰櫒涓嶅瓨鍦紝绛夊緟涓�涓嬪啀璇�
+          setTimeout(() => {
+            this.initChart()
+          }, 100)
+          return
+        }
+        
+        // 妫�鏌ュ鍣ㄥ昂瀵�
+        const container = this.$refs.chartContainer
+        if (container.offsetWidth === 0 || container.offsetHeight === 0) {
+          setTimeout(() => {
+            this.initChart()
+          }, 100)
+          return
+        }
+        this.chart = echarts.init(container)
+        
+        // 鐢熸垚24灏忔椂妯℃嫙鏁版嵁
+        const hours = []
+        const consumption = []
+        for (let i = 0; i < 24; i++) {
+          hours.push(`${i}:00`)
+          consumption.push(Math.floor(Math.random() * 50) + 20)
+        }
+        
+        const option = {
+          title: {
+            text: '24灏忔椂鐢ㄧ數閲忚秼鍔�',
+            left: 'center'
+          },
+          tooltip: {
+            trigger: 'axis',
+            formatter: '{b}<br/>鐢ㄧ數閲�: {c} kWh'
+          },
+          xAxis: {
+            type: 'category',
+            data: hours,
+            axisLabel: {
+              rotate: 45
+            }
+          },
+          yAxis: {
+            type: 'value',
+            name: '鐢ㄧ數閲� (kWh)'
+          },
+          series: [{
+            data: consumption,
+            type: 'line',
+            smooth: true,
+            areaStyle: {
+              opacity: 0.3
+            },
+            itemStyle: {
+              color: '#409EFF'
+            }
+          }]
+        }
+        
+        this.chart.setOption(option)
+      } catch (error) {
+        console.error('鍥捐〃鍒濆鍖栧け璐�:', error)
+        this.$message.error('鍥捐〃鍒濆鍖栧け璐�: ' + error.message)
+      }
+    }
+  },
+  
+  beforeUnmount() {
+    if (this.chart) {
+      try {
+        this.chart.dispose()
+        this.chart = null
+      } catch (error) {
+        console.error('娓呯悊鍥捐〃澶辫触:', error)
+      }
+    }
+  }
+}
+</script>
+
+<style scoped>
+.search-row {
+  margin-bottom: 20px;
+}
+
+.pagination {
+  margin-top: 20px;
+  text-align: right;
+}
+
+.el-table {
+  margin-top: 20px;
+}
+
+.detail-item {
+  margin-bottom: 15px;
+  padding: 10px;
+  border: 1px solid #ebeef5;
+  border-radius: 4px;
+  background-color: #fafafa;
+}
+
+.detail-item label {
+  font-weight: bold;
+  color: #606266;
+  margin-right: 10px;
+  min-width: 100px;
+  display: inline-block;
+}
+
+.detail-item span {
+  color: #303133;
+}
+
+.detail-item .el-tag {
+  margin-left: 0;
+}
+</style>
diff --git a/src/views/energyManagement/waterManagement/components/formDia.vue b/src/views/energyManagement/waterManagement/components/formDia.vue
index a692b95..2e58ea0 100644
--- a/src/views/energyManagement/waterManagement/components/formDia.vue
+++ b/src/views/energyManagement/waterManagement/components/formDia.vue
@@ -15,9 +15,9 @@
 			>
 				<el-row :gutter="30">
 					<el-col :span="12">
-						<el-form-item label="璁惧锛�" prop="code">
+						<el-form-item label="璁惧锛�" prop="deviceModel">
 							<el-select
-								v-model="form.code"
+								v-model="form.deviceModel"
 								placeholder="璇烽�夋嫨"
 								clearable
 								@change="setName"
@@ -35,9 +35,9 @@
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="姣忔棩闄愬埗姘撮噺锛�" prop="everyNum">
+						<el-form-item label="姣忔棩闄愬埗姘撮噺锛�" prop="waterDayLimit">
 							<el-input
-								v-model="form.everyNum"
+								v-model="form.waterDayLimit"
 								placeholder="璇疯緭鍏�"
 								clearable
 							/>
@@ -46,18 +46,18 @@
 				</el-row>
 				<el-row :gutter="30">
 					<el-col :span="12">
-						<el-form-item label="棰濆畾娴侀噺锛�" prop="flowRating">
+						<el-form-item label="棰濆畾娴侀噺锛�" prop="ratedRate">
 							<el-input
-								v-model="form.flowRating"
+								v-model="form.ratedRate"
 								placeholder="璇疯緭鍏�"
 								clearable
 							/>
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="瀹為檯娴侀噺锛�" prop="flowActual">
+						<el-form-item label="瀹為檯娴侀噺锛�" prop="actualTraffic">
 							<el-input
-								v-model="form.flowActual"
+								v-model="form.actualTraffic"
 								placeholder="璇疯緭鍏�"
 								clearable
 							/>
@@ -66,10 +66,10 @@
 				</el-row>
 				<el-row :gutter="30">
 					<el-col :span="12">
-						<el-form-item label="杩愯鏃堕棿锛�" prop="runDate">
+						<el-form-item label="杩愯鏃堕棿锛�" prop="runTime">
 							<el-date-picker
 								style="width: 100%"
-								v-model="form.runDate"
+								v-model="form.runTime"
 								value-format="YYYY-MM-DD"
 								format="YYYY-MM-DD"
 								type="date"
@@ -79,9 +79,9 @@
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="褰撴棩鐢ㄦ按閲忥細" prop="dayNum">
+						<el-form-item label="褰撴棩鐢ㄦ按閲忥細" prop="waterDay">
 							<el-input
-								v-model="form.dayNum"
+								v-model="form.waterDay"
 								placeholder="璇疯緭鍏�"
 								clearable
 							/>
@@ -99,9 +99,9 @@
 						</el-form-item>
 					</el-col>
 					<el-col :span="12">
-						<el-form-item label="鐢ㄦ按绫诲瀷锛�" prop="waterType">
+						<el-form-item label="鐢ㄦ按绫诲瀷锛�" prop="type">
 							<el-select
-								v-model="form.waterType"
+								v-model="form.type"
 								placeholder="璇烽�夋嫨"
 								clearable
 							>
@@ -136,25 +136,25 @@
 
 const data = reactive({
 	form: {
-		name: "",
-		code: "",
-		everyNum: "",
-		flowRating: "",
-		flowActual: "",
-		runDate: "",
-		dayNum: "",
+    deviceName: "",
+    deviceModel: "",
+    waterDayLimit: "",
+    ratedRate: "",
+    actualTraffic: "",
+    runTime: "",
+    waterDay: "",
 		waterPrice: "",
-		waterType: "",
+    type: "",
 	},
 	rules: {
-		code: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-		runDate: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
-		everyNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-		flowRating: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-		flowActual: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-		dayNum: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    deviceModel: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+		runTime: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    waterDayLimit: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    ratedRate: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    actualTraffic: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
+    waterDay: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
 		waterPrice: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" }],
-		waterType: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
+    type: [{ required: true, message: "璇烽�夋嫨", trigger: "change" }],
 	},
 })
 const { form, rules } = toRefs(data);
@@ -166,8 +166,8 @@
   dialogFormVisible.value = true;
 	form.value = {}
 	proxy.resetForm("formRef");
-	waterDeviceList().then((res) => {
-		codeList.value = res.data;
+	waterDeviceList({size: -1}).then((res) => {
+		codeList.value = res.data.records;
 	});
 	if (type === "edit") {
 		form.value = {...row}
diff --git a/src/views/energyManagement/waterManagement/index.vue b/src/views/energyManagement/waterManagement/index.vue
index 848a945..181ae88 100644
--- a/src/views/energyManagement/waterManagement/index.vue
+++ b/src/views/energyManagement/waterManagement/index.vue
@@ -4,7 +4,7 @@
 			<div>
 				<span class="search_title">璁惧鍚嶇О锛�</span>
 				<el-input
-					v-model="searchForm.name"
+					v-model="searchForm.deviceName"
 					style="width: 240px"
 					placeholder="璇疯緭鍏�"
 					@change="handleQuery"
@@ -101,35 +101,35 @@
 const tableColumn = ref([
 	{
 		label: "璁惧鍚嶇О",
-		prop: "name",
+		prop: "deviceName",
 		width: 200,
 	},
 	{
 		label: "瑙勬牸鍨嬪彿",
-		prop: "code",
+		prop: "deviceModel",
 		width: 200,
 	},
 	{
 		label: "棰濆畾娴侀噺",
-		prop: "flowRating",
+		prop: "ratedRate",
 	},
 	{
 		label: "瀹為檯娴侀噺",
-		prop: "flowActual",
+		prop: "actualTraffic",
 	},
 	{
 		label: "杩愯鏃堕棿",
-		prop: "runDate",
+		prop: "runTime",
 		width:150
 	},
 	{
 		label: "褰撴棩鐢ㄦ按閲�",
-		prop: "dayNum",
+		prop: "waterDay",
 		width: 150,
 	},
 	{
 		label: "姣忔棩闄愬埗姘撮噺",
-		prop: "everyNum",
+		prop: "waterDayLimit",
 		width:220
 	},
 	{
@@ -175,7 +175,7 @@
 	// 璁剧疆涓婁紶鐨勮姹傚ご閮�
 	headers: { Authorization: "Bearer " + getToken() },
 	// 涓婁紶鐨勫湴鍧�
-	url: import.meta.env.VITE_APP_BASE_API + "/waterEquipmentConsumption/importData",
+	url: import.meta.env.VITE_APP_BASE_API + "/waterRecord/importData",
 	// 鏂囦欢涓婁紶鍓嶇殑鍥炶皟
 	beforeUpload: (file) => {
 		console.log('鏂囦欢鍗冲皢涓婁紶', file);
@@ -257,7 +257,7 @@
 }
 function importTemplate() {
 	proxy.download(
-		"/waterEquipmentConsumption/export",
+		"/waterRecord/export",
 		{},
 		'鐢ㄦ按璁惧瀵煎叆妯$増.xlsx'
 	);
diff --git a/src/views/equipmentManagement/iotMonitor/index.vue b/src/views/equipmentManagement/iotMonitor/index.vue
new file mode 100644
index 0000000..b0cd818
--- /dev/null
+++ b/src/views/equipmentManagement/iotMonitor/index.vue
@@ -0,0 +1,317 @@
+<template>
+  <div class="app-container iot-monitor">
+    <div class="header">
+      <div class="title">瀹炴椂宸ュ喌鐩戞帶锛圛oT锛�</div>
+      <div class="actions">
+        <el-button type="primary" @click="toggleCollecting">{{ collecting ? '鏆傚仠閲囬泦' : '鍚姩閲囬泦' }}</el-button>
+        <el-button @click="resetAll">閲嶇疆</el-button>
+        <span class="ts">涓婃鏇存柊鏃堕棿锛歿{ lastUpdatedDisplay }}</span>
+      </div>
+    </div>
+
+<!--    <el-alert-->
+<!--      title="杈圭紭棰勮瑙勫垯锛氳酱鎵跨(鎹�-鎸姩鍊煎亸绂诲熀绾柯�5%瑙﹀彂鍛婅锛涙俯搴�/鍘嬪姏瓒婄晫瑙﹀彂鎻愰啋"-->
+<!--      type="info"-->
+<!--      :closable="false"-->
+<!--      show-icon-->
+<!--      class="rule-alert"-->
+<!--    />-->
+
+    <el-row :gutter="16">
+      <el-col v-for="dev in devices" :key="dev.id" :span="12">
+        <el-card :class="['device-card', dev.hasAlert ? 'is-alert' : '']">
+          <template #header>
+            <div class="card-header">
+              <div class="card-title">
+                <span class="device-name">{{ dev.name }}</span>
+                <el-tag :type="dev.hasAlert ? 'danger' : 'success'" size="small">{{ dev.hasAlert ? '鍛婅' : '姝e父' }}</el-tag>
+              </div>
+              <div class="meta">绫诲瀷锛歿{ dev.type }}锝滃熀绾挎尟鍔細{{ dev.baseline.vibration.toFixed(2) }} mm/s</div>
+            </div>
+          </template>
+
+          <div class="metrics">
+            <div class="metric" :class="{ 'metric-alert': dev.alerts.vibration }">
+              <div class="metric-head">
+                <span>鎸姩(mm/s)</span>
+                <el-tag :type="dev.alerts.vibration ? 'danger' : 'info'" size="small">{{ dev.alerts.vibration ? '卤5%瓒婄晫' : '鍩虹嚎卤5%' }}</el-tag>
+              </div>
+              <div class="metric-value">{{ currentValue(dev.series.vibration).toFixed(2) }}</div>
+              <Echarts
+                :xAxis="[{ type: 'category', data: xAxisLabels }]"
+                :yAxis="[{ type: 'value', name: 'mm/s' }]"
+                :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.vibration }]"
+                :tooltip="{ trigger: 'axis' }"
+                :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
+                :chartStyle="{ height: '160px', width: '100%' }"
+                :lineColors="['#409EFF']"
+              />
+            </div>
+
+            <div class="metric" :class="{ 'metric-alert': dev.alerts.temperature }">
+              <div class="metric-head">
+                <span>娓╁害(掳C)</span>
+                <el-tag :type="dev.alerts.temperature ? 'warning' : 'info'" size="small">{{ dev.alerts.temperature ? '瓒婄晫' : '20~80' }}</el-tag>
+              </div>
+              <div class="metric-value">{{ currentValue(dev.series.temperature).toFixed(1) }}</div>
+              <Echarts
+                :xAxis="[{ type: 'category', data: xAxisLabels }]"
+                :yAxis="[{ type: 'value', name: '掳C' }]"
+                :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.temperature }]"
+                :tooltip="{ trigger: 'axis' }"
+                :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
+                :chartStyle="{ height: '160px', width: '100%' }"
+                :lineColors="['#E6A23C']"
+              />
+            </div>
+
+            <div class="metric" :class="{ 'metric-alert': dev.alerts.pressure }">
+              <div class="metric-head">
+                <span>鍘嬪姏(MPa)</span>
+                <el-tag :type="dev.alerts.pressure ? 'warning' : 'info'" size="small">{{ dev.alerts.pressure ? '瓒婄晫' : '0.2~1.5' }}</el-tag>
+              </div>
+              <div class="metric-value">{{ currentValue(dev.series.pressure).toFixed(2) }}</div>
+              <Echarts
+                :xAxis="[{ type: 'category', data: xAxisLabels }]"
+                :yAxis="[{ type: 'value', name: 'MPa' }]"
+                :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.pressure }]"
+                :tooltip="{ trigger: 'axis' }"
+                :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
+                :chartStyle="{ height: '160px', width: '100%' }"
+                :lineColors="['#67C23A']"
+              />
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+  
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, onBeforeUnmount, computed } from 'vue'
+import { ElNotification } from 'element-plus'
+import Echarts from '@/components/Echarts/echarts.vue'
+
+defineOptions({ name: 'IoTMonitor' })
+
+const windowSize = 30
+const collecting = ref(true)
+const lastUpdated = ref(Date.now())
+const lastUpdatedDisplay = computed(() => new Date(lastUpdated.value).toLocaleTimeString())
+
+const xAxisLabels = ref(Array.from({ length: windowSize }, (_, i) => i - (windowSize - 1)).map(n => `${n}s`))
+
+function makeSeries(fill, decimals = 2) {
+  return Array.from({ length: windowSize }, () => Number(fill.toFixed(decimals)))
+}
+
+const devices = reactive([
+  {
+    id: 'water-pump',
+    name: '娉ㄦ按娉�1',
+    type: '绉诲姩瑁呭',
+    baseline: { vibration: 9 },
+    initial: { temperature: 40, pressure: 0.70 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(9),
+      temperature: makeSeries(40, 1),
+      pressure: makeSeries(0.7, 2),
+    },
+  },
+  {
+    id: 'fluid-supply-truck',
+    name: '娉ㄦ按娉�2',
+    type: '绉诲姩瑁呭',
+    baseline: { vibration: 7 },
+    initial: { temperature: 30, pressure: 0.60 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(7),
+      temperature: makeSeries(30, 1),
+      pressure: makeSeries(0.6, 2),
+    },
+  },
+  {
+    id: 'fracturing-truck',
+    name: '娉ㄦ按娉�3',
+    type: '绉诲姩瑁呭',
+    baseline: { vibration: 12 },
+    initial: { temperature: 65, pressure: 1.40 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(12),
+      temperature: makeSeries(65, 1),
+      pressure: makeSeries(1.4, 2),
+    },
+  },
+  {
+    id: 'oil-tank-truck',
+    name: '娉ㄦ按娉�4',
+    type: '绉诲姩瑁呭',
+    baseline: { vibration: 6 },
+    initial: { temperature: 28, pressure: 0.50 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(6),
+      temperature: makeSeries(28, 1),
+      pressure: makeSeries(0.5, 2),
+    },
+  },
+])
+
+function currentValue(arr) {
+  return arr[arr.length - 1] ?? 0
+}
+
+function pushWindow(arr, val) {
+  if (arr.length >= windowSize) arr.shift()
+  arr.push(val)
+}
+
+function clamp(val, min, max) { return Math.max(min, Math.min(max, val)) }
+
+function tickDevice(dev) {
+  const vibBase = dev.baseline.vibration
+  // 鎸姩锛氬熀绾柯�2%闅忔満娉㈠姩锛�5%姒傜巼瑙﹀彂8%~12%灏栧嘲妯℃嫙鍛婅
+  const spike = Math.random() < 0.05
+  const vibNoise = vibBase * (spike ? (1 + (Math.random() * 0.08 + 0.04) * (Math.random() < 0.5 ? -1 : 1)) : (1 + (Math.random() - 0.5) * 0.04))
+  const vibVal = Number(vibNoise.toFixed(2))
+  pushWindow(dev.series.vibration, vibVal)
+
+  // 娓╁害锛氱紦鎱㈤殢鏈烘父璧帮紝骞舵坊鍔犲伓鍙戦珮娓╁亸绉�
+  const tPrev = currentValue(dev.series.temperature)
+  const tDrift = tPrev + (Math.random() - 0.5) * 0.8 + (Math.random() < 0.02 ? 6 : 0)
+  const tVal = Number(clamp(tDrift, 15, 95).toFixed(1))
+  pushWindow(dev.series.temperature, tVal)
+
+  // 鍘嬪姏锛氬皬骞呮尝鍔紝鍋跺彂浣庡帇/楂樺帇
+  const pPrev = currentValue(dev.series.pressure)
+  const pDrift = pPrev + (Math.random() - 0.5) * 0.05 + (Math.random() < 0.02 ? (Math.random() < 0.5 ? -0.3 : 0.3) : 0)
+  const pVal = Number(clamp(pDrift, 0.05, 2.0).toFixed(2))
+  pushWindow(dev.series.pressure, pVal)
+
+  // 杈圭紭璁$畻闃堝�煎垽鏂�
+  const vibDelta = Math.abs(vibVal - vibBase) / vibBase
+  const vibAlert = vibDelta > 0.05
+  const tAlert = tVal < 20 || tVal > 80
+  const pAlert = pVal < 0.2 || pVal > 1.5
+
+  const prevHasAlert = dev.hasAlert
+  dev.alerts.vibration = vibAlert
+  dev.alerts.temperature = tAlert
+  dev.alerts.pressure = pAlert
+  dev.hasAlert = vibAlert || tAlert || pAlert
+
+  if (dev.hasAlert && !prevHasAlert) {
+    const reasons = []
+    if (vibAlert) reasons.push(`鎸姩鍋忕卤5% (褰撳墠 ${vibVal} / 鍩虹嚎 ${vibBase})`)
+    if (tAlert) reasons.push(`娓╁害瓒婄晫 (褰撳墠 ${tVal}掳C, 鏈熸湜 20~80掳C) `)
+    if (pAlert) reasons.push(`鍘嬪姏瓒婄晫 (褰撳墠 ${pVal}MPa, 鏈熸湜 0.2~1.5MPa) `)
+    ElNotification({
+      title: `${dev.name} 鍛婅`,
+      message: reasons.join('锛�'),
+      type: vibAlert ? 'error' : 'warning',
+      duration: 5000,
+    })
+  }
+}
+
+let timer = null
+function start() {
+  if (timer) return
+  timer = setInterval(() => {
+    if (!collecting.value) return
+    devices.forEach(tickDevice)
+    lastUpdated.value = Date.now()
+  }, 10000)
+}
+
+function stop() {
+  if (timer) {
+    clearInterval(timer)
+    timer = null
+  }
+}
+
+function toggleCollecting() { collecting.value = !collecting.value }
+
+function resetAll() {
+  devices.forEach(dev => {
+    dev.series.vibration = makeSeries(dev.baseline.vibration)
+    const t0 = dev.initial?.temperature ?? 45
+    const p0 = dev.initial?.pressure ?? 0.8
+    dev.series.temperature = makeSeries(t0, 1)
+    dev.series.pressure = makeSeries(p0, 2)
+    dev.alerts.vibration = false
+    dev.alerts.temperature = false
+    dev.alerts.pressure = false
+    dev.hasAlert = false
+  })
+  lastUpdated.value = Date.now()
+}
+
+onMounted(() => {
+  start()
+})
+
+onBeforeUnmount(() => {
+  stop()
+})
+</script>
+
+<style lang="scss" scoped>
+.iot-monitor {
+  .header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-bottom: 12px;
+    .title { font-size: 18px; font-weight: 600; }
+    .actions { display: flex; align-items: center; gap: 8px; }
+    .ts { color: #909399; font-size: 12px; }
+  }
+  .rule-alert { margin-bottom: 12px; }
+}
+
+.device-card {
+  margin-bottom: 16px;
+  transition: border-color 0.2s ease, box-shadow 0.2s ease;
+  &.is-alert { border-color: #F56C6C; box-shadow: 0 0 0 2px rgba(245,108,108,0.2) inset; }
+  .card-header {
+    display: flex; flex-direction: column; gap: 4px;
+    .card-title { display: flex; align-items: center; gap: 8px; font-weight: 600; }
+    .meta { color: #909399; font-size: 12px; }
+  }
+  .metrics {
+    display: grid;
+    grid-template-columns: 1fr;
+    gap: 12px;
+  }
+}
+
+.metric {
+  border: 1px solid #ebeef5;
+  border-radius: 6px;
+  padding: 8px 8px 0 8px;
+  &-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; font-size: 13px; color: #606266; }
+  &-value { font-size: 20px; font-weight: 600; margin: 2px 0 6px 0; }
+}
+
+.metric-alert {
+  border-color: #F56C6C;
+  background: #FFF6F6;
+}
+
+@media (min-width: 1200px) {
+  .device-card .metrics { grid-template-columns: 1fr 1fr 1fr; }
+}
+</style>
+
+
diff --git a/src/views/equipmentManagement/iotMonitor/indexWD.vue b/src/views/equipmentManagement/iotMonitor/indexWD.vue
new file mode 100644
index 0000000..40a2eb0
--- /dev/null
+++ b/src/views/equipmentManagement/iotMonitor/indexWD.vue
@@ -0,0 +1,317 @@
+<template>
+  <div class="app-container iot-monitor">
+    <div class="header">
+      <div class="title">瀹炴椂宸ュ喌鐩戞帶锛圛oT锛�</div>
+      <div class="actions">
+        <el-button type="primary" @click="toggleCollecting">{{ collecting ? '鏆傚仠閲囬泦' : '鍚姩閲囬泦' }}</el-button>
+        <el-button @click="resetAll">閲嶇疆</el-button>
+        <span class="ts">涓婃鏇存柊鏃堕棿锛歿{ lastUpdatedDisplay }}</span>
+      </div>
+    </div>
+
+<!--    <el-alert-->
+<!--      title="杈圭紭棰勮瑙勫垯锛氳酱鎵跨(鎹�-鎸姩鍊煎亸绂诲熀绾柯�5%瑙﹀彂鍛婅锛涙俯搴�/鍘嬪姏瓒婄晫瑙﹀彂鎻愰啋"-->
+<!--      type="info"-->
+<!--      :closable="false"-->
+<!--      show-icon-->
+<!--      class="rule-alert"-->
+<!--    />-->
+
+    <el-row :gutter="16">
+      <el-col v-for="dev in devices" :key="dev.id" :span="12">
+        <el-card :class="['device-card', dev.hasAlert ? 'is-alert' : '']">
+          <template #header>
+            <div class="card-header">
+              <div class="card-title">
+                <span class="device-name">{{ dev.name }}</span>
+                <el-tag :type="dev.hasAlert ? 'danger' : 'success'" size="small">{{ dev.hasAlert ? '鍛婅' : '姝e父' }}</el-tag>
+              </div>
+              <div class="meta">绫诲瀷锛歿{ dev.type }}锝滃熀绾挎尟鍔細{{ dev.baseline.vibration.toFixed(2) }} mm/s</div>
+            </div>
+          </template>
+
+          <div class="metrics">
+            <div class="metric" :class="{ 'metric-alert': dev.alerts.vibration }">
+              <div class="metric-head">
+                <span>鎸姩(mm/s)</span>
+                <el-tag :type="dev.alerts.vibration ? 'danger' : 'info'" size="small">{{ dev.alerts.vibration ? '卤5%瓒婄晫' : '鍩虹嚎卤5%' }}</el-tag>
+              </div>
+              <div class="metric-value">{{ currentValue(dev.series.vibration).toFixed(2) }}</div>
+              <Echarts
+                :xAxis="[{ type: 'category', data: xAxisLabels }]"
+                :yAxis="[{ type: 'value', name: 'mm/s' }]"
+                :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.vibration }]"
+                :tooltip="{ trigger: 'axis' }"
+                :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
+                :chartStyle="{ height: '160px', width: '100%' }"
+                :lineColors="['#409EFF']"
+              />
+            </div>
+
+            <div class="metric" :class="{ 'metric-alert': dev.alerts.temperature }">
+              <div class="metric-head">
+                <span>娓╁害(掳C)</span>
+                <el-tag :type="dev.alerts.temperature ? 'warning' : 'info'" size="small">{{ dev.alerts.temperature ? '瓒婄晫' : '20~80' }}</el-tag>
+              </div>
+              <div class="metric-value">{{ currentValue(dev.series.temperature).toFixed(1) }}</div>
+              <Echarts
+                :xAxis="[{ type: 'category', data: xAxisLabels }]"
+                :yAxis="[{ type: 'value', name: '掳C' }]"
+                :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.temperature }]"
+                :tooltip="{ trigger: 'axis' }"
+                :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
+                :chartStyle="{ height: '160px', width: '100%' }"
+                :lineColors="['#E6A23C']"
+              />
+            </div>
+
+            <div class="metric" :class="{ 'metric-alert': dev.alerts.pressure }">
+              <div class="metric-head">
+                <span>鍘嬪姏(MPa)</span>
+                <el-tag :type="dev.alerts.pressure ? 'warning' : 'info'" size="small">{{ dev.alerts.pressure ? '瓒婄晫' : '0.2~1.5' }}</el-tag>
+              </div>
+              <div class="metric-value">{{ currentValue(dev.series.pressure).toFixed(2) }}</div>
+              <Echarts
+                :xAxis="[{ type: 'category', data: xAxisLabels }]"
+                :yAxis="[{ type: 'value', name: 'MPa' }]"
+                :series="[{ type: 'line', smooth: true, showSymbol: false, data: dev.series.pressure }]"
+                :tooltip="{ trigger: 'axis' }"
+                :grid="{ left: 40, right: 10, top: 10, bottom: 20 }"
+                :chartStyle="{ height: '160px', width: '100%' }"
+                :lineColors="['#67C23A']"
+              />
+            </div>
+          </div>
+        </el-card>
+      </el-col>
+    </el-row>
+  </div>
+  
+</template>
+
+<script setup>
+import { ref, reactive, onMounted, onBeforeUnmount, computed } from 'vue'
+import { ElNotification } from 'element-plus'
+import Echarts from '@/components/Echarts/echarts.vue'
+
+defineOptions({ name: 'IoTMonitor' })
+
+const windowSize = 30
+const collecting = ref(true)
+const lastUpdated = ref(Date.now())
+const lastUpdatedDisplay = computed(() => new Date(lastUpdated.value).toLocaleTimeString())
+
+const xAxisLabels = ref(Array.from({ length: windowSize }, (_, i) => i - (windowSize - 1)).map(n => `${n}s`))
+
+function makeSeries(fill, decimals = 2) {
+  return Array.from({ length: windowSize }, () => Number(fill.toFixed(decimals)))
+}
+
+const devices = reactive([
+  {
+    id: 'hydrocyclone-desander',
+    name: '鏃嬫祦闄ょ爞鍣�',
+    type: '鍒嗙璁惧',
+    baseline: { vibration: 8 },
+    initial: { temperature: 35, pressure: 0.85 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(8),
+      temperature: makeSeries(35, 1),
+      pressure: makeSeries(0.85, 2),
+    },
+  },
+  {
+    id: 'high-pressure-separator',
+    name: '楂樺帇鍒嗙鍣ㄦ挰',
+    type: '鍒嗙璁惧',
+    baseline: { vibration: 6 },
+    initial: { temperature: 45, pressure: 1.20 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(6),
+      temperature: makeSeries(45, 1),
+      pressure: makeSeries(1.2, 2),
+    },
+  },
+  {
+    id: 'heating-throttle-pressure',
+    name: '缁勫悎寮忓姞鐑妭娴佽皟鍘�',
+    type: '璋冨帇璁惧',
+    baseline: { vibration: 10 },
+    initial: { temperature: 75, pressure: 1.80 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(10),
+      temperature: makeSeries(75, 1),
+      pressure: makeSeries(1.8, 2),
+    },
+  },
+  {
+    id: 'three-phase-separator',
+    name: '涓夌浉鍒嗙鍣�',
+    type: '鍒嗙璁惧',
+    baseline: { vibration: 7 },
+    initial: { temperature: 38, pressure: 0.95 },
+    alerts: { vibration: false, temperature: false, pressure: false },
+    hasAlert: false,
+    series: {
+      vibration: makeSeries(7),
+      temperature: makeSeries(38, 1),
+      pressure: makeSeries(0.95, 2),
+    },
+  },
+])
+
+function currentValue(arr) {
+  return arr[arr.length - 1] ?? 0
+}
+
+function pushWindow(arr, val) {
+  if (arr.length >= windowSize) arr.shift()
+  arr.push(val)
+}
+
+function clamp(val, min, max) { return Math.max(min, Math.min(max, val)) }
+
+function tickDevice(dev) {
+  const vibBase = dev.baseline.vibration
+  // 鎸姩锛氬熀绾柯�2%闅忔満娉㈠姩锛�5%姒傜巼瑙﹀彂8%~12%灏栧嘲妯℃嫙鍛婅
+  const spike = Math.random() < 0.05
+  const vibNoise = vibBase * (spike ? (1 + (Math.random() * 0.08 + 0.04) * (Math.random() < 0.5 ? -1 : 1)) : (1 + (Math.random() - 0.5) * 0.04))
+  const vibVal = Number(vibNoise.toFixed(2))
+  pushWindow(dev.series.vibration, vibVal)
+
+  // 娓╁害锛氱紦鎱㈤殢鏈烘父璧帮紝骞舵坊鍔犲伓鍙戦珮娓╁亸绉�
+  const tPrev = currentValue(dev.series.temperature)
+  const tDrift = tPrev + (Math.random() - 0.5) * 0.8 + (Math.random() < 0.02 ? 6 : 0)
+  const tVal = Number(clamp(tDrift, 15, 95).toFixed(1))
+  pushWindow(dev.series.temperature, tVal)
+
+  // 鍘嬪姏锛氬皬骞呮尝鍔紝鍋跺彂浣庡帇/楂樺帇
+  const pPrev = currentValue(dev.series.pressure)
+  const pDrift = pPrev + (Math.random() - 0.5) * 0.05 + (Math.random() < 0.02 ? (Math.random() < 0.5 ? -0.3 : 0.3) : 0)
+  const pVal = Number(clamp(pDrift, 0.05, 2.0).toFixed(2))
+  pushWindow(dev.series.pressure, pVal)
+
+  // 杈圭紭璁$畻闃堝�煎垽鏂�
+  const vibDelta = Math.abs(vibVal - vibBase) / vibBase
+  const vibAlert = vibDelta > 0.05
+  const tAlert = tVal < 20 || tVal > 80
+  const pAlert = pVal < 0.2 || pVal > 1.5
+
+  const prevHasAlert = dev.hasAlert
+  dev.alerts.vibration = vibAlert
+  dev.alerts.temperature = tAlert
+  dev.alerts.pressure = pAlert
+  dev.hasAlert = vibAlert || tAlert || pAlert
+
+  if (dev.hasAlert && !prevHasAlert) {
+    const reasons = []
+    if (vibAlert) reasons.push(`鎸姩鍋忕卤5% (褰撳墠 ${vibVal} / 鍩虹嚎 ${vibBase})`)
+    if (tAlert) reasons.push(`娓╁害瓒婄晫 (褰撳墠 ${tVal}掳C, 鏈熸湜 20~80掳C) `)
+    if (pAlert) reasons.push(`鍘嬪姏瓒婄晫 (褰撳墠 ${pVal}MPa, 鏈熸湜 0.2~1.5MPa) `)
+    ElNotification({
+      title: `${dev.name} 鍛婅`,
+      message: reasons.join('锛�'),
+      type: vibAlert ? 'error' : 'warning',
+      duration: 5000,
+    })
+  }
+}
+
+let timer = null
+function start() {
+  if (timer) return
+  timer = setInterval(() => {
+    if (!collecting.value) return
+    devices.forEach(tickDevice)
+    lastUpdated.value = Date.now()
+  }, 10000)
+}
+
+function stop() {
+  if (timer) {
+    clearInterval(timer)
+    timer = null
+  }
+}
+
+function toggleCollecting() { collecting.value = !collecting.value }
+
+function resetAll() {
+  devices.forEach(dev => {
+    dev.series.vibration = makeSeries(dev.baseline.vibration)
+    const t0 = dev.initial?.temperature ?? 45
+    const p0 = dev.initial?.pressure ?? 0.8
+    dev.series.temperature = makeSeries(t0, 1)
+    dev.series.pressure = makeSeries(p0, 2)
+    dev.alerts.vibration = false
+    dev.alerts.temperature = false
+    dev.alerts.pressure = false
+    dev.hasAlert = false
+  })
+  lastUpdated.value = Date.now()
+}
+
+onMounted(() => {
+  start()
+})
+
+onBeforeUnmount(() => {
+  stop()
+})
+</script>
+
+<style lang="scss" scoped>
+.iot-monitor {
+  .header {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-bottom: 12px;
+    .title { font-size: 18px; font-weight: 600; }
+    .actions { display: flex; align-items: center; gap: 8px; }
+    .ts { color: #909399; font-size: 12px; }
+  }
+  .rule-alert { margin-bottom: 12px; }
+}
+
+.device-card {
+  margin-bottom: 16px;
+  transition: border-color 0.2s ease, box-shadow 0.2s ease;
+  &.is-alert { border-color: #F56C6C; box-shadow: 0 0 0 2px rgba(245,108,108,0.2) inset; }
+  .card-header {
+    display: flex; flex-direction: column; gap: 4px;
+    .card-title { display: flex; align-items: center; gap: 8px; font-weight: 600; }
+    .meta { color: #909399; font-size: 12px; }
+  }
+  .metrics {
+    display: grid;
+    grid-template-columns: 1fr;
+    gap: 12px;
+  }
+}
+
+.metric {
+  border: 1px solid #ebeef5;
+  border-radius: 6px;
+  padding: 8px 8px 0 8px;
+  &-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 4px; font-size: 13px; color: #606266; }
+  &-value { font-size: 20px; font-weight: 600; margin: 2px 0 6px 0; }
+}
+
+.metric-alert {
+  border-color: #F56C6C;
+  background: #FFF6F6;
+}
+
+@media (min-width: 1200px) {
+  .device-card .metrics { grid-template-columns: 1fr 1fr 1fr; }
+}
+</style>
+
+
diff --git a/src/views/equipmentManagement/ledger/Form.vue b/src/views/equipmentManagement/ledger/Form.vue
index f7029ee..0951fd8 100644
--- a/src/views/equipmentManagement/ledger/Form.vue
+++ b/src/views/equipmentManagement/ledger/Form.vue
@@ -8,7 +8,7 @@
       </el-col>
       <el-col :span="12">
         <el-form-item label="瑙勬牸鍨嬪彿" prop="deviceModel">
-          <el-input v-model="form.deviceModel" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
+          <el-input v-model="form.deviceModel" :disabled="(form.deviceModel != null && operationType === 'edit')" placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�" />
         </el-form-item>
       </el-col>
       <el-col :span="12">
@@ -119,6 +119,7 @@
   name: "璁惧鍙拌处琛ㄥ崟",
 });
 const formRef = ref(null);
+const operationType = ref('');
 const formRules = {
 	deviceName: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
 	deviceModel: [{ required: true, trigger: "blur", message: "璇疯緭鍏�" }],
@@ -144,6 +145,9 @@
 });
 
 const loadForm = async (id) => {
+	if (id) {
+		operationType.value = 'edit'
+	}
   const { code, data } = await getLedgerById(id);
   if (code == 200) {
     form.deviceName = data.deviceName;
diff --git a/src/views/equipmentManagement/ledger/index.vue b/src/views/equipmentManagement/ledger/index.vue
index 16fbbc6..decd235 100644
--- a/src/views/equipmentManagement/ledger/index.vue
+++ b/src/views/equipmentManagement/ledger/index.vue
@@ -76,6 +76,8 @@
           size: pagination.pageSize,
           total: pagination.total,
         }"
+        :isShowSummary="true"
+        :summaryMethod="summaryMethod"
         @selection-change="handleSelectionChange"
         @pagination="changePage"
       >
@@ -103,6 +105,8 @@
 import dayjs from "dayjs";
 import QRCode from "qrcode";
 import { ref } from "vue";
+import { summarizeTable } from "@/utils/summarizeTable";
+import {Search} from "@element-plus/icons-vue";
 
 defineOptions({
   name: "璁惧鍙拌处",
@@ -127,7 +131,12 @@
 } = usePaginationApi(
   getLedgerPage,
   {
-    searchText: undefined,
+    deviceName: undefined,
+    deviceModel: undefined,
+    supplierName: undefined,
+    unit: undefined,
+    entryDateStart: undefined,
+    entryDateEnd: undefined,
   },
   [
     {
@@ -227,6 +236,20 @@
 	pagination.pageSize = limit;
   onCurrentChange(page);
 };
+
+// 鍚堣鏂规硶
+const summaryMethod = (param) => {
+  return summarizeTable(
+    param,
+    ['number', 'taxIncludingPriceTotal', 'unTaxIncludingPriceTotal', 'taxIncludingPriceUnit'],
+    {
+      number: { noDecimal: true },
+      taxIncludingPriceTotal: { decimalPlaces: 2 },
+      unTaxIncludingPriceTotal: { decimalPlaces: 2 }
+    }
+  );
+};
+
 const deleteRow = (id) => {
   ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?", "鎻愮ず", {
     confirmButtonText: "纭畾",
diff --git a/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue b/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
index c82fc8f..f9679a0 100644
--- a/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
+++ b/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
@@ -94,23 +94,23 @@
 						</el-form-item>
 					</el-col>
 				</el-row>
-				<el-row :gutter="30">
-					<el-col :span="24">
-						<el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
-							<el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
-												 :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
-												 :on-success="handleUploadSuccess" :on-remove="handleRemove">
-								<el-button type="primary" v-if="operationType !== 'view'">涓婁紶</el-button>
-								<template #tip v-if="operationType !== 'view'">
-									<div class="el-upload__tip">
-										鏂囦欢鏍煎紡鏀寔
-										doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
-									</div>
-								</template>
-							</el-upload>
-						</el-form-item>
-					</el-col>
-				</el-row>
+<!--				<el-row :gutter="30">-->
+<!--					<el-col :span="24">-->
+<!--						<el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">-->
+<!--							<el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload-->
+<!--												 :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"-->
+<!--												 :on-success="handleUploadSuccess" :on-remove="handleRemove">-->
+<!--								<el-button type="primary" v-if="operationType !== 'view'">涓婁紶</el-button>-->
+<!--								<template #tip v-if="operationType !== 'view'">-->
+<!--									<div class="el-upload__tip">-->
+<!--										鏂囦欢鏍煎紡鏀寔-->
+<!--										doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z-->
+<!--									</div>-->
+<!--								</template>-->
+<!--							</el-upload>-->
+<!--						</el-form-item>-->
+<!--					</el-col>-->
+<!--				</el-row>-->
 			</el-form>
 			<template #footer>
 				<div class="dialog-footer">
diff --git a/src/views/equipmentManagement/measurementEquipment/components/formDia.vue b/src/views/equipmentManagement/measurementEquipment/components/formDia.vue
index 6319cb6..a9e08d1 100644
--- a/src/views/equipmentManagement/measurementEquipment/components/formDia.vue
+++ b/src/views/equipmentManagement/measurementEquipment/components/formDia.vue
@@ -90,23 +90,23 @@
 						</el-form-item>
 					</el-col>
 				</el-row>
-				<el-row :gutter="30">
-					<el-col :span="24">
-						<el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">
-							<el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload
-												 :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"
-												 :on-success="handleUploadSuccess" :on-remove="handleRemove">
-								<el-button type="primary" v-if="operationType !== 'view'">涓婁紶</el-button>
-								<template #tip v-if="operationType !== 'view'">
-									<div class="el-upload__tip">
-										鏂囦欢鏍煎紡鏀寔
-										doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z
-									</div>
-								</template>
-							</el-upload>
-						</el-form-item>
-					</el-col>
-				</el-row>
+<!--				<el-row :gutter="30">-->
+<!--					<el-col :span="24">-->
+<!--						<el-form-item label="闄勪欢鏉愭枡锛�" prop="remark">-->
+<!--							<el-upload v-model:file-list="fileList" :action="upload.url" multiple ref="fileUpload" auto-upload-->
+<!--												 :headers="upload.headers" :before-upload="handleBeforeUpload" :on-error="handleUploadError"-->
+<!--												 :on-success="handleUploadSuccess" :on-remove="handleRemove">-->
+<!--								<el-button type="primary" v-if="operationType !== 'view'">涓婁紶</el-button>-->
+<!--								<template #tip v-if="operationType !== 'view'">-->
+<!--									<div class="el-upload__tip">-->
+<!--										鏂囦欢鏍煎紡鏀寔-->
+<!--										doc锛宒ocx锛寈ls锛寈lsx锛宲pt锛宲ptx锛宲df锛宼xt锛寈ml锛宩pg锛宩peg锛宲ng锛実if锛宐mp锛宺ar锛寊ip锛�7z-->
+<!--									</div>-->
+<!--								</template>-->
+<!--							</el-upload>-->
+<!--						</el-form-item>-->
+<!--					</el-col>-->
+<!--				</el-row>-->
 			</el-form>
 			<template #footer>
 				<div class="dialog-footer">
diff --git a/src/views/equipmentManagement/measurementEquipment/filesDia.vue b/src/views/equipmentManagement/measurementEquipment/filesDia.vue
new file mode 100644
index 0000000..f752496
--- /dev/null
+++ b/src/views/equipmentManagement/measurementEquipment/filesDia.vue
@@ -0,0 +1,202 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="dialogFormVisible"
+        title="涓婁紶闄勪欢"
+        width="50%"
+        @close="closeDia"
+    >
+      <div style="margin-bottom: 10px;text-align: right">
+        <el-upload
+            v-model:file-list="fileList"
+            class="upload-demo"
+            :action="uploadUrl"
+            :on-success="handleUploadSuccess"
+            :on-error="handleUploadError"
+            name="file"
+            :show-file-list="false"
+            :headers="headers"
+            style="display: inline;margin-right: 10px"
+        >
+          <el-button type="primary">涓婁紶闄勪欢</el-button>
+        </el-upload>
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+      </div>
+      <PIMTable
+          rowKey="id"
+          :column="tableColumn"
+          :tableData="tableData"
+          :tableLoading="tableLoading"
+          :isSelection="true"
+          @selection-change="handleSelectionChange"
+          height="500"
+      >
+      </PIMTable>
+			<pagination
+				style="margin: 10px 0"
+				v-show="total > 0"
+				@pagination="paginationSearch"
+				:total="total"
+				:page="page.current"
+				:limit="page.size"
+			/>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <filePreview ref="filePreviewRef" />
+  </div>
+</template>
+
+<script setup>
+import {ref} from "vue";
+import {ElMessageBox} from "element-plus";
+import {getToken} from "@/utils/auth.js";
+import filePreview from '@/components/filePreview/index.vue'
+import {
+  fileAdd,
+  fileDel,
+  fileListPage
+} from "@/api/financialManagement/revenueManagement.js";
+import Pagination from "@/components/PIMTable/Pagination.vue";
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close'])
+
+const dialogFormVisible = ref(false);
+const currentId = ref('')
+const selectedRows = ref([]);
+const filePreviewRef = ref()
+const tableColumn = ref([
+  {
+    label: "鏂囦欢鍚嶇О",
+    prop: "name",
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    operation: [
+      {
+        name: "涓嬭浇",
+        type: "text",
+        clickFun: (row) => {
+          downLoadFile(row);
+        },
+      },
+      {
+        name: "棰勮",
+        type: "text",
+        clickFun: (row) => {
+          lookFile(row);
+        },
+      }
+    ],
+  },
+]);
+const page = reactive({
+	current: 1,
+	size: 100,
+});
+const total = ref(0);
+const tableData = ref([]);
+const fileList = ref([]);
+const tableLoading = ref(false);
+const accountType = ref('')
+const headers = ref({
+  Authorization: "Bearer " + getToken(),
+});
+const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
+
+// 鎵撳紑寮规
+const openDialog = (row,type) => {
+  accountType.value = type;
+  dialogFormVisible.value = true;
+  currentId.value = row.id;
+  getList()
+}
+const paginationSearch = (obj) => {
+	page.current = obj.page;
+	page.size = obj.limit;
+	getList();
+};
+const getList = () => {
+  fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => {
+    tableData.value = res.data.records;
+		total.value = res.data.total;
+  })
+}
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+// 鍏抽棴寮规
+const closeDia = () => {
+  dialogFormVisible.value = false;
+  emit('close')
+};
+// 涓婁紶鎴愬姛澶勭悊
+function handleUploadSuccess(res, file) {
+  // 濡傛灉涓婁紶鎴愬姛
+  if (res.code == 200) {
+    const fileRow = {}
+    fileRow.name = res.data.originalName
+    fileRow.url = res.data.tempPath
+    uploadFile(fileRow)
+  } else {
+    proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+  }
+}
+function uploadFile(file) {
+  file.accountId = currentId.value;
+  file.accountType = accountType.value;
+  fileAdd(file).then(res => {
+    proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+    getList()
+  })
+}
+// 涓婁紶澶辫触澶勭悊
+function handleUploadError() {
+  proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+}
+// 涓嬭浇闄勪欢
+const downLoadFile = (row) => {
+  proxy.$download.name(row.url);
+}
+// 鍒犻櫎
+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(() => {
+    fileDel(ids).then((res) => {
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      getList();
+    });
+  }).catch(() => {
+    proxy.$modal.msg("宸插彇娑�");
+  });
+};
+// 棰勮闄勪欢
+const lookFile = (row) => {
+  filePreviewRef.value.open(row.url)
+}
+
+defineExpose({
+  openDialog,
+});
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/measurementEquipment/index.vue b/src/views/equipmentManagement/measurementEquipment/index.vue
index bb163be..e983a99 100644
--- a/src/views/equipmentManagement/measurementEquipment/index.vue
+++ b/src/views/equipmentManagement/measurementEquipment/index.vue
@@ -44,6 +44,7 @@
 		</div>
 		<form-dia ref="formDia" @close="handleQuery"></form-dia>
 		<calibration-dia ref="calibrationDia" @close="handleQuery"></calibration-dia>
+    <files-dia ref="filesDia"></files-dia>
 	</div>
 </template>
 
@@ -57,6 +58,7 @@
 	measuringInstrumentDelete,
 	measuringInstrumentListPage
 } from "@/api/equipmentManagement/measurementEquipment.js";
+import FilesDia from "./filesDia.vue";
 const { proxy } = getCurrentInstance();
 const userStore = useUserStore()
 
@@ -136,6 +138,7 @@
 		dataType: "action",
 		label: "鎿嶄綔",
 		align: "center",
+		width: '130',
 		fixed: 'right',
 		operation: [
 			{
@@ -149,7 +152,7 @@
 				name: "闄勪欢",
 				type: "text",
 				clickFun: (row) => {
-					openCalibrationDia("add", row);
+          openFilesFormDia(row);
 				},
 			},
 		],
@@ -157,6 +160,7 @@
 ]);
 const tableData = ref([]);
 const tableLoading = ref(false);
+const filesDia = ref()
 const page = reactive({
 	current: 1,
 	size: 100,
@@ -164,6 +168,14 @@
 });
 const selectedRows = ref([]);
 
+// 鎵撳紑闄勪欢寮规
+const openFilesFormDia = (row) => {
+  console.log(row)
+  nextTick(() => {
+    filesDia.value?.openDialog( row,'璁¢噺鍣ㄥ叿鍙拌处')
+  })
+};
+
 // 琛ㄦ牸閫夋嫨鏁版嵁
 const handleSelectionChange = (selection) => {
 	selectedRows.value = selection;
diff --git a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
index e8adc82..309be0e 100644
--- a/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/MaintainModal.vue
@@ -1,5 +1,5 @@
 <template>
-  <el-drawer v-model="visible" :title="modalOptions.title" direction="ltr">
+  <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr">
     <MaintainForm ref="maintainFormRef" />
     <template #footer>
 			<el-button type="primary" @click="sendForm" :loading="loading">
@@ -7,7 +7,7 @@
 			</el-button>
       <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
     </template>
-  </el-drawer>
+  </el-dialog>
 </template>
 
 <script setup>
diff --git a/src/views/equipmentManagement/repair/index.vue b/src/views/equipmentManagement/repair/index.vue
index 6cae307..3ef3692 100644
--- a/src/views/equipmentManagement/repair/index.vue
+++ b/src/views/equipmentManagement/repair/index.vue
@@ -139,6 +139,7 @@
 import { ElMessageBox, ElMessage } from "element-plus";
 import dayjs from "dayjs";
 import MaintainModal from "./Modal/MaintainModal.vue";
+import {Search} from "@element-plus/icons-vue";
 
 defineOptions({
   name: "璁惧鎶ヤ慨",
@@ -163,7 +164,12 @@
 } = usePaginationApi(
   getRepairPage,
   {
-    searchText: undefined,
+    deviceName: undefined,
+    deviceModel: undefined,
+    remark: undefined,
+    maintenanceName: undefined,
+    repairTimeStr: undefined,
+    maintenanceTimeStr: undefined,
   },
   [
     {
diff --git a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
index 1edcf23..1b5a7d4 100644
--- a/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
+++ b/src/views/equipmentManagement/upkeep/Modal/MaintenanceModal.vue
@@ -1,5 +1,5 @@
 <template>
-  <el-drawer v-model="visible" :title="modalOptions.title" direction="ltr">
+  <el-dialog v-model="visible" :title="modalOptions.title" direction="ltr">
     <MaintenanceForm ref="maintenanceFormRef" />
     <template #footer>
 			<el-button type="primary" @click="sendForm" :loading="loading">
@@ -7,7 +7,7 @@
 			</el-button>
       <el-button @click="closeModal">{{ modalOptions.cancelText }}</el-button>
     </template>
-  </el-drawer>
+  </el-dialog>
 </template>
 
 <script setup>
diff --git a/src/views/equipmentManagement/upkeep/index.vue b/src/views/equipmentManagement/upkeep/index.vue
index f44d817..484538c 100644
--- a/src/views/equipmentManagement/upkeep/index.vue
+++ b/src/views/equipmentManagement/upkeep/index.vue
@@ -127,6 +127,7 @@
 import MaintenanceModal from "./Modal/MaintenanceModal.vue";
 import dayjs from "dayjs";
 import { ElMessageBox, ElMessage } from "element-plus";
+import {Search} from "@element-plus/icons-vue";
 
 defineOptions({
   name: "璁惧淇濆吇",
@@ -154,7 +155,12 @@
   getTableData,
   resetFilters,
   onCurrentChange,
-} = usePaginationApi(getUpkeepPage, {}, [
+} = usePaginationApi(getUpkeepPage, {
+  deviceName: undefined,
+  maintenancePlanTime: undefined,
+  maintenanceActuallyTime: undefined,
+  maintenanceActuallyName: undefined,
+}, [
   {
     label: "璁惧鍚嶇О",
     align: "center",
diff --git a/src/views/financialManagement/expenseManagement/index.vue b/src/views/financialManagement/expenseManagement/index.vue
index 32d906b..b1e9fb1 100644
--- a/src/views/financialManagement/expenseManagement/index.vue
+++ b/src/views/financialManagement/expenseManagement/index.vue
@@ -1,7 +1,7 @@
 <template>
   <div class="app-container">
     <el-form :model="filters" :inline="true">
-      <el-form-item label="褰曞叆鏃ユ湡:">
+      <el-form-item label="鏀嚭鏃ユ湡:">
         <el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                         placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
       </el-form-item>
diff --git a/src/views/financialManagement/revenueManagement/index.vue b/src/views/financialManagement/revenueManagement/index.vue
index 35f3075..285b73f 100644
--- a/src/views/financialManagement/revenueManagement/index.vue
+++ b/src/views/financialManagement/revenueManagement/index.vue
@@ -1,7 +1,7 @@
 <template>
   <div class="app-container">
     <el-form :model="filters" :inline="true">
-      <el-form-item label="褰曞叆鏃ユ湡:">
+      <el-form-item label="鏀跺叆鏃ユ湡:">
         <el-date-picker v-model="filters.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
                         placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
       </el-form-item>
diff --git a/src/views/index.vue b/src/views/index.vue
index 95fe72c..67c8654 100644
--- a/src/views/index.vue
+++ b/src/views/index.vue
@@ -118,11 +118,11 @@
 			<div class="main-panel">
 				<div style="display: flex;justify-content: space-between;">
 					<div class="section-title">搴旀敹搴斾粯缁熻</div>
-					<el-radio-group v-model="radio1" size="large" @change="statisticsReceivable">
-						<el-radio-button label="鎸夊懆" :value="1" />
-						<el-radio-button label="鎸夋湀" :value="2" />
-						<el-radio-button label="鎸夊搴�" :value="3" />
-					</el-radio-group>
+<!--					<el-radio-group v-model="radio1" size="large" @change="statisticsReceivable">-->
+<!--						<el-radio-button label="鎸夊懆" :value="1" />-->
+<!--						<el-radio-button label="鎸夋湀" :value="2" />-->
+<!--						<el-radio-button label="鎸夊搴�" :value="3" />-->
+<!--					</el-radio-group>-->
 				</div>
 				<Echarts ref="chart"
 								 :color="barColors2"
@@ -138,23 +138,23 @@
 		
 		<!-- 搴曢儴妯悜涓ゆ爮 -->
 		<div class="dashboard-row">
-			<div class="main-panel">
-				<div class="section-title">璐ㄩ噺缁熻</div>
-				<div class="quality-cards">
-					<div class="quality-card one">鍘熸潗鏂欏凡妫�娴嬫暟 <span>{{qualityStatisticsObject.supplierNum}}浠�</span></div>
-					<div class="quality-card two">杩囩▼妫�楠屾暟閲� <span>{{qualityStatisticsObject.processNum}}浠�</span></div>
-					<div class="quality-card three">鍑哄巶宸叉鏁伴噺 <span>{{qualityStatisticsObject.factoryNum}}浠�</span></div>
-				</div>
-				<Echarts ref="chart"
-								 :chartStyle="chartStyle"
-								 :grid="grid"
-								 :legend="barLegend"
-								 :series="barSeries1"
-								 :tooltip="tooltip"
-								 :xAxis="xAxis1"
-								 :yAxis="yAxis1"
-								 style="height: 260px"></Echarts>
-			</div>
+<!--			<div class="main-panel">-->
+<!--				<div class="section-title">璐ㄩ噺缁熻</div>-->
+<!--				<div class="quality-cards">-->
+<!--					<div class="quality-card one">鍘熸潗鏂欏凡妫�娴嬫暟 <span>{{qualityStatisticsObject.supplierNum}}浠�</span></div>-->
+<!--					<div class="quality-card two">杩囩▼妫�楠屾暟閲� <span>{{qualityStatisticsObject.processNum}}浠�</span></div>-->
+<!--					<div class="quality-card three">鍑哄巶宸叉鏁伴噺 <span>{{qualityStatisticsObject.factoryNum}}浠�</span></div>-->
+<!--				</div>-->
+<!--				<Echarts ref="chart"-->
+<!--								 :chartStyle="chartStyle"-->
+<!--								 :grid="grid"-->
+<!--								 :legend="barLegend"-->
+<!--								 :series="barSeries1"-->
+<!--								 :tooltip="tooltip"-->
+<!--								 :xAxis="xAxis1"-->
+<!--								 :yAxis="yAxis1"-->
+<!--								 style="height: 260px"></Echarts>-->
+<!--			</div>-->
 			<div class="main-panel">
 				<div class="section-title">鍥炴涓庡紑绁ㄥ垎鏋�</div>
 				<Echarts ref="chart" :chartStyle="chartStyle" :grid="grid" :legend="lineLegend" :series="lineSeries"
@@ -744,15 +744,18 @@
 	color: #666;
 	list-style: none;
 	padding: 0;
+	height: 190px;
+	overflow-y: auto;
+	width: 460px;
 }
 .line {
 	position: relative;
-	width: 250px;
+	width: 230px;
 }
 .line::after {
 	content: '';
 	position: absolute;
-	right: 12px;
+	right: 2px;
 	top: 0;
 	bottom: 0;
 	width: 1px;
diff --git a/src/views/inventoryManagement/dispatchLog/index.vue b/src/views/inventoryManagement/dispatchLog/index.vue
index 504074e..6fe0473 100644
--- a/src/views/inventoryManagement/dispatchLog/index.vue
+++ b/src/views/inventoryManagement/dispatchLog/index.vue
@@ -33,13 +33,14 @@
         style="width: 100%"
         :summary-method="summarizeMainTable"
         height="calc(100vh - 18.5em)"
+        stripe
       >
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
         <el-table-column
           label="鍑哄簱鏃ユ湡"
           prop="createTime"
-          min-width="250"
+          min-width="130"
           show-overflow-tooltip
         />
         <el-table-column
@@ -75,13 +76,13 @@
         <el-table-column
           label="鍚◣鍗曚环(鍏�)"
           prop="taxInclusiveUnitPrice"
-          width="100"
+          width="200"
           show-overflow-tooltip
         />
         <el-table-column
           label="鍚◣鎬讳环(鍏�)"
           prop="taxInclusiveTotalPrice"
-          width="100"
+          width="200"
           show-overflow-tooltip
         />
         <el-table-column
diff --git a/src/views/inventoryManagement/issueManagement/index.vue b/src/views/inventoryManagement/issueManagement/index.vue
index 4240bef..cc4d8e1 100644
--- a/src/views/inventoryManagement/issueManagement/index.vue
+++ b/src/views/inventoryManagement/issueManagement/index.vue
@@ -16,7 +16,7 @@
     <div class="table_list">
       <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
         :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
-        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
+        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)" stripe>
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
         <el-table-column label="鍏ュ簱鏃堕棿" prop="createTime" width="100" show-overflow-tooltip />
diff --git a/src/views/inventoryManagement/receiptManagement/index.vue b/src/views/inventoryManagement/receiptManagement/index.vue
index acf0b68..238f3fd 100644
--- a/src/views/inventoryManagement/receiptManagement/index.vue
+++ b/src/views/inventoryManagement/receiptManagement/index.vue
@@ -16,7 +16,7 @@
     <div class="table_list">
       <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
         :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
-        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
+        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)" stripe>
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
         <el-table-column label="鍏ュ簱鏃堕棿" prop="createTime" width="100" show-overflow-tooltip />
@@ -66,6 +66,7 @@
           border
           v-loading="loadingProducts"
           @selection-change="handleSelectionChange"
+          stripe
         >
           <el-table-column align="center" type="selection" width="55" />
           <el-table-column
diff --git a/src/views/inventoryManagement/stockManagement/index.vue b/src/views/inventoryManagement/stockManagement/index.vue
index b4a29eb..06fcaf8 100644
--- a/src/views/inventoryManagement/stockManagement/index.vue
+++ b/src/views/inventoryManagement/stockManagement/index.vue
@@ -16,7 +16,7 @@
     <div class="table_list">
       <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
         :expand-row-keys="expandedRowKeys" :row-key="row => row.id" show-summary style="width: 100%"
-        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
+        :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)" stripe>
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
         <el-table-column label="搴撳瓨鏃ユ湡" prop="createTime" width="100" show-overflow-tooltip />
diff --git a/src/views/inventoryManagement/stockWarning/index.vue b/src/views/inventoryManagement/stockWarning/index.vue
index 3694265..4193352 100644
--- a/src/views/inventoryManagement/stockWarning/index.vue
+++ b/src/views/inventoryManagement/stockWarning/index.vue
@@ -51,6 +51,7 @@
         @selection-change="handleSelectionChange"
         style="width: 100%"
         height="calc(100vh - 280px)"
+        stripe
       >
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
diff --git a/src/views/login.vue b/src/views/login.vue
index 6046eeb..5300637 100644
--- a/src/views/login.vue
+++ b/src/views/login.vue
@@ -86,8 +86,8 @@
 const { proxy } = getCurrentInstance()
 
 const loginForm = ref({
-  username: "admin",
-  password: "admin123",
+  username: "",
+  password: "",
   rememberMe: false,
   currentFatoryId:'',
 })
@@ -181,7 +181,7 @@
 <style lang='scss' scoped>
 .login {
   height: 100%;
-  background-image: url("../assets/indexViews/JZYJView.png");
+  background-image: url("../assets/images/login-background.png");
   background-size: cover;
   position: relative;
 }
diff --git a/src/views/monitor/job/index.vue b/src/views/monitor/job/index.vue
index ee291a4..918be40 100644
--- a/src/views/monitor/job/index.vue
+++ b/src/views/monitor/job/index.vue
@@ -87,7 +87,7 @@
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
       </el-row>
 
-      <el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange">
+      <el-table v-loading="loading" :data="jobList" @selection-change="handleSelectionChange" stripe>
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="浠诲姟缂栧彿" width="100" align="center" prop="jobId" />
          <el-table-column label="浠诲姟鍚嶇О" align="center" prop="jobName" :show-overflow-tooltip="true" />
diff --git a/src/views/monitor/job/log.vue b/src/views/monitor/job/log.vue
index b425e45..30ef218 100644
--- a/src/views/monitor/job/log.vue
+++ b/src/views/monitor/job/log.vue
@@ -96,7 +96,7 @@
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
       </el-row>
 
-      <el-table v-loading="loading" :data="jobLogList" @selection-change="handleSelectionChange">
+      <el-table v-loading="loading" :data="jobLogList" @selection-change="handleSelectionChange" stripe>
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="鏃ュ織缂栧彿" width="80" align="center" prop="jobLogId" />
          <el-table-column label="浠诲姟鍚嶇О" align="center" prop="jobName" :show-overflow-tooltip="true" />
diff --git a/src/views/monitor/logininfor/index.vue b/src/views/monitor/logininfor/index.vue
index aa42b52..bee51a1 100644
--- a/src/views/monitor/logininfor/index.vue
+++ b/src/views/monitor/logininfor/index.vue
@@ -93,7 +93,7 @@
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
       </el-row>
 
-      <el-table ref="logininforRef" v-loading="loading" :data="logininforList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange">
+      <el-table ref="logininforRef" v-loading="loading" :data="logininforList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange" stripe>
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="璁块棶缂栧彿" align="center" prop="infoId" />
          <el-table-column label="鐢ㄦ埛鍚嶇О" align="center" prop="userName" :show-overflow-tooltip="true" sortable="custom" :sort-orders="['descending', 'ascending']" />
diff --git a/src/views/monitor/online/index.vue b/src/views/monitor/online/index.vue
index 21f6463..7a56ad5 100644
--- a/src/views/monitor/online/index.vue
+++ b/src/views/monitor/online/index.vue
@@ -28,6 +28,7 @@
          v-loading="loading"
          :data="onlineList.slice((pageNum - 1) * pageSize, pageNum * pageSize)"
          style="width: 100%;"
+         stripe
       >
          <el-table-column label="搴忓彿" width="50" type="index" align="center">
             <template #default="scope">
diff --git a/src/views/monitor/operlog/index.vue b/src/views/monitor/operlog/index.vue
index 92f9c35..edb57dd 100644
--- a/src/views/monitor/operlog/index.vue
+++ b/src/views/monitor/operlog/index.vue
@@ -107,7 +107,7 @@
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
       </el-row>
 
-      <el-table ref="operlogRef" v-loading="loading" :data="operlogList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange">
+      <el-table ref="operlogRef" v-loading="loading" :data="operlogList" @selection-change="handleSelectionChange" :default-sort="defaultSort" @sort-change="handleSortChange" stripe>
          <el-table-column type="selection" width="50" align="center" />
          <el-table-column label="鏃ュ織缂栧彿" align="center" prop="operId" />
          <el-table-column label="绯荤粺妯″潡" align="center" prop="title" :show-overflow-tooltip="true" />
diff --git a/src/views/personnelManagement/contractManagement/filesDia.vue b/src/views/personnelManagement/contractManagement/filesDia.vue
new file mode 100644
index 0000000..f752496
--- /dev/null
+++ b/src/views/personnelManagement/contractManagement/filesDia.vue
@@ -0,0 +1,202 @@
+<template>
+  <div>
+    <el-dialog
+        v-model="dialogFormVisible"
+        title="涓婁紶闄勪欢"
+        width="50%"
+        @close="closeDia"
+    >
+      <div style="margin-bottom: 10px;text-align: right">
+        <el-upload
+            v-model:file-list="fileList"
+            class="upload-demo"
+            :action="uploadUrl"
+            :on-success="handleUploadSuccess"
+            :on-error="handleUploadError"
+            name="file"
+            :show-file-list="false"
+            :headers="headers"
+            style="display: inline;margin-right: 10px"
+        >
+          <el-button type="primary">涓婁紶闄勪欢</el-button>
+        </el-upload>
+        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
+      </div>
+      <PIMTable
+          rowKey="id"
+          :column="tableColumn"
+          :tableData="tableData"
+          :tableLoading="tableLoading"
+          :isSelection="true"
+          @selection-change="handleSelectionChange"
+          height="500"
+      >
+      </PIMTable>
+			<pagination
+				style="margin: 10px 0"
+				v-show="total > 0"
+				@pagination="paginationSearch"
+				:total="total"
+				:page="page.current"
+				:limit="page.size"
+			/>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button @click="closeDia">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <filePreview ref="filePreviewRef" />
+  </div>
+</template>
+
+<script setup>
+import {ref} from "vue";
+import {ElMessageBox} from "element-plus";
+import {getToken} from "@/utils/auth.js";
+import filePreview from '@/components/filePreview/index.vue'
+import {
+  fileAdd,
+  fileDel,
+  fileListPage
+} from "@/api/financialManagement/revenueManagement.js";
+import Pagination from "@/components/PIMTable/Pagination.vue";
+const { proxy } = getCurrentInstance()
+const emit = defineEmits(['close'])
+
+const dialogFormVisible = ref(false);
+const currentId = ref('')
+const selectedRows = ref([]);
+const filePreviewRef = ref()
+const tableColumn = ref([
+  {
+    label: "鏂囦欢鍚嶇О",
+    prop: "name",
+  },
+  {
+    dataType: "action",
+    label: "鎿嶄綔",
+    align: "center",
+    operation: [
+      {
+        name: "涓嬭浇",
+        type: "text",
+        clickFun: (row) => {
+          downLoadFile(row);
+        },
+      },
+      {
+        name: "棰勮",
+        type: "text",
+        clickFun: (row) => {
+          lookFile(row);
+        },
+      }
+    ],
+  },
+]);
+const page = reactive({
+	current: 1,
+	size: 100,
+});
+const total = ref(0);
+const tableData = ref([]);
+const fileList = ref([]);
+const tableLoading = ref(false);
+const accountType = ref('')
+const headers = ref({
+  Authorization: "Bearer " + getToken(),
+});
+const uploadUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 涓婁紶鐨勫浘鐗囨湇鍔″櫒鍦板潃
+
+// 鎵撳紑寮规
+const openDialog = (row,type) => {
+  accountType.value = type;
+  dialogFormVisible.value = true;
+  currentId.value = row.id;
+  getList()
+}
+const paginationSearch = (obj) => {
+	page.current = obj.page;
+	page.size = obj.limit;
+	getList();
+};
+const getList = () => {
+  fileListPage({accountId: currentId.value,accountType:accountType.value, ...page}).then(res => {
+    tableData.value = res.data.records;
+		total.value = res.data.total;
+  })
+}
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+// 鍏抽棴寮规
+const closeDia = () => {
+  dialogFormVisible.value = false;
+  emit('close')
+};
+// 涓婁紶鎴愬姛澶勭悊
+function handleUploadSuccess(res, file) {
+  // 濡傛灉涓婁紶鎴愬姛
+  if (res.code == 200) {
+    const fileRow = {}
+    fileRow.name = res.data.originalName
+    fileRow.url = res.data.tempPath
+    uploadFile(fileRow)
+  } else {
+    proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+  }
+}
+function uploadFile(file) {
+  file.accountId = currentId.value;
+  file.accountType = accountType.value;
+  fileAdd(file).then(res => {
+    proxy.$modal.msgSuccess("鏂囦欢涓婁紶鎴愬姛");
+    getList()
+  })
+}
+// 涓婁紶澶辫触澶勭悊
+function handleUploadError() {
+  proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
+}
+// 涓嬭浇闄勪欢
+const downLoadFile = (row) => {
+  proxy.$download.name(row.url);
+}
+// 鍒犻櫎
+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(() => {
+    fileDel(ids).then((res) => {
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      getList();
+    });
+  }).catch(() => {
+    proxy.$modal.msg("宸插彇娑�");
+  });
+};
+// 棰勮闄勪欢
+const lookFile = (row) => {
+  filePreviewRef.value.open(row.url)
+}
+
+defineExpose({
+  openDialog,
+});
+</script>
+
+<style scoped>
+
+</style>
\ No newline at end of file
diff --git a/src/views/personnelManagement/contractManagement/index.vue b/src/views/personnelManagement/contractManagement/index.vue
index 57d7ec4..98f0272 100644
--- a/src/views/personnelManagement/contractManagement/index.vue
+++ b/src/views/personnelManagement/contractManagement/index.vue
@@ -3,52 +3,81 @@
     <div class="search_form">
       <div>
         <span class="search_title">濮撳悕锛�</span>
-        <el-input
-            v-model="searchForm.staffName"
-            style="width: 240px"
-            placeholder="璇疯緭鍏ュ鍚嶆悳绱�"
-            @change="handleQuery"
-            clearable
-            :prefix-icon="Search"
-        />
-        <span  style="margin-left: 10px" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span>
-        <el-date-picker  v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
-                         placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
-        <el-button type="primary" @click="handleQuery" style="margin-left: 10px"
-        >鎼滅储</el-button
-        >
+        <el-input v-model="searchForm.staffName" style="width: 240px" placeholder="璇疯緭鍏ュ鍚嶆悳绱�" @change="handleQuery"
+          clearable :prefix-icon="Search" />
+        <span style="margin-left: 10px" class="search_title">鍚堝悓缁撴潫鏃ユ湡锛�</span>
+        <el-date-picker v-model="searchForm.entryDate" value-format="YYYY-MM-DD" format="YYYY-MM-DD" type="daterange"
+          placeholder="璇烽�夋嫨" clearable @change="changeDaterange" />
+        <el-button type="primary" @click="handleQuery" style="margin-left: 10px">鎼滅储</el-button>
       </div>
       <div>
         <!--        <el-button type="primary" @click="openForm('add')">鏂板鍏ヨ亴</el-button>-->
+<!--        <el-button type="info" @click="handleImport">瀵煎叆</el-button>-->
         <el-button @click="handleOut">瀵煎嚭</el-button>
         <!--        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>-->
       </div>
     </div>
     <div class="table_list">
-      <PIMTable
-          rowKey="id"
-          :column="tableColumn"
-          :tableData="tableData"
-          :page="page"
-          :isSelection="true"
-          @selection-change="handleSelectionChange"
-          :tableLoading="tableLoading"
-          @pagination="pagination"
-          :total="page.total"
-      ></PIMTable>
+      <PIMTable rowKey="id" :column="tableColumn" :tableData="tableData" :page="page" :isSelection="true"
+        @selection-change="handleSelectionChange" :tableLoading="tableLoading" @pagination="pagination"
+        :total="page.total"></PIMTable>
     </div>
     <form-dia ref="formDia" @close="handleQuery"></form-dia>
+
+    <!-- 鍚堝悓瀵煎叆瀵硅瘽妗� -->
+    <el-dialog
+      :title="upload.title"
+      v-model="upload.open"
+      width="400px"
+      append-to-body
+    >
+      <el-upload
+        ref="uploadRef"
+        :limit="1"
+        accept=".xlsx, .xls"
+        :headers="upload.headers"
+        :action="upload.url + '?updateSupport=' + upload.updateSupport"
+        :disabled="upload.isUploading"
+        :on-progress="handleFileUploadProgress"
+        :on-success="handleFileSuccess"
+        :auto-upload="false"
+        drag
+      >
+        <el-icon class="el-icon--upload"><upload-filled /></el-icon>
+        <div class="el-upload__text">灏嗘枃浠舵嫋鍒版澶勶紝鎴�<em>鐐瑰嚮涓婁紶</em></div>
+        <template #tip>
+          <div class="el-upload__tip text-center">
+            <span>浠呭厑璁稿鍏ls銆亁lsx鏍煎紡鏂囦欢銆�</span>
+            <!-- <el-link
+              type="primary"
+              :underline="false"
+              style="font-size: 12px; vertical-align: baseline"
+              @click="importTemplate"
+              >涓嬭浇妯℃澘</el-link
+            > -->
+          </div>
+        </template>
+      </el-upload>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitFileForm">纭� 瀹�</el-button>
+          <el-button @click="upload.open = false">鍙� 娑�</el-button>
+        </div>
+      </template>
+    </el-dialog>
+    <files-dia ref="filesDia"></files-dia>
   </div>
 </template>
 
 <script setup>
 import { Search } from "@element-plus/icons-vue";
-import {onMounted, ref} from "vue";
+import { onMounted, ref } from "vue";
 import FormDia from "@/views/personnelManagement/contractManagement/components/formDia.vue";
-import {ElMessageBox} from "element-plus";
-import {staffOnJobListPage} from "@/api/personnelManagement/employeeRecord.js";
+import { ElMessageBox } from "element-plus";
+import { staffOnJobListPage } from "@/api/personnelManagement/employeeRecord.js";
 import dayjs from "dayjs";
-
+import { getToken } from "@/utils/auth.js";
+import FilesDia from "./filesDia.vue";
 const data = reactive({
   searchForm: {
     staffName: "",
@@ -108,7 +137,7 @@
   {
     label: "瀹跺涵浣忓潃",
     prop: "adress",
-    width:200
+    width: 200
   },
   {
     label: "绗竴瀛﹀巻",
@@ -117,12 +146,12 @@
   {
     label: "涓撲笟",
     prop: "profession",
-    width:100
+    width: 100
   },
   {
     label: "韬唤璇佸彿",
     prop: "identityCard",
-    width:200
+    width: 200
   },
   {
     label: "骞撮緞",
@@ -131,7 +160,7 @@
   {
     label: "鑱旂郴鐢佃瘽",
     prop: "phone",
-    width:150
+    width: 150
   },
   {
     label: "绱ф�ヨ仈绯讳汉",
@@ -141,7 +170,7 @@
   {
     label: "绱ф�ヨ仈绯讳汉鐢佃瘽",
     prop: "emergencyContactPhone",
-    width:150
+    width: 150
   },
   {
     label: "鍚堝悓骞撮檺",
@@ -162,6 +191,7 @@
     label: "鎿嶄綔",
     align: "center",
     fixed: 'right',
+    width: 120,
     operation: [
       {
         name: "璇︽儏",
@@ -170,9 +200,17 @@
           openForm("edit", row);
         },
       },
+      {
+        name: "闄勪欢",
+        type: "text",
+        clickFun: (row) => {
+          openFilesFormDia(row);
+        },
+      },
     ],
   },
 ]);
+const filesDia = ref()
 const tableData = ref([]);
 const selectedRows = ref([]);
 const tableLoading = ref(false);
@@ -192,6 +230,13 @@
     searchForm.value.entryDateEnd = dayjs(value[1]).format("YYYY-MM-DD");
   }
   getList();
+};
+// 鎵撳紑闄勪欢寮规
+const openFilesFormDia = (row) => {
+  console.log(row)
+  nextTick(() => {
+    filesDia.value?.openDialog( row,'鍚堝悓')
+  })
 };
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
@@ -234,12 +279,47 @@
     cancelButtonText: "鍙栨秷",
     type: "warning",
   })
-      .then(() => {
-        proxy.download("/staff/staffOnJob/export", {}, "鍚堝悓绠$悊.xlsx");
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
-      });
+    .then(() => {
+      proxy.download("/staff/staffOnJob/export", {}, "鍚堝悓绠$悊.xlsx");
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
+const upload = reactive({
+  // 鏄惁鏄剧ず寮瑰嚭灞傦紙鍚堝悓瀵煎叆锛�
+  open: false,
+  // 寮瑰嚭灞傛爣棰橈紙鍚堝悓瀵煎叆锛�
+  title: "",
+  // 鏄惁绂佺敤涓婁紶
+  isUploading: false,
+  // 鏄惁鏇存柊宸茬粡瀛樺湪鐨勭敤鎴锋暟鎹�
+  updateSupport: 1,
+  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
+  headers: { Authorization: "Bearer " + getToken() },
+  // 涓婁紶鐨勫湴鍧�
+  url: import.meta.env.VITE_APP_BASE_API + "/staff/staffOnJob/import",
+});
+/** 瀵煎叆鎸夐挳鎿嶄綔 */
+function handleImport() {
+  upload.title = "鍚堝悓瀵煎叆";
+  upload.open = true;
+}
+/** 鎻愪氦涓婁紶鏂囦欢 */
+function submitFileForm() {
+  console.log(upload.url + '?updateSupport=' + upload.updateSupport)
+  proxy.$refs["uploadRef"].submit();
+}
+/**鏂囦欢涓婁紶涓鐞� */
+const handleFileUploadProgress = (event, file, fileList) => {
+  upload.isUploading = true;
+};
+/** 鏂囦欢涓婁紶鎴愬姛澶勭悊 */
+const handleFileSuccess = (response, file, fileList) => {
+  upload.open = false;
+  upload.isUploading = false;
+  proxy.$refs["uploadRef"].handleRemove(file);
+  getList();
 };
 onMounted(() => {
   getList();
diff --git a/src/views/personnelManagement/onboarding/components/formDia.vue b/src/views/personnelManagement/onboarding/components/formDia.vue
index d0e76cc..7244ab0 100644
--- a/src/views/personnelManagement/onboarding/components/formDia.vue
+++ b/src/views/personnelManagement/onboarding/components/formDia.vue
@@ -124,6 +124,26 @@
             </el-form-item>
           </el-col>
         </el-row>
+        <el-row :gutter="30">
+          <el-col :span="12">
+            <el-form-item label="璇曠敤鏈燂紙鏈堬級锛�" prop="probationPeriod">
+              <el-input-number v-model="form.probationPeriod" :precision="0" :step="1" min="0" style="width: 100%"/>
+            </el-form-item>
+          </el-col>
+          <!-- <el-col :span="12">
+            <el-form-item label="鍏ヨ亴鏃ユ湡锛�" prop="entryDate">
+              <el-date-picker
+                  v-model="form.entryDate"
+                  type="date"
+                  placeholder="璇烽�夋嫨鏃ユ湡"
+                  value-format="YYYY-MM-DD"
+                  format="YYYY-MM-DD"
+                  clearable
+                  style="width: 100%"
+              />
+            </el-form-item>
+          </el-col> -->
+        </el-row>
       </el-form>
       <template #footer>
         <div class="dialog-footer">
@@ -136,7 +156,7 @@
 </template>
 
 <script setup>
-import {ref} from "vue";
+import {ref, reactive, toRefs} from "vue";
 import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
@@ -162,6 +182,7 @@
     contractStartTime: "",
     contractEndTime: "",
     staffState: "",
+    probationPeriod: 3, // 榛樿璇曠敤鏈�3涓湀
   },
   rules: {
     staffNo: [{ required: true, message: "璇疯緭鍏�", trigger: "blur" },],
diff --git a/src/views/personnelManagement/onboarding/index.vue b/src/views/personnelManagement/onboarding/index.vue
index d36f2e5..d993ee6 100644
--- a/src/views/personnelManagement/onboarding/index.vue
+++ b/src/views/personnelManagement/onboarding/index.vue
@@ -151,8 +151,39 @@
     width:150
   },
   {
-    label: "鍚堝悓骞撮檺",
+    label: "璇曠敤鏈燂紙鏈堬級",
+    prop: "probationPeriod",
+    width: 120,
+  },
+  // {
+  //   label: "杞鏃ユ湡",
+  //   prop: "probationEndDate",
+  //   width: 120,
+  //   formatData: (row) => {
+  //     // 淇敼涓轰娇鐢ㄥ悎鍚屽紑濮嬫棩鏈熻绠楄浆姝f棩鏈�
+  //     if (row.contractStartTime && row.probationPeriod) {
+  //       // 璁$畻杞鏃ユ湡锛堝悎鍚屽紑濮嬫棩鏈熷姞涓婅瘯鐢ㄦ湡鏈堟暟锛�
+  //       return dayjs(row.contractStartTime).add(row.probationPeriod, 'month').format('YYYY-MM-DD');
+  //     }
+  //     return '';
+  //   },
+  //   formatType: (row) => {
+  //     // 淇敼涓轰娇鐢ㄥ悎鍚屽紑濮嬫棩鏈熸鏌ユ槸鍚︿复杩戣浆姝o紙7澶╁唴锛�
+  //     if (row.contractStartTime && row.probationPeriod) {
+  //       const probationEndDate = dayjs(row.contractStartTime).add(row.probationPeriod, 'month');
+  //       const daysUntilProbationEnd = probationEndDate.diff(dayjs(), 'day');
+        
+  //       if (daysUntilProbationEnd >= 0 && daysUntilProbationEnd <= 7) {
+  //         return 'warning'; // 浣跨敤璀﹀憡鏍峰紡鏍囪涓磋繎杞鐨勫憳宸�
+  //       }
+  //     }
+  //     return '';
+  //   }
+  // },
+  {
+    label: "鍚堝悓骞撮檺锛堝勾锛�",
     prop: "contractTerm",
+    width: 120,
   },
   {
     label: "鍚堝悓寮�濮嬫棩鏈�",
@@ -222,10 +253,43 @@
     tableLoading.value = false;
     tableData.value = res.data.records
     page.total = res.data.total;
+
+    // 妫�鏌ユ槸鍚︽湁涓磋繎杞鐨勫憳宸ュ苟鎻愰啋
+    checkProbationEnding(tableData.value);
   }).catch(err => {
     tableLoading.value = false;
   })
 };
+// 妫�鏌ヤ复杩戣浆姝g殑鍛樺伐骞舵彁閱�
+const checkProbationEnding = (data) => {
+  const probationEndingSoon = [];
+  
+  data.forEach(item => {
+    // 淇敼涓轰娇鐢ㄥ悎鍚屽紑濮嬫棩鏈熸鏌�
+    if (item.contractStartTime && item.probationPeriod) {
+      const probationEndDate = dayjs(item.contractStartTime).add(item.probationPeriod, 'month');
+      const daysUntilProbationEnd = probationEndDate.diff(dayjs(), 'day');
+      
+      if (daysUntilProbationEnd >= 0 && daysUntilProbationEnd <= 7) {
+        probationEndingSoon.push({
+          staffName: item.staffName,
+          probationEndDate: probationEndDate.format('YYYY-MM-DD'),
+          daysLeft: daysUntilProbationEnd
+        });
+      }
+    }
+  });
+  
+  if (probationEndingSoon.length > 0) {
+    let message = '浠ヤ笅鍛樺伐灏嗗湪7澶╁唴杞锛歕n';
+    probationEndingSoon.forEach(item => {
+      message += `${item.staffName}锛�${item.probationEndDate}锛岃繕鏈�${item.daysLeft}澶╋級\n`;
+    });
+    
+    // 鏄剧ず鎻愰啋娑堟伅
+    proxy.$modal.msgInfo(message);
+  }
+};
 // 琛ㄦ牸閫夋嫨鏁版嵁
 const handleSelectionChange = (selection) => {
   selectedRows.value = selection;
diff --git a/src/views/procurementManagement/invoiceEntry/index.vue b/src/views/procurementManagement/invoiceEntry/index.vue
index 256377f..4b25c38 100644
--- a/src/views/procurementManagement/invoiceEntry/index.vue
+++ b/src/views/procurementManagement/invoiceEntry/index.vue
@@ -165,7 +165,7 @@
       },
     },
     {
-      label: "宸插紑绁ㄩ噾棰�(鍏�)",
+      label: "宸叉潵绁ㄩ噾棰�(鍏�)",
       prop: "receiptPaymentAmount",
       width:200,
       formatData: (val) => {
@@ -173,7 +173,7 @@
       },
     },
     {
-      label: "寰呭紑绁ㄩ噾棰�(鍏�)",
+      label: "寰呮潵绁ㄩ噾棰�(鍏�)",
       prop: "unReceiptPaymentAmount",
       width:200,
       formatData: (val) => {
diff --git a/src/views/procurementManagement/invoiceEntry/indexOld.vue b/src/views/procurementManagement/invoiceEntry/indexOld.vue
index 1b4c6b9..52fe222 100644
--- a/src/views/procurementManagement/invoiceEntry/indexOld.vue
+++ b/src/views/procurementManagement/invoiceEntry/indexOld.vue
@@ -37,6 +37,7 @@
         :summary-method="summarizeMainTable"
         @expand-change="expandChange"
         height="calc(100vh - 18.5em)"
+        stripe
       >
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column type="expand">
@@ -46,6 +47,7 @@
               border
               show-summary
               :summary-method="summarizeChildrenTable"
+              stripe
             >
               <el-table-column
                 align="center"
@@ -278,6 +280,7 @@
           :data="productData"
           border
           @selection-change="productSelected"
+          stripe
           show-summary
           style="width: 100%"
           :summary-method="summarizeChildrenTable"
diff --git a/src/views/procurementManagement/paymentEntry/index.vue b/src/views/procurementManagement/paymentEntry/index.vue
index 107ee30..3ce2a8d 100644
--- a/src/views/procurementManagement/paymentEntry/index.vue
+++ b/src/views/procurementManagement/paymentEntry/index.vue
@@ -61,6 +61,7 @@
 						show-summary
 						v-loading="childrenLoading"
 						:summary-method="summarizeMainTable2"
+						stripe
 					>
 						<el-table-column
 							align="center"
@@ -221,31 +222,31 @@
               </el-select>
             </el-form-item>
           </el-col>
-          <el-col :span="12">
-            <el-form-item label="鐧昏浜猴細" prop="registrant">
-              <el-input
-                v-model="form.registrant"
-                placeholder="璇疯緭鍏�"
-                clearable
-                disabled
-              />
-            </el-form-item>
-          </el-col>
+					<el-col :span="12">
+						<el-form-item label="浠樻鏃ユ湡锛�" prop="paymentDate">
+							<el-date-picker
+								style="width: 100%"
+								v-model="form.paymentDate"
+								value-format="YYYY-MM-DD"
+								format="YYYY-MM-DD"
+								type="date"
+								placeholder="璇烽�夋嫨"
+								clearable
+							/>
+						</el-form-item>
+					</el-col>
         </el-row>
         <el-row :gutter="30">
-          <el-col :span="12">
-            <el-form-item label="浠樻鏃ユ湡锛�" prop="paymentDate">
-              <el-date-picker
-                style="width: 100%"
-                v-model="form.paymentDate"
-                value-format="YYYY-MM-DD"
-                format="YYYY-MM-DD"
-                type="date"
-                placeholder="璇烽�夋嫨"
-                clearable
-              />
-            </el-form-item>
-          </el-col>
+					<el-col :span="12">
+						<el-form-item label="鐧昏浜猴細" prop="registrant">
+							<el-input
+								v-model="form.registrant"
+								placeholder="璇疯緭鍏�"
+								clearable
+								disabled
+							/>
+						</el-form-item>
+					</el-col>
           <el-col :span="12">
             <el-form-item label="鐧昏鏃ユ湡锛�" prop="registrationtDate">
               <el-input
diff --git a/src/views/procurementManagement/paymentHistory/index.vue b/src/views/procurementManagement/paymentHistory/index.vue
index 714c670..7c71979 100644
--- a/src/views/procurementManagement/paymentHistory/index.vue
+++ b/src/views/procurementManagement/paymentHistory/index.vue
@@ -63,6 +63,10 @@
 const isShowSummarySon = ref(true);
 const tableColumn = ref([
   {
+    label: "閲囪喘鍚堝悓鍙�",
+    prop: "purchaseContractNumber",
+  },
+  {
     label: "浠樻鏃ユ湡",
     prop: "paymentDate",
   },
diff --git a/src/views/procurementManagement/paymentLedger/index.vue b/src/views/procurementManagement/paymentLedger/index.vue
index 741e6ac..2f001a5 100644
--- a/src/views/procurementManagement/paymentLedger/index.vue
+++ b/src/views/procurementManagement/paymentLedger/index.vue
@@ -29,6 +29,7 @@
             height="calc(100vh - 18.5em)"
             :highlight-current-row="true"
             style="width: 100%"
+            stripe
             tooltip-effect="dark"
             @row-click="rowClick"
             :show-summary="isShowSummary"
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue b/src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue
index 77789c4..f939be4 100644
--- a/src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue
+++ b/src/views/procurementManagement/procurementInvoiceLedger/Form/EditForm.vue
@@ -53,7 +53,7 @@
 defineOptions({
   name: "鏉ョエ鍙拌处琛ㄥ崟",
 });
-
+const temFutureTickets = ref(0)
 const { form, resetForm } = useFormData({
   id: undefined,
   purchaseContractNumber: undefined, // 閲囪喘鍚堝悓鍙�
@@ -77,6 +77,7 @@
     form.ticketsAmount = data.ticketsAmount.toFixed(2);
     form.taxInclusiveUnitPrice = data.taxInclusiveUnitPrice;
     form.futureTickets = data.futureTickets;
+    temFutureTickets.value = data.futureTickets;
   }
 };
 
@@ -86,16 +87,14 @@
 		proxy.$modal.msgWarning("鍚◣鍗曚环涓嶈兘涓洪浂鎴栨湭瀹氫箟");
 		return;
 	}
-	
-	if (Number(form.ticketsNum) > Number(form.futureTickets)) {
+	if (Number(form.ticketsNum) > Number(temFutureTickets.value)) {
 		proxy.$modal.msgWarning("寮�绁ㄦ暟涓嶅緱澶т簬鏈紑绁ㄦ暟");
-		form.ticketsNum = form.futureTickets
-		return;
+		form.ticketsNum = temFutureTickets.value
 	}
 	
 	// 纭繚鎵�鏈夋暟鍊奸兘杞崲涓烘暟瀛楃被鍨嬭繘琛岃绠�
-	const ticketsAmount = Number(val) * Number(form.taxInclusiveUnitPrice);
-	const futureTickets = Number(form.futureTickets) - Number(val);
+	const ticketsAmount = Number(form.ticketsNum) * Number(form.taxInclusiveUnitPrice);
+	const futureTickets = Number(temFutureTickets.value) - Number(form.ticketsNum);
 	form.futureTickets = Number(futureTickets.toFixed(2));
 	form.ticketsAmount = Number(ticketsAmount.toFixed(2));
 };
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/index.vue b/src/views/procurementManagement/procurementInvoiceLedger/index.vue
index 255f3ac..8ad8799 100644
--- a/src/views/procurementManagement/procurementInvoiceLedger/index.vue
+++ b/src/views/procurementManagement/procurementInvoiceLedger/index.vue
@@ -162,14 +162,19 @@
       width: 150,
     },
     {
-      label: "瀹㈡埛鍚嶇О",
-      prop: "customerName",
+      label: "椤圭洰鍚嶇О",
+      prop: "projectName",
       width: 240,
     },
     {
       label: "渚涘簲鍟嗗悕绉�",
       prop: "supplierName",
       width: 240,
+    },
+    {
+      label: "浜у搧澶х被",
+      prop: "productCategory",
+      width: 150,
     },
     {
       label: "瑙勬牸鍨嬪彿",
@@ -190,12 +195,17 @@
       },
     },
     {
-      label: "寮�绁ㄦ棩鏈�",
+      label: "鏈鏉ョエ鏁�",
+      prop: "ticketsNum",
+      width: 110,
+    },
+    {
+      label: "鏉ョエ鏃ユ湡",
       prop: "createdAt",
       width: 110,
     },
     {
-      label: "寮�绁ㄩ噾棰�",
+      label: "鏉ョエ閲戦(鍏�)",
       prop: "ticketsAmount",
       width: 200,
       formatData: (cell) => {
diff --git a/src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue b/src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue
index 987e6a4..af38ab1 100644
--- a/src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue
+++ b/src/views/procurementManagement/procurementInvoiceLedger/indexOld.vue
@@ -52,6 +52,7 @@
         :summary-method="summarizeMainTable"
         @expand-change="expandChange"
         height="calc(100vh - 18.5em)"
+        stripe
       >
         <el-table-column align="center" label="搴忓彿" type="index" width="55" />
         <el-table-column type="expand">
@@ -61,6 +62,7 @@
               border
               show-summary
               :summary-method="summarizeChildrenTable"
+              stripe
             >
               <el-table-column
                 align="center"
diff --git a/src/views/procurementManagement/procurementLedger/index.vue b/src/views/procurementManagement/procurementLedger/index.vue
index b403fd1..4fbf775 100644
--- a/src/views/procurementManagement/procurementLedger/index.vue
+++ b/src/views/procurementManagement/procurementLedger/index.vue
@@ -39,6 +39,7 @@
     <div class="table_list">
       <div style="display: flex;justify-content: flex-end;margin-bottom: 20px;">
         <el-button type="primary" @click="openForm('add')">鏂板鍙拌处</el-button>
+        <el-button type="success" @click="openScanAddDialog">鎵爜鏂板</el-button>
         <el-button @click="handleOut">瀵煎嚭</el-button>
         <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
       </div>
@@ -53,6 +54,7 @@
         :summary-method="summarizeMainTable"
         @expand-change="expandChange"
         height="calc(100vh - 18.5em)"
+        stripe
       >
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column type="expand">
@@ -62,6 +64,7 @@
               border
               show-summary
               :summary-method="summarizeChildrenTable"
+              stripe
             >
               <el-table-column
                 align="center"
@@ -145,7 +148,7 @@
         <el-table-column
           fixed="right"
           label="鎿嶄綔"
-          min-width="60"
+          min-width="150"
           align="center"
         >
           <template #default="scope">
@@ -157,6 +160,14 @@
 							:disabled="scope.row.receiptPaymentAmount>0 || scope.row.recorderName !== userStore.nickName"
               >缂栬緫</el-button
             >
+            <el-button
+              link
+              type="success"
+              size="small"
+              @click="showQRCode(scope.row)"
+              >鐢熸垚浜岀淮鐮�</el-button
+            >
+
           </template>
         </el-table-column>
       </el-table>
@@ -296,6 +307,7 @@
           border
           @selection-change="productSelected"
           show-summary
+          stripe
           :summary-method="summarizeProTable"
         >
           <el-table-column align="center" type="selection" width="55" />
@@ -539,13 +551,228 @@
         </div>
       </template>
     </el-dialog>
+    
+    <!-- 浜岀淮鐮佹樉绀哄璇濇 -->
+    <el-dialog
+      v-model="qrCodeDialogVisible"
+      title="閲囪喘鍚堝悓鍙蜂簩缁寸爜"
+      width="400px"
+      center
+    >
+      <div style="text-align: center;">
+        <img :src="qrCodeUrl" alt="浜岀淮鐮�" style="width:200px;height:200px;" />
+        <div style="margin: 20px;">
+          <el-button type="primary" @click="downloadQRCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
+        </div>
+      </div>
+    </el-dialog>
+
+    <!-- 鎵爜鏂板瀵硅瘽妗� -->
+    <el-dialog
+      v-model="scanAddDialogVisible"
+      title="鎵爜鏂板閲囪喘鍙拌处"
+      width="70%"
+      @close="closeScanAddDialog"
+    >
+      <el-form
+        :model="scanAddForm"
+        label-width="140px"
+        label-position="top"
+        :rules="scanAddRules"
+        ref="scanAddFormRef"
+      >
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="鎵爜鍐呭锛�">
+              <el-input
+                v-model="scanAddForm.scanContent"
+                type="textarea"
+                :rows="3"
+                placeholder="璇锋壂鎻忎簩缁寸爜鎴栨墜鍔ㄨ緭鍏ラ噰璐悎鍚屼俊鎭�"
+                @input="parseScanContent"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細" prop="purchaseContractNumber">
+              <el-input
+                v-model="scanAddForm.purchaseContractNumber"
+                placeholder="璇疯緭鍏�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="渚涘簲鍟嗗悕绉帮細" prop="supplierName">
+              <el-input
+                v-model="scanAddForm.supplierName"
+                placeholder="璇疯緭鍏�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="椤圭洰鍚嶇О锛�" prop="projectName">
+              <el-input
+                v-model="scanAddForm.projectName"
+                placeholder="璇疯緭鍏�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鍚堝悓閲戦(鍏�)锛�" prop="contractAmount">
+              <el-input-number
+                v-model="scanAddForm.contractAmount"
+                :precision="2"
+                :step="0.1"
+                clearable
+                style="width: 100%"
+                placeholder="璇疯緭鍏�"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="浠樻鏂瑰紡锛�">
+              <el-input
+                v-model="scanAddForm.paymentMethod"
+                placeholder="璇疯緭鍏�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="褰曞叆浜猴細">
+              <el-input v-model="scanAddForm.recorderName" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="澶囨敞锛�">
+              <el-input
+                v-model="scanAddForm.remark"
+                type="textarea"
+                :rows="2"
+                placeholder="璇疯緭鍏ュ娉ㄤ俊鎭�"
+                clearable
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitScanAdd">纭鏂板</el-button>
+          <el-button @click="closeScanAddDialog">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
+    <!-- 鎵爜鐧昏瀵硅瘽妗� -->
+    <el-dialog
+      v-model="scanDialogVisible"
+      title="鎵爜鐧昏"
+      width="60%"
+      @close="closeScanDialog"
+    >
+      <el-form
+        :model="scanForm"
+        label-width="120px"
+        label-position="left"
+        :rules="scanRules"
+        ref="scanFormRef"
+      >
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="閲囪喘鍚堝悓鍙凤細">
+              <el-input v-model="scanForm.purchaseContractNumber" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="渚涘簲鍟嗗悕绉帮細">
+              <el-input v-model="scanForm.supplierName" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="椤圭洰鍚嶇О锛�">
+              <el-input v-model="scanForm.projectName" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎵爜鏃堕棿锛�">
+              <el-input v-model="scanForm.scanTime" disabled />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="12">
+            <el-form-item label="鎵爜浜猴細">
+              <el-input v-model="scanForm.scannerName" disabled />
+            </el-form-item>
+          </el-col>
+          <el-col :span="12">
+            <el-form-item label="鎵爜鐘舵�侊細">
+              <el-tag :type="scanForm.scanStatus === '宸叉壂鐮�' ? 'success' : 'warning'">
+                {{ scanForm.scanStatus }}
+              </el-tag>
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="鎵爜澶囨敞锛�">
+              <el-input
+                v-model="scanForm.scanRemark"
+                type="textarea"
+                :rows="3"
+                placeholder="璇疯緭鍏ユ壂鐮佸娉ㄤ俊鎭�"
+              />
+            </el-form-item>
+          </el-col>
+        </el-row>
+        <el-row :gutter="20">
+          <el-col :span="24">
+            <el-form-item label="鎵爜璁板綍锛�">
+              <el-table :data="scanRecords" border style="width: 100%" stripe>
+                <el-table-column label="搴忓彿" type="index" width="60" align="center" />
+                <el-table-column label="鎵爜鏃堕棿" prop="scanTime" width="180" />
+                <el-table-column label="鎵爜浜�" prop="scannerName" width="120" />
+                <el-table-column label="鎵爜鐘舵��" prop="scanStatus" width="100">
+                  <template #default="scope">
+                    <el-tag :type="scope.row.scanStatus === '宸叉壂鐮�' ? 'success' : 'warning'">
+                      {{ scope.row.scanStatus }}
+                    </el-tag>
+                  </template>
+                </el-table-column>
+                <el-table-column label="澶囨敞" prop="scanRemark" />
+              </el-table>
+            </el-form-item>
+          </el-col>
+        </el-row>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitScan">纭鎵爜</el-button>
+          <el-button @click="closeScanDialog">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
   </div>
 </template>
 
 <script setup>
 import { getToken } from "@/utils/auth";
 import pagination from "@/components/PIMTable/Pagination.vue";
-import { ref, onMounted } from "vue";
+import { ref, onMounted, reactive, toRefs, getCurrentInstance, nextTick } from "vue";
 import { Search } from "@element-plus/icons-vue";
 import { ElMessageBox } from "element-plus";
 import { userListNoPage } from "@/api/system/user.js";
@@ -567,6 +794,7 @@
   createPurchaseNo,
 } from "@/api/procurementManagement/procurementLedger.js";
 import useFormData from "@/hooks/useFormData.js";
+import QRCode from "qrcode";
 const { proxy } = getCurrentInstance();
 const tableData = ref([]);
 const productData = ref([]);
@@ -589,6 +817,10 @@
 import dayjs from "dayjs";
 
 const userStore = useUserStore();
+
+// 浜岀淮鐮佺浉鍏冲彉閲�
+const qrCodeDialogVisible = ref(false);
+const qrCodeUrl = ref("");
 
 // 鐢ㄦ埛淇℃伅琛ㄥ崟寮规鏁版嵁
 const operationType = ref("");
@@ -812,8 +1044,8 @@
 // 涓婁紶鍓嶆牎妫�
 function handleBeforeUpload(file) {
   // 鏍℃鏂囦欢澶у皬
-  if (file.size > 1024 * 1024 * 10) {
-    proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
+  if (file.size > 1024 * 1024 * 50) {
+    proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃50MB!");
     return false;
   }
   proxy.$modal.loading("姝e湪涓婁紶鏂囦欢锛岃绋嶅��...");
@@ -1152,6 +1384,194 @@
   }
 };
 
+// 鏄剧ず浜岀淮鐮�
+const showQRCode = async (row) => {
+  try {
+    // 鏋勫缓浜岀淮鐮佸唴瀹癸紝鍙寘鍚噰璐悎鍚屽彿锛堢函鏂囨湰锛�
+    const qrContent = row.purchaseContractNumber || '';
+    // 妫�鏌ュ唴瀹规槸鍚︿负绌�
+    if (!qrContent || qrContent.trim() === '') {
+      proxy.$modal.msgWarning("璇ヨ娌℃湁閲囪喘鍚堝悓鍙凤紝鏃犳硶鐢熸垚浜岀淮鐮�");
+      return;
+    }
+    qrCodeUrl.value = await QRCode.toDataURL(qrContent, {
+      width: 200,
+      margin: 2,
+      color: {
+        dark: '#000000',
+        light: '#FFFFFF'
+      }
+    });
+    qrCodeDialogVisible.value = true;
+  } catch (error) {
+    console.error('鐢熸垚浜岀淮鐮佸け璐�:', error);
+    proxy.$modal.msgError("鐢熸垚浜岀淮鐮佸け璐ワ細" + error.message);
+  }
+};
+
+// 涓嬭浇浜岀淮鐮�
+const downloadQRCode = () => {
+  if (!qrCodeUrl.value) {
+    proxy.$modal.msgWarning("浜岀淮鐮佹湭鐢熸垚");
+    return;
+  }
+  
+  const a = document.createElement('a');
+  a.href = qrCodeUrl.value;
+  a.download = `閲囪喘鍚堝悓鍙蜂簩缁寸爜_${new Date().getTime()}.png`;
+  document.body.appendChild(a);
+  a.click();
+  document.body.removeChild(a);
+  proxy.$modal.msgSuccess("涓嬭浇鎴愬姛");
+};
+
+// 鎵爜鏂板瀵硅瘽妗嗙浉鍏冲彉閲�
+const scanAddDialogVisible = ref(false);
+const scanAddForm = reactive({
+  scanContent: "",
+  purchaseContractNumber: "",
+  supplierName: "",
+  projectName: "",
+  contractAmount: "",
+  paymentMethod: "",
+  recorderName: "",
+  scanRemark: "",
+});
+const scanAddRules = {
+  purchaseContractNumber: [{ required: true, message: "璇疯緭鍏ラ噰璐悎鍚屽彿", trigger: "blur" }],
+  supplierName: [{ required: true, message: "璇疯緭鍏ヤ緵搴斿晢鍚嶇О", trigger: "blur" }],
+  projectName: [{ required: true, message: "璇疯緭鍏ラ」鐩悕绉�", trigger: "blur" }],
+};
+
+// 鎵爜鐧昏瀵硅瘽妗嗙浉鍏冲彉閲�
+const scanDialogVisible = ref(false);
+const scanForm = reactive({
+  purchaseContractNumber: "",
+  supplierName: "",
+  projectName: "",
+  scanTime: "",
+  scannerName: "",
+  scanStatus: "鏈壂鐮�",
+  scanRemark: "",
+});
+const scanRules = {
+  scanRemark: [{ required: true, message: "璇疯緭鍏ユ壂鐮佸娉�", trigger: "blur" }],
+};
+const scanRecords = ref([]);
+
+// 鎵撳紑鎵爜鏂板瀵硅瘽妗�
+const openScanAddDialog = () => {
+  scanAddForm.scanContent = "";
+  scanAddForm.purchaseContractNumber = "";
+  scanAddForm.supplierName = "";
+  scanAddForm.projectName = "";
+  scanAddForm.contractAmount = "";
+  scanAddForm.paymentMethod = "";
+  scanAddForm.recorderName = userStore.nickName;
+  scanAddForm.scanRemark = "";
+  scanAddDialogVisible.value = true;
+};
+
+// 瑙f瀽鎵爜鍐呭锛堟ā鎷熻В鏋愪簩缁寸爜鏁版嵁锛�
+const parseScanContent = (content) => {
+  if (!content) return;
+  
+  // 妯℃嫙瑙f瀽浜岀淮鐮佸唴瀹癸紝杩欓噷鍙互鏍规嵁瀹為檯闇�姹傝皟鏁磋В鏋愰�昏緫
+  // 鍋囪鎵爜鍐呭鏍煎紡涓猴細鍚堝悓鍙穦渚涘簲鍟唡椤圭洰|閲戦|浠樻鏂瑰紡
+  const parts = content.split('|');
+  if (parts.length >= 3) {
+    scanAddForm.purchaseContractNumber = parts[0] || "";
+    scanAddForm.supplierName = parts[1] || "";
+    scanAddForm.projectName = parts[2] || "";
+    scanAddForm.contractAmount = parts[3] || "";
+    scanAddForm.paymentMethod = parts[4] || "";
+  }
+};
+
+// 鍏抽棴鎵爜鏂板瀵硅瘽妗�
+const closeScanAddDialog = () => {
+  scanAddDialogVisible.value = false;
+  proxy.resetForm("scanAddFormRef");
+};
+
+// 鎻愪氦鎵爜鏂板
+const submitScanAdd = () => {
+  proxy.$refs["scanAddFormRef"].validate((valid) => {
+    if (valid) {
+      // 鏋勫缓鏂板鏁版嵁
+      const newData = {
+        purchaseContractNumber: scanAddForm.purchaseContractNumber,
+        supplierName: scanAddForm.supplierName,
+        projectName: scanAddForm.projectName,
+        contractAmount: scanAddForm.contractAmount,
+        paymentMethod: scanAddForm.paymentMethod,
+        recorderName: scanAddForm.recorderName,
+        entryDate: getCurrentDate(),
+        remark: scanAddForm.scanRemark,
+        type: 2
+      };
+      
+      // 妯℃嫙鏂板鎴愬姛
+      proxy.$modal.msgSuccess("鎵爜鏂板鎴愬姛锛�");
+      closeScanAddDialog();
+      
+      // 鍙互閫夋嫨鏄惁鍒锋柊鍒楄〃
+      // getList();
+    }
+  });
+};
+
+// 鎵撳紑鎵爜鐧昏瀵硅瘽妗�
+const openScanDialog = (row) => {
+  scanForm.purchaseContractNumber = row.purchaseContractNumber;
+  scanForm.supplierName = row.supplierName;
+  scanForm.projectName = row.projectName;
+  scanForm.scanTime = getCurrentDateTime();
+  scanForm.scannerName = userStore.nickName;
+  scanForm.scanStatus = "鏈壂鐮�";
+  scanForm.scanRemark = "";
+  scanRecords.value = [];
+  scanDialogVisible.value = true;
+};
+
+// 鍏抽棴鎵爜鐧昏瀵硅瘽妗�
+const closeScanDialog = () => {
+  scanDialogVisible.value = false;
+  proxy.resetForm("scanFormRef");
+};
+
+// 鎻愪氦鎵爜鐧昏
+const submitScan = () => {
+  proxy.$refs["scanFormRef"].validate((valid) => {
+    if (valid) {
+      // 娣诲姞鎵爜璁板綍
+      scanRecords.value.push({
+        ...scanForm,
+        id: Date.now(), // 妯℃嫙ID
+        scanTime: getCurrentDateTime(),
+      });
+      scanForm.scanStatus = "宸叉壂鐮�";
+      scanForm.scanRemark = scanForm.scanRemark || "鏃�";
+      proxy.$modal.msgSuccess("鎵爜鐧昏鎴愬姛锛�");
+      closeScanDialog();
+    }
+  });
+};
+
+// 鑾峰彇褰撳墠鏃ユ湡鏃堕棿
+function getCurrentDateTime() {
+  const now = new Date();
+  const year = now.getFullYear();
+  const month = String(now.getMonth() + 1).padStart(2, "0");
+  const day = String(now.getDate()).padStart(2, "0");
+  const hours = String(now.getHours()).padStart(2, "0");
+  const minutes = String(now.getMinutes()).padStart(2, "0");
+  const seconds = String(now.getSeconds()).padStart(2, "0");
+  return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`;
+}
+
+
+
 onMounted(() => {
   getList();
 });
diff --git a/src/views/productionManagement/operationScheduling/components/formDia.vue b/src/views/productionManagement/operationScheduling/components/formDia.vue
index ad37c4b..b8d1428 100644
--- a/src/views/productionManagement/operationScheduling/components/formDia.vue
+++ b/src/views/productionManagement/operationScheduling/components/formDia.vue
@@ -8,7 +8,7 @@
     >
       <el-button type="primary" @click="addRow" style="margin-bottom: 10px;">鏂板</el-button>
 			<span style="font-size: 18px;margin-left: 10px">寰呮帓浜ф暟閲忥細{{pendingNum}}</span>
-      <el-table :data="tableData" border style="width: 100%" :summary-method="summarizeMainTable" show-summary :row-key="row => row.id">
+      <el-table :data="tableData" border style="width: 100%" :summary-method="summarizeMainTable" show-summary :row-key="row => row.id" stripe>
         <el-table-column label="搴忓彿" width="60">
           <template #default="scope">
             {{ scope.$index + 1 }}
diff --git a/src/views/productionManagement/productionReporting/index.vue b/src/views/productionManagement/productionReporting/index.vue
index 3ceae74..bcb2d5d 100644
--- a/src/views/productionManagement/productionReporting/index.vue
+++ b/src/views/productionManagement/productionReporting/index.vue
@@ -50,6 +50,7 @@
 						:data="expandData"
 						border
 						show-summary
+						stripe
 						:summary-method="summarizeMainTable"
 						v-loading="childrenLoading"
 					>
diff --git a/src/views/productionManagement/safetyMonitoring/index.vue b/src/views/productionManagement/safetyMonitoring/index.vue
new file mode 100644
index 0000000..56f65e7
--- /dev/null
+++ b/src/views/productionManagement/safetyMonitoring/index.vue
@@ -0,0 +1,873 @@
+<template>
+	<div class="safety-monitoring">
+		<el-row :gutter="20">
+			<!-- 宸︿晶锛氬疄鏃剁洃鎺у尯鍩� -->
+			<el-col :span="16">
+				<el-card class="monitoring-card">
+					<div slot="header" class="card-header">
+						<span>瀹炴椂姘斾綋娴撳害鐩戞帶</span>
+						<el-tag :type="systemStatus === 'normal' ? 'success' : 'danger'">
+							{{ systemStatus === 'normal' ? '绯荤粺姝e父' : '绯荤粺鍛婅' }}
+						</el-tag>
+					</div>
+					
+					<!-- 鍌ㄧ綈鍖虹洃鎺� -->
+					<div class="monitoring-section">
+						<h3>鍌ㄧ綈鍖虹洃鎺�</h3>
+						<div class="sensor-grid">
+							<div class="sensor-item" v-for="sensor in tankSensors" :key="sensor.id">
+								<div class="sensor-header">
+									<span>{{ sensor.name }}</span>
+									<el-tag :type="sensor.status === 'normal' ? 'success' : 'danger'" size="small">
+										{{ sensor.status === 'normal' ? '姝e父' : '瓒呮爣' }}
+									</el-tag>
+								</div>
+								<div class="sensor-data">
+									<div class="data-item">
+										<span>鐢茬兎: {{ sensor.methane.toFixed(2) }}%</span>
+										<el-progress
+											:percentage="Math.min(Math.round(sensor.methane * 40 * 100) / 100, 100)"
+											:color="getProgressColor(Math.min(Math.round(sensor.methane * 40 * 100) / 100, 100), 80)"
+											:format="formatProgress"
+											:stroke-width="8"
+										/>
+									</div>
+									<div class="data-item">
+										<span>纭寲姘�: {{ sensor.h2s.toFixed(2) }}ppm</span>
+										<el-progress
+											:percentage="Math.min(Math.round((sensor.h2s / 20) * 100 * 100) / 100, 100)"
+											:color="getProgressColor(Math.min(Math.round((sensor.h2s / 20) * 100 * 100) / 100, 100), 80)"
+											:format="formatProgress"
+											:stroke-width="8"
+										/>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+					
+					<!-- 浜曞彛鍘嬬缉鏈虹洃鎺� -->
+					<div class="monitoring-section">
+						<h3>浜曞彛鍘嬬缉鏈虹洃鎺�</h3>
+						<div class="sensor-grid">
+							<div class="sensor-item" v-for="sensor in compressorSensors" :key="sensor.id">
+								<div class="sensor-header">
+									<span>{{ sensor.name }}</span>
+									<el-tag :type="sensor.status === 'normal' ? 'success' : 'danger'" size="small">
+										{{ sensor.status === 'normal' ? '姝e父' : '瓒呮爣' }}
+									</el-tag>
+								</div>
+								<div class="sensor-data">
+									<div class="data-item">
+										<span>鐢茬兎: {{ sensor.methane.toFixed(2) }}%</span>
+										<el-progress
+											:percentage="Math.min(Math.round(sensor.methane * 40 * 100) / 100, 100)"
+											:color="getProgressColor(sensor.methane, 2.5)"
+											:format="formatProgress"
+											:stroke-width="8"
+										/>
+									</div>
+									<div class="data-item">
+										<span>纭寲姘�: {{ sensor.h2s.toFixed(2) }}ppm</span>
+										<el-progress
+											:percentage="Math.min(Math.round((sensor.h2s / 20) * 100 * 100) / 100, 100)"
+											:color="getProgressColor(sensor.h2s, 10)"
+											:format="formatProgress"
+											:stroke-width="8"
+										/>
+									</div>
+								</div>
+							</div>
+						</div>
+					</div>
+					
+					<!-- 瀹炴椂鏇茬嚎鍥� -->
+					<div class="chart-section">
+						<h3>瀹炴椂娴撳害鏇茬嚎</h3>
+						<div class="chart-container">
+							<div ref="chart" class="chart"></div>
+						</div>
+					</div>
+				</el-card>
+			</el-col>
+			
+			<!-- 鍙充晶锛氭帶鍒堕潰鏉� -->
+			<el-col :span="8">
+				<el-card class="control-card">
+					<div slot="header" class="card-header">
+						<span>搴旀�ユ帶鍒堕潰鏉�</span>
+					</div>
+					
+					<!-- 鍠锋穻鐘舵�� -->
+					<div class="control-section">
+						<h4>鍠锋穻绯荤粺鐘舵��</h4>
+						<div class="status-grid">
+							<div class="status-item" v-for="sprinkler in sprinklerSystems" :key="sprinkler.id">
+								<div class="status-indicator" :class="sprinkler.status">
+									<i class="el-icon-circle-check" v-if="sprinkler.status === 'active'"></i>
+									<i class="el-icon-circle-close" v-else></i>
+								</div>
+								<span>{{ sprinkler.name }}</span>
+								<el-tag :type="sprinkler.status === 'active' ? 'success' : 'info'" size="small">
+									{{ sprinkler.status === 'active' ? '杩愯涓�' : '寰呮満' }}
+								</el-tag>
+							</div>
+						</div>
+					</div>
+					
+					<!-- 搴旀�ヨ褰曟寜閽� -->
+					<h4>搴旀�ョ鐞�</h4>
+					
+					<div class="control-section1">
+						<el-button type="primary" @click="showEmergencyRecords" style="margin-bottom: 10px;">
+							搴旀�ヨ褰�
+						</el-button>
+						<el-button type="warning" @click="triggerEmergency" :disabled="!hasEmergency">
+							瑙﹀彂搴旀�ュ搷搴�
+						</el-button>
+					</div>
+					
+					<!-- 绯荤粺鏃ュ織 -->
+					<div class="control-section">
+						<h4>绯荤粺鏃ュ織</h4>
+						<div class="log-container">
+							<div class="log-item" v-for="log in systemLogs" :key="log.id">
+								<span class="log-time">{{ log.time }}</span>
+								<span class="log-content">{{ log.content }}</span>
+							</div>
+						</div>
+					</div>
+				</el-card>
+			</el-col>
+		</el-row>
+		
+		<!-- 娉勬紡棰勮寮圭獥 -->
+		<el-dialog
+			title="鈿狅笍 娉勬紡棰勮"
+			:visible.sync="leakWarningVisible"
+			width="500px"
+			:close-on-click-modal="false"
+			:close-on-press-escape="false"
+			class="leak-warning-dialog"
+		>
+			<div class="warning-content">
+				<div class="warning-icon">
+					<i class="el-icon-warning"></i>
+				</div>
+				<div class="warning-text">
+					<h3>妫�娴嬪埌姘斾綋娴撳害瓒呮爣锛�</h3>
+					<p>浣嶇疆锛歿{ currentWarning.location }}</p>
+					<p>瓒呮爣姘斾綋锛歿{ currentWarning.gas }}</p>
+					<p>褰撳墠娴撳害锛歿{ currentWarning.value }}</p>
+				</div>
+			</div>
+			<div slot="footer" class="dialog-footer">
+				<el-button type="danger" @click="acknowledgeWarning">纭鍛婅</el-button>
+				<el-button type="primary" @click="viewDetails">鏌ョ湅璇︽儏</el-button>
+			</div>
+		</el-dialog>
+		
+		<!-- 搴旀�ヨ褰曞脊绐� -->
+		<el-dialog
+			title="搴旀�ヨ褰�"
+			:visible.sync="emergencyRecordsVisible"
+			width="800px"
+		>
+			<el-table :data="emergencyRecords" style="width: 100%" stripe>
+				<el-table-column prop="time" label="鏃堕棿" width="180"></el-table-column>
+				<el-table-column prop="location" label="浣嶇疆" width="150"></el-table-column>
+				<el-table-column prop="type" label="绫诲瀷" width="120"></el-table-column>
+				<el-table-column prop="status" label="鐘舵��" width="100">
+					<template slot-scope="scope">
+						<el-tag :type="scope.row.status === 'resolved' ? 'success' : 'warning'">
+							{{ scope.row.status === 'resolved' ? '宸茶В鍐�' : '澶勭悊涓�' }}
+						</el-tag>
+					</template>
+				</el-table-column>
+				<el-table-column prop="description" label="鎻忚堪"></el-table-column>
+				<el-table-column label="鎿嶄綔" width="120">
+					<template slot-scope="scope">
+						<el-button type="text" @click="viewBlockchainDetails(scope.row)">
+							鍖哄潡閾捐鎯�
+						</el-button>
+					</template>
+				</el-table-column>
+			</el-table>
+		</el-dialog>
+		
+		<!-- 鍖哄潡閾惧瓨璇佽鎯呭脊绐� -->
+		<el-dialog
+			title="鍖哄潡閾惧瓨璇佽鎯�"
+			:visible.sync="blockchainDetailsVisible"
+			width="900px"
+		>
+			<div class="blockchain-details">
+				<el-descriptions :column="2" border>
+					<el-descriptions-item label="浜嬩欢ID">{{ currentEvent.id }}</el-descriptions-item>
+					<el-descriptions-item label="鏃堕棿鎴�">{{ currentEvent.timestamp }}</el-descriptions-item>
+					<el-descriptions-item label="浣嶇疆">{{ currentEvent.location }}</el-descriptions-item>
+					<el-descriptions-item label="浜嬩欢绫诲瀷">{{ currentEvent.type }}</el-descriptions-item>
+				</el-descriptions>
+				
+				<div class="sensor-data-section">
+					<h4>浼犳劅鍣ㄦ暟鎹�</h4>
+					<el-table :data="currentEvent.sensorData" style="width: 100%" stripe>
+						<el-table-column prop="sensor" label="浼犳劅鍣�"></el-table-column>
+						<el-table-column prop="methane" label="鐢茬兎娴撳害"></el-table-column>
+						<el-table-column prop="h2s" label="纭寲姘㈡祿搴�"></el-table-column>
+						<el-table-column prop="timestamp" label="璁板綍鏃堕棿"></el-table-column>
+					</el-table>
+				</div>
+				
+				<div class="action-log-section">
+					<h4>澶勭疆鍔ㄤ綔璁板綍</h4>
+					<el-timeline>
+						<el-timeline-item
+							v-for="action in currentEvent.actions"
+							:key="action.id"
+							:timestamp="action.timestamp"
+							:type="action.type === 'emergency' ? 'danger' : 'primary'"
+						>
+							{{ action.description }}
+						</el-timeline-item>
+					</el-timeline>
+				</div>
+				
+				<div class="blockchain-info">
+					<h4>鍖哄潡閾句俊鎭�</h4>
+					<el-descriptions :column="1" border>
+						<el-descriptions-item label="鍖哄潡鍝堝笇">{{ currentEvent.blockHash }}</el-descriptions-item>
+						<el-descriptions-item label="浜ゆ槗鍝堝笇">{{ currentEvent.txHash }}</el-descriptions-item>
+						<el-descriptions-item label="纭鏁�">{{ currentEvent.confirmations }}</el-descriptions-item>
+					</el-descriptions>
+				</div>
+			</div>
+		</el-dialog>
+	</div>
+</template>
+
+<script>
+import * as echarts from 'echarts'
+
+export default {
+	name: 'SafetyMonitoring',
+	data() {
+		return {
+			systemStatus: 'normal',
+			leakWarningVisible: false,
+			emergencyRecordsVisible: false,
+			blockchainDetailsVisible: false,
+			currentWarning: {},
+			currentEvent: {},
+			hasEmergency: false,
+			
+			// 鍌ㄧ綈鍖轰紶鎰熷櫒鏁版嵁
+			tankSensors: [
+				{ id: 1, name: '鍌ㄧ綈T-001', methane: 1.20, h2s: 2.10, status: 'normal' },
+				{ id: 2, name: '鍌ㄧ綈T-002', methane: 0.80, h2s: 1.50, status: 'normal' },
+				{ id: 3, name: '鍌ㄧ綈T-003', methane: 3.20, h2s: 8.50, status: 'warning' },
+				{ id: 4, name: '鍌ㄧ綈T-004', methane: 0.60, h2s: 0.80, status: 'normal' }
+			],
+			
+			// 浜曞彛鍘嬬缉鏈轰紶鎰熷櫒鏁版嵁
+			compressorSensors: [
+				{ id: 5, name: '鍘嬬缉鏈篊-001', methane: 2.10, h2s: 3.20, status: 'normal' },
+				{ id: 6, name: '鍘嬬缉鏈篊-002', methane: 4.80, h2s: 12.50, status: 'warning' },
+				{ id: 7, name: '鍘嬬缉鏈篊-003', methane: 1.80, h2s: 2.80, status: 'normal' }
+			],
+			
+			// 鍠锋穻绯荤粺鐘舵��
+			sprinklerSystems: [
+				{ id: 1, name: '鍌ㄧ綈鍖哄柗娣�', status: 'active' },
+				{ id: 2, name: '鍘嬬缉鏈哄尯鍠锋穻', status: 'standby' },
+				{ id: 3, name: '绱ф�ュ柗娣�', status: 'standby' }
+			],
+			
+			// 绯荤粺鏃ュ織
+			systemLogs: [
+				{ id: 1, time: '14:30:25', content: '绯荤粺鍚姩瀹屾垚锛屾墍鏈変紶鎰熷櫒姝e父' },
+				{ id: 2, time: '14:35:12', content: '鍌ㄧ綈T-003鐢茬兎娴撳害瓒呮爣锛岃Е鍙戦璀�' },
+				{ id: 3, time: '14:35:15', content: '鍚姩鍌ㄧ綈鍖哄柗娣嬬郴缁�' },
+				{ id: 4, time: '14:35:20', content: '鍙戦�佺揣鎬ョ枏鏁e箍鎾�' }
+			],
+			
+			// 搴旀�ヨ褰�
+			emergencyRecords: [
+				{
+					id: 'EM001',
+					time: '2024-01-15 14:35:12',
+					location: '鍌ㄧ綈T-003',
+					type: '鐢茬兎瓒呮爣',
+					status: 'resolved',
+					description: '鍌ㄧ綈T-003鐢茬兎娴撳害杈惧埌3.2%锛岃秴杩囧畨鍏ㄩ槇鍊�2.5%'
+				},
+				{
+					id: 'EM002',
+					time: '2024-01-15 14:35:15',
+					location: '鍘嬬缉鏈篊-002',
+					type: '纭寲姘㈣秴鏍�',
+					status: 'processing',
+					description: '鍘嬬缉鏈篊-002纭寲姘㈡祿搴﹁揪鍒�12.5ppm锛岃秴杩囧畨鍏ㄩ槇鍊�10ppm'
+				}
+			],
+			
+			// 鍥捐〃瀹炰緥
+			chart: null,
+			
+			// 瀹氭椂鍣�
+			timer: null
+		}
+	},
+	
+	mounted() {
+		this.initChart()
+		this.startDataRefresh()
+		this.checkEmergencyStatus()
+	},
+	
+	beforeDestroy() {
+		if (this.timer) {
+			clearInterval(this.timer)
+		}
+		if (this.chart) {
+			this.chart.dispose()
+		}
+	},
+	
+	methods: {
+		// 缁熶竴杩涘害鏉℃牸寮忓寲涓轰袱浣嶅皬鏁帮紝閬垮厤娴偣璇樊鏄剧ず
+		formatProgress(percentage) {
+			if (percentage == null || isNaN(percentage)) return '0.00%'
+			const val = Math.round(Number(percentage) * 100) / 100
+			return `${val.toFixed(2)}%`
+		},
+		// 鍒濆鍖栧浘琛�
+		initChart() {
+			this.chart = echarts.init(this.$refs.chart)
+			this.updateChart()
+		},
+		
+		// 鏇存柊鍥捐〃鏁版嵁
+		updateChart() {
+			const option = {
+				title: {
+					text: '瀹炴椂姘斾綋娴撳害鐩戞帶',
+					left: 'center'
+				},
+				tooltip: {
+					trigger: 'axis',
+					axisPointer: {
+						type: 'cross'
+					}
+				},
+				legend: {
+					data: ['鍌ㄧ綈鍖虹敳鐑�', '鍌ㄧ綈鍖虹~鍖栨阿', '鍘嬬缉鏈虹敳鐑�', '鍘嬬缉鏈虹~鍖栨阿'],
+					top: 30
+				},
+				grid: {
+					left: '3%',
+					right: '4%',
+					bottom: '3%',
+					top: '15%',
+					containLabel: true
+				},
+				xAxis: {
+					type: 'category',
+					data: this.generateTimeData()
+				},
+				yAxis: [
+					{
+						type: 'value',
+						name: '鐢茬兎娴撳害(%)',
+						position: 'left'
+					},
+					{
+						type: 'value',
+						name: '纭寲姘㈡祿搴�(ppm)',
+						position: 'right'
+					}
+				],
+				series: [
+					{
+						name: '鍌ㄧ綈鍖虹敳鐑�',
+						type: 'line',
+						data: this.generateRandomData(20, 0.5, 3.5),
+						smooth: true,
+						yAxisIndex: 0
+					},
+					{
+						name: '鍌ㄧ綈鍖虹~鍖栨阿',
+						type: 'line',
+						data: this.generateRandomData(20, 0.5, 12),
+						smooth: true,
+						yAxisIndex: 1
+					},
+					{
+						name: '鍘嬬缉鏈虹敳鐑�',
+						type: 'line',
+						data: this.generateRandomData(20, 1.0, 5.0),
+						smooth: true,
+						yAxisIndex: 0
+					},
+					{
+						name: '鍘嬬缉鏈虹~鍖栨阿',
+						type: 'line',
+						data: this.generateRandomData(20, 1.0, 15),
+						smooth: true,
+						yAxisIndex: 1
+					}
+				]
+			}
+			
+			this.chart.setOption(option)
+		},
+		
+		// 鐢熸垚鏃堕棿鏁版嵁
+		generateTimeData() {
+			const times = []
+			const now = new Date()
+			for (let i = 19; i >= 0; i--) {
+				const time = new Date(now.getTime() - i * 5 * 60 * 1000)
+				times.push(time.toLocaleTimeString('zh-CN', { hour12: false }))
+			}
+			return times
+		},
+		
+		// 鐢熸垚闅忔満鏁版嵁
+		generateRandomData(count, min, max) {
+			const data = []
+			for (let i = 0; i < count; i++) {
+				data.push(+(Math.random() * (max - min) + min).toFixed(2))
+			}
+			return data
+		},
+		
+		// 寮�濮嬫暟鎹埛鏂�
+		startDataRefresh() {
+			this.timer = setInterval(() => {
+				this.refreshSensorData()
+				this.updateChart()
+				this.checkEmergencyStatus()
+			}, 5000) // 姣�5绉掑埛鏂颁竴娆�
+		},
+		
+		// 鍒锋柊浼犳劅鍣ㄦ暟鎹�
+		refreshSensorData() {
+			// 鏇存柊鍌ㄧ綈鍖轰紶鎰熷櫒鏁版嵁
+			this.tankSensors.forEach(sensor => {
+				sensor.methane = +(Math.random() * 4).toFixed(2)
+				sensor.h2s = +(Math.random() * 15).toFixed(2)
+				sensor.status = this.getSensorStatus(sensor.methane, sensor.h2s)
+			})
+			
+			// 鏇存柊鍘嬬缉鏈轰紶鎰熷櫒鏁版嵁
+			this.compressorSensors.forEach(sensor => {
+				sensor.methane = +(Math.random() * 6).toFixed(2)
+				sensor.h2s = +(Math.random() * 20).toFixed(2)
+				sensor.status = this.getSensorStatus(sensor.methane, sensor.h2s)
+			})
+			
+			// 妫�鏌ユ槸鍚﹂渶瑕佽Е鍙戦璀�
+			this.checkLeakWarning()
+		},
+		
+		// 鑾峰彇浼犳劅鍣ㄧ姸鎬�
+		getSensorStatus(methane, h2s) {
+			const methanePct = Math.min(Math.round(methane * 40 * 100) / 100, 100)
+			const h2sPct = Math.min(Math.round((h2s / 20) * 100 * 100) / 100, 100)
+			if (methanePct >= 80 || h2sPct >= 80) {
+				return 'warning'
+			}
+			return 'normal'
+		},
+		
+		// 妫�鏌ユ硠婕忛璀�
+		checkLeakWarning() {
+			const allSensors = [...this.tankSensors, ...this.compressorSensors]
+			const warningSensor = allSensors.find(sensor => this.getSensorStatus(sensor.methane, sensor.h2s) === 'warning')
+			
+			if (warningSensor && !this.leakWarningVisible) {
+				this.triggerLeakWarning(warningSensor)
+			}
+		},
+		
+		// 瑙﹀彂娉勬紡棰勮
+		triggerLeakWarning(sensor) {
+			const methanePct = Math.min(Math.round(sensor.methane * 40 * 100) / 100, 100)
+			const h2sPct = Math.min(Math.round((sensor.h2s / 20) * 100 * 100) / 100, 100)
+			const isMethaneMajor = methanePct >= h2sPct
+			const overGas = isMethaneMajor ? '鐢茬兎' : '纭寲姘�'
+			const percent = (isMethaneMajor ? methanePct : h2sPct).toFixed(2)
+			this.currentWarning = {
+				location: sensor.name,
+				gas: overGas,
+				value: `${percent}%`
+			}
+			
+			this.leakWarningVisible = true
+			this.hasEmergency = true
+			
+			// 鑷姩瑙﹀彂搴旀�ュ搷搴�
+			this.autoEmergencyResponse(sensor)
+			
+			// 娣诲姞绯荤粺鏃ュ織
+			this.addSystemLog(`妫�娴嬪埌${sensor.name}姘斾綋娴撳害瓒呮爣锛岃Е鍙戞硠婕忛璀)
+		},
+		
+		// 鑷姩搴旀�ュ搷搴�
+		autoEmergencyResponse(sensor) {
+			// 鍚姩鍠锋穻绯荤粺
+			if (sensor.name.includes('鍌ㄧ綈')) {
+				this.sprinklerSystems[0].status = 'active'
+			} else if (sensor.name.includes('鍘嬬缉鏈�')) {
+				this.sprinklerSystems[1].status = 'active'
+			}
+			
+			// 娣诲姞绯荤粺鏃ュ織
+			this.addSystemLog(`鍚姩${sensor.name}鍖哄煙鍠锋穻绯荤粺`)
+			this.addSystemLog(`鍙戦�佺揣鎬ョ枏鏁e箍鎾璥)
+			
+			// 鍒涘缓搴旀�ヨ褰�
+			this.createEmergencyRecord(sensor)
+		},
+		
+		// 娣诲姞绯荤粺鏃ュ織
+		addSystemLog(content) {
+			const now = new Date()
+			const time = now.toLocaleTimeString('zh-CN', { hour12: false })
+			
+			this.systemLogs.unshift({
+				id: Date.now(),
+				time: time,
+				content: content
+			})
+			
+			// 淇濇寔鏈�澶�20鏉℃棩蹇�
+			if (this.systemLogs.length > 20) {
+				this.systemLogs = this.systemLogs.slice(0, 20)
+			}
+		},
+		
+		// 鍒涘缓搴旀�ヨ褰�
+		createEmergencyRecord(sensor) {
+			const now = new Date()
+			const record = {
+				id: `EM${Date.now()}`,
+				time: now.toLocaleString('zh-CN'),
+				location: sensor.name,
+				type: sensor.methane > 2.5 ? '鐢茬兎瓒呮爣' : '纭寲姘㈣秴鏍�',
+				status: 'processing',
+				description: `${sensor.name}妫�娴嬪埌${sensor.methane > 2.5 ? '鐢茬兎' : '纭寲姘�'}娴撳害瓒呮爣`
+			}
+			
+			this.emergencyRecords.unshift(record)
+		},
+		
+		// 鑾峰彇杩涘害鏉¢鑹�
+		getProgressColor(value, threshold) {
+			if (value > threshold) {
+				return '#F56C6C'
+			} else if (value > threshold * 0.8) {
+				return '#E6A23C'
+			}
+			return '#67C23A'
+		},
+		
+		// 妫�鏌ュ簲鎬ョ姸鎬�
+		checkEmergencyStatus() {
+			const allSensors = [...this.tankSensors, ...this.compressorSensors]
+			const has = allSensors.some(sensor => this.getSensorStatus(sensor.methane, sensor.h2s) === 'warning')
+			this.hasEmergency = has
+			this.systemStatus = has ? 'warning' : 'normal'
+		},
+		
+		// 纭鍛婅
+		acknowledgeWarning() {
+			this.leakWarningVisible = false
+			this.addSystemLog('娉勬紡棰勮宸茬‘璁�')
+		},
+		
+		// 鏌ョ湅璇︽儏
+		viewDetails() {
+			this.leakWarningVisible = false
+			// 杩欓噷鍙互璺宠浆鍒拌缁嗛〉闈㈡垨鏄剧ず鏇村淇℃伅
+		},
+		
+		// 鏄剧ず搴旀�ヨ褰�
+		showEmergencyRecords() {
+			this.emergencyRecordsVisible = true
+		},
+		
+		// 鏌ョ湅鍖哄潡閾捐鎯�
+		viewBlockchainDetails(record) {
+			this.currentEvent = {
+				id: record.id,
+				timestamp: record.time,
+				location: record.location,
+				type: record.type,
+				sensorData: [
+					{
+						sensor: '鐢茬兎浼犳劅鍣�',
+						methane: '3.2%',
+						h2s: '8.5ppm',
+						timestamp: record.time
+					},
+					{
+						sensor: '纭寲姘紶鎰熷櫒',
+						methane: '2.8%',
+						h2s: '12.5ppm',
+						timestamp: record.time
+					}
+				],
+				actions: [
+					{
+						id: 1,
+						timestamp: record.time,
+						type: 'emergency',
+						description: '妫�娴嬪埌姘斾綋娴撳害瓒呮爣锛岃Е鍙戦璀�'
+					},
+					{
+						id: 2,
+						timestamp: new Date(new Date(record.time).getTime() + 3000).toLocaleString('zh-CN'),
+						type: 'action',
+						description: '鍚姩鍠锋穻绯荤粺闄嶆俯'
+					},
+					{
+						id: 3,
+						timestamp: new Date(new Date(record.time).getTime() + 5000).toLocaleString('zh-CN'),
+						type: 'action',
+						description: '鍙戦�佺揣鎬ョ枏鏁e箍鎾�'
+					}
+				],
+				blockHash: '0x1234567890abcdef...',
+				txHash: '0xabcdef1234567890...',
+				confirmations: 12
+			}
+			
+			this.emergencyRecordsVisible = false
+			this.blockchainDetailsVisible = true
+		},
+		
+		// 瑙﹀彂搴旀�ュ搷搴�
+		triggerEmergency() {
+			this.$message.success('搴旀�ュ搷搴斿凡瑙﹀彂')
+			this.addSystemLog('鎵嬪姩瑙﹀彂搴旀�ュ搷搴�')
+		}
+	}
+}
+</script>
+
+<style scoped>
+.safety-monitoring {
+	padding: 20px;
+	background-color: #f5f7fa;
+	min-height: calc(100vh - 84px);
+}
+
+.monitoring-card, .control-card {
+	margin-bottom: 20px;
+}
+
+.card-header {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+}
+
+.monitoring-section {
+	margin-bottom: 30px;
+}
+
+.monitoring-section h3 {
+	color: #303133;
+	margin-bottom: 15px;
+	padding-bottom: 8px;
+	border-bottom: 2px solid #409EFF;
+}
+
+.sensor-grid {
+	display: grid;
+	grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
+	gap: 15px;
+}
+
+.sensor-item {
+	background: #fff;
+	border: 1px solid #e4e7ed;
+	border-radius: 8px;
+	padding: 15px;
+	box-shadow: 0 2px 4px rgba(0,0,0,0.1);
+}
+
+.sensor-header {
+	display: flex;
+	justify-content: space-between;
+	align-items: center;
+	margin-bottom: 15px;
+	font-weight: bold;
+}
+
+.sensor-data .data-item {
+	margin-bottom: 12px;
+}
+
+.sensor-data .data-item span {
+	display: block;
+	margin-bottom: 5px;
+	font-size: 14px;
+	color: #606266;
+}
+
+.chart-section {
+	margin-top: 30px;
+}
+
+.chart-section h3 {
+	color: #303133;
+	margin-bottom: 15px;
+	padding-bottom: 8px;
+	border-bottom: 2px solid #409EFF;
+}
+
+.chart-container {
+	background: #fff;
+	border-radius: 8px;
+	padding: 20px;
+}
+
+.chart {
+	width: 100%;
+	height: 400px;
+}
+
+.control-section {
+	margin-bottom: 25px;
+}
+.control-section1 {
+	display: flex;
+}
+
+.control-section h4 {
+	color: #303133;
+	margin-bottom: 15px;
+	font-size: 16px;
+}
+
+.status-grid {
+	display: grid;
+	gap: 10px;
+}
+
+.status-item {
+	display: flex;
+	align-items: center;
+	gap: 10px;
+	padding: 10px;
+	background: #f8f9fa;
+	border-radius: 6px;
+}
+
+.status-indicator {
+	width: 20px;
+	height: 20px;
+	border-radius: 50%;
+	display: flex;
+	align-items: center;
+	justify-content: center;
+}
+
+.status-indicator.active {
+	color: #67C23A;
+}
+
+.status-indicator.standby {
+	color: #909399;
+}
+
+.log-container {
+	max-height: 200px;
+	overflow-y: auto;
+	background: #f8f9fa;
+	border-radius: 6px;
+	padding: 10px;
+}
+
+.log-item {
+	display: flex;
+	gap: 10px;
+	margin-bottom: 8px;
+	font-size: 12px;
+}
+
+.log-time {
+	color: #909399;
+	min-width: 60px;
+}
+
+.log-content {
+	color: #606266;
+}
+
+/* 娉勬紡棰勮寮圭獥鏍峰紡 */
+.leak-warning-dialog {
+	background: #fff5f5;
+}
+
+.warning-content {
+	text-align: center;
+	padding: 20px 0;
+}
+
+.warning-icon {
+	font-size: 60px;
+	color: #F56C6C;
+	margin-bottom: 20px;
+}
+
+.warning-text h3 {
+	color: #F56C6C;
+	margin-bottom: 15px;
+}
+
+.warning-text p {
+	margin: 8px 0;
+	color: #606266;
+}
+
+/* 鍖哄潡閾捐鎯呮牱寮� */
+.blockchain-details {
+	padding: 20px 0;
+}
+
+.sensor-data-section, .action-log-section, .blockchain-info {
+	margin-top: 25px;
+}
+
+.sensor-data-section h4, .action-log-section h4, .blockchain-info h4 {
+	color: #303133;
+	margin-bottom: 15px;
+	padding-bottom: 8px;
+	border-bottom: 1px solid #e4e7ed;
+}
+
+/* 鍝嶅簲寮忚璁� */
+@media (max-width: 1200px) {
+	.sensor-grid {
+		grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
+	}
+}
+
+@media (max-width: 768px) {
+	.safety-monitoring {
+		padding: 10px;
+	}
+	
+	.sensor-grid {
+		grid-template-columns: 1fr;
+	}
+	
+	.chart {
+		height: 300px;
+	}
+}
+</style>
diff --git a/src/views/qualityManagement/finalInspection/components/formDia.vue b/src/views/qualityManagement/finalInspection/components/formDia.vue
index 34f5990..6547e3f 100644
--- a/src/views/qualityManagement/finalInspection/components/formDia.vue
+++ b/src/views/qualityManagement/finalInspection/components/formDia.vue
@@ -58,8 +58,10 @@
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="妫�楠屽憳锛�" prop="checkName">
-              <el-input v-model="form.checkName" placeholder="璇疯緭鍏�" clearable/>
-            
+							<el-select v-model="form.checkName" placeholder="璇烽�夋嫨" clearable>
+								<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
+													 :value="item.nickName"/>
+							</el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
@@ -77,6 +79,17 @@
           </el-col>
         </el-row>
       </el-form>
+			<PIMTable
+				rowKey="id"
+				:column="tableColumn"
+				:tableData="tableData"
+				:tableLoading="tableLoading"
+				height="400"
+			>
+				<template #slot="{ row }">
+					<el-input v-model="row.testValue" clearable/>
+				</template>
+			</PIMTable>
       <template #footer>
         <div class="dialog-footer">
           <el-button type="primary" @click="submitForm">纭</el-button>
@@ -92,6 +105,9 @@
 import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
 import {productTreeList} from "@/api/basicData/product.js";
 import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
+import {userListNoPage} from "@/api/system/user.js";
+import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
@@ -125,17 +141,50 @@
 const { form, rules } = toRefs(data);
 const supplierList = ref([]);
 const productOptions = ref([]);
+const tableColumn = ref([
+	{
+		label: "鎸囨爣",
+		prop: "parameterItem",
+	},
+	{
+		label: "鍗曚綅",
+		prop: "unit",
+	},
+	{
+		label: "鏍囧噯鍊�",
+		prop: "standardValue",
+	},
+	{
+		label: "鍐呮帶鍊�",
+		prop: "controlValue",
+	},
+	{
+		label: "妫�楠屽��",
+		prop: "testValue",
+		dataType: 'slot',
+		slot: 'slot',
+	},
+]);
+const tableData = ref([]);
+const tableLoading = ref(false);
+const userList = ref([]);
+const currentProductId = ref(0);
 
 // 鎵撳紑寮规
-const openDialog = (type, row) => {
+const openDialog = async (type, row) => {
   operationType.value = type;
   dialogFormVisible.value = true;
   getOptions().then((res) => {
     supplierList.value = res.data;
   });
+	let userLists = await userListNoPage();
+	userList.value = userLists.data;
+	form.value = {}
   getProductOptions();
   if (operationType.value === 'edit') {
     form.value = {...row}
+		currentProductId.value = row.productId || 0
+		getQualityInspectParamList(row.id)
   }
 }
 const getProductOptions = () => {
@@ -144,7 +193,11 @@
   });
 };
 const getModels = (value) => {
+	currentProductId.value = value
   form.value.productName = findNodeById(productOptions.value, value);
+	if (currentProductId) {
+		getList();
+	}
 };
 const findNodeById = (nodes, productId) => {
   for (let i = 0; i < nodes.length; i++) {
@@ -179,13 +232,19 @@
   proxy.$refs.formRef.validate(valid => {
     if (valid) {
       form.value.inspectType = 2
+			if (operationType.value === "add") {
+				tableData.value.forEach((item) => {
+					delete item.id
+				})
+			}
+			const data = {...form.value, qualityInspectParams: tableData.value}
       if (operationType.value === "add") {
-        qualityInspectAdd(form.value).then(res => {
+        qualityInspectAdd(data).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
           closeDia();
         })
       } else {
-        qualityInspectUpdate(form.value).then(res => {
+        qualityInspectUpdate(data).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
           closeDia();
         })
@@ -193,6 +252,16 @@
     }
   })
 }
+const getList = () => {
+	qualityInspectDetailByProductId(currentProductId.value).then(res => {
+		tableData.value = res.data;
+	})
+}
+const getQualityInspectParamList = (id) => {
+	qualityInspectParamInfo(id).then(res => {
+		tableData.value = res.data;
+	})
+}
 // 鍏抽棴寮规
 const closeDia = () => {
   proxy.resetForm("formRef");
diff --git a/src/views/qualityManagement/finalInspection/index.vue b/src/views/qualityManagement/finalInspection/index.vue
index e8dcee6..3f2595f 100644
--- a/src/views/qualityManagement/finalInspection/index.vue
+++ b/src/views/qualityManagement/finalInspection/index.vue
@@ -40,6 +40,23 @@
     <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia>
     <FormDia ref="formDia" @close="handleQuery"></FormDia>
     <files-dia ref="filesDia" @close="handleQuery"></files-dia>
+		<el-dialog v-model="dialogFormVisible" title="缂栬緫妫�楠屽憳" width="30%"
+							 @close="closeDia">
+			<el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+				<el-form-item label="妫�楠屽憳锛�" prop="checkName">
+					<el-select v-model="form.checkName" placeholder="璇烽�夋嫨" clearable>
+						<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
+											 :value="item.nickName"/>
+					</el-select>
+				</el-form-item>
+			</el-form>
+			<template #footer>
+				<div class="dialog-footer">
+					<el-button type="primary" @click="submitForm">纭</el-button>
+					<el-button @click="closeDia">鍙栨秷</el-button>
+				</div>
+			</template>
+		</el-dialog>
   </div>
 </template>
 
@@ -49,9 +66,15 @@
 import InspectionFormDia from "@/views/qualityManagement/finalInspection/components/inspectionFormDia.vue";
 import FormDia from "@/views/qualityManagement/finalInspection/components/formDia.vue";
 import {ElMessageBox} from "element-plus";
-import {qualityInspectDel, qualityInspectListPage} from "@/api/qualityManagement/rawMaterialInspection.js";
+import {
+	downloadQualityInspect,
+	qualityInspectDel,
+	qualityInspectListPage, qualityInspectUpdate,
+	submitQualityInspect
+} from "@/api/qualityManagement/rawMaterialInspection.js";
 import FilesDia from "@/views/qualityManagement/finalInspection/components/filesDia.vue";
 import dayjs from "dayjs";
+import {userListNoPage} from "@/api/system/user.js";
 
 const data = reactive({
   searchForm: {
@@ -63,6 +86,9 @@
     entryDateStart: dayjs().format("YYYY-MM-DD"),
     entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
   },
+	rules: {
+		checkName: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+	},
 });
 const { searchForm } = toRefs(data);
 const tableColumn = ref([
@@ -111,12 +137,23 @@
       }
     },
   },
+	{
+		label: "鎻愪氦鐘舵��",
+		prop: "inspectState",
+		formatData: (params) => {
+			if (params) {
+				return "宸叉彁浜�";
+			} else {
+				return "鏈彁浜�";
+			}
+		},
+	},
   {
     dataType: "action",
     label: "鎿嶄綔",
     align: "center",
     fixed: "right",
-    width: 190,
+    width: 280,
     operation: [
       {
         name: "缂栬緫",
@@ -124,13 +161,9 @@
         clickFun: (row) => {
           openForm("edit", row);
         },
-      },
-      {
-        name: "鏂板妫�楠岃褰�",
-        type: "text",
-        clickFun: (row) => {
-          openInspectionForm("edit", row);
-        },
+				disabled: (row) => {
+					return row.inspectState == 1;
+				}
       },
       {
         name: "闄勪欢",
@@ -139,12 +172,44 @@
           openFilesFormDia(row);
         },
       },
+			{
+				name: "鎻愪氦",
+				type: "text",
+				clickFun: (row) => {
+					submit(row.id);
+				},
+				disabled: (row) => {
+					return row.inspectState == 1;
+				}
+			},
+			{
+				name: "鍒嗛厤妫�楠屽憳",
+				type: "text",
+				clickFun: (row) => {
+					if (!row.checkName) {
+						open(row)
+					} else {
+						proxy.$modal.msgError("妫�楠屽憳宸插瓨鍦�");
+					}
+				},
+				disabled: (row) => {
+					return row.inspectState == 1 || row.checkName;
+				}
+			},
+			{
+				name: "涓嬭浇",
+				type: "text",
+				clickFun: (row) => {
+					downLoadFile(row);
+				},
+			},
     ],
   },
 ]);
 const tableData = ref([]);
 const selectedRows = ref([]);
 const tableLoading = ref(false);
+const currentRow = ref(null)
 const page = reactive({
   current: 1,
   size: 100,
@@ -154,6 +219,11 @@
 const filesDia = ref()
 const inspectionFormDia = ref()
 const { proxy } = getCurrentInstance()
+const userList = ref([]);
+const form = ref({
+	checkName: ""
+});
+const dialogFormVisible = ref(false);
 
 const changeDaterange = (value) => {
   searchForm.value.entryDateStart = undefined;
@@ -249,6 +319,60 @@
         proxy.$modal.msg("宸插彇娑�");
       });
 };
+
+// 鎻愪环
+const submit = async (id) => {
+	const res = await submitQualityInspect({id: id})
+	if (res.code === 200) {
+		proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+		getList();
+	}
+}
+
+// 鍏抽棴寮规
+const closeDia = () => {
+	proxy.resetForm("formRef");
+	dialogFormVisible.value = false;
+};
+
+const submitForm = () => {
+	if (currentRow.value) {
+		const data = {
+			...form.value,
+			id: currentRow.value.id
+		}
+		qualityInspectUpdate(data).then(res => {
+			proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+			closeDia();
+			getList();
+		})
+	}
+};
+
+const open = async (row) => {
+	let userLists = await userListNoPage();
+	userList.value = userLists.data;
+	currentRow.value = row
+	dialogFormVisible.value = true
+}
+
+const downLoadFile = (row) => {
+	downloadQualityInspect({ id: row.id }).then((blobData) => {
+		const blob = new Blob([blobData], {
+			type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+		})
+		const downloadUrl = window.URL.createObjectURL(blob)
+		
+		const link = document.createElement('a')
+		link.href = downloadUrl
+		link.download = '鍘熸潗鏂欐楠屾姤鍛�.docx'
+		document.body.appendChild(link)
+		link.click()
+		
+		document.body.removeChild(link)
+		window.URL.revokeObjectURL(downloadUrl)
+	})
+};
 onMounted(() => {
   getList();
 });
diff --git a/src/views/qualityManagement/processInspection/components/filesDia.vue b/src/views/qualityManagement/processInspection/components/filesDia.vue
index 66392f3..fb47850 100644
--- a/src/views/qualityManagement/processInspection/components/filesDia.vue
+++ b/src/views/qualityManagement/processInspection/components/filesDia.vue
@@ -46,18 +46,13 @@
         </div>
       </template>
     </el-dialog>
+		<filePreview ref="filePreviewRef" />
   </div>
 </template>
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-import {Search} from "@element-plus/icons-vue";
-import {
-  qualityInspectParamDel,
-  qualityInspectParamInfo,
-  qualityInspectParamUpdate
-} from "@/api/qualityManagement/qualityInspectParam.js";
+import filePreview from '@/components/filePreview/index.vue'
 import {ElMessageBox} from "element-plus";
 import {getToken} from "@/utils/auth.js";
 import {
@@ -72,6 +67,7 @@
 const dialogFormVisible = ref(false);
 const currentId = ref('')
 const selectedRows = ref([]);
+const filePreviewRef = ref()
 const tableColumn = ref([
   {
     label: "鏂囦欢鍚嶇О",
@@ -88,7 +84,14 @@
         clickFun: (row) => {
           downLoadFile(row);
         },
-      }
+      },
+			{
+				name: "棰勮",
+				type: "text",
+				clickFun: (row) => {
+					lookFile(row);
+				},
+			}
     ],
   },
 ]);
@@ -158,6 +161,10 @@
 function handleUploadError() {
   proxy.$modal.msgError("鏂囦欢涓婁紶澶辫触");
 }
+// 棰勮闄勪欢
+const lookFile = (row) => {
+	filePreviewRef.value.open(row.url)
+}
 // 鍒犻櫎
 const handleDelete = () => {
   let ids = [];
diff --git a/src/views/qualityManagement/processInspection/components/formDia.vue b/src/views/qualityManagement/processInspection/components/formDia.vue
index 0ded52e..c24d425 100644
--- a/src/views/qualityManagement/processInspection/components/formDia.vue
+++ b/src/views/qualityManagement/processInspection/components/formDia.vue
@@ -65,8 +65,10 @@
         <el-row :gutter="30">
           <el-col :span="12">
             <el-form-item label="妫�楠屽憳锛�" prop="checkName">
-              <el-input v-model="form.checkName" placeholder="璇疯緭鍏�" clearable/>
-            
+							<el-select v-model="form.checkName" placeholder="璇烽�夋嫨" clearable>
+								<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
+													 :value="item.nickName"/>
+							</el-select>
             </el-form-item>
           </el-col>
           <el-col :span="12">
@@ -84,6 +86,17 @@
           </el-col>
         </el-row>
       </el-form>
+			<PIMTable
+				rowKey="id"
+				:column="tableColumn"
+				:tableData="tableData"
+				:tableLoading="tableLoading"
+				height="400"
+			>
+				<template #slot="{ row }">
+					<el-input v-model="row.testValue" clearable/>
+				</template>
+			</PIMTable>
       <template #footer>
         <div class="dialog-footer">
           <el-button type="primary" @click="submitForm">纭</el-button>
@@ -99,6 +112,9 @@
 import {getOptions} from "@/api/procurementManagement/procurementLedger.js";
 import {productTreeList} from "@/api/basicData/product.js";
 import {qualityInspectAdd, qualityInspectUpdate} from "@/api/qualityManagement/rawMaterialInspection.js";
+import {qualityInspectDetailByProductId} from "@/api/qualityManagement/metricMaintenance.js";
+import {userListNoPage} from "@/api/system/user.js";
+import {qualityInspectParamInfo} from "@/api/qualityManagement/qualityInspectParam.js";
 const { proxy } = getCurrentInstance()
 const emit = defineEmits(['close'])
 
@@ -129,21 +145,54 @@
     checkResult: [{ required: true, message: "璇疯緭鍏�", trigger: "change" }],
   },
 });
+const userList = ref([]);
 const { form, rules } = toRefs(data);
 const supplierList = ref([]);
 const productOptions = ref([]);
+const tableColumn = ref([
+	{
+		label: "鎸囨爣",
+		prop: "parameterItem",
+	},
+	{
+		label: "鍗曚綅",
+		prop: "unit",
+	},
+	{
+		label: "鏍囧噯鍊�",
+		prop: "standardValue",
+	},
+	{
+		label: "鍐呮帶鍊�",
+		prop: "controlValue",
+	},
+	{
+		label: "妫�楠屽��",
+		prop: "testValue",
+		dataType: 'slot',
+		slot: 'slot',
+	},
+]);
+const tableData = ref([]);
+const tableLoading = ref(false);
+const currentProductId = ref(0);
 
 // 鎵撳紑寮规
-const openDialog = (type, row) => {
-  operationType.value = type;
-  dialogFormVisible.value = true;
-  getOptions().then((res) => {
-    supplierList.value = res.data;
-  });
-  getProductOptions();
-  if (operationType.value === 'edit') {
-    form.value = {...row}
-  }
+const openDialog = async (type, row) => {
+	operationType.value = type;
+	dialogFormVisible.value = true;
+	getOptions().then((res) => {
+		supplierList.value = res.data;
+	});
+	let userLists = await userListNoPage();
+	userList.value = userLists.data;
+	form.value = {}
+	getProductOptions();
+	if (operationType.value === 'edit') {
+		form.value = {...row}
+		currentProductId.value = row.productId || 0
+		getQualityInspectParamList(row.id)
+	}
 }
 const getProductOptions = () => {
   productTreeList().then((res) => {
@@ -151,7 +200,11 @@
   });
 };
 const getModels = (value) => {
+	currentProductId.value = value
   form.value.productName = findNodeById(productOptions.value, value);
+	if (currentProductId) {
+		getList();
+	}
 };
 const findNodeById = (nodes, productId) => {
   for (let i = 0; i < nodes.length; i++) {
@@ -186,13 +239,19 @@
   proxy.$refs.formRef.validate(valid => {
     if (valid) {
       form.value.inspectType = 1
+			if (operationType.value === "add") {
+				tableData.value.forEach((item) => {
+					delete item.id
+				})
+			}
+			const data = {...form.value, qualityInspectParams: tableData.value}
       if (operationType.value === "add") {
-        qualityInspectAdd(form.value).then(res => {
+        qualityInspectAdd(data).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
           closeDia();
         })
       } else {
-        qualityInspectUpdate(form.value).then(res => {
+        qualityInspectUpdate(data).then(res => {
           proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
           closeDia();
         })
@@ -200,6 +259,16 @@
     }
   })
 }
+const getList = () => {
+	qualityInspectDetailByProductId(currentProductId.value).then(res => {
+		tableData.value = res.data;
+	})
+}
+const getQualityInspectParamList = (id) => {
+	qualityInspectParamInfo(id).then(res => {
+		tableData.value = res.data;
+	})
+}
 // 鍏抽棴寮规
 const closeDia = () => {
   proxy.resetForm("formRef");
diff --git a/src/views/qualityManagement/processInspection/index.vue b/src/views/qualityManagement/processInspection/index.vue
index 04ed1f3..6f5ddec 100644
--- a/src/views/qualityManagement/processInspection/index.vue
+++ b/src/views/qualityManagement/processInspection/index.vue
@@ -40,6 +40,23 @@
     <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia>
     <FormDia ref="formDia" @close="handleQuery"></FormDia>
     <files-dia ref="filesDia" @close="handleQuery"></files-dia>
+		<el-dialog v-model="dialogFormVisible" title="缂栬緫妫�楠屽憳" width="30%"
+							 @close="closeDia">
+			<el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
+				<el-form-item label="妫�楠屽憳锛�" prop="checkName">
+					<el-select v-model="form.checkName" placeholder="璇烽�夋嫨" clearable>
+						<el-option v-for="item in userList" :key="item.nickName" :label="item.nickName"
+											 :value="item.nickName"/>
+					</el-select>
+				</el-form-item>
+			</el-form>
+			<template #footer>
+				<div class="dialog-footer">
+					<el-button type="primary" @click="submitForm">纭</el-button>
+					<el-button @click="closeDia">鍙栨秷</el-button>
+				</div>
+			</template>
+		</el-dialog>
   </div>
 </template>
 
@@ -49,9 +66,15 @@
 import InspectionFormDia from "@/views/qualityManagement/processInspection/components/inspectionFormDia.vue";
 import FormDia from "@/views/qualityManagement/processInspection/components/formDia.vue";
 import {ElMessageBox} from "element-plus";
-import {qualityInspectDel, qualityInspectListPage} from "@/api/qualityManagement/rawMaterialInspection.js";
+import {
+	downloadQualityInspect,
+	qualityInspectDel,
+	qualityInspectListPage, qualityInspectUpdate,
+	submitQualityInspect
+} from "@/api/qualityManagement/rawMaterialInspection.js";
 import FilesDia from "@/views/qualityManagement/processInspection/components/filesDia.vue";
 import dayjs from "dayjs";
+import {userListNoPage} from "@/api/system/user.js";
 
 const data = reactive({
   searchForm: {
@@ -63,6 +86,9 @@
     entryDateStart: dayjs().format("YYYY-MM-DD"),
     entryDateEnd: dayjs().add(1, "day").format("YYYY-MM-DD"),
   },
+	rules: {
+		checkName: [{required: true, message: "璇烽�夋嫨", trigger: "change"}],
+	},
 });
 const { searchForm } = toRefs(data);
 const tableColumn = ref([
@@ -116,12 +142,23 @@
       }
     },
   },
+	{
+		label: "鎻愪氦鐘舵��",
+		prop: "inspectState",
+		formatData: (params) => {
+			if (params) {
+				return "宸叉彁浜�";
+			} else {
+				return "鏈彁浜�";
+			}
+		},
+	},
   {
     dataType: "action",
     label: "鎿嶄綔",
     align: "center",
     fixed: "right",
-    width: 190,
+    width: 280,
     operation: [
       {
         name: "缂栬緫",
@@ -129,13 +166,9 @@
         clickFun: (row) => {
           openForm("edit", row);
         },
-      },
-      {
-        name: "鏂板妫�楠岃褰�",
-        type: "text",
-        clickFun: (row) => {
-          openInspectionForm("edit", row);
-        },
+				disabled: (row) => {
+					return row.inspectState == 1;
+				}
       },
       {
         name: "闄勪欢",
@@ -144,12 +177,49 @@
           openFilesFormDia(row);
         },
       },
+			{
+				name: "鎻愪氦",
+				type: "text",
+				clickFun: (row) => {
+					submit(row.id);
+				},
+				disabled: (row) => {
+					return row.inspectState == 1;
+				}
+			},
+			{
+				name: "鍒嗛厤妫�楠屽憳",
+				type: "text",
+				clickFun: (row) => {
+					if (!row.checkName) {
+						open(row)
+					} else {
+						proxy.$modal.msgError("妫�楠屽憳宸插瓨鍦�");
+					}
+				},
+				disabled: (row) => {
+					return row.inspectState == 1 || row.checkName;
+				}
+			},
+			{
+				name: "涓嬭浇",
+				type: "text",
+				clickFun: (row) => {
+					downLoadFile(row);
+				},
+			},
     ],
   },
 ]);
+const userList = ref([]);
+const currentRow = ref(null)
 const tableData = ref([]);
 const selectedRows = ref([]);
 const tableLoading = ref(false);
+const dialogFormVisible = ref(false);
+const form = ref({
+	checkName: ""
+});
 const page = reactive({
   current: 1,
   size: 100,
@@ -214,6 +284,38 @@
     filesDia.value?.openDialog(type, row)
   })
 };
+// 鎻愪环
+const submit = async (id) => {
+	const res = await submitQualityInspect({id: id})
+	if (res.code === 200) {
+		proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+		getList();
+	}
+}
+const open = async (row) => {
+	let userLists = await userListNoPage();
+	userList.value = userLists.data;
+	currentRow.value = row
+	dialogFormVisible.value = true
+}
+// 鍏抽棴寮规
+const closeDia = () => {
+	proxy.resetForm("formRef");
+	dialogFormVisible.value = false;
+};
+const submitForm = () => {
+	if (currentRow.value) {
+		const data = {
+			...form.value,
+			id: currentRow.value.id
+		}
+		qualityInspectUpdate(data).then(res => {
+			proxy.$modal.msgSuccess("鎻愪氦鎴愬姛");
+			closeDia();
+			getList();
+		})
+	}
+};
 
 // 鍒犻櫎
 const handleDelete = () => {
@@ -239,6 +341,23 @@
         proxy.$modal.msg("宸插彇娑�");
       });
 };
+const downLoadFile = (row) => {
+	downloadQualityInspect({ id: row.id }).then((blobData) => {
+		const blob = new Blob([blobData], {
+			type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+		})
+		const downloadUrl = window.URL.createObjectURL(blob)
+		
+		const link = document.createElement('a')
+		link.href = downloadUrl
+		link.download = '杩囩▼妫�楠屾姤鍛�.docx'
+		document.body.appendChild(link)
+		link.click()
+		
+		document.body.removeChild(link)
+		window.URL.revokeObjectURL(downloadUrl)
+	})
+};
 // 瀵煎嚭
 const handleOut = () => {
   ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
diff --git a/src/views/qualityManagement/rawMaterialInspection/components/filesDia.vue b/src/views/qualityManagement/rawMaterialInspection/components/filesDia.vue
index 15a17cd..9907fbe 100644
--- a/src/views/qualityManagement/rawMaterialInspection/components/filesDia.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/components/filesDia.vue
@@ -46,18 +46,13 @@
         </div>
       </template>
     </el-dialog>
+		<filePreview ref="filePreviewRef" />
   </div>
 </template>
 
 <script setup>
 import {ref} from "vue";
-import {getStaffJoinInfo, staffJoinAdd, staffJoinUpdate} from "@/api/personnelManagement/onboarding.js";
-import {Search} from "@element-plus/icons-vue";
-import {
-  qualityInspectParamDel,
-  qualityInspectParamInfo,
-  qualityInspectParamUpdate
-} from "@/api/qualityManagement/qualityInspectParam.js";
+import filePreview from '@/components/filePreview/index.vue'
 import {ElMessageBox} from "element-plus";
 import {getToken} from "@/utils/auth.js";
 import {
@@ -88,7 +83,14 @@
         clickFun: (row) => {
           downLoadFile(row);
         },
-      }
+      },
+			{
+				name: "棰勮",
+				type: "text",
+				clickFun: (row) => {
+					lookFile(row);
+				},
+			}
     ],
   },
 ]);
@@ -100,6 +102,7 @@
 const tableData = ref([]);
 const fileList = ref([]);
 const tableLoading = ref(false);
+const filePreviewRef = ref()
 const headers = ref({
   Authorization: "Bearer " + getToken(),
 });
@@ -159,6 +162,10 @@
 const downLoadFile = (row) => {
   proxy.$download.name(row.url);
 }
+// 棰勮闄勪欢
+const lookFile = (row) => {
+	filePreviewRef.value.open(row.url)
+}
 // 鍒犻櫎
 const handleDelete = () => {
   let ids = [];
diff --git a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
index b61f84a..977b420 100644
--- a/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/components/formDia.vue
@@ -96,16 +96,14 @@
           </el-col>
         </el-row>
       </el-form>
-      <div style="margin-bottom: 10px;text-align: right">
-        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>
-      </div>
+<!--      <div style="margin-bottom: 10px;text-align: right">-->
+<!--        <el-button type="danger" plain @click="handleDelete">鍒犻櫎</el-button>-->
+<!--      </div>-->
       <PIMTable
           rowKey="id"
           :column="tableColumn"
           :tableData="tableData"
           :tableLoading="tableLoading"
-          :isSelection="true"
-          @selection-change="handleSelectionChange"
           height="400"
       >
         <template #slot="{ row }">
@@ -200,6 +198,7 @@
   getOptions().then((res) => {
     supplierList.value = res.data;
   });
+	form.value = {}
   getProductOptions();
   if (operationType.value === 'edit') {
     form.value = {...row}
@@ -254,6 +253,11 @@
   proxy.$refs.formRef.validate(valid => {
     if (valid) {
       form.value.inspectType = 0
+			if (operationType.value === "add") {
+				tableData.value.forEach((item) => {
+					delete item.id
+				})
+			}
       const data = {...form.value, qualityInspectParams: tableData.value}
       if (operationType.value === "add") {
         qualityInspectAdd(data).then(res => {
@@ -269,34 +273,6 @@
     }
   })
 }
-
-const handleSelectionChange = (selection) => {
-  selectedRows.value = selection;
-};
-
-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(() => {
-        qualityInspectParamDel(ids).then((res) => {
-          proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-          getList();
-        });
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
-      });
-};
 
 const getList = () => {
   qualityInspectDetailByProductId(currentProductId.value).then(res => {
diff --git a/src/views/qualityManagement/rawMaterialInspection/index.vue b/src/views/qualityManagement/rawMaterialInspection/index.vue
index 16db3eb..7536274 100644
--- a/src/views/qualityManagement/rawMaterialInspection/index.vue
+++ b/src/views/qualityManagement/rawMaterialInspection/index.vue
@@ -41,7 +41,7 @@
     <InspectionFormDia ref="inspectionFormDia" @close="handleQuery"></InspectionFormDia>
     <FormDia ref="formDia" @close="handleQuery"></FormDia>
     <files-dia ref="filesDia" @close="handleQuery"></files-dia>
-    <el-dialog v-model="dialogFormVisible" title="缂栬緫妫�楠屽憳" width="70%"
+    <el-dialog v-model="dialogFormVisible" title="缂栬緫妫�楠屽憳" width="30%"
                @close="closeDia">
       <el-form :model="form" label-width="140px" label-position="top" :rules="rules" ref="formRef">
         <el-form-item label="妫�楠屽憳锛�" prop="checkName">
@@ -160,7 +160,7 @@
     label: "鎿嶄綔",
     align: "center",
     fixed: "right",
-    width: 250,
+    width: 280,
     operation: [
       {
         name: "缂栬緫",
@@ -168,6 +168,9 @@
         clickFun: (row) => {
           openForm("edit", row);
         },
+				disabled: (row) => {
+					return row.inspectState == 1;
+				}
       },
       {
         name: "闄勪欢",
@@ -182,6 +185,9 @@
         clickFun: (row) => {
           submit(row.id);
         },
+				disabled: (row) => {
+					return row.inspectState == 1;
+				}
       },
       {
         name: "鍒嗛厤妫�楠屽憳",
@@ -193,6 +199,9 @@
             proxy.$modal.msgError("妫�楠屽憳宸插瓨鍦�");
           }
         },
+				disabled: (row) => {
+					return row.inspectState == 1 || row.checkName;
+				}
       },
       {
         name: "涓嬭浇",
@@ -263,12 +272,6 @@
 const openForm = (type, row) => {
   nextTick(() => {
     formDia.value?.openDialog(type, row)
-  })
-};
-// 鎵撳紑鏂板妫�楠屽脊妗�
-const openInspectionForm = (type, row) => {
-  nextTick(() => {
-    inspectionFormDia.value?.openDialog(type, row)
   })
 };
 // 鎵撳紑闄勪欢寮规
@@ -354,19 +357,18 @@
 }
 
 const downLoadFile = (row) => {
-  downloadQualityInspect({id: row.id}).then(res => {
-    // 鍒涘缓 blob 瀵硅薄
-    const blob = new Blob([res.data], {type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'})
+  downloadQualityInspect({ id: row.id }).then((blobData) => {
+    const blob = new Blob([blobData], {
+      type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
+    })
     const downloadUrl = window.URL.createObjectURL(blob)
 
-    // 鍒涘缓涓存椂 <a> 鏍囩杩涜涓嬭浇
     const link = document.createElement('a')
     link.href = downloadUrl
-    link.download = '妫�楠屾姤鍛�.docx' // 杩欓噷鍜屽悗绔竴鑷�
+    link.download = '鍘熸潗鏂欐楠屾姤鍛�.docx'
     document.body.appendChild(link)
     link.click()
 
-    // 娓呯悊
     document.body.removeChild(link)
     window.URL.revokeObjectURL(downloadUrl)
   })
diff --git a/src/views/reportAnalysis/projectProfit/index.vue b/src/views/reportAnalysis/projectProfit/index.vue
index c987e3c..9584776 100644
--- a/src/views/reportAnalysis/projectProfit/index.vue
+++ b/src/views/reportAnalysis/projectProfit/index.vue
@@ -20,6 +20,8 @@
           size: pagination.pageSize,
           total: pagination.total,
         }"
+        :isShowSummary="true"
+        :summaryMethod="summaryMethod"
         @pagination="changePage"
       ></PIMTable>
     </div>
@@ -30,6 +32,7 @@
 import { usePaginationApi } from "@/hooks/usePaginationApi";
 import { getPurchaseList } from "@/api/procurementManagement/projectProfit";
 import { onMounted } from "vue";
+import { summarizeTable } from "@/utils/summarizeTable";
 
 defineOptions({
   name: "椤圭洰鍒╂鼎",
@@ -98,6 +101,14 @@
   onCurrentChange(page);
 };
 
+// 鍚堣鏂规硶
+const summaryMethod = (param) => {
+  return summarizeTable(
+    param,
+    ['contractAmount', 'purchaseAmount', 'balance', 'balanceAmount', 'balanceRatio'],
+  );
+};
+
 onMounted(() => {
   getTableData();
 });
diff --git a/src/views/salesManagement/invoiceLedger/index.vue b/src/views/salesManagement/invoiceLedger/index.vue
index 91900fd..4e8c274 100644
--- a/src/views/salesManagement/invoiceLedger/index.vue
+++ b/src/views/salesManagement/invoiceLedger/index.vue
@@ -27,7 +27,7 @@
     </div>
     <div class="table_list">
       <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
-        :row-key="(row) => row.id" show-summary :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)">
+        :row-key="(row) => row.id" show-summary :summary-method="summarizeMainTable" height="calc(100vh - 18.5em)" stripe>
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
         <el-table-column label="閿�鍞悎鍚屽彿" prop="salesContractNo" show-overflow-tooltip width="180" />
@@ -43,7 +43,7 @@
         <el-table-column label="褰曞叆浜�" prop="invoicePerson" show-overflow-tooltip />
         <el-table-column label="褰曞叆鏃ユ湡" prop="createTime" show-overflow-tooltip :formatter="formatDate" width="180" />
         <el-table-column label="寮�绁ㄦ棩鏈�" prop="invoiceDate" show-overflow-tooltip width="120" />
-        <el-table-column label="鍙戠エ" prop="invoiceFileName" width="120" align="center" show-overflow-tooltip>
+        <el-table-column label="鍙戠エ" prop="invoiceFileName" width="120" align="center" show-overflow-tooltip fixed="right">
           <template #default="scope">
             <el-button v-if="scope.row.invoiceFileName" text bg type="primary"
               @click="handleFile(scope.row.commonFiles)">
@@ -296,8 +296,8 @@
 function handleBeforeUpload(file) {
   console.log("file", file);
   // 鏍℃鏂囦欢澶у皬
-  if (file.size > 1024 * 1024 * 10) {
-    proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃10MB!");
+  if (file.size > 1024 * 1024 * 50) {
+    proxy.$modal.msgError("涓婁紶鏂囦欢澶у皬涓嶈兘瓒呰繃50MB!");
     return false;
   }
   // 鍒ゆ柇鏂囦欢鏍煎紡鏄惁绗﹀悎
diff --git a/src/views/salesManagement/invoiceRegistration/index.vue b/src/views/salesManagement/invoiceRegistration/index.vue
index 8ceea47..9d39684 100644
--- a/src/views/salesManagement/invoiceRegistration/index.vue
+++ b/src/views/salesManagement/invoiceRegistration/index.vue
@@ -33,6 +33,12 @@
             @change="handleQuery"
           />
         </el-form-item>
+        <br/>
+        <el-form-item label="鍚堝悓褰曞叆鏃ユ湡">
+          <el-date-picker style="width: 240px" v-model="searchForm.commonDate" value-format="YYYY-MM-DD"
+                          format="YYYY-MM-DD" type="daterange" start-placeholder="寮�濮嬫椂闂�" end-placeholder="缁撴潫鏃堕棿" clearable
+                          @change="changeDateRange" @clear="clearRange" />
+        </el-form-item>
         <el-form-item>
           <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
           <el-button @click="resetForm"> 閲嶇疆 </el-button>
@@ -57,6 +63,7 @@
         :summary-method="summarizeMainTable"
         @expand-change="expandChange"
         @selection-change="handleSelectionChange"
+        stripe
       >
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column type="expand">
@@ -66,6 +73,7 @@
               border
               show-summary
               :summary-method="summarizeChildrenTable"
+              stripe
             >
               <el-table-column
                 align="center"
@@ -121,6 +129,7 @@
           </template>
         </el-table-column>
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+        <el-table-column label="鍚堝悓褰曞叆鏃ユ湡" prop="entryDate" width="120" />
         <el-table-column
           label="閿�鍞悎鍚屽彿"
           prop="salesContractNo"
@@ -461,6 +470,21 @@
 const { form, rules } = toRefs(data);
 const { form: searchForm, resetForm } = useFormData(data.searchForm);
 
+
+const changeDateRange = (date) => {
+  if (date) {
+    searchForm.entryDateStart = date[0];
+    searchForm.entryDateEnd = date[1];
+    getList();
+  }
+};
+
+const clearRange = () => {
+  searchForm.commonDate = [];
+  searchForm.entryDateStart = undefined;
+  searchForm.entryDateEnd = undefined;
+  getList();
+};
 const formattedNumber = (row, column, cellValue) => {
   if (cellValue == 0) {
     return parseFloat(cellValue).toFixed(2);
@@ -557,6 +581,7 @@
   getSalesLedgerWithProducts({ id: selectedRows.value[0].id }).then((res) => {
     form.value = { ...res };
     form.value.createTime = dayjs().format("YYYY-MM-DD");
+    form.value.issueDate = dayjs().format("YYYY-MM-DD");
     form.value.createUer = userStore.nickName;
     productData.value = form.value.productData.map((item) => {
       return item;
diff --git a/src/views/salesManagement/receiptPayment/index.vue b/src/views/salesManagement/receiptPayment/index.vue
index f72e546..b37ab85 100644
--- a/src/views/salesManagement/receiptPayment/index.vue
+++ b/src/views/salesManagement/receiptPayment/index.vue
@@ -38,6 +38,12 @@
                 @change="handleQuery"
               />
             </el-form-item>
+            <br/>
+            <el-form-item label="寮�绁ㄦ棩鏈�">
+              <el-date-picker style="width: 240px" v-model="searchForm.commonDate" value-format="YYYY-MM-DD"
+                              format="YYYY-MM-DD" type="daterange" start-placeholder="寮�濮嬫椂闂�" end-placeholder="缁撴潫鏃堕棿" clearable
+                              @change="changeDateRange" @clear="clearRange" />
+            </el-form-item>
             <el-form-item>
               <el-button type="primary" @click="handleQuery"> 鎼滅储 </el-button>
             </el-form-item>
@@ -65,7 +71,7 @@
         :summary-method="summarizeMainTable"
         :expand-row-keys="expandedRowKeys"
         @expand-change="expandChange"
-
+        stripe
         height="calc(100vh - 21.5em)"
       >
         <el-table-column align="center" type="selection" width="55" />
@@ -76,6 +82,7 @@
               border
               show-summary
               :summary-method="summarizeChildrenTable"
+              stripe
             >
               <el-table-column
                 align="center"
@@ -148,6 +155,12 @@
           </template>
         </el-table-column>
         <el-table-column align="center" label="搴忓彿" type="index" width="60" />
+        <el-table-column
+            label="寮�绁ㄦ棩鏈�"
+            prop="invoiceDate"
+            show-overflow-tooltip
+            width="240"
+        />
         <el-table-column
           label="閿�鍞悎鍚屽彿"
           prop="salesContractNo"
@@ -426,6 +439,21 @@
 const formattedNumber = (row, column, cellValue) => {
   return parseFloat(cellValue).toFixed(2);
 };
+
+const changeDateRange = (date) => {
+  if (date) {
+    searchForm.invoiceDateStart = date[0];
+    searchForm.invoiceDateEnd = date[1];
+    getList();
+  }
+};
+
+const clearRange = () => {
+  searchForm.commonDate = [];
+  searchForm.invoiceDateStart = undefined;
+  searchForm.invoiceDateEnd = undefined;
+  getList();
+};
 // 鏌ヨ鍒楄〃
 /** 鎼滅储鎸夐挳鎿嶄綔 */
 const handleQuery = () => {
@@ -514,7 +542,7 @@
     return;
   }
   if (selectedRows.value[0].noReceiptAmount == 0) {
-    proxy.$modal.warning("鏃犻渶鍐嶅洖娆�");
+    proxy.$modal.msgWarning("鏃犻渶鍐嶅洖娆�");
     return;
   }
   invoiceInfo({ id: selectedRows.value[0].id }).then((res) => {
diff --git a/src/views/salesManagement/receiptPaymentLedger/index.vue b/src/views/salesManagement/receiptPaymentLedger/index.vue
index 2cec625..3a4af2e 100644
--- a/src/views/salesManagement/receiptPaymentLedger/index.vue
+++ b/src/views/salesManagement/receiptPaymentLedger/index.vue
@@ -27,6 +27,7 @@
           :summary-method="summarizeMainTable"
           @row-click="rowClickMethod"
           height="calc(100vh - 18.5em)"
+          stripe
         >
           <el-table-column
             align="center"
@@ -81,6 +82,7 @@
           :data="receiptRecord"
           border
           :row-key="(row) => row.id"
+          stripe
           show-summary
           :summary-method="summarizeMainTable1"
           height="calc(100vh - 18.5em)"
diff --git a/src/views/salesManagement/salesLedger/fileList.vue b/src/views/salesManagement/salesLedger/fileList.vue
index da37db2..e9e3b87 100644
--- a/src/views/salesManagement/salesLedger/fileList.vue
+++ b/src/views/salesManagement/salesLedger/fileList.vue
@@ -1,6 +1,6 @@
 <template>
   <el-dialog v-model="dialogVisible" title="闄勪欢" width="40%" :before-close="handleClose">
-    <el-table :data="tableData" border height="40vh">
+    <el-table :data="tableData" border height="40vh" stripe>
       <el-table-column label="闄勪欢鍚嶇О" prop="name" min-width="400" show-overflow-tooltip />
       <el-table-column fixed="right" label="鎿嶄綔" width="100" align="center">
         <template #default="scope">
diff --git a/src/views/salesManagement/salesLedger/index.vue b/src/views/salesManagement/salesLedger/index.vue
index afe56b5..ed8d43d 100644
--- a/src/views/salesManagement/salesLedger/index.vue
+++ b/src/views/salesManagement/salesLedger/index.vue
@@ -40,11 +40,11 @@
       </div>
       <el-table :data="tableData" border v-loading="tableLoading" @selection-change="handleSelectionChange"
         :expand-row-keys="expandedRowKeys" :row-key="(row) => row.id" show-summary style="width: 100%"
-        :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)">
+        :summary-method="summarizeMainTable" @expand-change="expandChange" height="calc(100vh - 18.5em)" stripe>
         <el-table-column align="center" type="selection" width="55" />
         <el-table-column type="expand">
           <template #default="props">
-            <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable">
+            <el-table :data="props.row.children" border show-summary :summary-method="summarizeChildrenTable" stripe>
               <el-table-column align="center" label="搴忓彿" type="index" width="60" />
               <el-table-column label="浜у搧澶х被" prop="productCategory" />
               <el-table-column label="瑙勬牸鍨嬪彿" prop="specificationModel" />
@@ -66,6 +66,14 @@
         <el-table-column label="浠樻鏂瑰紡" prop="paymentMethod" show-overflow-tooltip />
         <el-table-column label="鍚堝悓閲戦(鍏�)" prop="contractAmount" width="220" show-overflow-tooltip
           :formatter="formattedNumber" />
+        <el-table-column label="宸插紑绁ㄩ噾棰�(鍏�)" prop="invoiceTotal" width="220" show-overflow-tooltip
+                         :formatter="formattedNumber" />
+        <el-table-column label="鏈紑绁ㄩ噾棰�(鍏�)" prop="noInvoiceAmountTotal" width="220" show-overflow-tooltip
+                         :formatter="formattedNumber" />
+        <el-table-column label="鍥炴閲戦(鍏�)" prop="receiptPaymentAmountTotal" width="220" show-overflow-tooltip
+                         :formatter="formattedNumber" />
+        <el-table-column label="寰呭洖娆鹃噾棰�(鍏�)" prop="noReceiptAmount" width="220" show-overflow-tooltip
+                         :formatter="formattedNumber" />
         <el-table-column label="褰曞叆浜�" prop="entryPersonName" width="100" show-overflow-tooltip />
         <el-table-column label="褰曞叆鏃ユ湡" prop="entryDate" width="120" show-overflow-tooltip />
         <el-table-column label="绛捐鏃ユ湡" prop="executionDate" width="120" show-overflow-tooltip />
@@ -157,7 +165,7 @@
             <el-button v-if="operationType !== 'view'" plain type="danger" @click="deleteProduct" >鍒犻櫎</el-button>
           </el-form-item>
         </el-row>
-        <el-table :data="productData" border @selection-change="productSelected" show-summary
+        <el-table :data="productData" border @selection-change="productSelected" show-summary stripe
           :summary-method="summarizeMainTable">
           <el-table-column align="center" type="selection" width="55" v-if="operationType !== 'view'" />
           <el-table-column align="center" label="搴忓彿" type="index" width="60" />
@@ -556,6 +564,10 @@
     "contractAmount",
     "taxInclusiveTotalPrice",
     "taxExclusiveTotalPrice",
+		'invoiceTotal',
+		'noInvoiceAmountTotal',
+		'receiptPaymentAmountTotal',
+		'noReceiptAmount',
   ]);
 };
 // 瀛愯〃鍚堣鏂规硶
diff --git a/src/views/system/config/index.vue b/src/views/system/config/index.vue
index 77d9f5a..9dd220d 100644
--- a/src/views/system/config/index.vue
+++ b/src/views/system/config/index.vue
@@ -96,7 +96,7 @@
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
       </el-row>
 
-      <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange">
+      <el-table v-loading="loading" :data="configList" @selection-change="handleSelectionChange" stripe>
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="鍙傛暟涓婚敭" align="center" prop="configId" />
          <el-table-column label="鍙傛暟鍚嶇О" align="center" prop="configName" :show-overflow-tooltip="true" />
diff --git a/src/views/system/dept/index.vue b/src/views/system/dept/index.vue
index 0a0532a..8d7a26b 100644
--- a/src/views/system/dept/index.vue
+++ b/src/views/system/dept/index.vue
@@ -1,17 +1,17 @@
 <template>
    <div class="app-container">
       <el-form :model="queryParams" ref="queryRef" :inline="true" v-show="showSearch">
-         <el-form-item label="閮ㄩ棬鍚嶇О" prop="deptName">
+         <el-form-item label="鍏徃鍚嶇О" prop="deptName">
             <el-input
                v-model="queryParams.deptName"
-               placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�"
+               placeholder="璇疯緭鍏ュ叕鍙稿悕绉�"
                clearable
                style="width: 200px"
                @keyup.enter="handleQuery"
             />
          </el-form-item>
          <el-form-item label="鐘舵��" prop="status">
-            <el-select v-model="queryParams.status" placeholder="閮ㄩ棬鐘舵��" clearable style="width: 200px">
+            <el-select v-model="queryParams.status" placeholder="鍏徃鐘舵��" clearable style="width: 200px">
                <el-option
                   v-for="dict in sys_normal_disable"
                   :key="dict.value"
@@ -54,8 +54,9 @@
          row-key="deptId"
          :default-expand-all="isExpandAll"
          :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
+         stripe
       >
-         <el-table-column prop="deptName" label="閮ㄩ棬鍚嶇О" width="260"></el-table-column>
+         <el-table-column prop="deptName" label="鍏徃鍚嶇О" width="260"></el-table-column>
          <el-table-column prop="orderNum" label="鎺掑簭" width="200"></el-table-column>
          <el-table-column prop="status" label="鐘舵��" width="100">
             <template #default="scope">
@@ -76,25 +77,25 @@
          </el-table-column>
       </el-table>
 
-      <!-- 娣诲姞鎴栦慨鏀归儴闂ㄥ璇濇 -->
+      <!-- 娣诲姞鎴栦慨鏀瑰叕鍙稿璇濇 -->
       <el-dialog :title="title" v-model="open" width="600px" append-to-body>
          <el-form ref="deptRef" :model="form" :rules="rules" label-width="80px">
             <el-row>
                <el-col :span="24" v-if="form.parentId !== 0">
-                  <el-form-item label="涓婄骇閮ㄩ棬" prop="parentId">
+                  <el-form-item label="涓婄骇鍏徃" prop="parentId">
                      <el-tree-select
                         v-model="form.parentId"
                         :data="deptOptions"
                         :props="{ value: 'deptId', label: 'deptName', children: 'children' }"
                         value-key="deptId"
-                        placeholder="閫夋嫨涓婄骇閮ㄩ棬"
+                        placeholder="閫夋嫨涓婄骇鍏徃"
                         check-strictly
                      />
                   </el-form-item>
                </el-col>
                <el-col :span="12">
-                  <el-form-item label="閮ㄩ棬鍚嶇О" prop="deptName">
-                     <el-input v-model="form.deptName" placeholder="璇疯緭鍏ラ儴闂ㄥ悕绉�" />
+                  <el-form-item label="鍏徃鍚嶇О" prop="deptName">
+                     <el-input v-model="form.deptName" placeholder="璇疯緭鍏ュ叕鍙稿悕绉�" />
                   </el-form-item>
                </el-col>
                <el-col :span="12">
@@ -118,7 +119,7 @@
                   </el-form-item>
                </el-col>
                <el-col :span="12">
-                  <el-form-item label="閮ㄩ棬鐘舵��">
+                  <el-form-item label="鍏徃鐘舵��">
                      <el-radio-group v-model="form.status">
                         <el-radio
                            v-for="dict in sys_normal_disable"
@@ -129,8 +130,8 @@
                   </el-form-item>
                </el-col>
               <el-col :span="12">
-                <el-form-item label="閮ㄩ棬缂栧彿" prop="deptNick">
-                  <el-input v-model="form.deptNick" placeholder="璇疯緭鍏ラ儴闂ㄧ紪鍙�" maxlength="50" />
+                <el-form-item label="鍏徃缂栧彿" prop="deptNick">
+                  <el-input v-model="form.deptNick" placeholder="璇疯緭鍏ュ叕鍙哥紪鍙�" maxlength="50" />
                 </el-form-item>
               </el-col>
             </el-row>
@@ -167,18 +168,18 @@
     status: undefined
   },
   rules: {
-    parentId: [{ required: true, message: "涓婄骇閮ㄩ棬涓嶈兘涓虹┖", trigger: "blur" }],
-    deptName: [{ required: true, message: "閮ㄩ棬鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
+    parentId: [{ required: true, message: "涓婄骇鍏徃涓嶈兘涓虹┖", trigger: "blur" }],
+    deptName: [{ required: true, message: "鍏徃鍚嶇О涓嶈兘涓虹┖", trigger: "blur" }],
     orderNum: [{ required: true, message: "鏄剧ず鎺掑簭涓嶈兘涓虹┖", trigger: "blur" }],
     email: [{ type: "email", message: "璇疯緭鍏ユ纭殑閭鍦板潃", trigger: ["blur", "change"] }],
     phone: [{ pattern: /^1[3|4|5|6|7|8|9][0-9]\d{8}$/, message: "璇疯緭鍏ユ纭殑鎵嬫満鍙风爜", trigger: "blur" }],
-    deptNick: [{ required: true, message: "閮ㄩ棬缂栧彿涓嶈兘涓虹┖", trigger: "blur" }],
+    deptNick: [{ required: true, message: "鍏徃缂栧彿涓嶈兘涓虹┖", trigger: "blur" }],
   },
 })
 
 const { queryParams, form, rules } = toRefs(data)
 
-/** 鏌ヨ閮ㄩ棬鍒楄〃 */
+/** 鏌ヨ鍏徃鍒楄〃 */
 function getList() {
   loading.value = true
   listDept(queryParams.value).then(response => {
@@ -230,7 +231,7 @@
     form.value.parentId = row.deptId
   }
   open.value = true
-  title.value = "娣诲姞閮ㄩ棬"
+  title.value = "娣诲姞鍏徃"
 }
 
 /** 灞曞紑/鎶樺彔鎿嶄綔 */
@@ -251,7 +252,7 @@
   getDept(row.deptId).then(response => {
     form.value = response.data
     open.value = true
-    title.value = "淇敼閮ㄩ棬"
+    title.value = "淇敼鍏徃"
   })
 }
 
diff --git a/src/views/system/dict/data.vue b/src/views/system/dict/data.vue
index f4e2c6f..23ca2a9 100644
--- a/src/views/system/dict/data.vue
+++ b/src/views/system/dict/data.vue
@@ -86,7 +86,7 @@
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
       </el-row>
 
-      <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange">
+      <el-table v-loading="loading" :data="dataList" @selection-change="handleSelectionChange" stripe>
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="瀛楀吀缂栫爜" align="center" prop="dictCode" />
          <el-table-column label="瀛楀吀鏍囩" align="center" prop="dictLabel">
diff --git a/src/views/system/dict/index.vue b/src/views/system/dict/index.vue
index 6c67e1b..98ac047 100644
--- a/src/views/system/dict/index.vue
+++ b/src/views/system/dict/index.vue
@@ -101,7 +101,7 @@
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
       </el-row>
 
-      <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange">
+      <el-table v-loading="loading" :data="typeList" @selection-change="handleSelectionChange" stripe>
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="瀛楀吀缂栧彿" align="center" prop="dictId" />
          <el-table-column label="瀛楀吀鍚嶇О" align="center" prop="dictName" :show-overflow-tooltip="true"/>
diff --git a/src/views/system/menu/index.vue b/src/views/system/menu/index.vue
index bccb9e9..2257fb0 100644
--- a/src/views/system/menu/index.vue
+++ b/src/views/system/menu/index.vue
@@ -51,6 +51,7 @@
          v-if="refreshTable"
          v-loading="loading"
          :data="menuList"
+         stripe
          row-key="menuId"
          :default-expand-all="isExpandAll"
          :tree-props="{ children: 'children', hasChildren: 'hasChildren' }"
diff --git a/src/views/system/notice/index.vue b/src/views/system/notice/index.vue
index 8043db0..76ddd05 100644
--- a/src/views/system/notice/index.vue
+++ b/src/views/system/notice/index.vue
@@ -68,7 +68,7 @@
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
       </el-row>
 
-      <el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange">
+      <el-table v-loading="loading" :data="noticeList" @selection-change="handleSelectionChange" stripe>
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="搴忓彿" align="center" prop="noticeId" width="100" />
          <el-table-column
diff --git a/src/views/system/post/index.vue b/src/views/system/post/index.vue
index 0e80652..39f807f 100644
--- a/src/views/system/post/index.vue
+++ b/src/views/system/post/index.vue
@@ -77,7 +77,7 @@
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
       </el-row>
 
-      <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange">
+      <el-table v-loading="loading" :data="postList" @selection-change="handleSelectionChange" stripe>
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="宀椾綅缂栧彿" align="center" prop="postId" />
          <el-table-column label="宀椾綅缂栫爜" align="center" prop="postCode" />
diff --git a/src/views/system/role/authUser.vue b/src/views/system/role/authUser.vue
index a460f3c..86243db 100644
--- a/src/views/system/role/authUser.vue
+++ b/src/views/system/role/authUser.vue
@@ -57,7 +57,7 @@
          <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar>
       </el-row>
 
-      <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange">
+      <el-table v-loading="loading" :data="userList" @selection-change="handleSelectionChange" stripe>
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="鐢ㄦ埛鍚嶇О" prop="userName" :show-overflow-tooltip="true" />
          <el-table-column label="鐢ㄦ埛鏄电О" prop="nickName" :show-overflow-tooltip="true" />
diff --git a/src/views/system/role/index.vue b/src/views/system/role/index.vue
index d960674..a32ab4a 100644
--- a/src/views/system/role/index.vue
+++ b/src/views/system/role/index.vue
@@ -92,7 +92,7 @@
       </el-row>
 
       <!-- 琛ㄦ牸鏁版嵁 -->
-      <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange">
+      <el-table v-loading="loading" :data="roleList" @selection-change="handleSelectionChange" stripe>
          <el-table-column type="selection" width="55" align="center" />
          <el-table-column label="瑙掕壊缂栧彿" prop="roleId" width="120" />
          <el-table-column label="瑙掕壊鍚嶇О" prop="roleName" :show-overflow-tooltip="true" width="150" />
diff --git a/src/views/system/role/selectUser.vue b/src/views/system/role/selectUser.vue
index 3e3d8aa..193c9a5 100644
--- a/src/views/system/role/selectUser.vue
+++ b/src/views/system/role/selectUser.vue
@@ -26,7 +26,7 @@
          </el-form-item>
       </el-form>
       <el-row>
-         <el-table @row-click="clickRow" ref="refTable" :data="userList" @selection-change="handleSelectionChange" height="260px">
+         <el-table @row-click="clickRow" ref="refTable" :data="userList" @selection-change="handleSelectionChange" height="260px" stripe>
             <el-table-column type="selection" width="55"></el-table-column>
             <el-table-column label="鐢ㄦ埛鍚嶇О" prop="userName" :show-overflow-tooltip="true" />
             <el-table-column label="鐢ㄦ埛鏄电О" prop="nickName" :show-overflow-tooltip="true" />
diff --git a/src/views/system/user/authRole.vue b/src/views/system/user/authRole.vue
index 3935ab1..85a6f1b 100644
--- a/src/views/system/user/authRole.vue
+++ b/src/views/system/user/authRole.vue
@@ -17,7 +17,7 @@
       </el-form>
 
       <h4 class="form-header h4">瑙掕壊淇℃伅</h4>
-      <el-table v-loading="loading" :row-key="getRowKey" @row-click="clickRow" ref="roleRef" @selection-change="handleSelectionChange" :data="roles.slice((pageNum - 1) * pageSize, pageNum * pageSize)">
+      <el-table v-loading="loading" :row-key="getRowKey" @row-click="clickRow" ref="roleRef" @selection-change="handleSelectionChange" :data="roles.slice((pageNum - 1) * pageSize, pageNum * pageSize)" stripe>
          <el-table-column label="搴忓彿" width="55" type="index" align="center">
             <template #default="scope">
                <span>{{ (pageNum - 1) * pageSize + scope.$index + 1 }}</span>
diff --git a/src/views/system/user/index.vue b/src/views/system/user/index.vue
index 40fb371..04adf59 100644
--- a/src/views/system/user/index.vue
+++ b/src/views/system/user/index.vue
@@ -157,6 +157,7 @@
               v-loading="loading"
               :data="userList"
               @selection-change="handleSelectionChange"
+              stripe
             >
               <el-table-column type="selection" width="50" align="center" />
               <el-table-column
diff --git a/src/views/tool/gen/editTable.vue b/src/views/tool/gen/editTable.vue
index 874fc94..59aa03d 100644
--- a/src/views/tool/gen/editTable.vue
+++ b/src/views/tool/gen/editTable.vue
@@ -5,7 +5,7 @@
         <basic-info-form ref="basicInfo" :info="info" />
       </el-tab-pane>
       <el-tab-pane label="瀛楁淇℃伅" name="columnInfo">
-        <el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight">
+        <el-table ref="dragTable" :data="columns" row-key="columnId" :max-height="tableHeight" stripe>
           <el-table-column label="搴忓彿" type="index" min-width="5%"/>
           <el-table-column
             label="瀛楁鍒楀悕"
diff --git a/src/views/tool/gen/importTable.vue b/src/views/tool/gen/importTable.vue
index 23dbf28..ea2ebef 100644
--- a/src/views/tool/gen/importTable.vue
+++ b/src/views/tool/gen/importTable.vue
@@ -26,7 +26,7 @@
       </el-form-item>
     </el-form>
     <el-row>
-      <el-table @row-click="clickRow" ref="table" :data="dbTableList" @selection-change="handleSelectionChange" height="260px">
+      <el-table @row-click="clickRow" ref="table" :data="dbTableList" @selection-change="handleSelectionChange" height="260px" stripe>
         <el-table-column type="selection" width="55"></el-table-column>
         <el-table-column prop="tableName" label="琛ㄥ悕绉�" :show-overflow-tooltip="true"></el-table-column>
         <el-table-column prop="tableComment" label="琛ㄦ弿杩�" :show-overflow-tooltip="true"></el-table-column>
diff --git a/src/views/tool/gen/index.vue b/src/views/tool/gen/index.vue
index aaddeb6..4930cef 100644
--- a/src/views/tool/gen/index.vue
+++ b/src/views/tool/gen/index.vue
@@ -106,6 +106,7 @@
       ref="genRef"
       v-loading="loading"
       :data="tableList"
+      stripe
       @selection-change="handleSelectionChange"
       :default-sort="defaultSort"
       @sort-change="handleSortChange"

--
Gitblit v1.9.3