ソースを参照

音频打点可以传一维数组

dsy 6 ヶ月 前
コミット
da71c34fe2

+ 1 - 1
src/components/CommonPreview.vue

@@ -147,7 +147,7 @@
 import CoursewarePreview from '@/views/book/courseware/preview/CoursewarePreview.vue';
 import MenuPopover from '@/views/personal_workbench/common/MenuPopover.vue';
 import RichText from '@/components/RichText.vue';
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 import MindMap from '@/components/MindMap.vue';
 import VideoPlay from '@/views/book/courseware/preview/components/common/VideoPlay.vue';
 import AudioPlay from '@/views/book/courseware/preview/components/common/AudioPlay.vue';

+ 12 - 9
src/utils/common.js

@@ -86,15 +86,6 @@ export function handleToneValue(valItem) {
   return numList.length === 0 ? [{ con: valItem }] : numList;
 }
 
-/**
- * @description 是否为 true
- * @param {'true'|'false'} value
- * @returns {boolean}
- */
-export function isTrue(value) {
-  return value === 'true';
-}
-
 // 全屏方法兼容
 export function fullScreenCompatibility(dom) {
   if (dom.requestFullscreen) {
@@ -133,3 +124,15 @@ export function toggleFullScreen(dom) {
     exitFullScreenCompatibility();
   }
 }
+
+/**
+ * @description 计算数组的深度
+ * @param {Array} arr 需要计算深度的数组
+ * @returns {Number} 数组的深度
+ */
+export function getArrayDepth(arr) {
+  if (!Array.isArray(arr)) return 0;
+  if (arr.length === 0) return 1;
+
+  return 1 + Math.max(...arr.map((item) => (Array.isArray(item) ? getArrayDepth(item) : 0)));
+}

+ 5 - 5
src/utils/index.js

@@ -1,8 +1,8 @@
 /**
  * 生成指定位随机数的函数
- * @param {number} length 随机数的位数
- * @param {boolean} isUpperCase 是否大写
- * @returns {string} 随机36进制数
+ * @param {Number} length 随机数的位数
+ * @param {Boolean} isUpperCase 是否大写
+ * @returns {String} 随机36进制数
  */
 export function getRandomNumber(length = 8, isUpperCase = false) {
   let randomNumber = Math.random()
@@ -16,8 +16,8 @@ export function getRandomNumber(length = 8, isUpperCase = false) {
 
 /**
  * 下载文件
- * @param {string} url 文件地址
- * @param {string} downloadName 文件名称
+ * @param {String} url 文件地址
+ * @param {String} downloadName 文件名称
  */
 export function downloadFile(url, downloadName) {
   const a = document.createElement('a');

+ 1 - 1
src/utils/transform.js

@@ -7,7 +7,7 @@ export function zeroFill(val) {
  * 将秒转为时:分:秒格式
  * @param {Number|String} val 秒
  * @param {'normal'|'chinese'} type 格式类型
- * @returns {string} 'normal' hh:MM:ss 小于1小时返回 MM:ss 'chinese' h时m分s秒
+ * @returns {String} 'normal' hh:MM:ss 小于1小时返回 MM:ss 'chinese' h时m分s秒
  */
 export function secondFormatConversion(val = 0, type = 'normal') {
   const seconds = parseInt(val); // 输入的秒数

+ 11 - 2
src/utils/validate.js

@@ -8,9 +8,18 @@ export function isExternal(path) {
 }
 
 /**
+ * @description 是否为 true
+ * @param {'true'|'false'} value
+ * @returns {Boolean}
+ */
+export function isTrue(value) {
+  return value === 'true';
+}
+
+/**
  * @description 只允许输入两位小数
- * @param {string} value
- * @returns {number}
+ * @param {String} value
+ * @returns {Number}
  */
 export function twoDecimal(value) {
   if (!value) {

+ 11 - 1
src/views/book/courseware/create/components/question/fill/Fill.vue

@@ -9,6 +9,15 @@
           toolbar="fontselect fontsizeselect forecolor backcolor | underline | bold italic strikethrough alignleft aligncenter alignright"
           :wordlimit-num="false"
         />
+        <el-input
+          v-if="data.property.fill_type === fillTypeList[1].value"
+          v-model="data.vocabulary"
+          type="textarea"
+          :autosize="{ minRows: 2, maxRows: 4 }"
+          resize="none"
+          placeholder="请输入词汇,用于选词填空"
+        />
+
         <span class="tips">在需要加空的内容处插入 3 个或以上的下划线“_”。</span>
         <div v-if="data.audio_file_id">
           <SoundRecord :wav-blob.sync="data.audio_file_id" />
@@ -51,7 +60,7 @@ import ModuleMixin from '../../common/ModuleMixin';
 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 { getFillData, arrangeTypeList, fillFontList } from '@/views/book/courseware/data/fill';
+import { getFillData, arrangeTypeList, fillFontList, fillTypeList } from '@/views/book/courseware/data/fill';
 import { addTone, handleToneValue } from '@/views/book/courseware/data/common';
 import { getRandomNumber } from '@/utils';
 import { GetStaticResources } from '@/api/app';
@@ -66,6 +75,7 @@ export default {
   data() {
     return {
       data: getFillData(),
+      fillTypeList,
     };
   },
   watch: {

+ 7 - 2
src/views/book/courseware/create/components/question/voice_matrix/CheckSubtitles.vue

@@ -10,6 +10,7 @@
             <div class="lrc-time">
               <span>[{{ audioTimeToMMSS(lrc_data.begin_time) }}]</span>
             </div>
+            <!-- eslint-disable-next-line vue/no-v-html -->
             <span class="lrc-text" v-html="content"></span>
           </div>
         </template>
@@ -53,6 +54,7 @@
 <script>
 import { GetFileURLMap } from '@/api/app';
 import { secondFormatConversion, audioTimeToMMSS } from '@/utils/transform';
+import { getArrayDepth } from '@/utils/common';
 
 export default {
   name: 'CheckSubtitles',
@@ -92,6 +94,7 @@ export default {
       audio_allTime: null, // 展示总时间
       secondFormatConversion,
       audioTimeToMMSS,
+      getArrayDepth,
     };
   },
   computed: {
@@ -118,7 +121,8 @@ export default {
     },
     optionList: {
       handler(val) {
-        this.dataList = JSON.parse(JSON.stringify(val));
+        let _val = JSON.parse(JSON.stringify(val));
+        this.dataList = this.getArrayDepth(_val) === 1 ? [_val] : _val;
       },
       immediate: true,
       deep: true,
@@ -244,7 +248,8 @@ export default {
       this.audio.paused = false;
     },
     saveSubtitles() {
-      this.$emit('saveSubtitles', this.dataList);
+      const subtitles = this.getArrayDepth(this.optionList) === 1 ? this.dataList.flat() : this.dataList;
+      this.$emit('saveSubtitles', subtitles);
       this.$message.success('字幕已保存');
     },
   },

+ 2 - 0
src/views/book/courseware/data/fill.js

@@ -69,8 +69,10 @@ export function getFillData() {
     audio_file_id: '',
     record_list: [],
     model_essay: [],
+    vocabulary: '', // 用于选词的词汇
     answer: {
       answer_list: [],
+      reference_answer: '',
     },
     mind_map: {
       node_list: [{ name: '横排中文填空组件' }],

+ 5 - 1
src/views/book/courseware/data/voiceMatrix.js

@@ -33,7 +33,11 @@ export function getOption() {
   return {
     content: '',
     mark: getRandomNumber(),
-    lrc_data: {}, // lrc 数据
+    lrc_data: {
+      begin_time: 0,
+      end_time: 0,
+      text: '',
+    },
   };
 }
 

+ 2 - 0
src/views/book/courseware/preview/common/SoundRecord.vue

@@ -17,6 +17,7 @@
         @click="playmicrophone(selectIndex || selectIndex == 0 ? recordList[selectIndex].toltime : '')"
       ></div>
     </template>
+
     <template v-else-if="type === 'pro'">
       <div :class="['record', microphoneStatus ? 'active' : '']" @click="microphone"></div>
       <el-select v-model="selectIndex" placeholder="无录音" class="proSelect" @change="handleChangeRecord">
@@ -28,6 +29,7 @@
       ></div>
       <a :class="['record-delete', hasMicro ? 'record-delete-has' : '']" @click="handleDelete"></a>
     </template>
+
     <template v-else>
       <div :class="['record', microphoneStatus ? 'active' : '']" @click="microphone"></div>
       <span

+ 21 - 2
src/views/book/courseware/preview/components/fill/FillPreview.vue

@@ -21,8 +21,15 @@
               </template>
 
               <template v-else-if="data.property.fill_type === fillTypeList[1].value">
-                <el-popover :key="j" placement="top" trigger="click" content="">
+                <el-popover :key="j" placement="top" trigger="click">
+                  <div class="word-list">
+                    <span v-for="(word, index) in wordList" :key="index" class="word-item" @click="li.content = word">
+                      {{ word }}
+                    </span>
+                  </div>
+
                   <el-input
+                    slot="reference"
                     v-model="li.content"
                     :disabled="true"
                     :class="[data.property.fill_font, ...computedAnswerClass(li.mark)]"
@@ -35,7 +42,8 @@
               <template v-else-if="data.property.fill_type === fillTypeList[2].value"></template>
 
               <template v-else-if="data.property.fill_type === fillTypeList[3].value">
-                <SoundRecord :key="j" :wav-blob.sync="li.audio_file_id" />
+                <!-- TODO -->
+                <!-- <SoundRecord :key="j" :wav-blob.sync="li.audio_file_id" /> -->
               </template>
               <span v-show="computedAnswerText(li.mark).length > 0" :key="`answer-${j}`" class="right-answer">
                 {{ computedAnswerText(li.mark) }}
@@ -81,6 +89,7 @@ export default {
     return {
       data: getFillData(),
       fillTypeList,
+      wordList: [],
     };
   },
   computed: {
@@ -109,6 +118,16 @@ export default {
       },
       deep: true,
     },
+    'data.vocabulary': {
+      handler(val) {
+        if (!val) return;
+        this.wordList = val
+          .split(/[\n\r]+/)
+          .map((item) => item.split(' ').filter((s) => s))
+          .flat();
+      },
+      immediate: true,
+    },
     isJudgingRightWrong(val) {
       if (!val) return;
 

+ 1 - 1
src/views/personal_workbench/check_task/audit/index.vue

@@ -36,7 +36,7 @@
 import MenuPage from '@/views/personal_workbench/common/menu.vue';
 import CommonPreview from '@/components/CommonPreview.vue';
 
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 import { FinishCoursewareCurFlowNodeAudit } from '@/api/project';
 
 export default {

+ 1 - 1
src/views/personal_workbench/common/MenuPopover.vue

@@ -24,7 +24,7 @@
 </template>
 
 <script>
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 
 export default {
   name: 'MenuPopover',

+ 1 - 1
src/views/personal_workbench/edit_task/preview/index.vue

@@ -19,7 +19,7 @@ import MenuPage from '@/views/personal_workbench/common/menu.vue';
 import CommonPreview from '@/components/CommonPreview.vue';
 
 import { SubmitBookCoursewareToAuditFlow } from '@/api/project';
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 
 export default {
   name: 'TaskPreviewPage',

+ 8 - 8
src/views/personal_workbench/project/components/MenuTree.vue

@@ -1,7 +1,7 @@
 <template>
   <div class="menu-list">
     <el-tree highlight-current :data="nodeList" :props="defaultProps" @node-click="handleNodeClick">
-      <div class="custom-tree-node" slot-scope="{ node }">
+      <div slot-scope="{ node }" class="custom-tree-node">
         <div
           :class="[
             'tree-box-item',
@@ -17,7 +17,7 @@
 </template>
 
 <script>
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 
 export default {
   name: 'MenuTree',
@@ -35,12 +35,6 @@ export default {
       default: '',
     },
   },
-  watch: {
-    nodeList: {
-      handler(val) {},
-      immediate: true,
-    },
-  },
   data() {
     return {
       isTrue,
@@ -58,6 +52,12 @@ export default {
       },
     };
   },
+  watch: {
+    nodeList: {
+      handler(val) {},
+      immediate: true,
+    },
+  },
   created() {},
   methods: {
     /**

+ 1 - 1
src/views/project_manage/book/BookPreview.vue

@@ -16,7 +16,7 @@
 import MenuPage from '@/views/personal_workbench/common/menu.vue';
 import CommonPreview from '@/components/CommonPreview.vue';
 
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 
 export default {
   name: 'BookPreview',

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

@@ -42,7 +42,7 @@ import PaginationPage from '@/components/PaginationPage.vue';
 import MenuPage from '@/views/personal_workbench/common/menu.vue';
 
 import { PageQueryMyProjectYSJBookList_Leader } from '@/api/list';
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 
 export default {
   name: 'BookPage',

+ 1 - 1
src/views/project_manage/org/book/OrgBookPreview.vue

@@ -22,7 +22,7 @@
 import ProjectMenu from '@/views/project_manage/common/ProjectMenu.vue';
 import CommonPreview from '@/components/CommonPreview.vue';
 
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 
 export default {
   name: 'OrgBookPreview',

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

@@ -42,7 +42,7 @@ import ProjectMenu from '@/views/project_manage/common/ProjectMenu.vue';
 import PaginationPage from '@/components/PaginationPage.vue';
 
 import { PageQueryYSJBookList_OrgManager } from '@/api/list';
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 
 export default {
   name: 'OrgBookPage',

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

@@ -35,7 +35,7 @@ import ProjectMenu from '@/views/project_manage/common/ProjectMenu.vue';
 import CommonPreview from '@/components/CommonPreview.vue';
 import ConfirmBookInfo from './components/ConfirmBookInfo.vue';
 
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 import { ShangjiaBook, RollbackProject, RejectShangjiaBookRequest, RejectRollbackProjectRequest } from '@/api/project';
 
 export default {

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

@@ -39,7 +39,7 @@ import PaginationPage from '@/components/PaginationPage.vue';
 import ProjectMenu from '@/views/project_manage/common/ProjectMenu.vue';
 
 import { PageQueryProjectList_OrgManager } from '@/api/list';
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 
 export default {
   name: 'OrgProjectPage',

+ 1 - 1
src/views/project_manage/project/ProjectPreview.vue

@@ -23,7 +23,7 @@ import MenuPage from '@/views/personal_workbench/common/menu.vue';
 import CommonPreview from '@/components/CommonPreview.vue';
 import RequestBook from './components/RequestBook.vue';
 
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 import { RequestShangjiaBook, RequestRollbackProject } from '@/api/project';
 
 export default {

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

@@ -43,7 +43,7 @@ import PaginationPage from '@/components/PaginationPage.vue';
 import MenuPage from '@/views/personal_workbench/common/menu.vue';
 
 import { PageQueryMyProjectList_Leader } from '@/api/list';
-import { isTrue } from '@/utils/common';
+import { isTrue } from '@/utils/validate';
 
 export default {
   name: 'ProjectManage',