From cb3265e796f8b70454c6a93f792f999b6ade6408 Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Tue, 7 Apr 2026 09:37:41 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AE=B0=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .DS_Store | Bin 18436 -> 18436 bytes assets/异常账户.xlsx | Bin 0 -> 10423 bytes docker-compose.yml | 1 + ...-31-nas-lsfx-mock-subset-startup-record.md | 21 +++ ...model-card-grid-frontend-implementation.md | 31 ++++ ...-sidebar-menu-width-240-frontend-record.md | 21 +++ ...31-abnormal-account-bank-tag-validation.md | 155 ++++++++++++++++++ ruoyi-ui/src/assets/styles/variables.scss | 2 +- .../components/detail/RiskModelSection.vue | 2 +- .../preliminary-check-model-card-grid.test.js | 4 +- 10 files changed, 233 insertions(+), 4 deletions(-) create mode 100644 assets/异常账户.xlsx create mode 100644 docs/reports/implementation/2026-03-31-nas-lsfx-mock-subset-startup-record.md create mode 100644 docs/reports/implementation/2026-03-31-results-overview-risk-model-card-grid-frontend-implementation.md create mode 100644 docs/reports/implementation/2026-03-31-sidebar-menu-width-240-frontend-record.md create mode 100644 docs/tests/records/2026-03-31-abnormal-account-bank-tag-validation.md diff --git a/.DS_Store b/.DS_Store index 0adf18c3e6764b2004c788d8feb5ad0b72a57590..f52ed6ac397585c4802a8db4a670cc70699c4ea5 100644 GIT binary patch delta 1149 zcmb`FTWAzl7{||l)a)4s&B>*BqMMi|#&zRrH*SnZ#oQXAi8ZmwHkY<(Cz**J%+AK0 z-NYE%#p08f5*biYM1z-t;ss)DX;EJ+*oXE(W3Bj5DSZ)qsg^=pw4Rv_g3z}*59jdz zzWL7go%8$e8ONS+T)tG|{2ENd=e@it6m-s6<0>8oNeV1Csw*t)n@bP zd!1d~JYl6MwzN!oHN(|W?A`LmDTI&n_60@vRO`UUcRRF z2*b3JVnCP)r?8TzJ1jkB=3t(xPUW(kY+k_UQ&vj5Qhj23N+d_U!oni1ePHNG^PRZi zmKtn=s$Qm~i1YW|Ohdwyt3jz3UKHS3hb^aJ`t*-WLYmgGO;`rAWh-}@aD~RB=|R2E z9At)?sasK{@y=m0VT-uMTBd`m*J!+}KOT$8!R;J`ro%O|b+6lcqi!c#hfM2b_lCDQ z@3FV)3A1&?G8639^i=C*{3Dj_W!$1hL)0YW37Pe-Uc@(1+U=fLXBej84cWHYEn&hM z7D+uRr)rm5%4WAIrKPoFVP}Z*w0o`6+A#6H{LJ=p1)-#ngh@SVCcR{cjFNri5II4v zkT1zq@*Vk++$X<~N91?%C;5x~P5!}5%z_UTk_rL{q8v+5iCWa59xZ6YyJ$xTK13f3 zm>57bjub|)1Ecs1d$At}@Hr0SBu?Qp&fp@h;W}>M7Vh9Ke!@LG#1lNlA9#l6_*YSt zT%}A2D2tV#Qm#alwMwJXth75P7qv;B`J2{nXl~i~-#&xtOaw$)ThKWyY|%GpMn{B^ z+}f?%{ibCIYfDtVjJbol(3o$E7tEXQFVPlK$(zl}$bc54k~GW8$dG>-mF8lKC$$QH zM3oj|Gcq#dU#U`tj99I$Ri&BO%#w_*(dty!$c%W}AM!U+%3cqq@5ycQGkHiJOH9u( zL&BMhVl2iotin3fNH7g(#3r<2v&7@V>BYy;(T_pI5XTS_s2;;Ee2O%7OGx`9CKu8X z9K|sl$60)Vb2yI+xQegvHNL^OxQQPmt_S$d2^TDw+#B4THK~RR)TURD{lBNCvnGAD H&wMWcHr*gt delta 985 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 CnLJ4V literal 0 HcmV?d00001 diff --git a/docker-compose.yml b/docker-compose.yml index b5ea0ec7..f24f342a 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,7 @@ services: context: . dockerfile: docker/mock/Dockerfile container_name: ccdi-lsfx-mock + command: ["python", "main.py", "--rule-hit-mode", "subset"] restart: unless-stopped depends_on: - backend diff --git a/docs/reports/implementation/2026-03-31-nas-lsfx-mock-subset-startup-record.md b/docs/reports/implementation/2026-03-31-nas-lsfx-mock-subset-startup-record.md new file mode 100644 index 00000000..8ea1c733 --- /dev/null +++ b/docs/reports/implementation/2026-03-31-nas-lsfx-mock-subset-startup-record.md @@ -0,0 +1,21 @@ +# NAS 部署 lsfx-mock-server subset 启动参数实施记录 + +## 变更目的 + +- 将 NAS 部署环境中的 `lsfx-mock-server` 启动方式显式固定为 `subset` 模式,避免容器启动时仅依赖应用默认值。 + +## 修改内容 + +- 修改根目录 `docker-compose.yml` + - 在 `lsfx-mock-server` 服务上新增启动命令: + - `python main.py --rule-hit-mode subset` + +## 影响范围 + +- 仅影响 NAS 部署链路使用的根目录 `docker-compose.yml` +- 不修改 `lsfx-mock-server` 本地开发脚本 +- 不修改主系统前后端业务逻辑 + +## 核验方式 + +- 执行 `docker compose config`,确认渲染后的 `lsfx-mock-server` 服务命令包含 `--rule-hit-mode subset` diff --git a/docs/reports/implementation/2026-03-31-results-overview-risk-model-card-grid-frontend-implementation.md b/docs/reports/implementation/2026-03-31-results-overview-risk-model-card-grid-frontend-implementation.md new file mode 100644 index 00000000..61c4c5f9 --- /dev/null +++ b/docs/reports/implementation/2026-03-31-results-overview-risk-model-card-grid-frontend-implementation.md @@ -0,0 +1,31 @@ +# 结果总览模型预警次数统计四列布局前端实施记录 + +## 本次改动 + +- 调整 [RiskModelSection.vue](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue) 中 `模型预警次数统计` 卡片区的桌面端栅格布局。 +- 将 `.model-card-grid` 的桌面端列数由 `repeat(5, minmax(0, 1fr))` 调整为 `repeat(4, minmax(0, 1fr))`,使桌面端固定每行 4 张卡片。 +- 保留现有响应式断点不变: + - `1200px` 以下 2 列 + - `768px` 以下 1 列 +- 更新 [preliminary-check-model-card-grid.test.js](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/tests/unit/preliminary-check-model-card-grid.test.js) 断言,防止后续回退到 5 列。 + +## 验证结果 + +执行命令: + +```bash +cd ruoyi-ui +node tests/unit/preliminary-check-model-card-grid.test.js +npm run build:prod +``` + +执行结果: + +- 静态测试通过 +- 生产构建通过 +- 构建过程中仅有仓库原有体积告警,没有新增编译错误 + +## 补充说明 + +- 本次仅调整桌面端卡片区排版,不改动模型卡片数据、联动筛选和人员列表逻辑。 +- 本轮未启动前端开发服务进行手工联调,因此不存在新增前端进程需要关闭的情况。 diff --git a/docs/reports/implementation/2026-03-31-sidebar-menu-width-240-frontend-record.md b/docs/reports/implementation/2026-03-31-sidebar-menu-width-240-frontend-record.md new file mode 100644 index 00000000..526fce0f --- /dev/null +++ b/docs/reports/implementation/2026-03-31-sidebar-menu-width-240-frontend-record.md @@ -0,0 +1,21 @@ +# 左侧菜单宽度调整为 240px 前端实施记录 + +## 本次改动 + +- 调整 [variables.scss](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/assets/styles/variables.scss) 中全局侧栏宽度变量 `$base-sidebar-width`,将左侧菜单宽度从 `200px` 调整为 `240px`。 +- 保持现有侧栏展开、折叠、移动端抽屉和固定头部联动逻辑不变,由现有布局样式继续复用同一宽度变量。 + +## 实现方式 + +- 直接修改全局样式变量 `$base-sidebar-width`,让 [sidebar.scss](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/assets/styles/sidebar.scss) 和 [layout/index.vue](/Users/wkc/Desktop/ccdi/ccdi/ruoyi-ui/src/layout/index.vue) 中依赖该变量的侧栏宽度、主内容区偏移量、固定头部宽度同步生效。 +- 不额外新增局部覆盖样式,避免出现展开态、折叠态和移动端宽度不一致的问题。 + +## 验证情况 + +- 执行 `cd ruoyi-ui && npm run build:prod`,生产构建通过。 +- 构建过程中仅出现仓库原有的静态资源体积告警,没有新增编译错误或构建失败。 + +## 边界说明 + +- 本次仅调整左侧菜单展示宽度,不改动菜单数据、路由、权限、交互行为和页面内容布局逻辑。 +- 本轮未启动前端开发服务进行手工联调,因此不存在新增前端进程需要关闭的情况。 diff --git a/docs/tests/records/2026-03-31-abnormal-account-bank-tag-validation.md b/docs/tests/records/2026-03-31-abnormal-account-bank-tag-validation.md new file mode 100644 index 00000000..68cac86c --- /dev/null +++ b/docs/tests/records/2026-03-31-abnormal-account-bank-tag-validation.md @@ -0,0 +1,155 @@ +# 异常账户标签识别联调验证记录 + +## 1. 验证目标 + +- 验证异常账户模型在真实数据库中可稳定命中 +- 验证页面展示结果与数据库、后端聚合结果一致 + +## 2. 关联文档 + +- 后端实施计划:`docs/plans/backend/2026-03-31-abnormal-account-bank-tag-backend-implementation-plan.md` +- 前端实施计划:`docs/plans/frontend/2026-03-31-abnormal-account-bank-tag-frontend-implementation-plan.md` + +## 3. 验证环境 + +- 验证日期:2026-03-31 +- 后端地址:`http://127.0.0.1:62318` +- 前端地址:`http://127.0.0.1:1026` +- 数据库连接:以 `ruoyi-admin/src/main/resources/application-dev.yml` 为准 + +说明: + +- MySQL MCP 当前连接的库与应用实际使用库不一致,本次最终 SQL 校验统一使用项目配置文件解析出的真实数据库连接执行,避免出现“页面有数据、MCP 无数据”的误判。 + +## 4. 数据准备 + +执行以下脚本补齐规则元数据与最小测试样本: + +```bash +bin/mysql_utf8_exec.sh sql/migration/2026-03-31-create-ccdi-account-info-and-abnormal-account-rules.sql +bin/mysql_utf8_exec.sh sql/migration/2026-03-31-add-abnormal-account-rule-test-data.sql +``` + +补齐后确认以下样本存在: + +- 项目:`90331 / 异常账户规则测试项目` +- 员工 A:`330101199001010001` +- 员工 B:`330101199001010002` +- 员工 C:`330101199001010003` +- 员工 D:`330101199001010004` +- 账户样本:4 条 +- 流水样本:7 条 + +## 5. SQL 校验结果 + +### 5.1 规则元数据 + +- `ABNORMAL_ACCOUNT / SUDDEN_ACCOUNT_CLOSURE / OBJECT / HIGH` +- `ABNORMAL_ACCOUNT / DORMANT_ACCOUNT_LARGE_ACTIVATION / OBJECT / HIGH` + +### 5.2 原始规则 SQL 命中结果 + +- `SUDDEN_ACCOUNT_CLOSURE` + - 命中员工:`330101199001010001` + - 账户:`6222000000000001` + - 销户日期:`2026-03-20` + - 销户前最后交易日:`2026-03-18` + - 窗口累计交易金额:`180000.00` + - 单笔最大金额:`70000.00` + +- `DORMANT_ACCOUNT_LARGE_ACTIVATION` + - 命中员工:`330101199001010002` + - 账户:`6222000000000002` + - 开户日期:`2025-01-01` + - 首次交易日期:`2025-08-01` + - 沉睡月数:`7` + - 启用后累计交易金额:`550000.00` + - 单笔最大金额:`300000.00` + +结论: + +- 仅员工 A 命中 `突然销户` +- 仅员工 B 命中 `休眠账户大额启用` +- 员工 C、员工 D 未误命中 + +## 6. 后端接口与落库验证 + +### 6.1 手动重算 + +调用: + +```bash +POST /login/test +POST /ccdi/project/tags/rebuild +``` + +入参: + +```json +{ + "projectId": 90331, + "modelCode": "ABNORMAL_ACCOUNT" +} +``` + +返回: + +- `code = 200` +- `msg = 标签重算任务已提交` + +### 6.2 任务与结果表 + +- 最新任务:`ccdi_bank_tag_task.id = 67` +- 任务状态:`SUCCESS` +- 命中数:`2` +- `ccdi_bank_statement_tag_result` 中 `ABNORMAL_ACCOUNT` 结果数:`2` +- `ccdi_project_overview_employee_result` 聚合结果数:`2` + +### 6.3 总览接口返回 + +- 风险模型卡片返回:`异常账户 / warningCount=2 / peopleCount=2` +- 风险人员总览返回: + - 测试员工 A:`突然销户` + - 测试员工 B:`休眠账户大额启用` +- 项目分析详情返回: + - 员工 A 的 `reasonDetail` 与 SQL 命中说明一致 + - 员工 B 的 `reasonDetail` 与 SQL 命中说明一致 + +## 7. 页面联调结果 + +通过前端页面 `http://127.0.0.1:1026/ccdiProject/detail/90331?tab=overview` 验证: + +- 项目列表中 `异常账户规则测试项目` 显示 `已完成` +- 项目列表中目标人数显示 `4`,预警人数显示 `2` +- 结果总览风险人员区域显示: + - `测试员工A / 突然销户` + - `测试员工B / 休眠账户大额启用` +- 风险模型区域显示模型卡片: + - `异常账户 / 2 / 涉及 2 人` +- 风险模型命中人员列表显示: + - `测试员工A / 异常账户 / 突然销户` + - `测试员工B / 异常账户 / 休眠账户大额启用` +- 点击 `测试员工A` 的 `查看详情` 后,项目分析详情弹窗展示: + - `异常对象摘要` + - `测试员工A` + - `员工对象` + - `账户6222000000000001于2026-03-20销户,销户前30天内最后交易日2026-03-18,累计交易金额180000.00元,单笔最大金额70000.00元` +- 风险详情页中的 `异常账户人员信息` 区块正常渲染占位文案,未因本轮后端接入报错 + +## 8. 发现与结论 + +### 8.1 验证结论 + +- 异常账户标签可以被正确识别 +- 数据库原始规则命中结果、后端聚合结果、前端页面展示结果三者一致 + +### 8.2 联调观察 + +- 打开项目分析详情弹窗时,前端控制台出现 2 条 Vue 告警: + - `Duplicate keys detected: '关联人员往来-object'` +- 该告警未阻断本次异常账户标签展示,但建议后续排查 `ProjectAnalysisAbnormalTab.vue` 中的 key 生成逻辑,避免详情弹窗在更多数据场景下出现渲染更新问题 + +## 9. 进程处理 + +- 本次验证复用了已运行的后端进程,未额外启动新的后端服务 +- 本次验证启动了前端开发服务,验证结束后需主动关闭 diff --git a/ruoyi-ui/src/assets/styles/variables.scss b/ruoyi-ui/src/assets/styles/variables.scss index 34484d47..72f4cb99 100644 --- a/ruoyi-ui/src/assets/styles/variables.scss +++ b/ruoyi-ui/src/assets/styles/variables.scss @@ -36,7 +36,7 @@ $base-sub-menu-background:#000c17; $base-sub-menu-hover:#001528; */ -$base-sidebar-width: 200px; +$base-sidebar-width: 240px; // the :export directive is the magic sauce for webpack // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass diff --git a/ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue b/ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue index bf330403..eb3ca5bf 100644 --- a/ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue +++ b/ruoyi-ui/src/views/ccdiProject/components/detail/RiskModelSection.vue @@ -428,7 +428,7 @@ export default { .model-card-grid { display: grid; - grid-template-columns: repeat(5, minmax(0, 1fr)); + grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 16px; } diff --git a/ruoyi-ui/tests/unit/preliminary-check-model-card-grid.test.js b/ruoyi-ui/tests/unit/preliminary-check-model-card-grid.test.js index ccd51296..a977cd4f 100644 --- a/ruoyi-ui/tests/unit/preliminary-check-model-card-grid.test.js +++ b/ruoyi-ui/tests/unit/preliminary-check-model-card-grid.test.js @@ -11,8 +11,8 @@ const source = fs.readFileSync( ); assert( - source.includes("grid-template-columns: repeat(5, minmax(0, 1fr));"), - "桌面端模型卡片应固定为每行 5 张" + source.includes("grid-template-columns: repeat(4, minmax(0, 1fr));"), + "桌面端模型卡片应固定为每行 4 张" ); assert( source.includes("@media (max-width: 1200px)"),