实现流水明细查询服务层规范化逻辑

This commit is contained in:
wkc
2026-03-10 16:10:25 +08:00
parent cfc3545fc7
commit 1c607c0b2d
3 changed files with 163 additions and 0 deletions

View File

@@ -1,6 +1,9 @@
package com.ruoyi.ccdi.project.service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.project.domain.dto.CcdiBankStatementQueryDTO;
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementFilterOptionsVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
/**
* 流水明细查询Service接口
@@ -16,4 +19,14 @@ public interface ICcdiBankStatementService {
* @return 筛选项
*/
CcdiBankStatementFilterOptionsVO getFilterOptions(Long projectId);
/**
* 分页查询流水明细
*
* @param page 分页对象
* @param queryDTO 查询条件
* @return 分页结果
*/
Page<CcdiBankStatementListVO> selectStatementPage(Page<CcdiBankStatementListVO> page,
CcdiBankStatementQueryDTO queryDTO);
}

View File

@@ -0,0 +1,112 @@
package com.ruoyi.ccdi.project.service.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.ccdi.project.domain.dto.CcdiBankStatementQueryDTO;
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementFilterOptionsVO;
import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO;
import com.ruoyi.ccdi.project.mapper.CcdiBankStatementMapper;
import com.ruoyi.ccdi.project.service.ICcdiBankStatementService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Collectors;
/**
* 流水明细查询Service实现
*
* @author ruoyi
*/
@Service
public class CcdiBankStatementServiceImpl implements ICcdiBankStatementService {
private static final Set<String> ALLOWED_TAB_TYPES = Set.of("all", "in", "out");
private static final Set<String> ALLOWED_ORDER_DIRECTIONS = Set.of("asc", "desc");
@Resource
private CcdiBankStatementMapper bankStatementMapper;
@Override
public CcdiBankStatementFilterOptionsVO getFilterOptions(Long projectId) {
CcdiBankStatementFilterOptionsVO options = bankStatementMapper.selectFilterOptions(projectId);
return options == null ? new CcdiBankStatementFilterOptionsVO() : options;
}
@Override
public Page<CcdiBankStatementListVO> selectStatementPage(Page<CcdiBankStatementListVO> page,
CcdiBankStatementQueryDTO queryDTO) {
CcdiBankStatementQueryDTO normalizedQuery = queryDTO == null ? new CcdiBankStatementQueryDTO() : queryDTO;
normalizeQuery(normalizedQuery);
return bankStatementMapper.selectStatementPage(page, normalizedQuery);
}
private void normalizeQuery(CcdiBankStatementQueryDTO queryDTO) {
queryDTO.setTransactionStartTime(normalizeText(queryDTO.getTransactionStartTime()));
queryDTO.setTransactionEndTime(normalizeText(queryDTO.getTransactionEndTime()));
queryDTO.setCounterpartyName(normalizeText(queryDTO.getCounterpartyName()));
queryDTO.setUserMemo(normalizeText(queryDTO.getUserMemo()));
queryDTO.setCounterpartyAccount(normalizeText(queryDTO.getCounterpartyAccount()));
queryDTO.setTransactionType(normalizeText(queryDTO.getTransactionType()));
queryDTO.setOurSubjects(normalizeList(queryDTO.getOurSubjects()));
queryDTO.setOurBanks(normalizeList(queryDTO.getOurBanks()));
queryDTO.setOurAccounts(normalizeList(queryDTO.getOurAccounts()));
queryDTO.setCounterpartyNameEmpty(Boolean.TRUE.equals(queryDTO.getCounterpartyNameEmpty()));
queryDTO.setUserMemoEmpty(Boolean.TRUE.equals(queryDTO.getUserMemoEmpty()));
queryDTO.setCounterpartyAccountEmpty(Boolean.TRUE.equals(queryDTO.getCounterpartyAccountEmpty()));
queryDTO.setTransactionTypeEmpty(Boolean.TRUE.equals(queryDTO.getTransactionTypeEmpty()));
queryDTO.setTabType(normalizeTabType(queryDTO.getTabType()));
queryDTO.setOrderBy(normalizeOrderBy(queryDTO.getOrderBy()));
queryDTO.setOrderDirection(normalizeOrderDirection(queryDTO.getOrderDirection()));
}
private String normalizeTabType(String tabType) {
String normalized = normalizeLowerCase(tabType);
return normalized != null && ALLOWED_TAB_TYPES.contains(normalized) ? normalized : "all";
}
private String normalizeOrderBy(String orderBy) {
String normalized = normalizeText(orderBy);
if (normalized == null) {
return "trxDate";
}
if ("amount".equalsIgnoreCase(normalized)) {
return "amount";
}
if ("trxDate".equalsIgnoreCase(normalized)) {
return "trxDate";
}
return "trxDate";
}
private String normalizeOrderDirection(String orderDirection) {
String normalized = normalizeLowerCase(orderDirection);
return normalized != null && ALLOWED_ORDER_DIRECTIONS.contains(normalized) ? normalized : "desc";
}
private String normalizeLowerCase(String value) {
String normalized = normalizeText(value);
return normalized == null ? null : normalized.toLowerCase(Locale.ROOT);
}
private String normalizeText(String value) {
if (value == null) {
return null;
}
String trimmed = value.trim();
return trimmed.isEmpty() ? null : trimmed;
}
private List<String> normalizeList(List<String> values) {
if (values == null || values.isEmpty()) {
return null;
}
List<String> normalized = values.stream()
.map(this::normalizeText)
.filter(item -> item != null)
.distinct()
.collect(Collectors.toList());
return normalized.isEmpty() ? null : normalized;
}
}

View File

@@ -15,9 +15,11 @@ import org.mockito.junit.jupiter.MockitoExtension;
import java.util.List;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.same;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
@@ -47,9 +49,45 @@ class CcdiBankStatementServiceImplTest {
queryDTO.setProjectId(100L);
queryDTO.setOrderBy("amount");
queryDTO.setOrderDirection("desc");
doReturn(page).when(bankStatementMapper).selectStatementPage(eq(page), same(queryDTO));
service.selectStatementPage(page, queryDTO);
verify(bankStatementMapper).selectStatementPage(eq(page), same(queryDTO));
}
@Test
void normalizeQuery_shouldFallbackToSafeDefaults() {
Page<CcdiBankStatementListVO> page = new Page<>(1, 10);
CcdiBankStatementQueryDTO queryDTO = new CcdiBankStatementQueryDTO();
queryDTO.setProjectId(100L);
queryDTO.setOrderBy("drop table");
queryDTO.setOrderDirection("sideways");
doReturn(page).when(bankStatementMapper).selectStatementPage(eq(page), same(queryDTO));
service.selectStatementPage(page, queryDTO);
assertEquals("trxDate", queryDTO.getOrderBy());
assertEquals("desc", queryDTO.getOrderDirection());
assertEquals("all", queryDTO.getTabType());
}
@Test
void normalizeQuery_shouldTrimBlankStringsToNull() {
Page<CcdiBankStatementListVO> page = new Page<>(1, 10);
CcdiBankStatementQueryDTO queryDTO = new CcdiBankStatementQueryDTO();
queryDTO.setProjectId(100L);
queryDTO.setCounterpartyName(" ");
queryDTO.setUserMemo(" ");
queryDTO.setCounterpartyAccount(" ");
queryDTO.setTransactionType(" ");
doReturn(page).when(bankStatementMapper).selectStatementPage(eq(page), same(queryDTO));
service.selectStatementPage(page, queryDTO);
assertNull(queryDTO.getCounterpartyName());
assertNull(queryDTO.getUserMemo());
assertNull(queryDTO.getCounterpartyAccount());
assertNull(queryDTO.getTransactionType());
}
}