Files
group_xinghuo_jinrong/docs/frontend/FRONTEND-HANDOFF.md
T
zhanghongyu_0626 9d4d4aaa6d feat(chat): Enhance session management with new API endpoints and filtering options
- Added `status` query parameter to `list_sessions_api` for filtering sessions by their status (active/closed).
- Introduced `close_all_sessions_api` endpoint to allow users to close all active sessions for the current actor.
- Updated `SessionRepository` to support status filtering in session listing and implemented logic for closing active sessions.
- Improved Redis connection settings for better performance and reliability.

This update enhances the chat functionality by providing more control over session management, improving user experience and system efficiency.
2026-09-10 22:30:07 +08:00

9.7 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。

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 信息提示

金融产品已有语义不能反转:正值 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;无预警时显示 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)· 无钻取(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)。分析对话页仍为占位。