This commit is contained in:
2023-12-28 16:16:25 +08:00
parent 0bb434bc22
commit 41e1f46cfc
28 changed files with 704 additions and 157 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 492 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

View File

@@ -11,12 +11,12 @@
<i
class=""
style="display: inline-block; margin-left: 12px; padding-top: 4px">
<img :src="imgSrc" width="18" height="16" alt="" />
<img :src="imgSrc" width="20" height="20" alt="" />
</i>
<span
style="
color: #fff;
font-size: 20px;
font-size: 24px;
line-height: 2;
margin-left: 6px;
display: inline-block;
@@ -48,11 +48,11 @@ export default {
case '风机运行频率':
return require('../assets/flow.png');
case 'ISRA缺陷检测':
return require('../assets/gas.png');
return require('../assets/check.png');
case '能耗':
return require('../assets/gas.png');
return require('../assets/energeCost.png');
case '窑炉信息':
return require('../assets/gas.png');
return require('../assets/msg.png');
case '烟气处理':
return require('../assets/gas.png');
}

View File

@@ -11,9 +11,11 @@
<script>
import * as echarts from 'echarts';
import resize from './../mixins/resize'
export default {
name: 'GasChart',
mixins: [resize],
components: {},
props: {},
data() {
@@ -110,7 +112,6 @@ export default {
},
};
},
inject: ['resizeChart'],
computed: {
sidebarStatus() {
return this.$store.state.app.sidebar.opened;
@@ -126,10 +127,6 @@ export default {
this.chart.setOption(this.option);
}, 500);
},
// resizeChart(val) {
// console.log('resizeChart', val);
// val && this.chart && this.chart.resize();
// },
},
mounted() {
this.$el.addEventListener('resize', () => {

View File

@@ -7,69 +7,93 @@
<template>
<header class="kiln-header">
<h1
style="
font-size: 32px;
margin-bottom: 36px;
color: #0ee8e4;
letter-spacing: 5px;
">
<h1>
窑炉生产运行驾驶舱
</h1>
<!-- left: 312px; -->
<div
class="firm"
style="
position: absolute;
bottom: 24px;
left: 16.5vw;
color: #fff;
font-size: 16px;
letter-spacing: 1px;
">
class="firm">
单位: 河南汇融科技服务有限公司
</div>
<div
class="datetime"
style="
position: absolute;
bottom: 18px;
right: 15.5vw;
color: #fff;
font-size: 16px;
letter-spacing: 1px;
display: flex;
align-items: center;
gap: 16px;
">
<DateBtnGroup />
class="datetime">
<!-- <DateBtnGroup /> -->
{{ new Date().toLocaleString() }}
</div>
<el-button
type="text"
class="screen-btn"
@click="changeFullScreen"
>
<svg-icon v-if="isFullScreen" icon-class="unFullScreenView" />
<svg-icon v-else icon-class="fullScreenView" />
</el-button>
</header>
</template>
<script>
import DateBtnGroup from './DateBtnGroup.vue';
// import DateBtnGroup from './DateBtnGroup.vue';
export default {
name: 'KilnHeader',
components: { DateBtnGroup },
props: {},
// components: { DateBtnGroup },
props: {
isFullScreen:false
},
data() {
return {};
return {
};
},
computed: {},
methods: {},
methods: {
changeFullScreen() {
this.$emit('screenfullChange')
}
},
};
</script>
<style scoped lang="scss">
.kiln-header {
background: url('../assets/head.png') no-repeat;
height: 88px;
height: 96px;
background-size: 100%;
background-position: 0 0;
display: grid;
place-content: center;
position: relative;
h1{
font-size: 32px;
margin-bottom: 36px;
color: #0ee8e4;
letter-spacing: 8px;
}
.firm{
position: absolute;
top: 45px;
left: 325px;
color: #fff;
font-size: 20px;
letter-spacing: 1px;
}
.datetime {
position: absolute;
top: 45px;
right: 240px;
color: #fff;
font-size: 20px;
letter-spacing: 1px;
display: flex;
align-items: center;
gap: 16px;
}
.screen-btn{
color: #00fff0;
font-size: 32px;
position: absolute;
right: 32px;
top:28px
}
}
</style>

View File

@@ -11,9 +11,11 @@
<script>
import * as echarts from 'echarts';
import resize from './../mixins/resize'
export default {
name: 'ISRAChart',
mixins: [resize],
components: {},
props: {},
data() {
@@ -24,6 +26,14 @@ export default {
tooltip: {
trigger: 'item',
},
legend: {
bottom: '3%',
left: 'center',
icon: 'circle',
textStyle: {
color: '#fff'
}
},
title: {
text: 11234,
subtext: '总数',
@@ -44,7 +54,7 @@ export default {
{
name: 'Access From',
type: 'pie',
radius: ['60%', '85%'],
radius: ['45%', '65%'],
avoidLabelOverlap: true,
label: {
show: true,
@@ -60,25 +70,25 @@ export default {
rich: {
a: {
color: '#2760ff',
fontSize: 18,
fontSize: 24,
borderWidth: 0,
textBorderWidth: 0,
},
b: {
color: '#518eec',
fontSize: 18,
fontSize: 24,
borderWidth: 0,
textBorderWidth: 0,
},
c: {
color: '#0ee8e4',
fontSize: 18,
fontSize: 24,
borderWidth: 0,
textBorderWidth: 0,
},
d: {
color: '#ddb523',
fontSize: 18,
fontSize: 24,
borderWidth: 0,
textBorderWidth: 0,
},

View File

@@ -36,7 +36,7 @@ export default {
.switcher {
:deep(.el-switch__core) {
border: none;
background-color: #213d566b;
background-color:rgba(3, 35, 60, 1);
&::after {
background-color: #02457e;
@@ -46,7 +46,7 @@ export default {
:deep(.is-checked) {
.el-switch__core {
border: none;
background-color: #b4fffc;
background-color: rgba(180, 255, 252, 0.71);
&::after {
background-color: #08d8cd;

View File

@@ -12,13 +12,13 @@
<div class="" style="flex: 2; padding: 8px">
<div
class="header-line"
style="margin-bottom: 8px; display: flex; align-items: center">
style="margin: 8px 0 16px; display: flex; align-items: center">
<h2 class="" style="margin: 0; color: #0ee8fe; margin-right: 12px">
烟气趋势图
能耗趋势图
</h2>
<Switcher />
<!-- <Switcher /> -->
<div>
<span class="lgd lgd-total">总量</span>
<!-- <span class="lgd lgd-total">总量</span> -->
<!-- <span class="lgd lgd-day">白班</span>
<span class="lgd lgd-night">夜班</span> -->
</div>
@@ -31,10 +31,10 @@
justify-content: space-between;
">
<SelectorBtnGroup
:options="['氧气含量', '二氧化硫', '一氧化氢', '二氧化氢']" />
<SelectorBtnGroup :options="['日', '周', '月', '年']" />
:options="['电耗能', '天然气I', '天然气II']" />
<SelectorBtnGroup :options="['周', '月', '年']" />
</div>
<div class="chart" style="height: 150px; margin-top: 8px;">
<div class="chart" style="height: 200px; margin-top: 8px;">
<GasChart />
</div>
</div>
@@ -45,8 +45,8 @@
import Container from '../components/Container.vue';
import ShadowRect from '../components/ShadowRect.vue';
import SplitLine from '../components/line';
import Switcher from '../components/Switcher.vue';
import EnergeTop from './EnergeTop.vue';
import Switcher from '../components/Switcher';
import EnergeTop from './EnergeTop';
import GasChart from '../components/GasChart.vue';
import SelectorBtnGroup from '../components/SelectorBtnGroup.vue';
export default {

View File

@@ -15,6 +15,7 @@
grid-template-rows: auto;
gap: 8px;
padding: 4px;
margin-bottom: 6px;
">
<ShadowRect
style="grid-row: 1 / 3; flex-direction: column; justify-content: center">

View File

@@ -7,7 +7,7 @@
<template>
<Container name="风机运行频率" size="middle" style="">
<div class="" style="position: absolute; top: 18px; left: 180px">
<div class="" style="position: absolute; top: 26px; left: 220px">
<Switcher />
</div>
<div
@@ -17,22 +17,22 @@
display: grid;
grid-template-columns: repeat(2, 1fr);
grid-auto-rows: auto;
gap: 8px;
gap: 10px;
">
<ShadowRect v-for="n in 14" :key="n" :rounded="false">
<ShadowRect v-for="(value, key, i) in fanFrequencyInfo" :key="i" :rounded="false">
<span
style="
font-size: 16px;
line-height: 1.24;
flex: 1.2;
font-size: 18px;
line-height: 1.1;
flex: 3.5;
text-align: right;
padding-right: 8px;
letter-spacing: 1px;
">
{{ n }}#风机
{{ key }}:
</span>
<span style="font-size: 16px; line-height: 1.24; flex: 1">
{{ Math.floor(Math.random() * 100) }}Hz
<span style="font-size: 20px; line-height: 1; flex: 1">
{{ value }}Hz
</span>
</ShadowRect>
</div>
@@ -42,16 +42,24 @@
<script>
import Container from '../components/Container.vue';
import ShadowRect from '../components/ShadowRect.vue';
import Switcher from '../components/Switcher.vue';
import Switcher from '../components/Switcher';
export default {
name: 'FanSequence',
components: { Container, ShadowRect, Switcher },
computed: {
fanFrequencyInfo() {
return this.$store.state.websocket.fanFrequencyInfo
}
},
props: {},
data() {
return {};
},
computed: {},
methods: {},
mounted() {
},
methods: {
}
};
</script>

View File

@@ -21,7 +21,7 @@
<ShadowRect>
<span
style="
font-size: 16px;
font-size: 20px;
line-height: 1.24;
flex: 1.2;
text-align: right;
@@ -30,12 +30,12 @@
">
氧气含量
</span>
<span style="font-size: 16px; line-height: 1.24; flex: 1">82%</span>
<span style="font-size: 20px; line-height: 1.24; flex: 1">82%</span>
</ShadowRect>
<ShadowRect>
<div
style="
font-size: 16px;
font-size: 20px;
line-height: 1.5;
flex: 1.2;
text-align: right;
@@ -45,13 +45,13 @@
<p style="margin: 0; line-height: inherit">一氧化氮</p>
<p style="margin: 0; line-height: inherit">排放浓度</p>
</div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">82%</span>
<span style="font-size: 20px; line-height: 1.24; flex: 1">82%</span>
</ShadowRect>
<ShadowRect>
<div
style="
font-size: 16px;
font-size: 20px;
line-height: 1.5;
flex: 1.2;
text-align: right;
@@ -61,13 +61,13 @@
<p style="margin: 0; line-height: inherit">二氧化硫</p>
<p style="margin: 0; line-height: inherit">排放浓度</p>
</div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">82%</span>
<span style="font-size: 20px; line-height: 1.24; flex: 1">59mg/</span>
</ShadowRect>
<ShadowRect>
<div
style="
font-size: 16px;
font-size: 20px;
line-height: 1.5;
flex: 1.2;
text-align: right;
@@ -77,22 +77,22 @@
<p style="margin: 0; line-height: inherit">二氧化氮</p>
<p style="margin: 0; line-height: inherit">排放浓度</p>
</div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">82%</span>
<span style="font-size: 20px; line-height: 1.24; flex: 1">82%</span>
</ShadowRect>
</div>
<KilnLine :horizontal="true" />
<div class="" style="flex: 2; padding: 8px">
<div
class="header-line"
style="margin-bottom: 8px; display: flex; align-items: center">
<h2 class="" style="margin: 0; color: #0ee8fe; margin-right: 12px">
style="margin-bottom: 10px; display: flex; align-items: center">
<h2 class="" style="margin: 5px 0; color: #0ee8fe; margin-right: 12px">
烟气趋势图
</h2>
<Switcher />
<!-- <Switcher /> -->
<div>
<span class="lgd lgd-total">总量</span>
<span class="lgd lgd-day">白班</span>
<span class="lgd lgd-night">夜班</span>
<!-- <span class="lgd lgd-total">总量</span> -->
<!-- <span class="lgd lgd-day">白班</span>
<span class="lgd lgd-night">夜班</span> -->
</div>
</div>
<div
@@ -103,10 +103,10 @@
justify-content: space-between;
">
<SelectorBtnGroup
:options="['氧气含量', '二氧化硫', '一氧化', '二氧化']" />
:options="['氧气含量', '二氧化硫', '一氧化', '二氧化']" />
<SelectorBtnGroup :options="['日', '周', '月', '年']" />
</div>
<div class="chart" style="height: 220px">
<div class="chart" style="height: 250px;margin-top: 10px;">
<GasChart />
</div>
</div>
@@ -118,7 +118,7 @@
import Container from '../components/Container.vue';
import ShadowRect from '../components/ShadowRect.vue';
import KilnLine from '../components/line';
import Switcher from '../components/Switcher.vue';
import Switcher from '../components/Switcher';
import SelectorBtnGroup from '../components/SelectorBtnGroup.vue';
import GasChart from '../components/GasChart.vue';

View File

@@ -7,9 +7,10 @@
<template>
<Container name="ISRA缺陷检测" size="middle" style="">
<div style="padding: 12px; display: flex; flex-direction: column; gap: 8px; height: 100%;">
<ISRAChart />
<!-- <div style="padding: 12px; display: flex; flex-direction: column; gap: 8px; height: 100%;">
<div class="f" style="flex: 9;">
<ISRAChart />
</div>
<ul
class="legend"
@@ -27,7 +28,7 @@
<li class="fault-3">缺陷3</li>
<li class="fault-4">缺陷4</li>
</ul>
</div>
</div> -->
</Container>
</template>

View File

@@ -17,22 +17,37 @@
grid-auto-rows: auto;
gap: 8px;
">
<ShadowRect v-for="info in kilnInfo" :key="info.name" :rounded="false">
<span
style="
font-size: 16px;
line-height: 1.45;
flex: 1.2;
text-align: right;
padding-right: 8px;
letter-spacing: 1px;
">
{{ info.name }}
</span>
<span style="font-size: 16px; line-height: 1.45; flex: 1">
{{ info.value }}
<!-- {{ Math.floor(Math.random() * 100) }}Hz -->
</span>
<ShadowRect :rounded="false">
<span class="kiln-info-item">窑炉压力:</span>
<span style="font-size: 20px; line-height: 1.7; flex: 1">{{ kilnInfoMsg?.kilnPressure }}</span>
</ShadowRect>
<ShadowRect :rounded="false">
<span class="kiln-info-item">循环水温度:</span>
<span style="font-size: 20px; line-height: 1.7; flex: 1">{{ kilnInfoMsg?.waterTemp }}</span>
</ShadowRect>
<ShadowRect :rounded="false">
<span class="kiln-info-item">循环水流量:</span>
<span style="font-size: 20px; line-height: 1.7; flex: 1">{{ kilnInfoMsg?.waterFlow }}</span>
</ShadowRect>
<ShadowRect :rounded="false">
<span class="kiln-info-item">循环水压力:</span>
<span style="font-size: 20px; line-height: 1.7; flex: 1">{{ kilnInfoMsg?.waterPressure }}</span>
</ShadowRect>
<ShadowRect :rounded="false">
<span class="kiln-info-item">助燃风压力:</span>
<span style="font-size: 20px; line-height: 1.7; flex: 1">{{ kilnInfoMsg?.combustionAirPressure }}</span>
</ShadowRect>
<ShadowRect :rounded="false">
<span class="kiln-info-item">碹顶加权温度:</span>
<span style="font-size: 20px; line-height: 1.7; flex: 1">{{ kilnInfoMsg?.topTemp }}</span>
</ShadowRect>
<ShadowRect :rounded="false">
<span class="kiln-info-item">压缩气压力:</span>
<span style="font-size: 20px; line-height: 1.7; flex: 1">{{ kilnInfoMsg?.compressedAirPressure }}</span>
</ShadowRect>
<ShadowRect :rounded="false">
<span class="kiln-info-item">熔化加权温度:</span>
<span style="font-size: 20px; line-height: 1.7; flex: 1">{{ kilnInfoMsg?.meltTemp }}</span>
</ShadowRect>
</div>
</Container>
@@ -48,24 +63,26 @@ export default {
props: {},
data() {
return {
kilnInfo: [
{ name: '窑炉压力', value: '83Kpa' },
{ name: '循环水温度', value: '53℃' },
{ name: '循环水流量', value: '23m³/h' },
{ name: '循环水压力', value: '33Kpa' },
{ name: '助燃风压力', value: '12Kpa' },
{ name: '碹顶加权温度', value: '32℃' },
{ name: '压缩气压力', value: '83Kpa' },
{ name: '融化加权温度', value: '123℃' },
],
};
},
computed: {},
computed: {
kilnInfoMsg() {
return this.$store.state.websocket.kilnInfo
}
},
methods: {},
};
</script>
<style scoped lang="scss">
.kiln-info {
.kiln-info-item {
font-size: 20px;
line-height: 1.7;
flex: 1.5;
text-align: right;
padding-right: 8px;
letter-spacing: 1px;
}
}
</style>

View File

@@ -12,7 +12,7 @@
display: grid;
gap: 16px;
grid-template-columns: 1fr 1fr;
grid-template-rows: 1fr 1fr;
grid-template-rows: 462px 462px;
">
<MaterialCost />
<IsraCheck />

View File

@@ -21,7 +21,7 @@
class="material"
style="
flex: 1;
padding: 6px;
padding: 12px 6px 20px;
display: flex;
flex-direction: column;
gap: 4px;
@@ -31,7 +31,7 @@
<span style="color: #0ee8e4; font-weight: 500; font-size: 32px">
234
</span>
<span style="color: #fff; font-size: 14px; letter-spacing: 1px">
<span style="color: #fff; font-size: 16px; letter-spacing: 1px">
- 原料1/ -
</span>
</div>

View File

@@ -8,7 +8,11 @@
<template>
<div
class="right-two"
style="display: flex; gap: 16px; flex-direction: column">
style="
display: grid;
gap: 16px;
grid-template-rows: 320px 605px;
">
<KilnInfo />
<GasHandle />
</div>
@@ -18,7 +22,7 @@
import Container from '../components/Container.vue';
import ShadowRect from '../components/ShadowRect.vue';
import KilnLine from '../components/line';
import Switcher from '../components/Switcher.vue';
import Switcher from '../components/Switcher';
import SelectorBtnGroup from '../components/SelectorBtnGroup.vue';
import KilnInfo from './KilnInfo.vue';
import GasHandle from './GasHandle.vue';

View File

@@ -6,36 +6,46 @@
-->
<template>
<div
class="KilnDataBoard"
style="
position: absolute;
top: -8px;
left: -16px;
width: calc(100% + 28px);
height: calc(100% + 38px);
display: flex;
flex-direction: column;
gap: 16px;
">
<KHeader />
<div id='kilnContainer' style="width: 100%;height: 100%;">
<div
class="main-body"
style="flex: 1; display: flex; gap: 16px; padding: 8px 16px">
<div class="left-side" style="flex: 2">
<LeftFour />
</div>
<div class="right-side" style="flex: 1">
<RightTwo />
id='kilnContainerB'
ref='kilnContainer'
class="KilnDataBoard"
style="
position: absolute;
transform-origin: 16px 8px;
font-size: 16px;
top: -8px;
left: -16px;
width: 1920px;
height: 1080px;
display: flex;
flex-direction: column;
gap: 24px;
"
:style="{transform:'scale('+scaleNum+')'}">
<KHeader :isFullScreen='isFullScreen' @screenfullChange='screenfullChange'/>
<div
class="main-body"
style="flex: 1; display: flex; gap: 20px; padding: 0px 16px">
<div class="left-side" style="flex: 2">
<LeftFour />
</div>
<div class="right-side" style="flex: 1">
<RightTwo />
</div>
</div>
</div>
</div>
</template>
<script>
import KHeader from '../components/Header.vue';
import LeftFour from './LeftFour.vue';
import KHeader from '../components/Header';
import LeftFour from './LeftFour';
import RightTwo from './RightTwo.vue';
import screenfull from 'screenfull'
import { debounce } from '@/utils/debounce'
import { getDcsMsg } from './../utils/dcs'
export default {
name: 'KilnDataBoard',
@@ -49,15 +59,110 @@ export default {
// resizeChart: null,
// };
// },
mounted() {
// this.$el.addEventListener('resize', () => {
// console.log('resizzzze...')
// this.resizeChart = Math.random();
// });
},
data() {
return {};
return {
isFullScreen: false,
scaleNum: 0.8
};
},
created() {
this.init()
},
destroy() {
this.destroy()
},
mounted() {
this.boxReset = debounce(() => {
this.resetSize()
}, 300)
this.boxReset()
window.addEventListener('resize', () => {
this.boxReset()
})
// this.getMes()
// closeWebsocket()
getDcsMsg()
console.log('mounted...........')
},
destroyed() {
console.log('destroyed...........')
},
methods: {
change() {
this.isFullScreen = screenfull.isFullscreen
},
init() {
if (screenfull.isEnabled) {
screenfull.on('change', this.change)
}
},
destroy() {
if (screenfull.isEnabled) {
screenfull.off('change', this.change)
}
},
// 全屏
screenfullChange() {
if (!screenfull.isEnabled) {
this.$message({
message: 'you browser can not work',
type: 'warning'
})
return false
}
screenfull.toggle(this.$refs.kilnContainer)
console.log('11111')
// this.resetSize()
console.log('2222')
},
resetSize() {
let kilnContainerBox = document.querySelector('#kilnContainerB')
let rw = parseFloat(window.innerWidth)
let rh = parseFloat(window.innerHeight)
let bw = parseFloat(kilnContainerBox.style.width)
let bh = parseFloat(kilnContainerBox.style.height)
let wx = 0
let hx = 0
if (screenfull.isFullscreen) {
console.log('全屏')
wx = rw / bw
hx = rh / bh
console.log(this.scaleNum)
}else{
console.log('非全屏')
console.log(this.$store.state.app.sidebar.opened)
if (this.$store.state.app.sidebar.opened) {
wx = (rw-264) / bw
hx = (rh-116) / bh
}else{
wx = (rw-78) / bw
hx = (rh-116) / bh
}
}
this.scaleNum = wx
},
// 获取ws
getMes() {
const userId = 'dcsmsg' + new Date().getTime()
connectWebsocket(
// 测试地址
'ws://10.70.180.10:8081/xc-screen/websocket/'+userId,
// 传递给后台的数据
'',
// 成功拿到后台返回的数据的回调函数
(data) => {
console.log('成功的回调函数, 接收到的data数据: ', data)
},
// websocket连接失败的回调函数
(err) => {
console.log('失败的回调函数', err)
}
)
}
}
};
</script>
@@ -66,5 +171,6 @@ export default {
background: url(../assets/bg.png) no-repeat;
background-size: cover;
background-position: 0 0;
overflow: auto;
}
</style>

View File

@@ -0,0 +1,55 @@
import { debounce } from '@/utils'
export default {
data() {
return {
$_sidebarElm: null,
$_resizeHandler: null
}
},
mounted() {
this.$_resizeHandler = debounce(() => {
if (this.chart) {
this.chart.resize()
}
}, 100)
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
},
beforeDestroy() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
},
// to fixed bug when cached by keep-alive
// https://github.com/PanJiaChen/vue-element-admin/issues/2116
activated() {
this.$_initResizeEvent()
this.$_initSidebarResizeEvent()
},
deactivated() {
this.$_destroyResizeEvent()
this.$_destroySidebarResizeEvent()
},
methods: {
// use $_ for mixins properties
// https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential
$_initResizeEvent() {
window.addEventListener('resize', this.$_resizeHandler)
},
$_destroyResizeEvent() {
window.removeEventListener('resize', this.$_resizeHandler)
},
$_sidebarResizeHandler(e) {
if (e.propertyName === 'width') {
this.$_resizeHandler()
}
},
$_initSidebarResizeEvent() {
this.$_sidebarElm = document.getElementsByClassName('sidebar-container')[0]
this.$_sidebarElm && this.$_sidebarElm.addEventListener('transitionend', this.$_sidebarResizeHandler)
},
$_destroySidebarResizeEvent() {
this.$_sidebarElm && this.$_sidebarElm.removeEventListener('transitionend', this.$_sidebarResizeHandler)
}
}
}

View File

@@ -0,0 +1,34 @@
import { connectWebsocket, closeWebsocket } from './../utils/websocket'
import store from "@/store";
// 创建dcs链接
export const getDcsMsg = () => {
const userId = 'dcsmsg' + new Date().getTime()
connectWebsocket(
// 测试地址
'ws://10.70.180.10:8081/xc-screen/websocket/'+userId,
// 传递给后台的数据
'',
// 成功拿到后台返回的数据的回调函数
(data) => {
console.log('成功的回调函数, 接收到的data数据: ', data)
let msgData = JSON.parse(data)
switch (msgData?.type) {
case "FanFrequencyInfo": {
store.dispatch({type: "websocket/setFanFrequencyInfo", payload:msgData.data.FanFrequencyInfo})
break;
}
case "KilnInfo": {
store.dispatch({type: "websocket/setKilnInfo", payload: msgData.data.kilnInfo})
break;
}
default:
console.log('++++++++')
}
},
// websocket连接失败的回调函数
(err) => {
console.log('失败的回调函数', err)
}
)
}

View File

@@ -0,0 +1,34 @@
import { connectWebsocket, closeWebsocket } from './../utils/websocket'
import store from "@/store";
// 创建dcs链接
export const getDcsMsg = () => {
const userId = 'dcsmsg' + new Date().getTime()
connectWebsocket(
// 测试地址
'ws://10.70.180.10:8081/xc-screen/websocket/'+userId,
// 传递给后台的数据
'',
// 成功拿到后台返回的数据的回调函数
(data) => {
console.log('成功的回调函数, 接收到的data数据: ', data)
let msgData = JSON.parse(data)
switch (msgData?.type) {
case "FanFrequencyInfo": {
store.dispatch({type: "websocket/setFanFrequencyInfo", payload:msgData.data.FanFrequencyInfo})
break;
}
case "KilnInfo": {
store.dispatch({type: "websocket/setKilnInfo", payload: msgData.data.kilnInfo})
break;
}
default:
console.log('++++++++')
}
},
// websocket连接失败的回调函数
(err) => {
console.log('失败的回调函数', err)
}
)
}

View File

@@ -0,0 +1,204 @@
// 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();
}
}
// 创建ws函数
const createWebSoket = () => {
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) => {
onWsOpen(event);
heartCheck.start();
}
// 监听服务器端返回的信息
wsObj.onmessage = (event) => {
onWsMessage(event);
heartCheck.start();
}
wsObj.onclose = (event) => {
writeToScreen('onclose执行关闭事件');
onWsClose(event);
}
wsObj.onerror = (event) => {
writeToScreen('onerror执行error事件开始重连');
onWsError(event);
reconnect();
}
} catch (err) {
writeToScreen('绑定事件没有成功,开始重连');
reconnect();
}
}
const onWsOpen = (event) => {
writeToScreen('CONNECT');
// // 客户端与服务器端通信
// 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);
}
}
const onWsMessage = (event) => {
const jsonStr = event.data;
writeToScreen('onWsMessage接收到服务器的数据: ', jsonStr);
messageCallback(jsonStr);
}
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();
}
}
const onWsError = (event) => {
writeToScreen('onWsError: ', event.data);
errorCallback(event);
}
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('重连完成');
}, 3000);
}
// 从浏览器地址中获取对应参数
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: 15000,
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 = { ping: true };
wsObj.send(JSON.stringify(datas));
} catch (err) {
writeToScreen("发送ping异常");
}
console.log("内嵌定时器this.serverTimeoutObj: ", this.serverTimeoutObj)
// 内嵌定时器
this.serverTimeoutObj = setTimeout(() => {
writeToScreen("没有收到后台的数据,重新连接");
reconnect();
}, this.timeout)
}, this.timeout)
}
}