364 lines
7.9 KiB
Vue
364 lines
7.9 KiB
Vue
<template>
|
||
<div class="dashboard-container">
|
||
<div class="dashboard-header">
|
||
<h1>仪表板</h1>
|
||
<p>欢迎回来,{{ userStore.nickname || userStore.username }}!</p>
|
||
</div>
|
||
|
||
<!-- 统计卡片 -->
|
||
<div class="stats-grid">
|
||
<div class="stat-card">
|
||
<div class="stat-icon user-icon">
|
||
<el-icon><User /></el-icon>
|
||
</div>
|
||
<div class="stat-content">
|
||
<h3>{{ stats.userCount }}</h3>
|
||
<p>用户总数</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stat-card">
|
||
<div class="stat-icon role-icon">
|
||
<el-icon><UserFilled /></el-icon>
|
||
</div>
|
||
<div class="stat-content">
|
||
<h3>{{ stats.roleCount }}</h3>
|
||
<p>角色总数</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stat-card">
|
||
<div class="stat-icon org-icon">
|
||
<el-icon><OfficeBuilding /></el-icon>
|
||
</div>
|
||
<div class="stat-content">
|
||
<h3>{{ stats.orgCount }}</h3>
|
||
<p>组织总数</p>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="stat-card">
|
||
<div class="stat-icon dict-icon">
|
||
<el-icon><Document /></el-icon>
|
||
</div>
|
||
<div class="stat-content">
|
||
<h3>{{ stats.dictCount }}</h3>
|
||
<p>字典总数</p>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- 快捷操作 -->
|
||
<div class="quick-actions">
|
||
<h2>快捷操作</h2>
|
||
<div class="actions-grid">
|
||
<el-card class="action-card" @click="routerclick('/Permission')">
|
||
<div class="action-content">
|
||
<el-icon class="action-icon"><User /></el-icon>
|
||
<span>用户管理</span>
|
||
</div>
|
||
</el-card>
|
||
|
||
<el-card class="action-card" @click="routerclick('/UserLogin')">
|
||
<div class="action-content">
|
||
<el-icon class="action-icon"><UserFilled /></el-icon>
|
||
<span>角色管理</span>
|
||
</div>
|
||
</el-card>
|
||
|
||
<el-card class="action-card" >
|
||
<div class="action-content">
|
||
<el-icon class="action-icon"><OfficeBuilding /></el-icon>
|
||
<span>组织管理</span>
|
||
</div>
|
||
</el-card>
|
||
|
||
<el-card class="action-card" @click="$router.push('/dictionaries')">
|
||
<div class="action-content">
|
||
<el-icon class="action-icon"><Document /></el-icon>
|
||
<span>字典管理</span>
|
||
</div>
|
||
</el-card>
|
||
</div>
|
||
</div>
|
||
<!-- 快捷操作 -->
|
||
<div class="quick-actions">
|
||
<h2>快捷操作</h2>
|
||
<div class="actions-grid">
|
||
<el-card class="action-card" @click="$router.push('/FormCreate?appId=1927666485224894465')">
|
||
<div class="action-content">
|
||
<el-icon class="action-icon"><User /></el-icon>
|
||
<span>FormCreat</span>
|
||
</div>
|
||
</el-card>
|
||
<el-card class="action-card" @click="$router.push('/visualization?id=1927640677370306561&busiFlag=dataV')">
|
||
<div class="action-content">
|
||
<el-icon class="action-icon"><User /></el-icon>
|
||
<span>GIS大屏</span>
|
||
</div>
|
||
</el-card>
|
||
<el-card class="action-card" @click="$router.push('/visualization?id=1927658989605187585&busiFlag=dashboard')">
|
||
<div class="action-content">
|
||
<el-icon class="action-icon"><User /></el-icon>
|
||
<span>数据看板</span>
|
||
</div>
|
||
</el-card>
|
||
</div>
|
||
</div>
|
||
<!-- 最近活动 -->
|
||
<div class="recent-activities">
|
||
<h2>最近活动</h2>
|
||
<el-card>
|
||
<el-timeline>
|
||
<el-timeline-item
|
||
v-for="activity in activities"
|
||
:key="activity.id"
|
||
:timestamp="activity.time"
|
||
:type="activity.type"
|
||
>
|
||
{{ activity.content }}
|
||
</el-timeline-item>
|
||
</el-timeline>
|
||
</el-card>
|
||
</div>
|
||
</div>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, reactive, onMounted } from 'vue'
|
||
import { useUserStore } from '@/store/user'
|
||
import { User, UserFilled, OfficeBuilding, Document } from '@element-plus/icons-vue'
|
||
import { useRouter } from 'vue-router'
|
||
const userStore = useUserStore()
|
||
const router = useRouter()
|
||
// 统计数据
|
||
const stats = reactive({
|
||
userCount: 0,
|
||
roleCount: 0,
|
||
orgCount: 0,
|
||
dictCount: 0
|
||
})
|
||
|
||
const activities = ref([
|
||
{
|
||
id: 1,
|
||
content: '系统启动成功',
|
||
time: '2024-01-01 09:00:00',
|
||
type: 'success'
|
||
},
|
||
{
|
||
id: 2,
|
||
content: '用户登录系统',
|
||
time: '2024-01-01 09:30:00',
|
||
type: 'primary'
|
||
},
|
||
{
|
||
id: 3,
|
||
content: '创建新用户',
|
||
time: '2024-01-01 10:00:00',
|
||
type: 'info'
|
||
},
|
||
{
|
||
id: 4,
|
||
content: '更新角色权限',
|
||
time: '2024-01-01 10:30:00',
|
||
type: 'warning'
|
||
}
|
||
])
|
||
|
||
// 加载统计数据
|
||
const loadStats = async () => {
|
||
try {
|
||
// 这里应该调用实际的API获取统计数据
|
||
// 暂时使用模拟数据
|
||
stats.userCount = 156
|
||
stats.roleCount = 8
|
||
stats.orgCount = 23
|
||
stats.dictCount = 45
|
||
} catch (error) {
|
||
console.error('加载统计数据失败:', error)
|
||
}
|
||
}
|
||
|
||
// 组件挂载时加载数据
|
||
onMounted(() => {
|
||
loadStats()
|
||
})
|
||
function routerclick(path) {
|
||
if(path == '/Permission'){
|
||
router.push({
|
||
path: path,
|
||
query: {
|
||
id: '1927554158852841473'
|
||
}
|
||
})
|
||
}else if(path == '/UserLogin'){
|
||
const route = router.resolve({
|
||
path: path,
|
||
query: { id: '1927554158852841473' ,name:'测试项目'}
|
||
});
|
||
window.open(route.href, '_blank');
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.dashboard-container {
|
||
padding: 20px;
|
||
max-width: 1200px;
|
||
margin: 0 auto;
|
||
}
|
||
|
||
.dashboard-header {
|
||
margin-bottom: 30px;
|
||
|
||
h1 {
|
||
color: #333;
|
||
margin-bottom: 8px;
|
||
font-size: 28px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
p {
|
||
color: #666;
|
||
font-size: 16px;
|
||
}
|
||
}
|
||
|
||
.stats-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
|
||
gap: 20px;
|
||
margin-bottom: 40px;
|
||
}
|
||
|
||
.stat-card {
|
||
background: white;
|
||
border-radius: 10px;
|
||
padding: 24px;
|
||
box-shadow: 0 2px 12px rgba(0, 0, 0, 0.1);
|
||
display: flex;
|
||
align-items: center;
|
||
gap: 16px;
|
||
transition: transform 0.2s, box-shadow 0.2s;
|
||
|
||
&:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||
}
|
||
}
|
||
|
||
.stat-icon {
|
||
width: 60px;
|
||
height: 60px;
|
||
border-radius: 12px;
|
||
display: flex;
|
||
align-items: center;
|
||
justify-content: center;
|
||
font-size: 24px;
|
||
color: white;
|
||
|
||
&.user-icon {
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
}
|
||
|
||
&.role-icon {
|
||
background: linear-gradient(135deg, #f093fb 0%, #f5576c 100%);
|
||
}
|
||
|
||
&.org-icon {
|
||
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
|
||
}
|
||
|
||
&.dict-icon {
|
||
background: linear-gradient(135deg, #43e97b 0%, #38f9d7 100%);
|
||
}
|
||
}
|
||
|
||
.stat-content {
|
||
h3 {
|
||
font-size: 32px;
|
||
font-weight: 700;
|
||
color: #333;
|
||
margin-bottom: 4px;
|
||
}
|
||
|
||
p {
|
||
color: #666;
|
||
font-size: 14px;
|
||
}
|
||
}
|
||
|
||
.quick-actions {
|
||
margin-bottom: 40px;
|
||
|
||
h2 {
|
||
color: #333;
|
||
margin-bottom: 20px;
|
||
font-size: 20px;
|
||
font-weight: 600;
|
||
}
|
||
}
|
||
|
||
.actions-grid {
|
||
display: grid;
|
||
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
|
||
gap: 16px;
|
||
}
|
||
|
||
.action-card {
|
||
cursor: pointer;
|
||
transition: transform 0.2s, box-shadow 0.2s;
|
||
|
||
&:hover {
|
||
transform: translateY(-2px);
|
||
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
||
}
|
||
}
|
||
|
||
.action-content {
|
||
display: flex;
|
||
flex-direction: column;
|
||
align-items: center;
|
||
gap: 12px;
|
||
padding: 20px;
|
||
|
||
.action-icon {
|
||
font-size: 32px;
|
||
color: #409eff;
|
||
}
|
||
|
||
span {
|
||
font-size: 16px;
|
||
font-weight: 500;
|
||
color: #333;
|
||
}
|
||
}
|
||
|
||
.recent-activities {
|
||
h2 {
|
||
color: #333;
|
||
margin-bottom: 20px;
|
||
font-size: 20px;
|
||
font-weight: 600;
|
||
}
|
||
|
||
.el-card {
|
||
padding: 20px;
|
||
}
|
||
}
|
||
|
||
@media (max-width: 768px) {
|
||
.dashboard-container {
|
||
padding: 16px;
|
||
}
|
||
|
||
.stats-grid {
|
||
grid-template-columns: 1fr;
|
||
}
|
||
|
||
.actions-grid {
|
||
grid-template-columns: repeat(2, 1fr);
|
||
}
|
||
}
|
||
</style> |