feat(query-tool): rewrite frontend with ECharts tree, multi-select, and modular composables
Replace the monolithic useQueryToolData composable and nested Vue component tree with a modular architecture: useLotResolve, useLotLineage, useLotDetail, and useEquipmentQuery. Introduce ECharts TreeChart (LR orthogonal layout) for lot lineage visualization with multi-select support, subtree expansion, zoom/pan, and serial number normalization. Add unified LineageEngine backend with split descendant traversal and leaf serial number queries. Archive the query-tool-rewrite openspec change and sync delta specs to main. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
242
docs/reject_history_performance.sql
Normal file
242
docs/reject_history_performance.sql
Normal file
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
Reject 歷史績效表建置腳本
|
||||
目的:
|
||||
- 以 DW_MES_LOTREJECTHISTORY 為主,建立可直接報表化的日彙總績效表
|
||||
- 補齊產品/工站維度,並區分扣帳報廢與不扣帳報廢
|
||||
*/
|
||||
|
||||
/* ============================================================
|
||||
1) 建表 (執行一次)
|
||||
============================================================ */
|
||||
|
||||
CREATE TABLE DWH.DW_PJ_REJECT_HISTORY_PERF_D (
|
||||
TXN_DAY DATE NOT NULL,
|
||||
TXN_MONTH VARCHAR2(7) NOT NULL,
|
||||
WORKCENTER_GROUP VARCHAR2(40) NOT NULL,
|
||||
WORKCENTERSEQUENCE_GROUP NUMBER(10) NOT NULL,
|
||||
WORKCENTERNAME VARCHAR2(40) NOT NULL,
|
||||
SPECNAME VARCHAR2(40) NOT NULL,
|
||||
EQUIPMENTNAME VARCHAR2(255) NOT NULL,
|
||||
PRIMARY_EQUIPMENTNAME VARCHAR2(40) NOT NULL,
|
||||
PRODUCTLINENAME VARCHAR2(40) NOT NULL,
|
||||
PJ_TYPE VARCHAR2(40) NOT NULL,
|
||||
LOSSREASONNAME VARCHAR2(40) NOT NULL,
|
||||
REJECTCATEGORYNAME VARCHAR2(40) NOT NULL,
|
||||
REJECT_EVENT_ROWS NUMBER NOT NULL,
|
||||
AFFECTED_LOT_COUNT NUMBER NOT NULL,
|
||||
AFFECTED_WORKORDER_COUNT NUMBER NOT NULL,
|
||||
MOVEIN_QTY NUMBER NOT NULL,
|
||||
REJECT_QTY NUMBER NOT NULL,
|
||||
REJECT_TOTAL_QTY NUMBER NOT NULL,
|
||||
DEFECT_QTY NUMBER NOT NULL,
|
||||
STANDBY_QTY NUMBER NOT NULL,
|
||||
QTYTOPROCESS_QTY NUMBER NOT NULL,
|
||||
INPROCESS_QTY NUMBER NOT NULL,
|
||||
PROCESSED_QTY NUMBER NOT NULL,
|
||||
REJECT_RATE_PCT NUMBER(18, 4) NOT NULL,
|
||||
DEFECT_RATE_PCT NUMBER(18, 4) NOT NULL,
|
||||
REJECT_SHARE_PCT NUMBER(18, 4) NOT NULL,
|
||||
LAST_REFRESH_TS DATE NOT NULL
|
||||
);
|
||||
|
||||
CREATE INDEX DWH.IDX_RJH_PERF_D_01 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (TXN_DAY);
|
||||
CREATE INDEX DWH.IDX_RJH_PERF_D_02 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (WORKCENTER_GROUP, TXN_DAY);
|
||||
CREATE INDEX DWH.IDX_RJH_PERF_D_03 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (PRIMARY_EQUIPMENTNAME, TXN_DAY);
|
||||
CREATE INDEX DWH.IDX_RJH_PERF_D_04 ON DWH.DW_PJ_REJECT_HISTORY_PERF_D (LOSSREASONNAME, TXN_DAY);
|
||||
|
||||
|
||||
/* ============================================================
|
||||
2) 區間刷新 (可每日排程)
|
||||
綁定參數:
|
||||
:start_date (YYYY-MM-DD)
|
||||
:end_date (YYYY-MM-DD)
|
||||
============================================================ */
|
||||
|
||||
DELETE FROM DWH.DW_PJ_REJECT_HISTORY_PERF_D
|
||||
WHERE TXN_DAY >= TO_DATE(:start_date, 'YYYY-MM-DD')
|
||||
AND TXN_DAY < TO_DATE(:end_date, 'YYYY-MM-DD') + 1;
|
||||
|
||||
INSERT /*+ APPEND */ INTO DWH.DW_PJ_REJECT_HISTORY_PERF_D (
|
||||
TXN_DAY,
|
||||
TXN_MONTH,
|
||||
WORKCENTER_GROUP,
|
||||
WORKCENTERSEQUENCE_GROUP,
|
||||
WORKCENTERNAME,
|
||||
SPECNAME,
|
||||
EQUIPMENTNAME,
|
||||
PRIMARY_EQUIPMENTNAME,
|
||||
PRODUCTLINENAME,
|
||||
PJ_TYPE,
|
||||
LOSSREASONNAME,
|
||||
REJECTCATEGORYNAME,
|
||||
REJECT_EVENT_ROWS,
|
||||
AFFECTED_LOT_COUNT,
|
||||
AFFECTED_WORKORDER_COUNT,
|
||||
MOVEIN_QTY,
|
||||
REJECT_QTY,
|
||||
REJECT_TOTAL_QTY,
|
||||
DEFECT_QTY,
|
||||
STANDBY_QTY,
|
||||
QTYTOPROCESS_QTY,
|
||||
INPROCESS_QTY,
|
||||
PROCESSED_QTY,
|
||||
REJECT_RATE_PCT,
|
||||
DEFECT_RATE_PCT,
|
||||
REJECT_SHARE_PCT,
|
||||
LAST_REFRESH_TS
|
||||
)
|
||||
WITH workcenter_map AS (
|
||||
SELECT
|
||||
WORK_CENTER,
|
||||
MIN(WORK_CENTER_GROUP) KEEP (
|
||||
DENSE_RANK FIRST ORDER BY WORKCENTERSEQUENCE_GROUP
|
||||
) AS WORKCENTER_GROUP,
|
||||
MIN(WORKCENTERSEQUENCE_GROUP) AS WORKCENTERSEQUENCE_GROUP
|
||||
FROM DWH.DW_MES_SPEC_WORKCENTER_V
|
||||
WHERE WORK_CENTER IS NOT NULL
|
||||
GROUP BY WORK_CENTER
|
||||
),
|
||||
reject_raw AS (
|
||||
SELECT
|
||||
TRUNC(r.TXNDATE) AS TXN_DAY,
|
||||
TO_CHAR(TRUNC(r.TXNDATE), 'YYYY-MM') AS TXN_MONTH,
|
||||
r.CONTAINERID,
|
||||
NVL(TRIM(r.PJ_WORKORDER), TRIM(c.MFGORDERNAME)) AS PJ_WORKORDER,
|
||||
NVL(TRIM(c.PJ_TYPE), '(NA)') AS PJ_TYPE,
|
||||
NVL(TRIM(c.PRODUCTLINENAME), '(NA)') AS PRODUCTLINENAME,
|
||||
NVL(TRIM(r.WORKCENTERNAME), '(NA)') AS WORKCENTERNAME,
|
||||
NVL(TRIM(wm.WORKCENTER_GROUP), NVL(TRIM(r.WORKCENTERNAME), '(NA)')) AS WORKCENTER_GROUP,
|
||||
NVL(wm.WORKCENTERSEQUENCE_GROUP, 999) AS WORKCENTERSEQUENCE_GROUP,
|
||||
NVL(TRIM(r.SPECNAME), '(NA)') AS SPECNAME,
|
||||
NVL(TRIM(r.EQUIPMENTNAME), '(NA)') AS EQUIPMENTNAME,
|
||||
NVL(
|
||||
TRIM(REGEXP_SUBSTR(r.EQUIPMENTNAME, '[^,]+', 1, 1)),
|
||||
NVL(TRIM(r.EQUIPMENTNAME), '(NA)')
|
||||
) AS PRIMARY_EQUIPMENTNAME,
|
||||
NVL(TRIM(r.LOSSREASONNAME), '(未填寫)') AS LOSSREASONNAME,
|
||||
NVL(TRIM(r.REJECTCATEGORYNAME), '(未填寫)') AS REJECTCATEGORYNAME,
|
||||
NVL(r.MOVEINQTY, 0) AS MOVEINQTY,
|
||||
NVL(r.REJECTQTY, 0) AS REJECT_QTY,
|
||||
NVL(r.STANDBYQTY, 0) AS STANDBY_QTY,
|
||||
NVL(r.QTYTOPROCESS, 0) AS QTYTOPROCESS_QTY,
|
||||
NVL(r.INPROCESSQTY, 0) AS INPROCESS_QTY,
|
||||
NVL(r.PROCESSEDQTY, 0) AS PROCESSED_QTY,
|
||||
NVL(r.REJECTQTY, 0)
|
||||
+ NVL(r.STANDBYQTY, 0)
|
||||
+ NVL(r.QTYTOPROCESS, 0)
|
||||
+ NVL(r.INPROCESSQTY, 0)
|
||||
+ NVL(r.PROCESSEDQTY, 0) AS REJECT_TOTAL_QTY,
|
||||
NVL(r.DEFECTQTY, 0) AS DEFECT_QTY,
|
||||
ROW_NUMBER() OVER (
|
||||
PARTITION BY NVL(
|
||||
TRIM(r.HISTORYMAINLINEID),
|
||||
TRIM(r.CONTAINERID) || ':' || TO_CHAR(r.TXNDATE, 'YYYYMMDDHH24MISS') || ':' || NVL(TRIM(r.SPECID), '-')
|
||||
)
|
||||
ORDER BY NVL(TRIM(r.LOSSREASONNAME), ' ')
|
||||
) AS EVENT_RN
|
||||
FROM DWH.DW_MES_LOTREJECTHISTORY r
|
||||
LEFT JOIN DWH.DW_MES_CONTAINER c
|
||||
ON c.CONTAINERID = r.CONTAINERID
|
||||
LEFT JOIN workcenter_map wm
|
||||
ON wm.WORK_CENTER = r.WORKCENTERNAME
|
||||
WHERE r.TXNDATE >= TO_DATE(:start_date, 'YYYY-MM-DD')
|
||||
AND r.TXNDATE < TO_DATE(:end_date, 'YYYY-MM-DD') + 1
|
||||
),
|
||||
daily_agg AS (
|
||||
SELECT
|
||||
TXN_DAY,
|
||||
TXN_MONTH,
|
||||
WORKCENTER_GROUP,
|
||||
WORKCENTERSEQUENCE_GROUP,
|
||||
WORKCENTERNAME,
|
||||
SPECNAME,
|
||||
EQUIPMENTNAME,
|
||||
PRIMARY_EQUIPMENTNAME,
|
||||
PRODUCTLINENAME,
|
||||
PJ_TYPE,
|
||||
LOSSREASONNAME,
|
||||
REJECTCATEGORYNAME,
|
||||
COUNT(*) AS REJECT_EVENT_ROWS,
|
||||
COUNT(DISTINCT CONTAINERID) AS AFFECTED_LOT_COUNT,
|
||||
COUNT(DISTINCT PJ_WORKORDER) AS AFFECTED_WORKORDER_COUNT,
|
||||
SUM(CASE WHEN EVENT_RN = 1 THEN MOVEINQTY ELSE 0 END) AS MOVEIN_QTY,
|
||||
SUM(REJECT_QTY) AS REJECT_QTY,
|
||||
SUM(REJECT_TOTAL_QTY) AS REJECT_TOTAL_QTY,
|
||||
SUM(DEFECT_QTY) AS DEFECT_QTY,
|
||||
SUM(STANDBY_QTY) AS STANDBY_QTY,
|
||||
SUM(QTYTOPROCESS_QTY) AS QTYTOPROCESS_QTY,
|
||||
SUM(INPROCESS_QTY) AS INPROCESS_QTY,
|
||||
SUM(PROCESSED_QTY) AS PROCESSED_QTY
|
||||
FROM reject_raw
|
||||
GROUP BY
|
||||
TXN_DAY,
|
||||
TXN_MONTH,
|
||||
WORKCENTER_GROUP,
|
||||
WORKCENTERSEQUENCE_GROUP,
|
||||
WORKCENTERNAME,
|
||||
SPECNAME,
|
||||
EQUIPMENTNAME,
|
||||
PRIMARY_EQUIPMENTNAME,
|
||||
PRODUCTLINENAME,
|
||||
PJ_TYPE,
|
||||
LOSSREASONNAME,
|
||||
REJECTCATEGORYNAME
|
||||
)
|
||||
SELECT
|
||||
TXN_DAY,
|
||||
TXN_MONTH,
|
||||
WORKCENTER_GROUP,
|
||||
WORKCENTERSEQUENCE_GROUP,
|
||||
WORKCENTERNAME,
|
||||
SPECNAME,
|
||||
EQUIPMENTNAME,
|
||||
PRIMARY_EQUIPMENTNAME,
|
||||
PRODUCTLINENAME,
|
||||
PJ_TYPE,
|
||||
LOSSREASONNAME,
|
||||
REJECTCATEGORYNAME,
|
||||
REJECT_EVENT_ROWS,
|
||||
AFFECTED_LOT_COUNT,
|
||||
AFFECTED_WORKORDER_COUNT,
|
||||
MOVEIN_QTY,
|
||||
REJECT_QTY,
|
||||
REJECT_TOTAL_QTY,
|
||||
DEFECT_QTY,
|
||||
STANDBY_QTY,
|
||||
QTYTOPROCESS_QTY,
|
||||
INPROCESS_QTY,
|
||||
PROCESSED_QTY,
|
||||
CASE
|
||||
WHEN MOVEIN_QTY = 0 THEN 0
|
||||
ELSE ROUND(REJECT_TOTAL_QTY * 100 / MOVEIN_QTY, 4)
|
||||
END AS REJECT_RATE_PCT,
|
||||
CASE
|
||||
WHEN MOVEIN_QTY = 0 THEN 0
|
||||
ELSE ROUND(DEFECT_QTY * 100 / MOVEIN_QTY, 4)
|
||||
END AS DEFECT_RATE_PCT,
|
||||
CASE
|
||||
WHEN (REJECT_TOTAL_QTY + DEFECT_QTY) = 0 THEN 0
|
||||
ELSE ROUND(REJECT_TOTAL_QTY * 100 / (REJECT_TOTAL_QTY + DEFECT_QTY), 4)
|
||||
END AS REJECT_SHARE_PCT,
|
||||
SYSDATE AS LAST_REFRESH_TS
|
||||
FROM daily_agg;
|
||||
|
||||
COMMIT;
|
||||
|
||||
|
||||
/* ============================================================
|
||||
3) 快速驗證查詢
|
||||
============================================================ */
|
||||
|
||||
SELECT
|
||||
TXN_DAY,
|
||||
WORKCENTER_GROUP,
|
||||
SUM(MOVEIN_QTY) AS MOVEIN_QTY,
|
||||
SUM(REJECT_QTY) AS REJECT_QTY,
|
||||
SUM(REJECT_TOTAL_QTY) AS REJECT_TOTAL_QTY,
|
||||
SUM(DEFECT_QTY) AS DEFECT_QTY,
|
||||
ROUND(SUM(REJECT_TOTAL_QTY) * 100 / NULLIF(SUM(MOVEIN_QTY), 0), 4) AS REJECT_RATE_PCT
|
||||
FROM DWH.DW_PJ_REJECT_HISTORY_PERF_D
|
||||
WHERE TXN_DAY BETWEEN TO_DATE(:start_date, 'YYYY-MM-DD') AND TO_DATE(:end_date, 'YYYY-MM-DD')
|
||||
GROUP BY TXN_DAY, WORKCENTER_GROUP
|
||||
ORDER BY TXN_DAY DESC, WORKCENTER_GROUP;
|
||||
Reference in New Issue
Block a user