diff --git a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/io/FileUtils.java b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/io/FileUtils.java
index 56baaed95..63732f1b3 100644
--- a/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/io/FileUtils.java
+++ b/yudao-framework/yudao-common/src/main/java/cn/iocoder/yudao/framework/common/util/io/FileUtils.java
@@ -22,13 +22,40 @@ public class FileUtils {
*/
@SneakyThrows
public static File createTempFile(String data) {
- // 创建文件,通过 UUID 保证唯一
- File file = File.createTempFile(IdUtil.simpleUUID(), null);
- // 标记 JVM 退出时,自动删除
- file.deleteOnExit();
+ File file = createTempFile();
// 写入内容
FileUtil.writeUtf8String(data, file);
return file;
}
+ /**
+ * 创建临时文件
+ * 该文件会在 JVM 退出时,进行删除
+ *
+ * @param data 文件内容
+ * @return 文件
+ */
+ @SneakyThrows
+ public static File createTempFile(byte[] data) {
+ File file = createTempFile();
+ // 写入内容
+ FileUtil.writeBytes(data, file);
+ return file;
+ }
+
+ /**
+ * 创建临时文件,无内容
+ * 该文件会在 JVM 退出时,进行删除
+ *
+ * @return 文件
+ */
+ @SneakyThrows
+ public static File createTempFile() {
+ // 创建文件,通过 UUID 保证唯一
+ File file = File.createTempFile(IdUtil.simpleUUID(), null);
+ // 标记 JVM 退出时,自动删除
+ file.deleteOnExit();
+ return file;
+ }
+
}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/pom.xml b/yudao-framework/yudao-spring-boot-starter-file/pom.xml
index 126bf9b77..015463941 100644
--- a/yudao-framework/yudao-spring-boot-starter-file/pom.xml
+++ b/yudao-framework/yudao-spring-boot-starter-file/pom.xml
@@ -51,6 +51,18 @@
jackson-core
+
+ commons-net
+ commons-net
+ 3.8.0
+
+
+ com.jcraft
+ jsch
+ 0.1.55
+
+
+
software.amazon.awssdk
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/AbstractFileClient.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/AbstractFileClient.java
index 13f104118..4aef2f387 100644
--- a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/AbstractFileClient.java
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/AbstractFileClient.java
@@ -1,5 +1,6 @@
package cn.iocoder.yudao.framework.file.core.client.impl;
+import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.file.core.client.FileClient;
import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
import lombok.extern.slf4j.Slf4j;
@@ -55,4 +56,16 @@ public abstract class AbstractFileClient implem
return id;
}
+ /**
+ * 格式化文件的 URL 访问地址
+ * 使用场景:local、ftp、db,通过 FileController 的 getFile 来获取文件内容
+ *
+ * @param domain 自定义域名
+ * @param path 文件路径
+ * @return URL 访问地址
+ */
+ protected String formatFileUrl(String domain, String path) {
+ return StrUtil.format("{}/system-api/{}/get/{}", domain, getId(), path);
+ }
+
}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/ftp/FtpFileClient.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/ftp/FtpFileClient.java
new file mode 100644
index 000000000..556f4e28c
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/ftp/FtpFileClient.java
@@ -0,0 +1,73 @@
+package cn.iocoder.yudao.framework.file.core.client.impl.ftp;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.CharsetUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.extra.ftp.Ftp;
+import cn.hutool.extra.ftp.FtpException;
+import cn.hutool.extra.ftp.FtpMode;
+import cn.iocoder.yudao.framework.file.core.client.impl.AbstractFileClient;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+
+/**
+ * Ftp 文件客户端
+ *
+ * @author 芋道源码
+ */
+public class FtpFileClient extends AbstractFileClient {
+
+ private Ftp ftp;
+
+ public FtpFileClient(Long id, FtpFileClientConfig config) {
+ super(id, config);
+ }
+
+ @Override
+ protected void doInit() {
+ // 补全风格。例如说 Linux 是 /,Windows 是 \
+ if (!config.getBasePath().endsWith(File.separator)) {
+ config.setBasePath(config.getBasePath() + File.separator);
+ }
+ // 初始化 Ftp 对象
+ this.ftp = new Ftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword(),
+ CharsetUtil.CHARSET_UTF_8, null, null, FtpMode.valueOf(config.getMode()));
+ }
+
+ @Override
+ public String upload(byte[] content, String path) {
+ // 执行写入
+ String filePath = getFilePath(path);
+ String fileName = FileUtil.getName(filePath);
+ String dir = StrUtil.removeSuffix(filePath, fileName);
+ boolean success = ftp.upload(dir, fileName, new ByteArrayInputStream(content));
+ if (!success) {
+ throw new FtpException(StrUtil.format("上海文件到目标目录 ({}) 失败", filePath));
+ }
+ // 拼接返回路径
+ return super.formatFileUrl(config.getDomain(), path);
+ }
+
+ @Override
+ public void delete(String path) {
+ String filePath = getFilePath(path);
+ ftp.delFile(filePath);
+ }
+
+ @Override
+ public byte[] getContent(String path) {
+ String filePath = getFilePath(path);
+ String fileName = FileUtil.getName(filePath);
+ String dir = StrUtil.removeSuffix(path, fileName);
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ ftp.download(dir, fileName, out);
+ return out.toByteArray();
+ }
+
+ private String getFilePath(String path) {
+ return config.getBasePath() + path;
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/ftp/FtpFileClientConfig.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/ftp/FtpFileClientConfig.java
new file mode 100644
index 000000000..bc0038219
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/ftp/FtpFileClientConfig.java
@@ -0,0 +1,59 @@
+package cn.iocoder.yudao.framework.file.core.client.impl.ftp;
+
+import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
+import lombok.Data;
+import org.hibernate.validator.constraints.URL;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/**
+ * Ftp 文件客户端的配置类
+ *
+ * @author 芋道源码
+ */
+@Data
+public class FtpFileClientConfig implements FileClientConfig {
+
+ /**
+ * 基础路径
+ */
+ @NotEmpty(message = "基础路径不能为空")
+ private String basePath;
+
+ /**
+ * 自定义域名
+ */
+ @NotEmpty(message = "domain 不能为空")
+ @URL(message = "domain 必须是 URL 格式")
+ private String domain;
+
+ /**
+ * 主机地址
+ */
+ @NotEmpty(message = "host 不能为空")
+ private String host;
+ /**
+ * 主机端口
+ */
+ @NotNull(message = "port 不能为空")
+ private Integer port;
+ /**
+ * 用户名
+ */
+ @NotEmpty(message = "用户名不能为空")
+ private String username;
+ /**
+ * 密码
+ */
+ @NotEmpty(message = "密码不能为空")
+ private String password;
+ /**
+ * 连接模式
+ *
+ * 使用 {@link cn.hutool.extra.ftp.FtpMode} 对应的字符串
+ */
+ @NotEmpty(message = "连接模式不能为空")
+ private String mode;
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/local/LocalFileClient.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/local/LocalFileClient.java
new file mode 100644
index 000000000..aea6b1ee2
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/local/LocalFileClient.java
@@ -0,0 +1,52 @@
+package cn.iocoder.yudao.framework.file.core.client.impl.local;
+
+import cn.hutool.core.io.FileUtil;
+import cn.iocoder.yudao.framework.file.core.client.impl.AbstractFileClient;
+
+import java.io.File;
+
+/**
+ * 本地文件客户端
+ *
+ * @author 芋道源码
+ */
+public class LocalFileClient extends AbstractFileClient {
+
+ public LocalFileClient(Long id, LocalFileClientConfig config) {
+ super(id, config);
+ }
+
+ @Override
+ protected void doInit() {
+ // 补全风格。例如说 Linux 是 /,Windows 是 \
+ if (!config.getBasePath().endsWith(File.separator)) {
+ config.setBasePath(config.getBasePath() + File.separator);
+ }
+ }
+
+ @Override
+ public String upload(byte[] content, String path) {
+ // 执行写入
+ String filePath = getFilePath(path);
+ FileUtil.writeBytes(content, filePath);
+ // 拼接返回路径
+ return super.formatFileUrl(config.getDomain(), path);
+ }
+
+ @Override
+ public void delete(String path) {
+ String filePath = getFilePath(path);
+ FileUtil.del(filePath);
+ }
+
+ @Override
+ public byte[] getContent(String path) {
+ String filePath = getFilePath(path);
+ return FileUtil.readBytes(filePath);
+ }
+
+ private String getFilePath(String path) {
+ return config.getBasePath() + path;
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/local/LocalFileClientConfig.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/local/LocalFileClientConfig.java
new file mode 100644
index 000000000..9820de7dd
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/local/LocalFileClientConfig.java
@@ -0,0 +1,30 @@
+package cn.iocoder.yudao.framework.file.core.client.impl.local;
+
+import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
+import lombok.Data;
+import org.hibernate.validator.constraints.URL;
+
+import javax.validation.constraints.NotEmpty;
+
+/**
+ * 本地文件客户端的配置类
+ *
+ * @author 芋道源码
+ */
+@Data
+public class LocalFileClientConfig implements FileClientConfig {
+
+ /**
+ * 基础路径
+ */
+ @NotEmpty(message = "基础路径不能为空")
+ private String basePath;
+
+ /**
+ * 自定义域名
+ */
+ @NotEmpty(message = "domain 不能为空")
+ @URL(message = "domain 必须是 URL 格式")
+ private String domain;
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/s3/S3FileClient.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/s3/S3FileClient.java
index 09d98398e..1f2b4aaae 100644
--- a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/s3/S3FileClient.java
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/s3/S3FileClient.java
@@ -7,6 +7,8 @@ import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.core.sync.RequestBody;
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.s3.S3Client;
+import software.amazon.awssdk.services.s3.model.DeleteObjectRequest;
+import software.amazon.awssdk.services.s3.model.GetObjectRequest;
import software.amazon.awssdk.services.s3.model.PutObjectRequest;
import java.net.URI;
@@ -14,7 +16,7 @@ import java.net.URI;
import static cn.iocoder.yudao.framework.file.core.client.impl.s3.S3FileClientConfig.ENDPOINT_QINIU;
/**
- * 基于 S3 协议,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务
+ * 基于 S3 协议的文件客户端,实现 MinIO、阿里云、腾讯云、七牛云、华为云等云服务
*
* S3 协议的客户端,采用亚马逊提供的 software.amazon.awssdk.s3 库
*
@@ -84,12 +86,18 @@ public class S3FileClient extends AbstractFileClient {
@Override
public void delete(String path) {
-
+ DeleteObjectRequest.Builder request = DeleteObjectRequest.builder()
+ .bucket(config.getBucket()) // bucket 必须传递
+ .key(path); // 相对路径作为 key
+ client.deleteObject(request.build());
}
@Override
public byte[] getContent(String path) {
- return new byte[0];
+ GetObjectRequest.Builder request = GetObjectRequest.builder()
+ .bucket(config.getBucket()) // bucket 必须传递
+ .key(path); // 相对路径作为 key
+ return client.getObjectAsBytes(request.build()).asByteArray();
}
}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/sftp/SftpFileClient.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/sftp/SftpFileClient.java
new file mode 100644
index 000000000..704300264
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/sftp/SftpFileClient.java
@@ -0,0 +1,61 @@
+package cn.iocoder.yudao.framework.file.core.client.impl.sftp;
+
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.extra.ssh.Sftp;
+import cn.iocoder.yudao.framework.common.util.io.FileUtils;
+import cn.iocoder.yudao.framework.file.core.client.impl.AbstractFileClient;
+
+import java.io.File;
+
+/**
+ * Sftp 文件客户端
+ *
+ * @author 芋道源码
+ */
+public class SftpFileClient extends AbstractFileClient {
+
+ private Sftp sftp;
+
+ public SftpFileClient(Long id, SftpFileClientConfig config) {
+ super(id, config);
+ }
+
+ @Override
+ protected void doInit() {
+ // 补全风格。例如说 Linux 是 /,Windows 是 \
+ if (!config.getBasePath().endsWith(File.separator)) {
+ config.setBasePath(config.getBasePath() + File.separator);
+ }
+ // 初始化 Ftp 对象
+ this.sftp = new Sftp(config.getHost(), config.getPort(), config.getUsername(), config.getPassword());
+ }
+
+ @Override
+ public String upload(byte[] content, String path) {
+ // 执行写入
+ String filePath = getFilePath(path);
+ File file = FileUtils.createTempFile(content);
+ sftp.upload(filePath, file);
+ // 拼接返回路径
+ return super.formatFileUrl(config.getDomain(), path);
+ }
+
+ @Override
+ public void delete(String path) {
+ String filePath = getFilePath(path);
+ sftp.delFile(filePath);
+ }
+
+ @Override
+ public byte[] getContent(String path) {
+ String filePath = getFilePath(path);
+ File destFile = FileUtils.createTempFile();
+ sftp.download(filePath, destFile);
+ return FileUtil.readBytes(destFile);
+ }
+
+ private String getFilePath(String path) {
+ return config.getBasePath() + path;
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/sftp/SftpFileClientConfig.java b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/sftp/SftpFileClientConfig.java
new file mode 100644
index 000000000..6941e1521
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/main/java/cn/iocoder/yudao/framework/file/core/client/impl/sftp/SftpFileClientConfig.java
@@ -0,0 +1,52 @@
+package cn.iocoder.yudao.framework.file.core.client.impl.sftp;
+
+import cn.iocoder.yudao.framework.file.core.client.FileClientConfig;
+import lombok.Data;
+import org.hibernate.validator.constraints.URL;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/**
+ * Sftp 文件客户端的配置类
+ *
+ * @author 芋道源码
+ */
+@Data
+public class SftpFileClientConfig implements FileClientConfig {
+
+ /**
+ * 基础路径
+ */
+ @NotEmpty(message = "基础路径不能为空")
+ private String basePath;
+
+ /**
+ * 自定义域名
+ */
+ @NotEmpty(message = "domain 不能为空")
+ @URL(message = "domain 必须是 URL 格式")
+ private String domain;
+
+ /**
+ * 主机地址
+ */
+ @NotEmpty(message = "host 不能为空")
+ private String host;
+ /**
+ * 主机端口
+ */
+ @NotNull(message = "port 不能为空")
+ private Integer port;
+ /**
+ * 用户名
+ */
+ @NotEmpty(message = "用户名不能为空")
+ private String username;
+ /**
+ * 密码
+ */
+ @NotEmpty(message = "密码不能为空")
+ private String password;
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/ftp/FtpFileClientTest.java b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/ftp/FtpFileClientTest.java
new file mode 100644
index 000000000..7c37c014d
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/ftp/FtpFileClientTest.java
@@ -0,0 +1,39 @@
+package cn.iocoder.yudao.framework.file.core.client.ftp;
+
+import cn.hutool.core.io.resource.ResourceUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.hutool.extra.ftp.FtpMode;
+import cn.iocoder.yudao.framework.file.core.client.impl.ftp.FtpFileClient;
+import cn.iocoder.yudao.framework.file.core.client.impl.ftp.FtpFileClientConfig;
+import org.junit.jupiter.api.Test;
+
+public class FtpFileClientTest {
+
+ @Test
+ public void test() {
+ // 创建客户端
+ FtpFileClientConfig config = new FtpFileClientConfig();
+ config.setDomain("http://127.0.0.1:48080");
+ config.setBasePath("/home/ftp");
+ config.setHost("kanchai.club");
+ config.setPort(221);
+ config.setUsername("");
+ config.setPassword("");
+ config.setMode(FtpMode.Passive.name());
+ FtpFileClient client = new FtpFileClient(0L, config);
+ client.init();
+ // 上传文件
+ String path = IdUtil.fastSimpleUUID() + ".jpg";
+ byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
+ String fullPath = client.upload(content, path);
+ System.out.println("访问地址:" + fullPath);
+ if (false) {
+ byte[] bytes = client.getContent(path);
+ System.out.println("文件内容:" + bytes);
+ }
+ if (false) {
+ client.delete(path);
+ }
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/local/LocalFileClientTest.java b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/local/LocalFileClientTest.java
new file mode 100644
index 000000000..62e5ea249
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/local/LocalFileClientTest.java
@@ -0,0 +1,27 @@
+package cn.iocoder.yudao.framework.file.core.client.local;
+
+import cn.hutool.core.io.resource.ResourceUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.iocoder.yudao.framework.file.core.client.impl.local.LocalFileClient;
+import cn.iocoder.yudao.framework.file.core.client.impl.local.LocalFileClientConfig;
+import org.junit.jupiter.api.Test;
+
+public class LocalFileClientTest {
+
+ @Test
+ public void test() {
+ // 创建客户端
+ LocalFileClientConfig config = new LocalFileClientConfig();
+ config.setDomain("http://127.0.0.1:48080");
+ config.setBasePath("/Users/yunai/file_test");
+ LocalFileClient client = new LocalFileClient(0L, config);
+ client.init();
+ // 上传文件
+ String path = IdUtil.fastSimpleUUID() + ".jpg";
+ byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
+ String fullPath = client.upload(content, path);
+ System.out.println("访问地址:" + fullPath);
+ client.delete(path);
+ }
+
+}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientTest.java b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientTest.java
index 5db3ac699..5d9224b74 100644
--- a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientTest.java
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/s3/S3FileClientTest.java
@@ -76,6 +76,15 @@ public class S3FileClientTest {
byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
String fullPath = client.upload(content, path);
System.out.println("访问地址:" + fullPath);
+ // 读取文件
+ if (false) {
+ byte[] bytes = client.getContent(path);
+ System.out.println("文件内容:" + bytes);
+ }
+ // 删除文件
+ if (false) {
+ client.delete(path);
+ }
}
}
diff --git a/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/sftp/SftpFileClientTest.java b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/sftp/SftpFileClientTest.java
new file mode 100644
index 000000000..13e331047
--- /dev/null
+++ b/yudao-framework/yudao-spring-boot-starter-file/src/test/java/cn/iocoder/yudao/framework/file/core/client/sftp/SftpFileClientTest.java
@@ -0,0 +1,37 @@
+package cn.iocoder.yudao.framework.file.core.client.sftp;
+
+import cn.hutool.core.io.resource.ResourceUtil;
+import cn.hutool.core.util.IdUtil;
+import cn.iocoder.yudao.framework.file.core.client.impl.sftp.SftpFileClient;
+import cn.iocoder.yudao.framework.file.core.client.impl.sftp.SftpFileClientConfig;
+import org.junit.jupiter.api.Test;
+
+public class SftpFileClientTest {
+
+ @Test
+ public void test() {
+ // 创建客户端
+ SftpFileClientConfig config = new SftpFileClientConfig();
+ config.setDomain("http://127.0.0.1:48080");
+ config.setBasePath("/home/ftp");
+ config.setHost("kanchai.club");
+ config.setPort(222);
+ config.setUsername("");
+ config.setPassword("");
+ SftpFileClient client = new SftpFileClient(0L, config);
+ client.init();
+ // 上传文件
+ String path = IdUtil.fastSimpleUUID() + ".jpg";
+ byte[] content = ResourceUtil.readBytes("file/erweima.jpg");
+ String fullPath = client.upload(content, path);
+ System.out.println("访问地址:" + fullPath);
+ if (false) {
+ byte[] bytes = client.getContent(path);
+ System.out.println("文件内容:" + bytes);
+ }
+ if (false) {
+ client.delete(path);
+ }
+ }
+
+}
diff --git a/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java b/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java
index 48c7e146c..7d449dbe8 100644
--- a/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java
+++ b/yudao-module-infra/yudao-module-infra-impl/src/main/java/cn/iocoder/yudao/module/infra/controller/admin/file/FileController.java
@@ -57,10 +57,15 @@ public class FileController {
return success(true);
}
- @GetMapping("/get/{path}")
+ @GetMapping("/{configId}/get/{path}")
@ApiOperation("下载文件")
- @ApiImplicitParam(name = "path", value = "文件附件", required = true, dataTypeClass = MultipartFile.class)
- public void getFile(HttpServletResponse response, @PathVariable("path") String path) throws IOException {
+ @ApiImplicitParams({
+ @ApiImplicitParam(name = "configId", value = "配置编号", required = true, dataTypeClass = String.class),
+ @ApiImplicitParam(name = "path", value = "文件路径", required = true, dataTypeClass = String.class)
+ })
+ public void getFile(HttpServletResponse response,
+ @PathVariable("configId") String configId,
+ @PathVariable("path") String path) throws IOException {
FileDO file = fileService.getFile(path);
if (file == null) {
log.warn("[getFile][path({}) 文件不存在]", path);