Files
app-govern/pages/device/APF/detail.vue
2023-07-24 15:00:19 +08:00

500 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>
<Cn-page :loading="loading" noPadding>
<view slot="body">
<view class="detail">
<view class="detail-header">
<Cn-htmlToImg domId="header" @renderFinish="renderFinish">
<view class="header" ref="header" @click="previewImg">
<image :src="deviceInfo.filePath" style="width: 375px" mode="widthFix" />
<view
class="point"
:style="{ left: item.lat + 'px', top: item.lng + 'px' }"
v-for="(item, index) in showtTarget"
:key="index"
>
<view class="grid-card mt10" style="width: fit-content">
<view class="grid-card-content-1">
<view class="item">{{ item.label }}</view>
<view class="item" v-for="(child, childIndex) in item.value" :key="childIndex">
{{ child.showText }}
</view>
</view>
</view>
</view>
<view class="module">
<view class="grid-card">
<view class="grid-card-content-2">
<view class="item">模块一</view>
<view class="item">
<view class="status-point-success mr10"></view>
<view style="width: 30rpx"> 15 </view>
<view> °C </view>
</view>
<view class="item">模块二</view>
<view class="item">
<view class="status-point-error mr10"></view>
<view style="width: 30rpx"> 0 </view>
<view> °C </view>
</view>
<view class="item">模块三</view>
<view class="item">
<view class="status-point-success mr10"></view>
<view style="width: 30rpx"> 15 </view>
<view> °C </view>
</view>
<view class="item">模块四</view>
<view class="item">
<view class="status-point-success mr10"></view>
<view style="width: 30rpx"> 15 </view>
<view> °C </view>
</view>
</view>
</view>
</view>
</view>
</Cn-htmlToImg>
<!-- <view class="des">
<text>设备基础信息</text>
<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>
</view>
</view>
<view class="content">
<view v-if="navMenuActive == 0">
<basic :deviceInfo="deviceInfo"></basic>
</view>
<view v-else-if="navMenuActive == 1">
<xieBo></xieBo>
</view>
<view v-else-if="navMenuActive == 2">
<power :deviceInfo="deviceInfo"></power>
</view>
<view v-else-if="navMenuActive == 3">
<oscillogram></oscillogram>
</view>
<view v-else-if="navMenuActive == 4">
<IO :deviceInfo="deviceInfo"></IO>
</view>
<view style="height: 20rpx"></view>
</view>
<uni-fab
ref="fab"
direction="vertical"
horizontal="right"
vertical="bottom"
:content="content"
@trigger="trigger"
/>
</view>
</view>
</Cn-page>
</template>
<script>
import basic from './comp/basic.vue'
import xieBo from './comp/xieBo.vue'
import power from './comp/power.vue'
import oscillogram from './comp/oscillogram.vue'
import IO from './comp/IO.vue'
import { queryTopologyDiagram } from '@/common/api/device'
import { MQTT_IP, MQTT_OPTIONS } from '@/common/js/mqtt.js'
import mqtt from 'mqtt/dist/mqtt.js'
export default {
components: {
basic,
xieBo,
power,
oscillogram,
IO,
},
data() {
return {
loading: true,
deviceInfo: {},
navMenuActive: 0,
navHeight: 0,
img: '',
navMenuList: [
{
text: '基本',
},
{
text: '谐波',
},
{
text: '功率',
},
{
text: '波形',
},
{
text: 'I/O',
},
],
content: [
{
iconPath: '/static/report.png',
text: '告警',
},
{
iconPath: '/static/record.png',
text: '记录',
},
{
iconPath: '/static/about.png',
text: '关于',
},
],
client: null,
timer: null,
devId: '',
dictData: [],
isMaster: 0,
userInfo: {},
}
},
computed: {
showtTarget() {
if (this.loading) {
return
}
let arr = JSON.parse(JSON.stringify(this.deviceInfo.appsLineTopologyDiagramPO))
arr.forEach((item) => {
item.value = item.value?.filter((item2) => {
return item2.showText
})
})
return arr
},
},
methods: {
trigger(e) {
console.log(e)
if (e.item.text === '分享') {
this.$refs.share.open()
} else if (e.item.text === '删除') {
uni.showModal({
title: '提示',
content: '确定删除该设备吗?',
success: function (res) {
if (res.confirm) {
console.log('用户点击确定')
} else if (res.cancel) {
console.log('用户点击取消')
}
},
})
} else if (e.item.text === '下载') {
this.$util.toast('下载成功')
} else if (e.item.text === '记录') {
uni.navigateTo({ url: '/pages/device/APF/record' })
} else if (e.item.text === '告警') {
uni.navigateTo({ url: '/pages/device/APF/report' })
} else if (e.item.text === '关于') {
uni.navigateTo({ url: '/pages/device/APF/about' })
} else if (e.item.text === '移交') {
uni.navigateTo({ url: '/pages/device/transfer?id=' + this.devId })
} else if (e.item.text === '反馈') {
uni.navigateTo({ url: '/pages/device/feedback' })
} else if (e.item.text === '用户') {
uni.navigateTo({ url: '/pages/device/user' })
} else if (e.item.text === '报表') {
this.$util.toast('效果是直接打开报表')
} else if (e.item.text === '版本') {
this.$util.toast('功能暂未开放')
} else if (e.item.text === '模版') {
this.$util.toast('效果是功能暂未开放直接打开报表')
}
this.$refs.fab.close()
},
navMenuClick(idx) {
this.navMenuActive = idx
uni.pageScrollTo({ scrollTop: 0, duration: 0 })
},
init() {
switch (this.userInfo.authorities) {
case 1:
this.content.splice(0, 1)
this.content.splice(
0,
0,
{
iconPath: '/static/version.png',
text: '版本',
},
{
iconPath: '/static/template.png',
text: '模版',
},
)
break
case 2:
this.content.splice(0, 1)
break
case 4:
this.content.splice(
1,
0,
{
iconPath: '/static/delate.png',
text: '报表',
},
{
iconPath: '/static/table.png',
text: '删除',
},
{
iconPath: '/static/feedback.png',
text: '反馈',
},
)
break
case 5:
this.content.splice(
2,
0,
{
iconPath: '/static/table.png',
text: '报表',
},
{
iconPath: '/static/feedback.png',
text: '反馈',
},
)
break
default:
break
}
},
renderFinish(e) {
this.img = e
},
previewImg() {
if (!this.img) {
uni.showLoading({
title: '图片生成中',
mask: false,
})
setTimeout(() => {
this.previewImg()
}, 500)
} else {
uni.hideLoading()
uni.previewImage({
urls: [this.img],
})
}
},
initMqtt() {
MQTT_OPTIONS.clientId = uni.getStorageSync('devCode')
// #ifdef APP-PLUS
this.client = mqtt.connect('wx://' + MQTT_IP, MQTT_OPTIONS)
// #endif
// #ifdef H5
this.client = mqtt.connect('ws://' + MQTT_IP, MQTT_OPTIONS)
// #endif
this.client
.on('connect', () => {
console.log('连接成功')
this.client.subscribe(`/zl/devData/${this.devId}`, (err) => {
if (!err) {
console.log(`订阅成功:/zl/devData/${this.devId}`)
this.client.publish(`/zl/askDevData/${this.devId}`)
this.timer = setInterval(() => {
console.log('askDevData')
this.client.publish(`/zl/askDevData/${this.devId}`)
}, 10000)
}
})
})
.on('reconnect', function (error) {
console.log(error)
console.log('正在重连...', that.topic)
})
.on('error', function (error) {
console.log('连接失败...', error)
})
.on('end', function () {
console.log('连接断开')
})
.on('message', (topic, message) => {
console.log('接收推送信息:', message.toString())
if (!message.toString()) {
return
}
this.loading = false
let dataList = []
this.deviceInfo.appsLineTopologyDiagramPO.forEach((element) => {
element.value = []
})
JSON.parse(message.toString()).forEach((item) => {
this.deviceInfo.appsLineTopologyDiagramPO.forEach((element) => {
if (element.linePostion === item.position) {
// element.value.push({
// label: item.statisticalName,
// value: item.statisticalData,
// })
element.value.push({
...item,
showText:
item.statisticalName.indexOf('ThdPh') > -1 && item.phase === 'avg'
? item.statisticalName + '' + item.statisticalData
: '',
})
}
})
})
this.$forceUpdate()
console.log(this.deviceInfo.appsLineTopologyDiagramPO)
})
},
},
// 页面销毁
onUnload() {
clearInterval(this.timer)
this.client.end()
},
onLoad(options) {
this.dictData = uni.getStorageSync(this.$cacheKey.dictData)
this.userInfo = uni.getStorageSync(this.$cacheKey.userInfo)
this.devId = options.id
this.isMaster = options.isMaster
this.content.splice(0, 0, {
iconPath: '/static/transfer.png',
text: '移交',
})
if (this.isMaster == 1) {
this.content.splice(0, 0, {
iconPath: '/static/transfer.png',
text: '移交',
})
if (this.userInfo.authorities !== 'engineering_user') {
this.content.splice(0, 0, {
iconPath: '/static/share.png',
text: '分享',
})
}
}
this.init()
queryTopologyDiagram(options.id).then((res) => {
this.deviceInfo = res.data
console.log(this.dictData)
this.dictData.forEach((item) => {
if (item.code == 'Line_Position') {
item.children.forEach((item2) => {
this.deviceInfo.appsLineTopologyDiagramPO.forEach((element) => {
if (element.linePostion === item2.id) {
element.label = item2.name
}
})
})
}
})
this.initMqtt()
console.log(this.loading, 'loading')
// this.$nextTick(() => {
// // 获取nav高度
// uni.createSelectorQuery()
// .select('.nav')
// .boundingClientRect((rect) => {
// this.navHeight = rect.height
// })
// .exec()
// })
})
},
}
</script>
<style lang="scss">
.detail {
// background: $uni-theme-white;
.header-bg {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-size: 100% 100%;
}
.header {
position: relative;
width: 375px;
margin: 0 auto;
image {
image-rendering: -moz-crisp-edges;
image-rendering: -o-crisp-edges;
image-rendering: -webkit-optimize-contrast;
image-rendering: crisp-edges;
-ms-interpolation-mode: nearest-neighbor;
}
.point {
position: absolute;
color: #111;
z-index: 2;
text-align: center;
color: #111;
width: 110rpx;
font-size: 16rpx;
.grid-card-content-2,
.grid-card-content-1 {
font-size: 16rpx;
.item {
min-height: unset;
white-space: nowrap;
}
}
}
.module {
position: absolute;
bottom: 0;
right: 20rpx;
width: 200rpx;
.grid-card-content-2,
.grid-card-content-1 {
font-size: 16rpx;
.item {
min-height: unset;
}
}
}
}
.des {
padding: 20rpx 20rpx 0;
font-size: 28rpx;
color: #999;
}
.content {
box-sizing: border-box;
padding: 0 20rpx;
}
.detail-header {
position: sticky;
top: 0;
left: 0;
z-index: 2;
background: #f3f4f5;
}
}
</style>