commit 2a8369ac46a1164e132ee229a03389b4b79df134 Author: “dongming” <“lidongming@aituringflow.com”> Date: Mon Dec 29 11:46:49 2025 +0800 first commit diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml new file mode 100644 index 0000000..4041b5e --- /dev/null +++ b/.gitea/workflows/deploy.yml @@ -0,0 +1,154 @@ +name: Deploy to Cloudflare Pages + +on: + push: + tags: + - 'deploy-*' # 只在推送 deploy-* 标签时触发 + +jobs: + deploy: + runs-on: ubuntu-latest + container: + image: swr.cn-south-1.myhuaweicloud.com/bws/node:20.19.6-bookworm-slim-ci + + steps: + # 1. 拉取代码 + - name: Checkout + uses: actions/checkout@v4 + + # 2. 设置 pnpm(使用 corepack,避免从 GitHub 拉取 action) + - name: Setup pnpm + run: | + corepack enable + corepack prepare pnpm@10.23.0 --activate + pnpm --version + + - name: Parse tag to env + shell: bash + run: | + # 获取 tag 名称(Gitea Actions 使用 GITHUB_REF_NAME) + TAG_NAME="${GITHUB_REF_NAME}" + echo "TAG_NAME=$TAG_NAME" + + # Tag 格式: deploy-{project_name}-{deploymentId_no_dashes} + # 例如: deploy-b7ea026a-cf09-4e31-9f29-b55d7c652b71-123e4567e89b12d3a456426614174000 + + # 去掉 "deploy-" 前缀 + PREFIX="deploy-" + REST="${TAG_NAME#$PREFIX}" + + # deploymentId(无破折号)固定是最后32个字符 + DEPLOYMENT_ID="${REST: -32}" + + # project_name 是剩余部分(去掉最后的 "-" 和 deploymentId) + PROJECT_NAME="${REST%-${DEPLOYMENT_ID}}" + + echo "PROJECT_NAME=$PROJECT_NAME" >> "$GITHUB_ENV" + echo "DEPLOYMENT_ID=$DEPLOYMENT_ID" >> "$GITHUB_ENV" + #echo "DOMAIN=${PROJECT_NAME}-preview.turingflowai.com" >> "$GITHUB_ENV" + + # 调试输出 + echo "Parsed PROJECT_NAME: $PROJECT_NAME" + echo "Parsed DEPLOYMENT_ID: $DEPLOYMENT_ID" + + - name: Check toolchain (debug only, 可选) + run: | + node -v || echo "node not found" + pnpm -v || echo "pnpm not found" + curl --version || echo "curl not found" + + - name: Use CN npm registry + run: | + pnpm config set registry http://repo.myhuaweicloud.com/repository/npm/ + + - name: Install dependencies + run: | + pnpm install --frozen-lockfile + + - name: Build + run: pnpm run build + + - name: Deploy to Cloudflare Pages + shell: bash + env: + CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }} + CLOUDFLARE_API_TOKEN: ${{ secrets.CF_API_TOKEN }} + PROJECT_NAME: ${{ env.PROJECT_NAME }} + DOMAIN: ${{ env.DOMAIN }} + run: | + set -euo pipefail + echo "[deploy] project: $PROJECT_NAME" + #echo "[deploy] domain: $DOMAIN" + + # 部署到 Cloudflare Pages (假定构建产物在 dist/) + # 使用项目本地安装的 wrangler + npx wrangler pages deploy dist \ + --project-name "$PROJECT_NAME" \ + --branch main + + # 绑定自定义域名:-preview.turingflowai.com + #echo "[deploy] 正在绑定自定义域名..." + #DOMAIN_RESPONSE=$(curl -s -w "\n%{http_code}" -X POST \ + # "https://api.cloudflare.com/client/v4/accounts/${CLOUDFLARE_ACCOUNT_ID}/pages/projects/${PROJECT_NAME}/domains" \ + # -H "Authorization: Bearer ${CLOUDFLARE_API_TOKEN}" \ + # -H "Content-Type: application/json" \ + # -d '{"name":"'"${DOMAIN}"'"}') + + #HTTP_CODE=$(echo "$DOMAIN_RESPONSE" | tail -n1) + #RESPONSE_BODY=$(echo "$DOMAIN_RESPONSE" | sed '$d') + + #if [ "$HTTP_CODE" = "200" ] || [ "$HTTP_CODE" = "409" ]; then + # echo "[deploy] 域名绑定成功或已存在 (HTTP $HTTP_CODE)" + #else + # echo "[deploy] 警告: 域名绑定失败 (HTTP $HTTP_CODE)" + # echo "[deploy] 响应: $RESPONSE_BODY" + # echo "[deploy] 继续执行,但域名可能未绑定成功" + #fi + + - name: Notify Deploy Service (success) + if: success() + shell: bash + env: + DEPLOY_SERVICE_CALLBACK_URL: ${{ secrets.DEPLOY_SERVICE_CALLBACK_URL }} + DEPLOY_SERVICE_TOKEN: ${{ secrets.DEPLOY_SERVICE_TOKEN }} + DEPLOYMENT_ID: ${{ env.DEPLOYMENT_ID }} + run: | + set -euo pipefail + + # 获取当前 commit SHA (Gitea Actions 使用 GITHUB_SHA) + COMMIT_SHA="${GITHUB_SHA}" + + curl -X POST "$DEPLOY_SERVICE_CALLBACK_URL" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DEPLOY_SERVICE_TOKEN" \ + -d '{ + "deploymentId": "'"${DEPLOYMENT_ID}"'", + "status": "deployed", + "commitSha": "'"${COMMIT_SHA}"'", + "cfDeploymentId": "", + "errorMessage": null + }' + + - name: Notify Deploy Service (failure) + if: failure() + shell: bash + env: + DEPLOY_SERVICE_CALLBACK_URL: ${{ secrets.DEPLOY_SERVICE_CALLBACK_URL }} + DEPLOY_SERVICE_TOKEN: ${{ secrets.DEPLOY_SERVICE_TOKEN }} + DEPLOYMENT_ID: ${{ env.DEPLOYMENT_ID }} + run: | + set -euo pipefail + + # 获取当前 commit SHA + COMMIT_SHA="${GITHUB_SHA}" + + curl -X POST "$DEPLOY_SERVICE_CALLBACK_URL" \ + -H "Content-Type: application/json" \ + -H "Authorization: Bearer $DEPLOY_SERVICE_TOKEN" \ + -d '{ + "deploymentId": "'"${DEPLOYMENT_ID}"'", + "status": "failed", + "commitSha": "'"${COMMIT_SHA}"'", + "cfDeploymentId": "", + "errorMessage": "see Gitea Actions logs" + }' diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e9e3b4c --- /dev/null +++ b/.gitignore @@ -0,0 +1,157 @@ +# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. + +# =================== +# Dependencies +# =================== +node_modules/ +/.pnp +.pnp.js +.yarn/install-state.gz +.yarn/cache +.yarn/unplugged +.yarn/build-state.yml +.yarn/install-state.gz +package-lock.json +yarn.lock +bun.lockb + +# =================== +# Next.js +# =================== +/.next/ +/out/ +/build/ +.next +out + +# =================== +# Production +# =================== +/dist/ +*.min.js +*.min.css + +# =================== +# Testing +# =================== +/coverage/ +.nyc_output +*.lcov +jest-results.json + +# =================== +# TypeScript +# =================== +*.tsbuildinfo +next-env.d.ts +tsconfig.tsbuildinfo + +# =================== +# Environment Variables +# =================== +.env +.env.* +.env.local +.env.development.local +.env.test.local +.env.production.local +!.env.example + +# =================== +# IDE & Editors +# =================== +.idea/ +.vscode/ +*.swp +*.swo +*.sublime-workspace +*.sublime-project +.project +.classpath +.c9/ +*.launch +.settings/ +*.code-workspace + +# =================== +# OS Generated Files +# =================== +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +Desktop.ini + +# =================== +# Logs +# =================== +logs/ +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +# =================== +# Cache +# =================== +.cache/ +.parcel-cache/ +.eslintcache +.stylelintcache +*.cache +.turbo/ +.tanstack +.pnpm-store + +# =================== +# Vercel +# =================== +.vercel + +# =================== +# Debug +# =================== +*.pem +*.key +*.crt +*.p12 + +# =================== +# Misc +# =================== +*.pid +*.seed +*.pid.lock +*.orig +.temp/ +.tmp/ +tmp/ +temp/ + +# =================== +# Storybook +# =================== +storybook-static/ + +# =================== +# PWA +# =================== +public/sw.js +public/workbox-*.js +public/sw.js.map +public/workbox-*.js.map + +# =================== +# Sentry +# =================== +.sentryclirc + +# =================== +# Docker +# =================== +docker-compose.override.yml diff --git a/README.md b/README.md new file mode 100644 index 0000000..7759b1f --- /dev/null +++ b/README.md @@ -0,0 +1,529 @@ +# turingflow-brand-001 + +企业品牌官网模板,适用于企业官网、商务咨询、金融服务等展示型网站。 + +## 技术栈 + +- React 19.2.3 (已锁定版本,修复 CVE-2025-55182 漏洞) +- Vite 7 (构建工具) +- Tailwind CSS 4 (使用 `@theme` 指令定义主题变量) +- TanStack Router (文件路由,自动代码分割) +- Swiper 11 (轮播组件) +- Font Awesome 4.7 (图标,CDN 引入) + +## 快速开始 + +```bash +pnpm install +pnpm dev +``` + +访问 http://localhost:3000 + +## 目录结构 + +```text +src/ +├── main.tsx # 应用入口,挂载到 #root +├── index.css # 全局样式 + Tailwind @theme 主题变量 +├── routeTree.gen.ts # 自动生成的路由树(勿手动修改) +├── data/ +│ └── siteData.ts # 所有静态数据(菜单、轮播、服务、团队等) +├── routes/ # 页面路由(TanStack Router 文件路由) +│ ├── __root.tsx # 根布局 (Header + Outlet + Footer + ScrollToTop) +│ ├── index.tsx # 首页 / +│ ├── about.tsx # 关于页 /about +│ ├── services.tsx # 服务页 /services +│ └── contact.tsx # 联系页 /contact +├── components/ +│ ├── layout/ # 布局组件 +│ │ ├── Header.tsx # 导航栏 (固定定位,滚动变色,响应式菜单) +│ │ ├── Footer.tsx # 页脚 (4列网格,联系信息,社交链接,订阅表单) +│ │ └── ScrollToTop.tsx # 回到顶部按钮 (滚动>200px显示) +│ ├── shared/ # 共享组件 +│ │ └── Breadcrumb.tsx # 面包屑导航 (props: title, currentPage) +│ ├── home/ # 首页组件 +│ │ ├── HeroSlider.tsx # 全屏轮播 (Swiper, 数据: sliderData) +│ │ ├── Features.tsx # 特性展示 (数据: featuresData) +│ │ ├── Services.tsx # 服务卡片 (数据: servicesData, hover变色) +│ │ ├── CTA.tsx # Call-to-Action 横幅 +│ │ ├── Testimonials.tsx # 客户评价轮播 (数据: testimonialsData) +│ │ ├── Stats.tsx # 统计+服务列表 (数据: statsData, serviceListData) +│ │ └── LatestNews.tsx # 最新文章 (数据: blogData) +│ ├── about/ # 关于页组件 +│ │ ├── Mission.tsx # 使命愿景 (数据: missionVisionData) +│ │ ├── WhyChooseUs.tsx # 为什么选择我们 (数据: whyChooseUsData) +│ │ ├── Statistics.tsx # 统计指标 (数据: aboutStatsData, 渐变背景) +│ │ └── Team.tsx # 团队成员 (数据: teamData, 社交图标hover) +│ ├── services/ # 服务页组件 +│ │ ├── ServiceCards.tsx # 服务卡片 (数据: serviceCardsData, 背景图) +│ │ ├── ProcessSteps.tsx # 流程步骤 (数据: processStepsData, 背景图+渐变叠加) +│ │ └── AdvanceFeatures.tsx # 高级特性 (数据: advanceFeaturesData, 图标卡片) +│ └── contact/ # 联系页组件 +│ ├── ContactForm.tsx # 联系表单 (数据: contactFormInfo) +│ └── Map.tsx # Google 地图嵌入 +└── assets/ + └── images/ # 图片资源 + ├── 1-6.jpg # 轮播/横幅背景图 + ├── g1-12.jpg # 内容区域图片 + ├── c1-3.jpg # 客户头像 + └── team1-4.jpg # 团队成员照片 +``` + +## 路由配置 + +| 路径 | 页面文件 | 包含组件 | +|------|----------|----------| +| `/` | routes/index.tsx | HeroSlider, Features, Services, CTA, Testimonials, Stats, LatestNews | +| `/about` | routes/about.tsx | Breadcrumb, Mission, WhyChooseUs, Statistics, Team | +| `/services` | routes/services.tsx | Breadcrumb, ServiceCards, ProcessSteps, AdvanceFeatures | +| `/contact` | routes/contact.tsx | Breadcrumb, ContactForm, Map | + +## 数据结构 + +所有数据集中在 `src/data/siteData.ts`,便于统一修改。 + +### 导航菜单 + +```typescript +// src/data/siteData.ts +export const menuItems = [ + { name: 'Home', href: '/' }, + { name: 'About', href: '/about' }, + { name: 'Services', href: '/services' }, + { name: 'Contact', href: '/contact' }, +] +``` + +### 轮播数据 + +```typescript +export const sliderData = [ + { + id: 1, + title: 'Check Out Our Latests Tips & Tricks', + buttonText: 'Read More', + buttonLink: '/services', + bgClass: 'bg-slider-1', // 对应 index.css 中的背景类 + }, + // ... +] +``` + +### 服务卡片数据 + +```typescript +export const servicesData = [ + { + id: 1, + icon: 'ravelry', // Font Awesome 图标名 (fa-ravelry) + title: 'Consulting', + description: '...', + }, + // ... +] +``` + +### 团队成员数据 + +```typescript +export const teamData = [ + { + id: 1, + name: 'Micheal Wagou', + role: 'Director', + image: '/src/assets/images/team1.jpg', + social: { + facebook: '#', + twitter: '#', + linkedin: '#', + google: '#', + }, + }, + // ... +] +``` + +### 统计数据 + +```typescript +// 首页统计 +export const statsData = [ + { id: 1, value: 2300, label: 'Clients', suffix: '' }, + // ... +] + +// 关于页统计 (带图标) +export const aboutStatsData = [ + { id: 1, value: 7242, label: 'Hours of Works', icon: 'hourglass' }, + // ... +] +``` + +### 联系信息 + +```typescript +export const contactInfo = { + address: '123 Business Street, Suite 100, New York, NY 10001, USA', + phone: '+1 (555) 123-4567', + email: 'contact@example.com', +} + +export const contactFormInfo = { + title: 'Leave us a Message', + subtitle: '...', + email: 'info@example.com', + address: 'Corporate Office, #32841 block...', + phone: '+121-345-6789', +} +``` + +### 页脚链接 + +```typescript +export const footerLinks = { + featured: [ + { name: 'Our People', href: '/contact' }, + // ... + ], + quick: [ + { name: 'Home', href: '/' }, + // ... + ], +} + +export const socialLinks = [ + { name: 'facebook', href: '#', icon: 'facebook' }, + // ... +] +``` + +## 主题配置 + +主题变量在 `src/index.css` 中使用 Tailwind CSS 4 的 `@theme` 指令定义: + +```css +@theme { + /* 主题色 */ + --color-primary: #2e5deb; /* 主题蓝 - 导航hover、按钮等 */ + --color-secondary: #ff5b83; /* 次要粉红 - 强调色、图标、hover */ + --color-text: #585858; /* 正文灰色 */ + --color-title: #1A1D2D; /* 标题深灰 */ + --color-light-bg: #f6f6f6; /* 浅色背景 */ + --color-services-bg: #f2f8ff; /* 服务区块背景 */ + + /* 字体 */ + --font-family-sans: 'Poppins', sans-serif; /* 标题字体 */ + --font-family-body: 'Hind', sans-serif; /* 正文字体 */ + + /* 阴影 */ + --shadow-card: 0px 9px 24px 5px rgba(0, 0, 0, 0.04); + --shadow-card-hover: 1px 20px 30px rgba(196, 196, 196, 0.2); +} +``` + +在组件中使用: + +```tsx +// Tailwind 类名直接使用 +
+

+

+``` + +## 组件说明 + +### Header (src/components/layout/Header.tsx) + +- 固定定位 `fixed top-0` +- 滚动时背景变为白色 (`scrolled` 状态) +- 响应式汉堡菜单 (移动端) +- 搜索弹窗功能 +- 使用 `menuItems` 数据 + +### Footer (src/components/layout/Footer.tsx) + +- 4 列网格布局 +- 使用 `contactInfo`, `footerLinks`, `socialLinks` 数据 +- 订阅表单 (`.subscribe` 样式类) + +### HeroSlider (src/components/home/HeroSlider.tsx) + +- Swiper 轮播组件 +- 配置:自动播放(5秒)、淡入淡出效果、导航箭头、分页点 +- 背景图通过 `bgClass` 指定 CSS 类 + +```tsx + +``` + +### Services (src/components/home/Services.tsx) + +- 4 列服务卡片网格 +- hover 时背景变为 secondary 色,文字变白 +- 图标使用 Font Awesome 4.7 (通过 CDN) +- **注意**:图标大小使用内联样式 `style={{ fontSize: '36px' }}` + +### Statistics (src/components/about/Statistics.tsx) + +- 渐变背景 `linear-gradient(100deg, #2e5deb 10%, #5360fd 50%, #ff5b83 100%)` +- 数字计数动画 (IntersectionObserver 触发) +- 图标使用 Font Awesome,内联样式设置大小 + +### Team (src/components/about/Team.tsx) + +- 团队成员卡片 +- 社交图标:粉色方形按钮 `bg-secondary hover:bg-primary rounded` +- hover 时变蓝 + +### ProcessSteps (src/components/services/ProcessSteps.tsx) + +- 背景图 + 深色渐变叠加层 +- 步骤数字:粉色圆形徽章 `bg-secondary rounded-full` + +### AdvanceFeatures (src/components/services/AdvanceFeatures.tsx) + +- 浅灰色背景 `bg-light-bg` +- 图标容器:55x55px 粉色圆角方形 + +### Breadcrumb (src/components/shared/Breadcrumb.tsx) + +```tsx + +``` + +- 背景图在 `index.css` 中定义 (`.breadcrum-bg`) + +## 常见修改任务 + +### 修改网站名称/Logo + +```tsx +// src/components/layout/Header.tsx (约第30行) + + Finance Ideas + + +// src/components/layout/Footer.tsx (约第20行) + + Finance Ideas + +``` + +### 修改导航菜单 + +```typescript +// src/data/siteData.ts (第1-7行) +export const menuItems = [ + { name: 'Home', href: '/' }, + { name: 'About', href: '/about' }, + // 添加或修改菜单项... +] +``` + +### 修改主题色 + +```css +/* src/index.css (第4-10行) */ +@theme { + --color-primary: #新蓝色; + --color-secondary: #新粉色; +} +``` + +### 修改轮播内容 + +```typescript +// src/data/siteData.ts (第9-39行) +export const sliderData = [ + { + id: 1, + title: '新标题', + buttonText: '新按钮文字', + buttonLink: '/新链接', + bgClass: 'bg-slider-1', + }, +] +``` + +### 修改轮播背景图 + +```css +/* src/index.css - 需要添加背景类 */ +.bg-slider-1 { + background: url('/src/assets/images/新图片.jpg'); + background-size: cover; + background-position: center; +} +``` + +### 修改团队成员 + +```typescript +// src/data/siteData.ts (第177-226行) +export const teamData = [ + { + id: 1, + name: '新姓名', + role: '新职位', + image: '/src/assets/images/team1.jpg', + social: { facebook: '#', twitter: '#', linkedin: '#', google: '#' }, + }, +] +``` + +### 修改联系信息 + +```typescript +// src/data/siteData.ts (第303-316行) +export const contactInfo = { + address: '新地址', + phone: '新电话', + email: '新邮箱', +} +``` + +### 添加新页面 + +1. 在 `src/routes/` 创建新文件: + +```tsx +// src/routes/newpage.tsx +import { createFileRoute } from '@tanstack/react-router' +import Breadcrumb from '../components/shared/Breadcrumb' + +export const Route = createFileRoute('/newpage')({ + component: NewPage, +}) + +function NewPage() { + return ( + <> + +

+
+ {/* 页面内容 */} +
+
+ + ) +} +``` + +2. 添加导航项: + +```typescript +// src/data/siteData.ts +export const menuItems = [ + // ... + { name: 'New Page', href: '/newpage' }, +] +``` + +3. 运行 `pnpm dev` 自动生成路由 + +### 修改服务卡片图标 + +图标使用 Font Awesome 4.7,图标名称参考:https://fontawesome.com/v4/icons/ + +```typescript +// src/data/siteData.ts (第58-83行) +export const servicesData = [ + { + id: 1, + icon: 'ravelry', // 改为其他图标名,如 'rocket', 'cogs' 等 + title: 'Consulting', + description: '...', + }, +] +``` + +## 样式说明 + +### 背景图类 (src/index.css) + +| 类名 | 用途 | 图片 | +|------|------|------| +| `ser-bg1` | 服务卡片背景1 | g1.jpg + 暗色遮罩 | +| `ser-bg2` | 服务卡片背景2 | g2.jpg + 暗色遮罩 | +| `ser-bg3` | 服务卡片背景3 | g4.jpg + 暗色遮罩 | +| `breadcrum-bg` | 面包屑背景 | 6.jpg + 暗色遮罩 | + +### 动画类 + +| 类名 | 效果 | +|------|------| +| `zoom` | 图片 hover 放大 1.1x | +| `icon-scroll` | 滚动鼠标指示动画 | + +### 表单类 + +| 类名 | 用途 | +|------|------| +| `contact-input` | 联系表单输入框 | +| `subscribe` | 订阅表单容器 | +| `btn-theme2` | 次要按钮样式 | + +## 图标说明 + +项目使用 Font Awesome 4.7.0 (CDN),在 `index.html` 中引入: + +```html + +``` + +使用方式: + +```tsx +