fix: require manual summary fields before registration
This commit is contained in:
+67
-6
@@ -75,6 +75,14 @@ let currentSummaryReviews = [];
|
||||
let activeSummaryReview = null;
|
||||
let summaryRegisterItemSeq = 0;
|
||||
|
||||
const SUMMARY_REQUIRED_FIELDS = [
|
||||
["student", "学生"],
|
||||
["date", "日期"],
|
||||
["time", "时间"],
|
||||
["teacher", "老师"],
|
||||
["subject", "科目"],
|
||||
];
|
||||
|
||||
function fmtHours(value) {
|
||||
return Number(value || 0).toLocaleString("zh-CN", { maximumFractionDigits: 2 });
|
||||
}
|
||||
@@ -596,20 +604,73 @@ function addSummaryRegisterItem(value = "") {
|
||||
const item = document.createElement("div");
|
||||
item.className = "summary-register-item";
|
||||
item.innerHTML = `<label for="${itemId}">课程小结</label>
|
||||
<textarea id="${itemId}" rows="7" placeholder="每个输入框填写一条课程小结">${escapeHtml(value)}</textarea>
|
||||
<textarea id="${itemId}" data-summary-field="body" rows="7" placeholder="每个输入框填写一条课程小结">${escapeHtml(value)}</textarea>
|
||||
<div class="summary-register-fields">
|
||||
<input data-summary-field="student" autocomplete="off" placeholder="学生" />
|
||||
<input data-summary-field="date" autocomplete="off" placeholder="日期 2026.06.15" />
|
||||
<input data-summary-field="time" autocomplete="off" placeholder="时间 08:00-09:00" />
|
||||
<input data-summary-field="teacher" autocomplete="off" placeholder="老师" />
|
||||
<input data-summary-field="subject" autocomplete="off" placeholder="科目" />
|
||||
</div>
|
||||
<p class="summary-register-missing" hidden></p>
|
||||
<button class="small-button summary-register-remove" type="button">删除本框</button>`;
|
||||
summaryRegisterItems.appendChild(item);
|
||||
}
|
||||
|
||||
function inferSummaryField(body, field) {
|
||||
const patterns = {
|
||||
student: /(?:学生|学员)[::]\s*([^\n;;,,]+)/,
|
||||
date: /(?:日期|上课日期)[::]\s*(\d{4}[./-]\d{1,2}[./-]\d{1,2})|(\d{4}[./-]\d{1,2}[./-]\d{1,2})/,
|
||||
time: /(?:时间|上课时间)[::]\s*(\d{1,2}:\d{2}-\d{1,2}:\d{2})|(\d{1,2}:\d{2}-\d{1,2}:\d{2})/,
|
||||
teacher: /(?:老师|教师)[::]\s*([^\n;;,,]+)|([\u4e00-\u9fa5A-Za-z0-9]{1,8}老师)/,
|
||||
subject: /(?:科目|课程)[::]\s*([^\n;;,,]+)|(数学|语文|英语|物理|化学|生物|历史|地理|政治|道法)/,
|
||||
};
|
||||
const match = String(body || "").match(patterns[field]);
|
||||
if (!match) return "";
|
||||
return (match[1] || match[2] || "").trim();
|
||||
}
|
||||
|
||||
function summaryRegisterItemPayload(item) {
|
||||
const body = item.querySelector("[data-summary-field='body']").value.trim();
|
||||
const values = { body };
|
||||
SUMMARY_REQUIRED_FIELDS.forEach(([field]) => {
|
||||
const input = item.querySelector(`[data-summary-field='${field}']`);
|
||||
values[field] = input.value.trim() || inferSummaryField(body, field);
|
||||
if (!input.value.trim() && values[field]) input.value = values[field];
|
||||
});
|
||||
const missing = SUMMARY_REQUIRED_FIELDS.filter(([field]) => !values[field]).map(([, label]) => label);
|
||||
const missingNode = item.querySelector(".summary-register-missing");
|
||||
missingNode.hidden = missing.length === 0;
|
||||
missingNode.textContent = missing.length ? `请补齐:${missing.join("、")};无法补齐请删除本框,本条不会提交。` : "";
|
||||
item.classList.toggle("has-missing", missing.length > 0);
|
||||
if (!body || missing.length) return null;
|
||||
return [
|
||||
`学生:${values.student}`,
|
||||
`日期:${values.date}`,
|
||||
`时间:${values.time}`,
|
||||
`老师:${values.teacher}`,
|
||||
`科目:${values.subject}`,
|
||||
"小结:",
|
||||
body,
|
||||
].join("\n");
|
||||
}
|
||||
|
||||
function summaryRegisterLines() {
|
||||
return Array.from(summaryRegisterItems.querySelectorAll("textarea"))
|
||||
.map((textarea) => textarea.value.trim())
|
||||
.filter(Boolean);
|
||||
const items = Array.from(summaryRegisterItems.querySelectorAll(".summary-register-item"));
|
||||
const lines = items.map(summaryRegisterItemPayload).filter(Boolean);
|
||||
return {
|
||||
lines,
|
||||
blocked: items.some((item) => item.classList.contains("has-missing")),
|
||||
};
|
||||
}
|
||||
|
||||
async function submitSummaryRegister(event) {
|
||||
event.preventDefault();
|
||||
const lines = summaryRegisterLines();
|
||||
const { lines, blocked } = summaryRegisterLines();
|
||||
if (blocked) {
|
||||
summaryRegisterStatus.textContent = "还有课程小结缺字段,请补齐后再提交;无法补齐的请删除本框。";
|
||||
return;
|
||||
}
|
||||
if (!lines.length) {
|
||||
summaryRegisterStatus.textContent = "请至少填写一条课程小结";
|
||||
return;
|
||||
@@ -621,7 +682,7 @@ async function submitSummaryRegister(event) {
|
||||
headers: { "Content-Type": "application/json" },
|
||||
body: JSON.stringify({ lines }),
|
||||
});
|
||||
summaryRegisterStatus.textContent = `已接收 ${data.received} 条;自动登记 ${data.auto_registered} 条;待审核 ${data.review_pending} 条;重复 ${data.duplicates} 条;失败 ${data.rejected} 条`;
|
||||
summaryRegisterStatus.textContent = `已接收 ${data.received} 条;自动登记 ${data.auto_registered} 条;重复 ${data.duplicates} 条;舍弃 ${data.rejected} 条`;
|
||||
summaryRegisterItems.innerHTML = "";
|
||||
addSummaryRegisterItem();
|
||||
await loadAdminHealth();
|
||||
|
||||
Reference in New Issue
Block a user