修复历史项目导入解环与流水查询SQL
This commit is contained in:
@@ -0,0 +1,38 @@
|
||||
package com.ruoyi.ccdi.project.domain.event;
|
||||
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectImportHistoryDTO;
|
||||
|
||||
/**
|
||||
* 历史项目导入提交事件
|
||||
*/
|
||||
public class CcdiProjectHistoryImportSubmittedEvent {
|
||||
|
||||
private final Long targetProjectId;
|
||||
private final Integer targetLsfxProjectId;
|
||||
private final CcdiProjectImportHistoryDTO dto;
|
||||
private final String operator;
|
||||
|
||||
public CcdiProjectHistoryImportSubmittedEvent(Long targetProjectId, Integer targetLsfxProjectId,
|
||||
CcdiProjectImportHistoryDTO dto, String operator) {
|
||||
this.targetProjectId = targetProjectId;
|
||||
this.targetLsfxProjectId = targetLsfxProjectId;
|
||||
this.dto = dto;
|
||||
this.operator = operator;
|
||||
}
|
||||
|
||||
public Long getTargetProjectId() {
|
||||
return targetProjectId;
|
||||
}
|
||||
|
||||
public Integer getTargetLsfxProjectId() {
|
||||
return targetLsfxProjectId;
|
||||
}
|
||||
|
||||
public CcdiProjectImportHistoryDTO getDto() {
|
||||
return dto;
|
||||
}
|
||||
|
||||
public String getOperator() {
|
||||
return operator;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
package com.ruoyi.ccdi.project.service.impl;
|
||||
|
||||
import com.ruoyi.ccdi.project.domain.event.CcdiProjectHistoryImportSubmittedEvent;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectHistoryImportService;
|
||||
import jakarta.annotation.Resource;
|
||||
import org.springframework.context.event.EventListener;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
/**
|
||||
* 历史项目导入事件监听器
|
||||
*/
|
||||
@Component
|
||||
public class CcdiProjectHistoryImportEventListener {
|
||||
|
||||
@Resource
|
||||
private ICcdiProjectHistoryImportService historyImportService;
|
||||
|
||||
@EventListener
|
||||
public void onSubmitted(CcdiProjectHistoryImportSubmittedEvent event) {
|
||||
historyImportService.submitImport(
|
||||
event.getTargetProjectId(),
|
||||
event.getTargetLsfxProjectId(),
|
||||
event.getDto(),
|
||||
event.getOperator()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -7,11 +7,11 @@ import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectImportHistoryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectQueryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSaveDTO;
|
||||
import com.ruoyi.ccdi.project.domain.event.CcdiProjectHistoryImportSubmittedEvent;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectHistoryListItemVO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectStatusCountsVO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectVO;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectHistoryImportService;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectService;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.lsfx.client.LsfxAnalysisClient;
|
||||
@@ -20,6 +20,7 @@ import com.ruoyi.lsfx.domain.response.GetTokenResponse;
|
||||
import jakarta.annotation.Resource;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.transaction.support.TransactionSynchronization;
|
||||
@@ -46,7 +47,7 @@ public class CcdiProjectServiceImpl implements ICcdiProjectService {
|
||||
private LsfxAnalysisClient lsfxAnalysisClient;
|
||||
|
||||
@Resource
|
||||
private ICcdiProjectHistoryImportService historyImportService;
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
@Override
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@@ -139,7 +140,9 @@ public class CcdiProjectServiceImpl implements ICcdiProjectService {
|
||||
TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {
|
||||
@Override
|
||||
public void afterCommit() {
|
||||
historyImportService.submitImport(project.getProjectId(), project.getLsfxProjectId(), dto, operator);
|
||||
applicationEventPublisher.publishEvent(
|
||||
new CcdiProjectHistoryImportSubmittedEvent(project.getProjectId(), project.getLsfxProjectId(), dto, operator)
|
||||
);
|
||||
}
|
||||
});
|
||||
return project;
|
||||
|
||||
@@ -49,16 +49,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
</resultMap>
|
||||
|
||||
<sql id="selectCcdiBankStatementVo">
|
||||
select bank_statement_id, project_id, LE_ID, ACCOUNT_ID, group_id,
|
||||
LE_ACCOUNT_NAME, LE_ACCOUNT_NO, ACCOUNTING_DATE_ID, ACCOUNTING_DATE,
|
||||
TRX_DATE, CURRENCY, AMOUNT_DR, AMOUNT_CR, AMOUNT_BALANCE,
|
||||
CASH_TYPE, CUSTOMER_LE_ID, CUSTOMER_ACCOUNT_NAME, CUSTOMER_ACCOUNT_NO,
|
||||
customer_bank, customer_reference, customer_cert_no, customer_social_credit_code, USER_MEMO, BANK_COMMENTS,
|
||||
BANK_TRX_NUMBER, BANK, TRX_FLAG, TRX_TYPE, EXCEPTION_TYPE,
|
||||
internal_flag, batch_id, batch_sequence, CREATE_DATE, created_by,
|
||||
meta_json, no_balance, begin_balance, end_balance,
|
||||
override_bs_id, payment_method, cret_no
|
||||
from ccdi_bank_statement
|
||||
bank_statement_id, project_id, LE_ID, ACCOUNT_ID, group_id,
|
||||
LE_ACCOUNT_NAME, LE_ACCOUNT_NO, ACCOUNTING_DATE_ID, ACCOUNTING_DATE,
|
||||
TRX_DATE, CURRENCY, AMOUNT_DR, AMOUNT_CR, AMOUNT_BALANCE,
|
||||
CASH_TYPE, CUSTOMER_LE_ID, CUSTOMER_ACCOUNT_NAME, CUSTOMER_ACCOUNT_NO,
|
||||
customer_bank, customer_reference, customer_cert_no, customer_social_credit_code, USER_MEMO, BANK_COMMENTS,
|
||||
BANK_TRX_NUMBER, BANK, TRX_FLAG, TRX_TYPE, EXCEPTION_TYPE,
|
||||
internal_flag, batch_id, batch_sequence, CREATE_DATE, created_by,
|
||||
meta_json, no_balance, begin_balance, end_balance,
|
||||
override_bs_id, payment_method, cret_no
|
||||
</sql>
|
||||
|
||||
<resultMap id="CcdiBankStatementListVOResultMap" type="com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO">
|
||||
@@ -304,8 +303,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||
<include refid="selectCcdiBankStatementVo"/>
|
||||
FROM ccdi_bank_statement bs
|
||||
<where>
|
||||
bs.project_id = #{projectId}
|
||||
AND bs.batch_id = #{batchId}
|
||||
(bs.project_id = #{projectId})
|
||||
AND (bs.batch_id = #{batchId})
|
||||
<if test="startDate != null and startDate != ''">
|
||||
AND (<include refid="parsedTrxDateExpr"/>) <![CDATA[ >= ]]>
|
||||
CASE
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.io.InputStream;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
@@ -172,6 +173,27 @@ class CcdiBankStatementMapperXmlTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void selectStatementsForHistoryImport_shouldNotGenerateDuplicatedSelectKeyword() throws Exception {
|
||||
MappedStatement mappedStatement = loadMappedStatement(
|
||||
"com.ruoyi.ccdi.project.mapper.CcdiBankStatementMapper.selectStatementsForHistoryImport");
|
||||
|
||||
Map<String, Object> params = new HashMap<>();
|
||||
params.put("projectId", 48L);
|
||||
params.put("batchId", 17094);
|
||||
params.put("startDate", "2026-03-17");
|
||||
params.put("endDate", "2026-03-18");
|
||||
|
||||
BoundSql boundSql = mappedStatement.getBoundSql(params);
|
||||
String sql = boundSql.getSql().replaceAll("\\s+", " ").trim();
|
||||
|
||||
assertFalse(sql.startsWith("SELECT select"), sql);
|
||||
assertTrue(sql.startsWith("SELECT bank_statement_id"), sql);
|
||||
assertFalse(sql.contains("FROM ccdi_bank_statement FROM ccdi_bank_statement"), sql);
|
||||
assertFalse(sql.contains("?AND"), sql);
|
||||
assertTrue(sql.contains("WHERE (bs.project_id = ?) AND (bs.batch_id = ?) AND ( CASE"), sql);
|
||||
}
|
||||
|
||||
@Test
|
||||
void insertBatch_shouldAvoidUpdatingAutoIncrementPrimaryKeyInDuplicateBranch() throws Exception {
|
||||
try (InputStream inputStream = getClass().getClassLoader().getResourceAsStream(RESOURCE)) {
|
||||
|
||||
@@ -7,20 +7,22 @@ import com.ruoyi.ccdi.project.domain.CcdiProject;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectImportHistoryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectQueryDTO;
|
||||
import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSaveDTO;
|
||||
import com.ruoyi.ccdi.project.domain.event.CcdiProjectHistoryImportSubmittedEvent;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectHistoryListItemVO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectStatusCountsVO;
|
||||
import com.ruoyi.ccdi.project.domain.vo.CcdiProjectVO;
|
||||
import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper;
|
||||
import com.ruoyi.ccdi.project.service.ICcdiProjectHistoryImportService;
|
||||
import com.ruoyi.common.exception.ServiceException;
|
||||
import com.ruoyi.lsfx.client.LsfxAnalysisClient;
|
||||
import com.ruoyi.lsfx.domain.response.GetTokenResponse;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.junit.jupiter.api.extension.ExtendWith;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.InjectMocks;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.context.ApplicationEventPublisher;
|
||||
import org.springframework.transaction.support.TransactionSynchronizationManager;
|
||||
|
||||
import java.util.List;
|
||||
@@ -31,7 +33,6 @@ import static org.junit.jupiter.api.Assertions.assertNotNull;
|
||||
import static org.junit.jupiter.api.Assertions.assertThrows;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyString;
|
||||
import static org.mockito.Mockito.doAnswer;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -50,7 +51,7 @@ class CcdiProjectServiceImplTest {
|
||||
private LsfxAnalysisClient lsfxAnalysisClient;
|
||||
|
||||
@Mock
|
||||
private ICcdiProjectHistoryImportService historyImportService;
|
||||
private ApplicationEventPublisher applicationEventPublisher;
|
||||
|
||||
@Test
|
||||
void shouldCountTaggingProjectsSeparately() {
|
||||
@@ -143,7 +144,7 @@ class CcdiProjectServiceImplTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldCreateProjectThenSubmitHistoryImportAfterCommit() {
|
||||
void shouldCreateProjectThenPublishHistoryImportEventAfterCommit() {
|
||||
CcdiProjectImportHistoryDTO dto = new CcdiProjectImportHistoryDTO();
|
||||
dto.setProjectName("新项目");
|
||||
dto.setDescription("从历史导入");
|
||||
@@ -165,11 +166,18 @@ class CcdiProjectServiceImplTest {
|
||||
assertNotNull(project);
|
||||
assertEquals(90L, project.getProjectId());
|
||||
assertEquals(1, TransactionSynchronizationManager.getSynchronizations().size());
|
||||
verify(historyImportService, never()).submitImport(any(), any(), any(), anyString());
|
||||
verify(applicationEventPublisher, never()).publishEvent(any());
|
||||
|
||||
TransactionSynchronizationManager.getSynchronizations().forEach(sync -> sync.afterCommit());
|
||||
|
||||
verify(historyImportService).submitImport(90L, 3001, dto, "tester");
|
||||
ArgumentCaptor<Object> eventCaptor = ArgumentCaptor.forClass(Object.class);
|
||||
verify(applicationEventPublisher).publishEvent(eventCaptor.capture());
|
||||
CcdiProjectHistoryImportSubmittedEvent event =
|
||||
(CcdiProjectHistoryImportSubmittedEvent) eventCaptor.getValue();
|
||||
assertEquals(90L, event.getTargetProjectId());
|
||||
assertEquals(3001, event.getTargetLsfxProjectId());
|
||||
assertEquals("tester", event.getOperator());
|
||||
assertEquals(dto, event.getDto());
|
||||
} finally {
|
||||
TransactionSynchronizationManager.clearSynchronization();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user