| | |
| | | <script setup name="alarmRt"> |
| | | 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 |
| | | } from '@/api/lockManager.js'; |
| | | import { ref, reactive, onMounted, watchEffect, nextTick } from "vue"; |
| | | import useWebSocket from "@/hooks/useWebsocket.js"; |
| | | import useElement from "@/hooks/useElement.js"; |
| | | import { confirmAlm, cancelAlm, delAlm } from '@/api/alarm.js'; |
| | | import { |
| | | getLinfById |
| | | } from '@/api/lockManager.js'; |
| | | |
| | | const { $loading, $message, $confirm } = useElement(); |
| | | const { sendData, message: listMessage } = useWebSocket("lockAlmRt"); |
| | | 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 datas = reactive({ |
| | | tableData: [], |
| | | keyInfo: {}, |
| | | }); |
| | | import useStation from "@/hooks/useStationList.js"; |
| | | const { stationName1, stationName2, stationName3, stationName4, |
| | | stationList1, stationList2, stationList3, stationList4, lockList |
| | | } = useStation(); |
| | | |
| | | const checkAll = ref(true) |
| | | const isIndeterminate = ref(false); |
| | | // [ 119001-通信故障 119002-开锁失败] |
| | | const checkedTypes = ref([119001, 119002]); |
| | | const types = [{ |
| | | value: 119001, |
| | | label: '通信故障' |
| | | }, { |
| | | value: 119002, |
| | | label: '开锁失败' |
| | | const { $loading, $message, $confirm } = useElement(); |
| | | const { sendData, message: listMessage } = useWebSocket("lockAlmRt"); |
| | | const pageCurr = ref(1); |
| | | const pageSize = ref(10); |
| | | const total = ref(0); |
| | | const lockName = ref(); |
| | | const confirmFlag = ref(0); |
| | | 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 |
| | | sendMessage(); |
| | | } |
| | | |
| | | function handleSizeChange(val) { |
| | | pageSize.value = val; |
| | | sendMessage(); |
| | | } |
| | | |
| | | function handleCurrentChange(val) { |
| | | pageCurr.value = val; |
| | | sendMessage(); |
| | | } |
| | | |
| | | function sendMessage() { |
| | | const params = { |
| | | pageNum: pageCurr.value, |
| | | pageSize: pageSize.value, |
| | | lockName: lockName.value || undefined, |
| | | almIds: checkedTypes.value?.length ? checkedTypes.value.join(',') : 0, |
| | | confirmFlag: confirmFlag.value, |
| | | stationName1: stationName1.value || undefined, |
| | | stationName2: stationName2.value || undefined, |
| | | stationName3: stationName3.value || undefined, |
| | | stationName4: stationName4.value || undefined |
| | | }; |
| | | sendData(JSON.stringify(params)); |
| | | } |
| | | |
| | | async function getLocks() { |
| | | if (!areaId.value.length) { |
| | | $message.error('请选择区域'); |
| | | return false; |
| | | } |
| | | ]; |
| | | |
| | | const handleCheckAllChange = (val) => { |
| | | checkedTypes.value = val ? types.map(v => v.value) : [] |
| | | isIndeterminate.value = false |
| | | let res = await getLinfById(areaId.value[areaId.value.length - 1]); |
| | | let { code, data, data2 } = res; |
| | | let _list = []; |
| | | if (code && data) { |
| | | _list = data2; |
| | | } |
| | | const handleCheckedCitiesChange = (value) => { |
| | | const checkedCount = value.length |
| | | checkAll.value = checkedCount === types.length |
| | | isIndeterminate.value = checkedCount > 0 && checkedCount < types.length |
| | | sendMessage(); |
| | | lockList.value = _list; |
| | | |
| | | } |
| | | |
| | | watchEffect(() => { |
| | | if (listMessage.value) { |
| | | let { |
| | | total: _total, |
| | | list |
| | | } = JSON.parse(listMessage.value).data2; |
| | | // 告警来源[1-平台触发 2-手机APP触发 3-锁具触发] |
| | | datas.tableData = list.map(v => ({ |
| | | ...v, |
| | | lockName: v.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; |
| | | } |
| | | }); |
| | | |
| | | function handleSizeChange(val) { |
| | | pageSize.value = val; |
| | | sendMessage(); |
| | | } |
| | | function confirmAlarm(scope) { |
| | | $confirm('确认告警', () => { |
| | | |
| | | function handleCurrentChange(val) { |
| | | pageCurr.value = val; |
| | | sendMessage(); |
| | | } |
| | | |
| | | function sendMessage() { |
| | | const params = { |
| | | pageNum: pageCurr.value, |
| | | pageSize: pageSize.value, |
| | | areaId: areaId.value?.length ? areaId.value[areaId.value.length - 1] : undefined, |
| | | lockId: lockId.value || undefined, |
| | | almIds: checkedTypes.value?.length ? checkedTypes.value.join(',') : 0, |
| | | confirmFlag: confirmFlag.value, |
| | | }; |
| | | sendData(JSON.stringify(params)); |
| | | } |
| | | |
| | | 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; |
| | | |
| | | } |
| | | |
| | | watchEffect(() => { |
| | | if (listMessage.value) { |
| | | let { |
| | | total: _total, |
| | | list |
| | | } = JSON.parse(listMessage.value).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; |
| | | } |
| | | }); |
| | | |
| | | function confirmAlarm(scope) { |
| | | $confirm('确认告警', () => { |
| | | |
| | | confirmAlm(scope.row.num).then(res => { |
| | | let { code, data } = res; |
| | | if (code && data) { |
| | | $message({ |
| | | type: 'success', |
| | | message: '确认成功!' |
| | | }); |
| | | sendMessage(); |
| | | } 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: '取消成功!' |
| | | }); |
| | | sendMessage(); |
| | | } else { |
| | | $message({ |
| | | type: 'error', |
| | | message: '取消失败!' |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | console.log(err); |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | function areaChange() { |
| | | sendMessage(); |
| | | // 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; |
| | | confirmAlm(scope.row.num).then(res => { |
| | | let { code, data } = res; |
| | | if (code && data) { |
| | | $message({ |
| | | type: 'success', |
| | | message: '确认成功!' |
| | | }); |
| | | sendMessage(); |
| | | } else { |
| | | $message({ |
| | | type: 'error', |
| | | message: '确认失败!' |
| | | }); |
| | | } |
| | | 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: '删除成功!' |
| | | }); |
| | | sendMessage(); |
| | | } else { |
| | | $message({ |
| | | type: 'error', |
| | | message: '删除失败!' |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | console.log(err); |
| | | }) |
| | | }).catch(err => { |
| | | console.log(err); |
| | | }); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | getAreaTree(); |
| | | sendMessage(); |
| | | }); |
| | | } |
| | | |
| | | function cancelAlarm(scope) { |
| | | $confirm('取消确认', () => { |
| | | cancelAlm(scope.row.num).then(res => { |
| | | let { code, data } = res; |
| | | if (code && data) { |
| | | $message({ |
| | | type: 'success', |
| | | message: '取消成功!' |
| | | }); |
| | | sendMessage(); |
| | | } else { |
| | | $message({ |
| | | type: 'error', |
| | | message: '取消失败!' |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | console.log(err); |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | function areaChange() { |
| | | sendMessage(); |
| | | // if (!areaId.value.length) { |
| | | // return false; |
| | | // } |
| | | // getLocks(); |
| | | } |
| | | |
| | | |
| | | function delAlarm(scope) { |
| | | $confirm('删除告警', () => { |
| | | delAlm(scope.row.num).then(res => { |
| | | let { code, data } = res; |
| | | if (code && data) { |
| | | $message({ |
| | | type: 'success', |
| | | message: '删除成功!' |
| | | }); |
| | | sendMessage(); |
| | | } else { |
| | | $message({ |
| | | type: 'error', |
| | | message: '删除失败!' |
| | | }); |
| | | } |
| | | }).catch(err => { |
| | | console.log(err); |
| | | }) |
| | | }); |
| | | } |
| | | |
| | | onMounted(() => { |
| | | sendMessage(); |
| | | }); |
| | | </script> |
| | | |
| | | <template> |
| | | <div class="page-wrapper"> |
| | | <div class="page-header"> |
| | | </div> |
| | | <div class="page-header"></div> |
| | | <div class="page-content"> |
| | | <hdw-card is-full> |
| | | <yc-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-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> |
| | | <el-select v-model="stationName1" clearable placeholder="请选择" @change="() => nextTick(() => sendMessage())" size="small" |
| | | style="width: 180px"> |
| | | <el-option v-for="(item, idx) in stationList1" :key="'province_' + idx" :label="item" :value="item" /> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | <!-- <div class="tools-filter-item"> |
| | | <div class="filter-label">锁具</div> |
| | | <div class="filter-content"> |
| | | <el-select v-model="lockId" clearable filterable @change="sendMessage" :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"> |
| | | <div class="filter-label">市:</div> |
| | | <div class="filter-content"> |
| | | <el-select v-model="stationName2" clearable placeholder="请选择" @change="() => nextTick(() => sendMessage())" size="small" |
| | | style="width: 180px"> |
| | | <el-option v-for="(item, idx) in stationList2" :key="'city_' + idx" :label="item" :value="item" /> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | <div class="tools-filter-item"> |
| | | <div class="filter-label">区县:</div> |
| | | <div class="filter-content"> |
| | | <el-select v-model="stationName3" clearable placeholder="请选择" @change="() => nextTick(() => sendMessage())" size="small" |
| | | style="width: 180px"> |
| | | <el-option v-for="(item, idx) in stationList3" :key="'list2_' + idx" :label="item" :value="item" /> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | <div class="tools-filter-item"> |
| | | <div class="filter-label">机房:</div> |
| | | <div class="filter-content"> |
| | | <el-select v-model="stationName4" clearable placeholder="请选择" @change="() => nextTick(() => sendMessage())" size="small" |
| | | style="width: 180px"> |
| | | <el-option v-for="(item, idx) in stationList4" :key="'list3_' + idx" :label="item" :value="item" /> |
| | | </el-select> |
| | | </div> |
| | | </div> |
| | | |
| | | <div class="tools-filter-item"> |
| | | <div class="filter-label">锁具名称:</div> |
| | | <div class="filter-content"> |
| | | <el-select v-model="lockName" clearable filterable placeholder="请选择" @change="() => nextTick(() => sendMessage())" size="small" |
| | | style="width: 180px"> |
| | | <el-option v-for="(item, idx) in lockList" :key="'list3_' + idx" :label="item.lockName" :value="item.lockName" /> |
| | | </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 |
| | | 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-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="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"> |
| | | <el-table |
| | | :data="datas.tableData" |
| | | border |
| | | style="width: 100%; height: 100%" |
| | | > |
| | | <el-table-column type="index" fixed="left" 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="stationName" |
| | | 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> |
| | | <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 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" /> |
| | | <el-pagination |
| | | v-model:current-page="pageCurr" |
| | | v-model:page-size="pageSize" |
| | | :page-sizes="[20, 40, 60, 80, 100, 200, 300, 400]" |
| | | size="small" |
| | | 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> |
| | | </yc-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> |
| | | |