From a1e28daec56034effb8d4f50bf6ca607a1b77e34 Mon Sep 17 00:00:00 2001 From: Stev_Wang <304865932@qq.com> Date: Tue, 3 Nov 2026 10:30:55 +0800 Subject: [PATCH] =?UTF-8?q?docs(routing):=20=E6=96=B0=E5=A2=9E=E5=89=8D?= =?UTF-8?q?=E7=AB=AF=E8=B7=AF=E7=94=B1=E4=B8=8E=E7=9B=AE=E5=BD=95=E8=A7=84?= =?UTF-8?q?=E8=8C=83=E5=B9=B6=E6=94=B6=E6=95=9B=E8=AE=A1=E5=88=92=E8=B7=AF?= =?UTF-8?q?=E7=94=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 背景: - 前端路由缺少统一规范:导航模块 key 与 URL 首段不一致,页面目录未镜像 路由,04 规范中的历史路由示例与实际实现不符; - 用户确认「平台」更名为「管理中心」,路由统一为 /<模块>/<功能>。 改动: - 新增 11-前端路由与目录规范:模块与基础路径表、路径语法(复数 kebab-case、 /new、:id、层级与 query 状态)、pages/<模块>/<功能>/ 目录映射、路由注册、 旧链重定向、新增页面检查清单; - 04 §8 的 API-27 改为模块化路由并链接 11;工程规范索引与 AGENTS §9 登记 11; - 开发计划:平台更名管理中心,附录 C 页面清单收敛为模块化路由,§7.1 / §8.3 同步,版本记录补「路由规范回写」; - A1 实施报告路由说明更新为 /system/users(旧 /users* 重定向)。 影响面: - 仅文档与规范,不改变功能范围、权限点与后端接口;后续批次按 11 执行。 回滚方式: - 回滚本提交即恢复原附录 C 与 04 §8 描述;代码不受影响。 验证证据: - pnpm format:check 通过;路由与代码行为见相邻的 web 重构提交。 --- AGENTS.md | 1 + docs/工程规范/04-API与路由规范.md | 4 +- docs/工程规范/11-前端路由与目录规范.md | 125 ++++++++++++++++++ docs/工程规范/README.md | 1 + ...灵犀_A1身份认证与用户管理_实施报告_V0.1.md | 4 +- .../灵犀_信息流素材生产平台_开发计划_V0.1.md | 39 +++--- 6 files changed, 152 insertions(+), 22 deletions(-) create mode 100644 docs/工程规范/11-前端路由与目录规范.md diff --git a/AGENTS.md b/AGENTS.md index da3758e..17b1191 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -158,6 +158,7 @@ docs/ PRD / 技术架构 / 立项建议 / 工程规范 | 日志与可观测 | [08-日志与可观测性规范](docs/工程规范/08-日志与可观测性规范.md) | Pino 字段、trace_id、审计与日志分离、告警 | | 环境变量与密钥 | [09-环境变量与密钥规范](docs/工程规范/09-环境变量与密钥规范.md) | `.env.example` 入库、启动校验、轮换与泄露处置 | | 资产命名与图层 | [10-资产命名与PSD图层规范](docs/工程规范/10-资产命名与PSD图层规范.md) | 命名占位符、PSD 图层前缀、规格矩阵、低质量标记 | +| 前端路由与目录 | [11-前端路由与目录规范](docs/工程规范/11-前端路由与目录规范.md) | `/模块/功能` 路由、模块表、目录映射、重定向与检查清单 | --- diff --git a/docs/工程规范/04-API与路由规范.md b/docs/工程规范/04-API与路由规范.md index 96e4066..ac31d80 100644 --- a/docs/工程规范/04-API与路由规范.md +++ b/docs/工程规范/04-API与路由规范.md @@ -129,8 +129,10 @@ JwtGuard → PermissionGuard(权限点)→ SpecialPermissionGuard(特殊 ## 8 前端路由 +> 前端路由的模块表、路径语法与目录映射以 [11](11-前端路由与目录规范.md) 为准;本节保留通用约束。 + - `API-26` 路由常量集中 `apps/web/src/routes.ts`,禁止散落字符串路径。 -- `API-27` 路径反映「行业 → 客户」归属:`/clients/:clientId/scripts`、`/clients/:clientId/media/batches/:batchId`。 +- `API-27` 前端路由统一为 `/<模块>/<功能>`:`/system/users`、`/scripts/library`;模块表、目录映射与旧路径重定向见 [11 · 前端路由与目录规范](11-前端路由与目录规范.md)。 - `API-28` 统一布局路由:登录后进入 `AppLayout`(侧边导航 + 面包屑),未登录访问自动跳 `/login` 并带回跳地址。 - `API-29` 权限守卫组件 ``;无权限渲染 403 页,**不隐藏路由**(避免"菜单有、点进去白屏")。 - `API-30` 页面级懒加载(`React.lazy` + `Suspense`),首屏包体积纳入性能预算。 diff --git a/docs/工程规范/11-前端路由与目录规范.md b/docs/工程规范/11-前端路由与目录规范.md new file mode 100644 index 0000000..0262ebc --- /dev/null +++ b/docs/工程规范/11-前端路由与目录规范.md @@ -0,0 +1,125 @@ +# 11 · 前端路由与目录规范 + +| 项 | 内容 | +| --- | --- | +| 文档版本 | V1.0(2026-11-03) | +| 依据 | 技术架构 §6 / §10、[04 · API 与路由规范](04-API与路由规范.md) §8、`AGENTS.md` §5 | +| 适用范围 | `apps/web` 全部页面路由、导航配置与页面目录 | +| 强制级别 | 强制 | + +> 目标:URL、导航、面包屑、页面目录四者一一对应,做到「看 URL 就能找到代码,看目录就能知道路由」。 + +--- + +## 1 模块与基础路径 + +导航一级模块与 URL 首段必须一致,模块 key 同时用于 `nav-config` 与占位路由解析。 + +| 导航模块 | 模块 key | 基础路径 | 页面目录 | +| --- | --- | --- | --- | +| 工作台 | `dashboard` | `/` | `pages/dashboard/` | +| 脚本 | `scripts` | `/scripts` | `pages/scripts/` | +| 素材 | `material` | `/material` | `pages/material/` | +| 资产 | `assets` | `/assets` | `pages/assets/` | +| 交付 | `delivery` | `/delivery` | `pages/delivery/` | +| 管理中心 | `system` | `/system` | `pages/system/` | + +- `FE-01` 新增一级模块必须先登记本表,再改 `nav-config`、路由与目录;禁止出现「导航有、路由无」或「路由有、导航无」。 +- `FE-02` 模块 key 取 URL 首段(复数资源用复数:`scripts` / `assets`),**不得**再用 `platform` 这类与路径不一致的别名。 +- `FE-03` 基础路径之外的例外页面只有:`/login`、`/401`、`/403`、`/404`、`/500`。 + +--- + +## 2 路径语法 + +统一形式:`/<模块>/<功能>[/<子资源>/...]`,功能段使用 **kebab-case 复数资源名**。 + +| 页面类型 | 形式 | 示例 | +| --- | --- | --- | +| 列表 / 首页 | `//` | `/system/users`、`/scripts/library` | +| 新建 | `///new` | `/system/users/new` | +| 详情 | `///:id` | `/system/users/:id` | +| 子资源 | `///:id/` | `/system/users/:id/...` | +| 子功能 | `///` | `/system/customer-fields/approvals` | + +- `FE-04` 资源名用复数 kebab-case:`users`、`roles`、`audit-logs`;禁止 `/system/user`、`/system/getUser`、`/system/users_list`。 +- `FE-05` 新建统一用 `/new`,**不用** `/create`、`/add`;详情参数统一叫 `:id`。 +- `FE-06` URL 中禁止动词(`/doGenerate`、`/approveUser`);动作走接口或子资源。 +- `FE-07` 禁止尾斜杠;大小写敏感,全部小写。 +- `FE-08` 层级:模块 → 功能 → 资源 ID → 子资源,**最多 4 段**;更深归属改用 query 过滤。 +- `FE-09` 筛选 / 分页 / 排序 / 选中态必须进 query(与 [04](04-API与路由规范.md) `API-31` 一致),保证链接可分享、刷新可恢复。 +- `FE-10` 路由参数中的 ID 必须 `encodeURIComponent`,拼接统一走 `routes.ts` 的 helper(如 `userDetailPath`)。 + +--- + +## 3 目录映射 + +``` +apps/web/src/pages/ +├─ dashboard/ # 工作台(对应 /) +│ └─ HomePage.tsx +├─ scripts/ # 脚本(对应 /scripts) +├─ material/ # 素材(对应 /material) +├─ assets/ # 资产(对应 /assets) +├─ delivery/ # 交付(对应 /delivery) +├─ system/ # 管理中心(对应 /system) +│ └─ users/ # 用户与组织(对应 /system/users) +│ ├─ UsersPage.tsx +│ ├─ UserNewPage.tsx +│ ├─ UserListPanel.tsx +│ ├─ dialogs/ +│ └─ *.spec.tsx +├─ login/ # 例外:登录页 +├─ errors/ # 例外:401 / 403 / 404 / 500 +└─ workspace/ # 例外:未实现批次的通用占位页 +``` + +- `FE-11` 页面目录 = `pages/<模块>/<功能>/`,与 URL 逐段对应;功能目录名与路由 feature 段一致。 +- `FE-12` 路由入口文件命名为 `Page.tsx`(如 `UsersPage.tsx`);新建 / 详情页同目录,命名为 `NewPage.tsx` / `DetailPage.tsx`。 +- `FE-13` 页面私有组件、弹窗、格式化函数、单测放在同一功能目录内(`dialogs/`、`*.spec.tsx`);**不**为单个页面另建共享目录。 +- `FE-14` 跨多个功能复用的组件放 `src/components/`,跨页面 Hook 放 `src/hooks/`;领域逻辑被两个以上页面复用时才考虑 `src/features//`。 +- `FE-15` `pages/login`、`pages/errors`、`pages/workspace` 是基础设施例外,不按模块归位。 +- `FE-16` 禁止把页面放到 `src/` 根下或 `pages//` 根下;必须落在具体功能目录内。 + +--- + +## 4 路由常量与注册 + +- `FE-17` 全部路径集中在 `src/routes.ts`,按模块分组;组件内禁止写字符串路径(与 [04](04-API与路由规范.md) `API-26` 一致)。 +- `FE-18` 路由在 `src/router.tsx` 集中声明;登录后页面挂在 `AppLayout` 下,页面级组件使用懒加载。 +- `FE-19` 导航配置 `nav-config.ts` 的模块 key 与 item path 必须与 `routes.ts` 一致;面包屑从导航配置派生,禁止在页面内写死。 +- `FE-20` 权限守卫按 [04](04-API与路由规范.md) `API-29`:`` 无权限渲染 403 页,不隐藏路由;按钮级权限用 ``。 +- `FE-21` 旧路径重命名时保留一个版本的 301/302 式前端重定向(``),并在计划 / 文档同一提交登记;下一版本删除。 +- `FE-22` 新增 / 改名路由必须同步:`routes.ts`、`router.tsx`、`nav-config.ts`、页面目录、面包屑、单测、e2e、开发计划附录 C。 + +--- + +## 5 新增页面检查清单 + +- [ ] 模块 key / 基础路径 / 页面目录能在 §1 表中查到; +- [ ] 路径符合 §2(复数、kebab-case、`/new`、`:id`、无动词、无尾斜杠); +- [ ] 路由常量集中在 `routes.ts`,无散落字符串; +- [ ] 导航、面包屑、页面标题与路由一致; +- [ ] 页面目录为 `pages/<模块>/<功能>/`,入口命名为 `Page.tsx`; +- [ ] 权限点与守卫齐全,无权限进 403; +- [ ] 旧路径(如有)加重定向与测试; +- [ ] 单测覆盖路由常量 / 导航 / 守卫;e2e 覆盖真实跳转; +- [ ] 开发计划附录 C 与实施报告已同步。 + +--- + +## 6 附:模块路径全表(当前) + +| 模块 | 功能路径 | +| --- | --- | +| 脚本 | `/scripts/library`、`/scripts/framework-cards`、`/scripts/templates`、`/scripts/batch`、`/scripts/review` | +| 素材 | `/material/image-compose`、`/material/video`、`/material/tasks`、`/material/quick-review`、`/material/preview` | +| 资产 | `/assets/library`、`/assets/templates`、`/assets/pools`、`/assets/prompts` | +| 交付 | `/delivery/export`、`/delivery/records`、`/delivery/manifests` | +| 管理中心 | `/system/users`、`/system/roles`、`/system/customers`、`/system/industries`、`/system/dicts`、`/system/audit-logs`、`/system/ai`、`/system/settings`、`/system/industry-packs`、`/system/forms`、`/system/customer-fields`、`/system/compliance` | + +## 7 修订记录 + +| 版本 | 日期 | 变更 | +| --- | --- | --- | +| V1.0 | 2026-11-03 | 初版:模块表、路径语法、目录映射、路由注册、旧链重定向与检查清单;管理中心由「平台」改名,A1 用户页迁移至 `/system/users` 与 `pages/system/users/` | diff --git a/docs/工程规范/README.md b/docs/工程规范/README.md index dac215f..446bb7c 100644 --- a/docs/工程规范/README.md +++ b/docs/工程规范/README.md @@ -15,6 +15,7 @@ | 08 | [日志与可观测性规范](08-日志与可观测性规范.md) | 日志字段、trace、审计、指标、告警 | 强制 | | 09 | [环境变量与密钥规范](09-环境变量与密钥规范.md) | env 命名、校验、密钥管理、轮换、泄露处置 | 强制 | | 10 | [资产命名与 PSD 图层规范](10-资产命名与PSD图层规范.md) | 资产归属、命名占位符、图层前缀、规格矩阵、低质量标记 | 强制 | +| 11 | [前端路由与目录规范](11-前端路由与目录规范.md) | 模块/路径表、路由语法、目录映射、旧链重定向、新增页面检查清单 | 强制 | ## 规范文档自身的约定 diff --git a/docs/开发计划/灵犀_A1身份认证与用户管理_实施报告_V0.1.md b/docs/开发计划/灵犀_A1身份认证与用户管理_实施报告_V0.1.md index 8a7fe03..ac6ec9b 100644 --- a/docs/开发计划/灵犀_A1身份认证与用户管理_实施报告_V0.1.md +++ b/docs/开发计划/灵犀_A1身份认证与用户管理_实施报告_V0.1.md @@ -23,7 +23,7 @@ | A1-FE-03 | `/me` 缓存、`usePermission` / ``、路由与按钮级控制、403 页 | ✅ | | A1-QA-01 | 登录 / 刷新 / 登出 / 停用 / 角色变更 / 越权 6 类用例 | ✅(接口 int + 浏览器 e2e) | -口径确认(用户拍板):初始密码由管理员设定、首次登录强制修改;手机号列表掩码、详情全号仅 `user:manage` 可见;路由按开发计划附录 C 使用 `/users`。 +口径确认(用户拍板):初始密码由管理员设定、首次登录强制修改;手机号列表掩码、详情全号仅 `user:manage` 可见;路由按开发计划附录 C 使用 `/system/users`(2026-11-03 路由规范调整后)。 --- @@ -52,7 +52,7 @@ ### 2.3 前端(`apps/web`) -- 路由:`/users`、`/users/new`、`/users/:id`、`/403`;`RequireAuth` + `RequirePermission`;未登录跳 `/login?redirect=`(含 `sanitizeRedirect` 防开放重定向);无权限进 403;停用账号回登录并给出停用说明。 +- 路由:`/system/users`、`/system/users/new`、`/system/users/:id`、`/403`(旧 `/users*` 已加重定向);`RequireAuth` + `RequirePermission`;未登录跳 `/login?redirect=`(含 `sanitizeRedirect` 防开放重定向);无权限进 403;停用账号回登录并给出停用说明。 - 权限:`usePermission` / `usePermissions` + ``,无权限按钮不渲染;`/me` 走 TanStack Query 缓存。 - 登录:方案 B 左右分屏(左 560 品牌 + 能力 + CSS 规格缩略,右表单卡);真实 `POST /auth/login`;错误 / loading / 锁定态;首次登录强改在登录页内完成,成功后清会话要求用新密码重登。 - 用户列表 / 详情:左 400 列表 + 右 760 详情(基本资料 / 角色权限 / 负责客户 / 登录与安全 / 操作记录);搜索、部门、角色、状态、排序、游标分页;停用 / 启用 / 客户转交 / 调整角色 / 超管授予均「对象卡 → 后果 → 勾选」二次确认;编辑资料弹窗;空 / 加载 / 错误三态;1024 / 1280 适配。 diff --git a/docs/开发计划/灵犀_信息流素材生产平台_开发计划_V0.1.md b/docs/开发计划/灵犀_信息流素材生产平台_开发计划_V0.1.md index 6b301e7..88b9ed9 100644 --- a/docs/开发计划/灵犀_信息流素材生产平台_开发计划_V0.1.md +++ b/docs/开发计划/灵犀_信息流素材生产平台_开发计划_V0.1.md @@ -24,6 +24,7 @@ | V0.1 | 2026-11-02 | 初稿:全项目 M0–M4 开发计划(M0 十二批次任务级 WBS;M1–M4 迭代 + 任务组 WBS;M5 预研边界)、七个管理模块专项、前后端并行与联调机制、质量门禁、风险与验收、待确认事项 | | V0.1(进度回写) | 2026-11-02 | A0 工程骨架与契约基线完成:批次总览增加状态列、A0 WBS 标注完成、回写执行证据与偏差;不改变原计划范围与验收口径 | | V0.1(进度回写 A1) | 2026-11-03 | A1 身份认证与用户管理完成:批次总览更新 A1 状态、A1 WBS 标注完成、回写执行证据与遗留;不改变原计划范围与验收口径 | +| V0.1(路由规范回写) | 2026-11-03 | 「平台」更名「管理中心」,前端路由统一为 `/<模块>/<功能>`(A1 用户页改为 `/system/users`);同步附录 C 页面清单与前端目录约定,不改变功能范围与验收口径 | ### 0.2 引用约定 @@ -912,7 +913,7 @@ PRD §7 把 **M-27(素材元素级拆解)** 与「自动字幕 → TTS 配 | 项 | 内容 | | --- | --- | -| 页面 | `/login`、`/users`、`/users/new`、`/users/:id`、部门树(内嵌用户页) | +| 页面 | `/login`、`/system/users`、`/system/users/new`、`/system/users/:id`、部门树(内嵌用户页) | | 接口 | `POST /auth/login`、`/auth/refresh`、`/auth/logout`、`GET /me`、`GET /users`、`POST /users`、`PATCH /users/{id}`(含角色分配)、`POST /users/{id}/transfer-customers` | | 关键规则 | 部门最多两级;手机号唯一;一人可多角色;离职**停用不删**,名下客户必须转交;超管建议 ≤ 2 人、授予二次确认并审计;停用即时生效 | | 页面状态 | 空态(无用户 / 无搜索结果)、加载骨架、错误重试、无权限 403;停用用户列表默认隐藏、可筛选查看 | @@ -1012,8 +1013,8 @@ PRD §7 把 **M-27(素材元素级拆解)** 与「自动字幕 → TTS 配 | 项 | 约定 | | --- | --- | -| 目录 | `apps/web/src/{app,pages,features,components,hooks,lib,stores}`;按业务域分 `features/`,禁止在 `apps/web` 内自建"共享包" | -| 路由 | 路由表集中声明(路径、标题、权限点、菜单分组);路由守卫读 `/me` 权限;无权限跳 403 | +| 目录 | `apps/web/src/{app,pages,features,components,hooks,lib,stores}`;页面按 `pages/<模块>/<功能>/` 与路由一一对应,详见 [11-前端路由与目录规范](../工程规范/11-前端路由与目录规范.md);禁止在 `apps/web` 内自建"共享包" | +| 路由 | 统一 `/<模块>/<功能>`(见 [11](../工程规范/11-前端路由与目录规范.md)),路由表集中声明(路径、标题、权限点、菜单分组);守卫读 `/me` 权限;无权限跳 403 | | 权限渲染 | 统一 `usePermission` / ``;禁止 `removeChild` 式隐藏;无权限按钮不渲染但接口仍要校验 | | 数据请求 | TanStack Query:queryKey 规范、失效策略、乐观更新仅用于勾选类;错误统一 toast + 页面级错误态 | | 表单 | 优先 Semi Form;动态表单走 `form-engine`;字段校验前后端同源(Zod / schema) | @@ -1368,22 +1369,22 @@ infra/:compose、Nginx、监控、备份脚本占位 | 路由 | 页面 | 权限点 | 批次 | | --- | --- | --- | --- | | `/login` | 登录 | 公开 | A1 | -| `/users`、`/users/new`、`/users/:id` | 用户与部门 | `user:view` / `user:manage` | A1 | -| `/roles`、`/roles/:id` | 角色与权限 | `role:view` / `role:manage` | A2 | -| `/industries` | 行业管理 | `industry_pack:view` / `customer:manage` | A3 | -| `/customers`、`/customers/new`、`/customers/:id` | 客户管理 | `customer:view` / `customer:manage` | A3 | -| `/customer-groups` | 客户组 | `customer_group:manage` | A3 | -| `/customer-fields/approvals` | 字段审批 | `customer_field:approve` | A3 | -| `/dicts`、`/dicts/:type` | 字典 | `dict:view` / `dict:edit` | A4 | -| `/system/configs` | 系统配置 | `system:configure` | A4 | -| `/audit-logs`、`/audit-logs/:id` | 审计 | `audit:view` | A5 | -| `/tasks`、`/tasks/:id` | 任务中心 | `media:view` / `media:generate` | A6 | -| `/ai/providers`、`/ai/routes`、`/ai/prompts`、`/ai/usage` | AI 配置 | `ai:view` / `ai:configure` | A7 | -| `/industry-packs`、`/industry-packs/:id/versions/:ver` | 行业包与设计器 | `industry_pack:*` | B0–B2 | -| `/assets`、`/assets/:id` | 资产包 | `asset:*` | B1 | -| `/brief-cards`、`/brief-cards/new`、`/brief-cards/:id` | 要素卡 | `brief_card:*` | B2 | -| `/script-templates` | 脚本模板 | `script_template:*` | B2 | -| `/exports`、`/exports/:id` | 导出与归档 | `export:create` | B3 | +| `/system/users`、`/system/users/new`、`/system/users/:id` | 用户与部门 | `user:view` / `user:manage` | A1 | +| `/system/roles`、`/system/roles/:id` | 角色与权限 | `role:view` / `role:manage` | A2 | +| `/system/industries` | 行业管理 | `industry_pack:view` / `customer:manage` | A3 | +| `/system/customers`、`/system/customers/new`、`/system/customers/:id` | 客户管理 | `customer:view` / `customer:manage` | A3 | +| `/system/customer-groups` | 客户组 | `customer_group:manage` | A3 | +| `/system/customer-fields/approvals` | 字段审批 | `customer_field:approve` | A3 | +| `/system/dicts`、`/system/dicts/:type` | 字典 | `dict:view` / `dict:edit` | A4 | +| `/system/settings` | 系统配置 | `system:configure` | A4 | +| `/system/audit-logs`、`/system/audit-logs/:id` | 审计 | `audit:view` | A5 | +| `/material/tasks`、`/material/tasks/:id` | 任务中心 | `media:view` / `media:generate` | A6 | +| `/system/ai`(后续 `/system/ai/providers` 等) | AI 配置 | `ai:view` / `ai:configure` | A7 | +| `/system/industry-packs`、`/system/industry-packs/:id/versions/:ver` | 行业包与设计器 | `industry_pack:*` | B0–B2 | +| `/assets/library`、`/assets/library/:id` | 资产包 | `asset:*` | B1 | +| `/scripts/framework-cards`、`/scripts/framework-cards/new`、`/scripts/framework-cards/:id` | 要素卡 | `brief_card:*` | B2 | +| `/scripts/templates` | 脚本模板 | `script_template:*` | B2 | +| `/delivery/export`、`/delivery/records`、`/delivery/records/:id` | 导出与归档 | `export:create` | B3 | | `/403`、`/404` | 异常页 | 公开 | A0 | ### D 接口清单