浏览代码

Merge branch 'master' into lhd

natasha 2 周之前
父节点
当前提交
5165754e8d
共有 20 个文件被更改,包括 258 次插入198 次删除
  1. 二进制
      src/assets/preview-bg.png
  2. 二进制
      src/assets/voice_matrix/pauseC-16-normal-blue copy.png
  3. 19 24
      src/components/CommonPreview.vue
  4. 6 0
      src/styles/common.scss
  5. 1 1
      src/styles/mixin.scss
  6. 8 2
      src/styles/variables.scss
  7. 5 4
      src/views/book/courseware/preview/CoursewarePreview.vue
  8. 31 5
      src/views/book/courseware/preview/common/SoundRecord.vue
  9. 46 46
      src/views/book/courseware/preview/components/character/CharacterPreview.vue
  10. 1 2
      src/views/book/courseware/preview/components/character_base/CharacterBasePreview.vue
  11. 7 1
      src/views/book/courseware/preview/components/fill/FillPreview.vue
  12. 21 8
      src/views/book/courseware/preview/components/fill/components/AudioFillPlay.vue
  13. 6 1
      src/views/book/courseware/preview/components/judge/JudgePreview.vue
  14. 2 1
      src/views/book/courseware/preview/components/matching/MatchingPreview.vue
  15. 57 57
      src/views/book/courseware/preview/components/newWord_template/NewWordTemplatePreview.vue
  16. 2 1
      src/views/book/courseware/preview/components/select/SelectPreview.vue
  17. 4 0
      src/views/book/courseware/preview/components/voice_matrix/VoiceMatrixPreview.vue
  18. 16 5
      src/views/book/courseware/preview/components/voice_matrix/components/AudioCompareMatrix.vue
  19. 17 12
      src/views/book/courseware/preview/components/voice_matrix/components/AudioLine.vue
  20. 9 28
      src/views/book/courseware/preview/components/voice_matrix/components/AudioRed.vue

二进制
src/assets/preview-bg.png


二进制
src/assets/voice_matrix/pauseC-16-normal-blue copy.png


+ 19 - 24
src/components/CommonPreview.vue

@@ -28,10 +28,7 @@
     <div class="audit-content">
       <div ref="previewMain" class="main-container">
         <main :class="['preview-main', { 'no-audit': !isShowAudit }]">
-          <span class="title" :style="{ backgroundColor: unified_attrib?.topic_color }">
-            <SvgIcon icon-class="menu-2" size="24" />
-            <span>{{ courseware_info.name_path }}</span>
-          </span>
+          <div class="preview-left"></div>
           <CoursewarePreview
             v-if="courseware_info.book_name"
             ref="courserware"
@@ -47,6 +44,7 @@
             @computeScroll="computeScroll"
             @addRemark="addRemark"
           />
+          <div class="preview-right"></div>
         </main>
       </div>
       <div v-if="isShowAudit" class="remark-list">
@@ -708,39 +706,36 @@ export default {
     flex: 1;
     min-width: 1110px;
     overflow: auto;
+    background: url('@/assets/preview-bg.png') repeat;
   }
 
   main.preview-main {
     display: flex;
     flex: 1;
-    flex-direction: column;
-    row-gap: 5px;
-    width: 1100px;
-    min-width: 1100px;
+    width: calc($courseware-width + $courseware-left-margin + $courseware-right-margin);
+    min-width: calc($courseware-width + $courseware-left-margin + $courseware-right-margin);
     min-height: 100%;
-    padding: 5px;
     margin: 0 auto;
     background-color: #fff;
     border-radius: 4px;
     box-shadow: 0 2px 4px rgba(0, 0, 0, 10%);
 
-    &.no-audit {
-      margin: 0 auto;
+    .preview-left {
+      width: $courseware-left-margin;
+      min-width: $courseware-left-margin;
+      max-width: $courseware-left-margin;
+      background-color: #ecf0f1;
     }
 
-    .title {
-      display: inline-flex;
-      column-gap: 24px;
-      align-items: center;
-      width: 100%;
-      min-width: 280px;
-      height: 64px;
-      padding: 18px 24px;
-      font-size: 20px;
-      color: #fff;
-      background-color: #f44444;
-      border-top-left-radius: 12px;
-      border-top-right-radius: 16px;
+    .preview-right {
+      width: $courseware-right-margin;
+      min-width: $courseware-right-margin;
+      max-width: $courseware-right-margin;
+      background-color: #ecf0f1;
+    }
+
+    &.no-audit {
+      margin: 0 auto;
     }
   }
 

+ 6 - 0
src/styles/common.scss

@@ -54,3 +54,9 @@
     margin-left: 8px;
   }
 }
+
+.icon-mask {
+  display: inline-block;
+  mask-repeat: no-repeat;
+  mask-size: 100% 100%;
+}

+ 1 - 1
src/styles/mixin.scss

@@ -41,7 +41,7 @@
 @mixin preview-base {
   display: grid;
   gap: 6px;
-  padding: 8px;
+  padding: $border-component-spacing;
 
   :deep .rich-text {
     @include rich-text;

+ 8 - 2
src/styles/variables.scss

@@ -21,5 +21,11 @@ $label-color: #076aff;
 $setting-active-color: #4176ff;
 
 // px
-$header-h: 64px;
-$courseware-width: 1100px;
+$header-h: 64px; // 顶部内容高度
+$courseware-width: 1000px; // 教材内容宽度
+$courseware-left-margin: 100px; // 教材左页边距
+$courseware-right-margin: 100px; // 教材右页边距
+$courseware-top-margin: 65px; // 教材顶部页边距
+$courseware-bottom-margin: 65px; // 教材底部页边距
+$component-spacing: 24px; // 组件间间距
+$border-component-spacing: 10px; // 组件边框与组件内容间距

+ 5 - 4
src/views/book/courseware/preview/CoursewarePreview.vue

@@ -385,11 +385,12 @@ export default {
   position: relative;
   display: flex;
   flex-direction: column;
-  row-gap: 6px;
+  row-gap: $component-spacing;
   width: 100%;
   height: 100%;
   min-height: 500px;
-  padding: 24px;
+  margin-top: $courseware-top-margin;
+  margin-bottom: $courseware-bottom-margin;
   background-color: #fff;
   background-repeat: no-repeat;
   border-bottom-right-radius: 12px;
@@ -397,11 +398,11 @@ export default {
 
   .row {
     display: grid;
-    gap: 16px;
+    gap: $component-spacing;
 
     .col {
       display: grid;
-      gap: 16px;
+      gap: $component-spacing;
       overflow: hidden;
     }
 

+ 31 - 5
src/views/book/courseware/preview/common/SoundRecord.vue

@@ -2,7 +2,14 @@
   <div class="record">
     <template v-if="type === 'normal' || type === 'mini'">
       <div :class="['record', microphoneStatus ? 'active' : '']" @click="microphone">
-        <img src="@/assets/voice_matrix/luyin-active.png" v-if="microphoneStatus" />
+        <div
+          v-if="microphoneStatus"
+          :style="{
+            backgroundColor: attrib?.topic_color,
+            maskImage: `url(${require('@/assets/voice_matrix/luyin-active.png')})`,
+          }"
+          class="icon-mask"
+        ></div>
         <SvgIcon
           v-else
           icon-class="luyin-radio-button"
@@ -36,7 +43,14 @@
 
     <template v-else-if="type === 'pro'">
       <div :class="['record', microphoneStatus ? 'active' : '']" @click="microphone">
-        <img src="@/assets/voice_matrix/luyin-active.png" v-if="microphoneStatus" />
+        <div
+          v-if="microphoneStatus"
+          :style="{
+            backgroundColor: attrib?.topic_color,
+            maskImage: `url(${require('@/assets/voice_matrix/luyin-active.png')})`,
+          }"
+          class="icon-mask"
+        ></div>
         <SvgIcon
           v-else
           icon-class="luyin-radio-button"
@@ -57,10 +71,10 @@
       </div>
       <a
         :class="['record-delete', hasMicro ? 'record-delete-has' : '']"
-        @click="handleDelete"
         :style="{
           color: hasMicro && attrib && attrib.topic_color ? attrib.topic_color : '',
         }"
+        @click="handleDelete"
       >
         <SvgIcon icon-class="luyin-delete" size="24" />
       </a>
@@ -68,7 +82,14 @@
 
     <template v-else>
       <div :class="['record', microphoneStatus ? 'active' : '']" @click="microphone">
-        <img src="@/assets/voice_matrix/luyin-active.png" v-if="microphoneStatus" />
+        <div
+          v-if="microphoneStatus"
+          :style="{
+            backgroundColor: attrib?.topic_color,
+            maskImage: `url(${require('@/assets/voice_matrix/luyin-active.png')})`,
+          }"
+          class="icon-mask"
+        ></div>
         <SvgIcon
           v-else
           icon-class="luyin-radio-button"
@@ -101,10 +122,10 @@
       </div>
       <a
         :class="['record-delete', hasMicro ? 'record-delete-has' : '']"
-        @click="handleDelete"
         :style="{
           color: hasMicro && attrib && attrib.topic_color ? attrib.topic_color : '',
         }"
+        @click="handleDelete"
       >
         <SvgIcon icon-class="luyin-delete" size="24" />
       </a>
@@ -390,6 +411,11 @@ export default {
   max-width: 160px;
   height: 32px;
 
+  .icon-mask {
+    width: 24px;
+    height: 24px;
+  }
+
   .playBack {
     width: 20px;
     height: 20px;

+ 46 - 46
src/views/book/courseware/preview/components/character/CharacterPreview.vue

@@ -6,10 +6,10 @@
     <div class="main">
       <template v-if="data.property.model === 'write'">
         <div
-          class="item-box"
-          :class="[!item.is_margin ? 'item-box-write' : '']"
           v-for="(item, index) in data.option_list"
           :key="index"
+          class="item-box"
+          :class="[!item.is_margin ? 'item-box-write' : '']"
         >
           <div
             class="number-box"
@@ -37,7 +37,7 @@
               {{ item.pinyin }}
             </div>
             <div class="items-flex">
-              <div class="items" v-for="(items, indexs) in item.content_list" :key="indexs">
+              <div v-for="(items, indexs) in item.content_list" :key="indexs" class="items">
                 <div
                   v-if="isEnable(data.property.view_pinyin) && !item.is_common_pinyin"
                   class="pinyin"
@@ -51,11 +51,11 @@
                 <div class="items-content">
                   <template v-if="items && items.type === 'img'">
                     <el-image
-                      class="items-image"
                       v-if="items.file_list[0]"
+                      class="items-image"
                       :src="items.file_list[0].file_url"
                       fit="contain"
-                    ></el-image>
+                    />
                   </template>
                   <template v-else-if="items && items.type === 'lian'">
                     <span
@@ -70,8 +70,8 @@
                   <Strockplayredline
                     v-if="items && items.type === 'hanzi'"
                     :Book_text="items.con"
-                    :playStorkes="isEnable(data.property.is_enable_play_structure)"
-                    :curItem="
+                    :play-storkes="isEnable(data.property.is_enable_play_structure)"
+                    :cur-item="
                       isEnable(data.property.is_enable_high_strokes)
                         ? data.property.model === 'input'
                           ? items.high_strokes
@@ -79,9 +79,9 @@
                         : null
                     "
                     :type="data.property.model === 'input' ? 'newWord-template-input' : data.type"
-                    :targetDiv="'newWordTemplate-character' + items.con + index + indexs + randomId"
+                    :target-div="'newWordTemplate-character' + items.con + index + indexs + randomId"
                     :hz_json="items.hz_info[0].hzDetail.hz_json"
-                    :bgType="data.property.frame_type"
+                    :bg-type="data.property.frame_type"
                     class="hanzi-storck"
                     :class="[
                       !item.is_margin && item.content_list.length > 1 && indexs == 0 ? 'leftBorderRadius' : '',
@@ -99,7 +99,7 @@
                         ? 'NoborderRight'
                         : '',
                     ]"
-                    :playColor="
+                    :play-color="
                       data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
                     "
                     :style="{
@@ -111,6 +111,7 @@
                   />
 
                   <div
+                    v-if="items && items.type === 'write'"
                     :class="[
                       'strockplay-newWord',
                       !item.is_margin && item.content_list.length > 1 && indexs == 0 ? 'leftBorderRadius' : '',
@@ -128,7 +129,12 @@
                         ? 'NoborderRight'
                         : '',
                     ]"
-                    v-if="items && items.type === 'write'"
+                    :style="{
+                      borderColor:
+                        data.unified_attrib && data.unified_attrib.topic_color
+                          ? data.unified_attrib.topic_color
+                          : '#346cda',
+                    }"
                     @click="
                       freeWrite(
                         userAnswer[index][indexs].imgArr ? userAnswer[index][indexs].imgArr : null,
@@ -136,22 +142,16 @@
                         indexs,
                       )
                     "
-                    :style="{
-                      borderColor:
-                        data.unified_attrib && data.unified_attrib.topic_color
-                          ? data.unified_attrib.topic_color
-                          : '#346cda',
-                    }"
                   >
                     <SvgIcon
+                      v-if="data.property.frame_type === 'tian'"
                       icon-class="hanzi-writer-bg"
                       class="character-target-bg"
-                      v-if="data.property.frame_type === 'tian'"
                     />
                     <SvgIcon
+                      v-else-if="data.property.frame_type === 'mi'"
                       icon-class="mi"
                       class="character-target-bg"
-                      v-else-if="data.property.frame_type === 'mi'"
                     />
                     <img
                       v-if="
@@ -177,15 +177,15 @@
             <div class="words-top">
               <div class="words-left" :style="{}">
                 <AudioPlay
+                  v-if="isEnable(data.property.is_enable_voice)"
                   :file-id="item.audio_file_id"
                   :theme-color="
                     data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
                   "
-                  v-if="isEnable(data.property.is_enable_voice)"
                 />
                 <span
-                  class="pinyin"
                   v-if="isEnable(data.property.view_pinyin) && item.is_common_pinyin"
+                  class="pinyin"
                   :style="{
                     fontSize:
                       data.unified_attrib && data.unified_attrib.pinyin_size ? data.unified_attrib.pinyin_size : '',
@@ -203,16 +203,16 @@
                   </div> -->
                   <Strockplayredline
                     :Book_text="items.con"
-                    :playStorkes="isEnable(data.property.is_enable_stroke)"
-                    :curItem="null"
-                    :targetDiv="'newWordTemplate-character-answer' + items.con + index + indexs"
+                    :play-storkes="isEnable(data.property.is_enable_stroke)"
+                    :cur-item="null"
+                    :target-div="'newWordTemplate-character-answer' + items.con + index + indexs"
                     :hz_json="
                       items.hz_info && items.hz_info[0].hzDetail.hz_json ? items.hz_info[0].hzDetail.hz_json : []
                     "
                     class="hanzi-storck"
                     :class="['strock-chinese', 'border-right-none']"
-                    :bgType="data.property.frame_type"
-                    :playColor="
+                    :bg-type="data.property.frame_type"
+                    :play-color="
                       data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
                     "
                     :style="{
@@ -229,13 +229,13 @@
                 v-for="(itemI, indexI) in item.miao_arr"
                 :key="indexI + index"
                 style="display: flex"
-                @click="miaoStorkes(index, indexI, item.mark, item.content, itemI.strokes)"
                 :style="{
                   borderColor:
                     data.unified_attrib && data.unified_attrib.topic_color
                       ? data.unified_attrib.topic_color
                       : '#346cda',
                 }"
+                @click="miaoStorkes(index, indexI, item.mark, item.content, itemI.strokes)"
               >
                 <Strockplayredlines
                   v-if="
@@ -247,8 +247,8 @@
                   :target-div="'write-praT-1' + indexI + index + randomId"
                   :book-strokes="itemI.strokes"
                   :class="['strock-chinese']"
-                  :bgType="data.property.frame_type"
-                  :playColor="
+                  :bg-type="data.property.frame_type"
+                  :play-color="
                     data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
                   "
                   :style="{
@@ -266,8 +266,8 @@
                   :book-strokes="itemI.strokes"
                   :stroke-color="'#ddd'"
                   :class="['strock-chinese']"
-                  :bgType="data.property.frame_type"
-                  :playColor="
+                  :bg-type="data.property.frame_type"
+                  :play-color="
                     data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
                   "
                   :style="{
@@ -282,6 +282,12 @@
               <div v-for="(items, indexs) in item.imgArr" :key="'write' + indexs" class="con-box">
                 <div
                   :class="['strockplay-newWord']"
+                  :style="{
+                    borderColor:
+                      data.unified_attrib && data.unified_attrib.topic_color
+                        ? data.unified_attrib.topic_color
+                        : '#346cda',
+                  }"
                   @click="
                     freeWrite(
                       userAnswer[index].strokes_content_list[indexs].imgArr
@@ -291,19 +297,13 @@
                       indexs,
                     )
                   "
-                  :style="{
-                    borderColor:
-                      data.unified_attrib && data.unified_attrib.topic_color
-                        ? data.unified_attrib.topic_color
-                        : '#346cda',
-                  }"
                 >
                   <SvgIcon
+                    v-if="data.property.frame_type === 'tian'"
                     icon-class="hanzi-writer-bg"
                     class="character-target-bg"
-                    v-if="data.property.frame_type === 'tian'"
                   />
-                  <SvgIcon icon-class="mi" class="character-target-bg" v-else-if="data.property.frame_type === 'mi'" />
+                  <SvgIcon v-else-if="data.property.frame_type === 'mi'" icon-class="mi" class="character-target-bg" />
                   <img
                     v-if="
                       !play_status &&
@@ -318,7 +318,7 @@
                 </div>
               </div>
             </div>
-            <div class="words-bottom" v-if="item.shiyi && isEnable(data.property.is_enable_shiyi)">
+            <div v-if="item.shiyi && isEnable(data.property.is_enable_shiyi)" class="words-bottom">
               {{ item.shiyi }}
             </div>
           </div>
@@ -334,12 +334,12 @@
           :col-index="active_col_index"
           :disabled="disabled"
           :show-play="isEnable(data.property.is_enable_play_back)"
+          :bg-type="data.property.frame_type"
+          :attrib="data.unified_attrib"
           @closeIfFreeShow="closeIfFreeShow"
           @changePraShow="changePraShow"
           @changeCurQue="changeCurQue"
           @deleteWriteRecord="deleteWriteRecord"
-          :bgType="data.property.frame_type"
-          :attrib="data.unified_attrib"
         />
       </div>
       <div v-if="if_miao_show" class="practiceBox practice-box-strock">
@@ -363,8 +363,8 @@
                 ? '#ddd'
                 : ''
             "
-            :bgType="data.property.frame_type"
-            :playColor="data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''"
+            :bg-type="data.property.frame_type"
+            :play-color="data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''"
           />
           <Strockred
             ref="strockRed"
@@ -381,7 +381,7 @@
             :book-strokes="current_hz_data"
             :is-answer.sync="userAnswer[active_index].strokes_content_list[active_col_index].flag"
             :show-error-tip="isEnable(data.property.is_enable_error)"
-            :bgType="data.property.frame_type"
+            :bg-type="data.property.frame_type"
           />
           <div v-if="!disabled" :class="['reset-box']" @click="resetHanzi">
             <SvgIcon icon-class="reset" class="reset-btn" />
@@ -492,7 +492,7 @@ export default {
           let obj = {
             // mark: item.mark,
             strokes_content_list: arr,
-            miao_arr: miao_arr,
+            miao_arr,
           };
           // if (!this.isJudgingRightWrong) {
           //   this.userAnswer.push(obj);

+ 1 - 2
src/views/book/courseware/preview/components/character_base/CharacterBasePreview.vue

@@ -23,7 +23,7 @@
             :book-strokes="items.strokes"
             :class="['strock-chinese', indexs !== data.hz_strokes_list.length - 1 ? 'border-right-none' : '']"
             :bg-type="data.property.frame_type"
-            :playColor="data.property.frame_color"
+            :play-color="data.property.frame_color"
           />
         </template>
         <template v-else>
@@ -195,7 +195,6 @@ export default {
       show_preview: false,
       miao_arr: [],
       if_miao_show: false, // 描红模块
-      show_preview: false,
       hanzi_color: '#404040', // 描红汉字底色
     };
   },

+ 7 - 1
src/views/book/courseware/preview/components/fill/FillPreview.vue

@@ -4,7 +4,11 @@
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
 
     <div class="main" :style="getMainStyle()">
-      <AudioFill v-if="data.audio_file_id.length > 0" :file-id="data.audio_file_id" />
+      <AudioFill
+        v-if="data.audio_file_id.length > 0"
+        :color="data.unified_attrib.topic_color"
+        :file-id="data.audio_file_id"
+      />
       <div class="fill-wrapper">
         <p v-for="(item, i) in modelEssay" :key="i">
           <template v-for="(li, j) in item">
@@ -72,6 +76,7 @@
                   type="mini"
                   :many-times="false"
                   class="record-box"
+                  :attrib="data.unified_attrib"
                   :answer-record-list="data.audio_answer_list"
                   :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
                   @handleWav="handleMiniWav($event, li.mark)"
@@ -90,6 +95,7 @@
         ref="record"
         type="normal"
         class="record-box"
+        :attrib="data.unified_attrib"
         :answer-record-list="data.record_list"
         :task-model="isJudgingRightWrong ? 'ANSWER' : ''"
         @handleWav="handleWav"

+ 21 - 8
src/views/book/courseware/preview/components/fill/components/AudioFillPlay.vue

@@ -1,10 +1,6 @@
 <template>
   <div class="audio-fill">
-    <img
-      :src="audio.paused ? require('@/assets/fill/voice-pause-red.png') : require('@/assets/fill/voice-play-red.png')"
-      class="audio-play"
-      @click="playAudio"
-    />
+    <span class="audio-play icon-mask" :style="maskStyle" @click="playAudio"></span>
     <audio
       :id="fileId"
       :ref="fileId"
@@ -28,6 +24,11 @@ export default {
       type: String,
       required: true,
     },
+    // 指定想要的颜色
+    color: {
+      type: String,
+      default: '#E84F4F',
+    },
   },
   data() {
     return {
@@ -36,16 +37,28 @@ export default {
       audio: {
         paused: true,
         playing: false,
-        // 音频当前播放时长
         current_time: 0,
-        // 音频最大播放时长
         max_time: 0,
         loading: false,
       },
       play_value: 0,
-      audio_allTime: null, // 展示总时间
+      audio_allTime: null,
     };
   },
+  computed: {
+    iconSrc() {
+      return this.audio.paused
+        ? require('@/assets/fill/voice-pause-red.png')
+        : require('@/assets/fill/voice-play-red.png');
+    },
+    // 通过 mask 把图标着成指定颜色
+    maskStyle() {
+      return {
+        backgroundColor: this.color,
+        maskImage: `url(${this.iconSrc})`,
+      };
+    },
+  },
   watch: {
     fileId: {
       handler(val) {

+ 6 - 1
src/views/book/courseware/preview/components/judge/JudgePreview.vue

@@ -10,7 +10,10 @@
           :style="{ cursor: disabled ? 'not-allowed' : 'pointer' }"
           :class="['option-item', { active: isAnswer(mark) }]"
         >
-          <div :class="['option-content', computedIsJudgeRight(mark)]">
+          <div
+            :style="{ borderColor: data.unified_attrib.topic_color }"
+            :class="['option-content', computedIsJudgeRight(mark)]"
+          >
             <span class="serial-number">{{ convertNumberToLetter(i) }}.</span>
             <PinyinText
               v-if="isEnable(data.property.view_pinyin)"
@@ -166,6 +169,8 @@ export default {
         align-items: center;
         padding: 12px 24px;
         background-color: $content-color;
+        border-style: solid;
+        border-width: 1px;
         border-radius: 40px;
 
         &.right {

+ 2 - 1
src/views/book/courseware/preview/components/matching/MatchingPreview.vue

@@ -337,7 +337,8 @@ export default {
     setPathAttr(path) {
       path.setAttribute('stroke-width', '2'); // 设置线条宽度
       path.setAttribute('stroke-linecap', 'round'); // 设置线段的两端样式
-      path.setAttribute('stroke', '#306eff'); // 设置填充颜色
+      const assistColor = this.data?.unified_attrib?.topic_color || '#306eff';
+      path.setAttribute('stroke', assistColor); // 设置填充颜色
       path.setAttribute('transform', `translate(2, 2)`); // 设置偏移量
     },
     /**

+ 57 - 57
src/views/book/courseware/preview/components/newWord_template/NewWordTemplatePreview.vue

@@ -4,10 +4,10 @@
     <SerialNumberPosition v-if="isEnable(data.property.sn_display_mode)" :property="data.property" />
     <div class="main">
       <div
-        class="item-box"
-        :class="['item-box-' + data.property.model]"
         v-for="(item, index) in data.option_list"
         :key="index"
+        class="item-box"
+        :class="['item-box-' + data.property.model]"
       >
         <div
           class="number-box"
@@ -38,15 +38,14 @@
             {{ item.pinyin }}
           </div>
           <div
-            class="inputdv pinyin-common"
             v-if="data.answer_type.indexOf('pinyin') > -1 && data.property.model === 'input' && item.is_common_pinyin"
+            class="inputdv pinyin-common"
           >
             <EditDiv
               :id="'b' + item.content + index"
-              :canEdit="!item.is_example && !disabled"
               v-model="userAnswer[index].answer_pinyin"
-              :textAlign="'center'"
-              @input="changeAnswer(item, index)"
+              :can-edit="!item.is_example && !disabled"
+              :text-align="'center'"
               :class="[classNameJudge(userAnswer[index].answer_pinyin, item.answer_pinyin, item.is_example)]"
               :style="{
                 fontSize:
@@ -56,14 +55,15 @@
                     ? data.unified_attrib.assist_color
                     : '#deebff',
               }"
+              @input="changeAnswer(item, index)"
             />
           </div>
           <div class="items-flex">
             <div
-              class="items"
-              :class="[items.is_example ? 'items-example' : '']"
               v-for="(items, indexs) in item.content_list"
               :key="indexs"
+              class="items"
+              :class="[items.is_example ? 'items-example' : '']"
             >
               <div
                 v-if="
@@ -79,18 +79,17 @@
                 {{ items.pinyin }}
               </div>
               <div
-                class="inputdv pinyin-common"
-                :class="[items.is_example ? 'items-example' : 'items-no-example']"
                 v-if="
                   data.answer_type.indexOf('pinyin') > -1 && data.property.model === 'input' && !item.is_common_pinyin
                 "
+                class="inputdv pinyin-common"
+                :class="[items.is_example ? 'items-example' : 'items-no-example']"
               >
                 <EditDiv
                   :id="'c' + items.con + index + indexs"
-                  :canEdit="!items.is_example && !disabled"
                   v-model="userAnswer[index].item[indexs].answer_pinyin"
-                  :textAlign="'center'"
-                  @input="changeAnswer(item, index, indexs)"
+                  :can-edit="!items.is_example && !disabled"
+                  :text-align="'center'"
                   :class="[
                     classNameJudge(userAnswer[index].item[indexs].answer_pinyin, items.answer_pinyin, items.is_example),
                   ]"
@@ -102,20 +101,21 @@
                         ? data.unified_attrib.assist_color
                         : '#deebff',
                   }"
+                  @input="changeAnswer(item, index, indexs)"
                 />
               </div>
               <div class="items-content">
                 <template v-if="items && items.type === 'img'">
                   <el-image
-                    class="items-image"
                     v-if="items.file_list[0]"
+                    class="items-image"
                     :src="items.file_list[0].file_url"
                     fit="contain"
                     :style="{
                       borderColor:
                         data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
                     }"
-                  ></el-image>
+                  />
                 </template>
                 <template v-else-if="items && items.type === 'lian'">
                   <span class="items-lian">{{ items.con }}</span>
@@ -123,8 +123,8 @@
                 <Strockplayredline
                   v-if="items && items.type === 'hanzi'"
                   :Book_text="items.con"
-                  :playStorkes="isEnable(data.property.is_enable_play_structure)"
-                  :curItem="
+                  :play-storkes="isEnable(data.property.is_enable_play_structure)"
+                  :cur-item="
                     isEnable(data.property.is_enable_high_strokes)
                       ? data.property.model === 'input'
                         ? items.high_strokes
@@ -132,7 +132,7 @@
                       : null
                   "
                   :type="data.property.model === 'input' ? 'newWord-template-input' : data.type"
-                  :targetDiv="'newWordTemplate-answer' + items.con + index + indexs + randomId"
+                  :target-div="'newWordTemplate-answer' + items.con + index + indexs + randomId"
                   :hz_json="items.hz_info[0].hzDetail.hz_json"
                   class="hanzi-storck"
                   :class="[
@@ -144,24 +144,23 @@
                       : '',
                     item.content_list.length > 1 && indexs != item.content_list.length - 1 ? 'NoborderRight' : '',
                   ]"
-                  bgType="tian"
+                  bg-type="tian"
                   :style="{
                     borderColor:
                       data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
                   }"
-                  :playColor="
+                  :play-color="
                     data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
                   "
                 />
               </div>
-              <div class="inputdv" v-if="data.property.model === 'miao'">
+              <div v-if="data.property.model === 'miao'" class="inputdv">
                 <EditDiv
                   v-if="items && items.type === 'hanzi' && items.is_can_input_answer"
                   :id="'a' + items.con + index + indexs"
-                  :canEdit="!items.is_example && !disabled"
                   v-model="userAnswer[index].item[indexs].answer"
-                  :textAlign="'center'"
-                  @input="changeAnswer(items, index, indexs)"
+                  :can-edit="!items.is_example && !disabled"
+                  :text-align="'center'"
                   :class="[classNameJudge(userAnswer[index].item[indexs].answer, items.answer, items.is_example)]"
                   :style="{
                     fontSize:
@@ -171,17 +170,17 @@
                         ? data.unified_attrib.assist_color
                         : '#deebff',
                   }"
+                  @input="changeAnswer(items, index, indexs)"
                 />
               </div>
             </div>
           </div>
-          <div class="inputdv en-common" v-if="data.answer_type.indexOf('en') > -1 && data.property.model === 'input'">
+          <div v-if="data.answer_type.indexOf('en') > -1 && data.property.model === 'input'" class="inputdv en-common">
             <EditDiv
               :id="'d' + item.content + index"
-              :canEdit="!item.is_example && !disabled"
               v-model="userAnswer[index].answer_en"
-              :textAlign="'center'"
-              @input="changeAnswer(item, index)"
+              :can-edit="!item.is_example && !disabled"
+              :text-align="'center'"
               :class="[classNameJudge(userAnswer[index].answer_en, item.answer_en, item.is_example)]"
               :style="{
                 fontSize:
@@ -191,9 +190,10 @@
                     ? data.unified_attrib.assist_color
                     : '#deebff',
               }"
+              @input="changeAnswer(item, index)"
             />
           </div>
-          <div class="en-common" v-if="data.property.model === 'input'">{{ item.shiyi }}</div>
+          <div v-if="data.property.model === 'input'" class="en-common">{{ item.shiyi }}</div>
         </div>
       </div>
     </div>
@@ -202,10 +202,10 @@
       <div class="title">正确答案</div>
       <div class="box">
         <div
-          class="item-box"
-          :class="['item-box-' + data.property.model]"
           v-for="(item, index) in data.option_list"
           :key="index"
+          class="item-box"
+          :class="['item-box-' + data.property.model]"
         >
           <div
             class="number-box"
@@ -237,15 +237,14 @@
               {{ item.pinyin }}
             </div>
             <div
-              class="inputdv pinyin-common"
               v-if="data.answer_type.indexOf('pinyin') > -1 && data.property.model === 'input' && item.is_common_pinyin"
+              class="inputdv pinyin-common"
             >
               <EditDiv
                 :id="'bz' + item.content + index"
-                :canEdit="!item.is_example && !disabled"
                 v-model="item.answer_pinyin"
-                :textAlign="'center'"
-                @input="changeAnswer(item, index)"
+                :can-edit="!item.is_example && !disabled"
+                :text-align="'center'"
                 :style="{
                   fontSize:
                     data.unified_attrib && data.unified_attrib.pinyin_size ? data.unified_attrib.pinyin_size : '16px',
@@ -254,14 +253,15 @@
                       ? data.unified_attrib.assist_color
                       : '#deebff',
                 }"
+                @input="changeAnswer(item, index)"
               />
             </div>
             <div class="items-flex">
               <div
-                class="items"
-                :class="[items.is_example ? 'items-example' : '']"
                 v-for="(items, indexs) in item.content_list"
                 :key="indexs"
+                class="items"
+                :class="[items.is_example ? 'items-example' : '']"
               >
                 <div
                   v-if="
@@ -277,17 +277,16 @@
                   {{ items.pinyin }}
                 </div>
                 <div
-                  class="inputdv pinyin-common"
                   v-if="
                     data.answer_type.indexOf('pinyin') > -1 && data.property.model === 'input' && !item.is_common_pinyin
                   "
+                  class="inputdv pinyin-common"
                 >
                   <EditDiv
                     :id="'cz' + items.con + index + indexs"
-                    :canEdit="!items.is_example && !disabled"
                     v-model="items.answer_pinyin"
-                    :textAlign="'center'"
-                    @input="changeAnswer(item, index, indexs)"
+                    :can-edit="!items.is_example && !disabled"
+                    :text-align="'center'"
                     :style="{
                       fontSize:
                         data.unified_attrib && data.unified_attrib.pinyin_size
@@ -298,20 +297,21 @@
                           ? data.unified_attrib.assist_color
                           : '#deebff',
                     }"
+                    @input="changeAnswer(item, index, indexs)"
                   />
                 </div>
                 <div class="items-content">
                   <template v-if="items && items.type === 'img'">
                     <el-image
-                      class="items-image"
                       v-if="items.file_list[0]"
+                      class="items-image"
                       :src="items.file_list[0].file_url"
                       fit="contain"
                       :style="{
                         borderColor:
                           data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
                       }"
-                    ></el-image>
+                    />
                   </template>
                   <template v-else-if="items && items.type === 'lian'">
                     <span class="items-lian">{{ items.con }}</span>
@@ -319,8 +319,8 @@
                   <Strockplayredline
                     v-if="items && items.type === 'hanzi'"
                     :Book_text="items.con"
-                    :playStorkes="isEnable(data.property.is_enable_play_structure)"
-                    :curItem="
+                    :play-storkes="isEnable(data.property.is_enable_play_structure)"
+                    :cur-item="
                       isEnable(data.property.is_enable_high_strokes)
                         ? data.property.model === 'input'
                           ? items.high_strokes
@@ -328,7 +328,7 @@
                         : null
                     "
                     :type="data.property.model === 'input' ? 'newWord-template-input' : data.type"
-                    :targetDiv="'newWordTemplatez' + items.con + index + indexs + randomId"
+                    :target-div="'newWordTemplatez' + items.con + index + indexs + randomId"
                     :hz_json="items.hz_info[0].hzDetail.hz_json"
                     class="hanzi-storck"
                     :class="[
@@ -344,20 +344,19 @@
                       borderColor:
                         data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : '',
                     }"
-                    :playColor="
+                    :play-color="
                       data.unified_attrib && data.unified_attrib.topic_color ? data.unified_attrib.topic_color : ''
                     "
-                    bgType="tian"
+                    bg-type="tian"
                   />
                 </div>
-                <div class="inputdv" v-if="data.property.model === 'miao'">
+                <div v-if="data.property.model === 'miao'" class="inputdv">
                   <EditDiv
                     v-if="items && items.type === 'hanzi' && items.is_can_input_answer"
                     :id="'az' + items.con + index + indexs"
-                    :canEdit="!items.is_example && !disabled"
                     v-model="items.answer"
-                    :textAlign="'center'"
-                    @input="changeAnswer(items, index, indexs)"
+                    :can-edit="!items.is_example && !disabled"
+                    :text-align="'center'"
                     :style="{
                       fontSize:
                         data.unified_attrib && data.unified_attrib.pinyin_size
@@ -368,20 +367,20 @@
                           ? data.unified_attrib.assist_color
                           : '#deebff',
                     }"
+                    @input="changeAnswer(items, index, indexs)"
                   />
                 </div>
               </div>
             </div>
             <div
-              class="inputdv en-common"
               v-if="data.answer_type.indexOf('en') > -1 && data.property.model === 'input'"
+              class="inputdv en-common"
             >
               <EditDiv
                 :id="'dz' + item.content + index"
-                :canEdit="!item.is_example && !disabled"
                 v-model="item.answer_en"
-                :textAlign="'center'"
-                @input="changeAnswer(item, index)"
+                :can-edit="!item.is_example && !disabled"
+                :text-align="'center'"
                 :style="{
                   fontSize:
                     data.unified_attrib && data.unified_attrib.pinyin_size ? data.unified_attrib.pinyin_size : '16px',
@@ -390,9 +389,10 @@
                       ? data.unified_attrib.assist_color
                       : '#deebff',
                 }"
+                @input="changeAnswer(item, index)"
               />
             </div>
-            <div class="en-common" v-if="data.property.model === 'input'">{{ item.shiyi }}</div>
+            <div v-if="data.property.model === 'input'" class="en-common">{{ item.shiyi }}</div>
           </div>
         </div>
       </div>

+ 2 - 1
src/views/book/courseware/preview/components/select/SelectPreview.vue

@@ -11,7 +11,7 @@
         <li
           v-for="({ content, mark, multilingual, paragraph_list }, i) in data.option_list"
           :key="mark"
-          :style="{ cursor: disabled ? 'not-allowed' : 'pointer' }"
+          :style="{ cursor: disabled ? 'not-allowed' : 'pointer', borderColor: data.unified_attrib.topic_color }"
           :class="['option-item', { active: isAnswer(mark) }, ...computedAnswerClass(mark)]"
           @click="selectAnswer(mark)"
         >
@@ -133,6 +133,7 @@ export default {
       color: #706f78;
       cursor: pointer;
       background-color: $content-color;
+      border: 1px solid $content-color;
       border-radius: 40px;
 
       .lang {

+ 4 - 0
src/views/book/courseware/preview/components/voice_matrix/VoiceMatrixPreview.vue

@@ -29,6 +29,7 @@
           :stop-audio="stopAudio"
           :mp3-source="mp3Source"
           :audio-data="data"
+          :attrib="data.unified_attrib"
           @handleChangeStopAudio="handleChangeStopAudio"
           @playChange="playChange"
         />
@@ -182,6 +183,7 @@
           type="promax"
           class="luyin-box"
           :answer-record-list="data.record_list"
+          :attrib="data.unified_attrib"
           @getWavblob="getWavblob"
           @getSelectData="getSelectData"
           @handleParentPlay="pauseOtherAudio"
@@ -192,6 +194,8 @@
           :style="{ flex: 1 }"
           :theme-color="themeColor"
           :wavblob="wavblob"
+          type="full"
+          :attrib="data.unified_attrib"
           :url="mp3Url"
           :is-record="isRecord"
           :sent-pause="sentPause"

+ 16 - 5
src/views/book/courseware/preview/components/voice_matrix/components/AudioCompareMatrix.vue

@@ -6,13 +6,14 @@
         :class="[type == 'full' ? 'compare-box-big' : 'compare-box']"
         @click.stop.capture="playAudio"
       >
-        <audio-line
+        <AudioLine
           ref="audioLine"
           :mp3="url"
           :get-cur-time="getCurTime"
           audio-id="audioCompareMatrix"
           :stop-audio="stopAudio"
           :hide-slider="true"
+          :attrib="attrib"
           :type="type"
           @handleChangeStopAudio="handleChangeStopAudio"
           @sentPause="sentPause"
@@ -20,11 +21,11 @@
         />
       </div>
       <div v-else :class="[type == 'full' ? 'compare-box-big' : 'compare-box']">
-        <audio-red
+        <AudioRed
           ref="audioRed"
           :mp3="wavblob"
           :is-compare="true"
-          :theme-color="themeColor"
+          :attrib="attrib"
           :type="type"
           @sentPause="sentPause"
         />
@@ -52,7 +53,18 @@ export default {
     AudioLine,
     AudioRed,
   },
-  props: ['themeColor', 'isRecord', 'wavblob', 'url', 'type', 'sentPause', 'matrixSelectLrc', 'getCurTime', 'curTime'],
+  props: [
+    'themeColor',
+    'isRecord',
+    'wavblob',
+    'url',
+    'type',
+    'sentPause',
+    'matrixSelectLrc',
+    'getCurTime',
+    'curTime',
+    'attrib',
+  ],
   data() {
     return {
       playing: false,
@@ -83,7 +95,6 @@ export default {
     playAudio() {
       if (this.playing) return this.handleParentPlay();
       if (this.unWatch) return this.$refs.audioLine.PlayAudio();
-      console.log(this.matrixSelectLrc);
       if (this.matrixSelectLrc === null) {
         this.sentPause(true);
         this.playChange(false);

+ 17 - 12
src/views/book/courseware/preview/components/voice_matrix/components/AudioLine.vue

@@ -4,15 +4,20 @@
     <div v-if="!hideSlider" class="audioLine">
       <div class="playBox" @click="PlayAudio">
         <div class="play" :class="[audio.loading ? 'loadBtn' : audio.playing ? 'playBtn' : 'pauseBtn']">
-          <SvgIcon v-if="audio.playing" icon-class="pause-large-fill" :style="{ color: bookInfo.theme_color }" />
-          <SvgIcon v-else icon-class="play-large-fill" :style="{ color: bookInfo.theme_color }" />
+          <SvgIcon
+            v-if="audio.playing"
+            size="24px"
+            icon-class="pause-large-fill"
+            :style="{ color: attrib.topic_color }"
+          />
+          <SvgIcon v-else size="24px" icon-class="play-large-fill" :style="{ color: attrib.topic_color }" />
         </div>
       </div>
 
       <template v-if="!isRepeat">
         <el-slider
           v-model="playValue"
-          :style="{ width: sliderWidth + 'px', height: '2px', '--slider-color': bookInfo.theme_color }"
+          :style="{ width: sliderWidth + 'px', height: '2px', '--slider-color': attrib.topic_color }"
           :format-tooltip="formatProcessToolTip"
           @change="changeCurrentTime"
         />
@@ -53,7 +58,9 @@
     <div v-else class="audioLine2">
       <div
         class="play-icon"
+        :style="{ backgroundColor: attrib.topic_color }"
         :class="[
+          'icon-mask',
           audio.loading ? 'loadBtn' : audio.playing ? 'playBtn-icon' : 'pauseBtn-icon',
           type == 'full' ? 'play-icon-big' : '',
         ]"
@@ -100,6 +107,7 @@
 
 <script>
 export default {
+  name: 'VoiceMatrixAudioLine',
   inject: ['bookInfo'],
   props: [
     'mp3',
@@ -115,6 +123,7 @@ export default {
     'audioId',
     'type',
     'audioData',
+    'attrib',
   ],
   data() {
     // 这里存放数据
@@ -375,7 +384,6 @@ export default {
     .play {
       display: block;
       width: 16px;
-      height: 16px;
       font-size: 0;
       cursor: pointer;
     }
@@ -403,20 +411,17 @@ export default {
       }
 
       &.playBtn-icon {
-        background: url('@/assets/voice_matrix/pauseC-16-normal-blue.png') no-repeat left top;
-        background-size: 100% 100%;
+        mask-image: url('@/assets/voice_matrix/pauseC-16-normal-blue.png');
       }
 
       &.pauseBtn-icon {
-        background: url('@/assets/voice_matrix/compare-pause-blue.png') no-repeat left top;
-        background-size: 100% 100%;
+        mask-image: url('@/assets/voice_matrix/compare-pause-blue.png');
       }
     }
   }
 
   .loadBtn {
-    background: url('@/assets/voice_matrix/loading-blue.png') no-repeat left top;
-    background-size: 100% 100%;
+    mask: url('@/assets/voice_matrix/loading-blue.png') no-repeat left top;
   }
 
   &.Audio-tts {
@@ -446,7 +451,7 @@ export default {
     top: 12px;
     width: 8px;
     height: 8px;
-    background: #1d2129;
+    background: var(--slider-color);
     border: none;
   }
 
@@ -464,7 +469,7 @@ export default {
 
   .el-slider__bar {
     height: 2px;
-    background: #1d2129;
+    background: var(--slider-color);
   }
 }
 </style>

+ 9 - 28
src/views/book/courseware/preview/components/voice_matrix/components/AudioRed.vue

@@ -1,14 +1,17 @@
 <!--  -->
 <template>
-  <div v-if="mp3" class="content-voices" @click="handlePlayVoice">
-    <img :src="voiceSrc" :class="type == 'full' ? 'icon-big' : ''" />
-  </div>
+  <div
+    v-if="mp3"
+    class="content-voices icon-mask"
+    :style="{ backgroundColor: attrib.topic_color, maskImage: `url(${voiceSrc})` }"
+    @click="handlePlayVoice"
+  ></div>
 </template>
 
 <script>
 export default {
   components: {},
-  props: ['seconds', 'mp3', 'wav', 'isCompare', 'type'],
+  props: ['seconds', 'mp3', 'wav', 'isCompare', 'type', 'attrib'],
   data() {
     return {
       audio: new Audio(),
@@ -85,31 +88,9 @@ export default {
   display: flex;
   align-items: center;
   justify-content: center;
-  width: 100%;
+  width: 24px;
+  height: 24px;
   font-size: 0;
   cursor: pointer;
-
-  span {
-    float: left;
-    font-family: 'sourceR';
-    font-size: 24px;
-    line-height: 30px;
-    color: #2c2c2c;
-
-    &.noMp3 {
-      margin-left: 0;
-    }
-  }
-
-  img {
-    float: left;
-    width: 16px;
-    height: 16px;
-  }
-
-  .icon-big {
-    width: 24px;
-    height: 24px;
-  }
 }
 </style>