Jelajahi Sumber

预览修改

dsy 1 bulan lalu
induk
melakukan
31400bcc90

+ 11 - 0
src/views/book/courseware/preview/CoursewarePreview.vue

@@ -21,6 +21,7 @@
                 :key="k"
                 ref="preview"
                 :content="computedColContent(grid.id)"
+                :background="computedColBackground(grid.id)"
                 :class="[grid.id]"
                 :data-id="grid.id"
                 :style="{
@@ -204,6 +205,16 @@ export default {
       if (!id) return '';
       return this.componentList.find((item) => item.component_id === id)?.content || '';
     },
+    /**
+     * 计算组件背景
+     * @param {string} id 组件id
+     * @returns {object} 组件背景样式
+     */
+    computedColBackground(id) {
+      if (!id) return {};
+      const background = this.componentList.find((item) => item.component_id === id)?.background;
+      return background ? JSON.parse(background) : {};
+    },
     getMultipleColStyle(i) {
       let row = this.data.row_list[i];
       let col = row.col_list;

+ 55 - 6
src/views/book/courseware/preview/components/article/NormalModelChs.vue

@@ -56,7 +56,10 @@
         <template v-if="resArr.length > 0">
           <div class="NPC-sentences-list">
             <div class="NPC-article-empty">
-              <div :class="['empty-left', isHasRemark ? 'hasRemark' : '']"></div>
+              <div
+                :class="['empty-left', isHasRemark ? 'hasRemark' : '']"
+                :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
+              ></div>
               <div class="empty-right"></div>
             </div>
             <div
@@ -73,6 +76,7 @@
                   'article-content',
                   isHasRemark ? 'hasRemark' : '',
                 ]"
+                :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
               >
                 <template v-if="item.sourceList.length > 0 && item.sourcePosition === 'before'">
                   <img
@@ -204,7 +208,11 @@
                                         ? attrib.topic_color
                                         : pItem.notesColor
                                           ? pItem.notesColor
-                                          : pItem.config.color,
+                                          : annotationList.indexOf(pItem.chs) > -1
+                                            ? NNPEAnnotationList.find(
+                                                (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
+                                              ).notesColor
+                                            : pItem.config.color,
                                   }"
                                   @click.stop="
                                     viewNotes(
@@ -339,7 +347,12 @@
                                     ? attrib.topic_color
                                     : item.wordsList[pIndex + 1].notesColor
                                       ? item.wordsList[pIndex + 1].notesColor
-                                      : item.wordsList[pIndex + 1].config.color,
+                                      : annotationList.indexOf(item.wordsList[pIndex + 1].chs) > -1
+                                        ? NNPEAnnotationList.find(
+                                            (item) =>
+                                              item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 1].chs,
+                                          ).notesColor
+                                        : item.wordsList[pIndex + 1].config.color,
                               }"
                               @click.stop="
                                 viewNotes(
@@ -483,7 +496,12 @@
                                     ? attrib.topic_color
                                     : item.wordsList[pIndex + 2].notesColor
                                       ? item.wordsList[pIndex + 2].notesColor
-                                      : item.wordsList[pIndex + 2].config.color,
+                                      : annotationList.indexOf(item.wordsList[pIndex + 2].chs) > -1
+                                        ? NNPEAnnotationList.find(
+                                            (item) =>
+                                              item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 2].chs,
+                                          ).notesColor
+                                        : item.wordsList[pIndex + 2].config.color,
                               }"
                               @click.stop="
                                 viewNotes(
@@ -627,7 +645,11 @@
                                       ? attrib.topic_color
                                       : pItem.notesColor
                                         ? pItem.notesColor
-                                        : pItem.config.color,
+                                        : annotationList.indexOf(pItem.chs) > -1
+                                          ? NNPEAnnotationList.find(
+                                              (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
+                                            ).notesColor
+                                          : pItem.config.color,
                                 }"
                                 @click.stop="
                                   viewNotes(
@@ -1350,6 +1372,7 @@
 import AudioLine from '../voice_matrix/components/AudioLine.vue';
 import Notecard from './components/Notecard.vue';
 import RemarkChs from '../dialogue_article/RemarkChs.vue';
+import { data } from 'vis-network';
 export default {
   name: 'NormalModelChs',
   components: {
@@ -1395,6 +1418,7 @@ export default {
       contentWidth: 732,
       windowWidth: window.innerWidth,
       isHasRemark: false,
+      annotationList: [],
     };
   },
   computed: {
@@ -1448,6 +1472,9 @@ export default {
   created() {},
   // 生命周期 - 挂载完成(可以访问DOM元素)
   mounted() {
+    if (this.NNPEAnnotationList && this.NNPEAnnotationList.length > 0) {
+      this.handleNewword();
+    }
     if (this.curQue) {
       this.handleData();
     }
@@ -1660,6 +1687,17 @@ export default {
       });
       this.resObj = { sentList: resArrs, timeList };
     },
+    handleNewword() {
+      let annotationList = [];
+      this.NNPEAnnotationList.forEach((wItem) => {
+        // item.forEach((wItem) => {
+        if (wItem.con) {
+          annotationList.push(wItem.con.replace(/<[^>]*>?/gm, ''));
+        }
+        // });
+      });
+      this.annotationList = JSON.parse(JSON.stringify(annotationList));
+    },
     mergeWordTime(resArr, wordTimeList) {
       resArr.forEach((item, index) => {
         let wordsResultList = wordTimeList[index].wordsResultList;
@@ -1730,11 +1768,22 @@ export default {
         if (_this.NNPEAnnotationList && _this.NNPEAnnotationList.length > 0) {
           _this.NNPEAnnotationList.forEach((item, indexs) => {
             let textContent = item.con.replace(/<[^>]*>?/gm, '');
-            if (textContent === words.matchNotes.trim()) {
+            if (textContent === words.matchNotes.trim() || item.number === words.matchNotes.trim()) {
               noteIndex = `${String(indexs)}`;
             }
           });
         }
+      } else if (
+        _this.NNPEAnnotationList &&
+        _this.NNPEAnnotationList.length > 0 &&
+        _this.annotationList.indexOf(words.chs) > -1
+      ) {
+        _this.NNPEAnnotationList.forEach((item, indexs) => {
+          let textContent = item.con.replace(/<[^>]*>?/gm, '');
+          if (textContent === words.chs.trim()) {
+            noteIndex = `${String(indexs)}`;
+          }
+        });
       } else {
         _this.handleChangeTime(time, ed, index);
       }

+ 58 - 7
src/views/book/courseware/preview/components/article/PhraseModelChs.vue

@@ -58,7 +58,10 @@
         <template v-if="resArr.length > 0">
           <div class="NPC-sentences-list">
             <div class="NPC-article-empty">
-              <div :class="['empty-left', isHasRemark ? 'hasRemark' : '']"></div>
+              <div
+                :class="['empty-left', isHasRemark ? 'hasRemark' : '']"
+                :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
+              ></div>
               <div class="empty-right"></div>
             </div>
             <div
@@ -75,6 +78,7 @@
                   'article-content',
                   isHasRemark ? 'hasRemark' : '',
                 ]"
+                :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
               >
                 <template v-if="item.sourceList.length > 0 && item.sourcePosition === 'before'">
                   <img
@@ -179,7 +183,11 @@
                                       ? attrib.topic_color
                                       : pItem.notesColor
                                         ? pItem.notesColor
-                                        : pItem.config.color,
+                                        : annotationList.indexOf(pItem.chs) > -1
+                                          ? NNPEAnnotationList.find(
+                                              (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
+                                            ).notesColor
+                                          : pItem.config.color,
                                 }"
                                 @click.stop="viewNotes($event, pItem.chs[wIndex], pItem.chs, pItem)"
                                 >{{ convertText(pItem.chs[wIndex]) }}</span
@@ -242,7 +250,11 @@
                                 fontWeight: item.wordsList[pIndex + 1].config.fontWeight,
                                 color: item.wordsList[pIndex + 1].notesColor
                                   ? item.wordsList[pIndex + 1].notesColor
-                                  : item.wordsList[pIndex + 1].config.color,
+                                  : annotationList.indexOf(item.wordsList[pIndex + 1].chs) > -1
+                                    ? NNPEAnnotationList.find(
+                                        (item) => item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 1].chs,
+                                      ).notesColor
+                                    : item.wordsList[pIndex + 1].config.color,
                                 height:
                                   attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
                                 fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
@@ -338,7 +350,11 @@
                                 fontWeight: item.wordsList[pIndex + 2].config.fontWeight,
                                 color: item.wordsList[pIndex + 2].notesColor
                                   ? item.wordsList[pIndex + 2].notesColor
-                                  : item.wordsList[pIndex + 2].config.color,
+                                  : annotationList.indexOf(item.wordsList[pIndex + 2].chs) > -1
+                                    ? NNPEAnnotationList.find(
+                                        (item) => item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 2].chs,
+                                      ).notesColor
+                                    : item.wordsList[pIndex + 2].config.color,
                                 height:
                                   attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
                                 fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
@@ -458,7 +474,11 @@
                                     ? attrib.topic_color
                                     : pItem.notesColor
                                       ? pItem.notesColor
-                                      : pItem.config.color,
+                                      : annotationList.indexOf(pItem.chs) > -1
+                                        ? NNPEAnnotationList.find(
+                                            (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
+                                          ).notesColor
+                                        : pItem.config.color,
                               }"
                               @click.stop="viewNotes($event, pItem.chs[wIndex], pItem.chs, pItem)"
                               >{{ convertText(pItem.chs[wIndex]) }}</span
@@ -860,7 +880,13 @@
                                 textDecoration: pItem.config.textDecoration,
                                 borderBottom: pItem.config.border === 'dotted' ? '1px dotted' : '',
                                 fontWeight: pItem.config.fontWeight,
-                                color: pItem.notesColor ? pItem.notesColor : pItem.config.color,
+                                color: pItem.notesColor
+                                  ? pItem.notesColor
+                                  : annotationList.indexOf(pItem.chs) > -1
+                                    ? NNPEAnnotationList.find(
+                                        (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
+                                      ).notesColor
+                                    : pItem.config.color,
                                 height:
                                   attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
                                 fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
@@ -1100,6 +1126,7 @@ export default {
       left: 0,
       articleImg: {}, // 文章图片
       newWordList: [],
+      annotationList: [],
       word: null,
       isShow: false,
       screenHeight: 0,
@@ -1180,7 +1207,10 @@ export default {
   created() {},
   // 生命周期 - 挂载完成(可以访问DOM元素)
   mounted() {
-    if (this.NNPENewWordList && this.NNPENewWordList.length > 0) {
+    if (
+      (this.NNPENewWordList && this.NNPENewWordList.length > 0) ||
+      (this.NNPEAnnotationList && this.NNPEAnnotationList.length > 0)
+    ) {
       this.handleNewword();
     }
     if (this.curQue) {
@@ -1525,6 +1555,15 @@ export default {
         // });
       });
       this.newWordList = JSON.parse(JSON.stringify(NewWordList));
+      let annotationList = [];
+      this.NNPEAnnotationList.forEach((wItem) => {
+        // item.forEach((wItem) => {
+        if (wItem.con) {
+          annotationList.push(wItem.con.replace(/<[^>]*>?/gm, ''));
+        }
+        // });
+      });
+      this.annotationList = JSON.parse(JSON.stringify(annotationList));
     },
 
     showWordDetail(e, word, words) {
@@ -1635,6 +1674,18 @@ export default {
             }
           });
         }
+      } else if (
+        _this.NNPEAnnotationList &&
+        _this.NNPEAnnotationList.length > 0 &&
+        _this.annotationList.indexOf(words.chs) > -1
+      ) {
+        _this.NNPEAnnotationList.forEach((item, indexs) => {
+          let textContent = item.con.replace(/<[^>]*>?/gm, '');
+          if (textContent === words.chs.trim()) {
+            noteIndex = `${String(indexs)}`;
+            this.showNoteDetail(e, noteIndex);
+          }
+        });
       } else if (this.newWordList.indexOf(noteNum) > -1) {
         if (_this.oldHz !== noteNum) {
           this.isShow = false;

+ 65 - 31
src/views/book/courseware/preview/components/common/PreviewMixin.js

@@ -40,6 +40,10 @@ const mixin = {
       type: String,
       default: '',
     },
+    background: {
+      type: Object,
+      default: () => ({}),
+    },
     coursewareId: {
       type: String,
       default: '',
@@ -183,45 +187,75 @@ const mixin = {
       };
     },
     /**
-     * 得到背景图、背景色及边框样式
+     * 计算组件背景样式
+     * @returns {Object} 组件背景样式对象
      */
     getComponentStyle() {
-      let backgroundData = {};
-      if (Object.hasOwn(this.data.property, 'background_image_url')) {
-        // 保护性读取位置/大小值,避免 undefined 导致字符串 "undefined%"
-        const { background_position: pos } = this.data.property;
-        const widthPct = typeof pos.width === 'undefined' ? '' : pos.width;
-        const heightPct = typeof pos.height === 'undefined' ? '' : pos.height;
-        const leftPct = typeof pos.left === 'undefined' ? '' : pos.left;
-        const topPct = typeof pos.top === 'undefined' ? '' : pos.top;
+      const {
+        background_image_url: bcImgUrl = '',
+        background_position: pos = {},
+        background: back,
+      } = this.background || {};
+
+      let canvasStyle = {
+        backgroundSize: bcImgUrl ? `${pos.width}% ${pos.height}%` : '',
+        backgroundPosition: bcImgUrl ? `${pos.left}% ${pos.top}%` : '',
+        backgroundImage: bcImgUrl ? `url(${bcImgUrl})` : '',
+        backgroundColor: bcImgUrl ? `rgba(255, 255, 255, ${1 - back?.image_opacity / 100})` : '',
+      };
 
-        backgroundData.backgroundImage = `url(${this.data.property.background_image_url})`;
-        let bcSize = '';
-        if (pos.image_mode === 'fill') {
-          bcSize = '100% 100%';
-        } else if (pos.image_mode === 'repeat') {
-          bcSize = 'auto';
+      if (back) {
+        if (back.mode === 'image') {
+          canvasStyle['backgroundBlendMode'] = 'lighten';
         } else {
-          bcSize = `${widthPct}% ${heightPct}%`;
+          canvasStyle['backgroundBlendMode'] = '';
+        }
+
+        if (back.imageMode === 'fill') {
+          canvasStyle['backgroundRepeat'] = 'repeat';
+          canvasStyle['backgroundSize'] = '';
+          canvasStyle['backgroundPosition'] = '';
+        } else {
+          canvasStyle['backgroundRepeat'] = 'no-repeat';
+        }
+
+        if (back.imageMode === 'stretch') {
+          canvasStyle['backgroundSize'] = '100% 100%';
+        }
+
+        if (back.imageMode === 'adapt') {
+          canvasStyle['backgroundSize'] = 'contain';
         }
-        backgroundData.backgroundSize = bcSize;
-        backgroundData.backgroundPosition = pos.image_mode === 'fill' ? '0% 0%' : `${leftPct}% ${topPct}%`;
-        backgroundData.backgroundRepeat = pos.image_mode === 'repeat' ? 'repeat' : 'no-repeat';
-      }
 
-      let borderData = {};
-      if (Object.hasOwn(this.data.property, 'is_border')) {
-        const isBorder = isEnable(this.data.property.is_border);
-        borderData.borderWidth = isBorder ? (this.data.property.border_style === 'double' ? '3px' : '1px') : '0px';
-        borderData.borderStyle = isBorder ? this.data.property.border_style : 'none';
-        borderData.borderColor = isBorder ? this.data.property.border_color : 'transparent';
+        if (back.imageMode === 'auto') {
+          canvasStyle['backgroundPosition'] = `${pos.imgX}% ${pos.imgY}%`;
+        }
+
+        if (back.mode === 'color') {
+          canvasStyle['backgroundColor'] = back.color;
+          canvasStyle['backgroundImage'] = '';
+          canvasStyle['backgroundRepeat'] = '';
+          canvasStyle['backgroundPosition'] = '';
+          canvasStyle['backgroundSize'] = '';
+        }
+
+        if (back.enable_border) {
+          canvasStyle['border'] = `${back.border_width}px ${back.border_style} ${back.border_color}`;
+        } else {
+          canvasStyle['border'] = 'none';
+        }
+
+        if (back.enable_radius) {
+          canvasStyle['border-top-left-radius'] = `${back.top_left_radius}px`;
+          canvasStyle['border-top-right-radius'] = `${back.top_right_radius}px`;
+          canvasStyle['border-bottom-left-radius'] = `${back.bottom_left_radius}px`;
+          canvasStyle['border-bottom-right-radius'] = `${back.bottom_right_radius}px`;
+        } else {
+          canvasStyle['border-radius'] = '0';
+        }
       }
 
-      return {
-        backgroundColor: this.data.property?.background_color,
-        ...backgroundData,
-        ...borderData,
-      };
+      return canvasStyle;
     },
     // 显示答案与解析页面
     showAnswerAnalysis() {

+ 63 - 6
src/views/book/courseware/preview/components/dialogue_article/NormalModelChs.vue

@@ -59,7 +59,10 @@
         }"
       >
         <div class="NPC-article-empty">
-          <div :class="['empty-left', isHasRemark ? 'hasRemark' : '']"></div>
+          <div
+            :class="['empty-left', isHasRemark ? 'hasRemark' : '']"
+            :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
+          ></div>
           <div class="empty-right"></div>
         </div>
 
@@ -86,6 +89,7 @@
                 attrib
                   ? attrib.assist_color
                   : '',
+              width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '',
             }"
           >
             <template v-if="item.type === 'notice'">
@@ -119,6 +123,12 @@
                       borderBottom: pItem.border === 'dotted' ? '1px dotted' : '',
                       fontWeight: pItem.fontWeight,
                       color: pItem.color,
+                      display: 'inline-block',
+                      margin: /^[A-Za-z]+$/.test(pItem.chs)
+                        ? indexs === 0 && indexss === 0
+                          ? '0 2px 0 0'
+                          : '0 2px'
+                        : '',
                     }"
                   >
                     {{ convertText(pItem.chs) }}
@@ -249,7 +259,11 @@
                                           ? attrib.topic_color
                                           : pItem.notesColor
                                             ? pItem.notesColor
-                                            : pItem.config.color,
+                                            : annotationList.indexOf(pItem.chs) > -1
+                                              ? NNPEAnnotationList.find(
+                                                  (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
+                                                ).notesColor
+                                              : pItem.config.color,
                                       fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
                                       lineHeight:
                                         attrib && attrib.font_size
@@ -360,7 +374,12 @@
                                       ? attrib.topic_color
                                       : item.wordsList[pIndex + 1].notesColor
                                         ? item.wordsList[pIndex + 1].notesColor
-                                        : item.wordsList[pIndex + 1].config.color,
+                                        : annotationList.indexOf(item.wordsList[pIndex + 1].chs) > -1
+                                          ? NNPEAnnotationList.find(
+                                              (item) =>
+                                                item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 1].chs,
+                                            ).notesColor
+                                          : item.wordsList[pIndex + 1].config.color,
                                   fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
                                   lineHeight:
                                     attrib && attrib.font_size
@@ -485,7 +504,12 @@
                                       ? attrib.topic_color
                                       : item.wordsList[pIndex + 2].notesColor
                                         ? item.wordsList[pIndex + 2].notesColor
-                                        : item.wordsList[pIndex + 2].config.color,
+                                        : annotationList.indexOf(item.wordsList[pIndex + 2].chs) > -1
+                                          ? NNPEAnnotationList.find(
+                                              (item) =>
+                                                item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 2].chs,
+                                            ).notesColor
+                                          : item.wordsList[pIndex + 2].config.color,
                                   fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
                                   lineHeight:
                                     attrib && attrib.font_size
@@ -613,7 +637,11 @@
                                         ? attrib.topic_color
                                         : pItem.notesColor
                                           ? pItem.notesColor
-                                          : pItem.config.color,
+                                          : annotationList.indexOf(pItem.chs) > -1
+                                            ? NNPEAnnotationList.find(
+                                                (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
+                                              ).notesColor
+                                            : pItem.config.color,
                                     fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
                                     lineHeight:
                                       attrib && attrib.font_size
@@ -724,7 +752,10 @@
           </div>
         </div>
         <div class="NPC-article-empty NPC-article-empty-bottom">
-          <div :class="['empty-left', isHasRemark ? 'hasRemark' : '']"></div>
+          <div
+            :class="['empty-left', isHasRemark ? 'hasRemark' : '']"
+            :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
+          ></div>
           <div class="empty-right"></div>
         </div>
         <template v-for="(items, indexs) in curQue.detail">
@@ -896,6 +927,7 @@ export default {
       contentWidth: 732,
       ed: undefined,
       windowWidth: window.innerWidth,
+      annotationList: [],
     };
   },
   computed: {
@@ -949,6 +981,9 @@ export default {
   created() {},
   // 生命周期 - 挂载完成(可以访问DOM元素)
   mounted() {
+    if (this.NNPEAnnotationList && this.NNPEAnnotationList.length > 0) {
+      this.handleNewword();
+    }
     if (this.curQue) {
       this.handleData();
       window.addEventListener('resize', this.getScreenHeight);
@@ -1096,6 +1131,17 @@ export default {
         });
       }
     },
+    handleNewword() {
+      let annotationList = [];
+      this.NNPEAnnotationList.forEach((wItem) => {
+        // item.forEach((wItem) => {
+        if (wItem.con) {
+          annotationList.push(wItem.con.replace(/<[^>]*>?/gm, ''));
+        }
+        // });
+      });
+      this.annotationList = JSON.parse(JSON.stringify(annotationList));
+    },
     mergeWordTime(resArr, wordTimeList) {
       resArr.forEach((item, index) => {
         let wordsResultList = wordTimeList[index].wordsResultList;
@@ -1186,6 +1232,17 @@ export default {
             }
           });
         }
+      } else if (
+        _this.NNPEAnnotationList &&
+        _this.NNPEAnnotationList.length > 0 &&
+        _this.annotationList.indexOf(words.chs) > -1
+      ) {
+        _this.NNPEAnnotationList.forEach((item, indexs) => {
+          let textContent = item.con.replace(/<[^>]*>?/gm, '');
+          if (textContent === words.chs.trim()) {
+            noteIndex = `${String(indexs)}`;
+          }
+        });
       } else {
         _this.handleChangeTime(time, item, ed);
       }

+ 63 - 7
src/views/book/courseware/preview/components/dialogue_article/PhraseModelChs.vue

@@ -57,7 +57,10 @@
         }"
       >
         <div class="NPC-article-empty">
-          <div :class="['empty-left', isHasRemark ? 'hasRemark' : '']"></div>
+          <div
+            :class="['empty-left', isHasRemark ? 'hasRemark' : '']"
+            :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
+          ></div>
           <div class="empty-right"></div>
         </div>
 
@@ -77,6 +80,7 @@
                 attrib
                   ? attrib.assist_color
                   : '',
+              width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '',
             }"
           >
             <template v-if="item.type === 'notice'">
@@ -110,6 +114,12 @@
                       borderBottom: pItem.border === 'dotted' ? '1px dotted' : '',
                       fontWeight: pItem.fontWeight,
                       color: pItem.color,
+                      display: 'inline-block',
+                      margin: /^[A-Za-z]+$/.test(pItem.chs)
+                        ? indexs === 0 && indexss === 0
+                          ? '0 2px 0 0'
+                          : '0 2px'
+                        : '',
                     }"
                   >
                     {{ convertText(pItem.chs) }}
@@ -215,7 +225,11 @@
                                         : pItem.config.color
                                       : pItem.notesColor
                                         ? pItem.notesColor
-                                        : pItem.config.color,
+                                        : annotationList.indexOf(pItem.chs) > -1
+                                          ? NNPEAnnotationList.find(
+                                              (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
+                                            ).notesColor
+                                          : pItem.config.color,
                                 }"
                                 @click.stop="viewNotes($event, pItem.words ? pItem.words : pItem.chs, pItem)"
                                 >{{ convertText(pItem.chs) }}</span
@@ -290,7 +304,12 @@
                                         : item.wordsList[pIndex + 1].config.color
                                       : item.wordsList[pIndex + 1].notesColor
                                         ? item.wordsList[pIndex + 1].notesColor
-                                        : item.wordsList[pIndex + 1].config.color,
+                                        : annotationList.indexOf(item.wordsList[pIndex + 1].chs) > -1
+                                          ? NNPEAnnotationList.find(
+                                              (item) =>
+                                                item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 1].chs,
+                                            ).notesColor
+                                          : item.wordsList[pIndex + 1].config.color,
                                 }"
                                 @click.stop="
                                   viewNotes(
@@ -394,7 +413,12 @@
                                         : item.wordsList[pIndex + 2].config.color
                                       : item.wordsList[pIndex + 2].notesColor
                                         ? item.wordsList[pIndex + 2].notesColor
-                                        : item.wordsList[pIndex + 2].config.color,
+                                        : annotationList.indexOf(item.wordsList[pIndex + 2].chs) > -1
+                                          ? NNPEAnnotationList.find(
+                                              (item) =>
+                                                item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 2].chs,
+                                            ).notesColor
+                                          : item.wordsList[pIndex + 2].config.color,
                                 }"
                                 @click.stop="
                                   viewNotes(
@@ -476,7 +500,11 @@
                                       : pItem.config.color
                                     : pItem.notesColor
                                       ? pItem.notesColor
-                                      : pItem.config.color,
+                                      : annotationList.indexOf(pItem.chs) > -1
+                                        ? NNPEAnnotationList.find(
+                                            (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
+                                          ).notesColor
+                                        : pItem.config.color,
                               }"
                               @click.stop="viewNotes($event, pItem.words ? pItem.words : pItem.chs, pItem)"
                               >{{ convertText(pItem.chs) }}</span
@@ -558,7 +586,10 @@
           </div>
         </div>
         <div class="NPC-article-empty NPC-article-empty-bottom">
-          <div :class="['empty-left', isHasRemark ? 'hasRemark' : '']"></div>
+          <div
+            :class="['empty-left', isHasRemark ? 'hasRemark' : '']"
+            :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
+          ></div>
           <div class="empty-right"></div>
         </div>
         <template v-for="(items, indexs) in curQue.detail">
@@ -747,6 +778,7 @@ export default {
       left: 0,
       articleImg: {}, // 文章图片
       newWordList: [],
+      annotationList: [],
       word: null,
       isShow: false,
       screenHeight: 0,
@@ -828,7 +860,10 @@ export default {
   created() {},
   // 生命周期 - 挂载完成(可以访问DOM元素)
   mounted() {
-    if (this.NNPENewWordList && this.NNPENewWordList.length > 0) {
+    if (
+      (this.NNPENewWordList && this.NNPENewWordList.length > 0) ||
+      (this.NNPEAnnotationList && this.NNPEAnnotationList.length > 0)
+    ) {
       this.handleNewword();
     }
     if (this.curQue) {
@@ -1075,6 +1110,15 @@ export default {
         // });
       });
       this.newWordList = JSON.parse(JSON.stringify(NewWordList));
+      let annotationList = [];
+      this.NNPEAnnotationList.forEach((wItem) => {
+        // item.forEach((wItem) => {
+        if (wItem.con) {
+          annotationList.push(wItem.con.replace(/<[^>]*>?/gm, ''));
+        }
+        // });
+      });
+      this.annotationList = JSON.parse(JSON.stringify(annotationList));
     },
 
     showWordDetail(e, word, words) {
@@ -1187,6 +1231,18 @@ export default {
             }
           });
         }
+      } else if (
+        _this.NNPEAnnotationList &&
+        _this.NNPEAnnotationList.length > 0 &&
+        _this.annotationList.indexOf(words.chs) > -1
+      ) {
+        _this.NNPEAnnotationList.forEach((item, indexs) => {
+          let textContent = item.con.replace(/<[^>]*>?/gm, '');
+          if (textContent === words.chs.trim()) {
+            noteIndex = `${String(indexs)}`;
+            this.showNoteDetail(e, noteIndex);
+          }
+        });
       } else if (this.newWordList.indexOf(noteNum) > -1) {
         if (_this.oldHz !== noteNum) {
           this.isShow = false;

+ 6 - 0
src/views/book/courseware/preview/components/dialogue_article/WordModelChs.vue

@@ -109,6 +109,12 @@
                       borderBottom: pItem.border === 'dotted' ? '1px dotted' : '',
                       fontWeight: pItem.fontWeight,
                       color: pItem.color,
+                      display: 'inline-block',
+                      margin: /^[A-Za-z]+$/.test(pItem.chs)
+                        ? indexs === 0 && indexss === 0
+                          ? '0 2px 0 0'
+                          : '0 2px'
+                        : '',
                     }"
                   >
                     {{ convertText(pItem.chs) }}

+ 5 - 5
src/views/book/courseware/preview/components/picture/PicturePreview.vue

@@ -1,5 +1,5 @@
 <template>
-  <div ref="pictureArea" class="picture-preview" :style="getAreaStyle()">
+  <div ref="pictureArea" class="picture-preview" :style="[getAreaStyle(), getComponentStyle()]">
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
 
     <div ref="pictureAreaBox" class="main">
@@ -10,7 +10,7 @@
             ref="pictureCarousel"
             indicator-position="none"
             :autoplay="false"
-            :style="{ height: elementHeight - 144 - 32 + 'px' }"
+            :style="{ height: `${elementHeight - 144 - 32}px` }"
             @change="handleChange"
           >
             <el-carousel-item v-for="(file, i) in data.file_list" :key="i">
@@ -37,8 +37,8 @@
           </div>
         </div>
         <div
-          v-else
           v-for="file in data.file_list"
+          v-else
           :key="file.file_id"
           class="alone-pic-area"
           :style="getVideoItemStyle()"
@@ -89,7 +89,7 @@ export default {
     data: {
       handler(val) {
         this.fileLen = val.file_list.length;
-        if (this.fileLen == 0) return;
+        if (this.fileLen === 0) return;
         if (this.data.property.view_method === 'list') {
           const ele = this.$refs.pictureAreaBox;
           const sn_position = this.data.property.sn_position;
@@ -136,7 +136,7 @@ export default {
         }
 
         this.elementHeight = Math.max(this.elementHeight, this.data.min_height);
-        this.$emit('handleHeightChange', this.id, this.elementHeight + 'px');
+        this.$emit('handleHeightChange', this.id, `${this.elementHeight}px`);
       },
       deep: true,
     },

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

@@ -59,7 +59,11 @@
                   :class="[
                     'item-con',
                     active_index_str === 0 + '-' + indexc ? 'active' : '',
-                    isJudgingRightWrong && !con_preview[0].user_answer[indexc].is_right ? 'error' : '',
+                    isJudgingRightWrong &&
+                    con_preview[0].user_answer[indexc].is_right !== '' &&
+                    !con_preview[0].user_answer[indexc].is_right
+                      ? 'error'
+                      : '',
                     data.property.fun_type === 'show' ? 'item-con-in' : '',
                   ]"
                   @click="
@@ -77,23 +81,12 @@
                 <span
                   v-for="(itemi, indexi) in itemc"
                   :key="indexi"
-                  :class="[
-                    'items-con',
-                    active_index_str === 0 + '-' + indexc + '-' + indexi ? 'active' : '',
-                    isJudgingRightWrong &&
-                    !con_preview[0].user_answer[indexc].is_right &&
-                    con_preview[0].user_answer[indexc].select_index_submit === indexi
-                      ? 'error'
-                      : '',
-                    isJudgingRightWrong &&
-                    !con_preview[0].user_answer[indexc].is_right &&
-                    con_preview[0].user_answer[indexc].right_index === indexi
-                      ? 'right'
-                      : '',
-                  ]"
+                  :class="['items-con', active_index_str === 0 + '-' + indexc + '-' + indexi ? 'active' : '']"
                   @click="handleSelectItemTone(0, indexc, indexi, con_preview[0].item_con_yuan[indexc][indexi])"
                   >{{ itemi }}</span
                 >
+                <!-- 拼音之间增加一点间隙 -->
+                <span v-if="indexc !== con_preview[0].item_con.length - 1" style="opacity: 0">a</span>
               </span>
             </template>
           </div>
@@ -155,9 +148,9 @@
           data.property.fun_type !== 'show' ||
           (data.property.fun_type === 'show' && isEnable(data.property.is_enable_voice_answer))
         "
+        :is-show-answer="isShowAnswers"
         @showAnswerAnalysis="showAnswerAnalysis"
         @retry="retry"
-        :isShowAnswer="isShowAnswers"
       />
       <AnswerCorrect
         :answer-correct="data?.answer_correct"
@@ -170,7 +163,7 @@
         :analysis-list="data.analysis_list"
         @closeAnswerAnalysis="closeAnswerAnalysis"
       >
-        <div v-if="data.property.fun_type === 'input'" slot="right-answer" class="right-answer">
+        <div v-if="data.property.fun_type !== 'show'" slot="right-answer" class="right-answer">
           <div
             class="content-box"
             :class="[data.property.arrange_type === 'horizontal' ? 'content-box-flex' : 'content-box-vertical']"
@@ -193,7 +186,7 @@
                 <!-- 拼音输入 -->
                 <template v-if="data.property.fun_type === 'input'">
                   <span
-                    v-for="(itemc, indexc) in con_preview"
+                    v-for="(itemc, indexc) in con_preview_right"
                     :key="indexc"
                     :class="['item-con', itemc.type === 'input' ? 'right' : '']"
                   >
@@ -201,18 +194,95 @@
                       v-if="itemc.type === 'input'"
                       v-model="itemc.answer"
                       :disabled="true"
-                      :style="[{ width: Math.max(20, itemc.con.length * 10) + 'px' }]"
+                      :style="[{ width: Math.max(20, itemc.answer.length * 10) + 'px' }]"
                       class="item-input"
                     />
                     <span v-else>{{ itemc.con }}</span>
                   </span>
                 </template>
+                <template v-else-if="data.property.answer_mode === 'select'">
+                  <span
+                    v-for="(itemc, indexc) in data.matically_pinyin_str[data.mark].split(' ')"
+                    :key="indexc"
+                    :class="['item-con', active_index_str_right === 0 + '-' + indexc ? 'active' : '']"
+                    @click="
+                      if (data.property.fun_type === 'show') return;
+                      con_preview_right[0].item_active_index = indexc;
+                      active_index_str_right = 0 + '-' + indexc;
+                    "
+                  >
+                    {{ itemc }}
+                  </span>
+                  <!-- <span
+                    v-for="(itemc, indexc) in con_preview_right[0].item_con"
+                    :key="indexc"
+                    :class="[
+                      'item-con',
+                      active_index_str === 0 + '-' + indexc ? 'active' : '',
+                      data.property.fun_type === 'show' ? 'item-con-in' : '',
+                    ]"
+                    @click="
+                      if (data.property.fun_type === 'show') return;
+                      con_preview_right[0].item_active_index = indexc;
+                      active_index_str = 0 + '-' + indexc;
+                    "
+                  >
+                    {{ itemc }}
+                  </span> -->
+                </template>
+                <template v-else>
+                  <span
+                    v-for="(itemc, indexc) in data.matically_pinyin_str[data.mark].split(' ')"
+                    :key="indexc"
+                    class="items-box"
+                  >
+                    <span
+                      v-for="(itemi, indexi) in itemc"
+                      :key="indexi"
+                      :class="['items-con', active_index_str_right === 0 + '-' + indexc + '-' + indexi ? 'active' : '']"
+                      @click="
+                        handleSelectItemTone(0, indexc, indexi, con_preview_right[0].item_con_yuan[indexc][indexi])
+                      "
+                      >{{ itemi }}</span
+                    >
+                    <!-- 拼音之间增加一点间隙 -->
+                    <span
+                      v-if="indexc !== data.matically_pinyin_str[data.mark].split(' ').length - 1"
+                      style="opacity: 0"
+                      >a</span
+                    >
+                  </span>
+                </template>
               </div>
               <AudioPlay
                 v-if="data.audio_file_id && data.property.audio_position === 'back'"
                 :file-id="data.audio_file_url"
               />
             </div>
+            <div v-if="data.property.fun_type === 'mark'" class="tone-box">
+              <span
+                v-for="({ img, value }, j) in toneList"
+                :key="j"
+                :class="[
+                  'tone',
+                  (isJudgingRightWrong &&
+                    con_preview_right[0].user_answer[con_preview_right[0].item_active_index].right_answer === value &&
+                    con_preview_right[0].user_answer[con_preview_right[0].item_active_index].select_index_submit !==
+                      con_preview_right[0].user_answer[con_preview_right[0].item_active_index].right_answer &&
+                    data.property.answer_mode === 'select') ||
+                  (isJudgingRightWrong &&
+                    data.property.answer_mode === 'label' &&
+                    con_preview_right[0].user_answer[con_preview_right[0].item_active_index].right_answer === value &&
+                    con_preview_right[0].user_answer[con_preview_right[0].item_active_index].right_index ===
+                      con_preview_right[0].user_answer[con_preview_right[0].item_active_index].select_index &&
+                    select_item_index === 0)
+                    ? 'right'
+                    : '',
+                ]"
+              >
+                <SvgIcon :icon-class="img" />
+              </span>
+            </div>
           </div>
         </div>
       </AnswerAnalysis>
@@ -248,6 +318,7 @@ export default {
         // { value: '0', label: '轻声', img: 'neutral-tone' },
       ],
       con_preview: [],
+      con_preview_right: [], // 查看答案是显示的
       tone_data: [
         ['ā', 'á', 'ǎ', 'à', 'a'],
         ['ō', 'ó', 'ǒ', 'ò', 'o'],
@@ -266,6 +337,7 @@ export default {
       ],
       final_con: '',
       active_index_str: '', // 高亮索引的字符串
+      active_index_str_right: '', // 查看答案时高亮索引
       active_letter: '', // 选中字母的值
       active_letter_index: 0, // 选择字母索引
       select_item_index: 0, // 小题索引
@@ -294,11 +366,11 @@ export default {
     },
   },
   created() {
-    // console.log(this.data);
     if (
       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.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;
     } else {
@@ -558,15 +630,26 @@ export default {
       if (this.data.property.fun_type === 'show') {
         return;
       }
-      this.con_preview[0].item_active_index = indexc;
-      this.con_preview[0].user_answer[indexc].select_index = indexi;
-      this.active_index_str = `${i}-${indexc}-${indexi}`;
-      this.active_letter = itemi;
-      this.active_letter_index = indexi;
-      this.select_item_index = i;
+      if (this.isJudgingRightWrong) {
+        this.con_preview_right[0].item_active_index = indexc;
+        this.con_preview_right[0].user_answer[indexc].select_index = indexi;
+        this.active_index_str_right = `${i}-${indexc}-${indexi}`;
+      } else {
+        this.con_preview[0].item_active_index = indexc;
+        this.con_preview[0].user_answer[indexc].select_index = indexi;
+        this.active_index_str = `${i}-${indexc}-${indexi}`;
+        this.select_item_index = i;
+        this.active_letter = itemi;
+        this.active_letter_index = indexi;
+      }
     },
     // 判断对错
     judgeRight() {
+      let active_index_old = 0;
+      this.active_index_str_right = '';
+      if (this.con_preview.length > 0) {
+        active_index_old = this.con_preview[0].item_active_index;
+      }
       this.show_preview = false;
 
       let answer_list_item = this.answer.answer_list.filter((items) => this.data.mark === items.mark);
@@ -582,6 +665,7 @@ export default {
           }
         });
       } else {
+        let old_con_preview = JSON.parse(JSON.stringify(this.con_preview));
         this.con_preview = [];
         let con_arr = JSON.parse(JSON.stringify(this.data.content_view));
         let user_answer = [];
@@ -642,18 +726,20 @@ export default {
           }
         });
         let obj = {
-          item_con: user_select,
+          item_con: old_con_preview[0].item_con,
           item_con_yuan: JSON.parse(JSON.stringify(con_arr)),
           mark: this.data.mark,
           user_answer,
-          item_active_index: 0,
+          item_active_index: active_index_old,
           active_letter: '',
           user_res_arr,
           all_right:
-            JSON.stringify(answer_list_item[0].value) === JSON.stringify(this.data.answer.answer_list[0].value),
+            answer_list_item[0].value.length === this.data.answer.answer_list[0].value.length &&
+            answer_list_item[0].value.every((value, index) => value === this.data.answer.answer_list[0].value[index]),
         };
         this.con_preview.push(obj);
       }
+      this.con_preview_right = JSON.parse(JSON.stringify(this.con_preview));
 
       setTimeout(() => {
         this.show_preview = true;