You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
5.7 KiB
5.7 KiB
媒体库与「媒体」入口设计
背景与目标
控制台已有 /me/media/orphans(图片孤儿审查与删除)与 POST /api/file/upload(图片入库到 media_assets),但缺少面向作者的 资源库:集中上传、浏览自己名下的媒体,并 复制公开 URL / Markdown 图片语法,以便在文章等编辑器中手动粘贴使用。
本设计首版强调 与编辑器解耦:不修改 Markdown 编辑器行为;后续可在编辑器内增加「从媒体库选用」等深度集成。
需求结论(已确认)
- 核心价值:以 上传 + 选用(复制) 为主,列表浏览为辅。
- 首版范围:媒体库页面 + 复制公开 URL + 复制
,不在文章/资料编辑器内做集成。 - 复制形态:同时提供 「复制图片 URL」 与 「复制 Markdown 图片」 两种操作(两个按钮或等价 UI)。
- URL 策略:在浏览器端使用
window.location.origin + '/public/assets/<storageKey>'生成 绝对 URL,两种复制均使用该地址,避免相对路径在外部编辑器中失效。 - 导航:单一「媒体」入口,下挂 资源库 与 孤儿清理 两个子能力。
- 首版不做:媒体库内对仍被引用的资源的一键删除(避免与
media_refs/ 正文同步规则冲突);孤儿删除与宽限逻辑 继续仅在「孤儿清理」子页 完成。
信息架构与路由
采用 Nuxt 父布局 + 子页面(推荐方案,已采纳):
| 路径 | 说明 |
|---|---|
/me/media |
默认落地:资源库(media/index.vue) |
/me/media/orphans |
图片孤儿审查(沿用现有逻辑与 API,页面作为子路由) |
新增父级壳页面(例如 app/pages/me/media.vue):
- 顶区标题:媒体
- 子导航:资源库 ↔ 孤儿清理(与当前子路由联动高亮)
- 内容区:
<NuxtPage />
文件布局约定:
app/pages/me/media.vue— 壳(导航 + 插槽)app/pages/me/media/index.vue— 资源库app/pages/me/media/orphans.vue— 孤儿页(由现有页面迁入嵌套结构;业务与接口尽量不变)
媒体库页(功能)
列表
- 数据源:当前登录用户的
media_assets(userId严格等于会话用户)。 - 排序:默认
createdAt降序。 - 分页:与孤儿页类似,提供 10 / 20 / 50 每页可选。
- 展示:缩略图网格;每张卡片展示 文件大小、上传时间。
- 引用数:对每条资产聚合
media_refs行数 作为refCount展示,便于区分「已出现在文章/封面/资料等」与「仅上传未写入内容」。不展示可编辑的「引用详情」全文(首版保持简单)。
上传
- 调用现有
POST /api/file/upload(multipart,与资料页一致:格式、大小上限、多文件上限等沿用服务端实现)。 - 上传成功后 刷新列表,并用 toast 提示成功;失败展示服务端错误信息。
复制
- 复制图片 URL:将绝对 URL 写入剪贴板。
- 复制 Markdown 图片:写入
。 - 复制成功 / 失败:toast 反馈。若剪贴板 API 不可用,首版以 toast 说明即可;可选增强:弹窗展示可手动复制的文本(实现阶段再决定是否纳入首版计划)。
明确不包含(首版)
- 媒体库内 删除 仍被引用或非孤儿宽限内的资源。
- 文章/资料编辑器内嵌媒体选择器、自动插入光标等。
服务端 API
GET /api/me/media/assets
- 鉴权:必须登录;仅返回 当前用户 的
media_assets。 - Query:
page(从 1 起)、pageSize(允许值与前端分页选项对齐,服务端需校验上限)。 - 响应(示意):
{ items: [...], total: number }
每项至少包含:id、storageKey(或等价字段)、sizeBytes、createdAt(ISO 或统一项目惯例)、mime、refCount;公开路径可与前端约定为固定前缀/public/assets/+storageKey,或由服务端返回publicPath以避免重复逻辑。 - 安全:禁止按参数指定其他
userId;不得泄露其他用户资源。
列表查询实现可放在 server/service/media 或并列模块,保持 handler 轻薄。
全局导航与控制台首页
AppShell 控制台子导航
- 在现有「资料 / 文章 / 时光机 / RSS」基础上增加 「媒体」→
/me/media。 - 更新相关注释(原「桌面端下拉内仅四个子链接」等)以反映 五个 子项。
/me 控制台首页
- 将原 「文章媒体清理」 卡片 合并 为单一 「媒体」 入口:文案说明内含 资源库 与 孤儿清理,主按钮指向
/me/media。 - 不在首页重复放置两个独立卡片指向同一能力域(除非产品明确要求「孤儿」快捷直达,本 spec 不采用)。
错误处理与空状态
- 列表加载失败:toast + 可重试(按钮或自动提示)。
- 空列表:说明可上传图片,并提供上传入口。
- 上传失败:toast,错误信息来自服务端。
测试建议
GET /api/me/media/assets:未登录返回 401;分页边界;用户隔离(仅本人数据);pageSize非法值处理。- 若有可单测的纯函数(例如 Markdown 拼接),可补充 单元测试;UI 以手测为主。
后续扩展(非本 spec 交付范围)
- 文章 Markdown 编辑器内:打开媒体库、插入链接或 Markdown。
- 资料页头像/头图:从媒体库选用(仍可与裁剪流程组合)。
- 媒体库内 删除:需与
syncPostMediaRefs/syncProfileMediaRefs及孤儿规则统一产品设计后再做。