# 路由规范(凯迪 ERP+OA 一体化平台) > 本平台融合了致远 OA 复刻 + 凯迪 ERP 扩建 + 多套部门系统。为避免「层级套用、前缀冗余」, > 统一收敛为一套**两段式扁平路由**体系。本文档是唯一规范,新增页面必须遵守。 ## 1. 顶层约定 | 项 | 取值 | 说明 | |----|------|------| | 路由模式 | `createWebHistory()` | HTML5 history,干净 `/...` 网址,**无 `#` 片段** | | 站点 base | `/` | 原 `/modern/app/`(OFBiz 遗留)已废弃 | | 路由前缀 | 无 | 原 `/oa/` 前缀已全量去除 | | 命名层级 | **两段** `//` | 不允许第三段嵌套 | | 路由 name | `oa::` | 由目录自动生成,全局唯一 | 历史层级 `//#/oa//`(三~四段 + `#`)-> 规范后 `//`(两段,无 `#`)。 > **去掉 `#` 的前提(已满足)**:history 模式要求服务端把「任意未知路径」回退到 `index.html`, > 否则直接刷新内页会 404。vite dev/preview 服务器**默认自带**该 SPA fallback,当前运行环境即此。 > 若将来把构建产物部署到裸静态服务器/nginx,需补一条 `try_files $uri /index.html` 之类的回退规则。 ## 2. 单一数据源 路由**不手写**。`src/data/oaModules.ts` 是唯一权威目录,每个页面一条记录: ```ts { key: 'accounts', label: '会计科目', kind: 'list', path: '/finance/accounts' } ``` `src/router/index.ts` 从 `oaAllPages` 自动生成路由表: - `path` 直接取 `page.path` - `name` = `oa:${moduleId}:${key}` - 组件解析 `pageComponent(moduleId, key)` -> `import.meta.glob('../oa/pages/**/*.vue')` 命中 `pages//.vue` 则用真实页面,否则回退 `OaGenericPage` 按 `kind` 渲染原型。 > **关键解耦**:组件解析走 `moduleId+key`,与 `path` 无关。改 `path` 不需要改页面文件名/目录。 ## 3. 顶层模块段(module) 业务域即顶层段,扁平并列,互不嵌套: ``` collab goal rd meeting masterdata knowledge hr budget culture report payment ehs archive appdev sealcenter ops intel contract mfg lab finance doccollab design crm bidding supervision mobile itasset audit ``` 特殊页(不入顶部导航): - `/` 个人空间门户(portal) - `/contacts` 通讯录 - `/org-space`、`/template-space` 空间占位 - `/collab/handle?id=…` 事项办理详情(由待办行点击进入) - `/login` 登录跳转 - `/:pathMatch(.*)*` -> NotFoundView ## 4. 命名规则 - module 段:小写、业务域语义(`finance` 而非 `cw`),多词用连字符。 - page 段(key):小写、动作或视图语义(`ledger` 台账 / `board` 看板 / `cockpit` 驾驶舱 / `accounts` 列表)。 - 同一业务概念只允许一条规范路由。**禁止重复**:如「合同台账」统一为 `/contract/ledger`, 已删除原 `/masterdata/contract` 重复路由(`pages/contract/ledger.vue` 以 import 复用 `pages/masterdata/contract.vue` 的组件,属文件级复用,非第二条路由)。 ## 5. 后端 API 命名(不随前端路由变动) 后端 API 是**独立命名空间**,与前端路由解耦,不参与本次重构: | 项 | 取值 | |----|------| | Base | `/api/oa`(dev 由 vite proxy 转发到 :8090) | | 客户端 | `http.get('/contracts')` -> 实际 `/api/oa/contracts` | | 风格 | 资源复数名词,统一 `ApiResp{code,message,data}`(code 0 = 成功) | > 前端路由用「业务域/视图」语义(给人看),后端 API 用「资源」语义(给程序用),两者各自规范、互不耦合。 > 改前端路由**不影响** API 调用——API 客户端 base 路径未动。 ## 6. 新增页面流程(务必遵守) 1. 在 `oaModules.ts` 对应模块的 `pages[]` 加一条 `{ key, label, kind, path: '//' }`。 2. 在 `src/oa/pages//.vue` 放真实页面(文件名 = key)。 3. 路由自动生成,**无需改 `router/index.ts`**。 4. 跨页跳转、搜索命中映射(`api/search.ts` 的 `HIT_ROUTE`)、移动端快捷入口 一律引用规范 `path`,不得硬编码旧 `/oa/...`。 ## 7. 验收基线(本次重构已达成) - 路由总数 118;其中 `oa:*` 命名路由 112,**112/112 自映射通过**,0 冲突、0 被遮蔽、0 落到 not-found。 - 伪造路径正确落 not-found;6 个特殊路由全部解析正常。 - `vue-tsc --noEmit` 通过(0 error);全量 emoji/箭头扫描 0。 - 无残留 `/oa/` 路由字面量(仅余 `/api/oa/` 与文件级 import,均正确)。 - **history 模式(去 `#`)实测**:直接加载/刷新深链 `/contract/ledger` 正常渲染(vite SPA fallback 生效, 5 条数据);裸输 `/zzz/...` 落 in-app NotFound;全站 live 导航网址均无 `#`(`anyHashAnywhere=false`)。 全代码仅 1 处 `createWebHashHistory->createWebHistory` + 2 处 `href="#/"` 锚点改为路由跳转;无 `location.hash` 逻辑。