静态文件授权支持

This commit is contained in:
ayan 2022-06-13 15:38:37 +08:00
parent 0996f140a9
commit 812749393d
6 changed files with 73 additions and 12 deletions

View File

@ -1,7 +1,13 @@
package org.jetlinks.community.io.excel; package org.jetlinks.community.io.excel;
import org.hswebframework.reactor.excel.converter.RowWrapper;
import org.hswebframework.utils.StringUtils;
import org.jetlinks.community.io.excel.easyexcel.ExcelReadDataListener; import org.jetlinks.community.io.excel.easyexcel.ExcelReadDataListener;
import org.jetlinks.community.io.file.FileManager;
import org.jetlinks.community.io.utils.FileUtils;
import org.springframework.core.io.Resource; import org.springframework.core.io.Resource;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.client.WebClient; import org.springframework.web.reactive.function.client.WebClient;
@ -11,6 +17,8 @@ import reactor.core.publisher.Mono;
import java.io.FileInputStream; import java.io.FileInputStream;
import java.io.InputStream; import java.io.InputStream;
import static org.hswebframework.reactor.excel.ReactorExcel.read;
/** /**
* @author bsetfeng * @author bsetfeng
* @since 1.0 * @since 1.0
@ -20,8 +28,12 @@ public class DefaultImportExportService implements ImportExportService {
private WebClient client; private WebClient client;
public DefaultImportExportService(WebClient.Builder builder) { private final FileManager fileManager;
public DefaultImportExportService(WebClient.Builder builder,
FileManager fileManager) {
client = builder.build(); client = builder.build();
this.fileManager = fileManager;
} }
public <T> Flux<RowResult<T>> doImport(Class<T> clazz, String fileUrl) { public <T> Flux<RowResult<T>> doImport(Class<T> clazz, String fileUrl) {
@ -34,6 +46,24 @@ public class DefaultImportExportService implements ImportExportService {
return ExcelReadDataListener.of(stream, clazz); return ExcelReadDataListener.of(stream, clazz);
} }
@Override
public <T> Flux<T> readData(String fileUrl, String fileId, RowWrapper<T> wrapper) {
if (!StringUtils.isNullOrEmpty(fileUrl)) {
return getInputStream(fileUrl)
.flatMapMany(inputStream -> read(inputStream, FileUtils.getExtension(fileUrl), wrapper));
} else {
return Mono
.zip(fileManager
.read(fileId)
.as(DataBufferUtils::join)
.map(DataBuffer::asInputStream),
fileManager.getFile(fileId))
.flatMapMany(t2 -> read(t2.getT1(), t2.getT2().getExtension(), wrapper));
}
}
public Mono<InputStream> getInputStream(String fileUrl) { public Mono<InputStream> getInputStream(String fileUrl) {
return Mono.defer(() -> { return Mono.defer(() -> {

View File

@ -1,6 +1,7 @@
package org.jetlinks.community.io.excel; package org.jetlinks.community.io.excel;
import org.hswebframework.reactor.excel.converter.RowWrapper;
import reactor.core.publisher.Flux; import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono; import reactor.core.publisher.Mono;
@ -19,4 +20,8 @@ public interface ImportExportService {
Mono<InputStream> getInputStream(String fileUrl); Mono<InputStream> getInputStream(String fileUrl);
<T> Flux<T> readData(String fileUrl, String fileId, RowWrapper<T> wrapper);
} }

View File

@ -44,6 +44,13 @@
<version>1.14.3</version> <version>1.14.3</version>
</dependency> </dependency>
<dependency>
<groupId>org.jetlinks.community</groupId>
<artifactId>io-component</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies> </dependencies>
</project> </project>

View File

@ -11,6 +11,7 @@ import org.hswebframework.web.id.IDGenerator;
import org.hswebframework.web.utils.ExpressionUtils; import org.hswebframework.web.utils.ExpressionUtils;
import org.hswebframework.web.utils.TemplateParser; import org.hswebframework.web.utils.TemplateParser;
import org.hswebframework.web.validator.ValidatorUtils; import org.hswebframework.web.validator.ValidatorUtils;
import org.jetlinks.community.io.file.FileManager;
import org.jetlinks.community.notify.*; import org.jetlinks.community.notify.*;
import org.jetlinks.community.notify.email.EmailProvider; import org.jetlinks.community.notify.email.EmailProvider;
import org.jetlinks.community.notify.template.TemplateManager; import org.jetlinks.community.notify.template.TemplateManager;
@ -19,6 +20,7 @@ import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.springframework.core.io.*; import org.springframework.core.io.*;
import org.springframework.core.io.buffer.DataBufferUtils;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.JavaMailSenderImpl; import org.springframework.mail.javamail.JavaMailSenderImpl;
@ -67,17 +69,23 @@ public class DefaultEmailNotifier extends AbstractNotifier<EmailTemplate> {
@Setter @Setter
private boolean enableFileSystemAttachment = Boolean.getBoolean("email.attach.local-file.enabled"); private boolean enableFileSystemAttachment = Boolean.getBoolean("email.attach.local-file.enabled");
private final FileManager fileManager;
public static Scheduler scheduler = Schedulers.elastic(); public static Scheduler scheduler = Schedulers.elastic();
public DefaultEmailNotifier(NotifierProperties properties, TemplateManager templateManager) { public DefaultEmailNotifier(NotifierProperties properties,
TemplateManager templateManager,
FileManager fileManager) {
this(properties.getId(), this(properties.getId(),
new JSONObject(properties.getConfiguration()).toJavaObject(DefaultEmailProperties.class), new JSONObject(properties.getConfiguration()).toJavaObject(DefaultEmailProperties.class),
templateManager); templateManager,
fileManager);
} }
public DefaultEmailNotifier(String id, public DefaultEmailNotifier(String id,
DefaultEmailProperties properties, DefaultEmailProperties properties,
TemplateManager templateManager) { TemplateManager templateManager,
FileManager fileManager) {
super(templateManager); super(templateManager);
ValidatorUtils.tryValidate(properties); ValidatorUtils.tryValidate(properties);
JavaMailSenderImpl mailSender = new JavaMailSenderImpl(); JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
@ -89,6 +97,7 @@ public class DefaultEmailNotifier extends AbstractNotifier<EmailTemplate> {
this.notifierId = id; this.notifierId = id;
this.sender = properties.getSender(); this.sender = properties.getSender();
this.javaMailSender = mailSender; this.javaMailSender = mailSender;
this.fileManager = fileManager;
} }
@Nonnull @Nonnull
@ -152,7 +161,7 @@ public class DefaultEmailNotifier extends AbstractNotifier<EmailTemplate> {
} }
protected Mono<InputStreamSource> convertResource(String resource) { protected Mono<? extends InputStreamSource> convertResource(String resource) {
if (resource.startsWith("http")) { if (resource.startsWith("http")) {
return WebClient return WebClient
.create() .create()
@ -166,12 +175,17 @@ public class DefaultEmailNotifier extends AbstractNotifier<EmailTemplate> {
return Mono.just( return Mono.just(
new ByteArrayResource(Base64.decodeBase64(base64)) new ByteArrayResource(Base64.decodeBase64(base64))
); );
} else if (enableFileSystemAttachment) { } else if (enableFileSystemAttachment && resource.contains("/")) {
return Mono.just( return Mono.just(
new FileSystemResource(resource) new FileSystemResource(resource)
); );
} else { } else {
throw new UnsupportedOperationException("不支持的文件地址:" + resource); return fileManager
.read(resource)
.as(DataBufferUtils::join)
.map(dataBuffer -> new ByteArrayResource(dataBuffer.asByteBuffer().array()))
.onErrorResume(e-> Mono.error(()-> new UnsupportedOperationException("不支持的文件地址:" + resource)))
.switchIfEmpty(Mono.error(()-> new UnsupportedOperationException("不支持的文件地址:" + resource)));
} }
} }

View File

@ -1,6 +1,7 @@
package org.jetlinks.community.notify.email.embedded; package org.jetlinks.community.notify.email.embedded;
import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSON;
import org.jetlinks.community.io.file.FileManager;
import org.jetlinks.community.notify.*; import org.jetlinks.community.notify.*;
import org.jetlinks.community.notify.email.EmailProvider; import org.jetlinks.community.notify.email.EmailProvider;
import org.jetlinks.community.notify.template.TemplateManager; import org.jetlinks.community.notify.template.TemplateManager;
@ -22,8 +23,12 @@ public class DefaultEmailNotifierProvider implements NotifierProvider, TemplateP
private final TemplateManager templateManager; private final TemplateManager templateManager;
public DefaultEmailNotifierProvider(TemplateManager templateManager) { private final FileManager fileManager;
public DefaultEmailNotifierProvider(TemplateManager templateManager,
FileManager fileManager) {
this.templateManager = templateManager; this.templateManager = templateManager;
this.fileManager = fileManager;
} }
@Nonnull @Nonnull
@ -111,7 +116,7 @@ public class DefaultEmailNotifierProvider implements NotifierProvider, TemplateP
@Nonnull @Nonnull
@Override @Override
public Mono<DefaultEmailNotifier> createNotifier(@Nonnull NotifierProperties properties) { public Mono<DefaultEmailNotifier> createNotifier(@Nonnull NotifierProperties properties) {
return Mono.fromSupplier(() -> new DefaultEmailNotifier(properties, templateManager)); return Mono.fromSupplier(() -> new DefaultEmailNotifier(properties, templateManager, fileManager));
} }
@Override @Override

View File

@ -446,7 +446,8 @@ public class DeviceInstanceController implements
@SaveAction @SaveAction
@Operation(summary = "导入设备数据") @Operation(summary = "导入设备数据")
public Flux<ImportDeviceInstanceResult> doBatchImportByProduct(@PathVariable @Parameter(description = "产品ID") String productId, public Flux<ImportDeviceInstanceResult> doBatchImportByProduct(@PathVariable @Parameter(description = "产品ID") String productId,
@RequestParam @Parameter(description = "文件地址,支持csv,xlsx文件格式") String fileUrl) { @RequestParam(required = false) @Parameter(description = "文件地址,支持csv,xlsx文件格式") String fileUrl,
@RequestParam(required = false) @Parameter(description = "文件Id") String fileId) {
return Authentication return Authentication
.currentReactive() .currentReactive()
.flatMapMany(auth -> { .flatMapMany(auth -> {
@ -461,8 +462,7 @@ public class DeviceInstanceController implements
.getDeviceProductDetail(productId) .getDeviceProductDetail(productId)
.map(tp4 -> Tuples.of(new DeviceWrapper(tp4.getT3().getTags(), tp4.getT4()), tp4.getT1())) .map(tp4 -> Tuples.of(new DeviceWrapper(tp4.getT3().getTags(), tp4.getT4()), tp4.getT1()))
.flatMapMany(wrapper -> importExportService .flatMapMany(wrapper -> importExportService
.getInputStream(fileUrl) .readData(fileUrl, fileId, wrapper.getT1())
.flatMapMany(inputStream -> read(inputStream, FileUtils.getExtension(fileUrl), wrapper.getT1()))
.doOnNext(info -> info.setProductName(wrapper.getT2().getName())) .doOnNext(info -> info.setProductName(wrapper.getT2().getName()))
) )
.map(info -> { .map(info -> {