"use server"; // xuchao: 考试判分——按卷面题判分,错题进错题本,达标联动数学打卡 import { revalidatePath } from "next/cache"; import { getSessionUser } from "@/lib/auth"; import { gradeAnswers, type AnswerValue } from "@/lib/grammar"; import { getPaper, paperQuestions, recordExam } from "@/lib/exam"; import { recordWrong } from "@/lib/wrongbook"; export type ExamResult = | { score: number; passed: boolean; correct: number; total: number; detail: boolean[] } | { error: string }; // 提交试卷:服务端判分、记录成绩、错题入库;可重考,取最近一次成绩 export async function takeExam(paperId: string, answers: AnswerValue[]): Promise { const user = await getSessionUser(); if (!user || user.role !== "child") return { error: "会话无效,请重新激活设备" }; const paper = await getPaper(paperId); if (!paper) return { error: "试卷不存在" }; const questions = paperQuestions(paper); if (questions.length === 0) return { error: "试卷暂无题目" }; const g = gradeAnswers(questions, answers); questions.forEach((q, i) => { if (!g.detail[i]) void recordWrong(user.id, "exam", paperId, paper.title, q, answers[i]); }); await recordExam(user.id, paperId, paper.title, g.score, g.correct, g.total, g.passed, answers); revalidatePath("/exam"); revalidatePath(`/exam/${paperId}`); revalidatePath("/kid"); revalidatePath("/parent"); revalidatePath("/wrongbook"); return g; }