|
@@ -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.*;
|
|
@@ -50,6 +52,7 @@ import org.springblade.business.feign.ArchiveFileClient;
|
|
|
import org.springblade.business.feign.MetadataClassificationClient;
|
|
|
import org.springblade.business.feign.TaskClient;
|
|
|
import org.springblade.common.utils.CommonUtil;
|
|
|
+import org.springblade.common.utils.DeepSeekClient;
|
|
|
import org.springblade.common.utils.SnowFlakeUtil;
|
|
|
import org.springblade.core.log.exception.ServiceException;
|
|
|
import org.springblade.core.mp.base.BaseServiceImpl;
|
|
@@ -73,6 +76,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;
|
|
@@ -91,6 +97,7 @@ import java.util.*;
|
|
|
import java.util.List;
|
|
|
import java.util.concurrent.ExecutorService;
|
|
|
import java.util.concurrent.TimeUnit;
|
|
|
+import java.util.concurrent.atomic.AtomicInteger;
|
|
|
import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
@@ -135,6 +142,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 +151,10 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
|
|
|
private final CommonFileClient commonFileClient;
|
|
|
|
|
|
+ private final IArchiveNameService archiveNameService;
|
|
|
+
|
|
|
+ private final IArchiveAiNameService aiNameService;
|
|
|
+
|
|
|
|
|
|
@Override
|
|
|
public IPage<ArchivesAutoVO> selectArchivesAutoPage(IPage<ArchivesAutoVO> page, ArchivesAutoVO archivesAuto) {
|
|
@@ -373,11 +386,138 @@ 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[] elementFiles = new ArchivesAutoVO.ApprovalFile[4];
|
|
|
+ AtomicInteger pageSize = new AtomicInteger(0);
|
|
|
+ if (approvalFiles != null && !approvalFiles.isEmpty()) {
|
|
|
+ // 四要素 使用名称判断
|
|
|
+ approvalFiles.removeIf(approvalFile -> {
|
|
|
+ if ("封面".equals(approvalFile.getFileName()) || "封面表".equals(approvalFile.getFileName())) {
|
|
|
+ elementFiles[0] = approvalFile;
|
|
|
+ return true;
|
|
|
+ } else if ("卷内目录".equals(approvalFile.getFileName()) || "卷内目录表".equals(approvalFile.getFileName()) || "目录表".equals(approvalFile.getFileName()) || "目录".equals(approvalFile.getFileName())) {
|
|
|
+ elementFiles[1] = approvalFile;
|
|
|
+ return true;
|
|
|
+ } else if ("备考表".equals(approvalFile.getFileName()) || "卷内备考表".equals(approvalFile.getFileName())) {
|
|
|
+ elementFiles[2] = approvalFile;
|
|
|
+ return true;
|
|
|
+ } else if ("背脊".equals(approvalFile.getFileName()) || "背脊表".equals(approvalFile.getFileName())) {
|
|
|
+ elementFiles[3] = approvalFile;
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ pageSize.addAndGet(approvalFile.getFilePage() == null ? 1 : approvalFile.getFilePage());
|
|
|
+ return false;
|
|
|
+ });
|
|
|
} else {
|
|
|
vo.setPageNumber(0);
|
|
|
}
|
|
|
+ ArchivesAutoVO.ApprovalFile front = elementFiles[0];
|
|
|
+ ArchivesAutoVO.ApprovalFile cataLog = elementFiles[1];
|
|
|
+ ArchivesAutoVO.ApprovalFile spare = elementFiles[2];
|
|
|
+ ArchivesAutoVO.ApprovalFile back = elementFiles[3];
|
|
|
+ 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 +1290,129 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+ private String builtArchiveName_new(List<ArchiveFile> waitArchiveFiles, ArchiveTreeContract node, boolean isCrossNode
|
|
|
+ ,IArchiveNameService.NodeHierarchy nameInfo,Set<Long> multiVolumeNodes,Integer archiveAutoType) {
|
|
|
+
|
|
|
+ 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.getContractNumber();
|
|
|
+ }
|
|
|
+ //获取案卷题名
|
|
|
+ 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));
|
|
|
+
|
|
|
+ String timeRange = "";
|
|
|
+
|
|
|
+ boolean extFlag = false;
|
|
|
+ if (node.getExtType()!= null && node.getExtType()== 1) {
|
|
|
+ extFlag = true;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ if (uniqueNodeIds.size() == 1 && extFlag == false) {
|
|
|
+ try {
|
|
|
+ Long nodeId = Long.parseLong(uniqueNodeIds.iterator().next());
|
|
|
+
|
|
|
+ // 检查该节点是否需要添加时间区间(生成多个案卷)
|
|
|
+ if (multiVolumeNodes != null && multiVolumeNodes.contains(nodeId)) {
|
|
|
+ // 获取所有有效的时间字符串
|
|
|
+ List<String> validTimes = waitArchiveFiles.stream()
|
|
|
+ .map(ArchiveFile::getFileTime)
|
|
|
+ .filter(time -> time != null && !time.trim().isEmpty())
|
|
|
+ .sorted() // 按字符串自然顺序排序
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ if (!validTimes.isEmpty()) {
|
|
|
+ String minTime = validTimes.get(0);
|
|
|
+ String maxTime = validTimes.get(validTimes.size() - 1);
|
|
|
+
|
|
|
+ // 生成时间区间字符串
|
|
|
+ timeRange = minTime + "~" + maxTime;
|
|
|
+ } else {
|
|
|
+ log.warn("组卷文件缺少有效时间戳:nodeId={}", nodeId);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (NumberFormatException e) {
|
|
|
+ log.warn("无效的节点ID格式", e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 2. 将节点ID从String转换为Long(保持原始顺序)
|
|
|
+ List<Long> nodeIds = uniqueNodeIds.stream()
|
|
|
+ .map(this::safeParseLong)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+
|
|
|
+ String fullPath = "";
|
|
|
+ if (extFlag == true) {
|
|
|
+ fullPath = archiveNameService.generateFullLevelName(nodeIds, nameInfo,true);
|
|
|
+ }else {
|
|
|
+ //独立组卷,且非工序节点,取节点名曾即可
|
|
|
+ if (archiveAutoType == 3) {
|
|
|
+ fullPath = node.getNodeName();
|
|
|
+ }else {
|
|
|
+ fullPath = archiveNameService.generateFullLevelName(nodeIds, nameInfo,false);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ archiveName += timeRange + 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 = "";
|
|
@@ -1218,7 +1481,6 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
//生成文件对应的页码,返回url
|
|
|
archiveAutoPdfService.builtFilePageNo(archivesAuto, waitArchiveFiles);
|
|
|
this.updateById(archivesAuto);
|
|
|
-
|
|
|
return "";
|
|
|
}
|
|
|
|
|
@@ -1245,7 +1507,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
//1.创建新案卷
|
|
|
ArchivesAuto archivesAuto = builtArchives(node, pageN, fileN, startDate, endDate, archiveName);
|
|
|
//2.设置文件所属案卷,组卷状态
|
|
|
- Long archivesAutoId = archivesAuto.getId();
|
|
|
+ //Long archivesAutoId = archivesAuto.getId();
|
|
|
|
|
|
//封面和生成文件页码
|
|
|
archiveAutoPdfService.buildArchiveFrontPdfs(archivesAuto.getProjectId(), archivesAuto, waitArchiveFiles, false);
|
|
@@ -1253,11 +1515,94 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
builtFilePageNo(archivesAuto, waitArchiveFiles);//生成文件页码
|
|
|
|
|
|
|
|
|
- for (ArchiveFile file : waitArchiveFiles) {
|
|
|
- file.setArchiveId(archivesAutoId);//设置文件所属案卷
|
|
|
- file.setIsArchive(1);
|
|
|
+ //设置文件所属案卷,组卷状态,排序
|
|
|
+ Long archivesAutoId = archivesAuto.getId();
|
|
|
+ setArchiveFiles(archivesAutoId,waitArchiveFiles);
|
|
|
+ archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
|
|
|
+ try {
|
|
|
+// for (ArchiveFile saveVo : waitArchiveFiles) {
|
|
|
+// metadataClassificationClient.createMetadataFile(saveVo.getId(), 0);
|
|
|
+// }
|
|
|
+ batchCreateMetadataFiles(waitArchiveFiles);
|
|
|
+ } catch (Exception e) {
|
|
|
+ e.printStackTrace();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ public void reCreateArchiveAuto(ArchivesAuto archivesAuto, List<ArchiveFile> waitArchiveFiles){
|
|
|
+ archiveAutoPdfService.assignArchiveTableUrl();
|
|
|
+ //生成四要素
|
|
|
+ archiveAutoPdfService.buildArchiveFrontPdfs(archivesAuto.getProjectId(), archivesAuto, waitArchiveFiles, true);
|
|
|
+ //生成页码
|
|
|
+ builtFilePageNo(archivesAuto, waitArchiveFiles);
|
|
|
+ archiveFileClient.updateArchiveFile(waitArchiveFiles);
|
|
|
+ }
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public boolean creatFileNameFormAI(String ids, Long projectId, Long contractId) throws IOException {
|
|
|
+ List<ArchivesAuto> archivesAutoList = this.listByIds(Func.toLongList(ids));
|
|
|
+ List<ArchiveAiName>aiNames=new ArrayList<>();
|
|
|
+ Long taskId=SnowFlakeUtil.getId();
|
|
|
+ List<ArchiveAiName> archiveAiNameList = aiNameService.getBaseMapper().selectList(new LambdaQueryWrapper<>(ArchiveAiName.class).eq(ArchiveAiName::getProjectId, projectId).eq(ArchiveAiName::getContractId, contractId).in(ArchiveAiName::getArchiveAutoId, Func.toLongList(ids)));
|
|
|
+ List<Long> existid=new ArrayList<>();
|
|
|
+ if(!archiveAiNameList.isEmpty()){
|
|
|
+ existid= archiveAiNameList.stream().filter(ai -> ai.getStatus() == 1).map(ai -> ai.getArchiveAutoId()).collect(Collectors.toList());
|
|
|
+ }
|
|
|
+ for (ArchivesAuto auto : archivesAutoList) {
|
|
|
+ if(!existid.isEmpty()){
|
|
|
+ if(existid.contains(auto.getId())){
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ ArchiveAiName aiName = new ArchiveAiName();
|
|
|
+ aiName.setProjectId(projectId);
|
|
|
+ aiName.setContractId(contractId);
|
|
|
+ aiName.setTaskId(taskId);
|
|
|
+ aiName.setArchiveAutoId(auto.getId());
|
|
|
+ aiName.setArchiveName(auto.getName());
|
|
|
+ aiName.setStatus(1);
|
|
|
+ aiNames.add(aiName);
|
|
|
+ }
|
|
|
+ //异步调用AI接口
|
|
|
+ aiNameService.syncCreatAiName(aiNames);
|
|
|
+ return aiNameService.saveBatch(aiNames);
|
|
|
+ }
|
|
|
+
|
|
|
|
|
|
+ /**
|
|
|
+ * 单独组卷规则组卷
|
|
|
+ *
|
|
|
+ * @param waitArchiveFiles
|
|
|
+ * @param node 规格参数所在节点
|
|
|
+ * @param pageN
|
|
|
+ */
|
|
|
+ private void createArchive3_new(List<ArchiveFile> waitArchiveFiles, ArchiveTreeContract node, int pageN,IArchiveNameService.NodeHierarchy nameInfo, Set<Long> multiVolumeNodes) {
|
|
|
+
|
|
|
+ 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,multiVolumeNodes,3);//获取案卷题名
|
|
|
+ //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);//生成文件页码
|
|
|
+
|
|
|
+
|
|
|
+ //设置文件所属案卷,组卷状态,排序
|
|
|
+ Long archivesAutoId = archivesAuto.getId();
|
|
|
+ setArchiveFiles(archivesAutoId,waitArchiveFiles);
|
|
|
archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
|
|
|
try {
|
|
|
// for (ArchiveFile saveVo : waitArchiveFiles) {
|
|
@@ -1269,20 +1614,22 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
/**
|
|
|
* 分类并卷组卷
|
|
|
*
|
|
|
* @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,Set<Long> multiVolumeNodes) {
|
|
|
|
|
|
//获取同一分类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 +1637,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 +1664,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
}
|
|
|
//默认组卷存在跨节点组卷 注意案卷归属节点,案卷命名方式
|
|
|
//获取案卷题名
|
|
|
- String archiveName = builtArchiveName(waitArchiveFiles, node, true);//获取案卷题名
|
|
|
+ String archiveName = builtArchiveName_new(waitArchiveFiles, node, true,nameInfo,multiVolumeNodes,2);//获取案卷题名
|
|
|
|
|
|
//1.创建新案卷
|
|
|
ArchivesAuto archivesAuto = builtArchives(node, pageN, fileN, startDate, endDate, archiveName);
|
|
@@ -1327,12 +1674,16 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
|
|
|
builtFilePageNo(archivesAuto, waitArchiveFiles);
|
|
|
|
|
|
- //3.设置文件所属案卷,组卷状态
|
|
|
+
|
|
|
+// Long archivesAutoId = archivesAuto.getId();
|
|
|
+// for (ArchiveFile file : waitArchiveFiles) {
|
|
|
+// file.setArchiveId(archivesAutoId);//设置文件所属案卷
|
|
|
+// file.setIsArchive(1);
|
|
|
+// }
|
|
|
+ //设置文件所属案卷,组卷状态,排序
|
|
|
Long archivesAutoId = archivesAuto.getId();
|
|
|
- for (ArchiveFile file : waitArchiveFiles) {
|
|
|
- file.setArchiveId(archivesAutoId);//设置文件所属案卷
|
|
|
- file.setIsArchive(1);
|
|
|
- }
|
|
|
+ setArchiveFiles(archivesAutoId,waitArchiveFiles);
|
|
|
+
|
|
|
archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
|
|
|
try {
|
|
|
batchCreateMetadataFiles(waitArchiveFiles);
|
|
@@ -1375,11 +1726,9 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
builtFilePageNo(archivesAuto, waitArchiveFiles);
|
|
|
|
|
|
//3.设置文件所属案卷,组卷状态
|
|
|
+ //设置文件所属案卷,组卷状态,排序
|
|
|
Long archivesAutoId = archivesAuto.getId();
|
|
|
- for (ArchiveFile file : waitArchiveFiles) {
|
|
|
- file.setArchiveId(archivesAutoId);//设置文件所属案卷
|
|
|
- file.setIsArchive(1);
|
|
|
- }
|
|
|
+ setArchiveFiles(archivesAutoId,waitArchiveFiles);
|
|
|
archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
|
|
|
try {
|
|
|
// for (ArchiveFile saveVo : waitArchiveFiles) {
|
|
@@ -1431,11 +1780,9 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
builtFilePageNo(archivesAuto, waitArchiveFiles);
|
|
|
|
|
|
//3.设置文件所属案卷,组卷状态
|
|
|
+ //设置文件所属案卷,组卷状态,排序
|
|
|
Long archivesAutoId = archivesAuto.getId();
|
|
|
- for (ArchiveFile file : waitArchiveFiles) {
|
|
|
- file.setArchiveId(archivesAutoId);//设置文件所属案卷
|
|
|
- file.setIsArchive(1);
|
|
|
- }
|
|
|
+ setArchiveFiles(archivesAutoId,waitArchiveFiles);
|
|
|
archiveFileClient.updateArchiveFileForCreateArchive(waitArchiveFiles);
|
|
|
try {
|
|
|
// for (ArchiveFile saveVo : waitArchiveFiles) {
|
|
@@ -1546,6 +1893,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:获取当前节点的案卷规格
|
|
@@ -1566,6 +1917,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
String completeMsg = "[自动组卷] 单独组卷:" + "-traceId:" + traceId + "节点:" + node.getNodeName() + " 文件数量:" + archiveFiles.size();
|
|
|
iTraceLogService.saveLog(traceId, completeMsg);
|
|
|
|
|
|
+ Set<Long> multiVolumeNodes = precalculateMultiVolumeNodes(archiveFiles, specificationSize);
|
|
|
+
|
|
|
// 步骤4:遍历未归档文件
|
|
|
List<ArchiveFile> waitArchiveFiles = new ArrayList<>(); // 待组卷文件集合
|
|
|
int archivesSize = 0; // 待组卷文件总页数
|
|
@@ -1581,7 +1934,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
|
|
|
// 如果是最后一个文件且有待组卷文件,则组卷
|
|
|
if (archiveFilesSize == archiveFiles.size() && !waitArchiveFiles.isEmpty()) {
|
|
|
- createArchive3(waitArchiveFiles, node, archivesSize);
|
|
|
+ createArchive3_new(waitArchiveFiles, node, archivesSize,nameInfo,null);
|
|
|
waitArchiveFiles.clear();
|
|
|
archivesSize = 0;
|
|
|
}
|
|
@@ -1600,7 +1953,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
|
|
|
// 最后一个文件直接组卷
|
|
|
if (archiveFilesSize == archiveFiles.size()) {
|
|
|
- createArchive3(waitArchiveFiles, node, archivesSize);
|
|
|
+ createArchive3_new(waitArchiveFiles, node, archivesSize,nameInfo,multiVolumeNodes);
|
|
|
waitArchiveFiles.clear();
|
|
|
archivesSize = 0;
|
|
|
}
|
|
@@ -1609,7 +1962,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,multiVolumeNodes);
|
|
|
|
|
|
// 重置待组卷集合
|
|
|
waitArchiveFiles.clear();
|
|
@@ -1619,7 +1972,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
else if (checkStatus == -1) {
|
|
|
if (!waitArchiveFiles.isEmpty()) {
|
|
|
// 先将现有集合组卷(不含当前文件)
|
|
|
- createArchive3(waitArchiveFiles, node, archivesSize);
|
|
|
+ createArchive3_new(waitArchiveFiles, node, archivesSize,nameInfo,multiVolumeNodes);
|
|
|
|
|
|
// 新建集合存放当前文件
|
|
|
waitArchiveFiles.clear();
|
|
@@ -1628,7 +1981,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
|
|
|
// 最后一个文件直接组卷
|
|
|
if (archiveFilesSize == archiveFiles.size()) {
|
|
|
- createArchive3(waitArchiveFiles, node, archivesSize);
|
|
|
+ createArchive3_new(waitArchiveFiles, node, archivesSize,nameInfo,multiVolumeNodes);
|
|
|
waitArchiveFiles.clear();
|
|
|
archivesSize = 0;
|
|
|
}
|
|
@@ -1636,7 +1989,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
// 当前文件单独成卷
|
|
|
waitArchiveFiles.add(file);
|
|
|
archivesSize = filePage;
|
|
|
- createArchive3(waitArchiveFiles, node, archivesSize);
|
|
|
+ createArchive3_new(waitArchiveFiles, node, archivesSize,nameInfo,multiVolumeNodes);
|
|
|
|
|
|
// 重置集合
|
|
|
waitArchiveFiles.clear();
|
|
@@ -1750,15 +2103,123 @@ 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(案卷归属节点)
|
|
|
+ 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
|
|
|
+ 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(案卷归属节点)
|
|
@@ -1769,6 +2230,10 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
// 当前顶层节点对应的分组ID
|
|
|
Long currArchiveAutoGroupId = null;
|
|
|
|
|
|
+ // 4. 构建节点层级关系
|
|
|
+ IArchiveNameService.NodeHierarchy nameInfo =
|
|
|
+ archiveNameService.buildNodeHierarchy(list);
|
|
|
+
|
|
|
// 步骤1:遍历节点集合
|
|
|
for (ArchiveTreeContract node : list) {
|
|
|
// 初始化当前节点的分组ID和顶层节点ID
|
|
@@ -1833,11 +2298,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;
|
|
|
}
|
|
@@ -1868,6 +2337,8 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
int fileIndex = 0;
|
|
|
int totalFiles = archiveFiles.size();
|
|
|
|
|
|
+ Set<Long> multiVolumeNodes = precalculateMultiVolumeNodes(archiveFiles, specificationSize);
|
|
|
+
|
|
|
for (ArchiveFile file : archiveFiles) {
|
|
|
fileIndex++;
|
|
|
// 获取文件页数,处理null值
|
|
@@ -1885,13 +2356,13 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
waitArchiveFiles.add(file);
|
|
|
archivesSize = tempTotalSize;
|
|
|
if (fileIndex == totalFiles) { // 是最后一个文件
|
|
|
- createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
|
|
|
+ createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId,nameInfo,multiVolumeNodes);
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
case 1: // 达到规格
|
|
|
waitArchiveFiles.add(file);
|
|
|
- createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
|
|
|
+ createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId,nameInfo,multiVolumeNodes);
|
|
|
waitArchiveFiles = new ArrayList<>();
|
|
|
archivesSize = 0;
|
|
|
break;
|
|
@@ -1899,10 +2370,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,multiVolumeNodes);
|
|
|
} else {
|
|
|
// 先将现有文件组卷
|
|
|
- createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
|
|
|
+ createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId,nameInfo,multiVolumeNodes);
|
|
|
|
|
|
// 创建新的待组卷集合
|
|
|
waitArchiveFiles = new ArrayList<>();
|
|
@@ -1910,7 +2381,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
archivesSize = filePage;
|
|
|
|
|
|
if (fileIndex == totalFiles) { // 是最后一个文件
|
|
|
- createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId);
|
|
|
+ createArchive2(waitArchiveFiles, archiveAutoGroupId, projectId,nameInfo,multiVolumeNodes);
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
@@ -2775,7 +3246,7 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
}
|
|
|
|
|
|
|
|
|
- public void test() {
|
|
|
+ public void test666() {
|
|
|
Long projectId = 0L;
|
|
|
List<ArchiveTreeContract> archiveTreeContracts = archiveTreeContractClient.getListByProjectId(projectId);
|
|
|
|
|
@@ -4024,8 +4495,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";
|
|
|
// 多条命令执行
|
|
@@ -4159,4 +4776,113 @@ public class ArchivesAutoServiceImpl extends BaseServiceImpl<ArchivesAutoMapper,
|
|
|
return R.success("保存成功");
|
|
|
}
|
|
|
|
|
|
+ // 归档文件设置函数
|
|
|
+ public void setArchiveFiles(Long archivesAutoId, List<ArchiveFile> waitArchiveFiles) {
|
|
|
+ if (waitArchiveFiles == null || archivesAutoId == null) {
|
|
|
+ return; // 处理空指针情况
|
|
|
+ }
|
|
|
+
|
|
|
+ int archiveSortCounter = 1; // 从1开始递增的archiveSort计数器
|
|
|
+
|
|
|
+ for (ArchiveFile file : waitArchiveFiles) {
|
|
|
+ file.setArchiveId(archivesAutoId); // 设置文件所属案卷ID
|
|
|
+ file.setIsArchive(1); // 标记文件已归档
|
|
|
+ file.setArchiveSort(archiveSortCounter++); // 设置自增的archiveSort
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private Set<Long> precalculateMultiVolumeNodes(List<ArchiveFile> files, int specificationSize) {
|
|
|
+ if (files == null || files.isEmpty()) {
|
|
|
+ return Collections.emptySet();
|
|
|
+ }
|
|
|
+
|
|
|
+ Map<Long, List<List<ArchiveFile>>> nodeGroupingMap = new HashMap<>();
|
|
|
+ Set<Long> multiVolumeNodes = new HashSet<>();
|
|
|
+
|
|
|
+ // 待组卷文件集合
|
|
|
+ List<ArchiveFile> waitArchiveFiles = new ArrayList<>();
|
|
|
+ // 待组卷文件总页数
|
|
|
+ int archivesSize = 0;
|
|
|
+ // 文件索引(用于处理最后文件)
|
|
|
+ int fileIndex = 0;
|
|
|
+ int totalFiles = files.size();
|
|
|
+
|
|
|
+ for (ArchiveFile file : files) {
|
|
|
+ fileIndex++;
|
|
|
+ int filePage = file.getFilePage() != null ? file.getFilePage() : 0;
|
|
|
+ int tempTotalSize = archivesSize + filePage;
|
|
|
+ int checkStatus = checkSpecificationSize(specificationSize, tempTotalSize);
|
|
|
+
|
|
|
+ switch (checkStatus) {
|
|
|
+ case 0: // 未到规格
|
|
|
+ waitArchiveFiles.add(file);
|
|
|
+ archivesSize = tempTotalSize;
|
|
|
+ if (fileIndex == totalFiles) { // 是最后一个文件
|
|
|
+ recordGroup(waitArchiveFiles, nodeGroupingMap);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
+ case 1: // 达到规格
|
|
|
+ waitArchiveFiles.add(file);
|
|
|
+ recordGroup(waitArchiveFiles, nodeGroupingMap);
|
|
|
+ waitArchiveFiles = new ArrayList<>();
|
|
|
+ archivesSize = 0;
|
|
|
+ break;
|
|
|
+
|
|
|
+ case -1: // 超出规格
|
|
|
+ if (!waitArchiveFiles.isEmpty()) {
|
|
|
+ recordGroup(waitArchiveFiles, nodeGroupingMap);
|
|
|
+ waitArchiveFiles = new ArrayList<>();
|
|
|
+ waitArchiveFiles.add(file);
|
|
|
+ archivesSize = filePage;
|
|
|
+ if (fileIndex == totalFiles) { // 是最后一个文件
|
|
|
+ recordGroup(waitArchiveFiles, nodeGroupingMap);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ waitArchiveFiles.add(file);
|
|
|
+ archivesSize = filePage;
|
|
|
+ recordGroup(waitArchiveFiles, nodeGroupingMap);
|
|
|
+ waitArchiveFiles = new ArrayList<>();
|
|
|
+ archivesSize = 0;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 确定哪些节点有多个卷
|
|
|
+ nodeGroupingMap.forEach((nodeId, groups) -> {
|
|
|
+ if (groups.size() > 1) {
|
|
|
+ multiVolumeNodes.add(nodeId);
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ return multiVolumeNodes;
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+ private void recordGroup(List<ArchiveFile> groupFiles, Map<Long, List<List<ArchiveFile>>> nodeGroupingMap) {
|
|
|
+ if (groupFiles == null || groupFiles.isEmpty()) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ // 提取节点ID(确保单一节点)
|
|
|
+ Set<Long> groupNodeIds = new HashSet<>();
|
|
|
+ for (ArchiveFile file : groupFiles) {
|
|
|
+ try {
|
|
|
+ Long nodeId = Long.parseLong(file.getNodeId());
|
|
|
+ groupNodeIds.add(nodeId);
|
|
|
+ } catch (Exception e) {
|
|
|
+ // 忽略无效节点ID
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 仅记录单节点分组
|
|
|
+ if (groupNodeIds.size() == 1) {
|
|
|
+ Long nodeId = groupNodeIds.iterator().next();
|
|
|
+ nodeGroupingMap.computeIfAbsent(nodeId, k -> new ArrayList<>())
|
|
|
+ .add(new ArrayList<>(groupFiles));
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
}
|