(() => { const templates = window.LINK_TEMPLATES; if (!templates?.length) return; const { convertTrackingLink } = window.TrackingLinkConverter; const HISTORY_KEY = 'traffic_link_history_v1'; const MAX_HISTORY = 50; const $ = (id) => document.getElementById(id); const platformSelect = $('platformSelect'); const macroBody = $('macroTableBody'); const output = $('urlOutput'); let activeResult = null; let history = loadHistory(); let inputTimer; $('templateCount').textContent = `${templates.length} 个平台模板`; templates.forEach((template, index) => platformSelect.add(new Option(template.name, index))); const activeTemplate = () => templates[Number(platformSelect.value || 0)]; function renderPlatform() { const template = activeTemplate(); const review = template.status.includes('待'); $('platformStatus').innerHTML = `${escapeHtml(template.status)}`; renderMacros(); if ($('originalLink').value.trim()) convertFromInput(false); } function renderMacros() { const query = $('macroSearch').value.trim().toLowerCase(); const allMacros = activeTemplate().macros; const rows = allMacros.filter(([macro, desc]) => `${macro} ${desc}`.toLowerCase().includes(query)); $('macroCount').textContent = `${allMacros.length} 个可用宏 · 点击展开`; macroBody.innerHTML = rows.length ? rows.map(([macro, desc]) => `${escapeHtml(macro)}${escapeHtml(desc)}`).join('') : '没有匹配的媒体宏'; } function renderChanges(changes) { const rows = changes.length ? changes : [{ key:'—', from:'原链接参数无需变化', to:'—' }]; $('mappingTableBody').innerHTML = rows.map((change) => ` ${escapeHtml(change.key)} ${escapeHtml(change.from || '(空值)')} ${change.to ? `${escapeHtml(change.to)}` : '留空'} `).join(''); } function showEmpty() { activeResult = null; $('conversionEmpty').classList.remove('hidden'); $('conversionResult').classList.add('hidden'); $('detectedType').textContent = '等待链接'; $('generatorMessage').textContent = ''; $('copyStatus').textContent = ''; $('copyLink').disabled = true; } function showError(message) { activeResult = null; $('generatorMessage').textContent = message; $('conversionEmpty').classList.remove('hidden'); $('conversionResult').classList.add('hidden'); $('detectedType').textContent = '无法识别'; $('copyLink').disabled = true; } function convertFromInput(showRequiredMessage = true) { const original = $('originalLink').value.trim(); $('copyStatus').textContent = ''; if (!original) { showEmpty(); if (showRequiredMessage) $('generatorMessage').textContent = '请先粘贴一条完整的 Tracking Link'; return null; } try { const result = convertTrackingLink(original, activeTemplate()); activeResult = result; const typeLabel = result.type === 'imp' ? 'Impression' : 'Click'; $('detectedType').innerHTML = `${typeLabel}`; $('summaryType').textContent = typeLabel; $('replacementCount').textContent = result.changes.length; $('preservedCount').textContent = result.preservedCount; $('urlLength').textContent = `${result.url.length} chars`; output.textContent = result.url; renderChanges(result.changes); $('generatorMessage').textContent = result.changes.length ? '' : '链接有效,但没有发现需要替换的参数'; $('conversionEmpty').classList.add('hidden'); $('conversionResult').classList.remove('hidden'); $('copyLink').disabled = false; return result; } catch (error) { showError(error.message === 'Invalid URL' ? '链接格式不正确,请粘贴包含 http:// 或 https:// 的完整链接' : error.message); return null; } } function convertAndSave() { const result = convertFromInput(true); if (!result) return; saveHistory(result); $('generatorMessage').textContent = '转换完成,已加入平台链接总结'; showToast('转换完成并已保存记录'); } function loadSample() { $('originalLink').value = 'https://trident.bigpinggo.com/l/click?advid=30&campid=91566789&platform=M_API_Self_Mintegral&pkg=com.salaryse.android&clickid={click_id}&offer_name={offer_name}&creative_id={creative_id}&creative_name={creative_name}&affiliate_id={affiliate_id}&idfa={idfa}&gaid={gaid}&imei={imei}&android_id={android_id}&mac={mac}&oaid={oaid}&uagent={ua}&os_platform={os_platform}&os_version={os_version}&device_model={device_model}&ip={ip}&country_code={country_code}&ext={ext}&rta_token={rta_token}&san_campid=91566789&adset_id=-1&c_cto=0'; convertFromInput(false); } function loadHistory() { try { const stored = JSON.parse(localStorage.getItem(HISTORY_KEY) || '[]'); return Array.isArray(stored) ? stored.filter((item) => item?.id && item?.url).slice(0, MAX_HISTORY) : []; } catch (_) { return []; } } function persistHistory() { try { localStorage.setItem(HISTORY_KEY, JSON.stringify(history)); return true; } catch (_) { showToast('浏览器无法保存记录,请检查存储权限'); return false; } } function extractPkg(url) { try { return new URL(url).searchParams.get('pkg') || '—'; } catch (_) { return '—'; } } function saveHistory(result) { const platform = activeTemplate().name; const pkg = extractPkg(result.url); history = history.filter((item) => item.url !== result.url); history.unshift({ id: `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`, platform, pkg, type: result.type, createdAt: new Date().toISOString(), url: result.url }); history = history.slice(0, MAX_HISTORY); persistHistory(); renderHistory(); } function formatTime(value) { const date = new Date(value); if (Number.isNaN(date.getTime())) return '—'; return new Intl.DateTimeFormat('zh-CN', { year:'numeric', month:'2-digit', day:'2-digit', hour:'2-digit', minute:'2-digit', second:'2-digit', hour12:false }).format(date); } function renderHistory() { $('historyCount').textContent = history.length; $('clearHistory').disabled = history.length === 0; $('historyEmpty').classList.toggle('hidden', history.length > 0); $('historyTableWrap').classList.toggle('hidden', history.length === 0); $('historyTableBody').innerHTML = history.map((item) => ` ${escapeHtml(item.platform)} ${escapeHtml(item.pkg)} `).join(''); } async function copyText(text) { try { await navigator.clipboard.writeText(text); } catch (_) { const area = document.createElement('textarea'); area.value = text; area.style.position = 'fixed'; area.style.opacity = '0'; document.body.appendChild(area); area.select(); document.execCommand('copy'); area.remove(); } } async function copyUrl() { if (!activeResult) return; await copyText(activeResult.url); $('copyStatus').textContent = '已复制'; showToast('转换后的平台链接已复制'); } function showToast(message) { const toast = $('toast'); toast.textContent = message; toast.classList.add('show'); clearTimeout(showToast.timer); showToast.timer = setTimeout(() => toast.classList.remove('show'), 1800); } function escapeHtml(value) { return String(value).replace(/[&<>"']/g, (char) => ({ '&':'&', '<':'<', '>':'>', '"':'"', "'":''' })[char]); } platformSelect.addEventListener('change', renderPlatform); $('macroSearch').addEventListener('input', renderMacros); $('convertLink').addEventListener('click', convertAndSave); $('sampleLink').addEventListener('click', loadSample); $('copyLink').addEventListener('click', copyUrl); $('clearConverter').addEventListener('click', () => { $('originalLink').value = ''; showEmpty(); $('originalLink').focus(); }); $('clearHistory').addEventListener('click', () => { if (!history.length || !window.confirm('确定清空全部平台链接记录吗?')) return; history = []; persistHistory(); renderHistory(); }); $('historyTableBody').addEventListener('click', async (event) => { const button = event.target.closest('button[data-action]'); if (!button) return; const item = history.find((record) => record.id === button.dataset.id); if (!item) return; if (button.dataset.action === 'copy') { await copyText(item.url); showToast('历史链接已复制'); } else if (button.dataset.action === 'delete') { history = history.filter((record) => record.id !== item.id); persistHistory(); renderHistory(); } }); $('originalLink').addEventListener('input', () => { clearTimeout(inputTimer); inputTimer = setTimeout(() => convertFromInput(false), 220); }); renderPlatform(); showEmpty(); renderHistory(); })();