Provide managers with a dedicated page to analyze hold lots across all stations. Extends existing service functions (get_hold_detail_summary, get_hold_detail_lots, get_wip_matrix) with optional parameters for backward compatibility, adds one new function (get_hold_overview_treemap), and registers the page in the portal navigation. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
7.2 KiB
7.2 KiB
1. Backend — 擴充現有 Service 函數
- 1.1 擴充
get_hold_detail_summary()簽名:reason改為Optional[str] = None,新增hold_type: Optional[str] = None參數;reason=None 時聚合所有 HOLD lots;hold_type 過濾品質/非品質;cache path 和 Oracle fallback 都需支援;確保現有 Hold Detail 呼叫get_hold_detail_summary(reason='xxx')行為不變 - 1.2 擴充
get_hold_detail_lots()簽名:reason改為Optional[str] = None,新增hold_type: Optional[str] = None和treemap_reason: Optional[str] = None參數;reason=None 時返回所有 HOLD lots;treemap_reason 作為額外 HOLDREASONNAME 過濾(TreeMap 點擊篩選用);增加 holdReason 欄位到 lot 回傳資料中;確保現有 Hold Detail 呼叫不受影響 - 1.3 擴充
get_wip_matrix()簽名:新增reason: Optional[str] = None參數,過濾 HOLDREASONNAME;cache path 用 DataFrame filter,Oracle fallback 用 QueryBuilder;reason=None 時行為不變,確保 WIP Overview 呼叫不受影響 - 1.4 新增
get_hold_overview_treemap()函數(唯一全新函數):使用_select_with_snapshot_indexes(status='HOLD', hold_type=...)取得 HOLD DataFrame,按 (WORKCENTER_GROUP, HOLDREASONNAME) groupBy 聚合,回傳[{ workcenter, reason, lots, qty, avgAge }];接受hold_type,reason,workcenter,package參數;含 Oracle fallback
2. Backend — 路由
- 2.1 建立
src/mes_dashboard/routes/hold_overview_routes.py,Flask Blueprinthold_overview_bp;頁面路由GET /hold-overview以send_from_directory提供 static Vite HTML,含 fallback HTML - 2.2 實作
GET /api/hold-overview/summary:解析hold_type(預設quality)和reasonquery params,委派給擴充後的get_hold_detail_summary(reason=reason, hold_type=hold_type) - 2.3 實作
GET /api/hold-overview/matrix:委派給現有get_wip_matrix(status='HOLD', hold_type=..., reason=...);套用 rate limiting (120 req/60s) - 2.4 實作
GET /api/hold-overview/treemap:解析hold_type,reason,workcenter,packageparams,委派給get_hold_overview_treemap() - 2.5 實作
GET /api/hold-overview/lots:解析所有 filter params + 分頁,委派給擴充後的get_hold_detail_lots(reason=reason, hold_type=hold_type, treemap_reason=treemap_reason, ...);套用 rate limiting (90 req/60s);per_page 上限 200 - 2.6 在 Flask app factory(
routes/__init__.py)中註冊hold_overview_bp
3. Backend — 向後相容驗證
- 3.1 驗證 Hold Detail 頁面現有 3 支 API(summary/distribution/lots)在擴充後行為不變:
get_hold_detail_summary(reason='xxx')和get_hold_detail_lots(reason='xxx', ...)結果與擴充前一致 - 3.2 驗證 WIP Overview 的
get_wip_matrix()呼叫在新增 reason 參數後行為不變(reason=None 預設值)
4. Frontend — 腳手架
- 4.1 建立
frontend/src/hold-overview/目錄結構:index.html,main.js,App.vue,style.css,components/ - 4.2 在
vite.config.js的 input 加入'hold-overview': resolve(__dirname, 'src/hold-overview/index.html') - 4.3 建立
index.html(Vue 3 mount point)、main.js(createApp(App).mount('#app')),importstyle.css和wip-shared/styles.css
5. Frontend — FilterBar(全新)
- 5.1 建立
components/FilterBar.vue:Hold Type radio group(品質異常 default, 非品質異常, 全部)+ Reason dropdown(全部 + dynamic reasons);emitchange事件帶{ holdType, reason }
6. Frontend — SummaryCards(直接 import)
- 6.1 在 App.vue 中直接
import SummaryCards from '../hold-detail/components/SummaryCards.vue';props 形狀{ totalLots, totalQty, avgAge, maxAge, workcenterCount }完全相容,無需新建元件
7. Frontend — HoldMatrix(基於 MatrixTable 新建)
- 7.1 建立
components/HoldMatrix.vue,以wip-overview/MatrixTable.vue為基礎:保留 matrix 渲染邏輯(sticky 首欄、Total row/column、"-" 零值、zh-TW 格式化) - 7.2 擴充互動:cell click → emit
{ workcenter, package }、workcenter name/row total click → emit{ workcenter }、package header/column total click → emit{ package };active cell/row/column highlight;toggle logic(再次點擊同一項 = 清除)
8. Frontend — HoldTreeMap(全新)
- 8.1 建立
components/HoldTreeMap.vue:ECharts TreeMap,import { TreemapChart } from 'echarts/charts';兩層結構(WC parent → Reason child);面積=QTY;visualMap色階 for avgAge(綠<1天, 黃1-3天, 橙3-7天, 紅>7天) - 8.2 實作 tooltip(workcenter, reason, lots, qty, avgAge)和 click handler → emit
{ workcenter, reason };toggle logic;"目前無 Hold 資料" empty state - 8.3 實作
autoresize和 responsive height
9. Frontend — LotTable(基於 hold-detail/LotTable 新建)
- 9.1 建立
components/LotTable.vue,以hold-detail/LotTable.vue為基礎:保留分頁邏輯(已 importwip-shared/Pagination.vue)、loading/error/empty 狀態、filter indicator;替換欄位:移除 Spec,新增 Hold Reason 欄位(holdReason)
10. Frontend — FilterIndicator(全新)
- 10.1 建立
components/FilterIndicator.vue:顯示 active matrixFilter 和/或 treemapFilter 標籤,含 ✕ 清除按鈕;任一 cascade filter 啟用時顯示「清除所有篩選」按鈕
11. Frontend — App.vue 整合
- 11.1 串接 App.vue:import 所有元件(SummaryCards 從 hold-detail import、其餘從 local components);設定 reactive state for
filterBar,matrixFilter,treemapFilter,page - 11.2 實作資料載入:
loadAllData()平行呼叫 4 支 API;loadTreemapAndLots()for matrix filter 變更;loadLots()for treemap filter 變更;使用useAutoRefreshcomposable(從wip-shared/composables/useAutoRefresh.jsimport) - 11.3 實作 filter cascade:filter bar 變更 → 清除 matrixFilter + treemapFilter →
loadAllData();matrix click → set matrixFilter, 清除 treemapFilter →loadTreemapAndLots();treemap click → set treemapFilter →loadLots() - 11.4 實作 loading states(initialLoading overlay、refreshing indicator、refresh success/error)、error handling、手動重新整理按鈕、AbortController request cancellation
- 11.5 從 treemap 資料的 distinct reasons 填充 Reason dropdown
12. Frontend — 樣式
- 12.1 建立
style.css,沿用wip-overview/style.css和hold-detail/style.css的 pattern;包含 header、summary cards、matrix table、treemap section、lot table、filter indicator、filter bar、loading overlay、error banner 樣式
13. Build & 驗證
- 13.1 執行
npm --prefix frontend run build,確認static/dist/生成hold-overview.html,hold-overview.js,hold-overview.css - 13.2 驗證 Flask serve
/hold-overview正常,4 支 API endpoint 回應正確 - 13.3 端對端測試:filter bar toggle → matrix click → treemap click → lot table cascade;驗證每層正確回應
- 13.4 回歸測試:確認 Hold Detail 頁面(
/hold-detail?reason=xxx)功能正常不受影響;確認 WIP Overview Matrix 功能正常不受影響