document.addEventListener("DOMContentLoaded", async () => { log("DOMContentLoaded - 页面加载完成"); const panel = document.getElementById("draggablePanel"); const header = document.querySelector(".header"); if (window.innerWidth > 900 && window.innerHeight > 700) { log("启用全屏模式"); document.body.classList.add("fullscreen"); if (panel) { panel.style.left = ""; panel.style.top = ""; panel.style.position = "fixed"; } } else if (panel && header) { log("启用可拖拽模式"); let dragging = false, offsetX = 0, offsetY = 0; header.addEventListener("mousedown", (e) => { dragging = true; offsetX = e.clientX - panel.offsetLeft; offsetY = e.clientY - panel.offsetTop; document.body.style.userSelect = "none"; }); document.addEventListener("mousemove", (e) => { if (dragging) { panel.style.left = Math.max(0, e.clientX - offsetX) + "px"; panel.style.top = Math.max(0, e.clientY - offsetY) + "px"; } }); document.addEventListener("mouseup", () => { dragging = false; document.body.style.userSelect = ""; }); } // ====== 元素选择 ====== const input = document.getElementById("searchInput"); const searchBtn = document.getElementById("searchBtn"); const clearBtn = document.getElementById("clearHistoryBtn"); const historyBox = document.getElementById("historyTags"); const historyWrapper = document.getElementById("historyWrapper"); const resultBox = document.getElementById("results"); const llmResultContainer = document.getElementById("llmResultContainer"); const llmResultContent = document.getElementById("llmResultContent"); const llmInput = document.getElementById("llmInput"); const llmSendBtn = document.getElementById("llmSendBtn"); const logoutBtn = document.getElementById("logoutBtn"); const userNameLabel = document.getElementById("userName"); const userAvatar = document.getElementById("userAvatar"); const userDropdown = document.getElementById("userDropdown"); const openTabBtn = document.getElementById("openTabBtn"); const tabEs = document.getElementById("tabEs"); const tabAi = document.getElementById("tabAi"); const tabContentEs = document.getElementById("tabContentEs"); const tabContentAi = document.getElementById("tabContentAi"); // ====== 标签切换 ====== tabEs.onclick = () => { log("切换到 ES 结果页"); tabEs.classList.add("active"); tabAi.classList.remove("active"); tabContentEs.classList.add("active"); tabContentAi.classList.remove("active"); }; tabAi.onclick = () => { log("切换到 LLM 结果页"); tabEs.classList.remove("active"); tabAi.classList.add("active"); tabContentEs.classList.remove("active"); tabContentAi.classList.add("active"); setTimeout(() => { llmResultContent.scrollTop = llmResultContent.scrollHeight; }, 100); }; function getQueryParam(name) { const url = new URL(window.location.href); return url.searchParams.get(name); } const isNewTab = getQueryParam("from") === "newtab"; let token = null; let currentPage = 1; let totalPages = 1; let lastKeywords = []; const auth = await loadToken(); if (!auth) { log("用户未认证,执行登出"); return handleLogout(); } token = auth.token; userNameLabel.textContent = auth.username; log("用户认证成功,用户名:", auth.username); async function triggerSearch() { const raw = input?.value?.trim(); if (!token || !raw) { log("取消搜索:token 丢失或关键词为空"); return; } log("执行 triggerSearch,关键词:", raw, "是否新标签页:", isNewTab); updateHistory(raw); renderHistoryTags(true); if (!isNewTab) { fetchLLMAnswer(raw, llmResultContainer, llmResultContent); } fetchResults(raw, 1); } function parseKeywordGroups(inputStr) { return inputStr .trim() .split("||") .map(group => { group = group.trim(); if (group.startsWith("(") && group.endsWith(")")) group = group.slice(1, -1); return group.split(/\s+/).filter(Boolean); }) .filter(g => g.length > 0); } function showLoading() { resultBox.innerHTML = "
  • 加载中...
  • "; } function clearResults() { log("清空结果和历史区域"); resultBox.innerHTML = ""; llmResultContent.innerHTML = ""; llmResultContainer.classList.add("hidden"); historyWrapper.classList.add("hidden"); } function renderPagination() { const pagination = document.createElement("div"); pagination.className = "pagination"; if (currentPage > 1) { const prev = document.createElement("button"); prev.textContent = "上一页"; prev.onclick = () => fetchResults(lastKeywords, currentPage - 1); pagination.appendChild(prev); } if (currentPage < totalPages) { const next = document.createElement("button"); next.textContent = "下一页"; next.onclick = () => fetchResults(lastKeywords, currentPage + 1); pagination.appendChild(next); } resultBox.appendChild(pagination); } async function fetchResults(rawInput, page) { currentPage = page; lastKeywords = rawInput; log("调用 fetchResults,关键词:", rawInput, "页码:", page); showLoading(); const keywordGroups = parseKeywordGroups(rawInput); const requestBody = { keywordGroups, page: currentPage, size: 10 }; try { const response = await fetch("http://app.wisdompulse.cn/search", { method: "POST", headers: { "Authorization": `${token}`, "Content-Type": "application/json" }, body: JSON.stringify(requestBody) }); log("搜索接口响应状态:", response.status); if (response.status === 401) { log("token 已失效,执行登出"); return handleLogout(); } const data = await response.json(); resultBox.innerHTML = ""; if (!data.results || data.results.length === 0) { log("无搜索结果"); resultBox.innerHTML = "
  • 未找到相关文档
  • "; return; } totalPages = Math.ceil(data.total / data.size); data.results.forEach(doc => { const li = document.createElement("li"); const path = doc.filepath.replace(/^import-data\//, "").replace(/\.md$/, ".html"); const link = document.createElement("a"); link.href = `http://share.wisdompulse.cn/public/${path}`; link.target = "_blank"; link.textContent = doc.filename; const snippet = document.createElement("div"); snippet.className = "summary"; snippet.innerHTML = doc.summary?.slice(0, 300) + "..."; li.appendChild(link); li.appendChild(snippet); resultBox.appendChild(li); }); renderPagination(); } catch (err) { log("搜索请求异常:", err); resultBox.innerHTML = "
  • 搜索失败,请检查网络或服务状态。
  • "; } } function updateHistory(keyword) { log("更新搜索历史:", keyword); chrome.storage.local.get(["searchHistory"], (res) => { let history = res.searchHistory || []; history = [keyword, ...history.filter(item => item !== keyword)]; if (history.length > 5) history = history.slice(0, 5); chrome.storage.local.set({ searchHistory: history }); }); } function renderHistoryTags(show = false) { log("渲染历史标签,是否显示:", show); chrome.storage.local.get(["searchHistory"], (res) => { const history = res.searchHistory || []; historyBox.innerHTML = ""; if (history.length === 0 || !show) { historyWrapper.classList.add("hidden"); return; } history.forEach(tagText => { const tag = document.createElement("span"); tag.className = "tag"; tag.textContent = tagText; tag.onclick = () => { input.value = tagText; triggerSearch(); }; historyBox.appendChild(tag); }); historyWrapper.classList.remove("hidden"); }); } // ====== DOM 事件绑定 ====== searchBtn.addEventListener("click", () => { log("点击搜索按钮"); triggerSearch(); }); input.addEventListener("keydown", e => { if (e.key === "Enter") { e.preventDefault(); triggerSearch(); } }); input.addEventListener("focus", () => renderHistoryTags(true)); input.addEventListener("input", () => { if (!input.value.trim()) { log("输入清空,清除结果"); clearResults(); } }); input.addEventListener("blur", () => setTimeout(() => historyWrapper.classList.add("hidden"), 200)); clearBtn.addEventListener("click", () => { log("点击清空历史按钮"); chrome.storage.local.remove("searchHistory", () => renderHistoryTags()); }); logoutBtn?.addEventListener("click", () => { log("点击退出登录按钮"); handleLogout(); }); userAvatar?.addEventListener("click", () => { log("点击用户头像,切换菜单"); userDropdown.classList.toggle("hidden"); }); window.addEventListener("click", (e) => { if (!userDropdown.contains(e.target) && e.target !== userAvatar) { userDropdown.classList.add("hidden"); } }); llmSendBtn?.addEventListener("click", () => { const val = llmInput.value.trim(); if (!val) return; llmInput.value = ""; log("发送 LLM 问题:", val); fetchLLMAnswer(val, llmResultContainer, llmResultContent); }); llmInput.addEventListener("keydown", e => { if (e.key === "Enter") { e.preventDefault(); document.getElementById("llmSendBtn").click(); } }); openTabBtn.onclick = () => { const val = input?.value?.trim(); const encoded = encodeURIComponent(val || ""); const url = chrome.runtime.getURL("pages/popup.html?keywords=" + encoded + "&from=newtab"); log("点击新标签页按钮,跳转到:", url); chrome.tabs?.create({ url }); }; const autoKeywords = getQueryParam("keywords"); if (autoKeywords) { input.value = decodeURIComponent(autoKeywords); log("检测到 URL 参数 keywords,自动搜索:", input.value); triggerSearch(); } renderHistoryTags(); });