2025-04-16 02:11:26 +01:00

368 lines
8.7 KiB
Vue
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<view class="dataAcquisition">
<u-search class="margin-top-20" placeholder="请输入设备名称" shape="square" :show-action="false" bg-color="#fff" :height="40" v-model="query.deviceName" @search="getDeviceList" @clear="getDeviceList"></u-search>
<!-- 设备数量统计 -->
<view class="padding-20 flex fdc aic font-size-25 font-color-l3 ">
<text class="font-style-italic margin-top-10">设备总数为{{total}}</text>
</view>
<!-- 设备列表 -->
<view v-if="deviceList.length>0" class="deviceList">
<view class="device" v-for="(item,index) in deviceList" :key="index" @click="jump(item)">
<image class="img" :src="baseUrl+item.src" mode=""></image>
<view class="info">
<view class="deviceName">{{item.deviceName}}</view>
<view class="number">设备编号:{{item.serialNumber}}</view>
</view>
<view class="flex aic font-size-24 width-120">
<view class="width-20 height-20 border-radius-15 margin-right-10" :style="{backgroundColor:statusColor(item.status)}">
</view>
{{item.status|statusName}}
</view>
</view>
</view>
<!-- 无数据控件 -->
<u-empty v-else mode="data" icon="https://cdn.uviewui.com/uview/empty/data.png"/>
<!-- 数据加载中控件 -->
<u-loading-page :loading="loading" loading-text="加载中..." style="z-index:999"></u-loading-page>
<!-- 快速返回顶部控件 top定义向下滚动多少距离显示rpxscrollTop向上返沪的距离用onPageScroll获取已经滚动的距离 -->
<u-back-top :scrollTop="scrollTop" top="50" icon="arrow-up"></u-back-top>
<!-- loadmore控件 -->
<u-loadmore :status="status" v-if="total>10"/>
</view>
</template>
<script>
import setting from '@/setting.js'
import sysTopics from '@/utils/sysTopics.js';
export default{
data() {
return {
//navbar标题
title:'数据采集',
//加载状态
loading:true,
status:'loadmore',
//返回的数据总条数
total:0,
//设备类标
deviceList:[],
//actionShett打开状态
show:false,
//地块列表
landList:[],
query:{
pageNum:1,
pageSize:10,
productId:null,
deviceName:''
},
scrollTop:0,
baseUrl:uni.$u.http.config.baseURL,
//因为公用页面这边根据传过来的产品ID过滤设备列表
productId:null
}
},
filters:{
statusName(val) {
switch (val) {
case 1:
return "未激活"
break;
case 2:
return "禁用"
break;
case 3:
return "在线"
break;
case 4:
return "离线"
break;
default:
break;
}
}
},
onLoad(option) {
//根据传过来的产品ID过滤设备列表同时设置导航的标题
if(JSON.stringify(option)!='{}'){
this.query.productId=option.productId
this.title=option.title;
}
//设置导航栏标题
uni.setNavigationBarTitle({
title:this.title
})
//加载设备数据
this.getDeviceList()
//连接mqtt
this.connectMqtt();
},
async onPullDownRefresh(){
//重置pageNum
this.query.pageNum=1
//查询设备数据
await this.getDeviceList()
//停止下拉刷新
uni.stopPullDownRefresh()
},
//触底
onReachBottom(){
this.status="loading"
this.pullUp()
},
//滚动
onPageScroll(e) {
this.scrollTop = e.scrollTop;
},
methods:{
//获取设备列表
async getDeviceList(){
const res = await uni.$u.http.get('/iot/device/list', {params: {...this.query,baseId:uni.getStorageSync('baseId')}})
this.deviceList=res.rows.map(item=>({
//是否摄像头
isCamera:item.isCamera,
//设备名称
deviceName:item.deviceName,
//设备ID
deviceId:item.deviceId,
//产品ID
productId:item.productId,
//产品名称呢个
productName:item.productName,
//转换产品的图片
src:item.imgUrl.split(",").length>1?item.imgUrl.split(",")[1]:item.imgUrl.split(",")[0],
//设备状态值
status:item.status,
//设备信号
rssi:item.rssi,
//设备序列号摄像头序列号为20位
serialNumber:item.serialNumber,
//是否支持设备影子
isShadow:item.isShadow
}))
this.total=res.total;
//快速返回顶部
uni.pageScrollTo({
scrollTop: 0,
duration: 100,
});
//加载状态设置为false
this.loading=false
},
//上拉加载
async pullUp(){
//计算共计多少页total返回的是总条数不是每页的条数
let totalPages = Math.ceil(this.total/10)
if(this.query.pageNum<totalPages){
this.query.pageNum++
const res = await uni.$u.http.get('/iot/device/list', {params: this.query})
this.deviceList=this.deviceList.concat(res.rows.map(item=>({
//是否摄像头
isCamera:item.isCamera,
//设备名称
deviceName:item.deviceName,
//设备ID
deviceId:item.deviceId,
//产品ID
productId:item.productId,
//产品名称呢个
productName:item.productName,
//转换产品的图片
src:item.imgUrl.split(",").length>1?item.imgUrl.split(",")[1]:item.imgUrl.split(",")[0],
//设备状态值
status:item.status,
//设备信号
rssi:item.rssi,
//设备序列号摄像头序列号为20位
serialNumber:item.serialNumber,
//是否支持设备影子
isShadow:item.isShadow
})));
this.total=res.total;
this.status="loadmore"
}else{
this.status="nomore"
}
},
//页面跳转
jump(data){
// console.log(data)
if(data.isCamera=='1'){
// #ifndef MP-WEIXIN
uni.$u.route({
url: 'pages/videoMonitor/videoPlay',
params: {
deviceId:data.deviceId,
deviceName:data.deviceName
}
})
// #endif
// #ifdef MP-WEIXIN
uni.$u.route({
url: setting.mpVideoMode == 'webView'?'pages/videoMonitor/webview':'pages/videoMonitor/videoPlay',
params: {
deviceId:data.deviceId,
deviceName:data.deviceName
}
})
// #endif
}else{
uni.$u.route({
url: 'pages/dataAcquisition/deviceDetail',
params: {
...data,
src:this.baseUrl+data.src
}
})
}
},
//mqtt连接和订阅
async connectMqtt() {
if (this.$mqttTool.client == null) {
await this.$mqttTool.connect();
}
this.mqttSubscribe();
this.mqttCallback();
},
//mqtt订阅主题
mqttSubscribe() {
const { device } = this;
//设备状态主题
let topicStatus ='/+' + '/+' + sysTopics.statusFetch;
let topics = [];
topics.push(topicStatus);
this.$mqttTool.subscribe(topics);
},
//mqtt回调
mqttCallback() {
this.$mqttTool.client.on('message', (topic, message, buffer) => {
let _topic = topic.split('/');
let _message = JSON.parse(message.toString());
if(_topic[1] && _topic[2] && _message.status){
this.deviceList.forEach(item=>{
//判断设备列表中的序列号和主题中的序列号是相等
if(item.serialNumber == _topic[2]){
item.status = _message.status;
}
})
}
});
},
//因为过滤器不支持style这边使用方法来根据status翻译颜色值
statusColor(val){
switch (val) {
case 1:
return "#e6a23c"
break;
case 2:
return "#F56C6C"
break;
case 3:
return "#2b7"
break;
case 4:
return "#808080"
break;
default:
break;
}
}
}
}
</script>
<style lang="scss" scoped>
.dataAcquisition{
padding:0 30rpx 30rpx 30rpx;
box-sizing: border-box;
/*#ifdef H5*/
height: calc(100vh - 44px);
/*#endif*/
// overflow: inherit;
// position: relative;
.select ::v-deep{
height:120rpx;
display: flex;
align-items: center;
background-color: #f3f4f6;
// margin-bottom: 10rpx;
position: sticky;
top: 0;
.u-input .u-input__content__field-wrapper__field{
height: 80rpx;
padding: 6px 9px;
box-sizing: border-box;
}
}
.deviceList{
.device{
display: flex;
align-items: center;
margin-bottom: 20rpx;
border-radius: 16rpx;
background-color: #fff;
padding: 30rpx 20rpx;
.img{
width: 70rpx;
height: 70rpx;
border-radius: 20rpx;
margin-right: 16rpx;
}
.info{
width: 70%;
margin-right: 16rpx;
.deviceName{
width: 100%;
overflow:hidden;
white-space: nowrap;
text-overflow: ellipsis;
font-weight: 900;
}
.number{
width: 100%;
font-size: 26rpx;
overflow:hidden;
white-space: nowrap;
text-overflow: ellipsis;
padding:10rpx 0;
color: #666;
}
}
}
}
.areaList{
.search{
width: 90%;
margin: 20rpx auto;
}
.selected{
height: 35vh;
overflow: auto;
.item{
padding: 0 50rpx;
display: flex;
justify-content: space-between;
height: 80rpx;
line-height: 80rpx;
position: relative;
&::after{
display: block;
content: '';
width: 100%;
height: 100%;
position: absolute;
left: 0;
top: 0;
}
}
}
}
}
</style>