8000 GitHub - amostsai/petshop: 寵物店網站範例,適合學習網站全端開發與容器化部署 · GitHub
[go: up one dir, main page]

Skip to content
amostsaiPublic

About

寵物店網站範例,適合學習網站全端開發與容器化部署

Resources

Stars

3 stars

Watchers

0 watching

Forks

Latest commit

 

History

17 Commits

Folders and files

Repository files navigation

毛孩樂園寵物店範例網站

本專案是一個以 Flask + MySQL + Nginx + Docker Compose 打造的寵物店網站範例,適合學習網站全端開發與容器化部署。


注意事項

本網站圖片都是從網路上隨機取得,教學使用 根據本範例修改爲其他商業網站,請記得更換圖片!


專案技術架構

[使用者瀏覽器]
        │
        ▼
    [Nginx]  ← 靜態檔案(圖片、CSS、JS)
        │
        ▼
    [Flask (app.py)]
        │
        ▼
    [MySQL 資料庫]
  • Nginx:反向代理,負責接收外部請求,將 API 請求轉發給 Flask,並直接提供靜態檔案(/static)。
  • Flask:Python Web 框架,負責處理動態頁面、路由、表單、資料庫互動。
  • MySQL:關聯式資料庫,儲存網站資料(最新消息、服務、聯絡表單等)。
  • Docker Compose:一鍵啟動所有服務,並用 volume 掛載本機程式碼,方便開發與同步。

下載與執行步驟

  1. 下載專案

    git clone git@github.com:amostsai/petshop.git
    cd petshop
  2. 準備 Docker Secrets

    • 編輯 secrets/ 目錄內的三個檔案:
      • mysql_root_password.txt
      • mysql_user_password.txt
      • flask_secret_key.txt
    • 將內容改成自己的安全密碼/金鑰。範例值僅供教學使用。
  3. 啟動服務

    docker compose up
    • 第一次啟動會自動建立資料庫與 seed 假資料。
    • 預設網站入口:http://localhost
  4. 關閉服務

    docker compose down
  5. 若修改靜態檔案(html, css, js, jpg, png, gif等檔案)

    docker compose down
    docker compose up

目錄結構說明

petshop/
├── app/                  # Flask 主程式
│   ├── __init__.py       # 匯出 create_app 供 flask run 使用
│   ├── app.py            # Flask application factory + feature 註冊
│   ├── config.py         # 分環境設定與秘密讀取邏輯
│   ├── features/         # 依網站功能分組的模組
│   │   ├── main/         # 首頁
│   │   ├── news/         # 最新消息
│   │   ├── contact/      # 聯絡我們
│   │   ├── services/     # 服務介紹
│   │   └── about/        # 關於我們
│   ├── lib/              # 共用工具(資料庫、快取、錯誤類別等)
│   ├── static/           # 靜態檔案(CSS, JS, 圖片)
│   └── templates/        # 共用模板(如 base.html)
├── env/
│   ├── flask/            # Dockerfile
│   ├── mysql/            # 資料庫初始化 SQL
│   └── nginx/            # Nginx 設定
├── docker-compose.yml    # 一鍵啟動所有服務
└── README.md             # 專案說明
  • 每個 feature 資料夾集中該功能所需的 Blueprint (__init__.py)、路由 (routes.py)、服務與資料存取層(視需求提供 service.py、repository.py)、以及對應模板 (templates/)。

學習重點

  • Blueprint 分層:如何將不同功能模組化,方便維護與擴充。
  • 資料庫連線:如何用 Python 連接 MySQL,並安全寫入資料。
  • 表單處理:前端驗證 + 後端驗證 + 資料寫入 DB。
  • 靜態檔案與模板:Nginx 如何直接服務 /static,Flask 如何渲染 Jinja2 模板。
  • Docker volume:程式碼即時同步到 container,開發方便。
  • 一鍵啟動:用 docker compose up 即可啟動所有服務。

商品販售體驗

  • /products 顯示商品分類、列表與詳細頁,可將有庫存的商品加入購物車。
  • 購物車支援調整數量、移除商品與查看訂單摘要,並在導覽列顯示件數徽章。
  • 結帳流程會寫入訂單與明細至 MySQL,並導向綠界測試付款頁。付款完成後可回到感謝頁查看訂單編號與付款狀態。

綠界測試金流

本專案預設使用綠界 ECPay STAGE 測試環境:

  • 付款網址:https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5
  • 測試 MerchantID:3002607
  • 測試 HashKey / HashIV 已在開發設定中提供,可用環境變數覆寫。

可用環境變數:

ECPAY_CHECKOUT_URL=https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5
ECPAY_MERCHANT_ID=3002607
ECPAY_HASH_KEY=你的 HashKey
ECPAY_HASH_IV=你的 HashIV
ECPAY_RETURN_URL=https://你的公開網址/cart/ecpay/return
ECPAY_CLIENT_BACK_URL=https://你的公開網址/cart/thank-you/訂單編號

注意:綠界付款完成後會由綠界伺服器呼叫 ECPAY_RETURN_URL。本機 Docker 的 localhost 無法被綠界連到;若要測試訂單自動更新為 paid,請使用 ngrok 或其他公開測試網址,例如:

ECPAY_RETURN_URL=https://example.ngrok-free.app/cart/ecpay/return docker compose up

若服務已經在執行,設定公開 callback 後需要重建 Flask container 讓環境變數進入容器:

ECPAY_RETURN_URL=https://example.ngrok-free.app/cart/ecpay/return docker compose up -d --force-recreate flask
docker compose exec flask env | grep ECPAY_RETURN_URL

付款後若平台仍顯示待付款,先確認 Flask log 是否有收到綠界 callback:

docker compose logs --tail=200 flask | grep /cart/ecpay/return

如果沒有任何 /cart/ecpay/return 紀錄,代表綠界沒有成功打到平台,通常是 ECPAY_RETURN_URL 沒有設定成公開網址、沒有傳進 container,或 ngrok/防火牆沒有轉到本機服務。

完成公開 callback smoke test 後,再封存 OpenSpec 任務:

  1. 用 ngrok 或公開測試網址設定 ECPAY_RETURN_URL=https://.../cart/ecpay/return。

  2. 完成一次綠界測試付款。

  3. 確認該訂單的 payment_status 變成 paid。

  4. 勾選 openspec/changes/add-ecpay-test-payment/tasks.md 的 2.3 Smoke test checkout in Docker with an externally reachable callback URL。

  5. 執行封存並驗證:

    openspec archive add-ecpay-test-payment --yes
    openspec validate --strict

目前此 OpenSpec change 先保留在 active changes,避免在公開 callback 驗證完成前封存。

若你是在既有 MySQL volume 上加入此功能,env/mysql/init.sql 不會自動重新套用。可選擇重建資料庫:

docker compose down -v
docker compose up

或手動補上訂單付款欄位:

ALTER TABLE orders
  ADD COLUMN payment_status ENUM('pending','paid','failed') NOT NULL DEFAULT 'pending' AFTER total_amount,
  ADD COLUMN ecpay_trade_no VARCHAR(20) NULL AFTER payment_status,
  ADD COLUMN ecpay_payment_type VARCHAR(20) NULL AFTER ecpay_trade_no,
  ADD COLUMN ecpay_payment_date DATETIME NULL AFTER ecpay_payment_type,
  ADD COLUMN ecpay_return_code VARCHAR(10) NULL AFTER ecpay_payment_date,
  ADD COLUMN ecpay_return_message VARCHAR(255) NULL AFTER ecpay_return_code;

測試指南

  • 安裝相依套件後可在專案根目錄執行 pytest,預設會載入 APP_ENV=testing 的 Flask 設定。
  • 測試使用 fixtures 模擬資料庫回傳值與購物車狀態,不需要啟動 MySQL 或額外 seeding。
  • 若要觀察重新導向流程,可加上 -s 或 --maxfail=1 輕鬆除錯。
  • 亦可透過 Docker 執行:docker compose --profile test run --rm pytest(或 COMPOSE_PROFILES=test docker compose run --rm pytest),會使用 testing 組態並在容器內跑完整測試。

後台訂單管理

後台入口:/admin/orders

預設開發帳密:

ADMIN_USERNAME=admin
ADMIN_PASSWORD=admin

可透過環境變數或 Docker secret 覆寫。正式環境請務必更換預設密碼。

後台目前提供:

  • 訂單列表與付款狀態篩選:pending、paid、failed、cancelled
  • 訂單詳情:顧客資訊、取貨方式、備註、商品明細、總金額、綠界交易資訊
  • 本地取消:可將 pending 或 failed 訂單標記為 cancelled

注意:目前取消只是站內狀態,不會呼叫綠界退款或取消 API。若訂單已標記為 cancelled,後續晚到的綠界 callback 不會自動把狀態改成 paid。

若你是在既有 MySQL volume 上加入後台取消狀態,需讓 orders.payment_status 支援 cancelled:

ALTER TABLE orders
  MODIFY COLUMN payment_status ENUM('pending','paid','failed','cancelled') NOT NULL DEFAULT 'pending';

進階練習建議

  • 嘗試新增一個「留言板」功能,練習 blueprint、資料庫設計、模板渲染。
  • 修改 Nginx 設定,體驗靜態檔案快取。

About

寵物店網站範例,適合學習網站全端開發與容器化部署

Resources

Stars

3 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

0