From 3abb45872eaa900bd0e99c2232cd5afb9a39779b Mon Sep 17 00:00:00 2001
From: 马宇豪 <978517621@qq.com>
Date: 星期三, 06 九月 2023 16:49:57 +0800
Subject: [PATCH] 更新大屏
---
src/router/route.ts | 2
src/views/bigScreen/index.vue | 1
src/views/bigScreen/components/screen.vue | 850 ++++++++++++++++++++++++++++++++++++++++++++++----------
src/api/bigScreen/index.ts | 47 +++
4 files changed, 749 insertions(+), 151 deletions(-)
diff --git a/src/api/bigScreen/index.ts b/src/api/bigScreen/index.ts
new file mode 100644
index 0000000..da3d499
--- /dev/null
+++ b/src/api/bigScreen/index.ts
@@ -0,0 +1,47 @@
+import request from '/@/utils/request';
+
+export function bigScreenApi() {
+ return {
+ getGas: () => {
+ return request({
+ url: import.meta.env.VITE_API_URL + '/gasCategory/list',
+ method: 'post'
+ });
+ },
+ getAreas: (data: object) => {
+ return request({
+ url: import.meta.env.VITE_API_URL + '/region/page',
+ method: 'post',
+ data: data
+ });
+ },
+ getWarningNum: (data: object) => {
+ return request({
+ url: import.meta.env.VITE_API_URL + '/gasWarnLog/gasWarnLogCountByTime',
+ method: 'post',
+ data: data
+ });
+ },
+ getWarningInfo: (data: object) => {
+ return request({
+ url: import.meta.env.VITE_API_URL + '/gasWarnLog/gasWarnLogInfoByTime',
+ method: 'post',
+ data: data
+ });
+ },
+ getGasNdData: (data: object) => {
+ return request({
+ url: import.meta.env.VITE_API_URL + '/gasMonitorData/gas/lineChart',
+ method: 'post',
+ data: data
+ });
+ },
+ getGasTlData: (data: object) => {
+ return request({
+ url: import.meta.env.VITE_API_URL + '/gasMonitorData/gasFlux/lineChart',
+ method: 'post',
+ data: data
+ });
+ }
+ };
+}
diff --git a/src/router/route.ts b/src/router/route.ts
index c9d3e74..9df1e76 100644
--- a/src/router/route.ts
+++ b/src/router/route.ts
@@ -5,7 +5,7 @@
path: '/',
name: '/',
component: () => import('/@/layout/index.vue'),
- redirect: '/home',
+ redirect: '/bigScreen',
meta: {
isKeepAlive: false
},
diff --git a/src/views/bigScreen/components/screen.vue b/src/views/bigScreen/components/screen.vue
index fd35822..dde3c1a 100644
--- a/src/views/bigScreen/components/screen.vue
+++ b/src/views/bigScreen/components/screen.vue
@@ -31,7 +31,7 @@
<div class="left-top withFilter">
<div class="chart-head">
<div class="chart-tit">预警汇总</div>
- <el-radio-group v-model="chart1Search">
+ <el-radio-group v-model="countTime" @change="changeTotal">
<el-radio :label="1" size="small" border>当日</el-radio>
<el-radio :label="2" size="small" border>近7天</el-radio>
<el-radio :label="3" size="small" border>近30天</el-radio>
@@ -40,10 +40,10 @@
</div>
<div class="chart-cont">
<div class="orange">
- <div><span>30</span><span>橙色预警</span></div>
+ <div><span>{{yellowNum}}</span><span>橙色预警</span></div>
</div>
<div class="red">
- <div><span>10</span><span>红色预警</span></div>
+ <div><span>{{redNum}}</span><span>红色预警</span></div>
</div>
</div>
</div>
@@ -59,6 +59,7 @@
range-separator="至"
start-placeholder="开始日期"
end-placeholder="结束日期"
+ @change="timeChange"
format="YYYY-MM-DD" value-format="YYYY-MM-DD HH:mm:ss"
/>
</div>
@@ -70,15 +71,15 @@
<div class="chart-head">
<div class="chart-tit">设备状态</div>
<div class="sys-status">
- <Cpu style="width: 1.2em; height: 1.2em; color: #fff" />
- <div>系统状态:<span>正常</span></div>
+ <Cpu :class="online == 3 ? 'onlineIcon':'offlineIcon'"/>
+ <div>系统状态:<span :class="online == 3 ? 'online':'offline'">{{online == 3?'正常':'异常'}}</span></div>
</div>
</div>
<div class="chart-cont">
<div class="online">
<dv-decoration-9 :color="['#22aaff','rgba(34,170,255,.6)']">
<div color-green font-600 class="isOnline" bg="~ dark/0">
- 0
+ {{online}}
</div>
</dv-decoration-9>
<div>在线</div>
@@ -86,7 +87,7 @@
<div class="online">
<dv-decoration-9 :color="['#ee594a','rgba(238,89,74,.6)']">
<div color-red font-600 class="isOnline red-font" bg="~ dark/0">
- 1
+ {{3 - online}}
</div>
</dv-decoration-9>
<div style="color:#ee594a;">离线</div>
@@ -108,7 +109,18 @@
<div></div>
<div></div>
</div>
- <dv-scroll-board :config="bigConfig" class="scroll-table" @mouseover="mouseoverHandler" @click="clickHandler" />
+<!-- <dv-scroll-board :config="bigConfig" class="scroll-table" @mouseover="mouseoverHandler" @click="clickHandler" />-->
+ <table class="weather">
+ <tr class="weatherTit"><td>时间</td><td>温度</td><td>湿度</td><td>风速</td><td>风向</td><td>气压</td></tr>
+ <tr v-for="(item,index) in weatherData" :key="index" class="weatherRow">
+ <td>{{item.time}}</td>
+ <td>{{item.temp}}</td>
+ <td>{{item.humidity}}</td>
+ <td>{{item.windSpeed}}</td>
+ <td>{{item.windDirection}}</td>
+ <td>{{item.pressure}}</td>
+ </tr>
+ </table>
</div>
</div>
</div>
@@ -116,14 +128,17 @@
<div class="right-top withFilterLong">
<div class="chart-head">
<div class="chart-tit long-tit">气体浓度监测</div>
- <el-select v-model="gasSearch" :teleported="false" class="m-2" placeholder="Select" size="small">
- <el-option
- v-for="item in gasOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
+ <div class="searchGroup">
+ <el-select v-model="gasSearch" :teleported="false" class="m-2" placeholder="Select" size="small" @change="changeGas1">
+ <el-option
+ v-for="item in gasOptions"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
+ />
+ </el-select>
+ <div class="checkMore" @click="toNdPage()"><el-icon><DArrowRight /></el-icon></div>
+ </div>
</div>
<div class="chart-cont">
<div class="echart" :id="gasN"></div>
@@ -133,22 +148,23 @@
<div class="chart-head">
<div class="chart-tit long-tit">气体通量监测</div>
<div class="searchGroup">
- <el-select v-model="searchParams.gasSearch" :teleported="false" class="m-2" placeholder="Select" size="small">
+ <el-select v-model="tlGasSearch" :teleported="false" class="m-2" placeholder="Select" size="small" @change="changeGas2">
<el-option
v-for="item in gasOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
+ :key="item.id"
+ :label="item.name"
+ :value="item.id"
/>
</el-select>
- <el-select v-model="searchParams.areaSearch" :teleported="false" class="m-2" placeholder="Select" size="small">
- <el-option
- v-for="item in areaOptions"
- :key="item.value"
- :label="item.label"
- :value="item.value"
- />
- </el-select>
+ <div class="checkMore" @click="toTlPage()"><el-icon><DArrowRight /></el-icon></div>
+<!-- <el-select v-model="searchParams.areaSearch" :teleported="false" class="m-2" placeholder="Select" size="small">-->
+<!-- <el-option-->
+<!-- v-for="item in areaOptions"-->
+<!-- :key="item.id"-->
+<!-- :label="item.name"-->
+<!-- :value="item.id"-->
+<!-- />-->
+<!-- </el-select>-->
</div>
</div>
<div class="chart-cont">
@@ -161,12 +177,12 @@
</div>
<div class="chart-cont">
<div class="online">
- <div class="totalNum"><span>1048</span>条</div>
+ <div class="totalNum"><span>{{ gasTotal }}</span>条</div>
<div class="dataPic"></div>
<div class="totalNum">浓度条数</div>
</div>
<div class="online">
- <div class="totalNum"><span>566</span>条</div>
+ <div class="totalNum"><span>{{ tlTotal }}</span>条</div>
<div class="dataPic"></div>
<div class="totalNum">通量条数</div>
</div>
@@ -174,6 +190,34 @@
</div>
</div>
</div>
+ <el-dialog
+ v-model="dialogWarning"
+ title="预警信息"
+ width="35%"
+ :append-to-body="true"
+ :draggable="true"
+ custom-class="warningMsg"
+ top="2vh"
+ >
+ <div class="warning-cont">
+ <div><span>预警信息:</span><span>{{warningGas.content}}</span></div>
+ <div><span>预警时间:</span><span>{{warningGas.warnTime}}</span></div>
+ <div><span>预警气体:</span><span>{{warningGas.gasName}}</span></div>
+ <div><span>预警级别:</span><span :class="warningGas.gasThresholdName == '红色预警'?'red':''">{{warningGas.gasThresholdName}}</span></div>
+ <div><span>气体单位:</span><span>{{warningGas.gasUnit}}</span></div>
+ <div><span>预警浓度:</span><span>{{warningGas.gasConcentration}}</span></div>
+ <div><span>处理状态:</span><span>{{warningGas.status == 0?'未处理':warningGas.status == 1?'已处理':'--'}}</span></div>
+ <div v-if="warningGas.handlerRealName"><span>处理人:</span><span>{{warningGas.handlerRealName}}</span></div>
+ <div v-if="warningGas.handlerTime"><span>处理时间:</span><span>{{warningGas.handlerTime}}</span></div>
+ </div>
+ <template #footer>
+ <span class="dialog-footer">
+ <el-button type="primary" @click="dialogWarning = false">
+ 确认
+ </el-button>
+ </span>
+ </template>
+ </el-dialog>
</div>
</template>
@@ -185,74 +229,89 @@
import "amfe-flexible";
import AMapLoader from '@amap/amap-jsapi-loader'
import { shallowRef } from '@vue/reactivity'
+import { storeToRefs } from 'pinia';
+import { useUserInfo } from '/@/stores/userInfo';
+import {bigScreenApi} from "/@/api/bigScreen";
// 定义接口来定义对象的类型
interface TableDataState {
+ socket: any
+ timer: any
+ heartbeat: any
+ heartbeatTimeOut: any
+ lockReconnect: boolean
+ maxReconnect: number
+ reconnectTime: number
time: string
date: string
weekDay: string
dayTime:string
isFull: boolean
- chart1Search: number | null
chart2Search: Array<string>
+ infoParams: {}
gasSearch: number | null
+ tlGasSearch: number | null
gasOptions: Array<gasType>
- searchParams: Object
+ gasData: Array<any>
+ gasTlData: Array<any>
areaOptions: Array<gasType>
+ gasTotal: null | number
+ tlTotal: null | number
+ online: number
+ warningGas: {},
+ dialogWarning: boolean
+ countTime: null | number
+ yellowNum: null | number
+ redNum: null | number
+ weatherData: Array<any>
}
interface gasType {
- label: string
- value: number | null
+ name: string
+ id: number | null
}
export default defineComponent({
name: 'bigScreen',
- components: { },
+ components: { },
props:{
isFull: Boolean
},
setup(props,context) {
+ const userInfo = useUserInfo();
+ const { userInfos } = storeToRefs(userInfo);
const state = reactive<TableDataState>({
+ yellowNum: null,
+ redNum: null,
+ socket: null,
+ timer: null,
+ heartbeat: null,
+ heartbeatTimeOut: null,
+ lockReconnect: false,
+ maxReconnect: 3, // 最大重连次数,-1代表无限重连
+ reconnectTime: 0, // 重连尝试次数
time: '',
date: '',
weekDay: '',
dayTime: '',
isFull: props.isFull,
- chart1Search: 1,
chart2Search: [],
- gasSearch: 1,
- gasOptions: [
- {
- label: '气体一',
- value: 1
- },
- {
- label: '气体二',
- value: 2
- },
- {
- label: '气体三',
- value: 3
- }
- ],
- searchParams:{
- gasSearch: 1,
- areaSearch: 1
+ infoParams:{
+ startTime: '',
+ endTime: ''
},
- areaOptions: [
- {
- label: '区域一',
- value: 1
- },
- {
- label: '区域二',
- value: 2
- },
- {
- label: '区域三',
- value: 3
- }
- ]
+ gasSearch: null,
+ tlGasSearch: null,
+ gasOptions: [],
+ gasData: [],
+ gasTlData: [],
+ areaOptions: [],
+ gasTotal: 0,
+ tlTotal: 0,
+ online: 3,
+ warningGas: {},
+ dialogWarning: false,
+ countTime: 1,
+ weatherData: []
});
const router = useRouter();
const gasN = ref("eChartgasN" + Date.now() + Math.random())
@@ -269,6 +328,12 @@
// 页面加载时
onMounted(() => {
+ getGasData()
+ getWarningNum()
+ getWarningInfo()
+ getWarning()
+ getUnusual()
+ getAreaData()
const baseSize = 38;
function setRem() {
const scale = document.documentElement.clientWidth / 1920;/* 当前页面宽度缩放比例,可根据自己需要修改 */
@@ -284,21 +349,418 @@
setInterval(() => {
getDateTime();
}, 1000);
- initgasN()
- initgasT()
initMap()
- });
+ })
+
+ onUnmounted(()=>{
+ destroyedWs()
+ })
+ const toNdPage = () =>{
+ router.push('/gasData')
+ }
+ const toTlPage = () =>{
+ router.push('/fluxData')
+ }
+ const getGasData = async ()=>{
+ const res = await bigScreenApi().getGas()
+ if(res.data.code == 100){
+ state.gasOptions = res.data.data
+ state.gasSearch = state.gasOptions[0].id
+ state.tlGasSearch = state.gasOptions[0].id
+ }else {
+ ElMessage({
+ type: 'warning',
+ message: res.data.msg
+ });
+ }
+ getGasSocket()
+ getGasTLSocket()
+ getGasNdData()
+ getGasTlData()
+ }
+
+ const getAreaData = async ()=>{
+ const res = await bigScreenApi().getAreas({pageSize: 99, pageIndex: 1, searchParams:{name: ''}})
+ if(res.data.code == 100){
+ state.areaOptions = res.data.data
+ // state.searchParams.areaSearch = state.areaOptions[0].id
+ }else {
+ ElMessage({
+ type: 'warning',
+ message: res.data.msg
+ });
+ }
+ }
+
+ const getWarningNum = async ()=>{
+ const res = await bigScreenApi().getWarningNum({countTime: state.countTime})
+ if(res.data.code == 100){
+ state.yellowNum = res.data.data?res.data.data.yellowWarnNum:0
+ state.redNum = res.data.data?res.data.data.redWarnNum:0
+ }else {
+ ElMessage({
+ type: 'warning',
+ message: res.data.msg
+ });
+ }
+ }
+
+ const getGasNdData = async ()=>{
+ const res = await bigScreenApi().getGasNdData({startTime: '',endTime: '',gasName: state.gasSearch})
+ if(res.data.code == 100){
+ if(res.data.data && res.data.data.length>0){
+ state.gasTotal = res.data.data.length
+ const timeList = res.data.data.map(i=>i.time.slice(11))
+ const dotList = res.data.data.map(i=>i.gasValue)
+ const weather = res.data.data.map((item)=>{
+ return {
+ time: item.time?item.time.slice(11):'--',
+ temp: item.temp?item.temp:'--',
+ humidity: item.humidity?item.humidity:'--',
+ windSpeed: item.windSpeed?item.windSpeed:'--',
+ windDirection: item.windDirection?item.windDirection:'--',
+ pressure: item.pressure?item.pressure:'--'
+ }
+ })
+ state.weatherData = [...weather].reverse().slice(0, 4);
+ initgasN(dotList.slice(dotList.length - 50),timeList.slice(timeList.length - 50))
+ }
+ }else {
+ ElMessage({
+ type: 'warning',
+ message: res.data.msg
+ });
+ }
+ }
+
+ const getGasTlData = async ()=>{
+ const res = await bigScreenApi().getGasTlData({startTime: '',endTime: '',gasName: state.tlGasSearch,areaId: null})
+ if(res.data.code == 100){
+ if(res.data.data && res.data.data.length>0){
+ state.tlTotal = res.data.data.length
+ const gasTime = res.data.data.map(i=>i.time?.slice(11))
+ const gasTlTime = [...new Set(gasTime)]
+ let areaData = state.areaOptions.map((item)=>{
+ return {
+ areaId: item.id,
+ name: item.name,
+ dotList: []
+ }
+ })
+ for(let i of gasTlTime){
+ const sameTimeData = res.data.data.filter(it=>it.time?.slice(11) == i)
+ for(let j of areaData){
+ const foundData = sameTimeData.find(k=>k.areaId == j.areaId)
+ if(foundData){
+ j.dotList.push(foundData.gasValue)
+ }else{
+ j.dotList.push(0)
+ }
+ }
+ }
+ const chartData = areaData.map((i)=>{
+ return {
+ name: i.name,
+ type: 'bar',
+ stack: 'total',
+ data: i.dotList.slice(i.dotList.length - 20)
+ }
+ })
+ initgasT(gasTlTime.slice(gasTlTime.length - 20),chartData)
+ }
+ }else {
+ ElMessage({
+ type: 'warning',
+ message: res.data.msg
+ });
+ }
+ }
+
+ const getWarningInfo = async ()=>{
+ const res = await bigScreenApi().getWarningInfo(state.infoParams)
+ if(res.data.code == 100){
+ if(res.data.data && res.data.data.length>0){
+ const newData = res.data.data.map((item)=>{
+ let i = []
+ if(item.gasThresholdName == '红色预警'){
+ i[0] = `<span style="color:red;">${item.gasThresholdName}</span>`
+ }else{
+ i[0] = item.gasThresholdName
+ }
+ i[1] = item.gasName
+ i[2] = item.gasConcentration
+ i[3] = item.warnTime
+ return i
+ })
+ config.data = newData
+ }
+ }else {
+ ElMessage({
+ type: 'warning',
+ message: res.data.msg
+ });
+ }
+ }
+ const timeChange = (value:Array<string>)=>{
+ state.infoParams.startTime = value[0]
+ state.infoParams.endTime = value[1]
+ getWarningInfo()
+ }
+
+ const changeGas1 = (value) =>{
+ getGasNdData()
+ getGasSocket()
+ }
+
+ const changeGas2 = (value)=>{
+ getGasTlData()
+ getGasTLSocket()
+ }
+
+ const changeTotal = () =>{
+ getWarningNum()
+ }
+
+ const getWarning = ()=>{
+ initWebSocket('/ws/gas/exc/','预警',60)
+ }
+
+ const getUnusual = ()=>{
+ initWebSocket('/ws/gas/device/exc/','异常',60)
+ }
+
+ const getGasSocket = ()=>{
+ initWebSocket('/ws/gas/','气体浓度',30)
+ }
+
+ const getGasTLSocket = ()=>{
+ initWebSocket('/ws/gas/flux/','气体通量',120)
+ }
+
+ const initWebSocket =async (requireUrl: string,type: string,beat: number)=>{
+ if (typeof WebSocket === 'undefined') {
+ alert('您的浏览器不支持socket');
+ } else {
+ // 实例化socket
+ let uid = userInfos.value.uid
+ let url = import.meta.env.VITE_API_URL + requireUrl + `${uid}`
+ url = url.replace('https', 'ws').replace('http', 'ws')
+ state.socket = new WebSocket(url)
+ // 监听socket连接
+ state.socket.onopen = () => {
+ console.log('socket连接成功')
+ startHeartbeat(beat)
+
+ }
+ // 监听socket错误信息
+ state.socket.onerror = () => {
+ console.log('socket连接错误')
+ console.log(state.socket,'soc')
+ // reconnect()
+ }
+ // 监听socket消息
+ state.socket.onmessage = (msg) => {
+ // if (msg.data === '连接成功') return
+ const text = msg.data
+ //收到服务器信息,心跳重置并发送
+ startHeartbeat(beat);
+ if (text.indexOf("连接成功") > 0) {
+ return;
+ }
+ if(type == '预警'){
+ console.log('预警')
+ const socketData = JSON.parse(text)
+ state.warningGas = JSON.parse(JSON.stringify(socketData))
+ state.dialogWarning = true
+ }
+ if(type == '异常'){
+ const socketData = JSON.parse(text)
+ const deviceStatus = JSON.parse(JSON.stringify(socketData))
+ if(deviceStatus.conState == 1){
+ if(deviceStatus.fluxState == 0){
+ if(deviceStatus.hardwareState.find(i=>i !== 0)){
+ state.online = 1
+ }else{
+ state.online = 2
+ }
+ }else{
+ if(deviceStatus.hardwareState.find(i=>i !== 0)){
+ state.online = 0
+ }else{
+ state.online = 1
+ }
+ }
+ }else{
+ if(deviceStatus.fluxState == 0){
+ if(deviceStatus.hardwareState.find(i=>i !== 0)){
+ state.online = 2
+ }else{
+ state.online = 3
+ }
+ }else{
+ if(deviceStatus.hardwareState.find(i=>i !== 0)){
+ state.online = 1
+ }else{
+ state.online = 2
+ }
+ }
+ }
+ }
+ if(type == '气体浓度'){
+ state.gasData = JSON.parse(text)
+ let gasNum = ''
+ let newArr = JSON.parse(JSON.stringify(state.gasData))
+ state.gasTotal = newArr.length
+ const weather = newArr.map((item)=>{
+ return {
+ time: item.dataReceivingTime?item.dataReceivingTime.slice(11,19):'--',
+ temp: item.temp?item.temp:'--',
+ humidity: item.humidity?item.humidity:'--',
+ windSpeed: item.windSpeed?item.windSpeed:'--',
+ windDirection: item.windDirection?item.windDirection:'--',
+ pressure: item.pressure?item.pressure:'--'
+ }
+ })
+ state.weatherData = [...weather].reverse().slice(0, 4);
+ for(let key in newArr[0]){
+ if(newArr[0][key] == state.gasSearch && key.indexOf("gasName") !== -1){
+ gasNum = key.substring(7)
+ }
+ }
+ const dotList = newArr.map((item)=>{
+ for(let key in item){
+ if(key.indexOf("gasValue") !== -1 && key.substring(8) == gasNum){
+ return item[key]
+ }
+ }
+ })
+ const gasTime = state.gasData.map(i=>i.dataReceivingTime?.slice(11,19))
+ initgasN(dotList.slice(dotList.length - 50),gasTime.slice(gasTime.length - 50))
+ }
+
+ if(type == '气体通量'){
+ state.gasTlData = JSON.parse(text)
+ let newArr = JSON.parse(JSON.stringify(state.gasTlData))
+ state.tlTotal = newArr.length
+ const gasTime = newArr.map(i=>i.dataReceivingTime?.slice(11,19))
+ const gasTlTime = [...new Set(gasTime)]
+ let areaData = state.areaOptions.map((item)=>{
+ return {
+ areaId: item.id,
+ name: item.name,
+ dotList: []
+ }
+ })
+ for(let i of gasTlTime){
+ const sameTimeData = newArr.filter(it=>it.dataReceivingTime?.slice(11,19) == i)
+ for(let j of areaData){
+ const foundData = sameTimeData.find(k=>k.areaId == j.areaId)
+ if(foundData){
+ let gasNum = ''
+ for(let key in sameTimeData[0]){
+ if(sameTimeData[0][key] == state.tlGasSearch && key.indexOf("gasName") !== -1){
+ gasNum = key.substring(7)
+ }
+ }
+ for(let key in foundData){
+ if(key.indexOf("gasValue") !== -1 && key.substring(8) == gasNum){
+ j.dotList.push(foundData[key])
+ }
+ }
+ }else{
+ j.dotList.push(0)
+ }
+ }
+ }
+ const chartData = areaData.map((i)=>{
+ return {
+ name: i.name,
+ type: 'bar',
+ stack: 'total',
+ data: i.dotList.slice(i.dotList.length - 20)
+ }
+ })
+ initgasT(gasTlTime.slice(gasTlTime.length - 20),chartData)
+ }
+
+ }
+ state.socket.onclose=()=>{
+ console.log("socket已经关闭")
+ }
+ }
+ }
+ const reconnect = (beat)=> {
+ if (state.socket.readyState === 1) {
+ // 如果状态等于1代表 websocket连接正常
+ return;
+ }
+ if (state.lockReconnect || (state.maxReconnect !== -1 && state.reconnectTime >= state.maxReconnect)) {
+ return;
+ }
+
+ // 让重连锁变为true,阻止进入下一个循环
+ state.lockReconnect = true;
+ setTimeout(() => {
+ state.reconnectTime++;
+ console.log("尝试重连");
+ // 建立新连接
+ // initWebSocket();
+ getGasSocket()
+ state.lockReconnect = false;
+ }, beat * 1000);
+ }
+
+ const startHeartbeat = (beat)=> {
+ const webSocket = state.socket;
+ // 清空定时器
+ clearTimeout(state.heartbeat);
+ state.heartbeat = null;
+ clearTimeout(state.heartbeatTimeOut);
+ state.heartbeatTimeOut = null;
+ // 延时发送下一次心跳
+ // console.log("心跳开启");
+ state.heartbeat = setTimeout(() => {
+ // 如果连接正常
+ // console.log("连接状态", webSocket.readyState);
+ if (webSocket.readyState === 1) {
+ //这里发送一个心跳,后端收到后,返回一个心跳消息,
+ let params = JSON.stringify({
+ type: "ping",
+ toUserId: userInfos.value.uid,
+ });
+ webSocket.send(params);
+ // 心跳发送后,如果服务器超时未响应则断开,如果响应了会被重置心跳定时器
+ state.heartbeatTimeOut = setTimeout(() => {
+ webSocket.close();
+ // 响应超时时间
+ }, beat * 1000);
+ } else {
+ // 否则重连
+ reconnect(beat);
+ }
+ // 心跳间隔时间是30s
+ }, beat * 1000);
+ }
+
+ const destroyedWs=()=> {
+ console.log("ws销毁");
+ // 关闭使用close方法关闭socket
+ if (state.socket) {
+ state.socket.close();
+ }
+ state.socket = null;
+ // 清除定时器
+ state.timer = null;
+ clearInterval(state.timer);
+ clearTimeout(state.heartbeat);
+ state.heartbeat = null;
+ clearTimeout(state.heartbeatTimeOut);
+ state.heartbeatTimeOut = null;
+ }
const config = reactive({
header: ['预警级别','气体名称', '气体浓度', '时间'],
- data: [
- ['红色预警', '甲烷', '19', '2023-08-10'],
- ['<span style="color:red;">红色预警</span>', '甲烷', '19', '2023-08-10'],
- ['红色预警', '甲烷', '19', '2023-08-10'],
- ['红色预警', '甲烷', '19', '2023-08-10'],
- ['红色预警', '甲烷', '19', '2023-08-10'],
- ['红色预警', '甲烷', '19', '2023-08-10']
- ],
+ data: [],
index: true,
columnWidth: [38],
align: ['center','center','center','center','center'],
@@ -307,17 +769,15 @@
evenRowBGC: ''
})
- const bigConfig = reactive({
- header: ['时间','温度', '湿度', '风速', '风向', '气压'],
- data: [
- ['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20'],['2023-08-10 13:29:25','56', '105', '40', '32', '20']
- ],
- align: ['center','center','center','center','center','center'],
- headerBGC: '',
- oddRowBGC: '',
- evenRowBGC: '',
- rowNum: 3
- })
+ // const bigConfig = reactive({
+ // header: ['时间','温度', '湿度', '风速', '风向', '气压'],
+ // data: [],
+ // align: ['center','center','center','center','center','center'],
+ // headerBGC: '',
+ // oddRowBGC: '',
+ // evenRowBGC: '',
+ // rowNum: 3
+ // })
const mouseoverHandler = (e: any) => {
console.log(e)
@@ -328,16 +788,22 @@
}
type EChartsOption = echarts.EChartsOption
- const initgasN =()=>{
+ const initgasN =(data:Array<string>,time: Array<string>)=>{
let dom = document.getElementById(gasN.value);
let myChart = echarts.init(dom);
let option: EChartsOption;
option = {
+ tooltip: {
+ trigger: 'axis',
+ },
xAxis: {
type: 'category',
- data: ['10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30'],
+ data: time,
axisLabel: {
color: '#fff'
+ },
+ splitLine: {
+ show: false
}
},
yAxis: {
@@ -354,37 +820,24 @@
grid: {
top: '5%',
bottom: '10%',
- right: '0%'
+ right: '2%'
},
series: [
{
- data: [150, 230, 224, 218, 135, 147, 230, 224, 218, 135, 147, 260],
+ data: data,
type: 'line',
- // label:{
- // show: true,
- // color: '#fff',
- // textBorderColor: 'transparent'
- // },
+ label:{
+ show: true,
+ color: '#fff',
+ textBorderColor: 'transparent',
+ fontSize: 8
+ },
+ // showSymbol: false,
lineStyle:{
color: '#54d5ff'
},
itemStyle:{
color: '#54d5ff',
- },
- areaStyle:{
- color: {
- type: 'linear',
- x: 0,
- y: 0,
- x2: 0,
- y2: 1,
- colorStops: [{
- offset: 0, color: '#2af' // 0% 处的颜色
- }, {
- offset: 1, color: 'rgba(255,255,255,.1)' // 100% 处的颜色
- }],
- global: false // 缺省为 false
- }
}
}
]
@@ -395,7 +848,7 @@
myChart.resize();
});
}
- const initgasT =()=>{
+ const initgasT =(time: Array<string>,data: Array<any>)=>{
let dom = document.getElementById(gasT.value);
let myChart = echarts.init(dom);
let option: EChartsOption;
@@ -419,7 +872,7 @@
},
xAxis: {
type: 'category',
- data: ['10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30', '10:36:30'],
+ data: time,
axisLabel: {
color: '#fff'
}
@@ -434,28 +887,7 @@
color: '#ccc'
}
},
- series: [
- {
- name: '2011',
- type: 'bar',
- data: [18, 23, 29, 10, 13, 6],
- label:{
- show: true,
- color: '#fff',
- textBorderColor: 'transparent'
- }
- },
- {
- name: '2012',
- type: 'bar',
- data: [19, 23, 31, 12, 13, 6],
- label:{
- show: true,
- color: '#fff',
- textBorderColor: 'transparent'
- }
- }
- ]
+ series: data
}
option && myChart.setOption(option);
@@ -482,10 +914,10 @@
mapStyle: 'amap://styles/normal',
zoom: 18,
center: [85.057805, 45.62550],
- // layers:[
- // new AMap.TileLayer.RoadNet({}),
- // new AMap.TileLayer.Satellite()
- // ],
+ layers:[
+ // new AMap.TileLayer.RoadNet({}),
+ // new AMap.TileLayer.Satellite()
+ ],
zooms:[2,20],
})
@@ -585,12 +1017,17 @@
return {
timeForm,
config,
- bigConfig,
gasN,
gasT,
map,
+ toNdPage,
+ toTlPage,
+ timeChange,
mouseoverHandler,
+ changeTotal,
clickHandler,
+ changeGas1,
+ changeGas2,
toFull,
back,
...toRefs(state)
@@ -598,6 +1035,40 @@
}
});
</script>
+<style lang="scss">
+.warningMsg{
+ background: rgba(4,18,67,.8);
+ border: 1px solid #00FFFF;
+ border-radius: 8px;
+
+ .el-dialog__title{
+ color: #fff;
+ }
+
+ .warning-cont{
+ width: 100%;
+ &>div{
+ width: 100%;
+ display: flex;
+ align-items: center;
+ color: #fff;
+ margin-bottom: 10px;
+ span{
+ &:first-of-type{
+ text-align: right;
+ }
+ &:last-of-type{
+ margin-left: 10px;
+ color: #11feee;
+ }
+ }
+ .red{
+ color: red;
+ }
+ }
+ }
+}
+</style>
<style lang="scss" scoped>
.charts-container{
width: 100%;
@@ -711,7 +1182,7 @@
}
.el-select{
width: 60%;
- height: 20px;
+ height: 24px;
}
::v-deep(.el-popper){
background-color: rgba(10,31,92,1);
@@ -737,6 +1208,38 @@
.sys-status{
width: 66%;
+ height: 100%;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 16px;
+ line-height: 40px;
+ .onlineIcon{
+ width: 18px;
+ height: 18px;
+ color: #11feee;
+ }
+ .offlineIcon{
+ width: 18px;
+ height: 18px;
+ color: red;
+ }
+ div{
+ color: #fff;
+ margin-left: 2px;
+ .online{
+ color: #11feee;
+ margin-left: 10px;
+ }
+ .offline{
+ color: red;
+ margin-left: 10px;
+ }
+ }
+ }
+
+ .sys-offstatus{
+ width: 66%;
height: 70%;
display: flex;
align-items: center;
@@ -746,7 +1249,7 @@
color: #fff;
margin-left: 2px;
span{
- color: #11feee;
+ color: red;
margin-left: 10px;
font-size: 14px;
}
@@ -754,7 +1257,7 @@
}
.el-radio-group{
- height: 90%;
+ height: 24px;
width: 66%;
flex-flow: row nowrap;
display: flex;
@@ -792,16 +1295,17 @@
}
:deep(.el-date-editor){
width: 66%;
- height: 20px;
+ height: 24px;
.el-range-separator{
color: #fff;
}
}
:deep(.el-input__wrapper){
+ height: 24px;
box-shadow: none;
border: 1px solid #11FEEE;
- background: #005dd6;
+ background: rgba(0,0,0,0);
color: #fff;
input{
@@ -816,9 +1320,26 @@
.searchGroup{
width: 60%;
- height: 20px;
+ height: 24px;
display: flex;
align-items: center;
+ justify-content: right;
+ padding-right: 4px;
+ .checkMore{
+ width: 22px;
+ height: 22px;
+ cursor: pointer;
+ margin-left: 10px;
+ line-height: 24px;
+ font-size: 14px;
+ border-radius: 50%;
+ border: 1px solid #11FEEE;
+ color: #11FEEE;
+ text-align: center;
+ &:hover{
+ background-color: rgba(10,31,92,1);
+ }
+ }
}
}
.chart-cont{
@@ -925,7 +1446,7 @@
flex-direction: column;
align-items: center;
justify-content: center;
- padding: 5px 10px;
+ padding: 0 10px 5px 15px;
.bigPic{
width: 100%;
height: 50px;
@@ -959,12 +1480,41 @@
background-size: 90% 90%;
}
}
+ .weather{
+ width: 100%;
+ height: calc(100% - 60px);
+ background: url("../../../assets/warningScreen/scroll-bg.png") no-repeat bottom;
+ background-size: 100% 82%;
+
+ tr{
+ width: 100%;
+ height: 20%;
+ display: flex;
+ align-items: center;
+ justify-content: space-around;
+ td{
+ width: calc(100% / 6);
+ text-align: center;
+ box-sizing: border-box;
+ font-size: 12px;
+ }
+ }
+ .weatherTit{
+ color: #11feee;
+ }
+ .weatherRow{
+ color: #fff;
+ }
+ }
+
+
:deep(.dv-scroll-board){
width: 100%;
height: calc(100% - 60px);
.header{
color: #11feee;
+ text-align: center;
}
.rows{
background: url("../../../assets/warningScreen/scroll-bg.png") no-repeat center;
diff --git a/src/views/bigScreen/index.vue b/src/views/bigScreen/index.vue
index 375be53..e41e39d 100644
--- a/src/views/bigScreen/index.vue
+++ b/src/views/bigScreen/index.vue
@@ -10,6 +10,7 @@
import screenfull from 'screenfull'
import { ElMessage, ElMessageBox } from 'element-plus';
+
// 定义接口来定义对象的类型
interface TableDataState {
isScreenfull: boolean
--
Gitblit v1.9.2