fix(reject-history): WORKORDER bind variable error + move policy filters to in-memory

Three fixes for the reject history query feature:

1. Fix DPY-4010 bind variable error when querying by WORKORDER — the
   workflow_lookup CTE had hardcoded :start_date/:end_date which aren't
   provided in container mode. Replaced with {{ WORKFLOW_FILTER }} template
   slot that defaults to date-based filter or container-based filter.

2. Move policy toggle filters (material scrap, PB_diode, excluded reasons)
   from SQL-level to in-memory pandas filtering. Cache now stores unfiltered
   data so toggling policy filters reuses cached results instantly instead
   of requiring a ~30s Oracle round-trip per combination.

3. Add per-WORKORDER expansion_info display in FilterPanel for multi-order
   container resolution diagnostics.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
egg
2026-02-26 13:21:31 +08:00
parent 07ced80fb0
commit 5d58ac551d
9 changed files with 161 additions and 16 deletions

View File

@@ -175,6 +175,7 @@ export function buildViewParams(queryId, {
detailReason = '',
page = 1,
perPage = 50,
policyFilters = {},
} = {}) {
const params = { query_id: queryId };
if (supplementaryFilters.packages?.length > 0) {
@@ -197,5 +198,16 @@ export function buildViewParams(queryId, {
}
params.page = page || 1;
params.per_page = perPage || 50;
// Policy filters (applied in-memory on cached data)
if (policyFilters.includeExcludedScrap) {
params.include_excluded_scrap = 'true';
}
if (policyFilters.excludeMaterialScrap === false) {
params.exclude_material_scrap = 'false';
}
if (policyFilters.excludePbDiode === false) {
params.exclude_pb_diode = 'false';
}
return params;
}

View File

@@ -242,6 +242,11 @@ async function refreshView() {
detailReason: detailReason.value,
page: page.value,
perPage: DEFAULT_PER_PAGE,
policyFilters: {
includeExcludedScrap: committedPrimary.includeExcludedScrap,
excludeMaterialScrap: committedPrimary.excludeMaterialScrap,
excludePbDiode: committedPrimary.excludePbDiode,
},
});
const resp = await apiGet('/api/reject-history/view', {
@@ -468,6 +473,11 @@ async function exportCsv() {
for (const date of selectedTrendDates.value) params.append('trend_dates', date);
if (detailReason.value) params.set('detail_reason', detailReason.value);
// Policy filters (applied in-memory on cached data)
if (committedPrimary.includeExcludedScrap) params.set('include_excluded_scrap', 'true');
if (!committedPrimary.excludeMaterialScrap) params.set('exclude_material_scrap', 'false');
if (!committedPrimary.excludePbDiode) params.set('exclude_pb_diode', 'false');
const response = await fetch(`/api/reject-history/export-cached?${params.toString()}`);
if (response.status === 410) {

View File

@@ -173,6 +173,11 @@ function emitSupplementary(patch) {
class="card-body resolution-info"
>
已解析 {{ resolutionInfo.resolved_count }} 筆容器
<template v-if="resolutionInfo.expansion_info && Object.keys(resolutionInfo.expansion_info).length > 1">
<span class="resolution-detail">
({{ Object.entries(resolutionInfo.expansion_info).map(([k, v]) => `${k}: ${v}`).join(', ') }})
</span>
</template>
<template v-if="resolutionInfo.not_found?.length > 0">
<span class="resolution-warn">
({{ resolutionInfo.not_found.length }} 筆未找到:

View File

@@ -67,6 +67,11 @@
font-weight: 600;
}
.resolution-detail {
color: #475569;
font-weight: 400;
}
.resolution-warn {
color: #b45309;
font-weight: 400;