<template>
|
<view class="app">
|
<z-paging ref="paging" v-model="dataList" show-refresher-update-time @query="queryList">
|
<!-- 需要固定在顶部不滚动的view放在slot="top"的view中,如果需要跟着滚动,则不要设置slot="top" -->
|
<template #top>
|
<cu-custom bgColor="bg-gradual-blue" :isBack="false" :isRight="true" @rightclick="rclick">
|
<block slot="content">报警</block>
|
|
</cu-custom>
|
|
<!--弹出层start-->
|
<view style="width: 100%; position: absolute;z-index: 1000;top:300rpx;padding: 20rpx;"
|
@touchmove.prevent>
|
<dropdown-menu v-show="filterMenuShow" @closeMenu="filterMenuShow = false " @reset='resetMenu' @change='changeMenu' :list='equList'
|
ref='dropdownMenuRef' />
|
|
</view>
|
<view class="lock-page dropdown-mask" @touchmove.prevent v-if="filterMenuShow"></view>
|
|
<!--弹出层end-->
|
|
<view class="card-box dynamic shadow">
|
<view class="title-box margin-bottom-sm">
|
<view style="width: 100vw;" class="left justify-between">
|
<view class="flex align-center">
|
<uni-text class="cuIcon-titles text-blue"></uni-text>
|
<view class="title">总览</view>
|
</view>
|
<view>
|
<text class="text-gray text-sm">{{curDate}}</text>
|
</view>
|
|
</view>
|
|
</view>
|
<view class="flex flex-direction padding-xs">
|
<view class="flex">
|
<view class="flex-sub flex flex-direction">
|
<text class="text-df">报警总数</text>
|
<text class="text-bold text-sl margin-top-xs text-red margin-top-sm">{{count}}
|
<text class="text-gray text-sm margin-left-xs">次</text></text>
|
|
</view>
|
<view class="flex-twice flex flex-direction justify-between">
|
<view class="flex-sub flex">
|
<view class="flex flex-direction flex-sub">
|
<text class="text-gray text-xs">报警信息</text>
|
|
<text class="text-black">故障次数:</text>
|
<text class="margin-lr-xs text-red text-bold text-xl">{{faultCount}}</text>
|
<text class="text-gray text-xs"></text>
|
|
|
</view>
|
<view class="flex flex-direction flex-sub">
|
<text class="text-gray text-xs">机台信息</text>
|
|
<text class="text-black">故障机台:</text>
|
<text class="margin-lr-xs text-red">{{faultEqus}}</text>
|
<text class="text-gray text-xs"></text>
|
|
|
</view>
|
|
</view>
|
<view class="flex-sub flex">
|
<view class="flex flex-direction flex-sub" >
|
<text class="text-white text-xs">报警信息</text>
|
|
<text class="text-black">告警次数:</text>
|
<text class="margin-lr-xs text-orange text-bold text-xl">{{alarmCount}}</text>
|
<text class="text-gray text-xs"></text>
|
|
|
</view>
|
<view class="flex flex-direction flex-sub">
|
<text class="text-white text-xs">机台信息</text>
|
<text class="text-black">告警机台:</text>
|
<text class="margin-lr-xs text-orange">{{alarmEqus}}</text>
|
<text class="text-gray text-xs"></text>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
<view>
|
<u-scroll-list>
|
|
</u-scroll-list>
|
|
</view>
|
|
</view>
|
|
|
|
</view>
|
|
</template>
|
|
<view class="tab-box card-box top dynamic shadow">
|
|
<u-tabs :list="tabList" @click="tabsChange"></u-tabs>
|
<!-- <z-tabs ref="tabs" :active-style="{'font-size':'30rpx','font-weight':'bold'}" :current="tabCurrent"
|
:list="tabList" @change="tabsChange"> -->
|
<!-- 自定义右侧插槽 -->
|
<!-- <template v-slot:right>
|
<u-icon name="setting" ></u-icon>
|
</template> -->
|
</z-tabs>
|
</view>
|
|
<!-- 如果希望其他view跟着页面滚动,可以放在z-paging标签内 -->
|
<real-warning ref="realWarining" v-if="tabCurrent === 0" @handleData="realHandleData"></real-warning>
|
<his-warning ref="hisWarining" v-else @handleData="hisHandleData"></his-warning>
|
|
|
</z-paging>
|
</view>
|
</template>
|
|
<script>
|
import dropdownMenu from '@/components/drop-down-menu/index.vue'
|
import realWarning from './components/realWarning.vue'
|
import hisWarning from './components/hisWarning.vue'
|
import dayjs from 'dayjs'
|
export default {
|
components: {
|
dropdownMenu,
|
realWarning,
|
hisWarning
|
},
|
data() {
|
return {
|
loading: true,
|
// v-model绑定的这个变量不要在分页请求结束中自己赋值!!!
|
dataList: [],
|
curDate: dayjs().format('YYYY-MM-DD'),
|
tabList: [{
|
name: '实时报警',
|
// badge: {
|
// count: 6
|
// }
|
}, {
|
name: '报警统计',
|
}],
|
equList: [{
|
code: 1,
|
name: '1#干燥机'
|
},
|
{
|
code: 2,
|
name: '2#干燥机'
|
}
|
],
|
|
//筛选框
|
filterMenuShow: false,
|
//当前选中tab
|
tabCurrent: 0,
|
//实时报警数据更新时间(一般10s)
|
refreshTime: '',
|
//报警总数
|
count: 0,
|
//告警总数
|
alarmCount: 0,
|
//故障总数
|
faultCount: 0,
|
//故障机台
|
faultEqus: "",
|
//告警机台
|
alarmEqus: "",
|
}
|
},
|
onTabItemTap: function(e) {
|
getApp().globalData.selectTab = e.index
|
},
|
onShow() {
|
// //实时故障
|
// if(this.tabCurrent === 0){
|
// this.$nextTick(()=>{
|
// this.$refs.realWarining.queryRealFaultData()
|
// })
|
// }
|
|
//实时故障
|
if (this.tabCurrent === 0) {
|
this.queryRealFaultData()
|
}
|
|
},
|
onReady() {
|
|
},
|
methods: {
|
|
queryList(pageNo, pageSize) {
|
this.loading = true;
|
// 组件加载时会自动触发此方法,因此默认页面加载时会自动触发,无需手动调用
|
// 这里的pageNo和pageSize会自动计算好,直接传给服务器即可
|
// 模拟请求服务器获取分页数据,请替换成自己的网络请求
|
const params = {
|
pageNo: pageNo,
|
pageSize: pageSize,
|
}
|
//
|
|
|
this.$api.querySampleList(params).then((res) => {
|
// // 将请求的结果数组传递给z-paging
|
//实时故障
|
if (this.tabCurrent === 0) {
|
this.queryRealFaultData()
|
}else if(this.tabCurrent === 1){
|
this.$refs.hisWarining.init();
|
}
|
|
this.$refs.paging.complete(res.result.records);
|
this.loading = false
|
}).catch(res => {
|
// 如果请求失败写this.$refs.paging.complete(false);
|
// 注意,每次都需要在catch中写这句话很麻烦,z-paging提供了方案可以全局统一处理
|
// 在底层的网络请求抛出异常时,写uni.$emit('z-paging-error-emit');即可
|
this.$refs.paging.complete(false);
|
this.loading = false
|
})
|
|
|
},
|
//tabs通知swiper切换
|
tabsChange(item) {
|
this.tabCurrent = item.index;
|
//重置故障统计数据
|
this.count = 0;
|
this.alarmCount = 0;
|
this.faultCount = 0;
|
this.faultEqus = "";
|
this.alarmEqus = "";
|
//实时故障
|
if (this.tabCurrent === 0) {
|
// this.$nextTick(()=>{
|
// this.$refs.realWarining.queryRealFaultData()
|
|
// })
|
this.queryRealFaultData()
|
|
this.curDate = dayjs().format('YYYY-MM-DD');
|
}else if(this.tabCurrent === 1){
|
this.curDate = dayjs().subtract(3, 'day').format('YYYY-MM-DD') +" - "+ dayjs().format('YYYY-MM-DD');
|
|
}
|
|
|
},
|
realHandleData(data) {
|
if (!data) return false
|
this.count = data.length
|
this.faultCount = data.filter(item => item.faultType === 1).length;
|
this.alarmCount = data.filter(item => item.faultType === 2).length;
|
|
const faultEquList = [...new Set(
|
data
|
.filter(item => item.faultType === 1) // 根据故障类型过滤
|
.map(item => {
|
const match = item.equName.match(/(\d+#)/);
|
return match ? match[0] : null; // 如果匹配成功,则返回匹配的编号;否则返回null
|
})
|
.filter(Boolean) // 再次过滤掉可能存在的null值
|
)];
|
if (faultEquList) {
|
this.faultEqus = faultEquList.join(',');
|
}
|
|
|
|
const alarmEquList = [...new Set(
|
data
|
.filter(item => item.faultType === 2) // 根据故障类型过滤
|
.map(item => {
|
const match = item.equName.match(/(\d+#)/);
|
return match ? match[0] : null; // 如果匹配成功,则返回匹配的编号;否则返回null
|
})
|
.filter(Boolean) // 再次过滤掉可能存在的null值
|
)];
|
|
if (alarmEquList) {
|
this.alarmEqus = alarmEquList.join(',')
|
}
|
|
|
},
|
hisHandleData(data){
|
if (!data) return false
|
this.count = data.reduce((sum, item) => sum + item.ecount, 0);
|
this.faultCount = data.filter(item => item.faultType === 1).reduce((sum, item) => sum + item.ecount, 0);
|
this.alarmCount = data.filter(item => item.faultType === 2).reduce((sum, item) => sum + item.ecount, 0);
|
|
},
|
changeMenu(selectData) {
|
console.info(selectData)
|
this.filterMenuShow = false
|
|
|
},
|
resetMenu(selectData) {
|
console.info(selectData)
|
|
},
|
rclick() {
|
this.filterMenuShow = !this.filterMenuShow
|
if (this.filterMenuShow) {
|
uni.pageScrollTo({
|
scrollTop: 0,
|
duration: 300 // 滚动动画持续时间,单位为毫秒
|
});
|
}
|
},
|
|
queryRealFaultData() {
|
//发送数据
|
const message = {
|
req: this.deviceId,
|
tenantId: this.tenantId,
|
timeStamp: new Date(),
|
|
}
|
let opts = {
|
topic: this.$constant.MOBILE_REQ_EQU_REAL_FAULT,
|
message: JSON.stringify(message),
|
}
|
|
this.$mqttTool.publish(opts).then(res => {
|
//console.error(res)
|
})
|
},
|
|
|
|
},
|
onReady() {
|
|
},
|
computed: {
|
tenantId() {
|
const userinfo = uni.getStorageSync('userinfo');
|
const tenantid = userinfo.loginTenantId
|
return tenantid + "";
|
},
|
deviceId() {
|
return uni.getStorageSync(this.$constant.DEVICE_ID);
|
},
|
|
|
},
|
}
|
</script>
|
|
<style lang="scss" scoped>
|
@import "components/table/helang-table";
|
|
.app {
|
width: 100%;
|
max-height: 100vh;
|
overflow: hidden;
|
}
|
|
|
|
|
.card-box {
|
margin: 20rpx;
|
padding: 20rpx;
|
box-sizing: border-box;
|
background-color: white;
|
border-radius: 20rpx;
|
font-family: Helvetica Neue, Helvetica, sans-serif;
|
|
}
|
|
|
.top {
|
margin: 0 20rpx;
|
border-radius: 0;
|
border-top-left-radius: 20rpx;
|
border-top-right-radius: 20rpx;
|
border-bot-left-radius: 0;
|
border-bot-right-radius: 0;
|
|
}
|
|
.center {
|
margin: 0 20rpx;
|
border-radius: 0;
|
|
}
|
|
.bot {
|
margin: 0 20rpx 20rpx 20rpx;
|
border-top-left-radius: 0;
|
border-top-right-radius: 0;
|
border-bot-left-radius: 20rpx;
|
border-bot-right-radius: 20rpx;
|
}
|
|
|
.title-box {
|
display: flex;
|
flex-direction: row;
|
align-items: center;
|
|
.left {
|
display: flex;
|
align-items: center;
|
|
.title {
|
margin: 0 10rpx;
|
font-weight: bold;
|
}
|
}
|
|
.right {
|
display: flex;
|
align-items: center;
|
|
.title {
|
margin: 0 10rpx;
|
font-weight: bold;
|
}
|
}
|
}
|
|
.info-box {
|
margin-top: 20rpx;
|
display: flex;
|
flex-direction: row;
|
align-items: center;
|
|
.left {
|
display: flex;
|
align-items: center;
|
|
.title {
|
margin: 0 10rpx;
|
}
|
}
|
|
.right {
|
display: flex;
|
align-items: center;
|
|
.title {
|
margin: 0 10rpx;
|
}
|
}
|
}
|
|
|
.chartsMain {
|
width: 100%;
|
height: 320rpx;
|
padding-top: 15rpx;
|
background: #fff;
|
margin-bottom: 24rpx;
|
border-top: 2rpx solid #f2f2f2;
|
|
.charts {
|
width: 50%;
|
height: 450rpx;
|
box-sizing: border-box;
|
}
|
}
|
|
.tab-box {
|
display: flex;
|
justify-content: center;
|
/* 强制水平居中 */
|
}
|
|
.swiper {
|
height: 2116rpx;
|
}
|
|
.swiper-item-view {
|
height: 2116rpx;
|
|
|
}
|
|
|
|
|
|
|
|
.picBox {
|
margin: 0 20rpx;
|
background-color: white;
|
|
image {
|
border-radius: 8rpx;
|
width: 100%;
|
|
}
|
}
|
|
.borderTop {
|
border-top: 2rpx solid #f2f2f2;
|
padding-top: 20rpx;
|
}
|
|
// 弹出层背景遮罩start
|
.dropdown-mask {
|
background: rgba(0, 0, 0, 0.5);
|
}
|
|
.lock-page {
|
height: 100vh;
|
width: 100vw;
|
position: fixed;
|
top: 0;
|
left: 0;
|
right: 0;
|
bottom: 0;
|
z-index: 998;
|
}
|
|
// 弹出层背景遮罩end
|
</style>
|