104 lines
2.9 KiB
Markdown
104 lines
2.9 KiB
Markdown
# 每日浏览任务追踪方案
|
|
|
|
## 目标
|
|
在前端路由变化时自动调用 `tasks.track` 上报浏览行为,使每日浏览任务能够正常统计进度。
|
|
|
|
---
|
|
|
|
## 当前状态分析
|
|
|
|
| 问题 | 原因 |
|
|
|------|------|
|
|
| 每日浏览任务不工作 | 前端没有在任何地方调用 `tasks.track({ action_type: 'browse' })` |
|
|
| 后端 API 已就绪 | `TaskTrackAPIView` 支持 `browse` action_type |
|
|
| 前端请求函数已存在 | `api_request.tasks.track({ action_type, count })` 已定义 |
|
|
|
|
---
|
|
|
|
## 实现方案
|
|
|
|
### 核心思路
|
|
在 `App.tsx` 中添加一个全局路由监听组件,当路由变化时调用 `tasks.track`。
|
|
|
|
### 需要修改的文件
|
|
|
|
| 文件 | 修改内容 |
|
|
|------|----------|
|
|
| `App.tsx` | 添加 `RouteChangeTracker` 组件,监听路由变化并上报浏览 |
|
|
| `hooks/useRouteTracker.ts` (新增) | 封装路由追踪逻辑,包含节流和登录判断 |
|
|
|
|
---
|
|
|
|
## 详细实现
|
|
|
|
### Step 1: 创建自定义 Hook `useRouteTracker`
|
|
|
|
**文件**: `src/hooks/useRouteTracker.ts`
|
|
|
|
```typescript
|
|
import { useEffect, useRef } from 'react';
|
|
import { useLocation } from 'react-router-dom';
|
|
import { useSelector } from 'react-redux';
|
|
import { selectIsLogin } from '@/features/login';
|
|
import { api_request } from '@/utils/request';
|
|
|
|
const TRACK_THROTTLE_MS = 3000; // 3秒内不重复上报同一页面
|
|
|
|
export const useRouteTracker = () => {
|
|
const location = useLocation();
|
|
const isLogin = useSelector(selectIsLogin);
|
|
const lastTrackedPath = useRef<string>('');
|
|
const lastTrackedTime = useRef<number>(0);
|
|
|
|
useEffect(() => {
|
|
if (!isLogin) return;
|
|
|
|
const currentPath = location.pathname + location.search;
|
|
const now = Date.now();
|
|
|
|
// 节流:同一页面 3 秒内不重复上报
|
|
if (currentPath === lastTrackedPath.current && now - lastTrackedTime.current < TRACK_THROTTLE_MS) {
|
|
return;
|
|
}
|
|
|
|
lastTrackedPath.current = currentPath;
|
|
lastTrackedTime.current = now;
|
|
|
|
api_request.tasks.track({ action_type: 'browse', count: 1 }).catch(() => {});
|
|
}, [location, isLogin]);
|
|
};
|
|
```
|
|
|
|
### Step 2: 在 App.tsx 中使用
|
|
|
|
**文件**: `src/App.tsx`
|
|
|
|
```tsx
|
|
import { useRouteTracker } from '@/hooks/useRouteTracker';
|
|
|
|
const App: React.FC = () => {
|
|
useRouteTracker(); // 添加路由追踪
|
|
// ... 其余代码
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## 设计决策
|
|
|
|
| 决策点 | 选择 | 原因 |
|
|
|--------|------|------|
|
|
| 节流时间 | 3 秒 | 避免快速切换页面导致大量请求 |
|
|
| 是否追踪所有页面 | 是 | 后端会匹配活跃的 browse 任务,无匹配则忽略 |
|
|
| 未登录时是否追踪 | 否 | 后端需要用户身份才能创建进度记录 |
|
|
| 是否包含 search 参数 | 是 | 不同搜索词视为不同浏览 |
|
|
|
|
---
|
|
|
|
## 验证步骤
|
|
|
|
1. 登录用户访问任意页面 → 打开 Network 面板,确认 `/user/tasks/track/` 被调用
|
|
2. 快速切换页面 → 确认 3 秒内不会重复上报同一页面
|
|
3. 未登录用户访问页面 → 确认不调用 track API
|
|
4. 进入任务中心 → 确认每日浏览任务进度 +1
|