优化富文本编辑器,粘贴其他网站时,通过上传服务器将图片转为base64格式

This commit is contained in:
jacky 2024-05-16 19:28:18 +08:00
parent 53c8857e9d
commit 9c40455709
3 changed files with 66 additions and 19 deletions

View File

@ -146,3 +146,15 @@ export const setArticleCategories = (data) => {
data data
}) })
} }
// @Summary 更新文章分类
// @Produce application/json
// @Param menu Object
// @Router /cms/article/setChannels [put]
export const getImgData = (params) => {
return service({
url: '/cms/article/getImgData',
method: 'get',
params
})
}

View File

@ -1,5 +1,5 @@
<template> <template>
<div class="border border-solid border-gray-100 h-full"> <div class="border border-solid border-gray-100 h-full" v-loading="loadingShow">
<Toolbar :editor="editorRef" :default-config="toolbarConfig" mode="default" /> <Toolbar :editor="editorRef" :default-config="toolbarConfig" mode="default" />
<Editor v-model="valueHtml" class="overflow-y-hidden mt-0.5" :style="style" :default-config="editorConfig" <Editor v-model="valueHtml" class="overflow-y-hidden mt-0.5" :style="style" :default-config="editorConfig"
mode="default" @onCreated="handleCreated" @onChange="change" @customPaste="customPaste" /> mode="default" @onCreated="handleCreated" @onChange="change" @customPaste="customPaste" />
@ -16,7 +16,9 @@ import { onBeforeUnmount, ref, shallowRef, watch } from 'vue'
import { Editor, Toolbar } from '@wangeditor/editor-for-vue' import { Editor, Toolbar } from '@wangeditor/editor-for-vue'
import { ElMessage } from 'element-plus' import { ElMessage } from 'element-plus'
import { getUrl } from '@/utils/image' import { getUrl } from '@/utils/image'
import { getImgData } from '@/api/article'
const loadingShow = ref(false)
const emits = defineEmits(['change', 'update:modelValue']) const emits = defineEmits(['change', 'update:modelValue'])
const change = (editor) => { const change = (editor) => {
emits('change', editor) emits('change', editor)
@ -74,40 +76,73 @@ const handleCreated = (editor) => {
} }
const customPaste = (editor, event, callback) => { const customPaste = (editor, event, callback) => {
//
loadingShow.value = true
let htmlData = event.clipboardData.getData('text/html') // html let htmlData = event.clipboardData.getData('text/html') // html
// console.log(htmlData) // console.log(htmlData)
let rtfData = event.clipboardData.getData('text/rtf') // html let rtfData = event.clipboardData.getData('text/rtf') // html
// console.log('-------------- rtfData --------------', rtfData) // console.log('-------------- rtfData --------------', rtfData)
htmlData = htmlData.replace(/<\/?span[^>]*>/g, ''); htmlData = htmlData.replace(/<\/?span[^>]*>/g, '');
htmlData = htmlData.replace(/<\/?font[^>]*>/g, '');
// htmlData = htmlData.replace(/<p[^>]*(?:>|\s[^>]*>)/gi, '<p>');
htmlData = htmlData.replace(/<img/g, '<img referrerpolicy="no-referrer"') htmlData = htmlData.replace(/<img/g, '<img referrerpolicy="no-referrer"')
// console.log('111111111111 replace after 1111111111', htmlData) // console.log('111111111111 replace after 1111111111', htmlData)
// htmlimgsrc
const imgSrcs = htmlData.match(/<img [^>]*src=['"]([^'"]+)[^>]*>/g);
// console.log('imgSrcs', imgSrcs)
if (rtfData !== "") { if (rtfData !== "") {
// word // word
// htmlimgsrc
const imgSrcs = htmlData.match(/<img [^>]*src=['"]([^'"]+)[^>]*>/g);
//
if (imgSrcs && Array.isArray(imgSrcs) && imgSrcs.length) { if (imgSrcs && Array.isArray(imgSrcs) && imgSrcs.length) {
// console.log('imgSrcs', imgSrcs)
// rtf // rtf
const rtfImageData = extractImageDataFromRtf(rtfData); const rtfImageData = extractImageDataFromRtf(rtfData);
// console.log('rtfImageData', rtfImageData)
// //
if (rtfImageData.length) { if (rtfImageData.length) {
// TODO,
// htmlimgsrcref // htmlimgsrcref
htmlData = replaceImageFile(htmlData, imgSrcs, rtfImageData) htmlData = replaceImageFile(htmlData, imgSrcs, rtfImageData)
// console.log('22222222222222222 replace after 22222222222222222', htmlData) // console.log('22222222222222222 ----------- 22222222222222222', htmlData)
editor.dangerouslyInsertHtml(htmlData);
loadingShow.value = false
callback(false)
} }
} }
} else {
if (imgSrcs && Array.isArray(imgSrcs) && imgSrcs.length) {
convertImgToBase64(imgSrcs).then(imgList => {
imgList.forEach(item => {
htmlData = htmlData.replace(item.src, item.tar)
})
// console.log('33333333333333333 ----------- 33333333333333333', htmlData)
editor.dangerouslyInsertHtml(htmlData);
//
loadingShow.value = false
callback(false)
})
} else {
loadingShow.value = false
callback(false)
}
}
event.preventDefault()
}
const convertImgToBase64 = async (data) => {
let replaces = []
for (let i = 0; i < data.length; i++) {
const imgSrc = data[i].match(/src=['"]([^'"]+)['"]/)
if (!imgSrc) {
return
}
// base64
const res = await getImgData({ url: imgSrc[1] })
if (res && res.data) {
replaces.push({ src: data[i], tar: `<img src='${res.data.imgData}' />` })
}
} }
editor.dangerouslyInsertHtml(htmlData); return replaces
event.preventDefault()
callback(false)
} }
/** /**
@ -125,16 +160,16 @@ const extractImageDataFromRtf = (rtfData) => {
const result = ref([]) const result = ref([])
if (images) { if (images) {
for (const image of images) { for (const image of images) {
const imageType = ref(false) let imageType = ''
if (image.includes('\\pngblip')) { if (image.includes('\\pngblip')) {
imageType.value = 'image/png' imageType = 'image/png'
} else if (image.includes('\\jpegblip')) { } else if (image.includes('\\jpegblip')) {
imageType.value = 'image/jpeg' imageType = 'image/jpeg'
} }
if (imageType.value) { if (imageType) {
result.value.push({ result.value.push({
hex: image.replace(regexPictureHeader, '').replace(/[^\da-fA-F]/g, ''), hex: image.replace(regexPictureHeader, '').replace(/[^\da-fA-F]/g, ''),
type: imageType.value type: imageType
}); });
} }
} }

View File

@ -439,7 +439,7 @@ watch(() => tableData.value, () => {
}) })
// ----- ----- // ----- -----
const getTableData = async valid => { const getTableData = async () => {
const res = await getArticleList({ page: page.value, pageSize: pageSize.value, ...searchInfo.value }) const res = await getArticleList({ page: page.value, pageSize: pageSize.value, ...searchInfo.value })
if (res.code === 0) { if (res.code === 0) {
tableData.value = res.data.list tableData.value = res.data.list