feat: backfill growth momo matches
All checks were successful
CD Pipeline / deploy (push) Successful in 1m9s
All checks were successful
CD Pipeline / deploy (push) Successful in 1m9s
This commit is contained in:
@@ -272,6 +272,40 @@
|
||||
box-shadow: inset 3px 0 0 var(--momo-success);
|
||||
}
|
||||
|
||||
.growth-task.is-loading {
|
||||
opacity: 0.78;
|
||||
}
|
||||
|
||||
.growth-backfill-status {
|
||||
margin-top: 9px;
|
||||
padding: 8px 10px;
|
||||
color: var(--momo-text-secondary);
|
||||
background: color-mix(in srgb, var(--momo-bg-paper) 72%, transparent);
|
||||
border: 1px solid var(--momo-border-light);
|
||||
border-radius: 8px;
|
||||
font-size: 11px;
|
||||
font-weight: 900;
|
||||
line-height: 1.35;
|
||||
}
|
||||
|
||||
.growth-backfill-status.is-success {
|
||||
color: var(--momo-success);
|
||||
border-color: rgba(48, 133, 94, 0.24);
|
||||
background: rgba(235, 248, 241, 0.72);
|
||||
}
|
||||
|
||||
.growth-backfill-status.is-warning {
|
||||
color: var(--momo-warning-text);
|
||||
border-color: rgba(210, 158, 58, 0.34);
|
||||
background: rgba(255, 248, 231, 0.72);
|
||||
}
|
||||
|
||||
.growth-backfill-status.is-danger {
|
||||
color: var(--momo-danger);
|
||||
border-color: rgba(188, 75, 49, 0.32);
|
||||
background: rgba(255, 244, 239, 0.72);
|
||||
}
|
||||
|
||||
.growth-strategy-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
|
||||
@@ -280,6 +280,84 @@ let priceChartInstance = null;
|
||||
button.addEventListener('click', () => runDashboardTask(button.dataset.dashboardTask));
|
||||
});
|
||||
|
||||
function getPchomeGrowthBackfillElements() {
|
||||
return {
|
||||
triggers: Array.from(document.querySelectorAll('[data-pchome-growth-backfill-trigger]')),
|
||||
status: document.querySelector('[data-pchome-growth-backfill-status]'),
|
||||
endpoint: '/api/ai/pchome-growth/backfill-momo-candidates'
|
||||
};
|
||||
}
|
||||
|
||||
function setGrowthBackfillStatus(message, tone) {
|
||||
const elements = getPchomeGrowthBackfillElements();
|
||||
if (!elements.status) return;
|
||||
elements.status.textContent = message;
|
||||
elements.status.classList.remove('is-success', 'is-warning', 'is-danger');
|
||||
if (tone) {
|
||||
elements.status.classList.add(`is-${tone}`);
|
||||
}
|
||||
}
|
||||
|
||||
function setGrowthBackfillBusy(isBusy) {
|
||||
const elements = getPchomeGrowthBackfillElements();
|
||||
elements.triggers.forEach(trigger => {
|
||||
trigger.disabled = isBusy;
|
||||
trigger.classList.toggle('is-loading', isBusy);
|
||||
});
|
||||
}
|
||||
|
||||
function renderGrowthBackfillResult(data) {
|
||||
const payload = data && data.data ? data.data : {};
|
||||
const sync = payload.external_offer_sync || {};
|
||||
const written = Number(sync.written_count || 0);
|
||||
const autoCount = Number(payload.auto_compare_count || 0);
|
||||
const reviewCount = Number(payload.review_count || 0);
|
||||
const candidateCount = Number(payload.candidate_count || 0);
|
||||
const scanned = Number(payload.scanned_products || 0);
|
||||
const tone = written > 0 ? 'success' : (candidateCount > 0 ? 'warning' : 'danger');
|
||||
const message = (
|
||||
`掃描 ${formatBackfillCount(scanned)} 個高業績品`
|
||||
+ ` · 候選 ${formatBackfillCount(candidateCount)}`
|
||||
+ ` · 可自動 ${formatBackfillCount(autoCount)}`
|
||||
+ ` · 寫入 ${formatBackfillCount(written)}`
|
||||
+ ` · 待覆核 ${formatBackfillCount(reviewCount)}`
|
||||
);
|
||||
setGrowthBackfillStatus(message, tone);
|
||||
if (written > 0) {
|
||||
setTimeout(() => window.location.reload(), 1200);
|
||||
}
|
||||
}
|
||||
|
||||
function backfillPchomeGrowthMomoCandidates(activeTrigger) {
|
||||
const elements = getPchomeGrowthBackfillElements();
|
||||
if (!elements.triggers.length) return;
|
||||
const trigger = activeTrigger && activeTrigger.dataset ? activeTrigger : elements.triggers[0];
|
||||
const limit = Number(trigger.dataset.limit || 12);
|
||||
setGrowthBackfillBusy(true);
|
||||
setGrowthBackfillStatus(`正在補 ${formatBackfillCount(limit)} 個高業績商品的 MOMO 對應`, '');
|
||||
fetch(elements.endpoint, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
'X-CSRFToken': getCSRFToken()
|
||||
},
|
||||
body: JSON.stringify({ limit })
|
||||
})
|
||||
.then(response => response.json().then(data => ({ ok: response.ok, data })))
|
||||
.then(({ ok, data }) => {
|
||||
if (!ok || !data.success) {
|
||||
throw new Error(data.error || data.message || 'MOMO 對應補抓失敗');
|
||||
}
|
||||
renderGrowthBackfillResult(data);
|
||||
})
|
||||
.catch(error => {
|
||||
setGrowthBackfillStatus(error.message || 'MOMO 對應補抓失敗', 'danger');
|
||||
})
|
||||
.finally(() => {
|
||||
setGrowthBackfillBusy(false);
|
||||
});
|
||||
}
|
||||
|
||||
let pchomeBackfillPollTimer = null;
|
||||
const DEFAULT_PCHOME_BACKFILL_LABEL = '補強 60 筆';
|
||||
const DEFAULT_PCHOME_REFRESH_STALE_LABEL = '刷新過期 120 筆';
|
||||
@@ -529,6 +607,10 @@ let priceChartInstance = null;
|
||||
|
||||
window.backfillPchomeMatches = backfillPchomeMatches;
|
||||
window.refreshStalePchomeMatches = refreshStalePchomeMatches;
|
||||
window.backfillPchomeGrowthMomoCandidates = backfillPchomeGrowthMomoCandidates;
|
||||
document.querySelectorAll('[data-pchome-growth-backfill-trigger]').forEach(button => {
|
||||
button.addEventListener('click', () => backfillPchomeGrowthMomoCandidates(button));
|
||||
});
|
||||
document.querySelectorAll('[data-pchome-backfill-trigger]').forEach(button => {
|
||||
button.addEventListener('click', () => backfillPchomeMatches(button));
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user