Kaynağa Gözat

新增文件服务应用

RuoYi 5 yıl önce
ebeveyn
işleme
b812e01100
27 değiştirilmiş dosya ile 1053 ekleme ve 13 silme
  1. 29 0
      ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/RemoteFileService.java
  2. 50 0
      ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/domain/SysFile.java
  3. 35 0
      ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/factory/RemoteFileFallbackFactory.java
  4. 5 0
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ServiceNameConstants.java
  5. 19 0
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileException.java
  6. 16 0
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileNameLengthLimitExceededException.java
  7. 16 0
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileSizeLimitExceededException.java
  8. 81 0
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/InvalidExtensionException.java
  9. 47 0
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileTypeUtils.java
  10. 63 2
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileUtils.java
  11. 59 0
      ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/MimeTypeUtils.java
  12. 1 0
      ruoyi-modules/pom.xml
  13. 81 0
      ruoyi-modules/ruoyi-file/pom.xml
  14. 35 0
      ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/RuoYFileApplication.java
  15. 36 0
      ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/config/ResourcesConfig.java
  16. 67 0
      ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/controller/SysFileController.java
  17. 21 0
      ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/ISysFileService.java
  18. 27 0
      ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/LocalSysFileServiceImpl.java
  19. 204 0
      ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/utils/FileUploadUtils.java
  20. 10 0
      ruoyi-modules/ruoyi-file/src/main/resources/banner.txt
  21. 24 0
      ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml
  22. 74 0
      ruoyi-modules/ruoyi-file/src/main/resources/logback.xml
  23. 41 0
      ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java
  24. 2 2
      ruoyi-ui/src/components/UploadImage/index.vue
  25. 1 1
      ruoyi-ui/src/store/modules/user.js
  26. 1 1
      ruoyi-ui/src/views/system/user/profile/userAvatar.vue
  27. 8 7
      sql/ry_config_20200924.sql

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

@@ -0,0 +1,29 @@
1
+package com.ruoyi.system.api;
2
+
3
+import org.springframework.cloud.openfeign.FeignClient;
4
+import org.springframework.http.MediaType;
5
+import org.springframework.web.bind.annotation.PostMapping;
6
+import org.springframework.web.bind.annotation.RequestPart;
7
+import org.springframework.web.multipart.MultipartFile;
8
+import com.ruoyi.common.core.constant.ServiceNameConstants;
9
+import com.ruoyi.common.core.domain.R;
10
+import com.ruoyi.system.api.domain.SysFile;
11
+import com.ruoyi.system.api.factory.RemoteFileFallbackFactory;
12
+
13
+/**
14
+ * 文件服务
15
+ * 
16
+ * @author ruoyi
17
+ */
18
+@FeignClient(contextId = "remoteFileService", value = ServiceNameConstants.FILE_SERVICE, fallbackFactory = RemoteFileFallbackFactory.class)
19
+public interface RemoteFileService
20
+{
21
+    /**
22
+     * 上传文件
23
+     *
24
+     * @param file 文件信息
25
+     * @return 结果
26
+     */
27
+    @PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
28
+    public R<SysFile> upload(@RequestPart(value = "file") MultipartFile file);
29
+}

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

@@ -0,0 +1,50 @@
1
+package com.ruoyi.system.api.domain;
2
+
3
+import org.apache.commons.lang3.builder.ToStringBuilder;
4
+import org.apache.commons.lang3.builder.ToStringStyle;
5
+
6
+/**
7
+ * 文件信息
8
+ * 
9
+ * @author ruoyi
10
+ */
11
+public class SysFile
12
+{
13
+    /**
14
+     * 文件名称
15
+     */
16
+    private String name;
17
+
18
+    /**
19
+     * 文件地址
20
+     */
21
+    private String url;
22
+
23
+    public String getName()
24
+    {
25
+        return name;
26
+    }
27
+
28
+    public void setName(String name)
29
+    {
30
+        this.name = name;
31
+    }
32
+
33
+    public String getUrl()
34
+    {
35
+        return url;
36
+    }
37
+
38
+    public void setUrl(String url)
39
+    {
40
+        this.url = url;
41
+    }
42
+
43
+    @Override
44
+    public String toString() {
45
+        return new ToStringBuilder(this,ToStringStyle.MULTI_LINE_STYLE)
46
+            .append("name", getName())
47
+            .append("url", getUrl())
48
+            .toString();
49
+    }
50
+}

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

@@ -0,0 +1,35 @@
1
+package com.ruoyi.system.api.factory;
2
+
3
+import org.slf4j.Logger;
4
+import org.slf4j.LoggerFactory;
5
+import org.springframework.stereotype.Component;
6
+import org.springframework.web.multipart.MultipartFile;
7
+import com.ruoyi.common.core.domain.R;
8
+import com.ruoyi.system.api.RemoteFileService;
9
+import com.ruoyi.system.api.domain.SysFile;
10
+import feign.hystrix.FallbackFactory;
11
+
12
+/**
13
+ * 文件服务降级处理
14
+ * 
15
+ * @author ruoyi
16
+ */
17
+@Component
18
+public class RemoteFileFallbackFactory implements FallbackFactory<RemoteFileService>
19
+{
20
+    private static final Logger log = LoggerFactory.getLogger(RemoteFileFallbackFactory.class);
21
+
22
+    @Override
23
+    public RemoteFileService create(Throwable throwable)
24
+    {
25
+        log.error("文件服务调用失败:{}", throwable.getMessage());
26
+        return new RemoteFileService()
27
+        {
28
+            @Override
29
+            public R<SysFile> upload(MultipartFile file)
30
+            {
31
+                return R.fail("上传文件失败:" + throwable.getMessage());
32
+            }
33
+        };
34
+    }
35
+}

+ 5 - 0
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/constant/ServiceNameConstants.java

@@ -16,4 +16,9 @@ public class ServiceNameConstants
16 16
      * 系统模块的serviceid
17 17
      */
18 18
     public static final String SYSTEM_SERVICE = "ruoyi-system";
19
+
20
+    /**
21
+     * 文件服务的serviceid
22
+     */
23
+    public static final String FILE_SERVICE = "ruoyi-file";
19 24
 }

+ 19 - 0
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/FileException.java

@@ -0,0 +1,19 @@
1
+package com.ruoyi.common.core.exception.file;
2
+
3
+import com.ruoyi.common.core.exception.BaseException;
4
+
5
+/**
6
+ * 文件信息异常类
7
+ * 
8
+ * @author ruoyi
9
+ */
10
+public class FileException extends BaseException
11
+{
12
+    private static final long serialVersionUID = 1L;
13
+
14
+    public FileException(String code, Object[] args)
15
+    {
16
+        super("file", code, args, null);
17
+    }
18
+
19
+}

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

@@ -0,0 +1,16 @@
1
+package com.ruoyi.common.core.exception.file;
2
+
3
+/**
4
+ * 文件名称超长限制异常类
5
+ * 
6
+ * @author ruoyi
7
+ */
8
+public class FileNameLengthLimitExceededException extends FileException
9
+{
10
+    private static final long serialVersionUID = 1L;
11
+
12
+    public FileNameLengthLimitExceededException(int defaultFileNameLength)
13
+    {
14
+        super("upload.filename.exceed.length", new Object[] { defaultFileNameLength });
15
+    }
16
+}

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

@@ -0,0 +1,16 @@
1
+package com.ruoyi.common.core.exception.file;
2
+
3
+/**
4
+ * 文件名大小限制异常类
5
+ * 
6
+ * @author ruoyi
7
+ */
8
+public class FileSizeLimitExceededException extends FileException
9
+{
10
+    private static final long serialVersionUID = 1L;
11
+
12
+    public FileSizeLimitExceededException(long defaultMaxSize)
13
+    {
14
+        super("upload.exceed.maxSize", new Object[] { defaultMaxSize });
15
+    }
16
+}

+ 81 - 0
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/exception/file/InvalidExtensionException.java

@@ -0,0 +1,81 @@
1
+package com.ruoyi.common.core.exception.file;
2
+
3
+import java.util.Arrays;
4
+import org.apache.commons.fileupload.FileUploadException;
5
+
6
+/**
7
+ * 文件上传 误异常类
8
+ * 
9
+ * @author ruoyi
10
+ */
11
+public class InvalidExtensionException extends FileUploadException
12
+{
13
+    private static final long serialVersionUID = 1L;
14
+
15
+    private String[] allowedExtension;
16
+    private String extension;
17
+    private String filename;
18
+
19
+    public InvalidExtensionException(String[] allowedExtension, String extension, String filename)
20
+    {
21
+        super("filename : [" + filename + "], extension : [" + extension + "], allowed extension : [" + Arrays.toString(allowedExtension) + "]");
22
+        this.allowedExtension = allowedExtension;
23
+        this.extension = extension;
24
+        this.filename = filename;
25
+    }
26
+
27
+    public String[] getAllowedExtension()
28
+    {
29
+        return allowedExtension;
30
+    }
31
+
32
+    public String getExtension()
33
+    {
34
+        return extension;
35
+    }
36
+
37
+    public String getFilename()
38
+    {
39
+        return filename;
40
+    }
41
+
42
+    public static class InvalidImageExtensionException extends InvalidExtensionException
43
+    {
44
+        private static final long serialVersionUID = 1L;
45
+
46
+        public InvalidImageExtensionException(String[] allowedExtension, String extension, String filename)
47
+        {
48
+            super(allowedExtension, extension, filename);
49
+        }
50
+    }
51
+
52
+    public static class InvalidFlashExtensionException extends InvalidExtensionException
53
+    {
54
+        private static final long serialVersionUID = 1L;
55
+
56
+        public InvalidFlashExtensionException(String[] allowedExtension, String extension, String filename)
57
+        {
58
+            super(allowedExtension, extension, filename);
59
+        }
60
+    }
61
+
62
+    public static class InvalidMediaExtensionException extends InvalidExtensionException
63
+    {
64
+        private static final long serialVersionUID = 1L;
65
+
66
+        public InvalidMediaExtensionException(String[] allowedExtension, String extension, String filename)
67
+        {
68
+            super(allowedExtension, extension, filename);
69
+        }
70
+    }
71
+    
72
+    public static class InvalidVideoExtensionException extends InvalidExtensionException
73
+    {
74
+        private static final long serialVersionUID = 1L;
75
+
76
+        public InvalidVideoExtensionException(String[] allowedExtension, String extension, String filename)
77
+        {
78
+            super(allowedExtension, extension, filename);
79
+        }
80
+    }
81
+}

+ 47 - 0
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileTypeUtils.java

@@ -0,0 +1,47 @@
1
+package com.ruoyi.common.core.utils.file;
2
+
3
+import java.io.File;
4
+import org.apache.commons.lang3.StringUtils;
5
+
6
+/**
7
+ * 文件类型工具类
8
+ *
9
+ * @author ruoyi
10
+ */
11
+public class FileTypeUtils
12
+{
13
+    /**
14
+     * 获取文件类型
15
+     * <p>
16
+     * 例如: ruoyi.txt, 返回: txt
17
+     * 
18
+     * @param file 文件名
19
+     * @return 后缀(不含".")
20
+     */
21
+    public static String getFileType(File file)
22
+    {
23
+        if (null == file)
24
+        {
25
+            return StringUtils.EMPTY;
26
+        }
27
+        return getFileType(file.getName());
28
+    }
29
+
30
+    /**
31
+     * 获取文件类型
32
+     * <p>
33
+     * 例如: ruoyi.txt, 返回: txt
34
+     *
35
+     * @param fileName 文件名
36
+     * @return 后缀(不含".")
37
+     */
38
+    public static String getFileType(String fileName)
39
+    {
40
+        int separatorIndex = fileName.lastIndexOf(".");
41
+        if (separatorIndex < 0)
42
+        {
43
+            return "";
44
+        }
45
+        return fileName.substring(separatorIndex + 1).toLowerCase();
46
+    }
47
+}

+ 63 - 2
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/file/FileUtils.java

@@ -7,7 +7,11 @@ import java.io.IOException;
7 7
 import java.io.OutputStream;
8 8
 import java.io.UnsupportedEncodingException;
9 9
 import java.net.URLEncoder;
10
+import java.nio.charset.StandardCharsets;
10 11
 import javax.servlet.http.HttpServletRequest;
12
+import javax.servlet.http.HttpServletResponse;
13
+import org.apache.commons.lang3.ArrayUtils;
14
+import com.ruoyi.common.core.utils.StringUtils;
11 15
 
12 16
 /**
13 17
  * 文件处理工具类
@@ -105,14 +109,37 @@ public class FileUtils extends org.apache.commons.io.FileUtils
105 109
     }
106 110
 
107 111
     /**
112
+     * 检查文件是否可下载
113
+     * 
114
+     * @param resource 需要下载的文件
115
+     * @return true 正常 false 非法
116
+     */
117
+    public static boolean checkAllowDownload(String resource)
118
+    {
119
+        // 禁止目录上跳级别
120
+        if (StringUtils.contains(resource, ".."))
121
+        {
122
+            return false;
123
+        }
124
+
125
+        // 检查允许下载的文件规则
126
+        if (ArrayUtils.contains(MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION, FileTypeUtils.getFileType(resource)))
127
+        {
128
+            return true;
129
+        }
130
+
131
+        // 不在允许下载的文件规则
132
+        return false;
133
+    }
134
+
135
+    /**
108 136
      * 下载文件名重新编码
109 137
      * 
110 138
      * @param request 请求对象
111 139
      * @param fileName 文件名
112 140
      * @return 编码后的文件名
113 141
      */
114
-    public static String setFileDownloadHeader(HttpServletRequest request, String fileName)
115
-            throws UnsupportedEncodingException
142
+    public static String setFileDownloadHeader(HttpServletRequest request, String fileName) throws UnsupportedEncodingException
116 143
     {
117 144
         final String agent = request.getHeader("USER-AGENT");
118 145
         String filename = fileName;
@@ -139,4 +166,38 @@ public class FileUtils extends org.apache.commons.io.FileUtils
139 166
         }
140 167
         return filename;
141 168
     }
169
+
170
+    /**
171
+     * 下载文件名重新编码
172
+     *
173
+     * @param response 响应对象
174
+     * @param realFileName 真实文件名
175
+     * @return
176
+     */
177
+    public static void setAttachmentResponseHeader(HttpServletResponse response, String realFileName) throws UnsupportedEncodingException
178
+    {
179
+        String percentEncodedFileName = percentEncode(realFileName);
180
+
181
+        StringBuilder contentDispositionValue = new StringBuilder();
182
+        contentDispositionValue.append("attachment; filename=")
183
+                .append(percentEncodedFileName)
184
+                .append(";")
185
+                .append("filename*=")
186
+                .append("utf-8''")
187
+                .append(percentEncodedFileName);
188
+
189
+        response.setHeader("Content-disposition", contentDispositionValue.toString());
190
+    }
191
+
192
+    /**
193
+     * 百分号编码工具方法
194
+     *
195
+     * @param s 需要百分号编码的字符串
196
+     * @return 百分号编码后的字符串
197
+     */
198
+    public static String percentEncode(String s) throws UnsupportedEncodingException
199
+    {
200
+        String encode = URLEncoder.encode(s, StandardCharsets.UTF_8.toString());
201
+        return encode.replaceAll("\\+", "%20");
202
+    }
142 203
 }

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

@@ -0,0 +1,59 @@
1
+package com.ruoyi.common.core.utils.file;
2
+
3
+/**
4
+ * 媒体类型工具类
5
+ * 
6
+ * @author ruoyi
7
+ */
8
+public class MimeTypeUtils
9
+{
10
+    public static final String IMAGE_PNG = "image/png";
11
+
12
+    public static final String IMAGE_JPG = "image/jpg";
13
+
14
+    public static final String IMAGE_JPEG = "image/jpeg";
15
+
16
+    public static final String IMAGE_BMP = "image/bmp";
17
+
18
+    public static final String IMAGE_GIF = "image/gif";
19
+
20
+    public static final String[] IMAGE_EXTENSION = { "bmp", "gif", "jpg", "jpeg", "png" };
21
+
22
+    public static final String[] FLASH_EXTENSION = { "swf", "flv" };
23
+
24
+    public static final String[] MEDIA_EXTENSION = { "swf", "flv", "mp3", "wav", "wma", "wmv", "mid", "avi", "mpg",
25
+            "asf", "rm", "rmvb" };
26
+
27
+    public static final String[] VIDEO_EXTENSION = { "mp4", "avi", "rmvb" };
28
+
29
+    public static final String[] DEFAULT_ALLOWED_EXTENSION = {
30
+            // 图片
31
+            "bmp", "gif", "jpg", "jpeg", "png",
32
+            // word excel powerpoint
33
+            "doc", "docx", "xls", "xlsx", "ppt", "pptx", "html", "htm", "txt",
34
+            // 压缩文件
35
+            "rar", "zip", "gz", "bz2",
36
+            // 视频格式
37
+            "mp4", "avi", "rmvb",
38
+            // pdf
39
+            "pdf" };
40
+
41
+    public static String getExtension(String prefix)
42
+    {
43
+        switch (prefix)
44
+        {
45
+            case IMAGE_PNG:
46
+                return "png";
47
+            case IMAGE_JPG:
48
+                return "jpg";
49
+            case IMAGE_JPEG:
50
+                return "jpeg";
51
+            case IMAGE_BMP:
52
+                return "bmp";
53
+            case IMAGE_GIF:
54
+                return "gif";
55
+            default:
56
+                return "";
57
+        }
58
+    }
59
+}

+ 1 - 0
ruoyi-modules/pom.xml

@@ -12,6 +12,7 @@
12 12
         <module>ruoyi-system</module>
13 13
         <module>ruoyi-gen</module>
14 14
         <module>ruoyi-job</module>
15
+        <module>ruoyi-file</module>
15 16
     </modules>
16 17
 
17 18
     <artifactId>ruoyi-modules</artifactId>

+ 81 - 0
ruoyi-modules/ruoyi-file/pom.xml

@@ -0,0 +1,81 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3
+         xmlns="http://maven.apache.org/POM/4.0.0"
4
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5
+    <parent>
6
+        <groupId>com.ruoyi</groupId>
7
+        <artifactId>ruoyi-modules</artifactId>
8
+        <version>2.2.0</version>
9
+    </parent>
10
+    <modelVersion>4.0.0</modelVersion>
11
+
12
+    <artifactId>ruoyi-modules-file</artifactId>
13
+
14
+    <description>
15
+        ruoyi-modules-file文件服务
16
+    </description>
17
+
18
+    <dependencies>
19
+    	
20
+    	<!-- SpringCloud Ailibaba Nacos -->
21
+        <dependency>
22
+            <groupId>com.alibaba.cloud</groupId>
23
+            <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
24
+        </dependency>
25
+        
26
+        <!-- SpringCloud Ailibaba Nacos Config -->
27
+        <dependency>
28
+            <groupId>com.alibaba.cloud</groupId>
29
+            <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
30
+        </dependency>
31
+        
32
+        <!-- SpringCloud Ailibaba Sentinel -->
33
+        <dependency>
34
+            <groupId>com.alibaba.cloud</groupId>
35
+            <artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
36
+        </dependency>
37
+        
38
+        <!-- SpringBoot Actuator -->
39
+        <dependency>
40
+            <groupId>org.springframework.boot</groupId>
41
+            <artifactId>spring-boot-starter-actuator</artifactId>
42
+        </dependency>
43
+		
44
+        <!-- Swagger -->
45
+        <dependency>
46
+            <groupId>io.springfox</groupId>
47
+            <artifactId>springfox-swagger-ui</artifactId>
48
+            <version>${swagger.fox.version}</version>
49
+        </dependency>
50
+        
51
+        <!-- Ruoyi Common Security -->
52
+        <dependency>
53
+            <groupId>com.ruoyi</groupId>
54
+            <artifactId>ruoyi-common-security</artifactId>
55
+        </dependency>
56
+        
57
+        <!-- Ruoyi Common Swagger -->
58
+        <dependency>
59
+            <groupId>com.ruoyi</groupId>
60
+            <artifactId>ruoyi-common-swagger</artifactId>
61
+        </dependency>
62
+        
63
+    </dependencies>
64
+
65
+    <build>
66
+        <plugins>
67
+            <plugin>
68
+                <groupId>org.springframework.boot</groupId>
69
+                <artifactId>spring-boot-maven-plugin</artifactId>
70
+                <executions>
71
+                    <execution>
72
+                        <goals>
73
+                            <goal>repackage</goal>
74
+                        </goals>
75
+                    </execution>
76
+                </executions>
77
+            </plugin>
78
+        </plugins>
79
+    </build>
80
+   
81
+</project>

+ 35 - 0
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/RuoYFileApplication.java

@@ -0,0 +1,35 @@
1
+package com.ruoyi.file;
2
+
3
+import org.springframework.boot.SpringApplication;
4
+import org.springframework.boot.autoconfigure.SpringBootApplication;
5
+import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
6
+import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
7
+import com.ruoyi.common.security.annotation.EnableRyFeignClients;
8
+import com.ruoyi.common.swagger.annotation.EnableCustomSwagger2;
9
+
10
+/**
11
+ * 文件服务
12
+ * 
13
+ * @author ruoyi
14
+ */
15
+@EnableCustomSwagger2
16
+@EnableRyFeignClients
17
+@EnableDiscoveryClient
18
+@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class })
19
+public class RuoYFileApplication
20
+{
21
+    public static void main(String[] args)
22
+    {
23
+        SpringApplication.run(RuoYFileApplication.class, args);
24
+        System.out.println("(♥◠‿◠)ノ゙  文件服务模块启动成功   ლ(´ڡ`ლ)゙  \n" +
25
+                " .-------.       ____     __        \n" +
26
+                " |  _ _   \\      \\   \\   /  /    \n" +
27
+                " | ( ' )  |       \\  _. /  '       \n" +
28
+                " |(_ o _) /        _( )_ .'         \n" +
29
+                " | (_,_).' __  ___(_ o _)'          \n" +
30
+                " |  |\\ \\  |  ||   |(_,_)'         \n" +
31
+                " |  | \\ `'   /|   `-'  /           \n" +
32
+                " |  |  \\    /  \\      /           \n" +
33
+                " ''-'   `'-'    `-..-'              ");
34
+    }
35
+}

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

@@ -0,0 +1,36 @@
1
+package com.ruoyi.file.config;
2
+
3
+import java.io.File;
4
+import org.springframework.beans.factory.annotation.Value;
5
+import org.springframework.context.annotation.Configuration;
6
+import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
7
+import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
8
+
9
+/**
10
+ * 通用映射配置
11
+ * 
12
+ * @author ruoyi
13
+ */
14
+@Configuration
15
+public class ResourcesConfig implements WebMvcConfigurer
16
+{
17
+    /**
18
+     * 上传文件存储在本地的根路径
19
+     */
20
+    @Value("${file.path}")
21
+    private String localFilePath;
22
+
23
+    /**
24
+     * 资源映射路径 前缀
25
+     */
26
+    @Value("${file.prefix}")
27
+    public String localFilePrefix;
28
+
29
+    @Override
30
+    public void addResourceHandlers(ResourceHandlerRegistry registry)
31
+    {
32
+        /** 本地文件上传路径 */
33
+        registry.addResourceHandler(localFilePrefix + "/**")
34
+                .addResourceLocations("file:" + localFilePath + File.separator);
35
+    }
36
+}

+ 67 - 0
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/controller/SysFileController.java

@@ -0,0 +1,67 @@
1
+package com.ruoyi.file.controller;
2
+
3
+import org.slf4j.Logger;
4
+import org.slf4j.LoggerFactory;
5
+import org.springframework.beans.factory.annotation.Autowired;
6
+import org.springframework.beans.factory.annotation.Value;
7
+import org.springframework.web.bind.annotation.PostMapping;
8
+import org.springframework.web.bind.annotation.RestController;
9
+import org.springframework.web.multipart.MultipartFile;
10
+import com.ruoyi.common.core.domain.R;
11
+import com.ruoyi.file.service.ISysFileService;
12
+import com.ruoyi.system.api.domain.SysFile;
13
+
14
+/**
15
+ * 文件请求处理
16
+ * 
17
+ * @author ruoyi
18
+ */
19
+@RestController
20
+public class SysFileController
21
+{
22
+    private static final Logger log = LoggerFactory.getLogger(SysFileController.class);
23
+
24
+    /**
25
+     * 上传文件存储在本地的根路径
26
+     */
27
+    @Value("${file.path}")
28
+    private String localFilePath;
29
+
30
+    /**
31
+     * 资源映射路径 前缀
32
+     */
33
+    @Value("${file.prefix}")
34
+    public String localFilePrefix;
35
+
36
+    /**
37
+     * 域名或本机访问地址
38
+     */
39
+    @Value("${file.domain}")
40
+    public String domain;
41
+
42
+    @Autowired
43
+    private ISysFileService sysFileService;
44
+
45
+    /**
46
+     * 文件上传请求
47
+     */
48
+    @PostMapping("upload")
49
+    public R<SysFile> upload(MultipartFile file)
50
+    {
51
+        try
52
+        {
53
+            // 上传并返回新文件名称
54
+            String fileName = sysFileService.uploadFile(file, localFilePath);
55
+            String url = domain + localFilePrefix + fileName;
56
+            SysFile sysFile = new SysFile();
57
+            sysFile.setName(fileName);
58
+            sysFile.setUrl(url);
59
+            return R.ok(sysFile);
60
+        }
61
+        catch (Exception e)
62
+        {
63
+            log.error("上传文件失败", e);
64
+            return R.fail(e.getMessage());
65
+        }
66
+    }
67
+}

+ 21 - 0
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/ISysFileService.java

@@ -0,0 +1,21 @@
1
+package com.ruoyi.file.service;
2
+
3
+import org.springframework.web.multipart.MultipartFile;
4
+
5
+/**
6
+ * 文件上传接口
7
+ * 
8
+ * @author ruoyi
9
+ */
10
+public interface ISysFileService
11
+{
12
+    /**
13
+     * 文件上传接口
14
+     * 
15
+     * @param file 上传的文件
16
+     * @param baseDir 相对应用的基目录
17
+     * @return 文件名称
18
+     * @throws Exception
19
+     */
20
+    public String uploadFile(MultipartFile file, String baseDir) throws Exception;
21
+}

+ 27 - 0
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/service/LocalSysFileServiceImpl.java

@@ -0,0 +1,27 @@
1
+package com.ruoyi.file.service;
2
+
3
+import org.springframework.stereotype.Service;
4
+import org.springframework.web.multipart.MultipartFile;
5
+import com.ruoyi.file.utils.FileUploadUtils;
6
+
7
+/**
8
+ * 本地文件存储
9
+ * 
10
+ * @author ruoyi
11
+ */
12
+@Service
13
+public class LocalSysFileServiceImpl implements ISysFileService
14
+{
15
+    /**
16
+     * 文件上传接口
17
+     * 
18
+     * @param file 上传的文件
19
+     * @param baseDir 相对应用的基目录
20
+     * @return 文件名称
21
+     * @throws Exception
22
+     */
23
+    public String uploadFile(MultipartFile file, String baseDir) throws Exception
24
+    {
25
+        return FileUploadUtils.upload(baseDir, file);
26
+    }
27
+}

+ 204 - 0
ruoyi-modules/ruoyi-file/src/main/java/com/ruoyi/file/utils/FileUploadUtils.java

@@ -0,0 +1,204 @@
1
+package com.ruoyi.file.utils;
2
+
3
+import java.io.File;
4
+import java.io.IOException;
5
+import org.apache.commons.io.FilenameUtils;
6
+import org.springframework.beans.factory.annotation.Value;
7
+import org.springframework.web.multipart.MultipartFile;
8
+import com.ruoyi.common.core.exception.file.FileNameLengthLimitExceededException;
9
+import com.ruoyi.common.core.exception.file.FileSizeLimitExceededException;
10
+import com.ruoyi.common.core.exception.file.InvalidExtensionException;
11
+import com.ruoyi.common.core.utils.DateUtils;
12
+import com.ruoyi.common.core.utils.IdUtils;
13
+import com.ruoyi.common.core.utils.StringUtils;
14
+import com.ruoyi.common.core.utils.file.MimeTypeUtils;
15
+
16
+/**
17
+ * 文件上传工具类
18
+ * 
19
+ * @author ruoyi
20
+ */
21
+public class FileUploadUtils
22
+{
23
+    /**
24
+     * 默认大小 50M
25
+     */
26
+    public static final long DEFAULT_MAX_SIZE = 50 * 1024 * 1024;
27
+
28
+    /**
29
+     * 默认的文件名最大长度 100
30
+     */
31
+    public static final int DEFAULT_FILE_NAME_LENGTH = 100;
32
+
33
+    /**
34
+     * 资源映射路径 前缀
35
+     */
36
+    @Value("${file.prefix}")
37
+    public String localFilePrefix;
38
+
39
+    /**
40
+     * 根据文件路径上传
41
+     *
42
+     * @param baseDir 相对应用的基目录
43
+     * @param file 上传的文件
44
+     * @return 文件名称
45
+     * @throws IOException
46
+     */
47
+    public static final String upload(String baseDir, MultipartFile file) throws IOException
48
+    {
49
+        try
50
+        {
51
+            return upload(baseDir, file, MimeTypeUtils.DEFAULT_ALLOWED_EXTENSION);
52
+        }
53
+        catch (Exception e)
54
+        {
55
+            throw new IOException(e.getMessage(), e);
56
+        }
57
+    }
58
+
59
+    /**
60
+     * 文件上传
61
+     *
62
+     * @param baseDir 相对应用的基目录
63
+     * @param file 上传的文件
64
+     * @param extension 上传文件类型
65
+     * @return 返回上传成功的文件名
66
+     * @throws FileSizeLimitExceededException 如果超出最大大小
67
+     * @throws FileNameLengthLimitExceededException 文件名太长
68
+     * @throws IOException 比如读写文件出错时
69
+     * @throws InvalidExtensionException 文件校验异常
70
+     */
71
+    public static final String upload(String baseDir, MultipartFile file, String[] allowedExtension)
72
+            throws FileSizeLimitExceededException, IOException, FileNameLengthLimitExceededException,
73
+            InvalidExtensionException
74
+    {
75
+        int fileNamelength = file.getOriginalFilename().length();
76
+        if (fileNamelength > FileUploadUtils.DEFAULT_FILE_NAME_LENGTH)
77
+        {
78
+            throw new FileNameLengthLimitExceededException(FileUploadUtils.DEFAULT_FILE_NAME_LENGTH);
79
+        }
80
+
81
+        assertAllowed(file, allowedExtension);
82
+
83
+        String fileName = extractFilename(file);
84
+
85
+        File desc = getAbsoluteFile(baseDir, fileName);
86
+        file.transferTo(desc);
87
+        String pathFileName = getPathFileName(fileName);
88
+        return pathFileName;
89
+    }
90
+
91
+    /**
92
+     * 编码文件名
93
+     */
94
+    public static final String extractFilename(MultipartFile file)
95
+    {
96
+        String fileName = file.getOriginalFilename();
97
+        String extension = getExtension(file);
98
+        fileName = DateUtils.datePath() + "/" + IdUtils.fastUUID() + "." + extension;
99
+        return fileName;
100
+    }
101
+
102
+    private static final File getAbsoluteFile(String uploadDir, String fileName) throws IOException
103
+    {
104
+        File desc = new File(uploadDir + File.separator + fileName);
105
+
106
+        if (!desc.exists())
107
+        {
108
+            if (!desc.getParentFile().exists())
109
+            {
110
+                desc.getParentFile().mkdirs();
111
+            }
112
+        }
113
+        return desc;
114
+    }
115
+
116
+    private static final String getPathFileName(String fileName) throws IOException
117
+    {
118
+        String pathFileName = "/" + fileName;
119
+        return pathFileName;
120
+    }
121
+
122
+    /**
123
+     * 文件大小校验
124
+     *
125
+     * @param file 上传的文件
126
+     * @return
127
+     * @throws FileSizeLimitExceededException 如果超出最大大小
128
+     * @throws InvalidExtensionException
129
+     */
130
+    public static final void assertAllowed(MultipartFile file, String[] allowedExtension)
131
+            throws FileSizeLimitExceededException, InvalidExtensionException
132
+    {
133
+        long size = file.getSize();
134
+        if (DEFAULT_MAX_SIZE != -1 && size > DEFAULT_MAX_SIZE)
135
+        {
136
+            throw new FileSizeLimitExceededException(DEFAULT_MAX_SIZE / 1024 / 1024);
137
+        }
138
+
139
+        String fileName = file.getOriginalFilename();
140
+        String extension = getExtension(file);
141
+        if (allowedExtension != null && !isAllowedExtension(extension, allowedExtension))
142
+        {
143
+            if (allowedExtension == MimeTypeUtils.IMAGE_EXTENSION)
144
+            {
145
+                throw new InvalidExtensionException.InvalidImageExtensionException(allowedExtension, extension,
146
+                        fileName);
147
+            }
148
+            else if (allowedExtension == MimeTypeUtils.FLASH_EXTENSION)
149
+            {
150
+                throw new InvalidExtensionException.InvalidFlashExtensionException(allowedExtension, extension,
151
+                        fileName);
152
+            }
153
+            else if (allowedExtension == MimeTypeUtils.MEDIA_EXTENSION)
154
+            {
155
+                throw new InvalidExtensionException.InvalidMediaExtensionException(allowedExtension, extension,
156
+                        fileName);
157
+            }
158
+            else if (allowedExtension == MimeTypeUtils.VIDEO_EXTENSION)
159
+            {
160
+                throw new InvalidExtensionException.InvalidVideoExtensionException(allowedExtension, extension,
161
+                        fileName);
162
+            }
163
+            else
164
+            {
165
+                throw new InvalidExtensionException(allowedExtension, extension, fileName);
166
+            }
167
+        }
168
+    }
169
+
170
+    /**
171
+     * 判断MIME类型是否是允许的MIME类型
172
+     *
173
+     * @param extension
174
+     * @param allowedExtension
175
+     * @return
176
+     */
177
+    public static final boolean isAllowedExtension(String extension, String[] allowedExtension)
178
+    {
179
+        for (String str : allowedExtension)
180
+        {
181
+            if (str.equalsIgnoreCase(extension))
182
+            {
183
+                return true;
184
+            }
185
+        }
186
+        return false;
187
+    }
188
+
189
+    /**
190
+     * 获取文件名的后缀
191
+     * 
192
+     * @param file 表单文件
193
+     * @return 后缀名
194
+     */
195
+    public static final String getExtension(MultipartFile file)
196
+    {
197
+        String extension = FilenameUtils.getExtension(file.getOriginalFilename());
198
+        if (StringUtils.isEmpty(extension))
199
+        {
200
+            extension = MimeTypeUtils.getExtension(file.getContentType());
201
+        }
202
+        return extension;
203
+    }
204
+}

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

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

+ 24 - 0
ruoyi-modules/ruoyi-file/src/main/resources/bootstrap.yml

@@ -0,0 +1,24 @@
1
+# Tomcat
2
+server:
3
+  port: 9300
4
+
5
+# Spring
6
+spring: 
7
+  application:
8
+    # 应用名称
9
+    name: ruoyi-file
10
+  profiles:
11
+    # 环境配置
12
+    active: dev
13
+  cloud:
14
+    nacos:
15
+      discovery:
16
+        # 服务注册地址
17
+        server-addr: 127.0.0.1:8848
18
+      config:
19
+        # 配置中心地址
20
+        server-addr: 127.0.0.1:8848
21
+        # 配置文件格式
22
+        file-extension: yml
23
+        # 共享配置
24
+        shared-dataids: application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}

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

@@ -0,0 +1,74 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<configuration scan="true" scanPeriod="60 seconds" debug="false">
3
+    <!-- 日志存放路径 -->
4
+	<property name="log.path" value="logs/ruoyi-file" />
5
+   <!-- 日志输出格式 -->
6
+	<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n" />
7
+
8
+    <!-- 控制台输出 -->
9
+	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
10
+		<encoder>
11
+			<pattern>${log.pattern}</pattern>
12
+		</encoder>
13
+	</appender>
14
+
15
+    <!-- 系统日志输出 -->
16
+	<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
17
+	    <file>${log.path}/info.log</file>
18
+        <!-- 循环政策:基于时间创建日志文件 -->
19
+		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
20
+            <!-- 日志文件名格式 -->
21
+			<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
22
+			<!-- 日志最大的历史 60天 -->
23
+			<maxHistory>60</maxHistory>
24
+		</rollingPolicy>
25
+		<encoder>
26
+			<pattern>${log.pattern}</pattern>
27
+		</encoder>
28
+		<filter class="ch.qos.logback.classic.filter.LevelFilter">
29
+            <!-- 过滤的级别 -->
30
+            <level>INFO</level>
31
+            <!-- 匹配时的操作:接收(记录) -->
32
+            <onMatch>ACCEPT</onMatch>
33
+            <!-- 不匹配时的操作:拒绝(不记录) -->
34
+            <onMismatch>DENY</onMismatch>
35
+        </filter>
36
+	</appender>
37
+
38
+    <appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
39
+	    <file>${log.path}/error.log</file>
40
+        <!-- 循环政策:基于时间创建日志文件 -->
41
+        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
42
+            <!-- 日志文件名格式 -->
43
+            <fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
44
+			<!-- 日志最大的历史 60天 -->
45
+			<maxHistory>60</maxHistory>
46
+        </rollingPolicy>
47
+        <encoder>
48
+            <pattern>${log.pattern}</pattern>
49
+        </encoder>
50
+        <filter class="ch.qos.logback.classic.filter.LevelFilter">
51
+            <!-- 过滤的级别 -->
52
+            <level>ERROR</level>
53
+			<!-- 匹配时的操作:接收(记录) -->
54
+            <onMatch>ACCEPT</onMatch>
55
+			<!-- 不匹配时的操作:拒绝(不记录) -->
56
+            <onMismatch>DENY</onMismatch>
57
+        </filter>
58
+    </appender>
59
+
60
+    <!-- 系统模块日志级别控制  -->
61
+	<logger name="com.ruoyi" level="info" />
62
+	<!-- Spring日志级别控制  -->
63
+	<logger name="org.springframework" level="warn" />
64
+
65
+	<root level="info">
66
+		<appender-ref ref="console" />
67
+	</root>
68
+	
69
+	<!--系统操作日志-->
70
+    <root level="info">
71
+        <appender-ref ref="file_info" />
72
+        <appender-ref ref="file_error" />
73
+    </root>
74
+</configuration>

+ 41 - 0
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysProfileController.java

@@ -1,17 +1,26 @@
1 1
 package com.ruoyi.system.controller;
2 2
 
3
+import java.io.IOException;
3 4
 import org.springframework.beans.factory.annotation.Autowired;
4 5
 import org.springframework.web.bind.annotation.GetMapping;
6
+import org.springframework.web.bind.annotation.PostMapping;
5 7
 import org.springframework.web.bind.annotation.PutMapping;
6 8
 import org.springframework.web.bind.annotation.RequestBody;
7 9
 import org.springframework.web.bind.annotation.RequestMapping;
10
+import org.springframework.web.bind.annotation.RequestParam;
8 11
 import org.springframework.web.bind.annotation.RestController;
12
+import org.springframework.web.multipart.MultipartFile;
13
+import com.ruoyi.common.core.domain.R;
14
+import com.ruoyi.common.core.utils.ServletUtils;
15
+import com.ruoyi.common.core.utils.StringUtils;
9 16
 import com.ruoyi.common.core.web.controller.BaseController;
10 17
 import com.ruoyi.common.core.web.domain.AjaxResult;
11 18
 import com.ruoyi.common.log.annotation.Log;
12 19
 import com.ruoyi.common.log.enums.BusinessType;
13 20
 import com.ruoyi.common.security.service.TokenService;
14 21
 import com.ruoyi.common.security.utils.SecurityUtils;
22
+import com.ruoyi.system.api.RemoteFileService;
23
+import com.ruoyi.system.api.domain.SysFile;
15 24
 import com.ruoyi.system.api.domain.SysUser;
16 25
 import com.ruoyi.system.api.model.LoginUser;
17 26
 import com.ruoyi.system.service.ISysUserService;
@@ -30,6 +39,9 @@ public class SysProfileController extends BaseController
30 39
     
31 40
     @Autowired
32 41
     private TokenService tokenService;
42
+    
43
+    @Autowired
44
+    private RemoteFileService remoteFileService;
33 45
 
34 46
     /**
35 47
      * 个人信息
@@ -94,4 +106,33 @@ public class SysProfileController extends BaseController
94 106
         }
95 107
         return AjaxResult.error("修改密码异常,请联系管理员");
96 108
     }
109
+    
110
+    /**
111
+     * 头像上传
112
+     */
113
+    @Log(title = "用户头像", businessType = BusinessType.UPDATE)
114
+    @PostMapping("/avatar")
115
+    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws IOException
116
+    {
117
+        if (!file.isEmpty())
118
+        {
119
+            LoginUser loginUser = tokenService.getLoginUser(ServletUtils.getRequest());
120
+            R<SysFile> fileResult = remoteFileService.upload(file);
121
+            if (StringUtils.isNull(fileResult) || StringUtils.isNull(fileResult.getData()))
122
+            {
123
+                return AjaxResult.error("文件服务异常,请联系管理员");
124
+            }
125
+            String url = fileResult.getData().getUrl();
126
+            if (userService.updateUserAvatar(loginUser.getUsername(), url))
127
+            {
128
+                AjaxResult ajax = AjaxResult.success();
129
+                ajax.put("imgUrl", url);
130
+                // 更新缓存用户头像
131
+                loginUser.getSysUser().setAvatar(url);
132
+                tokenService.setLoginUser(loginUser);
133
+                return ajax;
134
+            }
135
+        }
136
+        return AjaxResult.error("上传图片异常,请联系管理员");
137
+    }
97 138
 }

+ 2 - 2
ruoyi-ui/src/components/UploadImage/index.vue

@@ -24,7 +24,7 @@ export default {
24 24
   components: {},
25 25
   data() {
26 26
     return {
27
-      uploadImgUrl: process.env.VUE_APP_BASE_API + "/common/upload", // 上传的图片服务器地址
27
+      uploadImgUrl: process.env.VUE_APP_BASE_API + "/file/upload", // 上传的图片服务器地址
28 28
       headers: {
29 29
         Authorization: "Bearer " + getToken(),
30 30
       },
@@ -38,7 +38,7 @@ export default {
38 38
   },
39 39
   methods: {
40 40
     handleUploadSuccess(res) {
41
-      this.$emit("input", res.url);
41
+      this.$emit("input", res.data.url);
42 42
       this.loading.close();
43 43
     },
44 44
     handleBeforeUpload() {

+ 1 - 1
ruoyi-ui/src/store/modules/user.js

@@ -57,7 +57,7 @@ const user = {
57 57
       return new Promise((resolve, reject) => {
58 58
         getInfo(state.token).then(res => {
59 59
           const user = res.user
60
-          const avatar = user.avatar == "" ? require("@/assets/image/profile.jpg") : process.env.VUE_APP_BASE_API + user.avatar;
60
+          const avatar = user.avatar == "" ? require("@/assets/image/profile.jpg") : user.avatar;
61 61
           if (res.roles && res.roles.length > 0) { // 验证返回的roles是否是一个非空数组
62 62
             commit('SET_ROLES', res.roles)
63 63
             commit('SET_PERMISSIONS', res.permissions)

+ 1 - 1
ruoyi-ui/src/views/system/user/profile/userAvatar.vue

@@ -126,7 +126,7 @@ export default {
126 126
         formData.append("avatarfile", data);
127 127
         uploadAvatar(formData).then(response => {
128 128
           this.open = false;
129
-          this.options.img = process.env.VUE_APP_BASE_API + response.imgUrl;
129
+          this.options.img = response.imgUrl;
130 130
           store.commit('SET_AVATAR', this.options.img);
131 131
           this.msgSuccess("修改成功");
132 132
           this.visible = false;

Dosya farkı çok büyük olduğundan ihmal edildi
+ 8 - 7
sql/ry_config_20200924.sql