EditOtherQuestion.vue 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537
  1. <!-- 编辑填空,问答,判断题 -->
  2. <template>
  3. <div id="editOtherApp">
  4. <section v-loading="fullscreenLoading" class="content">
  5. <h3 class="box-title">
  6. <span v-if="!quesModel.id"
  7. ><LinkTitlesCustom :current-paths="['试题管理', '试题新增']"
  8. /></span>
  9. <span v-if="quesModel.id"
  10. ><LinkTitlesCustom :current-paths="['试题管理', '试题修改']"
  11. /></span>
  12. </h3>
  13. <div class="box-body">
  14. <el-form
  15. ref="quesModel"
  16. :model="quesModel"
  17. :rules="rules"
  18. label-position="right"
  19. label-width="80px"
  20. >
  21. <el-row :gutter="10">
  22. <el-col :xs="10" :sm="10" :md="10" :lg="10">
  23. <el-form-item label="题型">
  24. <el-select
  25. v-model="quesModel.questionType"
  26. :disabled="true"
  27. placeholder="请输入题型"
  28. >
  29. <el-option
  30. v-for="item in questionTypes"
  31. :key="item.value"
  32. :label="item.label"
  33. :value="item.value"
  34. >
  35. </el-option>
  36. </el-select>
  37. </el-form-item>
  38. </el-col>
  39. </el-row>
  40. <!-- created by weiwenhai -->
  41. <el-form-item label="难度">
  42. <el-select
  43. v-model="quesModel.difficultyDegree"
  44. placeholder="请输入难度"
  45. >
  46. <el-option
  47. v-for="item in difficultyDegreeList"
  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-form-item label="公开度">
  56. <el-select v-model="quesModel.publicity" placeholder="请输入公开度">
  57. <el-option
  58. v-for="item in publicityList"
  59. :key="item.value"
  60. :label="item.label"
  61. :value="item.value"
  62. >
  63. </el-option>
  64. </el-select>
  65. </el-form-item>
  66. <el-form-item
  67. v-if="quesModel.questionType == 'TEXT_ANSWER_QUESTION'"
  68. label="作答类型"
  69. >
  70. <el-select v-model="quesModel.answerType">
  71. <el-option
  72. v-for="item in answerTypes"
  73. :key="item.value"
  74. :label="item.label"
  75. :value="item.value"
  76. >
  77. </el-option>
  78. </el-select>
  79. </el-form-item>
  80. <el-form-item label="属性列表">
  81. <el-tooltip
  82. v-for="(content, index) in quesModel.quesProperties"
  83. :key="index"
  84. placement="top"
  85. >
  86. <div slot="content">
  87. <span v-if="content.firstProperty != null"
  88. >一级属性:{{ content.firstProperty.name }}</span
  89. ><br />
  90. <span v-if="content.secondProperty != null"
  91. >二级属性:{{ content.secondProperty.name }}</span
  92. >
  93. </div>
  94. <el-tag
  95. :key="content.id"
  96. style="margin-right: 5px"
  97. closable
  98. type="primary"
  99. @close="handleClose(content)"
  100. >
  101. {{ content.coursePropertyName }}
  102. </el-tag>
  103. </el-tooltip>
  104. </el-form-item>
  105. <el-row :gutter="20">
  106. <el-col :xs="6" :sm="6" :md="6" :lg="6">
  107. <el-form-item label="属性名">
  108. <el-select
  109. v-model="coursePropertyName"
  110. placeholder="属性名"
  111. class="property_with"
  112. @change="searchFirst"
  113. >
  114. <el-option
  115. v-for="item in coursePropertyList"
  116. :key="item.name"
  117. :label="item.name"
  118. :value="item.name"
  119. >
  120. </el-option>
  121. </el-select>
  122. </el-form-item>
  123. </el-col>
  124. <el-col :xs="6" :sm="6" :md="6" :lg="6">
  125. <el-form-item label="一级">
  126. <el-select
  127. v-model="firstPropertyId"
  128. placeholder="一级"
  129. class="property_with"
  130. @change="searchSecond"
  131. >
  132. <el-option
  133. v-for="item in firstPropertyList"
  134. :key="item.id"
  135. :label="item.name"
  136. :value="item.id"
  137. >
  138. </el-option>
  139. </el-select>
  140. </el-form-item>
  141. </el-col>
  142. <el-col :xs="6" :sm="6" :md="6" :lg="6">
  143. <el-form-item label="二级">
  144. <el-select
  145. v-model="secondPropertyId"
  146. placeholder="二级"
  147. class="property_with"
  148. >
  149. <el-option
  150. v-for="item in secondPropertyList"
  151. :key="item.id"
  152. :label="item.name"
  153. :value="item.id"
  154. >
  155. </el-option>
  156. </el-select>
  157. </el-form-item>
  158. </el-col>
  159. <el-col :xs="3" :sm="3" :md="3" :lg="3">
  160. <el-form-item>
  161. <el-button
  162. type="primary"
  163. style="margin-left: -30px"
  164. @click="insertProperty"
  165. ><i class="el-icon-plus"></i> 新增属性</el-button
  166. >
  167. </el-form-item>
  168. </el-col>
  169. </el-row>
  170. <!-- end -->
  171. <el-row :gutter="10">
  172. <el-col :xs="30" :sm="30" :md="30" :lg="30">
  173. <el-form-item label="题干" prop="quesBody">
  174. <ckeditor v-model="quesModel.quesBody"></ckeditor>
  175. </el-form-item>
  176. </el-col>
  177. </el-row>
  178. <el-row
  179. v-for="quesOption in quesModel.quesOptions"
  180. :key="quesOption"
  181. :gutter="10"
  182. >
  183. <el-col :xs="30" :sm="30" :md="30" :lg="30">
  184. <el-form-item :label="quesOption.number">
  185. <ckeditor v-model="quesOption.quesBody"></ckeditor>
  186. </el-form-item>
  187. </el-col>
  188. </el-row>
  189. <!-- 非套题 -->
  190. <div
  191. v-if="
  192. quesModel.questionType !== 'NESTED_ANSWER_QUESTION' &&
  193. quesModel.questionType !== 'BOOL_ANSWER_QUESTION'
  194. "
  195. >
  196. <el-form-item label="答案" prop="quesAnswer">
  197. <ckeditor v-model="quesModel.quesAnswer"></ckeditor>
  198. </el-form-item>
  199. </div>
  200. <div v-if="quesModel.questionType == 'BOOL_ANSWER_QUESTION'">
  201. <el-row>
  202. <el-col>
  203. <el-form-item label="答案" prop="quesAnswer">
  204. <el-select
  205. v-model="quesModel.quesAnswer"
  206. placeholder="请选择"
  207. >
  208. <el-option
  209. v-for="op in options"
  210. :key="op"
  211. :label="op"
  212. :value="op"
  213. >
  214. </el-option>
  215. </el-select>
  216. </el-form-item>
  217. </el-col>
  218. </el-row>
  219. </div>
  220. <div class="paper-top">
  221. <el-form-item>
  222. <el-button type="primary" @click="saveQues('quesModel')"
  223. >保存</el-button
  224. >
  225. <el-button
  226. type="primary"
  227. icon="caret-left"
  228. @click="backToQuesList()"
  229. >返回列表</el-button
  230. >
  231. </el-form-item>
  232. </div>
  233. </el-form>
  234. </div>
  235. </section>
  236. </div>
  237. </template>
  238. <script>
  239. import { QUESTION_API } from "@/constants/constants";
  240. import { isEmptyStr, QUESTION_TYPES } from "../constants/constants";
  241. import ckeditor from "../component/ckeditor.vue";
  242. import LinkTitlesCustom from "@/components/LinkTitlesCustom.vue";
  243. export default {
  244. name: "EditOtherApp",
  245. components: { ckeditor, LinkTitlesCustom },
  246. data() {
  247. return {
  248. fullscreenLoading: false,
  249. questionTypes: QUESTION_TYPES,
  250. courseName: "",
  251. courseNo: "",
  252. paperDetailId: "",
  253. paperId: "",
  254. quesModel: {
  255. courseName: "",
  256. courseNo: "",
  257. quesAnswer: "",
  258. quesBody: "",
  259. questionType: "",
  260. difficultyDegree: "",
  261. publicity: true,
  262. answerType: "",
  263. quesProperties: [],
  264. score: 0,
  265. },
  266. options: ["正确", "错误"],
  267. difficultyDegreeList: [
  268. { label: 0.1, value: 0.1 },
  269. { label: 0.2, value: 0.2 },
  270. { label: 0.3, value: 0.3 },
  271. { label: 0.4, value: 0.4 },
  272. { label: 0.5, value: 0.5 },
  273. { label: 0.6, value: 0.6 },
  274. { label: 0.7, value: 0.7 },
  275. { label: 0.8, value: 0.8 },
  276. { label: 0.9, value: 0.9 },
  277. { label: 1.0, value: 1.0 },
  278. ],
  279. publicityList: [
  280. { label: "公开", value: true },
  281. { label: "非公开", value: false },
  282. ],
  283. answerTypes: [
  284. { label: "文本", value: "DIVERSIFIED_TEXT" },
  285. { label: "音频", value: "SINGLE_AUDIO" },
  286. ],
  287. coursePropertyList: [],
  288. coursePropertyName: "", //课程属性名
  289. firstPropertyList: [], //一级属性集合
  290. firstPropertyId: "", //一级属性id
  291. secondPropertyList: [], //二级属性集合
  292. secondPropertyId: "", //二级属性id
  293. //验证
  294. rules: {
  295. // quesBody: [
  296. // {required: true, message: '请输入题干', trigger: 'blur'}
  297. // ],
  298. quesAnswer: [
  299. { required: true, message: "请输入答案", trigger: "blur" },
  300. ],
  301. },
  302. };
  303. },
  304. computed: {},
  305. created() {
  306. this.paperId = this.$route.params.paperId;
  307. this.paperDetailId = this.$route.params.paperDetailId;
  308. this.courseName = this.$route.params.courseName;
  309. this.courseNo = this.$route.params.courseNo;
  310. let questionType = this.$route.params.questionType;
  311. if (questionType) {
  312. this.quesModel.questionType = questionType;
  313. }
  314. this.questionId = this.$route.params.id;
  315. if (this.questionId) {
  316. this.quesModel["id"] = this.questionId;
  317. this.getQues(this.questionId);
  318. }
  319. if (this.courseNo) {
  320. this.$http
  321. .get(QUESTION_API + "/courseProperty/enable/" + this.courseNo)
  322. .then((response) => {
  323. this.coursePropertyList = response.data;
  324. });
  325. }
  326. if (isEmptyStr(this.quesModel.answerType)) {
  327. this.quesModel.answerType = "DIVERSIFIED_TEXT";
  328. }
  329. },
  330. mounted() {},
  331. methods: {
  332. saveQues(formName) {
  333. if (!this.quesModel.difficultyDegree) {
  334. this.$notify({
  335. message: "请选择试题难度",
  336. type: "error",
  337. });
  338. return false;
  339. }
  340. this.$refs[formName].validate((valid) => {
  341. if (valid) {
  342. if (this.questionId) {
  343. this.fullscreenLoading = true;
  344. //修改逻辑
  345. this.$httpWithMsg
  346. .put(QUESTION_API + "/question", this.quesModel)
  347. .then(() => {
  348. this.$notify({
  349. message: "保存成功",
  350. type: "success",
  351. });
  352. })
  353. .finally(() => (this.fullscreenLoading = false));
  354. } else {
  355. //新增逻辑
  356. this.quesModel.courseNo = this.courseNo;
  357. this.quesModel.courseName = this.courseName;
  358. this.fullscreenLoading = true;
  359. this.$http
  360. .post(
  361. QUESTION_API +
  362. "/paper/addQuestion/" +
  363. this.paperId +
  364. "/" +
  365. this.paperDetailId,
  366. this.quesModel
  367. )
  368. .then(() => {
  369. this.fullscreenLoading = false;
  370. this.$notify({
  371. type: "success",
  372. message: `保存成功`,
  373. });
  374. this.$router.push({ path: "/questions/question_list/0" });
  375. })
  376. .catch(() => {
  377. this.fullscreenLoading = false;
  378. });
  379. }
  380. } else {
  381. return false;
  382. }
  383. });
  384. },
  385. getQues(id) {
  386. this.$http.get(QUESTION_API + "/question/" + id).then((response) => {
  387. this.quesModel = response.data;
  388. if (isEmptyStr(this.quesModel.answerType)) {
  389. this.quesModel.answerType = "DIVERSIFIED_TEXT";
  390. }
  391. this.initCourseProperty();
  392. });
  393. },
  394. backToQuesList() {
  395. this.$router.push({
  396. path: "/questions/question_list/1",
  397. });
  398. },
  399. //查询所有课程属性名
  400. initCourseProperty() {
  401. var code = this.quesModel.course.code;
  402. this.$http
  403. .get(QUESTION_API + "/courseProperty/code/" + code)
  404. .then((response) => {
  405. this.coursePropertyList = response.data;
  406. });
  407. },
  408. //查询一级属性
  409. searchFirst() {
  410. this.firstPropertyId = "";
  411. this.secondPropertyId = "";
  412. this.secondPropertyList = [];
  413. for (let courseProperty of this.coursePropertyList) {
  414. if (courseProperty.name == this.coursePropertyName) {
  415. this.$http
  416. .get(QUESTION_API + "/property/first/" + courseProperty.id)
  417. .then((response) => {
  418. this.firstPropertyList = response.data;
  419. });
  420. }
  421. }
  422. },
  423. //查询二级属性
  424. searchSecond() {
  425. this.secondPropertyId = "";
  426. this.$http
  427. .get(QUESTION_API + "/property/second/" + this.firstPropertyId)
  428. .then((response) => {
  429. this.secondPropertyList = response.data;
  430. });
  431. },
  432. //新增属性
  433. insertProperty() {
  434. if (!this.checkInsertPro()) {
  435. return false;
  436. }
  437. var quesProperty = {
  438. id: "",
  439. coursePropertyName: "",
  440. firstProperty: {},
  441. secondProperty: {},
  442. };
  443. if (
  444. this.quesModel.quesProperties === undefined ||
  445. this.quesModel.quesProperties === null ||
  446. this.quesModel.quesProperties.length == 0
  447. ) {
  448. this.quesModel.quesProperties = [];
  449. }
  450. quesProperty.id =
  451. this.coursePropertyName +
  452. "-" +
  453. this.firstPropertyId +
  454. "-" +
  455. this.secondPropertyId;
  456. for (let quesPro of this.quesModel.quesProperties) {
  457. if (quesPro.id == quesProperty.id) {
  458. this.$notify({
  459. message: "该属性已存在,请重新选择",
  460. type: "error",
  461. });
  462. return false;
  463. }
  464. }
  465. quesProperty.coursePropertyName = this.coursePropertyName;
  466. //取到一级属性对象
  467. for (let property of this.firstPropertyList) {
  468. if (property.id == this.firstPropertyId) {
  469. quesProperty.firstProperty = property;
  470. }
  471. }
  472. //判断是否有二级属性
  473. if (
  474. this.secondPropertyList != undefined &&
  475. this.secondPropertyList.length > 0
  476. ) {
  477. if (!this.secondPropertyId) {
  478. this.$notify({
  479. message: "请选择二级属性",
  480. type: "error",
  481. });
  482. return false;
  483. }
  484. }
  485. //取到二级属性对象
  486. for (let property of this.secondPropertyList) {
  487. if (property.id == this.secondPropertyId) {
  488. quesProperty.secondProperty = property;
  489. }
  490. }
  491. this.quesModel.quesProperties.push(quesProperty);
  492. this.quesModel = Object.assign({}, this.quesModel);
  493. //清空下拉框
  494. this.coursePropertyName = "";
  495. this.firstPropertyId = "";
  496. this.secondPropertyId = "";
  497. this.firstPropertyList = [];
  498. this.secondPropertyList = [];
  499. },
  500. //删除属性
  501. handleClose(tag) {
  502. this.quesModel.quesProperties.splice(
  503. this.quesModel.quesProperties.indexOf(tag),
  504. 1
  505. );
  506. this.quesModel = Object.assign({}, this.quesModel);
  507. },
  508. //新增属性验证
  509. checkInsertPro() {
  510. if (!this.coursePropertyName) {
  511. this.$notify({
  512. message: "请选择属性",
  513. type: "error",
  514. });
  515. return false;
  516. }
  517. if (!this.firstPropertyId) {
  518. this.$notify({
  519. message: "请选择一级属性",
  520. type: "error",
  521. });
  522. return false;
  523. }
  524. return true;
  525. },
  526. },
  527. };
  528. </script>
  529. <style scoped src="../styles/Common.css"></style>