Commit 95a0457f authored by huyuchen's avatar huyuchen

huych-电子档案批量导入第🈚次提交

parent 6a8a1676
...@@ -523,11 +523,6 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo ...@@ -523,11 +523,6 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
.collect(Collectors.toList()); .collect(Collectors.toList());
List<TElectronicArchiveDetail> details = detailService.listByIds(detailIds); List<TElectronicArchiveDetail> details = detailService.listByIds(detailIds);
Map<String, TElectronicArchiveDetail> detailMap = details.stream()
.collect(Collectors.toMap(
d -> d.getEmpIdcard() + "_" + d.getEmpName(),
d -> d
));
// 创建临时目录用于解压ZIP文件 // 创建临时目录用于解压ZIP文件
String tempDirPath = System.getProperty("java.io.tmpdir") + File.separator + "archive_file" + File.separator String tempDirPath = System.getProperty("java.io.tmpdir") + File.separator + "archive_file" + File.separator
...@@ -561,25 +556,102 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo ...@@ -561,25 +556,102 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
return R.failed("解压ZIP文件失败:" + e.getMessage() + ",请检查ZIP文件是否完整且格式正确"); return R.failed("解压ZIP文件失败:" + e.getMessage() + ",请检查ZIP文件是否完整且格式正确");
} }
// 获取ZIP包的根目录(第一级目录,身份证+姓名目录) // 获取ZIP包的根目录(第一级目录,身份证+姓名目录)
File[] zipRootDirs = tempDir.listFiles(File::isDirectory); File[] zipRootDirs = tempDir.listFiles(File::isDirectory);
if (zipRootDirs == null || zipRootDirs.length == 0) { Map<String, File> zipDirMap = new HashMap<>();
updateTaskStatus(task, ArchiveConstants.TASK_STATUS_NOT_UPLOADED); if (zipRootDirs != null && zipRootDirs.length > 0) {
return R.failed("ZIP文件格式不正确"); // 将ZIP中的目录按照 身份证_姓名 建立映射
for (File personDir : zipRootDirs) {
String dirName = personDir.getName();
Map<String, String> idNameMap = parseIdCardAndName(dirName);
if (!idNameMap.isEmpty() && idNameMap.containsKey("idCard") && idNameMap.containsKey("name")) {
String uniqueKey = idNameMap.get("idCard") + "_" + idNameMap.get("name");
zipDirMap.put(uniqueKey, personDir);
}
} }
}
// 遍历每个人员目录,递归处理所有附件 // 按照第一步Excel导入的明细列表生成反馈表
for (File personDir : zipRootDirs) { // 用于记录每个人员的处理结果(一个人可能有多个资料类型)
processPersonDirectory(personDir, detailMap, feedbackList, taskId); Map<String, List<String>> personMaterialTypesMap = new HashMap<>();
Map<String, String> personProcessResultMap = new HashMap<>();
Map<String, String> personFailReasonMap = new HashMap<>();
// 遍历第一步导入的所有明细
for (TElectronicArchiveDetail detail : details) {
String uniqueKey = detail.getEmpIdcard() + "_" + detail.getEmpName();
// 检查ZIP中是否存在该人员的目录
File personDir = zipDirMap.get(uniqueKey);
if (personDir == null) {
// ZIP中没有该人员的文件夹,记录为跳过
personProcessResultMap.put(uniqueKey, ArchiveConstants.PROCESS_RESULT_SKIP);
personFailReasonMap.put(uniqueKey, "压缩包中未找到对应文件夹,跳过处理");
personMaterialTypesMap.put(uniqueKey, new ArrayList<>());
} else {
// ZIP中存在该人员的文件夹,处理其附件
List<String> materialTypes = new ArrayList<>();
List<String> failReasons = new ArrayList<>();
processPersonDirectoryWithResult(personDir, detail, materialTypes, failReasons, taskId);
personMaterialTypesMap.put(uniqueKey, materialTypes);
// 判断处理结果
if (materialTypes.isEmpty()) {
// 没有成功上传任何资料类型,记录为失败
personProcessResultMap.put(uniqueKey, ArchiveConstants.PROCESS_RESULT_FAILED);
if (failReasons.isEmpty()) {
personFailReasonMap.put(uniqueKey, "文件夹为空或格式不符");
} else {
personFailReasonMap.put(uniqueKey, String.join(";", failReasons));
}
} else {
// 有成功上传的资料类型
if (failReasons.isEmpty()) {
personProcessResultMap.put(uniqueKey, ArchiveConstants.PROCESS_RESULT_SUCCESS);
personFailReasonMap.put(uniqueKey, "");
} else {
// 部分成功,部分失败
personProcessResultMap.put(uniqueKey, ArchiveConstants.PROCESS_RESULT_FAILED);
personFailReasonMap.put(uniqueKey, String.join(";", failReasons));
}
}
} }
}
// 处理完成,更新任务状态 // 按照第一步Excel的顺序生成反馈表
task.setStatus(ArchiveConstants.TASK_STATUS_GENERATED); for (TElectronicArchiveDetail detail : details) {
taskService.updateById(task); String uniqueKey = detail.getEmpIdcard() + "_" + detail.getEmpName();
ArchiveFeedbackVO feedback = new ArchiveFeedbackVO();
feedback.setEmpName(detail.getEmpName());
feedback.setEmpIdcard(detail.getEmpIdcard());
feedback.setDeptNo(detail.getDeptNo());
feedback.setDeptName(detail.getDeptName());
// 设置资料类型(多个用逗号拼接)
List<String> materialTypes = personMaterialTypesMap.get(uniqueKey);
if (materialTypes != null && !materialTypes.isEmpty()) {
feedback.setMaterialType(String.join(",", materialTypes));
} else {
feedback.setMaterialType("");
}
feedback.setProcessResult(personProcessResultMap.get(uniqueKey));
feedback.setFailReason(personFailReasonMap.get(uniqueKey));
feedbackList.add(feedback);
}
// 处理完成,更新任务状态
task.setStatus(ArchiveConstants.TASK_STATUS_GENERATED);
taskService.updateById(task);
// 生成反馈表 // 生成反馈表
generateFeedbackExcel(task, feedbackList); generateFeedbackExcel(task, feedbackList);
return R.ok("处理完成"); return R.ok("处理完成");
} catch (Exception e) { } catch (Exception e) {
log.error("异步处理任务失败,任务ID:{}", taskId, e); log.error("异步处理任务失败,任务ID:{}", taskId, e);
...@@ -656,7 +728,7 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo ...@@ -656,7 +728,7 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
} }
/** /**
* 处理单个人员目录 * 处理单个人员目录(旧方法,保留向后兼容)
*/ */
private void processPersonDirectory(File personDir, Map<String, TElectronicArchiveDetail> detailMap, private void processPersonDirectory(File personDir, Map<String, TElectronicArchiveDetail> detailMap,
List<ArchiveFeedbackVO> feedbackList, String taskId) { List<ArchiveFeedbackVO> feedbackList, String taskId) {
...@@ -742,6 +814,76 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo ...@@ -742,6 +814,76 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
} }
} }
/**
* 处理单个人员目录(返回处理结果,用于按Excel顺序生成反馈表)
*
* @param personDir 人员目录
* @param detail 电子档案明细
* @param materialTypes 成功处理的资料类型列表(输出参数)
* @param failReasons 失败原因列表(输出参数)
* @param taskId 任务ID
*/
private void processPersonDirectoryWithResult(File personDir, TElectronicArchiveDetail detail,
List<String> materialTypes, List<String> failReasons, String taskId) {
// 处理第三级目录(资料类型或直接是文件)
File[] subFiles = personDir.listFiles();
if (subFiles == null || subFiles.length == 0) {
// 文件夹为空
failReasons.add("文件夹为空");
return;
}
// 用于记录该人员的所有资料类型
Set<String> materialTypesSet = new HashSet<>();
// 遍历第三级,按资料类型分组处理所有文件
for (File subFile : subFiles) {
if (subFile.isDirectory()) {
// 是资料类型目录
String materialType = subFile.getName();
//存量、新签、续签、减员
if (materialType.contains("存量")) {
materialType = "存量";
} else if (materialType.contains("新签")) {
materialType = "新签";
} else if (materialType.contains("续签")) {
materialType = "续签";
} else if (materialType.contains("减员")) {
materialType = "减员";
}
if (isValidMaterialType(materialType)) {
// 不是有效的资料类型,跳过
continue;
}
// 按资料类型分组处理目录下的所有文件
String result = processMaterialTypeDirectoryWithResult(subFile, detail, materialType, taskId);
if ("success".equals(result)) {
materialTypesSet.add(materialType);
} else {
failReasons.add(materialType + ":" + result);
}
} else {
// 直接是文件,默认为存量类型,按单个文件处理
List<File> singleFileList = new ArrayList<>();
singleFileList.add(subFile);
String result = processMaterialTypeFilesWithResult(singleFileList, detail, ArchiveConstants.MATERIAL_TYPE_STOCK, taskId);
if ("success".equals(result)) {
materialTypesSet.add(ArchiveConstants.MATERIAL_TYPE_STOCK);
} else {
failReasons.add(ArchiveConstants.MATERIAL_TYPE_STOCK + ":" + result);
}
}
}
// 更新明细表的资料类型和状态
if (!materialTypesSet.isEmpty()) {
materialTypes.addAll(materialTypesSet);
updateDetailMaterialType(detail, materialTypesSet);
}
}
/** /**
* 按资料类型处理目录下的所有文件 * 按资料类型处理目录下的所有文件
* 同一资料类型下的所有文件作为一个整体处理:先验证所有文件,全部通过后才统一上传 * 同一资料类型下的所有文件作为一个整体处理:先验证所有文件,全部通过后才统一上传
...@@ -764,6 +906,29 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo ...@@ -764,6 +906,29 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
// 统一处理该资料类型下的所有文件 // 统一处理该资料类型下的所有文件
processMaterialTypeFiles(allFiles, detail, materialType, feedbackList, materialTypes, taskId); processMaterialTypeFiles(allFiles, detail, materialType, feedbackList, materialTypes, taskId);
} }
/**
* 按资料类型处理目录下的所有文件(返回处理结果)
*
* @param directory 资料类型目录
* @param detail 电子档案明细
* @param materialType 资料类型
* @param taskId 任务ID
* @return "success" 表示成功,其他表示失败原因
*/
private String processMaterialTypeDirectoryWithResult(File directory, TElectronicArchiveDetail detail,
String materialType, String taskId) {
// 收集该资料类型目录下的所有文件(递归收集子目录中的文件)
List<File> allFiles = new ArrayList<>();
collectAllFiles(directory, allFiles);
if (allFiles.isEmpty()) {
return "文件夹为空";
}
// 统一处理该资料类型下的所有文件
return processMaterialTypeFilesWithResult(allFiles, detail, materialType, taskId);
}
/** /**
* 递归收集目录下的所有文件 * 递归收集目录下的所有文件
...@@ -858,6 +1023,66 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo ...@@ -858,6 +1023,66 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
} }
} }
/**
* 统一处理同一资料类型下的所有文件(返回处理结果)
*
* @param files 文件列表
* @param detail 电子档案明细
* @param materialType 资料类型
* @param taskId 任务ID
* @return "success" 表示成功,其他表示失败原因
*/
private String processMaterialTypeFilesWithResult(List<File> files, TElectronicArchiveDetail detail,
String materialType, String taskId) {
// 第一步:验证所有文件格式
for (File file : files) {
String fileName = file.getName();
if (checkFileFormat(fileName)) {
// 有文件格式不符,整体失败
return "文件格式不符,文件格式需为png\\jpg\\jpeg\\xlsx\\xls\\doc\\docx\\pdf\\ppt\\pptx\\txt:" + fileName;
}
}
// 第二步:所有文件格式验证通过,统一上传到阿里云
try {
// 构建OSS目录路径
String ossDirectory = buildOssDirectory(detail, materialType);
// 依次上传每个文件
for (File file : files) {
String fileName = file.getName();
// 转换为MultipartFile
MultipartFile multipartFile = fileToMultipartFile(file);
if (multipartFile == null) {
// 文件转换失败,整体失败
return "文件转换失败:" + fileName;
}
// 上传文件到阿里云OSS,uploadFileReturnAtta会自动生成TAttaInfo记录
R<TAttaInfo> uploadResult = fileUploadService.uploadFileReturnAtta(
multipartFile,
ossDirectory,
CommonConstants.FOUR_STRING,
detail.getId(),
taskId
);
if (!R.isSuccess(uploadResult)) {
// 上传失败,整体失败
return "文件上传失败:" + fileName + ",原因:" + (uploadResult != null ? uploadResult.getMsg() : "未知错误");
}
}
// 第三步:所有文件上传成功
return "success";
} catch (Exception e) {
log.error("上传文件失败,资料类型:{},电子档案详情ID:{},任务ID:{}", materialType, detail.getId(), taskId, e);
return "文件上传异常,原因:" + e.getMessage();
}
}
/** /**
* 构建OSS目录路径 * 构建OSS目录路径
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment