Files
plates-server/docs/schedule-exercise-api-examples.md
richarjiang bea71af5d3 优化训练计划项目管理功能
- 更新训练项目文档,增加与动作库的智能关联和简化接口操作的说明
- 移除批量操作接口,专注于单项操作,提升用户体验
- 增强数据模型,确保训练项目与动作库的关联性,提升数据一致性和查询性能
- 更新服务逻辑,支持动作存在性验证,确保数据的准确性和完整性
2025-08-15 11:37:11 +08:00

8.6 KiB
Raw Permalink Blame History

训练计划项目管理 API 使用示例(优化版)

这个版本展示了优化后的 API 设计,重点是与动作库的智能关联和简化的接口操作。

创建一个完整的训练计划项目

1. 创建基础训练计划

POST /training-plans
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "全身力量训练",
  "startDate": "2024-01-15T00:00:00.000Z",
  "mode": "daysOfWeek",
  "daysOfWeek": [1, 3, 5],
  "sessionsPerWeek": 3,
  "goal": "core_strength"
}

响应:

{
  "id": "plan_1705123456789_abc123",
  "name": "全身力量训练",
  "isActive": true,
  "userId": "user_123",
  "startDate": "2024-01-15T00:00:00.000Z",
  "mode": "daysOfWeek",
  "daysOfWeek": [1, 3, 5],
  "sessionsPerWeek": 3,
  "goal": "core_strength",
  "createdAt": "2024-01-10T10:30:00.000Z"
}

2. 逐个添加训练项目(关联动作库)

添加热身项目

POST /training-plans/plan_1705123456789_abc123/exercises
Authorization: Bearer {token}
Content-Type: application/json

{
  "exerciseKey": "dynamic_warmup",   // 关联动作库中的动态热身
  "name": "动态热身",
  "durationSec": 300,
  "itemType": "exercise",
  "note": "轻松活动关节,准备训练"
}

添加安全提醒

POST /training-plans/plan_1705123456789_abc123/exercises
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "安全提醒",
  "note": "如感到不适请立即停止,保持正确呼吸",
  "itemType": "note"
}

添加深蹲训练

POST /training-plans/plan_1705123456789_abc123/exercises
Authorization: Bearer {token}
Content-Type: application/json

{
  "exerciseKey": "squat",           // 关联动作库中的深蹲
  "name": "深蹲训练",
  "sets": 3,
  "reps": 15,
  "restSec": 60,
  "itemType": "exercise",
  "note": "下蹲时膝盖不超过脚尖"
}

添加休息时间

POST /training-plans/plan_1705123456789_abc123/exercises
Authorization: Bearer {token}
Content-Type: application/json

{
  "name": "组间休息",
  "durationSec": 90,
  "itemType": "rest"
}

添加俯卧撑训练

POST /training-plans/plan_1705123456789_abc123/exercises
Authorization: Bearer {token}
Content-Type: application/json

{
  "exerciseKey": "pushup",          // 关联动作库中的俯卧撑
  "name": "俯卧撑训练",
  "sets": 3,
  "reps": 12,
  "restSec": 60,
  "itemType": "exercise",
  "note": "保持身体一条直线"
}

每个添加请求的响应示例:
```json
{
  "id": "ex_1705123456790_def456",
  "trainingPlanId": "plan_1705123456789_abc123",
  "exerciseKey": "squat",
  "name": "深蹲训练",
  "sets": 3,
  "reps": 15,
  "restSec": 60,
  "note": "下蹲时膝盖不超过脚尖",
  "itemType": "exercise",
  "completed": false,
  "sortOrder": 3,
  "createdAt": "2024-01-10T10:35:00.000Z",
  "updatedAt": "2024-01-10T10:35:00.000Z"
}

3. 获取训练项目列表(包含动作库信息)

GET /training-plans/plan_1705123456789_abc123/exercises
Authorization: Bearer {token}

响应按sortOrder排序的完整项目列表包含关联的动作信息

[
  {
    "id": "ex_1705123456790_def456",
    "trainingPlanId": "plan_1705123456789_abc123", 
    "exerciseKey": "dynamic_warmup",
    "name": "动态热身",
    "durationSec": 300,
    "note": "轻松活动关节,准备训练",
    "itemType": "exercise",
    "completed": false,
    "sortOrder": 1,
    "exercise": {
      "key": "dynamic_warmup",
      "name": "动态热身",
      "description": "通过各种动态动作激活身体,为训练做准备",
      "categoryKey": "warmup",
      "categoryName": "热身"
    }
  },
  {
    "id": "ex_1705123456791_ghi789",
    "trainingPlanId": "plan_1705123456789_abc123",
    "name": "安全提醒",
    "note": "如感到不适请立即停止,保持正确呼吸",
    "itemType": "note",
    "completed": false,
    "sortOrder": 2
  },
  {
    "id": "ex_1705123456792_jkl012",
    "trainingPlanId": "plan_1705123456789_abc123",
    "exerciseKey": "squat",
    "name": "深蹲训练",
    "sets": 3,
    "reps": 15,
    "restSec": 60,
    "note": "下蹲时膝盖不超过脚尖",
    "itemType": "exercise",
    "completed": false,
    "sortOrder": 3,
    "exercise": {
      "key": "squat",
      "name": "深蹲",
      "description": "下肢力量训练的基础动作,主要锻炼大腿和臀部肌肉",
      "categoryKey": "strength",
      "categoryName": "力量训练"
    }
  },
  {
    "id": "ex_1705123456793_mno345",
    "trainingPlanId": "plan_1705123456789_abc123",
    "name": "组间休息",
    "durationSec": 90,
    "itemType": "rest",
    "completed": false,
    "sortOrder": 4
  }
]

4. 用户完成训练项目

PUT /training-plans/plan_1705123456789_abc123/exercises/ex_1705123456792_jkl012/complete
Authorization: Bearer {token}
Content-Type: application/json

{
  "completed": true
}

响应:

{
  "id": "ex_1705123456792_jkl012",
  "trainingPlanId": "plan_1705123456789_abc123",
  "key": "squat_exercise",
  "name": "深蹲训练",
  "category": "下肢力量",
  "sets": 3,
  "reps": 15,
  "restSec": 60,
  "itemType": "exercise",
  "completed": true,
  "sortOrder": 3,
  "updatedAt": "2024-01-10T11:15:00.000Z"
}

5. 调整训练项目顺序

PUT /training-plans/plan_1705123456789_abc123/exercises/order
Authorization: Bearer {token}
Content-Type: application/json

{
  "exerciseIds": [
    "ex_1705123456790_def456",  // 热身
    "ex_1705123456792_jkl012",  // 深蹲 (提前)
    "ex_1705123456791_ghi789",  // 安全提醒 (延后)
    "ex_1705123456793_mno345",  // 休息
    "ex_1705123456794_pqr678"   // 其他项目...
  ]
}

响应:

{
  "success": true
}

6. 批量更新训练强度

PUT /training-plans/plan_1705123456789_abc123/exercises/batch
Authorization: Bearer {token}
Content-Type: application/json

{
  "exercises": [
    {
      "id": "ex_1705123456792_jkl012",
      "sets": 4,          // 增加组数
      "reps": 18          // 增加次数
    },
    {
      "id": "ex_1705123456794_pqr678", 
      "sets": 4,
      "reps": 15
    },
    {
      "id": "ex_1705123456795_stu901",
      "durationSec": 75   // 增加平板支撑时长
    }
  ]
}

7. 查看训练完成统计

GET /training-plans/plan_1705123456789_abc123/exercises/stats/completion
Authorization: Bearer {token}

响应:

{
  "total": 5,        // 总共5个运动项目(不包括休息和提醒)
  "completed": 3,    // 已完成3个
  "percentage": 60   // 完成率60%
}

8. 删除不需要的项目

DELETE /training-plans/plan_1705123456789_abc123/exercises
Authorization: Bearer {token}
Content-Type: application/json

[
  "ex_1705123456793_mno345",  // 删除某个休息项目
  "ex_1705123456796_vwx234"   // 删除某个提醒项目
]

响应:

{
  "success": true,
  "deletedCount": 2
}

错误处理示例

重复的key错误

POST /training-plans/plan_1705123456789_abc123/exercises
{
  "key": "squat_exercise",  // 已存在的key
  "name": "新的深蹲"
}

响应:

{
  "statusCode": 400,
  "message": "项目key \"squat_exercise\" 已存在",
  "error": "Bad Request"
}

训练计划不存在

GET /training-plans/nonexistent_plan/exercises

响应:

{
  "statusCode": 404,
  "message": "训练计划不存在或不属于当前用户",
  "error": "Not Found"
}

前端集成建议

1. 训练项目组件状态管理

interface TrainingSessionState {
  exercises: ScheduleExercise[];
  currentExercise: number;
  completedCount: number;
  totalCount: number;
}

// 加载训练项目
const loadExercises = async (planId: string) => {
  const exercises = await api.get(`/training-plans/${planId}/exercises`);
  return exercises.filter(ex => ex.itemType === 'exercise');
};

// 标记完成
const markComplete = async (planId: string, exerciseId: string) => {
  await api.put(`/training-plans/${planId}/exercises/${exerciseId}/complete`, {
    completed: true
  });
};

2. 拖拽重新排序

const handleDragEnd = async (result: DropResult) => {
  if (!result.destination) return;
  
  const newOrder = Array.from(exercises);
  const [reorderedItem] = newOrder.splice(result.source.index, 1);
  newOrder.splice(result.destination.index, 0, reorderedItem);
  
  const exerciseIds = newOrder.map(ex => ex.id);
  await api.put(`/training-plans/${planId}/exercises/order`, {
    exerciseIds
  });
  
  setExercises(newOrder);
};

这个API设计提供了完整的训练项目管理功能支持用户创建个性化的训练流程实时跟踪完成进度并且具有良好的扩展性。