smart-power-ui/src/views/profile/DeviceRunStarts/index.vue

650 lines
18 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.

<template>
<div class="device-run-starts-wrap">
<div class="cmd-list">
<div class="cmd-title-wrap">
分组名称
<el-select v-model="selectedGroup" placeholder="请选择">
<el-option v-for="item in groupOptions" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
</div>
<div v-if="filteredProperties.length <= 0" style="width:100%; padding: 100px;text-align: center">
<i class="el-icon-s-order" style="font-size: 50px;color: #999"></i>
<div style="color: #909399;margin-top: 10px">暂无数据</div>
</div>
<div v-for="(item, index) in filteredProperties" :key="index" class="param-item2">
<div class="title-top">
<span class="name-wr">{{ item.name }}</span>
<span class="type-wr" @click="handleShowData(item)">查看</span>
</div>
<div class="value-info">
<div class="value-wrap">
<span class="val-span">
{{ formatValue(item) }}
</span>
</div>
</div>
<div class="time-w">
<span class="time-warp">{{ item.valueParams.unit || '' }}</span>
<span class="time">{{ item.timestamp }}</span>
</div>
</div>
</div>
<el-dialog :close-on-click-modal="false" :visible.sync="dialogShow" append-to-body class="device-run-state-dailog"
title="查看数据" width="700px" @close="dialogCloseCell" @opened="dialogOpen">
<run-state-table ref="showChart" :deviceId="sourceId" :deviceKey="deviceInfo.deviceKey" :dialogData="dialogData"
:dialogShow="dialogShow" :pro_type="dialogData.funDataType" :prodId="prodId" />
<div slot="footer" class="dialog-footer">
<el-button size="small" @click="dialogShow = false">关 闭</el-button>
</div>
</el-dialog>
</div>
</template>
<script>
import { getDeviceFunList, getDeviceCmdList } from "@/api/iot/device";
import { iotWebSocketBaseUrl } from "@/config/env";
import RunStateTable from "./table";
import moment from "moment";
export default {
name: "RunStartsWrap",
props: ["prodId", "sourceId", "deviceInfo", "wsUrl", "realTimeData"],
components: {
RunStateTable
},
data() {
return {
cmdList: [
{
cmdKey: "",
cmdName: "全部"
}
],
cmdObject: {},
stompClient: null,
deviceKey: "",
socket_flag: true,
dialogData: {},
dialogShow: false,
firstWsMassage: true,
prodObj: {
properties: [],
events: []
},
filterProdObj: {
properties: [],
events: []
},
runtimeProperties: [],
selectedGroup: "all",
metadata:{
properties: [],
propertyGroups: []
}
};
},
computed: {
groupOptions() {
const groups = this.metadata?.propertyGroups || [];
return [
{ label: '全部', value: 'all' },
...groups.map((group) => ({ label: group.name, value: group.id })),
];
},
filteredProperties() {
let properties = [...this.runtimeProperties];
if (this.selectedGroup !== 'all') {
const group = (this.metadata?.propertyGroups || []).find(
(g) => g.id === this.selectedGroup,
);
if (group?.properties) {
const ids = new Set(group.properties.map((p) => p.id));
properties = properties.filter((p) => ids.has(p.id));
}
}
// properties = properties.filter((p) => {
// const type = p.expands?.type || 'R';
// return selectedTypes.value.includes(type);
// });
return properties;
}
},
created() {
this.getMetaDate();
this.getProdObj();
// this.getCmdList();
// this.connection();
},
methods: {
getMetaDate(){
try {
this.metadata = JSON.parse(this.deviceInfo.metadata);
} catch (error) {
console.log(error);
}
},
changeCmd(e) {
if (e != "") {
const filterObj =
this.prodObj.properties.filter(item => item.cmdKey === e) || [];
this.$nextTick(() => {
this.$set(this.filterProdObj, "properties", filterObj);
});
} else {
this.$nextTick(() => {
this.$set(this.filterProdObj, "properties", this.prodObj.properties);
});
}
},
formatValue(property) {
const { value, valueParams } = property;
if (value === undefined || value === null) return '--';
let displayValue = value;
if (valueParams?.formType === 'input' && valueParams?.length) {
displayValue = value.slice(0, valueParams.length);
}
if (valueParams?.formType === 'switch') {
return value.toString() === valueParams.trueValue
? valueParams.trueText
: valueParams.falseText;
}
if (valueParams?.formType === 'select') {
return valueParams.enumConf.find((item) => item.value === value)?.text;
}
if (valueParams?.formType === 'time' && valueParams?.dataType !== 'string') {
return moment(value).format(valueParams.format);
}
if (
valueParams?.formType === 'number' ||
valueParams?.formType === 'progress'
) {
if (valueParams?.scale) return value.toFixed(valueParams.scale);
return value;
}
return displayValue;
},
getProdObj() {
if (this.metadata.properties) {
let list = this.metadata.properties.filter((item) => item.show === true) || [];
let properties = list.map(item => ({
...item,
value: null,
timestamp: moment().format('YYYY-MM-DD HH:mm:ss')
}));
this.runtimeProperties = properties;
this.$nextTick(() => {
this.$set(this, "runtimeProperties", properties);
});
} else {
this.runtimeProperties = [];
}
this.connection();
},
formatTime(date) {
// 检查时间戳长度
if (date && date.toString().length === 10) {
// 10 位时间戳
return moment(date * 1000).format("YYYY-MM-DD HH:mm:ss");
} else if (date && date.toString().length === 13) {
// 13 位时间戳
return moment(date).format("YYYY-MM-DD HH:mm:ss");
} else {
return date;
}
},
// 查看数据
handleShowData(row) {
row.chartDate = new Date();
this.dialogData = row;
this.dialogShow = true;
},
dialogOpen() {
this.$refs.showChart.initDialog(this.dialogData);
},
dialogCloseCell() {
this.$refs.showChart.close();
},
// 创建ws
connection() {
if (this.stompClient) {
return;
}
if (!this.wsUrl) {
return;
}
// let locahostUrl = 'ws://192.168.18.138/device/ws/dev/send/'
let headers = {
clientid: this.deviceInfo.wsClientId,
username: this.deviceInfo.wsUsername,
sign: this.deviceInfo.wsSign
};
this.stompClient = new WebSocket(
`${this.wsUrl}${headers.clientid}/${headers.username}/${headers.sign}`
);
this.stompClient.onmessage = this.socket_onmsg;
this.stompClient.onclose = this.socket_onclose;
},
socket_onmsg(evt) {
console.log("evt.data", evt.data);
this.setListData(evt.data);
},
setListData(data) {
// this.recursionSet(this.cmdList, JSON.parse(data));
this.recursionSet("", JSON.parse(data));
this.firstWsMassage = false;
this.$forceUpdate();
},
recursionSet(list, result) {
if (result.type === "result" && result.topic.endsWith('/report') && result.payload) {
// 更函数式的写法,避免直接修改
this.runtimeProperties = this.runtimeProperties.map(property => {
const propValue = result.payload.value[property.id];
if (propValue !== undefined) {
return {
...property,
value: propValue,
timestamp: moment(result.payload.timeString).format('YYYY-MM-DD HH:mm:ss')
};
}
return property;
});
// 更新实时属性数据
// Object.entries(result.payload).forEach(([propId, propValue]) => {
// const property = this.runtimeProperties.find(
// (p) => p.id === propId,
// );
// if (property) {
// property.value = propValue;
// property.timestamp = moment(data.payload.timeString).format(
// 'YYYY-MM-DD HH:mm:ss',
// );
// }
// });
}
// if (result.type === "properties") {
// if (result.tags.device_key === this.deviceInfo.deviceKey) {
// this.prodObj.properties = this.prodObj.properties.map(item => ({
// ...item,
// ...(item.funKey in result.properties && {
// lastValue: result.properties[item.funKey],
// lastTime: result.properties.timestamp
// })
// }));
// this.filterProdObj.properties = this.filterProdObj.properties.map(
// item => ({
// ...item,
// ...(item.funKey in result.properties && {
// lastValue: result.properties[item.funKey],
// lastTime: result.properties.timestamp
// })
// })
// );
// }
// }
// if (result.type === "state") {
// this.$emit("updateDeviceState", {
// deviceKey: this.deviceInfo.deviceKey,
// state: result.state
// });
// }
// for (var i = 0; i < list.length; i++) {
// // if (this.firstWsMassage) {
// // // result["cmd"] && list[i]['cmdKey'] === result["cmd"]
// // // if (result["cmd"] && list[i]['cmdKey'] === result["cmd"]) {
// // for (var v = 0; v < list[i].children.length; v++) {
// // if (
// // result.params[list[i].children[v]["funKey"]] !== null &&
// // result.params[list[i].children[v]["funKey"]] !== undefined
// // ) {
// // list[i].children[v]["lastValue"] =
// // result.params[list[i].children[v]["funKey"]];
// // list[i].children[v]["lastTime"] = result.params["timestamp"]
// // ? result.params["timestamp"]
// // : "";
// // }
// // }
// // // }
// // } else {
// if (result["cmd"] && list[i]["cmdKey"] === result["cmd"]) {
// console.log("list[i].children",list[i])
// for (var v = 0; v < list[i].children.length; v++) {
// if (
// result.params[list[i].children[v]["funKey"]] !== null &&
// result.params[list[i].children[v]["funKey"]] !== undefined
// ) {
// list[i].children[v]["lastValue"] = result.params[list[i].children[v]["funKey"]];
// list[i].children[v]["lastTime"] = result.params["timestamp"] ? result.params["timestamp"] : "";
// }
// }
// break;
// }
// // }
// }
},
socket_onclose(e) {
this.stompClient = null;
if (this.socket_flag) {
this.socket_flag = false;
let self = this;
setTimeout(function () {
self.socket_flag = true;
self.connection();
}, 10000);
}
},
async forGetParams(row, index) {
const param = {
cmdId: row.cmdId,
deviceId: this.deviceInfo.deviceId,
cmdKey: row.cmdKey,
deviceKey: this.deviceInfo.deviceKey
};
try {
const res = await getDeviceFunList(param);
if (res.data.length > 0) {
let list = res.data.filter(item => item.show === true) || [];
row.children = list.map(item => {
if (item.dataFormat) {
let dataFormat = JSON.parse(item.dataFormat);
item.dataFormatType = dataFormat.type;
if (dataFormat.list && dataFormat.type === "ENUM") {
try {
item.dataFormatObj = JSON.parse(
dataFormat.list.replace(/\\/g, "")
);
} catch (e) {
item.dataFormatObj = {};
}
}
}
return item;
});
} else {
row.children = [];
}
this.$forceUpdate();
} catch (error) {
console.error(`Error fetching data for row ${index}:`, error);
}
},
lengthReSize(str) {
if (str.toString().length < 18 && str.toString().length > 12) {
return "font-size: 18px;";
} else if (str.toString().length > 18) {
return "font-size: 18px; white-space: nowrap; display: inline-block;width: 80%; overflow: hidden; text-overflow: ellipsis;";
} else {
return "";
}
},
getCmdList() {
const params = {
deviceId: this.deviceInfo.deviceId,
cmdType: "1"
};
getDeviceCmdList(params).then(response => {
if (response.data && response.data.length > 0) {
this.cmdList = [
{
cmdKey: "",
cmdName: "全部"
},
...response.data
];
}
this.connection();
}).catch(error => {
this.connection();
});
},
closeWebscoket() {
if (this.stompClient) {
this.stompClient.close();
}
this.socket_flag = false;
this.stompClient = null;
clearTimeout(this.setTimeOut_flag);
},
async processAllRequests(data) {
try {
await Promise.all(
data.map(async (row, index) => {
await this.forGetParams(row, index);
})
);
this.connection();
} catch (error) {
console.error("Error processing all requests:", error);
}
}
},
destroyed() {
this.closeWebscoket();
},
watch: {
// cmdList(val) {
// if (val) {
// // val.forEach((v, index) => {
// // this.forGetParmas(v, index);
// // });
// // setTimeout(this.connection, 3000);
// // this.connection()
// this.processAllRequests(val);
// }
// },
realTimeData: {
handler: function () {
this.setListData(this.realTimeData);
},
deep: true
}
}
};
</script>
<style lang="scss">
.device-run-starts-wrap {
width: 100%;
display: flex;
flex-wrap: wrap;
overflow: auto;
//padding: 10px;
.el-button--medium {
position: absolute;
right: 30px;
}
.cmd-list {
width: 100%;
/* height: auto; */
display: flex;
flex-wrap: wrap;
cursor: default;
padding: 10px;
&:first-child {
padding-top: 0;
}
.cmd-title-wrap {
width: 100%;
display: flex;
// border-bottom: 1px solid #bdb7b7;
font-size: 16px;
align-items: center;
margin-bottom: 20px;
.cmd-title {
font-size: 14px;
color: #a9a6a6;
font-size: 16px;
color: #f35151;
letter-spacing: 1px;
}
}
.param-item {
height: 130px;
// border: 1px solid #777474;
width: 250px;
display: flex;
flex-wrap: wrap;
margin-right: 10px;
margin-top: 10px;
border-radius: 2px;
padding: 10px;
justify-content: flex-start;
align-items: flex-start;
margin: 0;
margin-left: 15px;
margin-top: 15px;
box-shadow: 0px 0px 3px 0px #b7b4b4;
.title-top {
height: 30px;
display: flex;
align-items: flex-end;
width: 100%;
border-bottom: 1px dotted #c5c3c3;
padding-bottom: 3px;
justify-content: space-between;
.name-wr {
font-size: 18px;
color: #1890ff;
}
.type-wr {
font-size: 14px;
color: #1890ff;
}
}
.value-info {
height: 55px;
display: flex;
margin-top: 5px;
align-items: center;
width: 100%;
.value-wrap {}
.val-span {
color: #03a9f4;
font-size: 20px;
width: 280px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}
}
.time-w {
margin-top: 5px;
font-size: 14px;
width: 100%;
display: flex;
justify-content: space-between;
color: #908c8c;
}
}
.param-item2 {
height: 150px;
width: 300px;
display: flex;
flex-wrap: wrap;
border-radius: 0px;
padding: 10px;
justify-content: flex-start;
align-items: flex-start;
margin: 0;
border: 1px solid #b7b4b4;
margin-left: -1px;
margin-top: -1px;
border-color: #e0e0e0;
.title-top {
height: 30px;
display: flex;
align-items: flex-end;
width: 100%;
border-bottom: 1px dotted #c5c3c3;
padding-bottom: 3px;
justify-content: space-between;
.name-wr {
font-size: 18px;
// color: #1890ff;
}
.type-wr {
font-size: 14px;
// color: #606266;
color: #1890ff;
}
.type-wr:hover {
color: #1890ff;
cursor: pointer;
}
}
.value-info {
height: 55px;
display: flex;
margin-top: 5px;
align-items: center;
width: 100%;
.value-wrap {}
.val-span {
color: #03a9f4;
font-size: 20px;
width: 280px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
display: inline-block;
}
}
.time-w {
margin-top: 5px;
font-size: 14px;
width: 100%;
display: flex;
justify-content: space-between;
color: #908c8c;
}
}
}
}
.device-run-state-dailog {
.el-dialog__header {
border-bottom: 1px solid #b6b6b6;
}
.el-dialog__footer {
border-top: 1px solid #b6b6b6;
padding-bottom: 10px;
}
}
</style>