ai-question-pro 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/demo/src/main.vue +340 -125
- package/components/demo/src/questionItem.vue +8 -8
- package/dist/ai-question-pro.common.js +296 -263
- package/dist/ai-question-pro.common.js.map +1 -1
- package/dist/ai-question-pro.umd.js +296 -263
- package/dist/ai-question-pro.umd.js.map +1 -1
- package/dist/ai-question-pro.umd.min.js +4 -4
- package/dist/ai-question-pro.umd.min.js.map +1 -1
- package/package.json +1 -1
|
@@ -9,41 +9,41 @@
|
|
|
9
9
|
<img src="../static/logo.png" alt="" style="width: 32px; height: 18px;"/>
|
|
10
10
|
<span>出题</span>
|
|
11
11
|
</div>
|
|
12
|
-
<div class="ai-bot-switch-wrap" style="position: absolute; left: 120px"
|
|
13
|
-
<div class="ai-bot-switch" @click="dropdownVisible = !dropdownVisible"
|
|
14
|
-
<img src="../static/aiBot-icon.png" alt="" style="width: 24px; height: 24px"
|
|
15
|
-
<span class="ai-bot-label"
|
|
16
|
-
{{ currentBot === 'course' ? '课程智能体' : '通义千问' }}
|
|
17
|
-
</span
|
|
18
|
-
<img src="../static/check-icon.png" alt="" style="width: 12px; height: 12px"
|
|
19
|
-
</div
|
|
20
|
-
<div
|
|
21
|
-
v-if="dropdownVisible"
|
|
22
|
-
class="ai-bot-dropdown"
|
|
23
|
-
@mousedown.prevent
|
|
24
|
-
style="position: absolute; z-index: 1000; min-width: 20%;"
|
|
25
|
-
|
|
26
|
-
<div
|
|
27
|
-
class="ai-bot-dropdown-item"
|
|
28
|
-
:class="{ active: currentBot === 'tongyi' }"
|
|
29
|
-
@click="selectBot('tongyi')"
|
|
30
|
-
>通义千问
|
|
31
|
-
</div>
|
|
12
|
+
<!-- <div class="ai-bot-switch-wrap" style="position: absolute; left: 120px">-->
|
|
13
|
+
<!-- <div class="ai-bot-switch" @click="dropdownVisible = !dropdownVisible">-->
|
|
14
|
+
<!-- <img src="../static/aiBot-icon.png" alt="" style="width: 24px; height: 24px">-->
|
|
15
|
+
<!-- <span class="ai-bot-label">-->
|
|
16
|
+
<!-- {{ currentBot === 'course' ? '课程智能体' : '通义千问' }}-->
|
|
17
|
+
<!-- </span>-->
|
|
18
|
+
<!-- <img src="../static/check-icon.png" alt="" style="width: 12px; height: 12px">-->
|
|
19
|
+
<!-- </div>-->
|
|
20
|
+
<!-- <div-->
|
|
21
|
+
<!-- v-if="dropdownVisible"-->
|
|
22
|
+
<!-- class="ai-bot-dropdown"-->
|
|
23
|
+
<!-- @mousedown.prevent-->
|
|
24
|
+
<!-- style="position: absolute; z-index: 1000; min-width: 20%;"-->
|
|
25
|
+
<!-- >-->
|
|
32
26
|
<!-- <div-->
|
|
33
|
-
<!-- v-if="courseId"-->
|
|
34
27
|
<!-- class="ai-bot-dropdown-item"-->
|
|
35
|
-
<!-- :class="{ active: currentBot === '
|
|
36
|
-
<!-- @click="selectBot('
|
|
37
|
-
<!--
|
|
28
|
+
<!-- :class="{ active: currentBot === 'tongyi' }"-->
|
|
29
|
+
<!-- @click="selectBot('tongyi')"-->
|
|
30
|
+
<!-- >通义千问-->
|
|
38
31
|
<!-- </div>-->
|
|
39
|
-
|
|
40
|
-
|
|
32
|
+
<!--<!– <div–>-->
|
|
33
|
+
<!--<!– v-if="courseId"–>-->
|
|
34
|
+
<!--<!– class="ai-bot-dropdown-item"–>-->
|
|
35
|
+
<!--<!– :class="{ active: currentBot === 'course' }"–>-->
|
|
36
|
+
<!--<!– @click="selectBot('course')"–>-->
|
|
37
|
+
<!--<!– >课程智能体–>-->
|
|
38
|
+
<!--<!– </div>–>-->
|
|
39
|
+
<!-- </div>-->
|
|
40
|
+
<!-- </div>-->
|
|
41
41
|
</template>
|
|
42
42
|
<div class="add_question_body">
|
|
43
43
|
<div class="question-type-header">
|
|
44
44
|
<span class="required-mark">*</span>
|
|
45
45
|
<span class="section-title">题目类型:</span>
|
|
46
|
-
<span class="tip-text">(
|
|
46
|
+
<span class="tip-text">(为避免您等待时间过长,所选择题型数量总和最好不超过10道</span>
|
|
47
47
|
</div>
|
|
48
48
|
|
|
49
49
|
<!-- 题目类型列表 -->
|
|
@@ -160,6 +160,12 @@
|
|
|
160
160
|
</div>
|
|
161
161
|
</div>
|
|
162
162
|
<div class="question_body" ref="generateDiv">
|
|
163
|
+
<div v-if="isGenerating" class="generating-loading">
|
|
164
|
+
<div class="loading-content">
|
|
165
|
+
<div class="loading-spinner"></div>
|
|
166
|
+
<div class="loading-text">AI生成中...</div>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
163
169
|
<questionItem v-if="aiResponse.questions && aiResponse.questions.length > 0" @agree="agree" @join="join"
|
|
164
170
|
@selectionChange="handleQuestionSelection"
|
|
165
171
|
:isJoined="joinedQuestions.includes(idx)"
|
|
@@ -293,7 +299,7 @@ export default {
|
|
|
293
299
|
{name: '简答题', id: 'shortanswer'},
|
|
294
300
|
],
|
|
295
301
|
difficultyList: [
|
|
296
|
-
{name: '
|
|
302
|
+
{name: '非常简单', id: 0},
|
|
297
303
|
{name: '简单', id: 1},
|
|
298
304
|
{name: '一般', id: 2},
|
|
299
305
|
{name: '困难', id: 3},
|
|
@@ -306,6 +312,10 @@ export default {
|
|
|
306
312
|
currentBot: 'tongyi',
|
|
307
313
|
selectedQuestions: [], // 存储选中的题目
|
|
308
314
|
joinedQuestions: [], // 存储已加入题库的题目索引
|
|
315
|
+
retryCountMap: {}, // 存储每个题目的重试次数
|
|
316
|
+
isGenerating: false, // 内部loading状态
|
|
317
|
+
typeGeneratedCounts: {}, // 跟踪每个题型已生成的数量
|
|
318
|
+
pendingGenerations: [], // 待生成的题目队列
|
|
309
319
|
}
|
|
310
320
|
},
|
|
311
321
|
watch: {
|
|
@@ -440,6 +450,15 @@ export default {
|
|
|
440
450
|
return this.$message.warning('请至少选择一种题目类型')
|
|
441
451
|
}
|
|
442
452
|
|
|
453
|
+
// 验证选中的题目类型是否都输入了数量
|
|
454
|
+
for (let type of selectedTypes) {
|
|
455
|
+
const count = this.form.typeCounts[type]
|
|
456
|
+
if (!count || count <= 0) {
|
|
457
|
+
const typeName = this.quesTypeList.find(item => item.id === type)?.name || type
|
|
458
|
+
return this.$message.warning(`请为${typeName}输入生成数量`)
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
443
462
|
// 验证是否选择了知识点
|
|
444
463
|
if (!this.form.knowledgeIds) {
|
|
445
464
|
return this.$message.warning('请选择关联知识点')
|
|
@@ -483,6 +502,7 @@ export default {
|
|
|
483
502
|
if (this.generateCount == totalCount) {
|
|
484
503
|
this.$message.success('题目(' + totalCount + '道)全部生成完毕!');
|
|
485
504
|
this.rebuildFlag = false;
|
|
505
|
+
this.isGenerating = false;
|
|
486
506
|
} else {
|
|
487
507
|
this.$message.success('生成' + this.generateCount + '道题目成功');
|
|
488
508
|
}
|
|
@@ -492,138 +512,153 @@ export default {
|
|
|
492
512
|
});
|
|
493
513
|
},
|
|
494
514
|
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
this.
|
|
498
|
-
|
|
499
|
-
|
|
515
|
+
// 重新生成失败的题目 - 需要指定具体的题型和难度
|
|
516
|
+
reSend(failedQuestionType = null, failedDifficulty = null) {
|
|
517
|
+
this.isGenerating = true;
|
|
518
|
+
|
|
519
|
+
// 如果没有指定失败的题型,则需要分析哪个题型还缺少题目
|
|
520
|
+
let targetType = failedQuestionType;
|
|
521
|
+
let targetDifficulty = failedDifficulty;
|
|
522
|
+
|
|
523
|
+
if (!targetType) {
|
|
524
|
+
// 分析哪个题型的数量不足
|
|
525
|
+
const selectedTypes = Object.keys(this.form.selectedTypes).filter(key => this.form.selectedTypes[key]);
|
|
526
|
+
for (let type of selectedTypes) {
|
|
527
|
+
const expectedCount = this.form.typeCounts[type];
|
|
528
|
+
const actualCount = this.typeGeneratedCounts[type] || 0;
|
|
529
|
+
if (actualCount < expectedCount) {
|
|
530
|
+
targetType = type;
|
|
531
|
+
targetDifficulty = this.form.typeDifficulties[type];
|
|
532
|
+
break;
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
// 如果找不到需要补充的题型,说明数量已经足够
|
|
538
|
+
if (!targetType) {
|
|
539
|
+
this.isGenerating = false;
|
|
540
|
+
return;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// 使用 generateSingleQuestion 方法来生成指定题型
|
|
544
|
+
this.generateSingleQuestion(targetType, targetDifficulty);
|
|
545
|
+
},
|
|
546
|
+
|
|
547
|
+
//发送请求
|
|
548
|
+
sendPost() {
|
|
549
|
+
checkVersion(this.businessSource).then(res => {
|
|
550
|
+
console.log(res);
|
|
551
|
+
if (res.errCode === '403') {
|
|
552
|
+
this.$message.warning(res.errMessage)
|
|
553
|
+
} else {
|
|
554
|
+
this.postQuestion();
|
|
555
|
+
}
|
|
500
556
|
});
|
|
557
|
+
},
|
|
558
|
+
|
|
559
|
+
postQuestion() {
|
|
560
|
+
this.rebuildFlag = true;
|
|
561
|
+
this.generateCount = 0;
|
|
562
|
+
this.aiResponse = {}
|
|
563
|
+
this.isGenerating = true;
|
|
564
|
+
|
|
565
|
+
// 初始化题型生成计数器
|
|
566
|
+
this.typeGeneratedCounts = {};
|
|
567
|
+
this.pendingGenerations = [];
|
|
501
568
|
|
|
502
569
|
const selectedTypes = Object.keys(this.form.selectedTypes).filter(key => this.form.selectedTypes[key])
|
|
503
|
-
const questionTypes = selectedTypes
|
|
504
|
-
const difficultys = selectedTypes.map(type => this.form.typeDifficulties[type])
|
|
505
570
|
|
|
571
|
+
// 初始化每个题型的计数器和待生成队列
|
|
572
|
+
selectedTypes.forEach(type => {
|
|
573
|
+
this.typeGeneratedCounts[type] = 0;
|
|
574
|
+
const count = this.form.typeCounts[type] || 1;
|
|
575
|
+
|
|
576
|
+
// 将每个需要生成的题目加入队列
|
|
577
|
+
for (let i = 0; i < count; i++) {
|
|
578
|
+
this.pendingGenerations.push({
|
|
579
|
+
type: type,
|
|
580
|
+
difficulty: this.form.typeDifficulties[type],
|
|
581
|
+
index: i
|
|
582
|
+
});
|
|
583
|
+
}
|
|
584
|
+
});
|
|
585
|
+
|
|
586
|
+
// 开始生成题目
|
|
587
|
+
this.pendingGenerations.forEach(item => {
|
|
588
|
+
this.generateSingleQuestion(item.type, item.difficulty);
|
|
589
|
+
});
|
|
590
|
+
},
|
|
591
|
+
|
|
592
|
+
// 生成单个题目的方法
|
|
593
|
+
generateSingleQuestion(questionType, difficulty) {
|
|
506
594
|
let obj = {
|
|
507
595
|
modelType: 'aliyun',
|
|
508
596
|
questionAddCmd: {
|
|
509
|
-
questionTypes:
|
|
597
|
+
questionTypes: [questionType], // 指定单个题型
|
|
510
598
|
count: 1,
|
|
511
599
|
knowledge: this.form.knowledge.join(' '),
|
|
512
600
|
knowledgeId: this.form.knowledgeId[this.form.knowledgeId.length - 1],
|
|
513
|
-
difficultys:
|
|
601
|
+
difficultys: [difficulty],
|
|
514
602
|
prompt: this.form.prompt
|
|
515
603
|
},
|
|
516
604
|
sessionId: this.aiResponse.sessionId ? this.aiResponse.sessionId : '',
|
|
517
605
|
businessSource: this.businessSource,
|
|
518
606
|
courseId: this.courseId,
|
|
519
607
|
}
|
|
520
|
-
|
|
608
|
+
|
|
521
609
|
getAiQuestion(obj).then(res => {
|
|
522
610
|
if (res.success) {
|
|
523
|
-
this.loading && this.loading.close()
|
|
524
611
|
if (res.data && res.data.questions && res.data.questions.length > 0) {
|
|
612
|
+
const newQuestion = res.data.questions[0];
|
|
613
|
+
|
|
614
|
+
// 检查是否有重复的题目标题和题型
|
|
615
|
+
const isDuplicate = this.checkDuplicateQuestion(newQuestion, questionType);
|
|
616
|
+
|
|
617
|
+
if (isDuplicate) {
|
|
618
|
+
// 重复题目,重新生成
|
|
619
|
+
const repetitionQuestions = this.getGeneratedQuestionsByType(questionType);
|
|
620
|
+
this.regenerateWithRepetition(obj, repetitionQuestions, questionType);
|
|
621
|
+
return;
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// 验证返回的题目类型是否正确
|
|
625
|
+
if (newQuestion.type && newQuestion.type !== questionType) {
|
|
626
|
+
console.log(`期望题型: ${questionType}, 实际题型: ${newQuestion.type}, 重新生成`);
|
|
627
|
+
this.generateSingleQuestion(questionType, difficulty);
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
|
|
525
631
|
if (this.aiResponse.questions && this.aiResponse.questions.length > 0) {
|
|
526
|
-
this.aiResponse.questions.push(
|
|
632
|
+
this.aiResponse.questions.push(newQuestion);
|
|
527
633
|
} else {
|
|
528
634
|
this.aiResponse = res.data;
|
|
529
635
|
}
|
|
530
|
-
this.$set(
|
|
636
|
+
this.$set(newQuestion, 'evaluate', 0)
|
|
637
|
+
// 设置题目类型,便于后续统计
|
|
638
|
+
this.$set(newQuestion, 'type', questionType)
|
|
639
|
+
|
|
640
|
+
// 更新该题型的生成计数
|
|
641
|
+
this.typeGeneratedCounts[questionType]++;
|
|
642
|
+
|
|
531
643
|
this.showGenerateResult();
|
|
532
644
|
} else {
|
|
533
645
|
this.$message.warning('题目获取失败,重新生成中...')
|
|
534
|
-
|
|
646
|
+
// 重新生成指定题型
|
|
647
|
+
this.generateSingleQuestion(questionType, difficulty);
|
|
535
648
|
}
|
|
536
649
|
} else {
|
|
537
|
-
this.
|
|
650
|
+
this.isGenerating = false;
|
|
538
651
|
this.$message.warning('题目获取失败')
|
|
539
652
|
this.rebuildFlag = false;
|
|
540
653
|
}
|
|
541
654
|
}).catch(error => {
|
|
542
655
|
console.log("error:" + error);
|
|
543
|
-
this.
|
|
656
|
+
this.isGenerating = false;
|
|
544
657
|
this.$message.warning('题目获取失败')
|
|
545
658
|
this.rebuildFlag = false;
|
|
546
659
|
})
|
|
547
660
|
},
|
|
548
661
|
|
|
549
|
-
//发送请求
|
|
550
|
-
sendPost() {
|
|
551
|
-
checkVersion(this.businessSource).then(res => {
|
|
552
|
-
console.log(res);
|
|
553
|
-
if (res.errCode === '403') {
|
|
554
|
-
this.$message.warning(res.errMessage)
|
|
555
|
-
} else {
|
|
556
|
-
this.postQuestion();
|
|
557
|
-
}
|
|
558
|
-
});
|
|
559
|
-
},
|
|
560
|
-
|
|
561
|
-
postQuestion() {
|
|
562
|
-
this.rebuildFlag = true;
|
|
563
|
-
this.generateCount = 0;
|
|
564
|
-
this.aiResponse = {}
|
|
565
|
-
this.loading && this.loading.close()
|
|
566
|
-
this.loading = this.$loading({
|
|
567
|
-
target: '.el-dialog',
|
|
568
|
-
text: 'AI生成中...'
|
|
569
|
-
});
|
|
570
|
-
|
|
571
|
-
const selectedTypes = Object.keys(this.form.selectedTypes).filter(key => this.form.selectedTypes[key])
|
|
572
|
-
|
|
573
|
-
// 按题型分别生成题目
|
|
574
|
-
selectedTypes.forEach(type => {
|
|
575
|
-
const count = this.form.typeCounts[type] || 1;
|
|
576
|
-
const difficulty = this.form.typeDifficulties[type];
|
|
577
|
-
|
|
578
|
-
// 为每种题型生成指定数量的题目
|
|
579
|
-
for (let i = 0; i < count; i++) {
|
|
580
|
-
let obj = {
|
|
581
|
-
modelType: 'aliyun',
|
|
582
|
-
questionAddCmd: {
|
|
583
|
-
questionTypes: [type], // 单个题型
|
|
584
|
-
count: 1,
|
|
585
|
-
knowledge: this.form.knowledge.join(' '),
|
|
586
|
-
knowledgeId: this.form.knowledgeId[this.form.knowledgeId.length - 1],
|
|
587
|
-
difficultys: [difficulty], // 对应的难度
|
|
588
|
-
prompt: this.form.prompt
|
|
589
|
-
},
|
|
590
|
-
sessionId: this.aiResponse.sessionId ? this.aiResponse.sessionId : '',
|
|
591
|
-
businessSource: this.businessSource,
|
|
592
|
-
courseId: this.courseId,
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
getAiQuestion(obj).then(res => {
|
|
596
|
-
if (res.success) {
|
|
597
|
-
this.loading && this.loading.close()
|
|
598
|
-
if (res.data && res.data.questions && res.data.questions.length > 0) {
|
|
599
|
-
if (this.aiResponse.questions && this.aiResponse.questions.length > 0) {
|
|
600
|
-
this.aiResponse.questions.push(res.data.questions[0]);
|
|
601
|
-
} else {
|
|
602
|
-
this.aiResponse = res.data;
|
|
603
|
-
}
|
|
604
|
-
this.$set(res.data.questions[0], 'evaluate', 0)
|
|
605
|
-
// 设置题目类型,便于后续统计
|
|
606
|
-
this.$set(res.data.questions[0], 'type', type)
|
|
607
|
-
this.showGenerateResult();
|
|
608
|
-
} else {
|
|
609
|
-
this.$message.warning('题目获取失败,重新生成中...')
|
|
610
|
-
return this.reSend()
|
|
611
|
-
}
|
|
612
|
-
} else {
|
|
613
|
-
this.loading && this.loading.close()
|
|
614
|
-
this.$message.warning('题目获取失败')
|
|
615
|
-
this.rebuildFlag = false;
|
|
616
|
-
}
|
|
617
|
-
}).catch(error => {
|
|
618
|
-
console.log("error:" + error);
|
|
619
|
-
this.loading && this.loading.close()
|
|
620
|
-
this.$message.warning('题目获取失败')
|
|
621
|
-
this.rebuildFlag = false;
|
|
622
|
-
})
|
|
623
|
-
}
|
|
624
|
-
});
|
|
625
|
-
},
|
|
626
|
-
|
|
627
662
|
//获取知识点名称
|
|
628
663
|
getKnowledgeName(e, array) {
|
|
629
664
|
array.forEach(item => {
|
|
@@ -749,6 +784,149 @@ export default {
|
|
|
749
784
|
// 清空选中状态
|
|
750
785
|
this.selectedQuestions = [];
|
|
751
786
|
},
|
|
787
|
+
|
|
788
|
+
// 检查题目是否重复
|
|
789
|
+
checkDuplicateQuestion(newQuestion, questionType) {
|
|
790
|
+
if (!this.aiResponse.questions || this.aiResponse.questions.length === 0) {
|
|
791
|
+
return false;
|
|
792
|
+
}
|
|
793
|
+
return this.aiResponse.questions.some(existingQuestion => {
|
|
794
|
+
return existingQuestion.title === newQuestion.title &&
|
|
795
|
+
existingQuestion.type === questionType;
|
|
796
|
+
});
|
|
797
|
+
},
|
|
798
|
+
|
|
799
|
+
// 获取指定题型的已生成题目信息
|
|
800
|
+
getGeneratedQuestionsByType(questionType) {
|
|
801
|
+
if (!this.aiResponse.questions || this.aiResponse.questions.length === 0) {
|
|
802
|
+
return [];
|
|
803
|
+
}
|
|
804
|
+
return this.aiResponse.questions
|
|
805
|
+
.filter(question => question.type === questionType)
|
|
806
|
+
.map(question => ({
|
|
807
|
+
title: question.title,
|
|
808
|
+
type: question.type
|
|
809
|
+
}));
|
|
810
|
+
},
|
|
811
|
+
|
|
812
|
+
// 重复题目信息重新生成
|
|
813
|
+
regenerateWithRepetition(originalObj, repetitionQuestions, questionType, retryCount = 0) {
|
|
814
|
+
console.log('检测到重复题目,重新生成,已生成题目:', repetitionQuestions, '重试次数:', retryCount);
|
|
815
|
+
|
|
816
|
+
// 如果重试次数超过3次,跳过此题目
|
|
817
|
+
if (retryCount >= 3) {
|
|
818
|
+
console.log('重试次数超过3次,跳过此题目');
|
|
819
|
+
this.isGenerating = false;
|
|
820
|
+
this.$message.warning('AI生成重复题目超过3次,已跳过该题目');
|
|
821
|
+
return;
|
|
822
|
+
}
|
|
823
|
+
|
|
824
|
+
const newObj = {
|
|
825
|
+
...originalObj,
|
|
826
|
+
repetitionQuestions: repetitionQuestions // 传递所有已生成的题目信息
|
|
827
|
+
};
|
|
828
|
+
|
|
829
|
+
getAiQuestion(newObj).then(res => {
|
|
830
|
+
if (res.success) {
|
|
831
|
+
this.loading && this.loading.close()
|
|
832
|
+
if (res.data && res.data.questions && res.data.questions.length > 0) {
|
|
833
|
+
const newQuestion = res.data.questions[0];
|
|
834
|
+
// 再次检查是否还有重复
|
|
835
|
+
const isStillDuplicate = this.checkDuplicateQuestion(newQuestion, questionType);
|
|
836
|
+
|
|
837
|
+
if (isStillDuplicate) {
|
|
838
|
+
console.log('重新生成后仍有重复,继续重试,当前重试次数:', retryCount + 1);
|
|
839
|
+
// 递归调用,增加重试次数,重新获取最新的当前题型已生成题目列表
|
|
840
|
+
const updatedRepetitionQuestions = this.getGeneratedQuestionsByType(questionType);
|
|
841
|
+
this.regenerateWithRepetition(originalObj, updatedRepetitionQuestions, questionType, retryCount + 1);
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
if (this.aiResponse.questions && this.aiResponse.questions.length > 0) {
|
|
846
|
+
this.aiResponse.questions.push(newQuestion);
|
|
847
|
+
} else {
|
|
848
|
+
this.aiResponse = res.data;
|
|
849
|
+
}
|
|
850
|
+
this.$set(newQuestion, 'evaluate', 0)
|
|
851
|
+
// 设置题目类型,便于后续统计
|
|
852
|
+
this.$set(newQuestion, 'type', questionType)
|
|
853
|
+
|
|
854
|
+
// 更新该题型的生成计数
|
|
855
|
+
if (!this.typeGeneratedCounts[questionType]) {
|
|
856
|
+
this.typeGeneratedCounts[questionType] = 0;
|
|
857
|
+
}
|
|
858
|
+
this.typeGeneratedCounts[questionType]++;
|
|
859
|
+
|
|
860
|
+
this.showGenerateResult();
|
|
861
|
+
} else {
|
|
862
|
+
this.$message.warning('重新生成题目失败')
|
|
863
|
+
}
|
|
864
|
+
} else {
|
|
865
|
+
this.$message.warning('重新生成题目失败')
|
|
866
|
+
}
|
|
867
|
+
}).catch(error => {
|
|
868
|
+
console.log("重新生成题目错误:" + error);
|
|
869
|
+
this.$message.warning('重新生成题目失败')
|
|
870
|
+
});
|
|
871
|
+
},
|
|
872
|
+
|
|
873
|
+
// 重新生成的重复检测重新生成
|
|
874
|
+
regenerateWithRepetitionForReSend(originalObj, repetitionQuestions, questionType, retryCount = 0) {
|
|
875
|
+
console.log('reSend检测到重复题目,重新生成,已生成题目:', repetitionQuestions, '重试次数:', retryCount);
|
|
876
|
+
// 如果重试次数超过3次,跳过此题目
|
|
877
|
+
if (retryCount >= 3) {
|
|
878
|
+
console.log('reSend重试次数超过3次,跳过此题目');
|
|
879
|
+
this.isGenerating = false;
|
|
880
|
+
this.$message.warning('AI生成重复题目超过3次,已跳过该题目');
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
const newObj = {
|
|
884
|
+
...originalObj,
|
|
885
|
+
repetitionQuestions: repetitionQuestions
|
|
886
|
+
};
|
|
887
|
+
|
|
888
|
+
getAiQuestion(newObj).then(res => {
|
|
889
|
+
if (res.success) {
|
|
890
|
+
this.loading && this.loading.close()
|
|
891
|
+
if (res.data && res.data.questions && res.data.questions.length > 0) {
|
|
892
|
+
const newQuestion = res.data.questions[0];
|
|
893
|
+
|
|
894
|
+
// 再次检查是否还有重复
|
|
895
|
+
const isStillDuplicate = this.checkDuplicateQuestion(newQuestion, questionType);
|
|
896
|
+
|
|
897
|
+
if (isStillDuplicate) {
|
|
898
|
+
console.log('reSend重新生成后仍有重复,继续重试,当前重试次数:', retryCount + 1);
|
|
899
|
+
// 递归调用,增加重试次数,重新获取最新的当前题型已生成题目列表
|
|
900
|
+
const updatedRepetitionQuestions = this.getGeneratedQuestionsByType(questionType);
|
|
901
|
+
this.regenerateWithRepetitionForReSend(originalObj, updatedRepetitionQuestions, questionType, retryCount + 1);
|
|
902
|
+
return;
|
|
903
|
+
}
|
|
904
|
+
|
|
905
|
+
if (this.aiResponse.questions && this.aiResponse.questions.length > 0) {
|
|
906
|
+
this.aiResponse.questions.push(newQuestion);
|
|
907
|
+
} else {
|
|
908
|
+
this.aiResponse = res.data;
|
|
909
|
+
}
|
|
910
|
+
this.$set(newQuestion, 'evaluate', 0)
|
|
911
|
+
// 设置题目类型,便于后续统计
|
|
912
|
+
this.$set(newQuestion, 'type', questionType)
|
|
913
|
+
this.showGenerateResult();
|
|
914
|
+
} else {
|
|
915
|
+
this.$message.warning('重新生成题目失败,重新生成中...')
|
|
916
|
+
return this.reSend()
|
|
917
|
+
}
|
|
918
|
+
} else {
|
|
919
|
+
this.loading && this.loading.close()
|
|
920
|
+
this.$message.warning('重新生成题目失败')
|
|
921
|
+
this.rebuildFlag = false;
|
|
922
|
+
}
|
|
923
|
+
}).catch(error => {
|
|
924
|
+
console.log("reSend重新生成题目错误:" + error);
|
|
925
|
+
this.loading && this.loading.close()
|
|
926
|
+
this.$message.warning('重新生成题目失败')
|
|
927
|
+
this.rebuildFlag = false;
|
|
928
|
+
});
|
|
929
|
+
},
|
|
752
930
|
}
|
|
753
931
|
}
|
|
754
932
|
</script>
|
|
@@ -759,7 +937,7 @@ export default {
|
|
|
759
937
|
|
|
760
938
|
::v-deep {
|
|
761
939
|
.el-drawer.rtl {
|
|
762
|
-
border-radius:
|
|
940
|
+
border-radius: 20px;
|
|
763
941
|
width: 720px !important;
|
|
764
942
|
}
|
|
765
943
|
|
|
@@ -775,6 +953,7 @@ export default {
|
|
|
775
953
|
background: linear-gradient(to bottom, rgba(255, 255, 255, 0), white),
|
|
776
954
|
linear-gradient(to right, #BCB9F4, #D5C6F8, #E6C6F9);
|
|
777
955
|
margin-bottom: 0;
|
|
956
|
+
border-radius: 20px;
|
|
778
957
|
}
|
|
779
958
|
|
|
780
959
|
.el-drawer__body {
|
|
@@ -824,7 +1003,7 @@ export default {
|
|
|
824
1003
|
|
|
825
1004
|
.el-input__inner {
|
|
826
1005
|
border-radius: 12px;
|
|
827
|
-
height: 48px;
|
|
1006
|
+
height: 48px !important;
|
|
828
1007
|
border: 1px solid #E0E0E0;
|
|
829
1008
|
}
|
|
830
1009
|
|
|
@@ -946,10 +1125,11 @@ export default {
|
|
|
946
1125
|
margin-left: 20px;
|
|
947
1126
|
|
|
948
1127
|
::v-deep .el-input__inner {
|
|
949
|
-
height: 42px;
|
|
1128
|
+
height: 42px !important;
|
|
950
1129
|
border-radius: 56px;
|
|
951
1130
|
text-align: center;
|
|
952
1131
|
font-size: 12px;
|
|
1132
|
+
padding: 0 !important;
|
|
953
1133
|
}
|
|
954
1134
|
}
|
|
955
1135
|
|
|
@@ -1135,6 +1315,41 @@ export default {
|
|
|
1135
1315
|
flex-direction: column;
|
|
1136
1316
|
}
|
|
1137
1317
|
|
|
1318
|
+
// 内部loading样式
|
|
1319
|
+
.generating-loading {
|
|
1320
|
+
display: flex;
|
|
1321
|
+
justify-content: center;
|
|
1322
|
+
align-items: center;
|
|
1323
|
+
height: 200px;
|
|
1324
|
+
|
|
1325
|
+
.loading-content {
|
|
1326
|
+
display: flex;
|
|
1327
|
+
flex-direction: column;
|
|
1328
|
+
align-items: center;
|
|
1329
|
+
gap: 16px;
|
|
1330
|
+
|
|
1331
|
+
.loading-spinner {
|
|
1332
|
+
width: 40px;
|
|
1333
|
+
height: 40px;
|
|
1334
|
+
border: 4px solid #f3f3f3;
|
|
1335
|
+
border-top: 4px solid #7C4DFF;
|
|
1336
|
+
border-radius: 50%;
|
|
1337
|
+
animation: spin 1s linear infinite;
|
|
1338
|
+
}
|
|
1339
|
+
|
|
1340
|
+
.loading-text {
|
|
1341
|
+
font-size: 14px;
|
|
1342
|
+
color: #7C4DFF;
|
|
1343
|
+
font-weight: 500;
|
|
1344
|
+
}
|
|
1345
|
+
}
|
|
1346
|
+
}
|
|
1347
|
+
|
|
1348
|
+
@keyframes spin {
|
|
1349
|
+
0% { transform: rotate(0deg); }
|
|
1350
|
+
100% { transform: rotate(360deg); }
|
|
1351
|
+
}
|
|
1352
|
+
|
|
1138
1353
|
.drawer_content_wrapper {
|
|
1139
1354
|
display: flex;
|
|
1140
1355
|
flex-direction: column;
|
|
@@ -13,14 +13,14 @@
|
|
|
13
13
|
<span class="difficult">{{ difficultyList.find(item => item.id == detail.difficulty).name }}</span>
|
|
14
14
|
<span>{{ detail.title }}</span>
|
|
15
15
|
</span>
|
|
16
|
-
<span class="question_contain_title_reght"
|
|
17
|
-
<img src="../static/zan_plain.png" v-if="detail.evaluate == 0 || detail.evaluate == 2"
|
|
18
|
-
@click="agree(1)"
|
|
19
|
-
<img src="../static/zan_bg.png" v-if="detail.evaluate == 1"
|
|
20
|
-
<img src="../static/unzan_plain.png" v-if="detail.evaluate == 0 || detail.evaluate == 1"
|
|
21
|
-
@click="agree(2)"
|
|
22
|
-
<img src="../static/unzan_bg.png" v-if="detail.evaluate == 2"
|
|
23
|
-
</span
|
|
16
|
+
<!-- <span class="question_contain_title_reght">-->
|
|
17
|
+
<!-- <img src="../static/zan_plain.png" v-if="detail.evaluate == 0 || detail.evaluate == 2"-->
|
|
18
|
+
<!-- @click="agree(1)">-->
|
|
19
|
+
<!-- <img src="../static/zan_bg.png" v-if="detail.evaluate == 1">-->
|
|
20
|
+
<!-- <img src="../static/unzan_plain.png" v-if="detail.evaluate == 0 || detail.evaluate == 1"-->
|
|
21
|
+
<!-- @click="agree(2)">-->
|
|
22
|
+
<!-- <img src="../static/unzan_bg.png" v-if="detail.evaluate == 2">-->
|
|
23
|
+
<!-- </span>-->
|
|
24
24
|
</div>
|
|
25
25
|
<div class="question_contain_question" v-if="detail.type == 'single' || detail.type == 'multiple' ">
|
|
26
26
|
<div v-for="item, idx in detail.options" :key="idx">
|