// ===== 路径解析:从 URL 取当前目录(去除首尾斜杠) ===== const currentPath = decodeURIComponent(window.location.pathname).replace(/^\/+|\/+$/g, ''); // ===== DOM 引用(id 与原版本完全一致,保持后端/前端契约不变) ===== const fileList = document.getElementById("fileList"); const loading = document.getElementById("loading"); const empty = document.getElementById("empty"); const searchInput = document.getElementById("searchInput"); const totalItems = document.getElementById("totalItems"); const totalDirs = document.getElementById("totalDirs"); const totalFiles = document.getElementById("totalFiles"); const totalVideos = document.getElementById("totalVideos"); const totalAudios = document.getElementById("totalAudios"); const btnRefresh = document.getElementById("btnRefresh"); const breadcrumb = document.getElementById("breadcrumb"); // ===== 状态 ===== let items = []; let searchQuery = ""; // ===== 工具函数 ===== const SIZE_UNITS = ["B", "KB", "MB", "GB"]; function formatSize(bytes) { if (bytes === 0) return "0B"; const i = Math.floor(Math.log(bytes) / Math.log(1024)); return (bytes / Math.pow(1024, i)).toFixed(1) + SIZE_UNITS[i]; } const FILE_ICONS = { pdf: "📄", doc: "📝", docx: "📝", xls: "📊", xlsx: "📊", zip: "📦", rar: "📦", "7z": "📦", jpg: "🖼️", jpeg: "🖼️", png: "🖼️", gif: "🖼️", txt: "📃", json: "📋", html: "🌐", css: "🎨", js: "⚡" }; function getIcon(item) { if (item.type === "dir") return "📁"; if (item.type === "video") return "🎬"; if (item.type === "audio") return "🎵"; const ext = item.name.split(".").pop().toLowerCase(); return FILE_ICONS[ext] || "📄"; } // 转义文本,防止文件名含特殊字符导致 XSS 或模板断裂 function esc(str) { return String(str) .replace(/&/g, "&") .replace(//g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } // ===== 导航行为(与原版本一致) ===== function navigate(path, type) { if (type === "dir") window.location.href = "/" + path; else if (type === "video" || type === "audio") window.location.href = "/video/" + path; else if (/\.html?$/i.test(path)) window.open("/" + path, "_blank"); else window.location.href = "/" + path; } function playMedia(path) { window.location.href = "/video/" + path; } function downloadFile(path) { window.location.href = "/" + path + "?download=true"; } // ===== 面包屑 ===== function renderBreadcrumb() { const parts = currentPath ? currentPath.split('/') : []; const frags = ['根目录']; let acc = ''; parts.forEach((part, i) => { if (i === parts.length - 1) { frags.push(`›${esc(part)}`); } else { acc += (i === 0 ? '' : '/') + part; frags.push(`›${esc(part)}`); } }); breadcrumb.innerHTML = frags.join(''); } // ===== 列表渲染(使用转义,避免文件名注入) ===== function render() { const q = searchQuery.toLowerCase(); const filtered = searchQuery ? items.filter(i => i.name.toLowerCase().includes(q)) : items; totalItems.textContent = filtered.length; totalDirs.textContent = filtered.filter(i => i.type === "dir").length; totalFiles.textContent = filtered.filter(i => i.type === "file").length; totalVideos.textContent = filtered.filter(i => i.type === "video").length; totalAudios.textContent = filtered.filter(i => i.type === "audio").length; if (filtered.length === 0) { fileList.innerHTML = ""; empty.style.display = "block"; loading.style.display = "none"; return; } empty.style.display = "none"; loading.style.display = "none"; fileList.innerHTML = filtered.map(item => { const path = esc(item.path); const type = esc(item.type); const name = esc(item.name); const sizeOrDir = item.type !== "dir" ? `${formatSize(item.size)}` : '📁 文件夹'; const playBtn = (item.type === "video" || item.type === "audio") ? `` : ''; return `