ExamQuestion.vue 35 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133
  1. <template>
  2. <el-container>
  3. <el-header height="220">
  4. <el-row>
  5. <el-select v-model="queryInfo.questionType" clearable placeholder="请选择试题类型" @change="typeChange">
  6. <el-option
  7. v-for="item in questionType"
  8. :key="item.id"
  9. :label="item.name"
  10. :value="item.id"
  11. />
  12. </el-select>
  13. <el-select
  14. v-model="queryInfo.questionBank"
  15. clearable
  16. placeholder="请选择题库"
  17. style="margin-left: 5px"
  18. @change="bankChange"
  19. >
  20. <el-option
  21. v-for="item in allSubject"
  22. :key="item.id"
  23. :label="item.value"
  24. :value="item.value"
  25. />
  26. </el-select>
  27. <el-input
  28. v-model="queryInfo.questionContent"
  29. placeholder="试题内容"
  30. style="margin-left: 5px;width: 220px"
  31. prefix-icon="el-icon-search"
  32. @blur="contentChange"
  33. />
  34. </el-row>
  35. <el-row style="margin-top: 10px">
  36. <el-button type="plain" icon="el-icon-plus" @click="addQuTableVisible = true">添加</el-button>
  37. </el-row>
  38. </el-header>
  39. <el-main>
  40. <el-table
  41. :data="dataList"
  42. border
  43. style="width: 100%"
  44. >
  45. <el-table-column
  46. fixed="left"
  47. label="No"
  48. type="index"
  49. />
  50. <el-table-column
  51. prop="subject"
  52. label="所属科目"
  53. />
  54. <el-table-column
  55. prop="type"
  56. label="试题类型"
  57. />
  58. <el-table-column
  59. prop="content"
  60. label="试题内容"
  61. :show-overflow-tooltip="true"
  62. >
  63. <template slot-scope="scope">
  64. <el-tooltip
  65. :content="scope.row.content"
  66. raw-content
  67. placement="top-start"
  68. >
  69. <span v-if="scope.row.content.length <= 15">
  70. {{ scope.row.content }}
  71. </span>
  72. <span v-else>
  73. {{ scope.row.content.substr(0, 15) + "..." }}
  74. </span>
  75. </el-tooltip>
  76. </template>
  77. </el-table-column>
  78. <el-table-column
  79. prop="level"
  80. label="试题难度"
  81. />
  82. <el-table-column
  83. prop="createBy"
  84. label="创建人"
  85. />
  86. <el-table-column
  87. prop="createAt"
  88. label="创建时间"
  89. />
  90. <el-table-column label="操作">
  91. <template slot-scope="scope">
  92. <el-button
  93. size="mini"
  94. type="info"
  95. @click="viewDetail(scope.row.questionId)"
  96. >查看</el-button>
  97. <el-button
  98. size="mini"
  99. type="danger"
  100. @click="onDeleteQuestion(scope.row.questionId)"
  101. >删除</el-button>
  102. </template>
  103. </el-table-column>
  104. </el-table>
  105. <el-pagination
  106. style="margin-top: 25px"
  107. :small="screenWidth <= 768"
  108. layout="total, sizes, prev, pager, next, jumper"
  109. :page-sizes="[10, 20, 50]"
  110. :page-size="pageSize"
  111. :current-page="currentPage"
  112. :total="totalSize"
  113. @current-change="handleCurrentChange"
  114. @prev-click="handleCurrentChange"
  115. @next-click="handleCurrentChange"
  116. />
  117. </el-main>
  118. <el-dialog title="更新试题" :visible.sync="updateQuTableVisible" width="50%" center>
  119. <el-card>
  120. <el-form ref="updateQuForm" :model="updateQuForm" :rules="updateQuFormRules">
  121. <el-form-item label="试题类型" label-width="120px" prop="questionType">
  122. <el-select
  123. v-model="updateQuForm.questionType"
  124. disabled
  125. placeholder="请选择"
  126. @change="updateQuForm.answer = []"
  127. >
  128. <el-option
  129. v-for="item in questionType"
  130. :key="item.id"
  131. :label="item.name"
  132. :value="item.id"
  133. />
  134. </el-select>
  135. </el-form-item>
  136. <el-form-item label="难度等级" label-width="120px" prop="questionLevel">
  137. <el-select v-model="updateQuForm.questionLevel" placeholder="请选择">
  138. <el-option :value="parseInt(1)" label="简单" />
  139. <el-option :value="parseInt(2)" label="中等" />
  140. <el-option :value="parseInt(3)" label="困难" />
  141. </el-select>
  142. </el-form-item>
  143. <el-form-item label="归属题库" label-width="120px" prop="subjectId">
  144. <el-select v-model="updateQuForm.subjectId" multiple placeholder="请选择">
  145. <el-option
  146. v-for="item in allSubject"
  147. :key="item.key"
  148. :label="item.value"
  149. :value="item.key"
  150. />
  151. </el-select>
  152. </el-form-item>
  153. <el-form-item label="试题内容" label-width="120px" prop="questionContent">
  154. <el-input
  155. v-model="updateQuForm.questionContent"
  156. style="margin-left: 5px"
  157. type="textarea"
  158. :rows="2"
  159. />
  160. </el-form-item>
  161. <el-form-item label="试题图片" label-width="120px">
  162. <el-upload
  163. :action="uploadImageUrl + '/teacher/uploadQuestionImage'"
  164. :on-preview="uploadPreview"
  165. :on-remove="handleUpdateRemove"
  166. :before-upload="beforeAvatarUpload"
  167. list-type="picture"
  168. :on-success="updateUploadImgSuccess"
  169. name="file"
  170. >
  171. <el-button size="small" type="primary">点击上传</el-button>
  172. <div slot="tip" class="el-upload__tip">只能上传jpg/png文件,且不超过10M</div>
  173. </el-upload>
  174. </el-form-item>
  175. <el-form-item label="试题解析" label-width="120px" prop="analysis">
  176. <el-input
  177. v-model="updateQuForm.analysis"
  178. style="margin-left: 5px"
  179. type="textarea"
  180. :rows="2"
  181. />
  182. </el-form-item>
  183. <el-button
  184. v-if="updateQuForm.questionType!==4"
  185. type="primary"
  186. plain
  187. size="small"
  188. icon="el-icon-plus"
  189. style="margin-left: 40px"
  190. @click="addUpdateAnswer"
  191. >
  192. 添加
  193. </el-button>
  194. <!--存放答案表单的信息-->
  195. <el-form-item v-if="updateQuForm.questionType !== 4" prop="answer">
  196. <el-table :data="updateQuForm.answer" border style="width: 96%;margin-left: 40px;margin-top: 10px">
  197. <el-table-column label="是否答案" width="80" align="center">
  198. <template slot-scope="scope">
  199. <el-checkbox v-model="scope.row.correct" @change="checked=>checkUpdateAnswer(checked,scope.row.id)">答案
  200. </el-checkbox>
  201. </template>
  202. </el-table-column>
  203. <el-table-column label="答案图片">
  204. <template slot-scope="scope">
  205. <el-upload
  206. id="answerUpload"
  207. :limit="1"
  208. :action="uploadImageUrl + '/teacher/uploadQuestionImage'"
  209. :on-preview="uploadPreview"
  210. :on-remove="handleUpdateAnswerRemove"
  211. :before-upload="beforeAvatarUpload"
  212. list-type="picture"
  213. :on-success="(res) => { return uploadUpdateAnswerImgSuccess(res,scope.row.id)}"
  214. name="file"
  215. >
  216. <el-button size="small" type="primary">点击上传</el-button>
  217. </el-upload>
  218. </template>
  219. </el-table-column>
  220. <el-table-column label="答案内容">
  221. <template slot-scope="scope">
  222. <el-input
  223. v-model="scope.row.answer"
  224. style="margin-left: 5px"
  225. type="textarea"
  226. :rows="2"
  227. />
  228. </template>
  229. </el-table-column>
  230. <el-table-column label="答案解析">
  231. <template slot-scope="scope">
  232. <el-input
  233. v-model="scope.row.analysis"
  234. style="margin-left: 5px"
  235. type="textarea"
  236. :rows="2"
  237. />
  238. </template>
  239. </el-table-column>
  240. <el-table-column label="操作" width="80" align="center">
  241. <template slot-scope="scope">
  242. <el-button
  243. type="danger"
  244. icon="el-icon-delete"
  245. circle
  246. @click="delUpdateAnswer(scope.row.id)"
  247. />
  248. </template>
  249. </el-table-column>
  250. </el-table>
  251. </el-form-item>
  252. </el-form>
  253. </el-card>
  254. <div slot="footer" class="dialog-footer">
  255. <el-button @click="updateQuTableVisible = false">取 消</el-button>
  256. <el-button type="primary" @click="updateQuestion">确 定</el-button>
  257. </div>
  258. </el-dialog>
  259. <el-dialog title="试题详情" :visible.sync="questionDetailDialog" width="50%" center>
  260. <el-card>
  261. <el-form :model="questionDetail">
  262. <el-form-item label="所属科目" label-width="120px">
  263. <span> {{ questionDetail.subject }} </span>
  264. </el-form-item>
  265. <el-form-item label="试题类型" label-width="120px">
  266. <span> {{ questionDetail.typeStr }} </span>
  267. </el-form-item>
  268. <el-form-item label="试题难度" label-width="120px">
  269. <span> {{ questionDetail.level }} </span>
  270. </el-form-item>
  271. <el-divider />
  272. <el-form-item label="试题内容" label-width="120px">
  273. <span> {{ questionDetail.content }} </span>
  274. </el-form-item>
  275. <el-form-item label="试题解析" label-width="120px">
  276. <span> {{ questionDetail.analysis }} </span>
  277. </el-form-item>
  278. <el-divider />
  279. <el-form-item v-if="questionDetail.type <= 7" label="试题选项" label-width="120px">
  280. <el-table :data="questionDetail.options" border style="width: 96%;margin-left: 40px;margin-top: 10px">
  281. <el-table-column label="正确答案" align="center">
  282. <template slot-scope="scope">
  283. <span v-if="scope.row.correct">YES</span>
  284. <span v-else>NO</span>
  285. </template>
  286. </el-table-column>
  287. <el-table-column
  288. prop="option"
  289. label="选项"
  290. />
  291. <el-table-column
  292. prop="content"
  293. label="内容"
  294. />
  295. <el-table-column
  296. prop="analysis"
  297. label="解析"
  298. />
  299. </el-table>
  300. </el-form-item>
  301. <div v-if="questionDetail.children">
  302. <div v-for="item in questionDetail.children">
  303. <el-form :model="item">
  304. <el-form-item label="试题类型" label-width="120px">
  305. <span> {{ item.typeStr }} </span>
  306. </el-form-item>
  307. <el-form-item label="试题难度" label-width="120px">
  308. <span> {{ item.level }} </span>
  309. </el-form-item>
  310. <el-form-item label="试题内容" label-width="120px">
  311. <span> {{ item.content }} </span>
  312. </el-form-item>
  313. <el-form-item label="试题解析" label-width="120px">
  314. <span> {{ item.analysis }} </span>
  315. </el-form-item>
  316. <el-form-item v-if="item.type <= 7" label="试题选项" label-width="120px">
  317. <el-table :data="item.options" border style="width: 96%;margin-left: 40px;margin-top: 10px">
  318. <el-table-column label="正确答案" align="center">
  319. <template slot-scope="scope">
  320. <span v-if="scope.row.correct">YES</span>
  321. <span v-else>NO</span>
  322. </template>
  323. </el-table-column>
  324. <el-table-column
  325. prop="option"
  326. label="选项"
  327. />
  328. <el-table-column
  329. prop="content"
  330. label="内容"
  331. />
  332. <el-table-column
  333. prop="analysis"
  334. label="解析"
  335. />
  336. </el-table>
  337. </el-form-item>
  338. <el-divider />
  339. </el-form>
  340. </div>
  341. </div>
  342. </el-form>
  343. </el-card>
  344. <div slot="footer" class="dialog-footer">
  345. <el-button @click="questionDetailDialog = false">关闭</el-button>
  346. </div>
  347. </el-dialog>
  348. <el-dialog
  349. title="加入题库"
  350. :visible.sync="addTableVisible"
  351. width="30%"
  352. center
  353. @close="resetAddForm"
  354. >
  355. <el-form ref="addForm" :model="addForm" :rules="addFormRules">
  356. <el-form-item label="题库名称" label-width="120px" prop="subjectId">
  357. <el-select v-model="addForm.subjectId" multiple placeholder="请选择题库">
  358. <el-option
  359. v-for="item in allSubject"
  360. :key="item.key"
  361. :label="item.value"
  362. :value="item.key"
  363. />
  364. </el-select>
  365. </el-form-item>
  366. </el-form>
  367. <div slot="footer" class="dialog-footer">
  368. <el-button @click="addTableVisible = false">取 消</el-button>
  369. <el-button type="primary" @click="addBank">确 定</el-button>
  370. </div>
  371. </el-dialog>
  372. <el-dialog
  373. title="从题库中移除"
  374. :visible.sync="removeTableVisible"
  375. width="30%"
  376. center
  377. @close="resetRemoveForm"
  378. >
  379. <el-form ref="removeForm" :model="removeForm" :rules="removeFormRules">
  380. <el-form-item label="题库名称" label-width="120px" prop="subjectId">
  381. <el-select v-model="removeForm.subjectId" multiple placeholder="请选择题库">
  382. <el-option
  383. v-for="item in allSubject"
  384. :key="item.key"
  385. :label="item.value"
  386. :value="item.key"
  387. />
  388. </el-select>
  389. </el-form-item>
  390. </el-form>
  391. <div slot="footer" class="dialog-footer">
  392. <el-button @click="removeTableVisible = false">取 消</el-button>
  393. <el-button type="primary" @click="removeBank">确 定</el-button>
  394. </div>
  395. </el-dialog>
  396. <!--图片回显-->
  397. <el-dialog :visible.sync="backShowImgVisible" @close="backShowImgVisible = false">
  398. <img style="width: 100%" :src="backShowImgUrl" alt="">
  399. </el-dialog>
  400. </el-container>
  401. </template>
  402. <script>
  403. import {getExamSubjectKV, postExamQuestion, getExamQuestion, getExamQuestion1, deleteExamQuestion} from '@/api/exam'
  404. import { validFormAndInvoke } from '@/utils/util'
  405. export default {
  406. name: 'ExamQuestion',
  407. data() {
  408. return {
  409. // 屏幕宽度, 为了控制分页条的大小
  410. screenWidth: document.body.clientWidth,
  411. currentPage: 1,
  412. pageSize: 20,
  413. totalSize: 0,
  414. dataList: [],
  415. // **********************************************************************
  416. uploadImageUrl: '/',
  417. // 查询用户的参数
  418. queryInfo: {
  419. // 试题类型下拉款所选的内容
  420. 'questionType': '',
  421. 'questionBank': '',
  422. 'questionContent': '',
  423. 'pageNo': 1,
  424. 'pageSize': 10
  425. },
  426. // 试题类型
  427. questionType: [
  428. {
  429. id: 1,
  430. name: '单选题'
  431. },
  432. {
  433. id: 2,
  434. name: '多选题'
  435. },
  436. {
  437. id: 3,
  438. name: '不定项选择题'
  439. },
  440. {
  441. id: 4,
  442. name: '判断题'
  443. },
  444. {
  445. id: 5,
  446. name: '填空题'
  447. },
  448. {
  449. id: 6,
  450. name: '问答题'
  451. },
  452. {
  453. id: 7,
  454. name: '理解题'
  455. },
  456. {
  457. id: 8,
  458. name: '組题'
  459. }
  460. ],
  461. // 题库信息
  462. allSubject: [],
  463. // 试题信息
  464. questionInfo: [],
  465. // 试题信息表格是否加载
  466. loading: true,
  467. // 表格被选中的所有行
  468. selectionTable: [],
  469. // 表格行被选中后的所有操作方式的数据
  470. optionInfo: [
  471. {
  472. 'label': '删除',
  473. 'desc': 'delete'
  474. },
  475. {
  476. 'label': '加入题库',
  477. 'desc': 'add'
  478. },
  479. {
  480. 'label': '题库中移除',
  481. 'desc': 'remove'
  482. }
  483. ],
  484. // 表格行被选中后的数据
  485. operation: '',
  486. // 试题总数
  487. total: 0,
  488. // 是否显示加入题库对话框
  489. addTableVisible: false,
  490. // 是否显示移除题库对话框
  491. removeTableVisible: false,
  492. // 是否显示添加试题的对话框
  493. addQuTableVisible: false,
  494. // 添加题库的表单信息
  495. addForm: {
  496. subjectId: ''
  497. },
  498. removeForm: {
  499. subjectId: ''
  500. },
  501. // 添加题库表单的验证
  502. addFormRules: {
  503. subjectId: [
  504. {
  505. required: true,
  506. message: '请选择需要添加进的题库',
  507. trigger: 'blur'
  508. }
  509. ]
  510. },
  511. // 移除题库表单的验证
  512. removeFormRules: {
  513. subjectId: [
  514. {
  515. required: true,
  516. message: '请选择需要移除的题库',
  517. trigger: 'blur'
  518. }
  519. ]
  520. },
  521. // 添加试题的表单信息
  522. addQuForm: {
  523. questionType: 1,
  524. questionLevel: 1,
  525. subjectId: '',
  526. questionContent: '',
  527. images: [],
  528. analysis: '',
  529. createPerson: localStorage.getItem('username'),
  530. // 答案对象
  531. options: [],
  532. children: []
  533. },
  534. questionForm: {
  535. questionType: 1,
  536. questionLevel: 1,
  537. subjectId: '',
  538. questionContent: '',
  539. images: [],
  540. analysis: '',
  541. // 答案对象
  542. options: []
  543. },
  544. // 添加试题表单的验证规则
  545. addQuFormRules: {
  546. questionType: [
  547. {
  548. required: true,
  549. message: '请选择问题类型',
  550. trigger: 'blur'
  551. }
  552. ],
  553. questionLevel: [
  554. {
  555. required: true,
  556. message: '请选择问题难度',
  557. trigger: 'blur'
  558. }
  559. ],
  560. subjectId: [
  561. {
  562. required: true,
  563. message: '请选择题库',
  564. trigger: 'blur'
  565. }
  566. ],
  567. questionContent: [
  568. {
  569. required: true,
  570. message: '请输入题库内容',
  571. trigger: 'blur'
  572. }
  573. ]
  574. },
  575. // 更新试题表单的验证规则
  576. updateQuFormRules: {
  577. questionType: [
  578. {
  579. required: true,
  580. message: '请选择问题类型',
  581. trigger: 'blur'
  582. }
  583. ],
  584. questionLevel: [
  585. {
  586. required: true,
  587. message: '请选择问题难度',
  588. trigger: 'blur'
  589. }
  590. ],
  591. subjectId: [
  592. {
  593. required: true,
  594. message: '请选择题库',
  595. trigger: 'blur'
  596. }
  597. ],
  598. questionContent: [
  599. {
  600. required: true,
  601. message: '请输入题库内容',
  602. trigger: 'blur'
  603. }
  604. ]
  605. },
  606. // 图片回显的样式
  607. backShowImgVisible: false,
  608. // 图片回显的图片地址
  609. backShowImgUrl: '',
  610. // 更新试题的数据信息
  611. updateQuForm: {
  612. questionId: '',
  613. questionType: 1,
  614. questionLevel: 1,
  615. subjectId: '',
  616. questionContent: '',
  617. images: [],
  618. analysis: '',
  619. createPerson: localStorage.getItem('username'),
  620. // 答案对象
  621. answer: []
  622. },
  623. // 是否显示更新试题的对话框
  624. updateQuTableVisible: false,
  625. questionDetailDialog: false,
  626. questionDetail: {}
  627. }
  628. },
  629. created() {
  630. document.title = '题库管理'
  631. this.getQuestionBankInfo()
  632. this.getData(this.searchForm)
  633. },
  634. methods: {
  635. getData(searchForm) {
  636. this.dataList = []
  637. getExamQuestion(this.currentPage).then(resp => {
  638. if (resp.code === 0) {
  639. this.dataList = resp.data.list
  640. this.totalSize = resp.data.totalSize
  641. } else {
  642. this.$notify({
  643. title: '提示',
  644. message: resp.msg,
  645. type: 'warning',
  646. duration: 3000
  647. })
  648. }
  649. }).catch(error => {
  650. this.$notify({
  651. title: '提示',
  652. message: error.message,
  653. type: 'error',
  654. duration: 3000
  655. })
  656. })
  657. },
  658. // 获取所有的题库信息
  659. getQuestionBankInfo() {
  660. getExamSubjectKV().then((resp) => {
  661. if (resp.code === 0) {
  662. this.allSubject = resp.data
  663. }
  664. })
  665. },
  666. // 试题类型变化
  667. typeChange(val) {
  668. this.queryInfo.questionType = val
  669. this.getQuestionInfo()
  670. },
  671. // 题库变化
  672. bankChange(val) {
  673. this.queryInfo.questionBank = val
  674. this.getQuestionInfo()
  675. },
  676. // 试题名字筛选
  677. contentChange() {
  678. // 发送查询试题总数的请求
  679. this.getQuestionInfo()
  680. },
  681. // 获取试题信息
  682. getQuestionInfo() {
  683. getQuestion(this.queryInfo).then((resp) => {
  684. if (resp.code === 0) {
  685. this.questionInfo = resp.data.data
  686. this.total = resp.data.total
  687. this.loading = false
  688. }
  689. })
  690. },
  691. // 处理表格被选中
  692. handleTableSectionChange(val) {
  693. this.selectionTable = val
  694. },
  695. // 处理操作选择框的变化
  696. operationChange(val) {
  697. // 清空上一次的选择
  698. this.operation = ''
  699. const questionIds = []
  700. if (val === 'delete') {
  701. this.selectionTable.map(item => {
  702. questionIds.push(item.id)
  703. })
  704. // 发起删除请求
  705. deleteQuestion({ 'questionIds': questionIds.join(',') }).then(resp => {
  706. if (resp.code === 0) {
  707. this.$notify({
  708. title: 'Tips',
  709. message: '删除成功',
  710. type: 'success',
  711. duration: 2000
  712. })
  713. this.getQuestionInfo()
  714. }
  715. })
  716. } else if (val === 'add') {
  717. this.addTableVisible = true
  718. } else if (val === 'remove') {
  719. this.removeTableVisible = true
  720. }
  721. },
  722. // 分页页面大小改变
  723. handleSizeChange(val) {
  724. this.queryInfo.pageSize = val
  725. this.getQuestionInfo()
  726. },
  727. // 分页插件的页数
  728. handleCurrentChange(val) {
  729. this.queryInfo.pageNo = val
  730. this.getQuestionInfo()
  731. },
  732. // 表单信息重置
  733. resetAddForm() {
  734. // 清空表格数据
  735. this.$refs['addForm'].resetFields()
  736. },
  737. resetRemoveForm() {
  738. // 清空表格数据
  739. this.$refs['removeForm'].resetFields()
  740. },
  741. resetAddQuForm() {
  742. this.$refs['addQuForm'].resetFields()
  743. },
  744. // 提交加入题库的表单信息
  745. addBank() {
  746. validFormAndInvoke(this.$refs['addForm'], () => {
  747. const questionIds = []
  748. const banks = this.addForm.subjectId
  749. // 将表格选中的数据中的问题id加入进去
  750. this.selectionTable.map(item => {
  751. questionIds.push(item.id)
  752. })
  753. questionBank.addBankQuestion({
  754. 'questionIds': questionIds.join(','),
  755. 'banks': banks.join(',')
  756. }).then((resp) => {
  757. if (resp.code === 0) {
  758. this.getQuestionInfo()
  759. this.$notify({
  760. title: 'Tips',
  761. message: resp.message,
  762. type: 'success',
  763. duration: 2000
  764. })
  765. }
  766. this.addTableVisible = false
  767. })
  768. }, '请选择需要加入进的题库')
  769. },
  770. // 提交移除题库的表单信息
  771. removeBank() {
  772. validFormAndInvoke(this.$refs['removeForm'], () => {
  773. const questionIds = []
  774. const banks = this.removeForm.subjectId
  775. // 将表格选中的数据中的问题id加入进去
  776. this.selectionTable.map(item => {
  777. questionIds.push(item.id)
  778. })
  779. // 发起移除请求
  780. questionBank.removeBankQuestion({
  781. 'questionIds': questionIds.join(','),
  782. 'banks': banks.join(',')
  783. }).then((resp) => {
  784. if (resp.code === 0) {
  785. this.getQuestionInfo()
  786. this.$notify({
  787. title: 'Tips',
  788. message: resp.message,
  789. type: 'success',
  790. duration: 2000
  791. })
  792. }
  793. this.removeTableVisible = false
  794. })
  795. }, '请选择需要移除的题库')
  796. },
  797. // 新增试题上传后 点击图片的回显
  798. uploadPreview(file) {
  799. this.backShowImgUrl = file.response.data
  800. this.backShowImgVisible = true
  801. },
  802. // 新增试题中的上传图片的移除
  803. handleRemove(file, fileList) {
  804. this.addQuForm.images.map((item, index) => { // 移除图片在表单中的数据
  805. if (item === file.response.data) this.addQuForm.images.splice(index, 1)
  806. })
  807. },
  808. // 更新试题中的上传图片的移除
  809. handleUpdateRemove(file, fileList) {
  810. this.updateQuForm.images.map((item, index) => { // 移除图片在表单中的数据
  811. if (item === file.response.data) this.updateQuForm.images.splice(index, 1)
  812. })
  813. },
  814. // 新增试题中的上传图片的格式大小限制
  815. beforeAvatarUpload(file) {
  816. const isImg = file.type === 'image/jpeg' ||
  817. file.type === 'image/png' ||
  818. file.type === 'image/jpg'
  819. const isLt = file.size / 1024 / 1024 < 10
  820. if (!isImg) {
  821. this.$message.error('上传图片只能是 JPG/PNG 格式!')
  822. }
  823. if (!isLt) {
  824. this.$message.error('上传头像图片大小不能超过 10MB!')
  825. }
  826. return isImg && isLt
  827. },
  828. // 新增试题中的上传图片成功后的钩子函数
  829. uploadImgSuccess(response, file, fileList) {
  830. this.addQuForm.images.push(response.data)
  831. },
  832. // 更新试题中的上传图片成功后的钩子函数
  833. updateUploadImgSuccess(response, file, fileList) {
  834. this.updateQuForm.images.push(response.data)
  835. },
  836. // 新增试题中的新增答案填写框
  837. addAnswer() {
  838. this.addQuForm.options.push({
  839. id: this.addQuForm.options.length,
  840. correct: false,
  841. content: '',
  842. images: [],
  843. analysis: ''
  844. })
  845. },
  846. // 更新时新增试题中的新增答案填写框
  847. addUpdateAnswer() {
  848. this.updateQuForm.answer.push({
  849. id: this.updateQuForm.answer.length,
  850. correct: false,
  851. answer: '',
  852. images: [],
  853. analysis: ''
  854. })
  855. },
  856. // 新增试题中的删除答案填写框
  857. delAnswer(id) { // 当前答案的id
  858. this.addQuForm.options.map((item, index) => {
  859. if (item.id === id) this.addQuForm.options.splice(index, 1)
  860. })
  861. },
  862. // 新增试题中的删除答案填写框
  863. delUpdateAnswer(id) { // 当前答案的id
  864. this.updateQuForm.answer.map((item, index) => {
  865. if (item.id === id) this.updateQuForm.answer.splice(index, 1)
  866. })
  867. },
  868. // 答案上传照片了
  869. uploadAnswerImgSuccess(response, id) {
  870. this.addQuForm.options[id].images.push(response.data)
  871. },
  872. // 更新的答案上传图片了
  873. uploadUpdateAnswerImgSuccess(response, id) {
  874. this.updateQuForm.answer[id].images.push(response.data)
  875. },
  876. // 答案上传成功后删除
  877. handleAnswerRemove(file) {
  878. this.addQuForm.options.images.map((item, index) => { // 移除图片在表单中的数据
  879. if (item === file.response.data) this.addQuForm.images.splice(index, 1)
  880. })
  881. },
  882. // 更新的时候答案上传成功后删除
  883. handleUpdateAnswerRemove(file) {
  884. this.updateQuForm.answer.images.map((item, index) => { // 移除图片在表单中的数据
  885. if (item === file.response.data) this.updateQuForm.images.splice(index, 1)
  886. })
  887. },
  888. // 选择正确答案的按钮变化事件
  889. checkAnswer(checked, id) {
  890. if (checked) {
  891. if (this.addQuForm.questionType === 1 || this.addQuForm.questionType === 3) { // 单选或者判断
  892. // 当前已经有一个正确的选择了
  893. this.addQuForm.options.map(item => {
  894. item.correct = false
  895. })
  896. this.addQuForm.options.map(item => {
  897. if (item.id === id) item.correct = true
  898. })
  899. } else { // 多选 可以有多个答案
  900. this.addQuForm.options.map(item => {
  901. if (item.id === id) item.correct = true
  902. })
  903. }
  904. } else {
  905. this.addQuForm.options.map(item => {
  906. if (item.id === id) item.correct = false
  907. })
  908. }
  909. },
  910. // 更新时选择正确答案的按钮变化事件
  911. checkUpdateAnswer(checked, id) {
  912. if (checked) {
  913. if (this.updateQuForm.questionType === 1 || this.updateQuForm.questionType === 3) { // 单选或者判断
  914. // 当前已经有一个正确的选择了
  915. this.updateQuForm.answer.map(item => {
  916. item.correct = false
  917. })
  918. this.updateQuForm.answer.map(item => {
  919. if (item.id === id) item.correct = true
  920. })
  921. } else { // 多选 可以有多个答案
  922. this.updateQuForm.answer.map(item => {
  923. if (item.id === id) item.correct = true
  924. })
  925. }
  926. } else {
  927. this.updateQuForm.answer.map(item => {
  928. if (item.id === id) item.correct = false
  929. })
  930. }
  931. },
  932. // 新增试题
  933. addQuestion() {
  934. this.$refs['addQuForm'].validate((valid) => {
  935. if (valid && this.addQuForm.options.some(item => item.correct) && this.addQuForm.questionType !== 4) { // 单选或者多选或者判断
  936. postExamQuestion(this.addQuForm).then((resp) => {
  937. if (resp.code === 0) {
  938. this.addQuTableVisible = false
  939. this.getData(this.searchForm)
  940. this.$notify({
  941. title: 'Tips',
  942. message: '新增试题成功',
  943. type: 'success',
  944. duration: 2000
  945. })
  946. }
  947. })
  948. } else if (valid && !this.addQuForm.options.some(item => item.correct) && this.addQuForm.questionType < 5) { // 无答案
  949. this.$message.error('必须有一个答案')
  950. return false
  951. } else if (valid && this.addQuForm.questionType >= 5 && this.addQuForm.questionType <= 7) { // 简答题 无标准答案直接发请求
  952. // 当是简答题的时候需要清除answer
  953. this.addQuForm.options = []
  954. postExamQuestion(this.addQuForm).then((resp) => {
  955. if (resp.code === 0) {
  956. this.addQuTableVisible = false
  957. this.getQuestionInfo()
  958. this.$notify({
  959. title: 'Tips',
  960. message: '新增试题成功',
  961. type: 'success',
  962. duration: 2000
  963. })
  964. }
  965. })
  966. } else if (this.addQuForm.questionType > 7) { // 組题
  967. // 当是简答题的时候需要清除answer
  968. this.addQuForm.options = []
  969. postExamQuestion(this.addQuForm).then((resp) => {
  970. if (resp.code === 0) {
  971. this.addQuTableVisible = false
  972. this.getQuestionInfo()
  973. this.$notify({
  974. title: 'Tips',
  975. message: '新增试题成功',
  976. type: 'success',
  977. duration: 2000
  978. })
  979. }
  980. })
  981. } else if (!valid) {
  982. this.$message.error('请填写必要信息')
  983. return false
  984. }
  985. })
  986. },
  987. // 更新试题
  988. updateQu(id) {
  989. getQuestionById(id).then((resp) => {
  990. if (resp.code === 0) {
  991. if (resp.data.questionType !== 4) {
  992. resp.data.answer.map(item => {
  993. item.correct = item.correct === 'true'
  994. })
  995. }
  996. this.updateQuForm = resp.data
  997. // 处理图片那个参数是个数组
  998. if (this.updateQuForm.images === null) this.updateQuForm.images = []
  999. if (resp.data.questionType !== 4) {
  1000. this.updateQuForm.answer.map(item => {
  1001. if (item.images === null) {
  1002. item.images = []
  1003. }
  1004. })
  1005. }
  1006. }
  1007. })
  1008. this.updateQuTableVisible = true
  1009. },
  1010. // 提交更新表单
  1011. updateQuestion() {
  1012. this.$refs['updateQuForm'].validate((valid) => {
  1013. if (valid && this.updateQuForm.questionType !== 4 && this.updateQuForm.answer.some(item => item.correct)) { // 单选或者多选或者判断
  1014. // 保证答案的图片只有一张
  1015. this.updateQuForm.answer.map(item => {
  1016. if (item.images.length > 1) {
  1017. item.images.splice(0, item.images.length - 1)
  1018. }
  1019. })
  1020. updateQuestion(this.updateQuForm).then((resp) => {
  1021. if (resp.code === 0) {
  1022. this.updateQuTableVisible = false
  1023. this.getQuestionInfo()
  1024. this.$notify({
  1025. title: 'Tips',
  1026. message: '更新试题成功',
  1027. type: 'success',
  1028. duration: 2000
  1029. })
  1030. }
  1031. })
  1032. } else if (valid && this.updateQuForm.questionType !== 4 && !this.updateQuForm.answer.some(item => item.correct)) { // 无答案
  1033. this.$message.error('必须有一个答案')
  1034. return false
  1035. } else if (valid && this.updateQuForm.questionType === 4) { // 简答题 无标准答案直接发请求
  1036. // 当是简答题的时候需要清除answer
  1037. this.addQuForm.options = []
  1038. updateQuestion(this.updateQuForm).then((resp) => {
  1039. if (resp.code === 0) {
  1040. this.updateQuTableVisible = false
  1041. this.getQuestionInfo()
  1042. this.$notify({
  1043. title: 'Tips',
  1044. message: '更新试题成功',
  1045. type: 'success',
  1046. duration: 2000
  1047. })
  1048. }
  1049. })
  1050. } else if (!valid) {
  1051. this.$message.error('请填写必要信息')
  1052. return false
  1053. }
  1054. })
  1055. },
  1056. viewDetail(questionId) {
  1057. getExamQuestion1(questionId).then(resp => {
  1058. if (resp.code === 0) {
  1059. this.questionDetail = resp.data
  1060. this.questionDetailDialog = true
  1061. } else {
  1062. this.$notify({
  1063. title: 'Tips',
  1064. message: resp.msg,
  1065. type: 'success',
  1066. duration: 2000
  1067. })
  1068. }
  1069. })
  1070. },
  1071. onDeleteQuestion(questionId) {
  1072. deleteExamQuestion(questionId).then(resp => {
  1073. if (resp.code === 0) {
  1074. this.$notify({
  1075. title: 'Tips',
  1076. message: '试题 ' + questionId + ' 已删除',
  1077. type: 'success',
  1078. duration: 1000
  1079. })
  1080. window.location.reload()
  1081. } else {
  1082. this.$notify({
  1083. title: 'Error',
  1084. message: resp.msg,
  1085. type: 'error',
  1086. duration: 1000
  1087. })
  1088. }
  1089. })
  1090. }
  1091. }
  1092. }
  1093. </script>
  1094. <style>
  1095. </style>