import fs from 'node:fs'; const j = JSON.parse(fs.readFileSync('.cdp/out/overview-capture.json', 'utf8')); const bodies = j.value.rawBodies; let best = null; for (const b of bodies) { if (!/singleuser\.seller\.summary/.test(b.url)) continue; const p = JSON.parse(b.text); const g = p?.data?.data?.graphBannerBenchData?.graphDataList; if (Array.isArray(g) && (!best || g.length > best.length)) best = g; } const rows = best.slice().sort((a, b) => a.ds.localeCompare(b.ds)); const N = v => Number(v) || 0; const L = []; L.push('逐日序列(' + rows.length + ' 天,' + rows[0].ds + ' ~ ' + rows[rows.length - 1].ds + ')'); L.push(''); L.push('日期 | 支付单 | 支付额 | 客单 | 曝光次数 | 曝光人数 | 浏览人数 | 询单人数 | 点击率 | 响应率 | 动销 | 在线'); L.push('---|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:|---:'); for (const r of rows) { L.push([ r.ds, N(r.payOrdCnt), N(r.payAmt).toFixed(2), N(r.aov).toFixed(2), N(r.showPv), N(r.showUv), N(r.ipvUv), N(r.chatUv), (N(r.uctr) * 100).toFixed(2) + '%', (N(r.rep3minUvRate) * 100).toFixed(0) + '%', N(r.stItmCnt), N(r.onlCnt), ].join(' | ')); } // 分段汇总 const agg = (from, to) => { const sel = rows.filter(r => r.ds >= from && r.ds <= to); const s = f => sel.reduce((a, b) => a + N(b[f]), 0); return { days: sel.length, ord: s('payOrdCnt'), amt: s('payAmt'), pv: s('showPv'), uv: s('showUv'), ipvUv: s('ipvUv'), chat: s('chatUv'), aov: s('payAmt') / (s('payOrdCnt') || 1), rep: s('rep3minUvRate') / (sel.length || 1), }; }; const last = rows[rows.length - 1].ds; const seg = (n, offset) => { const end = rows.length - 1 - offset; const start = end - n + 1; return agg(rows[Math.max(0, start)].ds, rows[end].ds); }; L.push(''); L.push('=== 分段对比(按天) ==='); const p1 = seg(7, 0), p2 = seg(7, 7), p3 = seg(7, 14); const fmt = (t, x) => `${t}: ${x.days}天 | 单 ${x.ord} (日均 ${(x.ord / x.days).toFixed(1)}) | 额 ¥${x.amt.toFixed(2)} (日均 ¥${(x.amt / x.days).toFixed(1)}) | 客单 ¥${x.aov.toFixed(2)} | 曝光次数 ${x.pv} | 曝光人数 ${x.uv} | 浏览人 ${x.ipvUv} | 询单 ${x.chat} | 响应率 ${(x.rep * 100).toFixed(0)}%`; L.push(fmt('最近7天', p1)); L.push(fmt('前7天 ', p2)); L.push(fmt('再前7天', p3)); L.push(''); const d = (a, b) => b ? (((a - b) / b) * 100).toFixed(1) + '%' : '-'; L.push('最近7天 vs 前7天: 单 ' + d(p1.ord, p2.ord) + ' | 额 ' + d(p1.amt, p2.amt) + ' | 曝光次数 ' + d(p1.pv, p2.pv) + ' | 浏览人 ' + d(p1.ipvUv, p2.ipvUv) + ' | 询单 ' + d(p1.chat, p2.chat)); L.push('前7天 vs 再前7天: 单 ' + d(p2.ord, p3.ord) + ' | 额 ' + d(p2.amt, p3.amt) + ' | 曝光次数 ' + d(p2.pv, p3.pv) + ' | 浏览人 ' + d(p2.ipvUv, p3.ipvUv) + ' | 询单 ' + d(p2.chat, p3.chat)); fs.writeFileSync('.cdp/out/ov-daily.txt', L.join('\n'), 'utf8');