he wei
2025-04-23 b9bd29a1a81f6f7de479e3cc3fdfe3d85fc660bf
src/views/general/alarm/alarmRt.vue
@@ -1,248 +1,268 @@
<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>
@@ -260,22 +280,90 @@
          <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>
@@ -285,22 +373,23 @@
          <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>