# 完善个人资料时调用 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)