device-detail.vue 6.65 KB
<template>
	<view class="device-detail-page">
		<!-- 公共组件-每个页面必须引入 -->
		<public-module></public-module>
		<u-sticky :bgColor="bgColor">
			<u-tabs :list="list" :current="currentTab" :lineWidth="transportType == deviceTypeNum.GBT?0:30" @click=" handleTabClick " :activeStyle="{activeColor}"
				:inactiveStyle="inActiveColor" :scrollable="isScrollable" itemStyle="padding: 0 11px;display:flex;flex-direction:row;align-items:center;justify-content:start;height:44px" />
		</u-sticky>
		<view class="mt-3">
			<basic-info v-show=" currentTab == 0 " :deviceDetail=" deviceDetail " />
			<realtime-data v-show=" currentTab === 1 " :recordList=" recordList " />
			<history-data v-if=" currentTab === 2 " :keys=" keys " :yesterday=" yesterday " :today=" today " :timeDiff=" timeDiff "
				:historyData=" historyData " :entityId=" entityId " :start=" startTs " :end=" endTs " @update=" handleUpdate " />
			<alarm-history v-show=" currentTab === 3 " :deviceId=" deviceId " />
			<commond-record v-if=" currentTab === 4 " :tbDeviceId=" entityId " />
		</view>
	</view>
</template>

<script>
import fTabbar from "@/components/module/f-tabbar/f-tabbar";
import basicInfo from "./components/basic-info.vue";
import realtimeData from "./components/realtime-data.vue";
import alarmHistory from "./components/alarm-history.vue";
import historyData from "./components/history-data.vue";
import commondRecord from "./components/command-record.vue";
import { getDeviceKeys, getHistoryData } from "./api/index.js";
import { formatToDate } from "@/plugins/utils.js";
import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js";
import moment from "moment";
import base from "@/config/baseUrl.js";
import { list } from './config/data.js'
import api from '@/api'
import { deviceTypeNum } from './config/data'

export default {
	mixins: [MescrollCompMixin],
	components: {
		fTabbar,
		basicInfo,
		realtimeData,
		alarmHistory,
		historyData,
		commondRecord,
	},
	data() {
		return {
			bgColor: '#fff',
			activeColor: {
				fontWeight: 'bold',
				color: '#333',
			},
			inActiveColor: {
				color: '#999',
			},
			list,
			currentTab: 0,
			deviceId: "",
			deviceDetail: {},
			keys: [],
			yesterday: "",
			today: "",
			timeDiff: "",
			historyData: [],
			entityId: "",
			startTs: "",
			endTs: "",
			recordList: [], //实时数据
			isScrollable: false,
			attrList: [],
			getAttrList: [],
			transportType:"",
			deviceTypeNum,
		};
	},
	onUnload() {
		// 页面关闭时,销毁webSocket连接,否则第二次会存在连接不到的情况
		uni.closeSocket();
	},
	async onLoad(options) {
		const { id, alarmStatus, lastOnlineTime, tbDeviceId, deviceProfileId, transportType } = options;
		this.deviceId = id;
		this.transportType = transportType
		const res = await api.deviceApi.getDeviceDetail(this.deviceId)
		if (!res) return
		this.deviceDetail = {
			...res,
			alarmStatus,
			lastOnlineTime,
			transportType
		};
		// 设备类型不是网关子设备的添加一个命令记录的选项卡
		if (this.deviceDetail.deviceType !== "SENSOR") {
			this.list.push({
				name: "命令记录",
			});
			const res = new Map()
			this.list = this.list.filter((item) => !res.has(item.name) && res.set(item.name, 1))
		} else {
			this.list = this.list.filter(item => item.name !== '命令记录')
		}
		if (transportType === deviceTypeNum.GBT) {
			this.list = this.list.filter(item => item.name == '基础信息')
		}
		this.isScrollable = this.list.length > 4;
		if (res.deviceProfileId) {
			this.getAttrList = await api.deviceApi.getAttribute(res.deviceProfileId)
			if (Array.isArray(this.getAttrList)) {
				this.attrList = this.getAttrList?.map(m => {
					return m.identifier
				})
			}
		}
		// 连接webSockte
		const socketTask = uni.connectSocket({
			url: `${base.socketPrefix}://${base.baseWebSocketUrl}/api/ws/plugins/telemetry?token=` + uni.getStorageSync("userInfo").isToken, //仅为示例,并非真实接口地址。
			complete: () => { },
		});
		uni.onSocketOpen((header) => {
			socketTask.send({
				data: JSON.stringify({
					attrSubCmds: [],
					tsSubCmds: [{
						entityType: "DEVICE",
						entityId: tbDeviceId,
						scope: "LATEST_TELEMETRY",
						cmdId: 1,
						keys: this.attrList.join(','),
					},],
					historyCmds: [],
					entityDataCmds: [],
					entityDataUnsubscribeCmds: [],
					alarmDataCmds: [],
					alarmDataUnsubscribeCmds: [],
					entityCountCmds: [],
					entityCountUnsubscribeCmds: [],
				}),
				success() { },
			});
		});
		socketTask.onMessage((msg) => {
			const { data } = JSON.parse(msg.data);
			const newArray = [];
			for (const key in data) {
				const [time, value] = data[key].flat(1);
				let obj = { key, time, value, };
				if (this.recordList.length === 0) {
					this.recordList.unshift(obj);
				} else {
					newArray.push(obj);
				}
			}
			newArray.forEach((item) => {
				let flag = false;
				this.recordList.forEach((item1) => {
					if (item1.key === item.key) {
						item1.value = item.value;
						item1.time = item.time;
						flag = true;
					}
				});
				if (!flag) {
					this.recordList.unshift(item);
				}
			});
			this.recordList = this.recordList?.map((item) => {
				return {
					...item,
					time: formatToDate(item.time, "YYYY-MM-DD HH:mm:ss"),
				};
			});
			if (this.getAttrList) {
				this.getAttrList.forEach(item => {
					this.recordList?.forEach(item1 => {
						if (item.identifier === item1.key) {
							item1.name = item.name
						}
					})
				})
			}
		});
		const keys = await getDeviceKeys(tbDeviceId);
		this.keys = this.getAttrList || []
		// 昨天
		this.yesterday = moment().subtract(1, "days").format("YYYY-MM-DD");
		// 今天
		this.today = moment().format("YYYY-MM-DD");
		// 开始时间
		this.startTs = moment().subtract(1, "days").format("x");
		// 结束时间
		this.endTs = moment().format("x");
		this.entityId = tbDeviceId;
		const data = await getHistoryData({
			entityId: tbDeviceId,
			startTs: this.startTs,
			endTs: this.endTs,
			keys: keys[0],
			// interval: 1800000,
			limit: 7,
			agg: 'NONE'
		});
		this.timeDiff = "30分钟";
		if (!Object.keys(data).length) return;
		this.historyData = data[keys[0]].map((item) => {
			return {
				value: item.value,
				ts: formatToDate(item.ts, "YYYY-MM-DD HH:mm:ss"),
			};
		});
	},
	methods: {
		handleTabClick({
			index
		}) {
			this.currentTab = index;
		},
		handleUpdate(data, e) {
			if (!Array.isArray(data)) {
				this.historyData = [];
				return;
			}
			this.historyData = data.map((item) => {
				return {
					value: item.value,
					ts: formatToDate(item.ts, "YYYY-MM-DD HH:mm:ss"),
				};
			});
		},
	},
};
</script>

<style lang="scss" scoped>
.device-detail-page {
	height: 100vh;
	background-color: #f8f9fa;
}
</style>