projects/mesxc-zjl #167

Merged
juzi merged 2 commits from projects/mesxc-zjl into projects/mesxc-test 2024-01-03 14:13:12 +08:00
26 changed files with 1361 additions and 271 deletions

View File

@ -13,7 +13,11 @@ VUE_APP_TITLE = MES系统
# 芋道管理系统/开发环境 # 芋道管理系统/开发环境
# VUE_APP_BASE_API = 'http://100.64.0.26:48082' # VUE_APP_BASE_API = 'http://100.64.0.26:48082'
VUE_APP_BASE_API = 'http://10.70.2.2:8080'
# VUE_APP_BASE_API = 'http://192.168.0.33:48082'
# VUE_APP_BASE_API = 'http://10.70.2.2:8080'
# VUE_APP_BASE_API = 'http://192.168.4.173:48080' # VUE_APP_BASE_API = 'http://192.168.4.173:48080'
# VUE_APP_BASE_API = 'http://192.168.2.173:48080' # VUE_APP_BASE_API = 'http://192.168.2.173:48080'
# VUE_APP_BASE_API = 'http://192.168.1.49:48082' # VUE_APP_BASE_API = 'http://192.168.1.49:48082'
@ -23,6 +27,8 @@ VUE_APP_BASE_API = 'http://10.70.2.2:8080'
# VUE_APP_BASE_API = 'http://192.168.1.62:48082' # VUE_APP_BASE_API = 'http://192.168.1.62:48082'
# VUE_APP_BASE_API = 'http://192.168.1.78:48082' # VUE_APP_BASE_API = 'http://192.168.1.78:48082'
VUE_APP_BASE_API = 'http://100.64.0.23:48082'
# 积木报表指向地址 # 积木报表指向地址
VUE_APP_JIMU_API = 'http://10.70.2.22:8080' VUE_APP_JIMU_API = 'http://10.70.2.22:8080'

View File

@ -48,6 +48,7 @@
<script> <script>
import ScrollPane from './ScrollPane'; import ScrollPane from './ScrollPane';
import path from 'path'; import path from 'path';
import { getDcsMsg, closeDcsMsg } from "@/websocket/wsInterface"
export default { export default {
components: { ScrollPane }, components: { ScrollPane },
@ -58,6 +59,7 @@ export default {
left: 0, left: 0,
selectedTag: {}, selectedTag: {},
affixTags: [], affixTags: [],
wsIsOpen: false
}; };
}, },
computed: { computed: {
@ -83,6 +85,27 @@ export default {
document.body.removeEventListener('click', this.closeMenu); document.body.removeEventListener('click', this.closeMenu);
} }
}, },
visitedViews(newVal, oldVal){
let num = 0
newVal && newVal.map(item => {
if (item.path === '/databoard/kiln' || item.path === '/databoard/whole-plant') {
num++
}
})
if (num > 0) {
if(!this.wsIsOpen) {
getDcsMsg()
this.wsIsOpen = true
console.log('开启websocket==========')
}
}else{
if (this.wsIsOpen) {
closeDcsMsg()
this.wsIsOpen = false
console.log('关闭============')
}
}
}
}, },
mounted() { mounted() {
this.initTags(); this.initTags();

View File

@ -1,10 +1,24 @@
const state = { const state = {
fanFrequencyInfo:{},// 分机运行频率 fanFrequencyInfo:{},// 分机运行频率
kilnInfo:{},// 窑炉信息 kilnInfo:{},// 窑炉信息
gasInfo:{},// 天然气 gasInfo:{},// 天然气流量图
sumGasInfo: {},// 天然气总量
israKiln:[],// ISRA缺陷检测 israKiln:[],// ISRA缺陷检测
material:[]// 原料 material:[],// 原料
energyInfo: {
elecQty1: '',
elecQty2: '',
waterQty: ''
}, // 能耗
energyWeekTrend:[],
energyMonthTrend:[],
energyYearTrend:[],// 能耗图
exhaustGasInfo:{}, // 烟气
gasChartDayTrend:{}, // 烟气
gasChartWeekTrend:{}, // 烟气
gasChartMonthTrend:{}, // 烟气
gasChartYearTrend:{} // 烟气
}; };
const mutations = { const mutations = {
SET_FANFREQUENCYINFO: (state, fanFrequencyInfo) => { SET_FANFREQUENCYINFO: (state, fanFrequencyInfo) => {
@ -16,6 +30,9 @@ const mutations = {
SET_GASINFO: (state, gasInfo) => { SET_GASINFO: (state, gasInfo) => {
state.gasInfo = gasInfo state.gasInfo = gasInfo
}, },
SET_SUMGASINFO: (state, sumGasInfo) => {
state.sumGasInfo = sumGasInfo
},
SET_ISRAKILN: (state, israKiln) => { SET_ISRAKILN: (state, israKiln) => {
@ -23,6 +40,34 @@ const mutations = {
}, },
SET_MATERIAL: (state, material) => { SET_MATERIAL: (state, material) => {
state.material = material state.material = material
},
SET_ENERGYINFO: (state, energyInfo) => {
if (Object.keys(energyInfo).length > 1) {
state.energyInfo.elecQty1 = energyInfo.elecQty1
state.energyInfo.elecQty2 = energyInfo.elecQty2
} else {
state.energyInfo.waterQty = energyInfo.waterQty
}
},
SET_ENERGYTREND: (state, energyTrend) => {
if (energyTrend.week.length > 0) {
state.energyWeekTrend = energyTrend.week
}
if (energyTrend.month.length > 0) {
state.energyMonthTrend = energyTrend.month
}
if (energyTrend.year.length > 0) {
state.energyYearTrend = energyTrend.year
}
},
SET_EXHAUSTGASINFO: (state, exhaustGasInfo) => {
state.exhaustGasInfo = exhaustGasInfo
},
SET_EXHAUSTGASCHART: (state, exhaustGasChart) => {
state.gasChartDayTrend = exhaustGasChart.gasChartDayTrend
state.gasChartWeekTrend = exhaustGasChart.gasChartWeekTrend
state.gasChartMonthTrend = exhaustGasChart.gasChartMonthTrend
state.gasChartYearTrend = exhaustGasChart.gasChartYearTrend
} }
}; };
const actions = { const actions = {
@ -35,6 +80,9 @@ const actions = {
setGasInfo({ commit }, gasInfo) { setGasInfo({ commit }, gasInfo) {
commit('SET_GASINFO', gasInfo.payload) commit('SET_GASINFO', gasInfo.payload)
}, },
setSumGasInfo({ commit }, sumGasInfo) {
commit('SET_SUMGASINFO', sumGasInfo.payload)
},
setIsraKiln({ commit }, israKiln) { setIsraKiln({ commit }, israKiln) {
@ -43,6 +91,18 @@ const actions = {
setMaterial({ commit }, material) { setMaterial({ commit }, material) {
commit('SET_MATERIAL', material.payload) commit('SET_MATERIAL', material.payload)
}, },
setEnergyInfo({ commit }, energyInfo) {
commit('SET_ENERGYINFO', energyInfo.payload)
},
setEnergyTrend({ commit }, energyTrend) {
commit('SET_ENERGYTREND', energyTrend.payload)
},
setExhaustGasInfo({ commit }, exhaustGasInfo) {
commit('SET_EXHAUSTGASINFO', exhaustGasInfo.payload)
},
setExhaustGasChart({ commit }, exhaustGasChart) {
commit('SET_EXHAUSTGASCHART', exhaustGasChart.payload)
},
}; };
export default { export default {
namespaced: true, namespaced: true,

View File

@ -0,0 +1,234 @@
<template>
<div class="gas-chart"></div>
</template>
<script>
import * as echarts from 'echarts';
import resize from './../mixins/resize'
export default {
name: 'GasChart',
mixins: [resize],
components: {},
props: {
chartType: '',
chartTime: ''
},
data() {
const colors = [
'#12FFF5',
'#2760FF',
'#FFD160',
'#E80091',
'#8064ff',
'#ff8a3b',
'#8cd26d',
'#2aa1ff',
];
return {
chart: null
};
},
computed: {
gasChartDayTrend() {
return this.$store.state.websocket.gasChartDayTrend
},
gasChartWeekTrend() {
return this.$store.state.websocket.gasChartWeekTrend
},
gasChartMonthTrend() {
return this.$store.state.websocket.gasChartMonthTrend
},
gasChartYearTrend() {
return this.$store.state.websocket.gasChartYearTrend
}
},
watch: {
gasChartDayTrend: {
handler(newVal, oldVal) {
if (this.chartTime === '日') {
this.updateChart()
}
}
},
gasChartWeekTrend: {
handler(newVal, oldVal) {
if (this.chartTime === '周') {
this.updateChart()
}
}
},
gasChartMonthTrend: {
handler(newVal, oldVal) {
if (this.chartTime === '月') {
this.updateChart()
}
}
},
gasChartYearTrend: {
handler(newVal, oldVal) {
if (this.chartTime === '年') {
this.updateChart()
}
}
},
chartType: {//
handler(newVal, oldVal) {
this.updateChart()
}
},
chartTime: {//
handler(newVal, oldVal) {
this.updateChart()
}
}
},
mounted() {
this.$el.addEventListener('resize', () => {
console.log('resziing.....');
});
this.updateChart()
},
methods: {
updateChart() {
let gasName = ''
const colors = ['#FFCB59'];
let temp1 = []
let temp2 = []
let seriesData = []
let xData = []
let yData = []
switch (this.chartTime) {
case '日':{
temp1 = this.gasChartDayTrend
break;
}
case '周':{
temp1 = this.gasChartWeekTrend
break;
}
case '月':{
temp1 = this.gasChartMonthTrend
break;
}
case '年':{
temp1 = this.gasChartYearTrend
break;
}
default:
}
switch (this.chartType) {
case '氧气含量':{
temp2 = temp1.O2_float || []
break;
}
case '二氧化硫':{
temp2 = temp1.SO2_float || []
break;
}
case '一氧化氮':{
temp2 = temp1.NOX_float || []
break;
}
case '颗粒物':{
temp2 = temp1.dust_float || []
break;
}
default:
}
temp2.length > 0 && temp2.map(i => {
xData.push(i.time)
yData.push(i.value)
})
if (yData.length == 0) {
seriesData = []
}else {
seriesData = [{
name: gasName,
data: yData,
type: "line",
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#FFCB59' + "40" },
{ offset: 0.5, color: '#FFCB59' + "20" },
{ offset: 1, color: '#FFCB59' + "00" },
]),
},
lineStyle: {
width: 1
},
symbolSize: 1,
emphasis: {
focus: 'series'
}
}]
}
//
if (
this.chart !== null &&
this.chart !== '' &&
this.chart !== undefined
) {
this.chart.dispose() // Dom
}
this.chart = echarts.init(this.$el);
var option = {
color: colors,
grid: { top: 32, right: 12, bottom: 20, left: 48 },
xAxis: {
type: 'category',
data: xData,
axisLabel: {
color: '#fff',
fontSize: 12,
},
axisTick: { show: false },
axisLine: {
lineStyle: {
width: 1,
color: '#213259',
},
},
},
yAxis: {
name: '单位m³/h',
nameTextStyle: {
color: '#fff',
fontSize: 10,
align: 'right',
},
type: 'value',
axisLabel: {
color: '#fff',
fontSize: 12,
},
axisLine: {
show: true,
lineStyle: {
color: '#213259',
},
},
splitLine: {
lineStyle: {
color: '#213259a0',
},
},
},
series: seriesData,
tooltip: {
trigger: 'axis',
},
}
option && this.chart.setOption(option)
}
},
};
</script>
<style scoped lang="scss">
.gas-chart {
width: 100%;
height: 100%;
}
</style>

View File

@ -17,7 +17,10 @@ export default {
name: 'GasChart', name: 'GasChart',
mixins: [resize], mixins: [resize],
components: {}, components: {},
props: {}, props: {
chartType: '', //
chartTime: ''
},
data() { data() {
const colors = [ const colors = [
'#12FFF5', '#12FFF5',
@ -30,22 +33,154 @@ export default {
'#2aa1ff', '#2aa1ff',
]; ];
return { return {
chart: null, chart: null
option: { };
color: colors, },
grid: { top: 32, right: 12, bottom: 20, left: 48 }, computed: {
xAxis: { gasChartMsg() {
type: 'category', return this.$store.state.websocket.sumGasInfo
data: Array(7) },
energyWeekTrend() {
return this.$store.state.websocket.energyWeekTrend
},
energyMonthTrend() {
return this.$store.state.websocket.energyMonthTrend
},
energyYearTrend() {
return this.$store.state.websocket.energyYearTrend
}
},
watch: {
energyWeekTrend: {//
handler(newVal, oldVal) {
if (this.chartTime === '周' && this.chartType === '电耗能') {
this.updateChart()
}
}
},
energyMonthTrend: {//
handler(newVal, oldVal) {
if (this.chartTime === '月' && this.chartType === '电耗能') {
this.updateChart()
}
}
},
energyYearTrend: {//
handler(newVal, oldVal) {
if (this.chartTime === '年' && this.chartType === '电耗能') {
this.updateChart()
}
}
},
chartTime: {//
handler(newVal, oldVal) {
this.updateChart()
}
},
chartType: {//
handler(newVal, oldVal) {
this.updateChart()
}
}
},
mounted() {
this.$el.addEventListener('resize', () => {
console.log('resziing.....');
});
this.updateChart()
},
methods: {
updateChart() {
let gasName = ''
const colors = ['#FFCB59'];
let temp = []
let seriesData = []
let xData = []
let yData = []
switch (this.chartType) {
case '电耗能':{
gasName = '电耗能'
if (this.chartTime === '周') {
temp = this.energyWeekTrend || []
}else if(this.chartTime === '月') {
temp = this.energyMonthTrend || []
}else{
temp = this.energyYearTrend || []
}
temp && temp.map(i => {
xData.push(i.time)
yData.push(i.qty)
})
break;
}
case '天然气I':{
yData = this.gasChartMsg.hisSumGas1 || []
gasName = '天然气I'
xData = Array(7)
.fill(1) .fill(1)
.map((_, index) => { .map((_, index) => {
const today = new Date(); const today = new Date();
const dtimestamp = today - index * 24 * 60 * 60 * 1000; const dtimestamp = today - (index+1) * 24 * 60 * 60 * 1000;
return `${new Date(dtimestamp).getMonth() + 1}.${new Date( return `${new Date(dtimestamp).getMonth() + 1}.${new Date(
dtimestamp dtimestamp
).getDate()}`; ).getDate()}`;
}) })
.reverse(), .reverse()
break;
}
default:
gasName = '天然气II'
yData = this.gasChartMsg.hisSumGas2 || []
xData = Array(7)
.fill(1)
.map((_, index) => {
const today = new Date();
const dtimestamp = today - (index+1) * 24 * 60 * 60 * 1000;
return `${new Date(dtimestamp).getMonth() + 1}.${new Date(
dtimestamp
).getDate()}`;
})
.reverse()
}
if (yData.length == 0) {
seriesData = []
}else {
seriesData = [{
name: gasName,
data: yData,
type: "line",
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: '#FFCB59' + "40" },
{ offset: 0.5, color: '#FFCB59' + "20" },
{ offset: 1, color: '#FFCB59' + "00" },
]),
},
lineStyle: {
width: 1
},
symbolSize: 1,
emphasis: {
focus: 'series'
}
}]
}
//
if (
this.chart !== null &&
this.chart !== '' &&
this.chart !== undefined
) {
this.chart.dispose() // Dom
}
this.chart = echarts.init(this.$el);
var option = {
color: colors,
grid: { top: 32, right: 12, bottom: 20, left: 48 },
xAxis: {
type: 'category',
data: xData,
axisLabel: { axisLabel: {
color: '#fff', color: '#fff',
fontSize: 12, fontSize: 12,
@ -82,71 +217,14 @@ export default {
}, },
}, },
}, },
series: [ series: seriesData,
Array(7)
.fill(1)
.map((_) => Math.ceil(Math.random() * 100)),
Array(7)
.fill(1)
.map((_) => Math.ceil(Math.random() * 100)),
Array(7)
.fill(1)
.map((_) => Math.ceil(Math.random() * 100)),
].map((v, i) => ({
name: ['总量', '白班', '夜班'][i],
data: v,
type: 'line',
symbol: 'circle',
areaStyle: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
// i % 8 8
{ offset: 0, color: colors[i % 8] + '40' },
{ offset: 0.5, color: colors[i % 8] + '20' },
{ offset: 1, color: colors[i % 8] + '00' },
]),
},
})),
tooltip: { tooltip: {
trigger: 'axis', trigger: 'axis',
}, },
},
};
},
computed: {
sidebarStatus() {
return this.$store.state.app.sidebar.opened;
},
gasChartMsg() {
return this.$store.state.websocket.gasInfo
}
},
watch: {
sidebarStatus(val) {
console.log('sidebarStatus', val);
this.chart && this.chart.dispose();
setTimeout(() => {
this.chart = echarts.init(this.$el);
this.chart.setOption(this.option);
}, 500);
},
gasChartMsg: {
handler(newVal, oldVal) {
console.log(newVal)
// this.chartData = newVal
console.log('newVal============')
// this.updateChart()
} }
option && this.chart.setOption(option)
} }
}, },
mounted() {
this.$el.addEventListener('resize', () => {
console.log('resziing.....');
});
this.chart = echarts.init(this.$el);
this.chart.setOption(this.option);
},
methods: {},
}; };
</script> </script>

View File

@ -1,10 +1,3 @@
<!--
filename: ISRAChart.vue
author: liubin
date: 2023-12-12 09:05:25
description:
-->
<template> <template>
<div class="isra-chart"></div> <div class="isra-chart"></div>
</template> </template>
@ -68,9 +61,7 @@ export default {
watch: { watch: {
israChartMsg: { israChartMsg: {
handler(newVal, oldVal) { handler(newVal, oldVal) {
console.log(newVal)
this.chartData = newVal this.chartData = newVal
console.log('newVal============')
this.updateChart() this.updateChart()
} }
} }
@ -99,48 +90,18 @@ export default {
color: '#fff', color: '#fff',
}, },
subtextStyle: { subtextStyle: {
fontSize: 16, fontSize: 20,
color: '#fff00', color: '#fff00',
}, },
}, },
series:[{ series:[{
name: 'Access From', name: 'ISRA缺陷检测',
type: 'pie', type: 'pie',
radius: ['45%', '65%'], center: ['50%', '40%'],
radius: ['45%', '70%'],
avoidLabelOverlap: true, avoidLabelOverlap: true,
label: { label: {
show: true, show: false
position: 'outside',
formatter: ({ dataIndex, percent }) => {
const styleName = ['a', 'b', 'c', 'd'][dataIndex % 4];
return `{${styleName}|${percent}%}`;
},
rich: {
a: {
color: '#2760ff',
fontSize: 24,
borderWidth: 0,
textBorderWidth: 0,
},
b: {
color: '#518eec',
fontSize: 24,
borderWidth: 0,
textBorderWidth: 0,
},
c: {
color: '#0ee8e4',
fontSize: 24,
borderWidth: 0,
textBorderWidth: 0,
},
d: {
color: '#ddb523',
fontSize: 24,
borderWidth: 0,
textBorderWidth: 0,
},
},
}, },
labelLine: { labelLine: {
show: true, show: true,

View File

@ -11,7 +11,7 @@
class="btn" class="btn"
v-for="opt in options" v-for="opt in options"
:key="opt" :key="opt"
@click="active = opt" @click="clickBtn(opt)"
:class="active == opt ? 'btn-active' : ''"> :class="active == opt ? 'btn-active' : ''">
{{ opt }} {{ opt }}
</button> </button>
@ -22,15 +22,18 @@
export default { export default {
name: 'SelectorBtnGroup', name: 'SelectorBtnGroup',
components: {}, components: {},
props: ['options'], props: ['options', 'active'],
data() { data() {
return { return {
active: this.options[0] || 'default' // active: this.options[0] || 'default'
}; };
}, },
computed: {}, computed: {},
methods: { methods: {
clickBtn(opt) {
// this.active = opt
this.$emit('emitFun', opt)
}
}, },
}; };
</script> </script>

View File

@ -6,10 +6,10 @@
class="deepProcessingBoard" class="deepProcessingBoard"
style=" style="
position: absolute; position: absolute;
transform-origin: 16px 8px; transform-origin: left top;
font-size: 16px; font-size: 16px;
top: -8px; top: 0px;
left: -16px; left: 0px;
width: 1920px; width: 1920px;
height: 1080px; height: 1080px;
display: flex; display: flex;
@ -18,6 +18,17 @@
" "
:style="{transform:'scale('+scaleNum+')'}"> :style="{transform:'scale('+scaleNum+')'}">
<KHeader :isFullScreen='isFullScreen' @screenfullChange='screenfullChange' topTitle='全厂总览驾驶舱'/> <KHeader :isFullScreen='isFullScreen' @screenfullChange='screenfullChange' topTitle='全厂总览驾驶舱'/>
<!-- <div
class="main-body"
style="
display: grid;
gap: 16px;
grid-template-rows: 605px 320px;
">
<GasHandle />
<YieldRate />
</div> -->
<div <div
class="main-body" class="main-body"
style="flex: 1; display: flex; gap: 20px; padding: 0px 16px"> style="flex: 1; display: flex; gap: 20px; padding: 0px 16px">
@ -103,14 +114,14 @@ export default {
}) })
return false return false
} }
screenfull.toggle(this.$refs.wholePlantContainerB) screenfull.toggle(this.$refs.deepProcessingContainerB)
}, },
resetSize() { resetSize() {
let wholePlantContainerBox = document.querySelector('#wholePlantContainer') let deepProcessingContainer = document.querySelector('#deepProcessingContainer')
let rw = parseFloat(window.innerWidth) let rw = parseFloat(window.innerWidth)
let rh = parseFloat(window.innerHeight) let rh = parseFloat(window.innerHeight)
let bw = parseFloat(wholePlantContainerBox.style.width) let bw = parseFloat(deepProcessingContainer.style.width)
let bh = parseFloat(wholePlantContainerBox.style.height) let bh = parseFloat(deepProcessingContainer.style.height)
let wx = 0 let wx = 0
let hx = 0 let hx = 0
if (screenfull.isFullscreen) { if (screenfull.isFullscreen) {

View File

@ -31,24 +31,24 @@
justify-content: space-between; justify-content: space-between;
"> ">
<SelectorBtnGroup <SelectorBtnGroup
:options="['电耗能', '天然气I', '天然气II']" @emitFun='toggleType'/> :options="['电耗能', '天然气I', '天然气II']" @emitFun='toggleType' :active='chartType'/>
<SelectorBtnGroup :options="['周', '月', '年']" @emitFun='toggleDate'/> <SelectorBtnGroup :options="['周', '月', '年']" @emitFun='toggleDate' :active='chartTime'/>
</div> </div>
<div class="chart" style="height: 200px; margin-top: 8px;"> <div class="chart" style="height: 200px; margin-top: 8px;">
<GasChart /> <GasChart :chartType='chartType' :chartTime='chartTime'/>
</div> </div>
</div> </div>
</Container> </Container>
</template> </template>
<script> <script>
import Container from '../components/Container.vue'; import Container from '../components/Container';
import ShadowRect from '../components/ShadowRect.vue'; import ShadowRect from '../components/ShadowRect.vue';
import SplitLine from '../components/line'; import SplitLine from '../components/line';
import Switcher from '../components/Switcher'; import Switcher from '../components/Switcher';
import EnergeTop from './EnergeTop'; import EnergeTop from './EnergeTop';
import GasChart from '../components/GasChart.vue'; import GasChart from '../components/GasChart.vue';
import SelectorBtnGroup from '../components/SelectorBtnGroup.vue'; import SelectorBtnGroup from '../components/SelectorBtnGroup';
export default { export default {
name: 'EnergeCost', name: 'EnergeCost',
components: { components: {
@ -62,17 +62,42 @@ export default {
}, },
props: {}, props: {},
data() { data() {
return {}; return {
chartType:'电耗能',
chartTime:'周'
};
},
computed: {
gasInfoMsg() {
return this.$store.state.websocket.gasInfo
},
}, },
computed: {},
methods: { methods: {
// //
toggleType() { toggleType(val) {
console.log('能源' + val)
if (val === '天然气I' || val === '天然气II') {
if (this.chartTime === '周') {
this.chartType = val
} else {
this.$message.warning('暂无数据')
}
}else {
this.chartType = val
}
}, },
// //
toggleDate() { toggleDate(val) {
console.log('时间' + val)
if (val === '月' || val === '年') {
if (this.chartType === '电耗能') {
this.chartTime = val
} else {
this.$message.warning('暂无数据')
}
}else{
this.chartTime = val
}
} }
}, },
}; };

View File

@ -23,8 +23,7 @@
style=" style="
font-size: 16px; font-size: 16px;
line-height: 1.55; line-height: 1.55;
text-align: right; text-align: center;
padding-right: 8px;
letter-spacing: 1px; letter-spacing: 1px;
"> ">
余热发电 余热发电
@ -33,11 +32,10 @@
style=" style="
font-size: 16px; font-size: 16px;
line-height: 1.55; line-height: 1.55;
text-align: right; text-align: center;
padding-right: 8px;
letter-spacing: 1px; letter-spacing: 1px;
"> ">
1023kWh {{energyInfo.elecQty1}}kwh
</span> </span>
</ShadowRect> </ShadowRect>
@ -46,14 +44,14 @@
style=" style="
font-size: 16px; font-size: 16px;
line-height: 1.25; line-height: 1.25;
flex: 1.2; flex: 1;
text-align: right; text-align: right;
padding-right: 8px; padding-right: 8px;
letter-spacing: 3px; letter-spacing: 3px;
"> ">
<p style="margin: 0; line-height: inherit">水耗量</p> <p style="margin: 0; line-height: inherit">水耗量</p>
</div> </div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">32K</span> <span style="font-size: 16px; line-height: 1.24; flex: 1">{{energyInfo.waterQty}}</span>
</ShadowRect> </ShadowRect>
<ShadowRect> <ShadowRect>
@ -61,14 +59,14 @@
style=" style="
font-size: 16px; font-size: 16px;
line-height: 1.25; line-height: 1.25;
flex: 1.2; flex: 1;
text-align: right; text-align: right;
padding-right: 8px; padding-right: 8px;
letter-spacing: 3px; letter-spacing: 3px;
"> ">
<p style="margin: 0; line-height: inherit">天然气I</p> <p style="margin: 0; line-height: inherit">天然气I</p>
</div> </div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">322Km³</span> <span style="font-size: 16px; line-height: 1.24; flex: 1">{{sumGasInfo.sumGas1Now}}</span>
</ShadowRect> </ShadowRect>
<ShadowRect> <ShadowRect>
@ -76,14 +74,14 @@
style=" style="
font-size: 16px; font-size: 16px;
line-height: 1.25; line-height: 1.25;
flex: 1.2; flex: 1;
text-align: right; text-align: right;
padding-right: 8px; padding-right: 8px;
letter-spacing: 3px; letter-spacing: 3px;
"> ">
<p style="margin: 0; line-height: inherit">电耗量</p> <p style="margin: 0; line-height: inherit">电耗量</p>
</div> </div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">132kWh</span> <span style="font-size: 16px; line-height: 1.24; flex: 1">{{energyInfo.elecQty2}}kwh</span>
</ShadowRect> </ShadowRect>
<ShadowRect> <ShadowRect>
@ -91,14 +89,14 @@
style=" style="
font-size: 16px; font-size: 16px;
line-height: 1.25; line-height: 1.25;
flex: 1.2; flex: 1;
text-align: right; text-align: right;
padding-right: 8px; padding-right: 8px;
letter-spacing: 3px; letter-spacing: 3px;
"> ">
<p style="margin: 0; line-height: inherit">天然气II</p> <p style="margin: 0; line-height: inherit">天然气II</p>
</div> </div>
<span style="font-size: 16px; line-height: 1.24; flex: 1">992Km³</span> <span style="font-size: 16px; line-height: 1.24; flex: 1">{{sumGasInfo.sumGas2Now}}</span>
</ShadowRect> </ShadowRect>
</div> </div>
</template> </template>
@ -113,7 +111,14 @@ export default {
data() { data() {
return {}; return {};
}, },
computed: {}, computed: {
sumGasInfo(){
return this.$store.state.websocket.sumGasInfo
},
energyInfo() {
return this.$store.state.websocket.energyInfo
}
},
methods: {}, methods: {},
}; };
</script> </script>

View File

@ -7,13 +7,13 @@
<template> <template>
<Container name="风机运行频率" size="middle" style=""> <Container name="风机运行频率" size="middle" style="">
<div class="" style="position: absolute; top: 26px; left: 220px"> <!-- <div class="" style="position: absolute; top: 26px; left: 220px">
<Switcher /> <Switcher />
</div> </div> -->
<div <div
class="absolute" class="absolute"
style=" style="
padding: 12px; padding: 5px 12px;
display: grid; display: grid;
grid-template-columns: repeat(2, 1fr); grid-template-columns: repeat(2, 1fr);
grid-auto-rows: auto; grid-auto-rows: auto;
@ -23,7 +23,7 @@
<span <span
style=" style="
font-size: 18px; font-size: 18px;
line-height: 1.1; line-height: 1.15;
flex: 3.5; flex: 3.5;
text-align: right; text-align: right;
padding-right: 8px; padding-right: 8px;
@ -31,7 +31,7 @@
"> ">
{{ key }}: {{ key }}:
</span> </span>
<span style="font-size: 20px; line-height: 1; flex: 1"> <span style="font-size: 20px; line-height: 1.15; flex: 1">
{{ value }}Hz {{ value }}Hz
</span> </span>
</ShadowRect> </ShadowRect>

View File

@ -1,10 +1,3 @@
<!--
filename: GasHandle.vue
author: liubin
date: 2023-12-11 09:02:40
description:
-->
<template> <template>
<div class="gas-handle" style="flex: 2"> <div class="gas-handle" style="flex: 2">
<Container name="烟气处理" size="large" style=""> <Container name="烟气处理" size="large" style="">
@ -26,11 +19,11 @@
flex: 1.2; flex: 1.2;
text-align: right; text-align: right;
padding-right: 8px; padding-right: 8px;
letter-spacing: 1px; letter-spacing: 3px;
"> ">
氧气含量 氧气含量
</span> </span>
<span style="font-size: 20px; line-height: 1.24; flex: 1">82%</span> <span style="font-size: 20px; line-height: 1.24; flex: 1">{{exhaustGasInfo.O2_float}}%</span>
</ShadowRect> </ShadowRect>
<ShadowRect> <ShadowRect>
<div <div
@ -45,7 +38,7 @@
<p style="margin: 0; line-height: inherit">一氧化氮</p> <p style="margin: 0; line-height: inherit">一氧化氮</p>
<p style="margin: 0; line-height: inherit">排放浓度</p> <p style="margin: 0; line-height: inherit">排放浓度</p>
</div> </div>
<span style="font-size: 20px; line-height: 1.24; flex: 1">82%</span> <span style="font-size: 20px; line-height: 1.24; flex: 1">{{exhaustGasInfo.NOX_float}}mg/</span>
</ShadowRect> </ShadowRect>
<ShadowRect> <ShadowRect>
@ -61,23 +54,22 @@
<p style="margin: 0; line-height: inherit">二氧化硫</p> <p style="margin: 0; line-height: inherit">二氧化硫</p>
<p style="margin: 0; line-height: inherit">排放浓度</p> <p style="margin: 0; line-height: inherit">排放浓度</p>
</div> </div>
<span style="font-size: 20px; line-height: 1.24; flex: 1">59mg/</span> <span style="font-size: 20px; line-height: 1.24; flex: 1">{{exhaustGasInfo.SO2_float}}mg/</span>
</ShadowRect> </ShadowRect>
<ShadowRect> <ShadowRect>
<div <span
style=" style="
font-size: 20px; font-size: 20px;
line-height: 1.5; line-height: 1.24;
flex: 1.2; flex: 1.2;
text-align: right; text-align: right;
padding-right: 8px; padding-right: 8px;
letter-spacing: 3px; letter-spacing: 1px;
"> ">
<p style="margin: 0; line-height: inherit">二氧化氮</p> 颗粒物浓度
<p style="margin: 0; line-height: inherit">排放浓度</p> </span>
</div> <span style="font-size: 20px; line-height: 1.24; flex: 1">{{exhaustGasInfo.dust_float}}mg/</span>
<span style="font-size: 20px; line-height: 1.24; flex: 1">82%</span>
</ShadowRect> </ShadowRect>
</div> </div>
<KilnLine :horizontal="true" /> <KilnLine :horizontal="true" />
@ -103,11 +95,11 @@
justify-content: space-between; justify-content: space-between;
"> ">
<SelectorBtnGroup <SelectorBtnGroup
:options="['氧气含量', '二氧化硫', '一氧化氮', '二氧化氮']" /> :options="['氧气含量', '二氧化硫', '一氧化氮', '颗粒物']" @emitFun='toggleType' :active='chartType'/>
<SelectorBtnGroup :options="['日', '周', '月', '年']" /> <SelectorBtnGroup :options="['日', '周', '月', '年']" @emitFun='toggleDate' :active='chartTime' />
</div> </div>
<div class="chart" style="height: 250px;margin-top: 10px;"> <div class="chart" style="height: 250px;margin-top: 10px;">
<GasChart /> <FlueGas :chartType='chartType' :chartTime='chartTime'/>
</div> </div>
</div> </div>
</Container> </Container>
@ -115,12 +107,12 @@
</template> </template>
<script> <script>
import Container from '../components/Container.vue'; import Container from '../components/Container';
import ShadowRect from '../components/ShadowRect.vue'; import ShadowRect from '../components/ShadowRect.vue';
import KilnLine from '../components/line'; import KilnLine from '../components/line';
import Switcher from '../components/Switcher'; import Switcher from '../components/Switcher';
import SelectorBtnGroup from '../components/SelectorBtnGroup.vue'; import SelectorBtnGroup from '../components/SelectorBtnGroup';
import GasChart from '../components/GasChart.vue'; import FlueGas from '../components/FlueGas';
export default { export default {
name: 'GasHandle', name: 'GasHandle',
@ -130,14 +122,32 @@ export default {
KilnLine, KilnLine,
Switcher, Switcher,
SelectorBtnGroup, SelectorBtnGroup,
GasChart, FlueGas,
}, },
props: {}, props: {},
data() { data() {
return {}; return {
chartType:'氧气含量',
chartTime:'日'
};
},
computed: {
exhaustGasInfo() {
return this.$store.state.websocket.exhaustGasInfo
}
},
methods: {
//
toggleType(val) {
console.log('烟气' + val)
this.chartType = val
},
//
toggleDate(val) {
console.log('时间' + val)
this.chartTime = val
}
}, },
computed: {},
methods: {},
}; };
</script> </script>

View File

@ -33,7 +33,7 @@
</template> </template>
<script> <script>
import Container from '../components/Container.vue'; import Container from '../components/Container';
import ShadowRect from '../components/ShadowRect.vue'; import ShadowRect from '../components/ShadowRect.vue';
import ISRAChart from '../components/ISRAChart.vue'; import ISRAChart from '../components/ISRAChart.vue';

View File

@ -34,7 +34,7 @@
{{item.materialUsed}} {{item.materialUsed}}
</span> </span>
<span style="color: #fff; font-size: 16px; letter-spacing: 1px"> <span style="color: #fff; font-size: 16px; letter-spacing: 1px">
- {{item.materialName}} - - {{item.materialName}}/kg-
</span> </span>
</div> </div>
</ShadowRect> </ShadowRect>
@ -60,7 +60,7 @@
{{item.materialUsed}} {{item.materialUsed}}
</span> </span>
<span style="color: #fff; font-size: 16px; letter-spacing: 1px"> <span style="color: #fff; font-size: 16px; letter-spacing: 1px">
- {{item.materialName}} - - {{item.materialName}}/kg-
</span> </span>
</div> </div>
</ShadowRect> </ShadowRect>
@ -71,7 +71,7 @@
</template> </template>
<script> <script>
import Container from '../components/Container.vue'; import Container from '../components/Container';
import ShadowRect from '../components/ShadowRect.vue'; import ShadowRect from '../components/ShadowRect.vue';
export default { export default {
name: 'MaterialCost', name: 'MaterialCost',

View File

@ -19,11 +19,11 @@
</template> </template>
<script> <script>
import Container from '../components/Container.vue'; import Container from '../components/Container';
import ShadowRect from '../components/ShadowRect.vue'; import ShadowRect from '../components/ShadowRect.vue';
import KilnLine from '../components/line'; import KilnLine from '../components/line';
import Switcher from '../components/Switcher'; import Switcher from '../components/Switcher';
import SelectorBtnGroup from '../components/SelectorBtnGroup.vue'; import SelectorBtnGroup from '../components/SelectorBtnGroup';
import KilnInfo from './KilnInfo.vue'; import KilnInfo from './KilnInfo.vue';
import GasHandle from './GasHandle.vue'; import GasHandle from './GasHandle.vue';
export default { export default {

View File

@ -1,10 +1,3 @@
<!--
filename: KilnDataBoard.vue
author: liubin
date: 2023-12-04 16:51:00
description:
-->
<template> <template>
<div id='kilnContainerB' ref='kilnContainerB' style="width: 100%;height: 100%;"> <div id='kilnContainerB' ref='kilnContainerB' style="width: 100%;height: 100%;">
<div <div
@ -13,10 +6,10 @@
class="KilnDataBoard" class="KilnDataBoard"
style=" style="
position: absolute; position: absolute;
transform-origin: 16px 8px; transform-origin: left top;
font-size: 16px; font-size: 16px;
top: -8px; top: 0px;
left: -16px; left: 0px;
width: 1920px; width: 1920px;
height: 1080px; height: 1080px;
display: flex; display: flex;
@ -45,15 +38,19 @@ import LeftFour from './LeftFour';
import RightTwo from './RightTwo.vue'; import RightTwo from './RightTwo.vue';
import screenfull from 'screenfull' import screenfull from 'screenfull'
import { debounce } from '@/utils/debounce' import { debounce } from '@/utils/debounce'
import { getDcsMsg, getMesMsg } from './../utils/wsInterface'
export default { export default {
name: 'KilnDataBoard', name: 'Kiln',
components: { components: {
KHeader, KHeader,
LeftFour, LeftFour,
RightTwo, RightTwo,
}, },
computed:{
sidebarStatus() {
return this.$store.state.app.sidebar.opened;
}
},
// provide() { // provide() {
// return { // return {
// resizeChart: null, // resizeChart: null,
@ -65,6 +62,11 @@ export default {
scaleNum: 0.8 scaleNum: 0.8
}; };
}, },
watch: {
sidebarStatus() {
this.boxReset()
},
},
created() { created() {
this.init() this.init()
}, },
@ -79,14 +81,6 @@ export default {
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
this.boxReset() this.boxReset()
}) })
// this.getMes()
// closeWebsocket()
getDcsMsg()
getMesMsg()
console.log('mounted...........')
},
destroyed() {
console.log('destroyed...........')
}, },
methods: { methods: {
change() { change() {

View File

@ -1,4 +1,4 @@
import { connectWebsocket, closeWebsocket } from './../utils/websocket' import { connectWebsocket, closeWebsocket } from './websocket'
import store from "@/store"; import store from "@/store";
// 创建dcs链接 // 创建dcs链接
@ -27,6 +27,10 @@ export const getDcsMsg = () => {
store.dispatch({type: "websocket/setGasInfo", payload: msgData.data}) store.dispatch({type: "websocket/setGasInfo", payload: msgData.data})
break; break;
} }
case "SumGasInfo": {
store.dispatch({type: "websocket/setSumGasInfo", payload: msgData.data})
break;
}
default: default:
} }
}, },
@ -41,54 +45,110 @@ export const getDcsMsg = () => {
export const getMesMsg = () => { export const getMesMsg = () => {
const sj = new Date().getTime() const sj = new Date().getTime()
// ISRA // ISRA
connectWebsocket( // connectWebsocket(
// 测试地址 // // 测试地址
'ws://10.70.2.2:8080/websocket/message?userId=KI'+sj, // 'ws://10.70.2.2:8080/websocket/message?userId=KI'+sj,
// 传递给后台的数据 // // 传递给后台的数据
'', // '',
// 成功拿到后台返回的数据的回调函数 // // 成功拿到后台返回的数据的回调函数
(data) => { // (data) => {
console.log('mes ISRA成功的回调函数, 接收到的data数据: ', data) // console.log('mes ISRA成功的回调函数, 接收到的data数据: ', data)
let msgData = JSON.parse(data) // let msgData = JSON.parse(data)
if (msgData == null) return; // if (msgData == null) return;
switch (msgData?.type) { // switch (msgData?.type) {
case "israKiln": { // case "israKiln": {
store.dispatch({type: "websocket/setIsraKiln", payload:msgData.detData.dayStatistic}) // store.dispatch({type: "websocket/setIsraKiln", payload:msgData.detData.dayStatistic})
break; // break;
} // }
// case "KilnInfo": { // // case "KilnInfo": {
// // store.dispatch({type: "websocket/setKilnInfo", payload: msgData.data.kilnInfo}) // // // store.dispatch({type: "websocket/setKilnInfo", payload: msgData.data.kilnInfo})
// break; // // break;
// } // // }
default: // default:
} // }
}, // },
// websocket连接失败的回调函数 // // websocket连接失败的回调函数
(err) => { // (err) => {
console.log('失败的回调函数', err) // console.log('失败的回调函数', err)
} // }
) // )
// 原料 MA // // 原料 MA
// connectWebsocket(
// // 测试地址
// 'ws://10.70.2.2:8080/websocket/message?userId=MA'+sj,
// // 传递给后台的数据
// '',
// // 成功拿到后台返回的数据的回调函数
// (data) => {
// console.log('mes 原料成功的回调函数, 接收到的data数据: ', data)
// let msgData = JSON.parse(data)
// if (msgData == null) return;
// switch (msgData?.type) {
// case "material": {
// store.dispatch({type: "websocket/setMaterial", payload:msgData.data})
// break;
// }
// // case "KilnInfo": {
// // // store.dispatch({type: "websocket/setKilnInfo", payload: msgData.data.kilnInfo})
// // break;
// // }
// default:
// }
// },
// // websocket连接失败的回调函数
// (err) => {
// console.log('失败的回调函数', err)
// }
// )
// 能耗 EN
// connectWebsocket(
// // 测试地址
// 'ws://10.70.2.2:8080/websocket/message?userId=ENERGY'+sj,
// // 传递给后台的数据
// '',
// // 成功拿到后台返回的数据的回调函数
// (data) => {
// console.log('mes 能耗成功的回调函数, 接收到的data数据: ', data)
// let msgData = JSON.parse(data)
// if (msgData == null) return;
// switch (msgData?.type) {
// case "EnergyInfo": {
// store.dispatch({type: "websocket/setEnergyInfo", payload:msgData.data})
// break;
// }
// default:
// }
// },
// // websocket连接失败的回调函数
// (err) => {
// console.log('失败的回调函数', err)
// }
// )
// 烟气 GAS
connectWebsocket( connectWebsocket(
// 测试地址 // 测试地址
'ws://10.70.2.2:8080/websocket/message?userId=MA'+sj, 'ws://10.70.2.2:8080/websocket/message?userId=GAS'+sj,
// 传递给后台的数据 // 传递给后台的数据
'', '',
// 成功拿到后台返回的数据的回调函数 // 成功拿到后台返回的数据的回调函数
(data) => { (data) => {
console.log('mes 原料成功的回调函数, 接收到的data数据: ', data) console.log('mes 烟气成功的回调函数, 接收到的data数据: ', data)
let msgData = JSON.parse(data) let msgData = JSON.parse(data)
if (msgData == null) return; if (msgData == null) return;
switch (msgData?.type) { switch (msgData?.type) {
case "material": { case "exhaustGas": {
store.dispatch({type: "websocket/setMaterial", payload:msgData.data}) store.dispatch({type: "websocket/setExhaustGasInfo", payload:msgData.realtime})
store.dispatch({type: "websocket/setExhaustGasChart", payload:{
dayTrend: msgData.dayTrend,
weekTrend: msgData.weekTrend,
monthTrend: msgData.monthTrend,
yearTrend: msgData.yearTrend,
}})
break; break;
} }
// case "KilnInfo": {
// // store.dispatch({type: "websocket/setKilnInfo", payload: msgData.data.kilnInfo})
// break;
// }
default: default:
} }
}, },

View File

@ -0,0 +1,34 @@
<template>
<div style="flex: 1;">
<Container name="产线缺陷统计" size="small">
<SelectorBtnGroup class="timeToggle" :options="['日', '周', '月', '年']" @emitFun='toggleDate' :active='chartTime' />
</Container>
</div>
</template>
<script>
import Container from '../components/Container';
import SelectorBtnGroup from '../components/SelectorBtnGroup';
export default {
name: 'DefectStatistics',
components: { Container, SelectorBtnGroup },
data() {
return {
chartTime:'日'
}
},
methods: {
//
toggleDate(val) {
console.log('时间' + val)
this.chartTime = val
}
}
}
</script>
<style lang='scss' scoped>
.timeToggle {
position: absolute;
right: 0;
}
</style>

View File

@ -4,7 +4,7 @@
style=" style="
display: grid; display: grid;
gap: 16px; gap: 16px;
grid-template-rows: 462px 462px; grid-template-rows: 308px 616px;
"> ">
<OrderStatus /> <OrderStatus />
<YieldRate /> <YieldRate />

View File

@ -4,19 +4,19 @@
style=" style="
display: grid; display: grid;
gap: 16px; gap: 16px;
grid-template-rows: 462px 462px; grid-template-rows: 605px 320px;
"> ">
<OrderStatus /> <GasHandle />
<YieldRate /> <DefectStatistics />
</div> </div>
</template> </template>
<script> <script>
import OrderStatus from './OrderStatus.vue'; import GasHandle from './../kiln/GasHandle';
import YieldRate from './YieldRate.vue'; import DefectStatistics from './DefectStatistics';
export default { export default {
name: 'MiddleFour', name: 'MiddleFour',
components: { OrderStatus, YieldRate }, components: { GasHandle, DefectStatistics },
props: {}, props: {},
data() { data() {
return {}; return {};

View File

@ -1,14 +1,155 @@
<template> <template>
<div style="flex: 1;"> <div style="flex: 1;">
<Container name="订单完成情况" size="small" style=""> <Container name="订单完成情况" size="small" class="wholeOrder">
digndna <div style="width: 100%;padding: 10px; 20px">
<el-table
:header-cell-style="{background:'rgba(4, 74, 132, 0.8)',color:'#fff',height: '40px',lineHeight: '40px', padding: 0,fontSize:'16px'}"
:row-style="setRowStyle"
:data="list"
height="225"
border
style="width: 100%; background: transparent"
>
<el-table-column
v-for="item in tableProps"
:key="item.prop"
:show-overflow-tooltip="item.showOverflowtooltip"
v-bind="item"
>
<template slot-scope="scope">
<component :is="item.subcomponent" v-if="item.subcomponent" :inject-data="{...scope.row, ...item}" @emitData="emitData" />
<span v-else>{{ scope.row[item.prop] | commonFilter(item.filter) }}</span>
</template>
</el-table-column>
<slot name="content" />
</el-table>
</div>
</Container> </Container>
</div> </div>
</template> </template>
<script> <script>
// :header-cell-style="{background:'rgba(79,114,136,0.29)',color:'#fff'}"
const tableProps = [
{
prop: 'time',
label: '添加时间',
filter: parseTime,
minWidth: 140
},
{
prop: 'name',
label: '订单名称',
minWidth: 120,
showOverflowtooltip: true
},
{
prop: 'code',
label: '订单编码',
minWidth: 180
},
{
prop: 'customerId',
label: '客户',
showOverflowtooltip: true
}
]
import Container from '../components/Container.vue'; import Container from '../components/Container.vue';
import { parseTime } from '@/utils/ruoyi'
export default { export default {
name: 'OrderStatus', name: 'OrderStatus',
filters: {
commonFilter: (source, filterType = a => a) => {
return filterType(source)
}
},
components: { Container }, components: { Container },
data() {
return {
tableProps,
list:[
{time: '2023-12-12', name: '名称名称'},
{time: '2023-12-13', name: '名称名称'},
{time: '2023-12-14', name: '名称名称'},
{time: '2023-12-15', name: '名称名称'},
{time: '2023-12-16', name: '名称名称'},
{time: '2023-12-17', name: '名称名称'},
{time: '2023-12-18', name: '名称名称'},
{time: '2023-12-19', name: '名称名称'},
{time: '2023-12-20', name: '名称名称'},
{time: '2023-12-21', name: '名称名称'}
]
}
},
mounted() {
},
methods:{
setRowStyle(v) {
if (v.rowIndex % 2 === 0) {
return {
background: 'rgba(11, 84, 153, 1)',
color: 'rgba(255,255,255,0.8)',
height: '40px',
lineHeight: '40px',
padding: 0,
fontSize: '16px'
}
} else {
return {
background: 'rgba(4, 74, 132, 1)',
color: 'rgba(255,255,255,0.8)',
height: '40px',
lineHeight: '40px',
padding: 0,
fontSize: '16px'
}
}
}
}
} }
</script> </script>
<style lang='scss'>
.wholeOrder {
.el-table {
border: 0;
}
.el-table::before,.el-table--border::after {
background-color: transparent;
}
.el-table th,td{
border-color: #0D1728 !important;
padding: 0;
}
.el-table tr {
background: transparent;
}
.el-table__row:hover > td {
background-color: rgba(79,114,136,0.29) !important;
}
.el-table__row--striped:hover > td {
background-color: rgba(79,114,136,0.29) !important;
}
// .el-table {
// border: 0;
// }
// .el-table::before,.el-table--border::after {
// background-color: transparent;
// }
// .el-table th,td{
// border-color: #0D1728 !important;
// padding: 0;
// }
// .el-table tr {
// background: transparent;
// }
// .el-table__row:hover > td {
// background-color: rgba(79,114,136,0.29) !important;
// }
// .el-table__row--striped:hover > td {
// background-color: rgba(79,114,136,0.29) !important;
// }
}
</style>

View File

@ -6,17 +6,17 @@
gap: 16px; gap: 16px;
grid-template-rows: 462px 462px; grid-template-rows: 462px 462px;
"> ">
<OrderStatus /> <EnergeCost />
<YieldRate /> <YieldRate />
</div> </div>
</template> </template>
<script> <script>
import OrderStatus from './OrderStatus.vue'; import EnergeCost from './../kiln/EnergeCost.vue';
import YieldRate from './YieldRate.vue'; import YieldRate from './YieldRate.vue';
export default { export default {
name: 'RightFour', name: 'RightFour',
components: { OrderStatus, YieldRate }, components: { EnergeCost, YieldRate },
props: {}, props: {},
data() { data() {
return {}; return {};

View File

@ -1,14 +1,127 @@
<template> <template>
<div style="flex: 1;"> <div style="flex: 2;" class="aaa">
<Container name="本日生产良品率" size="small" style=""> <Container name="本日生产良品率" size="small" style="">
0000987 <el-table
:header-cell-style="{background:'rgba(4, 74, 132, 0.8)',color:'#fff',height: '40px',lineHeight: '40px', padding: 0,fontSize:'16px'}"
:row-style="setRowStyle"
:data="list"
border
style="width: 100%; background: transparent"
>
<el-table-column
v-for="item in tableProps"
:key="item.prop"
:show-overflow-tooltip="item.showOverflowtooltip"
v-bind="item"
>
<template slot-scope="scope">
<component :is="item.subcomponent" v-if="item.subcomponent" :inject-data="{...scope.row, ...item}" @emitData="emitData" />
<span v-else>{{ scope.row[item.prop] | commonFilter(item.filter) }}</span>
</template>
</el-table-column>
<slot name="content" />
</el-table>
</Container> </Container>
</div> </div>
</template> </template>
<script> <script>
import Container from '../components/Container.vue'; const tableProps = [
{
prop: 'time',
label: '添加时间',
filter: parseTime,
minWidth: 140
},
{
prop: 'name',
label: '订单名称',
minWidth: 120,
showOverflowtooltip: true
},
{
prop: 'code',
label: '订单编码',
minWidth: 180
},
{
prop: 'customerId',
label: '客户',
showOverflowtooltip: true
}
]
import Container from '../components/Container';
import { parseTime } from '@/utils/ruoyi'
export default { export default {
name: 'YieldRate', name: 'YieldRate',
filters: {
commonFilter: (source, filterType = a => a) => {
return filterType(source)
}
},
components: { Container }, components: { Container },
data() {
return {
tableProps,
list:[
{time: '2023-12-12', name: '名称名称'},
{time: '2023-12-13', name: '名称名称'},
{time: '2023-12-14', name: '名称名称'},
{time: '2023-12-15', name: '名称名称'},
{time: '2023-12-16', name: '名称名称'},
{time: '2023-12-17', name: '名称名称'},
{time: '2023-12-18', name: '名称名称'},
{time: '2023-12-19', name: '名称名称'},
{time: '2023-12-20', name: '名称名称'},
{time: '2023-12-21', name: '名称名称'}
]
}
},
methods: {
setRowStyle(v) {
if (v.rowIndex % 2 === 0) {
return {
background: 'rgba(11, 84, 153, 1)',
color: 'rgba(255,255,255,0.8)',
height: '40px',
lineHeight: '40px',
padding: 0,
fontSize: '16px'
}
} else {
return {
background: 'rgba(4, 74, 132, 1)',
color: 'rgba(255,255,255,0.8)',
height: '40px',
lineHeight: '40px',
padding: 0,
fontSize: '16px'
}
}
}
}
} }
</script> </script>
<style lang='scss'>
.aaa {
.el-table {
border: 0;
}
.el-table::before,.el-table--border::after {
background-color: transparent;
}
.el-table th,td{
border-color: #0D1728 !important;
padding: 0;
}
.el-table tr {
background: transparent;
}
.el-table__row:hover > td {
background-color: rgba(79,114,136,0.29) !important;
}
.el-table__row--striped:hover > td {
background-color: rgba(79,114,136,0.29) !important;
}
}
</style>

View File

@ -8,8 +8,8 @@
position: absolute; position: absolute;
transform-origin: 16px 8px; transform-origin: 16px 8px;
font-size: 16px; font-size: 16px;
top: -8px; top: 0px;
left: -16px; left: 0px;
width: 1920px; width: 1920px;
height: 1080px; height: 1080px;
display: flex; display: flex;
@ -42,7 +42,6 @@ import MiddleTwo from './MiddleTwo';
import RightTwo from './RightTwo'; import RightTwo from './RightTwo';
import screenfull from 'screenfull' import screenfull from 'screenfull'
import { debounce } from '@/utils/debounce' import { debounce } from '@/utils/debounce'
import { getDcsMsg, getMesMsg } from './../utils/wsInterface'
export default { export default {
name: 'wholePlantBoard', name: 'wholePlantBoard',
@ -77,9 +76,6 @@ export default {
window.addEventListener('resize', () => { window.addEventListener('resize', () => {
this.boxReset() this.boxReset()
}) })
// closeWebsocket()
// getDcsMsg()
// getMesMsg()
console.log('mounted...........') console.log('mounted...........')
}, },
destroyed() { destroyed() {

176
src/websocket/websocket.js Normal file
View File

@ -0,0 +1,176 @@
/**
* 发起websocket请求函数
* @param {string} url ws连接地址
* @param {Object} agentData 传给后台的参数
* @param {function} successCallback 接收到ws数据对数据进行处理的回调函数
* @param {function} errCallback ws连接错误的回调函数
*/
export function WsConnect(url, agentData, successCallback, errCallback) {
this.wsUrl = url;
this.wsObj = null;
// 是否执行重连 true/不执行 false/执行
this.lockReconnect = false;
// 重连定时器
this.wsCreateHandler = null;
// 连接成功,执行回调函数
this.messageCallback = successCallback;
// 连接失败,执行回调函数
this.errorCallback = errCallback;
// 发送给后台的数据
this.sendDatas = agentData;
// 创建ws函数
this.createWebSoket = () => {
if (typeof WebSocket === "undefined") {
writeToScreen("您的浏览器不支持WebSocket无法获取数据");
return false;
}
try {
this.wsObj = new WebSocket(url);
initWsEventHandle();
} catch (e) {
writeToScreen("连接异常,开始重连");
reconnect();
}
};
// 手动关闭websocket 这里手动关闭会执行onclose事件
this.closeWebsocket = () => {
if (this.wsObj) {
writeToScreen("手动关闭websocket");
this.wsObj.close(); // 关闭websocket
// this.wsObj.onclose() // 关闭websocket(如果上面的关闭不生效就加上这一条)
// 关闭重连
this.lockReconnect = true;
this.wsCreateHandler && clearTimeout(this.wsCreateHandler);
// 关闭心跳检查
heartCheck.stop();
}
};
const initWsEventHandle = () => {
try {
// 连接成功
this.wsObj.onopen = (event) => {
onWsOpen(event);
heartCheck.start();
};
// 监听服务器端返回的信息
this.wsObj.onmessage = (event) => {
onWsMessage(event);
heartCheck.start();
};
this.wsObj.onclose = (event) => {
writeToScreen("onclose执行关闭事件");
onWsClose(event);
};
this.wsObj.onerror = (event) => {
writeToScreen("onerror执行error事件开始重连");
onWsError(event);
reconnect();
};
} catch (err) {
writeToScreen("绑定事件没有成功,开始重连");
reconnect();
}
};
const onWsOpen = (event) => {
writeToScreen("CONNECT");
// // 客户端与服务器端通信
// wsObj.send('我发送消息给服务端');
// 添加状态判断当为OPEN时发送消息
if (this.wsObj.readyState === this.wsObj.OPEN) {
// wsObj.OPEN = 1
// 发给后端的数据需要字符串化
this.wsObj.send(JSON.stringify(this.sendDatas));
}
if (this.wsObj.readyState === this.wsObj.CLOSED) {
// wsObj.CLOSED = 3
writeToScreen("wsObj.readyState=3, ws连接异常开始重连");
reconnect();
this.errorCallback(event);
}
};
const onWsMessage = (event) => {
const jsonStr = event.data;
writeToScreen("onWsMessage接收到服务器的数据: ", jsonStr);
this.messageCallback(jsonStr);
};
const onWsClose = (event) => {
writeToScreen("DISCONNECT");
// e.code === 1000 表示正常关闭。 无论为何目的而创建, 该链接都已成功完成任务。
// e.code !== 1000 表示非正常关闭。
console.log("onclose event: ", event);
if (event && event.code !== 1000) {
writeToScreen("非正常关闭");
this.errorCallback(event);
// 如果不是手动关闭,这里的重连会执行;如果调用了手动关闭函数,这里重连不会执行
reconnect();
}
};
const onWsError = (event) => {
writeToScreen("onWsError: ", event.data);
this.errorCallback(event);
};
const writeToScreen = (massage) => {
console.log(massage);
};
// 重连函数
const reconnect = () => {
if (this.lockReconnect) {
return;
}
writeToScreen("3秒后重连");
this.lockReconnect = true;
// 没连接上会一直重连,设置延迟避免请求过多
this.wsCreateHandler && clearTimeout(this.wsCreateHandler);
this.wsCreateHandler = setTimeout(() => {
writeToScreen("重连..." + this.wsUrl);
this.createWebSoket();
this.lockReconnect = false;
writeToScreen("重连完成");
}, 3000);
};
// 心跳检查看看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 };
this.wsObj.send(JSON.stringify(datas));
} catch (err) {
writeToScreen("发送ping异常");
}
console.log("内嵌定时器this.serverTimeoutObj: ", this.serverTimeoutObj);
// 内嵌定时器
this.serverTimeoutObj = setTimeout(() => {
writeToScreen("没有收到后台的数据,重新连接");
reconnect();
}, this.timeout);
}, this.timeout);
},
};
}

View File

@ -0,0 +1,160 @@
import { WsConnect } from './websocket'
import store from "@/store";
// 创建websocket链接
const timestr = new Date().getTime()
const dcsConn = new WsConnect(
// websocket地址
'ws://10.70.180.10:8081/xc-screen/websocket/dcsmsg'+timestr,
// 传递给后台的数据
'',
(data) => {
// console.log('dcs成功的回调函数, 接收到的data数据: ', data)
let msgData = JSON.parse(data)
if (msgData == null) return;
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})
break;
}
case "GasInfo": {
store.dispatch({type: "websocket/setGasInfo", payload: msgData.data})
break;
}
case "SumGasInfo": {
store.dispatch({type: "websocket/setSumGasInfo", payload: msgData.data})
break;
}
default:
}
},
(err) => {
console.log('失败的回调函数', err)
}
)
const mesIsra = new WsConnect(
'ws://10.70.2.2:8080/websocket/message?userId=KILN'+timestr,
'',
(data) => {
// console.log('mes ISRA成功的回调函数, 接收到的data数据: ', data)
let msgData = JSON.parse(data)
// console.log(msgData)
if (msgData == null) return;
switch (msgData?.type) {
case "israKiln": {
store.dispatch({type: "websocket/setIsraKiln", payload:msgData.detData.dayStatistic})
break;
}
// case "KilnInfo": {
// // store.dispatch({type: "websocket/setKilnInfo", payload: msgData.data.kilnInfo})
// break;
// }
default:
}
},
(err) => {
console.log('失败的回调函数', err)
}
)
// 原料 MA
const mesMA = new WsConnect(
'ws://10.70.2.2:8080/websocket/message?userId=MA'+timestr,
'',
(data) => {
// console.log('mes 原料成功的回调函数, 接收到的data数据: ', data)
let msgData = JSON.parse(data)
if (msgData == null) return;
switch (msgData?.type) {
case "material": {
store.dispatch({type: "websocket/setMaterial", payload:msgData.data})
break;
}
// case "KilnInfo": {
// // store.dispatch({type: "websocket/setKilnInfo", payload: msgData.data.kilnInfo})
// break;
// }
default:
}
},
(err) => {
console.log('失败的回调函数', err)
}
)
// 能耗 EN
const mesEN = new WsConnect(
// websocket地址
'ws://10.70.2.2:8080/websocket/message?userId=ENERGY'+timestr,
// 传递给后台的数据
'',
// 成功拿到后台返回的数据的回调函数
(data) => {
// console.log('mes 能耗成功的回调函数, 接收到的data数据: ', data)
let msgData = JSON.parse(data)
if (msgData == null) return;
switch (msgData?.type) {
case "EnergyInfo": {
store.dispatch({type: "websocket/setEnergyInfo", payload:msgData.data})
break;
}
case "EnergyTrend": {
store.dispatch({type: "websocket/setEnergyTrend", payload:msgData.data})
break;
}
default:
}
},
// websocket连接失败的回调函数
(err) => {
console.log('失败的回调函数', err)
}
)
// 烟气 GAS
const mesGAS = new WsConnect(
// websocket地址
'ws://10.70.2.2:8080/websocket/message?userId=GAS'+timestr,
// 传递给后台的数据
'',
// 成功拿到后台返回的数据的回调函数
(data) => {
// console.log('mes 烟气成功的回调函数, 接收到的data数据: ', data)
let msgData = JSON.parse(data)
if (msgData == null) return;
switch (msgData?.type) {
case "exhaustGas": {
store.dispatch({type: "websocket/setExhaustGasInfo", payload:msgData.realtime})
store.dispatch({type: "websocket/setExhaustGasChart", payload:{
dayTrend: msgData.dayTrend,
weekTrend: msgData.weekTrend,
monthTrend: msgData.monthTrend,
yearTrend: msgData.yearTrend,
}})
break;
}
default:
}
},
// websocket连接失败的回调函数
(err) => {
console.log('失败的回调函数', err)
}
)
export const getDcsMsg = () => {
dcsConn.createWebSoket()
mesIsra.createWebSoket()
mesMA.createWebSoket()
mesEN.createWebSoket()
mesGAS.createWebSoket()
}
export const closeDcsMsg = () => {
dcsConn.closeWebsocket()
mesIsra.closeWebsocket()
mesMA.closeWebsocket()
mesEN.closeWebsocket()
mesGAS.closeWebsocket()
}