绘制电脑治理信息页面

This commit is contained in:
guanj
2026-05-27 10:10:19 +08:00
parent 17e47c1f07
commit 7bcc68a9df
35 changed files with 2910 additions and 1492 deletions

View File

@@ -6,20 +6,16 @@
<view class="grid-card-title">温度</view>
<view class="grid-card-content-4">
<template v-for="item in renderData">
<view class="item item-title"
>{{ item[0].clDid }}
<view class="item item-title">{{ item[0].clDid }}
<template v-if="item[0].clDid"> (°C)</template>
</view>
<view class="item item-title"
>{{ item[1].clDid }}
<view class="item item-title">{{ item[1].clDid }}
<template v-if="item[1].clDid"> (°C)</template>
</view>
<view class="item item-title"
>{{ item[2].clDid }}
<view class="item item-title">{{ item[2].clDid }}
<template v-if="item[2].clDid"> (°C)</template>
</view>
<view class="item item-title"
>{{ item[3].clDid }}
<view class="item item-title">{{ item[3].clDid }}
<template v-if="item[3].clDid"> (°C)</template>
</view>
<view class="item">{{ item[0].clDid ? Math.round(item[0].value) || '-' : '' }}</view>
@@ -30,27 +26,21 @@
</view>
</view>
<!-- 运维管理员工程用户 可看 -->
<view
class="grid-card"
v-if="userInfo.authorities == 'operation_manager' || userInfo.authorities == 'engineering_user'"
>
<view class="grid-card"
v-if="(userInfo.authorities == 'operation_manager' || userInfo.authorities == 'engineering_user') && moduleData.length > 0">
<view class="grid-card-title">状态</view>
<view class="grid-card-content-4">
<template v-for="(item, index) in moduleData">
<view class="item item-title"
>{{ item[0].moduleName }}
<view class="item item-title">{{ item[0].moduleName }}
<template v-if="item[0].moduleName"></template>
</view>
<view class="item item-title"
>{{ item[1].moduleName }}
<view class="item item-title">{{ item[1].moduleName }}
<template v-if="item[1].moduleName"></template>
</view>
<view class="item item-title"
>{{ item[2].moduleName }}
<view class="item item-title">{{ item[2].moduleName }}
<template v-if="item[2].moduleName"></template>
</view>
<view class="item item-title"
>{{ item[3].moduleName }}
<view class="item item-title">{{ item[3].moduleName }}
<template v-if="item[3].moduleName"></template>
</view>
<!-- <uni-tag :text="item[0].moduleState" :type=" item[0].moduleState=='离线'?'error' : 'success'" /> -->
@@ -101,6 +91,7 @@ export default {
computed: {
renderData() {
let arr = []
// 把IOData转换成每4个一组的二维数组
for (let i = 0; i < this.IOData.length; i += 4) {
this.IOData.slice(i, i + 4).forEach((item) => {
@@ -120,7 +111,6 @@ export default {
}
}
})
console.warn(arr)
return arr
},
moduleData() {
@@ -159,6 +149,5 @@ export default {
}
</script>
<style lang="scss">
.basic {
}
.basic {}
</style>

View File

@@ -1,6 +1,7 @@
<template>
<view>
<uni-load-more status="loading" v-if="basicData.length == 0"></uni-load-more>
<uni-load-more status="loading"
v-if="renderData.电网电流.length == 0 || renderData.电网电压.length == 0 || renderData.负载电流.length == 0 || renderData.补偿电流.length == 0 "></uni-load-more>
<view class="basic" v-else>
<view class="grid-card">
<view class="grid-card-title">电网电流</view>
@@ -12,10 +13,10 @@
<view class="item">{{ item.phase }}</view>
<view class="item">{{
item['Apf_RmsI_Sys(A)'] > 0 ? item['Apf_RmsI_Sys(A)'].toFixed(2) : item['Apf_RmsI_Sys(A)']
}}</view>
}}</view>
<view class="item">{{
item['Apf_ThdA_Sys(%)'] > 0 ? item['Apf_ThdA_Sys(%)'].toFixed(2) : item['Apf_ThdA_Sys(%)']
}}</view>
}}</view>
</template>
</view>
</view>
@@ -30,13 +31,13 @@
<view class="item">{{ item.phase }}</view>
<view class="item">{{
item['Apf_PhV_Sys(V)'] > 0 ? item['Apf_PhV_Sys(V)'].toFixed(2) : item['Apf_PhV_Sys(V)']
}}</view>
}}</view>
<view class="item">{{
item['Apf_Freq(Hz)'] > 0 ? item['Apf_Freq(Hz)'].toFixed(2) : item['Apf_Freq(Hz)']
}}</view>
}}</view>
<view class="item">{{
item['Apf_ThdU_Sys(%)'] > 0 ? item['Apf_ThdU_Sys(%)'].toFixed(2) : item['Apf_ThdU_Sys(%)']
}}</view>
}}</view>
</template>
</view>
</view>
@@ -73,15 +74,15 @@
item['Apf_RmsI_TolOut(A)'] == 3.1415926
? '-'
: item['Apf_RmsI_TolOut(A)'] > 0
? item['Apf_RmsI_TolOut(A)'].toFixed(2)
: item['Apf_RmsI_TolOut(A)']
? item['Apf_RmsI_TolOut(A)'].toFixed(2)
: item['Apf_RmsI_TolOut(A)']
}}</view>
<view class="item">{{
item['load_Rate'] == 3.1415926
? '-'
: item['load_Rate'] > 0
? item['load_Rate'].toFixed(2)
: item['load_Rate']
? item['load_Rate'].toFixed(2)
: item['load_Rate']
}}</view>
</template>
</view>
@@ -179,6 +180,5 @@ export default {
}
</script>
<style lang="scss">
.basic {
}
.basic {}
</style>

View File

@@ -1,6 +1,6 @@
<template>
<view>
<uni-load-more status="loading" v-if="basicData.length == 0"></uni-load-more>
<uni-load-more status="loading" v-if="renderData.电网侧.length == 0 || renderData.负载侧.length == 0"></uni-load-more>
<view class="basic" v-else>
<view class="grid-card">
<view class="grid-card-title">电网侧</view>
@@ -12,14 +12,14 @@
<view class="item item-title">功率因数</view>
<template v-for="(item, index) in renderData.电网侧">
<view class="item">{{ item.phase }}</view>
<view class="item"
>{{ item['Apf_P_Sys(W)'] == '-' ? '-' : (item['Apf_P_Sys(W)'] / 1000).toFixed(2) }}
<view class="item">{{ item['Apf_P_Sys(W)'] == '-' ? '-' : (item['Apf_P_Sys(W)'] /
1000).toFixed(2) }}
</view>
<view class="item"
>{{ item['Apf_Q_Sys(Var)'] == '-' ? '-' : (item['Apf_Q_Sys(Var)'] / 1000).toFixed(2) }}
<view class="item">{{ item['Apf_Q_Sys(Var)'] == '-' ? '-' : (item['Apf_Q_Sys(Var)'] /
1000).toFixed(2) }}
</view>
<view class="item"
>{{ item['Apf_S_Sys(VA)'] == '-' ? '-' : (item['Apf_S_Sys(VA)'] / 1000).toFixed(2) }}
<view class="item">{{ item['Apf_S_Sys(VA)'] == '-' ? '-' : (item['Apf_S_Sys(VA)'] /
1000).toFixed(2) }}
</view>
<view class="item">{{ item['Apf_PF_Sys(null)'] || '-' }}</view>
</template>
@@ -35,14 +35,14 @@
<view class="item item-title">功率因数</view>
<template v-for="(item, index) in renderData.负载侧">
<view class="item">{{ item.phase }}</view>
<view class="item"
>{{ item['Apf_P_Load(W)'] == '-' ? '-' : (item['Apf_P_Load(W)'] / 1000).toFixed(2) }}
<view class="item">{{ item['Apf_P_Load(W)'] == '-' ? '-' : (item['Apf_P_Load(W)'] /
1000).toFixed(2) }}
</view>
<view class="item">{{
item['Apf_Q_Load(Var)'] == '-' ? '-' : (item['Apf_Q_Load(Var)'] / 1000).toFixed(2)
}}</view>
<view class="item"
>{{ item['Apf_S_Load(VA)'] == '-' ? '-' : (item['Apf_S_Load(VA)'] / 1000).toFixed(2) }}
}}</view>
<view class="item">{{ item['Apf_S_Load(VA)'] == '-' ? '-' : (item['Apf_S_Load(VA)'] /
1000).toFixed(2) }}
</view>
<view class="item">{{ item['Apf_PF_Load(null)'] || '-' }}</view>
</template>
@@ -130,6 +130,5 @@ export default {
}
</script>
<style lang="scss">
.basic {
}
.basic {}
</style>

View File

@@ -5,18 +5,10 @@
<view class="detail-header">
<Cn-htmlToImg domId="header" @renderFinish="renderFinish">
<view class="header" id="header" ref="header" @click="previewImg">
<img
:src="topoImg"
style="width: 375px; display: block"
mode="widthFix"
@load="domLoading = false"
/>
<view
class="point"
:style="{ left: item.lat + 'px', top: item.lng + 'px' }"
v-for="(item, index) in topolodyData"
:key="index"
>
<img :src="topoImg" style="width: 375px; display: block" mode="widthFix"
@load="domLoading = false" />
<view class="point" :style="{ left: item.lat + 'px', top: item.lng + 'px' }"
v-for="(item, index) in topolodyData" :key="index">
<view class="grid-card mt10" style="width: fit-content">
<view class="grid-card-content-1">
<view class="item">{{ item.label }}</view>
@@ -51,13 +43,9 @@
<text class="ml10">设备状态</text>
</view> -->
<view class="nav" style="margin-top: -10rpx">
<view
class="nav-menu"
:class="{ 'nav-menu-active': navMenuActive == index }"
v-for="(item, index) in navMenuList"
:key="index"
@click="navMenuClick(index)"
>{{ item.text }}
<view class="nav-menu" :class="{ 'nav-menu-active': navMenuActive == index }"
v-for="(item, index) in navMenuList" :key="index" @click="navMenuClick(index)">{{ item.text
}}
</view>
</view>
</view>
@@ -107,22 +95,10 @@
</uni-popup> -->
<!-- 输入框示例 -->
<uni-popup ref="inputDialog" type="dialog">
<uni-popup-dialog
ref="inputClose"
type="info"
mode="input"
:title="dialogType"
value="对话框预置提示内容!"
placeholder="请输入内容"
@confirm="dialogInputConfirm"
>
<uni-easyinput
type="textarea"
:maxlength="250"
autoHeight
v-model="remarkContent"
placeholder="请输入备注"
></uni-easyinput>
<uni-popup-dialog ref="inputClose" type="info" mode="input" :title="dialogType" value="对话框预置提示内容!"
placeholder="请输入内容" @confirm="dialogInputConfirm">
<uni-easyinput type="textarea" :maxlength="250" autoHeight v-model="remarkContent"
placeholder="请输入备注"></uni-easyinput>
</uni-popup-dialog>
</uni-popup>
</view>
@@ -140,6 +116,7 @@ import { manualAccess } from '@/common/api/accessBoot'
import { MQTT_IP, MQTT_OPTIONS } from '@/common/js/mqtt.js'
import mqtt from 'mqtt/dist/mqtt.js'
import { base64ToPath, pathToBase64 } from 'image-tools'
import { queryByCode, queryStatistical } from '@/common/api/dictionary'
import hoverMenu from '@/hover-menu/components/hover-menu/hover-menu.vue'
export default {
components: {
@@ -164,6 +141,7 @@ export default {
navHeight: 0,
img: '',
topoImg: '',
targetLists: [],
navMenuList: [
{
text: '基本',
@@ -177,9 +155,6 @@ export default {
text: '功率',
id: 'a16aceae7d1565bf9f94dd7410cf9bce',
},
// {
// text: '波形',
// },
{
text: '其他',
},
@@ -358,11 +333,21 @@ export default {
},
})
},
init() {
getTarget() {
return queryByCode('app_harmonic_code').then((res) => {
return queryStatistical({ id: res.data.id }).then((resp) => {
this.targetLists = resp.data.selectedList
})
})
},
async init() {
console.log('init')
this.loading = true
this.domLoading = true
queryTopologyDiagram(this.devId).then((res) => {
await queryTopologyDiagram(this.devId).then((res) => {
res.data.filePath = this.$config.static + res.data.filePath
this.deviceInfo = res.data
this.downloadImg()
@@ -371,6 +356,7 @@ export default {
let index = this.deviceInfo.appsLineTopologyDiagramPO?.findIndex((element) => {
element.label = element.name
item.label = element.name
item.target = element.target
return element.linePostion === item.linePostion
})
if (index > -1) {
@@ -384,10 +370,14 @@ export default {
})
console.log(this.topolodyData)
if (this.client) {
this.client.publish(`/zl/askDevData/${this.devId}/${this.navMenuList[0].id}`)
this.loading = false
} else {
this.initMqtt(this.navMenuList[0].id)
}
console.log("🚀 ~ this.client:", this.client)
})
},
renderFinish(e) {
@@ -460,22 +450,28 @@ export default {
console.log('连接断开')
})
.on('message', (topic, message) => {
console.log('接收推送信息:', JSON.parse(message.toString()), topic)
console.log('🚀 ~ .on ~ topic:', topic)
// console.log('接收推送信息:', JSON.parse(message.toString()), topic)
// console.log('🚀 ~ .on ~ topic:', topic)
if (topic === `/zl/devData/${this.devId}/${id}`) {
const data = JSON.parse(message.toString())
if (Array.isArray(data) && !data.length) return
if ((!message.toString() || message.toString().length < 10) && this.loading) {
this.$util.toast('该设备暂无数据')
}
this.loading = false
this.handlerData(JSON.parse(message.toString()))
this.handlerData(data)
} else if (topic === `/zl/TemperData/${this.devId}`) {
const data = JSON.parse(message.toString())
if (Array.isArray(data) && !data.length) return
// this.basicData.forEach((item) => {
// if (item.statisticalName === '温度' && item.phase === 'avg') {
// item.statisticalData = message.toString()
// }
// })
this.IOData = JSON.parse(message.toString())
this.IOData = data
// this.IOData = this.IOData.filter((item) => item.value !== 0)
this.IOData.forEach((item) => {
if (!item.value) {
@@ -490,37 +486,60 @@ export default {
})
},
handlerData(data) {
async handlerData(data) {
this.basicData = data
this.topolodyData.forEach((element) => {
let arr = []
let list = this.targetLists.filter(key => key.dataType == element.target)
element.showKey.forEach((key) => {
if (list.length > 0) {
let id = list[0]?.eleEpdPqdVOS.filter(key => key.phase == 'A')[0]?.id || ''
data.forEach((item) => {
if (item.statisticalName === key && item.phase === 'avg') {
if (key === 'Apf_RmsI_TolOut(A)') {
arr.push({
label: '总输出电流:',
value: Math.round(item.statisticalData) + 'A',
})
} else {
arr.push({
label: '电流畸变率:',
value: Math.round(item.statisticalData) + '%',
})
// arr.push('电流畸变率:' + item.statisticalData + '%')
}
if (item.statisticalIndex === id && item.phase === 'avg') {
arr.push({
label: list[0].dataTypeName.split('-')[1] + ':',
value: (item.statisticalData) + `${item.unit || ''}`,
})
}
if (item.time) {
this.dataTime = item.time.seconds
this.time = this.$util.parseTime(this.dataTime - 8 * 60 * 60)
// console.log(11111111,this.dataTime);
}
})
})
}
else {
element.showKey.forEach((key) => {
data.forEach((item) => {
if (item.statisticalName === key && item.phase === 'avg') {
if (key === 'Apf_RmsI_TolOut(A)') {
arr.push({
label: '总输出电流:',
value: (item.statisticalData) + 'A',
})
} else {
arr.push({
label: '电流畸变率:',
value: (item.statisticalData) + '%',
})
}
}
if (item.time) {
this.dataTime = item.time.seconds
this.time = this.$util.parseTime(this.dataTime - 8 * 60 * 60)
}
})
})
}
element.value = arr
})
console.log("🚀 ~ this.topolodyData:", this.topolodyData)
console.log(this.topolodyData)
this.$forceUpdate()
},
@@ -539,13 +558,16 @@ export default {
}, 1000)
},
onLoad(options) {
async onLoad(options) {
await this.getTarget()
this.pageOptions = options
this.device = JSON.parse(options.device)
console.log('🚀 ~ options:', options)
this.userInfo = uni.getStorageSync(this.$cacheKey.userInfo)
this.devId = options.id
this.isPrimaryUser = options.isPrimaryUser
if (this.pageOptions.process == 2 || this.pageOptions.process == 3) {
this.content.splice(
0,
@@ -626,9 +648,11 @@ export default {
lng: '',
showKey: item.showKey, //要展示的指标key
value: [],
target: item.target
}
})
})
this.init()
},
}
@@ -636,6 +660,7 @@ export default {
<style lang="scss">
.detail {
// background: $uni-theme-white;
.header-bg {
position: absolute;
@@ -666,7 +691,7 @@ export default {
z-index: 2;
text-align: center;
color: #111;
width: 110rpx;
width: 150rpx;
font-size: 16rpx;
opacity: 0.8;