Files
SuperJump/src/app/exam/actions.ts
T

38 lines
1.5 KiB
TypeScript

"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<ExamResult> {
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;
}