| | |
| | | <!-- |
| | | * @Date: 2024-04-09 22:11:21 |
| | | * @LastEditors: gaoshp |
| | | * @LastEditTime: 2024-10-09 20:40:22 |
| | | * @LastEditors: lzhe lzhe@example.com |
| | | * @LastEditTime: 2024-11-04 11:19:09 |
| | | * @FilePath: /cps-web/src/views/mdc/realtime-status/index.vue |
| | | 实时看板 |
| | | --> |
| | |
| | | <div class="status-card-box" style="border-color: #ccc;"> |
| | | <div class="status-card-top"> |
| | | <div class="status-card-detail"> |
| | | <div title="461" class="status-card-detail-name">{{ item.code }}</div> |
| | | <div class="status-card-detail-name" :title="item.name">{{ item.name }}</div> |
| | | <div class="status-card-detail-status"> |
| | | <div class="status-card-detail-point" :style="{ 'background-color': item.statusStyle }"> |
| | | </div>{{ item.statusName }} |
| | | <div class="status-card-detail-time" :style="{ 'color': item.statusStyle }">{{ item.time |
| | | }} |
| | | <div class="status-card-detail-time" :style="{ 'color': item.statusStyle }">{{ item.time }} |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <div class="status-card-machine" style="border-color: #ccc;"> |
| | | <div class="status-card-machine-img"> |
| | | <img src="./station1.jpg" width="68" height="68"> |
| | | <img :src="item.avatar" width="68" height="68"> |
| | | |
| | | </div> |
| | | <div class="status-card-machine-mesg"> |
| | |
| | | </div> |
| | | </div> |
| | | </div> |
| | | <el-dialog :title="titleMap" v-model="visible" :width="740"> |
| | | <el-dialog :title="titleMap" v-model="visible" :width="740" v-if="visible"> |
| | | <div class="dialogstyle"> |
| | | <div class="realtime-analysis-card" v-for="item in timestatus[clickIndex].properties"> |
| | | <div class="card-name" :style="{ 'background-color': item.color }">{{ item.name }}</div> |
| | | <div class="card-value" |
| | | :class="{ 'card-value': true, 'card-value-bg1': item.key != 'Alarm', 'card-value-bg2': item.key == 'Alarm' }"> |
| | | {{ item.code }}</div> |
| | | </div> |
| | | <el-table :data="timestatus[clickIndex].properties" style="width: 100%" border> |
| | | <el-table-column prop="name" label="数据点"></el-table-column> |
| | | <el-table-column prop="code" label="值"></el-table-column> |
| | | <el-table-column prop="moment" label="采集时间"></el-table-column> |
| | | </el-table> |
| | | </div> |
| | | </el-dialog> |
| | | </div> |
| | | </template> |
| | | |
| | | <script> |
| | | import station from "./station1.jpg"; |
| | | import moment from 'moment'; |
| | | import * as ElementPlusIconsVue from '@element-plus/icons-vue' |
| | | let icons = [] |
| | |
| | | }, |
| | | data() { |
| | | return { |
| | | station: station, |
| | | clickIndex: 0, |
| | | allwcs: [], |
| | | statusStyle: "#ccc", |
| | |
| | | } |
| | | }) |
| | | }, |
| | | setIntervalTime() { |
| | | function addTime(timeStr) { |
| | | var increaseByMilliseconds = 10 * 1000; // 10秒转换为毫秒 |
| | | // 解析时间字符串为天数、小时、分钟和秒 |
| | | if (timeStr != undefined && timeStr != "--") { |
| | | var parts = timeStr.match(/(\d+)天(\d+)时(\d+)分(\d+)秒/); |
| | | var days = parseInt(parts[1], 10) * 24 * 60 * 60 * 1000; // 天数转换为毫秒 |
| | | var hours = parseInt(parts[2], 10) * 60 * 60 * 1000; // 小时转换为毫秒 |
| | | var minutes = parseInt(parts[3], 10) * 60 * 1000; // 分钟转换为毫秒 |
| | | var seconds = parseInt(parts[4], 10) * 1000; // 秒转换为毫秒 |
| | | // 创建一个Moment.js的持续时间对象 |
| | | var duration = moment.duration(days + hours + minutes + seconds); |
| | | // 增加时间 |
| | | duration.add(increaseByMilliseconds); // 增加10秒 |
| | | // 将持续时间转换回天数、小时、分钟和秒(注意这里可能不完全精确,因为天数可能不是整数) |
| | | var totalMilliseconds = duration.asMilliseconds(); |
| | | var totalDays = Math.floor(totalMilliseconds / (1000 * 60 * 60 * 24)); |
| | | var remainingMilliseconds = totalMilliseconds % (1000 * 60 * 60 * 24); |
| | | var totalHours = Math.floor(remainingMilliseconds / (1000 * 60 * 60)); |
| | | remainingMilliseconds %= (1000 * 60 * 60); |
| | | var totalMinutes = Math.floor(remainingMilliseconds / (1000 * 60)); |
| | | remainingMilliseconds %= (1000 * 60); |
| | | var totalSeconds = Math.floor(remainingMilliseconds / 1000); |
| | | return `${totalDays}天${totalHours}时${totalMinutes}分${totalSeconds}秒`; |
| | | } else { |
| | | return timeStr; |
| | | } |
| | | } |
| | | setInterval(() => { |
| | | if (this.timestatus.length != 0) { |
| | | this.timestatus.forEach(item => { |
| | | item.time = addTime(item.time); |
| | | }) |
| | | } |
| | | }, 1000 * 10) |
| | | }, |
| | | changestationlabel(name) { |
| | | this.stationlabel = name; |
| | | this.stationlabelList.forEach(item => { |
| | |
| | | this.gettimestatus(); //查询列表 |
| | | }, |
| | | getstationlabelList() { |
| | | this.$HTTP.get("/api/blade-cps/group/get-mdc-group").then(res => { |
| | | this.$HTTP.get("/api/smis/group/get-mdc-group").then(res => { |
| | | if (res.code == 200) { |
| | | this.stationlabelList = res.data; |
| | | if (res.data.length != 0) { |
| | |
| | | this.stationlabel = this.stationlabelList[0].groupName; |
| | | this.workStationGroupIdList = [this.stationlabelList[0].groupId]; |
| | | } |
| | | this.clickIndex = 0; |
| | | this.gettimestatus(); //查询列表 |
| | | }, |
| | | showvisible(item, index) { |
| | | //clickIndex |
| | | if(item.properties.length == 0) { |
| | | this.$message({ |
| | | message: '该工位没有配置数据点', |
| | | type: 'warning' |
| | | }); |
| | | return; |
| | | } |
| | | this.clickIndex = index; |
| | | // if (item.properties == null || item.properties.length == 0) { |
| | | // this.$message({ |
| | | // message: '请配置采集项', |
| | | // type: 'warning' |
| | | // }); |
| | | // return; |
| | | // } |
| | | // var visibleList = JSON.parse(JSON.stringify(item.properties)); |
| | | // this.titleMap = "实时数据(" + item.code + ")"; |
| | | // this.visibleList = visibleList; |
| | | this.visible = true; |
| | | }, |
| | | searchstatus(item, index) { |
| | |
| | | } |
| | | }, |
| | | goSet() { |
| | | //console.log(this.$TOOL.data.get("MENU"));name == "配置中心" |
| | | this.$router.push('/mdc/configuration'); //分析设置 |
| | | this.$router.push('/mdc/configuration?isShowSearch=1'); //分析设置(isShowSearch表示即时信息来) |
| | | }, |
| | | gostatus(item) { |
| | | this.$router.push('/mdc/station-live?code=' + item.id); |
| | | }, |
| | | getprocess() { //颜色状态 |
| | | this.$HTTP.get(`/api/blade-cps/global_wcs/list?code=&name=`).then(res => { |
| | | this.$HTTP.get(`/api/smis/global_wcs/list?code=&name=`).then(res => { |
| | | if (res.code == 200) { |
| | | this.allwcs = res.data; |
| | | this.getdevicestatus(); //获取顶部title/具体数据 |
| | |
| | | } |
| | | }) |
| | | }, |
| | | changeTime(time) { |
| | | changeTime(time,diffTime) { |
| | | // 使用Moment.js解析这两个日期字符串 |
| | | var date1 = moment(time); |
| | | var date2 = moment(moment().format('YYYY-MM-DD HH:mm:ss')); |
| | | var date2 = moment(diffTime); |
| | | // 计算两个日期之间的差异(毫秒) |
| | | var differenceInMilliseconds = date2.diff(date1); // 注意:date2 - date1 给出正数差异 |
| | | var differenceInMilliseconds = date1.diff(date2); // 注意:date1 - date2 给出正数差异 |
| | | // 使用duration对象将差异转换为更易于处理的单位 |
| | | var duration = moment.duration(differenceInMilliseconds); |
| | | // 提取天数、小时数、分钟数和秒数 |
| | |
| | | workStationGroupIdList: this.workStationGroupIdList |
| | | } |
| | | this.timestatus = []; |
| | | this.$HTTP.post(`/api/blade-cps/workstation/real-time-status?current=${this.current || 0}&size=${this.size || 6}`, obj).then(res => { |
| | | this.$HTTP.post(`/api/smis/workstation/real-time-status?current=${this.current || 0}&size=${this.size || 6}`, obj).then(res => { |
| | | if (res.code == 200) { |
| | | var ids = []; |
| | | res.data.records.forEach(item => { |
| | | ids.push(item.id); |
| | | if (item.properties != null && item.properties.length != 0) { |
| | | item.properties.forEach(item1 => { |
| | | if (item1.key == "DeviceStatus") { |
| | | this.allwcs.forEach(item2 => { |
| | | if (item2.code == item1.value) { |
| | | item1.color = item2.color; |
| | | } |
| | | }) |
| | | } |
| | | }) |
| | | } else { |
| | | item.statusName = "未知"; |
| | | item.statusStyle = '#ccc'; |
| | | if(item.avatar == "") { |
| | | item.avatar = station; |
| | | } |
| | | ids.push(item.id); |
| | | }) |
| | | this.timestatus = res.data.records; |
| | | this.total = res.data.total; |
| | |
| | | that.$TOOL.socket.sendDataToWebSocket(obj); //发送 |
| | | } |
| | | }, 500); |
| | | //var num = 0; |
| | | var intervalId; |
| | | this.$TOOL.socket.websocket.onmessage = function (event) { |
| | | //num++; |
| | | var eventData = JSON.parse(event.data); |
| | | if (Object.keys(eventData.data).length == 0) return; |
| | | if (that.timestatus.length == 0) return; //没值不用循环 |
| | | that.timestatus.forEach((item, index) => { //第一步把v放到code里 |
| | | if (eventData.id == item.id) { |
| | |
| | | } |
| | | if (eventData.data.DeviceStatus) { |
| | | var time = moment(eventData.data.DeviceStatus.t).format('YYYY-MM-DD HH:mm:ss'); |
| | | var diffTime = that.changeTime(time); //转换成差值(时分秒) |
| | | that.setIntervalTime(); //十秒增加时间 |
| | | var preT = moment(eventData.data.DeviceStatus.preT).format('YYYY-MM-DD HH:mm:ss'); |
| | | var diffTime = that.changeTime(time,preT); //转换成差值(时分秒) |
| | | var diffTime = diffTime; |
| | | item.time = diffTime; |
| | | that.allwcs.forEach(item1 => { |
| | | if (item1.code == eventData.data.DeviceStatus.v) { |
| | |
| | | }) |
| | | } else { |
| | | if (item.time == undefined || item.time == "--") { |
| | | var diffTime = "--"; |
| | | item.time = diffTime; |
| | | item.time = "--"; |
| | | item.statusName = "未知"; |
| | | item.statusStyle = '#ccc'; |
| | | } |
| | | } |
| | | item.properties.forEach((item1, index1) => { |
| | | if (item1.key == "DeviceStatus") { //机器状态 |
| | | that.allwcs.forEach(item2 => { |
| | | if (item2.code == eventData.data.DeviceStatus.v) { |
| | | if(eventData.data.DeviceStatus && item2.code == eventData.data.DeviceStatus.v) { |
| | | item1.value = item2.code; |
| | | item1.color = item2.color; |
| | | item1.code = item2.name; |
| | | item1.moment = that.timestampChangeTime(eventData.data[item1.key].t); //时间戳转化成日期 |
| | | } |
| | | }) |
| | | if (Object.keys(eventData.data).length == 0) { //ws没有data数据,给默认值 |
| | | item1.code = ""; |
| | | item1.moment = ""; |
| | | }; |
| | | } else { |
| | | if (item1.key == 'Alarm') { //报警 |
| | | if (eventData.data[item1.key]) { |
| | | var v = JSON.parse(eventData.data[item1.key].v); |
| | | if (Array.isArray(v)) { //如果是数组,不赋值 |
| | | if (v.length == 0) { |
| | | res.data.records[index].properties.splice(index1, 1); |
| | | } else { |
| | | item1.name = v[0].code; |
| | | item1.code = v[0].msg; |
| | | } |
| | | } else { |
| | | item1.name = v.code; |
| | | item1.code = v.msg; |
| | | } |
| | | } |
| | | } else { |
| | | if (eventData.data[item1.key]) { |
| | | if(eventData.data[item1.key]) { |
| | | if(item1.key == "Alarm") { |
| | | var vJson = JSON.parse(eventData.data[item1.key].v); |
| | | item1.code = JSON.stringify(vJson[0]); |
| | | }else { |
| | | item1.code = eventData.data[item1.key].v; |
| | | } |
| | | item1.moment = that.timestampChangeTime(eventData.data[item1.key].t); //时间戳转化成日期 |
| | | }else { |
| | | item1.code = ""; |
| | | item1.moment = ""; |
| | | } |
| | | that.allwcs.forEach(item2 => { |
| | | if (item2.name == "报警") { |
| | | item1.color = item2.color; |
| | | } |
| | | }) |
| | | } |
| | | |
| | | }) |
| | | } |
| | | }); |
| | | }; |
| | | // var len = res.data.records.length; |
| | | // intervalId = setInterval(function() { |
| | | // if (num === len) { |
| | | // clearInterval(intervalId); |
| | | // that.timestatus = res.data.records; //等所有socket回来以后赋值 |
| | | // } |
| | | // }, 500); |
| | | } |
| | | }) |
| | | }, |
| | | timestampChangeTime(timestamp) { //时间戳转换成时间 |
| | | var date = new Date(timestamp); |
| | | //提取年月日小时分钟秒 |
| | | var year = date.getFullYear(); |
| | | var month = date.getMonth() + 1; // 月份从0开始,所以要加1 |
| | | var day = date.getDate(); |
| | | var hours = date.getHours(); |
| | | var minutes = date.getMinutes(); |
| | | var seconds = date.getSeconds(); |
| | | // 格式化日期字符串 |
| | | var formattedDate = `${year}-${month < 10 ? '0' : ''}${month}-${day < 10 ? '0' : ''}${day} ${hours < 10 ? '0' : ''}${hours}:${minutes < 10 ? '0' : ''}${minutes}:${seconds < 10 ? '0' : ''}${seconds}`; |
| | | return formattedDate; |
| | | }, |
| | | getdevicestatus() { |
| | | this.$HTTP.get(`/api/blade-mdc/work-station-analysis/device-status-statistics`).then(res => { |
| | | this.$HTTP.get(`/api/mdc/work-station-analysis/device-status-statistics`).then(res => { |
| | | if (res.code == 200) { |
| | | res.data.forEach(item => { |
| | | item.active = false; |
| | |
| | | font-weight: 700; |
| | | font-size: 16px; |
| | | color: #333; |
| | | width: 26%; |
| | | max-width: 37%; |
| | | overflow: hidden; |
| | | white-space: nowrap; |
| | | text-overflow: ellipsis; |
| | |
| | | width: 12px; |
| | | height: 12px; |
| | | border-radius: 6px; |
| | | margin-right: 8px; |
| | | margin-right: 2px; |
| | | } |
| | | |
| | | .status-card-detail-time { |
| | | line-height: 12px; |
| | | margin-left: 16px; |
| | | margin-left: 2px; |
| | | } |
| | | |
| | | .status-card-machine { |
| | |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .status-card-bottom-detail, |
| | |
| | | display: flex; |
| | | align-items: center; |
| | | justify-content: center; |
| | | cursor: pointer; |
| | | } |
| | | |
| | | .status-card-bottom-icon { |