From 384c4a7e38ef9199d5b05ec4920ebf282268f17a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A0=82=E7=B3=96?= Date: Thu, 31 Jul 2025 16:27:16 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E5=AF=8C=E6=96=87=E6=9C=AC?= =?UTF-8?q?=E7=BC=96=E8=BE=91=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/Quill/Quill.vue | 132 +++- pages/workbench/project/add.vue | 5 - pages/workbench/reportWork/reportWork.vue | 9 +- uni_modules/sv-editor/changelog.md | 35 + .../components/backup/sv-editor-plugin.vue | 656 ++++++++++++++++++ .../components/backup/sv-editor-wxplugin.js | 94 +++ .../sv-editor/components/common/config.js | 15 + .../components/common/file-handler.js | 261 +++++++ .../sv-editor/components/common/parse.js | 179 +++++ .../sv-editor/components/common/store.js | 101 +++ .../sv-editor/components/common/tool-list.js | 208 ++++++ .../sv-editor/components/common/utils.js | 412 +++++++++++ .../sv-editor/components/icons/iconfont.css | 233 +++++++ .../sv-editor/components/icons/iconfont.ttf | Bin 0 -> 12016 bytes .../components/plugins/sv-editor-plugin.vue | 52 ++ .../components/plugins/sv-editor-wxplugin.js | 10 + .../components/sv-editor/sv-choose-file.vue | 122 ++++ .../sv-editor/sv-editor-colorpicker.vue | 178 +++++ .../sv-editor/sv-editor-popup-more.vue | 445 ++++++++++++ .../components/sv-editor/sv-editor-render.vue | 150 ++++ .../sv-editor/sv-editor-toolbar.vue | 647 +++++++++++++++++ .../components/sv-editor/sv-editor.vue | 445 ++++++++++++ uni_modules/sv-editor/package.json | 87 +++ uni_modules/sv-editor/readme.md | 333 +++++++++ 24 files changed, 4772 insertions(+), 37 deletions(-) create mode 100644 uni_modules/sv-editor/changelog.md create mode 100644 uni_modules/sv-editor/components/backup/sv-editor-plugin.vue create mode 100644 uni_modules/sv-editor/components/backup/sv-editor-wxplugin.js create mode 100644 uni_modules/sv-editor/components/common/config.js create mode 100644 uni_modules/sv-editor/components/common/file-handler.js create mode 100644 uni_modules/sv-editor/components/common/parse.js create mode 100644 uni_modules/sv-editor/components/common/store.js create mode 100644 uni_modules/sv-editor/components/common/tool-list.js create mode 100644 uni_modules/sv-editor/components/common/utils.js create mode 100644 uni_modules/sv-editor/components/icons/iconfont.css create mode 100644 uni_modules/sv-editor/components/icons/iconfont.ttf create mode 100644 uni_modules/sv-editor/components/plugins/sv-editor-plugin.vue create mode 100644 uni_modules/sv-editor/components/plugins/sv-editor-wxplugin.js create mode 100644 uni_modules/sv-editor/components/sv-editor/sv-choose-file.vue create mode 100644 uni_modules/sv-editor/components/sv-editor/sv-editor-colorpicker.vue create mode 100644 uni_modules/sv-editor/components/sv-editor/sv-editor-popup-more.vue create mode 100644 uni_modules/sv-editor/components/sv-editor/sv-editor-render.vue create mode 100644 uni_modules/sv-editor/components/sv-editor/sv-editor-toolbar.vue create mode 100644 uni_modules/sv-editor/components/sv-editor/sv-editor.vue create mode 100644 uni_modules/sv-editor/package.json create mode 100644 uni_modules/sv-editor/readme.md diff --git a/components/Quill/Quill.vue b/components/Quill/Quill.vue index 4dbeded..22dc366 100644 --- a/components/Quill/Quill.vue +++ b/components/Quill/Quill.vue @@ -1,29 +1,72 @@ + + diff --git a/uni_modules/sv-editor/components/backup/sv-editor-wxplugin.js b/uni_modules/sv-editor/components/backup/sv-editor-wxplugin.js new file mode 100644 index 0000000..a811cb9 --- /dev/null +++ b/uni_modules/sv-editor/components/backup/sv-editor-wxplugin.js @@ -0,0 +1,94 @@ +/** + * 富文本plugin微信小程序特殊扩展 + * @author sonve + * @version 1.0.0 + * @date 2024-12-17 + */ +import config from '../common/config.js' + +/** + * 微信小程序特有的OffscreenCanvas方法 + * @param {String} coverImageUrl 封面资源地址 + * @returns {Promise} 处理后的封面图片的临时文件路径 + */ +export function wxCreateCoverThumbnail(coverImageUrl) { + const loadImage = () => { + return new Promise((resolve, reject) => { + uni.getImageInfo({ + src: coverImageUrl, + success: (info) => { + resolve(info) + }, + fail: (err) => { + reject(err) + } + }) + }) + } + return new Promise(async (resolve, reject) => { + try { + const imageInfo = await loadImage() + + // 创建离屏 Canvas + const canvas = uni.createOffscreenCanvas({ + type: '2d', + width: imageInfo.width, + height: imageInfo.height + }) + const ctx = canvas.getContext('2d') + + // 创建一个图片 + const coverImg = canvas.createImage() + // 等待图片加载 + await new Promise((resolve) => { + coverImg.onload = resolve + coverImg.src = coverImageUrl // 要加载的图片 url + }) + + // 绘制封面图片到离屏 Canvas + ctx.drawImage(coverImg, 0, 0, canvas.width, canvas.height) + + // 加载播放按钮图标 + const playIcon = canvas.createImage() + // 等待图片加载 + await new Promise((resolve) => { + playIcon.onload = resolve + playIcon.src = config.video_playicon // 要加载的图片 url + }) + + // 计算播放按钮的位置和大小 + // const playButtonSize = Math.min(canvas.width, canvas.height) * 0.15 + const playButtonSize = canvas.width * 0.15 + const playButtonX = (canvas.width - playButtonSize) / 2 + const playButtonY = (canvas.height - playButtonSize) / 2 + + // 确保播放按钮图标按比例缩放 + const iconAspectRatio = playIcon.width / playIcon.height + const iconWidth = playButtonSize + const iconHeight = iconWidth / iconAspectRatio + + // 绘制播放按钮图标到离屏 Canvas + ctx.drawImage(playIcon, playButtonX, playButtonY, iconWidth, iconHeight) + + // 获取画完后的数据 + uni.canvasToTempFilePath({ + canvas: canvas, + destWidth: canvas.width, + destHeight: canvas.height, + fileType: 'png', + success: (res) => { + resolve(res.tempFilePath) + }, + fail: (err) => { + reject(new Error('Failed to convert canvas to image.')) + } + }) + } catch (error) { + reject(error) + } + }) +} + +export default { + wxCreateCoverThumbnail +} \ No newline at end of file diff --git a/uni_modules/sv-editor/components/common/config.js b/uni_modules/sv-editor/components/common/config.js new file mode 100644 index 0000000..26118ef --- /dev/null +++ b/uni_modules/sv-editor/components/common/config.js @@ -0,0 +1,15 @@ +/** + * 公共配置参数 + * @author sonve + * @version 1.0.0 + * @date 2024-12-04 + */ +const config = { + // 视频默认封面 可能会失效,原图在示例工程根目录下static文件夹中 + video_thumbnail: 'http://qiniu.sonve.asia/assets/images/video-frame-cover.gif', + // 视频封面播放图标 + video_playicon: 'data:image/png;base64,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', + +} + +export default config \ No newline at end of file diff --git a/uni_modules/sv-editor/components/common/file-handler.js b/uni_modules/sv-editor/components/common/file-handler.js new file mode 100644 index 0000000..d2cc3d5 --- /dev/null +++ b/uni_modules/sv-editor/components/common/file-handler.js @@ -0,0 +1,261 @@ +/** + * 以下方法出自 image-tools + * @see https://ext.dcloud.net.cn/plugin?id=123 + */ + +function getLocalFilePath(path) { + if (path.indexOf('_www') === 0 || path.indexOf('_doc') === 0 || path.indexOf('_documents') === 0 || path.indexOf( + '_downloads') === 0) { + return path + } + if (path.indexOf('file://') === 0) { + return path + } + if (path.indexOf('/storage/emulated/0/') === 0) { + return path + } + if (path.indexOf('/') === 0) { + let localFilePath = plus.io.convertAbsoluteFileSystem(path) + if (localFilePath !== path) { + return localFilePath + } else { + path = path.substr(1) + } + } + return '_www/' + path +} + +function dataUrlToBase64(str) { + let array = str.split(',') + return array[array.length - 1] +} + +let index = 0 + +function getNewFileId() { + return Date.now() + String(index++) +} + +function biggerThan(v1, v2) { + let v1Array = v1.split('.') + let v2Array = v2.split('.') + let update = false + for (let index = 0; index < v2Array.length; index++) { + let diff = v1Array[index] - v2Array[index] + if (diff !== 0) { + update = diff > 0 + break + } + } + return update +} + +export function pathToBase64(path) { + return new Promise(function(resolve, reject) { + if (typeof window === 'object' && 'document' in window) { + if (typeof FileReader === 'function') { + let xhr = new XMLHttpRequest() + xhr.open('GET', path, true) + xhr.responseType = 'blob' + xhr.onload = function() { + if (this.status === 200) { + let fileReader = new FileReader() + fileReader.onload = function(e) { + resolve(e.target.result) + } + fileReader.onerror = reject + fileReader.readAsDataURL(this.response) + } + } + xhr.onerror = reject + xhr.send() + return + } + let canvas = document.createElement('canvas') + let c2x = canvas.getContext('2d') + let img = new Image + img.onload = function() { + canvas.width = img.width + canvas.height = img.height + c2x.drawImage(img, 0, 0) + resolve(canvas.toDataURL()) + canvas.height = canvas.width = 0 + } + img.onerror = reject + img.src = path + return + } + if (typeof plus === 'object') { + plus.io.resolveLocalFileSystemURL(getLocalFilePath(path), function(entry) { + entry.file(function(file) { + let fileReader = new plus.io.FileReader() + fileReader.onload = function(data) { + resolve(data.target.result) + } + fileReader.onerror = function(error) { + reject(error) + } + fileReader.readAsDataURL(file) + }, function(error) { + reject(error) + }) + }, function(error) { + reject(error) + }) + return + } + if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) { + wx.getFileSystemManager().readFile({ + filePath: path, + encoding: 'base64', + success: function(res) { + resolve('data:image/png;base64,' + res.data) + }, + fail: function(error) { + reject(error) + } + }) + return + } + reject(new Error('not support')) + }) +} + +export function base64ToPath(base64) { + return new Promise(function(resolve, reject) { + if (typeof window === 'object' && 'document' in window) { + base64 = base64.split(',') + let type = base64[0].match(/:(.*?);/)[1] + let str = atob(base64[1]) + let n = str.length + let array = new Uint8Array(n) + while (n--) { + array[n] = str.charCodeAt(n) + } + return resolve((window.URL || window.webkitURL).createObjectURL(new Blob([array], { + type: type + }))) + } + let extName = base64.split(',')[0].match(/data\:\S+\/(\S+);/) + if (extName) { + extName = extName[1] + } else { + reject(new Error('base64 error')) + } + let fileName = getNewFileId() + '.' + extName + if (typeof plus === 'object') { + let basePath = '_doc' + let dirPath = 'uniapp_temp' + let filePath = basePath + '/' + dirPath + '/' + fileName + if (!biggerThan(plus.os.name === 'Android' ? '1.9.9.80627' : '1.9.9.80472', plus.runtime.innerVersion)) { + plus.io.resolveLocalFileSystemURL(basePath, function(entry) { + entry.getDirectory(dirPath, { + create: true, + exclusive: false, + }, function(entry) { + entry.getFile(fileName, { + create: true, + exclusive: false, + }, function(entry) { + entry.createWriter(function(writer) { + writer.onwrite = function() { + resolve(filePath) + } + writer.onerror = reject + writer.seek(0) + writer.writeAsBinary(dataUrlToBase64(base64)) + }, reject) + }, reject) + }, reject) + }, reject) + return + } + let bitmap = new plus.nativeObj.Bitmap(fileName) + bitmap.loadBase64Data(base64, function() { + bitmap.save(filePath, {}, function() { + bitmap.clear() + resolve(filePath) + }, function(error) { + bitmap.clear() + reject(error) + }) + }, function(error) { + bitmap.clear() + reject(error) + }) + return + } + if (typeof wx === 'object' && wx.canIUse('getFileSystemManager')) { + let filePath = wx.env.USER_DATA_PATH + '/' + fileName + wx.getFileSystemManager().writeFile({ + filePath: filePath, + data: dataUrlToBase64(base64), + encoding: 'base64', + success: function() { + resolve(filePath) + }, + fail: function(error) { + reject(error) + } + }) + return + } + reject(new Error('not support')) + }) +} + +/** + * 本方法为本人自己写的,建议还是使用上述的pathToBase64方法 + * @description 图片地址转换为base64格式图片 + * @param {string} url 图片地址 网络地址 本地相对路径 + * @param {string} type base64图片类型 默认png + */ +export function urlToBase64(url, type = 'png') { + let promises + + // 网络地址 或者h5端本地相对路径 可使用request方式 + promises = new Promise((resolve, reject) => { + uni.request({ + url: url, + method: 'GET', + responseType: 'arraybuffer', + success: (res) => { + const base64 = `data:image/${type};base64,${uni.arrayBufferToBase64(res.data)}` + resolve(base64); + }, + fail: (err) => { + reject(err); + }, + }) + }) + + // #ifdef APP + if (!url.startsWith('http')) { + // app真机本地相对路径 + promises = new Promise((resolve, reject) => { + // 使用compressImage获取到安卓本地路径file:///... + uni.compressImage({ + src: url, + quality: 100, + success: (res) => { + const tempUrl = res.tempFilePath + plus.io.resolveLocalFileSystemURL(tempUrl, (entry) => { + entry.file((e) => { + let fileReader = new plus.io.FileReader(); + fileReader.onload = (r) => { + resolve(r.target.result) + } + fileReader.readAsDataURL(e) + }) + }) + }, + fail: (err) => { + reject(err); + }, + }) + }) + } + // #endif + + return promises +} \ No newline at end of file diff --git a/uni_modules/sv-editor/components/common/parse.js b/uni_modules/sv-editor/components/common/parse.js new file mode 100644 index 0000000..bb00c88 --- /dev/null +++ b/uni_modules/sv-editor/components/common/parse.js @@ -0,0 +1,179 @@ +/** + * 富文本解析工具 + * @author sonve + * @version 1.0.0 + * @date 2024-12-04 + */ + +import config from './config.js' + +/** + * 将含有封面占位图形式的视频富文本转换成正常视频的富文本 + * @param {String} richText 要进行处理的富文本字符串 + * @returns {String} 返回处理结果 + */ +export function parseHtmlWithVideo(richText) { + // 正则表达式匹配标签及其属性 + const imgRegex = /]+)>/gi; + // 正则表达式匹配data-custom属性中的url值 + const customUrlRegex = /\bdata-custom="[^"]*url=([^&"]+)/i; + + return richText.replace(imgRegex, (match, attrs) => { + // 查找data-custom属性中的url值 + const urlMatch = attrs.match(customUrlRegex); + if (urlMatch) { + // 获取data-custom中的url + const videoUrl = urlMatch[1]; + + // 解析出所有属性 + const attrArray = attrs.split(/\s+/).filter(attr => attr.trim() !== ''); + + // 过滤掉src属性和data-custom属性 + const newAttrs = attrArray.filter(attr => !attr.startsWith('src=') && !attr.startsWith('data-custom=')) + .join(' '); + + // 构建新的video标签,保留原有的其他属性,但去除src和data-custom + return ``; + } + // 如果没有匹配到data-custom中的url,则保持原样 + return match; + }); +} + +/** + * 带有视频的富文本逆向转换 + * @description 可自定义处理封面 + * @param {Promise} richText 要转换的富文本 + * @param {Function} customCallback 自定义处理封面回调,需要return封面图片资源,自带参数为视频地址 + * @returns {Promise} 转换后的富文本 注意异步处理 + */ +export async function replaceVideoWithImageRender(richText, customCallback) { + + // 正则表达式用于匹配