practiceExam.vue 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396
  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. label-position="right"
  16. >
  17. <div style="margin-bottom: 10px">
  18. <el-button type="primary" size="small" @click="saveExam"
  19. >保 存</el-button
  20. >
  21. <el-button type="primary" size="small" @click="back"
  22. >返 回</el-button
  23. >
  24. </div>
  25. <el-tabs type="border-card" v-model="activeName">
  26. <!-- 基础信息 -->
  27. <el-tab-pane label="基础信息" name="tab1">
  28. <el-row>
  29. <el-form-item
  30. label="考试名称"
  31. label-width="80px"
  32. placeholder="请输入考试名称"
  33. prop="name"
  34. >
  35. <el-input v-model="form.name"></el-input>
  36. </el-form-item>
  37. </el-row>
  38. <el-row>
  39. <el-form-item label="考试类型" label-width="80px">
  40. <el-select
  41. style="width:205px"
  42. :disabled="true"
  43. v-model="form.examType"
  44. placeholder="请选择"
  45. >
  46. <el-option
  47. v-for="item in examTypeList"
  48. :key="item.value"
  49. :label="item.label"
  50. :value="item.value"
  51. >
  52. </el-option>
  53. </el-select>
  54. </el-form-item>
  55. </el-row>
  56. <el-row>
  57. <el-form-item label="是否开启" label-width="80px">
  58. <el-radio-group
  59. v-model="form.enable"
  60. style="margin-left: 15px"
  61. >
  62. <el-radio label="true">开启</el-radio>
  63. <el-radio label="false">关闭</el-radio>
  64. </el-radio-group>
  65. </el-form-item>
  66. </el-row>
  67. <el-row>
  68. <el-form-item
  69. label="考试时间"
  70. prop="examDatetimeRange"
  71. label-width="80px"
  72. >
  73. <el-date-picker
  74. style="margin-left: 10px"
  75. v-model="examDatetimeRange"
  76. type="datetimerange"
  77. range-separator="至"
  78. start-placeholder="开始日期"
  79. end-placeholder="结束日期"
  80. value-format="yyyy-MM-dd HH:mm:ss"
  81. :clearable="false"
  82. >
  83. </el-date-picker>
  84. </el-form-item>
  85. </el-row>
  86. </el-tab-pane>
  87. <!-- 控制设置 -->
  88. <el-tab-pane label="控制设置" name="tab2">
  89. <el-row>
  90. <el-form-item
  91. label="考试时长"
  92. prop="duration"
  93. label-width="110px"
  94. >
  95. <el-input
  96. v-model.trim.number="form.duration"
  97. auto-complete="off"
  98. ></el-input>
  99. </el-form-item>
  100. <el-form-item label="分钟"></el-form-item>
  101. </el-row>
  102. <el-row>
  103. <el-form-item
  104. label="考试次数"
  105. prop="examTimes"
  106. label-width="110px"
  107. >
  108. <el-input
  109. v-model.trim.number="form.examTimes"
  110. auto-complete="off"
  111. ></el-input>
  112. </el-form-item>
  113. </el-row>
  114. <el-row>
  115. <el-form-item
  116. label="交卷冻结时间"
  117. prop="FREEZE_TIME"
  118. label-width="110px"
  119. >
  120. <el-input
  121. v-model.trim.number="form.properties.FREEZE_TIME"
  122. auto-complete="off"
  123. ></el-input>
  124. </el-form-item>
  125. <el-form-item label="分钟"></el-form-item>
  126. </el-row>
  127. <el-row>
  128. <el-form-item
  129. label="断点续考时间"
  130. prop="EXAM_RECONNECT_TIME"
  131. label-width="110px"
  132. >
  133. <el-input
  134. v-model.trim.number="form.properties.EXAM_RECONNECT_TIME"
  135. auto-complete="off"
  136. ></el-input>
  137. </el-form-item>
  138. <el-form-item label="分钟"></el-form-item>
  139. </el-row>
  140. </el-tab-pane>
  141. <el-tab-pane label="显示设置" name="tab3">
  142. <el-row v-if="show_ckeditor">
  143. <el-form-item label="考前说明" label-width="110px">
  144. <ckeditor
  145. v-model="form.properties.BEFORE_EXAM_REMARK"
  146. ></ckeditor>
  147. </el-form-item>
  148. </el-row>
  149. <el-row>
  150. <el-form-item label="客观题成绩显示" label-width="110px">
  151. <el-radio-group v-model="form.properties.IS_OBJ_SCORE_VIEW">
  152. <el-radio label="true">开启</el-radio>
  153. <el-radio label="false">关闭</el-radio>
  154. </el-radio-group>
  155. </el-form-item>
  156. </el-row>
  157. <el-row>
  158. <el-form-item label="练习模式" label-width="110px">
  159. <el-radio-group v-model="form.properties.PRACTICE_TYPE">
  160. <el-radio label="IN_PRACTICE">边答边显示答案</el-radio>
  161. <el-radio label="AFTER_PRACTICE"
  162. >结束统一显示答案</el-radio
  163. >
  164. <el-radio label="NO_ANSWER">不显示答案</el-radio>
  165. </el-radio-group>
  166. </el-form-item>
  167. </el-row>
  168. </el-tab-pane>
  169. </el-tabs>
  170. </el-form>
  171. </div>
  172. </div>
  173. </section>
  174. </div>
  175. </template>
  176. <script>
  177. import { EXAM_TYPE, EXAM_WORK_API } from "@/constants/constants.js";
  178. import moment from "moment";
  179. import ckeditor from "@/components/ckeditor.vue";
  180. import LinkTitlesCustom from "@/components/LinkTitlesCustom.vue";
  181. let _this = null;
  182. let validateName = (rule, value, callback) => {
  183. let name = _this.form.name;
  184. if (name == "") {
  185. callback(new Error("请输入考试名称"));
  186. _this.activeName = "tab1";
  187. } else {
  188. callback();
  189. }
  190. };
  191. let validateExamDatetimeRange = (rule, value, callback) => {
  192. let examDatetimeRange = _this.examDatetimeRange;
  193. if (!examDatetimeRange) {
  194. callback(new Error("请输入考试时间"));
  195. _this.activeName = "tab1";
  196. } else {
  197. callback();
  198. }
  199. };
  200. let validateDuration = (rule, value, callback) => {
  201. let duration = _this.form.duration;
  202. if (duration == "") {
  203. callback(new Error("请输入考试时长"));
  204. _this.activeName = "tab2";
  205. } else if (!duration.toString().match(/^[1-9]\d*|0$/)) {
  206. callback(new Error("只能是非负整数"));
  207. _this.activeName = "tab2";
  208. } else {
  209. callback();
  210. }
  211. };
  212. let validateExamTimes = (rule, value, callback) => {
  213. let examTimes = _this.form.examTimes;
  214. if (examTimes == "") {
  215. callback(new Error("请输入考试次数"));
  216. _this.activeName = "tab2";
  217. } else if (!examTimes.toString().match(/^[1-9]\d*$/)) {
  218. callback(new Error("只能是正整数"));
  219. _this.activeName = "tab2";
  220. } else {
  221. callback();
  222. }
  223. };
  224. let validateFreezeTime = (rule, value, callback) => {
  225. let freezeTime = _this.form.properties.FREEZE_TIME;
  226. let duration = _this.form.duration;
  227. if (freezeTime == "") {
  228. callback(new Error("请输入交卷冻结时长"));
  229. _this.activeName = "tab2";
  230. } else if (!freezeTime.toString().match(/^[1-9]\d*|0$/)) {
  231. callback(new Error("只能是非负整数"));
  232. _this.activeName = "tab2";
  233. } else if (duration != "" && freezeTime > duration) {
  234. callback(new Error("交卷冻结时长不能大于考试时长"));
  235. _this.activeName = "tab2";
  236. } else {
  237. callback();
  238. }
  239. };
  240. let validateExamReconnectTime = (rule, value, callback) => {
  241. let examReconnectTime = _this.form.properties.EXAM_RECONNECT_TIME;
  242. if (examReconnectTime == "") {
  243. callback(new Error("请输入断点续考时间"));
  244. _this.activeName = "tab2";
  245. } else if (!examReconnectTime.toString().match(/^[1-9]\d*$/)) {
  246. callback(new Error("只能是正整数"));
  247. _this.activeName = "tab2";
  248. } else {
  249. callback();
  250. }
  251. };
  252. export default {
  253. components: {
  254. ckeditor,
  255. LinkTitlesCustom
  256. },
  257. data() {
  258. return {
  259. activeName: "tab1",
  260. examDatetimeRange: [],
  261. show_ckeditor: false,
  262. form: {
  263. started: false,
  264. name: "",
  265. examType: "PRACTICE",
  266. examTimes: 1,
  267. beginTime: null,
  268. endTime: null,
  269. duration: 120,
  270. enable: "true",
  271. properties: {
  272. FREEZE_TIME: 0,
  273. EXAM_RECONNECT_TIME: 30,
  274. BEFORE_EXAM_REMARK: "",
  275. AFTER_EXAM_REMARK: "",
  276. IS_OBJ_SCORE_VIEW: "true",
  277. PRACTICE_TYPE: "IN_PRACTICE"
  278. }
  279. },
  280. examTypeList: EXAM_TYPE,
  281. examId: "",
  282. rules: {
  283. name: [{ required: true, validator: validateName, trigger: "blur" }],
  284. examDatetimeRange: [
  285. {
  286. required: true,
  287. validator: validateExamDatetimeRange,
  288. trigger: "blur"
  289. }
  290. ],
  291. duration: [
  292. { required: true, validator: validateDuration, trigger: "blur" }
  293. ],
  294. examTimes: [
  295. { required: true, validator: validateExamTimes, trigger: "blur" }
  296. ],
  297. FREEZE_TIME: [
  298. { required: true, validator: validateFreezeTime, trigger: "blur" }
  299. ],
  300. EXAM_RECONNECT_TIME: [
  301. {
  302. required: true,
  303. validator: validateExamReconnectTime,
  304. trigger: "blur"
  305. }
  306. ]
  307. }
  308. };
  309. },
  310. methods: {
  311. init() {
  312. if (this.examId != "add") {
  313. let url = EXAM_WORK_API + "/exam/" + this.examId;
  314. this.$http.get(url).then(response => {
  315. let body = response.data;
  316. body.properties = this.form.properties;
  317. this.form = Object.assign(this.form, response.data);
  318. this.form.enable = this.form.enable ? "true" : "false";
  319. this.examDatetimeRange = [this.form.beginTime, this.form.endTime];
  320. console.log("getOnlineExam(); form: ", this.form);
  321. let url = EXAM_WORK_API + "/exam/allProperties/" + this.examId;
  322. this.$http.get(url).then(response => {
  323. this.form.properties = Object.assign(
  324. this.form.properties,
  325. response.data
  326. );
  327. this.form.properties.IS_OBJ_SCORE_VIEW =
  328. this.form.properties.IS_OBJ_SCORE_VIEW == "true" ? true : false;
  329. this.show_ckeditor = true;
  330. });
  331. });
  332. } else {
  333. let now = moment().format("YYYY-MM-DD HH:mm:ss");
  334. this.examDatetimeRange = [now, now];
  335. this.show_ckeditor = true;
  336. }
  337. },
  338. saveExam: function() {
  339. this.form.beginTime = this.examDatetimeRange[0];
  340. this.form.endTime = this.examDatetimeRange[1];
  341. console.log(this.form);
  342. let url = EXAM_WORK_API + "/exam";
  343. this.$refs.form.validate(valid => {
  344. if (valid) {
  345. if (this.examId != "add") {
  346. this.$http.put(url, this.form).then(response => {
  347. if (200 != response.status) {
  348. this.$notify({
  349. type: "error",
  350. message: response.body.desc
  351. });
  352. return;
  353. }
  354. this.$notify({
  355. type: "success",
  356. message: "保存成功"
  357. });
  358. });
  359. } else {
  360. this.$http.post(url, this.form).then(response => {
  361. console.log(response);
  362. this.$notify({
  363. type: "success",
  364. message: "新增成功"
  365. });
  366. this.back();
  367. });
  368. }
  369. } else {
  370. return false;
  371. }
  372. });
  373. },
  374. back() {
  375. this.$router.push({ path: "/examwork/examInfo" });
  376. }
  377. },
  378. created() {
  379. _this = this;
  380. this.examId = this.$route.params.id;
  381. this.init();
  382. }
  383. };
  384. </script>
  385. <style scoped></style>