message / plugins /cache /frontend /index.html
hunian
refactor(plugins): 插件短名并统一 MCP tool 为 {plugin}-{tool}
cc826a1
Raw
History Blame Contribute Delete
5.01 kB
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>文件缓存</title>
<link rel="stylesheet" href="/static/plugin-ui.css">
</head>
<body>
<main class="plugin-shell">
<header class="plugin-header">
<div>
<h1 class="plugin-title">文件缓存</h1>
<p class="plugin-subtitle">上传临时或永久文件,查看缓存清单,并复制可访问地址。</p>
</div>
<span id="statusPill" class="plugin-status">检查中</span>
</header>
<div id="message" class="plugin-message"></div>
<section class="plugin-grid">
<div class="plugin-panel">
<h2 class="plugin-panel-title">上传文件</h2>
<div class="plugin-stack">
<div class="plugin-field">
<label class="plugin-label" for="file">文件</label>
<input id="file" type="file">
</div>
<div class="plugin-field">
<label class="plugin-label" for="fileType">保存类型</label>
<select id="fileType">
<option value="temp">临时文件</option>
<option value="permanent">永久文件</option>
</select>
</div>
<button class="plugin-button" onclick="uploadFile()">上传</button>
</div>
</div>
<div class="plugin-panel">
<h2 class="plugin-panel-title">插件状态</h2>
<pre id="statusOutput" class="plugin-output">等待状态数据。</pre>
</div>
</section>
<section class="plugin-panel">
<div class="plugin-header" style="margin-bottom:12px">
<h2 class="plugin-panel-title" style="margin:0">缓存文件</h2>
<button class="plugin-button secondary" onclick="loadFiles()">刷新列表</button>
</div>
<div id="fileList" class="plugin-list"></div>
</section>
</main>
<script src="/static/plugin-ui.js"></script>
<script>
const API = "/plugins/cache/api";
async function loadStatus() {
try {
const data = await PluginUI.request(`${API}/status`);
PluginUI.setJson("statusOutput", data);
const pill = document.getElementById("statusPill");
pill.textContent = data.enabled === false ? "插件未启用" : "可用";
pill.className = `plugin-status ${data.enabled === false ? "warn" : "ok"}`;
} catch (error) {
PluginUI.showMessage("message", error.message, "error");
}
}
async function uploadFile() {
try {
const input = document.getElementById("file");
if (!input.files.length) throw new Error("请选择要上传的文件");
const form = new FormData();
form.append("file", input.files[0]);
form.append("file_type", document.getElementById("fileType").value);
const data = await PluginUI.request(`${API}/upload`, { method: "POST", body: form });
PluginUI.showMessage("message", `上传成功:${data.filename}`);
input.value = "";
await loadFiles();
await loadStatus();
} catch (error) {
PluginUI.showMessage("message", error.message, "error");
}
}
async function loadFiles() {
const list = document.getElementById("fileList");
try {
const data = await PluginUI.request(`${API}/list`);
if (!data.files || data.files.length === 0) {
list.innerHTML = '<div class="plugin-muted">暂无缓存文件。</div>';
return;
}
list.innerHTML = data.files.map((file) => `
<div class="plugin-item">
<div>
<strong>${file.name || file.filename || file.file_id}</strong>
<div class="plugin-muted">${file.type || "-"} · ${file.file_id}</div>
</div>
<div class="plugin-row">
<a class="plugin-button secondary" href="${API}/file/${file.file_id}" target="_blank" rel="noreferrer">下载</a>
<button class="plugin-button secondary" onclick="copyUrl('${API}/file/${file.file_id}')">复制地址</button>
<button class="plugin-button danger" onclick="deleteFile('${file.file_id}')">删除</button>
</div>
</div>
`).join("");
} catch (error) {
list.innerHTML = "";
PluginUI.showMessage("message", error.message, "error");
}
}
async function copyUrl(url) {
await PluginUI.copyText(`${location.origin}${url}`);
PluginUI.showMessage("message", "文件地址已复制");
}
async function deleteFile(fileId) {
try {
const data = await PluginUI.request(`${API}/file/${fileId}`, { method: "DELETE" });
PluginUI.showMessage("message", data.message || "文件已删除");
await loadFiles();
await loadStatus();
} catch (error) {
PluginUI.showMessage("message", error.message, "error");
}
}
loadStatus();
loadFiles();
</script>
</body>
</html>