diff --git a/src/api/xj/inspection/center.js b/src/api/xj/inspection/center.js
new file mode 100644
index 0000000..4040817
--- /dev/null
+++ b/src/api/xj/inspection/center.js
@@ -0,0 +1,34 @@
+/*
+ * @Author: SunTao 328867980@qq.com
+ * @Date: 2024-11-28 10:26:24
+ * @LastEditors: SunTao 328867980@qq.com
+ * @LastEditTime: 2024-11-28 10:26:24
+ * @FilePath: \znxjxt-ui\src\api\xj\inspection\center.js
+ * @Description: 巡检中心-预警中心接口
+ */
+import request from "@/utils/request";
+
+// 获取预警中心列表
+export function getWarningList(query) {
+ return request({
+ url: "/notice/list",
+ method: "get",
+ params: query,
+ });
+}
+
+// 获取预警中心导航栏
+export function getWarningNav() {
+ return request({
+ url: "/notice/unreadCount",
+ method: "get",
+ });
+}
+
+// 根据id标记通知为已读
+export function markNoticeRead(id) {
+ return request({
+ url: `/notice/read/${id}`,
+ method: "post",
+ });
+}
diff --git a/src/main.js b/src/main.js
index fadbc9b..9c5b2af 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,72 +1,83 @@
-import Vue from 'vue'
+import Vue from "vue";
-import Cookies from 'js-cookie'
+import Cookies from "js-cookie";
-import Element from 'element-ui'
-import './assets/styles/element-variables.scss'
+import Element from "element-ui";
+import "./assets/styles/element-variables.scss";
-import '@/assets/styles/index.scss' // global css
-import '@/assets/styles/ruoyi.scss' // ruoyi css
-import App from './App'
-import store from './store'
-import router from './router'
-import directive from './directive' // directive
-import plugins from './plugins' // plugins
-import { download } from '@/utils/request'
+import "@/assets/styles/index.scss"; // global css
+import "@/assets/styles/ruoyi.scss"; // ruoyi css
+import App from "./App";
+import store from "./store";
+import router from "./router";
+import directive from "./directive"; // directive
+import plugins from "./plugins"; // plugins
+import { download } from "@/utils/request";
-import './assets/icons' // icon
-import './permission' // permission control
+import "./assets/icons"; // icon
+import "./permission"; // permission control
import { getDicts } from "@/api/system/dict/data";
import { getConfigKey } from "@/api/system/config";
-import { parseTime, resetForm, addDateRange, selectDictLabel, selectDictLabels, handleTree } from "@/utils/ruoyi";
+import {
+ parseTime,
+ resetForm,
+ addDateRange,
+ selectDictLabel,
+ selectDictLabels,
+ handleTree,
+} from "@/utils/ruoyi";
// 分页组件
import Pagination from "@/components/Pagination";
// 自定义表格工具组件
-import RightToolbar from "@/components/RightToolbar"
+import RightToolbar from "@/components/RightToolbar";
// 富文本组件
-import Editor from "@/components/Editor"
+import Editor from "@/components/Editor";
// 文件上传组件
-import FileUpload from "@/components/FileUpload"
+import FileUpload from "@/components/FileUpload";
// 图片上传组件
-import ImageUpload from "@/components/ImageUpload"
+import ImageUpload from "@/components/ImageUpload";
// 图片预览组件
-import ImagePreview from "@/components/ImagePreview"
+import ImagePreview from "@/components/ImagePreview";
// 字典标签组件
-import DictTag from '@/components/DictTag'
+import DictTag from "@/components/DictTag";
// 头部标签组件
-import VueMeta from 'vue-meta'
+import VueMeta from "vue-meta";
// 字典数据组件
-import DictData from '@/components/DictData'
+import DictData from "@/components/DictData";
+import { getToken } from "@/utils/auth.js";
//工作流
-import Tinymce from '@/components/tinymce/index.vue'
-import "./assets/text/font.css"
+import Tinymce from "@/components/tinymce/index.vue";
+import "./assets/text/font.css";
+import WebSocketService from "@/plugins/websocket";
+const wsService = new WebSocketService();
// 全局方法挂载
-Vue.prototype.getDicts = getDicts
-Vue.prototype.getConfigKey = getConfigKey
-Vue.prototype.parseTime = parseTime
-Vue.prototype.resetForm = resetForm
-Vue.prototype.addDateRange = addDateRange
-Vue.prototype.selectDictLabel = selectDictLabel
-Vue.prototype.selectDictLabels = selectDictLabels
-Vue.prototype.download = download
-Vue.prototype.handleTree = handleTree
+Vue.prototype.getDicts = getDicts;
+Vue.prototype.getConfigKey = getConfigKey;
+Vue.prototype.parseTime = parseTime;
+Vue.prototype.resetForm = resetForm;
+Vue.prototype.addDateRange = addDateRange;
+Vue.prototype.selectDictLabel = selectDictLabel;
+Vue.prototype.selectDictLabels = selectDictLabels;
+Vue.prototype.download = download;
+Vue.prototype.handleTree = handleTree;
+Vue.prototype.$ws = wsService;
// 全局组件挂载
-Vue.component('DictTag', DictTag)
-Vue.component('Pagination', Pagination)
-Vue.component('RightToolbar', RightToolbar)
-Vue.component('Editor', Editor)
-Vue.component('FileUpload', FileUpload)
-Vue.component('ImageUpload', ImageUpload)
-Vue.component('ImagePreview', ImagePreview)
-Vue.component('tinymce',Tinymce)
+Vue.component("DictTag", DictTag);
+Vue.component("Pagination", Pagination);
+Vue.component("RightToolbar", RightToolbar);
+Vue.component("Editor", Editor);
+Vue.component("FileUpload", FileUpload);
+Vue.component("ImageUpload", ImageUpload);
+Vue.component("ImagePreview", ImagePreview);
+Vue.component("tinymce", Tinymce);
-Vue.use(directive)
-Vue.use(plugins)
-Vue.use(VueMeta)
-DictData.install()
+Vue.use(directive);
+Vue.use(plugins);
+Vue.use(VueMeta);
+DictData.install();
/**
* If you don't want to use mock-server
@@ -78,14 +89,24 @@ DictData.install()
*/
Vue.use(Element, {
- size: Cookies.get('size') || 'medium' // set element-ui default size
-})
+ size: Cookies.get("size") || "medium", // set element-ui default size
+});
-Vue.config.productionTip = false
+Vue.config.productionTip = false;
new Vue({
- el: '#app',
+ el: "#app",
router,
store,
- render: h => h(App)
-})
+ render: (h) => h(App),
+});
+// 确保WebSocket连接在获取到token时建立
+store.watch(
+ () => store.getters.token,
+ (newToken) => {
+ if (newToken) {
+ wsService.connect(`ws://192.168.1.188:8080/websocket?token=${newToken}`);
+ }
+ },
+ { immediate: true }
+);
diff --git a/src/plugins/websocket.js b/src/plugins/websocket.js
index f5f467c..a08dd74 100644
--- a/src/plugins/websocket.js
+++ b/src/plugins/websocket.js
@@ -1,229 +1,61 @@
-/*
- * @Author: SunTao 328867980@qq.com
- * @Date: 2024-11-13 17:13:54
- * @LastEditors: SunTao 328867980@qq.com
- * @LastEditTime: 2024-11-13 17:14:13
- * @FilePath: \znxjxt-ui\src\plugins\websocket.js
- * @Description: websocket传输
- */
+// WebSocketService.js
+class WebSocketService {
+ constructor() {
+ this.ws = null;
+ this.reconnectInterval = 3000;
+ this.eventListeners = {};
+ }
-// websocket实例
-let wsObj = null;
-// ws连接地址
-let wsUrl = null;
-// let userId = null;
-// 是否执行重连 true/不执行 ; false/执行
-let lockReconnect = false;
-// 重连定时器
-let wsCreateHandler = null;
-// 连接成功,执行回调函数
-let messageCallback = null;
-// 连接失败,执行回调函数
-let errorCallback = null;
-// 发送给后台的数据
-let sendDatas = {};
-
-/**
- * 发起websocket请求函数
- * @param {string} url ws连接地址
- * @param {Object} agentData 传给后台的参数
- * @param {function} successCallback 接收到ws数据,对数据进行处理的回调函数
- * @param {function} errCallback ws连接错误的回调函数
- */
-export const connectWebsocket = (url, agentData, successCallback, errCallback) => {
- wsUrl = url;
- createWebSoket();
- messageCallback = successCallback;
- errorCallback = errCallback;
- sendDatas = agentData;
-};
-
-// 手动关闭websocket (这里手动关闭会执行onclose事件)
-export const closeWebsocket = () => {
- if (wsObj) {
- writeToScreen("手动关闭websocket");
- wsObj.close(); // 关闭websocket
- // wsObj.onclose() // 关闭websocket(如果上面的关闭不生效就加上这一条)
- // 关闭重连
- lockReconnect = true;
- wsCreateHandler && clearTimeout(wsCreateHandler);
- // 关闭心跳检查
- heartCheck.stop();
- }
-};
-
-//向服务器端发送消息
-export const sendMsg = value => {
- wsObj.send(JSON.stringify(value));
-};
-
-// 创建ws函数
-const createWebSoket = () => {
- //判断浏览器是否支持websocket
- if (typeof WebSocket === "undefined") {
- writeToScreen("您的浏览器不支持WebSocket,无法获取数据");
- return false;
- }
-
- // const host = window.location.host; //获取端口
- // userId = GetQueryString("userId");
- // wsUrl = "ws://" + host + "/websoket" + userId;
-
- try {
- wsObj = new WebSocket(wsUrl);
- initWsEventHandle();
- } catch (e) {
- writeToScreen("连接异常,开始重连");
- reconnect();
- }
-};
-
-
-const initWsEventHandle = () => {
- try {
- // 连接成功
- wsObj.onopen = event => {
- // heartCheck.start(); //开启心跳
- onWsOpen(event); //客户端与服务器端通信
+ connect(url) {
+ this.ws = new WebSocket(url);
+
+ this.ws.onopen = () => {
+ console.log('WebSocket connected');
+ this.emit('open');
};
-
- // 监听服务器端返回的信息
- wsObj.onmessage = event => {
- onWsMessage(event); //接收数据,抛出
- // heartCheck.reset(); //重置心跳
+
+ this.ws.onmessage = (event) => {
+ this.emit('message', JSON.parse(event.data));
};
-
- wsObj.onclose = event => {
- writeToScreen("onclose执行关闭事件");
- onWsClose(event); //关闭事件
+
+ this.ws.onerror = (error) => {
+ console.error('WebSocket error:', error);
+ this.emit('error', error);
};
-
- wsObj.onerror = event => {
- writeToScreen("onerror执行error事件,开始重连");
- onWsError(event); //error事件
- reconnect(); //重连
+
+ this.ws.onclose = () => {
+ console.log('WebSocket closed');
+ this.emit('close');
+ setTimeout(() => this.connect(url), this.reconnectInterval);
};
- } catch (err) {
- writeToScreen("绑定事件没有成功,开始重连");
- reconnect();
}
-};
-
-//open事件 WebSocket连接成功时触发
-const onWsOpen = event => {
- // 客户端与服务器端通信
- // wsObj.send('我发送消息给服务端');
- // 添加状态判断,当为OPEN时,发送消息
- if (wsObj.readyState === wsObj.OPEN) {
- // wsObj.OPEN = 1
- // 发给后端的数据需要字符串化
- wsObj.send(JSON.stringify(sendDatas));
+
+ send(data) {
+ if (this.ws && this.ws.readyState === WebSocket.OPEN) {
+ this.ws.send(JSON.stringify(data));
+ } else {
+ console.error('WebSocket is not connected');
+ }
}
- if (wsObj.readyState === wsObj.CLOSED) {
- // wsObj.CLOSED = 3
- writeToScreen("wsObj.readyState=3, ws连接异常,开始重连");
- reconnect();
- errorCallback(event);
+
+ on(event, callback) {
+ if (!this.eventListeners[event]) {
+ this.eventListeners[event] = [];
+ }
+ this.eventListeners[event].push(callback);
}
-};
-
-//message事件 接收到WebSocket服务器发送的消息时触发
-const onWsMessage = event => {
- const jsonStr = event.data;
- // writeToScreen("onWsMessage接收到服务器的数据: ", jsonStr);
- messageCallback(jsonStr);
-};
-
-//close事件 WebSocket连接关闭时触发
-const onWsClose = event => {
- writeToScreen("DISCONNECT");
- // e.code === 1000 表示正常关闭。 无论为何目的而创建, 该链接都已成功完成任务。
- // e.code !== 1000 表示非正常关闭。
- console.log("onclose event: ", event);
- if (event && event.code !== 1000) {
- writeToScreen("非正常关闭");
- errorCallback(event);
- // 如果不是手动关闭,这里的重连会执行;如果调用了手动关闭函数,这里重连不会执行
- reconnect();
+
+ emit(event, data) {
+ if (this.eventListeners[event]) {
+ this.eventListeners[event].forEach(callback => callback(data));
+ }
}
-};
-
-//error事件 WebSocket连接出错时触发
-const onWsError = event => {
- writeToScreen("onWsError: ", event.data);
- errorCallback(event);//抛出错误
-};
-
-//封装console.log()
-const writeToScreen = massage => {
- console.log(massage);
-};
-
-// 重连函数
-const reconnect = () => {
- if (lockReconnect) {
- return;
+
+ close() {
+ if (this.ws) {
+ this.ws.close();
+ }
}
- writeToScreen("3秒后重连");
- lockReconnect = true;
- // 没连接上会一直重连,设置延迟避免请求过多
- wsCreateHandler && clearTimeout(wsCreateHandler);
- wsCreateHandler = setTimeout(() => {
- writeToScreen("重连..." + wsUrl);
- createWebSoket();
- lockReconnect = false;
- writeToScreen("重连完成");
- }, 5000);
-};
-
-// 从浏览器地址中获取对应参数
-const GetQueryString = name => {
- let reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
- // 获取url中 ? 符后的字符串并正则匹配
- let r = window.location.search.substr(1).match(reg);
- let context = "";
- r && (context = r[2]);
- reg = null;
- r = null;
- return context;
-};
-
-// 心跳检查(看看websocket是否还在正常连接中)
-let heartCheck = {
- timeout: 15 * 1000,
- timeoutObj: null,
- serverTimeoutObj: null,
- // 重启
- reset() {
- clearTimeout(this.timeoutObj);
- clearTimeout(this.serverTimeoutObj);
- this.start();
- },
- // 停止
- stop() {
- clearTimeout(this.timeoutObj);
- clearTimeout(this.serverTimeoutObj);
- },
- // 开启定时器
- start() {
- this.timeoutObj && clearTimeout(this.timeoutObj);
- this.serverTimeoutObj && clearTimeout(this.serverTimeoutObj);
- // 15s之内如果没有收到后台的消息,则认为是连接断开了,需要重连
- this.timeoutObj = setTimeout(() => {
- writeToScreen("心跳检查,发送ping到后台");
- try {
- const datas = { content: "心跳检测" };
- wsObj.send(JSON.stringify(datas));
- } catch (err) {
- writeToScreen("发送ping异常,重连");
- reconnect();
- }
- // console.log("内嵌定时器this.serverTimeoutObj: ", this.serverTimeoutObj);
- // 内嵌定时器
- this.serverTimeoutObj = setTimeout(() => {
- writeToScreen("没有收到后台的数据,重新连接");
- reconnect();
- }, this.timeout);
- }, this.timeout);
- },
-};
\ No newline at end of file
+}
+
+export default WebSocketService;
\ No newline at end of file
diff --git a/src/views/big-screen/index.vue b/src/views/big-screen/index.vue
index 3b03506..5dc6551 100644
--- a/src/views/big-screen/index.vue
+++ b/src/views/big-screen/index.vue
@@ -2,7 +2,7 @@
* @Author: SunTao 328867980@qq.com
* @Date: 2024-10-17 11:34:00
* @LastEditors: SunTao 328867980@qq.com
- * @LastEditTime: 2024-11-21 09:12:52
+ * @LastEditTime: 2024-11-29 15:31:24
* @FilePath: \znxjxt-ui\src\views\big-screen\index.vue
* @Description: 大屏首页
-->
@@ -508,9 +508,20 @@ export default {
this.getRoadList();
this.getDieaseTypeList();
this.getMessageList();
- // this.initWebSocket();
+ this.handleMessage();
},
+ mounted() {},
methods: {
+ /**
+ * @description: 处理websocket消息
+ * @return {*}
+ */
+ handleMessage() {
+ this.$ws.on("message", (data) => {
+ console.log("收到xxxxxxxx消息:", data);
+ });
+ },
+
/**
* @description: 获取当前时间
* @return {*}
@@ -549,7 +560,7 @@ export default {
/**
* @description: 获取消息中心数据
- * @return {void}
+ * @return {void}
*/
getMessageList() {
// getMessageList().then(({ code, data }) => {
@@ -600,7 +611,7 @@ export default {
/**
* @description: 获取数据栏右上角选项数据
- * @return {void}
+ * @return {void}
*/
getSelect() {
selectTypeList().then(({ code, data }) => {
@@ -609,10 +620,10 @@ export default {
}
});
},
-
+
/**
* @description: 获取路段下拉数据
- * @return {void}
+ * @return {void}
*/
getRoadList() {
getRoadListTypes().then(({ code, data }) => {
@@ -624,7 +635,7 @@ export default {
/**
* @description: 获取图片背景左上角病害类型下拉
- * @return {void}
+ * @return {void}
*/
getDieaseTypeList() {
getDefectTypes().then(({ code, data }) => {
@@ -636,7 +647,7 @@ export default {
/**
* @description: 获取图片背景下坐标数据
- * @return {void}
+ * @return {void}
*/
getMapCare(value) {
const data = {
@@ -652,7 +663,7 @@ export default {
/**
* @description: 点击病害日志详情打开弹窗进行地图打点
- * @return {void}
+ * @return {void}
*/
getimagePoint(item) {
this.imgTitle = "查看";
@@ -673,7 +684,7 @@ export default {
/**
* @description: 关闭图片查看弹窗
- * @return {void}
+ * @return {void}
*/
imgCancel() {
this.imgTitle = "";
@@ -683,7 +694,7 @@ export default {
/**
* @description: 关闭查看点位大图弹窗
- * @return {void}
+ * @return {void}
*/
screenImgCancel() {
this.$refs.roadMap.removeSelectClick();
@@ -692,7 +703,7 @@ export default {
/**
* @description: 切换icon类型多选框事件
- * @return {void}
+ * @return {void}
*/
handleChecked(value) {
this.centerPiont = this.drawPointList.filter(
@@ -708,7 +719,7 @@ export default {
/**
* @description: 获取地图点位信息
- * @return {void}
+ * @return {void}
*/
getCenterPiont() {
// 如果当前已经有打点坐标
@@ -754,7 +765,7 @@ export default {
/**
* @description: 绘制地图点位
- * @return {void}
+ * @return {void}
*/
drawPoint() {
const features = [];
@@ -853,7 +864,7 @@ export default {
/**
* @description: 获取地图线段点位信息
- * @return {void}
+ * @return {void}
*/
getLinePoint() {
if (!this.markLayerLines) {
@@ -868,7 +879,7 @@ export default {
/**
* @description: 绘制地图线段
- * @return {void}
+ * @return {void}
*/
drawLine() {
const features = [];
@@ -929,8 +940,8 @@ export default {
/**
* @description: 地图线段颜色区分
- * @param {number} value
- * @return {string}
+ * @param {number} value
+ * @return {string}
*/
getLineColor(value) {
if (value > 92) {
@@ -945,11 +956,11 @@ export default {
return "#E64548";
}
},
-
+
/**
* @description: 地图下方4图标类别切换点击事件
- * @param {string} value
- * @return {void}
+ * @param {string} value
+ * @return {void}
*/
changeIconType(value) {
if (this.bottomTipClick !== value) {
@@ -970,7 +981,7 @@ export default {
/**
* @description: 获取icon多选数据
- * @return {void}
+ * @return {void}
*/
getIconType() {
this.mapLogeList = {};
@@ -992,8 +1003,8 @@ export default {
/**
* @description: 传回来的地图图层
- * @param {number} zoom
- * @return {void}
+ * @param {number} zoom
+ * @return {void}
*/
getZoom(zoom) {
this.mapZoom = zoom;
@@ -1006,8 +1017,8 @@ export default {
/**
* @description: 地图选中feature事件
- * @param {object} e
- * @return {void}
+ * @param {object} e
+ * @return {void}
*/
featureSelect(e) {
const map = this.$refs.roadMap.instance.get("map");
@@ -1043,8 +1054,8 @@ export default {
/**
* @description: 数据栏切换事件
- * @param {object} item
- * @return {void}
+ * @param {object} item
+ * @return {void}
*/
changeElement(item) {
if (this.elementDiv !== item) {
@@ -1098,6 +1109,9 @@ export default {
class: "twe",
},
];
+ // 不接收小车位置消息
+ const data = { type: "carLocation", status: false };
+ this.$ws.send(data);
// 地图右上角多选按钮隐藏
this.showIconList = false;
// 图层恢复
@@ -1141,6 +1155,10 @@ export default {
class: "twe",
},
];
+ // 发送小车位置消息
+ const data = { type: "carLocation", status: true };
+ this.$ws.send(data);
+ // 将地图层级初始化
this.$nextTick(() => {
const map = this.$refs.roadMap.instance.get("map");
map.getView().setZoom(10);
@@ -1191,6 +1209,9 @@ export default {
class: "one",
},
];
+ // 发送小车位置消息
+ const data = { type: "carLocation", status: true };
+ this.$ws.send(data);
// 地图右上角多选按钮隐藏
this.showIconList = false;
// 图层恢复
@@ -1202,11 +1223,6 @@ export default {
map.getView().setZoom(10);
map.getView().setCenter([123.30297096718999, 41.87942945541742]);
});
- // 地图右上角多选按钮显示
- // this.getIconType();
- // this.showIconList = true;
- // 进行地图打点
- // this.getCenterPiont();
this.getLinePoint();
}
}
@@ -1214,7 +1230,7 @@ export default {
/**
* @description: 跳转系统首页
- * @return {void}
+ * @return {void}
*/
goIndex() {
this.$router.push("/index");
@@ -1222,7 +1238,7 @@ export default {
/**
* @description: 图片位置信息获取
- * @return {void}
+ * @return {void}
*/
updateScreenRects() {
1;
@@ -1241,11 +1257,11 @@ export default {
/**
* @description: 图片红框位置
- * @param {object} left
- * @param {object} top
- * @param {object} width
- * @param {object} height
- * @return {object}
+ * @param {object} left
+ * @param {object} top
+ * @param {object} width
+ * @param {object} height
+ * @return {object}
*/
getScreenRectStyle({ left, top, width, height }) {
const image = this.$refs.mainImage;
@@ -1272,39 +1288,10 @@ export default {
boxSizing: "border-box",
};
},
-
- /**
- * @description: 初始化websocket
- * @return {void}
- */
- initWebSocket() {
- const url = `ws://192.168.1.188:8080/websocket?token=${getToken()}`;
- const data = { type: "carLocation", status: true };
- connectWebsocket(
- url,
- data,
- (res) => {
- // console.log("onWsMessage接收到服务器的数据: ", res);
- console.log(JSON.parse(res));
- },
- (err) => {
- console.log("断开重连");
- }
- );
- },
-
- /**
- * @description: 发送消息
- * @return {void}
- */
- sendMsg() {
- sendMsg(5555); //value是发送的值
- // this.value = "";
- },
},
beforeDestroy() {
clearInterval(this.timeFlag);
- closeWebsocket();
+ this.$ws.close();
},
};
diff --git a/src/views/xj/inspection-warn/warning-center/index.vue b/src/views/xj/inspection-warn/warning-center/index.vue
index 1c74809..a1cf726 100644
--- a/src/views/xj/inspection-warn/warning-center/index.vue
+++ b/src/views/xj/inspection-warn/warning-center/index.vue
@@ -17,17 +17,10 @@
:inline="true"
label-width="5rem"
>
-
-
-
-
+
@@ -42,17 +35,17 @@
-
+
@@ -108,27 +101,27 @@
v-for="(item, index) in editableTabs"
:key="`tabs-${index}`"
:label="item.title"
- :name="item.value"
+ :name="item.code"
>
- asd
- {{ scope.row.segmentName }}
+ {{ scope.row.createdTime }}
-
-
+ prop="title"
+ >
+
+
+