修复:目录导出缓存逻辑

master
guoxin 1 year ago
parent a00d201763
commit 5a5626fe25
  1. 43
      shandan-browser/src/main/java/com/keyware/shandan/browser/controller/SearchController.java
  2. 41
      shandan-browser/src/main/java/com/keyware/shandan/browser/service/ExportComponent.java

@ -14,9 +14,9 @@ import com.keyware.shandan.browser.entity.SearchConditionVo;
import com.keyware.shandan.browser.service.*;
import com.keyware.shandan.common.entity.Result;
import com.keyware.shandan.common.util.FileDownload;
import com.keyware.shandan.common.util.UUIDUtil;
import com.keyware.shandan.frame.annotation.AppLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
@ -24,7 +24,6 @@ import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* 组合搜索前端控制器
@ -51,8 +50,6 @@ public class SearchController {
@Autowired
private MetadataSearchService metadataSearchService;
private final Map<String, ExportComponent> exportCache = new HashMap<>();
/**
* 全文检索分页查询
*
@ -196,49 +193,63 @@ public class SearchController {
}
/**
* 数据导出-查询数据
* 目录数据导出-创建任务
*
* @param directoryId 目录ID
* @param condition 复杂查询条件
* @return 导出ID
*/
@PostMapping("/export/directory/{directoryId}")
public Result<Object> exportQuery(@PathVariable String directoryId, SearchConditionVo condition) {
String exportId = UUIDUtil.getUUID();
ExportComponent export = new ExportComponent(exportId);
public Result<Object> exportQuery(@PathVariable String directoryId, SearchConditionVo condition, Authentication auth) {
String userId = auth.getPrincipal().toString();
ExportComponent export = null;
// 这个逻辑只允许同一个用户同时只能有一个导出任务
if (ExportComponent.getCache(userId) != null) {
export = ExportComponent.getCache(userId).values().stream().findFirst().orElse(null);
}
if (export == null) {
export = new ExportComponent(userId);
// 查询数据
List<DirectoryResource> list = metadataSearchService.searchAllListByCondition(directoryId, condition);
export.setData(list);
// 打包数据
export.start();
exportCache.put(exportId, export);
}
return Result.of(export.getProgress());
}
/**
* 数据导出-打包数据
* 目录数据导出-查询任务状态
*
* @param exportId 导出ID
* @return 导出ID
*/
@GetMapping("/export/status/{exportId}")
public Result<Object> exportStatus(@PathVariable String exportId) {
ExportComponent export = exportCache.get(exportId);
public Result<Object> exportStatus(@PathVariable String exportId, Authentication auth) {
String userId = auth.getPrincipal().toString();
ExportComponent export = ExportComponent.getCache(userId, exportId);
if (export == null) {
return Result.of(null, false, "导出任务不存在");
}
return Result.of(export.getProgress());
}
/**
* 数据导出-下载
* 目录数据导出-下载
*
* @param response HttpServletResponse
* @param exportId 导出ID
* @return -
*/
@GetMapping("/export/download/{exportId}")
public String exportDownload(HttpServletResponse response, @PathVariable String exportId) {
String path = exportCache.remove(exportId).getExportPath() + ".zip";
public String exportDownload(HttpServletResponse response, @PathVariable String exportId, Authentication auth) {
String userId = auth.getPrincipal().toString();
ExportComponent export = ExportComponent.popCache(userId, exportId);
if (export == null) {
return "错误:导出任务不存在";
}
String path = export.getExportPath() + ".zip";
String downloadName = FileUtil.getName(path);
File file = new File(path);
return FileDownload.download(response, file, downloadName, true);

@ -14,6 +14,7 @@ import com.keyware.shandan.bianmu.entity.MetadataBasicVo;
import com.keyware.shandan.bianmu.service.MetadataService;
import com.keyware.shandan.common.util.StreamUtil;
import com.keyware.shandan.common.util.StringUtils;
import com.keyware.shandan.common.util.UUIDUtil;
import com.keyware.shandan.frame.config.component.AppContext;
import com.keyware.shandan.frame.properties.CustomProperties;
import com.keyware.shandan.system.entity.SysFile;
@ -25,11 +26,12 @@ import lombok.Getter;
import java.io.File;
import java.io.Serializable;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public class ExportComponent extends Thread {
@Getter
private final String exportId;
private final String exportId = UUIDUtil.getUUID();
private final String fileName;
private List<DirectoryResource> dataList;
private final CustomProperties customProperties;
@ -38,17 +40,48 @@ public class ExportComponent extends Thread {
@Getter
private final Progress progress;
// Progress
public ExportComponent(String exportId) {
this.exportId = exportId;
private final static ConcurrentHashMap<String, Map<String, ExportComponent>> cache = new ConcurrentHashMap<>();
public ExportComponent(String userId) {
this.customProperties = AppContext.getContext().getBean(CustomProperties.class);
this.fileService = AppContext.getContext().getBean(SysFileService.class);
this.metadataService = AppContext.getContext().getBean(MetadataService.class);
fileName = "目录导出_" + DateUtil.format(new Date(), "yyyyMMddHHmmss");
this.progress = new Progress(this.exportId);
setCache(userId);
}
public void setCache(String userId) {
Map<String, ExportComponent> userCache = cache.get(userId);
if (userCache == null) {
userCache = new HashMap<>();
}
userCache.put(this.exportId, this);
cache.put(userId, userCache);
}
static public Map<String, ExportComponent> getCache(String userId) {
return cache.get(userId);
}
static public ExportComponent getCache(String userId, String exportId) {
Map<String, ExportComponent> userCache = getCache(userId);
if (userCache == null) {
return null;
} else {
return userCache.get(exportId);
}
}
public static ExportComponent popCache(String userId, String exportId) {
Map<String, ExportComponent> userCache = getCache(userId);
if (userCache == null) {
return null;
} else {
return userCache.remove(exportId);
}
}
/**
* 开始打包