← 返回导航

API 设计

Spring Boot 风格

基础路径:`https://timesake-api.shihesuian.cn/api/v1`
认证:`Authorization: Bearer `(登录后下发,有效期 30 天)
统一响应:`{"code": 0, "message": "ok", "data": {...}}`(code=0 成功,非 0 见 message)
v0.2(2026-08-11 迭代二):记录支持图片(imageUrl 可空、content 可空,双空报 4001);自定义里程碑 `PUT /projects/{id}/milestones`;分享 records 带 `image_url`;文件上传接口归档

1. 认证(手机号验证码)

方法路径说明
POST/auth/sms/send发送验证码 {phone, scene} → 60s 限频,5 分钟有效
POST/auth/login登录/注册 {phone, code}{token, user}
POST/auth/wx-login微信小程序一键登录 {code}(免登录)→ code2session 换 openid → 已有账号直接登录/无则自动注册;未配置 AppID/Secret 返回 5001
POST/auth/bind-phone绑定手机号 {phone, code}(需登录):手机号未注册→直接绑定;已注册→自动合并(微信账号的项目/成员/记录/邀请/待办/分享迁入手机号账号后删除),返回新 token
GET/auth/me获取当前用户信息
PUT/auth/me更新昵称/头像

2. 项目

方法路径说明
POST/projects创建项目 {name, type, target_time?, start_time?, repeat_rule, icon, color}
GET/projects我的项目列表(创建 + 加入),支持 ?status=1 过滤
GET/projects/{id}项目详情(含成员数、我的角色)
PUT/projects/{id}编辑项目(管理员)
DELETE/projects/{id}删除项目(管理员,物理删除连带成员/记录)
PUT/projects/{id}/status转珍藏/封存(仅支持 status=2:期待 1→2 转珍藏 / 坚持 1→2 封存;重复转返回 4105)
PUT/projects/{id}/milestones自定义里程碑整体替换(管理员){milestones:[{name,days}]}:≤5 个、name 非空、days≥1,超限/null 报 4001;空列表=清空;项目详情响应带 milestones

3. 邀请与加入

方法路径说明
POST/projects/{id}/invite生成邀请 {expire_days=7}{token, qr_payload}
POST/projects/join加入项目 {token} → 项目详情
GET/projects/{id}/members成员列表
DELETE/projects/{id}/members/{uid}移除成员(管理员)

4. 记录条目(共同维护)

方法路径说明
POST/projects/{id}/records添加记录 {content?, imageUrl?, value_json?, record_date?}content 与 imageUrl 至少一项(双空报 4001),支持图文/纯图/纯文字
GET/projects/{id}/records记录列表(含 image_url),支持 ?record_date=2026-08-01?limit=50&offset=0
DELETE/projects/{id}/records/{rid}删除记录(本人或管理员)

6. 文件上传

方法路径说明
POST/upload/imagemultipart 上传图片 file{url}服务端统一压缩:最长边 >1920px 等比缩放 + JPEG 80%;≤1920px 原样直存;HEIC/解码失败兜底原图直存;支持 jpg/png/webp/heic/heif,限 10MB;失败 4002)

5. 待办(期待筹备期,一期)

方法路径说明
POST/projects/{id}/todos添加待办 {content}(仅期待项目)
GET/projects/{id}/todos待办列表
PUT/todos/{id}勾选/取消完成(记录 done_by/done_at 留痕)

7. 分享(珍藏只读)

方法路径说明
POST/projects/{id}/share生成只读分享(仅珍藏项目+管理员;已有有效分享则复用)→ {token, url}
DELETE/projects/{id}/share作废分享(管理员)
GET/share/{token}只读内容 {project, records, todos, wish}无需登录;records 含 image_url 支持媒体版时间线;坚持封存额外返回 days_elapsed/sealed_at 冻结值;曾是一念的珍藏额外返回 wish——一念描述 + 参与档案 + 建议(附议数/被采纳/留言嵌套),供分享页展示「这一念的旅程」)

8. 实时同步(WebSocket)

连接:wss://timesake-api.shihesuian.cn/ws/projects/{id}?token=<jwt>
鉴权(2026-08-16 评审 P0 修复):握手校验 JWT + 项目权限——进行中/珍藏需为正式成员;
一念(status=0)需为成员或已「看见」(参与档案 seen=1)。无权限连接被拒(1008 Policy Violation)。
消息(服务端→客户端):
  {"type": "record_added",   "data": {...record}}
  {"type": "record_deleted", "data": {"id": 123}}
  {"type": "member_joined",  "data": {...user}}
  {"type": "project_updated","data": {...project}}
  {"type": "todo_added", "data": {...todo}}          // 待办新增(2026-08-13)
  {"type": "todo_toggled", "data": {...todo}}        // 待办勾选(2026-08-13)
  {"type": "wish_updated", "data": null}             // 一念:表态/建议/附议变化
  {"type": "suggestion_commented", "data": null}     // 一念:留言/回复变化
客户端心跳:每 30s 发送 {"type": "ping"}(H5 发字符串,小程序发 {data})

9. 关键字段示例

创建项目请求:

{
  "name": "宝宝成长倒计时",
  "type": 2,
  "start_time": "2026-03-15T00:00:00+08:00",
  "repeat_rule": 0,
  "icon": "baby",
  "color": "#FFB6C1"
}

项目详情响应:

{
  "code": 0,
  "data": {
    "id": 1,
    "name": "宝宝成长倒计时",
    "type": 2,
    "start_time": "2026-03-15T00:00:00+08:00",
    "target_time": null,
    "repeat_rule": 0,
    "icon": "baby",
    "color": "#FFB6C1",
    "role": 1,
    "member_count": 3,
    "days_elapsed": 139,
    "milestones": [{"name": "会走路了", "days": 365}]
  }
}

记录列表响应(含图片):

{
  "code": 0,
  "data": [
    {
      "id": 88,
      "content": "今天会叫妈妈了!",
      "image_url": "https://timesake-api.shihesuian.cn/uploads/2026/08/xxxx.jpg",
      "record_date": "2026-08-11",
      "created_by": 1
    }
  ]
}

上传图片响应:

{"code": 0, "data": {"url": "https://timesake-api.shihesuian.cn/uploads/2026/08/xxxx.jpg"}}

10. 错误码

code含义
0成功
1001验证码错误/过期
1002发送太频繁(60s)
1003短信服务未配置
1004短信发送失败
1005登录状态失效,请重新登录(TOKEN_INVALID,2026-08-16 起独立码,原与 1003 重号)
1006验证码错误次数过多,已锁定 15 分钟(2026-08-16 防爆破)
2001未登录/令牌缺失
2002无权限(非管理员操作 / 用户被禁用)
3001项目不存在
3002邀请无效/过期
3003你不是该项目成员(含一念未「看见」)
4001参数错误(含:记录 content 与 imageUrl 双空;里程碑 >5 个或字段非法)
4002图片上传失败
4003仅支持 jpg/png/webp/heic 图片
4004图片不能超过 10MB
4005背景不存在
4101待办不存在
4102分享不存在或已失效
4103仅珍藏的项目可生成分享
4104仅进行中的项目可转为珍藏
4105该项目已珍藏
4106仅一念(status=0)可进行此操作(vote/confirm/suggestions/support/留言)
4107已珍藏的记忆不可修改(珍藏态 update 封禁)
5001微信登录未配置(缺 TIMESAKE_WX_APPID/SECRET)
5002微信登录失败(code2session 异常)
一念接口:`POST /projects/{id}/vote`(表态)、`/confirm`(敲定转正)、`/suggestions`(提建议)、`/suggestions/{sid}/support`(附议)、`/suggestions/{sid}/comments`(留言/回复/删除)——完整契约见 `spec-iteration-a.md`;建议 type 枚举已扩展至 1-7(交通/集合/预算/分工,迭代 B),见 `spec-iteration-b.md`。
`/confirm` 敲定时再选类型:请求体加 `type`(1=转期待 填 `targetTime` / 2=转坚持 填 `startTime`,默认 1)——采纳时间建议按 type 分流写入 `target_time` 或 `start_time`,详见 `spec-iteration-c.md`。

11. 备注