# 高雄天氣預報系統
> 一個即時、美觀、響應式的天氣預報 Web 應用程式,串接中央氣象署(CWA)開放資料平台,提供高雄市 36 小時天氣預報。
## 專案定位
**目標使用者**:高雄市民、觀光客、需要即時天氣資訊的使用者
**核心價值**:
- ✅ **即時準確**:直接串接 CWA 官方 API,提供最新天氣預報資料
- ✅ **直觀易讀**:卡片式設計搭配天氣圖示,快速掌握未來天氣變化
- ✅ **響應式設計**:支援桌面/平板/手機裝置,隨時隨地查看天氣
- ✅ **自動更新**:每 10 分鐘自動刷新資料,確保資訊即時性
- ✅ **輕量化架構**:前端使用 Vanilla JS、後端使用 Express,部署簡單快速
---
## 網站大綱
```mermaid
flowchart TD
A[首頁<br/>高雄天氣預報] --> B[載入中狀態<br/>Spinner]
A --> C[錯誤狀態<br/>重新載入按鈕]
A --> D[天氣卡片列表<br/>3 時段預報]
D --> D1[時段 1<br/>早上/下午/晚上/凌晨]
D --> D2[時段 2<br/>含時間範圍]
D --> D3[時段 3<br/>顯示天氣圖示]
D1 --> E[天氣資訊]
E --> E1[☀️ 天氣狀況]
E --> E2[🌡️ 溫度範圍]
E --> E3[💧 降雨機率]
E --> E4[😊 舒適度]
E --> E5[💨 風速]
```
---
## 系統架構圖
```mermaid
flowchart LR
subgraph Frontend["前端 Frontend"]
A[index.html|前端入口]
B[script.js|API 客戶端]
C[styles.css|樣式表]
end
subgraph Backend["後端 Backend"]
D[server.js|Express 入口]
E[weather.js|路由層]
F[weatherController.js|控制器]
G[.env|環境變數]
H[package.json|專案設定]
end
subgraph External["外部服務 External"]
I[CWA API|中央氣象署]
end
A -->|"載入"| B
A -->|"載入"| C
B -->|"GET /api/weather/kaohsiung|取得高雄天氣"| D
D -->|"使用路由"| E
D -->|"讀取配置"| G
E -->|"呼叫控制器"| F
F -->|"讀取 API Key"| G
F -->|"axios GET|請求天氣資料"| I
H -->|"定義依賴"| D
```
---
## 快速開始
### 前置需求
- Node.js >= 14.x
- npm 或 pnpm
- CWA API Key(至 [氣象資料開放平臺](https://opendata.cwa.gov.tw/) 申請)
### 安裝步驟
#### 1. 克隆專案
```bash
git clone <repository-url>
cd weather
```
#### 2. 安裝後端依賴
```bash
cd backend
npm install
```
#### 3. 設定環境變數
```bash
cp .env.example .env
```
編輯 `backend/.env`,填入您的 CWA API Key:
```env
CWA_API_KEY=your_actual_api_key_here
PORT=3000
NODE_ENV=development
```
#### 4. 啟動後端服務
**開發模式(支援熱重載)**:
```bash
npm run dev
```
**生產模式**:
```bash
npm start
```
後端服務將運行在 `http://localhost:3000`
#### 5. 啟動前端
前端為靜態檔案,可使用以下任一方式:
**方法 A:使用 VS Code Live Server**
1. 安裝 Live Server 擴充套件
2. 右鍵點擊 `frontend/index.html`
3. 選擇 "Open with Live Server"
**方法 B:使用 Python HTTP Server**
```bash
cd frontend
python3 -m http.server 8080
```
**方法 C:使用 Node.js http-server**
```bash
npx http-server frontend -p 8080
```
前端將運行在 `http://localhost:8080`(視使用工具而定)
### Docker 部署(TODO)
> **目前專案尚未提供 Docker 配置**,建議新增以下檔案:
```dockerfile
# 建議 Dockerfile 結構
FROM node:18-alpine
WORKDIR /app
COPY backend/package*.json ./
RUN npm ci --only=production
COPY backend/ ./
EXPOSE 3000
CMD ["node", "server.js"]
```
```yaml
# 建議 docker-compose.yml
version: '3.8'
services:
backend:
build: ./backend
ports:
- "3000:3000"
env_file:
- ./backend/.env
frontend:
image: nginx:alpine
volumes:
- ./frontend:/usr/share/nginx/html:ro
ports:
- "80:80"
```
---
## 環境變數
### 環境變數表格
| 變數名稱 | 用途 | 是否必填 | 預設值 | 說明 |
|---------|------|---------|--------|------|
| `CWA_API_KEY` | 中央氣象署 API 授權碼 | ✅ 必填 | 無 | 至 [opendata.cwa.gov.tw](https://opendata.cwa.gov.tw/) 申請 |
| `PORT` | 後端伺服器監聽埠號 | ❌ 選填 | `3000` | Express 服務埠號 |
| `NODE_ENV` | 執行環境標識 | ❌ 選填 | `development` | `development` 或 `production` |
### `.env.example`
```bash
# ========================================
# CWA 氣象資料開放平臺 API 設定
# ========================================
# 請至 https://opendata.cwa.gov.tw/ 申請授權碼
# 路徑:會員專區 → 取得授權碼
CWA_API_KEY=your_cwa_api_key_here
# ========================================
# 伺服器設定
# ========================================
# 後端 Express 服務埠號
PORT=3000
# 執行環境(development | production)
NODE_ENV=development
```
---
## 資料夾結構
```
weather/
├── frontend/ # 前端靜態網頁
│ ├── index.html # 主頁面|DOM 結構與 SEO meta
│ ├── script.js # API 客戶端|Fetch 呼叫與 DOM 渲染邏輯
│ └── styles.css # 樣式表|RWD 響應式設計、卡片動畫
│
└── backend/ # 後端 API 服務
├── server.js # Express 入口|CORS/路由註冊/錯誤處理
├── routes/
│ └── weather.js # 路由層|定義 /api/weather/* 端點
├── controllers/
│ └── weatherController.js # 控制器|呼叫 CWA API、資料轉換
├── .env # 環境變數(不納入版控)
├── .env.example # 環境變數範本
├── .gitignore # Git 忽略規則
├── package.json # 專案設定與依賴管理
└── README.md # 後端說明文件
```
### 關鍵檔案說明
| 檔案路徑 | 角色 | 說明 |
|---------|------|------|
| **`frontend/index.html`** | 前端入口 | 包含載入狀態、錯誤狀態、天氣卡片容器的 DOM 結構 |
| **`frontend/script.js`** | API 客戶端 | 呼叫 `/api/weather/kaohsiung`、處理回應、DOM 渲染、10 分鐘自動輪詢 |
| **`frontend/styles.css`** | 樣式表 | Grid 佈局、卡片 hover 效果、響應式斷點、天氣圖示樣式 |
| **`backend/server.js`** | Express 入口 | 中介軟體設定(CORS/JSON 解析)、路由註冊、錯誤處理 |
| **`backend/routes/weather.js`** | 路由層 | 定義 `GET /api/weather/kaohsiung` 端點 |
| **`backend/controllers/weatherController.js`** | 控制器 | 呼叫 CWA API (`F-C0032-001`)、解析天氣要素(Wx/PoP/MinT/MaxT/CI/WS) |
---
## 常用指令
### 後端指令
| 指令 | 說明 | 來源 |
|------|------|------|
| `npm install` | 安裝專案依賴 | `backend/package.json` |
| `npm start` | 啟動生產環境伺服器 | `backend/package.json` |
| `npm run dev` | 啟動開發環境(nodemon 熱重載) | `backend/package.json` |
### 前端指令
前端為靜態檔案,無需安裝依賴。可使用以下工具啟動:
```bash
# 使用 Python
python3 -m http.server 8080
# 使用 Node.js http-server
npx http-server frontend -p 8080
# 使用 VS Code Live Server 擴充套件
```
---
## API 與資料模型概觀
### 後端 API 端點
| 方法 | 路徑 | 說明 | 回應格式 |
|------|------|------|---------|
| `GET` | `/` | API 首頁|顯示可用端點 | JSON |
| `GET` | `/api/health` | 健康檢查|伺服器狀態 | `{ status: "OK", timestamp: "..." }` |
| `GET` | `/api/weather/kaohsiung` | 取得高雄市 36 小時天氣預報 | 見下方資料模型 |
### 天氣預報資料模型
**請求範例**:
```http
GET /api/weather/kaohsiung
```
**回應範例**:
```json
{
"success": true,
"data": {
"city": "高雄市",
"updateTime": "2025 年 9 月 30 日下午 05:00 更新",
"forecasts": [
{
"startTime": "2025-09-30 18:00:00",
"endTime": "2025-10-01 06:00:00",
"weather": "多雲時晴",
"rain": "10%",
"minTemp": "25°C",
"maxTemp": "32°C",
"comfort": "悶熱",
"windSpeed": "偏南風 3-4 級"
},
{
"startTime": "2025-10-01 06:00:00",
"endTime": "2025-10-01 18:00:00",
"weather": "晴時多雲",
"rain": "0%",
"minTemp": "26°C",
"maxTemp": "34°C",
"comfort": "悶熱",
"windSpeed": "偏南風 2-3 級"
},
{
"startTime": "2025-10-01 18:00:00",
"endTime": "2025-10-02 06:00:00",
"weather": "多雲",
"rain": "20%",
"minTemp": "25°C",
"maxTemp": "31°C",
"comfort": "悶熱",
"windSpeed": "偏南風 3-4 級"
}
]
}
}
```
### 外部 API 依賴
| 服務名稱 | 用途 | API 文件 |
|---------|------|---------|
| **CWA 氣象資料開放平臺** | 取得台灣天氣預報資料 | [opendata.cwa.gov.tw](https://opendata.cwa.gov.tw/dist/opendata-swagger.html) |
| 使用資料集 | F-C0032-001(一般天氣預報-今明 36 小時) | [API 文件](https://opendata.cwa.gov.tw/dist/opendata-swagger.html#/%E9%A0%90%E5%A0%B1/get_v1_rest_datastore_F_C0032_001) |
**TODO**: 目前專案未提供 OpenAPI (Swagger) 規格檔案,建議新增 `backend/openapi.yaml`。
---
## 部署與 CI/CD
### 當前部署狀態
✅ **已部署**:後端服務已部署至 Zeabur
- 部署 URL: `https://weather-backend.zeabur.app`
- 前端 API 端點: `https://weather-backend.zeabur.app/api/weather/kaohsiung`
### 部署建議
#### Zeabur 部署(後端)
1. 前往 [Zeabur](https://zeabur.com/)
2. 連接 GitHub 儲存庫
3. 選擇 `backend` 資料夾作為根目錄
4. 設定環境變數(`CWA_API_KEY`)
5. 部署完成後將獲得公開 URL
#### Vercel 部署(前端)
```bash
# 安裝 Vercel CLI
npm i -g vercel
# 部署前端
cd frontend
vercel --prod
```
或直接在 Vercel Dashboard 連接 GitHub 儲存庫,指定 `frontend` 資料夾。
#### Netlify 部署(前端)
1. 前往 [Netlify](https://www.netlify.com/)
2. 連接 GitHub 儲存庫
3. 設定建置參數:
- Base directory: `frontend`
- Publish directory: `.`(因為是靜態檔案)
4. 部署完成
### CI/CD 流程(建議)
**TODO**: 目前專案缺少 CI/CD 配置,建議新增以下檔案:
```yaml
name: Deploy
on:
push:
branches: [main]
jobs:
deploy-backend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: cd backend && npm ci
- run: cd backend && npm test # TODO: 需新增測試
- name: Deploy to Zeabur
run: echo "TODO: 整合 Zeabur CLI"
deploy-frontend:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Deploy to Vercel
run: npx vercel --prod --token=${{ secrets.VERCEL_TOKEN }}
```
### 環境需求
| 環境 | Node.js 版本 | 用途 |
|------|-------------|------|
| Development | >= 14.x | 本地開發與測試 |
| Production | >= 18.x (推薦) | 生產環境部署 |
---
## 技術債務與改進方向
- [ ] **測試覆蓋率**:新增 Jest/Vitest 單元測試與 Playwright E2E 測試
- [ ] **快取機制**:實作 Redis 或記憶體快取,減少 CWA API 呼叫次數
- [ ] **錯誤監控**:整合 Sentry 或 LogRocket
- [ ] **Docker 化**:新增 Dockerfile 與 docker-compose.yml
- [ ] **CI/CD**:建立 GitHub Actions 自動化部署流程
- [ ] **OpenAPI 文件**:自動生成 API 文件(Swagger UI)
- [ ] **多城市支援**:擴充為全台灣天氣預報
- [ ] **PWA 支援**:新增 Service Worker 實現離線功能
---
## 授權
MIT License
---
## 聯絡方式
如有問題或建議,歡迎透過以下方式聯繫:
- 提交 Issue
- 發送 Pull Request
- Email: [待補充]