fix: MC options display, question selection, timeout handling, and grading prompts

This commit is contained in:
Developer
2026-06-03 20:58:19 +08:00
parent a71bde3452
commit 6d9acd7252
12 changed files with 408 additions and 157 deletions
@@ -456,10 +456,6 @@ export class QuestionBankService {
): Promise<QuestionBankItem[]> {
const bank = await this.findOne(bankId);
if (bank.status !== QuestionBankStatus.DRAFT) {
throw new ForbiddenException('仅草稿状态的题库可生成题目');
}
if (count <= 0 || count > 50) {
throw new BadRequestException('生成数量必须在 1-50 之间');
}
@@ -523,6 +519,7 @@ export class QuestionBankService {
async selectQuestions(
bankId: string,
count: number,
dimensionWeights?: Array<{ name: string; weight: number }>,
): Promise<QuestionBankItem[]> {
const bank = await this.findOne(bankId);
@@ -537,40 +534,51 @@ export class QuestionBankService {
const usedIds = new Set<string>();
const selected: QuestionBankItem[] = [];
const availableItems = [...allItems];
let availableItems = [...allItems];
let dimIdx = 0;
while (selected.length < count && availableItems.length > 0) {
const dim = DIMENSIONS[dimIdx % DIMENSIONS.length];
dimIdx++;
const available = availableItems.filter(
(i) => i.dimension === dim && !usedIds.has(i.id),
);
if (available.length > 0) {
const idx = Math.floor(Math.random() * available.length);
const item = available[idx];
selected.push(item);
usedIds.add(item.id);
const actualIdx = availableItems.findIndex(i => i.id === item.id);
if (actualIdx > -1) {
availableItems.splice(actualIdx, 1);
if (dimensionWeights && dimensionWeights.length > 0) {
const totalWeight = dimensionWeights.reduce((s, d) => s + d.weight, 0);
for (const dw of dimensionWeights) {
const dimName = dw.name as QuestionDimension;
const targetForDim = Math.round(count * dw.weight / totalWeight);
const pool = availableItems.filter(i => i.dimension === dimName && !usedIds.has(i.id));
this.shuffleArray(pool);
const take = Math.min(targetForDim, pool.length);
for (let i = 0; i < take; i++) {
selected.push(pool[i]);
usedIds.add(pool[i].id);
}
}
if (dimIdx >= DIMENSIONS.length * 3) {
break;
availableItems = availableItems.filter(i => !usedIds.has(i.id));
this.shuffleArray(availableItems);
while (selected.length < count && availableItems.length > 0) {
const item = availableItems.pop()!;
selected.push(item);
usedIds.add(item.id);
}
}
if (selected.length < count && availableItems.length > 0) {
const shuffled = this.shuffleArray([...availableItems]);
for (const item of shuffled) {
if (selected.length >= count) break;
if (!usedIds.has(item.id)) {
} else {
let dimIdx = 0;
while (selected.length < count && availableItems.length > 0) {
const dim = DIMENSIONS[dimIdx % DIMENSIONS.length];
dimIdx++;
const pool = availableItems.filter(i => i.dimension === dim && !usedIds.has(i.id));
if (pool.length > 0) {
const idx = Math.floor(Math.random() * pool.length);
const item = pool[idx];
selected.push(item);
usedIds.add(item.id);
availableItems = availableItems.filter(i => i.id !== item.id);
}
if (dimIdx >= DIMENSIONS.length * 3) break;
}
if (selected.length < count && availableItems.length > 0) {
this.shuffleArray(availableItems);
for (const item of availableItems) {
if (selected.length >= count) break;
if (!usedIds.has(item.id)) {
selected.push(item);
usedIds.add(item.id);
}
}
}
}
@@ -49,6 +49,7 @@ export class TemplateService {
const { ...data } = createDto;
const template = this.templateRepository.create({
...data,
isActive: data.isActive !== undefined ? data.isActive : true,
createdBy: userId,
tenantId,
});