From f6da666d7e0e5a208ee59545bcfd3e2cdac8f438 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E2=80=9Cdongming=E2=80=9D?= <“lidongming@aituringflow.com”> Date: Fri, 19 Dec 2025 20:00:32 +0800 Subject: [PATCH] first commit --- .gitea/workflows/deploy.yml | 154 +++ .gitignore | 157 +++ README.md | 358 +++++ eslint.config.js | 29 + index.html | 15 + package.json | 29 + pnpm-lock.yaml | 2118 ++++++++++++++++++++++++++++++ public/audio/audio.mp3 | Bin 0 -> 1329534 bytes public/img/button-available.png | Bin 0 -> 53325 bytes public/img/button-googleplay.png | Bin 0 -> 38147 bytes public/img/gift.png | Bin 0 -> 5336 bytes public/img/homeimg.png | Bin 0 -> 279095 bytes public/img/iconlogo.png | Bin 0 -> 17901 bytes public/img/particules_medium.png | Bin 0 -> 2765 bytes public/img/particules_small.png | Bin 0 -> 4867 bytes public/img/pic1.jpg | Bin 0 -> 449596 bytes public/img/pic2.jpg | Bin 0 -> 138552 bytes public/img/pic3.jpg | Bin 0 -> 110661 bytes public/img/sep.png | Bin 0 -> 3710386 bytes src/App.jsx | 427 ++++++ src/index.css | 1063 +++++++++++++++ src/main.jsx | 10 + vite.config.js | 12 + 23 files changed, 4372 insertions(+) create mode 100644 .gitea/workflows/deploy.yml create mode 100644 .gitignore create mode 100644 README.md create mode 100644 eslint.config.js create mode 100644 index.html create mode 100644 package.json create mode 100644 pnpm-lock.yaml create mode 100644 public/audio/audio.mp3 create mode 100644 public/img/button-available.png create mode 100644 public/img/button-googleplay.png create mode 100644 public/img/gift.png create mode 100644 public/img/homeimg.png create mode 100644 public/img/iconlogo.png create mode 100644 public/img/particules_medium.png create mode 100644 public/img/particules_small.png create mode 100644 public/img/pic1.jpg create mode 100644 public/img/pic2.jpg create mode 100644 public/img/pic3.jpg create mode 100644 public/img/sep.png create mode 100644 src/App.jsx create mode 100644 src/index.css create mode 100644 src/main.jsx create mode 100644 vite.config.js 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..3f8ef15 --- /dev/null +++ b/README.md @@ -0,0 +1,358 @@ +# turingflow-landing-003 + +圣诞节/节日主题单页落地页,适用于促销活动、节日营销、优惠券发放等场景。 + +## 技术栈 + +- React 19.0.0 (已锁定版本) +- Vite 7.2.4 +- Tailwind CSS 4.1.18 +- Font Awesome 4.7 (图标) +- Google Fonts (Varela, Muli, Great Vibes, Marmelad) + +## 快速开始 + +```bash +pnpm install +pnpm run dev +``` + +开发服务器运行在 `http://localhost:3000` + +## 目录结构 + +```text +turingflow-landing-003/ +├── public/ # 静态资源 +│ ├── img/ # 图片资源 +│ │ ├── iconlogo.png # 导航栏 Logo +│ │ ├── homeimg.png # Header 区域主图 (手机展示图) +│ │ ├── pic1.jpg # Header 背景图 +│ │ ├── pic2.jpg # Contact 区域背景图 +│ │ ├── gift.png # 优惠券礼物图标 +│ │ ├── sep.png # FAQ 分隔符图片 +│ │ ├── button-available.png # App Store 按钮 +│ │ ├── button-googleplay.png # Google Play 按钮 +│ │ ├── particules_medium.png # 雪花粒子 (中) +│ │ └── particules_small.png # 雪花粒子 (小) +│ └── audio/ +│ └── audio.mp3 # 背景音乐 +├── src/ +│ ├── App.jsx # 主应用 (包含所有页面组件) +│ ├── index.css # 全局样式 + 响应式断点 +│ └── main.jsx # 入口文件 +├── index.html # HTML 模板 +├── vite.config.js # Vite 配置 +└── package.json # 依赖配置 +``` + +## 页面结构 + +单页应用,包含以下区域 (从上到下): + +| 区域 | 组件名 | Section ID | 说明 | +|------|--------|------------|------| +| 雪花动画 | `Illustration` | - | 固定背景,雪花下落动画 | +| 导航栏 | `Navbar` | - | 固定顶部,滚动时变色 | +| 头部 | `Header` | `#page-top` | Hero 区域,主标题 + 下载按钮 + 社交图标 | +| 优惠券 | `CouponSection` | `#coupon` | 促销优惠券展示 | +| FAQ | `FAQSection` | `#faq` | 常见问题,两列布局 | +| 联系 | `ContactSection` | `#contact` | 联系表单 | +| 页脚 | `Footer` | - | 版权信息 + 链接 | + +## 组件说明 + +### App.jsx 组件结构 + +```jsx +// 主应用入口 +function App() { + return ( + <> + // 雪花粒子动画背景 + // 固定导航栏 +
// Hero 区域 + // 优惠券区域 + // FAQ 区域 + // 联系表单 +