Quellcode durchsuchen

试卷编辑修改

zhangjie vor 2 Jahren
Ursprung
Commit
6d0d627559

+ 6 - 2
src/components/ImportFileDialog.vue

@@ -106,6 +106,10 @@ export default {
       type: String,
       default: "filename",
     },
+    addFileParam: {
+      type: String,
+      default: "file",
+    },
     templateUrl: {
       type: String,
       default: "",
@@ -182,7 +186,7 @@ export default {
       Object.entries(options.data).forEach(([k, v]) => {
         formData.append(k, v);
       });
-      formData.append("file", options.file);
+      formData.append(this.addFileParam, options.file);
 
       return $httpWithMsg.post(options.action, formData, {
         headers: options.headers,
@@ -238,7 +242,7 @@ export default {
       this.$refs.UploadComp.clearFiles();
     },
     exportFile() {
-      window.location.href = this.templateUrl;
+      window.open(this.templateUrl);
     },
   },
 };

+ 3 - 0
src/modules/paper/api.js

@@ -73,6 +73,9 @@ export const paperSaveApi = (paper) => {
 export const paperDeleteApi = (paperId) => {
   return $httpWithMsg.delete(`${QUESTION_API}/paper/${paperId}`, {});
 };
+export const paperQuestionSaveApi = (questionUnit) => {
+  return $httpWithMsg.put(`${QUESTION_API}/paperDetailUnit`, questionUnit);
+};
 
 // paper-info
 export const paperAuditInfoApi = ({ paperId, curPage, pageSize }) => {

+ 81 - 4
src/modules/paper/views/EditPaper.vue

@@ -65,6 +65,13 @@
           >
             进入查重
           </el-button>
+          <el-button
+            size="small"
+            type="primary"
+            plain
+            @click="toImportPaperAnswer"
+            >导入答案</el-button
+          >
           <el-button
             size="small"
             type="primary"
@@ -192,7 +199,7 @@
                 >编辑
               </el-button>
               <el-button
-                v-if="!detailIndex"
+                v-if="detailIndex"
                 size="small"
                 type="primary"
                 plain
@@ -315,7 +322,7 @@
                     >编辑
                   </el-button>
                   <el-button
-                    v-if="!unitIndex"
+                    v-if="unitIndex"
                     size="small"
                     type="primary"
                     plain
@@ -389,7 +396,7 @@
               >
                 <div class="edit-cont">
                   <div class="edit-cont-title">
-                    <span>{{ subQuestion.subNumber }}. </span>
+                    <span>{{ subIndex + 1 }}. </span>
                     <rich-text :text-json="subQuestion.quesBody"></rich-text>
                     <span
                       >({{ paperDetailUnit.subScoreList[subIndex] }}分)</span
@@ -458,6 +465,15 @@
     ></modify-detail-struct>
     <!-- 基础构成 -->
     <paper-base-info ref="PaperBaseInfo" :paper-id="paperId"></paper-base-info>
+    <!-- 上传答案文件 -->
+    <import-file-dialog
+      ref="ImportAnswerDialog"
+      dialog-title="上传答案文件"
+      :template-url="answerTemplateUrl"
+      :upload-url="uploadAnswerUrl"
+      add-file-param="dataFile"
+      @uploaded="initPaper"
+    ></import-file-dialog>
     <!-- 题型分布 -->
     <paper-questype-info
       ref="PaperQuestypeInfo"
@@ -474,6 +490,12 @@
       ref="PaperAuditInfo"
       :paper-id="paperId"
     ></paper-audit-info>
+    <!-- 试题编辑  -->
+    <question-edit-dialog
+      ref="QuestionEditDialog"
+      :question="curQuestion"
+      @modified="questionEdited"
+    ></question-edit-dialog>
   </div>
 </template>
 
@@ -488,15 +510,19 @@ import {
   paperQuestionMoveApi,
   paperQuestionDeleteApi,
   paperQuestionUnitDeleteApi,
+  paperQuestionSaveApi,
 } from "../api";
 import { QUESTION_API } from "@/constants/constants";
 
+import ImportFileDialog from "@/components/ImportFileDialog.vue";
 import PaperBaseInfo from "../components/PaperBaseInfo.vue";
 import PaperQuestypeInfo from "../components/PaperQuestypeInfo.vue";
 import PaperBlueInfo from "../components/PaperBlueInfo.vue";
 import PaperAuditInfo from "../components/PaperAuditInfo.vue";
 import ModifyDetailStruct from "../components/ModifyDetailStruct.vue";
 import ModifyRichText from "@/components/ModifyRichText.vue";
+import QuestionEditDialog from "../../question/components/QuestionEditDialog.vue";
+import { calcSum } from "@/plugins/utils";
 
 export default {
   name: "EditPaper",
@@ -507,6 +533,8 @@ export default {
     PaperBlueInfo,
     ModifyDetailStruct,
     ModifyRichText,
+    QuestionEditDialog,
+    ImportFileDialog,
   },
   data() {
     return {
@@ -527,6 +555,10 @@ export default {
       quesTagShow: false,
       quesAnswerShow: false,
       curDetail: {},
+      curQuestion: {},
+      // upload answer
+      uploadAnswerUrl: "",
+      answerTemplateUrl: "",
     };
   },
   computed: {
@@ -618,6 +650,13 @@ export default {
       window.history.go(-1);
       this.toBack();
     },
+    // 导入答案
+    toImportPaperAnswer() {
+      const { key, token } = this.user;
+      this.answerTemplateUrl = `${QUESTION_API}/paper/answer/template?$key=${key}&$token=${token}`;
+      this.uploadAnswerUrl = `${QUESTION_API}/paper/answer/import/${this.paperId}`;
+      this.$refs.ImportAnswerDialog.open();
+    },
     // 导出答案
     toExportPaperAnswer() {
       const { key, token } = this.user;
@@ -776,7 +815,45 @@ export default {
         },
       });
     },
-    toEditQues() {},
+    toEditQues(row) {
+      let question = row.question;
+      const courseInfo = {
+        courseId: question.course.id,
+        courseCode: question.course.code,
+        courseName: question.course.name,
+      };
+      let curQuestion = {
+        ...question,
+        ...courseInfo,
+        score: row.score,
+        editMode: "paper",
+        questionUnitId: row.id,
+      };
+      if (curQuestion.subQuestions && curQuestion.subQuestions.length) {
+        curQuestion.subQuestions = curQuestion.subQuestions.map((q) => {
+          return { ...q, ...courseInfo, editMode: "paper" };
+        });
+      }
+      this.curQuestion = curQuestion;
+
+      this.$refs.QuestionEditDialog.open();
+    },
+    async questionEdited(question) {
+      if (question.subQuestions && question.subQuestions.length) {
+        question.score = calcSum(
+          question.subQuestions.map((item) => item.score || 0)
+        );
+      }
+      let questionUnit = {
+        id: this.curQuestion.questionUnitId,
+        question,
+        score: question.score,
+      };
+      const res = await paperQuestionSaveApi(questionUnit).catch(() => {});
+      if (!res) return;
+      this.$message.success("保存成功!");
+      this.initPaper();
+    },
     // 移动小题
     async toMoveQues(detailId, unitid, vector) {
       const vectorStr = vector == "up" ? "上移" : "下移";

+ 6 - 0
src/modules/question/components/QuestionEditDialog.vue

@@ -259,6 +259,12 @@ export default {
       this.loading = true;
 
       this.questionModel = this.$refs.QuestionEditDetail.getData();
+      if (this.question.editMode === "paper") {
+        this.$emit("modified", this.questionModel);
+        this.loading = false;
+        this.close();
+        return;
+      }
       const res = await updateQuestionApi(this.questionModel).catch(() => {});
       this.loading = false;
       if (!res) return;

+ 40 - 4
src/modules/question/components/QuestionInfoEdit.vue

@@ -1,6 +1,6 @@
 <template>
   <div class="question-info-edit">
-    <el-form label-width="100px">
+    <el-form label-width="100px" inline>
       <el-form-item label="难度">
         <el-select
           v-model="modalForm.difficulty"
@@ -16,7 +16,30 @@
           </el-option>
         </el-select>
       </el-form-item>
-
+      <el-form-item v-if="IS_PAPER_MODE" label="分值" label-width="50px">
+        <el-input-number
+          v-model="modalForm.score"
+          placeholder="分值"
+          :precision="1"
+          :min="0"
+          :max="999"
+          :step="0.1"
+          step-strictly
+          :controls="false"
+        ></el-input-number>
+      </el-form-item>
+      <el-form-item v-if="IS_PAPER_MODE" label="时长" label-width="50px">
+        <el-input-number
+          v-model="modalForm.control.maxAnswerTime"
+          :precision="0"
+          :min="1"
+          :max="999"
+          :step="1"
+          step-strictly
+          :controls="false"
+        ></el-input-number>
+      </el-form-item>
+      <br />
       <el-form-item prop="quesProperties" label="属性名">
         <div class="box-flex">
           <property-select
@@ -24,14 +47,14 @@
             :course-id="modalForm.courseId"
             @change="coursePropertyChange"
           ></property-select>
-          <span class="margin-lr-10">一级</span>
+          <span style="margin: 0 12px 0 18px">一级</span>
           <property-sub-select
             v-model="properties.firstPropertyId"
             :parent-id="properties.coursePropertyId"
             data-type="first"
             @change="firstPropertyChange"
           ></property-sub-select>
-          <span class="margin-lr-10">二级</span>
+          <span style="margin: 0 12px 0 18px">二级</span>
           <property-sub-select
             v-model="properties.secondPropertyId"
             :parent-id="properties.firstPropertyId"
@@ -48,6 +71,7 @@
           >
         </div>
       </el-form-item>
+      <br />
       <el-form-item label="属性列表">
         <el-tag
           v-for="content in modalForm.quesProperties"
@@ -77,9 +101,12 @@
 import { DIFFICULTY_LIST } from "@/constants/constants";
 
 const initModalForm = {
+  editMode: "question",
   courseId: "",
   difficulty: "易",
   quesProperties: [],
+  score: 0,
+  control: { maxAnswerTime: 0 },
 };
 
 export default {
@@ -116,6 +143,9 @@ export default {
         this.properties.coursePropertyId && this.properties.firstPropertyId
       );
     },
+    IS_PAPER_MODE() {
+      return this.modalForm.editMode === "paper";
+    },
   },
   mounted() {
     this.initData();
@@ -123,6 +153,12 @@ export default {
   methods: {
     initData() {
       let modalForm = this.$objAssign(initModalForm, this.question);
+      if (modalForm.editMode === "paper" && this.question.control) {
+        modalForm.control = this.$objAssign(
+          initModalForm.control,
+          this.question.control
+        );
+      }
       if (modalForm.quesProperties && modalForm.quesProperties.length) {
         modalForm.quesProperties.forEach((item) => {
           let ids = [item.courseProperty.id, item.firstProperty.id];

+ 15 - 0
src/modules/question/components/edit/BankedClozeQuestion.vue

@@ -51,6 +51,17 @@
           </div>
         </div>
       </el-form-item>
+      <el-form-item label="答题模式">
+        <el-select v-model="modalForm.quesParam.matchingMode">
+          <el-option
+            v-for="item in matchingModes"
+            :key="item.value"
+            :label="item.label"
+            :value="item.value"
+          >
+          </el-option>
+        </el-select>
+      </el-form-item>
     </el-form>
 
     <el-collapse v-model="activeNames">
@@ -141,6 +152,10 @@ export default {
         },
         trigger: "change",
       },
+      matchingModes: [
+        { label: "单用", value: 1 },
+        { label: "复用", value: 2 },
+      ],
     };
   },
   computed: {

+ 5 - 1
src/modules/question/components/model/questionModel.js

@@ -87,8 +87,9 @@ export const bankedClozeQuestion = {
       optionBody: null,
     },
   ],
-  param: { matchingMode: 1, matchingType: 1 },
+  quesParam: { matchingMode: 1, matchingType: 1 },
   // 段落匹配: "param": { "matchingMode": 2, "matchingType": 2 },
+  // matchingType是配对题的属性,目前系统应该是用不到了
   // quesAnswer: [{ number: 1, answer: [8] }],
 };
 
@@ -121,6 +122,9 @@ export const getInitQuestionModel = (qtype) => {
     courseId: "",
     difficulty: "易",
     quesProperties: [],
+    editMode: "question",
+    score: 0,
+    control: { maxAnswerTime: 0 },
     ...deepCopy(models[qtype]),
   };
 };

+ 2 - 2
src/modules/questions/routes/routes.js

@@ -18,8 +18,8 @@ import Question from "../views/Question.vue";
 import EditSelectQuestion from "../views/EditSelectQuestion.vue";
 import EditOtherQuestion from "../views/EditOtherQuestion.vue";
 import InsertPaperTitle from "../views/InsertPaperTitle.vue";
-import EditPaper from "../views/EditPaper.vue";
-// import EditPaper from "../../paper/views/EditPaper.vue";
+// import EditPaper from "../views/EditPaper.vue";
+import EditPaper from "../../paper/views/EditPaper.vue";
 import PreviewPaper from "../views/PreviewPaper.vue";
 import SelectQuestion from "../views/SelectQuestion.vue";
 import Tips from "../../portal/views/tips/Tips.vue";