Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
Y
yifu-mvp
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
fangxinjiang
yifu-mvp
Commits
95a0457f
You need to sign in or sign up before continuing.
Commit
95a0457f
authored
Jan 06, 2026
by
huyuchen
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
huych-电子档案批量导入第
🈚
次提交
parent
6a8a1676
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
245 additions
and
20 deletions
+245
-20
ElectronicArchiveImportServiceImpl.java
...atch/service/impl/ElectronicArchiveImportServiceImpl.java
+245
-20
No files found.
yifu-batch/yifu-batch-biz/src/main/java/com/yifu/cloud/plus/v1/batch/service/impl/ElectronicArchiveImportServiceImpl.java
View file @
95a0457f
...
@@ -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目录路径
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment