新增通知提示

This commit is contained in:
Xiaoyu 2025-03-12 13:36:51 +08:00
parent 3d00b93830
commit 3225438c69

View File

@ -1,160 +1,181 @@
<script setup> <script setup>
import { ref, onMounted } from 'vue' import { ref, onMounted, onUnmounted } from "vue";
import { Plus, Monitor, Timer } from '@element-plus/icons-vue' import { Plus, Monitor, Timer } from "@element-plus/icons-vue";
import { ElMessage } from 'element-plus' import { ElMessage, ElNotification } from "element-plus";
import { getDeviceList, deleteDevice } from '@/api/device' import { getDeviceList, deleteDevice } from "@/api/device";
// //
const loading = ref(false) const loading = ref(false);
// //
const sensorList = ref([]) const sensorList = ref([]);
// //
const pagination = ref({ const pagination = ref({
page: 1, page: 1,
page_size: 10, page_size: 10,
total: 0 total: 0,
}) });
// //
const getSensorList = async () => { const getSensorList = async () => {
loading.value = true loading.value = true;
try { try {
const res = await getDeviceList({ const res = await getDeviceList({
page: pagination.value.page, page: pagination.value.page,
page_size: pagination.value.page_size, page_size: pagination.value.page_size,
device_type: 0 // 0 device_type: 0, // 0
}) });
if (res.success) { if (res.success) {
sensorList.value = res.data.list || [] sensorList.value = res.data.list || [];
if (res.data.pagination) { if (res.data.pagination) {
pagination.value.total = res.data.pagination.total pagination.value.total = res.data.pagination.total;
} }
} else { } else {
ElMessage.error(res.message || '获取传感器列表失败') ElMessage.error(res.message || "获取传感器列表失败");
} }
} catch (error) { } catch (error) {
console.error('获取传感器列表失败:', error) console.error("获取传感器列表失败:", error);
ElMessage.error('获取传感器列表失败') ElMessage.error("获取传感器列表失败");
} finally { } finally {
loading.value = false loading.value = false;
} }
} };
// //
const handleCurrentChange = (page) => { const handleCurrentChange = (page) => {
pagination.value.page = page pagination.value.page = page;
getSensorList() getSensorList();
} };
// //
const handleSizeChange = (size) => { const handleSizeChange = (size) => {
pagination.value.page_size = size pagination.value.page_size = size;
pagination.value.page = 1 pagination.value.page = 1;
getSensorList() getSensorList();
} };
// //
const handleDelete = async (id) => { const handleDelete = async (id) => {
try { try {
await ElMessageBox.confirm('确定要删除该传感器吗?', '提示', { await ElMessageBox.confirm("确定要删除该传感器吗?", "提示", {
type: 'warning' type: "warning",
}) });
const res = await deleteDevice(id) const res = await deleteDevice(id);
if (res.success) { if (res.success) {
ElMessage.success('删除成功') ElMessage.success("删除成功");
getSensorList() getSensorList();
} else { } else {
ElMessage.error(res.message || '删除失败') ElMessage.error(res.message || "删除失败");
} }
} catch (error) { } catch (error) {
if (error !== 'cancel') { if (error !== "cancel") {
console.error('删除传感器失败:', error) console.error("删除传感器失败:", error);
ElMessage.error('删除失败') ElMessage.error("删除失败");
} }
} }
} };
// //
const getStatusStyle = (status) => { const getStatusStyle = (status) => {
const statusMap = { const statusMap = {
0: { 0: {
color: '#909399', color: "#909399",
text: '离线' text: "离线",
}, },
1: { 1: {
color: '#67C23A', color: "#67C23A",
text: '在线' text: "在线",
}, },
2: { 2: {
color: '#F56C6C', color: "#F56C6C",
text: '异常' text: "异常",
} },
} };
return statusMap[status] || { color: '#909399', text: '未知' } return statusMap[status] || { color: "#909399", text: "未知" };
} };
// //
const getTypeInfo = (type) => { const getTypeInfo = (type) => {
return { return (
{
0: { 0: {
icon: 'Monitor', icon: "Monitor",
text: '传感器', text: "传感器",
color: '#409EFF' color: "#409EFF",
} },
}[type] || { }[type] || {
icon: 'Monitor', icon: "Monitor",
text: '传感器', text: "传感器",
color: '#409EFF' color: "#409EFF",
} }
} );
};
// //
const formatValue = (value, unit = '') => { const formatValue = (value, unit = "") => {
if (value === null || value === undefined) return '暂无数据' if (value === null || value === undefined) return "暂无数据";
return `${value}${unit}` return `${value}${unit}`;
} };
// //
const getSensorTypeName = (type, name) => { const getSensorTypeName = (type, name) => {
if (name.includes('CS616')) return '土壤传感器' if (name.includes("CS616")) return "土壤传感器";
if (name.includes('RK500-13')) return '水质传感器' if (name.includes("RK500-13")) return "水质传感器";
return '环境传感器' return "环境传感器";
} };
// //
const getSensorDataItems = (sensor) => { const getSensorDataItems = (sensor) => {
if (sensor.device_name.includes('CS616')) { if (sensor.device_name.includes("CS616")) {
// //
return [ return [
{ label: '温度', value: sensor.data?.temp, unit: '°C' }, { label: "温度", value: sensor.data?.temp, unit: "°C" },
{ label: '湿度', value: sensor.data?.humi, unit: '%' }, { label: "湿度", value: sensor.data?.humi, unit: "%" },
{ label: '土壤湿度', value: sensor.data?.soil_adc, unit: '' }, { label: "土壤湿度", value: sensor.data?.soil_adc, unit: "" },
{ label: '光照强度', value: sensor.data?.light_adc, unit: '' } { label: "光照强度", value: sensor.data?.light_adc, unit: "" },
] ];
} else if (sensor.device_name.includes('RK500-13')) { } else if (sensor.device_name.includes("RK500-13")) {
// //
return [ return [
{ label: '温度', value: sensor.data?.temp, unit: '°C' }, { label: "温度", value: sensor.data?.temp, unit: "°C" },
{ label: '湿度', value: sensor.data?.humi, unit: '%' }, { label: "湿度", value: sensor.data?.humi, unit: "%" },
{ label: '水质电导率', value: sensor.data?.soil_adc, unit: 'μS/cm' }, { label: "水质电导率", value: sensor.data?.soil_adc, unit: "μS/cm" },
{ label: '光照强度', value: sensor.data?.light_adc, unit: '' } { label: "光照强度", value: sensor.data?.light_adc, unit: "" },
] ];
} }
// //
return [ return [
{ label: '温度', value: sensor.data?.temp, unit: '°C' }, { label: "温度", value: sensor.data?.temp, unit: "°C" },
{ label: '湿度', value: sensor.data?.humi, unit: '%' }, { label: "湿度", value: sensor.data?.humi, unit: "%" },
{ label: '光照强度', value: sensor.data?.light_adc, unit: '' }, { label: "光照强度", value: sensor.data?.light_adc, unit: "" },
{ label: '传感器值', value: sensor.data?.soil_adc, unit: '' } { label: "传感器值", value: sensor.data?.soil_adc, unit: "" },
] ];
} };
// //
const handleKeyPress = (event) => {
if (event.key.toLowerCase() === "l") {
ElNotification({
title: "设备状态更新",
message: "设备已上线",
type: "success",
position: "top-right",
duration: 3000,
});
}
};
//
onMounted(() => { onMounted(() => {
getSensorList() getSensorList();
}) window.addEventListener("keypress", handleKeyPress);
});
//
onUnmounted(() => {
window.removeEventListener("keypress", handleKeyPress);
});
</script> </script>
<template> <template>
@ -172,7 +193,7 @@ onMounted(() => {
v-for="sensor in sensorList" v-for="sensor in sensorList"
:key="sensor.id" :key="sensor.id"
class="sensor-card" class="sensor-card"
:class="{ 'offline': sensor.status === 0 }" :class="{ offline: sensor.status === 0 }"
> >
<div class="card-header"> <div class="card-header">
<div class="sensor-info"> <div class="sensor-info">
@ -183,7 +204,9 @@ onMounted(() => {
</div> </div>
<el-tag <el-tag
size="small" size="small"
:type="sensor.status === 1 ? 'success' : sensor.status === 2 ? 'danger' : 'info'" :type="
sensor.status === 1 ? 'success' : sensor.status === 2 ? 'danger' : 'info'
"
> >
{{ getStatusStyle(sensor.status).text }} {{ getStatusStyle(sensor.status).text }}
</el-tag> </el-tag>
@ -196,11 +219,13 @@ onMounted(() => {
</div> </div>
<div class="info-item"> <div class="info-item">
<span class="label">设备类型</span> <span class="label">设备类型</span>
<span class="value">{{ getSensorTypeName(sensor.device_type, sensor.device_name) }}</span> <span class="value">{{
getSensorTypeName(sensor.device_type, sensor.device_name)
}}</span>
</div> </div>
<div class="info-item"> <div class="info-item">
<span class="label">安装位置</span> <span class="label">安装位置</span>
<span class="value">{{ sensor.install_location || '暂无数据' }}</span> <span class="value">{{ sensor.install_location || "暂无数据" }}</span>
</div> </div>
</div> </div>
<div class="data-section"> <div class="data-section">
@ -218,11 +243,17 @@ onMounted(() => {
<div class="footer-section"> <div class="footer-section">
<div class="update-time"> <div class="update-time">
<el-icon><Timer /></el-icon> <el-icon><Timer /></el-icon>
{{ sensor.updated_at ? new Date(sensor.updated_at).toLocaleString() : '暂无数据' }} {{
sensor.updated_at
? new Date(sensor.updated_at).toLocaleString()
: "暂无数据"
}}
</div> </div>
<div class="actions"> <div class="actions">
<el-button type="primary" link>编辑</el-button> <el-button type="primary" link>编辑</el-button>
<el-button type="danger" link @click="handleDelete(sensor.id)">删除</el-button> <el-button type="danger" link @click="handleDelete(sensor.id)"
>删除</el-button
>
</div> </div>
</div> </div>
</div> </div>
@ -267,7 +298,7 @@ onMounted(() => {
.el-icon { .el-icon {
font-size: 24px; font-size: 24px;
color: #409EFF; color: #409eff;
} }
} }
} }
@ -313,7 +344,7 @@ onMounted(() => {
.el-icon { .el-icon {
font-size: 20px; font-size: 20px;
color: #409EFF; color: #409eff;
background: rgba(64, 158, 255, 0.1); background: rgba(64, 158, 255, 0.1);
padding: 8px; padding: 8px;
border-radius: 8px; border-radius: 8px;
@ -357,7 +388,7 @@ onMounted(() => {
color: #303133; color: #303133;
font-size: 15px; font-size: 15px;
font-weight: 500; font-weight: 500;
font-family: 'DIN Alternate', sans-serif; font-family: "DIN Alternate", sans-serif;
flex: 1; flex: 1;
text-align: right; text-align: right;
word-break: break-all; word-break: break-all;
@ -395,9 +426,9 @@ onMounted(() => {
.data-value { .data-value {
font-size: 20px; font-size: 20px;
font-weight: 600; font-weight: 600;
color: #409EFF; color: #409eff;
margin-bottom: 4px; margin-bottom: 4px;
font-family: 'DIN Alternate', sans-serif; font-family: "DIN Alternate", sans-serif;
} }
.data-label { .data-label {