FastGPT 账号页 UI 改造设计:两栏布局、路由 Header 抽象与响应式滚动策略实战解析
【免费下载链接】FastGPTFastGPT is a knowledge-based platform built on the LLMs, offers a comprehensive suite of out-of-the-box capabilities such as data processing, RAG retrieval, and visual AI workflow orchestration, letting you easily develop and deploy complex question-answering systems without the need for extensive setup or configuration.项目地址: https://gitcode.com/GitHub_Trending/fa/FastGPT
导读
本文基于 FastGPT 仓库中的账号页 UI 改造设计文档(.agents/design/support/account-page-ui-redesign.md),完整梳理账号模块的桌面端两栏布局模型、共享样式抽象边界、各路由 Header 的差异化实现,以及移动端滚动所有权与 Header 显隐规则。读者阅读后,将理解AccountContainer与SecondaryNavigationContainer的分层协作方式、账号侧栏 220px 固定宽度的由来、表格页面滚动条贴边的实现原理,并掌握一套可复用的"全高无卡片两栏 + 路由自管内容"的账号页改造方案。
FastGPT 账号模块当前所有路由都复用同一个AccountContainer壳层,但桌面端此前仍使用带外边距、圆角和阴影的通用PageContainer,各路由又分别维护着不一致的 padding、滚动容器和标题样式。本次改造以新版 Figma 设计为基准,统一了账号侧栏与主内容区域的骨架,同时刻意不把业务差异明显的各页面 Header 强行收敛成万能组件。
背景:改造的动机与覆盖范围
现状问题
- 账号模块所有路由统一复用
AccountContainer,但其内部嵌套的通用PageContainer在桌面端带有 16px 外边距、圆角、阴影和灰色背景,与新版全高、无外层卡片的两栏设计不符。 - 各路由自行维护 padding、滚动容器和标题样式,导致"个人信息、团队管理、使用记录"等页面视觉与滚动行为不一致。
- 新版 Figma 设计统一了账号侧栏和主内容区域,但各页面 Header 的业务内容差异明显,无法用单一通用 Header 组件覆盖。
覆盖路由清单
本次改造覆盖以下 10 个路由:
| 路由 | 本次改动重点 |
|---|---|
| 个人信息 | 自适应双栏、分组细节调整 |
| 团队管理 | 页面 Header(标题 + 团队选择器 + 编辑入口 + 成员数量) |
| 使用记录 | 页面标题、Tab、积分入口、筛选与导出 |
| 第三方账号 | 页面标题、空资源表现 |
| 模型提供商 | 页面标题、模型 Tab、筛选与表格 |
| 自定义域名 | 页面标题、表格与业务操作 |
| API 密钥 | 标题、数量、教程入口、筛选与操作 |
| 通知 | 页面标题与通知列表 |
| 语言与时区 | 页面标题与设置表单 |
| 账单与发票 | 补齐页面 Header,沿用原有业务布局 |
其中账单页没有对应的完整新设计稿,本次沿用原有业务布局,仅补齐与其他账号页一致的页面 Header。
设计目标:改造的五条主线
- 桌面端账号区域与 Figma 一致,采用全高、无外层卡片的两栏结构。
- 账号侧栏固定为220px,主内容区自适应占满剩余宽度。
- 只抽象稳定的视觉和结构(容器、标题文字样式),不把不同业务 Header 强行统一成万能组件。
- 保留现有权限、配置开关、数据请求和交互逻辑,改造只动"壳"不动"业务"。
- 移动端保留现有横向导航和纵向内容布局;只有标题文案的页面 Header 不显示,包含操作或辅助信息的特殊 Header 保留。
布局模型:全高无卡片的两栏骨架
桌面端整体结构
全局导航 64px └── 账号区域 ├── 账号侧栏 220px └── 主内容 flex: 1; min-width: 0账号侧栏规格
- 宽度固定220px。
- 左右内边距11px,导航项可用宽度198px。
- 顶部内边距16px。
- 导航项高度约37px,项间距8px。
- 版本信息固定在底部。
- 当 OpenAI 账号和外部工作流变量均未开放时,不显示"第三方账号"导航。
这些规格在源码中有精确对应:SecondaryNavigationContainer桌面端侧栏使用flex: '0 0 220px'、borderRight: '1px solid'+borderColor: 'myGray.200',内部SideTabs以mx: 'auto'、w: '198px'居中布局,底部通过footer插槽渲染版本信息(见 SecondaryNavigationContainer.tsx)。
"第三方账号"导航的显隐逻辑在AccountContainer中实现(见 AccountContainer.tsx):
const showThirdPartyTab = feConfigs?.show_openai_account === true || feConfigs?.externalProviderWorkflowVariables?.some((item) => item.isOpen) === true;即只有当系统配置开启了 OpenAI 账号入口、或存在已开启的外部工作流变量提供商时,该导航项才会出现——这正是设计文档中"第三方资源全部关闭时导航项隐藏"验证点的代码依据。
主内容区规格
flex: 1、min-width: 0,不设置固定宽度或最大宽度。- 路由负责自身 Header、内容 padding 和滚动边界。
- 桌面端去掉通用
PageContainer的 16px 外边距、圆角、阴影和灰色背景。
在SecondaryNavigationContainer中,主内容区通过flex: '1 0 0'、minW: 0占满剩余宽度,并将滚动策略设为移动端auto、桌面端hidden(页面内部滚动由子路由接管),背景统一为白色(见 SecondaryNavigationContainer.tsx)。
抽象边界:共享什么、不共享什么
共享部分一:AccountContainer
AccountContainer承担四项职责:账号侧栏、移动端导航、主内容容器和权限过滤(见 AccountContainer.tsx)。它基于SecondaryNavigationContainer构建,通过tabs数组驱动导航渲染,并完成权限过滤:
- 团队管理、使用记录:仅
feConfigs.isPlus时显示。 - 账单与发票:仅
feConfigs.show_pay且当前用户团队拥有hasManagePer管理权限时显示。 - API 密钥:仅
userInfo?.team?.permission.hasApikeyCreatePer时显示。 - 自定义域名:仅
feConfigs.isPlus && feConfigs.customDomain?.enable时显示。 - 模型提供商、通知:仅
feConfigs.isPlus时显示。 - 退出登录:不跳转路由,而是弹出
useConfirm确认框,确认后setUserInfo(null)并跳转/login(见 AccountContainer.tsx)。
导航项通过router.pathname.split('/').pop()与TabEnum枚举比对,路由与 Tab 一一对应(info / usage / bill / inform / setting / thirdParty / apikey / team / model / customDomain)。
共享部分二:accountTitleTextStyles
accountTitleTextStyles抽象账号页标题与个人信息分组标题的文字视觉样式,定义于 styles.ts:
export const accountTitleTextStyles = { color: 'myGray.900', fontSize: '16px', fontWeight: 500, lineHeight: '24px', letterSpacing: '0.15px' } satisfies TextProps;该抽象只提供视觉属性,不绑定语义:页面标题使用h1,个人信息分组标题使用h2,避免视觉复用破坏语义层级。
同文件还提供了两个配套样式常量,支撑"移动端整体滚动、桌面端内部滚动"的响应式滚动策略:
/** 账号页在移动端由内容撑开,桌面端占满主内容区高度。 */ export const accountPageRootStyles = { h: ['auto', '100%'], minH: 0 } satisfies BoxProps; /** 账号页内部滚动区仅在桌面端接管纵向滚动,移动端跟随主内容区整体滚动。 */ export const accountContentScrollStyles = { flex: ['0 0 auto', '1 0 0'], h: ['auto', 0], minH: 0, overflowY: ['visible', 'auto'] } satisfies BoxProps;这两组样式在 API 密钥表格(Table.tsx)等场景中被组合消费:根容器用accountPageRootStyles.h控制高度模式,Header 固定 64px,滚动容器用accountContentScrollStyles.flex / h / overflowY实现"桌面端接管纵向滚动、移动端放行"。
不共享部分:不创建通用 Header 组件
各路由的 Header 结构与职责差异明显,设计上不创建通用 Header 组件,由各路由分别维护:
| 路由 | Header 结构 |
|---|---|
| 个人信息 | 无页面级 Header,直接展示内容分组 |
| 团队管理 | 标题、团队选择器、编辑入口、成员数量 |
| 使用记录 | 页面标题;内容区包含 Tab、积分入口、筛选和导出 |
| 第三方账号 | 页面标题 |
| 模型提供商 | 页面标题;内容区包含模型 Tab、筛选和表格 |
| 自定义域名 | 页面标题;内容区包含表格和业务操作 |
| API 密钥 | 标题、数量、教程入口;内容区包含筛选和操作 |
| 通知 | 页面标题和通知列表 |
| 语言与时区 | 页面标题和设置表单 |
| 账单与发票 | 页面标题;内容区保留 Tab、开票入口和业务表格 |
此外,个人信息页的字段行、快捷入口和用量展示只在该页面内部使用,局部 helper 保留在页面文件中,不提升为跨模块组件,控制抽象成本。
个人信息页:自适应双栏详解
个人信息页是本次改造中布局变化最大的页面,桌面端内容使用可用宽度,不设置1080px或1180px最大宽度:
主内容宽度 ├── 左右 padding:24px └── 内容 ├── 左栏:330px ├── 间距:45px └── 右栏:flex: 1; min-width: 0源码实现与设计一致(见 projects/app/src/pages/account/info/index.tsx):根容器应用accountPageRootStyles与py: [3, 6]、px: [5, 6],桌面端以Flex分栏,左栏flex: '0 0 330px',右栏ml: '45px'、flex: '1 0 0'、minW: 0;右侧套餐用量卡片还设置了maxW: '805px'。
需要特别说明的是:Figma 画布下测得的 1180px 内容宽度和 805px 右栏宽度只是 1512px 视口中的计算结果,不是布局约束。右栏实际采用flex: 1; min-width: 0自适应,套餐卡片和资源用量卡片随右栏宽度弹性伸缩。
其他调整:
- 移除"通用信息""团队信息""套餐与用量"标题前的图标。
- 桌面内容 padding 为 24px。
- 团队选择器高度调整为34px。
- 合并分割线与分组标题的重复垂直间距。
- 套餐卡片和资源用量卡片随右栏宽度自适应。
路由改造原则:统一骨架、差异化内容
页面 Header 通用规范
- 页面 Header 在桌面端高度为64px,左右 padding 为24px,底部使用
myGray.200边框;个人信息页除外(无页面级 Header)。 - Header 背景为白色,不显示旧版标题图标。
- 内容区默认从 Header 下方24px开始;具体间距由路由根据表格、Tab 或表单结构控制。
以团队管理页为例(见 projects/app/src/pages/account/team/index.tsx):Header 使用h: '64px'、px: 6、borderBottom: '1px solid'+borderColor: 'myGray.200',左侧依次渲染h1标题(accountTitleTextStyles)、TeamSelector height: '34px'、owner 编辑入口图标,右侧渲染成员数量徽章;下方用FillRowTabs承载 member / org / group / permission / audit 五个团队 Tab,其中审计 Tab 仅对拥有hasManagePer权限的用户显示,且受套餐auditLogStoreDuration配置约束。
API 密钥页的 Header 则体现了"标题 + 数量 + 教程入口"结构(见 Table.tsx):左侧标题动态拼接(apiKeys.length)数量,右侧渲染"使用教程"与"OpenAPI 文档"两个按钮,文档链接来自feConfigs.openAPIDocUrl或默认的/openapi/intro文档路径。
表格页面的滚动层级
- 表格型页面使用页面内部滚动,避免整个账号侧栏跟随滚动。
- 表格滚动容器占满主内容区宽度,左右留白放在滚动容器内部,使桌面端纵向滚动条贴合主内容区最右侧。
- 使用记录、账单与发票、自定义域名和模型提供商均以API 密钥页的滚动结构为准。
- 团队管理的成员、群组、权限和审计 Tab 同样使用全宽滚动容器;部门 Tab 保留独立布局,因为它包含左右分栏和右侧固定内容。
从团队管理页源码可见其处理方式:表格容器px在部门 Tab 下为6、其他 Tab 下为0,overflow在部门 Tab 下为['visible', 'auto']、其他 Tab 下为['visible', 'hidden'](见 projects/app/src/pages/account/team/index.tsx),滚动条贴边正是"padding 进滚动容器"这一原则的落地。
审计日志分页改造
审计日志从触底加载改为手动分页:默认每页 50 条(源码实现中usePagination的defaultPageSize: 100,并提供[50, 100, 200]的页大小选项,分页偏好通过pageSizeCacheKey: 'account-team-audit'缓存,见 Audit/index.tsx)。表格不产生横向滚动,详情列使用剩余宽度并自动换行(表格采用tableLayout: 'fixed'固定布局,见 Audit/index.tsx)。
既有逻辑保持
现有空状态、按钮和权限逻辑保持不变;设计稿中的示例数据不写入代码。
响应式策略:移动端与桌面端的滚动所有权划分
- 桌面端按 Figma 实现。
- 移动端继续使用
LightRowTabs(在SecondaryNavigationContainer中当isPc为 false 时渲染,见 SecondaryNavigationContainer.tsx)。 - 移动端隐藏纯标题 Header:语言与时区、使用记录、模型提供商、通知、第三方账号、账单与发票页面的 Header 只有标题文案,移动端隐藏整个 Header,不保留高度和底部分隔线。
- 移动端保留功能型 Header:团队管理、自定义域名和 API 密钥的 Header 包含选择器、操作按钮或教程入口,移动端继续显示。
- 个人信息页在移动端继续纵向排列,避免固定 330px 左栏造成横向滚动(见 projects/app/src/pages/account/info/index.tsx 中
isPc分支)。 - 滚动所有权规则:移动端只有
AccountContainer中 navbar 下方的主内容区负责纵向滚动;页面 Header、筛选区、表格、分页和其他内容作为一个整体滚动。各页面内部的独立纵向滚动仅在桌面端启用,表格仍可按需横向滚动。
这一策略在共享样式常量中有明确编码:accountPageRootStyles用h: ['auto', '100%']让移动端由内容撑开、桌面端占满高度;accountContentScrollStyles用flex: ['0 0 auto', '1 0 0']、h: ['auto', 0]、overflowY: ['visible', 'auto']让内部滚动区仅在桌面端接管纵向滚动(见 styles.ts)。
验证方式:改造后的自查清单
设计文档给出了一套可执行的验收步骤,与仓库中"局部 lint + 类型检查 + 视口复核"的实践一致:
- 对涉及文件运行ESLint(仓库根目录配置见 eslint.config.mjs)。
- 运行app TypeScript 检查(
projects/app的配置见 projects/app/tsconfig.json)。 - 启动本地页面后,至少检查1512×715 桌面视口下的账号侧栏、个人信息页和各路由 Header。
- 检查第三方资源全部关闭时导航项隐藏(对应
showThirdPartyTab的配置开关逻辑)。 - 检查窄桌面和移动端没有固定宽度溢出。
从改造 TODO 清单看,所有条目均已勾选完成,最后一条明确记录了验证结果:"运行局部 lint,并执行 app TypeScript 检查;类型检查仅剩当前分支基线中的 19 个 i18n 错误,本次文件无报错",并已对照 Figma 截图复核关键布局。这说明该设计已在仓库中完整落地,后续开发者可直接以 AccountContainer.tsx 与 styles.ts 为入口阅读具体实现。
总结:可复制的账号页改造范式
本次改造的价值在于它划清了三条边界:
- 壳与内容的边界:
SecondaryNavigationContainer负责侧栏、移动端导航与主内容容器;各路由负责自身 Header、padding 与滚动。 - 共享与独立的边界:只抽象
AccountContainer与accountTitleTextStyles这类稳定视觉/结构,拒绝为业务差异明显的 Header 造通用组件。 - 滚动所有权的边界:移动端统一由主内容区整体滚动,桌面端由表格页面内部滚动,并利用"padding 进滚动容器"实现滚动条贴边。
这三条边界共同支撑起"全高、无卡片、两栏自适应"的账号页体验,也保证了权限过滤、套餐开关、空状态等既有业务逻辑零改动。对任何需要重构账号/设置类页面的团队而言,这份设计与实现的对应关系都是一份值得直接参考的落地范本。
【免费下载链接】FastGPTFastGPT is a knowledge-based platform built on the LLMs, offers a comprehensive suite of out-of-the-box capabilities such as data processing, RAG retrieval, and visual AI workflow orchestration, letting you easily develop and deploy complex question-answering systems without the need for extensive setup or configuration.项目地址: https://gitcode.com/GitHub_Trending/fa/FastGPT
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考