yudao-dev/src/views/OperationalOverview/coldBoard.vue
‘937886381’ 8b1dbbeeea 修改
2024-01-04 08:33:05 +08:00

795 lines
24 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!--
* @Author: zwq
* @Date: 2021-07-19 15:18:30
* @LastEditors: zhp
* @LastEditTime: 2024-01-02 10:07:03
* @Description:
-->
<template>
<div id="container" ref="container" class="visual-container" :style="styles">
<el-row class="container-title" :style="{
height: 88 + 'px',
lineHeight: 88 + 'px',
fontSize: 31 + 'px'
}">
<img src="../../assets/img/logo.png" style="width:1.1em;position:relative;top:.4em" alt="">
许昌安彩冷端看板
<h3 class="unit">单位河南汇融科技服务有限公司</h3>
<h3 class="time">{{ times }}</h3>
<!-- <el-button
type="text"
class="title-button"
:style="{ right: 33 + 'px', top: 37 + 'px' }"
@click="changeFullScreen"
>
<svg-icon v-if="isFullScreen" icon-class="unFullScreenView" />
<svg-icon v-else icon-class="fullScreenView" />
</el-button> -->
</el-row>
<el-row class="container-main flex-col" type="flex">
<el-row :style="{ padding: '0 ' + 9 + 'px' }" :gutter="15" type="flex" class="flex-1">
<el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="8">
<base-container :title="'切割数据'" :title-icon="'eqAlarm'">
<base-table1 :page="1" :limit="9" :show-index="false" :table-config="cutProps"
:table-data="cutTableDataList" />
</base-container>
</el-col>
<el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="8">
<base-container :title="'产量及良率统计'" :title-icon="'productLine'">
<!-- <div style="width: 45%;position: absolute; top: 3em; right: 3em;">
<top-radio-group />
</div> -->
<!-- 像下面这样表格里的limit值也许可以用js动态计算出来 -->
<double-y-chart ref="productChart" :id="'doubleYChart'" :name-list="cxNameList" :data-list="cxDataList" :height="359"
:show-legend="true" />
</base-container>
</el-col>
<el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="8">
<base-container :title="'ISRA 缺陷数据'" :title-icon="'eqMonitoring'">
<base-table1 :page="1" :limit="9" :show-index="false" :table-config="ISRATableProps"
:table-data="ISRAList" />
</base-container>
</el-col>
</el-row>
<el-row :style="{ padding: '0 ' + 9 + 'px' }" :gutter="10" type="flex" class="flex-1">
<el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="12">
<base-container :height="256" :title="'废片 缺陷数据'" :title-icon="'energyMonitoring'">
<!-- <div style="width: 45%;position: absolute; top: 3em; right: 3em;">
<top-radio-group />
</div> -->
<!-- <el-row :gutter="9"> -->
<!-- <el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="24"> -->
<pile-bar-chart ref="pileChart" :name-list="EnergyMonitoringNameList" :data-list="EnergyMonitoringList"
:height="359" />
<!-- </el-col> -->
<!-- <el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="12">
<base-table3
:page="2"
:limit="5"
:table-config="qualityTableProps2"
:table-data="qualityList2"
/>
</el-col> -->
<!-- </el-row> -->
</base-container>
</el-col>
<el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="14">
<base-container :height="318 + 338 + 16" :title="'设备状态监控'" :title-icon="'scrap'">
<!-- <div style="width: 45%;position: absolute; top: 3em; right: 3em;">
<top-radio-group />
</div> -->
<!-- 像下面这样表格里的limit值也许可以用js动态计算出来 -->
<el-col :span="6">
<base-table1 :page="1" :limit="9" :show-index="false" :table-config="EqMonitoringPropsFun"
:table-data="funList" />
</el-col>
<el-col :span="6">
<base-table1 :page="1" :limit="9" :show-index="false" :table-config="EqMonitoringPropsFun"
:table-data="annealFunList" />
</el-col>
<el-col :span="12" style="float: right;">
<base-table1 :page="1" :limit="9" :show-index="false" :table-config="EqMonitoringProps"
:table-data="realEqList" />
</el-col>
<!-- <double-y-chart :id="'doubleYChart'" :name-list="cxNameList" :data-list="cxDataList" :height="359"
:show-legend="true" /> -->
</base-container>
</el-col>
</el-row>
<!-- end -->
<!-- <el-col :span="16">
<el-row>
<el-col :style="{ margin: 8 + 'px' + ' 0' }" :span="24">
<base-container :height="672">
<base-video :video-height="624" />
</base-container>
</el-col>
</el-row>
</el-col>
-->
</el-row>
</div>
</template>
<script>
import baseContainer from './components/baseContainer'
import baseTable1 from './components/baseTable'
// import baseTable2 from './components/baseTable'
// import baseTable3 from './components/baseTable'
import TopRadioGroup from './components/topRadioGroup'
// import pieChart1 from './components/PieChart'
// import pieChart2 from './components/PieChart'
// import pieChart3 from './components/PieChart'
// import { mapGetters } from 'vuex'
import screenfull from 'screenfull'
// import BaseVideo from './components/baseVideo.vue'
import alarmLevel from './components/alarmLevel'
import pileBarChart from './components/pileBarChart'
// import axios from '@/utils/request'
import doubleYChart from './components/doubleYChart '
// import elementResizeDetectorMaker from 'element-resize-detector';
// var erd = elementResizeDetectorMaker(); //创建实例
// let resizeFun = null
import { parseTime } from '../core/mixins/code-filter';
import LinearBarChart from './components/linearBarChart'
const qualityYearTableProps= []
const EqMonitoringPropsFun = [
{ prop: 'equipmentName', label: '设备名称' },
{ prop: 'status', label: '运行状态', width: 80}
]
const EqMonitoringProps = [
{ prop: 'productLine', label: '产线' },
{ prop: 'equipmentName', label: '设备名称' },
{ prop: 'equipmentCode', label: '设备编码' },
{
prop: 'status',
label: '运行状态',
filter: (val) =>
val != null ? ['正常', '计划停机', '故障'][val] : '',
},
{
prop: 'error',
label: '故障状态',
filter: (val) => (val != null ? (val ? '是' : '否') : ''),
},
]
const cutProps = [
{ prop: 'lineName', label: '产线', width: 50 },
{
prop: 'time', label: '时间',
filter: parseTime
},
{ prop: 'size', label: '规格' },
{ prop: 'productArea', label: '良品面积', width: 80 },
{ prop: 'wasteArea', label: '废片面积', width: 80 },
{ prop: 'product', label: '良品率', width: 80 },
]
const cxNameList = ['周一', '周二', '周三', '周四', '周五']
const cxDataList = [
{
topColor: '#9DD5FF',
bottomColor: '#1295FF',
name: '电耗能',
data: [100, 150, 121, 97, 140]
},
{
topColor: '#FF8BC3',
bottomColor: '#EB46A1',
name: '水耗能',
data: [110, 110, 151, 77, 110]
},
{
topColor: '#85F6E9',
bottomColor: '#2EC6B4',
name: '天然气',
data: [110, 120, 171, 287, 40]
},
{
topColor: '#9496FF',
bottomColor: '#6567FF',
name: '焦炉煤气',
data: [140, 157, 122, 27, 240]
},
{
topColor: '#F68E8A',
bottomColor: '#E95552',
name: '余热发电',
data: [170, 180, 127, 17, 340]
},
{
topColor: '#FFE873',
bottomColor: '#E7AE2A',
name: '二氧化硫',
data: [140, 160, 121, 57, 170]
}
]
const ISRATableProps = [
{
prop: 'linename',
label:'产线'
},
{
prop: 'time',
label: '时间'
},
{
prop: 'type',
label:'缺陷类型'
},
{
prop: 'num',
label: '缺陷数量'
},
{
prop: 'percent',
label: '占比'
}
]
export default {
name: 'ProductionMonitoringCockpit',
components: {
baseContainer,
baseTable1,
pileBarChart,
TopRadioGroup,
doubleYChart,
LinearBarChart
// pieChart1,
// pieChart2
// pieChart3
// BaseVideo
},
data() {
return {
beilv2: 1,
beilv: 1,
value: 100,
EqMonitoringProps,
EqMonitoringPropsFun,
realEqList:[],
qualityYearTableProps,
ISRATableProps,
orderList: [],
times: '',
ISRAList:[],
EnergyMonitoringNameList: [],
equipmentList: [],
EnergyMonitoringList: [],
// offsetWidth: null,
cxNameList,
cxDataList,
cutProps,
cutTableDataList:[],
clientWidth: 0,
containerWidth: 111111,
isFullScreen: false,
cutWsData: {},
funWsData: {},
SJGWsData: {},
// orderProcessList: [],
dateType: '0',
funList:[],
annealFunList: [],
queryParams: {
pageNo: 1,
pageSize: 10,
equipmentId: null,
productionLineId: null,
},
}
},
computed: {
// ...mapGetters(['sidebar']),
styles() {
const v = Math.floor(this.value * this.beilv2 * 100) / 10000
return {
transform: `scale(${v})`,
transformOrigin: 'top left'
}
}
},
watch: {
clientWidth(val) {
if (!this.timer) {
this.clientWidth = val
this.beilv2 = this.clientWidth / 1920
this.timer = true
let _this = this
setTimeout(function () {
_this.timer = false
}, 500)
}
// 这里可以添加修改时的方法
this.windowWidth(val);
}
},
created() {
// this.fetchList('exception-alarm')
// this.fetchList('inAndOutOfEachLine')
// this.fetchList('order-process')
// this.fetchList('line-chart-data')
this.init()
},
mounted() {
this.funInitWebSocket()
this.CutInitWebSocket()
this.SJGInitWebSocket()
this.getTimes()
const _this = this;
_this.beilv2 = document.documentElement.clientWidth / 1920
window.onresize = () => {
return (() => {
_this.clientWidth = `${document.documentElement.clientWidth}`
this.beilv2 = _this.clientWidth / 1920
})()
}
this.getList()
// const _this = this;
// window.onresize = () => {
// return (() => {
// _this.clientWidth = `${document.documentElement.clientWidth}`
// this.beilv2 = _this.clientWidth / 1920
// })()
// }
// this.beilv2 = window.innerWidth / 1920
// addEventListener('resize', resizeFun = () => {
// this.beilv2 = window.innerWidth / 1920
// })
// erd.listenTo(document, (element) => {
// this.beilv2 = element.offsetWidth / 1920
// // var width = element.offsetWidth;
// // var height = element.offsetHeight;
// });
},
// beforeDestroy() {
// //离开页面删除检测器和所有侦听器
// // erd.uninstall(document); //这里用ref是因为vue离开页面后获取不到dom
// removeEventListener('resize', resizeFun)
// },
methods: {
getList() {
// this.loading = true;
// 执行查询
// let data = '{ "data": { "FanFrequencyInfo": { "1#10处拐角冷却风机": "0", "1#L型吊墙冷却风机": "0", "1#助燃风机": "44.8", "1#澄清带池壁风机": "40", "1#融化带池壁风机": "43", "1#钢碹碴小炉垛风机": "48", "2#10处拐角冷却风机": "50", "2#L型吊墙冷却风机": "49.7", "2#助燃风机": "0", "2#澄清带池壁风机": "0", "2#融化带池壁风机": "0", "2#钢碹碴小炉垛风机": "48", "3#澄清带池壁风机": "0", "3#融化带池壁风机": "0", "4#澄清带池壁风机": "40", "4#融化带池壁风机": "43" } }, "type": "FanFrequencyInfo" }'
// let obj = JSON.parse(data)
// // for()
// let arr = []
// for (let i in obj.data.FanFrequencyInfo) {
// arr.push({
// equipmentName: i,
// status: obj.data.FanFrequencyInfo[i]
// })
// }
// this.funList = arr``
this.$axios.get(
'/monitoring/equipment-monitor/realtime-page',
'get',
this.queryParams
).then((res) => {
this.realEqList = res.data.list;
// this.total = response.data.total;
// this.loading = false;
});
},
getTimes() {
setInterval(this.getTimesInterval, 1000);
},
getTimesInterval: function () {
let _this = this;
let year = new Date().getFullYear(); //获取当前时间的年份
let month = new Date().getMonth() + 1; //获取当前时间的月份
let day = new Date().getDate(); //获取当前时间的天数
let hours = new Date().getHours(); //获取当前时间的小时
let minutes = new Date().getMinutes(); //获取当前时间的分数
let seconds = new Date().getSeconds(); //获取当前时间的秒数
//当小于 10 的是时候,在前面加 0
if (hours < 10) {
hours = "0" + hours;
}
if (minutes < 10) {
minutes = "0" + minutes;
}
if (seconds < 10) {
seconds = "0" + seconds;
}
//拼接格式化当前时间
this.times = year + "-" + month + "-" + day + " " + hours + ":" + minutes + ":" + seconds;
},
SJGInitWebSocket() {
if (typeof (WebSocket) === 'undefined') {
alert('您的浏览器不支持WebSocket')
} else {
// const wsUrl = 'ws://192.168.1.74:48080/websocket/message?userId=EN111'
// const wsUrl = 'ws://192.168.1.104:48082/websocket/message?userId=SJG'
let date = new Date().valueOf()
const SJGWsUrl = `ws://10.70.2.2:8080/websocket/message?userId=COLD${date}`
this.SJGWebsocket = new WebSocket(SJGWsUrl)
// 监听 WebSocket 连接
this.SJGWebsocket.onopen = this.SJGWebsocketOnOpen
// 监听 WebSocket 错误信息
this.SJGWebsocket.onerror = this.SJGWebsocketOnError
// 监听 WebSocket 消息
this.SJGWebsocket.onmessage = this.SJGWebsocketOnMessage
// 监听 webSocket 断开信息
this.SJGWebsocket.onclose = this.SJGWebsocketClose
}
},
CutInitWebSocket() {
if (typeof (WebSocket) === 'undefined') {
alert('您的浏览器不支持WebSocket')
} else {
// const wsUrl = 'ws://192.168.1.74:48080/websocket/message?userId=EN111'
// const wsUrl = 'ws://192.168.1.104:48082/websocket/message?userId=SJG'
let date = new Date().valueOf()
const cutWsUrl = `ws://10.70.2.2:8080/websocket/message?userId=CUTTING${date}`
this.cutWebsocket = new WebSocket(cutWsUrl)
// 监听 WebSocket 连接
this.cutWebsocket.onopen = this.cutWebsocketOnOpen
// 监听 WebSocket 错误信息
this.cutWebsocket.onerror = this.cutWebsocketOnError
// 监听 WebSocket 消息
this.cutWebsocket.onmessage = this.cutWebsocketOnMessage
// 监听 webSocket 断开信息
this.cutWebsocket.onclose = this.cutWebsocketClose
}
},
funInitWebSocket() {
if (typeof (WebSocket) === 'undefined') {
alert('您的浏览器不支持WebSocket')
} else {
// const wsUrl = 'ws://192.168.1.74:48080/websocket/message?userId=EN111'
// const wsUrl = 'ws://192.168.1.104:48082/websocket/message?userId=SJG'
let date = new Date().valueOf()
const funWsUrl = `ws://10.70.180.10:8081/xc-screen/websocket/${date}`
this.funWebsocket = new WebSocket(funWsUrl)
// 监听 WebSocket 连接
this.funWebsocket.onopen = this.funWebsocketOnOpen
// 监听 WebSocket 错误信息
this.funWebsocket.onerror = this.funWebsocketOnError
// 监听 WebSocket 消息
this.funWebsocket.onmessage = this.funWebsocketOnMessage
// 监听 webSocket 断开信息
this.funWebsocket.onclose = this.funWebsocketClose
}
},
funWebsocketOnOpen() {
console.log('socket连接成功')
this.SJGWebsocket.onmessage()
},
// 连接建立失败重连
funWebsocketOnError(e) {
this.funInitWebSocket()
},
// 数据接收
funWebsocketOnMessage(e) {
this.funWsData = e?.data ? JSON.parse(e?.data) : {}
// FanInfo
if (this.funWsData.type === 'AnnealFanInfo') {
let arr = []
for (let i in this.funWsData.data.annealFanInfo) {
arr.push({
equipmentName: i,
status: this.funWsData.data.annealFanInfo[i]
})
}
this.annealFunList = arr
}
if (this.funWsData.type === 'FanInfo') {
let arr = []
for (let i in this.funWsData.data.fanInfo) {
arr.push({
equipmentName: i,
status: this.funWsData.data.fanInfo[i]
})
}
this.funList = arr
}
},
cutWebsocketOnOpen() {
console.log('socket连接成功')
this.SJGWebsocket.onmessage()
},
// 连接建立失败重连
cutWebsocketOnError(e) {
this.CutInitWebSocket()
},
// 数据接收
cutWebsocketOnMessage(e) {
this.cutWsData = e?.data ? JSON.parse(e?.data) : {}
if (this.cutWsData.type === 'cutting' && this.cutWsData.name === 'table') {
this.cutTableDataList = this.cutWsData.productHourData.map((ele, index) => {
// if (ele.progressRate != 1) {
return {
id: ele.id,
lineName: ele.lineName,
time: ele.time,
size: ele.size,
productArea: ele.productArea + '㎡',
wasteArea: ele.wasteArea + '㎡',
product: (ele.product * 100).toFixed(2) + '%'
}
// }
});
} else if (this.cutWsData.type === 'cutting' && this.cutWsData.name === 'chart' && this.cutWsData.dateType === 'day') {
let nameList = []
let nameWasteList = []
let topNameList = []
let productList = []
let wasteList = []
let sumAreaList = []
let yieldList = []
// this.cutTableDataList =
this.cutWsData.coldDetData.forEach((ele, index) => {
nameList.push(ele.lineName)
topNameList.push('产线: ' + ele.lineName + ' ' + '总面积:' + ele.sumArea)
productList.push(ele.productArea)
wasteList.push(ele.wastArea)
nameWasteList.push('缺陷面积:' + ele.wastArea)
sumAreaList.push(ele.sumArea)
yieldList.push((ele.yield *100).toFixed(3))
})
this.$refs.pileChart.initChart(nameList, topNameList, nameWasteList, productList, wasteList)
this.$refs.productChart.initChart(nameList, yieldList, sumAreaList)
}
},
SJGWebsocketOnOpen() {
console.log('socket连接成功')
this.SJGWebsocket.onmessage()
},
// 连接建立失败重连
SJGWebsocketOnError(e) {
this.SJGInitWebSocket()
},
// 数据接收
SJGWebsocketOnMessage(e) {
// let data = { "data": { "FanFrequencyInfo": { "1#10处拐角冷却风机": "0", "1#L型吊墙冷却风机": "0", "1#助燃风机": "44.8", "1#澄清带池壁风机": "40", "1#融化带池壁风机": "43", "1#钢碹碴小炉垛风机": "48", "2#10处拐角冷却风机": "50", "2#L型吊墙冷却风机": "49.7", "2#助燃风机": "0", "2#澄清带池壁风机": "0", "2#融化带池壁风机": "0", "2#钢碹碴小炉垛风机": "48", "3#澄清带池壁风机": "0", "3#融化带池壁风机": "0", "4#澄清带池壁风机": "40", "4#融化带池壁风机": "43" } }, "type": "FanFrequencyInfo" }
// let obj = JSON.parse(data.data)
this.SJGWsData = e?.data ? JSON.parse(e?.data) : {}
if (this.SJGWsData.type === 'isra') {
this.ISRAList = this.SJGWsData.detData.map((ele, index) => {
// if (ele.progressRate != 1) {
return {
id: ele.id,
linename: ele.linename,
type: ele.type,
num: ele.num,
time:ele.time,
percent: ele.percent
}
// }
});
}
},
windowWidth(value) {
this.clientWidth = value
this.beilv2 = this.clientWidth / 1920
},
// fetchList(type) {
// switch (type) {
// case 'order-process':
// return axios({
// url: '/analysis/factory-monitor/order',
// method: 'post'
// }).then(res => {
// if (res.data) {
// this.orderProcessList = res.data
// // this.orderProcessList = [
// // { id: 1, name: '订单1', outRate: 0.5 },
// // { id: 2, name: '订单2', outRate: 0.54 },
// // { id: 3, name: '订单3', outRate: 0.45 },
// // { id: 4, name: '订单4', outRate: 0.65 },
// // { id: 5, name: '订单5', outRate: 0.35 },
// // { id: 6, name: '订单6', outRate: 0.15 },
// // { id: 7, name: '订单7', outRate: 0.5 },
// // { id: 8, name: '订单8', outRate: 0.5 }
// // ]
// } else {
// this.orderProcessList.splice(0)
// }
// })
// }
// },
change() {
this.isFullScreen = screenfull.isFullscreen
},
init() {
if (screenfull.enabled) {
screenfull.on('change', this.change)
}
},
destroy() {
if (screenfull.enabled) {
screenfull.off('change', this.change)
}
},
changeFullScreen() {
this.containerWidth = 223223223
if (!screenfull.enabled) {
this.$message({
message: 'you browser can not work',
type: 'warning'
})
return false
}
screenfull.toggle(this.$refs.container)
}
}
}
</script>
<style lang="scss" scoped>
.visual-container {
width: 1920px;
height: 1080px;
background: url('../../assets/img/OperationalOverview/back.png') no-repeat;
background-size: cover;
// opacity: .8;
.container-title {
width: 100%;
background: url('../../assets/img/OperationalOverview/title.png') no-repeat;
background-size: 100% 100%;
color: #00fff0;
text-align: center;
.unit {
position: absolute;
left: 260px;
top: 25px;
font-size: 20px;
}
.time {
position: absolute;
left: 1360px;
top: 25px;
font-size: 20px;
}
.title-button {
color: #00fff0;
font-size: 20px;
position: absolute;
}
}
.container-main {
padding: 10px;
}
}
.now-team-title {
margin: 0;
margin-top: -1em;
font-size: 1.2em;
line-height: 2em;
color: #fff;
}
.main-title {
text-align: center;
}
.now-secondary-title {
margin: 0;
font-size: 1em;
line-height: 2em;
color: #fff;
}
.now-team-content {
font-size: 3em;
line-height: 1em;
color: #52fff1;
text-align: center;
}
::v-deep .el-progress-bar__inner {
background-color: unset;
background-image: linear-gradient(to right, #4573fe, #47f8dc);
}
.visual-select {
position: absolute;
right: 1em;
top: 2em;
}
// .container-main {
// padding: 5px;
// }
</style>
<style lang="scss">
.visual-container {
::-webkit-scrollbar {
width: 8px;
height: 8px;
background-color: transparent;
}
::-webkit-scrollbar-track-piece {
background: #1b2b3d;
}
::-webkit-scrollbar-corner {
background: #1b2b3d;
}
::-webkit-scrollbar-track {
width: 6px;
background: #1b2b3d;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
}
::-webkit-scrollbar-thumb {
background: rgba($color: #5bc4be, $alpha: 0.7);
background-clip: padding-box;
min-height: 28px;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
transition: background-color 0.3s;
cursor: pointer;
}
::-webkit-scrollbar-thumb:hover {
background-color: rgba($color: #5bc4be, $alpha: 1);
}
}
.coldSelect {
.el-input {
min-height: 10px;
}
.el-input__inner {
background-color: rgba($color: #31878c, $alpha: 0.29);
border: rgba($color: #31878c, $alpha: 0.29);
color: aliceblue;
}
.el-divider--vertical {
height: 174px;
width: 1px;
border: rgba(255, 255, 255, 0.15);
color: rgba(255, 255, 255, 0.15);
margin-left: 3em;
}
}
</style>
<style scoped>
.flex-col {
flex-direction: column;
}
.flex-1 {
flex: 1 1;
}
.h-full {
height: calc(100vh - 150px);
}
/* .container-main {
min-height: calc(100vh - 10em);
} */
</style>