Files
dyf-vue-ui/src/views/equipmentAlarmRecord/index.vue
fengerli 3782f73215 提交
2025-09-01 17:02:21 +08:00

381 lines
12 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>
<div class="p-2">
<transition :enter-active-class="proxy?.animate.searchAnimate.enter"
:leave-active-class="proxy?.animate.searchAnimate.leave">
<div v-show="showSearch" class="mb-[10px]">
<el-card shadow="hover">
<el-button :type="isListView ? 'primary' : ''" @click="switchView('card')">
{{ isListView ? '卡片显示' : '卡片显示' }}
</el-button>
<el-button :type="!isListView ? 'primary' : ''" @click="switchView('list')">
{{ !isListView ? '列表显示' : '列表显示' }}
</el-button>
<el-form ref="queryFormRef" :model="queryParams" :inline="true" style="margin-top: 20px;">
<el-form-item label="设备名称" prop="deviceName">
<el-input v-model="queryParams.deviceName" placeholder="请输入设备名称" clearable @keyup.enter="handleQuery" />
</el-form-item>
<el-form-item label="设备类型" prop="deviceType">
<el-select v-model="queryParams.deviceType" placeholder="设备类型">
<el-option v-for="item in deviceTypeOptions" :key="item.value" :label="item.typeName"
:value="item.deviceTypeId" />
</el-select>
</el-form-item>
<el-form-item label="报警事项" prop="deviceAction">
<el-select v-model="queryParams.deviceAction">
<el-option value="0" label="强制报警"></el-option>
<el-option value="1" label="撞击闯入"></el-option>
<el-option value="2" label="手动报警"></el-option>
<el-option value="3" label="电子围栏告警"></el-option>
<el-option value="4" label="强制告警"></el-option>
</el-select>
</el-form-item>
<el-form-item label="报警时间" style="width: 308px">
<el-date-picker v-model="dateRange" value-format="YYYY-MM-DD HH:mm:ss" type="daterange"
range-separator="-" start-placeholder="开始日期" end-placeholder="结束日期"
:default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]"></el-date-picker>
</el-form-item>
<el-form-item label="报警状态" prop="treatmentState">
<el-select v-model="queryParams.treatmentState">
<el-option value="0" label="已处理"></el-option>
<el-option value="1" label="未处理"></el-option>
</el-select>
</el-form-item>
<el-form-item>
<el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button>
<el-button icon="Refresh" @click="resetQuery">重置</el-button>
</el-form-item>
</el-form>
</el-card>
</div>
</transition>
<el-card shadow="never">
<div v-if="isListView" key="card">
<el-row :gutter="20">
<el-col :span="6" v-for="(item, index) in alarmList" :key="index">
<el-card class="custom-alarm-card">
<div class="card-header">
<h4 class="device-name">{{ item.startTime }}</h4>
</div>
<!-- 卡片内容报警事项地点时间等信息 -->
<div class="card-body">
<div class="d_fl">
<div class="d_flex">
<div>
<img :src="item.devicePic" alt="" class="devicePicImg">
</div>
<div style="margin-left:10px;">
<div class="deviceName">{{ item.deviceName }}</div>
<div class="deviceTypeName">{{ item.deviceTypeName }}</div>
</div>
</div>
<div>
<span class="treatment-state" :class="item.treatmentState === 0 ? 'handled' : 'pending'">
{{ item.treatmentState === 0 ? '已处理' : '待处理' }}
</span>
</div>
</div>
<div class="label">报警事项</div>
<div class="alearm">
<template v-if="item.deviceAction === 0">强制报警
<span v-if="item.treatmentState === 1">({{ item.startTime.split(' ')[1] || '' }})</span>
</template>
<template v-else-if="item.deviceAction === 1">撞击闯入
<span v-if="item.treatmentState === 1">({{ item.startTime.split(' ')[1] || '' }})</span>
</template>
<template v-else-if="item.deviceAction === 2">手动报警
<span v-if="item.treatmentState === 1">({{ item.startTime.split(' ')[1] || '' }})</span>
</template>
<template v-else-if="item.deviceAction === 3">电子围栏告警
<span v-if="item.treatmentState === 1">({{ item.startTime.split(' ')[1] || '' }})</span>
</template>
<template v-else-if="item.deviceAction === 4">强制告警
<span v-if="item.treatmentState === 1">({{ item.startTime.split(' ')[1] || '' }})</span>
</template>
</div>
<div class="label">报警地点</div>
<div class="alearmADD">
{{ item.location }}
</div>
<div v-if="item.treatmentState === 0" class="dl_bot d_fl">
<div>时长:{{ item.durationTime }}</div>
<div>解除: {{ item.finishTime.split(' ')[1] || '' }}</div>
</div>
</div>
</el-card>
</el-col>
</el-row>
</div>
<div v-else key="list">
<el-table v-loading="loading" border :data="alarmList">
<el-table-column label="设备名称" align="center" prop="deviceName" />
<el-table-column label="设备类型" align="center" prop="deviceTypeName" />
<el-table-column label="IMEI/MAC" align="center">
<template #default="scope">
<div>{{ scope.row.deviceImei }} {{ scope.row.deviceMac }}</div>
</template>
</el-table-column>
<el-table-column label="报警地点" align="center" prop="location" />
<el-table-column label="报警事项" align="center" prop="deviceAction">
<template #default="scope">
<el-tag type="danger" v-if="scope.row.deviceAction == 0">强制报警</el-tag>
<el-tag type="danger" v-if="scope.row.deviceAction == 1">撞击闯入</el-tag>
<el-tag type="danger" v-if="scope.row.deviceAction == 2">手动报警</el-tag>
<el-tag type="danger" v-if="scope.row.deviceAction == 3">电子围栏告警</el-tag>
<el-tag type="danger" v-if="scope.row.deviceAction == 4">强制告警</el-tag>
</template>
</el-table-column>
<el-table-column label="报警持续时间" align="center" prop="durationTime" width="180">
<template #default="scope">
<el-tag type="danger">{{ scope.row.durationTime }}</el-tag>
</template>
</el-table-column>
<el-table-column label="处理状态" align="center" prop="treatmentState">
<template #default="scope">
<div class="ysStatus" v-if="scope.row.treatmentState == 0">已处理</div>
<el-tag type="danger" v-if="scope.row.treatmentState == 1">未处理</el-tag>
</template>
</el-table-column>
<el-table-column label="报警时间" align="center" prop="startTime" />
</el-table>
</div>
<pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum"
v-model:limit="queryParams.pageSize" @pagination="getList" />
</el-card>
</div>
</template>
<script setup name="Alarm" lang="ts">
import { listAlarm } from '@/api/equipmentAlarmRecord/index';
import { AlarmVO, AlarmQuery, AlarmForm } from '@/api/equipmentAlarmRecord/types';
import apiTypeAll from '@/api/equipmentManagement/device/index';
const { proxy } = getCurrentInstance() as ComponentInternalInstance;
const alarmList = ref<AlarmVO[]>([]);
const isListView = ref(true);
const dateRange = ref(['', '']);
const loading = ref(true);
const showSearch = ref(true);
const total = ref(0);
const deviceTypeOptions = ref([]); //设备类型
const queryFormRef = ref<ElFormInstance>();
const alarmFormRef = ref<ElFormInstance>();
const initFormData: AlarmForm = {
id: undefined,
deviceId: undefined,
deviceAction: undefined,
deviceName: undefined,
dataSource: undefined,
content: undefined,
deviceType: undefined,
longitude: undefined,
latitude: undefined,
location: undefined,
startTime: undefined,
}
const data = reactive<PageData<AlarmForm, AlarmQuery>>({
form: { ...initFormData },
queryParams: {
pageNum: 1,
pageSize: 8,
deviceId: undefined,
deviceAction: undefined,
deviceName: undefined,
dataSource: undefined,
content: undefined,
deviceType: undefined,
longitude: undefined,
latitude: undefined,
durationTime: undefined,
treatmentState: undefined,
params: {
}
},
rules: {
id: [
{ required: true, message: "ID不能为空", trigger: "blur" }
],
}
});
const { queryParams, form, rules } = toRefs(data);
const switchView = (view: 'list' | 'card') => {
isListView.value = (view === 'card');
};
/** 查询设备告警列表 */
const getList = async () => {
loading.value = true;
const [startTime, endTime] = dateRange.value;
queryParams.value = {
...queryParams.value,
queryTime1: startTime,
queryTime2: endTime
};
const res = await listAlarm(queryParams.value);
alarmList.value = res.rows;
total.value = res.total;
loading.value = false;
}
// 设备类型
const getDeviceType = () => {
apiTypeAll.deviceTypeAll().then(res => {
if (res.code == 200) {
deviceTypeOptions.value = res.data
}
}).catch(err => {
})
};
/** 表单重置 */
const reset = () => {
form.value = { ...initFormData };
alarmFormRef.value?.resetFields();
}
/** 搜索按钮操作 */
const handleQuery = () => {
queryParams.value.pageNum = 1;
getList();
}
/** 重置按钮操作 */
const resetQuery = () => {
queryFormRef.value?.resetFields();
handleQuery();
}
onMounted(() => {
getList();
getDeviceType()
});
</script>
<style lang="scss" scoped>
.custom-alarm-card {
height: 298px;
display: flex;
flex-direction: column;
box-shadow: 0px 0px 6px 0px rgba(0, 27, 74, 0.1);
background: linear-gradient(127.63deg, rgba(255, 240, 240, 1), rgba(255, 255, 255, 1) 100%);
border: none;
margin-bottom: 16px;
border-radius: 5px;
}
/* 卡片头部:设备名称 + 处理状态 布局 */
.card-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 10px;
border-bottom: 1px solid rgba(235, 238, 248, 1);
height: 30px;
margin-top: -11px;
}
.d_fl {
display: flex;
justify-content: space-between;
}
.d_flex {
display: flex;
}
.devicePicImg {
width: 48px;
height: 37px;
}
.deviceTypeName {
font-size: 13px;
font-weight: 400;
}
.deviceName {
color: rgba(56, 64, 79, 1);
font-family: Microsoft YaHei;
font-size: 16px;
font-weight: 700;
}
/* 处理状态标签:不同状态不同颜色 */
.treatment-state {
padding: 2px 6px;
border-radius: 4px;
font-size: 12px;
}
.handled {
/* 已处理-绿色 */
color: rgba(0, 165, 82, 1);
}
.pending {
/* 待处理-红色 */
color: rgba(224, 52, 52, 1);
}
/* 标签与值的间距 */
.label {
font-weight: 500;
margin-right: 4px;
margin: 12px 0;
}
.value {
flex: 1;
}
.alearm {
border-radius: 4px;
background: rgba(224, 52, 52, 0.04);
padding: 8px 18px;
margin: 10px 0 10px 0;
position: relative;
color: rgb(224, 52, 52);
}
.alearm::before {
position: absolute;
content: "";
width: 7px;
height: 7px;
background: rgb(224, 52, 52);
border-radius: 50%;
left: 6px;
top: 15px;
}
.alearmADD {
border-radius: 4px;
background: rgba(224, 52, 52, 0.04);
padding: 8px 18px;
margin: 10px 0 10px 0;
position: relative;
color: rgba(56, 64, 79, 1);
}
.alearmADD::before {
position: absolute;
content: "";
width: 7px;
height: 7px;
background: rgba(56, 64, 79, 1);
border-radius: 50%;
left: 6px;
top: 15px;
}
.dl_bot {
border-top: 1px solid rgba(235, 238, 248, 1);
padding-top: 10px;
color: rgba(56, 64, 79, 0.6);
font-size: 12px;
}
.ysStatus {
color: #00A552;
}
</style>