Files
FruitServer/docs/api-phase1.md
T

37 KiB
Raw Blame History

第一阶段接口清单(后台管理 + 客户端)

版本 v1.0 · 配套 PRD 与 后端设计 状态说明:已实现 = 代码已落地可联调;下一批 = 表结构与契约已冻结,代码待补。

0. 通用约定

服务入口:后台管理 fruitshorts-admin-api 只暴露 /admin/**(8080); 客户端 fruitshorts-app-api 只暴露 /app/** 与媒资 /files/**(8081)。

统一响应体

{ "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 吊销全部会话

发送验证码:

POST /app/auth/otp
{ "scene": "REGISTER", "targetType": "PHONE", "target": "08123456789", "deviceId": "d-1" }

手机号会自动规范化成 E.164(印尼本地 08xx → +62xxx)。频控:同号 60 秒一次、每日 10 次, 同 IP 每小时 20 次;连续输错 5 次该验证码作废。

注册:

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
}

响应(登录、刷新同结构):

{
  "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 可选 签发播放票据与签名地址
{
  "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 质量、数据与上线 已建 已冻结 压测与埋点 下一批