Files
smart_storage_app/pages/home-page/alarm/index.vue
2025-10-29 17:31:26 +08:00

724 lines
18 KiB
Vue
Raw 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="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">
<u-section :title="$t('homePage.alarm.device')" line-color="#009458" color="#2A2A2A"
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">
<u-section :title="$t('homePage.alarm.event')" line-color="#009458" color="#2A2A2A"
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">
<u-section :title="$t('homePage.alarm.level')" line-color="#009458" color="#2A2A2A"
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">
<u-section :title="$t('homePage.alarm.timeRange')" line-color="#009458" color="#2A2A2A"
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="{
backgroundColor: '#fdd100',
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="{
backgroundColor: '#009458',
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">
<u-subsection :list="alarmTypeList" :current="currentType" :animation="true" @change="sectionChange"
:active-color="'#009458'">
</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%;
text-align: center;
padding-right: 10rpx;
display: flex;
align-items: center;
justify-content: center;
}
}
.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 {
background-color: #e2fff3;
border: 1px solid #009458;
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>