From d430360d38039c03f9e876346cd7a60046009a62 Mon Sep 17 00:00:00 2001
From: LeonardYoung <shaojun47@qq.com>
Date: Fri, 29 Oct 2021 21:32:24 +0800
Subject: [PATCH] =?UTF-8?q?=E7=94=9F=E6=88=90=E7=BC=A9=E7=95=A5=E5=9B=BE?=
 =?UTF-8?q?=EF=BC=9B=E5=A2=9E=E5=A4=A7=E5=9B=BE=E7=89=87=E4=B8=8A=E4=BC=A0?=
 =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E9=99=90=E5=88=B6?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../main/java/com/ruoyi/RuoYiApplication.java |  4 +-
 .../system/BladeVisualController.java         |  7 +-
 .../system/VisualImageController.java         | 38 ++++++++
 .../src/main/resources/application.yml        |  9 +-
 .../framework/config/SecurityConfig.java      |  1 +
 .../system/service/IVisualImageService.java   |  8 +-
 .../service/impl/VisualImageServiceImpl.java  | 88 ++++++++++++++++++-
 ruoyi-ui/src/api/system/visualImage.js        |  9 ++
 .../src/views/screen/visualImage/index.vue    | 25 +++++-
 9 files changed, 177 insertions(+), 12 deletions(-)

diff --git a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
index e3c56ee54..14eac049e 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/RuoYiApplication.java
@@ -3,13 +3,15 @@ package com.ruoyi;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
+import org.springframework.scheduling.annotation.EnableAsync;
 
 /**
  * 启动程序
- * 
+ *
  * @author ruoyi
  */
 @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
+@EnableAsync
 public class RuoYiApplication
 {
     public static void main(String[] args)
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/BladeVisualController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/BladeVisualController.java
index 0c6b9e871..e76e9ffd1 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/BladeVisualController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/BladeVisualController.java
@@ -10,7 +10,10 @@ import com.ruoyi.common.core.page.VisualRespEmbData;
 import com.ruoyi.system.service.impl.BladeVisualConfigServiceImpl;
 import com.ruoyi.web.param.BladeVisualParam;
 import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.web.servlet.MultipartConfigFactory;
+import org.springframework.context.annotation.Bean;
 import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.util.unit.DataSize;
 import org.springframework.web.bind.annotation.*;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.core.controller.BaseController;
@@ -21,6 +24,7 @@ import com.ruoyi.system.service.IBladeVisualService;
 import org.springframework.web.multipart.MultipartFile;
 
 import javax.annotation.Resource;
+import javax.servlet.MultipartConfigElement;
 import javax.servlet.http.HttpServletRequest;
 
 /**
@@ -105,7 +109,7 @@ public class BladeVisualController extends BaseController
         String name = SecurityContextHolder.getContext().getAuthentication().getName();
         param.getVisual().setUpdateBy(name);
         param.getVisual().setUpdateTime(new Date());
-        
+
         int i = bladeVisualService.updateBladeVisual(param.getVisual());
 
         int j = configService.updateBladeVisualConfig(param.getConfig());
@@ -139,5 +143,6 @@ public class BladeVisualController extends BaseController
         return bladeVisualService.uploadFile(file);
 
     }
+
 }
 
diff --git a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/VisualImageController.java b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/VisualImageController.java
index 9c2d53938..7afbed084 100644
--- a/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/VisualImageController.java
+++ b/ruoyi-admin/src/main/java/com/ruoyi/web/controller/system/VisualImageController.java
@@ -5,14 +5,22 @@ import java.io.FileOutputStream;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import com.ruoyi.common.config.RuoYiConfig;
+import com.ruoyi.common.utils.spring.SpringUtils;
 import com.ruoyi.common.utils.uuid.UUID;
+import com.ruoyi.system.service.impl.VisualImageServiceImpl;
 import com.ruoyi.web.param.VisualImageAddParam;
+import org.aspectj.weaver.loadtime.Aj;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.web.servlet.MultipartConfigFactory;
+import org.springframework.context.ApplicationContext;
+import org.springframework.context.annotation.Bean;
 import org.springframework.security.access.prepost.PreAuthorize;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.security.core.context.SecurityContextHolder;
+import org.springframework.util.unit.DataSize;
 import org.springframework.web.bind.annotation.*;
 import com.ruoyi.common.annotation.Log;
 import com.ruoyi.common.core.controller.BaseController;
@@ -24,6 +32,8 @@ import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.common.core.page.TableDataInfo;
 import org.springframework.web.multipart.MultipartFile;
 
+import javax.servlet.MultipartConfigElement;
+
 /**
  * 图片管理。管理上传的图片Controller
  *
@@ -83,13 +93,27 @@ public class VisualImageController extends BaseController
     {
         String name = SecurityContextHolder.getContext().getAuthentication().getName();
         visualImage.setCreateBy(name);
+        visualImageService.saveThumb(visualImage);
+        // 切割图片是异步进行的
         visualImageService.divideImage(visualImage);
+
         return toAjax(visualImageService.insertVisualImage(visualImage));
     }
 
 //    @Value("${imageDir.visualImage}")
 //    private String imageDir;
 
+    @PreAuthorize("@ss.hasPermi('system:image:query')")
+    @GetMapping("/link")
+    private AjaxResult getLink(@RequestParam String fileName){
+        IVisualImageService vService = SpringUtils.getBean(IVisualImageService.class);
+        Map<String, String> map = vService.getLink(fileName);
+        if (map == null) {
+            return AjaxResult.error("文件名错误");
+        }
+        return AjaxResult.success(map);
+    }
+
 
 //    @PreAuthorize("@ss.hasPermi('system:image:add')")
 //    @Log(title = "图片管理。管理上传的图片", businessType = BusinessType.INSERT)
@@ -143,6 +167,20 @@ public class VisualImageController extends BaseController
 	@DeleteMapping("/{ids}")
     public AjaxResult remove(@PathVariable Long[] ids)
     {
+        // todo 删除本地图片
         return toAjax(visualImageService.deleteVisualImageByIds(ids));
     }
+
+    @Value("${imageDir.maxImageMB}")
+    private Integer maxImage;
+
+    @Bean
+    public MultipartConfigElement multipartConfigElement() {
+        MultipartConfigFactory factory = new MultipartConfigFactory();
+        factory.setMaxRequestSize(DataSize.ofMegabytes(maxImage));
+        factory.setMaxFileSize(DataSize.ofMegabytes(maxImage));
+        return factory.createMultipartConfig();
+    }
+
+
 }
diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml
index df1b2f10f..8e56de1f6 100644
--- a/ruoyi-admin/src/main/resources/application.yml
+++ b/ruoyi-admin/src/main/resources/application.yml
@@ -9,8 +9,8 @@ ruoyi:
   # 实例演示开关
   demoEnabled: true
   # 文件路径 示例( Windows配置D:/ruoyi/uploadPath,Linux配置 /home/ruoyi/uploadPath)
-#  profile: F:/ruoyi/uploadPath
-  profile: /home/yangsj/bigScreen
+  profile: F:/ruoyi/uploadPath
+#  profile: /home/yangsj/bigScreen
   # 获取ip地址开关
   addressEnabled: false
   # 验证码类型 math 数组计算 char 字符验证
@@ -21,6 +21,11 @@ imageDir:
   bigScreen: /overview
   # 其他图片存放文件夹名
   visualImage: /images
+  # 缩略图宽高
+  width: 100
+  height: 100
+  # 上传图片最大(MB)
+  maxImageMB: 300
 
 
 # 开发环境配置
diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
index 13057ac78..5ff6e3dc6 100644
--- a/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
+++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/config/SecurityConfig.java
@@ -108,6 +108,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
                         "/profile/**"
                 ).permitAll()
                 .antMatchers("/avue/api/category/list").permitAll()
+//                .antMatchers("/system/visualImage/link").permitAll()  // 测试
                 .antMatchers("/avue/api/visual/put-file").permitAll()
                 .antMatchers("/system/visualImage/upload").anonymous()
                 .antMatchers("/swagger-ui.html").anonymous()
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/IVisualImageService.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/IVisualImageService.java
index 274111182..93dac5bb9 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/IVisualImageService.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/IVisualImageService.java
@@ -1,6 +1,8 @@
 package com.ruoyi.system.service;
 
 import java.util.List;
+import java.util.Map;
+
 import com.ruoyi.system.domain.VisualImage;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -64,5 +66,9 @@ public interface IVisualImageService
 
     String saveImageToLocal(MultipartFile file);
 
-    int divideImage(VisualImage visualImage);
+    void divideImage(VisualImage visualImage);
+
+    void saveThumb(VisualImage visualImage);
+
+    Map<String,String> getLink(String fileName);
 }
diff --git a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VisualImageServiceImpl.java b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VisualImageServiceImpl.java
index 61e7b4bd4..c7bb46d32 100644
--- a/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VisualImageServiceImpl.java
+++ b/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/VisualImageServiceImpl.java
@@ -3,13 +3,19 @@ package com.ruoyi.system.service.impl;
 import java.awt.*;
 import java.awt.image.BufferedImage;
 import java.io.*;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.HashMap;
 import java.util.List;
+import java.util.Map;
 
 import com.ruoyi.common.config.RuoYiConfig;
+import com.ruoyi.common.constant.Constants;
 import com.ruoyi.common.utils.DateUtils;
 import com.ruoyi.common.utils.uuid.UUID;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.beans.factory.annotation.Value;
+import org.springframework.scheduling.annotation.Async;
 import org.springframework.stereotype.Service;
 import com.ruoyi.system.mapper.VisualImageMapper;
 import com.ruoyi.system.domain.VisualImage;
@@ -135,7 +141,8 @@ public class VisualImageServiceImpl implements IVisualImageService {
     }
 
     @Override
-    public int divideImage(VisualImage visualImage) {
+    @Async
+    public void divideImage(VisualImage visualImage) {
         String rootPath = RuoYiConfig.getProfile() + imageDir;
         String newFileName = rootPath + "/" + visualImage.getNewName();
         // 读入大图
@@ -179,7 +186,7 @@ public class VisualImageServiceImpl implements IVisualImageService {
                     gr.dispose();
 
                     // 输出小图
-                    String outFileName = outputDir + "/" + x + "_" + y + "." +  split[split.length - 1];
+                    String outFileName = outputDir + "/" + x + "_" + y + "." + split[split.length - 1];
                     ImageIO.write(imgs[count], split[split.length - 1], new File(outFileName));
                     count++;
                 }
@@ -190,6 +197,81 @@ public class VisualImageServiceImpl implements IVisualImageService {
         }
 
 
-        return 0;
+    }
+
+    @Value("${imageDir.width}")
+    private Integer thumbWidth;
+
+    @Value("${imageDir.height}")
+    private Integer thumbHeigth;
+
+    @Async
+    @Override
+    public void saveThumb(VisualImage visualImage) {
+        String rootPath = RuoYiConfig.getProfile() + imageDir;
+        String newFileName = rootPath + "/" + visualImage.getNewName();
+        // 读入大图
+        File file = new File(newFileName);
+        FileInputStream fis;
+        try {
+            fis = new FileInputStream(file);
+            BufferedImage image = ImageIO.read(fis);
+
+            // 新建文件夹存放子图
+            String[] split = visualImage.getNewName().split("\\.");
+            String outputDir = rootPath + "/" + split[0];
+            File targetFile = new File(outputDir);
+            if (!targetFile.exists()) {
+                targetFile.mkdirs();
+            }
+
+            //设置小图的大小和类型
+            BufferedImage imgs = new BufferedImage(thumbWidth, thumbHeigth, image.getType());
+
+            //写入图像内容
+            Graphics2D gr = imgs.createGraphics();
+            gr.drawImage(image, 0, 0, thumbWidth, thumbHeigth, null);
+            gr.dispose();
+
+            // 输出小图
+            String outFileName = outputDir +"/thumb."+ split[split.length - 1];
+            ImageIO.write(imgs, split[split.length - 1], new File(outFileName));
+
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Value("${server.port}")
+    private int serverPort;
+
+    @Value("${imageDir.visualImage}")
+    private String imagePrefix;
+
+    public String getUrl() {
+        InetAddress address = null;
+        try {
+            address = InetAddress.getLocalHost();
+        } catch ( UnknownHostException e) {
+            e.printStackTrace();
+        }
+        return "http://"+address.getHostAddress() +":"+this.serverPort;
+    }
+
+    @Override
+    public Map<String, String> getLink(String fileName) {
+        // todo 这里应该查找数据库或本地资源,判断图片是否存在
+
+        HashMap<String, String> map = new HashMap<>();
+        String[] split = fileName.split("\\.");
+        if (split.length != 2) {
+            return null;
+        }
+        String rootDir = this.getUrl() + Constants.RESOURCE_PREFIX +imagePrefix +"/";
+        map.put("subRoot",rootDir + split[0] + "/");
+        map.put("original",rootDir+fileName);
+        map.put("thumb",rootDir+"thumb."+ split[1]);
+
+        return map;
     }
 }
diff --git a/ruoyi-ui/src/api/system/visualImage.js b/ruoyi-ui/src/api/system/visualImage.js
index 04fe31c19..02f5f3889 100644
--- a/ruoyi-ui/src/api/system/visualImage.js
+++ b/ruoyi-ui/src/api/system/visualImage.js
@@ -60,3 +60,12 @@ export function uploadImage(query) {
     params: query
   })
 }
+
+// 获取link
+export function getLink(name) {
+  return request({
+    url: '/system/visualImage/link',
+    method: 'get',
+    params: name
+  })
+}
diff --git a/ruoyi-ui/src/views/screen/visualImage/index.vue b/ruoyi-ui/src/views/screen/visualImage/index.vue
index 6dd33c177..f15824b20 100644
--- a/ruoyi-ui/src/views/screen/visualImage/index.vue
+++ b/ruoyi-ui/src/views/screen/visualImage/index.vue
@@ -50,7 +50,7 @@
       <el-table-column label="新文件名" align="center" prop="newName" />
       <el-table-column label="切割宽高" align="center">
         <template slot-scope="scope">
-          <span >{{ scope.row.width + " × " +  scope.row.height}}</span>
+          <span>{{ scope.row.width + " × " +  scope.row.height}}</span>
         </template>
       </el-table-column>
 
@@ -121,7 +121,8 @@
     delVisualImage,
     addVisualImage,
     updateVisualImage,
-    exportVisualImage
+    exportVisualImage,
+    getLink
   } from "@/api/system/visualImage";
   // import { getToken } from '@/utils/auth'
 
@@ -160,30 +161,46 @@
         },
         // 表单参数
         form: {},
-        imageUrl:null,
+        imageUrl: null,
         uploadHeader: {},
         // 表单校验
-        rules: {}
+        rules: {},
+        loadObj:null,
       };
     },
     created() {
       this.getList();
     },
     mounted() {
+      // 测试代码
+      getLink({fileName:"test.png"})
       // this.uploadHeader['Content-Type'] = 'multipart/form-data'
       // this.uploadHeader['Authorization'] = 'Bearer ' + getToken()
       // console.log(this.uploadHeader);
     },
     methods: {
+      loadingStart() {
+        this.loadObj = this.$loading({
+          lock: true,
+          text: '正在上传',
+          spinner: 'el-icon-loading',
+          background: 'rgba(0, 0, 0, 0.7)'
+        });
+      },
+      loadingClose(){
+        this.loadObj.close();
+      },
       handleAvatarSuccess(res, file) {
         console.log(res, file);
         this.form.originName = file.name
         this.form.newName = res.data.name
         this.imageUrl = URL.createObjectURL(file.raw);
+        this.loadingClose()
       },
       beforeUpload(file) {
         //
         this.form.newName = null
+        this.loadingStart()
         return true;
       },
       /** 查询图片管理。管理上传的图片列表 */