闫增涛
2024-10-24 2715c0cd96a13dd36297195f4118db4c0e189cbc
src/books/mathBook/view/components/index.vue
@@ -18,31 +18,57 @@
      <chapterOne
        v-if="showCatalogList.indexOf(2) > -1"
        :showPageList="loadPageList"
      ></chapterOne>
        :questionData="questionDataMap"
      >
      </chapterOne>
      <chapterTwo
        v-if="showCatalogList.indexOf(3) > -1"
        :showPageList="loadPageList"
        :questionData="questionDataMap"
      >
      </chapterTwo>
      <chapterThree
        v-if="showCatalogList.indexOf(4) > -1"
        :showPageList="loadPageList"
        :questionData="questionDataMap"
      >
      </chapterThree>
      <chapterFour
        v-if="showCatalogList.indexOf(5) > -1"
        :showPageList="loadPageList"
        :questionData="questionDataMap"
      >
      </chapterFour>
      <chapterFive
        v-if="showCatalogList.indexOf(6) > -1"
        :showPageList="loadPageList"
        :questionData="questionDataMap"
      >
      </chapterFive>
    </div>
  </div>
</template>
<script>
import axios from "axios";
import pageHeader from "./header.vue";
import chapterOne from "./chapter001.vue";
// import chapterTwo from "./chapter002.vue";
// import chapterThree from "./chapter003.vue"
// import chapterFour from './chapter004.vue'
// import chapterFive from './chapter005.vue'
// import chapterSix from './chapter006.vue'
import chapterTwo from "./chapter002.vue";
import chapterThree from "./chapter003.vue";
import chapterFour from "./chapter004.vue";
import chapterFive from "./chapter005.vue";
import NoteIcon from "@/assets/images/biji.png";
import _ from "lodash";
import Swiper from "swiper/bundle";
import "swiper/swiper-bundle.css";
import Viewer from "viewerjs";
import "viewerjs/dist/viewer.css";
import getQuestionList from "@/assets/methods/examination";
export default {
  name:"pageContent",
  name: "pageContent",
  data() {
    return {
      catalogLength: 2, // 总章节数
      catalogLength: 6, // 总章节数
      showCatalogList: [], // 显示的章节
      loadThreshold: 300, // 触发加载阈值
      throttleThreshold: 100, // 节流阈值
@@ -54,6 +80,10 @@
      questionDataMap: {},
      renderSignMap: {},
      highlightData: null,
      questionId: {},
      collectId: [],
      questionDataIndex: 0, // 当前请求的是哪个章节的题目
      questionList: [], // 章节题目列表
    };
  },
  computed: {
@@ -159,35 +189,39 @@
    // 测试页面跳转
    // setTimeout(() => {
    //   this.gotoPage(1, 10);
    //   setTimeout(() => {
    //     this.renderSign("Highlight", {
    //       id: "2ACA9359",
    //       txt: "题一学习主题一 运动",
    //       page: "10",
    //       type: "Highlight",
    //       color: "#F5E12A"
    //     });
    // setTimeout(() => {
    //   this.delSign({
    //     ids: ["2ACA9359"]
    //   });
    // }, 2000);
    //   }, 5000);
    //   this.gotoPage(3,51);
    //   //   setTimeout(() => {
    //   //     this.renderSign("Highlight", {
    //   //       id: "2ACA9359",
    //   //       txt: "题一学习主题一 运动",
    //   //       page: "10",
    //   //       type: "Highlight",
    //   //       color: "#F5E12A"
    //   //     });
    //   // setTimeout(() => {
    //   //   this.delSign({
    //   //     ids: ["2ACA9359"]
    //   //   });
    //   // }, 2000);
    //   //   }, 5000);
    // const pageDom = (this.container ? this.container : document)
    //   .querySelector("#app")
    //   .querySelectorAll(".page-box");
    // 检索
    // console.log(this.searchTextByPage("保护内脏器官"), "searchTextByPage");
    // 检索跳转
    // this.searchItemLocation({
    //   catalog: 2,
    //   page: 10,
    //   txt: " 运动系统是由骨、骨连结和骨骼肌三部分组成的。全身的骨通过骨连结组成人体骨骼(见图1-1)。骨骼是人体的支架,具有保护内脏器官、供肌肉附着和作为肌肉运动的杠杆等作用。在神经系统的支配下,肌肉收缩牵动所附着的骨绕着关节转动,使身体产生各种动作。所以,运动系统具有运动、支持和保护等功能,幼年时期的骨骼还具有造血功能。 ",
    //   txtIndex: 57
    // });
    // }, 5000);
    //   // const pageDom = (this.container ? this.container : document)
    //   //   .querySelector("#app")
    //   //   .querySelectorAll(".page-box");
    //   // 检索
    //   // console.log(this.searchTextByPage("保护内脏器官"), "searchTextByPage");
    //   // 检索跳转
    //   // this.searchItemLocation({
    //   //   catalog: 2,
    //   //   page: 10,
    //   //   txt: " 运动系统是由骨、骨连结和骨骼肌三部分组成的。全身的骨通过骨连结组成人体骨骼(见图1-1)。骨骼是人体的支架,具有保护内脏器官、供肌肉附着和作为肌肉运动的杠杆等作用。在神经系统的支配下,肌肉收缩牵动所附着的骨绕着关节转动,使身体产生各种动作。所以,运动系统具有运动、支持和保护等功能,幼年时期的骨骼还具有造血功能。 ",
    //   //   txtIndex: 57
    //   // });
    // }, 500);
    // 获取题目id列表
    this.getQuestionId();
    this.getCollect();
  },
  methods: {
    // setZoom1() {
@@ -206,6 +240,7 @@
    // },
    // 滚动监听
    scrollFun(event) {
      this.handleVideoPicture();
      // 判断向上滚动还是向下滚动
      if (event.target.scrollTop > this.previousScrollTop) {
        // 向下
@@ -309,7 +344,10 @@
          this.container ? this.container : document
        ).querySelector(`[page="${data.page}"]`);
        // 创建 createTreeWalker 迭代器,用于遍历文本节点,保存到一个数组
        const treeWalker = document.createTreeWalker(pageDom, NodeFilter.SHOW_TEXT);
        const treeWalker = document.createTreeWalker(
          pageDom,
          NodeFilter.SHOW_TEXT
        );
        const allTextNodes = [];
        let currentNode = treeWalker.nextNode();
        while (currentNode) {
@@ -537,30 +575,26 @@
            // 添加页码
            this.loadPageList.push(Number(page));
            const catalog = catalogDom.getAttribute("num");
            // if (!this.questionDataMap[page]) {
            //   if (testData && testData[catalog]) {
            //     if (testData[catalog][page]) {
            //       if (Array.isArray(testData[catalog][page])) {
            //         this.questionDataMap[page] = await getQuestionList(
            //           page,
            //           testData[catalog][page],
            //           this.config.activeBook
            //         );
            //       } else {
            //         const obj = {};
            //         for (let key in testData[catalog][page]) {
            //           obj[key] = await getQuestionList(
            //             [],
            //             testData[catalog][page][key],
            //             this.config.activeBook
            //           );
            //         }
            //         this.questionDataMap[page] = obj;
            //       }
            //       console.log("题目", this.questionDataMap);
            //     }
            //   }
            // }
            if (!this.questionDataMap[page]) {
              if (this.questionId && this.questionId[catalog]) {
                if (this.questionId[catalog][page]) {
                  if (Array.isArray(this.questionId[catalog][page])) {
                    this.questionDataMap[page] = await this.getQuestion(
                      catalog,
                      page,
                      false
                    );
                  } else {
                    const obj = {};
                    for (let key in this.questionId[catalog][page]) {
                      obj[key] = await this.getQuestion(catalog, page, key);
                    }
                    this.questionDataMap[page] = obj;
                  }
                }
                console.log(1, this.questionDataMap);
              }
            }
            // 渲染这一页的标记
            for (const key in this.renderSignMap) {
              if (this.renderSignMap[key][page]) {
@@ -574,7 +608,10 @@
              // 高亮行
              setTimeout(() => {
                // 获取页面所有text节点
                const pageTextList = document.createTreeWalker(target, NodeFilter.SHOW_TEXT);
                const pageTextList = document.createTreeWalker(
                  target,
                  NodeFilter.SHOW_TEXT
                );
                // 匹配关键字
                const allPageTextNodes = [];
                let currentNode = pageTextList.nextNode();
@@ -625,12 +662,8 @@
          spaceBetween: 30, // 间隔
          // 如果需要前进后退按钮
          navigation: {
            nextEl: (this.container ? this.container : document).querySelector(
              ".swiper-button-next"
            ),
            prevEl: (this.container ? this.container : document).querySelector(
              ".swiper-button-prev"
            ),
            nextEl: dom.querySelector(".swiper-button-next"),
            prevEl: dom.querySelector(".swiper-button-prev"),
          },
          // 窗口变化,重新init,针对F11全屏和放大缩小,必须加
          observer: true,
@@ -657,12 +690,8 @@
          spaceBetween: 30, // 间隔
          // 如果需要前进后退按钮
          navigation: {
            nextEl: (this.container ? this.container : document).querySelector(
              ".swiper-button-next"
            ),
            prevEl: (this.container ? this.container : document).querySelector(
              ".swiper-button-prev"
            ),
            nextEl: dom.querySelector(".swiper-button-next"),
            prevEl: dom.querySelector(".swiper-button-prev"),
          },
          // 窗口变化,重新init,针对F11全屏和放大缩小,必须加
          observer: true,
@@ -710,11 +739,10 @@
      const pageData = {
        pageHeader,
        chapterOne,
        // chapterTwo,
        // chapterThree,
        // chapterFour,
        // chapterFive,
        // chapterSix,
        chapterTwo,
        chapterThree,
        chapterFour,
        chapterFive,
      };
      // 遍历所有章节文件
      for (const key in pageData) {
@@ -726,7 +754,7 @@
          propsData: {
            showPageList: [],
            questionData: {},
            isSearch: true
            isSearch: true,
          },
        });
        pageExample.$mount(
@@ -758,7 +786,7 @@
              propsData: {
                showPageList: [pageNum],
                questionData: {},
                isSearch: true
                isSearch: true,
              },
            });
            pageExample.$mount(
@@ -772,7 +800,10 @@
              .querySelector(`[page="${pageNum}"]`);
            if (thisPageDom) {
              // 获取页面所有text节点
              const pageTextList = document.createTreeWalker(thisPageDom, NodeFilter.SHOW_TEXT);
              const pageTextList = document.createTreeWalker(
                thisPageDom,
                NodeFilter.SHOW_TEXT
              );
              // 匹配关键字
              const allPageTextNodes = [];
              let currentNode = pageTextList.nextNode();
@@ -813,15 +844,151 @@
      // 跳转
      this.gotoPage(data.catalog, data.page, () => {});
    },
    // 获取题目列表
    getQuestionId() {
      axios
        .get(this.config.activeBook.resourceUrl + "/question.json")
        .then((res) => {
          this.questionId = res.data.data;
        });
    },
    // 获取题目收藏id列表
    getCollect() {
      if (!localStorage.getItem(this.config.tokenKey)) return false;
      this.MG.identity
        .getUserKey({
          domain: "collectData",
          keys: [this.config.activeBook.bookId],
        })
        .then((res) => {
          try {
            const collect = JSON.parse(res[0].value);
            if (collect.length) {
              this.collectId = collect.find(
                (item) => item.type == "json"
              ).collectList;
            }
          } catch (error) {
            console.log("暂无数据");
          }
        })
        .catch((res) => {
          console.log("index 请求题目收藏id报错");
        });
    },
    // 获取章节题目
    async getQuestion(num, page, questionIndex) {
      let cardList = [
        {
          catalogName: "单选题",
          infoList: [],
        },
        {
          catalogName: "判断题",
          infoList: [],
        },
        {
          catalogName: "多选题",
          infoList: [],
        },
        {
          catalogName: "填空题",
          infoList: [],
        },
        {
          catalogName: "简答题",
          infoList: [],
        },
      ];
      if (this.questionId) {
        if (this.questionId[num] && this.questionId[num][page]) {
          if (num != this.questionDataIndex || !this.questionList.length) {
            // 判断当前章节的题目json是否已经请求过
            const res = await axios.get(
              this.config.activeBook.resourceUrl + "/question-" + num + ".json"
            );
            if (!res.data) return [];
            this.questionList = res.data.data;
            this.questionDataIndex = res.data.chapterNum;
            console.log("章节号", num, res);
          }
          let ids = [];
          questionIndex
            ? (ids = this.questionId[num][page][questionIndex])
            : (ids = this.questionId[num][page]);
          for (let index = 0; index < this.questionList.length; index++) {
            const item = this.questionList[index];
            // 数学公式加类名去修改样式
            if (item.type && item.type == "material") {
              if (!item.infoList.length) return false;
              item.infoList.forEach((citem) => {
                if (citem.answer)
                  citem.answer = citem.answer.replace(
                    /\<math/gi,
                    '<math class="examination-math"'
                  );
              });
            } else {
              if (item.answer)
                item.answer = item.answer.replace(
                  /\<math/gi,
                  '<math class="examination-math"'
                );
            }
            item.isCollect =
              this.collectId.indexOf(item.id) > -1 ? true : false;
            if (ids.indexOf(item.id) > -1) {
              if (item.type && item.type == "material") {
                cardList.push(item);
              } else {
                if (item.questionType == "judge") {
                  cardList[1].infoList.push(item);
                }
                if (item.questionType == "singleChoice") {
                  cardList[0].infoList.push(item);
                }
                if (item.questionType == "multipleChoice") {
                  cardList[2].infoList.push(item);
                }
                if (item.questionType == "completion") {
                  cardList[3].infoList.push(item);
                }
                if (item.questionType == "shortAnswer") {
                  cardList[4].infoList.push(item);
                }
              }
            }
          }
          return cardList.filter((item) => item.infoList.length > 0);
        }
      } else {
        return [];
      }
    },
    // 视频小窗
    handleVideoPicture() {
      let doms = (this.container ? this.container : document).querySelectorAll(
        ".video"
      );
      doms = Array.from(doms);
      if (!doms.length) return false;
      const playVudio = doms.reverse().find((item) => item.paused == false);
      if (playVudio) {
        const bottomGap = playVudio.getBoundingClientRect().bottom;
        const topGap = playVudio.getBoundingClientRect().top;
        if (bottomGap < 0 || topGap > window.innerHeight) {
          playVudio.requestPictureInPicture();
        }
      }
    },
  },
  components: {
    pageHeader,
    chapterOne,
    // chapterTwo,
    // chapterThree,
    // chapterFour,
    // chapterFive,
    // chapterSix,
    chapterTwo,
    chapterThree,
    chapterFour,
    chapterFive,
  },
};
</script>
@@ -831,6 +998,7 @@
  width: 100%;
  height: 100%;
  overflow: auto;
  .page-content {
    max-width: 816px;
    min-width: 375px;