75 lines
3.1 KiB
JavaScript
75 lines
3.1 KiB
JavaScript
function closeDrawer() {
|
|
const el = document.getElementById("drawer");
|
|
if (el) el.classList.remove("show");
|
|
}
|
|
|
|
function esc(value) {
|
|
return String(value ?? "").replace(/[&<>"']/g, c => ({"&":"&","<":"<",">":">",'"':""","'":"'"}[c]));
|
|
}
|
|
|
|
async function openStudent(aid, sid) {
|
|
const res = await fetch(`/analysis/${aid}/api/student/${encodeURIComponent(sid)}`);
|
|
if (!res.ok) return;
|
|
const s = await res.json();
|
|
const exams = window.HB_EXAMS || [];
|
|
const rows = exams.map((exam, i) => {
|
|
const score = (s.scores || {})[exam];
|
|
const computed = (s.computed_scores || {})[exam];
|
|
const rank = (s.ranks || {})[exam];
|
|
const layer = (s.layers || {})[exam];
|
|
return `<tr>
|
|
<td>${esc(exam)}</td>
|
|
<td>${score == null ? "缺考(按 0 分)" : esc(score)}</td>
|
|
<td>${rank ?? "—"}</td><td>${layer ?? "—"}</td>
|
|
<td>${computed ?? "—"}</td>
|
|
</tr>`;
|
|
}).join("");
|
|
const box = document.getElementById("drawer");
|
|
const body = document.getElementById("drawer-body");
|
|
body.innerHTML = `
|
|
<div style="display:flex;justify-content:space-between;align-items:start">
|
|
<div>
|
|
<h2 style="margin:0">${esc(s.name)} <span class="tiny">${esc(s.sid)}</span></h2>
|
|
<div class="tiny">${esc(s.class_name)}班 · ${esc(s.group)} · ${esc(s.status || "在籍")} · ${esc(s.subjects || "")}</div>
|
|
${s.move ? `<p class="tiny">异动/备注:${esc(s.move)}</p>` : ""}
|
|
</div>
|
|
<button class="ghost" onclick="closeDrawer()">关闭</button>
|
|
</div>
|
|
<table class="table"><thead>
|
|
<tr><th>考试</th><th>原始分</th><th>方向名次</th><th>层次</th><th>计算分</th></tr>
|
|
</thead><tbody>${rows}</tbody></table>
|
|
`;
|
|
box.classList.add("show");
|
|
}
|
|
|
|
async function openClass(aid, group, target, className) {
|
|
const url = `/analysis/${aid}/api/class?group=${encodeURIComponent(group)}&target=${encodeURIComponent(target)}&class_name=${encodeURIComponent(className)}`;
|
|
const res = await fetch(url);
|
|
if (!res.ok) return;
|
|
const data = await res.json();
|
|
const lastExam = data.last_exam || (data.exams || []).slice(-1)[0];
|
|
const rows = (data.students || []).map((s) => {
|
|
const rank = (s.ranks || {})[lastExam];
|
|
const layer = (s.layers || {})[lastExam];
|
|
return `<tr class="clickable" onclick="openStudent(${aid}, '${esc(s.sid)}')">
|
|
<td>${esc(s.name)}</td><td>${esc(s.status || "")}</td>
|
|
<td>${rank ?? "—"}</td><td>${layer ?? "—"}</td>
|
|
</tr>`;
|
|
}).join("");
|
|
const box = document.getElementById("drawer");
|
|
const body = document.getElementById("drawer-body");
|
|
body.innerHTML = `
|
|
<div style="display:flex;justify-content:space-between">
|
|
<h2 style="margin:0">${esc(className)}班 · ${esc(lastExam || "")}</h2>
|
|
<button class="ghost" onclick="closeDrawer()">关闭</button>
|
|
</div>
|
|
<p class="tiny">按最后一次方向名次排序,共 ${data.n} 人。</p>
|
|
<table class="table"><thead><tr><th>姓名</th><th>学籍</th><th>名次</th><th>层次</th></tr></thead><tbody>${rows}</tbody></table>
|
|
`;
|
|
box.classList.add("show");
|
|
}
|
|
|
|
document.addEventListener("click", (e) => {
|
|
if (e.target.id === "drawer") closeDrawer();
|
|
});
|