4ce4486b26
新增 IndexedDB 与最近文件 L1 缓存、云保存/打开链路;首页支持下载与清空本地缓存;修复清空 storage 后语言初始化报错;优化 design2 背景加载与侧栏标签样式;完善会员激活/支付弹层样式;后端补充文件缩略图字段与 thumb 接口。 Co-authored-by: Cursor <cursoragent@cursor.com>
7.5 KiB
7.5 KiB
列表分页 API 契约
本文描述 backend-web 公开端(/api/v1)与管理端(/api/admin)列表接口的分页约定。实现以仓库内 PHP 控制器为准。
通用响应包装
所有 JSON 接口统一:
{
"ok": true,
"data": { }
}
失败时 ok: false,含 error(机器码)与 message(人类可读文案)。
推荐分页形态(page / size / total)
新接口与前端管理列表优先使用此形态。
请求 Query
| 参数 | 类型 | 默认 | 上限 | 说明 |
|---|---|---|---|---|
page |
int | 1 |
— | 从 1 开始 |
size |
int | 见各接口 | 见各接口 | 每页条数 |
响应 data
| 字段 | 类型 | 说明 |
|---|---|---|
items |
array | 当前页记录 |
total |
int | 符合条件的总条数(用于算总页数) |
page |
int | 当前页码(回显) |
size |
int | 当前每页条数(回显) |
总页数:ceil(total / size),total === 0 时视为 0 条、1 页。
示例
GET /api/admin/users?page=2&size=20&q=test%40local.test
Authorization: Bearer <admin_token>
{
"ok": true,
"data": {
"items": [ { "id": 1, "email": "..." } ],
"total": 42,
"page": 2,
"size": 20
}
}
管理端分页列表(/api/admin)
需管理员 JWT(role=admin)。默认 size 与上限见下表。
| 方法 | 路径 | 默认 size | size 上限 | 额外筛选 Query |
|---|---|---|---|---|
| GET | /api/admin/users |
20 | 200 | q 邮箱模糊 |
| GET | /api/admin/orders |
20 | 200 | q 订单号或邮箱;status pending/paid/cancelled/refunded;refund_status none/pending/approved/rejected;channel alipay/wechat;from/to 日期 YYYY-MM-DD |
| GET | /api/admin/audits |
50 | 200 | q 操作/目标/管理员邮箱;action 精确操作码;from/to 日期 |
实现参考:
backend-web/src/Admin/Controllers/UsersController.phpbackend-web/src/Admin/Controllers/OrdersController.phpbackend-web/src/Admin/Controllers/AuditsController.php
管理端全量列表(无分页)
以下接口一次返回全部 items,数据量预期较小:
| 路径 | 说明 |
|---|---|
GET /api/admin/plans |
套餐配置 |
GET/POST /api/admin/templates、PUT/DELETE /api/admin/templates/{id} |
模板库 CRUD |
GET /api/admin/settings |
系统键值 |
GET /api/admin/payment/status |
PEM 文件元数据 |
管理端固定条数嵌套列表
| 来源 | 条数 | 说明 |
|---|---|---|
GET /api/admin/stats → recent_orders |
5 | 仪表盘最近订单,非翻页接口 |
GET /api/admin/users/{id} → recent_orders |
5 | 用户详情内嵌 |
公开端分页列表(/api/v1)
需用户 JWT(除 plans 列表可匿名,见各控制器)。
| 方法 | 路径 | 默认 size | size 上限 | 分页参数 | 响应 |
|---|---|---|---|---|---|
| GET | /api/v1/files |
50(legacy) | 200 | 推荐 page+size;兼容 limit+offset |
见下文 |
| GET | /api/v1/pay/orders |
8 | 50 | page+size |
page 形态 |
实现参考:
backend-web/src/Controllers/FileController.phpbackend-web/src/Controllers/PayController.phpbackend-web/src/Services/MembershipService.php(listOrders)
GET /api/v1/files 双模式
推荐(page 形态) — 传 page≥1 时生效:
GET /api/v1/files?page=1&size=12
{
"ok": true,
"data": {
"items": [ { "id": 1, "name": "design.soon", "size": 1024, "version": 1 } ],
"total": 25,
"page": 1,
"size": 12
}
}
兼容(offset 形态) — 未传 page 或 page=0 时:
GET /api/v1/files?limit=50&offset=0
{
"ok": true,
"data": {
"items": [ ],
"total": 25,
"limit": 50,
"offset": 0
}
}
两种形态均含 total。新前端(首页文件列表、管理端)应使用 page+size。
GET /api/v1/pay/orders
会员中心订单历史,默认每页 8 条:
GET /api/v1/pay/orders?page=1&size=8
公开端全量 / 非标准列表
| 路径 | 形态 |
|---|---|
GET /api/v1/plans |
{ items: [...] } 全量活跃套餐 |
GET /api/v1/auth/me |
当前用户 + 会员摘要(is_member / tier / name) |
GET /api/v1/plans/me |
完整会员配额信息(云端用量等,按需调用) |
GET /api/v1/settings |
扁平 key-value 对象,非 items 数组 |
GET /api/v1/templates |
首页模板列表(仅 id/name/type/updated_at;缩略图按需拉取) |
GET /api/v1/templates/{id} |
模板 JSON 数据(门户标准读取端点,见下) |
GET /api/v1/templates/{id}/thumb |
模板缩略图(从 .soon 内 frontDisplayPic 提取) |
GET /api/v1/templates/{id}/file |
裸 .soon 流(Cache-Control: max-age=86400);门户读缓存首选 |
GET /api/v1/files/{id}/thumb |
云文件缩略图(需登录;从 .soon 内 frontDisplayPic 提取) |
GET /api/v1/soon-models |
兼容别名,同 GET /api/v1/templates |
GET /api/v1/templates/{id}(门户读取模板数据)
与 GET /api/v1/files/{id} 对齐,返回 JSON 包装,非裸文件流:
{
"ok": true,
"data": {
"id": 1,
"name": "示例模版",
"type": 1,
"updated_at": "2026-06-09 00:23:29",
"json": "{...}"
}
}
data.json为 字符串(与files/{id}一致),前端JSON.parse(data.json)后加载画布- 公开接口,无需登录
Web 虚拟 key 前缀(门户设计页)
| 前缀 | 含义 | readJsonFile | 保存 writeFile |
|---|---|---|---|
soondesign_file:{id}:v{ver} |
云端已登记文件 | GET /files/{id} |
PUT /files/{id} |
soondesign_template:{id} |
云端模板(只读源) | GET /templates/{id}/file |
POST /files(首次保存新建) |
soondesign_session:... |
本地/临时会话 | sessionStorage | 已登录 POST /files;未登录写 session |
- 保存/打开走 JSON API;仅首页「下载」走
GET /files/{id}/download落盘.soon - 门户读缓存与最近文件本地优先策略见
WEB-LOCAL-CACHE.md;模板首次加载推荐GET /templates/{id}/file(流式.soon,避免GET /templates/{id}二次包装)
前端约定
管理后台(frontend-web/pages/admin)
- 分页状态:
AdminState(users/orders/audits的page、size及筛选字段) - 分页 UI:
AdminPager+AdminUi.pagerHtml/bindPager - 请求:相对 admin base 的路径,如
users?page=1&size=20
门户 / 会员 / 首页
| 页面 | 接口 | 默认 size |
|---|---|---|
| 会员订单 | GET /api/v1/pay/orders |
8 |
| 首页云端文件 | GET /api/v1/files?page=&size= |
12 |
新增列表接口检查清单
- 响应是否包含
items+total? - 是否使用
page(从 1)+size,并在data中回显? size是否有合理默认值与上限(建议上限 200,管理端;用户订单建议 50)?- 筛选参数是否与分页独立(翻页时保留筛选)?
- 是否在本文档「管理端/公开端」表中登记?
变更记录
| 日期 | 说明 |
|---|---|
| 2026-06-08 | 初版:统一 page/size/total;files 兼容 limit/offset;pay/orders 分页 |
| 2026-06-08 | 新增 GET /templates/{id} JSON 契约;Web 虚拟 key 前缀;/file 标 legacy |
| 2026-06-08 | 新增 GET /files/{id}/thumb;files list 增 has_thumb;模板 /file 长缓存 |