Browse Source

Merge branch 'master' of http://60.205.254.193:3000/GCLS/eep_page

dsy 3 weeks ago
parent
commit
74052c0ab3

+ 8 - 0
src/api/article.js

@@ -42,3 +42,11 @@ export function getCoursewareWordExampleSentenceList(data) {
 export function getSysConfig() {
   return http.post(`${process.env.VUE_APP_EepServer}?MethodName=sys_config_manager-GetSysConfig`);
 }
+
+// 音频字幕打点-火山
+export function getWordTimes (data) {
+  return http.post(
+    `${process.env.VUE_APP_EepServer}?MethodName=tool-AudioTextDot_OldFormat`,
+    data,
+  );
+}

+ 1 - 0
src/icons/svg/borderDotted.svg

@@ -0,0 +1 @@
+<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg t="1766029286060" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="6052" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><path d="M578.4576 865.5872V115.6096H921.6V1.024H102.4v114.688h343.1424v749.9776z" fill="#000000" p-id="6053"></path><path d="M51.2 972.8m-51.2 0a51.2 51.2 0 1 0 102.4 0 51.2 51.2 0 1 0-102.4 0Z" fill="#000000" p-id="6054"></path><path d="M358.4 972.8m-51.2 0a51.2 51.2 0 1 0 102.4 0 51.2 51.2 0 1 0-102.4 0Z" fill="#000000" p-id="6055"></path><path d="M665.6 972.8m-51.2 0a51.2 51.2 0 1 0 102.4 0 51.2 51.2 0 1 0-102.4 0Z" fill="#000000" p-id="6056"></path><path d="M972.8 972.8m-51.2 0a51.2 51.2 0 1 0 102.4 0 51.2 51.2 0 1 0-102.4 0Z" fill="currentColor" p-id="6057"></path></svg>

+ 40 - 4
src/views/book/courseware/create/components/question/article/Article.vue

@@ -25,7 +25,7 @@
             <a size="medium" @click="compareTime('文字')">校对文字字幕时间</a>
           </template>
           <template v-else>
-            <a v-if="!isWordTime" size="medium" @click="createWordTime">自动生成字幕节点</a>
+            <a v-if="!isWordTime" size="medium" @click="createWordTimes">自动生成字幕节点</a>
             <p v-else>字幕节点生成中...请等待</p>
           </template>
           <el-button @click="handleMultilingual">课文多语言</el-button>
@@ -88,7 +88,14 @@ import NewWord from './NewWord.vue';
 import Notes from './Notes.vue';
 
 import { getArticleData } from '@/views/book/courseware/data/article';
-import { segSentences, BatchSegContent, getWordTime, prepareTranscribe, fileToBase64Text } from '@/api/article';
+import {
+  segSentences,
+  BatchSegContent,
+  getWordTime,
+  prepareTranscribe,
+  fileToBase64Text,
+  getWordTimes,
+} from '@/api/article';
 const Base64 = require('js-base64').Base64;
 import cnchar from 'cnchar';
 
@@ -241,6 +248,9 @@ export default {
               cnchar.spell(sItem, 'low', 'tone').charAt(0).toUpperCase() + cnchar.spell(sItem, 'low', 'tone').slice(1),
             pinyin_tone: toneStr.join(' '),
             fontFamily: '楷体',
+            textDecoration: '',
+            fontWeight: '',
+            border: '',
           };
           sentArr.push(obj);
         });
@@ -301,6 +311,9 @@ export default {
                 cnchar.spell(sItem, 'low', 'tone').slice(1),
               pinyin_tone: toneStr.join(' '),
               fontFamily: '楷体',
+              textDecoration: '',
+              fontWeight: '',
+              border: '',
             };
             sentArr.push(obj);
           });
@@ -351,8 +364,11 @@ export default {
         this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].pinyin = pinyin;
       }
     },
-    saveStyle(paraIndex, sentenceIndex, wordIndex, style) {
-      this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].fontFamily = style;
+    saveStyle(paraIndex, sentenceIndex, wordIndex, fontFamily, textDecoration, fontWeight, border) {
+      this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].fontFamily = fontFamily;
+      this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].textDecoration = textDecoration;
+      this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].fontWeight = fontWeight;
+      this.data.detail[paraIndex].wordsList[sentenceIndex][wordIndex].border = border;
     },
     // 保存校对
     saveCompare() {
@@ -391,6 +407,26 @@ export default {
       this.isWordTime = false;
       this.data.wordTime = [];
     },
+    createWordTimes() {
+      let _this = this;
+
+      if (_this.data.mp3_list && _this.data.mp3_list.length > 0 && _this.data.mp3_list[0].file_id) {
+        if (_this.data.content) {
+          _this.isWordTime = true;
+          let data = {
+            audio_file_id: _this.data.mp3_list[0].file_id,
+            text: _this.data.content,
+          };
+          getWordTimes(data).then((res) => {
+            _this.data.wordTime = res.data.result;
+            _this.isWordTime = false;
+          });
+        }
+      } else {
+        _this.$message.warning('请先上传音频');
+        _this.loading = false;
+      }
+    },
     createWordTime() {
       let _this = this;
       this.getfillLiu().then(() => {

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

@@ -35,6 +35,13 @@
           >
             <div class="remark-box"><i class="el-icon-upload"></i>上传图片/视频</div>
           </el-upload>
+          <div class="set-para">
+            <span>图片/视频位置:</span>
+            <el-radio-group v-model="item.sourcePosition">
+              <el-radio label="before">段落前</el-radio>
+              <el-radio label="after">段落后</el-radio>
+            </el-radio-group>
+          </div>
         </template>
         <div v-for="(items, indexs) in item.sentenceStr" :key="indexs + 'words'" class="sentence-box">
           <div class="sentence">
@@ -279,7 +286,6 @@ export default {
           this.activeItem.sourceList = file_info_list;
           this.activeItem.sourceList[0].name = file_info_list[0].file_name;
           this.activeItem.sourceList[0].type = file.file.type.includes('image') > -1 ? 'image' : 'video';
-          console.log(this.activeItem.sourceList);
         }
       });
     },

+ 111 - 26
src/views/book/courseware/create/components/question/article/CheckStyle.vue

@@ -23,6 +23,13 @@
               <span
                 class="words"
                 :class="[/^[0-9]*$/.test(items.text)] ? (/^[\u4e00-\u9fa5]/.test(items.text) ? 'hanzi' : 'en') : ''"
+                :style="{
+                  fontFamily: items.fontFamily,
+                  color: items.color,
+                  textDecoration: items.textDecoration,
+                  borderBottom: items.border === 'dotted' ? '1px dotted' : '',
+                  fontWeight: items.fontWeight,
+                }"
               >
                 {{ items.text }}
               </span>
@@ -38,26 +45,51 @@
       :close-on-click-modal="false"
       :modal-append-to-body="false"
       :modal="false"
-      width="250px"
+      width="400px"
       class="login-dialog"
     >
       <div class="check-box">
         <div class="content">
           <div class="words-box">
-            <span class="words">
+            <span
+              class="words"
+              :style="{
+                fontFamily: itemActive.fontFamily,
+                color: itemActive.color,
+                textDecoration: itemActive.textDecoration,
+                borderBottom: itemActive.border === 'dotted' ? '1px dotted' : '',
+                fontWeight: itemActive.fontWeight,
+              }"
+            >
               {{ itemActive.text }}
             </span>
           </div>
         </div>
-        <el-form>
-          <el-form-item label="字体">
-            <el-radio-group v-model="itemActive.fontFamily">
-              <el-radio v-for="(item, index) in fontFamilyList" :key="'fontFamilyList' + index" :label="item.value">
-                <span>{{ item.name }}</span>
-              </el-radio>
-            </el-radio-group>
-          </el-form-item>
-        </el-form>
+        <div ref="toolbarMenu" class="toolbar">
+          <el-select v-model="itemActive.fontFamily" placeholder="请选择">
+            <el-option v-for="item in fontFamilyList" :key="item.value" :label="item.name" :value="item.value" />
+          </el-select>
+          <span class="picker-area" :class="['tool-item', itemActive.color ? 'active' : '']">
+            <el-color-picker
+              ref="colorPicker"
+              v-model="itemActive.color"
+              @click="itemActive.color = itemActive.color"
+            />
+            <SvgIcon icon-class="fontcolor" title="字体颜色" size="18" />
+          </span>
+          <span :class="['tool-item', itemActive.textDecoration === 'underline' ? 'active' : '']">
+            <SvgIcon icon-class="underline" title="下划线" size="18" @click="setActiveTextStyle('underline')" />
+          </span>
+          <span :class="['tool-item', itemActive.fontWeight === 'bold' ? 'active' : '']">
+            <SvgIcon icon-class="bold" title="加粗" size="20" @click="setActiveTextStyle('bold')" />
+          </span>
+          <span :class="['tool-item', itemActive.textDecoration === 'line-through' ? 'active' : '']">
+            <SvgIcon icon-class="strikethrough" title="删除线" size="20" @click="setActiveTextStyle('line-through')" />
+          </span>
+          <span :class="['tool-item', itemActive.border === 'dotted' ? 'active' : '']">
+            <SvgIcon icon-class="borderDotted" title="下划虚线" size="16" @click="setActiveTextStyle('border')" />
+          </span>
+        </div>
         <div class="btn-box">
           <el-button type="info" size="small" @click="cancleDialog">取消</el-button>
           <el-button type="primary" size="small" @click="surePinyin">保存</el-button>
@@ -85,21 +117,6 @@ export default {
       dialogFlag: false,
       checkPinyinInput: '',
       oldInput: '',
-      tableData: [
-        ['ā', 'á', 'ǎ', 'à', 'a'],
-        ['ō', 'ó', 'ǒ', 'ò', 'o'],
-        ['ē', 'é', 'ě', 'è', 'e'],
-        ['ī', 'í', 'ǐ', 'ì', 'i'],
-        ['ū', 'ú', 'ǔ', 'ù', 'u'],
-        ['ǖ', 'ǘ', 'ǚ', 'ǜ', 'ü'],
-        ['Ā', 'Á', 'Â', 'À', 'A'],
-        ['Ō', 'Ó', 'Ô', 'Ò', 'O'],
-        ['Ē', 'É', 'Ê', 'È', 'E'],
-        ['Ī', 'Í', 'Î', 'Ì', 'I'],
-        ['Ū', 'Ú', 'Û', 'Ù', 'U'],
-        ['n', 'ń', 'ň', 'ǹ', 'n'],
-        ['m̄', 'ḿ', 'm', 'm̀', 'm'],
-      ],
       toneList: [' ', 'ˉ', 'ˊ', 'ˇ', 'ˋ'],
       fontFamilyList: [
         {
@@ -152,6 +169,9 @@ export default {
               marginRight: true,
               saveIndex,
               fontFamily: itemss.fontFamily,
+              textDecoration: itemss.textDecoration,
+              fontWeight: itemss.fontWeight,
+              border: itemss.border,
             };
             arr[index].push(obj);
             let saveObj = {
@@ -191,12 +211,32 @@ export default {
         this.itemActive.sentenceIndex,
         this.itemActive.wordIndex,
         this.itemActive.fontFamily,
+        this.itemActive.textDecoration,
+        this.itemActive.fontWeight,
+        this.itemActive.border,
       );
       this.$message.success('保存成功');
       this.activeIndex = null;
       // this.itemActive = null;
       this.dialogFlag = false;
     },
+    // 设置样式
+    setActiveTextStyle(type) {
+      let style = this.itemActive;
+      if (type === 'line-through') {
+        style.textDecoration = style.textDecoration === 'line-through' ? '' : 'line-through';
+        this.$set(this.itemActive, 'textDecoration', style.textDecoration);
+      } else if (type === 'bold') {
+        style.fontWeight = style.fontWeight === 'bold' ? '' : 'bold';
+        this.$set(this.itemActive, 'fontWeight', style.fontWeight);
+      } else if (type === 'underline') {
+        style.textDecoration = style.textDecoration === 'underline' ? '' : 'underline';
+        this.$set(this.itemActive, 'textDecoration', style.textDecoration);
+      } else if (type === 'border') {
+        style.border = style.border === 'dotted' ? '' : 'dotted';
+        this.$set(this.itemActive, 'border', style.border);
+      }
+    },
   },
 };
 </script>
@@ -368,6 +408,47 @@ export default {
     }
   }
 }
+
+.toolbar {
+  display: flex;
+  column-gap: 10px;
+  align-items: center;
+  margin: 10px 0;
+  cursor: pointer;
+
+  .picker-area {
+    position: relative;
+
+    :deep .el-color-picker {
+      position: absolute;
+
+      &__trigger {
+        border: none;
+      }
+
+      &__color {
+        border: none !important;
+
+        &-inner {
+          background-color: rgba(0, 0, 0, 0%) !important;
+        }
+      }
+
+      &__icon {
+        display: none !important;
+      }
+    }
+  }
+
+  .tool-item {
+    padding: 4px 6px;
+    border-radius: 8px;
+
+    &.active {
+      background: #a6ccf7;
+    }
+  }
+}
 </style>
 <style lang="scss">
 .check-article {
@@ -385,5 +466,9 @@ export default {
       background: #f3f3f3;
     }
   }
+
+  .el-color-picker__empty {
+    display: none;
+  }
 }
 </style>

+ 39 - 2
src/views/book/courseware/create/components/question/dialogue_article/Article.vue

@@ -146,7 +146,7 @@
             <a size="medium" @click="compareTime('文字')">校对文字字幕时间</a>
           </template>
           <template v-else>
-            <a v-if="!isWordTime" size="medium" @click="createWordTime">自动生成字幕节点</a>
+            <a v-if="!isWordTime" size="medium" @click="createWordTimes">自动生成字幕节点</a>
             <p v-else>字幕节点生成中...请等待</p>
           </template>
           <el-button @click="handleMultilingual">课文多语言</el-button>
@@ -298,7 +298,14 @@ import Notes from '../article/Notes.vue';
 
 import { getArticleData } from '@/views/book/courseware/data/dialogueArticle';
 import { fileUpload } from '@/api/app';
-import { segSentences, BatchSegContent, getWordTime, prepareTranscribe, fileToBase64Text } from '@/api/article';
+import {
+  segSentences,
+  BatchSegContent,
+  getWordTime,
+  prepareTranscribe,
+  fileToBase64Text,
+  getWordTimes,
+} from '@/api/article';
 const Base64 = require('js-base64').Base64;
 import cnchar from 'cnchar';
 
@@ -727,6 +734,36 @@ export default {
       this.isWordTime = false;
       this.data.wordTime = [];
     },
+    createWordTimes() {
+      let _this = this;
+
+      if (_this.data.mp3_list && _this.data.mp3_list.length > 0 && _this.data.mp3_list[0].file_id) {
+        let verseList = [];
+        let text = '';
+        _this.data.detail.forEach((item) => {
+          if (item.type === 'text') {
+            verseList = verseList.concat(item.sentences);
+            text += item.sentences;
+          }
+        });
+        if (verseList.length > 0) {
+          _this.isWordTime = true;
+          let data = {
+            audio_file_id: _this.data.mp3_list[0].file_id,
+            text: text,
+          };
+          getWordTimes(data).then((res) => {
+            _this.data.wordTime = res.data.result;
+            _this.isWordTime = false;
+          });
+        } else {
+          this.$message.warning('请先生成分词');
+        }
+      } else {
+        _this.$message.warning('请先上传音频');
+        _this.loading = false;
+      }
+    },
     createWordTime() {
       let _this = this;
       this.getfillLiu().then(() => {

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

@@ -155,6 +155,7 @@ export default {
         top: 0,
       },
       selectedInfo: null,
+      selectHandleInfo: null,
     };
   },
   watch: {
@@ -443,7 +444,14 @@ export default {
 
         const selectedText = selection.toString().trim();
         const range = selection.getRangeAt(0);
-        console.info(selectedText, range);
+        this.selectedInfo = {
+          text: selectedText,
+          range,
+        };
+        let selectHandleInfo = this.getSelectionInfo();
+        if (!selectHandleInfo || !selectHandleInfo.text) return;
+        this.selectHandleInfo = selectHandleInfo;
+
         this.showToolbar = true;
         const container = document.querySelector('.courserware');
         const boxRect = container.getBoundingClientRect();
@@ -452,21 +460,15 @@ export default {
           left: `${Math.round(selectRect.left - boxRect.left + selectRect.width / 2 - 63)}px`,
           top: `${Math.round(selectRect.top - boxRect.top + selectRect.height)}px`, // 向上偏移10px
         };
-
-        this.selectedInfo = {
-          text: selectedText,
-          range,
-        };
       }, 100);
     },
     // 笔记
     setNote() {
       this.showToolbar = false;
       this.oldRichData = {};
-      let info = this.getSelectionInfo();
+      let info = this.selectHandleInfo;
       if (!info) return;
       info.coursewareId = this.courseware_id;
-
       this.$emit('editNote', info);
       this.selectedInfo = null;
     },
@@ -474,7 +476,7 @@ export default {
     setCollect() {
       this.showToolbar = false;
 
-      let info = this.getSelectionInfo();
+      let info = this.selectHandleInfo;
       if (!info) return;
       info.coursewareId = this.courseware_id;
 
@@ -485,6 +487,7 @@ export default {
     handLocation(item) {
       this.scrollToDataId(item.blockId);
     },
+
     getSelectionInfo() {
       if (!this.selectedInfo) return;
       const range = this.selectedInfo.range;

+ 3 - 0
src/views/book/courseware/preview/components/article/index.vue

@@ -585,6 +585,9 @@ export default {
               words,
               config: {
                 fontFamily: wItem.fontFamily,
+                color: wItem.color,
+                textDecoration: wItem.textDecoration,
+                borderBottom: wItem.border,
               },
             };
             sentArr.push(obj);