ant design 组件上传视频直传七牛云

发布时间: 2022-05-14 10:37:43 作者: 大象笔记

由于视频文件太大,不适合通过自己服务器中转一层,还是在前端直接传到七牛云合理。

文档

关于 token

token 上传凭证。

拉取 token 的时机

CreateForm 初始化的时候拉取一次足够了,不太可能在这个页面停留 1 小时以上。

但是感觉还是封装成组件比较好,否则多个页面这些配置还要改 N 个地方。

TODO

七牛云上传地址

ant design upload 组件,action 属性需要填写对应的上传地址。 而七牛云不同地区 Bucket 有不同的上传地址,参考这里:

https://developer.qiniu.com/kodo/1671/region-endpoint-fq

例如,华南地区是:

https://upload-z2.qiniup.com

七牛接口返回

{"hash":"FuxTlDmDSHGp1ijpBEOo9LNZJnti","key":"FuxTlDmDSHGp1ijpBEOo9LNZJnti"}

key 即文件名,默认是七牛后台自动生成的。还是替换成自己的规则比较好。 需要在上传的时候,通过 key 指定文件名。

视频上传组件

import React from 'react';
import { Form, Upload, message, Button } from 'antd';
import { UploadOutlined } from '@ant-design/icons';
import { uploadToken } from '@/services/ant-design-pro/api';


const QINIU_SERVER = 'https://upload-z2.qiniup.com';    // 华南地区

/**
 * 视频上传组件
 *
 * props 值列表:
 * - value: form 中的值。多个视频链接以英文逗号分隔
 * - max: 最多可以上传几个视频。max = 1 可上传一张,不设置则可上传无限多。
 **/
class QiniuUploadVideo extends React.Component {
  constructor(props) {
    super(props);
    let _state = {
      token: '',
      filePrefix: '',
      urlPrefix: '',
      fileList: [],
      max: this.props.max,
    };

    if (this.props.value) {
      let urls = this.props.value.split(",");
      let i = -1;
      for (let url of urls) {
        _state.fileList.push({
          uid: i + "",
          name: '视频',
          status: 'done',
          url: url,
        })
      }
    }

    this.state = _state;
  }

  async componentDidMount() {
    await this.init();
  }

  init = async () => {
    try {
      const data = await uploadToken();
      console.log(data);

      this.setState({
        token: data.uploadToken,
        filePrefix: data.filePrefix,
        urlPrefix: data.urlPrefix,
      });
    } catch (error) {
      message.error(error);
    }
  };

  handleChange = ({ file, fileList, event }) => {
    const { status, response } = file
    if (status === 'done') {
      // 上传成功
      const { key, hash } = response
      if (key) {
        message.success("上传成功")
        let imgs = [];
        for (let file2 of fileList) {
          if (file2.url) {
            imgs.push(file2.url);
          } else {
            imgs.push(this.state.urlPrefix + "/" + file2.response.key);
          }
        }
        // 调用父组件 onChange 方法, 将新值传递回去
        this.props.onChange(imgs.join(","))
      } else {
        message.error("上传失败")
      }
    }
    this.setState({ fileList })
  };

  getExtraData = file => {
    const { token, filePrefix } = this.state;

    return {
      token: token,
      key: filePrefix + "_" + file.name,
    };
  };

  render() {
    const uploadButton = (
        <Button icon={<UploadOutlined />}>点击上传视频</Button>
    );
    const props = {
      action: QINIU_SERVER,
      name: 'file',
      fileList: this.state.fileList,
      //listType: "picture-card",
      onChange: this.handleChange,
      data: this.getExtraData,
    };
    return (
      <Upload {...props}>
          {(this.state.max && this.state.fileList.length >= this.state.max) ? null : uploadButton}
      </Upload>
    );
  }
}

export default QiniuUploadVideo;
我是一名山东烟台的开发者,联系作者