Parcourir la source

基础题型编辑完成

zhangjie il y a 2 ans
Parent
commit
7abe1b80c6

+ 3 - 0
src/assets/styles/base.scss

@@ -297,6 +297,9 @@ body {
 .margin-tb-20 {
   margin: 20px 0;
 }
+.margin-lr-10 {
+  margin: 0 10px;
+}
 .line-seperator {
   border-bottom: 1px solid $--color-border;
   margin: 15px 0;

+ 1 - 1
src/assets/styles/element-ui-costom.scss

@@ -4,7 +4,7 @@
     .el-dialog__header {
       width: 100%;
       position: fixed;
-      z-index: 9;
+      z-index: 19;
       background-color: #fff;
       border-bottom: 1px solid $--color-border;
       padding: 15px;

+ 2 - 1
src/assets/styles/pages.scss

@@ -853,7 +853,8 @@
 // question-edit-dialog
 .question-edit-dialog {
   .el-dialog__body {
-    bottom: 0;
+    bottom: 0 !important;
+    padding-top: 83px !important;
     background-color: $--color-background;
   }
   .el-dialog__footer {

+ 1 - 1
src/components/vEditor/VEditor.vue

@@ -114,7 +114,7 @@ export default {
       this.clearSetTs();
       // 延迟触发input任务,避免频繁触发,同时也等待图片渲染,方便获取图片显示尺寸
       this.addSetTime(() => {
-        console.log("input:" + Math.random());
+        // console.log("input:" + Math.random());
         this.inputDelaying = false;
         const json = toJSON(this.$refs.editor);
         this.$emit("input", json);

+ 4 - 0
src/modules/question/api.js

@@ -48,3 +48,7 @@ export function importQuestionApi(data, headData) {
     headers: headData,
   });
 }
+export function updateQuestionApi(data) {
+  // return $httpWithMsg.post(`${QUESTION_API}/paper/updateQuestion/`, data);
+  return Promise.resolve(data);
+}

+ 33 - 5
src/modules/question/components/QuestionEditDialog.vue

@@ -16,11 +16,17 @@
         <span>课程名称:{{ question.courseName }}</span>
       </div>
       <div>
-        <el-button type="primary" @click="confirm">确定</el-button>
-        <el-button v-if="!isEdit" type="primary" @click="initData"
+        <el-button
+          size="small"
+          type="primary"
+          :loading="loading"
+          @click="confirm"
+          >确定</el-button
+        >
+        <el-button v-if="!isEdit" size="small" type="primary" @click="initData"
           >继续出题</el-button
         >
-        <el-button @click="cancel">取消</el-button>
+        <el-button size="small" @click="cancel">取消</el-button>
       </div>
     </div>
     <div class="part-box question-edit">
@@ -30,6 +36,7 @@
             v-for="item in QUESTION_TYPES"
             :key="item.code"
             :type="curQuestionType === item.code ? 'primary' : 'default'"
+            size="small"
             @click="switchType(item)"
             >{{ item.name }}</el-button
           >
@@ -58,6 +65,7 @@ import FillBlankQuestion from "./edit/FillBlankQuestion.vue";
 import SelectQuestion from "./edit/SelectQuestion.vue";
 import TextAnswerQuestion from "./edit/TextAnswerQuestion.vue";
 import { randomCode } from "@/plugins/utils";
+import { updateQuestionApi } from "../api";
 
 const structTypeCompDict = {
   SINGLE_ANSWER_QUESTION: "select-question",
@@ -95,12 +103,16 @@ export default {
       curQuestionType: "SINGLE_ANSWER_QUESTION",
       questionModel: {},
       questionKey: "",
+      loading: false,
     };
   },
   computed: {
     isEdit() {
       return !!this.question.id;
     },
+    title() {
+      return this.isEdit ? "编辑试题" : "创建试题";
+    },
     structTypeComp() {
       return structTypeCompDict[this.curQuestionType];
     },
@@ -115,6 +127,7 @@ export default {
         getInitQuestionModel(this.curQuestionType),
         this.question
       );
+      this.loading = false;
     },
     cancel() {
       this.modalIsShow = false;
@@ -134,8 +147,23 @@ export default {
       this.curQuestionType = item.code;
       this.initData();
     },
-    confirm() {
-      this.cancel();
+    async confirm() {
+      const valid = await this.$refs.QuestionEditDetail.validate().catch(
+        () => {}
+      );
+      if (!valid) return;
+
+      if (this.loading) return;
+      this.loading = true;
+
+      this.questionModel = this.$refs.QuestionEditDetail.getData();
+      console.log(this.questionModel);
+      const res = await updateQuestionApi(this.questionModel).catch(() => {});
+      this.loading = false;
+      if (!res) return;
+
+      this.$message.success(this.title + "成功");
+      // this.cancel();
     },
   },
 };

+ 12 - 11
src/modules/question/components/QuestionInfoEdit.vue

@@ -3,7 +3,7 @@
     <el-form label-width="100px">
       <el-form-item label="难度">
         <el-select
-          v-model="modelForm.difficulty"
+          v-model="modalForm.difficulty"
           placeholder="请选择难度"
           @change="emitChange"
         >
@@ -21,17 +21,17 @@
         <div class="box-flex">
           <property-select
             v-model="properties.coursePropertyId"
-            :course-id="modelForm.courseId"
+            :course-id="modalForm.courseId"
             @change="coursePropertyChange"
           ></property-select>
-          <span>一级</span>
+          <span class="margin-lr-10">一级</span>
           <property-sub-select
             v-model="properties.firstPropertyId"
             :parent-id="properties.coursePropertyId"
             data-type="first"
             @change="firstPropertyChange"
           ></property-sub-select>
-          <span>二级</span>
+          <span class="margin-lr-10">二级</span>
           <property-sub-select
             v-model="properties.secondPropertyId"
             :parent-id="properties.firstPropertyId"
@@ -39,6 +39,7 @@
             @change="secondPropertyChange"
           ></property-sub-select>
           <el-button
+            class="margin-lr-10"
             type="primary"
             icon="icon icon-plus-white"
             :disabled="!propSelected"
@@ -49,7 +50,7 @@
       </el-form-item>
       <el-form-item label="属性列表">
         <el-tag
-          v-for="item in modelForm.quesProperties"
+          v-for="item in modalForm.quesProperties"
           :key="item.id"
           style="margin-right: 5px"
           closable
@@ -86,7 +87,7 @@ export default {
   data() {
     return {
       DIFFICULTY_LIST,
-      modelForm: {
+      modalForm: {
         ...initModalForm,
       },
       properties: {
@@ -115,7 +116,7 @@ export default {
   },
   methods: {
     initData() {
-      this.modelForm = this.$objAssign(initModalForm, this.question);
+      this.modalForm = this.$objAssign(initModalForm, this.question);
     },
     coursePropertyChange(val) {
       this.selection.courseProperty = val || {};
@@ -127,7 +128,7 @@ export default {
       this.selection.secondProperty = val || {};
     },
     removeProperty(property) {
-      this.modelForm.quesProperties = this.modelForm.quesProperties.filter(
+      this.modalForm.quesProperties = this.modalForm.quesProperties.filter(
         (item) => property.id !== item.id
       );
       this.emitChange();
@@ -139,18 +140,18 @@ export default {
         name: `${this.selection.courseProperty.name},${this.selection.firstProperty.name},${this.selection.secondProperty.name}`,
         ...this.properties,
       };
-      const propertyExist = this.modelForm.quesProperties.find(
+      const propertyExist = this.modalForm.quesProperties.find(
         (item) => item.id === newProperty.id
       );
       if (propertyExist) {
         this.$message.error("属性已存在!");
         return;
       }
-      this.modelForm.quesProperties.push(newProperty);
+      this.modalForm.quesProperties.push(newProperty);
       this.emitChange();
     },
     emitChange() {
-      this.$emit("change", this.modelForm);
+      this.$emit("change", this.modalForm);
     },
   },
 };

+ 12 - 3
src/modules/question/components/edit/BooleanQuestion.vue

@@ -2,12 +2,15 @@
   <div class="boolean-question">
     <el-form
       ref="modalFormComp"
-      :model="modelForm"
+      :model="modalForm"
       :rules="rules"
       label-width="100px"
     >
-      <el-form-item prop="quesBody" label="题干:">
-        <v-editor v-model="modalForm.quesBody"></v-editor>
+      <el-form-item prop="quesBody" label="题干">
+        <v-editor
+          v-model="modalForm.quesBody"
+          @change="quesBodyChange"
+        ></v-editor>
       </el-form-item>
       <el-form-item prop="quesAnswer" label="答案">
         <el-radio-group v-model="modalForm.quesAnswer" @change="answerChange">
@@ -86,6 +89,12 @@ export default {
         this.question
       );
     },
+    quesBodyChange() {
+      this.$refs.modalFormComp.validateField(`quesBody`, () => {});
+    },
+    answerChange() {
+      this.$refs.modalFormComp.validateField(`quesAnswer`, () => {});
+    },
     questionInfoChange(questionInfo) {
       this.modalForm = Object.assign({}, this.modalForm, questionInfo);
     },

+ 8 - 8
src/modules/question/components/edit/FillBlankQuestion.vue

@@ -2,29 +2,29 @@
   <div class="fill-blank-question">
     <el-form
       ref="modalFormComp"
-      :model="modelForm"
+      :model="modalForm"
       :rules="rules"
       label-width="100px"
     >
-      <el-form-item prop="quesBody" label="题干">
+      <el-form-item prop="quesBody" label="题干">
         <v-editor
           v-model="modalForm.quesBody"
           enable-answer-point
           @answer-point-changed="answerPointsChange"
         ></v-editor>
       </el-form-item>
-      <span>答案</span>
+      <el-form-item label="答案"></el-form-item>
       <el-form-item
         v-for="(answer, oindex) in modalForm.quesAnswer"
         :key="oindex"
         :prop="`quesAnswer.${oindex}.body`"
         :rules="answerRule"
       >
-        <div class="option-check">
-          {{ oindex + 1 }}
-        </div>
-        <div class="option-body">
-          <v-editor v-model="answer.body"></v-editor>
+        <div class="question-edit-option">
+          <div class="option-check">({{ oindex + 1 }})</div>
+          <div class="option-body">
+            <v-editor v-model="answer.body"></v-editor>
+          </div>
         </div>
       </el-form-item>
       <el-form-item label="答案解析">

+ 30 - 11
src/modules/question/components/edit/SelectQuestion.vue

@@ -7,7 +7,10 @@
       label-width="100px"
     >
       <el-form-item prop="quesBody" label="题干">
-        <v-editor v-model="modalForm.quesBody"></v-editor>
+        <v-editor
+          v-model="modalForm.quesBody"
+          @change="quesBodyChange"
+        ></v-editor>
       </el-form-item>
       <el-form-item
         v-for="(option, oindex) in modalForm.quesOptions"
@@ -21,6 +24,7 @@
               v-if="IS_SIMPLE"
               v-model="quesAnswer"
               :label="option.number"
+              @change="answerChange"
             >
               {{ (option.number - 1) | optionOrderWordFilter }}
             </el-radio>
@@ -34,7 +38,10 @@
             </el-checkbox>
           </div>
           <div class="option-body">
-            <v-editor v-model="option.body"></v-editor>
+            <v-editor
+              v-model="option.body"
+              @change="() => optionBodyChange(oindex)"
+            ></v-editor>
           </div>
           <div class="option-delete">
             <el-button
@@ -43,7 +50,7 @@
               type="primary"
               icon="el-icon-plus"
               title="新增"
-              @click.prevent="addQuesOption(index)"
+              @click.prevent="addQuesOption(oindex)"
             ></el-button>
             <el-button
               size="mini"
@@ -51,7 +58,8 @@
               type="danger"
               icon="el-icon-delete"
               title="删除"
-              @click.prevent="removeQuesOption(index)"
+              :disabled="deleleDisabled"
+              @click.prevent="removeQuesOption(oindex)"
             ></el-button>
           </div>
         </div>
@@ -143,7 +151,7 @@ export default {
       },
       optionRule: {
         validator: (rule, value, callback) => {
-          if (!value || !value.length) {
+          if (!value || isAnEmptyRichText(value)) {
             return callback(new Error(`请输入选项内容`));
           }
           callback();
@@ -163,13 +171,15 @@ export default {
         .map((value) => String.fromCharCode(64 + value))
         .join("");
     },
+    deleleDisabled() {
+      return this.modalForm.quesOptions.length === 1;
+    },
   },
   created() {
     this.initData();
   },
   methods: {
     initData() {
-      console.log("11");
       this.modalForm = this.$objAssign(
         getInitQuestionModel("SINGLE_ANSWER_QUESTION"),
         this.question
@@ -193,21 +203,29 @@ export default {
       this.resetNumberAndSaveOptions();
     },
     removeQuesOption(index) {
+      if (this.deleleDisabled) return;
       this.modalForm.quesOptions.splice(index, 1);
       this.resetNumberAndSaveOptions();
     },
     resetNumberAndSaveOptions() {
-      this.modalForm.quesOptions = this.modalForm.quesOptions.forEach(
-        (option, index) => {
-          option.number = index + 1;
-        }
-      );
+      this.modalForm.quesOptions.forEach((option, index) => {
+        option.number = index + 1;
+      });
       const optionCount = this.modalForm.quesOptions.length;
       if (this.IS_SIMPLE && this.quesAnswer > optionCount) {
         this.quesAnswer = null;
       }
       this.answerChange();
     },
+    quesBodyChange() {
+      this.$refs.modalFormComp.validateField(`quesBody`, () => {});
+    },
+    optionBodyChange(oindex) {
+      this.$refs.modalFormComp.validateField(
+        `quesOptions.${oindex}.body`,
+        () => {}
+      );
+    },
     answerChange() {
       if (this.IS_SIMPLE) {
         this.modalForm.quesAnswer = this.quesAnswer ? [this.quesAnswer] : [];
@@ -217,6 +235,7 @@ export default {
           .map((item) => item.number);
         this.modalForm.quesAnswer = this.quesAnswer;
       }
+      this.$refs.modalFormComp.validateField(`quesAnswer`, () => {});
     },
     questionInfoChange(questionInfo) {
       this.modalForm = Object.assign({}, this.modalForm, questionInfo);

+ 21 - 4
src/modules/question/components/edit/TextAnswerQuestion.vue

@@ -2,15 +2,18 @@
   <div class="text-answer-question">
     <el-form
       ref="modalFormComp"
-      :model="modelForm"
+      :model="modalForm"
       :rules="rules"
       label-width="100px"
     >
       <el-form-item prop="quesBody" label="题干">
-        <v-editor v-model="modalForm.quesBody"></v-editor>
+        <v-editor
+          v-model="modalForm.quesBody"
+          @change="quesBodyChange"
+        ></v-editor>
       </el-form-item>
       <el-form-item prop="quesAnswer" label="答案">
-        <v-editor v-model="modalForm.quesAnswer"></v-editor>
+        <v-editor v-model="quesAnswer" @change="answerChange"></v-editor>
       </el-form-item>
       <el-form-item label="答案解析">
         <v-editor v-model="modalForm.comment"></v-editor>
@@ -58,7 +61,7 @@ export default {
         quesAnswer: [
           {
             validator: (rule, value, callback) => {
-              if (!value || isAnEmptyRichText(value)) {
+              if (!this.quesAnswer || isAnEmptyRichText(this.quesAnswer)) {
                 return callback(new Error(`请输入答案`));
               }
               callback();
@@ -67,6 +70,7 @@ export default {
           },
         ],
       },
+      quesAnswer: null,
     };
   },
   created() {
@@ -78,6 +82,19 @@ export default {
         getInitQuestionModel("TEXT_ANSWER_QUESTION"),
         this.question
       );
+      this.quesAnswer = this.modalForm.quesAnswer[0] || null;
+    },
+    quesBodyChange() {
+      this.$refs.modalFormComp.validateField(`quesBody`, () => {});
+    },
+    answerChange() {
+      this.modalForm.quesAnswer = [
+        {
+          index: 1,
+          ...this.quesAnswer,
+        },
+      ];
+      this.$refs.modalFormComp.validateField(`quesAnswer`, () => {});
     },
     questionInfoChange(questionInfo) {
       this.modalForm = Object.assign({}, this.modalForm, questionInfo);

+ 14 - 21
src/modules/question/components/model/questionModel.js

@@ -34,35 +34,27 @@ export const booleanQuestion = {
 
 export const fillBlankQuestion = {
   questionType: "FILL_BLANK_QUESTION",
-  quesBody: {
-    sections: [],
-  },
+  quesBody: null,
   quesAnswer: [
-    {
-      index: 1,
-      sections: [{ blocks: [{ type: "text", value: "电纺丝技术" }] }],
-    },
-    {
-      index: 2,
-      sections: [{ blocks: [{ type: "text", value: "电纺丝技术" }] }],
-    },
+    // {
+    //   index: 1,
+    //   sections: [{ blocks: [{ type: "text", value: "" }] }],
+    // },
   ],
-  comment: { sections: [] },
+  comment: null,
 };
 
 export const textAnswerQuestion = {
   questionType: "TEXT_ANSWER_QUESTION",
-  quesBody: {
-    sections: [],
-  },
+  quesBody: null,
   // only one
   quesAnswer: [
-    {
-      index: 1,
-      sections: [{ blocks: [{ type: "text", value: "电纺丝技术" }] }],
-    },
+    // {
+    //   index: 1,
+    //   sections: [{ blocks: [{ type: "text", value: "" }] }],
+    // },
   ],
-  comment: { sections: [] },
+  comment: null,
 };
 // 完型填空/听力/阅读理解
 export const readingComprehensionQuestion = {
@@ -127,9 +119,10 @@ const models = {
 
 export const getInitQuestionModel = (qtype) => {
   return {
-    ...deepCopy(models[qtype]),
+    id: null,
     courseId: "",
     difficulty: "易",
     quesProperties: [],
+    ...deepCopy(models[qtype]),
   };
 };