feat: matrix status driven by real data + product order status (B2: only show channels with data)

This commit is contained in:
王源
2026-09-08 23:22:00 +08:00
parent fb24195233
commit 367eeda50c
2 changed files with 41 additions and 9 deletions
+24 -9
View File
@@ -209,7 +209,8 @@
<p class="hint">
<span class="badge badge-active">Active</span> 投放中 
<span class="badge badge-pause">Pause</span> 投过已停 
空白 = 未投放
空白 = 暂无数据(未接入或未投放)<br>
状态依据实际投放数据判定:产品订单为 Pause 直接判停;产品在投则看该渠道近期展示趋势(掉到个位数/断更视为已停)。仅显示已接入数据的渠道。
</p>
<div class="table-wrapper">
<table id="matrixTable"><thead></thead><tbody></tbody></table>
@@ -251,17 +252,18 @@
</div>
<script>
let perfData = [], orderData = [], campaignData = [];
let perfData = [], orderData = [], campaignData = [], matrixOverrides = {};
let impChart = null;
async function load() {
try {
const [p, o, c] = await Promise.all([
const [p, o, c, m] = await Promise.all([
fetch('mtg_data.json?' + Date.now()).then(r => r.json()).catch(() => []),
fetch('orders.json?' + Date.now()).then(r => r.json()).catch(() => []),
fetch('campaigns.json?' + Date.now()).then(r => r.json()).catch(() => [])
fetch('campaigns.json?' + Date.now()).then(r => r.json()).catch(() => []),
fetch('matrix_overrides.json?' + Date.now()).then(r => r.json()).catch(() => ({}))
]);
perfData = p; orderData = o; campaignData = c;
perfData = p; orderData = o; campaignData = c; matrixOverrides = m;
initTabs();
renderPerformance();
renderOrders();
@@ -401,8 +403,9 @@
}
function renderMatrix() {
// 列 = 产品(带 pkg 用于查数据状态)
const cols = orderData.map(o => ({
label: o.product, sub: o.geo, status: o.status,
label: o.product, sub: o.geo, pkg: o.pkg,
channels: new Set([...(o.agency_channels||[]), ...(o.self_channels||[])])
}));
const channels = [];
@@ -413,10 +416,22 @@
<th style="position:sticky;left:0;background:#f9fafb;z-index:2;">渠道 \\ 产品</th>
${cols.map(c => `<th style="text-align:center;min-width:88px;"><div>${c.label}</div><div style="font-weight:400;font-size:10px;color:#9ca3af;">${c.sub}</div></th>`).join('')}
</tr>`;
// 单元格:仅当该「渠道|包名」在 matrixOverrides 有记录时才显示状态(遵从事实:接了数据才判定)
// 产品 pkg 可能是 "a / b" 合并形式,任一命中即取用
const lookup = (ch, pkg) => {
const parts = String(pkg).replace(/\s/g,'').split('/');
for (const p of parts) {
const k = ch + '|' + p;
if (k in matrixOverrides) return matrixOverrides[k];
}
return undefined;
};
const cell = (col, ch) => {
if (!col.channels.has(ch)) return '<td></td>';
const cls = col.status === 'Active' ? 'badge-active' : 'badge-pause';
return `<td style="text-align:center;"><span class="badge ${cls}">${col.status}</span></td>`;
const st = lookup(ch, col.pkg);
if (st === undefined || st === 'none') return '<td></td>'; // 无数据 / 零曝光 -> 留空
const cls = st === 'Active' ? 'badge-active' : 'badge-pause';
return `<td style="text-align:center;"><span class="badge ${cls}">${st}</span></td>`;
};
document.querySelector('#matrixTable tbody').innerHTML = channels.map(ch => `
<tr>