ai-question-pro 0.0.21 → 0.0.22

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.
@@ -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)"
@@ -306,6 +312,8 @@ export default {
306
312
  currentBot: 'tongyi',
307
313
  selectedQuestions: [], // 存储选中的题目
308
314
  joinedQuestions: [], // 存储已加入题库的题目索引
315
+ retryCountMap: {}, // 存储每个题目的重试次数
316
+ isGenerating: false, // 内部loading状态
309
317
  }
310
318
  },
311
319
  watch: {
@@ -483,6 +491,7 @@ export default {
483
491
  if (this.generateCount == totalCount) {
484
492
  this.$message.success('题目(' + totalCount + '道)全部生成完毕!');
485
493
  this.rebuildFlag = false;
494
+ this.isGenerating = false;
486
495
  } else {
487
496
  this.$message.success('生成' + this.generateCount + '道题目成功');
488
497
  }
@@ -493,12 +502,7 @@ export default {
493
502
  },
494
503
 
495
504
  reSend() {
496
- this.loading && this.loading.close()
497
- this.loading = this.$loading({
498
- target: '.el-dialog',
499
- text: 'AI生成中...'
500
- });
501
-
505
+ this.isGenerating = true;
502
506
  const selectedTypes = Object.keys(this.form.selectedTypes).filter(key => this.form.selectedTypes[key])
503
507
  const questionTypes = selectedTypes
504
508
  const difficultys = selectedTypes.map(type => this.form.typeDifficulties[type])
@@ -522,25 +526,38 @@ export default {
522
526
  if (res.success) {
523
527
  this.loading && this.loading.close()
524
528
  if (res.data && res.data.questions && res.data.questions.length > 0) {
529
+ const newQuestion = res.data.questions[0];
530
+ const questionType = newQuestion.type;
531
+ // 检查是否有重复的题目标题和题型
532
+ const isDuplicate = this.checkDuplicateQuestion(newQuestion, questionType);
533
+
534
+ if (isDuplicate) {
535
+ const repetitionQuestions = this.getGeneratedQuestionsByType(questionType);
536
+ this.regenerateWithRepetitionForReSend(obj, repetitionQuestions, questionType);
537
+ return;
538
+ }
539
+
525
540
  if (this.aiResponse.questions && this.aiResponse.questions.length > 0) {
526
- this.aiResponse.questions.push(res.data.questions[0]);
541
+ this.aiResponse.questions.push(newQuestion);
527
542
  } else {
528
543
  this.aiResponse = res.data;
529
544
  }
530
- this.$set(res.data.questions[0], 'evaluate', 0)
545
+ this.$set(newQuestion, 'evaluate', 0)
546
+ // 设置题目类型,便于后续统计
547
+ this.$set(newQuestion, 'type', questionType)
531
548
  this.showGenerateResult();
532
549
  } else {
533
550
  this.$message.warning('题目获取失败,重新生成中...')
534
551
  return this.reSend()
535
552
  }
536
553
  } else {
537
- this.loading && this.loading.close()
554
+ this.isGenerating = false;
538
555
  this.$message.warning('题目获取失败')
539
556
  this.rebuildFlag = false;
540
557
  }
541
558
  }).catch(error => {
542
559
  console.log("error:" + error);
543
- this.loading && this.loading.close()
560
+ this.isGenerating = false;
544
561
  this.$message.warning('题目获取失败')
545
562
  this.rebuildFlag = false;
546
563
  })
@@ -562,11 +579,7 @@ export default {
562
579
  this.rebuildFlag = true;
563
580
  this.generateCount = 0;
564
581
  this.aiResponse = {}
565
- this.loading && this.loading.close()
566
- this.loading = this.$loading({
567
- target: '.el-dialog',
568
- text: 'AI生成中...'
569
- });
582
+ this.isGenerating = true;
570
583
 
571
584
  const selectedTypes = Object.keys(this.form.selectedTypes).filter(key => this.form.selectedTypes[key])
572
585
 
@@ -594,29 +607,40 @@ export default {
594
607
 
595
608
  getAiQuestion(obj).then(res => {
596
609
  if (res.success) {
597
- this.loading && this.loading.close()
598
610
  if (res.data && res.data.questions && res.data.questions.length > 0) {
611
+ const newQuestion = res.data.questions[0];
612
+
613
+ // 检查是否有重复的题目标题和题型
614
+ const isDuplicate = this.checkDuplicateQuestion(newQuestion, type);
615
+
616
+ if (isDuplicate) {
617
+ // 只传递当前题型
618
+ const repetitionQuestions = this.getGeneratedQuestionsByType(type);
619
+ this.regenerateWithRepetition(obj, repetitionQuestions, type);
620
+ return;
621
+ }
622
+
599
623
  if (this.aiResponse.questions && this.aiResponse.questions.length > 0) {
600
- this.aiResponse.questions.push(res.data.questions[0]);
624
+ this.aiResponse.questions.push(newQuestion);
601
625
  } else {
602
626
  this.aiResponse = res.data;
603
627
  }
604
- this.$set(res.data.questions[0], 'evaluate', 0)
628
+ this.$set(newQuestion, 'evaluate', 0)
605
629
  // 设置题目类型,便于后续统计
606
- this.$set(res.data.questions[0], 'type', type)
630
+ this.$set(newQuestion, 'type', type)
607
631
  this.showGenerateResult();
608
632
  } else {
609
633
  this.$message.warning('题目获取失败,重新生成中...')
610
634
  return this.reSend()
611
635
  }
612
636
  } else {
613
- this.loading && this.loading.close()
637
+ this.isGenerating = false;
614
638
  this.$message.warning('题目获取失败')
615
639
  this.rebuildFlag = false;
616
640
  }
617
641
  }).catch(error => {
618
642
  console.log("error:" + error);
619
- this.loading && this.loading.close()
643
+ this.isGenerating = false;
620
644
  this.$message.warning('题目获取失败')
621
645
  this.rebuildFlag = false;
622
646
  })
@@ -749,6 +773,142 @@ export default {
749
773
  // 清空选中状态
750
774
  this.selectedQuestions = [];
751
775
  },
776
+
777
+ // 检查题目是否重复
778
+ checkDuplicateQuestion(newQuestion, questionType) {
779
+ if (!this.aiResponse.questions || this.aiResponse.questions.length === 0) {
780
+ return false;
781
+ }
782
+ return this.aiResponse.questions.some(existingQuestion => {
783
+ return existingQuestion.title === newQuestion.title &&
784
+ existingQuestion.type === questionType;
785
+ });
786
+ },
787
+
788
+ // 获取指定题型的已生成题目信息
789
+ getGeneratedQuestionsByType(questionType) {
790
+ if (!this.aiResponse.questions || this.aiResponse.questions.length === 0) {
791
+ return [];
792
+ }
793
+ return this.aiResponse.questions
794
+ .filter(question => question.type === questionType)
795
+ .map(question => ({
796
+ title: question.title,
797
+ type: question.type
798
+ }));
799
+ },
800
+
801
+ // 重复题目信息重新生成
802
+ regenerateWithRepetition(originalObj, repetitionQuestions, questionType, retryCount = 0) {
803
+ console.log('检测到重复题目,重新生成,已生成题目:', repetitionQuestions, '重试次数:', retryCount);
804
+
805
+ // 如果重试次数超过3次,跳过此题目
806
+ if (retryCount >= 3) {
807
+ console.log('重试次数超过3次,跳过此题目');
808
+ this.isGenerating = false;
809
+ this.$message.warning('AI生成重复题目超过3次,已跳过该题目');
810
+ return;
811
+ }
812
+
813
+ const newObj = {
814
+ ...originalObj,
815
+ repetitionQuestions: repetitionQuestions // 传递所有已生成的题目信息
816
+ };
817
+
818
+ getAiQuestion(newObj).then(res => {
819
+ if (res.success) {
820
+ this.loading && this.loading.close()
821
+ if (res.data && res.data.questions && res.data.questions.length > 0) {
822
+ const newQuestion = res.data.questions[0];
823
+ // 再次检查是否还有重复
824
+ const isStillDuplicate = this.checkDuplicateQuestion(newQuestion, questionType);
825
+
826
+ if (isStillDuplicate) {
827
+ console.log('重新生成后仍有重复,继续重试,当前重试次数:', retryCount + 1);
828
+ // 递归调用,增加重试次数,重新获取最新的当前题型已生成题目列表
829
+ const updatedRepetitionQuestions = this.getGeneratedQuestionsByType(questionType);
830
+ this.regenerateWithRepetition(originalObj, updatedRepetitionQuestions, questionType, retryCount + 1);
831
+ return;
832
+ }
833
+
834
+ if (this.aiResponse.questions && this.aiResponse.questions.length > 0) {
835
+ this.aiResponse.questions.push(newQuestion);
836
+ } else {
837
+ this.aiResponse = res.data;
838
+ }
839
+ this.$set(newQuestion, 'evaluate', 0)
840
+ // 设置题目类型,便于后续统计
841
+ this.$set(newQuestion, 'type', questionType)
842
+ this.showGenerateResult();
843
+ } else {
844
+ this.$message.warning('重新生成题目失败')
845
+ }
846
+ } else {
847
+ this.$message.warning('重新生成题目失败')
848
+ }
849
+ }).catch(error => {
850
+ console.log("重新生成题目错误:" + error);
851
+ this.$message.warning('重新生成题目失败')
852
+ });
853
+ },
854
+
855
+ // 重新生成的重复检测重新生成
856
+ regenerateWithRepetitionForReSend(originalObj, repetitionQuestions, questionType, retryCount = 0) {
857
+ console.log('reSend检测到重复题目,重新生成,已生成题目:', repetitionQuestions, '重试次数:', retryCount);
858
+ // 如果重试次数超过3次,跳过此题目
859
+ if (retryCount >= 3) {
860
+ console.log('reSend重试次数超过3次,跳过此题目');
861
+ this.isGenerating = false;
862
+ this.$message.warning('AI生成重复题目超过3次,已跳过该题目');
863
+ return;
864
+ }
865
+ const newObj = {
866
+ ...originalObj,
867
+ repetitionQuestions: repetitionQuestions
868
+ };
869
+
870
+ getAiQuestion(newObj).then(res => {
871
+ if (res.success) {
872
+ this.loading && this.loading.close()
873
+ if (res.data && res.data.questions && res.data.questions.length > 0) {
874
+ const newQuestion = res.data.questions[0];
875
+
876
+ // 再次检查是否还有重复
877
+ const isStillDuplicate = this.checkDuplicateQuestion(newQuestion, questionType);
878
+
879
+ if (isStillDuplicate) {
880
+ console.log('reSend重新生成后仍有重复,继续重试,当前重试次数:', retryCount + 1);
881
+ // 递归调用,增加重试次数,重新获取最新的当前题型已生成题目列表
882
+ const updatedRepetitionQuestions = this.getGeneratedQuestionsByType(questionType);
883
+ this.regenerateWithRepetitionForReSend(originalObj, updatedRepetitionQuestions, questionType, retryCount + 1);
884
+ return;
885
+ }
886
+
887
+ if (this.aiResponse.questions && this.aiResponse.questions.length > 0) {
888
+ this.aiResponse.questions.push(newQuestion);
889
+ } else {
890
+ this.aiResponse = res.data;
891
+ }
892
+ this.$set(newQuestion, 'evaluate', 0)
893
+ // 设置题目类型,便于后续统计
894
+ this.$set(newQuestion, 'type', questionType)
895
+ this.showGenerateResult();
896
+ } else {
897
+ this.$message.warning('重新生成题目失败,重新生成中...')
898
+ return this.reSend()
899
+ }
900
+ } else {
901
+ this.loading && this.loading.close()
902
+ this.$message.warning('重新生成题目失败')
903
+ this.rebuildFlag = false;
904
+ }
905
+ }).catch(error => {
906
+ console.log("reSend重新生成题目错误:" + error);
907
+ this.loading && this.loading.close()
908
+ this.$message.warning('重新生成题目失败')
909
+ this.rebuildFlag = false;
910
+ });
911
+ },
752
912
  }
753
913
  }
754
914
  </script>
@@ -759,7 +919,7 @@ export default {
759
919
 
760
920
  ::v-deep {
761
921
  .el-drawer.rtl {
762
- border-radius: 15px 0 0 15px;
922
+ border-radius: 20px;
763
923
  width: 720px !important;
764
924
  }
765
925
 
@@ -775,6 +935,7 @@ export default {
775
935
  background: linear-gradient(to bottom, rgba(255, 255, 255, 0), white),
776
936
  linear-gradient(to right, #BCB9F4, #D5C6F8, #E6C6F9);
777
937
  margin-bottom: 0;
938
+ border-radius: 20px;
778
939
  }
779
940
 
780
941
  .el-drawer__body {
@@ -824,7 +985,7 @@ export default {
824
985
 
825
986
  .el-input__inner {
826
987
  border-radius: 12px;
827
- height: 48px;
988
+ height: 48px !important;
828
989
  border: 1px solid #E0E0E0;
829
990
  }
830
991
 
@@ -946,10 +1107,11 @@ export default {
946
1107
  margin-left: 20px;
947
1108
 
948
1109
  ::v-deep .el-input__inner {
949
- height: 42px;
1110
+ height: 42px !important;
950
1111
  border-radius: 56px;
951
1112
  text-align: center;
952
1113
  font-size: 12px;
1114
+ padding: 0 !important;
953
1115
  }
954
1116
  }
955
1117
 
@@ -1135,6 +1297,41 @@ export default {
1135
1297
  flex-direction: column;
1136
1298
  }
1137
1299
 
1300
+ // 内部loading样式
1301
+ .generating-loading {
1302
+ display: flex;
1303
+ justify-content: center;
1304
+ align-items: center;
1305
+ height: 200px;
1306
+
1307
+ .loading-content {
1308
+ display: flex;
1309
+ flex-direction: column;
1310
+ align-items: center;
1311
+ gap: 16px;
1312
+
1313
+ .loading-spinner {
1314
+ width: 40px;
1315
+ height: 40px;
1316
+ border: 4px solid #f3f3f3;
1317
+ border-top: 4px solid #7C4DFF;
1318
+ border-radius: 50%;
1319
+ animation: spin 1s linear infinite;
1320
+ }
1321
+
1322
+ .loading-text {
1323
+ font-size: 14px;
1324
+ color: #7C4DFF;
1325
+ font-weight: 500;
1326
+ }
1327
+ }
1328
+ }
1329
+
1330
+ @keyframes spin {
1331
+ 0% { transform: rotate(0deg); }
1332
+ 100% { transform: rotate(360deg); }
1333
+ }
1334
+
1138
1335
  .drawer_content_wrapper {
1139
1336
  display: flex;
1140
1337
  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">