From 491d36b7a8019bc9f4e3bbce8b8dbde6e2932d8a Mon Sep 17 00:00:00 2001 From: dap <15891557205@163.com> Date: Fri, 1 Aug 2025 11:53:28 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20Tinymce=20=E4=BF=9D=E5=AD=98=E5=9B=BE?= =?UTF-8?q?=E7=89=87id=20=E6=8F=90=E4=BE=9B`contentWithOssIdTransform`?= =?UTF-8?q?=E6=9D=A5=E6=98=BE=E7=A4=BA=E7=A7=81=E6=9C=89=E6=A1=B6=E5=9B=BE?= =?UTF-8?q?=E7=89=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 1 + .../src/components/tinymce/src/editor.vue | 11 ++++- .../src/components/tinymce/src/helper.ts | 42 +++++++++++++++++++ 3 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 apps/web-antd/src/components/tinymce/src/helper.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 28dedc14..df03caca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,7 @@ - useVbenForm 增加 TimeRangePicker(时间区间选择) 组件 - 字典(DictTag)支持fallback属性(未匹配到字典项时的回显) - 微服务版本 logout接口在配置错误的情况返回401的提示(解决死循环调用logout接口) +- Tinymce 保存图片id 提供`contentWithOssIdTransform`来显示私有桶图片 **REFACTOR** diff --git a/apps/web-antd/src/components/tinymce/src/editor.vue b/apps/web-antd/src/components/tinymce/src/editor.vue index 2294ce70..0ad2ffc7 100644 --- a/apps/web-antd/src/components/tinymce/src/editor.vue +++ b/apps/web-antd/src/components/tinymce/src/editor.vue @@ -147,9 +147,18 @@ const initOptions = computed((): InitOptions => { }; uploadApi(file, { onUploadProgress: progressEvent }) .then((response) => { - const { url } = response as unknown as UploadResult; + const { url, ossId } = response as unknown as UploadResult; console.log('tinymce上传图片:', url); resolve(url); + // 放在宏队列才能获取 + setTimeout(() => { + const imgDom = editorRef.value?.dom.select(`img[src="${url}"]`); + if (imgDom) { + editorRef.value?.dom.setAttrib(imgDom, 'data-oss-id', ossId); + } else { + console.warn('无法获取图片dom, 存储数据可能会出现问题'); + } + }); }) .catch((error) => { console.error('tinymce上传图片失败:', error); diff --git a/apps/web-antd/src/components/tinymce/src/helper.ts b/apps/web-antd/src/components/tinymce/src/helper.ts new file mode 100644 index 00000000..a7329f71 --- /dev/null +++ b/apps/web-antd/src/components/tinymce/src/helper.ts @@ -0,0 +1,42 @@ +import { ossInfo } from '#/api/system/oss'; + +/** + * 富文本内容中图片ossId转换 确保每次链接都是最新获取的(对于私有桶情况) + * + * 当然你可以使用后端来解析dom替换 达到相同的效果 就不用前端调用了 + * 使用方法: 在赋值前调用此方法 contentWithOssIdTransform(content); 转换一次再赋值 + * @param content 富文本内容 + * @returns string + */ +export async function contentWithOssIdTransform(content: string) { + if (!content) { + return null; + } + const parser = new DOMParser(); + const doc = parser.parseFromString(content, 'text/html'); + const imgDom = doc.querySelectorAll('img[data-oss-id]'); + + // 没有包含图片 不做处理 + if (imgDom.length === 0) { + return content; + } + + // 提取所有data-oss-id属性 作为string[] + const ossIds = [...imgDom].map( + (img) => (img as HTMLImageElement).dataset.ossId ?? '', + ); + const ossFileList = await ossInfo(ossIds); + + imgDom.forEach((item) => { + const img = item as HTMLImageElement; + // 找到对应的 替换 + const src = + ossFileList.find((file) => file.ossId === img.dataset.ossId)?.url ?? + // 未找到 取原先自己的src + img.src; + img.setAttribute('src', src); + }); + + // 获取dom string + return doc.body.innerHTML; +}