2025-05-25 14:41:05 +08:00

237 lines
7.0 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 () => {
const input = document.getElementById("searchInput");
const searchBtn = document.getElementById("searchBtn");
const clearHistoryBtn = document.getElementById("clearHistoryBtn");
const resultBox = document.getElementById("results");
const historyBox = document.getElementById("historyTags");
const historyWrapper = document.getElementById("historyWrapper");
const userDropdown = document.getElementById("userDropdown");
const logoutBtn = document.getElementById("logoutBtn");
const userNameLabel = document.getElementById("userName");
const userAvatar = document.getElementById("userAvatar");
let token = null;
let currentPage = 1;
let totalPages = 1;
let lastKeywords = [];
const TOKEN_EXPIRE_MS = 24 * 60 * 60 * 1000;
function log(...args) {
const version = chrome?.runtime?.getManifest?.().version || "dev";
console.log(`[v${version}]`, ...args);
}
async function loadToken() {
return new Promise((resolve) => {
chrome.storage.local.get(["token", "loginAt", "username"], (res) => {
log("加载本地存储 token:", res);
const now = Date.now();
if (!res.token || !res.loginAt || (now - res.loginAt > TOKEN_EXPIRE_MS)) {
log("token 不存在或已过期");
resolve(null);
} else {
log("token 加载成功");
resolve({
token: res.token,
username: res.username || "用户"
});
}
});
});
}
function handleLogout() {
log("执行退出登录逻辑");
chrome.storage.local.remove(["token", "loginAt", "username"], () => {
chrome.action.setPopup({ popup: "login.html" });
window.location.href = "login.html";
});
}
function showLoading() {
resultBox.innerHTML = "<li>加载中...</li>";
}
function clearResults() {
resultBox.innerHTML = "";
historyWrapper.classList.add("hidden");
}
function renderPagination() {
const pagination = document.createElement("div");
pagination.className = "pagination";
if (currentPage > 1) {
const prevBtn = document.createElement("button");
prevBtn.textContent = "上一页";
prevBtn.onclick = () => fetchResults(lastKeywords, currentPage - 1);
pagination.appendChild(prevBtn);
}
if (currentPage < totalPages) {
const nextBtn = document.createElement("button");
nextBtn.textContent = "下一页";
nextBtn.onclick = () => fetchResults(lastKeywords, currentPage + 1);
pagination.appendChild(nextBtn);
}
resultBox.appendChild(pagination);
}
function updateHistory(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() {
chrome.storage.local.get(["searchHistory"], (res) => {
const history = res.searchHistory || [];
historyBox.innerHTML = "";
if (history.length === 0) {
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");
});
}
async function fetchResults(keywords, page) {
log("执行搜索:", keywords, "page:", page);
if (!token) {
log("token 未初始化,跳转 login");
handleLogout();
return;
}
currentPage = page;
lastKeywords = keywords;
const keywordGroups = keywords.map(k => [k]);
const requestBody = {
keywordGroups,
page: currentPage,
size: 10
};
showLoading();
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("后端返回 401token 无效,登出");
handleLogout();
return;
}
const data = await response.json();
resultBox.innerHTML = "";
if (!data.results || data.results.length === 0) {
resultBox.innerHTML = "<li>未找到相关文档</li>";
return;
}
totalPages = Math.ceil(data.total / data.size);
data.results.forEach(doc => {
const li = document.createElement("li");
const cleanPath = doc.filepath.replace(/^import-data\//, "").replace(/\.md$/, ".html");
const link = document.createElement("a");
link.href = `http://share.wisdompulse.cn/public/${cleanPath}`;
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) {
console.error("搜索请求失败:", err);
resultBox.innerHTML = "<li>搜索失败,请检查网络或服务状态。</li>";
}
}
function triggerSearch() {
if (!token) {
log("triggerSearch 中 token 丢失,取消搜索");
return;
}
const val = input.value.trim();
if (!val) return clearResults();
const keywords = val.split(/\s+/);
updateHistory(val);
fetchResults(keywords, 1);
}
function bindEvents() {
log("绑定事件成功");
searchBtn.addEventListener("click", triggerSearch);
input.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
log("用户按下回车 ⏎");
triggerSearch();
}
});
input.addEventListener("focus", renderHistoryTags);
input.addEventListener("input", () => !input.value.trim() && clearResults());
input.addEventListener("blur", () => setTimeout(() => historyWrapper.classList.add("hidden"), 200));
clearHistoryBtn.addEventListener("click", () => {
chrome.storage.local.remove("searchHistory", renderHistoryTags);
});
logoutBtn.addEventListener("click", handleLogout);
userAvatar.addEventListener("click", () => userDropdown.classList.toggle("hidden"));
window.addEventListener("click", (e) => {
if (!userDropdown.contains(e.target) && e.target !== userAvatar) {
userDropdown.classList.add("hidden");
}
});
}
const auth = await loadToken();
if (!auth) {
log("未通过认证,执行登出");
handleLogout();
} else {
token = auth.token;
userNameLabel.textContent = auth.username;
log("用户认证通过,用户名:", auth.username);
bindEvents();
}
});