feat: 提交热榜评论分析工具 MVP 基线
This commit is contained in:
@@ -0,0 +1 @@
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
body {
|
||||
background: #f8f9fa;
|
||||
}
|
||||
|
||||
.card {
|
||||
border-radius: 8px;
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
function readInt(id) {
|
||||
return parseInt(document.getElementById(id).value, 10) || 0;
|
||||
}
|
||||
|
||||
function updateScaleHint() {
|
||||
const total = readInt("hotspot_limit") * readInt("item_limit_per_hotspot") * readInt("comment_limit_per_item");
|
||||
const target = document.getElementById("scale-calc");
|
||||
if (target) target.textContent = total.toLocaleString();
|
||||
}
|
||||
|
||||
function validateRange(input) {
|
||||
const value = readInt(input.id);
|
||||
const min = parseInt(input.min, 10);
|
||||
const max = parseInt(input.max, 10);
|
||||
const valid = value >= min && value <= max;
|
||||
input.classList.toggle("is-invalid", !valid);
|
||||
return valid;
|
||||
}
|
||||
|
||||
async function submitTask(event) {
|
||||
event.preventDefault();
|
||||
const btn = document.getElementById("submit-btn");
|
||||
const errorBox = document.getElementById("form-error");
|
||||
const inputs = Array.from(document.querySelectorAll(".scale-input"));
|
||||
if (!inputs.every(validateRange)) {
|
||||
errorBox.textContent = "参数超出范围,请检查配置。";
|
||||
errorBox.classList.remove("d-none");
|
||||
return;
|
||||
}
|
||||
|
||||
btn.disabled = true;
|
||||
btn.textContent = "提交中...";
|
||||
errorBox.classList.add("d-none");
|
||||
const payload = {
|
||||
platform: document.getElementById("platform").value,
|
||||
hotspot_limit: readInt("hotspot_limit"),
|
||||
item_limit_per_hotspot: readInt("item_limit_per_hotspot"),
|
||||
comment_limit_per_item: readInt("comment_limit_per_item"),
|
||||
};
|
||||
|
||||
try {
|
||||
const resp = await fetch("/api/tasks", {
|
||||
method: "POST",
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify(payload),
|
||||
});
|
||||
if (resp.ok) {
|
||||
const data = await resp.json();
|
||||
window.location.href = `/tasks/${data.task_id}`;
|
||||
return;
|
||||
}
|
||||
const data = await resp.json();
|
||||
errorBox.textContent = resp.status === 422 ? "参数错误,请检查配置。" : (data.detail || "服务器错误,请稍后重试。");
|
||||
errorBox.classList.remove("d-none");
|
||||
} catch (_error) {
|
||||
errorBox.textContent = "网络异常,请检查连接后重试。";
|
||||
errorBox.classList.remove("d-none");
|
||||
} finally {
|
||||
btn.disabled = false;
|
||||
btn.textContent = "开始抓取";
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", () => {
|
||||
document.querySelectorAll(".scale-input").forEach((input) => {
|
||||
input.addEventListener("input", () => {
|
||||
validateRange(input);
|
||||
updateScaleHint();
|
||||
});
|
||||
});
|
||||
updateScaleHint();
|
||||
});
|
||||
|
||||
async function downloadExport(url, defaultFilename, event) {
|
||||
if (event) event.preventDefault();
|
||||
const resp = await fetch(url);
|
||||
if (!resp.ok) {
|
||||
alert("导出失败,请稍后重试。");
|
||||
return;
|
||||
}
|
||||
const blob = await resp.blob();
|
||||
const disposition = resp.headers.get("Content-Disposition") || "";
|
||||
const match = disposition.match(/filename\*=UTF-8''([^;]+)/);
|
||||
const filename = match ? decodeURIComponent(match[1]) : defaultFilename;
|
||||
const blobUrl = URL.createObjectURL(blob);
|
||||
const link = document.createElement("a");
|
||||
link.href = blobUrl;
|
||||
link.download = filename;
|
||||
document.body.appendChild(link);
|
||||
link.click();
|
||||
document.body.removeChild(link);
|
||||
URL.revokeObjectURL(blobUrl);
|
||||
}
|
||||
Reference in New Issue
Block a user