dsy преди 1 ден
родител
ревизия
b53598baec

+ 1 - 12
src/views/book/courseware/preview/CoursewarePreview.vue

@@ -929,7 +929,7 @@ export default {
   row-gap: $component-spacing;
   width: 100%;
   height: 100%;
-  min-height: calc(100vh - 226px);
+  min-height: calc(100vh - 106px);
   padding-top: $courseware-top-padding;
   padding-bottom: $courseware-bottom-padding;
   margin: 15px 0;
@@ -938,17 +938,6 @@ export default {
   border-bottom-right-radius: 12px;
   border-bottom-left-radius: 12px;
 
-  &::before,
-  &::after {
-    position: absolute;
-    left: 0;
-    width: 100%;
-    height: 15px;
-    pointer-events: none;
-    content: '';
-    background: $courseware-bgColor;
-  }
-
   &::before {
     top: -15px;
   }

+ 17 - 0
src/views/book/courseware/preview/common/AnswerAnalysis.vue

@@ -135,6 +135,23 @@ export default {
       return Array.isArray(slotContent) && slotContent.length > 0; // 检查插槽内容是否存在且不为空
     },
   },
+  watch: {
+    visible(val) {
+      // 关闭时,停止所有音视频播放
+      if (!val) {
+        const audioPlayers = this.$el.querySelectorAll('.answer-audio-list audio, .analysis-audio-list audio');
+        audioPlayers.forEach((audio) => {
+          audio.pause();
+          audio.currentTime = 0;
+        });
+        const videoPlayers = this.$el.querySelectorAll('.answer-video-list video, .analysis-video-list video');
+        videoPlayers.forEach((video) => {
+          video.pause();
+          video.currentTime = 0;
+        });
+      }
+    },
+  },
   methods: {
     handleClose() {
       this.$emit('update:visible', false);

+ 6 - 1
src/views/book/courseware/preview/components/common/VideoPlay.vue

@@ -47,7 +47,12 @@
           <h2>您的浏览器<strong>不支持video标签</strong></h2>
         </video>
       </template>
-      <SvgIcon v-show="originPlay || showPlay" :class="{ hidden: hidden }" icon-class="paused" size="16" />
+      <SvgIcon
+        v-show="viewMethod === 'independent' && (originPlay || showPlay)"
+        :class="{ hidden: hidden }"
+        icon-class="paused"
+        size="16"
+      />
     </div>
   </div>
 </template>

+ 12 - 1
src/views/book/courseware/preview/components/dialogue_article/NormalModelChs.vue

@@ -76,7 +76,18 @@
               : '',
           ]"
         >
-          <div :class="['article-content', isHasRemark ? 'hasRemark' : '']">
+          <div
+            :class="['article-content', isHasRemark ? 'hasRemark' : '']"
+            :style="{
+              backgroundColor:
+                item.timeList.length > 0 &&
+                curTime >= item.timeList[0].bg + 0.01 &&
+                curTime <= item.timeList[item.timeList.length - 1].ed - 0.01 &&
+                attrib
+                  ? attrib.assist_color
+                  : '',
+            }"
+          >
             <template v-if="item.type === 'notice'">
               <p :class="['notice']">
                 {{ convertText(item.notice) }}

+ 23 - 2
src/views/book/courseware/preview/components/dialogue_article/PhraseModelChs.vue

@@ -66,7 +66,19 @@
           :key="'detail' + index"
           :class="['NNPE-detail', item.isTitle ? 'NNPE-detail-title' : '']"
         >
-          <div :class="['article-content', isHasRemark ? 'hasRemark' : '']">
+          <div
+            :class="['article-content', isHasRemark ? 'hasRemark' : '']"
+            :style="{
+              backgroundColor:
+                item.timeList &&
+                item.timeList.length > 0 &&
+                curTime >= item.timeList[0].bg + 0.01 &&
+                curTime <= item.timeList[item.timeList.length - 1].ed - 0.01 &&
+                attrib
+                  ? attrib.assist_color
+                  : '',
+            }"
+          >
             <template v-if="item.type === 'notice'">
               <p :class="['notice']">
                 {{ convertText(item.notice) }}
@@ -818,7 +830,7 @@ export default {
 
     handleWav() {},
     getCurTime(curTime) {
-      this.curTime = curTime;
+      this.curTime = curTime * 1000;
     },
     handleData() {
       let resArr = [];
@@ -889,11 +901,20 @@ export default {
             if (wItem.pinyin) dhaspinyin = true;
           });
         });
+        let curSentencesLeg = dItem.sentences.length;
+        let startLeg = dIndex === 0 ? 0 : curQue.detail[dIndex - 1].endLeg;
+        let endLeg = startLeg + curSentencesLeg;
+        dItem.endLeg = endLeg;
+        let timeList = [];
+        if (curQue.wordTime && curQue.wordTime.length > 0 && dItem.type === 'text') {
+          timeList = curQue.wordTime.slice(startLeg, endLeg);
+        }
         let enwords =
           dItem.sentencesEn && dItem.sentencesEn.length > 0 ? dItem.sentencesEn.join(' ').replace(/\\'/g, '’') : '';
         let paraObj = {
           wordsList: paraArr,
           enwords,
+          timeList,
           roleDetail,
           remarkDetail,
           dhaspinyin,

+ 13 - 1
src/views/book/courseware/preview/components/dialogue_article/WordModelChs.vue

@@ -65,7 +65,19 @@
           :key="'detail' + index"
           :class="['NNPE-detail', item.isTitle ? 'NNPE-detail-title' : '']"
         >
-          <div class="article-content">
+          <div
+            class="article-content"
+            :style="{
+              backgroundColor:
+                item.timeList &&
+                item.timeList.length > 0 &&
+                curTime >= item.timeList[0].bg + 0.01 &&
+                curTime <= item.timeList[item.timeList.length - 1].ed - 0.01 &&
+                attrib
+                  ? attrib.assist_color
+                  : '',
+            }"
+          >
             <template v-if="item.type === 'notice'">
               <p :class="['notice']">
                 {{ convertText(item.notice) }}

+ 9 - 2
src/views/book/courseware/preview/components/fill/FillPreview.vue

@@ -103,7 +103,7 @@
     </div>
 
     <WriteDialog :visible.sync="writeVisible" @confirm="handleWriteConfirm" />
-    <PreviewOperation @showAnswerAnalysis="showAnswerAnalysis" @retry="retry" />
+    <PreviewOperation :is-show-answer="isShowAnswer" @showAnswerAnalysis="showAnswerAnalysis" @retry="retry" />
     <AnswerCorrect :visible.sync="visibleAnswerCorrect" @closeAnswerCorrect="closeAnswerCorrect" />
     <AnswerAnalysis
       :visible.sync="visibleAnswerAnalysis"
@@ -174,7 +174,14 @@ export default {
   },
   computed: {
     fontFamily() {
-      return fillFontList.find(({ value }) => this.data.property.fill_font === value).font;
+      const fontItem = fillFontList.find(({ value }) => this.data.property.fill_font === value);
+      return fontItem ? fontItem.font : '';
+    },
+    isShowAnswer() {
+      return (
+        (Array.isArray(this.data.answer_list) && this.data.answer_list.length > 0) ||
+        (Array.isArray(this.data.analysis_list) && this.data.analysis_list.length > 0)
+      );
     },
   },
   watch: {

+ 13 - 3
src/views/book/courseware/preview/components/judge/JudgePreview.vue

@@ -14,7 +14,12 @@
             :style="{ borderColor: data.unified_attrib?.topic_color }"
             :class="['option-content', computedIsJudgeRight(mark)]"
           >
-            <span class="serial-number">{{ computedOptionNumber(i) }}.</span>
+            <span
+              v-if="!('enable_serial' in data.property) || isEnable(data.property.enable_serial)"
+              class="serial-number"
+            >
+              {{ computedOptionNumber(i) }}.
+            </span>
             <PinyinText
               v-if="isEnable(data.property.view_pinyin)"
               class="content"
@@ -80,7 +85,12 @@
             :style="{ borderColor: data.unified_attrib?.topic_color }"
             :class="['option-content', computedIsJudgeRight(mark)]"
           >
-            <span class="serial-number">{{ computedOptionNumber(i) }}.</span>
+            <span
+              v-if="!('enable_serial' in data.property) || isEnable(data.property.enable_serial)"
+              class="serial-number"
+            >
+              {{ computedOptionNumber(i) }}.
+            </span>
             <PinyinText
               v-if="isEnable(data.property.view_pinyin)"
               class="content"
@@ -191,7 +201,7 @@ export default {
     computedIsJudgeRight(mark) {
       if (!this.isJudgingRightWrong) return '';
       let selectOption = this.answer.answer_list.find((item) => item.mark === mark); // 查找是否已选中的选项
-      if (!selectOption) return 'wrong';
+      if (!selectOption) return '';
       return this.data.answer.answer_list.find((item) => item.mark === mark)?.option_type === selectOption.option_type
         ? 'right'
         : 'wrong';

+ 2 - 2
src/views/book/courseware/preview/components/matching/MatchingPreview.vue

@@ -346,7 +346,7 @@ export default {
       let svg = document.createElementNS(svgNS, 'svg');
       svg.setAttribute(
         'style',
-        `position:absolute; width: 102px; height: ${Math.max(8, height)}px; top: ${top}px; left: ${left}px;overflow: visible;`,
+        `position:absolute; width: 122px; height: ${Math.max(8, height)}px; top: ${top}px; left: ${left}px;overflow: visible;`,
       );
       svg.classList.add('connection-line', `svg-${mark}-${curMark}`); // 添加类名
       // 向SVG元素添加 path 元素
@@ -546,7 +546,7 @@ export default {
 
     .list-item {
       display: flex;
-      column-gap: 100px;
+      column-gap: 120px;
       align-items: stretch;
       padding: 1px;
 

+ 17 - 15
src/views/book/courseware/preview/components/notes/NotesPreview.vue

@@ -211,21 +211,23 @@ export default {
       this.wordShow = !this.wordShow;
     },
     handleData() {
-      this.data.multilingual.forEach((item) => {
-        let trans_arr = item.translation.split('\n');
-        this.$set(this.titleTrans, item.type, trans_arr[0] ? trans_arr[0] : '');
-        let chunkSize = 2;
-        let chunkedArr = trans_arr.splice(1).reduce((acc, curr, index) => {
-          // 当索引是chunkSize的倍数时,开始一个新的子数组
-          if (index % chunkSize === 0) {
-            acc.push([curr]); // 开始新的子数组并添加当前元素
-          } else {
-            acc[acc.length - 1].push(curr); // 将当前元素添加到最后一个子数组中
-          }
-          return acc;
-        }, []);
-        this.$set(this.multilingualTextList, item.type, chunkedArr);
-      });
+      if (this.data.multilingual) {
+        this.data.multilingual.forEach((item) => {
+          let trans_arr = item.translation.split('\n');
+          this.$set(this.titleTrans, item.type, trans_arr[0] ? trans_arr[0] : '');
+          let chunkSize = 2;
+          let chunkedArr = trans_arr.splice(1).reduce((acc, curr, index) => {
+            // 当索引是chunkSize的倍数时,开始一个新的子数组
+            if (index % chunkSize === 0) {
+              acc.push([curr]); // 开始新的子数组并添加当前元素
+            } else {
+              acc[acc.length - 1].push(curr); // 将当前元素添加到最后一个子数组中
+            }
+            return acc;
+          }, []);
+          this.$set(this.multilingualTextList, item.type, chunkedArr);
+        });
+      }
       // this.data.option.forEach((item) => {
       //   if (item.file_list && item.file_list[0]) {
       //     GetFileURLMap({ file_id_list: item.file_list }).then(({ url_map }) => {

+ 2 - 2
src/views/book/courseware/preview/components/pinyin_base/PinyinBasePreview.vue

@@ -296,8 +296,8 @@ export default {
   created() {
     // console.log(this.data);
     if (
-      data.property.fun_type !== 'show' ||
-      (data.property.fun_type === 'show' && this.data.answer_list && this.data.answer_list.length > 0) ||
+      this.data.property.fun_type !== 'show' ||
+      (this.data.property.fun_type === 'show' && this.data.answer_list && this.data.answer_list.length > 0) ||
       (this.data.analysis_list && this.data.analysis_list.length > 0)
     ) {
       this.isShowAnswers = true;

+ 1 - 1
src/views/book/courseware/preview/components/record_input/RecordInputPreview.vue

@@ -28,8 +28,8 @@
         />
       </div>
       <PreviewOperation
-        v-if="isEnable(data.is_enable_input)"
         :is-show-answer="isShowAnswers"
+        :is-show-retry="isEnable(data.is_enable_input)"
         @showAnswerAnalysis="showAnswerAnalysis"
         @retry="retry"
       />

+ 12 - 2
src/views/book/courseware/preview/components/select/SelectPreview.vue

@@ -18,7 +18,12 @@
           <span :class="[isSingle ? 'radio' : 'checkbox']">
             <SvgIcon icon-class="check-mark" width="10" height="7" />
           </span>
-          <span class="serial-number"> {{ computedOptionNumber(i) }}. </span>
+          <span
+            v-if="!('enable_serial' in data.property) || isEnable(data.property.enable_serial)"
+            class="serial-number"
+          >
+            {{ computedOptionNumber(i) }}.
+          </span>
           <PinyinText
             v-if="isEnable(data.property.view_pinyin)"
             class="content"
@@ -68,7 +73,12 @@
           <span :class="[isSingle ? 'radio' : 'checkbox']">
             <SvgIcon icon-class="check-mark" width="10" height="7" />
           </span>
-          <span class="serial-number"> {{ computedOptionNumber(i) }}. </span>
+          <span
+            v-if="!('enable_serial' in data.property) || isEnable(data.property.enable_serial)"
+            class="serial-number"
+          >
+            {{ computedOptionNumber(i) }}.
+          </span>
           <PinyinText
             v-if="isEnable(data.property.view_pinyin)"
             class="content"