From 657977dfb735cd598389b06812dd0bf414fa7db7 Mon Sep 17 00:00:00 2001 From: wjj <2069666735@qq.com> Date: Mon, 20 Jul 2026 11:13:54 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E5=96=84=E5=BC=82=E5=B8=B8=E8=B4=A6?= =?UTF-8?q?=E6=88=B7=E9=A2=84=E8=AD=A6=E5=8F=A3=E5=BE=84=E5=92=8C=E8=B4=A6?= =?UTF-8?q?=E6=88=B7=E6=9F=A5=E8=AF=A2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../domain/dto/CcdiAccountInfoQueryDTO.java | 4 +++ .../info/collection/CcdiAccountInfoMapper.xml | 3 ++ .../mapper/CcdiAccountInfoMapperTest.java | 12 ++++++++ .../CcdiProjectAbnormalAccountExcel.java | 7 +++++ .../vo/CcdiProjectAbnormalAccountItemVO.java | 5 ++++ .../CcdiProjectOverviewReportPdfExporter.java | 8 ++++-- .../impl/CcdiProjectOverviewServiceImpl.java | 2 ++ ...CcdiProjectRiskDetailWorkbookExporter.java | 4 ++- .../project/CcdiBankTagAnalysisMapper.xml | 16 ++++++++++- .../project/CcdiProjectOverviewMapper.xml | 17 +++++++++-- .../CcdiBankTagAnalysisMapperXmlTest.java | 20 +++++++++++++ .../CcdiProjectOverviewMapperSqlTest.java | 7 +++++ ...iProjectOverviewReportPdfExporterTest.java | 5 ++++ ...ectOverviewServiceAbnormalAccountTest.java | 9 ++++++ .../CcdiProjectOverviewServiceImplTest.java | 7 ++++- ...ProjectRiskDetailWorkbookExporterTest.java | 6 ++++ .../sql/CcdiBankTagRuleSqlMetadataTest.java | 4 +-- ...-result-overview-backend-implementation.md | 24 ++++++++++++++++ ...ccount-no-filter-backend-implementation.md | 22 +++++++++++++++ ...result-overview-frontend-implementation.md | 21 ++++++++++++++ ...count-no-filter-frontend-implementation.md | 21 ++++++++++++++ ...-07-17-abnormal-account-result-overview.md | 28 +++++++++++++++++++ ...26-07-17-account-info-account-no-filter.md | 22 +++++++++++++++ ruoyi-ui/src/views/ccdiAccountInfo/index.vue | 7 +++++ .../components/detail/RiskDetailSection.vue | 4 +++ ...isk-detail-abnormal-account-layout.test.js | 2 ++ ...31-add-abnormal-account-rule-test-data.sql | 2 +- ...ccount-info-and-abnormal-account-rules.sql | 4 +-- ...7-update-abnormal-account-rule-caliber.sql | 7 +++++ 29 files changed, 286 insertions(+), 14 deletions(-) create mode 100644 docs/plans/backend/2026-07-17-abnormal-account-result-overview-backend-implementation.md create mode 100644 docs/plans/backend/2026-07-17-account-info-account-no-filter-backend-implementation.md create mode 100644 docs/plans/frontend/2026-07-17-abnormal-account-result-overview-frontend-implementation.md create mode 100644 docs/plans/frontend/2026-07-17-account-info-account-no-filter-frontend-implementation.md create mode 100644 docs/reports/implementation/2026-07-17-abnormal-account-result-overview.md create mode 100644 docs/reports/implementation/2026-07-17-account-info-account-no-filter.md create mode 100644 sql/migration/2026-07-17-update-abnormal-account-rule-caliber.sql diff --git a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiAccountInfoQueryDTO.java b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiAccountInfoQueryDTO.java index 411aeed7..68f9faa8 100644 --- a/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiAccountInfoQueryDTO.java +++ b/ccdi-info-collection/src/main/java/com/ruoyi/info/collection/domain/dto/CcdiAccountInfoQueryDTO.java @@ -39,6 +39,10 @@ public class CcdiAccountInfoQueryDTO implements Serializable { @Schema(description = "账户姓名") private String accountName; + /** 账户号码 */ + @Schema(description = "账户号码") + private String accountNo; + /** 账户类型 */ @Schema(description = "账户类型") private String accountType; diff --git a/ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiAccountInfoMapper.xml b/ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiAccountInfoMapper.xml index 73bf8a74..d374b77c 100644 --- a/ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiAccountInfoMapper.xml +++ b/ccdi-info-collection/src/main/resources/mapper/info/collection/CcdiAccountInfoMapper.xml @@ -104,6 +104,9 @@ AND ai.account_name LIKE CONCAT('%', #{query.accountName}, '%') + + AND ai.account_no LIKE CONCAT('%', #{query.accountNo}, '%') + AND ai.account_type = #{query.accountType} diff --git a/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiAccountInfoMapperTest.java b/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiAccountInfoMapperTest.java index fe35c8ec..15ce67db 100644 --- a/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiAccountInfoMapperTest.java +++ b/ccdi-info-collection/src/test/java/com/ruoyi/info/collection/mapper/CcdiAccountInfoMapperTest.java @@ -38,6 +38,18 @@ class CcdiAccountInfoMapperTest { assertTrue(sql.contains("ai.owner_type <> 'credit_customer'"), sql); } + @Test + void selectAccountInfoPage_shouldFilterByAccountNo() throws Exception { + MappedStatement mappedStatement = loadMappedStatement( + "com.ruoyi.info.collection.mapper.CcdiAccountInfoMapper.selectAccountInfoPage"); + CcdiAccountInfoQueryDTO queryDTO = new CcdiAccountInfoQueryDTO(); + queryDTO.setAccountNo("6222"); + + String sql = renderSql(mappedStatement, Map.of("query", queryDTO)).toLowerCase(); + + assertTrue(sql.contains("ai.account_no like concat('%', ?, '%')"), sql); + } + private MappedStatement loadMappedStatement(String statementId) throws Exception { Configuration configuration = new Configuration(); configuration.setEnvironment(new Environment("test", new JdbcTransactionFactory(), new NoOpDataSource())); diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/excel/CcdiProjectAbnormalAccountExcel.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/excel/CcdiProjectAbnormalAccountExcel.java index 2d66b217..b161c459 100644 --- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/excel/CcdiProjectAbnormalAccountExcel.java +++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/excel/CcdiProjectAbnormalAccountExcel.java @@ -1,6 +1,7 @@ package com.ruoyi.ccdi.project.domain.excel; import com.ruoyi.common.annotation.Excel; +import java.math.BigDecimal; import lombok.Data; /** @@ -26,4 +27,10 @@ public class CcdiProjectAbnormalAccountExcel { @Excel(name = "状态") private String status; + + @Excel(name = "命中原因") + private String reasonDetail; + + @Excel(name = "涉及金额") + private BigDecimal involvedAmount; } diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectAbnormalAccountItemVO.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectAbnormalAccountItemVO.java index e4ae1f6c..1ca475ae 100644 --- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectAbnormalAccountItemVO.java +++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/domain/vo/CcdiProjectAbnormalAccountItemVO.java @@ -1,5 +1,6 @@ package com.ruoyi.ccdi.project.domain.vo; +import java.math.BigDecimal; import lombok.Data; /** @@ -19,4 +20,8 @@ public class CcdiProjectAbnormalAccountItemVO { private String abnormalTime; private String status; + + private String reasonDetail; + + private BigDecimal involvedAmount; } diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewReportPdfExporter.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewReportPdfExporter.java index a35379af..b599c815 100644 --- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewReportPdfExporter.java +++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectOverviewReportPdfExporter.java @@ -230,7 +230,7 @@ public class CcdiProjectOverviewReportPdfExporter { writer.subsection("3. 异常账户信息表(共" + report.getAbnormalAccounts().size() + "条)"); writer.table( - List.of("账号", "开户人", "银行", "异常类型", "异常发生时间", "状态"), + List.of("账号", "开户人", "银行", "异常类型", "异常发生时间", "状态", "命中原因", "涉及金额"), report.getAbnormalAccounts().stream() .map(item -> List.of( maskAccount(item.getAccountNo()), @@ -238,10 +238,12 @@ public class CcdiProjectOverviewReportPdfExporter { safeText(item.getBankName()), safeText(item.getAbnormalType()), safeText(item.getAbnormalTime()), - safeText(item.getStatus()) + safeText(item.getStatus()), + safeText(item.getReasonDetail()), + formatMoney(item.getInvolvedAmount()) )) .collect(Collectors.toList()), - new float[] { 0.18F, 0.13F, 0.2F, 0.23F, 0.14F, 0.12F }, + new float[] { 0.12F, 0.1F, 0.14F, 0.14F, 0.11F, 0.08F, 0.22F, 0.09F }, "暂无异常账户信息" ); } 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 6e12f7f6..2c2f9b34 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 @@ -905,6 +905,8 @@ public class CcdiProjectOverviewServiceImpl implements ICcdiProjectOverviewServi row.setAbnormalType(item.getAbnormalType()); row.setAbnormalTime(item.getAbnormalTime()); row.setStatus(item.getStatus()); + row.setReasonDetail(item.getReasonDetail()); + row.setInvolvedAmount(item.getInvolvedAmount()); return row; } diff --git a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectRiskDetailWorkbookExporter.java b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectRiskDetailWorkbookExporter.java index e0d581fd..f2a310b3 100644 --- a/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectRiskDetailWorkbookExporter.java +++ b/ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiProjectRiskDetailWorkbookExporter.java @@ -106,7 +106,7 @@ public class CcdiProjectRiskDetailWorkbookExporter { private void writeAbnormalAccountSheet(Sheet sheet, List rows) { Row header = sheet.createRow(0); - String[] headers = { "账号", "开户人", "银行", "异常类型", "异常发生时间", "状态" }; + String[] headers = { "账号", "开户人", "银行", "异常类型", "异常发生时间", "状态", "命中原因", "涉及金额" }; writeHeader(header, headers); for (int i = 0; i < rows.size(); i++) { @@ -118,6 +118,8 @@ public class CcdiProjectRiskDetailWorkbookExporter { row.createCell(3).setCellValue(safeText(item.getAbnormalType())); row.createCell(4).setCellValue(safeText(item.getAbnormalTime())); row.createCell(5).setCellValue(safeText(item.getStatus())); + row.createCell(6).setCellValue(safeText(item.getReasonDetail())); + row.createCell(7).setCellValue(safeNumber(item.getInvolvedAmount())); } } diff --git a/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiBankTagAnalysisMapper.xml b/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiBankTagAnalysisMapper.xml index 47724c9f..5cd27560 100644 --- a/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiBankTagAnalysisMapper.xml +++ b/ccdi-project/src/main/resources/mapper/ccdi/project/CcdiBankTagAnalysisMapper.xml @@ -1730,6 +1730,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" and tx.txDate < ai.invalid_date group by staff.id_card, ai.account_no, ai.invalid_date ) t + where t.windowTotalAmount >= 500000 + or t.windowMaxSingleAmount >= 100000