# 通用企业官网程序开发计划 > 项目目标:基于 PC 端 + H5 响应式,开发一套可复用于多租户 SaaS 的企业官网**纯前端展示系统**,支持模板切换、租户隔离、独立域名绑定、订阅过期校验等能力。 > **项目定位**:本项目仅为官网前台展示,不含任何后端管理端代码。所有数据与业务能力均通过调用自研 SaaS 后端 API 实现。 > 当前阶段:方案规划(暂不写代码) --- ## 一、项目背景与现状分析 ### 1.1 项目定位 本项目是一个**纯前端展示项目**: - ✅ 本项目负责:官网页面渲染、模板展示、SEO/SSR、H5 响应式、域名路由 - ❌ 本项目不含:后端管理端、CMS 内容管理后台、租户/应用管理控制台 - 📡 数据来源:统一调用自研 SaaS 后端(Java 多租户系统)提供的 API 接口 管理端能力(模板选择、内容编辑、域名绑定、订阅管理等)由 SaaS 后端的管理后台负责,本项目只消费其 API。 ### 1.2 现有资源 | 资源 | 路径 | 说明 | | ------- | ------------------------------------------------------------------------------------------ | -------------------------------------------------------------- | | 模板预览 | `/Users/gxwebsoft/VUE/website/templates/cloud-website/template-01.png` ~ `template-04.png` | 4 套企业官网模板效果图(静态设计稿) | | 参考项目 | `/Users/gxwebsoft/VUE/websopy-pc` | 基于 Nuxt 4 + Vue 3 + TypeScript 的项目,可参考其技术栈、代理模式、租户 header 传递机制 | | SaaS 后端 | 自研 Java 多租户系统 | 提供租户、应用、CMS 站点数据、订阅管理等 API 接口 | ### 1.3 参考项目 `websopy-pc` 技术栈评估 | 维度 | 现状 | 是否适合参考 | | ------ | -------------------------------- | ----------------------------- | | 框架 | Nuxt 4.2 + Vue 3 + TS | ✅ 适合:Nuxt 原生 SSR,对 SEO/GEO 友好 | | UI 库 | Ant Design Vue | ⚠️ 偏后台,官网前台不使用,模板内自定义样式 | | 用途 | 管理控制台、开发者中心、租户后台 | ❌ 本项目不包含管理端,仅参考技术栈与代理思路 | | 已有能力 | 多租户 header、CMS 站点 API、订阅 API、代理层 | ✅ 参考其接口调用方式和代理模式 | | SEO 支持 | 已有 `usePageSeo` composable,可扩展 | ✅ 参考其 SEO 实现思路 | **结论**:本项目采用与 `websopy-pc` 相同的 Nuxt 4 + Vue 3 + TS 技术栈,但作为**独立的纯前端展示项目**开发。参考 `websopy-pc` 的 Server API 代理模式、`runtimeConfig` 配置、租户 header 传递机制,但不复用其管理端代码。 ### 1.3 核心需求拆解 1. **模板切换**:多套官网模板可配置切换,不同租户/应用使用不同模板。 2. **多租户接入**:通过租户 ID(TenantId)和应用 ID(AppId)从 SaaS 后端拉取站点配置、页面数据、菜单、内容等。 3. **SEO + GEO**:服务端渲染(SSR)、动态 TDK、结构化数据(JSON-LD)、语义化 HTML、站点地图(Sitemap)、robots 等。 4. **H5 支持**:响应式布局,一套代码同时适配 PC 和 H5。 5. **独立域名绑定**: - 默认二级域名:`https://site-[租户ID].shoplnk.cn` - 支持反向代理绑定顶级域名(如 `www.example.com`)。 6. **订阅过期校验**:通过应用订阅接口判断网站是否已过期,过期后引导续费。 --- ## 二、技术栈选择 | 层级 | 技术 | 选型理由 | | ----- | ------------------------------ | ------------------------------------------------ | | 前端框架 | **Nuxt 4**(Vue 3 + TypeScript) | 原生 SSR/SSG,SEO/GEO 友好;同 `websopy-pc` 技术栈,团队学习成本低 | | 样式方案 | **Tailwind CSS** | 与 `websopy-pc` 一致,响应式能力强,适合多模板隔离 | | UI 组件 | 模板内自定义 + **Shadcn/Vue** 或轻量组件库 | 官网模板风格差异大,避免强绑定单一组件库 | | 状态管理 | Pinia / Nuxt 内置 `useState` | 简单场景用 `useState`,复杂用 Pinia | | 请求库 | `ofetch`(Nuxt 内置) | 与 `websopy-pc` 的 `server/api` 代理模式一致 | | 后端代理 | Nuxt **Server / Nitro** | 隐藏真实 API 域名,统一处理租户 header、缓存、鉴权 | | 部署 | Node.js + Nginx 反向代理 | 支持自定义域名、SSL、多租户路由分发 | --- ## 三、整体架构设计 ``` ┌──────────────────────────────────────────────────────────────────────┐ │ 用户访问层 │ │ 默认域名: https://site-[tenantId].shoplnk.cn │ │ 自定义域名: https://www.example.com → Nginx 反向代理 │ └──────────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ Nginx 网关层 │ │ • 根据 Host 解析租户 / 应用 ID │ │ • 自定义域名 → 查询域名-租户映射表 → 转发到 Nuxt 服务 │ │ • SSL 证书管理(通配符或单域名) │ └──────────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ Nuxt 官网前台服务(Nitro) │ │ • Middleware:根据 Host/Header 识别当前租户与应用 │ │ • Server API:代理 SaaS 后端接口(站点信息、页面、订阅、文件等) │ │ • SSR 渲染:动态生成页面 HTML + SEO Meta + JSON-LD │ │ • 模板引擎:根据模板 ID 加载对应模板组件与样式 │ └──────────────────────────────────┬─────────────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────────────────────────┐ │ 自研 SaaS 后端(Java) │ │ • 租户管理 / 应用管理 / 订阅管理 │ │ • CMS 站点数据:站点配置、页面、栏目、文章、产品、案例等 │ │ • 订阅接口:判断应用是否过期、续费引导 │ └──────────────────────────────────────────────────────────────────────┘ ``` --- ## 四、目录结构规划 本项目即为 `/Users/gxwebsoft/VUE/website`,纯前端展示项目,结构如下: ``` website/ ├── app/ │ ├── components/ # 公共组件(SEO、Header、Footer、Loading、Renewal) │ ├── composables/ # 组合式函数 │ │ ├── useSite.ts # 获取当前站点信息 │ │ ├── useTenant.ts # 租户/应用识别 │ │ ├── usePageSeo.ts # SEO Meta 设置 │ │ ├── useSubscription.ts # 订阅状态校验 │ │ └── useTemplate.ts # 模板加载与切换 │ ├── layouts/ # 布局(default、blank、renewal) │ ├── pages/ # 页面路由 │ │ ├── index.vue # 首页 │ │ ├── [slug].vue # 动态 CMS 页面(关于我们、产品中心...) │ │ ├── news/ # 新闻资讯列表/详情 │ │ ├── products/ │ │ ├── cases/ │ │ └── renewal.vue # 续费引导页 │ ├── templates/ # 模板集合(核心) │ │ ├── template-01/ # 模板 1:科技感蓝 │ │ │ ├── index.vue # 模板首页 │ │ │ ├── components/ # 模板私有组件 │ │ │ ├── pages/ # 模板私有页面布局 │ │ │ ├── config.ts # 模板配置(名称、预览图、支持模块) │ │ │ └── theme.css # 模板主题变量 │ │ ├── template-02/ │ │ ├── template-03/ │ │ └── template-04/ │ ├── api/ # 前端业务请求(可选,也可直接调 server/api) │ ├── types/ # TS 类型定义 │ ├── utils/ # 工具函数 │ ├── plugins/ # 插件 │ ├── app.vue # 根入口 │ └── error.vue # 错误页 ├── server/ │ ├── api/ # 服务端代理 API │ │ ├── site/ # 站点信息 │ │ ├── page/ # 页面内容 │ │ ├── subscription/ # 订阅状态 │ │ ├── file/ # 文件代理 │ │ └── sitemap.xml.ts # 动态站点地图 │ ├── middleware/ # 服务端中间件 │ │ └── tenant.ts # 租户识别、域名解析、订阅校验 │ └── utils/ # 服务端工具函数 ├── public/ # 静态资源 ├── nuxt.config.ts # Nuxt 配置 ├── tailwind.config.cjs # Tailwind 配置 ├── package.json ├── .env.example # 环境变量示例 └── README.md ``` --- ## 五、关键模块设计方案 ### 5.1 模板切换机制 模板是核心竞争力,需要设计为“可插拔”结构: 1. **模板注册表**:每个模板在 `templates/[template-id]/config.ts` 中声明: - `id`、`name`、`description`、`preview`(预览图路径) - `supportedModules`:该模板支持的功能模块(首页、关于、产品、案例、新闻、联系、留言) - `themeConfig`:主题色、字体、间距等变量 - `layouts`:模板提供的布局组件 2. **模板加载**:根据后端返回的 `templateId` 动态 `import()` 对应模板组件。 3. **模板隔离**: - CSS 使用 `data-template-id` 命名空间或 CSS Modules 隔离,避免模板间样式冲突。 - 模板组件只负责渲染,数据由 `useSite()` 统一提供。 4. **预览与切换**:模板预览和切换能力由 SaaS 后端管理后台提供,本项目根据后端返回的 `templateId` 动态渲染即可。 ### 5.2 多租户识别策略 Nuxt Server Middleware 中统一识别当前租户,优先级: 1. **自定义域名**:Host 不是 `*.shoplnk.cn` 时,查询 SaaS 后端“域名绑定表”获取 `tenantId` + `appId`。 2. **默认二级域名**:`site-[tenantId].shoplnk.cn` → 从 Host 解析 `tenantId`。 3. **环境变量默认**:用于本地开发或默认演示站点。 4. **Header 兜底**:`TenantId` / `AppId` Header(用于调试或特殊场景)。 识别结果写入 `event.context.tenant` 和 `event.context.app`,供 SSR 渲染和 Server API 使用。 ### 5.3 SaaS 后端接口对接 本项目作为纯前端展示层,所有数据均通过调用 SaaS 后端 API 获取。参考 `websopy-pc` 的代理模式,在 Nuxt Server 层统一转发,隐藏真实后端地址: | 能力 | 参考来源 | 本项目实现 | | ---- | ---------------------------------------------------------- | ------------------------------------------ | | 站点信息 | `websopy-pc/server/api/cms/cms-website/getSiteInfo.get.ts` | `server/api/site/info.get.ts` 代理 | | 页面列表 | `websopy-pc/server/api/cms/cms-website/pageAll.get.ts` | `server/api/page/all.get.ts` 代理 | | 订阅状态 | SaaS 后端订阅接口 | `server/api/subscription/status.get.ts` 代理 | | 域名映射 | SaaS 后端域名绑定查询 | `server/api/domain/resolve.get.ts` 代理 | | 文件代理 | `websopy-pc/server/api/_file/[...path].ts` | `server/api/file/[...path].ts` 代理 | | 表单提交 | SaaS 后端留言/表单接口 | `server/api/form/submit.post.ts` 代理 | 统一在服务端转发 `TenantId` 和必要的鉴权信息,避免前端暴露真实后端地址和鉴权细节。 ### 5.4 SEO + GEO 方案 1. **SSR 渲染**:Nuxt 默认 SSR,确保搜索引擎和 AI 爬虫能拿到完整 HTML。 2. **动态 TDK**:每页根据 CMS 数据设置 `title`、`description`、`keywords`。 3. **Open Graph / Twitter Card**:每页动态设置 `og:title`、`og:description`、`og:image`、`og:url`。 4. **Canonical URL**:避免重复内容,每个页面设置 canonical 链接。 5. **结构化数据(JSON-LD)**: - `Organization` 企业信息 - `WebSite` 站点信息 - `WebPage` 页面信息 - `Product`、`Article`、`BreadcrumbList` 等 6. **Sitemap**:`server/api/sitemap.xml.ts` 根据站点页面动态生成。 7. **Robots**:根据环境配置 `robots` meta,开发/测试环境禁止抓取。 8. **语义化 HTML**:模板组件使用 `
`、`