151 lines
7.7 KiB
Markdown
151 lines
7.7 KiB
Markdown
---
|
||
name: fms-vue业务架构搭建
|
||
overview: 参考 fms-vue-old2 搭建 fms-vue 的业务架构:迁移 api 请求层(TS→JS)、auth 登录态 store(localStorage 持久化)、路由(登录守卫 + NProgress),App.vue 改为 router-view 业务壳,新增登录页与 dashboard 临时占位页,组件库 demo 挂到 /demo 路由保留。
|
||
design:
|
||
architecture:
|
||
framework: vue
|
||
styleKeywords:
|
||
- 现代企业
|
||
- 简洁克制
|
||
- 居中卡片
|
||
- 柔和阴影
|
||
- 加载动效
|
||
fontSystem:
|
||
fontFamily: Noto Sans SC
|
||
heading:
|
||
size: 24px
|
||
weight: 600
|
||
subheading:
|
||
size: 14px
|
||
weight: 500
|
||
body:
|
||
size: 14px
|
||
weight: 400
|
||
colorSystem:
|
||
primary:
|
||
- "#0f172b"
|
||
- "#ffffff"
|
||
background:
|
||
- "#f5f6f8"
|
||
- "#ffffff"
|
||
text:
|
||
- "#1f2329"
|
||
- "#86909c"
|
||
- "#ffffff"
|
||
functional:
|
||
- "#ef4444"
|
||
- "#16a34a"
|
||
- "#f59e0b"
|
||
todos:
|
||
- id: migrate-services
|
||
content: 迁移 services/http.js、services/api.js 与 stores/auth.js 为 JS(接口与持久化逻辑同 old2)
|
||
status: completed
|
||
- id: rewrite-router
|
||
content: 重写 router/index.js:/login、/dashboard、/demo、404 路由 + NProgress + 登录守卫
|
||
status: completed
|
||
dependencies:
|
||
- migrate-services
|
||
- id: login-page
|
||
content: 用自研组件实现登录页与 dashboard 占位页,参考 [skill:ui-ux-pro-max] 完成视觉设计
|
||
status: completed
|
||
dependencies:
|
||
- rewrite-router
|
||
- id: app-entry-demo
|
||
content: 改造 App.vue 为业务入口,迁移 demo 壳至 views/demo/index.vue 并挂 /demo 路由
|
||
status: completed
|
||
dependencies:
|
||
- rewrite-router
|
||
---
|
||
|
||
## 产品概述
|
||
|
||
将 fms-vue(当前为纯组件库 demo 项目)升级为业务应用骨架,路由、缓存等架构参考 fms-vue-old2,api 请求接口不变(TS 转 JS)。本次交付:路由、App.vue 业务入口、登录页及登录链路,组件库 demo 保留在 /demo 路由。
|
||
|
||
## 核心功能
|
||
|
||
- 路由体系:/login(登录页)、/dashboard(临时占位页,登录后落地)、/demo(组件库展示页保留)、catchAll 重定向;NProgress 顶部进度条
|
||
- 登录守卫:未登录访问受保护页自动跳 /login?redirect=xxx,已登录访问 /login 自动跳 /dashboard(本次不做权限校验)
|
||
- 登录页:机构码 + 账号 + 密码,回车/按钮提交,登录成功写入会话并跳转,失败 Message 提示;用 fms-vue 自研组件(Form/Input/Button/Message)实现
|
||
- api 服务:axios 实例 + 统一响应结构处理 + 401/40101 自动登出跳转;登录/数据查询等接口函数保持与 old2 完全一致(仅 TS 转 JS)
|
||
- 认证缓存:auth store 持久化到 localStorage(key: fms-auth),刷新页面保持登录态
|
||
- App.vue 改为纯业务入口(router-view),原组件 demo 壳迁移为独立页面
|
||
|
||
## 技术栈
|
||
|
||
- Vue 3.5 + Vite 8(vite.config.js 已有 @ 别名、端口 5082)
|
||
- vue-router 5 + Pinia + pinia-plugin-persistedstate + axios + nprogress + @lucide/vue(全部为现有依赖,不新增)
|
||
- 纯 JavaScript(用户明确要求 TS 转 JS),自研组件库实现 UI
|
||
|
||
## 实现方案
|
||
|
||
- 分层架构:views(页面)→ router(路由+守卫)→ stores(状态+持久化)→ services(http 封装 + api 接口)
|
||
- http.js 沿用 old2 的拦截器模式:请求拦截器在调用时注入 Bearer token(拦截器内部调用 useAuthStore,保证 pinia 激活);响应拦截器统一按 ApiResult 结构(code===0 成功)处理,401/40101 清会话并跳转 /login?reason=,业务错误抛 Error(message 可直接提示)
|
||
- auth.js 沿用 old2 的 persist 配置:key="fms-auth"、storage=localStorage、pick=["token","orgId","user"],保留 sessionStorage 迁移逻辑;isAuthenticated 由 token 派生
|
||
- 路由守卫:beforeEach 中 NProgress.start + 登录判定(requiresAuth meta),afterEach NProgress.done;本次不含 permissions 权限校验
|
||
- 登录页 UI 用自研组件:Form(vertical 布局 + required 校验)包裹 Input(prefix 图标插槽)、Button(loading/block),Message 命令式提示;不引入 vee-validate/zod/vue-sonner
|
||
- 保留现有主题体系(stores/app.js、tokens.css、initThemeSync、index.html 防闪烁脚本)不动
|
||
|
||
## 架构与数据流
|
||
|
||
```mermaid
|
||
flowchart LR
|
||
A[用户访问 /] --> B{router.beforeEach}
|
||
B -->|未登录| C[/login?redirect=xxx/]
|
||
B -->|已登录| D[/dashboard/ 占位页]
|
||
C --> E[login/index.vue]
|
||
E -->|loginApi| F[http.js axios 实例]
|
||
F -->|Bearer token| G[后端 /api]
|
||
E -->|setSession| H[auth store 持久化 fms-auth]
|
||
E -->|router.replace redirect| D
|
||
G -->|401/40101| I[清会话 + 跳登录]
|
||
```
|
||
|
||
## 目录结构(变更清单)
|
||
|
||
```
|
||
fms-vue/
|
||
├── src/
|
||
│ ├── services/
|
||
│ │ ├── http.js # [NEW] axios 实例 + 拦截器(TS 转 JS,逻辑与 old2 一致)
|
||
│ │ └── api.js # [NEW] 接口函数:loginApi/loadDataApi/loadDataBySqlApi/pageDataApi/saveObjectApi/nextIdApi/nextCodeApi/describeApi(路径参数完全不变)
|
||
│ ├── stores/
|
||
│ │ ├── auth.js # [NEW] 认证 store:token/orgId/user/isAuthenticated + setSession/clearSession,persist key=fms-auth
|
||
│ │ └── app.js # 现有主题 store,保持不动
|
||
│ ├── router/
|
||
│ │ └── index.js # [MODIFY] 重写:路由表 + NProgress + 登录守卫(懒加载视图)
|
||
│ ├── views/
|
||
│ │ ├── login/index.vue # [NEW] 登录页:Form+Input+Button+Message,逻辑与 old2 一致
|
||
│ │ ├── dashboard/index.vue# [NEW] 临时占位页(标题+建设中提示)
|
||
│ │ └── demo/index.vue # [NEW] 原 App.vue demo 壳整体迁移,import 改 @/ 别名
|
||
│ ├── App.vue # [MODIFY] 改为业务入口:仅 <router-view />
|
||
│ └── main.js # 保持现状(pinia/persist/router/initThemeSync 已就绪)
|
||
├── index.html # [MODIFY] title 改为 FMS(防闪烁脚本无需改)
|
||
└── vite.config.js # 保持现状
|
||
```
|
||
|
||
## 关键约定
|
||
|
||
- http.js 响应结构:`{ success, code, message, data }`,无 code 字段时按成功透传
|
||
- 登录成功跳转:`router.replace(route.query.redirect || '/dashboard')`
|
||
- 登录页 onMounted 回填 authStore 的 orgId 与 user.account,聚焦机构码输入框
|
||
- 不主动执行构建/测试;交付后仅静态检查,并说明手动验证路径
|
||
|
||
## 设计风格
|
||
|
||
登录页采用现代企业 SaaS 风格,与现有 fms-vue 组件库视觉语言(--fms-* token)完全一致:浅灰背景 + 白色居中卡片,卡片带柔和阴影与圆角;品牌区展示 FMS Logo 与标题,表单区为机构码/账号/密码三个图标前缀输入框 + 通栏主色登录按钮;提交时按钮 loading 态,错误用 Message 顶部提示。整体简洁克制,信息层级清晰,支持深色模式(复用现有 tokens)。
|
||
|
||
## 页面布局(自上而下分块)
|
||
|
||
1. 全屏容器:flex 居中,背景 --fms-background,适配小屏(min-height: 100svh、p-6)
|
||
2. 品牌块:居中 Logo 图标 + "登录 FMS" 标题(约 24px 加粗)
|
||
3. 提示条(可选):reason=expired/session-replaced 时展示琥珀色警示条
|
||
4. 登录表单:Form vertical 布局,三个 Input(Building2/User/KeyRound 前缀图标),必填红星,回车即提交
|
||
5. 提交按钮:Button block 通栏,submitting 时 loading 态并禁用
|
||
|
||
## Agent Extensions
|
||
|
||
### Skill
|
||
|
||
- **ui-ux-pro-max**
|
||
- 用途:登录页视觉设计参考——现代企业 SaaS 登录页的布局、配色、排版与微交互(加载态、焦点态)
|
||
- 预期结果:登录页 UI 在复用 fms-vue 自研组件与 --fms-* token 的前提下,达到专业、精致的企业级视觉效果 |