新增积分系统:打卡/测试达标赚积分,纯累计可配置
- point_rule 规则表 + point_log 流水表(0008 迁移),唯一键防刷:同一事件首次达标才发放,重复静默返回 0 - 打卡分值随任务设置(模板/实例 points 字段,默认 10);测试类 6 种事件按规则表取值,各有默认分(单词 20/数学课 15/语法点 15/周测 50×2/考试通过 100) - 发放埋点 6 处:打卡、单词检测、数学课、语法知识点、英语/数学周测、考试通过;周测达标联动打卡实例不重复计分 - 孩子端:/kid 总积分徽章,新增 /points 积分页(总积分+流水),测验结果页即时显示「+N 积分」,周测结果页刷新后从流水取回已发积分 - 家长端:功能管理新增「积分管理」Section(规则分值配置+每孩子总积分/最近流水);任务管理内联编辑任务分值 - 修复:drizzle 将 mysql2 重复键错误包进 cause,沿错误链识别 ER_DUP_ENTRY Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
841f937b8e
commit
7a11a89031
+14
-5
@@ -25,7 +25,15 @@ export type SolveDetail = {
|
||||
};
|
||||
|
||||
export type ExamResult =
|
||||
| { score: number; passed: boolean; correct: number; total: number; detail: boolean[]; solves?: SolveDetail[] }
|
||||
| {
|
||||
score: number;
|
||||
passed: boolean;
|
||||
correct: number;
|
||||
total: number;
|
||||
detail: boolean[];
|
||||
solves?: SolveDetail[];
|
||||
pointsEarned: number;
|
||||
}
|
||||
| { error: string };
|
||||
|
||||
// xuchao: 签发解答题照片直传地址(或本地开发回退)
|
||||
@@ -109,9 +117,9 @@ export async function takeExam(paperId: string, answers: (AnswerValue | null)[])
|
||||
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);
|
||||
const pointsEarned = await recordExam(user.id, paperId, paper.title, g.score, g.correct, g.total, g.passed, answers);
|
||||
revalidateAll(paperId);
|
||||
return g;
|
||||
return { ...g, pointsEarned };
|
||||
}
|
||||
|
||||
// xuchao: 混合卷加权判分——解答题只信服务端最近一次判定,不信任客户端上报
|
||||
@@ -167,9 +175,9 @@ export async function takeExam(paperId: string, answers: (AnswerValue | null)[])
|
||||
|
||||
const score = pointSum ? Math.round((earnedSum / pointSum) * 100) : 0;
|
||||
const passed = score >= 80;
|
||||
await recordExam(user.id, paperId, paper.title, score, correct, questions.length, passed, storedAnswers);
|
||||
const pointsEarned = await recordExam(user.id, paperId, paper.title, score, correct, questions.length, passed, storedAnswers);
|
||||
revalidateAll(paperId);
|
||||
return { score, passed, correct, total: questions.length, detail, solves };
|
||||
return { score, passed, correct, total: questions.length, detail, solves, pointsEarned };
|
||||
}
|
||||
|
||||
function revalidateAll(paperId: string) {
|
||||
@@ -178,4 +186,5 @@ function revalidateAll(paperId: string) {
|
||||
revalidatePath("/kid");
|
||||
revalidatePath("/parent");
|
||||
revalidatePath("/wrongbook");
|
||||
revalidatePath("/points");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user