zhangjie vor 2 Jahren
Ursprung
Commit
1bd4b13cdd

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

@@ -321,10 +321,10 @@ export default {
 }
 .v-editor-head {
   position: absolute;
-  left: 2px;
-  right: 2px;
+  left: 9px;
+  right: 9px;
   background-color: #fff;
-  top: 2px;
+  top: 1px;
   z-index: 9;
   border-bottom: 1px solid #f0f0f0;
 }

+ 144 - 22
src/modules/question/components/QuestionImportEdit.vue

@@ -181,7 +181,10 @@ export default {
       paperRichJson: { sections: [] },
       richTextToJSON,
       renderRichText,
-      lastScrollTop: 0,
+      lastPaperScrollTop: 0,
+      lastRichTextScrollTop: 0,
+      richTextIndexList: [],
+      scrollType: "",
       // upload answer
       uploadAnswerUrl: `${QUESTION_API}/word/parse/import`,
       uploadAnswerData: {},
@@ -194,17 +197,45 @@ export default {
   methods: {
     async visibleChange() {
       await this.getCourseProperty();
-      this.paperData = deepCopy(paperParseData);
-      this.paperRichJson = this.transformRichText(paperRichTextJson);
+
+      this.resetData({
+        richText: paperRichTextJson,
+        detailInfo: paperParseData,
+      });
+      // this.resetData(this.data);
+
+      this.$nextTick(() => {
+        this.registScrollEvent();
+      });
+    },
+    resetData({ richText, detailInfo }) {
+      this.paperData = deepCopy(detailInfo);
+      this.paperRichJson = this.transformRichText(deepCopy(richText));
       this.uploadData = { courseId: this.data.importData.courseId };
-      // this.paperRichJson = deepCopy(this.data.richText);
-      // this.paperData = deepCopy(this.data.detailInfo);
       this.transformDataInfo();
       this.questionKey = randomCode();
 
       this.$nextTick(() => {
-        this.registSrollEvent();
+        this.getRichTextIndexList();
+      });
+    },
+    getRichTextIndexList() {
+      const richTextBodyDom =
+        this.$refs.RichTextEditor.$el.querySelector(".v-editor-body");
+      let richTextIndexList = [];
+      richTextBodyDom.childNodes.forEach((sectionNode) => {
+        const id = sectionNode.getAttribute("id");
+        if (!id) return;
+        if (
+          sectionNode.className &&
+          sectionNode.className.includes("section-error")
+        )
+          return;
+
+        const index = id.replace("section-", "") * 1;
+        richTextIndexList.push([index, sectionNode.offsetTop]);
       });
+      this.richTextIndexList = richTextIndexList;
     },
     transformRichText(richText) {
       let nsections = [];
@@ -292,7 +323,7 @@ export default {
       this.paperRichJson = { sections: [] };
       window.sessionStorage.removeItem("coursePropertys");
       this.$message.closeAll();
-      this.removeSrollEvent();
+      this.removeScrollEvent();
     },
     cancel() {
       this.modalIsShow = false;
@@ -746,25 +777,36 @@ export default {
       this.$message.error(error.message);
     },
     // scroll
-    registSrollEvent() {
+    registScrollEvent() {
       document
         .getElementById("qe-part-paper")
-        .addEventListener("scroll", this.scrollEvent);
+        .addEventListener("scroll", this.paperScrollEvent);
+      this.$refs.RichTextEditor.$el
+        .querySelector(".v-editor-container")
+        .addEventListener("scroll", this.richTextScrollEvent);
     },
-    removeSrollEvent() {
+    removeScrollEvent() {
       document
         .getElementById("qe-part-paper")
-        .removeEventListener("scroll", this.scrollEvent);
+        .removeEventListener("scroll", this.paperScrollEvent);
+      this.$refs.RichTextEditor.$el
+        .querySelector(".v-editor-container")
+        .removeEventListener("scroll", this.richTextScrollEvent);
     },
-    scrollEvent(e) {
+    paperScrollEvent(e) {
       // e.preventDefault();
       // e.stopPropagation();
+      if (this.scrollType === "rich-text") return;
+      this.scrollType = "paper";
+      setTimeout(() => {
+        this.scrollType = "";
+      }, 100);
       const questionContIndexList =
         this.$refs.QuestionImportPaperEdit.questionContIndexList;
 
       const scrollTop = e.target.scrollTop;
-      const isScrollDown = scrollTop > this.lastScrollTop;
-      this.lastScrollTop = scrollTop;
+      const isScrollDown = scrollTop > this.lastPaperScrollTop;
+      this.lastPaperScrollTop = scrollTop;
       const targeContIndex = questionContIndexList.findIndex(
         (item) => scrollTop < item[3]
       );
@@ -784,7 +826,7 @@ export default {
       }
 
       const richTextSectionDom = document.getElementById(
-        `section-${targeCont[2]}`
+        `section-${targeCont[2][0]}`
       );
       if (!richTextSectionDom) return;
 
@@ -793,20 +835,18 @@ export default {
       );
       const richTextMainDom =
         this.$refs.RichTextEditor.$el.querySelector(".v-editor-main");
-      const elPos = richTextMainDom.getBoundingClientRect();
-      const textPos = richTextSectionDom.getBoundingClientRect();
-      const sectionOffsetTop = textPos.y - elPos.y;
+      const sectionOffsetTop = richTextSectionDom.offsetTop;
       let nextSectionOffsetTop = richTextMainDom.offsetHeight;
 
       if (nextTargetCont) {
         const nextRichTextSectionDom = document.getElementById(
-          `section-${nextTargetCont[2]}`
+          `section-${nextTargetCont[2][0]}`
         );
         if (nextRichTextSectionDom) {
-          const nextTextPos = nextRichTextSectionDom.getBoundingClientRect();
-          nextSectionOffsetTop = nextTextPos.y - elPos.y;
+          nextSectionOffsetTop = nextRichTextSectionDom.offsetTop;
         } else {
-          nextSectionOffsetTop = richTextSectionDom.offsetHeight;
+          nextSectionOffsetTop =
+            richTextSectionDom.offsetTop + richTextSectionDom.offsetHeight;
         }
       }
 
@@ -824,6 +864,88 @@ export default {
         ? Math.max(textScrollTop, richTextContainerDom.scrollTop)
         : Math.min(textScrollTop, richTextContainerDom.scrollTop);
     },
+    richTextScrollEvent(e) {
+      if (this.scrollType === "paper") return;
+      this.scrollType = "rich-text";
+      setTimeout(() => {
+        this.scrollType = "";
+      }, 100);
+
+      const isScrollDown = e.target.scrollTop > this.lastRichTextScrollTop;
+      this.lastRichTextScrollTop = e.target.scrollTop;
+      const offsetH = isScrollDown ? 150 : 0;
+      const scrollTop = e.target.scrollTop + offsetH;
+
+      const richTextMainDom =
+        this.$refs.RichTextEditor.$el.querySelector(".v-editor-main");
+      const questionContIndexList =
+        this.$refs.QuestionImportPaperEdit.questionContIndexList;
+
+      const findQuestionItemDom = (sectionIndex) => {
+        const questionCont = questionContIndexList.find((item) =>
+          item[2].includes(sectionIndex)
+        );
+        if (!questionCont) return;
+        const [id, type] = questionCont;
+        let itemDom = document.getElementById(id);
+        if (type === "body") {
+          itemDom = itemDom.querySelector(".ep-question-title");
+        } else if (type === "option") {
+          itemDom = itemDom.querySelector(".ep-question-body");
+        } else if (type === "answer") {
+          itemDom =
+            itemDom.querySelector(".question-info-view") ||
+            itemDom.querySelector(".ep-question-props");
+        }
+        return itemDom;
+      };
+
+      const targeContIndex = this.richTextIndexList.findIndex(
+        (item) => scrollTop < item[1]
+      );
+      if (!targeContIndex) return;
+      let targeContPercent = 0;
+      let targeCont = null;
+      let nextTargetCont = null;
+      if (targeContIndex !== -1) {
+        targeCont = this.richTextIndexList[targeContIndex - 1];
+        nextTargetCont = this.richTextIndexList[targeContIndex];
+        targeContPercent =
+          (scrollTop - targeCont[1]) / (nextTargetCont[1] - targeCont[1]);
+      } else {
+        targeCont = this.richTextIndexList.slice(-1)[0];
+        const textHeight = richTextMainDom.offsetHeight;
+        targeContPercent =
+          (scrollTop - targeCont[1]) / (textHeight - targeCont[1]);
+      }
+
+      const questionContDom = findQuestionItemDom(targeCont[0]);
+      if (!questionContDom) return;
+      const questionListDom = this.$refs.QuestionImportPaperEdit.$el;
+      const elPos = questionListDom.getBoundingClientRect();
+      const questionPos = questionContDom.getBoundingClientRect();
+      const questionContOffsetTop = questionPos.y - elPos.y;
+      let nextQuestionContOffsetTop = questionListDom.offsetHeight;
+
+      if (nextTargetCont) {
+        const nextQuestionContDom = findQuestionItemDom(nextTargetCont[0]);
+        if (nextQuestionContDom) {
+          const nextQuestionPos = nextQuestionContDom.getBoundingClientRect();
+          nextQuestionContOffsetTop = nextQuestionPos.y - elPos.y;
+        } else {
+          nextQuestionContOffsetTop =
+            questionContOffsetTop + questionContDom.offsetHeight;
+        }
+      }
+
+      const questionScrollTop =
+        questionContOffsetTop +
+        targeContPercent * (nextQuestionContOffsetTop - questionContOffsetTop);
+      const questionContainerDom = document.getElementById("qe-part-paper");
+      questionContainerDom.scrollTop = isScrollDown
+        ? Math.max(questionScrollTop, questionContainerDom.scrollTop)
+        : Math.min(questionScrollTop, questionContainerDom.scrollTop);
+    },
   },
 };
 </script>

+ 25 - 9
src/modules/question/components/QuestionImportPaperEdit.vue

@@ -43,6 +43,7 @@ import TextAnswerQuestion from "./import-edit/TextAnswerQuestion.vue";
 import NestedQuestion from "./import-edit/NestedQuestion.vue";
 import BankedClozeQuestion from "./import-edit/BankedClozeQuestion.vue";
 import { STRUCT_TYPE_COMP_DICT } from "./edit/questionModel";
+import { mapState } from "vuex";
 
 export default {
   name: "QuestionExportPaperEdit",
@@ -72,11 +73,19 @@ export default {
       questionContIndexList: [],
     };
   },
+  computed: {
+    ...mapState("import-edit", ["curQuestion"]),
+  },
+  watch: {
+    curQuestion(val, oldval) {
+      if (val && oldval && val.id !== oldval.id)
+        this.updateQuestionContIndexTop();
+    },
+  },
   mounted() {
     this.transformPaperData();
     this.$nextTick(() => {
       this.updateQuestionContIndexTop();
-      console.log(this.questionContIndexList);
     });
   },
   methods: {
@@ -99,14 +108,21 @@ export default {
       const indexItems = ["bodyIndex", "optionIndex", "answerIndex"];
       let itemList = [];
       indexItems.forEach((item) => {
-        const indexs = questionIndex[item];
+        let indexs = questionIndex[item];
+
+        if (item === "answerIndex") {
+          indexs = [];
+          ["answerIndex", "difficultIndex", "propertyIndex"].forEach(
+            (field) => {
+              if (questionIndex[field] && questionIndex[field].length) {
+                indexs.push(...questionIndex[field]);
+              }
+            }
+          );
+        }
+
         if (indexs && indexs.length) {
-          itemList.push([
-            questionId,
-            item.replace("Index", ""),
-            indexs[0],
-            null,
-          ]);
+          itemList.push([questionId, item.replace("Index", ""), indexs, null]);
         }
       });
 
@@ -120,7 +136,7 @@ export default {
         questionContIndexList.push([
           `detail-${dIndex}`,
           "detail",
-          detail.detailIndex[0],
+          detail.detailIndex,
           null,
         ]);
         detail.questions.forEach((question) => {