Commit 1a1e18c68473e2d078a01f9f80c7f7bc4b1874a7

Authored by fengtao
1 parent 4fd21827

fix:修改设备实时数据传keys和历史数据传参加上limit

1 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 11 export function getHistoryData(params) {
3   - const {
4   - entityId,
5   - keys,
6   - startTs,
7   - endTs,
8   - interval
  12 + let {
  13 + entityId
9 14 } = params
  15 + params = getUrlParams(params)
10 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 23 // 获取当前设备的key
16 24 export function getDeviceKeys(id) {
17 25 return uni.$u.http.get(`/plugins/telemetry/DEVICE/${id}/keys/timeseries`);
18 26 };
19 27
20 28 export function issueCommand(type, tbDeviceId, data) {
21   - console.log(type,tbDeviceId)
  29 + console.log(type, tbDeviceId)
22 30 return uni.$u.http.post(`/rpc/${type==='OneWay'?'oneway':'twoway'}/${tbDeviceId}`, data)
23 31 }
... ...
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="{
  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 7 fontWeight: 'bold',
12 8 color: '#333',
13   - }"
14   - :inactiveStyle="{
  9 + }" :inactiveStyle="{
15 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 22 </template>
40 23
41 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 239 </script>
231 240
232 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 5 <view class="historyData-top">
6 6 <u-form :label-style="{ 'font-size': '0rpx' }">
7 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 10 <template slot="prefix">
10 11 <image class="icon" src="../../../static/can-der.png"></image>
11 12 </template>
12 13 </u-input>
13 14 </u-form-item>
14 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 18 <template slot="prefix">
17 19 <image class="icon" src="../../../static/time.png"></image>
18 20 </template>
19 21 </u-input>
20 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 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 37 </u-form-item>
24 38 </u-form>
25 39
26 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 44 </view>
36 45 <mescroll-empty v-if="!historyData.length" />
37 46 </view>
... ... @@ -41,166 +50,125 @@
41 50 <view class="th">变量值</view>
42 51 <view class="th">更新时间</view>
43 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 55 <view class="td">{{ item.value }}</view>
46 56 <view class="td">{{ item.ts }}</view>
47 57 </view>
48 58 </view>
49 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 69 </view>
75 70 </template>
76 71
77 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 172 label: '5分钟',
205 173 value: 300000
206 174 },
... ... @@ -225,173 +193,253 @@ export default {
225 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 382 </script>
344 383
345 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 415 display: flex;
  416 + width: 100%;
377 417 justify-content: center;
  418 + height: 3rem;
378 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 445 </style>
... ...
... ... @@ -4,7 +4,10 @@
4 4 <view class="device-top">
5 5 <view class="search">
6 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 11 </view>
9 12 <view @click="openSearchDialog" class="search-right">
10 13 <text>筛选</text>
... ... @@ -25,19 +28,19 @@
25 28 </view>
26 29 </view>
27 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 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 37 justify-content: flex-start;
35 38 flex-direction: column;
36 39 align-items: center;
37   - "
38   - >
  40 + ">
39 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 44 </view>
42 45 <view style="width: 450rpx; text-align: left; margin-top: 10rpx">
43 46 <view style="color: #666; font-size: 14px;display: flex;">
... ... @@ -54,32 +57,26 @@
54 57 </view>
55 58 <view class="item">
56 59 <view class="u-flex" style="margin-top: -6rpx">
57   - <image
58   - style="
  60 + <image style="
59 61 width: 30rpx;
60 62 height: 30rpx;
61 63 margin-top: 5rpx;
62 64 margin-right: 5rpx;
63   - "
64   - :src="
  65 + " :src="
65 66 item.deviceState === 'ONLINE'
66 67 ? '../../static/online.png'
67 68 : item.deviceState === 'INACTIVE'
68 69 ? '../../static/unonline.png'
69 70 : '../../static/baojing.png'
70   - "
71   - />
  71 + " />
72 72
73 73 <view>
74   - <text
75   - style="
  74 + <text style="
76 75 color: #377dff;
77 76 font-size: 13px;
78 77 margin-left: 5rpx;
79 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 80 {{ item.deviceState === 'ONLINE' ? '在线' : item.deviceState === 'INACTIVE' ? '待激活' : '离线' }}
84 81 </text>
85 82 </view>
... ... @@ -89,15 +86,24 @@
89 86 </view>
90 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 91 <view class="filter" @touchmove.stop.prevent="disabledScroll">
94 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 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 107 </view>
102 108 </view>
103 109 </u-popup>
... ... @@ -106,295 +112,317 @@
106 112 </template>
107 113
108 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 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 348 </script>
332 349
333 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 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 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 428 </style>
... ...
... ... @@ -48,6 +48,9 @@ button {
48 48 }
49 49 ///////////////////////////////////////////////////////////////小程序、app抽取公共样式/////////////////////////////////////////////////////////////////////
50 50 //通用(设备、告警、摄像头分页头部组织和设备数和设备、告警里面的详情(左边的文本)
  51 +.ml-10{
  52 + margin-left: 10rpx;
  53 +}
51 54 .text-org-bold {
52 55 width:200rpx;
53 56 color: #333333;
... ...