antd upload支持文件格式:.rar、.zip、.doc、.docx、.pdf,不能大于200M

antd upload

相信大家在上传文件、头像、图片的时候,第一时间想到的都是antd upload。
下面是我从antd拿过来的upload的属性。
在这里插入图片描述在这里插入图片描述

限制上传文件格式.rar、.zip、.doc、.docx、.pdf

我们一般用来对于限制上传文件格式的属性是accept,但是在开发的过程中,博主发现了,accept对于.doc、.docx、.pdf、.png、.jpg、.rar,格式的限制是完全没有问题的。但是对于.zip的限制就有问题了,当我属性设置为 accept=".rar,.zip,.doc,.docx,.pdf"的时候,只要有.zip,上传文件的格式就会支持.xmind、.xlsx格式,上传的时候就不会报错,会上传成功,这肯定是不行的,这个时候,我们就需要在beforeUpload这个属性中去做上传文件的限制。
beforeUpload是upload上传文件之前的钩子,参数为上传的文件,若返回 false 则停止上传。我们在beforeUpload函数的file参数中可以获取上床文件的文件信息,这个时候我们就可以根据file里面的参数来进行判断。
注意:博主为什么要用file.name的后缀来匹配他的文件类型,也是是在是没有办法。file有个type属性,表示文件类型,但是docx后缀的文件没有type类型,为了支持上传docx文件,所以,只能用下面的方法来实现:代码如下:

通过file.type来判断上传文件类型(无法判断.docx文件)

 const isJpgOrPng = file.type === 'application/zip' || file.type === 'application/wps-writer' || file.type === 'application/pdf' || file.type === 'application/x-rar';
        if (!isJpgOrPng) {
    
    
            message.error('仅支持文件格式:.rar、.zip、.doc、.docx、.pdf格式图片!');
            this.onRemove(file);
            return
        }

通过file.name来判断上传文件类型(适用于所有文件)

avatarBeforeUpload = file => {
    
    
        let fileType = file.name.split('.');
        const fileDate = fileType.slice(-1);
        if (['zip', 'rar', 'doc', 'docx', 'pdf'].indexOf(fileDate[0]) < 0) {
    
    
            message.error('仅支持文件格式:.rar、.zip、.doc、.docx、.pdf格式附件!');
            this.setState({
    
    
                file
            })
            this.onRemove(file);
            return false
        }
    };

限制上传文件大小不能大于200M

同样是在beforeUpload里面来做限制,下面是支持文件格式:.rar、.zip、.doc、.docx、.pdf并且不能大于200M的代码

avatarBeforeUpload = file => {
    
    
        let fileType = file.name.split('.');
        const fileDate = fileType.slice(-1);
        if (['zip', 'rar', 'doc', 'docx', 'pdf'].indexOf(fileDate[0]) < 0) {
    
    
            message.error('仅支持文件格式:.rar、.zip、.doc、.docx、.pdf格式附件!');
            this.setState({
    
    
                file
            })
            this.onRemove(file);
            return
        }
        const isLt200M = file.size / 1024 / 1024 < 200;
        if (!isLt1M) {
    
    
            message.error('附件大小不能超过200M!');
            this.setState({
    
    
                file
            })
            this.onRemove(file);
            return 
        }
        return isLt200M;
      
    };

限制上传文件大于200M并且不是.rar、.zip、.doc、.docx、.pdf的文件,不调用接口,只有满足条件的文件才能调用接口

这里就用到了customRequest属性,customRequest是通过覆盖默认的上传行为,可以自定义自己的上传实现,我们在这里,可以对于调用接口和传参进行限制,代码如下:

customRequest = async ({
     
      action, method, file, onProgress, onSuccess, onError, }) => {
    
    
        // const { onChange } = this.props;
        const formData = new FormData();
        formData.append('file', file);
        const fileData = this.state.file;
        // 当要上传的文件名和之前不满足条件的文件名进行匹配,相同的话,代码终止,不往下继续执行。
        if(file.name == fileData.name){
    
    
            return
        }
        try {
    
    

            const {
    
     data } = await axios.post(action, formData, {
    
    
                processData: false,
                noContentType: true,
                onUploadProgress: function (progressEvent) {
    
    
                    if (progressEvent.lengthComputable) {
    
    
                        let percent = Math.ceil((progressEvent.loaded / progressEvent.total) * 100);
                        onProgress({
    
    
                            percent,
                        });
                    }
                },
            });

            onSuccess();
            // if (isFunction(onChange)) {
    
    
            //     // onChange(data.data);
            this.props.form.setFieldsValue({
    
     'filePath': data.data })
            // }
            this.setState({
    
    
                file: {
    
    },
            })
        } catch (e) {
    
    
            console.log(e);
            onError(e);
        }

    }

调用后端接口删除文件

实现这个功能就需要用到onChange,onChange上传中、完成、失败都会调用这个函数。 当info.file.status === "removed"状态时候,调用removeFile方法,删除文件**。onRemove点击移除文件时的回调,返回值为 false 时不移除。** 要实现删除文件这个功能这需要三个方法来互相配合,在avatarBeforeUpload方法中又看到调用onRemove方法,这时候,文件的状态会变成removed。在文件变化时,会去调用changeImg方法,在changeImg中,代码会走到info.file.status === “removed”,然后去调用删除文件接口,大功告成,代码如下:

// 删除文件
    removeFile = () => {
    
    
        const fileId = this.props.form.getFieldValue('filePath');
        // console.log(fileId, 'fileId---')
        let params = {
    
    
            fileId: fileId,
        }
        axios.post("/api/tpc/tpc/expertJudgement/removeFile", params).then(res => {
    
    
            if (res.data.code == 200) {
    
    
                message.success(res.data.data || '删除成功')
            } else {
    
    
                message.error(res.data.message || '删除失败')
            }

        }).catch(err => {
    
    
            // console.log(err, 'err')
        })
    };
    //上传文件
    changeImg = info => {
    
    
        // console.log(info, 'inf----')
        const {
    
     file } = this.state;
        let fileList = info.fileList.slice(-1);;
        fileList.forEach((file) => {
    
    
            if (file.response) {
    
    
                file.url = file.response.url;
            }
        });
        const fileData = fileList.filter(item => item.name != file.name)
        this.setState({
    
     fileList: fileList.filter(item => item.name != file.name) }, () => {
    
    
     
        });

        if (info.file.status === "uploading") {
    
    
            this.setState({
    
     loading: true });
            return;
        }
        if (info.file.status === "removed") {
    
    
            this.removeFile();
            this.setState({
    
    
                loading: true
            }, () => {
    
    
                this.props.form.setFieldsValue({
    
    
                    'filePath': undefined
                })
            });
            return false;
        }
        if (info.file.status === "done") {
    
    
            this.setState({
    
    
                imageUrl: info.file.thumbUrl,
                loading: false,
                avatarFlag: true,
            })
        }
    };
    onRemove = (file) => {
    
    
        this.setState({
    
     fileList: this.state.fileList.filter(item => item.name !== file.name) }, () => {
    
    
            this.props.form.setFieldsValue({
    
     fileList: this.state.fileList });
        });
    }

只能上传一个文件(新上传的文件替换之前的文件)

这时候就需要fileList这个属性了, fileList对列表进行完全控制,可以实现文件的自定义功能,上传列表数量的限制。

//上传文件
    changeImg = info => {
    
    
        // console.log(info, 'inf----')
        const {
    
     file } = this.state;
        //*************上传一个文件,并且这个文件永远是最新上传的文件*****************
        let fileList = info.fileList.slice(-1);;
        fileList.forEach((file) => {
    
    
            if (file.response) {
    
    
                file.url = file.response.url;
            }
        });
        
        const fileData = fileList.filter(item => item.name != file.name)
        this.setState({
    
     fileList: fileList.filter(item => item.name != file.name) }, () => {
    
    
         //*************上传一个文件*****************

        if (info.file.status === "uploading") {
    
    
            this.setState({
    
     loading: true });
            return;
        }
        if (info.file.status === "removed") {
    
    
            this.removeFile();
            this.setState({
    
    
                loading: true
            }, () => {
    
    
                this.props.form.setFieldsValue({
    
    
                    'filePath': undefined
                })
            });
            return false;
        }
        if (info.file.status === "done") {
    
    
            this.setState({
    
    
                imageUrl: info.file.thumbUrl,
                loading: false,
                avatarFlag: true,
            })
        }
    };

完整代码如下

import React, {
    
     Component } from 'react';
import {
    
     Button, Form, message,Col,  Upload, } from 'antd';
import {
    
     axios } from '@/utils/request';
import style from './index.less'

const formItemLayout = {
    
    
    labelCol: {
    
    
        xs: {
    
     span: 20 },
        sm: {
    
     span: 2 },
    },
    wrapperCol: {
    
    
        xs: {
    
     span: 20 },
        sm: {
    
     span: 20 },
    },
};

class add extends Component {
    
    
    constructor(props) {
    
    
        super(props);
        this.state = {
    
    
            fileList: [],
            file: '',
            detailDate: {
    
    }, // 详情
        }
        this.formLayout = {
    
    
            labelCol: {
    
     span: 10 },
            wrapperCol: {
    
     span: 14 },
        };
        //    const
    }

    componentDidMount() {
    
    

    }

    //上传文件
    changeImg = info => {
    
    
        // console.log(info, 'inf----')
        const {
    
     file } = this.state;
        let fileList = info.fileList.slice(-1);;
        fileList.forEach((file) => {
    
    
            if (file.response) {
    
    
                file.url = file.response.url;
            }
        });
        const fileData = fileList.filter(item => item.name != file.name)
        this.setState({
    
     fileList: fileList.filter(item => item.name != file.name) }, () => {
    
    
            // console.log(this.state.fileList, 'fileList----', file, 'fileData', fileData)
            // this.props.form.setFieldsValue({ fileList: fileList });
        });

        // this.setState({
    
    
        //     fileList: fileList
        // });
        if (info.file.status === "uploading") {
    
    
            this.setState({
    
     loading: true });
            return;
        }
        if (info.file.status === "removed") {
    
    
            this.removeFile();
            this.setState({
    
    
                loading: true
            }, () => {
    
    
                this.props.form.setFieldsValue({
    
    
                    'filePath': undefined
                })
            });
            return false;
        }
        if (info.file.status === "done") {
    
    
            this.setState({
    
    
                imageUrl: info.file.thumbUrl,
                loading: false,
                avatarFlag: true,
            })
        }
    };

    customRequest = async ({
     
      action, method, file, onProgress, onSuccess, onError, }) => {
    
    
        // const { onChange } = this.props;
        const formData = new FormData();
        formData.append('file', file);
        const fileData = this.state.file;
        if (file.name == fileData.name) {
    
    
            return
        }
        try {
    
    

            const {
    
     data } = await axios.post(action, formData, {
    
    
                processData: false,
                noContentType: true,
                onUploadProgress: function (progressEvent) {
    
    
                    if (progressEvent.lengthComputable) {
    
    
                        let percent = Math.ceil((progressEvent.loaded / progressEvent.total) * 100);
                        onProgress({
    
    
                            percent,
                        });
                    }
                },
            });

            onSuccess();
            // if (isFunction(onChange)) {
    
    
            //     // onChange(data.data);
            this.props.form.setFieldsValue({
    
     'filePath': data.data })
            // }
            this.setState({
    
    
                file: {
    
    },
            })
        } catch (e) {
    
    
            console.log(e);
            onError(e);
        }

    }

    avatarBeforeUpload = file => {
    
    
        let fileType = file.name.split('.');
        const fileDate = fileType.slice(-1);
        if (['zip', 'rar', 'doc', 'docx', 'pdf'].indexOf(fileDate[0]) < 0) {
    
    
            message.error('仅支持文件格式:.rar、.zip、.doc、.docx、.pdf格式附件!');
            this.setState({
    
    
                file
            })
            this.onRemove(file);
            return
        }
        const isLt1M = file.size / 1024 / 1024 < 200;
        if (!isLt1M) {
    
    
            message.error('附件大小不能超过200M!');
            this.setState({
    
    
                avatarFlag: false,
                file
            })
            this.onRemove(file);
            return
        }
        return isLt1M;
        // return isJpgOrPng && isLt1M;
    };

    onRemove = (file) => {
    
    
        this.setState({
    
     fileList: this.state.fileList.filter(item => item.name !== file.name) }, () => {
    
    
            this.props.form.setFieldsValue({
    
     fileList: this.state.fileList });
        });
    }

    // 删除文件
    removeFile = () => {
    
    
        const fileId = this.props.form.getFieldValue('filePath');
        // console.log(fileId, 'fileId---')
        let params = {
    
    
            fileId: fileId,
        }
        axios.post(url, params).then(res => {
    
    
            if (res.data.code == 200) {
    
    
                message.success(res.data.data || '删除成功')
            } else {
    
    
                message.error(res.data.message || '删除失败')
            }

        }).catch(err => {
    
    
            // console.log(err, 'err')
        })
    };

    render() {
    
    
        const {
    
    
            form: {
    
     getFieldDecorator },
        } = this.props;
        return (
            <div className={
    
    styles.myOrder}>
                <div className={
    
    style.exportAnswer}>
                    <Form {
    
    ...formItemLayout}>
                        <Row>
                            <Col span={
    
    24}>
                                <Form.Item label="添加文件">
                                    {
    
    getFieldDecorator('filePath', {
    
    
                                    })(
                                        <Upload
                                            accept='.rar,.zip,.doc,.docx,.pdf,'
                                            action='url'   //后端提供的upload接口,返回url
                                            beforeUpload={
    
    this.avatarBeforeUpload}
                                            onChange={
    
    this.changeImg}
                                            multiple={
    
    false}
                                            method="POST"
                                            customRequest={
    
    this.customRequest}
                                            className='upload-list-inline'
                                            fileList={
    
    this.state.fileList}
                                        >
                                            <Button>
                                                上传文件
                                                </Button>
                                        </Upload>

                                    )}
                                </Form.Item>
                            </Col>
                        </Row>
                    </Form>
                </div>
            </div >
        );
    }
}

export default Form.create()(add);

猜你喜欢

转载自blog.csdn.net/qq_40657321/article/details/110388835