forked from 77media/video-flow
747 lines
19 KiB
Markdown
747 lines
19 KiB
Markdown
# Dashboard页面功能与接口调用全面分析
|
||
|
||
## 📋 概述
|
||
|
||
基于资深全栈开发视角,对Dashboard页面的功能架构、接口调用、数据流程和技术实现进行全面分析。
|
||
|
||
## 🏗️ 架构概览
|
||
|
||
### 1. 页面结构
|
||
```
|
||
Dashboard页面 (app/dashboard/page.tsx)
|
||
├── 页面容器组件
|
||
├── NetworkTimeline组件 (核心功能组件)
|
||
├── 数据获取逻辑
|
||
├── 实时刷新机制
|
||
└── 错误处理机制
|
||
```
|
||
|
||
### 2. 核心组件
|
||
- **主页面**: `app/dashboard/page.tsx` - 页面入口和数据管理
|
||
- **时间线组件**: `components/dashboard/network-timeline.tsx` - 核心功能实现
|
||
- **API层**: `api/video_flow.ts` - 接口调用封装
|
||
|
||
## 🔌 接口调用分析
|
||
|
||
### 1. 主要接口
|
||
|
||
#### 1.1 获取项目任务列表 (核心接口)
|
||
```typescript
|
||
// 接口定义
|
||
export const getProjectTaskList = async (data: {
|
||
project_id: string;
|
||
}): Promise<ApiResponse<TaskItem[]>>
|
||
|
||
// 接口地址
|
||
POST https://77.smartvideo.py.qikongjian.com/task/get_project_task_list
|
||
|
||
// 请求参数
|
||
{
|
||
"project_id": "d203016d-6f7e-4d1c-b66b-1b7d33632800"
|
||
}
|
||
|
||
// 响应结构
|
||
{
|
||
"code": 0,
|
||
"message": "操作成功",
|
||
"data": [
|
||
{
|
||
"plan_id": "string",
|
||
"task_id": "string",
|
||
"start_time": "2025-08-24T17:37:31",
|
||
"end_time": "2025-08-24T17:37:31",
|
||
"task_name": "string",
|
||
"task_status": "SUCCESS|FAILED|COMPLETED|IN_PROGRESS|INIT",
|
||
"task_result": "string|object",
|
||
"task_params": "string",
|
||
"task_message": "string",
|
||
"created_at": "2025-08-23T02:40:58",
|
||
"updated_at": "2025-08-24T17:37:31",
|
||
"error_message": "string|null",
|
||
"error_traceback": "string|null",
|
||
"parent_task_id": "string|null",
|
||
"sub_tasks": [...]
|
||
}
|
||
],
|
||
"successful": true
|
||
}
|
||
```
|
||
|
||
#### 1.2 其他相关接口
|
||
```typescript
|
||
// 项目详情
|
||
detailScriptEpisodeNew(data: { project_id: string })
|
||
|
||
// 项目标题
|
||
getScriptTitle(data: { project_id: string })
|
||
|
||
// 运行状态数据
|
||
getRunningStreamData(data: { project_id: string })
|
||
```
|
||
|
||
### 2. 接口调用策略
|
||
|
||
#### 2.1 数据获取流程
|
||
```typescript
|
||
// 主页面数据获取逻辑
|
||
const fetchDashboardData = async () => {
|
||
try {
|
||
setIsLoading(true);
|
||
const response = await getProjectTaskList({ project_id: projectId });
|
||
|
||
if (response.code === 0) {
|
||
setDashboardData(response.data);
|
||
setLastUpdate(new Date());
|
||
} else {
|
||
// 降级到Mock数据
|
||
setDashboardData(mockTaskData);
|
||
}
|
||
} catch (error) {
|
||
console.error('获取任务数据失败:', error);
|
||
setDashboardData(mockTaskData);
|
||
} finally {
|
||
setIsLoading(false);
|
||
}
|
||
};
|
||
```
|
||
|
||
#### 2.2 智能刷新机制
|
||
```typescript
|
||
// 智能轮询逻辑
|
||
useEffect(() => {
|
||
if (!isPolling || !dashboardData) return;
|
||
|
||
// 检查是否有活跃任务
|
||
const hasRunningTasks = dashboardData.some((task: any) =>
|
||
task.task_status === 'IN_PROGRESS' ||
|
||
task.task_status === 'INIT' ||
|
||
(task.sub_tasks && task.sub_tasks.some((subTask: any) =>
|
||
subTask.task_status === 'IN_PROGRESS' ||
|
||
subTask.task_status === 'INIT'
|
||
))
|
||
);
|
||
|
||
if (hasRunningTasks) {
|
||
const interval = setInterval(fetchDashboardData, 5000); // 5秒轮询
|
||
return () => clearInterval(interval);
|
||
}
|
||
}, [isPolling, dashboardData]);
|
||
```
|
||
|
||
## 📊 数据处理分析
|
||
|
||
### 1. 数据结构转换
|
||
|
||
#### 1.1 任务执行对象定义
|
||
```typescript
|
||
interface TaskExecution {
|
||
id: string; // 任务ID
|
||
name: string; // 任务名称
|
||
displayName: string; // 显示名称
|
||
status: string; // 任务状态
|
||
statusCode: number; // 状态码
|
||
type: string; // 任务类型
|
||
dataSize: number; // 数据大小
|
||
executionTime: number; // 执行时间
|
||
startTime: number; // 开始时间
|
||
endTime: number; // 结束时间
|
||
progress: number; // 进度百分比
|
||
level: number; // 层级:0=主任务,1=子任务
|
||
parentId?: string; // 父任务ID
|
||
isExpanded?: boolean; // 是否展开子任务
|
||
subTasks?: TaskExecution[]; // 子任务列表
|
||
phases: { // 执行阶段
|
||
initialization?: number;
|
||
dataLoading?: number;
|
||
aiProcessing?: number;
|
||
resultGeneration?: number;
|
||
dataTransfer?: number;
|
||
completion?: number;
|
||
};
|
||
taskResult?: any; // 任务结果
|
||
}
|
||
```
|
||
|
||
#### 1.2 数据转换逻辑
|
||
```typescript
|
||
// 主任务处理
|
||
const mainTask: TaskExecution = {
|
||
id: task.task_id,
|
||
name: task.task_name,
|
||
displayName: getTaskDisplayName(task.task_name),
|
||
status: task.task_status,
|
||
statusCode: getTaskStatusCode(task.task_status),
|
||
type: getTaskType(task.task_name),
|
||
// ... 其他字段映射
|
||
};
|
||
|
||
// 子任务处理
|
||
if (task.sub_tasks && Array.isArray(task.sub_tasks)) {
|
||
const realSubTasks = task.sub_tasks.map((subTask: any) => ({
|
||
id: subTask.task_id,
|
||
name: subTask.task_name,
|
||
status: subTask.task_status,
|
||
level: 1,
|
||
parentId: task.task_id,
|
||
// ... 其他字段映射
|
||
}));
|
||
mainTask.subTasks = realSubTasks;
|
||
}
|
||
```
|
||
|
||
### 2. 数据映射函数
|
||
|
||
#### 2.1 任务类型映射
|
||
```typescript
|
||
function getTaskType(taskName: string): string {
|
||
const typeMap: Record<string, string> = {
|
||
'generate_character': 'AI',
|
||
'generate_character_image': 'AI',
|
||
'generate_sketch': 'AI',
|
||
'generate_shot_sketch': 'AI',
|
||
'generate_video': 'Video',
|
||
'generate_videos': 'Video',
|
||
'generate_music': 'Audio',
|
||
'final_composition': 'Comp',
|
||
'refine_orginal_script': 'Script',
|
||
'generate_production_bible': 'Doc',
|
||
'generate_production_bible_json': 'Data'
|
||
};
|
||
return typeMap[taskName] || 'Task';
|
||
}
|
||
```
|
||
|
||
#### 2.2 状态映射
|
||
```typescript
|
||
function getTaskStatusCode(status: string): number {
|
||
const statusCodeMap: Record<string, number> = {
|
||
'SUCCESS': 200,
|
||
'COMPLETED': 200,
|
||
'FINISHED': 200,
|
||
'IN_PROGRESS': 202,
|
||
'RUNNING': 202,
|
||
'PROCESSING': 202,
|
||
'INIT': 100,
|
||
'PENDING': 100,
|
||
'QUEUED': 100,
|
||
'FAILED': 500,
|
||
'FAILURE': 500,
|
||
'ERROR': 500,
|
||
'CANCELLED': 499,
|
||
'TIMEOUT': 408
|
||
};
|
||
return statusCodeMap[status] || 500;
|
||
}
|
||
```
|
||
|
||
## 🎨 功能特性分析
|
||
|
||
### 1. 核心功能
|
||
|
||
#### 1.1 任务监控面板
|
||
- **实时状态显示**: 显示所有任务的执行状态
|
||
- **层级结构**: 支持主任务和子任务的层级显示
|
||
- **进度跟踪**: 实时显示任务执行进度
|
||
- **时间信息**: 显示开始时间、结束时间、执行时长
|
||
|
||
#### 1.2 交互功能
|
||
- **展开/收起**: 主任务可展开查看子任务
|
||
- **任务详情**: 点击任务查看详细信息
|
||
- **搜索过滤**: 支持按名称、状态、类型搜索
|
||
- **类型过滤**: 动态下拉选择过滤任务类型
|
||
|
||
#### 1.3 可视化展示
|
||
- **网络时间线**: 可视化任务执行时间线
|
||
- **状态图标**: 不同状态使用不同颜色和图标
|
||
- **进度条**: 直观显示任务完成进度
|
||
- **错误提示**: 悬停显示详细错误信息
|
||
|
||
### 2. 高级功能
|
||
|
||
#### 2.1 智能刷新
|
||
```typescript
|
||
// 基于任务状态的智能轮询
|
||
const hasRunningTasks = dashboardData.some((task: any) =>
|
||
task.task_status === 'IN_PROGRESS' ||
|
||
task.task_status === 'INIT'
|
||
);
|
||
|
||
if (hasRunningTasks) {
|
||
// 启动5秒轮询
|
||
const interval = setInterval(fetchDashboardData, 5000);
|
||
}
|
||
```
|
||
|
||
#### 2.2 错误处理
|
||
```typescript
|
||
// 多层级错误处理
|
||
try {
|
||
const response = await getProjectTaskList({ project_id });
|
||
// 处理成功响应
|
||
} catch (error) {
|
||
console.error('API调用失败:', error);
|
||
// 降级到Mock数据
|
||
setDashboardData(mockTaskData);
|
||
}
|
||
```
|
||
|
||
#### 2.3 性能优化
|
||
```typescript
|
||
// 数据计算优化
|
||
const mainTaskExecutions = useMemo(() => {
|
||
// 主任务计算,不依赖展开状态
|
||
}, [tasks]);
|
||
|
||
const taskExecutions = useMemo(() => {
|
||
// 轻量级展开状态处理
|
||
}, [mainTaskExecutions, expandedTasks]);
|
||
|
||
// 函数缓存
|
||
const toggleTaskExpansion = React.useCallback((taskId: string) => {
|
||
// 展开切换逻辑
|
||
}, []);
|
||
```
|
||
|
||
## 📈 统计信息
|
||
|
||
### 1. 任务统计
|
||
```typescript
|
||
const taskStats = useMemo(() => {
|
||
const stats = { total: 0, completed: 0, inProgress: 0, failed: 0, pending: 0 };
|
||
|
||
tasks.forEach((task: any) => {
|
||
stats.total++;
|
||
const status = task.task_status;
|
||
|
||
if (['COMPLETED', 'SUCCESS'].includes(status)) {
|
||
stats.completed++;
|
||
} else if (['IN_PROGRESS', 'RUNNING', 'PROCESSING'].includes(status)) {
|
||
stats.inProgress++;
|
||
} else if (['FAILED', 'FAILURE', 'ERROR'].includes(status)) {
|
||
stats.failed++;
|
||
} else {
|
||
stats.pending++;
|
||
}
|
||
});
|
||
|
||
return stats;
|
||
}, [tasks]);
|
||
```
|
||
|
||
### 2. 进度计算
|
||
```typescript
|
||
// 基于子任务的进度计算
|
||
function getTaskProgress(task: any): number {
|
||
if (task.sub_tasks && Array.isArray(task.sub_tasks) && task.sub_tasks.length > 0) {
|
||
const completedSubTasks = task.sub_tasks.filter((sub: any) =>
|
||
['SUCCESS', 'COMPLETED', 'FINISHED'].includes(sub.task_status)
|
||
).length;
|
||
return Math.round((completedSubTasks / task.sub_tasks.length) * 100);
|
||
}
|
||
|
||
// 其他进度计算逻辑...
|
||
}
|
||
```
|
||
|
||
## 🔧 技术实现
|
||
|
||
### 1. 状态管理
|
||
```typescript
|
||
// React状态管理
|
||
const [dashboardData, setDashboardData] = useState<any[]>([]);
|
||
const [isLoading, setIsLoading] = useState(true);
|
||
const [isPolling, setIsPolling] = useState(false);
|
||
const [lastUpdate, setLastUpdate] = useState<Date | null>(null);
|
||
const [selectedTask, setSelectedTask] = useState<string | null>(null);
|
||
const [expandedTasks, setExpandedTasks] = useState<Set<string>>(new Set());
|
||
```
|
||
|
||
### 2. 动画系统
|
||
```typescript
|
||
// Framer Motion动画
|
||
<motion.button
|
||
whileHover={{ scale: 1.1 }}
|
||
whileTap={{ scale: 0.95 }}
|
||
animate={{ rotate: expandedTasks.has(task.id) ? 90 : 0 }}
|
||
transition={{ duration: 0.2, ease: "easeOut" }}
|
||
>
|
||
```
|
||
|
||
### 3. 样式系统
|
||
```typescript
|
||
// Tailwind CSS + 条件样式
|
||
className={cn(
|
||
"flex items-center px-4 py-2 text-sm border-b border-gray-800/30",
|
||
"cursor-pointer hover:bg-gray-800/50 transition-all duration-200",
|
||
selectedTask === task.id && "bg-blue-600/20",
|
||
task.level === 1 && "ml-4 bg-gray-900/30"
|
||
)}
|
||
```
|
||
|
||
## 📊 数据流程图
|
||
|
||
```
|
||
用户访问Dashboard
|
||
↓
|
||
获取project_id (URL参数)
|
||
↓
|
||
调用getProjectTaskList接口
|
||
↓
|
||
数据转换和处理
|
||
↓
|
||
渲染NetworkTimeline组件
|
||
↓
|
||
用户交互 (展开/搜索/过滤)
|
||
↓
|
||
智能刷新检测
|
||
↓
|
||
条件性轮询更新
|
||
```
|
||
|
||
## 🎯 核心价值
|
||
|
||
### 1. 用户价值
|
||
- **实时监控**: 实时了解任务执行状态
|
||
- **层次清晰**: 主任务和子任务层级分明
|
||
- **操作便捷**: 直观的交互和搜索功能
|
||
- **信息完整**: 详细的任务信息和错误提示
|
||
|
||
### 2. 技术价值
|
||
- **性能优化**: 智能轮询和数据缓存
|
||
- **用户体验**: 流畅的动画和交互
|
||
- **可维护性**: 清晰的组件结构和数据流
|
||
- **扩展性**: 支持新的任务类型和状态
|
||
|
||
### 3. 业务价值
|
||
- **提升效率**: 快速定位和解决问题
|
||
- **降低成本**: 减少人工监控成本
|
||
- **增强体验**: 专业的监控界面
|
||
- **数据驱动**: 基于真实数据的决策支持
|
||
|
||
## 🚀 总结
|
||
|
||
Dashboard页面是一个功能完整、技术先进的任务监控系统,具备:
|
||
|
||
1. **完整的数据流程**: 从API调用到UI展示的完整链路
|
||
2. **智能的交互设计**: 基于用户需求的功能设计
|
||
3. **优秀的性能表现**: 通过多种优化策略确保流畅体验
|
||
4. **强大的扩展能力**: 支持未来功能扩展和数据结构变化
|
||
|
||
该系统充分体现了现代前端开发的最佳实践,是一个高质量的企业级应用。
|
||
|
||
## 🔍 深度技术分析
|
||
|
||
### 1. 接口设计模式
|
||
|
||
#### 1.1 RESTful API设计
|
||
```typescript
|
||
// 统一的API响应格式
|
||
interface ApiResponse<T> {
|
||
code: number; // 状态码:0=成功,非0=失败
|
||
message: string; // 响应消息
|
||
data: T; // 响应数据
|
||
successful: boolean; // 成功标识
|
||
}
|
||
|
||
// 错误处理策略
|
||
const handleApiError = (error: any) => {
|
||
if (error.code === 'NETWORK_ERROR') {
|
||
return '网络连接失败,请检查网络连接';
|
||
} else if (error.response?.status === 404) {
|
||
return 'API接口不存在';
|
||
} else if (error.response?.status === 500) {
|
||
return '服务器内部错误';
|
||
}
|
||
return error.message || '未知错误';
|
||
};
|
||
```
|
||
|
||
#### 1.2 数据缓存策略
|
||
```typescript
|
||
// 智能数据比较
|
||
const hasDataChanged = (newData: any, oldData: any) => {
|
||
if (!oldData || !newData) return true;
|
||
try {
|
||
return JSON.stringify(newData) !== JSON.stringify(oldData);
|
||
} catch {
|
||
return true; // 比较失败时认为数据已变化
|
||
}
|
||
};
|
||
|
||
// 后台静默刷新
|
||
const refreshDataSilently = async () => {
|
||
const response = await getProjectTaskList({ project_id: projectId });
|
||
if (hasDataChanged(response.data, dashboardData)) {
|
||
setDashboardData(response.data);
|
||
console.log('数据已更新');
|
||
} else {
|
||
console.log('数据无变化');
|
||
}
|
||
};
|
||
```
|
||
|
||
### 2. 组件架构设计
|
||
|
||
#### 2.1 组件职责分离
|
||
```typescript
|
||
// 页面组件 (app/dashboard/page.tsx)
|
||
// 职责:数据获取、状态管理、错误处理
|
||
export default function DashboardPage() {
|
||
// 数据管理逻辑
|
||
// 轮询逻辑
|
||
// 错误处理逻辑
|
||
}
|
||
|
||
// 展示组件 (components/dashboard/network-timeline.tsx)
|
||
// 职责:UI渲染、用户交互、数据展示
|
||
export function NetworkTimeline({ tasks, onRefresh, ... }) {
|
||
// UI渲染逻辑
|
||
// 交互处理逻辑
|
||
// 数据过滤和搜索逻辑
|
||
}
|
||
```
|
||
|
||
#### 2.2 Hook设计模式
|
||
```typescript
|
||
// 自定义Hook示例
|
||
const useTaskPolling = (projectId: string, interval: number) => {
|
||
const [data, setData] = useState(null);
|
||
const [isPolling, setIsPolling] = useState(false);
|
||
|
||
useEffect(() => {
|
||
if (!isPolling) return;
|
||
|
||
const timer = setInterval(async () => {
|
||
const response = await getProjectTaskList({ project_id: projectId });
|
||
setData(response.data);
|
||
}, interval);
|
||
|
||
return () => clearInterval(timer);
|
||
}, [projectId, interval, isPolling]);
|
||
|
||
return { data, isPolling, setIsPolling };
|
||
};
|
||
```
|
||
|
||
### 3. 性能优化策略
|
||
|
||
#### 3.1 渲染优化
|
||
```typescript
|
||
// 虚拟化长列表 (如果任务数量很大)
|
||
import { FixedSizeList as List } from 'react-window';
|
||
|
||
const TaskList = ({ tasks }) => (
|
||
<List
|
||
height={600}
|
||
itemCount={tasks.length}
|
||
itemSize={60}
|
||
itemData={tasks}
|
||
>
|
||
{TaskItem}
|
||
</List>
|
||
);
|
||
|
||
// 防抖搜索
|
||
const debouncedSearch = useMemo(
|
||
() => debounce((term: string) => {
|
||
setFilteredTasks(tasks.filter(task =>
|
||
task.name.toLowerCase().includes(term.toLowerCase())
|
||
));
|
||
}, 300),
|
||
[tasks]
|
||
);
|
||
```
|
||
|
||
#### 3.2 内存管理
|
||
```typescript
|
||
// 清理定时器和事件监听
|
||
useEffect(() => {
|
||
const interval = setInterval(fetchData, 5000);
|
||
const handleVisibilityChange = () => {
|
||
if (document.hidden) {
|
||
clearInterval(interval);
|
||
}
|
||
};
|
||
|
||
document.addEventListener('visibilitychange', handleVisibilityChange);
|
||
|
||
return () => {
|
||
clearInterval(interval);
|
||
document.removeEventListener('visibilitychange', handleVisibilityChange);
|
||
};
|
||
}, []);
|
||
```
|
||
|
||
### 4. 错误边界和容错机制
|
||
|
||
#### 4.1 React错误边界
|
||
```typescript
|
||
class TaskErrorBoundary extends React.Component {
|
||
constructor(props) {
|
||
super(props);
|
||
this.state = { hasError: false };
|
||
}
|
||
|
||
static getDerivedStateFromError(error) {
|
||
return { hasError: true };
|
||
}
|
||
|
||
componentDidCatch(error, errorInfo) {
|
||
console.error('任务组件错误:', error, errorInfo);
|
||
}
|
||
|
||
render() {
|
||
if (this.state.hasError) {
|
||
return <div>任务加载失败,请刷新页面</div>;
|
||
}
|
||
return this.props.children;
|
||
}
|
||
}
|
||
```
|
||
|
||
#### 4.2 API容错机制
|
||
```typescript
|
||
// 重试机制
|
||
const fetchWithRetry = async (url: string, options: any, retries = 3) => {
|
||
for (let i = 0; i < retries; i++) {
|
||
try {
|
||
const response = await fetch(url, options);
|
||
if (response.ok) return response;
|
||
} catch (error) {
|
||
if (i === retries - 1) throw error;
|
||
await new Promise(resolve => setTimeout(resolve, 1000 * (i + 1)));
|
||
}
|
||
}
|
||
};
|
||
|
||
// 降级策略
|
||
const fetchDataWithFallback = async () => {
|
||
try {
|
||
return await getProjectTaskList({ project_id });
|
||
} catch (error) {
|
||
console.warn('API调用失败,使用Mock数据');
|
||
return { code: 0, data: mockTaskData };
|
||
}
|
||
};
|
||
```
|
||
|
||
### 5. 测试策略
|
||
|
||
#### 5.1 单元测试
|
||
```typescript
|
||
// 数据转换函数测试
|
||
describe('getTaskType', () => {
|
||
it('should return correct task type', () => {
|
||
expect(getTaskType('generate_character')).toBe('AI');
|
||
expect(getTaskType('generate_video')).toBe('Video');
|
||
expect(getTaskType('unknown_task')).toBe('Task');
|
||
});
|
||
});
|
||
|
||
// 组件测试
|
||
describe('NetworkTimeline', () => {
|
||
it('should render task list correctly', () => {
|
||
const mockTasks = [{ task_id: '1', task_name: 'test' }];
|
||
render(<NetworkTimeline tasks={mockTasks} />);
|
||
expect(screen.getByText('test')).toBeInTheDocument();
|
||
});
|
||
});
|
||
```
|
||
|
||
#### 5.2 集成测试
|
||
```typescript
|
||
// API集成测试
|
||
describe('Dashboard API Integration', () => {
|
||
it('should fetch and display task data', async () => {
|
||
const mockResponse = { code: 0, data: mockTasks };
|
||
jest.spyOn(api, 'getProjectTaskList').mockResolvedValue(mockResponse);
|
||
|
||
render(<DashboardPage />);
|
||
|
||
await waitFor(() => {
|
||
expect(screen.getByText('任务列表')).toBeInTheDocument();
|
||
});
|
||
});
|
||
});
|
||
```
|
||
|
||
### 6. 监控和日志
|
||
|
||
#### 6.1 性能监控
|
||
```typescript
|
||
// 性能指标收集
|
||
const usePerformanceMonitor = () => {
|
||
useEffect(() => {
|
||
const observer = new PerformanceObserver((list) => {
|
||
list.getEntries().forEach((entry) => {
|
||
if (entry.entryType === 'measure') {
|
||
console.log(`${entry.name}: ${entry.duration}ms`);
|
||
}
|
||
});
|
||
});
|
||
|
||
observer.observe({ entryTypes: ['measure'] });
|
||
|
||
return () => observer.disconnect();
|
||
}, []);
|
||
};
|
||
|
||
// 渲染时间测量
|
||
const measureRenderTime = (componentName: string) => {
|
||
performance.mark(`${componentName}-start`);
|
||
|
||
useEffect(() => {
|
||
performance.mark(`${componentName}-end`);
|
||
performance.measure(
|
||
`${componentName}-render`,
|
||
`${componentName}-start`,
|
||
`${componentName}-end`
|
||
);
|
||
});
|
||
};
|
||
```
|
||
|
||
#### 6.2 错误日志
|
||
```typescript
|
||
// 错误上报
|
||
const reportError = (error: Error, context: string) => {
|
||
const errorInfo = {
|
||
message: error.message,
|
||
stack: error.stack,
|
||
context,
|
||
timestamp: new Date().toISOString(),
|
||
userAgent: navigator.userAgent,
|
||
url: window.location.href
|
||
};
|
||
|
||
// 发送到错误监控服务
|
||
fetch('/api/errors', {
|
||
method: 'POST',
|
||
headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify(errorInfo)
|
||
});
|
||
};
|
||
```
|
||
|
||
## 🎯 最佳实践总结
|
||
|
||
### 1. 代码质量
|
||
- **TypeScript**: 完整的类型定义和类型安全
|
||
- **ESLint/Prettier**: 代码规范和格式化
|
||
- **组件化**: 高内聚低耦合的组件设计
|
||
- **Hook复用**: 自定义Hook提取公共逻辑
|
||
|
||
### 2. 用户体验
|
||
- **加载状态**: 清晰的加载和错误状态提示
|
||
- **响应式设计**: 适配不同屏幕尺寸
|
||
- **无障碍访问**: 键盘导航和屏幕阅读器支持
|
||
- **性能优化**: 快速响应和流畅动画
|
||
|
||
### 3. 可维护性
|
||
- **模块化**: 清晰的文件结构和模块划分
|
||
- **文档化**: 完整的注释和文档
|
||
- **测试覆盖**: 单元测试和集成测试
|
||
- **版本控制**: 规范的Git提交和分支管理
|
||
|
||
这个Dashboard系统展现了现代React应用开发的最佳实践,是一个技术先进、用户友好、可维护性强的企业级应用。
|