Commit 082973bf92c99e3521dda5a55c7f7ea24dc40533
1 parent
3119517f
docs(spec:FE-02): 派生规格
Showing
1 changed file
with
190 additions
and
0 deletions
docs/superpowers/specs/2026-06-01-FE-02.md
0 → 100644
| 1 | +# FE-02 主页与导航框架 — 实现规格(前端) | |
| 2 | + | |
| 3 | +> 阶段:前端(frontend)。作用域限定 `frontend/` 下的页面 / 组件 / 路由 / store / api / 样式。 | |
| 4 | +> SSoT 引用:原型 `prototype/erp.html`(`#topbar` / `#nav-overlay` / `#screen-main` 三区域,布局与交互权威);技术规范 `docs/04-技术规范.md` § 零 / § 二;Design Tokens `src/styles/tokens.css`;登录态来源 FE-01 规格 `docs/superpowers/specs/2026-06-01-FE-01.md`(`authSlice` + token 持久化约定)。 | |
| 5 | +> 业务功能粒度:本 FE 覆盖**登录后落地页(主页/KPI 看板)** + **应用外壳(顶栏 + 全部导航总览 overlay + 标签页栈 + 路由壳 + 路由守卫)** + **常用操作快捷入口**。它是 FE-03(用户列表)/ FE-04(用户单据)的承载容器,但不实现这两个功能本身(标签页只负责挂载与切换,目标页内容属各自 FE)。 | |
| 6 | +> 本规格只消费已锁定事实。原型 KPI 看板 / 角色流程树 / 导航分组均为**静态 demo 数据**,docs/05 未定义任何 KPI / 导航 / 仪表盘后端端点;故本壳层除复用 FE-01 已写入 `authSlice` 的当前用户身份外,**不新增后端取数**(见 § 8 决策 D1)。 | |
| 7 | + | |
| 8 | +--- | |
| 9 | + | |
| 10 | +## 1. 关联 REQ + 关联原型 | |
| 11 | + | |
| 12 | +| 维度 | 内容 | | |
| 13 | +|---|---| | |
| 14 | +| 业务功能 | FE-02 主页与导航框架(顶栏 + 全部导航总览 + 主页 KPI 看板 + 常用操作;登录后落地页与路由壳) | | |
| 15 | +| 关联 REQ | 无直接的业务 CRUD REQ。本 FE 是壳层 / 落地页,是 REQ-USR-001~004 对应前端功能(FE-03 用户列表 / FE-04 用户单据 / FE-01 登录)的**导航与承载容器**:常用操作「用户列表」与导航总览「用户管理 > 用户列表」入口指向 FE-03(`GET /api/usr/users`),新增入口指向 FE-04(`POST /api/usr/users`)。当前用户身份展示复用 FE-01 登录后写入 `authSlice` 的 `user`(来源 REQ-USR-004 响应 `user:{ id, sUserName, sUserType, sLanguage }`) | | |
| 16 | +| 关联原型 | `prototype/erp.html` → `#topbar`(顶栏)、`#nav-overlay`(全部导航总览浮层)、`#screen-main`(主页:`.kpi-head` / `.three-col` 左侧角色流程树 + `.kpi-body` KPI 网格 / `.common-ops` 常用操作 / `footer.foot` 页脚)、`.app` / `.stage` / `.screen`(屏切换壳) | | |
| 17 | +| 路由 | 应用受保护区根路由 `/`(登录后落地到主页 `/` = `<HomePage>`);子路由 `/usr/users`(FE-03)、`/usr/users/new` 与 `/usr/users/:id`(FE-04)。React Router v6,外壳布局路由 `<AppLayout>` 包裹所有受保护子路由(见 § 6 路由与守卫) | | |
| 18 | +| 落地组件目录 | `frontend/src/layouts/AppLayout/`(应用外壳:顶栏 + 标签栈 + 导航 overlay + 内容 outlet + 页脚);`frontend/src/pages/home/HomePage/`(主页 KPI 看板);`frontend/src/router/`(路由表 + `RequireAuth` 守卫);导航 / KPI / 常用操作的静态配置置于 `frontend/src/layouts/AppLayout/navConfig.ts` 与 `frontend/src/pages/home/HomePage/dashboardData.ts`;当前用户身份读 `frontend/src/store/slices/authSlice` | | |
| 19 | + | |
| 20 | +> 原型用纯静态 HTML + 内联 demo 脚本(`goTo(name)` 切 `.screen.active`、`#nav-toggle` 切换 `#nav-overlay.show`、`openTab/tabsOpen` 维护用户列表/用户单据标签的显隐、`.close` 关闭标签、`data-go` 委托点击切屏)模拟单页多屏。本规格按 React Router v6 + AntD 5 复刻其**布局与交互语义**:原型的「屏切换」改为真实路由切换,「标签栈」改为受控的标签页状态,导航与 KPI 数据改为前端静态配置(无后端)。 | |
| 21 | + | |
| 22 | +--- | |
| 23 | + | |
| 24 | +## 2. 组件树(按区域分块,推导自 prototype DOM) | |
| 25 | + | |
| 26 | +应用外壳 `AppLayout`(受保护区布局路由,对应原型 `.app`:纵向 flex、占满视口、`overflow:hidden`): | |
| 27 | + | |
| 28 | +``` | |
| 29 | +AppLayout(对应 .app:column flex / 100vh / overflow hidden;登录后所有受保护路由的外壳) | |
| 30 | +├── TopBar(对应 #topbar:高 44px 深色顶栏,z 高于内容) | |
| 31 | +│ ├── BrandLogo(对应 .logo:鹿角 SVG,点击回主页 / data-go="main",复用原型 inline svg path) | |
| 32 | +│ ├── TabStrip(对应 .tabs:左起 全部导航按钮 + 固定「主页」标签 + 动态业务标签栈) | |
| 33 | +│ │ ├── NavToggleButton(对应 .nav-btn#nav-toggle:「全部导航」汉堡按钮,切换导航总览 overlay;overlay 打开时 .active) | |
| 34 | +│ │ ├── HomeTab(对应 .tab[data-go=main]:固定「主页」标签,不可关闭) | |
| 35 | +│ │ └── DynamicTab[](对应 #tab-userlist / #tab-userdetail:业务标签,含标题 + 关闭「✕」;按已打开集合渲染,见 § 3 标签栈状态) | |
| 36 | +│ └── TopBarRight(对应 .topbar .right:搜索图标 / 通知图标 / 当前用户区 / 更多「⋯」) | |
| 37 | +│ ├── IconSearch(对应 .right .ic[title=搜索],纯占位,无后端,见 § 8 决策 D4) | |
| 38 | +│ ├── IconNotice(对应 .right .ic[title=通知],纯占位,无后端,见 § 8 决策 D4) | |
| 39 | +│ ├── CurrentUserMenu(对应 .user:展示 `sUserName(sUserType)` + 下拉箭头;下拉含「退出登录」) | |
| 40 | +│ └── IconMore(对应 .more「⋯」,纯占位) | |
| 41 | +├── NavOverlay(对应 #nav-overlay:覆盖内容区的全屏深色导航总览浮层,默认隐藏 / .show 显示) | |
| 42 | +│ ├── NavOverlaySide(对应 #nav-overlay .side:左侧一级模块竖列,20 项,「系统设置」默认 active) | |
| 43 | +│ └── NavOverlayGrid(对应 #nav-overlay .grid:右侧 7 列分组卡片,每组标题 + 链接项;「用户列表」「系统功能模块设置」带 ★) | |
| 44 | +├── ContentOutlet(对应 .stage > .screen:受保护子路由内容渲染位,React Router <Outlet/>) | |
| 45 | +│ └── (主页 HomePage / 用户列表 FE-03 / 用户单据 FE-04 按当前路由挂载) | |
| 46 | +└── AppFooter(对应 footer.foot / .login-foot:版权 + 经营范围 + 备案号文本条,置底) | |
| 47 | + | |
| 48 | +HomePage(对应 #screen-main .main-wrap:主网格 1fr / 280px 两列,落地路由 `/`) | |
| 49 | +├── KpiHeadBar(对应 .kpi-head:标题「KPI监控」+ 今日未处理统计 + 未清总数统计 + AI 助手按钮) | |
| 50 | +│ ├── KpiTitle("KPI监控") | |
| 51 | +│ ├── KpiStat × 2("今日未处理"红色数字 / "未清总数"蓝色数字,数据见 § 8 决策 D2) | |
| 52 | +│ └── AiAssistantButton(对应 .ai-btn:「小ai同学,请帮我安排今日工作」,纯占位按钮,无后端) | |
| 53 | +├── DashboardThreeCol(对应 .three-col:左 280px 角色/流程树 + 右 KPI 主表) | |
| 54 | +│ ├── RoleProcessTree(对应 .left-nav.nav-tree:「按角色」「按流程」分组 + 部门/流程条目,静态,点击高亮,见 § 8 决策 D2) | |
| 55 | +│ └── KpiBoard(对应 .kpi-body 7 列网格:导航类型 / 角色 / KPI待处理事项 / KPI内容描述 / 今日未处理 / 未清总数 / 子流程;含跨行合并,静态数据) | |
| 56 | +└── CommonOps(对应 .common-ops:右侧「常用操作」卡片,链接:用户列表 → FE-03 路由;系统功能模块设置 → 占位) | |
| 57 | +``` | |
| 58 | + | |
| 59 | +- 控件选型(依据 `docs/04 § 零` `frontend.ui_lib = Ant Design 5.x`): | |
| 60 | + - 顶栏标签栈 → AntD `Tabs`(`type="editable-card"` 或自定义受控标签条,复刻原型「主页固定 + 业务标签可关」语义);亦可用自定义 `div` 条配合路由(实现取舍登记于 § 8 决策 D3),「主页」标签 `closable=false`。 | |
| 61 | + - 全部导航总览 → AntD `Drawer`(自定义全屏样式)或受控覆盖层 `div`,内部左列用列表、右侧用 `Row/Col` 栅格分组(对应原型 7 列);点击叶子链接 → 路由跳转或关闭 overlay(仅「用户列表」等有真实路由的项跳转,其余为占位项,见 § 8 决策 D4)。 | |
| 62 | + - 当前用户菜单 → AntD `Dropdown`,菜单项「退出登录」。 | |
| 63 | + - KPI 看板 → AntD `Table`(含 `rowSpan` 合并「导航类型 / 角色 / 子流程」列)或自定义 CSS Grid 复刻原型 `.kpi-body` 合并网格(实现取舍登记于 § 8 决策 D5);「KPI待处理事项」「KPI内容描述」为蓝色可点链接样式(原型 `.link`,纯展示,无明细页)。 | |
| 64 | + - 角色/流程树 → AntD `Tree` 或自定义列表,「按角色」「按流程」为分组节点,叶子带计数后缀(如「客服部 (30127)」),点击高亮选中(原型 `.item.active`),不触发取数。 | |
| 65 | + - 常用操作 / 链接 → 文本链接(AntD `Typography.Link` 或 `<a>`),「用户列表」`onClick` → `navigate('/usr/users')`(打开 FE-03 标签)。 | |
| 66 | + - 页脚 → 静态文本条。 | |
| 67 | +- 顶栏在登录页(`/login`,FE-01)**不渲染**(原型 `goTo('login')` 即 `topbar.display='none'`;本规格中 `/login` 不挂 `AppLayout`,故无顶栏)。 | |
| 68 | + | |
| 69 | +--- | |
| 70 | + | |
| 71 | +## 3. 页面状态机(≥5 态) | |
| 72 | + | |
| 73 | +外壳与主页的状态以「路由守卫态 + 标签栈本地态 + 导航 overlay 开关态 + 主页静态数据渲染态」表达。主页无后端取数,其「loading/error/empty」语义落在**身份就绪判定**与**静态数据渲染**上: | |
| 74 | + | |
| 75 | +| 状态 | 触发时机 | UI 表现 | | |
| 76 | +|---|---|---| | |
| 77 | +| `authResolving`(登录态校验中 / loading) | 进入任一受保护路由(含主页 `/`)时,`RequireAuth` 守卫判定 token 是否存在并解析 `authSlice.user`;刷新后 `user` 尚未从持久化 token 恢复时的瞬时态 | 外壳显示轻量加载占位(AntD `Spin` 居中),不渲染内容;解析完成后转 `ready` 或重定向 `/login` | | |
| 78 | +| `unauthenticated`(未登录 → 重定向) | 守卫判定无有效 token(未登录 / token 失效 / 收到 401) | 不渲染外壳,`<Navigate to="/login" replace />`(携带 `from` 以便登录后回跳,见 § 6) | | |
| 79 | +| `ready`(外壳就绪 / 正常) | 守卫通过、`authSlice.user` 已就绪 | 渲染 TopBar(含当前用户 `sUserName(sUserType)`)+ 主页落地内容(KPI 看板 / 角色树 / 常用操作);标签栈仅含「主页」 | | |
| 80 | +| `navOverlayOpen`(导航总览展开) | 点击「全部导航」按钮 | `NavOverlay` 覆盖内容区(`.show`),「全部导航」按钮 `.active`;点击叶子项 / 再次点击按钮 / Esc 关闭 | | |
| 81 | +| `tabOpen`(业务标签已打开 / 多标签栈) | 从主页常用操作或导航总览点击「用户列表」「新增用户」等有路由的入口 | 顶栏出现对应业务标签(FE-03「用户列表」/ FE-04「用户信息单据」),内容区切到该子路由;当前标签高亮,主页标签保留;关闭标签回退到前一个有效标签(默认主页,见 § 6 标签栈规则) | | |
| 82 | +| `empty`(KPI 看板 / 角色树空数据) | 静态数据源(`dashboardData.ts`)为空数组(理论兜底;当前为内置 demo 数据,非空) | KPI 看板与角色树渲染 AntD `Empty`「暂无数据」占位,不报错 | | |
| 83 | +| `error`(壳层渲染异常兜底) | 子路由组件渲染抛错(FE-03/FE-04 内部异常)或 token 过期被动 401 | 路由级 `ErrorBoundary` 兜底展示「页面出错,请刷新或返回主页」+ 返回主页入口;401 由 `request.ts` 响应拦截器统一跳 `/login`(docs/04 § 2.4) | | |
| 84 | + | |
| 85 | +> 状态以本地组件态 + RTK `authSlice` 表达:`navOverlayOpen` / 标签栈(已打开标签集合 + 当前激活标签)用本地 `useState`(或一个轻量 `uiSlice`,取舍见 § 8 决策 D3);`authResolving` / `unauthenticated` / `ready` 由 `RequireAuth` 读 `authSlice.token`/`user` 判定;本壳层**不发起 KPI/导航后端请求**,故无 `dataLoading`/`fetchError` 态(与原型静态 demo 一致)。 | |
| 86 | + | |
| 87 | +--- | |
| 88 | + | |
| 89 | +## 4. 消费的后端端点(对齐 docs/05) | |
| 90 | + | |
| 91 | +本壳层 / 落地页**自身不直接调用任何后端业务端点**。原型主页的 KPI 看板、角色/流程树、导航分组均为静态 demo,docs/05 未定义对应端点(无 KPI / dashboard / nav 接口),故不消费、不杜撰(见 § 8 决策 D1)。涉及的端点均为「外壳作为入口/容器」间接关联: | |
| 92 | + | |
| 93 | +| 端点 | 方法 | 与本 FE 的关系 | 触发位置 | 归属 FE | | |
| 94 | +|---|---|---|---|---| | |
| 95 | +| `/api/usr/login` | POST | 登录态来源:FE-01 登录成功写入 `authSlice`(`token` + `user`);本壳读 `authSlice.user` 渲染当前用户区,读 `authSlice.token` 做路由守卫 | 不由本壳触发(FE-01 触发) | FE-01(REQ-USR-004) | | |
| 96 | +| `/api/usr/users` | GET | 「常用操作 > 用户列表」与「导航总览 > 用户管理 > 用户列表」入口跳转后由 FE-03 调用;本壳只负责导航到 `/usr/users`,不直接调 | 入口点击 → 路由跳转 | FE-03(REQ-USR-003) | | |
| 97 | +| `/api/usr/users` | POST | 「新增用户」入口跳转后由 FE-04 调用;本壳只负责导航到 `/usr/users/new` | 「新增」入口点击 → 路由跳转 | FE-04(REQ-USR-001) | | |
| 98 | + | |
| 99 | +请求 / 响应约定(依据 `docs/04 § 1.4 / § 2.3 / § 2.4`,本壳仅承接守卫与跳转,不新增取数逻辑): | |
| 100 | +- 统一走 FE-01 已建立的 `frontend/src/api/request.ts` Axios 实例(`baseURL=/api`,开发期经 Vite proxy 转发到后端 `http://localhost:5172`,端口取 `config-vars.yaml backend.http_port=5172`;FE-01 § 7 D2 已锁定)。 | |
| 101 | +- 响应拦截器对 `401` 统一跳 `/login`(docs/04 § 2.4),与本壳路由守卫 `unauthenticated` 态协同:被动 401 清理 `authSlice` 并重定向登录页。 | |
| 102 | +- 退出登录:清空 `authSlice`(`clearCredentials`)+ 移除持久化 token(FE-01 锁定键名 `xly_erp_token`,localStorage)→ `navigate('/login', { replace:true })`(纯前端动作,无注销端点,见 § 8 决策 D6)。 | |
| 103 | + | |
| 104 | +> 错误码表:本壳层自身无业务端点,无专属错误码。被动 401(token 失效)按 docs/04 § 2.4 由响应拦截器兜底跳登录;子路由业务错误码由 FE-03 / FE-04 各自规格承载。 | |
| 105 | + | |
| 106 | +--- | |
| 107 | + | |
| 108 | +## 5. 业务规则前端复刻清单(逐条) | |
| 109 | + | |
| 110 | +> 本 FE 无 CRUD 业务校验规则(不在表单/查询语义内);其「规则」为**外壳导航 / 权限可见性 / 登录态约束**的交互规则,逐条复刻自原型交互语义与 docs/04 认证约定。 | |
| 111 | + | |
| 112 | +| # | 规则 | 触发时机 | 前端报错 / 反馈文案 | 来源 | | |
| 113 | +|---|---|---|---|---| | |
| 114 | +| BR1 | 未登录不得进入受保护区(主页及所有业务子路由) | 进入 `/`、`/usr/**` 等受保护路由时守卫判定无有效 token | —(无报错,静默 `<Navigate to="/login" replace />`,携 `from`) | docs/04 § 2.1 路由守卫「未登录跳登录页」/ § 1.7 认证 | | |
| 115 | +| BR2 | 已登录用户访问 `/login` 直接回主页 | 进入 `/login`(FE-01)时检测到有效登录态 | —(重定向到 `/` 或 `from`) | FE-01 § 6.7 路由守卫协作(已登录访问登录页重定向) | | |
| 116 | +| BR3 | 顶栏当前用户区展示登录用户标识 | 外壳就绪渲染时 | 展示 `sUserName(sUserType 中文名)`(如「朱子纯(超级管理员)」,对应原型文案);`user` 缺失时退化为占位用户名 | REQ-USR-004 响应 `user:{ sUserName, sUserType }` / 原型 `.user` 文案 | | |
| 117 | +| BR4 | 「主页」标签固定且不可关闭;业务标签可关闭 | 标签栈渲染 / 点击「✕」 | —(主页无关闭按钮;关闭业务标签后激活前一有效标签,默认主页) | 原型 `openTab/tabsOpen/.close` 逻辑(主页 tab 无 `.close`,userlist/userdetail tab 有) | | |
| 118 | +| BR5 | 关闭「用户列表」标签同时关闭其下「用户信息单据」标签 | 点击「用户列表」标签的「✕」 | —(联动关闭,回主页) | 原型 `data-close=userlist` 分支:`tabsOpen.userdetail=false` 后 `goTo('main')` | | |
| 119 | +| BR6 | 打开「用户信息单据」标签时自动确保「用户列表」标签存在 | 从主页/导航打开用户单据(如「新增用户」) | —(隐式打开父标签) | 原型 `openTab('userdetail')` 内 `tabsOpen.userlist=true` | | |
| 120 | +| BR7 | 全部导航总览:仅「用户列表」等已实现路由项可跳转,其余为占位(不跳转 / 不报错) | 点击导航总览叶子项 | 占位项点击:关闭 overlay 不跳转(或 `message.info("功能开发中")`,见 § 8 决策 D4) | 原型 `data-go` 仅 `userlist` 有目标,其余 `<a>` 无 `data-go`(占位) | | |
| 121 | +| BR8 | 常用操作「用户列表」跳转到用户查询页(FE-03) | 点击常用操作或导航中「用户列表」 | —(`navigate('/usr/users')` + 打开标签) | 原型 `.common-ops a[data-go=userlist]` / 导航「用户管理>用户列表 ★」 | | |
| 122 | +| BR9 | 退出登录清理登录态并回登录页 | 点击当前用户下拉「退出登录」 | `message.success("已退出登录")` 后跳 `/login` | docs/04 § 2.2 登录态进 store(退出即清)/ FE-01 token 持久化约定(清键) | | |
| 123 | +| BR10 | 被动登录失效(401)统一跳登录页 | 任意受保护请求返回 401(token 过期/无效) | `message.warning("登录已失效,请重新登录")`(拦截器兜底)后跳 `/login` | docs/04 § 2.4「401 跳登录」 | | |
| 124 | +| BR11 | KPI 看板 / 角色流程树为只读展示,不触发后端、不产生写副作用 | 主页渲染 / 点击树节点 / 点击 KPI 链接 | —(纯前端高亮 / 无明细页,静态 demo 数据) | 原型主页为静态 demo;docs/05 无 KPI 端点(见 § 8 决策 D1) | | |
| 125 | + | |
| 126 | +> 本壳层只做**导航编排 + 登录态守卫 + 静态展示**;任何业务真伪 / 权限裁决均由后端在子功能(FE-03/FE-04)调用时裁决,本壳不复制后端逻辑,亦不杜撰 KPI/导航后端取数。 | |
| 127 | + | |
| 128 | +--- | |
| 129 | + | |
| 130 | +## 6. 路由与交互实现要点(复刻原型语义) | |
| 131 | + | |
| 132 | +1. **路由结构(React Router v6,docs/04 § 2.1)**: | |
| 133 | + - `/login` → FE-01 `<LoginPage>`(放行路由,**不**包 `AppLayout`,故无顶栏,复刻原型登录态隐藏顶栏)。 | |
| 134 | + - 受保护区:`<RequireAuth>` 包裹的布局路由 `<AppLayout>`,子路由: | |
| 135 | + - index `/` → `<HomePage>`(登录后落地页 = 主页 KPI 看板)。 | |
| 136 | + - `/usr/users` → FE-03 用户列表。 | |
| 137 | + - `/usr/users/new` → FE-04 新增用户单据。 | |
| 138 | + - `/usr/users/:id` → FE-04 修改用户单据。 | |
| 139 | + - 未匹配路由 → 重定向 `/`(或 404 占位,见 § 8 决策 D7)。 | |
| 140 | +2. **路由守卫 `RequireAuth`(BR1/BR2/BR10)**:读 `authSlice.token`(刷新后由 FE-01 持久化键 `xly_erp_token` 恢复,FE-01 § 7 D6)。无 token → `<Navigate to="/login" replace state={{ from }} />`;有 token 但 `user` 未就绪 → `authResolving` 占位(`Spin`)。已登录访问 `/login` 由 FE-01 守卫处理(重定向到 `from` 或 `/`)。 | |
| 141 | +3. **屏切换 → 路由切换**:原型 `goTo(name)` 切 `.screen.active` 的单页多屏,本规格改为真实路由切换;`.stage > .screen` 容器对应 `AppLayout` 的 `<Outlet/>` 渲染位。 | |
| 142 | +4. **标签栈(BR4/BR5/BR6,复刻原型 `tabsOpen`/`openTab`/`.close`)**:顶栏维护一组「已打开业务标签」(受控本地态或 `uiSlice`)。「主页」为固定标签(不可关、恒在最左、对应 index 路由)。打开 FE-03 → 追加「用户列表」标签并激活;打开 FE-04 → 确保「用户列表」标签存在再追加「用户信息单据」标签(BR6)。关闭「用户列表」标签 → 联动移除「用户信息单据」标签并激活主页(BR5);关闭「用户信息单据」→ 回到「用户列表」标签。标签激活状态与当前路由保持同步(点击标签 = `navigate` 到对应路由)。 | |
| 143 | +5. **全部导航总览 overlay(BR7,复刻 `#nav-overlay` + `#nav-toggle`)**:点击「全部导航」按钮切换 overlay 显隐(`navOverlayOpen`),按钮高亮。overlay 左列 20 个一级模块(`navConfig.ts` 静态,「系统设置」默认 active)、右侧 7 列分组(`期初设置 / 用户管理 / 系统参数 / 计算方案 / 日志 / 开发平台 / API对接管理`,复刻原型 `navCols`)。叶子项中仅「用户列表」有真实路由(点击 → 关 overlay + `navigate('/usr/users')`);其余为占位项(点击关 overlay,不跳转或 `message.info("功能开发中")`,§ 8 D4)。「系统功能模块设置」「用户列表」带 ★ 标记(原型 `it.star`)。支持点击遮罩 / Esc 关闭。 | |
| 144 | +6. **主页 KPI 看板(BR11)**:复刻原型 `.kpi-head`(标题 + 今日未处理/未清总数统计 + AI 助手按钮)+ `.three-col`(左角色/流程树 + 右 KPI 合并网格)+ `.common-ops`(右侧常用操作)。数据来自 `dashboardData.ts` 内置静态 demo(角色/流程分组、KPI 行含跨行合并、统计汇总数;§ 8 D2 登记其静态来源)。KPI 网格含「导航类型 / 角色 / 子流程」列的纵向跨行合并(原型用 CSS Grid `gridRow span` 模拟),复刻为 AntD `Table` 的 `rowSpan` 或等价 CSS Grid(§ 8 D5)。「KPI待处理事项 / KPI内容描述」为蓝色链接样式但**无明细页**(纯展示)。AI 助手按钮为占位(无后端,§ 8 D4)。 | |
| 145 | +7. **退出登录(BR9)**:当前用户 `Dropdown` → 「退出登录」→ dispatch `authSlice.clearCredentials` + 删除 localStorage `xly_erp_token`(FE-01 锁定键)→ `message.success` → `navigate('/login', { replace:true })`。 | |
| 146 | +8. **顶栏 / 页脚静态文案**:品牌 Logo(鹿角 SVG,复用 FE-01/原型 inline path)、搜索/通知/更多图标为**纯占位**(无交互后端,§ 8 D4);页脚版权 / 经营范围 / 备案号文本复刻原型 `footer.foot`。 | |
| 147 | +9. **响应式**:目标为桌面端 ERP(CLAUDE.md「企业内部管理人员」),原型为定宽桌面布局(主网格 `1fr / 280px`、导航 7 列);不专门设计移动端断点,窄屏允许默认回流(§ 8 D8)。 | |
| 148 | + | |
| 149 | +--- | |
| 150 | + | |
| 151 | +## 7. Design Tokens 引用清单(`src/styles/tokens.css`,仅 `var(--color-*)`) | |
| 152 | + | |
| 153 | +> 约束:组件样式只用 `var(--color-*)`,禁止硬编码 hex/rgba;色值冲突时 `tokens.css` 优先于 `prototype/`(原型内联 `:root` 变量为 demo 私有,不作色值 SSoT)。AntD 主题色经 `ConfigProvider` 对齐 `--color-primary`。 | |
| 154 | + | |
| 155 | +| 用途 | Token | 备注 | | |
| 156 | +|---|---|---| | |
| 157 | +| 主操作 / 激活标签 / 「全部导航」激活态 / AI 按钮 / 链接强调 | `var(--color-primary)` | 对应原型 `.nav-btn.active` / `.tab.active` / `.ai-btn` 蓝;同时作为 AntD 主题 `colorPrimary` | | |
| 158 | +| 页面 / 内容区基础背景 | `var(--color-bg-base)` | 对应原型 `.stage` / `.main-wrap` 浅灰底(原型 `#f3f4f6`,映射到基础底色 token) | | |
| 159 | +| 面板 / 卡片 / 表格背景(白) | `var(--color-form-bg-edit)` | KPI 看板面板、常用操作卡、导航卡片白底(原型 `.panel` `#fff`) | | |
| 160 | +| 表头背景(KPI 网格表头 / 流程树分组头) | `var(--color-table-header-bg)` | 对应原型 `.kpi-body .h` / `.header-bg` | | |
| 161 | +| 表头文字 | `var(--color-table-header-fg)` | KPI 网格列头文字 | | |
| 162 | +| 表格行文字 | `var(--color-table-row-fg)` | KPI 行 / 用户名等单元文字 | | |
| 163 | +| 行 hover 背景 | `var(--color-table-row-bg-hover)` | KPI/树项 hover(原型 `.item:hover` / `tr:hover`,映射到行 hover token) | | |
| 164 | +| 选中行 / 树节点选中背景 | `var(--color-table-row-bg-selected)` | 角色/流程树 `.item.active` 选中高亮 | | |
| 165 | +| 通用文字 / 标题 | `var(--color-text)` | 「KPI监控」标题、统计文案、页脚正文 | | |
| 166 | +| 次要文字 / 占位 / 页脚版权 | `var(--color-text-secondary)` | 统计副文案、占位图标、备案号 / 版权文本 | | |
| 167 | +| 边框 / 分隔线 | `var(--color-border)` | 面板描边、KPI 网格线、标签分隔(原型 `.border` / `.kpi-body` 网格边) | | |
| 168 | +| 异常 / 红色统计数字 / 错误提示 | `var(--color-error)` | 「今日未处理」红色数字、KPI 红色待处理数(原型 `.num-red` / `.danger`)、`message.error` / `message.warning` 强调 | | |
| 169 | +| 成功提示(退出登录 / 操作成功反馈) | `var(--color-success)` | `message.success("已退出登录")` 等(显式登记以备自定义文案样式) | | |
| 170 | + | |
| 171 | +> 顶栏 `#topbar` 的深色底(原型 `--topbar:#1f1f23`)、导航总览 overlay 深色底(原型 `#2b3137`)、登录主视觉深蓝渐变(FE-01)等**品牌深色 / 装饰色**在 `tokens.css` 中**无对应语义 token**;本规格将顶栏与导航 overlay 的深色底作为**外壳局部装饰样式**保留在 `AppLayout` 的 scoped 样式里(不新增全局 token、不挪用语义 token,与 FE-01 § 7 D7 处理一致,见 § 8 决策 D9)。这些深色仅承载「外壳容器」视觉,不承载状态语义,不违反「语义色只用 token」约束。 | |
| 172 | + | |
| 173 | +--- | |
| 174 | + | |
| 175 | +## 8. 自主决策记录(decisions) | |
| 176 | + | |
| 177 | +| # | 问题 | 选择 | 依据 | 置信度 | | |
| 178 | +|---|---|---|---|---| | |
| 179 | +| D1 | 主页 KPI 看板 / 角色流程树 / 导航分组的数据来源(docs/05 无 KPI/dashboard/nav 端点) | 不调后端,全部用前端静态配置(`dashboardData.ts` / `navConfig.ts`)复刻原型 demo 数据 | docs/05 接口清单仅 4 个 USR 端点,无任何 KPI/导航/仪表盘端点;原型主页为纯静态 demo;硬约束禁止杜撰与现有约定冲突的「事实」(不得编造后端端点) | high | | |
| 180 | +| D2 | KPI 统计数字 / 角色计数 / KPI 行的具体值如何确定 | 沿用原型内置 demo 数值(如今日未处理 37428、未清总数 56433、各部门计数、kpiRows 全量行),作为静态展示数据 | 原型 `prototype/erp.html` 内联 `kpiRows` / `.kpi-head` 统计 / 角色树计数即唯一数据来源;无后端来源可对接;保留原值即「最有依据的解读」 | high | | |
| 181 | +| D3 | 标签栈 / 导航 overlay 开关 / 当前激活标签的状态放哪 | 优先用 `AppLayout` 本地 `useState`(标签栈 + overlay 开关),仅当需跨组件共享再抽 `uiSlice` | docs/04 § 2.2「跨页面共享的才进 store,避免把所有状态塞全局」;标签栈是外壳局部 UI 态,本地态更轻;登记以备实现期按需上提 | medium | | |
| 182 | +| D4 | 占位入口(搜索/通知/更多/AI 助手/导航总览中无路由的项)点击行为 | 一律为视觉占位:无路由项点击关 overlay 不跳转,可选 `message.info("功能开发中")`;搜索/通知/AI 等图标按钮不绑业务动作 | 原型对应元素均无 `data-go`/无目标(纯 demo);docs/05 无对应端点;占位化是最小且不杜撰功能的处理 | high | | |
| 183 | +| D5 | KPI 合并网格用 AntD Table 还是 CSS Grid 复刻 | 实现期二选一:默认 AntD `Table`(`rowSpan` 合并「导航类型/角色/子流程」列);若合并规则难以用 Table 表达则回退原型同款 CSS Grid `gridRow span` | `frontend.ui_lib=AntD 5`,优先组件库;原型已用 CSS Grid 合并验证可行,作为兜底;二者都满足布局语义,留实现期取舍并登记 | medium | | |
| 184 | +| D6 | 退出登录是否调后端注销端点 | 纯前端注销:清 `authSlice` + 删 localStorage token + 跳 `/login`,不调后端 | docs/04 § 1.7 为无状态 JWT(无服务端会话需失效);docs/05 无注销端点;无状态认证下前端清 token 即注销,不杜撰端点 | high | | |
| 185 | +| D7 | 未匹配路由(404)处理 | 受保护区内未匹配 → 重定向到主页 `/`;未登录态下未匹配 → 经守卫重定向 `/login` | 原型为固定几屏的单页 demo,无 404 设计;ERP 内部系统重定向主页是常见稳妥取舍;非验收硬项,故登记 | medium | | |
| 186 | +| D8 | 窄屏 / 移动端适配 | 不专门设计移动断点,桌面定宽布局默认随容器回流 | 目标用户为「企业内部管理人员」桌面端 ERP(CLAUDE.md);原型为定宽桌面布局;移动适配非本 FE 验收项(与 FE-01 § 7 D4 处理一致) | medium | | |
| 187 | +| D9 | 顶栏 / 导航 overlay 深色底色值来源(tokens.css 无对应品牌深色 token) | 作为外壳局部装饰样式保留在 `AppLayout` scoped 样式,不新增全局 token、不挪用语义 token;语义色(主操作/文字/边框/错误/成功)严格走 token | tokens.css 仅定义语义/状态色,无品牌深色顶栏 token;深色底纯装饰无状态语义,局部化最小侵入;与 FE-01 § 7 D7 一致 | medium | | |
| 188 | +| D10 | 当前用户区 `sUserType` 显示文案 | 直接展示后端 `user.sUserType`(取值「超级管理员/普通用户」,已是中文),拼为 `sUserName(sUserType)` | REQ-USR-001/004 中 `sUserType` 取值即中文「普通用户/超级管理员」;无需再映射;原型展示「朱子纯(超级管理员)」同形 | high | | |
| 189 | + | |
| 190 | +> 本规格不含后端实现细节(认证比对 / 令牌签发 / 数据访问 / 库表迁移等均不在前端作用域),亦不杜撰任何 KPI / 导航后端端点;当前用户身份来自 FE-01 已落地的 `authSlice`,所有业务裁决在子功能(FE-03/FE-04)调用时由后端产生。 | ... | ... |