- 建立 Gitea Actions CD pipeline (.gitea/workflows/cd.yaml) - 部署模式: rsync Python 檔案至 188 → docker restart (volume mount) - Dockerfile/requirements 變動時自動重建 Docker image - 部署通知: Telegram (開始/成功/失敗) - 健康檢查: https://mo.wooo.work/health (最多 5 次重試) - 同步最新 CLAUDE.md / ADR-008 / memory (2026-04-19) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
13 KiB
Superset 功能實作指南
本指南詳細說明如何在 Superset 中複製現有頁面的分析功能 建立日期: 2026-02-08
存取資訊
| 項目 | 值 |
|---|---|
| URL | https://monitor.wooo.work/superset/ |
| 帳號 | admin |
| 密碼 | Wooo_Superset_2026 |
| 資料庫 | MOMO_UAT |
已建立的資料集
| 資料集 | 資料表 | 用途 |
|---|---|---|
| daily_sales_snapshot | public.daily_sales_snapshot | 當日業績 |
| realtime_sales_monthly | public.realtime_sales_monthly | 銷售分析、成長分析 |
| monthly_summary_analysis | public.monthly_summary_analysis | 月度總結 |
| products | public.products | 商品資料、ABC 分析 |
| price_records | public.price_records | 價格趨勢 |
第一部分:當日業績 (Daily Sales)
對應頁面: /daily_sales
1.1 SQL Lab 建立虛擬資料集
在 SQL Lab 執行以下查詢,然後儲存為資料集:
-- 資料集名稱: daily_sales_kpi
-- 用途: 每日 KPI 彙總
SELECT
snapshot_date,
DATE_TRUNC('month', snapshot_date) as month,
EXTRACT(DOW FROM snapshot_date) as day_of_week,
COUNT(DISTINCT "商品代碼") as sku_count,
SUM("銷售金額") as total_revenue,
SUM("總成本") as total_cost,
SUM("銷售金額") - SUM("總成本") as gross_margin,
SUM("銷售數量") as total_qty,
CASE
WHEN SUM("銷售金額") > 0
THEN (SUM("銷售金額") - SUM("總成本")) / SUM("銷售金額") * 100
ELSE 0
END as margin_rate,
CASE
WHEN SUM("銷售數量") > 0
THEN SUM("銷售金額") / SUM("銷售數量")
ELSE 0
END as avg_price
FROM daily_sales_snapshot
GROUP BY snapshot_date
ORDER BY snapshot_date DESC
1.2 建議圖表
| 圖表名稱 | 類型 | 說明 |
|---|---|---|
| 當日業績 Big Number | Big Number with Trendline | 顯示最新日期的 total_revenue |
| 當日毛利 Big Number | Big Number with Trendline | 顯示最新日期的 gross_margin |
| 30 天業績趨勢 | Line Chart | X軸: snapshot_date, Y軸: total_revenue |
| DoD 比較 | Bar Chart | 比較今日與昨日 |
| WoW 比較 | Bar Chart | 比較今日與上週同日 |
| 分類業績圓餅圖 | Pie Chart | 依商品分類分組 |
| 日曆熱力圖 | Calendar Heatmap | 每日業績視覺化 |
1.3 建立步驟
- SQL Lab → 執行上述 SQL
- 點擊 Save → Save Dataset
- 命名為
daily_sales_kpi - 前往 Charts → + Chart
- 選擇
daily_sales_kpi資料集 - 依序建立各圖表
第二部分:銷售分析 (Sales Analysis)
對應頁面: /sales_analysis
2.1 SQL Lab 建立虛擬資料集
-- 資料集名稱: sales_analysis_detail
-- 用途: 銷售明細分析
SELECT
"日期" as order_date,
"商品名稱" as product_name,
"商品代碼" as product_code,
"館別" as category,
"品牌" as brand,
"廠商名稱" as vendor,
"總業績" as amount,
"總成本" as cost,
"總業績" - "總成本" as profit,
"銷量" as qty,
CASE
WHEN "總業績" > 0
THEN ("總業績" - "總成本") / "總業績" * 100
ELSE 0
END as margin_rate,
EXTRACT(DOW FROM "日期"::date) as day_of_week,
EXTRACT(HOUR FROM "訂單時間"::time) as order_hour,
DATE_TRUNC('month', "日期"::date) as month,
DATE_TRUNC('week', "日期"::date) as week
FROM realtime_sales_monthly
WHERE "日期" IS NOT NULL
2.2 建議圖表
| 圖表名稱 | 類型 | 設定 |
|---|---|---|
| 總業績 KPI | Big Number | SUM(amount) |
| 總毛利 KPI | Big Number | SUM(profit) |
| 毛利率 KPI | Big Number | AVG(margin_rate) |
| 業績 TOP 20 商品 | Bar Chart (Horizontal) | GROUP BY product_name, ORDER BY SUM(amount) DESC LIMIT 20 |
| 分類業績分佈 | Pie Chart | GROUP BY category |
| 品牌業績排行 | Bar Chart | GROUP BY brand |
| 廠商業績排行 | Bar Chart | GROUP BY vendor |
| 星期銷售熱力圖 | Heatmap | X: day_of_week, Y: order_hour, Value: SUM(amount) |
| 月度趨勢 | Line Chart | X: month, Y: SUM(amount) |
| 週趨勢 | Line Chart | X: week, Y: SUM(amount) |
| 價格區間分佈 | Histogram | amount 分佈 |
| BCG 矩陣 | Scatter Plot | X: SUM(qty), Y: margin_rate, Size: SUM(amount) |
| 樹狀圖 | Treemap | 分類 → 品牌 階層 |
2.3 篩選器設定
建立以下 Filter Box:
- 日期範圍 (order_date)
- 分類 (category)
- 品牌 (brand)
- 廠商 (vendor)
- 星期 (day_of_week)
- 時段 (order_hour)
第三部分:成長分析 (Growth Analysis)
對應頁面: /growth_analysis
3.1 SQL Lab 建立虛擬資料集
-- 資料集名稱: growth_analysis_monthly
-- 用途: 月度成長分析 (MoM, YoY, AOV)
WITH monthly_data AS (
SELECT
DATE_TRUNC('month', "日期"::date) as month,
SUM("總業績") as revenue,
SUM("總成本") as cost,
SUM("總業績") - SUM("總成本") as profit,
COUNT(DISTINCT "訂單編號") as orders
FROM realtime_sales_monthly
WHERE "日期" IS NOT NULL
GROUP BY DATE_TRUNC('month', "日期"::date)
),
with_growth AS (
SELECT
month,
revenue,
profit,
orders,
revenue / NULLIF(orders, 0) as aov,
profit / NULLIF(revenue, 0) * 100 as margin_rate,
-- MoM (月增率)
(revenue - LAG(revenue) OVER (ORDER BY month)) /
NULLIF(LAG(revenue) OVER (ORDER BY month), 0) * 100 as mom,
-- YoY (年增率)
(revenue - LAG(revenue, 12) OVER (ORDER BY month)) /
NULLIF(LAG(revenue, 12) OVER (ORDER BY month), 0) * 100 as yoy
FROM monthly_data
)
SELECT
month,
revenue,
profit,
orders,
ROUND(aov::numeric, 0) as aov,
ROUND(margin_rate::numeric, 1) as margin_rate,
COALESCE(ROUND(mom::numeric, 2), 0) as mom,
COALESCE(ROUND(yoy::numeric, 2), 0) as yoy
FROM with_growth
ORDER BY month DESC
3.2 建議圖表
| 圖表名稱 | 類型 | 說明 |
|---|---|---|
| YTD 業績 | Big Number | 今年累計業績 |
| YTD 成長率 | Big Number | 與去年同期比較 |
| 近 30 天客單價 | Big Number | 最近客單價 |
| 月度業績趨勢 | Line Chart | X: month, Y: revenue |
| 月度毛利趨勢 | Line Chart | X: month, Y: profit |
| MoM 月增率 | Bar Chart | X: month, Y: mom (紅/綠顏色區分正負) |
| YoY 年增率 | Bar Chart | X: month, Y: yoy |
| 客單價趨勢 | Line Chart | X: month, Y: aov |
| 毛利率趨勢 | Line Chart | X: month, Y: margin_rate |
| 綜合指標雙軸圖 | Mixed Chart | 左軸: revenue, 右軸: margin_rate |
第四部分:月度總結 (Monthly Summary)
對應頁面: /monthly_summary_analysis
4.1 使用現有資料集
直接使用 monthly_summary_analysis 資料集。
4.2 建議圖表
| 圖表名稱 | 類型 | 說明 |
|---|---|---|
| 本月業績 | Big Number | 最新月份的業績 |
| 月度業績比較 | Bar Chart | 12 個月業績對比 |
| 月環比 | Line Chart | MoM 變化 |
| 月度彙總表 | Pivot Table | 月份 x 各項指標 |
| 季度彙總 | Bar Chart | 依季度分組 |
第五部分:ABC 分析
對應頁面: /abc_analysis/detail
5.1 SQL Lab 建立虛擬資料集
-- 資料集名稱: abc_analysis
-- 用途: 商品 ABC 分類
WITH product_sales AS (
SELECT
p.i_code,
p.name as product_name,
p.category,
COALESCE(SUM(d."銷售金額"), 0) as total_sales,
COALESCE(SUM(d."銷售數量"), 0) as total_qty
FROM products p
LEFT JOIN daily_sales_snapshot d ON p.i_code = d."商品代碼"
GROUP BY p.i_code, p.name, p.category
HAVING COALESCE(SUM(d."銷售金額"), 0) > 0
),
ranked AS (
SELECT
*,
SUM(total_sales) OVER (ORDER BY total_sales DESC) as cumulative_sales,
SUM(total_sales) OVER () as grand_total,
ROW_NUMBER() OVER (ORDER BY total_sales DESC) as rank
FROM product_sales
)
SELECT
i_code,
product_name,
category,
total_sales,
total_qty,
cumulative_sales,
grand_total,
rank,
cumulative_sales / grand_total * 100 as cumulative_pct,
CASE
WHEN cumulative_sales / grand_total <= 0.7 THEN 'A'
WHEN cumulative_sales / grand_total <= 0.9 THEN 'B'
ELSE 'C'
END as abc_class
FROM ranked
ORDER BY rank
5.2 建議圖表
| 圖表名稱 | 類型 | 說明 |
|---|---|---|
| ABC 分類圓餅圖 | Pie Chart | GROUP BY abc_class |
| ABC 分類商品數 | Bar Chart | COUNT BY abc_class |
| 帕累托曲線 | Dual Axis Line | 銷售額 + 累計百分比 |
| A 類商品列表 | Table | FILTER abc_class = 'A' |
| B 類商品列表 | Table | FILTER abc_class = 'B' |
| C 類商品列表 | Table | FILTER abc_class = 'C' |
| 分類 ABC 分佈 | Stacked Bar | X: category, Y: COUNT, Color: abc_class |
第六部分:價格趨勢
對應頁面: 商品看板價格歷史
6.1 使用現有資料集
直接使用 price_records 資料集。
6.2 建議圖表
| 圖表名稱 | 類型 | 說明 |
|---|---|---|
| 價格歷史折線圖 | Line Chart | X: timestamp, Y: current_price, Filter: product_id |
| 今日價格變動 | Table | WHERE DATE(timestamp) = CURRENT_DATE |
| 漲價商品數 | Big Number | COUNT WHERE price_change > 0 |
| 降價商品數 | Big Number | COUNT WHERE price_change < 0 |
| 價格變動分佈 | Histogram | price_change_pct 分佈 |
儀表板建立順序
建議順序(由簡到繁)
- 成長分析儀表板 - 圖表較少,資料結構簡單
- 月度總結儀表板 - 使用現有資料集
- 當日業績儀表板 - 需要 DoD/WoW 計算
- 銷售分析儀表板 - 圖表最多,篩選器複雜
- ABC 分析儀表板 - 需要進階 SQL
- 價格趨勢儀表板 - 需要時間序列處理
驗證對照表
每個儀表板建立完成後,請與現有頁面比對以下項目:
| 驗證項目 | 檢查點 |
|---|---|
| 數據一致性 | KPI 數值是否與現有頁面一致 |
| 圖表呈現 | 圖表類型是否適當呈現資料 |
| 篩選功能 | 篩選器是否正常運作 |
| 效能 | 載入時間是否可接受 |
| 互動性 | 點擊鑽取是否正常 |
常用 Superset 操作
建立圖表快速步驟
- Charts → + Chart
- 選擇資料集
- 選擇圖表類型
- 設定 Metrics (指標) 和 Dimensions (維度)
- 設定篩選條件
- Run Query 預覽
- Save 儲存
建立儀表板
- Dashboards → + Dashboard
- 輸入名稱
- Edit Dashboard
- 從右側拖曳圖表
- 調整佈局
- 新增篩選器
- Save
設定篩選器
- 在儀表板編輯模式
- 點擊 + Add filter
- 選擇欄位和類型
- 設定影響的圖表
注意事項
- 欄位名稱: PostgreSQL 區分大小寫,中文欄位需用雙引號包起來
- 日期格式: 確保日期欄位正確轉換為 DATE 類型
- 效能: 大資料集建議加入時間篩選限制
- 快取: Superset 有快取機制,測試時可能需要清除快取
故障排除
頁面無限載入 (Infinite Loading)
症狀: 訪問 Superset 頁面時,畫面顯示無限載入中
原因: Superset Docker 映像 (3.1.0/3.1.1) 中的 theme.5ab95322dc4a489d8e8f.entry.js 檔案大小為 0 bytes (映像構建問題)
解決方案: 已在 docker-compose.yml 的啟動命令中自動修復:
echo '(function(){console.log("Theme loaded");})();' > /app/superset/static/assets/theme.5ab95322dc4a489d8e8f.entry.js
手動修復 (如果需要):
docker exec momo-superset sh -c 'echo "(function(){console.log(\"Theme loaded\");})();" > /app/superset/static/assets/theme.5ab95322dc4a489d8e8f.entry.js'
子路徑 404 錯誤
症狀: 訪問 /superset/ 返回 404
原因: Nginx 子路徑配置需要特別處理 URL 重寫
解決方案: 參考 nginx-superset.conf 配置,關鍵設定:
proxy_redirect / /superset/;- 重寫重定向sub_filter- 重寫 HTML 中的靜態資源路徑gzip off;- 禁用 gzip 讓 sub_filter 生效
雙重前綴問題 (/superset/superset/) (2026-02-08 修復)
症狀:
- 訪問
https://monitor.wooo.work/superset/被重定向到/superset/superset/welcome/ - 頁面無限載入
根本原因:
Superset 內部 Flask blueprints 路由已經是 /superset/...(例如 /superset/welcome/)。
如果 Nginx 使用 proxy_redirect / /superset/;,會把 /superset/welcome/ 再次加前綴變成 /superset/superset/welcome/。
解決方案:
- superset_config.py - 禁用 x_prefix:
ENABLE_PROXY_FIX = True
PROXY_FIX_CONFIG = {
"x_for": 1,
"x_proto": 1,
"x_host": 1,
"x_prefix": 0, # 必須為 0!
}
- Nginx 配置 - 智能 proxy_redirect:
location /superset/ {
proxy_pass http://127.0.0.1:8088/;
# 關鍵:已是 /superset/ 開頭的路徑保持不變
proxy_redirect /superset/ /superset/;
# 其他路徑才添加 /superset/ 前綴
proxy_redirect ~^/(?!superset)(.*)$ /superset/$1;
# 只重寫 static 路徑
sub_filter '"/static/' '"/superset/static/';
sub_filter "'/static/" "'/superset/static/";
sub_filter_once off;
}
- 驗證:
# 應該返回 302 到 /superset/welcome/ (不是 /superset/superset/welcome/)
curl -sI https://monitor.wooo.work/superset/ | grep -i location