Commit 57facb12 authored by 满振华's avatar 满振华

修改富文本

parent 3d4f7dad
import request from '@/utils/request';
// 文件上传获取token
export function getToken() {
return request('/qiniu/token', { method: 'get', prefix: '/adminApi' });
}
/**
*
* @param len 随机树位数 默认6位
* @param type 随机数集类型:n纯数字 l纯小写字母 u纯大写字母 lu大小写字母 默认数字字母
* @param extra 随机数集扩展 可加其他字符
* @returns {string} 返回随机字符串
*/
export function getRandom(len = 6, type?:string, extra?:string):string {
const num = '0123456789';
const letter = 'abcdefghigklmnopqrstuvwxyz';
const upLetter = letter.toUpperCase();
let str = num;
let result = '';
switch (type) {
case 'n':
str = num;
break;
case 'l':
str = letter;
break;
case 'u':
str = upLetter;
break;
case 'lu':
str = letter + upLetter;
break;
default:
str = num + letter + upLetter;
break;
}
if (extra && typeof extra === 'string') {
str += extra;
}
for (let i = 0; i < len; i += 1) {
result += str[Math.floor(Math.random() * str.length)];
}
return result;
}
/* eslint-disable react/no-access-state-in-setstate */
import React, { useState, useRef, useEffect, useImperativeHandle } from 'react';
// 引入编辑器组件
import BraftEditor from 'braft-editor';
import ColorPicker from 'braft-extensions/dist/color-picker';
import { ContentUtils } from 'braft-utils';
import { Progress } from 'antd';
import { PropertySafetyFilled } from '@ant-design/icons';
import UploadQIniu from './uploadQIniu';
import Preview from './preview';
// 引入编辑器样式
import 'braft-editor/dist/index.css';
import 'braft-extensions/dist/color-picker.css';
import styles from './style.less';
// 颜色色盘
BraftEditor.use(ColorPicker({
includeEditors: ['editor-with-color-picker'],
theme: 'light', // 支持dark和light两种主题,默认为dark
}));
// 默认不显示的控件
const excludeControlsDefault = ['emoji', 'blockquote', 'code', 'media'];
interface IObj {
[propsName: string]: any
}
interface IProps {
value?: string; // html
language?: 'zh' | 'en';
cRef?: any;
excludeControls?: string[]; // 不需要显示的控件
onChange?: Function
}
const EditorDemo: React.FC<IProps> = ({ value, language = 'zh', onChange, cRef, excludeControls = excludeControlsDefault }) => {
// 创建一个空的editorState作为初始值
const [editorState, setEditorState] = useState(BraftEditor.createEditorState(null));
const [percent, setPercent] = useState(0); // 进度条
const previewRef = useRef(null);
useEffect(() => {
// 使用BraftEditor.createEditorState将html字符串转换为编辑器需要的editorStat
setEditorState(BraftEditor.createEditorState(value));
}, [value]);
// 获取HTML
const getHtml = () => {
// 直接调用editorState.toHTML()来获取HTML格式的内容
const htmlContent = editorState.toHTML();
return htmlContent;
};
// change事件
const handleEditorChange = (editorState: any) => {
setEditorState(editorState);
if (onChange) {
const htmlContent = editorState.toHTML();
onChange(editorState, htmlContent);
}
};
// 图片上传进度
const percentCbk = (val: number) => {
setPercent(val);
};
// 图片上传进度条
const componentBelowControlBar = () => {
return (percent > 0 && percent < 100) ? (<Progress
percent={percent}
strokeColor="#04B4AD"
format={(p) => { return `图片上传中${parseInt(p, 10)}%`; }}
className={styles.progress}
/>) : null;
};
// 图片上传成功,获取图片信息
const successCbk = (obj: IObj) => {
const { url } = obj || {};
setEditorState(ContentUtils.insertMedias(editorState, [{
type: 'IMAGE',
url,
}]));
};
// 预览方法
const previewMth = () => {
previewRef && previewRef.current && previewRef.current.openFun();
};
// 图片上传组件
const extendControls = [
{
key: 'antd-uploader',
type: 'component',
component: (
<UploadQIniu percentCbk={percentCbk} successCbk={successCbk} language={language} />
),
},
];
// 向外抛出数据
useImperativeHandle(cRef, () => {
return {
getHtml,
previewMth,
};
});
return (
<div className={styles.box}>
<BraftEditor
id="editor-with-color-picker"
value={editorState}
excludeControls={excludeControls}
onChange={handleEditorChange}
extendControls={extendControls}
componentBelowControlBar={componentBelowControlBar()}
language={language}
/>
<Preview cRef={previewRef} htmlStr={getHtml()} language={language} />
</div>
);
};
export default EditorDemo;
import React, { useState, useImperativeHandle } from 'react';
import { Modal } from 'antd';
interface IProps {
htmlStr?: string;
cRef?: any;
language?: 'zh' | 'en';
}
const Preview:React.FC<IProps> = ({ htmlStr, cRef, language = 'zh' }) => {
const [visible, setVisible] = useState(false);
useImperativeHandle(cRef, () => {
return {
openFun: () => {
setVisible(true);
},
};
});
const closeFun = () => {
setVisible(false);
};
return (
<Modal
title={language === 'zh' ? '预览' : 'preview'}
visible={visible}
onCancel={closeFun}
centered
destroyOnClose
footer={null}
width={800}
>
<div dangerouslySetInnerHTML={{ __html: htmlStr }} />
</Modal>
);
};
export default Preview;
.box{
width: 100%;
// border: 1px solid #333;
border-radius:4px;
border:1px solid rgba(225,225,225,1);
}
.progress{
display: flex;
align-items: center;
justify-content: space-between;
padding: 0 10px;
:global .ant-progress-text{
width: auto;
padding: 0 10px;
}
}
.upload{
margin-top: 0 !important;
}
/* eslint-disable no-unused-expressions */
import React, { useState } from 'react';
import { Button, message, Upload } from 'antd';
import moment from 'moment';
import { PictureOutlined } from '@ant-design/icons';
import classnames from 'classnames';
import styles from './style.less';
import { getToken, getRandom } from './common';
const maxSizeDefault = 20; // 图片最大限制
interface IProps {
maxSize?: number; // 最大限制 默认20M
successCbk?: Function, // 成功回调
percentCbk?: Function, // 进度条回调
language?: 'zh' | 'en';
}
const UploadCom:React.FC<IProps> = ({ maxSize = maxSizeDefault, successCbk, percentCbk, language = 'zh' }) => {
const [token, setToken] = useState('');
const [domain, setDomain] = useState('');
// 获取七牛上传token
const getTokenFun = async () => {
const response = await getToken();
if (response && response.success && response.data) {
setToken(response.data.token);
setDomain(response.data.domain);
}
};
// 自定义七牛文件唯一key
const getKey = (file) => {
if (!file) return;
const suffix = file.name.match(/\.\w+$/)[0];
const rand6 = getRandom();
const time = moment().format('YYYYMMDDHHmmss');
return time + rand6 + suffix;
};
// 七牛上传额外数据,token和key
const getData = (file) => {
return {
token,
key: getKey(file),
};
};
const beforeUpload = async ({ size }) => {
const fileMaxSizeB = maxSize * 1024 * 1024;
if (size > fileMaxSizeB) {
message.warning(language === 'zh' ? `上传图片超过最大限制${maxSize}M` : `limit ${maxSize}M`);
// eslint-disable-next-line prefer-promise-reject-errors
return Promise.reject(false);
}
await getTokenFun();
return true;
};
const onChange = ({ file, fileList, event }) => {
if (file.status === 'done' && file.response) {
const data = file.response || {};
const url = `${`https://${domain}`}/${data.key}`;
// 上传成功后处理为服务端数据结构
const itemObj = {
uid: file.uid,
name: file.name,
value: url,
size: file.size,
url,
domain,
};
successCbk && successCbk(itemObj);
} else if (file.status === 'error') {
message.error('upload error');
percentCbk && percentCbk(0);
}
percentCbk && event && event.percent && percentCbk(event.percent);
};
return (
<Upload
action="https://upload-z1.qiniup.com/" // 七牛上传地址
data={getData}
beforeUpload={beforeUpload}
onChange={onChange}
accept="image/*"
showUploadList={false}
className={classnames('control-item', styles.upload)}
>
<button type="button" className="control-item button upload-button" data-title={language === 'zh' ? '插入图片' : 'insert picture'}>
<PictureOutlined />
</button>
</Upload>
);
};
export default UploadCom;
// className="control-item button upload-button"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment