feat: add minio

This commit is contained in:
landaiqing
2024-05-13 00:56:48 +08:00
parent c84289fe0a
commit 368d551b51
17 changed files with 1018 additions and 5 deletions

View File

@@ -4,9 +4,7 @@ import com.schisandra.auth.application.dto.SchisandraCaptchaDTO;
import com.schisandra.auth.common.entity.CaptchaResult;
import com.schisandra.auth.common.redis.RedisUtil;
import com.schisandra.auth.common.utils.AESUtils;
import com.schisandra.auth.common.utils.MD5Util;
import com.schisandra.auth.common.utils.RotateImageUtils;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
@@ -17,7 +15,6 @@ import javax.annotation.Resource;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Random;

View File

@@ -16,6 +16,12 @@ spring:
- Path=/auth/**
filters:
- StripPrefix=1
- id: system
uri: lb://schisandra-cloud-storage-system-dev
predicates:
- Path=/system/**
filters:
- StripPrefix=1
# redis配置
redis:
# Redis数据库索引默认为0

View File

@@ -0,0 +1,47 @@
package com.schisandra.oss.application.controller;
import com.schisandra.oss.application.oss.constant.OssConstant;
import com.schisandra.oss.application.oss.utils.MinIOUtils;
import com.schisandra.oss.domain.bo.SchisandraOssConfigBO;
import com.schisandra.oss.domain.service.impl.SchisandraOssConfigDomainService;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
/**
* @Classname SchisandraMinioOssController
* @BelongsProject: schisandra-cloud-storage
* @BelongsPackage: com.schisandra.oss.application.controller
* @Author: landaiqing
* @CreateTime: 2024-05-13 00:04
* @Description: TODO
* @Version: 1.0
*/
@RestController
@RequestMapping("/oss/minio/")
@Slf4j
public class SchisandraMinioOssController {
@Resource
private SchisandraOssConfigDomainService schisandraOssConfigDomainService;
@RequestMapping("init")
@SneakyThrows
public void init() {
SchisandraOssConfigBO minio = schisandraOssConfigDomainService.getOssConfig(OssConstant.OssType.MINIO);
if (ObjectUtils.isEmpty(minio)) {
log.error("minio配置信息获取失败");
}
new MinIOUtils(minio.getEndpoint(), minio.getBucketName(), minio.getAccessKey(), minio.getSecretKey(), minio.getImgSize(), minio.getFileSize());
}
@GetMapping("test")
public void test(){
System.out.println(MinIOUtils.getBasisUrl());
}
}

View File

@@ -18,5 +18,6 @@ public interface SchisandraOssConfigDTOConverter {
SchisandraOssConfigDTOConverter INSTANCE = Mappers.getMapper(SchisandraOssConfigDTOConverter.class);
SchisandraOssConfigBO convertDTOToBO(SchisandraOssConfigDTO schisandraOssConfigDTO);
SchisandraOssConfigDTO convertBOToDTO(SchisandraOssConfigBO schisandraOssConfig);
}

View File

@@ -0,0 +1,60 @@
package com.schisandra.oss.application.oss.constant;
import java.util.concurrent.TimeUnit;
/**
* @author landaiqing
*/
public class OssConstant {
public static final String OSS = "oss";
public static final String ENABLE = "enable";
public static final String DEFAULT_ENABLE_VALUE = "true";
public static final int KB = 1024;
public static final int MB = 1024 * KB;
/**
* 默认分片大小
*/
public static final Long DEFAULT_PART_SIZE = 5L * MB;
/**
* 默认缓冲区大小
*/
public static final int DEFAULT_BUFFER_SIZE = 8 * KB;
/**
* 默认最大分片数
*/
public static final Long DEFAULT_PART_NUM = 10000L;
/**
* 默认并发线程数
*/
public static final Integer DEFAULT_TASK_NUM = Runtime.getRuntime().availableProcessors();
public static final Long DEFAULT_CONNECTION_TIMEOUT = TimeUnit.MINUTES.toMillis(5);
/**
* OSS存储类型
*/
public interface OssType {
String LOCAL = "local";
String FTP = "ftp";
String SFTP = "sftp";
String ALI = "ali";
String QINIU = "qiniu";
String MINIO = "minio";
String BAIDU = "baidu";
String TENCENT = "tencent";
String HUAWEI = "huawei";
String JD = "jd";
String UP = "up";
String JINSHAN = "jinshan";
String WANGYI = "wangyi";
String UCLOUD = "ucloud";
String PINGAN = "pingan";
String QINGYUN = "qingyun";
String JDBC = "jdbc";
String AWS = "aws";
}
}

View File

@@ -0,0 +1,107 @@
package com.schisandra.oss.application.oss.constant;
/**
* @author landaiqing
*/
public enum OssType {
/**
* 本地磁盘存储
*/
LOCAL(OssConstant.OssType.LOCAL),
/**
* FTP协议存储
*/
FTP(OssConstant.OssType.FTP),
/**
* SFTP存储
*/
SFTP(OssConstant.OssType.SFTP),
/**
* 阿里OSS存储
*/
ALI(OssConstant.OssType.ALI),
/**
* 七牛云存储
*/
QINIU(OssConstant.OssType.QINIU),
/**
* MinIO存储
*/
MINIO(OssConstant.OssType.MINIO),
/**
* 百度云存储
*/
BAIDU(OssConstant.OssType.BAIDU),
/**
* 腾讯云存储
*/
TENCENT(OssConstant.OssType.TENCENT),
/**
* 华为云存储
*/
HUAWEI(OssConstant.OssType.HUAWEI),
/**
* 京东云存储
*/
JD(OssConstant.OssType.JD),
/**
* 又拍云存储
*/
UP(OssConstant.OssType.UP),
/**
* 金山云
*/
JINSHAN(OssConstant.OssType.JINSHAN),
/**
* 网易数帆
*/
WANGYI(OssConstant.OssType.WANGYI),
/**
* UCloud
*/
UCLOUD(OssConstant.OssType.UCLOUD),
/**
* 平安云
*/
PINGAN(OssConstant.OssType.PINGAN),
/**
* 青云
*/
QINGYUN(OssConstant.OssType.QINGYUN),
/**
* JDBC
*/
JDBC(OssConstant.OssType.JDBC),
/**
* 亚马逊
*/
AWS(OssConstant.OssType.AWS);
private final String value;
OssType(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}

View File

@@ -0,0 +1,52 @@
package com.schisandra.oss.application.oss.enums;
import cn.hutool.core.util.StrUtil;
public enum OssContentType {
DEFAULT("default","application/octet-stream"),
JPG("jpg", "image/jpeg"),
TIFF("tiff", "image/tiff"),
GIF("gif", "image/gif"),
JFIF("jfif", "image/jpeg"),
PNG("png", "image/png"),
TIF("tif", "image/tiff"),
ICO("ico", "image/x-icon"),
JPEG("jpeg", "image/jpeg"),
WBMP("wbmp", "image/vnd.wap.wbmp"),
FAX("fax", "image/fax"),
NET("net", "image/pnetvue"),
JPE("jpe", "image/jpeg"),
RP("rp", "image/vnd.rn-realpix"),
MP4("mp4", "video/mp4");
private String prefix;
private String type;
public static String getContentType(String prefix){
if(StrUtil.isEmpty(prefix)){
return DEFAULT.getType();
}
prefix = prefix.substring(prefix.lastIndexOf(".") + 1);
for (OssContentType value : OssContentType.values()) {
if(prefix.equalsIgnoreCase(value.getPrefix())){
return value.getType();
}
}
return DEFAULT.getType();
}
OssContentType(String prefix, String type) {
this.prefix = prefix;
this.type = type;
}
public String getPrefix() {
return prefix;
}
public String getType() {
return type;
}
}

View File

@@ -0,0 +1,439 @@
package com.schisandra.oss.application.oss.utils;
import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Bucket;
import io.minio.messages.DeleteObject;
import io.minio.messages.Item;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.multipart.MultipartFile;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
/**
* @Classname MinIOUtils
* @BelongsProject: schisandra-cloud-storage
* @BelongsPackage: com.schisandra.oss.application.oss.utils
* @Author: landaiqing
* @CreateTime: 2024-05-12 23:50
* @Description: MinIO工具类
* @Version: 1.0
*/
@Slf4j
public class MinIOUtils {
private static MinioClient minioClient;
private static String endpoint;
private static String bucketName;
private static String accessKey;
private static String secretKey;
private static Double imgSize;
private static Double fileSize;
private static final String SEPARATOR = "/";
public MinIOUtils() {
}
public MinIOUtils(String endpoint, String bucketName, String accessKey, String secretKey, Double imgSize, Double fileSize) {
MinIOUtils.endpoint = endpoint;
MinIOUtils.bucketName = bucketName;
MinIOUtils.accessKey = accessKey;
MinIOUtils.secretKey = secretKey;
MinIOUtils.imgSize = imgSize;
MinIOUtils.fileSize = fileSize;
createMinioClient();
}
/**
* 创建基于Java端的MinioClient
*/
public void createMinioClient() {
try {
if (null == minioClient) {
log.info("开始创建 MinioClient...");
minioClient = MinioClient
.builder()
.endpoint(endpoint)
.credentials(accessKey, secretKey)
.build();
createBucket(bucketName);
log.info("创建完毕 MinioClient...");
}
} catch (Exception e) {
log.error("MinIO服务器异常{}", e);
}
}
/**
* 获取上传文件前缀路径
* @return
*/
public static String getBasisUrl() {
return endpoint + SEPARATOR + bucketName + SEPARATOR;
}
/****************************** Operate Bucket Start ******************************/
/**
* 启动SpringBoot容器的时候初始化Bucket
* 如果没有Bucket则创建
* @throws Exception
*/
private static void createBucket(String bucketName) throws Exception {
if (!bucketExists(bucketName)) {
minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
}
}
/**
* 判断Bucket是否存在true存在false不存在
* @return
* @throws Exception
*/
public static boolean bucketExists(String bucketName) throws Exception {
return minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build());
}
/**
* 获得Bucket的策略
* @param bucketName
* @return
* @throws Exception
*/
public static String getBucketPolicy(String bucketName) throws Exception {
String bucketPolicy = minioClient
.getBucketPolicy(
GetBucketPolicyArgs
.builder()
.bucket(bucketName)
.build()
);
return bucketPolicy;
}
/**
* 获得所有Bucket列表
* @return
* @throws Exception
*/
public static List<Bucket> getAllBuckets() throws Exception {
return minioClient.listBuckets();
}
/**
* 根据bucketName获取其相关信息
* @param bucketName
* @return
* @throws Exception
*/
public static Optional<Bucket> getBucket(String bucketName) throws Exception {
return getAllBuckets().stream().filter(b -> b.name().equals(bucketName)).findFirst();
}
/**
* 根据bucketName删除Buckettrue删除成功 false删除失败文件或已不存在
* @param bucketName
* @throws Exception
*/
public static void removeBucket(String bucketName) throws Exception {
minioClient.removeBucket(RemoveBucketArgs.builder().bucket(bucketName).build());
}
/****************************** Operate Bucket End ******************************/
/****************************** Operate Files Start ******************************/
/**
* 判断文件是否存在
* @param bucketName 存储桶
* @param objectName 文件名
* @return
*/
public static boolean isObjectExist(String bucketName, String objectName) {
boolean exist = true;
try {
minioClient.statObject(StatObjectArgs.builder().bucket(bucketName).object(objectName).build());
} catch (Exception e) {
exist = false;
}
return exist;
}
/**
* 判断文件夹是否存在
* @param bucketName 存储桶
* @param objectName 文件夹名称
* @return
*/
public static boolean isFolderExist(String bucketName, String objectName) {
boolean exist = false;
try {
Iterable<Result<Item>> results = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucketName).prefix(objectName).recursive(false).build());
for (Result<Item> result : results) {
Item item = result.get();
if (item.isDir() && objectName.equals(item.objectName())) {
exist = true;
}
}
} catch (Exception e) {
exist = false;
}
return exist;
}
/**
* 根据文件前缀查询文件
* @param bucketName 存储桶
* @param prefix 前缀
* @param recursive 是否使用递归查询
* @return MinioItem 列表
* @throws Exception
*/
public static List<Item> getAllObjectsByPrefix(String bucketName,
String prefix,
boolean recursive) throws Exception {
List<Item> list = new ArrayList<>();
Iterable<Result<Item>> objectsIterator = minioClient.listObjects(
ListObjectsArgs.builder().bucket(bucketName).prefix(prefix).recursive(recursive).build());
if (objectsIterator != null) {
for (Result<Item> o : objectsIterator) {
Item item = o.get();
list.add(item);
}
}
return list;
}
/**
* 获取文件流
* @param bucketName 存储桶
* @param objectName 文件名
* @return 二进制流
*/
public static InputStream getObject(String bucketName, String objectName) throws Exception {
return minioClient.getObject(GetObjectArgs.builder().bucket(bucketName).object(objectName).build());
}
/**
* 断点下载
* @param bucketName 存储桶
* @param objectName 文件名称
* @param offset 起始字节的位置
* @param length 要读取的长度
* @return 二进制流
*/
public InputStream getObject(String bucketName, String objectName, long offset, long length)throws Exception {
return minioClient.getObject(
GetObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.offset(offset)
.length(length)
.build());
}
/**
* 获取路径下文件列表
* @param bucketName 存储桶
* @param prefix 文件名称
* @param recursive 是否递归查找false模拟文件夹结构查找
* @return 二进制流
*/
public static Iterable<Result<Item>> listObjects(String bucketName, String prefix,
boolean recursive) {
return minioClient.listObjects(
ListObjectsArgs.builder()
.bucket(bucketName)
.prefix(prefix)
.recursive(recursive)
.build());
}
/**
* 使用MultipartFile进行文件上传
* @param bucketName 存储桶
* @param file 文件名
* @param objectName 对象名
* @param contentType 类型
* @return
* @throws Exception
*/
public static ObjectWriteResponse uploadFile(String bucketName, MultipartFile file,
String objectName, String contentType) throws Exception {
InputStream inputStream = file.getInputStream();
return minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.contentType(contentType)
.stream(inputStream, inputStream.available(), -1)
.build());
}
/**
* 上传本地文件
* @param bucketName 存储桶
* @param objectName 对象名称
* @param fileName 本地文件路径
*/
public static ObjectWriteResponse uploadFile(String bucketName, String objectName,
String fileName) throws Exception {
return minioClient.uploadObject(
UploadObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.filename(fileName)
.build());
}
/**
* 通过流上传文件
*
* @param bucketName 存储桶
* @param objectName 文件对象
* @param inputStream 文件流
*/
public static ObjectWriteResponse uploadFile(String bucketName, String objectName, InputStream inputStream) throws Exception {
return minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(inputStream, inputStream.available(), -1)
.build());
}
/**
* 创建文件夹或目录
* @param bucketName 存储桶
* @param objectName 目录路径
*/
public static ObjectWriteResponse createDir(String bucketName, String objectName) throws Exception {
return minioClient.putObject(
PutObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.stream(new ByteArrayInputStream(new byte[]{}), 0, -1)
.build());
}
/**
* 获取文件信息, 如果抛出异常则说明文件不存在
*
* @param bucketName 存储桶
* @param objectName 文件名称
*/
public static String getFileStatusInfo(String bucketName, String objectName) throws Exception {
return minioClient.statObject(
StatObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build()).toString();
}
/**
* 拷贝文件
*
* @param bucketName 存储桶
* @param objectName 文件名
* @param srcBucketName 目标存储桶
* @param srcObjectName 目标文件名
*/
public static ObjectWriteResponse copyFile(String bucketName, String objectName,
String srcBucketName, String srcObjectName) throws Exception {
return minioClient.copyObject(
CopyObjectArgs.builder()
.source(CopySource.builder().bucket(bucketName).object(objectName).build())
.bucket(srcBucketName)
.object(srcObjectName)
.build());
}
/**
* 删除文件
* @param bucketName 存储桶
* @param objectName 文件名称
*/
public static void removeFile(String bucketName, String objectName) throws Exception {
minioClient.removeObject(
RemoveObjectArgs.builder()
.bucket(bucketName)
.object(objectName)
.build());
}
/**
* 批量删除文件
* @param bucketName 存储桶
* @param keys 需要删除的文件列表
* @return
*/
public static void removeFiles(String bucketName, List<String> keys) {
List<DeleteObject> objects = new LinkedList<>();
keys.forEach(s -> {
objects.add(new DeleteObject(s));
try {
removeFile(bucketName, s);
} catch (Exception e) {
log.error("批量删除失败error:{}",e);
}
});
}
/**
* 获取文件外链
* @param bucketName 存储桶
* @param objectName 文件名
* @param expires 过期时间 <=7 秒 (外链有效时间(单位:秒))
* @return url
* @throws Exception
*/
public static String getPresignedObjectUrl(String bucketName, String objectName, Integer expires) throws Exception {
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder().expiry(expires).bucket(bucketName).object(objectName).build();
return minioClient.getPresignedObjectUrl(args);
}
/**
* 获得文件外链
* @param bucketName
* @param objectName
* @return url
* @throws Exception
*/
public static String getPresignedObjectUrl(String bucketName, String objectName) throws Exception {
GetPresignedObjectUrlArgs args = GetPresignedObjectUrlArgs.builder()
.bucket(bucketName)
.object(objectName)
.method(Method.GET).build();
return minioClient.getPresignedObjectUrl(args);
}
/**
* 将URLDecoder编码转成UTF8
* @param str
* @return
* @throws UnsupportedEncodingException
*/
public static String getUtf8ByURLDecoder(String str) throws UnsupportedEncodingException {
String url = str.replaceAll("%(?![0-9a-fA-F]{2})", "%25");
return URLDecoder.decode(url, "UTF-8");
}
/****************************** Operate Files End ******************************/
}

View File

@@ -0,0 +1,68 @@
package com.schisandra.oss.application.oss.utils;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
/**
* @author landaiqing
* @version PathUtil.java, v 1.1 2022/2/18 17:01 chenmin Exp $
* Created on 2022/2/18
*/
@Slf4j
public class OssPathUtil {
public static String valid(String basePath) {
// 根路径未配置时,默认路径为 /
if (ObjectUtil.isEmpty(basePath)) {
basePath = StrUtil.SLASH;
}
// 将路径分隔符统一转为 /
basePath = basePath.replaceAll("\\\\", StrUtil.SLASH).replaceAll("//", StrUtil.SLASH);
// 将配置默认转为绝对路径
if (!basePath.startsWith(StrUtil.SLASH)) {
basePath = StrUtil.SLASH + basePath;
}
if (!basePath.endsWith(StrUtil.SLASH)) {
basePath = basePath + StrUtil.SLASH;
}
return basePath;
}
/**
* 路径转换
* 将路径分隔符转为统一的 / 分隔
* @param key 路径
* @param isAbsolute 是否绝对路径
* true绝对路径false相对路径
* @return 以 / 为分隔的路径
*/
public static String convertPath(String key, Boolean isAbsolute) {
key = key.replaceAll("\\\\", StrUtil.SLASH).replaceAll("//", StrUtil.SLASH);
if (isAbsolute && !key.startsWith(StrUtil.SLASH)) {
key = StrUtil.SLASH + key;
} else if (!isAbsolute && key.startsWith(StrUtil.SLASH)) {
key = key.replaceFirst(StrUtil.SLASH, "");
}
return key;
}
/**
* 获取相对根路径的绝对路径
* @param path 全路径
* @param basePath 根路径
* @param isAbsolute 是否绝对路径
* true绝对路径false相对路径
* @return 完整路径
*/
public static String replaceKey(String path, String basePath, Boolean isAbsolute) {
String newPath;
if (StrUtil.SLASH.equals(basePath)) {
newPath = convertPath(path, isAbsolute);
} else {
newPath = convertPath(path, isAbsolute).replaceAll(convertPath(basePath, isAbsolute), "");
}
return convertPath(newPath, isAbsolute);
}
}

View File

@@ -100,7 +100,24 @@
<artifactId>caffeine</artifactId>
<version>3.1.8</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.1.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>8.2.1</version>
</dependency>
<dependency>
<groupId>net.coobird</groupId>
<artifactId>thumbnailator</artifactId>
<version>0.4.8</version>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,194 @@
package com.schisandra.oss.common.utils;
import net.coobird.thumbnailator.Thumbnails;
import net.coobird.thumbnailator.geometry.Positions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextAttribute;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.AttributedCharacterIterator;
import java.text.AttributedString;
/**
* 图像工具类
*/
public class ImageUtil {
private static final Logger log = LoggerFactory.getLogger(ImageUtil.class);
//压缩率
private static final transient float IMAGE_RATIO = 0.1f;
//压缩最大宽度
private static final transient int IMAGE_WIDTH = 800;
// 水印透明度
private static float alpha = 0.3f;
// 水印文字字体
private static Font font = new Font("PingFang SC Regular", Font.PLAIN, 36);
// 水印文字颜色
private static Color color = new Color(111, 111, 111);
//水印文字内容
private static final String text = "这是一个水印文本";
// 水印之间的间隔
private static final int XMOVE = 80;
// 水印之间的间隔
private static final int YMOVE = 80;
/**
* 压缩图像
*
* @param image
* @return
* @throws IOException
*/
public static BufferedImage compress(BufferedImage image) throws IOException {
Thumbnails.Builder<BufferedImage> imageBuilder = Thumbnails.of(image).outputQuality(IMAGE_RATIO);
if (image.getWidth() > IMAGE_WIDTH) {
return imageBuilder.width(IMAGE_WIDTH).asBufferedImage();
} else {
return imageBuilder.scale(1).asBufferedImage();
}
}
/**
* 图像添加水印
*
* @param
* @return
*/
public static BufferedImage setWatermark(BufferedImage image) throws IOException {
return Thumbnails.of(image)
.outputQuality(IMAGE_RATIO)
.scale(1)
.watermark(Positions.BOTTOM_RIGHT
, createWatermark(text
, image.getWidth()
, image.getHeight()
)
, alpha)
.asBufferedImage();
}
/**
* 根据文件扩展名判断文件是否图片格式
*
* @return
*/
public static boolean isImage(String fileName) {
String[] imageExtension = new String[]{"jpeg", "jpg", "gif", "bmp", "png"};
for (String e : imageExtension) if (getFileExtention(fileName).toLowerCase().equals(e)) return true;
return false;
}
/**
* 获取文件后缀名称
*
* @param fileName
* @return
*/
public static String getFileExtention(String fileName) {
String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
return extension;
}
/**
* 根据图片对象获取对应InputStream
*
* @param image
* @param readImageFormat
* @return
* @throws IOException
*/
public static InputStream getInputStream(BufferedImage image, String readImageFormat) throws IOException {
ByteArrayOutputStream os = new ByteArrayOutputStream();
ImageIO.write(image, readImageFormat, os);
InputStream is = new ByteArrayInputStream(os.toByteArray());
os.close();
return is;
}
/**
* 创建水印图片
*
* @param text 水印文字
* @param width 图片宽
* @param height 图片高
* @return
*/
public static BufferedImage createWatermark(String text, int width, int height) {
BufferedImage image = new BufferedImage(width
, height, BufferedImage.TYPE_INT_RGB);
// 2.获取图片画笔
Graphics2D g = image.createGraphics();
// ---------- 增加下面的代码使得背景透明 -----------------
image = g.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
g.dispose();
g = image.createGraphics();
// ---------- 背景透明代码结束 -----------------
// 6、处理文字
AttributedString ats = new AttributedString(text);
ats.addAttribute(TextAttribute.FONT, font, 0, text.length());
AttributedCharacterIterator iter = ats.getIterator();
// 7、设置对线段的锯齿状边缘处理
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// 8、设置水印旋转
g.rotate(Math.toRadians(-30));
// 9、设置水印文字颜色
g.setColor(color);
// 10、设置水印文字Font
g.setFont(font);
// 11、设置水印文字透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha));
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
/**
* 水印铺满图片
* 计算水印位置
*/
int x = -width / 2;
int y = -height / 2;
int[] arr = getWidthAndHeight(text, font);
int markWidth = arr[0];// 字体长度
int markHeight = arr[1];// 字体高度
// 循环添加水印
while (x < width * 1.5) {
y = -height / 2;
while (y < height * 1.5) {
g.drawString(text, x, y);
y += markHeight + YMOVE;
}
x += markWidth + XMOVE;
}
// 13、释放资源
g.dispose();
return image;
}
/**
* 计算字体宽度及高度
*
* @param text
* @param font
* @return
*/
private static int[] getWidthAndHeight(String text, Font font) {
Rectangle2D r = font.getStringBounds(text, new FontRenderContext(
AffineTransform.getScaleInstance(1, 1), false, false));
int unitHeight = (int) Math.floor(r.getHeight());//
// 获取整个str用了font样式的宽度这里用四舍五入后+1保证宽度绝对能容纳这个字符串作为图片的宽度
int width = (int) Math.round(r.getWidth()) + 1;
// 把单个字符的高度+3保证高度绝对能容纳字符串作为图片的高度
int height = unitHeight + 3;
return new int[]{width, height};
}
}

View File

@@ -18,5 +18,6 @@ public interface SchisandraOssConfigBOConverter {
SchisandraOssConfigBOConverter INSTANCE = Mappers.getMapper(SchisandraOssConfigBOConverter.class);
SchisandraOssConfig convertBOToEntity(SchisandraOssConfigBO schisandraOssConfigBO);
SchisandraOssConfigBO convertEntityToBO(SchisandraOssConfig schisandraOssConfig);
}

View File

@@ -25,4 +25,5 @@ public interface SchisandraOssConfigDomainService {
*/
Boolean delete(SchisandraOssConfigBO schisandraOssConfigBO);
SchisandraOssConfigBO getOssConfig(String minio);
}

View File

@@ -4,7 +4,6 @@ package com.schisandra.oss.domain.service.impl;
import com.schisandra.oss.common.enums.IsDeletedFlagEnum;
import com.schisandra.oss.domain.convert.SchisandraOssConfigBOConverter;
import com.schisandra.oss.domain.bo.SchisandraOssConfigBO;
import com.schisandra.oss.domain.service.SchisandraOssConfigDomainService;
import com.schisandra.oss.infra.basic.entity.SchisandraOssConfig;
import com.schisandra.oss.infra.basic.service.SchisandraOssConfigService;
import lombok.extern.slf4j.Slf4j;
@@ -20,7 +19,7 @@ import javax.annotation.Resource;
*/
@Service
@Slf4j
public class SchisandraOssConfigDomainServiceImpl implements SchisandraOssConfigDomainService {
public class SchisandraOssConfigDomainService implements com.schisandra.oss.domain.service.SchisandraOssConfigDomainService {
@Resource
private SchisandraOssConfigService schisandraOssConfigService;
@@ -46,4 +45,11 @@ public class SchisandraOssConfigDomainServiceImpl implements SchisandraOssConfig
return schisandraOssConfigService.update(schisandraOssConfig) > 0;
}
@Override
public SchisandraOssConfigBO getOssConfig(String ossType) {
SchisandraOssConfig ossConfig = schisandraOssConfigService.getOssConfig(ossType);
SchisandraOssConfigBO schisandraOssConfigBO = SchisandraOssConfigBOConverter.INSTANCE.convertEntityToBO(ossConfig);
return schisandraOssConfigBO;
}
}

View File

@@ -47,4 +47,5 @@ public interface SchisandraOssConfigService {
*/
SchisandraOssConfig queryByCondition(SchisandraOssConfig schisandraOssConfig);
SchisandraOssConfig getOssConfig(String ossType);
}

View File

@@ -2,6 +2,7 @@ package com.schisandra.oss.infra.basic.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.schisandra.oss.infra.basic.dao.SchisandraOssConfigDao;
import com.schisandra.oss.infra.basic.entity.SchisandraOssConfig;
@@ -111,4 +112,11 @@ public class SchisandraOssConfigServiceImpl implements SchisandraOssConfigServic
}
@Override
public SchisandraOssConfig getOssConfig(String ossType) {
SchisandraOssConfig ossConfig = schisandraOssConfigDao.selectOne(new QueryWrapper<SchisandraOssConfig>()
.eq("oss_type", ossType).eq("is_deleted", 0));
return ossConfig;
}
}

View File

@@ -39,6 +39,14 @@
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.schisandra</groupId>