import type { QuestionEntity, QuestionFormModel, QuestionOption, QuestionType } from './types';
|
|
import { OPTION_LABELS } from './constants';
|
|
/** 按题型生成默认答案区 */
|
export function createDefaultOptions(type: QuestionType): QuestionOption[] {
|
if (type === 'single' || type === 'multi') {
|
return OPTION_LABELS.slice(0, 4).map((label, i) => ({
|
sortNo: i + 1,
|
optionLabel: label,
|
optionContent: '',
|
isCorrect: '0',
|
}));
|
}
|
if (type === 'judge') {
|
return [
|
{ sortNo: 1, optionLabel: 'T', optionContent: '正确', isCorrect: '1' },
|
{ sortNo: 2, optionLabel: 'F', optionContent: '错误', isCorrect: '0' },
|
];
|
}
|
if (type === 'blank') {
|
return [{ sortNo: 1, optionLabel: '1', optionContent: '', isCorrect: '1' }];
|
}
|
// essay:参考答案存在 option[0]
|
return [{ sortNo: 1, optionLabel: 'A', optionContent: '', isCorrect: '1' }];
|
}
|
|
/** 表单 → 落库实体(各题型解析) */
|
export function parseFormToEntity(form: QuestionFormModel): Omit<QuestionEntity, 'bankName' | 'adminUserName' | 'creatorTime'> {
|
const options = parseOptionsByType(form);
|
return {
|
id: form.id,
|
bankId: form.bankId || '',
|
questionType: form.questionType,
|
difficulty: form.difficulty,
|
sourceType: form.sourceType,
|
stem: form.stem,
|
analysis: form.analysis,
|
bizStatus: form.bizStatus,
|
blankMixMode: form.questionType === 'blank' ? form.blankMixMode : undefined,
|
options,
|
};
|
}
|
|
export function parseOptionsByType(form: QuestionFormModel): QuestionOption[] {
|
const { questionType } = form;
|
if (questionType === 'judge') {
|
const correct = form.judgeAnswer !== false;
|
return [
|
{ sortNo: 1, optionLabel: 'T', optionContent: '正确', isCorrect: correct ? '1' : '0' },
|
{ sortNo: 2, optionLabel: 'F', optionContent: '错误', isCorrect: correct ? '0' : '1' },
|
];
|
}
|
if (questionType === 'essay') {
|
return [
|
{
|
sortNo: 1,
|
optionLabel: 'A',
|
optionContent: form.essayAnswer ?? '',
|
isCorrect: '1',
|
},
|
];
|
}
|
// single / multi / blank:直接用 options,并重排 label
|
return (form.options || []).map((opt, i) => ({
|
...opt,
|
sortNo: i + 1,
|
optionLabel: questionType === 'blank' ? String(i + 1) : OPTION_LABELS[i] || String(i + 1),
|
}));
|
}
|
|
/** 实体 → 表单回填(各题型解析) */
|
export function hydrateFormFromEntity(entity: QuestionEntity): QuestionFormModel {
|
const type = entity.questionType;
|
const options = entity.options?.length ? [...entity.options] : createDefaultOptions(type);
|
const form: QuestionFormModel = {
|
id: entity.id,
|
questionType: type,
|
bankId: entity.bankId,
|
difficulty: entity.difficulty || 'normal',
|
sourceType: entity.sourceType || 'self',
|
bizStatus: entity.bizStatus || 'closed',
|
stem: entity.stem || '',
|
analysis: entity.analysis || '',
|
options,
|
blankMixMode: !!entity.blankMixMode,
|
judgeAnswer: true,
|
essayAnswer: '',
|
};
|
|
if (type === 'judge') {
|
const correct = options.find((o) => o.isCorrect === '1');
|
form.judgeAnswer = !correct || correct.optionLabel === 'T' || correct.optionContent === '正确';
|
} else if (type === 'essay') {
|
form.essayAnswer = options[0]?.optionContent || '';
|
}
|
return form;
|
}
|
|
/** 提交前校验(按题型) */
|
export function validateAnswerByType(form: QuestionFormModel): string | null {
|
if (!form.bankId) return '请选择所属题库';
|
if (!form.stem?.trim()) return '请填写题干内容';
|
|
switch (form.questionType) {
|
case 'single': {
|
const filled = form.options.filter((o) => o.optionContent?.trim());
|
if (filled.length < 2) return '单选题至少填写 2 个选项';
|
if (form.options.filter((o) => o.isCorrect === '1').length !== 1) return '单选题必须且只能选择 1 个正确答案';
|
break;
|
}
|
case 'multi': {
|
const filled = form.options.filter((o) => o.optionContent?.trim());
|
if (filled.length < 2) return '多选题至少填写 2 个选项';
|
if (form.options.filter((o) => o.isCorrect === '1').length < 2) return '多选题至少选择 2 个正确答案';
|
break;
|
}
|
case 'judge':
|
if (form.judgeAnswer === undefined) return '请选择判断题答案';
|
break;
|
case 'blank': {
|
if (!form.options.length) return '请至少增加一个填空';
|
if (form.options.some((o) => !o.optionContent?.trim())) return '请填写每个填空的答案';
|
break;
|
}
|
case 'essay':
|
if (!form.essayAnswer?.trim()) return '请填写问答题参考答案';
|
break;
|
}
|
return null;
|
}
|
|
/** 切换题型时重置答案区 */
|
export function resetAnswerForType(type: QuestionType): Pick<QuestionFormModel, 'options' | 'judgeAnswer' | 'essayAnswer' | 'blankMixMode'> {
|
return {
|
options: createDefaultOptions(type),
|
judgeAnswer: true,
|
essayAnswer: '',
|
blankMixMode: false,
|
};
|
}
|