Files
hot_comment_radar/app/static/app.js
T

114 lines
3.4 KiB
JavaScript

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();
});
function pollTaskDetailStatus(taskId) {
if (!taskId) return;
const intervalMs = 3000;
const poll = async () => {
try {
const resp = await fetch(`/api/tasks/${taskId}`, { cache: "no-store" });
if (!resp.ok) return;
const task = await resp.json();
if (task.status !== "running") {
window.location.reload();
return;
}
} catch (_error) {
return;
}
window.setTimeout(poll, intervalMs);
};
window.setTimeout(poll, intervalMs);
}
function pollTaskListStatus() {
const tableBody = document.querySelector("[data-task-list-auto-poll='true']");
if (!tableBody) return;
const intervalMs = 5000;
const poll = async () => {
try {
const resp = await fetch("/api/tasks", { cache: "no-store" });
if (!resp.ok) return;
const tasks = await resp.json();
const hasRunningTask = tasks.some((task) => task.status === "running");
window.location.reload();
if (!hasRunningTask) return;
} catch (_error) {
return;
}
window.setTimeout(poll, intervalMs);
};
window.setTimeout(poll, intervalMs);
}