Commit 6976b8200b3bc28d78655be6d5ef6369d3f33430

Authored by zichun
1 parent d0648b5e

docs(usr): 前端重写设计文档

docs/superpowers/specs/2026-05-08-frontend-design.md 0 → 100644
  1 +# 前端重写设计文档
  2 +
  3 +**日期**: 2026-05-08
  4 +**范围**: USR 模块前端 — 登录、用户列表、用户单据
  5 +**参考原型**: `prototype/erp.html`
  6 +**技术栈**: 不变(React 18 + Ant Design 5 + Redux Toolkit + React Router v6 + Vite)
  7 +
  8 +---
  9 +
  10 +## 一、核心决策记录
  11 +
  12 +| 决策项 | 结论 | 说明 |
  13 +|---|---|---|
  14 +| 导航结构 | 原型 Tab 顶栏,无侧边栏 | 与 docs/06 § 1.1 不符,已与用户确认,本文档为准 |
  15 +| 用户表单形式 | 全屏单据页(独立 Tab) | 替代原 Drawer;与原型一致 |
  16 +| Tab 状态管理 | Redux `tabsSlice` | 切换 Tab 时 React Router navigate + 列表筛选存 URL query,保证状态可恢复 |
  17 +| 主页 | 占位页面 | KPI 看板后续模块实现 |
  18 +| 现有 api / store | 保留不动 | 逻辑正确,仅重写 UI 层 |
  19 +
  20 +> **docs/06 偏差声明**: docs/06 § 1.1 规定 Header + Sider + Content 经典 Admin 布局。本设计采用原型的 Tab 顶栏导航,无侧边栏。后续若文档更新,以本文档为 USR 模块实现基准。
  21 +
  22 +---
  23 +
  24 +## 二、架构
  25 +
  26 +```
  27 +React Router v6 (路由/渲染)
  28 + + tabsSlice (Redux) (Tab 列表 / activeId)
  29 + ↓
  30 +AppShell (深色顶栏 + Tab 栏 + NavOverlay)
  31 + ↓
  32 +页面组件 (LoginPage / MainPage / UserListPage / UserDetailPage)
  33 + ↓
  34 +api/ (Axios,保留) + store/slices/authSlice (保留)
  35 +```
  36 +
  37 +**Tab 切换机制**:
  38 +- Tab 切换 = `navigate(tab.path)` + Redux `activateTab(id)`
  39 +- 列表筛选条件持久化到 URL query string(如 `/usr/users?queryField=username&queryValue=管广飞`),切回时自动恢复
  40 +- 用户单据 Tab 固定 id `"userdetail"`,新增/编辑复用同一 Tab
  41 +
  42 +---
  43 +
  44 +## 三、路由结构
  45 +
  46 +| 路径 | 页面 | Tab 行为 |
  47 +|---|---|---|
  48 +| `/login` | LoginPage | 无 Shell,全屏 |
  49 +| `/` | MainPage | 固定 Tab "主页",不可关闭 |
  50 +| `/usr/users` | UserListPage | Tab "用户列表",可关闭 |
  51 +| `/usr/users/new` | UserDetailPage (新增模式) | Tab "用户信息单据",可关闭 |
  52 +| `/usr/users/:id` | UserDetailPage (编辑模式) | 复用 Tab "用户信息单据",可关闭 |
  53 +
  54 +---
  55 +
  56 +## 四、文件变更清单
  57 +
  58 +### 新建
  59 +
  60 +| 文件 | 职责 |
  61 +|---|---|
  62 +| `src/store/slices/tabsSlice.ts` | Tab 状态:`tabs: Tab[]`、`activeId: string \| null`;actions: `openTab` / `closeTab` / `activateTab` |
  63 +| `src/components/AppShell.tsx` | 深色顶栏 + Tab 栏 + NavOverlay 入口;包裹所有已登录页面 |
  64 +| `src/components/NavOverlay.tsx` | 全屏模块导航(按 prototype § nav-overlay 还原);当前阶段仅"用户列表"可点击,其余展示占位 |
  65 +| `src/pages/MainPage.tsx` | 主页占位 |
  66 +| `src/pages/usr/UserDetailPage.tsx` | 全屏用户单据页:深色工具栏(新增/修改/删除/保存/取消/作废/重置密码)+ 3 列表单网格 + 权限组 Tab 列表 |
  67 +
  68 +### 重写(逻辑不变,仅 UI 层)
  69 +
  70 +| 文件 | 改动说明 |
  71 +|---|---|
  72 +| `src/pages/usr/LoginPage.tsx` | 还原原型登录视觉:蓝色渐变 hero + 右侧白色登录卡片;API 调用逻辑保留 |
  73 +| `src/pages/usr/UserListPage.tsx` | 还原原型列表视觉:深色工具栏 + filterbar + 带单选圆点的表格;双击行导航到单据页 |
  74 +| `src/App.tsx` | 路由改用 AppShell 包裹;新增 `/usr/users/new` 和 `/usr/users/:id` 路由 |
  75 +| `src/styles/tokens.css` | 追加原型色值 token(见 § 五) |
  76 +
  77 +### 删除
  78 +
  79 +| 文件 | 原因 |
  80 +|---|---|
  81 +| `src/pages/usr/UserFormDrawer.tsx` | 由 UserDetailPage 全屏单据页替代 |
  82 +
  83 +### 保留不动
  84 +
  85 +- `src/api/` — auth.ts / usr.ts / request.ts
  86 +- `src/store/slices/authSlice.ts`
  87 +- `src/store/index.ts`、`src/store/hooks.ts`
  88 +- `src/components/PermButton.tsx`
  89 +
  90 +---
  91 +
  92 +## 五、新增 Design Tokens
  93 +
  94 +在 `src/styles/tokens.css` `:root` 块追加:
  95 +
  96 +| 变量名 | 值 | 用途 |
  97 +|---|---|---|
  98 +| `--color-topbar-bg` | `#1f1f23` | 顶栏背景 |
  99 +| `--color-toolbar-bg` | `#2c2f36` | 深色工具栏背景 |
  100 +| `--color-toolbar-text` | `#e6e7ea` | 深色工具栏文字 |
  101 +| `--color-tab-active` | `#1e84e6` | 活动 Tab 文字 / 下划线 |
  102 +| `--color-tab-text` | `#9aa0a8` | 非活动 Tab 文字 |
  103 +| `--color-field-bg-edit` | `#eaf3fe` | 可编辑表单字段背景 |
  104 +| `--color-field-label-req` | `#f04848` | 必填标签色(* 号) |
  105 +| `--color-table-border` | `#e3e6eb` | 表格边框 |
  106 +| `--color-table-row-alt` | `#f7f8fa` | 表格隔行背景色 |
  107 +| `--color-filterbar-bg` | `#ffffff` | 筛选栏背景 |
  108 +| `--color-nav-overlay-bg` | `#2b3137` | 导航 Overlay 背景 |
  109 +
  110 +---
  111 +
  112 +## 六、页面规格
  113 +
  114 +### 6.1 LoginPage
  115 +
  116 +- 全屏两分区:左侧蓝色渐变 hero(`radial-gradient` 深蓝)+ 网格背景 + 品牌文字;右侧白色登录卡片
  117 +- 卡片内:用户名输入框 / 密码输入框 / 公司版本下拉(从 `getBrands()` 加载)/ 登录按钮
  118 +- 登录成功后 → navigate('/') + 打开"主页" Tab
  119 +
  120 +### 6.2 AppShell
  121 +
  122 +- 高度 44px 深色顶栏,从左到右:Logo(鹿角 SVG)/ "全部导航"按钮 / Tab 列表 / 右侧用户信息
  123 +- Tab 列表:每个 Tab 含标题 + 关闭按钮(✕);活动 Tab 蓝色下划线;主页 Tab 无关闭按钮
  124 +- 点"全部导航"展开 NavOverlay;点 Tab 切换路由;点✕关闭 Tab 并跳转到前一个 Tab
  125 +
  126 +### 6.3 NavOverlay
  127 +
  128 +- 全屏覆盖层,背景 `#2b3137`
  129 +- 左侧:模块分类列表(系统管理高亮,其余占位)
  130 +- 右侧网格:按 prototype 还原 7 列模块链接;仅"用户列表"绑定 `openTab + navigate`
  131 +- 点击任意区域外(或再次点"全部导航")收起
  132 +
  133 +### 6.4 UserListPage
  134 +
  135 +- 深色工具栏:刷新 / 新增(`usr:create` 权限)/ 导出Excel
  136 +- Filterbar:查询字段 Select + 匹配方式 Select + 查询值 Input + 搜索按钮 + 清空按钮
  137 +- 表格:带单选圆点列 + 序号列 + 用户名/员工名/用户号/部门/用户类型/语言/作废/登录日期/制单人/制单日期
  138 +- 双击行 → navigate(`/usr/users/${row.sId}`)
  139 +- 点"新增" → navigate('/usr/users/new')
  140 +- 筛选条件同步到 URL query string
  141 +
  142 +### 6.5 UserDetailPage
  143 +
  144 +- 深色工具栏:新增 / 修改 / 删除 / 保存 / 取消 / 作废 / 重置密码
  145 +- 3 列表单网格(与原型一致):创建时间(只读)/ 制单人(只读)/ 员工名(下拉,可选)/ 用户名 / 类型 / 语言 / 用户号 / 单据修改权限(复选框)
  146 +- 可编辑字段背景 `--color-field-bg-edit`,只读字段背景 `--color-bg-input-readonly`
  147 +- 权限组 Tab:横排 Tab 栏(权限组 / 客户查看权限等占位)+ 权限列表(复选框 + 权限名)
  148 +- 新增模式:表单空白,保存调 `POST /api/usr/users`
  149 +- 编辑模式:行数据通过 React Router `location.state` 从列表页传入(后端无单条 GET by ID 接口);若直接访问 URL 但 state 为空,redirect 回 `/usr/users`
  150 +- 保存编辑调 `PUT /api/usr/users/:id`
  151 +- 删除、作废、重置密码:当前阶段按钮展示但不实现(REQ 范围外)
  152 +
  153 +---
  154 +
  155 +## 七、超出 REQ 范围的按钮处理
  156 +
  157 +工具栏中"删除"、"作废"、"取消作废"、"重置密码"在原型中存在,但当前 REQ-USR-001/002 未覆盖对应接口。这些按钮渲染但 `disabled`,tooltip 提示"功能待实现"。
... ...