From 145dbc2a4f5bafcb432fb35d7bc91101aa3318d8 Mon Sep 17 00:00:00 2001
From: doum <doum>
Date: 星期一, 13 十月 2025 10:15:44 +0800
Subject: [PATCH] Merge remote-tracking branch 'origin/wuhuyancao' into wuhuyancao

---
 server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetLogCloudController.java          |   16 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/OpenGridDriverDTO.java             |   25 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkKeys.java                      |   20 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/AdminCabinetVO.java                 |   27 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/HiddenDangerServiceImpl.java  |   18 
 admin/package-lock.json                                                                                    |  160 +
 admin/src/views/business/jkKeys.vue                                                                        |  120 
 admin/src/api/business/jkCabinetGrid.js                                                                    |   10 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/OptGridDTO.java                    |   24 
 admin/src/views/business/jkCabinetLog.vue                                                                  |  171 +-
 admin/.env.development                                                                                     |    2 
 admin/src/components/business/BorrowingAndReturningRecords.vue                                             |  174 ++
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/WarningServiceImpl.java       |  146 +
 server/visits/admin_timer/src/main/java/com/doumee/api/WeatherTimerController.java                         |   42 
 server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetCloudController.java             |   63 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java        |   20 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/CloseGridDTO.java                  |   31 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCabinetGridMapper.java               |    4 
 server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java                             |    6 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinetLog.java                |   55 
 admin/src/components/business/alcoholTest.vue                                                              |  112 +
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/CarUseBook.java                  |    6 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkIccardServiceImpl.java      |  133 +
 admin/src/views/business/jkIccard.vue                                                                      |  111 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCabinetLogMapper.java                |    3 
 server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetGridCloudController.java         |   39 
 admin/src/components/business/OperaJkVersionWindow.vue                                                     |  153 +
 admin/src/api/business/jkKeys.js                                                                           |    7 
 server/visits/dmvisit_service/src/main/java/com/doumee/core/dingTalk/DingTalk.java                         |  181 +-
 server/system_service/src/main/java/com/doumee/core/utils/Constants.java                                   |   10 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkVersion.java                   |   23 
 admin/src/views/business/jkVersion.vue                                                                     |  100 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkVersionMapper.java                   |    3 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetLogServiceImpl.java  |   88 
 server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkKeysCloudController.java                |   25 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkKeysServiceImpl.java        |  151 +
 admin/src/components/business/OperaJkIccardWindow.vue                                                      |  106 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetConfigDataVO.java            |   30 
 server/system_service/src/main/java/com/doumee/dao/business/model/Member.java                              |    5 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkIccardMapper.java                    |    3 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/WarningService.java                |    2 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Visits.java                      |    5 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/ApproveServiceImpl.java       |  193 ++
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetGridServiceImpl.java |  467 +++++
 admin/src/views/business/jkCabinet.vue                                                                     |  203 -
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkKeysMapper.java                      |    3 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetDetailVO.java                |   53 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkIccard.java                    |    9 
 admin/src/api/business/jkCabinet.js                                                                        |   22 
 admin/src/components/business/cabinetDetails.vue                                                           |  199 ++
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinetGrid.java               |   40 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkIccardService.java               |    2 
 admin/src/api/business/jkVersion.js                                                                        |    2 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinet.java                   |   45 
 admin/src/components/business/OperaJkCabinetWindow.vue                                                     |  225 +
 admin/src/views/login.vue                                                                                  |    2 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetServiceImpl.java     |  438 ++++-
 admin/src/components/business/OperaJkKeysWindow.vue                                                        |   78 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetGridInfoVO.java              |   50 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCabinetGridService.java          |   46 
 admin/src/api/business/jkIccard.js                                                                         |    7 
 server/visits/admin_timer/src/main/java/com/doumee/api/DingTalkTokenTimerController.java                   |   56 
 server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/GetDriverGridDTO.java              |   24 
 server/system_service/src/main/java/com/doumee/core/utils/WeatherUtil.java                                 |   29 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkVersionServiceImpl.java     |  137 +
 server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkIccardCloudController.java              |   27 
 server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCabinetService.java              |   26 
 server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkVersionCloudController.java             |   16 
 68 files changed, 3,567 insertions(+), 1,262 deletions(-)

diff --git a/admin/.env.development b/admin/.env.development
index fd98857..3661935 100644
--- a/admin/.env.development
+++ b/admin/.env.development
@@ -2,7 +2,7 @@
 NODE_ENV = 'development'
 
 # VUE_APP_API_URL  = 'https://atwl.ahzyssl.com/zhyq_interface'
-VUE_APP_API_URL  = 'http://192.168.1.46:10010'
+VUE_APP_API_URL  = 'http://192.168.1.54:10010'
 # VUE_APP_API_URL  = 'https://atwl.ahzyssl.com/zhyq_interface'
 # VUE_APP_API_URL  = 'http://10.50.250.253:8088/gateway_interface'
 
diff --git a/admin/package-lock.json b/admin/package-lock.json
index f24166f..1e1e87e 100644
--- a/admin/package-lock.json
+++ b/admin/package-lock.json
@@ -1886,63 +1886,6 @@
           "integrity": "sha1-/q7SVZc9LndVW4PbwIhRpsY1IPo=",
           "dev": true
         },
-        "ansi-styles": {
-          "version": "4.3.0",
-          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
-          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "color-convert": "^2.0.1"
-          }
-        },
-        "chalk": {
-          "version": "4.1.2",
-          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
-          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "ansi-styles": "^4.1.0",
-            "supports-color": "^7.1.0"
-          }
-        },
-        "color-convert": {
-          "version": "2.0.1",
-          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
-          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "color-name": "~1.1.4"
-          }
-        },
-        "color-name": {
-          "version": "1.1.4",
-          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
-          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-          "dev": true,
-          "optional": true
-        },
-        "has-flag": {
-          "version": "4.0.0",
-          "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
-          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-          "dev": true,
-          "optional": true
-        },
-        "loader-utils": {
-          "version": "2.0.4",
-          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
-          "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "big.js": "^5.2.2",
-            "emojis-list": "^3.0.0",
-            "json5": "^2.1.2"
-          }
-        },
         "ssri": {
           "version": "8.0.1",
           "resolved": "https://registry.npm.taobao.org/ssri/download/ssri-8.0.1.tgz?cache=0&sync_timestamp=1617826515595&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fssri%2Fdownload%2Fssri-8.0.1.tgz",
@@ -1950,28 +1893,6 @@
           "dev": true,
           "requires": {
             "minipass": "^3.1.1"
-          }
-        },
-        "supports-color": {
-          "version": "7.2.0",
-          "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
-          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "has-flag": "^4.0.0"
-          }
-        },
-        "vue-loader-v16": {
-          "version": "npm:vue-loader@16.8.3",
-          "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
-          "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
-          "dev": true,
-          "optional": true,
-          "requires": {
-            "chalk": "^4.1.0",
-            "hash-sum": "^2.0.0",
-            "loader-utils": "^2.0.0"
           }
         }
       }
@@ -14207,6 +14128,87 @@
         }
       }
     },
+    "vue-loader-v16": {
+      "version": "npm:vue-loader@16.8.3",
+      "resolved": "https://registry.npmmirror.com/vue-loader/-/vue-loader-16.8.3.tgz",
+      "integrity": "sha512-7vKN45IxsKxe5GcVCbc2qFU5aWzyiLrYJyUuMz4BQLKctCj/fmCa0w6fGiiQ2cLFetNcek1ppGJQDCup0c1hpA==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "chalk": "^4.1.0",
+        "hash-sum": "^2.0.0",
+        "loader-utils": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "4.3.0",
+          "resolved": "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-4.3.0.tgz",
+          "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-convert": "^2.0.1"
+          }
+        },
+        "chalk": {
+          "version": "4.1.2",
+          "resolved": "https://registry.npmmirror.com/chalk/-/chalk-4.1.2.tgz",
+          "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ansi-styles": "^4.1.0",
+            "supports-color": "^7.1.0"
+          }
+        },
+        "color-convert": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmmirror.com/color-convert/-/color-convert-2.0.1.tgz",
+          "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "color-name": "~1.1.4"
+          }
+        },
+        "color-name": {
+          "version": "1.1.4",
+          "resolved": "https://registry.npmmirror.com/color-name/-/color-name-1.1.4.tgz",
+          "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+          "dev": true,
+          "optional": true
+        },
+        "has-flag": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-4.0.0.tgz",
+          "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+          "dev": true,
+          "optional": true
+        },
+        "loader-utils": {
+          "version": "2.0.4",
+          "resolved": "https://registry.npmmirror.com/loader-utils/-/loader-utils-2.0.4.tgz",
+          "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "big.js": "^5.2.2",
+            "emojis-list": "^3.0.0",
+            "json5": "^2.1.2"
+          }
+        },
+        "supports-color": {
+          "version": "7.2.0",
+          "resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-7.2.0.tgz",
+          "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "has-flag": "^4.0.0"
+          }
+        }
+      }
+    },
     "vue-property-decorator": {
       "version": "8.5.1",
       "resolved": "https://registry.npmjs.org/vue-property-decorator/-/vue-property-decorator-8.5.1.tgz",
diff --git a/admin/src/api/business/jkCabinet.js b/admin/src/api/business/jkCabinet.js
index c413215..2370a04 100644
--- a/admin/src/api/business/jkCabinet.js
+++ b/admin/src/api/business/jkCabinet.js
@@ -20,14 +20,34 @@
   return request.post('/visitsAdmin/cloudService/business/jkCabinet/create', data)
 }
 
+// 鍒楄〃
+export function list (data) {
+  return request.post('/visitsAdmin/cloudService/business/jkCabinet/list', data)
+}
+
 // 淇敼
 export function updateById (data) {
   return request.post('/visitsAdmin/cloudService/business/jkCabinet/updateById', data)
 }
 
+// 鏍规嵁ID淇敼鐘舵��
+export function updateStatusById (data) {
+  return request.post('/visitsAdmin/cloudService/business/jkCabinet/updateStatusById', data)
+}
+
+// 鏇存柊閰掔簿妫�娴嬮厤缃�
+export function updateCabinetConfig (data) {
+  return request.post('/visitsAdmin/cloudService/business/jkCabinet/updateCabinetConfig', data)
+}
+
 // 鍒犻櫎
 export function deleteById (id) {
-  return request.get(`/business/jkCabinet/delete/${id}`)
+  return request.get(`/visitsAdmin/cloudService/business/jkCabinet/delete/${id}`)
+}
+
+// 鑾峰彇閰掔簿妫�娴嬮厤缃�
+export function getCabinetConfig () {
+  return request.get(`/visitsAdmin/cloudService/business/jkCabinet/getCabinetConfig`)
 }
 
 // 鎵归噺鍒犻櫎
diff --git a/admin/src/api/business/jkCabinetGrid.js b/admin/src/api/business/jkCabinetGrid.js
index b97ee1f..15c20d7 100644
--- a/admin/src/api/business/jkCabinetGrid.js
+++ b/admin/src/api/business/jkCabinetGrid.js
@@ -25,6 +25,16 @@
   return request.post('/visitsAdmin/cloudService/business/jkCabinetGrid/updateById', data)
 }
 
+// 鏍规嵁ID淇敼鐘舵��
+export function updateStatusById (data) {
+  return request.post('/visitsAdmin/cloudService/business/jkCabinetGrid/updateStatusById', data)
+}
+
+// 瑙g粦閽ュ寵
+export function unBindKeys (data) {
+  return request.post('/visitsAdmin/cloudService/business/jkCabinetGrid/unBindKeys', data)
+}
+
 // 鍒犻櫎
 export function deleteById (id) {
   return request.get(`/business/jkCabinetGrid/delete/${id}`)
diff --git a/admin/src/api/business/jkIccard.js b/admin/src/api/business/jkIccard.js
index de6ea14..4b4e274 100644
--- a/admin/src/api/business/jkIccard.js
+++ b/admin/src/api/business/jkIccard.js
@@ -25,9 +25,14 @@
   return request.post('/visitsAdmin/cloudService/business/jkIccard/updateById', data)
 }
 
+// 鏍规嵁ID淇敼鐘舵��
+export function updateStatusById (data) {
+  return request.post('/visitsAdmin/cloudService/business/jkIccard/updateStatusById', data)
+}
+
 // 鍒犻櫎
 export function deleteById (id) {
-  return request.get(`/business/jkIccard/delete/${id}`)
+  return request.get(`/visitsAdmin/cloudService/business/jkIccard/delete/${id}`)
 }
 
 // 鎵归噺鍒犻櫎
diff --git a/admin/src/api/business/jkKeys.js b/admin/src/api/business/jkKeys.js
index a54dbfb..b85f391 100644
--- a/admin/src/api/business/jkKeys.js
+++ b/admin/src/api/business/jkKeys.js
@@ -20,6 +20,11 @@
   return request.post('/visitsAdmin/cloudService/business/jkKeys/create', data)
 }
 
+// 鍒楄〃鏌ヨ
+export function list (data) {
+  return request.post('/visitsAdmin/cloudService/business/jkKeys/list', data)
+}
+
 // 淇敼
 export function updateById (data) {
   return request.post('/visitsAdmin/cloudService/business/jkKeys/updateById', data)
@@ -27,7 +32,7 @@
 
 // 鍒犻櫎
 export function deleteById (id) {
-  return request.get(`/business/jkKeys/delete/${id}`)
+  return request.get(`/visitsAdmin/cloudService/business/jkKeys/delete/${id}`)
 }
 
 // 鎵归噺鍒犻櫎
diff --git a/admin/src/api/business/jkVersion.js b/admin/src/api/business/jkVersion.js
index 9c2df74..5d7065f 100644
--- a/admin/src/api/business/jkVersion.js
+++ b/admin/src/api/business/jkVersion.js
@@ -27,7 +27,7 @@
 
 // 鍒犻櫎
 export function deleteById (id) {
-  return request.get(`/business/jkVersion/delete/${id}`)
+  return request.get(`/visitsAdmin/cloudService/business/jkVersion/delete/${id}`)
 }
 
 // 鎵归噺鍒犻櫎
diff --git a/admin/src/components/business/BorrowingAndReturningRecords.vue b/admin/src/components/business/BorrowingAndReturningRecords.vue
new file mode 100644
index 0000000..209c667
--- /dev/null
+++ b/admin/src/components/business/BorrowingAndReturningRecords.vue
@@ -0,0 +1,174 @@
+<template>
+    <GlobalWindow
+        :title="title"
+        width="100%"
+        :visible.sync="visible"
+        :withFooter="false"
+    >
+        <el-form ref="searchForm" :model="searchForm" label-width="100px" inline>
+            <el-form-item label="鎿嶄綔浜�" prop="memberName">
+                <el-input v-model="searchForm.memberName" placeholder="璇疯緭鍏ユ搷浣滀汉" @keypress.enter.native="getList"></el-input>
+            </el-form-item>
+            <el-form-item label="鏃堕棿" prop="date">
+                <el-date-picker
+                    v-model="date"
+                    type="daterange"
+                    @change="setDate"
+                    range-separator="鑷�"
+                    start-placeholder="寮�濮嬫棩鏈�"
+                    end-placeholder="缁撴潫鏃ユ湡"
+                    format="yyyy 骞� MM 鏈� dd 鏃�"
+                    value-format="yyyy-MM-dd">
+                </el-date-picker>
+            </el-form-item>
+            <el-form-item label="鐘舵��" prop="status">
+                <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨" @change="getList">
+                    <el-option label="鍏ㄩ儴" value=""></el-option>
+                    <el-option label="鎴愬姛" :value="0"></el-option>
+                    <el-option label="澶辫触" :value="1"></el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item>
+                <el-button type="primary" @click="getList">鎼滅储</el-button>
+            </el-form-item>
+            <el-form-item>
+                <el-button @click="reset">閲嶇疆</el-button>
+            </el-form-item>
+            <el-form-item>
+                <el-button @click="exports">瀵煎嚭</el-button>
+            </el-form-item>
+        </el-form>
+        <el-table
+            v-loading="loading"
+            :data="list"
+            stripe
+        >
+            <el-table-column prop="code" label="閽ュ寵缂栧彿" min-width="100px"></el-table-column>
+            <el-table-column prop="cabinetName" label="瀛樻斁浣嶇疆" min-width="100px"></el-table-column>
+            <el-table-column prop="gridName" label="鎵�灞為挜鍖欐煖" min-width="100px"></el-table-column>
+            <el-table-column prop="memberName" label="鎿嶄綔浜�" min-width="100px"></el-table-column>
+            <el-table-column label="鏃堕棿" min-width="100px">
+                <template slot-scope="{row}">
+                    {{row.startDate}}~{{row.endDate}}
+                </template>
+            </el-table-column>
+            <el-table-column label="鐘舵��" min-width="100px">
+                <template slot-scope="{row}">
+                    <el-link v-if="row.status === 0">鎴愬姛</el-link>
+                    <el-link type="danger" v-if="row.status === 1">澶辫触</el-link>
+                </template>
+            </el-table-column>
+        </el-table>
+        <div style="width: 100%; text-align: right; margin-top: 20px">
+            <el-pagination
+                @current-change="handleCurrentChange"
+                :current-page="page"
+                :page-size="10"
+                layout="total, prev, pager, next, jumper"
+                :total="total">
+            </el-pagination>
+        </div>
+    </GlobalWindow>
+</template>
+
+<script>
+  import BaseOpera from '@/components/base/BaseOpera'
+  import GlobalWindow from '@/components/common/GlobalWindow'
+  import { fetchList, exportExcel } from '@/api/business/jkCabinetLog'
+  export default {
+    name: 'BorrowingAndReturningRecords',
+    extends: BaseOpera,
+    components: { GlobalWindow },
+    data () {
+      return {
+        id: null,
+        info: null,
+        searchForm: {
+          memberName: '',
+          status: '',
+          roleType: '',
+          startDate: '',
+          editDate: ''
+        },
+        date: [],
+        list: [],
+        page: 1,
+        total: 0,
+        loading: false
+      }
+    },
+    methods: {
+      open (title, id) {
+        this.title = title
+        this.id = id
+        this.getList()
+        this.visible = true
+      },
+      setDate(e) {
+        if (e && e.length > 1) {
+          this.searchForm.startDate = e[0]
+          this.searchForm.editDate = e[1]
+        } else {
+          this.searchForm.startDate = ''
+          this.searchForm.editDate = ''
+        }
+      },
+      handleCurrentChange(e) {
+        this.page = e
+        this.getList()
+      },
+      reset() {
+        this.searchForm.memberName = ''
+        this.searchForm.status = ''
+        this.searchForm.roleType = ''
+        this.searchForm.startDate = ''
+        this.searchForm.editDate = ''
+        this.date = []
+        this.page = 1
+        this.getList()
+      },
+      getList() {
+        this.loading = true
+        fetchList({
+          capacity: 10,
+          page: this.page,
+          model: {
+            memberName: this.searchForm.memberName,
+            status: this.searchForm.status,
+            roleType: this.searchForm.roleType,
+            startDate: this.searchForm.startDate,
+            editDate: this.searchForm.editDate,
+          }
+        }).then(res => {
+          this.list = res.records
+          this.total = res.total
+        }).finally(() => {
+          this.loading = false
+        })
+      },
+      exports() {
+        this.$dialog.exportConfirm('纭瀵煎嚭鍚楋紵')
+          .then(() => {
+            exportExcel({
+              page: 1,
+              capacity: 1000000,
+              model: {
+                memberName: this.searchForm.memberName,
+                status: this.searchForm.status,
+                roleType: this.searchForm.roleType,
+                startDate: this.searchForm.startDate,
+                editDate: this.searchForm.editDate,
+              }
+            })
+              .then(response => {
+                this.download(response)
+              })
+              .catch(e => {
+                this.$tip.apiFailed(e)
+              })
+          })
+          .catch(() => {})
+      }
+    }
+  }
+</script>
diff --git a/admin/src/components/business/OperaJkCabinetWindow.vue b/admin/src/components/business/OperaJkCabinetWindow.vue
index ee63049..fe508bb 100644
--- a/admin/src/components/business/OperaJkCabinetWindow.vue
+++ b/admin/src/components/business/OperaJkCabinetWindow.vue
@@ -1,29 +1,13 @@
 <template>
   <GlobalWindow
+    width="50%"
     :title="title"
     :visible.sync="visible"
     :confirm-working="isWorking"
     @confirm="confirm"
   >
     <el-form :model="form" ref="form" :rules="rules">
-      <el-form-item label="鍒涘缓浜虹紪鐮�" prop="creator">
-        <el-input v-model="form.creator" placeholder="璇疯緭鍏ュ垱寤轰汉缂栫爜" v-trim/>
-      </el-form-item>
-      <el-form-item label="鍒涘缓鏃堕棿" prop="createDate">
-        <el-date-picker v-model="form.createDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ュ垱寤烘椂闂�"></el-date-picker>
-      </el-form-item>
-      <el-form-item label="鏇存柊浜虹紪鐮�" prop="editor">
-        <el-input v-model="form.editor" placeholder="璇疯緭鍏ユ洿鏂颁汉缂栫爜" v-trim/>
-      </el-form-item>
-      <el-form-item label="鏇存柊鏃堕棿" prop="editDate">
-        <el-date-picker v-model="form.editDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ユ洿鏂版椂闂�"></el-date-picker>
-      </el-form-item>
-      <el-form-item label="鏄惁鍒犻櫎0鍚� 1鏄�" prop="isdeleted">
-        <el-input v-model="form.isdeleted" placeholder="璇疯緭鍏ユ槸鍚﹀垹闄�0鍚� 1鏄�" v-trim/>
-      </el-form-item>
-      <el-form-item label="澶囨敞" prop="info">
-        <el-input v-model="form.info" placeholder="璇疯緭鍏ュ娉�" v-trim/>
-      </el-form-item>
+      <h3 style="margin: 0 0 20px 0;">璁惧淇℃伅</h3>
       <el-form-item label="璁惧缂栧彿" prop="code">
         <el-input v-model="form.code" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" v-trim/>
       </el-form-item>
@@ -39,53 +23,97 @@
       <el-form-item label="閫氳鍦板潃" prop="linkAddr">
         <el-input v-model="form.linkAddr" placeholder="璇疯緭鍏ラ�氳鍦板潃" v-trim/>
       </el-form-item>
-      <el-form-item label="鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭" prop="status">
-        <el-input v-model="form.status" placeholder="璇疯緭鍏ョ姸鎬� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭" v-trim/>
+      <el-form-item label="绔彛鍙�" prop="port">
+        <el-input v-model="form.port" placeholder="璇疯緭鍏ョ鍙e彿" v-trim/>
       </el-form-item>
-      <el-form-item label="绔彛" prop="port">
-        <el-input v-model="form.port" placeholder="璇疯緭鍏ョ鍙�" v-trim/>
+      <el-form-item label="璁惧绠$悊鍛�" prop="managerIdList">
+        <el-select v-model="form.managerIdList" filterable multiple placeholder="璇烽�夋嫨璁惧绠$悊鍛�">
+          <el-option
+            v-for="item in memberList"
+            :key="item.id"
+            :label="item.name+'-'+item.companyName"
+            :value="item.id">
+          </el-option>
+        </el-select>
       </el-form-item>
-      <el-form-item label="璁惧绠$悊鍛樼紪鐮侊紙鍏宠仈member)" prop="managerId">
-        <el-input v-model="form.managerId" placeholder="璇疯緭鍏ヨ澶囩鐞嗗憳缂栫爜锛堝叧鑱攎ember)" v-trim/>
+      <el-form-item label="浣跨敤鏃堕暱" prop="useTime">
+        <div style="width: 100%; display: flex; align-items: center;">
+          <el-input v-model="form.useTime" placeholder="璇疯緭鍏ュ崟娆℃嬁鍙栭挜鍖欏彲浣跨敤鏃堕暱" v-trim style="flex: 1;"/>
+          <span style="margin-left: 20px;">鍗曚綅锛氬垎閽�</span>
+        </div>
       </el-form-item>
-      <el-form-item label="浣跨敤鏃堕暱(绉�)" prop="useTime">
-        <el-input v-model="form.useTime" placeholder="璇疯緭鍏ヤ娇鐢ㄦ椂闀�(绉�)" v-trim/>
+      <el-form-item label="鍙岄噸楠岃瘉" prop="doubleAuth">
+        <div style="width: 100%; display: flex; align-items: center;">
+          <el-switch
+            v-model="form.doubleAuth"
+            active-color="#13ce66"
+            inactive-color="#ff4949"
+            :active-value="1"
+            :inactive-value="0">
+          </el-switch>
+          <span style="margin-left: 20px; color: #999999;">寮�鍚弻閲嶈璇佸悗锛岄挜鍖欓鍙栨椂鍏堟牎楠岄獙璇佷汉韬唤锛屽啀鏍¢獙鍙告満韬唤</span>
+        </div>
       </el-form-item>
-      <el-form-item label="鏄惁鍙岄噸楠岃瘉 0鍚� 1鏄�" prop="doubleAuth">
-        <el-input v-model="form.doubleAuth" placeholder="璇疯緭鍏ユ槸鍚﹀弻閲嶉獙璇� 0鍚� 1鏄�" v-trim/>
-      </el-form-item>
-      <el-form-item label="楠岃瘉浜虹紪鐮侊紙鍏宠仈member)" prop="authMemberId">
-        <el-input v-model="form.authMemberId" placeholder="璇疯緭鍏ラ獙璇佷汉缂栫爜锛堝叧鑱攎ember)" v-trim/>
-      </el-form-item>
-      <el-form-item label="鎺掓暟" prop="rowNum">
-        <el-input v-model="form.rowNum" placeholder="璇疯緭鍏ユ帓鏁�" v-trim/>
-      </el-form-item>
-      <el-form-item label="鍒楁暟" prop="columnNum">
-        <el-input v-model="form.columnNum" placeholder="璇疯緭鍏ュ垪鏁�" v-trim/>
-      </el-form-item>
-      <el-form-item label="鏈�鍚庨�氳鏃堕棿" prop="haertTime">
-        <el-date-picker v-model="form.haertTime" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ユ渶鍚庨�氳鏃堕棿"></el-date-picker>
+      <el-form-item label="楠岃瘉浜�" prop="authMemberIdList">
+        <el-select v-model="form.authMemberIdList" filterable multiple placeholder="璇烽�夋嫨楠岃瘉浜�">
+          <el-option
+            v-for="item in memberList"
+            :key="item.id"
+            :label="item.name+'-'+item.companyName"
+            :value="item.id">
+          </el-option>
+        </el-select>
       </el-form-item>
       <el-form-item label="鎵�鍦ㄤ綅缃�" prop="lacation">
         <el-input v-model="form.lacation" placeholder="璇疯緭鍏ユ墍鍦ㄤ綅缃�" v-trim/>
       </el-form-item>
-      <el-form-item label="缁忓害" prop="longitude">
-        <el-input v-model="form.longitude" placeholder="璇疯緭鍏ョ粡搴�" v-trim/>
+      <el-form-item label="缁忕含搴�" prop="longitude">
+        <div style="width: 100%; display: flex; align-items: center;">
+          <el-input v-model="form.longitude" placeholder="璇疯緭鍏ョ粡绾害" v-trim/>
+          <a style="margin-left: 20px; flex-shrink: 0;" href="https://lbs.amap.com/tools/picker" target="_blank">缁忕含搴﹀湪绾挎嬀鍙栧湴鍧�</a>
+        </div>
       </el-form-item>
-      <el-form-item label="缁村害" prop="latitude">
-        <el-input v-model="form.latitude" placeholder="璇疯緭鍏ョ淮搴�" v-trim/>
+      <el-form-item label="鐘舵��" prop="status">
+        <el-switch
+          v-model="form.status"
+          active-color="#13ce66"
+          inactive-color="#ff4949"
+          :active-value="0"
+          :inactive-value="1">
+        </el-switch>
       </el-form-item>
-      <el-form-item label="缂栫爜鏂瑰紡 0鑷姩缂栫爜 1鎵嬪姩缂栫爜" prop="noType">
-        <el-input v-model="form.noType" placeholder="璇疯緭鍏ョ紪鐮佹柟寮� 0鑷姩缂栫爜 1鎵嬪姩缂栫爜" v-trim/>
+      <h3 style="margin: 20px 0;">鏌滅粍淇℃伅</h3>
+      <el-form-item label="鎺掑垪" prop="rowNum">
+        <div style="width: 100%; display: flex; align-items: center;">
+          <el-input v-model="form.rowNum" :disabled="form.id" type="number" placeholder="璇疯緭鍏ユ帓鏁�" v-trim>
+            <template slot="append">鎺�</template>
+          </el-input>
+          <span style="margin: 0 20px;">x</span>
+          <el-input v-model="form.columnNum" :disabled="form.id" type="number" placeholder="璇疯緭鍏ュ垪鏁�" v-trim>
+            <template slot="append">鍒�</template>
+          </el-input>
+        </div>
       </el-form-item>
-      <el-form-item label="缂栫爜鍓嶇紑" prop="noPrefix">
-        <el-input v-model="form.noPrefix" placeholder="璇疯緭鍏ョ紪鐮佸墠缂�" v-trim/>
+      <el-form-item label="缂栫爜" prop="noType">
+        <el-radio-group v-model="form.noType" @change="changeNoType">
+          <el-radio :label="0">鑷姩缂栫爜</el-radio>
+          <el-radio :label="1">鎵嬪姩缂栫爜</el-radio>
+        </el-radio-group>
       </el-form-item>
-      <el-form-item label="缂栫爜浣嶆暟" prop="noLength">
-        <el-input v-model="form.noLength" placeholder="璇疯緭鍏ョ紪鐮佷綅鏁�" v-trim/>
+      <el-form-item label="鍓嶇紑" prop="noPrefix" v-if="form.noType === 1">
+        <div style="width: 100%; display: flex; align-items: center;">
+          <el-input style="flex: 1;" v-model="form.noPrefix" placeholder="璇疯緭鍏ユ暟瀛楁垨瀛楁瘝" v-trim/>
+          <span style="margin: 0 20px;">浣嶆暟</span>
+          <el-input style="flex: 1;" v-model="form.noLength" placeholder="璇疯緭鍏ユ暟瀛�" v-trim/>
+          <span style="margin: 0 20px;">璧峰缂栧彿</span>
+          <el-input style="flex: 1;" v-model="form.noIndex" placeholder="璇疯緭鍏ユ暟瀛�" v-trim/>
+        </div>
       </el-form-item>
-      <el-form-item label="璧峰缂栫爜" prop="noIndex">
-        <el-input v-model="form.noIndex" placeholder="璇疯緭鍏ヨ捣濮嬬紪鐮�" v-trim/>
+      <el-form-item label="鎺掑垪椤哄簭" prop="sortType" v-if="form.noType === 1">
+        <el-radio-group v-model="form.sortType" :disabled="form.id">
+          <el-radio :label="0">浠庡乏寰�鍙�</el-radio>
+          <el-radio :label="1">浠庝笂鍚戜笅</el-radio>
+        </el-radio-group>
       </el-form-item>
     </el-form>
   </GlobalWindow>
@@ -94,6 +122,7 @@
 <script>
 import BaseOpera from '@/components/base/BaseOpera'
 import GlobalWindow from '@/components/common/GlobalWindow'
+import { allList } from '@/api/business/member'
 export default {
   name: 'OperaJkCabinetWindow',
   extends: BaseOpera,
@@ -103,37 +132,65 @@
       // 琛ㄥ崟鏁版嵁
       form: {
         id: null,
-        creator: '',
-        createDate: '',
-        editor: '',
-        editDate: '',
-        isdeleted: '',
-        info: '',
         code: '',
         name: '',
         devId: '',
         serialNo: '',
         linkAddr: '',
-        status: '',
+        status: 0,
         port: '',
-        managerId: '',
+        managerIdList: '',
         useTime: '',
-        doubleAuth: '',
-        authMemberId: '',
+        doubleAuth: 0,
+        authMemberIdList: '',
         rowNum: '',
         columnNum: '',
-        haertTime: '',
         lacation: '',
         longitude: '',
         latitude: '',
-        noType: '',
+        noType: 0,
         noPrefix: '',
         noLength: '',
-        noIndex: ''
+        noIndex: '',
+        sortType: 0
       },
       // 楠岃瘉瑙勫垯
       rules: {
-      }
+        code: [
+          { required: true, message: '璇疯緭鍏ヨ澶囩紪鍙�', trigger: 'blur' }
+        ],
+        name: [
+          { required: true, message: '璇疯緭鍏ヨ澶囧悕绉�', trigger: 'blur' }
+        ],
+        devId: [
+          { required: true, message: '璇疯緭鍏ヨ澶嘔D', trigger: 'blur' }
+        ],
+        linkAddr: [
+          { required: true, message: '璇疯緭鍏ラ�氳鍦板潃', trigger: 'blur' }
+        ],
+        port: [
+          { required: true, message: '璇疯緭鍏ョ鍙e彿', trigger: 'blur' }
+        ],
+        managerIdList: [
+          { required: true, message: '璇烽�夋嫨璁惧绠$悊鍛�', trigger: 'blur' }
+        ],
+        authMemberIdList: [
+          { required: true, message: '璇烽�夋嫨楠岃瘉浜�', trigger: 'blur' }
+        ],
+        rowNum: [
+          { required: true, message: '璇疯緭鍏ユ帓鍒�', trigger: 'blur' }
+        ],
+        noType: [
+          { required: true, message: '璇烽�夋嫨缂栫爜', trigger: 'blur' }
+        ],
+        noPrefix: [
+          { required: true, message: '璇疯緭鍏ュ墠缂�', trigger: 'blur' }
+        ],
+        sortType: [
+          { required: true, message: '璇疯緭鍏ユ帓鍒楅『搴�', trigger: 'blur' }
+        ]
+      },
+      memberList: []
     }
   },
   created () {
@@ -141,6 +198,42 @@
       api: '/business/jkCabinet',
       'field.id': 'id'
     })
+  },
+  methods: {
+    open (title, target) {
+      this.title = title
+      this.loadMember()
+      this.visible = true
+      // 鏂板缓
+      if (target == null) {
+        this.$nextTick(() => {
+          this.$refs.form.resetFields()
+          this.form[this.configData['field.id']] = null
+        })
+        return
+      }
+      // 缂栬緫
+      this.$nextTick(() => {
+        for (const key in this.form) {
+          this.form[key] = target[key]
+        }
+      })
+    },
+    loadMember () {
+      allList({
+        type: 2
+      }).then(res => {
+        this.memberList = res
+      })
+    },
+    changeNoType() {
+      if (this.form.noType === 0) {
+        this.form.noPrefix = ''
+        this.form.noLength = ''
+        this.form.noIndex = ''
+        this.form.sortType = 0
+      }
+    }
   }
 }
 </script>
diff --git a/admin/src/components/business/OperaJkIccardWindow.vue b/admin/src/components/business/OperaJkIccardWindow.vue
index 6136bb1..3d9b329 100644
--- a/admin/src/components/business/OperaJkIccardWindow.vue
+++ b/admin/src/components/business/OperaJkIccardWindow.vue
@@ -1,43 +1,37 @@
 <template>
   <GlobalWindow
+    width="50%"
     :title="title"
     :visible.sync="visible"
     :confirm-working="isWorking"
     @confirm="confirm"
   >
     <el-form :model="form" ref="form" :rules="rules">
-      <el-form-item label="鍒涘缓浜虹紪鐮�" prop="creator">
-        <el-input v-model="form.creator" placeholder="璇疯緭鍏ュ垱寤轰汉缂栫爜" v-trim/>
+      <el-form-item label="IC鍗″彿" prop="code">
+        <el-input v-model="form.code" :disabled="form.id" placeholder="璇疯緭鍏C鍗″彿锛屽彲浣跨敤璇诲崱鍣�/鎵爜鏋�" v-trim/>
       </el-form-item>
-      <el-form-item label="鍒涘缓鏃堕棿" prop="createDate">
-        <el-date-picker v-model="form.createDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ュ垱寤烘椂闂�"></el-date-picker>
+      <el-form-item label="韬唤绫诲瀷" prop="userType">
+        <el-radio-group v-model="form.userType" :disabled="form.id" @change="getUserAll">
+          <el-radio :label="0">鍙告満</el-radio>
+          <el-radio :label="1">鏍¢獙浜哄憳</el-radio>
+        </el-radio-group>
       </el-form-item>
-      <el-form-item label="鏇存柊浜虹紪鐮�" prop="editor">
-        <el-input v-model="form.editor" placeholder="璇疯緭鍏ユ洿鏂颁汉缂栫爜" v-trim/>
+      <el-form-item label="鍏宠仈鐢ㄦ埛" prop="memberId">
+        <div style="width: 100%; display: flex; flex-direction: column;">
+          <el-select v-model="form.memberId" placeholder="璇烽�夋嫨">
+            <el-option v-for="(item, index) in userAll" :key="index" :label="item.name" :value="item.id"></el-option>
+          </el-select>
+          <span style="color: #999999; margin-top: 5px;">绯荤粺浼氶�氳繃IC鍏宠仈鐢ㄦ埛锛屼笌閽ュ寵鏌滀笂鐨勮溅杈嗙殑鍙告満/楠岃瘉浜哄憳淇℃伅杩涜鏍¢獙</span>
+        </div>
       </el-form-item>
-      <el-form-item label="鏇存柊鏃堕棿" prop="editDate">
-        <el-date-picker v-model="form.editDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ユ洿鏂版椂闂�"></el-date-picker>
-      </el-form-item>
-      <el-form-item label="鏄惁鍒犻櫎0鍚� 1鏄�" prop="isdeleted">
-        <el-input v-model="form.isdeleted" placeholder="璇疯緭鍏ユ槸鍚﹀垹闄�0鍚� 1鏄�" v-trim/>
-      </el-form-item>
-      <el-form-item label="澶囨敞" prop="info">
-        <el-input v-model="form.info" placeholder="璇疯緭鍏ュ娉�" v-trim/>
-      </el-form-item>
-      <el-form-item label="浜哄憳缂栫爜缂栫爜锛堝叧鑱攎ember)" prop="memberId">
-        <el-input v-model="form.memberId" placeholder="璇疯緭鍏ヤ汉鍛樼紪鐮佺紪鐮侊紙鍏宠仈member)" v-trim/>
-      </el-form-item>
-      <el-form-item label="缂栫爜" prop="code">
-        <el-input v-model="form.code" placeholder="璇疯緭鍏ョ紪鐮�" v-trim/>
-      </el-form-item>
-      <el-form-item label="鐘舵�� 0绂佺敤 1鍚敤" prop="status">
-        <el-input v-model="form.status" placeholder="璇疯緭鍏ョ姸鎬� 0绂佺敤 1鍚敤" v-trim/>
-      </el-form-item>
-      <el-form-item label="鍗″悕绉�" prop="name">
-        <el-input v-model="form.name" placeholder="璇疯緭鍏ュ崱鍚嶇О" v-trim/>
-      </el-form-item>
-      <el-form-item label="閽ュ寵鏌滅紪鐮侊紙鍏宠仈jk_cabinet)" prop="cabinetId">
-        <el-input v-model="form.cabinetId" placeholder="璇疯緭鍏ラ挜鍖欐煖缂栫爜锛堝叧鑱攋k_cabinet)" v-trim/>
+      <el-form-item label="鐘舵��" prop="status">
+        <el-switch
+          v-model="form.status"
+          active-color="#13ce66"
+          inactive-color="#ff4949"
+          :active-value="1"
+          :inactive-value="0">
+        </el-switch>
       </el-form-item>
     </el-form>
   </GlobalWindow>
@@ -46,6 +40,7 @@
 <script>
 import BaseOpera from '@/components/base/BaseOpera'
 import GlobalWindow from '@/components/common/GlobalWindow'
+import { allList } from '@/api/business/member'
 export default {
   name: 'OperaJkIccardWindow',
   extends: BaseOpera,
@@ -55,21 +50,24 @@
       // 琛ㄥ崟鏁版嵁
       form: {
         id: null,
-        creator: '',
-        createDate: '',
-        editor: '',
-        editDate: '',
-        isdeleted: '',
-        info: '',
         memberId: '',
         code: '',
-        status: '',
-        name: '',
-        cabinetId: ''
+        status: 1,
+        userType: 0
       },
       // 楠岃瘉瑙勫垯
       rules: {
-      }
+        code: [
+          { required: true, message: '璇疯緭鍏C鍗″彿', trigger: 'blur' }
+        ],
+        userType: [
+          { required: true, message: '璇烽�夋嫨韬唤', trigger: 'blur' }
+        ],
+        memberId: [
+          { required: true, message: '璇烽�夋嫨鍏宠仈鐢ㄦ埛', trigger: 'blur' }
+        ]
+      },
+      userAll: []
     }
   },
   created () {
@@ -77,6 +75,36 @@
       api: '/business/jkIccard',
       'field.id': 'id'
     })
+  },
+  methods: {
+    open (title, target) {
+      this.title = title
+      this.visible = true
+      // 鏂板缓
+      if (target == null) {
+        this.$nextTick(() => {
+          this.$refs.form.resetFields()
+          this.form[this.configData['field.id']] = null
+        })
+        this.getUserAll()
+        return
+      }
+      // 缂栬緫
+      this.$nextTick(() => {
+        for (const key in this.form) {
+          this.form[key] = target[key]
+        }
+        this.getUserAll()
+      })
+    },
+    getUserAll() {
+      allList({
+        type: 2,
+        queryAuth: this.form.userType === 1 ? 1 : 0
+      }).then(res => {
+        this.userAll = res
+      })
+    }
   }
 }
 </script>
diff --git a/admin/src/components/business/OperaJkKeysWindow.vue b/admin/src/components/business/OperaJkKeysWindow.vue
index 9fbb1bf..099b5e2 100644
--- a/admin/src/components/business/OperaJkKeysWindow.vue
+++ b/admin/src/components/business/OperaJkKeysWindow.vue
@@ -1,46 +1,33 @@
 <template>
   <GlobalWindow
+    width="50%"
     :title="title"
     :visible.sync="visible"
     :confirm-working="isWorking"
     @confirm="confirm"
   >
     <el-form :model="form" ref="form" :rules="rules">
-      <el-form-item label="鍒涘缓浜虹紪鐮�" prop="creator">
-        <el-input v-model="form.creator" placeholder="璇疯緭鍏ュ垱寤轰汉缂栫爜" v-trim/>
-      </el-form-item>
-      <el-form-item label="鍒涘缓鏃堕棿" prop="createDate">
-        <el-date-picker v-model="form.createDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ュ垱寤烘椂闂�"></el-date-picker>
-      </el-form-item>
-      <el-form-item label="鏇存柊浜虹紪鐮�" prop="editor">
-        <el-input v-model="form.editor" placeholder="璇疯緭鍏ユ洿鏂颁汉缂栫爜" v-trim/>
-      </el-form-item>
-      <el-form-item label="鏇存柊鏃堕棿" prop="editDate">
-        <el-date-picker v-model="form.editDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ユ洿鏂版椂闂�"></el-date-picker>
-      </el-form-item>
-      <el-form-item label="鏄惁鍒犻櫎0鍚� 1鏄�" prop="isdeleted">
-        <el-input v-model="form.isdeleted" placeholder="璇疯緭鍏ユ槸鍚﹀垹闄�0鍚� 1鏄�" v-trim/>
-      </el-form-item>
-      <el-form-item label="澶囨敞" prop="info">
-        <el-input v-model="form.info" placeholder="璇疯緭鍏ュ娉�" v-trim/>
-      </el-form-item>
       <el-form-item label="閽ュ寵缂栧彿" prop="code">
         <el-input v-model="form.code" placeholder="璇疯緭鍏ラ挜鍖欑紪鍙�" v-trim/>
       </el-form-item>
-      <el-form-item label="杞︾墝鍙�" prop="carCode">
-        <el-input v-model="form.carCode" placeholder="璇疯緭鍏ヨ溅鐗屽彿" v-trim/>
-      </el-form-item>
-      <el-form-item label="鎵�灞炶溅杈�(鍏宠仈cars)" prop="carId">
-        <el-input v-model="form.carId" placeholder="璇疯緭鍏ユ墍灞炶溅杈�(鍏宠仈cars)" v-trim/>
+      <el-form-item label="鎵�灞炶溅杈�" prop="carId">
+        <el-select v-model="form.carId" placeholder="璇烽�夋嫨">
+          <el-option
+            v-for="item in carAll"
+            :key="item.id"
+            :label="item.code"
+            :value="item.id">
+          </el-option>
+        </el-select>
       </el-form-item>
       <el-form-item label="RFID鏍囩" prop="rfidLable">
         <el-input v-model="form.rfidLable" placeholder="璇疯緭鍏FID鏍囩" v-trim/>
       </el-form-item>
-      <el-form-item label="棰嗗彇瑙勫垯 0闅忚溅 1闅忔淳杞﹀崟" prop="roleType">
-        <el-input v-model="form.roleType" placeholder="璇疯緭鍏ラ鍙栬鍒� 0闅忚溅 1闅忔淳杞﹀崟" v-trim/>
-      </el-form-item>
-      <el-form-item label="鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭" prop="status">
-        <el-input v-model="form.status" placeholder="璇疯緭鍏ョ姸鎬� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭" v-trim/>
+      <el-form-item label="棰嗗彇瑙勫垯" prop="roleType">
+        <el-radio-group v-model="form.roleType">
+          <el-radio :label="0">闅忚溅</el-radio>
+          <el-radio :label="1">闅忔淳杞﹀崟</el-radio>
+        </el-radio-group>
       </el-form-item>
     </el-form>
   </GlobalWindow>
@@ -49,6 +36,7 @@
 <script>
 import BaseOpera from '@/components/base/BaseOpera'
 import GlobalWindow from '@/components/common/GlobalWindow'
+import { allList } from '@/api/business/cars'
 export default {
   name: 'OperaJkKeysWindow',
   extends: BaseOpera,
@@ -58,22 +46,27 @@
       // 琛ㄥ崟鏁版嵁
       form: {
         id: null,
-        creator: '',
-        createDate: '',
-        editor: '',
-        editDate: '',
-        isdeleted: '',
-        info: '',
         code: '',
-        carCode: '',
         carId: '',
         rfidLable: '',
-        roleType: '',
-        status: ''
+        roleType: 0
       },
       // 楠岃瘉瑙勫垯
       rules: {
-      }
+        code: [
+          { required: true, message: '璇疯緭鍏ラ挜鍖欑紪鍙�', trigger: 'blur' }
+        ],
+        carId: [
+          { required: true, message: '璇烽�夋嫨鎵�灞炶溅杈�', trigger: 'blur' }
+        ],
+        rfidLable: [
+          { required: true, message: '璇疯緭鍏FID鏍囩', trigger: 'blur' }
+        ],
+        roleType: [
+          { required: true, message: '璇烽�夋嫨棰嗗彇瑙勫垯', trigger: 'blur' }
+        ]
+      },
+      carAll: []
     }
   },
   created () {
@@ -81,6 +74,15 @@
       api: '/business/jkKeys',
       'field.id': 'id'
     })
+    this.getCars()
+  },
+  methods: {
+    getCars() {
+      allList({ type: 0 })
+        .then(res => {
+          this.carAll = res
+        })
+    }
   }
 }
 </script>
diff --git a/admin/src/components/business/OperaJkVersionWindow.vue b/admin/src/components/business/OperaJkVersionWindow.vue
index 101b354..83a120b 100644
--- a/admin/src/components/business/OperaJkVersionWindow.vue
+++ b/admin/src/components/business/OperaJkVersionWindow.vue
@@ -1,52 +1,43 @@
 <template>
   <GlobalWindow
     :title="title"
+    width="50%"
     :visible.sync="visible"
     :confirm-working="isWorking"
     @confirm="confirm"
   >
     <el-form :model="form" ref="form" :rules="rules">
-      <el-form-item label="鍒涘缓浜虹紪鐮�" prop="creator">
-        <el-input v-model="form.creator" placeholder="璇疯緭鍏ュ垱寤轰汉缂栫爜" v-trim/>
-      </el-form-item>
-      <el-form-item label="鍒涘缓鏃堕棿" prop="createDate">
-        <el-date-picker v-model="form.createDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ュ垱寤烘椂闂�"></el-date-picker>
-      </el-form-item>
-      <el-form-item label="鏇存柊浜虹紪鐮�" prop="editor">
-        <el-input v-model="form.editor" placeholder="璇疯緭鍏ユ洿鏂颁汉缂栫爜" v-trim/>
-      </el-form-item>
-      <el-form-item label="鏇存柊鏃堕棿" prop="editDate">
-        <el-date-picker v-model="form.editDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ユ洿鏂版椂闂�"></el-date-picker>
-      </el-form-item>
-      <el-form-item label="鏄惁鍒犻櫎0鍚� 1鏄�" prop="isdeleted">
-        <el-input v-model="form.isdeleted" placeholder="璇疯緭鍏ユ槸鍚﹀垹闄�0鍚� 1鏄�" v-trim/>
-      </el-form-item>
-      <el-form-item label="澶囨敞" prop="info">
-        <el-input v-model="form.info" placeholder="璇疯緭鍏ュ娉�" v-trim/>
-      </el-form-item>
       <el-form-item label="鐗堟湰鍙�" prop="versionInfo">
         <el-input v-model="form.versionInfo" placeholder="璇疯緭鍏ョ増鏈彿" v-trim/>
       </el-form-item>
-      <el-form-item label="瀹夎鍖呰矾寰�" prop="fileUrl">
-        <el-input v-model="form.fileUrl" placeholder="璇疯緭鍏ュ畨瑁呭寘璺緞" v-trim/>
-      </el-form-item>
-      <el-form-item label="瀹夎鐗堝悕绉�" prop="name">
-        <el-input v-model="form.name" placeholder="璇疯緭鍏ュ畨瑁呯増鍚嶇О" v-trim/>
+      <el-form-item label="瀹夎鍖�" prop="fileUrl">
+        <div style="width: 100%; height: 1px;"></div>
+        <el-upload
+          class="upload-demo"
+          accept=".APK,.apk"
+          :limit="1"
+          :action="uploadImgUrl"
+          :data="uploadData"
+          :on-success="handleSuccess"
+          :on-error="uploadError"
+          :on-remove="handleRemove"
+          :on-exceed="uploadExceed"
+          :file-list="fileList">
+          <el-button size="small" type="primary">鐐瑰嚮涓婁紶</el-button>
+          <div slot="tip" class="el-upload__tip">鏀寔涓婁紶APK鏂囦欢锛屽崟娆′笂浼�<2GB</div>
+        </el-upload>
       </el-form-item>
       <el-form-item label="鏇存柊鎻忚堪" prop="content">
-        <el-input v-model="form.content" placeholder="璇疯緭鍏ユ洿鏂版弿杩�" v-trim/>
+        <el-input type="textarea" :rows="5" maxlength="100" show-word-limit v-model="form.content" placeholder="璇疯緭鍏ユ洿鏂版弿杩�" v-trim/>
       </el-form-item>
-      <el-form-item label="鎺掑簭鐮�" prop="sortnum">
-        <el-input v-model="form.sortnum" placeholder="璇疯緭鍏ユ帓搴忕爜" v-trim/>
-      </el-form-item>
-      <el-form-item label="鏇存柊鏍囬" prop="title">
-        <el-input v-model="form.title" placeholder="璇疯緭鍏ユ洿鏂版爣棰�" v-trim/>
-      </el-form-item>
-      <el-form-item label="鏄惁寮哄埗鏇存柊 0鍚� 1鏄�" prop="isForce">
-        <el-input v-model="form.isForce" placeholder="璇疯緭鍏ユ槸鍚﹀己鍒舵洿鏂� 0鍚� 1鏄�" v-trim/>
-      </el-form-item>
-      <el-form-item label="骞冲彴绫诲瀷 0Android 1IOS" prop="type">
-        <el-input v-model="form.type" placeholder="璇疯緭鍏ュ钩鍙扮被鍨� 0Android 1IOS" v-trim/>
+      <el-form-item label="鏄惁寮哄埗鏇存柊" prop="isForce">
+        <el-switch
+          v-model="form.isForce"
+          active-color="#13ce66"
+          inactive-color="#ff4949"
+          :active-value="1"
+          :inactive-value="0">
+        </el-switch>
       </el-form-item>
     </el-form>
   </GlobalWindow>
@@ -61,26 +52,32 @@
   components: { GlobalWindow },
   data () {
     return {
+      uploadImgUrl: process.env.VUE_APP_API_PREFIX + '/visitsAdmin/cloudService/public/upload',
       // 琛ㄥ崟鏁版嵁
       form: {
         id: null,
-        creator: '',
-        createDate: '',
-        editor: '',
-        editDate: '',
-        isdeleted: '',
-        info: '',
         versionInfo: '',
         fileUrl: '',
-        name: '',
         content: '',
-        sortnum: '',
-        title: '',
-        isForce: '',
-        type: ''
+        fileSize: '',
+        name: '',
+        isForce: 1
       },
       // 楠岃瘉瑙勫垯
       rules: {
+        versionInfo: [
+          { required: true, message: '璇疯緭鍏ョ増鏈彿', trigger: 'blur' }
+        ],
+        fileUrl: [
+          { required: true, message: '璇蜂笂浼犲畨瑁呭寘', trigger: 'blur' }
+        ],
+        content: [
+          { required: true, message: '璇疯緭鍏ユ洿鏂版弿杩�', trigger: 'blur' }
+        ]
+      },
+      fileList: [],
+      uploadData: {
+        folder: 'appFile'
       }
     }
   },
@@ -89,6 +86,70 @@
       api: '/business/jkVersion',
       'field.id': 'id'
     })
+  },
+  methods: {
+    open (title, target) {
+      this.title = title
+      this.fileList = []
+      this.form.fileSize = ''
+      this.form.name = ''
+      this.visible = true
+      // 鏂板缓
+      if (target == null) {
+        this.$nextTick(() => {
+          this.$refs.form.resetFields()
+          this.form[this.configData['field.id']] = null
+        })
+        return
+      }
+      // 缂栬緫
+      this.$nextTick(() => {
+        for (const key in this.form) {
+          this.form[key] = target[key]
+        }
+        if (this.form.fileUrl) {
+          this.fileList.push({
+            name: this.form.name,
+            url: target.fullFileUrl
+          })
+        }
+      })
+    },
+    handleSuccess(res, file) {
+      if (res.code == 200) {
+        let { data } = res
+        this.form.fileUrl = data.imgaddr
+        this.form.fileSize = data.fileSize
+        this.form.name = data.originname
+        this.fileList.push({
+          name: data.originname,
+          url: data.url
+        })
+        this.$message.success('涓婁紶鎴愬姛')
+      } else {
+        this.$message.error('涓婁紶澶辫触')
+        this.form.fileUrl = ''
+        this.fileList = []
+        this.form.name = ''
+        this.form.fileSize = ''
+      }
+    },
+    uploadError() {
+      this.form.fileUrl = ''
+      this.fileList = []
+      this.form.name = ''
+      this.form.fileSize = ''
+      this.$message.error('涓婁紶澶辫触')
+    },
+    uploadExceed() {
+      this.$message.error('鏈�澶氬彧鑳戒笂浼犱竴涓枃浠�')
+    },
+    handleRemove() {
+      this.form.fileUrl = ''
+      this.fileList = []
+      this.form.name = ''
+      this.form.fileSize = ''
+    }
   }
 }
 </script>
diff --git a/admin/src/components/business/alcoholTest.vue b/admin/src/components/business/alcoholTest.vue
new file mode 100644
index 0000000..9d7e2d6
--- /dev/null
+++ b/admin/src/components/business/alcoholTest.vue
@@ -0,0 +1,112 @@
+<template>
+    <GlobalWindow
+        width="50%"
+        :title="title"
+        :visible.sync="visible"
+        :confirm-working="isWorking"
+        @confirm="confirm"
+    >
+        <el-form :model="form" ref="form" :rules="rules">
+            <el-form-item label="鍚规皵鏃堕暱" prop="blowTime">
+                <el-input v-model="form.blowTime" placeholder="璇疯緭鍏ュ惞姘旀椂闀匡紙绉掞級" v-trim/>
+            </el-form-item>
+            <el-form-item label="鍘嬪姏鍊�" prop="pressure">
+                <el-input v-model="form.pressure" placeholder="璇疯緭鍏ュ帇鍔涘��" v-trim/>
+            </el-form-item>
+            <el-form-item label="閰掔簿娴撳害闃堝��" prop="concentration">
+                <div style="width: 100%; display: flex; align-items: center;">
+                    <el-input v-model="form.concentration" placeholder="璇疯緭鍏ラ厭绮炬祿搴﹂璀﹀��" style="flex: 1;" v-trim/>
+                    <el-select v-model="form.threshold" placeholder="璇烽�夋嫨" style="flex-shrink: 0; margin-left: 15px;">
+                        <el-option label="mg/100ml" value="1"></el-option>
+                        <el-option label="mg/L" value="2"></el-option>
+                        <el-option label="%BAC" value="3"></el-option>
+                    </el-select>
+                </div>
+            </el-form-item>
+        </el-form>
+    </GlobalWindow>
+</template>
+
+<script>
+  import BaseOpera from '@/components/base/BaseOpera'
+  import GlobalWindow from '@/components/common/GlobalWindow'
+  import { updateCabinetConfig } from '@/api/business/jkCabinet'
+  export default {
+    name: 'alcoholTest',
+    extends: BaseOpera,
+    components: { GlobalWindow },
+    data () {
+      return {
+        // 琛ㄥ崟鏁版嵁
+        form: {
+          id: null,
+          blowTime: '',
+          pressure: '',
+          concentration: '',
+          threshold: ''
+        },
+        // 楠岃瘉瑙勫垯
+        rules: {
+          blowTime: [
+            { required: true, message: '璇疯緭鍏ュ惞姘旀椂闀�', trigger: 'blur' }
+          ],
+          pressure: [
+            { required: true, message: '璇疯緭鍏ュ帇鍔涘��', trigger: 'blur' }
+          ],
+          concentration: [
+            { required: true, message: '璇烽�夋嫨閰掔簿娴撳害棰勮鍊�', trigger: 'blur' }
+          ],
+        }
+      }
+    },
+    created () {
+      this.config({
+        api: '/business/jkCabinet',
+        'field.id': 'id'
+      })
+    },
+    methods: {
+      open (title, target) {
+        this.title = title
+        this.form.threshold = ''
+        this.visible = true
+        // 鏂板缓
+        if (target == null) {
+          this.$nextTick(() => {
+            this.$refs.form.resetFields()
+            this.form[this.configData['field.id']] = null
+          })
+          return
+        }
+        // 缂栬緫
+        this.$nextTick(() => {
+          for (const key in this.form) {
+            this.form[key] = target[key]
+          }
+        })
+      },
+      // 纭鏂板缓
+      __confirmCreate () {
+        this.$refs.form.validate((valid) => {
+          if (!valid) {
+            return
+          }
+          // 璋冪敤鏂板缓鎺ュ彛
+          this.isWorking = true
+          updateCabinetConfig(this.form)
+            .then(() => {
+              this.visible = false
+              this.$tip.apiSuccess('鎿嶄綔鎴愬姛')
+              this.$emit('success')
+            })
+            .catch(e => {
+              // this.$tip.apiFailed(e)
+            })
+            .finally(() => {
+              this.isWorking = false
+            })
+        })
+      },
+    }
+  }
+</script>
diff --git a/admin/src/components/business/cabinetDetails.vue b/admin/src/components/business/cabinetDetails.vue
new file mode 100644
index 0000000..f08a6ba
--- /dev/null
+++ b/admin/src/components/business/cabinetDetails.vue
@@ -0,0 +1,199 @@
+<template>
+    <GlobalWindow
+        :title="title"
+        width="100%"
+        :visible.sync="visible"
+        :withFooter="false"
+    >
+        <el-form ref="searchForm" :model="searchForm" label-width="100px" inline>
+            <el-form-item label="閽ュ寵" prop="keyCode">
+                <el-input v-model="searchForm.keyCode" placeholder="璇疯緭鍏ラ挜鍖欑紪鐮佹垨鍚嶇О" @keypress.enter.native="getList"></el-input>
+            </el-form-item>
+            <el-form-item label="鐘舵��" prop="status">
+                <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨" @change="getList">
+                    <el-option label="鍏ㄩ儴" value=""></el-option>
+                    <el-option label="鍚敤" :value="0"></el-option>
+                    <el-option label="绂佺敤" :value="1"></el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item label="鏌滄牸鐘舵��" prop="bindStatus">
+                <el-select v-model="searchForm.bindStatus" placeholder="璇烽�夋嫨" @change="getList">
+                    <el-option label="鍏ㄩ儴" value=""></el-option>
+                    <el-option label="鏈粦瀹�" :value="0"></el-option>
+                    <el-option label="宸茬粦瀹�" :value="1"></el-option>
+                </el-select>
+            </el-form-item>
+            <el-form-item>
+                <el-button type="primary" @click="getList">鎼滅储</el-button>
+            </el-form-item>
+            <el-form-item>
+                <el-button @click="reset">閲嶇疆</el-button>
+            </el-form-item>
+        </el-form>
+        <ul class="toolbar">
+            <li><el-button type="primary" @click="bathUnBindKeys">鎵归噺瑙g粦</el-button></li>
+        </ul>
+        <el-table
+            v-loading="loading"
+            :data="list"
+            stripe
+        >
+            <el-table-column prop="code" label="鏌滄牸缂栫爜" min-width="100px"></el-table-column>
+            <el-table-column prop="cabinetName" label="鎵�灞為挜鍖欐煖" min-width="100px"></el-table-column>
+            <el-table-column prop="keyId" label="缁戝畾閽ュ寵" min-width="100px">
+                <template slot-scope="{row}">
+                    <el-select v-model="row.keyId" placeholder="璇烽�夋嫨" @change="blurFunc($event, row, 1)">
+                        <el-option
+                            v-for="item in keysAll"
+                            :key="item.id"
+                            :label="item.code"
+                            :value="item.id"
+                            :disabled="item.isBinding === 1">
+                        </el-option>
+                    </el-select>
+                </template>
+            </el-table-column>
+            <el-table-column label="鏉垮彿" min-width="100px">
+                <template slot-scope="{row}">
+                    <el-input v-model="row.boardCode" @blur="blurFunc($event, row, 2)" placeholder="璇疯緭鍏ユ澘鍙�"></el-input>
+                </template>
+            </el-table-column>
+            <el-table-column label="閫氶亾鍙�" min-width="100px">
+                <template slot-scope="{row}">
+                    <el-input v-model="row.channelCode" @blur="blurFunc($event, row, 3)" placeholder="璇疯緭鍏ラ�氶亾鍙�"></el-input>
+                </template>
+            </el-table-column>
+            <el-table-column label="鐘舵��" min-width="100px">
+                <template slot-scope="{row}">
+                    <el-switch
+                        @change="changeStatus($event, row.id)"
+                        v-model="row.status"
+                        active-color="#13ce66"
+                        inactive-color="#ff4949"
+                        :active-value="0"
+                        :inactive-value="1">
+                    </el-switch>
+                </template>
+            </el-table-column>
+            <el-table-column label="杩愯鐘舵��" min-width="100px">
+                <template slot-scope="{row}">
+                    <el-link type="success" v-if="row.workingStatus === 0">姝e父</el-link>
+                    <el-link type="warning" v-if="row.workingStatus === 1">鏁呴殰</el-link>
+                </template>
+            </el-table-column>
+            <el-table-column label="鏌滄牸鐘舵��" min-width="100px">
+                <template slot-scope="{row}">
+                    <el-link type="warning" v-if="row.bindStatus === 0">鏈粦瀹�</el-link>
+                    <el-link type="success" v-if="row.bindStatus === 1">宸茬粦瀹�</el-link>
+                </template>
+            </el-table-column>
+        </el-table>
+    </GlobalWindow>
+</template>
+
+<script>
+  import BaseOpera from '@/components/base/BaseOpera'
+  import GlobalWindow from '@/components/common/GlobalWindow'
+  import { fetchList, updateStatusById, unBindKeys, updateById } from '@/api/business/jkCabinetGrid'
+  import { list } from '@/api/business/jkKeys'
+  export default {
+    name: 'cabinetDetails',
+    extends: BaseOpera,
+    components: { GlobalWindow },
+    data () {
+      return {
+        id: null,
+        info: null,
+        searchForm: {
+          keyCode: '',
+          status: '',
+          bindStatus: ''
+        },
+        list: [],
+        keysAll: [],
+        loading: false
+      }
+    },
+    methods: {
+      open (title, id) {
+        this.title = title
+        this.id = id
+        this.getList()
+        this.getKeysAll()
+        this.visible = true
+      },
+      getKeysAll() {
+        list({  })
+            .then(res => {
+              this.keysAll = res
+            })
+      },
+      blurFunc(e, row, type) {
+        let obj = {
+          id: row.id
+        }
+        if (type === 1) {
+          obj.keyId = row.keyId
+        } else if (type === 2) {
+          obj.boardCode = row.boardCode
+        } else if (type === 3) {
+          obj.channelCode = row.channelCode
+        }
+        updateById(obj)
+            .then(res => {
+              this.getList()
+              if (type === 1) {
+                this.getKeysAll()
+              }
+            })
+      },
+      bathUnBindKeys() {
+        this.$confirm('纭鎵归噺瑙g粦鍚�?', '鎻愮ず', {
+          confirmButtonText: '纭畾',
+          cancelButtonText: '鍙栨秷',
+          type: 'warning'
+        }).then(() => {
+          unBindKeys(this.list.map(item => item.id))
+            .then(res => {
+              this.getList()
+            })
+        }).catch(() => {
+
+        });
+      },
+      changeStatus(status, id) {
+        updateStatusById({ id, status })
+          .then(res => {
+            this.getList()
+          })
+      },
+      handleCurrentChange(e) {
+        this.page = e
+        this.getList()
+      },
+      reset() {
+        this.searchForm.keyId = ''
+        this.searchForm.status = ''
+        this.searchForm.workingStatus = ''
+        this.getList()
+      },
+      getList() {
+        this.loading = true
+        fetchList({
+          capacity: 99999,
+          page: 1,
+          model: {
+            cabinetId: this.id,
+            keyId: this.searchForm.keyId,
+            status: this.searchForm.status,
+            workingStatus: this.searchForm.workingStatus
+          }
+        }).then(res => {
+          this.list = res.records
+        }).finally(() => {
+          this.loading = false
+        })
+      }
+    }
+  }
+</script>
diff --git a/admin/src/views/business/jkCabinet.vue b/admin/src/views/business/jkCabinet.vue
index 6feef3f..a15d6d7 100644
--- a/admin/src/views/business/jkCabinet.vue
+++ b/admin/src/views/business/jkCabinet.vue
@@ -2,146 +2,82 @@
   <TableLayout :permissions="['business:jkcabinet:query']">
     <!-- 鎼滅储琛ㄥ崟 -->
     <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
-      <el-form-item label="涓婚敭" prop="id">
-        <el-input v-model="searchForm.id" placeholder="璇疯緭鍏ヤ富閿�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鍒涘缓浜虹紪鐮�" prop="creator">
-        <el-input v-model="searchForm.creator" placeholder="璇疯緭鍏ュ垱寤轰汉缂栫爜" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鍒涘缓鏃堕棿" prop="createDate">
-        <el-date-picker v-model="searchForm.createDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ュ垱寤烘椂闂�" @change="search"/>
-      </el-form-item>
-      <el-form-item label="鏇存柊浜虹紪鐮�" prop="editor">
-        <el-input v-model="searchForm.editor" placeholder="璇疯緭鍏ユ洿鏂颁汉缂栫爜" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鏇存柊鏃堕棿" prop="editDate">
-        <el-date-picker v-model="searchForm.editDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ユ洿鏂版椂闂�" @change="search"/>
-      </el-form-item>
-      <el-form-item label="鏄惁鍒犻櫎0鍚� 1鏄�" prop="isdeleted">
-        <el-input v-model="searchForm.isdeleted" placeholder="璇疯緭鍏ユ槸鍚﹀垹闄�0鍚� 1鏄�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="澶囨敞" prop="info">
-        <el-input v-model="searchForm.info" placeholder="璇疯緭鍏ュ娉�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
       <el-form-item label="璁惧缂栧彿" prop="code">
         <el-input v-model="searchForm.code" placeholder="璇疯緭鍏ヨ澶囩紪鍙�" @keypress.enter.native="search"></el-input>
       </el-form-item>
       <el-form-item label="璁惧鍚嶇О" prop="name">
         <el-input v-model="searchForm.name" placeholder="璇疯緭鍏ヨ澶囧悕绉�" @keypress.enter.native="search"></el-input>
       </el-form-item>
-      <el-form-item label="璁惧ID" prop="devId">
-        <el-input v-model="searchForm.devId" placeholder="璇疯緭鍏ヨ澶嘔D" @keypress.enter.native="search"></el-input>
+      <el-form-item label="杩愯鐘舵��" prop="rumStatus">
+        <el-select v-model="searchForm.rumStatus" placeholder="璇烽�夋嫨" @change="search">
+          <el-option label="鍏ㄩ儴" value=""></el-option>
+          <el-option label="鍦ㄧ嚎" :value="0"></el-option>
+          <el-option label="绂荤嚎" :value="1"></el-option>
+        </el-select>
       </el-form-item>
-      <el-form-item label="搴忓垪鍙�" prop="serialNo">
-        <el-input v-model="searchForm.serialNo" placeholder="璇疯緭鍏ュ簭鍒楀彿" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="閫氳鍦板潃" prop="linkAddr">
-        <el-input v-model="searchForm.linkAddr" placeholder="璇疯緭鍏ラ�氳鍦板潃" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭" prop="status">
-        <el-input v-model="searchForm.status" placeholder="璇疯緭鍏ョ姸鎬� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="绔彛" prop="port">
-        <el-input v-model="searchForm.port" placeholder="璇疯緭鍏ョ鍙�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="璁惧绠$悊鍛樼紪鐮侊紙鍏宠仈member)" prop="managerId">
-        <el-input v-model="searchForm.managerId" placeholder="璇疯緭鍏ヨ澶囩鐞嗗憳缂栫爜锛堝叧鑱攎ember)" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="浣跨敤鏃堕暱(绉�)" prop="useTime">
-        <el-input v-model="searchForm.useTime" placeholder="璇疯緭鍏ヤ娇鐢ㄦ椂闀�(绉�)" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鏄惁鍙岄噸楠岃瘉 0鍚� 1鏄�" prop="doubleAuth">
-        <el-input v-model="searchForm.doubleAuth" placeholder="璇疯緭鍏ユ槸鍚﹀弻閲嶉獙璇� 0鍚� 1鏄�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="楠岃瘉浜虹紪鐮侊紙鍏宠仈member)" prop="authMemberId">
-        <el-input v-model="searchForm.authMemberId" placeholder="璇疯緭鍏ラ獙璇佷汉缂栫爜锛堝叧鑱攎ember)" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鎺掓暟" prop="rowNum">
-        <el-input v-model="searchForm.rowNum" placeholder="璇疯緭鍏ユ帓鏁�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鍒楁暟" prop="columnNum">
-        <el-input v-model="searchForm.columnNum" placeholder="璇疯緭鍏ュ垪鏁�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鏈�鍚庨�氳鏃堕棿" prop="haertTime">
-        <el-date-picker v-model="searchForm.haertTime" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ユ渶鍚庨�氳鏃堕棿" @change="search"/>
-      </el-form-item>
-      <el-form-item label="鎵�鍦ㄤ綅缃�" prop="lacation">
-        <el-input v-model="searchForm.lacation" placeholder="璇疯緭鍏ユ墍鍦ㄤ綅缃�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="缁忓害" prop="longitude">
-        <el-input v-model="searchForm.longitude" placeholder="璇疯緭鍏ョ粡搴�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="缁村害" prop="latitude">
-        <el-input v-model="searchForm.latitude" placeholder="璇疯緭鍏ョ淮搴�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="缂栫爜鏂瑰紡 0鑷姩缂栫爜 1鎵嬪姩缂栫爜" prop="noType">
-        <el-input v-model="searchForm.noType" placeholder="璇疯緭鍏ョ紪鐮佹柟寮� 0鑷姩缂栫爜 1鎵嬪姩缂栫爜" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="缂栫爜鍓嶇紑" prop="noPrefix">
-        <el-input v-model="searchForm.noPrefix" placeholder="璇疯緭鍏ョ紪鐮佸墠缂�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="缂栫爜浣嶆暟" prop="noLength">
-        <el-input v-model="searchForm.noLength" placeholder="璇疯緭鍏ョ紪鐮佷綅鏁�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="璧峰缂栫爜" prop="noIndex">
-        <el-input v-model="searchForm.noIndex" placeholder="璇疯緭鍏ヨ捣濮嬬紪鐮�" @keypress.enter.native="search"></el-input>
+      <el-form-item label="鐘舵��" prop="status">
+        <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨" @change="search">
+          <el-option label="鍏ㄩ儴" value=""></el-option>
+          <el-option label="鍚敤" :value="1"></el-option>
+          <el-option label="绂佺敤" :value="0"></el-option>
+        </el-select>
       </el-form-item>
       <section>
         <el-button type="primary" @click="search">鎼滅储</el-button>
-        <el-button type="primary" :loading="isWorking.export" v-permissions="['business:jkcabinet:exportExcel']" @click="exportExcel">瀵煎嚭</el-button>
         <el-button @click="reset">閲嶇疆</el-button>
       </section>
     </el-form>
     <!-- 琛ㄦ牸鍜屽垎椤� -->
     <template v-slot:table-wrap>
       <ul class="toolbar" v-permissions="['business:jkcabinet:create', 'business:jkcabinet:delete']">
-        <li><el-button type="primary" @click="$refs.operaJkCabinetWindow.open('鏂板缓閽ュ寵鏌滃熀鏈俊鎭〃')" icon="el-icon-plus" v-permissions="['business:jkcabinet:create']">鏂板缓</el-button></li>
-        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:jkcabinet:delete']">鍒犻櫎</el-button></li>
+        <li><el-button type="primary" @click="$refs.operaJkCabinetWindow.open('鏂板缓璁惧')" icon="el-icon-plus" v-permissions="['business:jkcabinet:create']">鏂板缓</el-button></li>
+        <li><el-button type="warning" @click="$refs.alcoholTest.open('鏂板缓閰掔簿妫�娴嬮厤缃�', form)">閰掔簿妫�娴嬮厤缃�</el-button></li>
       </ul>
       <el-table
+        :height="tableHeightNew"
         v-loading="isWorking.search"
         :data="tableData.list"
         stripe
-        @selection-change="handleSelectionChange"
       >
-        <el-table-column type="selection" width="55"></el-table-column>
-        <el-table-column prop="id" label="涓婚敭" min-width="100px"></el-table-column>
-        <el-table-column prop="creator" label="鍒涘缓浜虹紪鐮�" min-width="100px"></el-table-column>
-        <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="100px"></el-table-column>
-        <el-table-column prop="editor" label="鏇存柊浜虹紪鐮�" min-width="100px"></el-table-column>
-        <el-table-column prop="editDate" label="鏇存柊鏃堕棿" min-width="100px"></el-table-column>
-        <el-table-column prop="isdeleted" label="鏄惁鍒犻櫎0鍚� 1鏄�" min-width="100px"></el-table-column>
-        <el-table-column prop="info" label="澶囨敞" min-width="100px"></el-table-column>
         <el-table-column prop="code" label="璁惧缂栧彿" min-width="100px"></el-table-column>
         <el-table-column prop="name" label="璁惧鍚嶇О" min-width="100px"></el-table-column>
         <el-table-column prop="devId" label="璁惧ID" min-width="100px"></el-table-column>
-        <el-table-column prop="serialNo" label="搴忓垪鍙�" min-width="100px"></el-table-column>
         <el-table-column prop="linkAddr" label="閫氳鍦板潃" min-width="100px"></el-table-column>
-        <el-table-column prop="status" label="鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭" min-width="100px"></el-table-column>
-        <el-table-column prop="port" label="绔彛" min-width="100px"></el-table-column>
-        <el-table-column prop="managerId" label="璁惧绠$悊鍛樼紪鐮侊紙鍏宠仈member)" min-width="100px"></el-table-column>
-        <el-table-column prop="useTime" label="浣跨敤鏃堕暱(绉�)" min-width="100px"></el-table-column>
-        <el-table-column prop="doubleAuth" label="鏄惁鍙岄噸楠岃瘉 0鍚� 1鏄�" min-width="100px"></el-table-column>
-        <el-table-column prop="authMemberId" label="楠岃瘉浜虹紪鐮侊紙鍏宠仈member)" min-width="100px"></el-table-column>
-        <el-table-column prop="rowNum" label="鎺掓暟" min-width="100px"></el-table-column>
-        <el-table-column prop="columnNum" label="鍒楁暟" min-width="100px"></el-table-column>
-        <el-table-column prop="haertTime" label="鏈�鍚庨�氳鏃堕棿" min-width="100px"></el-table-column>
+        <el-table-column prop="port" label="绔彛鍙�" min-width="100px"></el-table-column>
         <el-table-column prop="lacation" label="鎵�鍦ㄤ綅缃�" min-width="100px"></el-table-column>
-        <el-table-column prop="longitude" label="缁忓害" min-width="100px"></el-table-column>
-        <el-table-column prop="latitude" label="缁村害" min-width="100px"></el-table-column>
-        <el-table-column prop="noType" label="缂栫爜鏂瑰紡 0鑷姩缂栫爜 1鎵嬪姩缂栫爜" min-width="100px"></el-table-column>
-        <el-table-column prop="noPrefix" label="缂栫爜鍓嶇紑" min-width="100px"></el-table-column>
-        <el-table-column prop="noLength" label="缂栫爜浣嶆暟" min-width="100px"></el-table-column>
-        <el-table-column prop="noIndex" label="璧峰缂栫爜" min-width="100px"></el-table-column>
+        <el-table-column label="鏌滄牸鏁伴噺" min-width="100px">
+          <template slot-scope="{row}">
+            <el-button @click="$refs.cabinetDetails.open(row.name + '-鏌滄牸淇℃伅', row.id)">{{row.gridNum}}</el-button>
+          </template>
+        </el-table-column>
+        <el-table-column label="杩愯鐘舵��" min-width="100px">
+          <template slot-scope="{row}">
+            <el-link type="success" :underline="false" v-if="row.runStatus === 0">鍦ㄧ嚎</el-link>
+            <el-link type="danger" :underline="false" v-if="row.runStatus === 1">绂荤嚎</el-link>
+          </template>
+        </el-table-column>
+        <el-table-column label="鐘舵��" min-width="100px">
+          <template slot-scope="{row}">
+            <el-switch
+              v-model="row.status"
+              @change="changeStatus($event, row.id)"
+              active-color="#13ce66"
+              inactive-color="#ff4949"
+              :active-value="0"
+              :inactive-value="1">
+            </el-switch>
+          </template>
+        </el-table-column>
         <el-table-column
           v-if="containPermissions(['business:jkcabinet:update', 'business:jkcabinet:delete'])"
           label="鎿嶄綔"
-          min-width="120"
+          min-width="200"
           fixed="right"
         >
           <template slot-scope="{row}">
-            <el-button type="text" @click="$refs.operaJkCabinetWindow.open('缂栬緫閽ュ寵鏌滃熀鏈俊鎭〃', row)" icon="el-icon-edit" v-permissions="['business:jkcabinet:update']">缂栬緫</el-button>
-            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:jkcabinet:delete']">鍒犻櫎</el-button>
+            <el-button type="text" @click="$refs.cabinetDetails.open(row.name + '-鏌滄牸淇℃伅', row.id)">缁戝畾閽ュ寵</el-button>
+            <el-button type="text" @click="$refs.operaJkCabinetWindow.open('缂栬緫閽ュ寵鏌滃熀鏈俊鎭〃', row)" v-permissions="['business:jkcabinet:update']">缂栬緫</el-button>
+            <el-button type="text" @click="deleteById(row)" v-permissions="['business:jkcabinet:delete']">鍒犻櫎</el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -154,6 +90,10 @@
     </template>
     <!-- 鏂板缓/淇敼 -->
     <OperaJkCabinetWindow ref="operaJkCabinetWindow" @success="handlePageChange"/>
+    <!-- 鏌滃瓙璇︽儏 -->
+    <CabinetDetails ref="cabinetDetails" />
+    <!-- 鏂板閰掔簿妫�娴� -->
+    <AlcoholTest ref="alcoholTest" @success="GetCabinetConfig" />
   </TableLayout>
 </template>
 
@@ -162,43 +102,23 @@
 import TableLayout from '@/layouts/TableLayout'
 import Pagination from '@/components/common/Pagination'
 import OperaJkCabinetWindow from '@/components/business/OperaJkCabinetWindow'
+import CabinetDetails from '@/components/business/cabinetDetails'
+import AlcoholTest from '@/components/business/alcoholTest'
+import { updateStatusById, getCabinetConfig } from '@/api/business/jkCabinet'
 export default {
   name: 'JkCabinet',
   extends: BaseTable,
-  components: { TableLayout, Pagination, OperaJkCabinetWindow },
+  components: { TableLayout, Pagination, OperaJkCabinetWindow, CabinetDetails, AlcoholTest},
   data () {
     return {
       // 鎼滅储
       searchForm: {
-        id: '',
-        creator: '',
-        createDate: '',
-        editor: '',
-        editDate: '',
-        isdeleted: '',
-        info: '',
         code: '',
         name: '',
-        devId: '',
-        serialNo: '',
-        linkAddr: '',
         status: '',
-        port: '',
-        managerId: '',
-        useTime: '',
-        doubleAuth: '',
-        authMemberId: '',
-        rowNum: '',
-        columnNum: '',
-        haertTime: '',
-        lacation: '',
-        longitude: '',
-        latitude: '',
-        noType: '',
-        noPrefix: '',
-        noLength: '',
-        noIndex: ''
-      }
+        rumStatus: ''
+      },
+      form: null
     }
   },
   created () {
@@ -209,6 +129,21 @@
       'field.main': 'id'
     })
     this.search()
+    this.GetCabinetConfig()
+  },
+  methods: {
+    changeStatus(status, id) {
+      updateStatusById({ id, status })
+        .then(res => {
+          this.search()
+        })
+    },
+    GetCabinetConfig() {
+      getCabinetConfig()
+        .then(res => {
+          this.form = res
+        })
+    }
   }
 }
 </script>
diff --git a/admin/src/views/business/jkCabinetLog.vue b/admin/src/views/business/jkCabinetLog.vue
index 17d5c87..6bf29af 100644
--- a/admin/src/views/business/jkCabinetLog.vue
+++ b/admin/src/views/business/jkCabinetLog.vue
@@ -2,53 +2,44 @@
   <TableLayout :permissions="['business:jkcabinetlog:query']">
     <!-- 鎼滅储琛ㄥ崟 -->
     <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
-      <el-form-item label="涓婚敭" prop="id">
-        <el-input v-model="searchForm.id" placeholder="璇疯緭鍏ヤ富閿�" @keypress.enter.native="search"></el-input>
+      <el-form-item label="寮�闂ㄦ椂闂�" prop="date">
+        <el-date-picker
+          v-model="date"
+          @change="setDate"
+          type="daterange"
+          range-separator="鑷�"
+          start-placeholder="寮�濮嬫棩鏈�"
+          end-placeholder="缁撴潫鏃ユ湡"
+          format="yyyy 骞� MM 鏈� dd 鏃�"
+          value-format="yyyy-MM-dd">
+        </el-date-picker>
       </el-form-item>
-      <el-form-item label="鍒涘缓浜虹紪鐮�" prop="creator">
-        <el-input v-model="searchForm.creator" placeholder="璇疯緭鍏ュ垱寤轰汉缂栫爜" @keypress.enter.native="search"></el-input>
+      <el-form-item label="鎿嶄綔浜�" prop="memberName">
+        <el-input v-model="searchForm.memberName" placeholder="璇疯緭鍏�" @keypress.enter.native="search"></el-input>
       </el-form-item>
-      <el-form-item label="鍒涘缓鏃堕棿" prop="createDate">
-        <el-date-picker v-model="searchForm.createDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ュ垱寤烘椂闂�" @change="search"/>
+      <el-form-item label="閽ュ寵鏌�" prop="cabinetId">
+        <el-select v-model="searchForm.cabinetId" placeholder="璇烽�夋嫨" @change="search">
+          <el-option
+            v-for="item in keysAll"
+            :key="item.id"
+            :label="item.name"
+            :value="item.id">
+          </el-option>
+        </el-select>
       </el-form-item>
-      <el-form-item label="鏇存柊浜虹紪鐮�" prop="editor">
-        <el-input v-model="searchForm.editor" placeholder="璇疯緭鍏ユ洿鏂颁汉缂栫爜" @keypress.enter.native="search"></el-input>
+      <el-form-item label="楠岃瘉鏂瑰紡" prop="authType">
+        <el-select v-model="searchForm.authType" placeholder="璇烽�夋嫨" @change="search">
+          <el-option label="鍏ㄩ儴" value=""></el-option>
+          <el-option label="鍒疯劯" :value="0"></el-option>
+          <el-option label="鍒峰崱" :value="1"></el-option>
+        </el-select>
       </el-form-item>
-      <el-form-item label="鏇存柊鏃堕棿" prop="editDate">
-        <el-date-picker v-model="searchForm.editDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ユ洿鏂版椂闂�" @change="search"/>
-      </el-form-item>
-      <el-form-item label="鏄惁鍒犻櫎0鍚� 1鏄�" prop="isdeleted">
-        <el-input v-model="searchForm.isdeleted" placeholder="璇疯緭鍏ユ槸鍚﹀垹闄�0鍚� 1鏄�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="澶囨敞" prop="info">
-        <el-input v-model="searchForm.info" placeholder="璇疯緭鍏ュ娉�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="閽ュ寵鏌滅紪鐮侊紙鍏宠仈jk_cabinet)" prop="cabinetId">
-        <el-input v-model="searchForm.cabinetId" placeholder="璇疯緭鍏ラ挜鍖欐煖缂栫爜锛堝叧鑱攋k_cabinet)" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="閽ュ寵鏌滄牸缂栫爜(鍏宠仈jk_cabinet_grid)" prop="gridId">
-        <el-input v-model="searchForm.gridId" placeholder="璇疯緭鍏ラ挜鍖欐煖鏍肩紪鐮�(鍏宠仈jk_cabinet_grid)" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="楠岃瘉鏂瑰紡 0鍒疯劯 1鍒峰崱" prop="authType">
-        <el-input v-model="searchForm.authType" placeholder="璇疯緭鍏ラ獙璇佹柟寮� 0鍒疯劯 1鍒峰崱" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="杞﹁締缂栫爜锛堝叧鑱攃ars)" prop="carId">
-        <el-input v-model="searchForm.carId" placeholder="璇疯緭鍏ヨ溅杈嗙紪鐮侊紙鍏宠仈cars)" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="閽ュ寵缂栫爜(鍏宠仈jk_keys)" prop="keyId">
-        <el-input v-model="searchForm.keyId" placeholder="璇疯緭鍏ラ挜鍖欑紪鐮�(鍏宠仈jk_keys)" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="浜哄憳缂栫爜锛堝叧鑱攎ember)" prop="memberId">
-        <el-input v-model="searchForm.memberId" placeholder="璇疯緭鍏ヤ汉鍛樼紪鐮侊紙鍏宠仈member)" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="閽ュ寵淇℃伅锛堣溅鐗屽彿-閽ュ寵缂栫爜锛�" prop="keyInfo">
-        <el-input v-model="searchForm.keyInfo" placeholder="璇疯緭鍏ラ挜鍖欎俊鎭紙杞︾墝鍙�-閽ュ寵缂栫爜锛�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="棰嗗彇瑙勫垯 0闅忚溅 1闅忔淳杞﹀崟" prop="roleType">
-        <el-input v-model="searchForm.roleType" placeholder="璇疯緭鍏ラ鍙栬鍒� 0闅忚溅 1闅忔淳杞﹀崟" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鐘舵�� 0鎴愬姛 1澶辫触" prop="status">
-        <el-input v-model="searchForm.status" placeholder="璇疯緭鍏ョ姸鎬� 0鎴愬姛 1澶辫触" @keypress.enter.native="search"></el-input>
+      <el-form-item label="鐘舵��" prop="status">
+        <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨" @change="search">
+          <el-option label="鍏ㄩ儴" value=""></el-option>
+          <el-option label="鎴愬姛" :value="0"></el-option>
+          <el-option label="澶辫触" :value="1"></el-option>
+        </el-select>
       </el-form-item>
       <section>
         <el-button type="primary" @click="search">鎼滅储</el-button>
@@ -58,42 +49,27 @@
     </el-form>
     <!-- 琛ㄦ牸鍜屽垎椤� -->
     <template v-slot:table-wrap>
-      <ul class="toolbar" v-permissions="['business:jkcabinetlog:create', 'business:jkcabinetlog:delete']">
-        <li><el-button type="primary" @click="$refs.operaJkCabinetLogWindow.open('鏂板缓閽ュ寵鏌滃紑鍏抽棬璁板綍')" icon="el-icon-plus" v-permissions="['business:jkcabinetlog:create']">鏂板缓</el-button></li>
-        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:jkcabinetlog:delete']">鍒犻櫎</el-button></li>
-      </ul>
       <el-table
+        :height="tableHeightNew"
         v-loading="isWorking.search"
         :data="tableData.list"
         stripe
-        @selection-change="handleSelectionChange"
       >
-        <el-table-column type="selection" width="55"></el-table-column>
-        <el-table-column prop="id" label="涓婚敭" min-width="100px"></el-table-column>
-        <el-table-column prop="creator" label="鍒涘缓浜虹紪鐮�" min-width="100px"></el-table-column>
-        <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="100px"></el-table-column>
-        <el-table-column prop="editor" label="鏇存柊浜虹紪鐮�" min-width="100px"></el-table-column>
-        <el-table-column prop="editDate" label="鏇存柊鏃堕棿" min-width="100px"></el-table-column>
-        <el-table-column prop="isdeleted" label="鏄惁鍒犻櫎0鍚� 1鏄�" min-width="100px"></el-table-column>
-        <el-table-column prop="info" label="澶囨敞" min-width="100px"></el-table-column>
-        <el-table-column prop="cabinetId" label="閽ュ寵鏌滅紪鐮侊紙鍏宠仈jk_cabinet)" min-width="100px"></el-table-column>
-        <el-table-column prop="gridId" label="閽ュ寵鏌滄牸缂栫爜(鍏宠仈jk_cabinet_grid)" min-width="100px"></el-table-column>
-        <el-table-column prop="authType" label="楠岃瘉鏂瑰紡 0鍒疯劯 1鍒峰崱" min-width="100px"></el-table-column>
-        <el-table-column prop="carId" label="杞﹁締缂栫爜锛堝叧鑱攃ars)" min-width="100px"></el-table-column>
-        <el-table-column prop="keyId" label="閽ュ寵缂栫爜(鍏宠仈jk_keys)" min-width="100px"></el-table-column>
-        <el-table-column prop="memberId" label="浜哄憳缂栫爜锛堝叧鑱攎ember)" min-width="100px"></el-table-column>
-        <el-table-column prop="keyInfo" label="閽ュ寵淇℃伅锛堣溅鐗屽彿-閽ュ寵缂栫爜锛�" min-width="100px"></el-table-column>
-        <el-table-column prop="roleType" label="棰嗗彇瑙勫垯 0闅忚溅 1闅忔淳杞﹀崟" min-width="100px"></el-table-column>
-        <el-table-column prop="status" label="鐘舵�� 0鎴愬姛 1澶辫触" min-width="100px"></el-table-column>
-        <el-table-column
-          v-if="containPermissions(['business:jkcabinetlog:update', 'business:jkcabinetlog:delete'])"
-          label="鎿嶄綔"
-          min-width="120"
-          fixed="right"
-        >
+        <el-table-column prop="createDate" label="寮�闂ㄦ椂闂�" min-width="100px"></el-table-column>
+        <el-table-column prop="memberName" label="鎿嶄綔浜�" min-width="100px"></el-table-column>
+        <el-table-column label="鏍¢獙鏂瑰紡" min-width="100px">
           <template slot-scope="{row}">
-            <el-button type="text" @click="$refs.operaJkCabinetLogWindow.open('缂栬緫閽ュ寵鏌滃紑鍏抽棬璁板綍', row)" icon="el-icon-edit" v-permissions="['business:jkcabinetlog:update']">缂栬緫</el-button>
-            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:jkcabinetlog:delete']">鍒犻櫎</el-button>
+            <el-link :underline="false" v-if="row.authType === 0">鍒疯劯</el-link>
+            <el-link :underline="false" v-if="row.authType === 1">鍒峰崱</el-link>
+          </template>
+        </el-table-column>
+        <el-table-column prop="cabinetName" label="鎵�灞為挜鍖欐煖" min-width="100px"></el-table-column>
+        <el-table-column prop="editDate" label="鏌滄牸缂栧彿" min-width="100px"></el-table-column>
+        <el-table-column prop="isdeleted" label="閽ュ寵" min-width="100px"></el-table-column>
+        <el-table-column label="鐘舵��" min-width="100px">
+          <template slot-scope="{row}">
+            <el-link :underline="false" v-if="row.status === 0">鎴愬姛</el-link>
+            <el-link type="danger" :underline="false" v-if="row.status === 1">澶辫触</el-link>
           </template>
         </el-table-column>
       </el-table>
@@ -114,6 +90,7 @@
 import TableLayout from '@/layouts/TableLayout'
 import Pagination from '@/components/common/Pagination'
 import OperaJkCabinetLogWindow from '@/components/business/OperaJkCabinetLogWindow'
+import { list } from '@/api/business/jkCabinet'
 export default {
   name: 'JkCabinetLog',
   extends: BaseTable,
@@ -122,23 +99,15 @@
     return {
       // 鎼滅储
       searchForm: {
-        id: '',
-        creator: '',
-        createDate: '',
-        editor: '',
-        editDate: '',
-        isdeleted: '',
-        info: '',
+        endDate: '',
+        startDate: '',
         cabinetId: '',
-        gridId: '',
         authType: '',
-        carId: '',
-        keyId: '',
-        memberId: '',
-        keyInfo: '',
-        roleType: '',
+        memberName: '',
         status: ''
-      }
+      },
+      date: [],
+      keysAll: []
     }
   },
   created () {
@@ -149,6 +118,34 @@
       'field.main': 'id'
     })
     this.search()
+    this.getkeysAll()
+  },
+  methods: {
+    setDate(e) {
+      if (e && e.length > 1) {
+        this.searchForm.startDate = e[0]
+        this.searchForm.endDate = e[1]
+      } else {
+        this.searchForm.startDate = ''
+        this.searchForm.endDate = ''
+      }
+      this.search()
+    },
+    // 鎼滅储妗嗛噸缃�
+    reset () {
+      this.$refs.searchForm.resetFields()
+      this.date = []
+      this.searchForm.startDate = ''
+      this.searchForm.endDate = ''
+      this.search()
+    },
+    getkeysAll() {
+      list({})
+        .then(res => {
+          console.log(res)
+          this.keysAll = res
+        })
+    }
   }
 }
 </script>
diff --git a/admin/src/views/business/jkIccard.vue b/admin/src/views/business/jkIccard.vue
index 3577834..18fbe95 100644
--- a/admin/src/views/business/jkIccard.vue
+++ b/admin/src/views/business/jkIccard.vue
@@ -2,73 +2,63 @@
   <TableLayout :permissions="['business:jkiccard:query']">
     <!-- 鎼滅储琛ㄥ崟 -->
     <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
-      <el-form-item label="涓婚敭" prop="id">
-        <el-input v-model="searchForm.id" placeholder="璇疯緭鍏ヤ富閿�" @keypress.enter.native="search"></el-input>
+      <el-form-item label="鍗″彿" prop="name">
+        <el-input v-model="searchForm.name" placeholder="璇疯緭鍏ュ崱鍙�" @keypress.enter.native="search"></el-input>
       </el-form-item>
-      <el-form-item label="鍒涘缓浜虹紪鐮�" prop="creator">
-        <el-input v-model="searchForm.creator" placeholder="璇疯緭鍏ュ垱寤轰汉缂栫爜" @keypress.enter.native="search"></el-input>
+      <el-form-item label="濮撳悕" prop="memberName">
+        <el-input v-model="searchForm.memberName" placeholder="璇疯緭鍏�" @keypress.enter.native="search"></el-input>
       </el-form-item>
-      <el-form-item label="鍒涘缓鏃堕棿" prop="createDate">
-        <el-date-picker v-model="searchForm.createDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ュ垱寤烘椂闂�" @change="search"/>
+      <el-form-item label="韬唤绫诲瀷" prop="userType">
+        <el-select v-model="searchForm.userType" placeholder="璇烽�夋嫨" @change="search">
+          <el-option label="鍏ㄩ儴" value=""></el-option>
+          <el-option label="鍙告満" :value="0"></el-option>
+          <el-option label="鏍¢獙浜哄憳" :value="1"></el-option>
+        </el-select>
       </el-form-item>
-      <el-form-item label="鏇存柊浜虹紪鐮�" prop="editor">
-        <el-input v-model="searchForm.editor" placeholder="璇疯緭鍏ユ洿鏂颁汉缂栫爜" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鏇存柊鏃堕棿" prop="editDate">
-        <el-date-picker v-model="searchForm.editDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ユ洿鏂版椂闂�" @change="search"/>
-      </el-form-item>
-      <el-form-item label="鏄惁鍒犻櫎0鍚� 1鏄�" prop="isdeleted">
-        <el-input v-model="searchForm.isdeleted" placeholder="璇疯緭鍏ユ槸鍚﹀垹闄�0鍚� 1鏄�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="澶囨敞" prop="info">
-        <el-input v-model="searchForm.info" placeholder="璇疯緭鍏ュ娉�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="浜哄憳缂栫爜缂栫爜锛堝叧鑱攎ember)" prop="memberId">
-        <el-input v-model="searchForm.memberId" placeholder="璇疯緭鍏ヤ汉鍛樼紪鐮佺紪鐮侊紙鍏宠仈member)" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="缂栫爜" prop="code">
-        <el-input v-model="searchForm.code" placeholder="璇疯緭鍏ョ紪鐮�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鐘舵�� 0绂佺敤 1鍚敤" prop="status">
-        <el-input v-model="searchForm.status" placeholder="璇疯緭鍏ョ姸鎬� 0绂佺敤 1鍚敤" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鍗″悕绉�" prop="name">
-        <el-input v-model="searchForm.name" placeholder="璇疯緭鍏ュ崱鍚嶇О" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="閽ュ寵鏌滅紪鐮侊紙鍏宠仈jk_cabinet)" prop="cabinetId">
-        <el-input v-model="searchForm.cabinetId" placeholder="璇疯緭鍏ラ挜鍖欐煖缂栫爜锛堝叧鑱攋k_cabinet)" @keypress.enter.native="search"></el-input>
+      <el-form-item label="鐘舵��" prop="status">
+        <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨" @change="search">
+          <el-option label="鍏ㄩ儴" value=""></el-option>
+          <el-option label="绂佺敤" :value="0"></el-option>
+          <el-option label="鍚敤" :value="1"></el-option>
+        </el-select>
       </el-form-item>
       <section>
         <el-button type="primary" @click="search">鎼滅储</el-button>
-        <el-button type="primary" :loading="isWorking.export" v-permissions="['business:jkiccard:exportExcel']" @click="exportExcel">瀵煎嚭</el-button>
         <el-button @click="reset">閲嶇疆</el-button>
       </section>
     </el-form>
     <!-- 琛ㄦ牸鍜屽垎椤� -->
     <template v-slot:table-wrap>
       <ul class="toolbar" v-permissions="['business:jkiccard:create', 'business:jkiccard:delete']">
-        <li><el-button type="primary" @click="$refs.operaJkIccardWindow.open('鏂板缓閽ュ寵鏌淚C鍗′俊鎭〃')" icon="el-icon-plus" v-permissions="['business:jkiccard:create']">鏂板缓</el-button></li>
-        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:jkiccard:delete']">鍒犻櫎</el-button></li>
+        <li><el-button type="primary" @click="$refs.operaJkIccardWindow.open('鏂板缓IC鍗�')" icon="el-icon-plus" v-permissions="['business:jkiccard:create']">鏂板缓</el-button></li>
       </ul>
       <el-table
+        :height="tableHeightNew"
         v-loading="isWorking.search"
         :data="tableData.list"
         stripe
-        @selection-change="handleSelectionChange"
       >
-        <el-table-column type="selection" width="55"></el-table-column>
-        <el-table-column prop="id" label="涓婚敭" min-width="100px"></el-table-column>
-        <el-table-column prop="creator" label="鍒涘缓浜虹紪鐮�" min-width="100px"></el-table-column>
+        <el-table-column prop="code" label="IC鍗″彿" min-width="100px"></el-table-column>
+        <el-table-column label="韬唤绫诲瀷" min-width="100px">
+          <template slot-scope="{row}">
+            <span v-if="row.userType === 0">鍙告満</span>
+            <span v-if="row.userType === 1">鏍¢獙浜哄憳</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="memberName" label="鍏宠仈浜哄憳" min-width="100px"></el-table-column>
         <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="100px"></el-table-column>
-        <el-table-column prop="editor" label="鏇存柊浜虹紪鐮�" min-width="100px"></el-table-column>
-        <el-table-column prop="editDate" label="鏇存柊鏃堕棿" min-width="100px"></el-table-column>
-        <el-table-column prop="isdeleted" label="鏄惁鍒犻櫎0鍚� 1鏄�" min-width="100px"></el-table-column>
-        <el-table-column prop="info" label="澶囨敞" min-width="100px"></el-table-column>
-        <el-table-column prop="memberId" label="浜哄憳缂栫爜缂栫爜锛堝叧鑱攎ember)" min-width="100px"></el-table-column>
-        <el-table-column prop="code" label="缂栫爜" min-width="100px"></el-table-column>
-        <el-table-column prop="status" label="鐘舵�� 0绂佺敤 1鍚敤" min-width="100px"></el-table-column>
-        <el-table-column prop="name" label="鍗″悕绉�" min-width="100px"></el-table-column>
-        <el-table-column prop="cabinetId" label="閽ュ寵鏌滅紪鐮侊紙鍏宠仈jk_cabinet)" min-width="100px"></el-table-column>
+        <el-table-column label="鐘舵��" min-width="100px">
+          <template slot-scope="{row}">
+            <el-switch
+              v-model="row.status"
+              @change="changeStatus($event, row.id)"
+              active-color="#13ce66"
+              inactive-color="#ff4949"
+              :active-value="1"
+              :inactive-value="0">
+            </el-switch>
+          </template>
+        </el-table-column>
         <el-table-column
           v-if="containPermissions(['business:jkiccard:update', 'business:jkiccard:delete'])"
           label="鎿嶄綔"
@@ -76,7 +66,7 @@
           fixed="right"
         >
           <template slot-scope="{row}">
-            <el-button type="text" @click="$refs.operaJkIccardWindow.open('缂栬緫閽ュ寵鏌淚C鍗′俊鎭〃', row)" icon="el-icon-edit" v-permissions="['business:jkiccard:update']">缂栬緫</el-button>
+            <el-button type="text" @click="$refs.operaJkIccardWindow.open('缂栬緫鏂板缓IC鍗�', row)" icon="el-icon-edit" v-permissions="['business:jkiccard:update']">缂栬緫</el-button>
             <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:jkiccard:delete']">鍒犻櫎</el-button>
           </template>
         </el-table-column>
@@ -98,6 +88,7 @@
 import TableLayout from '@/layouts/TableLayout'
 import Pagination from '@/components/common/Pagination'
 import OperaJkIccardWindow from '@/components/business/OperaJkIccardWindow'
+import { updateStatusById } from '@/api/business/jkIccard'
 export default {
   name: 'JkIccard',
   extends: BaseTable,
@@ -106,18 +97,10 @@
     return {
       // 鎼滅储
       searchForm: {
-        id: '',
-        creator: '',
-        createDate: '',
-        editor: '',
-        editDate: '',
-        isdeleted: '',
-        info: '',
-        memberId: '',
-        code: '',
-        status: '',
         name: '',
-        cabinetId: ''
+        memberName: '',
+        userType: '',
+        status: ''
       }
     }
   },
@@ -129,6 +112,14 @@
       'field.main': 'id'
     })
     this.search()
+  },
+  methods: {
+    changeStatus(status, id) {
+      updateStatusById({ id, status })
+        .then(res => {
+          this.search()
+        })
+    }
   }
 }
 </script>
diff --git a/admin/src/views/business/jkKeys.vue b/admin/src/views/business/jkKeys.vue
index dd82388..23f116e 100644
--- a/admin/src/views/business/jkKeys.vue
+++ b/admin/src/views/business/jkKeys.vue
@@ -2,86 +2,76 @@
   <TableLayout :permissions="['business:jkkeys:query']">
     <!-- 鎼滅储琛ㄥ崟 -->
     <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
-      <el-form-item label="涓婚敭" prop="id">
-        <el-input v-model="searchForm.id" placeholder="璇疯緭鍏ヤ富閿�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鍒涘缓浜虹紪鐮�" prop="creator">
-        <el-input v-model="searchForm.creator" placeholder="璇疯緭鍏ュ垱寤轰汉缂栫爜" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鍒涘缓鏃堕棿" prop="createDate">
-        <el-date-picker v-model="searchForm.createDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ュ垱寤烘椂闂�" @change="search"/>
-      </el-form-item>
-      <el-form-item label="鏇存柊浜虹紪鐮�" prop="editor">
-        <el-input v-model="searchForm.editor" placeholder="璇疯緭鍏ユ洿鏂颁汉缂栫爜" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鏇存柊鏃堕棿" prop="editDate">
-        <el-date-picker v-model="searchForm.editDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ユ洿鏂版椂闂�" @change="search"/>
-      </el-form-item>
-      <el-form-item label="鏄惁鍒犻櫎0鍚� 1鏄�" prop="isdeleted">
-        <el-input v-model="searchForm.isdeleted" placeholder="璇疯緭鍏ユ槸鍚﹀垹闄�0鍚� 1鏄�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="澶囨敞" prop="info">
-        <el-input v-model="searchForm.info" placeholder="璇疯緭鍏ュ娉�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
       <el-form-item label="閽ュ寵缂栧彿" prop="code">
         <el-input v-model="searchForm.code" placeholder="璇疯緭鍏ラ挜鍖欑紪鍙�" @keypress.enter.native="search"></el-input>
       </el-form-item>
-      <el-form-item label="杞︾墝鍙�" prop="carCode">
-        <el-input v-model="searchForm.carCode" placeholder="璇疯緭鍏ヨ溅鐗屽彿" @keypress.enter.native="search"></el-input>
+      <el-form-item label="鎵�灞炶溅杈�" prop="carId">
+        <el-select v-model="searchForm.carId" placeholder="璇烽�夋嫨" @change="search">
+          <el-option
+            v-for="item in carAll"
+            :key="item.id"
+            :label="item.code"
+            :value="item.id">
+          </el-option>
+        </el-select>
       </el-form-item>
-      <el-form-item label="鎵�灞炶溅杈�(鍏宠仈cars)" prop="carId">
-        <el-input v-model="searchForm.carId" placeholder="璇疯緭鍏ユ墍灞炶溅杈�(鍏宠仈cars)" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="RFID鏍囩" prop="rfidLable">
-        <el-input v-model="searchForm.rfidLable" placeholder="璇疯緭鍏FID鏍囩" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="棰嗗彇瑙勫垯 0闅忚溅 1闅忔淳杞﹀崟" prop="roleType">
-        <el-input v-model="searchForm.roleType" placeholder="璇疯緭鍏ラ鍙栬鍒� 0闅忚溅 1闅忔淳杞﹀崟" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭" prop="status">
-        <el-input v-model="searchForm.status" placeholder="璇疯緭鍏ョ姸鎬� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭" @keypress.enter.native="search"></el-input>
+      <el-form-item label="鐘舵��" prop="status">
+        <el-select v-model="searchForm.status" placeholder="璇烽�夋嫨" @change="search">
+          <el-option label="鍏ㄩ儴" value=""></el-option>
+          <el-option label="缁翠慨淇濆吇" :value="3"></el-option>
+          <el-option label="鍊熷嚭" :value="2"></el-option>
+          <el-option label="鍦ㄤ綅" :value="1"></el-option>
+          <el-option label="鏈粦瀹�" :value="0"></el-option>
+        </el-select>
       </el-form-item>
       <section>
         <el-button type="primary" @click="search">鎼滅储</el-button>
-        <el-button type="primary" :loading="isWorking.export" v-permissions="['business:jkkeys:exportExcel']" @click="exportExcel">瀵煎嚭</el-button>
         <el-button @click="reset">閲嶇疆</el-button>
       </section>
     </el-form>
     <!-- 琛ㄦ牸鍜屽垎椤� -->
     <template v-slot:table-wrap>
       <ul class="toolbar" v-permissions="['business:jkkeys:create', 'business:jkkeys:delete']">
-        <li><el-button type="primary" @click="$refs.operaJkKeysWindow.open('鏂板缓閽ュ寵鍩烘湰淇℃伅琛�')" icon="el-icon-plus" v-permissions="['business:jkkeys:create']">鏂板缓</el-button></li>
-        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:jkkeys:delete']">鍒犻櫎</el-button></li>
+        <li><el-button type="primary" @click="$refs.operaJkKeysWindow.open('鏂板缓閽ュ寵淇℃伅')" icon="el-icon-plus" v-permissions="['business:jkkeys:create']">鏂板缓</el-button></li>
+<!--        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:jkkeys:delete']">鍒犻櫎</el-button></li>-->
       </ul>
       <el-table
+        :height="tableHeightNew"
         v-loading="isWorking.search"
         :data="tableData.list"
         stripe
         @selection-change="handleSelectionChange"
       >
         <el-table-column type="selection" width="55"></el-table-column>
-        <el-table-column prop="id" label="涓婚敭" min-width="100px"></el-table-column>
-        <el-table-column prop="creator" label="鍒涘缓浜虹紪鐮�" min-width="100px"></el-table-column>
-        <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="100px"></el-table-column>
-        <el-table-column prop="editor" label="鏇存柊浜虹紪鐮�" min-width="100px"></el-table-column>
-        <el-table-column prop="editDate" label="鏇存柊鏃堕棿" min-width="100px"></el-table-column>
-        <el-table-column prop="isdeleted" label="鏄惁鍒犻櫎0鍚� 1鏄�" min-width="100px"></el-table-column>
-        <el-table-column prop="info" label="澶囨敞" min-width="100px"></el-table-column>
         <el-table-column prop="code" label="閽ュ寵缂栧彿" min-width="100px"></el-table-column>
-        <el-table-column prop="carCode" label="杞︾墝鍙�" min-width="100px"></el-table-column>
-        <el-table-column prop="carId" label="鎵�灞炶溅杈�(鍏宠仈cars)" min-width="100px"></el-table-column>
+        <el-table-column prop="carCode" label="鎵�灞炶溅杈�" min-width="100px"></el-table-column>
         <el-table-column prop="rfidLable" label="RFID鏍囩" min-width="100px"></el-table-column>
-        <el-table-column prop="roleType" label="棰嗗彇瑙勫垯 0闅忚溅 1闅忔淳杞﹀崟" min-width="100px"></el-table-column>
-        <el-table-column prop="status" label="鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭" min-width="100px"></el-table-column>
+        <el-table-column prop="cabinetName" label="缁戝畾閽ュ寵鏌�" min-width="100px"></el-table-column>
+        <el-table-column prop="gridCode" label="瀛樻斁浣嶇疆" min-width="100px"></el-table-column>
+        <el-table-column label="缁戝畾鐘舵��" min-width="100px">
+          <template slot-scope="{row}">
+            <span v-if="row.isBinding === 0">鏈粦瀹�</span>
+            <span v-if="row.isBinding === 1">宸茬粦瀹�</span>
+          </template>
+        </el-table-column>
+        <el-table-column label="閽ュ寵鐘舵��" min-width="100px">
+          <template slot-scope="{row}">
+            <span v-if="row.status === 0">鏈粦瀹�</span>
+            <span v-if="row.status === 1">鍦ㄤ綅</span>
+            <span v-if="row.status === 2">鍊熷嚭</span>
+            <span v-if="row.status === 3">缁翠慨淇濆吇</span>
+          </template>
+        </el-table-column>
         <el-table-column
           v-if="containPermissions(['business:jkkeys:update', 'business:jkkeys:delete'])"
           label="鎿嶄綔"
-          min-width="120"
+          min-width="150"
           fixed="right"
         >
           <template slot-scope="{row}">
-            <el-button type="text" @click="$refs.operaJkKeysWindow.open('缂栬緫閽ュ寵鍩烘湰淇℃伅琛�', row)" icon="el-icon-edit" v-permissions="['business:jkkeys:update']">缂栬緫</el-button>
-            <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:jkkeys:delete']">鍒犻櫎</el-button>
+            <el-button type="text" @click="$refs.borrowingAndReturningRecords.open('鍊熻繕璁板綍', row)">棰嗗彇璁板綍</el-button>
+            <el-button type="text" @click="$refs.operaJkKeysWindow.open('缂栬緫閽ュ寵淇℃伅', row)" v-permissions="['business:jkkeys:update']">缂栬緫</el-button>
+            <el-button type="text" @click="deleteById(row)" v-permissions="['business:jkkeys:delete']">鍒犻櫎</el-button>
           </template>
         </el-table-column>
       </el-table>
@@ -94,6 +84,8 @@
     </template>
     <!-- 鏂板缓/淇敼 -->
     <OperaJkKeysWindow ref="operaJkKeysWindow" @success="handlePageChange"/>
+    <!-- 鍊熻繕璁板綍 -->
+    <BorrowingAndReturningRecords ref="borrowingAndReturningRecords"/>
   </TableLayout>
 </template>
 
@@ -102,28 +94,21 @@
 import TableLayout from '@/layouts/TableLayout'
 import Pagination from '@/components/common/Pagination'
 import OperaJkKeysWindow from '@/components/business/OperaJkKeysWindow'
+import BorrowingAndReturningRecords from '@/components/business/BorrowingAndReturningRecords'
+import { allList } from '@/api/business/cars'
 export default {
   name: 'JkKeys',
   extends: BaseTable,
-  components: { TableLayout, Pagination, OperaJkKeysWindow },
+  components: { TableLayout, Pagination, OperaJkKeysWindow, BorrowingAndReturningRecords },
   data () {
     return {
       // 鎼滅储
       searchForm: {
-        id: '',
-        creator: '',
-        createDate: '',
-        editor: '',
-        editDate: '',
-        isdeleted: '',
-        info: '',
         code: '',
-        carCode: '',
         carId: '',
-        rfidLable: '',
-        roleType: '',
         status: ''
-      }
+      },
+      carAll: []
     }
   },
   created () {
@@ -134,6 +119,15 @@
       'field.main': 'id'
     })
     this.search()
+    this.getCars()
+  },
+  methods: {
+    getCars() {
+      allList({ type: 0 })
+        .then(res => {
+          this.carAll = res
+        })
+    }
   }
 }
 </script>
diff --git a/admin/src/views/business/jkVersion.vue b/admin/src/views/business/jkVersion.vue
index 18e08f8..fc1e505 100644
--- a/admin/src/views/business/jkVersion.vue
+++ b/admin/src/views/business/jkVersion.vue
@@ -2,85 +2,50 @@
   <TableLayout :permissions="['business:jkversion:query']">
     <!-- 鎼滅储琛ㄥ崟 -->
     <el-form ref="searchForm" slot="search-form" :model="searchForm" label-width="100px" inline>
-      <el-form-item label="涓婚敭" prop="id">
-        <el-input v-model="searchForm.id" placeholder="璇疯緭鍏ヤ富閿�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鍒涘缓浜虹紪鐮�" prop="creator">
-        <el-input v-model="searchForm.creator" placeholder="璇疯緭鍏ュ垱寤轰汉缂栫爜" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鍒涘缓鏃堕棿" prop="createDate">
-        <el-date-picker v-model="searchForm.createDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ュ垱寤烘椂闂�" @change="search"/>
-      </el-form-item>
-      <el-form-item label="鏇存柊浜虹紪鐮�" prop="editor">
-        <el-input v-model="searchForm.editor" placeholder="璇疯緭鍏ユ洿鏂颁汉缂栫爜" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鏇存柊鏃堕棿" prop="editDate">
-        <el-date-picker v-model="searchForm.editDate" value-format="yyyy-MM-dd" placeholder="璇疯緭鍏ユ洿鏂版椂闂�" @change="search"/>
-      </el-form-item>
-      <el-form-item label="鏄惁鍒犻櫎0鍚� 1鏄�" prop="isdeleted">
-        <el-input v-model="searchForm.isdeleted" placeholder="璇疯緭鍏ユ槸鍚﹀垹闄�0鍚� 1鏄�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="澶囨敞" prop="info">
-        <el-input v-model="searchForm.info" placeholder="璇疯緭鍏ュ娉�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
       <el-form-item label="鐗堟湰鍙�" prop="versionInfo">
         <el-input v-model="searchForm.versionInfo" placeholder="璇疯緭鍏ョ増鏈彿" @keypress.enter.native="search"></el-input>
       </el-form-item>
-      <el-form-item label="瀹夎鍖呰矾寰�" prop="fileUrl">
-        <el-input v-model="searchForm.fileUrl" placeholder="璇疯緭鍏ュ畨瑁呭寘璺緞" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="瀹夎鐗堝悕绉�" prop="name">
-        <el-input v-model="searchForm.name" placeholder="璇疯緭鍏ュ畨瑁呯増鍚嶇О" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鏇存柊鎻忚堪" prop="content">
-        <el-input v-model="searchForm.content" placeholder="璇疯緭鍏ユ洿鏂版弿杩�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鎺掑簭鐮�" prop="sortnum">
-        <el-input v-model="searchForm.sortnum" placeholder="璇疯緭鍏ユ帓搴忕爜" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鏇存柊鏍囬" prop="title">
-        <el-input v-model="searchForm.title" placeholder="璇疯緭鍏ユ洿鏂版爣棰�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="鏄惁寮哄埗鏇存柊 0鍚� 1鏄�" prop="isForce">
-        <el-input v-model="searchForm.isForce" placeholder="璇疯緭鍏ユ槸鍚﹀己鍒舵洿鏂� 0鍚� 1鏄�" @keypress.enter.native="search"></el-input>
-      </el-form-item>
-      <el-form-item label="骞冲彴绫诲瀷 0Android 1IOS" prop="type">
-        <el-input v-model="searchForm.type" placeholder="璇疯緭鍏ュ钩鍙扮被鍨� 0Android 1IOS" @keypress.enter.native="search"></el-input>
+      <el-form-item label="鏄惁寮哄埗鏇存柊" prop="isForce">
+        <el-select v-model="searchForm.isForce" placeholder="璇烽�夋嫨" @change="search">
+          <el-option label="鍏ㄩ儴" value=""></el-option>
+          <el-option label="鍚�" :value="0"></el-option>
+          <el-option label="鏄�" :value="1"></el-option>
+        </el-select>
       </el-form-item>
       <section>
         <el-button type="primary" @click="search">鎼滅储</el-button>
-        <el-button type="primary" :loading="isWorking.export" v-permissions="['business:jkversion:exportExcel']" @click="exportExcel">瀵煎嚭</el-button>
         <el-button @click="reset">閲嶇疆</el-button>
       </section>
     </el-form>
     <!-- 琛ㄦ牸鍜屽垎椤� -->
     <template v-slot:table-wrap>
       <ul class="toolbar" v-permissions="['business:jkversion:create', 'business:jkversion:delete']">
-        <li><el-button type="primary" @click="$refs.operaJkVersionWindow.open('鏂板缓浜ゆ帶-閽ュ寵鏌滅粓绔増鏈俊鎭〃')" icon="el-icon-plus" v-permissions="['business:jkversion:create']">鏂板缓</el-button></li>
-        <li><el-button @click="deleteByIdInBatch" icon="el-icon-delete" v-permissions="['business:jkversion:delete']">鍒犻櫎</el-button></li>
+        <li><el-button type="primary" @click="$refs.operaJkVersionWindow.open('鏂板缓鐗堟湰')" icon="el-icon-plus" v-permissions="['business:jkversion:create']">鏂板缓</el-button></li>
       </ul>
       <el-table
+        :height="tableHeightNew"
         v-loading="isWorking.search"
         :data="tableData.list"
         stripe
-        @selection-change="handleSelectionChange"
       >
-        <el-table-column type="selection" width="55"></el-table-column>
-        <el-table-column prop="id" label="涓婚敭" min-width="100px"></el-table-column>
-        <el-table-column prop="creator" label="鍒涘缓浜虹紪鐮�" min-width="100px"></el-table-column>
-        <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="100px"></el-table-column>
-        <el-table-column prop="editor" label="鏇存柊浜虹紪鐮�" min-width="100px"></el-table-column>
-        <el-table-column prop="editDate" label="鏇存柊鏃堕棿" min-width="100px"></el-table-column>
-        <el-table-column prop="isdeleted" label="鏄惁鍒犻櫎0鍚� 1鏄�" min-width="100px"></el-table-column>
-        <el-table-column prop="info" label="澶囨敞" min-width="100px"></el-table-column>
         <el-table-column prop="versionInfo" label="鐗堟湰鍙�" min-width="100px"></el-table-column>
-        <el-table-column prop="fileUrl" label="瀹夎鍖呰矾寰�" min-width="100px"></el-table-column>
-        <el-table-column prop="name" label="瀹夎鐗堝悕绉�" min-width="100px"></el-table-column>
+        <el-table-column label="骞冲彴绫诲瀷" min-width="100px">
+          <template slot-scope="{row}">
+            <span v-if="row.type === 0">Android</span>
+            <span v-if="row.type === 1">IOS</span>
+          </template>
+        </el-table-column>
         <el-table-column prop="content" label="鏇存柊鎻忚堪" min-width="100px"></el-table-column>
-        <el-table-column prop="sortnum" label="鎺掑簭鐮�" min-width="100px"></el-table-column>
-        <el-table-column prop="title" label="鏇存柊鏍囬" min-width="100px"></el-table-column>
-        <el-table-column prop="isForce" label="鏄惁寮哄埗鏇存柊 0鍚� 1鏄�" min-width="100px"></el-table-column>
-        <el-table-column prop="type" label="骞冲彴绫诲瀷 0Android 1IOS" min-width="100px"></el-table-column>
+        <el-table-column prop="name" label="瀹夎鍖�" min-width="100px"></el-table-column>
+        <el-table-column prop="name" label="鏂囦欢澶у皬" min-width="100px"></el-table-column>
+        <el-table-column label="鏄惁寮哄埗鏇存柊" min-width="100px">
+          <template slot-scope="{row}">
+            <span v-if="row.isForce === 0">鍚�</span>
+            <span v-if="row.isForce === 1">鏄�</span>
+          </template>
+        </el-table-column>
+        <el-table-column prop="createUserName" label="鍒涘缓鑰�" min-width="100px"></el-table-column>
+        <el-table-column prop="createDate" label="鍒涘缓鏃堕棿" min-width="100px"></el-table-column>
         <el-table-column
           v-if="containPermissions(['business:jkversion:update', 'business:jkversion:delete'])"
           label="鎿嶄綔"
@@ -88,7 +53,7 @@
           fixed="right"
         >
           <template slot-scope="{row}">
-            <el-button type="text" @click="$refs.operaJkVersionWindow.open('缂栬緫浜ゆ帶-閽ュ寵鏌滅粓绔増鏈俊鎭〃', row)" icon="el-icon-edit" v-permissions="['business:jkversion:update']">缂栬緫</el-button>
+            <el-button type="text" @click="$refs.operaJkVersionWindow.open('缂栬緫鐗堟湰', row)" icon="el-icon-edit" v-permissions="['business:jkversion:update']">缂栬緫</el-button>
             <el-button type="text" @click="deleteById(row)" icon="el-icon-delete" v-permissions="['business:jkversion:delete']">鍒犻櫎</el-button>
           </template>
         </el-table-column>
@@ -118,21 +83,8 @@
     return {
       // 鎼滅储
       searchForm: {
-        id: '',
-        creator: '',
-        createDate: '',
-        editor: '',
-        editDate: '',
-        isdeleted: '',
-        info: '',
         versionInfo: '',
-        fileUrl: '',
-        name: '',
-        content: '',
-        sortnum: '',
-        title: '',
-        isForce: '',
-        type: ''
+        isForce: ''
       }
     }
   },
diff --git a/admin/src/views/login.vue b/admin/src/views/login.vue
index 765d208..12a0bb7 100644
--- a/admin/src/views/login.vue
+++ b/admin/src/views/login.vue
@@ -278,7 +278,7 @@
         align-items: center;
         justify-content: center;
         border-radius: 4px;
-        width: 186px;
+        width: 208px;
         display: flex;
         margin-bottom: 12px;
       }
diff --git a/server/system_service/src/main/java/com/doumee/core/utils/Constants.java b/server/system_service/src/main/java/com/doumee/core/utils/Constants.java
index 0d2ca0c..8cc9499 100644
--- a/server/system_service/src/main/java/com/doumee/core/utils/Constants.java
+++ b/server/system_service/src/main/java/com/doumee/core/utils/Constants.java
@@ -55,6 +55,15 @@
     public static final String SIGN_IN_QRCODE_PREFIX ="SIGN_IN_QRCODE_PREFIX" ;
 
 
+    public static final String WEATHER_CONFIG ="WEATHER_CONFIG" ;
+    public static final String REQUEST_URL ="REQUEST_URL" ;
+    public static final String LOCATION ="LOCATION" ;
+    public static final String API_KEY ="API_KEY" ;
+    public static final String CABINET_CONFIG ="CABINET_CONFIG" ;
+    public static final String BLOW_TIME ="BLOW_TIME" ;
+    public static final String PRESSURE ="PRESSURE" ;
+    public static final String CONCENTRATION ="CONCENTRATION" ;
+    public static final String THRESHOLD ="THRESHOLD" ;
     //琚嫓璁夸汉淇℃伅鏍¢獙鏂瑰紡锛�0鎵嬫満鍙峰崟鐙牎楠� 1鎵嬫満鍙峰拰濮撳悕缁勫悎鏍¢獙锛�
     public static final String BEVISITED_USER_VALID = "BEVISITED_USER_VALID";
     public static final String LW_BEVISITED_USER_VALID = "LW_BEVISITED_USER_VALID";
@@ -108,6 +117,7 @@
     public static final String FTP_USERNAME ="FTP_USERNAME" ;
     public static final String FTP_PWD ="FTP_PWD" ;
     public static final String COMPANY_DOCUMENTS ="COMPANY_DOCUMENTS" ;
+    public static final String APP_FILE ="APP_FILE" ;
 
     public static final String FTP_RESOURCE_PATH ="FTP_RESOURCE_PATH" ;
     public static final String FTP_LOCAL_RESOURCE_PATH ="FTP_LOCAL_RESOURCE_PATH" ;
diff --git a/server/system_service/src/main/java/com/doumee/core/utils/WeatherUtil.java b/server/system_service/src/main/java/com/doumee/core/utils/WeatherUtil.java
new file mode 100644
index 0000000..9322a46
--- /dev/null
+++ b/server/system_service/src/main/java/com/doumee/core/utils/WeatherUtil.java
@@ -0,0 +1,29 @@
+package com.doumee.core.utils;
+
+import lombok.extern.slf4j.Slf4j;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @Author : Rk
+ * @create 2025/10/10 11:31
+ */
+@Slf4j
+public class WeatherUtil {
+
+    //API鍦板潃锛� https://dev.qweather.com/docs/api/warning/weather-warning/
+    private static final String apiPath = "/v7/warning/now";
+
+    public  static  String getWeatherWarningInfo(String apiUrl,String apiKey,String location){
+        String url = apiUrl + apiPath + "?key=" + apiKey + "&location=" + location;
+        log.error(DateUtil.getCurrDateTime() + "澶╂皵璇锋眰鍦板潃锛�"+url);
+        String response = HttpsUtil.get(url,false);
+        log.error(DateUtil.getCurrDateTime() + "澶╂皵璇锋眰杩斿洖锛�"+response);
+        return response;
+    }
+
+
+
+
+
+}
diff --git a/server/system_service/src/main/java/com/doumee/dao/business/model/Member.java b/server/system_service/src/main/java/com/doumee/dao/business/model/Member.java
index 50a0bb2..4ea043a 100644
--- a/server/system_service/src/main/java/com/doumee/dao/business/model/Member.java
+++ b/server/system_service/src/main/java/com/doumee/dao/business/model/Member.java
@@ -300,4 +300,9 @@
     @ApiModelProperty(value = "鏄惁鏌ヨ鍥哄畾浜哄憳锛�0=鍚︼紱1=鏄�" )
     @TableField(exist = false)
     private Integer querySpecial;
+
+    @ApiModelProperty(value = "鏄惁鏌ヨ閽ュ寵鏌滄牎楠屼汉鍛橈細0=鍚︼紱1=鏄�" )
+    @TableField(exist = false)
+    private Integer queryAuth;
+
 }
diff --git a/server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java b/server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java
index 6835b17..9ca13c0 100644
--- a/server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java
+++ b/server/system_timer/src/main/java/com/doumee/jobs/fegin/VisitServiceFegin.java
@@ -103,5 +103,11 @@
     @PostMapping("/timer/platformJob/sendUnFinishNotice")
     ApiResponse sendUnFinishNotice();
 
+    @ApiOperation("銆愰拤閽夋暟鎹�戦拤閽塼oken瀹氭椂鍣ㄦ帴鍙�")
+    @PostMapping("/timer/dingTalkToken/updateDingTalkTokenOrigin")
+    ApiResponse updateDingTalkTokenOrigin() throws Exception;
 
+    @ApiOperation("銆愬ぉ姘斾俊鎭�戝畾鏃跺悓姝ュぉ姘旈璀�")
+    @PostMapping("/timer/weather/syncWeatherInfo")
+    ApiResponse syncWeatherInfo();
 }
diff --git a/server/visits/admin_timer/src/main/java/com/doumee/api/DingTalkTokenTimerController.java b/server/visits/admin_timer/src/main/java/com/doumee/api/DingTalkTokenTimerController.java
new file mode 100644
index 0000000..6c3d90c
--- /dev/null
+++ b/server/visits/admin_timer/src/main/java/com/doumee/api/DingTalkTokenTimerController.java
@@ -0,0 +1,56 @@
+package com.doumee.api;
+
+import com.alibaba.fastjson.JSONObject;
+import com.doumee.biz.system.SystemDictDataBiz;
+import com.doumee.core.dingTalk.DingTalk;
+import com.doumee.core.utils.Constants;
+import com.doumee.core.utils.HttpsUtil;
+import com.doumee.core.wx.WXConstant;
+import com.doumee.dao.system.model.SystemDictData;
+import com.doumee.service.business.third.model.ApiResponse;
+import com.doumee.service.system.SystemDictDataService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.mgt.DefaultSecurityManager;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+import java.util.Date;
+import java.util.Objects;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/30 15:33
+ */
+@Api(tags = "閽夐拤token瀹氭椂鍣ㄦ帴鍙�")
+@RestController
+@RequestMapping("/timer/dingTalkToken")
+public class DingTalkTokenTimerController extends BaseController {
+    @Autowired
+    private SystemDictDataBiz systemDictDataBiz;
+
+    @Autowired
+    private SystemDictDataService systemDictDataService;
+
+    @Autowired
+    private DingTalk dingTalk;
+    /**
+     * 鏄惁寮�鍙戣��
+     */
+    @Value("${debug_model}")
+    private Boolean timing;
+
+    @ApiOperation("寮�鍚畾鏃舵洿鏂伴拤閽変笟鍔oken")
+    @PostMapping("/updateDingTalkTokenOrigin")
+    public ApiResponse updateDingTalkTokenOrigin() throws Exception {
+        dingTalk.updTokenInfo();
+        return ApiResponse.success("寮�鍚畾鏃舵洿鏂板井淇″叕浼楀彿accesstoken鎴愬姛");
+    }
+
+
+
+}
diff --git a/server/visits/admin_timer/src/main/java/com/doumee/api/WeatherTimerController.java b/server/visits/admin_timer/src/main/java/com/doumee/api/WeatherTimerController.java
new file mode 100644
index 0000000..0b1a90b
--- /dev/null
+++ b/server/visits/admin_timer/src/main/java/com/doumee/api/WeatherTimerController.java
@@ -0,0 +1,42 @@
+package com.doumee.api;
+
+import com.doumee.biz.system.SystemDictDataBiz;
+import com.doumee.core.dingTalk.DingTalk;
+import com.doumee.service.business.WarningService;
+import com.doumee.service.business.third.model.ApiResponse;
+import com.doumee.service.system.SystemDictDataService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * @author 姹熻箘韫�
+ * @date 2023/11/30 15:33
+ */
+@Api(tags = "澶╂皵棰勮鍚屾")
+@RestController
+@RequestMapping("/timer/weather")
+public class WeatherTimerController extends BaseController {
+    @Autowired
+    private WarningService warningService;
+
+    /**
+     * 鏄惁寮�鍙戣��
+     */
+    @Value("${debug_model}")
+    private Boolean timing;
+
+    @ApiOperation("瀹氭椂鍚屾澶╂皵棰勮淇℃伅")
+    @PostMapping("/syncWeatherInfo")
+    public ApiResponse syncWeatherInfo(){
+        warningService.getWeatherInfo();
+        return ApiResponse.success("瀹氭椂鍚屾澶╂皵棰勮淇℃伅");
+    }
+
+
+
+}
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetCloudController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetCloudController.java
index 5000734..a51a381 100644
--- a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetCloudController.java
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetCloudController.java
@@ -6,6 +6,7 @@
 import com.doumee.core.annotation.pr.PreventRepeat;
 import com.doumee.core.utils.Constants;
 import com.doumee.dao.business.model.JkCabinet;
+import com.doumee.dao.business.vo.CabinetConfigDataVO;
 import com.doumee.service.business.JkCabinetService;
 import com.doumee.service.business.third.model.ApiResponse;
 import com.doumee.service.business.third.model.PageData;
@@ -35,57 +36,81 @@
     @ApiOperation("鏂板缓")
     @PostMapping("/create")
     @CloudRequiredPermission("business:jkcabinet:create")
-    public ApiResponse create(@RequestBody JkCabinet jkCabinet) {
+    public ApiResponse create(@RequestBody JkCabinet jkCabinet,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkCabinet.setLoginUserInfo(this.getLoginUser(token));
         return ApiResponse.success(jkCabinetService.create(jkCabinet));
     }
 
     @ApiOperation("鏍规嵁ID鍒犻櫎")
     @GetMapping("/delete/{id}")
     @CloudRequiredPermission("business:jkcabinet:delete")
-    public ApiResponse deleteById(@PathVariable Integer id) {
+    public ApiResponse deleteById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         jkCabinetService.deleteById(id);
         return ApiResponse.success(null);
     }
 
-    @ApiOperation("鎵归噺鍒犻櫎")
-    @GetMapping("/delete/batch")
-    @CloudRequiredPermission("business:jkcabinet:delete")
-    public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
-        String [] idArray = ids.split(",");
-        List<Integer> idList = new ArrayList<>();
-        for (String id : idArray) {
-            idList.add(Integer.valueOf(id));
-        }
-        jkCabinetService.deleteByIdInBatch(idList);
-        return ApiResponse.success(null);
-    }
 
     @ApiOperation("鏍规嵁ID淇敼")
     @PostMapping("/updateById")
     @CloudRequiredPermission("business:jkcabinet:update")
-    public ApiResponse updateById(@RequestBody JkCabinet jkCabinet) {
+    public ApiResponse updateById(@RequestBody JkCabinet jkCabinet,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkCabinet.setLoginUserInfo(this.getLoginUser(token));
         jkCabinetService.updateById(jkCabinet);
+        return ApiResponse.success(null);
+    }
+
+    @ApiOperation("鏍规嵁ID淇敼鐘舵��")
+    @PostMapping("/updateStatusById")
+    @CloudRequiredPermission("business:jkcabinet:update")
+    public ApiResponse updateStatusById(@RequestBody JkCabinet jkCabinet,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkCabinet.setLoginUserInfo(this.getLoginUser(token));
+        jkCabinetService.updateStatusById(jkCabinet);
         return ApiResponse.success(null);
     }
 
     @ApiOperation("鍒嗛〉鏌ヨ")
     @PostMapping("/page")
     @CloudRequiredPermission("business:jkcabinet:query")
-    public ApiResponse<PageData<JkCabinet>> findPage (@RequestBody PageWrap<JkCabinet> pageWrap) {
+    public ApiResponse<PageData<JkCabinet>> findPage (@RequestBody PageWrap<JkCabinet> pageWrap,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkCabinetService.findPage(pageWrap));
     }
+
+    @ApiOperation("鍒楄〃鏌ヨ")
+    @PostMapping("/list")
+    @CloudRequiredPermission("business:jkcabinet:query")
+    public ApiResponse<List<JkCabinet>> findList (@RequestBody JkCabinet jkCabinet,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        return ApiResponse.success(jkCabinetService.findList(jkCabinet));
+    }
+
 
     @ApiOperation("瀵煎嚭Excel")
     @PostMapping("/exportExcel")
     @CloudRequiredPermission("business:jkcabinet:exportExcel")
-    public void exportExcel (@RequestBody PageWrap<JkCabinet> pageWrap, HttpServletResponse response) {
+    public void exportExcel (@RequestBody PageWrap<JkCabinet> pageWrap, HttpServletResponse response,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         ExcelExporter.build(JkCabinet.class).export(jkCabinetService.findPage(pageWrap).getRecords(), "閽ュ寵鏌滃熀鏈俊鎭〃", response);
     }
 
     @ApiOperation("鏍规嵁ID鏌ヨ")
     @GetMapping("/{id}")
     @CloudRequiredPermission("business:jkcabinet:query")
-    public ApiResponse findById(@PathVariable Integer id) {
-        return ApiResponse.success(jkCabinetService.findById(id));
+    public ApiResponse findById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        return ApiResponse.success(jkCabinetService.getDetail(id));
     }
+
+    @ApiOperation("鏇存柊閰掔簿妫�娴嬮厤缃�")
+    @PostMapping("/updateCabinetConfig")
+    @CloudRequiredPermission("business:jkcabinet:update")
+    public ApiResponse updateCabinetConfig(@RequestBody CabinetConfigDataVO cabinetConfigDataVO, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkCabinetService.updCabinetConfig(cabinetConfigDataVO);
+        return ApiResponse.success(null);
+    }
+
+
+    @ApiOperation("鑾峰彇閰掔簿妫�娴嬮厤缃�")
+    @GetMapping("/getCabinetConfig")
+    @CloudRequiredPermission("business:jkcabinet:query")
+    public ApiResponse<CabinetConfigDataVO> getCabinetConfig( @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        return ApiResponse.success(jkCabinetService.getCabinetConfigDataVO());
+    }
+
 }
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetGridCloudController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetGridCloudController.java
index 0b9de85..2bbca3c 100644
--- a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetGridCloudController.java
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetGridCloudController.java
@@ -6,6 +6,7 @@
 import com.doumee.core.annotation.pr.PreventRepeat;
 import com.doumee.core.utils.Constants;
 import com.doumee.dao.business.model.JkCabinetGrid;
+import com.doumee.dao.business.model.JkIccard;
 import com.doumee.service.business.JkCabinetGridService;
 import com.doumee.service.business.third.model.ApiResponse;
 import com.doumee.service.business.third.model.PageData;
@@ -35,14 +36,14 @@
     @ApiOperation("鏂板缓")
     @PostMapping("/create")
     @CloudRequiredPermission("business:jkcabinetgrid:create")
-    public ApiResponse create(@RequestBody JkCabinetGrid jkCabinetGrid) {
+    public ApiResponse create(@RequestBody JkCabinetGrid jkCabinetGrid,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkCabinetGridService.create(jkCabinetGrid));
     }
 
     @ApiOperation("鏍规嵁ID鍒犻櫎")
     @GetMapping("/delete/{id}")
     @CloudRequiredPermission("business:jkcabinetgrid:delete")
-    public ApiResponse deleteById(@PathVariable Integer id) {
+    public ApiResponse deleteById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         jkCabinetGridService.deleteById(id);
         return ApiResponse.success(null);
     }
@@ -50,7 +51,7 @@
     @ApiOperation("鎵归噺鍒犻櫎")
     @GetMapping("/delete/batch")
     @CloudRequiredPermission("business:jkcabinetgrid:delete")
-    public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+    public ApiResponse deleteByIdInBatch(@RequestParam String ids,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         String [] idArray = ids.split(",");
         List<Integer> idList = new ArrayList<>();
         for (String id : idArray) {
@@ -63,29 +64,53 @@
     @ApiOperation("鏍规嵁ID淇敼")
     @PostMapping("/updateById")
     @CloudRequiredPermission("business:jkcabinetgrid:update")
-    public ApiResponse updateById(@RequestBody JkCabinetGrid jkCabinetGrid) {
+    public ApiResponse updateById(@RequestBody JkCabinetGrid jkCabinetGrid,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkCabinetGrid.setLoginUserInfo(getLoginUser(token));
         jkCabinetGridService.updateById(jkCabinetGrid);
+        return ApiResponse.success(null);
+    }
+
+
+    @ApiOperation("鏍规嵁ID淇敼鐘舵��")
+    @PostMapping("/updateStatusById")
+    @CloudRequiredPermission("business:jkcabinetgrid:update")
+    public ApiResponse updateStatusById(@RequestBody JkCabinetGrid jkCabinetGrid, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkCabinetGrid.setLoginUserInfo(this.getLoginUser(token));
+        jkCabinetGridService.updateStatusById(jkCabinetGrid);
+        return ApiResponse.success(null);
+    }
+
+
+    @ApiOperation("瑙g粦閽ュ寵")
+    @PostMapping("/unBindKeys")
+    @CloudRequiredPermission("business:jkcabinetgrid:update")
+    public ApiResponse unBindKeys(@RequestBody List<Integer> idList, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkCabinetGridService.unBindKeys(idList);
         return ApiResponse.success(null);
     }
 
     @ApiOperation("鍒嗛〉鏌ヨ")
     @PostMapping("/page")
     @CloudRequiredPermission("business:jkcabinetgrid:query")
-    public ApiResponse<PageData<JkCabinetGrid>> findPage (@RequestBody PageWrap<JkCabinetGrid> pageWrap) {
+    public ApiResponse<PageData<JkCabinetGrid>> findPage (@RequestBody PageWrap<JkCabinetGrid> pageWrap,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkCabinetGridService.findPage(pageWrap));
     }
 
     @ApiOperation("瀵煎嚭Excel")
     @PostMapping("/exportExcel")
     @CloudRequiredPermission("business:jkcabinetgrid:exportExcel")
-    public void exportExcel (@RequestBody PageWrap<JkCabinetGrid> pageWrap, HttpServletResponse response) {
+    public void exportExcel (@RequestBody PageWrap<JkCabinetGrid> pageWrap, HttpServletResponse response,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         ExcelExporter.build(JkCabinetGrid.class).export(jkCabinetGridService.findPage(pageWrap).getRecords(), "閽ュ寵鏌滄煖鏍煎熀鏈俊鎭〃", response);
     }
 
     @ApiOperation("鏍规嵁ID鏌ヨ")
     @GetMapping("/{id}")
     @CloudRequiredPermission("business:jkcabinetgrid:query")
-    public ApiResponse findById(@PathVariable Integer id) {
+    public ApiResponse findById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkCabinetGridService.findById(id));
     }
+
+
+
+
 }
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetLogCloudController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetLogCloudController.java
index 0299c8e..b0dbcb2 100644
--- a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetLogCloudController.java
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkCabinetLogCloudController.java
@@ -35,14 +35,14 @@
     @ApiOperation("鏂板缓")
     @PostMapping("/create")
     @CloudRequiredPermission("business:jkcabinetlog:create")
-    public ApiResponse create(@RequestBody JkCabinetLog jkCabinetLog) {
+    public ApiResponse create(@RequestBody JkCabinetLog jkCabinetLog,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkCabinetLogService.create(jkCabinetLog));
     }
 
     @ApiOperation("鏍规嵁ID鍒犻櫎")
     @GetMapping("/delete/{id}")
     @CloudRequiredPermission("business:jkcabinetlog:delete")
-    public ApiResponse deleteById(@PathVariable Integer id) {
+    public ApiResponse deleteById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         jkCabinetLogService.deleteById(id);
         return ApiResponse.success(null);
     }
@@ -50,7 +50,7 @@
     @ApiOperation("鎵归噺鍒犻櫎")
     @GetMapping("/delete/batch")
     @CloudRequiredPermission("business:jkcabinetlog:delete")
-    public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+    public ApiResponse deleteByIdInBatch(@RequestParam String ids,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         String [] idArray = ids.split(",");
         List<Integer> idList = new ArrayList<>();
         for (String id : idArray) {
@@ -63,7 +63,7 @@
     @ApiOperation("鏍规嵁ID淇敼")
     @PostMapping("/updateById")
     @CloudRequiredPermission("business:jkcabinetlog:update")
-    public ApiResponse updateById(@RequestBody JkCabinetLog jkCabinetLog) {
+    public ApiResponse updateById(@RequestBody JkCabinetLog jkCabinetLog,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         jkCabinetLogService.updateById(jkCabinetLog);
         return ApiResponse.success(null);
     }
@@ -71,21 +71,21 @@
     @ApiOperation("鍒嗛〉鏌ヨ")
     @PostMapping("/page")
     @CloudRequiredPermission("business:jkcabinetlog:query")
-    public ApiResponse<PageData<JkCabinetLog>> findPage (@RequestBody PageWrap<JkCabinetLog> pageWrap) {
+    public ApiResponse<PageData<JkCabinetLog>> findPage (@RequestBody PageWrap<JkCabinetLog> pageWrap,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkCabinetLogService.findPage(pageWrap));
     }
 
     @ApiOperation("瀵煎嚭Excel")
     @PostMapping("/exportExcel")
     @CloudRequiredPermission("business:jkcabinetlog:exportExcel")
-    public void exportExcel (@RequestBody PageWrap<JkCabinetLog> pageWrap, HttpServletResponse response) {
-        ExcelExporter.build(JkCabinetLog.class).export(jkCabinetLogService.findPage(pageWrap).getRecords(), "閽ュ寵鏌滃紑鍏抽棬璁板綍", response);
+    public void exportExcel (@RequestBody PageWrap<JkCabinetLog> pageWrap, HttpServletResponse response,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        ExcelExporter.build(JkCabinetLog.class).export(jkCabinetLogService.findPage(pageWrap).getRecords(), "閽ュ寵鏌滃紑鍏抽棬璁板綍_"+System.currentTimeMillis(), response);
     }
 
     @ApiOperation("鏍规嵁ID鏌ヨ")
     @GetMapping("/{id}")
     @CloudRequiredPermission("business:jkcabinetlog:query")
-    public ApiResponse findById(@PathVariable Integer id) {
+    public ApiResponse findById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkCabinetLogService.findById(id));
     }
 }
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkIccardCloudController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkIccardCloudController.java
index c8657a1..0639ce6 100644
--- a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkIccardCloudController.java
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkIccardCloudController.java
@@ -5,6 +5,7 @@
 import com.doumee.core.annotation.excel.ExcelExporter;
 import com.doumee.core.annotation.pr.PreventRepeat;
 import com.doumee.core.utils.Constants;
+import com.doumee.dao.business.model.JkCabinet;
 import com.doumee.dao.business.model.JkIccard;
 import com.doumee.service.business.JkIccardService;
 import com.doumee.service.business.third.model.ApiResponse;
@@ -35,14 +36,15 @@
     @ApiOperation("鏂板缓")
     @PostMapping("/create")
     @CloudRequiredPermission("business:jkiccard:create")
-    public ApiResponse create(@RequestBody JkIccard jkIccard) {
+    public ApiResponse create(@RequestBody JkIccard jkIccard,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkIccard.setLoginUserInfo(getLoginUser(token));
         return ApiResponse.success(jkIccardService.create(jkIccard));
     }
 
     @ApiOperation("鏍规嵁ID鍒犻櫎")
     @GetMapping("/delete/{id}")
     @CloudRequiredPermission("business:jkiccard:delete")
-    public ApiResponse deleteById(@PathVariable Integer id) {
+    public ApiResponse deleteById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         jkIccardService.deleteById(id);
         return ApiResponse.success(null);
     }
@@ -50,7 +52,7 @@
     @ApiOperation("鎵归噺鍒犻櫎")
     @GetMapping("/delete/batch")
     @CloudRequiredPermission("business:jkiccard:delete")
-    public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+    public ApiResponse deleteByIdInBatch(@RequestParam String ids,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         String [] idArray = ids.split(",");
         List<Integer> idList = new ArrayList<>();
         for (String id : idArray) {
@@ -63,29 +65,40 @@
     @ApiOperation("鏍规嵁ID淇敼")
     @PostMapping("/updateById")
     @CloudRequiredPermission("business:jkiccard:update")
-    public ApiResponse updateById(@RequestBody JkIccard jkIccard) {
+    public ApiResponse updateById(@RequestBody JkIccard jkIccard,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkIccard.setLoginUserInfo(getLoginUser(token));
         jkIccardService.updateById(jkIccard);
+        return ApiResponse.success(null);
+    }
+
+
+    @ApiOperation("鏍规嵁ID淇敼鐘舵��")
+    @PostMapping("/updateStatusById")
+    @CloudRequiredPermission("business:jkiccard:update")
+    public ApiResponse updateStatusById(@RequestBody JkIccard jkIccard, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkIccard.setLoginUserInfo(this.getLoginUser(token));
+        jkIccardService.updateStatusById(jkIccard);
         return ApiResponse.success(null);
     }
 
     @ApiOperation("鍒嗛〉鏌ヨ")
     @PostMapping("/page")
     @CloudRequiredPermission("business:jkiccard:query")
-    public ApiResponse<PageData<JkIccard>> findPage (@RequestBody PageWrap<JkIccard> pageWrap) {
+    public ApiResponse<PageData<JkIccard>> findPage (@RequestBody PageWrap<JkIccard> pageWrap,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkIccardService.findPage(pageWrap));
     }
 
     @ApiOperation("瀵煎嚭Excel")
     @PostMapping("/exportExcel")
     @CloudRequiredPermission("business:jkiccard:exportExcel")
-    public void exportExcel (@RequestBody PageWrap<JkIccard> pageWrap, HttpServletResponse response) {
+    public void exportExcel (@RequestBody PageWrap<JkIccard> pageWrap, HttpServletResponse response,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         ExcelExporter.build(JkIccard.class).export(jkIccardService.findPage(pageWrap).getRecords(), "閽ュ寵鏌淚C鍗′俊鎭〃", response);
     }
 
     @ApiOperation("鏍规嵁ID鏌ヨ")
     @GetMapping("/{id}")
     @CloudRequiredPermission("business:jkiccard:query")
-    public ApiResponse findById(@PathVariable Integer id) {
+    public ApiResponse findById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkIccardService.findById(id));
     }
 }
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkKeysCloudController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkKeysCloudController.java
index 4fe9b33..b814911 100644
--- a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkKeysCloudController.java
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkKeysCloudController.java
@@ -5,6 +5,7 @@
 import com.doumee.core.annotation.excel.ExcelExporter;
 import com.doumee.core.annotation.pr.PreventRepeat;
 import com.doumee.core.utils.Constants;
+import com.doumee.dao.business.model.JkCabinet;
 import com.doumee.dao.business.model.JkKeys;
 import com.doumee.service.business.JkKeysService;
 import com.doumee.service.business.third.model.ApiResponse;
@@ -35,14 +36,15 @@
     @ApiOperation("鏂板缓")
     @PostMapping("/create")
     @CloudRequiredPermission("business:jkkeys:create")
-    public ApiResponse create(@RequestBody JkKeys jkKeys) {
+    public ApiResponse create(@RequestBody JkKeys jkKeys,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkKeys.setLoginUserInfo(this.getLoginUser(token));
         return ApiResponse.success(jkKeysService.create(jkKeys));
     }
 
     @ApiOperation("鏍规嵁ID鍒犻櫎")
     @GetMapping("/delete/{id}")
     @CloudRequiredPermission("business:jkkeys:delete")
-    public ApiResponse deleteById(@PathVariable Integer id) {
+    public ApiResponse deleteById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         jkKeysService.deleteById(id);
         return ApiResponse.success(null);
     }
@@ -50,7 +52,7 @@
     @ApiOperation("鎵归噺鍒犻櫎")
     @GetMapping("/delete/batch")
     @CloudRequiredPermission("business:jkkeys:delete")
-    public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+    public ApiResponse deleteByIdInBatch(@RequestParam String ids,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         String [] idArray = ids.split(",");
         List<Integer> idList = new ArrayList<>();
         for (String id : idArray) {
@@ -63,7 +65,8 @@
     @ApiOperation("鏍规嵁ID淇敼")
     @PostMapping("/updateById")
     @CloudRequiredPermission("business:jkkeys:update")
-    public ApiResponse updateById(@RequestBody JkKeys jkKeys) {
+    public ApiResponse updateById(@RequestBody JkKeys jkKeys,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkKeys.setLoginUserInfo(this.getLoginUser(token));
         jkKeysService.updateById(jkKeys);
         return ApiResponse.success(null);
     }
@@ -71,21 +74,29 @@
     @ApiOperation("鍒嗛〉鏌ヨ")
     @PostMapping("/page")
     @CloudRequiredPermission("business:jkkeys:query")
-    public ApiResponse<PageData<JkKeys>> findPage (@RequestBody PageWrap<JkKeys> pageWrap) {
+    public ApiResponse<PageData<JkKeys>> findPage (@RequestBody PageWrap<JkKeys> pageWrap,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkKeysService.findPage(pageWrap));
     }
+
+    @ApiOperation("鍒楄〃鏌ヨ")
+    @PostMapping("/list")
+    @CloudRequiredPermission("business:jkkeys:query")
+    public ApiResponse<List<JkKeys>> findList (@RequestBody JkKeys jkKeys, @RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        return ApiResponse.success(jkKeysService.findList(jkKeys));
+    }
+
 
     @ApiOperation("瀵煎嚭Excel")
     @PostMapping("/exportExcel")
     @CloudRequiredPermission("business:jkkeys:exportExcel")
-    public void exportExcel (@RequestBody PageWrap<JkKeys> pageWrap, HttpServletResponse response) {
+    public void exportExcel (@RequestBody PageWrap<JkKeys> pageWrap, HttpServletResponse response,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         ExcelExporter.build(JkKeys.class).export(jkKeysService.findPage(pageWrap).getRecords(), "閽ュ寵鍩烘湰淇℃伅琛�", response);
     }
 
     @ApiOperation("鏍规嵁ID鏌ヨ")
     @GetMapping("/{id}")
     @CloudRequiredPermission("business:jkkeys:query")
-    public ApiResponse findById(@PathVariable Integer id) {
+    public ApiResponse findById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkKeysService.findById(id));
     }
 }
diff --git a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkVersionCloudController.java b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkVersionCloudController.java
index ef9edbc..c099b4a 100644
--- a/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkVersionCloudController.java
+++ b/server/visits/dmvisit_admin/src/main/java/com/doumee/cloud/admin/JkVersionCloudController.java
@@ -35,14 +35,15 @@
     @ApiOperation("鏂板缓")
     @PostMapping("/create")
     @CloudRequiredPermission("business:jkversion:create")
-    public ApiResponse create(@RequestBody JkVersion jkVersion) {
+    public ApiResponse create(@RequestBody JkVersion jkVersion,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkVersion.setLoginUserInfo(this.getLoginUser(token));
         return ApiResponse.success(jkVersionService.create(jkVersion));
     }
 
     @ApiOperation("鏍规嵁ID鍒犻櫎")
     @GetMapping("/delete/{id}")
     @CloudRequiredPermission("business:jkversion:delete")
-    public ApiResponse deleteById(@PathVariable Integer id) {
+    public ApiResponse deleteById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         jkVersionService.deleteById(id);
         return ApiResponse.success(null);
     }
@@ -50,7 +51,7 @@
     @ApiOperation("鎵归噺鍒犻櫎")
     @GetMapping("/delete/batch")
     @CloudRequiredPermission("business:jkversion:delete")
-    public ApiResponse deleteByIdInBatch(@RequestParam String ids) {
+    public ApiResponse deleteByIdInBatch(@RequestParam String ids,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         String [] idArray = ids.split(",");
         List<Integer> idList = new ArrayList<>();
         for (String id : idArray) {
@@ -63,7 +64,8 @@
     @ApiOperation("鏍规嵁ID淇敼")
     @PostMapping("/updateById")
     @CloudRequiredPermission("business:jkversion:update")
-    public ApiResponse updateById(@RequestBody JkVersion jkVersion) {
+    public ApiResponse updateById(@RequestBody JkVersion jkVersion,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
+        jkVersion.setLoginUserInfo(this.getLoginUser(token));
         jkVersionService.updateById(jkVersion);
         return ApiResponse.success(null);
     }
@@ -71,21 +73,21 @@
     @ApiOperation("鍒嗛〉鏌ヨ")
     @PostMapping("/page")
     @CloudRequiredPermission("business:jkversion:query")
-    public ApiResponse<PageData<JkVersion>> findPage (@RequestBody PageWrap<JkVersion> pageWrap) {
+    public ApiResponse<PageData<JkVersion>> findPage (@RequestBody PageWrap<JkVersion> pageWrap,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkVersionService.findPage(pageWrap));
     }
 
     @ApiOperation("瀵煎嚭Excel")
     @PostMapping("/exportExcel")
     @CloudRequiredPermission("business:jkversion:exportExcel")
-    public void exportExcel (@RequestBody PageWrap<JkVersion> pageWrap, HttpServletResponse response) {
+    public void exportExcel (@RequestBody PageWrap<JkVersion> pageWrap, HttpServletResponse response,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         ExcelExporter.build(JkVersion.class).export(jkVersionService.findPage(pageWrap).getRecords(), "浜ゆ帶-閽ュ寵鏌滅粓绔増鏈俊鎭〃", response);
     }
 
     @ApiOperation("鏍规嵁ID鏌ヨ")
     @GetMapping("/{id}")
     @CloudRequiredPermission("business:jkversion:query")
-    public ApiResponse findById(@PathVariable Integer id) {
+    public ApiResponse findById(@PathVariable Integer id,@RequestHeader(Constants.HEADER_USER_TOKEN) String token) {
         return ApiResponse.success(jkVersionService.findById(id));
     }
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/core/dingTalk/DingTalk.java b/server/visits/dmvisit_service/src/main/java/com/doumee/core/dingTalk/DingTalk.java
index 0f41075..84273d6 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/core/dingTalk/DingTalk.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/core/dingTalk/DingTalk.java
@@ -373,20 +373,26 @@
      * api 鍦板潃 https://open.dingtalk.com/document/orgapp/asynchronous-sending-of-enterprise-session-messages
      * @throws ApiException
      */
-    public void workInfoOANotice(Long agentId,String userIds,OapiMessageCorpconversationAsyncsendV2Request.Msg msg)throws ApiException {
-        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
-        OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
-        request.setAgentId(agentId);
-        request.setUseridList(userIds);
-        request.setToAllUser(false);
+    public Boolean workInfoOANotice(Long agentId,String userIds,OapiMessageCorpconversationAsyncsendV2Request.Msg msg){
+        try{
+            DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/message/corpconversation/asyncsend_v2");
+            OapiMessageCorpconversationAsyncsendV2Request request = new OapiMessageCorpconversationAsyncsendV2Request();
+            request.setAgentId(agentId);
+            request.setUseridList(userIds);
+            request.setToAllUser(false);
 
-        request.setMsg(msg);
-        OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(request, "60c2df248ca93d4eafb4a04a2330d3d3");//getToken());
-        if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
+            request.setMsg(msg);
+            OapiMessageCorpconversationAsyncsendV2Response rsp = client.execute(request, "60c2df248ca93d4eafb4a04a2330d3d3");//getToken());
+            if(rsp.getErrcode().equals(Constants.DD_ERR_CODE)){
+                return true;
+            }else{
+                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
+            }
+        }catch (ApiException apiException){
 
-        }else{
-            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),rsp.getMessage());
         }
+        return false;
+
     }
 
 
@@ -532,79 +538,83 @@
      * unionIdList 寰呭姙閫氱煡浜哄憳闆嗗悎
      * @throws Exception
      */
-    public String toDoNotice(String title,List<String> unionIdList,List<CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList> fieldList) throws Exception {
-        com.aliyun.dingtalktodo_1_0.Client client = DingTalk.createV1Client();
-        CreateTodoTaskHeaders createTodoTaskHeaders = new CreateTodoTaskHeaders();
-        createTodoTaskHeaders.xAcsDingtalkAccessToken = "43cf8213909f34ef81e7447905b822fb";//getToken();
-        //寰呭姙鎴鍓嶇殑鎻愰啋
-        CreateTodoTaskRequest.CreateTodoTaskRequestRemindNotifyConfigs remindNotifyConfigs = new CreateTodoTaskRequest.CreateTodoTaskRequestRemindNotifyConfigs()
-                .setDingNotify("1")
-                .setSendTodoApn("true");
-        //寰呭姙閫氱煡閰嶇疆
-        CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs notifyConfigs = new CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs()
-                .setDingNotify("1")
-                .setSendTodoApn("true")
-                .setSendAssistantChat("true");
-        //鎸夐挳浜嬩欢
-        CreateTodoTaskRequest.CreateTodoTaskRequestActionListParam actionList0Param = new CreateTodoTaskRequest.CreateTodoTaskRequestActionListParam()
-                .setBody("");
-        CreateTodoTaskRequest.CreateTodoTaskRequestActionList actionList0 = new CreateTodoTaskRequest.CreateTodoTaskRequestActionList()
-                .setTitle("鍘诲鐞�")
-                .setActionType(2)
-                .setParam(actionList0Param)
-                .setUrl("https://www.baidu.com") //TODO 璇︽儏鍦板潃
-                .setActionKey("ak-1-1");
-        //璇︽儏椤祏rl璺宠浆鍦板潃
-        CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl detailUrl = new CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl()
-                .setAppUrl("https://www.baidu.com")
-                .setPcUrl("https://www.baidu.com");
-        CreateTodoTaskRequest createTodoTaskRequest = new CreateTodoTaskRequest()
-                .setSubject(title)
-                .setCreatorId(unionIdList.get(Constants.ZERO))
-                .setDescription(title)
-                .setExecutorIds(unionIdList)
-                .setDetailUrl(detailUrl)
-                .setContentFieldList(fieldList)
-                .setIsOnlyShowExecutor(true)
-                .setPriority(20)
-                .setNotifyConfigs(notifyConfigs)
-                .setActionList(java.util.Arrays.asList(actionList0))
-                .setTodoType("TODO")
-                .setRemindNotifyConfigs(remindNotifyConfigs);
-        try {
-            CreateTodoTaskResponse response = client.createTodoTaskWithOptions(unionIdList.get(Constants.ZERO), createTodoTaskRequest, createTodoTaskHeaders, new com.aliyun.teautil.models.RuntimeOptions());
-            log.error("寰呭姙閫氱煡鍙戦�佹垚鍔燂紝鍙戦�佸唴瀹癸細{}"+JSONObject.toJSONString(response));
-            return response.getBody().getId();
-        } catch (TeaException err) {
-            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
-                log.error("寰呭姙閫氱煡鍙戦�佸け璐ワ紝澶辫触鍘熷洜锛歿}"+err.message);
+    public String toDoNotice(String title,List<String> unionIdList,List<CreateTodoTaskRequest.CreateTodoTaskRequestContentFieldList> fieldList,String url) {
+        try{
+            com.aliyun.dingtalktodo_1_0.Client client = DingTalk.createV1Client();
+            CreateTodoTaskHeaders createTodoTaskHeaders = new CreateTodoTaskHeaders();
+            createTodoTaskHeaders.xAcsDingtalkAccessToken = getToken();
+            //寰呭姙鎴鍓嶇殑鎻愰啋
+            CreateTodoTaskRequest.CreateTodoTaskRequestRemindNotifyConfigs remindNotifyConfigs = new CreateTodoTaskRequest.CreateTodoTaskRequestRemindNotifyConfigs()
+                    .setDingNotify("1")
+                    .setSendTodoApn("true");
+            //寰呭姙閫氱煡閰嶇疆
+            CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs notifyConfigs = new CreateTodoTaskRequest.CreateTodoTaskRequestNotifyConfigs()
+                    .setDingNotify("1")
+                    .setSendTodoApn("true")
+                    .setSendAssistantChat("true");
+            //鎸夐挳浜嬩欢
+            CreateTodoTaskRequest.CreateTodoTaskRequestActionListParam actionList0Param = new CreateTodoTaskRequest.CreateTodoTaskRequestActionListParam()
+                    .setBody("");
+            CreateTodoTaskRequest.CreateTodoTaskRequestActionList actionList0 = new CreateTodoTaskRequest.CreateTodoTaskRequestActionList()
+                    .setTitle("鍘诲鐞�")
+                    .setActionType(2)
+                    .setParam(actionList0Param)
+                    .setUrl("https://www.baidu.com") //TODO 璇︽儏鍦板潃
+                    .setActionKey("ak-1-1");
+            //璇︽儏椤祏rl璺宠浆鍦板潃
+            CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl detailUrl = new CreateTodoTaskRequest.CreateTodoTaskRequestDetailUrl()
+                    .setAppUrl("https://www.baidu.com")
+                    .setPcUrl("https://www.baidu.com");
+            CreateTodoTaskRequest createTodoTaskRequest = new CreateTodoTaskRequest()
+                    .setSubject(title)
+                    .setCreatorId(unionIdList.get(Constants.ZERO))
+                    .setDescription(title)
+                    .setExecutorIds(unionIdList)
+                    .setDetailUrl(detailUrl)
+                    .setContentFieldList(fieldList)
+                    .setIsOnlyShowExecutor(true)
+                    .setPriority(20)
+                    .setNotifyConfigs(notifyConfigs)
+                    .setActionList(java.util.Arrays.asList(actionList0))
+                    .setTodoType("TODO")
+                    .setRemindNotifyConfigs(remindNotifyConfigs);
+            try {
+                CreateTodoTaskResponse response = client.createTodoTaskWithOptions(unionIdList.get(Constants.ZERO), createTodoTaskRequest, createTodoTaskHeaders, new com.aliyun.teautil.models.RuntimeOptions());
+                log.error("寰呭姙閫氱煡鍙戦�佹垚鍔燂紝鍙戦�佸唴瀹癸細{}"+JSONObject.toJSONString(response));
+                return response.getBody().getId();
+            } catch (TeaException err) {
+                if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
+                    log.error("寰呭姙閫氱煡鍙戦�佸け璐ワ紝澶辫触鍘熷洜锛歿}"+err.message);
+                }
+            } catch (Exception _err) {
+                TeaException err = new TeaException(_err.getMessage(), _err);
+                if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
+                    // err 涓惈鏈� code 鍜� message 灞炴�э紝鍙府鍔╁紑鍙戝畾浣嶉棶棰�
+                    log.error("寰呭姙閫氱煡鍙戦�佸け璐ワ紝澶辫触鍘熷洜锛歿}"+err.message);
+                }
             }
-        } catch (Exception _err) {
-            TeaException err = new TeaException(_err.getMessage(), _err);
-            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
-                // err 涓惈鏈� code 鍜� message 灞炴�э紝鍙府鍔╁紑鍙戝畾浣嶉棶棰�
-                log.error("寰呭姙閫氱煡鍙戦�佸け璐ワ紝澶辫触鍘熷洜锛歿}"+err.message);
-            }
+            return null;
+        }catch (Exception e){
+            throw  new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"閽夐拤寰呭姙浠诲姟閫氱煡鍙戦�佸け璐�");
         }
-        return null;
     }
 
 
     /**
-     * 澶勭悊鍏ㄩ儴浜虹殑寰呭姙淇℃伅
+     * 澶勭悊鍏ㄩ儴浜虹殑寰呭姙淇℃伅 锛堟祦绋嬪鎵瑰畬鎴愩�佹湰绾у鎵瑰畬鎴� 浣跨敤锛�
      * @param unionId
      * @param taskId
      * api鍦板潃 https://open.dingtalk.com/document/orgapp/updates-dingtalk-to-do-tasks
      * @throws Exception
      */
-    public void updToDoNoticeInfoStatus(String unionId,String taskId) throws Exception {
-        com.aliyun.dingtalktodo_1_0.Client client = DingTalk.createV1Client();
-        UpdateTodoTaskHeaders updateTodoTaskHeaders = new UpdateTodoTaskHeaders();
-        updateTodoTaskHeaders.xAcsDingtalkAccessToken = "43cf8213909f34ef81e7447905b822fb";//getToken();
-        UpdateTodoTaskRequest updateTodoTaskRequest = new UpdateTodoTaskRequest()
-                .setOperatorId(unionId)
-                .setDone(true);
+    public void updToDoNoticeInfoStatus(String unionId,String taskId){
         try {
+            com.aliyun.dingtalktodo_1_0.Client client = DingTalk.createV1Client();
+            UpdateTodoTaskHeaders updateTodoTaskHeaders = new UpdateTodoTaskHeaders();
+            updateTodoTaskHeaders.xAcsDingtalkAccessToken = getToken();
+            UpdateTodoTaskRequest updateTodoTaskRequest = new UpdateTodoTaskRequest()
+                    .setOperatorId(unionId)
+                    .setDone(true);
             UpdateTodoTaskResponse response = client.updateTodoTaskWithOptions(unionId, taskId, updateTodoTaskRequest, updateTodoTaskHeaders, new RuntimeOptions());
             log.error("寰呭姙閫氱煡鍙戦�佹垚鍔燂紝鍙戦�佸唴瀹癸細{}"+JSONObject.toJSONString(response));
         } catch (TeaException err) {
@@ -612,7 +622,6 @@
                 // err 涓惈鏈� code 鍜� message 灞炴�э紝鍙府鍔╁紑鍙戝畾浣嶉棶棰�
                 log.error("寰呭姙閫氱煡鍙戦�佸け璐ワ紝澶辫触鍘熷洜锛歿}"+err.message);
             }
-
         } catch (Exception _err) {
             TeaException err = new TeaException(_err.getMessage(), _err);
             if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
@@ -630,18 +639,18 @@
      * api 鍦板潃 https://open.dingtalk.com/document/orgapp/update-dingtalk-to-do-status
      * @throws Exception
      */
-    public void updUserToDoNoticeInfoStatus(String unionId,String taskId,String dealUnionId) throws Exception {
-        com.aliyun.dingtalktodo_1_0.Client client = DingTalk.createV1Client();
-        UpdateTodoTaskExecutorStatusHeaders updateTodoTaskExecutorStatusHeaders = new UpdateTodoTaskExecutorStatusHeaders();
-        updateTodoTaskExecutorStatusHeaders.xAcsDingtalkAccessToken = "43cf8213909f34ef81e7447905b822fb";//getToken();
-        UpdateTodoTaskExecutorStatusRequest.UpdateTodoTaskExecutorStatusRequestExecutorStatusList executorStatusList0 = new UpdateTodoTaskExecutorStatusRequest.UpdateTodoTaskExecutorStatusRequestExecutorStatusList()
-                .setId(dealUnionId)
-                .setIsDone(true);
-        UpdateTodoTaskExecutorStatusRequest updateTodoTaskExecutorStatusRequest = new UpdateTodoTaskExecutorStatusRequest()
-                .setExecutorStatusList(java.util.Arrays.asList(
-                        executorStatusList0
-                ));
+    public void updUserToDoNoticeInfoStatus(String unionId,String taskId,String dealUnionId){
         try {
+            com.aliyun.dingtalktodo_1_0.Client client = DingTalk.createV1Client();
+            UpdateTodoTaskExecutorStatusHeaders updateTodoTaskExecutorStatusHeaders = new UpdateTodoTaskExecutorStatusHeaders();
+            updateTodoTaskExecutorStatusHeaders.xAcsDingtalkAccessToken = getToken();
+            UpdateTodoTaskExecutorStatusRequest.UpdateTodoTaskExecutorStatusRequestExecutorStatusList executorStatusList0 = new UpdateTodoTaskExecutorStatusRequest.UpdateTodoTaskExecutorStatusRequestExecutorStatusList()
+                    .setId(dealUnionId)
+                    .setIsDone(true);
+            UpdateTodoTaskExecutorStatusRequest updateTodoTaskExecutorStatusRequest = new UpdateTodoTaskExecutorStatusRequest()
+                    .setExecutorStatusList(java.util.Arrays.asList(
+                            executorStatusList0
+                    ));
             UpdateTodoTaskExecutorStatusResponse response = client.updateTodoTaskExecutorStatusWithOptions(unionId, taskId, updateTodoTaskExecutorStatusRequest, updateTodoTaskExecutorStatusHeaders, new RuntimeOptions());
             log.error("寰呭姙閫氱煡鍙戦�佹垚鍔燂紝鍙戦�佸唴瀹癸細{}"+JSONObject.toJSONString(response));
         } catch (TeaException err) {
@@ -729,10 +738,10 @@
         carUseBook.setType(Constants.ZERO);
 
 
-        dingTalk.workInfoOANotice(4015267031L,"1568490244651036",dingTalk.getCarUseNoticeMsg(carUseBook,"鐢ㄨ溅鐢宠"));
+//        dingTalk.workInfoOANotice(4015267031L,"1568490244651036",dingTalk.getCarUseNoticeMsg(carUseBook,"鐢ㄨ溅鐢宠"));
 
 
-//        dingTalk.toDoNotice("灏忚眴涓佹彁浜ょ殑鍏姟杞︾敤杞�",java.util.Arrays.asList("iPsP86axviPHiSP4nm5YgQNCQiEiE","XiPYJKRAv9eCoO4UPM20HQQiEiE","eWbHiSp3uRtrMtiiOX5LXamgiEiE") ,dingTalk.getToDoCarUseBookFiledInfo(carUseBook));
+        dingTalk.toDoNotice("灏忚眴涓佹彁浜ょ殑鍏姟杞︾敤杞�",java.util.Arrays.asList("iPsP86axviPHiSP4nm5YgQNCQiEiE","XiPYJKRAv9eCoO4UPM20HQQiEiE","eWbHiSp3uRtrMtiiOX5LXamgiEiE") ,dingTalk.getToDoCarUseBookFiledInfo(carUseBook),"");
 //
 
 //        dingTalk.updUserToDoNoticeInfoStatus("iPsP86axviPHiSP4nm5YgQNCQiEiE",
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCabinetGridMapper.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCabinetGridMapper.java
index 69cdf93..f5e0ee8 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCabinetGridMapper.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCabinetGridMapper.java
@@ -2,11 +2,13 @@
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.doumee.dao.business.model.JkCabinetGrid;
+import com.github.yulichang.base.mapper.MPJJoinMapper;
+import com.github.yulichang.interfaces.MPJBaseJoin;
 
 /**
  * @author 姹熻箘韫�
  * @date 2025/09/28 09:01
  */
-public interface JkCabinetGridMapper extends BaseMapper<JkCabinetGrid> {
+public interface JkCabinetGridMapper extends MPJJoinMapper<JkCabinetGrid> {
 
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCabinetLogMapper.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCabinetLogMapper.java
index 63566fe..4bf0c72 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCabinetLogMapper.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkCabinetLogMapper.java
@@ -2,11 +2,12 @@
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.doumee.dao.business.model.JkCabinetLog;
+import com.github.yulichang.base.mapper.MPJJoinMapper;
 
 /**
  * @author 姹熻箘韫�
  * @date 2025/09/28 09:01
  */
-public interface JkCabinetLogMapper extends BaseMapper<JkCabinetLog> {
+public interface JkCabinetLogMapper extends MPJJoinMapper<JkCabinetLog> {
 
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkIccardMapper.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkIccardMapper.java
index 571c5e3..32b5378 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkIccardMapper.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkIccardMapper.java
@@ -2,11 +2,12 @@
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.doumee.dao.business.model.JkIccard;
+import com.github.yulichang.base.mapper.MPJJoinMapper;
 
 /**
  * @author 姹熻箘韫�
  * @date 2025/09/28 09:01
  */
-public interface JkIccardMapper extends BaseMapper<JkIccard> {
+public interface JkIccardMapper extends MPJJoinMapper<JkIccard> {
 
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkKeysMapper.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkKeysMapper.java
index b854736..233ea58 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkKeysMapper.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkKeysMapper.java
@@ -2,11 +2,12 @@
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.doumee.dao.business.model.JkKeys;
+import com.github.yulichang.base.mapper.MPJJoinMapper;
 
 /**
  * @author 姹熻箘韫�
  * @date 2025/09/28 09:01
  */
-public interface JkKeysMapper extends BaseMapper<JkKeys> {
+public interface JkKeysMapper extends MPJJoinMapper<JkKeys> {
 
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkVersionMapper.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkVersionMapper.java
index 0e6ef61..b1d0375 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkVersionMapper.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/JkVersionMapper.java
@@ -2,11 +2,12 @@
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
 import com.doumee.dao.business.model.JkVersion;
+import com.github.yulichang.base.mapper.MPJJoinMapper;
 
 /**
  * @author 姹熻箘韫�
  * @date 2025/09/28 09:01
  */
-public interface JkVersionMapper extends BaseMapper<JkVersion> {
+public interface JkVersionMapper extends MPJJoinMapper<JkVersion> {
 
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/CloseGridDTO.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/CloseGridDTO.java
new file mode 100644
index 0000000..d48db4c
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/CloseGridDTO.java
@@ -0,0 +1,31 @@
+package com.doumee.dao.business.dto;
+
+import com.doumee.service.business.third.model.LoginUserModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @Author : Rk
+ * @create 2025/10/11 16:01
+ */
+@Data
+public class CloseGridDTO{
+
+    @ApiModelProperty(value = "閽ュ寵鏌滀富閿�")
+    private Integer cabinetId;
+
+    @ApiModelProperty(value = "楠岃瘉鏂瑰紡 0鍒疯劯 1鍒峰崱 2绠$悊鍛樻搷浣�")
+    private Integer authType;
+
+    @ApiModelProperty(value = "鏌滄牸涓婚敭")
+    private Integer gridId;
+
+    @ApiModelProperty(value = "鐢ㄦ埛涓婚敭")
+    private Integer memberId;
+
+    @ApiModelProperty(value = "閽ュ寵鐘舵�侊細1鍦ㄤ綅 2鍊熷嚭")
+    private Integer keyStatus;
+
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/GetDriverGridDTO.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/GetDriverGridDTO.java
new file mode 100644
index 0000000..6b63c22
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/GetDriverGridDTO.java
@@ -0,0 +1,24 @@
+package com.doumee.dao.business.dto;
+
+import com.doumee.service.business.third.model.LoginUserModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @Author : Rk
+ * @create 2025/10/11 16:01
+ */
+@Data
+public class GetDriverGridDTO{
+
+    @ApiModelProperty(value = "閽ュ寵鏌滀富閿�")
+    private Integer cabinetId;
+
+    @ApiModelProperty(value = "0=鍙� 1=杩�")
+    private Integer type;
+
+    @ApiModelProperty(value = "鐢ㄦ埛涓婚敭")
+    private Integer memberId;
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/OpenGridDriverDTO.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/OpenGridDriverDTO.java
new file mode 100644
index 0000000..2f76d84
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/OpenGridDriverDTO.java
@@ -0,0 +1,25 @@
+package com.doumee.dao.business.dto;
+
+import com.doumee.service.business.third.model.LoginUserModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @Author : Rk
+ * @create 2025/10/11 16:01
+ */
+@Data
+public class OpenGridDriverDTO extends LoginUserModel {
+
+    @ApiModelProperty(value = "閽ュ寵鏌滀富閿�")
+    private Integer cabinetId;
+
+    @ApiModelProperty(value = "楠岃瘉鏂瑰紡 0鍒疯劯 1鍒峰崱")
+    private Integer authType;
+
+    @ApiModelProperty(value = "鏌滄牸涓婚敭")
+    private Integer gridId;
+
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/OptGridDTO.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/OptGridDTO.java
new file mode 100644
index 0000000..64db8b0
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/dto/OptGridDTO.java
@@ -0,0 +1,24 @@
+package com.doumee.dao.business.dto;
+
+import com.doumee.service.business.third.model.LoginUserModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @Author : Rk
+ * @create 2025/10/11 16:01
+ */
+@Data
+public class OptGridDTO extends LoginUserModel {
+
+    @ApiModelProperty(value = "閽ュ寵鏌滀富閿�")
+    private Integer cabinetId;
+
+    @ApiModelProperty(value = "鏌滄牸涓婚敭鍒楄〃")
+    private List<Integer> gridIdList;
+
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/CarUseBook.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/CarUseBook.java
index 3376b70..cc1f7cd 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/CarUseBook.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/CarUseBook.java
@@ -145,6 +145,12 @@
     //@ExcelColumn(name="鍙告満缂栫爜锛堝叧鑱攎emberId锛�")
     private Integer driverId;
 
+    @ApiModelProperty(value = "閽夐拤寰呭姙浠诲姟涓婚敭")
+    private String ddToDoId;
+
+    @ApiModelProperty(value = "閽夐拤寰呭姙浠诲姟褰掑睘浜轰富閿�")
+    private String ddBelongToUnionId;
+
     @ApiModelProperty(value = "鍙告満濮撳悕", example = "1")
     @TableField(exist = false)
     private String driverName;
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinet.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinet.java
index 26f0b8c..e9e3f6c 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinet.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinet.java
@@ -1,5 +1,6 @@
 package com.doumee.dao.business.model;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.doumee.core.annotation.excel.ExcelColumn;
 import com.doumee.service.business.third.model.LoginUserModel;
 import io.swagger.annotations.ApiModel;
@@ -11,6 +12,7 @@
 import com.fasterxml.jackson.annotation.JsonFormat;
 import java.util.Date;
 import java.math.BigDecimal;
+import java.util.List;
 
 /**
  * 閽ュ寵鏌滃熀鏈俊鎭〃
@@ -73,17 +75,27 @@
     @ExcelColumn(name="閫氳鍦板潃")
     private String linkAddr;
 
-    @ApiModelProperty(value = "鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭", example = "1")
-    @ExcelColumn(name="鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭")
+    @ApiModelProperty(value = "鐘舵�� 0鍚敤 1绂佺敤", example = "1")
+    @ExcelColumn(name="鐘舵�� 0鍚敤 1绂佺敤")
     private Integer status;
+
+    @ApiModelProperty(value = "杩愯鐘舵�� 0=鍦ㄧ嚎 1=绂荤嚎", example = "1")
+    @ExcelColumn(name="杩愯鐘舵�� 0=鍦ㄧ嚎 1=绂荤嚎")
+    private Integer runStatus;
+
 
     @ApiModelProperty(value = "绔彛", example = "1")
     @ExcelColumn(name="绔彛")
     private Integer port;
 
-    @ApiModelProperty(value = "璁惧绠$悊鍛樼紪鐮侊紙鍏宠仈member)", example = "1")
+    @ApiModelProperty(value = "璁惧绠$悊鍛樼紪鐮侊紙鍏宠仈member) 澶氫釜浠�,鍒嗗壊", example = "1")
     @ExcelColumn(name="璁惧绠$悊鍛樼紪鐮侊紙鍏宠仈member)")
-    private Integer managerId;
+    private String managerId;
+
+    @ApiModelProperty(value = "楠岃瘉浜虹紪鐮侊紙鍏宠仈member)", example = "1")
+    @ExcelColumn(name="楠岃瘉浜虹紪鐮侊紙鍏宠仈member)")
+    private String authMemberId;
+
 
     @ApiModelProperty(value = "浣跨敤鏃堕暱(绉�)", example = "1")
     @ExcelColumn(name="浣跨敤鏃堕暱(绉�)")
@@ -93,10 +105,6 @@
     @ExcelColumn(name="鏄惁鍙岄噸楠岃瘉 0鍚� 1鏄�")
     private Integer doubleAuth;
 
-    @ApiModelProperty(value = "楠岃瘉浜虹紪鐮侊紙鍏宠仈member)", example = "1")
-    @ExcelColumn(name="楠岃瘉浜虹紪鐮侊紙鍏宠仈member)")
-    private Integer authMemberId;
-
     @ApiModelProperty(value = "鎺掓暟", example = "1")
     @ExcelColumn(name="鎺掓暟")
     private Integer rowNum;
@@ -104,6 +112,10 @@
     @ApiModelProperty(value = "鍒楁暟", example = "1")
     @ExcelColumn(name="鍒楁暟")
     private Integer columnNum;
+
+    @ApiModelProperty(value = "鎺掑簭椤哄簭锛�0=浠庡乏鍚戝彸锛�1=浠庝笂鍚戜笅", example = "1")
+    @ExcelColumn(name="鎺掑簭椤哄簭")
+    private Integer sortType;
 
     @ApiModelProperty(value = "鏈�鍚庨�氳鏃堕棿")
     @ExcelColumn(name="鏈�鍚庨�氳鏃堕棿")
@@ -138,4 +150,21 @@
     @ExcelColumn(name="璧峰缂栫爜")
     private Integer noIndex;
 
+    @ApiModelProperty(value = "缁忕含搴︿俊鎭� 鍙傛暟鍊硷細缁忓害,绾害")
+    @TableField(exist = false)
+    private String jwd;
+
+    @ApiModelProperty(value = "鏌滄牸鏁伴噺", example = "1")
+    @TableField(exist = false)
+    private Integer gridNum;
+
+    @ApiModelProperty(value = "璁惧绠$悊浜哄憳鏁扮粍", example = "1")
+    @TableField(exist = false)
+    private List<String> managerIdList;
+
+    @ApiModelProperty(value = "楠岃瘉浜虹紪鐮佹暟缁�", example = "1")
+    @TableField(exist = false)
+    private List<String> authMemberIdList;
+
+
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinetGrid.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinetGrid.java
index 35fa13a..84cb250 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinetGrid.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinetGrid.java
@@ -1,5 +1,6 @@
 package com.doumee.dao.business.model;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.doumee.core.annotation.excel.ExcelColumn;
 import com.doumee.service.business.third.model.LoginUserModel;
 import io.swagger.annotations.ApiModel;
@@ -68,12 +69,45 @@
     @ExcelColumn(name="搴忓垪鍙�")
     private String serialNo;
 
-    @ApiModelProperty(value = "鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭", example = "1")
-    @ExcelColumn(name="鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭")
+    @ApiModelProperty(value = "鐘舵�� 0鍚敤锛�1绂佺敤", example = "1")
+    @ExcelColumn(name="鐘舵�� 0鍚敤锛�1=绂佺敤")
     private Integer status;
 
-    @ApiModelProperty(value = "杩愯鐘舵��", example = "1")
+    @ApiModelProperty(value = "杩愯鐘舵�� 0姝e父 1鏁呴殰 ", example = "1")
     @ExcelColumn(name="杩愯鐘舵��")
     private Integer workingStatus;
 
+    @ApiModelProperty(value = "鏉垮彿")
+    @ExcelColumn(name="鏉垮彿")
+    private String boardCode;
+
+    @ApiModelProperty(value = "閫氶亾鍙�")
+    @ExcelColumn(name="閫氶亾鍙�")
+    private String channelCode;
+
+
+    @ApiModelProperty(value = "缁戝畾鐘舵�� 0鏈粦瀹氾紱1宸茬粦瀹�", example = "1")
+    @TableField(exist = false)
+    private Integer bindStatus;
+
+    @ApiModelProperty(value = "閽ュ寵鏌滃悕绉�", example = "1")
+    @TableField(exist = false)
+    private String cabinetName;
+
+    @ApiModelProperty(value = "閽ュ寵缂栫爜", example = "1")
+    @TableField(exist = false)
+    private String keyCode;
+
+    @ApiModelProperty(value = "杞︾墝鍙�", example = "1")
+    @TableField(exist = false)
+    private String carCode;
+
+    @ApiModelProperty(value = "杞﹁締涓婚敭", example = "1")
+    @TableField(exist = false)
+    private Integer carId;
+
+    @ApiModelProperty(value = "閽ュ寵鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭 3缁翠慨淇濆吇", example = "1")
+    @TableField(exist = false)
+    private Integer keyStatus;
+
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinetLog.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinetLog.java
index 63bd3e6..91d1265 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinetLog.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkCabinetLog.java
@@ -1,5 +1,6 @@
 package com.doumee.dao.business.model;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.doumee.core.annotation.excel.ExcelColumn;
 import com.doumee.service.business.third.model.LoginUserModel;
 import io.swagger.annotations.ApiModel;
@@ -22,70 +23,90 @@
 public class JkCabinetLog  extends LoginUserModel {
 
     @ApiModelProperty(value = "涓婚敭", example = "1")
-    @ExcelColumn(name="涓婚敭")
     @TableId(type = IdType.AUTO)
     private Integer id;
 
     @ApiModelProperty(value = "鍒涘缓浜虹紪鐮�", example = "1")
-    @ExcelColumn(name="鍒涘缓浜虹紪鐮�")
     private Integer creator;
 
     @ApiModelProperty(value = "鍒涘缓鏃堕棿")
-    @ExcelColumn(name="鍒涘缓鏃堕棿")
-    @JsonFormat(pattern = "yyyy-MM-dd")
+    @ExcelColumn(name="寮�闂ㄦ椂闂�",index = 0,dateFormat = "yyyy-MM-dd HH:mm:ss",width = 16)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private Date createDate;
 
     @ApiModelProperty(value = "鏇存柊浜虹紪鐮�", example = "1")
-    @ExcelColumn(name="鏇存柊浜虹紪鐮�")
     private Integer editor;
 
     @ApiModelProperty(value = "鏇存柊鏃堕棿")
-    @ExcelColumn(name="鏇存柊鏃堕棿")
     @JsonFormat(pattern = "yyyy-MM-dd")
     private Date editDate;
 
     @ApiModelProperty(value = "鏄惁鍒犻櫎0鍚� 1鏄�", example = "1")
-    @ExcelColumn(name="鏄惁鍒犻櫎0鍚� 1鏄�")
     private Integer isdeleted;
 
     @ApiModelProperty(value = "澶囨敞")
-    @ExcelColumn(name="澶囨敞")
     private String info;
 
     @ApiModelProperty(value = "閽ュ寵鏌滅紪鐮侊紙鍏宠仈jk_cabinet)", example = "1")
-    @ExcelColumn(name="閽ュ寵鏌滅紪鐮侊紙鍏宠仈jk_cabinet)")
     private Integer cabinetId;
 
     @ApiModelProperty(value = "閽ュ寵鏌滄牸缂栫爜(鍏宠仈jk_cabinet_grid)", example = "1")
-    @ExcelColumn(name="閽ュ寵鏌滄牸缂栫爜(鍏宠仈jk_cabinet_grid)")
     private Integer gridId;
 
     @ApiModelProperty(value = "楠岃瘉鏂瑰紡 0鍒疯劯 1鍒峰崱", example = "1")
-    @ExcelColumn(name="楠岃瘉鏂瑰紡 0鍒疯劯 1鍒峰崱")
+    @ExcelColumn(name="鏍¢獙鏂瑰紡",index = 2,width = 10,valueMapping = "0=浜鸿劯;1=鍒峰崱;2=绠$悊鎺堟潈;")
     private Integer authType;
 
     @ApiModelProperty(value = "杞﹁締缂栫爜锛堝叧鑱攃ars)", example = "1")
-    @ExcelColumn(name="杞﹁締缂栫爜锛堝叧鑱攃ars)")
     private Integer carId;
 
     @ApiModelProperty(value = "閽ュ寵缂栫爜(鍏宠仈jk_keys)", example = "1")
-    @ExcelColumn(name="閽ュ寵缂栫爜(鍏宠仈jk_keys)")
     private Integer keyId;
 
     @ApiModelProperty(value = "浜哄憳缂栫爜锛堝叧鑱攎ember)", example = "1")
-    @ExcelColumn(name="浜哄憳缂栫爜锛堝叧鑱攎ember)")
     private Integer memberId;
 
     @ApiModelProperty(value = "閽ュ寵淇℃伅锛堣溅鐗屽彿-閽ュ寵缂栫爜锛�")
-    @ExcelColumn(name="閽ュ寵淇℃伅锛堣溅鐗屽彿-閽ュ寵缂栫爜锛�")
+    @ExcelColumn(name="閽ュ寵",index = 5,width = 16)
     private String keyInfo;
 
     @ApiModelProperty(value = "棰嗗彇瑙勫垯 0闅忚溅 1闅忔淳杞﹀崟", example = "1")
-    @ExcelColumn(name="棰嗗彇瑙勫垯 0闅忚溅 1闅忔淳杞﹀崟")
     private Integer roleType;
 
     @ApiModelProperty(value = "鐘舵�� 0鎴愬姛 1澶辫触", example = "1")
-    @ExcelColumn(name="鐘舵�� 0鎴愬姛 1澶辫触")
+    @ExcelColumn(name="鐘舵��",index = 6,width = 10,valueMapping = "0=鎴愬姛;1=澶辫触;")
     private Integer status;
 
+    @ApiModelProperty(value = "鎿嶄綔绫诲瀷锛�0=寮�闂�;1=鍏抽棬;", example = "1")
+    private Integer type;
+
+    @ApiModelProperty(value = "鎿嶄綔浜洪儴闂�", example = "1",hidden = true)
+    @TableField(exist = false)
+    private String companyName;
+
+    @ApiModelProperty(value = "鎿嶄綔浜哄悕绉�", example = "1")
+    @ExcelColumn(name="鎿嶄綔浜�",index = 1,width = 2)
+    @TableField(exist = false)
+    private String memberName;
+
+    @ApiModelProperty(value = "閽ュ寵鏌滃悕绉�", example = "1")
+    @ExcelColumn(name="鎵�灞為挜鍖欐煖",index = 3,width = 12)
+    @TableField(exist = false)
+    private String cabinetName;
+
+    @ApiModelProperty(value = "鏌滄牸缂栧彿", example = "1")
+    @ExcelColumn(name="鏌滄牸缂栧彿",index = 4,width = 12)
+    @TableField(exist = false)
+    private String gridCode;
+
+    @ApiModelProperty(value = "鏌ヨ寮�濮嬫椂闂� yyyy-MM-dd ")
+    @TableField(exist = false)
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date startDate;
+
+    @ApiModelProperty(value = "鏌ヨ缁撴潫鏃堕棿 yyyy-MM-dd ")
+    @TableField(exist = false)
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    private Date endDate;
+
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkIccard.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkIccard.java
index 9bc6a43..c4f781e 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkIccard.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkIccard.java
@@ -1,5 +1,6 @@
 package com.doumee.dao.business.model;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.doumee.core.annotation.excel.ExcelColumn;
 import com.doumee.service.business.third.model.LoginUserModel;
 import io.swagger.annotations.ApiModel;
@@ -72,4 +73,12 @@
     @ExcelColumn(name="閽ュ寵鏌滅紪鐮侊紙鍏宠仈jk_cabinet)")
     private Integer cabinetId;
 
+    @ApiModelProperty(value = "鍏宠仈浜哄憳绫诲瀷锛�0=鍙告満锛�1=鏍¢獙浜哄憳", example = "1")
+    @ExcelColumn(name="鍏宠仈浜哄憳绫诲瀷锛�0=鍙告満锛�1=鏍¢獙浜哄憳")
+    private Integer userType;
+
+    @ApiModelProperty(value = "浜哄憳鍚嶇О", example = "1")
+    @TableField(exist = false)
+    private String memberName;
+
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkKeys.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkKeys.java
index 2148e5c..edf02f8 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkKeys.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkKeys.java
@@ -1,5 +1,6 @@
 package com.doumee.dao.business.model;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.doumee.core.annotation.excel.ExcelColumn;
 import com.doumee.service.business.third.model.LoginUserModel;
 import io.swagger.annotations.ApiModel;
@@ -54,7 +55,7 @@
 
     @ApiModelProperty(value = "閽ュ寵缂栧彿", example = "1")
     @ExcelColumn(name="閽ュ寵缂栧彿")
-    private Integer code;
+    private String code;
 
     @ApiModelProperty(value = "杞︾墝鍙�")
     @ExcelColumn(name="杞︾墝鍙�")
@@ -72,8 +73,21 @@
     @ExcelColumn(name="棰嗗彇瑙勫垯 0闅忚溅 1闅忔淳杞﹀崟")
     private Integer roleType;
 
-    @ApiModelProperty(value = "鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭", example = "1")
-    @ExcelColumn(name="鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭")
+    @ApiModelProperty(value = " 鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭 3缁翠慨淇濆吇", example = "1")
+    @ExcelColumn(name=" 鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭 3缁翠慨淇濆吇")
     private Integer status;
 
+
+    @ApiModelProperty(value = "瀛樻斁浣嶇疆", example = "1")
+    @TableField(exist = false)
+    private String gridCode;
+
+    @ApiModelProperty(value = "缁戝畾閽ュ寵鏌�", example = "1")
+    @TableField(exist = false)
+    private String cabinetName;
+
+    @ApiModelProperty(value = "鏄惁缁戝畾锛�0=鍚︼紱1=鏄紱", example = "1")
+    @TableField(exist = false)
+    private Integer isBinding;
+
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkVersion.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkVersion.java
index bf6fc75..a8db838 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkVersion.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/JkVersion.java
@@ -1,5 +1,6 @@
 package com.doumee.dao.business.model;
 
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.doumee.core.annotation.excel.ExcelColumn;
 import com.doumee.service.business.third.model.LoginUserModel;
 import io.swagger.annotations.ApiModel;
@@ -9,6 +10,8 @@
 import com.baomidou.mybatisplus.annotation.TableName;
 import lombok.Data;
 import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.math.BigDecimal;
 import java.util.Date;
 
 /**
@@ -84,4 +87,24 @@
     @ExcelColumn(name="骞冲彴绫诲瀷 0Android 1IOS")
     private Integer type;
 
+    @ApiModelProperty(value = "鏂囦欢澶у皬 鍗曚綅锛圞B锛�", example = "1")
+    @ExcelColumn(name="鏂囦欢澶у皬 鍗曚綅锛圞B锛�")
+    private Integer fileSize;
+
+    @ApiModelProperty(value = "鏂囦欢澶у皬 鍗曚綅锛圡B锛�", example = "1")
+    @TableField(exist = false)
+    private double fileSizeMb;
+
+
+    @ApiModelProperty(value = "鍒涘缓浜哄悕绉�", example = "1")
+    @TableField(exist = false)
+    private String createUserName;
+
+    @ApiModelProperty(value = "apk鍏ㄨ矾寰�", example = "1")
+    @TableField(exist = false)
+    private String fullFileUrl;
+
+
+
+
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Visits.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Visits.java
index 0c23522..244311f 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Visits.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/model/Visits.java
@@ -242,6 +242,11 @@
     @ExcelColumn(name="鏂藉伐浜嬬敱")
     private String constructionReason;
 
+    @ApiModelProperty(value = "閽夐拤寰呭姙浠诲姟涓婚敭")
+    private String ddToDoId;
+
+    @ApiModelProperty(value = "閽夐拤寰呭姙浠诲姟褰掑睘浜轰富閿�")
+    private String ddBelongToUnionId;
     @ApiModelProperty(value = "鏅�氳瀹㈢敵璇烽殢璁夸汉鍛�")
     @TableField(exist = false)
     private List<Visits> withUserList;
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/AdminCabinetVO.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/AdminCabinetVO.java
new file mode 100644
index 0000000..5b54199
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/AdminCabinetVO.java
@@ -0,0 +1,27 @@
+package com.doumee.dao.business.vo;
+
+import com.doumee.core.annotation.excel.ExcelColumn;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @Author : Rk
+ * @create 2024/5/23 14:56
+ */
+@Data
+public class AdminCabinetVO {
+
+    @ApiModelProperty(value = "璁惧涓婚敭锛堢郴缁熷唴锛�")
+    private Integer id;
+
+    @ApiModelProperty(value = "璁惧缂栧彿")
+    private String code;
+
+    @ApiModelProperty(value = "璁惧鍚嶇О")
+    private String name;
+
+    @ApiModelProperty(value = "璁惧ID")
+    private String devId;
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetConfigDataVO.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetConfigDataVO.java
new file mode 100644
index 0000000..03624f1
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetConfigDataVO.java
@@ -0,0 +1,30 @@
+package com.doumee.dao.business.vo;
+
+import com.doumee.dao.business.model.Approve;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @Author : Rk
+ * @create 2024/5/23 14:56
+ */
+@Data
+public class CabinetConfigDataVO {
+
+    @ApiModelProperty(value = "娴撳害闃堝�煎崟浣� (1=mg/100ml;2=mg/L;3=%BAC)")
+    private String threshold;
+
+    @ApiModelProperty(value = "鍚规皵鏃堕暱锛堢锛�")
+    private String blowTime;
+
+    @ApiModelProperty(value = "鍘嬪姏鍊�")
+    private String pressure;
+
+    @ApiModelProperty(value = "娴撳害闃堝��")
+    private String concentration;
+
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetDetailVO.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetDetailVO.java
new file mode 100644
index 0000000..618ffb5
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetDetailVO.java
@@ -0,0 +1,53 @@
+package com.doumee.dao.business.vo;
+
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @Author : Rk
+ * @create 2024/5/23 14:56
+ */
+@Data
+public class CabinetDetailVO {
+
+    @ApiModelProperty(value = "璁惧涓婚敭锛堢郴缁熷唴锛�")
+    private Integer id;
+
+    @ApiModelProperty(value = "璁惧缂栧彿")
+    private String code;
+
+    @ApiModelProperty(value = "璁惧鍚嶇О")
+    private String name;
+
+    @ApiModelProperty(value = "璁惧ID")
+    private String devId;
+
+    @ApiModelProperty(value = "鏌滄牸鎬绘暟")
+    private Integer gridNum;
+
+    @ApiModelProperty(value = "鍦ㄤ綅閽ュ寵鏁�")
+    private Integer onlineKeyNum;
+
+    @ApiModelProperty(value = "鍊熷嚭閽ュ寵鏁�")
+    private Integer outKeyNum;
+
+    @ApiModelProperty(value = "缁翠慨淇濆吇閽ュ寵鏁�")
+    private Integer serviceKeyNum;
+
+    @ApiModelProperty(value = "鏁呴殰鏌滀綋鏁伴噺")
+    private Integer errGridNum;
+
+    @ApiModelProperty(value = "鏈粦瀹氭煖浣撴暟閲�")
+    private Integer unBindGridNum;
+
+    @ApiModelProperty(value = "鏌滄牸淇℃伅")
+    private List<CabinetGridInfoVO> cabinetGridInfoVOList;
+
+
+
+
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetGridInfoVO.java b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetGridInfoVO.java
new file mode 100644
index 0000000..9045686
--- /dev/null
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/dao/business/vo/CabinetGridInfoVO.java
@@ -0,0 +1,50 @@
+package com.doumee.dao.business.vo;
+
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.doumee.core.annotation.excel.ExcelColumn;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.Date;
+
+/**
+ * Created by IntelliJ IDEA.
+ *
+ * @Author : Rk
+ * @create 2024/5/23 14:56
+ */
+@Data
+public class CabinetGridInfoVO {
+
+    @ApiModelProperty(value = "涓婚敭", example = "1")
+    private Integer id;
+
+    @ApiModelProperty(value = "缂栫爜")
+    private String code;
+
+    @ApiModelProperty(value = "閽ュ寵缂栫爜锛堝叧鑱攋k_keys)", example = "1")
+    private Integer keyId;
+
+    @ApiModelProperty(value = "鏌滀綋杩愯鐘舵�� 0姝e父 1鏁呴殰 ", example = "1")
+    private Integer workingStatus;
+
+    @ApiModelProperty(value = "缁戝畾鐘舵�� 0鏈粦瀹氾紱1宸茬粦瀹�", example = "1")
+    private Integer bindStatus;
+
+    @ApiModelProperty(value = "閽ュ寵鐘舵�� 0鏈粦瀹� 1鍦ㄤ綅 2鍊熷嚭 3缁翠慨淇濆吇", example = "1")
+    private Integer keyStatus;
+
+    @ApiModelProperty(value = "鏉垮彿")
+    private String boardCode;
+
+    @ApiModelProperty(value = "閫氶亾鍙�")
+    private String channelCode;
+
+    @ApiModelProperty(value = "杞︾墝鍙�", example = "1")
+    private String carCode;
+
+
+}
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCabinetGridService.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCabinetGridService.java
index 508b858..eee512d 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCabinetGridService.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCabinetGridService.java
@@ -1,8 +1,11 @@
 package com.doumee.service.business;
 
-//import com.doumee.service.business.third.model.PageData;
-//import com.doumee.service.business.third.model.PageWrap;
+import com.doumee.dao.business.dto.OptGridDTO;
+import com.doumee.dao.business.dto.CloseGridDTO;
+import com.doumee.dao.business.dto.GetDriverGridDTO;
+import com.doumee.dao.business.dto.OpenGridDriverDTO;
 import com.doumee.dao.business.model.JkCabinetGrid;
+import com.doumee.service.business.third.model.LoginUserInfo;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
 
@@ -97,4 +100,43 @@
      * @return long
      */
     long count(JkCabinetGrid jkCabinetGrid);
+
+    void updateStatusById(JkCabinetGrid jkCabinetGrid);
+
+    void unBindKeys(List<Integer> idList);
+
+    /**
+     * 鏍囪鏌滄牸鏁呴殰
+     * @param loginUserInfo
+     * @param cabinetId
+     * @param gridIdList
+     */
+    void markFault(OptGridDTO dto);
+
+    /**
+     * 鏍囪鏌滄牸姝e父
+     * @param loginUserInfo
+     * @param cabinetId
+     * @param gridIdList
+     */
+    void cancelFault(OptGridDTO dto);
+
+    /**
+     * 鎵归噺寮�闂� - 绠$悊鍛�
+     */
+    void batchOpenGridAdmin(OptGridDTO dto);
+    /**
+     * 鏍囪缁翠慨淇濆吇 - 绠$悊鍛�
+     * @param loginUserInfo
+     * @param cabinetId
+     * @param gridIdList
+     */
+    void markRepair(OptGridDTO dto);
+
+    void closeGrid(CloseGridDTO dto);
+
+    List<JkCabinetGrid> getDriverGrid(GetDriverGridDTO getDriverGridDTO);
+
+    void openGridDriver(OpenGridDriverDTO openGridDriverDTO);
+
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCabinetService.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCabinetService.java
index ad0bc17..95caaf0 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCabinetService.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkCabinetService.java
@@ -1,5 +1,9 @@
 package com.doumee.service.business;
 
+import com.doumee.dao.business.vo.AdminCabinetVO;
+import com.doumee.dao.business.vo.CabinetConfigDataVO;
+import com.doumee.dao.business.vo.CabinetDetailVO;
+import com.doumee.service.business.third.model.LoginUserInfo;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
 import com.doumee.dao.business.model.JkCabinet;
@@ -48,6 +52,8 @@
      */
     void updateById(JkCabinet jkCabinet);
 
+    void updateStatusById(JkCabinet jkCabinet);
+
     /**
      * 鎵归噺涓婚敭鏇存柊
      *
@@ -63,6 +69,7 @@
      */
     JkCabinet findById(Integer id);
 
+    JkCabinet getDetail(Integer id);
     /**
      * 鏉′欢鏌ヨ鍗曟潯璁板綍
      *
@@ -94,4 +101,23 @@
      * @return long
      */
     long count(JkCabinet jkCabinet);
+
+    CabinetConfigDataVO getCabinetConfigDataVO();
+
+    void updCabinetConfig(CabinetConfigDataVO cabinetConfigDataVO);
+
+
+    /**
+     * 閽ュ寵鏌滅鐞嗗憳 鑾峰彇鍙鐞嗙殑閽ュ寵鏌滃垪琛�
+     * @param loginUserInfo
+     * @return
+     */
+    List<AdminCabinetVO> getAdminCabinetInfo(LoginUserInfo loginUserInfo);
+
+    /**
+     * 鑾峰彇閽ュ寵鏌滆鎯�
+     * @param cabinetId
+     * @return
+     */
+    CabinetDetailVO getCabinetDetail(Integer cabinetId);
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkIccardService.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkIccardService.java
index b209b97..b9f531a 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkIccardService.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/JkIccardService.java
@@ -94,4 +94,6 @@
      * @return long
      */
     long count(JkIccard jkIccard);
+
+    void updateStatusById(JkIccard jkIccard);
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/WarningService.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/WarningService.java
index db51aba..c06822a 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/WarningService.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/WarningService.java
@@ -97,4 +97,6 @@
     long count(Warning warning);
 
     void updateStatus(Warning param);
+
+    void getWeatherInfo();
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/ApproveServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/ApproveServiceImpl.java
index b352a5e..fe94066 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/ApproveServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/ApproveServiceImpl.java
@@ -3,6 +3,7 @@
 import com.alibaba.fastjson.JSONObject;
 import com.doumee.biz.system.SystemDictDataBiz;
 import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.dingTalk.DingTalk;
 import com.doumee.core.exception.BusinessException;
 import com.doumee.core.haikang.model.HKConstants;
 import com.doumee.core.haikang.model.param.BaseResponse;
@@ -124,6 +125,8 @@
     private SmsEmailMapper smsEmailMapper;
     @Autowired
     private EmayService emayService;
+    @Autowired
+    private DingTalk dingTalk;
     @Override
     public Integer create(Approve approve) {
         approveMapper.insert(approve);
@@ -621,6 +624,7 @@
                                     Arrays.asList(member.getSystemOpenid().split(","))
                             );
                         }
+                        
                     }else if(Constants.equalsInteger(noticeType,Constants.noticesObjectType.visitReporting)){
                         //璁垮鎶ュ
                         SmsEmailServiceImpl.sendVisitReportSms(systemDictDataBiz,
@@ -659,9 +663,44 @@
                             }
                         }
                     }
+                } 
+            }
+            if(Constants.equalsInteger(i,Constants.ZERO) && CollectionUtils.isNotEmpty(memberList)){
+                //鐢熸垚绗竴鎵归拤閽夊鎵归�氱煡淇℃伅
+                List<String> erpId = memberList.stream().filter(m->StringUtils.isNotBlank(m.getErpId())).map(m->m.getErpId()).collect(Collectors.toList());
+                if(CollectionUtils.isNotEmpty(erpId)){
+                    if(Constants.equalsInteger(noticeType,Constants.noticesObjectType.useCar)){
+                        CarUseBook carUseBook = carUseBookMapper.selectJoinOne(CarUseBook.class,
+                                new MPJLambdaWrapper<CarUseBook>()
+                                        .selectAll(CarUseBook.class)
+                                        .selectAs(Member::getName,CarUseBook::getMemberName)
+                                        .leftJoin(Member.class,Member::getId,CarUseBook::getMemberId)
+                                        .eq(CarUseBook::getId,businessId)
+                                        .last(" limit 1 ")
+                        );
+                        if(Objects.nonNull(carUseBook)){
+                            if(CollectionUtils.isNotEmpty(erpId)){
+                                String ddTalkId = dingTalk.toDoNotice(StringUtils.isNotBlank(carUseBook.getMemberName())?(carUseBook.getMemberName()+"鎻愪氦鐨勫叕鍔$敤杞︾敵璇�"):"鍏姟杞︾敤杞︾敵璇�",
+                                        erpId ,
+                                        dingTalk.getToDoCarUseBookFiledInfo(carUseBook),"pages/staff/vehicle/sendACarDetail?id="+carUseBook.getId());
+                                carUseBookMapper.update(new UpdateWrapper<CarUseBook>().lambda()
+                                        .set(CarUseBook::getDdBelongToUnionId,erpId.get(Constants.ZERO))
+                                        .set(CarUseBook::getDdToDoId,ddTalkId).eq(CarUseBook::getId,carUseBook.getId()));
+                            }
+                        }
+                    }else if(Constants.equalsInteger(noticeType,Constants.noticesObjectType.visit) || Constants.equalsInteger(noticeType,Constants.noticesObjectType.visitReporting)) {
+                        Visits visits = visitsMapper.selectById(businessId);
+                        if (Objects.nonNull(visits)) {
+                            //TODO 缂哄皯鍩熷悕鍓嶇紑鍐呭
+                            String ddTalkId = dingTalk.toDoNotice(visits.getName() + "鐨勮瀹㈢敵璇�",
+                                    erpId,
+                                    dingTalk.getToDoVisitFiledInfo(visits), "pages/appointmentDetails/appointmentDetails?id=" + visits.getId());
+                            visitsMapper.update(new UpdateWrapper<Visits>().lambda()
+                                            .set(Visits::getDdBelongToUnionId,erpId.get(Constants.ZERO))
+                                    .set(Visits::getDdToDoId, ddTalkId).eq(Visits::getId, visits.getId()));
+                        }
+                    }
                 }
-
-
             }
         }
     }
@@ -1285,6 +1324,7 @@
         approveMapper.updateById(approve);
         //鏄惁澶勭悊 涓氬姟鏁版嵁
         Boolean dealBusinessBean = false;
+        Boolean dealDDToDo = false;
         //瀹℃壒椹冲洖鎯呭喌
         if(approveDTO.getStatus().equals(Constants.THREE)){
             dealBusinessBean = true;
@@ -1347,7 +1387,6 @@
                             .in(Approve::getId,approveList.stream().map(m->m.getId()).collect(Collectors.toList())));
                 }
                 /**寮�鍚笅涓�绾у埆鐨勬暟鎹负寰呭鏍�**/
-
                 List<Approve> waitAuditList = approveJoinMapper.selectJoinList(Approve.class,
                         new MPJLambdaWrapper<Approve>()
                                 .selectAll(Approve.class)
@@ -1383,13 +1422,17 @@
 //                }
             }else if(approve.getApproveType().equals(Constants.ONE)){
                 //浼氱 涓旂粓瀹�
+                if(!Constants.equalsInteger(approveList.size(),Constants.ZERO)&&Constants.equalsInteger(approve.getIsEndCheck(),Constants.ZERO)){
+                    //鏍囪閽夐拤閫氱煡鑷繁宸插鐞�
+                    dealDDToDo = true;
+                }
+
                 //鏃犱粬浜哄鎵圭殑鎯呭喌 鍒欎慨鏀规暟鎹姸鎬�
                 if(Constants.equalsInteger(approveList.size(),Constants.ZERO)&&Constants.equalsInteger(approve.getIsEndCheck(),Constants.ONE)){
                     dealBusinessBean = true;
                 }else{
                     if(Constants.equalsInteger(approveList.size(),Constants.ZERO)&&Constants.equalsInteger(approve.getIsEndCheck(),Constants.ZERO)){
                         /**寮�鍚笅涓�绾у埆鐨勬暟鎹负寰呭鏍�**/
-
                         List<Approve> waitAuditList = approveJoinMapper.selectJoinList(Approve.class,
                                 new MPJLambdaWrapper<Approve>()
                                         .selectAll(Approve.class)
@@ -1419,6 +1462,7 @@
                         List<String> memberPhone = waitAuditList.stream().filter(i->StringUtils.isNotBlank(i.getMemberPhone())).map(i->i.getMemberPhone()).collect(Collectors.toList());
                         List<String> openIdList =waitAuditList.stream().filter(i->StringUtils.isNotBlank(i.getSystemOpenid())).map(i->i.getSystemOpenid()).collect(Collectors.toList());
 
+
                         this.sendNextLvSms(approve,approveDTO,memberPhone,openIdList);
 
                     }
@@ -1428,7 +1472,7 @@
 //                    }
                 }
             }
-            this.passNextNotices(dealBusinessBean,notices,approve,approveList,approveCopyList,approveDTO);
+            this.passNextNotices(dealBusinessBean,notices,approve,approveList,approveCopyList,approveDTO,dealDDToDo);
         }
         //澶勭悊涓氬姟鏁版嵁
         if(dealBusinessBean){
@@ -1442,6 +1486,12 @@
     public void sendNextLvSms(Approve approve ,ApproveDTO approveDTO , List<String> memberPhone ,List<String> openIdList){
         WxPlatNotice wxPlatNotice = new WxPlatNotice();
         //鐗╂祦杞﹂绾�
+        List<Member> memberList = memberMapper.selectList(new QueryWrapper<Member>().lambda()
+                .in(Member::getPhone,memberPhone)
+                .eq(Member::getIsdeleted,Constants.ZERO)
+                .eq(Member::getStatus,Constants.ZERO)
+                .isNotNull(Member::getErpId)
+         );
         if(approveDTO.getObjType().equals(Constants.approveObjectType.reason)){
             SmsEmailServiceImpl.sendPlatformBookSms(systemDictDataBiz,
                     emayService,smsEmailMapper,smsConfigMapper,platformBooksMapper,approveDTO.getObjId(),
@@ -1468,9 +1518,15 @@
                     SmsConstants.carUseBookContent.carUseBookWaitAudit,
                     approveDTO.getCheckInfo(),memberPhone);
             //鍙戦�佸叕浼楀彿閫氱煡
-            if(CollectionUtils.isNotEmpty(openIdList)){
-                CarUseBook carUseBook = carUseBookMapper.selectById(approve.getObjId());
-                if(Objects.nonNull(carUseBook)){
+            CarUseBook carUseBook = carUseBookMapper.selectJoinOne(CarUseBook.class,
+                    new MPJLambdaWrapper<CarUseBook>()
+                            .selectAll(CarUseBook.class)
+                            .selectAs(Member::getName,CarUseBook::getMemberName)
+                            .leftJoin(Member.class,Member::getId,CarUseBook::getMemberId)
+                            .eq(CarUseBook::getId,approve.getObjId())
+                            .last(" limit 1 ")
+            );
+            if(CollectionUtils.isNotEmpty(openIdList)&&Objects.nonNull(carUseBook)){ 
                     SystemUser systemUser = systemUserMapper.selectById(carUseBook.getCreator());
                     if(Objects.nonNull(systemUser)){
                         carUseBook.setMemberName(systemUser.getRealname());
@@ -1479,9 +1535,19 @@
                                 wxNoticeConfigMapper,carUseBook,
                                 WxPlatConstants.carUseBookContent.carUseBookWaitAudit, 
                                 openIdList,1);
-                    }
-                }
+                    } 
             }
+            //鍙戦�侀拤閽夊緟鍔� 鍏姟杞︾敵璇�
+            if(Objects.nonNull(carUseBook)&&Objects.nonNull(memberList)){
+                //鏍囪褰撳墠瀹℃壒浜哄凡瀹屾垚
+                dingTalk.updToDoNoticeInfoStatus(carUseBook.getDdBelongToUnionId(),carUseBook.getDdToDoId());
+                //TODO 缂哄皯鍩熷悕鍓嶇紑鍐呭
+                String ddTalkId = dingTalk.toDoNotice(StringUtils.isNotBlank(carUseBook.getMemberName())?(carUseBook.getMemberName()+"鎻愪氦鐨勫叕鍔$敤杞︾敵璇�"):"鍏姟杞︾敤杞︾敵璇�",
+                        memberList.stream().map(i->i.getErpId()).collect(Collectors.toList()) ,
+                        dingTalk.getToDoCarUseBookFiledInfo(carUseBook),"pages/staff/vehicle/sendACarDetail?id="+carUseBook.getId());
+                carUseBookMapper.update(new UpdateWrapper<CarUseBook>().lambda()
+                        .set(CarUseBook::getDdToDoId,ddTalkId).eq(CarUseBook::getId,carUseBook.getId()));
+            } 
         }else
             //璁垮鐢宠/鎶ュ
             if(approveDTO.getObjType().equals(Constants.approveObjectType.unConstructionVisit)
@@ -1506,6 +1572,16 @@
                                 openIdList
                         );
                     }
+                    if(Objects.nonNull(visits)&&Objects.nonNull(memberList)){
+                        //鏍囪褰撳墠瀹℃壒浜哄凡瀹屾垚
+                        dingTalk.updToDoNoticeInfoStatus(visits.getDdBelongToUnionId(),visits.getDdToDoId());
+                        //TODO 缂哄皯鍩熷悕鍓嶇紑鍐呭
+                        String ddTalkId = dingTalk.toDoNotice(visits.getName()+"鐨勮瀹㈢敵璇�",
+                                memberList.stream().map(i->i.getErpId()).collect(Collectors.toList()) ,
+                                dingTalk.getToDoVisitFiledInfo(visits),"pages/appointmentDetails/appointmentDetails?id="+visits.getId());
+                        visitsMapper.update(new UpdateWrapper<Visits>().lambda()
+                                .set(Visits::getDdToDoId,ddTalkId).eq(Visits::getId,visits.getId()));
+                    }
 
                 }
             }
@@ -1518,15 +1594,15 @@
      * @param dealBusinessBean  鏄惁闇�瑕佽繘琛屾洿鏂颁笟鍔℃暟鎹姸鎬�
      * @param approve  瀹℃壒璁板綍
      * @param approveList  鍚岀骇寰呭鎵规暟鎹�
+     * @param dealDDToDo  鏄惁澶勭悊 褰撳墠瀹℃壒淇℃伅浜虹殑閽夐拤鐨勫伐浣滈�氱煡
+     *
      */
-    public void passNextNotices(Boolean dealBusinessBean,Notices notices,Approve approve,List<Approve> approveList,List<Approve> copyList,ApproveDTO approveDTO){
+    public void passNextNotices(Boolean dealBusinessBean,Notices notices,Approve approve,List<Approve> approveList,List<Approve> copyList,ApproveDTO approveDTO,Boolean dealDDToDo){
         //鏈紑鍚笅涓�绾ф椂锛屾搷浣滃悗鐨勫緟瀹℃壒浜�
         String memberNames =notices.getParam5()
                 .replaceAll(","+notices.getRemark(),"")
                 .replaceAll(notices.getRemark()+",","")
                 .replaceAll(notices.getRemark(),"");
-
-
 
         //1銆佷慨鏀硅嚜宸辩殑鏁版嵁璁板綍
         noticesJoinMapper.update(null,new UpdateWrapper<Notices>().lambda()
@@ -1607,6 +1683,30 @@
                 }
             }
         }
+        if(dealDDToDo){
+            if(approveDTO.getObjType().equals(Constants.approveObjectType.unConstructionVisit)
+                    ||approveDTO.getObjType().equals(Constants.approveObjectType.constructionVisit)
+                    ||approveDTO.getObjType().equals(Constants.approveObjectType.visitReporting)) {
+                Member member = memberMapper.selectById(approve.getChekorId());
+                // 璁垮 涓夌被涓氬姟鏁版嵁
+                Visits visits = visitsMapper.selectById(approveDTO.getObjId());
+                if(Objects.nonNull(member)&&Objects.nonNull(member.getErpId())
+                        &&Objects.nonNull(visits)&&Objects.nonNull(visits.getDdToDoId())&&Objects.nonNull(visits.getDdBelongToUnionId())){
+                    dingTalk.updUserToDoNoticeInfoStatus(visits.getDdBelongToUnionId(),visits.getDdToDoId(),member.getErpId());
+                }
+            }else if(approveDTO.getObjType().equals(Constants.approveObjectType.cityUseCar)||approveDTO.getObjType().equals(
+                    Constants.approveObjectType.unCityUseCar)){
+                Member member = memberMapper.selectById(approve.getChekorId());
+                CarUseBook carUseBook = carUseBookJoinMapper.selectById(approveDTO.getObjId());
+                if(Objects.nonNull(member)&&Objects.nonNull(member.getErpId())
+                        &&Objects.nonNull(carUseBook)&&Objects.nonNull(carUseBook.getDdToDoId())&&Objects.nonNull(carUseBook.getDdBelongToUnionId())){
+                    dingTalk.updUserToDoNoticeInfoStatus(carUseBook.getDdBelongToUnionId(),carUseBook.getDdToDoId(),member.getErpId());
+                }
+            }
+
+
+
+        }
     }
 
 
@@ -1654,11 +1754,13 @@
 
     public void dealBusinessData(ApproveDTO approveDTO,Approve approve){
         WxPlatNotice wxPlatNotice = new WxPlatNotice();
+        Visits visits = new Visits();
+        CarUseBook carUseBook = new CarUseBook();
         if(approveDTO.getObjType().equals(Constants.approveObjectType.unConstructionVisit)
                 ||approveDTO.getObjType().equals(Constants.approveObjectType.constructionVisit)
                 ||approveDTO.getObjType().equals(Constants.approveObjectType.visitReporting)){
             // 璁垮 涓夌被涓氬姟鏁版嵁
-            Visits visits = visitsMapper.selectById(approveDTO.getObjId());
+            visits = visitsMapper.selectById(approveDTO.getObjId());
             if(Objects.isNull(visits)){
                 throw new BusinessException(ResponseStatus.DATA_EMPTY.getCode(),"鏈煡璇㈠埌鐢宠璁板綍");
             }
@@ -1762,12 +1864,25 @@
                             Arrays.asList(visits.getOpenid().split(","))
                     );
                 }
+                //閽夐拤閫氱煡 璁垮琚浜烘垨鎶ュ鎻愪氦浜�
+                Member beVisitMember = memberMapper.selectById(Constants.equalsInteger(visits.getType(),Constants.TWO)?visits.getMemberId():visits.getReceptMemberId());
+                if(Objects.nonNull(beVisitMember)&&StringUtils.isNotBlank(beVisitMember.getDdId())){
+                    dingTalk.workInfoOANotice(Long.valueOf(systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.AGENT_ID).getCode()),
+                            beVisitMember.getDdId(),
+                            dingTalk.getVisitNoticeMsg(visits,visits.getName()+"鐨�"+(Constants.equalsInteger(visits.getType(),Constants.TWO)?"璁垮鎶ュ":"璁垮鐢宠")+"锛�"+
+                                    (Constants.equalsInteger(approveDTO.getStatus(),Constants.TWO)? "宸插鎵归�氳繃":"宸插鎵归┏鍥�"))
+                    );
+                }
             }
-
+            if(StringUtils.isNotBlank(visits.getDdBelongToUnionId())
+                    && StringUtils.isNotBlank(visits.getDdToDoId())){
+                //鏍囪褰撳墠閽夐拤瀹℃壒宸插畬鎴�
+                dingTalk.updToDoNoticeInfoStatus(visits.getDdBelongToUnionId(),visits.getDdToDoId());
+            }
         }else if(approveDTO.getObjType().equals(Constants.approveObjectType.cityUseCar)||approveDTO.getObjType().equals(
                 Constants.approveObjectType.unCityUseCar)){
             this.updDriver(approveDTO,approve,true);
-            CarUseBook carUseBook = carUseBookJoinMapper.selectById(approveDTO.getObjId());
+            carUseBook = carUseBookJoinMapper.selectById(approveDTO.getObjId());
             if(Objects.nonNull(carUseBook)){
                 SystemUser systemUser = systemUserMapper.selectById(carUseBook.getCreator());
                 //鍙戦�侀�氱煡鐭伅
@@ -1787,6 +1902,20 @@
                             Constants.equalsInteger(approveDTO.getStatus(),Constants.TWO)?WxPlatConstants.carUseBookContent.carUseBookAuditSuccess: WxPlatConstants.carUseBookContent.carUseBookAuditFail,
                             Arrays.asList(systemUser.getOpenid().split(",")),0);
                 }
+            }
+            //閽夐拤閫氱煡鍙戣捣浜�
+            Member creatMember = memberMapper.selectById(carUseBook.getMemberId());
+            if(Objects.nonNull(creatMember)&&StringUtils.isNotBlank(creatMember.getDdId())){
+                dingTalk.workInfoOANotice(Long.valueOf(systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.AGENT_ID).getCode()),
+                        creatMember.getErpId(),
+                                dingTalk.getCarUseNoticeMsg(carUseBook,carUseBook.getMemberName() + "鎻愪氦鐨勫叕鍔$敤杞︼紝"+
+                                        (Constants.equalsInteger(approveDTO.getStatus(),Constants.TWO)? "宸插鎵归�氳繃":"宸插鎵归┏鍥�"))
+                );
+            }
+            if(StringUtils.isNotBlank(carUseBook.getDdBelongToUnionId())
+                && StringUtils.isNotBlank(carUseBook.getDdToDoId())){
+                //鏍囪褰撳墠閽夐拤瀹℃壒宸插畬鎴�
+                dingTalk.updToDoNoticeInfoStatus(carUseBook.getDdBelongToUnionId(),carUseBook.getDdToDoId());
             }
 
         }else if(approveDTO.getObjType().equals(Constants.approveObjectType.reason)){
@@ -1862,13 +1991,33 @@
             throw new BusinessException(ResponseStatus.BAD_REQUEST);
         }
         if(Constants.equalsInteger(approveDTO.getStatus(),Constants.TWO)){
-            //澶勭悊閫氳繃 鏄剧ず鎵�鏈夌殑鎶勯�佽褰�
-            approveMapper.update(null,new UpdateWrapper<Approve>().lambda().set(Approve::getStatus,Constants.TWO)
-                    .set(Approve::getCheckDate,new Date())
-                    .eq(Approve::getObjId,approve.getObjId())
+            List<Approve> approveList = approveMapper.selectList(new QueryWrapper<Approve>().lambda().eq(Approve::getObjId,approve.getObjId())
                     .eq(Approve::getObjType,approve.getObjType())
-                    .eq(Approve::getType,Constants.ONE)
-            );
+                    .eq(Approve::getType,Constants.ONE));
+            if(CollectionUtils.isNotEmpty(approveList)){
+                //澶勭悊閫氳繃 鏄剧ず鎵�鏈夌殑鎶勯�佽褰�
+                approveMapper.update(null,new UpdateWrapper<Approve>().lambda().set(Approve::getStatus,Constants.TWO)
+                        .set(Approve::getCheckDate,new Date())
+                        .eq(Approve::getObjId,approve.getObjId())
+                        .eq(Approve::getObjType,approve.getObjType())
+                        .eq(Approve::getType,Constants.ONE)
+                );
+                List<Member> memberList = memberMapper.selectList(new QueryWrapper<Member>().lambda()
+                        .eq(Member::getIsdeleted,Constants.ZERO)
+                        .eq(Member::getStatus,Constants.ZERO)
+                        .isNotNull(Member::getDdId)
+                        .in(Member::getId,approveList.stream().map(i->i.getChekorId()).collect(Collectors.toList())));
+                if(CollectionUtils.isNotEmpty(memberList)){
+                    if(Objects.nonNull(visits)||Objects.nonNull(carUseBook)){
+                        dingTalk.workInfoOANotice(Long.valueOf(systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.AGENT_ID).getCode()),
+                                StringUtils.join(memberList.stream().map(i->i.getDdId()).collect(Collectors.toList()),","),
+                                Objects.nonNull(visits)?
+                                        dingTalk.getVisitNoticeMsg(visits,visits.getName()+"鐨�"+(Constants.equalsInteger(visits.getType(),Constants.TWO)?"璁垮鎶ュ":"璁垮鐢宠")+"锛屾妱閫佺粰鎮紝璇风煡鏅�"):
+                                        dingTalk.getCarUseNoticeMsg(carUseBook,carUseBook.getMemberName() + "鎻愪氦鐨勫叕鍔$敤杞︼紝鎶勯�佺粰鎮紝璇风煡鏅�")
+                        );
+                    }
+                }
+            }
         }
     }
 
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/HiddenDangerServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/HiddenDangerServiceImpl.java
index 7db1430..bc8fae7 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/HiddenDangerServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/HiddenDangerServiceImpl.java
@@ -7,6 +7,7 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.doumee.biz.system.SystemDictDataBiz;
 import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.dingTalk.DingTalk;
 import com.doumee.core.exception.BusinessException;
 import com.doumee.dao.business.dao.*;
 import com.doumee.dao.business.vo.GeneralDataVO;
@@ -98,6 +99,9 @@
 
     @Autowired
     private ApproveMapper approveMapper;
+
+    @Autowired
+    private DingTalk dingTalk;
 
 
     @Override
@@ -247,6 +251,13 @@
                     systemDictDataBiz.queryByCode(Constants.WX_PLATFORM,Constants.WX_PLATFORM_ACCESS_TOKEN).getCode(),
                     Arrays.asList(checkUser.getOpenid().split(",")));
         }
+
+        if(StringUtils.isNotBlank(member.getDdId())){
+            dingTalk.workInfoOANotice(Long.valueOf(systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.AGENT_ID).getCode()),
+                    member.getDdId(),
+                    dingTalk.getHiddenDangerNoticeMsg(hiddenDanger));
+        }
+
         return hiddenDanger.getId();
     }
 
@@ -794,6 +805,13 @@
                     systemDictDataBiz.queryByCode(Constants.WX_PLATFORM,Constants.WX_PLATFORM_ACCESS_TOKEN).getCode(),
                     Arrays.asList(checkUser.getOpenid().split(",")));
         }
+
+        if(StringUtils.isNotBlank(member.getDdId())){
+            dingTalk.workInfoOANotice(Long.valueOf(systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.AGENT_ID).getCode()),
+                    member.getDdId(),
+                    dingTalk.getHiddenDangerNoticeMsg(hiddenDanger));
+        }
+
     }
 
 
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetGridServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetGridServiceImpl.java
index d197518..28633c9 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetGridServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetGridServiceImpl.java
@@ -1,20 +1,33 @@
 package com.doumee.service.business.impl;
 
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.utils.Constants;
+import com.doumee.core.utils.DateUtil;
+import com.doumee.dao.business.*;
+import com.doumee.dao.business.dto.OptGridDTO;
+import com.doumee.dao.business.dto.CloseGridDTO;
+import com.doumee.dao.business.dto.GetDriverGridDTO;
+import com.doumee.dao.business.dto.OpenGridDriverDTO;
+import com.doumee.dao.business.model.*;
+import com.doumee.service.business.third.model.LoginUserInfo;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.core.utils.Utils;
-import com.doumee.dao.business.JkCabinetGridMapper;
-import com.doumee.dao.business.model.JkCabinetGrid;
 import com.doumee.service.business.JkCabinetGridService;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.doumee.service.business.third.model.PageWrap;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
+import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
+import org.springframework.transaction.annotation.Transactional;
 
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 閽ュ寵鏌滄煖鏍煎熀鏈俊鎭〃Service瀹炵幇
@@ -26,6 +39,16 @@
 
     @Autowired
     private JkCabinetGridMapper jkCabinetGridMapper;
+
+    @Autowired
+    private JkKeysMapper jkKeysMapper;
+
+    @Autowired
+    private JkCabinetMapper jkCabinetMapper;
+    @Autowired
+    private JkCabinetLogMapper jkCabinetLogMapper;
+
+
 
     @Override
     public Integer create(JkCabinetGrid jkCabinetGrid) {
@@ -54,7 +77,47 @@
 
     @Override
     public void updateById(JkCabinetGrid jkCabinetGrid) {
-        jkCabinetGridMapper.updateById(jkCabinetGrid);
+        if(Objects.isNull(jkCabinetGrid)
+                || Objects.isNull(jkCabinetGrid.getId())
+        ){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        LoginUserInfo loginUserInfo = jkCabinetGrid.getLoginUserInfo();
+        JkCabinetGrid model = jkCabinetGridMapper.selectById(jkCabinetGrid.getId());
+        if(Objects.isNull(model)|| Constants.equalsInteger(model.getIsdeleted(),Constants.ONE)){
+            throw new BusinessException(ResponseStatus.DATA_EMPTY);
+        }
+        if(Objects.nonNull(jkCabinetGrid.getKeyId())){
+            if(Objects.nonNull(model.getKeyId())){
+                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"宸茬粦瀹氾紝璇峰嬁閲嶅缁戝畾");
+            }
+            JkKeys keysModel = jkKeysMapper.selectById(jkCabinetGrid.getKeyId());
+            if(Objects.isNull(keysModel)|| Constants.equalsInteger(keysModel.getIsdeleted(),Constants.ONE)){
+                throw new BusinessException(ResponseStatus.DATA_EMPTY);
+            }
+            if(!Constants.equalsInteger(keysModel.getStatus(), (Constants.ZERO))){
+                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"閽ュ寵宸茶缁戝畾锛岃閫夋嫨鍏朵粬閽ュ寵缁戝畾");
+            }
+            //鏇存柊閽ュ寵鏌滀俊鎭�
+            jkCabinetGridMapper.update(new UpdateWrapper<JkCabinetGrid>().lambda()
+                    .set(JkCabinetGrid::getKeyId,jkCabinetGrid.getKeyId())
+                    .set(JkCabinetGrid::getEditor,loginUserInfo.getId())
+                    .set(JkCabinetGrid::getEditDate,DateUtil.getCurrDateTime())
+                    .set(JkCabinetGrid::getEditDate, DateUtil.getCurrDateTime())
+                    .eq(JkCabinetGrid::getId,jkCabinetGrid.getId()));
+            //鏍囪閽ュ寵淇℃伅
+            jkKeysMapper.update(new UpdateWrapper<JkKeys>().lambda()
+                    .set(JkKeys::getStatus,Constants.ONE)
+                    .eq(JkKeys::getId,jkCabinetGrid.getKeyId())
+            );
+            return;
+        }else if(Objects.nonNull(jkCabinetGrid.getChannelCode())||Objects.nonNull(jkCabinetGrid.getBoardCode())){
+            jkCabinetGridMapper.update(new UpdateWrapper<JkCabinetGrid>().lambda()
+                    .set(Objects.nonNull(jkCabinetGrid.getChannelCode()),JkCabinetGrid::getChannelCode,jkCabinetGrid.getChannelCode())
+                    .set(Objects.nonNull(jkCabinetGrid.getBoardCode()),JkCabinetGrid::getBoardCode,jkCabinetGrid.getBoardCode())
+                    .set(JkCabinetGrid::getEditDate, DateUtil.getCurrDateTime())
+                    .eq(JkCabinetGrid::getId,jkCabinetGrid.getId()));
+        }
     }
 
     @Override
@@ -87,57 +150,25 @@
     @Override
     public PageData<JkCabinetGrid> findPage(PageWrap<JkCabinetGrid> pageWrap) {
         IPage<JkCabinetGrid> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
-        QueryWrapper<JkCabinetGrid> queryWrapper = new QueryWrapper<>();
         Utils.MP.blankToNull(pageWrap.getModel());
-        if (pageWrap.getModel().getId() != null) {
-            queryWrapper.lambda().eq(JkCabinetGrid::getId, pageWrap.getModel().getId());
+        JkCabinetGrid model = pageWrap.getModel();
+        MPJLambdaWrapper<JkCabinetGrid> wrapper = new MPJLambdaWrapper<JkCabinetGrid>()
+                .selectAll(JkCabinetGrid.class)
+                .selectAs(JkCabinet::getName,JkCabinetGrid::getCabinetName)
+                .selectAs(JkKeys::getCode,JkCabinetGrid::getKeyCode)
+                .leftJoin(JkCabinet.class,JkCabinet::getId,JkCabinetGrid::getCabinetId)
+                .leftJoin(JkKeys.class,JkKeys::getId,JkCabinetGrid::getKeyId)
+                .eq(JkCabinetGrid::getIsdeleted,Constants.ZERO)
+                .eq(Objects.nonNull(model.getCabinetId()),JkCabinetGrid::getCabinetId,model.getCabinetId())
+                .eq(Objects.nonNull(model.getStatus()),JkCabinetGrid::getStatus,model.getStatus())
+                .isNull(Objects.nonNull(model.getBindStatus())&&Constants.equalsInteger(model.getBindStatus(),Constants.ZERO),JkCabinetGrid::getKeyId)
+                .isNotNull(Objects.nonNull(model.getBindStatus())&&Constants.equalsInteger(model.getBindStatus(),Constants.ONE),JkCabinetGrid::getKeyId)
+                .like(StringUtils.isNotBlank(model.getKeyCode()),JkKeys::getCode,model.getKeyCode());
+        IPage<JkCabinetGrid> iPage = jkCabinetGridMapper.selectJoinPage(page,JkCabinetGrid.class,wrapper);
+        for (JkCabinetGrid jkCabinetGrid:iPage.getRecords()) {
+            jkCabinetGrid.setBindStatus(Objects.isNull(jkCabinetGrid.getKeyId())?Constants.ZERO:Constants.ONE);
         }
-        if (pageWrap.getModel().getCreator() != null) {
-            queryWrapper.lambda().eq(JkCabinetGrid::getCreator, pageWrap.getModel().getCreator());
-        }
-        if (pageWrap.getModel().getCreateDate() != null) {
-            queryWrapper.lambda().ge(JkCabinetGrid::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
-            queryWrapper.lambda().le(JkCabinetGrid::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
-        }
-        if (pageWrap.getModel().getEditor() != null) {
-            queryWrapper.lambda().eq(JkCabinetGrid::getEditor, pageWrap.getModel().getEditor());
-        }
-        if (pageWrap.getModel().getEditDate() != null) {
-            queryWrapper.lambda().ge(JkCabinetGrid::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
-            queryWrapper.lambda().le(JkCabinetGrid::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
-        }
-        if (pageWrap.getModel().getIsdeleted() != null) {
-            queryWrapper.lambda().eq(JkCabinetGrid::getIsdeleted, pageWrap.getModel().getIsdeleted());
-        }
-        if (pageWrap.getModel().getInfo() != null) {
-            queryWrapper.lambda().eq(JkCabinetGrid::getInfo, pageWrap.getModel().getInfo());
-        }
-        if (pageWrap.getModel().getCabinetId() != null) {
-            queryWrapper.lambda().eq(JkCabinetGrid::getCabinetId, pageWrap.getModel().getCabinetId());
-        }
-        if (pageWrap.getModel().getCode() != null) {
-            queryWrapper.lambda().eq(JkCabinetGrid::getCode, pageWrap.getModel().getCode());
-        }
-        if (pageWrap.getModel().getKeyId() != null) {
-            queryWrapper.lambda().eq(JkCabinetGrid::getKeyId, pageWrap.getModel().getKeyId());
-        }
-        if (pageWrap.getModel().getSerialNo() != null) {
-            queryWrapper.lambda().eq(JkCabinetGrid::getSerialNo, pageWrap.getModel().getSerialNo());
-        }
-        if (pageWrap.getModel().getStatus() != null) {
-            queryWrapper.lambda().eq(JkCabinetGrid::getStatus, pageWrap.getModel().getStatus());
-        }
-        if (pageWrap.getModel().getWorkingStatus() != null) {
-            queryWrapper.lambda().eq(JkCabinetGrid::getWorkingStatus, pageWrap.getModel().getWorkingStatus());
-        }
-        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
-            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
-                queryWrapper.orderByDesc(sortData.getProperty());
-            } else {
-                queryWrapper.orderByAsc(sortData.getProperty());
-            }
-        }
-        return PageData.from(jkCabinetGridMapper.selectPage(page, queryWrapper));
+        return PageData.from(iPage);
     }
 
     @Override
@@ -145,4 +176,332 @@
         QueryWrapper<JkCabinetGrid> wrapper = new QueryWrapper<>(jkCabinetGrid);
         return jkCabinetGridMapper.selectCount(wrapper);
     }
+
+    @Override
+    public void updateStatusById(JkCabinetGrid jkCabinetGrid) {
+        if(Objects.isNull(jkCabinetGrid)
+                || Objects.isNull(jkCabinetGrid.getId())
+                || Objects.isNull(jkCabinetGrid.getStatus())){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        jkCabinetGridMapper.update(null,new UpdateWrapper<JkCabinetGrid>()
+                .lambda().set(JkCabinetGrid::getStatus,jkCabinetGrid.getStatus())
+                .set(JkCabinetGrid::getEditDate, DateUtil.getCurrDateTime())
+                .eq(JkCabinetGrid::getId,jkCabinetGrid.getId()));
+    }
+
+
+    @Override
+    @Transactional(rollbackFor = {Exception.class,BusinessException.class})
+    public void unBindKeys(List<Integer> idList){
+        if(CollectionUtils.isEmpty(idList)){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        if(idList.size()==Constants.ONE){
+            JkCabinetGrid model = jkCabinetGridMapper.selectById(idList.get(Constants.ZERO));
+            if(Objects.isNull(model)|| Constants.equalsInteger(model.getIsdeleted(),Constants.ONE)){
+                throw new BusinessException(ResponseStatus.DATA_EMPTY);
+            }
+            if(Objects.isNull(model.getKeyId())){
+                throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"褰撳墠瑙勬牸鏈粦瀹氶挜鍖欙紝璇峰埛鏂版煡鐪�");
+            }else{
+                //鏇存柊閽ュ寵鏌滀俊鎭�
+                jkCabinetGridMapper.update(new UpdateWrapper<JkCabinetGrid>().lambda()
+                        .set(JkCabinetGrid::getKeyId,null)
+                        .set(JkCabinetGrid::getEditDate, DateUtil.getCurrDateTime())
+                        .eq(JkCabinetGrid::getId,model.getId()));
+                JkKeys keysModel = jkKeysMapper.selectById(model.getKeyId());
+                if(Objects.nonNull(keysModel) && !Constants.equalsInteger(keysModel.getStatus(),Constants.ZERO)){
+                    jkKeysMapper.update(new UpdateWrapper<JkKeys>().lambda()
+                            .set(JkKeys::getStatus,Constants.ZERO)
+                            .eq(JkKeys::getId,keysModel.getId())
+                    );
+                }
+            }
+        }else{
+            List<JkCabinetGrid> jkCabinetGridList = jkCabinetGridMapper.selectList(new QueryWrapper<JkCabinetGrid>().lambda()
+                            .eq(JkCabinetGrid::getIsdeleted,Constants.ZERO)
+                            .isNotNull(JkCabinetGrid::getKeyId)
+                    .in(JkCabinetGrid::getId,idList));
+            if(CollectionUtils.isNotEmpty(jkCabinetGridList)){
+                jkCabinetGridMapper.update(new UpdateWrapper<JkCabinetGrid>().lambda()
+                        .set(JkCabinetGrid::getKeyId,null)
+                        .set(JkCabinetGrid::getEditDate, DateUtil.getCurrDateTime())
+                        .eq(JkCabinetGrid::getId,jkCabinetGridList.stream().map(i->i.getId()).collect(Collectors.toList())));
+                List<Integer> keyIdList = jkCabinetGridList.stream().filter(i->Objects.nonNull(i.getKeyId())).map(i->i.getKeyId()).collect(Collectors.toList());
+                if(CollectionUtils.isNotEmpty(keyIdList)){
+                    jkKeysMapper.update(new UpdateWrapper<JkKeys>().lambda()
+                            .set(JkKeys::getStatus,Constants.ZERO)
+                            .in(JkKeys::getId,keyIdList)
+                    );
+                }
+
+            }
+        }
+    }
+
+
+    /**
+     * 鏍囪鏁呴殰
+     */
+    @Override
+    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
+    public void markFault(OptGridDTO dto){
+        if(Objects.isNull(dto)
+                || Objects.isNull(dto.getCabinetId())
+                || CollectionUtils.isEmpty(dto.getGridIdList())){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        List<JkCabinetGrid> jkCabinetGridList = jkCabinetGridMapper.selectList(new QueryWrapper<JkCabinetGrid>().lambda().eq(JkCabinetGrid::getIsdeleted,Constants.ZERO)
+                .eq(JkCabinetGrid::getWorkingStatus,Constants.ZERO)
+                .eq(JkCabinetGrid::getCabinetId,dto.getCabinetId())
+                .in(JkCabinetGrid::getId,dto.getGridIdList())
+        );
+        if(CollectionUtils.isEmpty(jkCabinetGridList)){
+            return;
+        }
+        LoginUserInfo loginUserInfo = dto.getLoginUserInfo();
+        for (JkCabinetGrid jkCabinetGrid:jkCabinetGridList) {
+            jkCabinetGrid.setEditor(loginUserInfo.getId());
+            jkCabinetGrid.setEditDate(new Date());
+            jkCabinetGrid.setWorkingStatus(Constants.ONE);
+            jkCabinetGridMapper.updateById(jkCabinetGrid);
+        }
+    }
+
+    /**
+     * 鏍囪缁翠慨淇濆吇
+     */
+    @Override
+    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
+    public void markRepair(OptGridDTO dto){
+        if(Objects.isNull(dto)
+                || Objects.isNull(dto.getCabinetId())
+                || CollectionUtils.isEmpty(dto.getGridIdList())){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        List<JkCabinetGrid> jkCabinetGridList = jkCabinetGridMapper.selectJoinList(JkCabinetGrid.class,
+                new MPJLambdaWrapper<JkCabinetGrid>().selectAll(JkCabinetGrid.class)
+                        .selectAs(JkKeys::getCode,JkCabinetGrid::getKeyCode)
+                        .selectAs(JkKeys::getCarCode,JkCabinetGrid::getCarCode)
+                        .selectAs(JkKeys::getCarId,JkCabinetGrid::getCarId)
+                .leftJoin(JkKeys.class,JkKeys::getId,JkCabinetGrid::getKeyId)
+                .eq(JkCabinetGrid::getIsdeleted,Constants.ZERO)
+                .eq(JkKeys::getStatus,Constants.ONE)
+                .eq(JkCabinetGrid::getWorkingStatus,Constants.ZERO)
+                .eq(JkCabinetGrid::getCabinetId,dto.getCabinetId())
+                .isNotNull(JkCabinetGrid::getKeyId)
+                .in(JkCabinetGrid::getId,dto.getGridIdList())
+        );
+        if(CollectionUtils.isEmpty(jkCabinetGridList)){
+            return;
+        }
+        for (JkCabinetGrid jkCabinetGrid:jkCabinetGridList) {
+            jkKeysMapper.update(null,new UpdateWrapper<JkKeys>().lambda()
+                    .set(JkKeys::getEditDate,DateUtil.getCurrDateTime())
+                    .set(JkKeys::getStatus,Constants.TWO)
+                    .eq(JkKeys::getId,jkCabinetGrid.getKeyId())
+            );
+        }
+    }
+
+
+    /**
+     * 鍙栨秷鏁呴殰
+     */
+    @Override
+    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
+    public void cancelFault(OptGridDTO dto){
+        if(Objects.isNull(dto)
+                || Objects.isNull(dto.getCabinetId())
+                || CollectionUtils.isEmpty(dto.getGridIdList())){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        List<JkCabinetGrid> jkCabinetGridList = jkCabinetGridMapper.selectList(new QueryWrapper<JkCabinetGrid>().lambda().eq(JkCabinetGrid::getIsdeleted,Constants.ZERO)
+                .eq(JkCabinetGrid::getWorkingStatus,Constants.ONE)
+                .eq(JkCabinetGrid::getCabinetId,dto.getCabinetId())
+                .in(JkCabinetGrid::getId,dto.getGridIdList())
+        );
+        if(CollectionUtils.isEmpty(jkCabinetGridList)){
+            return;
+        }
+        LoginUserInfo loginUserInfo = dto.getLoginUserInfo();
+        for (JkCabinetGrid jkCabinetGrid:jkCabinetGridList) {
+            jkCabinetGrid.setEditor(loginUserInfo.getId());
+            jkCabinetGrid.setEditDate(new Date());
+            jkCabinetGrid.setWorkingStatus(Constants.ZERO);
+            jkCabinetGridMapper.updateById(jkCabinetGrid);
+        }
+    }
+
+
+    /**
+     * 璁惧绠$悊鍛樻壒閲忓紑閿�
+     */
+    @Override
+    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
+    public void batchOpenGridAdmin(OptGridDTO dto){
+        if(Objects.isNull(dto)
+        || Objects.isNull(dto.getCabinetId())
+        || CollectionUtils.isEmpty(dto.getGridIdList())){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        List<JkCabinetGrid> jkCabinetGridList = jkCabinetGridMapper.selectList(new QueryWrapper<JkCabinetGrid>().lambda().eq(JkCabinetGrid::getIsdeleted,Constants.ZERO)
+                .eq(JkCabinetGrid::getCabinetId,dto.getCabinetId())
+                .in(JkCabinetGrid::getId,dto.getGridIdList())
+        );
+        if(CollectionUtils.isEmpty(jkCabinetGridList)){
+            return;
+        }
+        LoginUserInfo loginUserInfo = dto.getLoginUserInfo();
+        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(jkCabinetGridList)){
+            List<JkCabinetLog> jkCabinetLogs = new ArrayList<>();
+            for (JkCabinetGrid jkCabinetGrid:jkCabinetGridList) {
+                JkCabinetLog jkCabinetLog = new JkCabinetLog();
+                jkCabinetLog.setCreateDate(new Date());
+                jkCabinetLog.setCreator(loginUserInfo.getId());
+                jkCabinetLog.setIsdeleted(Constants.ZERO);
+                jkCabinetLog.setCabinetId(dto.getCabinetId());
+                jkCabinetLog.setGridId(jkCabinetGrid.getId());
+                jkCabinetLog.setAuthType(Constants.TWO);
+                jkCabinetLog.setMemberId(loginUserInfo.getMemberId());
+                if(Objects.nonNull(jkCabinetGrid.getKeyId())){
+                    JkKeys jkKeys = jkKeysMapper.selectById(jkCabinetGrid.getKeyId());
+                    if(Objects.nonNull(jkKeys)){
+                        if(!Constants.equalsInteger(jkKeys.getStatus(),Constants.ZERO)){
+                            jkCabinetLog.setCarId(jkKeys.getCarId());
+                            jkCabinetLog.setKeyInfo(jkKeys.getCarCode() + "_" + jkKeys.getCode() );
+                        }
+                        jkCabinetLog.setRoleType(jkKeys.getRoleType());
+                    }
+                }
+                jkCabinetLog.setType(Constants.ZERO);
+                jkCabinetLogs.add(jkCabinetLog);
+            }
+            jkCabinetLogMapper.insert(jkCabinetLogs);
+        }
+    }
+
+
+    /**
+     * 閽ュ寵鏌滃叧闂�
+     */
+    @Override
+    @Transactional(rollbackFor = {BusinessException.class,Exception.class})
+    public void closeGrid(CloseGridDTO dto){
+        if(Objects.isNull(dto)
+            || Objects.isNull(dto.getGridId())
+            || Objects.isNull(dto.getCabinetId())
+            || Objects.isNull(dto.getKeyStatus())
+            || Objects.isNull(dto.getAuthType())
+            || Objects.isNull(dto.getMemberId())
+        ){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        JkCabinetGrid jkCabinetGrid = jkCabinetGridMapper.selectOne(new QueryWrapper<JkCabinetGrid>().lambda().eq(JkCabinetGrid::getIsdeleted,Constants.ZERO)
+                .eq(JkCabinetGrid::getCabinetId,dto.getCabinetId())
+                .eq(JkCabinetGrid::getId,dto.getGridId())
+                .last(" limit 1 ")
+        );
+        if(Objects.isNull(jkCabinetGrid)){
+            return;
+        }
+        JkCabinetLog jkCabinetLog = new JkCabinetLog();
+        jkCabinetLog.setCreateDate(new Date());
+        jkCabinetLog.setIsdeleted(Constants.ZERO);
+        jkCabinetLog.setCabinetId(dto.getCabinetId());
+        jkCabinetLog.setGridId(jkCabinetGrid.getId());
+        jkCabinetLog.setAuthType(dto.getAuthType());
+        jkCabinetLog.setMemberId(dto.getMemberId());
+        if(Objects.nonNull(jkCabinetGrid.getKeyId())){
+            //鍙湁閽ュ寵鏌滅粦瀹氫簡閽ュ寵淇℃伅 鎵嶄細鏇存柊閽ュ寵鐨勪俊鎭�
+            JkKeys jkKeys = jkKeysMapper.selectById(jkCabinetGrid.getKeyId());
+            if(Objects.nonNull(jkKeys)){
+                if(!Constants.equalsInteger(jkKeys.getStatus(),Constants.ZERO)){
+                    jkCabinetLog.setCarId(jkKeys.getCarId());
+                    jkCabinetLog.setKeyInfo(jkKeys.getCarCode() + "_" + jkKeys.getCode() );
+                }
+                jkCabinetLog.setRoleType(jkKeys.getRoleType());
+                //閽ュ寵鐘舵�佷笌褰撳墠鎿嶄綔鐘舵�佷笉涓�鑷达紝鍒欒繘琛屾洿鏂伴挜鍖欑姸鎬�
+                if(!Constants.equalsInteger(jkKeys.getStatus(),dto.getKeyStatus())){
+                    jkKeysMapper.update(null,new UpdateWrapper<JkKeys>().lambda()
+                            .set(JkKeys::getEditDate,DateUtil.getCurrDateTime())
+                            .set(JkKeys::getStatus,dto.getKeyStatus())
+                            .eq(JkKeys::getId,jkKeys.getId())
+                    );
+                }
+            }
+        }
+        jkCabinetLog.setType(Constants.ONE);
+        jkCabinetLogMapper.insert(jkCabinetLog);
+    }
+
+
+    /**
+     * 鍙告満鑾峰彇鍙搷浣滅殑閽ュ寵鏌滄煖鏍�
+     */
+    @Override
+    public List<JkCabinetGrid> getDriverGrid(GetDriverGridDTO dto){
+        if(Objects.isNull(dto.getCabinetId())
+            || Objects.isNull(dto.getCabinetId())
+            || Objects.isNull(dto.getMemberId())
+            || Objects.isNull(dto.getType())){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        List<JkCabinetGrid> jkCabinetGridList = jkCabinetGridMapper.selectJoinList(JkCabinetGrid.class,
+                new MPJLambdaWrapper<JkCabinetGrid>().selectAll(JkCabinetGrid.class)
+                        .selectAs(JkKeys::getCode,JkCabinetGrid::getKeyCode)
+                        .selectAs(JkKeys::getCarCode,JkCabinetGrid::getCarCode)
+                        .selectAs(JkKeys::getCarId,JkCabinetGrid::getCarId)
+                        .leftJoin(JkKeys.class,JkKeys::getId,JkCabinetGrid::getKeyId)
+                        .eq(JkCabinetGrid::getIsdeleted,Constants.ZERO)
+                        .eq(JkCabinetGrid::getWorkingStatus,Constants.ZERO)
+                        .eq(JkCabinetGrid::getCabinetId,dto.getCabinetId())
+                        .in(Constants.equalsInteger(dto.getType(),Constants.ONE),JkKeys::getStatus,Constants.TWO,Constants.THREE)
+                        .in(Constants.equalsInteger(dto.getType(),Constants.ZERO),JkKeys::getStatus,Constants.ONE)
+                        .isNotNull(JkCabinetGrid::getKeyId)
+                        .apply(" t1.car_id in ( select c.CAR_ID from car_driver c left join cars c1 on c.car_id = c1.id  where c.ISDELETED = 0 and c.TYPE != 0 and   c.MEMBER_ID = "+dto.getMemberId()+" ) ")
+        );
+        return jkCabinetGridList;
+    }
+
+
+    /**
+     * 鍙告満寮�鍚煖鏍�
+     * @param openGridDriverDTO
+     */
+    @Override
+    public void openGridDriver(OpenGridDriverDTO openGridDriverDTO){
+        JkCabinetGrid jkCabinetGrid = jkCabinetGridMapper.selectOne(new QueryWrapper<JkCabinetGrid>().lambda().eq(JkCabinetGrid::getIsdeleted,Constants.ZERO)
+                .eq(JkCabinetGrid::getCabinetId,openGridDriverDTO.getCabinetId())
+                .eq(JkCabinetGrid::getId,openGridDriverDTO.getGridId())
+                .last(" limit 1 ")
+        );
+        if(Objects.isNull(jkCabinetGrid)){
+            return;
+        }
+        LoginUserInfo loginUserInfo = openGridDriverDTO.getLoginUserInfo();
+        List<JkCabinetLog> jkCabinetLogs = new ArrayList<>();
+        JkCabinetLog jkCabinetLog = new JkCabinetLog();
+        jkCabinetLog.setCreateDate(new Date());
+        jkCabinetLog.setCreator(loginUserInfo.getId());
+        jkCabinetLog.setIsdeleted(Constants.ZERO);
+        jkCabinetLog.setCabinetId(openGridDriverDTO.getCabinetId());
+        jkCabinetLog.setGridId(jkCabinetGrid.getId());
+        jkCabinetLog.setAuthType(openGridDriverDTO.getAuthType());
+        jkCabinetLog.setMemberId(loginUserInfo.getMemberId());
+        jkCabinetLog.setType(Constants.ZERO);
+        if(Objects.nonNull(jkCabinetGrid.getKeyId())){
+            JkKeys jkKeys = jkKeysMapper.selectById(jkCabinetGrid.getKeyId());
+            if(Objects.nonNull(jkKeys)){
+                if(!Constants.equalsInteger(jkKeys.getStatus(),Constants.ZERO)){
+                    jkCabinetLog.setCarId(jkKeys.getCarId());
+                    jkCabinetLog.setKeyInfo(jkKeys.getCarCode() + "_" + jkKeys.getCode() );
+                }
+                jkCabinetLog.setRoleType(jkKeys.getRoleType());
+            }
+        }
+        jkCabinetLogMapper.insert(jkCabinetLogs);
+    }
+
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetLogServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetLogServiceImpl.java
index bb3b8da..7e36a98 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetLogServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetLogServiceImpl.java
@@ -1,20 +1,24 @@
 package com.doumee.service.business.impl;
 
+import com.doumee.core.utils.Constants;
+import com.doumee.dao.business.model.*;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
 import com.doumee.core.utils.Utils;
 import com.doumee.dao.business.JkCabinetLogMapper;
-import com.doumee.dao.business.model.JkCabinetLog;
 import com.doumee.service.business.JkCabinetLogService;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
 import java.util.List;
+import java.util.Objects;
 
 /**
  * 閽ュ寵鏌滃紑鍏抽棬璁板綍Service瀹炵幇
@@ -87,66 +91,34 @@
     @Override
     public PageData<JkCabinetLog> findPage(PageWrap<JkCabinetLog> pageWrap) {
         IPage<JkCabinetLog> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
-        QueryWrapper<JkCabinetLog> queryWrapper = new QueryWrapper<>();
         Utils.MP.blankToNull(pageWrap.getModel());
-        if (pageWrap.getModel().getId() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getId, pageWrap.getModel().getId());
-        }
-        if (pageWrap.getModel().getCreator() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getCreator, pageWrap.getModel().getCreator());
-        }
-        if (pageWrap.getModel().getCreateDate() != null) {
-            queryWrapper.lambda().ge(JkCabinetLog::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
-            queryWrapper.lambda().le(JkCabinetLog::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
-        }
-        if (pageWrap.getModel().getEditor() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getEditor, pageWrap.getModel().getEditor());
-        }
-        if (pageWrap.getModel().getEditDate() != null) {
-            queryWrapper.lambda().ge(JkCabinetLog::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
-            queryWrapper.lambda().le(JkCabinetLog::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
-        }
-        if (pageWrap.getModel().getIsdeleted() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getIsdeleted, pageWrap.getModel().getIsdeleted());
-        }
-        if (pageWrap.getModel().getInfo() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getInfo, pageWrap.getModel().getInfo());
-        }
-        if (pageWrap.getModel().getCabinetId() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getCabinetId, pageWrap.getModel().getCabinetId());
-        }
-        if (pageWrap.getModel().getGridId() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getGridId, pageWrap.getModel().getGridId());
-        }
-        if (pageWrap.getModel().getAuthType() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getAuthType, pageWrap.getModel().getAuthType());
-        }
-        if (pageWrap.getModel().getCarId() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getCarId, pageWrap.getModel().getCarId());
-        }
-        if (pageWrap.getModel().getKeyId() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getKeyId, pageWrap.getModel().getKeyId());
-        }
-        if (pageWrap.getModel().getMemberId() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getMemberId, pageWrap.getModel().getMemberId());
-        }
-        if (pageWrap.getModel().getKeyInfo() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getKeyInfo, pageWrap.getModel().getKeyInfo());
-        }
-        if (pageWrap.getModel().getRoleType() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getRoleType, pageWrap.getModel().getRoleType());
-        }
-        if (pageWrap.getModel().getStatus() != null) {
-            queryWrapper.lambda().eq(JkCabinetLog::getStatus, pageWrap.getModel().getStatus());
-        }
-        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
-            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
-                queryWrapper.orderByDesc(sortData.getProperty());
-            } else {
-                queryWrapper.orderByAsc(sortData.getProperty());
+        JkCabinetLog model = pageWrap.getModel();
+        MPJLambdaWrapper<JkCabinetLog> wrapper = new MPJLambdaWrapper<JkCabinetLog>()
+                .selectAll(JkCabinetLog.class)
+                .selectAs(Member::getName,JkCabinetLog::getMemberName)
+                .selectAs(Company::getName,JkCabinetLog::getCompanyName)
+                .selectAs(JkCabinet::getName,JkCabinetLog::getCabinetName)
+                .selectAs(JkCabinetGrid::getCode,JkCabinetLog::getGridCode)
+                .leftJoin(JkCabinet.class,JkCabinet::getId,JkCabinetLog::getCabinetId)
+                .leftJoin(JkCabinetGrid.class,JkCabinetGrid::getId,JkCabinetLog::getGridId)
+                .leftJoin(Member.class,Member::getId,JkCabinetLog::getMemberId)
+                .leftJoin(Company.class,Company::getId,Member::getCompanyId)
+                .ge(Objects.nonNull(model.getStartDate()),JkCabinetLog::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getStartDate()))
+                .le(Objects.nonNull(model.getEndDate()),JkCabinetLog::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getEndDate()))
+                .like(StringUtils.isNotBlank(model.getMemberName()),Member::getName,model.getMemberName())
+                .eq(Objects.nonNull(model.getCabinetId()),JkCabinetLog::getCabinetId,model.getCabinetId())
+                .eq(Objects.nonNull(model.getKeyId()),JkCabinetLog::getKeyId,model.getKeyId())
+                .eq(Objects.nonNull(model.getAuthType()),JkCabinetLog::getAuthType,model.getAuthType())
+                .eq(Objects.nonNull(model.getStatus()),JkCabinetLog::getStatus,model.getStatus())
+                .eq(JkCabinetLog::getIsdeleted, Constants.ZERO)
+                .orderByDesc(JkCabinetLog::getCreateDate);
+        IPage<JkCabinetLog>  iPage = jkCabinetLogMapper.selectJoinPage(page,JkCabinetLog.class,wrapper);
+        for (JkCabinetLog jkCabinetLog:iPage.getRecords()) {
+            if(StringUtils.isNotBlank(jkCabinetLog.getCompanyName())&&StringUtils.isNotBlank(jkCabinetLog.getMemberName())){
+                jkCabinetLog.setMemberName(jkCabinetLog.getMemberName() + " - " + jkCabinetLog.getCompanyName() );
             }
         }
-        return PageData.from(jkCabinetLogMapper.selectPage(page, queryWrapper));
+        return PageData.from(iPage);
     }
 
     @Override
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetServiceImpl.java
index be0bceb..161d43f 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkCabinetServiceImpl.java
@@ -1,5 +1,21 @@
 package com.doumee.service.business.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import com.doumee.biz.system.SystemDictDataBiz;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.utils.Constants;
+import com.doumee.core.utils.DateUtil;
+import com.doumee.dao.business.JkCabinetGridMapper;
+import com.doumee.dao.business.JkKeysMapper;
+import com.doumee.dao.business.model.JkCabinetGrid;
+import com.doumee.dao.business.model.JkKeys;
+import com.doumee.dao.business.vo.AdminCabinetVO;
+import com.doumee.dao.business.vo.CabinetConfigDataVO;
+import com.doumee.dao.business.vo.CabinetDetailVO;
+import com.doumee.dao.business.vo.CabinetGridInfoVO;
+import com.doumee.dao.system.model.SystemDictData;
+import com.doumee.service.business.third.model.LoginUserInfo;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
 import com.doumee.core.utils.Utils;
@@ -10,11 +26,18 @@
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import lombok.extern.java.Log;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.annotation.Bean;
 import org.springframework.stereotype.Service;
-import org.springframework.util.CollectionUtils;
+import org.springframework.transaction.annotation.Transactional;
+import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
 
-import java.util.List;
+import java.math.BigDecimal;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 閽ュ寵鏌滃熀鏈俊鎭〃Service瀹炵幇
@@ -27,15 +50,121 @@
     @Autowired
     private JkCabinetMapper jkCabinetMapper;
 
+    @Autowired
+    private JkCabinetGridMapper jkCabinetGridMapper;
+
+    @Autowired
+    private JkKeysMapper jkKeysMapper;
+
+    @Autowired
+    private SystemDictDataBiz systemDictDataBiz;
+
     @Override
+    @Transactional(rollbackFor = {Exception.class,BusinessException.class})
     public Integer create(JkCabinet jkCabinet) {
+        if(Objects.isNull(jkCabinet)
+            || StringUtils.isBlank(jkCabinet.getCode())
+            || StringUtils.isBlank(jkCabinet.getName())
+            || StringUtils.isBlank(jkCabinet.getDevId())
+            || StringUtils.isBlank(jkCabinet.getLinkAddr())
+            || StringUtils.isBlank(jkCabinet.getCode())
+
+            || Objects.isNull(jkCabinet.getPort())
+            || CollectionUtils.isEmpty(jkCabinet.getManagerIdList())
+            || CollectionUtils.isEmpty(jkCabinet.getAuthMemberIdList())
+            || Objects.isNull(jkCabinet.getDoubleAuth())
+
+            || Objects.isNull(jkCabinet.getRowNum())
+            || jkCabinet.getRowNum() <= Constants.ZERO
+            || Objects.isNull(jkCabinet.getColumnNum())
+            || jkCabinet.getColumnNum() <= Constants.ZERO
+            || Objects.isNull(jkCabinet.getNoType())
+            || Objects.isNull(jkCabinet.getSortType())
+            || (
+                Constants.equalsInteger(jkCabinet.getNoType(),Constants.ONE)
+                && ( Objects.isNull(jkCabinet.getNoIndex()) || Objects.isNull(jkCabinet.getNoLength()) || StringUtils.isBlank(jkCabinet.getNoPrefix()) )
+                )
+        ){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        //鏌ヨ缂栧彿鏄惁閲嶅
+        if(jkCabinetMapper.selectCount(new QueryWrapper<JkCabinet>().lambda().eq(JkCabinet::getCode,jkCabinet.getCode()).eq(JkCabinet::getIsdeleted,Constants.ZERO))>Constants.ZERO){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"閽ュ寵鏌滆澶囩紪鍙峰凡瀛樺湪锛�");
+        }
+        if(jkCabinetMapper.selectCount(new QueryWrapper<JkCabinet>().lambda().eq(JkCabinet::getDevId,jkCabinet.getDevId()).eq(JkCabinet::getIsdeleted,Constants.ZERO))>Constants.ZERO){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"閽ュ寵鏌滆澶嘔D宸插瓨鍦紒");
+        }
+        LoginUserInfo loginUserInfo = jkCabinet.getLoginUserInfo();
+        jkCabinet.setCreateDate(new Date());
+        jkCabinet.setEditDate(jkCabinet.getCreateDate());
+        jkCabinet.setCreator(loginUserInfo.getId());
+        jkCabinet.setEditor(loginUserInfo.getId());
+        jkCabinet.setIsdeleted(Constants.ZERO);
+        jkCabinet.setStatus(Constants.ZERO);
+        jkCabinet.setRunStatus(Constants.ONE);
+        if(StringUtils.isNotBlank(jkCabinet.getJwd())&&jkCabinet.getJwd().split(",").length>Constants.ONE){
+            jkCabinet.setLongitude(new BigDecimal(jkCabinet.getJwd().split(",")[Constants.ZERO]));
+            jkCabinet.setLatitude(new BigDecimal(jkCabinet.getJwd().split(",")[Constants.ONE]));
+        }
+        jkCabinet.setManagerId(String.join(",",jkCabinet.getManagerIdList()));
+        jkCabinet.setAuthMemberId(String.join(",",jkCabinet.getAuthMemberIdList()));
         jkCabinetMapper.insert(jkCabinet);
+        this.createGrid(jkCabinet);
         return jkCabinet.getId();
+    }
+
+
+    public void createGrid(JkCabinet jkCabinet){
+        LoginUserInfo loginUserInfo = jkCabinet.getLoginUserInfo();
+        Integer startNo =  Constants.equalsInteger(jkCabinet.getNoType(),Constants.ZERO)?1:jkCabinet.getNoIndex() ;
+        List<JkCabinetGrid> jkCabinetGridList = new ArrayList<>();
+        Integer maxNum = jkCabinet.getRowNum() * jkCabinet.getColumnNum();
+        for (int i = 0; i < maxNum; i++) {
+            JkCabinetGrid grid = new JkCabinetGrid();
+            grid.setCreateDate(new Date());
+            grid.setEditDate(jkCabinet.getCreateDate());
+            grid.setCreator(loginUserInfo.getId());
+            grid.setEditor(loginUserInfo.getId());
+            grid.setIsdeleted(Constants.ZERO);
+            grid.setStatus(Constants.ZERO);
+            grid.setCabinetId(jkCabinet.getId());
+            if(Constants.equalsInteger(jkCabinet.getNoType(),Constants.ZERO)){
+                grid.setCode(StringUtils.leftPad(startNo.toString(),maxNum.toString().length()+1,"0"));
+            }else{
+                grid.setCode(jkCabinet.getNoPrefix() +  StringUtils.leftPad(startNo.toString(),jkCabinet.getNoLength(),"0"));
+            }
+
+            jkCabinetGridList.add(grid);
+            startNo = startNo + 1;
+        }
+        jkCabinetGridMapper.insert(jkCabinetGridList);
     }
 
     @Override
     public void deleteById(Integer id) {
-        jkCabinetMapper.deleteById(id);
+        JkCabinet jkCabinet = jkCabinetMapper.selectById(id);
+        if(Constants.equalsInteger(jkCabinet.getStatus(),Constants.ZERO)){
+           throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"闈炵鐢ㄦ暟鎹紝鏃犳硶杩涜鍒犻櫎");
+        }
+        //鏌ヨ閽ュ寵鏌滀笅鐨勬煖鏍间俊鎭�
+        List<JkCabinetGrid> jkCabinetGridList = jkCabinetGridMapper.selectList(new QueryWrapper<JkCabinetGrid>().lambda().eq(JkCabinetGrid::getIsdeleted,Constants.ZERO)
+                .eq(JkCabinetGrid::getCabinetId,jkCabinet.getId())
+        );
+        if(Objects.nonNull(jkCabinetGridList)){
+            jkCabinetGridMapper.update(null,new UpdateWrapper<JkCabinetGrid>().lambda().set(JkCabinetGrid::getIsdeleted,Constants.ONE)
+                    .in(JkCabinetGrid::getId,jkCabinetGridList.stream().map(i->i.getId()).collect(Collectors.toList()))
+            );
+            List<Integer> keyIdList = jkCabinetGridList.stream().filter(i->Objects.nonNull(i.getKeyId())).map(i->i.getKeyId()).collect(Collectors.toList());
+            if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(keyIdList)){
+                jkKeysMapper.update(null,new UpdateWrapper<JkKeys>().lambda()
+                        .set(JkKeys::getStatus,Constants.ZERO)
+                        .in(JkKeys::getId,keyIdList)
+                );
+            }
+        }
+        jkCabinetMapper.update(null,new UpdateWrapper<JkCabinet>().lambda()
+                .set(JkCabinet::getIsdeleted,Constants.ONE)
+                .eq(JkCabinet::getId,jkCabinet.getId()));
     }
 
     @Override
@@ -54,8 +183,59 @@
 
     @Override
     public void updateById(JkCabinet jkCabinet) {
+        if(Objects.isNull(jkCabinet)
+                || Objects.isNull(jkCabinet.getId())
+                || StringUtils.isBlank(jkCabinet.getCode())
+                || StringUtils.isBlank(jkCabinet.getName())
+                || StringUtils.isBlank(jkCabinet.getDevId())
+                || StringUtils.isBlank(jkCabinet.getLinkAddr())
+                || StringUtils.isBlank(jkCabinet.getCode())
+                || CollectionUtils.isEmpty(jkCabinet.getManagerIdList())
+                || CollectionUtils.isEmpty(jkCabinet.getAuthMemberIdList())
+                || Objects.isNull(jkCabinet.getPort())
+                || Objects.isNull(jkCabinet.getDoubleAuth())
+        ){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        jkCabinet.setRowNum(null);
+        jkCabinet.setColumnNum(null);
+        jkCabinet.setSortType(null);
+        jkCabinet.setNoType(null);
+        jkCabinet.setNoIndex(null);
+        jkCabinet.setNoLength(null);
+        jkCabinet.setNoPrefix(null);
+        //鏌ヨ缂栧彿鏄惁閲嶅
+        if(jkCabinetMapper.selectCount(new QueryWrapper<JkCabinet>().lambda().ne(JkCabinet::getId,jkCabinet.getId()).eq(JkCabinet::getCode,jkCabinet.getCode()).eq(JkCabinet::getIsdeleted,Constants.ZERO))>Constants.ZERO){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"閽ュ寵鏌滆澶囩紪鍙峰凡瀛樺湪锛�");
+        }
+        if(jkCabinetMapper.selectCount(new QueryWrapper<JkCabinet>().lambda().ne(JkCabinet::getId,jkCabinet.getId()).eq(JkCabinet::getDevId,jkCabinet.getDevId()).eq(JkCabinet::getIsdeleted,Constants.ZERO))>Constants.ZERO){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"閽ュ寵鏌滆澶嘔D宸插瓨鍦紒");
+        }
+        LoginUserInfo loginUserInfo = jkCabinet.getLoginUserInfo();
+        jkCabinet.setEditDate(new Date());
+        jkCabinet.setEditor(loginUserInfo.getId());
+        if(StringUtils.isNotBlank(jkCabinet.getJwd())&&jkCabinet.getJwd().split(",").length>Constants.ONE){
+            jkCabinet.setLongitude(new BigDecimal(jkCabinet.getJwd().split(",")[Constants.ZERO]));
+            jkCabinet.setLatitude(new BigDecimal(jkCabinet.getJwd().split(",")[Constants.ONE]));
+        }
+        jkCabinet.setManagerId(String.join(",",jkCabinet.getManagerIdList()));
+        jkCabinet.setAuthMemberId(String.join(",",jkCabinet.getAuthMemberIdList()));
         jkCabinetMapper.updateById(jkCabinet);
     }
+
+    @Override
+    public void updateStatusById(JkCabinet jkCabinet) {
+        if(Objects.isNull(jkCabinet)
+        || Objects.isNull(jkCabinet.getId())
+        || Objects.isNull(jkCabinet.getStatus())){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        jkCabinetMapper.update(null,new UpdateWrapper<JkCabinet>()
+                .lambda().set(JkCabinet::getStatus,jkCabinet.getStatus())
+                .set(JkCabinet::getEditDate, DateUtil.getCurrDateTime())
+                .eq(JkCabinet::getId,jkCabinet.getId()));
+    }
+
 
     @Override
     public void updateByIdInBatch(List<JkCabinet> jkCabinets) {
@@ -72,6 +252,18 @@
         return jkCabinetMapper.selectById(id);
     }
 
+
+    @Override
+    public JkCabinet getDetail(Integer id){
+        JkCabinet jkCabinet = jkCabinetMapper.selectById(id);
+        if(Objects.nonNull(jkCabinet.getLongitude())
+            && Objects.nonNull(jkCabinet.getLatitude())){
+            jkCabinet.setJwd(jkCabinet.getLongitude() + "," + jkCabinet.getLatitude());
+        }
+        jkCabinet.setGridNum(jkCabinet.getColumnNum()*jkCabinet.getRowNum());
+        return jkCabinet;
+    }
+
     @Override
     public JkCabinet findOne(JkCabinet jkCabinet) {
         QueryWrapper<JkCabinet> wrapper = new QueryWrapper<>(jkCabinet);
@@ -80,6 +272,8 @@
 
     @Override
     public List<JkCabinet> findList(JkCabinet jkCabinet) {
+        jkCabinet.setIsdeleted(Constants.ZERO);
+        jkCabinet.setStatus(Constants.ZERO);
         QueryWrapper<JkCabinet> wrapper = new QueryWrapper<>(jkCabinet);
         return jkCabinetMapper.selectList(wrapper);
     }
@@ -87,103 +281,20 @@
     @Override
     public PageData<JkCabinet> findPage(PageWrap<JkCabinet> pageWrap) {
         IPage<JkCabinet> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
-        QueryWrapper<JkCabinet> queryWrapper = new QueryWrapper<>();
         Utils.MP.blankToNull(pageWrap.getModel());
-        if (pageWrap.getModel().getId() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getId, pageWrap.getModel().getId());
+        JkCabinet model = pageWrap.getModel();
+        IPage<JkCabinet> iPage = jkCabinetMapper.selectPage(page, new QueryWrapper<JkCabinet>()
+                .lambda()
+                .eq(JkCabinet::getIsdeleted,Constants.ZERO)
+                .like(StringUtils.isNotBlank(model.getName()),JkCabinet::getName, model.getName())
+                .like(StringUtils.isNotBlank(model.getCode()),JkCabinet::getCode, model.getCode())
+                .eq(Objects.nonNull(model.getStatus()),JkCabinet::getStatus, model.getStatus())
+                .eq(Objects.nonNull(model.getRunStatus()),JkCabinet::getRunStatus, model.getRunStatus())
+        );
+        for (JkCabinet jkCabinet:iPage.getRecords()) {
+            jkCabinet.setGridNum(jkCabinet.getColumnNum()*jkCabinet.getRowNum());
         }
-        if (pageWrap.getModel().getCreator() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getCreator, pageWrap.getModel().getCreator());
-        }
-        if (pageWrap.getModel().getCreateDate() != null) {
-            queryWrapper.lambda().ge(JkCabinet::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
-            queryWrapper.lambda().le(JkCabinet::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
-        }
-        if (pageWrap.getModel().getEditor() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getEditor, pageWrap.getModel().getEditor());
-        }
-        if (pageWrap.getModel().getEditDate() != null) {
-            queryWrapper.lambda().ge(JkCabinet::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
-            queryWrapper.lambda().le(JkCabinet::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
-        }
-        if (pageWrap.getModel().getIsdeleted() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getIsdeleted, pageWrap.getModel().getIsdeleted());
-        }
-        if (pageWrap.getModel().getInfo() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getInfo, pageWrap.getModel().getInfo());
-        }
-        if (pageWrap.getModel().getCode() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getCode, pageWrap.getModel().getCode());
-        }
-        if (pageWrap.getModel().getName() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getName, pageWrap.getModel().getName());
-        }
-        if (pageWrap.getModel().getDevId() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getDevId, pageWrap.getModel().getDevId());
-        }
-        if (pageWrap.getModel().getSerialNo() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getSerialNo, pageWrap.getModel().getSerialNo());
-        }
-        if (pageWrap.getModel().getLinkAddr() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getLinkAddr, pageWrap.getModel().getLinkAddr());
-        }
-        if (pageWrap.getModel().getStatus() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getStatus, pageWrap.getModel().getStatus());
-        }
-        if (pageWrap.getModel().getPort() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getPort, pageWrap.getModel().getPort());
-        }
-        if (pageWrap.getModel().getManagerId() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getManagerId, pageWrap.getModel().getManagerId());
-        }
-        if (pageWrap.getModel().getUseTime() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getUseTime, pageWrap.getModel().getUseTime());
-        }
-        if (pageWrap.getModel().getDoubleAuth() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getDoubleAuth, pageWrap.getModel().getDoubleAuth());
-        }
-        if (pageWrap.getModel().getAuthMemberId() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getAuthMemberId, pageWrap.getModel().getAuthMemberId());
-        }
-        if (pageWrap.getModel().getRowNum() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getRowNum, pageWrap.getModel().getRowNum());
-        }
-        if (pageWrap.getModel().getColumnNum() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getColumnNum, pageWrap.getModel().getColumnNum());
-        }
-        if (pageWrap.getModel().getHaertTime() != null) {
-            queryWrapper.lambda().ge(JkCabinet::getHaertTime, Utils.Date.getStart(pageWrap.getModel().getHaertTime()));
-            queryWrapper.lambda().le(JkCabinet::getHaertTime, Utils.Date.getEnd(pageWrap.getModel().getHaertTime()));
-        }
-        if (pageWrap.getModel().getLocation() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getLocation, pageWrap.getModel().getLocation());
-        }
-        if (pageWrap.getModel().getLongitude() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getLongitude, pageWrap.getModel().getLongitude());
-        }
-        if (pageWrap.getModel().getLatitude() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getLatitude, pageWrap.getModel().getLatitude());
-        }
-        if (pageWrap.getModel().getNoType() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getNoType, pageWrap.getModel().getNoType());
-        }
-        if (pageWrap.getModel().getNoPrefix() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getNoPrefix, pageWrap.getModel().getNoPrefix());
-        }
-        if (pageWrap.getModel().getNoLength() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getNoLength, pageWrap.getModel().getNoLength());
-        }
-        if (pageWrap.getModel().getNoIndex() != null) {
-            queryWrapper.lambda().eq(JkCabinet::getNoIndex, pageWrap.getModel().getNoIndex());
-        }
-        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
-            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
-                queryWrapper.orderByDesc(sortData.getProperty());
-            } else {
-                queryWrapper.orderByAsc(sortData.getProperty());
-            }
-        }
-        return PageData.from(jkCabinetMapper.selectPage(page, queryWrapper));
+        return PageData.from(iPage);
     }
 
     @Override
@@ -191,4 +302,135 @@
         QueryWrapper<JkCabinet> wrapper = new QueryWrapper<>(jkCabinet);
         return jkCabinetMapper.selectCount(wrapper);
     }
+
+
+
+    @Override
+    public CabinetConfigDataVO getCabinetConfigDataVO(){
+        CabinetConfigDataVO cabinetConfigDataVO = new CabinetConfigDataVO();
+        cabinetConfigDataVO.setConcentration(systemDictDataBiz.queryByCode(Constants.CABINET_CONFIG,Constants.CONCENTRATION).getCode());
+        cabinetConfigDataVO.setPressure(systemDictDataBiz.queryByCode(Constants.CABINET_CONFIG,Constants.PRESSURE).getCode());
+        cabinetConfigDataVO.setBlowTime(systemDictDataBiz.queryByCode(Constants.CABINET_CONFIG,Constants.BLOW_TIME).getCode());
+        cabinetConfigDataVO.setThreshold(systemDictDataBiz.queryByCode(Constants.CABINET_CONFIG,Constants.THRESHOLD).getCode());
+        return cabinetConfigDataVO;
+
+    }
+
+
+    @Override
+    public void updCabinetConfig(CabinetConfigDataVO cabinetConfigDataVO){
+        if(Objects.isNull(cabinetConfigDataVO)
+        || (StringUtils.isBlank(cabinetConfigDataVO.getBlowTime())
+        && StringUtils.isBlank(cabinetConfigDataVO.getConcentration())
+                && StringUtils.isBlank(cabinetConfigDataVO.getPressure())
+                && StringUtils.isBlank(cabinetConfigDataVO.getThreshold())
+        )){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        if(StringUtils.isNotBlank(cabinetConfigDataVO.getConcentration())){
+            SystemDictData systemDictData = systemDictDataBiz.queryByCode(Constants.CABINET_CONFIG,Constants.CONCENTRATION);
+            systemDictData.setCode(cabinetConfigDataVO.getConcentration());
+            systemDictDataBiz.updateByIdNew(systemDictData);
+        }
+        if(StringUtils.isNotBlank(cabinetConfigDataVO.getPressure())){
+            SystemDictData systemDictData = systemDictDataBiz.queryByCode(Constants.CABINET_CONFIG,Constants.PRESSURE);
+            systemDictData.setCode(cabinetConfigDataVO.getPressure());
+            systemDictDataBiz.updateByIdNew(systemDictData);
+        }
+        if(StringUtils.isNotBlank(cabinetConfigDataVO.getBlowTime())){
+            SystemDictData systemDictData = systemDictDataBiz.queryByCode(Constants.CABINET_CONFIG,Constants.BLOW_TIME);
+            systemDictData.setCode(cabinetConfigDataVO.getBlowTime());
+            systemDictDataBiz.updateByIdNew(systemDictData);
+        }
+        if(StringUtils.isNotBlank(cabinetConfigDataVO.getThreshold())){
+            SystemDictData systemDictData = systemDictDataBiz.queryByCode(Constants.CABINET_CONFIG,Constants.THRESHOLD);
+            systemDictData.setCode(cabinetConfigDataVO.getThreshold());
+            systemDictDataBiz.updateByIdNew(systemDictData);
+        }
+    }
+
+
+
+
+    @Override
+    public List<AdminCabinetVO> getAdminCabinetInfo(LoginUserInfo loginUserInfo){
+        List<AdminCabinetVO> adminCabinetVOList = new ArrayList<>();
+        List<JkCabinet> jkCabinetList = jkCabinetMapper.selectList(new QueryWrapper<JkCabinet>()
+                .lambda()
+                .eq(JkCabinet::getIsdeleted,Constants.ZERO)
+                .apply(" FIND_IN_SET("+loginUserInfo.getId()+",MANAGER_ID) ")
+                .orderByAsc(JkCabinet::getCreateDate)
+        );
+        if(CollectionUtils.isNotEmpty(jkCabinetList)){
+            for (JkCabinet jkCabinet:jkCabinetList) {
+                AdminCabinetVO adminCabinetVO = new AdminCabinetVO();
+                BeanUtil.copyProperties(jkCabinet,adminCabinetVO);
+                adminCabinetVOList.add(adminCabinetVO);
+            }
+        }
+        return adminCabinetVOList;
+    }
+
+
+    @Override
+    public CabinetDetailVO getCabinetDetail(Integer cabinetId){
+        CabinetDetailVO cabinetDetailVO = new CabinetDetailVO();
+        JkCabinet cabinet = jkCabinetMapper.selectOne(new QueryWrapper<JkCabinet>()
+                .lambda()
+                .eq(JkCabinet::getIsdeleted,Constants.ZERO)
+                .eq(JkCabinet::getId,cabinetId)
+                .last(" limit 1")
+        );
+        if(Objects.isNull(cabinet)){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"瀵逛笉璧凤紝鏈煡璇㈠埌閽ュ寵鏌滀俊鎭�");
+        }
+        BeanUtil.copyProperties(cabinet,cabinetDetailVO);
+        cabinetDetailVO.setGridNum(Constants.ZERO);
+        cabinetDetailVO.setErrGridNum(Constants.ZERO);
+        cabinetDetailVO.setOnlineKeyNum(Constants.ZERO);
+        cabinetDetailVO.setServiceKeyNum(Constants.ZERO);
+        cabinetDetailVO.setOutKeyNum(Constants.ZERO);
+        cabinetDetailVO.setUnBindGridNum(Constants.ZERO);
+
+        //鎵�鏈夋煖鏍间俊鎭�
+        List<JkCabinetGrid> jkCabinetGridList =
+                jkCabinetGridMapper.selectJoinList(JkCabinetGrid.class, new MPJLambdaWrapper<JkCabinetGrid>()
+                .selectAll(JkCabinetGrid.class)
+                .selectAs(JkKeys::getCarCode,JkCabinetGrid::getCarCode)
+                .selectAs(JkKeys::getStatus,JkCabinetGrid::getKeyStatus)
+                .leftJoin(JkKeys.class,JkKeys::getId,JkCabinetGrid::getKeyId)
+                .eq(JkCabinetGrid::getIsdeleted,Constants.ZERO)
+                .eq(JkCabinetGrid::getCabinetId,cabinet.getId())
+                .orderByDesc(JkCabinetGrid::getCode)
+        );
+
+        List<CabinetGridInfoVO> cabinetGridInfoVOList = new ArrayList<>();
+        if(CollectionUtils.isNotEmpty(jkCabinetGridList)){
+            cabinetDetailVO.setGridNum(jkCabinetGridList.size());
+            for (JkCabinetGrid jkCabinetGrid:jkCabinetGridList) {
+                CabinetGridInfoVO cabinetGridInfoVO = new CabinetGridInfoVO();
+                BeanUtil.copyProperties(jkCabinetGrid,cabinetGridInfoVO);
+                cabinetGridInfoVO.setBindStatus(Objects.isNull(jkCabinetGrid.getKeyId())?Constants.ZERO:Constants.ONE);
+                cabinetGridInfoVOList.add(cabinetGridInfoVO);
+            }
+            cabinetDetailVO.setErrGridNum(
+                    cabinetGridInfoVOList.stream().filter(i->Constants.equalsInteger(i.getWorkingStatus(),Constants.ONE)).collect(Collectors.toList()).size()
+            );
+            cabinetDetailVO.setOnlineKeyNum(
+                    cabinetGridInfoVOList.stream().filter(i->Constants.equalsInteger(i.getKeyStatus(),Constants.ONE)).collect(Collectors.toList()).size()
+            );
+            cabinetDetailVO.setOutKeyNum(
+                    cabinetGridInfoVOList.stream().filter(i->Constants.equalsInteger(i.getKeyStatus(),Constants.TWO)).collect(Collectors.toList()).size()
+            );
+            cabinetDetailVO.setServiceKeyNum(
+                    cabinetGridInfoVOList.stream().filter(i->Constants.equalsInteger(i.getKeyStatus(),Constants.THREE)).collect(Collectors.toList()).size()
+            );
+            cabinetDetailVO.setUnBindGridNum(
+                    cabinetGridInfoVOList.stream().filter(i->Constants.equalsInteger(i.getBindStatus(),Constants.ZERO)).collect(Collectors.toList()).size()
+            );
+        }
+        return cabinetDetailVO;
+    }
+
+
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkIccardServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkIccardServiceImpl.java
index 0964dc4..fcb86bc 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkIccardServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkIccardServiceImpl.java
@@ -1,5 +1,12 @@
 package com.doumee.service.business.impl;
 
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.utils.Constants;
+import com.doumee.core.utils.DateUtil;
+import com.doumee.dao.business.model.*;
+import com.doumee.dao.system.model.SystemUser;
+import com.doumee.service.business.third.model.LoginUserInfo;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
 import com.doumee.core.utils.Utils;
@@ -10,11 +17,15 @@
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
+import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * 閽ュ寵鏌淚C鍗′俊鎭〃Service瀹炵幇
@@ -29,13 +40,39 @@
 
     @Override
     public Integer create(JkIccard jkIccard) {
+        if(Objects.isNull(jkIccard)
+            || StringUtils.isBlank(jkIccard.getCode())
+            || Objects.isNull(jkIccard.getStatus())
+            || Objects.isNull(jkIccard.getMemberId())
+            || Objects.isNull(jkIccard.getUserType())
+        ){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+
+        LoginUserInfo loginUserInfo = jkIccard.getLoginUserInfo();
+        jkIccard.setCreateDate(new Date());
+        jkIccard.setCreator(loginUserInfo.getId());
+        jkIccard.setEditDate(jkIccard.getCreateDate());
+        jkIccard.setEditor(jkIccard.getCreator());
+        jkIccard.setIsdeleted(Constants.ZERO);
+        //鏌ヨ缂栧彿鏄惁閲嶅
+        if(jkIccardMapper.selectCount(new QueryWrapper<JkIccard>().lambda().eq(JkIccard::getCode,jkIccard.getCode()).eq(JkIccard::getIsdeleted,Constants.ZERO))>Constants.ZERO){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"IC鍗″彿宸插瓨鍦紒");
+        }
         jkIccardMapper.insert(jkIccard);
         return jkIccard.getId();
     }
 
     @Override
     public void deleteById(Integer id) {
-        jkIccardMapper.deleteById(id);
+        JkIccard jkIccard = jkIccardMapper.selectById(id);
+        if(Objects.isNull(jkIccard)||Constants.equalsInteger(jkIccard.getIsdeleted(),Constants.ONE)){
+            throw new BusinessException(ResponseStatus.DATA_EMPTY);
+        }
+        if(Constants.equalsInteger(jkIccard.getStatus(),Constants.ZERO)){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"鍚敤鏁版嵁鏃犳硶杩涜鍒犻櫎锛�");
+        }
+        jkIccardMapper.update(null,new UpdateWrapper<JkIccard>().lambda().set(JkIccard::getIsdeleted,Constants.ONE).eq(JkIccard::getId,jkIccard.getId()));
     }
 
     @Override
@@ -54,6 +91,25 @@
 
     @Override
     public void updateById(JkIccard jkIccard) {
+        if(Objects.isNull(jkIccard)
+                || Objects.isNull(jkIccard.getId())
+                || StringUtils.isBlank(jkIccard.getCode())
+                || Objects.isNull(jkIccard.getStatus())
+                || Objects.isNull(jkIccard.getMemberId())
+                || Objects.isNull(jkIccard.getUserType())
+        ){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        LoginUserInfo loginUserInfo = jkIccard.getLoginUserInfo();
+        jkIccard.setCreateDate(new Date());
+        jkIccard.setCreator(loginUserInfo.getId());
+        jkIccard.setEditDate(jkIccard.getCreateDate());
+        jkIccard.setEditor(jkIccard.getCreator());
+        jkIccard.setIsdeleted(Constants.ZERO);
+        //鏌ヨ缂栧彿鏄惁閲嶅
+        if(jkIccardMapper.selectCount(new QueryWrapper<JkIccard>().lambda().ne(JkIccard::getId,jkIccard.getId()).eq(JkIccard::getCode,jkIccard.getCode()).eq(JkIccard::getIsdeleted,Constants.ZERO))>Constants.ZERO){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"IC鍗″彿宸插瓨鍦紒");
+        }
         jkIccardMapper.updateById(jkIccard);
     }
 
@@ -87,54 +143,20 @@
     @Override
     public PageData<JkIccard> findPage(PageWrap<JkIccard> pageWrap) {
         IPage<JkIccard> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
-        QueryWrapper<JkIccard> queryWrapper = new QueryWrapper<>();
         Utils.MP.blankToNull(pageWrap.getModel());
-        if (pageWrap.getModel().getId() != null) {
-            queryWrapper.lambda().eq(JkIccard::getId, pageWrap.getModel().getId());
-        }
-        if (pageWrap.getModel().getCreator() != null) {
-            queryWrapper.lambda().eq(JkIccard::getCreator, pageWrap.getModel().getCreator());
-        }
-        if (pageWrap.getModel().getCreateDate() != null) {
-            queryWrapper.lambda().ge(JkIccard::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
-            queryWrapper.lambda().le(JkIccard::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
-        }
-        if (pageWrap.getModel().getEditor() != null) {
-            queryWrapper.lambda().eq(JkIccard::getEditor, pageWrap.getModel().getEditor());
-        }
-        if (pageWrap.getModel().getEditDate() != null) {
-            queryWrapper.lambda().ge(JkIccard::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
-            queryWrapper.lambda().le(JkIccard::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
-        }
-        if (pageWrap.getModel().getIsdeleted() != null) {
-            queryWrapper.lambda().eq(JkIccard::getIsdeleted, pageWrap.getModel().getIsdeleted());
-        }
-        if (pageWrap.getModel().getInfo() != null) {
-            queryWrapper.lambda().eq(JkIccard::getInfo, pageWrap.getModel().getInfo());
-        }
-        if (pageWrap.getModel().getMemberId() != null) {
-            queryWrapper.lambda().eq(JkIccard::getMemberId, pageWrap.getModel().getMemberId());
-        }
-        if (pageWrap.getModel().getCode() != null) {
-            queryWrapper.lambda().eq(JkIccard::getCode, pageWrap.getModel().getCode());
-        }
-        if (pageWrap.getModel().getStatus() != null) {
-            queryWrapper.lambda().eq(JkIccard::getStatus, pageWrap.getModel().getStatus());
-        }
-        if (pageWrap.getModel().getName() != null) {
-            queryWrapper.lambda().eq(JkIccard::getName, pageWrap.getModel().getName());
-        }
-        if (pageWrap.getModel().getCabinetId() != null) {
-            queryWrapper.lambda().eq(JkIccard::getCabinetId, pageWrap.getModel().getCabinetId());
-        }
-        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
-            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
-                queryWrapper.orderByDesc(sortData.getProperty());
-            } else {
-                queryWrapper.orderByAsc(sortData.getProperty());
-            }
-        }
-        return PageData.from(jkIccardMapper.selectPage(page, queryWrapper));
+        JkIccard model = pageWrap.getModel();
+        MPJLambdaWrapper<JkIccard> wrapper = new MPJLambdaWrapper<JkIccard>()
+                .selectAll(JkIccard.class)
+                .selectAs(Member::getName,JkIccard::getMemberName)
+                .leftJoin(Member.class,Member::getId,JkIccard::getMemberId)
+                .eq(JkIccard::getIsdeleted,Constants.ZERO)
+                .eq(Objects.nonNull(model.getStatus()),JkIccard::getStatus,model.getStatus())
+                .like(StringUtils.isNotBlank(model.getCode()),JkIccard::getCode,model.getCode())
+                .like(StringUtils.isNotBlank(model.getMemberName()),Member::getName,model.getMemberName())
+                .orderByDesc(JkIccard::getCreateDate)
+                ;
+        IPage<JkIccard> iPage = jkIccardMapper.selectJoinPage(page,JkIccard.class,wrapper);
+        return PageData.from(iPage);
     }
 
     @Override
@@ -142,4 +164,19 @@
         QueryWrapper<JkIccard> wrapper = new QueryWrapper<>(jkIccard);
         return jkIccardMapper.selectCount(wrapper);
     }
+
+    @Override
+    public void updateStatusById(JkIccard jkIccard) {
+        if(Objects.isNull(jkIccard)
+                || Objects.isNull(jkIccard.getId())
+                || Objects.isNull(jkIccard.getStatus())){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        jkIccardMapper.update(null,new UpdateWrapper<JkIccard>()
+                .lambda().set(JkIccard::getStatus,jkIccard.getStatus())
+                .set(JkIccard::getEditDate, DateUtil.getCurrDateTime())
+                .eq(JkIccard::getId,jkIccard.getId()));
+    }
+
+
 }
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkKeysServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkKeysServiceImpl.java
index dcb7279..d2b5382 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkKeysServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkKeysServiceImpl.java
@@ -1,5 +1,13 @@
 package com.doumee.service.business.impl;
 
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.utils.Constants;
+import com.doumee.dao.business.CarsMapper;
+import com.doumee.dao.business.model.Cars;
+import com.doumee.dao.business.model.JkCabinet;
+import com.doumee.dao.business.model.JkCabinetGrid;
+import com.doumee.service.business.third.model.LoginUserInfo;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
 import com.doumee.core.utils.Utils;
@@ -10,11 +18,16 @@
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.yulichang.interfaces.MPJBaseJoin;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
+import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * 閽ュ寵鍩烘湰淇℃伅琛⊿ervice瀹炵幇
@@ -27,14 +40,56 @@
     @Autowired
     private JkKeysMapper jkKeysMapper;
 
+    @Autowired
+    private CarsMapper carsMapper;
+
     @Override
     public Integer create(JkKeys jkKeys) {
+        if(Objects.isNull(jkKeys)
+        || Objects.isNull(jkKeys.getCarId())
+        || Objects.isNull(jkKeys.getRoleType())
+        || StringUtils.isBlank(jkKeys.getCode())
+        || StringUtils.isBlank(jkKeys.getRfidLable())
+        ){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        //鏌ヨ缂栧彿鏄惁閲嶅
+        if(jkKeysMapper.selectCount(new QueryWrapper<JkKeys>().lambda().eq(JkKeys::getCode,jkKeys.getCode()).eq(JkKeys::getIsdeleted,Constants.ZERO))>Constants.ZERO){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"閽ュ寵缂栧彿宸插瓨鍦紒");
+        }
+        Cars cars = carsMapper.selectById(jkKeys.getCarId());
+        if(Objects.isNull(cars)||Constants.equalsInteger(cars.getIsdeleted(),Constants.ONE)){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"杞﹁締淇℃伅鏈煡璇㈠埌锛�");
+        }
+        JkKeys carsKeys = jkKeysMapper.selectOne(new QueryWrapper<JkKeys>().lambda().eq(JkKeys::getCarId,jkKeys.getCarId()).eq(JkKeys::getIsdeleted,Constants.ZERO).last("limit 1"));
+        if(Objects.nonNull(carsKeys)){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"褰撳墠杞﹁締宸茶閽ュ寵["+carsKeys.getCode()+"]缁戝畾浣跨敤锛�");
+        }
+        JkKeys rfidKeys = jkKeysMapper.selectOne(new QueryWrapper<JkKeys>().lambda().eq(JkKeys::getRfidLable,jkKeys.getRfidLable()).eq(JkKeys::getIsdeleted,Constants.ZERO).last("limit 1"));
+        if(Objects.nonNull(rfidKeys)){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"褰撳墠RFID鏍囩宸茶閽ュ寵["+rfidKeys.getCode()+"]浣跨敤锛�");
+        }
+        LoginUserInfo loginUserInfo = jkKeys.getLoginUserInfo();
+        jkKeys.setCreateDate(new Date());
+        jkKeys.setEditDate(jkKeys.getCreateDate());
+        jkKeys.setCreator(loginUserInfo.getId());
+        jkKeys.setEditor(loginUserInfo.getId());
+        jkKeys.setIsdeleted(Constants.ZERO);
+        jkKeys.setStatus(Constants.ZERO);
+        jkKeys.setCarCode(cars.getCode());
         jkKeysMapper.insert(jkKeys);
         return jkKeys.getId();
     }
 
     @Override
     public void deleteById(Integer id) {
+        JkKeys jkKeys = jkKeysMapper.selectById(id);
+        if(Objects.isNull(jkKeys)||Constants.equalsInteger(jkKeys.getIsdeleted(),Constants.ONE)){
+            throw new BusinessException(ResponseStatus.DATA_EMPTY);
+        }
+        if(!Constants.equalsInteger(jkKeys.getStatus(),Constants.ZERO)){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"閽ュ寵宸茬粦瀹�,鏃犳硶杩涜鍒犻櫎");
+        }
         jkKeysMapper.deleteById(id);
     }
 
@@ -54,6 +109,35 @@
 
     @Override
     public void updateById(JkKeys jkKeys) {
+        if(Objects.isNull(jkKeys)
+                || Objects.isNull(jkKeys.getId())
+                || Objects.isNull(jkKeys.getCarId())
+                || Objects.isNull(jkKeys.getRoleType())
+                || StringUtils.isBlank(jkKeys.getCode())
+                || StringUtils.isBlank(jkKeys.getRfidLable())
+        ){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        //鏌ヨ缂栧彿鏄惁閲嶅
+        if(jkKeysMapper.selectCount(new QueryWrapper<JkKeys>().lambda().ne(JkKeys::getId,jkKeys.getId()).eq(JkKeys::getCode,jkKeys.getCode()).eq(JkKeys::getIsdeleted,Constants.ZERO))>Constants.ZERO){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"閽ュ寵缂栧彿宸插瓨鍦紒");
+        }
+        Cars cars = carsMapper.selectById(jkKeys.getCarId());
+        if(Objects.isNull(cars)||Constants.equalsInteger(cars.getIsdeleted(),Constants.ONE)){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"杞﹁締淇℃伅鏈煡璇㈠埌锛�");
+        }
+        JkKeys carsKeys = jkKeysMapper.selectOne(new QueryWrapper<JkKeys>().lambda().ne(JkKeys::getId,jkKeys.getId()).eq(JkKeys::getCarId,jkKeys.getCarId()).eq(JkKeys::getIsdeleted,Constants.ZERO).last("limit 1"));
+        if(Objects.nonNull(carsKeys)){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"褰撳墠杞﹁締宸茶閽ュ寵["+carsKeys.getCode()+"]缁戝畾浣跨敤锛�");
+        }
+        JkKeys rfidKeys = jkKeysMapper.selectOne(new QueryWrapper<JkKeys>().lambda().ne(JkKeys::getId,jkKeys.getId()).eq(JkKeys::getRfidLable,jkKeys.getRfidLable()).eq(JkKeys::getIsdeleted,Constants.ZERO).last("limit 1"));
+        if(Objects.nonNull(rfidKeys)){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED.getCode(),"褰撳墠RFID鏍囩宸茶閽ュ寵["+rfidKeys.getCode()+"]浣跨敤锛�");
+        }
+        LoginUserInfo loginUserInfo = jkKeys.getLoginUserInfo();
+        jkKeys.setEditDate(new Date());
+        jkKeys.setEditor(loginUserInfo.getId());
+        jkKeys.setCarCode(cars.getCode());
         jkKeysMapper.updateById(jkKeys);
     }
 
@@ -80,6 +164,8 @@
 
     @Override
     public List<JkKeys> findList(JkKeys jkKeys) {
+        jkKeys.setIsdeleted(Constants.ZERO);
+        jkKeys.setStatus(Constants.ZERO);
         QueryWrapper<JkKeys> wrapper = new QueryWrapper<>(jkKeys);
         return jkKeysMapper.selectList(wrapper);
     }
@@ -89,57 +175,26 @@
         IPage<JkKeys> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
         QueryWrapper<JkKeys> queryWrapper = new QueryWrapper<>();
         Utils.MP.blankToNull(pageWrap.getModel());
-        if (pageWrap.getModel().getId() != null) {
-            queryWrapper.lambda().eq(JkKeys::getId, pageWrap.getModel().getId());
+        JkKeys model = pageWrap.getModel();
+        MPJLambdaWrapper<JkKeys> wrapper = new MPJLambdaWrapper<JkKeys>()
+                .selectAll(JkKeys.class)
+                .selectAs(JkCabinetGrid::getCode,JkKeys::getGridCode)
+                .selectAs(JkCabinet::getName,JkKeys::getCabinetName)
+                .leftJoin(Cars.class,Cars::getId,JkKeys::getCarId)
+                .leftJoin(JkCabinetGrid.class,JkCabinetGrid::getKeyId,JkKeys::getId)
+                .leftJoin(JkCabinet.class,JkCabinet::getId,JkCabinetGrid::getCabinetId)
+                .eq(JkKeys::getIsdeleted,Constants.ZERO)
+                .like(StringUtils.isNotBlank(model.getCode()),JkKeys::getCode,model.getCode())
+                .like(StringUtils.isNotBlank(model.getCarCode()),JkKeys::getCarCode,model.getCode());
+        IPage<JkKeys> iPage = jkKeysMapper.selectJoinPage(page,JkKeys.class,wrapper);
+        for (JkKeys jkKeys:iPage.getRecords()) {
+            jkKeys.setIsBinding(StringUtils.isBlank(jkKeys.getGridCode())?Constants.ZERO:Constants.ONE);
         }
-        if (pageWrap.getModel().getCreator() != null) {
-            queryWrapper.lambda().eq(JkKeys::getCreator, pageWrap.getModel().getCreator());
-        }
-        if (pageWrap.getModel().getCreateDate() != null) {
-            queryWrapper.lambda().ge(JkKeys::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
-            queryWrapper.lambda().le(JkKeys::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
-        }
-        if (pageWrap.getModel().getEditor() != null) {
-            queryWrapper.lambda().eq(JkKeys::getEditor, pageWrap.getModel().getEditor());
-        }
-        if (pageWrap.getModel().getEditDate() != null) {
-            queryWrapper.lambda().ge(JkKeys::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
-            queryWrapper.lambda().le(JkKeys::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
-        }
-        if (pageWrap.getModel().getIsdeleted() != null) {
-            queryWrapper.lambda().eq(JkKeys::getIsdeleted, pageWrap.getModel().getIsdeleted());
-        }
-        if (pageWrap.getModel().getInfo() != null) {
-            queryWrapper.lambda().eq(JkKeys::getInfo, pageWrap.getModel().getInfo());
-        }
-        if (pageWrap.getModel().getCode() != null) {
-            queryWrapper.lambda().eq(JkKeys::getCode, pageWrap.getModel().getCode());
-        }
-        if (pageWrap.getModel().getCarCode() != null) {
-            queryWrapper.lambda().eq(JkKeys::getCarCode, pageWrap.getModel().getCarCode());
-        }
-        if (pageWrap.getModel().getCarId() != null) {
-            queryWrapper.lambda().eq(JkKeys::getCarId, pageWrap.getModel().getCarId());
-        }
-        if (pageWrap.getModel().getRfidLable() != null) {
-            queryWrapper.lambda().eq(JkKeys::getRfidLable, pageWrap.getModel().getRfidLable());
-        }
-        if (pageWrap.getModel().getRoleType() != null) {
-            queryWrapper.lambda().eq(JkKeys::getRoleType, pageWrap.getModel().getRoleType());
-        }
-        if (pageWrap.getModel().getStatus() != null) {
-            queryWrapper.lambda().eq(JkKeys::getStatus, pageWrap.getModel().getStatus());
-        }
-        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
-            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
-                queryWrapper.orderByDesc(sortData.getProperty());
-            } else {
-                queryWrapper.orderByAsc(sortData.getProperty());
-            }
-        }
-        return PageData.from(jkKeysMapper.selectPage(page, queryWrapper));
+        return PageData.from(iPage);
     }
 
+
+
     @Override
     public long count(JkKeys jkKeys) {
         QueryWrapper<JkKeys> wrapper = new QueryWrapper<>(jkKeys);
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkVersionServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkVersionServiceImpl.java
index 9a360c2..0f49383 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkVersionServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/JkVersionServiceImpl.java
@@ -1,5 +1,14 @@
 package com.doumee.service.business.impl;
 
+import com.doumee.biz.system.SystemDictDataBiz;
+import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.exception.BusinessException;
+import com.doumee.core.utils.Constants;
+import com.doumee.core.utils.DateUtil;
+import com.doumee.dao.business.model.JkCabinet;
+import com.doumee.dao.business.model.JkCabinetLog;
+import com.doumee.dao.system.model.SystemUser;
+import com.doumee.service.business.third.model.LoginUserInfo;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
 import com.doumee.core.utils.Utils;
@@ -10,11 +19,16 @@
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.github.yulichang.wrapper.MPJLambdaWrapper;
+import lombok.extern.java.Log;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
+import java.util.Date;
 import java.util.List;
+import java.util.Objects;
 
 /**
  * 浜ゆ帶-閽ュ寵鏌滅粓绔増鏈俊鎭〃Service瀹炵幇
@@ -27,15 +41,39 @@
     @Autowired
     private JkVersionMapper jkVersionMapper;
 
+    @Autowired
+    private SystemDictDataBiz systemDictDataBiz;
+
+
     @Override
     public Integer create(JkVersion jkVersion) {
+        if(Objects.isNull(jkVersion)
+                || Objects.isNull(jkVersion.getIsForce())
+                || StringUtils.isBlank(jkVersion.getVersionInfo())
+                || StringUtils.isBlank(jkVersion.getFileUrl())
+                || Objects.isNull(jkVersion.getFileSize())
+                || StringUtils.isBlank(jkVersion.getName())
+                || StringUtils.isBlank(jkVersion.getContent())
+        ){
+            throw new BusinessException(ResponseStatus.BAD_REQUEST);
+        }
+        LoginUserInfo loginUserInfo = jkVersion.getLoginUserInfo();
+        jkVersion.setCreateDate(new Date());
+        jkVersion.setCreator(loginUserInfo.getId());
+        jkVersion.setEditDate(jkVersion.getCreateDate());
+        jkVersion.setEditor(jkVersion.getCreator());
+        jkVersion.setIsdeleted(Constants.ZERO);
+        jkVersion.setType(Constants.ZERO);
         jkVersionMapper.insert(jkVersion);
         return jkVersion.getId();
     }
 
     @Override
     public void deleteById(Integer id) {
-        jkVersionMapper.deleteById(id);
+        jkVersionMapper.update(null,new UpdateWrapper<JkVersion>().lambda()
+                .set(JkVersion::getIsdeleted,Constants.ONE)
+                .eq(JkVersion::getId,id));
+//        jkVersionMapper.deleteById(id);
     }
 
     @Override
@@ -54,6 +92,20 @@
 
     @Override
     public void updateById(JkVersion jkVersion) {
+        if(Objects.isNull(jkVersion)
+                || Objects.isNull(jkVersion.getId())
+                || Objects.isNull(jkVersion.getIsForce())
+                || StringUtils.isBlank(jkVersion.getVersionInfo())
+                || StringUtils.isBlank(jkVersion.getFileUrl())
+                || Objects.isNull(jkVersion.getFileSize())
+                || StringUtils.isBlank(jkVersion.getName())
+                || StringUtils.isBlank(jkVersion.getContent())
+        ){
+            throw new BusinessException(ResponseStatus.NOT_ALLOWED);
+        }
+        LoginUserInfo loginUserInfo = jkVersion.getLoginUserInfo();
+        jkVersion.setEditDate(new Date());
+        jkVersion.setEditor(loginUserInfo.getId());
         jkVersionMapper.updateById(jkVersion);
     }
 
@@ -67,9 +119,18 @@
         }
     }
 
+
+
+
     @Override
     public JkVersion findById(Integer id) {
-        return jkVersionMapper.selectById(id);
+        JkVersion jkVersion = jkVersionMapper.selectById(id);
+        if(Objects.nonNull(jkVersion)&&StringUtils.isNotBlank(jkVersion.getFileUrl())){
+            String path = systemDictDataBiz.queryByCode(Constants.FTP,Constants.FTP_LOCAL_RESOURCE_PATH).getCode()
+                    +systemDictDataBiz.queryByCode(Constants.FTP,Constants.APP_FILE).getCode();
+            jkVersion.setFullFileUrl(path + jkVersion.getFileUrl());
+        }
+        return jkVersion;
     }
 
     @Override
@@ -87,63 +148,27 @@
     @Override
     public PageData<JkVersion> findPage(PageWrap<JkVersion> pageWrap) {
         IPage<JkVersion> page = new Page<>(pageWrap.getPage(), pageWrap.getCapacity());
-        QueryWrapper<JkVersion> queryWrapper = new QueryWrapper<>();
         Utils.MP.blankToNull(pageWrap.getModel());
-        if (pageWrap.getModel().getId() != null) {
-            queryWrapper.lambda().eq(JkVersion::getId, pageWrap.getModel().getId());
-        }
-        if (pageWrap.getModel().getCreator() != null) {
-            queryWrapper.lambda().eq(JkVersion::getCreator, pageWrap.getModel().getCreator());
-        }
-        if (pageWrap.getModel().getCreateDate() != null) {
-            queryWrapper.lambda().ge(JkVersion::getCreateDate, Utils.Date.getStart(pageWrap.getModel().getCreateDate()));
-            queryWrapper.lambda().le(JkVersion::getCreateDate, Utils.Date.getEnd(pageWrap.getModel().getCreateDate()));
-        }
-        if (pageWrap.getModel().getEditor() != null) {
-            queryWrapper.lambda().eq(JkVersion::getEditor, pageWrap.getModel().getEditor());
-        }
-        if (pageWrap.getModel().getEditDate() != null) {
-            queryWrapper.lambda().ge(JkVersion::getEditDate, Utils.Date.getStart(pageWrap.getModel().getEditDate()));
-            queryWrapper.lambda().le(JkVersion::getEditDate, Utils.Date.getEnd(pageWrap.getModel().getEditDate()));
-        }
-        if (pageWrap.getModel().getIsdeleted() != null) {
-            queryWrapper.lambda().eq(JkVersion::getIsdeleted, pageWrap.getModel().getIsdeleted());
-        }
-        if (pageWrap.getModel().getInfo() != null) {
-            queryWrapper.lambda().eq(JkVersion::getInfo, pageWrap.getModel().getInfo());
-        }
-        if (pageWrap.getModel().getVersionInfo() != null) {
-            queryWrapper.lambda().eq(JkVersion::getVersionInfo, pageWrap.getModel().getVersionInfo());
-        }
-        if (pageWrap.getModel().getFileUrl() != null) {
-            queryWrapper.lambda().eq(JkVersion::getFileUrl, pageWrap.getModel().getFileUrl());
-        }
-        if (pageWrap.getModel().getName() != null) {
-            queryWrapper.lambda().eq(JkVersion::getName, pageWrap.getModel().getName());
-        }
-        if (pageWrap.getModel().getContent() != null) {
-            queryWrapper.lambda().eq(JkVersion::getContent, pageWrap.getModel().getContent());
-        }
-        if (pageWrap.getModel().getSortnum() != null) {
-            queryWrapper.lambda().eq(JkVersion::getSortnum, pageWrap.getModel().getSortnum());
-        }
-        if (pageWrap.getModel().getTitle() != null) {
-            queryWrapper.lambda().eq(JkVersion::getTitle, pageWrap.getModel().getTitle());
-        }
-        if (pageWrap.getModel().getIsForce() != null) {
-            queryWrapper.lambda().eq(JkVersion::getIsForce, pageWrap.getModel().getIsForce());
-        }
-        if (pageWrap.getModel().getType() != null) {
-            queryWrapper.lambda().eq(JkVersion::getType, pageWrap.getModel().getType());
-        }
-        for(PageWrap.SortData sortData: pageWrap.getSorts()) {
-            if (sortData.getDirection().equalsIgnoreCase(PageWrap.DESC)) {
-                queryWrapper.orderByDesc(sortData.getProperty());
-            } else {
-                queryWrapper.orderByAsc(sortData.getProperty());
+        JkVersion model = pageWrap.getModel();
+        MPJLambdaWrapper<JkVersion> wrapper = new MPJLambdaWrapper<JkVersion>()
+                .selectAll(JkVersion.class)
+                .selectAs(SystemUser::getRealname,JkVersion::getCreateUserName)
+                .select(" ROUND( t.file_size / 1024, 2) ", JkVersion::getFileSizeMb)
+                .leftJoin(SystemUser.class,SystemUser::getId,JkVersion::getCreator)
+                .eq(JkVersion::getIsdeleted,Constants.ZERO)
+                .eq(Objects.nonNull(model.getIsForce()),JkVersion::getIsForce,model.getIsForce())
+                .like(StringUtils.isNotBlank(model.getVersionInfo()),JkVersion::getVersionInfo,model.getVersionInfo())
+                .orderByDesc(JkVersion::getVersionInfo,JkVersion::getCreateDate)
+                ;
+        IPage<JkVersion> iPage = jkVersionMapper.selectJoinPage(page,JkVersion.class,wrapper);
+        String path = systemDictDataBiz.queryByCode(Constants.FTP,Constants.FTP_LOCAL_RESOURCE_PATH).getCode()
+                +systemDictDataBiz.queryByCode(Constants.FTP,Constants.APP_FILE).getCode();
+        for (JkVersion jkVersion:iPage.getRecords()) {
+            if(Objects.nonNull(jkVersion)&&StringUtils.isNotBlank(jkVersion.getFileUrl())){
+                jkVersion.setFullFileUrl(path + jkVersion.getFileUrl());
             }
         }
-        return PageData.from(jkVersionMapper.selectPage(page, queryWrapper));
+        return PageData.from(iPage);
     }
 
     @Override
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
index bc1b948..01b1d19 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/MemberServiceImpl.java
@@ -96,6 +96,9 @@
     private MemberJoinMapper memberJoinMapper;
 
     @Autowired
+    private JkCabinetMapper jkCabinetMapper;
+
+    @Autowired
     private TrainTimeMapper trainTimeMapper;
 
     @Autowired
@@ -1210,6 +1213,21 @@
             if(StringUtils.isNotBlank(companySpecialId)){
                 queryWrapper.apply(" find_in_set('"+companySpecialId+"',REPLACE(t3.company_path,'/',',')) ");
             }
+        }
+        if(null != member.getQueryAuth() && Constants.equalsInteger(member.getQueryAuth(),Constants.ONE)){
+            List<JkCabinet> jkCabinets = jkCabinetMapper.selectList(new QueryWrapper<JkCabinet>().lambda()
+                    .eq(JkCabinet::getIsdeleted,Constants.ZERO)
+                    .isNotNull(JkCabinet::getAuthMemberId)
+            );
+            if(CollectionUtils.isNotEmpty(jkCabinets)){
+                List<String> memberIdList = new ArrayList<>();
+                List<String> authMemberId = jkCabinets.stream().map(i->i.getAuthMemberId()).collect(Collectors.toList());
+                for (String s:authMemberId) {
+                    memberIdList.addAll(Arrays.asList(s.split(","))) ;
+                }
+                queryWrapper.in(Member::getId,memberIdList);
+            }
+
         }
         queryWrapper.eq(Member::getIsdeleted,Constants.ZERO);
         queryWrapper.eq(Member::getWorkStatus,Constants.ZERO);
@@ -2491,7 +2509,7 @@
         if(Objects.nonNull(deptIdList)){
             List<Company> companyList = companyMapper.selectList(new QueryWrapper<Company>().lambda().in(Company::getErpId,deptIdList)
                     .eq(Company::getType,Constants.ONE).eq(Company::getIsdeleted,Constants.ZERO)
-//                    .isNotNull(Company::getHkId) 鏆傛椂鏃犳硶鍚屾寮�鑸� 鍏堟敞閲�
+//                    .isNotNull(Company::getHkId) 鏆傛椂鏃犳硶鍚屾娴峰悍 鍏堟敞閲�
             );
             if(CollectionUtils.isNotEmpty(companyList)){
                 member.setHkOrgId(companyList.get(Constants.ZERO).getHkId());
diff --git a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/WarningServiceImpl.java b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/WarningServiceImpl.java
index 6b7263d..1ea06ee 100644
--- a/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/WarningServiceImpl.java
+++ b/server/visits/dmvisit_service/src/main/java/com/doumee/service/business/impl/WarningServiceImpl.java
@@ -1,38 +1,69 @@
 package com.doumee.service.business.impl;
 
+import com.alibaba.fastjson.JSON;
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.doumee.biz.system.SystemDictDataBiz;
 import com.doumee.core.constants.ResponseStatus;
+import com.doumee.core.dingTalk.DingTalk;
 import com.doumee.core.exception.BusinessException;
 import com.doumee.core.utils.Constants;
-import com.doumee.dao.business.model.Category;
-import com.doumee.dao.business.model.PlatformGroup;
+import com.doumee.core.utils.DateUtil;
+import com.doumee.core.utils.WeatherUtil;
+import com.doumee.dao.business.*;
+import com.doumee.dao.business.dao.MemberMapper;
+import com.doumee.dao.business.model.*;
 import com.doumee.service.business.third.model.LoginUserInfo;
 import com.doumee.service.business.third.model.PageData;
 import com.doumee.service.business.third.model.PageWrap;
 import com.doumee.core.utils.Utils;
-import com.doumee.dao.business.WarningMapper;
-import com.doumee.dao.business.model.Warning;
 import com.doumee.service.business.WarningService;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang3.StringUtils;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.util.CollectionUtils;
 
-import java.util.Date;
-import java.util.List;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 鎶ヨ璁板綍淇℃伅琛⊿ervice瀹炵幇
  * @author 姹熻箘韫�
  * @date 2025/09/28 09:01
  */
+@Slf4j
 @Service
 public class WarningServiceImpl implements WarningService {
 
     @Autowired
     private WarningMapper warningMapper;
+
+    @Autowired
+    private WarningRuleMapper warningRuleMapper;
+
+    @Autowired
+    private WarningRuleDetailMapper warningRuleDetailMapper;
+
+    @Autowired
+    private WarningPushMapper warningPushMapper;
+
+    @Autowired
+    private WarningEventMapper warningEventMapper;
+
+    @Autowired
+    private DingTalk dingTalk;
+
+    @Autowired
+    private MemberMapper memberMapper;
+
+    @Autowired
+    private SystemDictDataBiz systemDictDataBiz;
+
 
     @Override
     public Integer create(Warning warning) {
@@ -213,4 +244,107 @@
         model.setEditor(param.getLoginUserInfo().getId());
         warningMapper.updateById(model);
     }
+
+
+    /**
+     * 瀹氭椂鑾峰彇澶╂皵淇℃伅鎵ц
+     */
+    @Override
+    public void getWeatherInfo(){
+        try{
+            String response = WeatherUtil.getWeatherWarningInfo(systemDictDataBiz.queryByCode(Constants.WEATHER_CONFIG,Constants.REQUEST_URL).getCode(),
+                    systemDictDataBiz.queryByCode(Constants.WEATHER_CONFIG,Constants.API_KEY).getCode(),
+                    systemDictDataBiz.queryByCode(Constants.WEATHER_CONFIG,Constants.LOCATION).getCode());
+            if(StringUtils.isBlank(response)){
+                log.error("鏃犺繑鍥炴暟鎹�");
+            }
+            JSONObject jsonObject = JSONObject.parseObject(response);
+            if(jsonObject.getString("code").equals("200")){
+                if(jsonObject.containsKey("warning")){
+                    Warning warning = warningMapper.selectOne(new QueryWrapper<Warning>().lambda()
+                            .eq(Warning::getType,Constants.FOUR).eq(Warning::getIsdeleted,Constants.ZERO).last("limt 1"));
+                    if(Objects.isNull(warning)){
+                        return;
+                    }
+                    //鏌ヨ閫氱煡浜哄憳
+                    List<WarningRule> warningRuleList = warningRuleMapper.selectList(new QueryWrapper<WarningRule>().lambda()
+                            .eq(WarningRule::getIsdeleted,Constants.ZERO)
+                            .apply(" id in ( select w.RULE_ID from warning_rule_detail w where w.WARNING_ID = '"+warning.getId()+"' and w.ISDELETED = 0  ) ")
+                    );
+                    List<Member> memberList = new ArrayList<>();
+                    if(org.apache.commons.collections.CollectionUtils.isNotEmpty(warningRuleList)){
+                        List<String> memberIdStr =  warningRuleList.stream().map(i->i.getMemberIds()).collect(Collectors.toList());
+                        if(org.apache.commons.collections.CollectionUtils.isNotEmpty(memberIdStr)){
+                            List<String> memberIdList = new ArrayList<>();
+                            for (String s:memberIdStr) {
+                                memberIdList.addAll(
+                                        Arrays.asList(s.split(","))
+                                );
+                            }
+                            memberList = memberMapper.selectList(new QueryWrapper<Member>().lambda().eq(Member::getIsdeleted,Constants.ZERO)
+                                    .notIn(Member::getErpId)
+                                    .in(Member::getId,memberIdList)
+                            );
+                        }
+                    }
+                    JSONArray jsonArray = jsonObject.getJSONArray("warning");
+                    for (int i = 0; i < jsonArray.size(); i++) {
+                        List<WarningPush> warningPushList = new ArrayList<>();
+                        JSONObject  weatherInfo = jsonArray.getJSONObject(i);
+                        String code = weatherInfo.getString("id");
+                        String title = weatherInfo.getString("title");
+                        String text = weatherInfo.getString("text");
+                        //瀛樺湪棰勮 鍒欏瓨鍌ㄩ璀︿俊鎭�
+                        if(warningEventMapper.selectCount(new QueryWrapper<WarningEvent>()
+                                .lambda()
+                                .eq(WarningEvent::getEventId,code)
+                        )>Constants.ZERO){
+                            continue;
+                        }
+
+                        WarningEvent warningEvent = new WarningEvent();
+                        warningEvent.setCreateDate(new Date());
+                        warningEvent.setIsdeleted(Constants.ZERO);
+                        warningEvent.setWarningId(warning.getId());
+                        warningEvent.setTitle(title);
+                        warningEvent.setContent(text);
+                        warningEvent.setEventId(code);
+                        warningEvent.setHappenTime(DateUtil.getCurrDateTime());
+                        warningEvent.setJsonContent(weatherInfo.toJSONString());
+                        warningEventMapper.insert(warningEvent);
+                        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(memberList)&&memberList.size()>Constants.ZERO){
+                            List<String> ddUserIdList = memberList.stream().map(j->j.getErpId()).collect(Collectors.toList());
+                            //鍙戦�佹帹閫侀拤閽夋秷鎭�
+                            Boolean isSuccess = dingTalk.workInfoOANotice(Long.valueOf(systemDictDataBiz.queryByCode(Constants.DD_TALK,Constants.AGENT_ID).getCode()),
+                                    String.join(",",ddUserIdList),
+                                    dingTalk.getWeatherNoticeMsg(title,text));
+                            for (Member member:memberList) {
+                                WarningPush warningPush = new WarningPush();
+                                warningPush.setCreateDate(new Date());
+                                warningPush.setWarningId(warning.getId());
+                                warningPush.setTitle(warningEvent.getTitle());
+                                warningPush.setContent(warningEvent.getContent());
+                                warningPush.setStatus(isSuccess?Constants.ONE:Constants.TWO);
+                                warningPush.setPushType(Constants.ZERO);
+                                warningPush.setMemberId(member.getId());
+                                warningPushList.add(warningPush);
+                            }
+                        }
+                        if(com.github.xiaoymin.knife4j.core.util.CollectionUtils.isNotEmpty(warningPushList)){
+                            warningPushMapper.insert(warningPushList);
+                        }
+                    }
+                }
+            }
+        }catch (Exception e){
+
+        }
+
+
+
+
+    }
+
+
+
 }

--
Gitblit v1.9.3