From c8d45416cfda4975bb590cf79bf36edb1d202c5c Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Tue, 31 Mar 2026 21:02:00 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E5=BC=82=E5=B8=B8=E8=B4=A6?= =?UTF-8?q?=E6=88=B7=E4=BA=BA=E5=91=98=E6=9C=8D=E5=8A=A1=E6=98=A0=E5=B0=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../service/ICcdiProjectOverviewService.java | 11 ++ .../impl/CcdiProjectOverviewServiceImpl.java | 48 ++++++ ...ectOverviewServiceAbnormalAccountTest.java | 148 ++++++++++++++++++ 3 files changed, 207 insertions(+) create mode 100644 ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceAbnormalAccountTest.java diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectOverviewService.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectOverviewService.java index 11c0aef4..854906b4 100644 --- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectOverviewService.java +++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/ICcdiProjectOverviewService.java @@ -6,6 +6,7 @@ import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO; import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskPeopleQueryDTO; import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO; +import com.ruoyi.ccdi.project.domain.excel.CcdiProjectAbnormalAccountExcel; import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel; import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel; import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel; @@ -158,6 +159,16 @@ public interface ICcdiProjectOverviewService { return new CcdiProjectAbnormalAccountPageVO(); } + /** + * 导出异常账户人员信息 + * + * @param projectId 项目ID + * @return 导出列表 + */ + default List exportAbnormalAccountPeople(Long projectId) { + return List.of(); + } + /** * 重算结果总览员工结果并同步项目风险人数 * diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImpl.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImpl.java index 9e9e10b4..26d9ae03 100644 --- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImpl.java +++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceImpl.java @@ -2,15 +2,19 @@ package com.ruoyi.ccdi.project.service.impl; import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.ruoyi.ccdi.project.domain.CcdiProject; +import com.ruoyi.ccdi.project.domain.dto.CcdiProjectAbnormalAccountQueryDTO; import com.ruoyi.ccdi.project.domain.dto.CcdiProjectEmployeeCreditNegativeQueryDTO; import com.ruoyi.ccdi.project.domain.dto.CcdiProjectPersonAnalysisDetailQueryDTO; import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskModelPeopleQueryDTO; import com.ruoyi.ccdi.project.domain.dto.CcdiProjectRiskPeopleQueryDTO; import com.ruoyi.ccdi.project.domain.dto.CcdiProjectSuspiciousTransactionQueryDTO; +import com.ruoyi.ccdi.project.domain.excel.CcdiProjectAbnormalAccountExcel; import com.ruoyi.ccdi.project.domain.excel.CcdiProjectEmployeeCreditNegativeExcel; import com.ruoyi.ccdi.project.domain.excel.CcdiProjectRiskPeopleOverviewExcel; import com.ruoyi.ccdi.project.domain.excel.CcdiProjectSuspiciousTransactionExcel; import com.ruoyi.ccdi.project.domain.entity.CcdiProjectOverviewEmployeeResult; +import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountItemVO; +import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountPageVO; import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementListVO; import com.ruoyi.ccdi.project.domain.vo.CcdiBankStatementHitTagVO; import com.ruoyi.ccdi.project.domain.vo.CcdiProjectEmployeeCreditNegativeItemVO; @@ -258,6 +262,31 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi return result; } + @Override + public CcdiProjectAbnormalAccountPageVO getAbnormalAccountPeople(CcdiProjectAbnormalAccountQueryDTO queryDTO) { + ensureProjectExists(queryDTO.getProjectId()); + + Page page = new Page<>( + defaultAbnormalAccountPageNum(queryDTO.getPageNum()), + defaultAbnormalAccountPageSize(queryDTO.getPageSize()) + ); + Page resultPage = overviewMapper.selectAbnormalAccountPage(page, queryDTO); + + CcdiProjectAbnormalAccountPageVO result = new CcdiProjectAbnormalAccountPageVO(); + result.setRows(defaultList(resultPage == null ? null : resultPage.getRecords())); + result.setTotal(resultPage == null ? 0L : resultPage.getTotal()); + return result; + } + + @Override + public List exportAbnormalAccountPeople(Long projectId) { + ensureProjectExists(projectId); + + return defaultList(overviewMapper.selectAbnormalAccountList(projectId)).stream() + .map(this::buildAbnormalAccountExcelRow) + .toList(); + } + @Override public void exportRiskDetails(HttpServletResponse response, Long projectId) { CcdiProjectSuspiciousTransactionQueryDTO queryDTO = new CcdiProjectSuspiciousTransactionQueryDTO(); @@ -420,6 +449,14 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi return pageSize == null || pageSize <= 0 ? 5L : pageSize.longValue(); } + private long defaultAbnormalAccountPageNum(Integer pageNum) { + return pageNum == null || pageNum <= 0 ? 1L : pageNum.longValue(); + } + + private long defaultAbnormalAccountPageSize(Integer pageSize) { + return pageSize == null || pageSize <= 0 ? 5L : pageSize.longValue(); + } + private long defaultPageNum(Integer pageNum) { return pageNum == null || pageNum < 1 ? 1L : pageNum.longValue(); } @@ -462,6 +499,17 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi return row; } + private CcdiProjectAbnormalAccountExcel buildAbnormalAccountExcelRow(CcdiProjectAbnormalAccountItemVO item) { + CcdiProjectAbnormalAccountExcel row = new CcdiProjectAbnormalAccountExcel(); + row.setAccountNo(item.getAccountNo()); + row.setAccountName(item.getAccountName()); + row.setBankName(item.getBankName()); + row.setAbnormalType(item.getAbnormalType()); + row.setAbnormalTime(item.getAbnormalTime()); + row.setStatus(item.getStatus()); + return row; + } + private String formatRelatedStaff(String relatedStaffName, String relatedStaffCode) { if (relatedStaffName == null || relatedStaffName.isBlank()) { return null; diff --git a/ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceAbnormalAccountTest.java b/ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceAbnormalAccountTest.java new file mode 100644 index 00000000..b06fc1c2 --- /dev/null +++ b/ccdi-project/src/test/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewServiceAbnormalAccountTest.java @@ -0,0 +1,148 @@ +package com.ruoyi.ccdi.project.service.impl; + +import com.baomidou.mybatisplus.extension.plugins.pagination.Page; +import com.ruoyi.ccdi.project.domain.CcdiProject; +import com.ruoyi.ccdi.project.domain.dto.CcdiProjectAbnormalAccountQueryDTO; +import com.ruoyi.ccdi.project.domain.excel.CcdiProjectAbnormalAccountExcel; +import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountItemVO; +import com.ruoyi.ccdi.project.domain.vo.CcdiProjectAbnormalAccountPageVO; +import com.ruoyi.ccdi.project.mapper.CcdiBankTagResultMapper; +import com.ruoyi.ccdi.project.mapper.CcdiProjectMapper; +import com.ruoyi.ccdi.project.mapper.CcdiProjectOverviewEmployeeResultMapper; +import com.ruoyi.ccdi.project.mapper.CcdiProjectOverviewMapper; +import com.ruoyi.common.exception.ServiceException; +import java.util.List; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertThrows; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.argThat; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +@ExtendWith(MockitoExtension.class) +class CcdiProjectOverviewServiceAbnormalAccountTest { + + @InjectMocks + private CcdiProjectOverviewServiceImpl service; + + @Mock + private CcdiProjectOverviewMapper overviewMapper; + + @Mock + private CcdiProjectMapper projectMapper; + + @Mock + private CcdiProjectOverviewEmployeeResultMapper overviewEmployeeResultMapper; + + @Mock + private CcdiBankTagResultMapper bankTagResultMapper; + + @Mock + private CcdiProjectOverviewEmployeeResultBuilder overviewEmployeeResultBuilder; + + @Mock + private CcdiProjectRiskDetailWorkbookExporter workbookExporter; + + @Test + void shouldMapAbnormalAccountPageRowsAndTotal() { + mockProjectExists(40L); + + CcdiProjectAbnormalAccountQueryDTO queryDTO = new CcdiProjectAbnormalAccountQueryDTO(); + queryDTO.setProjectId(40L); + queryDTO.setPageNum(1); + queryDTO.setPageSize(5); + + CcdiProjectAbnormalAccountItemVO item = new CcdiProjectAbnormalAccountItemVO(); + item.setAccountNo("6222000000000001"); + item.setAccountName("李四"); + item.setBankName("中国农业银行"); + item.setAbnormalType("突然销户"); + item.setAbnormalTime("2026-03-20"); + item.setStatus("已销户"); + + Page resultPage = new Page<>(1, 5); + resultPage.setRecords(List.of(item)); + resultPage.setTotal(1L); + when(overviewMapper.selectAbnormalAccountPage(any(Page.class), any(CcdiProjectAbnormalAccountQueryDTO.class))) + .thenReturn(resultPage); + + CcdiProjectAbnormalAccountPageVO result = service.getAbnormalAccountPeople(queryDTO); + + assertEquals(1, result.getRows().size()); + assertEquals(1L, result.getTotal()); + assertEquals("6222000000000001", result.getRows().getFirst().getAccountNo()); + assertEquals("突然销户", result.getRows().getFirst().getAbnormalType()); + verify(overviewMapper).selectAbnormalAccountPage( + argThat(page -> page.getCurrent() == 1L && page.getSize() == 5L), + argThat(query -> query.getProjectId().equals(40L)) + ); + } + + @Test + void shouldDefaultAbnormalAccountPageNumAndPageSizeToOneAndFive() { + mockProjectExists(40L); + + Page emptyPage = new Page<>(1, 5); + emptyPage.setRecords(List.of()); + emptyPage.setTotal(0L); + when(overviewMapper.selectAbnormalAccountPage(any(Page.class), any(CcdiProjectAbnormalAccountQueryDTO.class))) + .thenReturn(emptyPage); + + CcdiProjectAbnormalAccountQueryDTO queryDTO = new CcdiProjectAbnormalAccountQueryDTO(); + queryDTO.setProjectId(40L); + service.getAbnormalAccountPeople(queryDTO); + + verify(overviewMapper).selectAbnormalAccountPage( + argThat(page -> page.getCurrent() == 1L && page.getSize() == 5L), + any(CcdiProjectAbnormalAccountQueryDTO.class) + ); + } + + @Test + void shouldExportAbnormalAccountPeopleRows() { + mockProjectExists(40L); + + CcdiProjectAbnormalAccountItemVO item = new CcdiProjectAbnormalAccountItemVO(); + item.setAccountNo("6222000000000002"); + item.setAccountName("王五"); + item.setBankName("中国银行"); + item.setAbnormalType("休眠账户大额启用"); + item.setAbnormalTime("2025-08-01"); + item.setStatus("正常"); + when(overviewMapper.selectAbnormalAccountList(40L)).thenReturn(List.of(item)); + + List rows = service.exportAbnormalAccountPeople(40L); + + assertEquals(1, rows.size()); + assertEquals("6222000000000002", rows.getFirst().getAccountNo()); + assertEquals("王五", rows.getFirst().getAccountName()); + assertEquals("中国银行", rows.getFirst().getBankName()); + assertEquals("休眠账户大额启用", rows.getFirst().getAbnormalType()); + assertEquals("2025-08-01", rows.getFirst().getAbnormalTime()); + assertEquals("正常", rows.getFirst().getStatus()); + verify(overviewMapper).selectAbnormalAccountList(40L); + } + + @Test + void shouldThrowWhenProjectDoesNotExistForAbnormalAccountQueries() { + when(projectMapper.selectById(99L)).thenReturn(null); + + CcdiProjectAbnormalAccountQueryDTO queryDTO = new CcdiProjectAbnormalAccountQueryDTO(); + queryDTO.setProjectId(99L); + + assertThrows(ServiceException.class, () -> service.getAbnormalAccountPeople(queryDTO)); + assertThrows(ServiceException.class, () -> service.exportAbnormalAccountPeople(99L)); + } + + private void mockProjectExists(Long projectId) { + CcdiProject project = new CcdiProject(); + project.setProjectId(projectId); + when(projectMapper.selectById(projectId)).thenReturn(project); + } +}