2025-06-01 11:50:00 +08:00

325 lines
11 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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 = "<li>加载中...</li>";
}
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 = "<li>未找到相关文档</li>";
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 = "<li>搜索失败,请检查网络或服务状态。</li>";
}
}
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") {
log("按下回车键");
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") 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();
});