onlineExam.vue 34 KB

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