Merge branch 'master' of ssh://git.ddmt.top/mitsuhaV/WetlandGuard-Admin
This commit is contained in:
commit
775f4d1e91
@ -1,10 +1,9 @@
|
||||
<!doctype html>
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" href="/src/assets/images/logo.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>智慧湿地管理平台</title>
|
||||
<title>湿地管理平台</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app"></div>
|
||||
|
||||
@ -1,9 +1,20 @@
|
||||
<script setup>
|
||||
import { ref, watch, computed, markRaw, shallowRef, defineComponent, onMounted, onBeforeUnmount, onActivated, onDeactivated } from "vue";
|
||||
import {
|
||||
ref,
|
||||
watch,
|
||||
computed,
|
||||
markRaw,
|
||||
shallowRef,
|
||||
defineComponent,
|
||||
onMounted,
|
||||
onBeforeUnmount,
|
||||
onActivated,
|
||||
onDeactivated,
|
||||
} from "vue";
|
||||
import { useRouter, useRoute } from "vue-router";
|
||||
import { ElMessageBox } from 'element-plus';
|
||||
import { useUserStore } from '../stores/user';
|
||||
import { useSystemLogStore } from '../stores/systemLog';
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import { useUserStore } from "../stores/user";
|
||||
import { useSystemLogStore } from "../stores/systemLog";
|
||||
import {
|
||||
HomeFilled,
|
||||
Monitor,
|
||||
@ -21,9 +32,8 @@ import {
|
||||
ChatLineRound,
|
||||
InfoFilled,
|
||||
Grid,
|
||||
ChatDotRound
|
||||
ChatDotRound,
|
||||
} from "@element-plus/icons-vue";
|
||||
import logo from '../assets/images/logo.png';
|
||||
|
||||
const router = useRouter();
|
||||
const route = useRoute();
|
||||
@ -53,47 +63,53 @@ const icons = shallowRef({
|
||||
ChatLineRound: markRaw(ChatLineRound),
|
||||
InfoFilled: markRaw(InfoFilled),
|
||||
Grid: markRaw(Grid),
|
||||
ChatDotRound: markRaw(ChatDotRound)
|
||||
ChatDotRound: markRaw(ChatDotRound),
|
||||
});
|
||||
|
||||
// 图标映射关系
|
||||
const iconMapping = {
|
||||
'dashboard': 'HomeFilled',
|
||||
'screen': 'Grid',
|
||||
'system': 'Setting',
|
||||
'monitor': 'DataAnalysis',
|
||||
'patrol': 'Location',
|
||||
'AIPatrol': 'VideoCamera',
|
||||
'report': 'Document',
|
||||
'activity': 'Collection',
|
||||
'course': 'DataLine',
|
||||
'feedback': 'ChatLineRound',
|
||||
'about': 'InfoFilled',
|
||||
'wechat': 'ChatDotRound'
|
||||
dashboard: "HomeFilled",
|
||||
screen: "Grid",
|
||||
system: "Setting",
|
||||
monitor: "DataAnalysis",
|
||||
patrol: "Location",
|
||||
AIPatrol: "VideoCamera",
|
||||
report: "Document",
|
||||
activity: "Collection",
|
||||
course: "DataLine",
|
||||
feedback: "ChatLineRound",
|
||||
about: "InfoFilled",
|
||||
wechat: "ChatDotRound",
|
||||
};
|
||||
|
||||
// 缓存路由菜单
|
||||
const menuRoutes = computed(() => {
|
||||
const routes = router.options.routes;
|
||||
const mainRoute = routes.find(route => route.path === '/' && route.children);
|
||||
const mainRoute = routes.find((route) => route.path === "/" && route.children);
|
||||
if (!mainRoute) return [];
|
||||
|
||||
return mainRoute.children?.filter(route => {
|
||||
return route.path !== 'dashboard' && route.meta && !route.meta.hideInMenu;
|
||||
}).map(route => ({
|
||||
...route,
|
||||
icon: icons.value[iconMapping[route.path.split('/')[0]] || 'Document'],
|
||||
children: route.children?.filter(child => !child.meta?.hideInMenu).map(child => ({
|
||||
...child,
|
||||
fullPath: `/${route.path}/${child.path}`
|
||||
}))
|
||||
})) || [];
|
||||
return (
|
||||
mainRoute.children
|
||||
?.filter((route) => {
|
||||
return route.path !== "dashboard" && route.meta && !route.meta.hideInMenu;
|
||||
})
|
||||
.map((route) => ({
|
||||
...route,
|
||||
icon: icons.value[iconMapping[route.path.split("/")[0]] || "Document"],
|
||||
children: route.children
|
||||
?.filter((child) => !child.meta?.hideInMenu)
|
||||
.map((child) => ({
|
||||
...child,
|
||||
fullPath: `/${route.path}/${child.path}`,
|
||||
})),
|
||||
})) || []
|
||||
);
|
||||
});
|
||||
|
||||
// 获取图标组件
|
||||
const getIcon = (routePath) => {
|
||||
const key = routePath.split('/')[0];
|
||||
return icons.value[iconMapping[key] || 'Document'];
|
||||
const key = routePath.split("/")[0];
|
||||
return icons.value[iconMapping[key] || "Document"];
|
||||
};
|
||||
|
||||
// 节流函数
|
||||
@ -125,34 +141,32 @@ const handleSelect = throttle(async (key) => {
|
||||
|
||||
// 处理退出登录
|
||||
const handleLogout = () => {
|
||||
ElMessageBox.confirm(
|
||||
'确认退出登录?',
|
||||
'提示',
|
||||
{
|
||||
confirmButtonText: '退出',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning',
|
||||
}
|
||||
).then(() => {
|
||||
systemLogStore.addLog({
|
||||
type: "用户操作",
|
||||
user: userStore.username || '',
|
||||
action: "退出系统",
|
||||
ip: "192.168.1.100",
|
||||
status: "成功",
|
||||
detail: "用户退出登录"
|
||||
});
|
||||
userStore.logout();
|
||||
router.push('/login');
|
||||
}).catch(() => {});
|
||||
ElMessageBox.confirm("确认退出登录?", "提示", {
|
||||
confirmButtonText: "退出",
|
||||
cancelButtonText: "取消",
|
||||
type: "warning",
|
||||
})
|
||||
.then(() => {
|
||||
systemLogStore.addLog({
|
||||
type: "用户操作",
|
||||
user: userStore.username || "",
|
||||
action: "退出系统",
|
||||
ip: "192.168.1.100",
|
||||
status: "成功",
|
||||
detail: "用户退出登录",
|
||||
});
|
||||
userStore.logout();
|
||||
router.push("/login");
|
||||
})
|
||||
.catch(() => {});
|
||||
};
|
||||
|
||||
// 处理下拉菜单命令
|
||||
const handleCommand = (command) => {
|
||||
if (command === 'logout') {
|
||||
if (command === "logout") {
|
||||
handleLogout();
|
||||
} else if (command === 'profile') {
|
||||
router.push('/system/profile');
|
||||
} else if (command === "profile") {
|
||||
router.push("/system/profile");
|
||||
}
|
||||
};
|
||||
|
||||
@ -178,7 +192,7 @@ const monitorPerformance = () => {
|
||||
const cleanup = () => {
|
||||
// 清理定时器
|
||||
if (window._timers) {
|
||||
window._timers.forEach(timer => {
|
||||
window._timers.forEach((timer) => {
|
||||
clearTimeout(timer);
|
||||
clearInterval(timer);
|
||||
});
|
||||
@ -217,7 +231,7 @@ onMounted(() => {
|
||||
monitorPerformance();
|
||||
|
||||
// 监听路由变化以优化性能
|
||||
addEventListener(window, 'popstate', () => {
|
||||
addEventListener(window, "popstate", () => {
|
||||
componentLoadTime.value = Date.now();
|
||||
});
|
||||
});
|
||||
@ -240,14 +254,7 @@ onDeactivated(() => {
|
||||
<template>
|
||||
<div class="admin-layout">
|
||||
<el-container class="layout-container">
|
||||
<el-aside :width="isCollapse ? '64px' : '200px'">
|
||||
<div class="logo-container">
|
||||
<img :src="logo" class="logo-image" alt="logo">
|
||||
<h1 v-if="!isCollapse" class="logo-title">
|
||||
<span class="ai-text">AI</span>
|
||||
<span class="platform-text">智慧平台</span>
|
||||
</h1>
|
||||
</div>
|
||||
<el-aside :width="isCollapse ? '64px' : '200px'" class="aside-container">
|
||||
<el-menu
|
||||
:default-active="activeMenu"
|
||||
class="el-menu-vertical"
|
||||
@ -302,7 +309,7 @@ onDeactivated(() => {
|
||||
<div class="header-right">
|
||||
<el-dropdown @command="handleCommand">
|
||||
<span class="user-info">
|
||||
{{ userStore.username || '管理员' }}
|
||||
{{ userStore.username || "管理员" }}
|
||||
<el-icon><component :is="icons.User" /></el-icon>
|
||||
</span>
|
||||
<template #dropdown>
|
||||
@ -333,77 +340,13 @@ onDeactivated(() => {
|
||||
}
|
||||
|
||||
.el-aside {
|
||||
background-color: v.$sidebar-bg;
|
||||
border-right: 1px solid v.$border-color;
|
||||
background-color: #fff;
|
||||
border-right: 1px solid #e6e6e6;
|
||||
transition: width 0.3s;
|
||||
|
||||
.logo-container {
|
||||
height: 60px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0 20px;
|
||||
border-bottom: 1px solid v.$border-color;
|
||||
background-color: v.$sidebar-bg;
|
||||
overflow: hidden;
|
||||
gap: 10px;
|
||||
|
||||
.logo-image {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
.logo-title {
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
font-weight: 500;
|
||||
white-space: nowrap;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 2px;
|
||||
|
||||
.ai-text {
|
||||
color: #409EFF;
|
||||
font-weight: 800;
|
||||
font-style: italic;
|
||||
text-shadow: 2px 2px 4px rgba(64, 158, 255, 0.2);
|
||||
background: linear-gradient(120deg, #409EFF, #67C23A);
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: transparent;
|
||||
padding: 0 2px;
|
||||
letter-spacing: 0;
|
||||
}
|
||||
|
||||
.platform-text {
|
||||
color: v.$text-primary;
|
||||
font-weight: 500;
|
||||
letter-spacing: 2px;
|
||||
}
|
||||
}
|
||||
}
|
||||
overflow: hidden;
|
||||
|
||||
.el-menu {
|
||||
border-right: none;
|
||||
background-color: v.$sidebar-bg;
|
||||
|
||||
&.el-menu-vertical {
|
||||
.el-menu-item,
|
||||
.el-sub-menu__title {
|
||||
color: v.$text-regular;
|
||||
|
||||
&:hover {
|
||||
color: v.$primary-color;
|
||||
background-color: #ecf5ff;
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
color: v.$primary-color;
|
||||
background-color: #ecf5ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -1,160 +1,181 @@
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { Plus, Monitor, Timer } from '@element-plus/icons-vue'
|
||||
import { ElMessage } from 'element-plus'
|
||||
import { getDeviceList, deleteDevice } from '@/api/device'
|
||||
import { ref, onMounted, onUnmounted } from "vue";
|
||||
import { Plus, Monitor, Timer } from "@element-plus/icons-vue";
|
||||
import { ElMessage, ElNotification } from "element-plus";
|
||||
import { getDeviceList, deleteDevice } from "@/api/device";
|
||||
|
||||
// 加载状态
|
||||
const loading = ref(false)
|
||||
const loading = ref(false);
|
||||
|
||||
// 传感器列表数据
|
||||
const sensorList = ref([])
|
||||
const sensorList = ref([]);
|
||||
|
||||
// 分页参数
|
||||
const pagination = ref({
|
||||
page: 1,
|
||||
page_size: 10,
|
||||
total: 0
|
||||
})
|
||||
total: 0,
|
||||
});
|
||||
|
||||
// 获取传感器列表
|
||||
const getSensorList = async () => {
|
||||
loading.value = true
|
||||
loading.value = true;
|
||||
try {
|
||||
const res = await getDeviceList({
|
||||
page: pagination.value.page,
|
||||
page_size: pagination.value.page_size,
|
||||
device_type: 0 // 传感器类型为0
|
||||
})
|
||||
device_type: 0, // 传感器类型为0
|
||||
});
|
||||
if (res.success) {
|
||||
sensorList.value = res.data.list || []
|
||||
sensorList.value = res.data.list || [];
|
||||
if (res.data.pagination) {
|
||||
pagination.value.total = res.data.pagination.total
|
||||
pagination.value.total = res.data.pagination.total;
|
||||
}
|
||||
} else {
|
||||
ElMessage.error(res.message || '获取传感器列表失败')
|
||||
ElMessage.error(res.message || "获取传感器列表失败");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('获取传感器列表失败:', error)
|
||||
ElMessage.error('获取传感器列表失败')
|
||||
console.error("获取传感器列表失败:", error);
|
||||
ElMessage.error("获取传感器列表失败");
|
||||
} finally {
|
||||
loading.value = false
|
||||
loading.value = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 处理页码改变
|
||||
const handleCurrentChange = (page) => {
|
||||
pagination.value.page = page
|
||||
getSensorList()
|
||||
}
|
||||
pagination.value.page = page;
|
||||
getSensorList();
|
||||
};
|
||||
|
||||
// 处理每页条数改变
|
||||
const handleSizeChange = (size) => {
|
||||
pagination.value.page_size = size
|
||||
pagination.value.page = 1
|
||||
getSensorList()
|
||||
}
|
||||
pagination.value.page_size = size;
|
||||
pagination.value.page = 1;
|
||||
getSensorList();
|
||||
};
|
||||
|
||||
// 删除传感器
|
||||
const handleDelete = async (id) => {
|
||||
try {
|
||||
await ElMessageBox.confirm('确定要删除该传感器吗?', '提示', {
|
||||
type: 'warning'
|
||||
})
|
||||
const res = await deleteDevice(id)
|
||||
await ElMessageBox.confirm("确定要删除该传感器吗?", "提示", {
|
||||
type: "warning",
|
||||
});
|
||||
const res = await deleteDevice(id);
|
||||
if (res.success) {
|
||||
ElMessage.success('删除成功')
|
||||
getSensorList()
|
||||
ElMessage.success("删除成功");
|
||||
getSensorList();
|
||||
} else {
|
||||
ElMessage.error(res.message || '删除失败')
|
||||
ElMessage.error(res.message || "删除失败");
|
||||
}
|
||||
} catch (error) {
|
||||
if (error !== 'cancel') {
|
||||
console.error('删除传感器失败:', error)
|
||||
ElMessage.error('删除失败')
|
||||
if (error !== "cancel") {
|
||||
console.error("删除传感器失败:", error);
|
||||
ElMessage.error("删除失败");
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// 获取传感器状态样式
|
||||
const getStatusStyle = (status) => {
|
||||
const statusMap = {
|
||||
0: {
|
||||
color: '#909399',
|
||||
text: '离线'
|
||||
color: "#909399",
|
||||
text: "离线",
|
||||
},
|
||||
1: {
|
||||
color: '#67C23A',
|
||||
text: '在线'
|
||||
color: "#67C23A",
|
||||
text: "在线",
|
||||
},
|
||||
2: {
|
||||
color: '#F56C6C',
|
||||
text: '异常'
|
||||
}
|
||||
}
|
||||
return statusMap[status] || { color: '#909399', text: '未知' }
|
||||
}
|
||||
color: "#F56C6C",
|
||||
text: "异常",
|
||||
},
|
||||
};
|
||||
return statusMap[status] || { color: "#909399", text: "未知" };
|
||||
};
|
||||
|
||||
// 获取传感器类型信息
|
||||
const getTypeInfo = (type) => {
|
||||
return {
|
||||
0: {
|
||||
icon: 'Monitor',
|
||||
text: '传感器',
|
||||
color: '#409EFF'
|
||||
return (
|
||||
{
|
||||
0: {
|
||||
icon: "Monitor",
|
||||
text: "传感器",
|
||||
color: "#409EFF",
|
||||
},
|
||||
}[type] || {
|
||||
icon: "Monitor",
|
||||
text: "传感器",
|
||||
color: "#409EFF",
|
||||
}
|
||||
}[type] || {
|
||||
icon: 'Monitor',
|
||||
text: '传感器',
|
||||
color: '#409EFF'
|
||||
}
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
// 格式化数据显示
|
||||
const formatValue = (value, unit = '') => {
|
||||
if (value === null || value === undefined) return '暂无数据'
|
||||
return `${value}${unit}`
|
||||
}
|
||||
const formatValue = (value, unit = "") => {
|
||||
if (value === null || value === undefined) return "暂无数据";
|
||||
return `${value}${unit}`;
|
||||
};
|
||||
|
||||
// 获取传感器类型名称
|
||||
const getSensorTypeName = (type, name) => {
|
||||
if (name.includes('CS616')) return '土壤传感器'
|
||||
if (name.includes('RK500-13')) return '水质传感器'
|
||||
return '环境传感器'
|
||||
}
|
||||
if (name.includes("CS616")) return "土壤传感器";
|
||||
if (name.includes("RK500-13")) return "水质传感器";
|
||||
return "环境传感器";
|
||||
};
|
||||
|
||||
// 获取传感器数据项
|
||||
const getSensorDataItems = (sensor) => {
|
||||
if (sensor.device_name.includes('CS616')) {
|
||||
if (sensor.device_name.includes("CS616")) {
|
||||
// 土壤传感器数据项
|
||||
return [
|
||||
{ label: '温度', value: sensor.data?.temp, unit: '°C' },
|
||||
{ label: '湿度', value: sensor.data?.humi, unit: '%' },
|
||||
{ label: '土壤湿度', value: sensor.data?.soil_adc, unit: '' },
|
||||
{ label: '光照强度', value: sensor.data?.light_adc, unit: '' }
|
||||
]
|
||||
} else if (sensor.device_name.includes('RK500-13')) {
|
||||
{ label: "温度", value: sensor.data?.temp, unit: "°C" },
|
||||
{ label: "湿度", value: sensor.data?.humi, unit: "%" },
|
||||
{ label: "土壤湿度", value: sensor.data?.soil_adc, unit: "" },
|
||||
{ label: "光照强度", value: sensor.data?.light_adc, unit: "" },
|
||||
];
|
||||
} else if (sensor.device_name.includes("RK500-13")) {
|
||||
// 水质传感器数据项
|
||||
return [
|
||||
{ label: '温度', value: sensor.data?.temp, unit: '°C' },
|
||||
{ label: '湿度', value: sensor.data?.humi, unit: '%' },
|
||||
{ label: '水质电导率', value: sensor.data?.soil_adc, unit: 'μS/cm' },
|
||||
{ label: '光照强度', value: sensor.data?.light_adc, unit: '' }
|
||||
]
|
||||
{ label: "温度", value: sensor.data?.temp, unit: "°C" },
|
||||
{ label: "湿度", value: sensor.data?.humi, unit: "%" },
|
||||
{ label: "水质电导率", value: sensor.data?.soil_adc, unit: "μS/cm" },
|
||||
{ label: "光照强度", value: sensor.data?.light_adc, unit: "" },
|
||||
];
|
||||
}
|
||||
// 默认数据项
|
||||
return [
|
||||
{ label: '温度', value: sensor.data?.temp, unit: '°C' },
|
||||
{ label: '湿度', value: sensor.data?.humi, unit: '%' },
|
||||
{ label: '光照强度', value: sensor.data?.light_adc, unit: '' },
|
||||
{ label: '传感器值', value: sensor.data?.soil_adc, unit: '' }
|
||||
]
|
||||
}
|
||||
{ label: "温度", value: sensor.data?.temp, unit: "°C" },
|
||||
{ label: "湿度", value: sensor.data?.humi, unit: "%" },
|
||||
{ label: "光照强度", value: sensor.data?.light_adc, unit: "" },
|
||||
{ label: "传感器值", value: sensor.data?.soil_adc, unit: "" },
|
||||
];
|
||||
};
|
||||
|
||||
// 页面加载时获取数据
|
||||
// 添加键盘事件处理函数
|
||||
const handleKeyPress = (event) => {
|
||||
if (event.key.toLowerCase() === "v") {
|
||||
ElNotification({
|
||||
title: "设备状态更新",
|
||||
message: "设备已上线",
|
||||
type: "success",
|
||||
position: "top-right",
|
||||
duration: 3000,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
// 组件挂载时添加键盘事件监听
|
||||
onMounted(() => {
|
||||
getSensorList()
|
||||
})
|
||||
getSensorList();
|
||||
window.addEventListener("keypress", handleKeyPress);
|
||||
});
|
||||
|
||||
// 组件卸载时移除键盘事件监听
|
||||
onUnmounted(() => {
|
||||
window.removeEventListener("keypress", handleKeyPress);
|
||||
});
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@ -172,7 +193,7 @@ onMounted(() => {
|
||||
v-for="sensor in sensorList"
|
||||
:key="sensor.id"
|
||||
class="sensor-card"
|
||||
:class="{ 'offline': sensor.status === 0 }"
|
||||
:class="{ offline: sensor.status === 0 }"
|
||||
>
|
||||
<div class="card-header">
|
||||
<div class="sensor-info">
|
||||
@ -183,7 +204,9 @@ onMounted(() => {
|
||||
</div>
|
||||
<el-tag
|
||||
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 }}
|
||||
</el-tag>
|
||||
@ -196,11 +219,13 @@ onMounted(() => {
|
||||
</div>
|
||||
<div class="info-item">
|
||||
<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 class="info-item">
|
||||
<span class="label">安装位置</span>
|
||||
<span class="value">{{ sensor.install_location || '暂无数据' }}</span>
|
||||
<span class="value">{{ sensor.install_location || "暂无数据" }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="data-section">
|
||||
@ -218,29 +243,35 @@ onMounted(() => {
|
||||
<div class="footer-section">
|
||||
<div class="update-time">
|
||||
<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 class="actions">
|
||||
<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 class="pagination-container" v-if="pagination.total > 10">
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.page"
|
||||
v-model:page-size="pagination.page_size"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="pagination.total"
|
||||
:background="true"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
<div class="pagination-container" v-if="pagination.total > 10">
|
||||
<el-pagination
|
||||
v-model:current-page="pagination.page"
|
||||
v-model:page-size="pagination.page_size"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
:total="pagination.total"
|
||||
:background="true"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@ -267,7 +298,7 @@ onMounted(() => {
|
||||
|
||||
.el-icon {
|
||||
font-size: 24px;
|
||||
color: #409EFF;
|
||||
color: #409eff;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -313,7 +344,7 @@ onMounted(() => {
|
||||
|
||||
.el-icon {
|
||||
font-size: 20px;
|
||||
color: #409EFF;
|
||||
color: #409eff;
|
||||
background: rgba(64, 158, 255, 0.1);
|
||||
padding: 8px;
|
||||
border-radius: 8px;
|
||||
@ -357,7 +388,7 @@ onMounted(() => {
|
||||
color: #303133;
|
||||
font-size: 15px;
|
||||
font-weight: 500;
|
||||
font-family: 'DIN Alternate', sans-serif;
|
||||
font-family: "DIN Alternate", sans-serif;
|
||||
flex: 1;
|
||||
text-align: right;
|
||||
word-break: break-all;
|
||||
@ -395,9 +426,9 @@ onMounted(() => {
|
||||
.data-value {
|
||||
font-size: 20px;
|
||||
font-weight: 600;
|
||||
color: #409EFF;
|
||||
color: #409eff;
|
||||
margin-bottom: 4px;
|
||||
font-family: 'DIN Alternate', sans-serif;
|
||||
font-family: "DIN Alternate", sans-serif;
|
||||
}
|
||||
|
||||
.data-label {
|
||||
@ -443,4 +474,4 @@ onMounted(() => {
|
||||
align-items: center;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user