"""历史任务页:分页表格展示所有任务,可按文件名搜索、下载完成的字幕。 共享 _shared.py 的 BASE_CSS / SHARED_JS。 页面专属:搜索框(防抖)、分页表格、手动刷新(不自动轮询)。 """ from __future__ import annotations from ._shared import render_page PAGE_SIZE = 50 SEARCH_DEBOUNCE_MS = 350 _PAGE_JS = f""" const PAGE_SIZE = {PAGE_SIZE}; const SEARCH_DEBOUNCE_MS = {SEARCH_DEBOUNCE_MS}; let currentOffset = 0; let total = 0; let searchQuery = ""; let debounceTimer = null; const tbody = document.getElementById("task-body"); const infoEl = document.getElementById("info"); const emptyEl = document.getElementById("empty"); const paginationEl = document.getElementById("pagination"); const searchInput = document.getElementById("search"); document.getElementById("refresh-btn").addEventListener("click", () => load(currentOffset)); // 搜索:输入防抖,改动后回到第一页 searchInput.addEventListener("input", () => {{ clearTimeout(debounceTimer); debounceTimer = setTimeout(() => {{ searchQuery = searchInput.value.trim(); load(0); }}, SEARCH_DEBOUNCE_MS); }}); async function load(offset) {{ currentOffset = offset; try {{ const params = new URLSearchParams({{ limit: PAGE_SIZE, offset: offset }}); if (searchQuery) params.set("q", searchQuery); const r = await fetch("/api/tasks?" + params.toString()); if (!r.ok) {{ infoEl.textContent = "HTTP " + r.status; return; }} const data = await r.json(); total = data.total; renderTable(data.tasks); renderPagination(); const end = Math.min(offset + data.tasks.length, total); const prefix = searchQuery ? `搜索“${{escapeHtml(searchQuery)}}”匹配 ` : "共 "; infoEl.textContent = total === 0 ? (searchQuery ? "无匹配任务" : "暂无任务") : `${{prefix}}${{total}} 条,显示 ${{offset + 1}}–${{end}}`; }} catch (e) {{ infoEl.textContent = "加载失败"; }} }} function renderTable(tasks) {{ tbody.innerHTML = ""; if (tasks.length === 0) {{ emptyEl.style.display = "block"; return; }} emptyEl.style.display = "none"; for (const task of tasks) {{ const tr = document.createElement("tr"); const label = STATUS_LABEL[task.status] || task.status; const stateClass = "st-" + (task.status === "done" ? "done" : task.status === "failed" ? "fail" : "running"); const created = new Date(task.created_at).toLocaleString(); let action; if (task.status === "done") {{ action = `双语` + `英` + `中`; }} else if (task.status === "failed") {{ action = `查看错误`; }} else {{ action = `—`; }} let progress; if (task.status === "done") progress = "100%"; else if (task.status === "failed") progress = "—"; else progress = `
${{task.progress.toFixed(0)}}%`; tr.innerHTML = `所有转写任务记录。可按文件名搜索,完成任务可下载字幕,进行中显示进度。
| ID | 文件名 | 状态 | 进度 | 创建时间 | 操作 |
|---|