60 lines
3.6 KiB
JavaScript
60 lines
3.6 KiB
JavaScript
// 机器复核:从原始接口响应重算所有派生数字
|
|
import fs from 'node:fs';
|
|
import path from 'node:path';
|
|
|
|
const dir = path.resolve('.cdp/out/api');
|
|
const raw = fs.readFileSync(path.join(dir, '30d-08.txt'), 'utf8');
|
|
const json = JSON.parse(raw.slice(raw.indexOf('\n\n') + 2).trim());
|
|
|
|
const g = json.data.data.graphBannerBenchData;
|
|
const range = json.data.extendInfo.realDateRange;
|
|
const all = g.graphDataList;
|
|
console.log('realDateRange =', range, ' graphDataList len =', all.length);
|
|
|
|
const rows = all.filter(r => r.ds >= range[0] && r.ds <= range[1]);
|
|
console.log('clipped rows =', rows.length, ' from', rows[0].ds, 'to', rows[rows.length - 1].ds);
|
|
|
|
const sum = (a, k) => a.reduce((x, y) => x + (Number(y[k]) || 0), 0);
|
|
const fmt = (n, d = 2) => n.toFixed(d);
|
|
|
|
console.log('\n--- 校验 vs banner ---');
|
|
console.log('payAmt calc=' + fmt(sum(rows, 'payAmt')) + ' banner=' + g.bannerDataList.find(b => b.name === 'payAmt')?.dataStr);
|
|
console.log('payOrdCnt calc=' + sum(rows, 'payOrdCnt') + ' banner=' + g.bannerDataList.find(b => b.name === 'payOrdCnt')?.dataStr);
|
|
console.log('showPv calc=' + sum(rows, 'showPv') + ' banner=' + g.bannerDataList.find(b => b.name === 'showPv')?.dataStr);
|
|
|
|
const half = Math.floor(rows.length / 2);
|
|
const A = rows.slice(0, half), B = rows.slice(half);
|
|
console.log('\n--- 前后半月 ---');
|
|
console.log(`前半 ${A[0].ds}~${A[A.length-1].ds} (${A.length}天): ${sum(A,'payOrdCnt')} 单 / ¥${fmt(sum(A,'payAmt'))} / 日均 ¥${fmt(sum(A,'payAmt')/A.length)}`);
|
|
console.log(`后半 ${B[0].ds}~${B[B.length-1].ds} (${B.length}天): ${sum(B,'payOrdCnt')} 单 / ¥${fmt(sum(B,'payAmt'))} / 日均 ¥${fmt(sum(B,'payAmt')/B.length)}`);
|
|
const pct = (a, b) => ((b - a) / a * 100).toFixed(1);
|
|
console.log(`变化: 单量 ${pct(sum(A,'payOrdCnt'), sum(B,'payOrdCnt'))}% 金额 ${pct(sum(A,'payAmt'), sum(B,'payAmt'))}%`);
|
|
|
|
console.log('\n--- 5天一组 ---');
|
|
for (let i = 0; i < rows.length; i += 5) {
|
|
const blk = rows.slice(i, i + 5);
|
|
console.log(`${blk[0].ds}~${blk[blk.length-1].ds}: ${String(sum(blk,'payOrdCnt')).padStart(3)} 单 / ¥${fmt(sum(blk,'payAmt')).padStart(8)} / 曝光 ${String(sum(blk,'showPv')).padStart(6)} / 日均 ¥${fmt(sum(blk,'payAmt')/blk.length)}`);
|
|
}
|
|
|
|
console.log('\n--- 近7天窗口 10-26~11-01 ---');
|
|
const w = rows.filter(r => r.ds >= '20261026');
|
|
console.log(`${sum(w,'payOrdCnt')} 单 / ¥${fmt(sum(w,'payAmt'))} / 曝光 ${sum(w,'showPv')} / 询单 ${sum(w,'chatUv')}`);
|
|
|
|
console.log('\n--- 极值(46天窗口)---');
|
|
const top = [...all].sort((a, b) => b.payAmt - a.payAmt).slice(0, 3);
|
|
const bot = [...all].sort((a, b) => a.payAmt - b.payAmt).slice(0, 3);
|
|
console.log('最高: ' + top.map(r => `${r.ds} ¥${r.payAmt}/${r.payOrdCnt}单`).join(' '));
|
|
console.log('最低: ' + bot.map(r => `${r.ds} ¥${r.payAmt}/${r.payOrdCnt}单`).join(' '));
|
|
const top30 = [...rows].sort((a, b) => b.payAmt - a.payAmt)[0];
|
|
console.log('近30天最高: ' + `${top30.ds} ¥${top30.payAmt}/${top30.payOrdCnt}单`);
|
|
|
|
console.log('\n--- 响应率 ---');
|
|
const wk = rows.filter(r => ['20261003','20261004','20261010','20261011','20261017','20261018','20261024','20261025','20261031','20261101'].includes(r.ds));
|
|
const wd = rows.filter(r => !wk.includes(r));
|
|
const avg = a => (a.reduce((x, y) => x + (y.rep3minUvRate || 0), 0) / a.length * 100).toFixed(1);
|
|
console.log(`周末均值 ${avg(wk)}% (${wk.length}天) 工作日均值 ${avg(wd)}% (${wd.length}天)`);
|
|
console.log('11-01: ' + rows[rows.length-1].rep3minUvRate * 100 + '% 询单=' + rows[rows.length-1].chatUv);
|
|
|
|
console.log('\n--- 商品效率 ---');
|
|
console.log('在线商品 11-01 =', rows[rows.length-1].onlCnt, ' 期初 =', rows[0].onlCnt);
|