This is the 30th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021

Hello ~ I’m Milo! I am building an open source interface testing platform from 0 to 1, and I am also writing a complete tutorial corresponding to it. I hope you can support it. Welcome to follow my public account Milo test diary, get the latest article tutorial!

review

In the previous section we wrote oss related CRUD interfaces, so in this section we will write a new page for managing OSS data.

What will be done is an extremely streamlined file management page.

rendering

Since I always write a piece of code and then write a tutorial, renderings are not a problem:

Images can be downloaded or deleted.

Write oss download interface

But let’s do the homework before we do that.

  • Write random methods to get file names

Depending on the name of the file passed in, pity’s shuffling order + current timestamp guarantees roughly 90 percent of file name conflicts.

  • Ali cloud to achieve the download file method

Call get_object_to_file and return the new file path.

  • Method of encapsulating downloaded files

  • Write an interface to download files
@router.get("/download")
async def download_oss_file(filepath: str) :
    """ Update oss file, path cannot change :param filepath: :return: ""
    try:
        client = OssClient.get_oss_client()
        # cut to get file name
        filename = filepath.split("/")[-1]
        path = client.download_file(filepath, filename)
        return PityResponse.file(path, filename)
    except Exception as e:
        return PityResponse.failed(F "Download failed:{e}")
Copy the code

Note: since file names in OSS are paths (directories), we split the file names.

See what happens when you download it

Front page section

Front page form that piece of nature is a traditional craft, do not need to say more.

Here are a few things to note:

  • Upload file form

    There is an Upload component in the Upload file form, which is quite special, so we need to Upload manually. I also stepped in the pit for a long time.

    Here is the source code:

Almost all of these are based on the antD official website examples, which Form.Item cover 2 layers, which is how the demo is written, I tried to drop one of them, but still not enough.

ValuePropName Specifies a fileList.

  • An HTTP request to upload a file

    Because the front-end does not use an HTTP request library such as AXIos, but umi-Request (its own encapsulation).

    So here’s how to use it:

So this is how you upload a file, the first thing you do is create a FormData object and append the file data into it.

The second key is to specify a requestType as a form, which I’ve been experimenting with for quite some time.

  • The download file

    Use window.open or the A TAB to link to our Download interface:

    window.open( CONFIG.URL/oss/download? filepath={CONFIG.URL}/oss/download? filepath=CONFIG.URL/oss/download? filepath={record.key})

  • All the code

import {PageContainer} from "@ant-design/pro-layout";
import {Button, Card, Col, Divider, Form, Input, Modal, Row, Table, Upload} from "antd";
import {InboxOutlined, PlusOutlined} from "@ant-design/icons";
import {CONFIG} from "@/consts/config";
import {useEffect, useState} from "react";
import {connect} from 'umi';
import moment from "moment";

const Oss = ({loading, dispatch, gconfig}) = > {

  const [form] = Form.useForm();
  const {ossFileList, searchOssFileList} = gconfig;
  const [visible, setVisible] = useState(false);
  const [value, setValue] = useState(' ');

  const onDeleteFile = key= > {
    dispatch({
      type: 'gconfig/removeOssFile'.payload: {
        filepath: key
      }
    })
  }

  const listFile = () = > {
    dispatch({
      type: 'gconfig/listOssFile'})},const columns = [
    {
      title: 'File path'.key: 'key'.dataIndex: 'key'.render: key= > <a href={` ${CONFIG.URL} /oss/download?filepath=${key}`} target="_blank">{key}</a>
    },
    {
      title: 'size'.key: 'size'.dataIndex: 'size'.render: size= > `The ${Math.round(size / 1024)}kb`
    },
    {
      title: 'Update Time'.key: 'last_modified'.dataIndex: 'last_modified'.render: lastModified= > moment(lastModified * 1000).subtract(moment().utcOffset() / 60 - 8.'hours').format('YYYY-MM-DD HH:mm:ss')}, {title: 'operation'.key: 'ops'.render: (record) = > <>
        <a onClick={()= >{ window.open(`${CONFIG.URL}/oss/download? Filepath = ${record. Key} `)}} > download</a>
        <Divider type="vertical"/>
        <a onClick={()= >{ onDeleteFile(record.key); }} > delete</a>
      </>},]const normFile = (e) = > {
    if (Array.isArray(e)) {
      return e;
    }
    return e && e.fileList;
  };

  const onUpload = async() = > {const values = await form.validateFields();
    const res = dispatch({
      type: 'gconfig/uploadFile'.payload: values,
    })
    if (res) {
      setVisible(false)
      setValue(' ')
      listFile();
    }
  }

  useEffect(() = > {
    if (value === ' ') {
      dispatch({
        type: 'gconfig/save'.payload: {searchOssFileList: ossFileList}
      })
    } else {
      dispatch({
        type: 'gconfig/save'.payload: {searchOssFileList: ossFileList.filter(v= > v.key.toLowerCase().indexOf(value.toLowerCase()) > -1)}
      })
    }
  }, [value])


  useEffect(() = > {
    listFile();
  }, [])


  return (
    <PageContainer title="OSS File Management" breadcrumb={false}>
      <Card>
        <Modal width={600} title="Upload file" visible={visible} onCancel={()= > setVisible(false)} onOk={onUpload}>
          <Form form={form} {. CONFIG.LAYOUT} >
            <Form.Item label="File path" name="filepath"
                       rules={[{required: true.message:'Please enter the path where the files are to be stored, separated by/'}]}>
              <Input placeholder="Please enter the path where the files will be stored, separated by slashes."/>
            </Form.Item>
            <Form.Item label="File" required>
              <Form.Item name="files" valuePropName="fileList" getValueFromEvent={normFile} noStyle
                         rules={[{required: true.message:'Please upload at least one file '}]}>
                <Upload.Dragger name="files" maxCount={1}>
                  <p className="ant-upload-drag-icon">
                    <InboxOutlined/>
                  </p>
                  <p className="ant-upload-text">Click or drag the file to this area to upload 🎉</p>
                </Upload.Dragger>
              </Form.Item>
            </Form.Item>
          </Form>
        </Modal>
        <Row gutter={[8, 8]} style={{marginBottom: 12}} >
          <Col span={6}>
            <Button type="primary" onClick={()= > setVisible(true)}><PlusOutlined/>Add files</Button>
          </Col>
          <Col span={12} />
          <Col span={6}>
            <Input placeholder="Enter the name of the file you are looking for." value={value} onChange={e= >{ setValue(e.target.value); }} / ></Col>
        </Row>
        <Table rowKey={record= > record.key} dataSource={searchOssFileList} columns={columns}
               loading={loading.effects['gconfig/listOssFile']}/>
      </Card>
    </PageContainer>)}export default connect(({loading, gconfig}) = > ({loading, gconfig}))(Oss);

Copy the code

This is the end of today’s content. Now we can manage our files through OSS, how can we use it?

In the next section, HTTP requests support file uploads.