166 lines
5.3 KiB
Markdown
166 lines
5.3 KiB
Markdown
# 完善个人资料时调用 tasks.track
|
||
|
||
## 摘要
|
||
|
||
个人资料更新功能已完整,但缺少任务追踪调用。当用户修改资料(昵称、性别、简介、位置等)时,未触发 `action_type='profile'` 的任务进度上报,用户无法获得任务奖励(50积分 + 5金币 + 100 XP)。
|
||
|
||
需要在后端 `UserUpdateAPIView` 中添加追踪调用。
|
||
|
||
## 当前状态分析
|
||
|
||
### 现有基础设施(均已就绪)
|
||
|
||
| 组件 | 状态 | 文件 |
|
||
|:---|:---|:---|
|
||
| `tasks.track` API | ✅ 已实现 | `user/views/tasks.py:144-238` TaskTrackAPIView |
|
||
| "完善个人资料" 任务定义 | ✅ 已存在 | `user/models.py:169` action_type='profile' |
|
||
| `log_event` 工具函数 | ✅ 已实现 | `logs/utils.py:1-39` |
|
||
| Profile 前端页面 | ✅ 已实现 | `src/pages/Profile/UserInfoCard.tsx` |
|
||
| Profile 后端 API | ✅ 已实现但无追踪 | `user/views/user.py:496-527` UserUpdateAPIView.put() |
|
||
|
||
### 缺失的连接
|
||
|
||
`UserUpdateAPIView.put()` 在保存成功后仅返回响应,不调用:
|
||
- `log_event(event_type='profile_update', ...)`
|
||
- TaskTrackAPIView 上报 `action_type='profile'`
|
||
|
||
## 修改方案
|
||
|
||
### 文件:`chunyu_project\user\views\user.py`
|
||
|
||
**改动位置**:`UserUpdateAPIView.put()` 方法,在保存成功之后、返回响应之前
|
||
|
||
**具体修改**:
|
||
|
||
1. **新增导入**(文件顶部):
|
||
```python
|
||
from logs.utils import log_event
|
||
```
|
||
|
||
2. **在 `put()` 方法中添加追踪逻辑**(第 527 行 `return Response(...)` 之前):
|
||
|
||
```python
|
||
# 记录资料更新日志事件
|
||
request = self.request # 获取当前 request 对象
|
||
log_event(
|
||
event_type='profile_update',
|
||
user=request.user,
|
||
description=f'更新了{len(serializer.validated_data)}项个人资料',
|
||
metadata={'updated_fields': list(serializer.validated_data.keys())},
|
||
request=request
|
||
)
|
||
|
||
# 触发任务进度上报 - 完善个人资料
|
||
try:
|
||
from user.views.tasks import TaskTrackAPIView
|
||
# 内部调用 TaskTrackAPIView 的逻辑
|
||
from django.test import RequestFactory
|
||
# 直接导入并复用 TaskTrackAPIView 的追踪逻辑
|
||
from user.models import TaskDefinition, UserTaskProgress
|
||
from django.utils import timezone
|
||
|
||
task_def = TaskDefinition.objects.filter(
|
||
action_type='profile',
|
||
is_active=True
|
||
).first()
|
||
|
||
if task_def:
|
||
progress, _ = UserTaskProgress.objects.get_or_create(
|
||
user=request.user,
|
||
task=task_def,
|
||
defaults={'current_count': 0, 'completed': False}
|
||
)
|
||
if not progress.completed:
|
||
progress.current_count += 1
|
||
if progress.current_count >= task_def.target_count:
|
||
progress.completed = True
|
||
progress.completed_at = timezone.now()
|
||
progress.claimed = True
|
||
progress.save()
|
||
except Exception:
|
||
pass # 追踪失败不应影响主流程
|
||
```
|
||
|
||
**问题**:上述实现过于复杂,且需要导入大量模型。更简洁的方案是:
|
||
|
||
**更优方案**:直接在 `put()` 中构造内部请求调用 `TaskTrackAPIView`
|
||
|
||
```python
|
||
# 触发任务进度上报
|
||
try:
|
||
track_view = TrackAPIView()
|
||
track_request = RequestFactory().post('/tasks/track/', {
|
||
'action_type': 'profile',
|
||
'count': 1
|
||
})
|
||
track_request.user = request.user
|
||
track_view.post(track_request)
|
||
except Exception:
|
||
pass
|
||
```
|
||
|
||
**最终推荐**:复用 `TaskTrackAPIView` 的类方法
|
||
|
||
在 `user/views/tasks.py` 中提取追踪逻辑为独立函数:
|
||
|
||
```python
|
||
# 在 TaskTrackAPIView 同级添加
|
||
def track_user_action(user, action_type, count=1, request=None):
|
||
"""追踪用户行为并更新任务进度"""
|
||
from user.models import TaskDefinition, UserTaskProgress
|
||
from django.utils import timezone
|
||
|
||
task_def = TaskDefinition.objects.filter(
|
||
action_type=action_type,
|
||
is_active=True
|
||
).first()
|
||
|
||
if not task_def:
|
||
return
|
||
|
||
progress, _ = UserTaskProgress.objects.get_or_create(
|
||
user=user,
|
||
task=task_def,
|
||
defaults={'current_count': 0, 'completed': False}
|
||
)
|
||
|
||
if progress.completed:
|
||
return
|
||
|
||
progress.current_count += count
|
||
if progress.current_count >= task_def.target_count:
|
||
progress.completed = True
|
||
progress.completed_at = timezone.now()
|
||
progress.claimed = True
|
||
progress.save()
|
||
```
|
||
|
||
然后在 `UserUpdateAPIView.put()` 中调用:
|
||
|
||
```python
|
||
from .tasks import track_user_action
|
||
|
||
# 在保存成功后
|
||
track_user_action(request.user, 'profile', count=1, request=request)
|
||
```
|
||
|
||
### 文件:`chunyu_project\user\views\tasks.py`
|
||
|
||
**改动**:将 `TaskTrackAPIView.post()` 中的核心追踪逻辑提取为独立函数 `track_user_action`
|
||
|
||
修改 `TaskTrackAPIView.post()` 使其调用 `track_user_action`,保持 API 行为不变。
|
||
|
||
## 修改汇总
|
||
|
||
| 文件 | 改动类型 | 具体内容 |
|
||
|:---|:---|:---|
|
||
| `user/views/tasks.py` | 修改 | 提取 `track_user_action()` 函数;`TaskTrackAPIView.post()` 改为调用此函数 |
|
||
| `user/views/user.py` | 修改 | 添加 `log_event` 导入;`UserUpdateAPIView.put()` 中添加 `log_event` 和 `track_user_action` 调用 |
|
||
|
||
## 验证步骤
|
||
|
||
1. 登录后修改个人资料(如修改昵称)
|
||
2. 检查 `SystemEventLog` 表是否新增了 `event_type='profile_update'` 的记录
|
||
3. 检查 `UserTaskProgress` 表中 `action_type='profile'` 的任务进度是否更新
|
||
4. 确认用户获得了任务奖励(积分、金币、XP)
|