Files
smart_storage_app/pages/home-page/alarm/index.vue

723 lines
18 KiB
Vue
Raw Normal View History

2025-06-30 10:21:25 +08:00
<template>
<view class="warp">
<u-toast ref="uToast" />
<!-- 搜索框 -->
<u-navbar :is-back="true" :background="background" :border-bottom="false" :custom-back="toback">
<view class="slot-wrap">
<stationDropdow disabled style="width: 100%" ref="dropdow" />
</view>
</u-navbar>
<zero-loading v-if="loading" active-color="#ff9900" />
<view v-else class="alarm-warp">
<view class="search-warp" style="margin-top: 20rpx">
<Search :placeholder="$t('homePage.alarm.placeholderInput')" class="Search" @custom="showPopup"
ref="search" @blur="decSearch" />
</view>
<view class="clear-alarm">
<u-popup v-model="popupShow" mode="bottom" border-radius="20" height="75%" placement="top-end"
@close="closePop">
<view class="sift">{{$t('homePage.alarm.sift')}}</view>
<!-- 设备类型下拉框 -->
<view class="s-station">
2025-07-01 16:59:10 +08:00
<u-section :title="$t('homePage.alarm.device')" line-color="#009458" color="#2A2A2A"
2025-06-30 10:21:25 +08:00
class="s-title" :right="false"></u-section>
<!-- <view class="s-title">设备</view> -->
<view class="s-content">
<view class="s-button" v-if="!deviceList.length">
<view class="selectbox" @click="addTags">
<view class="select-title">
<view style="font-size: 24rpx" class="choice" @click="openSelectDevice">
{{$t('homePage.alarm.placeSelect')}}
</view>
<!-- {{ devType }} -->
</view>
<!-- <i class="iconfont icon-xiala"></i> -->
</view>
</view>
<block v-if="deviceNameList.length">
<u-tag style="margin-right: 10rpx; margin-bottom: 10rpx"
v-for="(item, index) in deviceNameList" :key="item.srcId" closeable type="success"
class="tag" :text="item.name" @close="handleDel(item, index)" />
<u-icon name="plus" color="#2979ff" size="28" @click="addTags"></u-icon>
</block>
</view>
</view>
<!-- 事件 -->
<view class="s-station">
2025-07-01 16:59:10 +08:00
<u-section :title="$t('homePage.alarm.event')" line-color="#009458" color="#2A2A2A"
2025-06-30 10:21:25 +08:00
class="s-title" :right="false"></u-section>
<!-- <view class="s-title">事件</view> -->
<view class="s-content">
<block v-for="item in newEventTypes" :key="item.value">
<view class="s-button" :class="{ 'checked-class': item.isActive }"
@click="choiceEvent(item)">
{{ item.label }}
</view>
</block>
</view>
</view>
<!-- 告警等级 -->
<view class="s-station">
2025-07-01 16:59:10 +08:00
<u-section :title="$t('homePage.alarm.level')" line-color="#009458" color="#2A2A2A"
2025-06-30 10:21:25 +08:00
class="s-title" :right="false"></u-section>
<!-- <view class="s-title">告警等级</view> -->
<view class="s-content">
<block v-for="(item, index) in newEventLevels" :key="index">
<view class="s-button" :class="{ 'checked-class': item.isActive }"
@click="choiceLevel(item, index)">{{
item.label }}</view>
</block>
</view>
</view>
<!-- 时间范围 -->
<view class="s-station" v-show="currentType === 1">
2025-07-01 16:59:10 +08:00
<u-section :title="$t('homePage.alarm.timeRange')" line-color="#009458" color="#2A2A2A"
2025-06-30 10:21:25 +08:00
class="s-title" :right="false"></u-section>
<!-- <view class="s-title">告警等级</view> -->
<view class="s-content" style="width: 100%;margin-top: 6px;">
<u-input style="width: 90%;" v-model="dateRange" :disabled="true"
:placeholder="$t('homePage.alarm.placeholderDate')" :type="'text'" :border="true"
clearable @click="calendarShow=true" />
</view>
</view>
<view class="other-button">
<u-button type="warning" :custom-style="{
2025-07-01 16:59:10 +08:00
backgroundColor: '#fdd100',
2025-06-30 10:21:25 +08:00
width: '280rpx',
height: '70rpx',
fontSize: '28rpx',
color: 'rgba(40, 40, 40, 1)'
}" @click="clearText()">{{$t('homePage.alarm.reset')}}</u-button>
<u-button type="primary" :custom-style="{
2025-07-01 16:59:10 +08:00
backgroundColor: '#009458',
2025-06-30 10:21:25 +08:00
width: '280rpx',
height: '70rpx',
fontSize: '28rpx',
color: 'rgba(255, 255, 255, 1)'
}" @click="search()">{{$t('homePage.alarm.sure')}}</u-button>
</view>
<tki-tree :select-data="deviceShowList" ref="tkitree" :range="devTreeOption" idKey="srcId" multiple
:rangeKey="'name'" selectParent childrenKey="children" confirmColor="#07bb07"
@confirm="confirmDevice" />
<u-calendar v-model="calendarShow" :mode="'range'" @change="calendarChange"></u-calendar>
</u-popup>
</view>
<view class="subsection-alarm">
2025-07-01 16:59:10 +08:00
<u-subsection :list="alarmTypeList" :current="currentType" :animation="true" @change="sectionChange" :active-color="'#009458'">
2025-06-30 10:21:25 +08:00
</u-subsection>
</view>
<view class="no_data" v-if="eventList.length === 0">
<u-empty :text="$t('homePage.alarm.noData')" mode="list"></u-empty>
</view>
<view class="loading" style="position: relative">
<Alarmevent v-for="(item, index) in eventList" :key="index" class="eventList-item"
@choice="choice($event)" :title="getEventname(item)"
:state="item.status === 1 ? $t('homePage.alarm.confirm') : $t('homePage.alarm.noConfirmed')"
:alarm-time="item.timeStamp" :name="item.name" :device-type="item.deviceName"
:belongs="item.stationName" :confirm-people="item.confirmMan ? item.confirmMan : ''"
:confirm-time="item.confirmTime ? item.confirmTime : ''" :alarm-content="item.description"
:conversionStatus="item.conversionStatus" :pid="item.id"></Alarmevent>
<view v-if="total > 10">
<u-loadmore :status="status" icon-type="iconType" :load-text="loadText" v-if="loadmoreshow" />
</view>
</view>
</view>
</view>
</template>
<script>
import tkiTree from "./components/tki-tree/tki-tree.vue";
import stationDropdow from "@/components/station-dropdow/index.vue";
import Search from "@/components/Search/index";
import Alarmevent from "./components/alarmevent.vue";
export default {
data() {
return {
dateRange: '',
startTime: null,
endTime: null,
alarmTypeList: [],
currentType: 0,
nodata: true,
calendarShow: false,
loadmoreshow: true,
// 事件列表
loading: false,
eventList: [],
filters: {
deviceTypeList: null,
},
pageSize: 5,
pageNum: 1,
status: "loadmore",
iconType: "flower",
loadText: this.$t('homePage.alarm.loadText'),
total: 0,
alarmid: [],
showStations: false,
stationList: [],
popupShow: false,
showDevice: false,
devType: "",
deviceTypeLists: [],
deviceTypetreeList: [],
informList: ["1", "2", "3", "4", "5"],
event: ["2", "3", "4", "5", "6"],
stationIds: [],
power: "power",
alarmContent: "",
stationId: "",
changeStationColor: "",
timer: null,
sureFlg: false,
AlarmStatus: null,
activeSelectLabel: this.$t('homePage.alarm.allStation'),
background: {
backgroundColor: "#4c9ce7",
},
activeSelectDevLabel: this.$t('homePage.alarm.device'),
activeSelectEventLabel: this.$t('homePage.alarm.event'),
activeSelectLevelsLabel: this.$t('homePage.alarm.level'),
deviceList: [],
devTreeOption: [],
selectDevice: false,
selectEvent: false,
selectLevel: false,
deviceShowList: [],
EventShowList: [],
eventShowList: [],
LevelShowList: [],
deviceNameList: [],
background: {
backgroundColor: "#0EA17E",
},
};
},
components: {
Alarmevent,
stationDropdow,
tkiTree,
Search,
},
watch: {
currentStation: {
handler(val) {
this.loading = true;
this.deviceShowList = [];
this.deviceList = [];
this.deviceNameList = [];
this.stationId = val.id;
this.eventList = [];
this.pageNum = 1;
this.GetAlarmList();
this.GetDeviceType();
},
immediate: true,
deep: true,
},
language: {
immediate: true,
deep:true,
handler(val) {
if (this.language === 'zh_CN') {
this.alarmTypeList = [{
name: '实时告警'
}, {
name: '历史告警'
}]
} else {
this.alarmTypeList = [{
name: 'Real-Time Alarm'
}, {
name: 'History Alarm'
}]
}
}
},
},
onShow() {
// if (this.language === 'zh_CN') {
// this.alarmTypeList = [{
// name: '实时告警'
// }, {
// name: '历史告警'
// }]
// } else {
// this.alarmTypeList = [{
// name: 'Real-Time Alarm'
// }, {
// name: 'History Alarm'
// }]
// }
},
mounted() {},
computed: {
language(){
return this.vuex_language
},
currentStation() {
return this.vuex_currentStation;
},
// 获取vuex中的eventlevel数据(告警等级)
eventLevels() {
return this.vuex_dicts["eventLevel"] || [];
},
// 获取vuex中的eventType数据(事件类型)
eventTypes() {
return this.vuex_dicts["eventType"] || [];
},
newEventLevels() {
if (this.eventLevels.length > 0) {
this.eventLevels.forEach((el) => {
el.isActive = true;
});
}
return this.eventLevels;
},
newEventTypes() {
if (this.eventTypes.length > 0) {
const r = this.eventTypes.findIndex((el) => {
if (el.label === this.$t('homePage.alarm.alarm')) {
return el;
}
});
if (r !== -1) {
this.eventTypes.splice(r, 1);
}
this.eventTypes.forEach((el) => {
el.isActive = true;
});
}
return this.eventTypes;
},
},
onReachBottom() {
if (this.eventList.length < this.total) {
// this.pageSize += 5
this.GetAlarmList();
} else {
this.status = "nomore";
}
},
methods: {
calendarChange(val) {
this.pageNum = 1;
this.startTime = val.startDate
this.endTime = val.endDate
this.dateRange = val.startDate + ' ~ ' + val.endDate
},
sectionChange(val) {
this.currentType = val
this.pageNum = 1;
this.eventList = [];
this.clearText();
setTimeout(() => {
this.GetAlarmList()
}, 100);
},
toback() {
uni.navigateBack({
delta: 1
})
},
// 设备增加
addTags() {
this.$refs.tkitree._show();
},
// 打开下方筛选
showPopup() {
this.popupShow = true;
},
closePop() {
},
// 打开设备框
openSelectDevice() {
if (this.devTreeOption.length === 0) {
this.$refs.uToast.show({
title: this.$t('homePage.alarm.noDevice'),
type: "warning",
});
return;
}
this.$refs.tkitree._show();
},
// 确认设备选中
confirmDevice(val) {
this.deviceNameList = [];
this.deviceList = [];
val.forEach((el) => {
this.deviceList.push(el.srcId);
this.deviceNameList.push(el);
});
this.eventList = [];
this.pageNum = 1;
this.deviceShowList = val;
},
handleDel: function(item, index) {
this.deviceList.splice(index, 1);
this.deviceNameList.splice(index, 1);
},
// 重置
clearText() {
(this.devType = ""), (this.power = ""), (this.deviceList = []);
this.deviceNameList = [];
this.deviceShowList = [];
this.deviceTypeList = undefined;
this.changeStationColor = "";
this.startTime = null
this.endTime = null
this.dateRange = ''
this.newEventLevels.forEach((el) => {
el.isActive = true;
this.$forceUpdate();
});
this.newEventTypes.forEach((el) => {
el.isActive = true;
this.$forceUpdate();
});
this.stationList.forEach((el) => {
el.isActive = true;
this.$forceUpdate();
});
},
// 获取设备类型
async GetDeviceType() {
const res = await this.$u.api.alarm.GetDeviceType({
stationId: this.stationId,
});
this.devTreeOption = res.data;
},
choice(e) {
if (!this.alarmid.includes(e)) {
this.alarmid.push(e);
} else {
const r = this.alarmid.findIndex((el) => el === e);
this.alarmid.splice(r, 1);
}
},
clear() {
this.SetAlarmConfirm();
},
decSearch(e) {
this.filters.description = e;
this.pageNum = 1;
this.eventList = [];
// const self = this
this.GetAlarmList();
// 输入框防抖
// clearTimeout(self
// .timer) // 每次进来的时候都将之前的清除掉如果还没到一秒的时候就将之前的清除掉这样就不会触发之前setTimeout绑定的事件 如果超过一秒之前的事件就会被触发下次进来的时候同样清除之前的timer
// self.timer = setTimeout(function() {
// self.GetAlarmList()
// }, 1000)
},
search() {
this.sureFlg = true;
this.informList = [];
this.event = [];
if (this.eventLevels.length) {
this.eventLevels.forEach((el) => {
if (el.isActive) {
this.informList.push(el.value);
this.informList = Array.from(new Set(this.informList));
}
});
}
if (this.eventTypes.length) {
this.eventTypes.forEach((el) => {
if (el.isActive) {
this.event.push(el.value);
this.event = Array.from(new Set(this.event));
}
});
}
const params = {
belongs: this.stationId,
description: this.filters.description,
eventLevels: this.informList,
eventTypes: this.event,
};
this.filters.belongs = params.belongs;
this.filters.description = params.description;
this.filters.eventLevels = params.eventLevels;
this.filters.eventTypes = params.eventTypes;
this.popupShow = false;
this.pageNum = 1;
this.eventList = [];
this.GetAlarmList();
},
// 如果事件的类型等于1的时候则显示告警的等级
getEventname(row) {
if (row) {
if (row.eventType === 1) {
if (
this.eventLevels.find((el) => Number(el.value) === row.eventLevel)
) {
return this.eventLevels.find(
(el) => Number(el.value) === row.eventLevel
).label;
}
// 否则则显示事件的类型
} else {
if (
this.eventTypes.find((el) => Number(el.value) === row.eventType)
) {
return this.eventTypes.find(
(el) => Number(el.value) === row.eventType
).label;
}
}
}
},
// 选择事件
choiceEvent(item) {
item.isActive = !item.isActive;
this.$forceUpdate();
},
// 选择告警等级
choiceLevel(item) {
item.isActive = !item.isActive;
this.$forceUpdate();
},
// 获取告警的数据
async GetAlarmList() {
// 对电站进行过滤显示
try {
let res = {};
let params = {};
if (this.currentType === 1) {
params = {
description: this.filters.description,
pageNum: this.pageNum,
pageSize: this.pageSize,
stationIds: this.stationId ? [this.stationId] : [],
srcIdList: this.deviceList,
eventLevels: this.informList,
eventTypes: this.event,
startTime: this.startTime,
endTime: this.endTime
};
res = await this.$u.api.alarm.GetHistoryAlarmList(params);
} else {
params = {
description: this.filters.description,
pageNum: this.pageNum,
pageSize: this.pageSize,
stationIds: this.stationId ? [this.stationId] : [],
srcIdList: this.deviceList,
eventLevels: this.informList,
eventTypes: this.event
};
res = await this.$u.api.alarm.GetAlarmList(params);
}
const data = res.data
this.total = data.totalRows;
this.eventNums = data.eventTypes;
let levelNums = Object.entries(data.eventLevels);
this.levelNums = {};
for (const [num, value] of levelNums) {
if (num === "-1") {
this.levelNums["all"] = value;
} else {
this.levelNums[num] = value;
}
}
this.total = data.totalRows;
this.eventList = this.eventList.concat(data.list);
if (data.totalRows === 0) {
this.eventList = [];
}
if (this.total) {
this.nodata = false;
} else {
this.nodata = true;
this.loadmoreshow = false;
}
this.pageNum += 1;
} catch (error) {} finally {
this.loading = false;
}
},
},
};
</script>
<style lang="scss" scoped>
.warp {
width: 100%;
height: 100%;
}
.alarm-warp {
width: 100%;
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
padding-left: 10px;
padding-right: 10px;
position: relative;
.search-warp {
width: 100%;
.Search {
width: 100%;
}
}
.subsection-alarm {
width: 100%;
2025-07-01 16:59:10 +08:00
text-align: center;
2025-06-30 10:21:25 +08:00
padding-right: 10rpx;
display: flex;
align-items: center;
2025-07-01 16:59:10 +08:00
justify-content: center;
2025-06-30 10:21:25 +08:00
}
}
.loading {
width: 100%;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
.eventList-item {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
background-color: #f5f5f5;
}
}
.clear-alarm {
width: 100%;
padding: 20rpx 20rpx 0;
text-align: right;
.button {
background-color: #4c9ce7;
width: 160rpx;
height: 60rpx;
line-height: 60rpx;
color: #ffffff;
}
}
.sift {
text-align: center;
font-size: 40rpx;
margin-bottom: 20rpx;
margin-top: 40rpx;
padding-left: 20rpx;
}
.s-station {
margin-bottom: 60rpx;
.s-title {
font-size: 35rpx;
text-align: left;
margin-bottom: 10rpx;
padding-left: 20rpx;
}
.s-content {
width: 100%;
display: flex;
flex-wrap: wrap;
padding-left: 20rpx;
.s-button {
margin-top: 10rpx;
border: 1px solid;
text-align: center;
margin-bottom: 10rpx;
background: #f8f8f8;
color: #282828;
border-radius: 4rpx;
padding: 10rpx;
border: 5rpx;
width: 30%;
margin-right: 20rpx;
}
.checked-class {
2025-07-01 16:59:10 +08:00
background-color: #e2fff3;
border: 1px solid #009458;
2025-06-30 10:21:25 +08:00
border-radius: 4rpx;
color: rgba(0, 156, 119, 1);
}
}
}
.no_data {
margin-top: 30vh;
}
.loadmore {
margin-top: 20rpx;
}
.other-button {
width: 100%;
display: flex;
display: flex;
flex-direction: row;
align-items: center;
justify-content: space-evenly;
}
.selectbox {
display: flex;
justify-content: center;
align-items: center;
}
.slot-wrap {
display: flex;
align-items: center;
/* 如果您想让slot内容占满整个导航栏的宽度 */
flex: 1;
/* 如果您想让slot内容与导航栏左右有空隙 */
/* padding: 0 30rpx; */
/deep/ .u-input__input {
color: #fff !important;
}
}
::v-deep .u-subsection {
width: 68% !important;
}
::v-deep .u-item-bg {
width: 50% !important;
}
</style>