2025-05-22 16:37:43 +08:00

966 lines
34 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>
<view class="device-detail">
<!-- 设备信息 -->
<view class="device-info" v-if="tabbarIndex === 0">
<view class="top-wrap">
<view class="nav-bar">
<navbar color="#ffffff">{{ navTitle }}</navbar>
</view>
<view class="sub-wrap" :style="{width: '85%'}" v-if="deviceForm.deviceType !== 3">
<u-subsection :list="baseTabList" :current="baseTabIndex" bgColor=" rgba(255,255,255,0.2)"
activeColor="#3378FE" inactiveColor="#FFFFFF" @change="handleBaseTabsClick"></u-subsection>
</view>
<view class="sub-wrap" :style="{width: '44%'}" v-else>
<u-subsection :list="videoTabList" :current="videotabIndex" bgColor=" rgba(255,255,255,0.2)"
activeColor="#3378FE" inactiveColor="#FFFFFF" @change="handleVideoTabsClick"></u-subsection>
</view>
</view>
<view class="content-wrap">
<!-- 设备 -->
<view class="device-content">
<view v-show="deviceForm.deviceType !== 3">
<!-- 设备运行状态 -->
<running-status v-show="baseTabIndex === 0" ref="runningStatus"
:device="deviceForm"></running-status>
<!-- 设备实时监测 -->
<device-monitor v-show="baseTabIndex == 1" ref="deviceMonitor" :show="baseTabIndex == 1"
:device="deviceForm">
</device-monitor>
<!-- 视频监控 -->
<video-monitor v-show="baseTabIndex == 2" ref="videoMonitor"
:device="deviceForm"></video-monitor>
<!-- 告警记录 -->
<device-alertLog v-show="baseTabIndex == 3" ref="deviceAlertLog"
:device="deviceForm"></device-alertLog>
</view>
<!-- 视频监控设备 -->
<view v-show="deviceForm.deviceType === 3">
<!-- 设备通道 -->
<view class="channel_wrap" v-show="videotabIndex == 0">
<view class="item_body" v-for="(item, i) in channelList" :key="i"
@click="gotoDevicePlayer(item.deviceSipId, item.channelSipId, item.status)">
<view class="img">
<u-icon name="play-circle" color="#2979ff" size="28"></u-icon>
</view>
<view>
<u--text lines="2" lineHeight="24" size="16" :text="item.channelName"></u--text>
<view style="display:flex;margin-top:6px;">
<view style="margin-right:20px;">
<u--text prefixIcon="info-circle"
iconStyle="color:#606266;font-size:14px;margin-right:3px;" size="12"
color="#606266" mode="name" :text="item.model"></u--text>
</view>
</view>
<view class="status">
<u-tag v-if="item.statusInfo" :type="item.statusInfo.type" :plain="true"
size="mini" :text="item.statusInfo.name"></u-tag>
</view>
</view>
</view>
<u-empty mode="list" :show="channelTotal === 0" marginTop="30"></u-empty>
<u-loadmore :status="channelLoadStatus" v-if="channelTotal > channelQueryParams.pageSize"
marginTop="20" />
</view>
<view class="base-info" v-show="videotabIndex === 1">
<u--form labelPosition="left" :model="deviceForm" :rules="deviceRules" ref="deviceForm"
labelWidth="90" labelAlign="left">
<view class="card-wrap">
<view class="title-wrap">
<u--text :text="$tt('deviceDetail.basicMsg')" bold color="#606266"></u--text>
</view>
<u-form-item :label="$tt('deviceDetail.deviceName')" prop="deviceName" borderBottom>
<view class="item-right" slot="right">
<u--input v-model="deviceForm.deviceName" clearable border="none"
inputAlign="right"></u--input>
</view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.longitude')"
v-if="deviceForm.locationWay === 3" borderBottom>
<view class="item-right" slot="right">
<u--input v-model="deviceForm.longitude" type="digit"
:placeholder="$tt('deviceDetail.inputLongitude')" border="none"
inputAlign="right"></u--input>
</view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.latitude')"
v-if="deviceForm.locationWay === 3" borderBottom>
<view class="item-right" slot="right">
<u--input v-model="deviceForm.latitude" type="digit"
:placeholder="$tt('deviceDetail.inputLatitude')" border="none"
inputAlign="right"></u--input>
</view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.address')"
v-if="deviceForm.locationWay === 3" borderBottom>
<view class="item-right" slot="right">
<u--input v-model="deviceForm.networkAddress" border="none"
inputAlign="right"></u--input>
</view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.remark')"></u-form-item>
<u-textarea v-model="deviceForm.remark" height="40" fontSize="14"
:placeholder="$tt('deviceDetail.inputMsg')" style="background-color: #F7F7F7;"
confirmType="done"></u-textarea>
<view style="margin-top: 20px; display: flex; gap: 10px;">
<u-button v-if="!profile.deptId" @tap="gotoShare" size="small" color='#CCCCCC'
:customStyle="{fontSize: '30rpx',height: '88rpx',borderRadius: '10rpx'}">{{$tt('deviceDetail.share')}}</u-button>
<u-button type="primary" @tap="submitForm" size="small"
:customStyle="{fontSize: '30rpx',height: '88rpx',borderRadius: '10rpx'}">{{$tt('deviceDetail.preserve')}}</u-button>
</view>
</view>
<!-- 设备状态 -->
<view class="card-wrap">
<u-form-item borderBottom>
<view style="display: flex;">
<u-row>
<u-col :span="7.5">
<u--text :text="$tt('deviceDetail.deviceStatus')" bold
color="#000000"></u--text>
</u-col>
<u-col :span="2">
<u-button :text="$tt('home.notActive')" type="warning" size="mini"
plain v-if="deviceForm.status == 1"
customStyle="width:50px;margin-left:12rpx;"></u-button>
<u-button :text="$tt('home.disabled')" type="error" size="mini"
plain v-if="deviceForm.status == 2"
customStyle="width:50px;margin-left:12rpx;"></u-button>
<u-button :text="$tt('home.onLine')" type="success" size="mini"
plain v-if="deviceForm.status == 3"
customStyle="width:50px;margin-left:12rpx;"></u-button>
<u-button :text="$tt('home.offline')" type="info" size="mini" plain
v-if="deviceForm.status == 4"
customStyle="width:50px;margin-left:12rpx;"></u-button>
</u-col>
</u-row>
</view>
<view slot="right" @click="handleDeleteDevice">
<u-icon name="trash" color="#f85959" size="23"></u-icon>
</view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.serialNumber')" borderBottom>
<view class="item-right" slot="right"><u--text
:text="deviceForm.serialNumber"></u--text></view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.belongingProducts')" borderBottom>
<view class="item-right" slot="right"><u--text
:text="deviceForm.productName"></u--text>
</view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.firmwareVersion')" borderBottom>
<view class="item-right" slot="right"><u--text
:text="formatVersion(deviceForm.firmwareVersion)"></u--text></view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.positionMethod')" borderBottom
v-if="deviceForm.deviceType === 3">
<view class="item-right" slot="right"><u--text
:text="deviceForm.locationWayInfo.name"></u--text></view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.longitude')" borderBottom
v-if="deviceForm.longitude && deviceForm.locationWay !== 3">
<view class="item-right" slot="right"><u--text
:text="deviceForm.longitude"></u--text>
</view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.latitude')" borderBottom
v-if="deviceForm.latitude && deviceForm.locationWay !== 3">
<view class="item-right" slot="right"><u--text
:text="deviceForm.latitude"></u--text>
</view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.equipmentSignal')" borderBottom>
<view class="item-right" slot="right"><u--text
:text="$tt('deviceDetail.veryGood')" type="success"
v-if="deviceForm.rssi >= '-55'"></u--text>
<u--text :text="$tt('deviceDetail.excellent')" type="success"
v-else-if="deviceForm.rssi >= '-70' && deviceForm.rssi < '-55'"></u--text>
<u--text :text="$tt('deviceDetail.good')" type="success"
v-else-if="deviceForm.rssi >= '-85' && deviceForm.rssi < '-70'"></u--text>
<u--text :text="$tt('deviceDetail.average')" type="warning"
v-else-if="deviceForm.rssi >= '-100' && deviceForm.rssi < '-85'"></u--text>
<u--text :text="$tt('deviceDetail.poor')" type="error" v-else></u--text>
</view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.address')"
v-if="deviceForm.networkAddress && deviceForm.locationWay !== 3" borderBottom>
<view class="item-right" slot="right"><u--text
:text="deviceForm.networkAddress"></u--text>
</view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.networkAddress')" borderBottom>
<view class="item-right" slot="right"><u--text
:text="deviceForm.networkIp"></u--text>
</view>
</u-form-item>
<u-form-item :label="$tt('deviceDetail.activationTime')">
<view class="item-right" slot="right"><u--text
:text="deviceForm.activeTime"></u--text>
</view>
</u-form-item>
<u--image :src="imageUrl" radius="10" mode="aspectFill" width="100%" height="200">
<view slot="error" style="font-size: 18rpx;">{{$tt('deviceDetail.loadingFail')}}
</view>
<template v-slot:loading>
<u-loading-icon></u-loading-icon>
</template>
</u--image>
</view>
</u--form>
</view>
</view>
<!-- 设备删除提示 -->
<u-modal :show="show" :title="modalTitle" :content="content" showCancelButton @confirm="confirm"
@cancel="cancel"></u-modal>
</view>
</view>
</view>
<!-- 设备定时 -->
<device-timing v-if="tabbarIndex === 1" ref="deviceTiming" :device="deviceForm"></device-timing>
<!-- 设备日志 -->
<device-log v-if="tabbarIndex === 2" ref="deviceLog" :device="deviceForm"></device-log>
<!-- 设备统计 -->
<!-- <device-statistic v-show="tabbarIndex === 3" :device="deviceForm" :type="tabbarIndex"
ref="deviceStatistic"></device-statistic> -->
<device-history v-if="tabbarIndex === 3" ref="deviceHistory" :device="deviceForm"></device-history>
<!-- 设备组态 -->
<device-scada v-show="tabbarIndex === 4" :show="tabbarIndex === 4" :device="deviceForm"
ref="deviceScada"></device-scada>
<u-tabbar :value="tabbarIndex" @change="tabbarChange" :fixed="true" :placeholder="true"
:safeAreaInsetBottom="true" :border="false" activeColor="#3378FE" v-if="deviceForm.deviceType !==3">
<u-tabbar-item :text="$tt('deviceDetail.device')" @click="tabbarClick(0)">
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/device_blue.png">
</image>
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/device_black.png">
</image>
</u-tabbar-item>
<u-tabbar-item :text="$tt('deviceDetail.timing')" @click="tabbarClick(1)">
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/time_blue.png">
</image>
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/time_black.png">
</image>
</u-tabbar-item>
<u-tabbar-item :text="$tt('deviceDetail.journal')" @click="tabbarClick(2)">
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/log_blue.png">
</image>
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/log_black.png">
</image>
</u-tabbar-item>
<u-tabbar-item :text="$tt('deviceDetail.static')" @click="tabbarClick(3)">
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/statistic_blue.png">
</image>
<image style="width:18px;height:18px;" slot="inactive-icon"
src="/static/home/tabBar/statistic_black.png">
</image>
</u-tabbar-item>
<u-tabbar-item :text="$tt('deviceDetail.scada')" @click="tabbarClick(4)">
<image style="width:18px;height:18px;" slot="active-icon" src="/static/home/tabBar/scada_blue.png">
</image>
<image style="width:18px;height:18px;" slot="inactive-icon" src="/static/home/tabBar/scada_black.png">
</image>
</u-tabbar-item>
</u-tabbar>
<u-modal :show="showScada" content="暂无组态,请先去网页端配置模板组态" @confirm="() => showScada = false"
@cancel="() => showScada = false" showCancelButton></u-modal>
</view>
</template>
<script>
import projectConfig from '@/env.config.js';
import navbar from '@/components/navBar/index.vue';
import videoMonitor from './video/index.vue';
import deviceAlertLog from './log/alertLog.vue';
import runningStatus from './status/index.vue';
import deviceLog from './log/index.vue';
import deviceHistory from './statistic/history.vue';
import deviceMonitor from './monitor/index.vue';
import deviceTiming from './timing/index.vue';
import deviceScada from './scada.vue';
import { listChannel } from '@/apis/modules/sip';
import {
getDevice,
getRunningStatus,
cacheJsonThingsModel,
deviceSynchronization,
updateDevice,
delDevice
} from '@/apis/modules/device';
import { getSipStatusInfo, getLocationWayInfo } from '@/helpers/common.js'
export default {
components: {
navbar,
runningStatus,
deviceLog,
deviceMonitor,
deviceTiming,
videoMonitor,
deviceAlertLog,
deviceHistory,
deviceScada
},
data() {
return {
navTitle: this.$tt('navBar.deviceDetails'),
deviceId: 0,
baseTabIndex: 0, // 基础设备tab index
videotabIndex: 0,
tabbarIndex: 0,
baseTabList: [{
name: this.$tt('deviceDetail.overview')
}, {
name: this.$tt('deviceDetail.monitor')
}, {
name: this.$tt('deviceDetail.Surveillance')
}, {
name: this.$tt('deviceDetail.alert')
}],
videoTabList: [{
name: this.$tt('deviceDetail.channel')
}, {
name: this.$tt('deviceDetail.deviceDetail')
}],
show: false, // 删除设备模态框
modalTitle: '删除警告', // 对话框标题
content: '', // 对话框内容
deviceForm: {
isShadow: 0, // 避免u-switch报错初始化
deviceName: '',
locationWay: 1,
protocolCode: '',
}, // 设备详情
deviceDisable: 0, // 设备状态1=禁用0=不禁用)
isSubDev: false, // 是否有子设备
imageUrl: '', // 图片地址
locationList: [{ // 定位方式
value: 1,
text: this.$tt('deviceDetail.autoPosition')
}, {
value: 2,
text: this.$tt('deviceDetail.devicePosition')
}, {
value: 3,
text: this.$tt('deviceDetail.customLocation')
}],
deviceRules: { // 表单校验
deviceName: [{
required: true,
message: this.$tt('deviceDetail.deviceCheck'),
trigger: ['blur', 'change']
}]
},
// 设备通道
channelLoadStatus: 'nomore',
channelQueryParams: {
pageNum: 1,
pageSize: 10,
deviceSipId: '',
},
channelTotal: 0,
channelList: [],
showScada: false,
};
},
onLoad: function(option) {
this.deviceId = Number(option.deviceId);
this.deviceForm.protocolCode = option.protocolCode;
this.connectMqtt(); // 连接mqtt
},
onUnload() {
this.mqttUnSubscribe(this.deviceForm); // 取消订阅主题
},
onShow() {
uni.$off('re-device-timing-list');
uni.$once('re-device-timing-list', (dat) => {
if (dat) {
this.$refs.deviceTiming.dataList = [];
this.$refs.deviceTiming.queryParams.pageNum = 1;
this.$refs.deviceTiming.getList();
}
});
},
computed: {
topContainerStyle() {
return {
height: this.tabbarIndex === 0 ? '300rpx' : '250rpx',
};
},
},
methods: {
goBack() {
uni.navigateBack();
},
// 基础tab点击事件
handleBaseTabsClick(index) {
this.baseTabIndex = index;
},
// 视频tab点击事件
handleVideoTabsClick(index) {
this.videotabIndex = index;
},
/* 连接Mqtt消息服务器 */
async connectMqtt() {
if (this.$mqttTool.client === null) {
await this.$mqttTool.connect(this.vuex_token);
}
this.mqttCallback();
// 获取设备信息并订阅主题
this.getDevice();
},
/* Mqtt回调处理 */
mqttCallback() {
this.$mqttTool.client.on('message', (topic, message, buffer) => {
let topics = topic.split('/');
let productId = topics[1];
let deviceNum = topics[2];
message = JSON.parse(message.toString());
if (!message) {
return;
};
if (topics[3] == 'status' || topics[2] == 'status') {
console.log('接收到【设备状态-详情】主题:', topic);
console.log('接收到【设备状态-详情】内容:', message);
// 更新列表中设备的状态
if (this.deviceForm.serialNumber == deviceNum) {
this.deviceForm.status = message.status;
this.deviceForm.isShadow = message.isShadow;
this.deviceForm.rssid = message.rssid;
}
};
//不是modbus不转发到子页面其他设备的页面有回调方法
if (this.isSubDev) {
/*发送设备上报到子模块*/
if (topic.endsWith('ws/service')) {
console.log('接收到【设备数据上报】主题:', topic)
console.log('接收到【设备数据上报】主题:', message)
this.$bus.$emit("updateDeviceStatus", {
serialNumber: topics[2],
productId: this.deviceForm.productId,
data: message.message,
})
}
}
});
},
/** Mqtt订阅主题 */
mqttSubscribe(device) {
// 订阅当前设备状态和实时监测
let topicStatus = '/' + device.productId + '/' + device.serialNumber + '/status/post';
let topicMonitor = '/' + device.productId + '/' + device.serialNumber + '/monitor/post';
let topicReply = '/' + device.productId + '/' + device.serialNumber + '/service/reply';
let topicService = '/' + device.productId + '/' + device.serialNumber + '/ws/service';
let topics = [];
topics.push(topicStatus);
topics.push(topicMonitor);
topics.push(topicReply);
topics.push(topicService);
this.$mqttTool.subscribe(topics);
},
/** Mqtt取消订阅主题 */
mqttUnSubscribe(device) {
// 订阅当前设备状态和实时监测
let topicStatus = '/' + device.productId + '/' + device.serialNumber + '/status/post';
let topicMonitor = '/' + device.productId + '/' + device.serialNumber + '/monitor/post';
let topicReply = '/' + device.productId + '/' + device.serialNumber + '/service/reply';
let topicService = '/' + device.productId + '/' + device.serialNumber + '/ws/service';
let topics = [];
topics.push(topicStatus);
topics.push(topicMonitor);
topics.push(topicReply);
topics.push(topicService);
this.$mqttTool.unsubscribe(topics);
console.log('取消订阅', topics);
},
// 导航栏改变
tabbarChange() {},
// 导航栏单击
tabbarClick(index) {
this.tabbarIndex = index;
},
// 格式化版本显示
formatVersion(version) {
return `Version ${version}`;
},
// 刷新设备
onPullDownRefresh() {
if (this.tabbarIndex == 0) {
if (this.baseTabIndex == 0) {
// 设备运行状态
this.getDevice();
this.$refs.runningStatus.baseStatusRefresh();
} else if (this.baseTabIndex == 2) {
// 设备信息
this.getDevice();
} else {
uni.stopPullDownRefresh();
}
} else if (this.tabbarIndex == 1) {
// 设备定时
this.$refs.deviceTiming.deviceTimerRefresh();
uni.stopPullDownRefresh();
} else if (this.tabbarIndex == 3) {
// 设备统计
this.$refs.deviceStatistic.getCacheThingsModdel();
} else {
uni.stopPullDownRefresh();
}
},
/**获取设备详情*/
getDevice() {
getDevice(this.deviceId).then(async response => {
try {
let data = response.data;
if (data.deviceType !== 3) {
// 获取缓存物模型
data.cacheThingsModel = await this.getCacheThingsModdel(data.productId);
// 获取设备运行状态
data.thingsModels = await this.getRunningStatusInfo(this.deviceId, data.slaveId);
// 格式化物模型,拆分出监测值,数组添加前缀
this.formatThingsModel(data);
} else {
// 获取通道列表
this.channelList = await this.getChannelList(data.serialNumber);
}
this.navTitle = data.deviceName;
// this.isSubDev = data.subDeviceList.length > 0;
this.imageUrl = data.imgUrl;
if (this.imageUrl != null && this.imageUrl != '') {
this.imageUrl = projectConfig.baseUrl + this.imageUrl;
} else {
this.imageUrl = '/static/common/device.png';
}
// 禁用状态
if (data.status == 2) {
this.deviceDisable = 1;
}
// 获取定位方式
data.locationWayInfo = getLocationWayInfo(data.locationWay);
//Mqtt订阅
uni.stopPullDownRefresh();
this.mqttSubscribe(data);
//增加协议字段为后面数据采集做判断
data.protocolCode = this.deviceForm.protocolCode;
this.deviceForm = data;
} catch (e) {
console.log(e);
}
});
},
// 设置设备的状态1-未激活2-禁用3-在线4-离线)
setDeviceStatus() {
if (this.deviceDisable == 1) {
this.deviceForm.status = 2;
} else {
// 禁用状态,启用后状态是离线
if (this.deviceForm.status == 2) {
this.deviceForm.status = 4;
}
}
},
// 设备数据同步
deviceSynchronization() {
deviceSynchronization(this.deviceForm.serialNumber).then(async response => {
try {
let data = response.data;
if (data.deviceType !== 3) {
// 获取缓存物模型
data.cacheThingsModel = await this.getCacheThingsModdel(data.productId);
// 获取设备运行状态
data.thingsModels = await this.getRunningStatusInfo(this.deviceId, data.slaveId);
// 格式化物模型,拆分出监测值,数组添加前缀
this.formatThingsModel(data);
}
this.navTitle = data.deviceName;
this.imageUrl = data.imgUrl;
if (this.imageUrl != null && this.imageUrl != '') {
this.imageUrl = projectConfig.baseUrl + this.imageUrl;
} else {
this.imageUrl = '/static/common/device.png';
}
// 禁用状态
if (data.status == 2) {
this.deviceDisable = 1;
}
this.deviceForm = response.data;
} catch (e) {
console.log(e);
}
});
},
/** 删除设备按钮操作 */
handleDeleteDevice() {
this.content = '是否确认删除 ' + this.deviceForm.deviceName + ' ';
this.show = true;
},
// 确认删除设备
confirm() {
this.show = false;
delDevice(this.deviceForm.deviceId).then(res => {
if (res.code == 200) {
// 跳转主页,通过globalData传递参数
getApp().globalData.operate = 'operate';
uni.switchTab({
url: '/pages/tabBar/home/index'
});
} else if (res.code == 500) {
uni.showToast({
icon: 'none',
title: res.msg
});
}
});
},
// 取消
cancel() {
this.show = false;
},
/** 提交按钮 */
submitForm() {
if (!this.deviceForm.locationWay) {
uni.showToast({
icon: 'none',
title: this.$tt('deviceDetail.positionCheck')
});
return;
}
this.$refs.deviceForm.validate().then(e => {
if (this.deviceForm.deviceId !== 0) {
this.setDeviceStatus(); // 设置设备状态
let device = {
deviceId: this.deviceForm.deviceId,
deviceName: this.deviceForm.deviceName,
isShadow: this.deviceForm.isShadow,
status: this.deviceForm.status,
remark: this.deviceForm.remark,
locationWay: this.deviceForm.locationWay,
longitude: this.deviceForm.longitude,
latitude: this.deviceForm.latitude,
networkAddress: this.deviceForm.networkAddress
};
updateDevice(device).then(res => {
if (res.code === 200) {
uni.showToast({
icon: 'success',
title: this.$tt('deviceDetail.updateSuccess')
});
}
});
}
});
},
gotoShare() {
uni.$u.route('/pagesA/device/share/list', {
deviceId: this.deviceForm.deviceId,
productId: this.deviceForm.productId,
deviceName: this.deviceForm.deviceName
});
},
/** 获取缓存物模型*/
getCacheThingsModdel(productId) {
return new Promise((resolve, reject) => {
cacheJsonThingsModel(productId).then(res => {
resolve(JSON.parse(res.data));
}).catch(err => {
reject(err);
})
})
},
// 获取设备运行状态
getRunningStatusInfo(deviceId, slaveId) {
return new Promise((resolve, reject) => {
getRunningStatus(deviceId, slaveId).then(res => {
resolve(res.data.thingsModels);
}).catch(err => {
reject(err);
})
});
},
// 物模型格式化
formatThingsModel(data) {
if (data && data.length !== 0) {
data.chartList = [];
data.monitorList = [];
data.statisticList = [];
for (let i = 0; i < data.thingsModels.length; i++) {
if (data.thingsModels[i].datatype.type === "array") {
if (data.thingsModels[i].datatype.arrayType === "object") {
for (let k = 0; k < data.thingsModels[i].datatype.arrayParams.length; k++) {
for (let j = 0; j < data.thingsModels[i].datatype.arrayParams[k].length; j++) {
// 数组元素中参数ID添加前缀例如array_00_
let index = k > 9 ? String(k) : '0' + k;
let prefix = 'array_' + index + '_';
data.thingsModels[i].datatype.arrayParams[k][j].id = prefix + data.thingsModels[i]
.datatype.arrayParams[k][j].id;
// 图表、实时监测、监测统计分类放置
if (data.thingsModels[i].datatype.arrayParams[k][j].isChart === 1) {
data.thingsModels[i].datatype.arrayParams[k][j].name = "[" + data.thingsModels[
i].name + (k + 1) + "] " + data.thingsModels[i].datatype.arrayParams[k]
[j].name;
data.thingsModels[i].datatype.arrayParams[k][j].datatype.arrayType = "object";
data.chartList.push(data.thingsModels[i].datatype.arrayParams[k][j]);
// 监测统计
if (data.thingsModels[i].datatype.arrayParams[k][j].isHistory == 1) {
data.statisticList.push(data.thingsModels[i].datatype.arrayParams[k][j]);
}
// 实时监测
if (data.thingsModels[i].datatype.arrayParams[k][j].isMonitor == 1) {
data.monitorList.push(data.thingsModels[i].datatype.arrayParams[k][j]);
}
data.thingsModels[i].datatype.arrayParams[k].splice(j--, 1);
}
}
}
} else {
// 字符串拆分为物模型数组 model=id/name/type/isReadonly/value/shadow
let values = data.thingsModels[i].value && data.thingsModels[i].value != "" ? data
.thingsModels[i].value.split(',') : [];
let shadows = data.thingsModels[i].shadow && data.thingsModels[i].shadow != "" ? data
.thingsModels[i].shadow.split(',') : [];
for (let j = 0; j < data.thingsModels[i].datatype.arrayCount; j++) {
if (!data.thingsModels[i].datatype.arrayModel) {
data.thingsModels[i].datatype.arrayModel = [];
}
// 数组里面的ID需要添加前缀和索引例如array_00_temperature
let index = j > 9 ? String(j) : '0' + j;
let prefix = 'array_' + index + '_';
data.thingsModels[i].datatype.arrayModel[j] = {
id: prefix + data.thingsModels[i].id,
name: data.thingsModels[i].name,
type: data.thingsModels[i].type,
isReadonly: data.thingsModels[i].isReadonly,
value: values[j] ? values[j] : "",
shadow: shadows[j] ? shadows[j] : ""
}
}
}
} else if (data.thingsModels[i].datatype.type === "object") {
for (let j = 0; j < data.thingsModels[i].datatype.params.length; j++) {
// 图表、实时监测、监测统计分类放置
if (data.thingsModels[i].datatype.params[j].isChart === 1) {
// 图表
data.thingsModels[i].datatype.params[j].name = "[" + data.thingsModels[i].name + "] " +
data.thingsModels[i].datatype.params[j].name;
data.chartList.push(data.thingsModels[i].datatype.params[j]);
// 监测统计
if (data.thingsModels[i].datatype.params[j].isHistory == 1) {
data.statisticList.push(data.thingsModels[i].datatype.params[j]);
}
// 实时监测
if (data.thingsModels[i].datatype.params[j].isMonitor == 1) {
data.monitorList.push(data.thingsModels[i].datatype.params[j]);
}
data.thingsModels[i].datatype.params.splice(j--, 1);
}
}
} else if (data.thingsModels[i].isChart === 1) {
// 图表、实时监测、监测统计分类放置
data.chartList.push(data.thingsModels[i]);
// 监测统计
if (data.thingsModels[i].isHistory == 1) {
data.statisticList.push(data.thingsModels[i]);
}
// 实时监测
if (data.thingsModels[i].isMonitor == 1) {
data.monitorList.push(data.thingsModels[i]);
}
// 使用i--解决索引变更问题
data.thingsModels.splice(i--, 1);
}
}
}
},
// 设备通道
getChannelList(serialNumber) {
this.channelQueryParams.deviceSipId = serialNumber;
return new Promise((resolve, reject) => {
listChannel(this.channelQueryParams).then(response => {
this.channelTotal = response.total;
response.rows.map(item => {
item.statusInfo = getSipStatusInfo(item.status);
return item;
})
resolve(response.rows);
}).catch(error => {
reject(error);
});
});
},
gotoDevicePlayer(deviceSipId, channelSipId, status) {
let statusInfo = getSipStatusInfo(status)
if (status !== 3) {
uni.showToast({
icon: 'none',
title: `无法查看${getSipStatusInfo(status).name}数据`
});
return;
}
// #ifdef H5
uni.$u.route('/pages_player/list/devicePlayer', {
deviceId: deviceSipId,
channelSipId: channelSipId,
});
//#endif
// #ifdef APP-PLUS
uni.$u.route('/pages_player/list/devicePlayerApp', {
deviceId: deviceSipId,
channelSipId: channelSipId,
});
//#endif
// #ifdef MP-WEIXIN
uni.showToast({
icon: 'none',
title: this.$tt('timing.nosupported')
});
//#endif
},
async onReachBottom() {
if (this.baseTabIndex === 0) {
this.channelLoadStatus = 'loading';
this.channelQueryParams.pageNum = this.channelQueryParams.pageNum + 1;
if ((this.channelQueryParams.pageNum - 1) * this.channelQueryParams.pageSize >= this
.channelTotal) {
this.channelLoadStatus = 'nomore';
} else {
let list = await this.getChannelList(this.deviceForm.serialNumber);
this.channelList = this.channelList.concat(list);
this.channelLoadStatus = 'nomore';
}
}
},
// 返回监听
onBackPress(options) {
if (options.from === 'navigateBack') {
return false;
}
uni.switchTab({
url: '/pages/tabBar/home/index'
});
return true;
},
}
};
</script>
<style lang="scss">
page {
background: $uni-bg-color-grey;
}
</style>
<style lang="scss" scoped>
.device-detail {
height: 100vh;
width: 100%;
overflow: hidden;
.device-info {
// #ifdef MP-WEIXIN
height: calc(100vh - 168rpx);
// #endif
// #ifndef MP-WEIXIN
height: calc(100vh - 100rpx);
// #endif
display: flex;
flex-direction: column;
overflow-y: hidden;
.top-wrap {
position: relative;
background-size: cover;
background-image: url('@/static/common/bg.png');
// #ifdef MP-WEIXIN
min-height: 480rpx;
// #endif
// #ifdef H5
min-height: 480rpx;
// #endif
// #ifdef APP-PLUS
min-height: 550rpx;
// #endif
z-index: 0;
.sub-wrap {
padding: 27rpx 34rpx;
::v-deep .u-subsection--button {
height: 68rpx;
padding: 8rpx;
}
}
}
.content-wrap {
flex: 1 1 auto;
border-top-left-radius: 40rpx;
border-top-right-radius: 40rpx;
background: $uni-bg-color-grey;
margin-top: -6.826rem;
// #ifndef H5 || APP-PLUS || MP-ALIPAY
margin-top: -4.746rem;
// #endif
z-index: 1;
overflow-x: hidden;
overflow-y: auto;
.device-content {
padding: 28rpx;
.channel_wrap {
.item_body {
position: relative;
display: flex;
align-items: center;
margin-bottom: 6px;
background: #fff;
border-radius: 20rpx;
.img {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
border-radius: 5px;
width: 90px;
height: 60px;
background: #e5e5e5;
margin: 10px;
}
.status {
position: absolute;
right: 13px;
top: 13px;
}
}
}
.base-info {
.card-wrap {
background-color: #fff;
padding: 29rpx 32rpx;
border-radius: 20rpx;
margin-bottom: 24rpx;
.item-right {
display: flex;
flex-direction: row;
}
::v-deep .u-form-item__body {
height: 80rpx;
}
.title-wrap {
display: flex;
padding: 20rpx 0;
border-bottom: 1px solid #efefef;
}
}
}
}
}
}
}
</style>