<script setup name="alarmHis">
|
import { ref, reactive, onMounted, watchEffect, } from "vue";
|
import useWebSocket from "@/hooks/useWebsocket.js";
|
import useElement from "@/hooks/useElement.js";
|
import { getAreaTreeApi } from "@/api/area";
|
import { formatAreaTree } from "@/utils/tree";
|
import { confirmAlm, cancelAlm, delAlm } from '@/api/alarm.js';
|
import {
|
getLinfById,
|
getLockAlmHis,
|
} from '@/api/lockManager.js';
|
|
import { Search } from '@element-plus/icons-vue';
|
|
import moment from 'moment';
|
|
const { $loading, $message, $confirm } = useElement();
|
const pageCurr = ref(1);
|
const pageSize = ref(10);
|
const total = ref(0);
|
const areaId = ref();
|
const lockId = ref();
|
const areaList = ref([]);
|
const lockList = ref([]);
|
const confirmFlag = ref(0);
|
const startTime = ref('2020-01-01');
|
const endTime = ref('');
|
const datas = reactive({
|
tableData: [],
|
keyInfo: {},
|
});
|
|
const checkAll = ref(true)
|
const isIndeterminate = ref(false);
|
// [ 119001-通信故障 119002-开锁失败]
|
const checkedTypes = ref([119001, 119002]);
|
const types = [{
|
value: 119001,
|
label: '通信故障'
|
}, {
|
value: 119002,
|
label: '开锁失败'
|
}
|
];
|
|
const handleCheckAllChange = (val) => {
|
checkedTypes.value = val ? types.map(v => v.value) : []
|
isIndeterminate.value = false
|
}
|
const handleCheckedCitiesChange = (value) => {
|
const checkedCount = value.length
|
checkAll.value = checkedCount === types.length
|
isIndeterminate.value = checkedCount > 0 && checkedCount < types.length
|
getList();
|
}
|
|
function handleSizeChange(val) {
|
pageSize.value = val;
|
getList();
|
}
|
|
function handleCurrentChange(val) {
|
pageCurr.value = val;
|
getList();
|
}
|
|
async function getList() {
|
let _almIds = checkedTypes.value?.length ? checkedTypes.value.join(',') : 0;
|
let _areaId = areaId.value?.length ? areaId.value[areaId.value.length - 1] : undefined;
|
let _startTime = startTime.value + ' 00:00:00';
|
let _endTime = endTime.value + ' 23:59:59';
|
let _pageNum = pageCurr.value;
|
let _pageSize = pageSize.value;
|
|
let res = await getLockAlmHis(_areaId, _startTime, _endTime, _pageNum, _pageSize, _almIds);
|
debugger;
|
if (res.code && res.data) {
|
let {
|
total: _total,
|
list
|
} = res.data2;
|
// 告警来源[1-平台触发 2-手机APP触发 3-锁具触发]
|
datas.tableData = list.map(v => ({
|
...v,
|
areaPath: v.linf.areaPath,
|
lockName: v.linf.lockName,
|
almName: types.find(t => t.value == v.almId).label,
|
alarmSource: v.almSource == 1 ? '平台触发' : v.almSource == 2 ? '手机APP触发' : '锁具触发',
|
almConfirmedTime: v.almIsConfirmed ? v.almConfirmedTime : '--',
|
almIsConfirmedStr: v.almIsConfirmed ? '已确认' : '未确认',
|
}));
|
|
total.value = _total;
|
}
|
}
|
|
async function getLocks() {
|
if (!areaId.value.length) {
|
$message.error('请选择区域');
|
return false;
|
}
|
let res = await getLinfById(areaId.value[areaId.value.length - 1]);
|
let { code, data, data2 } = res;
|
let _list = [];
|
if (code && data) {
|
_list = data2;
|
}
|
lockList.value = _list;
|
|
}
|
|
|
function confirmAlarm(scope) {
|
$confirm('确认告警', () => {
|
|
confirmAlm(scope.row.num).then(res => {
|
let { code, data } = res;
|
if (code && data) {
|
$message({
|
type: 'success',
|
message: '确认成功!'
|
});
|
getList();
|
} else {
|
$message({
|
type: 'error',
|
message: '确认失败!'
|
});
|
}
|
}).catch(err => {
|
console.log(err);
|
});
|
});
|
}
|
|
function cancelAlarm(scope) {
|
$confirm('取消确认', () => {
|
cancelAlm(scope.row.num).then(res => {
|
let { code, data } = res;
|
if (code && data) {
|
$message({
|
type: 'success',
|
message: '取消成功!'
|
});
|
getList();
|
} else {
|
$message({
|
type: 'error',
|
message: '取消失败!'
|
});
|
}
|
}).catch(err => {
|
console.log(err);
|
})
|
});
|
}
|
|
function areaChange() {
|
getList();
|
// if (!areaId.value.length) {
|
// return false;
|
// }
|
// getLocks();
|
}
|
|
async function getAreaTree() {
|
try {
|
const res = await getAreaTreeApi();
|
let _data = [];
|
if (res.code === 1 && res.data) {
|
_data = res.data2;
|
}
|
const treeList = [];
|
let ids = _data.map((v) => v.id);
|
for (let i = 0; i < _data.length; i++) {
|
formatAreaTree(_data[i], ids, treeList);
|
}
|
// console.log(_data, 'data');
|
// console.log(treeList, 'treeList');
|
areaList.value = treeList;
|
} catch (e) {
|
console.log(e);
|
}
|
}
|
|
function delAlarm(scope) {
|
$confirm('删除告警', () => {
|
delAlm(scope.row.num).then(res => {
|
let { code, data } = res;
|
if (code && data) {
|
$message({
|
type: 'success',
|
message: '删除成功!'
|
});
|
getList();
|
} else {
|
$message({
|
type: 'error',
|
message: '删除失败!'
|
});
|
}
|
}).catch(err => {
|
console.log(err);
|
})
|
});
|
}
|
|
onMounted(() => {
|
endTime.value = moment().format('YYYY-MM-DD');
|
getAreaTree();
|
getList();
|
});
|
</script>
|
|
<template>
|
<div class="page-wrapper">
|
<div class="page-header">
|
</div>
|
<div class="page-content">
|
<hdw-card is-full>
|
<div class="page-content-wrapper">
|
<div class="page-content-tools">
|
<div class="tools-filter">
|
<div class="tools-filter-item">
|
<div class="filter-label">区域</div>
|
<div class="filter-content">
|
<el-cascader class="select" filterable clearable v-model="areaId" @change="areaChange"
|
:props="{ value: 'id', checkStrictly: true }" :options="areaList"><template #default="{ node, data }">
|
<span>{{ data.label }}</span>
|
<span v-if="!node.isLeaf"> ({{ data.children.length }}) </span>
|
</template></el-cascader>
|
</div>
|
</div>
|
<!-- <div class="tools-filter-item">
|
<div class="filter-label">锁具</div>
|
<div class="filter-content">
|
<el-select v-model="lockId" clearable filterable @change="getList" :placeholder="!areaId?.length ? '请选择区域' : '请选择锁具'">
|
<el-option v-for="item in lockList" :key="'lock_' + item.lockId" :label="item.lockName"
|
:value="item.lockId" />
|
</el-select>
|
</div>
|
</div> -->
|
<div class="tools-filter-item flex-row">
|
<div class="filter-label">告警类型</div>
|
<el-checkbox class="select-all" v-model="checkAll" :indeterminate="isIndeterminate"
|
@change="handleCheckAllChange">
|
全选
|
</el-checkbox>
|
<el-checkbox-group v-model="checkedTypes" @change="handleCheckedCitiesChange">
|
<el-checkbox v-for="(item, idx) in types" :key="'type_' + idx" :label="item.label" :value="item.value">
|
</el-checkbox>
|
</el-checkbox-group>
|
</div>
|
<!-- <div class="tools-filter-item flex-row">
|
<div class="filter-label">确认状态</div>
|
<div class="filter-content">
|
<el-radio-group v-model="confirmFlag" @change="getList">
|
<el-radio :value="0">未确认</el-radio>
|
<el-radio :value="1">已确认</el-radio>
|
</el-radio-group>
|
</div>
|
</div> -->
|
<div class="tools-filter-item">
|
<div class="filter-label">起始时间</div>
|
<div class="filter-content">
|
<el-date-picker v-model="startTime" @change="getList" value-format="YYYY-MM-DD" type="date"
|
placeholder="" />
|
</div>
|
</div>
|
<div class="tools-filter-item">
|
<div class="filter-label">截止时间</div>
|
<div class="filter-content">
|
<el-date-picker v-model="endTime" type="date" value-format="YYYY-MM-DD" @change="getList"
|
placeholder="" />
|
</div>
|
</div>
|
<div class="tools-filter-item">
|
<el-button type="primary" :icon="Search" @click="getList">查询</el-button>
|
</div>
|
</div>
|
</div>
|
<div class="page-content-table">
|
<div class="pos-rel">
|
<div class="pos-abs">
|
<el-table :data="datas.tableData" border style="width: 100%; height: 100%">
|
<el-table-column type="index" width="50" />
|
<el-table-column prop="lockId" align="center" label="钥匙ID" width="120" />
|
<el-table-column prop="lockName" align="center" label="钥匙名称" width="140" />
|
<el-table-column prop="areaPath" align="center" label="所属区域" min-width="180" />
|
<el-table-column prop="almName" align="center" label="告警名称" width="180" />
|
<el-table-column prop="alarmSource" align="center" label="告警来源" width="180" />
|
<!-- <el-table-column prop="almIsConfirmedStr" align="center" label="是否确认" width="180" /> -->
|
<el-table-column prop="almStartTime" width="160" label="告警开始时间" />
|
<el-table-column prop="almEndTime" width="160" label="告警结束时间" />
|
<!-- <el-table-column prop="almConfirmedTime" width="160" label="告警确认时间" /> -->
|
<!-- <el-table-column align="center" fixed="right" label="操作" width="220">
|
<template #default="scope">
|
<el-button type="primary" v-if="scope.row.almIsConfirmed == 0" size="small"
|
@click="confirmAlarm(scope)">确认</el-button>
|
<el-button type="warning" v-else size="small" @click="cancelAlarm(scope)">取消</el-button>
|
<el-button type="danger" size="small" @click="delAlarm(scope)">删除</el-button>
|
</template>
|
</el-table-column> -->
|
</el-table>
|
</div>
|
</div>
|
</div>
|
<div class="page-content-page">
|
<div class="page-tool"></div>
|
<div class="el-page-container">
|
<el-pagination v-model:current-page="pageCurr" v-model:page-size="pageSize"
|
:page-sizes="[20, 40, 60, 80, 100, 200, 300, 400]" size="small" :disabled="disabled"
|
:background="background" layout="total, sizes, prev, pager, next, jumper" :total="total"
|
@size-change="handleSizeChange" @current-change="handleCurrentChange" />
|
</div>
|
<div class="page-tool"></div>
|
</div>
|
</div>
|
</hdw-card>
|
</div>
|
<div class="page-footer"></div>
|
<!-- 弹窗 -->
|
<el-dialog :title="dialogTitle" v-model="addEditVisible" top="0" :close-on-click-modal="false" class="dialog-center"
|
width="700px" center>
|
<add-edit v-if="addEditVisible" @success="onOk" :info="datas.keyInfo" @cancel="onCanel"></add-edit>
|
</el-dialog>
|
</div>
|
</template>
|
|
<style scoped lang="scss">
|
.page-wrapper {
|
display: flex;
|
flex-direction: row;
|
padding: 8px;
|
height: 100%;
|
|
.page-content {
|
flex: 1;
|
}
|
}
|
|
.page-content-wrapper {
|
display: flex;
|
flex-direction: column;
|
height: 100%;
|
|
.page-content-tools {
|
padding-bottom: 8px;
|
}
|
|
.page-content-table {
|
flex: 1;
|
margin-left: -8px;
|
margin-right: -8px;
|
}
|
|
.page-content-page {
|
padding: 8px 8px 0 8px;
|
text-align: center;
|
|
.el-page-container {
|
display: inline-block;
|
padding: 0 16px;
|
}
|
|
.page-tool {
|
display: inline-block;
|
}
|
}
|
}
|
|
.hdw-card-container {
|
width: 240px;
|
padding-right: 8px;
|
height: 100%;
|
}
|
|
.pos-rel {
|
position: relative;
|
width: 100%;
|
height: 100%;
|
|
.pos-abs {
|
position: absolute;
|
top: 0;
|
bottom: 0;
|
left: 0;
|
right: 0;
|
width: 100%;
|
height: 100%;
|
}
|
}
|
|
.tools-filter {
|
display: inline-block;
|
font-size: 14px;
|
|
.tools-filter-item {
|
display: inline-block;
|
margin-right: 8px;
|
|
&.flex-row {
|
display: inline-flex;
|
align-items: center;
|
|
.select-all {
|
margin: 0 16px;
|
}
|
}
|
|
.filter-label {
|
display: inline-block;
|
margin-right: 0.4em;
|
}
|
|
.filter-content {
|
min-width: 160px;
|
display: inline-block;
|
}
|
}
|
}
|
</style>
|