Browse Source

添加websocket 用于事件推送

11868 5 ngày trước cách đây
mục cha
commit
299291c6c7

+ 7 - 4
.env.development

@@ -1,11 +1,14 @@
 # 页面标题
-VUE_APP_TITLE = 智能督查管理平台
+VUE_APP_TITLE=智能督查管理平台
 
 # 开发环境配置
-ENV = 'development'
+ENV=development
 
 # 智能督察管理平台/开发环境
-VUE_APP_BASE_API = '/dev-api'
+VUE_APP_BASE_API=/dev-api
 
 # 路由懒加载
-VUE_CLI_BABEL_TRANSPILE_MODULES = true
+VUE_CLI_BABEL_TRANSPILE_MODULES=true
+
+# WebSocket 地址(开发环境)
+VUE_APP_WS_URL=ws://localhost:8090/websocket

+ 6 - 3
.env.production

@@ -1,8 +1,11 @@
 # 页面标题
-VUE_APP_TITLE = 智能督查管理平台
+VUE_APP_TITLE=智能督查管理平台
 
 # 生产环境配置
-ENV = 'production'
+ENV=production
 
 # 智能督察管理平台/生产环境
-VUE_APP_BASE_API = '/prod-api'
+VUE_APP_BASE_API=/prod-api
+
+# WebSocket 地址(生产环境)
+VUE_APP_WS_URL=wss://localhost:8090/websocket

+ 91 - 0
src/utils/WebSocketService.js

@@ -0,0 +1,91 @@
+class WebSocketService {
+  constructor() {
+    this.websocket = null;
+    this.heartbeatTimer = null;
+    this.reconnectTimer = null;
+    this.token = null;
+  }
+
+  initWebSocket(token) {
+    if (!token) {
+      console.warn('❌ WebSocket token 为空');
+      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);
+
+    this.websocket.onopen = this.websocketonopen.bind(this);
+    this.websocket.onerror = this.websocketonerror.bind(this);
+    this.websocket.onmessage = this.setOnmessageMessage.bind(this);
+    this.websocket.onclose = this.websocketclose.bind(this);
+  }
+
+  websocketonopen() {
+    console.log('✅ WebSocket连接成功');
+    this.startHeartbeat();
+  }
+
+  websocketonerror(e) {
+    console.error("❌ WebSocket连接错误:", e);
+    this.reconnect();
+  }
+
+  websocketclose(e) {
+    console.warn("⚠️ WebSocket连接关闭:", e);
+    this.stopHeartbeat();
+    this.reconnect();
+  }
+
+  reconnect() {
+    if (this.reconnectTimer) return;
+    this.reconnectTimer = setTimeout(() => {
+      console.warn('🔁 尝试重新连接 WebSocket...');
+      this.initWebSocket(this.token);
+      this.reconnectTimer = null;
+    }, 5000);
+  }
+
+  setOnmessageMessage(event) {
+    try {
+      const msg = JSON.parse(event.data);
+      console.log("📩 收到消息:", msg);
+      if (msg.type) {
+        window.dispatchEvent(new CustomEvent(msg.type, { detail: msg }));
+      }
+    } catch (err) {
+      console.error("WebSocket消息解析失败:", err);
+    }
+  }
+
+  startHeartbeat() {
+    this.stopHeartbeat();
+    this.heartbeatTimer = setInterval(() => {
+      if (this.websocket && this.websocket.readyState === WebSocket.OPEN) {
+        this.websocket.send(JSON.stringify({ type: 'heartbeat', time: new Date().toISOString() }));
+      }
+    }, 30000);
+  }
+
+  stopHeartbeat() {
+    if (this.heartbeatTimer) {
+      clearInterval(this.heartbeatTimer);
+      this.heartbeatTimer = null;
+    }
+  }
+
+  destroy() {
+    this.stopHeartbeat();
+    if (this.websocket) {
+      this.websocket.close();
+      this.websocket = null;
+    }
+    console.log("🧹 WebSocket 已销毁");
+  }
+}
+
+export default new WebSocketService();

+ 13 - 1
src/views/doorcarManage/infoManage/index.vue

@@ -263,7 +263,19 @@ export default {
     this.peopleData()
     this.fetchPeople()
   },
+  mounted() {
+    window.addEventListener("carGate", this.handleWsEvent);
+  },
+  beforeDestroy() {
+    window.removeEventListener("carGate", this.handleWsEvent);
+  },
   methods: {
+    handleWsEvent(e) {
+      const data = e.detail;
+      if (data.type === "carGate") {
+        this.carEvents.unshift(data.payload);
+      }
+    },
     getCarStatus(row) {
       const data = {
         deviceId: row.deviceId,
@@ -320,7 +332,7 @@ export default {
       console.log("重新连接设备:", device.name)
       // 调用你的后端接口进行重连操作
     },
-    toggleDoor() {
+    toggleDoor(device, door) {
       if (door.loading) return; // 防止连点
       // door.loading = true;
       // // 调用后端接口控制门

+ 12 - 0
src/views/doormanManage/infoManage/index.vue

@@ -302,7 +302,19 @@ export default {
     this.fetchPeople()
     // this.fetchDevices()
   },
+  mounted() {
+    window.addEventListener("doorGate", this.handleWsEvent);
+  },
+  beforeDestroy() {
+    window.removeEventListener("doorGate", this.handleWsEvent);
+  },
   methods: {
+    handleWsEvent(e) {
+      const data = e.detail;
+      if (data.type === "doorGate") {
+        this.doorEvents.unshift(data.payload);
+      }
+    },
     fetchDoorStatus(device) {
       request({
         url: `/door/status/${device.id}`,

+ 14 - 13
src/views/login.vue

@@ -54,6 +54,7 @@
 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",
@@ -150,19 +151,19 @@ export default {
             Cookies.remove("password");
             // Cookies.remove("rememberMe");
           }
-          this.$store
-            .dispatch("Login", this.loginForm)
-            .then(() => {
-              // this.requestFullScreen()
-              // this.$router.push({ path: this.redirect || "/" }).catch(() => {});
-              this.$router.push({ path: "/pt" }).catch(() => { });
-            })
-            .catch(() => {
-              this.loading = false;
-              if (this.captchaOnOff) {
-                this.getCode();
-              }
-            });
+          this.$store.dispatch("Login", this.loginForm).then(() => {
+            const token = this.$store.getters.token;
+            // console.log("token", token)
+            WebSocketService.initWebSocket(token);
+            // this.requestFullScreen()
+            // this.$router.push({ path: this.redirect || "/" }).catch(() => {});
+            this.$router.push({ path: "/pt" }).catch(() => { });
+          }).catch(() => {
+            this.loading = false;
+            if (this.captchaOnOff) {
+              this.getCode();
+            }
+          });
         }
       });
     },

+ 7 - 0
vue.config.js

@@ -36,9 +36,16 @@ module.exports = {
         target: `http://localhost:8090`,
         // target: `http://192.168.5.17/prod-api`,
         changeOrigin: true,
+        ws: true, // 开启 WebSocket 代理
         pathRewrite: {
           ['^' + process.env.VUE_APP_BASE_API]: ''
         }
+      },
+      // 👇 新增 WebSocket 专用代理
+      '/websocket': {
+        target: 'ws://localhost:8090',
+        ws: true,
+        changeOrigin: true
       }
     },
     disableHostCheck: true