...
|
...
|
@@ -3,229 +3,236 @@ |
3
|
3
|
<!-- 公共组件-每个页面必须引入 -->
|
4
|
4
|
<public-module></public-module>
|
5
|
5
|
<u-sticky :bgColor="bgColor">
|
6
|
|
- <u-tabs :list="list" :current="currentTab" @click="handleTabClick" :activeStyle="activeColor"
|
7
|
|
- :inactiveStyle="inActiveColor" :scrollable="isScrollable" />
|
|
6
|
+ <u-tabs :list="list" :current="currentTab" :lineWidth="transportType == deviceTypeNum.GBT?0:30" @click=" handleTabClick " :activeStyle="{activeColor}"
|
|
7
|
+ :inactiveStyle="inActiveColor" :scrollable="isScrollable" itemStyle="padding: 0 11px;display:flex;flex-direction:row;align-items:center;justify-content:start;height:44px" />
|
8
|
8
|
</u-sticky>
|
9
|
9
|
<view class="mt-3">
|
10
|
|
- <basic-info v-show="currentTab == 0" :deviceDetail="deviceDetail" />
|
11
|
|
- <realtime-data v-show="currentTab === 1" :recordList="recordList" />
|
12
|
|
- <history-data v-if="currentTab === 2" :keys="keys" :yesterday="yesterday" :today="today"
|
13
|
|
- :timeDiff="timeDiff" :historyData="historyData" :entityId="entityId" :start="startTs" :end="endTs"
|
14
|
|
- @update="handleUpdate" />
|
15
|
|
- <alarm-history v-show="currentTab === 3" :deviceId="deviceId" />
|
16
|
|
- <commond-record v-if="currentTab === 4" :tbDeviceId="entityId" />
|
|
10
|
+ <basic-info v-show=" currentTab == 0 " :deviceDetail=" deviceDetail " />
|
|
11
|
+ <realtime-data v-show=" currentTab === 1 " :recordList=" recordList " />
|
|
12
|
+ <history-data v-if=" currentTab === 2 " :keys=" keys " :yesterday=" yesterday " :today=" today " :timeDiff=" timeDiff "
|
|
13
|
+ :historyData=" historyData " :entityId=" entityId " :start=" startTs " :end=" endTs " @update=" handleUpdate " />
|
|
14
|
+ <alarm-history v-show=" currentTab === 3 " :deviceId=" deviceId " />
|
|
15
|
+ <commond-record v-if=" currentTab === 4 " :tbDeviceId=" entityId " />
|
17
|
16
|
</view>
|
18
|
17
|
</view>
|
19
|
18
|
</template>
|
20
|
19
|
|
21
|
20
|
<script>
|
22
|
|
- import fTabbar from "@/components/module/f-tabbar/f-tabbar";
|
23
|
|
- import basicInfo from "./components/basic-info.vue";
|
24
|
|
- import realtimeData from "./components/realtime-data.vue";
|
25
|
|
- import alarmHistory from "./components/alarm-history.vue";
|
26
|
|
- import historyData from "./components/history-data.vue";
|
27
|
|
- import commondRecord from "./components/command-record.vue";
|
28
|
|
- import { getDeviceKeys,getHistoryData } from "./api/index.js";
|
29
|
|
- import {formatToDate} from "@/plugins/utils.js";
|
30
|
|
- import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js";
|
31
|
|
- import moment from "moment";
|
32
|
|
- import base from "@/config/baseUrl.js";
|
33
|
|
- import { list } from './config/data.js'
|
34
|
|
- import api from '@/api'
|
|
21
|
+import fTabbar from "@/components/module/f-tabbar/f-tabbar";
|
|
22
|
+import basicInfo from "./components/basic-info.vue";
|
|
23
|
+import realtimeData from "./components/realtime-data.vue";
|
|
24
|
+import alarmHistory from "./components/alarm-history.vue";
|
|
25
|
+import historyData from "./components/history-data.vue";
|
|
26
|
+import commondRecord from "./components/command-record.vue";
|
|
27
|
+import { getDeviceKeys, getHistoryData } from "./api/index.js";
|
|
28
|
+import { formatToDate } from "@/plugins/utils.js";
|
|
29
|
+import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js";
|
|
30
|
+import moment from "moment";
|
|
31
|
+import base from "@/config/baseUrl.js";
|
|
32
|
+import { list } from './config/data.js'
|
|
33
|
+import api from '@/api'
|
|
34
|
+import { deviceTypeNum } from './config/data'
|
35
|
35
|
|
36
|
|
- export default {
|
37
|
|
- mixins: [MescrollCompMixin],
|
38
|
|
- components: {
|
39
|
|
- fTabbar,
|
40
|
|
- basicInfo,
|
41
|
|
- realtimeData,
|
42
|
|
- alarmHistory,
|
43
|
|
- historyData,
|
44
|
|
- commondRecord,
|
45
|
|
- },
|
46
|
|
- data() {
|
47
|
|
- return {
|
48
|
|
- bgColor: '#fff',
|
49
|
|
- activeColor: {
|
50
|
|
- fontWeight: 'bold',
|
51
|
|
- color: '#333',
|
52
|
|
- },
|
53
|
|
- inActiveColor: {
|
54
|
|
- color: '#999',
|
55
|
|
- },
|
56
|
|
- list,
|
57
|
|
- currentTab: 0,
|
58
|
|
- deviceId: "",
|
59
|
|
- deviceDetail: {},
|
60
|
|
- keys: [],
|
61
|
|
- yesterday: "",
|
62
|
|
- today: "",
|
63
|
|
- timeDiff: "",
|
64
|
|
- historyData: [],
|
65
|
|
- entityId: "",
|
66
|
|
- startTs: "",
|
67
|
|
- endTs: "",
|
68
|
|
- recordList: [], //实时数据
|
69
|
|
- isScrollable: false,
|
70
|
|
- attrList: [],
|
71
|
|
- getAttrList:[]
|
72
|
|
- };
|
73
|
|
- },
|
74
|
|
- onUnload() {
|
75
|
|
- // 页面关闭时,销毁webSocket连接,否则第二次会存在连接不到的情况
|
76
|
|
- uni.closeSocket();
|
77
|
|
- },
|
78
|
|
- async onLoad(options) {
|
79
|
|
- const {id,alarmStatus,lastOnlineTime,tbDeviceId,deviceProfileId} = options;
|
80
|
|
- this.deviceId = id;
|
81
|
|
- const res = await api.deviceApi.getDeviceDetail(this.deviceId)
|
82
|
|
- if(!res) return
|
83
|
|
- this.deviceDetail = {
|
84
|
|
- ...res,
|
85
|
|
- alarmStatus,
|
86
|
|
- lastOnlineTime,
|
87
|
|
- };
|
88
|
|
- // 设备类型不是网关子设备的添加一个命令记录的选项卡
|
89
|
|
- if (this.deviceDetail.deviceType !== "SENSOR") {
|
90
|
|
- this.list.push({
|
91
|
|
- name: "命令记录",
|
92
|
|
- });
|
93
|
|
- const res = new Map()
|
94
|
|
- this.list = this.list.filter((item) => !res.has(item.name) && res.set(item.name, 1))
|
95
|
|
- } else {
|
96
|
|
- this.list = this.list.filter(item => item.name !=='命令记录')
|
97
|
|
- }
|
98
|
|
- this.isScrollable = this.list.length > 4;
|
99
|
|
- if (res.deviceProfileId) {
|
100
|
|
- this.getAttrList = await api.deviceApi.getAttribute(res.deviceProfileId)
|
101
|
|
- if (Array.isArray(this.getAttrList)) {
|
102
|
|
- this.attrList = this.getAttrList?.map(m => {
|
103
|
|
- return m.identifier
|
104
|
|
- })
|
105
|
|
- }
|
106
|
|
- }
|
107
|
|
- // 连接webSockte
|
108
|
|
- const socketTask = uni.connectSocket({
|
109
|
|
- url: `${base.socketPrefix}://${base.baseWebSocketUrl}/api/ws/plugins/telemetry?token=` + uni.getStorageSync("userInfo").isToken, //仅为示例,并非真实接口地址。
|
110
|
|
- complete: () => {},
|
|
36
|
+export default {
|
|
37
|
+ mixins: [MescrollCompMixin],
|
|
38
|
+ components: {
|
|
39
|
+ fTabbar,
|
|
40
|
+ basicInfo,
|
|
41
|
+ realtimeData,
|
|
42
|
+ alarmHistory,
|
|
43
|
+ historyData,
|
|
44
|
+ commondRecord,
|
|
45
|
+ },
|
|
46
|
+ data() {
|
|
47
|
+ return {
|
|
48
|
+ bgColor: '#fff',
|
|
49
|
+ activeColor: {
|
|
50
|
+ fontWeight: 'bold',
|
|
51
|
+ color: '#333',
|
|
52
|
+ },
|
|
53
|
+ inActiveColor: {
|
|
54
|
+ color: '#999',
|
|
55
|
+ },
|
|
56
|
+ list,
|
|
57
|
+ currentTab: 0,
|
|
58
|
+ deviceId: "",
|
|
59
|
+ deviceDetail: {},
|
|
60
|
+ keys: [],
|
|
61
|
+ yesterday: "",
|
|
62
|
+ today: "",
|
|
63
|
+ timeDiff: "",
|
|
64
|
+ historyData: [],
|
|
65
|
+ entityId: "",
|
|
66
|
+ startTs: "",
|
|
67
|
+ endTs: "",
|
|
68
|
+ recordList: [], //实时数据
|
|
69
|
+ isScrollable: false,
|
|
70
|
+ attrList: [],
|
|
71
|
+ getAttrList: [],
|
|
72
|
+ transportType:"",
|
|
73
|
+ deviceTypeNum,
|
|
74
|
+ };
|
|
75
|
+ },
|
|
76
|
+ onUnload() {
|
|
77
|
+ // 页面关闭时,销毁webSocket连接,否则第二次会存在连接不到的情况
|
|
78
|
+ uni.closeSocket();
|
|
79
|
+ },
|
|
80
|
+ async onLoad(options) {
|
|
81
|
+ const { id, alarmStatus, lastOnlineTime, tbDeviceId, deviceProfileId, transportType } = options;
|
|
82
|
+ this.deviceId = id;
|
|
83
|
+ this.transportType = transportType
|
|
84
|
+ const res = await api.deviceApi.getDeviceDetail(this.deviceId)
|
|
85
|
+ if (!res) return
|
|
86
|
+ this.deviceDetail = {
|
|
87
|
+ ...res,
|
|
88
|
+ alarmStatus,
|
|
89
|
+ lastOnlineTime,
|
|
90
|
+ transportType
|
|
91
|
+ };
|
|
92
|
+ // 设备类型不是网关子设备的添加一个命令记录的选项卡
|
|
93
|
+ if (this.deviceDetail.deviceType !== "SENSOR") {
|
|
94
|
+ this.list.push({
|
|
95
|
+ name: "命令记录",
|
111
|
96
|
});
|
112
|
|
- uni.onSocketOpen((header) => {
|
113
|
|
- socketTask.send({
|
114
|
|
- data: JSON.stringify({
|
115
|
|
- attrSubCmds: [],
|
116
|
|
- tsSubCmds: [{
|
117
|
|
- entityType: "DEVICE",
|
118
|
|
- entityId: tbDeviceId,
|
119
|
|
- scope: "LATEST_TELEMETRY",
|
120
|
|
- cmdId: 1,
|
121
|
|
- keys: this.attrList.join(','),
|
122
|
|
- }, ],
|
123
|
|
- historyCmds: [],
|
124
|
|
- entityDataCmds: [],
|
125
|
|
- entityDataUnsubscribeCmds: [],
|
126
|
|
- alarmDataCmds: [],
|
127
|
|
- alarmDataUnsubscribeCmds: [],
|
128
|
|
- entityCountCmds: [],
|
129
|
|
- entityCountUnsubscribeCmds: [],
|
130
|
|
- }),
|
131
|
|
- success() {},
|
132
|
|
- });
|
|
97
|
+ const res = new Map()
|
|
98
|
+ this.list = this.list.filter((item) => !res.has(item.name) && res.set(item.name, 1))
|
|
99
|
+ } else {
|
|
100
|
+ this.list = this.list.filter(item => item.name !== '命令记录')
|
|
101
|
+ }
|
|
102
|
+ if (transportType === deviceTypeNum.GBT) {
|
|
103
|
+ this.list = this.list.filter(item => item.name == '基础信息')
|
|
104
|
+ }
|
|
105
|
+ this.isScrollable = this.list.length > 4;
|
|
106
|
+ if (res.deviceProfileId) {
|
|
107
|
+ this.getAttrList = await api.deviceApi.getAttribute(res.deviceProfileId)
|
|
108
|
+ if (Array.isArray(this.getAttrList)) {
|
|
109
|
+ this.attrList = this.getAttrList?.map(m => {
|
|
110
|
+ return m.identifier
|
|
111
|
+ })
|
|
112
|
+ }
|
|
113
|
+ }
|
|
114
|
+ // 连接webSockte
|
|
115
|
+ const socketTask = uni.connectSocket({
|
|
116
|
+ url: `${base.socketPrefix}://${base.baseWebSocketUrl}/api/ws/plugins/telemetry?token=` + uni.getStorageSync("userInfo").isToken, //仅为示例,并非真实接口地址。
|
|
117
|
+ complete: () => { },
|
|
118
|
+ });
|
|
119
|
+ uni.onSocketOpen((header) => {
|
|
120
|
+ socketTask.send({
|
|
121
|
+ data: JSON.stringify({
|
|
122
|
+ attrSubCmds: [],
|
|
123
|
+ tsSubCmds: [{
|
|
124
|
+ entityType: "DEVICE",
|
|
125
|
+ entityId: tbDeviceId,
|
|
126
|
+ scope: "LATEST_TELEMETRY",
|
|
127
|
+ cmdId: 1,
|
|
128
|
+ keys: this.attrList.join(','),
|
|
129
|
+ },],
|
|
130
|
+ historyCmds: [],
|
|
131
|
+ entityDataCmds: [],
|
|
132
|
+ entityDataUnsubscribeCmds: [],
|
|
133
|
+ alarmDataCmds: [],
|
|
134
|
+ alarmDataUnsubscribeCmds: [],
|
|
135
|
+ entityCountCmds: [],
|
|
136
|
+ entityCountUnsubscribeCmds: [],
|
|
137
|
+ }),
|
|
138
|
+ success() { },
|
133
|
139
|
});
|
134
|
|
- socketTask.onMessage((msg) => {
|
135
|
|
- const { data } = JSON.parse(msg.data);
|
136
|
|
- const newArray = [];
|
137
|
|
- for (const key in data) {
|
138
|
|
- const [time, value] = data[key].flat(1);
|
139
|
|
- let obj = { key,time,value, };
|
140
|
|
- if (this.recordList.length === 0) {
|
141
|
|
- this.recordList.unshift(obj);
|
142
|
|
- } else {
|
143
|
|
- newArray.push(obj);
|
144
|
|
- }
|
|
140
|
+ });
|
|
141
|
+ socketTask.onMessage((msg) => {
|
|
142
|
+ const { data } = JSON.parse(msg.data);
|
|
143
|
+ const newArray = [];
|
|
144
|
+ for (const key in data) {
|
|
145
|
+ const [time, value] = data[key].flat(1);
|
|
146
|
+ let obj = { key, time, value, };
|
|
147
|
+ if (this.recordList.length === 0) {
|
|
148
|
+ this.recordList.unshift(obj);
|
|
149
|
+ } else {
|
|
150
|
+ newArray.push(obj);
|
145
|
151
|
}
|
146
|
|
- newArray.forEach((item) => {
|
147
|
|
- let flag = false;
|
148
|
|
- this.recordList.forEach((item1) => {
|
149
|
|
- if (item1.key === item.key) {
|
150
|
|
- item1.value = item.value;
|
151
|
|
- item1.time = item.time;
|
152
|
|
- flag = true;
|
153
|
|
- }
|
154
|
|
- });
|
155
|
|
- if (!flag) {
|
156
|
|
- this.recordList.unshift(item);
|
|
152
|
+ }
|
|
153
|
+ newArray.forEach((item) => {
|
|
154
|
+ let flag = false;
|
|
155
|
+ this.recordList.forEach((item1) => {
|
|
156
|
+ if (item1.key === item.key) {
|
|
157
|
+ item1.value = item.value;
|
|
158
|
+ item1.time = item.time;
|
|
159
|
+ flag = true;
|
157
|
160
|
}
|
158
|
161
|
});
|
159
|
|
- this.recordList = this.recordList?.map((item) => {
|
160
|
|
- return {
|
161
|
|
- ...item,
|
162
|
|
- time: formatToDate(item.time, "YYYY-MM-DD HH:mm:ss"),
|
163
|
|
- };
|
164
|
|
- });
|
165
|
|
- if(this.getAttrList){
|
166
|
|
- this.getAttrList.forEach(item=>{
|
167
|
|
- this.recordList?.forEach(item1=>{
|
168
|
|
- if(item.identifier===item1.key){
|
169
|
|
- item1.name=item.name
|
170
|
|
- }
|
171
|
|
- })
|
172
|
|
- })
|
|
162
|
+ if (!flag) {
|
|
163
|
+ this.recordList.unshift(item);
|
173
|
164
|
}
|
174
|
165
|
});
|
175
|
|
- const keys = await getDeviceKeys(tbDeviceId);
|
176
|
|
- this.keys=this.getAttrList || []
|
177
|
|
- // 昨天
|
178
|
|
- this.yesterday = moment().subtract(1, "days").format("YYYY-MM-DD");
|
179
|
|
- // 今天
|
180
|
|
- this.today = moment().format("YYYY-MM-DD");
|
181
|
|
- // 开始时间
|
182
|
|
- this.startTs = moment().subtract(1, "days").format("x");
|
183
|
|
- // 结束时间
|
184
|
|
- this.endTs = moment().format("x");
|
185
|
|
- this.entityId = tbDeviceId;
|
186
|
|
- const data = await getHistoryData({
|
187
|
|
- entityId: tbDeviceId,
|
188
|
|
- startTs: this.startTs,
|
189
|
|
- endTs: this.endTs,
|
190
|
|
- keys: keys[0],
|
191
|
|
- // interval: 1800000,
|
192
|
|
- limit: 7,
|
193
|
|
- agg: 'NONE'
|
|
166
|
+ this.recordList = this.recordList?.map((item) => {
|
|
167
|
+ return {
|
|
168
|
+ ...item,
|
|
169
|
+ time: formatToDate(item.time, "YYYY-MM-DD HH:mm:ss"),
|
|
170
|
+ };
|
194
|
171
|
});
|
195
|
|
- this.timeDiff = "30分钟";
|
196
|
|
- if (!Object.keys(data).length) return;
|
197
|
|
- this.historyData = data[keys[0]].map((item) => {
|
|
172
|
+ if (this.getAttrList) {
|
|
173
|
+ this.getAttrList.forEach(item => {
|
|
174
|
+ this.recordList?.forEach(item1 => {
|
|
175
|
+ if (item.identifier === item1.key) {
|
|
176
|
+ item1.name = item.name
|
|
177
|
+ }
|
|
178
|
+ })
|
|
179
|
+ })
|
|
180
|
+ }
|
|
181
|
+ });
|
|
182
|
+ const keys = await getDeviceKeys(tbDeviceId);
|
|
183
|
+ this.keys = this.getAttrList || []
|
|
184
|
+ // 昨天
|
|
185
|
+ this.yesterday = moment().subtract(1, "days").format("YYYY-MM-DD");
|
|
186
|
+ // 今天
|
|
187
|
+ this.today = moment().format("YYYY-MM-DD");
|
|
188
|
+ // 开始时间
|
|
189
|
+ this.startTs = moment().subtract(1, "days").format("x");
|
|
190
|
+ // 结束时间
|
|
191
|
+ this.endTs = moment().format("x");
|
|
192
|
+ this.entityId = tbDeviceId;
|
|
193
|
+ const data = await getHistoryData({
|
|
194
|
+ entityId: tbDeviceId,
|
|
195
|
+ startTs: this.startTs,
|
|
196
|
+ endTs: this.endTs,
|
|
197
|
+ keys: keys[0],
|
|
198
|
+ // interval: 1800000,
|
|
199
|
+ limit: 7,
|
|
200
|
+ agg: 'NONE'
|
|
201
|
+ });
|
|
202
|
+ this.timeDiff = "30分钟";
|
|
203
|
+ if (!Object.keys(data).length) return;
|
|
204
|
+ this.historyData = data[keys[0]].map((item) => {
|
|
205
|
+ return {
|
|
206
|
+ value: item.value,
|
|
207
|
+ ts: formatToDate(item.ts, "YYYY-MM-DD HH:mm:ss"),
|
|
208
|
+ };
|
|
209
|
+ });
|
|
210
|
+ },
|
|
211
|
+ methods: {
|
|
212
|
+ handleTabClick({
|
|
213
|
+ index
|
|
214
|
+ }) {
|
|
215
|
+ this.currentTab = index;
|
|
216
|
+ },
|
|
217
|
+ handleUpdate(data, e) {
|
|
218
|
+ if (!Array.isArray(data)) {
|
|
219
|
+ this.historyData = [];
|
|
220
|
+ return;
|
|
221
|
+ }
|
|
222
|
+ this.historyData = data.map((item) => {
|
198
|
223
|
return {
|
199
|
224
|
value: item.value,
|
200
|
225
|
ts: formatToDate(item.ts, "YYYY-MM-DD HH:mm:ss"),
|
201
|
226
|
};
|
202
|
227
|
});
|
203
|
228
|
},
|
204
|
|
- methods: {
|
205
|
|
- handleTabClick({
|
206
|
|
- index
|
207
|
|
- }) {
|
208
|
|
- this.currentTab = index;
|
209
|
|
- },
|
210
|
|
- handleUpdate(data, e) {
|
211
|
|
- if (!Array.isArray(data)) {
|
212
|
|
- this.historyData = [];
|
213
|
|
- return;
|
214
|
|
- }
|
215
|
|
- this.historyData = data.map((item) => {
|
216
|
|
- return {
|
217
|
|
- value: item.value,
|
218
|
|
- ts: formatToDate(item.ts, "YYYY-MM-DD HH:mm:ss"),
|
219
|
|
- };
|
220
|
|
- });
|
221
|
|
- },
|
222
|
|
- },
|
223
|
|
- };
|
|
229
|
+ },
|
|
230
|
+};
|
224
|
231
|
</script>
|
225
|
232
|
|
226
|
233
|
<style lang="scss" scoped>
|
227
|
|
- .device-detail-page {
|
228
|
|
- height: 100vh;
|
229
|
|
- background-color: #f8f9fa;
|
230
|
|
- }
|
|
234
|
+.device-detail-page {
|
|
235
|
+ height: 100vh;
|
|
236
|
+ background-color: #f8f9fa;
|
|
237
|
+}
|
231
|
238
|
</style> |
...
|
...
|
|