ai-question-pro 0.0.19 → 0.0.21

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.
@@ -1,330 +1,597 @@
1
1
  <template>
2
- <div class="ai_contain">
3
- <slot>
4
- <span class="ai_button" @click="showAddQuestion">AI出题</span>
5
- </slot>
6
- <el-drawer :visible.sync="addShow" :direction="direction" :wrapperClosable="false" destroy-on-close>
7
- <template slot="title">
8
- <div class="add_question_title">
9
- <img src="../static/logo.png" alt="" style="width: 32px; height: 18px;"/>
10
- <span>出题</span>
11
- </div>
12
- </template>
13
- <div class="add_question_body">
14
- <el-form ref="form" :model="form" :rules="rules" label-width="100px" label-position="left">
15
- <el-form-item label="题目类型" prop="questionType">
16
- <!-- <el-checkbox-group v-model="form.questionTypes">-->
17
- <!-- <el-checkbox v-for="item in quesTypeList" :key="item.id" :label="item.id">-->
18
- <!-- {{ item.name }}-->
19
- <!-- </el-checkbox>-->
20
- <!-- </el-checkbox-group>-->
21
- <el-radio-group v-model="form.questionType" >
22
- <!-- <el-radio-button v-for="item in quesTypeList" :key="item.id" :label="item.id">{{ item.name }}</el-radio-button>-->
23
- <el-radio v-for="item in quesTypeList"
24
- style="margin-right: 8px; margin-bottom: 8px"
25
- :key="item.id"
26
- :label="item.id">{{ item.name }}</el-radio>
27
- </el-radio-group>
28
- </el-form-item>
29
- <el-form-item label="题目难度" prop="difficulty">
30
- <!-- <el-checkbox-group v-model="form.difficultys">-->
31
- <!-- <el-checkbox :label="item.id" v-for="item in difficultyList" :key="item.id">{{ item.name-->
32
- <!-- }}</el-checkbox>-->
33
- <!-- </el-checkbox-group>-->
34
- <el-radio-group v-model="form.difficulty" size="medium">
35
- <!-- <el-radio-button v-for="item in difficultyList" :key="item.id" :label="item.id">{{ item.name }}</el-radio-button>-->
36
- <el-radio v-for="item in difficultyList"
37
- style="margin-right: 8px; margin-bottom: 8px"
38
- :key="item.id"
39
- :label="item.id">{{ item.name }}</el-radio>
40
- </el-radio-group>
41
- </el-form-item>
42
- <el-form-item label="关联知识点" prop="knowledgeIds">
43
- <!-- <el-cascader v-model="form.knowledgeId" :options="knowledgeList" @change="closeDrowdown"-->
44
- <!-- :show-all-levels="false" ref="cascader" :props="{ checkStrictly: true, ...propFormat }"-->
45
- <!-- clearable></el-cascader>-->
46
- <cy-tree-select v-model="form.knowledgeIds" filterable :data="knowledgeList"></cy-tree-select>
47
- </el-form-item>
48
- <el-form-item label="题目数量" prop="count">
49
- <el-input class="number_input" v-model="form.count" min="1" max="10" type="number" placeholder="请输入"
50
- @input="handleInput"></el-input>
51
- <div class="remind">(为避免您等待时间过长,一次性最多生成10道题)</div>
52
- </el-form-item>
53
- <el-form-item label="自定义提示语">
54
- <el-input v-model="form.prompt" placeholder="这里可以写对于题目的要求和补充,比如:“出题内容请围绕一下知识内容:智能水利物联网是指利用物联网技术和智能化手段,对水利工程设施进行实时监测、数据采集、远程控制和智能分析,以实现对水资源的高效利用、水利设施的智能运营和管理。通过传感器、无线通信技术、云计算平台和大数据分析等技术手段,实现对水利系统各个环节的智能监测和管理,提高水资源利用效率,降低水利工程运行成本,保障水利工程安全稳定运行。”" type="textarea" :autosize="{ minRows: 10, maxRows: 10} " maxlength="200" show-word-limit></el-input>
55
- </el-form-item>
56
- </el-form>
2
+ <div class="ai_contain">
3
+ <slot>
4
+ <span class="ai_button" @click="showAddQuestion">AI出题</span>
5
+ </slot>
6
+ <el-drawer :visible.sync="addShow" :direction="direction" :wrapperClosable="false" destroy-on-close>
7
+ <template slot="title">
8
+ <div class="add_question_title">
9
+ <img src="../static/logo.png" alt="" style="width: 32px; height: 18px;"/>
10
+ <span>出题</span>
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
+ >通义千问
57
31
  </div>
58
- <div class="add_question_footer">
59
- <button class="button-handle button-cancel" @click="addShow = false">取 消</button>
60
- <button class="button-handle button-generate-question" @click="generate">生成题目</button>
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
+ </template>
42
+ <div class="add_question_body">
43
+ <div class="question-type-header">
44
+ <span class="required-mark">*</span>
45
+ <span class="section-title">题目类型:</span>
46
+ <span class="tip-text">(为避免您等待时间过长,一次性最多生成10道题)</span>
47
+ </div>
48
+
49
+ <!-- 题目类型列表 -->
50
+ <div class="question-type-list">
51
+ <div
52
+ v-for="(item, index) in quesTypeList"
53
+ :key="item.id"
54
+ class="question-type-item"
55
+ :class="{ 'disabled': !form.selectedTypes[item.id] }"
56
+ >
57
+ <div class="type-left">
58
+ <el-checkbox
59
+ v-model="form.selectedTypes[item.id]"
60
+ class="type-checkbox"
61
+ @change="handleTypeChange(item.id)"
62
+ ></el-checkbox>
63
+ <span class="type-name" :class="getTypeClass(item.id)">{{ item.name }}</span>
61
64
  </div>
62
- </el-drawer>
63
- <el-dialog :visible.sync="showQues" :close-on-click-modal="false">
64
- <template slot="title">
65
- <div class="question_title">
66
- <img src="../static/robot.png">
67
- <span>{{ title }}</span>
68
- </div>
69
- </template>
70
- <div class="question_body" ref="generateDiv">
71
- <questionItem v-if="aiResponse.questions && aiResponse.questions.length > 0" @agree="agree" @join="join"
72
- v-for="item, idx in aiResponse.questions" :key="idx" :detail="item" :index="idx">
73
- </questionItem>
65
+
66
+ <div class="type-right">
67
+ <el-input
68
+ v-model="form.typeCounts[item.id]"
69
+ size="small"
70
+ class="count-input"
71
+ placeholder="请输入生成数量"
72
+ min="1"
73
+ max="10"
74
+ @input="handleCountInput(item.id)"
75
+ ></el-input>
76
+ <div class="slider-container" :class="{ 'disabled': !form.selectedTypes[item.id] }">
77
+ <el-slider
78
+ v-model="form.typeDifficulties[item.id]"
79
+ :min="0"
80
+ :max="4"
81
+ :disabled="!form.selectedTypes[item.id]"
82
+ class="difficulty-slider"
83
+ :show-tooltip="false"
84
+ ></el-slider>
85
+ </div>
86
+ <span class="difficulty-label" :class="{ 'disabled': !form.selectedTypes[item.id] }">
87
+ {{ form.selectedTypes[item.id] ? getDifficultyLabel(form.typeDifficulties[item.id]) : '题目难度' }}
88
+ </span>
74
89
  </div>
75
- <div class="question_footer" slot="footer">
76
- <span class="question_remind">题目内容由人工智能大模型生成,请您审慎核查,确认内容准确,无不妥后再使用</span>
77
- <el-button type="primary" @click="rebuild" :disabled="rebuildFlag">重新生成</el-button>
90
+ </div>
91
+ </div>
92
+
93
+ <!-- 关联知识点 -->
94
+ <div class="knowledge-section">
95
+ <div class="section-header">
96
+ <span class="required-mark">*</span>
97
+ <span class="section-title">关联知识点:</span>
98
+ <span class="tip-text">(最多可以关联1个知识点)</span>
99
+ </div>
100
+ <div class="knowledge-input">
101
+ <cy-tree-select
102
+ v-model="form.knowledgeIds"
103
+ filterable
104
+ :data="knowledgeList"
105
+ placeholder="请选择"
106
+ ></cy-tree-select>
107
+ <img src="../static/link-icon.png" class="el-icon-link knowledge-icon" alt=""/>
108
+ </div>
109
+ </div>
110
+
111
+ <!-- 自定义提示语 -->
112
+ <div class="prompt-section">
113
+ <div class="section-header">
114
+ <span class="section-title" style="margin-left: 15px;">自定义提示语:</span>
115
+ </div>
116
+ <el-input
117
+ v-model="form.prompt"
118
+ type="textarea"
119
+ :autosize="{ minRows: 8, maxRows: 10 }"
120
+ maxlength="200"
121
+ show-word-limit
122
+ placeholder="这里可以写对于题目的要求和补充,比如:出题内容请围绕以下知识内容:智能水利物联网是指利用物联网技术和智能化手段,对水利工程设施进行实时监测、数据采集、远程控制和智能分析,以实现对水资源的高效利用、水利设施的智能运营和管理。通过传感器、无线通信技术、云计算平台和大数据分析等技术手段,实现对水利系统各个环节的智能监测和管理,提高水资源利用效率,降低水利工程运行成本,保障水利工程安全稳定运行。"
123
+ class="prompt-textarea"
124
+ resize="none"
125
+ ></el-input>
126
+ </div>
127
+ </div>
128
+ <div class="add_question_footer">
129
+ <button class="button-handle button-cancel" @click="addShow = false">取 消</button>
130
+ <button class="button-handle button-generate-question" @click="generate">
131
+ <img src="../static/generate-question-icon.png" style="width: 24px; height: 24px;" alt=""></img>
132
+ 生成题目
133
+ </button>
134
+ </div>
135
+ </el-drawer>
136
+ <el-drawer :visible.sync="showQues" :wrapperClosable="false" destroy-on-close class="question-result-drawer">
137
+ <template slot="title">
138
+ <div class="add_question_title">
139
+ <img src="../static/logo.png" alt="" style="width: 32px; height: 18px;"/>
140
+ <span>出题</span>
141
+ </div>
142
+ </template>
143
+ <div class="drawer_content_wrapper">
144
+ <div class="question_summary_warp">
145
+ <div class="question_summary">
146
+ <span class="summary_text">共为您生成了 {{
147
+ aiResponse.questions ? aiResponse.questions.length : 0
148
+ }} 道题目</span>
149
+ <div class="question_types_summary">
150
+ <span v-for="typeInfo in getQuestionTypeSummary()" :key="typeInfo.id" class="type_item">
151
+ {{ typeInfo.name }} <span class="summary_text">{{ typeInfo.count }}</span> 道
152
+ </span>
78
153
  </div>
79
- </el-dialog>
80
- </div>
154
+ </div>
155
+ <div class="question_summary_button">
156
+ <button class="button-handle button-cancel" @click="rebuild">重新生成</button>
157
+ <button class="button-handle button-generate-question" @click="addAllToBank">
158
+ 加入题库
159
+ </button>
160
+ </div>
161
+ </div>
162
+ <div class="question_body" ref="generateDiv">
163
+ <questionItem v-if="aiResponse.questions && aiResponse.questions.length > 0" @agree="agree" @join="join"
164
+ @selectionChange="handleQuestionSelection"
165
+ :isJoined="joinedQuestions.includes(idx)"
166
+ :ref="`questionItem_${idx}`"
167
+ v-for="item, idx in aiResponse.questions" :key="idx" :detail="item" :index="idx">
168
+ </questionItem>
169
+ </div>
170
+ <div class="question_footer_fixed">
171
+ <div class="footer_warning">
172
+ <img src="../static/warning-icon.png" class="el-icon-info" alt=""/>
173
+ <span class="question_remind">题目内容由人工智能大模型生成,请您审慎核查,确认内容准确,无不妥后再使用</span>
174
+ </div>
175
+ </div>
176
+ </div>
177
+ </el-drawer>
178
+ </div>
81
179
  </template>
82
180
  <script>
83
181
  import questionItem from './questionItem.vue'
84
182
  import CyTreeSelect from './CyTreeSelect.vue'
85
- // import {
86
- // Button, Drawer, Form, FormItem, Checkbox, CheckboxGroup, Input, Cascader, Dialog, Loading, this.$message
87
- // } from "element-ui"
88
- import { getAiQuestion, agreeQuestion, createBurial, checkVersion } from '../api/index'
183
+ import {getAiQuestion, agreeQuestion, createBurial, checkVersion} from '../api/index'
89
184
  import Cookies from 'js-cookie';
185
+ import {Image} from 'element-ui';
186
+
90
187
  export default {
91
- name: 'aiQuestion',
92
- components: {
93
- // 'el-button': Button,
94
- // 'el-drawer': Drawer,
95
- // 'el-form': Form,
96
- // 'el-form-item': FormItem,
97
- // 'el-checkbox': Checkbox,
98
- // 'el-checkbox-group': CheckboxGroup,
99
- // 'el-input': Input,
100
- // 'el-cascader': Cascader,
101
- // 'el-dialog': Dialog,
102
- questionItem,
103
- CyTreeSelect
188
+ name: 'aiQuestion',
189
+ components: {
190
+ questionItem,
191
+ CyTreeSelect
192
+ },
193
+ props: {
194
+ top: {
195
+ type: [String, Number],
196
+ default: 0
104
197
  },
105
- props: {
106
- top: {
107
- type: [String, Number],
108
- default: 0
198
+ knowledgeList: {
199
+ type: Array,
200
+ default: () => [
201
+ {
202
+ id: '1',
203
+ label: '大学英语',
204
+ children: [
205
+ {
206
+ id: '1-1',
207
+ label: '用英语打招呼',
208
+ }
209
+ ]
109
210
  },
110
- knowledgeList: {
111
- type: Array,
112
- default: () => [
113
- {
114
- id: '1',
115
- label: '大学英语',
116
- children: [
117
- {
118
- id: '1-1',
119
- label: '用英语打招呼',
120
- }
121
- ]
122
- },
123
- {
124
- id: '2',
125
- label: '大学物理',
126
- children: [
127
- {
128
- id: '2-1',
129
- label: '结构力学',
130
- children: [
131
- {
132
- id: '2-1-1',
133
- label: '力的构成',
134
- }
135
- ]
136
- },
137
- {
138
- id: '2-2',
139
- label: '流体力学',
140
- }
141
- ]
142
- },
211
+ {
212
+ id: '2',
213
+ label: '大学物理',
214
+ children: [
215
+ {
216
+ id: '2-1',
217
+ label: '结构力学',
218
+ children: [
143
219
  {
144
- id: '3',
145
- label: '高数'
220
+ id: '2-1-1',
221
+ label: '力的构成',
146
222
  }
147
- ]
223
+ ]
224
+ },
225
+ {
226
+ id: '2-2',
227
+ label: '流体力学',
228
+ }
229
+ ]
230
+ },
231
+ {
232
+ id: '3',
233
+ label: '高数'
234
+ }
235
+ ]
236
+ },
237
+ propFormat: {
238
+ type: Object,
239
+ default: () => ({
240
+ id: 'id',
241
+ label: 'label',
242
+ children: 'children'
243
+ })
244
+ },
245
+ businessSource: {
246
+ type: String,
247
+ default: "0",
248
+ },
249
+ courseId: {
250
+ type: String,
251
+ default: ''
252
+ }
253
+ },
254
+ data() {
255
+ return {
256
+ showQues: false,
257
+ addShow: false,
258
+ generateCount: 0,
259
+ direction: 'rtl',
260
+ rebuildFlag: true,
261
+ form: {
262
+ selectedTypes: {
263
+ single: false,
264
+ multiple: false,
265
+ judge: false,
266
+ gapfilling: false,
267
+ shortanswer: false
148
268
  },
149
- propFormat: {
150
- type: Object,
151
- default: () => ({
152
- id: 'id',
153
- label: 'label',
154
- children: 'children'
155
- })
269
+ typeCounts: {
270
+ single: null,
271
+ multiple: null,
272
+ judge: null,
273
+ gapfilling: null,
274
+ shortanswer: null
156
275
  },
157
- businessSource: {
158
- type: String,
159
- default: "0", // 默认值为空字符串
276
+ typeDifficulties: {
277
+ single: 0,
278
+ multiple: 0,
279
+ judge: 0,
280
+ gapfilling: 0,
281
+ shortanswer: 0
160
282
  },
283
+ knowledgeIds: '',
284
+ knowledgeId: [],
285
+ knowledge: [],
286
+ prompt: ''
287
+ },
288
+ quesTypeList: [
289
+ {name: '单选题', id: 'single'},
290
+ {name: '多选题', id: 'multiple'},
291
+ {name: '填空题', id: 'gapfilling'},
292
+ {name: '判断题', id: 'judge'},
293
+ {name: '简答题', id: 'shortanswer'},
294
+ ],
295
+ difficultyList: [
296
+ {name: '超级简单', id: 0},
297
+ {name: '简单', id: 1},
298
+ {name: '一般', id: 2},
299
+ {name: '困难', id: 3},
300
+ {name: '非常困难', id: 4},
301
+ ],
302
+ loading: null,
303
+ aiResponse: {},
304
+ title: '单选题',
305
+ dropdownVisible: false,
306
+ currentBot: 'tongyi',
307
+ selectedQuestions: [], // 存储选中的题目
308
+ joinedQuestions: [], // 存储已加入题库的题目索引
309
+ }
310
+ },
311
+ watch: {
312
+ showQues(e) {
313
+ if (!e) {
314
+ this.aiResponse = {}
315
+ }
316
+ }
317
+ },
318
+ mounted() {
319
+ let doc = document.getElementsByClassName('rtl')[0]
320
+ if (this.top) {
321
+ doc.style.top = this.top + 'px'
322
+ doc.style.height = `calc( 100% - ${this.top}px)`
323
+ }
324
+ //国窖平台没有简答题
325
+ if (this.businessSource === '4') {
326
+ this.quesTypeList = [
327
+ {name: '单选题', id: 'single'},
328
+ {name: '多选题', id: 'multiple'},
329
+ {name: '判断题', id: 'judge'},
330
+ {name: '填空题', id: 'gapfilling'},
331
+ ]
332
+ }
333
+ },
334
+ methods: {
335
+ // 处理题目类型选择变化
336
+ handleTypeChange(typeId) {
337
+ // 可以在这里添加额外的逻辑
161
338
  },
162
- data() {
163
- return {
164
- showQues: false,
165
- addShow: false,
166
- generateCount: 0,
167
- direction: 'rtl',
168
- rebuildFlag: true,
169
- form: {
170
- questionTypes: [],
171
- questionType: null,
172
- count: 1,
173
- knowledgeId: [],
174
- knowledgeIds: '',
175
- difficultys: [],
176
- difficulty: null,
177
- knowledge: []
178
- },
179
- quesTypeList: [
180
- { name: '单选题', id: 'single' },
181
- { name: '多选题', id: 'multiple' },
182
- { name: '判断题', id: 'judge' },
183
- { name: '填空题', id: 'gapfilling' },
184
- { name: '简答题', id: 'shortanswer' },
185
- ],
186
- difficultyList: [
187
- { name: '非常简单', id: 0 },
188
- { name: '简单', id: 1 },
189
- { name: '一般', id: 2 },
190
- { name: '困难', id: 3 },
191
- { name: '非常困难', id: 4 },
192
- ],
193
- rules: {
194
- questionTypes: [{ required: true, message: '此项必填', trigger: 'change' }],
195
- questionType: [{ required: true, message: '此项必填', trigger: 'change' }],
196
- count: [{ required: true, message: '此项必填', trigger: 'blur' }],
197
- knowledgeIds: [{ required: true, message: '此项必填', trigger: 'change' }],
198
- difficultys: [{ required: true, message: '此项必填', trigger: 'change' }],
199
- difficulty: [{ required: true, message: '此项必填', trigger: 'change' }],
200
- },
201
- loading: null,
202
- aiResponse: {},
203
- title: '单选题'
204
- }
339
+
340
+ // 处理数量变化,自动选中题目类型
341
+ handleCountChange(typeId) {
342
+ if (this.form.typeCounts[typeId] && this.form.typeCounts[typeId] > 0) {
343
+ this.form.selectedTypes[typeId] = true;
344
+ }
205
345
  },
206
- watch: {
207
- showQues(e) {
208
- if (!e) {
209
- this.aiResponse = {}
210
- }
211
- }
346
+
347
+ // 处理难度变化,自动选中题目类型
348
+ handleDifficultyChange(typeId) {
349
+ this.form.selectedTypes[typeId] = true;
212
350
  },
213
- mounted() {
214
- let doc = document.getElementsByClassName('rtl')[0]
215
- if (this.top) {
216
- doc.style.top = this.top + 'px'
217
- doc.style.height = `calc( 100% - ${this.top}px)`
218
- }
219
- //国窖平台没有简答题
220
- if(this.businessSource === '4'){
221
- this.quesTypeList = [
222
- { name: '单选题', id: 'single' },
223
- { name: '多选题', id: 'multiple' },
224
- { name: '判断题', id: 'judge' },
225
- { name: '填空题', id: 'gapfilling' },
226
- ]
227
- }
351
+
352
+ // 处理数量输入验证
353
+ handleCountInput(typeId) {
354
+ let inputValue = this.form.typeCounts[typeId];
355
+
356
+ // 如果输入为空,允许为空
357
+ if (inputValue === '' || inputValue === null || inputValue === undefined) {
358
+ return;
359
+ }
360
+
361
+ let value = parseInt(inputValue);
362
+ if (isNaN(value) || value < 1) {
363
+ this.form.typeCounts[typeId] = 1;
364
+ } else if (value > 10) {
365
+ this.form.typeCounts[typeId] = 10;
366
+ } else {
367
+ this.form.typeCounts[typeId] = value;
368
+ }
228
369
  },
229
- methods: {
230
- handleInput(value) {
231
- // value = parseFloat(value);
232
- value = parseInt(value);
233
- if (value < 1) {
234
- this.form.count = 1;
235
- } else if (value > 10) {
236
- this.form.count = 10;
237
- } else {
238
- this.form.count = value;
239
- }
240
- },
241
- //选中节点后关闭下拉框
242
- closeDrowdown(e) {
243
- this.$nextTick(() => {
244
- this.$refs.cascader.dropDownVisible = false
245
- });
370
+
371
+ // 获取题目类型的样式类
372
+ getTypeClass(typeId) {
373
+ const classMap = {
374
+ single: 'type-single',
375
+ multiple: 'type-multiple',
376
+ gapfilling: 'type-gapfilling',
377
+ judge: 'type-judge',
378
+ shortanswer: 'type-shortanswer'
379
+ }
380
+ return classMap[typeId] || ''
381
+ },
382
+
383
+ // 获取难度标签
384
+ getDifficultyLabel(difficultyId) {
385
+ const difficulty = this.difficultyList.find(item => item.id === difficultyId)
386
+ return difficulty ? difficulty.name : '一般'
387
+ },
388
+
389
+ //展示右边弹框
390
+ showAddQuestion() {
391
+ if (!Cookies.get("AiToken")) {
392
+ return this.$message.warning('未获取到登录信息,请重新登录')
393
+ }
394
+ this.resetForm()
395
+ this.addShow = !this.addShow
396
+ createBurial({
397
+ businessType: 3,
398
+ operatorType: 0,
399
+ businessSource: this.businessSource,
400
+ courseId: this.courseId
401
+ })
402
+ },
403
+
404
+ // 重置表单
405
+ resetForm() {
406
+ this.form = {
407
+ selectedTypes: {
408
+ single: false,
409
+ multiple: false,
410
+ judge: false,
411
+ gapfilling: false,
412
+ shortanswer: false
246
413
  },
247
- //展示右边弹框
248
- showAddQuestion() {
249
- if (!Cookies.get("AiToken")) {
250
- return this.$message.warning('未获取到登录信息,请重新登录')
251
- }
252
- this.form = {
253
- questionTypes: [],
254
- questionType: null,
255
- count: 1,
256
- knowledgeId: [],
257
- knowledgeIds: '',
258
- difficultys: [],
259
- difficulty: null,
260
- knowledge: []
261
- }
262
- this.addShow = !this.addShow
263
- createBurial({
264
- businessType: 3,
265
- operatorType: 0,
266
- businessSource:this.businessSource
267
- })
414
+ typeCounts: {
415
+ single: null,
416
+ multiple: null,
417
+ judge: null,
418
+ gapfilling: null,
419
+ shortanswer: null
268
420
  },
269
- //生成题目
270
- generate() {
271
- this.$refs.form.validate(valid => {
272
- if (valid) {
273
- this.form.knowledgeId = this.form.knowledgeIds.split(',');
274
- this.form.knowledgeId.forEach(item => {
275
- this.getKnowledgeName(item, this.knowledgeList)
276
- })
277
- this.form.questionTypes.push(this.form.questionType);
278
- this.form.difficultys.push(this.form.difficulty);
279
- if (this.form.questionTypes.length > 1) {
280
- this.title = '多类题'
281
- } else {
282
- this.title = this.quesTypeList.find(item => item.id == this.form.questionTypes[0]).name
283
- }
284
- this.showQues = true
285
- this.addShow = !this.addShow
286
- this.sendPost();
287
- this.$emit("questionCount", this.form.count);
288
- }
289
- })
421
+ typeDifficulties: {
422
+ single: 0,
423
+ multiple: 0,
424
+ judge: 0,
425
+ gapfilling: 0,
426
+ shortanswer: 0
290
427
  },
291
- //重新生成
292
- rebuild() {
293
- this.sendPost()
428
+ knowledgeIds: '',
429
+ knowledgeId: [],
430
+ knowledge: [],
431
+ prompt: ''
432
+ }
433
+ },
434
+
435
+ //生成题目
436
+ generate() {
437
+ // 验证是否选择了题目类型
438
+ const selectedTypes = Object.keys(this.form.selectedTypes).filter(key => this.form.selectedTypes[key])
439
+ if (selectedTypes.length === 0) {
440
+ return this.$message.warning('请至少选择一种题目类型')
441
+ }
442
+
443
+ // 验证是否选择了知识点
444
+ if (!this.form.knowledgeIds) {
445
+ return this.$message.warning('请选择关联知识点')
446
+ }
447
+
448
+ // 处理知识点数据
449
+ this.form.knowledgeId = this.form.knowledgeIds.split(',');
450
+ this.form.knowledgeId.forEach(item => {
451
+ this.getKnowledgeName(item, this.knowledgeList)
452
+ })
453
+
454
+ // 设置标题
455
+ if (selectedTypes.length > 1) {
456
+ this.title = '多类题'
457
+ } else {
458
+ this.title = this.quesTypeList.find(item => item.id === selectedTypes[0]).name
459
+ }
460
+
461
+ this.showQues = true
462
+ this.addShow = !this.addShow
463
+ this.sendPost();
464
+
465
+ // 计算总题目数量
466
+ const totalCount = selectedTypes.reduce((sum, type) => sum + this.form.typeCounts[type], 0)
467
+ this.$emit("questionCount", totalCount);
468
+ },
469
+
470
+ //重新生成
471
+ rebuild() {
472
+ // 重新生成时清空已加入题库的状态
473
+ this.joinedQuestions = [];
474
+ this.selectedQuestions = [];
475
+ this.sendPost()
476
+ },
477
+
478
+ showGenerateResult() {
479
+ this.generateCount++;
480
+ const selectedTypes = Object.keys(this.form.selectedTypes).filter(key => this.form.selectedTypes[key])
481
+ const totalCount = selectedTypes.reduce((sum, type) => sum + this.form.typeCounts[type], 0)
482
+
483
+ if (this.generateCount == totalCount) {
484
+ this.$message.success('题目(' + totalCount + '道)全部生成完毕!');
485
+ this.rebuildFlag = false;
486
+ } else {
487
+ this.$message.success('生成' + this.generateCount + '道题目成功');
488
+ }
489
+ this.$nextTick(() => {
490
+ const generateDiv = this.$refs.generateDiv;
491
+ generateDiv.scrollTop = generateDiv.scrollHeight;
492
+ });
493
+ },
494
+
495
+ reSend() {
496
+ this.loading && this.loading.close()
497
+ this.loading = this.$loading({
498
+ target: '.el-dialog',
499
+ text: 'AI生成中...'
500
+ });
501
+
502
+ 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
+
506
+ let obj = {
507
+ modelType: 'aliyun',
508
+ questionAddCmd: {
509
+ questionTypes: questionTypes,
510
+ count: 1,
511
+ knowledge: this.form.knowledge.join(' '),
512
+ knowledgeId: this.form.knowledgeId[this.form.knowledgeId.length - 1],
513
+ difficultys: difficultys,
514
+ prompt: this.form.prompt
294
515
  },
295
- showGenerateResult(){
296
- this.generateCount++;
297
- if(this.generateCount == this.form.count){
298
- this.$message.success( '题目(' + this.form.count + '道)全部生成完毕!');
299
- this.rebuildFlag = false;
516
+ sessionId: this.aiResponse.sessionId ? this.aiResponse.sessionId : '',
517
+ businessSource: this.businessSource,
518
+ courseId: this.courseId,
519
+ }
520
+
521
+ getAiQuestion(obj).then(res => {
522
+ if (res.success) {
523
+ this.loading && this.loading.close()
524
+ if (res.data && res.data.questions && res.data.questions.length > 0) {
525
+ if (this.aiResponse.questions && this.aiResponse.questions.length > 0) {
526
+ this.aiResponse.questions.push(res.data.questions[0]);
527
+ } else {
528
+ this.aiResponse = res.data;
529
+ }
530
+ this.$set(res.data.questions[0], 'evaluate', 0)
531
+ this.showGenerateResult();
300
532
  } else {
301
- this.$message.success('生成' + this.generateCount + '道题目成功');
533
+ this.$message.warning('题目获取失败,重新生成中...')
534
+ return this.reSend()
302
535
  }
303
- this.$nextTick(() => {
304
- const generateDiv = this.$refs.generateDiv;
305
- generateDiv.scrollTop = generateDiv.scrollHeight;
306
- });
307
- },
308
- reSend() {
536
+ } else {
309
537
  this.loading && this.loading.close()
310
- this.loading = this.$loading({
311
- target: '.el-dialog',
312
- text: 'AI生成中...'
313
- });
538
+ this.$message.warning('题目获取失败')
539
+ this.rebuildFlag = false;
540
+ }
541
+ }).catch(error => {
542
+ console.log("error:" + error);
543
+ this.loading && this.loading.close()
544
+ this.$message.warning('题目获取失败')
545
+ this.rebuildFlag = false;
546
+ })
547
+ },
548
+
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++) {
314
580
  let obj = {
315
581
  modelType: 'aliyun',
316
582
  questionAddCmd: {
317
- questionTypes: this.form.questionTypes,
318
- // count: this.form.count,
583
+ questionTypes: [type], // 单个题型
319
584
  count: 1,
320
585
  knowledge: this.form.knowledge.join(' '),
321
586
  knowledgeId: this.form.knowledgeId[this.form.knowledgeId.length - 1],
322
- difficultys: this.form.difficultys,
587
+ difficultys: [difficulty], // 对应的难度
323
588
  prompt: this.form.prompt
324
589
  },
325
590
  sessionId: this.aiResponse.sessionId ? this.aiResponse.sessionId : '',
326
- businessSource:this.businessSource
591
+ businessSource: this.businessSource,
592
+ courseId: this.courseId,
327
593
  }
594
+
328
595
  getAiQuestion(obj).then(res => {
329
596
  if (res.success) {
330
597
  this.loading && this.loading.close()
@@ -335,6 +602,8 @@ export default {
335
602
  this.aiResponse = res.data;
336
603
  }
337
604
  this.$set(res.data.questions[0], 'evaluate', 0)
605
+ // 设置题目类型,便于后续统计
606
+ this.$set(res.data.questions[0], 'type', type)
338
607
  this.showGenerateResult();
339
608
  } else {
340
609
  this.$message.warning('题目获取失败,重新生成中...')
@@ -351,187 +620,218 @@ export default {
351
620
  this.$message.warning('题目获取失败')
352
621
  this.rebuildFlag = false;
353
622
  })
354
- },
355
- //发送请求
356
- sendPost() {
357
- checkVersion(this.businessSource).then(res => {
358
- console.log(res);
359
- if (res.errCode === '403') {
360
- this.$message.warning(res.errMessage)
361
- } else {
362
- this.postQuestion();
363
- }
364
- });
365
- // this.postQuestion();
366
- },
367
- postQuestion() {
368
- this.rebuildFlag = true;
369
- this.generateCount = 0;
370
- this.aiResponse = {}
371
- this.loading && this.loading.close()
372
- this.loading = this.$loading({
373
- target: '.el-dialog',
374
- text: 'AI生成中...'
375
- });
376
- for(let i = 0; i<this.form.count; i++){
377
- let obj = {
378
- modelType: 'aliyun',
379
- questionAddCmd: {
380
- questionTypes: this.form.questionTypes,
381
- // count: this.form.count,
382
- count: 1,
383
- knowledge: this.form.knowledge.join(' '),
384
- knowledgeId: this.form.knowledgeId[this.form.knowledgeId.length - 1],
385
- difficultys: this.form.difficultys,
386
- prompt: this.form.prompt
387
- },
388
- sessionId: this.aiResponse.sessionId ? this.aiResponse.sessionId : '',
389
- businessSource:this.businessSource
390
- }
391
- getAiQuestion(obj).then(res => {
392
- // console.log("questions obj is :" + JSON.stringify(res.data.questions));
393
- // console.log("res is :" + JSON.stringify(res));
394
- if (res.success) {
395
- this.loading && this.loading.close()
396
- // this.aiResponse = {}
397
- // this.aiResponse = res.data || {}
398
- if (res.data && res.data.questions && res.data.questions.length > 0) {
399
- // this.aiResponse.questions.forEach(item => {
400
- // this.$set(item, 'evaluate', 0)
401
- // })
402
- if (this.aiResponse.questions && this.aiResponse.questions.length > 0) {
403
- this.aiResponse.questions.push(res.data.questions[0]);
404
- } else {
405
- this.aiResponse = res.data;
406
- }
407
- this.$set(res.data.questions[0], 'evaluate', 0)
408
- this.showGenerateResult();
409
- } else {
410
- this.$message.warning('题目获取失败,重新生成中...')
411
- return this.reSend()
412
- }
413
- } else {
414
- this.loading && this.loading.close()
415
- this.$message.warning('题目获取失败')
416
- this.rebuildFlag = false;
417
- }
418
- }).catch(error => {
419
- console.log("error:" + error);
420
- this.loading && this.loading.close()
421
- this.$message.warning('题目获取失败')
422
- this.rebuildFlag = false;
423
- })
424
- }
425
- },
426
- //获取知识点名称
427
- getKnowledgeName(e, array) {
428
- array.forEach(item => {
429
- if (e == item.id) {
430
- return this.form.knowledge.push(item.label)
431
- } else if (item.children && item.children.length > 0) {
432
- this.getKnowledgeName(e, item.children)
433
- }
434
- });
435
- },
436
- //点赞
437
- agree(e, j) {
438
- this.aiResponse.questions[e].evaluate = j
439
- let obj = {
440
- modelType: 'aliyun',
441
- ...this.aiResponse
442
- }
443
- agreeQuestion(obj).then(res => {
623
+ }
624
+ });
625
+ },
444
626
 
445
- }).catch(error => {
446
- console.log(error);
447
- })
448
- },
449
- //加入题库
450
- join(e) {
451
- this.$emit('joinQuestionBank', { ...e, knowledgePointsId: this.form.knowledgeId[this.form.knowledgeId.length - 1] })
627
+ //获取知识点名称
628
+ getKnowledgeName(e, array) {
629
+ array.forEach(item => {
630
+ if (e == item.id) {
631
+ return this.form.knowledge.push(item.label)
632
+ } else if (item.children && item.children.length > 0) {
633
+ this.getKnowledgeName(e, item.children)
452
634
  }
453
- }
454
- }
635
+ });
636
+ },
637
+
638
+ //点赞
639
+ agree(e, j) {
640
+ this.aiResponse.questions[e].evaluate = j
641
+ let obj = {
642
+ modelType: 'aliyun',
643
+ ...this.aiResponse
644
+ }
645
+ agreeQuestion(obj).then(res => {
646
+ // 处理响应
647
+ }).catch(error => {
648
+ console.log(error);
649
+ })
650
+ },
651
+
652
+ //加入题库
653
+ join(e) {
654
+ this.$emit('joinQuestionBank', {...e, knowledgePointsId: this.form.knowledgeId[this.form.knowledgeId.length - 1]})
655
+
656
+ // 当单个题目加入题库后,从选中列表中移除该题目
657
+ const questionIndex = this.aiResponse.questions.findIndex(q => q === e);
658
+ if (questionIndex !== -1) {
659
+ this.selectedQuestions = this.selectedQuestions.filter(q => q.index !== questionIndex);
660
+
661
+ // 将题目索引添加到已加入题库列表
662
+ if (!this.joinedQuestions.includes(questionIndex)) {
663
+ this.joinedQuestions.push(questionIndex);
664
+ }
665
+ }
666
+ },
667
+
668
+ selectBot(bot) {
669
+ this.currentBot = bot;
670
+ this.dropdownVisible = false;
671
+ },
672
+
673
+ // 处理题目选择变化
674
+ handleQuestionSelection(data) {
675
+ const { index, selected, detail } = data;
676
+
677
+ if (selected) {
678
+ // 添加到选中列表
679
+ if (!this.selectedQuestions.find(q => q.index === index)) {
680
+ this.selectedQuestions.push({ index, detail });
681
+ }
682
+ } else {
683
+ // 从选中列表移除
684
+ this.selectedQuestions = this.selectedQuestions.filter(q => q.index !== index);
685
+ }
686
+ },
687
+
688
+ // 获取题目类型统计
689
+ getQuestionTypeSummary() {
690
+ if (!this.aiResponse.questions || this.aiResponse.questions.length === 0) {
691
+ return [];
692
+ }
693
+
694
+ const typeCounts = {};
695
+ const typeNameMap = {
696
+ single: '单选题',
697
+ multiple: '多选题',
698
+ gapfilling: '填空题',
699
+ judge: '判断题',
700
+ shortanswer: '简答题'
701
+ };
702
+
703
+ // 统计各类型题目数量
704
+ this.aiResponse.questions.forEach(question => {
705
+ const type = question.type || 'single'; // 默认为单选题
706
+ typeCounts[type] = (typeCounts[type] || 0) + 1;
707
+ });
708
+
709
+ // 转换为显示格式
710
+ return Object.keys(typeCounts).map(typeId => ({
711
+ id: typeId,
712
+ name: typeNameMap[typeId] || typeId,
713
+ count: typeCounts[typeId]
714
+ }));
715
+ },
716
+
717
+ // 批量加入题库
718
+ addAllToBank() {
719
+ if (this.selectedQuestions.length === 0) {
720
+ return this.$message.warning('请先选择要加入题库的题目');
721
+ }
722
+
723
+ // 批量加入选中的题目到题库
724
+ this.selectedQuestions.forEach(({ index, detail }) => {
725
+ // 调用单个题目的加入题库方法
726
+ this.$emit('joinQuestionBank', {
727
+ ...detail,
728
+ knowledgePointsId: this.form.knowledgeId[this.form.knowledgeId.length - 1]
729
+ });
730
+
731
+ // 将题目索引添加到已加入题库列表
732
+ if (!this.joinedQuestions.includes(index)) {
733
+ this.joinedQuestions.push(index);
734
+ }
735
+
736
+ // 直接调用子组件方法清空选中状态
737
+ this.$nextTick(() => {
738
+ const questionItemRef = this.$refs[`questionItem_${index}`];
739
+ if (questionItemRef) {
740
+ // 如果是数组,取第一个元素;如果不是数组,直接使用
741
+ const componentInstance = Array.isArray(questionItemRef) ? questionItemRef[0] : questionItemRef;
742
+ if (componentInstance && componentInstance.clearSelection) {
743
+ componentInstance.clearSelection();
744
+ }
745
+ }
746
+ });
747
+ });
748
+
749
+ // 清空选中状态
750
+ this.selectedQuestions = [];
751
+ },
752
+ }
753
+ }
455
754
  </script>
456
755
  <style lang="scss" scoped>
457
756
  .ai_contain {
458
757
  display: inline-block;
758
+ font-family: "Microsoft YaHei", 微软雅黑, sans-serif;
459
759
 
460
760
  ::v-deep {
461
761
  .el-drawer.rtl {
462
762
  border-radius: 15px 0 0 15px;
763
+ width: 720px !important;
463
764
  }
464
765
 
465
766
  .el-icon-close:before {
466
767
  color: #0e0e0e;
467
768
  font-weight: bold;
468
- font-size: 16px;
769
+ font-size: 24px;
469
770
  }
470
771
 
471
772
  .el-drawer__header {
472
773
  padding-top: 0;
473
774
  height: 64px;
474
- background:
475
- linear-gradient(to bottom, rgba(255,255,255,0), white), /* 底部渐变到白色 */
476
- linear-gradient(to right, #BCB9F4, #D5C6F8, #E6C6F9); /* 从左到右的渐变色带 */
775
+ background: linear-gradient(to bottom, rgba(255, 255, 255, 0), white),
776
+ linear-gradient(to right, #BCB9F4, #D5C6F8, #E6C6F9);
777
+ margin-bottom: 0;
477
778
  }
478
779
 
479
780
  .el-drawer__body {
480
- padding: 0 20px;
781
+ padding: 0 30px;
481
782
  display: flex;
482
783
  flex-direction: column;
483
784
  justify-content: space-between;
484
785
  }
485
786
 
486
- .el-form-item__label {
487
- font-weight: 700;
488
- }
489
-
490
- .el-input__inner {
491
- padding-right: 0;
492
- border-radius: 25px;
787
+ .el-checkbox__inner {
788
+ width: 20px;
789
+ height: 20px;
790
+ border-radius: 4px;
493
791
  }
494
792
 
495
- .el-cascader {
496
- width: 100%;
793
+ .el-checkbox__input.is-checked .el-checkbox__inner {
794
+ background-color: #7C4DFF;
795
+ border-color: #7C4DFF;
497
796
  }
498
797
 
499
- .el-radio__inner {
500
- width: 24px;
501
- height: 24px;
798
+ .el-checkbox__inner::after {
799
+ width: 4px;
800
+ height: 9px;
801
+ border: 3px solid #fff;
802
+ border-left: 0;
803
+ border-top: 0;
804
+ left: 6px;
805
+ top: 2px;
502
806
  }
503
807
 
504
- .el-radio__input.is-checked+.el-radio__label {
505
- color: #606266;
808
+ .el-slider__runway {
809
+ height: 6px;
810
+ background-color: #E5E5E5;
811
+ border-radius: 3px;
506
812
  }
507
813
 
508
- .el-radio__input.is-checked .el-radio__inner {
509
- border-color: #7050D0;
510
- background: #7050D0;
814
+ .el-slider__button {
815
+ width: 20px;
816
+ height: 20px;
817
+ border: 1px solid #7C4DFF;
818
+ background-color: #7C4DFF;
511
819
  }
512
820
 
513
- .el-radio__input.is-checked .el-radio__inner::after {
514
- display: none;
821
+ .el-slider__bar {
822
+ background-color: #7C4DFF;
515
823
  }
516
824
 
517
- /* 使用Element UI的对号图标 */
518
- .el-radio__input.is-checked .el-radio__inner::before {
519
- font-family: "element-icons", serif;
520
- content: "\e6da"; /* Element UI check图标的Unicode */
521
- position: absolute;
522
- top: 50%;
523
- left: 50%;
524
- transform: translate(-50%, -50%);
525
- font-size: 12px;
526
- color: #fff;
527
- }
528
-
529
- .el-select .el-input__inner {
530
- border-radius: 25px;
825
+ .el-input__inner {
826
+ border-radius: 12px;
827
+ height: 48px;
828
+ border: 1px solid #E0E0E0;
531
829
  }
532
830
 
533
831
  .el-textarea__inner {
534
832
  border-radius: 16px;
833
+ border: 1px solid #E0E0E0;
834
+ font-family: "Microsoft YaHei", 微软雅黑, sans-serif;
535
835
  }
536
836
 
537
837
  .el-loading-mask {
@@ -539,26 +839,6 @@ export default {
539
839
  }
540
840
  }
541
841
 
542
- .button-handle {
543
- width: 168px;
544
- height: 48px;
545
- font-size: 14px;
546
- border-radius: 25px;
547
- border: none;
548
- color: #fff;
549
- cursor: pointer;
550
- }
551
-
552
- .button-generate-question {
553
- background: linear-gradient(to bottom, #7050D0, #2828E0);
554
- }
555
-
556
- .button-cancel {
557
- border: 1px solid #2828E0;
558
- background: transparent;
559
- color: #3030C0;
560
- }
561
-
562
842
  .ai_button {
563
843
  cursor: pointer;
564
844
  user-select: none;
@@ -576,29 +856,395 @@ export default {
576
856
  font-size: 18px;
577
857
  color: #333333;
578
858
  font-weight: bold;
579
- gap: 5px;
859
+ gap: 7px;
580
860
  }
581
861
 
582
862
  .add_question_body {
583
- .remind {
584
- font-size: 14px;
585
- color: #9BA1AE;
863
+ .question-type-header {
864
+ margin-bottom: 20px;
865
+
866
+ .required-mark {
867
+ color: #FF4455;
868
+ margin-right: 4px;
869
+ }
870
+
871
+ .section-title {
872
+ font-size: 14px;
873
+ color: #303040;
874
+ }
875
+
876
+ .tip-text {
877
+ font-size: 12px;
878
+ color: #999;
879
+ margin-left: 20px;
880
+ }
881
+ }
882
+
883
+ .question-type-list {
884
+ margin-bottom: 30px;
885
+
886
+ .question-type-item {
887
+ display: flex;
888
+ align-items: center;
889
+ padding: 5px 10px;
890
+ margin-bottom: 12px;
891
+ transition: all 0.3s ease;
892
+
893
+ .type-left {
894
+ display: flex;
895
+ align-items: center;
896
+
897
+ .type-checkbox {
898
+ margin-right: 12px;
899
+ }
900
+
901
+ .type-name {
902
+ font-size: 14px;
903
+ font-weight: bold;
904
+ border-radius: 54px;
905
+ color: #fff;
906
+ height: 40px;
907
+ width: 80px;
908
+ display: flex;
909
+ align-items: center;
910
+ justify-content: center;
911
+
912
+ &.type-single {
913
+ background: #8060F029;
914
+ color: #6040F0;
915
+ }
916
+
917
+ &.type-multiple {
918
+ background: #0090F029;
919
+ color: #0090FF;
920
+ }
921
+
922
+ &.type-gapfilling {
923
+ background: #60C09029;
924
+ color: #60C090;
925
+ }
926
+
927
+ &.type-judge {
928
+ background: #F0A00029;
929
+ color: #F0A000;
930
+ }
931
+
932
+ &.type-shortanswer {
933
+ background: #E060C029;
934
+ color: #E060C0;
935
+ }
936
+ }
937
+ }
938
+
939
+ .type-right {
940
+ display: flex;
941
+ align-items: center;
942
+ gap: 20px;
943
+
944
+ .count-input {
945
+ width: 160px;
946
+ margin-left: 20px;
947
+
948
+ ::v-deep .el-input__inner {
949
+ height: 42px;
950
+ border-radius: 56px;
951
+ text-align: center;
952
+ font-size: 12px;
953
+ }
954
+ }
955
+
956
+ .slider-container {
957
+ width: 240px;
958
+ margin-left: 10px;
959
+
960
+ &.disabled {
961
+ ::v-deep .el-slider__button {
962
+ background-color: #ffffff;
963
+ border: 1px solid #797979;
964
+ }
965
+ }
966
+ }
967
+
968
+ .difficulty-label {
969
+ font-size: 14px;
970
+ color: #6040E0;
971
+ min-width: 80px;
972
+ font-weight: bold;
973
+
974
+ &.disabled {
975
+ color: #CCC;
976
+ }
977
+ }
978
+
979
+ .placeholder-text {
980
+ font-size: 12px;
981
+ color: #DDDDE0;
982
+ width: 160px;
983
+ border: 1px solid #DDDDE0;
984
+ border-radius: 56px;
985
+ height: 40px;
986
+ text-align: center;
987
+ margin-left: 20px;
988
+ display: flex;
989
+ align-items: center;
990
+ justify-content: center;
991
+ }
992
+ }
993
+ }
994
+ }
995
+
996
+ .knowledge-section, .prompt-section {
997
+ margin-bottom: 24px;
998
+
999
+ .section-header {
1000
+ margin-bottom: 12px;
1001
+
1002
+ .required-mark {
1003
+ color: #FF4455;
1004
+ margin-right: 4px;
1005
+ }
1006
+
1007
+ .section-title {
1008
+ font-size: 14px;
1009
+ color: #303040;
1010
+ }
1011
+
1012
+ .tip-text {
1013
+ font-size: 12px;
1014
+ color: #999;
1015
+ margin-left: 20px;
1016
+ }
1017
+ }
1018
+
1019
+ .knowledge-input {
1020
+ position: relative;
1021
+
1022
+ .knowledge-icon {
1023
+ position: absolute;
1024
+ right: 12px;
1025
+ top: 50%;
1026
+ transform: translateY(-50%);
1027
+ color: #999;
1028
+ font-size: 16px;
1029
+ width: 24px;
1030
+ height: 24px;
1031
+ }
1032
+ }
1033
+ }
1034
+
1035
+ .prompt-textarea {
1036
+ .el-textarea__inner {
1037
+ min-height: 120px !important;
1038
+ font-family: "Microsoft YaHei", 微软雅黑, sans-serif;
1039
+ }
586
1040
  }
587
1041
  }
588
1042
 
589
1043
  .add_question_footer {
590
- padding: 20px 0;
591
- border-top: 1px solid #E6E6E6;
1044
+ padding-bottom: 30px;
592
1045
  display: flex;
593
1046
  justify-content: center;
594
1047
  align-items: center;
595
1048
  gap: 30px;
1049
+
1050
+ .button-handle {
1051
+ width: 168px;
1052
+ height: 48px;
1053
+ font-size: 14px;
1054
+ border-radius: 25px;
1055
+ border: none;
1056
+ color: #fff;
1057
+ cursor: pointer;
1058
+ transition: all 0.3s ease;
1059
+
1060
+ &:hover {
1061
+ transform: translateY(-1px);
1062
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
1063
+ }
1064
+ }
1065
+
1066
+ .button-generate-question {
1067
+ background: linear-gradient(to bottom, #7050D0 0%, #2828E0 100%);
1068
+ width: 280px;
1069
+ display: flex;
1070
+ justify-content: center;
1071
+ align-items: center;
1072
+ gap: 10px;
1073
+ }
1074
+
1075
+ .button-cancel {
1076
+ border: 1px solid #7050D0;
1077
+ background: transparent;
1078
+ color: #3030C0;
1079
+ }
596
1080
  }
597
- }
598
1081
 
599
- /* 对话框样式需要全局作用域,因为它会脱离当前组件 */
600
- </style>
1082
+ .ai-bot-switch {
1083
+ display: flex;
1084
+ align-items: center;
1085
+ background: transparent;
1086
+ justify-content: center;
1087
+ border-radius: 49px;
1088
+ -webkit-user-select: none;
1089
+ -moz-user-select: none;
1090
+ user-select: none;
1091
+ height: 40px;
1092
+ width: 144px;
1093
+ cursor: pointer;
1094
+ z-index: 2;
1095
+ border: 1px solid #6040E0A3;
1096
+ font-size: 12px;
1097
+ color: #182028;
1098
+ }
1099
+
1100
+ .ai-bot-label {
1101
+ font-weight: 500;
1102
+ margin-right: 2px;
1103
+ margin-left: 5px;
1104
+ width: 72px;
1105
+ }
1106
+
1107
+ .ai-bot-dropdown {
1108
+ background: #fff;
1109
+ border-radius: 8px;
1110
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
1111
+ border: 1px solid #e0e0ff;
1112
+ padding: 4px 0;
1113
+ }
1114
+
1115
+ .ai-bot-dropdown-item {
1116
+ padding: 8px 20px;
1117
+ cursor: pointer;
1118
+ font-size: 14px;
1119
+ color: #333;
1120
+ transition: background 0.2s;
1121
+ }
1122
+
1123
+ .ai-bot-dropdown-item.active,
1124
+ .ai-bot-dropdown-item:hover {
1125
+ background: #f0f2f8;
1126
+ color: #3830E0;
1127
+ }
1128
+
1129
+ // 题目结果抽屉样式
1130
+ .question-result-drawer {
1131
+ ::v-deep .el-drawer__body {
1132
+ padding: 0;
1133
+ height: 100%;
1134
+ display: flex;
1135
+ flex-direction: column;
1136
+ }
1137
+
1138
+ .drawer_content_wrapper {
1139
+ display: flex;
1140
+ flex-direction: column;
1141
+ height: 100%;
1142
+ padding: 0 20px;
1143
+ }
1144
+
1145
+ .question_summary_warp {
1146
+ display: flex;
1147
+ justify-content: space-between;
1148
+ margin-bottom: 20px;
601
1149
 
1150
+ .question_summary {
1151
+ .summary_text {
1152
+ color: #6040E0;
1153
+ font-size: 14px;
1154
+ font-weight: bold;
1155
+ }
1156
+
1157
+ .question_types_summary {
1158
+ .type_item {
1159
+ font-size: 12px;
1160
+ color: #182028A3;
1161
+ }
1162
+ }
1163
+ }
1164
+
1165
+ .question_summary_button {
1166
+ display: flex;
1167
+ gap: 15px;
1168
+ margin-right: 15px;
1169
+
1170
+ .button-handle {
1171
+ width: 96px;
1172
+ height: 40px;
1173
+ font-size: 14px;
1174
+ border-radius: 25px;
1175
+ border: none;
1176
+ color: #fff;
1177
+ cursor: pointer;
1178
+ transition: all 0.3s ease;
1179
+ }
1180
+ .button-generate-question {
1181
+ background: linear-gradient(to bottom, #7050D0 0%, #2828E0 100%);
1182
+ display: flex;
1183
+ justify-content: center;
1184
+ align-items: center;
1185
+ gap: 10px;
1186
+ }
1187
+
1188
+ .button-cancel {
1189
+ border: 1px solid #7050D0;
1190
+ background: transparent;
1191
+ color: #3030C0;
1192
+ }
1193
+ }
1194
+ }
1195
+
1196
+ .question_body {
1197
+ flex: 1;
1198
+ overflow-y: auto;
1199
+ padding-right: 10px;
1200
+
1201
+ &::-webkit-scrollbar {
1202
+ width: 6px;
1203
+ }
1204
+
1205
+ &::-webkit-scrollbar-track {
1206
+ background: rgba(255, 255, 255, 0.3);
1207
+ border-radius: 3px;
1208
+ }
1209
+
1210
+ &::-webkit-scrollbar-thumb {
1211
+ background: rgba(124, 77, 255, 0.3);
1212
+ border-radius: 3px;
1213
+
1214
+ &:hover {
1215
+ background: rgba(124, 77, 255, 0.5);
1216
+ }
1217
+ }
1218
+ }
1219
+
1220
+ .question_footer_fixed {
1221
+ flex-shrink: 0;
1222
+ padding: 0 0 10px 0;
1223
+ background: rgba(255, 255, 255, 0.9);
1224
+ border-top: 1px solid rgba(255, 255, 255, 0.3);
1225
+ backdrop-filter: blur(10px);
1226
+
1227
+ .footer_warning {
1228
+ display: flex;
1229
+ align-items: center;
1230
+ gap: 8px;
1231
+
1232
+ .el-icon-info {
1233
+ width: 24px;
1234
+ height: 24px;
1235
+ flex-shrink: 0;
1236
+ }
1237
+
1238
+ .question_remind {
1239
+ font-size: 12px;
1240
+ color: #797979;
1241
+ line-height: 1.4;
1242
+ }
1243
+ }
1244
+ }
1245
+ }
1246
+ }
1247
+ </style>
602
1248
 
603
1249
  <style lang="scss">
604
1250
  .ai-custom-dialog.el-dialog {
@@ -610,7 +1256,7 @@ export default {
610
1256
  align-items: center;
611
1257
  font-weight: 700;
612
1258
  font-size: 23px;
613
- color: #333333;
1259
+ color: #181820;
614
1260
 
615
1261
  img {
616
1262
  margin-right: 10px;
@@ -646,11 +1292,25 @@ export default {
646
1292
  .question_footer {
647
1293
  display: flex;
648
1294
  justify-content: space-between;
1295
+ align-items: center;
649
1296
 
650
- .question_remind {
651
- align-self: flex-end;
652
- font-size: 14px;
653
- color: #9BA1AE;
1297
+ .footer_warning {
1298
+ display: flex;
1299
+ align-items: center;
1300
+ gap: 8px;
1301
+ flex: 1;
1302
+
1303
+ .el-icon-info {
1304
+ color: #7C4DFF;
1305
+ font-size: 16px;
1306
+ flex-shrink: 0;
1307
+ }
1308
+
1309
+ .question_remind {
1310
+ font-size: 14px;
1311
+ color: #9BA1AE;
1312
+ line-height: 1.4;
1313
+ }
654
1314
  }
655
1315
  }
656
1316
  }