Files
group_xinghuo_jinrong/docs/frontend/FRONTEND-HANDOFF.md
T
zhanghongyu_0626 b04af6e701 feat(docs): Update demo SOP and enhance documentation for advisor agent
- Added new entry for "STAFF-20003" role in `jwt_service.py` to support additional user permissions.
- Revised the demo SOP documentation to reflect updated processes and clarify the presentation flow, including changes to the demo script and internal guidelines.
- Enhanced the presentation materials with a new HTML slide deck for the advisor agent demo, ensuring a cohesive visual representation of the features and capabilities.
- Updated various documentation files to align with recent changes in the advisor agent functionalities and testing baselines.

This update improves the clarity and usability of the demo materials while ensuring that the documentation accurately reflects the current state of the project.
2026-09-13 17:44:09 +08:00

11 KiB
Raw Blame History

JinRong 前端交接手册

1. 项目定位

当前前端采用「静奢智能」视觉方向:暖白与米灰背景、墨蓝品牌色、浅金点缀,收益语义使用朱砂红(正值)与翡翠绿(负值)。视觉层已经与业务数据层分离,后续 agent 可以在不改 API 契约的前提下扩展页面。

2. 启动与验证

从仓库根目录执行:

cd web
npm install
npm run dev
npm run build
npm run test
npm run lint

后端需要单独启动:

uvicorn app.main:app --reload

Vite 开发服务器默认使用 http://127.0.0.1:5173,并将 /api 代理到 http://127.0.0.1:8000。路由使用 HashRouter,页面 URL 形如 http://127.0.0.1:5173/#/app/customer/home。

环境自检(2026-09-11): 后端 GET /api/ready(Redis + 关键路由)· 前端顶栏 DevReadyBanner(开发态提示,不替代生产探针)。

测试基线: 全仓 python -m pytest → 825 passed, 1 skipped · cd web && npm run test → 27 Vitest。

3. 依赖方向

pages → hooks/api/utils
pages → components/dashboard
components/dashboard → components/ui
layouts/AppLayout → components/layout
components/ui → styles/tokens.css

边界规则:

  • components/ui 只能处理展示和可访问性,禁止导入 api、hooks、authStore 或角色业务类型。
  • components/layout 只接收导航和身份上下文,不发起 API 请求。
  • components/dashboard 只接收页面已经计算好的值、数组、ReactNode 和表格配置,不负责请求或聚合。
  • hooks 是 API loading、error、refresh 状态的所有者。
  • 页面负责业务文案、hook 调用、路由 Link、表格列和业务字段映射。

4. 设计令牌

令牌位于 web/src/styles/tokens.css,优先使用 Tailwind utility,不要在页面新增品牌色或重复 spacing 值。

Token Value 用途
jr-bg #F6F5F1 页面背景
jr-surface #FBFAF7 次级表面
jr-surface-strong #FFFFFF 卡片和主表面
jr-ink #132B3A 品牌墨蓝、主按钮
jr-text #17212B 正文
jr-muted #71808A 次级文字
jr-border #E5E2DB 边框和分隔线
jr-positive #178A68 负收益、正常状态
jr-negative #C9564A 正收益、风险状态
jr-gold #C9A66B eyebrow、焦点、强调
jr-info #3F718A 信息提示

状态阶(2026-09-13 · Radix Colors) —— 由 @radix-ui/colors 的 slate / jade 提供,用于 hover / active / disabled 与图表色序。只引这两条,其余色相刻意不引(品牌色是刻意降饱和的,Radix 复刻不了;选用依据与「色温陷阱」见 docs/memory/TODO.md 2026-09-13):

Token 值 用途
jr-text-soft var(--slate-11) 次级文字(强于 jr-muted)
jr-text-faint var(--slate-8) 禁用态文字
jr-positive-bg var(--jade-3) 成功态浅底
jr-positive-border var(--jade-6) 成功态边框
jr-positive-hover var(--jade-10) 成功态 hover
jr-positive-strong var(--jade-12) 成功态深字

字体(2026-09-13): 正文走 @fontsource-variable/inter 自托管(在 main.tsx import),字体栈 "Inter Variable" 排在最前(全平台统一,Mac 不再用原生 SF)。⚠️ 字族名带 Variable 后缀,写成 "Inter" 会匹配不上而静默回退系统字体。Inter 无 CJK 字形,中文回落 PingFang SC / Microsoft YaHei;运行时仅下载 latin 48KB(unicode-range 分片)。

金融产品已有语义不能反转:正值 P&L 显示朱砂红,负值显示翡翠绿,零值使用次级灰。这是现有产品约定,不要按通用股票配色改成相反语义。

5. 可复用组件

基础 UI:src/components/ui

<Surface>
  <MetricCard label="总市值" value={<AmountText value={value} />} />
</Surface>
<PageHeader eyebrow="WEALTH DESK" title="我的资产" action={<Button>刷新</Button>} />
<Badge tone="positive">运行正常</Badge>
<EmptyState title="暂无持仓" image="/assets/illustrations/empty-data.svg" />

组件职责和 props:

  • Button: variant 为 primary | secondary | ghost | quiet,size 为 sm | md | lg,支持 loading 和标准 button props。
  • Surface: variant 为 default | subtle | dark,padding 为 none | sm | md | lg,支持 as 和 HTML attributes。
  • Badge: tone 为 neutral | info | positive | negative | gold | ink。
  • MetricCard: label、value、可选 detail、trend、emphasis;value 接收 ReactNode,不会格式化或改写金额。
  • PageHeader: eyebrow、title、description、action。
  • SectionHeading: eyebrow、title、description、action。
  • EmptyState: 可选 image、description、action。

这些组件不拥有数据获取;用 slots/ReactNode 接入业务内容。

Dashboard:src/components/dashboard

<ChartCard title="资产结构">...</ChartCard>
<DataSection title="持仓明细">
  <Table columns={columns} dataSource={rows} />
</DataSection>
  • DashboardHero: 保留主指标、掩码、眼睛按钮和三项响应式指标;主值由页面提供。
  • QuickActionBar: 接收 { label, to }[],使用真正的 React Router Link,不能改为只有 onClick 的 button。
  • ChartCard: { eyebrow?, title, description?, children },只包裹图表 surface,不了解图表库内部。
  • DataSection: { title, description?, action?, children },只在表格内容区提供 overflow-x-auto。
  • DashboardLayout<T>: 接收页面传入的 hero、quick actions、chart data、ColumnsType<T>、row key 和空文案;保留 AntD Table 的排序、分页和行操作行为。

6. 新增角色 Dashboard 的流程

  1. 在 src/api 增加或复用 API 函数,保持 URL、method、参数、Authorization 行为不变。
  2. 在 src/hooks 保持 loading、error、refresh 和请求编排;不要把请求写进视觉组件。
  3. 需要聚合或格式化时放在 src/utils,并为纯函数补测试。
  4. 页面调用 hook,组合 PageHeader、DashboardHero、ChartCard、DataSection 和 EmptyState。
  5. 保留 ApiErrorResult、无假数据行为和已有 route Link。
  6. 菜单只在 src/routes/menus.tsx 增加,路由只在 src/App.tsx 增加;不要在页面复制导航模型。

7. 状态矩阵与 Ant Design 边界

Loading → Skeleton,应用壳层和页面层级仍可见
Success → 共享 Surface + 现有 Table/Charts
Empty   → EmptyState 或 AntD Empty,绝不填充假数字
Error   → ApiErrorResult,显示 error code、message 和 trace ID

Ant Design 继续负责:

  • Table 的排序、分页、row key 和行渲染;
  • Alert、Result、Empty、Skeleton 和 message;
  • @ant-design/charts 图表内部、tooltip、legend 和延迟挂载。

Tailwind 负责:

  • 页面布局、间距、响应式网格、排版、Surface 层级和轻量 hover/focus 动效;
  • 令牌来自 tokens.css,不要在页面硬编码新的品牌色。

禁止:

  • 全局 !important 覆盖 AntD 行为;
  • 将 API 请求或角色判断移入 components/ui;
  • API 失败时添加 demo/fallback 数字;
  • 把真实 Link 换成 click-only button;
  • 为了视觉改动 AuthState、jinrong.auth、接口字段或路由。

8. 浏览器验收清单

启动 FastAPI 与 Vite 后,使用四个 demo 账号检查:

  • 客户 → /app/customer/home
  • 理财师 → /app/advisor/home
  • 分析员 → /app/analyst/home
  • 风控 → /app/risk/home

每个角色都检查:

  • Logo、角色上下文、当前菜单高亮;
  • 侧栏折叠/展开;
  • actor ID copy;
  • 退出后回到登录页;
  • 至少一个共享平台 route。

业务回归:

  • 客户显示总市值、累计盈亏、昨日收益和持仓数;眼睛按钮只切换 ****,不改变表格行数据;图表、分页、排序、详情和助手链接可用。
  • 理财师显示客户数、总 AUM 和最大客户 fallback;客户市值降序、客户与 Chat 链接可用。
  • 分析员显示产品数、上涨/下跌/平盘;按日变化绝对值排序,行情/问数/Chat 链接可用。
  • 风控显示待审数量和 API disclaimer;台账 GET /alerts 的 stats.pending 与「已处置」聚合筛选(status=handled);适当性/AML/模拟页为结构化结果(非裸 JSON);无预警时显示 Empty,不出现假图表或假表格;有预警时显示图表、处置和助手链接。
  • 四角色 Chat(含客户 SSE):…侧栏每条可删除(调用 close API);侧栏仅展示 active;清空历史会话 调用 POST /api/chat/sessions/close-all(消息仍留库,仅关闭续聊)。
  • API 错误态显示 code、message、trace ID 和重试;loading 态保留 shell 与 skeleton。
  • 检查正收益红色、负收益绿色、零值灰色。

视口矩阵:1280px、1024px、768px、320px。

  • body 不出现横向滚动条;
  • 只有表格区域发生局部横向滚动;
  • 登录列在窄屏堆叠;
  • action rail 自动换行;
  • Hero 指标变成可读的响应式列;
  • 键盘 focus ring 可见。

9. 常见坑

  • 不要把 API 调用迁移到 visual component。
  • 不要在 API error 时补默认金额或默认条数。
  • 不要在页面里新增硬编码颜色或随意 spacing。
  • 不要删除共享组件而不检查 downstream agent 的引用。
  • 不要修改 AuthState、jinrong.auth localStorage key 或登录默认落点。
  • 对话续聊用 sessionStorage 键 jinrong.chat.activeSession.{agentType}(与登录 key 无关);勿在流式 POST 省略 session_id。
  • 不要把表格的 sorting、pagination、row action 逻辑重写成页面外的副本。
  • 修改后至少运行:
cd web
npm run build
npm run test
npm run lint

当前已知 lint warning 主要来自既有 hooks 的 set-state-in-effect 和 React Fast Refresh 对“组件文件同时导出常量”的提示;它们不是编译错误。Vite 可能提示主 chunk 超过 500 kB,属于当前依赖包体积提示。

10. 看板地图与加载(2026-09-10)

有可视化,入口是角色 home,不是单独 BI 产品:

角色 路由 图表
客户 #/app/customer/home 资产结构饼图 · 持仓盈亏柱图 · 表
理财师 #/app/advisor/home 名下客户 AUM 分布
分析 #/app/analyst/home 市场/产品概览
风控 #/app/risk/home 预警类型分布
问数 #/app/analytics/query MetricCard(/api/analyst/dashboard)· 抽样溯源 / 转人工(N-03/N-07)· 无钻取(D-12 未做)

为何每次进页都转圈:

  • Redis 不缓存平台 REST(持仓/净值/预警);只服务 Chat 窗口、问数 D-06、限流、L3。
  • 每个页面 mount 时 loading=true 全量重拉;离开路由 state 丢弃(无 React Query)。
  • fetchNavMap 对每个 product_id 单独请求 /nav,持仓/行情页请求次数多。

明日优化方向(见 TODO.md §2026-09-11): 批量净值 API · 客户端 stale-while-revalidate · 可选 Dashboard 短 TTL 缓存(后端)。

客户「产品趋势」: 客户助手 Chat 仅 C-05 最新净值;走势/预测 reject。统计类趋势走 问数工作台 + customer self 域(数据分析Agent-合并说明.md §9.6)。分析对话 URL 已重定向问数。