diff --git a/public/admin.html b/public/admin.html index 5ab01fc..567d362 100644 --- a/public/admin.html +++ b/public/admin.html @@ -117,7 +117,7 @@
| 名称 | 关联项目 | 权限 | MCP 访问 | Token | +名称 | 关联项目 | 权限 | Token | 状态 | 过期时间 | 创建时间 | 操作 | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 暂无 Token | ||||||||||||||||||||||||||||||||||
| 暂无 Token | ||||||||||||||||||||||||||||||||||
| " + esc(t.name) + " | " + - "" + esc(t.projectId === "all" ? "全部项目" : t.projectId) + " | " + + "" + esc(projectNames(t.projectIds)) + " | " + '' + (t.permission === "readwrite" ? "读写" : "只读") + " | " + - '' + (t.mcpEnabled - ? 'MCP' - : '—') + " | " + '' +
'' + masked + "" +
'' +
@@ -517,7 +555,7 @@
" " + fmtDate(t.expiresAt) + " | " +
"" + fmtDate(t.createdAt) + " | " +
'' +
- ' " +
+ ' " +
(t.enabled
? '"
: "") +
@@ -565,12 +603,10 @@
document.getElementById("modal-token-title").textContent = "生成 Token";
document.getElementById("edit-token-id").value = "";
document.getElementById("input-token-name").value = "";
- document.getElementById("input-token-project").value = "all";
document.getElementById("input-token-permission").value = "readonly";
document.getElementById("input-token-expiry").value = "90";
- document.getElementById("input-token-mcp").checked = false;
document.getElementById("btn-save-token").textContent = "生成";
- loadProjectsForSelect();
+ loadProjectsForSelect().then(function () { setSelectedProjectIds(["all"]); });
openModal("modal-token");
});
@@ -578,11 +614,10 @@
document.getElementById("modal-token-title").textContent = "编辑 Token";
document.getElementById("edit-token-id").value = t.id;
document.getElementById("input-token-name").value = t.name;
- document.getElementById("input-token-project").value = t.projectId;
document.getElementById("input-token-permission").value = t.permission;
- document.getElementById("input-token-mcp").checked = !!(t.mcpEnabled);
document.getElementById("btn-save-token").textContent = "保存";
- loadProjectsForSelect();
+ var ids = t.projectIds;
+ loadProjectsForSelect().then(function () { setSelectedProjectIds(ids); });
openModal("modal-token");
};
@@ -590,25 +625,20 @@
var id = document.getElementById("edit-token-id").value;
var name = document.getElementById("input-token-name").value.trim();
if (!name) { toast("请输入 Token 名称", "error"); return; }
+ var payload = {
+ name: name,
+ projectIds: getSelectedProjectIds(),
+ permission: document.getElementById("input-token-permission").value,
+ };
try {
if (id) {
- await API.updateToken(id, {
- name: name,
- projectId: document.getElementById("input-token-project").value,
- permission: document.getElementById("input-token-permission").value,
- mcpEnabled: document.getElementById("input-token-mcp").checked,
- });
+ await API.updateToken(id, payload);
closeModal("modal-token");
toast("Token 已更新", "success");
loadTokens();
} else {
- var data = await API.createToken({
- name: name,
- projectId: document.getElementById("input-token-project").value,
- permission: document.getElementById("input-token-permission").value,
- mcpEnabled: document.getElementById("input-token-mcp").checked,
- expiresInDays: parseInt(document.getElementById("input-token-expiry").value) || 0,
- });
+ payload.expiresInDays = parseInt(document.getElementById("input-token-expiry").value) || 0;
+ var data = await API.createToken(payload);
closeModal("modal-token");
document.getElementById("reveal-token-value").textContent = data.value;
openModal("modal-token-reveal");
diff --git a/public/index.html b/public/index.html
index 4c78641..2136b52 100644
--- a/public/index.html
+++ b/public/index.html
@@ -45,8 +45,9 @@
|
数据
-
-
+
+
+
@@ -303,7 +304,31 @@
-
+
+
+
+
+
+
+
+ 操作记录+ +
+
+
+
+
+
+
+
diff --git a/public/js/api.js b/public/js/api.js
index cd4e97e..6b71259 100644
--- a/public/js/api.js
+++ b/public/js/api.js
@@ -93,6 +93,11 @@ const API = {
return this.request(`/api/projects/${projectId}/configs/${configId}`, { method: "DELETE" });
},
+ getAudit(projectId, key) {
+ const qs = key ? `?key=${encodeURIComponent(key)}` : "";
+ return this.request(`/api/projects/${projectId}/configs/audit${qs}`);
+ },
+
// ========== 模式 ==========
getMode() {
diff --git a/public/js/app.js b/public/js/app.js
index 14a12f5..1c696c0 100644
--- a/public/js/app.js
+++ b/public/js/app.js
@@ -274,10 +274,11 @@ function renderConfigTable(configs, path) {
${escapeHtml(cfg.type)} |
${statusHtml.join("")} |
${escapeHtml(cfg.description)} |
-
-
-
-
+ |
+
+
+
+
|
`;
tbody.appendChild(tr);
@@ -670,9 +671,79 @@ async function copyAddress() {
}
}
-/**
- * 绑定所有事件监听
- * @returns {void}
+/**
+ * 打开操作记录弹窗
+ * @param {string|null} key - 为空时查当前项目全部记录;否则查指定配置键的记录
+ * @returns {Promise暂无操作记录 | ${escapeHtml(fmtTime(l.createdAt))} | ` +
+ `${escapeHtml(src)} | ` +
+ `${escapeHtml(l.actor || "")} | ` +
+ `${l.ip ? escapeHtml(l.ip) : "—"} | ` +
+ `${escapeHtml(act)} | ` +
+ `${escapeHtml(l.key || "")} | ` +
+ `${escapeHtml(val.length > 80 ? val.slice(0, 80) + "…" : val)} | ` +
+ " | |||||||||||||