# Novalon Website 四川睿新致远科技有限公司官方网站 - 企业数字化转型服务商 ## 项目概述 本项目是四川睿新致远科技有限公司的企业官网,采用 Next.js 16 + React 18 + TypeScript 技术栈构建,以静态生成(SSG)为主、混合渲染(SSR/ISR)为辅,提供现代化的企业展示、产品服务介绍、案例展示、新闻动态等功能。 ### 核心功能 - **首页展示** - Hero 区域、核心业务、产品服务、成功案例、关于我们、新闻动态 - **服务详情** - 软件开发、云服务、数据分析、信息安全等服务详细介绍 - **产品展示** - 产品列表和详情页面 - **案例展示** - 成功案例列表和详情 - **新闻动态** - 公司新闻、产品发布、合作动态、行业资讯 - **响应式设计** - 完美适配桌面端、平板和移动设备 - **SEO 优化** - 结构化数据、元信息优化 ## 项目规划 - **2026-07**:UI 重构(四层叙事模型、咨询专业风)、CMS 全覆盖、安全加固、封版发布 `v1.0.0-phase1` - **2026-08**:全量测试基线建立(单元 ~1600 / E2E ~800 / UJ-01~UJ-11)/ 官网产品模块品牌矩阵定位(产品外链独立站)/ 结构性文案全站 CMS 化(`page-copy`)/ 信任证据阶段 0(成立 <1 年策略) - **2026-08-20**:生产部署上线 + 生产目录 Drizzle 残留归档清理 详细历史里程碑、测试验收报告见 [docs/deployment.md](docs/deployment.md) 与 [docs/testing](docs/testing) 目录。 ## 项目进度 - [x] 首页/关于/产品/新闻等核心页面可访问性修复 - [x] JWT、中间件、表单、CMS 接口安全加固 - [x] CMS 全覆盖:法律页、新闻、团队、案例、服务、方案、产品、独立产品、首页运营位(ContentZone)、RBAC/工作流/媒体/通知全部从 CMS 读取并启用 ISR(3600s) - [x] CMS 管理后台:角色权限界面(`/admin/roles`)、内容模型 × 操作权限矩阵、super_admin 锁定 - [x] 全量测试体系:单元 **134 suites / 1697 例** / 功能 E2E **1080 例**(270 例 × chromium + chromium-mobile + firefox + webkit 四个 project)/ 视觉回归 **125 例**(25 例 × 桌面·平板·移动·firefox·webkit 五个 project)/ 用户旅程 UJ-01~UJ-11 / Lighthouse / k6 负载压力 / 安全扫描,全部通过。**计数为 2026-09-23 本树复跑实测**(`npm run test:coverage` ⇒ `Test Suites: 134 passed` / `Tests: 1697 passed` / EXIT=0;`cd e2e && npx playwright test --list` ⇒ `Total: 1205 tests in 22 files` = 1080 + 125),非估算;计数随树漂移,引用请附复算命令 - [x] **官网产品模块定位(IHG/字节式品牌矩阵,2026-08-19)**:官网品牌宣传为主,产品矩阵页为聚合入口;成熟产品 `externalUrl` 外链独立站(NovaVis → novavis.p.novalon.cn);未成熟产品详情页占位,独立站上线后切换外链 - [x] **结构性文案全站 CMS 化(2026-08-19)**:新增 `page-copy` 内容模型承载全部营销页面章节标题/眉标/描述/CTA/空状态(首页 + 服务/方案/产品/案例/新闻列表页),「CMS 优先 + 硬编码兜底」不白屏;seed 写入 6 条,本地 db:seed 已生效 - [x] **信任证据补齐·阶段 0(成立 <1 年策略,2026-08-20)**:信任策略从「结果证据」转向「可验证的过程 + 能力 + 治理证据」——首页「首批客户共创计划」板块(共创进行中/产品内测中/成果授权公开三档如实状态 + 招募 CTA)+ 关于页资质「建设中」如实空态,零编造 - [x] **生产部署上线(2026-08-20)**:`deploy.sh deploy`(本地 dist → 远端容器重建)+ 生产库 seed(page-copy/methodology 数据)完成;生产目录 Drizzle 残留源码归档清理;站点全路由 200、生产库 Prisma 结构 - [x] **数字口径结构强制(2026-09-20,critique P0 收尾)**:共享数字样式渲染的指标(`metrics`/`outcomes`/`dataProofs`)统一携带 `basis: target|team-history|verified`,渲染端自动附口径角注、未声明保守回落 `target`;CMS 新增 `basis` select 录入字段;删除产品详情页「每一项指标都源自真实客户案例」「经实际场景验证」等虚构佐证并补注角注;`metrics-basis.test.ts` 机械校验声明完整性并拦截虚构佐证禁词 - [ ] **信任证据补齐·阶段 1/2(待内测/试点客户素材)**:如实披露「共创中/内测中/已交付」三档 + 经授权客户(脱敏);有交付成果后经授权公示可量化结果(零编造原则)——口径字段与 admin 录入口已就绪,待真实数据把 `basis` 从 `target` 升级为 `verified` ## 技术栈 | 类别 | 技术 | 版本 | |------|------|------| | 框架 | Next.js | 16.2.11 | | UI 库 | React | 18.3.1 | | 语言 | TypeScript | 5.x | | 样式 | Tailwind CSS | 3.4.17 | | 代码检查 | ESLint | 9.25.1 | | 组件库 | shadcn/ui (Radix UI) | - | | 动画 | Framer Motion | 12.x | | 图标 | Lucide React | 0.563.0 | | 数据验证 | Zod | 4.3.6 | | 图表 | @antv/g2 | 5.4.8 | | 3D 效果 | Three.js | 0.183.1 | ## 快速开始 ### 环境要求 - Node.js 18+ - npm / yarn / pnpm / bun ### 安装依赖 ```bash npm install ``` ### 开发模式 ```bash npm run dev ``` 访问 http://localhost:3000 ### 构建生产版本 ```bash npm run build ``` 输出目录: `dist/` ### 预览生产版本 ```bash npm run build # 先产出 dist/ npm run preview # == npm run start == `next start -p 3000`(不是 `npx serve`) ``` `preview` 是 `start` 的同义别名,两者都是 `next start -p 3000`。项目为 `output: 'standalone'`,Next 16 在此组合下会打印 `"next start" does not work with "output: standalone" configuration. Use "node .next/standalone/server.js" instead.` ——这是**警告而非抛错**,服务仍会起来,但走的是**不受支持的降级路径**,因此它已不再被任何门禁当作产物口径: - 受支持的启动方式是 `node dist/standalone/server.js`(静态资源由 `package.json:9` 的 `postbuild` 在 `npm run build` 末尾自动拷入 `dist/standalone/`,standalone 产物本身不含 `dist/static` 与 `public`,缺了它们 `/_next/static/**` 全 404)。该启动方式**尚未做成 npm script**,目前由 `check:axe`、`check:headings`、`e2e/playwright.config.ts:134`(`E2E_TARGET=production`)与 `Jenkinsfile` 各自直接 `node` 起。 - `npm run test:e2e:prod` 走的是上面这条受支持路径(`e2e/playwright.config.ts:132-135`),**不是** `next start`。 - `npm run check:headings` 存在产物时直起 standalone,仅在产物缺失时回退 `npm run preview` 并打印告警(`scripts/utils/check-heading-hierarchy.ts:52-67`,验收 N-24③)。 详见 `CLAUDE.md`「Build & Preview」。 ## 项目结构 ``` novalon-website/ ├── src/ # 源代码 │ ├── app/ # Next.js App Router │ │ ├── (marketing)/ # 营销页面路由组 │ │ │ ├── page.tsx # 首页 │ │ │ ├── home-content-v15.tsx # 首页内容装配(V1.5) │ │ │ ├── about/ # 关于我们 │ │ │ ├── team/ # 团队 │ │ │ ├── cases/ # 成功案例 │ │ │ ├── contact/ # 联系我们 │ │ │ ├── methodology/ # 方法论 │ │ │ ├── news/ # 新闻动态 │ │ │ ├── products/ # 产品服务 │ │ │ ├── services/ # 核心业务 │ │ │ └── solutions/ # 解决方案 │ │ ├── admin/ # CMS 管理后台 │ │ ├── api/ # 服务端接口(表单、CMS、鉴权) │ │ ├── privacy/ # 隐私政策 │ │ ├── terms/ # 服务条款 │ │ ├── layout.tsx # 根布局 │ │ ├── error.tsx # 根段错误页面 │ │ ├── global-error.tsx # 全局错误边界 │ │ └── not-found.tsx # 404 页面 │ ├── components/ # React 组件 │ │ ├── ui/ # 基础 UI 组件 │ │ ├── layout/ # 布局组件 │ │ ├── sections/ # 页面区块组件 │ │ ├── content/ # 内容渲染组件(`sections.tsx`) │ │ ├── detail/ # 详情页组件 │ │ ├── admin/ # 后台组件 │ │ ├── theme/ # 主题组件 │ │ ├── seo/ # SEO 组件 │ │ └── analytics/ # 分析组件 │ ├── hooks/ # 自定义 Hooks │ ├── lib/ # 工具与领域逻辑(含 `cms/`、`constants/`、`media/`) │ └── types/ # 类型声明 ├── e2e/ # Playwright E2E + 视觉回归(**无独立 package.json**,依赖装在根目录) ├── tests/ # 非 Playwright 资产 │ ├── performance/ # k6 负载/压力脚本(由 k6 CLI 跑,不在 npm scripts 内) │ ├── lib/ # 集成测试 │ ├── styles/ # 样式测试 │ └── screenshots/ # 截图基线 ├── docs/ # 项目文档 ├── scripts/ # 脚本文件 ├── config/ # 配置文件 ├── public/ # 静态资源 └── dist/ # 构建输出 ``` ## 页面路由 | 路由 | 描述 | |------|------| | `/` | 首页 | | `/about` | 关于我们 | | `/services` | 核心业务列表 | | `/services/[id]` | 业务详情 | | `/products` | 产品服务列表 | | `/products/[id]` | 产品详情 | | `/cases` | 成功案例列表 | | `/cases/[id]` | 案例详情 | | `/news` | 新闻动态列表 | | `/news/[slug]` | 新闻详情 | | `/contact` | 联系我们 | | `/privacy` | 隐私政策 | | `/terms` | 服务条款 | ## NPM 脚本 | 命令 | 描述 | |------|------| | `npm run dev` | 启动开发服务器 | | `npm run build` | 构建生产版本 | | `npm start` | 启动生产服务器 | | `npm run lint` | 运行 ESLint 检查 | | `npm run type-check` | TypeScript 类型检查 | | `npm run test` | 全链路 E2E:`test:functional`(4 project ⇒ **1080 实例**)→ `test:visual:all`(5 project ⇒ **125 实例**)串行,`--list` 合计 **1205**。**webServer 默认是 dev server**,见 `test:e2e:prod` | | `npm run test:unit` | 运行单元测试(Jest,2026-09-23 本树复跑实测 **134 suites / 1697 tests**) | | `npm run test:coverage` | 运行测试覆盖率。**阈值**单一真源 `config/test/jest.config.js` 的 `coverageThreshold`(全局 statements/lines/functions ≥ 75%、branches ≥ 82%);**实测值**单一记录位见 [docs/development/quality-gates.md](docs/development/quality-gates.md) §3,本文件不再复制百分比以免再次互斥 | | `npm run test:e2e:fast` | 运行 E2E 快速测试(@smoke + @critical 标签) | | `npm run test:e2e:standard` | 运行 E2E 标准回归测试(@regression 标签) | | `npm run test:smoke` | 运行 E2E 冒烟测试(@smoke 标签) | | `npm run test:critical` | 运行 E2E 关键路径测试(@critical 标签) | | `npm run test:e2e:journey` | 运行用户旅程测试(@journey 标签,UJ-01/UJ-02) | | `npm run test:e2e:prod` | **产物目标** E2E(`E2E_TARGET=production` → harness 新起 `node dist/standalone/server.js`,**不是** `npm run start`——standalone 下 `next start` 不受支持;`@smoke\|@critical\|@journey` × 4 project)。**只有 GA4 的 16 例在这里真正断言**;生产响应头不在此 grep 集合内(它属 `@security` 标签与 `test:security:headers`,勿混)(2026-09-23 实测:排除 2 个写库 spec 后 92 例通过、0 skipped);须先 `npm run build`(`postbuild` 负责装配 `dist/static` + `public`) | | `npm run test:e2e:mobile` | 运行移动端 E2E 测试(`@mobile` 标签:**55 个用例**(16 `mobile.spec.ts` + 5 `mobile-user-journeys.spec.ts` + 14 `mobile-accessibility.spec.ts` + 18 `mobile-performance.spec.ts` + 2 `uj-11-home-conversion.spec.ts`),4 个功能 project 全跑 ⇒ **220 个实例**;`cd e2e && npx playwright test --list --grep @mobile` 实测 `Total: 220 tests in 5 files`) | | `npm run test:e2e:mobile:performance` | 运行移动端性能基线测试(FCP/LCP/加载时间) | | `npm run test:e2e:mobile:accessibility` | 运行移动端可访问性测试(axe-core WCAG 2.1 AA) | | `npm run test:mutation` | 运行变异测试(Stryker,评估测试质量)。**分数不在此声明**:全量轮耗时以十分钟计且 `--inPlace` 会改动工作树,本轮未复跑;最近一次落盘记录为整体 **36.98%**(`docs/test-strategy-plan.md` P4.5 / 验收清单条目,2026-08 轮次),引用时须附该出处与 `npm run test:mutation` 复算命令 | | `npm run test:mutation:quick` | 快速变异测试(`--mutate 'src/lib/utils.ts'`,同一落盘记录 **91.18%**,出处同上) | | `npm run test:security` | 安全扫描(npm audit + 安全响应头检查) | | `npm run test:security:headers` | 安全响应头检查(X-Content-Type-Options, CSP, HSTS 等) | | `npm run check:a11y` | 可访问性静态门禁伞:`check:contrast`(令牌对比度,只读 `globals.css`)+ `check:headings`(标题层级,有产物直起 standalone、缺产物才回退 preview)+ `check:brand-token`(双通道红) | | `npm run check:axe:routes` | 生成全站路由清单:sitemap ∪ 预渲染产物 ∪ 站内链接 BFS → `/tmp/axe-routes.xml`(`scripts/accessibility/crawl-routes.mjs`;退出码 0/2) | | `npm run check:axe` | 双引擎 × 双主题逐页 axe **节点计数** + 三条规则级通道的分母断言(`scripts/accessibility/axe-node-count.mjs`);退出码 0 通过 / 1 判红 / 2 清单缺失。**需先有 `node dist/standalone/server.js` 在 :3100**;不在 `test:all` 内,CI 由 `Jenkinsfile`「♿♿」阶段(仅 main)执行 | | `npm run test:all` | 全量门禁检查,`package.json:48` 原文七段:type-check + lint + coverage + **test:integration:real** + check:a11y + fast E2E + security headers;其 E2E 段仍是 dev 目标,GA4 `@critical` 在其中 skipped,需另跑 `test:e2e:prod` | | `npm run lighthouse` | 运行 Lighthouse 性能测试 | ## 代码质量门禁 项目配置了自动化质量门禁,确保代码提交前通过所有质量检查: - **ESLint**: 代码风格检查(pre-commit 经 husky + lint-staged 跑 `eslint --fix`,CI 跑全仓 `npm run lint`;判定口径 0 error,warning 不判红) - **commitlint**: 提交信息规范(`.husky/commit-msg`) - **Jest**: 代码覆盖率检查(阈值单一真源 `config/test/jest.config.js`) - **可访问性**: `npm run check:a11y`(对比度 / 标题层级 / 双通道红),CI 在「♿ 可访问性门禁」阶段逐条执行同一组 - **TypeScript**: `npm run type-check` —— **不在 pre-commit**(`.lintstagedrc.json` 只跑 `eslint --fix`),推送前须自行执行 - **E2E 目标**: `npm run test` 打 dev server;GA4 的 16 个 `@critical` 实例在该轮为 skipped,产物口径见 `npm run test:e2e:prod`(详见 [docs/development/quality-gates.md](docs/development/quality-gates.md) §5–§7) ### 提交规范 使用 Conventional Commits 规范: ``` (): ``` **提交类型**: - `feat`: 新功能 - `fix`: 修复bug - `docs`: 文档更新 - `style`: 代码格式调整 - `refactor`: 重构 - `perf`: 性能优化 - `test`: 测试相关 - `chore`: 构建/工具相关 ## 测试 项目采用多层测试策略,涵盖单元测试、集成测试、E2E 测试、用户旅程测试、视觉回归测试、变异测试等。 ### 测试工具链 | 工具 | 用途 | 配置 | |------|------|------| | **Jest** | 单元测试(2026-09-23 本树复跑:134 suites / 1697 tests) | `config/test/jest.config.js` | | **Playwright** | E2E / 视觉回归 / 用户旅程测试(`--list` 实测 1205 例 = 功能 1080 + 视觉 125) | `e2e/playwright.config.ts` | | **Stryker** | 变异测试(评估测试质量) | `stryker.config.json` | | **Allure** | 测试报告可视化 | Allure Playwright reporter | | **k6** | 负载/压力/API 性能测试 | `tests/performance/` | | **Lighthouse CI** | 性能/可访问性/SEO 审计 | `config/test/lighthouserc.json` | ### E2E 测试标签体系 | 标签 | 用途 | 执行命令 | |------|------|----------| | `@smoke` | 冒烟测试:核心功能 | `npm run test:smoke` | | `@critical` | 关键路径:CMS 工作流等 | `npm run test:critical` | | `@smoke` + `@critical` | 快速回归(<5min) | `npm run test:e2e:fast` | | `@regression` | 全量回归(<15min) | `npm run test:e2e:standard` | | `@journey` | 用户旅程(UJ-01/UJ-02) | `npm run test:e2e:journey` | | `@mobile` | 移动端专项测试(55 个用例:16 基础 + 5 用户旅程 + 14 可访问性 + 18 性能 + 2 UJ-11c;× 4 project = 220 实例) | `npm run test:e2e:mobile` | | (无标签) | 视觉回归:`@visual` 标签**并不存在**(`e2e/` 全量 grep 为 0 命中),视觉用例由 5 个 `visual-*` project 通过 `testMatch` 选中,且只跑 `visual-regression.spec.ts`(25 例 × 5 project = 125 实例) | `npm run test:visual:all` | ### 运行测试 ```bash # 单元测试 npm run test:unit # 134 suites / 1697 tests(2026-09-23 本树复跑) # 测试覆盖率 npm run test:coverage # 阈值: 全局 statements/lines/functions ≥75%、branches ≥82% # 实测值见 docs/development/quality-gates.md §3(此处不复制百分比) # E2E 测试 npm run test # 全量 E2E = 功能 1080 + 视觉 125 = 1205 实例 # 落盘通过数引自 docs/acceptance/2026-09-21-gates/skipped-tests-final-tree.json # (totalResults 1195 = 1167 passed / 28 skipped,生成于 2026-09-22 的 chain6 最终树); # 本轮未重跑全量 E2E(需 dev server + 4 引擎 + 视觉基线,且 28 条 skip 需按该文件逐条解释) npm run test:e2e:fast # 快速回归(@smoke + @critical) npm run test:e2e:standard # 标准回归(@regression) npm run test:e2e:journey # 用户旅程(@journey) # 移动端测试 npm run test:e2e:mobile # 全量移动端(55 个 @mobile 用例 × 4 project = 220 实例) npm run test:e2e:mobile:performance # 移动端性能基线 npm run test:e2e:mobile:accessibility # 移动端可访问性 # 变异测试(分数只引 docs/test-strategy-plan.md 的落盘记录,本仓未复跑) npm run test:mutation # 全量变异测试 npm run test:mutation:quick # 快速变异(仅 utils.ts) # 全量门禁检查 npm run test:all # type-check + lint + coverage + integration:real + check:a11y + fast E2E(dev 目标) + security headers ``` ## 部署 ### 统一发布脚本(推荐) 项目发布统一通过 `scripts/deploy.sh` 完成,包含构建、发布、回滚、状态查看: ```bash # 构建产物(`next build`,output=standalone;脚本再把 public/ 同步进 dist、把 dist/static 复制为 dist/_next/static 供 Nginx 直服) ./scripts/deploy.sh build # 构建并发布到生产服务器(默认命令,等价于 ./scripts/deploy.sh deploy) ./scripts/deploy.sh deploy # 使用现有 dist/ 直接发布(跳过本地构建) ./scripts/deploy.sh deploy --skip-build # 回滚到最近一次远程备份 ./scripts/deploy.sh rollback # 查看生产环境发布状态 ./scripts/deploy.sh status # 查看完整帮助 ./scripts/deploy.sh help ``` 常用选项: ```bash ./scripts/deploy.sh deploy --skip-build --auto-rollback ./scripts/deploy.sh deploy --server-ip 139.155.109.62 --project-name novalon-website ``` 也可通过环境变量覆盖默认配置:`SERVER_IP`、`SERVER_USER`、`DEPLOY_ROOT`、`PROJECT_NAME`、`NGINX_CONTAINER`、`DOMAIN`、`BACKUP_RETENTION_COUNT`、`DIST_DIR`。 npm 快捷命令:`npm run deploy`、`npm run deploy:skip-build`、`npm run deploy:rollback`、`npm run deploy:status`。 ### 混合渲染构建(当前) 项目当前使用 `output: 'standalone'`,构建产物位于 `dist/`: ```bash npm run build ``` 生产部署采用混合渲染: - Nginx 直接托管 `dist/` 中的公共静态资源(图片、字体、`_next/static` 等) - `/api/*`、`/admin/*` 及 ISR/SSR 回源代理到 Next.js 容器 `novalon-website:3000` - Next.js 容器通过 `Dockerfile.prod` + `docker-compose.server.yml` 启动,SQLite 数据库挂载在 `./data` ```bash # 本地构建 npm run build # 服务器构建并启动 Next.js 容器 cd /home/novalon/docker-app/novalon-website docker-compose -f docker-compose.server.yml up -d --build ``` ### 生产环境历史残留清理(Drizzle) 生产服务器 `/home/novalon/docker-app/novalon-website` 曾残留一套使用 Drizzle ORM 的历史源码(`src/db/`、`drizzle/`、`drizzle.config.ts`)。经核实,生产实际运行的环境为 **Prisma CMS**(容器从 `dist/` standalone 构建,含 `@prisma/client` 与 `prisma/seed.ts`),上述 Drizzle 源码不参与任何构建/部署/运行。 2026-08-20 已将 Drizzle 专属残留归档至 `archive-Drizzle-20260820_094628/`(含 `src/db/`、`drizzle/`、`drizzle.config.ts`)。同批做了一次更大范围整理:将历史源码/测试/文档/旧备份归档至 `archive-src-cleanup-20260820_095755/`(含 `src/`、`playwright-*`、`test-framework`、`tests`、`e2e`、`reports`、`docs`、`monitoring`、`html` 等)与 `archive-misc-20260820_095824/`(含根 `data.db`、`scripts.backup`、`test-results`、旧 `dist_backup_20260818_*` 等)。生产确认保留运行时资产:`dist/`、`public/`、`data/`、`uploads/`、`Dockerfile.prod`、`docker-compose.server.yml`、`.env*`、`deploy.sh`、`scripts/`。生产站点与数据库均不受影响(容器 healthy、全路由 200、共创板块正常)。后续如需彻底移除归档目录(共约 908M),可在运行稳定数周后删除。 ### CI/CD Jenkins Pipeline(`Jenkinsfile`)在部署阶段调用 `./scripts/deploy.sh deploy --skip-build`,部署失败时自动调用 `./scripts/deploy.sh rollback` 回滚。 ## 文档 详细文档位于 `docs/` 目录: - [架构文档](docs/architecture.md) - 系统架构设计 - [组件文档](docs/components.md) - 组件使用指南 - [测试文档](docs/testing.md) - 测试策略和指南 - [部署文档](docs/deployment.md) - 部署流程说明 - [经验教训](docs/lessons-learned.md) - 跨任务经验教训汇总,避免重复踩坑 - [问题排查](docs/troubleshooting.md) - 常见问题快速索引与解决方案 ## 许可证 Copyright © 2026 四川睿新致远科技有限公司