Checkpoint: v2.0完整版本:新增社区排行榜、每日打卡、24种成就徽章、实时摄像头姿势分析、在线录制(稳定压缩流/断线重连/自动剪辑)、移动端全面适配。47个测试通过。包含完整开发文档。

这个提交包含在:
Manus
2026-03-14 08:04:00 -04:00
父节点 36907d1110
当前提交 2c418b482e
修改 22 个文件,包含 4370 行新增41 行删除

340
docs/API.md 普通文件
查看文件

@@ -0,0 +1,340 @@
# Tennis Training Hub - API接口文档
本文档详细描述了Tennis Training Hub的所有tRPC API接口,包括输入参数、输出格式和认证要求。
## 认证说明
所有标记为 **需认证** 的接口需要用户已登录通过Session Cookie。未认证请求将返回 `UNAUTHORIZED` 错误。
## 接口列表
### 1. 认证模块 (`auth`)
#### `auth.me` - 获取当前用户信息
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | 不需要 |
| 输入 | 无 |
| 输出 | `User | null` |
返回当前登录用户的完整信息,未登录返回 `null`
#### `auth.loginWithUsername` - 用户名登录
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | 不需要 |
| 输入 | `{ username: string }` |
| 输出 | `{ user: User, isNew: boolean }` |
**输入验证:**
- `username`1-64个字符
若用户名不存在则自动创建新账户。
#### `auth.logout` - 退出登录
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | 不需要 |
| 输出 | `{ success: true }` |
---
### 2. 用户资料模块 (`profile`)
#### `profile.stats` - 获取用户统计数据
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输出 | `UserStats` |
#### `profile.update` - 更新用户资料
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | **需认证** |
| 输入 | `{ skillLevel?: "beginner" \| "intermediate" \| "advanced", trainingGoals?: string }` |
| 输出 | `{ success: true }` |
---
### 3. 训练计划模块 (`plan`)
#### `plan.generate` - AI生成训练计划
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | **需认证** |
| 输入 | `{ skillLevel: enum, durationDays: number, focusAreas?: string[] }` |
| 输出 | `{ planId: number, plan: TrainingPlanData }` |
**输入验证:**
- `skillLevel``"beginner"` / `"intermediate"` / `"advanced"`
- `durationDays`1-30
- `focusAreas`:可选,如 `["正手", "脚步"]`
#### `plan.list` - 获取用户所有训练计划
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输出 | `TrainingPlan[]` |
#### `plan.active` - 获取当前激活的训练计划
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输出 | `TrainingPlan | null` |
#### `plan.adjust` - AI自动调整训练计划
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | **需认证** |
| 输入 | `{ planId: number }` |
| 输出 | `{ success: true, adjustmentNotes: string }` |
---
### 4. 视频管理模块 (`video`)
#### `video.upload` - 上传训练视频
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | **需认证** |
| 输入 | `{ title: string, format: string, fileSize: number, fileBase64: string, exerciseType?: string }` |
| 输出 | `{ videoId: number, url: string }` |
#### `video.list` - 获取用户视频列表
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输出 | `TrainingVideo[]` |
#### `video.get` - 获取视频详情
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输入 | `{ videoId: number }` |
| 输出 | `TrainingVideo` |
#### `video.updateStatus` - 更新视频分析状态
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | **需认证** |
| 输入 | `{ videoId: number, status: "pending" \| "analyzing" \| "completed" \| "failed" }` |
| 输出 | `{ success: true }` |
---
### 5. 姿势分析模块 (`analysis`)
#### `analysis.save` - 保存姿势分析结果
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | **需认证** |
| 输入 | 见下表 |
| 输出 | `{ analysisId: number }` |
**输入参数:**
| 字段 | 类型 | 必填 | 说明 |
|------|------|------|------|
| videoId | number | 是 | 关联视频ID |
| overallScore | number | 否 | 总体评分(0-100) |
| poseMetrics | object | 否 | 关节角度等详细指标 |
| detectedIssues | array | 否 | 检测到的问题列表 |
| exerciseType | string | 否 | 动作类型 |
| framesAnalyzed | number | 否 | 分析帧数 |
| shotCount | number | 否 | 击球次数 |
| avgSwingSpeed | number | 否 | 平均挥拍速度 |
| maxSwingSpeed | number | 否 | 最大挥拍速度 |
| totalMovementDistance | number | 否 | 总移动距离 |
| strokeConsistency | number | 否 | 击球一致性(0-100) |
| footworkScore | number | 否 | 脚步评分(0-100) |
| fluidityScore | number | 否 | 流畅性评分(0-100) |
| keyMoments | array | 否 | 关键时刻标记 |
| movementTrajectory | array | 否 | 运动轨迹数据 |
保存分析结果后会自动触发NTRP评分重新计算。
#### `analysis.getCorrections` - AI生成矫正建议
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | **需认证** |
| 输入 | `{ poseMetrics: object, exerciseType: string, detectedIssues: array }` |
| 输出 | `{ corrections: string }` |
#### `analysis.list` - 获取用户所有分析记录
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输出 | `PoseAnalysis[]` |
#### `analysis.getByVideo` - 获取视频的分析结果
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输入 | `{ videoId: number }` |
| 输出 | `PoseAnalysis | null` |
---
### 6. 训练记录模块 (`record`)
#### `record.create` - 创建训练记录
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | **需认证** |
| 输入 | `{ exerciseName: string, planId?: number, durationMinutes?: number, notes?: string, poseScore?: number }` |
| 输出 | `{ recordId: number }` |
#### `record.complete` - 标记训练完成
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | **需认证** |
| 输入 | `{ recordId: number, poseScore?: number }` |
| 输出 | `{ success: true }` |
#### `record.list` - 获取训练记录列表
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输入 | `{ limit?: number }` (默认50) |
| 输出 | `TrainingRecord[]` |
---
### 7. 评分模块 (`rating`)
#### `rating.history` - 获取NTRP评分历史
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输出 | `RatingHistory[]` |
#### `rating.current` - 获取当前NTRP评分
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输出 | `{ rating: number }` |
---
### 8. 打卡模块 (`checkin`)
#### `checkin.today` - 获取今日打卡状态
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输出 | `DailyCheckin | null` |
#### `checkin.do` - 执行打卡
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | **需认证** |
| 输入 | `{ notes?: string, minutesTrained?: number }` (可选) |
| 输出 | `{ checkin: DailyCheckin, streak: number, newBadges: Badge[] }` |
打卡后会自动检查并授予新徽章。
#### `checkin.history` - 获取打卡历史
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输入 | `{ limit?: number }` (默认60) |
| 输出 | `DailyCheckin[]` |
---
### 9. 徽章模块 (`badge`)
#### `badge.list` - 获取用户徽章(含未获得)
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输出 | `BadgeWithStatus[]` |
返回所有24种徽章,标记已获得/未获得状态。
#### `badge.check` - 检查并授予新徽章
| 属性 | 值 |
|------|-----|
| 类型 | Mutation |
| 认证 | **需认证** |
| 输出 | `{ newBadges: Badge[] }` |
#### `badge.definitions` - 获取所有徽章定义
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | 不需要 |
| 输出 | `BadgeDefinition[]` |
---
### 10. 排行榜模块 (`leaderboard`)
#### `leaderboard.get` - 获取排行榜
| 属性 | 值 |
|------|-----|
| 类型 | Query |
| 认证 | **需认证** |
| 输入 | `{ sortBy?: enum, limit?: number }` |
| 输出 | `LeaderboardEntry[]` |
**sortBy选项**
- `"ntrpRating"` - 按NTRP评分排名默认
- `"totalMinutes"` - 按训练时长排名
- `"totalSessions"` - 按训练次数排名
- `"totalShots"` - 按击球数排名

67
docs/CHANGELOG.md 普通文件
查看文件

@@ -0,0 +1,67 @@
# Tennis Training Hub - 变更日志
## v2.0.0 (2026-03-14)
### 新增功能
- **社区排行榜**支持按NTRP评分、训练时长、训练次数、击球数四种维度排名
- **每日打卡系统**:日历视图展示打卡记录,自动计算连续打卡天数
- **成就徽章系统**24种成就徽章,涵盖里程碑、训练、连续打卡、视频、分析、评分6个类别
- **实时摄像头分析**:支持手机/电脑摄像头实时捕捉和MediaPipe姿势分析
- **摄像头位置确认提示**:引导用户调整摄像头到最佳位置
- **在线录制系统**稳定压缩流录制,自适应码率1-2.5Mbps
- **断线自动重连**:摄像头意外断开时自动检测并重新连接
- **自动剪辑功能**:基于运动检测自动标记关键时刻
- **移动端全面适配**:安全区域、触摸优化、横屏支持
- **手机摄像头优化**:前后摄像头切换、自适应分辨率
### 数据库变更
- 新增 `daily_checkins`
- 新增 `user_badges`
- `users` 表新增 `currentStreak``longestStreak``totalShots` 字段
### 测试
- 测试用例从15个增加到47个
- 新增打卡、徽章、排行榜相关测试
### 文档
- 新增完整README.md
- 新增API接口文档
- 新增数据库设计文档
- 新增功能列表清单
- 新增代码规范文档
- 新增变更日志
---
## v1.0.0 (2026-03-14)
### 初始版本
- 用户名简单登录系统
- AI训练计划生成初/中/高级)
- 视频上传功能webm/mp4
- MediaPipe浏览器端姿势识别
- 姿势矫正建议系统AI生成
- 训练计划自动调整
- NTRP自动评分系统五维度加权
- 训练进度追踪(可视化图表)
- 视频库管理
- 击球次数统计
- 挥拍速度估算
- 运动轨迹可视化
- 帧级别关键时刻标注
- 球员统计面板
### 数据库
- 初始9张表设计
- Drizzle ORM集成
- 3次数据库迁移
### 测试
- 15个核心功能测试

106
docs/CODING_STANDARDS.md 普通文件
查看文件

@@ -0,0 +1,106 @@
# Tennis Training Hub - 代码规范文档
## 项目约定
### 技术栈版本
| 技术 | 版本 | 用途 |
|------|------|------|
| React | 19 | UI框架 |
| TypeScript | 5.9 | 类型安全 |
| Tailwind CSS | 4 | 样式系统 |
| tRPC | 11 | 端到端类型安全API |
| Drizzle ORM | 0.44 | 数据库ORM |
| Vitest | 2.1 | 测试框架 |
| Express | 4 | HTTP服务器 |
### 文件命名规范
| 类型 | 规范 | 示例 |
|------|------|------|
| React页面 | PascalCase | `Dashboard.tsx`, `LiveCamera.tsx` |
| React组件 | PascalCase | `DashboardLayout.tsx` |
| 工具函数 | camelCase | `db.ts`, `storage.ts` |
| 测试文件 | `*.test.ts` | `features.test.ts` |
| 数据库迁移 | 自动生成 | `0001_public_prowler.sql` |
| 文档 | UPPER_CASE.md | `API.md`, `DATABASE.md` |
### 代码风格
**TypeScript/React**
- 使用函数组件和Hooks,不使用类组件
- 使用 `const` 优先,必要时使用 `let`,禁止 `var`
- 使用箭头函数作为回调
- 使用模板字符串而非字符串拼接
- 使用可选链 `?.` 和空值合并 `??`
- 导出组件使用 `export default function ComponentName()`
- 类型定义使用 `type` 而非 `interface`(除非需要继承)
**CSS/Tailwind**
- 优先使用Tailwind工具类
- 颜色使用OKLCH格式Tailwind 4要求
- 响应式设计使用移动优先策略(`sm:`, `md:`, `lg:`
- 语义化颜色变量定义在 `index.css``:root`
- 避免内联样式,除非动态计算值
**数据库:**
- 字段使用camelCase命名
- 主键统一使用 `id: int().autoincrement().primaryKey()`
- 时间字段使用 `timestamp` 类型
- JSON字段用于存储结构化但不需要索引的数据
- 所有表包含 `createdAt` 字段
### tRPC路由规范
```typescript
// 公开接口使用 publicProcedure
publicProcedure.query(...)
// 需要认证的接口使用 protectedProcedure
protectedProcedure.query(...)
protectedProcedure.mutation(...)
// 输入验证使用 Zod
.input(z.object({
field: z.string().min(1).max(64),
optional: z.number().optional(),
}))
```
### 测试规范
- 每个API路由至少有一个认证测试
- 输入验证测试覆盖边界值
- 使用 `createMockContext()` 创建测试上下文
- 数据库操作在测试中允许抛出连接错误,但输入验证不应失败
- 测试文件放在 `server/` 目录下
### Git提交规范
| 前缀 | 用途 | 示例 |
|------|------|------|
| `feat:` | 新功能 | `feat: 添加排行榜功能` |
| `fix:` | 修复 | `fix: 修复打卡连续天数计算` |
| `docs:` | 文档 | `docs: 更新API文档` |
| `test:` | 测试 | `test: 添加徽章系统测试` |
| `refactor:` | 重构 | `refactor: 优化评分计算逻辑` |
| `style:` | 样式 | `style: 调整移动端布局` |
### 安全规范
- 所有LLM调用必须在服务端执行
- 文件上传通过服务端中转到S3
- 用户输入使用Zod严格验证
- Session使用HttpOnly Cookie
- 敏感操作使用 `protectedProcedure`
### 性能规范
- MediaPipe推理在浏览器端执行,不占用服务器资源
- 视频文件存储在S3,不存入数据库
- 使用tRPC的React Query缓存减少重复请求
- 大列表查询使用 `limit` 参数分页
- 图片和媒体资源使用CDN URL

204
docs/DATABASE.md 普通文件
查看文件

@@ -0,0 +1,204 @@
# Tennis Training Hub - 数据库设计文档
## 概述
本项目使用MySQL/TiDB数据库,通过Drizzle ORM进行数据访问。数据库包含9张核心表,支持用户管理、训练计划、视频分析、评分系统、打卡和徽章等功能。
## ER关系图
```
users (1) ──── (N) username_accounts
├──── (N) training_plans
├──── (N) training_videos (1) ──── (1) pose_analyses
├──── (N) training_records
├──── (N) rating_history
├──── (N) daily_checkins
└──── (N) user_badges
```
## 表结构详解
### 1. `users` - 用户表
核心用户表,支持OAuth和用户名两种登录方式。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | INT | PK, AUTO_INCREMENT | 主键 |
| openId | VARCHAR(64) | UNIQUE, NOT NULL | OAuth标识符 |
| name | TEXT | - | 用户名 |
| email | VARCHAR(320) | - | 邮箱 |
| loginMethod | VARCHAR(64) | - | 登录方式 |
| role | ENUM('user','admin') | DEFAULT 'user' | 角色 |
| skillLevel | ENUM('beginner','intermediate','advanced') | DEFAULT 'beginner' | 技能水平 |
| trainingGoals | TEXT | - | 训练目标 |
| ntrpRating | FLOAT | DEFAULT 1.5 | NTRP评分 |
| totalSessions | INT | DEFAULT 0 | 总训练次数 |
| totalMinutes | INT | DEFAULT 0 | 总训练分钟 |
| currentStreak | INT | DEFAULT 0 | 当前连续打卡天数 |
| longestStreak | INT | DEFAULT 0 | 最长连续打卡天数 |
| totalShots | INT | DEFAULT 0 | 总击球数 |
| createdAt | TIMESTAMP | DEFAULT NOW | 创建时间 |
| updatedAt | TIMESTAMP | ON UPDATE NOW | 更新时间 |
| lastSignedIn | TIMESTAMP | DEFAULT NOW | 最后登录 |
### 2. `username_accounts` - 用户名账户表
简单用户名登录的映射表,将用户名映射到users表的用户。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | INT | PK, AUTO_INCREMENT | 主键 |
| username | VARCHAR(64) | UNIQUE, NOT NULL | 用户名 |
| userId | INT | NOT NULL | 关联用户ID |
| createdAt | TIMESTAMP | DEFAULT NOW | 创建时间 |
### 3. `training_plans` - 训练计划表
存储AI生成的训练计划,支持版本追踪和自动调整。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | INT | PK, AUTO_INCREMENT | 主键 |
| userId | INT | NOT NULL | 用户ID |
| title | VARCHAR(256) | NOT NULL | 计划标题 |
| skillLevel | ENUM | NOT NULL | 技能水平 |
| durationDays | INT | DEFAULT 7 | 计划天数 |
| exercises | JSON | NOT NULL | 训练内容JSON数组 |
| isActive | INT | DEFAULT 1 | 是否激活 |
| adjustmentNotes | TEXT | - | AI调整说明 |
| version | INT | DEFAULT 1 | 版本号 |
| createdAt | TIMESTAMP | DEFAULT NOW | 创建时间 |
| updatedAt | TIMESTAMP | ON UPDATE NOW | 更新时间 |
**exercises JSON结构**
```json
[
{
"day": 1,
"name": "正手影子挥拍",
"category": "挥拍练习",
"duration": 15,
"description": "...",
"tips": "...",
"sets": 3,
"reps": 20
}
]
```
### 4. `training_videos` - 训练视频表
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | INT | PK, AUTO_INCREMENT | 主键 |
| userId | INT | NOT NULL | 用户ID |
| title | VARCHAR(256) | NOT NULL | 视频标题 |
| fileKey | VARCHAR(512) | NOT NULL | S3文件键 |
| url | TEXT | NOT NULL | CDN访问URL |
| format | VARCHAR(16) | NOT NULL | 格式(webm/mp4) |
| fileSize | INT | - | 文件大小(字节) |
| duration | FLOAT | - | 时长(秒) |
| exerciseType | VARCHAR(64) | - | 动作类型 |
| analysisStatus | ENUM | DEFAULT 'pending' | 分析状态 |
| createdAt | TIMESTAMP | DEFAULT NOW | 创建时间 |
| updatedAt | TIMESTAMP | ON UPDATE NOW | 更新时间 |
### 5. `pose_analyses` - 姿势分析表
参考tennis_analysis项目设计,包含击球统计、挥拍速度、运动轨迹等高级分析字段。
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | INT | PK, AUTO_INCREMENT | 主键 |
| videoId | INT | NOT NULL | 视频ID |
| userId | INT | NOT NULL | 用户ID |
| overallScore | FLOAT | - | 总体评分(0-100) |
| poseMetrics | JSON | - | 关节角度详细指标 |
| detectedIssues | JSON | - | 检测到的问题 |
| corrections | JSON | - | 矫正建议 |
| exerciseType | VARCHAR(64) | - | 动作类型 |
| framesAnalyzed | INT | - | 分析帧数 |
| shotCount | INT | DEFAULT 0 | 击球次数 |
| avgSwingSpeed | FLOAT | - | 平均挥拍速度 |
| maxSwingSpeed | FLOAT | - | 最大挥拍速度 |
| totalMovementDistance | FLOAT | - | 总移动距离 |
| strokeConsistency | FLOAT | - | 击球一致性(0-100) |
| footworkScore | FLOAT | - | 脚步评分(0-100) |
| fluidityScore | FLOAT | - | 流畅性评分(0-100) |
| keyMoments | JSON | - | 关键时刻标记 |
| movementTrajectory | JSON | - | 运动轨迹数据 |
| createdAt | TIMESTAMP | DEFAULT NOW | 创建时间 |
### 6. `training_records` - 训练记录表
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | INT | PK, AUTO_INCREMENT | 主键 |
| userId | INT | NOT NULL | 用户ID |
| planId | INT | - | 关联计划ID |
| exerciseName | VARCHAR(128) | NOT NULL | 训练名称 |
| durationMinutes | INT | - | 时长(分钟) |
| completed | INT | DEFAULT 0 | 是否完成 |
| notes | TEXT | - | 备注 |
| poseScore | FLOAT | - | 姿势评分 |
| trainingDate | TIMESTAMP | DEFAULT NOW | 训练日期 |
| createdAt | TIMESTAMP | DEFAULT NOW | 创建时间 |
### 7. `rating_history` - 评分历史表
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | INT | PK, AUTO_INCREMENT | 主键 |
| userId | INT | NOT NULL | 用户ID |
| rating | FLOAT | NOT NULL | NTRP评分 |
| reason | VARCHAR(256) | - | 评分原因 |
| dimensionScores | JSON | - | 五维度分数明细 |
| analysisId | INT | - | 关联分析ID |
| createdAt | TIMESTAMP | DEFAULT NOW | 创建时间 |
**dimensionScores JSON结构**
```json
{
"poseAccuracy": 75.5,
"strokeConsistency": 68.2,
"footwork": 72.0,
"fluidity": 65.8,
"power": 58.3
}
```
### 8. `daily_checkins` - 每日打卡表
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | INT | PK, AUTO_INCREMENT | 主键 |
| userId | INT | NOT NULL | 用户ID |
| checkinDate | VARCHAR(10) | NOT NULL | 日期(YYYY-MM-DD) |
| streakCount | INT | DEFAULT 1 | 当时连续天数 |
| notes | TEXT | - | 打卡备注 |
| minutesTrained | INT | DEFAULT 0 | 当日训练分钟 |
| createdAt | TIMESTAMP | DEFAULT NOW | 创建时间 |
### 9. `user_badges` - 用户徽章表
| 字段 | 类型 | 约束 | 说明 |
|------|------|------|------|
| id | INT | PK, AUTO_INCREMENT | 主键 |
| userId | INT | NOT NULL | 用户ID |
| badgeKey | VARCHAR(64) | NOT NULL | 徽章标识键 |
| earnedAt | TIMESTAMP | DEFAULT NOW | 获得时间 |
## 迁移历史
| 版本 | 文件 | 内容 |
|------|------|------|
| 0001 | `0001_public_prowler.sql` | 初始表创建users扩展、username_accounts、training_plans、training_videos、pose_analyses、training_records、rating_history |
| 0002 | `0002_overrated_shriek.sql` | 添加totalShots字段 |
| 0003 | `0003_married_iron_lad.sql` | 添加daily_checkins和user_badges表、用户streak字段 |

79
docs/FEATURES.md 普通文件
查看文件

@@ -0,0 +1,79 @@
# Tennis Training Hub - 功能列表清单与开发记录
## 功能完成状态
### 核心功能
| 编号 | 功能 | 状态 | 版本 | 说明 |
|------|------|------|------|------|
| F-001 | 用户名简单登录 | 已完成 | v1.0 | 输入用户名即可登录,自动创建账户 |
| F-002 | 训练计划AI生成 | 已完成 | v1.0 | 支持初/中/高级,1-30天计划 |
| F-003 | 视频上传功能 | 已完成 | v1.0 | 支持webm/mp4格式,S3存储 |
| F-004 | MediaPipe姿势识别 | 已完成 | v1.0 | 浏览器端实时分析33个关键点 |
| F-005 | 姿势矫正建议 | 已完成 | v1.0 | AI根据分析数据生成矫正方案 |
| F-006 | 训练计划自动调整 | 已完成 | v1.0 | 基于分析结果智能调整计划 |
| F-007 | 训练进度追踪 | 已完成 | v1.0 | 可视化图表展示训练历史 |
| F-008 | 视频库管理 | 已完成 | v1.0 | 视频列表、详情、分析状态 |
### 参考tennis_analysis增强功能
| 编号 | 功能 | 状态 | 版本 | 说明 |
|------|------|------|------|------|
| F-009 | 击球次数统计 | 已完成 | v1.0 | 基于手腕关键点位移检测 |
| F-010 | 挥拍速度估算 | 已完成 | v1.0 | 手臂关键点帧间位移计算 |
| F-011 | 运动轨迹可视化 | 已完成 | v1.0 | 身体中心点移动轨迹绘制 |
| F-012 | 迷你球场叠加 | 已完成 | v1.0 | 视频分析界面球场示意图 |
| F-013 | 球员统计面板 | 已完成 | v1.0 | Dashboard综合数据展示 |
| F-014 | 帧级别关键时刻标注 | 已完成 | v1.0 | 自动标记击球、准备等关键帧 |
### NTRP评分系统
| 编号 | 功能 | 状态 | 版本 | 说明 |
|------|------|------|------|------|
| F-015 | NTRP自动评分 | 已完成 | v1.0 | 1.0-5.0评分,五维度加权 |
| F-016 | 历史评分自动更新 | 已完成 | v1.0 | 每次分析后自动重新计算 |
| F-017 | 多维度评分展示 | 已完成 | v1.0 | 雷达图展示五维度得分 |
| F-018 | 评分趋势图表 | 已完成 | v1.0 | 折线图展示评分变化趋势 |
### v2.0 新增功能
| 编号 | 功能 | 状态 | 版本 | 说明 |
|------|------|------|------|------|
| F-019 | 社区排行榜 - NTRP排名 | 已完成 | v2.0 | 按评分排序的用户排名 |
| F-020 | 社区排行榜 - 训练时长排名 | 已完成 | v2.0 | 按训练分钟排序 |
| F-021 | 社区排行榜 - 训练次数排名 | 已完成 | v2.0 | 按训练次数排序 |
| F-022 | 社区排行榜 - 击球数排名 | 已完成 | v2.0 | 按总击球数排序 |
| F-023 | 每日打卡系统 | 已完成 | v2.0 | 日历视图、连续天数追踪 |
| F-024 | 成就徽章系统 | 已完成 | v2.0 | 24种徽章,6个类别 |
| F-025 | 实时摄像头分析 | 已完成 | v2.0 | 手机/电脑摄像头实时捕捉 |
| F-026 | 摄像头位置确认提示 | 已完成 | v2.0 | 引导用户调整摄像头位置 |
| F-027 | 在线录制 | 已完成 | v2.0 | 稳定压缩流录制 |
| F-028 | 断线自动重连 | 已完成 | v2.0 | 摄像头断开自动恢复 |
| F-029 | 自动剪辑 | 已完成 | v2.0 | 基于运动检测标记关键片段 |
| F-030 | 移动端全面适配 | 已完成 | v2.0 | 响应式设计、安全区域、触摸优化 |
| F-031 | 手机摄像头优化 | 已完成 | v2.0 | 前后摄像头切换、自适应分辨率 |
## 开发时间线
| 日期 | 版本 | 里程碑 |
|------|------|--------|
| 2026-03-14 | v1.0 | 项目初始化、数据库设计、核心功能开发 |
| 2026-03-14 | v1.0 | 完成所有核心页面、MediaPipe集成、NTRP评分 |
| 2026-03-14 | v2.0 | 添加排行榜、打卡、徽章、实时摄像头、在线录制 |
| 2026-03-14 | v2.0 | 移动端适配、测试套件、文档编写 |
## 测试覆盖
| 模块 | 测试数 | 覆盖内容 |
|------|--------|---------|
| auth | 5 | me查询、logout、用户名登录验证 |
| profile | 4 | 认证检查、技能等级验证 |
| plan | 5 | 生成验证、列表、激活计划、调整 |
| video | 4 | 上传验证、列表、详情 |
| analysis | 4 | 保存验证、矫正建议、列表、视频查询 |
| record | 4 | 创建验证、完成、列表 |
| rating | 2 | 历史、当前评分 |
| checkin | 5 | 今日状态、打卡、历史 |
| badge | 5 | 列表、检查、定义、数据完整性 |
| leaderboard | 3 | 认证、排序参数、无效参数 |
| **总计** | **47** | **全部通过** |