619 lines
39 KiB
Markdown
619 lines
39 KiB
Markdown
# 第一阶段接口清单(后台管理 + 客户端)
|
||
|
||
> 版本 v1.0 · 配套 [PRD](./prd-phase1.md) 与 [后端设计](./backend-design-phase1.md)
|
||
> 状态说明:**已实现** = 代码已落地可联调;**下一批** = 表结构与契约已冻结,代码待补。
|
||
|
||
## 0. 通用约定
|
||
|
||
**服务入口**:后台管理 `fruitshorts-admin-api` 只暴露 `/admin/**`(8080);
|
||
客户端 `fruitshorts-app-api` 只暴露 `/app/**` 与媒资 `/files/**`(8081)。
|
||
|
||
**统一响应体**
|
||
|
||
```json
|
||
{ "code": 0, "message": "ok", "data": {} }
|
||
```
|
||
|
||
`code = 0` 成功;非 0 时 `message` 可直接展示给用户。分页统一为 `{ total, list }`。
|
||
|
||
**鉴权**:`Authorization: Bearer <token>`。
|
||
管理端与客户端用**两套独立密钥**签发,管理端 token 打到客户端接口会直接被拒。
|
||
客户端 `access token` 默认 2 小时,`refresh token` 30 天且每次刷新轮换。
|
||
|
||
**设备标识**:客户端建议所有请求都带 `X-Device-Id`,用于下载授权、并发播放限制与风控。
|
||
|
||
**主要错误码**
|
||
|
||
| code | 含义 | 客户端处理 |
|
||
| --- | --- | --- |
|
||
| 0 | 成功 | — |
|
||
| 400 | 参数校验失败 | 提示 message |
|
||
| 401 | 未登录或登录过期 | 用 refresh token 换新 token,失败则跳登录 |
|
||
| 403 | 无权限 | 提示无权限 |
|
||
| 429 | 请求过于频繁 | 提示稍后再试(验证码频控走这里) |
|
||
| 100000 | 账号或密码错误 | 提示 |
|
||
| 100001 | 账号已停用 | 展示封禁申诉入口 |
|
||
| 100002 | 金币余额不足 | 拉起充值 |
|
||
| 100003 | 剧集未发布或不存在 | 返回上一页 |
|
||
| 100005 | 订单已支付或已关闭 | 刷新订单状态 |
|
||
| 200002 | 数据不存在 | 提示 |
|
||
| 200003 | 当前状态不允许该操作 | 提示 |
|
||
|
||
## 1. 客户端接口(/app/**)
|
||
|
||
### 1.1 账号(已实现)
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| POST | `/app/auth/otp` | 匿名 | 发送验证码。`scene` = REGISTER/LOGIN/RESET_PWD/BIND |
|
||
| POST | `/app/auth/register` | 匿名 | 手机号/邮箱注册,返回令牌 |
|
||
| POST | `/app/auth/login` | 匿名 | 验证码或密码登录 |
|
||
| POST | `/app/auth/refresh` | 匿名 | 用 refresh token 换新令牌并轮换 |
|
||
| POST | `/app/auth/logout` | 可选 | 登出;`allDevices=true` 吊销全部会话 |
|
||
|
||
发送验证码:
|
||
|
||
```json
|
||
POST /app/auth/otp
|
||
{ "scene": "REGISTER", "targetType": "PHONE", "target": "08123456789", "deviceId": "d-1" }
|
||
```
|
||
|
||
手机号会自动规范化成 E.164(印尼本地 `08xx` → `+62xxx`)。频控:同号 60 秒一次、每日 10 次,
|
||
同 IP 每小时 20 次;连续输错 5 次该验证码作废。
|
||
|
||
注册:
|
||
|
||
```json
|
||
POST /app/auth/register
|
||
{
|
||
"targetType": "PHONE", "target": "08123456789", "code": "123456",
|
||
"password": "可选,设置后可用密码登录",
|
||
"nickname": "可选",
|
||
"deviceId": "d-1", "platform": "IOS", "appVersion": "1.0.0",
|
||
"agreementVersion": "2026-10-01", "marketingConsent": false
|
||
}
|
||
```
|
||
|
||
**邮箱 + 密码注册(C 端第一批口径)**
|
||
|
||
```json
|
||
POST /app/auth/register
|
||
{
|
||
"targetType": "EMAIL", "target": "User@Example.com ", "password": "nonton2026",
|
||
"deviceId": "d-1", "countryCode": "ID", "agreementVersion": "2026-10-01"
|
||
}
|
||
```
|
||
|
||
| 规则 | 口径 |
|
||
| --- | --- |
|
||
| `targetType=EMAIL` | **`code` 可以不传**(邮箱+密码直接注册);传了就走一次验证码校验(邮箱验证能力保留) |
|
||
| `targetType=PHONE` | 维持原状:`code` **必填** |
|
||
| 邮箱规范化 | 去空格 + 转小写(`batch1@Example.com ` → `batch1@example.com`);格式不合法直接 `400 邮箱格式不正确` |
|
||
| 密码强度 | 8–64 位,且**同时包含字母与数字**(不强制特殊字符:低端机输入成本高,拦机器注册靠频控) |
|
||
| 注册频控 | 同 IP 24h ≤ **5** 个、同设备 24h ≤ **3** 个,超出返回 `429`(`TOO_MANY_REQUESTS`) |
|
||
| 邮箱验证状态 | 免码注册时 `app_user_credential.verified = 0`(保留"待验证"),**不阻塞登录**;只有**验证码登录**会把 `verified` 置 1,密码登录不改变该状态 |
|
||
|
||
频控口径落库在 `app_user.register_ip` / `register_device_id` 上(按 24h 计数,不新建计数表)。
|
||
**残留风险**:IP 取自 `X-Forwarded-For`、设备号由客户端上报,都能伪造,只能挡脚本批量;
|
||
真要防住需要接图形/行为验证码或风控服务,本阶段未做。验证码通道目前是 `LogOtpSender`(只写日志不发信),
|
||
所以邮箱**可达性**未验证 —— 这也是"不阻塞注册"的前提。
|
||
|
||
响应(登录、刷新同结构):
|
||
|
||
```json
|
||
{
|
||
"code": 0, "message": "ok",
|
||
"data": {
|
||
"accessToken": "...", "refreshToken": "...", "expiresIn": 7200, "tokenType": "Bearer",
|
||
"newUser": true,
|
||
"user": { "uid": "U8KQ2ZP1", "nickname": "User8KQ2ZP", "status": "normal",
|
||
"countryCode": "ID", "language": "id-ID", "currency": "IDR",
|
||
"maskedTarget": "+628****789", "vipLevel": 0, "vipExpireAt": null }
|
||
}
|
||
}
|
||
```
|
||
|
||
### 1.2 个人中心(已实现)
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/app/me` | 当前用户资料 |
|
||
| PUT | `/app/me` | 修改昵称/头像/性别/生日/语言/时区/区域 |
|
||
| GET | `/app/me/devices` | 登录设备列表 |
|
||
| GET | `/app/me/export` | 数据导出(商店与隐私法规要求) |
|
||
| POST | `/app/me/deactivate` | 申请注销,进入 15 天冷静期并立即登出全部设备 |
|
||
| POST | `/app/me/deactivate/cancel` | 冷静期内撤销注销 |
|
||
|
||
### 1.3 内容浏览(已实现)
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/app/home/feed` | 首页:轮播 + 分区,卡片带 `preview` 可播预览集 |
|
||
| GET | `/app/discover/feed` | 发现页分区 |
|
||
| GET | `/app/categories` | 分类列表 |
|
||
| GET | `/app/dramas/{id}` | 详情(含剧集列表,免费集带**已签名**播放地址) |
|
||
|
||
### 1.4 播放(已实现,链路已重做)
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/app/episodes/{id}/play` | 可选 | 签发播放票据与签名地址 |
|
||
|
||
```json
|
||
{
|
||
"code": 0, "message": "ok",
|
||
"data": {
|
||
"episodeId": 12, "dramaId": 5, "number": 1, "title": "第 1 集", "durationSec": 180,
|
||
"accessible": true,
|
||
"accessType": "FREE",
|
||
"playUrl": "/files/episode/202610/xxx.mp4?e=1760000000&s=9f2c...",
|
||
"qualities": ["AUTO"],
|
||
"unlockCoin": 0,
|
||
"previewSeconds": 0
|
||
}
|
||
}
|
||
```
|
||
|
||
`accessType` 取值:`FREE`(免费集)、`ENTITLED`(已购权益)、`COIN_REQUIRED`(需解锁,
|
||
此时 `playUrl` 为空、`unlockCoin` 有值)、`NO_MEDIA`(还没上传片源或未转码完成)。
|
||
|
||
**判定顺序由服务端决定,客户端不得自行推断可否播放。** 签名默认 15 分钟有效;
|
||
开启 `fruitshorts.media.signature-required` 后,`/files/episode/**` 没带有效签名会返回 403。
|
||
|
||
### 1.5 观看记录与收藏(已实现)
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| POST | `/app/watch/progress` | 上报进度(建议每 10s 一次,切集时补一次) |
|
||
| GET | `/app/watch/progress?dramaId=` | 某剧续看位置 |
|
||
| GET | `/app/watch/recent?limit=20` | 最近观看 |
|
||
| DELETE | `/app/watch/progress/{dramaId}` | 删除某剧记录 |
|
||
| DELETE | `/app/watch/progress` | 清空记录 |
|
||
| POST | `/app/favorites/toggle` | 收藏/取消收藏,返回切换后状态 |
|
||
| GET | `/app/favorites` | 收藏列表(卡片结构与首页一致) |
|
||
| DELETE | `/app/favorites/{dramaId}` | 取消收藏 |
|
||
|
||
进度合并规则:同一集内只前进不后退;换集直接采纳新集;`finished` 只在接近片尾或客户端显式上报时置位。
|
||
这样用户换设备不会看到进度倒退。
|
||
|
||
### 1.6 离线下载(已实现)
|
||
|
||
服务端只发**授权**与**短时效地址**,分片由客户端直接向 CDN 拉取 ——
|
||
这样并发下载不会打到应用服务器,服务端只记账(进度、配额、有效期)。
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/app/downloads/policy` | 策略与配额:单设备上限、授权天数、仅 Wi-Fi、清晰度上限、已用/剩余 |
|
||
| PUT | `/app/downloads/settings` | 偏好设置:仅 Wi-Fi 下载、最高清晰度 |
|
||
| POST | `/app/downloads` | 申请下载授权(同剧集重复申请幂等,只刷新有效期) |
|
||
| GET | `/app/downloads` | 下载列表(授权 + 任务进度,可直接渲染) |
|
||
| GET | `/app/downloads/{episodeId}/url` | 断点续传前重新取地址(授权不变,地址是短时效的) |
|
||
| POST | `/app/downloads/{episodeId}/progress` | 上报下载进度,用于断点续传与跨端展示 |
|
||
| DELETE | `/app/downloads/{episodeId}` | 删除单条下载(吊销授权) |
|
||
| DELETE | `/app/downloads` | 清空当前设备全部下载,返回清除条数 |
|
||
|
||
设备标识优先取请求体 `deviceId`,其次取请求头 `X-Device-Id`。
|
||
授权默认 30 天有效,过期由每日定时任务置为 `EXPIRED`;被吊销或过期的授权客户端下次联网即失效。
|
||
需要解锁的剧集走权益判定,未解锁不允许下载(当前内容均为免费集,付费链路见 09)。
|
||
配额与有效期由 `fruitshorts.download.*` 配置,通过 `policy` 下发,客户端不要写死。
|
||
|
||
### 1.7 互动与内容治理(已实现)
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| POST | `/app/comments` | 登录 | 发表评论/回复:过敏感词后按策略发布或转待审 |
|
||
| GET | `/app/comments?dramaId=&cursor=&size=` | 匿名 | 游标翻页;不传 `rootId` 返回顶层评论,传了返回该楼层回复 |
|
||
| DELETE | `/app/comments/{id}` | 登录 | 删除自己的评论(逻辑置为 `deleted`) |
|
||
| POST | `/app/likes/toggle` | 登录 | 点赞/取消点赞,`targetType` 支持 `DRAMA` / `COMMENT` |
|
||
| POST | `/app/reports` | 登录 | 举报评论/用户/短剧;同一目标只保留一条待处理工单 |
|
||
|
||
**敏感词三档处置**:`BLOCK` 直接拒绝并返回原因、`REPLACE` 替换后放行、`REVIEW` 转人工待审。
|
||
审核策略由 `fruitshorts.interaction.comment-audit-mode` 控制:
|
||
`MACHINE_FIRST`(机审通过即发布,当前默认)或 `PRE_REVIEW`(全部先审后发,生产建议)。
|
||
|
||
**可见性**:匿名与其他人只看得到 `published`;自己待审的评论也会返回,便于展示"审核中"。
|
||
评论列表禁止重复提交(同一剧集每分钟 5 条,可配)。
|
||
|
||
### 1.8 金币与权益(已实现)
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/app/wallet` | 金币余额 + 最近流水 |
|
||
| POST | `/app/episodes/{id}/unlock` | 金币解锁分集;幂等键 `unlock:{userId}:{episodeId}`,重复调用不重复扣币 |
|
||
| GET | `/app/orders` | 我的订单 |
|
||
| POST | `/app/orders/verify` | 提交 IAP / Google Play 票据。**本轮只留端口不接商店**,会返回 `200003 尚未配置` |
|
||
|
||
解锁后播放入口与下载入口会同时放行 —— 权益判定由交易模块的 `EntitlementPort` 实现提供,
|
||
播放域与下载域都不需要改代码。金币变动一律带幂等键并写 `coin_ledger`,钱包余额与流水同事务。
|
||
|
||
### 1.9 创作者(下一批)
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/app/orders` | 我的订单 |
|
||
| GET | `/app/wallet` | 金币余额与流水 |
|
||
| POST | `/app/episodes/{id}/unlock` | 金币解锁分集 |
|
||
| POST | `/app/creator/apply` | 创作者入驻 |
|
||
| GET | `/app/creator/works` | 我的作品与审核状态 |
|
||
| GET | `/app/creator/stats` | 创作者数据看板 |
|
||
| GET | `/app/config` | 启动配置(协议版本、开关、最低版本) |
|
||
| GET | `/app/notices` | 系统公告 |
|
||
|
||
## 2. 后台管理接口(/admin/**)
|
||
|
||
### 2.1 认证与系统(已实现)
|
||
|
||
**认证**
|
||
|
||
| 方法 | 路径 | 鉴权 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| POST | `/admin/auth/login` | 匿名 | 登录,返回 token |
|
||
| GET | `/admin/auth/menus` | 登录 | 当前用户菜单树 |
|
||
| GET | `/admin/auth/profile` | 登录 | 当前用户资料 |
|
||
| POST | `/admin/auth/logout` | 登录 | 登出 |
|
||
| POST | `/admin/auth/password` | 登录 | 修改密码 |
|
||
|
||
**系统管理(RBAC)**
|
||
|
||
| 资源 | 方法 | 路径 | 权限点 |
|
||
| --- | --- | --- | --- |
|
||
| 管理员 | GET | `/admin/admin-users/page` · `/{id}` | `system:admin-user` |
|
||
| 管理员 | POST | `/admin/admin-users` | `system:admin-user` |
|
||
| 管理员 | PUT | `/admin/admin-users/{id}` · `/{id}/status` · `/{id}/password` | `system:admin-user` |
|
||
| 管理员 | DELETE | `/admin/admin-users/{id}` | `system:admin-user` |
|
||
| 角色 | GET | `/admin/roles/page` · `/list` · `/{id}` · `/{id}/permissions` | `system:role`(`/list` 登录即可) |
|
||
| 角色 | POST | `/admin/roles` | `system:role` |
|
||
| 角色 | PUT | `/admin/roles/{id}` · `/{id}/permissions` | `system:role` |
|
||
| 角色 | DELETE | `/admin/roles/{id}` | `system:role` |
|
||
| 权限 | GET | `/admin/permissions` | `system:role` |
|
||
| 菜单 | GET | `/admin/menus/tree` | `system:menu` |
|
||
| 菜单 | POST · PUT · DELETE | `/admin/menus` · `/admin/menus/{id}` | `system:menu` |
|
||
| 角色分类 | GET · POST | `/admin/role-categories` | `system:role-category` |
|
||
| 角色分类 | PUT · DELETE | `/admin/role-categories/{id}` | `system:role-category` |
|
||
| 系统配置 | GET | `/admin/configs` | `system:role` / `system:menu` |
|
||
| 系统配置 | PUT | `/admin/configs` | `system:role` |
|
||
| 操作日志 | GET | `/admin/operation-logs/page` · `/{id}` | `log:list` |
|
||
| 字典 | GET | `/admin/dicts/drama-category` · `/content-status` | `drama:list` |
|
||
|
||
### 2.2 内容与媒资(已实现)
|
||
|
||
新增字段:短剧 `rating`(内容分级)、`regionCodes`(可播区域)、版权窗口、
|
||
`creatorId`、`tags`、`trailerUrl`;剧集 `transcodeStatus`、`hlsUrl`、`previewSeconds`、字幕。
|
||
|
||
**短剧(含审核发布状态机)**
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/dramas/page` | `drama:list` | 检索(含热门、状态筛选) |
|
||
| GET | `/admin/dramas/{id}` | `drama:list` | 详情 |
|
||
| POST | `/admin/dramas` | `drama:create` | 新建短剧 |
|
||
| PUT | `/admin/dramas/{id}` | `drama:update` | 编辑短剧 |
|
||
| DELETE | `/admin/dramas/{id}` | `drama:delete` | 删除短剧 |
|
||
| POST | `/admin/dramas/{id}/submit` | `drama:review` / `drama:update` | 提交审核 |
|
||
| POST | `/admin/dramas/{id}/approve` | `drama:review` | 审核通过 |
|
||
| POST | `/admin/dramas/{id}/reject` | `drama:review` | 驳回 |
|
||
| POST | `/admin/dramas/{id}/publish` | `drama:review` | 上线 |
|
||
| POST | `/admin/dramas/{id}/offline` | `drama:review` | 下线 |
|
||
| GET | `/admin/dramas/{id}/review-records` | `drama:list` | 审核记录 |
|
||
|
||
**剧集**
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/episodes?dramaId=` | `episode:list` | 某剧分集列表 |
|
||
| POST | `/admin/episodes` | `episode:upload` | 新增分集 |
|
||
| PUT | `/admin/episodes/{id}` | `episode:upload` | 编辑分集 |
|
||
| DELETE | `/admin/episodes/{id}` | `episode:upload` | 删除分集 |
|
||
| PUT | `/admin/episodes/sort` | `episode:sort` | 批量排序 |
|
||
|
||
**短剧类型**
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/drama-categories` | `drama:list` | 类型列表 |
|
||
| POST | `/admin/drama-categories` | `drama:create` | 新增类型 |
|
||
| PUT | `/admin/drama-categories/{id}` | `drama:update` | 编辑类型 |
|
||
| DELETE | `/admin/drama-categories/{id}` | `drama:delete` | 删除类型 |
|
||
|
||
**轮播图**
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/banners/page` · `/admin/banners/{id}` | `banner:list` | 检索 / 详情 |
|
||
| POST | `/admin/banners` | `banner:create` | 新增 |
|
||
| PUT | `/admin/banners/{id}` · `/{id}/status` · `/sort` | `banner:update` | 编辑 / 改状态 / 排序 |
|
||
| DELETE | `/admin/banners/{id}` | `banner:delete` | 删除 |
|
||
|
||
**媒资分片上传(后台与创作者共用)**
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| POST | `/admin/media/upload/init` | 建上传会话(返回 `uploadId` / `chunkSize` / `totalChunks` / `objectKey`) |
|
||
| POST | `/admin/media/upload/chunk` | 传分片(`uploadId` + `index` + `file`),可重复传同一片 |
|
||
| GET | `/admin/media/upload/{uploadId}` | 断点续传回显(`receivedChunks` / `totalChunks` / `percent` / `status` / 完成后带 `url`) |
|
||
| POST | `/admin/media/upload/complete` | 合并分片出媒资(幂等:同一 uploadId 重复调用返回同一产物) |
|
||
| GET | `/admin/media/{id}` | 媒资详情 |
|
||
|
||
> 媒资上传与详情权限点均为 `cover:upload` 或 `episode:upload`(`@ss.hasAnyPermission`)。
|
||
|
||
**上传会话归属**:`uploadId` 相当于上传凭证,`chunk` / `complete` / 进度查询都校验会话发起人,
|
||
别人拿到 `uploadId` 也塞不进分片(`{"code":403,"message":"无权操作该上传会话"}`)。
|
||
|
||
### 2.3 App 用户管理(已实现)
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/app-users/page` | `app-user:list` | 检索:keyword(uid/昵称/手机号/邮箱)、status、countryCode、registerSource |
|
||
| GET | `/admin/app-users/{id}` | `app-user:list` | 详情 |
|
||
| GET | `/admin/app-users/{id}/ban-records` | `app-user:list` | 封禁与申诉记录 |
|
||
| GET | `/admin/app-users/{id}/watch-history` | `app-user:list` | 观看流水明细(带剧名/集号,客服核对用) |
|
||
| PUT | `/admin/app-users/{id}/status` | `app-user:update` | 改状态:normal/limited/banned |
|
||
|
||
状态处置会**立即吊销该用户全部会话**并写入封禁记录,避免"封了还能用"。
|
||
|
||
### 2.4 下载管理(已实现)
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/downloads/page` | `download:list` | 按用户 / 设备 / 状态检索下载授权,含剧名与集号 |
|
||
| GET | `/admin/downloads/stats` | `download:list` | 授权与任务的分布统计 |
|
||
| PUT | `/admin/downloads/{id}/revoke` | `download:revoke` | 吊销授权,用户侧下次联网即失效 |
|
||
| POST | `/admin/downloads/cleanup` | `download:revoke` | 手动清理过期授权(默认每天凌晨自动执行) |
|
||
|
||
### 2.5 内容治理(已实现)
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/comments/page` | `comment:list` | 检索评论,`status=pending` 即审核队列 |
|
||
| GET | `/admin/comments/{id}/audit-records` | `comment:list` | 审核留证:机审与人审的完整链路 |
|
||
| PUT | `/admin/comments/{id}/audit` | `comment:audit` | 通过 / 驳回(带原因码与说明) |
|
||
| DELETE | `/admin/comments/{id}` | `comment:audit` | 删除评论 |
|
||
| GET | `/admin/reports/page` | `report:list` | 举报工单检索(状态 / 类型 / 原因) |
|
||
| PUT | `/admin/reports/{id}/handle` | `report:handle` | 处理工单;结论成立会联动驳回被举报评论,可选择同时封禁被举报用户 |
|
||
| GET | `/admin/sensitive-words/page` | `sensitive-word:list` | 敏感词检索 |
|
||
| POST/PUT/DELETE | `/admin/sensitive-words[/{id}]` | `sensitive-word:update` | 维护词库,改动即时生效(服务端缓存失效重建) |
|
||
|
||
### 2.6 订单与权益(已实现)
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/orders/page` `/admin/orders/{orderNo}` `/{orderNo}/events` | `order:list` | 订单检索、详情、状态流转流水 |
|
||
| POST | `/admin/orders/{orderNo}/compensate` | `order:update` | 补发:已支付未交付的订单重新交付,已交付幂等返回 |
|
||
| POST | `/admin/orders/{orderNo}/refund` | `order:update` | 退款/撤销:回收权益 + 扣回金币(余额不足时留人工跟进备注) |
|
||
| GET | `/admin/entitlements/page` | `entitlement:list` | 权益检索 |
|
||
| POST | `/admin/entitlements` | `entitlement:update` | 人工补发权益(客服补偿) |
|
||
| PUT | `/admin/entitlements/{id}/revoke` | `entitlement:update` | 回收权益,播放判定实时生效 |
|
||
| GET | `/admin/wallets/{userId}/ledger` | `order:list` | 金币流水 |
|
||
| POST | `/admin/wallets/coins` | `wallet:update` | 人工补币/扣回,必须带幂等键,先校验用户存在 |
|
||
| POST | `/admin/reconcile/run` · GET `/admin/reconcile/page` | `reconcile:run` / `order:list` | 手动对账与历史(默认每天 04:20 自动跑前一天) |
|
||
|
||
### 2.7 创作者与内容审核(已实现)
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/creators/page` `/admin/creators/{id}` `/{id}/documents` | `creator:list` | 创作者检索、详情、资质文件 |
|
||
| PUT | `/admin/creators/{id}/audit` | `creator:audit` | 入驻审核:`APPROVE` / `REJECT`(必填原因+原因码)/ `FREEZE` |
|
||
| POST | `/admin/creators` | `creator:audit` | 手工录入创作者主体(C 端申请入驻未实现前的打通用口) |
|
||
| POST | `/admin/creators/{id}/account` | `creator:account` | 开通创作者账号(幂等) |
|
||
| POST | `/admin/creators/{id}/account/reset-password` | `creator:account` | 重置创作者账号密码(一次性明文返回) |
|
||
| GET | `/admin/submissions/page` `/admin/submissions/{id}` | `submission:list` | 内容提交检索与详情 |
|
||
| PUT | `/admin/submissions/{id}/audit` | `submission:audit` | 审核通过后按 `type` 落到短剧状态机(CREATE/UPDATE 留档、PUBLISH 上线、OFFLINE 下线) |
|
||
| GET · PUT | `/admin/prices` | `price:update` | 分集价格:整剧 `freeEpisodes`/`unlockCoin` + 逐集覆盖;改价立即影响播放与下载判定 |
|
||
|
||
**定时发布**:`DramaPublishJob` 每分钟扫一次,把 `publish_at` 到点的 `approved` 短剧推上线,
|
||
走的是短剧状态机(不直接改状态字段)。上下架也可通过内容提交的 `OFFLINE` 审核触发。
|
||
|
||
### 2.8 数据看板(已实现,只读)
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/dashboard/overview` | `dashboard:view` | 总览:用户 / 内容 / 播放 / 收入 / 成本 |
|
||
| GET | `/admin/dashboard/transcode` | `dashboard:view` | 转码队列积压与失败任务明细(含 `errorMsg` / `retryCount`) |
|
||
|
||
**口径(与代码注释一致,前端 tooltip 可直接复用)**
|
||
|
||
| 分组 | 指标 | 口径 |
|
||
| --- | --- | --- |
|
||
| 用户 | `total` / `newToday` / `new7d` | `app_user` 未删除总数;按 `created_at` 落在当天 / 近 7 天 |
|
||
| 用户 | `active7d` | `last_login_at` 在近 7 天内。**不是 DAU**,日活需要逐日登录快照,当前无产出 |
|
||
| 用户 | `banned` / `limited` / `deactivated` | 按 `status` 计数 |
|
||
| 内容 | `drama*` | 短剧按 `status` 计数(`reviewing` 为待审、`published` 为已上线) |
|
||
| 内容 | `episodeTotal` / `Published` / `WithMedia` | 剧集总数 / 已上线数 / `video_url` 非空数(均排除逻辑删除) |
|
||
| 内容 | `commentPending` / `reportPending` | 待审评论、待处理举报 |
|
||
| 播放 | `viewTotal` / `playTotal` | 短剧表累计计数列求和(累计口径,不限时间) |
|
||
| 播放 | `watchedDramas` / `finishedDramas` / `finishRate` | `watch_progress` 行数 / 其中 `finished=1` / 完播率 |
|
||
| 播放 | `playEvents7d` / `playEventsTotal` | `watch_history` 流水口径(与累计口径不可相加) |
|
||
| 收入 | `order*` / `paidAmount` | 订单按状态计数;金额为已支付+已交付合计(商店未接入前恒为 0) |
|
||
| 收入 | `coinRecharged` / `coinConsumed` / `coinBalance` | 取自 `coin_ledger`(RECHARGE / UNLOCK)与 `wallet` 余额合计 |
|
||
| 收入 | `entitlementActive` | 有效权益数 |
|
||
| 成本 | `transcode*` / `renditions` | `transcode_task` 按状态计数、`media_rendition` 产物数 |
|
||
| 成本 | `otpSent7d` | 近 7 天验证码发送条数(`app_user_otp`),作为短信成本近似 |
|
||
| 成本 | `cdnTrafficBytes` | **暂无数据源**,返回 `null` 并在 `notes` 说明 |
|
||
|
||
取不到数据源的指标一律返回 `null` 并在 `notes` 里写明缺什么,**不用 0 冒充**。
|
||
|
||
| 方法 | 路径 | 说明 |
|
||
| --- | --- | --- |
|
||
| GET | `/admin/comments/page` | 评论审核队列 |
|
||
| PUT | `/admin/comments/{id}/audit` | 通过/驳回(带原因码) |
|
||
| GET | `/admin/reports/page` | 举报工单 |
|
||
| PUT | `/admin/reports/{id}/handle` | 处理举报(可联动封禁) |
|
||
| GET/POST/PUT | `/admin/sensitive-words` | 敏感词库 |
|
||
| GET | `/admin/orders/page` | 订单检索(可按用户、状态、平台) |
|
||
| POST | `/admin/orders/{orderNo}/compensate` | 票据丢失的补发 |
|
||
| PUT | `/admin/entitlements/{id}/revoke` | 权益回收 |
|
||
| POST | `/admin/reconcile/run` | 手动触发对账 |
|
||
| GET | `/admin/creators/page` | 创作者审核队列 |
|
||
| PUT | `/admin/creators/{id}/audit` | 入驻审核 |
|
||
| GET | `/admin/submissions/page` | 内容提交审核 |
|
||
| PUT | `/admin/submissions/{id}/audit` | 内容审核(通过/驳回/驳回原因码) |
|
||
| PUT | `/admin/prices` | 分集价格与免费集配置 |
|
||
| GET | `/admin/dashboard/overview` | 经营大盘(用户/播放/收入/成本) |
|
||
| GET | `/admin/dashboard/transcode` | 转码队列与失败任务 |
|
||
|
||
### 2.9 后台前端页面(已实现)
|
||
|
||
`ReelShortWeb`(Vue3 + Element Plus,dev server `:3005`)的五个运营页面,统一沿用「api 封装 + 视图 + 样式」的写法;
|
||
表格列与下面这些接口的字段一一对应,**不在前端编字段**,时间列统一显示 `yyyy-MM-dd HH:mm:ss`。
|
||
|
||
| 页面 | 路由 | 菜单组件路径(`sys_menu.component`) | 依赖权限点 | 覆盖接口 |
|
||
| --- | --- | --- | --- | --- |
|
||
| 内容治理 | `/governance/content` | `views/governance/ContentGovernanceView` | `comment:list` `comment:audit` `report:list` `report:handle` `sensitive-word:list` `sensitive-word:update` | 评论检索与审核、举报工单处理、敏感词库增删改查 |
|
||
| 订单与权益 | `/commerce/orders` | `views/commerce/OrderManagementView` | `order:list` `order:update` `entitlement:list` `entitlement:update` `wallet:update` `reconcile:run` | 订单检索 / 流水 / 补发 / 退款、权益检索 / 人工补发 / 回收、金币流水 / 人工补币、对账运行与历史 |
|
||
| 创作者入驻 | `/creator/creators` | `views/creator/CreatorAuditView` | `creator:list` `creator:audit` | 创作者检索、资质查看、入驻审核(通过 / 驳回 / 冻结) |
|
||
| 内容审核 | `/creator/submissions` | `views/creator/SubmissionAuditView` | `submission:list` `submission:audit` | 内容提交检索、通过 / 驳回(带原因码) |
|
||
| 数据看板 | `/board/overview` | `views/dashboard/BusinessDashboardView` | `dashboard:view` | `overview` + `transcode`(纯只读) |
|
||
|
||
菜单、权限点与超管授权由 `sql/data-phase1.sql` 幂等落库(内容治理 / 订单与权益 / 数据看板挂菜单 id 20–25,创作者两条为 17–19)。
|
||
页面只读态与可操作态按权限点区分:没有 `*:update` / `*:audit` 的角色进入页面时按钮隐藏或显示「只读」。
|
||
|
||
### 2.10 创作者中心(批 1 ~ 批 3 已实现:工作台 / 内容编辑 / 上传挂载 / 收费配置)
|
||
|
||
创作者 Web 端做在后台管理里(`ReelShortWeb`),身份复用 `sys_admin_user`:
|
||
`creator.admin_user_id` 绑定后台账号(部分唯一索引,0 = 未绑定),角色 `creator` 只拿 `creator-center:*` 权限点。
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/creator-center/profile` | `creator-center:view` | 当前创作者主体与入驻状态 |
|
||
| GET | `/admin/creator-center/dramas/page` | `creator-center:view` | 我的作品(含最近一次提交的审核进度:类型 / 状态 / 驳回原因码 / 时间) |
|
||
| GET | `/admin/creator-center/dramas/{id}` | `creator-center:view` | 我的作品详情 |
|
||
| GET | `/admin/creator-center/notices` | `creator-center:view` | 我的通知:入驻审核结果 + 我提交内容的审核结果 |
|
||
|
||
**契约红线**:以上接口一律**不接收 `creatorId`**,归属由登录态(`sys_admin_user.id` → `creator.admin_user_id`)解析,
|
||
查询强制带 `where creator_id = 当前创作者`;访问他人作品统一返回 `{"code":403,"message":"无权访问该作品"}`,
|
||
未绑定创作者主体返回 `{"code":403,"message":"当前账号未绑定创作者主体,无法进入创作者中心"}`。
|
||
|
||
通知不新建表:第一阶段由 `creator`(入驻审核)与 `content_submission`(内容提交审核)派生;
|
||
系统公告 `ops_notice` 目前没有产出方,等有公告功能再接。
|
||
|
||
**内容编辑与提交(批 2)**
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| POST | `/admin/creator-center/dramas` | `creator-center:drama:edit` | 新建草稿(归属写自己,状态固定 `draft`) |
|
||
| PUT | `/admin/creator-center/dramas/{id}` | `creator-center:drama:edit` | 编辑作品信息(**未传的字段沿用现值**) |
|
||
| GET | `/admin/creator-center/dramas/{id}/episodes` | `creator-center:view` | 分集列表 |
|
||
| POST | `/admin/creator-center/dramas/{id}/episodes` | `creator-center:drama:edit` | 新增分集(不传集号则排到最大集号之后,默认免费) |
|
||
| PUT | `/admin/creator-center/dramas/{id}/episodes/{episodeId}` | `creator-center:drama:edit` | 编辑分集(时长 / 封面 / 片源 / 排序;未传字段沿用现值) |
|
||
| DELETE | `/admin/creator-center/dramas/{id}/episodes/{episodeId}` | `creator-center:drama:edit` | 删除分集 |
|
||
| PUT | `/admin/creator-center/dramas/{id}/episodes/sort` | `creator-center:drama:edit` | 批量排序(列表里出现不属于该剧的分集直接 403) |
|
||
| POST | `/admin/creator-center/dramas/{id}/submit` | `creator-center:drama:edit` | 提交审核,`type` = `CREATE` / `UPDATE` / `PUBLISH` / `OFFLINE` |
|
||
| POST | `/admin/creator-center/submissions/{id}/withdraw` | `creator-center:drama:edit` | 撤回自己的提交(撤回后作品退回草稿) |
|
||
| GET | `/admin/creator-center/dramas/{id}/submissions` | `creator-center:view` | 我的提交历史(审核进度) |
|
||
|
||
**可编辑状态闸**:只有 `draft`(草稿)与 `offline`(已下线)能直接改内容;`reviewing` 提示"提交正在审核中,请先撤回再改",
|
||
`approved` 不可编辑,`published` 提示"已上线的作品只读,请先提交「申请下线」"(错误码统一 `200003`)。
|
||
|
||
**提交矩阵**(状态 → 允许的提交类型):
|
||
|
||
| 作品状态 | 允许提交 | 提交后 |
|
||
| --- | --- | --- |
|
||
| `draft` | `CREATE`(仅首次)/ `UPDATE` / `PUBLISH` | 作品转 `reviewing` |
|
||
| `offline` | `UPDATE` / `PUBLISH` | 作品转 `reviewing` |
|
||
| `reviewing` | `PUBLISH`(内容审核通过后再申请上线) | 保持 `reviewing`,等后台上线审核 |
|
||
| `approved` | `PUBLISH` | 保持 `approved`,等后台上线审核 |
|
||
| `published` | `OFFLINE` | 保持 `published`,等后台下线审核 |
|
||
|
||
同一部剧**同时只能有一条在审提交**;提交后按其类型落到短剧状态机(审核动作仍在后台,创作者侧不新造状态)。
|
||
后台审核 `PUBLISH` 通过时,该剧仍处于 `draft` 的分集**一并上线**(否则会出现"剧上线了却一集都播不了");
|
||
后台**驳回**或创作者**撤回**时,处于 `reviewing` 的剧退回 `draft`,避免创作者卡在只读状态。
|
||
|
||
**上传挂载与收费配置(批 3)**
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| POST | `/admin/creator-center/dramas/{id}/episodes/{episodeId}/attach` | `creator-center:upload` | 把已上传的媒资挂到自己的分集(写 `video_asset_id` / `video_url`,时长为 0 时用产物时长补齐) |
|
||
| GET | `/admin/creator-center/dramas/{id}/prices` | `creator-center:view` | 读整剧免费集数 + 逐集免费 / 收费 / 试看秒数 |
|
||
| PUT | `/admin/creator-center/dramas/{id}/prices` | `creator-center:price:update` | 保存收费与试看秒数,复用后台同一套 `PriceService` |
|
||
|
||
**上传走已有的 `/admin/media/upload/{init,chunk,complete}`**(创作者角色直接持 `cover:upload` / `episode:upload`,
|
||
不新造一套上传接口);挂载时三道校验:分集属于自己这部剧 → 作品可编辑 → **产物是本次登录的人自己上传的**
|
||
(`media_asset.create_by` 必须等于当前账号,否则 `{"code":403,"message":"无权使用该上传产物"}`)。
|
||
只接受 `bizType=EPISODE` 且状态为 `ready` / `uploaded` 的产物。
|
||
|
||
**收费配置**:`previewSeconds` 落在 `drama_episode.preview_seconds`(0 = 不限制),
|
||
与 `is_free` / `unlock_coin` 一起就是播放与下载付费判定读的字段,**改完立即生效**(实测:未登录请求付费集返回
|
||
`{"accessType":"COIN_REQUIRED","unlockCoin":50,"previewSeconds":15}`;免费集直接返回签名播放地址)。
|
||
定价沿用「可编辑状态」口径:`draft` / `offline` 可改,已上线要改价需先申请下线(避免创作者悄悄改已上线内容的价格);
|
||
`dramaId` 以路径为准,body 里传别人的剧 id 无效,列表里带别人的 `episodeId` 会被忽略(只作用于自己剧的分集)。
|
||
|
||
**创作数据看板(批 4,只读)**
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/creator-center/dashboard` | `creator-center:stat:view` | 播放 / 完播 / 收藏 / 评论 / 解锁收入概览 |
|
||
|
||
**口径**(与代码注释一致,前端 tooltip 可直接复用;统计范围只含 `drama.creator_id = 当前创作者`)
|
||
|
||
| 分组 | 指标 | 口径 |
|
||
| --- | --- | --- |
|
||
| 作品 | `total` / `draft` / `reviewing` / `approved` / `published` / `offline` | 我的短剧按 `status` 计数(当前快照) |
|
||
| 作品 | `episodeTotal` / `episodeWithMedia` | 我的分集总数 / `video_url` 非空数 |
|
||
| 播放 | `viewTotal` / `playTotal` | 短剧表累计计数列求和(**累计口径,不限时间**) |
|
||
| 播放 | `watchedDramas` / `finishedDramas` / `finishRate` | `watch_progress` 是按「用户 × 剧」存的续看进度(唯一索引 `user_id + drama_id`),所以是**有多少人看过我的剧** / 其中最近一次标记完播的 / 完播率;**不是按集** |
|
||
| 播放 | `playEvents7d` / `playEventsTotal` | `watch_history` **流水口径**(近 7 天 / 全部),与累计口径不可相加 |
|
||
| 播放 | `finishEvents` | `watch_history` 中 `position_ms >= duration_ms` 的完播事件数(流水口径) |
|
||
| 互动 | `favoriteTotal` | `user_favorite` 指向我作品的行数 |
|
||
| 互动 | `commentTotal` / `commentPending` | `content_comment` 中属于我作品的评论数 / 其中待审数 |
|
||
| 收入 | `unlockCount` | `entitlement` 中 `source=ORDER` 且剧属于我的记录数(人工补发的 `ADMIN` 权益不计) |
|
||
| 收入 | `coinIncome` / `coinIncome7d` | `coin_ledger` 中 `biz_type=UNLOCK` 且 `biz_id` 命中我分集的扣币绝对值合计(全部 / 近 7 天) |
|
||
| 收入 | `paidOrderAmount` | **暂无数据源**,恒为 `null`:金币解锁不产生法币订单,真实金额要等 Apple/Google 商店接入 |
|
||
| 趋势 | `daily` | **暂无数据源**,恒为 `null`:`creator_stat_daily` 表已建但无产出任务 |
|
||
|
||
取不到的一律 `null` 并在 `notes` 说明缺什么、怎么补,**不用 0 冒充**(与运营大盘同口径)。
|
||
|
||
**创作者中心前端页面(批 5 已实现)**
|
||
|
||
`ReelShortWeb` 里新增四个页面(菜单 id 26–30,`sql/data-phase1.sql` 幂等落库),沿用 `AppUsersView` 的
|
||
「api 封装 + composable + 视图 + 样式」写法与 `console.css`:
|
||
|
||
| 页面 | 路由 | 菜单组件路径 | 依赖权限点 | 覆盖接口 |
|
||
| --- | --- | --- | --- | --- |
|
||
| 我的作品 | `/creator-center/workspace` | `views/creator-center/WorkspaceView` | `creator-center:view` `creator-center:drama:edit` | 主体信息、作品列表(含审核进度)、通知、新建草稿、提交 / 撤回 |
|
||
| 作品编辑 | `/creator-center/dramas/:id` | `views/creator-center/DramaEditView` | `creator-center:drama:edit` `creator-center:upload` | 作品信息、分集增删改与排序、分片上传(含断点续传)、产物挂载、提交记录 |
|
||
| 收费配置 | `/creator-center/prices` | `views/creator-center/PriceConfigView` | `creator-center:price:update` | 免费集数、解锁金币、试看秒数 |
|
||
| 数据看板 | `/creator-center/dashboard` | `views/creator-center/DashboardView` | `creator-center:stat:view` | 看板概览(只读,缺口显示「暂无数据源」) |
|
||
|
||
**创作者角色只挂这五条菜单**(含一条 `visible=0` 的隐藏路由):登录后侧边栏只有「创作者中心」,
|
||
看不到运营后台的任何菜单 —— 实测创作者菜单 JSON 里只有 `/creator-center` 及其子项,超管才拿得到全部。
|
||
「作品编辑」是详情页,用 `visible=0` 下发(后端把它翻译成 `meta.hidden`),路由照常注册、侧边栏不显示。
|
||
|
||
**本阶段进度**:07 全部 5 批完成,第一阶段 05 / 06 / 07 / 08 四块闭环。
|
||
|
||
**超管代看(只读)**
|
||
|
||
后台账号如果没绑定创作者主体,又点进了创作者中心,接口不再直接 403 白屏,而是三级解析:
|
||
|
||
| 情况 | 结果 |
|
||
| --- | --- |
|
||
| 账号绑定了 `creator.admin_user_id` | 用自己的身份(**创作者角色永远走这条**,代看逻辑不影响他) |
|
||
| 未绑定 + 有 `creator-center:impersonate` + 请求带 `X-Creator-Id` | 只读代看该创作者 |
|
||
| 其余 | `200004`(未绑定)/ `200005`(有代看权限但没选目标)—— 前端据此渲染引导页 |
|
||
|
||
**红线**:
|
||
- 目标创作者走**独立请求头 `X-Creator-Id`**,不做查询参数 —— creator-center 接口依旧不接收 `creatorId`;
|
||
- 这个头**只有**持有 `creator-center:impersonate` 的账号才生效,创作者自己带上没有任何作用(实测:带头上限仍只看到自己的数据,仍能正常编辑自己的作品);
|
||
- **代看只读**:作品编辑、分集增删改与排序、上传会话(`/admin/media/upload/*` 的 init/chunk/complete)与产物挂载、
|
||
提交 / 撤回、收费配置**全部拒绝**,错误码 `200006`;
|
||
- 代看进入写 `audit_log`(`biz_type=CREATOR`、`action=IMPERSONATE_VIEW`、操作人、IP、目标创作者),
|
||
同一操作人对同一目标 10 分钟内去重,避免翻页把审计表刷爆。
|
||
|
||
| 方法 | 路径 | 权限点 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| GET | `/admin/creator-center/impersonation/targets` | `creator-center:impersonate` | 代看目标下拉的数据源(id / 名称 / 状态) |
|
||
|
||
## 3. 契约与实现状态对照
|
||
|
||
| 模块 | 表结构 | 接口 | 代码 |
|
||
| --- | --- | --- | --- |
|
||
| 01 基础与交付准备 | 已就绪 | 约定已冻结 | 脚手架 / 契约 / 签名 / 转码骨架 已实现 |
|
||
| 02 用户账号与登录 | 已建 | 已冻结 | **已实现**(手机号/邮箱,第三方登录走同一凭证表) |
|
||
| 03 内容发现与详情 | 已建 | 已冻结 | 已实现(补了分级、区域、版权、标签字段) |
|
||
| 04 播放器与播放控制 | 已建 | 已冻结 | 票据 + 签名 + 进度 已实现;多码率依赖转码 worker |
|
||
| 05 记录、收藏与下载 | 已建 | 已冻结 | **已实现**:进度、观看流水、收藏、离线下载授权与任务 |
|
||
| 06 评论、点赞与分享 | 已建 | 已冻结 | **已实现**:评论(游标翻页/审核/删除)、点赞、举报、敏感词;分享埋点在下一批 |
|
||
| 07 创作者中心 | 已建 | 已冻结 | **已实现**:创作者工作台(我的作品 / 审核进度 / 通知)、内容编辑与分集管理、分片上传与断点续传、提交审核与上下架、分集收费与试看、数据看板;Web 端页面见 2.10,不含提现 / 结算 |
|
||
| 08 平台运营后台 | 已建 | 已冻结 | **已实现**:后台接口(用户管理、内容治理、订单与权益、创作者与内容审核、数据看板)与后台页面(内容治理 / 订单与权益 / 创作者审核 / 数据看板,见 2.9)全部落地 |
|
||
| 09 分集收费与支付 | 已建 | 已冻结 | 下一批(权益判定端口已预留,接上即生效) |
|
||
| 10 质量、数据与上线 | 已建 | 已冻结 | 压测与埋点 下一批 |
|