import React, { useEffect, useImperativeHandle, useRef, useState } from 'react'; import AlertMenu from './fullScreen' import E from 'wangeditor'; import { Button, message, Spin } from 'antd'; import { pictureDisplayPath, uploadAttachmentPath } from '@/utils/DownloadUtils'; import { isEmpty, isNotEmpty } from '@/utils/CommonUtils'; import { createNewFileBid } from '@/services/download_'; interface WangType { braftRef: any;//挂载 disabled?: any;//是否可编辑 echo?: any;//回显内容 value?: any; height?: number; onChange?: (value: any) => void; useImage?: boolean;//使用图片上传 imageId?: string;//图片objectId } let editor: any = null; const BraftText: React.FC = (props) => { let willCreate = true; // 菜单 key ,各个菜单不能重复-自定义工具 const menuKey = 'alertMenuKey' //======================================================================================state const [content, setContent] = useState(''); const [fullScreen, fullScreenSet] = useState(false); //遮罩 const [loading, setLoading] = useState(false); //imageId const objectId = useRef(null); const { braftRef, echo, disabled, value, height, onChange, useImage, imageId, } = props; const tools = [//工具栏 'head',//标题 'fontSize', //字号 // 'lineHeight', //行高 'foreColor', //颜色 'bold', //加粗 'italic', //斜体 'underline', //下划线 'strikeThrough', //文字删除线 'indent', //缩进 'justify', //文字对齐方式 'list', //列表 'undo', //撤销 'redo', //恢复 'fullscreen', //全屏 // 'image',//图片 // 'emoticon',//表情 // 'video',//视频 // 'table',//表格 // 'todo',//待办 ]; //=======================================================================================func useEffect(() => { if (willCreate) { // 注:class写法需要在componentDidMount 创建编辑器 editor = new E("#div1"); //添加图片上传 useImage && tools.splice(-3, 0, 'image'); //工具栏 editor.config.menus = tools; //提示 editor.config.placeholder = '为了能顺利发布,建议您内容去掉下划线等格式,尽量以纯文本形式发布。'; // 配置 onchange 回调函数 editor.config.onchange = editorOnChange; // 注册菜单 // editor.menus.extend(menuKey, AlertMenu); // 将菜单加入到 editor.config.menus 中 const menuKey = 'alertMenuKey' // 也可以通过配置 menus 调整菜单的顺序,参考【配置菜单】部分的文档 editor.config.menus.push(menuKey) // editor.config.menus = editor.config.menus.concat(menuKey) // 设置编辑区域高度为 500px height && (editor.config.height = height); //关闭网络上传图片 editor.config.showLinkImg = false; // 关闭粘贴内容中的样式 editor.config.pasteFilterStyle = false; // 忽略粘贴内容中的图片 editor.config.pasteIgnoreImg = true; // 上传图片到服务器,对应的是controller层的@RequestMapping("/upload") editor.config.uploadImgServer = uploadAttachmentPath;//接口名称 //自定义name,接收的时候图片文件的那么用这个,对应的是参数中的MultipartFile upimg名称,这个名称即上传到浏览器的参数名称 editor.config.uploadFileName = "multipartFiles";//这个需要和后台商量上传图片的名称 //设置请求体额外参数 if (useImage) { if (isEmpty(imageId)) { createNewFileBid().then(res => {//获取雪花id editor.config.uploadImgParams = { appCode: 'ebtp-cloud-frontend', objectId: res?.id, }; objectId.current = res?.id; }) } else { editor.config.uploadImgParams = { appCode: 'ebtp-cloud-frontend', objectId: imageId, }; objectId.current = imageId; } } // 将 timeout 时间改为 60s editor.config.uploadImgTimeout = 60000; // 将图片大小限制为 600k editor.config.uploadImgMaxSize = 600 * 1024; // 限制一次最多上传 1 张图片 editor.config.uploadImgMaxLength = 1; //上传图片的错误提示默认使用alert弹出,也可以自定义用户体验更好的提示方式 editor.config.customAlert = function (info: string) { const repinfo = info.replace(/0.5859375M/g, '600K'); // info 是需要提示的内容 message.error(repinfo); }; // 上传图片的结果反馈 editor.config.uploadImgHooks = { before: function (xhr: any, editor: any, files: any) { // 图片上传之前触发 // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,files 是选择的图片文件 // 如果返回的结果是 {prevent: true, msg: 'xxxx'} 则表示用户放弃上传 // return { // prevent: true, // msg: '放弃上传' // } // console.log("before:",xhr) if (isEmpty(objectId.current)) { return { prevent: true, msg: '上传失败,原因:上传参数错误' } } setLoading(true); return { prevent: false, } }, success: function (xhr: any, editor: any, result: any) { // 图片上传并返回结果,图片插入成功之后触发 // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果 // console.log("success:",result) }, fail: function (xhr: any, editor: any, result: any) { // 图片上传并返回结果,但图片插入错误时触发 // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象,result 是服务器端返回的结果 }, error: function (xhr: any, editor: any) { // 图片上传出错时触发 // xhr 是 XMLHttpRequst 对象,editor 是编辑器对象 }, // 上传图片超时 timeout: function (xhr: any) { message.error('服务器超时!'); setLoading(false); }, // 如果服务器端返回的不是 {errno:0, data: [...]} 这种格式,可使用该配置 // (但是,服务器端返回的必须是一个 JSON 格式字符串!!!否则会报错) customInsert: function (insertImg: (arg0: any) => void, result: any, editor: any) { // 图片上传并返回结果,自定义插入图片的事件(而不是编辑器自动插入图片!!!) // insertImg 是插入图片的函数,参数editor 是编辑器对象,result 是服务器端返回的结果 // 举例:假如上传图片成功后,服务器端返回的是 {url:'....'} 这种格式,即可这样插入图片: if (result?.success) { const url = pictureDisplayPath + '?filePath=' + result.data[0].sysStorageVO.filePath; insertImg(url); } else { message.error('图片上传失败!'); } setLoading(false); // var url = result.result.remote_path; // insertImg(url); // result 必须是一个 JSON 格式字符串!!!否则报错 } }; /**一定要创建 */ editor.create(); //控制是否可编辑 disabled && makeDis(); willCreate = false; } return () => { // 组件销毁时销毁编辑器 注:class写法需要在componentWillUnmount中调用 editor.destroy() setLoading(false); setContent(''); } }, []); useEffect(() => { // 重新设置编辑器内容 echo && editor.txt.html(echo); }, [echo]) /** *提供给父级的内容 **/ useImperativeHandle(braftRef, () => ({ getText, getHtml, getHtml1, makeDis, getImageId, })); // 获取html方法1 function getHtml() { return content } // 获取html方法2 function getHtml1() { return editor.txt.html() } // 获取text function getText() { alert(editor.txt.text()) } //change function editorOnChange(newHtml: any) { setContent(newHtml); triggerChange(newHtml) } //不可编辑 function makeDis() { editor.disable(); } //form取值 const triggerChange = (newHtml: any) => { onChange?.(newHtml); }; //获取富文本图片objectId function getImageId() { return objectId.current; } return (
) } export default BraftText