springboot+antd实现多文件、文件夹上传下载

标题使用springboot+antd+vue3实现单/多文件、文件夹上传功能

1、先看看后端

先看看我的项目结构吧
在这里插入图片描述

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.7.10</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>fileUpload-Antd</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>fileUpload-Antd</name>
	<description>fileUpload-Antd</description>
	<properties>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
        <!--    引入sprinbgoot jpa    -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-jpa</artifactId>
		</dependency>
        <!--    引入sprinbgoot web启动器    -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
        <!--    引入热部署工具    -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>
        <!--    引入mysql驱动包    -->
		<dependency>
			<groupId>com.mysql</groupId>
			<artifactId>mysql-connector-j</artifactId>
			<scope>runtime</scope>
		</dependency>
        <!--    lombok包    -->
		<dependency>
			<groupId>org.projectlombok</groupId>
			<artifactId>lombok</artifactId>
			<optional>true</optional>
		</dependency>
        <!--    引入测试启动器(可有可无)   -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
				<configuration>
					<excludes>
						<exclude>
							<groupId>org.projectlombok</groupId>
							<artifactId>lombok</artifactId>
						</exclude>
					</excludes>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

配置application.yml文件

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/files
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
  servlet:
    multipart:
      max-file-size: 300MB
      max-request-size: 300MB
  devtools:
    restart:
      enabled: true  #设置开启热部署
      additional-paths: src/main/java #重启目录
      exclude: WEB-INF/**
  freemarker:
    cache: false    #页面不加载缓存,修改即时生效
  jpa:
    show-sql: true
    hibernate:
      naming: #命名转化策略 不做任何操作 直接返回数据库中的名称(不做驼峰转化)
        physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

file:
  location: D:/home/uploadfile/ #自定义上传文件本地保存路径
  path: /file/ #映射数据库中的文件路径

由于是前后端分离的项目,存在跨域问题,我这边就直接在后端解决跨域问题了,并且一并配置了路径映射问题(也就是数据库存入的文件路径和磁盘真实存储路径映射)
MyWebMVCConfig

package com.example.fileupload.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyWebMVCConfig implements WebMvcConfigurer{
  //处理数据库中路径和真实路径的映射问题
  @Override
  public void addResourceHandlers(ResourceHandlerRegistry registry){
      //匹配到resourceHandler,将URL映射至location,也就是本地文件夹
      registry.addResourceHandler("/file/**").addResourceLocations("file:///" + "D:/home/uploadfile/");//这里最后一个/不能不写
  }
  //处理跨域
  @Override
  public void addCorsMappings(CorsRegistry registry){
      registry.addMapping("/**")
//                .allowedOrigins("*") //浏览器允许所有的域访问 / 注意 * 不能满足带有cookie的访问,Origin 必须是全匹配
              .allowedOriginPatterns("*")
              .allowedMethods("*")
              .allowCredentials(true)  // 允许带cookie访问
              .allowedHeaders("token")
              .maxAge(3600);
  }
}

新建实体类Files,用于数据库的操作

package com.example.fileupload.entity;

import lombok.Data;

import javax.persistence.*;
import java.util.Date;

@Entity
@Table(name = "files",schema="files")
@Data
public class Files{
    @Id
    @Column(name = "fileId")
    private String FilesId;

    @Column(name = "fileName")
    private String fileName;

    @Column(name = "fileOriginalName")
    private String fileOriginalName;

    @Column(name = "fileSize")
    private Long fileSize;

    @Column(name = "fileType")
    private String fileType;

    @Column(name = "fileExd")
    private String fileExd;

    @Column(name = "filePath")
    private String filePath;

    @Column(name = "fileRealPath")
    private String fileRealPath;

    @Column(name = "cjr")
    private String cjr;

    @Column(name = "cjsj")
    @Temporal(TemporalType.TIMESTAMP)
    private Date cjsj;

    @Column(name = "scbz")
    private String scbz;
}

DAO层,与数据库交互FilesRepoistory

package com.example.fileupload.repository;

import com.example.fileupload.entity.Files;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface FilesRepoistory extends JpaRepository<Files,String>{}

我这边为了方便,没有写service层(其实也没用具体的业务逻辑,直接省略了)
UploadController

package com.example.fileupload.controller;

import com.example.fileupload.entity.Files;
import com.example.fileupload.repository.FilesRepoistory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import java.util.List;
import java.util.UUID;

@Controller
public class UploadController{
    @Value("${file.location}")
    private String location;
    @Value("${file.path}")
    private String path;

    @Autowired
    FilesRepoistory filesRepoistory;

    @RequestMapping("/list")
    @ResponseBody
    public List<Files> list(){
        List<Files> all = filesRepoistory.findAll();
        return all;
    }

    @RequestMapping("/uploadMultiple")
    @ResponseBody
    public String upm(HttpServletRequest httpRequest, @RequestParam("files") List<MultipartFile> files){
        String res = "fail";
        for(MultipartFile file : files){
            //获取当前上传文件名称
            String fileName = file.getOriginalFilename();
            System.out.println("文件名称:" + fileName);
            //使用UUID将其重命名
            String fileNameUU = UUID.randomUUID().toString();
            //截取类型并组合为新名称
            String fileNewName = fileNameUU + fileName.substring(fileName.indexOf('.'));
            String filePath=this.path+fileNewName;
            String fileRelPath=this.location + fileNewName;
            System.out.println("文件新名称:" + fileNewName);
            try{
                file.transferTo(new File(fileRelPath));
                Files files1 = new Files();
                files1.setFilesId(UUID.randomUUID().toString());
                files1.setFileName(fileNewName);
                files1.setFileOriginalName(fileName);
                files1.setFileSize(file.getSize());
                files1.setFileType(file.getContentType());
                files1.setFileExd(fileName.substring(fileName.indexOf('.')));
                files1.setFilePath(filePath);
                files1.setFileRealPath(fileRelPath);
                files1.setCjr("Junibl");
                files1.setCjsj(new Date());
                files1.setScbz("N");
                res="ok";
                this.filesRepoistory.save(files1);
            }catch(IOException e){
                e.printStackTrace();
            }
        }
        return res;
    }

    //上传单个文件
    @RequestMapping("/uploadSingle")
    @ResponseBody
    public String ups(HttpServletRequest httpRequest, @RequestParam("file") MultipartFile file){
        String res = "fail";
        //获取当前上传文件名称
        String fileName = file.getOriginalFilename();
        System.out.println("文件名称:" + fileName);
        //使用UUID将其重命名
        String fileNameUU = UUID.randomUUID().toString();
        //截取类型并组合为新名称
        String fileNewName = fileNameUU + fileName.substring(fileName.indexOf('.'));
        String filePath=this.path+fileNewName;
        String fileRelPath=this.location + fileNewName;
        System.out.println("文件新名称:" + fileNewName);
        try{
            file.transferTo(new File(fileRelPath));
            Files files1 = new Files();
            files1.setFilesId(UUID.randomUUID().toString());
            files1.setFileName(fileNewName);
            files1.setFileOriginalName(fileName);
            files1.setFileSize(file.getSize());
            files1.setFileType(file.getContentType());
            files1.setFileExd(fileName.substring(fileName.indexOf('.')));
            files1.setFilePath(filePath);
            files1.setFileRealPath(fileRelPath);
            files1.setCjr("Junibl");
            files1.setCjsj(new Date());
            files1.setScbz("N");
            res="ok";
            this.filesRepoistory.save(files1);
        }catch(IOException e){
            e.printStackTrace();
        }
        return res;
    }
}

其实上面的三个方法可以合并,我就懒得处理了

启动器FileUploadAntdApplication,这就没啥可说的了

package com.example.fileupload;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class FileUploadAntdApplication{

    public static void main(String[] args){
        SpringApplication.run(FileUploadAntdApplication.class, args);
    }
}

前端

前端要细讲还挺多的,但是离不开nodejs,按照官方给的文档新建项目就行
1、下载nodejs 安装,使用node -v查看是否安装成功(注意版本:我这边是16+)
在这里插入图片描述

2、安装pnpm 用于管理包,原生的npm浪费内存资源,使用pnpm -v查看是否安装成功(反正尽量都安装最新的就行)
在这里插入图片描述

3、去vue官网,按照教程安装vue,查看是否安装成功vue -V(其实指的是脚手架)
在这里插入图片描述
跟着教程创建项目

好了,进入教程安装依赖包:pnpm i ,等待即可

安装antd-vue:pnpm install ant-design-vue --save ,等待
安装axios:pnpm install axios,等待
安装qs(JSON处理的一个工具):pnpm i qs,继续等待,所有安装好了就差不多了

全局引入vue和antd,main.ts(我这边是加入了typescript,所以是main.ts)

import { createApp } from 'vue'
import App from './App.vue'
import 'ant-design-vue/dist/antd.css';
import Antd from "ant-design-vue";
import './assets/main.css'



const app=createApp(App)
app.use(Antd).mount('#app')
app.config.productionTip = false

我想偷懒,所以直接在app.vue上写东西了App.vue


<script setup lang="ts">
import axios, { type AxiosProgressEvent } from "axios";
import { ref } from "vue";

//上传进度

let pre=ref()
let preFolder=ref(0)
let preMul=ref(0)

const uploadMultifile = async (option: Request) => {
  const callBack=updateProcess
  const formData = new FormData()
  const fileUrl = "http://localhost:8080/uploadMultiple"
  formData.append("files", option.file)
  // console.log(option.file)
  let that=this
  axios.post(
    fileUrl,
    formData,
    {
      onUploadProgress:(progressEvent:AxiosProgressEvent)=>{
        // 处理原生进度事件
        // console.log(progressEvent)
        callBack && callBack(progressEvent,'mul')
      }
    }
  )
  .then((res)=>{
    // console.log('上传结果:',res)
    option.onSuccess(res.data, option)
  })
};

const uploadFolder =async (option: Request) => {
  const callBack=updateProcess
  const formData = new FormData()
  const fileUrl = "http://localhost:8080/uploadMultiple"
  formData.append("files", option.file)
  // console.log(option.file)
  let that=this
  axios.post(
    fileUrl,
    formData,
    {
      onUploadProgress:(progressEvent:AxiosProgressEvent)=>{
        // 处理原生进度事件
        // console.log(progressEvent)
        callBack && callBack(progressEvent,'folder')
      }
    }
  )
  .then((res)=>{
    // console.log('上传结果:',res)
    option.onSuccess(res.data, option)
  })
};

const uploadSingle = async (option: Request) => {
  const callBack=updateProcess
  const formData = new FormData()
  const fileUrl = "http://localhost:8080/uploadSingle"
  formData.append("file", option.file)

  axios.post(
    fileUrl,
    formData,
    {
      onUploadProgress:(progressEvent:AxiosProgressEvent)=>{
        // 处理原生进度事件
        // console.log(progressEvent)
        callBack && callBack(progressEvent,'single')
      }
    }
  )
  .then((res)=>{
    // console.log('上传结果:',res)
    option.onSuccess(res.data, option)
  })
}

//更新进度条
const updateProcess=function(progressEvent:AxiosProgressEvent,type: string):void{
  // console.log('progressEvent:',progressEvent)
  if(type=='folder'){
    preFolder.value=Math.floor(progressEvent.loaded/progressEvent.total*100)
  }else if(type=='single'){
    pre.value=Math.floor(progressEvent.loaded/progressEvent.total*100)
  }else if(type=='mul'){
    preMul.value=Math.floor(progressEvent.loaded/progressEvent.total*100)
  }
  
}
</script>

<template>
  <a-row type="flex">
    <a-col :span="8">
      上传文件夹:
      <a-upload directory :customRequest="uploadFolder">
        <a-button type="primary">上传文件夹 </a-button>
      </a-upload>
      <a-progress :percent="preFolder" status="active" />
    </a-col>
    <a-col :span="8">
      上传多个文件:
      <a-upload :multiple="true" :customRequest="uploadMultifile">
        <a-button type="primary">上传多文件 </a-button>
      </a-upload>
      <a-progress :percent="preMul" status="active" />
    </a-col>
    <a-col :span="8">
      上传单个文件:
      <a-upload :customRequest="uploadSingle" >
        <a-button type="primary">上传单个文件 </a-button>
      </a-upload>
      <a-progress :percent="pre" status="active" />
    </a-col>
  </a-row>
</template>
<style scoped>
</style>

好了基本OK了,来看看效果吧
在这里插入图片描述

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值