385 行
9.2 KiB
Markdown
385 行
9.2 KiB
Markdown
# 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[] }` |
|
||
| 输出 | `{ taskId: string, task: BackgroundTask }` |
|
||
|
||
**输入验证:**
|
||
- `skillLevel`:`"beginner"` / `"intermediate"` / `"advanced"`
|
||
- `durationDays`:1-30
|
||
- `focusAreas`:可选,如 `["正手", "脚步"]`
|
||
|
||
#### `plan.list` - 获取用户所有训练计划
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 类型 | Query |
|
||
| 认证 | **需认证** |
|
||
| 输出 | `TrainingPlan[]` |
|
||
|
||
#### `plan.active` - 获取当前激活的训练计划
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 类型 | Query |
|
||
| 认证 | **需认证** |
|
||
| 输出 | `TrainingPlan | null` |
|
||
|
||
#### `plan.adjust` - AI自动调整训练计划
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 类型 | Mutation |
|
||
| 认证 | **需认证** |
|
||
| 输入 | `{ planId: number }` |
|
||
| 输出 | `{ taskId: string, task: BackgroundTask }` |
|
||
|
||
---
|
||
|
||
### 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, imageUrls?: string[], imageDataUrls?: string[] }` |
|
||
| 输出 | `{ taskId: string, task: BackgroundTask }` |
|
||
|
||
该接口始终走后台任务。若提供 `imageUrls` 或 `imageDataUrls`,服务端会优先走多模态纠正链路,并把相对地址规范化为可公网访问的绝对 URL。
|
||
|
||
#### `analysis.list` - 获取用户所有分析记录
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 类型 | Query |
|
||
| 认证 | **需认证** |
|
||
| 输出 | `PoseAnalysis[]` |
|
||
|
||
#### `analysis.getByVideo` - 获取视频的分析结果
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 类型 | Query |
|
||
| 认证 | **需认证** |
|
||
| 输入 | `{ videoId: number }` |
|
||
| 输出 | `PoseAnalysis | null` |
|
||
|
||
---
|
||
|
||
### 6. 训练记录模块 (`record`)
|
||
|
||
### 5.1 后台任务模块 (`task`)
|
||
|
||
#### `task.list` - 获取当前用户后台任务
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 类型 | Query |
|
||
| 认证 | **需认证** |
|
||
| 输入 | `{ limit?: number }` |
|
||
| 输出 | `BackgroundTask[]` |
|
||
|
||
#### `task.get` - 获取单个后台任务
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 类型 | Query |
|
||
| 认证 | **需认证** |
|
||
| 输入 | `{ taskId: string }` |
|
||
| 输出 | `BackgroundTask | null` |
|
||
|
||
#### `task.retry` - 重试失败任务
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 类型 | Mutation |
|
||
| 认证 | **需认证** |
|
||
| 输入 | `{ taskId: string }` |
|
||
| 输出 | `{ task: BackgroundTask }` |
|
||
|
||
#### `task.createMediaFinalize` - 提交录制归档后台任务
|
||
|
||
| 属性 | 值 |
|
||
|------|-----|
|
||
| 类型 | Mutation |
|
||
| 认证 | **需认证** |
|
||
| 输入 | `{ sessionId: string, title: string, exerciseType?: string }` |
|
||
| 输出 | `{ taskId: string, task: BackgroundTask }` |
|
||
|
||
该接口会校验媒体会话所属用户,并由后台 worker 轮询 Go 媒体服务状态,归档完成后自动登记到视频库。
|
||
|
||
### 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"` - 按击球数排名
|