Commit 8db181df authored by huyuchen's avatar huyuchen

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

parent 8a04736a
......@@ -84,9 +84,9 @@ public interface ArchiveConstants {
String MATERIAL_TYPE_RENEW = "续签";
/**
* 资料类型-离职
* 资料类型-减员
*/
String MATERIAL_TYPE_LEAVE = "离职";
String MATERIAL_TYPE_LEAVE = "减员";
/**
* 处理结果-成功
......
......@@ -48,10 +48,10 @@ public class SingleArchiveUploadDTO {
private String deptName;
/**
* 资料类型(存量、新签、续签、离职
* 资料类型(存量、新签、续签、减员
*/
@NotBlank(message = "资料类型不能为空")
@Schema(description = "资料类型(存量、新签、续签、离职)")
@Schema(description = "资料类型(存量、新签、续签、减员)")
private String materialType;
}
......@@ -84,11 +84,11 @@ public class TElectronicArchiveDetail extends BaseEntity {
private String customerCode;
/**
* 资料类型(存量、新签、续签、离职,多个用逗号分隔)
* 资料类型(存量、新签、续签、减员,多个用逗号分隔)
*/
@ExcelAttribute(name = "资料类型")
@ExcelProperty("资料类型")
@Schema(description = "资料类型 存量、新签、续签、离职,多个用逗号分隔)")
@Schema(description = "资料类型 存量、新签、续签、减员,多个用逗号分隔)")
private String materialType;
/**
......@@ -99,6 +99,14 @@ public class TElectronicArchiveDetail extends BaseEntity {
@Schema(description = "档案所在地-省")
private Integer fileProvince;
/**
* 档案所在地
*/
@ExcelAttribute(name = "档案所在地")
@ExcelProperty("档案所在地")
@Schema(description = "档案所在地")
private String fileAddress;
/**
* 档案所在地-市
*/
......
......@@ -32,10 +32,10 @@ public class ArchiveAttachmentDeleteRequestVO {
private String taskId;
/**
* 资料类型(存量、新签、续签、离职
* 资料类型(存量、新签、续签、减员
*/
@NotBlank(message = "资料类型不能为空")
@Schema(description = "资料类型(存量、新签、续签、离职)")
@Schema(description = "资料类型(存量、新签、续签、减员)")
private String materialType;
/**
......
......@@ -32,42 +32,62 @@ public class ArchiveDownloadFeedbackVO implements Serializable {
/**
* 身份证号码
*/
@ExcelProperty(value = "身份证号", index = 1)
@Schema(description = "身份证号")
@ExcelProperty(value = "身份证号", index = 1)
@Schema(description = "身份证号")
private String empIdcard;
/**
* 项目编码
*/
@ExcelProperty(value = "项目编码", index = 2)
@Schema(description = "项目编码")
private String deptNo;
/**
* 项目名称
*/
@ExcelProperty(value = "项目名称", index = 3)
@Schema(description = "项目名称")
private String deptName;
/**
* 客户名称
*/
@ExcelProperty(value = "客户名称", index = 4)
@Schema(description = "客户名称")
private String customerName;
/**
* 资料类型
*/
@ExcelProperty(value = "资料类型", index = 4)
@ExcelProperty(value = "资料类型", index = 5)
@Schema(description = "资料类型")
private String materialType;
/**
* 资料类型
*/
@ExcelProperty(value = "档案所在地", index = 6)
@Schema(description = "档案所在地")
private String fileAddress;
/**
* 项目编码
*/
@ExcelProperty(value = "项目编码", index = 7)
@Schema(description = "项目编码")
private String deptNo;
/**
* 客户编码
*/
@ExcelProperty(value = "客户编码", index = 8)
@Schema(description = "客户编码")
private String customerCode;
/**
* 下载状态(成功/失败)
*/
@ExcelProperty(value = "下载状态", index = 5)
@ExcelProperty(value = "下载状态", index = 9)
@Schema(description = "下载状态")
private String downloadStatus;
/**
* 失败原因
*/
@ExcelProperty(value = "失败原因", index = 6)
@ExcelProperty(value = "失败原因", index = 10)
@Schema(description = "失败原因")
private String failReason;
}
......
......@@ -56,7 +56,7 @@ public class ArchiveFeedbackVO implements Serializable {
*/
@ExcelAttribute(name = "资料类型")
@ExcelProperty(value = "资料类型", index = 4)
@Schema(description = "资料类型(存量、新签、续签、离职)")
@Schema(description = "资料类型(存量、新签、续签、减员)")
private String materialType;
/**
......
......@@ -39,7 +39,7 @@ public class ArchiveSelectedExportRequestVO implements Serializable {
* 资料类型列表(要导出的资料类型)
*/
@NotEmpty(message = "资料类型列表不能为空")
@Schema(description = "资料类型列表(存量、新签、续签、离职)")
@Schema(description = "资料类型列表(存量、新签、续签、减员)")
private List<String> materialTypes;
}
......@@ -49,10 +49,10 @@ public class SingleArchiveUploadVO implements Serializable {
private String deptName;
/**
* 资料类型(存量、新签、续签、离职
* 资料类型(存量、新签、续签、减员
*/
@NotBlank(message = "资料类型不能为空")
@Schema(description = "资料类型(存量、新签、续签、离职)")
@Schema(description = "资料类型(存量、新签、续签、减员)")
private String materialType;
/**
......
......@@ -59,10 +59,10 @@ public class TElectronicArchiveDetailVo extends RowIndex implements Serializable
@ExcelProperty("客户编码")
private String customerCode;
/**
* 资料类型(存量、新签、续签、离职,多个用逗号分隔)
* 资料类型(存量、新签、续签、减员,多个用逗号分隔)
*/
@ExcelAttribute(name = "资料类型")
@Schema(description = "资料类型(存量、新签、续签、离职,多个用逗号分隔)")
@Schema(description = "资料类型(存量、新签、续签、减员,多个用逗号分隔)")
@ExcelProperty("资料类型")
private String materialType;
/**
......
......@@ -45,7 +45,7 @@ public class TaskAttachmentGroupVO {
/**
* 资料类型及对应的附件列表
* key: 资料类型(存量、新签、续签、离职
* key: 资料类型(存量、新签、续签、减员
* value: 该资料类型下的附件列表
*/
@Schema(description = "资料类型及对应的附件列表")
......
......@@ -117,7 +117,7 @@ public class FileUploadController {
* @Date 2019-08-16
* @param id domainId
**/
@Operation(description = "附件预览下载地址 资源类型 0 存量 1 新签 2续签 3离职")
@Operation(description = "附件预览下载地址 资源类型 0 存量 1 新签 2续签 3减员")
@GetMapping("/ossFileUrl/{id}")
public R<List<TAttaInfo>> ossFileUrl(@PathVariable String id) {
List<TAttaInfo> attas = tAttaInfoService.list(Wrappers.<TAttaInfo>query().lambda().eq(TAttaInfo::getDomainId,id));
......
......@@ -705,31 +705,33 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
// 用于记录该人员的所有资料类型
Set<String> materialTypes = new HashSet<>();
// 遍历第三级,递归处理所有文件
// 遍历第三级,按资料类型分组处理所有文件
for (File subFile : subFiles) {
if (subFile.isDirectory()) {
// 是资料类型目录
String materialType = subFile.getName();
//存量、新签、续签、离职
if(materialType.contains("存量")) {
//存量、新签、续签、减员
if (materialType.contains("存量")) {
materialType = "存量";
} else if(materialType.contains("新签")) {
} else if (materialType.contains("新签")) {
materialType = "新签";
} else if(materialType.contains("续签")) {
} else if (materialType.contains("续签")) {
materialType = "续签";
} else if(materialType.contains("离职")) {
materialType = "离职";
} else if (materialType.contains("减员")) {
materialType = "减员";
}
if (!isValidMaterialType(materialType)) {
if (isValidMaterialType(materialType)) {
// 不是有效的资料类型,跳过
continue;
}
// 递归处理资料类型目录下的所有文件(包括子目录)
processDirectoryRecursively(subFile, detail, materialType, feedbackList, materialTypes, taskId);
// 按资料类型分组处理目录下的所有文件
processMaterialTypeDirectory(subFile, detail, materialType, feedbackList, materialTypes, taskId);
} else {
// 直接是文件,默认为存量类型
processFile(subFile, detail, ArchiveConstants.MATERIAL_TYPE_STOCK, feedbackList, materialTypes, taskId);
// 直接是文件,默认为存量类型,按单个文件处理
List<File> singleFileList = new ArrayList<>();
singleFileList.add(subFile);
processMaterialTypeFiles(singleFileList, detail, ArchiveConstants.MATERIAL_TYPE_STOCK, feedbackList, materialTypes, taskId);
}
}
......@@ -740,96 +742,122 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
}
/**
* 递归处理目录下的所有文件(包括子目录)
* 按资料类型处理目录下的所有文件
* 同一资料类型下的所有文件作为一个整体处理:先验证所有文件,全部通过后才统一上传
*/
private void processDirectoryRecursively(File directory, TElectronicArchiveDetail detail,
String materialType, List<ArchiveFeedbackVO> feedbackList,
Set<String> materialTypes, String taskId) {
File[] files = directory.listFiles();
if (files == null || files.length == 0) {
private void processMaterialTypeDirectory(File directory, TElectronicArchiveDetail detail,
String materialType, List<ArchiveFeedbackVO> feedbackList,
Set<String> materialTypes, String taskId) {
// 收集该资料类型目录下的所有文件(递归收集子目录中的文件)
List<File> allFiles = new ArrayList<>();
collectAllFiles(directory, allFiles);
if (allFiles.isEmpty()) {
// 文件夹为空
ArchiveFeedbackVO feedback = createFeedbackVO(detail, materialType,
ArchiveConstants.PROCESS_RESULT_FAILED, "文件夹为空");
feedbackList.add(feedback);
return;
}
// 递归处理该目录下的所有文件和子目录
// 统一处理该资料类型下的所有文件
processMaterialTypeFiles(allFiles, detail, materialType, feedbackList, materialTypes, taskId);
}
/**
* 递归收集目录下的所有文件
*/
private void collectAllFiles(File directory, List<File> fileList) {
File[] files = directory.listFiles();
if (files == null || files.length == 0) {
return;
}
for (File file : files) {
if (file.isDirectory()) {
// 如果是子目录,递归处理
processDirectoryRecursively(file, detail, materialType, feedbackList, materialTypes, taskId);
// 递归收集子目录中的文件
collectAllFiles(file, fileList);
} else if (file.isFile()) {
// 如果是文件,上传到阿里云并生成TAttaInfo记录
processFile(file, detail, materialType, feedbackList, materialTypes, taskId);
fileList.add(file);
}
}
}
/**
* 处理单个文件(上传到阿里云OSS,每个文件生成一条TAttaInfo记录)
* 统一处理同一资料类型下的所有文件
* 1. 先验证所有文件格式,如果有一个失败则整体失败
* 2. 全部验证通过后,统一上传到阿里云
* 3. 只生成一条反馈记录
*/
private void processFile(File file, TElectronicArchiveDetail detail, String materialType,
List<ArchiveFeedbackVO> feedbackList, Set<String> materialTypes, String taskId) {
String fileName = file.getName();
// 2. 校验文件格式
if (!checkFileFormat(fileName)) {
ArchiveFeedbackVO feedback = createFeedbackVO(detail, materialType,
ArchiveConstants.PROCESS_RESULT_FAILED, "文件格式不符,文件格式需为png\\jpg\\jpeg\\xlsx\\xls\\doc\\docx\\pdf\\ppt\\pptx\\txt:" + fileName);
feedbackList.add(feedback);
return;
}
// 3. 上传文件到阿里云OSS
try {
// 构建OSS目录路径
String ossDirectory = buildOssDirectory(detail, materialType);
// 转换为MultipartFile
MultipartFile multipartFile = fileToMultipartFile(file);
if (multipartFile == null) {
ArchiveFeedbackVO feedback = createFeedbackVO(detail, materialType,
ArchiveConstants.PROCESS_RESULT_FAILED, "文件转换失败:" + fileName);
feedbackList.add(feedback);
return;
}
// 上传文件,uploadFileReturnAtta会自动生成TAttaInfo记录
// domainId为电子档案详情表的id(detail.getId())
// taskId为任务表的id,用于区分同一个domainId下不同任务的附件
R<TAttaInfo> uploadResult = fileUploadService.uploadFileReturnAtta(
multipartFile,
ossDirectory,
CommonConstants.FOUR_STRING,
detail.getId(),
taskId
);
if (!R.isSuccess(uploadResult)) {
private void processMaterialTypeFiles(List<File> files, TElectronicArchiveDetail detail,
String materialType, List<ArchiveFeedbackVO> feedbackList,
Set<String> materialTypes, String taskId) {
// 第一步:验证所有文件格式
for (File file : files) {
String fileName = file.getName();
if (checkFileFormat(fileName)) {
// 有文件格式不符,整体失败,不再处理后续文件
ArchiveFeedbackVO feedback = createFeedbackVO(detail, materialType,
ArchiveConstants.PROCESS_RESULT_FAILED,
"文件上传失败:" + fileName + ",原因:" + (uploadResult != null ? uploadResult.getMsg() : "未知错误"));
"文件格式不符,文件格式需为png\\jpg\\jpeg\\xlsx\\xls\\doc\\docx\\pdf\\ppt\\pptx\\txt:" + fileName);
feedbackList.add(feedback);
return;
}
// 记录该人员的资料类型
materialTypes.add(materialType);
}
// 第二步:所有文件格式验证通过,统一上传到阿里云
try {
// 构建OSS目录路径
String ossDirectory = buildOssDirectory(detail, materialType);
// 依次上传每个文件
for (File file : files) {
String fileName = file.getName();
// 转换为MultipartFile
MultipartFile multipartFile = fileToMultipartFile(file);
if (multipartFile == null) {
// 文件转换失败,整体失败
ArchiveFeedbackVO feedback = createFeedbackVO(detail, materialType,
ArchiveConstants.PROCESS_RESULT_FAILED, "文件转换失败:" + fileName);
feedbackList.add(feedback);
return;
}
// 上传文件到阿里云OSS,uploadFileReturnAtta会自动生成TAttaInfo记录
R<TAttaInfo> uploadResult = fileUploadService.uploadFileReturnAtta(
multipartFile,
ossDirectory,
CommonConstants.FOUR_STRING,
detail.getId(),
taskId
);
if (!R.isSuccess(uploadResult)) {
// 上传失败,整体失败
ArchiveFeedbackVO feedback = createFeedbackVO(detail, materialType,
ArchiveConstants.PROCESS_RESULT_FAILED,
"文件上传失败:" + fileName + ",原因:" + (uploadResult != null ? uploadResult.getMsg() : "未知错误"));
feedbackList.add(feedback);
return;
}
}
// 生成成功反馈
// 第三步:所有文件上传成功,记录资料类型并生成成功反馈
materialTypes.add(materialType);
ArchiveFeedbackVO feedback = createFeedbackVO(detail, materialType,
ArchiveConstants.PROCESS_RESULT_SUCCESS, "");
feedbackList.add(feedback);
} catch (Exception e) {
log.error("上传文件失败:{},电子档案详情ID:{},任务ID:{}", fileName, detail.getId(), taskId, e);
log.error("上传文件失败,资料类型:{},电子档案详情ID:{},任务ID:{}", materialType, detail.getId(), taskId, e);
ArchiveFeedbackVO feedback = createFeedbackVO(detail, materialType,
ArchiveConstants.PROCESS_RESULT_FAILED, "文件上传异常:" + fileName + ",原因:" + e.getMessage());
ArchiveConstants.PROCESS_RESULT_FAILED, "文件上传异常,原因:" + e.getMessage());
feedbackList.add(feedback);
}
}
/**
* 构建OSS目录路径
*/
......@@ -859,10 +887,10 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
* 判断是否是有效的资料类型
*/
private boolean isValidMaterialType(String typeName) {
return ArchiveConstants.MATERIAL_TYPE_STOCK.equals(typeName) ||
ArchiveConstants.MATERIAL_TYPE_NEW.equals(typeName) ||
ArchiveConstants.MATERIAL_TYPE_RENEW.equals(typeName) ||
ArchiveConstants.MATERIAL_TYPE_LEAVE.equals(typeName);
return !ArchiveConstants.MATERIAL_TYPE_STOCK.equals(typeName) &&
!ArchiveConstants.MATERIAL_TYPE_NEW.equals(typeName) &&
!ArchiveConstants.MATERIAL_TYPE_RENEW.equals(typeName) &&
!ArchiveConstants.MATERIAL_TYPE_LEAVE.equals(typeName);
}
/**
......@@ -969,8 +997,13 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
Map<String, String> result = new HashMap<>();
// 尝试用-分隔
if (folderName.contains("-")) {
String[] parts = folderName.split("-");
if (folderName.contains("-") || folderName.contains("—")) {
String[] parts;
if (folderName.contains("-")) {
parts = folderName.split("-");
}else {
parts = folderName.split("—");
}
if (parts.length == 2) {
// 判断哪个是身份证号(18位数字)
if (parts[0].matches("\\d{18}")) {
......@@ -1009,16 +1042,16 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
*/
private boolean checkFileFormat(String fileName) {
if (StrUtil.isBlank(fileName)) {
return false;
return true;
}
String ext = FileUtil.extName(fileName).toLowerCase();
for (String format : ArchiveConstants.SUPPORTED_FILE_FORMATS) {
if (format.equalsIgnoreCase(ext)) {
return true;
return false;
}
}
return false;
return true;
}
/**
......@@ -1044,8 +1077,8 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
}
// 校验资料类型是否有效
if (!isValidMaterialType(materialType)) {
return R.failed("资料类型不正确,必须为:存量、新签、续签、离职");
if (isValidMaterialType(materialType)) {
return R.failed("资料类型不正确,必须为:存量、新签、续签、减员");
}
// 校验身份证格式
......@@ -1117,16 +1150,9 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
continue;
}
// // 校验文件大小
// if (file.getSize() > ArchiveConstants.SINGLE_FILE_MAX_SIZE) {
// failCount++;
// failReasons.append(file.getOriginalFilename()).append(":文件大小超过15M;");
// continue;
// }
// 校验文件格式
String fileName = file.getOriginalFilename();
if (!checkFileFormat(fileName)) {
if (checkFileFormat(fileName)) {
failCount++;
failReasons.append(fileName).append(":文件格式不符;");
continue;
......@@ -1195,8 +1221,8 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
}
// 校验资料类型是否有效
if (!isValidMaterialType(materialType)) {
return R.failed("资料类型不正确,必须为:存量、新签、续签、离职");
if (isValidMaterialType(materialType)) {
return R.failed("资料类型不正确,必须为:存量、新签、续签、减员");
}
// 校验身份证格式
......@@ -1255,12 +1281,6 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
detail.setFileTown(empInfo.getFileTown());
detailService.save(detail);
// 建立任务和档案详情的关联关系
TTaskArchiveRelation relation = new TTaskArchiveRelation();
relation.setTaskId(task.getId());
relation.setArchiveDetailId(detail.getId());
relationService.save(relation);
} else {
// 存在则更新资料类型(追加)
Set<String> existTypes = new HashSet<>();
......@@ -1272,6 +1292,12 @@ public class ElectronicArchiveImportServiceImpl implements ElectronicArchiveImpo
detailService.updateById(detail);
}
// 建立任务和档案详情的关联关系
TTaskArchiveRelation relation = new TTaskArchiveRelation();
relation.setTaskId(task.getId());
relation.setArchiveDetailId(detail.getId());
relationService.save(relation);
// 5. 更新附件的domainId
int successCount = 0;
int failCount = 0;
......
......@@ -617,7 +617,7 @@ public class TElectronicArchiveDetailServiceImpl extends ServiceImpl<TElectronic
// 2. 校验资料类型是否有效
if (isValidMaterialType(request.getMaterialType())) {
return R.failed("资料类型不正确,必须为:存量、新签、续签、离职");
return R.failed("资料类型不正确,必须为:存量、新签、续签、减员");
}
// 3. 查询要删除的附件
......
......@@ -23,6 +23,7 @@
<result property="createTime" column="CREATE_TIME"/>
<result property="updateBy" column="UPDATE_BY"/>
<result property="updateTime" column="UPDATE_TIME"/>
<result property="fileAddress" column="FILE_ADRESS"/>
</resultMap>
<sql id="Base_Column_List">
a.ID,
......@@ -42,7 +43,8 @@
a.CREATE_NAME,
a.CREATE_TIME,
a.UPDATE_BY,
a.UPDATE_TIME
a.UPDATE_TIME,
a.FILE_ADRESS
</sql>
<sql id="tElectronicArchiveDetail_where">
<if test="tElectronicArchiveDetail != null">
......
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