Commit 0f18827df80a2e9c8f4cc0e16a01979e47d3d27f

Authored by sqy
1 parent 0b83e8b9

fix:修改设备的页面

1 // 获取某个Key的历史数据 1 // 获取某个Key的历史数据
2 export function getHistroyData(params) { 2 export function getHistroyData(params) {
3 - const {entityId,keys,startTs,endTs} = params 3 + const {entityId,keys,startTs,endTs,interval} = params
4 return uni.$u.http.get( 4 return uni.$u.http.get(
5 - `/plugins/telemetry/DEVICE/${params.entityId}/values/timeseries?keys=${params.keys}&startTs=${params.startTs}&endTs=${params.endTs}`); 5 + `/plugins/telemetry/DEVICE/${entityId}/values/timeseries?keys=${keys}&startTs=${startTs}&endTs=${endTs}&interval=${interval}`);
6 } 6 }
7 7
8 // 获取当前设备的key 8 // 获取当前设备的key
@@ -4,11 +4,22 @@ @@ -4,11 +4,22 @@
4 <public-module></public-module> 4 <public-module></public-module>
5 <u-sticky bgColor="#fff"><u-tabs :list="list" :current="currentTab" @click="handleTabClick"></u-tabs></u-sticky> 5 <u-sticky bgColor="#fff"><u-tabs :list="list" :current="currentTab" @click="handleTabClick"></u-tabs></u-sticky>
6 <view style="margin-top:30rpx;"> 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" /> 7 + <basicInfo v-show="currentTab == 0" :deviceDetail="deviceDetail" />
  8 + <realTimeData v-show="currentTab === 1" :recordList="recordList" />
  9 + <historyData
  10 + v-if="currentTab === 2"
  11 + :keys="keys"
  12 + :yesterday="yesterday"
  13 + :today="today"
  14 + :timeDiff="timeDiff"
  15 + :historyData="historyData"
  16 + :entityId="entityId"
  17 + @update="handleUpdate"
  18 + :start="startTs"
  19 + :end="endTs"
  20 + />
  21 + <alarmHistory v-show="currentTab === 3" :deviceId="deviceId" />
  22 + <commondRecord v-show="currentTab === 4" :deviceId="deviceId" />
12 </view> 23 </view>
13 <f-tabbar></f-tabbar> 24 <f-tabbar></f-tabbar>
14 </view> 25 </view>
@@ -20,8 +31,8 @@ import basicInfo from './tabDetail/basicInfo.vue'; @@ -20,8 +31,8 @@ import basicInfo from './tabDetail/basicInfo.vue';
20 import realTimeData from './tabDetail/realtimeData.vue'; 31 import realTimeData from './tabDetail/realtimeData.vue';
21 import alarmHistory from './tabDetail/alarmHistory.vue'; 32 import alarmHistory from './tabDetail/alarmHistory.vue';
22 import historyData from './tabDetail/historyData.vue'; 33 import historyData from './tabDetail/historyData.vue';
23 -import commondRecord from './tabDetail/commondRecord.vue';  
24 -import { getDeviceKeys, getHistroyData } from '@/pages/device/api/index.js'; 34 +import commondRecord from './tabDetail/CommandRecord.vue';
  35 +import { getDeviceKeys, getHistroyData } from './api/index.js';
25 import { formatToDate } from '@/plugins/utils.js'; 36 import { formatToDate } from '@/plugins/utils.js';
26 export default { 37 export default {
27 components: { 38 components: {
@@ -35,58 +46,88 @@ export default { @@ -35,58 +46,88 @@ export default {
35 data() { 46 data() {
36 return { 47 return {
37 list: [{ name: '基础信息' }, { name: '实时数据' }, { name: '历史数据' }, { name: '告警记录' }, { name: '命令记录' }], 48 list: [{ name: '基础信息' }, { name: '实时数据' }, { name: '历史数据' }, { name: '告警记录' }, { name: '命令记录' }],
38 - currentTab: 2,  
39 - id: '', 49 + currentTab: 3,
  50 + deviceId: '',
40 deviceDetail: {}, 51 deviceDetail: {},
41 keys: [], 52 keys: [],
42 yesterday: '', 53 yesterday: '',
43 today: '', 54 today: '',
44 timeDiff: '', 55 timeDiff: '',
45 historyData: [], 56 historyData: [],
46 - entityId: '' 57 + entityId: '',
  58 + startTs: '',
  59 + endTs: '',
  60 + recordList: []
47 }; 61 };
48 }, 62 },
49 async onLoad(options) { 63 async onLoad(options) {
50 const { id, alarmStatus, lastOnlineTime, tbDeviceId } = options; 64 const { id, alarmStatus, lastOnlineTime, tbDeviceId } = options;
  65 + this.deviceId = id;
  66 + console.log(this.deviceId);
51 const res = await uni.$u.http.get(`/yt/device/${id}`); 67 const res = await uni.$u.http.get(`/yt/device/${id}`);
52 this.deviceDetail = { ...res, alarmStatus, lastOnlineTime }; 68 this.deviceDetail = { ...res, alarmStatus, lastOnlineTime };
  69 + const socketTask = uni.connectSocket({
  70 + url: 'wss://dev.thingskit.com/api/ws/plugins/telemetry?token=' + uni.getStorageSync('userInfo').isToken, //仅为示例,并非真实接口地址。
  71 + complete: () => {}
  72 + });
  73 + uni.onSocketOpen(header => {
  74 + socketTask.send({
  75 + data: JSON.stringify({
  76 + attrSubCmds: [],
  77 + tsSubCmds: [
  78 + {
  79 + entityType: 'DEVICE',
  80 + entityId: tbDeviceId,
  81 + scope: 'LATEST_TELEMETRY',
  82 + cmdId: 1
  83 + }
  84 + ],
  85 + historyCmds: [],
  86 + entityDataCmds: [],
  87 + entityDataUnsubscribeCmds: [],
  88 + alarmDataCmds: [],
  89 + alarmDataUnsubscribeCmds: [],
  90 + entityCountCmds: [],
  91 + entityCountUnsubscribeCmds: []
  92 + }),
  93 + success() {}
  94 + });
  95 + });
  96 + socketTask.onMessage(msg => {
  97 + const { data } = JSON.parse(msg.data);
  98 + const newArray = [];
  99 + for (const key in data) {
  100 + const [time, value] = data[key].flat(1);
  101 + let obj = { key, time, value };
  102 + if (this.recordList.length === 0) {
  103 + this.recordList.unshift(obj);
  104 + } else {
  105 + newArray.push(obj);
  106 + }
  107 + }
  108 + newArray.forEach(item => {
  109 + let flag = false;
  110 + this.recordList.forEach(item1 => {
  111 + if (item1.key === item.key) {
  112 + item1.value = item.value;
  113 + item1.time = item.time;
  114 + flag = true;
  115 + }
  116 + });
  117 + if (!flag) {
  118 + this.recordList.unshift(item);
  119 + }
  120 + });
53 121
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 - // }); 122 + this.recordList = this.recordList.map(item => {
  123 + return {
  124 + ...item,
  125 + time: formatToDate(item.time, 'YYYY-MM-DD HH:mm:ss')
  126 + };
  127 + });
  128 + });
87 129
88 const keys = await getDeviceKeys(tbDeviceId); 130 const keys = await getDeviceKeys(tbDeviceId);
89 - // 隐藏原生的tabbar'  
90 this.keys = [keys]; 131 this.keys = [keys];
91 const date = new Date(); 132 const date = new Date();
92 const year = date.getFullYear(); //获取完整的年份(4位) 133 const year = date.getFullYear(); //获取完整的年份(4位)
@@ -96,12 +137,15 @@ export default { @@ -96,12 +137,15 @@ export default {
96 const today = `${year}-${month}-${day + 1}`; 137 const today = `${year}-${month}-${day + 1}`;
97 this.yesterday = yesterday; 138 this.yesterday = yesterday;
98 this.today = today; 139 this.today = today;
99 - this.entityId = tbDeviceId 140 + this.startTs = formatToDate(yesterday, 'x');
  141 + this.endTs = formatToDate(today, 'x');
  142 + this.entityId = tbDeviceId;
100 const data = await getHistroyData({ 143 const data = await getHistroyData({
101 entityId: tbDeviceId, 144 entityId: tbDeviceId,
102 startTs: formatToDate(yesterday, 'x'), 145 startTs: formatToDate(yesterday, 'x'),
103 endTs: formatToDate(today, 'x'), 146 endTs: formatToDate(today, 'x'),
104 - keys: keys[0] 147 + keys: keys[0],
  148 + interval: 1800000
105 }); 149 });
106 150
107 this.historyData = data[keys[0]].map(item => { 151 this.historyData = data[keys[0]].map(item => {
@@ -111,13 +155,16 @@ export default { @@ -111,13 +155,16 @@ export default {
111 }; 155 };
112 }); 156 });
113 this.timeDiff = '30分钟'; 157 this.timeDiff = '30分钟';
114 - uni.hideTabBar();  
115 }, 158 },
116 methods: { 159 methods: {
117 handleTabClick({ index }) { 160 handleTabClick({ index }) {
118 this.currentTab = index; 161 this.currentTab = index;
119 }, 162 },
120 - handleUpdate(data){ 163 + handleUpdate(data) {
  164 + if (!Array.isArray(data)) {
  165 + this.historyData = [];
  166 + return;
  167 + }
121 this.historyData = data.map(item => { 168 this.historyData = data.map(item => {
122 return { 169 return {
123 value: item.value, 170 value: item.value,
  1 +<template>
  2 + <view class="command-detail">
  3 + <view class="detail-top">网关设备1</view>
  4 + <view class="detail">
  5 + <view class="detail-item">
  6 + <view class="detail-label">设备类型</view>
  7 + <view class="detail-value">网关子设备</view>
  8 + </view>
  9 + <u-line length="90%" margin="0 auto"></u-line>
  10 + <view class="detail-item">
  11 + <view class="detail-label">设备编号</view>
  12 + <view class="detail-value">SN98489123471829</view>
  13 + </view>
  14 + <u-line length="90%" margin="0 auto"></u-line>
  15 + <view class="detail-item">
  16 + <view class="detail-label">所属组织</view>
  17 + <view class="detail-value">云腾汽车</view>
  18 + </view>
  19 + <u-line length="90%" margin="0 auto"></u-line>
  20 + <view class="detail-item">
  21 + <view class="detail-label">命令下发时间</view>
  22 + <view class="detail-value">2022-01-25 12:44:22</view>
  23 + </view>
  24 + <u-line length="90%" margin="0 auto"></u-line>
  25 + <view class="detail-item">
  26 + <view class="detail-label">命令类型</view>
  27 + <view class="detail-value">Mqtt命令</view>
  28 + </view>
  29 + <u-line length="90%" margin="0 auto"></u-line>
  30 + <view class="detail-item">
  31 + <view class="detail-label">响应类型</view>
  32 + <view class="detail-value">OneWay</view>
  33 + </view>
  34 + <u-line length="90%" margin="0 auto"></u-line>
  35 + <view class="detail-item">
  36 + <view class="detail-label">下发结果</view>
  37 + <view class="detail-value">成功</view>
  38 + </view>
  39 + <u-line length="90%" margin="0 auto"></u-line>
  40 + <view class="detail-item">
  41 + <view class="detail-label">响应结果</view>
  42 + <view class="detail-value">成功</view>
  43 + </view>
  44 + </view>
  45 + <view class="command">命令内容</view>
  46 + <u-textarea></u-textarea>
  47 + </view>
  48 +</template>
  49 +
  50 +<script></script>
  51 +
  52 +<style lang="scss" scoped>
  53 +.command-detail {
  54 + padding: 0 30rpx;
  55 + .detail-top {
  56 + height: 118rpx;
  57 + width: 690rpx;
  58 + display: flex;
  59 + align-items: center;
  60 + background-color: #fff;
  61 + color: #333;
  62 + border-radius: 20rpx;
  63 + font-size: 30rpx;
  64 + margin-top: 30rpx;
  65 + padding: 30rpx;
  66 + }
  67 + .detail {
  68 + background-color: #fff;
  69 + margin-top: 30rpx;
  70 + border-radius: 20rpx;
  71 + width: 690rpx;
  72 + .detail-item {
  73 + padding: 30rpx;
  74 + display: flex;
  75 + align-items: center;
  76 + .detail-label {
  77 + color: #333;
  78 + font-size: 30rpx;
  79 + }
  80 + .detail-value {
  81 + color: #666;
  82 + font-size: 28rpx;
  83 + margin-left: 30rpx;
  84 + }
  85 + }
  86 + }
  87 + .command{
  88 + margin: 30rpx 0;
  89 + }
  90 +}
  91 +</style>
  1 +<template>
  2 + <view class="alert-page">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module></public-module>
  5 + <mescroll-body ref="mescrollRef" @init="mescrollInit" :down="downOption" @down="downCallback" @up="upCallback">
  6 + <view @click="openDeviceDetail(item)" class="list-item" v-for="(item, index) in list" :key="index">
  7 + <view class="item">
  8 + <view class="item-first">
  9 + <text>{{ item.deviceName }}</text>
  10 + <view class="item-right">响应成功</view>
  11 + </view>
  12 + <view>
  13 + 命令类型:<text style="margin-left: 16rpx;">MQTT命令</text>
  14 + </view>
  15 + <view>
  16 + 命令状态:<text style="margin-left: 16rpx;">下发成功</text>
  17 + </view>
  18 + <view class="time">{{ item.createdTime }}</view>
  19 + </view>
  20 + </view>
  21 + </mescroll-body>
  22 + <!-- 告警筛选 -->
  23 + <u-popup @close="close" closeable :overlay="true" :show="show" mode="bottom" bgColor="#fff">
  24 + <view>
  25 + <view style="text-align: center; margin-top: 28rpx"><text>筛选条件</text></view>
  26 + <FilterItem :filterList="alarmStatus" title="告警状态" @clickTag="currentIndex => handleClickTag(currentIndex, alarmStatus)"></FilterItem>
  27 + <FilterItem :filterList="typeStatus" title="设备类型" @clickTag="currentIndex => handleClickTag(currentIndex, typeStatus)"></FilterItem>
  28 + <FilterItem :filterList="alarmLevelStatus" title="告警等级" @clickTag="currentIndex => handleClickTag(currentIndex, alarmLevelStatus)"></FilterItem>
  29 + <FilterItem :filterList="timeStatus" title="选择时间" @clickTag="currentIndex => handleClickTag(currentIndex, timeStatus)"></FilterItem>
  30 + <view class="u-flex" style="margin-top: 40rpx; margin-left: 55rpx">
  31 + <view style="width: 300rpx"><u-button type="info" shape="circle" text="重置" @click="resetFilter"></u-button></view>
  32 + <view style="width: 300rpx; margin-left: 46rpx"><u-button type="primary" shape="circle" text="确认" @click="confirmFilter"></u-button></view>
  33 + </view>
  34 + </view>
  35 + </u-popup>
  36 + <u-calendar
  37 + :show="showCalendar"
  38 + mode="range"
  39 + @confirm="calendarConfirm"
  40 + @close="calendarClose"
  41 + startText="开始时间"
  42 + endText="结束时间"
  43 + confirmDisabledText="请选择日期"
  44 + :formatter="formatter"
  45 + ></u-calendar>
  46 + </view>
  47 +</template>
  48 +<script>
  49 +import FilterItem from '@/pages/device/FilterItem.vue';
  50 +import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
  51 +export default {
  52 + mixins: [MescrollMixin],
  53 + components: {
  54 + FilterItem
  55 + },
  56 + props: {
  57 + deviceId: {
  58 + type: String,
  59 + default: ''
  60 + }
  61 + },
  62 + mounted() {
  63 + this.loadData(1, {
  64 + deviceId: this.deviceId
  65 + });
  66 + },
  67 + data() {
  68 + return {
  69 + show: false,
  70 + list: [],
  71 + total: '',
  72 + timeData: {
  73 + selectTime: '',
  74 + getTimeGap: ''
  75 + },
  76 + showCalendar: false,
  77 + alarmStatus: [
  78 + {
  79 + checked: true,
  80 + name: '全部',
  81 + type: ''
  82 + },
  83 + {
  84 + checked: false,
  85 + name: '激活未确认',
  86 + type: 'ACTIVE_UNACK'
  87 + },
  88 + {
  89 + checked: false,
  90 + name: '激活已确认',
  91 + type: 'ACTIVE_ACK'
  92 + },
  93 + {
  94 + checked: false,
  95 + name: '清除未确认',
  96 + type: 'CLEARED_UNACK'
  97 + },
  98 + {
  99 + checked: false,
  100 + name: '清除已确认',
  101 + type: 'CLEARED_ACK'
  102 + }
  103 + ],
  104 + typeStatus: [
  105 + {
  106 + checked: true,
  107 + name: '全部',
  108 + type: ''
  109 + },
  110 + {
  111 + checked: false,
  112 + name: '网关设备',
  113 + type: 'GATEWAY'
  114 + },
  115 + {
  116 + checked: false,
  117 + name: '网关子设备',
  118 + type: 'SENSOR'
  119 + },
  120 + {
  121 + checked: false,
  122 + name: '直连设备',
  123 + type: 'DIRECT_CONNECTION'
  124 + }
  125 + ],
  126 + alarmLevelStatus: [
  127 + {
  128 + checked: true,
  129 + name: '全部',
  130 + type: ''
  131 + },
  132 + {
  133 + checked: false,
  134 + name: '危险',
  135 + type: 'CRITICAL'
  136 + },
  137 + {
  138 + checked: false,
  139 + name: '重要',
  140 + type: 'MAJOR'
  141 + },
  142 + {
  143 + checked: false,
  144 + name: '次要',
  145 + type: 'MINOR'
  146 + },
  147 + {
  148 + checked: false,
  149 + name: '警告',
  150 + type: 'WARNING'
  151 + },
  152 + {
  153 + checked: false,
  154 + name: '不确定',
  155 + type: 'INDETERMINATE'
  156 + }
  157 + ],
  158 + timeStatus: [
  159 + {
  160 + checked: true,
  161 + name: '全部',
  162 + type: ''
  163 + },
  164 + {
  165 + checked: false,
  166 + name: '30分钟',
  167 + type: '1800000'
  168 + },
  169 + {
  170 + checked: false,
  171 + name: '一小时',
  172 + type: '3600000'
  173 + },
  174 + {
  175 + checked: false,
  176 + name: '2小时',
  177 + type: '7200000'
  178 + },
  179 + {
  180 + checked: false,
  181 + name: '近一天',
  182 + type: '1440000'
  183 + }
  184 + ],
  185 + downOption: {
  186 + auto: false //是否在初始化后,自动执行downCallback; 默认true
  187 + },
  188 + page:{
  189 + num:0,
  190 + sizie:10
  191 + }
  192 + };
  193 + },
  194 + methods: {
  195 + /*下拉刷新的回调 */
  196 + downCallback() {
  197 + //联网加载数据
  198 + this.list = [];
  199 + this.page.num = 1;
  200 + this.loadData(this.page.num, {
  201 + deviceId: this.deviceId
  202 + });
  203 + },
  204 + /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
  205 + upCallback() {
  206 + //联网加载数据
  207 + this.page.num += 1;
  208 + this.loadData(this.page.num, {
  209 + deviceId: this.deviceId
  210 + });
  211 + },
  212 + //获取告警数据
  213 + loadData(pageNo, params = {}) {
  214 + let httpData = {
  215 + ...params,
  216 + page: pageNo,
  217 + pageSize: 10
  218 + };
  219 + uni.$u.http
  220 + .get('/yt/alarm', {
  221 + params: httpData,
  222 + custom: {
  223 + load: false
  224 + }
  225 + })
  226 + .then(res => {
  227 + this.total = res.total;
  228 + uni.stopPullDownRefresh();
  229 + console.log('获取后端数据', res);
  230 + //方法一(推荐): 后台接口有返回列表的总页数 totalPage
  231 + this.mescroll.endByPage(res.items.length,res.total); //必传参数(当前页的数据个数, 总页数)
  232 + if (pageNo == 1) {
  233 + this.list = res.items;
  234 + } else {
  235 + this.list = this.list.concat(res.items);
  236 + }
  237 + })
  238 + .catch(() => {
  239 + //联网失败, 结束加载
  240 + this.mescroll.endErr();
  241 + });
  242 + },
  243 + handleClickTag(currentIndex, list) {
  244 + list.map((item, index) => {
  245 + item.checked = index === currentIndex;
  246 + });
  247 + },
  248 + resetFilter() {
  249 + const { alarmStatus, typeStatus, alarmLevelStatus, timeStatus } = this;
  250 + [alarmStatus, typeStatus, alarmLevelStatus, timeStatus].forEach(item => item.map((item, index) => (item.checked = index === 0)));
  251 + },
  252 + close() {
  253 + this.show = false;
  254 + },
  255 + openSearchDialog() {
  256 + this.show = true;
  257 + },
  258 + hideKeyboard() {
  259 + uni.hideKeyboard();
  260 + },
  261 + calendarConfirm(e) {
  262 + this.showCalendar = false;
  263 + this.timeData.selectTime = `${e[0]} / ${e[e.length - 1]}`;
  264 + },
  265 + confirmFilter() {
  266 + const alarmState = this.alarmStatus.find(item => item.checked);
  267 + const typeState = this.typeStatus.find(item => item.checked);
  268 + const alarmLevelState = this.alarmLevelStatus.find(item => item.checked);
  269 + const timeState = this.timeStatus.find(item => item.checked);
  270 + const endTs = Date.now();
  271 + const startTs = endTs - timeState.type;
  272 + this.loadData(1, {
  273 + status: alarmState.type ? alarmState.type : undefined,
  274 + deviceType: typeState.type ? typeState.type : undefined,
  275 + alarmType: alarmLevelState.type ? alarmLevelState.type : undefined,
  276 + startTime: timeState.type ? startTs : undefined,
  277 + endTime: timeState.type ? endTs : undefined,
  278 + deviceId: this.deviceId
  279 + });
  280 + this.show = false;
  281 + },
  282 + calendarClose() {
  283 + this.showCalendar = false;
  284 + },
  285 + openDeviceDetail(item) {
  286 + const { id, deviceName, severity, originatorType, details, createdTime, status } = item;
  287 + let obj = {
  288 + id,
  289 + deviceName,
  290 + severity,
  291 + originatorType,
  292 + details,
  293 + createdTime,
  294 + status
  295 + };
  296 + console.log(123)
  297 + uni.navigateTo({
  298 + url:'/deviceSubPage/deviceDetailPage/tabDetail/CommandDetail'
  299 + });
  300 + }
  301 + }
  302 +};
  303 +</script>
  304 +
  305 +<style lang="scss" scoped>
  306 +.alert-page {
  307 + padding: 20rpx;
  308 + .list-item {
  309 + width: 690rpx;
  310 + height: 262rpx;
  311 + background-color: #fff;
  312 + border-radius: 20rpx;
  313 + margin: 20rpx auto;
  314 + color: #333;
  315 + .item {
  316 + padding: 30rpx;
  317 + view {
  318 + font-size: 28rpx;
  319 + margin-bottom: 10rpx;
  320 + }
  321 + .time {
  322 + color: #999;
  323 + }
  324 + .item-first {
  325 + display: flex;
  326 + justify-content: space-between;
  327 + align-items: center;
  328 + font-size: 30rpx;
  329 + font-weight: 500;
  330 + align-items: center;
  331 + .item-right {
  332 + display: flex;
  333 + justify-content: center;
  334 + align-items: center;
  335 + color: #00c9a7;
  336 + width: 104rpx;
  337 + height: 36rpx;
  338 + font-size: 20rpx;
  339 + background-color: #00c9a725;
  340 + border-radius: 20rpx;
  341 + }
  342 + }
  343 + }
  344 + }
  345 +}
  346 +</style>
@@ -2,134 +2,68 @@ @@ -2,134 +2,68 @@
2 <view class="alert-page"> 2 <view class="alert-page">
3 <!-- 公共组件-每个页面必须引入 --> 3 <!-- 公共组件-每个页面必须引入 -->
4 <public-module></public-module> 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> 5 + <mescroll-body ref="mescrollRef" @init="mescrollInit" :down="downOption" @down="downCallback" @up="upCallback">
  6 + <view style="width: 192rpx;"><u-button @click="openSearchDialog" shape="circle" type="info" icon="search" text="筛选"></u-button></view>
  7 + <view @click="openDeviceDetail(item)" class="list-item" v-for="(item, index) in list" :key="index">
22 <view class="item"> 8 <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> 9 + <view class="item-first">
  10 + <text>{{ item.deviceName }}</text>
  11 + <view class="item-right">
  12 + <image
  13 + :src="
  14 + item.severity === 'CRITICAL'
  15 + ? '../../../static/danger.png'
  16 + : item.severity === 'MAJOR'
  17 + ? '../../../static/major.png'
  18 + : item.severity === 'MINOR'
  19 + ? '../../../static/secondary.png'
  20 + : item.severity === 'WARNING'
  21 + ? '../../../static/warn.png'
  22 + : '../../../static/noshue.png'
  23 + "
  24 + ></image>
  25 + <text
  26 + :style="{
  27 + color:
  28 + item.severity === 'CRITICAL'
  29 + ? '#DE4437'
  30 + : item.severity === 'MAJOR'
  31 + ? '#DE7337'
  32 + : item.severity === 'MINOR'
  33 + ? '#FFC107'
  34 + : item.severity === 'WARNING'
  35 + ? '#FF1E0B'
  36 + : '#00C9A7'
  37 + }"
  38 + >
  39 + {{
  40 + item.severity === 'CRITICAL' ? '危险' : item.severity === 'MAJOR' ? '重要' : item.severity === 'MINOR' ? '次要' : item.severity === 'WARNING' ? '警告' : '不确定'
  41 + }}
  42 + </text>
27 </view> 43 </view>
28 </view> 44 </view>
  45 + <view>{{ Object.entries(item.details.data)[0][0] }} : {{ Object.entries(item.details.data)[0][1] }}</view>
  46 + <view v-if="item.status">
  47 + 告警状态:{{
  48 + item.status === 'CLEARED_UNACK' ? '清除未确认' : item.status === 'CLEARED_ACK' ? '清除已确认' : item.status === 'ACTIVE_UNACK' ? '激活未确认' : '激活已确认'
  49 + }}
  50 + </view>
  51 + <view class="time">{{ item.createdTime }}</view>
29 </view> 52 </view>
30 </view> 53 </view>
31 - </view>  
32 - <view style="height: 30rpx;"></view> 54 + </mescroll-body>
33 <!-- 告警筛选 --> 55 <!-- 告警筛选 -->
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> 56 + <u-popup @close="close" closeable :overlay="true" :show="show" mode="bottom" bgColor="#fff">
  57 + <view>
  58 + <view style="text-align: center; margin-top: 28rpx"><text>筛选条件</text></view>
  59 + <FilterItem :filterList="alarmStatus" title="告警状态" @clickTag="currentIndex => handleClickTag(currentIndex, alarmStatus)"></FilterItem>
  60 + <FilterItem :filterList="typeStatus" title="设备类型" @clickTag="currentIndex => handleClickTag(currentIndex, typeStatus)"></FilterItem>
  61 + <FilterItem :filterList="alarmLevelStatus" title="告警等级" @clickTag="currentIndex => handleClickTag(currentIndex, alarmLevelStatus)"></FilterItem>
  62 + <FilterItem :filterList="timeStatus" title="选择时间" @clickTag="currentIndex => handleClickTag(currentIndex, timeStatus)"></FilterItem>
  63 + <view class="u-flex" style="margin-top: 40rpx; margin-left: 55rpx">
  64 + <view style="width: 300rpx"><u-button type="info" shape="circle" text="重置" @click="resetFilter"></u-button></view>
  65 + <view style="width: 300rpx; margin-left: 46rpx"><u-button type="primary" shape="circle" text="确认" @click="confirmFilter"></u-button></view>
54 </view> 66 </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> 67 </view>
134 </u-popup> 68 </u-popup>
135 <u-calendar 69 <u-calendar
@@ -142,225 +76,212 @@ @@ -142,225 +76,212 @@
142 confirmDisabledText="请选择日期" 76 confirmDisabledText="请选择日期"
143 :formatter="formatter" 77 :formatter="formatter"
144 ></u-calendar> 78 ></u-calendar>
145 -  
146 </view> 79 </view>
147 </template> 80 </template>
148 -  
149 <script> 81 <script>
150 -import fTabbar from '@/components/module/f-tabbar/f-tabbar'; 82 +import FilterItem from '@/pages/device/FilterItem.vue';
  83 +import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
151 export default { 84 export default {
  85 + mixins: [MescrollMixin],
152 components: { 86 components: {
153 - fTabbar 87 + FilterItem
  88 + },
  89 + props: {
  90 + deviceId: {
  91 + type: String,
  92 + default: ''
  93 + }
  94 + },
  95 + mounted() {
  96 + this.loadData(1, {
  97 + deviceId: this.deviceId
  98 + });
154 }, 99 },
155 data() { 100 data() {
156 return { 101 return {
157 show: false, 102 show: false,
  103 + list: [],
  104 + total: '',
158 timeData: { 105 timeData: {
159 selectTime: '', 106 selectTime: '',
160 getTimeGap: '' 107 getTimeGap: ''
161 }, 108 },
162 showCalendar: false, 109 showCalendar: false,
163 - alertStatus: [ 110 + alarmStatus: [
164 { 111 {
165 - index: 1, 112 + checked: true,
166 name: '全部', 113 name: '全部',
167 - bgColor: '#377DFF',  
168 - textColor: '#377DFF' 114 + type: ''
169 }, 115 },
170 { 116 {
171 - index: 2, 117 + checked: false,
172 name: '激活未确认', 118 name: '激活未确认',
173 - bgColor: '#F6F6F6',  
174 - textColor: '#F6F6F6' 119 + type: 'ACTIVE_UNACK'
175 }, 120 },
176 { 121 {
177 - index: 3, 122 + checked: false,
178 name: '激活已确认', 123 name: '激活已确认',
179 - bgColor: '#F6F6F6',  
180 - textColor: '#F6F6F6' 124 + type: 'ACTIVE_ACK'
181 }, 125 },
182 { 126 {
183 - index: 4, 127 + checked: false,
184 name: '清除未确认', 128 name: '清除未确认',
185 - bgColor: '#F6F6F6',  
186 - textColor: '#F6F6F6' 129 + type: 'CLEARED_UNACK'
187 }, 130 },
188 { 131 {
189 - index: 5, 132 + checked: false,
190 name: '清除已确认', 133 name: '清除已确认',
191 - bgColor: '#F6F6F6',  
192 - textColor: '#F6F6F6'  
193 - },  
194 - {  
195 - index: 6,  
196 - name: '清除已确认',  
197 - bgColor: '#F6F6F6',  
198 - textColor: '#F6F6F6' 134 + type: 'CLEARED_ACK'
199 } 135 }
200 ], 136 ],
201 - deviceType: [ 137 + typeStatus: [
202 { 138 {
203 - index: 1, 139 + checked: true,
204 name: '全部', 140 name: '全部',
205 - bgColor: '#377DFF',  
206 - textColor: '#377DFF' 141 + type: ''
207 }, 142 },
208 { 143 {
209 - index: 2, 144 + checked: false,
210 name: '网关设备', 145 name: '网关设备',
211 - bgColor: '#F6F6F6',  
212 - textColor: '#F6F6F6' 146 + type: 'GATEWAY'
213 }, 147 },
214 { 148 {
215 - index: 3, 149 + checked: false,
216 name: '网关子设备', 150 name: '网关子设备',
217 - bgColor: '#F6F6F6',  
218 - textColor: '#F6F6F6' 151 + type: 'SENSOR'
219 }, 152 },
220 { 153 {
221 - index: 4, 154 + checked: false,
222 name: '直连设备', 155 name: '直连设备',
223 - bgColor: '#F6F6F6',  
224 - textColor: '#F6F6F6' 156 + type: 'DIRECT_CONNECTION'
225 } 157 }
226 ], 158 ],
227 - alertLevel: [ 159 + alarmLevelStatus: [
228 { 160 {
229 - index: 1, 161 + checked: true,
230 name: '全部', 162 name: '全部',
231 - bgColor: '#377DFF',  
232 - textColor: '#377DFF' 163 + type: ''
233 }, 164 },
234 { 165 {
235 - index: 2, 166 + checked: false,
236 name: '危险', 167 name: '危险',
237 - bgColor: '#F6F6F6',  
238 - textColor: '#F6F6F6' 168 + type: 'CRITICAL'
239 }, 169 },
240 { 170 {
241 - index: 3, 171 + checked: false,
242 name: '重要', 172 name: '重要',
243 - bgColor: '#F6F6F6',  
244 - textColor: '#F6F6F6' 173 + type: 'MAJOR'
245 }, 174 },
246 { 175 {
247 - index: 4, 176 + checked: false,
248 name: '次要', 177 name: '次要',
249 - bgColor: '#F6F6F6',  
250 - textColor: '#F6F6F6' 178 + type: 'MINOR'
251 }, 179 },
252 { 180 {
253 - index: 4, 181 + checked: false,
254 name: '警告', 182 name: '警告',
255 - bgColor: '#F6F6F6',  
256 - textColor: '#F6F6F6' 183 + type: 'WARNING'
257 }, 184 },
258 { 185 {
259 - index: 4, 186 + checked: false,
260 name: '不确定', 187 name: '不确定',
261 - bgColor: '#F6F6F6',  
262 - textColor: '#F6F6F6' 188 + type: 'INDETERMINATE'
263 } 189 }
264 ], 190 ],
265 - timeArea: [ 191 + timeStatus: [
266 { 192 {
267 - index: 1, 193 + checked: true,
268 name: '全部', 194 name: '全部',
269 - value: '全部',  
270 - bgColor: '#F6F6F6',  
271 - textColor: '#F6F6F6' 195 + type: ''
272 }, 196 },
273 { 197 {
274 - index: 2, 198 + checked: false,
275 name: '30分钟', 199 name: '30分钟',
276 - value: '30',  
277 - bgColor: '#F6F6F6',  
278 - textColor: '#F6F6F6' 200 + type: '1800000'
279 }, 201 },
280 { 202 {
281 - index: 3,  
282 - name: '1小时',  
283 - value: '30',  
284 - bgColor: '#F6F6F6',  
285 - textColor: '#F6F6F6' 203 + checked: false,
  204 + name: '一小时',
  205 + type: '3600000'
286 }, 206 },
287 { 207 {
288 - index: 4, 208 + checked: false,
289 name: '2小时', 209 name: '2小时',
290 - value: '120',  
291 - bgColor: '#F6F6F6',  
292 - textColor: '#F6F6F6' 210 + type: '7200000'
293 }, 211 },
294 { 212 {
295 - index: 5, 213 + checked: false,
296 name: '近一天', 214 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' 215 + type: '1440000'
307 } 216 }
308 ], 217 ],
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 - ] 218 + downOption: {
  219 + auto: false //是否在初始化后,自动执行downCallback; 默认true
  220 + },
  221 + page: {
  222 + num: 0,
  223 + size: 10
  224 + }
356 }; 225 };
357 }, 226 },
358 - onLoad(e) {  
359 - // 隐藏原生的tabbar  
360 - uni.hideTabBar();  
361 - },  
362 methods: { 227 methods: {
363 - open() {}, 228 + /*下拉刷新的回调 */
  229 + downCallback() {
  230 + //联网加载数据
  231 + this.list = [];
  232 + this.page.num = 1;
  233 + this.loadData(this.page.num, {
  234 + deviceId: this.deviceId
  235 + });
  236 + },
  237 + /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
  238 + upCallback() {
  239 + //联网加载数据
  240 + this.page.num += 1;
  241 + this.loadData(this.page.num, {
  242 + deviceId: this.deviceId
  243 + });
  244 + },
  245 + //获取告警数据
  246 + loadData(pageNo, params = {}) {
  247 + let httpData = {
  248 + ...params,
  249 + page: pageNo,
  250 + pageSize: 10
  251 + };
  252 + uni.$u.http
  253 + .get('/yt/alarm', {
  254 + params: httpData,
  255 + custom: {
  256 + load: false
  257 + }
  258 + })
  259 + .then(res => {
  260 + this.total = res.total;
  261 + uni.stopPullDownRefresh();
  262 + console.log('获取后端数据', res);
  263 + //方法一(推荐): 后台接口有返回列表的总页数 totalPage
  264 + this.mescroll.endByPage(res.items.length, res.total); //必传参数(当前页的数据个数, 总页数)
  265 + if (pageNo == 1) {
  266 + this.list = res.items;
  267 + } else {
  268 + this.list = this.list.concat(res.items);
  269 + }
  270 + })
  271 + .catch(() => {
  272 + //联网失败, 结束加载
  273 + this.mescroll.endErr();
  274 + });
  275 + },
  276 + handleClickTag(currentIndex, list) {
  277 + list.map((item, index) => {
  278 + item.checked = index === currentIndex;
  279 + });
  280 + },
  281 + resetFilter() {
  282 + const { alarmStatus, typeStatus, alarmLevelStatus, timeStatus } = this;
  283 + [alarmStatus, typeStatus, alarmLevelStatus, timeStatus].forEach(item => item.map((item, index) => (item.checked = index === 0)));
  284 + },
364 close() { 285 close() {
365 this.show = false; 286 this.show = false;
366 }, 287 },
@@ -374,8 +295,41 @@ export default { @@ -374,8 +295,41 @@ export default {
374 this.showCalendar = false; 295 this.showCalendar = false;
375 this.timeData.selectTime = `${e[0]} / ${e[e.length - 1]}`; 296 this.timeData.selectTime = `${e[0]} / ${e[e.length - 1]}`;
376 }, 297 },
  298 + confirmFilter() {
  299 + const alarmState = this.alarmStatus.find(item => item.checked);
  300 + const typeState = this.typeStatus.find(item => item.checked);
  301 + const alarmLevelState = this.alarmLevelStatus.find(item => item.checked);
  302 + const timeState = this.timeStatus.find(item => item.checked);
  303 + const endTs = Date.now();
  304 + const startTs = endTs - timeState.type;
  305 + this.loadData(1, {
  306 + status: alarmState.type ? alarmState.type : undefined,
  307 + deviceType: typeState.type ? typeState.type : undefined,
  308 + alarmType: alarmLevelState.type ? alarmLevelState.type : undefined,
  309 + startTime: timeState.type ? startTs : undefined,
  310 + endTime: timeState.type ? endTs : undefined,
  311 + deviceId: this.deviceId
  312 + });
  313 + this.show = false;
  314 + },
377 calendarClose() { 315 calendarClose() {
378 this.showCalendar = false; 316 this.showCalendar = false;
  317 + },
  318 + openDeviceDetail(item) {
  319 + const { id, deviceName, severity, originatorType, details, createdTime, status } = item;
  320 + let obj = {
  321 + id,
  322 + deviceName,
  323 + severity,
  324 + originatorType,
  325 + details,
  326 + createdTime,
  327 + status
  328 + };
  329 + uni.navigateTo({
  330 + url: '/alarmSubPage/alarmDetailPage/alarmDetail?data=' + JSON.stringify(obj)
  331 + // url: '/' + JSON.stringify(obj)
  332 + });
379 } 333 }
380 } 334 }
381 }; 335 };
@@ -383,24 +337,39 @@ export default { @@ -383,24 +337,39 @@ export default {
383 337
384 <style lang="scss" scoped> 338 <style lang="scss" scoped>
385 .alert-page { 339 .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; 340 + padding: 20rpx;
393 .list-item { 341 .list-item {
394 - width: 713rpx;  
395 - height: 233rpx; 342 + width: 690rpx;
  343 + height: 262rpx;
396 background-color: #fff; 344 background-color: #fff;
397 - margin-top: 24rpx;  
398 - display: flex;  
399 -  
400 - border-radius: 10px;  
401 - justify-content: space-between; 345 + border-radius: 20rpx;
  346 + margin: 20rpx auto;
  347 + color: #333;
402 .item { 348 .item {
403 - margin: 30rpx; 349 + padding: 30rpx;
  350 + view {
  351 + font-size: 28rpx;
  352 + margin-bottom: 10rpx;
  353 + }
  354 + .time {
  355 + color: #999;
  356 + }
  357 + .item-first {
  358 + display: flex;
  359 + justify-content: space-between;
  360 + font-size: 30rpx;
  361 + font-weight: 500;
  362 + align-items: center;
  363 + .item-right {
  364 + display: flex;
  365 + align-items: center;
  366 + image {
  367 + width: 28rpx;
  368 + height: 28rpx;
  369 + margin-right: 10rpx;
  370 + }
  371 + }
  372 + }
404 } 373 }
405 } 374 }
406 } 375 }
@@ -2,103 +2,148 @@ @@ -2,103 +2,148 @@
2 <view class="basic-page"> 2 <view class="basic-page">
3 <!-- 公共组件-每个页面必须引入 --> 3 <!-- 公共组件-每个页面必须引入 -->
4 <public-module /> 4 <public-module />
5 - <view class="u-flex" style="justify-content: space-between;height: 140rpx;background-color: #fff;border-radius: 18px;"> 5 + <view class="basic-title">
6 <view class="u-flex"> 6 <view class="u-flex">
7 - <view style="margin-left: 20rpx;">  
8 - {{deviceDetail.name}} 7 + <view style="margin-left: 20rpx;">{{ deviceDetail.name }}</view>
  8 + <view
  9 + style="margin-left: 20rpx; font-size: 14px;"
  10 + :style="{ color: deviceDetail.deviceState === 'INACTIVE' ? '#666' : deviceDetail.deviceState === 'ONLINE' ? '#377DFF' : '#DE4437' }"
  11 + >
  12 + {{ deviceDetail.deviceState === 'INACTIVE' ? '待激活' : deviceDetail.deviceState === 'ONLINE' ? '在线' : '离线' }}
9 </view> 13 </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> 14 </view>
  15 + <view style="margin-right: 20rpx;"><u-button type="primary" shape="circle" size="mini" text="下发命令" @click="showModal" /></view>
17 </view> 16 </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> 17 + <view class="detail">
  18 + <view class="detail-item">
  19 + <view class="detail-label">设备编号</view>
  20 + <view class="detail-value">{{ deviceDetail.sn }}</view>
  21 + </view>
  22 + <u-line length="90%" margin="0 auto"></u-line>
  23 + <view class="detail-item">
  24 + <view class="detail-label">设备类型</view>
  25 + <view class="detail-value">{{ deviceType }}</view>
  26 + </view>
  27 + <u-line length="90%" margin="0 auto"></u-line>
  28 + <view class="detail-item">
  29 + <view class="detail-label">所属组织</view>
  30 + <view class="detail-value">{{ deviceDetail.organizationDTO.name }}</view>
  31 + </view>
  32 + <u-line length="90%" margin="0 auto"></u-line>
  33 + <view class="detail-item">
  34 + <view class="detail-label">最后连接时间</view>
  35 + <view class="detail-value">{{ formatLastOnlineTime }}</view>
  36 + </view>
  37 + <u-line length="90%" margin="0 auto"></u-line>
  38 + <view class="detail-item">
  39 + <view class="detail-label">是否告警</view>
  40 + <view class="detail-value">{{ alarmStatus }}</view>
  41 + </view>
  42 + <u-line length="90%" margin="0 auto"></u-line>
  43 + <view class="detail-item">
  44 + <view class="detail-label">设备描述</view>
  45 + <view class="detail-value">{{ deviceDetail.description }}</view>
  46 + </view>
51 </view> 47 </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 /> 48 +
  49 + <!-- 下发命令 -->
  50 + <u-modal :show="showModel" closeOnClickOverlay showCancelButton width="375px" @close="hiddenModal" @cancel="hiddenModal" @confirm="handleConfirm">
  51 + <view>
  52 + <view class="u-flex" style="align-items: center;">
  53 + <text style="color: #333; font-size: 28rpx;margin-right: 10rpx;">下发类型:</text>
  54 + <u-radio-group v-model="value" placement="row" style="margin-left: 10rpx;" size="20">
  55 + <u-radio activeColor="#3388FF" label="OneWay"></u-radio>
  56 + <u-radio activeColor="#3388FF" label="TwoWay"></u-radio>
  57 + </u-radio-group>
  58 + </view>
  59 + <view style="margin-top: 28rpx;"><u--textarea placeholder="请输入命令内容" v-model="formModel.intro" /></view>
  60 + </view>
55 </u-modal> 61 </u-modal>
56 </view> 62 </view>
57 </template> 63 </template>
58 64
59 <script> 65 <script>
60 -import {formatToDate} from '@/plugins/utils.js'; 66 +import { formatToDate } from '@/plugins/utils.js';
61 export default { 67 export default {
62 - props:{  
63 - deviceDetail:{  
64 - type:Object,  
65 - default:()=>({}), 68 + props: {
  69 + deviceDetail: {
  70 + type: Object,
  71 + default: () => ({})
66 } 72 }
67 }, 73 },
68 data() { 74 data() {
69 return { 75 return {
70 - showModel: false, 76 + showModel: false
71 }; 77 };
72 }, 78 },
73 - computed:{  
74 - deviceType(){  
75 - return this.deviceDetail.deviceType==='DIRECT_CONNECTION'?'直连设备':this.deviceDetail.deviceType==='GATEWAY'?'网关设备':this.deviceDetail.deviceType==='SENSOR'?'网关子设备':'' 79 + computed: {
  80 + deviceType() {
  81 + return this.deviceDetail.deviceType === 'DIRECT_CONNECTION'
  82 + ? '直连设备'
  83 + : this.deviceDetail.deviceType === 'GATEWAY'
  84 + ? '网关设备'
  85 + : this.deviceDetail.deviceType === 'SENSOR'
  86 + ? '网关子设备'
  87 + : '';
76 }, 88 },
77 - alarmStatus(){  
78 - return this.deviceDetail.alarmStatus === '0'?'否':'是' 89 + alarmStatus() {
  90 + return this.deviceDetail.alarmStatus === '0' ? '否' : '是';
79 }, 91 },
80 - formatLastOnlineTime(){  
81 - return formatToDate(Number(this.deviceDetail.lastOnlineTime),'YYYY-MM-DD HH:mm:ss') 92 + formatLastOnlineTime() {
  93 + return formatToDate(Number(this.deviceDetail.lastOnlineTime), 'YYYY-MM-DD HH:mm:ss');
82 } 94 }
83 }, 95 },
84 onLoad(e) { 96 onLoad(e) {
85 // 隐藏原生的tabbar 97 // 隐藏原生的tabbar
86 uni.hideTabBar(); 98 uni.hideTabBar();
87 }, 99 },
88 - onMounted(){  
89 - console.log(this.deviceDetail)  
90 - 100 + onMounted() {
  101 + console.log(this.deviceDetail);
91 }, 102 },
92 methods: { 103 methods: {
93 showModal() { 104 showModal() {
94 this.showModel = true; 105 this.showModel = true;
95 }, 106 },
96 - hiddenModal(){ 107 + hiddenModal() {
97 this.showModel = false; 108 this.showModel = false;
98 }, 109 },
99 - handleConfirm(){  
100 - console.log('确定') 110 + handleConfirm() {
  111 + console.log('确定');
101 } 112 }
102 } 113 }
103 }; 114 };
104 </script> 115 </script>
  116 +
  117 +<style lang="scss" scoped>
  118 +.basic-page {
  119 + padding: 0 30rpx;
  120 + .basic-title {
  121 + display: flex;
  122 + justify-content: space-between;
  123 + align-items: center;
  124 + height: 140rpx;
  125 + background-color: #fff;
  126 + border-radius: 20rpx;
  127 + }
  128 + .detail {
  129 + background-color: #fff;
  130 + margin-top: 30rpx;
  131 + border-radius: 20rpx;
  132 + width: 690rpx;
  133 + .detail-item {
  134 + padding: 30rpx;
  135 + display: flex;
  136 + align-items: center;
  137 + .detail-label {
  138 + color: #333;
  139 + font-size: 30rpx;
  140 + }
  141 + .detail-value {
  142 + color: #666;
  143 + font-size: 28rpx;
  144 + margin-left: 30rpx;
  145 + }
  146 + }
  147 + }
  148 +}
  149 +</style>
1 -<template>  
2 - <view class="alert-page">  
3 - <view style="width: 192rpx;margin: 19rpx;"><u-button @click="openSearchDialog" shape="circle" type="info" icon="search" text="筛选"></u-button></view>  
4 - <!-- 公共组件-每个页面必须引入 -->  
5 - <public-module></public-module>  
6 - <view class="device-list">  
7 - <view @click="openAlertDetail(item.id)" class="list-item" v-for="(item, index) in list" :key="index">  
8 - <view class="u-flex item" style="margin-top: 48rpx;justify-content: flex-start;flex-direction: column;align-items: center;">  
9 - <view style="width: 400rpx;text-align: left;">  
10 - <text style="color:#333333;font-size: 15px;">{{ item.name1 }}</text>  
11 - </view>  
12 - <view style="width: 400rpx;text-align: left;">  
13 - <text style="color:#666666;font-size: 15px;">{{ item.name2 }}</text>  
14 - </view>  
15 - <view style="width: 400rpx;text-align: left;">  
16 - <text style="color:#999999;font-size: 15px;">{{ item.time }}</text>  
17 - </view>  
18 - </view>  
19 - <view class="item">  
20 - <view class="u-flex" style="margin-top: 28rpx;flex-direction: column;justify-content: space-between;">  
21 - <view style="text-align:center;line-height:30rpx;width: 100rpx;height: 40rpx;background-color: #377DFF;">  
22 - <text style="color: #FFFFFF;font-size: 11px;">{{ item.name3 }}</text>  
23 - </view>  
24 - <view style="text-align:center;line-height:30rpx;margin-top: 10rpx;width: 100rpx;height: 40rpx;background-color: #377DFF;">  
25 - <text style="color: #FFFFFF;font-size: 11px;">{{ item.name4 }}</text>  
26 - </view>  
27 - </view>  
28 - </view>  
29 - </view>  
30 - </view>  
31 - <view style="height: 20rpx;"></view>  
32 - <!-- 告警筛选 -->  
33 - <u-popup @close="close" closeable bgColor="transparent" :overlay="true" :show="show" mode="bottom">  
34 - <view style="height: 1100rpx;background:#FFFFFF;border-radius: 20rpx;overflow-y: scroll;">  
35 - <view style="text-align: center;position: relative;top: 68rpx;margin-top: -40rpx;"><text style="font-size: 16px;color: #333333;">筛选条件</text></view>  
36 - <view style="margin-top: 97rpx;margin-left: 43rpx;">  
37 - <view style="width: 750rpx;margin-left: 14rpx;" class=""><text style="color: #333333;font-size: 14px;">告警状态</text></view>  
38 - <view  
39 - class="u-flex"  
40 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;flex-direction: row;  
41 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
42 - >  
43 - <view  
44 - v-for="(item, index) in alertStatus"  
45 - :key="index"  
46 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
47 - width:180rpx;height: 60rpx;  
48 - background-color:#F6F6F6;border-radius:32px"  
49 - >  
50 - <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>  
51 - </view>  
52 - </view>  
53 - </view>  
54 - <view style="margin-top: 145rpx;margin-left: 43rpx;">  
55 - <view style="width: 750rpx;margin-left: 14rpx;" class=""><text style="color: #333333;font-size: 14px;">设备类型</text></view>  
56 - <view  
57 - class="u-flex"  
58 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;flex-direction: row;  
59 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
60 - >  
61 - <view  
62 - v-for="(item, index) in deviceType"  
63 - :key="index"  
64 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
65 - width:180rpx;height: 60rpx;  
66 - background-color:#F6F6F6;border-radius:32px"  
67 - >  
68 - <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>  
69 - </view>  
70 - </view>  
71 - </view>  
72 - <view style="margin-top: 136rpx;margin-left: 43rpx;">  
73 - <view style="width: 750rpx;margin-left: 14rpx;" class=""><text style="color: #333333;font-size: 14px;">告警等级</text></view>  
74 - <view  
75 - class="u-flex"  
76 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;flex-direction: row;  
77 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
78 - >  
79 - <view  
80 - v-for="(item, index) in alertLevel"  
81 - :key="index"  
82 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
83 - width:180rpx;height: 60rpx;  
84 - background-color:#F6F6F6;border-radius:32px"  
85 - >  
86 - <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>  
87 - </view>  
88 - </view>  
89 - </view>  
90 - <view style="margin-top: 136rpx;margin-left: 43rpx;">  
91 - <view style="width: 750rpx;margin-left: 14rpx;" class=""><text style="color: #333333;font-size: 14px;">选择时间</text></view>  
92 - <view  
93 - class="u-flex"  
94 - style="margin-top: 15rpx;width:650rpx;height: 60rpx;flex-direction: row;  
95 - flex-wrap: wrap;justify-content: space-between; align-content: space-between;"  
96 - >  
97 - <view  
98 - v-for="(item, index) in timeArea"  
99 - :key="index"  
100 - style="margin: 10rpx;line-height: 50rpx;text-align: center;  
101 - width:180rpx;height: 60rpx;  
102 - background-color:#F6F6F6;border-radius:32px"  
103 - >  
104 - <text style="color:#333333;font-size: 13px;">{{ item.name }}</text>  
105 - </view>  
106 - </view>  
107 - </view>  
108 - <view style="margin-top: 136rpx;margin-left: 43rpx;">  
109 - <view class="u-flex" style="margin-left: 10rpx;margin-top: 15rpx;width:750rpx;height: 60rpx;flex-direction: row;">  
110 - <u--form labelPosition="left" :model="timeData" :rules="rules" ref="form1" style="padding-left: 26rpx;width: 617rpx!important;">  
111 - <u-form-item  
112 - style="font-size: 14px;"  
113 - label="选择日期"  
114 - prop="selectTime"  
115 - labelWidth="80"  
116 - borderBottom  
117 - @click="  
118 - showCalendar = true;  
119 - hideKeyboard();  
120 - "  
121 - >  
122 - <u--input v-model="timeData.selectTime" placeholder="请选择日期" border="none"></u--input>  
123 - </u-form-item>  
124 - </u--form>  
125 - </view>  
126 - </view>  
127 - <view class="u-flex" style="flex-direction: row;margin-top: 128rpx;margin-left: 55rpx;">  
128 - <view style="width: 300rpx"><u-button type="info" shape="circle" text="重置"></u-button></view>  
129 - <view style="width: 300rpx;margin-left:46rpx ;"><u-button type="primary" shape="circle" text="确认"></u-button></view>  
130 - </view>  
131 - <view style="height: 30rpx;"></view>  
132 - </view>  
133 - </u-popup>  
134 - <u-calendar  
135 - :show="showCalendar"  
136 - mode="range"  
137 - @confirm="calendarConfirm"  
138 - @close="calendarClose"  
139 - startText="开始时间"  
140 - endText="结束时间"  
141 - confirmDisabledText="请选择日期"  
142 - :formatter="formatter"  
143 - ></u-calendar>  
144 -  
145 - </view>  
146 -</template>  
147 -  
148 -<script>  
149 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
150 -  
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 - show: false,  
164 - alertStatus: [  
165 - {  
166 - index: 1,  
167 - name: '全部',  
168 - bgColor: '#377DFF',  
169 - textColor: '#377DFF'  
170 - },  
171 - {  
172 - index: 2,  
173 - name: '激活未确认',  
174 - bgColor: '#F6F6F6',  
175 - textColor: '#F6F6F6'  
176 - },  
177 - {  
178 - index: 3,  
179 - name: '激活已确认',  
180 - bgColor: '#F6F6F6',  
181 - textColor: '#F6F6F6'  
182 - },  
183 - {  
184 - index: 4,  
185 - name: '清除未确认',  
186 - bgColor: '#F6F6F6',  
187 - textColor: '#F6F6F6'  
188 - },  
189 - {  
190 - index: 5,  
191 - name: '清除已确认',  
192 - bgColor: '#F6F6F6',  
193 - textColor: '#F6F6F6'  
194 - },  
195 - {  
196 - index: 6,  
197 - name: '清除已确认',  
198 - bgColor: '#F6F6F6',  
199 - textColor: '#F6F6F6'  
200 - }  
201 - ],  
202 - deviceType: [  
203 - {  
204 - index: 1,  
205 - name: '全部',  
206 - bgColor: '#377DFF',  
207 - textColor: '#377DFF'  
208 - },  
209 - {  
210 - index: 2,  
211 - name: '网关设备',  
212 - bgColor: '#F6F6F6',  
213 - textColor: '#F6F6F6'  
214 - },  
215 - {  
216 - index: 3,  
217 - name: '网关子设备',  
218 - bgColor: '#F6F6F6',  
219 - textColor: '#F6F6F6'  
220 - },  
221 - {  
222 - index: 4,  
223 - name: '直连设备',  
224 - bgColor: '#F6F6F6',  
225 - textColor: '#F6F6F6'  
226 - }  
227 - ],  
228 - alertLevel: [  
229 - {  
230 - index: 1,  
231 - name: '全部',  
232 - bgColor: '#377DFF',  
233 - textColor: '#377DFF'  
234 - },  
235 - {  
236 - index: 2,  
237 - name: '危险',  
238 - bgColor: '#F6F6F6',  
239 - textColor: '#F6F6F6'  
240 - },  
241 - {  
242 - index: 3,  
243 - name: '重要',  
244 - bgColor: '#F6F6F6',  
245 - textColor: '#F6F6F6'  
246 - },  
247 - {  
248 - index: 4,  
249 - name: '次要',  
250 - bgColor: '#F6F6F6',  
251 - textColor: '#F6F6F6'  
252 - },  
253 - {  
254 - index: 4,  
255 - name: '警告',  
256 - bgColor: '#F6F6F6',  
257 - textColor: '#F6F6F6'  
258 - },  
259 - {  
260 - index: 4,  
261 - name: '不确定',  
262 - bgColor: '#F6F6F6',  
263 - textColor: '#F6F6F6'  
264 - }  
265 - ],  
266 - timeArea: [  
267 - {  
268 - index: 1,  
269 - name: '全部',  
270 - value: '全部',  
271 - bgColor: '#F6F6F6',  
272 - textColor: '#F6F6F6'  
273 - },  
274 - {  
275 - index: 2,  
276 - name: '30分钟',  
277 - value: '30',  
278 - bgColor: '#F6F6F6',  
279 - textColor: '#F6F6F6'  
280 - },  
281 - {  
282 - index: 3,  
283 - name: '1小时',  
284 - value: '30',  
285 - bgColor: '#F6F6F6',  
286 - textColor: '#F6F6F6'  
287 - },  
288 - {  
289 - index: 4,  
290 - name: '2小时',  
291 - value: '120',  
292 - bgColor: '#F6F6F6',  
293 - textColor: '#F6F6F6'  
294 - },  
295 - {  
296 - index: 5,  
297 - name: '近一天',  
298 - value: '24',  
299 - bgColor: '#F6F6F6',  
300 - textColor: '#F6F6F6'  
301 - },  
302 - {  
303 - index: 6,  
304 - name: '',  
305 - value: '',  
306 - bgColor: '#F6F6F6',  
307 - textColor: '#F6F6F6'  
308 - }  
309 - ],  
310 - list: [  
311 - {  
312 - name1: '1号楼1楼三单元水表',  
313 - name2: '下发命令:MQTT命令',  
314 - time: '2022-04-01 02:12:23',  
315 - id: 'xx1',  
316 - name3: '下发成功',  
317 - name4: '响应成功'  
318 - },  
319 - {  
320 - name1: '1号楼1楼三单元水表',  
321 - name2: '下发命令:MQTT命令',  
322 - time: '2022-04-01 02:12:23',  
323 - id: 'xx1',  
324 - name3: '下发成功',  
325 - name4: '响应成功'  
326 - },  
327 - {  
328 - name1: '1号楼1楼三单元水表',  
329 - name2: '下发命令:MQTT命令',  
330 - time: '2022-04-01 02:12:23',  
331 - id: 'xx1',  
332 - name3: '下发成功',  
333 - name4: '响应成功'  
334 - },  
335 - {  
336 - name1: '1号楼1楼三单元水表',  
337 - name2: '下发命令:MQTT命令',  
338 - time: '2022-04-01 02:12:23',  
339 - id: 'xx1',  
340 - name3: '下发成功',  
341 - name4: '响应成功'  
342 - },  
343 - {  
344 - name1: '1号楼1楼三单元水表',  
345 - name2: '下发命令:MQTT命令',  
346 - time: '2022-04-01 02:12:23',  
347 - id: 'xx1',  
348 - name3: '下发成功',  
349 - name4: '响应成功'  
350 - }  
351 - ]  
352 - };  
353 - },  
354 - onLoad(e) {  
355 - // 隐藏原生的tabbar  
356 - uni.hideTabBar();  
357 - },  
358 - methods: {  
359 - open() {},  
360 - close() {  
361 - this.show = false;  
362 - },  
363 - openSearchDialog() {  
364 - this.show = true;  
365 - },  
366 - hideKeyboard() {  
367 - uni.hideKeyboard();  
368 - },  
369 - calendarConfirm(e) {  
370 - this.showCalendar = false;  
371 - this.timeData.selectTime = `${e[0]} / ${e[e.length - 1]}`;  
372 - },  
373 - calendarClose() {  
374 - this.showCalendar = false;  
375 - }  
376 - }  
377 -};  
378 -</script>  
379 -  
380 -<style lang="scss" scoped>  
381 -.alert-page {  
382 - margin-top: 5rpx;  
383 -}  
384 -.device-list {  
385 - display: flex;  
386 - flex-direction: column;  
387 - padding-left: 18rpx;  
388 - .list-item {  
389 - width: 713rpx;  
390 - height: 233rpx;  
391 - background-color: #fff;  
392 - margin-top: 24rpx;  
393 - display: flex;  
394 - flex-direction: row;  
395 - border-radius: 10px;  
396 - justify-content: space-between;  
397 - .item {  
398 - margin: 30rpx;  
399 - }  
400 - }  
401 -}  
402 -</style>  
@@ -20,7 +20,13 @@ @@ -20,7 +20,13 @@
20 </u-form-item> 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> 21 <u-form-item @click="openType"><u-input shape="circle" v-model="timeData.getType" placeholder="请选择属性" disabled disabledColor="#377DFF0D" /></u-form-item>
22 </u-form> 22 </u-form>
23 - <view class="charts-box"><qiun-data-charts type="area" :chartData="chartData" :opts="{ xAxis: { disabled: true }, legend: { show: false } }" /></view> 23 + <view class="charts-box" v-if="historyData.length"><qiun-data-charts type="area" :chartData="chartData" :opts="{ xAxis: { disabled: true }, legend: { show: false } }" /></view>
  24 + <view v-else style="display: flex;justify-content: center; align-items: center;">
  25 + <view>
  26 + <image src="../../../static/empty.png" style="width: 160rpx;height: 160rpx;" />
  27 + <view style="text-align: center; color:#e8e8e8;padding-bottom: 30rpx;">暂无数据</view>
  28 + </view>
  29 + </view>
24 </view> 30 </view>
25 <view class="historyData-bottom"> 31 <view class="historyData-bottom">
26 <view class="table"> 32 <view class="table">
@@ -28,10 +34,16 @@ @@ -28,10 +34,16 @@
28 <view class="th">变量值</view> 34 <view class="th">变量值</view>
29 <view class="th">更新时间</view> 35 <view class="th">更新时间</view>
30 </view> 36 </view>
31 - <view class="tr bg-g" v-for="(item, index) in historyData" :key="index"> 37 + <view class="tr bg-g" :class="{ odd: index % 2 === 1 }" v-for="(item, index) in historyData" :key="index">
32 <view class="td">{{ item.value }}</view> 38 <view class="td">{{ item.value }}</view>
33 <view class="td">{{ item.ts }}</view> 39 <view class="td">{{ item.ts }}</view>
34 </view> 40 </view>
  41 + <view v-if="!historyData.length" style="display: flex;justify-content: center">
  42 + <view>
  43 + <image src="../../../static/empty.png" style="width: 160rpx;height: 160rpx;" />
  44 + <view style="text-align: center; color:#e8e8e8;padding-bottom: 30rpx;">暂无数据</view>
  45 + </view>
  46 + </view>
35 </view> 47 </view>
36 </view> 48 </view>
37 <u-calendar 49 <u-calendar
@@ -64,7 +76,7 @@ @@ -64,7 +76,7 @@
64 <script> 76 <script>
65 import fTabbar from '@/components/module/f-tabbar/f-tabbar'; 77 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'; 78 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'; 79 +import { getHistroyData } from '../api/index.js';
68 import { formatToDate } from '@/plugins/utils.js'; 80 import { formatToDate } from '@/plugins/utils.js';
69 const d = new Date(); 81 const d = new Date();
70 const year = d.getFullYear(); 82 const year = d.getFullYear();
@@ -100,12 +112,20 @@ export default { @@ -100,12 +112,20 @@ export default {
100 entityId: { 112 entityId: {
101 type: String, 113 type: String,
102 required: true 114 required: true
  115 + },
  116 + start: {
  117 + type: String,
  118 + required: true
  119 + },
  120 + end: {
  121 + type: String,
  122 + required: true
103 } 123 }
104 }, 124 },
105 data() { 125 data() {
106 return { 126 return {
107 - startTs: '',  
108 - endTs: '', 127 + startTs: this.start,
  128 + endTs: this.end,
109 showCalendar: false, 129 showCalendar: false,
110 showTimeGap: false, 130 showTimeGap: false,
111 showSelectType: false, 131 showSelectType: false,
@@ -156,10 +176,21 @@ export default { @@ -156,10 +176,21 @@ export default {
156 } 176 }
157 }; 177 };
158 }, 178 },
159 - onReady() {  
160 - setTimeout(() => {  
161 - console.log(this.chartData);  
162 - }); 179 + watch: {
  180 + historyData(newValue) {
  181 + if (!newValue.length) {
  182 + this.chartData.categories = [];
  183 + this.chartData.series = [];
  184 + } else {
  185 + this.chartData.categories = newValue.map(item => item.ts);
  186 + this.chartData.series = [
  187 + {
  188 + name: this.keys[0][0],
  189 + data: this.historyData.map(item => Number(item.value))
  190 + }
  191 + ];
  192 + }
  193 + }
163 }, 194 },
164 methods: { 195 methods: {
165 // 动态生成Columns 196 // 动态生成Columns
1 -<template>  
2 - <view class="realtime-page">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module></public-module>  
5 - <view class="u-flex" style="margin-top: -44rpx;flex-direction: column;justify-content: space-between; align-content: space-between;">  
6 - <view  
7 - class="u-flex"  
8 - v-for="(item, index) in list"  
9 - :key="index"  
10 - style="border-radius: 20px;flex-direction: row;justify-content: space-between;margin: 15rpx;  
11 - background-color: #fff;height: 200rpx;width: 698rpx;"  
12 - >  
13 - <view style="margin: 20rpx;">  
14 - <view style="margin-top: 4rpx;">  
15 - <text style="color:#333333;font-size: 16px;">{{ item.name }}</text>  
16 - </view>  
17 - <view style="margin-top: 14rpx;">  
18 - <text style="color:#999999;font-size: 13px;">{{ item.time }}</text>  
19 - </view>  
20 - </view>  
21 - <view style="margin-right: 30rpx;margin-top: -58rpx;">  
22 - <text style="color:#333333;font-size: 17px;">{{ item.value }}</text>  
23 - </view>  
24 - </view>  
25 - </view>  
26 - </view>  
27 -</template>  
28 -  
29 -<script>  
30 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
31 -export default {  
32 - components: {  
33 - fTabbar  
34 - },  
35 - data() {  
36 - return {  
37 - list: [  
38 - {  
39 - name: 'CO2',  
40 - time: '2021-12-25 14:25:52',  
41 - value: '85.6'  
42 - },  
43 - {  
44 - name: 'PH',  
45 - time: '2021-12-25 14:25:52',  
46 - value: '10'  
47 - },  
48 - {  
49 - name: 'NH3',  
50 - time: '2021-12-25 14:25:52',  
51 - value: '635'  
52 - },  
53 - {  
54 - name: '水深',  
55 - time: '2021-12-25 14:25:52',  
56 - value: '2.21'  
57 - }  
58 - ]  
59 - };  
60 - },  
61 - onLoad(e) {  
62 - // 隐藏原生的tabbar  
63 - uni.hideTabBar();  
64 - }  
65 -};  
66 -</script>  
67 -  
68 -<style lang="scss" scoped>  
69 -.realtime-page {  
70 - padding: 20rpx;  
71 -} 1 +<template>
  2 + <view class="realtime-page">
  3 + <view class="item" v-for="(item, index) in recordList" :key="index">
  4 + <view class="item-top">
  5 + <view>{{ item.key }}</view>
  6 + <view>{{ item.value }}</view>
  7 + </view>
  8 + <view class="item-time">{{ item.time }}</view>
  9 + </view>
  10 + </view>
  11 +</template>
  12 +
  13 +<script>
  14 +export default {
  15 + props: {
  16 + recordList: {
  17 + type: Array,
  18 + default: () => []
  19 + }
  20 + }
  21 +};
  22 +</script>
  23 +
  24 +<style lang="scss" scoped>
  25 +.realtime-page {
  26 + .item {
  27 + margin: 30rpx;
  28 + padding: 30rpx;
  29 + border-radius: 20rpx;
  30 + background-color: #fff;
  31 + height: 160rpx;
  32 + width: 690rpx;
  33 + .item-top {
  34 + display: flex;
  35 + justify-content: space-between;
  36 + color: #333;
  37 + font-size: 32rpx;
  38 + font-family: PingFangSC-Medium, PingFang SC;
  39 + font-weight: 500;
  40 + }
  41 + .item-time {
  42 + margin-top: 4rpx;
  43 + font-size: 26rpx;
  44 + color: #999;
  45 + }
  46 + }
  47 +}
72 </style> 48 </style>
@@ -3,10 +3,7 @@ @@ -3,10 +3,7 @@
3 "version": "1.0.0", 3 "version": "1.0.0",
4 "description": "### 项目结构", 4 "description": "### 项目结构",
5 "main": "main.js", 5 "main": "main.js",
6 - "scripts": {  
7 - "test": "echo \"Error: no test specified\" && exit 1",  
8 - "dev:mp-wenxin": "cross-env NODE_ENV=development UNI_PLATFORM=mp-weixin vue-cli-service uni-build --watch --minimize"  
9 - }, 6 + "scripts": {},
10 "repository": { 7 "repository": {
11 "type": "git", 8 "type": "git",
12 "url": "http://git.yuntengiot.com/huang/thingskit-app.git" 9 "url": "http://git.yuntengiot.com/huang/thingskit-app.git"
@@ -14,12 +14,6 @@ @@ -14,12 +14,6 @@
14 "navigationBarTitleText": "设备" 14 "navigationBarTitleText": "设备"
15 } 15 }
16 }, 16 },
17 - // {  
18 - // "path": "pages/device/deviceDetail",  
19 - // "style": {  
20 - // "navigationBarTitleText": "设备详情"  
21 - // }  
22 - // },  
23 { 17 {
24 "path": "pages/device/org/org", 18 "path": "pages/device/org/org",
25 "style": { 19 "style": {
@@ -85,6 +79,12 @@ @@ -85,6 +79,12 @@
85 "style": { 79 "style": {
86 "navigationBarTitleText": "设备详情" 80 "navigationBarTitleText": "设备详情"
87 } 81 }
  82 + },
  83 + {
  84 + "path": "deviceDetailPage/tabDetail/CommandDetail",
  85 + "style": {
  86 + "navigationBarTitleText": "命令详情"
  87 + }
88 }] 88 }]
89 }, 89 },
90 { 90 {
1 <template> 1 <template>
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=" 2 + <view class="device-page">
  3 + <f-navbar>
  4 + <view slot="left">
  5 + <view style="width: 580rpx"><u--input prefixIcon="search" placeholder="输入设备SN或名称搜索" border="surround" shape="circle" @change="inputChanged"></u--input></view>
  6 + </view>
  7 + <view @click="openSearchDialog" slot="right" class="u-flex">
  8 + <text style="color: #333; font-size: 14px">筛选</text>
  9 + <image style="width: 40rpx; height: 40rpx" src="../../static/shaixuan.png" />
  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
  24 + style="
49 width: 6px; 25 width: 6px;
50 height: 10px; 26 height: 10px;
51 float: right; 27 float: right;
52 margin-right: 34rpx; 28 margin-right: 34rpx;
53 margin-top: 58rpx; 29 margin-top: 58rpx;
54 " 30 "
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=" 31 + src="../../static/right-arrow.png"
  32 + />
  33 + </view>
  34 + </view>
  35 + <mescroll-body ref="mescrollRef" @init="mescrollInit" :down="downOption" @down="downCallback" @up="upCallback">
  36 + <view class="device-list">
  37 + <view @click="openDeviceDetail(item.id, item.alarmStatus, item.lastOnlineTime, item.tbDeviceId)" class="list-item" v-for="item in list" :key="item.id">
  38 + <view
  39 + class="u-flex item"
  40 + style="
83 justify-content: flex-start; 41 justify-content: flex-start;
84 flex-direction: column; 42 flex-direction: column;
85 align-items: center; 43 align-items: center;
86 " 44 "
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=" 45 + >
  46 + <view style="width: 450rpx; text-align: left">
  47 + <text style="color: #333; font-size: 15px">{{ item.name }}</text>
  48 + </view>
  49 + <view style="width: 450rpx; text-align: left; margin-top: 10rpx">
  50 + <view style="color: #666; font-size: 15px;display: flex;">
  51 + 设备编号:
  52 + <view style="margin-left:16rpx">{{ item.sn }}</view>
  53 + </view>
  54 + </view>
  55 + <view style="width: 450rpx; text-align: left; margin-top: 10rpx">
  56 + <view style="color: #666; font-size: 15px;display: flex;">
  57 + 所属组织:
  58 + <view style="margin-left:16rpx">{{ item.organizationDTO.name }}</view>
  59 + </view>
  60 + </view>
  61 + </view>
  62 + <view class="item">
  63 + <view class="u-flex" style="margin-top: -6rpx">
  64 + <image
  65 + style="
110 width: 30rpx; 66 width: 30rpx;
111 height: 30rpx; 67 height: 30rpx;
112 margin-top: 5rpx; 68 margin-top: 5rpx;
113 margin-right: 5rpx; 69 margin-right: 5rpx;
114 " 70 "
115 - :src="  
116 - item.deviceState === 'ONLINE'  
117 - ? '../../static/online.png'  
118 - : item.deviceState === 'INACTIVE'  
119 - ? '../../static/secondary.png'  
120 - : '../../static/baojing.png'  
121 - "  
122 - /> 71 + :src="item.deviceState === 'ONLINE' ? '../../static/online.png' : item.deviceState === 'INACTIVE' ? '../../static/unonline.png' : '../../static/baojing.png'"
  72 + />
123 73
124 - <view>  
125 - <text  
126 - style=" 74 + <view>
  75 + <text
  76 + style="
127 color: #377dff; 77 color: #377dff;
128 font-size: 13px; 78 font-size: 13px;
129 margin-left: 5rpx; 79 margin-left: 5rpx;
130 margin-top: 20rpx; 80 margin-top: 20rpx;
131 " 81 "
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 - > 82 + :style="{ color: item.deviceState === 'ONLINE' ? '#377DFF' : item.deviceState === 'INACTIVE' ? '#666666' : '#DE4437' }"
  83 + >
  84 + {{ item.deviceState === 'ONLINE' ? '在线' : item.deviceState === 'INACTIVE' ? '待激活' : '离线' }}
  85 + </text>
  86 + </view>
  87 + </view>
  88 + </view>
  89 + </view>
  90 + </view>
  91 + </mescroll-body>
  92 + <!-- 设备筛选 -->
  93 + <u-popup @close="close" closeable bgColor="#fff" :show="show" mode="bottom" :round="20">
  94 + <view>
  95 + <view style="text-align: center; margin-top: 28rpx"><text>筛选条件</text></view>
160 96
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> 97 + <FilterItem :filterList="deviceStatus" title="设备状态" @clickTag="currentIndex => handleClickTag(currentIndex, deviceStatus)"></FilterItem>
  98 + <FilterItem :filterList="alarmStatus" title="告警状态" @clickTag="currentIndex => handleClickTag(currentIndex, alarmStatus)"></FilterItem>
  99 + <FilterItem :filterList="typeStatus" title="设备类型" @clickTag="currentIndex => handleClickTag(currentIndex, typeStatus)"></FilterItem>
  100 + <view class="u-flex" style="margin-top: 40rpx; margin-left: 55rpx">
  101 + <view style="width: 300rpx"><u-button type="info" shape="circle" text="重置" @click="resetFilter"></u-button></view>
  102 + <view style="width: 300rpx; margin-left: 46rpx"><u-button type="primary" shape="circle" text="确认" @click="confirmFilter"></u-button></view>
  103 + </view>
  104 + </view>
  105 + </u-popup>
  106 + <f-tabbar></f-tabbar>
  107 + </view>
202 </template> 108 </template>
203 109
204 <script> 110 <script>
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"; 111 +import fTabbar from '@/components/module/f-tabbar/f-tabbar';
  112 +import fNavbar from '@/components/module/f-navbar/f-navbar';
  113 +import FilterItem from './FilterItem.vue';
  114 +import MescrollMixin from '@/uni_modules/mescroll-uni/components/mescroll-uni/mescroll-mixins.js';
  115 +import { debounce } from '@/plugins/throttle.js';
210 export default { 116 export default {
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 - }, 117 + mixins: [MescrollMixin], // 使用mixin (在main.js注册全局组件)
  118 + components: {
  119 + fTabbar,
  120 + fNavbar,
  121 + FilterItem
  122 + },
  123 + data() {
  124 + return {
  125 + downOption: {
  126 + auto: false //是否在初始化后,自动执行downCallback; 默认true
  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'
  161 + },
  162 + {
  163 + checked: false,
  164 + name: '正常',
  165 + type: '0'
  166 + }
  167 + ],
  168 + typeStatus: [
  169 + {
  170 + checked: true,
  171 + name: '全部',
  172 + type: ''
  173 + },
  174 + {
  175 + checked: false,
  176 + name: '直连设备',
  177 + type: 'DIRECT_CONNECTION'
  178 + },
  179 + {
  180 + checked: false,
  181 + name: '网关设备',
  182 + type: 'GATEWAY'
  183 + },
  184 + {
  185 + checked: false,
  186 + name: '网关子设备',
  187 + type: 'SENSOR'
  188 + }
  189 + ],
  190 + total: 0,
  191 + list: [],
  192 + page: {
  193 + num: 0,
  194 + size: 10
  195 + }
  196 + };
  197 + },
  198 + onLoad() {
  199 + // 隐藏原生的tabbar
  200 + uni.hideTabBar();
  201 + },
  202 + onShow() {
  203 + if (this.orgId) {
  204 + this.loadData(1, {
  205 + organizationId: this.orgId
  206 + });
  207 + }
  208 + },
  209 + methods: {
  210 + /*下拉刷新的回调 */
  211 + downCallback() {
  212 + //联网加载数据
  213 + this.list = [];
  214 + this.page.num = 1;
  215 + //联网加载数据
  216 + this.loadData(this.page.num);
  217 + },
  218 +
  219 + /*上拉加载的回调: 其中page.num:当前页 从1开始, page.size:每页数据条数,默认10 */
  220 + upCallback() {
  221 + //联网加载数据
  222 + this.page.num += 1;
  223 + this.loadData(this.page.num);
  224 + },
311 225
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 - }, 226 + //获取设备
  227 + loadData(pageNo, params = {}) {
  228 + let httpData = {
  229 + page: pageNo,
  230 + pageSize: 10,
  231 + ...params
  232 + };
  233 + uni.$u.http
  234 + .get('/yt/device', {
  235 + params: httpData,
  236 + custom: {
  237 + load: false
  238 + }
  239 + })
  240 + .then(res => {
  241 + this.total = res.total;
  242 + uni.stopPullDownRefresh();
  243 + console.log('获取后端数据', res);
  244 + //方法一(推荐): 后台接口有返回列表的总页数 totalPage
  245 + this.mescroll.endByPage(res.items.length, res.total); //必传参数(当前页的数据个数, 总页数)
  246 + if (pageNo == 1) {
  247 + this.list = res.items;
  248 + } else {
  249 + this.list = this.list.concat(res.items);
  250 + }
  251 + })
  252 + .catch(() => {
  253 + //联网失败, 结束加载
  254 + this.mescroll.endErr();
  255 + });
  256 + },
  257 + openOrg() {
  258 + uni.navigateTo({
  259 + url: './org/org'
  260 + });
  261 + },
  262 + close() {
  263 + this.resetFilter();
  264 + this.show = false;
  265 + },
  266 + openSearchDialog() {
  267 + this.show = true;
  268 + },
  269 + openDeviceDetail(id, alarmStatus, lastOnlineTime, tbDeviceId) {
  270 + uni.navigateTo({
  271 + url: `/deviceSubPage/deviceDetailPage/deviceDetail?id=${id}&alarmStatus=${alarmStatus}&lastOnlineTime=${lastOnlineTime}&tbDeviceId=${tbDeviceId}`
  272 + });
  273 + },
  274 + handleClickTag(currentIndex, list) {
  275 + list.map((item, index) => {
  276 + item.checked = index === currentIndex;
  277 + });
  278 + },
  279 + resetFilter() {
  280 + const { deviceStatus, alarmStatus, typeStatus } = this;
  281 + [deviceStatus, alarmStatus, typeStatus].forEach(item => item.map((item, index) => (item.checked = index === 0)));
  282 + },
  283 + confirmFilter() {
  284 + const deviceState = this.deviceStatus.find(item => item.checked);
  285 + const alarmStatus = this.alarmStatus.find(item => item.checked);
  286 + const deviceType = this.typeStatus.find(item => item.checked);
  287 + this.loadData(1, {
  288 + deviceState: deviceState.type ? deviceState.type : undefined,
  289 + deviceType: deviceType.type ? deviceType.type : undefined,
  290 + alarmStatus: alarmStatus.type === '0' || alarmStatus.type === '1' ? alarmStatus.type : undefined
  291 + });
  292 + this.show = false;
  293 + },
  294 + inputChanged: debounce(function(name) {
  295 + this.loadData(1, {
  296 + name
  297 + });
  298 + }, 500)
  299 + }
391 }; 300 };
392 </script> 301 </script>
393 302
394 <style lang="scss" scoped> 303 <style lang="scss" scoped>
395 .device-page { 304 .device-page {
396 - min-height: 100vh;  
397 - background-color: #f8f9fa; 305 + min-height: 100vh;
  306 + background-color: #f8f9fa;
398 } 307 }
399 308
400 .org-sty { 309 .org-sty {
401 - width: 750rpx;  
402 - height: 150rpx;  
403 - margin-top: 1rpx;  
404 - background-color: #fff;  
405 - display: flex;  
406 - justify-content: space-between; 310 + width: 750rpx;
  311 + height: 150rpx;
  312 + margin-top: 1rpx;
  313 + background-color: #fff;
  314 + display: flex;
  315 + justify-content: space-between;
407 316
408 - .org-item {  
409 - width: 350rpx;  
410 - height: 200rpx;  
411 - } 317 + .org-item {
  318 + width: 350rpx;
  319 + height: 200rpx;
  320 + }
412 } 321 }
413 322
414 .device-list { 323 .device-list {
415 - display: flex;  
416 - flex-direction: column;  
417 - padding-left: 20rpx; 324 + display: flex;
  325 + flex-direction: column;
  326 + padding-left: 20rpx;
418 327
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; 328 + .list-item {
  329 + width: 713rpx;
  330 + height: 200rpx;
  331 + background-color: #fff;
  332 + margin-top: 24rpx;
  333 + display: flex;
  334 + border-radius: 10px;
  335 + justify-content: space-between;
427 336
428 - .item {  
429 - margin: 30rpx;  
430 - }  
431 - } 337 + .item {
  338 + margin: 30rpx;
  339 + }
  340 + }
432 } 341 }
433 -</style> 342 +</style>
1 -<template>  
2 - <view class="org-content">  
3 - <!-- 公共组件-每个页面必须引入 -->  
4 - <public-module></public-module>  
5 - <view>  
6 - <luyj-tree @sendValue="confirm" :is-check="isCheck" search-placeholder="请输入搜索内容" :search-if="true" v-slot:default="{ item }" :max="max" :trees="tree" :nodes="false">  
7 - <view>  
8 - <view class="content-item">  
9 - <view class="word">{{ item.name }}</view>  
10 - </view>  
11 - </view>  
12 - </luyj-tree>  
13 - </view>  
14 - </view>  
15 -</template>  
16 -  
17 -<script>  
18 -import fTabbar from '@/components/module/f-tabbar/f-tabbar';  
19 -import { transOrgFunc } from '@/config/common.js';  
20 -export default {  
21 - components: {  
22 - fTabbar  
23 - },  
24 - data() {  
25 - return {  
26 - isCheck: true, // 是否可选  
27 - tree: [],  
28 - max: 5,  
29 - id: ''  
30 - };  
31 - },  
32 - onLoad(e) {  
33 - // 隐藏原生的tabbar  
34 - uni.hideTabBar();  
35 - this.loadData();  
36 - },  
37 - methods: {  
38 - loadData() {  
39 - uni.$u.http  
40 - .get('/yt/organization/me/list')  
41 - .then(res => {  
42 - if (res) {  
43 - const list = transOrgFunc(res);  
44 - this.tree = list;  
45 - }  
46 - })  
47 - .catch(e => {  
48 - uni.$u.toast(e.data.message);  
49 - });  
50 - },  
51 - confirm(val) {  
52 - this.id = val[0].id;  
53 - let pages = getCurrentPages(); //获取所有页面栈实例列表  
54 - let nowPage = pages[pages.length - 1]; //当前页页面实例  
55 - let prevPage = pages[pages.length - 2]; //上一页页面实例  
56 - prevPage.$vm.orgId = this.id;  
57 - uni.navigateBack({  
58 - delta: 1  
59 - });  
60 - }  
61 - }  
62 -};  
63 -</script>  
64 -  
65 -<style lang="scss" scoped>  
66 -.org-content {  
67 - padding: 0 10rpx;  
68 -} 1 +<template>
  2 + <view class="org-content">
  3 + <!-- 公共组件-每个页面必须引入 -->
  4 + <public-module></public-module>
  5 + <view>
  6 + <luyj-tree @sendValue="confirm" :is-check="isCheck" search-placeholder="请输入搜索内容" :search-if="true" v-slot:default="{ item }" :max="max" :trees="tree" :nodes="false">
  7 + <view>
  8 + <view class="content-item">
  9 + <view class="word">{{ item.name }}</view>
  10 + </view>
  11 + </view>
  12 + </luyj-tree>
  13 + </view>
  14 + </view>
  15 +</template>
  16 +
  17 +<script>
  18 +import fTabbar from '@/components/module/f-tabbar/f-tabbar';
  19 +import { transOrgFunc } from '@/config/common.js';
  20 +export default {
  21 + components: {
  22 + fTabbar
  23 + },
  24 + data() {
  25 + return {
  26 + isCheck: true, // 是否可选
  27 + tree: [],
  28 + max: 5,
  29 + id: ''
  30 + };
  31 + },
  32 + onLoad(e) {
  33 + // 隐藏原生的tabbar
  34 + uni.hideTabBar();
  35 + this.loadData();
  36 + },
  37 + methods: {
  38 + loadData() {
  39 + uni.$u.http
  40 + .get('/yt/organization/me/list')
  41 + .then(res => {
  42 + if (res) {
  43 + const list = transOrgFunc(res);
  44 + this.tree = list;
  45 + }
  46 + })
  47 + .catch(e => {
  48 + uni.$u.toast(e.data.message);
  49 + });
  50 + },
  51 + confirm(val) {
  52 + this.id = val[0].id;
  53 + let pages = getCurrentPages(); //获取所有页面栈实例列表
  54 + let nowPage = pages[pages.length - 1]; //当前页页面实例
  55 + let prevPage = pages[pages.length - 2]; //上一页页面实例
  56 + prevPage.$vm.orgId = this.id;
  57 + uni.navigateBack({
  58 + delta: 1
  59 + });
  60 + }
  61 + }
  62 +};
  63 +</script>
  64 +
  65 +<style lang="scss" scoped>
  66 +.org-content {
  67 + padding: 0 10rpx;
  68 +}
69 </style> 69 </style>

1004 Bytes