异常记录检测修改

This commit is contained in:
super
2026-05-04 19:04:55 +08:00
parent f46c231323
commit 111f30d150
70 changed files with 7182 additions and 252 deletions
@@ -14,10 +14,7 @@ import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
@@ -28,9 +25,7 @@ import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.net.URI;
@RestController
@RequiredArgsConstructor
@@ -100,15 +95,14 @@ public class ConvertRunController {
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "200", description = "返回结果文件流"),
@io.swagger.v3.oas.annotations.responses.ApiResponse(responseCode = "404", description = "结果文件不存在")
})
public ResponseEntity<Resource> download(
public ResponseEntity<Void> download(
@Parameter(description = "格式转换结果记录 ID", required = true) @PathVariable Long resultId,
@Parameter(name = "user_id", description = "当前登录用户 ID", required = true, in = ParameterIn.QUERY)
@RequestParam("user_id") Long userId) {
File resultFile = convertRunService.getResultFile(resultId, userId);
String encodedFilename = URLEncoder.encode(resultFile.getName(), StandardCharsets.UTF_8).replaceAll("\\+", "%20");
return ResponseEntity.ok()
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename*=UTF-8''" + encodedFilename)
.body(new FileSystemResource(resultFile));
String downloadUrl = convertRunService.getResultDownloadUrl(resultId, userId);
return ResponseEntity.status(302)
.location(URI.create(downloadUrl))
.header(HttpHeaders.CACHE_CONTROL, "no-store")
.build();
}
}
@@ -29,6 +29,7 @@ import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
@@ -43,6 +44,7 @@ public class ConvertRunService {
private static final String MODULE_TYPE = "CONVERT";
private static final String TEMPLATE_CODE_FIVE_COUNTRIES = "uk_offer";
private static final DateTimeFormatter ZIP_NAME_DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");
private static final List<String> FIVE_COUNTRY_OUTPUT_FILES = List.of(
"英国.txt",
"法国.txt",
@@ -76,10 +78,12 @@ public class ConvertRunService {
fileTaskMapper.insert(task);
boolean folderMode = request.getArchiveName() != null && !request.getArchiveName().isBlank();
boolean archiveMode = folderMode || request.getFiles().size() > 1;
List<ConvertResultItemVo> items = new ArrayList<>();
int successCount = 0;
int failedCount = 0;
List<ConvertArchiveEntry> archiveEntries = new ArrayList<>();
List<String> successSourceNames = new ArrayList<>();
for (UploadedSourceFileDto sourceFile : request.getFiles()) {
try {
@@ -92,10 +96,11 @@ public class ConvertRunService {
? inputFile.getName()
: sourceFile.getOriginalFilename();
List<GeneratedConvertFile> generatedFiles = generateOutputFiles(inputFile, template);
if (folderMode) {
if (archiveMode) {
for (GeneratedConvertFile generatedFile : generatedFiles) {
archiveEntries.add(new ConvertArchiveEntry(sourceFile.getRelativePath(), inputName, generatedFile));
}
successSourceNames.add(inputName);
successCount++;
continue;
}
@@ -153,12 +158,13 @@ public class ConvertRunService {
}
}
if (folderMode && !archiveEntries.isEmpty()) {
File zipFile = packageFolderConvertResultsAsZip(request.getArchiveName(), archiveEntries);
if (archiveMode && !archiveEntries.isEmpty()) {
String archiveName = resolveArchiveName(request.getArchiveName(), successSourceNames);
File zipFile = packageFolderConvertResultsAsZip(archiveName, archiveEntries);
String ossObjectKey = ossStorageService.uploadResultFile(zipFile, MODULE_TYPE);
// 只存 objectKey
ConvertResultItemVo item = new ConvertResultItemVo();
item.setSourceFilename(request.getArchiveName());
item.setSourceFilename(folderMode ? request.getArchiveName() : "Current convert task");
item.setOutputFilename(zipFile.getName());
item.setSuccess(true);
item.setDownloadUrl(ossStorageService.generateFreshDownloadUrl(ossObjectKey));
@@ -166,7 +172,7 @@ public class ConvertRunService {
FileResultEntity resultEntity = new FileResultEntity();
resultEntity.setTaskId(task.getId());
resultEntity.setModuleType(MODULE_TYPE);
resultEntity.setSourceFilename(request.getArchiveName());
resultEntity.setSourceFilename(item.getSourceFilename());
resultEntity.setResultFilename(zipFile.getName());
resultEntity.setResultFileUrl(ossObjectKey); // 存 objectKey
resultEntity.setResultFileSize(zipFile.length());
@@ -205,7 +211,7 @@ public class ConvertRunService {
vo.setResultId(entity.getId());
vo.setSourceFilename(entity.getSourceFilename());
vo.setOutputFilename(entity.getResultFilename());
vo.setDownloadUrl(null);
vo.setDownloadUrl(entity.getResultFileUrl() == null ? null : ossStorageService.generateFreshDownloadUrl(entity.getResultFileUrl()));
vo.setSuccess(entity.getSuccess() != null && entity.getSuccess() == 1);
vo.setError(entity.getErrorMessage());
return vo;
@@ -221,17 +227,12 @@ public class ConvertRunService {
fileResultMapper.deleteById(resultId);
}
public File getResultFile(Long resultId, Long userId) {
public String getResultDownloadUrl(Long resultId, Long userId) {
FileResultEntity entity = fileResultMapper.selectById(resultId);
if (entity == null || entity.getResultFileUrl() == null || !MODULE_TYPE.equals(entity.getModuleType()) || !userId.equals(entity.getUserId())) {
throw new BusinessException("Convert result file does not exist.");
}
File file = new File(entity.getResultFileUrl());
if (!file.exists()) {
throw new BusinessException("Convert result file does not exist.");
}
return file;
return ossStorageService.generateFreshDownloadUrl(entity.getResultFileUrl());
}
private List<GeneratedConvertFile> generateOutputFiles(File inputFile, ConvertTemplateEntity templateEntity) throws IOException {
@@ -410,6 +411,16 @@ public class ConvertRunService {
return zipFile;
}
private String resolveArchiveName(String archiveName, List<String> successSourceNames) {
if (archiveName != null && !archiveName.isBlank()) {
return FileUtil.mainName(archiveName.trim());
}
if (successSourceNames.size() == 1) {
return FileUtil.mainName(successSourceNames.getFirst());
}
return "convert-" + LocalDateTime.now().format(ZIP_NAME_DATE_FORMATTER);
}
private String buildFolderZipEntry(String relativePath, String inputName, String outputFilename, boolean includeSourceStemFolder) {
String normalizedRelativePath = relativePath == null ? "" : relativePath.replace('\\', '/');
String relativeDir = normalizedRelativePath.contains("/")