support select dir
This commit is contained in:
@@ -57,6 +57,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<div id="file-selector-container" style="margin-bottom: 20px; background: white; padding: 15px; border-radius: 12px; box-shadow: 0 4px 6px rgba(0,0,0,0.05); display: flex; align-items: center; gap: 15px;">
|
||||||
|
<button id="btnSelectDir" class="btn btn-primary" onclick="pickDirectory()"></button>
|
||||||
|
<span id="t-label-files" style="font-weight: 600; color: #636e72;"></span>
|
||||||
|
<select id="fileDropdown" style="flex-grow: 1; padding: 8px 12px; border-radius: 8px; border: 1px solid #ddd; outline: none; cursor: pointer;" onchange="loadSelectedFile(this.value)">
|
||||||
|
<option value="" disabled selected id="t-select-placeholder"></option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="drop-zone">
|
<div id="drop-zone">
|
||||||
<p id="t-drop-hint"></p>
|
<p id="t-drop-hint"></p>
|
||||||
<span id="t-click-hint" style="color: #95a5a6;"></span>
|
<span id="t-click-hint" style="color: #95a5a6;"></span>
|
||||||
@@ -86,8 +94,8 @@
|
|||||||
<script>
|
<script>
|
||||||
// 内置默认语言
|
// 内置默认语言
|
||||||
const defaultI18n = {
|
const defaultI18n = {
|
||||||
zh: { name: "简体中文", dropHint: "📂 <b>拖入</b>生成的文件到这里", clickHint: "或者 点击此处手动选择", labelMatch: "一致 (Match)", labelMismatch: "损坏 (Mismatch)", labelMissing: "缺失 (Missing)", labelExtra: "多余 (Extra)", btnExpand: "全部展开", btnCollapse: "全部收起", modeFull: "显示模式:完整清单", modeError: "显示模式:只看异常", loadSuccess: "✅ 已加载:", files: " 个文件" },
|
zh: { name: "简体中文", dropHint: "📂 <b>拖入</b>生成的文件到这里", clickHint: "或者 点击此处手动选择", labelMatch: "一致 (Match)", labelMismatch: "损坏 (Mismatch)", labelMissing: "缺失 (Missing)", labelExtra: "多余 (Extra)", btnExpand: "全部展开", btnCollapse: "全部收起", modeFull: "显示模式:完整清单", modeError: "显示模式:只看异常", loadSuccess: "✅ 已加载:", files: " 个文件", labelFiles: "切换文件:", selectPlaceholder: "--- 请选择已加载的报告 ---", btnPickDir: "📂 选择结果目录" },
|
||||||
en: { name: "English", dropHint: "📂 <b>Drag</b> your file here", clickHint: "or click to select manually", labelMatch: "Match", labelMismatch: "Mismatch", labelMissing: "Missing", labelExtra: "Extra", btnExpand: "Expand All", btnCollapse: "Collapse All", modeFull: "View: All Files", modeError: "View: Errors Only", loadSuccess: "✅ Loaded: ", files: " files" }
|
en: { name: "English", dropHint: "📂 <b>Drag</b> your file here", clickHint: "or click to select manually", labelMatch: "Match", labelMismatch: "Mismatch", labelMissing: "Missing", labelExtra: "Extra", btnExpand: "Expand All", btnCollapse: "Collapse All", modeFull: "View: All Files", modeError: "View: Errors Only", loadSuccess: "✅ Loaded: ", files: " files", labelFiles: "Switch File:", selectPlaceholder: "--- Select a loaded report ---", btnPickDir: "📂 Open Directory" }
|
||||||
};
|
};
|
||||||
|
|
||||||
// 合并外部语言
|
// 合并外部语言
|
||||||
@@ -95,8 +103,46 @@
|
|||||||
let currentLang = 'zh';
|
let currentLang = 'zh';
|
||||||
let globalData = "";
|
let globalData = "";
|
||||||
let errorMode = false;
|
let errorMode = false;
|
||||||
|
let fileHandles = {}; // 存储文件句柄
|
||||||
|
|
||||||
|
// 文件夹选择器逻辑 (File System Access API)
|
||||||
|
async function pickDirectory() {
|
||||||
|
try {
|
||||||
|
const directoryHandle = await window.showDirectoryPicker();
|
||||||
|
const dropdown = document.getElementById('fileDropdown');
|
||||||
|
dropdown.innerHTML = `<option value="" disabled selected>${allI18n[currentLang].selectPlaceholder}</option>`;
|
||||||
|
fileHandles = {};
|
||||||
|
|
||||||
|
for await (const entry of directoryHandle.values()) {
|
||||||
|
if (entry.kind === 'file' && entry.name.endsWith('.txt')) {
|
||||||
|
fileHandles[entry.name] = entry;
|
||||||
|
const opt = document.createElement('option');
|
||||||
|
opt.value = entry.name;
|
||||||
|
opt.innerText = entry.name;
|
||||||
|
dropdown.appendChild(opt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
alert(`已成功加载 ${Object.keys(fileHandles).length} 个报告文件。`);
|
||||||
|
} catch (err) {
|
||||||
|
if (err.name !== 'AbortError') {
|
||||||
|
console.error('选择目录失败:', err);
|
||||||
|
alert('浏览器不支持该功能或选择失败,请确保使用 Chrome/Edge 并授予权限。');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function loadSelectedFile(fileName) {
|
||||||
|
const handle = fileHandles[fileName];
|
||||||
|
if (handle) {
|
||||||
|
const file = await handle.getFile();
|
||||||
|
const text = await file.text();
|
||||||
|
globalData = text;
|
||||||
|
processData(globalData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// 初始化语言选择器
|
// 初始化语言选择器
|
||||||
|
|
||||||
const langSelect = document.getElementById('langSelect');
|
const langSelect = document.getElementById('langSelect');
|
||||||
Object.keys(allI18n).forEach(key => {
|
Object.keys(allI18n).forEach(key => {
|
||||||
const opt = document.createElement('option');
|
const opt = document.createElement('option');
|
||||||
@@ -121,6 +167,9 @@
|
|||||||
document.getElementById('t-label-extra').innerText = t.labelExtra;
|
document.getElementById('t-label-extra').innerText = t.labelExtra;
|
||||||
document.getElementById('t-btn-expand').innerText = t.btnExpand;
|
document.getElementById('t-btn-expand').innerText = t.btnExpand;
|
||||||
document.getElementById('t-btn-collapse').innerText = t.btnCollapse;
|
document.getElementById('t-btn-collapse').innerText = t.btnCollapse;
|
||||||
|
document.getElementById('t-label-files').innerText = t.labelFiles;
|
||||||
|
document.getElementById('t-select-placeholder').innerText = t.selectPlaceholder;
|
||||||
|
document.getElementById('btnSelectDir').innerText = t.btnPickDir;
|
||||||
const filterBtn = document.getElementById('toggleFilterBtn');
|
const filterBtn = document.getElementById('toggleFilterBtn');
|
||||||
filterBtn.innerText = errorMode ? t.modeError : t.modeFull;
|
filterBtn.innerText = errorMode ? t.modeError : t.modeFull;
|
||||||
filterBtn.className = errorMode ? 'btn btn-danger' : 'btn btn-primary';
|
filterBtn.className = errorMode ? 'btn btn-danger' : 'btn btn-primary';
|
||||||
@@ -152,6 +201,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function processData(text) {
|
function processData(text) {
|
||||||
|
if (!text) return;
|
||||||
|
// 处理 PowerShell 偶尔可能返回数组或非字符串对象的情况
|
||||||
|
if (Array.isArray(text)) text = text.join('\n');
|
||||||
|
if (typeof text !== 'string') text = String(text);
|
||||||
|
|
||||||
const lines = text.split(/\r?\n/);
|
const lines = text.split(/\r?\n/);
|
||||||
const tree = {};
|
const tree = {};
|
||||||
const stats = {'=':0, '*':0, '-':0, '+':0};
|
const stats = {'=':0, '*':0, '-':0, '+':0};
|
||||||
|
|||||||
Reference in New Issue
Block a user