FinAgent 个人中心实现:路由、头像与安全接口实践


摘要:个人中心是典型登录后壳+子路由的场景。本文说明**/profile 页面如何接到侧栏入口、父组件如何用user+avatarEpoch同步侧栏与页面头像;同时说明页面设计布局,需 Bearer 鉴权的头像为何不能简单<img src>、如何用fetch+blob URL展示,以及Canvas 圆形裁剪**上传链路等等。


一、界面布局:个人中心入口

登录成功后,整个页面布局由顶栏(含浅色 / 深色主题)、侧栏主内容区组成。

侧栏底部有一块可点击区域:圆形头像(或首字母占位)+展示名+文案「个人中心」,内部执行navigate('/profile'),与单股分析,走势看板等导航并列。
在这里插入图片描述


二、路由与状态:为何要多一个 avatarEpoch

路由App.tsxRoute path="/profile"挂载ProfilePage。只有会话已从加载中变为已登录用户对象时才会进入带侧栏的壳;未登录走登录流程。

父组件里与个人信息强相关的状态:

状态 作用
userAuthUser 来自GET /api/auth/me,改昵称、改头像成功后都要用后端返回的新对象覆盖更新
avatarEpoch(数字) 头像上传/删除后 自增;用于在avatar_url 字符串不变的情况下,仍强制重新请求图片(见第五节)

ProfilePage 通过props拿到:useravatarEpochonUserUpdatedonAvatarChanged。资料或头像任意一次写库成功,都应 onUserUpdated(nextUser)仅头像变更时再调 onAvatarChanged()(内部即 avatarEpoch++),这样侧栏与页面内头像 同源刷新


三、页面长什么样

3.1 布局

  • Hero:标题个人中心加上副文案;装饰性符号不参与交互。
  • 提示:登录名不可在本页修改(降低误操作与安全争议)。
  • 栅格:有两块宽卡片:个人信息(可编辑)和账号信息(只读)。

3.2 个人信息卡片里有什么

模块 要点
头像 有头像则显示圆图,否则显示昵称/用户名前两字大写。选图仅接受JPEG/PNG/WebP,选完进裁剪弹窗(第四节)。可移除头像
资料表单 昵称maxLength={64};简介textarea 上限500 字。提交→PATCH /api/auth/me
改密码 两步:先填当前密码→再设新密码并确认;前端校验两次新密码一致、最小长度等;提交→POST /api/auth/me/password
使用指南 静态说明:侧栏入口、各业务模块、头像大小限制、演示环境勿复用密码等。

3.3 账号信息卡片(只读)

展示 登录名 username数字 id(反馈问题时用)、注册时间。与可编辑区分离,避免用户误以为能改登录凭证。
在这里插入图片描述


四、头像链路:从选图到落盘

4.1 前端裁剪

用户选本地文件后,用Image+Canvas 做预览:圆形可视区域、支持缩放与平移;确认后导出256×256 PNG圆形图,再包装成File调用uploadAvatar

4.2 上传请求

  • POST /api/auth/me/avatar
  • multipart/form-data,字段名**file**
  • Header:Authorization: Bearer <token>
  • 响应:更新后的用户 JSON(含 avatar_url 等字段)

4.3 后端行为

  • 单文件不超过 2MB,超出返回413
  • 上传新图前删除旧文件,避免磁盘堆积;校验失败返回400
  • 头像路径写入SQLite。

注意:业务上返回给前端的avatar_url形如固定路径/api/auth/me/avatar(有头像时)——即同源 API,不是公开CDN 直链,因此必须带登录态才能拉取。
在这里插入图片描述


五、为什么要写 useAuthAvatarUrl<img> 带不了 Bearer

若直接把src设为/api/auth/me/avatar,浏览器发的是普通 GET无法附加 Authorization,后端JWT校验会失败。

常见做法是:

  1. fetch(url+'?_e='+epoch, { headers: { Authorization: 'Bearer ...' } }) 拿到blob
  2. URL.createObjectURL(blob)生成 blob: 临时地址 赋给 <img src>
  3. 依赖变更或组件卸载时 URL.revokeObjectURL,防止泄漏。

avatarEpoch(或 query 里的 _e:上传新头像后,数据库里的路径可能仍是同一路由字符串,浏览器HTTP 缓存可能仍显示旧图;让epoch递增,URL查询串变化,可绕过缓存,强制重新拉取。侧栏与个人中心页共用user+avatarEpoch,避免两处头像不一致。


六、总结

个人中心 = /profile 单页 + 只读账号区 + 可编辑展示资料 + Canvas 圆裁剪头像 + 两步改密

数据统一落在 /api/auth/me*;头像展示的关键坑是JWT 与<img>原生不兼容问题,用 fetch+blob URL 解决;同路径换图要用 avatarEpoch 打碎缓存。后续考虑加邮箱绑定、MFA,应该仍然在该路由增卡片,并与后端 PATCH 字段同步演进。


【山东大学项目实训FinAgent】本周进度报告:AKshare 数据接入与测试
【山东大学项目实训FinAgent】 周报(2026-04-19):Dataflow分层设计与FastAPI路由协作实践
【山东大学项目实训FinAgent】进度报告:并行分析师、指标批量拉取与进度LRU扩容实现单股分析耗时优化

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐