Files
group_fqcd_jr/app/static/portal
lzf_0626 48b43cfad5 投顾推荐空候选池:把"为什么没有产品"讲清楚,而不是一句"没有通过校验的产品"
"当前没有通过适当性与证据校验的产品。" 这句话对运营毫无信息量:既不知道是谁的问题,
也不知道下一步该做什么。现在空态会说明证据门口径(每个产品都要求 ①销售机构的**已验证**
适当性证据 ②基金合同快照,且都要带可核查的来源链接与文档 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,所以连"排除原因"也没有可展示的条目)。
2026-09-14 23:34:36 +08:00
..
2026-09-14 18:13:10 +08:00

Portal 路由与角色映射

正式门户使用原生 JavaScript、原生 CSS 与同源 fetch,静态资源统一从 /static/portal/ 加载。

路由 角色 数据源
/portal/guest/home/ 访客 / 全部 P001(推荐位取前 3 只)
/portal/guest/products/ 访客 / 全部 P001
/portal/guest/product-detail/?code= 访客 / 全部 P001(不含历史净值曲线)
/portal/customer/login/ 未登录客户 A034
/portal/customer/dashboard/ customer / admin T001、T002
/portal/customer/holdings/ customer / admin T006
/portal/customer/profit-loss/ customer / admin T001
/portal/customer/orders/ customer / admin T003
/portal/customer/transactions/ customer / admin T007
/portal/customer/cash-ledger/ customer / admin T009
/portal/customer/risk-questionnaire/ customer ONB001、ONB002
/portal/employee-console/login/ 未登录员工 / 管理员 A034
/portal/employee-console/workspace/ admin / super_admin A002-A006、A012、A033、A035-A040、客服转人工管理接口
/portal/employee-risk/dashboard/ risk_operator / admin / super_admin /api/v1/risk/**、R001-R003
/portal/employee-advisor/dashboard/ advisor / admin / super_admin /api/v1/advisor/recommendations/published(本人 + 名下归属客户的已发布交付物)
运营账号默认进入 /portal/employee-operations/offsite/ operator / admin / super_admin /api/v1/offsite-fund/mails、/api/v1/offsite-fund/mailbox-status

投顾页的数据口径:接口按「本人 + sys_customer_assignment 里名下归属客户」过滤,且同时覆盖 investment_goal_book(方案书,发布后 review_status='published')与 advisor_recommendation_plan(推荐方案,审核后 review_status='approved')两类内容。 方案书的审核与发布都要求管理员(investment-goal:review / publish 都带 admin=True), 投顾自己发不出来 —— 这是有意设计的复核环节,不是缺陷。

客服浮窗由公开首页、基金产品页和客户工作台统一挂载。访客使用 /api/v1/visitor-tokens 获取短期令牌(角色 visitor,权限只有 agent:run + knowledge:query),因此必须走 query_knowledge 这个工具名;登录客户走 search_knowledge。两者都要出现在发布配置的 agent_tools/customer_service:<intent> 白名单里,缺哪一条,对应人群就一问即失败。

公开产品数据来自 GET /api/v1/products(编号 P001,见 docs/05 §19), 产品与净值取自 fin_product(status='上市')、行情取自 fin_market_price 的最新一行。 访客页面通过 common/visitor-token.js 取短期访客令牌后调用;该文件是访客令牌的唯一实现 (客服浮窗也用它),不要在页面里另写一份,否则存储 key 与过期判断迟早不一致。 公开产品数据不得与登录后的真实账户数据混用。

三点口径(改前端前先读):

  1. change_pct 可能是 null(行情只同步过一个交易日时算不出涨跌)。 调用方必须显示"暂无",不得当成 0 —— formatPercent 收到 null 会渲染成 +0.00%, 那等于告诉客户"今天平盘"。
  2. 历史净值曲线没有数据源:fin_nav_history 目前 0 行,详情页因此不画走势图, 并显式说明"尚未接入"。此前那条曲线是 mock 里 12 个编造点位 —— 走势图最容易被当成真数据。
  3. 产品级披露在 common/product-notes.js(如 510300 的"同指数参考产品,非本公司发行")。 fin_product 没有这个字段,所以它留在前端;新增需要披露的产品时改那一份。 凡渲染公开产品的页面都要挂 data-source-notice 说明数据来源。

客户页面均由 common/auth.js 执行入口守卫,接口路径只在 common/api-client.js 的端点表登记。