feat: 访问记录后台分页,支持时间范围/操作/键过滤
build-and-deploy / build-and-deploy (push) Successful in 43s

This commit is contained in:
jif2.zhang
2026-09-21 10:49:55 +08:00
parent ed1457e582
commit dc4c67e386
8 changed files with 304 additions and 42 deletions
+108 -13
View File
@@ -671,9 +671,22 @@ async function copyAddress() {
}
}
/**
* 访问记录查询状态
*/
const auditState = {
key: "",
action: "",
start: "",
end: "",
page: 1,
pageSize: 20,
total: 0,
};
/**
* 打开访问记录弹窗
* @param {string|null} key - 为空时查当前项目全部记录;否则查指定配置键的记录
* @param {string|null} key - 传入配置键时作为过滤条件预填;为空时按当前过滤条件查全部记录
* @returns {Promise<void>}
*/
async function openAudit(key) {
@@ -681,32 +694,80 @@ async function openAudit(key) {
toast("请先选择项目", "error");
return;
}
document.getElementById("audit-title").textContent = key
? `(${state.currentProject.name} · ${key})`
: `(${state.currentProject.name})`;
document.getElementById("audit-title").textContent = `(${state.currentProject.name})`;
if (key) {
auditState.key = key;
document.getElementById("audit-filter-key").value = key;
}
openModal("modal-audit");
await loadAudit();
}
/**
* 读取当前过滤条件并分页加载访问记录
* @returns {Promise<void>}
*/
async function loadAudit() {
if (!state.currentProject) return;
auditState.key = document.getElementById("audit-filter-key").value.trim();
auditState.action = document.getElementById("audit-filter-action").value;
auditState.start = toUtcIso(document.getElementById("audit-filter-start").value);
auditState.end = toUtcIso(document.getElementById("audit-filter-end").value);
auditState.pageSize = parseInt(document.getElementById("audit-page-size").value, 10) || 20;
try {
const logs = await API.getAudit(state.currentProject.id, key || "");
renderAudit(logs);
const data = await API.getAudit(state.currentProject.id, {
key: auditState.key,
action: auditState.action,
start: auditState.start,
end: auditState.end,
page: auditState.page,
pageSize: auditState.pageSize,
});
auditState.total = data.total || 0;
renderAudit(data.items || []);
renderAuditPagination(data);
} catch (err) {
toast("加载访问记录失败: " + err.message, "error");
}
}
/**
* 渲染访问记录表格
* @param {Array} logs - 访问记录列表
* datetime-local 输入值转 UTC ISO 字符串
* @param {string} value - 形如 "2026-09-21T12:30"(浏览器本地时区)
* @returns {string} UTC ISO,空值原样返回
*/
function toUtcIso(value) {
if (!value) return "";
const d = new Date(value);
return isNaN(d.getTime()) ? "" : d.toISOString();
}
/**
* 渲染分页信息
* @param {Object} data - { total, page, pageSize }
* @returns {void}
*/
function renderAudit(logs) {
function renderAuditPagination(data) {
const totalPages = Math.max(1, Math.ceil((data.total || 0) / (data.pageSize || 1)));
document.getElementById("btn-audit-prev").disabled = data.page <= 1;
document.getElementById("btn-audit-next").disabled = data.page >= totalPages;
document.getElementById("audit-page-info").textContent = `第 ${data.page} / ${totalPages} 页 · 共 ${data.total} 条`;
}
/**
* 渲染访问记录表格
* @param {Array} items - 当前页访问记录列表
* @returns {void}
*/
function renderAudit(items) {
const tbody = document.getElementById("audit-tbody");
if (!logs || !logs.length) {
if (!items || !items.length) {
tbody.innerHTML = '<tr><td colspan="7" style="text-align:center;color:#999;padding:24px">暂无访问记录</td></tr>';
return;
}
const ACTION_NAMES = { read: "读取", create: "新增", update: "更新", delete: "删除" };
const SOURCE_NAMES = { web: "网页", mcp: "MCP" };
tbody.innerHTML = logs
tbody.innerHTML = items
.map((l) => {
const act = ACTION_NAMES[l.action] || l.action;
const src = SOURCE_NAMES[l.source] || l.source;
@@ -867,8 +928,42 @@ function bindEvents() {
}
});
// 操作记录
document.getElementById("btn-audit").addEventListener("click", () => openAudit(null));
// 访问记录:打开弹窗
document.getElementById("btn-audit").addEventListener("click", () => openAudit(null));
// 访问记录:过滤与分页
document.getElementById("btn-audit-query").addEventListener("click", () => {
auditState.page = 1;
loadAudit();
});
document.getElementById("btn-audit-reset").addEventListener("click", () => {
document.getElementById("audit-filter-key").value = "";
document.getElementById("audit-filter-action").value = "";
document.getElementById("audit-filter-start").value = "";
document.getElementById("audit-filter-end").value = "";
auditState.page = 1;
loadAudit();
});
document.getElementById("btn-audit-prev").addEventListener("click", () => {
if (auditState.page > 1) {
auditState.page -= 1;
loadAudit();
}
});
document.getElementById("btn-audit-next").addEventListener("click", () => {
auditState.page += 1;
loadAudit();
});
document.getElementById("audit-page-size").addEventListener("change", () => {
auditState.page = 1;
loadAudit();
});
document.getElementById("audit-filter-key").addEventListener("keydown", (e) => {
if (e.key === "Enter") {
auditState.page = 1;
loadAudit();
}
});
// 表格操作(事件委托)
document.getElementById("config-tbody").addEventListener("click", (e) => {