zq 2 недель назад
Родитель
Сommit
6609bba759

+ 19 - 0
src/components/CommonPreview.vue

@@ -590,6 +590,25 @@ export default {
         }
 
         if (component_list) this.component_list = component_list;
+        this.component_list.forEach((x) => {
+          if (x.component_type === 'audio') {
+            let _c = JSON.parse(x.content);
+            let p = _c.property || {};
+            if (!p.file_name_display_mode) p.file_name_display_mode = 'true';
+            if (p.view_method === 'independent' && !p.style_mode) {
+              p.style_mode = 'middle';
+            }
+            if (!p.style_mode) p.style_mode = 'big';
+            if (p.view_method === 'icon') {
+              p.file_name_display_mode = 'false';
+              p.view_method = 'independent';
+              p.style_mode = 'small';
+            }
+
+            x.content = JSON.stringify(_c);
+          }
+        });
+
         if (content_group_row_list) this.content_group_row_list = JSON.parse(content_group_row_list) || [];
       });
     },

+ 33 - 4
src/views/book/courseware/create/components/base/audio/AudioSetting.vue

@@ -1,14 +1,37 @@
 <template>
   <div>
-    <el-form :model="property" :label-position="labelPosition" label-width="72px">
+    <el-form :model="property" :label-position="labelPosition" label-width="90px">
       <SerailNumber :property="property" />
 
+      <el-form-item label="文件名称">
+        <el-radio
+          v-for="{ value, label } in displayList"
+          :key="value"
+          v-model="property.file_name_display_mode"
+          :label="value"
+        >
+          {{ label }}
+        </el-radio>
+      </el-form-item>
+
       <el-form-item label="查看方式">
         <el-radio
           v-for="{ value, label } in audioViewMethodList"
           :key="value"
           v-model="property.view_method"
           :label="value"
+          @change="viewMethodChange"
+        >
+          {{ label }}
+        </el-radio>
+      </el-form-item>
+
+      <el-form-item v-if="property.view_method == 'independent'" label="播放器样式">
+        <el-radio
+          v-for="{ value, label } in audioViewStyleList"
+          :key="value"
+          v-model="property.style_mode"
+          :label="value"
         >
           {{ label }}
         </el-radio>
@@ -20,19 +43,25 @@
 <script>
 import SettingMixin from '@/views/book/courseware/create/components/common/SettingMixin';
 
-import { audioViewMethodList, getAudioProperty } from '@/views/book/courseware/data/audio';
-
+import { audioViewMethodList, getAudioProperty, audioViewStyleList } from '@/views/book/courseware/data/audio';
+import { displayList } from '@/views/book/courseware/data/common';
 export default {
   name: 'AudioSetting',
   mixins: [SettingMixin],
   data() {
     return {
       audioViewMethodList,
+      displayList,
+      audioViewStyleList,
       labelPosition: 'left',
       property: getAudioProperty(),
     };
   },
-  methods: {},
+  methods: {
+    viewMethodChange(val) {
+      if (val === 'list') this.property.style_mode = 'big';
+    },
+  },
 };
 </script>
 

+ 15 - 1
src/views/book/courseware/create/components/common/ModuleMixin.js

@@ -102,7 +102,21 @@ const mixin = {
 
       ContentGetCoursewareComponentContent({ courseware_id: coursewareID, component_id }).then(({ content }) => {
         if (content) {
-          this.data = JSON.parse(content);
+          let oldData = JSON.parse(content);
+          if (oldData.type === 'audio') {
+            let p = oldData.property || {};
+            if (!p.file_name_display_mode) p.file_name_display_mode = 'true';
+            if (p.view_method === 'independent' && !p.style_mode) {
+              p.style_mode = 'middle';
+            }
+            if (!p.style_mode) p.style_mode = 'big';
+            if (p.view_method === 'icon') {
+              p.file_name_display_mode = 'false';
+              p.view_method = 'independent';
+              p.style_mode = 'small';
+            }
+          }
+          this.data = oldData;
         } else {
           const bookUnifiedAttr = this.getBookUnifiedAttr();
 

+ 7 - 1
src/views/book/courseware/data/audio.js

@@ -4,7 +4,11 @@ import { serialNumberTypeList, serialNumberPositionList, displayList } from '@/v
 export const audioViewMethodList = [
   { value: 'independent', label: '独立' },
   { value: 'list', label: '列表' },
-  { value: 'icon', label: '图标' },
+];
+export const audioViewStyleList = [
+  { value: 'big', label: '大' },
+  { value: 'middle', label: '中' },
+  { value: 'small', label: '小' },
 ];
 
 export function getAudioProperty() {
@@ -14,6 +18,8 @@ export function getAudioProperty() {
     sn_position: serialNumberPositionList[3].value,
     sn_display_mode: displayList[1].value,
     view_method: audioViewMethodList[0].value,
+    file_name_display_mode: displayList[0].value,
+    style_mode: audioViewStyleList[0].value,
   };
 }
 

+ 35 - 8
src/views/book/courseware/preview/components/audio/AudioPreview.vue

@@ -3,21 +3,44 @@
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
 
     <div ref="audioAreaBox" class="main">
-      <ul v-if="'independent' === data.property.view_method" class="view-independent">
+      <div v-if="'independent' === data.property.view_method">
+        <ul v-if="data.property.style_mode == 'big'" class="view-list">
+          <li v-for="(file, i) in data.file_list" :key="i">
+            <AudioPlay
+              :view-size="data.property.style_mode"
+              :view-method="data.property.view_method"
+              :file-id="file.file_id"
+              :file-name-display="data.property.file_name_display_mode"
+              :file-name="file.file_name.slice(0, file.file_name.lastIndexOf('.'))"
+              :audio-index="i"
+              :topic-color="data.unified_attrib?.topic_color"
+            />
+          </li>
+        </ul>
+        <ul v-else class="view-independent">
+          <li v-for="(file, i) in data.file_list" :key="i">
+            <AudioPlay
+              :view-size="data.property.style_mode"
+              :view-method="data.property.view_method"
+              :file-id="file.file_id"
+              :file-name-display="data.property.file_name_display_mode"
+              :file-name="file.file_name.slice(0, file.file_name.lastIndexOf('.'))"
+              :audio-index="i"
+              :topic-color="data.unified_attrib?.topic_color"
+            />
+          </li>
+        </ul>
+      </div>
+      <ul v-else-if="'icon' === data.property.view_method" class="view-icon">
         <li v-for="(file, i) in data.file_list" :key="i">
           <AudioPlay
-            view-size="middle"
+            view-size="small"
             :file-id="file.file_id"
-            :file-name="file.file_name.slice(0, file.file_name.lastIndexOf('.'))"
             :audio-index="i"
+            :topic-color="data.unified_attrib?.topic_color"
           />
         </li>
       </ul>
-      <ul v-else-if="'icon' === data.property.view_method" class="view-icon">
-        <li v-for="(file, i) in data.file_list" :key="i">
-          <AudioPlay view-size="small" :file-id="file.file_id" :audio-index="i" />
-        </li>
-      </ul>
       <div v-else class="view-list">
         <el-carousel
           ref="audio_carousel"
@@ -29,10 +52,13 @@
           <el-carousel-item v-for="(file, i) in data.file_list" :key="i">
             <AudioPlay
               view-size="big"
+              :view-method="data.property.view_method"
               :file-id="file.file_id"
+              :file-name-display="data.property.file_name_display_mode"
               :file-name="file.file_name.slice(0, file.file_name.lastIndexOf('.'))"
               :show-slider="true"
               :cur-audio-index="curAudioIndex"
+              :topic-color="data.unified_attrib?.topic_color"
               @changeFile="changeFile"
             />
           </el-carousel-item>
@@ -47,6 +73,7 @@
                 :show-slider="false"
                 :audio-index="i"
                 :cur-audio-index="curAudioIndex"
+                :topic-color="data.unified_attrib?.topic_color"
               />
             </li>
           </ul>

+ 62 - 20
src/views/book/courseware/preview/components/common/AudioPlay.vue

@@ -1,25 +1,42 @@
 <template>
   <div class="audio-wrapper">
     <div v-if="'big' === viewSize" class="audio-big">
-      <div class="audio-name">{{ audioIndex + 1 }}. {{ fileName }}</div>
-      <div v-if="showSlider" class="slider-area">
-        <span class="audio-time">{{ secondFormatConversion(audio.current_time) }}</span>
-        <el-slider
-          v-model="play_value"
-          class="audio-slider"
-          :format-tooltip="formatProcessToolTip"
-          @change="changeCurrentTime"
-        />
-        <span class="audio-time">{{ audio_allTime }}</span>
+      <div v-if="'list' === viewMethod">
+        <div v-if="fileNameDisplay == 'true'" class="audio-name">{{ curAudioIndex + 1 }}. {{ fileName }}</div>
+        <div v-if="showSlider" class="slider-area">
+          <span class="audio-time">{{ secondFormatConversion(audio.current_time) }}</span>
+          <el-slider
+            v-model="play_value"
+            class="audio-slider"
+            :format-tooltip="formatProcessToolTip"
+            @change="changeCurrentTime"
+          />
+          <span class="audio-time">{{ audio_allTime }}</span>
+        </div>
+        <div class="audio-icon">
+          <SvgIcon icon-class="pre" size="12" :color="topicColor" @click="changeFile('prev')" />
+          <SvgIcon :icon-class="iconClass" size="26" @click="playAudio" />
+          <SvgIcon icon-class="next" size="12" :color="topicColor" @click="changeFile('next')" />
+        </div>
       </div>
-      <div class="audio-icon">
-        <SvgIcon icon-class="pre" size="12" @click="changeFile('prev')" />
-        <SvgIcon :icon-class="iconClass" size="26" @click="playAudio" />
-        <SvgIcon icon-class="next" size="12" @click="changeFile('next')" />
+      <div v-else class="independent-big">
+        <div v-if="fileNameDisplay == 'true'" class="audio-name">{{ audioIndex + 1 }}. {{ fileName }}</div>
+        <div class="slider-area">
+          <SvgIcon :icon-class="iconClass" size="18" :color="topicColor" @click="playAudio" />
+          <span class="audio-time">{{ secondFormatConversion(audio.current_time) }}</span>
+          <el-slider
+            v-model="play_value"
+            class="audio-slider"
+            :format-tooltip="formatProcessToolTip"
+            :style="{ '--slider-color': topicColor }"
+            @change="changeCurrentTime"
+          />
+          <span class="audio-time">{{ audio_allTime }}</span>
+        </div>
       </div>
     </div>
     <div v-else-if="'middle' === viewSize" class="audio-middle">
-      <div class="audio-name">{{ audioIndex + 1 }}. {{ fileName }}</div>
+      <div v-if="fileNameDisplay == 'true'" class="audio-name">{{ audioIndex + 1 }}. {{ fileName }}</div>
       <div class="slider-area">
         <SvgIcon :icon-class="iconClass" size="18" @click="playAudio" />
         <span class="audio-time">{{ secondFormatConversion(audio.current_time) }}</span>
@@ -33,7 +50,7 @@
       </div>
     </div>
     <div v-else-if="'small' === viewSize" class="audio-icons">
-      <span>{{ audioIndex + 1 }}.</span>
+      <div v-if="fileNameDisplay == 'true'" class="audio-name">{{ audioIndex + 1 }}. {{ fileName }}</div>
       <span class="icon-box">
         <SvgIcon
           :icon-class="iconClass"
@@ -66,7 +83,6 @@
 <script>
 import { GetFileURLMap } from '@/api/app';
 import { secondFormatConversion } from '@/utils/transform';
-
 export default {
   name: 'AudioPlay',
   props: {
@@ -80,7 +96,7 @@ export default {
     },
     viewSize: {
       type: String,
-      required: true,
+      default: 'big',
     },
     viewMethod: {
       type: String,
@@ -103,6 +119,14 @@ export default {
       type: Boolean,
       default: true,
     },
+    fileNameDisplay: {
+      type: String,
+      default: 'true',
+    },
+    topicColor: {
+      type: String,
+      default: '#076aff',
+    },
   },
   data() {
     return {
@@ -151,6 +175,9 @@ export default {
     });
   },
   methods: {
+    getCurTime(curTime) {
+      this.curTime = curTime * 1000;
+    },
     playAudio() {
       if (!this.url) return;
       const audio = this.$refs[this.fileId];
@@ -251,6 +278,12 @@ export default {
     }
   }
 
+  .independent-big {
+    .audio-name {
+      text-align: left;
+    }
+  }
+
   .audio-middle {
     width: 280px;
     padding: 12px 16px;
@@ -270,9 +303,19 @@ export default {
 
   .audio-icons {
     display: flex;
+    flex-direction: column;
     column-gap: 10px;
     align-items: center;
 
+    .audio-name {
+      padding: 8px;
+      margin-bottom: 8px;
+      font-size: 14px;
+      text-align: center;
+      background-color: #eee;
+      border-radius: 4px;
+    }
+
     .icon-box {
       display: flex;
       align-items: center;
@@ -325,7 +368,6 @@ export default {
 
       :deep .el-slider__runway {
         height: 4px;
-        background-color: #fff;
       }
 
       :deep .el-slider__button {
@@ -337,7 +379,7 @@ export default {
 
       :deep .el-slider__bar {
         height: 4px;
-        background-color: #076aff;
+        background-color: var(--slider-color, #076aff);
       }
     }
   }

+ 17 - 1
src/views/book/courseware/preview/components/common/PreviewMixin.js

@@ -73,7 +73,23 @@ const mixin = {
     getCoursewareComponentContent() {
       ContentGetCoursewareComponentContent({ courseware_id: this.coursewareId, component_id: this.id }).then(
         ({ content }) => {
-          if (content) this.data = JSON.parse(content);
+          if (content) {
+            let oldData = JSON.parse(content);
+            if (oldData.type === 'audio') {
+              let p = oldData.property || {};
+              if (!p.file_name_display_mode) p.file_name_display_mode = 'true';
+              if (p.view_method === 'independent' && !p.style_mode) {
+                p.style_mode = 'middle';
+              }
+              if (!p.style_mode) p.style_mode = 'big';
+              if (p.view_method === 'icon') {
+                p.file_name_display_mode = 'false';
+                p.view_method = 'independent';
+                p.style_mode = 'small';
+              }
+            }
+            this.data = oldData;
+          }
           this.loader = true;
         },
       );

+ 19 - 0
src/views/personal_workbench/edit_task/edit/UseTemplate.vue

@@ -169,6 +169,25 @@ export default {
         }
 
         if (component_list) this.component_list = component_list;
+        this.component_list.forEach((x) => {
+          if (x.component_type === 'audio') {
+            let _c = JSON.parse(x.content);
+            let p = _c.property || {};
+            if (!p.file_name_display_mode) p.file_name_display_mode = 'true';
+            if (p.view_method === 'independent' && !p.style_mode) {
+              p.style_mode = 'middle';
+            }
+            if (!p.style_mode) p.style_mode = 'big';
+            if (p.view_method === 'icon') {
+              p.file_name_display_mode = 'false';
+              p.view_method = 'independent';
+              p.style_mode = 'small';
+            }
+
+            x.content = JSON.stringify(_c);
+          }
+        });
+
         if (content_group_row_list) this.content_group_row_list = JSON.parse(content_group_row_list) || [];
       });
     },

+ 18 - 0
src/views/personal_workbench/template_list/preview/CommonPreview.vue

@@ -157,6 +157,24 @@ export default {
         }
 
         if (component_list) this.component_list = component_list;
+        this.component_list.forEach((x) => {
+          if (x.component_type === 'audio') {
+            let _c = JSON.parse(x.content);
+            let p = _c.property || {};
+            if (!p.file_name_display_mode) p.file_name_display_mode = 'true';
+            if (p.view_method === 'independent' && !p.style_mode) {
+              p.style_mode = 'middle';
+            }
+            if (!p.style_mode) p.style_mode = 'big';
+            if (p.view_method === 'icon') {
+              p.file_name_display_mode = 'false';
+              p.view_method = 'independent';
+              p.style_mode = 'small';
+            }
+
+            x.content = JSON.stringify(_c);
+          }
+        });
         if (content_group_row_list) this.content_group_row_list = JSON.parse(content_group_row_list) || [];
       });
     },