From 48b43cfad59fe50fa2050359541d58276ddc347f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=8D=BF=E4=BA=91=E7=A7=8B=E6=9C=88?= <15273589815@163.com> Date: Mon, 14 Sep 2026 23:34:36 +0800 Subject: [PATCH] =?UTF-8?q?=EF=BB=BF=E6=8A=95=E9=A1=BE=E6=8E=A8=E8=8D=90?= =?UTF-8?q?=E7=A9=BA=E5=80=99=E9=80=89=E6=B1=A0=EF=BC=9A=E6=8A=8A"?= =?UTF-8?q?=E4=B8=BA=E4=BB=80=E4=B9=88=E6=B2=A1=E6=9C=89=E4=BA=A7=E5=93=81?= =?UTF-8?q?"=E8=AE=B2=E6=B8=85=E6=A5=9A=EF=BC=8C=E8=80=8C=E4=B8=8D?= =?UTF-8?q?=E6=98=AF=E4=B8=80=E5=8F=A5"=E6=B2=A1=E6=9C=89=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E6=A0=A1=E9=AA=8C=E7=9A=84=E4=BA=A7=E5=93=81"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "当前没有通过适当性与证据校验的产品。" 这句话对运营毫无信息量:既不知道是谁的问题, 也不知道下一步该做什么。现在空态会说明证据门口径(每个产品都要求 ①销售机构的**已验证** 适当性证据 ②基金合同快照,且都要带可核查的来源链接与文档 sha256,缺一即整只排除, fail closed),并给出本轮候选/入选/排除的数量,以及两条可执行路径: - 真实方案:先由产品治理线导入适当性证据与合同快照 ( ools/import_product_governance_reference.py,CSV 需带 source_url 与 document_sha256); - 呈现效果:切到页面顶部「本地演示数据」,那里的方案会标注"规则模拟、不构成真实推荐"。 同时说明本环境为空的原因:dvisor_product_suitability_reference 与 dvisor_product_contract_snapshot **均为 0 行**(26 个上市产品因此全部被证据门排除, candidate_count=0,所以连"排除原因"也没有可展示的条目)。 --- .../dashboard/actions-module.js | 25 ++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/app/static/portal/employee-advisor/dashboard/actions-module.js b/app/static/portal/employee-advisor/dashboard/actions-module.js index 161b249..44bb4e1 100644 --- a/app/static/portal/employee-advisor/dashboard/actions-module.js +++ b/app/static/portal/employee-advisor/dashboard/actions-module.js @@ -231,7 +231,30 @@ export function createActionsModule({ output, alert, steps, amountInput, horizon + ''; } if (!products.length) { - html += note('当前没有通过适当性与证据校验的产品。', 'info'); + // 空候选池**必须说清为什么**:只写"没有产品",运营既不知道是谁的问题、 + // 也不知道下一步做什么。这里把证据门的口径与可执行动作一并给出。 + const summary = data.selection_summary || {}; + html += note( + '当前没有通过「适当性与证据校验」的产品。投顾推荐对每个产品都要求' + + '①销售机构的**已验证**适当性证据、②基金合同快照,且两者都要带可核查的' + + '来源链接与文档 sha256 —— 缺任一项即整只排除(fail closed)。' + + '本环境这两类证据暂无数据,因此候选为 0。', + 'info', + ); + if (summary.candidate_count !== undefined) { + html += note( + `本轮候选 ${summary.candidate_count ?? 0} 只:入选 ${summary.selected_count ?? 0} 只、` + + `排除 ${summary.excluded_count ?? 0} 只。`, + 'info', + ); + } + html += note( + '要看真实方案:先由产品治理线导入适当性证据与合同快照' + + '(`tools/import_product_governance_reference.py`,CSV 需带 source_url 与 document_sha256);' + + '只想先看呈现效果:可切到页面顶部的「本地演示数据」,那里的方案会明确标注' + + '"规则模拟、不构成真实推荐"。', + 'info', + ); } else { html += table(['产品', '风险级', '评分', '推荐依据'], products.map((product) => { const evidence = product.recommendation_evidence_card || {};