onlineExam.vue 41 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193
  1. <template>
  2. <div>
  3. <LinkTitlesCustom
  4. :currentPaths="['考试管理', '考试信息', '网络考试设置']"
  5. />
  6. <section class="content">
  7. <div class="box box-info">
  8. <!-- 正文信息 -->
  9. <div class="box-body">
  10. <el-form
  11. :inline="true"
  12. :rules="rules"
  13. ref="form"
  14. :model="form"
  15. inline-message
  16. label-position="right"
  17. >
  18. <div style="margin-bottom: 10px;">
  19. <el-button type="primary" size="small" @click="saveExam"
  20. >保 存</el-button
  21. >
  22. <el-button
  23. type="primary"
  24. size="small"
  25. @click="back"
  26. icon="el-icon-arrow-left"
  27. >返 回</el-button
  28. >
  29. </div>
  30. <el-tabs type="border-card" v-model="activeName">
  31. <!-- 基础信息 -->
  32. <el-tab-pane label="基础信息" name="tab1">
  33. <el-row v-if="examId != 'add'">
  34. <el-form-item
  35. label="ID"
  36. prop="id"
  37. :label-width="style.label_width_tab1"
  38. >
  39. <el-input
  40. v-model="form.id"
  41. class="input"
  42. :disabled="true"
  43. maxlength="20"
  44. ></el-input>
  45. </el-form-item>
  46. </el-row>
  47. <el-row v-if="examId != 'add'">
  48. <el-form-item
  49. label="考试编码"
  50. placeholder="请输入考试编码"
  51. prop="code"
  52. :label-width="style.label_width_tab1"
  53. >
  54. <el-input
  55. v-model="form.code"
  56. class="input"
  57. :disabled="true"
  58. maxlength="20"
  59. ></el-input>
  60. </el-form-item>
  61. </el-row>
  62. <el-row v-else>
  63. <el-form-item
  64. label="考试编码"
  65. placeholder="请输入考试编码"
  66. prop="code"
  67. :label-width="style.label_width_tab1"
  68. >
  69. <el-input
  70. v-model="form.name"
  71. class="input"
  72. :disabled="true"
  73. maxlength="20"
  74. ></el-input>
  75. </el-form-item>
  76. </el-row>
  77. <el-row>
  78. <el-form-item
  79. label="考试名称"
  80. placeholder="请输入考试名称"
  81. prop="name"
  82. :label-width="style.label_width_tab1"
  83. >
  84. <el-input
  85. v-model="form.name"
  86. class="input"
  87. maxlength="20"
  88. ></el-input>
  89. </el-form-item>
  90. </el-row>
  91. <el-row>
  92. <el-form-item
  93. label="考试类型"
  94. :label-width="style.label_width_tab1"
  95. >
  96. <el-select
  97. class="input"
  98. :disabled="true"
  99. v-model="form.examType"
  100. placeholder="请选择"
  101. >
  102. <el-option
  103. v-for="item in examTypeList"
  104. :key="item.value"
  105. :label="item.label"
  106. :value="item.value"
  107. ></el-option>
  108. </el-select>
  109. </el-form-item>
  110. </el-row>
  111. <el-row>
  112. <el-form-item
  113. label="状态"
  114. :label-width="style.label_width_tab1"
  115. >
  116. <el-radio-group v-model="form.enable" class="input">
  117. <el-radio label="true">启用</el-radio>
  118. <el-radio label="false">禁用</el-radio>
  119. </el-radio-group>
  120. </el-form-item>
  121. </el-row>
  122. <el-row v-if="1 == 2">
  123. <el-form-item
  124. label="是否可以考试"
  125. :label-width="style.label_width_tab1"
  126. >
  127. <el-radio-group v-model="form.examLimit" class="input">
  128. <el-radio label="true">否</el-radio>
  129. <el-radio label="false">是</el-radio>
  130. </el-radio-group>
  131. </el-form-item>
  132. </el-row>
  133. <el-row>
  134. <el-form-item
  135. label="考试时间"
  136. prop="examDatetimeRange"
  137. :label-width="style.label_width_tab1"
  138. >
  139. <el-date-picker
  140. class="input"
  141. v-model="examDatetimeRange"
  142. type="datetimerange"
  143. range-separator="至"
  144. start-placeholder="开始日期"
  145. end-placeholder="结束日期"
  146. value-format="yyyy-MM-dd HH:mm:ss"
  147. :clearable="false"
  148. ></el-date-picker>
  149. </el-form-item>
  150. </el-row>
  151. <el-row>
  152. <el-form-item
  153. label="开启环境检测"
  154. :label-width="style.label_width_tab1"
  155. >
  156. <el-switch
  157. v-model="form.properties.CHECK_ENVIRONMENT"
  158. on-text="是"
  159. off-text="否"
  160. ></el-switch>
  161. </el-form-item>
  162. </el-row>
  163. </el-tab-pane>
  164. <!-- 控制设置 -->
  165. <el-tab-pane label="控制设置" name="tab2">
  166. <el-row>
  167. <el-form-item
  168. label="考试时长"
  169. prop="duration"
  170. :label-width="style.label_width_tab2"
  171. >
  172. <el-input
  173. maxlength="5"
  174. v-model.trim.number="form.duration"
  175. auto-complete="off"
  176. class="input"
  177. >
  178. <template slot="append"
  179. >分钟</template
  180. >
  181. </el-input>
  182. </el-form-item>
  183. </el-row>
  184. <el-row>
  185. <el-form-item
  186. label="考试次数"
  187. prop="examTimes"
  188. :label-width="style.label_width_tab2"
  189. >
  190. <el-input
  191. maxlength="5"
  192. v-model.trim.number="form.examTimes"
  193. auto-complete="off"
  194. class="input"
  195. >
  196. <template slot="append"
  197. >次</template
  198. >
  199. </el-input>
  200. </el-form-item>
  201. </el-row>
  202. <el-row>
  203. <el-form-item
  204. label="交卷冻结时间"
  205. prop="FREEZE_TIME"
  206. :label-width="style.label_width_tab2"
  207. >
  208. <el-input
  209. maxlength="5"
  210. v-model.trim.number="form.properties.FREEZE_TIME"
  211. auto-complete="off"
  212. class="input"
  213. >
  214. <template slot="append"
  215. >分钟</template
  216. >
  217. </el-input>
  218. </el-form-item>
  219. </el-row>
  220. <el-row>
  221. <el-form-item
  222. label="断点续考时间"
  223. prop="EXAM_RECONNECT_TIME"
  224. :label-width="style.label_width_tab2"
  225. >
  226. <el-input
  227. maxlength="5"
  228. v-model.trim.number="form.properties.EXAM_RECONNECT_TIME"
  229. auto-complete="off"
  230. class="input"
  231. >
  232. <template slot="append"
  233. >分钟</template
  234. >
  235. </el-input>
  236. </el-form-item>
  237. </el-row>
  238. <el-row>
  239. <el-form-item
  240. label="断点续考次数"
  241. prop="MAX_INTERRUPT_NUM"
  242. :label-width="style.label_width_tab2"
  243. >
  244. <el-input
  245. maxlength="5"
  246. v-model.trim.number="form.properties.MAX_INTERRUPT_NUM"
  247. auto-complete="off"
  248. class="input"
  249. >
  250. <template slot="append"
  251. >次</template
  252. >
  253. </el-input>
  254. </el-form-item>
  255. </el-row>
  256. </el-tab-pane>
  257. <el-tab-pane label="显示设置" name="tab3">
  258. <el-row v-if="show_ckeditor">
  259. <el-form-item
  260. label="考前说明"
  261. :label-width="style.label_width_tab3"
  262. >
  263. <ckeditor
  264. v-model="form.properties.BEFORE_EXAM_REMARK"
  265. ></ckeditor>
  266. </el-form-item>
  267. </el-row>
  268. <el-row v-if="show_ckeditor">
  269. <el-form-item
  270. label="考后说明"
  271. :label-width="style.label_width_tab3"
  272. >
  273. <ckeditor
  274. v-model="form.properties.AFTER_EXAM_REMARK"
  275. ></ckeditor>
  276. </el-form-item>
  277. </el-row>
  278. <el-row>
  279. <el-form-item
  280. label="展示作弊说明"
  281. :label-width="style.label_width_tab3"
  282. >
  283. <el-radio-group
  284. v-model="form.properties.SHOW_CHEATING_REMARK"
  285. class="input"
  286. >
  287. <el-radio label="true">开启</el-radio>
  288. <el-radio label="false">关闭</el-radio>
  289. </el-radio-group>
  290. </el-form-item>
  291. </el-row>
  292. <el-row v-if="show_ckeditor">
  293. <el-form-item
  294. label="作弊说明"
  295. :label-width="style.label_width_tab3"
  296. >
  297. <ckeditor
  298. v-model="form.properties.CHEATING_REMARK"
  299. ></ckeditor>
  300. </el-form-item>
  301. </el-row>
  302. <el-row>
  303. <el-form-item
  304. label="单选题补充说明"
  305. :label-width="style.label_width_tab3"
  306. >
  307. <el-input
  308. maxlength="20"
  309. :disabled="!form.properties.SINGLE_EDIT"
  310. v-model="form.properties.SINGLE_ANSWER_REMARK"
  311. auto-complete="off"
  312. class="input"
  313. ></el-input>
  314. </el-form-item>
  315. <el-form-item label>
  316. <el-switch
  317. v-model="form.properties.SINGLE_EDIT"
  318. on-text="启用"
  319. off-text="禁用"
  320. ></el-switch>
  321. </el-form-item>
  322. </el-row>
  323. <el-row>
  324. <el-form-item
  325. label="多选题补充说明"
  326. :label-width="style.label_width_tab3"
  327. >
  328. <el-input
  329. maxlength="20"
  330. :disabled="!form.properties.MUTIPLE_EDIT"
  331. v-model="form.properties.MUTIPLE_ANSWER_REMARK"
  332. auto-complete="off"
  333. class="input"
  334. ></el-input>
  335. </el-form-item>
  336. <el-form-item label>
  337. <el-switch
  338. v-model="form.properties.MUTIPLE_EDIT"
  339. on-text="启用"
  340. off-text="禁用"
  341. ></el-switch>
  342. </el-form-item>
  343. </el-row>
  344. <el-row>
  345. <el-form-item
  346. label="判断题补充说明"
  347. :label-width="style.label_width_tab3"
  348. >
  349. <el-input
  350. maxlength="20"
  351. :disabled="!form.properties.BOOL_EDIT"
  352. v-model="form.properties.BOOL_ANSWER_REMARK"
  353. class="input"
  354. auto-complete="off"
  355. ></el-input>
  356. </el-form-item>
  357. <el-form-item label>
  358. <el-switch
  359. v-model="form.properties.BOOL_EDIT"
  360. on-text="启用"
  361. off-text="禁用"
  362. ></el-switch>
  363. </el-form-item>
  364. </el-row>
  365. <el-row>
  366. <el-form-item
  367. label="填空题补充说明"
  368. :label-width="style.label_width_tab3"
  369. >
  370. <el-input
  371. maxlength="20"
  372. :disabled="!form.properties.FILL_BLANK_EDIT"
  373. v-model="form.properties.FILL_BLANK_REMARK"
  374. class="input"
  375. auto-complete="off"
  376. ></el-input>
  377. </el-form-item>
  378. <el-form-item label>
  379. <el-switch
  380. v-model="form.properties.FILL_BLANK_EDIT"
  381. on-text="启用"
  382. off-text="禁用"
  383. ></el-switch>
  384. </el-form-item>
  385. </el-row>
  386. <el-row>
  387. <el-form-item
  388. label="客观题成绩显示"
  389. :label-width="style.label_width_tab3"
  390. >
  391. <el-radio-group
  392. v-model="form.properties.IS_OBJ_SCORE_VIEW"
  393. class="input"
  394. >
  395. <el-radio label="true">开启</el-radio>
  396. <el-radio label="false">关闭</el-radio>
  397. </el-radio-group>
  398. </el-form-item>
  399. </el-row>
  400. </el-tab-pane>
  401. <el-tab-pane label="身份检测设置" name="tab4">
  402. <el-row>
  403. <el-form-item
  404. label="开启身份检测"
  405. :label-width="style.label_width_tab4"
  406. >
  407. <el-radio-group
  408. @change="faceEnableChange"
  409. v-model="form.properties.IS_FACE_ENABLE"
  410. :disabled="this.is_face_enable_diabled"
  411. class="input"
  412. >
  413. <el-radio label="true">是</el-radio>
  414. <el-radio label="false">否</el-radio>
  415. </el-radio-group>
  416. </el-form-item>
  417. </el-row>
  418. <el-row>
  419. <el-form-item
  420. label="启用陌生人检测"
  421. prop="IS_STRANGER_ENABLE"
  422. :label-width="style.label_width_tab4"
  423. v-show="form.properties.IS_FACE_ENABLE == 'true'"
  424. >
  425. <el-radio-group
  426. v-model="form.properties.IS_STRANGER_ENABLE"
  427. class="input"
  428. >
  429. <el-radio label="true">是</el-radio>
  430. <el-radio label="false">否</el-radio>
  431. </el-radio-group>
  432. </el-form-item>
  433. </el-row>
  434. <el-row v-show="form.properties.IS_FACE_ENABLE == 'true'">
  435. <el-form-item
  436. label="考试强制使用"
  437. :label-width="style.label_width_tab4"
  438. >
  439. <el-radio-group
  440. v-model="form.properties.IS_FACE_CHECK"
  441. class="input"
  442. >
  443. <el-radio label="true">强制</el-radio>
  444. <el-radio label="false">非强制</el-radio>
  445. </el-radio-group>
  446. </el-form-item>
  447. </el-row>
  448. <el-row v-show="form.properties.IS_FACE_ENABLE == 'true'">
  449. <el-form-item
  450. label="抓拍间隔"
  451. prop="SNAPSHOT_INTERVAL"
  452. :label-width="style.label_width_tab4"
  453. >
  454. <el-input
  455. maxlength="5"
  456. v-model.trim.number="form.properties.SNAPSHOT_INTERVAL"
  457. auto-complete="off"
  458. class="input"
  459. >
  460. <template slot="append"
  461. >分钟</template
  462. >
  463. </el-input>
  464. </el-form-item>
  465. </el-row>
  466. <el-row v-show="form.properties.IS_FACE_ENABLE == 'true'">
  467. <el-form-item
  468. label="预警阀值"
  469. prop="WARN_THRESHOLD"
  470. :label-width="style.label_width_tab4"
  471. >
  472. <el-input
  473. maxlength="5"
  474. v-model="form.properties.WARN_THRESHOLD"
  475. auto-complete="off"
  476. class="input"
  477. >
  478. <template slot="append"
  479. >%</template
  480. >
  481. </el-input>
  482. </el-form-item>
  483. </el-row>
  484. <el-row v-show="form.properties.IS_FACE_ENABLE == 'true'">
  485. <el-form-item
  486. label="真实性预警阀值"
  487. prop="LIVING_WARN_THRESHOLD"
  488. :label-width="style.label_width_tab4"
  489. >
  490. <el-input
  491. maxlength="5"
  492. v-model="form.properties.LIVING_WARN_THRESHOLD"
  493. auto-complete="off"
  494. class="input"
  495. >
  496. <template slot="append"
  497. >%</template
  498. >
  499. </el-input>
  500. </el-form-item>
  501. </el-row>
  502. <el-row v-show="form.properties.IS_FACE_ENABLE == 'true'">
  503. <el-form-item
  504. label="开启人脸活体检测"
  505. :label-width="style.label_width_tab4"
  506. >
  507. <el-radio-group
  508. v-model="form.properties.IS_FACE_VERIFY"
  509. :disabled="this.is_face_verify_diabled"
  510. class="input"
  511. >
  512. <el-radio label="true">是</el-radio>
  513. <el-radio label="false">否</el-radio>
  514. </el-radio-group>
  515. </el-form-item>
  516. </el-row>
  517. <el-row v-show="form.properties.IS_FACE_VERIFY == 'true'">
  518. <el-form-item
  519. label="人脸活体检测开始时间"
  520. prop="FACE_VERIFY_START_MINUTE"
  521. :label-width="style.label_width_tab4"
  522. >
  523. <el-input
  524. maxlength="5"
  525. v-model.trim.number="
  526. form.properties.FACE_VERIFY_START_MINUTE
  527. "
  528. auto-complete="off"
  529. class="input"
  530. >
  531. <template slot="append"
  532. >分钟</template
  533. >
  534. </el-input>
  535. </el-form-item>
  536. </el-row>
  537. <el-row v-show="form.properties.IS_FACE_VERIFY == 'true'">
  538. <el-form-item
  539. label="人脸活体检测结束时间"
  540. prop="FACE_VERIFY_END_MINUTE"
  541. :label-width="style.label_width_tab4"
  542. >
  543. <el-input
  544. maxlength="5"
  545. v-model.trim.number="
  546. form.properties.FACE_VERIFY_END_MINUTE
  547. "
  548. auto-complete="off"
  549. class="input"
  550. >
  551. <template slot="append"
  552. >分钟</template
  553. >
  554. </el-input>
  555. </el-form-item>
  556. </el-row>
  557. </el-tab-pane>
  558. <el-tab-pane label="阅卷设置" name="tab5">
  559. <el-row>
  560. <el-form-item
  561. label="阅卷方式"
  562. :label-width="style.label_width_tab5"
  563. >
  564. <el-radio-group
  565. :disabled="form.started"
  566. v-model="form.properties.MARKING_TYPE"
  567. class="input"
  568. >
  569. <el-radio label="ALL">全部评阅</el-radio>
  570. <el-radio label="OBJECT_SCORE_MAX">客观分最高</el-radio>
  571. <el-radio label="LAST_SUBMIT">最后一次提交</el-radio>
  572. </el-radio-group>
  573. </el-form-item>
  574. </el-row>
  575. </el-tab-pane>
  576. <el-tab-pane label="网络设置" name="tab6">
  577. <el-row>
  578. <el-form-item
  579. label="IP限制"
  580. :label-width="style.label_width_tab6"
  581. >
  582. <el-radio-group v-model="form.properties.IP_LIMIT">
  583. <el-radio label="true">开启</el-radio>
  584. <el-radio label="false">关闭</el-radio>
  585. </el-radio-group>
  586. </el-form-item>
  587. </el-row>
  588. <el-row>
  589. <el-form-item
  590. label="IP段( *表示任意 )"
  591. :label-width="style.label_width_tab6"
  592. >
  593. <el-input
  594. maxlength="2000"
  595. v-model="form.properties.IP_ADDRESSES"
  596. class="input"
  597. type="textarea"
  598. rows="6"
  599. ></el-input>
  600. </el-form-item>
  601. </el-row>
  602. </el-tab-pane>
  603. <el-tab-pane label="其它" name="tab7">
  604. <el-row>
  605. <el-form-item
  606. label="是否推送成绩"
  607. :label-width="style.label_width_tab7"
  608. >
  609. <el-radio-group v-model="form.properties.PUSH_SCORE">
  610. <el-radio label="true">是</el-radio>
  611. <el-radio label="false">否</el-radio>
  612. </el-radio-group>
  613. </el-form-item>
  614. </el-row>
  615. </el-tab-pane>
  616. </el-tabs>
  617. </el-form>
  618. </div>
  619. </div>
  620. </section>
  621. </div>
  622. </template>
  623. <script>
  624. import { EXAM_TYPE, EXAM_WORK_API, CORE_API } from "@/constants/constants.js";
  625. import moment from "moment";
  626. import ckeditor from "@/components/ckeditor.vue";
  627. import LinkTitlesCustom from "@/components/LinkTitlesCustom.vue";
  628. let _this = null;
  629. let validateCode = (rule, value, callback) => {
  630. if (_this.examId == "add") {
  631. _this.form.code = _this.form.name;
  632. }
  633. let code = _this.form.code;
  634. if (code == "") {
  635. callback(new Error("请输入考试编码"));
  636. if (!_this.toActiveName) {
  637. _this.toActiveName = "tab1";
  638. _this.activeName = "tab1";
  639. }
  640. } else {
  641. callback();
  642. }
  643. };
  644. let validateName = (rule, value, callback) => {
  645. let name = _this.form.name;
  646. if (name == "") {
  647. callback(new Error("请输入考试名称"));
  648. if (!_this.toActiveName) {
  649. _this.toActiveName = "tab1";
  650. _this.activeName = "tab1";
  651. }
  652. } else {
  653. callback();
  654. }
  655. };
  656. let validateExamDatetimeRange = (rule, value, callback) => {
  657. let examDatetimeRange = _this.examDatetimeRange;
  658. if (!examDatetimeRange) {
  659. callback(new Error("请输入考试时间"));
  660. if (!_this.toActiveName) {
  661. _this.toActiveName = "tab1";
  662. _this.activeName = "tab1";
  663. }
  664. } else {
  665. callback();
  666. }
  667. };
  668. let validateDuration = (rule, value, callback) => {
  669. let duration = _this.form.duration;
  670. if (duration === "") {
  671. callback(new Error("请输入考试时长"));
  672. if (!_this.toActiveName) {
  673. _this.toActiveName = "tab2";
  674. _this.activeName = "tab2";
  675. }
  676. } else if (!duration.toString().match(/^[1-9]\d*|0$/)) {
  677. callback(new Error("只能是非负整数"));
  678. if (!_this.toActiveName) {
  679. _this.toActiveName = "tab2";
  680. _this.activeName = "tab2";
  681. }
  682. } else {
  683. callback();
  684. }
  685. };
  686. let validateExamTimes = (rule, value, callback) => {
  687. let examTimes = _this.form.examTimes;
  688. if (examTimes === "") {
  689. callback(new Error("请输入考试次数"));
  690. if (!_this.toActiveName) {
  691. _this.toActiveName = "tab2";
  692. _this.activeName = "tab2";
  693. }
  694. } else if (!examTimes.toString().match(/^[1-9]\d*$/)) {
  695. callback(new Error("只能是正整数"));
  696. if (!_this.toActiveName) {
  697. _this.toActiveName = "tab2";
  698. _this.activeName = "tab2";
  699. }
  700. } else {
  701. callback();
  702. }
  703. };
  704. let validateFreezeTime = (rule, value, callback) => {
  705. let freezeTime = _this.form.properties.FREEZE_TIME;
  706. let duration = _this.form.duration;
  707. if (freezeTime === "") {
  708. callback(new Error("请输入交卷冻结时长"));
  709. if (!_this.toActiveName) {
  710. _this.toActiveName = "tab2";
  711. _this.activeName = "tab2";
  712. }
  713. } else if (!freezeTime.toString().match(/^[1-9]\d*|0$/)) {
  714. callback(new Error("只能是非负整数"));
  715. if (!_this.toActiveName) {
  716. _this.toActiveName = "tab2";
  717. _this.activeName = "tab2";
  718. }
  719. } else if (duration != "" && parseInt(freezeTime) > parseInt(duration)) {
  720. callback(new Error("交卷冻结时长不能大于考试时长"));
  721. if (!_this.toActiveName) {
  722. _this.toActiveName = "tab2";
  723. _this.activeName = "tab2";
  724. }
  725. } else {
  726. callback();
  727. }
  728. };
  729. let validateExamReconnectTime = (rule, value, callback) => {
  730. let examReconnectTime = _this.form.properties.EXAM_RECONNECT_TIME;
  731. if (examReconnectTime === "") {
  732. callback(new Error("请输入断点续考时间"));
  733. if (!_this.toActiveName) {
  734. _this.toActiveName = "tab2";
  735. _this.activeName = "tab2";
  736. }
  737. } else if (!examReconnectTime.toString().match(/^[1-9]\d*$/)) {
  738. callback(new Error("只能是正整数"));
  739. if (!_this.toActiveName) {
  740. _this.toActiveName = "tab2";
  741. _this.activeName = "tab2";
  742. }
  743. } else {
  744. callback();
  745. }
  746. };
  747. let validateMaxInterruptNum = (rule, value, callback) => {
  748. let examReconnectTime = _this.form.properties.MAX_INTERRUPT_NUM;
  749. if (examReconnectTime === "") {
  750. callback();
  751. } else if (!examReconnectTime.toString().match(/^[0-9]\d*$/)) {
  752. callback(new Error("只能是非负整数"));
  753. if (!_this.toActiveName) {
  754. _this.toActiveName = "tab2";
  755. _this.activeName = "tab2";
  756. }
  757. } else {
  758. callback();
  759. }
  760. };
  761. let validateSnapshotInterval = (rule, value, callback) => {
  762. let isFaceEnable = _this.form.properties.IS_FACE_ENABLE;
  763. let snapshotnterval = _this.form.properties.SNAPSHOT_INTERVAL;
  764. let duration = _this.form.duration;
  765. if (isFaceEnable == "true") {
  766. if (snapshotnterval === "") {
  767. callback(new Error("请输入抓拍间隔"));
  768. if (!_this.toActiveName) {
  769. _this.toActiveName = "tab4";
  770. _this.activeName = "tab4";
  771. }
  772. } else if (!snapshotnterval.toString().match(/^[1-9]\d*$/)) {
  773. callback(new Error("只能是正整数"));
  774. if (!_this.toActiveName) {
  775. _this.toActiveName = "tab4";
  776. _this.activeName = "tab4";
  777. }
  778. } else if (
  779. duration != "" &&
  780. parseInt(snapshotnterval) > parseInt(duration)
  781. ) {
  782. callback(new Error("抓拍间隔不能大于考试时长"));
  783. if (!_this.toActiveName) {
  784. _this.toActiveName = "tab4";
  785. _this.activeName = "tab4";
  786. }
  787. } else {
  788. callback();
  789. }
  790. } else {
  791. callback();
  792. }
  793. };
  794. let validateWarnThreshold = (rule, value, callback) => {
  795. let isFaceEnable = _this.form.properties.IS_FACE_ENABLE;
  796. let warnThreshold = _this.form.properties.WARN_THRESHOLD;
  797. if (isFaceEnable == "true") {
  798. if (warnThreshold === "") {
  799. callback(new Error("请输入预警阀值"));
  800. if (!_this.toActiveName) {
  801. _this.toActiveName = "tab4";
  802. _this.activeName = "tab4";
  803. }
  804. } else if (!warnThreshold.toString().match(/^(0|([1-9]\d?)|100)$/)) {
  805. callback(new Error("只能是0到100的整数"));
  806. if (!_this.toActiveName) {
  807. _this.toActiveName = "tab4";
  808. _this.activeName = "tab4";
  809. }
  810. } else {
  811. callback();
  812. }
  813. } else {
  814. callback();
  815. }
  816. };
  817. let validateLivingWarnThreshold = (rule, value, callback) => {
  818. let isFaceEnable = _this.form.properties.IS_FACE_ENABLE;
  819. let livingWarnThreshold = _this.form.properties.LIVING_WARN_THRESHOLD;
  820. if (isFaceEnable == "true") {
  821. if (livingWarnThreshold === "") {
  822. callback(new Error("请输入真实性预警阀值"));
  823. if (!_this.toActiveName) {
  824. _this.toActiveName = "tab4";
  825. _this.activeName = "tab4";
  826. }
  827. } else if (!livingWarnThreshold.toString().match(/^(0|([1-9]\d?)|100)$/)) {
  828. callback(new Error("只能是0到100的整数"));
  829. if (!_this.toActiveName) {
  830. _this.toActiveName = "tab4";
  831. _this.activeName = "tab4";
  832. }
  833. } else {
  834. callback();
  835. }
  836. } else {
  837. callback();
  838. }
  839. };
  840. let validateFaceVerifyStartMinute = (rule, value, callback) => {
  841. let isFaceVerify = _this.form.properties.IS_FACE_VERIFY;
  842. let freezeTime = _this.form.properties.FREEZE_TIME;
  843. let v = _this.form.properties.FACE_VERIFY_START_MINUTE;
  844. if (isFaceVerify == "true") {
  845. if (v === "") {
  846. callback(new Error("请输入活体检测开始分钟数"));
  847. if (!_this.toActiveName) {
  848. _this.toActiveName = "tab4";
  849. _this.activeName = "tab4";
  850. }
  851. } else if (!v.toString().match(/^[1-9]\d*$/)) {
  852. callback(new Error("只能是正整数"));
  853. if (!_this.toActiveName) {
  854. _this.toActiveName = "tab4";
  855. _this.activeName = "tab4";
  856. }
  857. } else if (freezeTime !== "" && parseInt(v) > parseInt(freezeTime)) {
  858. callback(new Error("活体检测开始分钟数不能大于交卷冻结时长"));
  859. if (!_this.toActiveName) {
  860. _this.toActiveName = "tab4";
  861. _this.activeName = "tab4";
  862. }
  863. } else {
  864. callback();
  865. }
  866. } else {
  867. callback();
  868. }
  869. };
  870. let validateFaceVerifyEndMinute = (rule, value, callback) => {
  871. let isFaceVerify = _this.form.properties.IS_FACE_VERIFY;
  872. let freezeTime = _this.form.properties.FREEZE_TIME;
  873. let start = _this.form.properties.FACE_VERIFY_START_MINUTE;
  874. let v = _this.form.properties.FACE_VERIFY_END_MINUTE;
  875. if (isFaceVerify == "true") {
  876. if (v === "") {
  877. callback(new Error("请输入活体检测结束分钟数"));
  878. if (!_this.toActiveName) {
  879. _this.toActiveName = "tab4";
  880. _this.activeName = "tab4";
  881. }
  882. } else if (!v.toString().match(/^[1-9]\d*$/)) {
  883. callback(new Error("只能是正整数"));
  884. if (!_this.toActiveName) {
  885. _this.toActiveName = "tab4";
  886. _this.activeName = "tab4";
  887. }
  888. } else if (start !== "" && parseInt(v) < parseInt(start)) {
  889. callback(new Error("活体检测结束分钟数不能小于活体检测开始分钟数"));
  890. if (!_this.toActiveName) {
  891. _this.toActiveName = "tab4";
  892. _this.activeName = "tab4";
  893. }
  894. } else if (freezeTime !== "" && parseInt(v) > parseInt(freezeTime)) {
  895. callback(new Error("活体检测结束分钟数不能大于交卷冻结时长"));
  896. if (!_this.toActiveName) {
  897. _this.toActiveName = "tab4";
  898. _this.activeName = "tab4";
  899. }
  900. } else {
  901. callback();
  902. }
  903. } else {
  904. callback();
  905. }
  906. };
  907. export default {
  908. components: {
  909. ckeditor,
  910. LinkTitlesCustom
  911. },
  912. data() {
  913. return {
  914. style: {
  915. label_width_tab1: "100px",
  916. label_width_tab2: "110px",
  917. label_width_tab3: "120px",
  918. label_width_tab4: "170px",
  919. label_width_tab5: "80px",
  920. label_width_tab6: "120px",
  921. label_width_tab7: "150px"
  922. },
  923. activeName: "tab1",
  924. toActiveName: null,
  925. examDatetimeRange: [],
  926. show_ckeditor: false,
  927. is_face_verify_diabled: true,
  928. is_face_enable_diabled: true,
  929. form: {
  930. started: false,
  931. name: "",
  932. code: "",
  933. examType: "ONLINE",
  934. examTimes: 1,
  935. beginTime: null,
  936. endTime: null,
  937. duration: 120,
  938. enable: "true",
  939. examLimit: "false",
  940. properties: {
  941. IS_OBJ_SCORE_VIEW: "true",
  942. IS_STRANGER_ENABLE: "false",
  943. MAX_INTERRUPT_NUM: "",
  944. EXAM_RECONNECT_TIME: 30,
  945. FREEZE_TIME: 0,
  946. BEFORE_EXAM_REMARK: "",
  947. AFTER_EXAM_REMARK: "",
  948. SHOW_CHEATING_REMARK: "true",
  949. CHEATING_REMARK: "",
  950. SINGLE_EDIT: "false",
  951. MUTIPLE_EDIT: "false",
  952. BOOL_EDIT: "false",
  953. FILL_BLANK_EDIT: "false",
  954. SINGLE_ANSWER_REMARK: "",
  955. MUTIPLE_ANSWER_REMARK: "",
  956. FILL_BLANK_REMARK: "",
  957. BOOL_ANSWER_REMARK: "",
  958. IS_FACE_ENABLE: "false",
  959. IS_FACE_CHECK: "false",
  960. SNAPSHOT_INTERVAL: 30,
  961. WARN_THRESHOLD: 50,
  962. MARKING_TYPE: "ALL",
  963. IP_LIMIT: "false",
  964. IP_ADDRESSES: null,
  965. LIVING_WARN_THRESHOLD: 50,
  966. IS_FACE_VERIFY: "false",
  967. FACE_VERIFY_START_MINUTE: 5,
  968. FACE_VERIFY_END_MINUTE: 10,
  969. PUSH_SCORE: "false",
  970. CHECK_ENVIRONMENT: "false"
  971. }
  972. },
  973. examTypeList: EXAM_TYPE,
  974. examId: "",
  975. rules: {
  976. code: [{ required: true, validator: validateCode, trigger: "blur" }],
  977. name: [{ required: true, validator: validateName, trigger: "blur" }],
  978. examDatetimeRange: [
  979. {
  980. required: true,
  981. validator: validateExamDatetimeRange,
  982. trigger: "blur"
  983. }
  984. ],
  985. duration: [
  986. { required: true, validator: validateDuration, trigger: "blur" }
  987. ],
  988. examTimes: [
  989. { required: true, validator: validateExamTimes, trigger: "blur" }
  990. ],
  991. FREEZE_TIME: [
  992. { required: true, validator: validateFreezeTime, trigger: "blur" }
  993. ],
  994. EXAM_RECONNECT_TIME: [
  995. {
  996. required: true,
  997. validator: validateExamReconnectTime,
  998. trigger: "blur"
  999. }
  1000. ],
  1001. MAX_INTERRUPT_NUM: [
  1002. {
  1003. required: false,
  1004. validator: validateMaxInterruptNum,
  1005. trigger: "blur"
  1006. }
  1007. ],
  1008. SNAPSHOT_INTERVAL: [
  1009. {
  1010. required: true,
  1011. validator: validateSnapshotInterval,
  1012. trigger: "blur"
  1013. }
  1014. ],
  1015. WARN_THRESHOLD: [
  1016. {
  1017. required: true,
  1018. validator: validateWarnThreshold,
  1019. trigger: "change"
  1020. }
  1021. ],
  1022. FACE_VERIFY_START_MINUTE: [
  1023. {
  1024. required: true,
  1025. validator: validateFaceVerifyStartMinute,
  1026. trigger: "blur"
  1027. }
  1028. ],
  1029. FACE_VERIFY_END_MINUTE: [
  1030. {
  1031. required: true,
  1032. validator: validateFaceVerifyEndMinute,
  1033. trigger: "blur"
  1034. }
  1035. ],
  1036. LIVING_WARN_THRESHOLD: [
  1037. {
  1038. required: true,
  1039. validator: validateLivingWarnThreshold,
  1040. trigger: "change"
  1041. }
  1042. ]
  1043. }
  1044. };
  1045. },
  1046. methods: {
  1047. faceEnableChange() {
  1048. if (this.form.properties.IS_FACE_ENABLE == "false") {
  1049. this.form.properties.IS_STRANGER_ENABLE = "false";
  1050. this.form.properties.IS_FACE_CHECK = "false";
  1051. this.form.properties.IS_FACE_VERIFY = "false";
  1052. }
  1053. },
  1054. init() {
  1055. if (this.examId != "add") {
  1056. let url = EXAM_WORK_API + "/exam/" + this.examId;
  1057. this.$httpWithMsg.get(url).then(response => {
  1058. let body = response.data;
  1059. body.properties = this.form.properties;
  1060. this.form = Object.assign(this.form, response.data);
  1061. this.form.enable = this.form.enable ? "true" : "false";
  1062. this.form.examLimit = this.form.examLimit ? "true" : "false";
  1063. this.examDatetimeRange = [this.form.beginTime, this.form.endTime];
  1064. console.log("getOnlineExam(); form: ", this.form);
  1065. let url = EXAM_WORK_API + "/exam/allProperties/" + this.examId;
  1066. this.$httpWithMsg.get(url).then(response => {
  1067. this.form.properties = Object.assign(
  1068. this.form.properties,
  1069. response.data
  1070. );
  1071. this.form.properties.SINGLE_EDIT =
  1072. this.form.properties.SINGLE_EDIT === "true";
  1073. this.form.properties.MUTIPLE_EDIT =
  1074. this.form.properties.MUTIPLE_EDIT === "true";
  1075. this.form.properties.BOOL_EDIT =
  1076. this.form.properties.BOOL_EDIT === "true";
  1077. this.form.properties.FILL_BLANK_EDIT =
  1078. this.form.properties.FILL_BLANK_EDIT === "true";
  1079. this.form.properties.CHECK_ENVIRONMENT =
  1080. this.form.properties.CHECK_ENVIRONMENT === "true";
  1081. this.show_ckeditor = true;
  1082. this.checkRootOrgPrivileges();
  1083. });
  1084. });
  1085. } else {
  1086. let now = moment().format("YYYY-MM-DD HH:mm:ss");
  1087. this.examDatetimeRange = [now, now];
  1088. this.show_ckeditor = true;
  1089. this.checkRootOrgPrivileges();
  1090. }
  1091. },
  1092. checkRootOrgPrivileges: function() {
  1093. let url =
  1094. CORE_API +
  1095. "/rolePrivilege/checkRootOrgPrivileges?privilegeCodes=FACE_CHECK,IDENTIFICATION_OF_LIVING_BODY";
  1096. this.$httpWithMsg.post(url).then(response => {
  1097. let res = response.data;
  1098. if (!res.FACE_CHECK) {
  1099. this.form.properties.IS_FACE_ENABLE = "false";
  1100. this.form.properties.IS_STRANGER_ENABLE = "false";
  1101. this.form.properties.IS_FACE_CHECK = "false";
  1102. this.form.properties.IS_FACE_VERIFY = "false";
  1103. this.is_face_enable_diabled = true;
  1104. } else {
  1105. this.is_face_enable_diabled = false;
  1106. }
  1107. if (!res.IDENTIFICATION_OF_LIVING_BODY) {
  1108. this.is_face_verify_diabled = true;
  1109. this.form.properties.IS_FACE_VERIFY = "false";
  1110. } else {
  1111. this.is_face_verify_diabled = false;
  1112. }
  1113. });
  1114. },
  1115. saveExam: function() {
  1116. this.toActiveName = null;
  1117. this.form.beginTime = this.examDatetimeRange[0];
  1118. this.form.endTime = this.examDatetimeRange[1];
  1119. console.log(this.form);
  1120. let url = EXAM_WORK_API + "/exam";
  1121. this.$refs.form.validate(valid => {
  1122. if (valid) {
  1123. if (this.examId != "add") {
  1124. this.$httpWithMsg.put(url, this.form).then(response => {
  1125. if (200 != response.status) {
  1126. this.$notify({
  1127. type: "error",
  1128. message: response.body.desc
  1129. });
  1130. return;
  1131. }
  1132. this.$notify({
  1133. type: "success",
  1134. message: "保存成功"
  1135. });
  1136. });
  1137. } else {
  1138. this.form.code = this.form.name;
  1139. this.$httpWithMsg.post(url, this.form).then(response => {
  1140. console.log(response);
  1141. this.$notify({
  1142. type: "success",
  1143. message: "新增成功"
  1144. });
  1145. this.examId = response.data.id;
  1146. this.form.id = this.examId;
  1147. this.$router.push({
  1148. path: "/examwork/onlineExam/" + response.data.id
  1149. });
  1150. });
  1151. }
  1152. } else {
  1153. return false;
  1154. }
  1155. });
  1156. },
  1157. back() {
  1158. this.$router.push({ path: "/examwork/examInfo" });
  1159. }
  1160. },
  1161. created() {
  1162. _this = this;
  1163. this.examId = this.$route.params.id;
  1164. this.init();
  1165. }
  1166. };
  1167. </script>
  1168. <style scoped>
  1169. .input {
  1170. width: 440px;
  1171. }
  1172. .input >>> .el-input__inner {
  1173. -webkit-appearance: button;
  1174. }
  1175. </style>