瀏覽代碼

修改 车闸、门闸 界面

11868 2 天之前
父節點
當前提交
be382cee57

+ 2 - 1
package.json

@@ -43,7 +43,7 @@
     "core-js": "3.8.1",
     "dayjs": "^1.11.18",
     "docx-preview": "^0.1.4",
-    "echarts": "^4.9.0",
+    "echarts": "^5.6.0",
     "element-ui": "2.15.6",
     "file-saver": "^2.0.5",
     "flv.js": "^1.6.2",
@@ -66,6 +66,7 @@
     "vue-count-to": "1.0.13",
     "vue-cropper": "0.5.5",
     "vue-doc-preview": "^0.3.2",
+    "vue-echarts": "^8.0.1",
     "vue-horizontal-calendar": "^1.0.0",
     "vue-meta": "^2.4.0",
     "vue-pdf": "^4.3.0",

+ 21 - 11
src/layout/components/Navbar.vue

@@ -57,6 +57,7 @@ import Search from "@/components/HeaderSearch";
 import RuoYiGit from "@/components/supervision/Git";
 import RuoYiDoc from "@/components/supervision/Doc";
 import { getUserProfile } from "@/api/system/user";
+import WebSocketService from "@/utils/WebSocketService";
 
 export default {
   components: {
@@ -110,17 +111,26 @@ export default {
       this.$store.dispatch("app/toggleSideBar");
     },
     async logout() {
-      this.$confirm("确定注销并退出系统吗?", "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning",
-      })
-        .then(() => {
-          this.$store.dispatch("LogOut").then(() => {
-            location.href = "/index";
-          });
-        })
-        .catch(() => { });
+      try {
+        await this.$confirm("确定注销并退出系统吗?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        });
+
+        // 调用 Vuex 退出登录
+        await this.$store.dispatch("LogOut");
+
+        // 断开 WebSocket(如果存在)
+        if (this.$store.getters.webSocketState === 'open') {
+          WebSocketService.close();
+        }
+
+        // 跳转登录页
+        location.href = "/index";
+      } catch (err) {
+        // 用户取消操作,不处理
+      }
     },
     getUser() {
       getUserProfile().then((response) => {

+ 6 - 5
src/store/getters.js

@@ -11,8 +11,9 @@ const getters = {
   roles: state => state.user.roles,
   permissions: state => state.user.permissions,
   permission_routes: state => state.permission.routes,
-  topbarRouters:state => state.permission.topbarRouters,
-  defaultRoutes:state => state.permission.defaultRoutes,
-  sidebarRouters:state => state.permission.sidebarRouters,
-}
-export default getters
+  topbarRouters: state => state.permission.topbarRouters,
+  defaultRoutes: state => state.permission.defaultRoutes,
+  sidebarRouters: state => state.permission.sidebarRouters,
+  webSocketState: state => state.ws.webSocketState
+};
+export default getters;

+ 14 - 12
src/store/index.js

@@ -1,13 +1,14 @@
-import Vue from 'vue'
-import Vuex from 'vuex'
-import app from './modules/app'
-import user from './modules/user'
-import tagsView from './modules/tagsView'
-import permission from './modules/permission'
-import settings from './modules/settings'
-import getters from './getters'
+import Vue from "vue";
+import Vuex from "vuex";
+import app from "./modules/app";
+import user from "./modules/user";
+import tagsView from "./modules/tagsView";
+import permission from "./modules/permission";
+import settings from "./modules/settings";
+import ws from "./modules/ws";
+import getters from "./getters";
 
-Vue.use(Vuex)
+Vue.use(Vuex);
 
 const store = new Vuex.Store({
   state:{
@@ -18,9 +19,10 @@ const store = new Vuex.Store({
     user,
     tagsView,
     permission,
-    settings
+    settings,
+    ws,
   },
   getters
-})
+});
 
-export default store
+export default store;

+ 35 - 0
src/store/modules/ws.js

@@ -0,0 +1,35 @@
+import WebSocketService from '@/utils/WebSocketService';
+
+export default {
+  namespaced: true,
+  state: {
+    webSocketState: 'closed', // 'open' | 'connecting' | 'error' | 'closed'
+  },
+  mutations: {
+    setWebSocketStatus(state, status) {
+      console.log('WebSocket状态已更新:', status);
+      state.webSocketState = status;
+    },
+  },
+  actions: {
+    connectWebSocket({ commit }, token) {
+      commit('setWebSocketStatus', 'connecting');
+      WebSocketService.initWebSocket(token);
+
+      const handler = (e) => commit('setWebSocketStatus', e.detail);
+
+      // 避免重复绑定
+      window.removeEventListener('ws-status', handler);
+      window.addEventListener('ws-status', handler);
+    },
+    reconnectWebSocket({ state, commit }) {
+      if (state.status === 'open' || state.status === 'connecting') {
+        console.log("WebSocket 已连接或正在连接中,跳过重连");
+        return;
+      }
+
+      commit('setWebSocketStatus', 'connecting');
+      WebSocketService.reconnect();
+    },
+  }
+};

+ 42 - 3
src/utils/WebSocketService.js

@@ -1,3 +1,5 @@
+// WebSocketService.js
+
 class WebSocketService {
   constructor() {
     this.websocket = null;
@@ -9,12 +11,35 @@ class WebSocketService {
   initWebSocket(token) {
     if (!token) {
       console.warn('❌ WebSocket token 为空');
+
+      // 全局提示用户登录过期
+      if (typeof window !== 'undefined' && window.Vue && Vue.prototype.$message) {
+        Vue.prototype.$message.error('登录状态已过期,请重新登录!');
+      } else {
+        alert('登录状态已过期,请重新登录!');
+      }
+
+      // 退出并跳转登录页
+      if (this.store) {
+        this.store.dispatch("LogOut").then(() => {
+          location.href = "/index";
+        });
+      } else {
+        // 如果没有 store 引用,直接跳转
+        location.href = "/index";
+      }
+      return;
+    }
+
+    // 如果已连接或连接中,跳过
+    if (this.websocket &&
+      (this.websocket.readyState === WebSocket.OPEN || this.websocket.readyState === WebSocket.CONNECTING)) {
+      console.log('ℹ️ WebSocket 已连接或连接中,跳过重复连接');
       return;
     }
 
     this.token = token;
     const wsUrl = `${process.env.VUE_APP_WS_URL}/${token}`;
-    console.log("🔌 WebSocket连接中:", process.env.VUE_APP_WS_URL);
     console.log("🔌 WebSocket连接中:", wsUrl);
 
     this.websocket = new WebSocket(wsUrl);
@@ -23,26 +48,39 @@ class WebSocketService {
     this.websocket.onerror = this.websocketonerror.bind(this);
     this.websocket.onmessage = this.setOnmessageMessage.bind(this);
     this.websocket.onclose = this.websocketclose.bind(this);
+
+    // 初始化状态为 connecting
+    window.dispatchEvent(new CustomEvent('ws-status', { detail: 'connecting' }));
   }
 
   websocketonopen() {
     console.log('✅ WebSocket连接成功');
     this.startHeartbeat();
+    window.dispatchEvent(new CustomEvent('ws-status', { detail: 'open' }));
   }
 
   websocketonerror(e) {
-    console.error("❌ WebSocket连接错误:", e);
+    console.error('❌ WebSocket连接错误:', e);
+    window.dispatchEvent(new CustomEvent('ws-status', { detail: 'error' }));
     this.reconnect();
   }
 
   websocketclose(e) {
-    console.warn("⚠️ WebSocket连接关闭:", e);
+    console.warn('⚠️ WebSocket连接关闭:', e);
     this.stopHeartbeat();
+    window.dispatchEvent(new CustomEvent('ws-status', { detail: 'closed' }));
     this.reconnect();
   }
 
   reconnect() {
     if (this.reconnectTimer) return;
+
+    if (this.websocket &&
+      (this.websocket.readyState === WebSocket.OPEN || this.websocket.readyState === WebSocket.CONNECTING)) {
+      console.log('ℹ️ WebSocket 已连接,无需重连');
+      return;
+    }
+
     this.reconnectTimer = setTimeout(() => {
       console.warn('🔁 尝试重新连接 WebSocket...');
       this.initWebSocket(this.token);
@@ -85,6 +123,7 @@ class WebSocketService {
       this.websocket = null;
     }
     console.log("🧹 WebSocket 已销毁");
+    window.dispatchEvent(new CustomEvent('ws-status', { detail: 'closed' }));
   }
 }
 

+ 294 - 0
src/views/doorcarManage/infoManage/eventTypeMap.js

@@ -0,0 +1,294 @@
+// eventTypeMap.js
+
+export const minorTypeMap = {
+  0x1: {
+    0x400: "防区短路报警",
+    0x401: "防区断路报警",
+    0x402: "防区异常报警",
+    0x403: "防区报警恢复",
+    0x404: "设备防拆报警",
+    0x405: "设备防拆恢复",
+    0x406: "读卡器防拆报警",
+    0x407: "读卡器防拆恢复",
+    0x408: "事件输入报警",
+    0x409: "事件输入恢复",
+    0x40a: "胁迫报警",
+    0x40b: "离线事件满90%报警",
+    0x40c: "卡号认证失败超次报警",
+    0x40d: "SD卡存储满报警",
+    0x40e: "联动抓拍事件报警",
+    0x40f: "门控安全模块防拆报警",
+    0x410: "门控安全模块防拆恢复",
+    0x411: "POS开启",
+    0x412: "POS结束",
+    0x413: "人脸图像画质低",
+    0x414: "指纹图像画质低",
+    0x415: "消防输入短路报警",
+    0x416: "消防输入断路报警",
+    0x417: "消防输入恢复",
+    0x418: "消防按钮触发",
+    0x419: "消防按钮恢复",
+    0x41a: "维护按钮触发",
+    0x41b: "维护按钮恢复",
+    0x41c: "紧急按钮触发",
+    0x41d: "紧急按钮恢复",
+    0x41e: "分控器防拆报警",
+    0x41f: "分控器防拆报警恢复",
+    0x422: "通道控制器防拆报警",
+    0x423: "通道控制器防拆报警恢复",
+    0x424: "通道控制器消防输入报警",
+    0x425: "通道控制器消防输入报警恢复",
+    0x442: "合法事件满90%报警",
+    0x95d: "智能锁防劫持报警",
+  },
+  0x2: {
+    // MAJOR_EXCEPTION - 异常
+    0x27: "网络断开",
+    0x28: "网络恢复",
+    0x3a: "RS485连接状态异常",
+    0x3b: "RS485连接状态异常恢复",
+    0x400: "设备上电启动",
+    0x401: "设备掉电关闭",
+    0x402: "看门狗复位",
+    0x403: "蓄电池电压低",
+    0x404: "蓄电池电压恢复正常",
+    0x405: "交流电断电",
+    0x406: "交流电恢复",
+    0x407: "网络恢复",
+    0x408: "FLASH读写异常",
+    0x409: "读卡器掉线",
+    0x40a: "读卡器掉线恢复",
+    0x40b: "指示灯关闭",
+    0x40c: "指示灯恢复",
+    0x40d: "通道控制器掉线",
+    0x40e: "通道控制器恢复",
+    0x40f: "门控安全模块掉线",
+    0x410: "门控安全模块掉线恢复",
+    0x411: "电池电压低(仅人脸设备使用)",
+    0x412: "电池电压恢复正常(仅人脸设备使用)",
+    0x413: "就地控制器网络断开",
+    0x414: "就地控制器网络恢复",
+    0x415: "主控RS485环路节点断开",
+    0x416: "主控RS485环路节点恢复",
+    0x417: "就地控制器掉线",
+    0x418: "就地控制器掉线恢复",
+    0x419: "就地下行RS485环路断开",
+    0x41a: "就地下行RS485环路恢复",
+    0x41b: "分控器在线",
+    0x41c: "分控器离线",
+    0x41d: "身份证阅读器未连接(智能专用)",
+    0x41e: "身份证阅读器连接恢复(智能专用)",
+    0x41f: "指纹模组未连接(智能专用)",
+    0x420: "指纹模组连接恢复(智能专用)",
+    0x421: "摄像头未连接",
+    0x422: "摄像头连接恢复",
+    0x423: "COM口未连接",
+    0x424: "COM口连接恢复",
+    0x425: "设备未授权",
+    0x426: "人证设备在线",
+    0x427: "人证设备离线",
+    0x428: "本地登录锁定",
+    0x429: "本地登录解锁",
+    0x42a: "与反潜回服务器通信断开",
+    0x42b: "与反潜回服务器通信恢复",
+    0x42c: "电机或传感器异常",
+    0x42d: "CAN总线异常",
+    0x42e: "CAN总线恢复",
+    0x42f: "闸机腔体温度超限",
+    0x430: "红外对射异常",
+    0x431: "红外对射恢复",
+    0x432: "灯板通信异常",
+    0x433: "灯板通信恢复",
+    0x434: "红外转接板通信异常",
+    0x435: "红外转接板通信恢复",
+  },
+  0x3: {
+    // MAJOR_OPERATION - 操作
+    0x50: "本地登陆",
+    0x51: "本地注销登陆",
+    0x52: "修改密码",
+    0x53: "本地参数修改",
+    0x5a: "本地升级",
+    0x60: "远程参数修改",
+    0x61: "远程开门",
+    0x62: "远程关闭门",
+    0x70: "远程登录",
+    0x71: "远程注销登陆",
+    0x72: "远程升级",
+    0x73: "远程布防/撤防",
+    0x79: "远程布防",
+    0x7a: "远程撤防",
+    0x7b: "远程重启",
+    0x7e: "远程升级",
+    0x86: "远程导出配置文件",
+    0x87: "远程导入配置文件",
+    0xd6: "远程手动开启报警输出",
+    0xd7: "远程手动关闭报警输出",
+    0x400: "远程开门",
+    0x401: "远程关门(梯控受控)",
+    0x402: "远程常开(梯控自由)",
+    0x403: "远程常关(梯控禁用)",
+    0x404: "远程手动校时",
+    0x405: "NTP自动校时",
+    0x406: "远程清空卡号",
+    0x407: "远程恢复默认参数",
+    0x408: "防区布防",
+    0x409: "防区撤防",
+    0x40a: "本地恢复默认参数",
+    0x40b: "远程抓拍",
+    0x40c: "修改网络中心参数配置",
+    0x40d: "修改GPRS中心参数配置",
+    0x40e: "修改中心组参数配置",
+    0x40f: "解除码输入",
+    0x410: "自动重新编号",
+    0x411: "自动补充编号",
+    0x412: "导入普通配置文件",
+    0x413: "导出普通配置文件",
+    0x414: "导入卡权限参数",
+    0x415: "导出卡权限参数",
+    0x416: "本地U盘升级",
+    0x417: "访客呼梯",
+    0x418: "住户呼梯",
+    0x419: "远程实时布防",
+    0x41a: "远程实时撤防",
+    0x41b: "遥控器未对码操作失败",
+    0x41c: "遥控器关门",
+    0x41d: "遥控器开门",
+    0x41e: "遥控器常开门",
+  },
+  0x5: {
+    // MAJOR_EVENT - 事件
+    0x01: "合法卡认证通过",
+    0x02: "刷卡加密码认证通过",
+    0x03: "刷卡加密码认证失败",
+    0x04: "数卡加密码认证超时",
+    0x05: "刷卡加密码超次",
+    0x06: "未分配权限",
+    0x07: "无效时段",
+    0x08: "卡号过期",
+    0x09: "无此卡号",
+    0x0a: "反潜回认证失败",
+    0x0b: "互锁门未关闭",
+    0x0c: "卡不属于多重认证群组",
+    0x0d: "卡不在多重认证时间段内",
+    0x0e: "多重认证模式超级权限认证失败",
+    0x0f: "多重认证模式远程认证失败",
+    0x10: "多重认证成功",
+    0x11: "首卡开门开始",
+    0x12: "首卡开门结束",
+    0x13: "常开状态开始",
+    0x14: "常开状态结束",
+    0x15: "门锁打开",
+    0x16: "门锁关闭",
+    0x17: "开门按钮打开",
+    0x18: "开门按钮放开",
+    0x19: "正常开门(门磁)",
+    0x1a: "正常关门(门磁)",
+    0x1b: "门异常打开(门磁)",
+    0x1c: "门打开超时(门磁)",
+    0x1d: "报警输出打开",
+    0x1e: "报警输出关闭",
+    0x1f: "常关状态开始",
+    0x20: "常关状态结束",
+    0x21: "多重认证需要远程开门",
+    0x22: "多重认证超级密码认证成功事件",
+    0x23: "多重认证重复认证事件",
+    0x24: "多重认证超时",
+    0x25: "门铃响",
+    0x26: "指纹比对通过",
+    0x27: "指纹比对失败",
+    0x28: "刷卡加指纹认证通过",
+    0x29: "刷卡加指纹认证失败",
+    0x2a: "刷卡加指纹认证超时",
+    0x2b: "刷卡加指纹加密码认证通过",
+    0x2c: "刷卡加指纹加密码认证失败",
+    0x2d: "刷卡加指纹加密码认证超时",
+    0x2e: "指纹加密码认证通过",
+    0x2f: "指纹加密码认证失败",
+    0x30: "指纹加密码认证超时",
+    0x31: "指纹不存在",
+    0x32: "刷卡平台认证",
+    0x33: "呼叫中心事件",
+    0x34: "消防继电器导通触发门常开",
+    0x35: "消防继电器恢复门恢复正常",
+    0x36: "人脸加指纹认证通过",
+    0x37: "人脸加指纹认证失败",
+    0x38: "人脸加指纹认证超时",
+    0x39: "人脸加密码认证通过",
+    0x3a: "人脸加密码认证失败",
+    0x3b: "人脸加密码认证超时",
+    0x3c: "人脸加刷卡认证通过",
+    0x3d: "人脸加刷卡认证失败",
+    0x3e: "人脸加刷卡认证超时",
+    0x3f: "人脸加密码加指纹认证通过",
+    0x40: "人脸加密码加指纹认证失败",
+    0x41: "人脸加密码加指纹认证超时",
+    0x42: "人脸加刷卡加指纹认证通过",
+    0x43: "人脸加刷卡加指纹认证失败",
+    0x44: "人脸加刷卡加指纹认证超时",
+    0x45: "工号加指纹认证通过",
+    0x46: "工号加指纹认证失败",
+    0x47: "工号加指纹认证超时",
+    0x48: "工号加指纹加密码认证通过",
+    0x49: "工号加指纹加密码认证失败",
+    0x4a: "工号加指纹加密码认证超时",
+    0x4b: "人脸认证通过",
+    0x4c: "人脸认证失败",
+    0x4d: "工号加人脸认证通过",
+    0x4e: "工号加人脸认证失败",
+    0x4f: "工号加人脸认证超时",
+    0x50: "人脸抓拍失败",
+    0x51: "首卡授权开始",
+    0x52: "首卡授权结束",
+    0x53: "门锁输入短路报警",
+    0x54: "门锁输入断路报警",
+    0x55: "门锁输入异常报警",
+    0x56: "门磁输入短路报警",
+    0x57: "门磁输入断路报警",
+    0x58: "门磁输入异常报警",
+    0x59: "开门按钮输入短路报警",
+    0x5a: "开门按钮输入断路报警",
+    0x5b: "开门按钮输入异常报警",
+    0x5c: "门锁异常打开",
+    0x5d: "门锁打开超时",
+    0x5e: "首卡未授权开门失败",
+    0x5f: "呼梯继电器断开",
+    0x60: "呼梯继电器闭合",
+    0x61: "自动按键继电器断开",
+    0x62: "自动按键继电器闭合",
+    0x63: "按键梯控继电器断开",
+    0x64: "按键梯控继电器闭合",
+    0x65: "工号加密码认证通过",
+    0x66: "工号加密码认证失败",
+    0x67: "工号加密码认证超时",
+    0x68: "真人检测失败",
+    0x69: "人证比对通过",
+    0x70: "人证比对失败",
+    0x71: "非授权名单事件",
+    0x72: "合法短信",
+    0x73: "非法短信",
+    0x74: "MAC侦测",
+    0x75: "门状态常闭或休眠状态认证失败",
+    0x76: "认证计划休眠模式认证失败",
+    0x77: "卡加密校验失败",
+    0x78: "反潜回服务器应答失败",
+    0x85: "尾随通行",
+    0x86: "反向闯入",
+    0x87: "外力冲撞",
+    0x88: "翻越",
+    0x89: "通行超时",
+    0x8a: "误闯报警",
+    0x8b: "闸机自由通行时未认证通过",
+    0x8c: "摆臂被阻挡",
+    0x8d: "摆臂阻挡消除",
+    0x8e: "设备升级本地人脸建模失败",
+    0x8f: "逗留事件",
+    0x97: "密码不匹配",
+    0x98: "工号不存在",
+    0x99: "组合认证通过",
+    0x9a: "组合认证超时",
+    0x9b: "认证方式不匹配",
+  },
+};
+
+export default minorTypeMap;

File diff suppressed because it is too large
+ 772 - 285
src/views/doorcarManage/infoManage/index.vue


+ 294 - 0
src/views/doormanManage/infoManage/eventTypeMap.js

@@ -0,0 +1,294 @@
+// eventTypeMap.js
+
+export const minorTypeMap = {
+  0x1: {
+    0x400: "防区短路报警",
+    0x401: "防区断路报警",
+    0x402: "防区异常报警",
+    0x403: "防区报警恢复",
+    0x404: "设备防拆报警",
+    0x405: "设备防拆恢复",
+    0x406: "读卡器防拆报警",
+    0x407: "读卡器防拆恢复",
+    0x408: "事件输入报警",
+    0x409: "事件输入恢复",
+    0x40a: "胁迫报警",
+    0x40b: "离线事件满90%报警",
+    0x40c: "卡号认证失败超次报警",
+    0x40d: "SD卡存储满报警",
+    0x40e: "联动抓拍事件报警",
+    0x40f: "门控安全模块防拆报警",
+    0x410: "门控安全模块防拆恢复",
+    0x411: "POS开启",
+    0x412: "POS结束",
+    0x413: "人脸图像画质低",
+    0x414: "指纹图像画质低",
+    0x415: "消防输入短路报警",
+    0x416: "消防输入断路报警",
+    0x417: "消防输入恢复",
+    0x418: "消防按钮触发",
+    0x419: "消防按钮恢复",
+    0x41a: "维护按钮触发",
+    0x41b: "维护按钮恢复",
+    0x41c: "紧急按钮触发",
+    0x41d: "紧急按钮恢复",
+    0x41e: "分控器防拆报警",
+    0x41f: "分控器防拆报警恢复",
+    0x422: "通道控制器防拆报警",
+    0x423: "通道控制器防拆报警恢复",
+    0x424: "通道控制器消防输入报警",
+    0x425: "通道控制器消防输入报警恢复",
+    0x442: "合法事件满90%报警",
+    0x95d: "智能锁防劫持报警",
+  },
+  0x2: {
+    // MAJOR_EXCEPTION - 异常
+    0x27: "网络断开",
+    0x28: "网络恢复",
+    0x3a: "RS485连接状态异常",
+    0x3b: "RS485连接状态异常恢复",
+    0x400: "设备上电启动",
+    0x401: "设备掉电关闭",
+    0x402: "看门狗复位",
+    0x403: "蓄电池电压低",
+    0x404: "蓄电池电压恢复正常",
+    0x405: "交流电断电",
+    0x406: "交流电恢复",
+    0x407: "网络恢复",
+    0x408: "FLASH读写异常",
+    0x409: "读卡器掉线",
+    0x40a: "读卡器掉线恢复",
+    0x40b: "指示灯关闭",
+    0x40c: "指示灯恢复",
+    0x40d: "通道控制器掉线",
+    0x40e: "通道控制器恢复",
+    0x40f: "门控安全模块掉线",
+    0x410: "门控安全模块掉线恢复",
+    0x411: "电池电压低(仅人脸设备使用)",
+    0x412: "电池电压恢复正常(仅人脸设备使用)",
+    0x413: "就地控制器网络断开",
+    0x414: "就地控制器网络恢复",
+    0x415: "主控RS485环路节点断开",
+    0x416: "主控RS485环路节点恢复",
+    0x417: "就地控制器掉线",
+    0x418: "就地控制器掉线恢复",
+    0x419: "就地下行RS485环路断开",
+    0x41a: "就地下行RS485环路恢复",
+    0x41b: "分控器在线",
+    0x41c: "分控器离线",
+    0x41d: "身份证阅读器未连接(智能专用)",
+    0x41e: "身份证阅读器连接恢复(智能专用)",
+    0x41f: "指纹模组未连接(智能专用)",
+    0x420: "指纹模组连接恢复(智能专用)",
+    0x421: "摄像头未连接",
+    0x422: "摄像头连接恢复",
+    0x423: "COM口未连接",
+    0x424: "COM口连接恢复",
+    0x425: "设备未授权",
+    0x426: "人证设备在线",
+    0x427: "人证设备离线",
+    0x428: "本地登录锁定",
+    0x429: "本地登录解锁",
+    0x42a: "与反潜回服务器通信断开",
+    0x42b: "与反潜回服务器通信恢复",
+    0x42c: "电机或传感器异常",
+    0x42d: "CAN总线异常",
+    0x42e: "CAN总线恢复",
+    0x42f: "闸机腔体温度超限",
+    0x430: "红外对射异常",
+    0x431: "红外对射恢复",
+    0x432: "灯板通信异常",
+    0x433: "灯板通信恢复",
+    0x434: "红外转接板通信异常",
+    0x435: "红外转接板通信恢复",
+  },
+  0x3: {
+    // MAJOR_OPERATION - 操作
+    0x50: "本地登陆",
+    0x51: "本地注销登陆",
+    0x52: "修改密码",
+    0x53: "本地参数修改",
+    0x5a: "本地升级",
+    0x60: "远程参数修改",
+    0x61: "远程开门",
+    0x62: "远程关闭门",
+    0x70: "远程登录",
+    0x71: "远程注销登陆",
+    0x72: "远程升级",
+    0x73: "远程布防/撤防",
+    0x79: "远程布防",
+    0x7a: "远程撤防",
+    0x7b: "远程重启",
+    0x7e: "远程升级",
+    0x86: "远程导出配置文件",
+    0x87: "远程导入配置文件",
+    0xd6: "远程手动开启报警输出",
+    0xd7: "远程手动关闭报警输出",
+    0x400: "远程开门",
+    0x401: "远程关门(梯控受控)",
+    0x402: "远程常开(梯控自由)",
+    0x403: "远程常关(梯控禁用)",
+    0x404: "远程手动校时",
+    0x405: "NTP自动校时",
+    0x406: "远程清空卡号",
+    0x407: "远程恢复默认参数",
+    0x408: "防区布防",
+    0x409: "防区撤防",
+    0x40a: "本地恢复默认参数",
+    0x40b: "远程抓拍",
+    0x40c: "修改网络中心参数配置",
+    0x40d: "修改GPRS中心参数配置",
+    0x40e: "修改中心组参数配置",
+    0x40f: "解除码输入",
+    0x410: "自动重新编号",
+    0x411: "自动补充编号",
+    0x412: "导入普通配置文件",
+    0x413: "导出普通配置文件",
+    0x414: "导入卡权限参数",
+    0x415: "导出卡权限参数",
+    0x416: "本地U盘升级",
+    0x417: "访客呼梯",
+    0x418: "住户呼梯",
+    0x419: "远程实时布防",
+    0x41a: "远程实时撤防",
+    0x41b: "遥控器未对码操作失败",
+    0x41c: "遥控器关门",
+    0x41d: "遥控器开门",
+    0x41e: "遥控器常开门",
+  },
+  0x5: {
+    // MAJOR_EVENT - 事件
+    0x01: "合法卡认证通过",
+    0x02: "刷卡加密码认证通过",
+    0x03: "刷卡加密码认证失败",
+    0x04: "数卡加密码认证超时",
+    0x05: "刷卡加密码超次",
+    0x06: "未分配权限",
+    0x07: "无效时段",
+    0x08: "卡号过期",
+    0x09: "无此卡号",
+    0x0a: "反潜回认证失败",
+    0x0b: "互锁门未关闭",
+    0x0c: "卡不属于多重认证群组",
+    0x0d: "卡不在多重认证时间段内",
+    0x0e: "多重认证模式超级权限认证失败",
+    0x0f: "多重认证模式远程认证失败",
+    0x10: "多重认证成功",
+    0x11: "首卡开门开始",
+    0x12: "首卡开门结束",
+    0x13: "常开状态开始",
+    0x14: "常开状态结束",
+    0x15: "门锁打开",
+    0x16: "门锁关闭",
+    0x17: "开门按钮打开",
+    0x18: "开门按钮放开",
+    0x19: "正常开门(门磁)",
+    0x1a: "正常关门(门磁)",
+    0x1b: "门异常打开(门磁)",
+    0x1c: "门打开超时(门磁)",
+    0x1d: "报警输出打开",
+    0x1e: "报警输出关闭",
+    0x1f: "常关状态开始",
+    0x20: "常关状态结束",
+    0x21: "多重认证需要远程开门",
+    0x22: "多重认证超级密码认证成功事件",
+    0x23: "多重认证重复认证事件",
+    0x24: "多重认证超时",
+    0x25: "门铃响",
+    0x26: "指纹比对通过",
+    0x27: "指纹比对失败",
+    0x28: "刷卡加指纹认证通过",
+    0x29: "刷卡加指纹认证失败",
+    0x2a: "刷卡加指纹认证超时",
+    0x2b: "刷卡加指纹加密码认证通过",
+    0x2c: "刷卡加指纹加密码认证失败",
+    0x2d: "刷卡加指纹加密码认证超时",
+    0x2e: "指纹加密码认证通过",
+    0x2f: "指纹加密码认证失败",
+    0x30: "指纹加密码认证超时",
+    0x31: "指纹不存在",
+    0x32: "刷卡平台认证",
+    0x33: "呼叫中心事件",
+    0x34: "消防继电器导通触发门常开",
+    0x35: "消防继电器恢复门恢复正常",
+    0x36: "人脸加指纹认证通过",
+    0x37: "人脸加指纹认证失败",
+    0x38: "人脸加指纹认证超时",
+    0x39: "人脸加密码认证通过",
+    0x3a: "人脸加密码认证失败",
+    0x3b: "人脸加密码认证超时",
+    0x3c: "人脸加刷卡认证通过",
+    0x3d: "人脸加刷卡认证失败",
+    0x3e: "人脸加刷卡认证超时",
+    0x3f: "人脸加密码加指纹认证通过",
+    0x40: "人脸加密码加指纹认证失败",
+    0x41: "人脸加密码加指纹认证超时",
+    0x42: "人脸加刷卡加指纹认证通过",
+    0x43: "人脸加刷卡加指纹认证失败",
+    0x44: "人脸加刷卡加指纹认证超时",
+    0x45: "工号加指纹认证通过",
+    0x46: "工号加指纹认证失败",
+    0x47: "工号加指纹认证超时",
+    0x48: "工号加指纹加密码认证通过",
+    0x49: "工号加指纹加密码认证失败",
+    0x4a: "工号加指纹加密码认证超时",
+    0x4b: "人脸认证通过",
+    0x4c: "人脸认证失败",
+    0x4d: "工号加人脸认证通过",
+    0x4e: "工号加人脸认证失败",
+    0x4f: "工号加人脸认证超时",
+    0x50: "人脸抓拍失败",
+    0x51: "首卡授权开始",
+    0x52: "首卡授权结束",
+    0x53: "门锁输入短路报警",
+    0x54: "门锁输入断路报警",
+    0x55: "门锁输入异常报警",
+    0x56: "门磁输入短路报警",
+    0x57: "门磁输入断路报警",
+    0x58: "门磁输入异常报警",
+    0x59: "开门按钮输入短路报警",
+    0x5a: "开门按钮输入断路报警",
+    0x5b: "开门按钮输入异常报警",
+    0x5c: "门锁异常打开",
+    0x5d: "门锁打开超时",
+    0x5e: "首卡未授权开门失败",
+    0x5f: "呼梯继电器断开",
+    0x60: "呼梯继电器闭合",
+    0x61: "自动按键继电器断开",
+    0x62: "自动按键继电器闭合",
+    0x63: "按键梯控继电器断开",
+    0x64: "按键梯控继电器闭合",
+    0x65: "工号加密码认证通过",
+    0x66: "工号加密码认证失败",
+    0x67: "工号加密码认证超时",
+    0x68: "真人检测失败",
+    0x69: "人证比对通过",
+    0x70: "人证比对失败",
+    0x71: "非授权名单事件",
+    0x72: "合法短信",
+    0x73: "非法短信",
+    0x74: "MAC侦测",
+    0x75: "门状态常闭或休眠状态认证失败",
+    0x76: "认证计划休眠模式认证失败",
+    0x77: "卡加密校验失败",
+    0x78: "反潜回服务器应答失败",
+    0x85: "尾随通行",
+    0x86: "反向闯入",
+    0x87: "外力冲撞",
+    0x88: "翻越",
+    0x89: "通行超时",
+    0x8a: "误闯报警",
+    0x8b: "闸机自由通行时未认证通过",
+    0x8c: "摆臂被阻挡",
+    0x8d: "摆臂阻挡消除",
+    0x8e: "设备升级本地人脸建模失败",
+    0x8f: "逗留事件",
+    0x97: "密码不匹配",
+    0x98: "工号不存在",
+    0x99: "组合认证通过",
+    0x9a: "组合认证超时",
+    0x9b: "认证方式不匹配",
+  },
+};
+
+export default minorTypeMap;

File diff suppressed because it is too large
+ 676 - 264
src/views/doormanManage/infoManage/index.vue


+ 3 - 3
src/views/login.vue

@@ -54,7 +54,6 @@
 import { getCodeImg } from "@/api/login";
 import Cookies from "js-cookie";
 import { encrypt, decrypt } from "@/utils/jsencrypt";
-import WebSocketService from "@/utils/WebSocketService";
 
 export default {
   name: "Login",
@@ -153,8 +152,9 @@ export default {
           }
           this.$store.dispatch("Login", this.loginForm).then(() => {
             const token = this.$store.getters.token;
-            // console.log("token", token)
-            WebSocketService.initWebSocket(token);
+            if (token) {
+              this.$store.dispatch('ws/connectWebSocket', token);
+            }
             // this.requestFullScreen()
             // this.$router.push({ path: this.redirect || "/" }).catch(() => {});
             this.$router.push({ path: "/pt" }).catch(() => { });

+ 72 - 61
src/views/pt.vue

@@ -811,6 +811,7 @@
     </el-dialog>
   </div>
 </template>
+
 <script>
 import {
   printTrigger,
@@ -834,6 +835,8 @@ import {
 import { getUserProfile } from "@/api/system/user";
 import Cookies from "js-cookie";
 import axios from "axios";
+import WebSocketService from "@/utils/WebSocketService";
+
 export default {
   dicts: ["sys_notice_status", "sys_notice_type"],
   data() {
@@ -847,13 +850,12 @@ export default {
       timer2: null,
       open5: false,
       ggflg: false,
-      form: "",
-      rules: "",
       title: "",
       title2: "",
       title3: "",
       title4: "",
       url: process.env.VUE_APP_BASE_API,
+      form: "",
       rules: {
         noticeTitle: [
           { required: true, message: "公告标题不能为空", trigger: "blur" },
@@ -862,8 +864,6 @@ export default {
           { required: true, message: "公告类型不能为空", trigger: "change" },
         ],
       },
-      // 表单参数
-      form: {},
       noticeList: [],
       worklist: [],
       // 用户信息
@@ -935,18 +935,29 @@ export default {
     },
     // 退出
     async logout() {
-      this.$confirm("确定注销并退出系统吗?", "提示", {
-        confirmButtonText: "确定",
-        cancelButtonText: "取消",
-        type: "warning",
-      })
-        .then(() => {
-          this.$store.dispatch("LogOut").then(() => {
-            location.href = "/index";
-            Cookies.remove("tixing");
-          });
-        })
-        .catch(() => {});
+      try {
+        await this.$confirm("确定注销并退出系统吗?", "提示", {
+          confirmButtonText: "确定",
+          cancelButtonText: "取消",
+          type: "warning",
+        });
+
+        // 调用 Vuex 退出登录
+        await this.$store.dispatch("LogOut");
+
+        // 清理本地数据
+        Cookies.remove("tixing");
+
+        // 断开 WebSocket(如果存在)
+        if (this.$store.getters.webSocketState === 'open') {
+          WebSocketService.close();
+        }
+
+        // 跳转登录页
+        location.href = "/index";
+      } catch (err) {
+        // 用户取消操作,不处理
+      }
     },
     // 手机柜线S地址console
     xianShang() {
@@ -1368,7 +1379,7 @@ li {
   height: 100%;
   width: 100%;
   overflow: auto;
-  background: url("../images/背景1.png") no-repeat center;
+  background: url("~@/images/背景1.png") no-repeat center;
   background-size: 100% 100%;
   position: relative;
 }
@@ -1376,7 +1387,7 @@ li {
   color: #fff;
   position: relative;
   height: 120px;
-  background: url("../assets/images/首页顶部.gif") no-repeat center;
+  background: url("~@/assets/images/首页顶部.gif") no-repeat center;
   background-size: cover;
 }
 .tou .yong_hu {
@@ -1410,7 +1421,7 @@ li {
   color: #fff;
   width: 107px;
   height: 95%;
-  background: url("../images/tx.png") no-repeat;
+  background: url("~@/images/tx.png") no-repeat;
   text-align: center;
   margin-top: 10%;
   position: relative;
@@ -1483,7 +1494,7 @@ hr {
   color: #fff;
   width: 529px;
   height: 41vh;
-  background: url("../images/底3.png") no-repeat;
+  background: url("~@/images/底3.png") no-repeat;
   margin-bottom: 10px;
   padding: 16px 20px 0px 20px;
   background-size: 100% 100%;
@@ -1780,7 +1791,7 @@ hr {
 .jiben {
   width: 760px;
   height: 32px;
-  background-image: url("../images/小标题底.png");
+  background-image: url("~@/images/小标题底.png");
   margin-bottom: 25px;
   color: #fff;
   padding-left: 16px;
@@ -1852,7 +1863,7 @@ hr {
 .tkbox {
   width: 500px;
   height: 220px;
-  background-image: url("../assets/images/框.png");
+  background-image: url("~@/assets/images/框.png");
   background-size: 100% 100%;
   background-repeat: no-repeat;
   position: absolute;
@@ -1863,7 +1874,7 @@ hr {
 .tkbox2 {
   width: 500px;
   height: 220px;
-  background-image: url("../assets/images/框.png");
+  background-image: url("~@/assets/images/框.png");
   background-size: 100% 100%;
   background-repeat: no-repeat;
   position: absolute;
@@ -1874,7 +1885,7 @@ hr {
 .tkbox3 {
   width: 500px;
   height: 220px;
-  background-image: url("../assets/images/框.png");
+  background-image: url("~@/assets/images/框.png");
   background-size: 100% 100%;
   background-repeat: no-repeat;
   position: absolute;
@@ -1885,7 +1896,7 @@ hr {
 .tkbox4 {
   width: 500px;
   height: 220px;
-  background-image: url("../assets/images/框.png");
+  background-image: url("~@/assets/images/框.png");
   background-size: 100% 100%;
   background-repeat: no-repeat;
   position: absolute;
@@ -2006,114 +2017,114 @@ hr {
   width: 30px;
   height: 30px;
   top: 6.5%;
-  background: url(../images/无光_00000.png) no-repeat;
+  background: url(~@/images/无光_00000.png) no-repeat;
   animation: mymove 2s 0.5s infinite linear alternate forwards;
 }
 @keyframes mymove {
   0% {
-    background: url(../images/无光_00000.png) no-repeat;
+    background: url(~@/images/无光_00000.png) no-repeat;
   }
   3% {
-    background: url(../images/无光_00001.png) no-repeat;
+    background: url(~@/images/无光_00001.png) no-repeat;
   }
   6% {
-    background: url(../images/无光_00002.png) no-repeat;
+    background: url(~@/images/无光_00002.png) no-repeat;
   }
   9% {
-    background: url(../images/无光_00003.png) no-repeat;
+    background: url(~@/images/无光_00003.png) no-repeat;
   }
   12% {
-    background: url(../images/无光_00004.png) no-repeat;
+    background: url(~@/images/无光_00004.png) no-repeat;
   }
   15% {
-    background: url(../images/无光_00005.png) no-repeat;
+    background: url(~@/images/无光_00005.png) no-repeat;
   }
   18% {
-    background: url(../images/无光_00006.png) no-repeat;
+    background: url(~@/images/无光_00006.png) no-repeat;
   }
   21% {
-    background: url(../images/无光_00007.png) no-repeat;
+    background: url(~@/images/无光_00007.png) no-repeat;
   }
   24% {
-    background: url(../images/无光_00008.png) no-repeat;
+    background: url(~@/images/无光_00008.png) no-repeat;
   }
   27% {
-    background: url(../images/无光_00009.png) no-repeat;
+    background: url(~@/images/无光_00009.png) no-repeat;
   }
   30% {
-    background: url(../images/无光_00010.png) no-repeat;
+    background: url(~@/images/无光_00010.png) no-repeat;
   }
   33% {
-    background: url(../images/无光_00011.png) no-repeat;
+    background: url(~@/images/无光_00011.png) no-repeat;
   }
   36% {
-    background: url(../images/无光_00012.png) no-repeat;
+    background: url(~@/images/无光_00012.png) no-repeat;
   }
   39% {
-    background: url(../images/无光_00013.png) no-repeat;
+    background: url(~@/images/无光_00013.png) no-repeat;
   }
   42% {
-    background: url(../images/无光_00014.png) no-repeat;
+    background: url(~@/images/无光_00014.png) no-repeat;
   }
   45% {
-    background: url(../images/无光_00015.png) no-repeat;
+    background: url(~@/images/无光_00015.png) no-repeat;
   }
   48% {
-    background: url(../images/无光_00016.png) no-repeat;
+    background: url(~@/images/无光_00016.png) no-repeat;
   }
   51% {
-    background: url(../images/无光_00017.png) no-repeat;
+    background: url(~@/images/无光_00017.png) no-repeat;
   }
   54% {
-    background: url(../images/无光_00018.png) no-repeat;
+    background: url(~@/images/无光_00018.png) no-repeat;
   }
   57% {
-    background: url(../images/无光_00019.png) no-repeat;
+    background: url(~@/images/无光_00019.png) no-repeat;
   }
   60% {
-    background: url(../images/无光_00020.png) no-repeat;
+    background: url(~@/images/无光_00020.png) no-repeat;
   }
   63% {
-    background: url(../images/无光_00021.png) no-repeat;
+    background: url(~@/images/无光_00021.png) no-repeat;
   }
   66% {
-    background: url(../images/无光_00022.png) no-repeat;
+    background: url(~@/images/无光_00022.png) no-repeat;
   }
   69% {
-    background: url(../images/无光_00023.png) no-repeat;
+    background: url(~@/images/无光_00023.png) no-repeat;
   }
   72% {
-    background: url(../images/无光_00024.png) no-repeat;
+    background: url(~@/images/无光_00024.png) no-repeat;
   }
   75% {
-    background: url(../images/无光_00025.png) no-repeat;
+    background: url(~@/images/无光_00025.png) no-repeat;
   }
   78% {
-    background: url(../images/无光_00026.png) no-repeat;
+    background: url(~@/images/无光_00026.png) no-repeat;
   }
   81% {
-    background: url(../images/无光_00027.png) no-repeat;
+    background: url(~@/images/无光_00027.png) no-repeat;
   }
   84% {
-    background: url(../images/无光_00028.png) no-repeat;
+    background: url(~@/images/无光_00028.png) no-repeat;
   }
   87% {
-    background: url(../images/无光_00029.png) no-repeat;
+    background: url(~@/images/无光_00029.png) no-repeat;
   }
   90% {
-    background: url(../images/无光_00030.png) no-repeat;
+    background: url(~@/images/无光_00030.png) no-repeat;
   }
   92% {
-    background: url(../images/无光_00031.png) no-repeat;
+    background: url(~@/images/无光_00031.png) no-repeat;
   }
   95% {
-    background: url(../images/无光_00032.png) no-repeat;
+    background: url(~@/images/无光_00032.png) no-repeat;
   }
   98% {
-    background: url(../images/无光_00033.png) no-repeat;
+    background: url(~@/images/无光_00033.png) no-repeat;
   }
   100% {
-    background: url(../images/无光_00034.png) no-repeat;
+    background: url(~@/images/无光_00034.png) no-repeat;
   }
 }
 </style>

Some files were not shown because too many files changed in this diff