From 2e295f417d1f54d4c2f24ea1eb500cc6ef000cff Mon Sep 17 00:00:00 2001 From: wkc <978997012@qq.com> Date: Fri, 20 Mar 2026 09:52:52 +0800 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=A8=A1=E5=9E=8B=E4=BF=A1?= =?UTF-8?q?=E6=81=AFxlsx=E5=B9=B6=E8=A1=A5=E5=85=85SQL=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=E7=BB=93=E8=AE=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/模型信息.xlsx | Bin 13743 -> 17084 bytes ...026-03-20-model-info-xlsx-update-design.md | 0 ...0-model-info-xlsx-update-implementation.md | 172 ++++++++++++++++++ ...026-03-20-model-info-xlsx-update-record.md | 76 ++++++++ 4 files changed, 248 insertions(+) rename docs/{superpowers/specs => design}/2026-03-20-model-info-xlsx-update-design.md (100%) create mode 100644 docs/plans/fullstack/2026-03-20-model-info-xlsx-update-implementation.md create mode 100644 docs/reports/implementation/2026-03-20-model-info-xlsx-update-record.md diff --git a/assets/模型信息.xlsx b/assets/模型信息.xlsx index 8a557b97adfd74962e807cab250e6c5377d02b1c..2cea8c004c2ba12d692f0207cef44bba7dd2a6cb 100644 GIT binary patch literal 17084 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 literal 13743 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 **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. + +**Goal:** 直接更新 `assets/模型信息.xlsx`,仅对未真实实现模型补齐可明确推出的字段,并新增 SQL 可执行性与缺少内容结论列。 + +**Architecture:** 先以项目代码、规则定义、数据库表结构为依据,逐行判定模型是否已经具备真实命中逻辑;对未实现模型再执行表格回填和 SQL 可执行性校验,最后补充实施记录。整个过程不新增业务规则,不修改后端实现逻辑,只更新资料文件与文档。 + +**Tech Stack:** Python 3、openpyxl、rg、MySQL MCP、Git + +--- + +### Task 1: 梳理实现状态与回填依据 + +**Files:** +- Modify: `assets/模型信息.xlsx` +- Reference: `docs/design/2026-03-20-model-info-xlsx-update-design.md` +- Reference: `docs/reports/implementation/2026-03-17-model-sql-check-and-rewrite.md` + +- [ ] **Step 1: 列出 XLSX 中的全部模型行** + +Run: + +```bash +python3 - <<'PY' +from openpyxl import load_workbook +wb = load_workbook('assets/模型信息.xlsx') +ws = wb['Sheet1'] +for idx, row in enumerate(ws.iter_rows(min_row=2, values_only=True), start=2): + if row[2]: + print(idx, row[2], row[3], row[6], row[7]) +PY +``` + +Expected: 输出每一行对应的序号、模型名称、相关指标和指标英文名。 + +- [ ] **Step 2: 检索项目内真实规则实现与占位规则** + +Run: + +```bash +rg -n "HOUSE_OR_CAR_EXPENSE|TAX_EXPENSE|SINGLE_LARGE_INCOME|CUMULATIVE_INCOME|ANNUAL_TURNOVER|LARGE_CASH_DEPOSIT|ABNORMAL_CUSTOMER_TRANSACTION|LOW_INCOME_RELATIVE_LARGE_TRANSACTION|MULTI_PARTY_GAMBLING_TRANSFER|GAMBLING_SENSITIVE_KEYWORD|MONTHLY_FIXED_INCOME|FIXED_COUNTERPARTY_TRANSFER|FOREX_BUY_AMT|INTEREST_PAYMENT_BY_OTHERS|LARGE_PURCHASE_TRANSACTION|SUPPLIER_CONCENTRATION|STOCK_TFR_LARGE|WITHDRAW_CNT|SALARY_QUICK_TRANSFER" ccdi-project ruoyi-ui sql docs +``` + +Expected: 区分哪些模型已有真实命中逻辑,哪些只有占位规则或文档描述。 + +- [ ] **Step 3: 用当前数据库结构确认 SQL 校验基线** + +Run: + +```bash +python3 - <<'PY' +from openpyxl import load_workbook +wb = load_workbook('assets/模型信息.xlsx') +ws = wb['Sheet1'] +print('rows=', ws.max_row, 'cols=', ws.max_column) +PY +``` + +Expected: 确认当前工作簿可正常读取,为后续回写做基线检查。 + +### Task 2: 更新 XLSX 未实现模型信息 + +**Files:** +- Modify: `assets/模型信息.xlsx` + +- [ ] **Step 1: 追加两列表头** + +实现要求: + +```text +在现有最后一列后新增: +1. 当前环境是否可执行SQL +2. 当前缺少内容 +``` + +- [ ] **Step 2: 对已真实实现模型保持跳过** + +实现要求: + +```text +只标记为“已实现并跳过”,不重写该行原有内容,不填新增结论列。 +``` + +- [ ] **Step 3: 对未实现模型补齐可明确推出的字段** + +实现要求: + +```text +优先补充指标英文名、风险筛查对象、技术口径、可疑结果返回、风险等级; +仅在项目代码、规则表、SQL 或当前库结构能明确支持时回填,不能唯一确定则保留原值。 +``` + +- [ ] **Step 4: 写入 SQL 可执行性结论** + +实现要求: + +```text +当前环境可直接执行写“是”,否则写“否”; +“当前缺少内容”列中写最小必需缺项或明确错误,可执行则写“/”。 +``` + +- [ ] **Step 5: 保存工作簿** + +Run: + +```bash +python3 - <<'PY' +from openpyxl import load_workbook +wb = load_workbook('assets/模型信息.xlsx') +wb.save('assets/模型信息.xlsx') +print('saved') +PY +``` + +Expected: 输出 `saved`,且文件可再次被 `openpyxl` 正常打开。 + +### Task 3: 校验结果并补充实施记录 + +**Files:** +- Modify: `assets/模型信息.xlsx` +- Create: `docs/reports/implementation/2026-03-20-model-info-xlsx-update-record.md` + +- [ ] **Step 1: 抽样读取更新后的关键行** + +Run: + +```bash +python3 - <<'PY' +from openpyxl import load_workbook +wb = load_workbook('assets/模型信息.xlsx') +ws = wb['Sheet1'] +for row_no in [10, 11, 12, 14, 18, 22, 25, 26, 28, 31]: + vals = [ws.cell(row_no, col).value for col in range(3, ws.max_column + 1)] + print(row_no, vals) +PY +``` + +Expected: 关键未实现模型行已带有新增结论列,且补充信息与设计口径一致。 + +- [ ] **Step 2: 记录本次实施内容和判定依据** + +实施记录应包含: + +```text +1. 已实现模型跳过的判定口径 +2. 未实现模型的回填原则 +3. 新增列说明 +4. SQL 可执行性判断依据 +5. 抽样验证结果 +``` + +- [ ] **Step 3: 检查 Git 变更范围** + +Run: + +```bash +git status --short +``` + +Expected: 只包含本次任务相关文件;如存在无关变更,不纳入提交。 + +- [ ] **Step 4: 提交本次修改** + +Run: + +```bash +git add docs/plans/fullstack/2026-03-20-model-info-xlsx-update-implementation.md docs/reports/implementation/2026-03-20-model-info-xlsx-update-record.md assets/模型信息.xlsx +git commit -m "更新模型信息xlsx并补充校验结论" +``` + +Expected: 生成仅包含本次任务文件的中文提交。 diff --git a/docs/reports/implementation/2026-03-20-model-info-xlsx-update-record.md b/docs/reports/implementation/2026-03-20-model-info-xlsx-update-record.md new file mode 100644 index 00000000..0914c6d6 --- /dev/null +++ b/docs/reports/implementation/2026-03-20-model-info-xlsx-update-record.md @@ -0,0 +1,76 @@ +# 模型信息 XLSX 更新实施记录 + +## 修改目标 + +- 直接更新 [assets/模型信息.xlsx](/Users/wkc/Desktop/ccdi/ccdi/assets/模型信息.xlsx) +- 按“已有真实 SQL 或真实结果产出逻辑才算已实现”的口径,区分跳过模型和待补充模型 +- 对未实现模型新增 SQL 可执行性结论列,并补齐可从项目和数据库明确推出的缺失字段 + +## 判定口径 + +- 已实现并跳过: + - 仅认定 `CcdiBankTagServiceImpl` 已接入且 `CcdiBankTagAnalysisMapper.xml` 中存在真实查询逻辑的模型 + - 本次跳过的是大额交易前 8 条规则: + - `HOUSE_OR_CAR_EXPENSE` + - `TAX_EXPENSE` + - `SINGLE_LARGE_INCOME` + - `CUMULATIVE_INCOME` + - `ANNUAL_TURNOVER` + - `LARGE_CASH_DEPOSIT` + - `FREQUENT_CASH_DEPOSIT` + - `LARGE_TRANSFER` +- 未实现并处理: + - 虽然项目已挂规则入口,但 `CcdiBankTagAnalysisMapper.xml` 中仍是 `where 1 = 0` 的占位 SQL + - 原始 SQL 引用了当前环境不存在的外部库表、字段或不兼容语法 + - 原始 SQL 为空 + +## XLSX 修改内容 + +- 在 `Sheet1` 末尾新增两列: + - `当前环境是否可执行SQL` + - `当前缺少内容` +- 对未实现模型补齐了以下信息: + - 指标英文名统一补到当前项目规则编码风格,如 `ABNORMAL_CUSTOMER_TRANSACTION`、`WITHDRAW_AMT`、`SALARY_UNUSED` + - 少量技术口径按当前库表字段修正为真实表结构描述,例如: + - 房产相关规则由历史描述中的 `ccdi_family_liability` 调整为当前实际存在的 `ccdi_asset_info` + - 采购规则技术口径改为基于 `ccdi_purchase_transaction.actual_amount` + - 对缺少原始 SQL 的行保留原业务口径,同时在新增列中明确写明“缺少原始SQL” + +## SQL 可执行性结论 + +- 判定标准: + - 以当前 `ccdi` 库真实表结构为准 + - 以当前 MySQL 能力为准 + - 不假设外部 schema、外部表、临时表和占位变量已经准备好 +- 本次结论概况: + - 标记为 `是` 的 1 行: + - `9.1 可疑采购 / LARGE_PURCHASE_TRANSACTION` + - 标记为 `否` 的未实现行,主要原因包括: + - `PROJECT_ID`、`$$$$` 等占位变量未替换 + - `trx_time`、`updated_at` 等字段在当前库不存在 + - `WITH`、`add_months()` 等不兼容当前 MySQL 的语法 + - 缺少外部表,如 `odsdb.blfmconf`、`sjfx_pro.bdfmhqaa_orc`、`xdzx.*` + - 原始 SQL 为空 + +## 验证记录 + +- 已执行工作簿结构校验,确认表头已扩展到 16 列 +- 已抽样回读以下关键行,确认新增列和补齐字段已写入: + - 第 10 行:异常交易 2.1 + - 第 12 行:疑似赌博 3.1 + - 第 15 行:可疑兼职 5.1 + - 第 18 行:可疑财产 6.1 + - 第 21 行:可疑财产 收入资产不符 + - 第 24 行:可疑外汇交易 跨境汇款 + - 第 26 行:可疑采购 9.1 + - 第 27 行:可疑采购 9.2 + - 第 30 行:异常行为 微信支付宝提现超额 + - 第 32 行:异常行为 工资无使用记录 + - 第 34 行:异常行为 疑似代理他人账户 + +## 本次涉及文件 + +- 更新 [assets/模型信息.xlsx](/Users/wkc/Desktop/ccdi/ccdi/assets/模型信息.xlsx) +- 新增 [docs/design/2026-03-20-model-info-xlsx-update-design.md](/Users/wkc/Desktop/ccdi/ccdi/docs/design/2026-03-20-model-info-xlsx-update-design.md) +- 新增 [docs/plans/fullstack/2026-03-20-model-info-xlsx-update-implementation.md](/Users/wkc/Desktop/ccdi/ccdi/docs/plans/fullstack/2026-03-20-model-info-xlsx-update-implementation.md) +- 新增 [docs/reports/implementation/2026-03-20-model-info-xlsx-update-record.md](/Users/wkc/Desktop/ccdi/ccdi/docs/reports/implementation/2026-03-20-model-info-xlsx-update-record.md)