- Established the P0 scaffolding for the frontend, including login, layout, and routing for four roles. - Integrated the Customer Wealth Dashboard, Advisor Clients Dashboard, Analyst Market Dashboard, and Risk Alerts Dashboard. - Updated the API client to support fetching customer and product data, enhancing the overall functionality of the dashboard. - Added error handling components to improve user experience during data fetching. - Enhanced charting capabilities using Ant Design Charts for better data visualization. This update lays the groundwork for further development of the frontend application, ensuring a robust structure for future features and integrations.
23 KiB
前端 P0 设计 · 四角色工作台 + 平台壳 + 跨角色数据分析 Agent
日期:2026-09-09
状态:脚手架已落地 · 业务待接(brainstorming 定稿)
技术栈:React 19 + Vite 7 + TypeScript strict + Ant Design 5 + HashRouter + Vitest
关联:docs/memory/FRAMEWORK.md·docs/项目框架设计/接口契约-代销平台API-v0.1.md·02-JWT-RBAC鉴权手册.md
1. 目标与范围
1.1 P0 要交付什么
- 初始化
web/,可npm run dev联调本机 FastAPI(:8000)。 - 四角色 Demo 工作台(Ant Design ProLayout:侧栏 + 顶栏 + 内容区),平台读 API 尽量真接。
- Chat 真 SSE:customer、risk 完整;advisor/analyst 共用组件,能力弱处加 Banner。
- 平台功能布局完善:各角色菜单、按钮、空状态、403 页齐全;Agent 专属能力用占位/Mock,等队友接入。
- 产品行情(静态 · P0):共享页「净值一览」,真接
GET /api/products+GET /api/products/{id}/nav;页眉标明 模拟静态净值,非实时行情;动态行情 Phase B 接外部信息 API(见 §2.6)。 - 四角色「收益/洞察」登录首页(桌面):登录 defaultRoute 即 Dashboard(Hero+图+表);详见
docs/superpowers/specs/2026-09-09-frontend-wealth-dashboard-design.md(替换 RoleHomePage 假指标)。 - 数据分析模块(新增拍板):
- analyst 角色:拥有完整「数据分析工作台」页面(问数 + Chat)。
- 其他已登录角色:也可进入 数据分析 Agent(Chat / 问数入口),但 查表/明细级查询 由后端鉴权;权限不足时 403 + 审计,前端展示统一错误,不静默降级。
1.2 不做什么(P0)
- 不 Mock 整个平台 REST(避免与 v0.1 打架)。
- 不做 simulate 交易写 UI(菜单可 Disabled + Tooltip)。
- 不引入 shadcn(与 FRAMEWORK 已定 AntD 5 一致)。
- 不在 P0 实现完整 NL2SQL Agent(分析页可先 Mock 表格 + 真 Chat 骨架)。
- 不做 实时看盘 / K 线 / 自选股 / 外部行情推送(留 Phase B)。
1.3 后端 Agent 接入现状(供前端预期管理)
| Agent | 对话入口 | Tool / 业务能力 |
|---|---|---|
| customer(客户财富) | ✅ /api/chat /stream |
✅ 持仓/流水/档案/KB;无独立客服产品 Agent |
| advisor(代理人) | ✅ | ✅ 同类 Core/KB Tool;业务 Agent 空壳 |
| analyst(数据分析) | ✅ 矩阵准入 | ❌ chat 内 无 NL2SQL Tool(match_intent 不含 analyst) |
| risk(风控) | ✅ | ✅ 四只读风控 Tool + 事件线 |
2. 信息架构与路由(§1 定稿 + 分析模块修订)
2.1 顶层路由
#/login
#/app # 登录后壳(ProLayout)
├─ #/app/home # 角色差异化首页
│
├─ #/app/market # 【共享】产品行情 · 静态净值一览(§2.6)
│
├─ #/app/analytics # 【共享】数据分析模块(见 §2.3)
│ ├─ .../query # 问数页(analyst 全量;其他角色受限/403)
│ └─ .../chat # 数据分析 Agent Chat(X-Agent-Type: analyst)
│
├─ #/app/customer/* # 客户专属(CUST 登录默认)
├─ #/app/advisor/* # 理财师专属
├─ #/app/analyst/* # 分析员专属(可 redirect 到 /app/analytics)
└─ #/app/risk/* # 风控专属
2.2 各角色侧栏(摘要)
| 角色 | 主菜单 | 共享入口 |
|---|---|---|
| customer | 首页 · 我的档案 · 持仓 · 流水 · 产品 · 适当性 · 客户 Chat | 产品行情 · 数据分析 |
| advisor | 首页 · 名下客户 · 草稿(占位) · 顾问 Chat | 产品行情 · 数据分析 |
| analyst | 首页 · 数据分析工作台(= analytics 模块) | 产品行情 |
| risk_officer | 首页 · 预警台账 · AML(占位) · 风控 Chat | 产品行情 · 数据分析 |
侧栏中 「数据分析」 对所有已登录角色可见;analyst 登录时该项高亮且默认 landing 到 /app/analytics/query。
2.3 跨角色数据分析 Agent(用户拍板)
产品行为:
- 入口:任意角色侧栏均可进
#/app/analytics/chat;analyst 另有#/app/analytics/query完整问数页。 - Chat:统一
X-Agent-Type: analyst;会话与其他 Agent 线 隔离(同 actor 下 analyst 会话独立列表)。 - 问数页:
- analyst:展示 SQL 输入/结果表/留痕说明(P0 结果区可 Mock,提交时若后端未就绪则 Banner)。
- 其他角色:同一页面壳;发起 明细级查表 时若返回
AUTH_403_SCOPE/AUTH_403_ROLE,用ApiErrorResult展示手册错误码与 trace_id,不伪造数据。
- 权限提示(前端):进入 analytics 前读取 JWT
roles/permissions(login 响应或 decode payload);无sql:execute:readonly时问数页 Primary 按钮 Disabled + Tooltip「需要数据分析权限」;仍可使用 Chat 做通用问答。
与 JWT 手册对齐(意图):
| 角色 | 预期查数范围 | 前端提示 |
|---|---|---|
| analyst | 目录内只读 SQL + 聚合 | 全功能 |
| compliance | 审计/聚合 | 明细按钮 Disabled 或 403 |
| advisor | 名下客户聚合(未来 Tool) | Banner + 403 友好文案 |
| risk_officer | 全量读预警相关;明细 SQL 可能 403 | 同上 |
| customer | 仅本人/聚合(未来) | 强提示「客户视图」 |
2.4 后端接缝(实现前须知晓)
当前 AGENT_ACCESS_MATRIX(app/api/deps.py)仅允许 analyst、compliance 使用 X-Agent-Type: analyst。
advisor / risk_officer / customer 现在调用 analyst Chat 会得到 AUTH_403_AGENT_MISMATCH。
P0 前端按本设计先做 UI 与路由;若要满足「其他角色也能进数据分析 Agent」,需 统筹/后端小改(扩大 analyst 矩阵准入 + Tool/SQL 网关按 permissions 挡明细)。建议单独 Issue:
- 扩大
analyst的roles白名单(至少advisor,risk_officer,customer等 staff/customer 组合按手册 §5.4 修订)。 - NL2SQL / 查表 Tool 接入后,在 Tool 层用
permissions/assert_customer_access挡明细。
前端不绕过鉴权;403 即产品行为。
2.5 Demo 登录账号
| 卡片 | actor_id | token_type | 默认 landing |
|---|---|---|---|
| 客户 | CUST-9527 |
customer | #/app/customer/home |
| 理财师 | STAFF-10086 |
staff | #/app/advisor/home(改 · 原 customers) |
| 分析员 | STAFF-20001 |
staff | #/app/analyst/home(改 · 问数仍 #/app/analytics/query) |
| 风控专员 | STAFF-30001 |
staff | #/app/risk/home(改 · 台账仍 #/app/risk/alerts) |
详见 wealth-dashboard spec §7 · Demo 锚点 §5。
2.6 产品行情 · 静态净值一览(用户拍板 2026-09-09)
定位: P0 替代「看盘」的 轻量 Demo——展示代销产品 最新一条模拟净值,不是证券实时行情。
路由: #/app/market(全角色共享,侧栏「产品行情」)
数据来源(真接,不 Mock):
GET /api/products?limit=50&offset=0→ 产品列表(名称、风险等级、产品类型等)- 对每个
product_id调GET /api/products/{product_id}/nav→ 合并为表格行- P0 产品约 14 只,前端
Promise.all并发可接受 - v0.2 草案:
GET /api/products/nav-snapshot批量接口,减少 N+1(非 P0 阻塞;见 接口契约 v0.2 行情扩展草案)
- P0 产品约 14 只,前端
表格列(Ant Design Table):
| 列 | 字段 |
|---|---|
| 产品代码 | product_id |
| 产品名称 | product_name |
| 最新净值 | nav |
| 日涨跌 | daily_chg_pct(正红负绿,Typography.Text type="danger/success") |
| 净值日期 | nav_date |
| 操作 | 链接 #/app/customer/products 或弹 Drawer 产品详情(GET /api/products/{id}) |
页眉 Alert(固定 copy):
当前为 Core 模拟库静态净值(种子日期如 2026-09-04),非实时行情。实时/K 线/自选等能力计划在 Phase B 接入外部信息 API。
交互:
- 支持按产品名搜索(前端 filter)、按
daily_chg_pct排序 - 刷新按钮:重新拉 products + nav
- 无 nav 的产品:行内
-+ Tooltip「暂无净值数据」
Phase B(不在 P0 实现,已登记文档):
第三方 REST(咕咕/iTick/次方等择一 PoC · 见 C-05 选型对比)
↓ scripts/sync/sync_market_nav.py(仅后端 cron/手动)
↓ UPSERT core_product_nav
↓ GET /api/products/nav-snapshot(Platform API · v0.2 草案)
web /app/market 改调 nav-snapshot;Alert 文案切「T+1 同步 · 非实时交易行情」
详见:C-05-行情数据源选型对比.md · 接口契约 v0.2 行情扩展草案
需求场景 C-05 行情 仍归 Agent/平台后续;P0 只交付静态页满足 Demo 与布局完整性。
3. 技术结构(§2 定稿)
3.1 目录
web/
├── vite.config.ts # proxy /api → :8000
├── src/
│ ├── api/client.ts # Bearer、错误体四键、X-Trace-Id
│ ├── api/chatStream.ts # SSE OpenAI chunk 解析
│ ├── stores/authStore.ts
│ ├── layouts/AppLayout.tsx
│ ├── routes/menus.tsx # 角色菜单 + 共享 analytics 项
│ ├── pages/market/ # MarketQuotes.tsx 静态净值一览
│ ├── pages/analytics/ # query.tsx + chat.tsx(共享模块)
│ ├── pages/{customer,advisor,risk}/...
│ ├── components/chat/ # ChatPanel 复用
│ ├── components/AgentBanner.tsx
│ ├── components/PermissionGate.tsx # 按 permissions 禁用/提示
│ └── mocks/analystQuery.ts # 问数 Mock(仅 analyst P0 演示)
3.2 API 调用约定
| 场景 | Header |
|---|---|
| 平台读 API | Authorization: Bearer |
| 各角色 Chat | + X-Agent-Type: customer|advisor|risk |
| 数据分析 Chat / sessions | + X-Agent-Type: analyst(固定) |
3.3 Chat 组件
ChatPanel接收 propagentType,内部所有 chat API 带对应X-Agent-Type。/app/analytics/chat固定agentType="analyst"。- SSE:首帧
meta.session_id / trace_id / disclaimer;错误帧STREAM_FAILED/PERSIST_FAILED。
3.4 权限 UI
PermissionGate:permissions.includes('sql:execute:readonly')等。authStore保存 login 返回的roles;若后端 JWT payload 含permissions,解析存入(dev token 已有)。
4. Mock / 真接策略(§3 定稿)
| 页面 | 数据 |
|---|---|
| 客户/产品/持仓/流水/适当性/理财师客户列表 | ✅ 平台 API 真接 |
| 产品行情(静态) | ✅ GET /api/products + 逐产品 GET .../nav 合并 |
| customer / risk Chat | ✅ SSE 真接 |
| advisor Chat | ✅ SSE + Banner |
| analytics Chat | ✅ SSE(analyst);非 analyst 角色依赖后端矩阵扩展 |
| analytics 问数 | analyst:Mock 表格 + 留痕说明;其他角色:同壳,403 真展示 |
| 风控 alerts | ✅ GET /api/risk/alerts |
| 首页 KPI | ✅ 四角色 Dashboard 真汇总(wealth-dashboard spec);删除 RoleHomePage 假指标 |
5. 验收标准
- 四 Demo 账号登录进入对应工作台;侧栏均有 数据分析、产品行情 入口。
- 产品行情 页展示 ≥10 行净值数据,页眉 Alert 标明静态模拟;涨跌列可排序。
STAFF-20001可进问数 + Chat;其他角色可进 analytics Chat 路由(后端未扩矩阵前可见 403 页也算预期,文档注明)。- 客户持仓页、风控预警列表有真数据;Chat 流式与 disclaimer 正常。
- 403/401 统一
ApiErrorResult,可复制 trace_id。 npm run build通过;Vitest 至少覆盖authStore、SSE 解析、mergeProductNavRows纯函数。
6. 实现顺序建议(供 writing-plans)
web/init(Vite + AntD + HashRouter + proxy)authStore+ Login + AppLayout + 路由守卫- 平台 API client + customer 只读页(一条链路跑通)
- 共享
/app/market静态产品行情页 - 共享
ChatPanel+ customer/risk Chat /app/analytics模块(PermissionGate + query + chat)- advisor / risk 其余页 + 占位页
- Vitest + README(
web/README.md启动说明)
7. 修订记录
| 日期 | 说明 |
|---|---|
| 2026-09-09 | 首版:AntD P0 壳 + 四角色 + 平台真接 |
| 2026-09-09 | 增补:数据分析模块跨角色可进;查表鉴权挡;后端矩阵扩展待办 |
| 2026-09-09 | §8 视觉布局确认 + web/ 脚手架:登录插画/Logo/Empty SVG · ProLayout 壳 · Demo 登录 |
| 2026-09-09 | 现状盘点:脚手架已落地;Chat/SSE/平台读/risk alerts 仍为 Placeholder → 见 docs/memory/TODO.md §前端 P0 待接 |
| 2026-09-09 | 增补 四角色收益/洞察 Dashboard 需求 → 2026-09-09-frontend-wealth-dashboard-design.md(登录痒点 · 真 API · 图表) |
| 2026-09-09 | Dashboard 需求 v2:§2.5 defaultRoute 与 wealth-dashboard 对齐 · 首页 KPI 改真汇总 |
8. 视觉风格与布局(待用户确认 · 2026-09-09)
8.1 整体风格定位
| 维度 | P0 拍板 |
|---|---|
| 气质 | 金融代销 / 内勤工作台——稳重、信息密度适中,偏「银行 App + 运营后台」而非 C 端炫动 |
| 组件库 | Ant Design 5 默认 Design Token + 少量品牌色覆盖(不上 Ant Design Pro 付费版;用 Layout 自拼 ProLayout 结构) |
| 主题 | 浅色为主(algorithm: default);P0 不做暗色切换 |
| 主色 | #1677ff(AntD 默认蓝,信任感);风控警示用 #ff4d4f,涨 #cf1322 / 跌 #389e0d(A 股习惯:红涨绿跌) |
| 圆角 | 全局 borderRadius: 6(卡片、按钮统一) |
| 密度 | size: middle 默认;表格 size="small" 以容纳更多列 |
| 字体 | 系统栈:-apple-system, "Segoe UI", "PingFang SC", "Microsoft YaHei", sans-serif;数字列 font-variant-numeric: tabular-nums 对齐 |
| 图标 | @ant-design/icons;侧栏菜单项带 outline 图标(UserOutlined、LineChartOutlined 等) |
不做: 大面积渐变、玻璃拟态、动效-heavy 首页;P0 不定制插画系统。
8.2 全局壳布局(登录后 #/app/*)
┌─────────────────────────────────────────────────────────────────┐
│ Header 高 56px · 白底 · 底边 1px #f0f0f0 │
│ [≡折叠] JinRong 智能管家 [角色Tag] [ActorId] [退出] │
├──────────┬──────────────────────────────────────────────────────┤
│ Sider │ Content 区 · 背景 #f5f5f5 · padding 24px │
│ 宽 220px │ ┌─ PageShell ─────────────────────────────────────┐ │
│ 可折叠 │ │ Breadcrumb + 标题 + 右侧操作区(刷新/导出占位) │ │
│ 白底 │ ├─────────────────────────────────────────────────┤ │
│ │ │ Card / Table / Chat 主体 │ │
│ · 角色菜单│ └─────────────────────────────────────────────────┘ │
│ · 共享菜单│ │
│ 产品行情│ │
│ 数据分析│ │
└──────────┴──────────────────────────────────────────────────────┘
| 区域 | 规格 |
|---|---|
| Header | 左:Logo 文案 + 侧栏折叠;右:Tag 显示当前角色(客户/理财师/分析/风控)、Typography.Text 显示 actor_id(可复制)、退出按钮 |
| Sider | 220px 展开 / 64px 折叠;菜单 分组:「工作台」「智能 Agent」「平台服务」;当前路由高亮;共享项(产品行情、数据分析)在「平台服务」组 |
| Content | 最大内容宽 无硬 cap(表格全宽);Chat 页除外(见 8.4) |
| PageShell | 统一:Breadcrumb → Typography.Title level={4} → 可选 Alert(静态净值/Agent 建设中)→ 子内容 |
8.3 登录页 #/login
┌────────────────────────────────────────────┐
│ 左 40% 品牌区(浅蓝 #e6f4ff 底) │
│ JinRong 智能管家 · 四 Agent 演示平台 │
│ │
│ 右 60% 白底卡片 │
│ 「选择演示账号登录」 │
│ [ 客户 CUST-9527 ] 一键登录 │
│ [ 理财师 STAFF-10086 ] │
│ [ 分析员 STAFF-20001 ] │
│ [ 风控 STAFF-30001 ] │
│ 小字:Mock JWT · 仅供开发演示 │
└────────────────────────────────────────────┘
- 移动端 P0 不优先适配(桌面 Demo 为主);最小宽 1280px 设计。
8.4 页面类型模板
A. 数据列表页(持仓 / 流水 / 产品行情 / 预警 / 名下客户)
[ Alert 可选 ]
[ Card ]
Toolbar: [搜索 Input] [刷新 Button] [占位 Primary 禁用+Tooltip]
Table: bordered=false, pagination, 金额右对齐, 涨跌带色
- 产品行情:顶部 黄色 Alert「静态模拟净值…」;涨跌列红涨绿跌。
B. 详情 / 表单页(档案 / 适当性试算)
- 左
Descriptionsbordered 或右Form+Card;提交Button type="primary";结果用Result或Alert type="success/error"展示阻断原因列表。
C. Chat 页(各 Agent 共用 ChatPanel)
┌─────────────────────────────────────────────────────────────┐
│ [ AgentBanner 可选 · info 蓝条 ] │
├───────────────┬─────────────────────────────────────────────┤
│ SessionList │ MessageList(气泡) │
│ 宽 260px │ flex 1 · 灰底 #fafafa │
│ Card 内 │ user 右对齐蓝泡 / assistant 左对齐白泡 │
│ 新建/关闭会话 │ 底部固定:免责声明小字(has_disclaimer) │
├───────────────┴─────────────────────────────────────────────┤
│ Input.TextArea + [发送] · SSE 流式逐字 │
└─────────────────────────────────────────────────────────────┘
- 免责声明:customer/risk 在首帧
meta.disclaimer下发展示Alert type="warning"折叠条,assistant 气泡底部也可重复小字(与后端落库一致)。 - 流式:assistant 气泡末尾闪烁光标
▍(P0 简易 CSS)。
D. 首页 #/app/home(按角色)
| 角色 | 布局 |
|---|---|
| customer | 4 列 Statistic Card(持仓市值/产品数/会话数/占位)+ 快捷入口 Row + Button |
| advisor | 名下客户 Statistic + 待办占位 Card |
| analyst | 跳转数据分析 Card 可点击 |
| risk | 待审预警数 Badge + 最近预警 List 摘要 |
部分数字带 「演示」Tag(半 Mock KPI)。
E. 占位页(草稿箱 / AML / 未接入 Agent)
- 统一
Empty+ 说明文案 +Button type="link"回首页;不用整页插画。
8.5 状态与反馈
| 场景 | 组件 |
|---|---|
| 加载 | 表格 Skeleton / 页面 Spin |
| 403/401 | Result status="403" + error_code + 可复制 trace_id |
| Agent 建设中 | Alert type="info" showIcon(AgentBanner) |
| 操作成功 | message.success(toast) |
| 流式失败 | Chat 区内 Alert type="error"(STREAM_FAILED) |
8.6 ConfigProvider 初值(web/src/theme.ts)
{
token: {
colorPrimary: '#1677ff',
borderRadius: 6,
fontSize: 14,
},
components: {
Layout: { headerBg: '#ffffff', siderBg: '#ffffff', bodyBg: '#f5f5f5' },
Table: { headerBg: '#fafafa' },
},
}
8.7 与后续 Phase B 的兼容
- 外部行情接入后:产品行情 页仅增 Tab「静态净值 | 实时行情」,壳布局 不变。
- 暗色主题:预留
theme.ts导出,P0 不接线。
请用户确认: 以上风格(金融稳重 + AntD 默认蓝 + 红涨绿跌 + 侧栏工作台壳 + Chat 左会话右消息)是否 OK;若需「招行红」「深色 Header」等品牌色,指出主色 hex 即可调整。
8.8 装饰素材(用户拍板 · 2026-09-09)
| 位置 | 素材 | 来源 / 许可 |
|---|---|---|
| 登录页左栏 | web/public/assets/illustrations/login-finance.svg |
项目自绘矢量(主色 #1677ff,金融图表+盾牌意象) |
| 登录页 / Header 小标 | web/public/assets/brand/logo-mark.svg |
自绘「JR」圆角标 |
| Empty / 占位页 | web/public/assets/illustrations/empty-data.svg |
自绘(文件夹+图表) |
| Chat 空会话 | web/public/assets/illustrations/empty-chat.svg |
自绘(对话气泡) |
| 首页 Hero(可选) | 角色差异化 Statistic Card 为主,不铺大图 | — |
备选(后续可替换): unDraw Finance / Personal Finance / Financial Advisor 类 SVG(免费商用、无需署名;禁止打包再分发)。替换时保持主色 #1677ff 即可。
规范: 插图仅用于登录/Empty/403 等非数据区;表格、行情、持仓页不用背景大图,避免干扰读数。