浏览代码

增加文件上传

gjs 4 年之前
父节点
当前提交
b334118e9b

+ 74 - 0
src/main/java/com/macro/mall/tiny/common/util/FileUtils.java

@@ -0,0 +1,74 @@
+package com.macro.mall.tiny.common.util;
+
+
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.*;
+import java.util.UUID;
+
+/**
+ * 文件操作工具类
+ */
+public class FileUtils {
+
+    /**
+     * 写入文件
+     * @param target
+     * @param src
+     * @throws IOException
+     */
+    public static void write(String target, InputStream src) throws IOException {
+        OutputStream os = new FileOutputStream(target);
+        byte[] buf = new byte[1024];
+        int len;
+        while (-1 != (len = src.read(buf))) {
+            os.write(buf,0,len);
+        }
+        os.flush();
+        os.close();
+    }
+
+    /**
+     * 分块写入文件
+     * @param target
+     * @param targetSize
+     * @param src
+     * @param srcSize
+     * @param chunks
+     * @param chunk
+     * @throws IOException
+     */
+    public static void writeWithBlok(String target, Long targetSize, InputStream src, Long srcSize, Integer chunks, Integer chunk) throws IOException {
+        RandomAccessFile randomAccessFile = new RandomAccessFile(target,"rw");
+        randomAccessFile.setLength(targetSize);
+        if (chunk == chunks - 1 && chunk != 0) {
+            randomAccessFile.seek(chunk * (targetSize - srcSize) / chunk);
+        } else {
+            randomAccessFile.seek(chunk * srcSize);
+        }
+        byte[] buf = new byte[1024];
+        int len;
+        while (-1 != (len = src.read(buf))) {
+            randomAccessFile.write(buf,0,len);
+        }
+        randomAccessFile.close();
+    }
+
+    /**
+     * 生成随机文件名
+     * @return
+     */
+    public static String generateFileName() {
+        return UUID.randomUUID().toString();
+    }
+
+    /**
+     * 获取文件扩展名
+     * @param file
+     * @return
+     */
+    public static String getExt(MultipartFile file) {
+        String fileName = file.getOriginalFilename();
+        return fileName.substring(fileName.lastIndexOf(".") + 1);
+    }
+}

+ 96 - 0
src/main/java/com/macro/mall/tiny/common/util/UploadUtils.java

@@ -0,0 +1,96 @@
+package com.macro.mall.tiny.common.util;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import static com.macro.mall.tiny.common.util.FileUtils.generateFileName;
+
+
+/**
+ * 分块上传工具类
+ */
+public class UploadUtils {
+
+    private static final Map<String, Value> chunkMap = new HashMap<>();
+
+    /**
+     * 内部类记录分块上传文件信息
+     */
+    private static class Value {
+        String name;
+        boolean[] status;
+
+        Value(int n) {
+            this.name = generateFileName();
+            this.status = new boolean[n];
+        }
+    }
+
+
+    /**
+     * 判断文件所有分块是否已上传
+     *
+     * @param key
+     * @return
+     */
+    public static boolean isUploaded(String key) {
+        if (isExist(key)) {
+            for (boolean b : chunkMap.get(key).status) {
+                if (!b) {
+                    return false;
+                }
+            }
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 判断文件是否有分块已上传
+     *
+     * @param key
+     * @return
+     */
+    private static boolean isExist(String key) {
+        return chunkMap.containsKey(key);
+    }
+
+    /**
+     * 为文件添加上传分块记录
+     *
+     * @param key
+     * @param chunk
+     */
+    public static void addChunk(String key, int chunk) {
+        chunkMap.get(key).status[chunk] = true;
+    }
+
+    /**
+     * 从map中删除键为key的键值对
+     *
+     * @param key
+     */
+    public static void removeKey(String key) {
+        if (isExist(key)) {
+            chunkMap.remove(key);
+        }
+    }
+
+    /**
+     * 获取随机生成的文件名
+     *
+     * @param key
+     * @param chunks
+     * @return
+     */
+    public static String getFileName(String key, int chunks) {
+        if (!isExist(key)) {
+            synchronized (UploadUtils.class) {
+                if (!isExist(key)) {
+                    chunkMap.put(key, new Value(chunks));
+                }
+            }
+        }
+        return chunkMap.get(key).name;
+    }
+}

+ 21 - 0
src/main/java/com/macro/mall/tiny/config/UploadConfig.java

@@ -0,0 +1,21 @@
+package com.macro.mall.tiny.config;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class UploadConfig {
+
+    public static String path;
+    public static String tempPath;
+
+    @Value("${upload.path}")
+    public void setPath(String path) {
+        UploadConfig.path = path;
+    }
+
+    @Value("${upload.temp-path}")
+    public void setTempPath(String path) {
+        UploadConfig.tempPath = path;
+    }
+}

+ 46 - 0
src/main/java/com/macro/mall/tiny/modules/business/controller/BigFileUploadController.java

@@ -0,0 +1,46 @@
+package com.macro.mall.tiny.modules.business.controller;
+
+import com.macro.mall.tiny.modules.business.service.FileService;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.CrossOrigin;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
+/**
+ * 大文件上传
+ */
+@RestController
+@RequestMapping("/file")
+@CrossOrigin
+@Api(tags = "文件上传相关接口", description = "提供文件上传相关API")
+public class BigFileUploadController {
+    @Autowired
+    private FileService fileService;
+
+
+    /**
+     * @param size
+     * @param chunks 文件分块数
+     * @param chunk  文件分块序号
+     * @param file   文件
+     * @throws IOException
+     */
+    @ApiOperation("文件上传接口")
+    @PostMapping("/upload")
+    public void upload(Long size,
+                       Integer chunks,
+                       Integer chunk,
+                       MultipartFile file) throws IOException {
+        if (chunks != null && chunks != 0) {
+            fileService.uploadWithBlock(size, chunks, chunk, file);
+        } else {
+            fileService.upload(file);
+        }
+    }
+}

+ 6 - 0
src/main/java/com/macro/mall/tiny/modules/business/model/BTower.java

@@ -4,6 +4,8 @@ import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.annotation.IdType;
 import com.baomidou.mybatisplus.annotation.TableId;
 import java.io.Serializable;
+import java.math.BigDecimal;
+
 import io.swagger.annotations.ApiModel;
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
@@ -41,5 +43,9 @@ public class BTower implements Serializable {
     @ApiModelProperty(value = "线路ID")
     private Integer lineId;
 
+    @ApiModelProperty(value = "经度")
+    private BigDecimal lon;
 
+    @ApiModelProperty(value = "纬度")
+    private BigDecimal lat;
 }

+ 17 - 0
src/main/java/com/macro/mall/tiny/modules/business/service/FileService.java

@@ -0,0 +1,17 @@
+package com.macro.mall.tiny.modules.business.service;
+
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
+
+/**
+ * @author gjs
+ * @description
+ * @date 2021/3/24 23:47
+ */
+public interface FileService {
+
+    void upload(MultipartFile file) throws IOException;
+
+    void uploadWithBlock(Long size, Integer chunks, Integer chunk, MultipartFile file) throws IOException;
+}

+ 52 - 0
src/main/java/com/macro/mall/tiny/modules/business/service/impl/FileServiceImpl.java

@@ -0,0 +1,52 @@
+package com.macro.mall.tiny.modules.business.service.impl;
+
+import com.macro.mall.tiny.common.util.FileUtils;
+import com.macro.mall.tiny.config.UploadConfig;
+import com.macro.mall.tiny.modules.business.service.FileService;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Date;
+
+import static com.macro.mall.tiny.common.util.UploadUtils.*;
+
+
+/**
+ * 文件上传服务
+ */
+@Service
+public class FileServiceImpl implements FileService {
+
+    /**
+     * 上传文件
+     *
+     * @param file
+     */
+    public void upload(MultipartFile file) throws IOException {
+        String path = UploadConfig.path + file.getOriginalFilename();
+        FileUtils.write(path, file.getInputStream());
+    }
+
+    /**
+     * 分块上传文件
+     *
+     * @param size
+     * @param chunks
+     * @param chunk
+     * @param file
+     * @throws IOException
+     */
+    public void uploadWithBlock(Long size,
+                                Integer chunks,
+                                Integer chunk,
+                                MultipartFile file) throws IOException {
+        String fileName = file.getOriginalFilename();
+        FileUtils.writeWithBlok(UploadConfig.tempPath + fileName, size, file.getInputStream(), file.getSize(), chunks, chunk);
+        addChunk(fileName, chunk);
+        if (isUploaded(fileName)) {
+            removeKey(fileName);
+        }
+    }
+}

+ 8 - 0
src/main/resources/application.yml

@@ -6,6 +6,10 @@ spring:
     name: power-system
   profiles:
     active: dev
+  servlet:
+    multipart:
+      max-file-size: 10737418240
+      max-request-size: 10737418240
 
 mybatis-plus:
   mapper-locations: classpath:/mapper/**/*.xml
@@ -50,3 +54,7 @@ secure:
       - /admin/register
       - /admin/info
       - /admin/logout
+
+upload:
+  temp-path: ./temp/
+  path: ./upload/ #文件上传路径

+ 9 - 2
src/main/resources/mapper/business/BLineMapper.xml

@@ -9,7 +9,9 @@
                t.name          t_name,
                t.shape         t_shape,
                t.hardware_type t_hardware_type,
-               t.line_id       t_line_id
+               t.line_id       t_line_id,
+               t.lon           t_lon,
+               t.lat           t_lat
         FROM b_line l
                  LEFT JOIN b_tower t ON l.id = t.line_id;
     </select>
@@ -21,7 +23,9 @@
                t.name          t_name,
                t.shape         t_shape,
                t.hardware_type t_hardware_type,
-               t.line_id       t_line_id
+               t.line_id       t_line_id,
+               t.lon           t_lon,
+               t.lat           t_lat
         FROM b_line l
                  LEFT JOIN b_tower t ON l.id = t.line_id
                  LEFT JOIN b_province p on l.province_id = p.id
@@ -40,6 +44,9 @@
             <result column="t_shape" property="shape"/>
             <result column="t_hardware_type" property="hardwareType"/>
             <result column="t_line_id" property="lineId"/>
+            <result column="t_line_id" property="lineId"/>
+            <result column="t_lon" property="lon"/>
+            <result column="t_lat" property="lat"/>
         </collection>
     </resultMap>