const state = { data: null };
const statusLabels = {
normal: "正常",
risk: "有风险",
need_help: "需要支持"
};
function text(value) {
return String(value || "");
}
function escapeHtml(value) {
return text(value).replace(/[&<>"']/g, (char) => ({
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'"
}[char]));
}
function render() {
const employeeQuery = document.querySelector("#employee-filter").value.trim().toLowerCase();
const keywordQuery = document.querySelector("#keyword-filter").value.trim().toLowerCase();
const onlyBlockers = document.querySelector("#blocker-filter").checked;
const data = state.data;
document.querySelector("#stats").innerHTML = `
应提交:${data.expectedCount}
已提交:${data.submittedCount}
未提交:${data.missingCount}
`;
const reports = data.reports.filter((report) => {
const employeeMatch = report.employee_name.toLowerCase().includes(employeeQuery);
const searchable = [
report.today_done,
report.tomorrow_plan,
report.blockers,
report.help_needed,
statusLabels[report.report_status]
].join(" ").toLowerCase();
const keywordMatch = searchable.includes(keywordQuery);
const blockerMatch = !onlyBlockers || report.blockers || report.help_needed || report.report_status === "need_help";
return employeeMatch && keywordMatch && blockerMatch;
});
document.querySelector("#reports").innerHTML = reports.length ? reports.map((report) => `
${escapeHtml(report.employee_name)}
${statusLabels[report.report_status] || "正常"}
今日完成
${escapeHtml(report.today_done)}
明日计划
${escapeHtml(report.tomorrow_plan)}
遇到的问题
${escapeHtml(report.blockers || "无")}
需要协助
${escapeHtml(report.help_needed || "无")}
提交时间:${escapeHtml(report.updated_at)}
`).join("") : "当前筛选下没有日报。
";
document.querySelector("#missing").textContent = data.missing.length
? data.missing.map((employee) => employee.name).join("、")
: "无";
}
async function loadReports() {
const date = document.querySelector("#date-filter").value;
document.querySelector("#export-link").href = `/api/reports/export?date=${date}`;
const response = await fetch(`/api/reports?date=${date}`);
state.data = await response.json();
render();
}
document.querySelector("#date-filter").addEventListener("change", loadReports);
document.querySelector("#employee-filter").addEventListener("input", render);
document.querySelector("#keyword-filter").addEventListener("input", render);
document.querySelector("#blocker-filter").addEventListener("change", render);
document.querySelector("#copy-summary").addEventListener("click", async () => {
const data = state.data;
const lines = [
`${data.date} 日报汇总`,
`已提交:${data.submittedCount}/${data.expectedCount}`,
`未提交:${data.missing.length ? data.missing.map((employee) => employee.name).join("、") : "无"}`
];
await navigator.clipboard.writeText(lines.join("\n"));
});
loadReports();