浏览代码

修改file上传文件

zhaojinyu 2 周之前
父节点
当前提交
683ad08f06

+ 17 - 1
base-modules/service-file/pom.xml

@@ -72,7 +72,23 @@
         </dependency>
         <dependency>
             <groupId>com.usky</groupId>
-            <artifactId>ruoyi-common-core</artifactId>
+            <artifactId>common-cloud-starter</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>com.usky</groupId>
+            <artifactId>ruoyi-common-swagger</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+            <version>2.1.4</version>
+        </dependency>
+        <dependency>
+            <groupId>mysql</groupId>
+            <artifactId>mysql-connector-java</artifactId>
+            <scope>runtime</scope>
         </dependency>
 
     </dependencies>

+ 42 - 5
base-modules/service-file/src/main/java/com/ruoyi/file/RuoYiFileApplication.java

@@ -1,21 +1,58 @@
 package com.ruoyi.file;
 
+import org.mybatis.spring.annotation.MapperScan;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
 import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
+import org.springframework.cloud.openfeign.EnableFeignClients;
+import org.springframework.context.ConfigurableApplicationContext;
+import org.springframework.context.annotation.ComponentScan;
+import org.springframework.context.annotation.EnableAspectJAutoProxy;
+import org.springframework.core.env.Environment;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 
 /**
  * 文件服务
  * 
  * @author ruoyi
  */
+//@EnableCustomSwagger2
+//@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
+//public class RuoYiFileApplication
+//{
+//    public static void main(String[] args)
+//    {
+//        SpringApplication.run(RuoYiFileApplication.class, args);
+//    }
+//}
+
+
 @EnableCustomSwagger2
-@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
+@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
+@EnableFeignClients(basePackages = {"com.ruoyi"})
+@MapperScan(value = "com.ruoyi.file.mapper")
+@ComponentScan(basePackages = {"com.ruoyi"})
+@SpringBootApplication
 public class RuoYiFileApplication
 {
-    public static void main(String[] args)
-    {
-        SpringApplication.run(RuoYiFileApplication.class, args);
+    private static final Logger LOGGER = LoggerFactory.getLogger(RuoYiFileApplication.class);
+
+    public static void main(String[] args) throws UnknownHostException {
+        ConfigurableApplicationContext application = SpringApplication.run(RuoYiFileApplication.class, args);
+        Environment env = application.getEnvironment();
+        String ip = InetAddress.getLocalHost().getHostAddress();
+        String port = env.getProperty("server.port");
+        String path = env.getProperty("server.servlet.context-path");
+        LOGGER.info("\n----------------------------------------------------------\n\t" +
+                "Application is running! Access URLs:\n\t" +
+                "Local: \t\thttp://localhost:" + port + (null==path?"":path) + "/\n\t" +
+                "External: \thttp://" + ip + ":" + port + (null==path?"":path) + "/\n\t" +
+                "Api: \t\thttp://" + ip + ":" + port + (null==path?"":path) + "/swagger-ui/index.html\n\t" +
+                "----------------------------------------------------------");
     }
-}
+}

+ 30 - 0
base-modules/service-file/src/main/java/com/ruoyi/file/controller/FilesController.java

@@ -0,0 +1,30 @@
+package com.ruoyi.file.controller;
+
+import com.ruoyi.file.service.FilesService;
+import com.usky.common.core.bean.ApiResult;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+
+@RestController
+@RequestMapping("/files")
+public class FilesController {
+
+    @Autowired
+    private FilesService filesService;
+
+    @PostMapping("/upload")
+    public ApiResult<String> upload(@RequestParam MultipartFile file) {
+        //获取上传文件
+        String url = filesService.upload(file);
+        return ApiResult.success(url);
+    }
+
+    @GetMapping("/{filesUUID}")
+    public void download(@PathVariable String filesUUID, HttpServletResponse response) {
+        //下载文件
+        filesService.download(filesUUID, response);
+    }
+}

+ 10 - 0
base-modules/service-file/src/main/java/com/ruoyi/file/mapper/FilesMapper.java

@@ -0,0 +1,10 @@
+package com.ruoyi.file.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ruoyi.file.service.Files;
+import org.apache.ibatis.annotations.Mapper;
+
+@Mapper
+public interface FilesMapper extends BaseMapper<Files> {
+
+}

+ 41 - 0
base-modules/service-file/src/main/java/com/ruoyi/file/service/Files.java

@@ -0,0 +1,41 @@
+package com.ruoyi.file.service;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableLogic;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+import java.util.Date;
+
+@Data
+@TableName("files")
+public class Files implements Serializable {
+    private Integer id;//编号
+
+    private String filesName;//文件名称
+
+    private String type;//文件类型
+
+    private Double size;//文件大小
+
+    private String url;//下载链接
+
+    private String md5;//文件MD5
+
+    private Boolean enable;//链接是否可用(1:是 0:否)
+
+    @TableField(fill = FieldFill.INSERT)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime createTime;//创建时间
+
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private LocalDateTime updateTime;//更新时间
+
+    @TableLogic()
+    private Integer isDelete;//是否删除(1:是 0:否)
+}

+ 14 - 0
base-modules/service-file/src/main/java/com/ruoyi/file/service/FilesService.java

@@ -0,0 +1,14 @@
+package com.ruoyi.file.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+
+public interface FilesService extends IService<Files> {
+    //上传文件
+    String upload(MultipartFile file);
+
+    //下载文件
+    void download(String filesUUID, HttpServletResponse response);
+}

+ 133 - 0
base-modules/service-file/src/main/java/com/ruoyi/file/service/FilesServiceImpl.java

@@ -0,0 +1,133 @@
+package com.ruoyi.file.service;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.file.mapper.FilesMapper;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.util.DigestUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.time.LocalDateTime;
+import java.util.List;
+import java.util.UUID;
+
+@Service
+public class FilesServiceImpl extends ServiceImpl<FilesMapper, Files> implements FilesService {
+    @Value("${file.path}")
+    private String filesUploadPath;//获取文件路径
+
+    @Value("${file.domain}")
+    private String filesUploadDomain;//文件域名
+
+    @Value("${file.prefix}")
+    private String filesPrefix;//文件前缀
+
+
+    @Override
+    public String upload(MultipartFile file) {
+        //将相对路径转化为绝对路径
+        String destPath = new File(filesUploadPath).getAbsolutePath();
+        //文件夹路径名称
+        String originalFilename = file.getOriginalFilename();
+        //文件大小
+        double size = file.getSize();
+        //文件类型
+        String type = originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase();
+
+        //使用uuid生成随机唯一值
+        String uuid = UUID.randomUUID().toString().replaceAll("-", "");
+        //新的文件名称,uuid+文件类型
+        String fileUuid = uuid + "." + type;
+        //新的文件地址,绝对路径+新的文件名称
+        File uploadFile = new File(destPath + "/" + fileUuid);
+
+        //判断配置的文件目录是否存在,若不存在则创建一个新的文件目录
+        File parentFile = uploadFile.getParentFile();
+        if (!parentFile.exists()) {
+            parentFile.mkdirs();
+        }
+
+        try {
+            String url;
+            //获取文件的md5,通过对比文件md5,防止上传相同内容的文件
+            String md5 = DigestUtils.md5DigestAsHex(file.getInputStream());
+            //通过MD5来查询文件
+            Files dbFiles = this.getFileByMD5(md5);
+            if (dbFiles != null) {//如果数据库存在相同文件,直接获取url
+                url = dbFiles.getUrl();
+            } else {//如果数据库不存在相同文件,先存储到本地磁盘,再设置文件url
+                file.transferTo(uploadFile);//把获取到的文件存储带磁盘目录
+                url = filesUploadDomain + filesPrefix + "/" + fileUuid;//设置文件url
+            }
+
+            //将文件存储到数据库
+            Files saveFile = new Files();
+            saveFile.setFilesName(originalFilename);
+            saveFile.setType(type);
+            saveFile.setSize(size / 1024);//(单位:KB)
+            saveFile.setUrl(url);
+            saveFile.setMd5(md5);
+            saveFile.setEnable(true);
+            saveFile.setCreateTime(LocalDateTime.now());
+            saveFile.setUpdateTime(null);
+            //保存操作
+            save(saveFile);
+
+            //返回文件下载路径url
+            return url;
+        } catch (IOException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+    //将文件以流的形式一次性读取到内存,通过响应输出流输出到前端
+    @Override
+    public void download(String filesUUID, HttpServletResponse response) {
+        try {
+            //根据文件的唯一标识码获取文件
+            File uploadFile = new File(filesUploadPath + filesUUID);
+
+            //读取文件的字节流
+            FileInputStream fileInputStream = new FileInputStream(uploadFile);
+            //将文件写入输入流
+            InputStream inputStream = new BufferedInputStream(fileInputStream);
+
+            byte[] buffer = new byte[inputStream.available()];
+            inputStream.read(buffer);
+            inputStream.close();
+
+
+            //attachment表示以附件方式下载 inline表示在线打开 "Content-Disposition: inline; filename=文件名.png"
+            //filename表示文件的默认名称,因为网络传输只支持URL编码的相关支付,因此需要将文件名URL编码后进行传输,前端收到后需要反编码才能获取到真正的名称
+            response.addHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(filesUUID, "UTF-8"));
+            response.setContentType("application/octet-stream");
+
+            //设置输出流的格式
+            ServletOutputStream os = response.getOutputStream();
+            os.write(buffer);
+
+            //关闭
+            fileInputStream.close();
+            os.flush();
+            os.close();
+        } catch (IOException e) {
+            e.printStackTrace();
+        }
+    }
+
+    //通过文件MD5查询文件
+    private Files getFileByMD5(String md5) {
+        //查找数据库是否已经存在一样的图片
+        QueryWrapper<Files> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("md5", md5);
+        List<Files> filesList = list(queryWrapper);
+        return filesList.size() == 0 ? null : filesList.get(0);
+    }
+}

+ 5 - 0
base-modules/service-file/src/main/resources/mapper.file/FilesMapper.xml

@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="com.ruoyi.file.mapper.FilesMapper">
+
+</mapper>