【React 】基于Antd Design的Upload图片墙组件封装

最近在统一UI组件库,基于项目的需求,封装了一个专门用来上传图片的控件,主要有以下一些功能:

a. 可以动态配置保存的方式,可以上传到文档库、Redis缓存以及base64保存在数据库中;

b. 动态配置允许上传多少张,超过限制不显示上传按钮;

c. 动态配置允许上传图片的大小,超过限制大小不允许上传;

d. 支持图片的预览以及删除;

e. 支持在父组件中获取已上传的图片信息;

f. 支持动态配置回显图片信息;

g. 支持Form管理值,表单提交直接获取值进行提交;

h. onRemove回调给父组件进行删除后续处理,onChange回调给父组件进行值处理;

一、NHPicturesWall.js

import React from 'react';
import {Icon, message, Modal, Upload} from 'antd';
import PropTypes from "prop-types";
import {createUuid} from '../../../utils/NHCore';
import {baseUrl} from '../../../utils/NHPrefixUrl';
import './NHPicturesWall.css';

const fileDocDownloadPath = 'api/docrepo/download?attachmentId=';
const redisDownloadPath = baseUrl + '/proData/downloadRedisCacheImage?uuid=';

/**
 * @author weishihuai
 * @date 2018/9/12
 * @time 9:52
 * @Description: 图片墙上传组件
 *
 *   图片墙使用说明:
 *   onRemove: this.onImageRemove.bind(this), 非必须, 图片删除之后回传删除图片给父组件的方法
 *   onChange: this.onChange.bind(this), 非必须, 值改变时执行的方法
 *   numberOfLimit: 2, 必须, 图片墙允许上传的图片张数,超过numberOfLimit上传按钮自动隐藏
 *   numberOfSize: 5,  必须, 图片墙允许上传图片大小的最大值,超过numberOfSize的话直接不上传
 *   saveType: 'file', 必须, 图片墙图片保存的格式,默认为‘file’保存在文档库,‘redis’为缓存在redis,‘base64’保存在内存中,如果需要永久保存文件,建议保存在文档库
 *   cacheTime: 30,  非必须, Redis缓存时长,单位:分钟  超过30分钟redis会删除缓存的图片信息
 *   imageList: ['0264a687-baa4-490f-92f5-e988dcd8d976','0264a687-baa4-490f-92f5-e988dcd8d976'] 非必须, 如果是编辑模式下,需要回显已经保存的图片信息,注意一下需要构造如下类型数据才能显示出来:
 */
class NHPicturesWall extends React.Component {

    constructor(props) {
        super(props);
        this.state = {
            uploadedImageList: [],          //已上传图片
            previewImageVisible: false,     //是否预览图片标识
            previewImageUrl: '',            //预览图片的URL
            previewImageName: '',           //预览图片的名称
        }
    }

    //设置props默认值
    static defaultProps = {
        saveType: 'file',       //保存的类型,默认为file文档库,可选的值: 'file'(上传文档库)、'base64'(保存数据库)、'redis'(缓存redis)
        imageList: [],          //设置默认上传的图片 格式:imageList: [{ uid: '对应文档库uuid', name: '图片名称',status: 'done', url: '图片url'}]
        cacheTime: 30,          //设置Redis缓存的时间,单位:分钟 表示Redis超过30分钟会删除缓存的信息
        numberOfLimit: 1,       //最多允许上传多少张图片 默认为1张
        numberOfSize: 2,        //默认上传大小限制2MB
        disabled: false,        //是否禁用
        onRemove: () => {       //删除成功回调
        },
        onChange: () => {
        },                      //值改变时的回调
        base64UploadUrl: '',    //base64上传图片路径
    };

    //组件render之前组装已经上传成功的图片信息uploadedImageList,主要用于回显图片
    componentWillMount() {
        let saveType = this.props.saveType || 'file';
        if (saveType === 'base64') {
            if (this.props.imageList.length > 0) {
                let uploadedImageList = [];
                this.props.imageList.map((base64Code) => {
                    uploadedImageList.push({
                        uuid: base64Code,
                        uid: base64Code,
                        url: base64Code
                    });
                });
                this.setState({
                    uploadedImageList: uploadedImageList
                });

                let imageList = [];
                uploadedImageList.map((file) => {
                    let obj = {
                        uuid: file.uuid,
                        base64Url: file.url
                    };
                    imageList.push(obj);
                });

                if (this.props.onChange && typeof this.props.onChange === "function") {
                    this.props.onChange(imageList);
                }
            }
        } else {
            if (this.props.imageList.length > 0) {
                let uploadedImageList = [];
                this.props.imageList.map((uuid) => {
                    uploadedImageList.push({
                        uuid: uuid,
                        uid: uuid,
                        url: saveType === 'file' ? fileDocDownloadPath + uuid : redisDownloadPath + uuid
                    });
                });
                this.setState({
                    uploadedImageList: uploadedImageList
                });

                let imageList = [];
                uploadedImageList.map((file) => {
                    let obj = {uuid: file.uuid};
                    imageList.push(obj);
                });

                if (this.props.onChange && typeof this.props.onChange === "function") {
                    this.props.onChange(imageList);
                }
            }
        }
    }

    //图片预览事件
    handlePreview = (file) => {
        this.setState({
            previewImageUrl: file.url || file.thumbUrl,
            previewImageName: file.name,
            previewImageVisible: true
        });
    };

    //取消图片预览事件
    handlePreviewCancel = () => {
        this.setState({
            previewImageVisible: false
        });
    };

    //文件上传改变事件
    handleChange = (e) => {
        const saveType = this.props.saveType || 'file';
        let fileList = e.fileList;
        let fileStatus = e.file.status;

        if (fileStatus === 'uploading') {    //上传中
            // console.log('uploading....');
        } else if (fileStatus === 'done') {  //上传成功
            let response = e.file.response;
            if (!response) {
                message.error("抱歉,文件由于未知原因上传失败!");
                return;
            }
            let responseMeta = response.meta;
            if (saveType === 'file') {   //上传到文档库
                //上传成功(success为true并且响应码为200)
                if (responseMeta && responseMeta.success && responseMeta.statusCode === 200) {
                    fileList = fileList.map((file) => {
                        if (file.uid === e.file.uid) {
                            // file.uuid = response.data.ssbh;
                            file.uuid = response.data.bh;
                        }
                        return file;
                    });

                    this.getUploadedImage(fileList, 'file');
                } else {
                    message.error("抱歉,文件由于未知原因上传失败!");
                    //过滤上传失败的图片
                    fileList = this.filterUploadFailFile(e.fileList, e.file);
                }

            } else if (saveType === 'redis') { //缓存Redis
                //缓存成功(响应码为200)
                if (response.code === 200) {
                    fileList = fileList.map((file) => {
                        if (file.uid === e.file.uid) {
                            file.uuid = response.data;
                        }
                        return file;
                    });
                    this.getUploadedImage(fileList, 'redis');
                } else {
                    message.error("抱歉,文件由于未知原因上传失败!");
                    //过滤上传失败的图片
                    fileList = this.filterUploadFailFile(e.fileList, e.file);
                }
            } else if (saveType === 'base64') {  //用于保存数据库
                this.getImageBase64(e.file.originFileObj, (imageUrl) => {
                    // console.log(imageUrl);
                    //上传成功
                    if (response.code === 200) {
                        fileList = fileList.map((file) => {
                            if (file.uid === e.file.uid) {
                                file.uuid = imageUrl;
                                file.base64Url = imageUrl;
                            } else {
                                file.base64Url = file.thumbUrl || file.url;
                            }
                            return file;
                        });
                        this.getUploadedImage(fileList, 'base64');
                    } else {
                        message.error("抱歉,文件由于未知原因上传失败!");
                        //过滤上传失败的图片
                        fileList = this.filterUploadFailFile(e.fileList, e.file);
                    }
                });

            }
        } else if (fileStatus === 'error') {  //上传出错
            message.error("抱歉,文件由于未知原因上传失败!");
            //过滤上传失败的图片
            fileList = this.filterUploadFailFile(e.fileList, e.file);
        }
        if (fileStatus) {
            this.setState({
                uploadedImageList: fileList
            });
        }
    };

    //获取图片Base64
    getImageBase64 = (img, callback) => {
        const reader = new FileReader();
        reader.addEventListener('load', () => callback(reader.result));
        reader.readAsDataURL(img);
    };

    //过滤上传失败的图片
    filterUploadFailFile = (list, failUploadedFile) => {
        return list.filter(file =>
            file.uid !== failUploadedFile.uid
        );
    };

    //获取上传成功的图片
    getUploadedImage = (fileList, saveType) => {
        if (saveType === 'base64') {
            let uploadedImageList = [];
            fileList.map((file) => {
                let obj = {
                    uuid: file.uuid,
                    base64Url: file.base64Url
                };
                uploadedImageList.push(obj);
            });

            //父组件回调方法,在父组件可以拿到已经上传成功的图片信息
            if (this.props.onChange && typeof this.props.onChange === "function") {
                this.props.onChange(uploadedImageList);
            }
        } else {
            let uploadedImageList = [];
            fileList.map(file => {
                let obj = {
                    uuid: file.uuid
                };
                uploadedImageList.push(obj);
            });

            //父组件回调方法,在父组件可以拿到已经上传成功的图片信息
            if (this.props.onChange && typeof this.props.onChange === "function") {
                this.props.onChange(uploadedImageList);
            }
        }
    };

    //上传文件之前的钩子,参数为准备上传的文件,若返回 false 则停止上传
    //一般在beforeUpload方法内限制文件上传的格式以及大小
    handelBeforeUpload = (file) => {
        let fileType = file.type;
        let fileName = file.name;
        //判断是否支持该文件格式
        let isInvalidFileType = !fileType || fileType.length < 1;
        if (isInvalidFileType) {
            message.error('抱歉,不支持上传该格式的文件!');
            return !isInvalidFileType;
        }

        let availFileSuffix = ['.png', '.PNG', '.jpg', '.JPG', '.bpm', '.BPM', '.gif', '.GIF'];
        let fileSuffixName = fileName.substring(file.name.lastIndexOf('.'));
        let isAvailableSuffix = availFileSuffix.includes(fileSuffixName);
        if (!isAvailableSuffix) {
            let msg = '抱歉,只支持上传【' + availFileSuffix.join(' || ') + '】格式的文件!';
            message.error(msg);
            return isAvailableSuffix;
        }

        //限制上传文件大小(默认上传大小限制2MB)
        let availSize = this.props.numberOfSize || 2;
        let fileSize = file.size / 1024 / 1024;
        const isOverSize = fileSize > availSize;

        if (isOverSize) {
            let msg = '抱歉,上传文件大小最大不能超过' + availSize + 'M!';
            message.error(msg);
            return !isOverSize;
        }
        return true;
    };

    //删除图片事件
    handleRemove = (file) => {
        let uploadedImageList = this.state.uploadedImageList;
        for (let index = 0, len = uploadedImageList.length; index < len; index++) {
            if (uploadedImageList[index].uid === file.uid) {
                uploadedImageList.splice(index, 1);
                break;
            }
        }
        this.setState({
            uploadedImageList: uploadedImageList
        });

        //组装数据返回给父组件,包含文档库的uuid以及文件名称
        let imageList = [];
        uploadedImageList.length > 0 && uploadedImageList.map((file) => {
            let obj = {uuid: file.uuid};
            imageList.push(obj);
        });

        if (this.props.onChange && typeof this.props.onChange === 'function') {
            this.props.onChange(imageList);
        }

        //如果有需要对删除的图片做删除文档库等操作,回传给父组件进行处理
        if (this.props.onRemove && typeof this.props.onRemove === 'function') {
            this.props.onRemove(file.uuid);
        }
    };

    render() {
        const {previewImageVisible, previewImageUrl, uploadedImageList, previewImageName} = this.state;
        const numberOfLimit = this.props.numberOfLimit || 1;    //默认最多上传一张图片
        const saveType = this.props.saveType || 'file';      //默认上传到文档库
        const redisCacheTime = this.props.cacheTime || 30;      //Redis默认保存时长,单位:分钟

        const uploadButton = (
            
Upload
); //根据saveType构造上传的url const action = saveType === 'file' ? 'api/docrepo/upload' : saveType === 'redis' ? baseUrl + '/proData/uploadRedis' : this.props.base64UploadUrl; //请求发送的数据 let requestData = saveType === 'file' ? { uuid: createUuid(), type: '1' } : saveType === 'redis' ? { 'redisData': redisCacheTime } : {}; const params = { name: 'file', action: action, //图片上传路径 accept: 'image/*', //接受上传的文件类型,指定为image/**的话,弹出选择文件窗口的时候只会显示图片类型文件,过滤掉.txt、.xsl等非图片文件 listType: 'picture-card', //图片墙样式 multiple: false, //是否允许多选 fileList: uploadedImageList, //已上传的图片 data: requestData, //上传所需参数 onRemove: this.handleRemove, //删除执行的方法 beforeUpload: this.handelBeforeUpload, //图片上传前执行的方法 onPreview: this.handlePreview, //预览图片执行的方法 onChange: this.handleChange, //值改变执行的方法 }; return (
{uploadedImageList.length >= numberOfLimit ? null : uploadButton} {previewImageName}
); } } //属性检查 NHPicturesWall.PropTypes = { saveType: PropTypes.string, //保存的类型 imageList: PropTypes.array, //初始化图片信息 cacheTime: PropTypes.number, //Redis缓存时间 numberOfLimit: PropTypes.number, //允许上传的图片张数 numberOfSize: PropTypes.number, //允许上传的图片大小 disabled: PropTypes.bool, //是否禁用 base64UploadUrl: PropTypes.string, //base64图片上传路径 onRemove: PropTypes.func, //删除成功回调 onChange: PropTypes.func, //值改变回调 }; export default NHPicturesWall;

二、NHPicturesWall.css

.ant-upload-select-picture-card i {
    font-size: 32px;
    color: #999;
}

.ant-upload-select-picture-card .ant-upload-text {
    margin-top: 8px;
    color: #666;
}

三、PicturesWallContainer.js

import React from "react";
import css from './index.css';
import TestPicturesWall from './TestPicturesWall';
import getSize from "../../../utils/getSize";
import {Scrollbars} from 'react-custom-scrollbars';

export default class PicturesWallContainer extends React.Component {

    constructor(props) {
        super(props);
    }

    render() {
        return (
            
); } }

四、index.css


/*右侧主内容div样式*/
.main_right_content{
    margin: 12px 12px 0 12px;
    padding: 16px;
    background: #fff;
    minHeight: 280;
    overflow: hidden;
}

/*表格部分样式*/
.main_right_content .table {
    width: 100%;
    height: 100%;
}

五、TestPicturesWall.js

import React from 'react';
import {Button, Form} from 'antd';
import NHPicturesWall from '../../common/NHPicturesWall/NHPicturesWall';

const FormItem = Form.Item;

/**
 * @author weishihuai
 * @date 2018/9/13
 * @time 14:01
 * @Description: 测试图片墙示例
 *
 *   图片墙使用说明:
 *   onRemove: this.onImageRemove.bind(this), 非必须, 图片删除之后回传删除图片给父组件的方法
 *   onChange: this.onChange.bind(this), 非必须, 值改变时执行的方法
 *   numberOfLimit: 2, 必须, 图片墙允许上传的图片张数,超过numberOfLimit上传按钮自动隐藏
 *   numberOfSize: 5,  必须, 图片墙允许上传图片大小的最大值,超过numberOfSize的话直接不上传
 *   saveType: 'file', 必须, 图片墙图片保存的格式,默认为‘file’保存在文档库,‘redis’为缓存在redis,‘base64’保存在内存中,如果需要永久保存文件,建议保存在文档库
 *   cacheTime: 30,  非必须, Redis缓存时长,单位:分钟  超过30分钟redis会删除缓存的图片信息
 *   imageList: ['0264a687-baa4-490f-92f5-e988dcd8d976','0264a687-baa4-490f-92f5-e988dcd8d976'] 非必须, 初始化图片列表,需要传入图片唯一标识组成的数组
 */
class TestPicturesWall extends React.Component {

    //图片删除成功后的回调方法
    onImageRemove = (uuid) => {
        //这里可以拿到文件的唯一标识或者base64码,进行具体的处理
        console.log(uuid);
    };

    //表单提交事件
    handleSubmit = (e) => {
        e.preventDefault();

        this.props.form.validateFields((err, fieldsValue) => {
            if (err) {
                return;
            }

            //Form表单FieldValues
            console.log('-------fieldsValue-------', fieldsValue);

        });
    };

    render() {
        const formItemLayout = {
            labelCol: {
                xs: {span: 24},
                sm: {span: 5},
            },
            wrapperCol: {
                xs: {span: 24},
                sm: {span: 19},
            },
        };
        let {form} = this.props;
        const {getFieldDecorator} = form;
        const tailFormItemLayout = {
            wrapperCol: {
                xs: {span: 24},
                sm: {span: 12, offset: 6},
                md: {span: 10, offset: 7},
            }
        };


        //file上传到文档库
        const fileUploadParams = {
            onRemove: this.onImageRemove.bind(this),
            numberOfLimit: 3,
            numberOfSize: 10,
            saveType: 'file'
        };

        //缓存Redis
        const redisUploadParams = {
            onRemove: this.onImageRemove.bind(this),
            numberOfLimit: 2,
            numberOfSize: 5,
            saveType: 'redis',
            cacheTime: 30,  //redis缓存时长,单位:分钟.(超过30分钟redis会删除缓存的图片信息)
        };

        //Base64保存数据库
        const base64UploadParams = {
            onRemove: this.onImageRemove.bind(this),
            numberOfLimit: 3,
            numberOfSize: 10,
            saveType: 'base64',
            base64UploadUrl: 'api/zhxg-yxxt/fwwgl/sytp/uploadPicture'  //base64指定上传路径
        };

        const fileUploadParams2 = {
            onRemove: this.onImageRemove.bind(this),
            numberOfLimit: 3,
            numberOfSize: 10,
            saveType: 'file',
            imageList: ['f3b96094-31dd-4694-92e6-14419af5940c', '67dc4599-6c3b-40f0-9b2a-b6ed8a2e3e37'],
        };

        const redisUploadParams2 = {
            onRemove: this.onImageRemove.bind(this),
            numberOfLimit: 2,
            numberOfSize: 5,
            saveType: 'redis',
            cacheTime: 30,  //redis缓存时长,单位:分钟  超过30分钟redis会删除缓存的图片信息
            imageList: ['f3b96094-31dd-4694-92e6-14419af5940c'],
        };

        const base64UploadParams2 = {
            onRemove: this.onImageRemove.bind(this),
            numberOfLimit: 3,
            numberOfSize: 10,
            saveType: 'base64',
            base64UploadUrl: 'api/zhxg-yxxt/fwwgl/sytp/uploadPicture',  //base64指定上传路径
            imageList: [
                'data:image/jpeg;base64,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'
            ],
        };

        return (
            
{getFieldDecorator('imageUrl1', {rules: [{required: true, message: '请上传图片!'}]})( )} {getFieldDecorator('imageUrl2', {rules: [{required: true, message: '请上传图片!'}]})( )} {getFieldDecorator('imageUrl3', {rules: [{required: true, message: '请上传图片!'}]})( )} {getFieldDecorator('imageUrl4', {rules: [{required: true, message: '请上传图片!'}]})( )} {getFieldDecorator('imageUrl5', {rules: [{required: true, message: '请上传图片!'}]})( )} {getFieldDecorator('imageUrl6', {rules: [{required: true, message: '请上传图片!'}]})( )}
) } } export default Form.create()(TestPicturesWall);

六、测试结果


【React 】基于Antd Design的Upload图片墙组件封装_第1张图片

 

【React 】基于Antd Design的Upload图片墙组件封装_第2张图片

【React 】基于Antd Design的Upload图片墙组件封装_第3张图片

 

你可能感兴趣的:(React)