Showing
3 changed files
with
597 additions
and
323 deletions
1 | <template> | 1 | <template> |
2 | - <view class="device-detail-page"> | ||
3 | - <!-- 公共组件-每个页面必须引入 --> | ||
4 | - <public-module></public-module> | ||
5 | - <u-sticky bgColor="#fff"> | ||
6 | - <u-tabs | ||
7 | - :list="list" | ||
8 | - :current="currentTab" | ||
9 | - @click="handleTabClick" | ||
10 | - :activeStyle="{ | ||
11 | - fontWeight: 'bold', | ||
12 | - color: '#333' | ||
13 | - }" | ||
14 | - :inactiveStyle="{ | ||
15 | - color: '#999' | ||
16 | - }" | ||
17 | - :scrollable="isScrollable" | ||
18 | - /> | ||
19 | - </u-sticky> | ||
20 | - <view style="margin-top:30rpx;"> | ||
21 | - <basicInfo v-show="currentTab == 0" :deviceDetail="deviceDetail" /> | ||
22 | - <realTimeData v-show="currentTab === 1" :recordList="recordList" /> | ||
23 | - <historyData | ||
24 | - v-if="currentTab === 2" | ||
25 | - :keys="keys" | ||
26 | - :yesterday="yesterday" | ||
27 | - :today="today" | ||
28 | - :timeDiff="timeDiff" | ||
29 | - :historyData="historyData" | ||
30 | - :entityId="entityId" | ||
31 | - :start="startTs" | ||
32 | - :end="endTs" | ||
33 | - @update="handleUpdate" | ||
34 | - /> | ||
35 | - <alarmHistory v-show="currentTab === 3" :deviceId="deviceId" /> | ||
36 | - <commondRecord v-if="currentTab === 4" :tbDeviceId="entityId" /> | ||
37 | - </view> | ||
38 | - </view> | 2 | + <view class="device-detail-page"> |
3 | + <!-- 公共组件-每个页面必须引入 --> | ||
4 | + <public-module></public-module> | ||
5 | + <u-sticky bgColor="#fff"> | ||
6 | + <u-tabs | ||
7 | + :list="list" | ||
8 | + :current="currentTab" | ||
9 | + @click="handleTabClick" | ||
10 | + :activeStyle="{ | ||
11 | + fontWeight: 'bold', | ||
12 | + color: '#333', | ||
13 | + }" | ||
14 | + :inactiveStyle="{ | ||
15 | + color: '#999', | ||
16 | + }" | ||
17 | + :scrollable="isScrollable" | ||
18 | + /> | ||
19 | + </u-sticky> | ||
20 | + <view style="margin-top: 30rpx"> | ||
21 | + <basicInfo v-show="currentTab == 0" :deviceDetail="deviceDetail" /> | ||
22 | + <realTimeData v-show="currentTab === 1" :recordList="recordList" /> | ||
23 | + <historyData | ||
24 | + v-if="currentTab === 2" | ||
25 | + :keys="keys" | ||
26 | + :yesterday="yesterday" | ||
27 | + :today="today" | ||
28 | + :timeDiff="timeDiff" | ||
29 | + :historyData="historyData" | ||
30 | + :entityId="entityId" | ||
31 | + :start="startTs" | ||
32 | + :end="endTs" | ||
33 | + @update="handleUpdate" | ||
34 | + /> | ||
35 | + <alarmHistory v-show="currentTab === 3" :deviceId="deviceId" /> | ||
36 | + <commondRecord v-if="currentTab === 4" :tbDeviceId="entityId" /> | ||
37 | + </view> | ||
38 | + </view> | ||
39 | </template> | 39 | </template> |
40 | 40 | ||
41 | <script> | 41 | <script> |
42 | -import fTabbar from '@/components/module/f-tabbar/f-tabbar'; | ||
43 | -import basicInfo from './tabDetail/basicInfo.vue'; | ||
44 | -import realTimeData from './tabDetail/realtimeData.vue'; | ||
45 | -import alarmHistory from './tabDetail/alarmHistory.vue'; | ||
46 | -import historyData from './tabDetail/historyData.vue'; | ||
47 | -import commondRecord from './tabDetail/CommandRecord.vue'; | ||
48 | -import { getDeviceKeys, getHistoryData } from './api/index.js'; | ||
49 | -import { formatToDate } from '@/plugins/utils.js'; | 42 | +import fTabbar from "@/components/module/f-tabbar/f-tabbar"; |
43 | +import basicInfo from "./tabDetail/basicInfo.vue"; | ||
44 | +import realTimeData from "./tabDetail/realtimeData.vue"; | ||
45 | +import alarmHistory from "./tabDetail/alarmHistory.vue"; | ||
46 | +import historyData from "./tabDetail/historyData.vue"; | ||
47 | +import commondRecord from "./tabDetail/CommandRecord.vue"; | ||
48 | +import { getDeviceKeys, getHistoryData } from "./api/index.js"; | ||
49 | +import { formatToDate } from "@/plugins/utils.js"; | ||
50 | import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js"; | 50 | import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js"; |
51 | -import moment from 'moment'; | ||
52 | -export default { | ||
53 | - mixins: [MescrollCompMixin], | ||
54 | - components: { | ||
55 | - fTabbar, | ||
56 | - basicInfo, | ||
57 | - realTimeData, | ||
58 | - alarmHistory, | ||
59 | - historyData, | ||
60 | - commondRecord | ||
61 | - }, | ||
62 | - data() { | ||
63 | - return { | ||
64 | - list: [{ name: '基础信息' }, { name: '实时数据' }, { name: '历史数据' }, { name: '告警记录' }], | ||
65 | - currentTab: 0, | ||
66 | - deviceId: '', | ||
67 | - deviceDetail: {}, | ||
68 | - keys: [], | ||
69 | - yesterday: '', | ||
70 | - today: '', | ||
71 | - timeDiff: '', | ||
72 | - historyData: [], | ||
73 | - entityId: '', | ||
74 | - startTs: '', | ||
75 | - endTs: '', | ||
76 | - recordList: [], | ||
77 | - isScrollable: false | ||
78 | - }; | ||
79 | - }, | ||
80 | - onUnload() { | ||
81 | - // 页面关闭时,销毁webSocket连接,否则第二次会存在连接不到的情况 | ||
82 | - uni.closeSocket(); | ||
83 | - }, | ||
84 | - async onLoad(options) { | ||
85 | - const { id, alarmStatus, lastOnlineTime, tbDeviceId } = options; | ||
86 | - this.deviceId = id; | ||
87 | - const res = await uni.$u.http.get(`/yt/device/${id}`); | ||
88 | - this.deviceDetail = { ...res, alarmStatus, lastOnlineTime }; | 51 | +import moment from "moment"; |
52 | +import base from "@/config/baseUrl.js"; | ||
89 | 53 | ||
90 | - // 设备类型不是网关子设备的添加一个命令记录的选项卡 | ||
91 | - if (this.deviceDetail.deviceType !== 'SENSOR') { | ||
92 | - this.list.push({ | ||
93 | - name: '命令记录' | ||
94 | - }); | ||
95 | - } | ||
96 | - this.isScrollable = this.list.length > 4; | ||
97 | - // 连接webSockte | ||
98 | - const socketTask = uni.connectSocket({ | ||
99 | - url: 'wss://dev.thingskit.com/api/ws/plugins/telemetry?token=' + uni.getStorageSync('userInfo').isToken, //仅为示例,并非真实接口地址。 | ||
100 | - complete: () => {} | ||
101 | - }); | ||
102 | - uni.onSocketOpen(header => { | ||
103 | - socketTask.send({ | ||
104 | - data: JSON.stringify({ | ||
105 | - attrSubCmds: [], | ||
106 | - tsSubCmds: [ | ||
107 | - { | ||
108 | - entityType: 'DEVICE', | ||
109 | - entityId: tbDeviceId, | ||
110 | - scope: 'LATEST_TELEMETRY', | ||
111 | - cmdId: 1 | ||
112 | - } | ||
113 | - ], | ||
114 | - historyCmds: [], | ||
115 | - entityDataCmds: [], | ||
116 | - entityDataUnsubscribeCmds: [], | ||
117 | - alarmDataCmds: [], | ||
118 | - alarmDataUnsubscribeCmds: [], | ||
119 | - entityCountCmds: [], | ||
120 | - entityCountUnsubscribeCmds: [] | ||
121 | - }), | ||
122 | - success() {} | ||
123 | - }); | ||
124 | - }); | ||
125 | - socketTask.onMessage(msg => { | ||
126 | - const { data } = JSON.parse(msg.data); | ||
127 | - const newArray = []; | ||
128 | - for (const key in data) { | ||
129 | - const [time, value] = data[key].flat(1); | ||
130 | - let obj = { key, time, value }; | ||
131 | - if (this.recordList.length === 0) { | ||
132 | - this.recordList.unshift(obj); | ||
133 | - } else { | ||
134 | - newArray.push(obj); | ||
135 | - } | ||
136 | - } | ||
137 | - newArray.forEach(item => { | ||
138 | - let flag = false; | ||
139 | - this.recordList.forEach(item1 => { | ||
140 | - if (item1.key === item.key) { | ||
141 | - item1.value = item.value; | ||
142 | - item1.time = item.time; | ||
143 | - flag = true; | ||
144 | - } | ||
145 | - }); | ||
146 | - if (!flag) { | ||
147 | - this.recordList.unshift(item); | ||
148 | - } | ||
149 | - }); | ||
150 | - this.recordList = this.recordList.map(item => { | ||
151 | - return { | ||
152 | - ...item, | ||
153 | - time: formatToDate(item.time, 'YYYY-MM-DD HH:mm:ss') | ||
154 | - }; | ||
155 | - }); | ||
156 | - }); | 54 | +export default { |
55 | + mixins: [MescrollCompMixin], | ||
56 | + components: { | ||
57 | + fTabbar, | ||
58 | + basicInfo, | ||
59 | + realTimeData, | ||
60 | + alarmHistory, | ||
61 | + historyData, | ||
62 | + commondRecord, | ||
63 | + }, | ||
64 | + data() { | ||
65 | + return { | ||
66 | + list: [ | ||
67 | + { | ||
68 | + name: "基础信息", | ||
69 | + }, | ||
70 | + { | ||
71 | + name: "实时数据", | ||
72 | + }, | ||
73 | + { | ||
74 | + name: "历史数据", | ||
75 | + }, | ||
76 | + { | ||
77 | + name: "告警记录", | ||
78 | + }, | ||
79 | + ], | ||
80 | + currentTab: 0, | ||
81 | + deviceId: "", | ||
82 | + deviceDetail: {}, | ||
83 | + keys: [], | ||
84 | + yesterday: "", | ||
85 | + today: "", | ||
86 | + timeDiff: "", | ||
87 | + historyData: [], | ||
88 | + entityId: "", | ||
89 | + startTs: "", | ||
90 | + endTs: "", | ||
91 | + recordList: [], | ||
92 | + isScrollable: false, | ||
93 | + }; | ||
94 | + }, | ||
95 | + onUnload() { | ||
96 | + // 页面关闭时,销毁webSocket连接,否则第二次会存在连接不到的情况 | ||
97 | + uni.closeSocket(); | ||
98 | + }, | ||
99 | + async onLoad(options) { | ||
100 | + const { id, alarmStatus, lastOnlineTime, tbDeviceId } = options; | ||
101 | + this.deviceId = id; | ||
102 | + const res = await uni.$u.http.get(`/yt/device/${id}`); | ||
103 | + this.deviceDetail = { | ||
104 | + ...res, | ||
105 | + alarmStatus, | ||
106 | + lastOnlineTime, | ||
107 | + }; | ||
157 | 108 | ||
158 | - const keys = await getDeviceKeys(tbDeviceId); | ||
159 | - this.keys = [keys]; | ||
160 | - // 昨天 | ||
161 | - this.yesterday = moment() | ||
162 | - .subtract(1, 'days') | ||
163 | - .format('YYYY-MM-DD'); | ||
164 | - // 今天 | ||
165 | - this.today = moment().format('YYYY-MM-DD'); | ||
166 | - // 开始时间 | ||
167 | - this.startTs = moment() | ||
168 | - .subtract(1, 'days') | ||
169 | - .format('x'); | ||
170 | - // 结束时间 | ||
171 | - this.endTs = moment().format('x'); | ||
172 | - this.entityId = tbDeviceId; | 109 | + // 设备类型不是网关子设备的添加一个命令记录的选项卡 |
110 | + if (this.deviceDetail.deviceType !== "SENSOR") { | ||
111 | + this.list.push({ | ||
112 | + name: "命令记录", | ||
113 | + }); | ||
114 | + } | ||
115 | + this.isScrollable = this.list.length > 4; | ||
116 | + // 连接webSockte | ||
117 | + const socketTask = uni.connectSocket({ | ||
118 | + url: | ||
119 | + `${base.socketPrefix}://${base.baseWebSocketUrl}/api/ws/plugins/telemetry?token=` + | ||
120 | + uni.getStorageSync("userInfo").isToken, //仅为示例,并非真实接口地址。 | ||
121 | + complete: () => {}, | ||
122 | + }); | ||
123 | + uni.onSocketOpen((header) => { | ||
124 | + socketTask.send({ | ||
125 | + data: JSON.stringify({ | ||
126 | + attrSubCmds: [], | ||
127 | + tsSubCmds: [ | ||
128 | + { | ||
129 | + entityType: "DEVICE", | ||
130 | + entityId: tbDeviceId, | ||
131 | + scope: "LATEST_TELEMETRY", | ||
132 | + cmdId: 1, | ||
133 | + }, | ||
134 | + ], | ||
135 | + historyCmds: [], | ||
136 | + entityDataCmds: [], | ||
137 | + entityDataUnsubscribeCmds: [], | ||
138 | + alarmDataCmds: [], | ||
139 | + alarmDataUnsubscribeCmds: [], | ||
140 | + entityCountCmds: [], | ||
141 | + entityCountUnsubscribeCmds: [], | ||
142 | + }), | ||
143 | + success() {}, | ||
144 | + }); | ||
145 | + }); | ||
146 | + socketTask.onMessage((msg) => { | ||
147 | + const { data } = JSON.parse(msg.data); | ||
148 | + const newArray = []; | ||
149 | + for (const key in data) { | ||
150 | + const [time, value] = data[key].flat(1); | ||
151 | + let obj = { | ||
152 | + key, | ||
153 | + time, | ||
154 | + value, | ||
155 | + }; | ||
156 | + if (this.recordList.length === 0) { | ||
157 | + this.recordList.unshift(obj); | ||
158 | + } else { | ||
159 | + newArray.push(obj); | ||
160 | + } | ||
161 | + } | ||
162 | + newArray.forEach((item) => { | ||
163 | + let flag = false; | ||
164 | + this.recordList.forEach((item1) => { | ||
165 | + if (item1.key === item.key) { | ||
166 | + item1.value = item.value; | ||
167 | + item1.time = item.time; | ||
168 | + flag = true; | ||
169 | + } | ||
170 | + }); | ||
171 | + if (!flag) { | ||
172 | + this.recordList.unshift(item); | ||
173 | + } | ||
174 | + }); | ||
175 | + this.recordList = this.recordList.map((item) => { | ||
176 | + return { | ||
177 | + ...item, | ||
178 | + time: formatToDate(item.time, "YYYY-MM-DD HH:mm:ss"), | ||
179 | + }; | ||
180 | + }); | ||
181 | + }); | ||
173 | 182 | ||
174 | - const data = await getHistoryData({ | ||
175 | - entityId: tbDeviceId, | ||
176 | - startTs: this.startTs, | ||
177 | - endTs: this.endTs, | ||
178 | - keys: keys[0], | ||
179 | - interval: 1800000 | ||
180 | - }); | ||
181 | - this.timeDiff = '30分钟'; | ||
182 | - if (!Object.keys(data).length) return; | 183 | + const keys = await getDeviceKeys(tbDeviceId); |
184 | + this.keys = [keys]; | ||
185 | + // 昨天 | ||
186 | + this.yesterday = moment().subtract(1, "days").format("YYYY-MM-DD"); | ||
187 | + // 今天 | ||
188 | + this.today = moment().format("YYYY-MM-DD"); | ||
189 | + // 开始时间 | ||
190 | + this.startTs = moment().subtract(1, "days").format("x"); | ||
191 | + // 结束时间 | ||
192 | + this.endTs = moment().format("x"); | ||
193 | + this.entityId = tbDeviceId; | ||
183 | 194 | ||
184 | - this.historyData = data[keys[0]] | ||
185 | - .map(item => { | ||
186 | - return { | ||
187 | - value: item.value, | ||
188 | - ts: formatToDate(item.ts, 'YYYY-MM-DD HH:mm:ss') | ||
189 | - }; | ||
190 | - }) | 195 | + const data = await getHistoryData({ |
196 | + entityId: tbDeviceId, | ||
197 | + startTs: this.startTs, | ||
198 | + endTs: this.endTs, | ||
199 | + keys: keys[0], | ||
200 | + interval: 1800000, | ||
201 | + }); | ||
202 | + this.timeDiff = "30分钟"; | ||
203 | + if (!Object.keys(data).length) return; | ||
191 | 204 | ||
192 | - }, | ||
193 | - methods: { | ||
194 | - handleTabClick({ index }) { | ||
195 | - this.currentTab = index; | ||
196 | - }, | ||
197 | - handleUpdate(data) { | ||
198 | - if (!Array.isArray(data)) { | ||
199 | - this.historyData = []; | ||
200 | - return; | ||
201 | - } | ||
202 | - this.historyData = data | ||
203 | - .map(item => { | ||
204 | - return { | ||
205 | - value: item.value, | ||
206 | - ts: formatToDate(item.ts, 'YYYY-MM-DD HH:mm:ss') | ||
207 | - }; | ||
208 | - }) | ||
209 | - } | ||
210 | - } | 205 | + this.historyData = data[keys[0]].map((item) => { |
206 | + return { | ||
207 | + value: item.value, | ||
208 | + ts: formatToDate(item.ts, "YYYY-MM-DD HH:mm:ss"), | ||
209 | + }; | ||
210 | + }); | ||
211 | + }, | ||
212 | + methods: { | ||
213 | + handleTabClick({ index }) { | ||
214 | + this.currentTab = index; | ||
215 | + }, | ||
216 | + handleUpdate(data) { | ||
217 | + if (!Array.isArray(data)) { | ||
218 | + this.historyData = []; | ||
219 | + return; | ||
220 | + } | ||
221 | + this.historyData = data.map((item) => { | ||
222 | + return { | ||
223 | + value: item.value, | ||
224 | + ts: formatToDate(item.ts, "YYYY-MM-DD HH:mm:ss"), | ||
225 | + }; | ||
226 | + }); | ||
227 | + }, | ||
228 | + }, | ||
211 | }; | 229 | }; |
212 | </script> | 230 | </script> |
213 | 231 | ||
214 | <style lang="scss" scoped> | 232 | <style lang="scss" scoped> |
215 | .device-detail-page { | 233 | .device-detail-page { |
216 | - height: 100vh; | ||
217 | - background-color: #f8f9fa; | 234 | + height: 100vh; |
235 | + background-color: #f8f9fa; | ||
218 | } | 236 | } |
219 | -</style> | 237 | +</style> |
1 | +.cu-modal { | ||
2 | + position: fixed; | ||
3 | + top: 0; | ||
4 | + right: 0; | ||
5 | + bottom: 0; | ||
6 | + left: 0; | ||
7 | + z-index: 1110; | ||
8 | + opacity: 0; | ||
9 | + outline: 0; | ||
10 | + text-align: center; | ||
11 | + -ms-transform: scale(1.185); | ||
12 | + transform: scale(1.185); | ||
13 | + backface-visibility: hidden; | ||
14 | + perspective: 2000upx; | ||
15 | + background: rgba(0, 0, 0, 0.6); | ||
16 | + transition: all 0.3s ease-in-out 0s; | ||
17 | + pointer-events: none; | ||
18 | +} | ||
19 | + | ||
20 | +.cu-modal::before { | ||
21 | + content: "\200B"; | ||
22 | + display: inline-block; | ||
23 | + height: 100%; | ||
24 | + vertical-align: middle; | ||
25 | +} | ||
26 | + | ||
27 | +.cu-modal.show { | ||
28 | + opacity: 1; | ||
29 | + transition-duration: 0.3s; | ||
30 | + -ms-transform: scale(1); | ||
31 | + transform: scale(1); | ||
32 | + overflow-x: hidden; | ||
33 | + overflow-y: auto; | ||
34 | + pointer-events: auto; | ||
35 | +} | ||
36 | + | ||
37 | +.cu-dialog { | ||
38 | + position: relative; | ||
39 | + display: inline-block; | ||
40 | + vertical-align: middle; | ||
41 | + margin-left: auto; | ||
42 | + margin-right: auto; | ||
43 | + width: 680upx; | ||
44 | + max-width: 100%; | ||
45 | + background-color: #f8f8f8; | ||
46 | + border-radius: 10upx; | ||
47 | + overflow: hidden; | ||
48 | +} | ||
49 | + | ||
50 | +.cu-modal.bottom-modal::before { | ||
51 | + vertical-align: bottom; | ||
52 | +} | ||
53 | + | ||
54 | +.cu-modal.bottom-modal .cu-dialog { | ||
55 | + width: 100%; | ||
56 | + border-radius: 0; | ||
57 | +} | ||
58 | + | ||
59 | +.cu-modal.bottom-modal { | ||
60 | + margin-bottom: -1000upx; | ||
61 | +} | ||
62 | + | ||
63 | +.cu-modal.bottom-modal.show { | ||
64 | + margin-bottom: 0; | ||
65 | +} | ||
66 | + | ||
67 | +.cu-modal.drawer-modal { | ||
68 | + transform: scale(1); | ||
69 | + display: flex; | ||
70 | +} | ||
71 | + | ||
72 | +.cu-modal.drawer-modal .cu-dialog { | ||
73 | + height: 100%; | ||
74 | + min-width: 200upx; | ||
75 | + border-radius: 0; | ||
76 | + margin: initial; | ||
77 | + transition-duration: 0.3s; | ||
78 | +} | ||
79 | + | ||
80 | +.cu-modal.drawer-modal.justify-start .cu-dialog { | ||
81 | + transform: translateX(-100%); | ||
82 | +} | ||
83 | + | ||
84 | +.cu-modal.drawer-modal.justify-end .cu-dialog { | ||
85 | + transform: translateX(100%); | ||
86 | +} | ||
87 | + | ||
88 | +.cu-modal.drawer-modal.show .cu-dialog { | ||
89 | + transform: translateX(0%); | ||
90 | +} | ||
91 | + | ||
92 | +.cu-modal .cu-dialog>.cu-bar:first-child .action { | ||
93 | + min-width: 100rpx; | ||
94 | + margin-right: 0; | ||
95 | + min-height: 100rpx; | ||
96 | +} |
@@ -4,17 +4,26 @@ | @@ -4,17 +4,26 @@ | ||
4 | <public-module /> | 4 | <public-module /> |
5 | <view class="basic-title"> | 5 | <view class="basic-title"> |
6 | <view class="u-flex"> | 6 | <view class="u-flex"> |
7 | - <view style="padding-left: 32rpx;"><u-icon v-if="deviceDetail.deviceInfo.longitude !== ''" @click="handleClick" name="map-fill"></u-icon></view> | 7 | + <view style="padding-left: 32rpx;"> |
8 | + <u-icon v-if="deviceDetail.deviceInfo.longitude !== ''" @click="handleClick" name="map-fill"> | ||
9 | + </u-icon> | ||
10 | + </view> | ||
8 | <view style="margin-left: 20rpx;">{{ deviceDetail.name }}</view> | 11 | <view style="margin-left: 20rpx;">{{ deviceDetail.name }}</view> |
9 | - <view | ||
10 | - style="margin-left: 20rpx; font-size: 14px;" | ||
11 | - :style="{ color: deviceDetail.deviceState === 'INACTIVE' ? '#666' : deviceDetail.deviceState === 'ONLINE' ? '#377DFF' : '#DE4437' }" | ||
12 | - > | 12 | + <view style="margin-left: 20rpx; font-size: 14px;" |
13 | + :style="{ color: deviceDetail.deviceState === 'INACTIVE' ? '#666' : deviceDetail.deviceState === 'ONLINE' ? '#377DFF' : '#DE4437' }"> | ||
13 | {{ deviceDetail.deviceState === 'INACTIVE' ? '待激活' : deviceDetail.deviceState === 'ONLINE' ? '在线' : '离线' }} | 14 | {{ deviceDetail.deviceState === 'INACTIVE' ? '待激活' : deviceDetail.deviceState === 'ONLINE' ? '在线' : '离线' }} |
14 | </view> | 15 | </view> |
15 | </view> | 16 | </view> |
16 | - <view style="margin-right: 20rpx;" v-if="deviceDetail.deviceState === 'ONLINE' && deviceDetail.deviceType !== 'SENSOR'"> | ||
17 | - <u-button type="primary" shape="circle" size="mini" text="下发命令" @click="showModal" /> | 17 | + <view style="margin-right: 20rpx;" |
18 | + v-if="deviceDetail.deviceState === 'ONLINE' && deviceDetail.deviceType !== 'SENSOR'"> | ||
19 | + <!-- #ifdef MP --> | ||
20 | + <u-button type="primary" shape="circle" size="mini" text="下发命令" @click="showModalBtn" /> | ||
21 | + <!-- #endif --> | ||
22 | + <!-- #ifdef APP-PLUS --> | ||
23 | + <view class="cu-item" @tap="showModal" data-target="Modal"> | ||
24 | + <text>下发命令</text> | ||
25 | + </view> | ||
26 | + <!-- #endif --> | ||
18 | </view> | 27 | </view> |
19 | </view> | 28 | </view> |
20 | <view class="detail"> | 29 | <view class="detail"> |
@@ -48,9 +57,60 @@ | @@ -48,9 +57,60 @@ | ||
48 | <view class="detail-value">{{ deviceDetail.description }}</view> | 57 | <view class="detail-value">{{ deviceDetail.description }}</view> |
49 | </view> | 58 | </view> |
50 | </view> | 59 | </view> |
51 | - | ||
52 | <!-- 下发命令 --> | 60 | <!-- 下发命令 --> |
53 | - <u-modal :show="showModel" closeOnClickOverlay :showConfirmButton="false" width="720rpx" @close="hiddenModal" @touchmove.stop.prevent="disabledScroll"> | 61 | + <!-- #ifdef APP-PLUS --> |
62 | + <view v-show="showNodal" class="cu-modal" :class="modalName=='Modal'?'show':''"> | ||
63 | + <view class="cu-dialog" style=""> | ||
64 | + <view class="modal_main"> | ||
65 | + <view class='nav-list margin-top'> | ||
66 | + <view style="width: 100%; padding: 0 30rpx;"> | ||
67 | + <view style="text-align: center; font-weight:700;margin-top: 40rpx;">命令下发</view> | ||
68 | + <view style="height: 20rpx;"></view> | ||
69 | + <view class="u-flex"> | ||
70 | + <text | ||
71 | + style="color: #333; font-size: 14px;font-weight:700;margin-right: 30rpx;">下发类型:</text> | ||
72 | + <view> | ||
73 | + <radio-group style="display: flex;" @change="radioChange"> | ||
74 | + <label class="uni-list-cell uni-list-cell-pd" v-for="(item, index) in items" | ||
75 | + :key="item.value"> | ||
76 | + <view style="display: flex"> | ||
77 | + <view style="margin-left: 10rpx;"> | ||
78 | + <radio :value="item.value" :checked="index === current" /> | ||
79 | + </view> | ||
80 | + <view style="width:10rpx"></view> | ||
81 | + <view style="margin-left: 10rpx;">{{item.name}}</view> | ||
82 | + </view> | ||
83 | + </label> | ||
84 | + </radio-group> | ||
85 | + </view> | ||
86 | + </view> | ||
87 | + <view style="margin-top: 15rpx"> | ||
88 | + <view class="cusAppplusContent"> | ||
89 | + <textarea v-model="inputCommandVal" placeholder="请输入下发内容(json格式)" /> | ||
90 | + </view> | ||
91 | + </view> | ||
92 | + <view class="button-group"> | ||
93 | + <view> | ||
94 | + <view class="cusAppplusCancelBtn" @click="cancelCommand"><text | ||
95 | + style="color: #333333">取消</text> | ||
96 | + </view> | ||
97 | + </view> | ||
98 | + <view> | ||
99 | + <view class="cusAppplusConfrimBtn" @click="confirmCommand"> | ||
100 | + <text style="color:white">确认</text> | ||
101 | + </view> | ||
102 | + </view> | ||
103 | + </view> | ||
104 | + <view style="height:30rpx"></view> | ||
105 | + </view> | ||
106 | + </view> | ||
107 | + </view> | ||
108 | + </view> | ||
109 | + </view> | ||
110 | + <!-- #endif --> | ||
111 | + <!-- #ifdef MP --> | ||
112 | + <u-modal :show="showModel" closeOnClickOverlay :showConfirmButton="false" width="720rpx" @close="hiddenModal" | ||
113 | + @touchmove.stop.prevent="disabledScroll"> | ||
54 | <view style="width: 100%; padding: 0 30rpx;"> | 114 | <view style="width: 100%; padding: 0 30rpx;"> |
55 | <view style="text-align: center; font-weight:700;margin-bottom: 40rpx;">命令下发</view> | 115 | <view style="text-align: center; font-weight:700;margin-bottom: 40rpx;">命令下发</view> |
56 | <view class="u-flex"> | 116 | <view class="u-flex"> |
@@ -62,144 +122,244 @@ | @@ -62,144 +122,244 @@ | ||
62 | <u-radio activeColor="#3388FF" label="双向" name="TwoWay"></u-radio> | 122 | <u-radio activeColor="#3388FF" label="双向" name="TwoWay"></u-radio> |
63 | </u-radio-group> | 123 | </u-radio-group> |
64 | </view> | 124 | </view> |
65 | - <view style="margin-top: 28rpx;width: 100%;"><u--textarea placeholder="请输入下发内容(json格式)" v-model="inputCommandVal" /></view> | 125 | + <view style="margin-top: 28rpx;width: 100%;"> |
126 | + <u--textarea placeholder="请输入下发内容(json格式)" v-model="inputCommandVal" /> | ||
127 | + </view> | ||
66 | 128 | ||
67 | <view class="button-group"> | 129 | <view class="button-group"> |
68 | - <view><u-button :customStyle="{ color: '#333' }" color="#e3e3e5" shape="circle" text="取消" @click="cancelCommand"></u-button></view> | ||
69 | - <view><u-button color="#3388ff" shape="circle" text="确认" @click="confirmCommand"></u-button></view> | 130 | + <view> |
131 | + <u-button :customStyle="{ color: '#333' }" color="#e3e3e5" shape="circle" text="取消" | ||
132 | + @click="cancelCommand"></u-button> | ||
133 | + </view> | ||
134 | + <view> | ||
135 | + <u-button color="#3388ff" shape="circle" text="确认" @click="confirmCommand"></u-button> | ||
136 | + </view> | ||
70 | </view> | 137 | </view> |
71 | </view> | 138 | </view> |
72 | </u-modal> | 139 | </u-modal> |
140 | + <!-- #endif --> | ||
73 | </view> | 141 | </view> |
74 | </template> | 142 | </template> |
75 | 143 | ||
76 | <script> | 144 | <script> |
77 | -import { formatToDate } from '@/plugins/utils.js'; | ||
78 | -import { issueCommand } from '../api/index.js'; | ||
79 | -export default { | ||
80 | - props: { | ||
81 | - deviceDetail: { | ||
82 | - type: Object, | ||
83 | - default: () => ({}) | ||
84 | - } | ||
85 | - }, | ||
86 | - data() { | ||
87 | - return { | ||
88 | - showModel: false, | ||
89 | - commandType: 'OneWay', | ||
90 | - commandValue: {}, | ||
91 | - inputCommandVal: '' | ||
92 | - }; | ||
93 | - }, | ||
94 | - computed: { | ||
95 | - deviceType() { | ||
96 | - return this.deviceDetail.deviceType === 'DIRECT_CONNECTION' | ||
97 | - ? '直连设备' | ||
98 | - : this.deviceDetail.deviceType === 'GATEWAY' | ||
99 | - ? '网关设备' | ||
100 | - : this.deviceDetail.deviceType === 'SENSOR' | ||
101 | - ? '网关子设备' | ||
102 | - : ''; | ||
103 | - }, | ||
104 | - alarmStatus() { | ||
105 | - return this.deviceDetail.alarmStatus === '0' ? '否' : '是'; | 145 | + import { |
146 | + formatToDate | ||
147 | + } from '@/plugins/utils.js'; | ||
148 | + import { | ||
149 | + issueCommand | ||
150 | + } from '../api/index.js'; | ||
151 | + export default { | ||
152 | + props: { | ||
153 | + deviceDetail: { | ||
154 | + type: Object, | ||
155 | + default: () => ({}) | ||
156 | + } | ||
106 | }, | 157 | }, |
107 | - formatLastOnlineTime() { | ||
108 | - return formatToDate(Number(this.deviceDetail.lastOnlineTime), 'YYYY-MM-DD HH:mm:ss'); | ||
109 | - } | ||
110 | - }, | ||
111 | - onLoad(e) { | ||
112 | - // 隐藏原生的tabbar | ||
113 | - uni.hideTabBar(); | ||
114 | - }, | ||
115 | - mounted() {}, | ||
116 | - methods: { | ||
117 | - handleClick() { | ||
118 | - const data = { | ||
119 | - longitude: this.deviceDetail.deviceInfo.longitude || 0, | ||
120 | - latitude: this.deviceDetail.deviceInfo.latitude || 0 | 158 | + data() { |
159 | + return { | ||
160 | + showNodal: false, | ||
161 | + items: [{ | ||
162 | + value: 'OneWay', | ||
163 | + name: '单向', | ||
164 | + checked: 'true' | ||
165 | + }, | ||
166 | + { | ||
167 | + value: 'TwoWay', | ||
168 | + name: '双向' | ||
169 | + }, | ||
170 | + ], | ||
171 | + current: 0, | ||
172 | + modalName: null, | ||
173 | + showModel: false, | ||
174 | + commandType: 'OneWay', | ||
175 | + commandValue: {}, | ||
176 | + inputCommandVal: '' | ||
121 | }; | 177 | }; |
122 | - uni.navigateTo({ | ||
123 | - url: '/deviceSubPage/deviceDetailPage/devicePosition?data=' + JSON.stringify(data) | ||
124 | - }); | ||
125 | }, | 178 | }, |
126 | - showModal() { | ||
127 | - this.showModel = true; | ||
128 | - this.inputCommandVal = ''; | 179 | + computed: { |
180 | + deviceType() { | ||
181 | + return this.deviceDetail.deviceType === 'DIRECT_CONNECTION' ? | ||
182 | + '直连设备' : | ||
183 | + this.deviceDetail.deviceType === 'GATEWAY' ? | ||
184 | + '网关设备' : | ||
185 | + this.deviceDetail.deviceType === 'SENSOR' ? | ||
186 | + '网关子设备' : | ||
187 | + ''; | ||
188 | + }, | ||
189 | + alarmStatus() { | ||
190 | + return this.deviceDetail.alarmStatus === '0' ? '否' : '是'; | ||
191 | + }, | ||
192 | + formatLastOnlineTime() { | ||
193 | + return formatToDate(Number(this.deviceDetail.lastOnlineTime), 'YYYY-MM-DD HH:mm:ss'); | ||
194 | + } | ||
129 | }, | 195 | }, |
130 | - disabledScroll() { | ||
131 | - return; | 196 | + onLoad(e) { |
197 | + // 隐藏原生的tabbar | ||
198 | + uni.hideTabBar(); | ||
132 | }, | 199 | }, |
133 | - hiddenModal() { | ||
134 | - this.showModel = false; | 200 | + mounted() {}, |
201 | + beforeCreate() { | ||
202 | + this.modalName = null | ||
135 | }, | 203 | }, |
136 | - async confirmCommand() { | ||
137 | - try { | ||
138 | - const commandJsonValue = JSON.parse(this.inputCommandVal); | ||
139 | - this.commandValue.persistent = true; | ||
140 | - this.commandValue.additionalInfo = { | ||
141 | - cmdType: 'API' | ||
142 | - }; | ||
143 | - this.commandValue.method = 'methodThingskit'; | ||
144 | - this.commandValue.params = { | ||
145 | - params: commandJsonValue | 204 | + methods: { |
205 | + radioChange: function(evt) { | ||
206 | + for (let i = 0; i < this.items.length; i++) { | ||
207 | + if (this.items[i].value === evt.detail.value) { | ||
208 | + this.current = i; | ||
209 | + break; | ||
210 | + } | ||
211 | + } | ||
212 | + this.commandType = evt.detail.value | ||
213 | + }, | ||
214 | + handleClick() { | ||
215 | + const data = { | ||
216 | + longitude: this.deviceDetail.deviceInfo.longitude || 0, | ||
217 | + latitude: this.deviceDetail.deviceInfo.latitude || 0 | ||
146 | }; | 218 | }; |
147 | - await issueCommand(this.commandType, this.deviceDetail.tbDeviceId, this.commandValue); | 219 | + uni.navigateTo({ |
220 | + url: '/deviceSubPage/deviceDetailPage/devicePosition?data=' + JSON.stringify(data) | ||
221 | + }); | ||
222 | + }, | ||
223 | + showModal(e) { | ||
224 | + this.modalName = e.currentTarget.dataset.target | ||
225 | + this.showNodal = true | ||
226 | + }, | ||
227 | + showModalBtn() { | ||
228 | + this.showModel = true; | ||
229 | + this.inputCommandVal = ''; | ||
230 | + }, | ||
231 | + disabledScroll() { | ||
232 | + return; | ||
233 | + }, | ||
234 | + hiddenModal() { | ||
235 | + this.showModel = false; | ||
236 | + this.inputCommandVal = ''; | ||
237 | + // #ifdef APP-PLUS | ||
238 | + this.modalName = null | ||
239 | + this.showNodal = false | ||
240 | + // #endif | ||
241 | + }, | ||
242 | + async confirmCommand() { | ||
243 | + try { | ||
244 | + const commandJsonValue = JSON.parse(this.inputCommandVal); | ||
245 | + this.commandValue.persistent = true; | ||
246 | + this.commandValue.additionalInfo = { | ||
247 | + cmdType: 'API' | ||
248 | + }; | ||
249 | + this.commandValue.method = 'methodThingskit'; | ||
250 | + this.commandValue.params = { | ||
251 | + params: commandJsonValue | ||
252 | + }; | ||
253 | + await issueCommand(this.commandType, this.deviceDetail.tbDeviceId, this.commandValue); | ||
254 | + this.hiddenModal(); | ||
255 | + uni.$u.toast('下发成功~'); | ||
256 | + } catch (e) { | ||
257 | + uni.$u.toast('下发失败~'); | ||
258 | + } | ||
259 | + }, | ||
260 | + cancelCommand() { | ||
148 | this.hiddenModal(); | 261 | this.hiddenModal(); |
149 | - uni.$u.toast('下发成功~'); | ||
150 | - } catch (e) { | ||
151 | - uni.$u.toast('下发失败~'); | 262 | + // #ifdef APP-PLUS |
263 | + this.modalName = null | ||
264 | + this.showNodal = false | ||
265 | + // #endif | ||
152 | } | 266 | } |
153 | - }, | ||
154 | - cancelCommand() { | ||
155 | - this.hiddenModal(); | ||
156 | } | 267 | } |
157 | - } | ||
158 | -}; | 268 | + }; |
159 | </script> | 269 | </script> |
160 | 270 | ||
161 | <style lang="scss" scoped> | 271 | <style lang="scss" scoped> |
162 | -.basic-page { | ||
163 | - padding: 0 30rpx; | ||
164 | - .basic-title { | ||
165 | - display: flex; | ||
166 | - justify-content: space-between; | ||
167 | - align-items: center; | ||
168 | - height: 140rpx; | ||
169 | - background-color: #fff; | ||
170 | - border-radius: 20rpx; | 272 | + @import url('../styles/modal.css'); |
273 | + | ||
274 | + .cusAppplusContent { | ||
275 | + width: 625rpx; | ||
276 | + height: 400rpx; | ||
277 | + background: #FFFFFF; | ||
278 | + box-shadow: 2px 2px 4px 0px rgba(0, 0, 0, 0.03); | ||
279 | + border-radius: 10px; | ||
280 | + | ||
281 | + } | ||
282 | + | ||
283 | + .cusAppplusCancelBtn { | ||
284 | + background: #e3e3e5; | ||
285 | + border-radius: 38rpx; | ||
286 | + height: 85rpx; | ||
287 | + line-height: 85rpx | ||
288 | + } | ||
289 | + | ||
290 | + .cusAppplusConfrimBtn { | ||
291 | + background: #3388ff; | ||
292 | + border-radius: 38rpx; | ||
293 | + height: 85rpx; | ||
294 | + line-height: 85rpx | ||
295 | + } | ||
296 | + | ||
297 | + .cu-item { | ||
298 | + background: #3388FF; | ||
299 | + border-radius: 12px; | ||
300 | + width: 120rpx; | ||
301 | + height: 48rpx; | ||
302 | + text-align: center; | ||
303 | + line-height: 40rpx; | ||
304 | + | ||
305 | + text { | ||
306 | + font-size: 12px; | ||
307 | + font-family: PingFangSC-Regular, PingFang SC; | ||
308 | + font-weight: 400; | ||
309 | + color: #FFFFFF; | ||
310 | + } | ||
171 | } | 311 | } |
172 | - .detail { | ||
173 | - background-color: #fff; | ||
174 | - margin-top: 30rpx; | ||
175 | - border-radius: 20rpx; | ||
176 | - width: 690rpx; | ||
177 | - .detail-item { | ||
178 | - padding: 30rpx; | 312 | + |
313 | + | ||
314 | + | ||
315 | + .basic-page { | ||
316 | + padding: 0 30rpx; | ||
317 | + | ||
318 | + .basic-title { | ||
179 | display: flex; | 319 | display: flex; |
320 | + justify-content: space-between; | ||
180 | align-items: center; | 321 | align-items: center; |
181 | - .detail-label { | ||
182 | - color: #333; | ||
183 | - font-size: 15px; | ||
184 | - } | ||
185 | - .detail-value { | ||
186 | - color: #666; | ||
187 | - font-size: 14px; | ||
188 | - margin-left: 30rpx; | 322 | + height: 140rpx; |
323 | + background-color: #fff; | ||
324 | + border-radius: 20rpx; | ||
325 | + } | ||
326 | + | ||
327 | + .detail { | ||
328 | + background-color: #fff; | ||
329 | + margin-top: 30rpx; | ||
330 | + border-radius: 20rpx; | ||
331 | + width: 690rpx; | ||
332 | + | ||
333 | + .detail-item { | ||
334 | + padding: 30rpx; | ||
335 | + display: flex; | ||
336 | + align-items: center; | ||
337 | + | ||
338 | + .detail-label { | ||
339 | + color: #333; | ||
340 | + font-size: 15px; | ||
341 | + } | ||
342 | + | ||
343 | + .detail-value { | ||
344 | + color: #666; | ||
345 | + font-size: 14px; | ||
346 | + margin-left: 30rpx; | ||
347 | + } | ||
189 | } | 348 | } |
190 | } | 349 | } |
191 | } | 350 | } |
192 | -} | ||
193 | -/deep/ .u-modal__content { | ||
194 | - padding: 30rpx 0 !important; | ||
195 | -} | ||
196 | - | ||
197 | -.button-group { | ||
198 | - display: flex; | ||
199 | - margin-top: 40rpx; | ||
200 | - justify-content: space-between; | ||
201 | - view { | ||
202 | - width: 300rpx; | 351 | + |
352 | + /deep/ .u-modal__content { | ||
353 | + padding: 30rpx 0 !important; | ||
354 | + } | ||
355 | + | ||
356 | + .button-group { | ||
357 | + display: flex; | ||
358 | + margin-top: 40rpx; | ||
359 | + justify-content: space-between; | ||
360 | + | ||
361 | + view { | ||
362 | + width: 300rpx; | ||
363 | + } | ||
203 | } | 364 | } |
204 | -} | ||
205 | </style> | 365 | </style> |