From 124596ae9475118af3ed3f278311cd8273fe8c1f Mon Sep 17 00:00:00 2001
From: Zopt <100939012+Zopt@users.noreply.github.com>
Date: Tue, 16 Sep 2025 16:37:48 +0800
Subject: [PATCH] first commit
---
.eslintrc.json | 3 +
.gitignore | 39 +
.prettierrc | 11 +
README.md | 273 +
STATIC_DEPLOYMENT.md | 166 +
WINDOWS_BUILD_GUIDE.md | 185 +
app/[locale]/about/page.tsx | 90 +
app/[locale]/layout.tsx | 14 +
app/[locale]/news/[id]/not-found.tsx | 147 +
app/[locale]/news/[id]/page.tsx | 467 +
app/[locale]/news/page.tsx | 380 +
app/[locale]/page.tsx | 65 +
app/[locale]/products/page.tsx | 266 +
app/[locale]/support/page.tsx | 259 +
app/[locale]/test-seo/page.tsx | 34 +
app/about/page.tsx | 7 +
app/favicon.ico | Bin 0 -> 15406 bytes
app/globals.css | 168 +
app/layout.tsx | 198 +
app/news/[id]/page.tsx | 297 +
app/news/page.tsx | 7 +
app/page.tsx | 48 +
app/products/page.tsx | 7 +
app/robots.ts | 12 +
app/sitemap.ts | 41 +
app/support/page.tsx | 7 +
build-static.js | 98 +
bun.lockb | Bin 0 -> 184880 bytes
components.json | 20 +
components/Footer.tsx | 153 +
components/HomePageClient.tsx | 271 +
components/HomePageSEO.tsx | 314 +
components/LanguageSwitcher.tsx | 72 +
components/Layout.tsx | 38 +
components/Navigation.tsx | 212 +
components/SEOPreview.tsx | 95 +
components/StructuredData.tsx | 146 +
components/TDKConfigManager.tsx | 230 +
components/TDKManager.tsx | 88 +
components/about/CertificationsSection.tsx | 90 +
components/about/CompanyMilestones.tsx | 95 +
components/about/CompanyOverview.tsx | 147 +
components/about/TeamSection.tsx | 64 +
data/locales/en/about.json | 129 +
data/locales/en/common.json | 24 +
data/locales/en/home.json | 63 +
data/locales/en/news.json | 97 +
data/locales/en/products.json | 128 +
data/locales/en/support.json | 101 +
data/locales/zh-CN/about.json | 128 +
data/locales/zh-CN/common.json | 24 +
data/locales/zh-CN/home.json | 63 +
data/locales/zh-CN/news.json | 97 +
data/locales/zh-CN/products.json | 114 +
data/locales/zh-CN/support.json | 101 +
data/locales/zh-TW/about.json | 129 +
data/locales/zh-TW/common.json | 24 +
data/locales/zh-TW/home.json | 63 +
data/locales/zh-TW/news.json | 97 +
data/locales/zh-TW/products.json | 121 +
data/locales/zh-TW/support.json | 101 +
docs/news/en/ai-transformation-2024.md | 64 +
docs/news/en/cloud-security-best-practices.md | 88 +
docs/news/en/company-expansion-2024.md | 64 +
docs/news/zh-CN/ai-transformation-2024.md | 64 +
.../zh-CN/cloud-security-best-practices.md | 88 +
docs/news/zh-CN/company-expansion-2024.md | 64 +
docs/news/zh-TW/ai-transformation-2024.md | 64 +
.../zh-TW/cloud-security-best-practices.md | 88 +
docs/news/zh-TW/company-expansion-2024.md | 64 +
dsds | 1 -
lib/i18n.ts | 99 +
lib/markdown.ts | 125 +
lib/seo.ts | 358 +
lib/utils.ts | 6 +
middleware.ts | 69 +
next.config.mjs | 28 +
package-lock.json | 7865 +++++++++++++++++
package.json | 42 +
postcss.config.mjs | 8 +
public/images/logo.png | Bin 0 -> 109498 bytes
public/site.webmanifest | 16 +
tailwind.config.ts | 67 +
tsconfig.json | 40 +
yarn.lock | 4152 +++++++++
85 files changed, 20451 insertions(+), 1 deletion(-)
create mode 100644 .eslintrc.json
create mode 100644 .gitignore
create mode 100644 .prettierrc
create mode 100644 README.md
create mode 100644 STATIC_DEPLOYMENT.md
create mode 100644 WINDOWS_BUILD_GUIDE.md
create mode 100644 app/[locale]/about/page.tsx
create mode 100644 app/[locale]/layout.tsx
create mode 100644 app/[locale]/news/[id]/not-found.tsx
create mode 100644 app/[locale]/news/[id]/page.tsx
create mode 100644 app/[locale]/news/page.tsx
create mode 100644 app/[locale]/page.tsx
create mode 100644 app/[locale]/products/page.tsx
create mode 100644 app/[locale]/support/page.tsx
create mode 100644 app/[locale]/test-seo/page.tsx
create mode 100644 app/about/page.tsx
create mode 100644 app/favicon.ico
create mode 100644 app/globals.css
create mode 100644 app/layout.tsx
create mode 100644 app/news/[id]/page.tsx
create mode 100644 app/news/page.tsx
create mode 100644 app/page.tsx
create mode 100644 app/products/page.tsx
create mode 100644 app/robots.ts
create mode 100644 app/sitemap.ts
create mode 100644 app/support/page.tsx
create mode 100644 build-static.js
create mode 100644 bun.lockb
create mode 100644 components.json
create mode 100644 components/Footer.tsx
create mode 100644 components/HomePageClient.tsx
create mode 100644 components/HomePageSEO.tsx
create mode 100644 components/LanguageSwitcher.tsx
create mode 100644 components/Layout.tsx
create mode 100644 components/Navigation.tsx
create mode 100644 components/SEOPreview.tsx
create mode 100644 components/StructuredData.tsx
create mode 100644 components/TDKConfigManager.tsx
create mode 100644 components/TDKManager.tsx
create mode 100644 components/about/CertificationsSection.tsx
create mode 100644 components/about/CompanyMilestones.tsx
create mode 100644 components/about/CompanyOverview.tsx
create mode 100644 components/about/TeamSection.tsx
create mode 100644 data/locales/en/about.json
create mode 100644 data/locales/en/common.json
create mode 100644 data/locales/en/home.json
create mode 100644 data/locales/en/news.json
create mode 100644 data/locales/en/products.json
create mode 100644 data/locales/en/support.json
create mode 100644 data/locales/zh-CN/about.json
create mode 100644 data/locales/zh-CN/common.json
create mode 100644 data/locales/zh-CN/home.json
create mode 100644 data/locales/zh-CN/news.json
create mode 100644 data/locales/zh-CN/products.json
create mode 100644 data/locales/zh-CN/support.json
create mode 100644 data/locales/zh-TW/about.json
create mode 100644 data/locales/zh-TW/common.json
create mode 100644 data/locales/zh-TW/home.json
create mode 100644 data/locales/zh-TW/news.json
create mode 100644 data/locales/zh-TW/products.json
create mode 100644 data/locales/zh-TW/support.json
create mode 100644 docs/news/en/ai-transformation-2024.md
create mode 100644 docs/news/en/cloud-security-best-practices.md
create mode 100644 docs/news/en/company-expansion-2024.md
create mode 100644 docs/news/zh-CN/ai-transformation-2024.md
create mode 100644 docs/news/zh-CN/cloud-security-best-practices.md
create mode 100644 docs/news/zh-CN/company-expansion-2024.md
create mode 100644 docs/news/zh-TW/ai-transformation-2024.md
create mode 100644 docs/news/zh-TW/cloud-security-best-practices.md
create mode 100644 docs/news/zh-TW/company-expansion-2024.md
delete mode 100644 dsds
create mode 100644 lib/i18n.ts
create mode 100644 lib/markdown.ts
create mode 100644 lib/seo.ts
create mode 100644 lib/utils.ts
create mode 100644 middleware.ts
create mode 100644 next.config.mjs
create mode 100644 package-lock.json
create mode 100644 package.json
create mode 100644 postcss.config.mjs
create mode 100644 public/images/logo.png
create mode 100644 public/site.webmanifest
create mode 100644 tailwind.config.ts
create mode 100644 tsconfig.json
create mode 100644 yarn.lock
diff --git a/.eslintrc.json b/.eslintrc.json
new file mode 100644
index 0000000..bffb357
--- /dev/null
+++ b/.eslintrc.json
@@ -0,0 +1,3 @@
+{
+ "extends": "next/core-web-vitals"
+}
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..b45fcb9
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,39 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+.yarn/install-state.gz
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env*.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
+next-env.d.ts
+
+# vscode
+.vscode
\ No newline at end of file
diff --git a/.prettierrc b/.prettierrc
new file mode 100644
index 0000000..36f0850
--- /dev/null
+++ b/.prettierrc
@@ -0,0 +1,11 @@
+{
+ "singleQuote": true,
+ "printWidth": 100,
+ "tabWidth": 4,
+ "useTabs": false,
+ "semi": true,
+ "jsxSingleQuote": false,
+ "bracketSpacing": true,
+ "arrowParens": "always",
+ "endOfLine": "lf"
+}
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..a3329a8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,273 @@
+# HaoAWS官方网站
+
+
+
+
+
+一个现代化的多语言企业云服务官网,基于 Next.js 14 构建,支持完全静态导出和多语言国际化。
+
+## ✨ 项目特性
+
+- 🌍 **多语言支持** - 简体中文、繁体中文、英文
+- 📱 **响应式设计** - 完美适配桌面、平板、手机
+- ⚡ **静态导出** - 支持完全静态化部署,加载速度极快
+- 🔍 **SEO 优化** - 完整的 Meta 标签、结构化数据、多语言 sitemap
+- 📰 **新闻系统** - 基于 Markdown 的内容管理系统
+- 🎨 **现代 UI** - 使用 Tailwind CSS 和 ShadCN 组件
+- 🚀 **性能优化** - 代码分割、图片优化、预加载
+- 📦 **部署友好** - 支持 Netlify、Vercel、GitHub Pages 等平台
+
+## 🛠️ 技术栈
+
+- **前端框架**: [Next.js 14](https://nextjs.org/) (App Router)
+- **样式**: [Tailwind CSS](https://tailwindcss.com/)
+- **组件**: [ShadCN/UI](https://ui.shadcn.com/)
+- **国际化**: 自定义 i18n 解决方案
+- **内容管理**: Markdown + Gray Matter
+- **类型安全**: TypeScript
+- **代码规范**: ESLint + Prettier
+
+## 📁 项目结构
+
+```
+kejiyun/
+├── app/ # Next.js App Router
+│ ├── [locale]/ # 多语言路由
+│ │ ├── about/ # 关于我们页面
+│ │ ├── news/ # 新闻列表和详情
+│ │ ├── products/ # 产品页面
+│ │ ├── support/ # 支持页面
+│ │ └── layout.tsx # 多语言布局
+│ ├── news/[id]/ # 默认语言新闻详情
+│ ├── globals.css # 全局样式
+│ └── layout.tsx # 根布局
+├── components/ # 可复用组件
+│ ├── about/ # 关于页面组件
+│ ├── LanguageSwitcher.tsx # 语言切换器
+│ ├── Layout.tsx # 布局组件
+│ └── SEOPreview.tsx # SEO 预览
+├── data/ # 数据文件
+│ └── locales/ # 多语言翻译文件
+│ ├── en/ # 英文翻译
+│ ├── zh-CN/ # 简体中文翻译
+│ └── zh-TW/ # 繁体中文翻译
+├── docs/ # 文档和新闻内容
+│ └── news/ # 新闻 Markdown 文件
+├── lib/ # 工具函数
+│ ├── i18n.ts # 国际化配置
+│ ├── markdown.ts # Markdown 解析
+│ └── seo.ts # SEO 工具
+├── public/ # 静态资源
+└── middleware.ts # 路由中间件
+```
+
+## 🚀 快速开始
+
+### 安装依赖
+
+```bash
+npm install
+# 或
+yarn install
+```
+
+### 开发模式
+
+```bash
+npm run dev
+```
+
+打开 [http://localhost:3000](http://localhost:3000) 查看网站。
+
+### 构建生产版本
+
+```bash
+# 普通构建
+npm run build
+
+# 静态导出构建
+npm run build:static
+```
+
+### 本地预览静态版本
+
+```bash
+npm run serve
+# 或
+npm run preview
+```
+
+## 🌍 多语言支持
+
+### 支持的语言
+
+- **简体中文** (`zh-CN`) - 默认语言,路径: `/`
+- **繁体中文** (`zh-TW`) - 路径: `/zh-TW/`
+- **英文** (`en`) - 路径: `/en/`
+
+### 路由示例
+
+```
+/ # 简体中文首页
+/about/ # 简体中文关于页面
+/news/article-id/ # 简体中文新闻详情
+
+/zh-TW/ # 繁体中文首页
+/zh-TW/about/ # 繁体中文关于页面
+/zh-TW/news/article-id/ # 繁体中文新闻详情
+
+/en/ # 英文首页
+/en/about/ # 英文关于页面
+/en/news/article-id/ # 英文新闻详情
+```
+
+### 添加新语言
+
+1. 在 `lib/i18n.ts` 中添加语言配置
+2. 在 `data/locales/` 中创建对应的翻译文件
+3. 在 `docs/news/` 中添加对应语言的新闻文件
+4. 更新各页面的 `generateStaticParams` 函数
+
+## 📰 新闻系统
+
+### 新闻文件结构
+
+```markdown
+---
+title: "文章标题"
+description: "文章描述"
+date: "2024-01-01"
+author: "作者"
+tags: ["标签1", "标签2"]
+---
+
+# 文章内容
+
+这里是 Markdown 格式的文章内容...
+```
+
+### 添加新新闻
+
+1. 在 `docs/news/[语言]/` 目录下创建新的 `.md` 文件
+2. 更新 `app/[locale]/news/[id]/page.tsx` 中的 `generateStaticParams` 函数
+3. 重新构建网站
+
+## 🔍 SEO 优化
+
+### 已实现的 SEO 功能
+
+- ✅ 多语言 Meta 标签
+- ✅ Open Graph 标签
+- ✅ Twitter Card 支持
+- ✅ 结构化数据 (JSON-LD)
+- ✅ 自动生成 sitemap.xml
+- ✅ robots.txt 配置
+- ✅ 语言链接标签 (hreflang)
+
+### SEO 配置
+
+在 `lib/seo.ts` 中配置默认的 SEO 设置,每个页面可以覆盖这些设置。
+
+## 📦 部署
+
+### 静态部署(推荐)
+
+#### Netlify
+```bash
+# 构建命令
+npm run build:static
+
+# 发布目录
+out
+```
+
+#### Vercel
+```bash
+npm install -g vercel
+vercel --prod
+```
+
+#### GitHub Pages
+```bash
+npm run build:static
+# 将 out/ 目录内容推送到 gh-pages 分支
+```
+
+### 服务器部署
+
+```bash
+npm run build
+npm start
+```
+
+## 🎨 自定义和扩展
+
+### 添加新页面
+
+1. 在 `app/[locale]/` 目录下创建新页面
+2. 添加对应的翻译文件
+3. 更新导航菜单
+4. 添加 `generateStaticParams` 函数(如果需要静态导出)
+
+### 修改样式
+
+项目使用 Tailwind CSS,可以在以下文件中修改样式:
+- `app/globals.css` - 全局样式
+- `tailwind.config.ts` - Tailwind 配置
+- 各组件文件中的 className
+
+### 添加新组件
+
+在 `components/` 目录下创建新组件,遵循现有的命名和结构规范。
+
+## 🔧 开发指南
+
+### 代码规范
+
+```bash
+# 代码格式化
+npm run format
+
+# 代码检查
+npm run lint
+```
+
+### Windows 开发
+
+如果在 Windows 上遇到权限问题,请参考 [WINDOWS_BUILD_GUIDE.md](./WINDOWS_BUILD_GUIDE.md)。
+
+## 📋 可用脚本
+
+```bash
+npm run dev # 开发模式
+npm run build # 生产构建
+npm run build:static # 静态导出构建
+npm run build:simple # 简化构建(解决权限问题)
+npm run start # 启动生产服务器
+npm run lint # 代码检查
+npm run format # 代码格式化
+npm run serve # 本地预览静态文件
+npm run preview # 构建并预览
+```
+
+## 🐛 故障排除
+
+### 常见问题
+
+1. **构建权限错误** - 参考 [WINDOWS_BUILD_GUIDE.md](./WINDOWS_BUILD_GUIDE.md)
+2. **语言切换不工作** - 检查 Cookie 设置和客户端 JavaScript
+3. **静态导出失败** - 确保所有动态路由都有 `generateStaticParams`
+
+### 获取帮助
+
+- 查看 [静态部署指南](./STATIC_DEPLOYMENT.md)
+- 查看 [Windows 构建指南](./WINDOWS_BUILD_GUIDE.md)
+- 检查 Next.js 官方文档
+
+## 📄 许可证
+
+本项目采用 MIT 许可证。
+
+---
+
+**提示**: 这是一个完全静态化的网站,构建后可以部署到任何静态文件托管服务,无需 Node.js 服务器环境。
diff --git a/STATIC_DEPLOYMENT.md b/STATIC_DEPLOYMENT.md
new file mode 100644
index 0000000..f9280ea
--- /dev/null
+++ b/STATIC_DEPLOYMENT.md
@@ -0,0 +1,166 @@
+# 静态部署指南
+
+## 🚀 静态打包命令
+
+### 构建静态文件
+```bash
+npm run build:static
+```
+
+### 本地预览静态网站
+```bash
+npm run preview
+```
+
+### 仅构建(不启动服务器)
+```bash
+npm run build
+```
+
+### 仅启动静态文件服务器
+```bash
+npm run serve
+```
+
+## 📁 输出目录
+
+静态文件将生成在 `out/` 目录中,包含:
+
+```
+out/
+├── index.html # 首页 (简体中文)
+├── zh-TW/
+│ ├── index.html # 繁体中文首页
+│ ├── about/index.html # 关于我们页面
+│ ├── products/index.html # 产品页面
+│ ├── news/
+│ │ ├── index.html # 新闻列表
+│ │ └── [id]/index.html # 新闻详情
+│ └── support/index.html # 支持页面
+├── en/
+│ ├── index.html # 英文首页
+│ └── ... # 其他英文页面
+├── news/
+│ ├── index.html # 默认语言新闻列表
+│ └── [id]/index.html # 默认语言新闻详情
+├── about/index.html # 默认语言关于页面
+├── products/index.html # 默认语言产品页面
+├── support/index.html # 默认语言支持页面
+└── _next/ # Next.js 静态资源
+```
+
+## 🌐 部署到不同平台
+
+### 1. Netlify
+1. 将 `out/` 目录拖拽到 Netlify 控制台
+2. 或连接 Git 仓库,设置构建命令:
+ ```
+ Build command: npm run build:static
+ Publish directory: out
+ ```
+
+### 2. Vercel
+```bash
+npx vercel --prod
+```
+
+### 3. GitHub Pages
+1. 将 `out/` 目录内容推送到 `gh-pages` 分支
+2. 在仓库设置中启用 GitHub Pages
+
+### 4. 服务器部署
+将 `out/` 目录上传到服务器的网站根目录
+
+## ⚙️ 配置说明
+
+### 基础路径配置
+如果需要部署到子目录,修改 `next.config.mjs`:
+
+```js
+const nextConfig = {
+ output: 'export',
+ basePath: '/your-subdirectory', // 取消注释并设置路径
+ // ...
+};
+```
+
+### 图片优化
+静态导出中图片优化已设置为:
+```js
+images: {
+ unoptimized: true, // 静态导出必需
+}
+```
+
+## 🔄 多语言路由说明
+
+静态导出后的路由结构:
+
+- **简体中文 (默认)**:`/`, `/about`, `/news/xxx`
+- **繁体中文**:`/zh-TW/`, `/zh-TW/about`, `/zh-TW/news/xxx`
+- **英文**:`/en/`, `/en/about`, `/en/news/xxx`
+
+## ⚠️ 注意事项
+
+### 静态导出限制
+1. **无服务器端渲染**:所有页面在构建时生成
+2. **无中间件**:语言切换依赖客户端逻辑
+3. **无动态API路由**:不能使用 `/api` 路由
+4. **无服务器端重定向**:依赖客户端跳转
+
+### 语言切换机制
+在静态模式下:
+- 中间件不会执行
+- 语言切换完全依赖客户端 JavaScript
+- Cookie 设置在客户端进行
+
+### 新增文章
+如需添加新文章,需要:
+1. 在 `docs/news/` 中添加 Markdown 文件
+2. 更新页面中的 `generateStaticParams` 函数
+3. 重新构建
+
+## 🧪 测试
+
+### 本地测试
+```bash
+# 构建并预览
+npm run preview
+
+# 访问 http://localhost:3000
+```
+
+### 构建验证
+```bash
+# 检查构建输出
+npm run build:static
+ls -la out/
+
+# 验证多语言页面
+ls -la out/zh-TW/
+ls -la out/en/
+```
+
+## 🔧 故障排除
+
+### 常见问题
+
+1. **页面404**:检查 `generateStaticParams` 是否包含所有路由
+2. **样式丢失**:确认 CSS 文件正确引入
+3. **图片不显示**:检查图片路径和 `unoptimized: true` 设置
+4. **语言切换无效**:确认 JavaScript 已启用
+
+### 调试步骤
+1. 检查 `out/` 目录结构
+2. 查看浏览器开发者工具控制台
+3. 验证静态文件访问路径
+
+## 📈 性能优化
+
+- ✅ 自动代码分割
+- ✅ 静态资源优化
+- ✅ CSS 压缩
+- ✅ JavaScript 压缩
+- ✅ 预加载关键资源
+
+静态导出的网站加载速度极快,适合 CDN 分发!
\ No newline at end of file
diff --git a/WINDOWS_BUILD_GUIDE.md b/WINDOWS_BUILD_GUIDE.md
new file mode 100644
index 0000000..b6ecdce
--- /dev/null
+++ b/WINDOWS_BUILD_GUIDE.md
@@ -0,0 +1,185 @@
+# Windows 静态构建指南
+
+## 🚨 常见权限问题解决方案
+
+### 方法一:使用管理员权限
+1. 右键点击 PowerShell 或 CMD
+2. 选择"以管理员身份运行"
+3. 导航到项目目录:`cd "E:\成品的网站\kejiyun"`
+4. 运行构建:`npm run build:static`
+
+### 方法二:修改杀毒软件设置
+1. 临时关闭实时保护(Windows Defender 或其他杀毒软件)
+2. 将项目目录添加到杀毒软件白名单
+3. 重新尝试构建
+
+### 方法三:使用简化构建命令
+```bash
+# 方法 1
+npm run build:simple
+
+# 方法 2
+npx next build
+
+# 方法 3(如果上面的失败)
+set NEXT_DISABLE_TELEMETRY=1
+set NODE_ENV=production
+npx next build
+```
+
+## 🔧 手动构建步骤
+
+### 1. 清理环境
+```powershell
+# 停止所有Node进程
+Get-Process node -ErrorAction SilentlyContinue | Stop-Process -Force
+
+# 清理缓存目录
+Remove-Item -Path ".next", "out" -Recurse -Force -ErrorAction SilentlyContinue
+
+# 清理npm缓存
+npm cache clean --force
+```
+
+### 2. 检查文件权限
+```powershell
+# 检查当前目录权限
+Get-Acl . | Format-List
+
+# 如果需要,修改目录权限
+icacls . /grant $env:USERNAME:F /t
+```
+
+### 3. 重新安装依赖
+```bash
+# 删除node_modules
+Remove-Item -Path "node_modules" -Recurse -Force -ErrorAction SilentlyContinue
+
+# 重新安装
+npm install
+```
+
+### 4. 构建
+```bash
+npm run build:static
+```
+
+## 🚀 成功构建后的验证
+
+构建成功后,您应该看到:
+
+```
+out/
+├── index.html # ✅ 简体中文首页
+├── about/
+│ └── index.html # ✅ 关于页面
+├── news/
+│ ├── index.html # ✅ 新闻列表
+│ ├── ai-transformation-2024/
+│ ├── cloud-security-best-practices/
+│ └── company-expansion-2024/
+├── products/
+├── support/
+├── zh-TW/ # ✅ 繁体中文版本
+├── en/ # ✅ 英文版本
+└── _next/ # ✅ 静态资源
+```
+
+## 🌐 本地预览
+
+```bash
+# 启动静态服务器
+npm run serve
+
+# 或者使用Python(如果安装了)
+python -m http.server 3000 --directory out
+
+# 或者使用其他静态服务器
+npx http-server out -p 3000
+```
+
+## 🔍 故障排除
+
+### 错误:EPERM: operation not permitted
+**原因**:文件权限或进程锁定问题
+
+**解决方案**:
+1. 以管理员身份运行终端
+2. 确保没有其他进程正在使用项目文件
+3. 临时关闭杀毒软件
+4. 重启电脑后重试
+
+### 错误:构建过程中卡住
+**解决方案**:
+1. 按 `Ctrl+C` 停止进程
+2. 运行:`npm run build:simple`
+3. 或使用 `npx next build --debug`
+
+### 错误:out目录为空或缺少文件
+**检查**:
+1. 查看构建日志中的错误信息
+2. 确认 `generateStaticParams` 函数正确
+3. 检查是否有动态导入或服务器端功能
+
+### 错误:语言切换不工作
+这是正常的,静态导出模式下:
+- 中间件不会执行
+- 语言切换依赖客户端JavaScript
+- 需要在浏览器中测试
+
+## 📦 部署选项
+
+### 1. Netlify(推荐)
+```bash
+# 方法1:拖拽部署
+# 将整个 out/ 目录拖拽到 https://app.netlify.com/drop
+
+# 方法2:命令行部署
+npm install -g netlify-cli
+netlify deploy --prod --dir=out
+```
+
+### 2. Vercel
+```bash
+npm install -g vercel
+vercel --prod
+```
+
+### 3. GitHub Pages
+```bash
+# 推送 out/ 内容到 gh-pages 分支
+git subtree push --prefix out origin gh-pages
+```
+
+### 4. 传统服务器
+- 上传 `out/` 目录到服务器的网站根目录
+- 确保服务器支持SPA路由(对于多语言URL)
+
+## ⚡ 性能优化
+
+构建后的静态网站已经包含:
+- ✅ 代码分割
+- ✅ 资源压缩
+- ✅ 图片优化
+- ✅ CSS/JS 最小化
+- ✅ 预加载关键资源
+
+## 🔄 更新流程
+
+当您修改内容后:
+1. 更新相应的Markdown或JSON文件
+2. 如果添加新文章,更新 `generateStaticParams`
+3. 重新运行 `npm run build:static`
+4. 重新部署 `out/` 目录
+
+## 📞 需要帮助?
+
+如果仍然遇到问题:
+1. 确保使用管理员权限
+2. 检查Windows版本兼容性
+3. 尝试在不同的文件夹位置重新克隆项目
+4. 考虑使用WSL(Windows Subsystem for Linux)
+
+---
+
+**记住**:静态导出的网站速度极快,完全不需要Node.js服务器,可以部署到任何静态网站托管服务!
\ No newline at end of file
diff --git a/app/[locale]/about/page.tsx b/app/[locale]/about/page.tsx
new file mode 100644
index 0000000..4258b51
--- /dev/null
+++ b/app/[locale]/about/page.tsx
@@ -0,0 +1,90 @@
+import { getTranslations, Locale, getNavigationPaths } from '@/lib/i18n';
+import { generateMetadata as generateSEOMetadata } from '@/lib/seo';
+import Layout from '@/components/Layout';
+import CompanyOverview from '@/components/about/CompanyOverview';
+import CompanyMilestones from '@/components/about/CompanyMilestones';
+import TeamSection from '@/components/about/TeamSection';
+import CertificationsSection from '@/components/about/CertificationsSection';
+
+interface AboutPageProps {
+ params: {
+ locale: Locale;
+ };
+}
+
+export async function generateStaticParams() {
+ const locales = ['zh-CN', 'zh-TW', 'en'];
+ return locales.map((locale) => ({
+ locale,
+ }));
+}
+
+export async function generateMetadata({ params }: AboutPageProps) {
+ return generateSEOMetadata(params.locale, 'about');
+}
+
+export default async function AboutPage({ params }: AboutPageProps) {
+ const { locale } = params;
+ const [common, about] = await Promise.all([
+ getTranslations(locale, 'common'),
+ getTranslations(locale, 'about'),
+ ]);
+
+ const navigationPaths = getNavigationPaths(locale);
+ const navigation = [
+ {
+ name: common.navigation.home,
+ href: navigationPaths.find((p) => p.key === 'home')?.path || '/',
+ },
+ {
+ name: common.navigation.products,
+ href: navigationPaths.find((p) => p.key === 'products')?.path || '/products',
+ },
+ {
+ name: common.navigation.news,
+ href: navigationPaths.find((p) => p.key === 'news')?.path || '/news',
+ },
+ {
+ name: common.navigation.support,
+ href: navigationPaths.find((p) => p.key === 'support')?.path || '/support',
+ },
+ {
+ name: common.navigation.about,
+ href: navigationPaths.find((p) => p.key === 'about')?.path || '/about',
+ },
+ ];
+
+ return (
+
+ {/* Hero Section */}
+
+
+
+ {about.title}
+
+
+ {about.subtitle}
+
+
+
+
+ {/* Company Overview */}
+
+
+ {/* Company Milestones */}
+
+
+ {/* Team Section */}
+
+
+ {/* Certifications */}
+
+
+ );
+}
diff --git a/app/[locale]/layout.tsx b/app/[locale]/layout.tsx
new file mode 100644
index 0000000..4debfc7
--- /dev/null
+++ b/app/[locale]/layout.tsx
@@ -0,0 +1,14 @@
+import { Locale } from '@/lib/i18n';
+
+interface LocaleLayoutProps {
+ children: React.ReactNode;
+ params: {
+ locale: Locale;
+ };
+}
+
+export default function LocaleLayout({ children, params }: LocaleLayoutProps) {
+ // 在动态路由布局中,我们只需要返回children
+ // 语言属性通过generateMetadata在页面级别设置
+ return <>{children}>;
+}
diff --git a/app/[locale]/news/[id]/not-found.tsx b/app/[locale]/news/[id]/not-found.tsx
new file mode 100644
index 0000000..1166bb0
--- /dev/null
+++ b/app/[locale]/news/[id]/not-found.tsx
@@ -0,0 +1,147 @@
+import Link from 'next/link';
+import { getTranslations, Locale, getNavigationPaths } from '@/lib/i18n';
+import Layout from '@/components/Layout';
+
+export default async function NewsNotFound() {
+ // Since we can't access params in not-found.tsx, we'll use the default locale
+ const locale: Locale = 'zh-CN';
+ const common = await getTranslations(locale, 'common');
+ const navigationPaths = getNavigationPaths(locale);
+
+ const navigation = [
+ {
+ name: common.navigation.home,
+ href: navigationPaths.find((p) => p.key === 'home')?.path || '/',
+ },
+ {
+ name: common.navigation.products,
+ href: navigationPaths.find((p) => p.key === 'products')?.path || '/products',
+ },
+ {
+ name: common.navigation.news,
+ href: navigationPaths.find((p) => p.key === 'news')?.path || '/news',
+ },
+ {
+ name: common.navigation.support,
+ href: navigationPaths.find((p) => p.key === 'support')?.path || '/support',
+ },
+ {
+ name: common.navigation.about,
+ href: navigationPaths.find((p) => p.key === 'about')?.path || '/about',
+ },
+ ];
+
+ return (
+
+
+
+
+
+
+
+ 404
+
+
+
+ 文章未找到
+
+
+
+ 抱歉,您请求的新闻文章不存在,或者该文章的当前语言版本尚未提供。
+
+
+
+
+
+ 可能的原因:
+
+
+
+
+
+ •
+
+ 文章链接已过期或不正确
+
+
+
+ •
+
+ 该文章尚未翻译成当前语言
+
+
+
+ •
+
+ 文章已被移除或归档
+
+
+
+
+ p.key === 'news')?.path || '/news'
+ }
+ className="bg-blue-600 text-white px-6 py-3 rounded-lg hover:bg-blue-700 transition-colors font-light"
+ data-oid="c45-.pd"
+ >
+ 返回新闻列表
+
+
+ p.key === 'home')?.path || '/'}
+ className="bg-gray-100 text-gray-700 px-6 py-3 rounded-lg hover:bg-gray-200 transition-colors font-light"
+ data-oid="vzzstbf"
+ >
+ 返回首页
+
+
+
+
+
+
+ 如果您认为这是一个错误,请联系我们的技术支持团队。
+
+
+
+
+
+ );
+}
diff --git a/app/[locale]/news/[id]/page.tsx b/app/[locale]/news/[id]/page.tsx
new file mode 100644
index 0000000..48ba963
--- /dev/null
+++ b/app/[locale]/news/[id]/page.tsx
@@ -0,0 +1,467 @@
+import { notFound } from 'next/navigation';
+import ReactMarkdown from 'react-markdown';
+import remarkGfm from 'remark-gfm';
+import { getTranslations, Locale, getNavigationPaths } from '@/lib/i18n';
+import { generateMetadata as generateSEOMetadata } from '@/lib/seo';
+import { getNewsArticle, getAvailableLocalesForArticle, checkArticleExists } from '@/lib/markdown';
+import Layout from '@/components/Layout';
+import LanguageSwitcher from '@/components/LanguageSwitcher';
+import Link from 'next/link';
+
+interface NewsDetailPageProps {
+ params: {
+ locale: Locale;
+ id: string;
+ };
+}
+
+export async function generateStaticParams() {
+ const locales = ['zh-CN', 'zh-TW', 'en'];
+ const articles = ['ai-transformation-2024', 'cloud-security-best-practices', 'company-expansion-2024'];
+
+ const params = [];
+ for (const locale of locales) {
+ for (const id of articles) {
+ params.push({ locale, id });
+ }
+ }
+ return params;
+}
+
+export async function generateMetadata({ params }: NewsDetailPageProps) {
+ const { locale, id } = params;
+
+ // Check if article exists
+ if (!checkArticleExists(id, locale)) {
+ return {
+ title: 'Article Not Found',
+ description: 'The requested article could not be found.',
+ };
+ }
+
+ const article = await getNewsArticle(id, locale);
+ if (!article) {
+ return {
+ title: 'Article Not Found',
+ description: 'The requested article could not be found.',
+ };
+ }
+
+ return {
+ title: article.title,
+ description: article.excerpt,
+ openGraph: {
+ title: article.title,
+ description: article.excerpt,
+ type: 'article',
+ publishedTime: article.date,
+ authors: [article.author],
+ tags: article.tags,
+ },
+ };
+}
+
+export default async function NewsDetailPage({ params }: NewsDetailPageProps) {
+ const { locale, id } = params;
+
+ // Check if article exists in the requested locale
+ if (!checkArticleExists(id, locale)) {
+ notFound();
+ }
+
+ const article = await getNewsArticle(id, locale);
+ if (!article) {
+ notFound();
+ }
+
+ const [common, availableLocales] = await Promise.all([
+ getTranslations(locale, 'common'),
+ getAvailableLocalesForArticle(id),
+ ]);
+
+ const navigationPaths = getNavigationPaths(locale);
+ const navigation = [
+ {
+ name: common.navigation.home,
+ href: navigationPaths.find((p) => p.key === 'home')?.path || '/',
+ },
+ {
+ name: common.navigation.products,
+ href: navigationPaths.find((p) => p.key === 'products')?.path || '/products',
+ },
+ {
+ name: common.navigation.news,
+ href: navigationPaths.find((p) => p.key === 'news')?.path || '/news',
+ },
+ {
+ name: common.navigation.support,
+ href: navigationPaths.find((p) => p.key === 'support')?.path || '/support',
+ },
+ {
+ name: common.navigation.about,
+ href: navigationPaths.find((p) => p.key === 'about')?.path || '/about',
+ },
+ ];
+
+ return (
+
+ {/* Breadcrumb */}
+
+
+
+ p.key === 'home')?.path || '/'}
+ className="hover:text-blue-600 transition-colors"
+ data-oid="kpvk_7j"
+ >
+ {common.navigation.home}
+
+ /
+ p.key === 'news')?.path || '/news'}
+ className="hover:text-blue-600 transition-colors"
+ data-oid=":-tqwq_"
+ >
+ {common.navigation.news}
+
+ /
+
+ {article.title}
+
+
+
+
+
+ {/* Language Switcher */}
+
+
+
+
+
+ {locale === 'en'
+ ? 'Available in:'
+ : locale === 'zh-TW'
+ ? '可用語言:'
+ : '可用语言:'}
+
+
+
+
+ {/* Back to News */}
+
p.key === 'news')?.path || '/news'}
+ className="text-sm text-blue-600 hover:text-blue-800 flex items-center space-x-1"
+ data-oid="eatue3o"
+ >
+
+
+
+
+ {locale === 'en'
+ ? 'Back to News'
+ : locale === 'zh-TW'
+ ? '返回新聞'
+ : '返回新闻'}
+
+
+
+
+
+
+ {/* Article Header */}
+
+
+
+
+
+ {article.category}
+
+ {article.featured && (
+
+ {locale === 'en'
+ ? 'Featured'
+ : locale === 'zh-TW'
+ ? '精選'
+ : '精选'}
+
+ )}
+
+
+
+ {article.title}
+
+
+
+
+
+
+
+
+
+
{article.author}
+
+
+
+
+
+
+
{article.readTime}
+
+
+
+
+ {article.excerpt}
+
+
+
+ {/* Tags */}
+ {article.tags.length > 0 && (
+
+ {article.tags.map((tag) => (
+
+ #{tag}
+
+ ))}
+
+ )}
+
+
+
+ {/* Article Content */}
+
+
+
+
(
+
+ {children}
+
+ ),
+
+ h2: ({ children }) => (
+
+ {children}
+
+ ),
+
+ h3: ({ children }) => (
+
+ {children}
+
+ ),
+
+ p: ({ children }) => (
+
+ {children}
+
+ ),
+
+ ul: ({ children }) => (
+
+ ),
+
+ ol: ({ children }) => (
+
+ {children}
+
+ ),
+
+ li: ({ children }) => (
+
+ {children}
+
+ ),
+
+ blockquote: ({ children }) => (
+
+ {children}
+
+ ),
+
+ code: ({ children }) => (
+
+ {children}
+
+ ),
+
+ pre: ({ children }) => (
+
+ {children}
+
+ ),
+ }}
+ data-oid="gwxptyo"
+ >
+ {article.content}
+
+
+
+
+
+ {/* Article Footer */}
+
+
+
+
+
+ {locale === 'en'
+ ? 'Published on'
+ : locale === 'zh-TW'
+ ? '發布於'
+ : '发布于'}{' '}
+ {article.date}
+
+
+ {locale === 'en' ? 'By' : locale === 'zh-TW' ? '作者:' : '作者:'}{' '}
+ {article.author}
+
+
+
+
+
+
+
+
+
+ {locale === 'en'
+ ? 'Share'
+ : locale === 'zh-TW'
+ ? '分享'
+ : '分享'}
+
+
+
+
+
+
+
+ );
+}
diff --git a/app/[locale]/news/page.tsx b/app/[locale]/news/page.tsx
new file mode 100644
index 0000000..0701942
--- /dev/null
+++ b/app/[locale]/news/page.tsx
@@ -0,0 +1,380 @@
+import { getTranslations, Locale, getNavigationPaths } from '@/lib/i18n';
+import { generateMetadata as generateSEOMetadata } from '@/lib/seo';
+import Layout from '@/components/Layout';
+import Link from 'next/link';
+
+interface NewsPageProps {
+ params: {
+ locale: Locale;
+ };
+}
+
+export async function generateStaticParams() {
+ const locales = ['zh-CN', 'zh-TW', 'en'];
+ return locales.map((locale) => ({
+ locale,
+ }));
+}
+
+export async function generateMetadata({ params }: NewsPageProps) {
+ return generateSEOMetadata(params.locale, 'news');
+}
+
+export default async function NewsPage({ params }: NewsPageProps) {
+ const { locale } = params;
+ const [common, news] = await Promise.all([
+ getTranslations(locale, 'common'),
+ getTranslations(locale, 'news'),
+ ]);
+
+ const navigationPaths = getNavigationPaths(locale);
+ const navigation = [
+ {
+ name: common.navigation.home,
+ href: navigationPaths.find((p) => p.key === 'home')?.path || '/',
+ },
+ {
+ name: common.navigation.products,
+ href: navigationPaths.find((p) => p.key === 'products')?.path || '/products',
+ },
+ {
+ name: common.navigation.news,
+ href: navigationPaths.find((p) => p.key === 'news')?.path || '/news',
+ },
+ {
+ name: common.navigation.support,
+ href: navigationPaths.find((p) => p.key === 'support')?.path || '/support',
+ },
+ {
+ name: common.navigation.about,
+ href: navigationPaths.find((p) => p.key === 'about')?.path || '/about',
+ },
+ ];
+
+ // Separate featured and regular articles
+ const featuredArticles = news.articles.filter((article: any) => article.featured);
+ const regularArticles = news.articles.filter((article: any) => !article.featured);
+
+ return (
+
+ {/* Hero Section */}
+
+
+
+ {news.title}
+
+
+ {news.subtitle}
+
+
+
+
+ {/* Categories Filter */}
+
+
+
+
+ {locale === 'en' ? 'All' : locale === 'zh-TW' ? '全部' : '全部'}
+
+ {news.categories.map((category: any) => (
+
+ {category.name}
+
+ ))}
+
+
+
+
+ {/* Featured Articles */}
+ {featuredArticles.length > 0 && (
+
+
+
+ {locale === 'en'
+ ? 'Featured Stories'
+ : locale === 'zh-TW'
+ ? '精選報導'
+ : '精选报道'}
+
+
+ {featuredArticles.map((article: any, index: number) => (
+
+ {/* Article Image */}
+
+
+
+
+ {article.category}
+
+
+
+
+ {locale === 'en'
+ ? 'Featured'
+ : locale === 'zh-TW'
+ ? '精選'
+ : '精选'}
+
+
+
+
+
+
+ {article.date}
+ •
+ {article.readTime}
+
+
+
+ {article.title}
+
+
+
+ {article.excerpt}
+
+
+ {news.readMore}
+
+
+
+
+
+
+ ))}
+
+
+
+ )}
+
+ {/* Regular Articles */}
+
+
+
+ {locale === 'en'
+ ? 'Latest News'
+ : locale === 'zh-TW'
+ ? '最新消息'
+ : '最新消息'}
+
+
+ {regularArticles.map((article: any, index: number) => (
+
+
+
+
+
+
+ {article.category}
+
+
+ {article.date}
+
+
+ {article.readTime}
+
+
+
+
+ {article.title}
+
+
+
+ {article.excerpt}
+
+
+
+ {news.readMore}
+
+
+
+
+
+ {locale === 'en'
+ ? 'By'
+ : locale === 'zh-TW'
+ ? '作者:'
+ : '作者:'}{' '}
+ {article.author}
+
+
+
+
+
+ ))}
+
+
+
+
+ {/* Newsletter Subscription */}
+
+
+
+ {locale === 'en'
+ ? 'Stay Updated'
+ : locale === 'zh-TW'
+ ? '保持更新'
+ : '保持更新'}
+
+
+ {locale === 'en'
+ ? 'Subscribe to our newsletter for the latest industry insights and company updates.'
+ : locale === 'zh-TW'
+ ? '訂閱我們的電子報,獲取最新的行業洞察和公司動態。'
+ : '订阅我们的电子报,获取最新的行业洞察和公司动态。'}
+
+
+
+
+
+ {locale === 'en' ? 'Subscribe' : locale === 'zh-TW' ? '訂閱' : '订阅'}
+
+
+
+
+
+ );
+}
diff --git a/app/[locale]/page.tsx b/app/[locale]/page.tsx
new file mode 100644
index 0000000..15ad012
--- /dev/null
+++ b/app/[locale]/page.tsx
@@ -0,0 +1,65 @@
+import { getTranslations, Locale, getNavigationPaths } from '@/lib/i18n';
+import { generateMetadata as generateSEOMetadata } from '@/lib/seo';
+import { getLatestNewsArticles } from '@/lib/markdown';
+import Layout from '@/components/Layout';
+import HomePageClient from '@/components/HomePageClient';
+import HomePageSEO from '@/components/HomePageSEO';
+
+interface HomePageProps {
+ params: {
+ locale: Locale;
+ };
+}
+
+export async function generateStaticParams() {
+ const locales = ['zh-CN', 'zh-TW', 'en'];
+ return locales.map((locale) => ({
+ locale,
+ }));
+}
+
+export async function generateMetadata({ params }: HomePageProps) {
+ return generateSEOMetadata(params.locale, 'home');
+}
+
+export default async function HomePage({ params }: HomePageProps) {
+ const { locale } = params;
+ const [common, home, latestNews] = await Promise.all([
+ getTranslations(locale, 'common'),
+ getTranslations(locale, 'home'),
+ getLatestNewsArticles(locale, 3),
+ ]);
+
+ const navigationPaths = getNavigationPaths(locale);
+ const navigation = [
+ {
+ name: common.navigation.home,
+ href: navigationPaths.find((p) => p.key === 'home')?.path || '/',
+ },
+ {
+ name: common.navigation.products,
+ href: navigationPaths.find((p) => p.key === 'products')?.path || '/products',
+ },
+ {
+ name: common.navigation.news,
+ href: navigationPaths.find((p) => p.key === 'news')?.path || '/news',
+ },
+ {
+ name: common.navigation.support,
+ href: navigationPaths.find((p) => p.key === 'support')?.path || '/support',
+ },
+ {
+ name: common.navigation.about,
+ href: navigationPaths.find((p) => p.key === 'about')?.path || '/about',
+ },
+ ];
+
+ return (
+ <>
+
+
+
+
+ >
+ );
+}
diff --git a/app/[locale]/products/page.tsx b/app/[locale]/products/page.tsx
new file mode 100644
index 0000000..91c44af
--- /dev/null
+++ b/app/[locale]/products/page.tsx
@@ -0,0 +1,266 @@
+import { getTranslations, Locale, getNavigationPaths } from '@/lib/i18n';
+import { generateMetadata as generateSEOMetadata } from '@/lib/seo';
+import Layout from '@/components/Layout';
+
+interface ProductsPageProps {
+ params: {
+ locale: Locale;
+ };
+}
+
+export async function generateStaticParams() {
+ const locales = ['zh-CN', 'zh-TW', 'en'];
+ return locales.map((locale) => ({
+ locale,
+ }));
+}
+
+export async function generateMetadata({ params }: ProductsPageProps) {
+ return generateSEOMetadata(params.locale, 'products');
+}
+
+export default async function ProductsPage({ params }: ProductsPageProps) {
+ const { locale } = params;
+ const [common, products] = await Promise.all([
+ getTranslations(locale, 'common'),
+ getTranslations(locale, 'products'),
+ ]);
+
+ const navigationPaths = getNavigationPaths(locale);
+ const navigation = [
+ {
+ name: common.navigation.home,
+ href: navigationPaths.find((p) => p.key === 'home')?.path || '/',
+ },
+ {
+ name: common.navigation.products,
+ href: navigationPaths.find((p) => p.key === 'products')?.path || '/products',
+ },
+ {
+ name: common.navigation.news,
+ href: navigationPaths.find((p) => p.key === 'news')?.path || '/news',
+ },
+ {
+ name: common.navigation.support,
+ href: navigationPaths.find((p) => p.key === 'support')?.path || '/support',
+ },
+ {
+ name: common.navigation.about,
+ href: navigationPaths.find((p) => p.key === 'about')?.path || '/about',
+ },
+ ];
+
+ return (
+
+ {/* Hero Section */}
+
+
+
+ {products.title}
+
+
+ {products.subtitle}
+
+
+
+
+ {/* Categories Section */}
+
+
+
+
+ {locale === 'en'
+ ? 'Service Categories'
+ : locale === 'zh-TW'
+ ? '服務類別'
+ : '服务类别'}
+
+
+
+ {products.categories.map((category: any, index: number) => (
+
+
+ {category.icon}
+
+
+ {category.name}
+
+
+ {category.description}
+
+
+ ))}
+
+
+
+
+ {/* Products Grid */}
+
+
+
+
+ {locale === 'en'
+ ? 'Our Solutions'
+ : locale === 'zh-TW'
+ ? '我們的解決方案'
+ : '我们的解决方案'}
+
+
+
+ {products.items.map((product: any, index: number) => (
+
+ {/* Product Icon/Image */}
+
+
+ {product.icon || '💼'}
+
+
+
+
+
+ {product.title}
+
+
+ {product.description}
+
+
+ {/* Features */}
+
+
+ {locale === 'en'
+ ? 'Key Features:'
+ : locale === 'zh-TW'
+ ? '主要功能:'
+ : '主要功能:'}
+
+
+ {product.features
+ .slice(0, 4)
+ .map((feature: string, featureIndex: number) => (
+
+ {feature}
+
+ ))}
+ {product.features.length > 4 && (
+
+ +{product.features.length - 4}{' '}
+ {locale === 'en'
+ ? 'more'
+ : locale === 'zh-TW'
+ ? '更多'
+ : '更多'}
+
+ )}
+
+
+
+ {/* CTA Button */}
+
+ {locale === 'en'
+ ? 'Learn More'
+ : locale === 'zh-TW'
+ ? '了解更多'
+ : '了解更多'}
+
+
+
+ ))}
+
+
+
+
+ {/* CTA Section */}
+
+
+
+ {locale === 'en'
+ ? 'Ready to Transform Your Business?'
+ : locale === 'zh-TW'
+ ? '準備好轉型您的業務了嗎?'
+ : '准备好转型您的业务了吗?'}
+
+
+ {locale === 'en'
+ ? 'Contact our experts to discuss your specific needs and get a customized solution.'
+ : locale === 'zh-TW'
+ ? '聯絡我們的專家討論您的具體需求,獲得客製化解決方案。'
+ : '联系我们的专家讨论您的具体需求,获得定制化解决方案。'}
+
+
+
+ {locale === 'en'
+ ? 'Get Started'
+ : locale === 'zh-TW'
+ ? '開始使用'
+ : '开始使用'}
+
+
+ {locale === 'en'
+ ? 'Schedule Consultation'
+ : locale === 'zh-TW'
+ ? '預約諮詢'
+ : '预约咨询'}
+
+
+
+
+
+ );
+}
diff --git a/app/[locale]/support/page.tsx b/app/[locale]/support/page.tsx
new file mode 100644
index 0000000..d28b658
--- /dev/null
+++ b/app/[locale]/support/page.tsx
@@ -0,0 +1,259 @@
+import { getTranslations, Locale, getNavigationPaths } from '@/lib/i18n';
+import { generateMetadata as generateSEOMetadata } from '@/lib/seo';
+import Layout from '@/components/Layout';
+
+interface SupportPageProps {
+ params: {
+ locale: Locale;
+ };
+}
+
+export async function generateStaticParams() {
+ const locales = ['zh-CN', 'zh-TW', 'en'];
+ return locales.map((locale) => ({
+ locale,
+ }));
+}
+
+export async function generateMetadata({ params }: SupportPageProps) {
+ return generateSEOMetadata(params.locale, 'support');
+}
+
+export default async function SupportPage({ params }: SupportPageProps) {
+ const { locale } = params;
+ const [common, support] = await Promise.all([
+ getTranslations(locale, 'common'),
+ getTranslations(locale, 'support'),
+ ]);
+
+ const navigationPaths = getNavigationPaths(locale);
+ const navigation = [
+ {
+ name: common.navigation.home,
+ href: navigationPaths.find((p) => p.key === 'home')?.path || '/',
+ },
+ {
+ name: common.navigation.products,
+ href: navigationPaths.find((p) => p.key === 'products')?.path || '/products',
+ },
+ {
+ name: common.navigation.news,
+ href: navigationPaths.find((p) => p.key === 'news')?.path || '/news',
+ },
+ {
+ name: common.navigation.support,
+ href: navigationPaths.find((p) => p.key === 'support')?.path || '/support',
+ },
+ {
+ name: common.navigation.about,
+ href: navigationPaths.find((p) => p.key === 'about')?.path || '/about',
+ },
+ ];
+
+ return (
+
+ {/* Hero Section */}
+
+
+
+ {support.title}
+
+
+ {support.subtitle}
+
+
+
+
+ {/* Contact Methods */}
+
+
+
+
+ {support.sections.contact.title}
+
+
+ {support.sections.contact.subtitle}
+
+
+
+ {support.sections.contact.methods.map((method: any, index: number) => (
+
+
+ {method.icon}
+
+
+ {method.title}
+
+
+ {method.value}
+
+
+ {method.description}
+
+
+ ))}
+
+
+
+
+ {/* Help Resources */}
+
+
+
+
+ {support.sections.resources.title}
+
+
+ {support.sections.resources.subtitle}
+
+
+
+ {support.sections.resources.items.map((resource: any, index: number) => (
+
+
+ {resource.icon}
+
+
+ {resource.title}
+
+
+ {resource.description}
+
+
+ ))}
+
+
+
+
+ {/* FAQ Section */}
+
+
+
+
+ {support.sections.faq.title}
+
+
+ {support.sections.faq.subtitle}
+
+
+
+ {support.sections.faq.items.map((item: any, index: number) => (
+
+
+
+ Q
+
+ {item.question}
+
+
+
+ ))}
+
+
+
+
+ {/* Contact CTA */}
+
+
+
+ {locale === 'en'
+ ? 'Still Need Help?'
+ : locale === 'zh-TW'
+ ? '仍需要幫助?'
+ : '仍需要帮助?'}
+
+
+ {locale === 'en'
+ ? 'Our support team is ready to assist you with any questions or issues.'
+ : locale === 'zh-TW'
+ ? '我們的支援團隊隨時準備協助您解決任何問題。'
+ : '我们的支持团队随时准备协助您解决任何问题。'}
+
+
+
+ {locale === 'en'
+ ? 'Contact Support'
+ : locale === 'zh-TW'
+ ? '聯絡支援'
+ : '联系支持'}
+
+
+ {locale === 'en'
+ ? 'Schedule Call'
+ : locale === 'zh-TW'
+ ? '預約通話'
+ : '预约通话'}
+
+
+
+
+
+ );
+}
diff --git a/app/[locale]/test-seo/page.tsx b/app/[locale]/test-seo/page.tsx
new file mode 100644
index 0000000..1741e5b
--- /dev/null
+++ b/app/[locale]/test-seo/page.tsx
@@ -0,0 +1,34 @@
+import { Locale } from '@/lib/i18n';
+import { generateMetadata as generateSEOMetadata } from '@/lib/seo';
+
+interface TestSEOPageProps {
+ params: {
+ locale: Locale;
+ };
+}
+
+export async function generateStaticParams() {
+ const locales = ['zh-CN', 'zh-TW', 'en'];
+ return locales.map((locale) => ({
+ locale,
+ }));
+}
+
+export async function generateMetadata({ params }: TestSEOPageProps) {
+ return generateSEOMetadata(params.locale, 'home');
+}
+
+export default function TestSEOPage({ params }: TestSEOPageProps) {
+ const { locale } = params;
+
+ return (
+
+
SEO测试页面 - {locale}
+
检查页面的title、description和keywords是否正确显示
+
+
当前语言: {locale}
+
请查看浏览器标题栏和页面源代码中的meta标签
+
+
+ );
+}
diff --git a/app/about/page.tsx b/app/about/page.tsx
new file mode 100644
index 0000000..0efb8f6
--- /dev/null
+++ b/app/about/page.tsx
@@ -0,0 +1,7 @@
+import { redirect } from 'next/navigation';
+import { defaultLocale } from '@/lib/i18n';
+
+export default function AboutPage() {
+ // Redirect to the localized version
+ redirect(`/${defaultLocale}/about`);
+}
diff --git a/app/favicon.ico b/app/favicon.ico
new file mode 100644
index 0000000000000000000000000000000000000000..08f2470cb3cd949a6a40f833d9bb68411e422116
GIT binary patch
literal 15406
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 {
+ return (
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {children}
+
+ {/* Google Analytics */}
+
+
+
+ {/* AI客服系统 */}
+
+
+ {/* 客服按钮样式强制应用脚本 */}
+