feat: add Campaign ID detail module (campid -> pkg + geo + channel)
This commit is contained in:
+70
-2
@@ -442,6 +442,36 @@
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 模块3:Campaign ID 明细 -->
|
||||
<div class="table-section" style="margin-top:24px;">
|
||||
<h2>Campaign ID 明细(唯一识别值)</h2>
|
||||
<div class="controls" style="box-shadow:none;padding:0 0 14px;background:transparent;">
|
||||
<div class="control-group">
|
||||
<label>产品</label>
|
||||
<select id="campProductFilter"><option value="all">全部</option></select>
|
||||
</div>
|
||||
<div class="control-group">
|
||||
<label>渠道</label>
|
||||
<select id="campChannelFilter"><option value="all">全部</option></select>
|
||||
</div>
|
||||
</div>
|
||||
<div class="table-wrapper">
|
||||
<table id="campaignTable">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Campaign ID</th>
|
||||
<th>Product</th>
|
||||
<th>Pkg / 包名</th>
|
||||
<th>投放国家</th>
|
||||
<th>渠道</th>
|
||||
<th>投放方式</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody></tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div><!-- /tab-orders -->
|
||||
|
||||
<div class="updated-time" id="updatedTime"></div>
|
||||
@@ -455,16 +485,19 @@
|
||||
|
||||
let rawData = [];
|
||||
let orderData = [];
|
||||
let campaignData = [];
|
||||
let charts = {};
|
||||
|
||||
async function loadData() {
|
||||
try {
|
||||
const [dResp, oResp] = await Promise.all([
|
||||
const [dResp, oResp, cResp] = await Promise.all([
|
||||
fetch('data.json?' + Date.now()),
|
||||
fetch('orders.json?' + Date.now())
|
||||
fetch('orders.json?' + Date.now()),
|
||||
fetch('campaigns.json?' + Date.now())
|
||||
]);
|
||||
rawData = await dResp.json();
|
||||
orderData = await oResp.json();
|
||||
campaignData = await cResp.json();
|
||||
init();
|
||||
} catch(e) {
|
||||
console.error('Failed to load data:', e);
|
||||
@@ -475,6 +508,7 @@
|
||||
populateFilters();
|
||||
renderAll();
|
||||
renderOrders();
|
||||
renderCampaigns();
|
||||
setupTabs();
|
||||
document.getElementById('pkgFilter').addEventListener('change', renderAll);
|
||||
document.getElementById('dateFilter').addEventListener('change', renderAll);
|
||||
@@ -595,6 +629,40 @@
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function renderCampaigns() {
|
||||
// 填充筛选器
|
||||
const prods = [...new Set(campaignData.map(c => c.product))].sort();
|
||||
const chans = [...new Set(campaignData.map(c => c.channel))].sort();
|
||||
const pf = document.getElementById('campProductFilter');
|
||||
const cf = document.getElementById('campChannelFilter');
|
||||
prods.forEach(p => { const o=document.createElement('option'); o.value=p; o.textContent=p; pf.appendChild(o); });
|
||||
chans.forEach(c => { const o=document.createElement('option'); o.value=c; o.textContent=c; cf.appendChild(o); });
|
||||
pf.addEventListener('change', drawCampaignRows);
|
||||
cf.addEventListener('change', drawCampaignRows);
|
||||
drawCampaignRows();
|
||||
}
|
||||
|
||||
function drawCampaignRows() {
|
||||
const pf = document.getElementById('campProductFilter').value;
|
||||
const cf = document.getElementById('campChannelFilter').value;
|
||||
let data = campaignData;
|
||||
if (pf !== 'all') data = data.filter(c => c.product === pf);
|
||||
if (cf !== 'all') data = data.filter(c => c.channel === cf);
|
||||
|
||||
const modeColor = m => m === '自投' ? 'status-active' : (m === '代投' ? 'status-pause' : '');
|
||||
const tbody = document.querySelector('#campaignTable tbody');
|
||||
tbody.innerHTML = data.map(c => `
|
||||
<tr>
|
||||
<td class="num-cell" style="font-weight:600;color:#4338ca;">${c.campid}</td>
|
||||
<td style="font-weight:500">${c.product}</td>
|
||||
<td class="num-cell" style="font-size:11px">${c.pkg}</td>
|
||||
<td><span class="pkg-tag">${c.geo}</span></td>
|
||||
<td>${c.channel}</td>
|
||||
<td><span class="status-badge ${modeColor(c.mode)}" style="padding:2px 8px;font-size:10px;">${c.mode}</span></td>
|
||||
</tr>
|
||||
`).join('');
|
||||
}
|
||||
|
||||
function populateFilters() {
|
||||
const pkgs = [...new Set(rawData.map(d => d.pkg))];
|
||||
const sel = document.getElementById('pkgFilter');
|
||||
|
||||
Reference in New Issue
Block a user