feat(app): 添加多模板关于我们页面及相关路由和404页面

- 新增404页面,优化未找到页面体验,避免被搜索引擎索引
- 增加文件代理接口,隐藏真实文件服务器地址,支持文件请求代理
- 实现/article、/case、/product及/page动态路由兼容列表与详情展示
- 添加动态CMS页面兼容入口处理旧式路径,统一路由与SEO设置
- 新增模板1、模板7、模板2、模板3关于我们页面,实现多模板支持
- 模板增强支持CMS单页内容加载及SEO信息动态设置
- 配置环境变量及Git忽略文件规则辅助开发和构建环境管理
This commit is contained in:
2026-09-08 12:13:44 +08:00
commit 2b69686795
381 changed files with 59891 additions and 0 deletions
+77
View File
@@ -0,0 +1,77 @@
# 单页管理(cms_page)与导航(cms_navigation)关联对接说明
> 面向后端 / website-admin「单页管理」模块负责人。
> 目标:把"菜单结构"与"单页内容"解耦又关联——导航只管菜单层级,单页管理只管正文,二者用 URL(slug)挂钩。
---
## 1. 约定结论(已与前端确认)
| 项 | 约定 |
|---|---|
| **内容唯一源** | 新建的单页内容一律建在「单页管理」(`cms_page`),按 `slug` 存取;导航节点不再存放单页正文(`design.content` 仅保留给旧租户兼容)。 |
| **规范 URL** | 单页对外地址统一为 `/page/{slug}`,例如 `/page/about-us`。 |
| **About / Contact** | `/about``/contact` 为独立富组件路由,是这两个页面的**规范地址**;`/page/about``/page/contact` 仅作兼容入口,前端已 301 跳到顶层(见 §4)。 |
| **导航关联方式** | 后台建菜单关联单页时,把 `nav.path` 写成 `/page/{slug}`(前端已支持,无需额外接口)。`CmsNavigation.pageId` 作为后端对账键保留。 |
| **旧数据兼容** | `/page/{数字}`(数字 navigationId)仍走旧 `cms_navigation + design.content`,不破坏旧租户。 |
---
## 2. 前端已具备的能力(后端无需改动即可生效)
- `getNavLink(nav)`:当 `nav.model === 'page'``nav.path``/page/` 开头时,直接返回该 path,**不会追加 `?navId=`**,单页菜单 URL 干净。
- `app/pages/page/[id].vue`
- 非数字 slug → 调 `/api/page/detail?path={slug}` → 取 `cms_page` 已发布单页正文。
- slug 为 `about` / `contact` → 301 收敛到 `/about``/contact`
- 列表/详情类栏目(article/product/case)维持原 `?navId=` 行为,不受影响。
---
## 3. 后台需要配合的 3 件事
### 3.1 单页管理创建页面时生成 slug
- `cms_page.slug` 必须**全局唯一、SEO 友好**(建议英文小写 + 连字符,如 `about-us``privacy-policy`)。
- 同一站点内 slug 不可重复;应做唯一性校验并报错提示。
- 不建议用中文或含空格的 slug(不利于 URL 与 SEO)。
### 3.2 导航菜单关联单页时填 path
两种方式任选其一(推荐方式 A,零成本):
- **方式 A(推荐)**:在「单页管理」与导航建立关联时,把菜单 `nav.path` 直接写为 `/page/{slug}`。前端拿到即可跳转,无需新增接口。
- **方式 B**:只填 `nav.pageId = cms_page.id`,由后台在返回导航树时**回写** `nav.path = /page/{slug}`(需后台保证返回前已解析)。前端不感知 pageId。
> 无论哪种方式,最终下发给前端的 `nav.path` 必须是 `/page/{slug}` 形态。
### 3.3 关联/解绑时的数据一致性
- 单页被删除或 slug 变更时,应同步清理或更新引用它的导航 `nav.path`,避免产生死链(前端遇到无效 slug 会渲染空状态,但死链对 SEO 不友好)。
- 建议后台在单页管理列表页提供"已绑定菜单"反查,便于排查。
---
## 4. 路由收敛规则(前端已落实,供后端理解)
| 访问地址 | 行为 |
|---|---|
| `/page/{slug}` | 正常渲染 cms_page 单页内容(slug 非 about/contact |
| `/page/{数字}` | 旧逻辑:按 navigationId 取 cms_navigation 正文(兼容旧租户) |
| `/page/about` | 301 → `/about`(独立富组件,规范地址) |
| `/page/contact` | 301 → `/contact`(独立富组件,规范地址) |
| `/about``/contact` | 直接渲染独立富组件 |
---
## 5. 待办(需前后端共同确认,前端暂未做)
- **动态 sitemap**:当前站点地图未纳入 `cms_page` 的 slug。需后台提供"当前站点全部已发布单页 slug 列表"接口(或 site info 携带),前端再补充到 sitemap。
- **顶层兜底层清理**`app/pages/[slug].vue` 旧兜底层可能与 `/page/{slug}` 产生 SEO 重复,后续建议收窄或移除(低优先级,不影响当前功能)。
---
## 6. 对接自查清单
- [ ] 单页管理创建页面 → 生成唯一 SEO slug ✅
- [ ] 导航关联单页 → `nav.path` 输出为 `/page/{slug}`
- [ ] slug 删除/变更 → 同步更新导航 path ✅
- [ ] 单页访问 → `/page/{slug}` 正常出内容 ✅
- [ ] about/contact 访问 → `/about``/contact`(非 `/page/about`)✅
- [ ] sitemap 是否需纳入 cms_page(待排期)⬜