添加配置页,40%
This commit is contained in:
parent
f40c01b078
commit
cea109d8ac
@ -1,3 +1,4 @@
|
||||
<!-- popup.html -->
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
@ -18,6 +19,7 @@
|
||||
<div class="user-avatar" id="userAvatar">👤</div>
|
||||
<div class="user-dropdown hidden" id="userDropdown">
|
||||
<div id="userName">未登录</div>
|
||||
<div id="settingsBtn" class="logout-option">插件设置</div>
|
||||
<div id="logoutBtn" class="logout-option">退出登录</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -55,12 +57,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- JS模块加载顺序非常重要,请保持此顺序 -->
|
||||
<!-- 脚本加载顺序不可错乱 -->
|
||||
<script src="../scripts/config.js"></script>
|
||||
<script src="../scripts/utils.js"></script>
|
||||
<script src="../scripts/auth.js"></script>
|
||||
<script src="../scripts/llm.js"></script>
|
||||
<script src="../scripts/popup.js"></script>
|
||||
<!-- 新增 marked.js CDN -->
|
||||
<script src="../scripts/markdown-min.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
152
pages/settings.html
Normal file
152
pages/settings.html
Normal file
@ -0,0 +1,152 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<title>插件设置</title>
|
||||
<style>
|
||||
body {
|
||||
font-family: "Microsoft YaHei", sans-serif;
|
||||
padding: 20px 30px;
|
||||
max-width: 1000px;
|
||||
margin: auto;
|
||||
background-color: #f7f8fc;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.back-link {
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 14px;
|
||||
color: #2560de;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.section {
|
||||
margin-bottom: 30px;
|
||||
background: #fff;
|
||||
border: 1px solid #dfe4ed;
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 2px 6px rgba(0,0,0,0.04);
|
||||
padding: 20px 24px;
|
||||
}
|
||||
|
||||
.section h3 {
|
||||
margin: 0 0 10px;
|
||||
font-size: 17px;
|
||||
color: #1e3a8a;
|
||||
}
|
||||
|
||||
.form-row {
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.form-row label {
|
||||
display: block;
|
||||
font-weight: bold;
|
||||
font-size: 13px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.form-row input {
|
||||
width: 100%;
|
||||
padding: 8px;
|
||||
font-size: 13px;
|
||||
border: 1px solid #ccc;
|
||||
border-radius: 5px;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.api-block {
|
||||
border-top: 1px solid #e3e7f1;
|
||||
margin-top: 25px;
|
||||
padding-top: 18px;
|
||||
}
|
||||
|
||||
.api-name {
|
||||
font-weight: bold;
|
||||
font-size: 15px;
|
||||
margin-bottom: 8px;
|
||||
color: #2560de;
|
||||
padding: 4px 8px;
|
||||
background: #eef3fc;
|
||||
border-left: 4px solid #2560de;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.param-group {
|
||||
margin-top: 12px;
|
||||
padding-left: 12px;
|
||||
border-left: 3px solid #e0e8f8;
|
||||
margin-bottom: 14px;
|
||||
}
|
||||
|
||||
.param-group h4 {
|
||||
font-size: 13px;
|
||||
margin-bottom: 8px;
|
||||
color: #444;
|
||||
}
|
||||
|
||||
.btn-row {
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
gap: 10px;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
button {
|
||||
padding: 8px 18px;
|
||||
font-size: 14px;
|
||||
border-radius: 5px;
|
||||
cursor: pointer;
|
||||
border: 1px solid #ccc;
|
||||
}
|
||||
|
||||
#saveBtn {
|
||||
background-color: #2560de;
|
||||
color: white;
|
||||
border: none;
|
||||
}
|
||||
|
||||
#resetBtn {
|
||||
background: #f8f8f8;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 13px;
|
||||
color: #666;
|
||||
margin-top: 4px;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="back-link" id="backToPopup">← 返回主界面</div>
|
||||
|
||||
<h2>插件设置</h2>
|
||||
|
||||
<div class="section">
|
||||
<h3>通用设置</h3>
|
||||
<div class="form-row">
|
||||
<label for="tokenExpireHours">Token 有效期(小时,最大 168)</label>
|
||||
<input id="tokenExpireHours" type="number" min="1" max="168" />
|
||||
<div class="desc">超出有效期将要求重新登录</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="section" id="endpointSection">
|
||||
<h3>接口配置</h3>
|
||||
<!-- 动态插入接口配置 -->
|
||||
</div>
|
||||
|
||||
<div class="btn-row">
|
||||
<button id="resetBtn">恢复默认</button>
|
||||
<button id="saveBtn">保存设置</button>
|
||||
</div>
|
||||
|
||||
<script src="../scripts/config.js"></script>
|
||||
<script src="../scripts/settings.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
99
scripts/config.js
Normal file
99
scripts/config.js
Normal file
@ -0,0 +1,99 @@
|
||||
const defaultConfig = {
|
||||
tokenExpireHours: 24,
|
||||
apiConfig: {
|
||||
esSearch: {
|
||||
name: "ES 搜索接口",
|
||||
url: "http://app.wisdompulse.cn/search",
|
||||
requestParams: [
|
||||
{ label: "关键词组", field: "keywordGroups" },
|
||||
{ label: "页码", field: "page" },
|
||||
{ label: "分页大小", field: "size" }
|
||||
],
|
||||
responseParams: [
|
||||
{ label: "结果字段", field: "results" },
|
||||
{ label: "总条数字段", field: "total" },
|
||||
{ label: "分页大小字段", field: "size" }
|
||||
]
|
||||
},
|
||||
materialPublicUrl: {
|
||||
name: "材料公开地址",
|
||||
url: "http://share.wisdompulse.cn/public",
|
||||
requestParams: [],
|
||||
responseParams: []
|
||||
},
|
||||
login: {
|
||||
name: "登录接口",
|
||||
url: "http://app.wisdompulse.cn/api/v1/user/login",
|
||||
requestParams: [
|
||||
{ label: "用户名字段", field: "username" },
|
||||
{ label: "密码字段", field: "password" }
|
||||
],
|
||||
responseParams: [
|
||||
{ label: "Token 字段", field: "token" },
|
||||
{ label: "用户名字段", field: "username" }
|
||||
]
|
||||
},
|
||||
filePath: {
|
||||
name: "获取文件路径接口",
|
||||
url: "http://app.wisdompulse.cn/search/file-path",
|
||||
requestParams: [
|
||||
{ label: "文件名字段", field: "filename" }
|
||||
],
|
||||
responseParams: [
|
||||
{ label: "路径字段", field: "filepath" }
|
||||
]
|
||||
},
|
||||
llmToken: {
|
||||
name: "获取 AnythingLLM Token 接口",
|
||||
url: "http://llm.wisdompulse.cn/api/request-token",
|
||||
requestParams: [
|
||||
{ label: "用户名字段", field: "username" }
|
||||
],
|
||||
responseParams: [
|
||||
{ label: "Token 字段", field: "token" }
|
||||
]
|
||||
},
|
||||
workspaces: {
|
||||
name: "获取工作区接口",
|
||||
url: "http://llm.wisdompulse.cn/api/workspaces",
|
||||
requestParams: [],
|
||||
responseParams: [
|
||||
{ label: "工作区数组字段", field: "workspaces" }
|
||||
]
|
||||
},
|
||||
llmChat: {
|
||||
name: "指定工作区对话接口",
|
||||
url: "http://llm.wisdompulse.cn/api/workspace/${workId}/stream-chat",
|
||||
requestParams: [
|
||||
{ label: "问题字段", field: "prompt" },
|
||||
{ label: "历史字段", field: "messages" }
|
||||
],
|
||||
responseParams: []
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
function loadMergedConfig() {
|
||||
return new Promise((resolve) => {
|
||||
chrome.storage.local.get(["customConfig"], (res) => {
|
||||
const merged = JSON.parse(JSON.stringify(defaultConfig));
|
||||
if (res.customConfig && typeof res.customConfig === "object") {
|
||||
merged.tokenExpireHours = res.customConfig.tokenExpireHours || merged.tokenExpireHours;
|
||||
for (const key in merged.apiConfig) {
|
||||
const override = res.customConfig.apiConfig?.[key];
|
||||
if (override) {
|
||||
merged.apiConfig[key].url = override.url || merged.apiConfig[key].url;
|
||||
merged.apiConfig[key].requestParams.forEach((param, i) => {
|
||||
if (override.requestParams?.[i]?.field) param.field = override.requestParams[i].field;
|
||||
});
|
||||
merged.apiConfig[key].responseParams.forEach((param, i) => {
|
||||
if (override.responseParams?.[i]?.field) param.field = override.responseParams[i].field;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve(merged);
|
||||
});
|
||||
});
|
||||
}
|
||||
109
scripts/popup.js
109
scripts/popup.js
@ -1,10 +1,8 @@
|
||||
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 = "";
|
||||
@ -12,7 +10,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
panel.style.position = "fixed";
|
||||
}
|
||||
} else if (panel && header) {
|
||||
log("启用可拖拽模式");
|
||||
let dragging = false, offsetX = 0, offsetY = 0;
|
||||
header.addEventListener("mousedown", (e) => {
|
||||
dragging = true;
|
||||
@ -32,7 +29,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
});
|
||||
}
|
||||
|
||||
// ====== 元素选择 ======
|
||||
const input = document.getElementById("searchInput");
|
||||
const searchBtn = document.getElementById("searchBtn");
|
||||
const clearBtn = document.getElementById("clearHistoryBtn");
|
||||
@ -48,22 +44,20 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
const userAvatar = document.getElementById("userAvatar");
|
||||
const userDropdown = document.getElementById("userDropdown");
|
||||
const openTabBtn = document.getElementById("openTabBtn");
|
||||
|
||||
const settingsBtn = document.getElementById("settingsBtn");
|
||||
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");
|
||||
@ -73,35 +67,22 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
}, 100);
|
||||
};
|
||||
|
||||
function getQueryParam(name) {
|
||||
const url = new URL(window.location.href);
|
||||
return url.searchParams.get(name);
|
||||
}
|
||||
|
||||
const isNewTab = getQueryParam("from") === "newtab";
|
||||
const isNewTab = new URLSearchParams(window.location.search).get("from") === "newtab";
|
||||
|
||||
let token = null;
|
||||
let currentPage = 1;
|
||||
let totalPages = 1;
|
||||
let lastKeywords = [];
|
||||
let config = await loadMergedConfig();
|
||||
|
||||
const auth = await loadToken();
|
||||
if (!auth) {
|
||||
log("用户未认证,执行登出");
|
||||
return handleLogout();
|
||||
}
|
||||
if (!auth) 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);
|
||||
if (!token || !raw) return;
|
||||
updateHistory(raw);
|
||||
renderHistoryTags(true);
|
||||
if (!isNewTab) {
|
||||
@ -127,7 +108,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
}
|
||||
|
||||
function clearResults() {
|
||||
log("清空结果和历史区域");
|
||||
resultBox.innerHTML = "";
|
||||
llmResultContent.innerHTML = "";
|
||||
llmResultContainer.classList.add("hidden");
|
||||
@ -155,18 +135,20 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
async function fetchResults(rawInput, page) {
|
||||
currentPage = page;
|
||||
lastKeywords = rawInput;
|
||||
log("调用 fetchResults,关键词:", rawInput, "页码:", page);
|
||||
showLoading();
|
||||
|
||||
const endpoint = config.apiConfig.esSearch;
|
||||
const [kwField, pageField, sizeField] = endpoint.requestParams.map(p => p.field);
|
||||
const [resultsField, totalField, sizeField2] = endpoint.responseParams.map(p => p.field);
|
||||
const keywordGroups = parseKeywordGroups(rawInput);
|
||||
const requestBody = {
|
||||
keywordGroups,
|
||||
page: currentPage,
|
||||
size: 10
|
||||
[kwField]: keywordGroups,
|
||||
[pageField]: page,
|
||||
[sizeField]: 10
|
||||
};
|
||||
|
||||
try {
|
||||
const response = await fetch("http://app.wisdompulse.cn/search", {
|
||||
const response = await fetch(endpoint.url, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Authorization": `${token}`,
|
||||
@ -175,31 +157,30 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
body: JSON.stringify(requestBody)
|
||||
});
|
||||
|
||||
log("搜索接口响应状态:", response.status);
|
||||
|
||||
if (response.status === 401) {
|
||||
log("token 已失效,执行登出");
|
||||
return handleLogout();
|
||||
}
|
||||
|
||||
if (response.status === 401) return handleLogout();
|
||||
const data = await response.json();
|
||||
const results = data[resultsField];
|
||||
const total = data[totalField];
|
||||
const pageSize = data[sizeField2] || 10;
|
||||
|
||||
resultBox.innerHTML = "";
|
||||
|
||||
if (!data.results || data.results.length === 0) {
|
||||
log("无搜索结果");
|
||||
if (!results || results.length === 0) {
|
||||
resultBox.innerHTML = "<li>未找到相关文档</li>";
|
||||
return;
|
||||
}
|
||||
|
||||
totalPages = Math.ceil(data.total / data.size);
|
||||
totalPages = Math.ceil(total / pageSize);
|
||||
const fileBaseUrl = config.apiConfig.materialPublicUrl.url;
|
||||
|
||||
data.results.forEach(doc => {
|
||||
results.forEach(doc => {
|
||||
const li = document.createElement("li");
|
||||
const path = doc.filepath.replace(/^import-data\//, "").replace(/\.md$/, ".html");
|
||||
const filename = doc.filename || doc.title || "未知文件";
|
||||
const filepath = doc.filepath?.replace(/^import-data\//, "").replace(/\.md$/, ".html") || "";
|
||||
const link = document.createElement("a");
|
||||
link.href = `http://share.wisdompulse.cn/public/${path}`;
|
||||
link.href = `${fileBaseUrl}/${filepath || filename}`;
|
||||
link.target = "_blank";
|
||||
link.textContent = doc.filename;
|
||||
link.textContent = filename;
|
||||
|
||||
const snippet = document.createElement("div");
|
||||
snippet.className = "summary";
|
||||
@ -212,13 +193,11 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
|
||||
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)];
|
||||
@ -228,7 +207,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
}
|
||||
|
||||
function renderHistoryTags(show = false) {
|
||||
log("渲染历史标签,是否显示:", show);
|
||||
chrome.storage.local.get(["searchHistory"], (res) => {
|
||||
const history = res.searchHistory || [];
|
||||
historyBox.innerHTML = "";
|
||||
@ -253,11 +231,7 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
});
|
||||
}
|
||||
|
||||
// ====== DOM 事件绑定 ======
|
||||
searchBtn.addEventListener("click", () => {
|
||||
log("点击搜索按钮");
|
||||
triggerSearch();
|
||||
});
|
||||
searchBtn.addEventListener("click", triggerSearch);
|
||||
input.addEventListener("keydown", e => {
|
||||
if (e.key === "Enter") {
|
||||
e.preventDefault();
|
||||
@ -266,26 +240,20 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
});
|
||||
input.addEventListener("focus", () => renderHistoryTags(true));
|
||||
input.addEventListener("input", () => {
|
||||
if (!input.value.trim()) {
|
||||
log("输入清空,清除结果");
|
||||
clearResults();
|
||||
}
|
||||
if (!input.value.trim()) 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();
|
||||
});
|
||||
|
||||
logoutBtn?.addEventListener("click", () => handleLogout());
|
||||
userAvatar?.addEventListener("click", () => {
|
||||
log("点击用户头像,切换菜单");
|
||||
userDropdown.classList.toggle("hidden");
|
||||
});
|
||||
settingsBtn?.addEventListener("click", () => {
|
||||
chrome.tabs.create({ url: chrome.runtime.getURL("pages/settings.html") });
|
||||
});
|
||||
|
||||
window.addEventListener("click", (e) => {
|
||||
if (!userDropdown.contains(e.target) && e.target !== userAvatar) {
|
||||
@ -297,7 +265,6 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
const val = llmInput.value.trim();
|
||||
if (!val) return;
|
||||
llmInput.value = "";
|
||||
log("发送 LLM 问题:", val);
|
||||
fetchLLMAnswer(val, llmResultContainer, llmResultContent);
|
||||
});
|
||||
|
||||
@ -308,18 +275,16 @@ document.addEventListener("DOMContentLoaded", async () => {
|
||||
}
|
||||
});
|
||||
|
||||
openTabBtn.onclick = () => {
|
||||
openTabBtn.addEventListener("click", () => {
|
||||
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 });
|
||||
};
|
||||
chrome.tabs.create({ url });
|
||||
});
|
||||
|
||||
const autoKeywords = getQueryParam("keywords");
|
||||
const autoKeywords = new URLSearchParams(location.search).get("keywords");
|
||||
if (autoKeywords) {
|
||||
input.value = decodeURIComponent(autoKeywords);
|
||||
log("检测到 URL 参数 keywords,自动搜索:", input.value);
|
||||
triggerSearch();
|
||||
}
|
||||
|
||||
|
||||
125
scripts/settings.js
Normal file
125
scripts/settings.js
Normal file
@ -0,0 +1,125 @@
|
||||
// scripts/settings.js
|
||||
|
||||
function getMergedConfig(callback) {
|
||||
chrome.storage.local.get(["customConfig"], (res) => {
|
||||
const merged = JSON.parse(JSON.stringify(defaultConfig));
|
||||
if (res.customConfig && typeof res.customConfig === "object") {
|
||||
merged.tokenExpireHours = res.customConfig.tokenExpireHours || merged.tokenExpireHours;
|
||||
for (const key in merged.apiConfig) {
|
||||
const override = res.customConfig.apiConfig?.[key];
|
||||
if (override) {
|
||||
merged.apiConfig[key].url = override.url || merged.apiConfig[key].url;
|
||||
|
||||
merged.apiConfig[key].requestParams.forEach((param, i) => {
|
||||
if (override.requestParams?.[i]?.field) param.field = override.requestParams[i].field;
|
||||
});
|
||||
|
||||
merged.apiConfig[key].responseParams.forEach((param, i) => {
|
||||
if (override.responseParams?.[i]?.field) param.field = override.responseParams[i].field;
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
callback(merged);
|
||||
});
|
||||
}
|
||||
|
||||
function renderConfig(config) {
|
||||
document.getElementById("tokenExpireHours").value = config.tokenExpireHours;
|
||||
const container = document.getElementById("endpointSection");
|
||||
container.innerHTML = "";
|
||||
|
||||
for (const [key, endpoint] of Object.entries(config.apiConfig)) {
|
||||
const block = document.createElement("div");
|
||||
block.className = "api-block";
|
||||
|
||||
block.innerHTML += `<div class="api-name">【${endpoint.name}】</div>`;
|
||||
|
||||
const urlRow = document.createElement("div");
|
||||
urlRow.className = "form-row";
|
||||
urlRow.innerHTML = `
|
||||
<label>接口地址</label>
|
||||
<input data-key="${key}" data-type="url" value="${endpoint.url}" />
|
||||
`;
|
||||
block.appendChild(urlRow);
|
||||
|
||||
const reqGroup = document.createElement("div");
|
||||
reqGroup.className = "param-group";
|
||||
reqGroup.innerHTML = `<h4>请求参数</h4>`;
|
||||
endpoint.requestParams.forEach((param, index) => {
|
||||
const row = document.createElement("div");
|
||||
row.className = "form-row";
|
||||
row.innerHTML = `
|
||||
<label>${param.label}</label>
|
||||
<input data-key="${key}" data-type="requestParams" data-index="${index}" value="${param.field}" />
|
||||
`;
|
||||
reqGroup.appendChild(row);
|
||||
});
|
||||
block.appendChild(reqGroup);
|
||||
|
||||
const resGroup = document.createElement("div");
|
||||
resGroup.className = "param-group";
|
||||
resGroup.innerHTML = `<h4>响应字段</h4>`;
|
||||
endpoint.responseParams.forEach((param, index) => {
|
||||
const row = document.createElement("div");
|
||||
row.className = "form-row";
|
||||
row.innerHTML = `
|
||||
<label>${param.label}</label>
|
||||
<input data-key="${key}" data-type="responseParams" data-index="${index}" value="${param.field}" />
|
||||
`;
|
||||
resGroup.appendChild(row);
|
||||
});
|
||||
block.appendChild(resGroup);
|
||||
|
||||
container.appendChild(block);
|
||||
}
|
||||
}
|
||||
|
||||
function collectUserConfig() {
|
||||
const tokenExpireHours = Math.min(168, parseInt(document.getElementById("tokenExpireHours").value) || 24);
|
||||
const apiConfig = {};
|
||||
|
||||
const inputs = document.querySelectorAll("input[data-key]");
|
||||
for (const input of inputs) {
|
||||
const key = input.dataset.key;
|
||||
const type = input.dataset.type;
|
||||
const index = input.dataset.index;
|
||||
|
||||
if (!apiConfig[key]) {
|
||||
apiConfig[key] = { requestParams: [], responseParams: [] };
|
||||
}
|
||||
|
||||
if (type === "url") {
|
||||
apiConfig[key].url = input.value.trim();
|
||||
} else if (type === "requestParams") {
|
||||
apiConfig[key].requestParams[index] = { field: input.value.trim() };
|
||||
} else if (type === "responseParams") {
|
||||
apiConfig[key].responseParams[index] = { field: input.value.trim() };
|
||||
}
|
||||
}
|
||||
|
||||
return { tokenExpireHours, apiConfig };
|
||||
}
|
||||
|
||||
document.getElementById("saveBtn").addEventListener("click", () => {
|
||||
const newConfig = collectUserConfig();
|
||||
chrome.storage.local.set({ customConfig: newConfig }, () => {
|
||||
alert("设置已保存!");
|
||||
});
|
||||
});
|
||||
|
||||
document.getElementById("resetBtn").addEventListener("click", () => {
|
||||
chrome.storage.local.remove("customConfig", () => {
|
||||
alert("已恢复默认设置,刷新页面以生效");
|
||||
location.reload();
|
||||
});
|
||||
});
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
getMergedConfig(renderConfig);
|
||||
const backBtn = document.getElementById("backToPopup");
|
||||
backBtn.addEventListener("click", () => {
|
||||
const popupUrl = chrome.runtime.getURL("pages/popup.html");
|
||||
chrome.tabs.create({ url: popupUrl });
|
||||
});
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user