Compare commits

3 Commits

Author SHA1 Message Date
wkc
ce66dc3ba8 项目上传删除暂不调用流水分析平台 2026-06-26 15:19:23 +08:00
wkc
f3c1e2ea93 移除风险模型导出按钮 2026-06-26 15:18:46 +08:00
wkc
87b2352001 为风险明细列表添加分页选择器 2026-06-26 15:16:30 +08:00
9 changed files with 108 additions and 30 deletions

View File

@@ -226,15 +226,18 @@ public class CcdiFileUploadServiceImpl implements ICcdiFileUploadService {
CcdiFileUploadRecord record = recordMapper.selectById(id);
validateDeleteRecord(record);
DeleteFilesRequest request = new DeleteFilesRequest();
request.setGroupId(record.getLsfxProjectId());
request.setLogIds(new Integer[]{record.getLogId()});
request.setUserId(toUploadUserId(operatorUserId));
DeleteFilesResponse response = lsfxClient.deleteFiles(request);
if (response == null || Boolean.FALSE.equals(response.getSuccessResponse())) {
throw new RuntimeException("流水分析平台删除文件失败");
}
/*
* 按当前要求,项目管理-上传数据页面删除时先不调用流水分析平台删除接口。
* DeleteFilesRequest request = new DeleteFilesRequest();
* request.setGroupId(record.getLsfxProjectId());
* request.setLogIds(new Integer[]{record.getLogId()});
* request.setUserId(toUploadUserId(operatorUserId));
*
* DeleteFilesResponse response = lsfxClient.deleteFiles(request);
* if (response == null || Boolean.FALSE.equals(response.getSuccessResponse())) {
* throw new RuntimeException("流水分析平台删除文件失败");
* }
*/
bankStatementMapper.deleteByProjectIdAndBatchId(record.getProjectId(), record.getLogId());
refreshProjectTargetCount(record.getProjectId());

View File

@@ -0,0 +1,22 @@
# 项目上传数据删除暂不调用流水分析平台实施记录
## 修改背景
项目管理-上传数据页面点击删除后,当前阶段要求后端先不调用流水分析平台删除文件接口。
## 修改内容
- 调整 `ccdi-project/src/main/java/com/ruoyi/ccdi/project/service/impl/CcdiFileUploadServiceImpl.java`
-`deleteFileUploadRecord` 方法中注释 `DeleteFilesRequest` 构造、`lsfxClient.deleteFiles(request)` 调用以及平台删除失败判断。
- 保留本地删除后续逻辑:删除本地银行流水记录、刷新项目目标人数、更新上传记录状态为 `deleted`、触发项目重新打标。
## 影响范围
- 仅影响项目管理-上传数据页面按记录删除上传文件时的后端处理链路。
- 不影响流水分析平台客户端 `LsfxAnalysisClient.deleteFiles` 本身,也不影响测试 Controller 中直接调用流水分析删除接口的能力。
- 删除操作不再依赖流水分析平台删除接口返回结果,本地记录删除与重新打标逻辑保持原有执行顺序。
## 验证情况
- 已执行 `mvn -pl ccdi-project -am -DskipTests compile`,编译通过。
- 本次为后端链路调整,未改动前端页面。

View File

@@ -0,0 +1,25 @@
# 风险明细列表分页选择器实施记录
## 保存路径确认
- 本实施记录保存于 `docs/reports/implementation/`,符合项目实施记录目录规范。
## 修改内容
-`RiskDetailSection.vue` 中为风险明细卡片内的三个列表统一启用分页条数选择器。
- 新增风险明细列表共享分页选项 `[5, 10, 20, 50]`,首屏默认仍保持每页 5 条。
- 涉疑交易明细、员工负面征信信息、异常账户人员信息翻页或切换每页条数时,均使用当前分页参数重新请求对应接口。
## 影响范围
- 仅影响项目详情结果总览中的风险明细前端展示与分页请求参数。
- 不涉及后端接口、数据库结构、导出逻辑和风险模型计算逻辑。
## 验证情况
- 已通过 `nvm use` 切换到 Node `v14.21.3` 后执行风险明细分页相关前端源码断言测试。
- 已执行 `npm run build:prod`,构建通过,仅保留项目既有资源体积 warning。
- 已在应用内浏览器打开真实项目详情结果总览页面,验证风险明细分页选择器展示与切换:
- `0430test` 项目涉疑交易明细从 `5条/页` 切换为 `10条/页` 后展示 10 行。
- `0430test` 项目异常账户人员信息从 `5条/页` 切换为 `10条/页` 后展示 6 行。
- 验证过程中未发现浏览器控制台错误。

View File

@@ -0,0 +1,14 @@
# 风险模型导出按钮移除实施记录
## 修改内容
- 移除项目详情页“风险模型”模块中“模型预警次数统计”标题右侧的“导出”按钮。
## 影响范围
- 仅调整前端展示层文件:`ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue`
- 不涉及后端接口、数据结构、权限菜单或业务统计逻辑变更。
## 验证情况
- 已执行静态检索确认该模块内目标“导出”按钮已移除。

View File

@@ -120,8 +120,8 @@
:total="suspiciousTotal"
:page.sync="suspiciousPageNum"
:limit.sync="suspiciousPageSize"
:page-sizes="[5]"
layout="total, prev, pager, next, jumper"
:page-sizes="riskDetailPageSizeOptions"
layout="total, sizes, prev, pager, next, jumper"
@pagination="handlePageChange"
/>
</div>
@@ -174,8 +174,8 @@
:total="employeeCreditNegativeTotal"
:page.sync="employeeCreditNegativePageNum"
:limit.sync="employeeCreditNegativePageSize"
:page-sizes="[5]"
layout="total, prev, pager, next, jumper"
:page-sizes="riskDetailPageSizeOptions"
layout="total, sizes, prev, pager, next, jumper"
@pagination="handleEmployeeCreditNegativePageChange"
/>
</div>
@@ -209,8 +209,8 @@
:total="abnormalAccountTotal"
:page.sync="abnormalAccountPageNum"
:limit.sync="abnormalAccountPageSize"
:page-sizes="[5]"
layout="total, prev, pager, next, jumper"
:page-sizes="riskDetailPageSizeOptions"
layout="total, sizes, prev, pager, next, jumper"
@pagination="handleAbnormalAccountPageChange"
/>
</div>
@@ -352,6 +352,8 @@ const SUSPICIOUS_TYPE_OPTIONS = [
{ value: "NAME_LIST", label: "名单库命中" },
{ value: "MODEL_RULE", label: "模型规则命中" },
];
const DEFAULT_RISK_DETAIL_PAGE_SIZE = 5;
const RISK_DETAIL_PAGE_SIZE_OPTIONS = [5, 10, 20, 50];
const normalizeSuspiciousType = (value) => (
SUSPICIOUS_TYPE_OPTIONS.some((item) => item.value === value) ? value : "ALL"
@@ -465,17 +467,17 @@ export default {
detailData: createEmptyDetailData(),
currentSuspiciousType: "ALL",
suspiciousPageNum: 1,
suspiciousPageSize: 5,
suspiciousPageSize: DEFAULT_RISK_DETAIL_PAGE_SIZE,
suspiciousTotal: 0,
suspiciousTransactionList: [],
employeeCreditNegativeLoading: false,
employeeCreditNegativePageNum: 1,
employeeCreditNegativePageSize: 5,
employeeCreditNegativePageSize: DEFAULT_RISK_DETAIL_PAGE_SIZE,
employeeCreditNegativeTotal: 0,
employeeCreditNegativeList: [],
abnormalAccountLoading: false,
abnormalAccountPageNum: 1,
abnormalAccountPageSize: 5,
abnormalAccountPageSize: DEFAULT_RISK_DETAIL_PAGE_SIZE,
abnormalAccountTotal: 0,
abnormalAccountList: [],
projectId: null,
@@ -483,6 +485,9 @@ export default {
};
},
computed: {
riskDetailPageSizeOptions() {
return RISK_DETAIL_PAGE_SIZE_OPTIONS;
},
suspiciousTypeOptions() {
return SUSPICIOUS_TYPE_OPTIONS;
},
@@ -499,13 +504,13 @@ export default {
this.projectId = value && value.projectId ? value.projectId : null;
this.currentSuspiciousType = normalizeSuspiciousType(value && value.suspiciousType);
this.suspiciousPageNum = 1;
this.suspiciousPageSize = 5;
this.suspiciousPageSize = DEFAULT_RISK_DETAIL_PAGE_SIZE;
this.suspiciousTotal = Number(value && value.total) || 0;
this.employeeCreditNegativePageNum = 1;
this.employeeCreditNegativePageSize = 5;
this.employeeCreditNegativePageSize = DEFAULT_RISK_DETAIL_PAGE_SIZE;
this.employeeCreditNegativeTotal = Number(value && value.employeeCreditNegativeTotal) || 0;
this.abnormalAccountPageNum = 1;
this.abnormalAccountPageSize = 5;
this.abnormalAccountPageSize = DEFAULT_RISK_DETAIL_PAGE_SIZE;
this.abnormalAccountTotal = 0;
this.abnormalAccountList = [];
const rows = Array.isArray(value && value.suspiciousTransactionList)
@@ -531,7 +536,7 @@ export default {
this.suspiciousPageNum = pageInfo;
} else {
this.suspiciousPageNum = pageInfo.page;
this.suspiciousPageSize = 5;
this.suspiciousPageSize = pageInfo.limit || this.suspiciousPageSize;
}
await this.loadSuspiciousTransactions();
},
@@ -540,7 +545,7 @@ export default {
this.employeeCreditNegativePageNum = pageInfo;
} else {
this.employeeCreditNegativePageNum = pageInfo.page;
this.employeeCreditNegativePageSize = 5;
this.employeeCreditNegativePageSize = pageInfo.limit || this.employeeCreditNegativePageSize;
}
await this.loadEmployeeCreditNegative();
},
@@ -549,7 +554,7 @@ export default {
this.abnormalAccountPageNum = pageInfo;
} else {
this.abnormalAccountPageNum = pageInfo.page;
this.abnormalAccountPageSize = 5;
this.abnormalAccountPageSize = pageInfo.limit || this.abnormalAccountPageSize;
}
await this.loadAbnormalAccountPeople();
},
@@ -567,7 +572,7 @@ export default {
projectId: this.projectId,
suspiciousType: this.currentSuspiciousType,
pageNum: this.suspiciousPageNum,
pageSize: 5,
pageSize: this.suspiciousPageSize,
});
const data = (response && response.data) || {};
this.suspiciousTotal = Number(data.total) || 0;
@@ -593,7 +598,7 @@ export default {
const response = await getOverviewEmployeeCreditNegative({
projectId: this.projectId,
pageNum: this.employeeCreditNegativePageNum,
pageSize: 5,
pageSize: this.employeeCreditNegativePageSize,
});
const data = (response && response.data) || {};
this.employeeCreditNegativeList = Array.isArray(data.rows) ? data.rows : [];

View File

@@ -14,7 +14,6 @@
<div class="block-title">模型预警次数统计</div>
<div class="block-subtitle">按模型汇总预警命中次数与涉及人数</div>
</div>
<el-button size="mini" type="text">导出</el-button>
</div>
<div v-loading="cardLoading" class="model-card-grid">

View File

@@ -19,4 +19,8 @@ const source = fs.readFileSync(
"abnormalAccountList",
"handleAbnormalAccountPageChange",
"loadAbnormalAccountPeople",
":page-sizes=\"riskDetailPageSizeOptions\"",
"layout=\"total, sizes, prev, pager, next, jumper\"",
"pageSize: this.abnormalAccountPageSize",
"this.abnormalAccountPageSize = pageInfo.limit || this.abnormalAccountPageSize",
].forEach((token) => assert(source.includes(token), token));

View File

@@ -19,4 +19,8 @@ const source = fs.readFileSync(
"loadEmployeeCreditNegative",
"handleEmployeeCreditNegativePageChange",
"getOverviewEmployeeCreditNegative",
":page-sizes=\"riskDetailPageSizeOptions\"",
"layout=\"total, sizes, prev, pager, next, jumper\"",
"pageSize: this.employeeCreditNegativePageSize",
"this.employeeCreditNegativePageSize = pageInfo.limit || this.employeeCreditNegativePageSize",
].forEach((token) => assert(source.includes(token), token));

View File

@@ -21,9 +21,11 @@ const source = fs.readFileSync(
"摘要 / 交易类型",
"异常标签",
"<pagination",
"pageSize: 5",
":page-sizes=\"[5]\"",
"layout=\"total, prev, pager, next, jumper\"",
"DEFAULT_RISK_DETAIL_PAGE_SIZE",
"RISK_DETAIL_PAGE_SIZE_OPTIONS = [5, 10, 20, 50]",
":page-sizes=\"riskDetailPageSizeOptions\"",
"layout=\"total, sizes, prev, pager, next, jumper\"",
"pageSize: this.suspiciousPageSize",
].forEach((token) => assert(source.includes(token), token));
[