更新环境监测页面和报告模块
This commit is contained in:
parent
fca3cde8bc
commit
a4496ca0fa
@ -3664,7 +3664,7 @@ GET /api/education/knowledge
|
||||
|»» created_by|integer|false|none||none|
|
||||
|»» updated_by|integer|false|none||none|
|
||||
|
||||
## GET 获取知识详情
|
||||
## GET
|
||||
|
||||
GET /api/education/knowledge/1
|
||||
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, reactive, onMounted } from "vue";
|
||||
import * as echarts from "echarts";
|
||||
import { ElMessage } from 'element-plus';
|
||||
import { Monitor, Warning, TrendCharts } from '@element-plus/icons-vue';
|
||||
import { ElMessage } from "element-plus";
|
||||
import { Monitor, Warning, TrendCharts } from "@element-plus/icons-vue";
|
||||
|
||||
interface EnvData {
|
||||
id: number;
|
||||
@ -65,7 +65,7 @@ const envStats = ref([
|
||||
]);
|
||||
|
||||
// 时间范围选择
|
||||
const timeRange = ref('24h');
|
||||
const timeRange = ref("24h");
|
||||
|
||||
// 初始化图表
|
||||
const initChart = () => {
|
||||
@ -75,167 +75,180 @@ const initChart = () => {
|
||||
const myChart = echarts.init(chartDom);
|
||||
const option = {
|
||||
title: {
|
||||
text: '环境监测趋势',
|
||||
text: "环境监测趋势",
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
fontWeight: 500,
|
||||
color: '#303133'
|
||||
}
|
||||
color: "#303133",
|
||||
},
|
||||
},
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
backgroundColor: 'rgba(255, 255, 255, 0.95)',
|
||||
borderColor: '#eee',
|
||||
trigger: "axis",
|
||||
backgroundColor: "rgba(255, 255, 255, 0.95)",
|
||||
borderColor: "#eee",
|
||||
padding: [10, 15],
|
||||
textStyle: {
|
||||
color: '#666'
|
||||
color: "#666",
|
||||
},
|
||||
formatter: function(params: any) {
|
||||
formatter: function (params: any) {
|
||||
let result = `${params[0].axisValue}<br/>`;
|
||||
params.forEach((item: any) => {
|
||||
result += `${item.marker} ${item.seriesName}: ${item.value}${
|
||||
item.seriesName.includes('温度') ? '°C' :
|
||||
item.seriesName.includes('湿度') ? '%' : ''
|
||||
item.seriesName.includes("温度")
|
||||
? "°C"
|
||||
: item.seriesName.includes("湿度")
|
||||
? "%"
|
||||
: ""
|
||||
}<br/>`;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
},
|
||||
},
|
||||
legend: {
|
||||
data: ['温度', '湿度', '水质指数', '空气质量'],
|
||||
data: ["温度", "湿度", "水质指数", "空气质量"],
|
||||
right: 20,
|
||||
top: 10,
|
||||
textStyle: {
|
||||
color: '#666'
|
||||
color: "#666",
|
||||
},
|
||||
itemWidth: 12,
|
||||
itemHeight: 12,
|
||||
itemGap: 20
|
||||
itemGap: 20,
|
||||
},
|
||||
grid: {
|
||||
left: '3%',
|
||||
right: '4%',
|
||||
bottom: '3%',
|
||||
containLabel: true
|
||||
left: "3%",
|
||||
right: "4%",
|
||||
bottom: "3%",
|
||||
containLabel: true,
|
||||
},
|
||||
xAxis: {
|
||||
type: 'category',
|
||||
type: "category",
|
||||
boundaryGap: false,
|
||||
data: ['00:00', '03:00', '06:00', '09:00', '12:00', '15:00', '18:00', '21:00', '24:00'],
|
||||
data: [
|
||||
"00:00",
|
||||
"03:00",
|
||||
"06:00",
|
||||
"09:00",
|
||||
"12:00",
|
||||
"15:00",
|
||||
"18:00",
|
||||
"21:00",
|
||||
"24:00",
|
||||
],
|
||||
axisLine: {
|
||||
lineStyle: {
|
||||
color: '#DCDFE6'
|
||||
}
|
||||
color: "#DCDFE6",
|
||||
},
|
||||
},
|
||||
axisTick: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#909399',
|
||||
formatter: '{value}'
|
||||
}
|
||||
color: "#909399",
|
||||
formatter: "{value}",
|
||||
},
|
||||
},
|
||||
yAxis: [
|
||||
{
|
||||
type: 'value',
|
||||
name: '温度/湿度',
|
||||
type: "value",
|
||||
name: "温度/湿度",
|
||||
nameTextStyle: {
|
||||
color: '#909399',
|
||||
padding: [0, 30, 0, 0]
|
||||
color: "#909399",
|
||||
padding: [0, 30, 0, 0],
|
||||
},
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: '#EBEEF5',
|
||||
type: 'dashed'
|
||||
}
|
||||
color: "#EBEEF5",
|
||||
type: "dashed",
|
||||
},
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#909399',
|
||||
formatter: '{value}'
|
||||
}
|
||||
color: "#909399",
|
||||
formatter: "{value}",
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'value',
|
||||
name: '指数',
|
||||
type: "value",
|
||||
name: "指数",
|
||||
nameTextStyle: {
|
||||
color: '#909399',
|
||||
padding: [0, 0, 0, 30]
|
||||
color: "#909399",
|
||||
padding: [0, 0, 0, 30],
|
||||
},
|
||||
splitLine: {
|
||||
show: false
|
||||
show: false,
|
||||
},
|
||||
axisLabel: {
|
||||
color: '#909399',
|
||||
formatter: '{value}'
|
||||
}
|
||||
}
|
||||
color: "#909399",
|
||||
formatter: "{value}",
|
||||
},
|
||||
},
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '温度',
|
||||
type: 'line',
|
||||
name: "温度",
|
||||
type: "line",
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: '#409EFF'
|
||||
color: "#409EFF",
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#409EFF'
|
||||
color: "#409EFF",
|
||||
},
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: 'rgba(64, 158, 255, 0.2)' },
|
||||
{ offset: 1, color: 'rgba(64, 158, 255, 0)' }
|
||||
])
|
||||
{ offset: 0, color: "rgba(64, 158, 255, 0.2)" },
|
||||
{ offset: 1, color: "rgba(64, 158, 255, 0)" },
|
||||
]),
|
||||
},
|
||||
data: [22, 23, 24, 25, 26, 27, 26, 25, 24]
|
||||
data: [22, 23, 24, 25, 26, 27, 26, 25, 24],
|
||||
},
|
||||
{
|
||||
name: '湿度',
|
||||
type: 'line',
|
||||
name: "湿度",
|
||||
type: "line",
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: '#67C23A'
|
||||
color: "#67C23A",
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#67C23A'
|
||||
color: "#67C23A",
|
||||
},
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: 'rgba(103, 194, 58, 0.2)' },
|
||||
{ offset: 1, color: 'rgba(103, 194, 58, 0)' }
|
||||
])
|
||||
{ offset: 0, color: "rgba(103, 194, 58, 0.2)" },
|
||||
{ offset: 1, color: "rgba(103, 194, 58, 0)" },
|
||||
]),
|
||||
},
|
||||
data: [60, 62, 65, 63, 65, 68, 67, 65, 64]
|
||||
data: [60, 62, 65, 63, 65, 68, 67, 65, 64],
|
||||
},
|
||||
{
|
||||
name: '水质指数',
|
||||
type: 'line',
|
||||
name: "水质指数",
|
||||
type: "line",
|
||||
yAxisIndex: 1,
|
||||
smooth: true,
|
||||
lineStyle: {
|
||||
width: 3,
|
||||
color: '#36CFC9'
|
||||
color: "#36CFC9",
|
||||
},
|
||||
itemStyle: {
|
||||
color: '#36CFC9'
|
||||
color: "#36CFC9",
|
||||
},
|
||||
areaStyle: {
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{ offset: 0, color: 'rgba(54, 207, 201, 0.2)' },
|
||||
{ offset: 1, color: 'rgba(54, 207, 201, 0)' }
|
||||
])
|
||||
{ offset: 0, color: "rgba(54, 207, 201, 0.2)" },
|
||||
{ offset: 1, color: "rgba(54, 207, 201, 0)" },
|
||||
]),
|
||||
},
|
||||
data: [90, 91, 92, 92, 93, 92, 92, 91, 92]
|
||||
}
|
||||
]
|
||||
data: [90, 91, 92, 92, 93, 92, 92, 91, 92],
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
myChart.setOption(option);
|
||||
|
||||
// 监听窗口大小变化
|
||||
window.addEventListener('resize', () => {
|
||||
window.addEventListener("resize", () => {
|
||||
myChart.resize();
|
||||
});
|
||||
};
|
||||
|
||||
@ -12,14 +12,14 @@ import {
|
||||
Cpu,
|
||||
Link,
|
||||
Cellphone,
|
||||
Share
|
||||
Share,
|
||||
} from "@element-plus/icons-vue";
|
||||
|
||||
const projectInfo = ref({
|
||||
title: "智慧湿地管理系统",
|
||||
version: "v2.0.0",
|
||||
description: `智慧湿地管理系统是一个基于现代信息技术的综合性湿地生态监测和管理平台。系统采用"前后端分离+小程序"的技术架构,
|
||||
实现了Web端管理和移动端监测的完整生态系统。通过实时数据采集、可视化展示等手段,为湿地生态保护提供智能化解决方案。`,
|
||||
description: `智慧湿地管理系统是一个基于现代信息技术的综合性湿地生态监测和管理平台。系统采用"Web管理端+微信小程序"的架构,
|
||||
通过多端协同为湿地生态保护提供智能化解决方案。`,
|
||||
|
||||
// 核心指标
|
||||
stats: [
|
||||
@ -49,7 +49,7 @@ const projectInfo = ref({
|
||||
change: "+15%",
|
||||
color: "#064E3B",
|
||||
bgColor: "linear-gradient(120deg, #4ADE80 0%, #22C55E 100%)",
|
||||
textColor: "#FFFFFF"
|
||||
textColor: "#FFFFFF",
|
||||
},
|
||||
{
|
||||
title: "设备在线",
|
||||
@ -59,7 +59,7 @@ const projectInfo = ref({
|
||||
change: "stable",
|
||||
color: "#EDE9FE",
|
||||
bgColor: "linear-gradient(120deg, #A78BFA 0%, #8B5CF6 100%)",
|
||||
textColor: "#FFFFFF"
|
||||
textColor: "#FFFFFF",
|
||||
},
|
||||
],
|
||||
|
||||
@ -73,40 +73,28 @@ const projectInfo = ref({
|
||||
{ name: "Element Plus", desc: "组件库" },
|
||||
{ name: "TypeScript", desc: "开发语言" },
|
||||
{ name: "ECharts", desc: "数据可视化" },
|
||||
{ name: "Vite", desc: "构建工具" }
|
||||
]
|
||||
{ name: "Vite", desc: "构建工具" },
|
||||
],
|
||||
},
|
||||
backend: {
|
||||
title: "后端服务",
|
||||
icon: Cpu,
|
||||
items: [
|
||||
{ name: "Node.js", desc: "运行环境" },
|
||||
{ name: "MySQL", desc: "数据存储" },
|
||||
{ name: "Redis", desc: "缓存服务" },
|
||||
{ name: "RESTful API", desc: "接口规范" },
|
||||
{ name: "WebSocket", desc: "实时通信" }
|
||||
]
|
||||
{ name: "MySQL", desc: "数据库" },
|
||||
{ name: "Apifox", desc: "接口管理" },
|
||||
],
|
||||
},
|
||||
miniapp: {
|
||||
title: "小程序端",
|
||||
icon: Cellphone,
|
||||
items: [
|
||||
{ name: "微信小程序", desc: "WXML & WXSS" },
|
||||
{ name: "微信小程序", desc: "原生开发" },
|
||||
{ name: "Vant Weapp", desc: "UI组件库" },
|
||||
{ name: "wx-charts", desc: "图表库" },
|
||||
{ name: "WebSocket", desc: "实时通信" }
|
||||
]
|
||||
{ name: "wx-charts", desc: "轻量图表库" },
|
||||
{ name: "ec-canvas", desc: "ECharts适配" },
|
||||
],
|
||||
},
|
||||
deployment: {
|
||||
title: "开发部署",
|
||||
icon: Share,
|
||||
items: [
|
||||
{ name: "Git", desc: "版本控制" },
|
||||
{ name: "Docker", desc: "容器化部署" },
|
||||
{ name: "Nginx", desc: "Web服务器" },
|
||||
{ name: "PM2", desc: "进程管理" }
|
||||
]
|
||||
}
|
||||
},
|
||||
|
||||
// 应用场景
|
||||
@ -115,33 +103,27 @@ const projectInfo = ref({
|
||||
title: "Web管理端",
|
||||
icon: Monitor,
|
||||
desc: "提供完整的湿地生态系统管理功能",
|
||||
features: ["数据看板", "环境监测", "物种管理", "系统配置"]
|
||||
},
|
||||
{
|
||||
title: "环境监测",
|
||||
icon: DataAnalysis,
|
||||
desc: "实时采集和分析环境数据",
|
||||
features: ["水质监测", "空气监测", "土壤监测", "气象监测"]
|
||||
features: ["数据看板", "环境监测", "物种管理", "系统配置"],
|
||||
},
|
||||
{
|
||||
title: "小程序端",
|
||||
icon: Cellphone,
|
||||
desc: "面向公众的湿地生态互动平台",
|
||||
features: [
|
||||
"实时数据查看",
|
||||
"生态科普",
|
||||
"环保打卡",
|
||||
"在线咨询",
|
||||
"消息通知"
|
||||
]
|
||||
"实时生态数据监测",
|
||||
"湿地生态知识科普",
|
||||
"最新公告通知",
|
||||
"环保行为打卡",
|
||||
"AI生态问答助手",
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "巡护管理",
|
||||
icon: Location,
|
||||
desc: "智能化的巡护任务管理系统",
|
||||
features: ["任务分配", "轨迹记录", "实时通讯", "数据采集"]
|
||||
}
|
||||
]
|
||||
title: "数据服务",
|
||||
icon: DataAnalysis,
|
||||
desc: "提供数据存储和分析能力",
|
||||
features: ["数据采集", "实时监测", "数据分析", "预警提醒"],
|
||||
},
|
||||
],
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -160,18 +142,19 @@ const projectInfo = ref({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 系统架构 -->
|
||||
<div class="architecture-section">
|
||||
<!-- 系统架构部分 -->
|
||||
<div class="section architecture-section">
|
||||
<h2>系统架构</h2>
|
||||
<div class="arch-grid">
|
||||
<el-card v-for="(arch, key) in projectInfo.architecture"
|
||||
<div class="card-grid">
|
||||
<el-card
|
||||
v-for="(arch, key) in projectInfo.architecture"
|
||||
:key="key"
|
||||
class="arch-card"
|
||||
shadow="hover">
|
||||
<div class="arch-header">
|
||||
<el-icon :size="24" :class="key">
|
||||
<component :is="arch.icon" />
|
||||
</el-icon>
|
||||
>
|
||||
<div class="card-header">
|
||||
<div :class="['icon-wrapper', key]">
|
||||
<el-icon><component :is="arch.icon" /></el-icon>
|
||||
</div>
|
||||
<h3>{{ arch.title }}</h3>
|
||||
</div>
|
||||
<ul class="tech-list">
|
||||
@ -184,14 +167,15 @@ const projectInfo = ref({
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 应用场景 -->
|
||||
<div class="scenarios-section">
|
||||
<!-- 应用场景部分 -->
|
||||
<div class="section scenarios-section">
|
||||
<h2>应用场景</h2>
|
||||
<div class="scenario-grid">
|
||||
<el-card v-for="scenario in projectInfo.scenarios"
|
||||
<div class="card-grid">
|
||||
<el-card
|
||||
v-for="scenario in projectInfo.scenarios"
|
||||
:key="scenario.title"
|
||||
class="scenario-card"
|
||||
shadow="hover">
|
||||
>
|
||||
<div class="scenario-icon">
|
||||
<el-icon :size="32">
|
||||
<component :is="scenario.icon" />
|
||||
@ -200,9 +184,7 @@ const projectInfo = ref({
|
||||
<h3>{{ scenario.title }}</h3>
|
||||
<p>{{ scenario.desc }}</p>
|
||||
<div class="feature-tags">
|
||||
<el-tag v-for="feature in scenario.features"
|
||||
:key="feature"
|
||||
size="small">
|
||||
<el-tag v-for="feature in scenario.features" :key="feature" size="small">
|
||||
{{ feature }}
|
||||
</el-tag>
|
||||
</div>
|
||||
@ -214,6 +196,108 @@ const projectInfo = ref({
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.about-container {
|
||||
padding: 20px;
|
||||
|
||||
.section {
|
||||
margin-bottom: 60px;
|
||||
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 24px;
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 24px; // 添加统一的内边距
|
||||
}
|
||||
}
|
||||
|
||||
// 统一卡片样式
|
||||
.el-card {
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s;
|
||||
height: 100%;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
|
||||
.card-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.icon-wrapper {
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
border-radius: 16px;
|
||||
font-size: 24px;
|
||||
|
||||
&.frontend {
|
||||
background: rgba(24, 144, 255, 0.1);
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
&.backend {
|
||||
background: rgba(82, 196, 26, 0.1);
|
||||
color: #52c41a;
|
||||
}
|
||||
|
||||
&.miniapp {
|
||||
background: rgba(250, 84, 28, 0.1);
|
||||
color: #fa541c;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 架构部分特有样式
|
||||
.tech-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.tech-name {
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.tech-desc {
|
||||
font-size: 13px;
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.hero-section {
|
||||
padding: 40px;
|
||||
margin: -20px -20px 20px;
|
||||
@ -264,105 +348,7 @@ const projectInfo = ref({
|
||||
}
|
||||
}
|
||||
|
||||
.architecture-section {
|
||||
margin-bottom: 60px;
|
||||
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.arch-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, 1fr);
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.arch-card {
|
||||
.arch-header {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 12px;
|
||||
margin-bottom: 20px;
|
||||
|
||||
.el-icon {
|
||||
padding: 12px;
|
||||
border-radius: 8px;
|
||||
|
||||
&.frontend {
|
||||
background: rgba(24, 144, 255, 0.1);
|
||||
color: #1890FF;
|
||||
}
|
||||
|
||||
&.backend {
|
||||
background: rgba(82, 196, 26, 0.1);
|
||||
color: #52C41A;
|
||||
}
|
||||
|
||||
&.miniapp {
|
||||
background: rgba(250, 84, 28, 0.1);
|
||||
color: #FA541C;
|
||||
}
|
||||
|
||||
&.tools {
|
||||
background: rgba(114, 46, 209, 0.1);
|
||||
color: #722ED1;
|
||||
}
|
||||
}
|
||||
|
||||
h3 {
|
||||
margin: 0;
|
||||
font-size: 18px;
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
.tech-list {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
|
||||
li {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
padding: 8px 0;
|
||||
border-bottom: 1px solid #f0f0f0;
|
||||
|
||||
&:last-child {
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
.tech-name {
|
||||
font-weight: 500;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.tech-desc {
|
||||
font-size: 13px;
|
||||
color: #909399;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scenarios-section {
|
||||
h2 {
|
||||
font-size: 24px;
|
||||
margin-bottom: 30px;
|
||||
text-align: center;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.scenario-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 24px;
|
||||
}
|
||||
|
||||
.scenario-card {
|
||||
text-align: center;
|
||||
padding: 30px;
|
||||
@ -376,7 +362,7 @@ const projectInfo = ref({
|
||||
justify-content: center;
|
||||
border-radius: 16px;
|
||||
background: rgba(24, 144, 255, 0.1);
|
||||
color: #1890FF;
|
||||
color: #1890ff;
|
||||
}
|
||||
|
||||
h3 {
|
||||
@ -403,16 +389,5 @@ const projectInfo = ref({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.el-card {
|
||||
border: none;
|
||||
border-radius: 12px;
|
||||
transition: all 0.3s;
|
||||
|
||||
&:hover {
|
||||
transform: translateY(-2px);
|
||||
box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user