Merge branch 'master-jdk21' of https://gitee.com/zhijiantianya/yudao-cloud
# Conflicts: # yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/dal/mysql/file/FileContentDAOImpl.java # yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/db/DBFileClientConfig.java # yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/ftp/FtpFileClientConfig.java # yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/local/LocalFileClientConfig.java # yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/s3/S3FileClientConfig.java # yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/framework/file/core/client/sftp/SftpFileClientConfig.java # yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileConfigService.java # yudao-module-infra/yudao-module-infra-biz/src/main/java/cn/iocoder/yudao/module/infra/service/file/FileServiceImpl.java # yudao-module-infra/yudao-module-infra-biz/src/test/java/cn/iocoder/yudao/module/infra/framework/file/core/s3/S3FileClientTest.java
This commit is contained in:
commit
5edcfb9d91
@ -604,11 +604,6 @@
|
|||||||
<artifactId>okhttp</artifactId>
|
<artifactId>okhttp</artifactId>
|
||||||
<version>${okhttp3.version}</version>
|
<version>${okhttp3.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
|
||||||
<groupId>cn.iocoder.cloud</groupId>
|
|
||||||
<artifactId>yudao-spring-boot-starter-file</artifactId>
|
|
||||||
<version>${revision}</version>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.minio</groupId>
|
<groupId>io.minio</groupId>
|
||||||
<artifactId>minio</artifactId>
|
<artifactId>minio</artifactId>
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
<module>yudao-spring-boot-starter-web</module>
|
<module>yudao-spring-boot-starter-web</module>
|
||||||
<module>yudao-spring-boot-starter-security</module>
|
<module>yudao-spring-boot-starter-security</module>
|
||||||
|
|
||||||
<module>yudao-spring-boot-starter-file</module>
|
|
||||||
<module>yudao-spring-boot-starter-monitor</module>
|
<module>yudao-spring-boot-starter-monitor</module>
|
||||||
<module>yudao-spring-boot-starter-protection</module>
|
<module>yudao-spring-boot-starter-protection</module>
|
||||||
<!-- <module>yudao-spring-boot-starter-config</module>-->
|
<!-- <module>yudao-spring-boot-starter-config</module>-->
|
||||||
|
@ -136,6 +136,21 @@ public class JsonUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 解析 JSON 字符串成指定类型的对象,如果解析失败,则返回 null
|
||||||
|
*
|
||||||
|
* @param text 字符串
|
||||||
|
* @param typeReference 类型引用
|
||||||
|
* @return 指定类型的对象
|
||||||
|
*/
|
||||||
|
public static <T> T parseObjectQuietly(String text, TypeReference<T> typeReference) {
|
||||||
|
try {
|
||||||
|
return objectMapper.readValue(text, typeReference);
|
||||||
|
} catch (IOException e) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> List<T> parseArray(String text, Class<T> clazz) {
|
public static <T> List<T> parseArray(String text, Class<T> clazz) {
|
||||||
if (StrUtil.isEmpty(text)) {
|
if (StrUtil.isEmpty(text)) {
|
||||||
return new ArrayList<>();
|
return new ArrayList<>();
|
||||||
|
@ -1,83 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
|
||||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
|
||||||
<parent>
|
|
||||||
<artifactId>yudao-framework</artifactId>
|
|
||||||
<groupId>cn.iocoder.cloud</groupId>
|
|
||||||
<version>${revision}</version>
|
|
||||||
</parent>
|
|
||||||
<modelVersion>4.0.0</modelVersion>
|
|
||||||
<artifactId>yudao-spring-boot-starter-file</artifactId>
|
|
||||||
|
|
||||||
<name>${project.artifactId}</name>
|
|
||||||
<description>文件客户端,支持多种存储器
|
|
||||||
1. file:本地磁盘
|
|
||||||
2. ftp:FTP 服务器
|
|
||||||
2. sftp:SFTP 服务器
|
|
||||||
4. db:数据库
|
|
||||||
5. s3:支持 S3 协议的云存储服务,例如说 MinIO、阿里云、华为云、腾讯云、七牛云等等
|
|
||||||
</description>
|
|
||||||
<url>https://github.com/YunaiV/ruoyi-vue-pro</url>
|
|
||||||
|
|
||||||
<dependencies>
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.iocoder.cloud</groupId>
|
|
||||||
<artifactId>yudao-common</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Spring 核心 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- 工具类相关 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.springframework.boot</groupId>
|
|
||||||
<artifactId>spring-boot-starter-validation</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.slf4j</groupId>
|
|
||||||
<artifactId>slf4j-api</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-databind</artifactId>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.fasterxml.jackson.core</groupId>
|
|
||||||
<artifactId>jackson-core</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>commons-net</groupId>
|
|
||||||
<artifactId>commons-net</artifactId> <!-- 解决 ftp 连接 -->
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.jcraft</groupId>
|
|
||||||
<artifactId>jsch</artifactId> <!-- 解决 sftp 连接 -->
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<dependency>
|
|
||||||
<groupId>org.apache.tika</groupId>
|
|
||||||
<artifactId>tika-core</artifactId> <!-- 文件类型的识别 -->
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- 三方云服务相关 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>io.minio</groupId>
|
|
||||||
<artifactId>minio</artifactId>
|
|
||||||
</dependency>
|
|
||||||
|
|
||||||
<!-- Test 测试相关 -->
|
|
||||||
<dependency>
|
|
||||||
<groupId>cn.iocoder.cloud</groupId>
|
|
||||||
<artifactId>yudao-spring-boot-starter-test</artifactId>
|
|
||||||
<scope>test</scope>
|
|
||||||
</dependency>
|
|
||||||
</dependencies>
|
|
||||||
|
|
||||||
</project>
|
|
@ -1,21 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.file.config;
|
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientFactory;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientFactoryImpl;
|
|
||||||
import org.springframework.boot.autoconfigure.AutoConfiguration;
|
|
||||||
import org.springframework.context.annotation.Bean;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件配置类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@AutoConfiguration
|
|
||||||
public class YudaoFileAutoConfiguration {
|
|
||||||
|
|
||||||
@Bean
|
|
||||||
public FileClientFactory fileClientFactory() {
|
|
||||||
return new FileClientFactoryImpl();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,48 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.db;
|
|
||||||
|
|
||||||
import cn.hutool.extra.spring.SpringUtil;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.AbstractFileClient;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 基于 DB 存储的文件客户端的配置类
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
public class DBFileClient extends AbstractFileClient<DBFileClientConfig> {
|
|
||||||
|
|
||||||
private DBFileContentFrameworkDAO dao;
|
|
||||||
|
|
||||||
public DBFileClient(Long id, DBFileClientConfig config) {
|
|
||||||
super(id, config);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void doInit() {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String upload(byte[] content, String path, String type) {
|
|
||||||
getDao().insert(getId(), path, content);
|
|
||||||
// 拼接返回路径
|
|
||||||
return super.formatFileUrl(config.getDomain(), path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(String path) {
|
|
||||||
getDao().delete(getId(), path);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] getContent(String path) {
|
|
||||||
return getDao().selectContent(getId(), path);
|
|
||||||
}
|
|
||||||
|
|
||||||
private DBFileContentFrameworkDAO getDao() {
|
|
||||||
// 延迟获取,因为 SpringUtil 初始化太慢
|
|
||||||
if (dao == null) {
|
|
||||||
dao = SpringUtil.getBean(DBFileContentFrameworkDAO.class);
|
|
||||||
}
|
|
||||||
return dao;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.db;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件内容 Framework DAO 接口
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
public interface DBFileContentFrameworkDAO {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 插入文件内容
|
|
||||||
*
|
|
||||||
* @param configId 配置编号
|
|
||||||
* @param path 路径
|
|
||||||
* @param content 内容
|
|
||||||
*/
|
|
||||||
void insert(Long configId, String path, byte[] content);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 删除文件内容
|
|
||||||
*
|
|
||||||
* @param configId 配置编号
|
|
||||||
* @param path 路径
|
|
||||||
*/
|
|
||||||
void delete(Long configId, String path);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 获得文件内容
|
|
||||||
*
|
|
||||||
* @param configId 配置编号
|
|
||||||
* @param path 路径
|
|
||||||
* @return 内容
|
|
||||||
*/
|
|
||||||
byte[] selectContent(Long configId, String path);
|
|
||||||
|
|
||||||
}
|
|
@ -1,55 +0,0 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.enums;
|
|
||||||
|
|
||||||
import cn.hutool.core.util.ArrayUtil;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.db.DBFileClient;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.db.DBFileClientConfig;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.ftp.FtpFileClient;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.ftp.FtpFileClientConfig;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.local.LocalFileClient;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.local.LocalFileClientConfig;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.s3.S3FileClient;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.sftp.SftpFileClient;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.sftp.SftpFileClientConfig;
|
|
||||||
import lombok.AllArgsConstructor;
|
|
||||||
import lombok.Getter;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 文件存储器枚举
|
|
||||||
*
|
|
||||||
* @author 芋道源码
|
|
||||||
*/
|
|
||||||
@AllArgsConstructor
|
|
||||||
@Getter
|
|
||||||
public enum FileStorageEnum {
|
|
||||||
|
|
||||||
DB(1, DBFileClientConfig.class, DBFileClient.class),
|
|
||||||
|
|
||||||
LOCAL(10, LocalFileClientConfig.class, LocalFileClient.class),
|
|
||||||
FTP(11, FtpFileClientConfig.class, FtpFileClient.class),
|
|
||||||
SFTP(12, SftpFileClientConfig.class, SftpFileClient.class),
|
|
||||||
|
|
||||||
S3(20, S3FileClientConfig.class, S3FileClient.class),
|
|
||||||
;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 存储器
|
|
||||||
*/
|
|
||||||
private final Integer storage;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 配置类
|
|
||||||
*/
|
|
||||||
private final Class<? extends FileClientConfig> configClass;
|
|
||||||
/**
|
|
||||||
* 客户端类
|
|
||||||
*/
|
|
||||||
private final Class<? extends FileClient> clientClass;
|
|
||||||
|
|
||||||
public static FileStorageEnum getByStorage(Integer storage) {
|
|
||||||
return ArrayUtil.firstMatch(o -> o.getStorage().equals(storage), values());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1 +0,0 @@
|
|||||||
cn.iocoder.yudao.framework.file.config.YudaoFileAutoConfiguration
|
|
@ -1,4 +0,0 @@
|
|||||||
/**
|
|
||||||
* 占位,避免 package 无法提交到 Git 仓库
|
|
||||||
*/
|
|
||||||
package cn.iocoder.yudao.framework.file.config;
|
|
@ -1,4 +0,0 @@
|
|||||||
/**
|
|
||||||
* 占位,避免 package 无法提交到 Git 仓库
|
|
||||||
*/
|
|
||||||
package cn.iocoder.yudao.framework.file.core.enums;
|
|
Binary file not shown.
Before Width: | Height: | Size: 18 KiB |
@ -139,8 +139,21 @@
|
|||||||
|
|
||||||
<!-- 三方云服务相关 -->
|
<!-- 三方云服务相关 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>cn.iocoder.cloud</groupId>
|
<groupId>commons-net</groupId>
|
||||||
<artifactId>yudao-spring-boot-starter-file</artifactId>
|
<artifactId>commons-net</artifactId> <!-- 文件客户端:解决 ftp 连接 -->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.jcraft</groupId>
|
||||||
|
<artifactId>jsch</artifactId> <!-- 文件客户端:解决 sftp 连接 -->
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.minio</groupId>
|
||||||
|
<artifactId>minio</artifactId> <!-- 文件客户端:解决阿里云、腾讯云、minio 等 S3 连接 -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.tika</groupId>
|
||||||
|
<artifactId>tika-core</artifactId> <!-- 文件客户端:文件类型的识别 -->
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.infra.controller.admin.file.vo.config;
|
package cn.iocoder.yudao.module.infra.controller.admin.file.vo.config;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
|
|
||||||
|
@ -1,12 +1,20 @@
|
|||||||
package cn.iocoder.yudao.module.infra.dal.dataobject.file;
|
package cn.iocoder.yudao.module.infra.dal.dataobject.file;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.file.core.enums.FileStorageEnum;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.ftp.FtpFileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.sftp.SftpFileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.enums.FileStorageEnum;
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
import com.baomidou.mybatisplus.annotation.TableField;
|
import com.baomidou.mybatisplus.annotation.TableField;
|
||||||
import com.baomidou.mybatisplus.annotation.TableName;
|
import com.baomidou.mybatisplus.annotation.TableName;
|
||||||
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
|
import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
|
||||||
|
import com.fasterxml.jackson.core.type.TypeReference;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,7 +60,42 @@ public class FileConfigDO extends BaseDO {
|
|||||||
/**
|
/**
|
||||||
* 支付渠道配置
|
* 支付渠道配置
|
||||||
*/
|
*/
|
||||||
@TableField(typeHandler = JacksonTypeHandler.class)
|
@TableField(typeHandler = FileClientConfigTypeHandler.class)
|
||||||
private FileClientConfig config;
|
private FileClientConfig config;
|
||||||
|
|
||||||
|
public static class FileClientConfigTypeHandler extends AbstractJsonTypeHandler<Object> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Object parse(String json) {
|
||||||
|
FileClientConfig config = JsonUtils.parseObjectQuietly(json, new TypeReference<>() {});
|
||||||
|
if (config != null) {
|
||||||
|
return config;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 兼容老版本的包路径
|
||||||
|
String className = JsonUtils.parseObject(json, "@class", String.class);
|
||||||
|
className = StrUtil.subAfter(className, ".", true);
|
||||||
|
switch (className) {
|
||||||
|
case "DBFileClientConfig":
|
||||||
|
return JsonUtils.parseObject2(json, DBFileClientConfig.class);
|
||||||
|
case "FtpFileClientConfig":
|
||||||
|
return JsonUtils.parseObject2(json, FtpFileClientConfig.class);
|
||||||
|
case "LocalFileClientConfig":
|
||||||
|
return JsonUtils.parseObject2(json, LocalFileClientConfig.class);
|
||||||
|
case "SftpFileClientConfig":
|
||||||
|
return JsonUtils.parseObject2(json, SftpFileClientConfig.class);
|
||||||
|
case "S3FileClientConfig":
|
||||||
|
return JsonUtils.parseObject2(json, S3FileClientConfig.class);
|
||||||
|
default:
|
||||||
|
throw new IllegalArgumentException("未知的 FileClientConfig 类型:" + json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected String toJson(Object obj) {
|
||||||
|
return JsonUtils.toJsonString(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package cn.iocoder.yudao.module.infra.dal.dataobject.file;
|
package cn.iocoder.yudao.module.infra.dal.dataobject.file;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClient;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
import com.baomidou.mybatisplus.annotation.KeySequence;
|
import com.baomidou.mybatisplus.annotation.KeySequence;
|
||||||
import com.baomidou.mybatisplus.annotation.TableId;
|
import com.baomidou.mybatisplus.annotation.TableId;
|
||||||
@ -10,7 +11,7 @@ import lombok.*;
|
|||||||
/**
|
/**
|
||||||
* 文件内容表
|
* 文件内容表
|
||||||
*
|
*
|
||||||
* 专门用于存储 {@link cn.iocoder.yudao.framework.file.core.client.db.DBFileClient} 的文件内容
|
* 专门用于存储 {@link DBFileClient} 的文件内容
|
||||||
*
|
*
|
||||||
* @author 芋道源码
|
* @author 芋道源码
|
||||||
*/
|
*/
|
||||||
|
@ -1,46 +0,0 @@
|
|||||||
package cn.iocoder.yudao.module.infra.dal.mysql.file;
|
|
||||||
|
|
||||||
import cn.hutool.core.collection.CollUtil;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.db.DBFileContentFrameworkDAO;
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileContentDO;
|
|
||||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
||||||
import org.springframework.stereotype.Repository;
|
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
@Repository
|
|
||||||
public class FileContentDAOImpl implements DBFileContentFrameworkDAO {
|
|
||||||
|
|
||||||
@Resource
|
|
||||||
private FileContentMapper fileContentMapper;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void insert(Long configId, String path, byte[] content) {
|
|
||||||
FileContentDO entity = new FileContentDO().setConfigId(configId)
|
|
||||||
.setPath(path).setContent(content);
|
|
||||||
fileContentMapper.insert(entity);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete(Long configId, String path) {
|
|
||||||
fileContentMapper.delete(buildQuery(configId, path));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public byte[] selectContent(Long configId, String path) {
|
|
||||||
List<FileContentDO> list = fileContentMapper.selectList(
|
|
||||||
buildQuery(configId, path).select(FileContentDO::getContent).orderByDesc(FileContentDO::getId));
|
|
||||||
return Optional.ofNullable(CollUtil.getFirst(list))
|
|
||||||
.map(FileContentDO::getContent)
|
|
||||||
.orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private LambdaQueryWrapper<FileContentDO> buildQuery(Long configId, String path) {
|
|
||||||
return new LambdaQueryWrapper<FileContentDO>()
|
|
||||||
.eq(FileContentDO::getConfigId, configId)
|
|
||||||
.eq(FileContentDO::getPath, path);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,9 +1,25 @@
|
|||||||
package cn.iocoder.yudao.module.infra.dal.mysql.file;
|
package cn.iocoder.yudao.module.infra.dal.mysql.file;
|
||||||
|
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileContentDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileContentDO;
|
||||||
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||||
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
import org.apache.ibatis.annotations.Mapper;
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Mapper
|
@Mapper
|
||||||
public interface FileContentMapper extends BaseMapper<FileContentDO> {
|
public interface FileContentMapper extends BaseMapper<FileContentDO> {
|
||||||
|
|
||||||
|
default void deleteByConfigIdAndPath(Long configId, String path) {
|
||||||
|
this.delete(new LambdaQueryWrapper<FileContentDO>()
|
||||||
|
.eq(FileContentDO::getConfigId, configId)
|
||||||
|
.eq(FileContentDO::getPath, path));
|
||||||
|
}
|
||||||
|
|
||||||
|
default List<FileContentDO> selectListByConfigIdAndPath(Long configId, String path) {
|
||||||
|
return selectList(new LambdaQueryWrapper<FileContentDO>()
|
||||||
|
.eq(FileContentDO::getConfigId, configId)
|
||||||
|
.eq(FileContentDO::getPath, path));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,21 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.framework.file.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientFactory;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientFactoryImpl;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件配置类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@Configuration(proxyBeanMethods = false)
|
||||||
|
public class YudaoFileAutoConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public FileClientFactory fileClientFactory() {
|
||||||
|
return new FileClientFactoryImpl();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
@ -1,6 +1,6 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.s3.FilePresignedUrlRespDTO;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.s3.FilePresignedUrlRespDTO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件客户端
|
* 文件客户端
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
import com.fasterxml.jackson.annotation.JsonTypeInfo;
|
||||||
|
|
@ -1,4 +1,6 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.enums.FileStorageEnum;
|
||||||
|
|
||||||
public interface FileClientFactory {
|
public interface FileClientFactory {
|
||||||
|
|
||||||
@ -14,7 +16,7 @@ public interface FileClientFactory {
|
|||||||
* 创建文件客户端
|
* 创建文件客户端
|
||||||
*
|
*
|
||||||
* @param configId 配置编号
|
* @param configId 配置编号
|
||||||
* @param storage 存储器的枚举 {@link cn.iocoder.yudao.framework.file.core.enums.FileStorageEnum}
|
* @param storage 存储器的枚举 {@link FileStorageEnum}
|
||||||
* @param config 文件配置
|
* @param config 文件配置
|
||||||
*/
|
*/
|
||||||
<Config extends FileClientConfig> void createOrUpdateFileClient(Long configId, Integer storage, Config config);
|
<Config extends FileClientConfig> void createOrUpdateFileClient(Long configId, Integer storage, Config config);
|
@ -1,8 +1,8 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client;
|
||||||
|
|
||||||
import cn.hutool.core.lang.Assert;
|
import cn.hutool.core.lang.Assert;
|
||||||
import cn.hutool.core.util.ReflectUtil;
|
import cn.hutool.core.util.ReflectUtil;
|
||||||
import cn.iocoder.yudao.framework.file.core.enums.FileStorageEnum;
|
import cn.iocoder.yudao.module.infra.framework.file.core.enums.FileStorageEnum;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
|
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
@ -0,0 +1,55 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.framework.file.core.client.db;
|
||||||
|
|
||||||
|
import cn.hutool.core.collection.CollUtil;
|
||||||
|
import cn.hutool.extra.spring.SpringUtil;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileContentDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileContentMapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
|
||||||
|
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 基于 DB 存储的文件客户端的配置类
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
public class DBFileClient extends AbstractFileClient<DBFileClientConfig> {
|
||||||
|
|
||||||
|
private FileContentMapper fileContentMapper;
|
||||||
|
|
||||||
|
public DBFileClient(Long id, DBFileClientConfig config) {
|
||||||
|
super(id, config);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void doInit() {
|
||||||
|
fileContentMapper = SpringUtil.getBean(FileContentMapper.class);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String upload(byte[] content, String path, String type) {
|
||||||
|
FileContentDO contentDO = new FileContentDO().setConfigId(getId())
|
||||||
|
.setPath(path).setContent(content);
|
||||||
|
fileContentMapper.insert(contentDO);
|
||||||
|
// 拼接返回路径
|
||||||
|
return super.formatFileUrl(config.getDomain(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(String path) {
|
||||||
|
fileContentMapper.deleteByConfigIdAndPath(getId(), path);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public byte[] getContent(String path) {
|
||||||
|
List<FileContentDO> list = fileContentMapper.selectListByConfigIdAndPath(getId(), path);
|
||||||
|
if (CollUtil.isEmpty(list)) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
// 排序后,拿 id 最大的,即最后上传的
|
||||||
|
list.sort(Comparator.comparing(FileContentDO::getId));
|
||||||
|
return CollUtil.getLast(list).getContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,11 +1,10 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.db;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client.db;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.URL;
|
import org.hibernate.validator.constraints.URL;
|
||||||
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于 DB 存储的文件客户端的配置类
|
* 基于 DB 存储的文件客户端的配置类
|
||||||
*
|
*
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.ftp;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client.ftp;
|
||||||
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.core.util.CharsetUtil;
|
import cn.hutool.core.util.CharsetUtil;
|
||||||
@ -6,7 +6,7 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.hutool.extra.ftp.Ftp;
|
import cn.hutool.extra.ftp.Ftp;
|
||||||
import cn.hutool.extra.ftp.FtpException;
|
import cn.hutool.extra.ftp.FtpException;
|
||||||
import cn.hutool.extra.ftp.FtpMode;
|
import cn.hutool.extra.ftp.FtpMode;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.AbstractFileClient;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
@ -1,12 +1,11 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.ftp;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client.ftp;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.URL;
|
import org.hibernate.validator.constraints.URL;
|
||||||
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ftp 文件客户端的配置类
|
* Ftp 文件客户端的配置类
|
||||||
*
|
*
|
@ -1,7 +1,7 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.local;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client.local;
|
||||||
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.AbstractFileClient;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
@ -1,11 +1,10 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.local;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client.local;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.URL;
|
import org.hibernate.validator.constraints.URL;
|
||||||
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 本地文件客户端的配置类
|
* 本地文件客户端的配置类
|
||||||
*
|
*
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.s3;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client.s3;
|
||||||
|
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
@ -1,18 +1,15 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.s3;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client.s3;
|
||||||
|
|
||||||
import cn.hutool.core.io.IoUtil;
|
import cn.hutool.core.io.IoUtil;
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.hutool.http.HttpUtil;
|
import cn.hutool.http.HttpUtil;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.AbstractFileClient;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
|
||||||
import io.minio.*;
|
import io.minio.*;
|
||||||
import io.minio.http.Method;
|
import io.minio.http.Method;
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_ALIYUN;
|
|
||||||
import static cn.iocoder.yudao.framework.file.core.client.s3.S3FileClientConfig.ENDPOINT_TENCENT;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务
|
* 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务
|
||||||
* <p>
|
* <p>
|
||||||
@ -76,15 +73,15 @@ public class S3FileClient extends AbstractFileClient<S3FileClientConfig> {
|
|||||||
*/
|
*/
|
||||||
private String buildRegion() {
|
private String buildRegion() {
|
||||||
// 阿里云必须有 region,否则会报错
|
// 阿里云必须有 region,否则会报错
|
||||||
if (config.getEndpoint().contains(ENDPOINT_ALIYUN)) {
|
if (config.getEndpoint().contains(S3FileClientConfig.ENDPOINT_ALIYUN)) {
|
||||||
return StrUtil.subBefore(config.getEndpoint(), '.', false)
|
return StrUtil.subBefore(config.getEndpoint(), '.', false)
|
||||||
.replaceAll("-internal", "")// 去除内网 Endpoint 的后缀
|
.replaceAll("-internal", "")// 去除内网 Endpoint 的后缀
|
||||||
.replaceAll("https://", "");
|
.replaceAll("https://", "");
|
||||||
}
|
}
|
||||||
// 腾讯云必须有 region,否则会报错
|
// 腾讯云必须有 region,否则会报错
|
||||||
if (config.getEndpoint().contains(ENDPOINT_TENCENT)) {
|
if (config.getEndpoint().contains(S3FileClientConfig.ENDPOINT_TENCENT)) {
|
||||||
return StrUtil.subAfter(config.getEndpoint(), "cos.", false)
|
return StrUtil.subAfter(config.getEndpoint(), "cos.", false)
|
||||||
.replaceAll("." + ENDPOINT_TENCENT, ""); // 去除 Endpoint
|
.replaceAll("." + S3FileClientConfig.ENDPOINT_TENCENT, ""); // 去除 Endpoint
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
@ -1,14 +1,13 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.s3;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client.s3;
|
||||||
|
|
||||||
import cn.hutool.core.util.StrUtil;
|
import cn.hutool.core.util.StrUtil;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
||||||
import com.fasterxml.jackson.annotation.JsonIgnore;
|
import com.fasterxml.jackson.annotation.JsonIgnore;
|
||||||
|
import jakarta.validation.constraints.AssertTrue;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.URL;
|
import org.hibernate.validator.constraints.URL;
|
||||||
|
|
||||||
import javax.validation.constraints.AssertTrue;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* S3 文件客户端的配置类
|
* S3 文件客户端的配置类
|
||||||
*
|
*
|
@ -1,9 +1,9 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.sftp;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client.sftp;
|
||||||
|
|
||||||
import cn.hutool.core.io.FileUtil;
|
import cn.hutool.core.io.FileUtil;
|
||||||
import cn.hutool.extra.ssh.Sftp;
|
import cn.hutool.extra.ssh.Sftp;
|
||||||
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.AbstractFileClient;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.AbstractFileClient;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
@ -1,12 +1,11 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.sftp;
|
package cn.iocoder.yudao.module.infra.framework.file.core.client.sftp;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
||||||
|
import jakarta.validation.constraints.NotEmpty;
|
||||||
|
import jakarta.validation.constraints.NotNull;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.hibernate.validator.constraints.URL;
|
import org.hibernate.validator.constraints.URL;
|
||||||
|
|
||||||
import javax.validation.constraints.NotEmpty;
|
|
||||||
import javax.validation.constraints.NotNull;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sftp 文件客户端的配置类
|
* Sftp 文件客户端的配置类
|
||||||
*
|
*
|
@ -0,0 +1,55 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.framework.file.core.enums;
|
||||||
|
|
||||||
|
import cn.hutool.core.util.ArrayUtil;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.db.DBFileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.ftp.FtpFileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.ftp.FtpFileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.sftp.SftpFileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.sftp.SftpFileClientConfig;
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件存储器枚举
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum FileStorageEnum {
|
||||||
|
|
||||||
|
DB(1, DBFileClientConfig.class, DBFileClient.class),
|
||||||
|
|
||||||
|
LOCAL(10, LocalFileClientConfig.class, LocalFileClient.class),
|
||||||
|
FTP(11, FtpFileClientConfig.class, FtpFileClient.class),
|
||||||
|
SFTP(12, SftpFileClientConfig.class, SftpFileClient.class),
|
||||||
|
|
||||||
|
S3(20, S3FileClientConfig.class, S3FileClient.class),
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 存储器
|
||||||
|
*/
|
||||||
|
private final Integer storage;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 配置类
|
||||||
|
*/
|
||||||
|
private final Class<? extends FileClientConfig> configClass;
|
||||||
|
/**
|
||||||
|
* 客户端类
|
||||||
|
*/
|
||||||
|
private final Class<? extends FileClient> clientClass;
|
||||||
|
|
||||||
|
public static FileStorageEnum getByStorage(Integer storage) {
|
||||||
|
return ArrayUtil.firstMatch(o -> o.getStorage().equals(storage), values());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.utils;
|
package cn.iocoder.yudao.module.infra.framework.file.core.utils;
|
||||||
|
|
||||||
import com.alibaba.ttl.TransmittableThreadLocal;
|
import com.alibaba.ttl.TransmittableThreadLocal;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
@ -0,0 +1,12 @@
|
|||||||
|
/**
|
||||||
|
* 文件客户端,支持多种存储器
|
||||||
|
*
|
||||||
|
* 1. local:本地磁盘
|
||||||
|
* 2. ftp:FTP 服务器
|
||||||
|
* 3. sftp:SFTP 服务器
|
||||||
|
* 4. db:数据库
|
||||||
|
* 5. s3:支持 S3 协议的云存储服务,例如说 MinIO、阿里云、华为云、腾讯云、七牛云等等
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
package cn.iocoder.yudao.module.infra.framework.file;
|
@ -1,12 +1,12 @@
|
|||||||
package cn.iocoder.yudao.module.infra.service.file;
|
package cn.iocoder.yudao.module.infra.service.file;
|
||||||
|
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigPageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigPageReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigSaveReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
|
||||||
|
|
||||||
import javax.validation.Valid;
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 文件配置 Service 接口
|
* 文件配置 Service 接口
|
||||||
|
@ -5,15 +5,15 @@ import cn.hutool.core.util.IdUtil;
|
|||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientFactory;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.enums.FileStorageEnum;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigPageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigPageReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigSaveReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.convert.file.FileConfigConvert;
|
import cn.iocoder.yudao.module.infra.convert.file.FileConfigConvert;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper;
|
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientFactory;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.enums.FileStorageEnum;
|
||||||
import com.google.common.cache.CacheLoader;
|
import com.google.common.cache.CacheLoader;
|
||||||
import com.google.common.cache.LoadingCache;
|
import com.google.common.cache.LoadingCache;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
@ -5,19 +5,18 @@ import cn.hutool.core.util.StrUtil;
|
|||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
import cn.iocoder.yudao.framework.common.util.io.FileUtils;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.s3.FilePresignedUrlRespDTO;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.utils.FileTypeUtils;
|
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileCreateReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FileCreateReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePresignedUrlRespVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
|
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.s3.FilePresignedUrlRespDTO;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.utils.FileTypeUtils;
|
||||||
|
import jakarta.annotation.Resource;
|
||||||
import lombok.SneakyThrows;
|
import lombok.SneakyThrows;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.annotation.Resource;
|
|
||||||
|
|
||||||
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
|
||||||
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
|
import static cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants.FILE_NOT_EXISTS;
|
||||||
|
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.ftp;
|
package cn.iocoder.yudao.module.infra.framework.file.core.ftp;
|
||||||
|
|
||||||
import cn.hutool.core.io.resource.ResourceUtil;
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.hutool.extra.ftp.FtpMode;
|
import cn.hutool.extra.ftp.FtpMode;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.ftp.FtpFileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.ftp.FtpFileClientConfig;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
@ -1,7 +1,9 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.local;
|
package cn.iocoder.yudao.module.infra.framework.file.core.local;
|
||||||
|
|
||||||
import cn.hutool.core.io.resource.ResourceUtil;
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClientConfig;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
@ -1,13 +1,14 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.s3;
|
package cn.iocoder.yudao.module.infra.framework.file.core.s3;
|
||||||
|
|
||||||
import cn.hutool.core.io.resource.ResourceUtil;
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.s3.S3FileClientConfig;
|
||||||
|
import jakarta.validation.Validation;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
||||||
import javax.validation.Validation;
|
|
||||||
|
|
||||||
public class S3FileClientTest {
|
public class S3FileClientTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
@ -1,7 +1,9 @@
|
|||||||
package cn.iocoder.yudao.framework.file.core.client.sftp;
|
package cn.iocoder.yudao.module.infra.framework.file.core.sftp;
|
||||||
|
|
||||||
import cn.hutool.core.io.resource.ResourceUtil;
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
import cn.hutool.core.util.IdUtil;
|
import cn.hutool.core.util.IdUtil;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.sftp.SftpFileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.sftp.SftpFileClientConfig;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
|
@ -4,17 +4,17 @@ import cn.hutool.core.date.DatePattern;
|
|||||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||||
import cn.hutool.core.map.MapUtil;
|
import cn.hutool.core.map.MapUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClientFactory;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.local.LocalFileClient;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.client.local.LocalFileClientConfig;
|
|
||||||
import cn.iocoder.yudao.framework.file.core.enums.FileStorageEnum;
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigPageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigPageReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigSaveReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.config.FileConfigSaveReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileConfigDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper;
|
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileConfigMapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClientFactory;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClient;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.local.LocalFileClientConfig;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.enums.FileStorageEnum;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
|
@ -3,12 +3,12 @@ package cn.iocoder.yudao.module.infra.service.file;
|
|||||||
import cn.hutool.core.io.resource.ResourceUtil;
|
import cn.hutool.core.io.resource.ResourceUtil;
|
||||||
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
import cn.iocoder.yudao.framework.common.pojo.PageResult;
|
||||||
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
import cn.iocoder.yudao.framework.common.util.object.ObjectUtils;
|
||||||
import cn.iocoder.yudao.framework.file.core.client.FileClient;
|
|
||||||
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
import cn.iocoder.yudao.framework.test.core.ut.BaseDbUnitTest;
|
||||||
import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
|
import cn.iocoder.yudao.framework.test.core.util.AssertUtils;
|
||||||
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
import cn.iocoder.yudao.module.infra.controller.admin.file.vo.file.FilePageReqVO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.file.FileDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
|
import cn.iocoder.yudao.module.infra.dal.mysql.file.FileMapper;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.file.core.client.FileClient;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.springframework.boot.test.mock.mockito.MockBean;
|
import org.springframework.boot.test.mock.mockito.MockBean;
|
||||||
import org.springframework.context.annotation.Import;
|
import org.springframework.context.annotation.Import;
|
||||||
|
Loading…
Reference in New Issue
Block a user