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