Antd Upload 和 Antd Form 结合的踩坑记录

今天弄了半天这个上传组件结合表单组件的问题。

这个上传文件列表,如果是当前正在修改或者上传成功,当然是可以正常工作的,但是想要增加一个功能:
下次打开 Modal 时,表单字段中的上传文件字段,可以默认回显文件列表(该列表是 Upload 组件内部实现的)。

由于该 Upload 组件已经使用 Form 组件统一代理,所以需要通过 initialValue 字段进行初始值的设定(如果有的话)。当然也可以不代理,单独处理,但这样最终提交数据还是要再增加上去,而且还需要自行实现必填项的校验。

此时既要照顾到 Upload 自身所需字段(特别是 uid 字段),又要迎合最终向后端提交附件时方便新老文件统一处理(通过 JSON.stringify() 的第二个过滤器参数进行处理)。

import React from 'react';
import {
  message,
  Modal,
  Row,
  Col,
  Form,
  Select,
  Button,
  Input,
  Spin,
  Radio,
  DatePicker,
  Upload,
  Icon
} from 'antd';
import moment from 'moment';

const FormItem = Form.Item;
const Option = Select.Option;
const TextArea = Input.TextArea;


class MakeBill extends React.Component {
  state = {
    loading: false,
    disabledOk: false,
    confirmLoading: false,    
    fileList: [],
  }

  handleSubmit = () => {
    this.props.form.validateFieldsAndScroll((err, values) => {
      if (!err) {
        this.setState({ loading: true, confirmLoading: true });
        const submitInfo = JSON.parse(JSON.stringify(values, (key, value) => {
          if (key === 'pay_time') {
            return moment(value).format('YYYY-MM-DD');
          } else if (key === 'attachments') {
            return value.map(f => ({ ...f.saveParams, type: 1 }));
          }
          return value;
        }));
        commerceApi.saveInvoiceOfFinance(submitInfo).then(result => {
          message.success('提交成功!');
          this.props.form.resetFields();
          this.props.onClose('refresh');
          this.setState({ loading: false, confirmLoading: false });
        }, () => {
          this.setState({ loading: false, confirmLoading: false });
        });
      }
    });
  }

  closeForm = () => {
    this.props.form.resetFields();
    this.props.onClose();
  }

  getContactInfo = (id) => {
    commerceApi.getContactDetail({ id, isedit: true }, (result) => {
      this.setState({ relationContactInfo: result });
    });
  }

  render() {
    let { loading, disabledOk, confirmLoading, fileList } = this.state;
    let { form, show, incomeId, busId, details } = this.props;
    let _this = this;
    const { getFieldDecorator } = form;
    if (!Object.keys(details).length) { // 如果没有历史数据,则需要提供一些默认值
      details['invoice_type'] = 0;
    }
    const formItemLayout = {
      labelCol: {
        sm: { span: 8 },
      },
      wrapperCol: {
        sm: { span: 16 },
      },
    };
    const fullLayout = {
      labelCol: {
        sm: { span: 4 },
      },
      wrapperCol: {
        sm: { span: 20 },
      },
    };
    /**
      * 上传组件操作思路:
      * 当文件大于10M时,在调接口前,就提示报错,并且调用onRemove移除
      */
    const props = {
      accept: ".rar,.zip,.doc,.docx,.pdf,.jpg,.png",
      name: 'file',
      action: '/cmp/crm/upload',
      beforeUpload(file) {
        const isLt10M = file.size / 1024 / 1024 <= 10;
        if (!isLt10M) {
          message.error("文件大小限制在10M以下!");
          this.onRemove(file);
          return false;
        }
      },
      onRemove(file) {
        _this.setState({ fileList: fileList.filter(item => item.name !== file.name) }, () => {
          _this.props.form.setFieldsValue({ fileList: fileList });
        });
      },
      onChange(info) { // 上传中、完成、失败都会调用这个函数
        let curFileList = info.fileList;
        curFileList = curFileList.map((file) => {
          if (file.response) {
            // 这里上传组件回调的数据,有些是提供给上传组件自身使用的,所以不能不要
            // 而需要向后端提交的数据这里提前封装起来,以方便最终的提交
            let saveParams = {};
            saveParams["filename"] = file.response.data[0].filename;
            saveParams["url"] = file.response.data[0].url;
            saveParams["size"] = file.response.data[0].size;
            file["saveParams"] = saveParams;
            file['url'] = file.response.data[0].url;
          }
          return file;
        });
        curFileList = curFileList.filter(file => {
          if (file.size / 1024 / 1024 <= 10) {
            if (file.response) {
              return file.response.code === 0;
            }
            return true;
          } else {
            return false;
          }
        });
        _this.setState({ fileList: curFileList });
      },
      // fileList: fileList, // 上传组件已使用Form进行代理,所以不要再直接设置
    };

    return (
      
{ show ? 取消, ]}>
{getFieldDecorator('attachments', { initialValue: (details.attachments || []).map(f => ({ // 为了提供给上传组件回显 uid: f.id, // 这是上传组件规定的文件唯一标识,内部会提供给Form以便正常渲染回显列表 name: f.filename, status: 'done', url: f.url, // 为了迎合最终向后端提交附件时方便新老文件统一处理 saveParams: { filename: f.filename, url: f.url, size: f.size } })), rules: [{ required: true, message: '请上传证明材料' }], valuePropName: 'fileList', getValueFromEvent: (e) => { if (Array.isArray(e)) { return e; } return e && e.fileList; } })(

支持扩展名:.rar .zip .doc .pdf .jpg .png

材料包括:合同,验收单,订单截图,打款记录

)}
: null }
) } } export default Form.create()(MakeBill);

转载于:https://www.cnblogs.com/nicholaswang/p/10799782.html

你可能感兴趣的:(Antd Upload 和 Antd Form 结合的踩坑记录)