Explorar el Código

文件系统模块代码提交

kouchengxing hace 4 años
padre
commit
4225299f70
Se han modificado 29 ficheros con 1394 adiciones y 15 borrados
  1. 29 0
      dgtis-api/dgtis-api-system/src/main/java/com/dgtis/system/api/RemoteFileService.java
  2. 50 0
      dgtis-api/dgtis-api-system/src/main/java/com/dgtis/system/api/domain/SysFile.java
  3. 35 0
      dgtis-api/dgtis-api-system/src/main/java/com/dgtis/system/api/factory/RemoteFileFallbackFactory.java
  4. 4 0
      dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/constant/ServiceNameConstants.java
  5. 20 0
      dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/exception/file/FileException.java
  6. 16 0
      dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/exception/file/FileNameLengthLimitExceededException.java
  7. 16 0
      dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/exception/file/FileSizeLimitExceededException.java
  8. 82 0
      dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/exception/file/InvalidExtensionException.java
  9. 77 0
      dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/utils/file/FileTypeUtils.java
  10. 124 10
      dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/utils/file/FileUtils.java
  11. 87 0
      dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/utils/file/ImageUtils.java
  12. 59 0
      dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/utils/file/MimeTypeUtils.java
  13. 84 0
      dgtis-modules/dgtis-modules-file/pom.xml
  14. 31 0
      dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/DgtisFileApplication.java
  15. 82 0
      dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/config/MinioConfig.java
  16. 36 0
      dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/config/ResourcesConfig.java
  17. 48 0
      dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/controller/SysFileController.java
  18. 42 0
      dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/service/FastDfsSysFileServiceImpl.java
  19. 20 0
      dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/service/ISysFileService.java
  20. 50 0
      dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/service/LocalSysFileServiceImpl.java
  21. 45 0
      dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/service/MinioSysFileServiceImpl.java
  22. 197 0
      dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/utils/FileUploadUtils.java
  23. 10 0
      dgtis-modules/dgtis-modules-file/src/main/resources/banner.txt
  24. 31 0
      dgtis-modules/dgtis-modules-file/src/main/resources/bootstrap.yml
  25. 74 0
      dgtis-modules/dgtis-modules-file/src/main/resources/logback.xml
  26. 0 0
      dgtis-modules/dgtis-modules-file/src/main/resources/minio.properties
  27. 43 5
      dgtis-modules/dgtis-modules-system/src/main/java/com/dgtis/system/controller/SysProfileController.java
  28. 1 0
      dgtis-modules/pom.xml
  29. 1 0
      pom.xml

+ 29 - 0
dgtis-api/dgtis-api-system/src/main/java/com/dgtis/system/api/RemoteFileService.java

@@ -0,0 +1,29 @@
+package com.dgtis.system.api;
+
+import com.dgtis.common.core.constant.ServiceNameConstants;
+import com.dgtis.common.core.domain.R;
+import com.dgtis.system.api.domain.SysFile;
+import com.dgtis.system.api.factory.RemoteFileFallbackFactory;
+import org.springframework.cloud.openfeign.FeignClient;
+import org.springframework.http.MediaType;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RequestPart;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 文件服务
+ * 
+ * @author ruoyi
+ */
+@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.FILE_SERVICE, fallbackFactory = RemoteFileFallbackFactory.class)
+public interface RemoteFileService
+{
+    /**
+     * 上传文件
+     *
+     * @param file 文件信息
+     * @return 结果
+     */
+    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
+    public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file);
+}

+ 50 - 0
dgtis-api/dgtis-api-system/src/main/java/com/dgtis/system/api/domain/SysFile.java

@@ -0,0 +1,50 @@
+package com.dgtis.system.api.domain;
+
+import org.apache.commons.lang3.builder.ToStringBuilder;
+import org.apache.commons.lang3.builder.ToStringStyle;
+
+/**
+ * 文件信息
+ * 
+ * @author ruoyi
+ */
+public class SysFile
+{
+    /**
+     * 文件名称
+     */
+    private String name;
+
+    /**
+     * 文件地址
+     */
+    private String url;
+
+    public String getName()
+    {
+        return name;
+    }
+
+    public void setName(String name)
+    {
+        this.name = name;
+    }
+
+    public String getUrl()
+    {
+        return url;
+    }
+
+    public void setUrl(String url)
+    {
+        this.url = url;
+    }
+
+    @Override
+    public String toString() {
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
+            .append("name", getName())
+            .append("url", getUrl())
+            .toString();
+    }
+}

+ 35 - 0
dgtis-api/dgtis-api-system/src/main/java/com/dgtis/system/api/factory/RemoteFileFallbackFactory.java

@@ -0,0 +1,35 @@
+package com.dgtis.system.api.factory;
+
+import com.dgtis.common.core.domain.R;
+import com.dgtis.system.api.RemoteFileService;
+import com.dgtis.system.api.domain.SysFile;
+import feign.hystrix.FallbackFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Component;
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 文件服务降级处理
+ * 
+ * @author ruoyi
+ */
+@Component
+public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileService>
+{
+    private static final Logger log = LoggerFactory.getLogger(RemoteFileFallbackFactory.class);
+
+    @Override
+    public RemoteFileService create(Throwable throwable)
+    {
+        log.error("文件服务调用失败:{}", throwable.getMessage());
+        return new RemoteFileService()
+        {
+            @Override
+            public R<SysFile> upload(MultipartFile file)
+            {
+                return R.fail("上传文件失败:" + throwable.getMessage());
+            }
+        };
+    }
+}

+ 4 - 0
dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/constant/ServiceNameConstants.java

@@ -16,4 +16,8 @@ public class ServiceNameConstants
      * 系统模块的serviceid
      */
     public static final String SYSTEM_SERVICE = "dgtis-system";
+    /**
+     * 文件服务的serviceid
+     */
+    public static final String FILE_SERVICE = "ruoyi-file";
 }

+ 20 - 0
dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/exception/file/FileException.java

@@ -0,0 +1,20 @@
+package com.dgtis.common.core.exception.file;
+
+
+import com.dgtis.common.core.exception.BaseException;
+
+/**
+ * 文件信息异常类
+ * 
+ * @author ruoyi
+ */
+public class FileException extends BaseException
+{
+    private static final long serialVersionUID = 1L;
+
+    public FileException(String code, Object[] args)
+    {
+        super("file", code, args, null);
+    }
+
+}

+ 16 - 0
dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/exception/file/FileNameLengthLimitExceededException.java

@@ -0,0 +1,16 @@
+package com.dgtis.common.core.exception.file;
+
+/**
+ * 文件名称超长限制异常类
+ * 
+ * @author ruoyi
+ */
+public class FileNameLengthLimitExceededException extends FileException
+{
+    private static final long serialVersionUID = 1L;
+
+    public FileNameLengthLimitExceededException(int defaultFileNameLength)
+    {
+        super("upload.filename.exceed.length", new Object[] { defaultFileNameLength });
+    }
+}

+ 16 - 0
dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/exception/file/FileSizeLimitExceededException.java

@@ -0,0 +1,16 @@
+package com.dgtis.common.core.exception.file;
+
+/**
+ * 文件名大小限制异常类
+ * 
+ * @author ruoyi
+ */
+public class FileSizeLimitExceededException extends FileException
+{
+    private static final long serialVersionUID = 1L;
+
+    public FileSizeLimitExceededException(long defaultMaxSize)
+    {
+        super("upload.exceed.maxSize", new Object[] { defaultMaxSize });
+    }
+}

+ 82 - 0
dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/exception/file/InvalidExtensionException.java

@@ -0,0 +1,82 @@
+package com.dgtis.common.core.exception.file;
+
+import org.apache.commons.fileupload.FileUploadException;
+
+import java.util.Arrays;
+
+/**
+ * 文件上传 误异常类
+ * 
+ * @author ruoyi
+ */
+public class InvalidExtensionException extends FileUploadException
+{
+    private static final long serialVersionUID = 1L;
+
+    private String[] allowedExtension;
+    private String extension;
+    private String filename;
+
+    public InvalidExtensionException(String[] allowedExtension, String extension, String filename)
+    {
+        super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]");
+        this.allowedExtension = allowedExtension;
+        this.extension = extension;
+        this.filename = filename;
+    }
+
+    public String[] getAllowedExtension()
+    {
+        return allowedExtension;
+    }
+
+    public String getExtension()
+    {
+        return extension;
+    }
+
+    public String getFilename()
+    {
+        return filename;
+    }
+
+    public static class InvalidImageExtensionException extends InvalidExtensionException
+    {
+        private static final long serialVersionUID = 1L;
+
+        public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
+        {
+            super(allowedExtension, extension, filename);
+        }
+    }
+
+    public static class InvalidFlashExtensionException extends InvalidExtensionException
+    {
+        private static final long serialVersionUID = 1L;
+
+        public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
+        {
+            super(allowedExtension, extension, filename);
+        }
+    }
+
+    public static class InvalidMediaExtensionException extends InvalidExtensionException
+    {
+        private static final long serialVersionUID = 1L;
+
+        public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
+        {
+            super(allowedExtension, extension, filename);
+        }
+    }
+    
+    public static class InvalidVideoExtensionException extends InvalidExtensionException
+    {
+        private static final long serialVersionUID = 1L;
+
+        public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename)
+        {
+            super(allowedExtension, extension, filename);
+        }
+    }
+}

+ 77 - 0
dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/utils/file/FileTypeUtils.java

@@ -0,0 +1,77 @@
+package com.dgtis.common.core.utils.file;
+
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.File;
+
+/**
+ * 文件类型工具类
+ *
+ * @author ruoyi
+ */
+public class FileTypeUtils
+{
+    /**
+     * 获取文件类型
+     * <p>
+     * 例如: ruoyi.txt, 返回: txt
+     * 
+     * @param file 文件名
+     * @return 后缀(不含".")
+     */
+    public static String getFileType(File file)
+    {
+        if (null == file)
+        {
+            return StringUtils.EMPTY;
+        }
+        return getFileType(file.getName());
+    }
+
+    /**
+     * 获取文件类型
+     * <p>
+     * 例如: ruoyi.txt, 返回: txt
+     *
+     * @param fileName 文件名
+     * @return 后缀(不含".")
+     */
+    public static String getFileType(String fileName)
+    {
+        int separatorIndex = fileName.lastIndexOf(".");
+        if (separatorIndex < 0)
+        {
+            return "";
+        }
+        return fileName.substring(separatorIndex + 1).toLowerCase();
+    }
+
+    /**
+     * 获取文件类型
+     * 
+     * @param photoByte 文件字节码
+     * @return 后缀(不含".")
+     */
+    public static String getFileExtendName(byte[] photoByte)
+    {
+        String strFileExtendName = "JPG";
+        if ((photoByte[0] == 71) && (photoByte[1] == 73) && (photoByte[2] == 70) && (photoByte[3] == 56)
+                && ((photoByte[4] == 55) || (photoByte[4] == 57)) && (photoByte[5] == 97))
+        {
+            strFileExtendName = "GIF";
+        }
+        else if ((photoByte[6] == 74) && (photoByte[7] == 70) && (photoByte[8] == 73) && (photoByte[9] == 70))
+        {
+            strFileExtendName = "JPG";
+        }
+        else if ((photoByte[0] == 66) && (photoByte[1] == 77))
+        {
+            strFileExtendName = "BMP";
+        }
+        else if ((photoByte[1] == 80) && (photoByte[2] == 78) && (photoByte[3] == 71))
+        {
+            strFileExtendName = "PNG";
+        }
+        return strFileExtendName;
+    }
+}

+ 124 - 10
dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/utils/file/FileUtils.java

@@ -1,21 +1,27 @@
 package com.dgtis.common.core.utils.file;
 
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.io.UnsupportedEncodingException;
-import java.net.URLEncoder;
+import com.dgtis.common.core.utils.StringUtils;
+import org.apache.commons.lang3.ArrayUtils;
+
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.*;
+import java.net.URLEncoder;
+import java.nio.charset.StandardCharsets;
 
 /**
  * 文件处理工具类
  * 
- * @author dgtis
+ * @author ruoyi
  */
 public class FileUtils extends org.apache.commons.io.FileUtils
 {
+    /** 字符常量:斜杠 {@code '/'} */
+    public static final char SLASH = '/';
+
+    /** 字符常量:反斜杠 {@code '\\'} */
+    public static final char BACKSLASH = '\\';
+
     public static String FILENAME_PATTERN = "[a-zA-Z0-9_\\-\\|\\.\\u4e00-\\u9fa5]+";
 
     /**
@@ -104,6 +110,30 @@ public class FileUtils extends org.apache.commons.io.FileUtils
         return filename.matches(FILENAME_PATTERN);
     }
 
+    /**
+     * 检查文件是否可下载
+     * 
+     * @param resource 需要下载的文件
+     * @return true 正常 false 非法
+     */
+    public static boolean checkAllowDownload(String resource)
+    {
+        // 禁止目录上跳级别
+        if (StringUtils.contains(resource, ".."))
+        {
+            return false;
+        }
+
+        // 检查允许下载的文件规则
+        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
+        {
+            return true;
+        }
+
+        // 不在允许下载的文件规则
+        return false;
+    }
+
     /**
      * 下载文件名重新编码
      * 
@@ -111,8 +141,7 @@ public class FileUtils extends org.apache.commons.io.FileUtils
      * @param fileName 文件名
      * @return 编码后的文件名
      */
-    public static String setFileDownloadHeader(HttpServletRequest request, String fileName)
-            throws UnsupportedEncodingException
+    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
     {
         final String agent = request.getHeader("USER-AGENT");
         String filename = fileName;
@@ -139,4 +168,89 @@ public class FileUtils extends org.apache.commons.io.FileUtils
         }
         return filename;
     }
+
+    /**
+     * 返回文件名
+     *
+     * @param filePath 文件
+     * @return 文件名
+     */
+    public static String getName(String filePath)
+    {
+        if (null == filePath)
+        {
+            return null;
+        }
+        int len = filePath.length();
+        if (0 == len)
+        {
+            return filePath;
+        }
+        if (isFileSeparator(filePath.charAt(len - 1)))
+        {
+            // 以分隔符结尾的去掉结尾分隔符
+            len--;
+        }
+
+        int begin = 0;
+        char c;
+        for (int i = len - 1; i > -1; i--)
+        {
+            c = filePath.charAt(i);
+            if (isFileSeparator(c))
+            {
+                // 查找最后一个路径分隔符(/或者\)
+                begin = i + 1;
+                break;
+            }
+        }
+
+        return filePath.substring(begin, len);
+    }
+
+    /**
+     * 是否为Windows或者Linux(Unix)文件分隔符<br>
+     * Windows平台下分隔符为\,Linux(Unix)为/
+     *
+     * @param c 字符
+     * @return 是否为Windows或者Linux(Unix)文件分隔符
+     */
+    public static boolean isFileSeparator(char c)
+    {
+        return SLASH == c || BACKSLASH == c;
+    }
+
+    /**
+     * 下载文件名重新编码
+     *
+     * @param response 响应对象
+     * @param realFileName 真实文件名
+     * @return
+     */
+    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
+    {
+        String percentEncodedFileName = percentEncode(realFileName);
+
+        StringBuilder contentDispositionValue = new StringBuilder();
+        contentDispositionValue.append("attachment; filename=")
+                .append(percentEncodedFileName)
+                .append(";")
+                .append("filename*=")
+                .append("utf-8''")
+                .append(percentEncodedFileName);
+
+        response.setHeader("Content-disposition", contentDispositionValue.toString());
+    }
+
+    /**
+     * 百分号编码工具方法
+     *
+     * @param s 需要百分号编码的字符串
+     * @return 百分号编码后的字符串
+     */
+    public static String percentEncode(String s) throws UnsupportedEncodingException
+    {
+        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
+        return encode.replaceAll("\\+", "%20");
+    }
 }

+ 87 - 0
dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/utils/file/ImageUtils.java

@@ -0,0 +1,87 @@
+package com.dgtis.common.core.utils.file;
+
+import org.apache.poi.util.IOUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.net.URL;
+import java.net.URLConnection;
+import java.util.Arrays;
+
+/**
+ * 图片处理工具类
+ *
+ * @author ruoyi
+ */
+public class ImageUtils
+{
+    private static final Logger log = LoggerFactory.getLogger(ImageUtils.class);
+
+    public static byte[] getImage(String imagePath)
+    {
+        InputStream is = getFile(imagePath);
+        try
+        {
+            return IOUtils.toByteArray(is);
+        }
+        catch (Exception e)
+        {
+            log.error("图片加载异常 {}", e);
+            return null;
+        }
+        finally
+        {
+            IOUtils.closeQuietly(is);
+        }
+    }
+
+    public static InputStream getFile(String imagePath)
+    {
+        try
+        {
+            byte[] result = readFile(imagePath);
+            result = Arrays.copyOf(result, result.length);
+            return new ByteArrayInputStream(result);
+        }
+        catch (Exception e)
+        {
+            log.error("获取图片异常 {}", e);
+        }
+        return null;
+    }
+
+    /**
+     * 读取文件为字节数据
+     * 
+     * @param key 地址
+     * @return 字节数据
+     */
+    public static byte[] readFile(String url)
+    {
+        InputStream in = null;
+        ByteArrayOutputStream baos = null;
+        try
+        {
+            // 网络地址
+            URL urlObj = new URL(url);
+            URLConnection urlConnection = urlObj.openConnection();
+            urlConnection.setConnectTimeout(30 * 1000);
+            urlConnection.setReadTimeout(60 * 1000);
+            urlConnection.setDoInput(true);
+            in = urlConnection.getInputStream();
+            return IOUtils.toByteArray(in);
+        }
+        catch (Exception e)
+        {
+            log.error("访问文件异常 {}", e);
+            return null;
+        }
+        finally
+        {
+            IOUtils.closeQuietly(baos);
+        }
+    }
+}

+ 59 - 0
dgtis-common/dgtis-common-core/src/main/java/com/dgtis/common/core/utils/file/MimeTypeUtils.java

@@ -0,0 +1,59 @@
+package com.dgtis.common.core.utils.file;
+
+/**
+ * 媒体类型工具类
+ * 
+ * @author ruoyi
+ */
+public class MimeTypeUtils
+{
+    public static final String IMAGE_PNG = "image/png";
+
+    public static final String IMAGE_JPG = "image/jpg";
+
+    public static final String IMAGE_JPEG = "image/jpeg";
+
+    public static final String IMAGE_BMP = "image/bmp";
+
+    public static final String IMAGE_GIF = "image/gif";
+
+    public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" };
+
+    public static final String[] FLASH_EXTENSION = { "swf", "flv" };
+
+    public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
+            "asf", "rm", "rmvb" };
+
+    public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" };
+
+    public static final String[] DEFAULT_ALLOWED_EXTENSION = {
+            // 图片
+            "bmp", "gif", "jpg", "jpeg", "png",
+            // word excel powerpoint
+            "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
+            // 压缩文件
+            "rar", "zip", "gz", "bz2",
+            // 视频格式
+            "mp4", "avi", "rmvb",
+            // pdf
+            "pdf" };
+
+    public static String getExtension(String prefix)
+    {
+        switch (prefix)
+        {
+            case IMAGE_PNG:
+                return "png";
+            case IMAGE_JPG:
+                return "jpg";
+            case IMAGE_JPEG:
+                return "jpeg";
+            case IMAGE_BMP:
+                return "bmp";
+            case IMAGE_GIF:
+                return "gif";
+            default:
+                return "";
+        }
+    }
+}

+ 84 - 0
dgtis-modules/dgtis-modules-file/pom.xml

@@ -0,0 +1,84 @@
+<?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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <artifactId>dgtis-modules</artifactId>
+        <groupId>com.dgtis</groupId>
+        <version>2.2.0</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+    <artifactId>dgtis-modules-file</artifactId>
+    <dependencies>
+
+        <!-- SpringCloud Ailibaba Nacos -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
+        </dependency>
+
+        <!-- SpringCloud Ailibaba Nacos Config -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
+        </dependency>
+
+        <!-- SpringCloud Ailibaba Sentinel -->
+        <dependency>
+            <groupId>com.alibaba.cloud</groupId>
+            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
+        </dependency>
+
+        <!-- SpringBoot Actuator -->
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-actuator</artifactId>
+        </dependency>
+
+        <!-- FastDFS -->
+        <dependency>
+            <groupId>com.github.tobato</groupId>
+            <artifactId>fastdfs-client</artifactId>
+            <version>1.26.5</version>
+        </dependency>
+
+        <!-- Minio -->
+        <dependency>
+            <groupId>io.minio</groupId>
+            <artifactId>minio</artifactId>
+            <version>${minio.version}</version>
+        </dependency>
+
+        <!-- dgtis Api System -->
+        <dependency>
+            <groupId>com.dgtis</groupId>
+            <artifactId>dgtis-api-system</artifactId>
+        </dependency>
+
+        <!-- dgtis Common Swagger -->
+        <dependency>
+            <groupId>com.dgtis</groupId>
+            <artifactId>dgtis-common-swagger</artifactId>
+        </dependency>
+
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

+ 31 - 0
dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/DgtisFileApplication.java

@@ -0,0 +1,31 @@
+package com.dgtis.file;
+
+import org.springframework.boot.SpringApplication;
+import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import com.dgtis.common.swagger.annotation.EnableCustomSwagger2;
+
+/**
+ * 文件服务
+ * 
+ * @author dgtis
+ */
+@EnableCustomSwagger2
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
+public class DgtisFileApplication
+{
+    public static void main(String[] args)
+    {
+        SpringApplication.run(DgtisFileApplication.class, args);
+        System.out.println("(♥◠‿◠)ノ゙  文件服务模块启动成功   ლ(´ڡ`ლ)゙  \n" +
+                " .-------.       ____     __        \n" +
+                " |  _ _   \\      \\   \\   /  /    \n" +
+                " | ( ' )  |       \\  _. /  '       \n" +
+                " |(_ o _) /        _( )_ .'         \n" +
+                " | (_,_).' __  ___(_ o _)'          \n" +
+                " |  |\\ \\  |  ||   |(_,_)'         \n" +
+                " |  | \\ `'   /|   `-'  /           \n" +
+                " |  |  \\    /  \\      /           \n" +
+                " ''-'   `'-'    `-..-'              ");
+    }
+}

+ 82 - 0
dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/config/MinioConfig.java

@@ -0,0 +1,82 @@
+package com.dgtis.file.config;
+
+import org.springframework.boot.context.properties.ConfigurationProperties;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import io.minio.MinioClient;
+
+/**
+ * Minio 配置信息
+ *
+ * @author ruoyi
+ */
+@Configuration
+@ConfigurationProperties(prefix = "minio")
+public class MinioConfig
+{
+    /**
+     * 服务地址
+     */
+    private String url;
+
+    /**
+     * 用户名
+     */
+    private String accessKey;
+
+    /**
+     * 密码
+     */
+    private String secretKey;
+
+    /**
+     * 存储桶名称
+     */
+    private String bucketName;
+
+    public String getUrl()
+    {
+        return url;
+    }
+
+    public void setUrl(String url)
+    {
+        this.url = url;
+    }
+
+    public String getAccessKey()
+    {
+        return accessKey;
+    }
+
+    public void setAccessKey(String accessKey)
+    {
+        this.accessKey = accessKey;
+    }
+
+    public String getSecretKey()
+    {
+        return secretKey;
+    }
+
+    public void setSecretKey(String secretKey)
+    {
+        this.secretKey = secretKey;
+    }
+
+    public String getBucketName()
+    {
+        return bucketName;
+    }
+
+    public void setBucketName(String bucketName)
+    {
+        this.bucketName = bucketName;
+    }
+
+    @Bean
+    public MinioClient getMinioClient()
+    {
+        return MinioClient.builder().endpoint(url).credentials(accessKey, secretKey).build();
+    }
+}

+ 36 - 0
dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/config/ResourcesConfig.java

@@ -0,0 +1,36 @@
+package com.dgtis.file.config;
+
+import java.io.File;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
+
+/**
+ * 通用映射配置
+ * 
+ * @author ruoyi
+ */
+@Configuration
+public class ResourcesConfig implements WebMvcConfigurer
+{
+    /**
+     * 上传文件存储在本地的根路径
+     */
+    @Value("${file.path}")
+    private String localFilePath;
+
+    /**
+     * 资源映射路径 前缀
+     */
+    @Value("${file.prefix}")
+    public String localFilePrefix;
+
+    @Override
+    public void addResourceHandlers(ResourceHandlerRegistry registry)
+    {
+        /** 本地文件上传路径 */
+        registry.addResourceHandler(localFilePrefix + "/**")
+                .addResourceLocations("file:" + localFilePath + File.separator);
+    }
+}

+ 48 - 0
dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/controller/SysFileController.java

@@ -0,0 +1,48 @@
+package com.dgtis.file.controller;
+
+import com.dgtis.common.core.utils.file.FileUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.PostMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.multipart.MultipartFile;
+import com.dgtis.common.core.domain.R;
+import com.dgtis.file.service.ISysFileService;
+import com.dgtis.system.api.domain.SysFile;
+
+/**
+ * 文件请求处理
+ * 
+ * @author dgtis
+ */
+@RestController
+public class SysFileController
+{
+    private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
+
+    @Autowired
+    private ISysFileService sysFileService;
+
+    /**
+     * 文件上传请求
+     */
+    @PostMapping("upload")
+    public R<SysFile> upload(MultipartFile file)
+    {
+        try
+        {
+            // 上传并返回访问地址
+            String url = sysFileService.uploadFile(file);
+            SysFile sysFile = new SysFile();
+            sysFile.setName(FileUtils.getName(url));
+            sysFile.setUrl(url);
+            return R.ok(sysFile);
+        }
+        catch (Exception e)
+        {
+            log.error("上传文件失败", e);
+            return R.fail(e.getMessage());
+        }
+    }
+}

+ 42 - 0
dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/service/FastDfsSysFileServiceImpl.java

@@ -0,0 +1,42 @@
+package com.dgtis.file.service;
+
+import org.apache.commons.io.FilenameUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+import com.github.tobato.fastdfs.domain.fdfs.StorePath;
+import com.github.tobato.fastdfs.service.FastFileStorageClient;
+
+/**
+ * FastDFS 文件存储
+ * 
+ * @author ruoyi
+ */
+@Service
+public class FastDfsSysFileServiceImpl implements ISysFileService
+{
+    /**
+     * 域名或本机访问地址
+     */
+    @Value("${file.domain}")
+    public String domain;
+
+    @Autowired
+    private FastFileStorageClient storageClient;
+
+    /**
+     * FastDfs文件上传接口
+     * 
+     * @param file 上传的文件
+     * @return 访问地址
+     * @throws Exception
+     */
+    @Override
+    public String uploadFile(MultipartFile file) throws Exception
+    {
+        StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(),
+                FilenameUtils.getExtension(file.getOriginalFilename()), null);
+        return domain + "/" + storePath.getFullPath();
+    }
+}

+ 20 - 0
dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/service/ISysFileService.java

@@ -0,0 +1,20 @@
+package com.dgtis.file.service;
+
+import org.springframework.web.multipart.MultipartFile;
+
+/**
+ * 文件上传接口
+ * 
+ * @author dgtis
+ */
+public interface ISysFileService
+{
+    /**
+     * 文件上传接口
+     * 
+     * @param file 上传的文件
+     * @return 访问地址
+     * @throws Exception
+     */
+    public String uploadFile(MultipartFile file) throws Exception;
+}

+ 50 - 0
dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/service/LocalSysFileServiceImpl.java

@@ -0,0 +1,50 @@
+package com.dgtis.file.service;
+
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Primary;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+import com.dgtis.file.utils.FileUploadUtils;
+
+/**
+ * 本地文件存储
+ * 
+ * @author ruoyi
+ */
+@Primary
+@Service
+public class LocalSysFileServiceImpl implements ISysFileService
+{
+    /**
+     * 资源映射路径 前缀
+     */
+    @Value("${file.prefix}")
+    public String localFilePrefix;
+
+    /**
+     * 域名或本机访问地址
+     */
+    @Value("${file.domain}")
+    public String domain;
+    
+    /**
+     * 上传文件存储在本地的根路径
+     */
+    @Value("${file.path}")
+    private String localFilePath;
+
+    /**
+     * 本地文件上传接口
+     * 
+     * @param file 上传的文件
+     * @return 访问地址
+     * @throws Exception
+     */
+    @Override
+    public String uploadFile(MultipartFile file) throws Exception
+    {
+        String name = FileUploadUtils.upload(localFilePath, file);
+        String url = domain + localFilePrefix + name;
+        return url;
+    }
+}

+ 45 - 0
dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/service/MinioSysFileServiceImpl.java

@@ -0,0 +1,45 @@
+package com.dgtis.file.service;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.web.multipart.MultipartFile;
+import com.dgtis.file.config.MinioConfig;
+import com.dgtis.file.utils.FileUploadUtils;
+import io.minio.MinioClient;
+import io.minio.PutObjectArgs;
+
+/**
+ * Minio 文件存储
+ * 
+ * @author ruoyi
+ */
+@Service
+public class MinioSysFileServiceImpl implements ISysFileService
+{
+    @Autowired
+    private MinioConfig minioConfig;
+
+    @Autowired
+    private MinioClient client;
+
+    /**
+     * 本地文件上传接口
+     * 
+     * @param file 上传的文件
+     * @return 访问地址
+     * @throws Exception
+     */
+    @Override
+    public String uploadFile(MultipartFile file) throws Exception
+    {
+        String fileName = FileUploadUtils.extractFilename(file);
+        PutObjectArgs args = PutObjectArgs.builder()
+                .bucket(minioConfig.getBucketName())
+                .object(fileName)
+                .stream(file.getInputStream(), file.getSize(), -1)
+                .contentType(file.getContentType())
+                .build();
+        client.putObject(args);
+        return minioConfig.getUrl() + "/" + minioConfig.getBucketName() + "/" + fileName;
+    }
+}

+ 197 - 0
dgtis-modules/dgtis-modules-file/src/main/java/com/dgtis/file/utils/FileUploadUtils.java

@@ -0,0 +1,197 @@
+package com.dgtis.file.utils;
+
+import com.dgtis.common.core.exception.file.FileNameLengthLimitExceededException;
+import com.dgtis.common.core.exception.file.FileSizeLimitExceededException;
+import com.dgtis.common.core.exception.file.InvalidExtensionException;
+import com.dgtis.common.core.utils.DateUtils;
+import com.dgtis.common.core.utils.IdUtils;
+import com.dgtis.common.core.utils.StringUtils;
+import com.dgtis.common.core.utils.file.MimeTypeUtils;
+import org.apache.commons.io.FilenameUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * 文件上传工具类
+ * 
+ * @author dgtis
+ */
+public class FileUploadUtils
+{
+    /**
+     * 默认大小 50M
+     */
+    public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
+
+    /**
+     * 默认的文件名最大长度 100
+     */
+    public static final int DEFAULT_FILE_NAME_LENGTH = 100;
+
+    /**
+     * 根据文件路径上传
+     *
+     * @param baseDir 相对应用的基目录
+     * @param file 上传的文件
+     * @return 文件名称
+     * @throws IOException
+     */
+    public static final String upload(String baseDir, MultipartFile file) throws IOException
+    {
+        try
+        {
+            return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
+        }
+        catch (Exception e)
+        {
+            throw new IOException(e.getMessage(), e);
+        }
+    }
+
+    /**
+     * 文件上传
+     *
+     * @param baseDir 相对应用的基目录
+     * @param file 上传的文件
+     * @param allowedExtension 上传文件类型
+     * @return 返回上传成功的文件名
+     * @throws FileSizeLimitExceededException 如果超出最大大小
+     * @throws FileNameLengthLimitExceededException 文件名太长
+     * @throws IOException 比如读写文件出错时
+     * @throws InvalidExtensionException 文件校验异常
+     */
+    public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
+            throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
+            InvalidExtensionException
+    {
+        int fileNamelength = file.getOriginalFilename().length();
+        if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
+        {
+            throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
+        }
+
+        assertAllowed(file, allowedExtension);
+
+        String fileName = extractFilename(file);
+
+        File desc = getAbsoluteFile(baseDir, fileName);
+        file.transferTo(desc);
+        String pathFileName = getPathFileName(fileName);
+        return pathFileName;
+    }
+
+    /**
+     * 编码文件名
+     */
+    public static final String extractFilename(MultipartFile file)
+    {
+        String fileName = file.getOriginalFilename();
+        String extension = getExtension(file);
+        fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
+        return fileName;
+    }
+
+    private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
+    {
+        File desc = new File(uploadDir + File.separator + fileName);
+
+        if (!desc.exists())
+        {
+            if (!desc.getParentFile().exists())
+            {
+                desc.getParentFile().mkdirs();
+            }
+        }
+        return desc.isAbsolute() ? desc : desc.getAbsoluteFile();
+    }
+
+    private static final String getPathFileName(String fileName) throws IOException
+    {
+        String pathFileName = "/" + fileName;
+        return pathFileName;
+    }
+
+    /**
+     * 文件大小校验
+     *
+     * @param file 上传的文件
+     * @throws FileSizeLimitExceededException 如果超出最大大小
+     * @throws InvalidExtensionException 文件校验异常
+     */
+    public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
+            throws FileSizeLimitExceededException, InvalidExtensionException
+    {
+        long size = file.getSize();
+        if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE)
+        {
+            throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
+        }
+
+        String fileName = file.getOriginalFilename();
+        String extension = getExtension(file);
+        if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
+        {
+            if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
+            {
+                throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
+                        fileName);
+            }
+            else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
+            {
+                throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
+                        fileName);
+            }
+            else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
+            {
+                throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
+                        fileName);
+            }
+            else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
+            {
+                throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
+                        fileName);
+            }
+            else
+            {
+                throw new InvalidExtensionException(allowedExtension, extension, fileName);
+            }
+        }
+    }
+
+    /**
+     * 判断MIME类型是否是允许的MIME类型
+     *
+     * @param extension 上传文件类型
+     * @param allowedExtension 允许上传文件类型
+     * @return true/false
+     */
+    public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
+    {
+        for (String str : allowedExtension)
+        {
+            if (str.equalsIgnoreCase(extension))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * 获取文件名的后缀
+     * 
+     * @param file 表单文件
+     * @return 后缀名
+     */
+    public static final String getExtension(MultipartFile file)
+    {
+        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
+        if (StringUtils.isEmpty(extension))
+        {
+            extension = MimeTypeUtils.getExtension(file.getContentType());
+        }
+        return extension;
+    }
+}

+ 10 - 0
dgtis-modules/dgtis-modules-file/src/main/resources/banner.txt

@@ -0,0 +1,10 @@
+Spring Boot Version: ${spring-boot.version}
+Spring Application Name: ${spring.application.name}
+                            _           __  _  _       
+                           (_)         / _|(_)| |      
+ _ __  _   _   ___   _   _  _  ______ | |_  _ | |  ___ 
+| '__|| | | | / _ \ | | | || ||______||  _|| || | / _ \
+| |   | |_| || (_) || |_| || |        | |  | || ||  __/
+|_|    \__,_| \___/  \__, ||_|        |_|  |_||_| \___|
+                      __/ |                            
+                     |___/                             

+ 31 - 0
dgtis-modules/dgtis-modules-file/src/main/resources/bootstrap.yml

@@ -0,0 +1,31 @@
+dgtis:
+  project-name: ShangHaiLife-ECIF
+  common-server-addr: 192.168.100.254
+# Tomcat
+server:
+  port: 19205
+file:
+  path: /home/shanghailifeecif/profile
+  prefix: /profile
+  domain: 127.0.0.1
+# Spring
+spring: 
+  application:
+    # 应用名称
+    name: dgtis-file
+  profiles:
+    # 环境配置
+    active: dev
+  cloud:
+    nacos:
+      discovery:
+        # 服务注册地址
+        server-addr: ${dgtis.common-server-addr}:8848
+      config:
+        # 配置中心地址
+        server-addr: ${dgtis.common-server-addr}:8848
+        # 配置文件格式
+        file-extension: yml
+        # 共享配置
+        shared-configs:
+          - application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

+ 74 - 0
dgtis-modules/dgtis-modules-file/src/main/resources/logback.xml

@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
+    <!-- 日志存放路径 -->
+	<property name="log.path" value="logs/dgtis-file" />
+   <!-- 日志输出格式 -->
+	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
+
+    <!-- 控制台输出 -->
+	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+	</appender>
+
+    <!-- 系统日志输出 -->
+	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/info.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+			<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+		</rollingPolicy>
+		<encoder>
+			<pattern>${log.pattern}</pattern>
+		</encoder>
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>INFO</level>
+            <!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+            <!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+	</appender>
+
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
+	    <file>${log.path}/error.log</file>
+        <!-- 循环政策:基于时间创建日志文件 -->
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
+            <!-- 日志文件名格式 -->
+            <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
+			<!-- 日志最大的历史 60天 -->
+			<maxHistory>60</maxHistory>
+        </rollingPolicy>
+        <encoder>
+            <pattern>${log.pattern}</pattern>
+        </encoder>
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
+            <!-- 过滤的级别 -->
+            <level>ERROR</level>
+			<!-- 匹配时的操作:接收(记录) -->
+            <onMatch>ACCEPT</onMatch>
+			<!-- 不匹配时的操作:拒绝(不记录) -->
+            <onMismatch>DENY</onMismatch>
+        </filter>
+    </appender>
+
+    <!-- 系统模块日志级别控制  -->
+	<logger name="com.dgtis" level="info" />
+	<!-- Spring日志级别控制  -->
+	<logger name="org.springframework" level="warn" />
+
+	<root level="info">
+		<appender-ref ref="console" />
+	</root>
+	
+	<!--系统操作日志-->
+    <root level="info">
+        <appender-ref ref="file_info" />
+        <appender-ref ref="file_error" />
+    </root>
+</configuration>

+ 0 - 0
dgtis-modules/dgtis-modules-file/src/main/resources/minio.properties


+ 43 - 5
dgtis-modules/dgtis-modules-system/src/main/java/com/dgtis/system/controller/SysProfileController.java

@@ -1,12 +1,15 @@
 package com.dgtis.system.controller;
 
+import com.dgtis.common.core.domain.R;
+import com.dgtis.common.core.utils.ServletUtils;
+import com.dgtis.common.core.utils.StringUtils;
+import com.dgtis.system.api.RemoteFileService;
+import com.dgtis.system.api.domain.SysFile;
 import com.dgtis.system.service.ISysUserService;
+import org.apache.commons.fileupload.FileUpload;
 import org.springframework.beans.factory.annotation.Autowired;
-import org.springframework.web.bind.annotation.GetMapping;
-import org.springframework.web.bind.annotation.PutMapping;
-import org.springframework.web.bind.annotation.RequestBody;
-import org.springframework.web.bind.annotation.RequestMapping;
-import org.springframework.web.bind.annotation.RestController;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.*;
 import com.dgtis.common.core.web.controller.BaseController;
 import com.dgtis.common.core.web.domain.AjaxResult;
 import com.dgtis.common.log.annotation.Log;
@@ -15,6 +18,9 @@ import com.dgtis.common.security.service.TokenService;
 import com.dgtis.common.security.utils.SecurityUtils;
 import com.dgtis.system.api.domain.SysUser;
 import com.dgtis.system.api.model.LoginUser;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.io.IOException;
 
 /**
  * 个人信息 业务处理
@@ -31,6 +37,9 @@ public class SysProfileController extends BaseController
     @Autowired
     private TokenService tokenService;
 
+    @Autowired
+    private RemoteFileService remoteFileService;
+
     /**
      * 个人信息
      */
@@ -94,4 +103,33 @@ public class SysProfileController extends BaseController
         }
         return AjaxResult.error("修改密码异常,请联系管理员");
     }
+
+    /**
+     * 头像上传
+     */
+    @Log(title = "用户头像", businessType = BusinessType.UPDATE)
+    @PostMapping("/avatar")
+    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file)
+    {
+        if (!file.isEmpty())
+        {
+            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
+            R<SysFile> fileResult = remoteFileService.upload(file);
+            if (StringUtils.isNull(fileResult) || StringUtils.isNull(fileResult.getData()))
+            {
+                return AjaxResult.error("文件服务异常,请联系管理员");
+            }
+            String url = fileResult.getData().getUrl();
+            if (userService.updateUserAvatar(loginUser.getUsername(), url))
+            {
+                AjaxResult ajax = AjaxResult.success();
+                ajax.put("imgUrl", url);
+                // 更新缓存用户头像
+                loginUser.getSysUser().setAvatar(url);
+                tokenService.setLoginUser(loginUser);
+                return ajax;
+            }
+        }
+        return AjaxResult.error("上传图片异常,请联系管理员");
+    }
 }

+ 1 - 0
dgtis-modules/pom.xml

@@ -13,6 +13,7 @@
         <module>dgtis-modules-gen</module>
         <module>dgtis-modules-job</module>
         <module>dgtis-modules-data</module>
+        <module>dgtis-modules-file</module>
     </modules>
 
     <artifactId>dgtis-modules</artifactId>

+ 1 - 0
pom.xml

@@ -31,6 +31,7 @@
         <commons.fileupload.version>1.3.3</commons.fileupload.version>
         <velocity.version>1.7</velocity.version>
         <fastjson.version>1.2.74</fastjson.version>
+        <minio.version>8.0.3</minio.version>
 		<poi.version>3.17</poi.version>
         <common-pool.version>2.6.2</common-pool.version>