fix(lot-detail): use actual data update time and add LF/wafer description fields
Hold Detail "Last Update" now reads dataUpdateDate from the API response instead of using browser-local page load time. Lot Detail panels in both WIP Detail and Resource Status tooltip now show LEADFRAMEDESC and WAFERDESC from DWH.DW_MES_LOT_V, with multi-row values joined by ", ". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -36,7 +36,9 @@ const refreshing = ref(false);
|
||||
const lotsLoading = ref(false);
|
||||
const lotsError = ref('');
|
||||
const loadError = ref('');
|
||||
const lastUpdate = ref('');
|
||||
const lastUpdate = computed(() => {
|
||||
return summary.value?.dataUpdateDate ? `Last Update: ${summary.value.dataUpdateDate}` : '';
|
||||
});
|
||||
|
||||
function unwrapApiResult(result, fallbackMessage) {
|
||||
if (result?.success) {
|
||||
@@ -216,7 +218,6 @@ async function loadAllData(showOverlay = true) {
|
||||
totalPages: Number(lotsData?.pagination?.totalPages || 1),
|
||||
};
|
||||
|
||||
lastUpdate.value = `Last Update: ${new Date().toLocaleString('zh-TW')}`;
|
||||
} catch (error) {
|
||||
if (error?.name === 'AbortError') {
|
||||
return;
|
||||
|
||||
@@ -275,10 +275,18 @@ onBeforeUnmount(() => {
|
||||
<span class="tooltip-field-label">Wafer P/N</span>
|
||||
<span class="tooltip-field-value">{{ lotDetailValue(getLotDetail(lot.RUNCARDLOTID), 'waferPn') }}</span>
|
||||
</div>
|
||||
<div class="tooltip-field">
|
||||
<span class="tooltip-field-label">Wafer Description</span>
|
||||
<span class="tooltip-field-value">{{ lotDetailValue(getLotDetail(lot.RUNCARDLOTID), 'waferDesc') }}</span>
|
||||
</div>
|
||||
<div class="tooltip-field">
|
||||
<span class="tooltip-field-label">Leadframe</span>
|
||||
<span class="tooltip-field-value">{{ lotDetailValue(getLotDetail(lot.RUNCARDLOTID), 'leadframeName') }}</span>
|
||||
</div>
|
||||
<div class="tooltip-field">
|
||||
<span class="tooltip-field-label">LF Description</span>
|
||||
<span class="tooltip-field-value">{{ lotDetailValue(getLotDetail(lot.RUNCARDLOTID), 'leadframeDesc') }}</span>
|
||||
</div>
|
||||
<div class="tooltip-field">
|
||||
<span class="tooltip-field-label">Compound</span>
|
||||
<span class="tooltip-field-value">{{ lotDetailValue(getLotDetail(lot.RUNCARDLOTID), 'compoundName') }}</span>
|
||||
|
||||
@@ -103,7 +103,7 @@ function hasHoldSection() {
|
||||
const basicFields = ['lotId', 'workorder', 'wipStatus', 'status', 'qty', 'qty2', 'ageByDays', 'priority'];
|
||||
const productFields = ['product', 'productLine', 'packageLef', 'pjType', 'pjFunction', 'bop', 'dateCode', 'produceRegion'];
|
||||
const processFields = ['workcenterGroup', 'workcenter', 'spec', 'specSequence', 'workflow', 'equipment', 'equipmentCount', 'location'];
|
||||
const materialFields = ['waferLotId', 'waferPn', 'waferLotPrefix', 'leadframeName', 'leadframeOption', 'compoundName', 'dieConsumption', 'uts'];
|
||||
const materialFields = ['waferLotId', 'waferPn', 'waferLotPrefix', 'waferDesc', 'leadframeName', 'leadframeOption', 'leadframeDesc', 'compoundName', 'dieConsumption', 'uts'];
|
||||
const holdFields = ['holdReason', 'holdCount', 'holdEmp', 'holdDept', 'holdComment', 'releaseTime', 'releaseEmp', 'releaseComment'];
|
||||
const ncrFields = ['ncrId', 'ncrDate'];
|
||||
const commentFields = ['comment', 'commentDate', 'commentEmp', 'futureHoldComment'];
|
||||
|
||||
@@ -3036,6 +3036,8 @@ LOT_DETAIL_FIELD_LABELS = {
|
||||
'priority': 'Work Order Priority',
|
||||
'tmttRemaining': 'TMTT Remaining',
|
||||
'dieConsumption': 'Die Consumption Qty',
|
||||
'leadframeDesc': 'LF Description',
|
||||
'waferDesc': 'Wafer Description',
|
||||
'wipStatus': 'WIP Status',
|
||||
'dataUpdateDate': 'Data Update Date'
|
||||
}
|
||||
@@ -3062,6 +3064,12 @@ def get_lot_detail(lotid: str) -> Optional[Dict[str, Any]]:
|
||||
return None
|
||||
|
||||
row = df.iloc[0]
|
||||
if len(df) > 1:
|
||||
row = row.copy()
|
||||
for col in ('LEADFRAMEDESC', 'WAFERDESC'):
|
||||
if col in df.columns:
|
||||
vals = df[col].dropna().unique()
|
||||
row[col] = ', '.join(str(v) for v in vals) if len(vals) > 0 else None
|
||||
return _build_lot_detail_response(row)
|
||||
except (DatabasePoolExhaustedError, DatabaseCircuitOpenError):
|
||||
raise
|
||||
@@ -3127,7 +3135,9 @@ def _get_lot_detail_from_oracle(lotid: str) -> Optional[Dict[str, Any]]:
|
||||
PRIORITYCODENAME,
|
||||
TMTT_R,
|
||||
WAFER_FACTOR,
|
||||
SYS_DATE
|
||||
SYS_DATE,
|
||||
LEADFRAMEDESC,
|
||||
WAFERDESC
|
||||
FROM {WIP_VIEW}
|
||||
WHERE LOTID = :lotid
|
||||
"""
|
||||
@@ -3137,6 +3147,12 @@ def _get_lot_detail_from_oracle(lotid: str) -> Optional[Dict[str, Any]]:
|
||||
return None
|
||||
|
||||
row = df.iloc[0]
|
||||
if len(df) > 1:
|
||||
row = row.copy()
|
||||
for col in ('LEADFRAMEDESC', 'WAFERDESC'):
|
||||
if col in df.columns:
|
||||
vals = df[col].dropna().unique()
|
||||
row[col] = ', '.join(str(v) for v in vals) if len(vals) > 0 else None
|
||||
return _build_lot_detail_response(row)
|
||||
except (DatabasePoolExhaustedError, DatabaseCircuitOpenError):
|
||||
raise
|
||||
@@ -3233,7 +3249,9 @@ def _build_lot_detail_response(row) -> Dict[str, Any]:
|
||||
'dateCode': _safe_value(safe_get('DATECODE')),
|
||||
'leadframeName': _safe_value(safe_get('LEADFRAMENAME')),
|
||||
'leadframeOption': _safe_value(safe_get('LEADFRAMEOPTION')),
|
||||
'leadframeDesc': _safe_value(safe_get('LEADFRAMEDESC')),
|
||||
'compoundName': _safe_value(safe_get('COMNAME')),
|
||||
'waferDesc': _safe_value(safe_get('WAFERDESC')),
|
||||
'location': _safe_value(safe_get('LOCATIONNAME')),
|
||||
'ncrId': _safe_value(safe_get('EVENTNAME')),
|
||||
'ncrDate': format_date('OCCURRENCEDATE'),
|
||||
|
||||
Reference in New Issue
Block a user