feat(web): 富文本编辑器换成 Vditor,不再自研轮子
CI / backend (push) Canceled after 0s

上一版我自己写了 textarea + 正则工具栏,看着能用,一到粘贴图片、
中文输入法、撤销栈就露馅——这几样正是成熟组件积累的部分。按要求改成品。

- 编辑器开关 def: RichTextEditor = Vditor 4.0.1(MIT,ir 模式)
  * 运行时资源自托管:web/scripts/vendor-vditor.mjs 把 lute/i18n/icons
    同步到 public/vditor,predev/prebuild 自动执行,不走 unpkg CDN
    (内网会一直卡在加载)
- 只读渲染换 markdown-it + dompurify,删掉自写的正则渲染器
- 附件直链的令牌只在内存里存在:落库前 stripAttachmentTokens,
  渲染/装载前补回(<img> 带不了 Authorization 头,raw?token= 是必要折中)
- Vditor 不会替我们插入 upload.handler 的返回值(只当提示语 tip.show),
  所以上传完自己 insertMD

验证:pytest 70 passed;e2e richtext 13 项、smoke 7、tickets 8、
knowledge 7 全绿;tsc 0 错;主包 299 kB/gzip 75 kB,Vditor 独立
chunk 385 kB 按需加载。
This commit is contained in:
dadao
2026-10-29 02:30:10 +08:00
parent 7a7ea932a4
commit fbdf54cb4c
18 changed files with 630 additions and 419 deletions
+4 -6
View File
@@ -1,5 +1,5 @@
/**
* 截图:详情抽屉里的 Markdown 编辑器(写作态 + 预览态)。
* 截图:详情抽屉里的富文本编辑器(Vditor,边写边看)。
* 只用于留存界面现状,不做断言。
*/
import { chromium } from "playwright-core";
@@ -91,13 +91,11 @@ await page.getByRole("button", { name: "全部", exact: true }).click();
await page.getByRole("button", { name: "把十月报销单寄给财务", exact: true }).click();
const drawer = page.getByRole("dialog");
await drawer.waitFor();
await page.waitForTimeout(600);
// Vditor 是"边写边看",没有单独的预览态:等它把 lute 与正文渲染出来再截图
await page.waitForSelector(".vditor-ir strong", { timeout: 20000 });
await page.waitForTimeout(1200);
await page.screenshot({ path: "../2.Design/screens/web-editor-write.png" });
await drawer.getByRole("button", { name: "预览" }).click();
await page.waitForTimeout(900);
await page.screenshot({ path: "../2.Design/screens/web-editor-preview.png" });
await context.close();
await browser.close();
console.log("shots saved");