Files
ObsidianHome/小鱼/.cdp/ov-daily.mjs
T

69 lines
2.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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');