467 lines
13 KiB
Markdown
467 lines
13 KiB
Markdown
# Superset 功能實作指南
|
||
|
||
> 本指南詳細說明如何在 Superset 中複製現有頁面的分析功能
|
||
> 建立日期: 2026-02-08
|
||
|
||
---
|
||
|
||
## 存取資訊
|
||
|
||
| 項目 | 值 |
|
||
|------|-----|
|
||
| URL | https://monitor.wooo.work/superset/ |
|
||
| 帳號 | admin |
|
||
| 密碼 | <SUPERSET_ADMIN_PASSWORD> |
|
||
| 資料庫 | 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 執行以下查詢,然後儲存為資料集:
|
||
|
||
```sql
|
||
-- 資料集名稱: 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 建立步驟
|
||
|
||
1. **SQL Lab** → 執行上述 SQL
|
||
2. 點擊 **Save** → **Save Dataset**
|
||
3. 命名為 `daily_sales_kpi`
|
||
4. 前往 **Charts** → **+ Chart**
|
||
5. 選擇 `daily_sales_kpi` 資料集
|
||
6. 依序建立各圖表
|
||
|
||
---
|
||
|
||
## 第二部分:銷售分析 (Sales Analysis)
|
||
|
||
**對應頁面**: `/sales_analysis`
|
||
|
||
### 2.1 SQL Lab 建立虛擬資料集
|
||
|
||
```sql
|
||
-- 資料集名稱: 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 建立虛擬資料集
|
||
|
||
```sql
|
||
-- 資料集名稱: 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 建立虛擬資料集
|
||
|
||
```sql
|
||
-- 資料集名稱: 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 分佈 |
|
||
|
||
---
|
||
|
||
## 儀表板建立順序
|
||
|
||
### 建議順序(由簡到繁)
|
||
|
||
1. **成長分析儀表板** - 圖表較少,資料結構簡單
|
||
2. **月度總結儀表板** - 使用現有資料集
|
||
3. **當日業績儀表板** - 需要 DoD/WoW 計算
|
||
4. **銷售分析儀表板** - 圖表最多,篩選器複雜
|
||
5. **ABC 分析儀表板** - 需要進階 SQL
|
||
6. **價格趨勢儀表板** - 需要時間序列處理
|
||
|
||
---
|
||
|
||
## 驗證對照表
|
||
|
||
每個儀表板建立完成後,請與現有頁面比對以下項目:
|
||
|
||
| 驗證項目 | 檢查點 |
|
||
|----------|--------|
|
||
| 數據一致性 | KPI 數值是否與現有頁面一致 |
|
||
| 圖表呈現 | 圖表類型是否適當呈現資料 |
|
||
| 篩選功能 | 篩選器是否正常運作 |
|
||
| 效能 | 載入時間是否可接受 |
|
||
| 互動性 | 點擊鑽取是否正常 |
|
||
|
||
---
|
||
|
||
## 常用 Superset 操作
|
||
|
||
### 建立圖表快速步驟
|
||
|
||
1. **Charts** → **+ Chart**
|
||
2. 選擇資料集
|
||
3. 選擇圖表類型
|
||
4. 設定 Metrics (指標) 和 Dimensions (維度)
|
||
5. 設定篩選條件
|
||
6. **Run Query** 預覽
|
||
7. **Save** 儲存
|
||
|
||
### 建立儀表板
|
||
|
||
1. **Dashboards** → **+ Dashboard**
|
||
2. 輸入名稱
|
||
3. **Edit Dashboard**
|
||
4. 從右側拖曳圖表
|
||
5. 調整佈局
|
||
6. 新增篩選器
|
||
7. **Save**
|
||
|
||
### 設定篩選器
|
||
|
||
1. 在儀表板編輯模式
|
||
2. 點擊 **+ Add filter**
|
||
3. 選擇欄位和類型
|
||
4. 設定影響的圖表
|
||
|
||
---
|
||
|
||
## 注意事項
|
||
|
||
1. **欄位名稱**: PostgreSQL 區分大小寫,中文欄位需用雙引號包起來
|
||
2. **日期格式**: 確保日期欄位正確轉換為 DATE 類型
|
||
3. **效能**: 大資料集建議加入時間篩選限制
|
||
4. **快取**: Superset 有快取機制,測試時可能需要清除快取
|
||
|
||
---
|
||
|
||
## 故障排除
|
||
|
||
### 頁面無限載入 (Infinite Loading)
|
||
|
||
**症狀**: 訪問 Superset 頁面時,畫面顯示無限載入中
|
||
|
||
**原因**: Superset Docker 映像 (3.1.0/3.1.1) 中的 `theme.5ab95322dc4a489d8e8f.entry.js` 檔案大小為 0 bytes (映像構建問題)
|
||
|
||
**解決方案**: 已在 docker-compose.yml 的啟動命令中自動修復:
|
||
|
||
```bash
|
||
echo '(function(){console.log("Theme loaded");})();' > /app/superset/static/assets/theme.5ab95322dc4a489d8e8f.entry.js
|
||
```
|
||
|
||
**手動修復** (如果需要):
|
||
|
||
```bash
|
||
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/`。
|
||
|
||
**解決方案**:
|
||
|
||
1. **superset_config.py** - 禁用 x_prefix:
|
||
```python
|
||
ENABLE_PROXY_FIX = True
|
||
PROXY_FIX_CONFIG = {
|
||
"x_for": 1,
|
||
"x_proto": 1,
|
||
"x_host": 1,
|
||
"x_prefix": 0, # 必須為 0!
|
||
}
|
||
```
|
||
|
||
2. **Nginx 配置** - 智能 proxy_redirect:
|
||
```nginx
|
||
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;
|
||
}
|
||
```
|
||
|
||
3. **驗證**:
|
||
```bash
|
||
# 應該返回 302 到 /superset/welcome/ (不是 /superset/superset/welcome/)
|
||
curl -sI https://monitor.wooo.work/superset/ | grep -i location
|
||
```
|