zhangjie %!s(int64=2) %!d(string=hai) anos
pai
achega
283628e3db

+ 61 - 0
src/components/ModifyRichText.vue

@@ -0,0 +1,61 @@
+<template>
+  <el-dialog
+    :title="title"
+    :visible.sync="modalIsShow"
+    width="520px"
+    :modal="false"
+    append-to-body
+    custom-class="side-dialog"
+    @open="visibleChange"
+  >
+    <v-editor
+      v-model="editCont"
+      placeholder="请输入"
+      :enable-formula="false"
+    ></v-editor>
+
+    <div slot="footer">
+      <el-button type="primary" @click="confirm">保存</el-button>
+      <el-button type="danger" plain @click="cancel">返回</el-button>
+    </div>
+  </el-dialog>
+</template>
+
+<script>
+export default {
+  name: "ModifyRichText",
+  props: {
+    content: {
+      type: Object,
+      default() {
+        return {};
+      },
+    },
+    title: {
+      type: String,
+      default: "",
+    },
+  },
+  data() {
+    return {
+      modalIsShow: false,
+      editCont: "",
+    };
+  },
+  methods: {
+    visibleChange() {
+      this.editCont = this.content;
+    },
+    cancel() {
+      this.modalIsShow = false;
+    },
+    open() {
+      this.modalIsShow = true;
+    },
+    confirm() {
+      this.$emit("modified", this.editCont);
+      this.cancel();
+    },
+  },
+};
+</script>

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

@@ -70,3 +70,36 @@ export const paperBaseInfoApi = ({ paperId }) => {
     },
   });
 };
+export const paperDetailUpdateApi = (paperId, datas) => {
+  return $httpWithMsg.post(
+    `${QUESTION_API}/updatePaperDetail/${paperId}`,
+    datas
+  );
+};
+export const paperDetailMoveApi = ({ paperId, detailId, vector }) => {
+  return $httpWithMsg.put(
+    `${QUESTION_API}/paperDetail/${paperId}/${detailId}/${vector}`,
+    {}
+  );
+};
+export const paperDetailDeleteApi = ({ paperId, detailId }) => {
+  return $httpWithMsg.delete(
+    `${QUESTION_API}/paperDetail/${paperId}/${detailId}`,
+    {}
+  );
+};
+export const paperQuestionMoveApi = ({ detailId, unitid, vector }) => {
+  return $httpWithMsg.put(
+    `${QUESTION_API}/paperDetailUnit/${detailId}/${unitid}/${vector}`,
+    {}
+  );
+};
+export const paperQuestionDeleteApi = (unitid) => {
+  return $httpWithMsg.delete(`${QUESTION_API}/paperDetailUnit/${unitid}`, {});
+};
+export const paperQuestionUnitDeleteApi = ({ unitid, questionId }) => {
+  return $httpWithMsg.delete(
+    `${QUESTION_API}/paper/deleteQuestion/${unitid}/${questionId}`,
+    {}
+  );
+};

+ 3 - 3
src/modules/paper/components/BuildPaperAuto.vue

@@ -42,8 +42,8 @@
             ></el-button>
           </div>
         </div>
-        <div v-if="detail.remark" class="detail-desc">
-          <rich-text :text-json="detail.remark"></rich-text>
+        <div v-if="detail.description" class="detail-desc">
+          <rich-text :text-json="detail.description"></rich-text>
         </div>
         <table class="table detail-info">
           <tr>
@@ -89,7 +89,7 @@ export default {
         {
           id: "32qk2guo99mg24no",
           name: "单项选择题",
-          remark: {
+          description: {
             sections: [
               {
                 blocks: [

+ 2 - 2
src/modules/paper/components/BuildPaperManual.vue

@@ -41,8 +41,8 @@
             ></el-button>
           </div>
         </div>
-        <div v-if="detail.remark" class="detail-desc">
-          <rich-text :text-json="detail.remark"></rich-text>
+        <div v-if="detail.description" class="detail-desc">
+          <rich-text :text-json="detail.description"></rich-text>
         </div>
         <div class="detail-questions">
           <template v-for="(question, qindex) in detail.questions">

+ 9 - 5
src/modules/paper/components/ModifyDetailStruct.vue

@@ -21,19 +21,19 @@
           placeholder="请输入题型名称"
         ></el-input>
       </el-form-item>
-      <el-form-item label="大题描述" prop="remark">
+      <el-form-item label="大题描述" prop="description">
         <v-editor
-          v-model="modalForm.remark"
+          v-model="modalForm.description"
           placeholder="请输入大题描述"
           :enable-formula="false"
         ></v-editor>
       </el-form-item>
-      <el-form-item label="题型" prop="questionType">
+      <el-form-item v-if="!onlyName" label="题型" prop="questionType">
         <question-type-select
           v-model="modalForm.questionType"
         ></question-type-select>
       </el-form-item>
-      <el-form-item label="每题分值" prop="scorePerQuestion">
+      <el-form-item v-if="!onlyName" label="每题分值" prop="scorePerQuestion">
         <el-input-number
           v-model="modalForm.scorePerQuestion"
           placeholder="请输入每题分值"
@@ -59,7 +59,7 @@ import { randomCode } from "@/plugins/utils";
 const initModalForm = {
   id: null,
   name: "",
-  remark: "",
+  description: "",
   questionType: null,
   scorePerQuestion: 1,
 };
@@ -72,6 +72,10 @@ export default {
         return {};
       },
     },
+    onlyName: {
+      type: Boolean,
+      default: false,
+    },
   },
   data() {
     return {

+ 285 - 98
src/modules/paper/views/EditPaper.vue

@@ -139,7 +139,7 @@
                 type="primary"
                 plain
                 size="small"
-                @click="openEditExamPaperRemark"
+                @click="toEditExamRemark"
                 >编辑</el-button
               >
             </div>
@@ -153,8 +153,7 @@
       <!-- 循环大题 -->
       <div
         v-for="(paperDetail, detailIndex) in paper.paperDetails"
-        v-show="paperDetailShow(paperDetail)"
-        :key="detailIndex"
+        :key="paperDetail.id"
         class="edit-part-list"
       >
         <div class="edit-part">
@@ -178,57 +177,54 @@
             ></rich-text>
             <div class="edit-cont-action">
               <el-button
-                v-show="parentView == 'gen_paper'"
+                v-show="parentView === 'gen_paper'"
                 size="small"
                 type="primary"
                 plain
-                @click="selectQues(paperDetail.id)"
+                @click="toSelectPaperDetailQues(paperDetail)"
                 >选题
               </el-button>
               <el-button
                 size="small"
                 type="primary"
                 plain
-                @click="openEditPaperDetail(paperDetail)"
+                @click="toEditPaperDetail(paperDetail)"
                 >编辑
               </el-button>
               <el-button
-                v-if="showUp(paperDetail)"
+                v-if="!detailIndex"
                 size="small"
                 type="primary"
                 plain
-                @click="movePaperDetail(paperDetail, 'up')"
+                @click="toMovePaperDetail(paperDetail, 'up')"
                 >上移
               </el-button>
               <el-button
-                v-if="showDown(paperDetail)"
+                v-if="detailIndex < paper.paperDetails.length - 1"
                 size="small"
                 type="primary"
                 plain
-                @click="movePaperDetail(paperDetail, 'down')"
+                @click="toMovePaperDetail(paperDetail, 'down')"
                 >下移
               </el-button>
               <el-button
                 size="small"
                 type="danger"
-                @click="deletePaperDetail(paperDetail.id)"
+                @click="toDeletePaperDetail(paperDetail)"
                 >删除
               </el-button>
               <el-button
-                v-show="showButtons[detailIndex].up"
                 size="small"
                 type="primary"
                 plain
-                icon="el-icon-arrow-up"
-                @click.stop="hideContent(detailIndex)"
-              ></el-button>
-              <el-button
-                v-show="!showButtons[detailIndex].up"
-                size="small"
-                icon="el-icon-arrow-down"
-                type="primary"
-                plain
-                @click.stop="showContent(detailIndex)"
+                :icon="
+                  paperDetail.showQuestions
+                    ? 'el-icon-arrow-up'
+                    : 'el-icon-arrow-down'
+                "
+                @click.stop="
+                  paperDetail.showQuestions = !paperDetail.showQuestions
+                "
               ></el-button>
             </div>
           </div>
@@ -252,15 +248,11 @@
           </div>
         </div>
         <!-- 循环小题 -->
-        <div
-          v-show="showQuestions[detailIndex].is_show"
-          class="edit-paper-questions"
-        >
+        <div v-show="paperDetail.showQuestions" class="edit-paper-questions">
           <template
             v-for="(paperDetailUnit, unitIndex) in paperDetail.paperDetailUnits"
           >
             <div
-              v-show="quesShow(paperDetailUnit.id)"
               :key="`question-${unitIndex}`"
               :class="[
                 'edit-part',
@@ -310,69 +302,56 @@
                     size="small"
                     type="primary"
                     plain
-                    @click="checkDuplicateQuestion(paperDetailUnit.question.id)"
+                    @click="
+                      toCheckDuplicateQuestion(paperDetailUnit.question.id)
+                    "
                     >进入查重
                   </el-button>
                   <el-button
                     size="small"
                     type="primary"
                     plain
-                    @click="editQues(paperDetailUnit, paperDetailUnit.question)"
+                    @click="toEditQues(paperDetailUnit)"
                     >编辑
                   </el-button>
                   <el-button
-                    v-if="showUnitUp(paperDetail, paperDetailUnit.id)"
+                    v-if="!unitIndex"
                     size="small"
                     type="primary"
                     plain
                     @click="
-                      movePaperDetailUnit(
-                        paperDetail.id,
-                        paperDetailUnit.id,
-                        'up'
-                      )
+                      toMoveQues(paperDetail.id, paperDetailUnit.id, 'up')
                     "
                     >上移
                   </el-button>
                   <el-button
-                    v-if="showUnitDown(paperDetail, paperDetailUnit.id)"
+                    v-if="unitIndex < paperDetail.paperDetailUnits.length"
                     size="small"
                     type="primary"
                     plain
                     @click="
-                      movePaperDetailUnit(
-                        paperDetail.id,
-                        paperDetailUnit.id,
-                        'down'
-                      )
+                      toMoveQues(paperDetail.id, paperDetailUnit.id, 'down')
                     "
                     >下移
                   </el-button>
                   <el-button
                     type="danger"
                     size="small"
-                    @click="deleteQues(paperDetailUnit)"
+                    @click="toDeleteQues(paperDetailUnit)"
                     >删除
                   </el-button>
                   <el-button
-                    v-show="
-                      isNested(paperDetailUnit.questionType) &&
-                      showSubButtons[detailIndex + '-' + unitIndex]
-                    "
+                    v-if="isNested(paperDetailUnit.questionType)"
                     size="small"
-                    icon="el-icon-arrow-up"
-                    @click.stop="hideSubContent(detailIndex + '-' + unitIndex)"
-                  ></el-button>
-                  <el-button
-                    v-show="
-                      isNested(paperDetailUnit.questionType) &&
-                      !showSubButtons[detailIndex + '-' + unitIndex]
+                    :icon="
+                      paperDetailUnit.showSubQuestions
+                        ? 'el-icon-arrow-up'
+                        : 'el-icon-arrow-down'
+                    "
+                    @click.stop="
+                      paperDetailUnit.showSubQuestions =
+                        !paperDetailUnit.showSubQuestions
                     "
-                    size="small"
-                    type="primary"
-                    plain
-                    icon="el-icon-arrow-down"
-                    @click.stop="showSubContent(detailIndex + '-' + unitIndex)"
                   ></el-button>
                 </div>
               </div>
@@ -397,14 +376,14 @@
               </div>
             </div>
             <div
-              v-show="showSubQuestions[detailIndex + '-' + unitIndex]"
+              v-if="isNested(paperDetailUnit.questionType)"
+              v-show="paperDetailUnit.showSubQuestions"
               :key="`question-sub-${unitIndex}`"
               class="edit-paper-question-subs"
             >
               <div
                 v-for="(subQuestion, subIndex) in paperDetailUnit.question
                   .subQuestions"
-                v-show="quesShow(subQuestion.id)"
                 :key="subIndex"
                 class="edit-part"
               >
@@ -438,43 +417,6 @@
                     <question-answer :data="subQuestion"></question-answer>
                     <!-- <rich-text :text-json="subQuestion.quesAnswer"></rich-text> -->
                   </div>
-                  <div class="edit-cont-action">
-                    <el-button
-                      size="small"
-                      type="primary"
-                      plain
-                      @click="editQues(paperDetailUnit, subQuestion)"
-                      >编辑
-                    </el-button>
-                    <el-button
-                      v-if="showUnitSubUp(paperDetailUnit, subQuestion.id)"
-                      size="small"
-                      type="primary"
-                      plain
-                      @click="
-                        movePaperDetailUnitSub(
-                          paperDetailUnit.id,
-                          subQuestion.id,
-                          'up'
-                        )
-                      "
-                      >上移
-                    </el-button>
-                    <el-button
-                      v-if="showUnitSubDown(paperDetailUnit, subQuestion.id)"
-                      size="small"
-                      type="primary"
-                      plain
-                      @click="
-                        movePaperDetailUnitSub(
-                          paperDetailUnit.id,
-                          subQuestion.id,
-                          'down'
-                        )
-                      "
-                      >下移
-                    </el-button>
-                  </div>
                 </div>
                 <div v-show="quesTagShow" class="edit-property">
                   <div class="edit-property-box">
@@ -501,6 +443,19 @@
       </div>
     </div>
 
+    <!-- 编辑考试说明 -->
+    <modify-rich-text
+      ref="ModifyRichText"
+      :content="paper.examRemark"
+      @modified="examRemarkModified"
+    ></modify-rich-text>
+    <!-- 编辑大题弹框 -->
+    <modify-detail-struct
+      ref="ModifyDetailStruct"
+      :detail="curDetail"
+      only-name
+      @modified="detailModified"
+    ></modify-detail-struct>
     <!-- 基础构成 -->
     <paper-base-info ref="PaperBaseInfo" :paper-id="paperId"></paper-base-info>
     <!-- 题型分布 -->
@@ -523,13 +478,25 @@
 </template>
 
 <script>
-import { paperDetailInfoApi, paperSaveApi, paperDeleteApi } from "../api";
+import {
+  paperDetailInfoApi,
+  paperSaveApi,
+  paperDeleteApi,
+  paperDetailUpdateApi,
+  paperDetailMoveApi,
+  paperDetailDeleteApi,
+  paperQuestionMoveApi,
+  paperQuestionDeleteApi,
+  paperQuestionUnitDeleteApi,
+} from "../api";
 import { QUESTION_API } from "@/constants/constants";
 
 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";
 
 export default {
   name: "EditPaper",
@@ -538,6 +505,8 @@ export default {
     PaperQuestypeInfo,
     PaperAuditInfo,
     PaperBlueInfo,
+    ModifyDetailStruct,
+    ModifyRichText,
   },
   data() {
     return {
@@ -557,6 +526,7 @@ export default {
       checkDuplicateBtnShow: false,
       quesTagShow: false,
       quesAnswerShow: false,
+      curDetail: {},
     };
   },
   computed: {
@@ -693,6 +663,223 @@ export default {
         },
       });
     },
+    // header-action ----end
+    // 考试说明
+    toEditExamRemark() {
+      this.$refs.ModifyRichText.open();
+    },
+    examRemarkModified(content) {
+      this.paper.examRemark = content;
+      this.toSavePaper();
+    },
+    // detail-action
+    toSelectPaperDetailQues(detail) {
+      this.$router.push({
+        path:
+          "/select_question/" +
+          this.paper.id +
+          "/" +
+          this.paper.course.id +
+          "/" +
+          detail.id +
+          "/" +
+          this.parentView,
+      });
+    },
+    // 大题编辑
+    toEditPaperDetail(detail) {
+      this.curDetail = detail;
+      this.$refs.ModifyDetailStruct.open();
+    },
+    async detailModified(detail) {
+      const res = await paperDetailUpdateApi(this.paperId, detail).catch(
+        (error) => {
+          this.$notify({
+            type: "error",
+            message: error.response.data.desc,
+          });
+        }
+      );
+
+      if (!res) return;
+      this.$message.success("修改成功!");
+
+      const paperDetail = this.paper.paperDetails.find(
+        (item) => item.id === detail.id
+      );
+      if (!paperDetail) return;
+      paperDetail.name = detail.name;
+      paperDetail.description = detail.description;
+    },
+    // 移动大题
+    async toMovePaperDetail(detail, vector) {
+      const vectorStr = vector == "up" ? "上移" : "下移";
+      const confirm = await this.$confirm(
+        `确定要${vectorStr}该大题吗?`,
+        "提示",
+        {
+          type: "warning",
+        }
+      ).catch(() => {});
+      if (confirm !== "confirm") return;
+
+      const res = await paperDetailMoveApi({
+        paperId: this.paperId,
+        detailId: detail.id,
+        vector,
+      }).catch((error) => {
+        this.$notify({
+          type: "error",
+          message: error.response.data.desc,
+        });
+      });
+
+      if (!res) return;
+      this.$message.success("操作成功!");
+      this.initPaper();
+    },
+    // 删除大题
+    async toDeletePaperDetail(detail) {
+      if (detail.paperDetailUnits.length) {
+        this.$message.error("大题下还有小题,不可删除!");
+        return;
+      }
+
+      const confirm = await this.$confirm(`确定要删除该大题吗?`, "提示", {
+        type: "warning",
+      }).catch(() => {});
+      if (confirm !== "confirm") return;
+
+      const res = await paperDetailDeleteApi({
+        paperId: this.paperId,
+        detailId: detail.id,
+      }).catch((error) => {
+        this.$notify({
+          type: "error",
+          message: error.response.data.desc,
+        });
+      });
+
+      if (!res) return;
+      this.$message.success("操作成功!");
+      this.initPaper();
+    },
+    // detail-action ----end
+    // question-action
+    toCheckDuplicateQuestion(questionId) {
+      this.$router.push({
+        name: "check_duplicate_info",
+        query: {
+          quesId: questionId,
+          basePaperId: this.paperId,
+          from: "paper",
+        },
+      });
+    },
+    toEditQues() {},
+    // 移动小题
+    async toMoveQues(detailId, unitid, vector) {
+      const vectorStr = vector == "up" ? "上移" : "下移";
+      const confirm = await this.$confirm(
+        `确定要${vectorStr}该小题吗?`,
+        "提示",
+        {
+          type: "warning",
+        }
+      ).catch(() => {});
+      if (confirm !== "confirm") return;
+
+      const res = await paperQuestionMoveApi({
+        detailId,
+        unitid,
+        vector,
+      }).catch((error) => {
+        this.$notify({
+          type: "error",
+          message: error.response.data.desc,
+        });
+      });
+
+      if (!res) return;
+      this.$message.success("操作成功!");
+      this.initPaper();
+    },
+    // 删除小题
+    async toDeleteQues(paperDetailUnit) {
+      const confirm = await this.$confirm(`确定要删除该题吗?`, "提示", {
+        type: "warning",
+      }).catch(() => {});
+      if (confirm !== "confirm") return;
+
+      if (this.paper.paperType == "GENERATE") {
+        const res = await paperQuestionDeleteApi(paperDetailUnit.id).catch(
+          (error) => {
+            this.$notify({
+              type: "error",
+              message: error.response.data.desc,
+            });
+          }
+        );
+        if (!res) return;
+      } else {
+        let questionId = paperDetailUnit.question.id;
+        const res = await paperQuestionUnitDeleteApi({
+          unitid: paperDetailUnit.id,
+          questionId,
+        }).catch((error) => {
+          this.$notify({
+            type: "error",
+            message: error.response.data.desc,
+          });
+        });
+        if (!res) return;
+      }
+
+      this.$message.success("操作成功!");
+      this.initPaper();
+    },
+
+    // other
+    isNested(questionType) {
+      if (
+        questionType == "PARAGRAPH_MATCHING" ||
+        questionType == "BANKED_CLOZE" ||
+        questionType == "CLOZE" ||
+        questionType == "READING_COMPREHENSION" ||
+        questionType == "LISTENING_QUESTION"
+      ) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    isMatchingQuestion(questionType) {
+      if (
+        questionType == "PARAGRAPH_MATCHING" ||
+        questionType == "BANKED_CLOZE"
+      ) {
+        return true;
+      } else {
+        return false;
+      }
+    },
+    isInOtherSelect(optIndex, quesModel) {
+      if (quesModel.parentQuesParam.matchingMode != 1) {
+        return false;
+      }
+      if (!quesModel.optionsSelected) {
+        return false;
+      }
+      if (!quesModel.optionsSelected[optIndex + 1]) {
+        return false;
+      }
+      if (
+        quesModel.optionsSelected[optIndex + 1].includes(quesModel.subNumber)
+      ) {
+        return false;
+      }
+      return true;
+    },
   },
 };
 </script>