forked from wangziqi/gongxue-base
feat: improve student practice experience
This commit is contained in:
@@ -226,6 +226,33 @@ function judgeAnswer(row: QuestionAnswerRow, selectedOptions: string[], answerTe
|
||||
return null;
|
||||
}
|
||||
|
||||
function hasObjectiveAnswer(row: QuestionAnswerRow) {
|
||||
return normalizeNumberArray(row.correct_option_indices).length > 0 ||
|
||||
(row.correct_option_index !== null && row.correct_option_index !== undefined);
|
||||
}
|
||||
|
||||
function optionalBodyBoolean(body: Record<string, unknown>, key: string): boolean | undefined {
|
||||
const value = body[key];
|
||||
if (value === undefined || value === null) return undefined;
|
||||
if (typeof value === 'boolean') return value;
|
||||
throw new HttpError(400, `${key} must be boolean`, 'INVALID_BOOLEAN_FIELD');
|
||||
}
|
||||
|
||||
function resolveJudgedAnswer(
|
||||
row: QuestionAnswerRow,
|
||||
selectedOptions: string[],
|
||||
answerText: string,
|
||||
selfJudgedCorrect: boolean | undefined,
|
||||
) {
|
||||
if (selfJudgedCorrect !== undefined) {
|
||||
if (hasObjectiveAnswer(row)) {
|
||||
throw new HttpError(400, 'Self judgment is only allowed for subjective questions', 'SELF_JUDGMENT_NOT_ALLOWED');
|
||||
}
|
||||
return selfJudgedCorrect;
|
||||
}
|
||||
return judgeAnswer(row, selectedOptions, answerText);
|
||||
}
|
||||
|
||||
function optionalBodyString(body: Record<string, unknown>, key: string) {
|
||||
const value = body[key];
|
||||
return typeof value === 'string' && value.trim() ? value.trim() : null;
|
||||
@@ -699,6 +726,7 @@ export async function submitAnswerRoute(ctx: RequestContext) {
|
||||
const questionId = requiredString(body, 'questionId');
|
||||
const selectedOptions = optionalStringArray(body, 'selectedOptions');
|
||||
const answerText = optionalString(body, 'answerText');
|
||||
const selfJudgedCorrect = optionalBodyBoolean(body, 'selfJudgedCorrect');
|
||||
const practiceSessionId = optionalString(body, 'practiceSessionId') || null;
|
||||
|
||||
const question = await queryOne<QuestionAnswerRow>(
|
||||
@@ -717,10 +745,9 @@ export async function submitAnswerRoute(ctx: RequestContext) {
|
||||
throw new HttpError(404, 'Question not found', 'QUESTION_NOT_FOUND');
|
||||
}
|
||||
|
||||
const judged = judgeAnswer(question, selectedOptions, answerText);
|
||||
|
||||
const result = await transaction(async client => {
|
||||
await assertAnswerSessionAccess(client, { tenantId, userId, practiceSessionId, questionId });
|
||||
const judged = resolveJudgedAnswer(question, selectedOptions, answerText, selfJudgedCorrect);
|
||||
|
||||
const answerResult = await client.query(
|
||||
`
|
||||
@@ -774,7 +801,10 @@ export async function submitAnswerRoute(ctx: RequestContext) {
|
||||
[tenantId, userId, judged],
|
||||
);
|
||||
|
||||
return answerResult.rows[0];
|
||||
return {
|
||||
...answerResult.rows[0],
|
||||
selfJudged: selfJudgedCorrect !== undefined,
|
||||
};
|
||||
});
|
||||
|
||||
return { item: result };
|
||||
|
||||
Reference in New Issue
Block a user