(function smsBowerFloatingTool() { if (window.__smsBowerFloatingToolInstalled) { return; } window.__smsBowerFloatingToolInstalled = true; const PANEL_ID = 'smsbower-floating-phone-tool'; const FALLBACK_COUNTRIES = [ { id: 0, label: 'Russia' }, { id: 1, label: 'Ukraine' }, { id: 2, label: 'Kazakhstan' }, { id: 3, label: 'China' }, { id: 4, label: 'Philippines' }, { id: 5, label: 'Myanmar' }, { id: 6, label: 'Indonesia' }, { id: 7, label: 'Malaysia' }, { id: 10, label: 'Vietnam' }, { id: 12, label: 'USA virtual' }, { id: 16, label: 'United Kingdom' }, { id: 22, label: 'India' }, { id: 32, label: 'Romania' }, { id: 36, label: 'Canada' }, { id: 43, label: 'Germany' }, { id: 52, label: 'Thailand' }, { id: 73, label: 'France' }, { id: 78, label: 'Turkey' }, { id: 151, label: 'Japan' }, { id: 187, label: 'USA' } ]; const COUNTRY_ALIASES = { 0: '俄罗斯 俄国 Russia RU', 1: '乌克兰 Ukraine UA', 2: '哈萨克斯坦 Kazakhstan KZ', 3: '中国 China CN', 4: '菲律宾 Philippines PH', 5: '缅甸 Myanmar Burma MM', 6: '印度尼西亚 印尼 Indonesia ID', 7: '马来西亚 Malaysia MY', 10: '越南 Vietnam VN', 12: '美国虚拟 USA virtual United States US', 16: '英国 United Kingdom Britain GB UK', 22: '印度 India IN', 32: '罗马尼亚 Romania RO', 36: '加拿大 Canada CA', 43: '德国 Germany DE', 52: '泰国 Thailand TH', 73: '法国 France FR', 78: '土耳其 Turkey TR', 151: '日本 Japan JP', 187: '美国 USA United States US' }; let allCountries = FALLBACK_COUNTRIES.slice(); let selectedCountries = [{ id: 6, label: 'Indonesia' }]; let latestSettings = null; let panel = null; let dragState = null; let codePollToken = 0; let autoRotateObserver = null; let autoRotateTimer = null; let autoRotateInFlight = false; let autoRotateEnabled = true; let lastErroredPhoneNumber = ''; const AUTO_ROTATE_DEBOUNCE_MS = 800; function stopCodePolling() { codePollToken += 1; } function isVisible(el) { if (!el) return false; const style = window.getComputedStyle(el); const rect = el.getBoundingClientRect(); return style.visibility !== 'hidden' && style.display !== 'none' && rect.width > 0 && rect.height > 0; } function scoreInput(el) { const text = [el.type, el.name, el.id, el.placeholder, el.autocomplete, el.getAttribute('aria-label')].join(' ').toLowerCase(); let score = 0; if (el === document.activeElement) score += 100; if (/phone|mobile|tel|手机号|電話|电话|号码|number/.test(text)) score += 50; if (el.type === 'tel') score += 40; if (el.type === 'text' || !el.type) score += 5; if (el.readOnly || el.disabled) score -= 1000; if (!isVisible(el)) score -= 1000; return score; } function findBestInput() { const inputs = Array.from(document.querySelectorAll('input, textarea')) .filter((el) => !panel || !panel.contains(el)); const ranked = inputs.map((el) => ({ el, score: scoreInput(el) })).sort((a, b) => b.score - a.score); return ranked[0]?.score > -100 ? ranked[0].el : null; } function setValue(el, value) { el.focus(); const proto = el instanceof HTMLTextAreaElement ? HTMLTextAreaElement.prototype : HTMLInputElement.prototype; const desc = Object.getOwnPropertyDescriptor(proto, 'value'); if (desc?.set) desc.set.call(el, value); else el.value = value; el.dispatchEvent(new Event('input', { bubbles: true })); el.dispatchEvent(new Event('change', { bubbles: true })); } function fillPhone(phoneNumber) { const input = findBestInput(); if (!input) throw new Error('当前页面没有找到可填写的输入框。请先点一下目标输入框再获取。'); setValue(input, phoneNumber); return { phoneNumber, input, tag: input.tagName, name: input.name || '', id: input.id || '' }; } function scoreSubmitButton(button, input) { if (!button || panel?.contains(button)) return -1000; const style = window.getComputedStyle(button); const rect = button.getBoundingClientRect(); if (button.disabled || style.visibility === 'hidden' || style.display === 'none' || rect.width <= 0 || rect.height <= 0) return -1000; const text = [ button.innerText, button.textContent, button.value, button.name, button.id, button.getAttribute('aria-label'), button.getAttribute('title') ].join(' ').toLowerCase(); let score = 0; if (/下一步|继续|发送验证码|获取验证码|发送代码|发送短信|验证|提交|next|continue|send\s*(code|sms)?|verify|submit/.test(text)) score += 100; if (/取消|返回|back|cancel|关闭|close|skip|跳过|resend|重发/.test(text)) score -= 140; if (button.type === 'submit') score += 35; if (input) { const inputRect = input.getBoundingClientRect(); const dy = rect.top - inputRect.bottom; const dx = Math.abs((rect.left + rect.right) / 2 - (inputRect.left + inputRect.right) / 2); if (dy >= -20 && dy < 260) score += Math.max(0, 60 - dy / 5); if (dx < 360) score += Math.max(0, 30 - dx / 20); } return score; } function findSubmitButton(input) { const formButton = input?.form?.querySelector('button[type="submit"], input[type="submit"]'); const candidates = Array.from(document.querySelectorAll('button, input[type="button"], input[type="submit"], [role="button"]')) .filter((el) => !panel || !panel.contains(el)); if (formButton && !candidates.includes(formButton)) candidates.unshift(formButton); const ranked = candidates.map((el) => ({ el, score: scoreSubmitButton(el, input) })).sort((a, b) => b.score - a.score); return ranked[0]?.score > 30 ? ranked[0].el : null; } async function autoSubmitPhone(input) { await sleep(250); const button = findSubmitButton(input); if (button) { button.scrollIntoView?.({ block: 'center', inline: 'center' }); button.click(); return { method: 'button', text: String(button.innerText || button.textContent || button.value || button.getAttribute('aria-label') || '').trim().slice(0, 40) }; } const form = input?.form; if (form) { if (typeof form.requestSubmit === 'function') form.requestSubmit(); else form.dispatchEvent(new Event('submit', { bubbles: true, cancelable: true })); return { method: 'form' }; } input?.dispatchEvent(new KeyboardEvent('keydown', { key: 'Enter', code: 'Enter', bubbles: true })); input?.dispatchEvent(new KeyboardEvent('keyup', { key: 'Enter', code: 'Enter', bubbles: true })); return { method: 'enter' }; } function send(type, payload = {}) { return chrome.runtime.sendMessage({ type, payload }).then((res) => { if (!res?.ok) throw new Error(res?.error || '操作失败'); return res; }); } function normalizeCountry(country) { const id = Math.floor(Number(country?.id)); return { id, label: String(country?.label || `Country #${id}`).trim() }; } function sameCountry(a, b) { return Number(a?.id) === Number(b?.id); } function getCountrySearchText(country = {}) { const id = Math.floor(Number(country?.id)); return [country?.label, id, COUNTRY_ALIASES[id] || ''].join(' ').toLowerCase(); } function sleep(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } function $(selector) { return panel?.querySelector(selector) || null; } function setStatus(text, isError = false) { const node = $('.sb-status'); if (!node) return; node.textContent = text; node.style.color = isError ? '#fecaca' : '#bbf7d0'; } async function copyText(text) { try { await navigator.clipboard.writeText(text); } catch {} } function collectSettings() { return { provider: $('.sb-provider')?.value || 'sms-bower', apiKey: $('.sb-api-key')?.value.trim() || '', baseUrl: $('.sb-base-url')?.value.trim() || '', lubanBaseUrl: $('.sb-luban-base-url')?.value.trim() || '', fiveSimBaseUrl: $('.sb-five-sim-base-url')?.value.trim() || '', serviceCode: $('.sb-service-code')?.value.trim() || 'dr', lubanServiceId: $('.sb-luban-service-id')?.value.trim() || '', fiveSimCountry: $('.sb-five-sim-country')?.value.trim() || 'vietnam', fiveSimOperator: $('.sb-five-sim-operator')?.value.trim() || 'any', fiveSimProduct: $('.sb-five-sim-product')?.value.trim() || 'openai', minPrice: $('.sb-min-price')?.value.trim() || '', maxPrice: $('.sb-max-price')?.value.trim() || '', countries: selectedCountries, }; } async function saveSettings() { stopCodePolling(); const res = await send('SAVE_SETTINGS', collectSettings()); latestSettings = res.settings; selectedCountries = (res.settings.countries || []).map(normalizeCountry); renderCountries(); setStatus('设置已保存'); } async function refreshCountries() { stopCodePolling(); await saveSettings(); setStatus('正在刷新国家列表...'); const res = await send('FETCH_COUNTRIES'); allCountries = (res.countries || []).map(normalizeCountry).filter((c) => c.id >= 0); renderCountries(); setStatus('国家列表已刷新'); } async function fetchAndFill(options = {}) { stopCodePolling(); const btn = $('.sb-fetch'); if (btn) btn.disabled = true; try { if (!options.skipSave) await saveSettings(); const reason = options.reason || 'manual_replace'; const releaseAction = options.releaseAction || (reason === 'phone_number_used' ? 'ban' : 'cancel'); setStatus(releaseAction === 'ban' ? '正在释放被拒号码并获取新号...' : '正在取消上一个激活并获取新号...'); const res = await send('FETCH_NEXT_PHONE', { reason, releaseAction }); const phone = res.activation.phoneNumber; await copyText(phone); const filled = fillPhone(phone); $('.sb-current-phone').textContent = phone; lastErroredPhoneNumber = ''; $('.sb-current-id').textContent = res.activation.activationId; const codeNode = $('.sb-current-code'); if (codeNode) codeNode.textContent = '无'; const submit = await autoSubmitPhone(filled.input); setStatus(`已切换、填入、复制并自动提交:${phone}${submit.text ? `(${submit.text})` : ''}`); } catch (error) { setStatus(error.message || String(error), true); } finally { if (btn) btn.disabled = false; } } function getPageTextForPhoneError() { const clone = document.body?.cloneNode(true); if (!clone) return ''; clone.querySelector(`#${PANEL_ID}`)?.remove(); return String(clone.innerText || clone.textContent || '').slice(-12000); } function updateAutoRotateToggle() { const btn = $('.sb-auto-toggle'); if (!btn) return; btn.textContent = autoRotateEnabled ? '自动切号:开' : '自动切号:关'; btn.classList.toggle('sb-auto-on', autoRotateEnabled); } function updateProviderFields() { const provider = $('.sb-provider')?.value || 'sms-bower'; const isLuban = provider === 'luban-sms'; panel?.querySelectorAll('.sb-smsbower-only').forEach((el) => { el.style.display = isLuban ? 'none' : ''; }); panel?.querySelectorAll('.sb-luban-only').forEach((el) => { el.style.display = isLuban ? '' : 'none'; }); } function getCurrentPhoneNumber() { const phone = $('.sb-current-phone')?.textContent || latestSettings?.activeActivation?.phoneNumber || ''; return String(phone).trim(); } async function rotateFromClassifiedError(classified, source = 'manual') { const currentPhone = getCurrentPhoneNumber(); if (autoRotateInFlight) return false; if (source === 'auto' && (!currentPhone || currentPhone === '无')) return false; if (source === 'auto' && currentPhone === lastErroredPhoneNumber) return false; autoRotateInFlight = true; try { lastErroredPhoneNumber = currentPhone; setStatus(source === 'auto' ? `当前号码 ${currentPhone} 触发${classified.reason === 'phone_number_used' ? '已使用' : '验证码发送失败'},正在自动切下一个号...` : '检测到手机号错误,正在切号...'); await fetchAndFill({ reason: classified.reason, releaseAction: classified.releaseAction, skipSave: true }); return true; } finally { autoRotateInFlight = false; } } async function detectAndRotate(source = 'manual') { const text = getPageTextForPhoneError(); const classified = await send('CLASSIFY_PHONE_ERROR', { text }); if (!classified.matched) { if (source !== 'auto') setStatus('未检测到明确的手机号错误。', true); return false; } return rotateFromClassifiedError(classified, source); } function scheduleAutoRotateCheck() { if (!autoRotateEnabled || autoRotateInFlight) return; if (autoRotateTimer) clearTimeout(autoRotateTimer); autoRotateTimer = setTimeout(() => { autoRotateTimer = null; detectAndRotate('auto').catch((error) => setStatus(error.message || String(error), true)); }, AUTO_ROTATE_DEBOUNCE_MS); } function startAutoRotateObserver() { if (autoRotateObserver) return; autoRotateObserver = new MutationObserver((mutations) => { if (!autoRotateEnabled) return; if (mutations.some((m) => m.target && panel && panel.contains(m.target))) return; scheduleAutoRotateCheck(); }); if (document.body) { autoRotateObserver.observe(document.body, { childList: true, subtree: true, characterData: true }); } window.addEventListener('focus', scheduleAutoRotateCheck); } async function cancelActive() { stopCodePolling(); try { setStatus('正在取消当前激活...'); await send('CANCEL_ACTIVE'); $('.sb-current-phone').textContent = '无'; $('.sb-current-id').textContent = '无'; const codeNode = $('.sb-current-code'); if (codeNode) codeNode.textContent = '无'; setStatus('当前激活已取消'); } catch (error) { setStatus(error.message || String(error), true); } } async function fetchAndCopyCode() { stopCodePolling(); const token = codePollToken; const btn = $('.sb-code'); if (btn) { btn.disabled = true; btn.textContent = '获取中...'; } try { let round = 0; while (token === codePollToken) { round += 1; setStatus(`正在查询验证码,第 ${round} 次...`); try { const res = await send('FETCH_ACTIVE_CODE'); if (token !== codePollToken) return; const codeNode = $('.sb-current-code'); if (codeNode) codeNode.textContent = res.code || '无'; setStatus(`已获取验证码:${res.code}`); return; } catch (error) { if (token !== codePollToken) return; const message = error.message || String(error); if (/未知消息\s*[::]\s*FETCH_ACTIVE_CODE/i.test(message)) { throw new Error('后台脚本还是旧版,没加载验证码接口。请到扩展管理页点“重新加载”,然后刷新当前网页并重新打开悬浮窗。'); } if (/验证码还没到|STATUS_WAIT_CODE|NO_CODE|WAIT/i.test(message)) { setStatus(`验证码还没到,1 秒后继续查询...(第 ${round} 次)`); await sleep(1000); continue; } throw error; } } } catch (error) { if (token === codePollToken) setStatus(error.message || String(error), true); } finally { if (token === codePollToken && btn) { btn.disabled = false; btn.textContent = '获取验证码'; } } } function updateProviderFields() { const provider = $('.sb-provider')?.value || 'sms-bower'; panel?.querySelectorAll('.sb-smsbower-only').forEach((el) => { el.style.display = provider === 'sms-bower' ? '' : 'none'; }); panel?.querySelectorAll('.sb-luban-only').forEach((el) => { el.style.display = provider === 'luban-sms' ? '' : 'none'; }); panel?.querySelectorAll('.sb-five-sim-only').forEach((el) => { el.style.display = provider === '5sim' ? '' : 'none'; }); const minPrice = $('.sb-min-price'); if (minPrice) { minPrice.closest('label').style.display = provider === '5sim' ? 'none' : ''; if (provider === '5sim') minPrice.value = ''; } const apiKey = $('.sb-api-key'); if (apiKey) apiKey.placeholder = provider === '5sim' ? '5SIM Bearer Token' : 'API Key / apikey'; } function renderCountries() { const selectedBox = $('.sb-selected-countries'); const list = $('.sb-country-list'); const keyword = ($('.sb-country-search')?.value || '').trim().toLowerCase(); if (!selectedBox || !list) return; selectedBox.innerHTML = ''; selectedCountries.forEach((country, index) => { const chip = document.createElement('span'); chip.className = 'sb-chip'; chip.textContent = `${index + 1}. ${country.label} #${country.id}`; const close = document.createElement('button'); close.type = 'button'; close.textContent = '×'; close.addEventListener('click', () => { selectedCountries = selectedCountries.filter((x) => !sameCountry(x, country)); renderCountries(); }); chip.appendChild(close); selectedBox.appendChild(chip); }); list.innerHTML = ''; allCountries .filter((c) => !keyword || getCountrySearchText(c).includes(keyword)) .slice(0, 120) .forEach((country) => { const btn = document.createElement('button'); btn.type = 'button'; btn.className = 'sb-country-item' + (selectedCountries.some((x) => sameCountry(x, country)) ? ' selected' : ''); btn.innerHTML = `${escapeHtml(country.label)}#${country.id}`; btn.addEventListener('click', () => { if (selectedCountries.some((x) => sameCountry(x, country))) { selectedCountries = selectedCountries.filter((x) => !sameCountry(x, country)); } else { selectedCountries.push(country); } renderCountries(); }); list.appendChild(btn); }); } function escapeHtml(value) { return String(value || '').replace(/[&<>'"]/g, (ch) => ({ '&': '&', '<': '<', '>': '>', "'": ''', '"': '"' }[ch])); } function injectStyles() { if (document.getElementById('smsbower-floating-phone-tool-style')) return; const style = document.createElement('style'); style.id = 'smsbower-floating-phone-tool-style'; style.textContent = ` #${PANEL_ID} { position: fixed; z-index: 2147483647; right: 18px; top: 80px; width: 390px; max-height: calc(100vh - 110px); overflow: auto; box-sizing: border-box; padding: 12px; border: 1px solid #334155; border-radius: 14px; background: #0f172a; color: #e5e7eb; box-shadow: 0 18px 60px rgba(0,0,0,.45); font: 13px/1.45 system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif; } #${PANEL_ID} * { box-sizing: border-box; } #${PANEL_ID} .sb-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 10px; cursor: move; user-select: none; } #${PANEL_ID} .sb-title { font-size: 16px; font-weight: 700; } #${PANEL_ID} .sb-close { width: 28px; height: 28px; padding: 0; border: 1px solid #334155; border-radius: 8px; color: #e5e7eb; background: #1f2937; cursor: pointer; } #${PANEL_ID} label { display: grid; gap: 4px; margin: 7px 0; color: #cbd5e1; } #${PANEL_ID} input, #${PANEL_ID} select { width: 100%; padding: 7px 9px; border: 1px solid #334155; border-radius: 8px; color: #e5e7eb; background: #111827; outline: none; } #${PANEL_ID} input:focus { border-color: #38bdf8; box-shadow: 0 0 0 2px rgba(56,189,248,.18); } #${PANEL_ID} .sb-row { display: grid; grid-template-columns: 1fr 1fr 1fr; gap: 8px; } #${PANEL_ID} .sb-country-box { margin-top: 9px; padding: 9px; border: 1px solid #253244; border-radius: 10px; background: #111827; } #${PANEL_ID} .sb-country-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 7px; } #${PANEL_ID} button { padding: 7px 10px; border: 1px solid #334155; border-radius: 8px; color: #e5e7eb; background: #1f2937; cursor: pointer; font: inherit; } #${PANEL_ID} button:hover { background: #273449; } #${PANEL_ID} button:disabled { opacity: .55; cursor: not-allowed; } #${PANEL_ID} .sb-primary { background: #2563eb; border-color: #3b82f6; } #${PANEL_ID} .sb-primary:hover { background: #1d4ed8; } #${PANEL_ID} .sb-selected-countries { display: flex; flex-wrap: wrap; gap: 6px; min-height: 24px; margin: 7px 0; } #${PANEL_ID} .sb-chip { display: inline-flex; gap: 5px; align-items: center; padding: 4px 7px; border-radius: 999px; background: #0e7490; color: #ecfeff; } #${PANEL_ID} .sb-chip button { padding: 0 3px; border: 0; background: transparent; } #${PANEL_ID} .sb-country-list { max-height: 150px; overflow: auto; border: 1px solid #253244; border-radius: 8px; } #${PANEL_ID} .sb-country-item { display: flex; justify-content: space-between; gap: 8px; width: 100%; padding: 7px 9px; border: 0; border-bottom: 1px solid #1f2937; border-radius: 0; background: #0b1220; text-align: left; } #${PANEL_ID} .sb-country-item.selected { background: #123044; color: #bae6fd; } #${PANEL_ID} .sb-top-fetch { width: 100%; margin: 2px 0 10px; font-weight: 700; } #${PANEL_ID} .sb-actions { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 11px; } #${PANEL_ID} .sb-code-row { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; margin-top: 8px; } #${PANEL_ID} .sb-current { margin-top: 10px; padding: 9px; border-radius: 10px; background: #020617; color: #cbd5e1; } #${PANEL_ID} code { color: #67e8f9; user-select: all; } #${PANEL_ID} .sb-hint { margin: 7px 0 0; color: #94a3b8; font-size: 12px; } #${PANEL_ID} .sb-status { color: #bbf7d0; } #${PANEL_ID} .sb-auto-on { border-color: #22c55e; color: #bbf7d0; } `; document.documentElement.appendChild(style); } async function createPanel() { injectStyles(); panel = document.createElement('div'); panel.id = PANEL_ID; panel.innerHTML = `
接码填号
国家顺序

优先级:价低优先;同价按国家选择顺序。

当前号码:
激活ID:
验证码:
状态:就绪
`; document.documentElement.appendChild(panel); bindPanelEvents(); await loadSettingsIntoPanel(); updateAutoRotateToggle(); startAutoRotateObserver(); scheduleAutoRotateCheck(); } function bindPanelEvents() { $('.sb-close').addEventListener('click', () => { panel.style.display = 'none'; }); $('.sb-save').addEventListener('click', saveSettings); $('.sb-provider').addEventListener('change', updateProviderFields); $('.sb-fetch').addEventListener('click', () => fetchAndFill({ reason: 'manual_replace', releaseAction: 'cancel' })); $('.sb-auto-toggle').addEventListener('click', () => { autoRotateEnabled = !autoRotateEnabled; updateAutoRotateToggle(); setStatus(autoRotateEnabled ? '自动切号已开启' : '自动切号已关闭'); if (autoRotateEnabled) scheduleAutoRotateCheck(); }); $('.sb-rotate-detect').addEventListener('click', () => detectAndRotate('manual')); $('.sb-rotate-used').addEventListener('click', () => fetchAndFill({ reason: 'phone_number_used', releaseAction: 'ban' })); $('.sb-cancel').addEventListener('click', cancelActive); $('.sb-code').addEventListener('click', fetchAndCopyCode); $('.sb-copy-code').addEventListener('click', async () => { const code = $('.sb-current-code')?.textContent || ''; if (code && code !== '无') { await copyText(code); setStatus(`验证码已复制:${code}`); } else { setStatus('当前没有验证码可复制,请先点“获取验证码”。', true); } }); $('.sb-refresh').addEventListener('click', refreshCountries); $('.sb-country-search').addEventListener('input', renderCountries); const head = $('.sb-head'); head.addEventListener('mousedown', (event) => { if (event.target.closest('button')) return; const rect = panel.getBoundingClientRect(); dragState = { x: event.clientX, y: event.clientY, left: rect.left, top: rect.top }; event.preventDefault(); }); window.addEventListener('mousemove', (event) => { if (!dragState) return; panel.style.left = `${Math.max(0, dragState.left + event.clientX - dragState.x)}px`; panel.style.top = `${Math.max(0, dragState.top + event.clientY - dragState.y)}px`; panel.style.right = 'auto'; }); window.addEventListener('mouseup', () => { dragState = null; }); } async function loadSettingsIntoPanel() { const res = await send('GET_SETTINGS'); latestSettings = res.settings; allCountries = (res.fallbackCountries || FALLBACK_COUNTRIES).map(normalizeCountry); selectedCountries = (latestSettings.countries || []).map(normalizeCountry); $('.sb-provider').value = latestSettings.provider || 'sms-bower'; $('.sb-api-key').value = latestSettings.apiKey || ''; $('.sb-base-url').value = latestSettings.baseUrl || ''; $('.sb-luban-base-url').value = latestSettings.lubanBaseUrl || 'https://lubansms.com/v2/api'; $('.sb-five-sim-base-url').value = latestSettings.fiveSimBaseUrl || 'https://5sim.net'; $('.sb-service-code').value = latestSettings.serviceCode || 'dr'; $('.sb-luban-service-id').value = latestSettings.lubanServiceId || ''; $('.sb-five-sim-country').value = latestSettings.fiveSimCountry || 'vietnam'; $('.sb-five-sim-operator').value = latestSettings.fiveSimOperator || 'any'; $('.sb-five-sim-product').value = latestSettings.fiveSimProduct || 'openai'; $('.sb-min-price').value = latestSettings.minPrice || ''; $('.sb-max-price').value = latestSettings.maxPrice || ''; if (latestSettings.activeActivation) { $('.sb-current-phone').textContent = latestSettings.activeActivation.phoneNumber || '无'; $('.sb-current-id').textContent = latestSettings.activeActivation.activationId || '无'; const codeNode = $('.sb-current-code'); if (codeNode) codeNode.textContent = latestSettings.activeActivation.lastCode || '无'; } updateProviderFields(); renderCountries(); } async function togglePanel() { try { if (!panel || !document.documentElement.contains(panel)) { await createPanel(); } else { panel.style.display = panel.style.display === 'none' ? 'block' : 'none'; if (panel.style.display !== 'none') await loadSettingsIntoPanel(); } } catch (error) { alert(`SMSBower 悬浮窗打开失败:${error.message || error}`); } } chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { (async () => { if (message?.type === 'FILL_PHONE') { const phoneNumber = String(message.phoneNumber || '').trim(); if (!phoneNumber) throw new Error('缺少手机号。'); return { ok: true, ...fillPhone(phoneNumber) }; } if (message?.type === 'TOGGLE_FLOAT_PANEL') { await togglePanel(); return { ok: true }; } return undefined; })().then((result) => { if (result !== undefined) sendResponse(result); }).catch((error) => sendResponse({ ok: false, error: error.message || String(error) })); return true; }); })();