Browse Source

文章气泡预览高亮对应颜色

natasha 3 days ago
parent
commit
99c0a6bdd5

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

@@ -12,7 +12,12 @@
           >
             <el-option v-for="{ value, label } in fontFamilyList" :key="value" :label="label" :value="value" />
           </el-select>
-          <el-select v-model="articleAttrib.font_size" placeholder="请选择" style="width: 130px">
+          <el-select
+            v-model="articleAttrib.font_size"
+            placeholder="请选择"
+            style="width: 130px"
+            @change="data.unified_attrib.font_size = articleAttrib.font_size"
+          >
             <el-option
               v-for="(value, index) in 16"
               :key="index"
@@ -1327,6 +1332,8 @@ export default {
       })
         .then(() => {
           this.handleSyncCon(this.matchNotesObj, 'delete');
+          let index = this.data.notes_list.option.findIndex((items) => items.id === this.matchNotesObj.id);
+          this.data.notes_list.option.splice(index, 1);
           this.matchNoteFlag = false;
         })
         .catch(() => {});

+ 231 - 11
src/views/book/courseware/create/components/question/dialogue_article/Article.vue

@@ -12,7 +12,12 @@
           >
             <el-option v-for="{ value, label } in fontFamilyList" :key="value" :label="label" :value="value" />
           </el-select>
-          <el-select v-model="articleAttrib.font_size" placeholder="请选择" style="width: 130px">
+          <el-select
+            v-model="articleAttrib.font_size"
+            placeholder="请选择"
+            style="width: 130px"
+            @change="data.unified_attrib.font_size = articleAttrib.font_size"
+          >
             <el-option
               v-for="(value, index) in 16"
               :key="index"
@@ -50,7 +55,12 @@
         <div class="content">
           <div v-for="(item, index) in data.detail" :key="index" class="content-list">
             <div v-if="item.type === 'notice'" class="content-item">
-              <span v-html="item.notice"></span>
+              <span
+                v-html="item.notice"
+                :style="{
+                  fontSize: data.property.notice_size ? data.property.notice_size + 'px' : '',
+                }"
+              ></span>
               <div class="content-operation">
                 <div class="up-down">
                   <span
@@ -127,15 +137,22 @@
                       :style="{
                         textAlign: windex === 0 && wIndex === 0 ? 'left' : '',
                       }"
-                      @click="selectItem(wItem)"
                     >
-                      <span v-if="isEnable(data.property.view_pinyin)" class="pinyin">{{
-                        windex === 0 &&
-                        wIndex === 0 &&
-                        data.property.is_first_sentence_first_hz_pinyin_first_char_upper_case === 'true'
-                          ? wItem.pinyin_up
-                          : wItem.pinyin
-                      }}</span>
+                      <span
+                        v-if="isEnable(data.property.view_pinyin)"
+                        class="pinyin"
+                        :style="{
+                          fontSize: articleAttrib.pinyin_size,
+                        }"
+                        @click="selectItem(wItem)"
+                        >{{
+                          windex === 0 &&
+                          wIndex === 0 &&
+                          data.property.is_first_sentence_first_hz_pinyin_first_char_upper_case === 'true'
+                            ? wItem.pinyin_up
+                            : wItem.pinyin
+                        }}</span
+                      >
                       <span
                         class="word"
                         :style="{
@@ -143,8 +160,13 @@
                           textDecoration: wItem.textDecoration,
                           borderBottom: wItem.border === 'dotted' ? '1px dotted' : '',
                           fontWeight: wItem.fontWeight,
-                          color: wItem.color,
+                          color:
+                            wItem.matchNotesObj.con && wItem.matchNotesObj.notesColor
+                              ? wItem.matchNotesObj.notesColor
+                              : wItem.color,
+                          fontSize: articleAttrib.font_size,
                         }"
+                        @click="matchItemNotes(wItem)"
                         >{{ wItem.chs }}</span
                       >
                     </div>
@@ -459,6 +481,7 @@
           :data-notes="data.notes_list"
           :unified-attrib="data.unified_attrib ? data.unified_attrib : null"
           @sureNotes="sureNotes"
+          @handleSyncCon="handleSyncCon"
         />
         <NewWord
           v-if="editWordIndex === 2"
@@ -475,6 +498,41 @@
         :option-list="subtitleList"
         @saveSubtitles="saveSubtitles"
       />
+      <!-- 关联注释 -->
+      <el-dialog
+        v-if="matchNoteFlag"
+        :visible.sync="matchNoteFlag"
+        :show-close="true"
+        :close-on-click-modal="false"
+        :modal-append-to-body="false"
+        :modal="false"
+        width="600px"
+        class="article-matchNotes-dialog"
+        :title="matchNotesObj.id ? '编辑气泡' : '添加气泡'"
+      >
+        <div class="matchNotes-box">
+          <RichText
+            v-if="matchNotesObj.isRich"
+            ref="richText"
+            v-model="matchNotesObj.con"
+            :font-size="data.unified_attrib?.font_size"
+            :font-family="data.unified_attrib?.font"
+            :font-color="data.unified_attrib?.text_color"
+            toolbar="fontselect fontsizeselect forecolor backcolor | underline | bold italic strikethrough alignleft aligncenter alignright image media link"
+          />
+          <el-input v-else v-model="matchNotesObj.con" type="textarea" rows="5"></el-input>
+          <div class="matchNotes-color">
+            <span>气泡颜色<el-color-picker v-model="matchNotesObj.notesColor"></el-color-picker></span>
+            <span @click="matchNotesObj.isRich = !matchNotesObj.isRich"
+              ><SvgIcon icon-class="change" size="16" />切换文本模式</span
+            >
+          </div>
+          <div class="btn-box">
+            <el-button type="info" size="small" @click="cancleMatchNotesDialog">删除</el-button>
+            <el-button type="primary" size="small" @click="sureMatchNotes">保存</el-button>
+          </div>
+        </div>
+      </el-dialog>
     </template>
   </ModuleBase>
 </template>
@@ -495,6 +553,7 @@ import { toolGetWordPinyinCorrectionList } from '@/api/pinyinCorrection';
 import { getRandomNumber } from '@/utils';
 import { BatchSegContent, getWordTime, prepareTranscribe, fileToBase64Text, getWordTimes } from '@/api/article';
 import { fontFamilyList } from '@/views/book/courseware/data/table';
+import { PinyinBuild_OldFormat } from '@/api/book';
 
 export default {
   name: 'DialogueArticlePage',
@@ -554,6 +613,8 @@ export default {
       pinyinList: [], // 拼音校正列表
       fontFamilyList,
       articleAttrib: null,
+      matchNoteItem: null, // 选中关联注释的词
+      matchNoteFlag: false,
     };
   },
   watch: {
@@ -1021,8 +1082,19 @@ export default {
             matchWords: '',
             matchNotes: '',
             notesColor: '',
+
             img: [],
             imgPosition: 'after',
+            matchNotesObj: {
+              number: '',
+              con: '',
+              pinyin: '',
+              interpret: '',
+              note: '',
+              notesColor: '#8206BF',
+              id: '',
+              isRich: true,
+            },
           };
           sentArr.push(obj);
         });
@@ -1124,6 +1196,16 @@ export default {
                   notesColor: '',
                   img: [],
                   imgPosition: 'after',
+                  matchNotesObj: {
+                    number: '',
+                    con: '',
+                    pinyin: '',
+                    interpret: '',
+                    note: '',
+                    notesColor: '#8206BF',
+                    id: '',
+                    isRich: true,
+                  },
                 };
                 sentArr.push(obj);
               });
@@ -1678,6 +1760,99 @@ export default {
         });
       }
     },
+    // 点击汉字打开关联注释弹窗
+    matchItemNotes(item) {
+      if (!item.matchNotesObj.id) {
+        item.matchNotesObj.id = getRandomNumber();
+      }
+      this.matchNotesObj = item.matchNotesObj;
+      this.matchNoteFlag = true;
+    },
+    cancleMatchNotesDialog() {
+      this.$confirm('确定要删除此条气泡吗?', '提示', {
+        confirmButtonText: '确定',
+        cancelButtonText: '取消',
+        type: 'warning',
+      })
+        .then(() => {
+          this.handleSyncCon(this.matchNotesObj, 'delete');
+          let index = this.data.notes_list.option.findIndex((items) => items.id === this.matchNotesObj.id);
+          this.data.notes_list.option.splice(index, 1);
+          this.matchNoteFlag = false;
+        })
+        .catch(() => {});
+    },
+    // 确定关联注释
+    sureMatchNotes() {
+      let index = this.data.notes_list.option.findIndex((items) => items.id === this.matchNotesObj.id);
+      if (index > -1) {
+        this.data.notes_list.option[index] = this.matchNotesObj;
+      } else {
+        this.data.notes_list.option.push(this.matchNotesObj);
+      }
+      this.matchNoteFlag = false;
+      this.editWordsFlag = true;
+      this.editWordIndex = 1;
+    },
+    async handleBlurCon() {
+      let text = this.matchNotesObj.con.replace(/<[^>]+>/g, '');
+      if (text) {
+        this.matchNotesObj.pinyin = await this.handlePinyins(
+          text,
+          this.data.notes_list.property.is_first_sentence_first_hz_pinyin_first_char_upper_case,
+        );
+      }
+    },
+    // 自动生成拼音
+    handlePinyins(text, flag) {
+      let data = {
+        text: text,
+        is_rich_text: 'false',
+        is_first_sentence_first_hz_pinyin_first_char_upper_case: flag ? flag : 'false',
+        is_fill_space: 'false',
+        is_custom_fc: 'false',
+      };
+      return new Promise((resolve, reject) => {
+        PinyinBuild_OldFormat(data).then((res) => {
+          if (res.parsed_text) {
+            let mergedData = '';
+            res.parsed_text.paragraph_list.map((outerArr, i) =>
+              outerArr.map((innerArr, j) =>
+                innerArr.map((newItem, k) => {
+                  mergedData += newItem.pinyin + ' ';
+                }),
+              ),
+            );
+            resolve(mergedData);
+          }
+        });
+      });
+    },
+    // 在气泡列表里修改了内容,同步detail的内容
+    handleSyncCon(obj, type) {
+      this.data.detail.forEach((item) => {
+        item.wordsList.forEach((items) => {
+          items.forEach((itemss) => {
+            if (itemss.matchNotesObj.id === obj.id) {
+              if (type === 'delete') {
+                itemss.matchNotesObj = {
+                  number: '',
+                  con: '',
+                  pinyin: '',
+                  interpret: '',
+                  note: '',
+                  notesColor: '#8206BF',
+                  id: '',
+                  isRich: true,
+                };
+              } else {
+                itemss.matchNotesObj = obj;
+              }
+            }
+          });
+        });
+      });
+    },
   },
 };
 </script>
@@ -1761,6 +1936,7 @@ export default {
   .text-item {
     padding: 0 1px;
     text-align: center;
+    cursor: pointer;
   }
 
   .pinyin {
@@ -1946,6 +2122,50 @@ export default {
   }
 }
 
+.article-matchNotes-dialog {
+  .el-dialog__header,
+  .el-dialog__body {
+    padding: 5px 10px;
+  }
+
+  .btn-box {
+    display: block;
+    padding: 5px 0;
+    text-align: right;
+
+    .el-button {
+      padding: 2px 12px;
+      font-size: 12px;
+      line-height: 20px;
+    }
+  }
+
+  .matchNotes-color {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-top: 5px;
+
+    span {
+      display: flex;
+      gap: 3px;
+      align-items: center;
+      cursor: pointer;
+    }
+
+    .el-color-picker--small {
+      height: 16px;
+    }
+
+    .el-color-picker__trigger {
+      width: 16px;
+      height: 16px;
+      padding: 0;
+      border: none;
+    }
+  }
+}
+
 .article-checkpinyin-dialog {
   .el-dialog__header {
     padding: 0;

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

@@ -488,8 +488,8 @@
                                   curTime <= item.timeList[pItem.sentIndex].ed &&
                                   attrib
                                     ? attrib.topic_color
-                                    : item.wordsList[pIndex + 1].matchNotesObj.con &&
-                                        item.wordsList[pIndex + 1].matchNotesObj.notesColor
+                                    : item.wordsList[pIndex + 2].matchNotesObj.con &&
+                                        item.wordsList[pIndex + 2].matchNotesObj.notesColor
                                       ? item.wordsList[pIndex + 2].matchNotesObj.notesColor
                                       : item.wordsList[pIndex + 2].config.color,
                               }"

+ 21 - 33
src/views/book/courseware/preview/components/dialogue_article/NormalModelChs.vue

@@ -61,7 +61,9 @@
         <div class="NPC-article-empty">
           <div
             :class="['empty-left', isHasRemark ? 'hasRemark' : '']"
-            :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
+            :style="{
+              width: isHasRemark && curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '',
+            }"
           ></div>
           <div class="empty-right"></div>
         </div>
@@ -82,7 +84,7 @@
           <div
             :class="['article-content', isHasRemark ? 'hasRemark' : '']"
             :style="{
-              width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '',
+              width: isHasRemark && curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '',
             }"
           >
             <template v-if="item.type === 'notice'">
@@ -257,13 +259,9 @@
                                         curTime < item.timeList[pItem.sentIndex].ed &&
                                         attrib
                                           ? attrib.topic_color
-                                          : pItem.notesColor
-                                            ? pItem.notesColor
-                                            : annotationList.indexOf(pItem.chs) > -1
-                                              ? NNPEAnnotationList.find(
-                                                  (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
-                                                ).notesColor
-                                              : pItem.config.color,
+                                          : pItem.matchNotesObj.con && pItem.matchNotesObj.notesColor
+                                            ? pItem.matchNotesObj.notesColor
+                                            : pItem.config.color,
                                       fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
                                       lineHeight:
                                         attrib && attrib.font_size
@@ -372,14 +370,10 @@
                                     curTime <= item.timeList[pItem.sentIndex].ed &&
                                     attrib
                                       ? attrib.topic_color
-                                      : item.wordsList[pIndex + 1].notesColor
-                                        ? item.wordsList[pIndex + 1].notesColor
-                                        : annotationList.indexOf(item.wordsList[pIndex + 1].chs) > -1
-                                          ? NNPEAnnotationList.find(
-                                              (item) =>
-                                                item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 1].chs,
-                                            ).notesColor
-                                          : item.wordsList[pIndex + 1].config.color,
+                                      : item.wordsList[pIndex + 1].matchNotesObj.con &&
+                                          item.wordsList[pIndex + 1].matchNotesObj.notesColor
+                                        ? item.wordsList[pIndex + 1].matchNotesObj.notesColor
+                                        : item.wordsList[pIndex + 1].config.color,
                                   fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
                                   lineHeight:
                                     attrib && attrib.font_size
@@ -502,14 +496,10 @@
                                     curTime <= item.timeList[pItem.sentIndex].ed &&
                                     attrib
                                       ? attrib.topic_color
-                                      : item.wordsList[pIndex + 2].notesColor
-                                        ? item.wordsList[pIndex + 2].notesColor
-                                        : annotationList.indexOf(item.wordsList[pIndex + 2].chs) > -1
-                                          ? NNPEAnnotationList.find(
-                                              (item) =>
-                                                item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 2].chs,
-                                            ).notesColor
-                                          : item.wordsList[pIndex + 2].config.color,
+                                      : item.wordsList[pIndex + 2].matchNotesObj.con &&
+                                          item.wordsList[pIndex + 2].matchNotesObj.notesColor
+                                        ? item.wordsList[pIndex + 2].matchNotesObj.notesColor
+                                        : item.wordsList[pIndex + 2].config.color,
                                   fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
                                   lineHeight:
                                     attrib && attrib.font_size
@@ -635,13 +625,9 @@
                                       curTime <= item.timeList[pItem.sentIndex].ed &&
                                       attrib
                                         ? attrib.topic_color
-                                        : pItem.notesColor
-                                          ? pItem.notesColor
-                                          : annotationList.indexOf(pItem.chs) > -1
-                                            ? NNPEAnnotationList.find(
-                                                (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
-                                              ).notesColor
-                                            : pItem.config.color,
+                                        : pItem.matchNotesObj.con && pItem.matchNotesObj.notesColor
+                                          ? pItem.matchNotesObj.notesColor
+                                          : pItem.config.color,
                                     fontSize: attrib && attrib.font_size ? attrib.font_size : '20px',
                                     lineHeight:
                                       attrib && attrib.font_size
@@ -754,7 +740,9 @@
         <div class="NPC-article-empty NPC-article-empty-bottom">
           <div
             :class="['empty-left', isHasRemark ? 'hasRemark' : '']"
-            :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
+            :style="{
+              width: isHasRemark && curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '',
+            }"
           ></div>
           <div class="empty-right"></div>
         </div>

+ 21 - 33
src/views/book/courseware/preview/components/dialogue_article/PhraseModelChs.vue

@@ -59,7 +59,9 @@
         <div class="NPC-article-empty">
           <div
             :class="['empty-left', isHasRemark ? 'hasRemark' : '']"
-            :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
+            :style="{
+              width: isHasRemark && curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '',
+            }"
           ></div>
           <div class="empty-right"></div>
         </div>
@@ -72,7 +74,7 @@
           <div
             :class="['article-content', isHasRemark ? 'hasRemark' : '']"
             :style="{
-              width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '',
+              width: isHasRemark && curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '',
             }"
           >
             <template v-if="item.type === 'notice'">
@@ -227,13 +229,9 @@
                                       ? attrib
                                         ? attrib.topic_color
                                         : pItem.config.color
-                                      : pItem.notesColor
-                                        ? pItem.notesColor
-                                        : annotationList.indexOf(pItem.chs) > -1
-                                          ? NNPEAnnotationList.find(
-                                              (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
-                                            ).notesColor
-                                          : pItem.config.color,
+                                      : pItem.matchNotesObj.con && pItem.matchNotesObj.notesColor
+                                        ? pItem.matchNotesObj.notesColor
+                                        : pItem.config.color,
                                 }"
                                 @click.stop="viewNotes($event, pItem.words ? pItem.words : pItem.chs, pItem)"
                                 >{{ convertText(pItem.chs) }}</span
@@ -306,14 +304,10 @@
                                       ? attrib
                                         ? attrib.topic_color
                                         : item.wordsList[pIndex + 1].config.color
-                                      : item.wordsList[pIndex + 1].notesColor
-                                        ? item.wordsList[pIndex + 1].notesColor
-                                        : annotationList.indexOf(item.wordsList[pIndex + 1].chs) > -1
-                                          ? NNPEAnnotationList.find(
-                                              (item) =>
-                                                item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 1].chs,
-                                            ).notesColor
-                                          : item.wordsList[pIndex + 1].config.color,
+                                      : item.wordsList[pIndex + 1].matchNotesObj.con &&
+                                          item.wordsList[pIndex + 1].matchNotesObj.notesColor
+                                        ? item.wordsList[pIndex + 1].matchNotesObj.notesColor
+                                        : item.wordsList[pIndex + 1].config.color,
                                 }"
                                 @click.stop="
                                   viewNotes(
@@ -415,14 +409,10 @@
                                       ? attrib
                                         ? attrib.topic_color
                                         : item.wordsList[pIndex + 2].config.color
-                                      : item.wordsList[pIndex + 2].notesColor
-                                        ? item.wordsList[pIndex + 2].notesColor
-                                        : annotationList.indexOf(item.wordsList[pIndex + 2].chs) > -1
-                                          ? NNPEAnnotationList.find(
-                                              (item) =>
-                                                item.con.replace(/<[^>]*>?/gm, '') === item.wordsList[pIndex + 2].chs,
-                                            ).notesColor
-                                          : item.wordsList[pIndex + 2].config.color,
+                                      : item.wordsList[pIndex + 2].matchNotesObj.con &&
+                                          item.wordsList[pIndex + 2].matchNotesObj.notesColor
+                                        ? item.wordsList[pIndex + 2].matchNotesObj.notesColor
+                                        : item.wordsList[pIndex + 2].config.color,
                                 }"
                                 @click.stop="
                                   viewNotes(
@@ -502,13 +492,9 @@
                                     ? attrib
                                       ? attrib.topic_color
                                       : pItem.config.color
-                                    : pItem.notesColor
-                                      ? pItem.notesColor
-                                      : annotationList.indexOf(pItem.chs) > -1
-                                        ? NNPEAnnotationList.find(
-                                            (item) => item.con.replace(/<[^>]*>?/gm, '') === pItem.chs,
-                                          ).notesColor
-                                        : pItem.config.color,
+                                    : pItem.matchNotesObj.con && pItem.matchNotesObj.notesColor
+                                      ? pItem.matchNotesObj.notesColor
+                                      : pItem.config.color,
                               }"
                               @click.stop="viewNotes($event, pItem.words ? pItem.words : pItem.chs, pItem)"
                               >{{ convertText(pItem.chs) }}</span
@@ -592,7 +578,9 @@
         <div class="NPC-article-empty NPC-article-empty-bottom">
           <div
             :class="['empty-left', isHasRemark ? 'hasRemark' : '']"
-            :style="{ width: curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '' }"
+            :style="{
+              width: isHasRemark && curQue.property.remarkWidth ? 100 - curQue.property.remarkWidth * 1 + '%' : '',
+            }"
           ></div>
           <div class="empty-right"></div>
         </div>