Showing
3 changed files
with
597 additions
and
323 deletions
1 | 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 | 39 | </template> |
40 | 40 | |
41 | 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 | 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 | 230 | </script> |
213 | 231 | |
214 | 232 | <style lang="scss" scoped> |
215 | 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 | 4 | <public-module /> |
5 | 5 | <view class="basic-title"> |
6 | 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 | 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 | 14 | {{ deviceDetail.deviceState === 'INACTIVE' ? '待激活' : deviceDetail.deviceState === 'ONLINE' ? '在线' : '离线' }} |
14 | 15 | </view> |
15 | 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 | 27 | </view> |
19 | 28 | </view> |
20 | 29 | <view class="detail"> |
... | ... | @@ -48,9 +57,60 @@ |
48 | 57 | <view class="detail-value">{{ deviceDetail.description }}</view> |
49 | 58 | </view> |
50 | 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 | 114 | <view style="width: 100%; padding: 0 30rpx;"> |
55 | 115 | <view style="text-align: center; font-weight:700;margin-bottom: 40rpx;">命令下发</view> |
56 | 116 | <view class="u-flex"> |
... | ... | @@ -62,144 +122,244 @@ |
62 | 122 | <u-radio activeColor="#3388FF" label="双向" name="TwoWay"></u-radio> |
63 | 123 | </u-radio-group> |
64 | 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 | 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 | 137 | </view> |
71 | 138 | </view> |
72 | 139 | </u-modal> |
140 | + <!-- #endif --> | |
73 | 141 | </view> |
74 | 142 | </template> |
75 | 143 | |
76 | 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 | 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 | 269 | </script> |
160 | 270 | |
161 | 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 | 319 | display: flex; |
320 | + justify-content: space-between; | |
180 | 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 | 365 | </style> | ... | ... |