YM
2024-05-29 d82733fc757f080c8910049ae12567454ee1aeac
Merge branch 'master' of http://182.92.203.7:2001/r/testbookLayout
9个文件已修改
9398 ■■■■ 已修改文件
package-lock.json 11 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
public/index.html 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/assets/methods/examination.js 48 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/books/English/view/components/header.vue 4 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/books/English/view/components/index.vue 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/books/embedded/view/components/chapter001.vue 31 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/books/embedded/view/components/header.vue 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/books/embedded/view/components/index.vue 282 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
yarn.lock 9013 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
package-lock.json
@@ -17,6 +17,7 @@
        "qiankun": "^2.10.16",
        "spark-md5": "^3.0.2",
        "swiper": "^6.8.1",
        "viewerjs": "^1.11.6",
        "vue": "^2.6.14",
        "vuex": "^3.6.2"
      },
@@ -12103,6 +12104,11 @@
        "node": ">= 0.8"
      }
    },
    "node_modules/viewerjs": {
      "version": "1.11.6",
      "resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.11.6.tgz",
      "integrity": "sha512-TlhdSp2oEOLFXvEp4psKaeTjR5zBjTRcM/sHUN8PkV1UWuY8HKC8n7GaVdW5Xqnwdr/F1OmzLik1QwDjI4w/nw=="
    },
    "node_modules/vue": {
      "version": "2.7.16",
      "resolved": "https://registry.npmmirror.com/vue/-/vue-2.7.16.tgz",
@@ -21424,6 +21430,11 @@
      "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
      "dev": true
    },
    "viewerjs": {
      "version": "1.11.6",
      "resolved": "https://registry.npmjs.org/viewerjs/-/viewerjs-1.11.6.tgz",
      "integrity": "sha512-TlhdSp2oEOLFXvEp4psKaeTjR5zBjTRcM/sHUN8PkV1UWuY8HKC8n7GaVdW5Xqnwdr/F1OmzLik1QwDjI4w/nw=="
    },
    "vue": {
      "version": "2.7.16",
      "resolved": "https://registry.npmmirror.com/vue/-/vue-2.7.16.tgz",
public/index.html
@@ -8,8 +8,6 @@
    <meta http-equiv="Cache-Control" content="no-cache, must-revalidate">
    <meta http-equiv="expires" content="0">
    <link rel="icon" href="<%= BASE_URL %>favicon.ico">
    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/Swiper/6.8.1/css/swiper.css">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/Swiper/6.8.1/js/swiper.js"></script>
    <title>数字教材</title>
  </head>
  <body>
src/assets/methods/examination.js
@@ -1,43 +1,44 @@
import MG from "@/assets/js/middleGround/WebMiddleGroundApi";
import getPublicImage from "@/assets/js/middleGround/tool";
const getQuestionList = async (page, questionList,activeBook) => {
  console.log('page',page);
  const oldAnswerData = localStorage.getItem(activeBook.name + 'oldAnswerData')
  let oldData = null
  let oldList = []
  if(oldAnswerData) {
    oldData = JSON.parse(oldAnswerData)
const getQuestionList = async (page, questionList, activeBook) => {
  console.log("page", page);
  const oldAnswerData = localStorage.getItem(activeBook.name + "oldAnswerData");
  let oldData = null;
  let oldList = [];
  if (oldAnswerData) {
    oldData = JSON.parse(oldAnswerData);
  }
 if(oldData && oldData[page]) {
  oldList = oldData[page]
 }
  if (oldData && oldData[page]) {
    oldList = oldData[page];
  }
  let cardList = [
    {
      catalogName: "单选题",
      infoList: []
      infoList: [],
    },
    {
      catalogName: "判断题",
      infoList: []
      infoList: [],
    },
    {
      catalogName: "多选题",
      infoList: []
      infoList: [],
    },
    {
      catalogName: "填空题",
      infoList: []
      infoList: [],
    },
    {
      catalogName: "简答题",
      infoList: []
    }
      infoList: [],
    },
  ];
  let singleChoiceArr = []; // 单选
  let judgeArr = []; // 判断
  let shortArr = []; // 简答
  let multipleChoiceArr = []; // 多选
  let completionArr = []; // 填空
  // 11
  for (let qindex = 0; qindex < questionList.length; qindex++) {
    const qitem = questionList[qindex];
    let query = {
@@ -57,11 +58,11 @@
        Embedded_QuestionBank_StemStyle: [],
        Embedded_QuestionBank_OptionStyle: [],
        Embedded_QuestionBank_KnowledgePoint: [],
        Embedded_QuestionBank_Difficulty: []
      }
        Embedded_QuestionBank_Difficulty: [],
      },
    };
    const res = await MG.store.getProductDetail(query);
    if(!res.datas) return false
    if (!res.datas) return false;
    res.datas.cmsDatas[0].datas.forEach((item, index) => {
      let oldObj = {};
      if (oldList) {
@@ -97,7 +98,7 @@
        isRight: null, // 是否正确
        isComplete: false,
        isCollect: true,
        isUnfold: ""
        isUnfold: "",
      };
      // 多选和填空答案肯为数组,要转换JSON格式
      if (
@@ -118,7 +119,7 @@
          if (item == "input") {
            questionObj.stem[i] = {
              num: index,
              data: "input"
              data: "input",
            };
            questionObj.userAnswer[index] = "";
            index++;
@@ -206,6 +207,7 @@
      }
    });
  }
  // 22
  cardList[0].infoList = singleChoiceArr;
  cardList[1].infoList = judgeArr;
  cardList[2].infoList = multipleChoiceArr;
@@ -221,7 +223,7 @@
  return cardList.filter((item) => item.infoList.length > 0);
};
const getQuestionData = async (chapter, chapterData,activeBook) => {
const getQuestionData = async (chapter, chapterData, activeBook) => {
  const data = { ...chapterData };
  const oldAnswerData = localStorage.getItem("oldAnswerData");
  const oldData = oldAnswerData ? JSON.parse(oldAnswerData) : {};
@@ -234,7 +236,7 @@
    if (oldChapterData) {
      oldList = oldChapterData[key];
    }
    data[key] = await getQuestionList(oldList, chapterData[key],activeBook);
    data[key] = await getQuestionList(oldList, chapterData[key], activeBook);
  }
  return data;
};
src/books/English/view/components/header.vue
@@ -93,7 +93,7 @@
      </div>
    </div>
    <!-- 4 -->
    <div class="page-box">
    <div class="page-box" page="4">
      <div class="mb-20" style="padding-right: 20px;">
        <div class="primary-bc fl al-end" style="height: 100px;padding-left: 40px;">
          <div class="preface-header-box y-bc">
@@ -137,7 +137,7 @@
      </div>
    </div>
    <!-- 5 -->
    <div class="page-box">
    <div class="page-box" page="5">
      <ul class="preface-odd-header w100 fl ju-bt">
        <li class="left primary-bc "></li>
        <li>
src/books/English/view/components/index.vue
@@ -1,7 +1,7 @@
<template>
  <div class="page-main" @scroll="throttledScrollHandler">
    <div class="page-content">
      <pageHeader></pageHeader>
      <pageHeader ></pageHeader>
      <chapterOne @saveCharacters="saveCharacters"></chapterOne>
    </div>
  </div>
src/books/embedded/view/components/chapter001.vue
@@ -175,23 +175,27 @@
              能,有效帮助用户建造从嵌入式设备、现场监控工作站到企业生产监控信息网在内的完整的自动化解决方案。图1-1~图1-4所示为嵌入式组态软件系统应用于各个行业的情况。
            </p>
            <div class="qrbodyPic">
              <el-image
                :src="imgOne"
                :preview-src-list="[imgOne]"
                class="w100"
              />
              <div class="openImgBox">
                <img src="../../assets/images/img00014001.jpg" alt="" class="w100">
              </div>
              <p class="imgdescript">图1-1 嵌入式组态软件系统应用于电力行业</p>
            </div>
            <div class="qrbodyPic">
              <el-image :src="imgTwo" :preview-src-list="[imgTwo]" />
              <div class="openImgBox">
                <img src="../../assets/images/img00014002.jpg" alt="" class="w100">
              </div>
              <p class="imgdescript">图1-2 嵌入式组态软件系统应用于铁路行业</p>
            </div>
            <div class="qrbodyPic">
              <el-image :src="imgThree" :preview-src-list="[imgThree]" />
              <div class="openImgBox">
                <img src="../../assets/images/img00014003.jpg" alt="" class="w100">
              </div>
              <p class="imgdescript">图1-3 嵌入式组态软件系统应用于橡胶行业</p>
            </div>
            <div class="qrbodyPic">
              <el-image :src="imgFour" :preview-src-list="[imgFour]" />
              <div class="openImgBox">
                <img src="../../assets/images/img00014004.jpg" alt="" class="w100">
              </div>
              <p class="imgdescript">图1-4 嵌入式组态软件系统应用于纺织行业</p>
            </div>
          </div>
@@ -254,7 +258,9 @@
          MCGS嵌入版组态软件生成的用户应用系统,由主控窗口、设备窗口、用户窗口、实时数据库和运行策略五部分构成,如图1-5所示。
        </p>
        <div class="qrbodyPic">
          <el-image :src="imgFive" :preview-src-list="[imgFive]" />
          <div class="openImgBox">
            <img src="../../assets/images/img00015001.jpg" alt="" class="w100">
          </div>
          <p class="imgdescript">图1-5 用户应用系统组成</p>
        </div>
        <p class="content">
@@ -354,11 +360,14 @@
        </div>
        <div class="fl">
          <div class="">
            <el-image
            <!-- <el-image
              :src="imgSix"
              active="true"
              :preview-src-list="[imgSix]"
            />
            /> -->
            <div class="openImgBox">
            <img src="../../assets/images/img00017001.jpg" alt="" class="w100">
          </div>
            <p class="imgdescript">图1-6 正视图</p>
          </div>
          <div class="">
src/books/embedded/view/components/header.vue
@@ -355,6 +355,11 @@
<script>
export default {
  name: "headerPage",
  props:{
    showPageList:{
      type:Array
    }
  }
};
</script>
<style scoped lang="less">
src/books/embedded/view/components/index.vue
@@ -1,8 +1,12 @@
<template>
  <div class="page-main" @scroll="throttledScrollHandler">
    <div class="page-content">
      <pageHeader v-if="showCatalogList.indexOf(0) > -1"></pageHeader>
      <chapterOne v-if="showCatalogList.indexOf(1) > -1" />
    <div class="page-content"       :style="{
        fontSize: fontSize ? fontSize + 'px' : '16px',
        transform: `scale(${pageZoom ? pageZoom : 1})`,
        transformOrigin: 'center top',
      }">
      <pageHeader v-if="showCatalogList.indexOf(1) > -1" :showPageList="loadPageList"></pageHeader>
      <chapterOne v-if="showCatalogList.indexOf(2) > -1" :showPageList="loadPageList" />
    </div>
  </div>
</template>
@@ -11,9 +15,21 @@
import chapterOne from "./chapter001.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";
export default {
  name: "pageContent",
  components: { pageHeader, chapterOne },
  computed: {
    fontSize() {
      return this.$store.state.qiankun.fontSize;
    },
    pageZoom() {
      return this.$store.state.qiankun.scale / 100;
    },
  },
  data() {
    return {
      catalogLength: 2, // 总章节数
@@ -23,6 +39,10 @@
      previousScrollTop: 0,
      throttledScrollHandler: null,
      observer: null,
      loadPageObserver: null,
      loadPageList: [],
      questionData: {},
      testData:{}
    };
  },
  watch: {
@@ -40,13 +60,22 @@
        // 启动页码观察
        setTimeout(() => {
          this.initObservation();
          this.initThemeColor();
        }, 500);
      },
      }
    },
    loadPageList: {
      handler(newVal, oldVal) {
        setTimeout(() => {
          this.initSwiper();
          this.initViewer();
        }, 200);
      }
    }
  },
  mounted() {
    // 默认加载章节
    this.showCatalogList = [0,1];
    this.showCatalogList = [1];
    // 滚动监听节流
    this.throttledScrollHandler = _.throttle(
      this.scrollFun,
@@ -79,29 +108,36 @@
      threshold: 0.5, // 指定交叉比例,这里设为 0.5,表示当目标元素一半或更多显示在视窗中时触发回调函数。
    });
    this.loadPageObserver = new IntersectionObserver(this.loadPageCallback, {
      root: null, // 指定根元素,这里设为 null,表示选取整个视窗作为根元素。
      rootMargin: "0px", // 指定根元素的边界,这里设为 "0px",表示根元素的边界和视窗的边界重合
      threshold: 0, // 指定交叉比例,这里设为 0.5,表示当目标元素一半或更多显示在视窗中时触发回调函数。
    });
    // 启动页码观察
    setTimeout(() => {
      this.initObservation();
      this.initThemeColor();
    }, 500);
    // 测试页面跳转
    // setTimeout(() => {
    //   this.gotoPage(5, 100);
    //   setTimeout(() => {
    //     this.renderSign("Note", {
    //       id: "2ACA9359",
    //       txt: "营养素和热量,才能",
    //       page: "100",
    //       type: "Highlight",
    //       color: "#F5E12A"
    //     });
    //     setTimeout(() => {
    //       this.delSign({
    //         ids: ["2ACA9359"]
    //       });
    //     }, 2000);
    //   }, 1000);
    // }, 3000);
    //   this.gotoPage(1, 11);
    //   //   setTimeout(() => {
    //   //     this.renderSign("Note", {
    //   //       id: "2ACA9359",
    //   //       txt: "营养素和热量,才能",
    //   //       page: "100",
    //   //       type: "Highlight",
    //   //       color: "#F5E12A"
    //   //     });
    //   //     setTimeout(() => {
    //   //       this.delSign({
    //   //         ids: ["2ACA9359"]
    //   //       });
    //   //     }, 2000);
    //   //   }, 1000);
    // }, 1000);
  },
  methods: {
    // 滚动监听
@@ -179,6 +215,7 @@
        console.log("章节错误!");
      }
    },
    // 渲染标记
    renderSign(type, data) {
      const existence = (
@@ -209,7 +246,7 @@
            // 笔记
            pageDom.innerHTML = pageDom.innerHTML.replace(
              reg,
              `<span datatype="Note" dataid="${data.id}" style="border-bottom-color:${data.color}" class="notesline" onclick="signClick('Note','${data.id}','${data.chapterNum}')" onmouseover="noteHover('Note','${data.id}','${data.chapterNum}')">${data.txt}<img src="${NoteIcon}" style="cursor: pointer" /></span>`
              `<span datatype="Note" dataid="${data.id}" style="border-bottom-color:${data.color}" class="notesline" onclick="signClick('Note','${data.id}','${data.chapterNum}')" onmouseover="noteHover('Note','${data.id}','${data.chapterNum}')" onmouseout="noteOut('Note')">${data.txt}<img src="${NoteIcon}"/></span>`
            );
            break;
        }
@@ -246,14 +283,116 @@
      const sections = (
        this.container ? this.container : document
      ).querySelectorAll(".page-box");
      //observer 观察每个元素,以便在它们进入或离开视窗时触发回调函数。
      sections.forEach((section) => {
        if (this.config.activeBook && this.config.activeBook.tryPageCount) {
          const page = section.getAttribute("page");
          if (Number(page) > this.config.activeBook.tryPageCount) {
            let chapterDom = this.getParentWithClass(section, "chapter");
            const chapterNum = chapterDom.getAttribute("num");
            this.catalogLength = Number(chapterNum) - 1;
            section.remove();
            return false;
          }
        }
        //observer 观察每个元素,以便在它们进入或离开视窗时触发回调函数。
        const isObserver = section.getAttribute("observer");
        const isLoadObserver = section.getAttribute("loadObserver");
        if (!isObserver) {
          this.observer.observe(section);
          section.setAttribute("observer", "1");
        }
        if (!isLoadObserver) {
          this.loadPageObserver.observe(section);
          section.setAttribute("loadObserver", "1");
        }
      });
    },
    initThemeColor() {
      // 获取各种需要主题色的节点
      const colorDom = (
        this.container ? this.container : document
      ).querySelectorAll(".theme-color");
      const backgroundColorDom = (
        this.container ? this.container : document
      ).querySelectorAll(".theme-back");
      const borderColorDom = (
        this.container ? this.container : document
      ).querySelectorAll(".theme-border");
      // 获取配置的主题色
      const bookThemeColor =
        this.config.activeBook && this.config.activeBook.bookThemeColor
          ? this.config.activeBook.bookThemeColor
          : null;
      const chapterThemeColor =
        this.config.activeBook && this.config.activeBook.chapterThemeColor
          ? this.config.activeBook.chapterThemeColor
          : null;
      const pageThemeColor =
        this.config.activeBook && this.config.activeBook.pageThemeColor
          ? this.config.activeBook.pageThemeColor
          : null;
      colorDom.forEach((domItem) => {
        // 获取章节、页码
        let pageDom = this.getParentWithClass(domItem, "page-box");
        let chapterDom = this.getParentWithClass(domItem, "chapter");
        let page, chapterNum;
        if (pageDom) page = pageDom.getAttribute("page");
        if (chapterDom) chapterNum = chapterDom.getAttribute("num");
        // 向上匹配主题色
        const themeColor =
          page && pageThemeColor && pageThemeColor[page]
            ? pageThemeColor[page]
            : chapterNum && chapterThemeColor && chapterThemeColor[chapterNum]
            ? chapterThemeColor[chapterNum]
            : bookThemeColor;
        if (themeColor) {
          domItem.style.color = themeColor;
        }
      });
      backgroundColorDom.forEach((domItem) => {
        // 获取章节、页码
        let pageDom = this.getParentWithClass(domItem, "page-box");
        let chapterDom = this.getParentWithClass(domItem, "chapter");
        let page, chapterNum;
        if (pageDom) page = pageDom.getAttribute("page");
        if (chapterDom) chapterNum = chapterDom.getAttribute("num");
        // 向上匹配主题色
        const themeColor =
          page && pageThemeColor && pageThemeColor[page]
            ? pageThemeColor[page]
            : chapterNum && chapterThemeColor && chapterThemeColor[chapterNum]
            ? chapterThemeColor[chapterNum]
            : bookThemeColor;
        if (themeColor) {
          domItem.style.backgroundColor = themeColor;
        }
      });
      borderColorDom.forEach((domItem) => {
        // 获取章节、页码
        let pageDom = this.getParentWithClass(domItem, "page-box");
        let chapterDom = this.getParentWithClass(domItem, "chapter");
        let page, chapterNum;
        if (pageDom) page = pageDom.getAttribute("page");
        if (chapterDom) chapterNum = chapterDom.getAttribute("num");
        // 向上匹配主题色
        const themeColor =
          page && pageThemeColor && pageThemeColor[page]
            ? pageThemeColor[page]
            : chapterNum && chapterThemeColor && chapterThemeColor[chapterNum]
            ? chapterThemeColor[chapterNum]
            : bookThemeColor;
        if (themeColor) {
          domItem.style.borderColor = themeColor;
        }
      });
    },
    getParentWithClass(element, className) {
      while (element.parentElement) {
        element = element.parentElement;
        if (element.classList.contains(className)) {
          return element;
        }
      }
    },
    pageChangeCallback(entries, observer) {
      //entries:代表观察到的目标元素的集合。 observer:代表观察者对象。
@@ -268,12 +407,18 @@
            "chapter"
          );
          const catalog = catalogDom.getAttribute("num");
          console.log("page", page, catalog);
          console.log(page, "page", catalog, "catalog");
          let text = null;
          if (target.querySelector("p")) {
            console.log(target.querySelector("p").textContent.substring(0, 20));
            text = target.querySelector("p").textContent.substring(0, 20);
          }
          // 返回页码和章节信息
          if (this.$store.state.qiankun && this.$store.state.qiankun.pageChange)
            this.$store.state.qiankun.pageChange({
              page: page,
              catalog: catalog,
              text
            });
          // const sections = Array.from(document.querySelectorAll(".section"));
          //sections:获取所有具有 .section 类名的元素,并转换为数组。
@@ -282,6 +427,95 @@
        }
      });
    },
    loadPageCallback(entries, observer) {
      entries.forEach(async (entry) => {
        if (entry.isIntersecting) {
          const target = entry.target;
          const page = target.getAttribute("page");
          if (this.loadPageList.indexOf(page) == -1) {
            //
            const catalogDom = this.tool.getParentNodeByClassName(
              target,
              "chapter"
            );
            const catalog = catalogDom.getAttribute("num");
            // if (!this.questionData[page]) {
            //   if (testData && testData[catalog]) {
            //     if (testData[catalog][page]) {
            //       if (Array.isArray(testData[catalog][page])) {
            //         this.questionData[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.questionData[page] = obj;
            //       }
            //     }
            //   }
            // }
            this.loadPageList.push(Number(page));
            if (this.loadPageList.length > 5) {
              // 超过5页
              this.loadPageList.shift();
            }
          }
        }
      });
    },
    initSwiper() {
      const doms = (
        this.container ? this.container : document
      ).querySelectorAll(".swiper-container");
      for (let i = 0; i < doms.length; i++) {
        const dom = doms[i];
        new Swiper(dom, {
          loop: false, // 无缝
          autoplay: {
            //自动开始
            delay: 3000, //时间间隔
            disableOnInteraction: false //*手动操作轮播图后不会暂停*
          },
          paginationClickable: true,
          slidesPerView: 1, // 一组三个
          spaceBetween: 30, // 间隔
          // 如果需要前进后退按钮
          navigation: {
            nextEl: ".swiper-button-next",
            prevEl: ".swiper-button-prev"
          },
          // 窗口变化,重新init,针对F11全屏和放大缩小,必须加
          observer: true,
          observeParents: true,
          // 如果需要分页器
          pagination: {
            el: ".swiper-pagination",
            clickable: true // 分页器可以点击
          }
        });
      }
    },
    initViewer() {
      const doms = (
        this.container ? this.container : document
      ).querySelectorAll(".openImgBox");
      for (let i = 0; i < doms.length; i++) {
        const dom = doms[i];
        new Viewer(dom, {
          navbar: true, // 显示导航栏
          toolbar: true, // 显示工具栏
          title: true // 显示标题
        });
      }
    }
  },
};
</script>
yarn.lock
Diff too large