Просмотр исходного кода

Merge branch 'master' of http://gcls-git.helxsoft.cn/GCLS/eep_page

zq 3 месяцев назад
Родитель
Сommit
1a95b8356f

+ 17 - 0
preload.js

@@ -88,4 +88,21 @@ contextBridge.exposeInMainWorld('fileAPI', {
    * @returns {Promise} 文件路径
    */
   openFileDialog: (opts) => ipcRenderer.invoke('dialog:openFiles', opts),
+
+  /**
+   * 检查文件路径是否存在
+   * @param {string} filePath 文件路径
+   * @returns {boolean} 是否存在
+   */
+  existsSync: (filePath) => fs.existsSync(filePath),
+
+  /**
+   * 创建目录(递归)
+   * @param {string} dirPath 目录路径
+   */
+  mkdirSync: (dirPath) => {
+    if (!fs.existsSync(dirPath)) {
+      fs.mkdirSync(dirPath, { recursive: true });
+    }
+  },
 });

+ 9 - 9
src/components/CommonPreview.vue

@@ -162,7 +162,7 @@
                 </el-table-column>
                 <el-table-column label="" width="50">
                   <template #default="{ row }">
-                    <el-link type="primary" @click="handLocation(row, 3)">定位</el-link>
+                    <el-link type="primary" @click="handleLocation(row, 3)">定位</el-link>
                   </template>
                 </el-table-column>
               </el-table>
@@ -220,7 +220,7 @@
                   <el-divider direction="vertical" />
                   <el-button type="text" class="el-icon-delete" @click="handDelNote(item.id)"> 删除</el-button>
                   <el-divider direction="vertical" />
-                  <el-button type="text" class="el-icon-place" @click="handLocation(item, 1)"> 定位</el-button>
+                  <el-button type="text" class="el-icon-place" @click="handleLocation(item, 1)"> 定位</el-button>
                 </div>
               </li>
             </ul>
@@ -235,7 +235,7 @@
                 <div class="remark-bottom">
                   <el-button type="text" class="el-icon-delete" @click="handDelCollect(item.id)"> 删除</el-button>
                   <el-divider direction="vertical" />
-                  <el-button type="text" class="el-icon-place" @click="handLocation(item, 2)"> 定位</el-button>
+                  <el-button type="text" class="el-icon-place" @click="handleLocation(item, 2)"> 定位</el-button>
                 </div>
               </li>
             </ul>
@@ -430,7 +430,7 @@ export default {
       component_list: [],
       content_group_row_list: [],
       remark_list: [],
-      remark_list_obj: {}, // 存放以组件为对象的数组
+      remark_list_obj: {}, // 存放以组件为对象的批注数组
       searchList: [],
       searchContent: '',
       visible: false,
@@ -907,15 +907,15 @@ export default {
         behavior: 'smooth',
       });
     },
-    handLocation(item, type) {
-      if (type == 3) {
-        var did = item.courseware_id + '#' + item.component_id;
+    handleLocation(item, type) {
+      if (type === 3) {
+        let did = `${item.courseware_id}#${item.component_id}`;
         this.handleNodeClick(did);
         return;
       }
-      if (this.$refs.courserware && this.$refs.courserware.handLocation) {
+      if (this.$refs.courserware && this.$refs.courserware.handleLocation) {
         item.type = type;
-        this.$refs.courserware.handLocation(item);
+        this.$refs.courserware.handleLocation(item);
       }
     },
     async getNote(params) {

+ 5 - 0
src/styles/font/font.css

@@ -6,4 +6,9 @@
 @font-face {
   font-family: 'League';
   src: url('GBPinyinok-B-new.otf');
+}
+
+@font-face {
+  font-family: 'Sans-GBNPC';
+  src: url('GBPinyinok-B-new.otf');
 }

+ 33 - 4
src/views/book/courseware/create/components/CreateCanvas.vue

@@ -72,6 +72,7 @@
                   :id="grid.id"
                   ref="component"
                   :key="`grid-${grid.id}`"
+                  :old-id="grid?.oldId"
                   :class="[grid.id]"
                   :data-row="i"
                   :data-col="j"
@@ -1330,19 +1331,47 @@ export default {
      * @param {Array} param.content_group_row_list - 内容分组行列表
      */
     insertTemplateData_CreateCanvas({ row_list = [], content_group_row_list = [] }) {
+      let contentGroupRowList = JSON.parse(JSON.stringify(content_group_row_list));
+
+      let rowList = row_list.map((row) => {
+        const oldRowID = row.row_id;
+        const newRowID = `R${getRandomNumber(6, true)}`;
+        row.row_id = newRowID;
+        // 更新内容分组行列表中的 row_id
+        for (let idx = 0; idx < contentGroupRowList.length; idx++) {
+          if (contentGroupRowList[idx].row_id === oldRowID) {
+            contentGroupRowList[idx] = { ...contentGroupRowList[idx], row_id: newRowID };
+          }
+        }
+
+        row.col_list = row.col_list.map((col) => {
+          col.col_id = `C${getRandomNumber(8, true)}`;
+
+          col.grid_list = col.grid_list.map((grid) => {
+            grid.oldId = grid.id;
+            grid.id = `ID-${getRandomNumber(12, true)}`;
+            grid.grid_area = `L${getRandomNumber(6, true)}`;
+            return grid;
+          });
+
+          return col;
+        });
+        return row;
+      });
+
       const curId = this.getCurSettingId();
       // 如果无选中组件,则插入到最后
       if (!curId) {
-        this.data.row_list.push(...row_list);
-        this.content_group_row_list.push(...content_group_row_list);
+        this.data.row_list.push(...rowList);
+        this.content_group_row_list.push(...contentGroupRowList);
         return;
       }
       // 插入到当前选中组件后面
       const attrs = this.findChildComponentByKey(`grid-${curId}`)?.$attrs;
       if (!attrs) return;
       const i = Number(attrs['data-row']);
-      this.data.row_list.splice(i + 1, 0, ...row_list);
-      this.content_group_row_list.splice(i + 1, 0, ...content_group_row_list);
+      this.data.row_list.splice(i + 1, 0, ...rowList);
+      this.content_group_row_list.splice(i + 1, 0, ...contentGroupRowList);
     },
     /**
      * @description 复制组件

+ 14 - 0
src/views/book/courseware/create/components/base/h5_games/H5Games.vue

@@ -24,6 +24,7 @@
 import ModuleMixin from '../../common/ModuleMixin';
 import UploadFile from '../common/UploadFile.vue';
 import { getH5GamesData } from '@/views/book/courseware/data/h5Games';
+import { H5StartupFile } from '@/api/app';
 
 export default {
   name: 'H5GamesPage',
@@ -45,6 +46,19 @@ export default {
       this.data.file_list = file_list;
       this.data.file_id_list = file_id_list;
       this.data.file_info = file_info;
+      this.data.file_list.forEach((item, index) => {
+        const suffix = item.file_url
+          ? item.file_url.slice(item.file_url.lastIndexOf('.') + 1, item.file_url.length).toLowerCase()
+          : '';
+        if (suffix === 'zip') {
+          H5StartupFile({ file_id: item.file_id, index_file_name: 'index.html' }).then((res) => {
+            this.$set(this.data.file_info, res.file_id, this.data.file_info[item.file_id]);
+            item.file_url = res.file_url;
+            item.file_id = res.file_id;
+            this.data.file_id_list[index] = res.file_id;
+          });
+        }
+      });
     },
     handleMindMap() {
       // 思维导图数据

+ 34 - 30
src/views/book/courseware/create/components/common/ModuleMixin.js

@@ -30,6 +30,10 @@ const mixin = {
       type: String,
       required: true,
     },
+    oldId: {
+      type: String,
+      default: '',
+    },
     componentMove: {
       type: Function,
       required: true,
@@ -94,43 +98,43 @@ const mixin = {
       if (this.courseware_id === '' || this.id === '') return;
       let temporaryCoursewareID = this.getTemporaryCoursewareID();
       let coursewareID = temporaryCoursewareID || this.courseware_id;
-      ContentGetCoursewareComponentContent({ courseware_id: coursewareID, component_id: this.id }).then(
-        ({ content }) => {
-          if (content) {
-            this.data = JSON.parse(content);
-          } else {
-            const bookUnifiedAttr = this.getBookUnifiedAttr();
+      let component_id = temporaryCoursewareID.length > 0 ? this.oldId || this.id : this.id;
 
-            this.$set(this.data, 'unified_attrib', bookUnifiedAttr);
+      ContentGetCoursewareComponentContent({ courseware_id: coursewareID, component_id }).then(({ content }) => {
+        if (content) {
+          this.data = JSON.parse(content);
+        } else {
+          const bookUnifiedAttr = this.getBookUnifiedAttr();
 
-            // 初始化时,如果有 view_pinyin 则根据全教材设置配置设 view_pinyin 和 pinyin_position
-            if ('view_pinyin' in this.data.property) {
-              this.data.property.view_pinyin = bookUnifiedAttr?.view_pinyin ?? 'false';
-              this.data.property.pinyin_position = bookUnifiedAttr?.pinyin_position ?? 'top';
-            }
+          this.$set(this.data, 'unified_attrib', bookUnifiedAttr);
 
-            if ('frame_color' in this.data.property) {
-              // 框颜色初始化为主题色
-              this.data.property.frame_color = bookUnifiedAttr?.topic_color ?? '#F13232';
-            }
+          // 初始化时,如果有 view_pinyin 则根据全教材设置配置设 view_pinyin 和 pinyin_position
+          if ('view_pinyin' in this.data.property) {
+            this.data.property.view_pinyin = bookUnifiedAttr?.view_pinyin ?? 'false';
+            this.data.property.pinyin_position = bookUnifiedAttr?.pinyin_position ?? 'top';
+          }
 
-            if ('sn_background_color' in this.data.property) {
-              // 序号背景色
-              this.data.property.sn_background_color = bookUnifiedAttr?.topic_color ?? '#EA3232';
-            }
+          if ('frame_color' in this.data.property) {
+            // 框颜色初始化为主题色
+            this.data.property.frame_color = bookUnifiedAttr?.topic_color ?? '#F13232';
           }
 
-          this.property.isGetContent = true;
+          if ('sn_background_color' in this.data.property) {
+            // 序号背景色
+            this.data.property.sn_background_color = bookUnifiedAttr?.topic_color ?? '#EA3232';
+          }
+        }
 
-          this.$watch(
-            'data',
-            () => {
-              this.$emit('changeData');
-            },
-            { deep: true },
-          );
-        },
-      );
+        this.property.isGetContent = true;
+
+        this.$watch(
+          'data',
+          () => {
+            this.$emit('changeData');
+          },
+          { deep: true },
+        );
+      });
     },
     /**
      * @description 复制组件

+ 2048 - 0
src/views/book/courseware/preview/components/article/NotesModelChs.vue

@@ -0,0 +1,2048 @@
+<!--  -->
+<template>
+  <div v-if="curQue" class="NNPE-ArticleView" id="notes-model">
+    <div
+      v-if="
+        ((curQue.mp3_list && curQue.mp3_list.length > 0 && curQue.mp3_list[0].url) ||
+          config.isHasPY ||
+          config.isHasEN) &&
+        curQue.property.mp3_position === 'top'
+      "
+      class="aduioLine-box aduioLine-practice-npc"
+    >
+      <div class="aduioLine-content">
+        <template v-if="curQue.mp3_list && curQue.mp3_list.length > 0 && curQue.mp3_list[0].url">
+          <AudioLine
+            ref="audioLine"
+            audio-id="artNormalAudio"
+            :mp3="curQue.mp3_list[0].url"
+            :get-cur-time="getCurTime"
+            :duration="curQue.mp3_list[0].media_duration"
+            :mp3-source="curQue.mp3_list[0].source"
+            :width="colLength == 2 ? 200 : 700"
+            :ed="ed"
+            type="audioLine"
+            :attrib="attrib"
+            @emptyEd="emptyEd"
+          />
+        </template>
+      </div>
+      <div class="aduioLine-right">
+        <SvgIcon
+          v-if="config.isHasPY"
+          icon-class="pin-btn"
+          size="16"
+          :class="['pinyin-16', config.isShowPY ? '' : 'disabled']"
+          :style="{ color: config.isShowPY ? (attrib ? attrib.topic_color : '') : '#DCDFE6' }"
+          @click="changePinyin"
+        />
+        <SvgIcon
+          v-if="config.isHasEN"
+          icon-class="en-btn"
+          size="16"
+          :class="['EN-16', config.isShowEN ? '' : 'disabled']"
+          :style="{ color: config.isShowEN ? (attrib ? attrib.topic_color : '') : '#DCDFE6' }"
+          @click="changeEN"
+        />
+      </div>
+    </div>
+    <template v-if="!config.isHasEN || (config.isHasEN && !config.isShowEN)">
+      <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-right"></div>
+          </div>
+          <div
+            v-for="(item, index) in resArr"
+            :key="'detail' + index"
+            :class="['NNPE-detail', item.isTitle ? 'NNPE-detail-title' : '']"
+          >
+            <div
+              class="wordsList-box"
+              :class="[
+                curQue.detail[index].paragraphAttr
+                  ? 'wordsList-box-' + curQue.detail[index].paragraphAttr.paragraphAlign
+                  : '',
+                'article-content',
+                isHasRemark ? 'hasRemark' : '',
+              ]"
+            >
+              <template v-if="item.sourceList.length > 0 && item.sourcePosition === 'before'">
+                <img
+                  v-if="item.sourceList[0] && item.sourceList[0].type === 'image'"
+                  :src="item.sourceList[0].file_url_open"
+                  :style="{
+                    width: item.widthNumber + 'px',
+                    height: item.heightNumber + 'px',
+                  }"
+                />
+                <video
+                  :src="item.sourceList[0].file_url_open"
+                  width="100%"
+                  height="400"
+                  controls
+                  controlsList="nodownload"
+                  v-else
+                ></video>
+              </template>
+
+              <div :class="[item.isTitle ? 'NNPE-title' : '', 'para-' + item.paraAlign]">
+                <div
+                  v-for="(pItem, pIndex) in item.wordsList"
+                  :key="'wordsList' + pIndex"
+                  class="NNPE-words"
+                  :class="[
+                    pItem.chs != '“' && pItem.wordIndex == 0 ? 'textLeft' : 'textCenter',
+                    pItem.chs == '“' ? 'textRight' : '',
+                  ]"
+                  @mousedown="mouseupClick(pItem, pIndex)"
+                >
+                  <template v-if="!pItem.width">
+                    <template v-if="pItem.isShow">
+                      <template
+                        v-if="
+                          item.wordsList[pIndex + 1] &&
+                          item.wordsList[pIndex + 1].chs &&
+                          (chsFhList.indexOf(item.wordsList[pIndex + 1].chs) > -1 ||
+                            NumberList.indexOf(item.wordsList[pIndex + 1].chs) > -1)
+                        "
+                      >
+                        <span v-if="pItem.leg > 0" class="NNPE-words-box">
+                          <span
+                            v-if="curQue.property.pinyin_position == 'top' && config.isShowPY && item.dhaspinyin"
+                            :class="[
+                              'NNPE-pinyin',
+                              pItem.className ? pItem.className : '',
+                              noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{ NumberList.indexOf(pItem.pinyin) == -1 ? pItem.pinyin : '' }}</span
+                          >
+                          <span
+                            class="NNPE-chs"
+                            :class="[
+                              item.timeList &&
+                              item.timeList[pItem.sentIndex] &&
+                              curTime >= item.timeList[pItem.sentIndex].bg &&
+                              curTime <= item.timeList[pItem.sentIndex].ed &&
+                              curTime
+                                ? 'active'
+                                : '',
+                              pItem.paraIndex == paraIndex && pItem.sentIndex == sentIndex ? 'overActive' : '',
+                            ]"
+                            :style="{
+                              fontFamily: pItem.config.fontFamily,
+                              textDecoration: pItem.config.textDecoration,
+                              borderBottom: pItem.config.border === 'dotted' ? '1px dotted' : '',
+                              fontWeight: pItem.config.fontWeight,
+                              height:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
+                              lineHeight:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              backgroundColor:
+                                item.timeList &&
+                                item.timeList[pItem.sentIndex] &&
+                                curTime >= item.timeList[pItem.sentIndex].bg &&
+                                curTime <= item.timeList[pItem.sentIndex].ed &&
+                                curTime &&
+                                attrib
+                                  ? attrib.assist_color
+                                  : '',
+                            }"
+                          >
+                            <template>
+                              <span
+                                v-for="(wItem, wIndex) in pItem.leg"
+                                :key="'ci' + wIndex + pIndex + index"
+                                :class="[
+                                  isPlaying &&
+                                  pItem.chstimeList &&
+                                  pItem.chstimeList[wIndex] &&
+                                  curTime >= pItem.chstimeList[wIndex].wordBg &&
+                                  curTime < item.timeList[pItem.sentIndex].ed
+                                    ? 'wordActive'
+                                    : '',
+                                ]"
+                                :style="{
+                                  color:
+                                    isPlaying &&
+                                    pItem.chstimeList &&
+                                    pItem.chstimeList[wIndex] &&
+                                    curTime >= pItem.chstimeList[wIndex].wordBg &&
+                                    curTime < item.timeList[pItem.sentIndex].ed &&
+                                    attrib
+                                      ? attrib.topic_color
+                                      : pItem.config.color,
+                                }"
+                                >{{ pItem.chs[wIndex] }}</span
+                              >
+                              <img
+                                v-if="pItem.img && pItem.img.length > 0 && pItem.imgPosition === 'after'"
+                                :src="pItem.img[0].file_url"
+                                :style="{
+                                  height: attrib && attrib.font_size ? attrib.font_size : '20px',
+                                }"
+                              />
+                            </template>
+                          </span>
+                          <span
+                            v-if="curQue.property.pinyin_position == 'bottom' && config.isShowPY && item.dhaspinyin"
+                            :class="[
+                              'NNPE-pinyin',
+                              pItem.className ? pItem.className : '',
+                              noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{ NumberList.indexOf(pItem.pinyin) == -1 ? pItem.pinyin : '' }}</span
+                          >
+                        </span>
+                        <span class="NNPE-words-box">
+                          <span
+                            v-if="curQue.property.pinyin_position == 'top' && config.isShowPY && item.dhaspinyin"
+                            :class="[
+                              'NNPE-pinyin',
+                              noFont.indexOf(item.wordsList[pIndex + 1].pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            style="text-align: left"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{
+                              NumberList.indexOf(item.wordsList[pIndex + 1].pinyin) == -1
+                                ? item.wordsList[pIndex + 1].pinyin
+                                : ''
+                            }}</span
+                          >
+                          <span
+                            class="NNPE-chs"
+                            style="text-align: left"
+                            :class="[
+                              isPlaying &&
+                              item.timeList &&
+                              item.timeList[pItem.sentIndex] &&
+                              curTime >= item.timeList[pItem.sentIndex].bg &&
+                              curTime <= item.timeList[pItem.sentIndex].ed &&
+                              curTime
+                                ? 'active'
+                                : '',
+                              pItem.paraIndex == paraIndex && pItem.sentIndex == sentIndex ? 'overActive' : '',
+                              pItem.chstimeList &&
+                              pItem.chstimeList[pItem.leg - 1] &&
+                              curTime >= pItem.chstimeList[pItem.leg - 1].wordBg &&
+                              curQue.wordTime &&
+                              curTime <= item.timeList[pItem.sentIndex].ed
+                                ? 'wordActive'
+                                : '',
+                            ]"
+                            :style="{
+                              fontFamily: item.wordsList[pIndex + 1].config.fontFamily,
+                              textDecoration: item.wordsList[pIndex + 1].config.textDecoration,
+                              borderBottom: item.wordsList[pIndex + 1].config.border === 'dotted' ? '1px dotted' : '',
+                              fontWeight: item.wordsList[pIndex + 1].config.fontWeight,
+                              height:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
+                              lineHeight:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              width: item.wordsList[pIndex + 1].chs.trim() === '' ? '6px' : '',
+                              backgroundColor:
+                                isPlaying &&
+                                item.timeList &&
+                                item.timeList[pItem.sentIndex] &&
+                                curTime >= item.timeList[pItem.sentIndex].bg &&
+                                curTime <= item.timeList[pItem.sentIndex].ed &&
+                                curTime &&
+                                attrib
+                                  ? attrib.assist_color
+                                  : '',
+                              color:
+                                pItem.chstimeList &&
+                                pItem.chstimeList[pItem.leg - 1] &&
+                                curTime >= pItem.chstimeList[pItem.leg - 1].wordBg &&
+                                curQue.wordTime &&
+                                curTime <= item.timeList[pItem.sentIndex].ed &&
+                                attrib
+                                  ? attrib.topic_color
+                                  : item.wordsList[pIndex + 1].config.color,
+                            }"
+                            ><span>{{ item.wordsList[pIndex + 1].chs }}</span
+                            ><img
+                              v-if="
+                                item.wordsList[pIndex + 1].img &&
+                                item.wordsList[pIndex + 1].img.length > 0 &&
+                                item.wordsList[pIndex + 1].imgPosition === 'after'
+                              "
+                              :src="item.wordsList[pIndex + 1].img[0].file_url"
+                              :style="{
+                                height: attrib && attrib.font_size ? attrib.font_size : '20px',
+                              }"
+                          /></span>
+                          <span
+                            v-if="curQue.property.pinyin_position == 'bottom' && config.isShowPY && item.dhaspinyin"
+                            :class="[
+                              'NNPE-pinyin',
+                              noFont.indexOf(item.wordsList[pIndex + 1].pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            style="text-align: left"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{
+                              NumberList.indexOf(item.wordsList[pIndex + 1].pinyin) == -1
+                                ? item.wordsList[pIndex + 1].pinyin
+                                : ''
+                            }}</span
+                          >
+                        </span>
+                        <span
+                          v-if="
+                            item.wordsList[pIndex + 2] &&
+                            item.wordsList[pIndex + 2].chs &&
+                            (chsFhList.indexOf(item.wordsList[pIndex + 2].chs) > -1 ||
+                              NumberList.indexOf(item.wordsList[pIndex + 2].chs) > -1)
+                          "
+                          class="NNPE-words-box"
+                        >
+                          <span
+                            v-if="curQue.property.pinyin_position == 'top' && config.isShowPY && item.dhaspinyin"
+                            :class="[
+                              'NNPE-pinyin',
+                              noFont.indexOf(item.wordsList[pIndex + 2].pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            style="text-align: left"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{
+                              NumberList.indexOf(item.wordsList[pIndex + 2].pinyin) == -1
+                                ? item.wordsList[pIndex + 2].pinyin
+                                : ''
+                            }}</span
+                          >
+                          <span
+                            class="NNPE-chs"
+                            style="text-align: left"
+                            :class="[
+                              isPlaying &&
+                              item.timeList &&
+                              item.timeList[pItem.sentIndex] &&
+                              curTime >= item.timeList[pItem.sentIndex].bg &&
+                              curTime <= item.timeList[pItem.sentIndex].ed &&
+                              curTime
+                                ? 'active'
+                                : '',
+                              pItem.paraIndex == paraIndex && pItem.sentIndex == sentIndex ? 'overActive' : '',
+                              pItem.chstimeList &&
+                              pItem.chstimeList[pItem.leg - 1] &&
+                              curTime >= pItem.chstimeList[pItem.leg - 1].wordBg &&
+                              curQue.wordTime &&
+                              curTime <= item.timeList[pItem.sentIndex].ed
+                                ? 'wordActive'
+                                : '',
+                            ]"
+                            :style="{
+                              fontFamily: item.wordsList[pIndex + 2].config.fontFamily,
+                              textDecoration: item.wordsList[pIndex + 2].config.textDecoration,
+                              borderBottom: item.wordsList[pIndex + 2].config.border === 'dotted' ? '1px dotted' : '',
+                              fontWeight: item.wordsList[pIndex + 2].config.fontWeight,
+                              height:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
+                              lineHeight:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              width: item.wordsList[pIndex + 2].chs.trim() === '' ? '6px' : '',
+                              backgroundColor:
+                                isPlaying &&
+                                item.timeList &&
+                                item.timeList[pItem.sentIndex] &&
+                                curTime >= item.timeList[pItem.sentIndex].bg &&
+                                curTime <= item.timeList[pItem.sentIndex].ed &&
+                                curTime &&
+                                attrib
+                                  ? attrib.assist_color
+                                  : '',
+                              color:
+                                pItem.chstimeList &&
+                                pItem.chstimeList[pItem.leg - 1] &&
+                                curTime >= pItem.chstimeList[pItem.leg - 1].wordBg &&
+                                curQue.wordTime &&
+                                curTime <= item.timeList[pItem.sentIndex].ed &&
+                                attrib
+                                  ? attrib.topic_color
+                                  : item.wordsList[pIndex + 2].config.color,
+                            }"
+                            ><span>{{ item.wordsList[pIndex + 2].chs }}</span
+                            ><img
+                              v-if="
+                                item.wordsList[pIndex + 2].img &&
+                                item.wordsList[pIndex + 2].img.length > 0 &&
+                                item.wordsList[pIndex + 2].imgPosition === 'after'
+                              "
+                              :src="item.wordsList[pIndex + 2].img[0].file_url"
+                              :style="{
+                                height: attrib && attrib.font_size ? attrib.font_size : '20px',
+                              }"
+                          /></span>
+                          <span
+                            v-if="curQue.property.pinyin_position == 'bottom' && config.isShowPY && item.dhaspinyin"
+                            :class="[
+                              'NNPE-pinyin',
+                              noFont.indexOf(item.wordsList[pIndex + 2].pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            style="text-align: left"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{
+                              NumberList.indexOf(item.wordsList[pIndex + 2].pinyin) == -1
+                                ? item.wordsList[pIndex + 2].pinyin
+                                : ''
+                            }}</span
+                          >
+                        </span>
+                      </template>
+                      <template v-else>
+                        <span
+                          v-if="curQue.property.pinyin_position == 'top' && config.isShowPY && item.dhaspinyin"
+                          class="NNPE-pinyin"
+                          :class="[
+                            pItem.chs != '“' && pItem.padding ? 'padding' : '',
+                            pItem.className ? pItem.className : '',
+                            noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
+                          ]"
+                          :style="{
+                            fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                            height:
+                              attrib && attrib.pinyin_size ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt' : '22px',
+                          }"
+                          >{{ NumberList.indexOf(pItem.pinyin) == -1 ? pItem.pinyin : '' }}</span
+                        >
+                        <span
+                          class="NNPE-chs"
+                          :class="[
+                            item.timeList &&
+                            item.timeList[pItem.sentIndex] &&
+                            curTime >= item.timeList[pItem.sentIndex].bg &&
+                            curTime <= item.timeList[pItem.sentIndex].ed &&
+                            curTime
+                              ? 'active'
+                              : '',
+                            pItem.chs != '“' && pItem.padding && config.isShowPY ? 'padding' : '',
+                            pItem.paraIndex == paraIndex && pItem.sentIndex == sentIndex ? 'overActive' : '',
+                          ]"
+                          :style="{
+                            backgroundColor:
+                              item.timeList &&
+                              item.timeList[pItem.sentIndex] &&
+                              curTime >= item.timeList[pItem.sentIndex].bg &&
+                              curTime <= item.timeList[pItem.sentIndex].ed &&
+                              curTime &&
+                              attrib
+                                ? attrib.assist_color
+                                : '',
+                          }"
+                        >
+                          <template v-for="(wItem, wIndex) in pItem.leg">
+                            <span
+                              :key="'ci' + wIndex + pIndex + index"
+                              :class="[
+                                isPlaying &&
+                                pItem.chstimeList &&
+                                pItem.chstimeList[wIndex] &&
+                                curTime >= pItem.chstimeList[wIndex].wordBg &&
+                                curTime < item.timeList[pItem.sentIndex].ed
+                                  ? 'wordActive'
+                                  : '',
+                              ]"
+                              :style="{
+                                fontFamily: pItem.config.fontFamily,
+                                textDecoration: pItem.config.textDecoration,
+                                borderBottom: pItem.config.border === 'dotted' ? '1px dotted' : '',
+                                fontWeight: pItem.config.fontWeight,
+                                height:
+                                  attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                                fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
+                                lineHeight:
+                                  attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                                width: pItem.chs[wIndex].trim() === '' ? '6px' : '',
+                                color:
+                                  isPlaying &&
+                                  pItem.chstimeList &&
+                                  pItem.chstimeList[wIndex] &&
+                                  curTime >= pItem.chstimeList[wIndex].wordBg &&
+                                  curTime < item.timeList[pItem.sentIndex].ed &&
+                                  attrib
+                                    ? attrib.topic_color
+                                    : pItem.config.color,
+                              }"
+                              >{{ pItem.chs[wIndex] }}</span
+                            >
+                          </template>
+                          <img
+                            v-if="pItem.img && pItem.img.length > 0 && pItem.imgPosition === 'after'"
+                            :src="pItem.img[0].file_url"
+                            :style="{
+                              height: attrib && attrib.font_size ? attrib.font_size : '20px',
+                            }"
+                          />
+                        </span>
+                        <span
+                          v-if="curQue.property.pinyin_position == 'bottom' && config.isShowPY && item.dhaspinyin"
+                          class="NNPE-pinyin"
+                          :class="[
+                            pItem.chs != '“' && pItem.padding ? 'padding' : '',
+                            pItem.className ? pItem.className : '',
+                            noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
+                          ]"
+                          :style="{
+                            fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                            height:
+                              attrib && attrib.pinyin_size ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt' : '22px',
+                          }"
+                          >{{ NumberList.indexOf(pItem.pinyin) == -1 ? pItem.pinyin : '' }}</span
+                        >
+                      </template>
+                    </template>
+                  </template>
+                  <template v-else>
+                    <span
+                      :style="{
+                        height: pItem.height + 'px',
+                        width: pItem.width + 'px',
+                      }"
+                    ></span>
+                  </template>
+                </div>
+              </div>
+              <div
+                v-if="curQue.property.multilingual_position === 'para'"
+                class="multilingual-para"
+                :class="[item.isTitle ? 'multilingual-para-center' : '', 'multilingual-' + item.paraAlign]"
+              >
+                {{
+                  curQue.detail[index].multilingualTextList && curQue.detail[index].multilingualTextList[multilingual]
+                    ? curQue.detail[index].multilingualTextList[multilingual].join(' ')
+                    : ''
+                }}
+              </div>
+              <template v-if="item.sourceList.length > 0 && item.sourcePosition === 'after'">
+                <img
+                  v-if="item.sourceList[0] && item.sourceList[0].type === 'image'"
+                  :src="item.sourceList[0].file_url_open"
+                  :style="{
+                    width: item.widthNumber + 'px',
+                    height: item.heightNumber + 'px',
+                  }"
+                />
+                <video
+                  :src="item.sourceList[0].file_url_open"
+                  width="100%"
+                  height="400"
+                  controls
+                  controlsList="nodownload"
+                  v-else
+                ></video>
+              </template>
+            </div>
+            <div v-if="item.remarkDetail" :class="['remarkBox', 'remark-top-8']">
+              <RemarkChs :remark-detail="item.remarkDetail" :margin-top="8" />
+            </div>
+          </div>
+        </div>
+      </template>
+    </template>
+    <template v-else>
+      <template v-if="resObj">
+        <!-- 段落对齐方式和备注在此模式里没有写,如果段落里添加了英文后需要在此添加段落对齐和备注、大小图片、生词样式 -->
+        <div class="NPC-sentences-list">
+          <div
+            v-for="(item, index) in resObj.sentList"
+            :key="'detail' + index"
+            :class="['NNPE-detail-box', sentIndex == index ? 'active' : '']"
+          >
+            <div
+              :class="['NNPE-details']"
+              @click="
+                handleChangeTime(
+                  curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].bg,
+                  curQue.wordTime && curQue.wordTime[index] && curQue.wordTime[index].ed,
+                  index,
+                )
+              "
+            >
+              <div
+                v-if="item.enwords && config.isShowEN && curQue.enPosition && curQue.enPosition == 'top'"
+                :class="['enwords', sentIndex == index ? 'wordBlank' : '']"
+              >
+                {{ item.enwords }}
+              </div>
+              <div style="overflow: hidden; clear: both"></div>
+              <div
+                v-for="(pItem, pIndex) in item.sentArr"
+                :key="'wordsList' + pIndex"
+                class="NNPE-words"
+                :class="[
+                  pItem.chs != '“' && pItem.wordIndex == 0 ? 'textLeft' : 'textCenter',
+                  pItem.chs == '“' ? 'textRight' : '',
+                ]"
+                @mousedown="mouseupClick(pItem, pIndex)"
+              >
+                <template v-if="!pItem.width">
+                  <template v-if="pItem.isShow">
+                    <template
+                      v-if="
+                        item.sentArr[pIndex + 1] &&
+                        item.sentArr[pIndex + 1].chs &&
+                        (chsFhList.indexOf(item.sentArr[pIndex + 1].chs) > -1 ||
+                          NumberList.indexOf(item.sentArr[pIndex + 1].chs) > -1)
+                      "
+                    >
+                      <span class="NNPE-words-box">
+                        <template v-if="curQue.property.pinyin_position == 'top'">
+                          <span
+                            v-if="config.isShowPY"
+                            class="NNPE-pinyin"
+                            :class="[
+                              pItem.className ? pItem.className : '',
+                              sentIndex == index ? 'wordBlank' : '',
+                              noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{ pItem.pinyin }}</span
+                          >
+                        </template>
+                        <span
+                          class="NNPE-chs"
+                          :class="[
+                            pItem.padding && config.isShowPY ? 'padding' : '',
+                            sentIndex == index ? 'wordBlank' : '',
+                          ]"
+                        >
+                          <template v-for="(wItem, wIndex) in pItem.leg">
+                            <span
+                              :key="'ci' + wIndex + pIndex + index"
+                              :class="[
+                                pItem.timeList[wIndex] &&
+                                curTime >= pItem.timeList[wIndex].wordBg &&
+                                curTime <= curQue.wordTime[index].ed &&
+                                curTime
+                                  ? 'active'
+                                  : '',
+                                sentIndex == index ? 'wordBlank' : '',
+                              ]"
+                              :style="{
+                                fontFamily: pItem.config.fontFamily,
+                                color: pItem.config.color,
+                                textDecoration: pItem.config.textDecoration,
+                                borderBottom: pItem.config.border === 'dotted' ? '1px dotted' : '',
+                                fontWeight: pItem.config.fontWeight,
+                                height:
+                                  attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                                fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
+                                lineHeight:
+                                  attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                                width: pItem.chs[wIndex].trim() === '' ? '6px' : '',
+                              }"
+                              >{{ NumberList.indexOf(pItem.pinyin) == -1 ? pItem.chs[wIndex] : '' }}</span
+                            >
+                          </template>
+                        </span>
+                        <template v-if="curQue.property.pinyin_position == 'bottom'">
+                          <span
+                            v-if="config.isShowPY"
+                            class="NNPE-pinyin"
+                            :class="[
+                              pItem.className ? pItem.className : '',
+                              sentIndex == index ? 'wordBlank' : '',
+                              noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{ pItem.pinyin }}</span
+                          >
+                        </template>
+                      </span>
+                      <span class="NNPE-words-box">
+                        <template v-if="curQue.property.pinyin_position == 'top'">
+                          <span
+                            v-if="config.isShowPY"
+                            :class="[
+                              'NNPE-pinyin',
+                              sentIndex == index ? 'wordBlank' : '',
+                              noFont.indexOf(item.sentArr[pIndex + 1].pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            style="text-align: left"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{ item.sentArr[pIndex + 1].pinyin }}</span
+                          >
+                        </template>
+                        <span
+                          class="NNPE-chs"
+                          style="text-align: left"
+                          :style="{
+                            height:
+                              attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                            fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
+                            lineHeight:
+                              attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                          }"
+                        >
+                          <span
+                            :class="[
+                              pItem.timeList[pItem.leg - 1] &&
+                              curQue.wordTime &&
+                              curTime >= pItem.timeList[pItem.leg - 1].wordBg &&
+                              curTime <= curQue.wordTime[index].ed &&
+                              curTime
+                                ? 'active'
+                                : '',
+                              sentIndex == index ? 'wordBlank' : '',
+                            ]"
+                            :style="{
+                              fontFamily: item.sentArr[pIndex + 1].config.fontFamily,
+                              color: item.sentArr[pIndex + 1].config.color,
+                              textDecoration: item.sentArr[pIndex + 1].config.textDecoration,
+                              borderBottom: item.sentArr[pIndex + 1].config.border === 'dotted' ? '1px dotted' : '',
+                              fontWeight: item.sentArr[pIndex + 1].config.fontWeight,
+                              height:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
+                              lineHeight:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              width: item.sentArr[pIndex + 1].chs.trim() === '' ? '6px' : '',
+                            }"
+                          >
+                            {{
+                              NumberList.indexOf(item.sentArr[pIndex + 1].pinyin) == -1
+                                ? item.sentArr[pIndex + 1].chs
+                                : ''
+                            }}</span
+                          >
+                        </span>
+                        <template v-if="curQue.property.pinyin_position == 'bottom'">
+                          <span
+                            v-if="config.isShowPY"
+                            :class="[
+                              'NNPE-pinyin',
+                              sentIndex == index ? 'wordBlank' : '',
+                              noFont.indexOf(item.sentArr[pIndex + 1].pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            style="text-align: left"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{ item.sentArr[pIndex + 1].pinyin }}</span
+                          >
+                        </template>
+                      </span>
+                      <span
+                        v-if="
+                          item.sentArr[pIndex + 2] &&
+                          item.sentArr[pIndex + 2].chs &&
+                          chsFhList.indexOf(item.sentArr[pIndex + 2].chs) > -1
+                        "
+                        class="NNPE-words-box"
+                      >
+                        <template v-if="curQue.property.pinyin_position == 'top'">
+                          <span
+                            v-if="config.isShowPY"
+                            :class="[
+                              'NNPE-pinyin',
+                              sentIndex == index ? 'wordBlank' : '',
+                              noFont.indexOf(item.sentArr[pIndex + 2].pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            style="text-align: left"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{ item.sentArr[pIndex + 2].pinyin }}</span
+                          >
+                        </template>
+                        <span class="NNPE-chs" style="text-align: left">
+                          <span
+                            :class="[
+                              pItem.timeList[pItem.leg - 1] &&
+                              curQue.wordTime &&
+                              curTime >= pItem.timeList[pItem.leg - 1].wordBg &&
+                              curTime <= curQue.wordTime[index].ed &&
+                              curTime
+                                ? 'active'
+                                : '',
+                              sentIndex == index ? 'wordBlank' : '',
+                            ]"
+                            :style="{
+                              fontFamily: item.sentArr[pIndex + 2].config.fontFamily,
+                              color: item.sentArr[pIndex + 2].config.color,
+                              textDecoration: item.sentArr[pIndex + 2].config.textDecoration,
+                              borderBottom: item.sentArr[pIndex + 2].config.border === 'dotted' ? '1px dotted' : '',
+                              fontWeight: item.sentArr[pIndex + 2].config.fontWeight,
+                              height:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
+                              lineHeight:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              width: item.sentArr[pIndex + 2].chs.trim() === '' ? '6px' : '',
+                            }"
+                          >
+                            {{
+                              NumberList.indexOf(item.sentArr[pIndex + 2].pinyin) == -1
+                                ? item.sentArr[pIndex + 2].chs
+                                : ''
+                            }}</span
+                          >
+                        </span>
+                        <template v-if="curQue.property.pinyin_position == 'bottom'">
+                          <span
+                            v-if="config.isShowPY"
+                            :class="[
+                              'NNPE-pinyin',
+                              sentIndex == index ? 'wordBlank' : '',
+                              noFont.indexOf(item.sentArr[pIndex + 2].pinyin) > -1 ? 'noFont' : '',
+                            ]"
+                            style="text-align: left"
+                            :style="{
+                              fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                              height:
+                                attrib && attrib.pinyin_size
+                                  ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt'
+                                  : '22px',
+                            }"
+                            >{{ item.sentArr[pIndex + 2].pinyin }}</span
+                          >
+                        </template>
+                      </span>
+                    </template>
+                    <template v-else>
+                      <template v-if="curQue.property.pinyin_position == 'top'">
+                        <span
+                          v-if="config.isShowPY"
+                          class="NNPE-pinyin"
+                          :class="[
+                            pItem.chs != '“' && pItem.padding ? 'padding' : '',
+                            pItem.className ? pItem.className : '',
+                            sentIndex == index ? 'wordBlank' : '',
+                            noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
+                          ]"
+                          :style="{
+                            fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                            height:
+                              attrib && attrib.pinyin_size ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt' : '22px',
+                          }"
+                          >{{ pItem.pinyin }}</span
+                        >
+                      </template>
+                      <span
+                        class="NNPE-chs"
+                        :class="[
+                          pItem.chs != '“' && pItem.padding && config.isShowPY ? 'padding' : '',
+                          sentIndex == index ? 'wordBlank' : '',
+                        ]"
+                        :style="{
+                          height: attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                          fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
+                          lineHeight:
+                            attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                        }"
+                      >
+                        <template v-for="(wItem, wIndex) in pItem.leg">
+                          <span
+                            :key="'ci' + wIndex + pIndex + index"
+                            :class="[
+                              pItem.timeList[wIndex] &&
+                              curQue.wordTime &&
+                              curQue.wordTime[index] &&
+                              curTime >= pItem.timeList[wIndex].wordBg &&
+                              curTime <= curQue.wordTime[index].ed
+                                ? 'active'
+                                : '',
+                              sentIndex == index ? 'wordBlank' : '',
+                            ]"
+                            :style="{
+                              fontFamily: pItem.config.fontFamily,
+                              color: pItem.config.color,
+                              textDecoration: pItem.config.textDecoration,
+                              borderBottom: pItem.config.border === 'dotted' ? '1px dotted' : '',
+                              fontWeight: pItem.config.fontWeight,
+                              height:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
+                              lineHeight:
+                                attrib && attrib.font_size ? attrib.font_size.replace('pt', '') * 1.4 + 'pt' : '28px',
+                              width: pItem.chs[wIndex].trim() === '' ? '6px' : '',
+                            }"
+                            >{{ NumberList.indexOf(pItem.pinyin) == -1 ? pItem.chs[wIndex] : '' }}</span
+                          >
+                        </template>
+                      </span>
+                      <template v-if="curQue.property.pinyin_position == 'bottom'">
+                        <span
+                          v-if="config.isShowPY"
+                          class="NNPE-pinyin"
+                          :class="[
+                            pItem.chs != '“' && pItem.padding ? 'padding' : '',
+                            pItem.className ? pItem.className : '',
+                            sentIndex == index ? 'wordBlank' : '',
+                            noFont.indexOf(pItem.pinyin) > -1 ? 'noFont' : '',
+                          ]"
+                          :style="{
+                            fontSize: attrib && attrib.pinyin_size ? attrib.pinyin_size : '14px',
+                            height:
+                              attrib && attrib.pinyin_size ? attrib.pinyin_size.replace('pt', '') * 1.5 + 'pt' : '22px',
+                          }"
+                          >{{ pItem.pinyin }}</span
+                        >
+                      </template>
+                    </template>
+                  </template>
+                </template>
+                <template v-else>
+                  <span
+                    :style="{
+                      height: pItem.height + 'px',
+                      width: pItem.width + 'px',
+                    }"
+                  ></span>
+                </template>
+              </div>
+              <div style="overflow: hidden; clear: both"></div>
+              <div
+                v-if="
+                  item.enwords &&
+                  config.isShowEN &&
+                  (!curQue.enPosition || (curQue.enPosition && curQue.enPosition == 'bottom'))
+                "
+                :class="['enwords', sentIndex == index ? 'wordBlank' : '']"
+              >
+                {{ item.enwords }}
+              </div>
+            </div>
+            <div
+              v-if="curQue.property.multilingual_position === 'para'"
+              class="multilingual-para"
+              :class="[item.isTitle ? 'multilingual-para-center' : '', 'multilingual-' + item.paraAlign]"
+            >
+              {{ multilingualTextList[multilingual] ? multilingualTextList[multilingual].join(' ') : '' }}
+            </div>
+          </div>
+        </div>
+      </template>
+    </template>
+    <template v-for="(items, indexs) in curQue.detail">
+      <div
+        v-if="
+          curQue.property.multilingual_position === 'all' &&
+          items.multilingualTextList &&
+          items.multilingualTextList[multilingual] &&
+          items.multilingualTextList[multilingual].length > 0
+        "
+        :key="indexs"
+        class="multilingual"
+      >
+        <div
+          class="multilingual-para"
+          :class="[items.isTitle ? 'multilingual-para-center' : '', 'multilingual-' + items.paraAlign]"
+        >
+          {{
+            items.multilingualTextList && items.multilingualTextList[multilingual]
+              ? items.multilingualTextList[multilingual].join(' ')
+              : ''
+          }}
+        </div>
+      </div>
+    </template>
+    <div
+      v-if="
+        ((curQue.mp3_list && curQue.mp3_list.length > 0 && curQue.mp3_list[0].url) ||
+          config.isHasPY ||
+          config.isHasEN) &&
+        curQue.property.mp3_position === 'bottom'
+      "
+      class="aduioLine-box aduioLine-practice-npc aduioLine-box-bottom"
+    >
+      <div class="aduioLine-content">
+        <template v-if="curQue.mp3_list && curQue.mp3_list.length > 0 && curQue.mp3_list[0].url">
+          <AudioLine
+            ref="audioLine"
+            audio-id="artNormalAudio"
+            :mp3="curQue.mp3_list[0].url"
+            :get-cur-time="getCurTime"
+            :duration="curQue.mp3_list[0].media_duration"
+            :mp3-source="curQue.mp3_list[0].source"
+            :width="colLength == 2 ? 200 : 700"
+            :ed="ed"
+            type="audioLine"
+            :attrib="attrib"
+            @emptyEd="emptyEd"
+          />
+        </template>
+      </div>
+      <div class="aduioLine-right">
+        <SvgIcon
+          v-if="config.isHasPY"
+          icon-class="pin-btn"
+          size="16"
+          :class="['pinyin-16', config.isShowPY ? '' : 'disabled']"
+          :style="{ color: config.isShowPY ? (attrib ? attrib.topic_color : '') : '#DCDFE6' }"
+          @click="changePinyin"
+        />
+        <SvgIcon
+          v-if="config.isHasEN"
+          icon-class="en-btn"
+          size="16"
+          :class="['EN-16', config.isShowEN ? '' : 'disabled']"
+          :style="{ color: config.isShowEN ? (attrib ? attrib.topic_color : '') : '#DCDFE6' }"
+          @click="changeEN"
+        />
+      </div>
+    </div>
+    <el-dialog
+      :visible.sync="notesFlag"
+      :show-close="true"
+      :title="'笔记'"
+      :close-on-click-modal="false"
+      width="367px"
+      class="notes-dialog"
+      @close="handleData"
+      v-if="notesFlag"
+    >
+      <p>{{ notesObj.title }}</p>
+      <el-input type="textarea" :rows="4" maxlength="200" show-word-limit placeholder="请输入" v-model="notesObj.notes">
+      </el-input>
+      <div class="btn-box">
+        <el-button type="danger" plain size="small" @click="deleteNotes" v-if="notesObj.id">删除</el-button>
+        <el-button type="primary" @click="handleSave" size="small" :loading="loading">保存</el-button>
+      </div>
+    </el-dialog>
+  </div>
+</template>
+
+<script>
+import AudioLine from '../voice_matrix/components/AudioLine.vue';
+import RemarkChs from '../dialogue_article/RemarkChs.vue';
+import Highlighter from 'web-highlighter';
+export default {
+  name: 'NotesModelChs',
+  components: {
+    AudioLine,
+    RemarkChs,
+  },
+  props: [
+    'curQue',
+    'noFont',
+    'config',
+    'NNPEAnnotationList',
+    'colLength',
+    'themeColor',
+    'multilingual',
+    'attrib',
+    'isMobile',
+  ],
+  data() {
+    return {
+      resArr: [],
+      resObj: null,
+      curTime: 0, // 单位s
+      chsFhList: [',', '。', '”', ':', '》', '?', '!', ';', '#', '、'],
+      enFhList: [',', '.', ';', '?', '!', ':', '>', '<'],
+      NumberList: ['①', '②', '③', '④', '⑤', '⑥', '⑦', '⑧', '⑨', '⑩', '⑪', '⑫', '⑬', '⑭', '⑮', '⑯', '⑰', '⑱', '⑲', '⑳'],
+      articleImg: {}, // 文章图片
+      paraIndex: -1, // 段落索引
+      sentIndex: -1, // 句子索引
+      ed: undefined,
+      isHasRemark: false,
+      highlighter: null,
+      notesFlag: false, // 笔记弹窗
+      notesObj: {
+        title: '',
+        id: '',
+        notes: '',
+        pos: '',
+      },
+      highDataList: [],
+      activeSentObj: null, // 点击的句子
+      loading: false,
+    };
+  },
+  computed: {
+    isPlaying() {
+      let playing = false;
+      if (this.$refs.audioLine) {
+        playing = this.$refs.audioLine.audio.isPlaying;
+      }
+      return playing;
+    },
+  },
+  watch: {
+    curQue: {
+      handler(val) {
+        if (val) {
+          this.handleData();
+        }
+      },
+      // 深度观察监听
+      deep: true,
+    },
+  },
+  // 生命周期 - 创建完成(可以访问当前this实例)
+  created() {},
+  // 生命周期 - 挂载完成(可以访问DOM元素)
+  mounted() {
+    if (this.curQue) {
+      this.handleData();
+    }
+  },
+  beforeCreate() {}, // 生命周期 - 创建之前
+  beforeMount() {}, // 生命周期 - 挂载之前
+  beforeUpdate() {}, // 生命周期 - 更新之前
+  updated() {}, // 生命周期 - 更新之后
+  beforeDestroy() {}, // 生命周期 - 销毁之前
+  destroyed() {}, // 生命周期 - 销毁完成
+  activated() {},
+  // 方法集合
+  methods: {
+    // 拼音的显示和隐藏
+    changePinyin() {
+      if (this.config.isHasPY) {
+        this.$emit('changeConfig', 'isShowPY');
+      }
+    },
+    // 英文的显示和隐藏
+    changeEN() {
+      if (this.config.isHasEN) {
+        this.$emit('changeConfig', 'isShowEN');
+      }
+    },
+    getCurTime(curTime) {
+      this.curTime = curTime * 1000;
+      this.getSentIndex(this.curTime);
+    },
+    getSentIndex(curTime) {
+      if (this.curQue.wordTime) {
+        for (let i = 0; i < this.curQue.wordTime.length; i++) {
+          let bg = this.curQue.wordTime[i].bg;
+          let ed = this.curQue.wordTime[i].ed;
+          if (curTime >= bg && curTime <= ed) {
+            this.sentIndex = i;
+            break;
+          }
+        }
+      }
+    },
+    handleData() {
+      let _this = this;
+      let resArr = [];
+      let curQue = JSON.parse(JSON.stringify(this.curQue));
+      let wordTimeList = curQue.wordTime;
+      let asIndex = 0;
+      let dhaspinyin = false; // 每段是否有拼音
+      curQue.detail.forEach((dItem, dIndex) => {
+        dhaspinyin = false;
+        let remarkDetail = dItem.remark;
+        if (
+          remarkDetail &&
+          (remarkDetail.chs || remarkDetail.en || (remarkDetail.img_list && remarkDetail.img_list.length > 0))
+        ) {
+          this.isHasRemark = true;
+        }
+        let paraArr = [];
+        if (dItem.paraAlign !== 'center') {
+          paraArr = [
+            {
+              pinyin: '',
+              chs: '',
+              width: 20,
+              height: 20,
+            },
+            {
+              width: 20,
+              height: 20,
+              pinyin: '',
+              chs: '',
+            },
+          ];
+        }
+        dItem.wordsList.forEach((sItem, sIndex) => {
+          let sentArr = [];
+          sItem.forEach((wItem, wIndex) => {
+            let startIndex = wIndex === 0 ? 0 : sentArr[wIndex - 1].startIndex + sentArr[wIndex - 1].chs.length;
+            let endIndex = wIndex === 0 ? wItem.chs.length : sentArr[wIndex - 1].endIndex + wItem.chs.length;
+            this.mergeWordSymbol(wItem);
+            let obj = {
+              paraIndex: dIndex, // 段落索引
+              sentIndex: sIndex, // 在段落中句子索引
+              articleSentIndex: asIndex, // 在文章中句子索引
+              wordIndex: wIndex, // 单词的索引
+              pinyin:
+                curQue.pinyin_type === 'pinyin'
+                  ? curQue.property.is_first_sentence_first_hz_pinyin_first_char_upper_case === 'true' && wIndex === 0
+                    ? wItem.pinyin_up
+                    : wItem.pinyin
+                  : wItem.pinyin_tone,
+              chs: wItem.chs,
+              padding: true, // wItem.padding,
+              className: wItem.className,
+              isShow: wItem.isShow,
+              startIndex,
+              endIndex,
+              leg: wItem.chs.length,
+              config: {
+                fontFamily: wItem.fontFamily,
+                color: wItem.color,
+                textDecoration: wItem.textDecoration,
+                border: wItem.border,
+                fontWeight: wItem.fontWeight,
+              },
+              matchWords: wItem.matchWords,
+              matchNotes: wItem.matchNotes,
+              img: wItem.img,
+              imgPosition: wItem.imgPosition,
+            };
+            if (wordTimeList && wordTimeList.length > 0) {
+              obj.chstimeList = wordTimeList[asIndex].wordsResultList.slice(startIndex, endIndex);
+            }
+            sentArr.push(obj);
+            paraArr.push(obj);
+            if (wIndex === sItem.length - 1) {
+              asIndex += 1;
+            }
+            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 = curQue.wordTime ? curQue.wordTime.slice(startLeg, endLeg) : [];
+        let paraObj = {
+          wordsList: paraArr,
+          timeList,
+          isTitle: dItem.isTitle,
+          dhaspinyin,
+          enwords: dItem.sentencesEn ? dItem.sentencesEn : [],
+          paraAlign: dItem.paraAlign,
+          remarkDetail,
+          sourceList: dItem.sourceList ? dItem.sourceList : [],
+          sourcePosition: dItem.sourcePosition,
+          widthNumber: dItem.widthNumber,
+          heightNumber: dItem.heightNumber,
+        };
+        resArr.push(paraObj);
+      });
+      this.resArr = resArr;
+
+      // 循环文章图片
+      if (curQue.img_list) {
+        curQue.img_list.forEach((item) => {
+          this.articleImg[item.imgNumber] = item.id;
+        });
+      }
+
+      let resArrs = [];
+      let sentArrTotal = [];
+      let timeArr = [];
+      curQue.detail.forEach((dItem, dIndex) => {
+        dItem.wordsList.forEach((sItem, sIndex) => {
+          let sentArr = [];
+
+          sItem.forEach((wItem, wIndex) => {
+            let startIndex = wIndex === 0 ? 0 : sentArr[wIndex - 1].startIndex + sentArr[wIndex - 1].chs.length;
+            let endIndex = wIndex === 0 ? wItem.chs.length : sentArr[wIndex - 1].endIndex + wItem.chs.length;
+            // this.judgePad(sItem, wItem, wIndex);
+            this.mergeWordSymbol(wItem);
+            let obj = {
+              paraIndex: dIndex, // 段落索引
+              sentIndex: sIndex, // 在段落中句子索引
+              wordIndex: wIndex, // 单词的索引
+              pinyin:
+                curQue.pinyin_type === 'pinyin'
+                  ? curQue.property.is_first_sentence_first_hz_pinyin_first_char_upper_case === 'true' && wIndex === 0
+                    ? wItem.pinyin_up
+                    : wItem.pinyin
+                  : wItem.pinyin_tone,
+              chs: wItem.chs,
+              padding: true,
+              className: wItem.className,
+              isShow: wItem.isShow,
+              startIndex,
+              endIndex,
+              leg: wItem.chs.length,
+              timeList: [],
+            };
+            sentArr.push(obj);
+          });
+          let objs = {
+            sentArr,
+            enwords: dItem.sentencesEn && dItem.sentencesEn[sIndex] && dItem.sentencesEn[sIndex].replace(/'/g, '’'),
+            paraAlign: dItem.paraAlign,
+            sourceList: dItem.sourceList ? dItem.sourceList : [],
+            sourcePosition: dItem.sourcePosition,
+            widthNumber: dItem.widthNumber,
+            heightNumber: dItem.heightNumber,
+          };
+          sentArrTotal.push(sentArr);
+          resArrs.push(objs);
+        });
+        timeArr.push(dItem.timeList);
+      });
+      if (wordTimeList && wordTimeList.length > 0) {
+        this.mergeWordTime(sentArrTotal, wordTimeList);
+      }
+      let timeList = [];
+      timeArr.forEach((item) => {
+        item.forEach((aItem) => {
+          if (timeList.indexOf(aItem) < 0) {
+            timeList.push(aItem);
+          }
+        });
+      });
+      this.resObj = { sentList: resArrs, timeList };
+      setTimeout(() => {
+        _this.highlighter = new Highlighter({
+          $root: document.getElementById('notes-model'),
+          exceptSelectors: ['pre', 'code'],
+        });
+        _this.highlighter.dispose();
+        _this.highlighter
+          .on('selection:hover', ({ id }) => {
+            // 通过添加 class,实现类似 hover 效果
+            _this.highlighter.addClass('highlight-wrap-hover', id);
+          })
+          .on('selection:hover-out', ({ id }) => {
+            // 鼠标离开时清除悬停样式
+            _this.highlighter.removeClass('highlight-wrap-hover', id);
+          })
+          .on('selection:create', ({ sources }) => {
+            // sources = sources.map(hs => ({hs}));
+            if (sources && sources[0]) {
+              console.log(sources[0]);
+              _this.notesObj.title = sources[0].text;
+              _this.notesObj.pos = JSON.stringify({
+                sent_id: _this.activeSentObj,
+                s: sources[0].startMeta.textOffset,
+                e: sources[0].endMeta.textOffset,
+              });
+              _this.notesObj.notes = '';
+              _this.notesObj.id = '';
+              _this.notesId = sources[0].id;
+              _this.notesFlag = true;
+            }
+
+            // 存储
+            // store.save(sources);
+          });
+        _this.highlighter.run();
+      }, 100);
+    },
+    mergeWordTime(resArr, wordTimeList) {
+      resArr.forEach((item, index) => {
+        let wordsResultList = wordTimeList[index].wordsResultList;
+        item.forEach((wItem) => {
+          let startIndex = wItem.startIndex;
+          let endIndex = wItem.endIndex;
+          wItem.timeList = wordsResultList.slice(startIndex, endIndex);
+        });
+      });
+    },
+    // 词和标点合一起
+    mergeWordSymbol(wItem) {
+      if (this.chsFhList.indexOf(wItem.chs) > -1 || this.NumberList.indexOf(wItem.chs) > -1) {
+        wItem.isShow = false;
+      } else {
+        wItem.isShow = true;
+      }
+    },
+    // 判断是否有padding
+    judgePad(sItem, wItem, curIndex) {
+      let leg = sItem.length;
+      if (curIndex < leg - 1) {
+        let nextIndex = curIndex + 1;
+        let chs = sItem[nextIndex].chs;
+        if (this.chsFhList.indexOf(chs) > -1 || this.chsFhList.indexOf(wItem.chs) > -1) {
+          wItem.padding = false;
+        } else {
+          wItem.padding = true;
+        }
+        if (this.enFhList.indexOf(wItem.pinyin) > -1) {
+          wItem.className = 'textLeft';
+        }
+      }
+    },
+    // 点击播放某个句子
+    handleChangeTime(time, ed, index) {
+      this.sentIndex = index;
+      if (time) {
+        this.curTime = time;
+        this.$refs.audioLine.onTimeupdateTime(time / 1000, true);
+        this.ed = ed;
+      }
+    },
+    emptyEd() {
+      this.ed = undefined;
+    },
+    // 保存
+    handleSave() {
+      this.loading = true;
+      // let MethodName = "/PaperServer/Client/Article/ArtNoteAdd";
+      // let data = {
+      //   iss_id: this.$route.query.iss_id,
+      //   art_id: this.$route.query.id,
+      //   pos: this.notesObj.pos,
+      //   select_text: this.notesObj.title,
+      //   note: this.notesObj.notes.trim(),
+      // };
+      // if (this.notesObj.id) {
+      //   MethodName = "/PaperServer/Client/Article/ArtNoteEdit";
+      //   data.id = this.notesObj.id;
+      // }
+      // getLogin(MethodName, data)
+      //   .then((res) => {
+      //     if (res.status === 1) {
+      //       this.loading = false;
+      this.notesFlag = false;
+      this.handleHighSentence();
+      this.$message.success('保存成功');
+      //   }
+      // })
+      // .catch(() => {
+      //   this.loading = false;
+      // });
+    },
+    // 删除
+    deleteNotes() {
+      this.$confirm('确定删除吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      }).then(() => {
+        // let MethodName = "/PaperServer/Client/Article/ArtNoteDelete";
+        // let data = {
+        //   id: this.notesObj.id,
+        // };
+        // getLogin(MethodName, data).then((res) => {
+        //   if (res.status === 1) {
+        this.notesFlag = false;
+        // this.handleData();
+        this.$message.success('删除成功');
+        // }
+        // });
+      });
+    },
+    // 高亮笔记句子
+    async handleHighSentence() {
+      let _this = this;
+      // let MethodName = "/PaperServer/Client/Article/ArtNoteListInArt";
+      // let data = {
+      //   id: this.$route.query.id,
+      // };
+      // await getLogin(MethodName, data).then((res) => {
+      //   if (res.status === 1) {
+      // this.highDataList = res.data;
+      // this.highDataList.forEach((itemh) => {
+      //   if (JSON.parse(itemh.pos).sent_id) {
+      //     this.resArr.forEach((itemr, indexr) => {
+      //       // itemr.wordsList.forEach(itemw=>{
+      //       if (indexr === JSON.parse(itemh.pos).sent_id) {
+      //         itemr.text = itemr.text.replace(
+      //           itemh.select_text,
+      //           "<span class='selece-high-sent' attr-id='" +
+      //             itemh.id +
+      //             "'>" +
+      //             itemh.select_text +
+      //             "</span>"
+      //         );
+      //       }
+      //       // })
+      //     });
+      //   }
+      // });
+      setTimeout(() => {
+        document.getElementsByClassName('selece-high-sent').forEach((itemH, indexH) => {
+          // if(indexH===0){
+          itemH.addEventListener('mousedown', function () {
+            _this.notesFlag = true;
+            _this.notesObj.id = itemH.getAttribute('attr-id');
+            for (let i = 0; i < _this.highDataList.length; i++) {
+              if (_this.highDataList[i].id === itemH.getAttribute('attr-id')) {
+                _this.notesObj.title = _this.highDataList[i].select_text;
+                _this.notesObj.pos = _this.highDataList[i].pos;
+                _this.notesObj.notes = _this.highDataList[i].note;
+                break;
+              }
+            }
+          });
+          // }
+        });
+      }, 200);
+      //   }
+      // });
+    },
+    mouseupClick(obj, index) {
+      console.log(obj);
+      this.activeSentObj = index;
+    },
+  }, // 如果页面有keep-alive缓存功能,这个函数会触发
+};
+</script>
+
+<style lang="scss" scoped>
+.NNPE-ArticleView {
+  width: 100%;
+
+  .aduioLine-practice-npc {
+    display: flex;
+    align-items: center;
+    justify-content: flex-start;
+
+    .aduioLine-content {
+      flex: 1;
+    }
+
+    .aduioLine-right {
+      box-sizing: border-box;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      width: 69px;
+      height: 40px;
+      padding: 0 12px;
+      border-left: 1px solid rgba(0, 0, 0, 10%);
+
+      .svg-icon {
+        width: 16px;
+        height: 16px;
+        cursor: pointer;
+      }
+    }
+  }
+
+  .NPC-sentences-list {
+    // padding: 24px 0;
+    color: rgba(0, 0, 0, 85%);
+
+    .NPC-article-empty {
+      display: flex;
+      align-items: flex-start;
+      justify-content: flex-start;
+
+      > div {
+        height: 24px;
+
+        &.empty-left {
+          box-sizing: border-box;
+          width: 100%;
+
+          &.hasRemark {
+            box-sizing: border-box;
+            width: 70%;
+            border-right: 1px rgba(0, 0, 0, 10%) solid;
+          }
+        }
+
+        &.empty-right {
+          flex: 1;
+        }
+      }
+
+      &-bottom {
+        > div {
+          height: 40px;
+        }
+      }
+    }
+  }
+
+  .NNPE-detail {
+    // overflow: hidden; // 为了不遮挡备注内容
+    display: flex;
+    align-items: flex-start;
+    justify-content: flex-start;
+    clear: both;
+
+    .para-center {
+      display: flex;
+      flex-flow: wrap;
+      justify-content: center;
+      width: 100%;
+    }
+
+    .para-right {
+      display: flex;
+      flex-flow: wrap;
+      justify-content: end;
+      width: 100%;
+    }
+
+    .NNPE-words {
+      float: left;
+      padding-bottom: 5px;
+
+      &-box {
+        float: left;
+
+        > span {
+          display: block;
+
+          &.NNPE-pinyin {
+            height: 22px;
+            font-family: 'League';
+            font-size: 14px;
+            font-weight: normal;
+            line-height: 1.5;
+            color: #000;
+
+            &.noFont {
+              font-family: initial;
+            }
+
+            &.textLeft {
+              text-align: left;
+            }
+
+            &.textRight {
+              text-align: right;
+            }
+          }
+
+          &.NNPE-chs {
+            display: flex;
+            flex-flow: wrap;
+            align-items: center;
+            font-family: '楷体';
+            font-size: 20px;
+            line-height: 1.4;
+            color: #000;
+
+            &.overActive {
+              background: rgba(0, 0, 0, 6%);
+            }
+
+            &.active {
+              background: rgba(222, 68, 68, 15%);
+            }
+
+            &.wordActive {
+              color: rgba(222, 68, 68, 100%);
+            }
+
+            .wordActive {
+              color: rgba(222, 68, 68, 100%);
+            }
+          }
+
+          &.padding {
+            padding: 0 3px;
+          }
+        }
+      }
+
+      &.textLeft {
+        text-align: left;
+      }
+
+      &.textCenter {
+        text-align: center;
+
+        .NNPE-chs {
+          justify-content: center;
+        }
+      }
+
+      &.textRight {
+        text-align: right;
+      }
+
+      > span {
+        display: block;
+
+        &.NNPE-pinyin {
+          height: 22px;
+          font-family: 'League';
+          font-size: 14px;
+          font-weight: normal;
+          line-height: 1.5;
+          color: #000;
+
+          &.noFont {
+            font-family: initial;
+          }
+
+          &.textLeft {
+            text-align: left;
+          }
+
+          &.textRight {
+            text-align: right;
+          }
+        }
+
+        &.NNPE-chs {
+          display: flex;
+          flex-flow: wrap;
+          align-items: center;
+          font-family: '楷体';
+          font-size: 20px;
+          line-height: 1.4;
+          color: #000;
+
+          &.overActive {
+            background: rgba(0, 0, 0, 6%);
+          }
+
+          &.active {
+            background: rgba(222, 68, 68, 15%);
+          }
+
+          &.wordActive {
+            color: rgba(222, 68, 68, 100%);
+          }
+
+          .wordActive {
+            color: rgba(222, 68, 68, 100%);
+          }
+        }
+
+        &.padding {
+          padding: 0 3px;
+        }
+      }
+    }
+
+    &.NNPE-detail-title {
+      .NNPE-title {
+        margin: 0 auto;
+      }
+
+      .wordsList-box {
+        > div {
+          display: flex;
+          flex-flow: wrap;
+          justify-content: center;
+        }
+      }
+    }
+
+    .index {
+      box-sizing: border-box;
+      width: 48px;
+      padding: 8px;
+      text-align: right;
+      border-right: 1px solid rgba(0, 0, 0, 10%);
+
+      b {
+        font-weight: 400;
+        line-height: 1.5;
+        color: #000;
+      }
+    }
+
+    .wordsList-box {
+      // display: flex;
+      width: 100%;
+      padding: 6px 24px 12px;
+
+      &-left {
+        justify-content: flex-start;
+      }
+
+      &-center {
+        justify-content: center;
+      }
+
+      &-right {
+        justify-content: flex-end;
+      }
+
+      > div {
+        overflow: hidden;
+        clear: both;
+      }
+
+      > img {
+        display: block;
+        max-width: 100%;
+        margin: 0 auto;
+      }
+    }
+
+    .article-content {
+      box-sizing: border-box;
+
+      // display: flex;
+      // align-items: flex-start;
+      // justify-content: flex-start;
+      width: 100%;
+
+      &.hasRemark {
+        width: 70%;
+        padding: 8px 0 8px 23px;
+        border-right: 1px rgba(0, 0, 0, 10%) solid;
+      }
+
+      &.paraLast {
+        padding-bottom: 24px;
+      }
+    }
+  }
+
+  .remarkBox {
+    position: relative;
+    display: flex;
+    flex: 1;
+    align-items: center;
+    justify-content: center;
+
+    &.remark72 {
+      padding-top: 72px;
+    }
+
+    &.remark-top {
+      padding-top: 44px;
+    }
+
+    &.remark-top-8 {
+      padding-top: 8px;
+    }
+  }
+
+  .NNPE-noteDetail {
+    position: fixed;
+    top: 50%;
+    left: 50%;
+    z-index: 9999;
+    max-width: 100%;
+    margin-top: -196px;
+    overflow: auto;
+
+    // box-shadow: 0 4px 16px rgba(0, 0, 0, 15%);
+  }
+
+  .NNPE-detail-box {
+    box-sizing: border-box;
+    width: 100%;
+    padding: 8px 24px;
+    margin-bottom: 8px;
+
+    &.active {
+      background: rgba(222, 68, 68, 15%);
+    }
+  }
+
+  .NNPE-details {
+    overflow: hidden;
+    clear: both;
+
+    .NNPE-words {
+      float: left;
+
+      &-box {
+        float: left;
+
+        > span {
+          display: block;
+
+          &.NNPE-pinyin {
+            height: 20px;
+            font-family: 'League';
+            font-size: 14px;
+            font-weight: normal;
+            line-height: 20px;
+            color: rgba(0, 0, 0, 100%);
+
+            &.noFont {
+              font-family: initial;
+            }
+
+            &.textLeft {
+              text-align: left;
+            }
+
+            &.wordBlank {
+              color: rgba(0, 0, 0, 100%);
+            }
+          }
+
+          &.NNPE-chs {
+            display: flex;
+            flex-flow: wrap;
+            align-items: center;
+            font-family: '楷体';
+            font-size: 20px;
+            line-height: 28px;
+            color: rgba(0, 0, 0, 100%);
+
+            .active {
+              color: #de4444;
+            }
+
+            &.wordBlank {
+              color: rgba(0, 0, 0, 100%);
+            }
+          }
+
+          // &.padding {
+          //   padding-right: 6px;
+          // }
+        }
+      }
+
+      &.textLeft {
+        text-align: left;
+      }
+
+      &.textCenter {
+        text-align: center;
+
+        .NNPE-chs {
+          justify-content: center;
+        }
+      }
+
+      &.textRight {
+        text-align: right;
+      }
+
+      > span {
+        display: block;
+
+        &.NNPE-pinyin {
+          height: 20px;
+          font-family: 'League';
+          font-size: 14px;
+          font-weight: normal;
+          line-height: 20px;
+          color: rgba(0, 0, 0, 100%);
+
+          &.noFont {
+            font-family: initial;
+          }
+
+          &.textLeft {
+            text-align: left;
+          }
+
+          &.wordBlank {
+            color: rgba(0, 0, 0, 100%);
+          }
+        }
+
+        &.NNPE-chs {
+          display: flex;
+          flex-flow: wrap;
+          align-items: center;
+          font-family: '楷体';
+          font-size: 20px;
+          line-height: 28px;
+          color: rgba(0, 0, 0, 100%);
+
+          .active {
+            color: #de4444;
+          }
+
+          &.wordBlank {
+            color: rgba(0, 0, 0, 100%);
+          }
+        }
+
+        &.padding {
+          padding: 0 3px;
+        }
+      }
+    }
+  }
+
+  .enwords {
+    padding-left: 3px;
+    font-family: 'Helvetica';
+    font-size: 14px;
+    font-weight: normal;
+    line-height: 22px;
+    color: rgba(0, 0, 0, 100%);
+    word-break: break-word;
+
+    &.wordBlank {
+      color: rgba(0, 0, 0, 100%);
+    }
+  }
+
+  .multilingual {
+    padding: 6px 24px 12px;
+    word-break: break-word;
+  }
+
+  .multilingual-para {
+    text-indent: 40px;
+    word-break: break-word;
+
+    &-center,
+    &.multilingual-center {
+      text-align: center;
+      text-indent: 0;
+    }
+
+    &.multilingual-right {
+      text-align: right;
+    }
+  }
+}
+
+.selece-high-sent {
+  text-decoration: underline dotted;
+  text-decoration-color: #175dff;
+  cursor: pointer;
+}
+</style>

+ 1 - 1
src/views/book/courseware/preview/components/h5_games/H5GamesPreview.vue

@@ -61,7 +61,7 @@ export default {
   methods: {
     initData() {
       this.data.file_list.forEach((item) => {
-        const suffix = item.file_name.slice(item.file_name.lastIndexOf('.') + 1, item.file_name.length).toLowerCase();
+        const suffix = item.file_url.slice(item.file_url.lastIndexOf('.') + 1, item.file_url.length).toLowerCase();
         if (suffix === 'html') {
           this.games_url = item.file_url;
         } else {

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

@@ -5,6 +5,7 @@
       <div class="view-area">
         <template v-if="isMore">
           <div class="picture-area">
+            <!-- 播放列表 -->
             <template v-if="'list' === data.property.view_method">
               <el-carousel
                 ref="pictureCarousel"
@@ -38,14 +39,15 @@
               </div>
             </template>
             <ul v-else class="view-independent">
-              <li v-for="(file, i) in data.file_list" :key="i" @click="handleIndicatorClick(i)">
+              <li v-for="file in data.file_list" :key="file.file_id" @click="handleIndicatorClick(i)">
                 <el-image :id="file.file_id" :src="file.file_url" fit="contain" />
               </li>
             </ul>
           </div>
         </template>
-        <template v-else>
-          <div v-for="(file, i) in data.file_list" :key="i" class="alone-pic-area">
+        <!-- 独立排放 -->
+        <template v-else-if="data.property.view_method === 'independent'">
+          <div v-for="file in data.file_list" :key="file.file_id" class="alone-pic-area">
             <el-image
               :id="file.file_id"
               :src="file.file_url"
@@ -132,9 +134,8 @@ export default {
   },
   mounted() {
     this.$nextTick(() => {
-      const canvasElement = document.querySelector('.canvas');
-      if (!canvasElement) {
-        const ele = this.$refs.pictureAreaBox;
+      const ele = this.$refs.pictureAreaBox;
+      if (ele) {
         const sn_position = this.data.property.sn_position;
         const viewMemo = this.isEnable(this.data.property.view_memo);
         // 序号在左和右补齐序号高度,去掉padding(8*2)
@@ -153,6 +154,7 @@ export default {
         this.isViewLeftRightBtn();
         return;
       }
+
       this.resizeObserver = new ResizeObserver((entries) => {
         if (!this.getDragStatus()) return;
         this.isResizing = true; // 标记为调整中

+ 2 - 1
src/views/project_manage/org/book/index.vue

@@ -16,6 +16,7 @@
         <el-table-column prop="org_name" label="所属机构" width="120" header-align="center" />
         <el-table-column prop="content_count" label="教材页面数" width="100" header-align="center" />
         <el-table-column prop="shangjia_time" label="上架时间" width="180" header-align="center" />
+        <el-table-column prop="version" label="版本号" width="90" header-align="center" align="center" />
         <el-table-column label="已申请下架" align="center" header-align="center">
           <template slot-scope="{ row }">
             <span style="color: #f53f3f">
@@ -31,7 +32,7 @@
               @click="
                 $router.push({
                   path: `/personal_workbench/project_info/${row.id}`,
-                  query: { isManage: false, backPath: 'org/book' },
+                  query: { isManage: false, backPath: '/project_manage/org/book' },
                 })
               "
             >

+ 1 - 1
src/views/project_manage/org/final/index.vue

@@ -25,7 +25,7 @@
               @click="
                 $router.push({
                   path: `/personal_workbench/project_info/${row.id}`,
-                  query: { isManage: false, backPath: 'org/final' },
+                  query: { isManage: false, backPath: '/project_manage/org/final' },
                 })
               "
               >查看信息</span

+ 7 - 0
src/views/project_manage/org/offlinepackauth/index.vue

@@ -380,6 +380,13 @@ export default {
 
       file_info_list.forEach((fileInfo) => {
         const { file_name, file_url, dir_name } = fileInfo;
+        // 如果有子目录,则判断是否有,没有就创建子目录
+        if (dir_name.split('/').length > 1) {
+          if (!window.fileAPI.existsSync(`${this.tempDir}\\${dir_name}`)) {
+            window.fileAPI.mkdirSync(`${this.tempDir}\\${dir_name}`);
+          }
+        }
+
         window.fileAPI.downloadFile(file_url, `${this.tempDir}\\${dir_name}\\${file_name}`).then(() => {
           this.downloadCompleted += 1;
         });

+ 1 - 1
src/views/project_manage/org/project/index.vue

@@ -28,7 +28,7 @@
               @click="
                 $router.push({
                   path: `/personal_workbench/project_info/${row.id}`,
-                  query: { isManage: false, backPath: 'org/project' },
+                  query: { isManage: false, backPath: '/project_manage/org/project' },
                 })
               "
               >查看信息</span