refactor: simplify MTG financial metrics

This commit is contained in:
王源
2026-10-14 18:50:29 +08:00
parent 839ccfc68e
commit 82e7250b4d
+6 -13
View File
@@ -504,7 +504,6 @@
summary.append( summary.append(
kpi('Valid Clicks', nf.format(data.meta.valid_clicks), `${nf.format(data.meta.rows)} 条明细`), kpi('Valid Clicks', nf.format(data.meta.valid_clicks), `${nf.format(data.meta.rows)} 条明细`),
kpi('Postback Installs', nf.format(data.meta.installs), `安装率 ${data.meta.install_rate === null ? '-' : percent(data.meta.install_rate)}`), kpi('Postback Installs', nf.format(data.meta.installs), `安装率 ${data.meta.install_rate === null ? '-' : percent(data.meta.install_rate)}`),
kpi('Revenue', money(data.meta.revenue), `利润 ${money(data.meta.profit)}`, 'success'),
kpi('Cost', money(data.meta.cost), `${nf.format(data.meta.matched_order_rows)} 条已关联订单`), kpi('Cost', money(data.meta.cost), `${nf.format(data.meta.matched_order_rows)} 条已关联订单`),
kpi('ROAS', data.meta.roas === null ? '-' : percent(data.meta.roas), `${nf.format(data.meta.unmatched_order_rows)} 条未关联订单`) kpi('ROAS', data.meta.roas === null ? '-' : percent(data.meta.roas), `${nf.format(data.meta.unmatched_order_rows)} 条未关联订单`)
); );
@@ -521,11 +520,10 @@
const sort = selectControl('mtgSort', ''); const sort = selectControl('mtgSort', '');
[ [
['cost-desc','Cost:高到低'], ['cost-asc','Cost:低到高'], ['cost-desc','Cost:高到低'], ['cost-asc','Cost:低到高'],
['revenue-desc','Revenue:高到低'], ['revenue-asc','Revenue:低到高'],
['valid_clicks-desc','Clicks:高到低'], ['valid_clicks-asc','Clicks:低到高'], ['valid_clicks-desc','Clicks:高到低'], ['valid_clicks-asc','Clicks:低到高'],
['installs-desc','Installs:高到低'], ['installs-asc','Installs:低到高'], ['installs-desc','Installs:高到低'], ['installs-asc','Installs:低到高'],
['roas-desc','ROAS:高到低'], ['roas-asc','ROAS:低到高'], ['roas-desc','ROAS:高到低'], ['roas-asc','ROAS:低到高'],
['profit-desc','利润:高到低'], ['adpingid-asc','Adping ID:升序'], ['pkg-asc','Pkg:A-Z'] ['adpingid-asc','Adping ID:升序'], ['pkg-asc','Pkg:A-Z']
].forEach(([value,label]) => sort.append(new Option(`排序 · ${label}`, value))); ].forEach(([value,label]) => sort.append(new Option(`排序 · ${label}`, value)));
const exportButton = el('button', 'button', '导出 MTG 数据'); const exportButton = el('button', 'button', '导出 MTG 数据');
exportButton.id = 'mtgExport'; exportButton.type = 'button'; exportButton.id = 'mtgExport'; exportButton.type = 'button';
@@ -630,9 +628,8 @@
}; };
setCard(0, nf.format(clicks), `${nf.format(mtgState.filtered.length)} 条筛选明细`); setCard(0, nf.format(clicks), `${nf.format(mtgState.filtered.length)} 条筛选明细`);
setCard(1, nf.format(installs), `安装率 ${clicks ? percent(installs / clicks) : '-'}`); setCard(1, nf.format(installs), `安装率 ${clicks ? percent(installs / clicks) : '-'}`);
setCard(2, money(revenue), `利润 ${money(revenue - cost)}`); setCard(2, money(cost), `${nf.format(matchedRows)} 条已关联订单`);
setCard(3, money(cost), `${nf.format(matchedRows)} 条已关联订单`); setCard(3, cost ? percent(revenue / cost) : '-', `${nf.format(unmatchedRows)} 条未关联订单`);
setCard(4, cost ? percent(revenue / cost) : '-', `${nf.format(unmatchedRows)} 条未关联订单`);
const meta = panel.querySelector('.result-meta'); const meta = panel.querySelector('.result-meta');
meta.textContent = ''; meta.textContent = '';
@@ -645,12 +642,12 @@
wrap.textContent = ''; wrap.textContent = '';
const table = el('table'); const table = el('table');
const thead = el('thead'); const header = el('tr'); const thead = el('thead'); const header = el('tr');
['Adping ID', 'Pkg', '国家', 'Valid Clicks', 'Postback Installs', '安装率', 'Revenue', 'Cost', '利润', 'ROAS', '订单关联', 'TaurusxDSP 状态'] ['Adping ID', 'Pkg', '国家', 'Valid Clicks', 'Postback Installs', '安装率', 'Cost', 'ROAS', '订单关联', 'TaurusxDSP 状态']
.forEach(label => header.append(el('th', '', label))); .forEach(label => header.append(el('th', '', label)));
thead.append(header); table.append(thead); thead.append(header); table.append(thead);
const tbody = el('tbody'); const tbody = el('tbody');
if (!rows.length) { if (!rows.length) {
const cell = el('td', 'empty', '没有符合当前条件的 MTG 记录'); cell.colSpan = 12; const cell = el('td', 'empty', '没有符合当前条件的 MTG 记录'); cell.colSpan = 10;
const row = el('tr'); row.append(cell); tbody.append(row); const row = el('tr'); row.append(cell); tbody.append(row);
} }
rows.forEach(record => { rows.forEach(record => {
@@ -668,9 +665,7 @@
el('td', '', nf.format(record.valid_clicks)), el('td', '', nf.format(record.valid_clicks)),
el('td', '', nf.format(record.installs)), el('td', '', nf.format(record.installs)),
el('td', '', record.install_rate === null ? '-' : percent(record.install_rate)), el('td', '', record.install_rate === null ? '-' : percent(record.install_rate)),
el('td', '', money(record.revenue)),
el('td', '', money(record.cost)), el('td', '', money(record.cost)),
el('td', '', money(record.profit)),
el('td', '', record.roas === null ? '-' : percent(record.roas)), el('td', '', record.roas === null ? '-' : percent(record.roas)),
orderStatus, orderStatus,
targetStatus targetStatus
@@ -689,7 +684,7 @@
} }
function exportMtgCsv() { function exportMtgCsv() {
const headers = ['Adping ID', 'Pkg', '国家', 'Valid Clicks', 'Postback Installs', '安装率', 'Revenue', 'Cost', '利润', 'ROAS', '订单关联', 'TaurusxDSP状态']; const headers = ['Adping ID', 'Pkg', '国家', 'Valid Clicks', 'Postback Installs', '安装率', 'Cost', 'ROAS', '订单关联', 'TaurusxDSP状态'];
const rows = [headers, ...mtgState.filtered.map(record => [ const rows = [headers, ...mtgState.filtered.map(record => [
record.adpingid, record.adpingid,
record.pkg, record.pkg,
@@ -697,9 +692,7 @@
record.valid_clicks, record.valid_clicks,
record.installs, record.installs,
record.install_rate === null ? '' : record.install_rate, record.install_rate === null ? '' : record.install_rate,
record.revenue,
record.cost, record.cost,
record.profit,
record.roas === null ? '' : record.roas, record.roas === null ? '' : record.roas,
record.order_match ? (record.adpingid_match ? 'ID已匹配' : '仅Pkg_国家匹配') : '未关联', record.order_match ? (record.adpingid_match ? 'ID已匹配' : '仅Pkg_国家匹配') : '未关联',
mtgMatchStatus(record).label mtgMatchStatus(record).label