|
@@ -24,6 +24,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
|
|
|
|
|
|
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
|
|
+import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
import com.itextpdf.text.*;
|
|
@@ -35,6 +36,7 @@ import lombok.extern.slf4j.Slf4j;
|
|
|
import org.apache.commons.lang.StringUtils;
|
|
|
|
|
|
import org.springblade.archive.dto.ArchiveWarningDTO;
|
|
|
+import org.springblade.archive.dto.FindAndReplaceDto;
|
|
|
import org.springblade.archive.dto.JiLinQueryDto;
|
|
|
import org.springblade.archive.dto.SaveApplyDTO;
|
|
|
import org.springblade.archive.entity.*;
|
|
@@ -73,6 +75,9 @@ import org.springblade.system.entity.DictBiz;
|
|
|
import org.springblade.system.feign.IDictBizClient;
|
|
|
import org.springblade.system.user.entity.User;
|
|
|
import org.springframework.beans.factory.annotation.Autowired;
|
|
|
+import org.springframework.jdbc.core.BeanPropertyRowMapper;
|
|
|
+import org.springframework.jdbc.core.JdbcTemplate;
|
|
|
+import org.springframework.scheduling.annotation.Async;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
|
|
import org.springframework.transaction.annotation.Transactional;
|
|
@@ -135,6 +140,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
private final IArchiveExpertConclusionService expertConclusionService;
|
|
|
private final ITraceLogService iTraceLogService;
|
|
|
|
|
|
+ private final JdbcTemplate jdbcTemplate;
|
|
|
+
|
|
|
//表格高度
|
|
|
private static int high = 20;
|
|
|
//表格宽度
|
|
@@ -142,6 +149,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
|
|
|
private final CommonFileClient commonFileClient;
|
|
|
|
|
|
+ private final IArchiveNameService archiveNameService;
|
|
|
+
|
|
|
|
|
|
@Override
|
|
|
public IPage<ArchivesAutoVO> selectArchivesAutoPage(IPage<ArchivesAutoVO> page, ArchivesAutoVO archivesAuto) {
|
|
@@ -373,11 +382,147 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
if (StringUtils.isNotBlank(vo.getSecretLevel())) {
|
|
|
vo.setSecretLevelValue("1".equals(vo.getSecretLevel()) ? "机密" : ("2".equals(vo.getSecretLevel()) ? "绝密" : "秘密"));
|
|
|
}
|
|
|
- if (vo.getApprovalFileList() != null && vo.getApprovalFileList().size() > 0) {
|
|
|
- vo.setPageNumber(vo.getApprovalFileList().size());
|
|
|
+ List<ArchivesAutoVO.ApprovalFile> approvalFiles = vo.getApprovalFileList();
|
|
|
+ ArchivesAutoVO.ApprovalFile front = null;
|
|
|
+ ArchivesAutoVO.ApprovalFile cataLog = null;
|
|
|
+ ArchivesAutoVO.ApprovalFile spare = null;
|
|
|
+ ArchivesAutoVO.ApprovalFile back = null;
|
|
|
+ if (approvalFiles != null && !approvalFiles.isEmpty()) {
|
|
|
+ // todo 四要素 使用名称判断
|
|
|
+ Map<String, List<ArchivesAutoVO.ApprovalFile>> collect = approvalFiles.stream().collect(Collectors.groupingBy(approvalFile -> {
|
|
|
+ if (approvalFile != null &&
|
|
|
+ (approvalFile.getFileName().equals("封面") || approvalFile.getFileName().equals("卷内目录") || approvalFile.getFileName().equals("卷内备考表") || approvalFile.getFileName().equals("备考表") || approvalFile.getFileName().equals("背脊"))) {
|
|
|
+ if (approvalFile.getFileName().equals("卷内备考表")) {
|
|
|
+ return "备考表";
|
|
|
+ }
|
|
|
+ return approvalFile.getFileName();
|
|
|
+ }
|
|
|
+ return "0";
|
|
|
+ }, Collectors.toList()));
|
|
|
+ List<ArchivesAutoVO.ApprovalFile> approvalFiles1 = collect.get("0");
|
|
|
+ if (approvalFiles1 == null) {
|
|
|
+ approvalFiles1 = new ArrayList<>();
|
|
|
+ }
|
|
|
+ vo.setPageNumber(approvalFiles1.size());
|
|
|
+ vo.setApprovalFileList(approvalFiles1);
|
|
|
+ if (collect.containsKey("封面")) {
|
|
|
+ front = collect.get("封面").stream().max(Comparator.comparing(ArchivesAutoVO.ApprovalFile::getId)).orElse(null);
|
|
|
+ }
|
|
|
+ if (collect.containsKey("卷内目录")) {
|
|
|
+ cataLog = collect.get("卷内目录").stream().max(Comparator.comparing(ArchivesAutoVO.ApprovalFile::getId)).orElse(null);
|
|
|
+ }
|
|
|
+ if (collect.containsKey("备考表")) {
|
|
|
+ spare = collect.get("备考表").stream().max(Comparator.comparing(ArchivesAutoVO.ApprovalFile::getId)).orElse(null);
|
|
|
+ }
|
|
|
+ if (collect.containsKey("背脊")) {
|
|
|
+ back = collect.get("背脊").stream().max(Comparator.comparing(ArchivesAutoVO.ApprovalFile::getId)).orElse(null);
|
|
|
+ }
|
|
|
} else {
|
|
|
vo.setPageNumber(0);
|
|
|
}
|
|
|
+ String outUrl = vo.getOutUrl();
|
|
|
+ if (StringUtils.isNotBlank(outUrl)) {
|
|
|
+ // 根据 factorType 字符串生成档案号码字符串链表
|
|
|
+ ArchiveProjectConfig config = archiveProjectConfigService.getByProjectIdOrNew(vo.getProjectId());
|
|
|
+ String[] frontUrls = outUrl.split(",");
|
|
|
+ for (String frontUrl : frontUrls) {
|
|
|
+ // 封面(原r_Archives_front)增加中文"封面"匹配
|
|
|
+ if (front == null && (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[0])
|
|
|
+ || frontUrl.contains("封面"))
|
|
|
+ && config.getFactorType().contains("1")) {
|
|
|
+ front = new ArchivesAutoVO.ApprovalFile();
|
|
|
+ front.setFileName("封面");
|
|
|
+ if(frontUrl.contains("@@@")){
|
|
|
+ front.setFileUrl(frontUrl.substring(0,frontUrl.indexOf("@@@")));
|
|
|
+ }else {
|
|
|
+ front.setFileUrl(frontUrl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 卷内目录(原r_Archives_catalog)增加中文匹配
|
|
|
+ else if (cataLog == null && (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[1])
|
|
|
+ || frontUrl.contains("卷内目录"))
|
|
|
+ && config.getFactorType().contains("2")) {
|
|
|
+ cataLog = new ArchivesAutoVO.ApprovalFile();
|
|
|
+ cataLog.setFileName("卷内目录");
|
|
|
+ if(frontUrl.contains("@@@")){
|
|
|
+ cataLog.setFileUrl(frontUrl.substring(0,frontUrl.indexOf("@@@")));
|
|
|
+ }else {
|
|
|
+ cataLog.setFileUrl(frontUrl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 备考表(原r_Archives_spare)增加中文匹配
|
|
|
+ else if (spare == null && (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[2])
|
|
|
+ || frontUrl.contains("备考表"))
|
|
|
+ && config.getFactorType().contains("3")) {
|
|
|
+ spare = new ArchivesAutoVO.ApprovalFile();
|
|
|
+ spare.setFileName("备考表");
|
|
|
+ if(frontUrl.contains("@@@")){
|
|
|
+ spare.setFileUrl(frontUrl.substring(0,frontUrl.indexOf("@@@")));
|
|
|
+ }else {
|
|
|
+ spare.setFileUrl(frontUrl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 背脊(原r_Archives_back)增加中文匹配
|
|
|
+ else if (back == null && (frontUrl.contains(ArchiveAutoPdfServiceImpl.ARCHIVE_NUMBER[3])
|
|
|
+ || frontUrl.contains("背脊"))
|
|
|
+ && config.getFactorType().contains("4")) {
|
|
|
+ back = new ArchivesAutoVO.ApprovalFile();
|
|
|
+ back.setFileName("背脊");
|
|
|
+ if(frontUrl.contains("@@@")){
|
|
|
+ back.setFileUrl(frontUrl.substring(0,frontUrl.indexOf("@@@")));
|
|
|
+ }else {
|
|
|
+ back.setFileUrl(frontUrl);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ List<ArchivesAutoVO.ApprovalFile> files = vo.getApprovalFileList();;
|
|
|
+ if (files != null) {
|
|
|
+ String tempId = null;
|
|
|
+ if (!files.isEmpty()) {
|
|
|
+ tempId = files.get(0).getId();
|
|
|
+ }
|
|
|
+ if (front != null && front.getFileUrl() != null) {
|
|
|
+ if (front.getId() == null && tempId != null) {
|
|
|
+ front.setId(tempId + "_1");
|
|
|
+ }
|
|
|
+ if (front.getId() != null) {
|
|
|
+ front.setPdfFileUrl(front.getFileUrl());
|
|
|
+ files.add(0,front);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (cataLog != null && cataLog.getFileUrl() != null) {
|
|
|
+ if (cataLog.getId() == null && tempId != null) {
|
|
|
+ cataLog.setId(tempId + "_2");
|
|
|
+ }
|
|
|
+ if (cataLog.getId() != null) {
|
|
|
+ cataLog.setPdfFileUrl(cataLog.getFileUrl());
|
|
|
+ if (front != null && front.getFileUrl() != null) {
|
|
|
+ files.add(1,cataLog);
|
|
|
+ } else {
|
|
|
+ files.add(0,cataLog);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (spare != null && spare.getFileUrl() != null) {
|
|
|
+ if (spare.getId() == null && tempId != null) {
|
|
|
+ spare.setId(tempId + "_3");
|
|
|
+ }
|
|
|
+ if (spare.getId() != null) {
|
|
|
+ spare.setPdfFileUrl(spare.getFileUrl());
|
|
|
+ files.add(spare);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (back != null && back.getFileUrl() != null) {
|
|
|
+ if (back.getId() == null && tempId != null) {
|
|
|
+ back.setId(tempId + "_4");
|
|
|
+ }
|
|
|
+ if (back.getId() != null) {
|
|
|
+ back.setPdfFileUrl(back.getFileUrl());
|
|
|
+ files.add(back);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
return vo;
|
|
|
}
|
|
|
|
|
@@ -1150,6 +1295,83 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ private String builtArchiveName_new(List<ArchiveFile> waitArchiveFiles, ArchiveTreeContract node, boolean isCrossNode
|
|
|
+ ,IArchiveNameService.NodeHierarchy nameInfo) {
|
|
|
+
|
|
|
+ String archiveName = "";
|
|
|
+
|
|
|
+ Long projectId = node.getProjectId();
|
|
|
+ ProjectInfo projectInfo = projectClient.getById(String.valueOf(projectId));
|
|
|
+ String projectName = projectInfo.getProjectName();
|
|
|
+ String contractName = "";
|
|
|
+ Long contractId = node.getContractId();
|
|
|
+ if (contractId != null && contractId != -1) {
|
|
|
+ ContractInfo contract = contractClient.getContractById(contractId);
|
|
|
+ contractName = contract.getContractName();
|
|
|
+ }
|
|
|
+ //获取案卷题名
|
|
|
+ archiveName = projectName;
|
|
|
+ if (StringUtils.isNotEmpty(contractName)) {
|
|
|
+ archiveName = archiveName + contractName;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //--正常节点
|
|
|
+ Set<String> uniqueNodeIds = waitArchiveFiles.stream()
|
|
|
+ .map(ArchiveFile::getNodeId)
|
|
|
+ .filter(nodeId -> nodeId != null && !nodeId.isEmpty())
|
|
|
+ .collect(Collectors.toCollection(LinkedHashSet::new));
|
|
|
+
|
|
|
+ // 2. 将节点ID从String转换为Long(保持原始顺序)
|
|
|
+ List<Long> nodeIds = uniqueNodeIds.stream()
|
|
|
+ .map(this::safeParseLong)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+
|
|
|
+ String fullPath = archiveNameService.generateFullLevelName(nodeIds, nameInfo);
|
|
|
+
|
|
|
+ archiveName+=fullPath;
|
|
|
+
|
|
|
+// if (archiveName.length() > 200) {
|
|
|
+// // 从150位置开始查找第一个顿号
|
|
|
+// int index = archiveName.indexOf('、', 200);
|
|
|
+// if (index != -1) {
|
|
|
+// // 找到顿号,截取到顿号位置(去掉顿号)并拼接“等文件”
|
|
|
+// archiveName = archiveName.substring(0, index) + "等文件";
|
|
|
+// } else {
|
|
|
+// // 没有找到顿号,直接截取150个字符并拼接“等文件”
|
|
|
+// archiveName = archiveName.substring(0, 200) + "等文件";
|
|
|
+// }
|
|
|
+// }
|
|
|
+
|
|
|
+ if (archiveName.length() > 1100) {
|
|
|
+ // 直接截取前1100个字符
|
|
|
+ archiveName = archiveName.substring(0, 1100);
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ //TODO wbs节点
|
|
|
+ //不存在跨节点 项目名称+案卷题名规则(在后台归档目录树设置的)+后缀
|
|
|
+ //存在跨节点 获取当前所有节点的父级节点题名规则+所有同层级跨节点并卷的节点名称拼接+后缀
|
|
|
+ String archiveNameSuffix = node.getArchiveNameSuffix();
|
|
|
+ if (archiveNameSuffix == null || archiveNameSuffix.equals("null")) {
|
|
|
+ archiveNameSuffix = "";
|
|
|
+ }
|
|
|
+ return archiveName + archiveNameSuffix;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 安全解析Long的方法(处理格式异常)
|
|
|
+ private Long safeParseLong(String value) {
|
|
|
+ try {
|
|
|
+ return Long.parseLong(value);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ log.warn("无法转换的节点ID格式: {}", value);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
private String builtArchiveName(List<ArchiveFile> waitArchiveFiles, ArchiveTreeContract node, boolean isCrossNode) {
|
|
|
|
|
|
String archiveName = "";
|
|
@@ -1269,20 +1491,68 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * 单独组卷规则组卷
|
|
|
+ *
|
|
|
+ * @param waitArchiveFiles
|
|
|
+ * @param node 规格参数所在节点
|
|
|
+ * @param pageN
|
|
|
+ */
|
|
|
+ private void createArchive3_new(List<ArchiveFile> waitArchiveFiles, ArchiveTreeContract node, int pageN,IArchiveNameService.NodeHierarchy nameInfo) {
|
|
|
+
|
|
|
+ String archiveStartDateAndEndDate = getArchiveStartDateAndEndDate(waitArchiveFiles);
|
|
|
+ String[] split = archiveStartDateAndEndDate.split(",");
|
|
|
+ String startDate = split.length >= 1 ? split[0] : "";
|
|
|
+ String endDate = split.length >= 2 ? split[1] : "";
|
|
|
+ int fileN = waitArchiveFiles.size();
|
|
|
+ if (fileN == 0) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ String archiveName = builtArchiveName_new(waitArchiveFiles, node, false,nameInfo);//获取案卷题名
|
|
|
+ //1.创建新案卷
|
|
|
+ ArchivesAuto archivesAuto = builtArchives(node, pageN, fileN, startDate, endDate, archiveName);
|
|
|
+ //2.设置文件所属案卷,组卷状态
|
|
|
+ Long archivesAutoId = archivesAuto.getId();
|
|
|
+
|
|
|
+ //封面和生成文件页码
|
|
|
+ archiveAutoPdfService.buildArchiveFrontPdfs(archivesAuto.getProjectId(), archivesAuto, waitArchiveFiles, false);
|
|
|
+
|
|
|
+ builtFilePageNo(archivesAuto, waitArchiveFiles);//生成文件页码
|
|
|
+
|
|
|
+
|
|
|
+ for (ArchiveFile file : waitArchiveFiles) {
|
|
|
+ file.setArchiveId(archivesAutoId);//设置文件所属案卷
|
|
|
+ file.setIsArchive(1);
|
|
|
+
|
|
|
+ }
|
|
|
+ archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
|
|
|
+ try {
|
|
|
+// for (ArchiveFile saveVo : waitArchiveFiles) {
|
|
|
+// metadataClassificationClient.createMetadataFile(saveVo.getId(), 0);
|
|
|
+// }
|
|
|
+ batchCreateMetadataFiles(waitArchiveFiles);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 分类并卷组卷
|
|
|
*
|
|
|
* @param waitArchiveFiles
|
|
|
* @param archiveAutoGroupId 分类并卷分组ID
|
|
|
*/
|
|
|
- private void createArchive2(List<ArchiveFile> waitArchiveFiles, Long archiveAutoGroupId, Long projectId) {
|
|
|
+ private void createArchive2(List<ArchiveFile> waitArchiveFiles, Long archiveAutoGroupId, Long projectId,IArchiveNameService.NodeHierarchy nameInfo) {
|
|
|
|
|
|
//获取同一分类archiveAutoGroupId下设置的(设置规则时选中的)节点,排好序
|
|
|
- List<ArchiveTreeContract> selectList = archiveTreeContractClient.getStorageNodeByGroupId(projectId, archiveAutoGroupId);
|
|
|
- //分类并卷节点默认采用同类型下第一个存储节点为归属节点
|
|
|
- if (selectList== null || selectList.size() == 0) {
|
|
|
- return;
|
|
|
- }
|
|
|
+// List<ArchiveTreeContract> selectList = archiveTreeContractClient.getStorageNodeByGroupId(projectId, archiveAutoGroupId);
|
|
|
+// //分类并卷节点默认采用同类型下第一个存储节点为归属节点
|
|
|
+// if (selectList== null || selectList.size() == 0) {
|
|
|
+// return;
|
|
|
+// }
|
|
|
|
|
|
if (waitArchiveFiles==null || waitArchiveFiles.size()== 0) {
|
|
|
return;
|
|
@@ -1290,7 +1560,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
|
|
|
String strfirstNodeId = waitArchiveFiles.get(0).getNodeId();
|
|
|
|
|
|
- ArchiveTreeContract node = selectList.get(0);
|
|
|
+ ArchiveTreeContract node = null;
|
|
|
if (StringUtils.isNotEmpty(strfirstNodeId)) {
|
|
|
Long firstNodeId = Long.parseLong(strfirstNodeId);
|
|
|
ArchiveTreeContract firstNode = archiveTreeContractClient.getArchiveTreeContractById(firstNodeId);
|
|
@@ -1317,7 +1587,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
}
|
|
|
//默认组卷存在跨节点组卷 注意案卷归属节点,案卷命名方式
|
|
|
//获取案卷题名
|
|
|
- String archiveName = builtArchiveName(waitArchiveFiles, node, true);//获取案卷题名
|
|
|
+ String archiveName = builtArchiveName_new(waitArchiveFiles, node, true,nameInfo);//获取案卷题名
|
|
|
|
|
|
//1.创建新案卷
|
|
|
ArchivesAuto archivesAuto = builtArchives(node, pageN, fileN, startDate, endDate, archiveName);
|
|
@@ -1546,6 +1816,10 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
|
|
|
private void archiveAutoMethod3(List<ArchiveTreeContract> list, Map<String, List<ArchiveFile>> boxMap,
|
|
|
Map<Long, String> boxFileMap, Long traceId) {
|
|
|
+
|
|
|
+ // 4. 构建节点层级关系
|
|
|
+ IArchiveNameService.NodeHierarchy nameInfo =
|
|
|
+ archiveNameService.buildNodeHierarchy(list);
|
|
|
// 步骤1:遍历节点集合
|
|
|
for (ArchiveTreeContract node : list) {
|
|
|
// 步骤2:获取当前节点的案卷规格
|
|
@@ -1581,7 +1855,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
|
|
|
// 如果是最后一个文件且有待组卷文件,则组卷
|
|
|
if (archiveFilesSize == archiveFiles.size() && !waitArchiveFiles.isEmpty()) {
|
|
|
- createArchive3(waitArchiveFiles, node, archivesSize);
|
|
|
+ createArchive3_new(waitArchiveFiles, node, archivesSize,nameInfo);
|
|
|
waitArchiveFiles.clear();
|
|
|
archivesSize = 0;
|
|
|
}
|
|
@@ -1600,7 +1874,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
|
|
|
// 最后一个文件直接组卷
|
|
|
if (archiveFilesSize == archiveFiles.size()) {
|
|
|
- createArchive3(waitArchiveFiles, node, archivesSize);
|
|
|
+ createArchive3_new(waitArchiveFiles, node, archivesSize,nameInfo);
|
|
|
waitArchiveFiles.clear();
|
|
|
archivesSize = 0;
|
|
|
}
|
|
@@ -1609,7 +1883,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
else if (checkStatus == 1) {
|
|
|
waitArchiveFiles.add(file);
|
|
|
archivesSize = tempTotalSize;
|
|
|
- createArchive3(waitArchiveFiles, node, archivesSize);
|
|
|
+ createArchive3_new(waitArchiveFiles, node, archivesSize,nameInfo);
|
|
|
|
|
|
// 重置待组卷集合
|
|
|
waitArchiveFiles.clear();
|
|
@@ -1619,7 +1893,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
else if (checkStatus == -1) {
|
|
|
if (!waitArchiveFiles.isEmpty()) {
|
|
|
// 先将现有集合组卷(不含当前文件)
|
|
|
- createArchive3(waitArchiveFiles, node, archivesSize);
|
|
|
+ createArchive3_new(waitArchiveFiles, node, archivesSize,nameInfo);
|
|
|
|
|
|
// 新建集合存放当前文件
|
|
|
waitArchiveFiles.clear();
|
|
@@ -1628,7 +1902,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
|
|
|
// 最后一个文件直接组卷
|
|
|
if (archiveFilesSize == archiveFiles.size()) {
|
|
|
- createArchive3(waitArchiveFiles, node, archivesSize);
|
|
|
+ createArchive3_new(waitArchiveFiles, node, archivesSize,nameInfo);
|
|
|
waitArchiveFiles.clear();
|
|
|
archivesSize = 0;
|
|
|
}
|
|
@@ -1636,7 +1910,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
// 当前文件单独成卷
|
|
|
waitArchiveFiles.add(file);
|
|
|
archivesSize = filePage;
|
|
|
- createArchive3(waitArchiveFiles, node, archivesSize);
|
|
|
+ createArchive3_new(waitArchiveFiles, node, archivesSize,nameInfo);
|
|
|
|
|
|
// 重置集合
|
|
|
waitArchiveFiles.clear();
|
|
@@ -1750,15 +2024,19 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
//一个archiveAutoGroupId组成一个案卷 案卷归属同个key的归档树节点select=1的第一个groupId2NodeIdMap
|
|
|
//createArchive2(archiveFiles, archiveAutoGroupId, projectId);
|
|
|
|
|
|
- archiveAutoMethodGroup(archiveFiles, archiveAutoGroupId, projectId);
|
|
|
+ archiveAutoMethodGroup(archiveFiles, archiveAutoGroupId, projectId,null);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
-
|
|
|
private void archiveAutoMethod2_new(List<ArchiveTreeContract> list, List<ArchiveTreeContract> topList, Long projectId,
|
|
|
Map<String, List<ArchiveFile>> boxMap, Map<Long, String> boxFileMap, Long traceId) {
|
|
|
|
|
|
+ // 构建TOP节点ID集合(提前计算提高效率)
|
|
|
+ Set<Long> topIdSet = topList.stream()
|
|
|
+ .map(ArchiveTreeContract::getId)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
// 分类并卷集合<groupId, List<文件>>
|
|
|
Map<Long, List<ArchiveFile>> archiveMap = new LinkedHashMap<>();
|
|
|
// 记录同个分组id对应的第一个节点ID(案卷归属节点)
|
|
@@ -1769,6 +2047,114 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
// 当前顶层节点对应的分组ID
|
|
|
Long currArchiveAutoGroupId = null;
|
|
|
|
|
|
+ // 4. 构建节点层级关系
|
|
|
+ IArchiveNameService.NodeHierarchy nameInfo =
|
|
|
+ archiveNameService.buildNodeHierarchy(list);
|
|
|
+
|
|
|
+ // 步骤1:遍历节点集合
|
|
|
+ for (ArchiveTreeContract node : list) {
|
|
|
+ // 初始化当前节点的分组ID和顶层节点ID
|
|
|
+ Long archiveAutoGroupId = node.getArchiveAutoGroupId();
|
|
|
+ Long nodeTopId = 0L;
|
|
|
+
|
|
|
+ String ancestors = node.getAncestors();
|
|
|
+ if (ancestors != null && !ancestors.trim().isEmpty()) {
|
|
|
+ // 分割祖先字符串并转换为Long列表
|
|
|
+ List<Long> ancestorIds = Arrays.stream(ancestors.split(","))
|
|
|
+ .map(String::trim)
|
|
|
+ .filter(s -> !s.isEmpty())
|
|
|
+ .map(s -> {
|
|
|
+ try {
|
|
|
+ return Long.parseLong(s);
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ // 从上到下遍历:根节点(开始) → 最近祖先(末尾)
|
|
|
+ // 查找最后一个匹配的TOP节点(离当前节点最近的)
|
|
|
+ for (int i = ancestorIds.size() - 1; i >= 0; i--) {
|
|
|
+ Long ancestorId = ancestorIds.get(i);
|
|
|
+ if (topIdSet.contains(ancestorId)) {
|
|
|
+ nodeTopId = ancestorId;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // =========== 关键修改结束 ===========
|
|
|
+
|
|
|
+ // 步骤3:确定当前节点的分组ID
|
|
|
+ if (curTopId != null && curTopId.equals(nodeTopId) && nodeTopId != 0) {
|
|
|
+ // 如果属于同一个非零顶层节点,使用之前的分组ID
|
|
|
+ archiveAutoGroupId = currArchiveAutoGroupId;
|
|
|
+ } else {
|
|
|
+ // 新顶层节点或没有顶层节点,更新当前分组信息
|
|
|
+ curTopId = nodeTopId;
|
|
|
+ currArchiveAutoGroupId = archiveAutoGroupId;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 步骤4:查询节点下的未归档文件(保持原逻辑)
|
|
|
+ List<ArchiveFile> archiveFiles = archiveFileClient.getListByNodeID(node.getId().toString());
|
|
|
+
|
|
|
+ if (archiveFiles != null && !archiveFiles.isEmpty()) {
|
|
|
+ // 记录日志(每个节点只记录一次)
|
|
|
+ String completeMsg = "[自动组卷] 分类组卷:" + "-traceId:" + traceId + "节点:" + node.getNodeName() + " 文件数量:" + archiveFiles.size();
|
|
|
+ iTraceLogService.saveLog(traceId, completeMsg);
|
|
|
+
|
|
|
+ // 步骤5:遍历未归档文件
|
|
|
+ for (ArchiveFile file : archiveFiles) {
|
|
|
+ // 步骤6:判断文件是否存在分盒设置
|
|
|
+ if (file.getBoxNumber() != null && file.getBoxNumber() != -1) {
|
|
|
+ // 添加到分盒文件集合
|
|
|
+ addBoxMap(file, boxMap, boxFileMap);
|
|
|
+ } else {
|
|
|
+ // 分类并卷流程
|
|
|
+ // 步骤7:将文件按照<groupId,List<文件>>放入集合
|
|
|
+ //改用top分组了
|
|
|
+ archiveAutoGroupId = curTopId;
|
|
|
+ if (archiveMap.containsKey(archiveAutoGroupId)) {
|
|
|
+ List<ArchiveFile> groupList = archiveMap.get(archiveAutoGroupId);
|
|
|
+ groupList.add(file);
|
|
|
+ } else {
|
|
|
+ List<ArchiveFile> groupList = new ArrayList<>();
|
|
|
+ groupList.add(file);
|
|
|
+ archiveMap.put(archiveAutoGroupId, groupList);
|
|
|
+ groupId2NodeIdMap.put(archiveAutoGroupId, node.getId());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 步骤8:按集合创建案卷(保持原逻辑)
|
|
|
+ for (Map.Entry<Long, List<ArchiveFile>> entry : archiveMap.entrySet()) {
|
|
|
+ Long archiveAutoGroupId = entry.getKey();
|
|
|
+ List<ArchiveFile> archiveFiles = entry.getValue();
|
|
|
+
|
|
|
+ // 同一个分组ID下的文件分组组卷
|
|
|
+ archiveAutoMethodGroup(archiveFiles, archiveAutoGroupId, projectId,nameInfo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ private void archiveAutoMethod2_new1(List<ArchiveTreeContract> list, List<ArchiveTreeContract> topList, Long projectId,
|
|
|
+ Map<String, List<ArchiveFile>> boxMap, Map<Long, String> boxFileMap, Long traceId) {
|
|
|
+
|
|
|
+ // 分类并卷集合<groupId, List<文件>>
|
|
|
+ Map<Long, List<ArchiveFile>> archiveMap = new LinkedHashMap<>();
|
|
|
+ // 记录同个分组id对应的第一个节点ID(案卷归属节点)
|
|
|
+ Map<Long, Long> groupId2NodeIdMap = new HashMap<>();
|
|
|
+
|
|
|
+ // 当前处理的顶层节点ID
|
|
|
+ Long curTopId = null;
|
|
|
+ // 当前顶层节点对应的分组ID
|
|
|
+ Long currArchiveAutoGroupId = null;
|
|
|
+
|
|
|
+ // 4. 构建节点层级关系
|
|
|
+ IArchiveNameService.NodeHierarchy nameInfo =
|
|
|
+ archiveNameService.buildNodeHierarchy(list);
|
|
|
+
|
|
|
// 步骤1:遍历节点集合
|
|
|
for (ArchiveTreeContract node : list) {
|
|
|
// 初始化当前节点的分组ID和顶层节点ID
|
|
@@ -1833,11 +2219,15 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
List<ArchiveFile> archiveFiles = entry.getValue();
|
|
|
|
|
|
// 同一个分组ID下的文件分组组卷
|
|
|
- archiveAutoMethodGroup(archiveFiles, archiveAutoGroupId, projectId);
|
|
|
+ archiveAutoMethodGroup(archiveFiles, archiveAutoGroupId, projectId,nameInfo);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void archiveAutoMethodGroup(List<ArchiveFile> archiveFiles, Long archiveAutoGroupId, Long projectId) {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ private void archiveAutoMethodGroup(List<ArchiveFile> archiveFiles, Long archiveAutoGroupId, Long projectId,IArchiveNameService.NodeHierarchy nameInfo) {
|
|
|
if (archiveFiles.size()==0) {
|
|
|
return;
|
|
|
}
|
|
@@ -1885,13 +2275,13 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
waitArchiveFiles.add(file);
|
|
|
archivesSize = tempTotalSize;
|
|
|
if (fileIndex == totalFiles) { // 是最后一个文件
|
|
|
- createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
|
|
|
+ createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId,nameInfo);
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case 1: // 达到规格
|
|
|
waitArchiveFiles.add(file);
|
|
|
- createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
|
|
|
+ createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId,nameInfo);
|
|
|
waitArchiveFiles = new ArrayList<>();
|
|
|
archivesSize = 0;
|
|
|
break;
|
|
@@ -1899,10 +2289,10 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
case -1: // 超出规格
|
|
|
if (waitArchiveFiles.isEmpty()) {
|
|
|
// 当前文件单独成卷
|
|
|
- createArchive2(Collections.singletonList(file), archiveAutoGroupId, projectId);
|
|
|
+ createArchive2(Collections.singletonList(file), archiveAutoGroupId, projectId,nameInfo);
|
|
|
} else {
|
|
|
// 先将现有文件组卷
|
|
|
- createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
|
|
|
+ createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId,nameInfo);
|
|
|
|
|
|
// 创建新的待组卷集合
|
|
|
waitArchiveFiles = new ArrayList<>();
|
|
@@ -1910,7 +2300,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
archivesSize = filePage;
|
|
|
|
|
|
if (fileIndex == totalFiles) { // 是最后一个文件
|
|
|
- createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
|
|
|
+ createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId,nameInfo);
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
@@ -2775,7 +3165,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
}
|
|
|
|
|
|
|
|
|
- public void test() {
|
|
|
+ public void test666() {
|
|
|
Long projectId = 0L;
|
|
|
List<ArchiveTreeContract> archiveTreeContracts = archiveTreeContractClient.getListByProjectId(projectId);
|
|
|
|
|
@@ -4024,8 +4414,154 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
return list;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
- public void deleteFile(String defaultDir,Long id){
|
|
|
+ @Override
|
|
|
+ @Async
|
|
|
+ public void fileNumberFlush(Long projectId, Long contractId, List<String> nodeIds,Integer isArchive) {
|
|
|
+ ArchiveProjectConfig config = archiveProjectConfigService.getByProjectIdOrNew(projectId);
|
|
|
+ List<ArchivesAutoVO4>list=baseMapper.selectAllArchiveAuto(projectId,contractId,nodeIds,isArchive);
|
|
|
+ if(list!=null && list.size()>0){
|
|
|
+ if(config.getDirType()==null||config.getDirType()==0){
|
|
|
+ List<ArchivesAuto> archivesAutos = setFileNumberByConfig(config, list);
|
|
|
+ this.updateBatchById(archivesAutos);
|
|
|
+ }else {
|
|
|
+ Map<Long, List<ArchivesAutoVO4>> map = list.stream().collect(Collectors.groupingBy(ArchivesAutoVO4::getParentId));
|
|
|
+ for (Map.Entry<Long, List<ArchivesAutoVO4>> entry : map.entrySet()) {
|
|
|
+ List<ArchivesAutoVO4> value = entry.getValue();
|
|
|
+ List<ArchivesAuto> archivesAutos = setFileNumberByConfig(config, value);
|
|
|
+ this.updateBatchById(archivesAutos);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean reBuildArchiveFrontPdfs(String archiveIds, Long projectId) {
|
|
|
+ if(StringUtils.isEmpty(archiveIds)){
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ archiveAutoPdfService.assignArchiveTableUrl();
|
|
|
+ String[] ids = archiveIds.split(",");
|
|
|
+ for (String archiveId : ids) {
|
|
|
+ ArchivesAuto auto = baseMapper.selectById(archiveId);
|
|
|
+ String sql="select * from u_archive_file where archive_id = "+archiveId+" and is_deleted = 0 order by sort,sort_num,create_time";
|
|
|
+ //List<ArchiveFile> archiveFiles = archiveFileClient.getArchiveFileByArchiveID(Long.valueOf(archiveId));
|
|
|
+ List<ArchiveFile> archiveFiles= jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(ArchiveFile.class));
|
|
|
+ archiveAutoPdfService.buildArchiveFrontPdfs(projectId,auto,archiveFiles,true);
|
|
|
+ baseMapper.updateById(auto);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean findAndReplace(List<ArchivesAuto> archivesAutos, FindAndReplaceDto dto) {
|
|
|
+ List<ArchivesAuto>updates = new ArrayList<>();
|
|
|
+ for (ArchivesAuto archivesAuto : archivesAutos) {
|
|
|
+ ArchivesAuto auto = new ArchivesAuto();
|
|
|
+ if(dto.getType()==1){
|
|
|
+ if(StringUtils.isNotEmpty(dto.getQuery())&&StringUtils.isNotEmpty(dto.getReplace())){
|
|
|
+ String name = archivesAuto.getName();
|
|
|
+ if (StringUtils.isNotEmpty(name)&&name.contains(dto.getQuery())) {
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
+ int lastIndex = 0;
|
|
|
+ // 查找所有匹配的位置
|
|
|
+ int index = name.indexOf(dto.getQuery());
|
|
|
+ while (index != -1) {
|
|
|
+ // 添加未处理部分(从上一个 lastIndex 到当前 index)
|
|
|
+ sb.append(name, lastIndex, index);
|
|
|
+
|
|
|
+ // 根据位置插入替换内容
|
|
|
+ if (dto.getPosition() != null) {
|
|
|
+ switch (dto.getPosition()) {
|
|
|
+ case 1: // 在查询内容前插入
|
|
|
+ sb.append(dto.getReplace());
|
|
|
+ sb.append(dto.getQuery());
|
|
|
+ break;
|
|
|
+ case 2: // 在查询内容后插入
|
|
|
+ sb.append(dto.getQuery());
|
|
|
+ sb.append(dto.getReplace());
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ throw new ServiceException("请选择正确的定位条件");
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ sb.append(dto.getQuery()); // 没有指定位置时保留原内容
|
|
|
+ }
|
|
|
+ // 更新 lastIndex 到当前匹配结束位置
|
|
|
+ lastIndex = index + dto.getQuery().length();
|
|
|
+ // 继续查找下一个匹配项
|
|
|
+ index = name.indexOf(dto.getQuery(), lastIndex);
|
|
|
+ }
|
|
|
+ // 添加剩余的部分
|
|
|
+ sb.append(name.substring(lastIndex));
|
|
|
+ // 更新名称
|
|
|
+ archivesAuto.setName(sb.toString());
|
|
|
+ auto.setId(archivesAuto.getId());
|
|
|
+ auto.setName(archivesAuto.getName());
|
|
|
+ updates.add(auto);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } else if (dto.getType()==2) {
|
|
|
+ if(StringUtils.isNotEmpty(dto.getQuery())&&StringUtils.isNotEmpty(dto.getReplace())){
|
|
|
+ String name = archivesAuto.getName();
|
|
|
+ if (StringUtils.isNotEmpty(name)&&name.contains(dto.getQuery())) {
|
|
|
+ String newName = name.replaceAll(dto.getQuery(), dto.getReplace());
|
|
|
+ archivesAuto.setName(newName);
|
|
|
+ auto.setId(archivesAuto.getId());
|
|
|
+ auto.setName(archivesAuto.getName());
|
|
|
+ updates.add(auto);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }else {
|
|
|
+ if(StringUtils.isNotEmpty(dto.getQuery())){
|
|
|
+ String name = archivesAuto.getName();
|
|
|
+ if (StringUtils.isNotEmpty(name)&&name.contains(dto.getQuery())) {
|
|
|
+ String newName = name.replaceAll(dto.getQuery(), "");
|
|
|
+ archivesAuto.setName(newName);
|
|
|
+ auto.setId(archivesAuto.getId());
|
|
|
+ auto.setName(archivesAuto.getName());
|
|
|
+ updates.add(auto);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if(!updates.isEmpty()){
|
|
|
+ return this.updateBatchById(archivesAutos);
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ public List<ArchivesAuto> setFileNumberByConfig(ArchiveProjectConfig config,List<ArchivesAutoVO4> value){
|
|
|
+ int i=1;
|
|
|
+ List<ArchivesAuto>list=new ArrayList<>();
|
|
|
+ for (ArchivesAutoVO4 v:value) {
|
|
|
+ ArchivesAuto auto = new ArchivesAuto();
|
|
|
+ if(config.getIndexType()==null||config.getIndexType()==0){
|
|
|
+ v.setFileNumber(v.getFileNumberPrefix()+"_"+i);
|
|
|
+ }else {
|
|
|
+ String prefix = v.getFileNumberPrefix();
|
|
|
+ int index = i; // 编号从 1 开始
|
|
|
+ // 获取配置中的编号长度(最多多少位)
|
|
|
+ int numLength = config.getIndexNum();
|
|
|
+ // 默认最多4位,防止过长或无效值
|
|
|
+ if (numLength > 10) { // 限制最大为10位
|
|
|
+ numLength = 4;
|
|
|
+ }
|
|
|
+ // 使用 %0xd 格式化数字,x 表示总长度
|
|
|
+ String formattedIndex = String.format("%0" + numLength + "d", index);
|
|
|
+ // 设置最终档号
|
|
|
+ v.setFileNumber(prefix + "_" + formattedIndex);
|
|
|
+ }
|
|
|
+ auto.setId(v.getId());
|
|
|
+ auto.setFileNumber(v.getFileNumber());
|
|
|
+ list.add(auto);
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ return list;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void deleteFile(String defaultDir,Long id){
|
|
|
String dir = defaultDir+"/"+id;
|
|
|
String file = defaultDir+"/"+id+".zip";
|
|
|
// 多条命令执行
|