Files
app-govern/pages/device/APF/detail.vue
2023-08-17 09:24:59 +08:00

459 lines
17 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" :style="{ opacity: domLoading ? '0' : '1' }">
<view class="detail-header">
<Cn-htmlToImg domId="header" @renderFinish="renderFinish">
<view class="header" id="header" ref="header" @click="previewImg">
<img
:src="deviceInfo.filePath"
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 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>
</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" v-if="deviceInfo">
<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 == 3">
<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"
/>
<uni-popup ref="share" type="share" :safe-area="false">
<uni-popup-share title="分享到"></uni-popup-share>
<view style="height: 40rpx; background: #fff"></view>
</uni-popup>
</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, deleteDevice } from '@/common/api/device'
import { MQTT_IP, MQTT_OPTIONS } from '@/common/js/mqtt.js'
import mqtt from 'mqtt/dist/mqtt.js'
import { base64ToPath, pathToBase64 } from 'image-tools'
export default {
components: {
basic,
xieBo,
power,
oscillogram,
IO,
},
data() {
return {
domLoading: true,
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: [],
isPrimaryUser: 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: (res) => {
if (res.confirm) {
console.log('用户点击确定')
deleteDevice(this.devId).then((res) => {
uni.showToast({
title: '删除成功',
icon: 'none',
})
setTimeout(() => {
uni.navigateBack()
}, 1500)
})
} 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?id=' + this.devId })
} 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('效果是功能暂未开放直接打开报表')
} else if (e.item.text === '编辑') {
uni.navigateTo({
url: '/pages/device/edit?deviceInfo=' + encodeURIComponent(JSON.stringify(this.deviceInfo)),
})
}
this.$refs.fab.close()
},
navMenuClick(idx) {
this.navMenuActive = idx
uni.pageScrollTo({ scrollTop: 0, duration: 0 })
},
init() {
if (this.isPrimaryUser == 1) {
this.content.splice(
0,
0,
{
iconPath: '/static/transfer.png',
text: '移交',
},
{
iconPath: '/static/feedback.png',
text: '编辑',
},
{
iconPath: '/static/delate.png',
text: '删除',
},
)
if (this.userInfo.authorities === 'app_vip_user') {
this.content.splice(3, 0, {
iconPath: '/static/share.png',
text: '分享',
})
}
}
},
renderFinish(e) {
this.img = e
},
previewImg() {
if (!this.img) {
uni.showLoading({
title: '图片生成中',
mask: false,
})
setTimeout(() => {
this.previewImg()
}, 500)
} else {
uni.hideLoading()
base64ToPath(this.img).then((res) => {
console.log(res)
uni.previewImage({
urls: [res],
})
})
}
},
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().length)
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.isPrimaryUser = options.isPrimaryUser
this.init()
queryTopologyDiagram(options.id).then((res) => {
this.deviceInfo = res.data
uni.setNavigationBarTitle({ title: this.deviceInfo.devName || '设备详情' })
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()
})
},
}
</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: 10rpx;
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>