|
|
|
@ -1,5 +1,7 @@
|
|
|
|
package com.ruoyi.system.service;
|
|
|
|
package com.ruoyi.system.service;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import cn.hutool.core.img.Img;
|
|
|
|
|
|
|
|
import cn.hutool.core.lang.UUID;
|
|
|
|
import com.ruoyi.common.core.domain.PageQuery;
|
|
|
|
import com.ruoyi.common.core.domain.PageQuery;
|
|
|
|
import com.ruoyi.common.core.page.TableDataInfo;
|
|
|
|
import com.ruoyi.common.core.page.TableDataInfo;
|
|
|
|
import com.ruoyi.system.domain.SysOss;
|
|
|
|
import com.ruoyi.system.domain.SysOss;
|
|
|
|
@ -8,7 +10,13 @@ import com.ruoyi.system.domain.vo.SysOssVo;
|
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
import org.springframework.web.multipart.MultipartFile;
|
|
|
|
|
|
|
|
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
import javax.servlet.http.HttpServletResponse;
|
|
|
|
|
|
|
|
import java.awt.*;
|
|
|
|
|
|
|
|
import java.awt.image.BufferedImage;
|
|
|
|
|
|
|
|
import java.io.ByteArrayInputStream;
|
|
|
|
|
|
|
|
import java.io.ByteArrayOutputStream;
|
|
|
|
import java.io.IOException;
|
|
|
|
import java.io.IOException;
|
|
|
|
|
|
|
|
import java.io.InputStream;
|
|
|
|
|
|
|
|
import java.util.Calendar;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.Collection;
|
|
|
|
import java.util.List;
|
|
|
|
import java.util.List;
|
|
|
|
|
|
|
|
|
|
|
|
@ -19,6 +27,8 @@ import java.util.List;
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public interface ISysOssService {
|
|
|
|
public interface ISysOssService {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
String IMAGE_WEBP="webp";
|
|
|
|
|
|
|
|
|
|
|
|
TableDataInfo<SysOssVo> queryPageList(SysOssBo sysOss, PageQuery pageQuery);
|
|
|
|
TableDataInfo<SysOssVo> queryPageList(SysOssBo sysOss, PageQuery pageQuery);
|
|
|
|
|
|
|
|
|
|
|
|
List<SysOssVo> listByIds(Collection<Long> ossIds);
|
|
|
|
List<SysOssVo> listByIds(Collection<Long> ossIds);
|
|
|
|
@ -27,8 +37,201 @@ public interface ISysOssService {
|
|
|
|
|
|
|
|
|
|
|
|
SysOssVo upload(MultipartFile file);
|
|
|
|
SysOssVo upload(MultipartFile file);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param file
|
|
|
|
|
|
|
|
* @param pre - 图片保存路径前缀
|
|
|
|
|
|
|
|
* @return
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
SysOssVo upload(MultipartFile file,String pre);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 使用默认的最大高宽和水印保存图片
|
|
|
|
|
|
|
|
* @param file
|
|
|
|
|
|
|
|
* @param pre - 图片保存路径前缀
|
|
|
|
|
|
|
|
* @return
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
SysOssVo uploadImgs(MultipartFile file,String pre);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param file
|
|
|
|
|
|
|
|
* @param pre - 图片保存路径前缀
|
|
|
|
|
|
|
|
* @param maxWidth - 缩放到指定的宽 小于1表示不缩放
|
|
|
|
|
|
|
|
* @param maxHeight - 缩放到指定的高 小于1表示不缩放
|
|
|
|
|
|
|
|
* @param watermark - 水印图片 null表示不加水印
|
|
|
|
|
|
|
|
* @return
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
SysOssVo uploadImgs(MultipartFile file,String pre, int maxWidth, int maxHeight,
|
|
|
|
|
|
|
|
BufferedImage watermark);
|
|
|
|
|
|
|
|
|
|
|
|
void download(Long ossId, HttpServletResponse response) throws IOException;
|
|
|
|
void download(Long ossId, HttpServletResponse response) throws IOException;
|
|
|
|
|
|
|
|
|
|
|
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
|
|
|
Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default InputStream formatImage(MultipartFile file, int maxWidth, int maxHeight,
|
|
|
|
|
|
|
|
BufferedImage watermark) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
if (file == null || file.isEmpty()) {
|
|
|
|
|
|
|
|
throw new RuntimeException("上传图片不能为空");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!file.getContentType().startsWith("image/")) {
|
|
|
|
|
|
|
|
throw new RuntimeException("上传的文件不是图片");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return formatImage(file.getInputStream(), maxWidth, maxHeight, watermark);
|
|
|
|
|
|
|
|
} catch (IOException e) {
|
|
|
|
|
|
|
|
throw new RuntimeException("处理图片错误", e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default InputStream formatImage(Image img, int maxWidth, int maxHeight, BufferedImage watermark) {
|
|
|
|
|
|
|
|
if (img == null) {
|
|
|
|
|
|
|
|
throw new RuntimeException("图片不能为空");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return formatImage(Img.from(img), maxWidth, maxHeight, watermark);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default InputStream formatImage(InputStream in, int maxWidth, int maxHeight, BufferedImage watermark) {
|
|
|
|
|
|
|
|
return formatImage(Img.from(in), maxWidth, maxHeight, watermark);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
default InputStream formatImage(Img img, int maxWidth, int maxHeight, BufferedImage watermark) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
int w = img.getImg().getWidth(null);
|
|
|
|
|
|
|
|
int h = img.getImg().getHeight(null);
|
|
|
|
|
|
|
|
if(maxWidth>0 && maxHeight > 0){
|
|
|
|
|
|
|
|
if (w > maxWidth || h > maxHeight) {
|
|
|
|
|
|
|
|
int outWidth = 0;
|
|
|
|
|
|
|
|
int outHeight = 0;
|
|
|
|
|
|
|
|
outHeight = maxWidth * h / w;
|
|
|
|
|
|
|
|
if (outHeight > maxHeight) {
|
|
|
|
|
|
|
|
outHeight = maxHeight;
|
|
|
|
|
|
|
|
outWidth = outHeight * maxWidth / h;
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
outWidth = maxWidth;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
img = img.scale(outWidth, outHeight);
|
|
|
|
|
|
|
|
w = outWidth;
|
|
|
|
|
|
|
|
h = outHeight;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (watermark != null) {
|
|
|
|
|
|
|
|
int ww = watermark.getWidth(null);
|
|
|
|
|
|
|
|
int wh = watermark.getHeight(null);
|
|
|
|
|
|
|
|
if (w > ww && h > wh) {
|
|
|
|
|
|
|
|
img = img.pressImage(watermark, 0, 0, 1f);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ByteArrayOutputStream pout = new ByteArrayOutputStream();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
img.setTargetImageType(IMAGE_WEBP).write(pout);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ByteArrayInputStream pin = new ByteArrayInputStream(pout.toByteArray());
|
|
|
|
|
|
|
|
pout.close();
|
|
|
|
|
|
|
|
pout = null;
|
|
|
|
|
|
|
|
return pin;
|
|
|
|
|
|
|
|
} catch (Exception e) {
|
|
|
|
|
|
|
|
throw new RuntimeException("处理图片错误", e);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* <pre>
|
|
|
|
|
|
|
|
* - 根据存放规则和文件名生成存放的URI
|
|
|
|
|
|
|
|
* - 支持
|
|
|
|
|
|
|
|
* - {yyyy}/{MM}/{dd}/{HH}/{mm}/{ss} 年月日时分秒
|
|
|
|
|
|
|
|
* - {UUID} 32位的唯一标志
|
|
|
|
|
|
|
|
* - {id} int类型的唯一id,防止重复建议+年月日路径
|
|
|
|
|
|
|
|
* - {id16} int类型的唯一id16进制表示,防止重复建议+年月日路径
|
|
|
|
|
|
|
|
* - {id36} int类型的唯一id36进制表示,防止重复建议+年月日路径
|
|
|
|
|
|
|
|
* - {filename} 文件基础名称
|
|
|
|
|
|
|
|
* - {ext} 扩展名
|
|
|
|
|
|
|
|
* </pre>
|
|
|
|
|
|
|
|
*
|
|
|
|
|
|
|
|
* @param rule
|
|
|
|
|
|
|
|
* @param filename
|
|
|
|
|
|
|
|
* @return
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
default String generateURI(String rule, String filename) {
|
|
|
|
|
|
|
|
Calendar c = Calendar.getInstance();
|
|
|
|
|
|
|
|
if (rule.contains("{yyyy}")) {
|
|
|
|
|
|
|
|
rule = rule.replace("{yyyy}", "" + c.get(Calendar.YEAR));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.contains("{MM}")) {
|
|
|
|
|
|
|
|
rule = rule.replace("{MM}", "" + (c.get(Calendar.MONTH) + 1));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.contains("{dd}")) {
|
|
|
|
|
|
|
|
rule = rule.replace("{dd}", "" + c.get(Calendar.DATE));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.contains("{HH}")) {
|
|
|
|
|
|
|
|
rule = rule.replace("{HH}", "" + c.get(Calendar.HOUR_OF_DAY));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.contains("{mm}")) {
|
|
|
|
|
|
|
|
rule = rule.replace("{mm}", "" + c.get(Calendar.MINUTE));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.contains("{ss}")) {
|
|
|
|
|
|
|
|
rule = rule.replace("{ss}", "" + c.get(Calendar.SECOND));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.contains("{UUID}")) {
|
|
|
|
|
|
|
|
rule = rule.replace("{UUID}", UUID.fastUUID().toString(true));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.contains("{id}")) {
|
|
|
|
|
|
|
|
rule = rule.replace("{id}", Integer.toString(id.nextId()));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.contains("{id16}")) {
|
|
|
|
|
|
|
|
rule = rule.replace("{id16}", Integer.toString(id.nextId(), 16));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.contains("{id36}")) {
|
|
|
|
|
|
|
|
rule = rule.replace("{id36}", Integer.toString(id.nextId(), 36));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rule.contains("{filename}")) {
|
|
|
|
|
|
|
|
String temp = null;
|
|
|
|
|
|
|
|
if (filename.contains(".")) {
|
|
|
|
|
|
|
|
temp = filename.substring(0, filename.lastIndexOf("."));
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
temp = filename;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
rule = rule.replace("{filename}", temp);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (rule.contains("{ext}")) {
|
|
|
|
|
|
|
|
String temp = null;
|
|
|
|
|
|
|
|
if (filename.contains(".")) {
|
|
|
|
|
|
|
|
temp = filename.substring(filename.lastIndexOf(".") + 1);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
temp = "";
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
rule = rule.replace("{ext}", temp.toLowerCase());
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return rule;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
Id id = new Id();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static class Id {
|
|
|
|
|
|
|
|
private long lastTimestamp = 0;
|
|
|
|
|
|
|
|
private int sequence = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public synchronized int nextId() {
|
|
|
|
|
|
|
|
long timestamp = System.currentTimeMillis();
|
|
|
|
|
|
|
|
if (lastTimestamp == timestamp) {
|
|
|
|
|
|
|
|
sequence = (sequence + 1) & 0xF;
|
|
|
|
|
|
|
|
if (sequence == 0) {
|
|
|
|
|
|
|
|
while (timestamp <= lastTimestamp) {
|
|
|
|
|
|
|
|
timestamp = System.currentTimeMillis();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
sequence = 0;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
lastTimestamp = timestamp;
|
|
|
|
|
|
|
|
return (int) (timestamp & 0xFFFF) << 8 | sequence;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|