Skip to content

前端联调 · 训练中心(training.ts) ​

归属:前端联调 API 手册 → src/api/training.ts 端点:5 个 · REST 风格(非 action 协议) 错误码段:40406xxx(全表见 错误码注册表) 错误契约:HTTP 400 / 401 / 404 + {code, msg, data};⚠️ 但业务失败(如计划冲突)走 HTTP 200 + code "0" + {ok:false} —— 见下 取值语义:取值速查 · training —— kind 三类计划的种子差异、data.ok=false 时哪些键不存在、tasks[].status 实际只产两值、completeSource 两条写入路径 深入说明:training API Docs

本页 curl 变量 ​

bash
BASE_URL=https://api.qingmulife.cn   # 本地:http://localhost:3000
ACCESS=<access_token>
ENV=Prd                              # Dev | Prd —— 全程必须一致

⚠️ 身份一律以 token 为准(2026-09-18 越权修复):body.userId / ?user_id= 一律被后端忽略。 传它们是死参数 —— 前端本地 uid 与 token 用户不一致时(换号残留),返回的仍是 token 用户的数据,且前端无法感知。

端点一览 ​

#方法路径鉴权场景
1GET/api/v1/training/plans公开计划模板列表(向导推荐用)
2POST/api/v1/training/enrollaccess报名计划(生成任务 + 提醒)
3GET/api/v1/training/tasksaccess我的打卡任务(日历/计划页)
4POST/api/v1/training/task/checkinaccess任务打卡
5GET/api/v1/training/remindersaccess我的提醒列表

listTrainingPlans ​

一句话:计划模板列表 —— 向导推荐 / 计划选择页展示用(免登录)。

curl ​

bash
curl -s "$BASE_URL/api/v1/training/plans" \
  -H 'X-Env: Prd'

请求 ​

字段类型必填说明
———无任何入参、免登录

响应 data —— 顶层是数组 ​

字段类型可空说明
[].idnumber否int —— 原样回传给 enroll 的 planId
[].planKeystring否计划键(英文机器名)
[].name / [].descriptionstring否展示文案
[].kindstring否种子值 running | cycling | strength(前端类型为三值联合 ✓)
[].targetKmnumber否float
[].targetSessionsnumber否int
[].durationWeeksnumber否int

错误码 ​

无业务错误码(公开只读接口)。服务不可用 → HTTP 5xx。


enrollTrainingPlan ​

一句话:报名训练计划 —— 服务端生成打卡任务 + 提醒。

🔴 这是本页最大的坑:业务失败也返回 HTTP 200 + code: "0",只是 data.ok = false。不是幂等 upsert —— 后端规则是「一次只允许一个进行中的计划」。

curl ​

bash
curl -s "$BASE_URL/api/v1/training/enroll" \
  -H 'Content-Type: application/json' \
  -H 'X-Env: Prd' \
  -H "Authorization: Bearer $ACCESS" \
  -d '{"planId":1}'

请求 ​

字段类型必填说明
planIdnumber✔来自 listTrainingPlans 的 [].id
userIdstring✖⚠️ 死参数 —— 后端忽略(越权修复)。传了无害,但别据此断言身份
Authorization / X-Envheader✔

响应 data(两条分支) ​

成功路径:

字段类型可空说明
okboolean否true
creatednumber否仅成功路径有 —— 创建的任务数
remindersnumber否仅成功路径有 —— 创建的提醒数
enrollmentIdnumber否后端返回第 4 键,前端未声明(不消费无影响)

失败路径(⚠️ HTTP 200 + code "0"):

字段类型可空说明
okboolean否false
reasonstring否已知取值:"计划不存在或未发布" · "已有进行中的计划(一次一个)"
created / reminders——失败路径不返回这两个键(前端 TS 声明为必填 number → 读到 undefined)

🔴 前端必做:await 之后先查 res.data.ok,再读 created。 直接读 er.created 会得到 undefined;直接按 HTTP/code 判成功会误报报名成功。 reason 可直接 toast(中文文案后端已给)。

错误码 ​

业务码HTTP触发条件前端建议处置
40406002401未登录 / token 无效走拦截器 401 分档
40406001400planId 缺失(body.get("planId", 0) → 0)检查调用点
40406005400计划已下架(PLAN_ARCHIVED)toast「计划已下架」+ 刷新列表
—200计划冲突 / 计划不存在⚠️ 不是错误码 —— 查 data.ok === false + data.reason

listMyTasks ​

一句话:我的打卡任务列表(按计划日排序)—— 计划页 / 日历页。

curl ​

bash
curl -s "$BASE_URL/api/v1/training/tasks?cacheTime=$(date +%s)" \
  -H 'X-Env: Prd' \
  -H "Authorization: Bearer $ACCESS"

请求 ​

字段类型必填说明
user_id (query)string✖⚠️ 死参数 —— 后端忽略(身份以 token 为准)。前端目前传本地 storage uid
cacheTime (query)number✖前端自动附加(防缓存击穿),后端忽略
Authorization / X-Envheader✔

响应 data —— 顶层是数组 ​

字段类型可空说明
[].idnumber否int —— 打卡时回传
[].weekIndex / [].sessionIndexnumber否int,周序 / 课序
[].plannedDatestring否'YYYY-MM-DD'
[].kindstring否来自所属 plan.kind
[].statusstring否实际只产生 'pending' | 'done' —— 'missed' 后端无生成逻辑(前端类型更宽 ✓)
[].completeSourcestring | null是manual | auto_sport

错误码 ​

业务码HTTP触发条件前端建议处置
40406002401未登录 / token 无效走拦截器 401 分档

checkinTask ​

一句话:任务打卡(幂等:已完成直接返回 status='done')。

🔴 坑位:task 不存在 / 非本人时返回 data: null(HTTP 200,不报错不 404)。 前端现状是 await 后本地把 task.status = 'done' → null 时显示「打卡成功」= 假成功。

curl ​

bash
curl -s "$BASE_URL/api/v1/training/task/checkin" \
  -H 'Content-Type: application/json' \
  -H 'X-Env: Prd' \
  -H "Authorization: Bearer $ACCESS" \
  -d '{"taskId":1}'

请求 ​

字段类型必填说明
taskIdnumber✔来自 listMyTasks 的 [].id
userIdstring✖⚠️ 死参数 —— 后端忽略
Authorization / X-Envheader✔

响应 data ​

字段类型可空说明
(整个 data)object | null是🔴 null = task 不存在或非本人
taskIdnumber是回显
statusstring是'done'

🔴 前端必做:if (!res.data) { /* 打卡失败,别置本地 done */ }。 正常路径 taskId 来自任务列表,不易触发;但任何"离线补打卡"/"从通知进打卡"的场景都会踩。

错误码 ​

业务码HTTP触发条件前端建议处置
—200task 不存在 / 非本人⚠️ 不是错误码 —— 判 data === null,勿本地置 done
40406002401未登录走拦截器 401 分档
40406004404计划/任务不存在(NOT_FOUND)toast + 刷新任务列表

listMyReminders ​

一句话:我的提醒列表(App 内提醒)—— 计划页提醒区块。

curl ​

bash
curl -s "$BASE_URL/api/v1/training/reminders?cacheTime=$(date +%s)" \
  -H 'X-Env: Prd' \
  -H "Authorization: Bearer $ACCESS"

请求 ​

字段类型必填说明
user_id (query)string✖⚠️ 死参数(同 tasks)
Authorization / X-Envheader✔

响应 data —— 顶层是数组 ​

字段类型可空说明
[].idnumber否int
[].taskIdnumber否关联任务
[].remindAtstring ISO否提醒时刻
[].statusstring否pending 等

错误码 ​

业务码HTTP触发条件前端建议处置
40406002401未登录走拦截器 401 分档

本页合同要点速记 ​

要点值
身份来源token(body.userId / ?user_id 全是死参数)
业务失败表达enroll → data.ok=false;checkin → data=null(都不是错误码)
列表响应形态plans / tasks / reminders 顶层都是数组(直接 res.data.map)
缺 missedtasks[].status 后端只产 pending / done