# 仪表盘页面设计文档
## 1. 页面概述
仪表盘页面是用户登录后看到的第一个界面,旨在提供系统关键信息的概览。它主要面向管理员、决策者和主管,展示核心业务指标、任务状态分布、近期活动等,以便用户快速掌握系统整体状况并做出决策。
## 2. 页面布局

### 2.1 布局结构
页面采用响应式网格布局,确保在不同屏幕尺寸下都有良好的可读性。
- **顶部**: 页面标题和一个时间范围选择器,用于筛选仪表盘数据。
- **中部**: 关键指标卡片区域,展示核心数据(如总任务数、待处理反馈等)。
- **下部**:
- **左侧**: 图表区域,通过饼图和柱状图展示任务状态和类型的分布。
- **右侧**: 近期活动或任务列表,展示最新的任务分配或状态变更。
### 2.2 响应式设计
- **桌面端**: 采用多列网格布局,充分利用屏幕空间。
- **平板端**: 网格列数减少,卡片和图表垂直堆叠。
- **移动端**: 单列布局,所有模块垂直排列,保证可读性。
## 3. 组件结构
```vue
任务状态分布
任务类型分布
近期任务动态
{{ row.status }}
```
## 4. 数据结构
```typescript
// 仪表盘统计数据
interface DashboardStats {
totalTasks: number;
pendingTasks: number;
pendingFeedback: number;
activeUsers: number;
}
// 图表数据项
interface ChartDataItem {
name: string;
value: number;
}
// 近期任务项
interface RecentTask {
id: number;
title: string;
assignee: string;
status: 'PENDING' | 'IN_PROGRESS' | 'COMPLETED' | 'REVIEWED';
updatedAt: string;
}
// 仪表盘完整数据
interface DashboardData {
stats: DashboardStats;
taskStatusDistribution: ChartDataItem[];
taskTypeDistribution: ChartDataItem[];
recentTasks: RecentTask[];
}
```
## 5. 状态管理
```typescript
// 组件内状态
const dateRange = ref<[Date, Date]>();
const loading = ref(true);
const error = ref(null);
// 全局状态 (Pinia Store)
const dashboardStore = useDashboardStore();
const { stats, taskStatusChartData, taskTypeChartData, recentTasks } = storeToRefs(dashboardStore);
```
## 6. 交互逻辑
### 6.1 数据加载
```typescript
// 在组件挂载时加载数据
onMounted(() => {
fetchDashboardData();
});
const fetchDashboardData = async () => {
try {
loading.value = true;
error.value = null;
// 从 store 中调用 action 加载数据
await dashboardStore.fetchDashboardData({
startDate: dateRange.value?.[0],
endDate: dateRange.value?.[1],
});
} catch (err) {
error.value = '仪表盘数据加载失败,请稍后重试。';
} finally {
loading.value = false;
}
};
// 当日期范围变化时重新加载数据
const handleDateChange = () => {
fetchDashboardData();
};
```
### 6.2 辅助函数
```typescript
// 根据任务状态返回不同的标签类型
const getStatusTagType = (status: RecentTask['status']) => {
switch (status) {
case 'PENDING': return 'warning';
case 'IN_PROGRESS': return 'primary';
case 'COMPLETED': return 'success';
case 'REVIEWED': return 'info';
default: return 'info';
}
};
```
## 7. API 调用
### 7.1 仪表盘 API
```typescript
// api/dashboard.ts
export const dashboardApi = {
getDashboardData: (params: { startDate?: Date; endDate?: Date }) =>
apiClient.get('/dashboard', { params })
};
// stores/dashboard.ts
export const useDashboardStore = defineStore('dashboard', {
state: (): DashboardData => ({
stats: { totalTasks: 0, pendingTasks: 0, pendingFeedback: 0, activeUsers: 0 },
taskStatusDistribution: [],
taskTypeDistribution: [],
recentTasks: [],
}),
getters: {
// 将后端数据转换为 ECharts 需要的格式
taskStatusChartData: (state) => ({
legend: state.taskStatusDistribution.map(item => item.name),
series: [{ data: state.taskStatusDistribution }]
}),
taskTypeChartData: (state) => ({
xAxis: state.taskTypeDistribution.map(item => item.name),
series: [{ data: state.taskTypeDistribution.map(item => item.value) }]
})
},
actions: {
async fetchDashboardData(params) {
try {
const { data } = await dashboardApi.getDashboardData(params);
// 更新整个 state
this.$patch(data);
return data;
} catch (error) {
console.error('获取仪表盘数据失败:', error);
throw error;
}
}
}
});
```
## 8. 样式设计
```scss
.dashboard-page {
padding: 24px;
.page-header {
margin-bottom: 24px;
}
.dashboard-filters {
margin-bottom: 24px;
}
.summary-cards {
margin-bottom: 20px;
}
.charts-section {
margin-bottom: 20px;
}
.el-card {
border: none;
border-radius: 8px;
}
.loading-state,
.error-state {
padding: 40px;
}
}
// 响应式样式
@media screen and (max-width: 768px) {
.dashboard-page {
padding: 16px;
.summary-cards .el-col,
.charts-section .el-col {
margin-bottom: 20px;
}
}
}
```
## 9. 测试用例
1. **单元测试**
- 测试 `getStatusTagType` 辅助函数的正确性。
- 测试 Pinia store中getters的数据转换逻辑。
- 测试 `StatisticCard`、`PieChart`、`BarChart` 组件的渲染是否正确。
2. **集成测试**
- 测试页面在加载、成功、失败状态下的显示。
- 测试日期选择器筛选功能是否能正确触发数据重新加载。
- 模拟 API 调用,验证数据是否正确渲染到页面上。
## 10. 性能优化
1. **懒加载图表**: 使用 `v-if` 或动态导入,确保图表库只在需要时加载和渲染。
2. **骨架屏**: 在数据加载时使用骨架屏,提升用户体验。
3. **数据缓存**: 对不经常变化的数据(如任务类型),可以在 Pinia store 中设置缓存策略,避免重复请求。
4. **节流/防抖**: 对日期选择器的 `change` 事件使用节流或防抖,防止用户快速操作导致频繁的 API 请求。