diff --git a/docs/superpowers/specs/2026-05-08-frontend-design.md b/docs/superpowers/specs/2026-05-08-frontend-design.md new file mode 100644 index 0000000..fc57f3f --- /dev/null +++ b/docs/superpowers/specs/2026-05-08-frontend-design.md @@ -0,0 +1,157 @@ +# 前端重写设计文档 + +**日期**: 2026-05-08 +**范围**: USR 模块前端 — 登录、用户列表、用户单据 +**参考原型**: `prototype/erp.html` +**技术栈**: 不变(React 18 + Ant Design 5 + Redux Toolkit + React Router v6 + Vite) + +--- + +## 一、核心决策记录 + +| 决策项 | 结论 | 说明 | +|---|---|---| +| 导航结构 | 原型 Tab 顶栏,无侧边栏 | 与 docs/06 § 1.1 不符,已与用户确认,本文档为准 | +| 用户表单形式 | 全屏单据页(独立 Tab) | 替代原 Drawer;与原型一致 | +| Tab 状态管理 | Redux `tabsSlice` | 切换 Tab 时 React Router navigate + 列表筛选存 URL query,保证状态可恢复 | +| 主页 | 占位页面 | KPI 看板后续模块实现 | +| 现有 api / store | 保留不动 | 逻辑正确,仅重写 UI 层 | + +> **docs/06 偏差声明**: docs/06 § 1.1 规定 Header + Sider + Content 经典 Admin 布局。本设计采用原型的 Tab 顶栏导航,无侧边栏。后续若文档更新,以本文档为 USR 模块实现基准。 + +--- + +## 二、架构 + +``` +React Router v6 (路由/渲染) + + tabsSlice (Redux) (Tab 列表 / activeId) + ↓ +AppShell (深色顶栏 + Tab 栏 + NavOverlay) + ↓ +页面组件 (LoginPage / MainPage / UserListPage / UserDetailPage) + ↓ +api/ (Axios,保留) + store/slices/authSlice (保留) +``` + +**Tab 切换机制**: +- Tab 切换 = `navigate(tab.path)` + Redux `activateTab(id)` +- 列表筛选条件持久化到 URL query string(如 `/usr/users?queryField=username&queryValue=管广飞`),切回时自动恢复 +- 用户单据 Tab 固定 id `"userdetail"`,新增/编辑复用同一 Tab + +--- + +## 三、路由结构 + +| 路径 | 页面 | Tab 行为 | +|---|---|---| +| `/login` | LoginPage | 无 Shell,全屏 | +| `/` | MainPage | 固定 Tab "主页",不可关闭 | +| `/usr/users` | UserListPage | Tab "用户列表",可关闭 | +| `/usr/users/new` | UserDetailPage (新增模式) | Tab "用户信息单据",可关闭 | +| `/usr/users/:id` | UserDetailPage (编辑模式) | 复用 Tab "用户信息单据",可关闭 | + +--- + +## 四、文件变更清单 + +### 新建 + +| 文件 | 职责 | +|---|---| +| `src/store/slices/tabsSlice.ts` | Tab 状态:`tabs: Tab[]`、`activeId: string \| null`;actions: `openTab` / `closeTab` / `activateTab` | +| `src/components/AppShell.tsx` | 深色顶栏 + Tab 栏 + NavOverlay 入口;包裹所有已登录页面 | +| `src/components/NavOverlay.tsx` | 全屏模块导航(按 prototype § nav-overlay 还原);当前阶段仅"用户列表"可点击,其余展示占位 | +| `src/pages/MainPage.tsx` | 主页占位 | +| `src/pages/usr/UserDetailPage.tsx` | 全屏用户单据页:深色工具栏(新增/修改/删除/保存/取消/作废/重置密码)+ 3 列表单网格 + 权限组 Tab 列表 | + +### 重写(逻辑不变,仅 UI 层) + +| 文件 | 改动说明 | +|---|---| +| `src/pages/usr/LoginPage.tsx` | 还原原型登录视觉:蓝色渐变 hero + 右侧白色登录卡片;API 调用逻辑保留 | +| `src/pages/usr/UserListPage.tsx` | 还原原型列表视觉:深色工具栏 + filterbar + 带单选圆点的表格;双击行导航到单据页 | +| `src/App.tsx` | 路由改用 AppShell 包裹;新增 `/usr/users/new` 和 `/usr/users/:id` 路由 | +| `src/styles/tokens.css` | 追加原型色值 token(见 § 五) | + +### 删除 + +| 文件 | 原因 | +|---|---| +| `src/pages/usr/UserFormDrawer.tsx` | 由 UserDetailPage 全屏单据页替代 | + +### 保留不动 + +- `src/api/` — auth.ts / usr.ts / request.ts +- `src/store/slices/authSlice.ts` +- `src/store/index.ts`、`src/store/hooks.ts` +- `src/components/PermButton.tsx` + +--- + +## 五、新增 Design Tokens + +在 `src/styles/tokens.css` `:root` 块追加: + +| 变量名 | 值 | 用途 | +|---|---|---| +| `--color-topbar-bg` | `#1f1f23` | 顶栏背景 | +| `--color-toolbar-bg` | `#2c2f36` | 深色工具栏背景 | +| `--color-toolbar-text` | `#e6e7ea` | 深色工具栏文字 | +| `--color-tab-active` | `#1e84e6` | 活动 Tab 文字 / 下划线 | +| `--color-tab-text` | `#9aa0a8` | 非活动 Tab 文字 | +| `--color-field-bg-edit` | `#eaf3fe` | 可编辑表单字段背景 | +| `--color-field-label-req` | `#f04848` | 必填标签色(* 号) | +| `--color-table-border` | `#e3e6eb` | 表格边框 | +| `--color-table-row-alt` | `#f7f8fa` | 表格隔行背景色 | +| `--color-filterbar-bg` | `#ffffff` | 筛选栏背景 | +| `--color-nav-overlay-bg` | `#2b3137` | 导航 Overlay 背景 | + +--- + +## 六、页面规格 + +### 6.1 LoginPage + +- 全屏两分区:左侧蓝色渐变 hero(`radial-gradient` 深蓝)+ 网格背景 + 品牌文字;右侧白色登录卡片 +- 卡片内:用户名输入框 / 密码输入框 / 公司版本下拉(从 `getBrands()` 加载)/ 登录按钮 +- 登录成功后 → navigate('/') + 打开"主页" Tab + +### 6.2 AppShell + +- 高度 44px 深色顶栏,从左到右:Logo(鹿角 SVG)/ "全部导航"按钮 / Tab 列表 / 右侧用户信息 +- Tab 列表:每个 Tab 含标题 + 关闭按钮(✕);活动 Tab 蓝色下划线;主页 Tab 无关闭按钮 +- 点"全部导航"展开 NavOverlay;点 Tab 切换路由;点✕关闭 Tab 并跳转到前一个 Tab + +### 6.3 NavOverlay + +- 全屏覆盖层,背景 `#2b3137` +- 左侧:模块分类列表(系统管理高亮,其余占位) +- 右侧网格:按 prototype 还原 7 列模块链接;仅"用户列表"绑定 `openTab + navigate` +- 点击任意区域外(或再次点"全部导航")收起 + +### 6.4 UserListPage + +- 深色工具栏:刷新 / 新增(`usr:create` 权限)/ 导出Excel +- Filterbar:查询字段 Select + 匹配方式 Select + 查询值 Input + 搜索按钮 + 清空按钮 +- 表格:带单选圆点列 + 序号列 + 用户名/员工名/用户号/部门/用户类型/语言/作废/登录日期/制单人/制单日期 +- 双击行 → navigate(`/usr/users/${row.sId}`) +- 点"新增" → navigate('/usr/users/new') +- 筛选条件同步到 URL query string + +### 6.5 UserDetailPage + +- 深色工具栏:新增 / 修改 / 删除 / 保存 / 取消 / 作废 / 重置密码 +- 3 列表单网格(与原型一致):创建时间(只读)/ 制单人(只读)/ 员工名(下拉,可选)/ 用户名 / 类型 / 语言 / 用户号 / 单据修改权限(复选框) +- 可编辑字段背景 `--color-field-bg-edit`,只读字段背景 `--color-bg-input-readonly` +- 权限组 Tab:横排 Tab 栏(权限组 / 客户查看权限等占位)+ 权限列表(复选框 + 权限名) +- 新增模式:表单空白,保存调 `POST /api/usr/users` +- 编辑模式:行数据通过 React Router `location.state` 从列表页传入(后端无单条 GET by ID 接口);若直接访问 URL 但 state 为空,redirect 回 `/usr/users` +- 保存编辑调 `PUT /api/usr/users/:id` +- 删除、作废、重置密码:当前阶段按钮展示但不实现(REQ 范围外) + +--- + +## 七、超出 REQ 范围的按钮处理 + +工具栏中"删除"、"作废"、"取消作废"、"重置密码"在原型中存在,但当前 REQ-USR-001/002 未覆盖对应接口。这些按钮渲染但 `disabled`,tooltip 提示"功能待实现"。