Skip to content

前端应用

vilas edited this page Aug 25, 2026 · 1 revision

前端应用

**本文引用的文件** - [frontends/admin/package.json](https://github.com/voidvec/fulla/blob/master/frontends/admin/package.json) - [frontends/user/package.json](https://github.com/voidvec/fulla/blob/master/frontends/user/package.json) - [frontends/admin/src/main.ts](https://github.com/voidvec/fulla/blob/master/frontends/admin/src/main.ts) - [frontends/user/src/main.ts](https://github.com/voidvec/fulla/blob/master/frontends/user/src/main.ts) - [frontends/admin/vite.config.ts](https://github.com/voidvec/fulla/blob/master/frontends/admin/vite.config.ts) - [frontends/user/vite.config.ts](https://github.com/voidvec/fulla/blob/master/frontends/user/vite.config.ts) - [frontends/admin/src/router/index.ts](https://github.com/voidvec/fulla/blob/master/frontends/admin/src/router/index.ts) - [frontends/user/src/router/index.ts](https://github.com/voidvec/fulla/blob/master/frontends/user/src/router/index.ts) - [frontends/admin/src/stores/auth.ts](https://github.com/voidvec/fulla/blob/master/frontends/admin/src/stores/auth.ts) - [frontends/user/src/stores/auth.ts](https://github.com/voidvec/fulla/blob/master/frontends/user/src/stores/auth.ts) - [frontends/admin/src/App.vue](https://github.com/voidvec/fulla/blob/master/frontends/admin/src/App.vue) - [frontends/user/src/App.vue](https://github.com/voidvec/fulla/blob/master/frontends/user/src/App.vue) - [frontends/admin/src/components/layout/AdminLayout.vue](https://github.com/voidvec/fulla/blob/master/frontends/admin/src/components/layout/AdminLayout.vue) - [frontends/user/src/layouts/AuthLayout.vue](https://github.com/voidvec/fulla/blob/master/frontends/user/src/layouts/AuthLayout.vue) - [frontends/admin/src/pages/dashboard/DashboardPage.vue](https://github.com/voidvec/fulla/blob/master/frontends/admin/src/pages/dashboard/DashboardPage.vue) - [frontends/user/src/pages/auth/LoginPage.vue](https://github.com/voidvec/fulla/blob/master/frontends/user/src/pages/auth/LoginPage.vue) - [frontends/user/src/pages/oauth/ConsentPage.vue](https://github.com/voidvec/fulla/blob/master/frontends/user/src/pages/oauth/ConsentPage.vue) - [frontends/admin/src/services/errorAdapter.ts](https://github.com/voidvec/fulla/blob/master/frontends/admin/src/services/errorAdapter.ts)

目录

  1. 简介
  2. 项目结构
  3. 核心组件
  4. 架构总览
  5. 详细组件分析
  6. 依赖关系分析
  7. 性能考虑
  8. 故障排查指南
  9. 结论
  10. 附录

简介

本文件为 Fulla 前端应用的完整技术文档,覆盖管理控制台(frontends/admin)与用户界面(frontends/user)的功能、实现与开发指南。重点包括:

  • 管理控制台模块结构与页面:仪表板、应用管理、用户管理、角色权限、令牌管理等
  • 用户界面认证流程、账户管理与 OAuth 同意页等自服务功能
  • 前端技术栈:Vue 3 + Vite + Pinia + TailwindCSS
  • 路由配置、状态管理、组件复用与样式系统
  • 开发环境搭建、构建流程与测试方法
  • UI 组件使用示例与自定义指南

项目结构

两个独立的前端应用共享相似的技术栈与工程化方案,但职责不同:

  • frontends/admin:管理控制台,面向管理员,提供平台运营能力
  • frontends/user:用户界面,面向终端用户,提供登录注册、OAuth 同意、账户管理等
graph TB
subgraph "管理控制台 (admin)"
A_main["main.ts"]
A_router["router/index.ts"]
A_store_auth["stores/auth.ts"]
A_layout["components/layout/AdminLayout.vue"]
A_dashboard["pages/dashboard/DashboardPage.vue"]
A_error["services/errorAdapter.ts"]
end
subgraph "用户界面 (user)"
U_main["main.ts"]
U_router["router/index.ts"]
U_store_auth["stores/auth.ts"]
U_layout["layouts/AuthLayout.vue"]
U_login["pages/auth/LoginPage.vue"]
U_consent["pages/oauth/ConsentPage.vue"]
end
A_main --> A_router
A_main --> A_store_auth
A_router --> A_layout
A_layout --> A_dashboard
A_store_auth --> A_error
U_main --> U_router
U_main --> U_store_auth
U_router --> U_layout
U_layout --> U_login
U_layout --> U_consent
Loading

图表来源

章节来源

核心组件

  • 应用入口
    • admin:创建 Vue 应用、挂载 Pinia 与 Router,启动时恢复会话并挂载根组件
    • user:创建 Vue 应用、挂载 Pinia 与 Router,并在存在刷新令牌时尝试恢复会话
  • 路由守卫与会话恢复
    • admin:对 requiresAuth 的路由进行鉴权,必要时等待一次性会话恢复后再放行或跳转登录
    • user:根据 meta.auth/guest 控制访问,未登录且需要保护时重定向到登录并携带 redirect
  • 状态管理
    • admin:集中管理 access_token、refresh_token、用户信息;封装登录、刷新、登出、错误归一化与拦截器
    • user:通过 service 层调用后端接口,维护用户信息与登录态,支持 MFA、授权码交换与退出
  • 布局与页面
    • admin:AdminLayout 提供侧边栏导航、面包屑、用户菜单与响应式交互;Dashboard 聚合健康检查与统计卡片
    • user:AuthLayout 提供品牌展示与表单容器;LoginPage 处理登录与 MFA;ConsentPage 处理 OAuth 同意与参数透传

章节来源

架构总览

前后端分离,Vite 作为开发与构建工具,TailwindCSS 提供原子化样式,Pinia 管理状态,Vue Router 负责路由与导航。管理控制台采用“登录后直调”的 JSON 模式获取授权码并换发令牌;用户界面遵循标准 OAuth/OIDC 流程,包含登录、MFA、授权同意与回调。

sequenceDiagram
participant Admin as "管理控制台"
participant UserUI as "用户界面"
participant API as "后端 /oauth2"
participant Store as "Pinia 状态"
Admin->>Store : 初始化(恢复会话/监听路由)
UserUI->>Store : 初始化(恢复会话/监听路由)
Note over Admin,UserUI : 首次进入受保护路由时触发鉴权
Admin->>API : POST /oauth2/login (JSON 模式)
API-->>Admin : {code|{mfa_required}}
alt 需要 MFA
Admin->>API : POST /oauth2/mfa/verify
API-->>Admin : {code}
end
Admin->>API : POST /oauth2/token (grant_type=authorization_code)
API-->>Admin : {access_token, refresh_token}
Admin->>Store : 写入令牌/用户信息
Admin->>API : GET /oauth2/userinfo
API-->>Admin : 用户信息
UserUI->>API : 标准授权流程(含 consent/device 等)
API-->>UserUI : 回调/同意结果
UserUI->>Store : 更新登录态
Loading

图表来源

详细组件分析

管理控制台(Admin)

  • 路由与鉴权
    • 定义登录、回调及受保护的子路由(仪表板、应用、用户、角色、范围、日志、令牌、设置)
    • beforeEach 中等待一次性会话恢复,避免误判未登录而跳转
  • 布局与导航
    • 侧边栏分组导航、折叠、移动端抽屉、面包屑与用户下拉菜单
    • 登出调用 store.logout 并跳转登录页
  • 仪表板
    • 并行请求健康检查与统计数据,失败时统一归一化错误并展示
    • 骨架屏在加载期间提升体验
  • 状态管理
    • 登录流程:POST /oauth2/login → 可选 MFA → POST /oauth2/token → 获取用户信息 → 校验 admin 角色
    • 自动刷新:Axios 拦截器在 401 时尝试刷新令牌,失败则清理会话并提示“登录已过期”
    • 安全策略:access_token 仅内存存储,refresh_token 持久化于 sessionStorage,异常降级不影响基本功能
flowchart TD
Start(["进入受保护路由"]) --> CheckAuth{"是否已登录?"}
CheckAuth --> |是| Next["继续渲染页面"]
CheckAuth --> |否| Restore["一次性恢复会话"]
Restore --> Restored{"恢复成功?"}
Restored --> |是| Next
Restored --> |否| ToLogin["跳转到登录页"]
Loading

图表来源

章节来源

用户界面(User)

  • 路由与布局
    • 认证相关页面使用 AuthLayout,账户相关页面使用 AppLayout
    • 路由元信息区分 guest/auth,配合前置守卫进行重定向
  • 登录与 MFA
    • 支持邮箱/用户名+密码登录,若返回 mfa_required 则进入 MFA 验证流程
    • 支持 GitHub 第三方登录(通过环境变量注入客户端 ID)
  • OAuth 同意页
    • 从查询参数读取 client_id、scope、redirect_uri、state、code_challenge、nonce 等
    • 提交同意/拒绝后,服务端返回重定向地址,浏览器完成授权码回调
  • 状态管理
    • 基于 service 层封装登录、MFA、授权码交换、用户信息查询与登出
    • 页面重载时尝试用 refresh_token 恢复会话,成功后拉取用户信息
sequenceDiagram
participant U as "用户界面"
participant S as "authService"
participant API as "后端 /oauth2"
U->>S : login(username,password)
S->>API : POST /oauth2/login
API-->>S : {code | {mfa_required,mfa_token}}
alt 需要 MFA
U->>S : verifyMfa(mfa_token, code)
S->>API : POST /oauth2/mfa/verify
API-->>S : {code}
end
S->>API : POST /oauth2/token (grant_type=authorization_code)
API-->>S : {access_token, refresh_token}
S->>API : GET /oauth2/userinfo
API-->>S : 用户信息
S-->>U : 标记已登录并跳转
Loading

图表来源

章节来源

错误处理与国际化

  • 统一错误归一化模块
    • 将 Axios 错误转换为稳定结构,包含 code、message、request_id、httpStatus
    • 优先级:错误信封 > RFC 6749 协议错误 > 未知错误 > 网络错误
    • 会话过期场景生成专用 NormalizedError,便于拦截器统一处理
  • 消息目录
    • 默认语言 zh-CN,所有用户可见消息均通过目录映射,保证一致性与可本地化

章节来源

依赖关系分析

  • 技术栈与插件
    • Vue 3、Vue Router、Pinia、Axios、TailwindCSS、Vite、TypeScript、Playwright、Vitest
  • 构建与代理
    • Vite 启用 Vue 与 Tailwind 插件,开发服务器端口与路径别名配置
    • 代理 /api、/oauth2、/health、/.well-known 至本地后端服务
  • 应用间一致性
    • 错误归一化逻辑在两个前端保持一致,确保跨应用错误展示统一
graph LR
Vite["Vite 构建"] --> Vue["Vue 3"]
Vite --> Tailwind["TailwindCSS"]
Vue --> Router["Vue Router"]
Vue --> Pinia["Pinia"]
Pinia --> Axios["Axios"]
Axios --> API["后端 /oauth2"]
Loading

图表来源

章节来源

性能考虑

  • 并发刷新令牌去重:防止多请求同时刷新导致令牌失效
  • 一次性会话恢复:避免重复恢复导致的多次网络请求
  • 骨架屏与并行请求:仪表板使用骨架屏与 Promise.all 提升首屏体验
  • 按需加载:路由级动态导入减少初始包体积
  • 代理与缓存:开发期通过 Vite 代理减少跨域开销;生产部署建议结合 CDN 与静态资源缓存

[本节为通用指导,不直接分析具体文件]

故障排查指南

  • 401 自动刷新失败
    • 现象:登录后一段时间请求失败并跳转登录
    • 原因:refresh_token 过期或被撤销,刷新失败
    • 处理:清理会话、显示“登录已过期”、跳转登录
  • 网络错误
    • 现象:无 HTTP 响应或超时
    • 处理:归一化为网络错误码,展示友好提示
  • 会话恢复失败
    • 现象:刷新页面后仍被重定向到登录
    • 处理:检查 sessionStorage 中的 refresh_token 是否存在且有效
  • 授权同意页参数丢失
    • 现象:授权码颁发未携带 PKCE/nonce
    • 处理:确认同意页正确透传 code_challenge、code_challenge_method、nonce 等参数

章节来源

结论

Fulla 前端以 Vue 3 + Vite + Pinia + TailwindCSS 为基础,构建了清晰的管理控制台与用户界面。通过统一的状态管理、错误归一化与路由守卫,实现了安全的认证流程与良好的用户体验。管理控制台聚焦平台管理能力,用户界面聚焦自服务与 OAuth 流程。建议在后续迭代中持续优化首屏性能、完善端到端测试覆盖,并加强可观测性指标采集。

[本节为总结,不直接分析具体文件]

附录

开发环境搭建

  • 安装依赖
    • 进入对应前端目录执行包管理器安装命令
  • 启动开发服务器
    • 运行开发脚本,Vite 将启动本地服务并代理后端接口
  • 构建与预览
    • 执行构建脚本生成静态资源,使用预览脚本查看产物

章节来源

构建流程

  • 插件与别名
    • 启用 Vue 与 Tailwind 插件,配置路径别名与扩展名解析
  • 代理配置
    • 将 /api、/oauth2、/health、/.well-known 代理至后端服务地址

章节来源

测试方法

  • 单元测试
    • 使用 Vitest 运行单元与属性测试
  • 端到端测试
    • 使用 Playwright 编写 e2e 用例,支持 UI 模式与有头模式

章节来源

UI 组件使用示例与自定义指南

  • 基础组件
    • 按钮、输入框、告警、卡片、表格、模态框、空状态、骨架屏等
  • 布局组件
    • 管理控制台侧边栏布局、用户界面认证布局
  • 自定义指南
    • 基于 Tailwind 原子类快速组合样式
    • 通过 props 暴露可控行为,保持组件单一职责
    • 复用全局设计令牌与主题变量,确保视觉一致性

章节来源

fulla wiki

Clone this wiki locally