From 26e6fd858456a53935fe136167ca0270c6ce9edf Mon Sep 17 00:00:00 2001 From: SunTao <328867980@qq.com> Date: Thu, 14 Nov 2024 17:43:24 +0800 Subject: [PATCH] =?UTF-8?q?fix=EF=BC=9Awebsocket=E6=8E=A5=E5=85=A5?= =?UTF-8?q?=EF=BC=8C=E5=A4=A7=E5=B1=8F=E4=BF=AE=E6=94=B9=E9=83=A8=E5=88=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 + src/api/xj/screen/index.js | 29 +- src/api/xj/surface.js | 2 +- src/components/map/fssm-map.vue | 5 +- src/plugins/websocket.js | 229 +++++++++++++++ .../big-screen/components/img-dialog.vue | 226 +++++++++++---- .../disease-components/traffic-log.vue | 34 +-- src/views/big-screen/index.vue | 213 ++++++++++---- .../overview-components/disease-trends.vue | 132 ++++----- .../inspection-vehicles.vue | 21 +- .../overview-components/patrol-order.vue | 270 +++++++++++++++++- .../overview-components/today-inspection.vue | 130 ++++++++- .../components/image-dialog.vue | 17 +- .../inspection/surface-management/index.vue | 3 +- 14 files changed, 1071 insertions(+), 241 deletions(-) create mode 100644 src/plugins/websocket.js diff --git a/package.json b/package.json index 423ef5a..cd710f2 100644 --- a/package.json +++ b/package.json @@ -68,6 +68,7 @@ "vue-seamless-scroll": "^1.1.23", "vuedraggable": "2.24.3", "vuex": "3.6.0", + "websocket": "^1.0.35", "xcrud": "^0.4.19" }, "devDependencies": { diff --git a/src/api/xj/screen/index.js b/src/api/xj/screen/index.js index 60c6cef..fcb5c2c 100644 --- a/src/api/xj/screen/index.js +++ b/src/api/xj/screen/index.js @@ -2,7 +2,7 @@ * @Author: SunTao 328867980@qq.com * @Date: 2024-10-24 15:03:28 * @LastEditors: SunTao 328867980@qq.com - * @LastEditTime: 2024-11-06 13:25:37 + * @LastEditTime: 2024-11-14 09:16:02 * @FilePath: \znxjxt-ui\src\api\xj\screen\index.js * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE */ @@ -17,10 +17,18 @@ export function selectTypeList(query) { }); } +// v1 // 获取地图打点数据接口 +// export function mapPointList(query) { +// return request({ +// url: "/bigscreen/getMapPoint", +// method: "get", +// params: query, +// }); +// } export function mapPointList(query) { return request({ - url: "/bigscreen/getMapPoint", + url: "/bigscreen/v2/getMapPoint", method: "get", params: query, }); @@ -79,12 +87,21 @@ export function getSegment(data) { }); } -// 根据选择的按钮类型查下级选项框 -export function getItemTypes(params) { +// 病害筛选根据点击的详情查图片详情 +export function getMediaIndex(data){ return request({ - url: "/metadata/getItemTypes", + url: "/bigscreen/v2/getTableIndex", + method: "post", + data, + }); +} + +// 根据选择的按钮类型查下级选项框 +export function getItemTypes(query) { + return request({ + url: "/bigscreen/v2/getAllDefectType", method: "get", - params, + params: query, }); } diff --git a/src/api/xj/surface.js b/src/api/xj/surface.js index 1de0a9c..fd7dced 100644 --- a/src/api/xj/surface.js +++ b/src/api/xj/surface.js @@ -20,7 +20,7 @@ export function getSegment() { // 病害类型下拉数据 export function getDefectList(params) { return request({ - url: "/metadata/defectType", + url: "/bigscreen/v2/getAllDefectType", method: "get", params, }); diff --git a/src/components/map/fssm-map.vue b/src/components/map/fssm-map.vue index 42bf066..baeac1b 100644 --- a/src/components/map/fssm-map.vue +++ b/src/components/map/fssm-map.vue @@ -2,7 +2,7 @@ * @Author: SunTao 328867980@qq.com * @Date: 2024-10-14 10:46:23 * @LastEditors: SunTao 328867980@qq.com - * @LastEditTime: 2024-11-06 16:42:42 + * @LastEditTime: 2024-11-14 16:58:34 * @FilePath: \znxjxt-ui\src\views\xj\inspection\task-management\components\fssm-map.vue * @Description: 公共地图 --> @@ -150,6 +150,7 @@ export default { deep: true, immediate: true, }, + /* 监听传过来的底图类型 */ baseMap: { handler(val) { @@ -211,7 +212,7 @@ export default { minZoom: 7, maxZoom: 18, }), - layers: [ tianditu_img_c, tianditu_cva_c], + layers: [tianditu_img_c, tianditu_cva_c], }); // 图层点击事件 map.on("singleclick", (e) => { diff --git a/src/plugins/websocket.js b/src/plugins/websocket.js new file mode 100644 index 0000000..f5f467c --- /dev/null +++ b/src/plugins/websocket.js @@ -0,0 +1,229 @@ +/* + * @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传输 + */ + +// 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); //客户端与服务器端通信 + }; + + // 监听服务器端返回的信息 + wsObj.onmessage = event => { + onWsMessage(event); //接收数据,抛出 + // heartCheck.reset(); //重置心跳 + }; + + wsObj.onclose = event => { + writeToScreen("onclose执行关闭事件"); + onWsClose(event); //关闭事件 + }; + + wsObj.onerror = event => { + writeToScreen("onerror执行error事件,开始重连"); + onWsError(event); //error事件 + reconnect(); //重连 + }; + } 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)); + } + if (wsObj.readyState === wsObj.CLOSED) { + // wsObj.CLOSED = 3 + writeToScreen("wsObj.readyState=3, ws连接异常,开始重连"); + reconnect(); + errorCallback(event); + } +}; + +//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(); + } +}; + +//error事件 WebSocket连接出错时触发 +const onWsError = event => { + writeToScreen("onWsError: ", event.data); + errorCallback(event);//抛出错误 +}; + +//封装console.log() +const writeToScreen = massage => { + console.log(massage); +}; + +// 重连函数 +const reconnect = () => { + if (lockReconnect) { + return; + } + 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 diff --git a/src/views/big-screen/components/img-dialog.vue b/src/views/big-screen/components/img-dialog.vue index a162b14..2a7a77d 100644 --- a/src/views/big-screen/components/img-dialog.vue +++ b/src/views/big-screen/components/img-dialog.vue @@ -2,7 +2,7 @@ * @Author: SunTao 328867980@qq.com * @Date: 2024-10-22 15:30:25 * @LastEditors: SunTao 328867980@qq.com - * @LastEditTime: 2024-11-13 13:31:49 + * @LastEditTime: 2024-11-14 16:44:42 * @FilePath: \znxjxt-ui\src\views\big-screen\components\img-dialog.vue * @Description: 大屏查看图片弹窗 --> @@ -53,6 +53,7 @@ v-model="imgForm.segmentId" placeholder="请选择路段名称" :popper-append-to-body="false" + filterable clearable > - - + + + + + diff --git a/src/views/big-screen/index.vue b/src/views/big-screen/index.vue index 7077449..af79fd6 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-13 14:11:57 + * @LastEditTime: 2024-11-14 17:26:53 * @FilePath: \znxjxt-ui\src\views\big-screen\index.vue * @Description: 大屏首页 --> @@ -73,6 +73,7 @@ :select="item.select" :is="item.component" :bottomTipClick="bottomTipClick" + @imagePoint="getimagePoint" > diff --git a/src/views/big-screen/overview-components/disease-trends.vue b/src/views/big-screen/overview-components/disease-trends.vue index b20ec1c..b08faa3 100644 --- a/src/views/big-screen/overview-components/disease-trends.vue +++ b/src/views/big-screen/overview-components/disease-trends.vue @@ -2,7 +2,7 @@ * @Author: SunTao 328867980@qq.com * @Date: 2024-10-18 10:16:30 * @LastEditors: SunTao 328867980@qq.com - * @LastEditTime: 2024-10-24 17:09:27 + * @LastEditTime: 2024-11-14 15:49:52 * @FilePath: \znxjxt-ui\src\views\big-screen\disease-components\disease-trends.vue * @Description: 总览大屏-病害趋势 --> @@ -44,12 +44,12 @@ export default { const yData1 = this.echartList.map((item) => { return item.A1000; }); - const yData2 = this.echartList.map((item) => { - return item.A2001; - }); - const yData3 = this.echartList.map((item) => { - return item.A2000; - }); + // const yData2 = this.echartList.map((item) => { + // return item.A2001; + // }); + // const yData3 = this.echartList.map((item) => { + // return item.A2000; + // }); const yData4 = this.echartList.map((item) => { return item.A0; }); @@ -167,8 +167,66 @@ export default { }, data: yData1, }, + // { + // name: "块状修补(沥青)", + // type: "line", + // smooth: true, + // areaStyle: { + // color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + // { + // offset: 0, + // color: "#08B4A6", + // }, + // { + // offset: 1, + // color: "rgba(8,180,166,0)", + // }, + // ]), + // }, + // lineStyle: { + // width: 1, + // color: "#08B4A6", + // }, + // // 设置节点样式 + // showSymbol: false, + // symbol: "circle", // 可以选择 circle, diamond, pin 等 + // symbolSize: 10, // 节点大小 + // itemStyle: { + // color: "#08B4A6", + // }, + // data: yData2, + // }, + // { + // name: "条状修补(沥青)", + // type: "line", + // smooth: true, + // areaStyle: { + // color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ + // { + // offset: 0, + // color: "#146fd7", + // }, + // { + // offset: 1, + // color: "rgba(20, 111, 215,0)", + // }, + // ]), + // }, + // lineStyle: { + // width: 1, + // color: "#146fd7", + // }, + // // 设置节点样式 + // showSymbol: false, + // symbol: "circle", // 可以选择 circle, diamond, pin 等 + // symbolSize: 10, // 节点大小 + // itemStyle: { + // color: "#146fd7", + // }, + // data: yData3, + // }, { - name: "块状修补(沥青)", + name: "横向裂缝", type: "line", smooth: true, areaStyle: { @@ -194,64 +252,6 @@ export default { itemStyle: { color: "#08B4A6", }, - data: yData2, - }, - { - name: "条状修补(沥青)", - type: "line", - smooth: true, - areaStyle: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { - offset: 0, - color: "#146fd7", - }, - { - offset: 1, - color: "rgba(20, 111, 215,0)", - }, - ]), - }, - lineStyle: { - width: 1, - color: "#146fd7", - }, - // 设置节点样式 - showSymbol: false, - symbol: "circle", // 可以选择 circle, diamond, pin 等 - symbolSize: 10, // 节点大小 - itemStyle: { - color: "#146fd7", - }, - data: yData3, - }, - { - name: "横向裂缝", - type: "line", - smooth: true, - areaStyle: { - color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ - { - offset: 0, - color: "#994EFF", - }, - { - offset: 1, - color: "rgba(153,78,255,0)", - }, - ]), - }, - lineStyle: { - width: 1, - color: "#994EFF", - }, - // 设置节点样式 - showSymbol: false, - symbol: "circle", // 可以选择 circle, diamond, pin 等 - symbolSize: 10, // 节点大小 - itemStyle: { - color: "#994EFF", - }, data: yData4, }, { diff --git a/src/views/big-screen/overview-components/inspection-vehicles.vue b/src/views/big-screen/overview-components/inspection-vehicles.vue index 047da9a..9f8fc73 100644 --- a/src/views/big-screen/overview-components/inspection-vehicles.vue +++ b/src/views/big-screen/overview-components/inspection-vehicles.vue @@ -2,7 +2,7 @@ * @Author: SunTao 328867980@qq.com * @Date: 2024-11-08 09:40:18 * @LastEditors: SunTao 328867980@qq.com - * @LastEditTime: 2024-11-13 13:23:21 + * @LastEditTime: 2024-11-14 15:54:12 * @FilePath: \znxjxt-ui\src\views\big-screen\disease-components\inspection-vehicles.vue * @Description: 总览大屏-巡检车辆 --> @@ -29,6 +29,7 @@ > @@ -42,7 +43,7 @@ height="285" > - + @@ -101,11 +288,84 @@ export default { .value { span { + cursor: pointer; font-family: "DouYu"; font-size: 1.4rem; } } } } + +// 弹窗内容样式 +.patrol-content { + height: 30rem; + padding: 0 2rem; + + ::v-deep .el-select { + width: 12rem; + + .el-input .el-select__caret { + line-height: 1.5rem; + } + + .el-input--medium .el-input__inner { + height: 1.5rem; + background-color: transparent; + color: #89c5e8; + border-color: #6991cd; + } + + .el-select-dropdown { + background-color: #102649; + border-color: #08204f; + .el-scrollbar { + .el-select-dropdown__wrap { + .el-scrollbar__view { + .el-select-dropdown__item { + color: #aaabb8; + } + + .el-select-dropdown__item:hover { + background-color: #2b4c7e; + } + + .el-select-dropdown__item.selected { + background-color: #2b4c7e; + } + + .el-select-dropdown__item.hover { + background-color: #2b4c7e; + } + } + + .el-select-dropdown__list { + background-color: #102649; + } + } + } + } + } + + .dialog-div { + width: 100%; + height: 100%; + } +} + +/* 修改弹窗样式 */ +::v-deep .el-dialog__header { + padding: 10px; + background-color: #113463; + + span, + i { + color: #ffffff; + } +} + +::v-deep .el-dialog__body { + padding: 0; + background-color: #113463; +} \ No newline at end of file diff --git a/src/views/big-screen/overview-components/today-inspection.vue b/src/views/big-screen/overview-components/today-inspection.vue index 4514b0b..023e240 100644 --- a/src/views/big-screen/overview-components/today-inspection.vue +++ b/src/views/big-screen/overview-components/today-inspection.vue @@ -2,7 +2,7 @@ * @Author: SunTao 328867980@qq.com * @Date: 2024-10-18 09:42:49 * @LastEditors: SunTao 328867980@qq.com - * @LastEditTime: 2024-11-13 13:38:46 + * @LastEditTime: 2024-11-14 15:48:21 * @FilePath: \znxjxt-ui\src\views\big-screen\disease-components\today-inspection.vue * @Description: 总览大屏-今日巡查 --> @@ -10,10 +10,10 @@