Browse Source

课文生词

natasha 5 days ago
parent
commit
06c31145bf

+ 7 - 5
src/views/book/courseware/create/components/question/article/Article.vue

@@ -16,7 +16,7 @@
         </div>
         <div v-if="data.content" class="btn-box">
           <a @click="checkArticle">文章校对</a>
-          <!-- <a @click="editWordsFlag = true">编辑生词短语注释</a> -->
+          <a @click="editWordsFlag = !editWordsFlag">编辑生词短语注释</a>
           <template v-if="data.wordTime && data.wordTime.length > 0">
             <!-- <span>已有字幕时间节点</span> -->
             <a type="text" @click="againWordTime">重新生成字幕时间</a>
@@ -49,11 +49,12 @@
           <el-button :loading="compareloading" type="primary" @click="saveCompare">确 定</el-button>
         </span>
       </el-dialog>
-      <el-dialog title="" :visible.sync="editWordsFlag" width="80%" :close-on-click-modal="true" top="0">
+      <!-- <el-dialog title="" :visible.sync="editWordsFlag" width="80%" :close-on-click-modal="true" top="0"> -->
+      <template v-if="editWordsFlag">
         <div class="tabs-box">
           <a :class="[editWordIndex === 0 ? 'active' : '']" @click="editWordIndex = 0">生词</a>
-          <a :class="[editWordIndex === 1 ? 'active' : '']" @click="editWordIndex = 1">注释</a>
           <a :class="[editWordIndex === 2 ? 'active' : '']" @click="editWordIndex = 2">其他词汇</a>
+          <a :class="[editWordIndex === 1 ? 'active' : '']" @click="editWordIndex = 1">注释</a>
         </div>
         <NewWord
           v-if="editWordIndex === 0"
@@ -64,7 +65,8 @@
 
         <Notes v-if="editWordIndex === 1" key="notes" :data-notes="data.notes_list" @sureNotes="sureNotes" />
         <NewWord v-if="editWordIndex === 2" :data-new-word="data.other_word_list" @sureNewWords="sureOtherNewWords" />
-      </el-dialog>
+      </template>
+      <!-- </el-dialog> -->
     </template>
   </ModuleBase>
 </template>
@@ -493,7 +495,7 @@ export default {
 .tabs-box {
   display: flex;
   column-gap: 12px;
-  margin-bottom: 12px;
+  margin: 12px 0;
 
   a {
     padding: 5px 16px;

+ 405 - 71
src/views/book/courseware/create/components/question/article/NewWord.vue

@@ -7,84 +7,183 @@
       :placeholder="'输入标题'"
       toolbar="fontselect fontsizeselect forecolor backcolor | underline | bold italic strikethrough alignleft aligncenter alignright"
     />
-    <el-table :data="data.option" border style="width: 100%">
-      <el-table-column fixed prop="number" label="序号" width="70">
-        <template slot-scope="scope">
-          <el-input v-model="scope.row.number" />
-        </template>
-      </el-table-column>
-      <el-table-column fixed prop="new_word" label="生词/短语" width="110">
-        <template slot-scope="scope">
-          <el-input v-model="scope.row.new_word" />
-        </template>
-      </el-table-column>
-      <el-table-column prop="mp3_list" label="读音" width="200">
-        <template slot-scope="scope">
-          <div v-if="scope.row.mp3_list">
-            <SoundRecord :wav-blob.sync="scope.row.mp3_list" />
-          </div>
+    <div class="option-list">
+      <div class="table-node">
+        <div class="table-th" style="width: 70px">
+          <label>序号</label>
+        </div>
+        <div class="table-th" style="width: 110px">
+          <label>生词/短语</label>
+        </div>
+        <div class="table-th" style="width: 200px">
+          <label>读音</label>
+        </div>
+        <div class="table-th" style="width: 110px">
+          <label>拼音</label>
+        </div>
+        <div class="table-th" style="width: 110px">
+          <label>词性</label>
+        </div>
+        <div class="table-th" style="width: 200px">
+          <label>图片</label>
+        </div>
+        <div class="table-th" style="width: 200px">
+          <label>释义</label>
+        </div>
+        <div class="table-th" style="width: 200px">
+          <label>搭配</label>
+        </div>
+        <div class="table-th" style="width: 300px">
+          <label>例句</label>
+        </div>
+        <div class="table-th" style="width: 100px">
+          <label>页眉</label>
+        </div>
+        <div class="table-th" style="width: 100px">
+          <label>标签</label>
+        </div>
+        <div class="table-th" style="width: 150px">
+          <label>操作</label>
+        </div>
+      </div>
+      <div v-for="(item, i) in data.new_word_list" :key="i" class="table-node">
+        <div class="table-item" style="width: 70px">
+          <el-input v-model="item.number" />
+        </div>
+        <div class="table-item" style="width: 110px">
+          <el-input v-model="item.new_word" @blur="handleBlurCon(item)" />
+        </div>
+        <div class="table-item" style="width: 200px">
+          <template v-if="data.lrc_arr.length > 0 && data.lrc_arr[i]">
+            <span class="adult-book-lable">字幕时间:</span>
+            <div style="display: flex; align-items: center">
+              <el-input
+                class="adult-book-input"
+                style="width: 50px"
+                v-model.trim="data.lrc_arr[i].bg"
+                maxlength="200"
+              ></el-input>
+              ~
+              <el-input
+                class="adult-book-input"
+                style="width: 50px"
+                v-model.trim="data.lrc_arr[i].ed"
+                maxlength="200"
+              ></el-input>
+            </div>
+          </template>
           <template v-else>
-            <div :class="['upload-audio-play']">
-              <div class="auto-matic" @click="handleMatic(scope.$index)">
-                <SvgIcon icon-class="voiceprint-line" class="record" />
-                <span class="auto-btn">{{ scope.row.mp3_list ? '已生成' : '生成音频' }}</span
-                >{{ scope.row.mp3_list ? '成功' : '' }}
-              </div>
+            <div v-if="item.mp3_list">
+              <SoundRecord :wav-blob.sync="item.mp3_list" />
             </div>
+            <template v-else>
+              <div :class="['upload-audio-play']">
+                <UploadAudio
+                  v-if="data.property.audio_generation_method === 'upload'"
+                  :file-id="item.mp3_list"
+                  :item-index="i"
+                  :show-upload="!item.mp3_list"
+                  @upload="uploads"
+                  @deleteFile="deleteFiles"
+                />
+                <div
+                  v-else-if="data.property.audio_generation_method === 'auto'"
+                  class="auto-matic"
+                  @click="handleMatic(i)"
+                >
+                  <SvgIcon icon-class="voiceprint-line" class="record" />
+                  <span class="auto-btn">{{ item.mp3_list ? '已生成' : '生成音频' }}</span
+                  >{{ item.mp3_list ? '成功' : '' }}
+                </div>
+                <SoundRecord v-else :wav-blob.sync="item.mp3_list" />
+              </div>
+            </template>
           </template>
-        </template>
-      </el-table-column>
-      <el-table-column prop="pinyin" label="拼音" width="110">
-        <template slot-scope="scope">
-          <el-input v-model="scope.row.pinyin" />
-        </template>
-      </el-table-column>
-      <el-table-column prop="cixing" label="词性" width="110">
-        <template slot-scope="scope">
+        </div>
+        <div class="table-item" style="width: 110px">
+          <el-input v-model="item.pinyin" />
+        </div>
+        <div class="table-item" style="width: 110px">
           <RichText
-            v-model="scope.row.cixing"
+            v-model="item.cixing"
             :inline="true"
             toolbar="fontselect fontsizeselect forecolor backcolor | underline | bold italic strikethrough alignleft aligncenter alignright"
           />
-        </template>
-      </el-table-column>
-      <el-table-column prop="definition_list" label="释义" width="200">
-        <template slot-scope="scope">
+        </div>
+        <div class="table-item" style="width: 200px">
+          <UploadPicture
+            :file-id="item.file_list[0]"
+            :item-index="i"
+            :show-upload="!item.file_list[0]"
+            @upload="uploadPic"
+            @deleteFile="deletePic"
+          />
+        </div>
+        <div class="table-item" style="width: 200px">
           <RichText
-            v-model="scope.row.definition_list"
+            v-model="item.definition_list"
             :inline="true"
             :placeholder="'多个释义用;隔开'"
             toolbar="fontselect fontsizeselect forecolor backcolor | underline | bold italic strikethrough alignleft aligncenter alignright"
           />
-        </template>
-      </el-table-column>
-      <el-table-column prop="collocation" label="搭配" width="200">
-        <template slot-scope="scope">
+        </div>
+        <div class="table-item" style="width: 200px">
           <RichText
-            v-model="scope.row.collocation"
+            v-model="item.collocation"
             :inline="true"
             toolbar="fontselect fontsizeselect forecolor backcolor | underline | bold italic strikethrough alignleft aligncenter alignright"
           />
-        </template>
-      </el-table-column>
-      <el-table-column prop="liju_list" label="例句" width="300">
-        <template slot-scope="scope">
+        </div>
+        <div class="table-item" style="width: 300px">
           <RichText
-            v-model="scope.row.liju_list"
+            v-model="item.liju_list"
             :inline="true"
             :placeholder="'多条例句用回车'"
             toolbar="fontselect fontsizeselect forecolor backcolor | underline | bold italic strikethrough alignleft aligncenter alignright"
           />
-        </template>
-      </el-table-column>
-      <el-table-column label="操作" width="150">
-        <template slot-scope="scope">
-          <el-button size="mini" type="text" @click="handleDelete(scope.$index)">删除</el-button>
-          <el-button size="mini" type="text" @click="moveElement(scope.row, scope.$index, 'up')">上移</el-button>
-          <el-button size="mini" type="text" @click="moveElement(scope.row, scope.$index, 'down')">下移</el-button>
-        </template>
-      </el-table-column>
-    </el-table>
+        </div>
+        <div class="table-item" style="width: 100px">
+          <el-input v-model="item.header_con" />
+        </div>
+        <div class="table-item" style="width: 100px">
+          <el-input v-model="item.label" />
+        </div>
+        <div class="table-item" style="width: 150px">
+          <el-button size="mini" type="text" @click="handleDelete(i)">删除</el-button>
+          <el-button size="mini" type="text" @click="moveElement(item, i, 'up')">上移</el-button>
+          <el-button size="mini" type="text" @click="moveElement(item, i, 'down')">下移</el-button>
+        </div>
+      </div>
+
+      <div class="table-node">
+        <div class="table-item" style="width: 70px">
+          <label style="line-height: 32px">列宽</label>
+        </div>
+        <div class="table-item" style="width: 110px">
+          <el-input v-model="data.col_width[0].value"></el-input>
+        </div>
+        <div class="table-item" style="width: 200px"></div>
+        <div class="table-item" style="width: 110px">
+          <el-input v-model="data.col_width[1].value"></el-input>
+        </div>
+        <div class="table-item" style="width: 110px">
+          <el-input v-model="data.col_width[2].value"></el-input>
+        </div>
+        <div class="table-item" style="width: 200px"></div>
+        <div class="table-item" style="width: 200px">
+          <el-input v-model="data.col_width[3].value"></el-input>
+        </div>
+        <div class="table-item" style="width: 200px">
+          <el-input v-model="data.col_width[4].value"></el-input>
+        </div>
+        <div class="table-item" style="width: 300px">
+          <el-input v-model="data.col_width[5].value"></el-input>
+        </div>
+        <div class="table-item" style="width: 100px"></div>
+        <div class="table-item" style="width: 100px"></div>
+        <div class="table-item" style="width: 150px"></div>
+      </div>
+    </div>
     <el-button icon="el-icon-plus" style="margin: 24px 0" @click="addElement">增加一个</el-button>
     <SelectUpload label="生词音频" type="audio" width="500px" @uploadSuccess="uploadAudioSuccess" />
     <div v-if="data.audio_data.url.length > 0" class="upload-file">
@@ -106,9 +205,53 @@
       </div>
       <SvgIcon icon-class="delete-black" size="12" @click="removeFile('lrc')" />
     </div>
-    <div class="btn-box" style="text-align: right">
-      <el-button @click="sureNewWords">保存</el-button>
+    <div class="lrc-box" style="margin: 5px 0">
+      <div v-if="data.lrc_arr && data.lrc_arr.length > 0" class="lrc-box">
+        <span>已有字幕时间节点</span>
+        <el-button type="text" @click="againWordTime">重新生成</el-button>
+      </div>
+      <template v-else>
+        <el-button v-if="!isWordTime" size="medium" @click="createWordTime" :loading="loading"
+          >自动生成字幕节点</el-button
+        >
+        <p v-else>字幕节点生成中...请等待</p>
+      </template>
+    </div>
+    <div class="adult-book-input-item">
+      <span class="adult-book-lable"></span>
+      <el-button type="primary" size="small" class="distribution" @click="parseLrcFile"> 分配时间 </el-button>
     </div>
+    <el-form :model="data.property" label-width="72px" label-position="left">
+      <el-form-item label="详细信息">
+        <el-radio-group v-model="data.property.is_has_infor">
+          <el-radio v-for="{ value, label } in inforList" :key="value" :label="value">
+            {{ label }}
+          </el-radio>
+        </el-radio-group>
+      </el-form-item>
+
+      <!-- <el-form-item label="自动换行">
+        <el-radio-group v-model="data.property.auto_wrap">
+          <el-radio v-for="{ value, label } in switchOption" :key="value" :label="value">{{ label }}</el-radio>
+        </el-radio-group>
+      </el-form-item> -->
+      <el-form-item label="读音">
+        <el-select v-model="data.property.audio_generation_method" placeholder="请选择">
+          <el-option v-for="{ value, label } in audioGenerationMethodList" :key="value" :label="label" :value="value" />
+        </el-select>
+      </el-form-item>
+
+      <el-form-item label="拼音位置">
+        <el-radio-group v-model="data.property.pinyin_position">
+          <el-radio v-for="{ value, label } in pinyinPositionList" :key="value" :label="value">
+            {{ label }}
+          </el-radio>
+        </el-radio-group>
+      </el-form-item>
+    </el-form>
+    <!-- <div class="btn-box" style="text-align: right">
+      <el-button @click="sureNewWords">保存</el-button>
+    </div> -->
   </div>
 </template>
 
@@ -116,8 +259,16 @@
 import SoundRecord from '@/views/book/courseware/create/components/question/fill/components/SoundRecord.vue';
 import UploadAudio from '@/views/book/courseware/create/components/question/fill/components/UploadAudio.vue';
 import SelectUpload from '@/views/book/courseware/create/components/common/SelectUpload.vue';
+import UploadPicture from '../new_word/components/UploadPicture.vue';
+
 import { GetStaticResources } from '@/api/app';
 import RichText from '@/components/RichText.vue';
+import {
+  audioGenerationMethodList,
+  pinyinPositionList,
+  inforList,
+  switchOption,
+} from '@/views/book/courseware/data/article';
 
 export default {
   name: 'NewWordPage',
@@ -126,11 +277,18 @@ export default {
     SoundRecord,
     UploadAudio,
     RichText,
+    UploadPicture,
   },
   props: ['dataNewWord'],
   data() {
     return {
-      data: JSON.parse(JSON.stringify(this.dataNewWord)),
+      data: this.dataNewWord,
+      isWordTime: false,
+      loading: false,
+      pinyinPositionList,
+      audioGenerationMethodList,
+      inforList,
+      switchOption,
     };
   },
   methods: {
@@ -139,11 +297,17 @@ export default {
         number: '',
         new_word: '',
         cixing: '', // 词性
-        definition_list: '', // 需要增加词性
+        definition_list: '', // 释义
         pinyin: '',
         mp3_list: '',
         collocation: '', // 搭配
         liju_list: '', // 例句
+        file_list: [''], // 图片
+        header_con: '', // 页眉
+        label: '', // 标签
+        hz_info: [],
+        bg: 0,
+        ed: 0,
       };
     },
     /**
@@ -180,6 +344,7 @@ export default {
           file_id,
         };
         this.parseLrcFile();
+        this.data.file_id_list.push(file_id);
       }
     },
     uploadAudioSuccess(fileList) {
@@ -192,14 +357,56 @@ export default {
           url: file_id,
           file_id,
         };
+        this.data.file_id_list.push(file_id);
+        let _this = this;
+        _this.loading = true;
+        let data = {
+          file_id: file_id,
+        };
+        fileToBase64Text(data)
+          .then((res) => {
+            let taskIddata = {
+              fileName: name,
+              speechBase64: res.base64_text,
+              language: 'ch',
+            };
+            prepareTranscribe(taskIddata)
+              .then((reses) => {
+                _this.loading = false;
+                _this.$set(_this.data, 'taskId', reses.data.taskId);
+              })
+              .catch(() => {
+                _this.loading = false;
+              });
+          })
+          .catch(() => {
+            _this.loading = false;
+          });
       }
     },
+    getBase64(file) {
+      return new Promise(function (resolve, reject) {
+        let reader = new FileReader();
+        let imgResult = '';
+        reader.readAsDataURL(file);
+        reader.onload = function () {
+          imgResult = reader.result;
+        };
+        reader.onerror = function (error) {
+          reject(error);
+        };
+        reader.onloadend = function () {
+          resolve(imgResult);
+        };
+      });
+    },
     /**
      * 删除文件
      * @param {'audio' | 'lrc'} type
      */
     removeFile(type) {
       if (type === 'audio') {
+        this.data.file_id_list = this.data.file_id_list.filter((item) => item !== this.data.audio_data.file_id);
         this.data.audio_data = {
           name: '',
           media_duration: 0,
@@ -208,6 +415,7 @@ export default {
           file_id: '',
         };
       } else if (type === 'lrc') {
+        this.data.file_id_list = this.data.file_id_list.filter((item) => item !== this.data.lrc_data.file_id);
         this.data.lrc_data = {
           name: '',
           url: '',
@@ -218,42 +426,128 @@ export default {
       this.data.lrc_arr = [];
     },
     uploads(file_id, index) {
-      this.data.option[index].mp3_list = file_id;
+      this.data.new_word_list[index].mp3_list = file_id;
+      this.data.file_id_list.push(file_id);
     },
     deleteFiles(file_id, index) {
-      this.data.option[index].mp3_list = '';
+      this.data.new_word_list[index].mp3_list = '';
+      this.data.file_id_list = this.data.file_id_list.filter((item) => item !== file_id);
+    },
+    uploadPic(file_id, index) {
+      this.data.new_word_list[index].file_list[0] = file_id;
+      this.data.file_id_list.push(file_id);
+    },
+    deletePic(file_id, index) {
+      this.data.new_word_list[index].file_list[0] = '';
+      this.data.file_id_list = this.data.file_id_list.filter((item) => item !== file_id);
     },
     // 自动生成音频
     handleMatic(index) {
       GetStaticResources('tool-TextToVoiceFile', {
-        text: this.data.option[index].new_word.replace(/<[^>]+>/g, ''),
+        text: this.data.new_word_list[index].new_word.replace(/<[^>]+>/g, ''),
       })
         .then(({ status, file_id }) => {
           if (status === 1) {
-            this.data.option[index].mp3_list = file_id;
+            this.data.new_word_list[index].mp3_list = file_id;
+            this.data.file_id_list.push(file_id);
           }
         })
         .catch(() => {});
     },
     // 删除行
     handleDelete(index) {
-      this.data.option.splice(index, 1);
+      this.data.file_id_list = this.data.file_id_list.filter(
+        (item) => item !== this.data.new_word_list[index].mp3_list,
+      );
+      this.data.new_word_list.splice(index, 1);
     },
     // 上移下移
     moveElement(dItem, index, type) {
       let obj = JSON.parse(JSON.stringify(dItem));
       if (type == 'up' && index > 0) {
-        this.data.option.splice(index - 1, 0, obj);
-        this.data.option.splice(index + 1, 1);
+        this.data.new_word_list.splice(index - 1, 0, obj);
+        this.data.new_word_list.splice(index + 1, 1);
       }
-      if (type == 'down' && index < this.data.option.length - 1) {
-        this.data.option[index] = this.data.option.splice(index + 1, 1, this.data.option[index])[0];
+      if (type == 'down' && index < this.data.new_word_list.length - 1) {
+        this.data.new_word_list[index] = this.data.new_word_list.splice(
+          index + 1,
+          1,
+          this.data.new_word_list[index],
+        )[0];
       }
     },
     // 增加
     addElement() {
-      this.data.option.push(this.getOption());
+      this.data.new_word_list.push(this.getOption());
+    },
+    // 获取数据
+    handleBlurCon(row) {
+      let cons = row.new_word.trim();
+      let MethodName = 'hz_resource_manager-GetMultHZStrokesContent';
+      let data = {
+        hz_str: cons,
+      };
+      GetStaticResources(MethodName, data)
+        .then((res) => {
+          for (let key in res) {
+            if (key != 'status' && key != ',' && res[key]) {
+              res[key] = JSON.parse(res[key]);
+            }
+          }
+          let hzDetailList = res;
+          let hz_list = [];
+          cons.split('').forEach((items) => {
+            let res = JSON.parse(JSON.stringify(hzDetailList[items]));
+            let obj = {
+              con: items,
+              hzDetail: {
+                hz_json: res,
+              },
+            };
+            hz_list.push(obj);
+          });
+          row.hz_info = hz_list;
+        })
+        .catch(() => {
+          this.loading = false;
+        });
+
+      row.pinyin = cnchar.spell(cons, 'array', 'low', 'tone').join(' ');
+    },
+    createWordTime() {
+      if (this.data.taskId) {
+        let verseList = [];
+        this.data.new_word_list.forEach((sItem, index) => {
+          // item.forEach((sItem, sIndex) => {
+          verseList.push(sItem.new_word);
+          // });
+        });
+        if (verseList.length > 0) {
+          this.isWordTime = true;
+          let data = {
+            taskId: this.data.taskId,
+            verseList: JSON.stringify(verseList),
+            matchType: 'chinese',
+            language: 'ch',
+          };
+          getWordTime(data)
+            .then((res) => {
+              this.data.lrc_arr = res.data.result;
+              this.isWordTime = false;
+            })
+            .catch(() => {
+              this.isWordTime = false;
+            });
+        }
+      } else {
+        this.$message.warning('请先上传音频');
+      }
+    },
+    againWordTime() {
+      this.isWordTime = false;
+      this.$set(this.data, 'lrc_arr', []);
     },
+
     sureNewWords() {
       this.$emit('sureNewWords', this.data);
     },
@@ -289,6 +583,46 @@ export default {
     cursor: pointer;
   }
 }
+
+.option-list {
+  margin-bottom: 12px;
+  overflow: auto;
+
+  .table-node {
+    display: flex;
+    row-gap: 16px;
+    width: 1850px;
+
+    .table-th {
+      padding: 8px;
+      background: #f2f3f5;
+      border: 1px solid $border-color;
+      border-bottom: none;
+
+      &:not(:last-child) {
+        border-right: 0;
+      }
+    }
+
+    .table-item {
+      padding: 8px;
+      overflow: hidden;
+      border: 1px solid $border-color;
+
+      &:not(:last-child) {
+        border-right: 0;
+      }
+
+      :deep p {
+        margin: 0;
+      }
+    }
+  }
+}
+
+:deep .upload-wrapper {
+  margin-top: 0;
+}
 </style>
 <style lang="scss">
 .tox .tox-editor-header {

+ 1 - 1
src/views/book/courseware/create/components/question/article/Notes.vue

@@ -62,7 +62,7 @@ export default {
   props: ['dataNotes'],
   data() {
     return {
-      data: JSON.parse(JSON.stringify(this.dataNotes)),
+      data: this.dataNotes,
     };
   },
   methods: {

+ 119 - 9
src/views/book/courseware/data/article.js

@@ -21,19 +21,37 @@ export const positionList = [
   },
 ];
 
-// 汉字框
-export const frameList = [
+export const wordShowList = [
+  { value: 'true', label: '是' },
+  { value: 'false', label: '否' },
+];
+
+export const inforList = [
+  { value: 'true', label: '有' },
+  { value: 'false', label: '没有' },
+];
+
+// 拼音位置
+export const pinyinPositionList = [
+  { value: 'front', label: '前面' },
+  { value: 'back', label: '后面' },
+  { value: 'top', label: '上面' },
+  { value: 'bottom', label: '下面' },
+];
+
+// 读音生成方式
+export const audioGenerationMethodList = [
   {
-    value: 'tian',
-    label: '田字格',
+    value: 'upload',
+    label: '上传',
   },
   {
-    value: 'fang',
-    label: '方框',
+    value: 'auto',
+    label: '自动生成',
   },
   {
-    value: 'none',
-    label: '无',
+    value: 'record',
+    label: '录音',
   },
 ];
 
@@ -63,7 +81,99 @@ export function getArticleData() {
     file_id_list: [], // 文件 id
     detail: [], // 分段分句分词详情
     wordTime: [], // 字幕时间
-    new_word_list: [], // 生词列表
+    new_word_list: {
+      title_con: '',
+      property: {
+        audio_generation_method: audioGenerationMethodList[0].value,
+        pinyin_position: pinyinPositionList[0].value,
+        auto_wrap: switchOption[0].value, // 自动换行
+        is_has_infor: inforList[0].value,
+      },
+      new_word_list: [],
+      lrc_arr: [], // lrc 文件解析后的数据
+      // lrc 文件数据
+      lrc_data: {
+        name: '',
+        url: '',
+        id: '',
+        file_id: '',
+      },
+      // 音频文件数据
+      audio_data: {
+        name: '',
+        media_duration: 0,
+        temporary_url: '',
+        url: '',
+        file_id: '',
+      },
+      wordTime: [], // 字幕时间节点
+      taskId:'',
+      file_id_list: [], // 文件 id
+      col_width: [
+        {
+          value:125  // 生词
+        },{
+          value:125  // 拼音
+        },{
+          value:125  // 词性
+        },{
+          value:125  // 释义
+        },{
+          value:150  // 搭配
+        },{
+          value:300  // 例句
+        }
+      ], // 列宽
+    }, // 生词列表
+    other_word_list: {
+      title_con: '',
+      property: {
+        audio_generation_method: audioGenerationMethodList[0].value,
+        pinyin_position: pinyinPositionList[0].value,
+        auto_wrap: switchOption[0].value, // 自动换行
+        is_has_infor: inforList[0].value,
+      },
+      new_word_list: [],
+      lrc_arr: [], // lrc 文件解析后的数据
+      // lrc 文件数据
+      lrc_data: {
+        name: '',
+        url: '',
+        id: '',
+        file_id: '',
+      },
+      // 音频文件数据
+      audio_data: {
+        name: '',
+        media_duration: 0,
+        temporary_url: '',
+        url: '',
+        file_id: '',
+      },
+      wordTime: [], // 字幕时间节点
+      taskId:'',
+      file_id_list: [], // 文件 id
+      col_width: [
+        {
+          value:125  // 生词
+        },{
+          value:125  // 拼音
+        },{
+          value:125  // 词性
+        },{
+          value:125  // 释义
+        },{
+          value:150  // 搭配
+        },{
+          value:300  // 例句
+        }
+      ], // 列宽
+    },
+    notes_list: {
+      title_con: '',
+      option: [],
+      property:{}
+    },
     sentence_list_mp: [], // 句子+分词数组
     pinyin_type:'pinyin',
     mind_map: {

+ 15 - 5
src/views/book/courseware/preview/components/article/index.vue

@@ -154,9 +154,15 @@
           />
         </div>
       </div>
-      <!--<template v-if="data.new_word_list.option.length > 0">
-        <NewWordPreview :newData="data.new_word_list"></NewWordPreview> 
-      </template>-->
+      <template v-if="data.new_word_list.new_word_list.length > 0">
+        <NewWordPreview :newData="data.new_word_list"></NewWordPreview>
+      </template>
+      <template v-if="data.other_word_list.new_word_list.length > 0">
+        <NewWordPreview :newData="data.other_word_list"></NewWordPreview>
+      </template>
+      <template v-if="data.notes_list.option.length > 0">
+        <NotesPreview :notesData="data.notes_list"></NotesPreview>
+      </template>
     </div>
   </div>
 </template>
@@ -174,6 +180,7 @@ import Voicefullscreen from './Voicefullscreen.vue';
 import { getToken } from '@/utils/auth';
 import { analysSubmit, GetFileURLMap } from '@/api/app';
 import NewWordPreview from '../new_word/NewWordPreview.vue';
+import NotesPreview from '../notes/NotesPreview.vue';
 
 export default {
   name: 'ArticlePreview',
@@ -184,6 +191,7 @@ export default {
     PhraseModel,
     Voicefullscreen,
     NewWordPreview,
+    NotesPreview,
   },
   mixins: [PreviewMixin],
   inject: ['bookInfo'],
@@ -386,8 +394,10 @@ export default {
           this.data.mp3_list[0].url = url_map[this.data.mp3_list[0].file_id];
         });
       }
-      this.NNPENewWordList = this.data.new_word_list_other_component_input;
-      // this.NNPEAnnotationList = this.data.notes_list.option;
+      this.NNPENewWordList = this.data.new_word_list_other_component_input
+        .concat(this.data.new_word_list.new_word_list)
+        .concat(this.data.other_word_list.new_word_list);
+      this.NNPEAnnotationList = this.data.notes_list.option;
       let resArr = [];
       let sentArrTotal = [];
       let timeArr = [];

+ 2 - 1
src/views/book/courseware/preview/components/new_word/NewWordPreview.vue

@@ -388,11 +388,12 @@ export default {
     AudioPlay,
     Strockplay,
   },
+  props: ['newData'],
   mixins: [PreviewMixin],
   inject: ['bookInfo'],
   data() {
     return {
-      data: getNewWordData(),
+      data: this.newData ? this.newData : getNewWordData(),
       wordShow: true,
       dataWord: null,
       detailShow: false,

+ 4 - 3
src/views/book/courseware/preview/components/notes/NotesPreview.vue

@@ -45,11 +45,12 @@ import PreviewMixin from '../common/PreviewMixin';
 export default {
   name: 'NotesPreview',
   components: {},
+  props: ['notesData'],
   mixins: [PreviewMixin],
   data() {
     return {
-      data: getNotesData(),
-      wordShow: false,
+      data: this.notesData ? this.notesData : getNotesData(),
+      wordShow: true,
     };
   },
   computed: {},
@@ -57,7 +58,7 @@ export default {
     data: {
       handler(val) {
         if (val) {
-          this.wordShow = isEnable(this.data.property.is_word_show);
+          // this.wordShow = isEnable(this.data.property.is_word_show);
         }
       },
       deep: true,