onlineExam.vue 33 KB

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