测试平台系列——编写oss管理页面

news2024/9/21 2:44:59

上一节我们编写好了oss相关的crud接口,那这一节我们就得为oss数据的管理编写一个新的页面了。

即将做的是一个极度精简的文件管理页面。

效果图
因为我每次都是写完一段代码,然后编写对应教程,所以效果图这种东西自然是不在话下:

图片可以点击下载,也可以删除。

编写oss下载接口

在此之前还是先搞定下之前的作业。

  • 编写随机获取文件名的方法

根据传入的文件名,配合pity的打乱顺序+当前时间戳,基本可以保证百分之90的文件名冲突问题。

  • 实现阿里云的下载文件方法

调用get_object_to_file即可,并返回新的文件路径。

  • 封装下载文件的方法
  • 编写下载文件接口
@router.get("/download")
async def download_oss_file(filepath: str):
    """
    更新oss文件,路径不能变化
    :param filepath:
    :return:
    """
    try:
        client = OssClient.get_oss_client()
        # 切割获取文件名
        filename = filepath.split("/")[-1]
        path = client.download_file(filepath, filename)
        return PityResponse.file(path, filename)
    except Exception as e:
        return PityResponse.failed(f"下载失败: {e}")

注意: 由于oss里面的文件名都是带路径的(目录),所以我们split一下取出文件名。

看看下载的效果
前端页面部分

前端页面表格那块自然是传统手艺,不需要多说了。

值得注意的是下面这几个地方:

  • 上传文件表单
    上传文件表单里面有个Upload组件,这个比较特殊,我们需要手动上传,我也踩了很久的坑。

这里附上源码:

这些几乎都是根据antd官网的例子来的,其中Form.Item套了2层,demo就是这么写的,我试了下去掉一个还不行。

valuePropName固定要是fileList。

上传文件的http请求

由于前端未使用axios这样的http请求库,而是umi-request(自己封装的)。

所以这边还是说明一下怎么使用:

这是文件上传的方法,第一是要制造FormData对象,并把文件数据append进去。

第二个关键就是requestType要指定为form,这2点我摸索了挺久。

下载文件

用window.open或者a标签链接到我们的download接口接口:

window.open( C O N F I G . U R L / o s s / d o w n l o a d ? f i l e p a t h = {CONFIG.URL}/oss/download?filepath= CONFIG.URL/oss/download?filepath={record.key})

全部代码

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: '文件路径',
      key: 'key',
      dataIndex: 'key',
      render: key => <a href={`${CONFIG.URL}/oss/download?filepath=${key}`} target="_blank">{key}</a>
    },
    {
      title: '大小',
      key: 'size',
      dataIndex: 'size',
      render: size => `${Math.round(size / 1024)}kb`
    },
    {
      title: '更新时间',
      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: '操作',
      key: 'ops',
      render: (record) => <>
        <a onClick={() => {
          window.open(`${CONFIG.URL}/oss/download?filepath=${record.key}`)
        }}>下载</a>
        <Divider type="vertical"/>
        <a onClick={() => {
          onDeleteFile(record.key);
        }}>删除</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文件管理" breadcrumb={false}>
      <Card>
        <Modal width={600} title="上传文件" visible={visible} onCancel={() => setVisible(false)} onOk={onUpload}>
          <Form form={form} {...CONFIG.LAYOUT}>
            <Form.Item label="文件路径" name="filepath"
                       rules={[{required: true, message: '请输入文件要存储的路径, 目录用/隔开'}]}>
              <Input placeholder="请输入文件要存储的路径, 目录用/隔开"/>
            </Form.Item>
            <Form.Item label="文件" required>
              <Form.Item name="files" valuePropName="fileList" getValueFromEvent={normFile} noStyle
                         rules={[{required: true, message: '请至少上传一个文件'}]}>
                <Upload.Dragger name="files" maxCount={1}>
                  <p className="ant-upload-drag-icon">
                    <InboxOutlined/>
                  </p>
                  <p className="ant-upload-text">点击或拖拽文件到此区域上传

最后:下方这份完整的软件测试视频学习教程已经整理上传完成,朋友们如果需要可以自行免费领取 【保证100%免费】

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/343616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

更改SAP GUI登录界面信息

在SAP GUI的登录界面&#xff0c;左部输入登录信息如客户端、用户名、密码等&#xff0c;右部空余部分可维护一些登录信息文本&#xff0c;如登录的产品、客户端说明及注意事项等&#xff0c;此项操作详见SAP Notes 205487 – Own text on SAPGui logon screen 维护文档使用的…

从春节后央行的首批罚单,看金融反欺诈反洗钱的复杂性

目录 个人信息保护的问题 征信管理的问题 反洗钱与反欺诈的问题 金融欺诈愈加复杂多变 金融机构如何增强反欺诈反洗钱 春节后&#xff0c;央行公示首批罚单。其中&#xff0c;厦门银行被中国人民银行福州中心支行给予警告&#xff0c;并没收违法所得767.17元&#xff0c;处…

30个HTML+CSS前端开发案例(五)

30个HTMLCSS前端开发案例&#xff08;21-25&#xff09;本人说明全屏加载动画效果代码实现效果吃豆豆动画效果代码实现效果鼠标悬停3D翻转效果代码实现效果3D旋转木马效果代码实现效果flex弹性布局-酷狗音乐播放列表代码实现效果资源包本人说明 本专栏为记录博主的毕业设计而开…

论文阅读 | Restormer: Efficient Transformer for High-Resolution Image Restoration

前言&#xff1a;CVPR2022oral 用transformer应用到low-level任务 Restormer: Efficient Transformer for High-Resolution Image Restoration 引言 low-level task 如deblurring\denoising\dehazing等任务多是基于CNN做的&#xff0c;这样的局限性有二&#xff1a; 第一是卷…

文献综述,参考文献引用

知网完成文献综述 点击已选&#xff1a; 点导出题录 点自定义&#xff0c;点摘要&#xff0c;点预览 复制到剪切板 参考文献如何在论文中标注引用 国内外研究综述 简单介绍主题和所用理论&#xff0c;用第一段写综述的总结。 【 ...作...在西方国家已经有...多年的历史&…

基于应力的拓扑优化的高效3D灵敏度分析代码(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【FFMPEG源码分析】从ffplay源码摸清ffmpeg框架(三)

从ffplay源码分析这篇文章中可以知道int stream_component_open(VideoState *is, int stream_index)函数是创建和初始化decoder的入口。本篇文章从此入口看下ffmpeg中decoder的内部结构是什么样子。 同样先提出几个问题&#xff0c;带着问题梳理源码&#xff0c;效率贼快啊 ff…

Linux(Linux的连接使用)

连接Linux我们一般使用CRT或者Xshell工具进行连接使用。 如CRT使用SSH的方式 输出主机&#xff0c;账户&#xff0c;密码那些就可以连接上了。 Linux系统是一个文件型操作系统&#xff0c;有一句话说Linux的一切皆是文件。Linux系统的启动大致有下面几个步骤 Linux系统有7个运…

excel应用技巧:如何用函数制作简易抽奖动图

利用INDEX函数和随机整数函数RANDBETWEEN配合&#xff0c;在Excel中做一个简单的抽奖器&#xff0c;可以随机抽取姓名或者奖品。有兴趣的伙伴可以做出来试试&#xff0c;撞撞2023年好运气。每次年会大家最期待的就是抽奖环节。为了看看自己今年运气怎么样&#xff0c;会不会获奖…

中国版ChatGPT来了! 如何解读ChatGPT将带来的技术变革

最近这段时间&#xff0c;ChatGPT真的是太火了&#xff01;各平台都在铺天盖地式的宣传&#xff0c;相信在这么些天的宣传中&#xff0c;大家也对ChatGPT有了一个大概的了解&#xff0c;我们这边也就简单介绍一下。据ChatGPT自我介绍&#xff0c;它是一款预训练语言模型&#x…

ContextCapture Master 倾斜摄影测量实景三维建模技术

ContextCapture实景建模大师是一套无需人工干预&#xff0c;通过影像自动生成高分辨率的三维模型的软件解决方案。它集合了全球最先进数字影像处理、计算机虚拟现实以及计算机几何图形算法&#xff0c;在易用性、数据兼容性、运算性能、友好的人机交互及自由的硬件配置兼容性等…

Java设计模式-02工厂模式

为什么需要工厂模式&#xff0c;其作用什么&#xff1f;如何实现&#xff0c;代码演示解析优缺点。Q1:为什么需要工厂模式&#xff1f;工厂模式的作用(优点)是什么&#xff1f; 解耦。把对象的创建和使用的过程分开。就是Class A 想调用 Class B &#xff0c;那么A只是调用B的…

安装jdk8

目录标题一、下载地址&#xff08;一&#xff09;Linux下载&#xff08;二&#xff09;Win下载二、安装&#xff08;一&#xff09;Linux&#xff08;二&#xff09;Win三、卸载&#xff08;一&#xff09;Linux&#xff08;二&#xff09;Win一、下载地址 jdk8最新版 jdk8其他…

Tessent Mbist(5) 并行static Retention(静态保持)测试

本章描述当嵌入存储器被不同的memory BIST控制器所测试或者被不同的memory BIST controller steps按顺序进行测试时如何进行retention测试. 在跑PSRT(parallel static retention testing)之前,建议先跑BIST in HWDefault 或者 RunTimeProg 模式去保证有足够高的fault覆盖率;PSR…

iOS 奔溃EXC_BAD_ACCESS(KERN_INVALID_ADDRESS)分析

EXC_BAD_ACCESS (KERN_INVALID_ADDRESS)是一种常见的iOS应用程序崩溃错误&#xff0c;可能有以下原因&#xff1a; 尝试访问已释放的对象&#xff1a;即使是一个引用计数为0的对象&#xff0c;尝试访问它将导致崩溃。 尝试访问不正确的内存地址&#xff1a;例如&#xff0c;尝…

SpringBoot+Vue实现养老智慧服务平台

文末获取源码 开发语言&#xff1a;Java 框架&#xff1a;springboot JDK版本&#xff1a;JDK1.8 服务器&#xff1a;tomcat7 数据库&#xff1a;mysql 5.7/8.0 数据库工具&#xff1a;Navicat11 开发软件&#xff1a;eclipse/myeclipse/idea Maven包&#xff1a;Maven3.3.9 浏…

高姿态下的面部表情识别系统

效果展示&#xff1a; python表情、性别识别面部表情识别 (FER) 在计算机安全、神经科学、心理学和工程学方面有大量应用。由于其非侵入性&#xff0c;它被认为是打击犯罪的有用技术。然而&#xff0c;FER 面临着几个挑战&#xff0c;其中最严重的是它在严重的头部姿势下的预测…

浅谈二维数组元素的地址

一维数组元素的地址大家都比较容易理解&#xff0c;但对于二维数组&#xff0c;就很容易搞混了.今天我又被这个问题给弄糊涂了&#xff0c;翻了翻老谭的书本&#xff0c;对这个问题有了更深的认识. 首先给出一个二维数组a&#xff0c;它的定义为: int a[3][4] {{1,3,5,7}, {9,…

同花顺2023届春招内推

同花顺2023届春招开始啦&#xff01; 同花顺是国内首家上市的互联网金融信息服务平台&#xff0c;如果你对互联网金融感兴趣&#xff0c;如果你有志向在人工智能方向发挥所长&#xff0c;如果你也是一个激情澎湃的小伙伴&#xff0c;欢迎加入我们&#xff01;岗位类别&#xf…

企业级信息系统开发学习笔记1.1 初探Spring——采用Spring配置文件管理Bean

文章目录零、本讲学习目标一、Web开发技术二、Spring框架&#xff08;一&#xff09;Spring官网&#xff08;二&#xff09;Spring框架优点&#xff08;三&#xff09;为什么要选择Spring&#xff1f;&#xff08;四&#xff09; Spring框架因何而来&#xff08;五&#xff09;…