- 追蹤 ID 存 site_settings(空字串即關閉),於 /admin/settings 管理 - Base.astro 僅在用戶同意後載入分析工具,未同意前零請求 - 新增 /privacy 私隱政策頁與「重設 Cookie 偏好」按鈕 - 前台 SSR 頁面(首頁、blog、about、privacy)傳入 gaId / metaPixelId - seed 加入預設空值,Footer 加入私隱政策連結 - 同步更新 AGENTS.md 與 README 說明
151 lines
6.3 KiB
Markdown
151 lines
6.3 KiB
Markdown
# 盈豐太陽能工程有限公司 — 官網(村屋太陽能)
|
||
|
||
**Astro 7 + React 19 + Chakra UI v3 + Cloudflare Workers + D1 + KV + R2 + Drizzle。全部部署喺 Cloudflare,零維運。**
|
||
|
||
一頁式官網(村屋太陽能)+ Blog + 內容管理後台。
|
||
|
||
## 功能
|
||
|
||
- **一頁式官網** `/`(SSR,讀 D1):Hero、服務、特色、流程、完成案例、FAQ、聯絡 CTA
|
||
- **Blog** `/blog`、`/blog/[slug]`:封面卡片列表 + Markdown 文章頁
|
||
- **後台** `/admin`(密碼登入):管理文章、首頁內容(服務/特色/流程/FAQ)、完成案例、網站設定(公司資料/聯絡/Hero/SEO)
|
||
- **AI 生成 Blog** `/admin/ai`:設定 AI 供應商、維護關鍵字佇列,一按生成完整草稿(DeepSeek 相容 API,可選 Tavily 上網研究)
|
||
- **SEO**:canonical、OG/Twitter card、`/sitemap.xml`、`/robots.txt`、結構化語意 HTML
|
||
- 首頁/Blog 用邊緣快取(`s-maxage`),後台改完約 1 分鐘內生效
|
||
|
||
## 技術棧
|
||
|
||
| 層 | 選用 |
|
||
|---|---|
|
||
| 前端框架 | Astro 7(`output: "static"` + per-page SSR) |
|
||
| UI | React 19 + `@chakra-ui/react` v3 + `@emotion/react`(editorial 極簡 theme:暖米白底、琥珀金 accent) |
|
||
| Adapter | `@astrojs/cloudflare`(一個 Worker) |
|
||
| DB | Cloudflare D1(SQLite) |
|
||
| ORM | Drizzle |
|
||
| 物件儲存 | Cloudflare R2(後台圖片上傳,binding `MEDIA`) |
|
||
| Auth | HMAC-signed cookie(`src/lib/auth.ts`) |
|
||
| Markdown | `marked` |
|
||
| Icons | `lucide-react` |
|
||
|
||
> Chakra v3 用 Emotion,SSR 會輸出 inline critical CSS(首屏即有樣式、零 FOUC),client hydrate 後整合到 `<head>`;已實測 Astro 7 + React 19 無 hydration error。
|
||
|
||
## 本機開發
|
||
|
||
```bash
|
||
npm install
|
||
|
||
# 建本機 D1 + 套 migration
|
||
npm run db:migrate:local
|
||
|
||
# 匯入種子資料(同 migration 分開,可重複執行)
|
||
npm run db:seed:local
|
||
|
||
# 開發 server(:4321)
|
||
npm run dev
|
||
```
|
||
|
||
本機後台密碼喺 `.dev.vars`(`ADMIN_PASSWORD=changeme-local`,已 gitignore)。
|
||
|
||
想模擬 production(wrangler):`npm run preview`。
|
||
|
||
## 部署到 Cloudflare
|
||
|
||
### 1. 先設定網址(部署前一定要做)
|
||
|
||
`sitemap` / `canonical` / `OG` 全部靠 `astro.config.mjs` 嘅 `site`,所以**先改佢**:
|
||
|
||
```js
|
||
// astro.config.mjs
|
||
site: "https://your-domain.com",
|
||
```
|
||
|
||
想用 Cloudflare 自訂網域(例如 `solar.develop-cat.com`)就順手喺 `wrangler.jsonc` 加:
|
||
|
||
```jsonc
|
||
"routes": [
|
||
{ "pattern": "solar.develop-cat.com", "custom_domain": true }
|
||
],
|
||
```
|
||
|
||
部署時會自動建立 DNS + TLS,唔使自己開 record。唔加就淨係用 `https://<worker-name>.<account>.workers.dev`;亦可以部署後喺 Dashboard → Worker → Settings → Domains & Routes 手動加。
|
||
|
||
### 2. 首次設定(一鍵)
|
||
|
||
```bash
|
||
npm run login # 瀏覽器授權
|
||
npm run setup # 建 D1 / KV / R2、寫入 wrangler.jsonc 嘅 id、設 secret、可選 migration + seed + build + deploy
|
||
```
|
||
|
||
`npm run setup` 會逐步問你:設定後台密碼?套 migration/seed?build + deploy?若 `site` 仍係 `https://example.com`,會跳過 build + deploy 並提醒你改(改完再 `npm run deploy`)。
|
||
|
||
### 3. 之後更新
|
||
|
||
```bash
|
||
npm run deploy # = npm run build + wrangler deploy
|
||
```
|
||
|
||
### Git push 自動部署(Cloudflare Workers Builds)
|
||
|
||
1. Cloudflare Dashboard → Workers & Pages → 連接 GitHub repo
|
||
2. Build command:`npm run build`
|
||
3. Deploy command:`npx wrangler deploy`
|
||
4. 喺 Dashboard 設 secrets:`ADMIN_PASSWORD`、`AI_API_KEY`、`TAVILY_API_KEY`
|
||
|
||
**Migration 唔會喺 CI 自動執行**:改完 `src/db/schema.ts` 要手動跑
|
||
`npm run db:generate` → `npm run db:migrate`(雲端)→ `npm run db:seed`(如有新 seed)。
|
||
`seed.sql` 放喺 `scripts/`(唔可以放喺 `migrations/`,否則 `db:migrate` 會連 seed 一齊種)。
|
||
|
||
## AI 生成 Blog
|
||
|
||
後台 `/admin/ai`:
|
||
|
||
- 設定 AI 供應商(OpenAI 相容 Base URL + 模型)、寫作風格、公司背景
|
||
- 維護關鍵字佇列(新增 / 略過 / 刪除)
|
||
- 「生成草稿」= 自由輸入主題;「生成下一篇」= 攞佇列下一個 pending
|
||
- 生成係同步進行(約 10–40 秒),完成後一律存為**草稿**並跳去文章編輯頁覆核
|
||
- 需要 secret:`AI_API_KEY`(必需)、`TAVILY_API_KEY`(如開上網研究)
|
||
|
||
## 後台點用
|
||
|
||
1. 去 `/admin`,輸入密碼登入
|
||
2. **內容總覽** → 服務 / 特色 / 流程 / 常見問題 / 完成案例 / 網站設定 / AI 生成
|
||
3. 每個項目可新增、修改、刪除、用 ↑↓ 排序、「已發布 / 草稿」控制前台顯示
|
||
4. 圖片:可揀檔即時上傳去 R2(瀏覽器端先縮圖轉 WebP),亦可貼圖片 URL
|
||
5. **AI 生成**:設定供應商同關鍵字佇列,生成草稿後去文章編輯頁覆核發布
|
||
|
||
## 結構
|
||
|
||
```
|
||
src/
|
||
├─ theme/system.ts Chakra theme(tokens / 顏色 / 字體)
|
||
├─ components/site/*.tsx 前台 React 元件(Header/Hero/Services/Faq…)
|
||
├─ data/
|
||
│ ├─ content.ts D1 讀取 + WhatsApp/電話 link helper
|
||
│ └─ settings-fields.ts 後台設定欄位定義
|
||
├─ db/schema.ts Drizzle schema(posts / site_settings / content_items / cases / blog_keywords)
|
||
├─ schemas/ Zod 驗證 schema(表單輸入 + AI 輸出)
|
||
├─ layouts/Base.astro SEO head + fonts
|
||
├─ layouts/AdminLayout.astro 後台外框
|
||
├─ pages/
|
||
│ ├─ index.astro SSR 首頁
|
||
│ ├─ about.astro 關於(靜態)
|
||
│ ├─ blog/… Blog
|
||
│ ├─ admin/… 後台(含 admin/ai、admin/upload 上傳 endpoint)
|
||
│ ├─ media/[...key].ts R2 圖片出圖 endpoint
|
||
│ └─ sitemap.xml.ts / robots.txt.ts
|
||
├─ components/admin/ImageField.astro 後台圖片欄(URL + 上傳 + 預覽)
|
||
├─ lib/{auth,db,env,form,media,ai,markdown,schema-org}.ts
|
||
migrations/
|
||
├─ 0000_init.sql … Drizzle migrations
|
||
scripts/
|
||
├─ setup.mjs 一鍵 Cloudflare provision
|
||
└─ seed.sql 種子資料(用 db:seed 另外執行,唔可以放喺 migrations/)
|
||
```
|
||
|
||
## 待客戶提供(可喺 `/admin/settings` 自行更新)
|
||
|
||
- 真實電話 / WhatsApp / Email / 地址
|
||
- 電業承辦商牌照號碼
|
||
- 真域名(`astro.config.mjs` 嘅 `site`)
|
||
- 真實工程相片(現時用佔位圖)
|