一、富文本braft-editor

  • 安装并引用

    npm install braft-editor --save
    
    import BraftEditor from 'braft-editor'
    import 'braft-editor/dist/index.css'
  • state中初始内容

    editorState: BraftEditor.createEditorState(),
  • 表单中使用<BraftEditor/>

     <FormItem label="教程正文" {...formLayout}>
    {getFieldDecorator('content', {
    validateTrigger: 'onBlur',
    rules: [{
    required: true,
    validator: (_, value, callback) => {
    if (value.isEmpty()) {
    callback('请输入正文内容')
    } else {
    callback()
    }
    }
    }],
    // 内容必须通过BraftEditor.createEditorState()转化为可读的格式
    initialValue: current && detail ? BraftEditor.createEditorState(defaultContent(detail.content)) : ''
    })(
    <BraftEditor
    className="my-editor"
    controls={controls} // 按需添加控件按钮
    extendControls={extendControls} // 自定义控件按钮
    placeholder="请输入正文内容"
    media={{ // 媒体对象
    uploadFn: handleUploadFn, // 上传七牛云服务器获取url
    validateFn: handleValidateFn, // 上传文件的限制
    accepts: { // 可上传格式
    image: 'image/png, image/jpeg, image/jpg, image/gif, image/webp, image/apng, image/svg',
    video: 'video/mp4',
    audio: 'audio/mp3, audio/mp4, audio/ogg, audio/mpeg'
    }
    }}
    onChange={this.handleContentChange} // 内容更改方法
    />
    )}
    </FormItem>
  • 打开弹框时处理获取到的HTML格式的content,转化为插件可读格式,同时字符串切割替换转换后台传来的七牛云前缀与安卓ios视频图片需要的标签处理

    showEditModal = item => {
    const { dispatch } = this.props; let content = '';
    if(item.content){
    content = item.content;
    let contentObj = JSON.parse(BraftEditor.createEditorState(content).toRAW());
    let urlArr;
    Object.keys(contentObj.entityMap).forEach((key) => {
    if(contentObj.entityMap[key].data.url){
    urlArr = contentObj.entityMap[key].data.url.split('/')
    console.log('编辑时', urlArr)
    if(urlArr.length == 2){ //ios视频前缀yihezo
    urlArr.splice(0,1);
    contentObj.entityMap[key].data.url = `${setFileHost()}`+ 'yihezo/' + urlArr.join('/');
    } if(urlArr.length == 3){ //其它媒体文件前缀sys/tutorial
    urlArr.splice(0,1);
    contentObj.entityMap[key].data.url = `${setFileHost()}`+ 'sys/' + urlArr.join('/');
    }
    }
    });
    let contentRaw = JSON.stringify(contentObj);
    item.content = contentRaw;
    }; dispatch({
    type: 'course/fetchDetail',
    payload: {
    id: item.id
    },
    callback: (res) => {
    if(res){
    let detail = res.data;
    let HTML = detail.content;
    HTML = HTML.substring(24).substring(0, HTML.length-6);
    HTML = HTML.replace(/style='max-width:100%' /g, "").replace(/poster=['|"].*?['|"]/g, "").replace(/alt='picvision' /g, "");
    detail.content = HTML; this.setState({
    detail,
    current: item,
    addSubmit: false
    }, () => {
    this.setState({
    visible: true
    })
    });
    }
    }
    })
    };
  • 组件需要的参数和方法 
    // 自带的可按需选择的控件按钮
    const controls = [ 'undo', 'redo', 'separator',
    'font-size', 'line-height', 'letter-spacing', 'separator',
    'text-color', 'bold', 'italic', 'underline', 'strike-through', 'separator',
    'superscript', 'subscript', 'remove-styles', 'emoji', 'separator', 'text-indent', 'text-align', 'separator',
    'headings', 'list-ul', 'list-ol', 'separator',
    'link', 'separator', 'hr', 'separator',
    'media', 'separator',
    'clear'
    ]; // 上传七牛云服务器获取url
    const handleUploadFn = (param) => {
    const { file } = param; const fileTypeArr = file.type.split('/');
    const fileType = fileTypeArr[0]; if(fileType == 'video'){
    handleImageUpload(file, 'tutorialVideo').then(res => {
    param.success({
    url: `${setFileHost()+res}`,
    meta: {
    id: new Date().getTime(),
    loop: false,
    autoPlay: false,
    controls: true
    }
    })
    })
    }else{
    handleImageUpload(file, 'tutorial').then(res => {
    param.success({
    url: `${setFileHost()+res}`,
    meta: {
    id: new Date().getTime(),
    loop: false,
    autoPlay: false,
    controls: true
    }
    })
    })
    }
    } // 可上传文件的大小范围
    const handleValidateFn = (file) => {
    return file.size < 1024 * 1024 * 100
    } // content内容存在时,处理为可编辑数据
    const defaultContent = (content) => {
    let contentObj = JSON.parse(BraftEditor.createEditorState(content).toRAW());
    let urlArr;
    Object.keys(contentObj.entityMap).forEach((key) => {
    if(contentObj.entityMap[key].data.url){
    urlArr = contentObj.entityMap[key].data.url.split('/')
    console.log('默认内容', urlArr);
    if(urlArr.length == 2){ //ios视频前缀yihezo
    urlArr.splice(0,1);
    contentObj.entityMap[key].data.url = `${setFileHost()}`+ 'yihezo/' + urlArr.join('/');
    } if(urlArr.length == 3){ //其它媒体文件前缀sys/tutorail
    urlArr.splice(0,1);
    contentObj.entityMap[key].data.url = `${setFileHost()}`+ 'sys/' + urlArr.join('/');
    }
    }
    });
    let contentRaw = JSON.stringify(contentObj);
    return contentRaw;
    } // 自定义控件按钮
    const extendControls = [
    {
    key: 'custom-button',
    type: 'button',
    text: '预览',
    onClick: this.handleEditPreview
    }
    ];
  • react页面渲染HTML
    <div dangerouslySetInnerHTML = {{__html:返回的html代码片段}} ></div>
    

    原理:

    1.dangerouslySetInnerHTMl 是React标签的一个属性,类似于angular的ng-bind;

    2.有2个{{}},第一{}代表jsx语法开始,第二个是代表dangerouslySetInnerHTML接收的是一个对象键值对;

    3.既可以插入DOM,又可以插入字符串;  

二、图片裁剪  

  • 安装并引用

    npm install react-cropper --save
    
    import Cropper from 'react-cropper'
    import "cropperjs/dist/cropper.css"
  • Modal弹框包裹<Cropper />组件

     <Modal
    title="上传轮播图"
    visible={this.state.editImageModalVisible}
    width={500}
    bodyStyle={{height: 350, textAlign: 'center' }}
    maskClosable={false}
    onCancel={this.handleCancelImg}
    okText="确认上传"
    cancelText="取消"
    onOk={this.handleSaveImg}
    onCancel={this.handleCancelImg}
    >
    <Cropper
    src={this.state.srcCropper} //图片路径,即是base64的值,在Upload上传的时候获取到的
    ref="cropper"
    viewMode={1} //定义cropper的视图模式
    aspectRatio={1/1}
    zoomable={false} //是否允许放大图像
    movable={false}
    guides={true} //显示在裁剪框上方的虚线
    background={false} //是否显示背景的马赛克
    rotatable={false} //是否旋转
    style={{ maxWidth:500, maxHeight: 300 }}
    cropBoxResizable={true} //是否可以拖拽
    cropBoxMovable={true} //是否可以移动裁剪框
    dragMode="move"
    center={true}
    />
    </Modal>
  • beforeUpload方法中在获得file之后,判断this.refs.cropper,设置组件所需参数

    beforeUpload = (file) => {
    let type = file.type.split('/')[0];
    let name = file.name.split('.')[0];
    if(type == 'video') {
    let imgArray = [...this.state.imgList];
    imgArray.push(file); handleImageUpload(file, 'video', name).then(res => {
    this.setState({
    imgList: imgArray
    });
    this.handleFileThumb(res, file, imgArray)
    })
    }else{
    //当打开同一张图片的时候清除上一次的缓存
    if (this.refs.cropper) {
    this.refs.cropper.reset();
    } var reader = new FileReader();
    const image = new Image();
    //因为读取文件需要时间,所以要在回调函数中使用读取的结果
    reader.readAsDataURL(file); //开始读取文件 reader.onload = (e) => {
    image.src = reader.result;
    image.onload = () => {
    this.setState({
    srcCropper: e.target.result, //cropper的图片路径
    selectImgName: file.name, //文件名称
    selectImgSize: (file.size / 1024 / 1024), //文件大小
    selectImgSuffix: file.type.split("/")[1], //文件类型
    editImageModalVisible: true, //打开控制裁剪弹窗的变量,为true即弹窗
    })
    if (this.refs.cropper) {
    this.refs.cropper.replace(e.target.result);
    }
    }
    }
    return false;
    }
    }
  • 点击弹框中【确定/保存裁剪后的图片,上传七牛云获取url,在Upload组件中显示】,【取消/关闭弹框】

    handleSaveImg = () => {
    let imgArray = [...this.state.imgList];
    let imgFile = this.dataURLtoFile(this.refs.cropper.getCroppedCanvas().toDataURL(), this.state.selectImgName)
    imgArray.push(imgFile); // 上传七牛云方法 --- Upload组件使用中有js封装过程
    handleImageUpload(imgFile, 'image').then(res => {
    this.setState({
    imgList: imgArray,
    srcCropper: this.state.srcCropper, //cropper的图片路径
    }, () => {
    this.setState({
    editImageModalVisible: false
    })
    })
    this.handleFileThumb(res, imgFile, imgArray)
    })
    } handleCancelImg = () => {
    this.setState({
    editImageModalVisible: false,
    });
    }

三、统计图表  

  

  • 官网图例:https://bizcharts.net/products/bizCharts
  • 安装和引用
    npm install bizcharts --save
    
    import {ChartCard, Field, TimelineChart} from '@/components/Charts';
    
    import {
    G2,
    Chart,
    Geom,
    Axis,
    Tooltip,
    Coord,
    Label,
    Legend,
    View,
    Guide,
    Shape,
    Facet,
    Util
    } from "bizcharts";

    官方折线图Mock数据示例:

    class Curved extends React.Component {
    render() {
    const data = [
    {
    month: "Jan",
    city: "Tokyo",
    temperature: 7
    },
    {
    month: "Jan",
    city: "London",
    temperature: 3.9
    },
    {
    month: "Feb",
    city: "Tokyo",
    temperature: 6.9
    },
    {
    month: "Feb",
    city: "London",
    temperature: 4.2
    },
    {
    month: "Mar",
    city: "Tokyo",
    temperature: 9.5
    },
    {
    month: "Mar",
    city: "London",
    temperature: 5.7
    },
    {
    month: "Apr",
    city: "Tokyo",
    temperature: 14.5
    },
    {
    month: "Apr",
    city: "London",
    temperature: 8.5
    },
    {
    month: "May",
    city: "Tokyo",
    temperature: 18.4
    },
    {
    month: "May",
    city: "London",
    temperature: 11.9
    },
    {
    month: "Jun",
    city: "Tokyo",
    temperature: 21.5
    },
    {
    month: "Jun",
    city: "London",
    temperature: 15.2
    },
    {
    month: "Jul",
    city: "Tokyo",
    temperature: 25.2
    },
    {
    month: "Jul",
    city: "London",
    temperature: 17
    },
    {
    month: "Aug",
    city: "Tokyo",
    temperature: 26.5
    },
    {
    month: "Aug",
    city: "London",
    temperature: 16.6
    },
    {
    month: "Sep",
    city: "Tokyo",
    temperature: 23.3
    },
    {
    month: "Sep",
    city: "London",
    temperature: 14.2
    },
    {
    month: "Oct",
    city: "Tokyo",
    temperature: 18.3
    },
    {
    month: "Oct",
    city: "London",
    temperature: 10.3
    },
    {
    month: "Nov",
    city: "Tokyo",
    temperature: 13.9
    },
    {
    month: "Nov",
    city: "London",
    temperature: 6.6
    },
    {
    month: "Dec",
    city: "Tokyo",
    temperature: 9.6
    },
    {
    month: "Dec",
    city: "London",
    temperature: 4.8
    }
    ];
    const cols = {
    month: {
    range: [0, 1]
    }
    };
    return (
    <div>
    <Chart height={400} data={data} scale={cols} forceFit>
    <Legend />
    <Axis name="month" />
    <Axis
    name="temperature"
    label={{
    formatter: val => `${val}°C`
    }}
    />
    <Tooltip
    crosshairs={{
    type: "y"
    }}
    />
    <Geom
    type="line"
    position="month*temperature"
    size={2}
    color={"city"}
    shape={"smooth"}
    />
    <Geom
    type="point"
    position="month*temperature"
    size={4}
    shape={"circle"}
    color={"city"}
    style={{
    stroke: "#fff",
    lineWidth: 1
    }}
    />
    </Chart>
    </div>
    );
    }
    } ReactDOM.render(<Curved />, mountNode)

转载请注明出处

【后台管理系统】—— Ant Design Pro结合插件(一)的更多相关文章

  1. 【后台管理系统】—— Ant Design Pro入门学习&项目实践笔记(三)

    前言:前一篇记录了[后台管理系统]目前进展开发中遇到的一些应用点,这一篇会梳理一些自己学习Ant Design Pro源码的功能点.附:Ant Design Pro 在线预览地址. Dashboard ...

  2. Ant Design Pro (中后台系统)教程

    一.概念:https://pro.ant.design/docs/getting-started-cn(官方网站) 1.Ant Design Pro 是什么:  https://www.cnblogs ...

  3. ant design pro(一)安装、目录结构、项目加载启动【原始、以及idea开发】

    一.概述 1.1.脚手架概念 编程领域中的“脚手架(Scaffolding)”指的是能够快速搭建项目“骨架”的一类工具.例如大多数的React项目都有src,public,webpack配置文件等等, ...

  4. 使用ant design pro搭建项目

    脚手架搭建 git clone --depth=1 https://github.com/ant-design/ant-design-pro.git my-project 然后 cd my-proje ...

  5. 轻松玩转Ant Design Pro一

    ant design pro来源于ant design,其是一段自带样式的react组件,用于企业后台的漂亮的,可控的组件.ant design有很多组件和样式,不可能所有都记住,我们只要记住常用的, ...

  6. ant design pro 当中改变ant design 组件的样式和 数据管理

    ant design pro 简介 官网简介 链接 https://pro.ant.design/docs/getting-started-cn 项目结构 https://github.com/ant ...

  7. Ant Design Pro 学习笔记:数据流向

    在讲这个问题之前,有一个问题应当讲一下: Ant Design Pro / umi / dva 是什么关系? 首先是 umi / dva 的关系. umi 是一个基于路由的 react 开发框架. d ...

  8. 阿里开源项目之Ant Design Pro

    本篇文章主要包含的内容有三个方面. 第一.Ant Design Pro简介; 第二.Ant Design Pro能做什么; 第三.初步使用; 我相信通过这三个方面的讲解能让你大概知道Ant Desig ...

  9. ant design pro (十一)advanced Mock 和联调

    一.概述 原文地址:https://pro.ant.design/docs/mock-api-cn Mock 数据是前端开发过程中必不可少的一环,是分离前后端开发的关键链路.通过预先跟服务器端约定好的 ...

随机推荐

  1. Centos7 用gogs搭建git仓库

    0.安装步骤 先安装依赖,然后创建数据库,创建git用户,安装Gogs软件,设置启动,访问web界面进行配置 一.Gogs依赖环境 安装Gogs之前需要配置相应的依赖环境,官网介绍的依赖环境如下: 数 ...

  2. springboot导包spring-boot-starter-parent出现错误

    <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot ...

  3. 二、Ubuntu16.04安装搜狗wps

    1.搜狗: 安装搜狗输入法,下载地址:http://pinyin.sogou.com/linux/(搜索官网下载及安装方法),deb安装方法类似Windows的exe安装,安装后重启生效. 2.wps ...

  4. ASP.NET 中 取得 Repeater 里的checkbox值

    前言:这两天在维护ASP.NET的项目,需要做一个checkbox来选择数据进行导出,下面提供两种解决思路 1.ASP:CheckBox asp:CheckBox自带控件,没有Value值 <a ...

  5. CentOS 7添加开机启动服务脚本

    一.添加开机自启服务 在CentOS 7中添加开机自启服务非常方便,只需要两条命令(以Jenkins为例): systemctl enable jenkins.service #设置jenkins服务 ...

  6. 基本运算符与if while详解:

    ''' 基本运算符与if while详解: ''' # 算术运算符 # + - * / % // ** # 返回一个数值 # 比较运算符 # > >= < <= == != # ...

  7. Flume 实时获取日志内容插入MySQL

    https://www.jianshu.com/p/22e6133649ca 采用链接的方法试了一下,好像不成功,问题出在 channel.take();   //获取出来的Event为空,不知道为啥

  8. Linux中关闭SSH的DNS解析

    在操作中,我们都会用SSH协议来远程控制虚拟机,但是在输入用户名时候,会有一段时间的卡顿,此时正在进行SSH协议的DNS解析,我们为了快速的连接到虚拟机上,就要关闭这个解析过程,如下是具体配置: 1. ...

  9. Gitlab+Jenkins+Docker实现net core持续集成

    前言 在项目中使用这一套自动集成的体系之后,一直想找个时间总结出来,用于自己记录也打算将自己的所得分享给园友们,不经常写文章,可能会有错误的地方,希望各位不吝指正,我会及时的改正并表示感谢,希望大家能 ...

  10. R中的常用命令(持续更新)

    (1)工作环境 #Ctrl+L键:清屏#Ctrl+Shift+C键:注释.取消注释(仅在RStudio中)(可以多行) rm(变量) #清除某变量 ls() #列出内存中的变量 rm(list=ls( ...