diff --git a/static/app.js b/static/app.js index 0c8d1aa..aec3441 100644 --- a/static/app.js +++ b/static/app.js @@ -79,10 +79,28 @@ function taskStatusBadge(t) { return '未运行'; } +const GROUPS = [ + { key: "batch", label: "📄 批量爬取", desc: "一次性爬取指定网址列表" }, + { key: "scheduled", label: "⏰ 定时爬取", desc: "按间隔或 cron 表达式定时执行" }, + { key: "auto", label: "🤖 自动爬取", desc: "从起始网址自动发现链接并爬取" }, +]; + function renderTasks() { const box = $("taskList"); $("emptyState").classList.toggle("hidden", state.tasks.length > 0); - box.innerHTML = state.tasks.map(taskCard).join(""); + box.innerHTML = GROUPS.map((g) => { + const items = state.tasks.filter((t) => t.mode === g.key); + if (!items.length) return ""; + return ` +
+
+ ${g.label} + ${g.desc} + ${items.length} 个任务 +
+
${items.map(taskCard).join("")}
+
`; + }).join(""); } function taskCard(t) { diff --git a/static/style.css b/static/style.css index 863414c..7684ffb 100644 --- a/static/style.css +++ b/static/style.css @@ -85,6 +85,16 @@ main { padding: 20px 24px; max-width: 1500px; margin: 0 auto; } .stat-num.num-run { color: var(--accent); } .stat-label { font-size: 12px; color: var(--muted); margin-top: 3px; } +/* ---------- 分组展示 ---------- */ +.group { display: flex; flex-direction: column; gap: 12px; margin-bottom: 24px; } +.group-head { display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; } +.group-title { font-size: 16px; font-weight: 700; } +.group-desc { font-size: 12px; color: var(--muted); } +.group-count { + font-size: 11px; padding: 2px 10px; border-radius: 10px; + background: var(--panel2); border: 1px solid var(--border); color: var(--muted); +} + /* ---------- task grid ---------- */ .task-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(380px, 1fr)); gap: 16px; } .card {