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> | ... | ... |