1 changed files with 75 additions and 0 deletions
@ -0,0 +1,75 @@ |
|||||
|
# 设计:文章编辑页美化与 Markdown 分屏编辑(含图片上传) |
||||
|
|
||||
|
**日期**:2026-04-18 |
||||
|
**状态**:已定稿(与产品对话一致) |
||||
|
|
||||
|
## 1. 背景与目标 |
||||
|
|
||||
|
「编辑文章」「新建文章」页当前为 **Nuxt UI 表单 + `UTextarea`**,正文无工具栏、无预览、无上传辅助。目标: |
||||
|
|
||||
|
1. **美化**:更清晰的层级、间距与容器(与 **Nuxt UI 4** / Tailwind 一致),避免「裸表单」观感。 |
||||
|
2. **正文**:**Markdown 编辑器**,**分屏**(左编辑、右预览,**比例可调**),并支持 **图片上传** 与在文中插入 ``。 |
||||
|
3. **上传**:本期 **仅图片**;**单文件上限 10MB**;多图插入体验优于仅单次选择一张(具体交互由实现计划结合所选组件能力定稿)。 |
||||
|
|
||||
|
## 2. 产品规则(已确认) |
||||
|
|
||||
|
| 维度 | 规则 | |
||||
|
|------|------| |
||||
|
| 整页布局 | **C — 写作优先**:首屏以正文工作区为主;**标题、slug、摘要、可见性** 等收入 **可折叠「文章设置」**(分享提示仍放在设置区或紧贴设置区,与现逻辑一致)。 | |
||||
|
| 预览形态 | **B — 分屏**:左侧 Markdown 编辑,右侧渲染预览;**比例可调**(组件内置或薄封装分隔条)。 | |
||||
|
| 上传类型 | **仅图片**;MIME 与现网一致:**PNG / JPEG / WebP**(不设 SVG 等本期扩展)。 | |
||||
|
| 单图大小 | **10MB**(服务端 `multer` 与接口契约与现 **5MB** 对齐上调)。 | |
||||
|
| 插入格式 | 上传成功后,在 **光标处**(或组件约定的插入点)插入 **``**;多文件 **按顺序** 插入多条图片语法。 | |
||||
|
| 接口 | 复用 **`POST /api/file/upload`**;请求体与 `app/pages/me/profile/index.vue` 一致(`FormData` 字段 **`file`**,可多文件时与现有多文件约定一致)。 | |
||||
|
|
||||
|
## 3. 非目标(本期) |
||||
|
|
||||
|
- **非图片附件**(PDF、ZIP 等)及单独「附件列表」管理。 |
||||
|
- 外链图床配置、图片压缩服务端流水线。 |
||||
|
- **公开文章详情页**、未列出分享页将 `bodyMarkdown` 从当前展示方式改为 **完整 Markdown 渲染**(与本次需求独立;若后续单独立项再开 spec)。 |
||||
|
- 剪贴板粘贴上传:若所选编辑器 **原生支持**,可在实现计划中列为增强;**不作为本期验收硬条件**。 |
||||
|
|
||||
|
## 4. 技术取向(已拍板) |
||||
|
|
||||
|
**首选方案**:集成 **成熟 Vue 3 Markdown 编辑组件**(实现计划中 **锁定 npm 包与版本**),须同时满足: |
||||
|
|
||||
|
- 分屏编辑/预览或可等价配置为分屏; |
||||
|
- **自定义上传回调**,可调用站内 `/api/file/upload` 并拿到 `url`; |
||||
|
- 在 **Nuxt 4** 中可用 **`ClientOnly`(或等价)** 包裹,避免 SSR 与编辑器 DOM 不兼容。 |
||||
|
|
||||
|
**不推荐本期采用**:自研 CodeMirror 6 + 全量工具栏(工期过长);或仅 `textarea` + 极简按钮(与「多图顺手插入」目标不符)。 |
||||
|
|
||||
|
## 5. 页面与组件边界 |
||||
|
|
||||
|
| 单元 | 职责 | |
||||
|
|------|------| |
||||
|
| `app/pages/me/posts/[id].vue` | 编辑页:加载/保存/删除、折叠「文章设置」、挂载 Markdown 编辑器、绑定 `bodyMarkdown`。 | |
||||
|
| `app/pages/me/posts/new.vue` | 新建页:**与编辑页同一套** 正文编辑与布局模式(避免两套体验);创建后仍跳转编辑或列表,行为保持现有 API。 | |
||||
|
| 编辑器封装(建议新建组件,路径实现计划定) | props:`modelValue`(Markdown 字符串);emit:`update:modelValue`;内部:分屏、上传、主题与 Nuxt UI 协调。 | |
||||
|
|
||||
|
## 6. 后端与契约 |
||||
|
|
||||
|
**文件**:`server/api/file/upload.post.ts` |
||||
|
|
||||
|
- **`limits.fileSize`**:改为 **10 * 1024 * 1024**(10MB)。 |
||||
|
- **`fileFilter`**:**不变**(仍为 PNG / JPG / WebP)。 |
||||
|
- 响应格式 **不变**:`R.success({ files: [{ name, url, path, mimeType, size }, ...] })`,`url` 仍为 **`/public/assets/...`** 形式,与静态资源一致。 |
||||
|
|
||||
|
**文章 CRUD**:`bodyMarkdown` 仍为纯文本存储;**无需**迁移或新表。 |
||||
|
|
||||
|
## 7. 错误处理与 UX |
||||
|
|
||||
|
- 上传失败(类型不符、超大、网络错误):使用 **Nuxt UI 的 Toast 或 Alert** 提示,**不**静默失败。 |
||||
|
- 保存/加载失败:沿用现有 `request` 错误表现;不在本 spec 扩大重试策略。 |
||||
|
- 分屏在窄屏:实现计划需约定 **响应式**(例如小屏改为上下栈叠或默认隐藏预览),避免横向溢出。 |
||||
|
|
||||
|
## 8. 测试与验收(手动) |
||||
|
|
||||
|
- 编辑页:折叠/展开「文章设置」;分屏比例调整;保存后刷新内容一致。 |
||||
|
- 新建页:与编辑页正文体验一致;创建成功流程不变。 |
||||
|
- 上传:单图、多图;**略小于 10MB** 成功;**超过 10MB** 被拒绝并有提示;错误 MIME 拒绝。 |
||||
|
- 认证:未登录不应误用上传(与现站策略一致;若上传需登录,与 profile 行为对齐)。 |
||||
|
|
||||
|
## 9. 与前期 Visual Companion 结论的对应 |
||||
|
|
||||
|
- 布局 **C**、预览 **B**、上传范围 **C**、单图 **10MB(选项 A)** 均已纳入上文表格与第 6 节。 |
||||
Loading…
Reference in new issue