Showing
5 changed files
with
927 additions
and
831 deletions
| 1 | // 获取某个Key的历史数据 | 1 | // 获取某个Key的历史数据 | 
| 2 | +const getUrlParams = (params) => { | ||
| 3 | + return Object.keys(params).reduce((prev, next, currentIndex) => { | ||
| 4 | + if (params[next]) { | ||
| 5 | + return prev += `${!currentIndex ? '?' : '&'}${next}=${params[next]}` | ||
| 6 | + } | ||
| 7 | + return prev | ||
| 8 | + }, '') | ||
| 9 | +} | ||
| 10 | + | ||
| 2 | export function getHistoryData(params) { | 11 | export function getHistoryData(params) { | 
| 3 | - const { | ||
| 4 | - entityId, | ||
| 5 | - keys, | ||
| 6 | - startTs, | ||
| 7 | - endTs, | ||
| 8 | - interval | 12 | + let { | 
| 13 | + entityId | ||
| 9 | } = params | 14 | } = params | 
| 15 | + params = getUrlParams(params) | ||
| 10 | return uni.$u.http.get( | 16 | return uni.$u.http.get( | 
| 11 | - `/plugins/telemetry/DEVICE/${entityId}/values/timeseries?keys=${keys}&startTs=${startTs}&endTs=${endTs}&interval=${interval}` | 17 | + `/plugins/telemetry/DEVICE/${entityId}/values/timeseries${params}` | 
| 12 | ); | 18 | ); | 
| 13 | } | 19 | } | 
| 14 | 20 | ||
| 21 | + | ||
| 22 | + | ||
| 15 | // 获取当前设备的key | 23 | // 获取当前设备的key | 
| 16 | export function getDeviceKeys(id) { | 24 | export function getDeviceKeys(id) { | 
| 17 | return uni.$u.http.get(`/plugins/telemetry/DEVICE/${id}/keys/timeseries`); | 25 | return uni.$u.http.get(`/plugins/telemetry/DEVICE/${id}/keys/timeseries`); | 
| 18 | }; | 26 | }; | 
| 19 | 27 | ||
| 20 | export function issueCommand(type, tbDeviceId, data) { | 28 | export function issueCommand(type, tbDeviceId, data) { | 
| 21 | - console.log(type,tbDeviceId) | 29 | + console.log(type, tbDeviceId) | 
| 22 | return uni.$u.http.post(`/rpc/${type==='OneWay'?'oneway':'twoway'}/${tbDeviceId}`, data) | 30 | return uni.$u.http.post(`/rpc/${type==='OneWay'?'oneway':'twoway'}/${tbDeviceId}`, data) | 
| 23 | } | 31 | } | 
| 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="{ | 2 | + <view class="device-detail-page"> | 
| 3 | + <!-- 公共组件-每个页面必须引入 --> | ||
| 4 | + <public-module></public-module> | ||
| 5 | + <u-sticky bgColor="#fff"> | ||
| 6 | + <u-tabs :list="list" :current="currentTab" @click="handleTabClick" :activeStyle="{ | ||
| 11 | fontWeight: 'bold', | 7 | fontWeight: 'bold', | 
| 12 | color: '#333', | 8 | color: '#333', | 
| 13 | - }" | ||
| 14 | - :inactiveStyle="{ | 9 | + }" :inactiveStyle="{ | 
| 15 | color: '#999', | 10 | 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> | 11 | + }" :scrollable="isScrollable" /> | 
| 12 | + </u-sticky> | ||
| 13 | + <view style="margin-top: 30rpx"> | ||
| 14 | + <basicInfo v-show="currentTab == 0" :deviceDetail="deviceDetail" /> | ||
| 15 | + <realTimeData v-show="currentTab === 1" :recordList="recordList" /> | ||
| 16 | + <historyData v-if="currentTab === 2" :keys="keys" :yesterday="yesterday" :today="today" :timeDiff="timeDiff" | ||
| 17 | + :historyData="historyData" :entityId="entityId" :start="startTs" :end="endTs" @update="handleUpdate" /> | ||
| 18 | + <alarmHistory v-show="currentTab === 3" :deviceId="deviceId" /> | ||
| 19 | + <commondRecord v-if="currentTab === 4" :tbDeviceId="entityId" /> | ||
| 20 | + </view> | ||
| 21 | + </view> | ||
| 39 | </template> | 22 | </template> | 
| 40 | 23 | ||
| 41 | <script> | 24 | <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"; | ||
| 50 | -import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js"; | ||
| 51 | -import moment from "moment"; | ||
| 52 | -import base from "@/config/baseUrl.js"; | 25 | + import fTabbar from "@/components/module/f-tabbar/f-tabbar"; | 
| 26 | + import basicInfo from "./tabDetail/basicInfo.vue"; | ||
| 27 | + import realTimeData from "./tabDetail/realtimeData.vue"; | ||
| 28 | + import alarmHistory from "./tabDetail/alarmHistory.vue"; | ||
| 29 | + import historyData from "./tabDetail/historyData.vue"; | ||
| 30 | + import commondRecord from "./tabDetail/CommandRecord.vue"; | ||
| 31 | + import { | ||
| 32 | + getDeviceKeys, | ||
| 33 | + getHistoryData | ||
| 34 | + } from "./api/index.js"; | ||
| 35 | + import { | ||
| 36 | + formatToDate | ||
| 37 | + } from "@/plugins/utils.js"; | ||
| 38 | + import MescrollCompMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mixins/mescroll-comp.js"; | ||
| 39 | + import moment from "moment"; | ||
| 40 | + import base from "@/config/baseUrl.js"; | ||
| 53 | 41 | ||
| 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 | - }; | 42 | + export default { | 
| 43 | + mixins: [MescrollCompMixin], | ||
| 44 | + components: { | ||
| 45 | + fTabbar, | ||
| 46 | + basicInfo, | ||
| 47 | + realTimeData, | ||
| 48 | + alarmHistory, | ||
| 49 | + historyData, | ||
| 50 | + commondRecord, | ||
| 51 | + }, | ||
| 52 | + data() { | ||
| 53 | + return { | ||
| 54 | + list: [{ | ||
| 55 | + name: "基础信息", | ||
| 56 | + }, | ||
| 57 | + { | ||
| 58 | + name: "实时数据", | ||
| 59 | + }, | ||
| 60 | + { | ||
| 61 | + name: "历史数据", | ||
| 62 | + }, | ||
| 63 | + { | ||
| 64 | + name: "告警记录", | ||
| 65 | + }, | ||
| 66 | + ], | ||
| 67 | + currentTab: 0, | ||
| 68 | + deviceId: "", | ||
| 69 | + deviceDetail: {}, | ||
| 70 | + keys: [], | ||
| 71 | + yesterday: "", | ||
| 72 | + today: "", | ||
| 73 | + timeDiff: "", | ||
| 74 | + historyData: [], | ||
| 75 | + entityId: "", | ||
| 76 | + startTs: "", | ||
| 77 | + endTs: "", | ||
| 78 | + recordList: [], | ||
| 79 | + isScrollable: false, | ||
| 80 | + attrList: [] | ||
| 81 | + }; | ||
| 82 | + }, | ||
| 83 | + onUnload() { | ||
| 84 | + // 页面关闭时,销毁webSocket连接,否则第二次会存在连接不到的情况 | ||
| 85 | + uni.closeSocket(); | ||
| 86 | + }, | ||
| 87 | + async onLoad(options) { | ||
| 88 | + const { | ||
| 89 | + id, | ||
| 90 | + alarmStatus, | ||
| 91 | + lastOnlineTime, | ||
| 92 | + tbDeviceId, | ||
| 93 | + deviceProfileId | ||
| 94 | + } = | ||
| 95 | + options; | ||
| 96 | + this.deviceId = id; | ||
| 97 | + const res = await uni.$u.http.get(`/yt/device/${id}`); | ||
| 98 | + this.deviceDetail = { | ||
| 99 | + ...res, | ||
| 100 | + alarmStatus, | ||
| 101 | + lastOnlineTime, | ||
| 102 | + }; | ||
| 108 | 103 | ||
| 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 | - }); | 104 | + // 设备类型不是网关子设备的添加一个命令记录的选项卡 | 
| 105 | + if (this.deviceDetail.deviceType !== "SENSOR") { | ||
| 106 | + this.list.push({ | ||
| 107 | + name: "命令记录", | ||
| 108 | + }); | ||
| 109 | + } | ||
| 110 | + this.isScrollable = this.list.length > 4; | ||
| 111 | + if (res.deviceProfileId) { | ||
| 112 | + const getAttrList = await uni.$u.http.get( | ||
| 113 | + `/yt/device/attributes/${res.deviceProfileId}` | ||
| 114 | + ); | ||
| 115 | + if (Array.isArray(getAttrList)) { | ||
| 116 | + this.attrList = getAttrList.map(m => { | ||
| 117 | + return m.identifier | ||
| 118 | + }) | ||
| 119 | + } | ||
| 120 | + } | ||
| 121 | + // 连接webSockte | ||
| 122 | + const socketTask = uni.connectSocket({ | ||
| 123 | + url: `${base.socketPrefix}://${base.baseWebSocketUrl}/api/ws/plugins/telemetry?token=` + | ||
| 124 | + uni.getStorageSync("userInfo").isToken, //仅为示例,并非真实接口地址。 | ||
| 125 | + complete: () => {}, | ||
| 126 | + }); | ||
| 127 | + uni.onSocketOpen((header) => { | ||
| 128 | + socketTask.send({ | ||
| 129 | + data: JSON.stringify({ | ||
| 130 | + attrSubCmds: [], | ||
| 131 | + tsSubCmds: [{ | ||
| 132 | + entityType: "DEVICE", | ||
| 133 | + entityId: tbDeviceId, | ||
| 134 | + scope: "LATEST_TELEMETRY", | ||
| 135 | + cmdId: 1, | ||
| 136 | + keys: this.attrList.join(','), | ||
| 137 | + }, ], | ||
| 138 | + historyCmds: [], | ||
| 139 | + entityDataCmds: [], | ||
| 140 | + entityDataUnsubscribeCmds: [], | ||
| 141 | + alarmDataCmds: [], | ||
| 142 | + alarmDataUnsubscribeCmds: [], | ||
| 143 | + entityCountCmds: [], | ||
| 144 | + entityCountUnsubscribeCmds: [], | ||
| 145 | + }), | ||
| 146 | + success() {}, | ||
| 147 | + }); | ||
| 148 | + }); | ||
| 149 | + socketTask.onMessage((msg) => { | ||
| 150 | + const { | ||
| 151 | + data | ||
| 152 | + } = JSON.parse(msg.data); | ||
| 153 | + const newArray = []; | ||
| 154 | + for (const key in data) { | ||
| 155 | + const [time, value] = data[key].flat(1); | ||
| 156 | + let obj = { | ||
| 157 | + key, | ||
| 158 | + time, | ||
| 159 | + value, | ||
| 160 | + }; | ||
| 161 | + if (this.recordList.length === 0) { | ||
| 162 | + this.recordList.unshift(obj); | ||
| 163 | + } else { | ||
| 164 | + newArray.push(obj); | ||
| 165 | + } | ||
| 166 | + } | ||
| 167 | + newArray.forEach((item) => { | ||
| 168 | + let flag = false; | ||
| 169 | + this.recordList.forEach((item1) => { | ||
| 170 | + if (item1.key === item.key) { | ||
| 171 | + item1.value = item.value; | ||
| 172 | + item1.time = item.time; | ||
| 173 | + flag = true; | ||
| 174 | + } | ||
| 175 | + }); | ||
| 176 | + if (!flag) { | ||
| 177 | + this.recordList.unshift(item); | ||
| 178 | + } | ||
| 179 | + }); | ||
| 180 | + this.recordList = this.recordList.map((item) => { | ||
| 181 | + return { | ||
| 182 | + ...item, | ||
| 183 | + time: formatToDate(item.time, "YYYY-MM-DD HH:mm:ss"), | ||
| 184 | + }; | ||
| 185 | + }); | ||
| 186 | + }); | ||
| 182 | 187 | ||
| 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; | 188 | + const keys = await getDeviceKeys(tbDeviceId); | 
| 189 | + this.keys = [keys]; | ||
| 190 | + // 昨天 | ||
| 191 | + this.yesterday = moment().subtract(1, "days").format("YYYY-MM-DD"); | ||
| 192 | + // 今天 | ||
| 193 | + this.today = moment().format("YYYY-MM-DD"); | ||
| 194 | + // 开始时间 | ||
| 195 | + this.startTs = moment().subtract(1, "days").format("x"); | ||
| 196 | + // 结束时间 | ||
| 197 | + this.endTs = moment().format("x"); | ||
| 198 | + this.entityId = tbDeviceId; | ||
| 194 | 199 | ||
| 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; | 200 | + const data = await getHistoryData({ | 
| 201 | + entityId: tbDeviceId, | ||
| 202 | + startTs: this.startTs, | ||
| 203 | + endTs: this.endTs, | ||
| 204 | + keys: keys[0], | ||
| 205 | + // interval: 1800000, | ||
| 206 | + limit: 7, | ||
| 207 | + agg: 'NONE' | ||
| 208 | + }); | ||
| 209 | + this.timeDiff = "30分钟"; | ||
| 210 | + if (!Object.keys(data).length) return; | ||
| 204 | 211 | ||
| 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 | - }, | ||
| 229 | -}; | 212 | + this.historyData = data[keys[0]].map((item) => { | 
| 213 | + return { | ||
| 214 | + value: item.value, | ||
| 215 | + ts: formatToDate(item.ts, "YYYY-MM-DD HH:mm:ss"), | ||
| 216 | + }; | ||
| 217 | + }); | ||
| 218 | + }, | ||
| 219 | + methods: { | ||
| 220 | + handleTabClick({ | ||
| 221 | + index | ||
| 222 | + }) { | ||
| 223 | + this.currentTab = index; | ||
| 224 | + }, | ||
| 225 | + handleUpdate(data, e) { | ||
| 226 | + if (!Array.isArray(data)) { | ||
| 227 | + this.historyData = []; | ||
| 228 | + return; | ||
| 229 | + } | ||
| 230 | + this.historyData = data.map((item) => { | ||
| 231 | + return { | ||
| 232 | + value: item.value, | ||
| 233 | + ts: formatToDate(item.ts, "YYYY-MM-DD HH:mm:ss"), | ||
| 234 | + }; | ||
| 235 | + }); | ||
| 236 | + }, | ||
| 237 | + }, | ||
| 238 | + }; | ||
| 230 | </script> | 239 | </script> | 
| 231 | 240 | ||
| 232 | <style lang="scss" scoped> | 241 | <style lang="scss" scoped> | 
| 233 | -.device-detail-page { | ||
| 234 | - height: 100vh; | ||
| 235 | - background-color: #f8f9fa; | ||
| 236 | -} | ||
| 237 | -</style> | 242 | + .device-detail-page { | 
| 243 | + height: 100vh; | ||
| 244 | + background-color: #f8f9fa; | ||
| 245 | + } | ||
| 246 | +</style> | 
| @@ -5,33 +5,42 @@ | @@ -5,33 +5,42 @@ | ||
| 5 | <view class="historyData-top"> | 5 | <view class="historyData-top"> | 
| 6 | <u-form :label-style="{ 'font-size': '0rpx' }"> | 6 | <u-form :label-style="{ 'font-size': '0rpx' }"> | 
| 7 | <u-form-item @click="openCalendar"> | 7 | <u-form-item @click="openCalendar"> | 
| 8 | - <u-input v-model="timeData.selectTime" disabled disabledColor="#fff" placeholder="请选择日期" border="none" suffixIcon="arrow-down"> | 8 | + <u-input v-model="timeData.selectTime" disabled disabledColor="#fff" placeholder="请选择日期" | 
| 9 | + border="none" suffixIcon="arrow-down"> | ||
| 9 | <template slot="prefix"> | 10 | <template slot="prefix"> | 
| 10 | <image class="icon" src="../../../static/can-der.png"></image> | 11 | <image class="icon" src="../../../static/can-der.png"></image> | 
| 11 | </template> | 12 | </template> | 
| 12 | </u-input> | 13 | </u-input> | 
| 13 | </u-form-item> | 14 | </u-form-item> | 
| 14 | <u-form-item @click="openTimeGap"> | 15 | <u-form-item @click="openTimeGap"> | 
| 15 | - <u-input v-model="timeData.getTimeGap" disabled disabledColor="#fff" placeholder="请选择时间区间" border="none" suffixIcon="arrow-down"> | 16 | + <u-input v-model="timeData.getTimeGap" disabled disabledColor="#fff" placeholder="请选择时间区间" | 
| 17 | + border="none" suffixIcon="arrow-down"> | ||
| 16 | <template slot="prefix"> | 18 | <template slot="prefix"> | 
| 17 | <image class="icon" src="../../../static/time.png"></image> | 19 | <image class="icon" src="../../../static/time.png"></image> | 
| 18 | </template> | 20 | </template> | 
| 19 | </u-input> | 21 | </u-input> | 
| 20 | </u-form-item> | 22 | </u-form-item> | 
| 23 | + <u-form-item @click="openAvg"> | ||
| 24 | + <u-input shape="circle" v-model="aggText" placeholder="请选择数据聚合功能" disabled disabledColor="#377DFF0D" | ||
| 25 | + suffixIcon="arrow-down" /> | ||
| 26 | + </u-form-item> | ||
| 27 | + <u-form-item @click="openTimeGap" v-if="limitFlag"> | ||
| 28 | + <view class="u-flex"> | ||
| 29 | + <text>最大条数</text> | ||
| 30 | + <u-number-box style="margin-left:30rpx" class="ml-10" v-model="timeData.limit" :min="7" | ||
| 31 | + :max="50000"></u-number-box> | ||
| 32 | + </view> | ||
| 33 | + </u-form-item> | ||
| 21 | <u-form-item @click="openType"> | 34 | <u-form-item @click="openType"> | 
| 22 | - <u-input shape="circle" v-model="timeData.getType" placeholder="请选择属性" disabled disabledColor="#377DFF0D" suffixIcon="arrow-down" /> | 35 | + <u-input shape="circle" v-model="timeData.getType" placeholder="请选择属性" disabled | 
| 36 | + disabledColor="#377DFF0D" suffixIcon="arrow-down" /> | ||
| 23 | </u-form-item> | 37 | </u-form-item> | 
| 24 | </u-form> | 38 | </u-form> | 
| 25 | 39 | ||
| 26 | <view class="charts-box" v-show="historyData.length"> | 40 | <view class="charts-box" v-show="historyData.length"> | 
| 27 | - <qiun-data-charts | ||
| 28 | - type="area" | ||
| 29 | - canvas2d | ||
| 30 | - canvasId="daskujdhasljkdcnzjkdfhuoqwlqwjhkdsamjczxnmdasd123321" | ||
| 31 | - :chartData="chartData" | ||
| 32 | - :ontouch="true" | ||
| 33 | - :opts="{ xAxis: { disabled: true, itemCount: 6, scrollShow: true }, legend: { show: false }, enableScroll: true }" | ||
| 34 | - /> | 41 | + <qiun-data-charts type="area" canvas2d canvasId="daskujdhasljkdcnzjkdfhuoqwlqwjhkdsamjczxnmdasd123321" | 
| 42 | + :chartData="chartData" :ontouch="true" | ||
| 43 | + :opts="{ xAxis: { disabled: true, itemCount: 6, scrollShow: true }, legend: { show: false }, enableScroll: true }" /> | ||
| 35 | </view> | 44 | </view> | 
| 36 | <mescroll-empty v-if="!historyData.length" /> | 45 | <mescroll-empty v-if="!historyData.length" /> | 
| 37 | </view> | 46 | </view> | 
| @@ -41,166 +50,125 @@ | @@ -41,166 +50,125 @@ | ||
| 41 | <view class="th">变量值</view> | 50 | <view class="th">变量值</view> | 
| 42 | <view class="th">更新时间</view> | 51 | <view class="th">更新时间</view> | 
| 43 | </view> | 52 | </view> | 
| 44 | - <view class="tr bg-g" :class="{ odd: index % 2 === 0 }" v-for="(item, index) in historyData" :key="index"> | 53 | + <view class="tr bg-g" :class="{ odd: index % 2 === 0 }" v-for="(item, index) in historyData" | 
| 54 | + :key="index"> | ||
| 45 | <view class="td">{{ item.value }}</view> | 55 | <view class="td">{{ item.value }}</view> | 
| 46 | <view class="td">{{ item.ts }}</view> | 56 | <view class="td">{{ item.ts }}</view> | 
| 47 | </view> | 57 | </view> | 
| 48 | </view> | 58 | </view> | 
| 49 | </view> | 59 | </view> | 
| 50 | - <u-calendar | ||
| 51 | - :show="showCalendar" | ||
| 52 | - :defaultDate="defaultDate" | ||
| 53 | - closeOnClickOverlay | ||
| 54 | - mode="range" | ||
| 55 | - startText="开始时间" | ||
| 56 | - endText="结束时间" | ||
| 57 | - confirmDisabledText="请选择日期" | ||
| 58 | - :minDate="minDate" | ||
| 59 | - :maxDate="maxDate" | ||
| 60 | - @confirm="calendarConfirm" | ||
| 61 | - @close="calendarClose" | ||
| 62 | - ></u-calendar> | ||
| 63 | - <u-picker | ||
| 64 | - :show="showTimeGap" | ||
| 65 | - :columns="columns" | ||
| 66 | - keyName="label" | ||
| 67 | - closeOnClickOverlay | ||
| 68 | - @confirm="confirmTimeGap" | ||
| 69 | - @cancel="cancelTimeGap" | ||
| 70 | - @close="cancelTimeGap" | ||
| 71 | - :defaultIndex="[3]" | ||
| 72 | - ></u-picker> | ||
| 73 | - <u-picker :show="showSelectType" :columns="keys" closeOnClickOverlay @confirm="confirmTypeGap" @cancel="cancelTypeGap" @close="cancelTypeGap"></u-picker> | 60 | + <u-calendar :show="showCalendar" :defaultDate="defaultDate" closeOnClickOverlay mode="range" startText="开始时间" | 
| 61 | + endText="结束时间" confirmDisabledText="请选择日期" :minDate="minDate" :maxDate="maxDate" @confirm="calendarConfirm" | ||
| 62 | + @close="calendarClose"></u-calendar> | ||
| 63 | + <u-picker :show="showTimeGap" :columns="columns" keyName="label" closeOnClickOverlay @confirm="confirmTimeGap" | ||
| 64 | + @cancel="cancelTimeGap" @close="cancelTimeGap" :defaultIndex="[3]"></u-picker> | ||
| 65 | + <u-picker :show="showSelectType" :columns="keys" closeOnClickOverlay @confirm="confirmTypeGap" | ||
| 66 | + @cancel="cancelTypeGap" @close="cancelTypeGap"></u-picker> | ||
| 67 | + <u-picker :show="showSelectAvg" :columns="avgColumns" keyName="label" closeOnClickOverlay | ||
| 68 | + @confirm="confirmAvgGap" @cancel="showSelectAvg=false" @close="showSelectAvg=false"></u-picker> | ||
| 74 | </view> | 69 | </view> | 
| 75 | </template> | 70 | </template> | 
| 76 | 71 | ||
| 77 | <script> | 72 | <script> | 
| 78 | -import fTabbar from '@/components/module/f-tabbar/f-tabbar'; | ||
| 79 | -import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'; | ||
| 80 | -import { getHistoryData } from '../api/index.js'; | ||
| 81 | -import { formatToDate } from '@/plugins/utils.js'; | ||
| 82 | -const d = new Date(); | ||
| 83 | -const year = d.getFullYear(); | ||
| 84 | -let month = d.getMonth() + 1; | ||
| 85 | -month = month < 10 ? `0${month}` : month; | ||
| 86 | -const date = d.getDate(); | ||
| 87 | -export default { | ||
| 88 | - components: { | ||
| 89 | - fTabbar, | ||
| 90 | - qiunDataCharts | ||
| 91 | - }, | ||
| 92 | - props: { | ||
| 93 | - keys: { | ||
| 94 | - type: Array, | ||
| 95 | - default: () => [] | ||
| 96 | - }, | ||
| 97 | - yesterday: { | ||
| 98 | - type: String, | ||
| 99 | - default: '' | ||
| 100 | - }, | ||
| 101 | - today: { | ||
| 102 | - type: String, | ||
| 103 | - default: '' | ||
| 104 | - }, | ||
| 105 | - timeDiff: { | ||
| 106 | - type: String, | ||
| 107 | - default: '' | ||
| 108 | - }, | ||
| 109 | - historyData: { | ||
| 110 | - type: Array, | ||
| 111 | - default: () => [] | ||
| 112 | - }, | ||
| 113 | - entityId: { | ||
| 114 | - type: String, | ||
| 115 | - required: true | ||
| 116 | - }, | ||
| 117 | - start: { | ||
| 118 | - type: String, | ||
| 119 | - required: true | 73 | + import fTabbar from '@/components/module/f-tabbar/f-tabbar'; | 
| 74 | + import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue'; | ||
| 75 | + import { | ||
| 76 | + getHistoryData | ||
| 77 | + } from '../api/index.js'; | ||
| 78 | + import { | ||
| 79 | + formatToDate | ||
| 80 | + } from '@/plugins/utils.js'; | ||
| 81 | + const d = new Date(); | ||
| 82 | + const year = d.getFullYear(); | ||
| 83 | + let month = d.getMonth() + 1; | ||
| 84 | + month = month < 10 ? `0${month}` : month; | ||
| 85 | + const date = d.getDate(); | ||
| 86 | + export default { | ||
| 87 | + components: { | ||
| 88 | + fTabbar, | ||
| 89 | + qiunDataCharts | ||
| 120 | }, | 90 | }, | 
| 121 | - end: { | ||
| 122 | - type: String, | ||
| 123 | - required: true | ||
| 124 | - } | ||
| 125 | - }, | ||
| 126 | - data() { | ||
| 127 | - return { | ||
| 128 | - startTs: this.start, | ||
| 129 | - endTs: this.end, | ||
| 130 | - showCalendar: false, | ||
| 131 | - showTimeGap: false, | ||
| 132 | - showSelectType: false, | ||
| 133 | - minDate: `${year}-${month - 1}-${date}`, | ||
| 134 | - maxDate: `${year}-${month}-${date + 1}`, | ||
| 135 | - defaultDate: [this.yesterday, this.today], | ||
| 136 | - chartData: { | ||
| 137 | - categories: this.historyData.length && this.historyData.map(item => item.ts), | ||
| 138 | - series: [ | ||
| 139 | - { | ||
| 140 | - name: this.keys[0][0], | ||
| 141 | - data: this.historyData.length && this.historyData.map(item => Number(item.value)) | ||
| 142 | - } | ||
| 143 | - ] | 91 | + props: { | 
| 92 | + keys: { | ||
| 93 | + type: Array, | ||
| 94 | + default: () => [] | ||
| 144 | }, | 95 | }, | 
| 145 | - columns: [ | ||
| 146 | - [ | ||
| 147 | - { | ||
| 148 | - label: '5分钟', | ||
| 149 | - value: 300000 | ||
| 150 | - }, | ||
| 151 | - { | ||
| 152 | - label: '10分钟', | ||
| 153 | - value: 600000 | ||
| 154 | - }, | ||
| 155 | - { | ||
| 156 | - label: '15分钟', | ||
| 157 | - value: 900000 | ||
| 158 | - }, | ||
| 159 | - { | ||
| 160 | - label: '30分钟', | ||
| 161 | - value: 1800000 | ||
| 162 | - }, | ||
| 163 | - { | ||
| 164 | - label: '1小时', | ||
| 165 | - value: 3600000 | ||
| 166 | - }, | ||
| 167 | - { | ||
| 168 | - label: '2小时', | ||
| 169 | - value: 7200000 | ||
| 170 | - } | ||
| 171 | - ] | ||
| 172 | - ], | ||
| 173 | - timeData: { | ||
| 174 | - selectTime: this.yesterday + ' 至 ' + this.today, | ||
| 175 | - getTimeGap: this.timeDiff, | ||
| 176 | - getType: this.keys[0][0] | ||
| 177 | - } | ||
| 178 | - }; | ||
| 179 | - }, | ||
| 180 | - watch: { | ||
| 181 | - historyData(newValue) { | ||
| 182 | - if (!newValue.length) { | ||
| 183 | - this.chartData.categories = []; | ||
| 184 | - this.chartData.series = []; | ||
| 185 | - } else { | ||
| 186 | - this.chartData.categories = newValue.map(item => item.ts); | ||
| 187 | - this.chartData.series = [ | ||
| 188 | - { | ||
| 189 | - name: this.keys[0][0], | ||
| 190 | - data: newValue.map(item => Number(item.value)) | ||
| 191 | - } | ||
| 192 | - ]; | 96 | + yesterday: { | 
| 97 | + type: String, | ||
| 98 | + default: '' | ||
| 99 | + }, | ||
| 100 | + today: { | ||
| 101 | + type: String, | ||
| 102 | + default: '' | ||
| 103 | + }, | ||
| 104 | + timeDiff: { | ||
| 105 | + type: String, | ||
| 106 | + default: '' | ||
| 107 | + }, | ||
| 108 | + historyData: { | ||
| 109 | + type: Array, | ||
| 110 | + default: () => [] | ||
| 111 | + }, | ||
| 112 | + entityId: { | ||
| 113 | + type: String, | ||
| 114 | + required: true | ||
| 115 | + }, | ||
| 116 | + start: { | ||
| 117 | + type: String, | ||
| 118 | + required: true | ||
| 119 | + }, | ||
| 120 | + end: { | ||
| 121 | + type: String, | ||
| 122 | + required: true | ||
| 193 | } | 123 | } | 
| 194 | - } | ||
| 195 | - }, | ||
| 196 | - methods: { | ||
| 197 | - // 动态生成Columns | ||
| 198 | - generateColumns(value) { | ||
| 199 | - if (value < 604800000) { | ||
| 200 | - // 小于7天 | ||
| 201 | - return [ | ||
| 202 | - [ | 124 | + }, | 
| 125 | + data() { | ||
| 126 | + return { | ||
| 127 | + limitFlag: true, | ||
| 128 | + avgColumns: [ | ||
| 129 | + [{ | ||
| 130 | + label: '最小值', | ||
| 131 | + value: 'MIN' | ||
| 132 | + }, { | ||
| 133 | + label: '最大值', | ||
| 134 | + value: 'MAX' | ||
| 135 | + }, | ||
| 136 | + { | ||
| 137 | + label: '平均值', | ||
| 138 | + value: 'AVG' | ||
| 139 | + }, | ||
| 140 | + { | ||
| 141 | + label: '求和', | ||
| 142 | + value: 'SUM' | ||
| 143 | + }, | ||
| 144 | + { | ||
| 145 | + label: '计数', | ||
| 146 | + value: 'COUNT' | ||
| 147 | + }, | ||
| 203 | { | 148 | { | 
| 149 | + label: '空', | ||
| 150 | + value: 'NONE' | ||
| 151 | + }, | ||
| 152 | + ] | ||
| 153 | + ], | ||
| 154 | + startTs: this.start, | ||
| 155 | + endTs: this.end, | ||
| 156 | + showCalendar: false, | ||
| 157 | + showTimeGap: false, | ||
| 158 | + showSelectType: false, | ||
| 159 | + showSelectAvg: false, | ||
| 160 | + minDate: `${year}-${month - 1}-${date}`, | ||
| 161 | + maxDate: `${year}-${month}-${date + 1}`, | ||
| 162 | + defaultDate: [this.yesterday, this.today], | ||
| 163 | + chartData: { | ||
| 164 | + categories: this.historyData.length && this.historyData.map(item => item.ts), | ||
| 165 | + series: [{ | ||
| 166 | + name: this.keys[0][0], | ||
| 167 | + data: this.historyData.length && this.historyData.map(item => Number(item.value)) | ||
| 168 | + }] | ||
| 169 | + }, | ||
| 170 | + columns: [ | ||
| 171 | + [{ | ||
| 204 | label: '5分钟', | 172 | label: '5分钟', | 
| 205 | value: 300000 | 173 | value: 300000 | 
| 206 | }, | 174 | }, | 
| @@ -225,173 +193,253 @@ export default { | @@ -225,173 +193,253 @@ export default { | ||
| 225 | value: 7200000 | 193 | value: 7200000 | 
| 226 | } | 194 | } | 
| 227 | ] | 195 | ] | 
| 228 | - ]; | ||
| 229 | - } else if (value < 2592000000) { | ||
| 230 | - // 小于30天 | ||
| 231 | - return [ | ||
| 232 | - [ | ||
| 233 | - { | ||
| 234 | - label: '30分钟', | ||
| 235 | - value: 1800000 | ||
| 236 | - }, | ||
| 237 | - { | ||
| 238 | - label: '1小时', | ||
| 239 | - value: 3600000 | ||
| 240 | - }, | ||
| 241 | - { | ||
| 242 | - label: '2小时', | ||
| 243 | - value: 7200000 | ||
| 244 | - }, | ||
| 245 | - { | ||
| 246 | - label: '5小时', | ||
| 247 | - value: 18000000 | ||
| 248 | - }, | ||
| 249 | - { | ||
| 250 | - label: '10小时', | ||
| 251 | - value: 36000000 | ||
| 252 | - }, | ||
| 253 | - { | ||
| 254 | - label: '12小时', | ||
| 255 | - value: 43200000 | ||
| 256 | - }, | ||
| 257 | - { | ||
| 258 | - label: '1天', | ||
| 259 | - value: 86400000 | ||
| 260 | - } | ||
| 261 | - ] | ||
| 262 | - ]; | ||
| 263 | - } else if (value >= 2592000000) { | ||
| 264 | - // 大于30天 | ||
| 265 | - return [ | ||
| 266 | - [ | ||
| 267 | - { | ||
| 268 | - label: '2小时', | ||
| 269 | - value: 7200000 | ||
| 270 | - }, | ||
| 271 | - { | ||
| 272 | - label: '5小时', | ||
| 273 | - value: 18000000 | ||
| 274 | - }, | ||
| 275 | - { | ||
| 276 | - label: '10小时', | ||
| 277 | - value: 36000000 | ||
| 278 | - }, | ||
| 279 | - { | ||
| 280 | - label: '12小时', | ||
| 281 | - value: 43200000 | ||
| 282 | - }, | ||
| 283 | - { | ||
| 284 | - label: '1天', | ||
| 285 | - value: 86400000 | ||
| 286 | - } | ||
| 287 | - ] | ||
| 288 | - ]; | ||
| 289 | - } | ||
| 290 | - }, | ||
| 291 | - openCalendar() { | ||
| 292 | - this.showCalendar = true; | ||
| 293 | - }, | ||
| 294 | - openTimeGap() { | ||
| 295 | - this.showTimeGap = true; | 196 | + ], | 
| 197 | + timeData: { | ||
| 198 | + selectTime: this.yesterday + ' 至 ' + this.today, | ||
| 199 | + getTimeGap: this.timeDiff, | ||
| 200 | + getType: this.keys[0][0], | ||
| 201 | + limit: 7, | ||
| 202 | + agg: 'NONE' | ||
| 203 | + }, | ||
| 204 | + aggText: '空' | ||
| 205 | + }; | ||
| 296 | }, | 206 | }, | 
| 297 | - openType() { | ||
| 298 | - this.showSelectType = true; | ||
| 299 | - }, | ||
| 300 | - calendarConfirm(date) { | ||
| 301 | - this.showCalendar = false; | ||
| 302 | - this.timeData.selectTime = `${date[0]} 至 ${date[date.length - 1]}`; | ||
| 303 | - // 选择的日期时间差(时间戳) | ||
| 304 | - const timeDiff = formatToDate(date[date.length - 1], 'x') - formatToDate(date[0], 'x'); | ||
| 305 | - const genColumns = this.generateColumns(timeDiff); | ||
| 306 | - this.columns = genColumns; | ||
| 307 | - this.timeData.getTimeGap = ''; | ||
| 308 | - this.timeData.getType = ''; | ||
| 309 | - this.startTs = formatToDate(date[0], 'x'); | ||
| 310 | - // 最后时间的最后一秒 | ||
| 311 | - this.endTs = formatToDate(`${date[date.length - 1]} 23:59:59`, 'x'); | ||
| 312 | - }, | ||
| 313 | - calendarClose() { | ||
| 314 | - this.showCalendar = false; | ||
| 315 | - }, | ||
| 316 | - confirmTimeGap(time) { | ||
| 317 | - this.showTimeGap = false; | ||
| 318 | - this.timeData.getTimeGap = time.value[0].label; | ||
| 319 | - this.timeData.getType = ''; | 207 | + watch: { | 
| 208 | + historyData(newValue) { | ||
| 209 | + if (!newValue.length) { | ||
| 210 | + this.chartData.categories = []; | ||
| 211 | + this.chartData.series = []; | ||
| 212 | + } else { | ||
| 213 | + this.chartData.categories = newValue.map(item => item.ts); | ||
| 214 | + this.chartData.series = [{ | ||
| 215 | + name: this.keys[0][0], | ||
| 216 | + data: newValue.map(item => Number(item.value)) | ||
| 217 | + }]; | ||
| 218 | + } | ||
| 219 | + } | ||
| 320 | }, | 220 | }, | 
| 221 | + methods: { | ||
| 222 | + // 动态生成Columns | ||
| 223 | + generateColumns(value) { | ||
| 224 | + if (value < 604800000) { | ||
| 225 | + // 小于7天 | ||
| 226 | + return [ | ||
| 227 | + [{ | ||
| 228 | + label: '5分钟', | ||
| 229 | + value: 300000 | ||
| 230 | + }, | ||
| 231 | + { | ||
| 232 | + label: '10分钟', | ||
| 233 | + value: 600000 | ||
| 234 | + }, | ||
| 235 | + { | ||
| 236 | + label: '15分钟', | ||
| 237 | + value: 900000 | ||
| 238 | + }, | ||
| 239 | + { | ||
| 240 | + label: '30分钟', | ||
| 241 | + value: 1800000 | ||
| 242 | + }, | ||
| 243 | + { | ||
| 244 | + label: '1小时', | ||
| 245 | + value: 3600000 | ||
| 246 | + }, | ||
| 247 | + { | ||
| 248 | + label: '2小时', | ||
| 249 | + value: 7200000 | ||
| 250 | + } | ||
| 251 | + ] | ||
| 252 | + ]; | ||
| 253 | + } else if (value < 2592000000) { | ||
| 254 | + // 小于30天 | ||
| 255 | + return [ | ||
| 256 | + [{ | ||
| 257 | + label: '30分钟', | ||
| 258 | + value: 1800000 | ||
| 259 | + }, | ||
| 260 | + { | ||
| 261 | + label: '1小时', | ||
| 262 | + value: 3600000 | ||
| 263 | + }, | ||
| 264 | + { | ||
| 265 | + label: '2小时', | ||
| 266 | + value: 7200000 | ||
| 267 | + }, | ||
| 268 | + { | ||
| 269 | + label: '5小时', | ||
| 270 | + value: 18000000 | ||
| 271 | + }, | ||
| 272 | + { | ||
| 273 | + label: '10小时', | ||
| 274 | + value: 36000000 | ||
| 275 | + }, | ||
| 276 | + { | ||
| 277 | + label: '12小时', | ||
| 278 | + value: 43200000 | ||
| 279 | + }, | ||
| 280 | + { | ||
| 281 | + label: '1天', | ||
| 282 | + value: 86400000 | ||
| 283 | + } | ||
| 284 | + ] | ||
| 285 | + ]; | ||
| 286 | + } else if (value >= 2592000000) { | ||
| 287 | + // 大于30天 | ||
| 288 | + return [ | ||
| 289 | + [{ | ||
| 290 | + label: '2小时', | ||
| 291 | + value: 7200000 | ||
| 292 | + }, | ||
| 293 | + { | ||
| 294 | + label: '5小时', | ||
| 295 | + value: 18000000 | ||
| 296 | + }, | ||
| 297 | + { | ||
| 298 | + label: '10小时', | ||
| 299 | + value: 36000000 | ||
| 300 | + }, | ||
| 301 | + { | ||
| 302 | + label: '12小时', | ||
| 303 | + value: 43200000 | ||
| 304 | + }, | ||
| 305 | + { | ||
| 306 | + label: '1天', | ||
| 307 | + value: 86400000 | ||
| 308 | + } | ||
| 309 | + ] | ||
| 310 | + ]; | ||
| 311 | + } | ||
| 312 | + }, | ||
| 313 | + openCalendar() { | ||
| 314 | + this.showCalendar = true; | ||
| 315 | + }, | ||
| 316 | + openTimeGap() { | ||
| 317 | + this.showTimeGap = true; | ||
| 318 | + }, | ||
| 319 | + openType() { | ||
| 320 | + this.showSelectType = true; | ||
| 321 | + }, | ||
| 322 | + openAvg() { | ||
| 323 | + this.showSelectAvg = true | ||
| 324 | + }, | ||
| 325 | + calendarConfirm(date) { | ||
| 326 | + this.showCalendar = false; | ||
| 327 | + this.timeData.selectTime = `${date[0]} 至 ${date[date.length - 1]}`; | ||
| 328 | + // 选择的日期时间差(时间戳) | ||
| 329 | + const timeDiff = formatToDate(date[date.length - 1], 'x') - formatToDate(date[0], 'x'); | ||
| 330 | + const genColumns = this.generateColumns(timeDiff); | ||
| 331 | + this.columns = genColumns; | ||
| 332 | + this.timeData.getTimeGap = ''; | ||
| 333 | + this.timeData.getType = ''; | ||
| 334 | + this.startTs = formatToDate(date[0], 'x'); | ||
| 335 | + // 最后时间的最后一秒 | ||
| 336 | + this.endTs = formatToDate(`${date[date.length - 1]} 23:59:59`, 'x'); | ||
| 337 | + }, | ||
| 338 | + calendarClose() { | ||
| 339 | + this.showCalendar = false; | ||
| 340 | + }, | ||
| 341 | + confirmTimeGap(time) { | ||
| 342 | + this.showTimeGap = false; | ||
| 343 | + this.timeData.getTimeGap = time.value[0].label; | ||
| 344 | + this.timeData.getType = ''; | ||
| 345 | + }, | ||
| 321 | 346 | ||
| 322 | - cancelTimeGap() { | ||
| 323 | - this.showTimeGap = false; | ||
| 324 | - }, | ||
| 325 | - async confirmTypeGap(time) { | ||
| 326 | - this.showSelectType = false; | ||
| 327 | - this.timeData.getType = time.value[0]; | ||
| 328 | - const interval = this.columns[0].find(item => item.label === this.timeData.getTimeGap); | ||
| 329 | - const data = await getHistoryData({ | ||
| 330 | - startTs: this.startTs, | ||
| 331 | - endTs: this.endTs, | ||
| 332 | - keys: this.timeData.getType, | ||
| 333 | - interval: interval.value, | ||
| 334 | - entityId: this.entityId | ||
| 335 | - }); | ||
| 336 | - this.$emit('update', data[this.timeData.getType]); | ||
| 337 | - }, | ||
| 338 | - cancelTypeGap() { | ||
| 339 | - this.showSelectType = false; | 347 | + cancelTimeGap() { | 
| 348 | + this.showTimeGap = false; | ||
| 349 | + }, | ||
| 350 | + confirmAvgGap(e) { | ||
| 351 | + this.timeData.agg = e.value[0].value | ||
| 352 | + this.aggText = e.value[0].label | ||
| 353 | + if (e.value[0].value === 'NONE') { | ||
| 354 | + this.limitFlag = true | ||
| 355 | + this.timeData.limit = 7 | ||
| 356 | + } else { | ||
| 357 | + this.timeData.limit = null | ||
| 358 | + this.limitFlag = false | ||
| 359 | + } | ||
| 360 | + this.showSelectAvg = false | ||
| 361 | + }, | ||
| 362 | + async confirmTypeGap(time) { | ||
| 363 | + this.showSelectType = false; | ||
| 364 | + this.timeData.getType = time.value[0]; | ||
| 365 | + const interval = this.columns[0].find(item => item.label === this.timeData.getTimeGap); | ||
| 366 | + const data = await getHistoryData({ | ||
| 367 | + startTs: this.startTs, | ||
| 368 | + endTs: this.endTs, | ||
| 369 | + keys: this.timeData.getType, | ||
| 370 | + interval: this.limitFlag ? null : interval.value, | ||
| 371 | + entityId: this.entityId, | ||
| 372 | + limit: this.timeData.limit, | ||
| 373 | + agg: this.timeData.agg | ||
| 374 | + }); | ||
| 375 | + this.$emit('update', data[this.timeData.getType]); | ||
| 376 | + }, | ||
| 377 | + cancelTypeGap() { | ||
| 378 | + this.showSelectType = false; | ||
| 379 | + } | ||
| 340 | } | 380 | } | 
| 341 | - } | ||
| 342 | -}; | 381 | + }; | 
| 343 | </script> | 382 | </script> | 
| 344 | 383 | ||
| 345 | <style lang="scss" scoped> | 384 | <style lang="scss" scoped> | 
| 346 | -.charts-box { | ||
| 347 | - width: 100%; | ||
| 348 | - height: 550rpx; | ||
| 349 | -} | ||
| 350 | -.historyData { | ||
| 351 | - margin: 30rpx; | ||
| 352 | - .historyData-top { | ||
| 353 | - padding: 30rpx; | ||
| 354 | - background-color: #fff; | ||
| 355 | - // height: 870rpx; | ||
| 356 | - border-radius: 20rpx; | ||
| 357 | - .icon { | ||
| 358 | - width: 28rpx; | ||
| 359 | - height: 28rpx; | ||
| 360 | - margin-right: 15rpx; | ||
| 361 | - } | 385 | + .charts-box { | 
| 386 | + width: 100%; | ||
| 387 | + height: 550rpx; | ||
| 362 | } | 388 | } | 
| 363 | - .historyData-bottom { | ||
| 364 | - margin-top: 30rpx; | ||
| 365 | - background-color: #fff; | ||
| 366 | - border-radius: 20rpx; | ||
| 367 | - .table { | ||
| 368 | - border: 0px solid darkgray; | ||
| 369 | - .tr { | ||
| 370 | - display: flex; | ||
| 371 | - width: 100%; | ||
| 372 | - justify-content: center; | ||
| 373 | - height: 3rem; | ||
| 374 | - align-items: center; | ||
| 375 | - .th { | 389 | + | 
| 390 | + .historyData { | ||
| 391 | + margin: 30rpx; | ||
| 392 | + | ||
| 393 | + .historyData-top { | ||
| 394 | + padding: 30rpx; | ||
| 395 | + background-color: #fff; | ||
| 396 | + // height: 870rpx; | ||
| 397 | + border-radius: 20rpx; | ||
| 398 | + | ||
| 399 | + .icon { | ||
| 400 | + width: 28rpx; | ||
| 401 | + height: 28rpx; | ||
| 402 | + margin-right: 15rpx; | ||
| 403 | + } | ||
| 404 | + } | ||
| 405 | + | ||
| 406 | + .historyData-bottom { | ||
| 407 | + margin-top: 30rpx; | ||
| 408 | + background-color: #fff; | ||
| 409 | + border-radius: 20rpx; | ||
| 410 | + | ||
| 411 | + .table { | ||
| 412 | + border: 0px solid darkgray; | ||
| 413 | + | ||
| 414 | + .tr { | ||
| 376 | display: flex; | 415 | display: flex; | 
| 416 | + width: 100%; | ||
| 377 | justify-content: center; | 417 | justify-content: center; | 
| 418 | + height: 3rem; | ||
| 378 | align-items: center; | 419 | align-items: center; | 
| 379 | - width: 50%; | ||
| 380 | - color: #333; | ||
| 381 | - font-weight: 500; | ||
| 382 | - } | ||
| 383 | - .td { | ||
| 384 | - color: #999; | ||
| 385 | - width: 50%; | ||
| 386 | - display: flex; | ||
| 387 | - justify-content: center; | ||
| 388 | - text-align: center; | 420 | + | 
| 421 | + .th { | ||
| 422 | + display: flex; | ||
| 423 | + justify-content: center; | ||
| 424 | + align-items: center; | ||
| 425 | + width: 50%; | ||
| 426 | + color: #333; | ||
| 427 | + font-weight: 500; | ||
| 428 | + } | ||
| 429 | + | ||
| 430 | + .td { | ||
| 431 | + color: #999; | ||
| 432 | + width: 50%; | ||
| 433 | + display: flex; | ||
| 434 | + justify-content: center; | ||
| 435 | + text-align: center; | ||
| 436 | + } | ||
| 389 | } | 437 | } | 
| 390 | } | 438 | } | 
| 391 | } | 439 | } | 
| 392 | } | 440 | } | 
| 393 | -} | ||
| 394 | -.odd { | ||
| 395 | - background-color: #f9fcff; | ||
| 396 | -} | 441 | + | 
| 442 | + .odd { | ||
| 443 | + background-color: #f9fcff; | ||
| 444 | + } | ||
| 397 | </style> | 445 | </style> | 
| @@ -4,7 +4,10 @@ | @@ -4,7 +4,10 @@ | ||
| 4 | <view class="device-top"> | 4 | <view class="device-top"> | 
| 5 | <view class="search"> | 5 | <view class="search"> | 
| 6 | <view> | 6 | <view> | 
| 7 | - <view class="search-left"><u--input prefixIcon="search" placeholder="输入设备SN或名称搜索" shape="circle" @change="inputChanged"></u--input></view> | 7 | + <view class="search-left"> | 
| 8 | + <u--input prefixIcon="search" placeholder="输入设备SN或名称搜索" shape="circle" | ||
| 9 | + @change="inputChanged"></u--input> | ||
| 10 | + </view> | ||
| 8 | </view> | 11 | </view> | 
| 9 | <view @click="openSearchDialog" class="search-right"> | 12 | <view @click="openSearchDialog" class="search-right"> | 
| 10 | <text>筛选</text> | 13 | <text>筛选</text> | 
| @@ -25,19 +28,19 @@ | @@ -25,19 +28,19 @@ | ||
| 25 | </view> | 28 | </view> | 
| 26 | </view> | 29 | </view> | 
| 27 | </u-sticky> | 30 | </u-sticky> | 
| 28 | - <mescroll-body ref="mescrollRef" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" @up="upCallback"> | 31 | + <mescroll-body ref="mescrollRef" @init="mescrollInit" :up="upOption" :down="downOption" @down="downCallback" | 
| 32 | + @up="upCallback"> | ||
| 29 | <view class="device-list"> | 33 | <view class="device-list"> | 
| 30 | - <view @click="openDeviceDetail(item.id, item.alarmStatus, item.lastOnlineTime, item.tbDeviceId)" class="list-item" v-for="item in list" :key="item.id"> | ||
| 31 | - <view | ||
| 32 | - class="u-flex item" | ||
| 33 | - style=" | 34 | + <view @click="openDeviceDetail(item.id, item.alarmStatus, item.lastOnlineTime, item.tbDeviceId)" | 
| 35 | + class="list-item" v-for="item in list" :key="item.id"> | ||
| 36 | + <view class="u-flex item" style=" | ||
| 34 | justify-content: flex-start; | 37 | justify-content: flex-start; | 
| 35 | flex-direction: column; | 38 | flex-direction: column; | 
| 36 | align-items: center; | 39 | align-items: center; | 
| 37 | - " | ||
| 38 | - > | 40 | + "> | 
| 39 | <view style="width: 450rpx; text-align: left"> | 41 | <view style="width: 450rpx; text-align: left"> | 
| 40 | - <text style="color: #333; font-size: 15px;font-weight: bold;">{{ item.name }}</text> | 42 | + <text | 
| 43 | + style="color: #333; font-size: 15px;font-weight: bold;">{{ item.alias?item.alias:item.name }}</text> | ||
| 41 | </view> | 44 | </view> | 
| 42 | <view style="width: 450rpx; text-align: left; margin-top: 10rpx"> | 45 | <view style="width: 450rpx; text-align: left; margin-top: 10rpx"> | 
| 43 | <view style="color: #666; font-size: 14px;display: flex;"> | 46 | <view style="color: #666; font-size: 14px;display: flex;"> | 
| @@ -54,32 +57,26 @@ | @@ -54,32 +57,26 @@ | ||
| 54 | </view> | 57 | </view> | 
| 55 | <view class="item"> | 58 | <view class="item"> | 
| 56 | <view class="u-flex" style="margin-top: -6rpx"> | 59 | <view class="u-flex" style="margin-top: -6rpx"> | 
| 57 | - <image | ||
| 58 | - style=" | 60 | + <image style=" | 
| 59 | width: 30rpx; | 61 | width: 30rpx; | 
| 60 | height: 30rpx; | 62 | height: 30rpx; | 
| 61 | margin-top: 5rpx; | 63 | margin-top: 5rpx; | 
| 62 | margin-right: 5rpx; | 64 | margin-right: 5rpx; | 
| 63 | - " | ||
| 64 | - :src=" | 65 | + " :src=" | 
| 65 | item.deviceState === 'ONLINE' | 66 | item.deviceState === 'ONLINE' | 
| 66 | ? '../../static/online.png' | 67 | ? '../../static/online.png' | 
| 67 | : item.deviceState === 'INACTIVE' | 68 | : item.deviceState === 'INACTIVE' | 
| 68 | ? '../../static/unonline.png' | 69 | ? '../../static/unonline.png' | 
| 69 | : '../../static/baojing.png' | 70 | : '../../static/baojing.png' | 
| 70 | - " | ||
| 71 | - /> | 71 | + " /> | 
| 72 | 72 | ||
| 73 | <view> | 73 | <view> | 
| 74 | - <text | ||
| 75 | - style=" | 74 | + <text style=" | 
| 76 | color: #377dff; | 75 | color: #377dff; | 
| 77 | font-size: 13px; | 76 | font-size: 13px; | 
| 78 | margin-left: 5rpx; | 77 | margin-left: 5rpx; | 
| 79 | margin-top: 20rpx; | 78 | margin-top: 20rpx; | 
| 80 | - " | ||
| 81 | - :style="{ color: item.deviceState === 'ONLINE' ? '#377DFF' : item.deviceState === 'INACTIVE' ? '#666666' : '#DE4437' }" | ||
| 82 | - > | 79 | + " :style="{ color: item.deviceState === 'ONLINE' ? '#377DFF' : item.deviceState === 'INACTIVE' ? '#666666' : '#DE4437' }"> | 
| 83 | {{ item.deviceState === 'ONLINE' ? '在线' : item.deviceState === 'INACTIVE' ? '待激活' : '离线' }} | 80 | {{ item.deviceState === 'ONLINE' ? '在线' : item.deviceState === 'INACTIVE' ? '待激活' : '离线' }} | 
| 84 | </text> | 81 | </text> | 
| 85 | </view> | 82 | </view> | 
| @@ -89,15 +86,24 @@ | @@ -89,15 +86,24 @@ | ||
| 89 | </view> | 86 | </view> | 
| 90 | </mescroll-body> | 87 | </mescroll-body> | 
| 91 | <!-- 设备筛选 --> | 88 | <!-- 设备筛选 --> | 
| 92 | - <u-popup @close="close" closeable bgColor="#fff" :show="show" mode="bottom" :round="20" @touchmove.stop.prevent="disabledScroll"> | 89 | + <u-popup @close="close" closeable bgColor="#fff" :show="show" mode="bottom" :round="20" | 
| 90 | + @touchmove.stop.prevent="disabledScroll"> | ||
| 93 | <view class="filter" @touchmove.stop.prevent="disabledScroll"> | 91 | <view class="filter" @touchmove.stop.prevent="disabledScroll"> | 
| 94 | <view class="filter-title"><text>筛选条件</text></view> | 92 | <view class="filter-title"><text>筛选条件</text></view> | 
| 95 | - <FilterItem :filterList="deviceStatus" title="设备状态" @clickTag="currentIndex => handleClickTag(currentIndex, deviceStatus)"></FilterItem> | ||
| 96 | - <FilterItem :filterList="alarmStatus" title="告警状态" @clickTag="currentIndex => handleClickTag(currentIndex, alarmStatus)"></FilterItem> | ||
| 97 | - <FilterItem :filterList="typeStatus" title="设备类型" @clickTag="currentIndex => handleClickTag(currentIndex, typeStatus)"></FilterItem> | 93 | + <FilterItem :filterList="deviceStatus" title="设备状态" | 
| 94 | + @clickTag="currentIndex => handleClickTag(currentIndex, deviceStatus)"></FilterItem> | ||
| 95 | + <FilterItem :filterList="alarmStatus" title="告警状态" | ||
| 96 | + @clickTag="currentIndex => handleClickTag(currentIndex, alarmStatus)"></FilterItem> | ||
| 97 | + <FilterItem :filterList="typeStatus" title="设备类型" | ||
| 98 | + @clickTag="currentIndex => handleClickTag(currentIndex, typeStatus)"></FilterItem> | ||
| 98 | <view class="button-group"> | 99 | <view class="button-group"> | 
| 99 | - <view><u-button :customStyle="{ color: '#333' }" color="#e3e3e5" shape="circle" text="重置" @click="resetFilter"></u-button></view> | ||
| 100 | - <view><u-button color="#3388ff" shape="circle" text="确认" @click="confirmFilter"></u-button></view> | 100 | + <view> | 
| 101 | + <u-button :customStyle="{ color: '#333' }" color="#e3e3e5" shape="circle" text="重置" | ||
| 102 | + @click="resetFilter"></u-button> | ||
| 103 | + </view> | ||
| 104 | + <view> | ||
| 105 | + <u-button color="#3388ff" shape="circle" text="确认" @click="confirmFilter"></u-button> | ||
| 106 | + </view> | ||
| 101 | </view> | 107 | </view> | 
| 102 | </view> | 108 | </view> | 
| 103 | </u-popup> | 109 | </u-popup> | 
| @@ -106,295 +112,317 @@ | @@ -106,295 +112,317 @@ | ||
| 106 | </template> | 112 | </template> | 
| 107 | 113 | ||
| 108 | <script> | 114 | <script> | 
| 109 | -import fTabbar from '@/components/module/f-tabbar/f-tabbar'; | ||
| 110 | -import FilterItem from './FilterItem.vue'; | ||
| 111 | -import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'; | ||
| 112 | -import { debounce } from '@/plugins/throttle.js'; | ||
| 113 | -export default { | ||
| 114 | - mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件) | ||
| 115 | - components: { | ||
| 116 | - fTabbar, | ||
| 117 | - FilterItem | ||
| 118 | - }, | ||
| 119 | - data() { | ||
| 120 | - return { | ||
| 121 | - downOption: { | ||
| 122 | - auto: false //是否在初始化后,自动执行downCallback; 默认true | ||
| 123 | - }, | ||
| 124 | - upOption: { | ||
| 125 | - isBounce: false, | ||
| 126 | - auto: false // 不自动加载 | ||
| 127 | - }, | ||
| 128 | - show: false, | ||
| 129 | - deviceStatus: [ | ||
| 130 | - { | ||
| 131 | - checked: true, | ||
| 132 | - name: '全部', | ||
| 133 | - type: '' | ||
| 134 | - }, | ||
| 135 | - { | ||
| 136 | - checked: false, | ||
| 137 | - name: '在线', | ||
| 138 | - type: 'ONLINE' | ||
| 139 | - }, | ||
| 140 | - { | ||
| 141 | - checked: false, | ||
| 142 | - name: '离线', | ||
| 143 | - type: 'OFFLINE' | ||
| 144 | - }, | ||
| 145 | - { | ||
| 146 | - checked: false, | ||
| 147 | - name: '待激活', | ||
| 148 | - type: 'INACTIVE' | ||
| 149 | - } | ||
| 150 | - ], | ||
| 151 | - alarmStatus: [ | ||
| 152 | - { | ||
| 153 | - checked: true, | ||
| 154 | - name: '全部', | ||
| 155 | - type: '' | ||
| 156 | - }, | ||
| 157 | - { | ||
| 158 | - checked: false, | ||
| 159 | - name: '告警', | ||
| 160 | - type: '1' | 115 | + import fTabbar from '@/components/module/f-tabbar/f-tabbar'; | 
| 116 | + import FilterItem from './FilterItem.vue'; | ||
| 117 | + import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js'; | ||
| 118 | + import { | ||
| 119 | + debounce | ||
| 120 | + } from '@/plugins/throttle.js'; | ||
| 121 | + export default { | ||
| 122 | + mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件) | ||
| 123 | + components: { | ||
| 124 | + fTabbar, | ||
| 125 | + FilterItem | ||
| 126 | + }, | ||
| 127 | + data() { | ||
| 128 | + return { | ||
| 129 | + downOption: { | ||
| 130 | + auto: false //是否在初始化后,自动执行downCallback; 默认true | ||
| 161 | }, | 131 | }, | 
| 162 | - { | ||
| 163 | - checked: false, | ||
| 164 | - name: '正常', | ||
| 165 | - type: '0' | ||
| 166 | - } | ||
| 167 | - ], | ||
| 168 | - typeStatus: [ | ||
| 169 | - { | ||
| 170 | - checked: true, | ||
| 171 | - name: '全部', | ||
| 172 | - type: '' | 132 | + upOption: { | 
| 133 | + isBounce: false, | ||
| 134 | + auto: false // 不自动加载 | ||
| 173 | }, | 135 | }, | 
| 136 | + show: false, | ||
| 137 | + deviceStatus: [{ | ||
| 138 | + checked: true, | ||
| 139 | + name: '全部', | ||
| 140 | + type: '' | ||
| 141 | + }, | ||
| 142 | + { | ||
| 143 | + checked: false, | ||
| 144 | + name: '在线', | ||
| 145 | + type: 'ONLINE' | ||
| 146 | + }, | ||
| 147 | + { | ||
| 148 | + checked: false, | ||
| 149 | + name: '离线', | ||
| 150 | + type: 'OFFLINE' | ||
| 151 | + }, | ||
| 152 | + { | ||
| 153 | + checked: false, | ||
| 154 | + name: '待激活', | ||
| 155 | + type: 'INACTIVE' | ||
| 156 | + } | ||
| 157 | + ], | ||
| 158 | + alarmStatus: [{ | ||
| 159 | + checked: true, | ||
| 160 | + name: '全部', | ||
| 161 | + type: '' | ||
| 162 | + }, | ||
| 163 | + { | ||
| 164 | + checked: false, | ||
| 165 | + name: '告警', | ||
| 166 | + type: '1' | ||
| 167 | + }, | ||
| 168 | + { | ||
| 169 | + checked: false, | ||
| 170 | + name: '正常', | ||
| 171 | + type: '0' | ||
| 172 | + } | ||
| 173 | + ], | ||
| 174 | + typeStatus: [{ | ||
| 175 | + checked: true, | ||
| 176 | + name: '全部', | ||
| 177 | + type: '' | ||
| 178 | + }, | ||
| 174 | 179 | ||
| 175 | - { | ||
| 176 | - checked: false, | ||
| 177 | - name: '直连设备', | ||
| 178 | - type: 'DIRECT_CONNECTION' | ||
| 179 | - }, | ||
| 180 | - { | ||
| 181 | - checked: false, | ||
| 182 | - name: '网关设备', | ||
| 183 | - type: 'GATEWAY' | 180 | + { | 
| 181 | + checked: false, | ||
| 182 | + name: '直连设备', | ||
| 183 | + type: 'DIRECT_CONNECTION' | ||
| 184 | + }, | ||
| 185 | + { | ||
| 186 | + checked: false, | ||
| 187 | + name: '网关设备', | ||
| 188 | + type: 'GATEWAY' | ||
| 189 | + }, | ||
| 190 | + { | ||
| 191 | + checked: false, | ||
| 192 | + name: '网关子设备', | ||
| 193 | + type: 'SENSOR' | ||
| 194 | + } | ||
| 195 | + ], | ||
| 196 | + total: 0, | ||
| 197 | + list: [], | ||
| 198 | + page: { | ||
| 199 | + num: 0, | ||
| 200 | + size: 10 | ||
| 184 | }, | 201 | }, | 
| 185 | - { | ||
| 186 | - checked: false, | ||
| 187 | - name: '网关子设备', | ||
| 188 | - type: 'SENSOR' | ||
| 189 | - } | ||
| 190 | - ], | ||
| 191 | - total: 0, | ||
| 192 | - list: [], | ||
| 193 | - page: { | ||
| 194 | - num: 0, | ||
| 195 | - size: 10 | ||
| 196 | - }, | ||
| 197 | - deviceState: '', | ||
| 198 | - deviceName: '' | ||
| 199 | - }; | ||
| 200 | - }, | ||
| 201 | - async onLoad(options) { | ||
| 202 | - // 隐藏原生的tabbar | ||
| 203 | - uni.hideTabBar(); | ||
| 204 | - this.page.num = 1; | ||
| 205 | - const { deviceState } = options; | ||
| 206 | - this.deviceState = deviceState; | ||
| 207 | - if (deviceState) { | ||
| 208 | - this.deviceStatus.forEach(item => { | ||
| 209 | - item.type === deviceState ? (item.checked = true) : (item.checked = false); | ||
| 210 | - }); | ||
| 211 | - await this.loadData(1, { | ||
| 212 | - deviceState | ||
| 213 | - }); | ||
| 214 | - } else { | ||
| 215 | - await this.loadData(1); | ||
| 216 | - } | ||
| 217 | - if (!this.list.length) { | ||
| 218 | - this.mescroll.showEmpty(); | ||
| 219 | - } | ||
| 220 | - }, | ||
| 221 | - onShow() { | ||
| 222 | - if (this.orgId) { | ||
| 223 | - this.loadData(1, { | ||
| 224 | - organizationId: this.orgId | ||
| 225 | - }); | ||
| 226 | - } | ||
| 227 | - }, | ||
| 228 | - methods: { | ||
| 229 | - disabledScroll() { | ||
| 230 | - return; | 202 | + deviceState: '', | 
| 203 | + deviceName: '' | ||
| 204 | + }; | ||
| 231 | }, | 205 | }, | 
| 232 | - /*下拉刷新的回调 */ | ||
| 233 | - downCallback() { | ||
| 234 | - this.deviceName = ''; | ||
| 235 | - this.orgId = ''; | ||
| 236 | - //联网加载数据 | ||
| 237 | - this.list = []; | 206 | + async onLoad(options) { | 
| 207 | + // 隐藏原生的tabbar | ||
| 208 | + uni.hideTabBar(); | ||
| 238 | this.page.num = 1; | 209 | this.page.num = 1; | 
| 239 | - //联网加载数据 | ||
| 240 | - this.resetFilter(); | ||
| 241 | - this.loadData(this.page.num); | 210 | + const { | 
| 211 | + deviceState | ||
| 212 | + } = options; | ||
| 213 | + this.deviceState = deviceState; | ||
| 214 | + if (deviceState) { | ||
| 215 | + this.deviceStatus.forEach(item => { | ||
| 216 | + item.type === deviceState ? (item.checked = true) : (item.checked = false); | ||
| 217 | + }); | ||
| 218 | + await this.loadData(1, { | ||
| 219 | + deviceState | ||
| 220 | + }); | ||
| 221 | + } else { | ||
| 222 | + await this.loadData(1); | ||
| 223 | + } | ||
| 224 | + if (!this.list.length) { | ||
| 225 | + this.mescroll.showEmpty(); | ||
| 226 | + } | ||
| 242 | }, | 227 | }, | 
| 243 | - | ||
| 244 | - /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */ | ||
| 245 | - upCallback() { | ||
| 246 | - //联网加载数据 | ||
| 247 | - this.page.num += 1; | ||
| 248 | - const deviceState = this.deviceStatus.find(item => item.checked); | ||
| 249 | - const alarmStatus = this.alarmStatus.find(item => item.checked); | ||
| 250 | - const deviceType = this.typeStatus.find(item => item.checked); | ||
| 251 | - this.loadData(this.page.num, { | ||
| 252 | - deviceState: deviceState.type ? deviceState.type : undefined, | ||
| 253 | - deviceType: deviceType.type ? deviceType.type : undefined, | ||
| 254 | - alarmStatus: alarmStatus.type === '0' || alarmStatus.type === '1' ? alarmStatus.type : undefined, | ||
| 255 | - name: this.deviceName == null ? null : this.deviceName, | ||
| 256 | - organizationId: this.orgId == null ? null : this.orgId | ||
| 257 | - }); | 228 | + onShow() { | 
| 229 | + if (this.orgId) { | ||
| 230 | + this.loadData(1, { | ||
| 231 | + organizationId: this.orgId | ||
| 232 | + }); | ||
| 233 | + } | ||
| 258 | }, | 234 | }, | 
| 235 | + methods: { | ||
| 236 | + disabledScroll() { | ||
| 237 | + return; | ||
| 238 | + }, | ||
| 239 | + /*下拉刷新的回调 */ | ||
| 240 | + downCallback() { | ||
| 241 | + this.deviceName = ''; | ||
| 242 | + this.orgId = ''; | ||
| 243 | + //联网加载数据 | ||
| 244 | + this.list = []; | ||
| 245 | + this.page.num = 1; | ||
| 246 | + //联网加载数据 | ||
| 247 | + this.resetFilter(); | ||
| 248 | + this.loadData(this.page.num); | ||
| 249 | + }, | ||
| 259 | 250 | ||
| 260 | - //获取设备 | ||
| 261 | - async loadData(pageNo, params = {}) { | ||
| 262 | - try { | ||
| 263 | - let httpData = { | ||
| 264 | - page: pageNo, | ||
| 265 | - pageSize: 10, | ||
| 266 | - ...params | ||
| 267 | - }; | ||
| 268 | - const { total, items } = await uni.$u.http.get('/yt/device', { | ||
| 269 | - params: httpData, | ||
| 270 | - custom: { | ||
| 271 | - load: false | ||
| 272 | - } | 251 | + /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */ | 
| 252 | + upCallback() { | ||
| 253 | + //联网加载数据 | ||
| 254 | + this.page.num += 1; | ||
| 255 | + const deviceState = this.deviceStatus.find(item => item.checked); | ||
| 256 | + const alarmStatus = this.alarmStatus.find(item => item.checked); | ||
| 257 | + const deviceType = this.typeStatus.find(item => item.checked); | ||
| 258 | + this.loadData(this.page.num, { | ||
| 259 | + deviceState: deviceState.type ? deviceState.type : undefined, | ||
| 260 | + deviceType: deviceType.type ? deviceType.type : undefined, | ||
| 261 | + alarmStatus: alarmStatus.type === '0' || alarmStatus.type === '1' ? alarmStatus.type : | ||
| 262 | + undefined, | ||
| 263 | + name: this.deviceName == null ? null : this.deviceName, | ||
| 264 | + organizationId: this.orgId == null ? null : this.orgId | ||
| 273 | }); | 265 | }); | 
| 274 | - this.total = total; | ||
| 275 | - uni.stopPullDownRefresh(); | ||
| 276 | - this.mescroll.endByPage(items.length, total); //必传参数(当前页的数据个数, 总页数) | ||
| 277 | - if (pageNo == 1) { | ||
| 278 | - this.list = items; | ||
| 279 | - } else { | ||
| 280 | - this.list = this.list.concat(items); | 266 | + }, | 
| 267 | + | ||
| 268 | + //获取设备 | ||
| 269 | + async loadData(pageNo, params = {}) { | ||
| 270 | + try { | ||
| 271 | + let httpData = { | ||
| 272 | + page: pageNo, | ||
| 273 | + pageSize: 10, | ||
| 274 | + ...params | ||
| 275 | + }; | ||
| 276 | + const { | ||
| 277 | + total, | ||
| 278 | + items | ||
| 279 | + } = await uni.$u.http.get('/yt/device', { | ||
| 280 | + params: httpData, | ||
| 281 | + custom: { | ||
| 282 | + load: false | ||
| 283 | + } | ||
| 284 | + }); | ||
| 285 | + this.total = total; | ||
| 286 | + uni.stopPullDownRefresh(); | ||
| 287 | + this.mescroll.endByPage(items.length, total); //必传参数(当前页的数据个数, 总页数) | ||
| 288 | + if (pageNo == 1) { | ||
| 289 | + this.list = items; | ||
| 290 | + } else { | ||
| 291 | + this.list = this.list.concat(items); | ||
| 292 | + } | ||
| 293 | + } catch { | ||
| 294 | + this.mescroll.endErr(); | ||
| 281 | } | 295 | } | 
| 282 | - } catch { | ||
| 283 | - this.mescroll.endErr(); | 296 | + }, | 
| 297 | + openOrg() { | ||
| 298 | + uni.navigateTo({ | ||
| 299 | + url: './org/org' | ||
| 300 | + }); | ||
| 301 | + }, | ||
| 302 | + close() { | ||
| 303 | + this.show = false; | ||
| 304 | + }, | ||
| 305 | + openSearchDialog() { | ||
| 306 | + this.show = true; | ||
| 307 | + }, | ||
| 308 | + openDeviceDetail(id, alarmStatus, lastOnlineTime, tbDeviceId) { | ||
| 309 | + uni.navigateTo({ | ||
| 310 | + url: `/deviceSubPage/deviceDetailPage/deviceDetail?id=${id}&alarmStatus=${alarmStatus}&lastOnlineTime=${lastOnlineTime}&tbDeviceId=${tbDeviceId}` | ||
| 311 | + }); | ||
| 312 | + }, | ||
| 313 | + handleClickTag(currentIndex, list) { | ||
| 314 | + list.map((item, index) => { | ||
| 315 | + item.checked = index === currentIndex; | ||
| 316 | + }); | ||
| 317 | + }, | ||
| 318 | + resetFilter() { | ||
| 319 | + const { | ||
| 320 | + deviceStatus, | ||
| 321 | + alarmStatus, | ||
| 322 | + typeStatus | ||
| 323 | + } = this; | ||
| 324 | + [deviceStatus, alarmStatus, typeStatus].forEach(item => item.map((item, index) => (item.checked = index === | ||
| 325 | + 0))); | ||
| 326 | + }, | ||
| 327 | + confirmFilter() { | ||
| 328 | + const deviceState = this.deviceStatus.find(item => item.checked); | ||
| 329 | + const alarmStatus = this.alarmStatus.find(item => item.checked); | ||
| 330 | + const deviceType = this.typeStatus.find(item => item.checked); | ||
| 331 | + this.loadData(1, { | ||
| 332 | + deviceState: deviceState.type ? deviceState.type : undefined, | ||
| 333 | + deviceType: deviceType.type ? deviceType.type : undefined, | ||
| 334 | + alarmStatus: alarmStatus.type === '0' || alarmStatus.type === '1' ? alarmStatus.type : | ||
| 335 | + undefined | ||
| 336 | + }); | ||
| 337 | + this.show = false; | ||
| 338 | + }, | ||
| 339 | + inputChanged(e) { | ||
| 340 | + this.page.num = 1; | ||
| 341 | + this.deviceName = e; | ||
| 342 | + this.loadData(1, { | ||
| 343 | + name: this.deviceName | ||
| 344 | + }); | ||
| 284 | } | 345 | } | 
| 285 | - }, | ||
| 286 | - openOrg() { | ||
| 287 | - uni.navigateTo({ | ||
| 288 | - url: './org/org' | ||
| 289 | - }); | ||
| 290 | - }, | ||
| 291 | - close() { | ||
| 292 | - this.show = false; | ||
| 293 | - }, | ||
| 294 | - openSearchDialog() { | ||
| 295 | - this.show = true; | ||
| 296 | - }, | ||
| 297 | - openDeviceDetail(id, alarmStatus, lastOnlineTime, tbDeviceId) { | ||
| 298 | - uni.navigateTo({ | ||
| 299 | - url: `/deviceSubPage/deviceDetailPage/deviceDetail?id=${id}&alarmStatus=${alarmStatus}&lastOnlineTime=${lastOnlineTime}&tbDeviceId=${tbDeviceId}` | ||
| 300 | - }); | ||
| 301 | - }, | ||
| 302 | - handleClickTag(currentIndex, list) { | ||
| 303 | - list.map((item, index) => { | ||
| 304 | - item.checked = index === currentIndex; | ||
| 305 | - }); | ||
| 306 | - }, | ||
| 307 | - resetFilter() { | ||
| 308 | - const { deviceStatus, alarmStatus, typeStatus } = this; | ||
| 309 | - [deviceStatus, alarmStatus, typeStatus].forEach(item => item.map((item, index) => (item.checked = index === 0))); | ||
| 310 | - }, | ||
| 311 | - confirmFilter() { | ||
| 312 | - const deviceState = this.deviceStatus.find(item => item.checked); | ||
| 313 | - const alarmStatus = this.alarmStatus.find(item => item.checked); | ||
| 314 | - const deviceType = this.typeStatus.find(item => item.checked); | ||
| 315 | - this.loadData(1, { | ||
| 316 | - deviceState: deviceState.type ? deviceState.type : undefined, | ||
| 317 | - deviceType: deviceType.type ? deviceType.type : undefined, | ||
| 318 | - alarmStatus: alarmStatus.type === '0' || alarmStatus.type === '1' ? alarmStatus.type : undefined | ||
| 319 | - }); | ||
| 320 | - this.show = false; | ||
| 321 | - }, | ||
| 322 | - inputChanged(e) { | ||
| 323 | - this.page.num = 1; | ||
| 324 | - this.deviceName = e; | ||
| 325 | - this.loadData(1, { | ||
| 326 | - name: this.deviceName | ||
| 327 | - }); | ||
| 328 | } | 346 | } | 
| 329 | - } | ||
| 330 | -}; | 347 | + }; | 
| 331 | </script> | 348 | </script> | 
| 332 | 349 | ||
| 333 | <style lang="scss" scoped> | 350 | <style lang="scss" scoped> | 
| 334 | -.device-page { | ||
| 335 | - min-height: 100vh; | ||
| 336 | - background-color: #f8f9fa; | ||
| 337 | -} | ||
| 338 | -.device-top { | ||
| 339 | - padding: 10rpx 30rpx; | ||
| 340 | - background-color: #fff; | ||
| 341 | - .search { | ||
| 342 | - display: flex; | ||
| 343 | - justify-content: space-between; | ||
| 344 | - padding-bottom: 10rpx; | ||
| 345 | - .search-left { | ||
| 346 | - width: 580rpx; | ||
| 347 | - background-color: #f8f9fa; | ||
| 348 | - border-radius: 200rpx; | ||
| 349 | - } | ||
| 350 | - .search-right { | 351 | + .device-page { | 
| 352 | + min-height: 100vh; | ||
| 353 | + background-color: #f8f9fa; | ||
| 354 | + } | ||
| 355 | + | ||
| 356 | + .device-top { | ||
| 357 | + padding: 10rpx 30rpx; | ||
| 358 | + background-color: #fff; | ||
| 359 | + | ||
| 360 | + .search { | ||
| 351 | display: flex; | 361 | display: flex; | 
| 352 | - align-items: center; | ||
| 353 | - text { | ||
| 354 | - color: #333; | ||
| 355 | - font-size: 14px; | 362 | + justify-content: space-between; | 
| 363 | + padding-bottom: 10rpx; | ||
| 364 | + | ||
| 365 | + .search-left { | ||
| 366 | + width: 580rpx; | ||
| 367 | + background-color: #f8f9fa; | ||
| 368 | + border-radius: 200rpx; | ||
| 356 | } | 369 | } | 
| 357 | - image { | ||
| 358 | - width: 40rpx; | ||
| 359 | - height: 40rpx; | 370 | + | 
| 371 | + .search-right { | ||
| 372 | + display: flex; | ||
| 373 | + align-items: center; | ||
| 374 | + | ||
| 375 | + text { | ||
| 376 | + color: #333; | ||
| 377 | + font-size: 14px; | ||
| 378 | + } | ||
| 379 | + | ||
| 380 | + image { | ||
| 381 | + width: 40rpx; | ||
| 382 | + height: 40rpx; | ||
| 383 | + } | ||
| 360 | } | 384 | } | 
| 361 | } | 385 | } | 
| 362 | } | 386 | } | 
| 363 | -} | ||
| 364 | 387 | ||
| 365 | -.device-list { | ||
| 366 | - display: flex; | ||
| 367 | - flex-direction: column; | ||
| 368 | - padding-left: 20rpx; | ||
| 369 | - .list-item { | ||
| 370 | - width: 713rpx; | ||
| 371 | - height: 200rpx; | ||
| 372 | - background-color: #fff; | ||
| 373 | - margin-top: 24rpx; | 388 | + .device-list { | 
| 374 | display: flex; | 389 | display: flex; | 
| 375 | - border-radius: 10px; | ||
| 376 | - justify-content: space-between; | ||
| 377 | - .item { | ||
| 378 | - margin: 30rpx; | 390 | + flex-direction: column; | 
| 391 | + padding-left: 20rpx; | ||
| 392 | + | ||
| 393 | + .list-item { | ||
| 394 | + width: 713rpx; | ||
| 395 | + height: 200rpx; | ||
| 396 | + background-color: #fff; | ||
| 397 | + margin-top: 24rpx; | ||
| 398 | + display: flex; | ||
| 399 | + border-radius: 10px; | ||
| 400 | + justify-content: space-between; | ||
| 401 | + | ||
| 402 | + .item { | ||
| 403 | + margin: 30rpx; | ||
| 404 | + } | ||
| 379 | } | 405 | } | 
| 380 | } | 406 | } | 
| 381 | -} | ||
| 382 | 407 | ||
| 383 | -.filter { | ||
| 384 | - padding: 0 30rpx; | ||
| 385 | - .filter-title { | ||
| 386 | - text-align: center; | ||
| 387 | - margin-top: 14px; | ||
| 388 | - font-size: 16px; | ||
| 389 | - font-weight: 700; | ||
| 390 | - } | ||
| 391 | - .button-group { | ||
| 392 | - display: flex; | ||
| 393 | - margin-top: 40rpx; | ||
| 394 | - justify-content: space-between; | ||
| 395 | - view { | ||
| 396 | - width: 330rpx; | 408 | + .filter { | 
| 409 | + padding: 0 30rpx; | ||
| 410 | + | ||
| 411 | + .filter-title { | ||
| 412 | + text-align: center; | ||
| 413 | + margin-top: 14px; | ||
| 414 | + font-size: 16px; | ||
| 415 | + font-weight: 700; | ||
| 416 | + } | ||
| 417 | + | ||
| 418 | + .button-group { | ||
| 419 | + display: flex; | ||
| 420 | + margin-top: 40rpx; | ||
| 421 | + justify-content: space-between; | ||
| 422 | + | ||
| 423 | + view { | ||
| 424 | + width: 330rpx; | ||
| 425 | + } | ||
| 397 | } | 426 | } | 
| 398 | } | 427 | } | 
| 399 | -} | ||
| 400 | </style> | 428 | </style> | 
| @@ -48,6 +48,9 @@ button { | @@ -48,6 +48,9 @@ button { | ||
| 48 | } | 48 | } | 
| 49 | ///////////////////////////////////////////////////////////////小程序、app抽取公共样式///////////////////////////////////////////////////////////////////// | 49 | ///////////////////////////////////////////////////////////////小程序、app抽取公共样式///////////////////////////////////////////////////////////////////// | 
| 50 | //通用(设备、告警、摄像头分页头部组织和设备数和设备、告警里面的详情(左边的文本) | 50 | //通用(设备、告警、摄像头分页头部组织和设备数和设备、告警里面的详情(左边的文本) | 
| 51 | +.ml-10{ | ||
| 52 | + margin-left: 10rpx; | ||
| 53 | +} | ||
| 51 | .text-org-bold { | 54 | .text-org-bold { | 
| 52 | width:200rpx; | 55 | width:200rpx; | 
| 53 | color: #333333; | 56 | color: #333333; |