fix: 修复tempFilePaths和records对应关系的潜在bug
问题: - 原代码中保存临时文件和创建记录使用两个独立的循环 - 无法保证两个列表的索引严格一一对应 - 如果中间出现异常或跳过,会导致对应关系错乱 修复: - 将两个循环合并为一个,在同一个循环中处理 - 使用相同的索引i创建tempFilePaths[i]和records[i] - 添加数量一致性验证 - 临时文件名中加入索引i,避免文件名冲突 - 日志中记录索引i便于调试 影响: - 确保临时文件和数据库记录严格一一对应 - 避免异步处理时出现文件与记录不匹配的问题
This commit is contained in:
@@ -166,8 +166,11 @@ public class CcdiFileUploadServiceImpl implements ICcdiFileUploadService {
|
||||
|
||||
log.info("【文件上传】项目信息验证通过: projectId={}, lsfxProjectId={}", projectId, lsfxProjectId);
|
||||
|
||||
// Critical Fix #2: 保存MultipartFile到临时存储,避免异步处理时文件已被清理
|
||||
// Critical Fix #2 & #4: 保存临时文件和创建记录在同一个循环中,确保一一对应
|
||||
List<String> tempFilePaths = new ArrayList<>();
|
||||
List<CcdiFileUploadRecord> records = new ArrayList<>();
|
||||
Date now = new Date();
|
||||
|
||||
try {
|
||||
// 确保临时目录存在
|
||||
Path tempDir = Paths.get(getTempFileDir());
|
||||
@@ -175,39 +178,41 @@ public class CcdiFileUploadServiceImpl implements ICcdiFileUploadService {
|
||||
Files.createDirectories(tempDir);
|
||||
}
|
||||
|
||||
// 保存所有文件到临时目录
|
||||
for (MultipartFile file : files) {
|
||||
// 同一个循环中保存临时文件和创建记录,确保索引一一对应
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
MultipartFile file = files[i];
|
||||
|
||||
// 1. 保存临时文件
|
||||
String originalFilename = file.getOriginalFilename();
|
||||
String tempFileName = batchId + "_" + System.currentTimeMillis() + "_" + originalFilename;
|
||||
String tempFileName = batchId + "_" + i + "_" + System.currentTimeMillis() + "_" + originalFilename;
|
||||
Path tempFilePath = tempDir.resolve(tempFileName);
|
||||
|
||||
// 将MultipartFile内容复制到临时文件
|
||||
Files.copy(file.getInputStream(), tempFilePath, StandardCopyOption.REPLACE_EXISTING);
|
||||
tempFilePaths.add(tempFilePath.toString());
|
||||
|
||||
log.debug("【文件上传】保存临时文件: originalName={}, tempPath={}",
|
||||
originalFilename, tempFilePath);
|
||||
log.debug("【文件上传】保存临时文件[{}]: originalName={}, tempPath={}",
|
||||
i, originalFilename, tempFilePath);
|
||||
|
||||
// 2. 创建记录(使用相同的索引i)
|
||||
CcdiFileUploadRecord record = new CcdiFileUploadRecord();
|
||||
record.setProjectId(projectId);
|
||||
record.setLsfxProjectId(lsfxProjectId);
|
||||
record.setFileName(originalFilename);
|
||||
record.setFileSize(file.getSize());
|
||||
record.setFileStatus("uploading");
|
||||
record.setUploadTime(now);
|
||||
record.setUploadUser(username);
|
||||
records.add(record);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
log.error("【文件上传】保存临时文件失败", e);
|
||||
throw new RuntimeException("保存临时文件失败: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
// 3. 批量插入文件记录(status=uploading)
|
||||
List<CcdiFileUploadRecord> records = new ArrayList<>();
|
||||
Date now = new Date();
|
||||
|
||||
for (int i = 0; i < files.length; i++) {
|
||||
MultipartFile file = files[i];
|
||||
CcdiFileUploadRecord record = new CcdiFileUploadRecord();
|
||||
record.setProjectId(projectId);
|
||||
record.setLsfxProjectId(lsfxProjectId);
|
||||
record.setFileName(file.getOriginalFilename());
|
||||
record.setFileSize(file.getSize());
|
||||
record.setFileStatus("uploading");
|
||||
record.setUploadTime(now);
|
||||
record.setUploadUser(username);
|
||||
records.add(record);
|
||||
// 验证数量一致性
|
||||
if (tempFilePaths.size() != records.size()) {
|
||||
throw new RuntimeException(String.format(
|
||||
"临时文件数量(%d)与记录数量(%d)不一致", tempFilePaths.size(), records.size()));
|
||||
}
|
||||
|
||||
recordMapper.insertBatch(records);
|
||||
|
||||
Reference in New Issue
Block a user