37 lines
9.5 KiB
HTML
37 lines
9.5 KiB
HTML
<!doctype html>
|
||
<html lang="zh-CN">
|
||
<head>
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
<meta name="color-scheme" content="light dark">
|
||
<title>Amazon ZA 每日交付报告</title>
|
||
<style>
|
||
:root{--bg:#f4f7fb;--panel:#fff;--ink:#162033;--muted:#667085;--line:#dce3ec;--blue:#2f6fed;--gold:#d79b24;--orange:#e56d35;--soft:#eaf1ff;--shadow:0 8px 28px rgba(23,43,77,.08)}
|
||
*{box-sizing:border-box}body{margin:0;background:var(--bg);color:var(--ink);font:14px/1.55 Inter,ui-sans-serif,system-ui,-apple-system,"Segoe UI",sans-serif}main{max-width:1180px;margin:auto;padding:42px 24px 64px}.eyebrow{color:var(--blue);font-weight:700;letter-spacing:.08em;text-transform:uppercase}.hero h1{font-size:clamp(28px,4vw,46px);line-height:1.1;margin:8px 0 12px}.hero p{color:var(--muted);font-size:16px;margin:0;max-width:800px}.status{display:inline-flex;align-items:center;gap:8px;margin-top:18px;padding:7px 11px;border:1px solid var(--line);border-radius:999px;background:var(--panel);color:var(--muted)}.dot{width:8px;height:8px;border-radius:50%;background:var(--blue)}section{margin-top:30px}h2{font-size:22px;margin:0 0 12px}.summary{display:grid;grid-template-columns:repeat(4,1fr);gap:14px}.card,.panel{background:var(--panel);border:1px solid var(--line);border-radius:16px;box-shadow:var(--shadow)}.card{padding:18px}.card .label{color:var(--muted);font-weight:600}.card .value{font-size:28px;font-weight:750;margin-top:6px;font-variant-numeric:tabular-nums}.card .note{color:var(--muted);font-size:12px;margin-top:3px}.panel{padding:22px;margin-top:14px}.takeaway{border-left:4px solid var(--blue);padding-left:14px;color:var(--muted)}.takeaway strong{color:var(--ink)}.charts{display:grid;grid-template-columns:1fr 1fr;gap:14px}.chart{min-height:300px}.chart-head{margin-bottom:16px}.chart-title{font-weight:750;font-size:16px}.chart-sub{color:var(--muted);font-size:12px}.bars{height:220px;display:flex;align-items:end;gap:14px;padding:20px 10px 28px;border-bottom:1px solid var(--line);position:relative}.bar-group{flex:1;height:100%;display:flex;align-items:end;justify-content:center;gap:6px;position:relative}.bar{min-width:16px;max-width:34px;width:33%;border-radius:6px 6px 0 0;position:relative}.bar span{position:absolute;top:-21px;left:50%;transform:translateX(-50%);font-size:11px;font-weight:700;white-space:nowrap}.bar-label{position:absolute;bottom:-25px;left:50%;transform:translateX(-50%);color:var(--muted);font-size:11px}.legend{display:flex;gap:14px;margin-top:13px;color:var(--muted);font-size:12px}.swatch{width:9px;height:9px;border-radius:2px;display:inline-block;margin-right:5px}.rate-bars .bar{width:52%;background:var(--orange)}table{width:100%;border-collapse:collapse;font-variant-numeric:tabular-nums}th,td{padding:12px 10px;border-bottom:1px solid var(--line);text-align:right;white-space:nowrap}th:first-child,td:first-child{text-align:left}th{color:var(--muted);font-size:12px}tbody tr:hover{background:var(--soft)}.footer-note{color:var(--muted);font-size:12px;margin-top:18px}.error{padding:18px;border:1px solid #f0b7b7;background:#fff2f2;color:#912b2b;border-radius:12px}@media(max-width:850px){.summary{grid-template-columns:1fr 1fr}.charts{grid-template-columns:1fr}}@media(max-width:520px){main{padding:26px 14px}.summary{grid-template-columns:1fr}.panel{padding:16px;overflow:auto}.card .value{font-size:24px}}
|
||
@media(prefers-color-scheme:dark){:root{--bg:#0c1220;--panel:#121a2a;--ink:#eef3fb;--muted:#9ba9bd;--line:#28354a;--soft:#182743;--shadow:none}}
|
||
</style>
|
||
</head>
|
||
<body><main>
|
||
<header class="hero"><div class="eyebrow">Daily Delivery · ZA</div><h1>Amazon ZA 每日交付报告</h1><p>包名:com.amazon.mShop.android.shopping。聚焦 repostback 交付、E1+E2 转化与 Midas / Payable spend。</p><div class="status"><span class="dot"></span><span id="range">正在载入数据…</span></div></header>
|
||
<section><h2>Executive Summary</h2><div id="summaryText" class="panel takeaway">载入中…</div></section>
|
||
<section><h2>核心指标</h2><div class="summary" id="cards"></div></section>
|
||
<section><h2>每日交付与转化</h2><div class="takeaway"><strong>如何阅读:</strong>先看每日 Install 与 E1/E2 的规模,再结合 E1+E2% 判断转化效率;仅有 3 个日期,因此使用离散柱状图,避免把短窗口误读为长期趋势。</div><div class="charts"><div class="panel chart"><div class="chart-head"><div class="chart-title">每日 Install、Event1 与 Event2</div><div class="chart-sub">均取 repostback;按 ZA 日期汇总</div></div><div id="deliveryChart" class="bars"></div><div class="legend"><span><i class="swatch" style="background:var(--blue)"></i>Install</span><span><i class="swatch" style="background:var(--gold)"></i>Event1</span><span><i class="swatch" style="background:var(--orange)"></i>Event2</span></div></div><div class="panel chart"><div class="chart-head"><div class="chart-title">每日 E1+E2%</div><div class="chart-sub">(Event1 + Event2) ÷ Install</div></div><div id="rateChart" class="bars rate-bars"></div></div></div></section>
|
||
<section><h2>消耗对比</h2><div id="spendText" class="takeaway"></div><div class="panel chart"><div class="chart-head"><div class="chart-title">Midas spend 与 Payable spend</div><div class="chart-sub">USD;Payable spend = (E1 + E2) × $3</div></div><div id="spendChart" class="bars"></div><div class="legend"><span><i class="swatch" style="background:var(--blue)"></i>Midas spend</span><span><i class="swatch" style="background:var(--gold)"></i>Payable spend</span></div></div></section>
|
||
<section><h2>每日明细</h2><div class="panel"><table><thead><tr><th>日期</th><th>Install</th><th>Event1</th><th>Event2</th><th>E1+E2%</th><th>Midas spend</th><th>Payable spend</th></tr></thead><tbody id="rows"></tbody></table><div class="footer-note">口径:Install、Event1、Event2 均取 repostback;金额为 USD。源文件更新后,update.sh 会重新生成 data.json。</div></div></section>
|
||
<section><h2>建议关注</h2><div class="panel"><ul><li>继续监控 E1+E2% 是否在更长日期窗口内稳定,当前 3 天样本不宜外推长期趋势。</li><li>对比 Payable spend 与 Midas spend 的日级差额,优先排查差额扩大日期的事件质量和计费口径。</li><li>若要实现新增日期自动进入报告,需要让 update.sh 能访问持续更新的数据源;当前版本自动重算仓库内两份 CSV 快照。</li></ul></div></section>
|
||
</main><script>
|
||
const fmt=n=>new Intl.NumberFormat('en-US').format(n), money=n=>'$'+new Intl.NumberFormat('en-US',{minimumFractionDigits:2,maximumFractionDigits:2}).format(n), pct=n=>n==null?'—':n.toFixed(2)+'%';
|
||
const label=d=>d.slice(5).replace('-','/');
|
||
function bars(el,data,series,max){el.innerHTML=data.map(d=>`<div class="bar-group">${series.map(s=>`<div class="bar" style="height:${Math.max(2,d[s.key]/max*100)}%;background:${s.color}"><span>${s.format(d[s.key])}</span></div>`).join('')}<div class="bar-label">${label(d.date)}</div></div>`).join('')}
|
||
fetch('data.json',{cache:'no-store'}).then(r=>{if(!r.ok)throw Error('data.json '+r.status);return r.json()}).then(data=>{
|
||
const t=data.totals,d=data.daily,latest=d[d.length-1],first=d[0];document.getElementById('range').textContent=`${data.meta.date_start} 至 ${data.meta.date_end} · 每日快照`;
|
||
const delta=first&&latest?latest.e1e2_rate-first.e1e2_rate:0;document.getElementById('summaryText').innerHTML=`<strong>${d.length} 天累计 ${fmt(t.install)} Install,产生 ${fmt(t.e1e2)} 个 E1+E2,整体转化率 ${pct(t.e1e2_rate)}。</strong> Midas spend 为 ${money(t.midas_spend)},按每个 E1/E2 事件 $3 计算的 Payable spend 为 ${money(t.payable_spend)}。窗口首尾 E1+E2% ${delta>=0?'上升':'下降'} ${Math.abs(delta).toFixed(2)} 个百分点;由于仅有 ${d.length} 天数据,应作为短期交付快照解读。`;
|
||
const cards=[['Install',fmt(t.install),'af_app_opened repostback'],['E1 + E2',fmt(t.e1e2),`${fmt(t.event1)} E1 · ${fmt(t.event2)} E2`],['E1+E2%',pct(t.e1e2_rate),'累计 E1+E2 ÷ 累计 Install'],['Payable spend',money(t.payable_spend),`Midas spend ${money(t.midas_spend)}`]];document.getElementById('cards').innerHTML=cards.map(x=>`<div class="card"><div class="label">${x[0]}</div><div class="value">${x[1]}</div><div class="note">${x[2]}</div></div>`).join('');
|
||
bars(document.getElementById('deliveryChart'),d,[{key:'install',color:'var(--blue)',format:fmt},{key:'event1',color:'var(--gold)',format:fmt},{key:'event2',color:'var(--orange)',format:fmt}],Math.max(...d.flatMap(x=>[x.install,x.event1,x.event2]),1));
|
||
bars(document.getElementById('rateChart'),d,[{key:'e1e2_rate',color:'var(--orange)',format:pct}],Math.max(...d.map(x=>x.e1e2_rate||0),1));
|
||
bars(document.getElementById('spendChart'),d,[{key:'midas_spend',color:'var(--blue)',format:money},{key:'payable_spend',color:'var(--gold)',format:money}],Math.max(...d.flatMap(x=>[x.midas_spend,x.payable_spend]),1));
|
||
const gap=t.payable_spend-t.midas_spend;document.getElementById('spendText').innerHTML=`<strong>累计 Payable spend ${gap>=0?'高于':'低于'} Midas spend ${money(Math.abs(gap))}。</strong> 该差额来自约定的事件计费公式与平台实际消耗之间的口径差异,不应直接解读为利润。`;
|
||
document.getElementById('rows').innerHTML=d.slice().reverse().map(x=>`<tr><td>${x.date}</td><td>${fmt(x.install)}</td><td>${fmt(x.event1)}</td><td>${fmt(x.event2)}</td><td>${pct(x.e1e2_rate)}</td><td>${money(x.midas_spend)}</td><td>${money(x.payable_spend)}</td></tr>`).join('');
|
||
}).catch(e=>{document.getElementById('summaryText').className='error';document.getElementById('summaryText').textContent='数据载入失败:'+e.message});
|
||
</script></body></html>
|