const defaults = { baseUrl: "https://api.openai.com", model: "gpt-4o-mini", targetLang: "zh-CN" }; const baseUrlEl = document.getElementById("baseUrl"); const apiKeyEl = document.getElementById("apiKey"); const modelEl = document.getElementById("model"); const targetLangEl = document.getElementById("targetLang"); const msgEl = document.getElementById("msg"); const saveBtn = document.getElementById("save"); const testBtn = document.getElementById("test"); const clearBtn = document.getElementById("clear"); function setMessage(text, type = "info") { msgEl.textContent = text || ""; msgEl.dataset.type = type; } function resetActionButtons() { saveBtn.disabled = false; testBtn.disabled = false; clearBtn.disabled = false; saveBtn.textContent = "保存配置"; testBtn.textContent = "测试连接"; clearBtn.textContent = "清除配置"; } function setActionBusy(activeBtn, busyText) { saveBtn.disabled = true; testBtn.disabled = true; clearBtn.disabled = true; activeBtn.textContent = busyText; } function readFormConfig() { return { baseUrl: (baseUrlEl.value || "").trim(), apiKey: (apiKeyEl.value || "").trim(), model: (modelEl.value || "").trim(), targetLang: (targetLangEl.value || "").trim() || defaults.targetLang }; } function sendRuntimeMessage(payload) { return new Promise((resolve, reject) => { chrome.runtime.sendMessage(payload, (response) => { if (chrome.runtime.lastError) { reject(new Error(chrome.runtime.lastError.message)); return; } if (!response?.ok) { reject(new Error(response?.error || "请求失败")); return; } resolve(response); }); }); } async function loadConfig() { const syncData = await chrome.storage.sync.get(defaults); const localData = await chrome.storage.local.get({ apiKey: "" }); baseUrlEl.value = syncData.baseUrl || defaults.baseUrl; modelEl.value = syncData.model || defaults.model; targetLangEl.value = syncData.targetLang || defaults.targetLang; apiKeyEl.value = localData.apiKey || ""; } async function saveConfig() { const { baseUrl, apiKey, model, targetLang } = readFormConfig(); if (!baseUrl || !model) { setMessage("Base URL 和 Model 不能为空", "error"); return; } setActionBusy(saveBtn, "保存中..."); try { await chrome.storage.sync.set({ baseUrl, model, targetLang }); await chrome.storage.local.set({ apiKey }); setMessage("已保存,可直接关闭此页", "success"); } catch (err) { setMessage(err.message || "保存失败", "error"); } finally { resetActionButtons(); } } async function testConfig() { const config = readFormConfig(); if (!config.baseUrl || !config.apiKey || !config.model) { setMessage("请先填写 Base URL / API Key / Model", "error"); return; } setActionBusy(testBtn, "测试中..."); try { const response = await sendRuntimeMessage({ action: "testConfig", config }); setMessage(response.text || "连接成功", "success"); } catch (err) { setMessage(err.message || "测试失败", "error"); } finally { resetActionButtons(); } } async function clearConfig() { const ok = confirm("确定清除已保存的 Base URL / API Key / Model / 目标语言吗?"); if (!ok) { return; } setActionBusy(clearBtn, "清除中..."); try { await chrome.storage.sync.remove(["baseUrl", "model", "targetLang"]); await chrome.storage.local.remove(["apiKey"]); baseUrlEl.value = defaults.baseUrl; modelEl.value = defaults.model; targetLangEl.value = defaults.targetLang; apiKeyEl.value = ""; setMessage("已清除浏览器中的配置", "success"); } catch (err) { setMessage(err.message || "清除失败", "error"); } finally { resetActionButtons(); } } saveBtn.addEventListener("click", () => { saveConfig().catch((err) => setMessage(err.message || "保存失败", "error")); }); testBtn.addEventListener("click", () => { testConfig().catch((err) => setMessage(err.message || "测试失败", "error")); }); clearBtn.addEventListener("click", () => { clearConfig().catch((err) => setMessage(err.message || "清除失败", "error")); }); loadConfig().then(() => { setMessage("已加载当前配置", "info"); }).catch((err) => { setMessage(err.message || "加载失败", "error"); });