From 46d190aa74d7ff521adf672fc1f2d88cd2df1624 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Sun, 29 Mar 2026 09:54:05 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=8E=86=E5=8F=B2=E9=A1=B9?= =?UTF-8?q?=E7=9B=AE=E6=B5=81=E6=B0=B4=E5=A4=8D=E5=88=B6=E5=90=8E=E7=AB=AF?= =?UTF-8?q?=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mapper/CcdiBankStatementMapper.java | 5 + .../mapper/CcdiFileUploadRecordMapper.java | 8 + .../CcdiProjectHistoryImportServiceImpl.java | 168 +++++++++++++++++- .../ccdi/project/CcdiBankStatementMapper.xml | 27 +++ .../project/CcdiFileUploadRecordMapper.xml | 15 +- .../CcdiBankStatementMapperXmlTest.java | 22 +++ ...diProjectHistoryImportServiceImplTest.java | 166 +++++++++++++++++ ...3-29-project-import-history-plan-record.md | 8 + 8 files changed, 412 insertions(+), 7 deletions(-) create mode 100644 ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectHistoryImportServiceImplTest.java diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiBankStatementMapper.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiBankStatementMapper.java index 7070ac8e..4a6ba154 100644 --- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiBankStatementMapper.java +++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiBankStatementMapper.java @@ -30,6 +30,11 @@ public interface CcdiBankStatementMapper extends BaseMapper { int deleteByProjectIdAndBatchId(@Param("projectId") Long projectId, @Param("batchId") Integer batchId); + List selectStatementsForHistoryImport(@Param("projectId") Long projectId, + @Param("batchId") Integer batchId, + @Param("startDate") String startDate, + @Param("endDate") String endDate); + Page selectStatementPage(Page page, @Param("query") CcdiBankStatementQueryDTO query); diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiFileUploadRecordMapper.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiFileUploadRecordMapper.java index abd4a249..68f63fc0 100644 --- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiFileUploadRecordMapper.java +++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/mapper/CcdiFileUploadRecordMapper.java @@ -25,6 +25,14 @@ public interface CcdiFileUploadRecordMapper extends BaseMapper records); + /** + * 查询来源项目中解析成功且具备logId的文件记录 + * + * @param projectIds 来源项目ID列表 + * @return 文件记录列表 + */ + List selectSuccessfulRecordsByProjectIds(@Param("projectIds") List projectIds); + /** * 统计各状态文件数量 * diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectHistoryImportServiceImpl.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectHistoryImportServiceImpl.java index 8cbdd583..19a9bb3e 100644 --- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectHistoryImportServiceImpl.java +++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectHistoryImportServiceImpl.java @@ -1,11 +1,27 @@ package com.ruoyi.ccdi.project.service.impl; +import com.ruoyi.ccdi.project.domain.CcdiProject; import com.ruoyi.ccdi.project.domain.dto.CcdiProjectImportHistoryDTO; +import com.ruoyi.ccdi.project.domain.entity.CcdiBankStatement; +import com.ruoyi.ccdi.project.domain.entity.CcdiFileUploadRecord; +import com.ruoyi.ccdi.project.mapper.CcdiBankStatementMapper; +import com.ruoyi.ccdi.project.mapper.CcdiFileUploadRecordMapper; +import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper; import com.ruoyi.ccdi.project.service.ICcdiProjectHistoryImportService; +import jakarta.annotation.Resource; import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.BeanUtils; +import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.stereotype.Service; -import java.util.concurrent.CompletableFuture; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Objects; +import java.util.Set; +import java.util.concurrent.Executor; +import java.util.concurrent.atomic.AtomicInteger; /** * 历史项目导入服务实现 @@ -16,12 +32,154 @@ import java.util.concurrent.CompletableFuture; @Service public class CcdiProjectHistoryImportServiceImpl implements ICcdiProjectHistoryImportService { + private static final AtomicInteger HISTORY_IMPORT_BATCH_ID = new AtomicInteger(1_000_000); + + @Resource + private CcdiBankStatementMapper bankStatementMapper; + + @Resource + private CcdiFileUploadRecordMapper recordMapper; + + @Resource + private CcdiProjectMapper projectMapper; + + @Resource + @Qualifier("fileUploadExecutor") + private Executor fileUploadExecutor; + @Override public void submitImport(Long targetProjectId, Integer targetLsfxProjectId, CcdiProjectImportHistoryDTO dto, String operator) { - CompletableFuture.runAsync(() -> log.info( - "【项目历史导入】任务已提交: projectId={}, lsfxProjectId={}, sourceProjectIds={}, operator={}", - targetProjectId, targetLsfxProjectId, dto.getSourceProjectIds(), operator - )); + fileUploadExecutor.execute(() -> executeImport(targetProjectId, targetLsfxProjectId, dto, operator)); + } + + private void executeImport(Long targetProjectId, Integer targetLsfxProjectId, + CcdiProjectImportHistoryDTO dto, String operator) { + List sourceRecords = recordMapper.selectSuccessfulRecordsByProjectIds(dto.getSourceProjectIds()); + if (sourceRecords == null || sourceRecords.isEmpty()) { + log.info("【项目历史导入】无可复制的来源批次: projectId={}, sourceProjectIds={}", + targetProjectId, dto.getSourceProjectIds()); + return; + } + + List statementsToInsert = new ArrayList<>(); + List recordsToInsert = new ArrayList<>(); + Set dedupKeys = new HashSet<>(); + + for (CcdiFileUploadRecord sourceRecord : sourceRecords) { + List sourceStatements = bankStatementMapper.selectStatementsForHistoryImport( + sourceRecord.getProjectId(), sourceRecord.getLogId(), dto.getStartDate(), dto.getEndDate() + ); + if (sourceStatements == null || sourceStatements.isEmpty()) { + continue; + } + + Integer newBatchId = HISTORY_IMPORT_BATCH_ID.incrementAndGet(); + int sizeBefore = statementsToInsert.size(); + + for (CcdiBankStatement sourceStatement : sourceStatements) { + CcdiBankStatement targetStatement = copyStatement(sourceStatement, targetProjectId, targetLsfxProjectId, newBatchId); + if (dedupKeys.add(buildDedupKey(targetStatement))) { + statementsToInsert.add(targetStatement); + } + } + + if (statementsToInsert.size() > sizeBefore) { + recordsToInsert.add(buildHistoryImportRecord( + sourceRecord, targetProjectId, targetLsfxProjectId, newBatchId, resolveSourceProjectName(sourceRecord.getProjectId()), operator + )); + } + } + + if (!statementsToInsert.isEmpty()) { + bankStatementMapper.insertBatch(statementsToInsert); + } + if (!recordsToInsert.isEmpty()) { + recordMapper.insertBatch(recordsToInsert); + } + } + + private CcdiBankStatement copyStatement(CcdiBankStatement sourceStatement, Long targetProjectId, + Integer targetLsfxProjectId, Integer newBatchId) { + CcdiBankStatement targetStatement = new CcdiBankStatement(); + BeanUtils.copyProperties(sourceStatement, targetStatement); + targetStatement.setBankStatementId(null); + targetStatement.setProjectId(targetProjectId); + targetStatement.setGroupId(targetLsfxProjectId); + targetStatement.setBatchId(newBatchId); + normalizeDedupFields(targetStatement); + return targetStatement; + } + + private CcdiFileUploadRecord buildHistoryImportRecord(CcdiFileUploadRecord sourceRecord, Long targetProjectId, + Integer targetLsfxProjectId, Integer newBatchId, + String sourceProjectName, String operator) { + CcdiFileUploadRecord record = new CcdiFileUploadRecord(); + record.setProjectId(targetProjectId); + record.setLsfxProjectId(targetLsfxProjectId); + record.setLogId(newBatchId); + record.setFileName(sourceRecord.getFileName()); + record.setFileSize(sourceRecord.getFileSize()); + record.setFileStatus("parsed_success"); + record.setEnterpriseNames(sourceRecord.getEnterpriseNames()); + record.setAccountNos(sourceRecord.getAccountNos()); + record.setUploadTime(new Date()); + record.setUploadUser(operator); + record.setSourceType("HISTORY_IMPORT"); + record.setSourceProjectId(sourceRecord.getProjectId()); + record.setSourceProjectName(sourceProjectName); + return record; + } + + private String resolveSourceProjectName(Long sourceProjectId) { + CcdiProject sourceProject = projectMapper.selectById(sourceProjectId); + return sourceProject == null ? null : sourceProject.getProjectName(); + } + + private void normalizeDedupFields(CcdiBankStatement statement) { + statement.setLeAccountNo(trimToNull(statement.getLeAccountNo())); + } + + private String trimToNull(String value) { + if (value == null) { + return null; + } + String trimmed = value.trim(); + return trimmed.isEmpty() ? null : trimmed; + } + + private String buildDedupKey(CcdiBankStatement statement) { + return String.join("|", + valueOf(statement.getTrxDate()), + valueOf(statement.getCurrency()), + valueOf(statement.getLeAccountNo()), + valueOf(statement.getLeAccountName()), + valueOf(statement.getAccountId()), + valueOf(statement.getCustomerAccountName()), + valueOf(statement.getCustomerAccountNo()), + valueOf(statement.getCustomerBank()), + valueOf(statement.getCustomerReference()), + valueOf(statement.getCustomerCertNo()), + valueOf(statement.getCustomerSocialCreditCode()), + valueOf(statement.getAmountDr()), + valueOf(statement.getAmountCr()), + valueOf(statement.getAmountBalance()), + valueOf(statement.getCashType()), + valueOf(statement.getUserMemo()), + valueOf(statement.getBankComments()), + valueOf(statement.getBankTrxNumber()), + valueOf(statement.getBank()), + valueOf(statement.getTrxFlag()), + valueOf(statement.getTrxType()), + valueOf(statement.getExceptionType()), + valueOf(statement.getInternalFlag()), + valueOf(statement.getCreateDate()), + valueOf(statement.getPaymentMethod()), + valueOf(statement.getCretNo()) + ); + } + + private String valueOf(Object value) { + return Objects.toString(value, ""); } } diff --git a/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiBankStatementMapper.xml b/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiBankStatementMapper.xml index 2bc53df8..a19d2c8c 100644 --- a/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiBankStatementMapper.xml +++ b/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiBankStatementMapper.xml @@ -299,6 +299,33 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" + + + + where project_id in + + #{projectId} + + and file_status = 'parsed_success' + and log_id is not null + order by project_id asc, log_id asc, id asc + +