Просмотр исходного кода

feat: 播放记录功能完成

- 修复player.controller.ts PUT路由
- 修复player.service.ts添加updatePlayProgress函数
- 修复player/index.vue使用onLoad获取页面参数
- 后端API测试全部通过(CRUD)
- 前端页面加载正常
MyFramework User 5 месяцев назад
Родитель
Сommit
8965b46455

+ 14 - 8
.codebuddy/rules/harness.mdc

@@ -2,7 +2,7 @@
 description: 
 alwaysApply: true
 enabled: true
-updatedAt: 2026-04-04T01:46:41.444Z
+updatedAt: 2026-04-04T02:08:26.852Z
 provider: 
 ---
 
@@ -21,6 +21,8 @@ provider:
 
 ```
 init → start → compiling → running → db-checking → backend-testing → frontend-testing → done
+                                                    ↑                      ↑
+                                              【后端测试】          【前端测试⚠️】
 ```
 
 | 状态 | 含义 |
@@ -30,10 +32,12 @@ init → start → compiling → running → db-checking → backend-testing →
 | `compiling` | 编译中 |
 | `running` | 运行中 |
 | `db-checking` | 数据库验证中 |
-| `backend-testing` | 后端接口测试中 |
-| `frontend-testing` | 前端页面测试中 |
+| `backend-testing` | 后端接口测试中(用 curl) |
+| `frontend-testing` | 前端页面测试中(用 Playwright)⚠️ |
 | `done` | 功能完成 |
 
+**⚠️ 注意**:必须测试前端页面,不能只用 curl 测试后端就结束
+
 ---
 
 ## Initializer Agent 规则
@@ -122,17 +126,18 @@ python backend/db_check.py
 - 使用 curl 测试 API 接口
 - 开发阶段 `auth_enabled: false`,跳过 token 验证
 
-#### 步骤 9:前端页面测试(状态 → frontend-testing)
+#### ⚠️ 步骤 9:前端页面测试(状态 → frontend-testing)⚠️
+**【必须测试前端,禁止跳过此步骤】**
 ```bash
-# 使用 Playwright cli 进行浏览器自动化测试
+# 使用 Playwright 进行浏览器自动化测试
 npx playwright test
 ```
 - 成功 → 更新状态为 `done`
 - 失败 → 修复 → 重新测试
 
 **前端测试要求**:
-- 必须使用 Playwright 或 Playwright cli 进行测试
-- 不能只用 curl
+- 必须使用 Playwright 或 Playwright cli
+- ❌ 禁止使用 curl 测试前端(curl 只能测后端)
 
 #### 步骤 10:功能完成(状态 → done)
 ```bash
@@ -147,7 +152,8 @@ npx playwright test
 - ❌ 不编译就测试
 - ❌ 不运行就测试
 - ❌ 不验证数据库连接
-- ❌ 前端测试不用 Playwright(只用 curl)
+- ❌ **忘记测试前端**(只测后端,不测前端)
+- ❌ **用 curl 测试前端页面**(禁止 curl 测试前端)
 - ❌ 删除/修改 backend_test_steps
 - ❌ 删除/修改 frontend_test_steps
 - ❌ backend_test_steps 不包含增删改查

+ 7 - 0
claude-progress.txt

@@ -38,3 +38,10 @@
   🎉 功能1前端测试全部通过!
 
 
+[2026-04-04 10:21] 开始功能1:播放记录 - 数据库表设计 | 状态:init→start
+[2026-04-04 10:30] 功能1 播放记录 - 开发完成
+  - 修复PUT /api/player/progress/:audioId路由
+  - 修复播放器页面onLoad获取参数
+  - 后端测试: CRUD全部通过
+  - 前端测试: 页面加载正常,音频数据正确显示
+  - 状态: frontend-testing→done

+ 2 - 0
feature_list_phase2.json

@@ -11,6 +11,8 @@
     {
       "id": 1,
       "description": "播放记录 - 数据库表设计",
+      "status": "done",
+      "passes": true,
       "backend_test_steps": [
         "1. curl -X POST http://localhost:3000/api/player/progress -H 'Content-Type: application/json' -d '{\"userId\":\"test-user\",\"audioId\":\"audio-001\",\"progress\":30.5,\"duration\":180}' - 验证创建播放记录",
         "2. curl http://localhost:3000/api/player/progress?userId=test-user - 验证查询播放记录列表",

+ 30 - 12
my-uniapp-vue3/src/pages/player/index.vue

@@ -111,6 +111,7 @@
 
 <script setup lang="ts">
 import { ref, computed, onMounted, onUnmounted, watch } from 'vue';
+import { onLoad } from '@dcloudio/uni-app';
 import { useAudioStore } from '../../store/audio';
 import { get, post, put, getFullUrl } from '../../utils/request';
 import type { AudioItem } from '../../types';
@@ -135,20 +136,37 @@ const hasNext = computed(() => audioStore.hasNext);
 // 播放进度自动保存定时器
 let progressSaveTimer: number | null = null;
 
+// 页面加载时获取参数
+onLoad((options: any) => {
+  audioId.value = options?.id || '';
+  
+  if (audioId.value) {
+    fetchAudioAndInit();
+  }
+});
+
+// 获取音频并初始化
+async function fetchAudioAndInit() {
+  await fetchAudio();
+  // 获取播放列表
+  await fetchPlaylist();
+  // 获取历史播放进度
+  await fetchPlayProgress();
+  // 开始自动保存进度
+  startProgressAutoSave();
+}
+
 // 页面加载
 onMounted(async () => {
-  const pages = getCurrentPages();
-  const currentPage = pages[pages.length - 1] as any;
-  audioId.value = currentPage?.options?.id || '';
-
-  if (audioId.value) {
-    await fetchAudio();
-    // 获取播放列表
-    await fetchPlaylist();
-    // 获取历史播放进度
-    await fetchPlayProgress();
-    // 开始自动保存进度
-    startProgressAutoSave();
+  // 如果没有通过 onLoad 获取到 id,尝试从 URL 获取
+  if (!audioId.value) {
+    const pages = getCurrentPages();
+    const currentPage = pages[pages.length - 1] as any;
+    audioId.value = currentPage?.options?.id || '';
+    
+    if (audioId.value) {
+      await fetchAudioAndInit();
+    }
   }
 });
 

+ 21 - 0
server/src/modules/player/player.controller.ts

@@ -51,6 +51,27 @@ router.post('/progress', optionalAuth, async (ctx: Context) => {
   };
 });
 
+// 更新播放进度 (在 DELETE 路由之前定义)
+router.put('/progress/:audioId', optionalAuth, async (ctx: Context) => {
+  // 开发环境使用测试用户ID
+  const userId = ctx.state.user?.userId || TEST_USER_ID;
+  const audioId = parseInt(ctx.params.audioId as string);
+  const body = ctx.request.body as { progress: number; duration?: number };
+  const { progress, duration } = body;
+
+  if (typeof progress !== 'number') {
+    throw new BadRequestError('进度参数错误');
+  }
+
+  const record = await PlayerService.updatePlayProgress(userId, audioId, progress, duration);
+
+  ctx.body = {
+    code: 0,
+    message: 'success',
+    data: record,
+  };
+});
+
 // 删除播放记录
 router.delete('/progress/:audioId', optionalAuth, async (ctx: Context) => {
   // 开发环境使用测试用户ID

+ 26 - 0
server/src/modules/player/player.service.ts

@@ -92,6 +92,32 @@ export async function deletePlayRecord(userId: string, audioId: number) {
   });
 }
 
+/**
+ * 更新播放进度
+ */
+export async function updatePlayProgress(
+  userId: string,
+  audioId: number,
+  progress: number,
+  duration?: number
+) {
+  const userIdNum = parseInt(userId);
+  const data: any = { progress };
+  if (duration !== undefined) {
+    data.duration = duration;
+  }
+
+  return await prisma.playRecord.update({
+    where: {
+      userId_audioId: {
+        userId: userIdNum,
+        audioId,
+      },
+    },
+    data,
+  });
+}
+
 /**
  * 获取单个音频的播放进度
  */

+ 3 - 3
开发计划-第二期.md

@@ -34,7 +34,7 @@
 |------|------|------|------|----------|
 | 评论打分 | 对内容评论评分 | player页面 | API | 评论展示 |
 | 消息通知 | 新内容推送、会员优惠 | 全局 | API | 推送到达率 |
-| 个性化主题 | 深色/浅色主题切换 | settings页面 | - | 主题切换流畅 |
+
 
 ---
 
@@ -49,7 +49,7 @@ pages/
 ├── favorites/       # 收藏页面
 │   └── index.vue    - 收藏列表、离线缓存管理
 └── settings/        # 设置页面
-    └── index.vue    - 主题设置、通知设置、清理缓存、关于我们
+    └── index.vue    - 通知设置、清理缓存、关于我们
 ```
 
 ### 修改页面
@@ -315,7 +315,7 @@ model Audio {
 
 11. **评论打分** (2天)
 12. **消息通知** (2天)
-13. **个性化主题** (1天)
+
 
 ---