fix: 优化导文件预览

This commit is contained in:
tangwei 2026-04-30 08:50:09 +08:00
parent a8521c554c
commit 91b14b3e3e
3 changed files with 203 additions and 12 deletions

View File

@ -54,6 +54,7 @@ public class SecurityConfig {
.requestMatchers("/user/login").anonymous() .requestMatchers("/user/login").anonymous()
.requestMatchers("/user/code").permitAll() .requestMatchers("/user/code").permitAll()
.requestMatchers("/sms/resetPassword").permitAll() .requestMatchers("/sms/resetPassword").permitAll()
.requestMatchers("/data/fishDraft/previewFile").permitAll()
.requestMatchers("/tempFile/**").permitAll() .requestMatchers("/tempFile/**").permitAll()
.requestMatchers("/system/user/auditUser").permitAll() .requestMatchers("/system/user/auditUser").permitAll()
.requestMatchers("/eng/**").permitAll() .requestMatchers("/eng/**").permitAll()

View File

@ -1,5 +1,15 @@
package com.yfd.platform.data.controller; package com.yfd.platform.data.controller;
import java.io.File;
import java.io.FileInputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import java.nio.file.Files;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import cn.hutool.core.io.FileUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import com.yfd.platform.common.DataSourceRequest; import com.yfd.platform.common.DataSourceRequest;
@ -21,6 +31,8 @@ import com.yfd.platform.utils.SecurityUtils;
import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag; import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource; import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
@ -57,7 +69,7 @@ public class FishDraftDataController {
@PostMapping("/page") @PostMapping("/page")
@Operation(summary = "分页查询过鱼数据(关联电站和设施)") @Operation(summary = "分页查询过鱼数据(关联电站和设施)")
public ResponseResult queryPageList(@RequestBody DataSourceRequest dataSourceRequest) { public ResponseResult queryPageList(@RequestBody DataSourceRequest dataSourceRequest) {
Page<FishDraftDataVO> result = fishDraftDataService.queryPageList( dataSourceRequest); Page<FishDraftDataVO> result = fishDraftDataService.queryPageList(dataSourceRequest);
return ResponseResult.successData(result); return ResponseResult.successData(result);
} }
@ -141,7 +153,7 @@ public class FishDraftDataController {
@PostMapping("/submitDraft") @PostMapping("/submitDraft")
@Operation(summary = "提交草稿") @Operation(summary = "提交草稿")
public ResponseResult submitDraft(@RequestParam String id, public ResponseResult submitDraft(@RequestParam String id,
@RequestParam String operatorId) { @RequestParam String operatorId) {
boolean result = fishDraftDataService.submitDraft(id, operatorId); boolean result = fishDraftDataService.submitDraft(id, operatorId);
return result ? ResponseResult.success("提交成功") : ResponseResult.error("提交失败"); return result ? ResponseResult.success("提交成功") : ResponseResult.error("提交失败");
} }
@ -168,7 +180,6 @@ public class FishDraftDataController {
} }
@PostMapping("/lockDraft") @PostMapping("/lockDraft")
@Operation(summary = "锁定草稿") @Operation(summary = "锁定草稿")
public ResponseResult lockDraft(@RequestParam String id) { public ResponseResult lockDraft(@RequestParam String id) {
@ -256,7 +267,7 @@ public class FishDraftDataController {
result.setTaskId(taskId); result.setTaskId(taskId);
String status = "VALIDATED"; String status = "VALIDATED";
if ("1".equals(result.getCode())) { if ("1".equals(result.getCode())) {
status="FAILED"; status = "FAILED";
} }
importTaskService.updateStatus(taskId, status, null); importTaskService.updateStatus(taskId, status, null);
importTaskService.updateProgress(taskId, result.getTotalCount(), result.getSuccessCount(), result.getFailedCount()); importTaskService.updateProgress(taskId, result.getTotalCount(), result.getSuccessCount(), result.getFailedCount());
@ -275,10 +286,186 @@ public class FishDraftDataController {
} }
} }
@GetMapping("/previewTempFiles")
@Operation(summary = "预览临时文件列表")
public ResponseResult previewTempFiles(@RequestParam String taskId) {
if (taskId == null || taskId.isEmpty()) {
return ResponseResult.error("任务ID不能为空");
}
try {
ImportTask task = importTaskService.getById(taskId);
if (task == null) {
return ResponseResult.error("任务不存在");
}
String resultJson = task.getResultJson();
if (resultJson == null || resultJson.isEmpty()) {
return ResponseResult.error("任务结果为空");
}
FishImportResult importResult = objectMapper.readValue(resultJson, FishImportResult.class);
Map<String, Object> previewData = new HashMap<>();
previewData.put("tempDir", importResult.getTempDir());
previewData.put("excelFileName", importResult.getExcelFileName());
previewData.put("excelFilePath", importResult.getExcelFilePath());
List<Map<String, String>> imageList = new ArrayList<>();
if (importResult.getImageFiles() != null) {
for (Map.Entry<String, String> entry : importResult.getImageFiles().entrySet()) {
Map<String, String> fileInfo = new HashMap<>();
fileInfo.put("originalName", entry.getKey());
fileInfo.put("path", entry.getValue());
fileInfo.put("type", "image");
imageList.add(fileInfo);
}
}
previewData.put("images", imageList);
List<Map<String, String>> videoList = new ArrayList<>();
if (importResult.getVideoFiles() != null) {
for (Map.Entry<String, String> entry : importResult.getVideoFiles().entrySet()) {
Map<String, String> fileInfo = new HashMap<>();
fileInfo.put("originalName", entry.getKey());
fileInfo.put("path", entry.getValue());
fileInfo.put("type", "video");
videoList.add(fileInfo);
}
}
previewData.put("videos", videoList);
previewData.put("totalImages", imageList.size());
previewData.put("totalVideos", videoList.size());
return ResponseResult.successData(previewData);
} catch (Exception e) {
log.error("预览临时文件失败: " + e.getMessage(), e);
return ResponseResult.error("预览失败: " + e.getMessage());
}
}
@GetMapping("/previewFile")
@Operation(summary = "预览临时文件内容")
public void previewFile(@RequestParam String taskId, @RequestParam String filename, @RequestParam String type, HttpServletRequest request, HttpServletResponse response) {
ImportTask importTask = importTaskService.getById(taskId);
String resultJson = importTask.getResultJson();
String filePath = null;
String dir = "1".equals(type) ? "images" : "videos";
if (resultJson != null && !resultJson.isEmpty()) {
try {
FishImportResult importResult = objectMapper.readValue(resultJson, FishImportResult.class);
String tempDir = importResult.getTempDir();
filePath = tempDir + File.separator + dir + File.separator + filename;
} catch (Exception e) {
e.printStackTrace();
// ignore parse error
}
}
if (filePath == null) {
writeErrorResponse(response, "文件路径不能为空");
return;
}
File file = new File(filePath);
if (!file.exists() || !file.isFile()) {
writeErrorResponse(response, "文件不存在");
return;
}
try {
String fileName = file.getName();
String contentType = request.getServletContext().getMimeType(fileName);
if (contentType == null) {
contentType = "application/octet-stream";
}
response.setContentType(contentType);
response.setHeader("Content-Disposition", "inline; filename=\"" + URLEncoder.encode(fileName, "UTF-8") + "\"");
response.setContentLengthLong(file.length());
try (FileInputStream fis = new FileInputStream(file);
OutputStream os = response.getOutputStream()) {
byte[] buffer = new byte[4096];
int bytesRead;
while ((bytesRead = fis.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.flush();
}
} catch (Exception e) {
log.error("预览文件失败: " + e.getMessage(), e);
writeErrorResponse(response, "预览失败: " + e.getMessage());
}
}
@GetMapping("/previewFileBase64")
@Operation(summary = "预览临时文件内容(Base64方式)")
public ResponseResult previewFileBase64(@RequestParam String filePath) {
if (filePath == null || filePath.isEmpty()) {
return ResponseResult.error("文件路径不能为空");
}
File file = new File(filePath);
if (!file.exists() || !file.isFile()) {
return ResponseResult.error("文件不存在");
}
try {
String fileName = file.getName();
String contentType = getMimeType(fileName);
byte[] fileContent = Files.readAllBytes(file.toPath());
String base64Content = Base64.getEncoder().encodeToString(fileContent);
Map<String, Object> result = new HashMap<>();
result.put("fileName", fileName);
result.put("contentType", contentType);
result.put("base64Content", base64Content);
result.put("size", file.length());
return ResponseResult.successData(result);
} catch (Exception e) {
log.error("预览文件失败: " + e.getMessage(), e);
return ResponseResult.error("预览失败: " + e.getMessage());
}
}
private void writeErrorResponse(HttpServletResponse response, String message) {
try {
response.setContentType("application/json;charset=UTF-8");
response.getWriter().write("{\"success\":false,\"message\":\"" + message + "\"}");
} catch (Exception ignored) {
}
}
private String getMimeType(String fileName) {
if (fileName == null) return "application/octet-stream";
String lowerName = fileName.toLowerCase();
if (lowerName.endsWith(".jpg") || lowerName.endsWith(".jpeg")) {
return "image/jpeg";
} else if (lowerName.endsWith(".png")) {
return "image/png";
} else if (lowerName.endsWith(".gif")) {
return "image/gif";
} else if (lowerName.endsWith(".mp4")) {
return "video/mp4";
} else if (lowerName.endsWith(".webm")) {
return "video/webm";
} else if (lowerName.endsWith(".pdf")) {
return "application/pdf";
} else if (lowerName.endsWith(".xlsx") || lowerName.endsWith(".xls")) {
return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
}
return "application/octet-stream";
}
@PostMapping("/cancelImport") @PostMapping("/cancelImport")
@Operation(summary = "取消导入任务") @Operation(summary = "取消导入任务")
public ResponseResult cancelImport(@RequestBody FishImportRequest fishImportRequest) { public ResponseResult cancelImport(@RequestBody FishImportRequest fishImportRequest) {
boolean result = importTaskService.cancelTask(fishImportRequest.getTaskId(),SecurityUtils.getUserId()); boolean result = importTaskService.cancelTask(fishImportRequest.getTaskId(), SecurityUtils.getUserId());
return result ? ResponseResult.success("取消成功") : ResponseResult.error("取消失败"); return result ? ResponseResult.success("取消成功") : ResponseResult.error("取消失败");
} }
@ -529,34 +716,34 @@ public class FishDraftDataController {
} }
private void validateAndNormalizeData(FishDraftData data, FishImportResult.FishImportRow importRow, private void validateAndNormalizeData(FishDraftData data, FishImportResult.FishImportRow importRow,
List<String> warnings) { List<String> warnings) {
if (data.getStcd() == null || data.getStcd().isEmpty()) { if (data.getStcd() == null || data.getStcd().isEmpty()) {
warnings.add("stcd"); warnings.add("stcd");
} else { } else {
String stcd = fishImportService.resolveFpssCode(data.getStcd(),data.getStnm()); String stcd = fishImportService.resolveFpssCode(data.getStcd(), data.getStnm());
if (stcd == null) { if (stcd == null) {
warnings.add("stcd"); warnings.add("stcd");
} }
} }
if (data.getRstcd() != null && !data.getRstcd().isEmpty()) { if (data.getRstcd() != null && !data.getRstcd().isEmpty()) {
String stationCode = fishImportService.resolveStationCode(data.getRstcd(),data.getEnnm()); String stationCode = fishImportService.resolveStationCode(data.getRstcd(), data.getEnnm());
if (stationCode == null) { if (stationCode == null) {
warnings.add("rstcd"); warnings.add("rstcd");
} }
}else{ } else {
warnings.add("rstcd"); warnings.add("rstcd");
} }
if (data.getBaseId() != null && !data.getBaseId().isEmpty()) { if (data.getBaseId() != null && !data.getBaseId().isEmpty()) {
String baseId = fishImportService.resolveBaseCode(data.getBaseId(),data.getBaseName()); String baseId = fishImportService.resolveBaseCode(data.getBaseId(), data.getBaseName());
if (baseId == null) { if (baseId == null) {
warnings.add("baseId"); warnings.add("baseId");
} }
} }
if (data.getRvcd() != null && !data.getRvcd().isEmpty()) { if (data.getRvcd() != null && !data.getRvcd().isEmpty()) {
String rvcd = fishImportService.resolveRiverCode(data.getRvcd(),data.getRvcd()); String rvcd = fishImportService.resolveRiverCode(data.getRvcd(), data.getRvcd());
if (rvcd == null) { if (rvcd == null) {
warnings.add("rvcd"); warnings.add("rvcd");
} }
@ -569,7 +756,7 @@ public class FishDraftDataController {
if (data.getFtp() == null || data.getFtp().isEmpty()) { if (data.getFtp() == null || data.getFtp().isEmpty()) {
warnings.add("ftp"); warnings.add("ftp");
} else { } else {
String ftpCode = fishImportService.resolveFishDictCode(data.getFtp(),data.getFtpName()); String ftpCode = fishImportService.resolveFishDictCode(data.getFtp(), data.getFtpName());
if (ftpCode == null) { if (ftpCode == null) {
warnings.add("ftp"); warnings.add("ftp");
} }

View File

@ -200,6 +200,9 @@ public class ImportTaskServiceImpl extends ServiceImpl<ImportTaskMapper, ImportT
fileIds.forEach(fileId -> attachmentUploadService.deleteFile(fileId)); fileIds.forEach(fileId -> attachmentUploadService.deleteFile(fileId));
} }
} }
String tempDir = importResult.getTempDir();
// del 方法会递归删除目录及其所有内容
FileUtil.del(tempDir);
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
// ignore parse error // ignore parse error