From f49bfd6c085cbf28a25d9404f8dc5b74368b716a Mon Sep 17 00:00:00 2001
From: gaoluyang <2820782392@qq.com>
Date: 星期五, 29 五月 2026 15:54:02 +0800
Subject: [PATCH] 新疆马铃薯 1.代码更新

---
 multiple/config.json                                                             |  177 -
 src/views/equipmentManagement/upkeep/Form/PlanModal.vue                          |  274 +
 src/api/equipmentManagement/upkeep.js                                            |    9 
 multiple/assets/favicon/favicon.ico                                              |    0 
 src/api/inspectionManagement/index.js                                            |   11 
 src/views/equipmentManagement/calibration/index.vue                              |    2 
 public/favicon.ico                                                               |    0 
 src/views/equipmentManagement/ledger/index.vue                                   |  726 ++++--
 vite.config.js                                                                   |    2 
 multiple/assets/logo/Logo.png                                                    |    0 
 src/views/equipmentManagement/upkeep/index.vue                                   | 1182 ++++++-----
 src/views/equipmentManagement/operationManagement/index.vue                      |  132 -
 src/views/equipmentManagement/spareParts/index.vue                               |    2 
 multiple/multiple-build.js                                                       |  188 -
 src/views/equipmentManagement/repair/Modal/RepairModal.vue                       |  506 ++--
 src/views/equipmentManagement/defectManagement/index.vue                         |    2 
 src/views/equipmentManagement/repair/index.vue                                   |  463 ++--
 src/views/equipmentManagement/brand/index.vue                                    |    2 
 src/views/equipmentManagement/inspectionManagement/index.vue                     |  855 ++++---
 src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue |   33 
 src/api/equipmentManagement/measurementEquipment.js                              |   27 
 src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue      |  360 +-
 /dev/null                                                                        |  144 -
 src/api/equipmentManagement/repair.js                                            |   13 
 src/views/equipmentManagement/measurementEquipment/index.vue                     |  614 ++---
 src/views/equipmentManagement/ledger/Modal.vue                                   |    7 
 src/api/equipmentManagement/deviceArea.js                                        |   55 
 src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue                   |  361 +-
 28 files changed, 3,120 insertions(+), 3,027 deletions(-)

diff --git a/multiple/assets/favicon/BTYXfavicon.ico b/multiple/assets/favicon/BTYXfavicon.ico
deleted file mode 100644
index 8da0f2a..0000000
--- a/multiple/assets/favicon/BTYXfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/BWSMfavicon.ico b/multiple/assets/favicon/BWSMfavicon.ico
deleted file mode 100644
index 12c7cd0..0000000
--- a/multiple/assets/favicon/BWSMfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/CKGMfavicon.ico b/multiple/assets/favicon/CKGMfavicon.ico
deleted file mode 100644
index 7668e42..0000000
--- a/multiple/assets/favicon/CKGMfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/DYKJfavicon.ico b/multiple/assets/favicon/DYKJfavicon.ico
deleted file mode 100644
index 8437010..0000000
--- a/multiple/assets/favicon/DYKJfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/DZZBfavicon.ico b/multiple/assets/favicon/DZZBfavicon.ico
deleted file mode 100644
index 63bf216..0000000
--- a/multiple/assets/favicon/DZZBfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/HQJCfavicon.ico b/multiple/assets/favicon/HQJCfavicon.ico
deleted file mode 100644
index 65e6942..0000000
--- a/multiple/assets/favicon/HQJCfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/HYJCfavicon.ico b/multiple/assets/favicon/HYJCfavicon.ico
deleted file mode 100644
index e52f096..0000000
--- a/multiple/assets/favicon/HYJCfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/HYLQfavicon.ico b/multiple/assets/favicon/HYLQfavicon.ico
deleted file mode 100644
index 9a2dbf3..0000000
--- a/multiple/assets/favicon/HYLQfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/HYZCfavicon.ico b/multiple/assets/favicon/HYZCfavicon.ico
deleted file mode 100644
index 996ab43..0000000
--- a/multiple/assets/favicon/HYZCfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/JHHGfavicon.ico b/multiple/assets/favicon/JHHGfavicon.ico
deleted file mode 100644
index 54bbe64..0000000
--- a/multiple/assets/favicon/JHHGfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/JHYfavicon.ico b/multiple/assets/favicon/JHYfavicon.ico
deleted file mode 100644
index f818f6f..0000000
--- a/multiple/assets/favicon/JHYfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/JXJHfavicon.ico b/multiple/assets/favicon/JXJHfavicon.ico
deleted file mode 100644
index 0c90589..0000000
--- a/multiple/assets/favicon/JXJHfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/JXSMico.ico b/multiple/assets/favicon/JXSMico.ico
deleted file mode 100644
index f5681e8..0000000
--- a/multiple/assets/favicon/JXSMico.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/KSfavicon.ico b/multiple/assets/favicon/KSfavicon.ico
deleted file mode 100644
index 57ebd54..0000000
--- a/multiple/assets/favicon/KSfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/KYHGfavicon.ico b/multiple/assets/favicon/KYHGfavicon.ico
deleted file mode 100644
index 8178896..0000000
--- a/multiple/assets/favicon/KYHGfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/LFJZfavicon.ico b/multiple/assets/favicon/LFJZfavicon.ico
deleted file mode 100644
index 9f2b565..0000000
--- a/multiple/assets/favicon/LFJZfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/QXYfavicon.ico b/multiple/assets/favicon/QXYfavicon.ico
deleted file mode 100644
index e56847e..0000000
--- a/multiple/assets/favicon/QXYfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/SDJCfavicon.ico b/multiple/assets/favicon/SDJCfavicon.ico
deleted file mode 100644
index 5e80af3..0000000
--- a/multiple/assets/favicon/SDJCfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/SDTXfavicon.ico b/multiple/assets/favicon/SDTXfavicon.ico
deleted file mode 100644
index 6e84a60..0000000
--- a/multiple/assets/favicon/SDTXfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/WTXCfavicon.ico b/multiple/assets/favicon/WTXCfavicon.ico
deleted file mode 100644
index ce783dc..0000000
--- a/multiple/assets/favicon/WTXCfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/XCDQfavicon.ico b/multiple/assets/favicon/XCDQfavicon.ico
deleted file mode 100644
index 69a2280..0000000
--- a/multiple/assets/favicon/XCDQfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/XLZBico.ico b/multiple/assets/favicon/XLZBico.ico
deleted file mode 100644
index 63ff233..0000000
--- a/multiple/assets/favicon/XLZBico.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/XSWHfavicon.ico b/multiple/assets/favicon/XSWHfavicon.ico
deleted file mode 100644
index f6cd72d..0000000
--- a/multiple/assets/favicon/XSWHfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/YSJXico.ico b/multiple/assets/favicon/YSJXico.ico
deleted file mode 100644
index ce3c0c3..0000000
--- a/multiple/assets/favicon/YSJXico.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/YTJZfavicon.ico b/multiple/assets/favicon/YTJZfavicon.ico
deleted file mode 100644
index ad7b03b..0000000
--- a/multiple/assets/favicon/YTJZfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/ZQSYfavicon.ico b/multiple/assets/favicon/ZQSYfavicon.ico
deleted file mode 100644
index 9e3422f..0000000
--- a/multiple/assets/favicon/ZQSYfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/ZXZNfavicon.ico b/multiple/assets/favicon/ZXZNfavicon.ico
deleted file mode 100644
index 73bc9dd..0000000
--- a/multiple/assets/favicon/ZXZNfavicon.ico
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/favicon/favicon.ico b/multiple/assets/favicon/favicon.ico
index 2fa05d5..0e02f96 100644
--- a/multiple/assets/favicon/favicon.ico
+++ b/multiple/assets/favicon/favicon.ico
Binary files differ
diff --git a/multiple/assets/logo/BTYXLogo.png b/multiple/assets/logo/BTYXLogo.png
deleted file mode 100644
index 0890259..0000000
--- a/multiple/assets/logo/BTYXLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/BWSMLogo.png b/multiple/assets/logo/BWSMLogo.png
deleted file mode 100644
index 044d31c..0000000
--- a/multiple/assets/logo/BWSMLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/CKGMLogo.png b/multiple/assets/logo/CKGMLogo.png
deleted file mode 100644
index cfa60b2..0000000
--- a/multiple/assets/logo/CKGMLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/DYKJLogo.png b/multiple/assets/logo/DYKJLogo.png
deleted file mode 100644
index b96b61c..0000000
--- a/multiple/assets/logo/DYKJLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/DZZBLogo.png b/multiple/assets/logo/DZZBLogo.png
deleted file mode 100644
index 5b3f56b..0000000
--- a/multiple/assets/logo/DZZBLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/HQJCLogo.png b/multiple/assets/logo/HQJCLogo.png
deleted file mode 100644
index 5e21e9c..0000000
--- a/multiple/assets/logo/HQJCLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/HYJCLogo.png b/multiple/assets/logo/HYJCLogo.png
deleted file mode 100644
index 367f64d..0000000
--- a/multiple/assets/logo/HYJCLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/HYLQLogo.png b/multiple/assets/logo/HYLQLogo.png
deleted file mode 100644
index 8eda2f7..0000000
--- a/multiple/assets/logo/HYLQLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/HYZCLogo.png b/multiple/assets/logo/HYZCLogo.png
deleted file mode 100644
index e8e4cad..0000000
--- a/multiple/assets/logo/HYZCLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/JHHGLogo.png b/multiple/assets/logo/JHHGLogo.png
deleted file mode 100644
index 3373e60..0000000
--- a/multiple/assets/logo/JHHGLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/JHYLogo.png b/multiple/assets/logo/JHYLogo.png
deleted file mode 100644
index edf5921..0000000
--- a/multiple/assets/logo/JHYLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/JXJHLogo.png b/multiple/assets/logo/JXJHLogo.png
deleted file mode 100644
index 1d47288..0000000
--- a/multiple/assets/logo/JXJHLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/JXSMLogo.png b/multiple/assets/logo/JXSMLogo.png
deleted file mode 100644
index f1da7e9..0000000
--- a/multiple/assets/logo/JXSMLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/KSLogo.png b/multiple/assets/logo/KSLogo.png
deleted file mode 100644
index 39d52a0..0000000
--- a/multiple/assets/logo/KSLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/KYHGLogo.png b/multiple/assets/logo/KYHGLogo.png
deleted file mode 100644
index 0186c87..0000000
--- a/multiple/assets/logo/KYHGLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/LFJZLogo.png b/multiple/assets/logo/LFJZLogo.png
deleted file mode 100644
index 3f2fc03..0000000
--- a/multiple/assets/logo/LFJZLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/Logo.png b/multiple/assets/logo/Logo.png
index a5831b8..17e2f8d 100644
--- a/multiple/assets/logo/Logo.png
+++ b/multiple/assets/logo/Logo.png
Binary files differ
diff --git a/multiple/assets/logo/QXYLogo.png b/multiple/assets/logo/QXYLogo.png
deleted file mode 100644
index 45318ed..0000000
--- a/multiple/assets/logo/QXYLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/SDJCLogo.png b/multiple/assets/logo/SDJCLogo.png
deleted file mode 100644
index 139e398..0000000
--- a/multiple/assets/logo/SDJCLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/SDTXLogo.png b/multiple/assets/logo/SDTXLogo.png
deleted file mode 100644
index f69cf0b..0000000
--- a/multiple/assets/logo/SDTXLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/WTXCLogo.png b/multiple/assets/logo/WTXCLogo.png
deleted file mode 100644
index 0a486cd..0000000
--- a/multiple/assets/logo/WTXCLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/XCDQLogo.png b/multiple/assets/logo/XCDQLogo.png
deleted file mode 100644
index d10580a..0000000
--- a/multiple/assets/logo/XCDQLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/XLZBLogo.png b/multiple/assets/logo/XLZBLogo.png
deleted file mode 100644
index d79c119..0000000
--- a/multiple/assets/logo/XLZBLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/XSWHLogo.png b/multiple/assets/logo/XSWHLogo.png
deleted file mode 100644
index d0c32f5..0000000
--- a/multiple/assets/logo/XSWHLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/YSJXLogo.png b/multiple/assets/logo/YSJXLogo.png
deleted file mode 100644
index 945463b..0000000
--- a/multiple/assets/logo/YSJXLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/YTJZLogo.png b/multiple/assets/logo/YTJZLogo.png
deleted file mode 100644
index ea0c489..0000000
--- a/multiple/assets/logo/YTJZLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/ZQSYLogo.png b/multiple/assets/logo/ZQSYLogo.png
deleted file mode 100644
index fe865b6..0000000
--- a/multiple/assets/logo/ZQSYLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/assets/logo/ZXZNLogo.png b/multiple/assets/logo/ZXZNLogo.png
deleted file mode 100644
index 83df55b..0000000
--- a/multiple/assets/logo/ZXZNLogo.png
+++ /dev/null
Binary files differ
diff --git a/multiple/config.json b/multiple/config.json
index c5c07f9..531dc78 100644
--- a/multiple/config.json
+++ b/multiple/config.json
@@ -3,180 +3,21 @@
     "env": {
       "VITE_APP_TITLE": "鑺浜戯紙绠$悊淇℃伅绯荤粺锛�"
     },
+    "screen": "screen/PCDZView.png",
     "logo": "logo/Logo.png",
     "favicon": "favicon/favicon.ico"
   },
-  "TEST": {
+  "DLS": {
     "env": {
-      "VITE_APP_TITLE": "宸ュ巶鏁板瓧鍖朚OM绯荤粺",
-      "VITE_BASE_API": "http://1.15.17.182:9048",
-      "VITE_JAVA_API": "http://1.15.17.182:9049"
+      "VITE_APP_TITLE": "鏂扮枂澶х綏绱犻┈閾冭柉淇℃伅绠$悊",
+      "VITE_BASE_API": "http://1.15.17.182:9027",
+      "VITE_JAVA_API": "http://1.15.17.182:9026"
     },
-    "logo": "logo/XDRJ.png",
+    "screen": "screen/login-background.png",
+    "logo": "logo/Logo.png",
     "favicon": "favicon/favicon.ico"
   },
-  "BTYX": {
-    "env": {
-      "VITE_APP_TITLE": "娌冲崡甯お浼橀�夐鍝佹湁闄愬叕鍙�",
-      "VITE_BASE_API": "http://1.15.17.182:9056",
-      "VITE_JAVA_API": "http://1.15.17.182:9057"
-    },
-    "logo": "logo/BTYXLogo.png",
-    "favicon": "favicon/BTYXfavicon.ico"
-  },
-  "ZXZN": {
-    "env": {
-      "VITE_APP_TITLE": "娌冲崡鏅鸿姱鏅鸿兘鏈哄櫒浜烘湁闄愬叕鍙�",
-      "VITE_BASE_API": "http://127.0.0.1:9001",
-      "VITE_JAVA_API": "http://127.0.0.1:9000"
-    },
-    "logo": "logo/ZXZNLogo.png",
-    "favicon": "favicon/ZXZNfavicon.ico"
-  },
-  "SDTX": {
-    "env": {
-      "VITE_APP_TITLE": "娌冲崡鍠勯紟閫氫俊绉戞妧鏈夐檺鍏徃",
-      "VITE_BASE_API": "http://36.213.156.184:9001",
-      "VITE_JAVA_API": "http://36.213.156.184:9000"
-    },
-    "logo": "logo/SDTXLogo.png",
-    "favicon": "favicon/SDTXfavicon.ico"
-  },
-  "QXY": {
-    "env": {
-      "VITE_APP_TITLE": "寮轰俊瀹囩數鍣ㄧ鐞嗙郴缁�",
-      "VITE_BASE_API": "http://36.134.154.10:9001",
-      "VITE_JAVA_API": "http://36.134.154.10:9000"
-    },
-    "logo": "logo/QXYLogo.png",
-    "favicon": "favicon/QXYfavicon.ico"
-  },
-  "HQJC": {
-    "env": {
-      "VITE_APP_TITLE": "鍗庡己寤烘潗绠$悊绯荤粺",
-      "VITE_BASE_API": "http://36.134.77.64:9001",
-      "VITE_JAVA_API": "http://36.134.77.64:9000"
-    },
-    "logo": "logo/HQJCLogo.png",
-    "favicon": "favicon/HQJCfavicon.ico"
-  },
-  "XCDQ": {
-    "env": {
-      "VITE_APP_TITLE": "鏃櫒鐢靛櫒绠$悊绯荤粺",
-      "VITE_BASE_API": "http://36.133.45.183:9001",
-      "VITE_JAVA_API": "http://36.133.45.183:9002"
-    },
-    "logo": "logo/XCDQLogo.png",
-    "favicon": "favicon/XCDQfavicon.ico"
-  },
-  "BWSM": {
-    "env": {
-      "VITE_APP_TITLE": "鍏淮鍟嗚锤绠$悊绯荤粺",
-      "VITE_BASE_API": "http://1.15.17.182:9070",
-      "VITE_JAVA_API": "http://1.15.17.182:9069"
-    },
-    "logo": "logo/BWSMLogo.png",
-    "favicon": "favicon/BWSMfavicon.ico"
-  },
-  "CKGM": {
-    "env": {
-      "VITE_APP_TITLE": "瀹稿悍宸ヨ锤绠$悊绯荤粺",
-      "VITE_BASE_API": "http://1.15.17.182:9072",
-      "VITE_JAVA_API": "http://1.15.17.182:9071"
-    },
-    "logo": "logo/CKGMLogo.png",
-    "favicon": "favicon/CKGMfavicon.ico"
-  },
-  "ZQSY": {
-    "env": {
-      "VITE_APP_TITLE": "娉芥穱瀹炰笟",
-      "VITE_BASE_API": "http://36.213.128.159:9000",
-      "VITE_JAVA_API": "http://36.213.128.159:9001"
-    },
-    "logo": "logo/ZQSYLogo.png",
-    "favicon": "favicon/ZQSYfavicon.ico"
-  },
-  "JXJH": {
-    "env": {
-      "VITE_APP_TITLE": "娴氬幙姹熸捣姘存偿鍒跺搧鏈夐檺鍏徃",
-      "VITE_BASE_API": "http://36.139.201.20:9000",
-      "VITE_JAVA_API": "http://36.139.201.20:9001"
-    },
-    "logo": "logo/JXJHLogo.png",
-    "favicon": "favicon/JXJHfavicon.ico"
-  },
-  "YTJZ": {
-    "env": {
-      "VITE_APP_TITLE": "璞嘲寤虹瓚鏉愭枡鏈夐檺鍏徃",
-      "VITE_BASE_API": "http://36.139.201.181:9000",
-      "VITE_JAVA_API": "http://36.139.201.181:9001"
-    },
-    "logo": "logo/YTJZLogo.png",
-    "favicon": "favicon/YTJZfavicon.ico"
-  },
-  "HYLQ": {
-    "env": {
-      "VITE_APP_TITLE": "鑸�歌矾妗ュ伐绋嬫湁闄愬叕鍙�",
-      "VITE_BASE_API": "http://36.139.202.111:9000",
-      "VITE_JAVA_API": "http://36.139.202.111:9001"
-    },
-    "logo": "logo/HYLQLogo.png",
-    "favicon": "favicon/HYLQfavicon.ico"
-  },
-  "QXY": {
-    "env": {
-      "VITE_APP_TITLE": "寮轰俊瀹囩數鍣ㄤ簯涓绘満",
-      "VITE_BASE_API": "http://36.134.154.10:9000",
-      "VITE_JAVA_API": "http://36.134.154.10:9001"
-    },
-    "logo": "logo/QXYLogo.png",
-    "favicon": "favicon/QXYfavicon.ico"
-  },
-  "HYJC": {
-    "env": {
-      "VITE_APP_TITLE": "鎭掓磱寤烘潗",
-      "VITE_BASE_API": "http://36.138.94.178:9000",
-      "VITE_JAVA_API": "http://36.138.94.178:9001"
-    },
-    "logo": "logo/HYJCLogo.png",
-    "favicon": "favicon/HYJCfavicon.ico"
-  },
-  "JHY": {
-    "env": {
-      "VITE_APP_TITLE": "灞辫タ鐪佹绀惧幙鏅嬪拰鍥鍝佹湁闄愬叕鍙�",
-      "VITE_BASE_API": "http://223.15.233.27:9001",
-      "VITE_JAVA_API": "http://223.15.233.27:9002"
-    },
-    "logo": "logo/JHYLogo.png",
-    "favicon": "favicon/JHYfavicon.ico"
-  },
-  "XCDQ": {
-    "env": {
-      "VITE_APP_TITLE": "鏃櫒鐢靛櫒绠$悊绯荤粺",
-      "VITE_BASE_API": "http://36.133.45.183:9001",
-      "VITE_JAVA_API": "http://36.133.45.183:9002"
-    },
-    "logo": "logo/XCDQLogo.png",
-    "favicon": "favicon/XCDQfavicon.ico"
-  },
-  "KYHG": {
-    "env": {
-      "VITE_APP_TITLE": "灞辫タ鍧ゆ簮鍖栧伐鏈夐檺鍏徃",
-      "VITE_BASE_API": "http://36.137.13.29:9001",
-      "VITE_JAVA_API": "http://36.137.13.29:9002"
-    },
-    "logo": "logo/KYHGLogo.png",
-    "favicon": "favicon/KYHGfavicon.ico"
-  },
-  "JXSM": {
-    "env": {
-      "VITE_APP_TITLE": "瑗勫灒鍘挎磥閼晢璐告湁闄愬叕鍙�",
-      "VITE_BASE_API": "http://36.134.76.148:9001",
-      "VITE_JAVA_API": "http://36.134.76.148:9002"
-    },
-    "logo": "logo/JXSMLogo.png",
-    "favicon": "favicon/JXSMico.ico"
-  },
+  "screen": "/src/assets/images/login-background.png",
   "logo": "/src/assets/logo/logo.png",
   "favicon": "/public/favicon.ico"
-}
\ No newline at end of file
+}
diff --git a/multiple/multiple-build.js b/multiple/multiple-build.js
index afcd4d5..8e078e1 100644
--- a/multiple/multiple-build.js
+++ b/multiple/multiple-build.js
@@ -1,152 +1,86 @@
-import fs from "fs/promises";
-import fsSync from "fs";
-import path from "path";
-import { fileURLToPath } from "url";
+import fs from 'fs/promises';
+import fsSync from 'fs';
+import path from 'path';
+import { fileURLToPath } from 'url';
 import { execSync } from "child_process";
 
+// 鑾峰彇 __dirname
 const __filename = fileURLToPath(import.meta.url);
 const __dirname = path.dirname(__filename);
 
-const data = await fs.readFile(path.join(__dirname, "config.json"), "utf-8");
+// 璇诲彇 JSON 閰嶇疆
+const data = await fs.readFile(path.join(__dirname, 'config.json'), 'utf-8');
 const config = JSON.parse(data);
 
-const rootPath = path.resolve(__dirname, "..");
-const resourcePath = path.join(rootPath, "multiple", "assets");
-const replacePath = path.join(rootPath, "replace");
-const envFilePath = path.join(rootPath, ".env.production.local");
+// 椤圭洰璺緞
+const rootPath = path.resolve(__dirname, '..');
+const resourcePath = path.join(rootPath, 'multiple', 'assets');
+const replacePath = path.join(rootPath, 'replace');
 
+// 鑾峰彇鍛戒护琛屽弬鏁�
 const params = parseArgs(process.argv);
-const company = resolveCompany(params);
+const company = params["company"] ?? "default";
 const companyMap = config[company];
 
-if (!companyMap) {
-  const availableCompanies = Object.entries(config)
-    .filter(([, value]) => value && typeof value === "object" && value.env)
-    .map(([key]) => key)
-    .sort();
-  throw new Error(
-    `鏈煡 company: "${company}"銆傚彲閫夊��: ${availableCompanies.join(", ")}`
-  );
-}
-
-console.log(`褰撳墠 company: ${company}`);
-
-async function copyFileWithOverwrite(src, dest) {
-  await fs.mkdir(path.dirname(dest), { recursive: true });
-  if (fsSync.existsSync(dest)) {
-    try {
-      await fs.chmod(dest, 0o666);
-    } catch {
-      // Ignore chmod failure and continue.
-    }
-    await fs.rm(dest, { force: true });
-  }
-  await fs.copyFile(src, dest);
-}
+const envFilePath = path.join(process.cwd(), '.env.production.local');
 
 try {
-  console.log("=======鐢熸垚.env=======");
-  const envContent =
-    Object.entries(companyMap.env)
-      .map(([key, value]) => `${key}='${value}'`)
-      .join("\n") + "\n";
-  await fs.writeFile(envFilePath, envContent, "utf-8");
+    // 1锔忊儯 鐢熸垚 .env
+    console.log("=======鐢熸垚.env=======");
+    const envContent = Object.entries(companyMap.env)
+        .map(([key, value]) => `${key}='${value}'`)
+        .join('\n') + '\n';
+    await fs.writeFile(envFilePath, envContent, 'utf-8');
 
-  console.log("=======淇敼璧勬簮=======");
-  for (const [key] of Object.entries(companyMap)) {
-    if (key === "env") continue;
+    // 2锔忊儯 澶囦唤鍘熷璧勬簮骞舵浛鎹�
+    console.log("=======淇敼璧勬簮=======");
+    for (const [key, value] of Object.entries(companyMap)) {
+        if (key === 'env') continue;
 
-    const originFile = path.join(rootPath, config[key]);
-    const backupFile = path.join(replacePath, config[key]);
-    const replaceFile = path.join(resourcePath, companyMap[key]);
+        const originFile = path.join(rootPath, config[key]);
+        const backupFile = path.join(replacePath, config[key]);
+        const replaceFile = path.join(resourcePath, companyMap[key]);
 
-    await copyFileWithOverwrite(originFile, backupFile);
-    await copyFileWithOverwrite(replaceFile, originFile);
-  }
+        await fs.mkdir(path.dirname(backupFile), { recursive: true });
+        await fs.copyFile(originFile, backupFile);
+        await fs.copyFile(replaceFile, originFile);
+    }
 
-  console.log("=====寮�濮嬫墦鍖�=====");
-  const buildEnv = createBuildEnv(companyMap.env);
-  execSync("vite build", { stdio: "inherit", cwd: rootPath, env: buildEnv });
-  console.log("=====鎵撳寘瀹屾垚======");
+    console.log("=====寮�濮嬫墦鍖�======");
+    execSync("vite build", { stdio: "inherit" });
+    console.log("=====鎵撳寘瀹屾垚======");
 } finally {
-  console.log("=====鎭㈠璧勬簮======");
+    console.log("=====鎭㈠璧勬簮======");
 
-  if (fsSync.existsSync(envFilePath)) {
-    await fs.unlink(envFilePath);
-    console.log(`馃棏锔� 宸插垹闄� ${envFilePath}`);
-  }
-
-  if (fsSync.existsSync(replacePath)) {
-    for (const [key] of Object.entries(companyMap)) {
-      if (key === "env") continue;
-
-      const originFile = path.join(rootPath, config[key]);
-      const backupFile = path.join(replacePath, config[key]);
-      await copyFileWithOverwrite(backupFile, originFile);
+    // 鍒犻櫎涓存椂 .env 鏂囦欢
+    if (fsSync.existsSync(envFilePath)) {
+        await fs.unlink(envFilePath);
+        console.log(`馃棏锔� 宸插垹闄� ${envFilePath}`);
     }
-    await fs.rm(replacePath, { recursive: true, force: true });
-    console.log(`馃棏锔� 宸插垹闄� ${replacePath}`);
-  }
+
+    // 鎭㈠璧勬簮鏂囦欢
+    if (fsSync.existsSync(replacePath)) {
+        for (const [key, value] of Object.entries(companyMap)) {
+            if (key === 'env') continue;
+
+            const originFile = path.join(rootPath, config[key]);
+            const backupFile = path.join(replacePath, config[key]);
+
+            await fs.copyFile(backupFile, originFile);
+        }
+        await fs.rm(replacePath, { recursive: true, force: true });
+        console.log(`馃棏锔� 宸插垹闄� ${replacePath}`);
+    }
 }
 
+// 绠�鍗曞懡浠よ鍙傛暟瑙f瀽
 function parseArgs(argv) {
-  const params = {};
-  for (let index = 2; index < argv.length; index++) {
-    const arg = argv[index];
-    if (!arg.startsWith("--")) continue;
-
-    const normalized = arg.slice(2);
-    const equalIndex = normalized.indexOf("=");
-    if (equalIndex >= 0) {
-      const key = normalized.slice(0, equalIndex);
-      const value = normalized.slice(equalIndex + 1);
-      params[key] = value || true;
-      continue;
+    const params = {};
+    for (const arg of argv.slice(2)) {
+        if (arg.startsWith('--')) {
+            const [key, value] = arg.slice(2).split('=');
+            params[key] = value ?? true;
+        }
     }
-
-    const nextArg = argv[index + 1];
-    if (nextArg && !nextArg.startsWith("--")) {
-      params[normalized] = nextArg;
-      index += 1;
-      continue;
-    }
-
-    params[normalized] = true;
-  }
-  return params;
-}
-
-function resolveCompany(parsedParams) {
-  const fromArg = parseValue(parsedParams.company);
-  if (fromArg) return fromArg;
-
-  const fromNpmConfig = parseValue(process.env.npm_config_company);
-  if (fromNpmConfig) return fromNpmConfig;
-
-  const fromEnv = parseValue(process.env.COMPANY ?? process.env.company);
-  if (fromEnv) return fromEnv;
-
-  return "default";
-}
-
-function parseValue(value) {
-  if (value == null || value === true) return undefined;
-  if (typeof value !== "string") return undefined;
-  const trimmed = value.trim();
-  if (!trimmed) return undefined;
-  return trimmed.replace(/^["']|["']$/g, "");
-}
-
-function createBuildEnv(companyEnv) {
-  const env = { ...process.env };
-  for (const key of Object.keys(env)) {
-    if (key.startsWith("VITE_")) {
-      delete env[key];
-    }
-  }
-  return {
-    ...env,
-    ...companyEnv,
-    VITE_APP_ENV: "production",
-  };
+    return params;
 }
diff --git a/public/favicon.ico b/public/favicon.ico
index ce783dc..e263760 100644
--- a/public/favicon.ico
+++ b/public/favicon.ico
Binary files differ
diff --git a/src/api/equipmentManagement/deviceArea.js b/src/api/equipmentManagement/deviceArea.js
new file mode 100644
index 0000000..2671840
--- /dev/null
+++ b/src/api/equipmentManagement/deviceArea.js
@@ -0,0 +1,55 @@
+import request from "@/utils/request";
+
+export function getDeviceAreaTree(params) {
+  return request({
+    url: "/device/area/tree",
+    method: "get",
+    params,
+  });
+}
+
+export function getDeviceAreaTreeWithDevices(params) {
+  return request({
+    url: "/device/area/treeWithDevices",
+    method: "get",
+  });
+}
+
+export function getDeviceAreaPage(params) {
+  return request({
+    url: "/device/area/page",
+    method: "get",
+    params,
+  });
+}
+
+export function getDeviceAreaDetail(id) {
+  return request({
+    url: `/device/area/${id}`,
+    method: "get",
+  });
+}
+
+export function addDeviceArea(data) {
+  return request({
+    url: "/device/area",
+    method: "post",
+    data,
+  });
+}
+
+export function updateDeviceArea(data) {
+  return request({
+    url: "/device/area",
+    method: "put",
+    data,
+  });
+}
+
+export function deleteDeviceArea(ids) {
+  return request({
+    url: "/device/area",
+    method: "delete",
+    data: ids,
+  });
+}
diff --git a/src/api/equipmentManagement/measurementEquipment.js b/src/api/equipmentManagement/measurementEquipment.js
index ba73317..8bb8a7f 100644
--- a/src/api/equipmentManagement/measurementEquipment.js
+++ b/src/api/equipmentManagement/measurementEquipment.js
@@ -52,31 +52,4 @@
         method:"post",
         data
     })
-}
-
-// 閫氱敤闄勪欢鏌ヨ
-export function getStorageAttachmentList(query) {
-  return request({
-    url: "/storageAttachment/list",
-    method: "get",
-    params: query,
-  });
-}
-
-// 閫氱敤闄勪欢淇濆瓨
-export function addStorageAttachment(data) {
-  return request({
-    url: "/storageAttachment/add",
-    method: "post",
-    data: data,
-  });
-}
-
-// 閫氱敤闄勪欢鍒犻櫎
-export function delStorageAttachment(ids) {
-  return request({
-    url: "/storageAttachment/delete",
-    method: "delete",
-    data: ids,
-  });
 }
\ No newline at end of file
diff --git a/src/api/equipmentManagement/repair.js b/src/api/equipmentManagement/repair.js
index 16bfd28..0233ae6 100644
--- a/src/api/equipmentManagement/repair.js
+++ b/src/api/equipmentManagement/repair.js
@@ -70,16 +70,3 @@
     data,
   });
 };
-
-/**
- * @desc 楠屾敹瀹℃壒
- * @param {楠屾敹鍙傛暟} data
- * @returns
- */
-export const repairAcceptance = (data) => {
-  return request({
-    url: `/device/repair/acceptance`,
-    method: "post",
-    data,
-  });
-};
diff --git a/src/api/equipmentManagement/upkeep.js b/src/api/equipmentManagement/upkeep.js
index 234d2a5..5774654 100644
--- a/src/api/equipmentManagement/upkeep.js
+++ b/src/api/equipmentManagement/upkeep.js
@@ -102,3 +102,12 @@
     data: params,
   });
 };
+
+// 璁惧淇濆吇瀹氭椂浠诲姟鍚敤鐘舵�佸垏鎹�
+export const deviceMaintenanceTaskChangeEnable = (params) => {
+  return request({
+    url: '/deviceMaintenanceTask/changeEnable',
+    method: "post",
+    data: params,
+  });
+};
diff --git a/src/api/inspectionManagement/index.js b/src/api/inspectionManagement/index.js
index d0c444a..0a76c42 100644
--- a/src/api/inspectionManagement/index.js
+++ b/src/api/inspectionManagement/index.js
@@ -58,4 +58,13 @@
         method: 'post',
         data: query
     })
-}
\ No newline at end of file
+}
+
+// 瀹氭椂宸℃浠诲姟鍚敤鐘舵�佸垏鎹�
+export function changeTimingTaskEnable(query) {
+    return request({
+        url: '/timingTask/changeEnable',
+        method: 'post',
+        data: query
+    })
+}
diff --git a/src/views/equipmentManagement/brand/index.vue b/src/views/equipmentManagement/brand/index.vue
index f93518a..6607cc8 100644
--- a/src/views/equipmentManagement/brand/index.vue
+++ b/src/views/equipmentManagement/brand/index.vue
@@ -60,8 +60,8 @@
         </el-form-item>
       </el-form>
       <template #footer>
-        <el-button type="primary" @click="handleSubmit">纭畾</el-button>
         <el-button @click="visible = false">鍙栨秷</el-button>
+        <el-button type="primary" @click="handleSubmit">纭畾</el-button>
       </template>
     </el-dialog>
   </div>
diff --git a/src/views/equipmentManagement/calibration/index.vue b/src/views/equipmentManagement/calibration/index.vue
index b04da2e..e3eaef6 100644
--- a/src/views/equipmentManagement/calibration/index.vue
+++ b/src/views/equipmentManagement/calibration/index.vue
@@ -1,6 +1,6 @@
 <template>
 	<div class="app-container">
-		<div class="search_form mb20">
+		<div class="search_form">
 			<div>
 				<span class="search_title">妫�瀹氭棩鏈燂細</span>
 				<el-date-picker
diff --git a/src/views/equipmentManagement/defectManagement/index.vue b/src/views/equipmentManagement/defectManagement/index.vue
index 8673000..f35454f 100644
--- a/src/views/equipmentManagement/defectManagement/index.vue
+++ b/src/views/equipmentManagement/defectManagement/index.vue
@@ -65,8 +65,8 @@
       </el-form>
       <template #footer>
         <span class="dialog-footer">
-          <el-button type="primary" @click="submitDefectForm">纭畾</el-button>
           <el-button @click="showRegisterDialog = false">鍙栨秷</el-button>
+          <el-button type="primary" @click="submitDefectForm">纭畾</el-button>
         </span>
       </template>
     </el-dialog>
diff --git a/src/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue b/src/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue
deleted file mode 100644
index 36256c8..0000000
--- a/src/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue
+++ /dev/null
@@ -1,680 +0,0 @@
-<template>
-  <FormDialog
-    v-model="dialogVisible"
-    title="涓婁紶宸℃璁板綍"
-    width="980px"
-    @close="handleClose"
-    @cancel="handleClose"
-  >
-    <main class="upload-content">
-      <el-card v-if="taskInfo" class="section-card">
-        <el-descriptions :column="1" border>
-          <el-descriptions-item label="宸℃浠诲姟鍚嶇О">
-            {{ taskInfo.taskName || "-" }}
-          </el-descriptions-item>
-          <el-descriptions-item label="宸℃椤圭洰">
-            {{ taskInfo.inspectionProject || "-" }}
-          </el-descriptions-item>
-          <el-descriptions-item label="澶囨敞">
-            {{ taskInfo.remarks || "-" }}
-          </el-descriptions-item>
-        </el-descriptions>
-      </el-card>
-
-      <el-card class="section-card">
-        <h3>宸℃鐘舵��</h3>
-        <el-radio-group v-model="hasException">
-          <el-radio-button :value="false">姝e父</el-radio-button>
-          <el-radio-button :value="true">瀛樺湪寮傚父</el-radio-button>
-        </el-radio-group>
-      </el-card>
-
-      <el-card v-if="hasException === true" class="section-card">
-        <h3>寮傚父鎻忚堪</h3>
-        <el-input
-          v-model="abnormalDescription"
-          type="textarea"
-          maxlength="500"
-          show-word-limit
-          :rows="4"
-          placeholder="璇锋弿杩板紓甯告儏鍐�..."
-        />
-      </el-card>
-
-      <el-card v-if="hasException === true" class="section-card">
-        <el-tabs v-model="currentUploadType">
-          <el-tab-pane label="鐢熶骇鍓�" name="before" />
-          <el-tab-pane label="鐢熶骇涓�" name="after" />
-          <el-tab-pane label="鐢熶骇鍚�" name="issue" />
-        </el-tabs>
-
-        <div class="upload-buttons">
-          <el-upload
-            :show-file-list="false"
-            :http-request="uploadFile"
-            :disabled="getCurrentFiles().length >= uploadConfig.limit || uploading"
-            accept="image/*"
-          >
-            <el-button type="primary" :loading="uploading">
-              <el-icon><Camera /></el-icon>
-              閫夋嫨鍥剧墖
-            </el-button>
-          </el-upload>
-
-          <el-upload
-            :show-file-list="false"
-            :http-request="uploadFile"
-            :disabled="getCurrentFiles().length >= uploadConfig.limit || uploading"
-            accept="video/*"
-          >
-            <el-button type="success" :loading="uploading">
-              <el-icon><VideoCamera /></el-icon>
-              閫夋嫨瑙嗛
-            </el-button>
-          </el-upload>
-        </div>
-
-        <el-progress
-          v-if="uploading"
-          :percentage="uploadProgress"
-          class="upload-progress"
-        />
-
-        <div v-if="getCurrentFiles().length" class="file-list">
-          <div
-            v-for="(file, index) in getCurrentFiles()"
-            :key="file.uid || file.id || index"
-            class="file-item"
-          >
-            <div class="file-preview-container">
-              <el-image
-                v-if="file.type === 'image' || !file.type"
-                :src="file.url || file.tempFilePath || file.path || file.downloadUrl"
-                fit="cover"
-                class="file-preview"
-                :preview-src-list="[file.url || file.tempFilePath || file.path || file.downloadUrl]"
-                preview-teleported
-              />
-
-              <div v-else class="video-preview" @click="previewVideo(file)">
-                <el-icon><VideoCamera /></el-icon>
-                <span>瑙嗛</span>
-              </div>
-
-              <el-button
-                class="delete-btn"
-                type="danger"
-                circle
-                size="small"
-                @click="removeFile(index)"
-              >
-                <el-icon><Close /></el-icon>
-              </el-button>
-            </div>
-
-            <div class="file-info">
-              <div class="file-name">
-                {{ file.bucketFilename || file.name || (file.type === "image" ? "鍥剧墖" : "瑙嗛") }}
-              </div>
-              <div class="file-size">{{ formatFileSize(file.size) }}</div>
-            </div>
-          </div>
-        </div>
-
-        <el-empty
-          v-else
-          :description="`璇烽�夋嫨瑕佷笂浼犵殑${getUploadTypeText()}鍥剧墖鎴栬棰慲"
-        />
-
-        <el-alert
-          class="upload-summary"
-          type="info"
-          :closable="false"
-          :title="`鐢熶骇鍓嶏細${beforeModelValue.length}涓枃浠� | 鐢熶骇涓細${afterModelValue.length}涓枃浠� | 鐢熶骇鍚庯細${issueModelValue.length}涓枃浠禶"
-        />
-      </el-card>
-
-      <el-result
-        v-if="hasException === false"
-        icon="success"
-        title="璁惧杩愯姝e父"
-        sub-title="鏃犻渶涓婁紶鐓х墖"
-      />
-    </main>
-
-    <template #footer>
-      <footer class="footer-buttons">
-        <el-button type="primary" @click="submitUpload">鎻愪氦</el-button>
-        <el-button v-if="hasException === true" type="warning" @click="goToRepair">
-          鏂板鎶ヤ慨
-        </el-button>
-        <el-button @click="handleClose">鍙栨秷</el-button>
-      </footer>
-    </template>
-  </FormDialog>
-
-  <el-dialog
-    v-model="showVideoDialog"
-    :title="currentVideoFile?.originalFilename || currentVideoFile?.name || '瑙嗛棰勮'"
-    width="720px"
-  >
-    <video
-      v-if="currentVideoFile"
-      :src="currentVideoFile.url || currentVideoFile.downloadUrl"
-      class="video-player"
-      controls
-      autoplay
-    />
-  </el-dialog>
-</template>
-
-<script setup>
-import { computed, ref } from "vue";
-import { useRouter } from "vue-router";
-import { ElLoading, ElMessage, ElMessageBox } from "element-plus";
-import { Camera, Close, VideoCamera } from "@element-plus/icons-vue";
-import axios from "axios";
-import FormDialog from "@/components/Dialog/FormDialog.vue";
-import { uploadInspectionTask } from "@/api/inspectionManagement/index.js";
-import { getToken } from "@/utils/auth";
-
-const emit = defineEmits(["closeDia", "success"]);
-const router = useRouter();
-
-const dialogVisible = ref(false);
-const taskInfo = ref(null);
-const uploading = ref(false);
-const uploadProgress = ref(0);
-
-const beforeModelValue = ref([]);
-const afterModelValue = ref([]);
-const issueModelValue = ref([]);
-
-const currentUploadType = ref("before");
-const hasException = ref(null);
-const abnormalDescription = ref("");
-
-const showVideoDialog = ref(false);
-const currentVideoFile = ref(null);
-
-const uploadConfig = {
-  action: "/common/upload",
-  limit: 10,
-  fileSize: 50,
-  fileType: ["jpg", "jpeg", "png", "mp4", "mov"],
-};
-
-const uploadFileUrl = computed(
-  () => `${import.meta.env.VITE_APP_BASE_API}${uploadConfig.action}`
-);
-
-const processFileUrl = fileUrl => {
-  if (!fileUrl) return "";
-
-  let currentUrl = String(fileUrl);
-  if (currentUrl.includes("\\")) {
-    const uploadsIndex = currentUrl.toLowerCase().indexOf("uploads");
-    if (uploadsIndex > -1) {
-      currentUrl = `/${currentUrl.substring(uploadsIndex).replace(/\\/g, "/")}`;
-    } else {
-      const fileName = currentUrl.split("\\").pop();
-      currentUrl = `/uploads/${fileName}`;
-    }
-  }
-
-  if (currentUrl && !currentUrl.startsWith("http")) {
-    if (!currentUrl.startsWith("/")) {
-      currentUrl = `/${currentUrl}`;
-    }
-    currentUrl = __BASE_API__ + currentUrl;
-  }
-
-  return currentUrl;
-};
-
-const normalizeList = (list, fileType) => {
-  if (!Array.isArray(list)) return [];
-
-  return list.filter(Boolean).map(item => {
-    let currentType = item.type;
-    if (!currentType && item.contentType) {
-      currentType = item.contentType.startsWith("video") ? "video" : "image";
-    } else if (!currentType) {
-      currentType = fileType || "image";
-    }
-
-    return {
-      ...item,
-      url: processFileUrl(item.url || item.previewURL || item.downloadUrl || item.path || ""),
-      downloadUrl: processFileUrl(
-        item.downloadUrl || item.url || item.previewURL || item.path || ""
-      ),
-      name: item.name || item.originalFilename || item.bucketFilename,
-      tempId: item.tempId || item.id || item.tempFileId,
-      tempFileId: item.tempFileId || item.tempId || item.id,
-      size: item.size || item.byteSize || 0,
-      type: currentType,
-      status: "success",
-      uid: item.uid || `${Date.now()}-${Math.random()}`,
-    };
-  });
-};
-
-const resetState = () => {
-  taskInfo.value = null;
-  beforeModelValue.value = [];
-  afterModelValue.value = [];
-  issueModelValue.value = [];
-  currentUploadType.value = "before";
-  hasException.value = null;
-  abnormalDescription.value = "";
-  uploading.value = false;
-  uploadProgress.value = 0;
-  showVideoDialog.value = false;
-  currentVideoFile.value = null;
-};
-
-const openDialog = row => {
-  const raw = JSON.parse(JSON.stringify(row?.__raw || row || {}));
-  taskInfo.value = raw;
-
-  beforeModelValue.value = normalizeList(
-    raw.commonFileListBeforeVO || raw.commonFileListBefore || [],
-    "image"
-  );
-  afterModelValue.value = normalizeList(
-    raw.commonFileListVO || raw.commonFileList || [],
-    "image"
-  );
-  issueModelValue.value = normalizeList(
-    raw.commonFileListAfterVO || raw.commonFileListAfter || [],
-    "image"
-  );
-
-  abnormalDescription.value = raw.abnormalDescription || "";
-
-  if (raw.hasException !== undefined && raw.hasException !== null) {
-    hasException.value = raw.hasException;
-  } else if (raw.inspectionResult !== undefined && raw.inspectionResult !== null) {
-    hasException.value = String(raw.inspectionResult) === "0";
-  } else {
-    hasException.value = null;
-  }
-
-  if (
-    hasException.value !== true &&
-    (beforeModelValue.value.length || afterModelValue.value.length || issueModelValue.value.length)
-  ) {
-    hasException.value = true;
-  }
-
-  dialogVisible.value = true;
-};
-
-const handleClose = () => {
-  dialogVisible.value = false;
-  resetState();
-  emit("closeDia");
-};
-
-const getCurrentFiles = () => {
-  if (currentUploadType.value === "before") return beforeModelValue.value;
-  if (currentUploadType.value === "after") return afterModelValue.value;
-  if (currentUploadType.value === "issue") return issueModelValue.value;
-  return [];
-};
-
-const getUploadTypeText = () => {
-  if (currentUploadType.value === "before") return "鐢熶骇鍓�";
-  if (currentUploadType.value === "after") return "鐢熶骇涓�";
-  if (currentUploadType.value === "issue") return "鐢熶骇鍚�";
-  return "";
-};
-
-const getTabType = () => {
-  if (currentUploadType.value === "before") return 10;
-  if (currentUploadType.value === "after") return 11;
-  if (currentUploadType.value === "issue") return 12;
-  return 10;
-};
-
-const previewVideo = file => {
-  currentVideoFile.value = file;
-  showVideoDialog.value = true;
-};
-
-const uploadFile = async uploadRequest => {
-  const rawFile = uploadRequest.file;
-
-  if (getCurrentFiles().length >= uploadConfig.limit) {
-    ElMessage.warning(`鏈�澶氬彧鑳介�夋嫨${uploadConfig.limit}涓枃浠禶);
-    return;
-  }
-
-  const ext = rawFile.name.split(".").pop()?.toLowerCase();
-  if (!uploadConfig.fileType.includes(ext)) {
-    ElMessage.warning(`鏂囦欢鏍煎紡涓嶆敮鎸侊紝璇蜂笂浼� ${uploadConfig.fileType.join("/")} 鏍煎紡`);
-    return;
-  }
-
-  if (rawFile.size > uploadConfig.fileSize * 1024 * 1024) {
-    ElMessage.warning(`鏂囦欢澶у皬涓嶈兘瓒呰繃 ${uploadConfig.fileSize}MB`);
-    return;
-  }
-
-  const token = getToken();
-  if (!token) {
-    ElMessage.warning("鐢ㄦ埛鏈櫥褰�");
-    return;
-  }
-
-  const formData = new FormData();
-  formData.append("files", rawFile);
-  formData.append("type", getTabType());
-
-  uploading.value = true;
-  uploadProgress.value = 0;
-
-  try {
-    const { data } = await axios.post(uploadFileUrl.value, formData, {
-      headers: {
-        Authorization: `Bearer ${token}`,
-        "Content-Type": "multipart/form-data",
-      },
-      onUploadProgress: event => {
-        if (event.total) {
-          uploadProgress.value = Math.round((event.loaded / event.total) * 100);
-        }
-      },
-    });
-
-    if (data.code !== 200) {
-      ElMessage.error(data.msg || "涓婁紶澶辫触");
-      return;
-    }
-
-    const resultData = Array.isArray(data.data) ? data.data[0] : data.data;
-    const finalUrl = processFileUrl(
-      resultData.url || resultData.previewURL || resultData.downloadUrl || ""
-    );
-    const finalName = resultData.name || resultData.originalFilename || resultData.bucketFilename;
-    const finalId = resultData.tempId || resultData.id || resultData.tempFileId;
-
-    const uploadedFile = {
-      ...resultData,
-      url: finalUrl,
-      downloadUrl: finalUrl,
-      name: finalName,
-      tempId: finalId,
-      tempFileId: resultData.tempFileId || finalId,
-      size: rawFile.size || resultData.size || resultData.byteSize || 0,
-      type: rawFile.type?.startsWith("video") ? "video" : "image",
-      status: "success",
-      uid: `${Date.now()}-${Math.random()}`,
-    };
-
-    getCurrentFiles().push(uploadedFile);
-    ElMessage.success("涓婁紶鎴愬姛");
-  } catch (error) {
-    ElMessage.error(error?.message || "涓婁紶澶辫触");
-  } finally {
-    uploading.value = false;
-  }
-};
-
-const buildFileItem = item => ({
-  id: item?.id,
-  tempId: item?.tempId,
-  tempFileId: item?.tempFileId,
-  url: item?.downloadUrl || item?.url || "",
-  downloadUrl: item?.downloadUrl || item?.url || "",
-  name: item?.name,
-  bucketFilename: item?.bucketFilename || item?.name,
-  originalFilename: item?.originalFilename || item?.name,
-  size: item?.size || 0,
-  byteSize: item?.byteSize || item?.size || 0,
-  contentType: item?.contentType || "",
-  type: item?.type,
-});
-
-const submitUpload = async () => {
-  if (hasException.value === null) {
-    ElMessage.warning("璇烽�夋嫨宸℃鐘舵��");
-    return;
-  }
-
-  if (hasException.value === true) {
-    const totalFiles =
-      beforeModelValue.value.length +
-      afterModelValue.value.length +
-      issueModelValue.value.length;
-
-    if (!totalFiles) {
-      ElMessage.warning("璇蜂笂浼犲紓甯哥収鐗囨垨瑙嗛");
-      return;
-    }
-
-    if (!abnormalDescription.value.trim()) {
-      ElMessage.warning("璇峰~鍐欏紓甯告弿杩�");
-      return;
-    }
-  }
-
-  const loading = ElLoading.service({
-    text: "鎻愪氦涓�...",
-    background: "rgba(0, 0, 0, 0.3)",
-  });
-
-  try {
-    const allFiles = [
-      ...beforeModelValue.value,
-      ...afterModelValue.value,
-      ...issueModelValue.value,
-    ];
-
-    const tempFileIds = allFiles
-      .map(item => item?.tempId ?? item?.tempFileId ?? item?.id)
-      .filter(Boolean);
-
-    const {
-      createTime,
-      updateTime,
-      storageBlobDTO,
-      commonFileListAfterVO,
-      commonFileListVO,
-      commonFileListBeforeVO,
-      commonFileListAfter,
-      commonFileList,
-      commonFileListBefore,
-      __raw,
-      ...baseTaskInfo
-    } = taskInfo.value || {};
-
-    const submitData = {
-      ...baseTaskInfo,
-      commonFileListBeforeDTO: beforeModelValue.value.map(buildFileItem),
-      commonFileListDTO: afterModelValue.value.map(buildFileItem),
-      commonFileListAfterDTO: issueModelValue.value.map(buildFileItem),
-      hasException: hasException.value,
-      inspectionResult: hasException.value ? 0 : 1,
-      abnormalDescription: abnormalDescription.value,
-      tempFileIds,
-    };
-
-    const result = await uploadInspectionTask(submitData);
-
-    if (result && (result.code === 200 || result.success)) {
-      ElMessage.success("鎻愪氦鎴愬姛");
-      dialogVisible.value = false;
-      resetState();
-      emit("success");
-      emit("closeDia");
-    } else {
-      ElMessage.error(result?.msg || result?.message || "鎻愪氦澶辫触");
-    }
-  } catch (error) {
-    ElMessage.error(error?.message || "鎻愪氦澶辫触");
-  } finally {
-    loading.close();
-  }
-};
-
-const removeFile = async index => {
-  try {
-    await ElMessageBox.confirm("纭畾瑕佸垹闄よ繖涓枃浠跺悧锛�", "纭鍒犻櫎", {
-      type: "warning",
-    });
-    getCurrentFiles().splice(index, 1);
-  } catch {}
-};
-
-const goToRepair = () => {
-  const taskData = {
-    taskId: taskInfo.value?.taskId || taskInfo.value?.id,
-    taskName: taskInfo.value?.taskName,
-    inspectionLocation: taskInfo.value?.inspectionLocation,
-    inspector: taskInfo.value?.inspector,
-    hasException: hasException.value,
-    inspectionResult: hasException.value ? 0 : 1,
-    commonFileListBeforeDTO: beforeModelValue.value.map(buildFileItem),
-    commonFileListDTO: afterModelValue.value.map(buildFileItem),
-    commonFileListAfterDTO: issueModelValue.value.map(buildFileItem),
-    uploadedFiles: {
-      before: beforeModelValue.value,
-      after: afterModelValue.value,
-      issue: issueModelValue.value,
-    },
-  };
-
-  sessionStorage.setItem("repairTaskInfo", JSON.stringify(taskData));
-  router.push("/equipmentManagement/repair/add");
-};
-
-const formatFileSize = size => {
-  if (!size) return "0 B";
-
-  const units = ["B", "KB", "MB", "GB"];
-  let index = 0;
-  let fileSize = size;
-
-  while (fileSize >= 1024 && index < units.length - 1) {
-    fileSize /= 1024;
-    index += 1;
-  }
-
-  return `${fileSize.toFixed(2)} ${units[index]}`;
-};
-
-defineExpose({
-  openDialog,
-});
-</script>
-
-<style scoped>
-.inspection-upload-page {
-  min-height: 70vh;
-  background: #f5f7fa;
-  padding: 20px 20px 90px;
-  box-sizing: border-box;
-}
-
-.upload-content {
-  max-width: 960px;
-  margin: 20px auto 0;
-}
-
-.section-card {
-  margin-bottom: 16px;
-}
-
-.section-card h3 {
-  margin: 0 0 16px;
-  font-size: 16px;
-}
-
-.upload-buttons {
-  display: flex;
-  gap: 12px;
-  margin: 16px 0;
-}
-
-.upload-progress {
-  margin-bottom: 16px;
-}
-
-.file-list {
-  display: grid;
-  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
-  gap: 12px;
-}
-
-.file-preview-container {
-  position: relative;
-  aspect-ratio: 1;
-  border-radius: 8px;
-  overflow: hidden;
-  background: #f2f3f5;
-}
-
-.file-preview {
-  width: 100%;
-  height: 100%;
-}
-
-.video-preview {
-  width: 100%;
-  height: 100%;
-  background: #303133;
-  color: #fff;
-  display: flex;
-  gap: 6px;
-  align-items: center;
-  justify-content: center;
-  cursor: pointer;
-}
-
-.delete-btn {
-  position: absolute;
-  top: 6px;
-  right: 6px;
-}
-
-.file-info {
-  margin-top: 6px;
-  font-size: 12px;
-}
-
-.file-name {
-  color: #606266;
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-
-.file-size {
-  color: #909399;
-  margin-top: 2px;
-}
-
-.upload-summary {
-  margin-top: 16px;
-}
-
-.footer-buttons {
-  position: sticky;
-  left: 0;
-  right: 0;
-  bottom: 0;
-  padding: 14px 20px 0;
-  background: #f5f7fa;
-  display: flex;
-  justify-content: center;
-  gap: 12px;
-}
-
-.video-player {
-  width: 100%;
-  max-height: 70vh;
-  background: #000;
-}
-</style>
diff --git a/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue b/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue
index b5604fe..154ae7d 100644
--- a/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue
+++ b/src/views/equipmentManagement/inspectionManagement/components/viewFiles.vue
@@ -1,226 +1,251 @@
 <template>
   <div>
-    <el-dialog title="鏌ョ湅闄勪欢" v-model="dialogVisitable" width="800px" @close="cancel">
+    <el-dialog title="鏌ョ湅闄勪欢"
+               v-model="dialogVisitable" width="800px" @close="cancel">
       <div class="upload-container">
+        <!-- 鐢熶骇鍓� -->
         <div class="form-container">
           <div class="title">鐢熶骇鍓�</div>
-
-          <div class="media-list">
-            <img
-              v-for="(item, index) in beforeProductionImgs"
-              :key="`before-img-${index}`"
-              :src="item"
-              alt=""
-              class="media-image"
-              @click="showMedia(beforeProductionImgs, index, 'image')"
-            />
+          
+          <!-- 鍥剧墖鍒楄〃 -->
+          <div style="display: flex; flex-wrap: wrap;">
+            <img v-for="(item, index) in beforeProductionImgs" :key="index"
+                 @click="showMedia(beforeProductionImgs, index, 'image')"
+                 :src="item" style="max-width: 100px; height: 100px; margin: 5px;" alt="">
           </div>
-
-          <div class="media-list">
+          
+          <!-- 瑙嗛鍒楄〃 -->
+          <div style="display: flex; flex-wrap: wrap;">
             <div
-              v-for="(videoUrl, index) in beforeProductionVideos"
-              :key="`before-video-${index}`"
-              class="video-item"
-              @click="showMedia(beforeProductionVideos, index, 'video')"
+                v-for="(videoUrl, index) in beforeProductionVideos"
+                :key="index"
+                @click="showMedia(beforeProductionVideos, index, 'video')"
+                style="position: relative; margin: 10px; cursor: pointer;"
             >
-              <div class="video-thumb">
-                <img src="@/assets/images/video.png" alt="鎾斁" class="video-icon" />
+              <div style="width: 160px; height: 90px; background-color: #333; display: flex; align-items: center; justify-content: center;">
+                <img src="@/assets/images/video.png" alt="鎾斁" style="width: 30px; height: 30px; opacity: 0.8;" />
               </div>
-              <div class="video-text">鐐瑰嚮鎾斁</div>
+              <div style="text-align: center; font-size: 12px; color: #666;">鐐瑰嚮鎾斁</div>
             </div>
           </div>
         </div>
-
-        <div class="form-container">
-          <div class="title">鐢熶骇涓�</div>
-
-          <div class="media-list">
-            <img
-              v-for="(item, index) in afterProductionImgs"
-              :key="`during-img-${index}`"
-              :src="item"
-              alt=""
-              class="media-image"
-              @click="showMedia(afterProductionImgs, index, 'image')"
-            />
-          </div>
-
-          <div class="media-list">
-            <div
-              v-for="(videoUrl, index) in afterProductionVideos"
-              :key="`during-video-${index}`"
-              class="video-item"
-              @click="showMedia(afterProductionVideos, index, 'video')"
-            >
-              <div class="video-thumb">
-                <img src="@/assets/images/video.png" alt="鎾斁" class="video-icon" />
-              </div>
-              <div class="video-text">鐐瑰嚮鎾斁</div>
-            </div>
-          </div>
-        </div>
-
+				
+				<!-- 鐢熶骇涓� -->
+				<div class="form-container">
+					<div class="title">鐢熶骇涓�</div>
+					
+					<!-- 鍥剧墖鍒楄〃 -->
+					<div style="display: flex; flex-wrap: wrap;">
+						<img v-for="(item, index) in productionIssuesImgs" :key="index"
+			           @click="showMedia(productionIssuesImgs, index, 'image')"
+			           :src="item" style="max-width: 100px; height: 100px; margin: 5px;" alt="">
+					</div>
+					
+					<!-- 瑙嗛鍒楄〃 -->
+					<div style="display: flex; flex-wrap: wrap;">
+						<div
+							v-for="(videoUrl, index) in productionIssuesVideos"
+				      :key="index"
+				      @click="showMedia(productionIssuesVideos, index, 'video')"
+				      style="position: relative; margin: 10px; cursor: pointer;"
+						>
+							<div style="width: 160px; height: 90px; background-color: #333; display: flex; align-items: center; justify-content: center;">
+								<img src="@/assets/images/video.png" alt="鎾斁" style="width: 30px; height: 30px; opacity: 0.8;" />
+							</div>
+							<div style="text-align: center; font-size: 12px; color: #666;">鐐瑰嚮鎾斁</div>
+						</div>
+					</div>
+				</div>
+				
+        <!-- 鐢熶骇鍚� -->
         <div class="form-container">
           <div class="title">鐢熶骇鍚�</div>
-
-          <div class="media-list">
-            <img
-              v-for="(item, index) in productionIssuesImgs"
-              :key="`after-img-${index}`"
-              :src="item"
-              alt=""
-              class="media-image"
-              @click="showMedia(productionIssuesImgs, index, 'image')"
-            />
+          
+          <!-- 鍥剧墖鍒楄〃 -->
+          <div style="display: flex; flex-wrap: wrap;">
+            <img v-for="(item, index) in afterProductionImgs" :key="index"
+                 @click="showMedia(afterProductionImgs, index, 'image')"
+                 :src="item" style="max-width: 100px; height: 100px; margin: 5px;" alt="">
           </div>
-
-          <div class="media-list">
+          
+          <!-- 瑙嗛鍒楄〃 -->
+          <div style="display: flex; flex-wrap: wrap;">
             <div
-              v-for="(videoUrl, index) in productionIssuesVideos"
-              :key="`after-video-${index}`"
-              class="video-item"
-              @click="showMedia(productionIssuesVideos, index, 'video')"
+                v-for="(videoUrl, index) in afterProductionVideos"
+                :key="index"
+                @click="showMedia(afterProductionVideos, index, 'video')"
+                style="position: relative; margin: 10px; cursor: pointer;"
             >
-              <div class="video-thumb">
-                <img src="@/assets/images/video.png" alt="鎾斁" class="video-icon" />
+              <div style="width: 160px; height: 90px; background-color: #333; display: flex; align-items: center; justify-content: center;">
+                <img src="@/assets/images/video.png" alt="鎾斁" style="width: 30px; height: 30px; opacity: 0.8;" />
               </div>
-              <div class="video-text">鐐瑰嚮鎾斁</div>
+              <div style="text-align: center; font-size: 12px; color: #666;">鐐瑰嚮鎾斁</div>
             </div>
           </div>
         </div>
       </div>
     </el-dialog>
-
+    
+    <!-- 缁熶竴濯掍綋鏌ョ湅鍣� -->
     <div v-if="isMediaViewerVisible" class="media-viewer-overlay" @click.self="closeMediaViewer">
       <div class="media-viewer-content" @click.stop>
+        <!-- 鍥剧墖 -->
         <vue-easy-lightbox
-          v-if="mediaType === 'image'"
-          :visible="isMediaViewerVisible"
-          :imgs="mediaList"
-          :index="currentMediaIndex"
-          @hide="closeMediaViewer"
-        />
-
-        <div v-else-if="mediaType === 'video'" class="video-player-wrap">
-          <video :src="mediaList[currentMediaIndex]" autoplay controls class="video-player" />
+            v-if="mediaType === 'image'"
+            :visible="isMediaViewerVisible"
+            :imgs="mediaList"
+            :index="currentMediaIndex"
+            @hide="closeMediaViewer"
+        ></vue-easy-lightbox>
+        
+        <!-- 瑙嗛 -->
+        <div v-else-if="mediaType === 'video'" style="position: relative;">
+          <video
+              :src="mediaList[currentMediaIndex]"
+              autoplay
+              controls
+              style="max-width: 90vw; max-height: 80vh;"
+          />
         </div>
       </div>
     </div>
   </div>
 </template>
-
 <script setup>
-import { ref } from "vue";
-import VueEasyLightbox from "vue-easy-lightbox";
+import { ref } from 'vue';
+import VueEasyLightbox from 'vue-easy-lightbox';
+const { proxy } = getCurrentInstance();
 
+// 鎺у埗寮圭獥鏄剧ず
 const dialogVisitable = ref(false);
 
+// 鍥剧墖鏁扮粍
 const beforeProductionImgs = ref([]);
 const afterProductionImgs = ref([]);
 const productionIssuesImgs = ref([]);
 
+// 瑙嗛鏁扮粍
 const beforeProductionVideos = ref([]);
 const afterProductionVideos = ref([]);
 const productionIssuesVideos = ref([]);
 
+// 濯掍綋鏌ョ湅鍣ㄧ姸鎬�
 const isMediaViewerVisible = ref(false);
 const currentMediaIndex = ref(0);
-const mediaList = ref([]);
-const mediaType = ref("image");
+const mediaList = ref([]); // 瀛樺偍褰撳墠瑕佹煡鐪嬬殑濯掍綋鍒楄〃锛堝惈鍥剧墖鍜岃棰戝璞★級
+const mediaType = ref('image'); // image | video
+const javaApi = proxy.javaApi;
 
-const processFileUrl = fileUrl => {
-  if (!fileUrl) return "";
-
-  let currentUrl = String(fileUrl);
-  if (currentUrl.includes("\\")) {
-    const uploadsIndex = currentUrl.toLowerCase().indexOf("uploads");
+// 澶勭悊 URL锛氬皢 Windows 璺緞杞崲涓哄彲璁块棶鐨� URL
+function processFileUrl(fileUrl) {
+  if (!fileUrl) return '';
+  
+  // 濡傛灉 URL 鏄� Windows 璺緞鏍煎紡锛堝寘鍚弽鏂滄潬锛夛紝闇�瑕佽浆鎹�
+  if (fileUrl && fileUrl.indexOf('\\') > -1) {
+    // 鏌ユ壘 uploads 鍏抽敭瀛楃殑浣嶇疆锛屼粠閭i噷寮�濮嬫彁鍙栫浉瀵硅矾寰�
+    const uploadsIndex = fileUrl.toLowerCase().indexOf('uploads');
     if (uploadsIndex > -1) {
-      currentUrl = `/${currentUrl.substring(uploadsIndex).replace(/\\/g, "/")}`;
+      // 浠� uploads 寮�濮嬫彁鍙栬矾寰勶紝骞跺皢鍙嶆枩鏉犳浛鎹负姝f枩鏉�
+      const relativePath = fileUrl.substring(uploadsIndex).replace(/\\/g, '/');
+      fileUrl = '/' + relativePath;
     } else {
-      const fileName = currentUrl.split("\\").pop();
-      currentUrl = `/uploads/${fileName}`;
+      // 濡傛灉娌℃湁鎵惧埌 uploads锛屾彁鍙栨渶鍚庝竴涓洰褰曞拰鏂囦欢鍚�
+      const parts = fileUrl.split('\\');
+      const fileName = parts[parts.length - 1];
+      fileUrl = '/uploads/' + fileName;
     }
   }
-
-  if (currentUrl && !currentUrl.startsWith("http")) {
-    if (!currentUrl.startsWith("/")) {
-      currentUrl = `/${currentUrl}`;
+  
+  // 纭繚鎵�鏈夐潪 http 寮�澶寸殑 URL 閮芥嫾鎺� baseUrl
+  if (fileUrl && !fileUrl.startsWith('http')) {
+    // 纭繚璺緞浠� / 寮�澶�
+    if (!fileUrl.startsWith('/')) {
+      fileUrl = '/' + fileUrl;
     }
-    currentUrl = __BASE_API__ + currentUrl;
+    // 鎷兼帴 baseUrl
+    fileUrl = javaApi + fileUrl;
   }
+  
+  return fileUrl;
+}
 
-  return currentUrl;
-};
-
-const processItems = items => {
+// 澶勭悊姣忎竴绫绘暟鎹細鍒嗙鍥剧墖鍜岃棰�
+function processItems(items) {
   const images = [];
   const videos = [];
-
-  if (!Array.isArray(items)) {
+  
+  // 妫�鏌� items 鏄惁瀛樺湪涓斾负鏁扮粍
+  if (!items || !Array.isArray(items)) {
     return { images, videos };
   }
-
+  
   items.forEach(item => {
-    if (!item) return;
-
-    const fileUrl = processFileUrl(
-      item.previewURL || item.url || item.downloadUrl || item.path || ""
-    );
-    const contentType = String(item.contentType || "").toLowerCase();
-
-    if (!fileUrl) return;
-
-    if (contentType.startsWith("video/")) {
+    if (!item || !item.url) return;
+    
+    // 澶勭悊鏂囦欢 URL
+    const fileUrl = processFileUrl(item.url);
+    
+    // 鏍规嵁鏂囦欢鎵╁睍鍚嶅垽鏂槸鍥剧墖杩樻槸瑙嗛
+    const urlLower = fileUrl.toLowerCase();
+    if (urlLower.match(/\.(jpg|jpeg|png|gif|bmp|webp)$/)) {
+      images.push(fileUrl);
+    } else if (urlLower.match(/\.(mp4|avi|mov|wmv|flv|mkv|webm)$/)) {
       videos.push(fileUrl);
-      return;
+    } else if (item.contentType) {
+      // 濡傛灉鏈� contentType锛屼娇鐢� contentType 鍒ゆ柇
+      if (item.contentType.startsWith('image/')) {
+        images.push(fileUrl);
+      } else if (item.contentType.startsWith('video/')) {
+        videos.push(fileUrl);
+      }
     }
-
-    images.push(fileUrl);
   });
-
+  
   return { images, videos };
-};
+}
 
-const openDialog = row => {
-  const { images: beforeImgs, videos: beforeVids } = processItems(
-    row.commonFileListBeforeVO || []
-  );
-  const { images: afterImgs, videos: afterVids } = processItems(
-    row.commonFileListVO || []
-  );
-  const { images: issueImgs, videos: issueVids } = processItems(
-    row.commonFileListAfterVO || []
-  );
-
+// 鎵撳紑寮圭獥骞跺姞杞芥暟鎹�
+const openDialog = async (row) => {
+  // 浣跨敤姝g‘鐨勫瓧娈靛悕锛歝ommonFileListBefore, commonFileListAfter
+  // productionIssues 鍙兘涓嶅瓨鍦紝浣跨敤绌烘暟缁�
+  const { images: beforeImgs, videos: beforeVids } = processItems(row.commonFileListBefore || []);
+  const { images: afterImgs, videos: afterVids } = processItems(row.commonFileListAfter || []);
+  const { images: issueImgs, videos: issueVids } = processItems(row.productionIssues || []);
+  
   beforeProductionImgs.value = beforeImgs;
   beforeProductionVideos.value = beforeVids;
+  
   afterProductionImgs.value = afterImgs;
   afterProductionVideos.value = afterVids;
+  
   productionIssuesImgs.value = issueImgs;
   productionIssuesVideos.value = issueVids;
+  
   dialogVisitable.value = true;
 };
 
-const showMedia = (items, index, type) => {
-  mediaList.value = items;
+// 鏄剧ず濯掍綋锛堝浘鐗� or 瑙嗛锛�
+function showMedia(mediaArray, index, type) {
+  mediaList.value = mediaArray;
   currentMediaIndex.value = index;
   mediaType.value = type;
   isMediaViewerVisible.value = true;
-};
+}
 
-const closeMediaViewer = () => {
+// 鍏抽棴濯掍綋鏌ョ湅鍣�
+function closeMediaViewer() {
   isMediaViewerVisible.value = false;
   mediaList.value = [];
-  mediaType.value = "image";
-};
+  mediaType.value = 'image';
+}
 
+// 琛ㄥ崟鍏抽棴鏂规硶
 const cancel = () => {
   dialogVisitable.value = false;
 };
 
 defineExpose({ openDialog });
 </script>
-
 <style scoped lang="scss">
 .upload-container {
   display: flex;
@@ -229,7 +254,7 @@
   padding: 20px;
   border: 1px solid #dcdfe6;
   box-sizing: border-box;
-
+  
   .form-container {
     flex: 1;
     width: 100%;
@@ -245,7 +270,7 @@
   padding-left: 10px;
   position: relative;
   margin: 6px 0;
-
+  
   &::before {
     content: "";
     position: absolute;
@@ -257,48 +282,12 @@
   }
 }
 
-.media-list {
-  display: flex;
-  flex-wrap: wrap;
-}
-
-.media-image {
-  max-width: 100px;
-  height: 100px;
-  margin: 5px;
-  cursor: pointer;
-}
-
-.video-item {
-  position: relative;
-  margin: 10px;
-  cursor: pointer;
-}
-
-.video-thumb {
-  width: 160px;
-  height: 90px;
-  background-color: #333;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-}
-
-.video-icon {
-  width: 30px;
-  height: 30px;
-  opacity: 0.8;
-}
-
-.video-text {
-  text-align: center;
-  font-size: 12px;
-  color: #666;
-}
-
 .media-viewer-overlay {
   position: fixed;
-  inset: 0;
+  top: 0;
+  left: 0;
+  right: 0;
+  bottom: 0;
   background-color: rgba(0, 0, 0, 0.8);
   z-index: 9999;
   display: flex;
@@ -312,13 +301,4 @@
   max-height: 90vh;
   overflow: hidden;
 }
-
-.video-player-wrap {
-  position: relative;
-}
-
-.video-player {
-  max-width: 90vw;
-  max-height: 80vh;
-}
-</style>
+</style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/inspectionManagement/index.vue b/src/views/equipmentManagement/inspectionManagement/index.vue
index 8c0d52c..b0f4f58 100644
--- a/src/views/equipmentManagement/inspectionManagement/index.vue
+++ b/src/views/equipmentManagement/inspectionManagement/index.vue
@@ -1,449 +1,490 @@
 <template>
   <div class="app-container">
-    <el-form :inline="true"
-             :model="queryParams"
-             class="search-form">
+    <el-form :inline="true" :model="queryParams" class="search-form">
       <el-form-item label="宸℃浠诲姟鍚嶇О">
-        <el-input v-model="queryParams.taskName"
-                  placeholder="璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О"
-                  clearable
-                  style="width: 200px " />
+        <el-input
+          v-model="queryParams.taskName"
+          placeholder="璇疯緭鍏ュ贰妫�浠诲姟鍚嶇О"
+          clearable
+          style="width: 200px"
+        />
+      </el-form-item>
+      <el-form-item label="鎵�灞炲尯鍩�">
+        <el-tree-select
+          v-model="queryParams.areaId"
+          :data="areaOptions"
+          :props="areaTreeProps"
+          node-key="id"
+          value-key="id"
+          check-strictly
+          clearable
+          filterable
+          placeholder="璇烽�夋嫨鎵�灞炲尯鍩�"
+          style="width: 220px"
+        />
+      </el-form-item>
+      <el-form-item v-show="activeRadio === 'taskManage'" label="鏄惁鍚敤">
+        <el-select
+          v-model="queryParams.isEnabled"
+          placeholder="璇烽�夋嫨"
+          clearable
+          style="width: 140px"
+        >
+          <el-option label="鍚敤" :value="1" />
+          <el-option label="绂佺敤" :value="0" />
+        </el-select>
+      </el-form-item>
+      <el-form-item v-show="activeRadio === 'task'" label="鎵ц鏃ユ湡">
+        <el-date-picker
+          v-model="queryDate"
+          type="date"
+          placeholder="璇烽�夋嫨鏃ユ湡"
+          value-format="YYYY-MM-DD"
+          format="YYYY-MM-DD"
+          style="width: 180px"
+          @change="handleQuery"
+        />
       </el-form-item>
       <el-form-item>
-        <el-button type="primary"
-                   @click="handleQuery">鏌ヨ</el-button>
+        <el-button type="primary" @click="handleQuery">鏌ヨ</el-button>
         <el-button @click="resetQuery">閲嶇疆</el-button>
       </el-form-item>
     </el-form>
     <el-card>
-      <div style="display: flex;flex-direction: row;justify-content: space-between;margin-bottom: 10px;">
-        <el-radio-group v-model="activeRadio"
-                        @change="radioChange">
-          <el-radio-button v-for="tab in radios"
-                           :key="tab.name"
-                           :label="tab.label"
-                           :value="tab.name" />
+      <div class="toolbar">
+        <el-radio-group v-model="activeRadio" @change="radioChange">
+          <el-radio-button
+            v-for="tab in radios"
+            :key="tab.name"
+            :label="tab.label"
+            :value="tab.name"
+          />
         </el-radio-group>
-        <!-- 鎿嶄綔鎸夐挳鍖� -->
         <el-space v-if="activeRadio !== 'task'">
-          <el-button type="primary"
-                     :icon="Plus"
-                     @click="handleAdd(undefined)">鏂板缓</el-button>
-          <el-button type="danger"
-                     :icon="Delete"
-                     @click="handleDelete">鍒犻櫎</el-button>
+          <el-button type="primary" :icon="Plus" @click="handleAdd(undefined)">鏂板缓</el-button>
+          <el-button type="danger" :icon="Delete" @click="handleDelete">鍒犻櫎</el-button>
           <el-button @click="handleOut">瀵煎嚭</el-button>
         </el-space>
         <el-space v-else>
           <el-button @click="handleOut">瀵煎嚭</el-button>
         </el-space>
       </div>
-      <div>
-        <PIMTable :table-loading="tableLoading"
-                  :table-data="tableData"
-                  :column="tableColumns"
-                  @selection-change="handleSelectionChange"
-                  @pagination="handlePagination"
-                  :is-selection="true"
-                  :border="true"
-                  :page="{
-                  current: pageNum,
-                  size: pageSize,
-                  total: total,
-                  layout: 'total, sizes, prev, pager, next, jumper'
-                }"
-                  height="calc(100vh - 23em)"
-                  :table-style="{ width: '100%' }">
-          <template #inspector="{ row }">
-            <div class="person-tags">
-              <!-- 璋冭瘯淇℃伅锛屼笂绾挎椂鍒犻櫎 -->
-              <!-- {{ console.log('inspector data:', row.inspector) }} -->
-              <template v-if="row.inspector && row.inspector.length > 0">
-                <el-tag v-for="(person, index) in row.inspector"
-                        :key="index"
-                        size="small"
-                        type="primary"
-                        class="person-tag">
-                  {{ person }}
-                </el-tag>
-              </template>
-              <span v-else
-                    class="no-data">--</span>
-            </div>
-          </template>
-          <template #isEnabled="{ row }">
-            <el-tag :type="row.isEnabled === 1 ? 'success' : 'danger'"
-                    size="small">
-              {{ row.isEnabled == 1 ? '鏄�' : '鍚�' }}
-            </el-tag>
-          </template>
-        </PIMTable>
-      </div>
+      <PIMTable
+        :table-loading="tableLoading"
+        :table-data="tableData"
+        :column="tableColumns"
+        :is-selection="true"
+        :border="true"
+        :page="{
+          current: pageNum,
+          size: pageSize,
+          total,
+          layout: 'total, sizes, prev, pager, next, jumper',
+        }"
+        :table-style="{ width: '100%', height: 'calc(100vh - 23em)' }"
+        @selection-change="handleSelectionChange"
+        @pagination="handlePagination"
+      >
+        <template #inspector="{ row }">
+          <div class="person-tags">
+            <template v-if="row.inspector && row.inspector.length > 0">
+              <el-tag
+                v-for="(person, index) in row.inspector"
+                :key="index"
+                size="small"
+                type="primary"
+                class="person-tag"
+              >
+                {{ person }}
+              </el-tag>
+            </template>
+            <span v-else class="no-data">--</span>
+          </div>
+        </template>
+        <template #isEnabledSwitch="{ row }">
+          <el-switch
+            v-model="row.isEnabled"
+            :active-value="1"
+            :inactive-value="0"
+            :loading="row.enableSwitchLoading"
+            :before-change="() => handleTimingTaskEnableBeforeChange(row)"
+          />
+        </template>
+      </PIMTable>
     </el-card>
-    <form-dia ref="formDia"
-              @closeDia="handleQuery"></form-dia>
-    <view-files ref="viewFiles"></view-files>
-    <upload-files ref="uploadFiles"
-                  @success="handleQuery"
-                  @closeDia="handleQuery"></upload-files>
+    <form-dia ref="formDia" @closeDia="handleQuery" />
+    <view-files ref="viewFiles" />
   </div>
 </template>
 
 <script setup>
-  import { Delete, Plus } from "@element-plus/icons-vue";
-  import { onMounted, ref, reactive, getCurrentInstance, nextTick } from "vue";
-  import { ElMessageBox } from "element-plus";
-  import dayjs from "dayjs";
+import { Delete, Plus } from "@element-plus/icons-vue";
+import { ElMessage, ElMessageBox } from "element-plus";
+import { getCurrentInstance, nextTick, onMounted, reactive, ref } from "vue";
+import dayjs from "dayjs";
+import PIMTable from "@/components/PIMTable/PIMTable.vue";
+import FormDia from "@/views/equipmentManagement/inspectionManagement/components/formDia.vue";
+import ViewFiles from "@/views/equipmentManagement/inspectionManagement/components/viewFiles.vue";
+import {
+  changeTimingTaskEnable,
+  delTimingTask,
+  inspectionTaskList,
+  timingTaskList,
+} from "@/api/inspectionManagement/index.js";
+import { getDeviceAreaTree } from "@/api/equipmentManagement/deviceArea";
 
-  // 缁勪欢寮曞叆
-  import PIMTable from "@/components/PIMTable/PIMTable.vue";
-  import FormDia from "@/views/equipmentManagement/inspectionManagement/components/formDia.vue";
-  import UploadFiles from "@/views/equipmentManagement/inspectionManagement/components/uploadFiles.vue";
-  import ViewFiles from "@/views/equipmentManagement/inspectionManagement/components/viewFiles.vue";
+const { proxy } = getCurrentInstance();
+const formDia = ref();
+const viewFiles = ref();
 
-  // 鎺ュ彛寮曞叆
-  import {
-    delTimingTask,
-    inspectionTaskList,
-    timingTaskList,
-  } from "@/api/inspectionManagement/index.js";
+const queryParams = reactive({
+  taskName: "",
+  areaId: undefined,
+  isEnabled: undefined,
+  createTimeStart: undefined,
+  createTimeEnd: undefined,
+});
 
-  // 鍏ㄥ眬鍙橀噺
-  const { proxy } = getCurrentInstance();
-  const formDia = ref();
-  const viewFiles = ref();
-  const uploadFiles = ref();
+// 鏌ヨ鏃ユ湡锛堢敤浜庡畾鏃朵换鍔¤褰曪級
+const queryDate = ref(dayjs().format("YYYY-MM-DD"));
 
-  // 鏌ヨ鍙傛暟
-  const queryParams = reactive({
-    taskName: "",
-  });
+const areaOptions = ref([]);
+const areaTreeProps = {
+  label: "areaName",
+  children: "children",
+};
 
-  // 鍗曢�夋閰嶇疆
-  const activeRadio = ref("taskManage");
-  const radios = reactive([
-    { name: "taskManage", label: "宸℃浠诲姟" },
-    { name: "task", label: "宸℃璁板綍" },
-  ]);
+const activeRadio = ref("taskManage");
+const radios = reactive([
+  { name: "taskManage", label: "瀹氭椂浠诲姟绠$悊" },
+  { name: "task", label: "瀹氭椂浠诲姟璁板綍" },
+]);
 
-  // 琛ㄦ牸鏁版嵁
-  const selectedRows = ref([]);
-  const tableData = ref([]);
-  const operationsArr = ref([]);
-  const tableColumns = ref([]);
-  const tableLoading = ref(false);
-  const total = ref(0);
-  const pageNum = ref(1);
-  const pageSize = ref(10);
+const selectedRows = ref([]);
+const tableData = ref([]);
+const tableColumns = ref([]);
+const tableLoading = ref(false);
+const total = ref(0);
+const pageNum = ref(1);
+const pageSize = ref(10);
 
-  // 鍒楅厤缃�
-  const columns = ref([
-    { prop: "taskName", label: "宸℃浠诲姟鍚嶇О", minWidth: 200 },
-    { prop: "inspectionProject", label: "宸℃椤圭洰", minWidth: 180 },
-    { prop: "remarks", label: "澶囨敞", minWidth: 180 },
-    { prop: "inspector", label: "鎵ц宸℃浜�", minWidth: 180, slot: "inspector" },
-    {
-      prop: "isEnabled",
-      label: "鏄惁鍚敤",
-      minWidth: 100,
-      dataType: "slot",
-      slot: "isEnabled",
-    },
-    {
-      prop: "frequencyType",
-      label: "棰戞",
-      minWidth: 120,
-      formatData: params => {
-        return params === "DAILY"
-          ? "姣忔棩"
-          : params === "WEEKLY"
-          ? "姣忓懆"
-          : params === "MONTHLY"
-          ? "姣忔湀"
-          : params === "QUARTERLY"
-          ? "瀛e害"
-          : "";
-      },
-    },
-    {
-      prop: "frequencyDetail",
-      label: "寮�濮嬫棩鏈熶笌鏃堕棿",
-      minWidth: 200,
-      formatter: (row, column, cellValue) => {
-        // 鍏堝垽鏂槸鍚︽槸瀛楃涓�
-        if (typeof cellValue !== "string") return "";
-        let val = cellValue;
-        const replacements = {
-          MON: "鍛ㄤ竴",
-          TUE: "鍛ㄤ簩",
-          WED: "鍛ㄤ笁",
-          THU: "鍛ㄥ洓",
-          FRI: "鍛ㄤ簲",
-          SAT: "鍛ㄥ叚",
-          SUN: "鍛ㄦ棩",
-        };
-        // 浣跨敤姝e垯涓�娆℃�ф浛鎹㈡墍鏈夊尮閰嶉」
-        return val.replace(
-          /MON|TUE|WED|THU|FRI|SAT|SUN/g,
-          match => replacements[match]
-        );
-      },
-    },
-    { prop: "registrant", label: "鐧昏浜�", minWidth: 120 },
-    {
-      prop: "createTime",
-      label: "鐧昏鏃ユ湡",
-      minWidth: 180,
-      formatData: cell => {
-        if (!cell) return "-";
-        try {
-          return dayjs(cell).format("YYYY-MM-DD HH:mm:ss");
-        } catch {
-          return cell;
-        }
-      },
-    },
-    // {
-    //   prop: "inspectionResult",
-    //   label: "宸℃缁撴灉",
-    //   minWidth: 100,
-    //   dataType: "tag",
-    //   formatData: val => {
-    //     return val == 1 ? "姝e父" : "寮傚父";
-    //   },
-    //   formatType: val => {
-    //     return val == 1 ? "success" : "danger";
-    //   },
-    // },
-    { prop: "abnormalDescription", label: "寮傚父鎻忚堪", minWidth: 150 },
-  ]);
-
-  // 鎿嶄綔鍒楅厤缃�
-  const getOperationColumn = operations => {
-    if (!operations || operations.length === 0) return null;
-
-    const operationConfig = {
-      label: "鎿嶄綔",
-      width: operations.length > 1 ? 180 : 130,
-      fixed: "right",
-      align: "center",
-      dataType: "action",
-      operation: operations
-        .map(op => {
-          switch (op) {
-            case "edit":
-              return {
-                name: "缂栬緫",
-                clickFun: handleAdd,
-                color: "#409EFF",
-              };
-            case "upload":
-              return {
-                name: "涓婁紶",
-                clickFun: openUploadDialog,
-                color: "#409EFF",
-              };
-            case "viewFile":
-              return {
-                name: "鏌ョ湅闄勪欢",
-                clickFun: viewFile,
-                color: "#67C23A",
-              };
-            default:
-              return null;
-          }
-        })
-        .filter(Boolean),
-    };
-
-    return operationConfig;
-  };
-
-  onMounted(() => {
-    radioChange("taskManage");
-  });
-
-  // 鍗曢�夊彉鍖�
-  const radioChange = value => {
-    if (value === "taskManage") {
-      const operationColumn = getOperationColumn(["edit"]);
-      tableColumns.value = [
-        ...columns.value,
-        ...(operationColumn ? [operationColumn] : []),
-      ];
-      operationsArr.value = ["edit"];
-    } else if (value === "task") {
-      const operationColumn = getOperationColumn(["upload", "viewFile"]);
-      // 宸℃璁板綍涓嶅睍绀�"鏄惁鍚敤"鍒�
-      const taskColumns = columns.value.filter(col => col.prop !== "isEnabled");
-      tableColumns.value = [
-        ...taskColumns,
-        ...(operationColumn ? [operationColumn] : []),
-      ];
-      operationsArr.value = ["upload", "viewFile"];
-    }
-    pageNum.value = 1;
-    pageSize.value = 10;
-    getList();
-  };
-
-  // 鏌ヨ鎿嶄綔
-  const handleQuery = () => {
-    pageNum.value = 1;
-    pageSize.value = 10;
-    getList();
-  };
-  // 鍒嗛〉澶勭悊
-  const handlePagination = val => {
-    pageNum.value = val.page;
-    pageSize.value = val.limit;
-    getList();
-  };
-  // 鑾峰彇鍒楄〃鏁版嵁
-  const getList = () => {
-    tableLoading.value = true;
-
-    const params = {
-      ...queryParams,
-      size: pageSize.value,
-      current: pageNum.value,
-    };
-
-    let apiCall;
-    if (activeRadio.value === "task") {
-      apiCall = inspectionTaskList(params);
-    } else {
-      apiCall = timingTaskList(params);
-    }
-
-    apiCall
-      .then(res => {
-        const rawData = res.data.records || [];
-        // 澶勭悊 inspector 瀛楁锛屽皢瀛楃涓茶浆鎹负鏁扮粍锛堥�傜敤浜庢墍鏈夋儏鍐碉級
-        tableData.value = rawData.map(item => {
-          const processedItem = { ...item };
-          processedItem.__raw = { ...item };
-
-          // 澶勭悊 inspector 瀛楁
-          if (processedItem.inspector) {
-            if (typeof processedItem.inspector === "string") {
-              // 瀛楃涓叉寜閫楀彿鍒嗗壊
-              processedItem.inspector = processedItem.inspector
-                .split(",")
-                .map(s => s.trim())
-                .filter(s => s);
-            } else if (!Array.isArray(processedItem.inspector)) {
-              // 闈炴暟缁勮浆涓烘暟缁�
-              processedItem.inspector = [processedItem.inspector];
-            }
-          } else {
-            // 绌哄�艰涓虹┖鏁扮粍
-            processedItem.inspector = [];
-          }
-
-          return processedItem;
-        });
-        total.value = res.data.total || 0;
-      })
-      .finally(() => {
-        tableLoading.value = false;
-      });
-  };
-
-  // 閲嶇疆鏌ヨ
-  const resetQuery = () => {
-    for (const key in queryParams) {
-      if (!["pageNum", "pageSize"].includes(key)) {
-        queryParams[key] = "";
+const columns = ref([
+	{
+		label: "鎵�鍦ㄥ尯鍩�",
+		prop: "areaName",
+	},
+  { prop: "taskName", label: "宸℃浠诲姟鍚嶇О", minWidth: 160 },
+  { prop: "remarks", label: "澶囨敞", minWidth: 150 },
+  { prop: "inspector", label: "鎵ц宸℃浜�", minWidth: 150, slot: "inspector" },
+  {
+    prop: "frequencyType",
+    label: "棰戞",
+    minWidth: 150,
+    formatData: (value) =>
+      ({
+        DAILY: "姣忔棩",
+        WEEKLY: "姣忓懆",
+        MONTHLY: "姣忔湀",
+        QUARTERLY: "瀛e害",
+				YEARLY: "姣忓勾",
+      }[value] || ""),
+  },
+  {
+    prop: "frequencyDetail",
+    label: "寮�濮嬫棩鏈熶笌鏃堕棿",
+    minWidth: 150,
+    formatter: (row, column, cellValue) => {
+      if (typeof cellValue !== "string") {
+        return "";
       }
-    }
-    handleQuery();
-  };
+      const replacements = {
+        MON: "鍛ㄤ竴",
+        TUE: "鍛ㄤ簩",
+        WED: "鍛ㄤ笁",
+        THU: "鍛ㄥ洓",
+        FRI: "鍛ㄤ簲",
+        SAT: "鍛ㄥ叚",
+        SUN: "鍛ㄦ棩",
+      };
+      return cellValue.replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, (match) => replacements[match]);
+    },
+  },
+  { prop: "registrant", label: "鐧昏浜�", minWidth: 100 },
+  { prop: "createTime", label: "鐧昏鏃ユ湡", width: 130 },
+]);
 
-  // 鏂板 / 缂栬緫
-  const handleAdd = row => {
-    const type = row ? "edit" : "add";
-    nextTick(() => {
-      formDia.value?.openDialog(type, row);
-    });
-  };
+const isEnabledColumn = {
+  prop: "isEnabled",
+  label: "鏄惁鍚敤",
+  minWidth: 110,
+  dataType: "slot",
+  slot: "isEnabledSwitch",
+};
 
-  // 鏌ョ湅闄勪欢
-  const viewFile = row => {
-    nextTick(() => {
-      viewFiles.value?.openDialog(row);
-    });
-  };
+// 宸℃鐘舵�佸垪锛堜粎瀹氭椂浠诲姟璁板綍鏄剧ず锛�
+const inspectionStatusColumn = {
+  prop: "inspectionStatus",
+  label: "宸℃鐘舵��",
+  minWidth: 100,
+  dataType: "tag",
+  formatData: (value) =>
+    ({
+      1: "寰呭贰妫�",
+      2: "宸插贰妫�",
+    }[value] || ""),
+  formatType: (value) =>
+    ({
+      1: "warning",
+      2: "success",
+    }[value] || "info"),
+};
+// 宸℃缁撴灉鍒楋紙浠呭畾鏃朵换鍔¤褰曟樉绀猴級
+const inspectionResultColumn = {
+  prop: "inspectionResult",
+  label: "宸℃缁撴灉",
+  minWidth: 100,
+  dataType: "tag",
+  formatData: (value) =>
+    ({
+      1: "姝e父",
+      2: "寮傚父",
+    }[value] || "-"),
+  formatType: (value) =>
+    ({
+      1: "success",
+      2: "error",
+    }[value] || "info"),
+};
 
-  const openUploadDialog = row => {
-    nextTick(() => {
-      uploadFiles.value?.openDialog(row);
-    });
-  };
-
-  // 鍒犻櫎鎿嶄綔
-  const handleDelete = () => {
-    if (!selectedRows.value.length) {
-      proxy.$modal.msgWarning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
-      return;
-    }
-
-    const deleteIds = selectedRows.value.map(item => item.id);
-
-    proxy.$modal
-      .confirm("鏄惁纭鍒犻櫎鎵�閫夋暟鎹」锛�")
-      .then(() => {
-        return delTimingTask(deleteIds);
-      })
-      .then(() => {
-        proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-        handleQuery();
-      })
-      .catch(() => {});
-  };
-
-  // 澶氶�夊彉鏇�
-  const handleSelectionChange = selection => {
-    selectedRows.value = selection;
-  };
-
-  // 瀵煎嚭
-  const handleOut = () => {
-    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-      confirmButtonText: "纭",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    })
-      .then(() => {
-        // 鏍规嵁褰撳墠閫変腑鐨勬爣绛鹃〉璋冪敤涓嶅悓鐨勫鍑烘帴鍙�
-        if (activeRadio.value === "taskManage") {
-          // 宸℃浠诲姟
-          proxy.download("/timingTask/export", {}, "宸℃浠诲姟.xlsx");
-        } else if (activeRadio.value === "task") {
-          // 宸℃璁板綍
-          proxy.download("/inspectionTask/export", {}, "宸℃璁板綍.xlsx");
+const getOperationColumn = (operations) => {
+  if (!operations || operations.length === 0) {
+    return null;
+  }
+  return {
+    label: "鎿嶄綔",
+    width: 130,
+    fixed: "right",
+    dataType: "action",
+    operation: operations
+      .map((op) => {
+        switch (op) {
+          case "edit":
+            return {
+              name: "缂栬緫",
+              clickFun: handleAdd,
+              color: "#409EFF",
+            };
+          case "viewFile":
+            return {
+              name: "鏌ョ湅闄勪欢",
+              clickFun: viewFile,
+              color: "#67C23A",
+            };
+          default:
+            return null;
         }
       })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
-      });
+      .filter(Boolean),
   };
+};
+
+const loadAreaTree = async () => {
+  const { data } = await getDeviceAreaTree();
+  areaOptions.value = Array.isArray(data) ? data : [];
+};
+
+onMounted(() => {
+  loadAreaTree();
+  radioChange("taskManage");
+});
+
+const radioChange = (value) => {
+  if (value === "taskManage") {
+    const operationColumn = getOperationColumn(["edit"]);
+    tableColumns.value = [...columns.value, isEnabledColumn, ...(operationColumn ? [operationColumn] : [])];
+  } else {
+    const operationColumn = getOperationColumn(["viewFile"]);
+    // 瀹氭椂浠诲姟璁板綍娣诲姞宸℃鐘舵�佸垪
+    tableColumns.value = [...columns.value, inspectionStatusColumn, inspectionResultColumn, ...(operationColumn ? [operationColumn] : [])];
+    // 鍒囨崲鍒板畾鏃朵换鍔¤褰曟椂锛岄粯璁ゆ煡璇㈠綋澶�
+    queryDate.value = dayjs().format("YYYY-MM-DD");
+    queryParams.isEnabled = undefined;
+  }
+  pageNum.value = 1;
+  pageSize.value = 10;
+  getList();
+};
+
+const handleQuery = () => {
+  pageNum.value = 1;
+  pageSize.value = 10;
+  getList();
+};
+
+const handlePagination = (val) => {
+  pageNum.value = val.page;
+  pageSize.value = val.limit;
+  getList();
+};
+
+const getList = () => {
+  tableLoading.value = true;
+  // 璁剧疆鏃ユ湡鍙傛暟锛堝畾鏃朵换鍔¤褰曟椂锛�
+  if (activeRadio.value === "task" && queryDate.value) {
+    queryParams.createTimeStart = `${queryDate.value} 00:00:00`;
+    queryParams.createTimeEnd = `${queryDate.value} 23:59:59`;
+  } else {
+    queryParams.createTimeStart = undefined;
+    queryParams.createTimeEnd = undefined;
+  }
+  const params = {
+    ...queryParams,
+    size: pageSize.value,
+    current: pageNum.value,
+  };
+  const apiCall =
+    activeRadio.value === "task" ? inspectionTaskList(params) : timingTaskList(params);
+
+  apiCall
+    .then((res) => {
+      const rawData = res?.data?.records || [];
+      tableData.value = rawData.map((item) => {
+        const processedItem = { ...item };
+        if (activeRadio.value === "taskManage") {
+          processedItem.isEnabled = Number(
+            processedItem.isEnabled ?? processedItem.status ?? 1
+          );
+          processedItem.enableSwitchLoading = false;
+        }
+        if (processedItem.inspector) {
+          if (typeof processedItem.inspector === "string") {
+            processedItem.inspector = processedItem.inspector
+              .split(",")
+              .map((text) => text.trim())
+              .filter(Boolean);
+          } else if (!Array.isArray(processedItem.inspector)) {
+            processedItem.inspector = [processedItem.inspector];
+          }
+        } else {
+          processedItem.inspector = [];
+        }
+        return processedItem;
+      });
+      total.value = res?.data?.total || 0;
+    })
+    .finally(() => {
+      tableLoading.value = false;
+    });
+};
+
+const resetQuery = () => {
+  queryParams.taskName = "";
+  queryParams.areaId = undefined;
+  queryParams.isEnabled = undefined;
+  queryParams.createTimeStart = undefined;
+  queryParams.createTimeEnd = undefined;
+  // 瀹氭椂浠诲姟璁板綍鏃堕噸缃负褰撳ぉ
+  queryDate.value = dayjs().format("YYYY-MM-DD");
+  handleQuery();
+};
+
+const handleAdd = (row) => {
+  const type = row ? "edit" : "add";
+  nextTick(() => {
+    formDia.value?.openDialog(type, row);
+  });
+};
+
+const viewFile = (row) => {
+  nextTick(() => {
+    viewFiles.value?.openDialog(row);
+  });
+};
+
+const handleDelete = () => {
+  if (!selectedRows.value.length) {
+    proxy.$modal.msgWarning("璇烽�夋嫨瑕佸垹闄ょ殑鏁版嵁");
+    return;
+  }
+  const deleteIds = selectedRows.value.map((item) => item.id);
+  proxy.$modal
+    .confirm("鏄惁纭鍒犻櫎鎵�閫夋暟鎹」锛�")
+    .then(() => delTimingTask(deleteIds))
+    .then(() => {
+      proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+      handleQuery();
+    })
+    .catch(() => {});
+};
+
+const handleSelectionChange = (selection) => {
+  selectedRows.value = selection;
+};
+
+const handleTimingTaskEnableBeforeChange = async (row) => {
+  if (row.enableSwitchLoading) {
+    return false;
+  }
+  const nextValue = Number(row.isEnabled) === 1 ? 0 : 1;
+  row.enableSwitchLoading = true;
+  try {
+    const res = await changeTimingTaskEnable({
+      id: row.id,
+      isEnabled: nextValue,
+    });
+    if (res?.code !== 200) {
+      throw new Error(res?.msg || "鏇存柊澶辫触");
+    }
+    ElMessage.success("鍚敤鐘舵�佸凡鏇存柊");
+    return true;
+  } catch (error) {
+    proxy.$modal.msgError(error?.message || "鍚敤鐘舵�佹洿鏂板け璐�");
+    return false;
+  } finally {
+    row.enableSwitchLoading = false;
+  }
+};
+
+const handleOut = () => {
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
+    .then(() => {
+      if (activeRadio.value === "taskManage") {
+        proxy.download("/timingTask/export", {}, "瀹氭椂浠诲姟绠$悊.xlsx");
+      } else {
+        proxy.download("/inspectionTask/export", {}, "瀹氭椂浠诲姟璁板綍.xlsx");
+      }
+    })
+    .catch(() => {
+      proxy.$modal.msg("宸插彇娑�");
+    });
+};
 </script>
 
 <style scoped>
-  .person-tags {
-    display: flex;
-    flex-wrap: wrap;
-    gap: 4px;
-  }
+.toolbar {
+  display: flex;
+  flex-direction: row;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
 
-  .person-tag {
-    margin-right: 4px;
-    margin-bottom: 2px;
-  }
+.person-tags {
+  display: flex;
+  flex-wrap: wrap;
+  gap: 4px;
+}
 
-  .no-data {
-    color: #909399;
-    font-size: 14px;
-  }
+.person-tag {
+  margin-right: 4px;
+  margin-bottom: 2px;
+}
+
+.no-data {
+  color: #909399;
+  font-size: 14px;
+}
 </style>
diff --git a/src/views/equipmentManagement/ledger/Modal.vue b/src/views/equipmentManagement/ledger/Modal.vue
index 16166c6..3870862 100644
--- a/src/views/equipmentManagement/ledger/Modal.vue
+++ b/src/views/equipmentManagement/ledger/Modal.vue
@@ -62,8 +62,15 @@
   formRef.value.loadForm(id);
 };
 
+const openCreateModal = async (areaId) => {
+  openModal();
+  await nextTick();
+  formRef.value.setAreaId(areaId);
+};
+
 defineExpose({
   openModal,
   loadForm,
+  openCreateModal,
 });
 </script>
diff --git a/src/views/equipmentManagement/ledger/index.vue b/src/views/equipmentManagement/ledger/index.vue
index af10532..ebc0325 100644
--- a/src/views/equipmentManagement/ledger/index.vue
+++ b/src/views/equipmentManagement/ledger/index.vue
@@ -1,85 +1,191 @@
 <template>
-  <div class="app-container">
-    <el-form :model="filters" :inline="true">
-      <el-form-item label="璁惧鍚嶇О">
+  <div class="app-container ledger-view">
+    <div class="left-panel">
+      <div class="tree-toolbar">
         <el-input
-          v-model="filters.deviceName"
-          style="width: 200px"
-          placeholder="璇疯緭鍏ヨ澶囧悕绉�"
+          v-model="treeKeyword"
+          style="width: calc(100% - 102px)"
+          placeholder="璇疯緭鍏ュ尯鍩熷悕绉�"
           clearable
-          @change="getTableData"
+          prefix-icon="Search"
+          @input="filterTree"
+          @clear="filterTree"
         />
-      </el-form-item>
-      <el-form-item label="瑙勬牸鍨嬪彿">
-        <el-input
+        <el-button type="primary" @click="openAreaDialog('addRoot')">鏂板鍖哄煙</el-button>
+      </div>
+      <div class="tree-actions">
+        <el-button link type="primary" @click="resetTreeSelection">鍏ㄩ儴鍖哄煙</el-button>
+      </div>
+      <el-tree
+        ref="treeRef"
+        v-loading="treeLoading"
+        :data="treeData"
+        :props="treeProps"
+        node-key="id"
+        highlight-current
+        default-expand-all
+        :expand-on-click-node="false"
+        :filter-node-method="filterTreeNode"
+        class="ledger-tree"
+        @node-click="handleTreeNodeClick"
+      >
+        <template #default="{ node, data }">
+          <div class="tree-node">
+            <span class="tree-node-content">
+              <el-icon class="tree-node-icon">
+                <component
+                  :is="
+                    data.children && data.children.length > 0
+                      ? node.expanded
+                        ? 'FolderOpened'
+                        : 'Folder'
+                      : 'Tickets'
+                  "
+                />
+              </el-icon>
+              <span class="tree-node-label">{{ data.areaName }}</span>
+            </span>
+            <div class="tree-node-actions">
+              <el-button link type="primary" @click.stop="openAreaDialog('edit', data)">缂栬緫</el-button>
+              <el-button link type="primary" @click.stop="openAreaDialog('addChild', data)">鏂板</el-button>
+              <el-button
+                v-if="!hasChildren(data)"
+                link
+                type="danger"
+                @click.stop="handleDeleteArea(data)"
+              >
+                鍒犻櫎
+              </el-button>
+            </div>
+          </div>
+        </template>
+      </el-tree>
+    </div>
+
+    <div class="right-panel">
+      <el-form :model="filters" :inline="true">
+        <el-form-item label="璁惧鍚嶇О">
+          <el-input
+            v-model="filters.deviceName"
+            style="width: 200px"
+            placeholder="璇疯緭鍏ヨ澶囧悕绉�"
+            clearable
+            @change="getTableData"
+          />
+        </el-form-item>
+        <el-form-item label="瑙勬牸鍨嬪彿">
+          <el-input
             v-model="filters.deviceModel"
             style="width: 200px"
             placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
             clearable
             @change="getTableData"
-        />
-      </el-form-item>
-      <el-form-item label="渚涘簲鍟�">
-        <el-input
+          />
+        </el-form-item>
+        <el-form-item label="渚涘簲鍟�">
+          <el-input
             v-model="filters.supplierName"
             style="width: 200px"
             placeholder="璇疯緭鍏ヤ緵搴斿晢"
             clearable
             @change="getTableData"
-        />
-      </el-form-item>
-      <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>
-      <el-form-item>
-        <el-button type="primary" @click="getTableData">鎼滅储</el-button>
-        <el-button @click="resetFilters">閲嶇疆</el-button>
-      </el-form-item>
-    </el-form>
-    <div class="table_list">
-      <div class="actions">
-        <div></div>
-        <div>
-          <el-button type="primary" @click="add" icon="Plus"> 鏂板 </el-button>
-          <el-button type="info" @click="handleImport" icon="Upload">瀵煎叆</el-button>
-          <el-button @click="handleOut" icon="download">瀵煎嚭</el-button>
-          <el-button
-            type="danger"
-            icon="Delete"
-            :disabled="multipleList.length <= 0"
-            @click="deleteRow(multipleList.map((item) => item.id))"
-          >
-            鎵归噺鍒犻櫎
-          </el-button>
+          />
+        </el-form-item>
+        <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>
+        <el-form-item>
+          <el-button type="primary" @click="getTableData">鎼滅储</el-button>
+          <el-button @click="handleResetFilters">閲嶇疆</el-button>
+        </el-form-item>
+      </el-form>
+
+      <div class="table_list">
+        <div class="actions">
+          <div class="actions-tip">
+            <span v-if="selectedAreaName">褰撳墠鍖哄煙锛歿{ selectedAreaName }}</span>
+          </div>
+          <div>
+            <el-button type="primary" icon="Plus" @click="add">鏂板</el-button>
+            <el-button type="info" icon="Upload" @click="handleImport">瀵煎叆</el-button>
+            <el-button icon="download" @click="handleOut">瀵煎嚭</el-button>
+            <el-button
+              type="danger"
+              icon="Delete"
+              :disabled="multipleList.length <= 0"
+              @click="deleteRow(multipleList.map((item) => item.id))"
+            >
+              鎵归噺鍒犻櫎
+            </el-button>
+          </div>
         </div>
+        <PIMTable
+          rowKey="id"
+          isSelection
+          :column="columns"
+          :tableData="dataList"
+          :page="{
+            current: pagination.currentPage,
+            size: pagination.pageSize,
+            total: pagination.total,
+          }"
+          @selection-change="handleSelectionChange"
+          @pagination="changePage"
+        />
       </div>
-      <PIMTable
-        rowKey="id"
-        isSelection
-        :column="columns"
-        :tableData="dataList"
-        :page="{
-          current: pagination.currentPage,
-          size: pagination.pageSize,
-          total: pagination.total,
-        }"
-        @selection-change="handleSelectionChange"
-        @pagination="changePage"
-      >
-      </PIMTable>
     </div>
-    <Modal ref="modalRef" @success="getTableData"></Modal>
+
+    <Modal ref="modalRef" @success="getTableData" />
+
+    <el-dialog
+      v-model="areaDialogVisible"
+      :title="areaDialogTitle"
+      width="480px"
+      @close="closeAreaDialog"
+    >
+      <el-form ref="areaFormRef" :model="areaForm" :rules="areaRules" label-width="88px">
+        <el-form-item label="鍖哄煙鍚嶇О" prop="areaName">
+          <el-input v-model="areaForm.areaName" placeholder="璇疯緭鍏ュ尯鍩熷悕绉�" />
+        </el-form-item>
+        <el-form-item label="鎺掑簭" prop="sort">
+          <el-input-number v-model="areaForm.sort" :min="0" :step="1" style="width: 100%" />
+        </el-form-item>
+        <el-form-item label="澶囨敞" prop="remark">
+          <el-input
+            v-model="areaForm.remark"
+            type="textarea"
+            :rows="4"
+            maxlength="200"
+            show-word-limit
+            placeholder="璇疯緭鍏ュ娉�"
+          />
+        </el-form-item>
+      </el-form>
+      <template #footer>
+        <div class="dialog-footer">
+          <el-button type="primary" @click="submitAreaForm">纭畾</el-button>
+          <el-button @click="closeAreaDialog">鍙栨秷</el-button>
+        </div>
+      </template>
+    </el-dialog>
+
     <el-dialog v-model="qrDialogVisible" title="浜岀淮鐮�" width="300px" draggable>
-      <div style="text-align:center;">
-        <img :src="qrCodeUrl" alt="浜岀淮鐮�" style="width:200px;height:200px;" />
-        <div style="margin:10px 0;">
+      <div class="qr-dialog">
+        <img :src="qrCodeUrl" alt="浜岀淮鐮�" class="qr-image" />
+        <div class="qr-footer">
           <el-button type="primary" @click="downloadQRCode">涓嬭浇浜岀淮鐮佸浘鐗�</el-button>
         </div>
       </div>
     </el-dialog>
-    
-    <!-- 瀵煎叆瀵硅瘽妗� -->
+
     <el-dialog :title="upload.title" v-model="upload.open" width="400px" append-to-body>
       <el-upload
         ref="uploadRef"
@@ -97,55 +203,23 @@
         <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; margin-left: 5px;" @click="importTemplate">涓嬭浇妯℃澘</el-link>
+            <span>浠呭厑璁稿鍏� xls銆亁lsx 鏍煎紡鏂囦欢銆�</span>
+            <el-link
+              type="primary"
+              :underline="false"
+              style="font-size: 12px; vertical-align: baseline; margin-left: 5px"
+              @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>
+          <el-button type="primary" @click="submitFileForm">纭畾</el-button>
+          <el-button @click="upload.open = false">鍙栨秷</el-button>
         </div>
-      </template>
-    </el-dialog>
-
-    <!-- 璇︽儏瀵硅瘽妗� -->
-    <el-dialog v-model="detailDialogVisible" title="璁惧鍙拌处璇︽儏" width="60%" draggable>
-      <el-descriptions :column="2" border>
-        <el-descriptions-item label="璁惧鍚嶇О">{{ detailData.deviceName }}</el-descriptions-item>
-        <el-descriptions-item label="瑙勬牸鍨嬪彿">{{ detailData.deviceModel }}</el-descriptions-item>
-        <el-descriptions-item label="璁惧鍝佺墝">{{ detailData.deviceBrand }}</el-descriptions-item>
-        <el-descriptions-item label="璁惧绫诲瀷">{{ detailData.type }}</el-descriptions-item>
-        <el-descriptions-item label="渚涘簲鍟�">{{ detailData.supplierName }}</el-descriptions-item>
-        <el-descriptions-item label="瀛樻斁浣嶇疆">{{ detailData.storageLocation }}</el-descriptions-item>
-        <el-descriptions-item label="鍗曚綅">{{ detailData.unit }}</el-descriptions-item>
-        <el-descriptions-item label="鏁伴噺">{{ detailData.number }}</el-descriptions-item>
-        <el-descriptions-item label="鍚敤鎶樻棫">{{ detailData.isDepr === 1 ? '鏄�' : '鍚�' }}</el-descriptions-item>
-        <el-descriptions-item label="姣忓勾鎶樻棫閲戦">{{ detailData.annualDepreciationAmount }}</el-descriptions-item>
-        <el-descriptions-item label="鍚◣鍗曚环">{{ detailData.taxIncludingPriceUnit }}</el-descriptions-item>
-        <el-descriptions-item label="鍚◣鎬讳环">{{ detailData.taxIncludingPriceTotal }}</el-descriptions-item>
-        <el-descriptions-item label="绋庣巼(%)">{{ detailData.taxRate }}</el-descriptions-item>
-        <el-descriptions-item label="涓嶅惈绋庢�讳环">{{ detailData.unTaxIncludingPriceTotal }}</el-descriptions-item>
-        <el-descriptions-item label="褰曞叆鏃ユ湡">{{ detailData.createTime }}</el-descriptions-item>
-        <el-descriptions-item label="棰勮杩愯鏃堕棿">{{ detailData.planRuntimeTime ? dayjs(detailData.planRuntimeTime).format('YYYY-MM-DD') : '' }}</el-descriptions-item>
-        <el-descriptions-item label="璁惧鍥剧墖" :span="2">
-          <div v-if="detailData.storageBlobVOs && detailData.storageBlobVOs.length > 0" style="display: flex; gap: 10px; flex-wrap: wrap;">
-            <el-image 
-              v-for="(file, index) in detailData.storageBlobVOs" 
-              :key="index" 
-              :src="file.previewURL || file.url" 
-              :preview-src-list="detailData.storageBlobVOs.map(u => u.previewURL || u.url)"
-              :initial-index="index"
-              style="width: 100px; height: 100px" 
-              fit="cover" 
-            />
-          </div>
-          <span v-else>鏃犲浘鐗�</span>
-        </el-descriptions-item>
-      </el-descriptions>
-      <template #footer>
-        <el-button @click="detailDialogVisible = false">鍏抽棴</el-button>
       </template>
     </el-dialog>
   </div>
@@ -153,8 +227,14 @@
 
 <script setup>
 import { usePaginationApi } from "@/hooks/usePaginationApi";
-// import { Search } from "@element-plus/icons-vue";
-import { getLedgerPage, delLedger, getLedgerById } from "@/api/equipmentManagement/ledger";
+import { getLedgerPage, delLedger } from "@/api/equipmentManagement/ledger";
+import {
+  getDeviceAreaTree,
+  getDeviceAreaDetail,
+  addDeviceArea,
+  updateDeviceArea,
+  deleteDeviceArea,
+} from "@/api/equipmentManagement/deviceArea";
 import { onMounted, getCurrentInstance, ref, reactive } from "vue";
 import Modal from "./Modal.vue";
 import { ElMessageBox, ElMessage } from "element-plus";
@@ -167,31 +247,47 @@
   name: "璁惧鍙拌处",
 });
 
-// 琛ㄦ牸澶氶�夋閫変腑椤�
 const multipleList = ref([]);
 const { proxy } = getCurrentInstance();
 const modalRef = ref();
+const treeRef = ref();
+const areaFormRef = ref();
+const treeKeyword = ref("");
+const treeLoading = ref(false);
+const treeData = ref([]);
+const selectedAreaName = ref("");
+const areaDialogVisible = ref(false);
+const areaDialogTitle = ref("鏂板鍖哄煙");
+const areaDialogMode = ref("addRoot");
 const qrDialogVisible = ref(false);
 const qrCodeUrl = ref("");
 const qrRowData = ref(null);
+const uploadRef = ref(null);
 
-const detailDialogVisible = ref(false);
-const detailData = ref({});
+const treeProps = {
+  children: "children",
+  label: "areaName",
+};
 
-// 瀵煎叆鐩稿叧
-const uploadRef = ref(null)
 const upload = reactive({
-  // 鏄惁鏄剧ず寮瑰嚭灞�
   open: false,
-  // 寮瑰嚭灞傛爣棰�
   title: "",
-  // 鏄惁绂佺敤涓婁紶
   isUploading: false,
-  // 璁剧疆涓婁紶鐨勮姹傚ご閮�
   headers: { Authorization: "Bearer " + getToken() },
-  // 涓婁紶鐨勫湴鍧�
-  url: import.meta.env.VITE_APP_BASE_API + "/device/ledger/import"
-})
+  url: import.meta.env.VITE_APP_BASE_API + "/device/ledger/import",
+});
+
+const areaForm = reactive({
+  id: undefined,
+  areaName: "",
+  parentId: undefined,
+  sort: 0,
+  remark: "",
+});
+
+const areaRules = {
+  areaName: [{ required: true, message: "璇疯緭鍏ュ尯鍩熷悕绉�", trigger: "blur" }],
+};
 
 const {
   filters,
@@ -199,7 +295,6 @@
   dataList,
   pagination,
   getTableData,
-  resetFilters,
   onCurrentChange,
 } = usePaginationApi(
   getLedgerPage,
@@ -207,10 +302,17 @@
     deviceName: undefined,
     deviceModel: undefined,
     supplierName: undefined,
+    entryDate: undefined,
     entryDateStart: undefined,
     entryDateEnd: undefined,
+    areaId: undefined,
+    areaName: undefined,
   },
   [
+    {
+      label: "鎵�鍦ㄥ尯鍩�",
+      prop: "areaName",
+    },
     {
       label: "璁惧鍚嶇О",
       prop: "deviceName",
@@ -219,10 +321,10 @@
       label: "瑙勬牸鍨嬪彿",
       prop: "deviceModel",
     },
-    {
-      label: "璁惧鍝佺墝",
-      prop: "deviceBrand",
-    },
+    // {
+    //   label: "璁惧鍝佺墝",
+    //   prop: "deviceBrand",
+    // },
     {
       label: "璁惧绫诲瀷",
       prop: "type",
@@ -247,45 +349,162 @@
       label: "褰曞叆鏃ユ湡",
       prop: "createTime",
       formatData: (v) => {
-        if (!v) return '';
-        // 濡傛灉鍖呭惈鏃跺垎绉掞紝鍙彇鏃ユ湡閮ㄥ垎
-        if (v.includes(' ')) {
-          return v.split(' ')[0];
-        }
-        return v;
+        if (!v) return "";
+        return v.includes(" ") ? v.split(" ")[0] : v;
       },
     },
-		{
-			dataType: "action",
-			label: "鎿嶄綔",
-			align: "center",
-			fixed: 'right',
-			width: 180,
-			operation: [
+    {
+      label: "鐗╄仈璁惧",
+      prop: "isIotDevice",
+      formatData: (v) => {
+        return v === 1 ? "鏄�" : "鍚�";
+      },
+    },
+    {
+      label: "澶栭儴缂栫爜",
+      prop: "externalCode",
+    },
+    {
+      dataType: "action",
+      label: "鎿嶄綔",
+      align: "center",
+      fixed: "right",
+      width: 150,
+      operation: [
         {
-          name: "璇︽儏",
+          name: "缂栬緫",
           clickFun: (row) => {
-            handleDetail(row);
+            edit(row.id);
           },
         },
-				{
-					name: "缂栬緫",
-					clickFun: (row) => {
-						edit(row.id)
-					},
-				},
-				{
-					name: "浜岀淮鐮�",
-					clickFun: (row) => {
-						showQRCode(row)
-					},
-				},
-			],
-		},
+        {
+          name: "鐢熸垚浜岀淮鐮�",
+          clickFun: (row) => {
+            showQRCode(row);
+          },
+        },
+      ],
+    },
   ]
 );
 
-// 澶氶�夊悗鍋氫粈涔�
+const loadTreeData = async () => {
+  treeLoading.value = true;
+  try {
+    const res = await getDeviceAreaTree();
+    treeData.value = Array.isArray(res?.data) ? res.data : Array.isArray(res) ? res : [];
+  } finally {
+    treeLoading.value = false;
+  }
+};
+
+const resetAreaForm = () => {
+  areaForm.id = undefined;
+  areaForm.areaName = "";
+  areaForm.parentId = undefined;
+  areaForm.sort = 0;
+  areaForm.remark = "";
+};
+
+const filterTree = () => {
+  treeRef.value?.filter(treeKeyword.value);
+};
+
+const filterTreeNode = (value, data) => {
+  if (!value) {
+    return true;
+  }
+  return String(data.areaName || "").includes(value);
+};
+
+const handleTreeNodeClick = (data) => {
+  filters.areaId = data.id;
+  filters.areaName = data.areaName;
+  selectedAreaName.value = data.areaName || "";
+  getTableData();
+};
+
+const openAreaDialog = async (mode, row) => {
+  areaDialogMode.value = mode;
+  areaDialogTitle.value =
+    mode === "edit" ? "缂栬緫鍖哄煙" : mode === "addChild" ? "鏂板瀛愬尯鍩�" : "鏂板鍖哄煙";
+  resetAreaForm();
+  areaDialogVisible.value = true;
+  if (mode === "addChild") {
+    areaForm.parentId = row.id;
+    areaForm.sort = 0;
+    return;
+  }
+  if (mode === "edit" && row?.id) {
+    const res = await getDeviceAreaDetail(row.id);
+    const detail = res?.data || {};
+    areaForm.id = detail.id;
+    areaForm.areaName = detail.areaName || "";
+    areaForm.parentId = detail.parentId;
+    areaForm.sort = detail.sort ?? 0;
+    areaForm.remark = detail.remark || "";
+  }
+};
+
+const closeAreaDialog = () => {
+  areaDialogVisible.value = false;
+  areaFormRef.value?.resetFields();
+  resetAreaForm();
+};
+
+const submitAreaForm = () => {
+  areaFormRef.value?.validate(async (valid) => {
+    if (!valid) {
+      return;
+    }
+    const submitData = {
+      id: areaForm.id,
+      areaName: areaForm.areaName,
+      parentId: areaForm.parentId,
+      sort: areaForm.sort,
+      remark: areaForm.remark,
+    };
+    const request = areaDialogMode.value === "edit" ? updateDeviceArea : addDeviceArea;
+    const { code } = await request(submitData);
+    if (code === 200) {
+      ElMessage.success(areaDialogMode.value === "edit" ? "淇敼鎴愬姛" : "鏂板鎴愬姛");
+      closeAreaDialog();
+      await loadTreeData();
+    }
+  });
+};
+
+const handleDeleteArea = (row) => {
+  if (hasChildren(row)) {
+    ElMessage.warning("褰撳墠鍖哄煙瀛樺湪涓嬬骇鍖哄煙锛屼笉鑳藉垹闄�");
+    return;
+  }
+  ElMessageBox.confirm("姝ゆ搷浣滃皢鍒犻櫎璇ヨ澶囧尯鍩燂紝鏄惁缁х画锛�", "鎻愮ず", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(async () => {
+    const { code } = await deleteDeviceArea([row.id]);
+    if (code === 200) {
+      ElMessage.success("鍒犻櫎鎴愬姛");
+      if (filters.areaId === row.id) {
+        resetTreeSelection();
+      }
+      await loadTreeData();
+    }
+  });
+};
+
+const hasChildren = (row) => Array.isArray(row?.children) && row.children.length > 0;
+
+const resetTreeSelection = () => {
+  treeRef.value?.setCurrentKey(null);
+  selectedAreaName.value = "";
+  filters.areaId = undefined;
+  filters.areaName = undefined;
+  getTableData();
+};
+
 const handleSelectionChange = (selectionList) => {
   multipleList.value = selectionList;
 };
@@ -293,23 +512,19 @@
 const add = () => {
   modalRef.value.openModal();
 };
+
 const edit = (id) => {
   modalRef.value.loadForm(id);
 };
-const handleDetail = async (row) => {
-  const { code, data } = await getLedgerById(row.id);
-  if (code == 200) {
-    detailData.value = data;
-    detailDialogVisible.value = true;
-  }
-};
+
 const changePage = ({ page, limit }) => {
   pagination.currentPage = page;
-	pagination.pageSize = limit;
+  pagination.pageSize = limit;
   onCurrentChange(page);
 };
+
 const deleteRow = (id) => {
-  ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ枃浠�, 鏄惁缁х画?", "鎻愮ず", {
+  ElMessageBox.confirm("姝ゆ搷浣滃皢姘镐箙鍒犻櫎璇ユ暟鎹紝鏄惁缁х画锛�", "鎻愮ず", {
     confirmButtonText: "纭畾",
     cancelButtonText: "鍙栨秷",
     type: "warning",
@@ -336,14 +551,24 @@
   getTableData();
 };
 
+const handleResetFilters = () => {
+  filters.deviceName = undefined;
+  filters.deviceModel = undefined;
+  filters.supplierName = undefined;
+  filters.entryDate = undefined;
+  filters.entryDateStart = undefined;
+  filters.entryDateEnd = undefined;
+  getTableData();
+};
+
 const handleOut = () => {
-  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+  ElMessageBox.confirm("褰撳墠鏌ヨ缁撴灉灏嗚瀵煎嚭锛屾槸鍚︾‘璁ゅ鍑猴紵", "瀵煎嚭", {
     confirmButtonText: "纭",
     cancelButtonText: "鍙栨秷",
     type: "warning",
   })
     .then(() => {
-      proxy.download(`/device/ledger/export`, {}, "璁惧鍙拌处妗f.xlsx");
+      proxy.download("/device/ledger/export", {}, "璁惧鍙拌处妗f.xlsx");
     })
     .catch(() => {
       proxy.$modal.msg("宸插彇娑�");
@@ -351,36 +576,8 @@
 };
 
 const showQRCode = async (row) => {
-  // 鐩存帴浣跨敤URL锛屼笉瑕佺敤JSON.stringify鍖呰
-  const qrContent = proxy.javaApi + '/device-info?deviceId=' + row.id;
-  const qrDataUrl = await QRCode.toDataURL(qrContent, { width: 200, margin: 2 });
-  
-  // 鍒涘缓canvas鍚堟垚甯﹀悕绉扮殑浜岀淮鐮佸浘鐗�
-  const canvas = document.createElement('canvas');
-  const ctx = canvas.getContext('2d');
-  const qrSize = 200;
-  const textHeight = 30;
-  const padding = 10;
-  canvas.width = qrSize + padding * 2;
-  canvas.height = qrSize + textHeight + padding * 2;
-  
-  // 濉厖鐧借壊鑳屾櫙
-  ctx.fillStyle = '#ffffff';
-  ctx.fillRect(0, 0, canvas.width, canvas.height);
-  
-  // 缁樺埗浜岀淮鐮�
-  const qrImg = new Image();
-  qrImg.src = qrDataUrl;
-  await new Promise((resolve) => { qrImg.onload = resolve; });
-  ctx.drawImage(qrImg, padding, padding, qrSize, qrSize);
-  
-  // 缁樺埗璁惧鍚嶇О
-  ctx.fillStyle = '#333333';
-  ctx.font = 'bold 14px Arial';
-  ctx.textAlign = 'center';
-  ctx.fillText(row.deviceName || '', canvas.width / 2, qrSize + padding + 20);
-  
-  qrCodeUrl.value = canvas.toDataURL('image/png');
+  const qrContent = proxy.javaApi + "/device-info?deviceId=" + row.id;
+  qrCodeUrl.value = await QRCode.toDataURL(qrContent);
   qrRowData.value = row;
   qrDialogVisible.value = true;
 };
@@ -392,48 +589,141 @@
   a.click();
 };
 
-// 瀵煎叆鎸夐挳鎿嶄綔
 const handleImport = () => {
-  upload.title = "璁惧鍙拌处瀵煎叆"
-  upload.open = true
-}
+  upload.title = "璁惧鍙拌处瀵煎叆";
+  upload.open = true;
+};
 
-// 涓嬭浇妯℃澘鎿嶄綔
 const importTemplate = () => {
-  proxy.download("/device/ledger/downloadTemplate", {}, `璁惧鍙拌处瀵煎叆妯℃澘_${new Date().getTime()}.xlsx`)
-}
+  proxy.download("/device/ledger/downloadTemplate", {}, `璁惧鍙拌处瀵煎叆妯℃澘_${new Date().getTime()}.xlsx`);
+};
 
-// 鏂囦欢涓婁紶涓鐞�
-const handleFileUploadProgress = (event, file, fileList) => {
-  upload.isUploading = true
-}
+const handleFileUploadProgress = () => {
+  upload.isUploading = true;
+};
 
-// 鏂囦欢涓婁紶鎴愬姛澶勭悊
-const handleFileSuccess = (response, file, fileList) => {
-  upload.open = false
-  upload.isUploading = false
-  proxy.$refs["uploadRef"].handleRemove(file)
-  proxy.$alert("<div style='overflow: auto;overflow-x: hidden;max-height: 70vh;padding: 10px 20px 0;'>" + response.msg + "</div>", "瀵煎叆缁撴灉", { dangerouslyUseHTMLString: true })
-  getTableData()
-}
+const handleFileSuccess = (response, file) => {
+  upload.open = false;
+  upload.isUploading = false;
+  uploadRef.value?.handleRemove(file);
+  proxy.$alert(
+    "<div style='overflow:auto;overflow-x:hidden;max-height:70vh;padding:10px 20px 0;'>" +
+      response.msg +
+      "</div>",
+    "瀵煎叆缁撴灉",
+    { dangerouslyUseHTMLString: true }
+  );
+  getTableData();
+};
 
-// 鎻愪氦涓婁紶鏂囦欢
 const submitFileForm = () => {
-  proxy.$refs["uploadRef"].submit()
-}
+  uploadRef.value?.submit();
+};
 
-onMounted(() => {
+onMounted(async () => {
+  await loadTreeData();
   getTableData();
 });
 </script>
 
 <style lang="scss" scoped>
-.table_list {
-  margin-top: unset;
+.ledger-view {
+  display: flex;
+  gap: 20px;
 }
+
+.left-panel {
+  width: 320px;
+  min-width: 320px;
+  padding: 16px;
+  background: #fff;
+  border-radius: 4px;
+}
+
+.right-panel {
+  flex: 1;
+  min-width: 0;
+  padding: 16px;
+  background: #fff;
+  border-radius: 4px;
+}
+
+.tree-toolbar {
+  display: flex;
+  gap: 10px;
+  align-items: center;
+  margin-bottom: 8px;
+}
+
+.tree-actions {
+  display: flex;
+  justify-content: flex-end;
+  margin-bottom: 8px;
+}
+
+.ledger-tree {
+  height: calc(100vh - 230px);
+  overflow-y: auto;
+}
+
+.tree-node {
+  flex: 1;
+  min-width: 0;
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  gap: 8px;
+}
+
+.tree-node-content {
+  display: flex;
+  align-items: center;
+  min-width: 0;
+}
+
+.tree-node-icon {
+  color: #e6a23c;
+  margin-right: 8px;
+  font-size: 18px;
+}
+
+.tree-node-label {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.tree-node-actions {
+  flex-shrink: 0;
+}
+
+.table_list {
+  margin-top: 0;
+}
+
 .actions {
   display: flex;
   justify-content: space-between;
+  align-items: center;
   margin-bottom: 10px;
+  gap: 12px;
+}
+
+.actions-tip {
+  color: #606266;
+  font-size: 14px;
+}
+
+.qr-dialog {
+  text-align: center;
+}
+
+.qr-image {
+  width: 200px;
+  height: 200px;
+}
+
+.qr-footer {
+  margin: 10px 0;
 }
 </style>
diff --git a/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue b/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
index 923dd2c..b7fa07e 100644
--- a/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
+++ b/src/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue
@@ -228,6 +228,39 @@
 	form.value.entryDate = getCurrentDate();
 }
 
+// 涓婁紶鍓嶆牎妫�
+function handleBeforeUpload(file) {
+	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) {
+		file.tempId = res.data.tempId;
+		form.value.tempFileIds.push(file.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("鍒犻櫎鎴愬姛");
+		});
+	}
+}
+
 // 澶勭悊鏈夋晥鏃ユ湡杈撳叆锛屽彧鍏佽姝f暣鏁�
 const handleValidInput = (value) => {
 	if (value === '' || value === null || value === undefined) {
diff --git a/src/views/equipmentManagement/measurementEquipment/components/dialogForm.vue b/src/views/equipmentManagement/measurementEquipment/components/dialogForm.vue
deleted file mode 100644
index c6aa70e..0000000
--- a/src/views/equipmentManagement/measurementEquipment/components/dialogForm.vue
+++ /dev/null
@@ -1,7 +0,0 @@
-<template>
-
-</template>
-
-<script setup>
-
-</script>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/measurementEquipment/index.vue b/src/views/equipmentManagement/measurementEquipment/index.vue
index 007eef6..46ca100 100644
--- a/src/views/equipmentManagement/measurementEquipment/index.vue
+++ b/src/views/equipmentManagement/measurementEquipment/index.vue
@@ -1,354 +1,298 @@
 <template>
-  <div class="app-container">
-    <div class="search_form mb20">
-      <div>
-        <span class="search_title">褰曞叆鏃ユ湡锛�</span>
-        <el-date-picker v-model="searchForm.recordDate"
-                        value-format="YYYY-MM-DD"
-                        format="YYYY-MM-DD"
-                        type="date"
-                        placeholder="璇烽�夋嫨"
-                        clearable
-                        style="width: 160px"
-                        @change="handleQuery" />
-        <span class="search_title ml10">璁¢噺鍣ㄥ叿缂栧彿锛�</span>
-        <el-input v-model="searchForm.code"
-                  placeholder="璇疯緭鍏ョ紪鍙�"
-                  clearable
-                  style="width: 240px"
-                  @change="handleQuery" />
-        <span class="search_title ml10">鐘舵�侊細</span>
-        <el-select v-model="searchForm.status"
-                   placeholder="璇烽�夋嫨鐘舵��"
-                   @change="handleQuery"
-                   style="width: 160px"
-                   clearable>
-          <el-option label="鏈夋晥"
-                     :value="1"></el-option>
-          <el-option label="閫炬湡"
-                     :value="2"></el-option>
-        </el-select>
-        <el-button type="primary"
-                   @click="handleQuery"
-                   style="margin-left: 10px">鎼滅储</el-button>
-        <el-button @click="handleReset"
-                   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>
-        <el-button @click="handleOut">瀵煎嚭</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"
-                :dbRowClick="dbRowClick"
-                :rowClassName="rowClassName"></PIMTable>
-    </div>
-    <form-dia ref="formDia"
-              @close="handleQuery"></form-dia>
-    <calibration-dia ref="calibrationDia"
-                     @close="handleQuery"></calibration-dia>
+	<div class="app-container">
+		<div class="search_form">
+			<div>
+				<span class="search_title">褰曞叆鏃ユ湡锛�</span>
+				<el-date-picker
+					v-model="searchForm.recordDate"
+					value-format="YYYY-MM-DD"
+					format="YYYY-MM-DD"
+					type="date"
+					placeholder="璇烽�夋嫨"
+					clearable
+					style="width: 160px"
+					@change="handleQuery"
+				/>
+				<span class="search_title ml10">璁¢噺鍣ㄥ叿缂栧彿锛�</span>
+				<el-input v-model="searchForm.code" placeholder="璇疯緭鍏ョ紪鍙�" clearable style="width: 240px" @change="handleQuery"/>
+				<span class="search_title ml10">鐘舵�侊細</span>
+				<el-select v-model="searchForm.status" placeholder="璇烽�夋嫨鐘舵��" @change="handleQuery" style="width: 160px" clearable>
+					<el-option label="鏈夋晥" :value="1"></el-option>
+					<el-option label="閫炬湡" :value="2"></el-option>
+				</el-select>
+				<el-button type="primary" @click="handleQuery" style="margin-left: 10px"
+				>鎼滅储</el-button
+				>
+				<el-button @click="handleReset" 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>
+				<el-button @click="handleOut">瀵煎嚭</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"
+        :dbRowClick="dbRowClick"
+			></PIMTable>
+		</div>
+		<form-dia ref="formDia" @close="handleQuery"></form-dia>
+		<calibration-dia ref="calibrationDia" @close="handleQuery"></calibration-dia>
     <files-dia ref="filesDia"></files-dia>
     <rowClickDataForm ref="rowClickData"></rowClickDataForm>
-  </div>
+	</div>
 </template>
 
 <script setup>
-  import {
-    onMounted,
-    ref,
-    reactive,
-    toRefs,
-    getCurrentInstance,
-    nextTick,
-  } from "vue";
-  import FormDia from "@/views/equipmentManagement/measurementEquipment/components/formDia.vue";
-  import { ElMessageBox } from "element-plus";
-  import useUserStore from "@/store/modules/user.js";
-  import CalibrationDia from "@/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue";
-  import {
-    measuringInstrumentDelete,
-    measuringInstrumentListPage,
-  } from "@/api/equipmentManagement/measurementEquipment.js";
-  import FilesDia from "./filesDia.vue";
-  import rowClickDataForm from "./components/rowClickData.vue";
-  const { proxy } = getCurrentInstance();
-  const userStore = useUserStore();
+import {onMounted, ref, reactive, toRefs, getCurrentInstance, nextTick} from "vue";
+import FormDia from "@/views/equipmentManagement/measurementEquipment/components/formDia.vue";
+import {ElMessageBox} from "element-plus";
+import useUserStore from "@/store/modules/user.js";
+import CalibrationDia from "@/views/equipmentManagement/measurementEquipment/components/calibrationDia.vue";
+import {
+  measuringInstrumentDelete,
+  measuringInstrumentListPage,
+} from "@/api/equipmentManagement/measurementEquipment.js";
+import FilesDia from "./filesDia.vue";
+import rowClickDataForm from "./components/rowClickData.vue"
+const { proxy } = getCurrentInstance();
+const userStore = useUserStore()
 
-  const data = reactive({
-    searchForm: {
-      recordDate: "",
-      code: "",
-      status: "",
-    },
-  });
-  const { searchForm } = toRefs(data);
+const data = reactive({
+	searchForm: {
+		recordDate: "",
+		code: "",
+		status: "",
+	},
+});
+const { searchForm } = toRefs(data);
 
-  const tableColumn = ref([
-    {
-      label: "鍑哄巶缂栧彿",
-      prop: "code",
-      minWidth: 150,
-      align: "center",
-    },
-    {
-      label: "璁¢噺鍣ㄥ叿鍚嶇О",
-      prop: "name",
-      width: "160px",
-      align: "center",
-    },
-    {
-      label: "妫�瀹氬崟浣�",
-      prop: "unit",
-      width: 200,
-      align: "center",
-    },
-    {
-      label: "璇佷功缂栧彿",
-      prop: "model",
-      width: 200,
-      align: "center",
-    },
-    {
-      label: "鏈�鏂伴壌瀹氭棩鏈�",
-      prop: "mostDate",
-      width: 130,
-      align: "center",
-    },
-    {
-      label: "褰曞叆浜�",
-      prop: "userName",
-      width: 130,
-      align: "center",
-    },
-    {
-      label: "褰曞叆鏃ユ湡",
-      prop: "recordDate",
-      align: "center",
-      minWidth: 130,
-    },
-    {
-      label: "鏈夋晥鏃ユ湡",
-      prop: "valid",
-      width: 130,
-      align: "center",
-    },
-    {
-      label: "鐘舵��",
-      prop: "status",
-      width: 130,
-      align: "center",
-      formatData: params => {
-        if (params === 1) {
-          return "鏈夋晥";
-        } else if (params === 2) {
-          return "閫炬湡";
-        } else {
-          return null;
-        }
-      },
-    },
-    {
-      dataType: "action",
-      label: "鎿嶄綔",
-      align: "center",
-      width: "130",
-      fixed: "right",
-      operation: [
-        {
-          name: "闄勪欢",
-          type: "text",
-          clickFun: row => {
-            openFilesFormDia(row);
-          },
-        },
-        {
-          name: "缂栬緫",
-          type: "text",
-          clickFun: row => {
-            openCalibrationDia("verifying", row);
-          },
-        },
-      ],
-    },
-  ]);
-  const tableData = ref([]);
-  const tableLoading = ref(false);
-  const rowClickData = ref([]);
-  const filesDia = ref();
-  const page = reactive({
-    current: 1,
-    size: 100,
-    total: 0,
-  });
-  const selectedRows = ref([]);
-
-  // 鎵撳紑闄勪欢寮规
-  const openFilesFormDia = row => {
-    filesDia.value?.openDialog(row, "measuring_instrument_ledger");
-  };
-
-  const dbRowClick = row => {
-    rowClickData.value?.openDialog(row);
-  };
-
-  // 琛屾牱寮忥細蹇埌鏈燂紙7澶╁唴锛夋垨閫炬湡鏍囩孩
-  const rowClassName = ({ row }) => {
-    console.log("rowClassName called:", row);
-    // valid 鏄湁鏁堝ぉ鏁帮紝mostDate 鏄渶鏂版瀹氭棩鏈�
-    if (row.valid && row.mostDate) {
-      const mostDate = new Date(row.mostDate);
-      // 璁$畻鍒版湡鏃ユ湡 = 妫�瀹氭棩鏈� + 鏈夋晥澶╂暟
-      const validDays = parseInt(row.valid) || 0;
-      const expireDate = new Date(mostDate);
-      expireDate.setDate(expireDate.getDate() + validDays);
-
-      const now = new Date();
-      const diffDays = Math.ceil((expireDate - now) / (1000 * 60 * 60 * 24));
-      console.log(
-        "row:",
-        row.code,
-        "validDays:",
-        validDays,
-        "expireDate:",
-        expireDate,
-        "diffDays:",
-        diffDays
-      );
-      // 7澶╁唴鍒版湡鎴栧凡閫炬湡閮芥爣绾�
-      if (diffDays <= 7) {
-        console.log("return warning-row");
-        return "warning-row";
+const tableColumn = ref([
+	{
+		label: "鍑哄巶缂栧彿",
+		prop: "code",
+    minWidth:150,
+    align:"center"
+	},
+  {
+    label: "璁¢噺鍣ㄥ叿鍚嶇О",
+    prop: "name",
+    width: '160px',
+    align: "center",
+  },
+	{
+		label: "瀹夎浣嶇疆",
+		prop: "instationLocation",
+		width: 150,
+    align:"center"
+	},
+	{
+		label: "妫�瀹氬崟浣�",
+		prop: "unit",
+		width: 200,
+    align:"center"
+	},
+	{
+		label: "璇佷功缂栧彿",
+		prop: "model",
+		width:200,
+    align:"center"
+	},
+	{
+		label: "鏈�鏂伴壌瀹氭棩鏈�",
+		prop: "mostDate",
+		width: 130,
+    align:"center"
+	},
+	{
+		label: "褰曞叆浜�",
+		prop: "userName",
+		width: 130,
+    align:"center"
+	},
+	{
+		label: "褰曞叆鏃ユ湡",
+		prop: "recordDate",
+    align:"center",
+    minWidth: 130
+	},
+	{
+		label: "鏈夋晥鏃ユ湡",
+		prop: "valid",
+		width: 130,
+    align:"center"
+	},
+  {
+    label: "妫�瀹氬懆鏈�(澶�)",
+    prop: "cycle",
+    width: 130,
+    align:"center"
+  },
+  {
+    label: "鐘舵��",
+    prop: "status",
+    width: 130,
+    align: "center",
+    formatData: (params) => {
+      if (params === 1) {
+        return "鏈夋晥";
+      } else if (params === 2) {
+        return "閫炬湡";
+      } else {
+        return null;
       }
-    } else {
-      console.log("row missing valid or mostDate:", row.valid, row.mostDate);
     }
-    return "";
-  };
+  },
+	{
+		dataType: "action",
+		label: "鎿嶄綔",
+		align: "center",
+		width: '130',
+		fixed: 'right',
+		operation: [
+      {
+      	name: "闄勪欢",
+      	type: "text",
+      	clickFun: (row) => {
+          openFilesFormDia(row);
+      	},
+      },
+			{
+				name: "鏌ョ湅",
+				type: "text",
+				clickFun: (row) => {
+					openCalibrationDia("verifying", row);
+				},
+			},
+		],
+	},
+]);
+const tableData = ref([]);
+const tableLoading = ref(false);
+const rowClickData = ref([])
+const filesDia = ref()
+const page = reactive({
+	current: 1,
+	size: 100,
+	total: 0,
+});
+const selectedRows = ref([]);
 
-  // 琛ㄦ牸閫夋嫨鏁版嵁
-  const handleSelectionChange = selection => {
-    selectedRows.value = selection;
-  };
-  const formDia = ref();
-  const calibrationDia = ref();
+// 鎵撳紑闄勪欢寮规
+const openFilesFormDia = (row) => {
+    filesDia.value?.openDialog(row,'璁¢噺鍣ㄥ叿鍙拌处')
+};
 
-  // 鏌ヨ鍒楄〃
-  /** 鎼滅储鎸夐挳鎿嶄綔 */
-  const handleQuery = () => {
-    page.current = 1;
-    getList();
-  };
+const dbRowClick = (row)=>{
+  rowClickData.value?.openDialog(row)
+}
 
-  // 閲嶇疆鎼滅储鏉′欢
-  const handleReset = () => {
-    searchForm.value.recordDate = "";
-    searchForm.value.code = "";
-    searchForm.value.status = "";
-    page.current = 1;
-    getList();
-  };
-  const pagination = obj => {
-    page.current = obj.page;
-    page.size = obj.limit;
-    getList();
-  };
-  const getList = () => {
-    tableLoading.value = true;
-    measuringInstrumentListPage({ ...searchForm.value, ...page })
-      .then(res => {
-        tableLoading.value = false;
-        tableData.value = res.data.records;
-        page.total = res.data.total;
-      })
-      .catch(err => {
-        tableLoading.value = false;
-      });
-  };
+// 琛ㄦ牸閫夋嫨鏁版嵁
+const handleSelectionChange = (selection) => {
+	selectedRows.value = selection;
+};
+const formDia = ref()
+const calibrationDia = ref()
 
-  // 鎵撳紑寮规
-  const openForm = (type, row) => {
-    nextTick(() => {
-      formDia.value?.openDialog(type, row);
-    });
-  };
-  // 鎵撳紑妫�瀹氭牎鍑嗗脊妗�
-  const openCalibrationDia = (type, row) => {
-    nextTick(() => {
-      calibrationDia.value?.openDialog(type, row);
-    });
-  };
+// 鏌ヨ鍒楄〃
+/** 鎼滅储鎸夐挳鎿嶄綔 */
+const handleQuery = () => {
+	page.current = 1;
+	getList();
+};
 
-  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;
-        measuringInstrumentDelete(ids)
-          .then(res => {
-            proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
-            getList();
-          })
-          .finally(() => {
-            tableLoading.value = false;
-          });
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
-      });
-  };
-  // 瀵煎嚭
-  const handleOut = () => {
-    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-      confirmButtonText: "纭",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    })
-      .then(() => {
-        proxy.download(
-          "/measuringInstrumentLedger/export",
-          {},
-          "璁¢噺鍣ㄥ叿鍙拌处.xlsx"
-        );
-      })
-      .catch(() => {
-        proxy.$modal.msg("宸插彇娑�");
-      });
-  };
-  onMounted(() => {
-    getList();
-  });
+// 閲嶇疆鎼滅储鏉′欢
+const handleReset = () => {
+	searchForm.value.recordDate = "";
+	searchForm.value.code = "";
+	searchForm.value.status = "";
+	page.current = 1;
+	getList();
+};
+const pagination = (obj) => {
+	page.current = obj.page;
+	page.size = obj.limit;
+	getList();
+};
+const getList = () => {
+	tableLoading.value = true;
+	measuringInstrumentListPage({ ...searchForm.value, ...page }).then((res) => {
+		tableLoading.value = false;
+		tableData.value = res.data.records;
+		page.total = res.data.total;
+	}).catch((err) => {
+		tableLoading.value = false;
+	})
+};
+
+// 鎵撳紑寮规
+const openForm = (type, row) => {
+	nextTick(() => {
+		formDia.value?.openDialog(type, row)
+	})
+};
+// 鎵撳紑妫�瀹氭牎鍑嗗脊妗�
+const openCalibrationDia = (type, row) => {
+	nextTick(() => {
+		calibrationDia.value?.openDialog(type, row)
+	})
+}
+
+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;
+			measuringInstrumentDelete(ids)
+				.then((res) => {
+					proxy.$modal.msgSuccess("鍒犻櫎鎴愬姛");
+					getList();
+				})
+				.finally(() => {
+					tableLoading.value = false;
+				});
+		})
+		.catch(() => {
+			proxy.$modal.msg("宸插彇娑�");
+		});
+};
+// 瀵煎嚭
+const handleOut = () => {
+	ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+		confirmButtonText: "纭",
+		cancelButtonText: "鍙栨秷",
+		type: "warning",
+	})
+		.then(() => {
+			proxy.download("/measuringInstrumentLedger/export", {}, "璁¢噺鍣ㄥ叿鍙拌处.xlsx");
+		})
+		.catch(() => {
+			proxy.$modal.msg("宸插彇娑�");
+		});
+};
+onMounted(() => {
+	getList();
+});
 </script>
 
 <style scoped>
-  :deep(.el-table .warning-row) {
-    background-color: #fef0f0 !important;
-  }
-  :deep(.el-table .warning-row:hover > td) {
-    background-color: #f9d5d5 !important;
-  }
-  :deep(.el-table .el-table__body tr.warning-row td) {
-    background-color: #fef0f0 !important;
-  }
+
 </style>
\ No newline at end of file
diff --git a/src/views/equipmentManagement/operationManagement/index.vue b/src/views/equipmentManagement/operationManagement/index.vue
index 99c3bd1..008cc2c 100644
--- a/src/views/equipmentManagement/operationManagement/index.vue
+++ b/src/views/equipmentManagement/operationManagement/index.vue
@@ -104,7 +104,7 @@
           align="center"
         >
           <template #default="scope">
-            {{ getRuntimeDurationDisplay(scope.row) }}
+            {{ scope.row.runtimeDuration || '-' }}
           </template>
         </el-table-column>
         <el-table-column
@@ -154,8 +154,7 @@
 </template>
 
 <script setup>
-import { ref, onMounted, onUnmounted, computed } from 'vue'
-import dayjs from 'dayjs'
+import { ref, onMounted, computed } from 'vue'
 import { ElMessage } from 'element-plus'
 import {
   VideoPlay,
@@ -194,98 +193,6 @@
 
   return filtered
 })
-
-// 杩愯涓棤缁撴潫鏃堕棿鏃讹紝杩愯鏃堕暱闇�闅忓綋鍓嶆椂闂村彉鍖栵紝鐢� tick 瑙﹀彂妯℃澘閲嶇畻
-const runtimeDisplayTick = ref(0)
-
-/** 鍙栧悗绔彲鑳戒娇鐢ㄧ殑寮�濮�/缁撴潫鏃堕棿瀛楁 */
-const pickStartTime = (row) => row?.startRuntimeTime ?? row?.startTime ?? row?.start_time
-const pickEndTime = (row) => row?.endRuntimeTime ?? row?.endTime ?? row?.end_time
-
-/**
- * 瑙f瀽鎺ュ彛/鍓嶇鍐欏叆鐨勫悇绫绘椂闂达細鏃堕棿鎴炽�両SO 瀛楃涓层�亂yyy-MM-dd HH:mm:ss銆丣ackson 鏁扮粍 [y,M,d,h,m,s]銆佸惈涓枃鐨� toLocaleString 绛�
- */
-const parseDeviceTime = (input) => {
-  if (input === null || input === undefined || input === '') return null
-  if (typeof input === 'number' && !Number.isNaN(input)) {
-    const d = dayjs(input)
-    return d.isValid() ? d.toDate() : null
-  }
-  if (Array.isArray(input)) {
-    const [y, mo, day, h = 0, mi = 0, se = 0] = input
-    if (y == null || y === '') return null
-    const d = dayjs()
-        .year(Number(y))
-        .month(Number(mo || 1) - 1)
-        .date(Number(day || 1))
-        .hour(Number(h) || 0)
-        .minute(Number(mi) || 0)
-        .second(Number(se) || 0)
-    return d.isValid() ? d.toDate() : null
-  }
-  const s = String(input).trim()
-  if (!s || s === '-') return null
-  let d = dayjs(s)
-  if (d.isValid()) return d.toDate()
-  d = dayjs(s.replace(/-/g, '/'))
-  if (d.isValid()) return d.toDate()
-  d = dayjs(s.replace(/\//g, '-'))
-  if (d.isValid()) return d.toDate()
-  return null
-}
-
-const formatDurationMs = (durationMs) => {
-  if (durationMs == null || Number.isNaN(durationMs) || durationMs < 0) return '-'
-  const hours = Math.floor(durationMs / (1000 * 60 * 60))
-  const minutes = Math.floor((durationMs % (1000 * 60 * 60)) / (1000 * 60))
-  if (hours === 0 && minutes === 0) return '涓嶈冻1鍒嗛挓'
-  return `${hours}灏忔椂${minutes}鍒嗛挓`
-}
-
-const hasMeaningfulEnd = (endRaw) =>
-    endRaw !== null &&
-    endRaw !== undefined &&
-    String(endRaw).trim() !== '' &&
-    String(endRaw).trim() !== '-'
-
-const formatStoredDuration = (row) => {
-  const rd = row?.runtimeDuration
-  if (rd === null || rd === undefined) return ''
-  const t = String(rd).trim()
-  return t === '' || t === '-' ? '' : String(rd)
-}
-
-/** 杩愯涓細濮嬬粓鐢ㄣ�屽綋鍓嶆椂闂� - 寮�濮嬫椂闂淬�嶏紱宸插仠姝細浼樺厛鎺ュ彛 runtimeDuration锛屽惁鍒欑敤缁撴潫-寮�濮嬶紱鏃犵粨鏉熷彲鐪嬪凡瀛樻椂闀挎垨鍔ㄦ�佹帹绠� */
-const getRuntimeDurationDisplay = (row) => {
-  void runtimeDisplayTick.value
-  const start = parseDeviceTime(pickStartTime(row))
-  if (!start) {
-    return formatStoredDuration(row) || '-'
-  }
-
-  const statusStr = String(row?.status ?? '').trim()
-  const isRunning = statusStr === '杩愯涓�' || statusStr === '1'
-  const endRaw = pickEndTime(row)
-  const hasEnd = hasMeaningfulEnd(endRaw)
-
-  // 鏃犵粨鏉熸椂闂达細杩愯涓竴瀹氬姩鎬佺畻锛涘凡鍋滄鍒欎紭鍏堝睍绀哄悗绔凡瀛樻椂闀匡紝娌℃湁鍐嶆寜褰撳墠鏃堕棿鎺ㄧ畻
-  if (!hasEnd) {
-    if (isRunning) return formatDurationMs(Date.now() - start.getTime())
-    const stored = formatStoredDuration(row)
-    if (stored) return stored
-    return formatDurationMs(Date.now() - start.getTime())
-  }
-
-  if (isRunning) {
-    return formatDurationMs(Date.now() - start.getTime())
-  }
-
-  const end = parseDeviceTime(endRaw)
-  const stored = formatStoredDuration(row)
-  if (stored) return stored
-  if (end) return formatDurationMs(end.getTime() - start.getTime())
-  return '-'
-}
 
 // 妫�鏌ヨ澶囨槸鍚﹁秴鏃舵湭鍚姩
 const isOverdue = (device) => {
@@ -339,11 +246,12 @@
       device.endRuntimeTime = currentTime
       // 璁$畻杩愯鏃堕暱
       if (device.startRuntimeTime) {
-        const startTime = parseDeviceTime(device.startRuntimeTime)
-        const endTime = parseDeviceTime(currentTime)
-        if (startTime && endTime) {
-          device.runtimeDuration = formatDurationMs(endTime.getTime() - startTime.getTime())
-        }
+        const startTime = new Date(device.startRuntimeTime)
+        const endTime = new Date(currentTime)
+        const duration = endTime - startTime
+        const hours = Math.floor(duration / (1000 * 60 * 60))
+        const minutes = Math.floor((duration % (1000 * 60 * 60)) / (1000 * 60))
+        device.runtimeDuration = `${hours}灏忔椂${minutes}鍒嗛挓`
       }
     }
     const params = {
@@ -389,31 +297,9 @@
 
 
 
-const POLL_MS = 60 * 1000
-const RUNTIME_TICK_MS = 30 * 1000
-let listPollTimer = null
-let runtimeTickTimer = null
-
-// 缁勪欢鎸傝浇鏃舵媺鍙栨暟鎹紝骞舵瘡鍒嗛挓鍒锋柊涓�娆″垪琛紱杩愯涓椂闀挎瘡 30 绉掑埛鏂版樉绀�
+// 缁勪欢鎸傝浇鏃跺垵濮嬪寲鏁版嵁
 onMounted(() => {
   getList()
-  listPollTimer = setInterval(() => {
-    getList()
-  }, POLL_MS)
-  runtimeTickTimer = setInterval(() => {
-    runtimeDisplayTick.value++
-  }, RUNTIME_TICK_MS)
-})
-
-onUnmounted(() => {
-  if (listPollTimer != null) {
-    clearInterval(listPollTimer)
-    listPollTimer = null
-  }
-  if (runtimeTickTimer != null) {
-    clearInterval(runtimeTickTimer)
-    runtimeTickTimer = null
-  }
 })
 </script>
 
diff --git a/src/views/equipmentManagement/repair/Modal/AcceptanceModal.vue b/src/views/equipmentManagement/repair/Modal/AcceptanceModal.vue
deleted file mode 100644
index 6d61a9f..0000000
--- a/src/views/equipmentManagement/repair/Modal/AcceptanceModal.vue
+++ /dev/null
@@ -1,144 +0,0 @@
-<template>
-  <FormDialog
-    v-model="visible"
-    title="楠屾敹瀹℃壒"
-    width="500px"
-    @confirm="submitForm"
-    @cancel="handleCancel"
-    @close="handleCancel"
-  >
-    <el-form :model="form" :rules="rules" label-width="100px">
-      <el-form-item label="楠屾敹浜�" prop="acceptanceName">
-        <el-select
-          v-model="form.acceptanceName"
-          placeholder="璇烽�夋嫨楠屾敹浜�"
-          filterable
-          style="width: 100%"
-        >
-          <el-option
-            v-for="item in userList"
-            :key="item.userId"
-            :label="item.nickName"
-            :value="item.nickName"
-          />
-        </el-select>
-      </el-form-item>
-      <el-form-item label="楠屾敹鏃堕棿" prop="acceptanceTime">
-        <el-date-picker
-          v-model="form.acceptanceTime"
-          type="datetime"
-          placeholder="璇烽�夋嫨楠屾敹鏃堕棿"
-          format="YYYY-MM-DD HH:mm:ss"
-          value-format="YYYY-MM-DD HH:mm:ss"
-          style="width: 100%"
-        />
-      </el-form-item>
-      <el-form-item label="楠屾敹澶囨敞" prop="acceptanceRemark">
-        <el-input
-          v-model="form.acceptanceRemark"
-          type="textarea"
-          :rows="3"
-          placeholder="璇疯緭鍏ラ獙鏀跺娉�"
-        />
-      </el-form-item>
-    </el-form>
-  </FormDialog>
-</template>
-
-<script setup>
-import FormDialog from "@/components/Dialog/FormDialog.vue";
-import { ref, reactive } from "vue";
-import { ElMessage } from "element-plus";
-import { userListNoPageByTenantId } from "@/api/system/user.js";
-import { repairAcceptance } from "@/api/equipmentManagement/repair";
-import dayjs from "dayjs";
-
-defineOptions({
-  name: "楠屾敹瀹℃壒寮圭獥",
-});
-
-const emits = defineEmits(["ok"]);
-
-const visible = ref(false);
-const loading = ref(false);
-const repairId = ref(null);
-const userList = ref([]);
-
-const form = reactive({
-  acceptanceName: undefined,
-  acceptanceTime: dayjs().format("YYYY-MM-DD HH:mm:ss"),
-  acceptanceRemark: undefined,
-});
-
-const rules = {
-  acceptanceName: [
-    { required: true, message: "璇烽�夋嫨楠屾敹浜�", trigger: "change" },
-  ],
-  acceptanceTime: [
-    { required: true, message: "璇烽�夋嫨楠屾敹鏃堕棿", trigger: "change" },
-  ],
-  acceptanceRemark: [
-    { required: true, message: "璇疯緭鍏ラ獙鏀跺娉�", trigger: "blur" },
-  ],
-};
-
-// 鍔犺浇鐢ㄦ埛鍒楄〃
-const loadUserList = async () => {
-  const { data } = await userListNoPageByTenantId();
-  userList.value = data;
-};
-
-// 鎵撳紑寮圭獥
-const open = async (row) => {
-  repairId.value = row.id;
-  visible.value = true;
-  // 閲嶇疆琛ㄥ崟
-  form.acceptanceName = undefined;
-  form.acceptanceTime = dayjs().format("YYYY-MM-DD HH:mm:ss");
-  form.acceptanceRemark = undefined;
-  await loadUserList();
-};
-
-// 鎻愪氦琛ㄥ崟
-const submitForm = async () => {
-  if (!form.acceptanceName) {
-    ElMessage.warning("璇烽�夋嫨楠屾敹浜�");
-    return;
-  }
-  if (!form.acceptanceTime) {
-    ElMessage.warning("璇烽�夋嫨楠屾敹鏃堕棿");
-    return;
-  }
-  if (!form.acceptanceRemark) {
-    ElMessage.warning("璇疯緭鍏ラ獙鏀跺娉�");
-    return;
-  }
-
-  loading.value = true;
-  try {
-    const { code } = await repairAcceptance({
-      id: repairId.value,
-      acceptanceName: form.acceptanceName,
-      acceptanceTime: form.acceptanceTime,
-      acceptanceRemark: form.acceptanceRemark,
-    });
-    if (code === 200) {
-      ElMessage.success("楠屾敹閫氳繃");
-      visible.value = false;
-      emits("ok");
-    }
-  } finally {
-    loading.value = false;
-  }
-};
-
-const handleCancel = () => {
-  visible.value = false;
-};
-
-defineExpose({
-  open,
-});
-</script>
-
-<style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/Modal/RepairModal.vue b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
index 4a10071..022ae6f 100644
--- a/src/views/equipmentManagement/repair/Modal/RepairModal.vue
+++ b/src/views/equipmentManagement/repair/Modal/RepairModal.vue
@@ -1,126 +1,101 @@
 <template>
-  <FormDialog v-model="visible"
-              :title="computedTitle"
-              :operation-type="operationType"
-              width="800px"
-              @confirm="sendForm"
-              @cancel="handleCancel"
-              @close="handleClose">
-    <el-form :model="form"
-             label-width="100px">
+  <FormDialog
+    v-model="visible"
+    :title="id ? '缂栬緫璁惧鎶ヤ慨' : '鏂板璁惧鎶ヤ慨'"
+    width="800px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" label-width="100px">
       <el-row>
         <el-col :span="12">
+          <el-form-item label="鎵�灞炲尯鍩�">
+            <el-tree-select
+              v-model="form.areaId"
+              :data="areaOptions"
+              :props="areaTreeProps"
+              node-key="id"
+              value-key="id"
+              check-strictly
+              clearable
+              filterable
+              placeholder="璇烽�夋嫨鎵�灞炲尯鍩�"
+              style="width: 100%"
+              @change="handleAreaChange"
+            />
+          </el-form-item>
+        </el-col>
+        <el-col :span="12">
           <el-form-item label="璁惧鍚嶇О">
-            <el-select v-model="form.deviceLedgerId"
-                       @change="setDeviceModel"
-                       filterable
-                       :disabled="operationType === 'view'">
-              <el-option v-for="(item, index) in deviceOptions"
-                         :key="index"
-                         :label="item.deviceName"
-                         :value="item.id"></el-option>
+            <el-select
+              v-model="form.deviceLedgerIds"
+              filterable
+              clearable
+              multiple
+              collapse-tags
+              collapse-tags-tooltip
+              placeholder="璇峰厛閫夋嫨鍖哄煙锛屽啀閫夋嫨璁惧"
+              style="width: 100%"
+              @change="setDeviceModels"
+            >
+              <el-option
+                v-for="item in deviceOptions"
+                :key="item.id"
+                :label="item.deviceName"
+                :value="item.id"
+              />
             </el-select>
           </el-form-item>
         </el-col>
         <el-col :span="12">
           <el-form-item label="瑙勬牸鍨嬪彿">
-            <el-input v-model="form.deviceModel"
-                      placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
-                      disabled />
+            <el-input
+              v-model="form.deviceModel"
+              placeholder="鑷姩甯﹀嚭瑙勬牸鍨嬪彿"
+              disabled
+            />
           </el-form-item>
         </el-col>
         <el-col :span="12">
           <el-form-item label="鎶ヤ慨鏃ユ湡">
-            <el-date-picker v-model="form.repairTime"
-                            placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
-                            format="YYYY-MM-DD"
-                            value-format="YYYY-MM-DD"
-                            type="date"
-                            clearable
-                            style="width: 100%"
-                            :disabled="operationType === 'view'" />
+            <el-date-picker
+              v-model="form.repairTime"
+              placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
+              format="YYYY-MM-DD"
+              value-format="YYYY-MM-DD"
+              type="date"
+              clearable
+              style="width: 100%"
+            />
           </el-form-item>
         </el-col>
         <el-col :span="12">
           <el-form-item label="鎶ヤ慨浜�">
-            <el-input v-model="form.repairName"
-                      placeholder="璇疯緭鍏ユ姤淇汉"
-                      :disabled="operationType === 'view'" />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="鎶ヤ慨鎶ヤ慨椤圭洰">
-            <el-input v-model="form.machineryCategory"
-                      placeholder="璇疯緭鍏ユ姤淇姤淇」鐩�"
-                      :disabled="operationType === 'view'" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row>
-        <el-col :span="12">
-          <el-form-item label="缁翠慨浜�">
-            <el-input v-model="form.maintenanceName"
-                      placeholder="璇疯緭鍏ョ淮淇汉濮撳悕"
-                      :disabled="operationType === 'view'" />
+            <el-input v-model="form.repairName" placeholder="璇疯緭鍏ユ姤淇汉" />
           </el-form-item>
         </el-col>
       </el-row>
       <el-row v-if="id">
         <el-col :span="12">
           <el-form-item label="鎶ヤ慨鐘舵��">
-            <el-select v-model="form.status"
-                       disabled>
-              <el-option label="寰呯淮淇�"
-                         :value="0"></el-option>
-              <el-option label="宸查獙鏀�"
-                         :value="1"></el-option>
-              <el-option label="澶辫触"
-                         :value="2"></el-option>
+            <el-select v-model="form.status">
+              <el-option label="寰呯淮淇�" :value="0" />
+              <el-option label="瀹岀粨" :value="1" />
+              <el-option label="澶辫触" :value="2" />
             </el-select>
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <!-- 楠屾敹淇℃伅灞曠ず -->
-      <el-row v-if="id && (form.status === 1 || form.status === 3)">
-        <el-col :span="12">
-          <el-form-item label="楠屾敹浜�">
-            <el-input v-model="form.acceptanceName"
-                      disabled />
-          </el-form-item>
-        </el-col>
-        <el-col :span="12">
-          <el-form-item label="楠屾敹鏃堕棿">
-            <el-input v-model="form.acceptanceTime"
-                      disabled />
-          </el-form-item>
-        </el-col>
-        <el-col :span="24">
-          <el-form-item label="楠屾敹澶囨敞">
-            <el-input v-model="form.acceptanceRemark"
-                      type="textarea"
-                      :rows="2"
-                      disabled />
           </el-form-item>
         </el-col>
       </el-row>
       <el-row>
         <el-col :span="24">
           <el-form-item label="鏁呴殰鐜拌薄">
-            <el-input v-model="form.remark"
-                      :rows="2"
-                      type="textarea"
-                      placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
-                      :disabled="operationType === 'view'" />
-          </el-form-item>
-        </el-col>
-      </el-row>
-      <el-row v-if="operationType !== 'view'"
-              :gutter="30">
-        <el-col :span="24">
-          <el-form-item label="闄勪欢"
-                        prop="attachmentIds">
-            <FileUpload v-model:file-list="form.storageBlobDTOs"
-                        :disabled="operationType === 'view'" />
+            <el-input
+              v-model="form.remark"
+              :rows="2"
+              type="textarea"
+              placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
+            />
           </el-form-item>
         </el-col>
       </el-row>
@@ -129,140 +104,239 @@
 </template>
 
 <script setup>
-  import FormDialog from "@/components/Dialog/FormDialog.vue";
-  import FileUpload from "@/components/AttachmentUpload/file/index.vue";
-  import {
-    addRepair,
-    editRepair,
-    getRepairById,
-  } from "@/api/equipmentManagement/repair";
-  import { ElMessage } from "element-plus";
-  import dayjs from "dayjs";
-  import useFormData from "@/hooks/useFormData";
-  import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-  import useUserStore from "@/store/modules/user";
+import { nextTick, ref, unref } from "vue";
+import dayjs from "dayjs";
+import { ElMessage } from "element-plus";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import useFormData from "@/hooks/useFormData";
+import useUserStore from "@/store/modules/user";
+import {
+  addRepair,
+  editRepair,
+  getRepairById,
+} from "@/api/equipmentManagement/repair";
+import {
+  getDeviceAreaTree,
+  getDeviceAreaTreeWithDevices,
+} from "@/api/equipmentManagement/deviceArea";
 
-  defineOptions({
-    name: "璁惧鎶ヤ慨寮圭獥",
-  });
+defineOptions({
+  name: "璁惧鎶ヤ慨寮圭獥",
+});
 
-  const emits = defineEmits(["ok"]);
+const emits = defineEmits(["ok"]);
 
-  const id = ref();
-  const visible = ref(false);
-  const loading = ref(false);
-  const operationType = ref(""); // add, edit, view
+const id = ref();
+const visible = ref(false);
+const loading = ref(false);
+const userStore = useUserStore();
+const areaOptions = ref([]);
+const deviceOptions = ref([]);
+const areaTreeProps = {
+  label: "areaName",
+  children: "children",
+};
 
-  const computedTitle = computed(() => {
-    if (operationType.value === "add") return "鏂板璁惧鎶ヤ慨";
-    if (operationType.value === "edit") return "缂栬緫璁惧鎶ヤ慨";
-    if (operationType.value === "view") return "璁惧鎶ヤ慨璇︽儏";
-    return "";
-  });
+const { form, resetForm } = useFormData({
+  areaId: undefined,
+  deviceLedgerId: undefined,
+  deviceLedgerIds: [],
+  deviceLedgerIdsStr: undefined,
+  deviceName: undefined,
+  deviceModel: undefined,
+  repairTime: dayjs().format("YYYY-MM-DD"),
+  repairName: userStore.nickName,
+  remark: undefined,
+  status: 0,
+});
 
-  const userStore = useUserStore();
-  const deviceOptions = ref([]);
-  const fileList = ref([]);
+const loadAreaTree = async () => {
+  const { data } = await getDeviceAreaTree();
+  areaOptions.value = Array.isArray(data) ? data : [];
+};
 
-  const loadDeviceName = async () => {
-    const { data } = await getDeviceLedger();
-    deviceOptions.value = data;
-  };
+const normalizeIdList = (value) => {
+  if (Array.isArray(value)) {
+    return value
+      .map((item) => Number(item))
+      .filter((item) => Number.isFinite(item));
+  }
+  if (typeof value === "string") {
+    return value
+      .split(",")
+      .map((item) => Number(item.trim()))
+      .filter((item) => Number.isFinite(item));
+  }
+  if (value !== undefined && value !== null && value !== "") {
+    const numericValue = Number(value);
+    return Number.isFinite(numericValue) ? [numericValue] : [];
+  }
+  return [];
+};
 
-  const { form, resetForm } = useFormData({
-    deviceLedgerId: undefined, // 璁惧Id
-    deviceName: undefined, // 璁惧鍚嶇О
-    deviceModel: undefined, // 瑙勬牸鍨嬪彿
-    repairTime: dayjs().format("YYYY-MM-DD"), // 鎶ヤ慨鏃ユ湡锛岄粯璁ゅ綋澶�
-    repairName: userStore.nickName, // 鎶ヤ慨浜�
-    remark: undefined, // 鏁呴殰鐜拌薄
-    status: 0, // 鎶ヤ慨鐘舵��
-    machineryCategory: undefined,
-    storageBlobDTOs: [],
-    maintenanceName: undefined, // 缁翠慨浜�
-  });
+const getNodeDevices = (node) => {
+  const candidates = [
+    node?.deviceList,
+    node?.devices,
+    node?.deviceLedgerList,
+    node?.deviceLedgers,
+    node?.ledgerList,
+    node?.ledgers,
+  ];
+  return candidates.find((item) => Array.isArray(item)) || [];
+};
 
-  const setDeviceModel = deviceId => {
-    const option = deviceOptions.value.find(item => item.id === deviceId);
-    form.deviceModel = option.deviceModel;
-  };
+const normalizeDevice = (item) => ({
+  ...item,
+  id: item.id ?? item.deviceLedgerId,
+  deviceName: item.deviceName ?? item.name,
+  deviceModel: item.deviceModel ?? item.model,
+});
 
-  const setForm = data => {
-    form.deviceLedgerId = data.deviceLedgerId;
-    form.deviceName = data.deviceName;
-    form.deviceModel = data.deviceModel;
-    form.repairTime = data.repairTime;
-    form.repairName = data.repairName;
-    form.remark = data.remark;
-    form.status = data.status;
-    form.machineryCategory = data.machineryCategory;
-    form.storageBlobDTOs = data.storageBlobVOs || [];
-    form.maintenanceName = data.maintenanceName;
-    form.acceptanceName = data.acceptanceName;
-    form.acceptanceTime = data.acceptanceTime;
-    form.acceptanceRemark = data.acceptanceRemark;
-  };
-
-  const sendForm = async () => {
-    loading.value = true;
-    try {
-      const { code } = id.value
-        ? await editRepair({ id: unref(id), ...form })
-        : await addRepair(form);
-      if (code == 200) {
-        ElMessage.success(`${id.value ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
-        visible.value = false;
-        emits("ok");
-      }
-    } finally {
-      loading.value = false;
+const collectDevices = (node) => {
+  const currentDevices = getNodeDevices(node).map(normalizeDevice);
+  const childDevices = (node?.children || []).flatMap((child) =>
+    collectDevices(child)
+  );
+  const deviceMap = new Map();
+  [...currentDevices, ...childDevices].forEach((item) => {
+    if (item?.id !== undefined && item?.id !== null) {
+      deviceMap.set(Number(item.id), item);
     }
-  };
-
-  const handleCancel = () => {
-    resetForm();
-    visible.value = false;
-  };
-
-  const handleClose = () => {
-    resetForm();
-    visible.value = false;
-  };
-
-  const openAdd = async () => {
-    id.value = undefined;
-    operationType.value = "add";
-    visible.value = true;
-    fileList.value = [];
-    await nextTick();
-    await loadDeviceName();
-  };
-
-  const openEdit = async editId => {
-    const { data } = await getRepairById(editId);
-    id.value = editId;
-    operationType.value = "edit";
-    visible.value = true;
-    await nextTick();
-    await loadDeviceName();
-    setForm(data);
-  };
-
-  const openView = async viewId => {
-    const { data } = await getRepairById(viewId);
-    id.value = viewId;
-    operationType.value = "view";
-    visible.value = true;
-    await nextTick();
-    await loadDeviceName();
-    setForm(data);
-  };
-
-  defineExpose({
-    openAdd,
-    openEdit,
-    openView,
   });
+  return Array.from(deviceMap.values());
+};
+
+const findAreaNode = (nodes, areaId) => {
+  for (const node of nodes || []) {
+    if (Number(node.id) === Number(areaId)) {
+      return node;
+    }
+    const target = findAreaNode(node.children, areaId);
+    if (target) {
+      return target;
+    }
+  }
+  return null;
+};
+
+const loadDevicesByArea = async (areaId) => {
+  if (!areaId) {
+    deviceOptions.value = [];
+    return;
+  }
+  const { data } = await getDeviceAreaTreeWithDevices();
+  const treeData = Array.isArray(data) ? data : [];
+  const currentNode = findAreaNode(treeData, areaId);
+  deviceOptions.value = currentNode ? collectDevices(currentNode) : [];
+};
+
+const syncDeviceFields = (deviceIds) => {
+  const selectedIds = normalizeIdList(deviceIds);
+  const selectedDevices = selectedIds
+    .map((deviceId) =>
+      deviceOptions.value.find((item) => Number(item.id) === Number(deviceId))
+    )
+    .filter(Boolean);
+
+  form.deviceLedgerIds = selectedIds;
+  form.deviceLedgerId = selectedIds[0];
+  form.deviceLedgerIdsStr = selectedIds.join(",");
+  form.deviceName = selectedDevices
+    .map((item) => item.deviceName)
+    .filter(Boolean)
+    .join(",");
+  form.deviceModel = selectedDevices
+    .map((item) => item.deviceModel || "-")
+    .join(",");
+};
+
+const setDeviceModels = (deviceIds) => {
+  syncDeviceFields(deviceIds);
+};
+
+const setForm = (data) => {
+  form.areaId = data.areaId;
+  form.deviceLedgerIds = normalizeIdList(
+    data.deviceLedgerIds ?? data.deviceLedgerIdsStr ?? data.deviceLedgerId
+  );
+  form.deviceLedgerId = form.deviceLedgerIds[0];
+  form.deviceLedgerIdsStr =
+    data.deviceLedgerIdsStr ?? form.deviceLedgerIds.join(",");
+  form.deviceName = data.deviceName;
+  form.deviceModel = data.deviceModel;
+  form.repairTime = data.repairTime;
+  form.repairName = data.repairName;
+  form.remark = data.remark;
+  form.status = data.status;
+};
+
+const handleAreaChange = async (areaId) => {
+  form.deviceLedgerId = undefined;
+  form.deviceLedgerIds = [];
+  form.deviceLedgerIdsStr = undefined;
+  form.deviceName = undefined;
+  form.deviceModel = undefined;
+  await loadDevicesByArea(areaId);
+};
+
+const sendForm = async () => {
+  loading.value = true;
+  try {
+    syncDeviceFields(form.deviceLedgerIds);
+    const payload = {
+      ...form,
+      deviceLedgerId: form.deviceLedgerIds[0],
+      deviceLedgerIds: [...form.deviceLedgerIds],
+      deviceLedgerIdsStr: form.deviceLedgerIds.join(","),
+      deviceModel: form.deviceModel || "-",
+    };
+    const { code } = id.value
+      ? await editRepair({ id: unref(id), ...payload })
+      : await addRepair(payload);
+    if (code === 200) {
+      ElMessage.success(`${id.value ? "缂栬緫" : "鏂板"}鎶ヤ慨鎴愬姛`);
+      visible.value = false;
+      emits("ok");
+    }
+  } finally {
+    loading.value = false;
+  }
+};
+
+const handleCancel = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const handleClose = () => {
+  resetForm();
+  visible.value = false;
+};
+
+const openAdd = async () => {
+  id.value = undefined;
+  visible.value = true;
+  await nextTick();
+  await loadAreaTree();
+  deviceOptions.value = [];
+};
+
+const openEdit = async (editId) => {
+  const { data } = await getRepairById(editId);
+  id.value = editId;
+  visible.value = true;
+  await nextTick();
+  await loadAreaTree();
+  setForm(data);
+  await loadDevicesByArea(form.areaId);
+  syncDeviceFields(form.deviceLedgerIds);
+};
+
+defineExpose({
+  openAdd,
+  openEdit,
+});
 </script>
 
 <style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/repair/index.vue b/src/views/equipmentManagement/repair/index.vue
index f1573cb..1699cff 100644
--- a/src/views/equipmentManagement/repair/index.vue
+++ b/src/views/equipmentManagement/repair/index.vue
@@ -1,195 +1,168 @@
 <template>
   <div class="app-container">
-    <el-form :model="filters"
-             :inline="true">
+    <el-form :model="filters" :inline="true">
       <el-form-item label="璁惧鍚嶇О">
-        <el-input v-model="filters.deviceName"
-                  style="width: 240px"
-                  placeholder="璇疯緭鍏ヨ澶囧悕绉�"
-                  clearable
-                  :prefix-icon="Search"
-                  @change="getTableData" />
+        <el-input
+            v-model="filters.deviceName"
+            style="width: 240px"
+            placeholder="璇疯緭鍏ヨ澶囧悕绉�"
+            clearable
+            @change="getTableData"
+        />
       </el-form-item>
       <el-form-item label="瑙勬牸鍨嬪彿">
-        <el-input v-model="filters.deviceModel"
-                  style="width: 240px"
-                  placeholder="璇烽�夋嫨瑙勬牸鍨嬪彿"
-                  clearable
-                  :prefix-icon="Search"
-                  @change="getTableData" />
+        <el-input
+            v-model="filters.deviceModel"
+            style="width: 240px"
+            placeholder="璇烽�夋嫨瑙勬牸鍨嬪彿"
+            clearable
+            @change="getTableData"
+        />
       </el-form-item>
       <el-form-item label="鏁呴殰鐜拌薄">
-        <el-input v-model="filters.remark"
-                  style="width: 240px"
-                  placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
-                  clearable
-                  :prefix-icon="Search"
-                  @change="getTableData" />
+        <el-input
+            v-model="filters.remark"
+            style="width: 240px"
+            placeholder="璇疯緭鍏ユ晠闅滅幇璞�"
+            clearable
+            @change="getTableData"
+        />
       </el-form-item>
       <el-form-item label="缁翠慨浜�">
-        <el-input v-model="filters.maintenanceName"
-                  style="width: 240px"
-                  placeholder="璇疯緭鍏ョ淮淇汉"
-                  clearable
-                  :prefix-icon="Search"
-                  @change="getTableData" />
+        <el-input
+            v-model="filters.maintenanceName"
+            style="width: 240px"
+            placeholder="璇疯緭鍏ョ淮淇汉"
+            clearable
+            @change="getTableData"
+        />
       </el-form-item>
       <el-form-item label="鎶ヤ慨鏃ユ湡">
-        <el-date-picker v-model="filters.repairTimeStr"
-                        type="date"
-                        placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
-                        size="default"
-                        @change="(date) => handleDateChange(date,2)" />
+        <el-date-picker
+            v-model="filters.repairTimeStr"
+            type="date"
+            placeholder="璇烽�夋嫨鎶ヤ慨鏃ユ湡"
+            size="default"
+            @change="(date) => handleDateChange(date,2)"
+        />
       </el-form-item>
       <el-form-item label="缁翠慨鏃ユ湡">
-        <el-date-picker v-model="filters.maintenanceTimeStr"
-                        type="date"
-                        placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
-                        size="default"
-                        @change="(date) => handleDateChange(date,1)" />
+        <el-date-picker
+            v-model="filters.maintenanceTimeStr"
+            type="date"
+            placeholder="璇烽�夋嫨缁翠慨鏃ユ湡"
+            size="default"
+            @change="(date) => handleDateChange(date,1)"
+        />
       </el-form-item>
       <el-form-item>
-        <el-button type="primary"
-                   @click="getTableData">鎼滅储</el-button>
+        <el-button type="primary" @click="getTableData">鎼滅储</el-button>
         <el-button @click="resetFilters">閲嶇疆</el-button>
       </el-form-item>
     </el-form>
     <div class="table_list">
       <div class="actions">
-        <el-text class="mx-1"
-                 size="large">璁惧鎶ヤ慨</el-text>
+        <el-text class="mx-1" size="large">璁惧鎶ヤ慨</el-text>
         <div>
-          <el-button type="success"
-                     icon="Van"
-                     @click="addRepair">
+          <el-button type="success" icon="Van" @click="addRepair">
             鏂板鎶ヤ慨
           </el-button>
           <el-button @click="handleOut">
             瀵煎嚭
           </el-button>
-          <el-button type="danger"
-                     icon="Delete"
-                     :disabled="multipleList.length <= 0 || hasFinishedStatus"
-                     @click="delRepairByIds(multipleList.map((item) => item.id))">
+          <el-button
+            type="danger"
+            icon="Delete"
+            :disabled="multipleList.length <= 0 || hasFinishedStatus"
+            @click="delRepairByIds(multipleList.map((item) => item.id))"
+          >
             鎵归噺鍒犻櫎
           </el-button>
         </div>
       </div>
-      <PIMTable rowKey="id"
-                isSelection
-                :column="columns"
-                :tableData="dataList"
-                :page="{
+      <PIMTable
+          rowKey="id"
+          isSelection
+          :column="columns"
+          :tableData="dataList"
+          :page="{
           current: pagination.currentPage,
           size: pagination.pageSize,
           total: pagination.total,
         }"
-                @selection-change="handleSelectionChange"
-                @pagination="changePage">
+          @selection-change="handleSelectionChange"
+          @pagination="changePage"
+      >
         <template #statusRef="{ row }">
-          <el-tag v-if="row.status === 2"
-                  type="danger">澶辫触</el-tag>
-          <el-tag v-if="row.status === 1"
-                  type="success">瀹岀粨</el-tag>
-          <el-tag v-if="row.status === 3"
-                  type="info">寰呴獙鏀�</el-tag>
-          <el-tag v-if="row.status === 0"
-                  type="warning">寰呯淮淇�</el-tag>
+          <el-tag v-if="row.status === 2" type="danger">澶辫触</el-tag>
+          <el-tag v-if="row.status === 1" type="success">瀹岀粨</el-tag>
+          <el-tag v-if="row.status === 0" type="warning">寰呯淮淇�</el-tag>
         </template>
         <template #operation="{ row }">
-          <el-button type="primary"
-                     link
-                     @click="viewRepair(row.id)">
-            璇︽儏
-          </el-button>
-          <el-button type="primary"
-                     link
-                     :disabled="row.status === 1 || row.status === 3"
-                     @click="editRepair(row.id)">
+          <el-button
+            type="primary"
+            link
+            :disabled="row.status === 1"
+            @click="editRepair(row.id)"
+          >
             缂栬緫
           </el-button>
-          <el-button type="success"
-                     link
-                     :disabled="row.status !== 0"
-                     @click="addMaintain(row)">
+          <el-button
+            type="success"
+            link
+            :disabled="row.status === 1"
+            @click="addMaintain(row)"
+          >
             缁翠慨
           </el-button>
-          <el-button type="warning"
-                     link
-                     :disabled="row.status !== 3"
-                     @click="openAcceptance(row)">
-            楠屾敹
-          </el-button>
-          <el-button type="danger"
-                     link
-                     :disabled="row.status === 1 || row.status === 3"
-                     @click="delRepairByIds(row.id)">
+          <el-button
+            type="danger"
+            link
+            :disabled="row.status === 1"
+            @click="delRepairByIds(row.id)"
+          >
             鍒犻櫎
-          </el-button>
-          <el-button type="primary"
-                     link
-                     @click="openFileDialog(row)">
-            闄勪欢
           </el-button>
         </template>
       </PIMTable>
     </div>
-    <RepairModal ref="repairModalRef"
-                 @ok="getTableData" />
-    <MaintainModal ref="maintainModalRef"
-                   @ok="getTableData" />
-    <AcceptanceModal ref="acceptanceModalRef"
-                     @ok="getTableData" />
-    <FileList v-if="fileDialogVisible"
-              v-model:visible="fileDialogVisible"
-              :record-type="'device_repair'"
-              :record-id="recordId" />
+    <RepairModal ref="repairModalRef" @ok="getTableData"/>
+    <MaintainModal ref="maintainModalRef" @ok="getTableData"/>
   </div>
 </template>
 
 <script setup>
-  import {
-    onMounted,
-    getCurrentInstance,
-    computed,
-    ref,
-    defineAsyncComponent,
-  } from "vue";
-  import { usePaginationApi } from "@/hooks/usePaginationApi";
-  import { getRepairPage, delRepair } from "@/api/equipmentManagement/repair";
-  import RepairModal from "./Modal/RepairModal.vue";
-  import { ElMessageBox, ElMessage } from "element-plus";
-  import dayjs from "dayjs";
-  import MaintainModal from "./Modal/MaintainModal.vue";
-  import AcceptanceModal from "./Modal/AcceptanceModal.vue";
-  const FileList = defineAsyncComponent(() =>
-    import("@/components/Dialog/FileList.vue")
-  );
+import { onMounted, getCurrentInstance, computed } from "vue";
+import {usePaginationApi} from "@/hooks/usePaginationApi";
+import {getRepairPage, delRepair} from "@/api/equipmentManagement/repair";
+import RepairModal from "./Modal/RepairModal.vue";
+import {ElMessageBox, ElMessage} from "element-plus";
+import dayjs from "dayjs";
+import MaintainModal from "./Modal/MaintainModal.vue";
 
-  defineOptions({
-    name: "璁惧鎶ヤ慨",
-  });
+defineOptions({
+  name: "璁惧鎶ヤ慨",
+});
 
-  const { proxy } = getCurrentInstance();
+const {proxy} = getCurrentInstance();
 
-  // 妯℃�佹瀹炰緥
-  const repairModalRef = ref();
-  const maintainModalRef = ref();
-  const acceptanceModalRef = ref();
+// 妯℃�佹瀹炰緥
+const repairModalRef = ref();
+const maintainModalRef = ref();
 
-  // 琛ㄦ牸澶氶�夋閫変腑椤�
-  const multipleList = ref([]);
+// 琛ㄦ牸澶氶�夋閫変腑椤�
+const multipleList = ref([]);
 
-  // 琛ㄦ牸閽╁瓙
-  const {
-    filters,
-    columns,
-    dataList,
-    pagination,
-    getTableData,
-    resetFilters,
-    onCurrentChange,
-  } = usePaginationApi(
+// 琛ㄦ牸閽╁瓙
+const {
+  filters,
+  columns,
+  dataList,
+  pagination,
+  getTableData,
+  resetFilters,
+  onCurrentChange,
+} = usePaginationApi(
     getRepairPage,
     {
       deviceName: undefined,
@@ -200,6 +173,10 @@
       maintenanceTimeStr: undefined,
     },
     [
+			{
+				label: "鎵�鍦ㄥ尯鍩�",
+				prop: "areaName",
+			},
       {
         label: "璁惧鍚嶇О",
         align: "center",
@@ -214,12 +191,33 @@
         label: "鎶ヤ慨鏃ユ湡",
         align: "center",
         prop: "repairTime",
-        formatData: cell => dayjs(cell).format("YYYY-MM-DD"),
+        formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"),
       },
       {
         label: "鎶ヤ慨浜�",
         align: "center",
         prop: "repairName",
+      },
+      {
+        label: "鏁呴殰鐜拌薄",
+        align: "center",
+        prop: "remark",
+      },
+      {
+        label: "缁翠慨浜�",
+        align: "center",
+        prop: "maintenanceName",
+      },
+      {
+        label: "缁翠慨缁撴灉",
+        align: "center",
+        prop: "maintenanceResult",
+      },
+      {
+        label: "缁翠慨鏃ユ湡",
+        align: "center",
+        prop: "maintenanceTime",
+        formatData: (cell) => (cell ? dayjs(cell).format("YYYY-MM-DD") : ""),
       },
       {
         label: "鐘舵��",
@@ -234,132 +232,113 @@
         dataType: "slot",
         slot: "operation",
         align: "center",
-        width: "320px",
+        width: "300px",
       },
     ]
-  );
+);
 
-  // type === 1 缁翠慨 2鎶ヤ慨闂�
-  const handleDateChange = (value, type) => {
-    filters.maintenanceTimeStr = null;
-    filters.c = null;
-    if (type === 1) {
-      if (value) {
-        filters.maintenanceTimeStr = dayjs(value).format("YYYY-MM-DD");
-      }
-    } else {
-      if (value) {
-        filters.repairTimeStr = dayjs(value).format("YYYY-MM-DD");
-      }
+// type === 1 缁翠慨 2鎶ヤ慨闂�
+const handleDateChange = (value, type) => {
+  filters.maintenanceTimeStr = null
+  filters.c = null
+  if (type === 1) {
+    if (value) {
+      filters.maintenanceTimeStr = dayjs(value).format("YYYY-MM-DD");
     }
-    getTableData();
-  };
+  } else {
+    if (value) {
+      filters.repairTimeStr = dayjs(value).format("YYYY-MM-DD");
+    }
+  }
+  getTableData();
+};
 
-  // 鎵撳紑闄勪欢寮圭獥
-  const recordId = ref(0);
-  const fileDialogVisible = ref(false);
+// 澶氶�夊悗鍋氫粈涔�
+const handleSelectionChange = (selectionList) => {
+  multipleList.value = selectionList;
+};
 
-  const openFileDialog = async row => {
-    recordId.value = row.id;
-    fileDialogVisible.value = true;
-  };
+// 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
+const hasFinishedStatus = computed(() => {
+  return multipleList.value.some(item => item.status === 1)
+})
 
-  // 澶氶�夊悗鍋氫粈涔�
-  const handleSelectionChange = selectionList => {
-    multipleList.value = selectionList;
-  };
+// 鏂板鎶ヤ慨
+const addRepair = () => {
+  repairModalRef.value.openAdd();
+};
 
-  // 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
-  const hasFinishedStatus = computed(() => {
-    return multipleList.value.some(item => item.status === 1);
+// 缂栬緫鎶ヤ慨
+const editRepair = (id) => {
+  repairModalRef.value.openEdit(id);
+};
+
+// 鏂板缁翠慨
+const addMaintain = (row) => {
+  maintainModalRef.value.open(row.id, row);
+};
+
+const changePage = ({page, limit}) => {
+  pagination.currentPage = page;
+  pagination.pageSize = limit;
+  onCurrentChange(page);
+};
+
+// 鍗曡鍒犻櫎
+const delRepairByIds = async (ids) => {
+  // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
+  const idsArray = Array.isArray(ids) ? ids : [ids];
+  const hasFinished = idsArray.some(id => {
+    const record = dataList.value.find(item => item.id === id);
+    return record && record.status === 1;
   });
 
-  // 鏂板鎶ヤ慨
-  const addRepair = () => {
-    repairModalRef.value.openAdd();
-  };
+  if (hasFinished) {
+    ElMessage.warning('涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�');
+    return;
+  }
 
-  // 璇︽儏鏌ョ湅
-  const viewRepair = id => {
-    repairModalRef.value.openView(id);
-  };
-
-  // 缂栬緫鎶ヤ慨
-  const editRepair = id => {
-    repairModalRef.value.openEdit(id);
-  };
-
-  // 鏂板缁翠慨
-  const addMaintain = row => {
-    maintainModalRef.value.open(row.id, row);
-  };
-
-  // 鎵撳紑楠屾敹寮圭獥
-  const openAcceptance = row => {
-    acceptanceModalRef.value.open(row);
-  };
-
-  const changePage = ({ page, limit }) => {
-    pagination.currentPage = page;
-    pagination.pageSize = limit;
-    onCurrentChange(page);
-  };
-
-  // 鍗曡鍒犻櫎
-  const delRepairByIds = async ids => {
-    // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
-    const idsArray = Array.isArray(ids) ? ids : [ids];
-    const hasFinished = idsArray.some(id => {
-      const record = dataList.value.find(item => item.id === id);
-      return record && record.status === 1;
-    });
-
-    if (hasFinished) {
-      ElMessage.warning("涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�");
-      return;
+  ElMessageBox.confirm("纭鍒犻櫎鎶ヤ慨鏁版嵁, 姝ゆ搷浣滀笉鍙��?", "璀﹀憡", {
+    confirmButtonText: "纭畾",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  }).then(async () => {
+    const {code} = await delRepair(ids);
+    if (code === 200) {
+      ElMessage.success("鍒犻櫎鎴愬姛");
+      getTableData();
     }
+  });
+};
 
-    ElMessageBox.confirm("纭鍒犻櫎鎶ヤ慨鏁版嵁, 姝ゆ搷浣滀笉鍙��?", "璀﹀憡", {
-      confirmButtonText: "纭畾",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    }).then(async () => {
-      const { code } = await delRepair(ids);
-      if (code === 200) {
-        ElMessage.success("鍒犻櫎鎴愬姛");
-        getTableData();
-      }
-    });
-  };
-
-  // 瀵煎嚭
-  const handleOut = () => {
-    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-      confirmButtonText: "纭",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
-    })
+// 瀵煎嚭
+const handleOut = () => {
+  ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
+    confirmButtonText: "纭",
+    cancelButtonText: "鍙栨秷",
+    type: "warning",
+  })
       .then(() => {
         proxy.download("/device/repair/export", {}, "璁惧鎶ヤ慨.xlsx");
       })
       .catch(() => {
         ElMessage.info("宸插彇娑�");
       });
-  };
+};
 
-  onMounted(() => {
-    getTableData();
-  });
+onMounted(() => {
+  getTableData();
+});
 </script>
 
 <style lang="scss" scoped>
-  .table_list {
-    margin-top: unset;
-  }
+.table_list {
+  margin-top: unset;
+}
 
-  .actions {
-    display: flex;
-    justify-content: space-between;
-    margin-bottom: 10px;
-  }
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
 </style>
diff --git a/src/views/equipmentManagement/spareParts/index.vue b/src/views/equipmentManagement/spareParts/index.vue
index 8abe35d..45e0157 100644
--- a/src/views/equipmentManagement/spareParts/index.vue
+++ b/src/views/equipmentManagement/spareParts/index.vue
@@ -88,8 +88,8 @@
           </el-form>
           <template #footer>
             <span class="dialog-footer">
-              <el-button type="primary" @click="submitForm" :loading="formLoading">纭畾</el-button>
               <el-button @click="dialogVisible = false" :disabled="formLoading">鍙栨秷</el-button>
+              <el-button type="primary" @click="submitForm" :loading="formLoading">纭畾</el-button>
             </span>
           </template>
         </el-dialog>
diff --git a/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
index 0fcccb2..e86b64a 100644
--- a/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
+++ b/src/views/equipmentManagement/upkeep/Form/MaintenanceModal.vue
@@ -1,216 +1,199 @@
 <template>
-  <FormDialog v-model="visible"
-              :title="'璁惧淇濆吇'"
-              width="500px"
-              @confirm="sendForm"
-              @cancel="handleCancel"
-              @close="handleClose">
-    <el-form :model="form"
-             label-width="100px">
+  <FormDialog
+    v-model="visible"
+    :title="'璁惧淇濆吇'"
+    width="500px"
+    @confirm="sendForm"
+    @cancel="handleCancel"
+    @close="handleClose"
+  >
+    <el-form :model="form" label-width="100px">
       <el-form-item label="瀹為檯淇濆吇浜�">
-        <el-input v-model="form.maintenanceActuallyName"
-                  placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"></el-input>
+        <el-input
+          v-model="form.maintenanceActuallyName"
+          placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
+        ></el-input>
       </el-form-item>
       <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
-        <el-date-picker v-model="form.maintenanceActuallyTime"
-                        placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
-                        format="YYYY-MM-DD HH:mm:ss"
-                        value-format="YYYY-MM-DD HH:mm:ss"
-                        type="datetime"
-                        clearable
-                        style="width: 100%" />
+        <el-date-picker
+          v-model="form.maintenanceActuallyTime"
+          placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
+          format="YYYY-MM-DD HH:mm:ss"
+          value-format="YYYY-MM-DD HH:mm:ss"
+          type="datetime"
+          clearable
+          style="width: 100%"
+        />
       </el-form-item>
       <el-form-item label="淇濆吇鐘舵��">
         <el-select v-model="form.status">
-          <el-option label="寰呬繚鍏�"
-                     :value="0"></el-option>
-          <el-option label="瀹岀粨"
-                     :value="1"></el-option>
-          <el-option label="澶辫触"
-                     :value="2"></el-option>
+          <el-option label="寰呬繚鍏�" :value="0"></el-option>
+          <el-option label="瀹岀粨" :value="1"></el-option>
+          <el-option label="澶辫触" :value="2"></el-option>
         </el-select>
       </el-form-item>
       <el-form-item label="淇濆吇缁撴灉">
-        <el-input v-model="form.maintenanceResult"
-                  placeholder="璇疯緭鍏ヤ繚鍏荤粨鏋�"
-                  type="text" />
+        <el-input
+          v-model="form.maintenanceResult"
+          placeholder="璇疯緭鍏ヤ繚鍏荤粨鏋�"
+          type="text" />
       </el-form-item>
       <el-form-item label="璁惧澶囦欢">
-        <el-select v-model="form.sparePartsIds"
-                   :loading="loadingSparePartOptions"
-                   placeholder="璇烽�夋嫨璁惧澶囦欢"
-                   multiple
-                   filterable>
-          <el-option v-for="item in sparePartOptions"
-                     :key="item.id"
-                     :label="item.name"
-                     :value="item.id" />
+        <el-select v-model="form.sparePartsIds" :loading="loadingSparePartOptions" placeholder="璇烽�夋嫨璁惧澶囦欢" multiple filterable>
+          <el-option
+              v-for="item in sparePartOptions"
+              :key="item.id"
+              :label="item.name"
+              :value="item.id"
+          />
         </el-select>
       </el-form-item>
-      <el-form-item v-if="selectedSpareParts.length"
-                    label="棰嗙敤鏁伴噺">
+
+      <el-form-item v-if="selectedSpareParts.length" label="棰嗙敤鏁伴噺">
         <div style="width: 100%">
-          <div v-for="item in selectedSpareParts"
-               :key="item.id"
-               style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;">
+          <div
+              v-for="item in selectedSpareParts"
+              :key="item.id"
+              style="display: flex; align-items: center; gap: 10px; margin-bottom: 10px;"
+          >
             <div style="flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;">
               {{ item.name }}
-              <span v-if="item.quantity !== null && item.quantity !== undefined"
-                    style="color: #909399;">
+              <span v-if="item.quantity !== null && item.quantity !== undefined" style="color: #909399;">
                 锛堝簱瀛橈細{{ item.quantity }}锛�
               </span>
             </div>
-            <el-input-number v-model="sparePartQtyMap[item.id]"
-                             :min="1"
-                             :max="item.quantity !== null && item.quantity !== undefined ? Number(item.quantity) : undefined"
-                             :step="1"
-                             controls-position="right"
-                             style="width: 180px" />
+            <el-input-number
+                v-model="sparePartQtyMap[item.id]"
+                :min="1"
+                :max="item.quantity !== null && item.quantity !== undefined ? Number(item.quantity) : undefined"
+                :step="1"
+                controls-position="right"
+                style="width: 180px"
+            />
           </div>
         </div>
-      </el-form-item>
-      <el-form-item label="闄勪欢">
-        <FileUpload v-model:file-list="form.storageBlobDTOs" />
       </el-form-item>
     </el-form>
   </FormDialog>
 </template>
 
 <script setup>
-  import FormDialog from "@/components/Dialog/FormDialog.vue";
-  import FileUpload from "@/components/AttachmentUpload/file/index.vue";
-  import { addMaintenance } from "@/api/equipmentManagement/upkeep";
-  import useFormData from "@/hooks/useFormData";
-  import dayjs from "dayjs";
-  import useUserStore from "@/store/modules/user";
-  import { ElMessage } from "element-plus";
-  import { computed, ref, nextTick, getCurrentInstance } from "vue";
-  import { getSparePartsList } from "@/api/equipmentManagement/spareParts.js";
+import FormDialog from "@/components/Dialog/FormDialog.vue";
+import { addMaintenance } from "@/api/equipmentManagement/upkeep";
+import useFormData from "@/hooks/useFormData";
+import dayjs from "dayjs";
+import useUserStore from "@/store/modules/user";
+import { ElMessage } from "element-plus";
+import {computed, ref} from "vue";
+import {getSparePartsList} from "@/api/equipmentManagement/spareParts.js";
 
-  defineOptions({
-    name: "淇濆吇妯℃�佹",
-  });
+defineOptions({
+  name: "淇濆吇妯℃�佹",
+});
 
-  const emits = defineEmits(["ok"]);
+const emits = defineEmits(["ok"]);
 
-  const { proxy } = getCurrentInstance();
-  // 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
-  const planId = ref();
-  const visible = ref(false);
-  const loading = ref(false);
-  const userStore = useUserStore();
+// 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
+const planId = ref();
+const visible = ref(false);
+const loading = ref(false);
+const userStore = useUserStore();
 
-  const { form, resetForm } = useFormData({
-    maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
-    maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
-    maintenanceResult: undefined, // 淇濆吇缁撴灉
-    status: 0, // 淇濆吇鐘舵��
-    sparePartsIds: [],
-    storageBlobDTOs: [],
-  });
+const { form, resetForm } = useFormData({
+  maintenanceActuallyName: undefined, // 瀹為檯淇濆吇浜�
+  maintenanceActuallyTime: undefined, // 瀹為檯淇濆吇鏃ユ湡
+  maintenanceResult: undefined, // 淇濆吇缁撴灉
+  status: 0, // 淇濆吇鐘舵��
+  sparePartsIds: [],
+});
 
-  const sparePartOptions = ref([]);
-  const loadingSparePartOptions = ref(true);
-  const sparePartQtyMap = ref({});
+const sparePartOptions = ref([])
+const loadingSparePartOptions = ref(true)
+const sparePartQtyMap = ref({})
 
-  const selectedSpareParts = computed(() => {
-    const ids = Array.isArray(form.sparePartsIds) ? form.sparePartsIds : [];
-    const set = new Set(ids.map(i => String(i)));
-    return (sparePartOptions.value || []).filter(p => set.has(String(p.id)));
-  });
+const selectedSpareParts = computed(() => {
+  const ids = Array.isArray(form.sparePartsIds) ? form.sparePartsIds : [];
+  const set = new Set(ids.map((i) => String(i)));
+  return (sparePartOptions.value || []).filter((p) => set.has(String(p.id)));
+});
 
-  const setForm = data => {
-    form.maintenanceActuallyName =
-      data.maintenanceActuallyName ?? userStore.nickName;
-    form.maintenanceActuallyTime = data.maintenanceActuallyTime
+const setForm = (data) => {
+  form.maintenanceActuallyName =
+    data.maintenanceActuallyName ?? userStore.nickName;
+  form.maintenanceActuallyTime =
+    data.maintenanceActuallyTime 
       ? dayjs(data.maintenanceActuallyTime).format("YYYY-MM-DD HH:mm:ss")
       : dayjs().format("YYYY-MM-DD HH:mm:ss");
-    form.maintenanceResult = data.maintenanceResult;
-    form.status = 1; // 榛樿鐘舵�佷负瀹岀粨
-    // multiple 閫夋嫨鍣ㄨ姹傛暟缁勶紱鍚庣甯歌繑鍥� "1,2,3"
-    if (Array.isArray(data?.sparePartsIds)) {
-      form.sparePartsIds = data.sparePartsIds
-        .map(v => Number(v))
-        .filter(v => Number.isFinite(v));
-    } else if (typeof data?.sparePartsIds === "string") {
-      form.sparePartsIds = data.sparePartsIds
+  form.maintenanceResult = data.maintenanceResult;
+  form.status = 1; // 榛樿鐘舵�佷负瀹岀粨
+  // multiple 閫夋嫨鍣ㄨ姹傛暟缁勶紱鍚庣甯歌繑鍥� "1,2,3"
+  if (Array.isArray(data?.sparePartsIds)) {
+    form.sparePartsIds = data.sparePartsIds.map((v) => Number(v)).filter((v) => Number.isFinite(v));
+  } else if (typeof data?.sparePartsIds === "string") {
+    form.sparePartsIds = data.sparePartsIds
         .split(",")
-        .map(s => Number(String(s).trim()))
-        .filter(v => Number.isFinite(v));
-    } else if (typeof data?.sparePartsIds === "number") {
-      form.sparePartsIds = [data.sparePartsIds];
-    } else {
-      form.sparePartsIds = [];
-    }
-    form.storageBlobDTOs = data.storageBlobVOs || [];
-  };
+        .map((s) => Number(String(s).trim()))
+        .filter((v) => Number.isFinite(v));
+  } else if (typeof data?.sparePartsIds === "number") {
+    form.sparePartsIds = [data.sparePartsIds];
+  } else {
+    form.sparePartsIds = [];
+  }
+};
 
-  /**
-   * @desc 淇濆瓨淇濆吇
-   */
-  const sendForm = async () => {
-    loading.value = true;
-    try {
-      // 棰嗙敤鏁伴噺鏍¢獙
-      if (Array.isArray(form.sparePartsIds) && form.sparePartsIds.length > 0) {
-        for (const partId of form.sparePartsIds) {
-          const qty = Number(sparePartQtyMap.value?.[partId]);
-          if (!Number.isFinite(qty) || qty <= 0) {
-            proxy?.$modal?.msgError?.("璇峰~鍐欏浠堕鐢ㄦ暟閲�");
+/**
+ * @desc 淇濆瓨淇濆吇
+ */
+const sendForm = async () => {
+  loading.value = true;
+  try {
+    // 棰嗙敤鏁伴噺鏍¢獙
+    if (Array.isArray(form.sparePartsIds) && form.sparePartsIds.length > 0) {
+      for (const partId of form.sparePartsIds) {
+        const qty = Number(sparePartQtyMap.value?.[partId]);
+        if (!Number.isFinite(qty) || qty <= 0) {
+          proxy?.$modal?.msgError?.("璇峰~鍐欏浠堕鐢ㄦ暟閲�");
+          return;
+        }
+        const part = sparePartOptions.value.find((p) => String(p.id) === String(partId));
+        const stock = part?.quantity;
+        if (stock !== null && stock !== undefined && Number.isFinite(Number(stock))) {
+          if (qty > Number(stock)) {
+            proxy?.$modal?.msgError?.(`澶囦欢銆�${part?.name || ""}銆嶉鐢ㄦ暟閲忎笉鑳借秴杩囧簱瀛橈紙${stock}锛塦);
             return;
-          }
-          const part = sparePartOptions.value.find(
-            p => String(p.id) === String(partId)
-          );
-          const stock = part?.quantity;
-          if (
-            stock !== null &&
-            stock !== undefined &&
-            Number.isFinite(Number(stock))
-          ) {
-            if (qty > Number(stock)) {
-              proxy?.$modal?.msgError?.(
-                `澶囦欢銆�${part?.name || ""}銆嶉鐢ㄦ暟閲忎笉鑳借秴杩囧簱瀛橈紙${stock}锛塦
-              );
-              return;
-            }
           }
         }
       }
-      const data = {
-        id: planId.value,
-        ...form,
-        sparePartsIds: form.sparePartsIds ? form.sparePartsIds.join(",") : "",
-        sparePartsQty: form.sparePartsIds
-          ? form.sparePartsIds
-              .map(id => sparePartQtyMap.value?.[id] ?? 1)
-              .join(",")
-          : "",
-        sparePartsUseList: form.sparePartsIds
-          ? form.sparePartsIds.map(id => ({
-              id,
-              quantity: sparePartQtyMap.value?.[id] ?? 1,
-            }))
-          : [],
-      };
-      const { code } = await addMaintenance(data);
-      if (code == 200) {
-        ElMessage.success("淇濆吇鎴愬姛");
-        emits("ok");
-        resetForm();
-        sparePartQtyMap.value = {};
-        visible.value = false;
-      }
-    } finally {
-      loading.value = false;
     }
-  };
+    const data = {
+      id: planId.value,
+      ...form,
+      sparePartsIds: form.sparePartsIds ? form.sparePartsIds.join(",") : "",
+      sparePartsQty: form.sparePartsIds
+          ? form.sparePartsIds.map((id) => sparePartQtyMap.value?.[id] ?? 1).join(",")
+          : "",
+      sparePartsUseList: form.sparePartsIds
+          ? form.sparePartsIds.map((id) => ({ id, quantity: sparePartQtyMap.value?.[id] ?? 1 }))
+          : [],
+    }
+    const { code } = await addMaintenance(data);
+    if (code == 200) {
+      ElMessage.success("淇濆吇鎴愬姛");
+      emits("ok");
+      resetForm();
+      sparePartQtyMap.value = {};
+      visible.value = false;
+    }
+  } finally {
+    loading.value = false;
+  }
+};
 
-  const fetchSparePartOptions = () => {
-    loadingSparePartOptions.value = true;
-    // 鍜屽浠剁鐞嗛〉涓�鑷达細/spareParts/listPage 鈫� res.data.records
-    getSparePartsList({ current: 1, size: 1000 })
-      .then(res => {
+const fetchSparePartOptions = () => {
+  loadingSparePartOptions.value = true;
+  // 鍜屽浠剁鐞嗛〉涓�鑷达細/spareParts/listPage 鈫� res.data.records
+  getSparePartsList({ current: 1, size: 1000 })
+      .then((res) => {
         if (res.code === 200) {
           sparePartOptions.value = res?.data?.records || [];
         } else {
@@ -223,31 +206,31 @@
       .finally(() => {
         loadingSparePartOptions.value = false;
       });
-  };
+}
 
-  const handleCancel = () => {
-    resetForm();
-    sparePartQtyMap.value = {};
-    visible.value = false;
-  };
+const handleCancel = () => {
+  resetForm();
+  sparePartQtyMap.value = {};
+  visible.value = false;
+};
 
-  const handleClose = () => {
-    resetForm();
-    sparePartQtyMap.value = {};
-    visible.value = false;
-  };
+const handleClose = () => {
+  resetForm();
+  sparePartQtyMap.value = {};
+  visible.value = false;
+};
 
-  const open = async (id, row) => {
-    planId.value = id; // 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
-    visible.value = true;
-    await nextTick();
-    fetchSparePartOptions();
-    setForm(row);
-  };
+const open = async (id, row) => {
+  planId.value = id; // 淇濆瓨璁″垝淇濆吇璁板綍鐨刬d
+  visible.value = true;
+  await nextTick();
+  fetchSparePartOptions()
+  setForm(row);
+};
 
-  defineExpose({
-    open,
-  });
+defineExpose({
+  open,
+});
 </script>
 
 <style lang="scss" scoped></style>
diff --git a/src/views/equipmentManagement/upkeep/Form/PlanModal.vue b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
index 8a9cd98..e44d6af 100644
--- a/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
+++ b/src/views/equipmentManagement/upkeep/Form/PlanModal.vue
@@ -8,34 +8,46 @@
     @close="handleClose"
   >
     <el-form :model="form" label-width="100px">
+      <el-form-item label="鎵�灞炲尯鍩�">
+        <el-tree-select
+          v-model="form.areaId"
+          :data="areaOptions"
+          :props="areaTreeProps"
+          node-key="id"
+          value-key="id"
+          check-strictly
+          clearable
+          filterable
+          placeholder="璇烽�夋嫨鎵�灞炲尯鍩�"
+          style="width: 100%"
+          @change="handleAreaChange"
+        />
+      </el-form-item>
       <el-form-item label="璁惧鍚嶇О">
         <el-select
-          v-model="form.deviceLedgerId"
-          @change="setDeviceModel"
-          placeholder="璇烽�夋嫨璁惧"
+          v-model="form.deviceLedgerIds"
           filterable
-          default-first-option
-          :reserve-keyword="false"
+          clearable
+          multiple
+          collapse-tags
+          collapse-tags-tooltip
+          placeholder="璇烽�夋嫨璁惧"
+          style="width: 100%"
+          @change="setDeviceModels"
         >
           <el-option
-            v-for="(item, index) in deviceOptions"
-            :key="index"
+            v-for="item in deviceOptions"
+            :key="item.id"
             :label="item.deviceName"
             :value="item.id"
-          ></el-option>
+          />
         </el-select>
       </el-form-item>
       <el-form-item label="瑙勬牸鍨嬪彿">
         <el-input
           v-model="form.deviceModel"
-          placeholder="璇疯緭鍏ヨ鏍煎瀷鍙�"
+          placeholder="鑷姩甯﹀嚭瑙勬牸鍨嬪彿"
           disabled
-        />
-      </el-form-item>
-      <el-form-item label="淇濆吇椤圭洰">
-        <el-input
-            v-model="form.machineryCategory"
-            placeholder="璇疯緭鍏ヤ繚鍏婚」鐩�"
         />
       </el-form-item>
       <el-form-item label="褰曞叆浜�">
@@ -57,54 +69,42 @@
       </el-form-item>
       <el-form-item v-if="id" label="淇濅慨鐘舵��">
         <el-select v-model="form.status">
-          <el-option label="寰呬繚淇�" :value="0"></el-option>
-          <el-option label="瀹岀粨" :value="1"></el-option>
-          <el-option label="澶辫触" :value="2"></el-option>
+          <el-option label="寰呬繚淇�" :value="0" />
+          <el-option label="瀹岀粨" :value="1" />
+          <el-option label="澶辫触" :value="2" />
         </el-select>
-      </el-form-item>
-      <el-form-item label="淇濆吇浜�">
-        <el-input
-          v-model="form.maintenancePerson"
-          placeholder="璇疯緭鍏ヤ繚鍏讳汉濮撳悕"
-          clearable
-        />
       </el-form-item>
       <el-form-item label="璁″垝淇濆吇鏃ユ湡">
         <el-date-picker
-          style="width: 100%"
           v-model="form.maintenancePlanTime"
+          style="width: 100%"
           format="YYYY-MM-DD"
           value-format="YYYY-MM-DD HH:mm:ss"
           type="date"
-          placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡鏃ユ湡"
+          placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡"
           clearable
         />
       </el-form-item>
-      <el-row :gutter="30">
-        <el-col :span="24">
-          <el-form-item label="闄勪欢" prop="attachmentIds">
-            <FileUpload v-model:file-list="form.storageBlobDTOs" />
-          </el-form-item>
-        </el-col>
-      </el-row>
     </el-form>
   </FormDialog>
 </template>
 
 <script setup>
+import { nextTick, onMounted, ref, unref } from "vue";
+import dayjs from "dayjs";
+import { ElMessage } from "element-plus";
 import FormDialog from "@/components/Dialog/FormDialog.vue";
+import useFormData from "@/hooks/useFormData";
+import { userListNoPage } from "@/api/system/user.js";
 import {
   addUpkeep,
   editUpkeep,
   getUpkeepById,
 } from "@/api/equipmentManagement/upkeep";
-import { ElMessage } from "element-plus";
-import useFormData from "@/hooks/useFormData";
-import { getDeviceLedger } from "@/api/equipmentManagement/ledger";
-import { onMounted } from "vue";
-import dayjs from "dayjs";
-import { userListNoPage } from "@/api/system/user.js";
-import FileUpload from "@/components/AttachmentUpload/file/index.vue";
+import {
+  getDeviceAreaTree,
+  getDeviceAreaTreeWithDevices,
+} from "@/api/equipmentManagement/deviceArea";
 
 defineOptions({
   name: "璁惧淇濆吇鏂板璁″垝",
@@ -115,55 +115,159 @@
 const id = ref();
 const visible = ref(false);
 const loading = ref(false);
-
+const areaOptions = ref([]);
 const deviceOptions = ref([]);
-const loadDeviceName = async () => {
-  const { data } = await getDeviceLedger();
-  deviceOptions.value = data;
+const userList = ref([]);
+const areaTreeProps = {
+  label: "areaName",
+  children: "children",
 };
 
 const { form, resetForm } = useFormData({
-  deviceLedgerId: undefined, // 璁惧Id
-  deviceName: undefined, // 璁惧鍚嶇О
-  deviceModel: undefined, // 瑙勬牸鍨嬪彿
-  maintenancePlanTime: undefined, // 璁″垝淇濆吇鏃ユ湡
-  createUser: undefined, // 褰曞叆浜�
-  status: 0, //淇濅慨鐘舵��
-  machineryCategory: undefined,
-  storageBlobDTOs: [],
-  maintenancePerson: undefined, // 淇濆吇浜�
+  areaId: undefined,
+  deviceLedgerId: undefined,
+  deviceLedgerIds: [],
+  deviceLedgerIdsStr: undefined,
+  deviceName: undefined,
+  deviceModel: undefined,
+  maintenancePlanTime: undefined,
+  createUser: undefined,
+  status: 0,
 });
 
-const setDeviceModel = (deviceId) => {
-  const option = deviceOptions.value.find((item) => item.id === deviceId);
-  form.deviceModel = option.deviceModel;
+const loadAreaTree = async () => {
+  const { data } = await getDeviceAreaTree();
+  areaOptions.value = Array.isArray(data) ? data : [];
 };
 
-/**
- * @desc 璁剧疆琛ㄥ崟鍐呭
- * @param data 璁惧淇℃伅
- */
+const normalizeIdList = (value) => {
+  if (Array.isArray(value)) {
+    return value
+      .map((item) => Number(item))
+      .filter((item) => Number.isFinite(item));
+  }
+  if (typeof value === "string") {
+    return value
+      .split(",")
+      .map((item) => Number(item.trim()))
+      .filter((item) => Number.isFinite(item));
+  }
+  if (value !== undefined && value !== null && value !== "") {
+    const numericValue = Number(value);
+    return Number.isFinite(numericValue) ? [numericValue] : [];
+  }
+  return [];
+};
+
+const getNodeDevices = (node) => {
+  const candidates = [
+    node?.deviceList,
+    node?.devices,
+    node?.deviceLedgerList,
+    node?.deviceLedgers,
+    node?.ledgerList,
+    node?.ledgers,
+  ];
+  return candidates.find((item) => Array.isArray(item)) || [];
+};
+
+const normalizeDevice = (item) => ({
+  ...item,
+  id: item.id ?? item.deviceLedgerId,
+  deviceName: item.deviceName ?? item.name,
+  deviceModel: item.deviceModel ?? item.model,
+});
+
+const collectDevices = (node) => {
+  const currentDevices = getNodeDevices(node).map(normalizeDevice);
+  const childDevices = (node?.children || []).flatMap((child) =>
+    collectDevices(child)
+  );
+  const deviceMap = new Map();
+  [...currentDevices, ...childDevices].forEach((item) => {
+    if (item?.id !== undefined && item?.id !== null) {
+      deviceMap.set(Number(item.id), item);
+    }
+  });
+  return Array.from(deviceMap.values());
+};
+
+const findAreaNode = (nodes, areaId) => {
+  for (const node of nodes || []) {
+    if (Number(node.id) === Number(areaId)) {
+      return node;
+    }
+    const target = findAreaNode(node.children, areaId);
+    if (target) {
+      return target;
+    }
+  }
+  return null;
+};
+
+const loadDevicesByArea = async (areaId) => {
+  if (!areaId) {
+    deviceOptions.value = [];
+    return;
+  }
+  const { data } = await getDeviceAreaTreeWithDevices();
+  const treeData = Array.isArray(data) ? data : [];
+  const currentNode = findAreaNode(treeData, areaId);
+  deviceOptions.value = currentNode ? collectDevices(currentNode) : [];
+};
+
+const syncDeviceFields = (deviceIds) => {
+  const selectedIds = normalizeIdList(deviceIds);
+  const selectedDevices = selectedIds
+    .map((deviceId) =>
+      deviceOptions.value.find((item) => Number(item.id) === Number(deviceId))
+    )
+    .filter(Boolean);
+
+  form.deviceLedgerIds = selectedIds;
+  form.deviceLedgerId = selectedIds[0];
+  form.deviceLedgerIdsStr = selectedIds.join(",");
+  form.deviceName = selectedDevices
+    .map((item) => item.deviceName)
+    .filter(Boolean)
+    .join(",");
+  form.deviceModel = selectedDevices
+    .map((item) => item.deviceModel || "-")
+    .join(",");
+};
+
+const setDeviceModels = (deviceIds) => {
+  syncDeviceFields(deviceIds);
+};
+
+const handleAreaChange = async (areaId) => {
+  form.deviceLedgerId = undefined;
+  form.deviceLedgerIds = [];
+  form.deviceLedgerIdsStr = undefined;
+  form.deviceName = undefined;
+  form.deviceModel = undefined;
+  await loadDevicesByArea(areaId);
+};
+
 const setForm = (data) => {
-  form.deviceLedgerId = data.deviceLedgerId;
+  form.areaId = data.areaId;
+  form.deviceLedgerIds = normalizeIdList(
+    data.deviceLedgerIds ?? data.deviceLedgerIdsStr ?? data.deviceLedgerId
+  );
+  form.deviceLedgerId = form.deviceLedgerIds[0];
+  form.deviceLedgerIdsStr =
+    data.deviceLedgerIdsStr ?? form.deviceLedgerIds.join(",");
   form.deviceName = data.deviceName;
   form.deviceModel = data.deviceModel;
   form.createUser = Number(data.createUser);
   form.status = data.status;
-  form.machineryCategory = data.machineryCategory;
-  form.maintenancePerson = data.maintenancePerson;
-  if (data.maintenancePlanTime) {
-    form.maintenancePlanTime = dayjs(data.maintenancePlanTime).format(
-      "YYYY-MM-DD HH:mm:ss"
-    );
-  }
-  form.storageBlobDTOs = data.storageBlobVOs || [];
+  form.maintenancePlanTime = data.maintenancePlanTime
+    ? dayjs(data.maintenancePlanTime).format("YYYY-MM-DD HH:mm:ss")
+    : undefined;
 };
 
-// 鐢ㄦ埛鍒楄〃
-const userList = ref([]);
-
 onMounted(() => {
-  loadDeviceName();
+  loadAreaTree();
   userListNoPage().then((res) => {
     userList.value = res.data;
   });
@@ -174,16 +278,27 @@
   id.value = editId;
   visible.value = true;
   await nextTick();
+  await loadAreaTree();
   setForm(data);
+  await loadDevicesByArea(form.areaId);
+  syncDeviceFields(form.deviceLedgerIds);
 };
 
 const sendForm = async () => {
   loading.value = true;
   try {
+    syncDeviceFields(form.deviceLedgerIds);
+    const payload = {
+      ...form,
+      deviceLedgerId: form.deviceLedgerIds[0],
+      deviceLedgerIds: [...form.deviceLedgerIds],
+      deviceLedgerIdsStr: form.deviceLedgerIds.join(","),
+      deviceModel: form.deviceModel || "-",
+    };
     const { code } = id.value
-      ? await editUpkeep({ id: unref(id), ...form })
-      : await addUpkeep(form);
-    if (code == 200) {
+      ? await editUpkeep({ id: unref(id), ...payload })
+      : await addUpkeep(payload);
+    if (code === 200) {
       ElMessage.success(`${id.value ? "缂栬緫" : "鏂板"}璁″垝鎴愬姛`);
       visible.value = false;
       emits("ok");
@@ -203,9 +318,12 @@
   visible.value = false;
 };
 
-const openModal = () => {
+const openModal = async () => {
   id.value = undefined;
   visible.value = true;
+  await nextTick();
+  await loadAreaTree();
+  deviceOptions.value = [];
 };
 
 defineExpose({
diff --git a/src/views/equipmentManagement/upkeep/index.vue b/src/views/equipmentManagement/upkeep/index.vue
index 245a162..419e9aa 100644
--- a/src/views/equipmentManagement/upkeep/index.vue
+++ b/src/views/equipmentManagement/upkeep/index.vue
@@ -1,652 +1,746 @@
 <template>
   <div class="app-container">
-    <el-tabs v-model="activeTab"
-             @tab-change="handleTabChange">
-      <!-- 淇濆吇浠诲姟tab -->
-      <el-tab-pane label="淇濆吇浠诲姟"
-                   name="scheduled">
+    <el-tabs v-model="activeTab" @tab-change="handleTabChange">
+      <!-- 瀹氭椂浠诲姟绠$悊tab -->
+      <el-tab-pane label="瀹氭椂浠诲姟绠$悊" name="scheduled">
         <div class="search_form">
-          <el-form :model="scheduledFilters"
-                   :inline="true">
+          <el-form :model="scheduledFilters" :inline="true">
             <el-form-item label="浠诲姟鍚嶇О">
-              <el-input v-model="scheduledFilters.taskName"
-                        style="width: 240px"
-                        placeholder="璇疯緭鍏ヤ换鍔″悕绉�"
-                        clearable
-                        :prefix-icon="Search"
-                        @change="getScheduledTableData" />
+              <el-input
+                  v-model="scheduledFilters.taskName"
+                  style="width: 240px"
+                  placeholder="璇疯緭鍏ヤ换鍔″悕绉�"
+                  clearable
+                  :prefix-icon="Search"
+                  @change="getScheduledTableData"
+              />
             </el-form-item>
-            <el-form-item label="浠诲姟鐘舵��">
-              <el-select v-model="scheduledFilters.status"
-                         placeholder="璇烽�夋嫨浠诲姟鐘舵��"
-                         clearable
-                         style="width: 200px">
-                <el-option label="鍚敤"
-                           value="1" />
-                <el-option label="鍋滅敤"
-                           value="0" />
+            <el-form-item label="鏄惁鍚敤">
+              <el-select v-model="scheduledFilters.isEnabled" placeholder="璇烽�夋嫨鏄惁鍚敤" clearable style="width: 200px">
+                <el-option label="鍚敤" :value="1" />
+                <el-option label="绂佺敤" :value="0" />
               </el-select>
             </el-form-item>
             <el-form-item>
-              <el-button type="primary"
-                         @click="getScheduledTableData">鎼滅储</el-button>
+              <el-button type="primary" @click="getScheduledTableData">鎼滅储</el-button>
               <el-button @click="resetScheduledFilters">閲嶇疆</el-button>
             </el-form-item>
           </el-form>
         </div>
         <div class="table_list">
           <div class="actions">
-            <el-text class="mx-1"
-                     size="large">淇濆吇浠诲姟</el-text>
+            <el-text class="mx-1" size="large">瀹氭椂浠诲姟绠$悊</el-text>
             <div>
-              <el-button type="primary"
-                         icon="Plus"
-                         @click="addScheduledTask">
+              <el-button type="primary" icon="Plus" @click="addScheduledTask">
                 鏂板浠诲姟
               </el-button>
-              <el-button type="danger"
-                         icon="Delete"
-                         :disabled="scheduledMultipleList.length <= 0"
-                         @click="delScheduledTaskByIds(scheduledMultipleList.map((item) => item.id))">
+              <el-button
+                type="danger"
+                icon="Delete"
+                :disabled="scheduledMultipleList.length <= 0"
+                @click="delScheduledTaskByIds(scheduledMultipleList.map((item) => item.id))"
+              >
                 鎵归噺鍒犻櫎
               </el-button>
             </div>
           </div>
-          <PIMTable rowKey="id"
-                    isSelection
-                    :column="scheduledColumns"
-                    :tableData="scheduledDataList"
-                    :page="{
+          <PIMTable
+            rowKey="id"
+            isSelection
+            :column="scheduledColumns"
+            :tableData="scheduledDataList"
+            :page="{
               current: scheduledPagination.currentPage,
               size: scheduledPagination.pageSize,
               total: scheduledPagination.total,
             }"
-                    @selection-change="handleScheduledSelectionChange"
-                    @pagination="changeScheduledPage">
-            <template #statusRef="{ row }">
-              <el-tag v-if="row.status === 1"
-                      type="success">鍚敤</el-tag>
-              <el-tag v-if="row.status === 0"
-                      type="danger">鍋滅敤</el-tag>
+            @selection-change="handleScheduledSelectionChange"
+            @pagination="changeScheduledPage"
+          >
+            <template #isEnabledRef="{ row }">
+              <el-switch
+                v-model="row.isEnabled"
+                :active-value="1"
+                :inactive-value="0"
+                :loading="row.enableSwitchLoading"
+                :before-change="() => handleScheduledEnableBeforeChange(row)"
+              />
             </template>
             <template #operation="{ row }">
-              <el-button type="primary"
-                         link
-                         @click="editScheduledTask(row)">
+              <el-button
+                type="primary"
+                link
+                @click="editScheduledTask(row)"
+              >
                 缂栬緫
               </el-button>
-              <el-button type="danger"
-                         link
-                         @click="delScheduledTaskByIds(row.id)">
+              <el-button
+                type="danger"
+                link
+                @click="delScheduledTaskByIds(row.id)"
+              >
                 鍒犻櫎
               </el-button>
             </template>
           </PIMTable>
         </div>
       </el-tab-pane>
-      <!-- 淇濆吇璁板綍tab锛堝師璁惧淇濆吇椤甸潰锛� -->
-      <el-tab-pane label="淇濆吇璁板綍"
-                   name="record">
+
+      <!-- 浠诲姟璁板綍tab锛堝師璁惧淇濆吇椤甸潰锛� -->
+      <el-tab-pane label="浠诲姟璁板綍" name="record">
         <div class="search_form">
-          <el-form :model="filters"
-                   :inline="true">
+          <el-form :model="filters" :inline="true">
             <el-form-item label="璁惧鍚嶇О">
-              <el-input v-model="filters.deviceName"
-                        style="width: 240px"
-                        placeholder="璇疯緭鍏ヨ澶囧悕绉�"
-                        clearable
-                        :prefix-icon="Search"
-                        @change="getTableData" />
+              <el-input
+                  v-model="filters.deviceName"
+                  style="width: 240px"
+                  placeholder="璇疯緭鍏ヨ澶囧悕绉�"
+                  clearable
+                  :prefix-icon="Search"
+                  @change="getTableData"
+              />
             </el-form-item>
             <el-form-item label="璁″垝淇濆吇鏃ユ湡">
-              <el-date-picker v-model="filters.maintenancePlanTime"
-                              type="date"
-                              placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡"
-                              size="default"
-                              @change="(date) => handleDateChange(date,2)" />
+              <el-date-picker
+                  v-model="filters.maintenancePlanTime"
+                  type="date"
+                  placeholder="璇烽�夋嫨璁″垝淇濆吇鏃ユ湡"
+                  size="default"
+                  @change="(date) => handleDateChange(date,2)"
+              />
             </el-form-item>
             <el-form-item label="瀹為檯淇濆吇鏃ユ湡">
-              <el-date-picker v-model="filters.maintenanceActuallyTime"
-                              type="date"
-                              placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
-                              size="default"
-                              @change="(date) => handleDateChange(date,1)" />
+              <el-date-picker
+                  v-model="filters.maintenanceActuallyTime"
+                  type="date"
+                  placeholder="璇烽�夋嫨瀹為檯淇濆吇鏃ユ湡"
+                  size="default"
+                  @change="(date) => handleDateChange(date,1)"
+              />
             </el-form-item>
             <el-form-item label="瀹為檯淇濆吇浜�">
-              <el-input v-model="filters.maintenanceActuallyName"
-                        style="width: 240px"
-                        placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
-                        clearable
-                        :prefix-icon="Search"
-                        @change="getTableData" />
+              <el-input
+                  v-model="filters.maintenanceActuallyName"
+                  style="width: 240px"
+                  placeholder="璇疯緭鍏ュ疄闄呬繚鍏讳汉"
+                  clearable
+                  :prefix-icon="Search"
+                  @change="getTableData"
+              />
             </el-form-item>
             <el-form-item>
-              <el-button type="primary"
-                         @click="getTableData">鎼滅储</el-button>
+              <el-button type="primary" @click="getTableData">鎼滅储</el-button>
               <el-button @click="resetFilters">閲嶇疆</el-button>
             </el-form-item>
           </el-form>
         </div>
         <div class="table_list">
           <div class="actions">
-            <el-text class="mx-1"
-                     size="large">淇濆吇璁板綍</el-text>
+            <el-text class="mx-1" size="large">浠诲姟璁板綍</el-text>
             <div>
-              <el-button type="success"
-                         icon="Van"
-                         @click="addPlan">
+              <el-button type="success" icon="Van" @click="addPlan">
                 鏂板璁″垝
               </el-button>
               <el-button @click="handleOut">
                 瀵煎嚭
               </el-button>
-              <el-button type="danger"
-                         icon="Delete"
-                         :disabled="multipleList.length <= 0 || hasFinishedStatus"
-                         @click="delRepairByIds(multipleList.map((item) => item.id))">
+              <el-button
+                type="danger"
+                icon="Delete"
+                :disabled="multipleList.length <= 0 || hasFinishedStatus"
+                @click="delRepairByIds(multipleList.map((item) => item.id))"
+              >
                 鎵归噺鍒犻櫎
               </el-button>
             </div>
           </div>
-          <PIMTable rowKey="id"
-                    isSelection
-                    :column="columns"
-                    :tableData="dataList"
-                    :page="{
+         <PIMTable
+        rowKey="id"
+        isSelection
+        :column="columns"
+        :tableData="dataList"
+        :page="{
           current: pagination.currentPage,
           size: pagination.pageSize,
           total: pagination.total,
         }"
-                    @selection-change="handleSelectionChange"
-                    @pagination="changePage">
-            <template #maintenanceResultRef="{ row }">
-              <div>{{ row.maintenanceResult || '-' }}</div>
-            </template>
-            <template #statusRef="{ row }">
-              <el-tag v-if="row.status === 2"
-                      type="danger">澶辫触</el-tag>
-              <el-tag v-if="row.status === 1"
-                      type="success">瀹岀粨</el-tag>
-              <el-tag v-if="row.status === 0"
-                      type="warning">寰呬繚鍏�</el-tag>
-            </template>
-            <template #operation="{ row }">
-              <!-- 杩欎釜鍔熻兘璺熸柊澧炰繚鍏诲姛鑳戒竴妯′竴鏍凤紝鏈夊暐鎰忎箟锛� -->
-              <!-- <el-button
+        @selection-change="handleSelectionChange"
+        @pagination="changePage"
+      >
+        <template #maintenanceResultRef="{ row }">
+          <div>{{ row.maintenanceResult || '-' }}</div>
+        </template>
+        <template #statusRef="{ row }">
+          <el-tag v-if="row.status === 2" type="danger">澶辫触</el-tag>
+          <el-tag v-if="row.status === 1" type="success">瀹岀粨</el-tag>
+          <el-tag v-if="row.status === 0" type="warning">寰呬繚鍏�</el-tag>
+        </template>
+        <template #operation="{ row }">
+          <!-- 杩欎釜鍔熻兘璺熸柊澧炰繚鍏诲姛鑳戒竴妯′竴鏍凤紝鏈夊暐鎰忎箟锛� -->
+          <!-- <el-button
               type="primary"
               text
               @click="addMaintain(row)"
           >
             鏂板淇濆吇
           </el-button> -->
-              <el-button type="primary"
-                         link
-                         :disabled="row.status === 1"
-                         @click="editPlan(row.id)">
-                缂栬緫
-              </el-button>
-              <el-button type="success"
-                         link
-                         :disabled="row.status === 1"
-                         @click="addMaintain(row)">
-                淇濆吇
-              </el-button>
-              <el-button type="danger"
-                         link
-                         :disabled="row.status === 1"
-                         @click="delRepairByIds(row.id)">
-                鍒犻櫎
-              </el-button>
-              <el-button type="primary"
-                         link
-                         @click="openFileDialog(row)">
-                闄勪欢
-              </el-button>
-            </template>
-          </PIMTable>
+          <el-button
+            type="primary"
+            link
+            :disabled="row.status === 1"
+            @click="editPlan(row.id)"
+          >
+            缂栬緫
+          </el-button>
+          <el-button
+            type="success"
+            link
+            :disabled="row.status === 1"
+            @click="addMaintain(row)"
+          >
+            淇濆吇
+          </el-button>
+          <el-button
+            type="danger"
+            link
+            :disabled="row.status === 1"
+            @click="delRepairByIds(row.id)"
+          >
+            鍒犻櫎
+          </el-button>
+          <el-button
+            type="primary"
+            link
+            @click="openFileDialog(row)"
+          >
+            闄勪欢
+          </el-button>
+        </template>
+      </PIMTable>
         </div>
       </el-tab-pane>
     </el-tabs>
-    <PlanModal ref="planModalRef"
-               @ok="getTableData" />
-    <MaintenanceModal ref="maintainModalRef"
-                      @ok="getTableData" />
-    <FormDia ref="formDiaRef"
-             @closeDia="getScheduledTableData" />
-    <FileList v-if="fileDialogVisible"
-              v-model:visible="fileDialogVisible"
-              :record-type="'device_maintenance'"
-              :record-id="currentMaintenanceTaskId" />
+    <PlanModal ref="planModalRef" @ok="getTableData" />
+        <MaintenanceModal ref="maintainModalRef" @ok="getTableData" />
+        <FormDia ref="formDiaRef" @closeDia="getScheduledTableData" />
+    <FileListDialog 
+      ref="fileListDialogRef"
+      v-model="fileDialogVisible"
+      :show-upload-button="true"
+      :show-delete-button="true"
+      :delete-method="handleAttachmentDelete"
+      :name-column-label="'闄勪欢鍚嶇О'"
+      :rulesRegulationsManagementId="currentMaintenanceTaskId"
+      @upload="handleAttachmentUpload" />
   </div>
 </template>
 
 <script setup>
-  import {
-    ref,
-    onMounted,
-    reactive,
-    getCurrentInstance,
-    nextTick,
-    computed,
-    defineAsyncComponent,
-  } from "vue";
-  import { Search } from "@element-plus/icons-vue";
-  import { ElMessage, ElMessageBox } from "element-plus";
-  import PlanModal from "./Form/PlanModal.vue";
-  import MaintenanceModal from "./Form/MaintenanceModal.vue";
-  import FormDia from "./Form/formDia.vue";
-  import {
-    getUpkeepPage,
-    delUpkeep,
-    deviceMaintenanceTaskList,
-    deviceMaintenanceTaskDel,
-  } from "@/api/equipmentManagement/upkeep";
-  import dayjs from "dayjs";
+import { ref, onMounted, reactive, getCurrentInstance, nextTick, computed } from 'vue'
+import { Search } from '@element-plus/icons-vue'
+import { ElMessage, ElMessageBox } from 'element-plus'
+import PlanModal from './Form/PlanModal.vue'
+import MaintenanceModal from './Form/MaintenanceModal.vue'
+import FormDia from './Form/formDia.vue'
+import FileListDialog from '@/components/Dialog/FileListDialog.vue'
+import {
+  getUpkeepPage,
+  delUpkeep,
+  deviceMaintenanceTaskList,
+  deviceMaintenanceTaskDel,
+  deviceMaintenanceTaskChangeEnable,
+} from '@/api/equipmentManagement/upkeep'
+import {
+  listMaintenanceTaskFiles,
+  addMaintenanceTaskFile,
+  delMaintenanceTaskFile,
+} from '@/api/equipmentManagement/maintenanceTaskFile'
+import dayjs from 'dayjs'
 
-  const { proxy } = getCurrentInstance();
-  const FileList = defineAsyncComponent(() =>
-    import("@/components/Dialog/FileList.vue")
-  );
+const { proxy } = getCurrentInstance()
 
-  // Tab鐩稿叧
-  const activeTab = ref("scheduled");
+// Tab鐩稿叧
+const activeTab = ref('scheduled')
 
-  // 璁″垝寮圭獥鎺у埗鍣�
-  const planModalRef = ref();
-  // 淇濆吇寮圭獥鎺у埗鍣�
-  const maintainModalRef = ref();
-  // 瀹氭椂浠诲姟寮圭獥鎺у埗鍣�
-  const formDiaRef = ref();
-  // 闄勪欢寮圭獥
-  const fileListDialogRef = ref(null);
-  const fileDialogVisible = ref(false);
-  const currentMaintenanceTaskId = ref(null);
+// 璁″垝寮圭獥鎺у埗鍣�
+const planModalRef = ref()
+// 淇濆吇寮圭獥鎺у埗鍣�
+const maintainModalRef = ref()
+// 瀹氭椂浠诲姟寮圭獥鎺у埗鍣�
+const formDiaRef = ref()
+// 闄勪欢寮圭獥
+const fileListDialogRef = ref(null)
+const fileDialogVisible = ref(false)
+const currentMaintenanceTaskId = ref(null)
 
-  // 淇濆吇璁板綍tab锛堝師璁惧淇濆吇椤甸潰锛夌浉鍏冲彉閲�
-  const filters = reactive({
-    deviceName: "",
-    maintenancePlanTime: "",
-    maintenanceActuallyTime: "",
-    maintenanceActuallyName: "",
-  });
+// 浠诲姟璁板綍tab锛堝師璁惧淇濆吇椤甸潰锛夌浉鍏冲彉閲�
+const filters = reactive({
+  deviceName: '',
+  maintenancePlanTime: '',
+  maintenanceActuallyTime: '',
+  maintenanceActuallyName: '',
+})
 
-  const dataList = ref([]);
-  const pagination = ref({
-    currentPage: 1,
-    pageSize: 10,
-    total: 0,
-  });
-  const multipleList = ref([]);
+const dataList = ref([])
+const pagination = ref({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+})
+const multipleList = ref([])
 
-  // 淇濆吇浠诲姟tab鐩稿叧鍙橀噺
-  const scheduledFilters = reactive({
-    taskName: "",
-    status: "",
-  });
+// 瀹氭椂浠诲姟绠$悊tab鐩稿叧鍙橀噺
+const scheduledFilters = reactive({
+  taskName: '',
+  isEnabled: undefined,
+})
 
-  const scheduledDataList = ref([]);
-  const scheduledPagination = reactive({
-    currentPage: 1,
-    pageSize: 10,
-    total: 0,
-  });
-  const scheduledMultipleList = ref([]);
+const scheduledDataList = ref([])
+const scheduledPagination = reactive({
+  currentPage: 1,
+  pageSize: 10,
+  total: 0,
+})
+const scheduledMultipleList = ref([])
 
-  // 淇濆吇浠诲姟琛ㄦ牸鍒楅厤缃�
-  const scheduledColumns = ref([
-    { prop: "taskName", label: "璁惧鍚嶇О" },
-    {
-      label: "瑙勬牸鍨嬪彿",
-      prop: "deviceModel",
-    },
-    {
-      label: "淇濆吇椤圭洰",
-      prop: "machineryCategory",
-      minWidth: 120,
-      formatData: cell => cell || "--",
-    },
-    {
-      prop: "frequencyType",
-      label: "棰戞",
-      minWidth: 150,
-      // PIMTable 浣跨敤鐨勬槸 formatData锛岃�屼笉鏄� Element-Plus 鐨� formatter
-      formatData: cell =>
-        ({
-          DAILY: "姣忔棩",
-          WEEKLY: "姣忓懆",
-          MONTHLY: "姣忔湀",
-          QUARTERLY: "瀛e害",
-        }[cell] || ""),
-    },
-    {
-      prop: "frequencyDetail",
-      label: "寮�濮嬫棩鏈熶笌鏃堕棿",
-      minWidth: 150,
-      // 鍚屾牱鏀圭敤 formatData锛孭IMTable 鍐呴儴浼氭妸鍗曞厓鏍煎�间紶杩涙潵
-      formatData: cell => {
-        if (typeof cell !== "string") return "";
-        let val = cell;
-        const replacements = {
-          MON: "鍛ㄤ竴",
-          TUE: "鍛ㄤ簩",
-          WED: "鍛ㄤ笁",
-          THU: "鍛ㄥ洓",
-          FRI: "鍛ㄤ簲",
-          SAT: "鍛ㄥ叚",
-          SUN: "鍛ㄦ棩",
-        };
-        // 浣跨敤姝e垯涓�娆℃�ф浛鎹㈡墍鏈夊尮閰嶉」
-        return val.replace(
-          /MON|TUE|WED|THU|FRI|SAT|SUN/g,
-          match => replacements[match]
-        );
-      },
-    },
-    { prop: "maintenancePerson", label: "淇濆吇浜�", minWidth: 100 },
-    { prop: "registrant", label: "鐧昏浜�", minWidth: 100 },
-    {
-      prop: "registrationDate",
-      label: "鐧昏鏃ユ湡",
-      minWidth: 100,
-      formatData: cell =>
-        cell ? dayjs(cell).format("YYYY-MM-DD HH:mm:ss") : "-",
-    },
-    {
-      fixed: "right",
-      label: "鎿嶄綔",
-      dataType: "slot",
-      slot: "operation",
-      align: "center",
-      width: "200px",
-    },
-  ]);
+// 瀹氭椂浠诲姟绠$悊琛ㄦ牸鍒楅厤缃�
+const scheduledColumns = ref([
+	{
+		label: "鎵�鍦ㄥ尯鍩�",
+		prop: "areaName",
+	},
+	{ prop: "taskName", label: "璁惧鍚嶇О"},
+	{
+		label: "瑙勬牸鍨嬪彿",
+		prop: "deviceModel",
+	},
+	{
+		prop: "frequencyType",
+		label: "棰戞",
+		minWidth: 150,
+		// PIMTable 浣跨敤鐨勬槸 formatData锛岃�屼笉鏄� Element-Plus 鐨� formatter
+		formatData: (cell) => ({
+			DAILY: "姣忔棩",
+			WEEKLY: "姣忓懆",
+			MONTHLY: "姣忔湀",
+			QUARTERLY: "瀛e害",
+			YEARLY: "姣忓勾",
+		}[cell] || "")
+	},
+	{
+		prop: "frequencyDetail",
+		label: "寮�濮嬫棩鏈熶笌鏃堕棿",
+		minWidth: 150,
+		// 鍚屾牱鏀圭敤 formatData锛孭IMTable 鍐呴儴浼氭妸鍗曞厓鏍煎�间紶杩涙潵
+		formatData: (cell) => {
+			if (typeof cell !== 'string') return '';
+			let val = cell;
+			const replacements = {
+				MON: '鍛ㄤ竴',
+				TUE: '鍛ㄤ簩',
+				WED: '鍛ㄤ笁',
+				THU: '鍛ㄥ洓',
+				FRI: '鍛ㄤ簲',
+				SAT: '鍛ㄥ叚',
+				SUN: '鍛ㄦ棩'
+			};
+			// 浣跨敤姝e垯涓�娆℃�ф浛鎹㈡墍鏈夊尮閰嶉」
+			return val.replace(/MON|TUE|WED|THU|FRI|SAT|SUN/g, match => replacements[match]);
+		}
+	},
+	{ prop: "registrant", label: "鐧昏浜�", minWidth: 100 },
+	{ prop: "registrationDate", label: "鐧昏鏃ユ湡", minWidth: 100 },
+	{
+		label: "鏄惁鍚敤",
+		prop: "isEnabled",
+		dataType: "slot",
+		slot: "isEnabledRef",
+		align: "center",
+		width: "120px",
+	},
+	{
+		fixed: "right",
+		label: "鎿嶄綔",
+		dataType: "slot",
+		slot: "operation",
+		align: "center",
+		width: "200px",
+	},
+])
 
-  // 淇濆吇璁板綍琛ㄦ牸鍒楅厤缃紙鍘熻澶囦繚鍏昏〃鏍煎垪锛�
-  const columns = ref([
-    {
-      label: "璁惧鍚嶇О",
-      align: "center",
-      prop: "deviceName",
-    },
-    {
-      label: "瑙勬牸鍨嬪彿",
-      align: "center",
-      prop: "deviceModel",
-    },
-    {
-      label: "璁″垝淇濆吇鏃ユ湡",
-      align: "center",
-      prop: "maintenancePlanTime",
-      formatData: cell => {
-        return cell == null ? "-" : dayjs(cell).format("YYYY-MM-DD");
-      },
-    },
-    {
-      label: "褰曞叆浜�",
-      align: "center",
-      prop: "createUserName",
-    },
-    {
-      label: "淇濆吇椤圭洰",
-      align: "center",
-      prop: "machineryCategory",
-      formatData: cell => cell || "--",
-    },
-    // {
-    //   label: "褰曞叆鏃ユ湡",
-    //   align: "center",
-    //   prop: "createTime",
-    //   formatData: (cell) => dayjs(cell).format("YYYY-MM-DD HH:mm:ss"),
-    //   width: 200,
-    // },
-    {
-      label: "瀹為檯淇濆吇浜�",
-      align: "center",
-      prop: "maintenanceActuallyName",
-    },
-    {
-      label: "瀹為檯淇濆吇鏃ユ湡",
-      align: "center",
-      prop: "maintenanceActuallyTime",
-      formatData: cell =>
-        cell ? dayjs(cell).format("YYYY-MM-DD HH:mm:ss") : "-",
-    },
-    {
-      label: "淇濆吇缁撴灉",
-      align: "center",
-      prop: "maintenanceResult",
-      dataType: "slot",
-      slot: "maintenanceResultRef",
-    },
-    {
-      label: "鐘舵��",
-      align: "center",
-      prop: "status",
-      dataType: "slot",
-      slot: "statusRef",
-    },
-    {
-      fixed: "right",
-      label: "鎿嶄綔",
-      dataType: "slot",
-      slot: "operation",
-      align: "center",
-      width: "350px",
-    },
-  ]);
+// 浠诲姟璁板綍琛ㄦ牸鍒楅厤缃紙鍘熻澶囦繚鍏昏〃鏍煎垪锛�
+const columns = ref([
+	{
+		label: "鎵�鍦ㄥ尯鍩�",
+		prop: "areaName",
+	},
+	{
+		label: "璁惧鍚嶇О",
+		align: "center",
+		prop: "deviceName",
+	},
+	{
+		label: "瑙勬牸鍨嬪彿",
+		align: "center",
+		prop: "deviceModel",
+	},
+	{
+		label: "璁″垝淇濆吇鏃ユ湡",
+		align: "center",
+		prop: "maintenancePlanTime",
+		formatData: (cell) => dayjs(cell).format("YYYY-MM-DD"),
+	},
+	{
+		label: "褰曞叆浜�",
+		align: "center",
+		prop: "createUserName",
+	},
+	// {
+	//   label: "褰曞叆鏃ユ湡",
+	//   align: "center",
+	//   prop: "createTime",
+	//   formatData: (cell) => dayjs(cell).format("YYYY-MM-DD HH:mm:ss"),
+	//   width: 200,
+	// },
+	{
+		label: "瀹為檯淇濆吇浜�",
+		align: "center",
+		prop: "maintenanceActuallyName",
+	},
+	{
+		label: "瀹為檯淇濆吇鏃ユ湡",
+		align: "center",
+		prop: "maintenanceActuallyTime",
+		formatData: (cell) =>
+			cell ? dayjs(cell).format("YYYY-MM-DD HH:mm:ss") : "-",
+	},
+	{
+		label: "淇濆吇缁撴灉",
+		align: "center",
+		prop: "maintenanceResult",
+		dataType: "slot",
+		slot: "maintenanceResultRef",
+	},
+	{
+		label: "鐘舵��",
+		align: "center",
+		prop: "status",
+		dataType: "slot",
+		slot: "statusRef",
+	},
+	{
+		fixed: "right",
+		label: "鎿嶄綔",
+		dataType: "slot",
+		slot: "operation",
+		align: "center",
+		width: "350px",
+	},
+])
 
-  // Tab鍒囨崲澶勭悊
-  const handleTabChange = tabName => {
-    if (tabName === "record") {
-      getTableData();
-    } else if (tabName === "scheduled") {
-      getScheduledTableData();
+// Tab鍒囨崲澶勭悊
+const handleTabChange = (tabName) => {
+  if (tabName === 'record') {
+    getTableData()
+  } else if (tabName === 'scheduled') {
+    getScheduledTableData()
+  }
+}
+
+// 瀹氭椂浠诲姟绠$悊鐩稿叧鏂规硶
+const getScheduledTableData = async () => {
+  try {
+    const params = {
+      current: scheduledPagination.currentPage,
+      size: scheduledPagination.pageSize,
+      taskName: scheduledFilters.taskName || undefined,
+      isEnabled: scheduledFilters.isEnabled,
     }
-  };
-
-  // 淇濆吇浠诲姟鐩稿叧鏂规硶
-  const getScheduledTableData = async () => {
-    try {
-      const params = {
-        current: scheduledPagination.currentPage,
-        size: scheduledPagination.pageSize,
-        taskName: scheduledFilters.taskName || undefined,
-        status: scheduledFilters.status || undefined,
-      };
-      const { code, data } = await deviceMaintenanceTaskList(params);
-      if (code === 200) {
-        scheduledDataList.value = data?.records || [];
-        scheduledPagination.total = data?.total || 0;
-      }
-    } catch (error) {
-      ElMessage.error("鑾峰彇瀹氭椂浠诲姟鍒楄〃澶辫触");
+    const { code, data } = await deviceMaintenanceTaskList(params)
+    if (code === 200) {
+      const records = data?.records || []
+      scheduledDataList.value = records.map((item) => ({
+        ...item,
+        isEnabled: Number(item.isEnabled ?? item.status ?? 1),
+        enableSwitchLoading: false,
+      }))
+      scheduledPagination.total = data?.total || 0
     }
-  };
+  } catch (error) {
+    ElMessage.error('鑾峰彇瀹氭椂浠诲姟鍒楄〃澶辫触')
+  }
+}
 
-  const resetScheduledFilters = () => {
-    scheduledFilters.taskName = "";
-    scheduledFilters.status = "";
-    getScheduledTableData();
-  };
+const resetScheduledFilters = () => {
+  scheduledFilters.taskName = ''
+  scheduledFilters.isEnabled = undefined
+  getScheduledTableData()
+}
 
-  const handleScheduledSelectionChange = selection => {
-    scheduledMultipleList.value = selection;
-  };
+const handleScheduledSelectionChange = (selection) => {
+  scheduledMultipleList.value = selection
+}
 
-  const changeScheduledPage = page => {
-    scheduledPagination.currentPage = page.page;
-    scheduledPagination.pageSize = page.limit;
-    getScheduledTableData();
-  };
+const changeScheduledPage = (page) => {
+  scheduledPagination.currentPage = page.page
+  scheduledPagination.pageSize = page.limit
+  getScheduledTableData()
+}
 
-  const addScheduledTask = () => {
-    nextTick(() => {
-      formDiaRef.value?.openDialog("add");
-    });
-  };
+const addScheduledTask = () => {
+  nextTick(() => {
+		formDiaRef.value?.openDialog('add');
+	});
+}
 
-  const editScheduledTask = row => {
-    if (row) {
-      nextTick(() => {
-        formDiaRef.value?.openDialog("edit", row);
-      });
-    }
-  };
+const editScheduledTask = (row) => {
+  if (row) {
+		nextTick(() => {
+			formDiaRef.value?.openDialog('edit', row);
+		});
+  }
+}
 
-  const delScheduledTaskByIds = async ids => {
-    try {
-      await ElMessageBox.confirm("纭畾鍒犻櫎閫変腑鐨勫畾鏃朵换鍔″悧锛�", "鎻愮ず", {
-        type: "warning",
-      });
-      const payload = Array.isArray(ids) ? ids : [ids];
-      await deviceMaintenanceTaskDel(payload);
-      ElMessage.success("鍒犻櫎瀹氭椂浠诲姟鎴愬姛");
-      getScheduledTableData();
-    } catch (error) {
-      // 鐢ㄦ埛鍙栨秷鍒犻櫎
-    }
-  };
-
-  const handleScheduledOut = () => {
-    ElMessage.info("瀵煎嚭瀹氭椂浠诲姟鍔熻兘寰呭疄鐜�");
-  };
-
-  // 淇濆吇璁板綍鐩稿叧鏂规硶锛堝師璁惧淇濆吇椤甸潰鏂规硶锛�
-  const getTableData = async () => {
-    try {
-      const params = {
-        current: pagination.value.currentPage,
-        size: pagination.value.pageSize,
-        deviceName: filters.deviceName || undefined,
-        maintenancePlanTime: filters.maintenancePlanTime
-          ? dayjs(filters.maintenancePlanTime).format("YYYY-MM-DD")
-          : undefined,
-        maintenanceActuallyTime: filters.maintenanceActuallyTime
-          ? dayjs(filters.maintenanceActuallyTime).format("YYYY-MM-DD")
-          : undefined,
-        maintenanceActuallyName: filters.maintenanceActuallyName || undefined,
-      };
-
-      const { code, data } = await getUpkeepPage(params);
-      if (code === 200) {
-        dataList.value = data.records;
-        pagination.value.total = data.total;
-      }
-    } catch (error) {
-      console.log(error);
-    }
-  };
-
-  const resetFilters = () => {
-    filters.deviceName = "";
-    filters.maintenancePlanTime = "";
-    filters.maintenanceActuallyTime = "";
-    filters.maintenanceActuallyName = "";
-    getTableData();
-  };
-
-  const handleSelectionChange = selection => {
-    multipleList.value = selection;
-  };
-
-  // 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
-  const hasFinishedStatus = computed(() => {
-    return multipleList.value.some(item => item.status === 1);
-  });
-
-  const changePage = page => {
-    pagination.value.currentPage = page.page;
-    pagination.value.pageSize = page.limit;
-    getTableData();
-  };
-
-  const addMaintain = row => {
-    maintainModalRef.value.open(row.id, row);
-  };
-
-  const addPlan = () => {
-    planModalRef.value.openModal();
-  };
-
-  const editPlan = id => {
-    planModalRef.value.openEdit(id);
-  };
-
-  const delRepairByIds = async ids => {
-    // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
-    const hasFinished = multipleList.value.some(item => item.status === 1);
-    if (hasFinished) {
-      ElMessage.warning("涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�");
-      return;
-    }
-
-    try {
-      await ElMessageBox.confirm("纭鍒犻櫎淇濆吇鏁版嵁, 姝ゆ搷浣滀笉鍙��?", "璀﹀憡", {
-        confirmButtonText: "纭畾",
-        cancelButtonText: "鍙栨秷",
-        type: "warning",
-      });
-
-      const { code } = await delUpkeep(ids);
-      if (code === 200) {
-        ElMessage.success("鍒犻櫎鎴愬姛");
-        getTableData();
-      }
-    } catch (error) {
-      // 鐢ㄦ埛鍙栨秷鍒犻櫎
-    }
-  };
-
-  const handleOut = () => {
-    ElMessageBox.confirm("閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�", "瀵煎嚭", {
-      confirmButtonText: "纭",
-      cancelButtonText: "鍙栨秷",
-      type: "warning",
+const delScheduledTaskByIds = async (ids) => {
+  try {
+    await ElMessageBox.confirm('纭畾鍒犻櫎閫変腑鐨勫畾鏃朵换鍔″悧锛�', '鎻愮ず', {
+      type: 'warning',
     })
-      .then(() => {
-        proxy.download("/device/maintenance/export", {}, "璁惧淇濆吇.xlsx");
-      })
-      .catch(() => {
-        ElMessage.info("宸插彇娑�");
-      });
-  };
+    const payload = Array.isArray(ids) ? ids : [ids]
+    await deviceMaintenanceTaskDel(payload)
+    ElMessage.success('鍒犻櫎瀹氭椂浠诲姟鎴愬姛')
+    getScheduledTableData()
+  } catch (error) {
+    // 鐢ㄦ埛鍙栨秷鍒犻櫎
+  }
+}
 
-  const handleDateChange = (date, type) => {
-    if (type === 1) {
-      filters.maintenanceActuallyTime = date
-        ? dayjs(date).format("YYYY-MM-DD")
-        : "";
-    } else {
-      filters.maintenancePlanTime = date ? dayjs(date).format("YYYY-MM-DD") : "";
+const handleScheduledEnableBeforeChange = async (row) => {
+  if (row.enableSwitchLoading) {
+    return false
+  }
+  const nextValue = Number(row.isEnabled) === 1 ? 0 : 1
+  row.enableSwitchLoading = true
+  try {
+    const res = await deviceMaintenanceTaskChangeEnable({
+      id: row.id,
+      isEnabled: nextValue,
+    })
+    if (res?.code !== 200) {
+      throw new Error(res?.msg || '鏇存柊澶辫触')
     }
-    getTableData();
-  };
+    ElMessage.success('鍚敤鐘舵�佸凡鏇存柊')
+    return true
+  } catch (error) {
+    ElMessage.error(error?.message || '鍚敤鐘舵�佹洿鏂板け璐�')
+    return false
+  } finally {
+    row.enableSwitchLoading = false
+  }
+}
 
-  // 鎵撳紑闄勪欢寮圭獥
-  const openFileDialog = async row => {
-    currentMaintenanceTaskId.value = row.id;
-    fileDialogVisible.value = true;
-  };
+const handleScheduledOut = () => {
+  ElMessage.info('瀵煎嚭瀹氭椂浠诲姟鍔熻兘寰呭疄鐜�')
+}
 
-  onMounted(() => {
-    // 鏍规嵁榛樿婵�娲荤殑 Tab 璋冪敤瀵瑰簲鐨勬煡璇㈡帴鍙�
-    if (activeTab.value === "scheduled") {
-      getScheduledTableData();
-    } else {
-      getTableData();
+// 浠诲姟璁板綍鐩稿叧鏂规硶锛堝師璁惧淇濆吇椤甸潰鏂规硶锛�
+const getTableData = async () => {
+  try {
+    const params = {
+      current: pagination.value.currentPage,
+      size: pagination.value.pageSize,
+      deviceName: filters.deviceName || undefined,
+      maintenancePlanTime: filters.maintenancePlanTime ? dayjs(filters.maintenancePlanTime).format('YYYY-MM-DD') : undefined,
+      maintenanceActuallyTime: filters.maintenanceActuallyTime ? dayjs(filters.maintenanceActuallyTime).format('YYYY-MM-DD') : undefined,
+      maintenanceActuallyName: filters.maintenanceActuallyName || undefined,
     }
-  });
+
+    const { code, data } = await getUpkeepPage(params)
+    if (code === 200) {
+      dataList.value = data.records
+      pagination.value.total = data.total
+    }
+  } catch (error) {
+    console.log(error);
+    
+  }
+}
+
+const resetFilters = () => {
+  filters.deviceName = ''
+  filters.maintenancePlanTime = ''
+  filters.maintenanceActuallyTime = ''
+  filters.maintenanceActuallyName = ''
+  getTableData()
+}
+
+const handleSelectionChange = (selection) => {
+  multipleList.value = selection
+}
+
+// 妫�鏌ラ�変腑鐨勮褰曚腑鏄惁鏈夊畬缁撶姸鎬佺殑
+const hasFinishedStatus = computed(() => {
+  return multipleList.value.some(item => item.status === 1)
+})
+
+const changePage = (page) => {
+  pagination.value.currentPage = page.page
+  pagination.value.pageSize = page.limit
+  getTableData()
+}
+
+const addMaintain = (row) => {
+  maintainModalRef.value.open(row.id, row)
+}
+
+const addPlan = () => {
+  planModalRef.value.openModal()
+}
+
+const editPlan = (id) => {
+  planModalRef.value.openEdit(id)
+}
+
+const delRepairByIds = async (ids) => {
+  // 妫�鏌ユ槸鍚︽湁瀹岀粨鐘舵�佺殑璁板綍
+  const hasFinished = multipleList.value.some(item => item.status === 1)
+  if (hasFinished) {
+    ElMessage.warning('涓嶈兘鍒犻櫎鐘舵�佷负瀹岀粨鐨勮褰�')
+    return
+  }
+  
+  try {
+    await ElMessageBox.confirm('纭鍒犻櫎淇濆吇鏁版嵁, 姝ゆ搷浣滀笉鍙��?', '璀﹀憡', {
+      confirmButtonText: '纭畾',
+      cancelButtonText: '鍙栨秷',
+      type: 'warning',
+    })
+    
+    const { code } = await delUpkeep(ids)
+    if (code === 200) {
+      ElMessage.success('鍒犻櫎鎴愬姛')
+      getTableData()
+    }
+  } catch (error) {
+    // 鐢ㄦ埛鍙栨秷鍒犻櫎
+  }
+}
+
+const handleOut = () => {
+  ElMessageBox.confirm('閫変腑鐨勫唴瀹瑰皢琚鍑猴紝鏄惁纭瀵煎嚭锛�', '瀵煎嚭', {
+    confirmButtonText: '纭',
+    cancelButtonText: '鍙栨秷',
+    type: 'warning',
+  })
+    .then(() => {
+      proxy.download('/device/maintenance/export', {}, '璁惧淇濆吇.xlsx')
+    })
+    .catch(() => {
+      ElMessage.info('宸插彇娑�')
+    })
+}
+
+const handleDateChange = (date, type) => {
+  if (type === 1) {
+    filters.maintenanceActuallyTime = date ? dayjs(date).format('YYYY-MM-DD') : ''
+  } else {
+    filters.maintenancePlanTime = date ? dayjs(date).format('YYYY-MM-DD') : ''
+  }
+  getTableData()
+}
+
+// 闄勪欢鐩稿叧鏂规硶
+// 鏌ヨ闄勪欢鍒楄〃
+const fetchMaintenanceTaskFiles = async (deviceMaintenanceId) => {
+  try {
+    const params = {
+      current: 1,
+      size: 100,
+      deviceMaintenanceId,
+      rulesRegulationsManagementId:deviceMaintenanceId
+    }
+    const res = await listMaintenanceTaskFiles(params)
+    const records = res?.data?.records || []
+    const mapped = records.map(item => ({
+      id: item.id,
+      name: item.fileName || item.name,
+      url: item.fileUrl || item.url,
+      raw: item,
+    }))
+    fileListDialogRef.value?.setList(mapped)
+  } catch (error) {
+    ElMessage.error('鑾峰彇闄勪欢鍒楄〃澶辫触')
+  }
+}
+
+// 鎵撳紑闄勪欢寮圭獥
+const openFileDialog = async (row) => {
+  currentMaintenanceTaskId.value = row.id
+  fileDialogVisible.value = true
+  await fetchMaintenanceTaskFiles(row.id)
+}
+
+// 鍒锋柊闄勪欢鍒楄〃
+const refreshFileList = async () => {
+  if (!currentMaintenanceTaskId.value) return
+  await fetchMaintenanceTaskFiles(currentMaintenanceTaskId.value)
+}
+
+// 涓婁紶闄勪欢
+const handleAttachmentUpload = async (filePayload) => {
+  if (!currentMaintenanceTaskId.value) return
+  try {
+    const payload = {
+      name: filePayload?.fileName || filePayload?.name,
+      url: filePayload?.fileUrl || filePayload?.url,
+      deviceMaintenanceId: currentMaintenanceTaskId.value,
+    }
+    await addMaintenanceTaskFile(payload)
+    ElMessage.success('鏂囦欢涓婁紶鎴愬姛')
+    await refreshFileList()
+  } catch (error) {
+    ElMessage.error('鏂囦欢涓婁紶澶辫触')
+  }
+}
+
+// 鍒犻櫎闄勪欢
+const handleAttachmentDelete = async (row) => {
+  if (!row?.id) return false
+  try {
+    await ElMessageBox.confirm('纭鍒犻櫎璇ラ檮浠讹紵', '鎻愮ず', { type: 'warning' })
+  } catch {
+    return false
+  }
+  try {
+    await delMaintenanceTaskFile(row.id)
+    ElMessage.success('鍒犻櫎鎴愬姛')
+    await refreshFileList()
+    return true
+  } catch (error) {
+    ElMessage.error('鍒犻櫎澶辫触')
+    return false
+  }
+}
+
+onMounted(() => {
+  // 鏍规嵁榛樿婵�娲荤殑 Tab 璋冪敤瀵瑰簲鐨勬煡璇㈡帴鍙�
+  if (activeTab.value === 'scheduled') {
+    getScheduledTableData()
+  } else {
+    getTableData()
+  }
+})
 </script>
 
 <style lang="scss" scoped>
-  .table_list {
-    margin-top: unset;
-  }
-  .actions {
-    display: flex;
-    justify-content: space-between;
-    margin-bottom: 10px;
-  }
+.table_list {
+  margin-top: unset;
+}
+.actions {
+  display: flex;
+  justify-content: space-between;
+  margin-bottom: 10px;
+}
 </style>
 
 
diff --git a/vite.config.js b/vite.config.js
index fcc019d..b0f0f70 100644
--- a/vite.config.js
+++ b/vite.config.js
@@ -8,7 +8,7 @@
   const { VITE_APP_ENV } = env;
   const baseUrl =
       env.VITE_APP_ENV === "development"
-          ? "http://1.15.17.182:9048"
+          ? "http://192.168.0.226:7005"
           : env.VITE_BASE_API;
   const javaUrl =
       env.VITE_APP_ENV === "development"

--
Gitblit v1.9.3