生成缩略图;增大图片上传大小限制

This commit is contained in:
LeonardYoung 2021-10-29 21:32:24 +08:00
parent 74967faef3
commit d430360d38
9 changed files with 177 additions and 12 deletions

View File

@ -3,6 +3,7 @@ package com.ruoyi;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration; import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.scheduling.annotation.EnableAsync;
/** /**
* 启动程序 * 启动程序
@ -10,6 +11,7 @@ import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
* @author ruoyi * @author ruoyi
*/ */
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class }) @SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
@EnableAsync
public class RuoYiApplication public class RuoYiApplication
{ {
public static void main(String[] args) public static void main(String[] args)

View File

@ -10,7 +10,10 @@ import com.ruoyi.common.core.page.VisualRespEmbData;
import com.ruoyi.system.service.impl.BladeVisualConfigServiceImpl; import com.ruoyi.system.service.impl.BladeVisualConfigServiceImpl;
import com.ruoyi.web.param.BladeVisualParam; import com.ruoyi.web.param.BladeVisualParam;
import org.springframework.beans.factory.annotation.Autowired; 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.security.core.context.SecurityContextHolder;
import org.springframework.util.unit.DataSize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; import com.ruoyi.common.core.controller.BaseController;
@ -21,6 +24,7 @@ import com.ruoyi.system.service.IBladeVisualService;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.annotation.Resource; import javax.annotation.Resource;
import javax.servlet.MultipartConfigElement;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
@ -139,5 +143,6 @@ public class BladeVisualController extends BaseController
return bladeVisualService.uploadFile(file); return bladeVisualService.uploadFile(file);
} }
} }

View File

@ -5,14 +5,22 @@ import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.utils.spring.SpringUtils;
import com.ruoyi.common.utils.uuid.UUID; import com.ruoyi.common.utils.uuid.UUID;
import com.ruoyi.system.service.impl.VisualImageServiceImpl;
import com.ruoyi.web.param.VisualImageAddParam; import com.ruoyi.web.param.VisualImageAddParam;
import org.aspectj.weaver.loadtime.Aj;
import org.springframework.beans.factory.annotation.Value; 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.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.util.unit.DataSize;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log; import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController; 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 com.ruoyi.common.core.page.TableDataInfo;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
import javax.servlet.MultipartConfigElement;
/** /**
* 图片管理管理上传的图片Controller * 图片管理管理上传的图片Controller
* *
@ -83,13 +93,27 @@ public class VisualImageController extends BaseController
{ {
String name = SecurityContextHolder.getContext().getAuthentication().getName(); String name = SecurityContextHolder.getContext().getAuthentication().getName();
visualImage.setCreateBy(name); visualImage.setCreateBy(name);
visualImageService.saveThumb(visualImage);
// 切割图片是异步进行的
visualImageService.divideImage(visualImage); visualImageService.divideImage(visualImage);
return toAjax(visualImageService.insertVisualImage(visualImage)); return toAjax(visualImageService.insertVisualImage(visualImage));
} }
// @Value("${imageDir.visualImage}") // @Value("${imageDir.visualImage}")
// private String imageDir; // 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')") // @PreAuthorize("@ss.hasPermi('system:image:add')")
// @Log(title = "图片管理。管理上传的图片", businessType = BusinessType.INSERT) // @Log(title = "图片管理。管理上传的图片", businessType = BusinessType.INSERT)
@ -143,6 +167,20 @@ public class VisualImageController extends BaseController
@DeleteMapping("/{ids}") @DeleteMapping("/{ids}")
public AjaxResult remove(@PathVariable Long[] ids) public AjaxResult remove(@PathVariable Long[] ids)
{ {
// todo 删除本地图片
return toAjax(visualImageService.deleteVisualImageByIds(ids)); 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();
}
} }

View File

@ -9,8 +9,8 @@ ruoyi:
# 实例演示开关 # 实例演示开关
demoEnabled: true demoEnabled: true
# 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath # 文件路径 示例( Windows配置D:/ruoyi/uploadPathLinux配置 /home/ruoyi/uploadPath
# profile: F:/ruoyi/uploadPath profile: F:/ruoyi/uploadPath
profile: /home/yangsj/bigScreen # profile: /home/yangsj/bigScreen
# 获取ip地址开关 # 获取ip地址开关
addressEnabled: false addressEnabled: false
# 验证码类型 math 数组计算 char 字符验证 # 验证码类型 math 数组计算 char 字符验证
@ -21,6 +21,11 @@ imageDir:
bigScreen: /overview bigScreen: /overview
# 其他图片存放文件夹名 # 其他图片存放文件夹名
visualImage: /images visualImage: /images
# 缩略图宽高
width: 100
height: 100
# 上传图片最大MB
maxImageMB: 300
# 开发环境配置 # 开发环境配置

View File

@ -108,6 +108,7 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter
"/profile/**" "/profile/**"
).permitAll() ).permitAll()
.antMatchers("/avue/api/category/list").permitAll() .antMatchers("/avue/api/category/list").permitAll()
// .antMatchers("/system/visualImage/link").permitAll() // 测试
.antMatchers("/avue/api/visual/put-file").permitAll() .antMatchers("/avue/api/visual/put-file").permitAll()
.antMatchers("/system/visualImage/upload").anonymous() .antMatchers("/system/visualImage/upload").anonymous()
.antMatchers("/swagger-ui.html").anonymous() .antMatchers("/swagger-ui.html").anonymous()

View File

@ -1,6 +1,8 @@
package com.ruoyi.system.service; package com.ruoyi.system.service;
import java.util.List; import java.util.List;
import java.util.Map;
import com.ruoyi.system.domain.VisualImage; import com.ruoyi.system.domain.VisualImage;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -64,5 +66,9 @@ public interface IVisualImageService
String saveImageToLocal(MultipartFile file); String saveImageToLocal(MultipartFile file);
int divideImage(VisualImage visualImage); void divideImage(VisualImage visualImage);
void saveThumb(VisualImage visualImage);
Map<String,String> getLink(String fileName);
} }

View File

@ -3,13 +3,19 @@ package com.ruoyi.system.service.impl;
import java.awt.*; import java.awt.*;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.io.*; import java.io.*;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
import com.ruoyi.common.config.RuoYiConfig; import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.Constants;
import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.UUID; import com.ruoyi.common.utils.uuid.UUID;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value; import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import com.ruoyi.system.mapper.VisualImageMapper; import com.ruoyi.system.mapper.VisualImageMapper;
import com.ruoyi.system.domain.VisualImage; import com.ruoyi.system.domain.VisualImage;
@ -135,7 +141,8 @@ public class VisualImageServiceImpl implements IVisualImageService {
} }
@Override @Override
public int divideImage(VisualImage visualImage) { @Async
public void divideImage(VisualImage visualImage) {
String rootPath = RuoYiConfig.getProfile() + imageDir; String rootPath = RuoYiConfig.getProfile() + imageDir;
String newFileName = rootPath + "/" + visualImage.getNewName(); String newFileName = rootPath + "/" + visualImage.getNewName();
// 读入大图 // 读入大图
@ -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;
} }
} }

View File

@ -60,3 +60,12 @@ export function uploadImage(query) {
params: query params: query
}) })
} }
// 获取link
export function getLink(name) {
return request({
url: '/system/visualImage/link',
method: 'get',
params: name
})
}

View File

@ -50,7 +50,7 @@
<el-table-column label="新文件名" align="center" prop="newName" /> <el-table-column label="新文件名" align="center" prop="newName" />
<el-table-column label="切割宽高" align="center"> <el-table-column label="切割宽高" align="center">
<template slot-scope="scope"> <template slot-scope="scope">
<span >{{ scope.row.width + " × " + scope.row.height}}</span> <span>{{ scope.row.width + " × " + scope.row.height}}</span>
</template> </template>
</el-table-column> </el-table-column>
@ -121,7 +121,8 @@
delVisualImage, delVisualImage,
addVisualImage, addVisualImage,
updateVisualImage, updateVisualImage,
exportVisualImage exportVisualImage,
getLink
} from "@/api/system/visualImage"; } from "@/api/system/visualImage";
// import { getToken } from '@/utils/auth' // import { getToken } from '@/utils/auth'
@ -160,30 +161,46 @@
}, },
// //
form: {}, form: {},
imageUrl:null, imageUrl: null,
uploadHeader: {}, uploadHeader: {},
// //
rules: {} rules: {},
loadObj:null,
}; };
}, },
created() { created() {
this.getList(); this.getList();
}, },
mounted() { mounted() {
//
getLink({fileName:"test.png"})
// this.uploadHeader['Content-Type'] = 'multipart/form-data' // this.uploadHeader['Content-Type'] = 'multipart/form-data'
// this.uploadHeader['Authorization'] = 'Bearer ' + getToken() // this.uploadHeader['Authorization'] = 'Bearer ' + getToken()
// console.log(this.uploadHeader); // console.log(this.uploadHeader);
}, },
methods: { 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) { handleAvatarSuccess(res, file) {
console.log(res, file); console.log(res, file);
this.form.originName = file.name this.form.originName = file.name
this.form.newName = res.data.name this.form.newName = res.data.name
this.imageUrl = URL.createObjectURL(file.raw); this.imageUrl = URL.createObjectURL(file.raw);
this.loadingClose()
}, },
beforeUpload(file) { beforeUpload(file) {
// //
this.form.newName = null this.form.newName = null
this.loadingStart()
return true; return true;
}, },
/** 查询图片管理。管理上传的图片列表 */ /** 查询图片管理。管理上传的图片列表 */