diff --git a/index.html b/index.html index e1b0dc5..a03ac88 100644 --- a/index.html +++ b/index.html @@ -501,9 +501,18 @@ const match = selectControl('mtgMatch', ''); [['all','全部关联状态'], ['matched','已关联订单'], ['missing','关联且待搬单'], ['covered','关联且已覆盖'], ['unmatched','未关联订单']] .forEach(([value,label]) => match.append(new Option(label, value))); + const sort = selectControl('mtgSort', ''); + [ + ['cost-desc','Cost:高到低'], ['cost-asc','Cost:低到高'], + ['revenue-desc','Revenue:高到低'], ['revenue-asc','Revenue:低到高'], + ['valid_clicks-desc','Clicks:高到低'], ['valid_clicks-asc','Clicks:低到高'], + ['installs-desc','Installs:高到低'], ['installs-asc','Installs:低到高'], + ['roas-desc','ROAS:高到低'], ['roas-asc','ROAS:低到高'], + ['profit-desc','利润:高到低'], ['adpingid-asc','Adping ID:升序'], ['pkg-asc','Pkg:A-Z'] + ].forEach(([value,label]) => sort.append(new Option(`排序 · ${label}`, value))); const exportButton = el('button', 'button', '导出 MTG 数据'); exportButton.id = 'mtgExport'; exportButton.type = 'button'; - filters.append(search, country, match, exportButton); + filters.append(search, country, match, sort, exportButton); header.append(head, summary, filters); panel.append(header, el('div', 'result-meta'), el('div', 'table-wrap'), el('div', 'pagination')); @@ -513,6 +522,7 @@ search.addEventListener('input', () => { mtgState.page = 1; applyMtgFilters(); }); country.addEventListener('change', () => { mtgState.page = 1; applyMtgFilters(); }); match.addEventListener('change', () => { mtgState.page = 1; applyMtgFilters(); }); + sort.addEventListener('change', () => { mtgState.page = 1; applyMtgFilters(); }); ['search', 'countryFilter', 'platformFilter', 'statusFilter'].forEach(id => { const control = document.getElementById(id); control.addEventListener(id === 'search' ? 'input' : 'change', () => { @@ -528,6 +538,8 @@ const query = document.getElementById('mtgSearch').value.trim().toLocaleLowerCase(); const country = document.getElementById('mtgCountry').value; const match = document.getElementById('mtgMatch').value; + const sortControl = document.getElementById('mtgSort'); + const sort = sortControl.value; const mainSearch = document.getElementById('search').value.trim().toLocaleLowerCase(); const mainCountry = document.getElementById('countryFilter').value; const mainPlatform = document.getElementById('platformFilter').value; @@ -554,6 +566,22 @@ && (mainStatus === 'all' || coverageStatus === mainStatus); }); + const [field, direction] = sort.split('-'); + const multiplier = direction === 'asc' ? 1 : -1; + mtgState.filtered.sort((left, right) => { + const a = left[field]; + const b = right[field]; + if (a === null && b !== null) return 1; + if (a !== null && b === null) return -1; + if (typeof a === 'string' || typeof b === 'string') { + const result = String(a).localeCompare(String(b), undefined, { numeric: true, sensitivity: 'base' }); + return result * multiplier || left.adpingid.localeCompare(right.adpingid, undefined, { numeric: true }); + } + return (Number(a) - Number(b)) * multiplier + || left.adpingid.localeCompare(right.adpingid, undefined, { numeric: true }); + }); + mtgState.sortLabel = sortControl.options[sortControl.selectedIndex].text.replace('排序 · ', ''); + const linked = [mainStatusControl.options[mainStatusControl.selectedIndex].text]; if (mainCountry !== 'all') linked.push(`国家 ${mainCountry}`); if (mainPlatform !== 'all') linked.push(`平台 ${mainPlatform}`);