新增解答题拍照判分:百炼 Qwen-VL 按评分点逐点判分,无 API Key 时演示判分回退;混合卷按真实分值加权计分;判分照片与评分点进错题本;补齐历史迁移缺口(0005 模板生效方式/0006 五张缺失表+grammar_progress point_id)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
4033abc21d
commit
f80a931ef0
+12
-9
@@ -63,19 +63,22 @@ export async function passedCount(childId: number): Promise<number> {
|
||||
|
||||
const norm = (s: unknown) => String(s ?? "").trim().toLowerCase();
|
||||
|
||||
// 服务端判分:五种题型 choice/judge/fill/order/match
|
||||
// 服务端判分:六种题型 choice/judge/fill/order/match/solve(solve 不在此处判,走 AI)
|
||||
export type AnswerValue = number | string | string[];
|
||||
|
||||
// xuchao: 单题客观判分(solve 返回 false,由 AI 判分链路单独处理)
|
||||
export function gradeOne(q: QuizQ, a: AnswerValue | null | undefined): boolean {
|
||||
if (q.type === "fill") return (q.answers ?? []).some((x) => norm(x) === norm(a));
|
||||
if (q.type === "order") return Array.isArray(a) && a.join(" ").trim() === (q.answer as string[]).join(" ").trim();
|
||||
if (q.type === "match") return Array.isArray(a) && (q.pairs ?? []).every((p, pi) => norm(a[pi]) === norm(p[1]));
|
||||
if (q.type === "solve") return false;
|
||||
return Number(a) === (q.answer as number);
|
||||
}
|
||||
|
||||
export function gradeAnswers(questions: QuizQ[], answers: AnswerValue[]) {
|
||||
let correct = 0;
|
||||
const detail = questions.map((q, i) => {
|
||||
const a = answers[i];
|
||||
let ok = false;
|
||||
if (q.type === "fill") ok = (q.answers ?? []).some((x) => norm(x) === norm(a));
|
||||
else if (q.type === "order")
|
||||
ok = Array.isArray(a) && a.join(" ").trim() === (q.answer as string[]).join(" ").trim();
|
||||
else if (q.type === "match")
|
||||
ok = Array.isArray(a) && (q.pairs ?? []).every((p, pi) => norm(a[pi]) === norm(p[1]));
|
||||
else ok = Number(a) === (q.answer as number);
|
||||
const ok = gradeOne(q, answers[i]);
|
||||
if (ok) correct++;
|
||||
return ok;
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user