Phase 1 #20 #23: 通用模块 + Vue3 前端框架搭建

#20 通用模块:
- MinioService: MinIO 文件上传/下载/桶管理
- @DataScope 注解: 数据权限切片
- ExcelUtils: EasyExcel 导出
- IdUtils: Snowflake ID 生成器
- BaseEntity: MyBatis-Plus 基础实体

#23 前端框架:
- Vue3 + TypeScript + Vite + Element Plus + ECharts + Pinia
- 路由系统: 登录守卫 + 动态路由
- 登录页: 渐变背景 + Axios+Sa-Token 认证
- 仪表盘: 统计卡片 + 供水趋势折线图 + 片区饼图
- MainLayout: 侧边栏菜单 + 顶栏用户下拉(退出)
- API 层: Axios 请求/响应拦截器 + Token 自动注入
- 系统管理骨架: 用户/角色/菜单/部门 列表页
This commit is contained in:
bot_pm
2026-06-14 13:17:40 +08:00
parent 9a7e0481ef
commit 575b2138c1
24 changed files with 538 additions and 0 deletions
@@ -0,0 +1,62 @@
<template>
<div class="dashboard">
<h2>供水总览</h2>
<el-row :gutter="16">
<el-col :span="6" v-for="card in cards" :key="card.title">
<el-card shadow="hover">
<div class="stat-card">
<div class="stat-value">{{ card.value }}</div>
<div class="stat-title">{{ card.title }}</div>
</div>
</el-card>
</el-col>
</el-row>
<el-row :gutter="16" style="margin-top:16px">
<el-col :span="12"><el-card><div ref="chart1" style="height:300px" /></el-card></el-col>
<el-col :span="12"><el-card><div ref="chart2" style="height:300px" /></el-card></el-col>
</el-row>
</div>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue'
import * as echarts from 'echarts'
const cards = [
{ title: '今日进水(m³)', value: '12,580' },
{ title: '今日出水(m³)', value: '11,230' },
{ title: '在线设备', value: '156' },
{ title: '今日报警', value: '3' },
]
const chart1 = ref()
const chart2 = ref()
onMounted(() => {
const c1 = echarts.init(chart1.value)
c1.setOption({
title: { text: '24小时供水趋势' },
tooltip: { trigger: 'axis' },
xAxis: { data: ['00:00','04:00','08:00','12:00','16:00','20:00'] },
yAxis: { name: '流量(m³/h)' },
series: [{ data: [320,280,450,520,480,380], type: 'line', smooth: true, areaStyle: {} }]
})
const c2 = echarts.init(chart2.value)
c2.setOption({
title: { text: '片区用水分布' },
tooltip: {},
series: [{
type: 'pie', radius: ['45%','70%'],
data: [{ value: 3200, name: '一体化水厂' },{ value: 1800, name: '精芒片区' },
{ value: 1500, name: '八家户片区' },{ value: 1200, name: '托里片区' },
{ value: 900, name: '大镇片区' },{ value: 600, name: '托托片区' }]
}]
})
})
</script>
<style scoped>
.stat-card { text-align:center; padding:10px }
.stat-value { font-size:28px; font-weight:bold; color:#2a5298 }
.stat-title { color:#666; margin-top:8px }
</style>