Commit ea961ac09edf08b35393ff3ead4b88aeb8a65ccb

Authored by fengtao
2 parents f01616e3 0b83e8b9

Merge branch 'main' into dev-ft

1 -<template>  
2 - <view class="device-detail-page">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module></public-module>  
5 - <u-sticky bgColor="#fff"><u-tabs :list="list" :current="currentTab" @click="handleTabClick"></u-tabs></u-sticky>  
6 - <view style="margin-top:30rpx;">  
7 - <basicInfo v-if="currentTab == 0" :deviceDetail="deviceDetail" />  
8 - <realTimeData v-if="currentTab === 1" />  
9 - <historyData v-if="currentTab === 2" :keys="keys" />  
10 - <alarmHistory v-if="currentTab === 3" />  
11 - <commondRecord v-if="currentTab === 4" />  
12 - </view>  
13 - <f-tabbar></f-tabbar>  
14 - </view>  
15 -</template>  
16 -  
17 -<script>  
18 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
19 -import basicInfo from './tabDetail/basicInfo.vue';  
20 -import realTimeData from './tabDetail/realtimeData.vue';  
21 -import alarmHistory from './tabDetail/alarmHistory.vue';  
22 -import historyData from './tabDetail/historyData.vue';  
23 -import commondRecord from './tabDetail/commondRecord.vue';  
24 -import { getDeviceKeys } from '../../pages/device/api/index';  
25 -export default {  
26 - components: {  
27 - fTabbar,  
28 - basicInfo,  
29 - realTimeData,  
30 - alarmHistory,  
31 - historyData,  
32 - commondRecord  
33 - },  
34 - data() {  
35 - return {  
36 - list: [{ name: '基础信息' }, { name: '实时数据' }, { name: '历史数据' }, { name: '告警记录' }, { name: '命令记录' }],  
37 - currentTab: 0,  
38 - id: '',  
39 - deviceDetail: {},  
40 - keys:[]  
41 - };  
42 - },  
43 - async onLoad(options) {  
44 - const { id, alarmStatus, lastOnlineTime, tbDeviceId } = options;  
45 - const res = await uni.$u.http.get(`/yt/device/${id}`);  
46 - this.deviceDetail = { ...res, alarmStatus, lastOnlineTime };  
47 -  
48 - // var socketTask = uni.connectSocket({  
49 - // url: 'wss://dev.thingskit.com:8080/api/ws/plugins/telemetry?token=' + uni.getStorageSync('userInfo').isToken, //仅为示例,并非真实接口地址。  
50 - // complete: ()=> {}  
51 - // });  
52 - // uni.onSocketOpen((header)=>{  
53 - // console.log('连接成功',header)  
54 - // })  
55 - // // socketTask.onMessage(function(data) {  
56 - // // console.log('收到消息了', data);  
57 - // // });  
58 - // socketTask.send({  
59 - // data: JSON.stringify({  
60 - // attrSubCmds: [],  
61 - // tsSubCmds: [  
62 - // {  
63 - // entityType: 'DEVICE',  
64 - // entityId: id,  
65 - // scope: 'LATEST_TELEMETRY',  
66 - // cmdId: 1  
67 - // }  
68 - // ],  
69 - // historyCmds: [],  
70 - // entityDataCmds: [],  
71 - // entityDataUnsubscribeCmds: [],  
72 - // alarmDataCmds: [],  
73 - // alarmDataUnsubscribeCmds: [],  
74 - // entityCountCmds: [],  
75 - // entityCountUnsubscribeCmds: []  
76 - // }),  
77 - // success() {  
78 - // console.log('发送成功了');  
79 - // }  
80 - // });  
81 -  
82 -  
83 - const keys = await getDeviceKeys(tbDeviceId);  
84 - // 隐藏原生的tabbar'  
85 - this.keys = [keys]  
86 - uni.hideTabBar();  
87 - },  
88 - methods: {  
89 - handleTabClick({ index }) {  
90 - this.currentTab = index;  
91 - }  
92 - }  
93 -}; 1 +<template>
  2 + <view class="device-detail-page">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module></public-module>
  5 + <u-sticky bgColor="#fff"><u-tabs :list="list" :current="currentTab" @click="handleTabClick"></u-tabs></u-sticky>
  6 + <view style="margin-top:30rpx;">
  7 + <basicInfo v-if="currentTab == 0" :deviceDetail="deviceDetail" />
  8 + <realTimeData v-if="currentTab === 1" />
  9 + <historyData v-if="currentTab === 2" :keys="keys" :yesterday="yesterday" :today="today" :timeDiff="timeDiff" :historyData="historyData" :entityId="entityId" @update="handleUpdate" />
  10 + <alarmHistory v-if="currentTab === 3" />
  11 + <commondRecord v-if="currentTab === 4" />
  12 + </view>
  13 + <f-tabbar></f-tabbar>
  14 + </view>
  15 +</template>
  16 +
  17 +<script>
  18 +import fTabbar from '@/components/module/f-tabbar/f-tabbar';
  19 +import basicInfo from './tabDetail/basicInfo.vue';
  20 +import realTimeData from './tabDetail/realtimeData.vue';
  21 +import alarmHistory from './tabDetail/alarmHistory.vue';
  22 +import historyData from './tabDetail/historyData.vue';
  23 +import commondRecord from './tabDetail/commondRecord.vue';
  24 +import { getDeviceKeys, getHistroyData } from '@/pages/device/api/index.js';
  25 +import { formatToDate } from '@/plugins/utils.js';
  26 +export default {
  27 + components: {
  28 + fTabbar,
  29 + basicInfo,
  30 + realTimeData,
  31 + alarmHistory,
  32 + historyData,
  33 + commondRecord
  34 + },
  35 + data() {
  36 + return {
  37 + list: [{ name: '基础信息' }, { name: '实时数据' }, { name: '历史数据' }, { name: '告警记录' }, { name: '命令记录' }],
  38 + currentTab: 2,
  39 + id: '',
  40 + deviceDetail: {},
  41 + keys: [],
  42 + yesterday: '',
  43 + today: '',
  44 + timeDiff: '',
  45 + historyData: [],
  46 + entityId: ''
  47 + };
  48 + },
  49 + async onLoad(options) {
  50 + const { id, alarmStatus, lastOnlineTime, tbDeviceId } = options;
  51 + const res = await uni.$u.http.get(`/yt/device/${id}`);
  52 + this.deviceDetail = { ...res, alarmStatus, lastOnlineTime };
  53 +
  54 + // var socketTask = uni.connectSocket({
  55 + // url: 'wss://dev.thingskit.com:8080/api/ws/plugins/telemetry?token=' + uni.getStorageSync('userInfo').isToken, //仅为示例,并非真实接口地址。
  56 + // complete: ()=> {}
  57 + // });
  58 + // uni.onSocketOpen((header)=>{
  59 + // console.log('连接成功',header)
  60 + // })
  61 + // // socketTask.onMessage(function(data) {
  62 + // // console.log('收到消息了', data);
  63 + // // });
  64 + // socketTask.send({
  65 + // data: JSON.stringify({
  66 + // attrSubCmds: [],
  67 + // tsSubCmds: [
  68 + // {
  69 + // entityType: 'DEVICE',
  70 + // entityId: id,
  71 + // scope: 'LATEST_TELEMETRY',
  72 + // cmdId: 1
  73 + // }
  74 + // ],
  75 + // historyCmds: [],
  76 + // entityDataCmds: [],
  77 + // entityDataUnsubscribeCmds: [],
  78 + // alarmDataCmds: [],
  79 + // alarmDataUnsubscribeCmds: [],
  80 + // entityCountCmds: [],
  81 + // entityCountUnsubscribeCmds: []
  82 + // }),
  83 + // success() {
  84 + // console.log('发送成功了');
  85 + // }
  86 + // });
  87 +
  88 + const keys = await getDeviceKeys(tbDeviceId);
  89 + // 隐藏原生的tabbar'
  90 + this.keys = [keys];
  91 + const date = new Date();
  92 + const year = date.getFullYear(); //获取完整的年份(4位)
  93 + const month = date.getMonth() + 1; //获取当前月份(0-11,0代表1月)
  94 + const day = date.getDate(); //获取当前日(1-31)
  95 + const yesterday = `${year}-${month}-${day - 1}`;
  96 + const today = `${year}-${month}-${day + 1}`;
  97 + this.yesterday = yesterday;
  98 + this.today = today;
  99 + this.entityId = tbDeviceId
  100 + const data = await getHistroyData({
  101 + entityId: tbDeviceId,
  102 + startTs: formatToDate(yesterday, 'x'),
  103 + endTs: formatToDate(today, 'x'),
  104 + keys: keys[0]
  105 + });
  106 +
  107 + this.historyData = data[keys[0]].map(item => {
  108 + return {
  109 + value: item.value,
  110 + ts: formatToDate(item.ts, 'YYYY-MM-DD HH:mm:ss')
  111 + };
  112 + });
  113 + this.timeDiff = '30分钟';
  114 + uni.hideTabBar();
  115 + },
  116 + methods: {
  117 + handleTabClick({ index }) {
  118 + this.currentTab = index;
  119 + },
  120 + handleUpdate(data){
  121 + this.historyData = data.map(item => {
  122 + return {
  123 + value: item.value,
  124 + ts: formatToDate(item.ts, 'YYYY-MM-DD HH:mm:ss')
  125 + };
  126 + });
  127 + }
  128 + }
  129 +};
94 </script> 130 </script>
1 -<template>  
2 - <view class="alert-page">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module></public-module>  
5 - <view style="width: 192rpx;margin: 19rpx;"><u-button @click="openSearchDialog" shape="circle" type="info" icon="search" text="筛选"></u-button></view>  
6 - <view class="device-list">  
7 - <view @click="openDeviceDetail(item.id)" class="list-item" v-for="(item, index) in list" :key="index">  
8 - <view class="u-flex item" style="justify-content: flex-start;flex-direction: column;align-items: center;">  
9 - <view style="width: 400rpx;text-align: left;">  
10 - <text style="color:#333;font-size: 15px;">{{ item.name1 }}</text>  
11 - </view>  
12 - <view style="width: 400rpx;text-align: left;">  
13 - <text style="color:#666;font-size: 15px;">{{ item.name2 }}</text>  
14 - </view>  
15 - <view style="width: 400rpx;text-align: left;">  
16 - <text style="color:#666;font-size: 15px;">{{ item.name3 }}</text>  
17 - </view>  
18 - <view style="width: 400rpx;text-align: left;">  
19 - <text style="color:#999;font-size: 15px;">{{ item.time }}</text>  
20 - </view>  
21 - </view>  
22 - <view class="item">  
23 - <view class="u-flex" style="margin-top: -6rpx;">  
24 - <image style="width: 30rpx;height: 30rpx;margin-top: 5rpx;margin-right: 5rpx;" :src="item.name4" mode=""></image>  
25 - <view>  
26 - <text style="color: #377DFF;font-size: 13px;margin-left: 5rpx;margin-top: 20rpx;">{{ item.name5 }}</text>  
27 - </view>  
28 - </view>  
29 - </view>  
30 - </view>  
31 - </view>  
32 - <view style="height: 30rpx;"></view>  
33 - <!-- 告警筛选 -->  
34 - <u-popup @close="close" closeable bgColor="transparent" :overlay="true" :show="show" mode="bottom">  
35 - <view style="height: 1100rpx;background:#fff;border-radius: 20rpx;overflow-y: scroll;">  
36 - <view style="text-align: center;position: relative;top: 68rpx;margin-top: -40rpx;"><text style="font-size: 16px;color: #333333;">筛选条件</text></view>  
37 - <view style="margin-top: 97rpx;margin-left: 43rpx;">  
38 - <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">告警状态</text></view>  
39 - <view  
40 - class="u-flex"  
41 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;  
42 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
43 - >  
44 - <view  
45 - v-for="(item, index) in alertStatus"  
46 - :key="index"  
47 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
48 - width:180rpx;height: 60rpx;  
49 - background-color:#F6F6F6;border-radius:32px"  
50 - >  
51 - <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>  
52 - </view>  
53 - </view>  
54 - </view>  
55 - <view style="margin-top: 145rpx;margin-left: 43rpx;">  
56 - <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">设备类型</text></view>  
57 - <view  
58 - class="u-flex"  
59 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;  
60 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
61 - >  
62 - <view  
63 - v-for="(item, index) in deviceType"  
64 - :key="index"  
65 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
66 - width:180rpx;height: 60rpx;  
67 - background-color:#F6F6F6;border-radius:32px"  
68 - >  
69 - <text style="color:#333;font-size: 13px;">{{ item.name }}</text>  
70 - </view>  
71 - </view>  
72 - </view>  
73 - <view style="margin-top: 136rpx;margin-left: 43rpx;">  
74 - <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333;font-size: 14px;">告警等级</text></view>  
75 - <view  
76 - class="u-flex"  
77 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;  
78 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
79 - >  
80 - <view  
81 - v-for="(item, index) in alertLevel"  
82 - :key="index"  
83 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
84 - width:180rpx;height: 60rpx;  
85 - background-color:#F6F6F6;border-radius:32px"  
86 - >  
87 - <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>  
88 - </view>  
89 - </view>  
90 - </view>  
91 - <view style="margin-top: 136rpx;margin-left: 43rpx;">  
92 - <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">选择时间</text></view>  
93 - <view  
94 - class="u-flex"  
95 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;  
96 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
97 - >  
98 - <view  
99 - v-for="(item, index) in timeArea"  
100 - :key="index"  
101 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
102 - width:180rpx;height: 60rpx;  
103 - background-color:#F6F6F6;border-radius:32px"  
104 - >  
105 - <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>  
106 - </view>  
107 - </view>  
108 - </view>  
109 - <view style="margin-top: 136rpx;margin-left: 43rpx;">  
110 - <view class="u-flex" style="margin-left: 10rpx;margin-top: 15rpx;width:750rpx;height: 60rpx;">  
111 - <u--form labelPosition="left" :model="timeData" :rules="rules" ref="form1" style="padding-left: 26rpx;width: 617rpx!important;">  
112 - <u-form-item  
113 - style="font-size: 14px;"  
114 - label="选择日期"  
115 - prop="selectTime"  
116 - labelWidth="80"  
117 - borderBottom  
118 - @click="  
119 - showCalendar = true;  
120 - hideKeyboard();  
121 - "  
122 - >  
123 - <u--input v-model="timeData.selectTime" placeholder="请选择日期" border="none"></u--input>  
124 - </u-form-item>  
125 - </u--form>  
126 - </view>  
127 - </view>  
128 - <view class="u-flex" style="margin-top: 128rpx;margin-left: 55rpx;">  
129 - <view style="width: 300rpx"><u-button type="info" shape="circle" text="重置"></u-button></view>  
130 - <view style="width: 300rpx;margin-left:46rpx ;"><u-button type="primary" shape="circle" text="确认"></u-button></view>  
131 - </view>  
132 - <view style="height: 30rpx;"></view>  
133 - </view>  
134 - </u-popup>  
135 - <u-calendar  
136 - :show="showCalendar"  
137 - mode="range"  
138 - @confirm="calendarConfirm"  
139 - @close="calendarClose"  
140 - startText="开始时间"  
141 - endText="结束时间"  
142 - confirmDisabledText="请选择日期"  
143 - :formatter="formatter"  
144 - ></u-calendar>  
145 - <f-tabbar :isFillHeight="false"></f-tabbar>  
146 - </view>  
147 -</template>  
148 -  
149 -<script>  
150 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
151 -export default {  
152 - components: {  
153 - fTabbar  
154 - },  
155 - data() {  
156 - return {  
157 - show: false,  
158 - timeData: {  
159 - selectTime: '',  
160 - getTimeGap: ''  
161 - },  
162 - showCalendar: false,  
163 - alertStatus: [  
164 - {  
165 - index: 1,  
166 - name: '全部',  
167 - bgColor: '#377DFF',  
168 - textColor: '#377DFF'  
169 - },  
170 - {  
171 - index: 2,  
172 - name: '激活未确认',  
173 - bgColor: '#F6F6F6',  
174 - textColor: '#F6F6F6'  
175 - },  
176 - {  
177 - index: 3,  
178 - name: '激活已确认',  
179 - bgColor: '#F6F6F6',  
180 - textColor: '#F6F6F6'  
181 - },  
182 - {  
183 - index: 4,  
184 - name: '清除未确认',  
185 - bgColor: '#F6F6F6',  
186 - textColor: '#F6F6F6'  
187 - },  
188 - {  
189 - index: 5,  
190 - name: '清除已确认',  
191 - bgColor: '#F6F6F6',  
192 - textColor: '#F6F6F6'  
193 - },  
194 - {  
195 - index: 6,  
196 - name: '清除已确认',  
197 - bgColor: '#F6F6F6',  
198 - textColor: '#F6F6F6'  
199 - }  
200 - ],  
201 - deviceType: [  
202 - {  
203 - index: 1,  
204 - name: '全部',  
205 - bgColor: '#377DFF',  
206 - textColor: '#377DFF'  
207 - },  
208 - {  
209 - index: 2,  
210 - name: '网关设备',  
211 - bgColor: '#F6F6F6',  
212 - textColor: '#F6F6F6'  
213 - },  
214 - {  
215 - index: 3,  
216 - name: '网关子设备',  
217 - bgColor: '#F6F6F6',  
218 - textColor: '#F6F6F6'  
219 - },  
220 - {  
221 - index: 4,  
222 - name: '直连设备',  
223 - bgColor: '#F6F6F6',  
224 - textColor: '#F6F6F6'  
225 - }  
226 - ],  
227 - alertLevel: [  
228 - {  
229 - index: 1,  
230 - name: '全部',  
231 - bgColor: '#377DFF',  
232 - textColor: '#377DFF'  
233 - },  
234 - {  
235 - index: 2,  
236 - name: '危险',  
237 - bgColor: '#F6F6F6',  
238 - textColor: '#F6F6F6'  
239 - },  
240 - {  
241 - index: 3,  
242 - name: '重要',  
243 - bgColor: '#F6F6F6',  
244 - textColor: '#F6F6F6'  
245 - },  
246 - {  
247 - index: 4,  
248 - name: '次要',  
249 - bgColor: '#F6F6F6',  
250 - textColor: '#F6F6F6'  
251 - },  
252 - {  
253 - index: 4,  
254 - name: '警告',  
255 - bgColor: '#F6F6F6',  
256 - textColor: '#F6F6F6'  
257 - },  
258 - {  
259 - index: 4,  
260 - name: '不确定',  
261 - bgColor: '#F6F6F6',  
262 - textColor: '#F6F6F6'  
263 - }  
264 - ],  
265 - timeArea: [  
266 - {  
267 - index: 1,  
268 - name: '全部',  
269 - value: '全部',  
270 - bgColor: '#F6F6F6',  
271 - textColor: '#F6F6F6'  
272 - },  
273 - {  
274 - index: 2,  
275 - name: '30分钟',  
276 - value: '30',  
277 - bgColor: '#F6F6F6',  
278 - textColor: '#F6F6F6'  
279 - },  
280 - {  
281 - index: 3,  
282 - name: '1小时',  
283 - value: '30',  
284 - bgColor: '#F6F6F6',  
285 - textColor: '#F6F6F6'  
286 - },  
287 - {  
288 - index: 4,  
289 - name: '2小时',  
290 - value: '120',  
291 - bgColor: '#F6F6F6',  
292 - textColor: '#F6F6F6'  
293 - },  
294 - {  
295 - index: 5,  
296 - name: '近一天',  
297 - value: '24',  
298 - bgColor: '#F6F6F6',  
299 - textColor: '#F6F6F6'  
300 - },  
301 - {  
302 - index: 6,  
303 - name: '',  
304 - value: '',  
305 - bgColor: '#F6F6F6',  
306 - textColor: '#F6F6F6'  
307 - }  
308 - ],  
309 - list: [  
310 - {  
311 - name1: '1号楼1楼三单元水表',  
312 - name2: 'CO₂:65.32',  
313 - name3: '告警状态:清除已确认',  
314 - name4: '../../../static/danger.png',  
315 - name5: '危险',  
316 - time: '2022-04-01 02:12:23',  
317 - id: 'xx1'  
318 - },  
319 - {  
320 - name1: '2号楼1楼三单元水表',  
321 - name2: 'PH:9.8',  
322 - name3: '告警状态:激活未确认',  
323 - name4: '../../../static/major.png',  
324 - name5: '重要',  
325 - time: '2022-04-01 02:12:23',  
326 - id: 'xx2'  
327 - },  
328 - {  
329 - name1: '3号楼1楼三单元水表',  
330 - name2: 'NH3:600',  
331 - name3: '告警状态:激活未确认',  
332 - name4: '../../../static/secondary.png',  
333 - name5: '次要',  
334 - time: '2022-04-01 02:12:23',  
335 - id: 'xx3'  
336 - },  
337 - {  
338 - name1: '4号楼1楼三单元水表',  
339 - name2: '水深:1.4',  
340 - name3: '告警状态:激活未确认',  
341 - name4: '../../../static/secondary.png',  
342 - name5: '次要',  
343 - time: '2022-04-01 02:12:23',  
344 - id: 'xx4'  
345 - },  
346 - {  
347 - name1: '5号楼1楼三单元水表',  
348 - name2: 'COD:125',  
349 - name3: '告警状态:激活未确认',  
350 - name4: '../../../static/noshue.png',  
351 - name5: '不确定',  
352 - time: '2022-04-01 02:12:23',  
353 - id: 'xx5'  
354 - }  
355 - ]  
356 - };  
357 - },  
358 - onLoad(e) {  
359 - // 隐藏原生的tabbar  
360 - uni.hideTabBar();  
361 - },  
362 - methods: {  
363 - open() {},  
364 - close() {  
365 - this.show = false;  
366 - },  
367 - openSearchDialog() {  
368 - this.show = true;  
369 - },  
370 - hideKeyboard() {  
371 - uni.hideKeyboard();  
372 - },  
373 - calendarConfirm(e) {  
374 - this.showCalendar = false;  
375 - this.timeData.selectTime = `${e[0]} / ${e[e.length - 1]}`;  
376 - },  
377 - calendarClose() {  
378 - this.showCalendar = false;  
379 - }  
380 - }  
381 -};  
382 -</script>  
383 -  
384 -<style lang="scss" scoped>  
385 -.alert-page {  
386 - margin-top: -39rpx;  
387 -}  
388 -.device-list {  
389 - display: flex;  
390 - flex-direction: column;  
391 - padding-left: 18rpx;  
392 - margin-top: -18rpx;  
393 - .list-item {  
394 - width: 713rpx;  
395 - height: 233rpx;  
396 - background-color: #fff;  
397 - margin-top: 24rpx;  
398 - display: flex;  
399 -  
400 - border-radius: 10px;  
401 - justify-content: space-between;  
402 - .item {  
403 - margin: 30rpx;  
404 - }  
405 - }  
406 -} 1 +<template>
  2 + <view class="alert-page">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module></public-module>
  5 + <view style="width: 192rpx;margin: 19rpx;"><u-button @click="openSearchDialog" shape="circle" type="info" icon="search" text="筛选"></u-button></view>
  6 + <view class="device-list">
  7 + <view @click="openDeviceDetail(item.id)" class="list-item" v-for="(item, index) in list" :key="index">
  8 + <view class="u-flex item" style="justify-content: flex-start;flex-direction: column;align-items: center;">
  9 + <view style="width: 400rpx;text-align: left;">
  10 + <text style="color:#333;font-size: 15px;">{{ item.name1 }}</text>
  11 + </view>
  12 + <view style="width: 400rpx;text-align: left;">
  13 + <text style="color:#666;font-size: 15px;">{{ item.name2 }}</text>
  14 + </view>
  15 + <view style="width: 400rpx;text-align: left;">
  16 + <text style="color:#666;font-size: 15px;">{{ item.name3 }}</text>
  17 + </view>
  18 + <view style="width: 400rpx;text-align: left;">
  19 + <text style="color:#999;font-size: 15px;">{{ item.time }}</text>
  20 + </view>
  21 + </view>
  22 + <view class="item">
  23 + <view class="u-flex" style="margin-top: -6rpx;">
  24 + <image style="width: 30rpx;height: 30rpx;margin-top: 5rpx;margin-right: 5rpx;" :src="item.name4" mode=""></image>
  25 + <view>
  26 + <text style="color: #377DFF;font-size: 13px;margin-left: 5rpx;margin-top: 20rpx;">{{ item.name5 }}</text>
  27 + </view>
  28 + </view>
  29 + </view>
  30 + </view>
  31 + </view>
  32 + <view style="height: 30rpx;"></view>
  33 + <!-- 告警筛选 -->
  34 + <u-popup @close="close" closeable bgColor="transparent" :overlay="true" :show="show" mode="bottom">
  35 + <view style="height: 1100rpx;background:#fff;border-radius: 20rpx;overflow-y: scroll;">
  36 + <view style="text-align: center;position: relative;top: 68rpx;margin-top: -40rpx;"><text style="font-size: 16px;color: #333333;">筛选条件</text></view>
  37 + <view style="margin-top: 97rpx;margin-left: 43rpx;">
  38 + <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">告警状态</text></view>
  39 + <view
  40 + class="u-flex"
  41 + style="margin-top: 15rpx;width:650rpx;height: 60rpx;
  42 + flex-wrap: wrap;justify-content: space-between; align-content: space-between;"
  43 + >
  44 + <view
  45 + v-for="(item, index) in alertStatus"
  46 + :key="index"
  47 + style="margin: 10rpx;line-height: 50rpx;text-align: center;
  48 + width:180rpx;height: 60rpx;
  49 + background-color:#F6F6F6;border-radius:32px"
  50 + >
  51 + <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>
  52 + </view>
  53 + </view>
  54 + </view>
  55 + <view style="margin-top: 145rpx;margin-left: 43rpx;">
  56 + <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">设备类型</text></view>
  57 + <view
  58 + class="u-flex"
  59 + style="margin-top: 15rpx;width:650rpx;height: 60rpx;
  60 + flex-wrap: wrap;justify-content: space-between; align-content: space-between;"
  61 + >
  62 + <view
  63 + v-for="(item, index) in deviceType"
  64 + :key="index"
  65 + style="margin: 10rpx;line-height: 50rpx;text-align: center;
  66 + width:180rpx;height: 60rpx;
  67 + background-color:#F6F6F6;border-radius:32px"
  68 + >
  69 + <text style="color:#333;font-size: 13px;">{{ item.name }}</text>
  70 + </view>
  71 + </view>
  72 + </view>
  73 + <view style="margin-top: 136rpx;margin-left: 43rpx;">
  74 + <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333;font-size: 14px;">告警等级</text></view>
  75 + <view
  76 + class="u-flex"
  77 + style="margin-top: 15rpx;width:650rpx;height: 60rpx;
  78 + flex-wrap: wrap;justify-content: space-between; align-content: space-between;"
  79 + >
  80 + <view
  81 + v-for="(item, index) in alertLevel"
  82 + :key="index"
  83 + style="margin: 10rpx;line-height: 50rpx;text-align: center;
  84 + width:180rpx;height: 60rpx;
  85 + background-color:#F6F6F6;border-radius:32px"
  86 + >
  87 + <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>
  88 + </view>
  89 + </view>
  90 + </view>
  91 + <view style="margin-top: 136rpx;margin-left: 43rpx;">
  92 + <view style="width: 750rpx;margin-left: 14rpx;"><text style="color: #333333;font-size: 14px;">选择时间</text></view>
  93 + <view
  94 + class="u-flex"
  95 + style="margin-top: 15rpx;width:650rpx;height: 60rpx;
  96 + flex-wrap: wrap;justify-content: space-between; align-content: space-between;"
  97 + >
  98 + <view
  99 + v-for="(item, index) in timeArea"
  100 + :key="index"
  101 + style="margin: 10rpx;line-height: 50rpx;text-align: center;
  102 + width:180rpx;height: 60rpx;
  103 + background-color:#F6F6F6;border-radius:32px"
  104 + >
  105 + <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>
  106 + </view>
  107 + </view>
  108 + </view>
  109 + <view style="margin-top: 136rpx;margin-left: 43rpx;">
  110 + <view class="u-flex" style="margin-left: 10rpx;margin-top: 15rpx;width:750rpx;height: 60rpx;">
  111 + <u--form labelPosition="left" :model="timeData" :rules="rules" ref="form1" style="padding-left: 26rpx;width: 617rpx!important;">
  112 + <u-form-item
  113 + style="font-size: 14px;"
  114 + label="选择日期"
  115 + prop="selectTime"
  116 + labelWidth="80"
  117 + borderBottom
  118 + @click="
  119 + showCalendar = true;
  120 + hideKeyboard();
  121 + "
  122 + >
  123 + <u--input v-model="timeData.selectTime" placeholder="请选择日期" border="none"></u--input>
  124 + </u-form-item>
  125 + </u--form>
  126 + </view>
  127 + </view>
  128 + <view class="u-flex" style="margin-top: 128rpx;margin-left: 55rpx;">
  129 + <view style="width: 300rpx"><u-button type="info" shape="circle" text="重置"></u-button></view>
  130 + <view style="width: 300rpx;margin-left:46rpx ;"><u-button type="primary" shape="circle" text="确认"></u-button></view>
  131 + </view>
  132 + <view style="height: 30rpx;"></view>
  133 + </view>
  134 + </u-popup>
  135 + <u-calendar
  136 + :show="showCalendar"
  137 + mode="range"
  138 + @confirm="calendarConfirm"
  139 + @close="calendarClose"
  140 + startText="开始时间"
  141 + endText="结束时间"
  142 + confirmDisabledText="请选择日期"
  143 + :formatter="formatter"
  144 + ></u-calendar>
  145 +
  146 + </view>
  147 +</template>
  148 +
  149 +<script>
  150 +import fTabbar from '@/components/module/f-tabbar/f-tabbar';
  151 +export default {
  152 + components: {
  153 + fTabbar
  154 + },
  155 + data() {
  156 + return {
  157 + show: false,
  158 + timeData: {
  159 + selectTime: '',
  160 + getTimeGap: ''
  161 + },
  162 + showCalendar: false,
  163 + alertStatus: [
  164 + {
  165 + index: 1,
  166 + name: '全部',
  167 + bgColor: '#377DFF',
  168 + textColor: '#377DFF'
  169 + },
  170 + {
  171 + index: 2,
  172 + name: '激活未确认',
  173 + bgColor: '#F6F6F6',
  174 + textColor: '#F6F6F6'
  175 + },
  176 + {
  177 + index: 3,
  178 + name: '激活已确认',
  179 + bgColor: '#F6F6F6',
  180 + textColor: '#F6F6F6'
  181 + },
  182 + {
  183 + index: 4,
  184 + name: '清除未确认',
  185 + bgColor: '#F6F6F6',
  186 + textColor: '#F6F6F6'
  187 + },
  188 + {
  189 + index: 5,
  190 + name: '清除已确认',
  191 + bgColor: '#F6F6F6',
  192 + textColor: '#F6F6F6'
  193 + },
  194 + {
  195 + index: 6,
  196 + name: '清除已确认',
  197 + bgColor: '#F6F6F6',
  198 + textColor: '#F6F6F6'
  199 + }
  200 + ],
  201 + deviceType: [
  202 + {
  203 + index: 1,
  204 + name: '全部',
  205 + bgColor: '#377DFF',
  206 + textColor: '#377DFF'
  207 + },
  208 + {
  209 + index: 2,
  210 + name: '网关设备',
  211 + bgColor: '#F6F6F6',
  212 + textColor: '#F6F6F6'
  213 + },
  214 + {
  215 + index: 3,
  216 + name: '网关子设备',
  217 + bgColor: '#F6F6F6',
  218 + textColor: '#F6F6F6'
  219 + },
  220 + {
  221 + index: 4,
  222 + name: '直连设备',
  223 + bgColor: '#F6F6F6',
  224 + textColor: '#F6F6F6'
  225 + }
  226 + ],
  227 + alertLevel: [
  228 + {
  229 + index: 1,
  230 + name: '全部',
  231 + bgColor: '#377DFF',
  232 + textColor: '#377DFF'
  233 + },
  234 + {
  235 + index: 2,
  236 + name: '危险',
  237 + bgColor: '#F6F6F6',
  238 + textColor: '#F6F6F6'
  239 + },
  240 + {
  241 + index: 3,
  242 + name: '重要',
  243 + bgColor: '#F6F6F6',
  244 + textColor: '#F6F6F6'
  245 + },
  246 + {
  247 + index: 4,
  248 + name: '次要',
  249 + bgColor: '#F6F6F6',
  250 + textColor: '#F6F6F6'
  251 + },
  252 + {
  253 + index: 4,
  254 + name: '警告',
  255 + bgColor: '#F6F6F6',
  256 + textColor: '#F6F6F6'
  257 + },
  258 + {
  259 + index: 4,
  260 + name: '不确定',
  261 + bgColor: '#F6F6F6',
  262 + textColor: '#F6F6F6'
  263 + }
  264 + ],
  265 + timeArea: [
  266 + {
  267 + index: 1,
  268 + name: '全部',
  269 + value: '全部',
  270 + bgColor: '#F6F6F6',
  271 + textColor: '#F6F6F6'
  272 + },
  273 + {
  274 + index: 2,
  275 + name: '30分钟',
  276 + value: '30',
  277 + bgColor: '#F6F6F6',
  278 + textColor: '#F6F6F6'
  279 + },
  280 + {
  281 + index: 3,
  282 + name: '1小时',
  283 + value: '30',
  284 + bgColor: '#F6F6F6',
  285 + textColor: '#F6F6F6'
  286 + },
  287 + {
  288 + index: 4,
  289 + name: '2小时',
  290 + value: '120',
  291 + bgColor: '#F6F6F6',
  292 + textColor: '#F6F6F6'
  293 + },
  294 + {
  295 + index: 5,
  296 + name: '近一天',
  297 + value: '24',
  298 + bgColor: '#F6F6F6',
  299 + textColor: '#F6F6F6'
  300 + },
  301 + {
  302 + index: 6,
  303 + name: '',
  304 + value: '',
  305 + bgColor: '#F6F6F6',
  306 + textColor: '#F6F6F6'
  307 + }
  308 + ],
  309 + list: [
  310 + {
  311 + name1: '1号楼1楼三单元水表',
  312 + name2: 'CO₂:65.32',
  313 + name3: '告警状态:清除已确认',
  314 + name4: '../../../static/danger.png',
  315 + name5: '危险',
  316 + time: '2022-04-01 02:12:23',
  317 + id: 'xx1'
  318 + },
  319 + {
  320 + name1: '2号楼1楼三单元水表',
  321 + name2: 'PH:9.8',
  322 + name3: '告警状态:激活未确认',
  323 + name4: '../../../static/major.png',
  324 + name5: '重要',
  325 + time: '2022-04-01 02:12:23',
  326 + id: 'xx2'
  327 + },
  328 + {
  329 + name1: '3号楼1楼三单元水表',
  330 + name2: 'NH3:600',
  331 + name3: '告警状态:激活未确认',
  332 + name4: '../../../static/secondary.png',
  333 + name5: '次要',
  334 + time: '2022-04-01 02:12:23',
  335 + id: 'xx3'
  336 + },
  337 + {
  338 + name1: '4号楼1楼三单元水表',
  339 + name2: '水深:1.4',
  340 + name3: '告警状态:激活未确认',
  341 + name4: '../../../static/secondary.png',
  342 + name5: '次要',
  343 + time: '2022-04-01 02:12:23',
  344 + id: 'xx4'
  345 + },
  346 + {
  347 + name1: '5号楼1楼三单元水表',
  348 + name2: 'COD:125',
  349 + name3: '告警状态:激活未确认',
  350 + name4: '../../../static/noshue.png',
  351 + name5: '不确定',
  352 + time: '2022-04-01 02:12:23',
  353 + id: 'xx5'
  354 + }
  355 + ]
  356 + };
  357 + },
  358 + onLoad(e) {
  359 + // 隐藏原生的tabbar
  360 + uni.hideTabBar();
  361 + },
  362 + methods: {
  363 + open() {},
  364 + close() {
  365 + this.show = false;
  366 + },
  367 + openSearchDialog() {
  368 + this.show = true;
  369 + },
  370 + hideKeyboard() {
  371 + uni.hideKeyboard();
  372 + },
  373 + calendarConfirm(e) {
  374 + this.showCalendar = false;
  375 + this.timeData.selectTime = `${e[0]} / ${e[e.length - 1]}`;
  376 + },
  377 + calendarClose() {
  378 + this.showCalendar = false;
  379 + }
  380 + }
  381 +};
  382 +</script>
  383 +
  384 +<style lang="scss" scoped>
  385 +.alert-page {
  386 + margin-top: -39rpx;
  387 +}
  388 +.device-list {
  389 + display: flex;
  390 + flex-direction: column;
  391 + padding-left: 18rpx;
  392 + margin-top: -18rpx;
  393 + .list-item {
  394 + width: 713rpx;
  395 + height: 233rpx;
  396 + background-color: #fff;
  397 + margin-top: 24rpx;
  398 + display: flex;
  399 +
  400 + border-radius: 10px;
  401 + justify-content: space-between;
  402 + .item {
  403 + margin: 30rpx;
  404 + }
  405 + }
  406 +}
407 </style> 407 </style>
1 -<template>  
2 - <view class="basic-page">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module />  
5 - <view class="u-flex" style="justify-content: space-between;height: 140rpx;background-color: #fff;border-radius: 18px;">  
6 - <view class="u-flex">  
7 - <view style="margin-left: 20rpx;">  
8 - {{deviceDetail.name}}  
9 - </view>  
10 - <view style="margin-left: 20rpx; font-size: 14px;" :style="{color:deviceDetail.deviceState==='INACTIVE'?'#666':deviceDetail.deviceState==='ONLINE'?'#377DFF':'#DE4437'}">  
11 - {{deviceDetail.deviceState==='INACTIVE'?'未激活':deviceDetail.deviceState==='ONLINE'?'在线':'离线'}}  
12 - </view>  
13 - </view>  
14 - <view style="margin-right: 20rpx;">  
15 - <u-button type="primary" shape="circle" size="mini" text="下发命令" @click="showModal"/>  
16 - </view>  
17 - </view>  
18 - <view style="margin-top: 40rpx;height: 577rpx;background-color: #fff;border-radius: 20px;">  
19 - <u-list>  
20 - <u-list-item>  
21 -  
22 - <u-cell :title="deviceDetail.sn">  
23 - <view slot="icon">设备编号</view>  
24 - </u-cell>  
25 - </u-list-item>  
26 - <u-list-item>  
27 - <u-cell :title="deviceType">  
28 - <view slot="icon">设备类型</view>  
29 - </u-cell>  
30 - </u-list-item>  
31 - <u-list-item>  
32 - <u-cell :title="deviceDetail.organizationDTO.name">  
33 - <view slot="icon">所属组织</view>  
34 - </u-cell>  
35 - </u-list-item>  
36 - <u-list-item>  
37 - <u-cell :title="formatLastOnlineTime">  
38 - <view slot="icon">最后连接时间</view>  
39 - </u-cell>  
40 - </u-list-item>  
41 - <u-list-item>  
42 - <u-cell :title="alarmStatus">  
43 - <view slot="icon">是否告警</view>  
44 - </u-cell>  
45 - </u-list-ite>  
46 - <u-cell :title="deviceDetail.description">  
47 - <view slot="icon">设备描述</view>  
48 - </u-cell>  
49 - </u-list-item>  
50 - </u-list>  
51 - </view>  
52 - <!-- 下发指令 -->  
53 - <u-modal :show="showModel" title="命令下发" closeOnClickOverlay showCancelButton @close="hiddenModal" @cancel="hiddenModal" @confirm="handleConfirm" >  
54 - <u--textarea placeholder="请输入命令内容" v-model="formModel.intro" count />  
55 - </u-modal>  
56 - <f-tabbar />  
57 - </view>  
58 -</template>  
59 -  
60 -<script>  
61 -import {formatToDate} from '@/plugins/utils.js';  
62 -export default {  
63 - props:{  
64 - deviceDetail:{  
65 - type:Object,  
66 - default:()=>({}),  
67 - }  
68 - },  
69 - data() {  
70 - return {  
71 - showModel: false,  
72 - };  
73 - },  
74 - computed:{  
75 - deviceType(){  
76 - return this.deviceDetail.deviceType==='DIRECT_CONNECTION'?'直连设备':this.deviceDetail.deviceType==='GATEWAY'?'网关设备':this.deviceDetail.deviceType==='SENSOR'?'网关子设备':''  
77 - },  
78 - alarmStatus(){  
79 - return this.deviceDetail.alarmStatus === '0'?'否':'是'  
80 - },  
81 - formatLastOnlineTime(){  
82 - return formatToDate(Number(this.deviceDetail.lastOnlineTime),'YYYY-MM-DD HH:mm:ss')  
83 - }  
84 - },  
85 - onLoad(e) {  
86 - // 隐藏原生的tabbar  
87 - uni.hideTabBar();  
88 - },  
89 - onMounted(){  
90 - console.log(this.deviceDetail)  
91 -  
92 - },  
93 - methods: {  
94 - showModal() {  
95 - this.showModel = true;  
96 - },  
97 - hiddenModal(){  
98 - this.showModel = false;  
99 - },  
100 - handleConfirm(){  
101 - console.log('确定')  
102 - }  
103 - }  
104 -};  
105 -</script> 1 +<template>
  2 + <view class="basic-page">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module />
  5 + <view class="u-flex" style="justify-content: space-between;height: 140rpx;background-color: #fff;border-radius: 18px;">
  6 + <view class="u-flex">
  7 + <view style="margin-left: 20rpx;">
  8 + {{deviceDetail.name}}
  9 + </view>
  10 + <view style="margin-left: 20rpx; font-size: 14px;" :style="{color:deviceDetail.deviceState==='INACTIVE'?'#666':deviceDetail.deviceState==='ONLINE'?'#377DFF':'#DE4437'}">
  11 + {{deviceDetail.deviceState==='INACTIVE'?'待激活':deviceDetail.deviceState==='ONLINE'?'在线':'离线'}}
  12 + </view>
  13 + </view>
  14 + <view style="margin-right: 20rpx;">
  15 + <u-button type="primary" shape="circle" size="mini" text="下发命令" @click="showModal"/>
  16 + </view>
  17 + </view>
  18 + <view style="margin-top: 40rpx;height: 577rpx;background-color: #fff;border-radius: 20px;">
  19 + <u-list>
  20 + <u-list-item>
  21 +
  22 + <u-cell :title="deviceDetail.sn">
  23 + <view slot="icon">设备编号</view>
  24 + </u-cell>
  25 + </u-list-item>
  26 + <u-list-item>
  27 + <u-cell :title="deviceType">
  28 + <view slot="icon">设备类型</view>
  29 + </u-cell>
  30 + </u-list-item>
  31 + <u-list-item>
  32 + <u-cell :title="deviceDetail.organizationDTO.name">
  33 + <view slot="icon">所属组织</view>
  34 + </u-cell>
  35 + </u-list-item>
  36 + <u-list-item>
  37 + <u-cell :title="formatLastOnlineTime">
  38 + <view slot="icon">最后连接时间</view>
  39 + </u-cell>
  40 + </u-list-item>
  41 + <u-list-item>
  42 + <u-cell :title="alarmStatus">
  43 + <view slot="icon">是否告警</view>
  44 + </u-cell>
  45 + </u-list-ite>
  46 + <u-cell :title="deviceDetail.description">
  47 + <view slot="icon">设备描述</view>
  48 + </u-cell>
  49 + </u-list-item>
  50 + </u-list>
  51 + </view>
  52 + <!-- 下发指令 -->
  53 + <u-modal :show="showModel" title="命令下发" closeOnClickOverlay showCancelButton @close="hiddenModal" @cancel="hiddenModal" @confirm="handleConfirm" >
  54 + <u--textarea placeholder="请输入命令内容" v-model="formModel.intro" count />
  55 + </u-modal>
  56 + </view>
  57 +</template>
  58 +
  59 +<script>
  60 +import {formatToDate} from '@/plugins/utils.js';
  61 +export default {
  62 + props:{
  63 + deviceDetail:{
  64 + type:Object,
  65 + default:()=>({}),
  66 + }
  67 + },
  68 + data() {
  69 + return {
  70 + showModel: false,
  71 + };
  72 + },
  73 + computed:{
  74 + deviceType(){
  75 + return this.deviceDetail.deviceType==='DIRECT_CONNECTION'?'直连设备':this.deviceDetail.deviceType==='GATEWAY'?'网关设备':this.deviceDetail.deviceType==='SENSOR'?'网关子设备':''
  76 + },
  77 + alarmStatus(){
  78 + return this.deviceDetail.alarmStatus === '0'?'否':'是'
  79 + },
  80 + formatLastOnlineTime(){
  81 + return formatToDate(Number(this.deviceDetail.lastOnlineTime),'YYYY-MM-DD HH:mm:ss')
  82 + }
  83 + },
  84 + onLoad(e) {
  85 + // 隐藏原生的tabbar
  86 + uni.hideTabBar();
  87 + },
  88 + onMounted(){
  89 + console.log(this.deviceDetail)
  90 +
  91 + },
  92 + methods: {
  93 + showModal() {
  94 + this.showModel = true;
  95 + },
  96 + hiddenModal(){
  97 + this.showModel = false;
  98 + },
  99 + handleConfirm(){
  100 + console.log('确定')
  101 + }
  102 + }
  103 +};
  104 +</script>
@@ -141,7 +141,7 @@ @@ -141,7 +141,7 @@
141 confirmDisabledText="请选择日期" 141 confirmDisabledText="请选择日期"
142 :formatter="formatter" 142 :formatter="formatter"
143 ></u-calendar> 143 ></u-calendar>
144 - <f-tabbar></f-tabbar> 144 +
145 </view> 145 </view>
146 </template> 146 </template>
147 147
1 -<template>  
2 - <view class="historyData">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module></public-module>  
5 - <view class="historyData-top">  
6 - <u-form :label-style="{ 'font-size': '0rpx' }">  
7 - <u-form-item @click="openCalendar">  
8 - <u-input v-model="timeData.selectTime" disabled disabledColor="#fff" placeholder="请选择日期" border="none">  
9 - <template slot="prefix">  
10 - <image class="icon" src="../../../static/can-der.png"></image>  
11 - </template>  
12 - </u-input>  
13 - </u-form-item>  
14 - <u-form-item @click="openTimeGap">  
15 - <u-input v-model="timeData.getTimeGap" disabled disabledColor="#fff" placeholder="请选择时间区间" border="none">  
16 - <template slot="prefix">  
17 - <image class="icon" src="../../../static/time.png"></image>  
18 - </template>  
19 - </u-input>  
20 - </u-form-item>  
21 - <u-form-item @click="openType"><u-input shape="circle" v-model="timeData.getType" placeholder="请选择属性" disabled disabledColor="#377DFF0D" /></u-form-item>  
22 - </u-form>  
23 - <!-- <qiun-data-charts type="tarea" :chartData="chartData" canvas2d /> -->  
24 - </view>  
25 - <view class="historyData-bottom">  
26 - <view class="table">  
27 - <view class="tr bg-w">  
28 - <view class="th">变量值</view>  
29 - <view class="th">更新时间</view>  
30 - </view>  
31 - <view class="tr bg-g">  
32 - <view class="td">10</view>  
33 - <view class="td">2022-03-01 18:16:33</view>  
34 - </view>  
35 -  
36 - </view>  
37 - </view>  
38 - <u-calendar  
39 - :show="showCalendar"  
40 - closeOnClickOverlay  
41 - mode="range"  
42 - startText="开始时间"  
43 - endText="结束时间"  
44 - confirmDisabledText="请选择日期"  
45 - @confirm="calendarConfirm"  
46 - @close="calendarClose"  
47 - ></u-calendar>  
48 - <u-picker :show="showTimeGap" :columns="columns" keyName="label" closeOnClickOverlay @confirm="confirmTimeGap" @cancel="cancelTimeGap" @close="cancelTimeGap"></u-picker>  
49 - <u-picker :show="showSelectType" :columns="keys" closeOnClickOverlay @confirm="confirmTypeGap" @cancel="cancelTypeGap" @close="cancelTypeGap"></u-picker>  
50 - <f-tabbar></f-tabbar>  
51 - </view>  
52 -</template>  
53 -  
54 -<script>  
55 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
56 -import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue';  
57 -import { getDeviceKeys, getHistroyData } from '../../../pages/device/api/index';  
58 -export default {  
59 - components: {  
60 - fTabbar,  
61 - qiunDataCharts  
62 - },  
63 - props:{  
64 - keys:{  
65 - type:Array,  
66 - default:()=>[]  
67 - }  
68 - },  
69 - data() {  
70 - return {  
71 - showCalendar: false,  
72 - showTimeGap: false,  
73 - showSelectType: false,  
74 - columns: [  
75 - [  
76 - {  
77 - label: '5分钟',  
78 - value: 300  
79 - },  
80 - {  
81 - label: '10分钟',  
82 - value: 600  
83 - },  
84 - {  
85 - label: '15分钟',  
86 - value: 900  
87 - },  
88 - {  
89 - label: '30分钟',  
90 - value: 1800  
91 - },  
92 - {  
93 - label: '1小时',  
94 - value: 3600  
95 - },  
96 - {  
97 - label: '2小时',  
98 - value: 7200  
99 - },  
100 - {  
101 - label: '6小时',  
102 - value: 21600  
103 - }  
104 - ]  
105 - ],  
106 - timeData: {  
107 - selectTime: '',  
108 - getTimeGap: '',  
109 - getType: ''  
110 - }  
111 - };  
112 - },  
113 - methods: {  
114 - openCalendar() {  
115 - this.showCalendar = true;  
116 - },  
117 - openTimeGap() {  
118 - this.showTimeGap = true;  
119 - },  
120 - openType() {  
121 - this.showSelectType = true;  
122 - },  
123 - calendarConfirm(date) {  
124 - this.showCalendar = false;  
125 - this.timeData.selectTime = `${date[0]} 至 ${date[1]}`;  
126 - },  
127 - calendarClose() {  
128 - this.showCalendar = false;  
129 - },  
130 - confirmTimeGap(time) {  
131 - this.showTimeGap = false;  
132 - this.timeData.getTimeGap = time.value[0].label;  
133 - },  
134 -  
135 - cancelTimeGap() {  
136 - this.showTimeGap = false;  
137 - },  
138 - confirmTypeGap(time) {  
139 - this.showSelectType = false;  
140 - this.timeData.getType = time.value[0];  
141 - },  
142 - cancelTypeGap() {  
143 - this.showSelectType = false;  
144 - }  
145 - }  
146 -};  
147 -</script>  
148 -  
149 -<style lang="scss" scoped>  
150 -.historyData {  
151 - margin: 30rpx;  
152 - .historyData-top {  
153 - padding: 30rpx;  
154 - background-color: #fff;  
155 - height: 870rpx;  
156 - border-radius: 20rpx;  
157 - .icon {  
158 - width: 28rpx;  
159 - height: 28rpx;  
160 - margin-right: 15rpx;  
161 - }  
162 - }  
163 - .historyData-bottom {  
164 - margin-top: 30rpx;  
165 - background-color: #fff;  
166 - border-radius: 20rpx;  
167 - .table {  
168 - border: 0px solid darkgray;  
169 - .tr {  
170 - display: flex;  
171 - width: 100%;  
172 - justify-content: center;  
173 - height: 3rem;  
174 - align-items: center;  
175 - .th {  
176 - display: flex;  
177 - justify-content: center;  
178 - align-items: center;  
179 - width: 50%;  
180 - color: #333;  
181 - font-weight: 500;  
182 - }  
183 - .td {  
184 - color: #999;  
185 - width: 50%;  
186 - display: flex;  
187 - justify-content: center;  
188 - text-align: center;  
189 - }  
190 - }  
191 - }  
192 - }  
193 -}  
194 -.odd {  
195 - background-color: #f9fcff;  
196 -} 1 +<template>
  2 + <view class="historyData">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module></public-module>
  5 + <view class="historyData-top">
  6 + <u-form :label-style="{ 'font-size': '0rpx' }">
  7 + <u-form-item @click="openCalendar">
  8 + <u-input v-model="timeData.selectTime" disabled disabledColor="#fff" placeholder="请选择日期" border="none">
  9 + <template slot="prefix">
  10 + <image class="icon" src="../../../static/can-der.png"></image>
  11 + </template>
  12 + </u-input>
  13 + </u-form-item>
  14 + <u-form-item @click="openTimeGap">
  15 + <u-input v-model="timeData.getTimeGap" disabled disabledColor="#fff" placeholder="请选择时间区间" border="none">
  16 + <template slot="prefix">
  17 + <image class="icon" src="../../../static/time.png"></image>
  18 + </template>
  19 + </u-input>
  20 + </u-form-item>
  21 + <u-form-item @click="openType"><u-input shape="circle" v-model="timeData.getType" placeholder="请选择属性" disabled disabledColor="#377DFF0D" /></u-form-item>
  22 + </u-form>
  23 + <view class="charts-box"><qiun-data-charts type="area" :chartData="chartData" :opts="{ xAxis: { disabled: true }, legend: { show: false } }" /></view>
  24 + </view>
  25 + <view class="historyData-bottom">
  26 + <view class="table">
  27 + <view class="tr bg-w">
  28 + <view class="th">变量值</view>
  29 + <view class="th">更新时间</view>
  30 + </view>
  31 + <view class="tr bg-g" v-for="(item, index) in historyData" :key="index">
  32 + <view class="td">{{ item.value }}</view>
  33 + <view class="td">{{ item.ts }}</view>
  34 + </view>
  35 + </view>
  36 + </view>
  37 + <u-calendar
  38 + :show="showCalendar"
  39 + :defaultDate="defaultDate"
  40 + closeOnClickOverlay
  41 + mode="range"
  42 + startText="开始时间"
  43 + endText="结束时间"
  44 + confirmDisabledText="请选择日期"
  45 + :minDate="minDate"
  46 + :maxDate="maxDate"
  47 + @confirm="calendarConfirm"
  48 + @close="calendarClose"
  49 + ></u-calendar>
  50 + <u-picker
  51 + :show="showTimeGap"
  52 + :columns="columns"
  53 + keyName="label"
  54 + closeOnClickOverlay
  55 + @confirm="confirmTimeGap"
  56 + @cancel="cancelTimeGap"
  57 + @close="cancelTimeGap"
  58 + :defaultIndex="[3]"
  59 + ></u-picker>
  60 + <u-picker :show="showSelectType" :columns="keys" closeOnClickOverlay @confirm="confirmTypeGap" @cancel="cancelTypeGap" @close="cancelTypeGap"></u-picker>
  61 + </view>
  62 +</template>
  63 +
  64 +<script>
  65 +import fTabbar from '@/components/module/f-tabbar/f-tabbar';
  66 +import qiunDataCharts from '@/uni_modules/qiun-data-charts/components/qiun-data-charts/qiun-data-charts.vue';
  67 +import { getHistroyData } from '@/pages/device/api/index.js';
  68 +import { formatToDate } from '@/plugins/utils.js';
  69 +const d = new Date();
  70 +const year = d.getFullYear();
  71 +let month = d.getMonth() + 1;
  72 +month = month < 10 ? `0${month}` : month;
  73 +const date = d.getDate();
  74 +export default {
  75 + components: {
  76 + fTabbar,
  77 + qiunDataCharts
  78 + },
  79 + props: {
  80 + keys: {
  81 + type: Array,
  82 + default: () => []
  83 + },
  84 + yesterday: {
  85 + type: String,
  86 + default: ''
  87 + },
  88 + today: {
  89 + type: String,
  90 + default: ''
  91 + },
  92 + timeDiff: {
  93 + type: String,
  94 + default: ''
  95 + },
  96 + historyData: {
  97 + type: Array,
  98 + default: () => []
  99 + },
  100 + entityId: {
  101 + type: String,
  102 + required: true
  103 + }
  104 + },
  105 + data() {
  106 + return {
  107 + startTs: '',
  108 + endTs: '',
  109 + showCalendar: false,
  110 + showTimeGap: false,
  111 + showSelectType: false,
  112 + minDate: `${year}-${month - 1}-${date}`,
  113 + maxDate: `${year}-${month}-${date + 1}`,
  114 + defaultDate: [this.yesterday, this.today],
  115 + chartData: {
  116 + categories: this.historyData.map(item => item.ts),
  117 + series: [
  118 + {
  119 + name: this.keys[0][0],
  120 + data: this.historyData.map(item => Number(item.value))
  121 + }
  122 + ]
  123 + },
  124 + columns: [
  125 + [
  126 + {
  127 + label: '5分钟',
  128 + value: 300000
  129 + },
  130 + {
  131 + label: '10分钟',
  132 + value: 600000
  133 + },
  134 + {
  135 + label: '15分钟',
  136 + value: 900000
  137 + },
  138 + {
  139 + label: '30分钟',
  140 + value: 1800000
  141 + },
  142 + {
  143 + label: '1小时',
  144 + value: 3600000
  145 + },
  146 + {
  147 + label: '2小时',
  148 + value: 7200000
  149 + }
  150 + ]
  151 + ],
  152 + timeData: {
  153 + selectTime: this.yesterday + ' 至 ' + this.today,
  154 + getTimeGap: this.timeDiff,
  155 + getType: this.keys[0][0]
  156 + }
  157 + };
  158 + },
  159 + onReady() {
  160 + setTimeout(() => {
  161 + console.log(this.chartData);
  162 + });
  163 + },
  164 + methods: {
  165 + // 动态生成Columns
  166 + generateColumns(value) {
  167 + if (value < 604800000) {
  168 + // 小于7天
  169 + return [
  170 + [
  171 + {
  172 + label: '5分钟',
  173 + value: 300000
  174 + },
  175 + {
  176 + label: '10分钟',
  177 + value: 600000
  178 + },
  179 + {
  180 + label: '15分钟',
  181 + value: 900000
  182 + },
  183 + {
  184 + label: '30分钟',
  185 + value: 1800000
  186 + },
  187 + {
  188 + label: '1小时',
  189 + value: 3600000
  190 + },
  191 + {
  192 + label: '2小时',
  193 + value: 7200000
  194 + }
  195 + ]
  196 + ];
  197 + } else if (value < 2592000000) {
  198 + // 小于30天
  199 + return [
  200 + [
  201 + {
  202 + label: '30分钟',
  203 + value: 1800000
  204 + },
  205 + {
  206 + label: '1小时',
  207 + value: 3600000
  208 + },
  209 + {
  210 + label: '2小时',
  211 + value: 7200000
  212 + },
  213 + {
  214 + label: '5小时',
  215 + value: 18000000
  216 + },
  217 + {
  218 + label: '10小时',
  219 + value: 36000000
  220 + },
  221 + {
  222 + label: '12小时',
  223 + value: 43200000
  224 + },
  225 + {
  226 + label: '1天',
  227 + value: 86400000
  228 + }
  229 + ]
  230 + ];
  231 + } else if (value >= 2592000000) {
  232 + // 大于30天
  233 + return [
  234 + [
  235 + {
  236 + label: '2小时',
  237 + value: 7200000
  238 + },
  239 + {
  240 + label: '5小时',
  241 + value: 18000000
  242 + },
  243 + {
  244 + label: '10小时',
  245 + value: 36000000
  246 + },
  247 + {
  248 + label: '12小时',
  249 + value: 43200000
  250 + },
  251 + {
  252 + label: '1天',
  253 + value: 86400000
  254 + }
  255 + ]
  256 + ];
  257 + }
  258 + },
  259 + openCalendar() {
  260 + this.showCalendar = true;
  261 + },
  262 + openTimeGap() {
  263 + this.showTimeGap = true;
  264 + },
  265 + openType() {
  266 + this.showSelectType = true;
  267 + },
  268 + calendarConfirm(date) {
  269 + this.showCalendar = false;
  270 + this.timeData.selectTime = `${date[0]} 至 ${date[date.length - 1]}`;
  271 + // 选择的日期时间差(时间戳)
  272 + const timeDiff = formatToDate(date[date.length - 1], 'x') - formatToDate(date[0], 'x');
  273 + const genColumns = this.generateColumns(timeDiff);
  274 + this.columns = genColumns;
  275 + this.timeData.getTimeGap = '';
  276 + this.timeData.getType = '';
  277 + this.startTs = formatToDate(date[0], 'x');
  278 + this.endTs = formatToDate(date[date.length - 1], 'x');
  279 + },
  280 + calendarClose() {
  281 + this.showCalendar = false;
  282 + },
  283 + confirmTimeGap(time) {
  284 + this.showTimeGap = false;
  285 + this.timeData.getTimeGap = time.value[0].label;
  286 + this.timeData.getType = '';
  287 + },
  288 +
  289 + cancelTimeGap() {
  290 + this.showTimeGap = false;
  291 + },
  292 + async confirmTypeGap(time) {
  293 + this.showSelectType = false;
  294 + this.timeData.getType = time.value[0];
  295 + const interval = this.columns[0].find(item => item.label === this.timeData.getTimeGap);
  296 + const data = await getHistroyData({
  297 + startTs: this.startTs,
  298 + endTs: this.endTs,
  299 + keys: this.timeData.getType,
  300 + interval: interval.value,
  301 + entityId: this.entityId
  302 + });
  303 + this.$emit('update', data[this.timeData.getType]);
  304 + },
  305 + cancelTypeGap() {
  306 + this.showSelectType = false;
  307 + }
  308 + }
  309 +};
  310 +</script>
  311 +
  312 +<style lang="scss" scoped>
  313 +.charts-box {
  314 + width: 100%;
  315 + height: 550rpx;
  316 +}
  317 +.historyData {
  318 + margin: 30rpx;
  319 + .historyData-top {
  320 + padding: 30rpx;
  321 + background-color: #fff;
  322 + height: 870rpx;
  323 + border-radius: 20rpx;
  324 + .icon {
  325 + width: 28rpx;
  326 + height: 28rpx;
  327 + margin-right: 15rpx;
  328 + }
  329 + }
  330 + .historyData-bottom {
  331 + margin-top: 30rpx;
  332 + background-color: #fff;
  333 + border-radius: 20rpx;
  334 + .table {
  335 + border: 0px solid darkgray;
  336 + .tr {
  337 + display: flex;
  338 + width: 100%;
  339 + justify-content: center;
  340 + height: 3rem;
  341 + align-items: center;
  342 + .th {
  343 + display: flex;
  344 + justify-content: center;
  345 + align-items: center;
  346 + width: 50%;
  347 + color: #333;
  348 + font-weight: 500;
  349 + }
  350 + .td {
  351 + color: #999;
  352 + width: 50%;
  353 + display: flex;
  354 + justify-content: center;
  355 + text-align: center;
  356 + }
  357 + }
  358 + }
  359 + }
  360 +}
  361 +.odd {
  362 + background-color: #f9fcff;
  363 +}
197 </style> 364 </style>
@@ -23,7 +23,6 @@ @@ -23,7 +23,6 @@
23 </view> 23 </view>
24 </view> 24 </view>
25 </view> 25 </view>
26 - <f-tabbar></f-tabbar>  
27 </view> 26 </view>
28 </template> 27 </template>
29 28
1 -// 获取某个Key的历史数据  
2 -export function getHistroyData(params) {  
3 - return uni.$u.http.get({  
4 - url: `/plugins/telemetry/DEVICE/${params.entityId}/values/timeseries`,  
5 - params: {  
6 - ...params,  
7 - entityId: null,  
8 - orderBy: 'ASC'  
9 - }  
10 - });  
11 -}  
12 -  
13 -// 获取当前设备的key  
14 -export function getDeviceKeys(id) {  
15 - return uni.$u.http.get(`/plugins/telemetry/DEVICE/${id}/keys/timeseries`); 1 +// 获取某个Key的历史数据
  2 +export function getHistroyData(params) {
  3 + const {entityId,keys,startTs,endTs} = params
  4 + return uni.$u.http.get(
  5 + `/plugins/telemetry/DEVICE/${params.entityId}/values/timeseries?keys=${params.keys}&startTs=${params.startTs}&endTs=${params.endTs}`);
  6 +}
  7 +
  8 +// 获取当前设备的key
  9 +export function getDeviceKeys(id) {
  10 + return uni.$u.http.get(`/plugins/telemetry/DEVICE/${id}/keys/timeseries`);
16 }; 11 };
1 <template> 1 <template>
2 - <view class="device-page">  
3 - <f-navbar>  
4 - <view class="u-flex" slot="left" style="justify-content: space-between;">  
5 - <view style="width: 580rpx;"><u--input prefixIcon="search" placeholder="输入设备SN或名称搜索" border="surround" shape="circle" @change="inputChanged"></u--input></view>  
6 - <view style="margin-left: 7rpx;">  
7 - <view><text style="color:#333;font-size: 14px;">筛选</text></view>  
8 - </view>  
9 - <view style="margin-left: 7rpx;"><image @click="openSearchDialog" style="width: 40rpx;height: 40rpx;" src="../../static/shaixuan.png" /></view>  
10 - </view>  
11 - </f-navbar>  
12 - <!-- 公共组件-每个页面必须引入 -->  
13 - <public-module></public-module>  
14 - <view class="org-sty" @click="openOrg">  
15 - <view class="org-item">  
16 - <view class="u-flex" style="margin-top: 26rpx;margin-left: 15rpx;"><text style="color:#333;font-size: 15px;margin-left: 14rpx;">组织关系</text></view>  
17 - <view style="margin-top: 20rpx;margin-left: 15rpx;" class="u-flex" v-if="total">  
18 - <image style="margin-left: 14rpx;width: 30rpx;height: 30rpx;" src="../../static/org.png" />  
19 - <text style="margin-left: 10rpx;color:#666;font-size: 12px;">设备数 : {{ total }}</text>  
20 - </view>  
21 - </view>  
22 - <view class="org-item">  
23 - <image style="width: 6px;height: 10px;float: right; margin-right: 34rpx; margin-top: 58rpx;" src="../../static/right-arrow.png" />  
24 - </view>  
25 - </view>  
26 - <mescroll-body ref="mescrollRef" @init="mescrollInit" :down="downOption" @down="downCallback" @up="upCallback" >  
27 - <view class="device-list">  
28 - <view @click="openDeviceDetail(item.id, item.alarmStatus, item.lastOnlineTime,item.tbDeviceId)" class="list-item" v-for="item in list" :key="item.id">  
29 - <view class="u-flex item" style="justify-content: flex-start;flex-direction: column;align-items: center;">  
30 - <view style="width: 450rpx;text-align: left;">  
31 - <text style="color:#333;font-size: 15px;">{{ item.name ? `设备名称:${item.name}` : '' }}</text>  
32 - </view>  
33 - <view style="width: 450rpx;text-align: left; margin-top: 10rpx;">  
34 - <text style="color:#666;font-size: 15px;">{{ item.sn ? `设备编号:${item.sn}` : '' }}</text>  
35 - </view>  
36 - <view style="width: 450rpx;text-align: left; margin-top: 10rpx;">  
37 - <text style="color:#666;font-size: 15px;">{{ item.organizationDTO.name ? `所属组织:${item.organizationDTO.name}` : '' }}</text>  
38 - </view>  
39 - </view>  
40 - <view class="item">  
41 - <view class="u-flex" style="margin-top: -6rpx;">  
42 - <image  
43 - style="width: 30rpx;height: 30rpx;margin-top: 5rpx;margin-right: 5rpx;"  
44 - :src="item.deviceState === 'ONLINE' ? '../../static/online.png' : item.deviceState === 'INACTIVE' ? '../../static/secondary.png' : '../../static/baojing.png'"  
45 - /> 2 + <view class="device-page">
  3 + <f-navbar>
  4 + <view slot="left">
  5 + <view style="width: 580rpx"
  6 + ><u--input
  7 + prefixIcon="search"
  8 + placeholder="输入设备SN或名称搜索"
  9 + border="surround"
  10 + shape="circle"
  11 + @change="inputChanged"
  12 + ></u--input
  13 + ></view>
  14 + </view>
  15 + <view @click="openSearchDialog" slot="right" class="u-flex">
  16 + <text style="color: #333; font-size: 14px">筛选</text>
  17 + <image
  18 + style="width: 40rpx; height: 40rpx"
  19 + src="../../static/shaixuan.png"
  20 + />
  21 + </view>
  22 + </f-navbar>
  23 + <!-- 公共组件-每个页面必须引入 -->
  24 + <public-module></public-module>
  25 + <view class="org-sty" @click="openOrg">
  26 + <view class="org-item">
  27 + <view class="u-flex" style="margin-top: 26rpx; margin-left: 15rpx"
  28 + ><text style="color: #333; font-size: 15px; margin-left: 14rpx"
  29 + >组织关系</text
  30 + ></view
  31 + >
  32 + <view
  33 + style="margin-top: 20rpx; margin-left: 15rpx"
  34 + class="u-flex"
  35 + v-if="total"
  36 + >
  37 + <image
  38 + style="margin-left: 14rpx; width: 30rpx; height: 30rpx"
  39 + src="../../static/org.png"
  40 + />
  41 + <text style="margin-left: 10rpx; color: #666; font-size: 12px"
  42 + >设备数 : {{ total }}</text
  43 + >
  44 + </view>
  45 + </view>
  46 + <view class="org-item">
  47 + <image
  48 + style="
  49 + width: 6px;
  50 + height: 10px;
  51 + float: right;
  52 + margin-right: 34rpx;
  53 + margin-top: 58rpx;
  54 + "
  55 + src="../../static/right-arrow.png"
  56 + />
  57 + </view>
  58 + </view>
  59 + <mescroll-body
  60 + ref="mescrollRef"
  61 + @init="mescrollInit"
  62 + :down="downOption"
  63 + @down="downCallback"
  64 + @up="upCallback"
  65 + >
  66 + <view class="device-list">
  67 + <view
  68 + @click="
  69 + openDeviceDetail(
  70 + item.id,
  71 + item.alarmStatus,
  72 + item.lastOnlineTime,
  73 + item.tbDeviceId
  74 + )
  75 + "
  76 + class="list-item"
  77 + v-for="item in list"
  78 + :key="item.id"
  79 + >
  80 + <view
  81 + class="u-flex item"
  82 + style="
  83 + justify-content: flex-start;
  84 + flex-direction: column;
  85 + align-items: center;
  86 + "
  87 + >
  88 + <view style="width: 450rpx; text-align: left">
  89 + <text style="color: #333; font-size: 15px">{{
  90 + item.name ? `设备名称:${item.name}` : ""
  91 + }}</text>
  92 + </view>
  93 + <view style="width: 450rpx; text-align: left; margin-top: 10rpx">
  94 + <text style="color: #666; font-size: 15px">{{
  95 + item.sn ? `设备编号:${item.sn}` : ""
  96 + }}</text>
  97 + </view>
  98 + <view style="width: 450rpx; text-align: left; margin-top: 10rpx">
  99 + <text style="color: #666; font-size: 15px">{{
  100 + item.organizationDTO.name
  101 + ? `所属组织:${item.organizationDTO.name}`
  102 + : ""
  103 + }}</text>
  104 + </view>
  105 + </view>
  106 + <view class="item">
  107 + <view class="u-flex" style="margin-top: -6rpx">
  108 + <image
  109 + style="
  110 + width: 30rpx;
  111 + height: 30rpx;
  112 + margin-top: 5rpx;
  113 + margin-right: 5rpx;
  114 + "
  115 + :src="
  116 + item.deviceState === 'ONLINE'
  117 + ? '../../static/online.png'
  118 + : item.deviceState === 'INACTIVE'
  119 + ? '../../static/secondary.png'
  120 + : '../../static/baojing.png'
  121 + "
  122 + />
46 123
47 - <view>  
48 - <text style="color: #377DFF;font-size: 13px;margin-left: 5rpx;margin-top: 20rpx;">  
49 - {{ item.deviceState === 'ONLINE' ? '在线' : item.deviceState === 'INACTIVE' ? '待激活' : '离线' }}  
50 - </text>  
51 - </view>  
52 - </view>  
53 - </view>  
54 - </view>  
55 - </view>  
56 - </mescroll-body>  
57 - <!-- 设备筛选 -->  
58 - <u-popup @close="close" closeable bgColor="#fff" :show="show" mode="bottom" :round="20">  
59 - <view>  
60 - <view style="text-align: center;margin-top: 28rpx;"><text>筛选条件</text></view> 124 + <view>
  125 + <text
  126 + style="
  127 + color: #377dff;
  128 + font-size: 13px;
  129 + margin-left: 5rpx;
  130 + margin-top: 20rpx;
  131 + "
  132 + >
  133 + {{
  134 + item.deviceState === "ONLINE"
  135 + ? "在线"
  136 + : item.deviceState === "INACTIVE"
  137 + ? "待激活"
  138 + : "离线"
  139 + }}
  140 + </text>
  141 + </view>
  142 + </view>
  143 + </view>
  144 + </view>
  145 + </view>
  146 + </mescroll-body>
  147 + <!-- 设备筛选 -->
  148 + <u-popup
  149 + @close="close"
  150 + closeable
  151 + bgColor="#fff"
  152 + :show="show"
  153 + mode="bottom"
  154 + :round="20"
  155 + >
  156 + <view>
  157 + <view style="text-align: center; margin-top: 28rpx"
  158 + ><text>筛选条件</text></view
  159 + >
61 160
62 - <FilterItem :filterList="deviceStatus" title="设备状态" @clickTag="currentIndex => handleClickTag(currentIndex, deviceStatus)"></FilterItem>  
63 - <FilterItem :filterList="alarmStatus" title="告警状态" @clickTag="currentIndex => handleClickTag(currentIndex, alarmStatus)"></FilterItem>  
64 - <FilterItem :filterList="typeStatus" title="设备类型" @clickTag="currentIndex => handleClickTag(currentIndex, typeStatus)"></FilterItem>  
65 - <view class="u-flex" style="margin-top:40rpx;margin-left: 55rpx;">  
66 - <view style="width: 300rpx"><u-button type="info" shape="circle" text="重置" @click="resetFilter"></u-button></view>  
67 - <view style="width: 300rpx;margin-left:46rpx;"><u-button type="primary" shape="circle" text="确认" @click="confirmFilter"></u-button></view>  
68 - </view>  
69 - </view>  
70 - </u-popup>  
71 - <f-tabbar></f-tabbar>  
72 - </view> 161 + <FilterItem
  162 + :filterList="deviceStatus"
  163 + title="设备状态"
  164 + @clickTag="
  165 + (currentIndex) => handleClickTag(currentIndex, deviceStatus)
  166 + "
  167 + ></FilterItem>
  168 + <FilterItem
  169 + :filterList="alarmStatus"
  170 + title="告警状态"
  171 + @clickTag="
  172 + (currentIndex) => handleClickTag(currentIndex, alarmStatus)
  173 + "
  174 + ></FilterItem>
  175 + <FilterItem
  176 + :filterList="typeStatus"
  177 + title="设备类型"
  178 + @clickTag="(currentIndex) => handleClickTag(currentIndex, typeStatus)"
  179 + ></FilterItem>
  180 + <view class="u-flex" style="margin-top: 40rpx; margin-left: 55rpx">
  181 + <view style="width: 300rpx"
  182 + ><u-button
  183 + type="info"
  184 + shape="circle"
  185 + text="重置"
  186 + @click="resetFilter"
  187 + ></u-button
  188 + ></view>
  189 + <view style="width: 300rpx; margin-left: 46rpx"
  190 + ><u-button
  191 + type="primary"
  192 + shape="circle"
  193 + text="确认"
  194 + @click="confirmFilter"
  195 + ></u-button
  196 + ></view>
  197 + </view>
  198 + </view>
  199 + </u-popup>
  200 + <f-tabbar></f-tabbar>
  201 + </view>
73 </template> 202 </template>
74 203
75 <script> 204 <script>
76 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
77 -import fNavbar from '@/components/module/f-navbar/f-navbar';  
78 -import FilterItem from './FilterItem.vue';  
79 -import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';  
80 -import { debounce } from '@/plugins/throttle.js'; 205 +import fTabbar from "@/components/module/f-tabbar/f-tabbar";
  206 +import fNavbar from "@/components/module/f-navbar/f-navbar";
  207 +import FilterItem from "./FilterItem.vue";
  208 +import MescrollMixin from "@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js";
  209 +import { debounce } from "@/plugins/throttle.js";
81 export default { 210 export default {
82 - mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件)  
83 - components: {  
84 - fTabbar,  
85 - fNavbar,  
86 - FilterItem  
87 - },  
88 - data() {  
89 - return {  
90 - downOption: {  
91 - auto: false //是否在初始化后,自动执行downCallback; 默认true  
92 - },  
93 - show: false,  
94 - deviceStatus: [  
95 - {  
96 - checked: true,  
97 - name: '全部',  
98 - type: ''  
99 - },  
100 - {  
101 - checked: false,  
102 - name: '在线',  
103 - type: 'ONLINE'  
104 - },  
105 - {  
106 - checked: false,  
107 - name: '离线',  
108 - type: 'OFFLINE'  
109 - },  
110 - {  
111 - checked: false,  
112 - name: '待激活',  
113 - type: 'INACTIVE'  
114 - }  
115 - ],  
116 - alarmStatus: [  
117 - {  
118 - checked: true,  
119 - name: '全部',  
120 - type: ''  
121 - },  
122 - {  
123 - checked: false,  
124 - name: '告警',  
125 - type: '1'  
126 - },  
127 - {  
128 - checked: false,  
129 - name: '正常',  
130 - type: '0'  
131 - }  
132 - ],  
133 - typeStatus: [  
134 - {  
135 - checked: true,  
136 - name: '全部',  
137 - type: ''  
138 - },  
139 - {  
140 - checked: false,  
141 - name: '直连设备',  
142 - type: 'DIRECT_CONNECTION'  
143 - },  
144 - {  
145 - checked: false,  
146 - name: '网关设备',  
147 - type: 'GATEWAY'  
148 - },  
149 - {  
150 - checked: false,  
151 - name: '网关子设备',  
152 - type: 'SENSOR'  
153 - }  
154 - ],  
155 - total: 0,  
156 - list: []  
157 - };  
158 - },  
159 - onLoad() {  
160 - // 隐藏原生的tabbar  
161 - uni.hideTabBar();  
162 - },  
163 - onShow(){  
164 - if(this.orgId){  
165 - this.loadData(1,{  
166 - organizationId:this.orgId  
167 - })  
168 - }  
169 - },  
170 - methods: {  
171 - /*下拉刷新的回调 */  
172 - downCallback() {  
173 - //联网加载数据  
174 - this.loadData(1);  
175 - },  
176 - /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */  
177 - upCallback(page) {  
178 - //联网加载数据  
179 - console.log(page);  
180 - this.loadData(page.num);  
181 - }, 211 + mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件)
  212 + components: {
  213 + fTabbar,
  214 + fNavbar,
  215 + FilterItem,
  216 + },
  217 + data() {
  218 + return {
  219 + downOption: {
  220 + auto: false, //是否在初始化后,自动执行downCallback; 默认true
  221 + },
  222 + show: false,
  223 + deviceStatus: [
  224 + {
  225 + checked: true,
  226 + name: "全部",
  227 + type: "",
  228 + },
  229 + {
  230 + checked: false,
  231 + name: "在线",
  232 + type: "ONLINE",
  233 + },
  234 + {
  235 + checked: false,
  236 + name: "离线",
  237 + type: "OFFLINE",
  238 + },
  239 + {
  240 + checked: false,
  241 + name: "待激活",
  242 + type: "INACTIVE",
  243 + },
  244 + ],
  245 + alarmStatus: [
  246 + {
  247 + checked: true,
  248 + name: "全部",
  249 + type: "",
  250 + },
  251 + {
  252 + checked: false,
  253 + name: "告警",
  254 + type: "1",
  255 + },
  256 + {
  257 + checked: false,
  258 + name: "正常",
  259 + type: "0",
  260 + },
  261 + ],
  262 + typeStatus: [
  263 + {
  264 + checked: true,
  265 + name: "全部",
  266 + type: "",
  267 + },
  268 + {
  269 + checked: false,
  270 + name: "直连设备",
  271 + type: "DIRECT_CONNECTION",
  272 + },
  273 + {
  274 + checked: false,
  275 + name: "网关设备",
  276 + type: "GATEWAY",
  277 + },
  278 + {
  279 + checked: false,
  280 + name: "网关子设备",
  281 + type: "SENSOR",
  282 + },
  283 + ],
  284 + total: 0,
  285 + list: [],
  286 + };
  287 + },
  288 + onLoad() {
  289 + // 隐藏原生的tabbar
  290 + uni.hideTabBar();
  291 + },
  292 + onShow() {
  293 + if (this.orgId) {
  294 + this.loadData(1, {
  295 + organizationId: this.orgId,
  296 + });
  297 + }
  298 + },
  299 + methods: {
  300 + /*下拉刷新的回调 */
  301 + downCallback() {
  302 + //联网加载数据
  303 + this.loadData(1);
  304 + },
  305 + /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
  306 + upCallback(page) {
  307 + //联网加载数据
  308 + console.log(page);
  309 + this.loadData(page.num);
  310 + },
182 311
183 - //获取设备  
184 - loadData(pageNo, params = {}) {  
185 - let httpData = {  
186 - page: pageNo,  
187 - pageSize: 10,  
188 - ...params  
189 - };  
190 - uni.$u.http  
191 - .get('/yt/device', {  
192 - params: httpData,  
193 - custom: {  
194 - load: false  
195 - }  
196 - })  
197 - .then(res => {  
198 - this.total = res.total;  
199 - uni.stopPullDownRefresh();  
200 - console.log('获取后端数据', res);  
201 - //方法一(推荐): 后台接口有返回列表的总页数 totalPage  
202 - this.mescroll.endByPage(res.total, Math.ceil(res.total / 10)); //必传参数(当前页的数据个数, 总页数)  
203 - if (pageNo == 1) {  
204 - this.list = res.items;  
205 - } else {  
206 - this.list = this.list.concat(res.items);  
207 - }  
208 - })  
209 - .catch(() => {  
210 - //联网失败, 结束加载  
211 - this.mescroll.endErr();  
212 - });  
213 - },  
214 - openOrg() {  
215 - uni.navigateTo({  
216 - url: './org/org'  
217 - });  
218 - },  
219 - close() {  
220 - this.resetFilter();  
221 - this.show = false;  
222 - },  
223 - openSearchDialog() {  
224 - this.show = true;  
225 - },  
226 - openDeviceDetail(id, alarmStatus, lastOnlineTime,tbDeviceId) {  
227 - uni.navigateTo({  
228 - url: `/deviceSubPage/deviceDetailPage/deviceDetail?id=${id}&alarmStatus=${alarmStatus}&lastOnlineTime=${lastOnlineTime}&tbDeviceId=${tbDeviceId}`  
229 - });  
230 - },  
231 - handleClickTag(currentIndex, list) {  
232 - list.map((item, index) => {  
233 - item.checked = index === currentIndex;  
234 - });  
235 - },  
236 - resetFilter() {  
237 - const { deviceStatus, alarmStatus, typeStatus } = this;  
238 - [deviceStatus, alarmStatus, typeStatus].forEach(item => item.map((item, index) => (item.checked = index === 0)));  
239 - },  
240 - confirmFilter() {  
241 - const deviceState = this.deviceStatus.find(item => item.checked);  
242 - const alarmStatus = this.alarmStatus.find(item => item.checked);  
243 - const deviceType = this.typeStatus.find(item => item.checked);  
244 - this.loadData(1, {  
245 - deviceState: deviceState.type ? deviceState.type : undefined,  
246 - deviceType: deviceType.type ? deviceType.type : undefined,  
247 - alarmStatus: alarmStatus.type === '0' || alarmStatus.type === '1' ? alarmStatus.type : undefined  
248 - });  
249 - this.show = false;  
250 - },  
251 - inputChanged: debounce(function(name) {  
252 - this.loadData(1, {  
253 - name  
254 - });  
255 - }, 500)  
256 - } 312 + //获取设备
  313 + loadData(pageNo, params = {}) {
  314 + let httpData = {
  315 + page: pageNo,
  316 + pageSize: 10,
  317 + ...params,
  318 + };
  319 + uni.$u.http
  320 + .get("/yt/device", {
  321 + params: httpData,
  322 + custom: {
  323 + load: false,
  324 + },
  325 + })
  326 + .then((res) => {
  327 + this.total = res.total;
  328 + uni.stopPullDownRefresh();
  329 + console.log("获取后端数据", res);
  330 + //方法一(推荐): 后台接口有返回列表的总页数 totalPage
  331 + this.mescroll.endByPage(res.total, Math.ceil(res.total / 10)); //必传参数(当前页的数据个数, 总页数)
  332 + if (pageNo == 1) {
  333 + this.list = res.items;
  334 + } else {
  335 + this.list = this.list.concat(res.items);
  336 + }
  337 + })
  338 + .catch(() => {
  339 + //联网失败, 结束加载
  340 + this.mescroll.endErr();
  341 + });
  342 + },
  343 + openOrg() {
  344 + uni.navigateTo({
  345 + url: "./org/org",
  346 + });
  347 + },
  348 + close() {
  349 + this.resetFilter();
  350 + this.show = false;
  351 + },
  352 + openSearchDialog() {
  353 + this.show = true;
  354 + },
  355 + openDeviceDetail(id, alarmStatus, lastOnlineTime, tbDeviceId) {
  356 + uni.navigateTo({
  357 + url: `/deviceSubPage/deviceDetailPage/deviceDetail?id=${id}&alarmStatus=${alarmStatus}&lastOnlineTime=${lastOnlineTime}&tbDeviceId=${tbDeviceId}`,
  358 + });
  359 + },
  360 + handleClickTag(currentIndex, list) {
  361 + list.map((item, index) => {
  362 + item.checked = index === currentIndex;
  363 + });
  364 + },
  365 + resetFilter() {
  366 + const { deviceStatus, alarmStatus, typeStatus } = this;
  367 + [deviceStatus, alarmStatus, typeStatus].forEach((item) =>
  368 + item.map((item, index) => (item.checked = index === 0))
  369 + );
  370 + },
  371 + confirmFilter() {
  372 + const deviceState = this.deviceStatus.find((item) => item.checked);
  373 + const alarmStatus = this.alarmStatus.find((item) => item.checked);
  374 + const deviceType = this.typeStatus.find((item) => item.checked);
  375 + this.loadData(1, {
  376 + deviceState: deviceState.type ? deviceState.type : undefined,
  377 + deviceType: deviceType.type ? deviceType.type : undefined,
  378 + alarmStatus:
  379 + alarmStatus.type === "0" || alarmStatus.type === "1"
  380 + ? alarmStatus.type
  381 + : undefined,
  382 + });
  383 + this.show = false;
  384 + },
  385 + inputChanged: debounce(function (name) {
  386 + this.loadData(1, {
  387 + name,
  388 + });
  389 + }, 500),
  390 + },
257 }; 391 };
258 </script> 392 </script>
259 393
260 <style lang="scss" scoped> 394 <style lang="scss" scoped>
261 .device-page { 395 .device-page {
262 - min-height: 100vh;  
263 - background-color: #f8f9fa; 396 + min-height: 100vh;
  397 + background-color: #f8f9fa;
264 } 398 }
265 399
266 .org-sty { 400 .org-sty {
267 - width: 750rpx;  
268 - height: 150rpx;  
269 - margin-top: 1rpx;  
270 - background-color: #fff;  
271 - display: flex;  
272 - justify-content: space-between; 401 + width: 750rpx;
  402 + height: 150rpx;
  403 + margin-top: 1rpx;
  404 + background-color: #fff;
  405 + display: flex;
  406 + justify-content: space-between;
273 407
274 - .org-item {  
275 - width: 350rpx;  
276 - height: 200rpx;  
277 - } 408 + .org-item {
  409 + width: 350rpx;
  410 + height: 200rpx;
  411 + }
278 } 412 }
279 413
280 .device-list { 414 .device-list {
281 - display: flex;  
282 - flex-direction: column;  
283 - padding-left: 20rpx; 415 + display: flex;
  416 + flex-direction: column;
  417 + padding-left: 20rpx;
284 418
285 - .list-item {  
286 - width: 713rpx;  
287 - height: 200rpx;  
288 - background-color: #fff;  
289 - margin-top: 24rpx;  
290 - display: flex;  
291 - border-radius: 10px;  
292 - justify-content: space-between; 419 + .list-item {
  420 + width: 713rpx;
  421 + height: 200rpx;
  422 + background-color: #fff;
  423 + margin-top: 24rpx;
  424 + display: flex;
  425 + border-radius: 10px;
  426 + justify-content: space-between;
293 427
294 - .item {  
295 - margin: 30rpx;  
296 - }  
297 - } 428 + .item {
  429 + margin: 30rpx;
  430 + }
  431 + }
298 } 432 }
299 </style> 433 </style>
1 -import Vue from 'vue';  
2 -// import moment from 'moment'; 1 +import Vue from 'vue';
  2 +import moment from 'moment';
3 // #ifdef APP-PLUS 3 // #ifdef APP-PLUS
4 import {judgePermission} from './permission' 4 import {judgePermission} from './permission'
5 // #endif 5 // #endif
@@ -232,8 +232,8 @@ export const getAppLatLon = function(successCallback, errCallback, isOpenSetting @@ -232,8 +232,8 @@ export const getAppLatLon = function(successCallback, errCallback, isOpenSetting
232 } 232 }
233 }); 233 });
234 // #endif 234 // #endif
235 -}  
236 - 235 +}
  236 +
237 export function formatToDate(date = undefined, format = DATE_TIME_FORMAT) { 237 export function formatToDate(date = undefined, format = DATE_TIME_FORMAT) {
238 return moment(date).format(format); 238 return moment(date).format(format);
239 } 239 }