38 lines
1.5 KiB
TypeScript
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;
|
|
}
|