# 路由模組重構說明 ## 概述 此目錄包含從 `app.py` 中分離出來的路由模組,採用 Flask Blueprint 架構。 這樣的模組化設計使得代碼更易於維護、測試和擴展。 ## 模組清單 | 模組 | 狀態 | 說明 | 路由 | |------|------|------|------| | `system_routes.py` | ✅ 獨立 | 系統管理 | `/settings`, `/logs`, `/health`, `/metrics`, `/api/backup` 等 | | `edm_routes.py` | ✅ 獨立 | EDM 儀表板 | `/edm`, `/festival` | | `monthly_routes.py` | ✅ 獨立 | 月結分析 | `/monthly_summary_analysis`, `/api/monthly_summary_data` | | `dashboard_routes.py` | ✅ 獨立 | 首頁看板 | `/`, `/brand_assets` | | `daily_sales_routes.py` | ✅ 獨立 | 當日業績 | `/daily_sales`, `/daily_sales/export*` | | `api_routes.py` | ✅ 已獨立 | 通用 API | `/api/run_task`, `/api/history/*` 等 | | `export_routes.py` | ✅ 已獨立 | 匯出功能 | `/api/export/*` | | `import_routes.py` | ✅ 已獨立 | 匯入功能 | `/api/import_excel`, `/api/import/monthly_summary` | | `sales_routes.py` | ⚡ 延遲導入 | 業績分析 | `/sales_analysis`, `/growth_analysis`, `/api/sales_analysis/*` | ## 啟用模組 ### 方法一:修改 config.py(推薦) 在 `config.py` 中設定 `USE_MODULAR_ROUTES`: ```python USE_MODULAR_ROUTES = { 'system': True, # 啟用 system_routes 'edm': True, # 啟用 edm_routes 'monthly': True, # 啟用 monthly_routes 'dashboard': True, # 啟用 dashboard_routes 'daily_sales': True, # 啟用 daily_sales_routes 'api': False, # api_routes 有依賴,暫不啟用 'export': False, # export_routes 有依賴,暫不啟用 'import': False, # import_routes 有依賴,暫不啟用 'sales': False, # sales_routes 有依賴,暫不啟用 } ``` ### 方法二:環境變數 可透過環境變數覆蓋設定(待實作)。 ## 運作原理 1. **Blueprint 註冊**:`routes/__init__.py` 中的 `register_blueprints()` 函數根據 `USE_MODULAR_ROUTES` 設定決定是否註冊各模組的 Blueprint。 2. **重複路由清理**:`app.py` 底部的 `cleanup_duplicate_routes()` 函數會在所有路由定義完成後,移除與已啟用 Blueprint 重複的路由。 3. **優先順序**:Blueprint 中的路由優先於 app.py 中的同名路由。 ## 模組依賴說明 ### 完全獨立模組 - `system_routes.py` - `edm_routes.py` - `monthly_routes.py` - `dashboard_routes.py` - 提供 `get_consolidated_data`, `get_dashboard_stats` - `daily_sales_routes.py` 這些模組不依賴 app.py 中的任何函數或變數。 ### 已獨立化的模組(使用 services 或其他獨立模組) - `api_routes.py`: - 使用 `services/task_runner.py` 中的 `run_momo_task_with_notification` - 使用 `routes/dashboard_routes.py` 中的 `get_dashboard_stats` - `export_routes.py`: - 使用 `routes/dashboard_routes.py` 中的 `get_consolidated_data` - 使用 `services/cache_service.py` 中的快取變數 - `import_routes.py`: - 使用 `services/cache_service.py` 中的 `_SALES_DF_CACHE`, `_SALES_PROCESSED_CACHE` ### 延遲導入模組 - `sales_routes.py`: - `growth_analysis()` 已完全獨立 - 其他 API 函數使用延遲導入從 app.py 取得(函數邏輯複雜,暫不遷移) ## 開發指南 ### 新增路由模組 1. 在 `routes/` 目錄建立新的 Python 檔案 2. 定義 Blueprint: ```python from flask import Blueprint my_bp = Blueprint('my_module', __name__) ``` 3. 在 `routes/__init__.py` 中加入註冊邏輯 4. 在 `config.py` 的 `USE_MODULAR_ROUTES` 中加入控制項 ### 從 app.py 遷移路由 1. 複製路由函數到對應模組 2. 將 `@app.route` 改為 `@blueprint_name.route` 3. 確認所有導入正確 4. 測試模組可正常導入:`python -c "from routes.xxx import xxx_bp"` 5. 在 `MODULAR_ENDPOINTS` 中記錄端點名稱 ## 測試 測試模組是否正常運作: ```bash # 測試所有模組導入 python -c " from routes.system_routes import system_bp from routes.edm_routes import edm_bp from routes.monthly_routes import monthly_bp from routes.dashboard_routes import dashboard_bp from routes.daily_sales_routes import daily_sales_bp print('All independent modules imported successfully!') " # 測試完整應用(啟用所有獨立模組) python -c " import config config.USE_MODULAR_ROUTES = { 'system': True, 'edm': True, 'monthly': True, 'dashboard': True, 'daily_sales': True, 'api': False, 'export': False, 'import': False, 'sales': False } import app print(f'Total routes: {len(list(app.app.url_map.iter_rules()))}') " ``` ## 已知問題 ### 模板 url_for 端點名稱問題 當啟用模組化路由時,端點名稱會從 `'index'` 變為 `'dashboard.index'`。 這會導致模板中的 `url_for('index')` 調用失敗。 **影響範圍**: - `index.html` 中的 `url_for('index', ...)` - `edm_dashboard.html` 中的 `url_for('edm_dashboard', ...)` **解決方案**(需在啟用模組前執行): 1. 在模板中使用完整的端點名稱,如 `url_for('dashboard.index', ...)` 2. 或在 app.py 中加入端點別名 **注意**:目前預設所有模組皆禁用(`USE_MODULAR_ROUTES` 全為 False), 因此不會影響正常使用。此問題只會在手動啟用模組後出現。 ## 變更歷史 - **2026-01-18**: - 初始版本,建立 9 個路由模組,5 個獨立模組可直接啟用 - 修復 url_for 端點名稱問題,新增 `register_endpoint_aliases()` 函數 - 處理有依賴的模組 (api, export, import),使用獨立 services 模組 - 新增 `services/task_runner.py` 封裝爬蟲任務執行邏輯 - 所有 9 個模組已啟用並通過測試