Browse Source

添加标签

lex-xin 5 months ago
parent
commit
23eeaa9b75

BIN
src/views/hot-music-more/images/icon-change.png


BIN
src/views/hot-music-more/images/icon-download.png


BIN
src/views/hot-music-more/images/icon-staff.png


BIN
src/views/hot-music-more/images/icon-title-arrow.png


BIN
src/views/hot-music-more/images/staff/first-active.png


BIN
src/views/hot-music-more/images/staff/first.png


BIN
src/views/hot-music-more/images/staff/fixed-active.png


BIN
src/views/hot-music-more/images/staff/fixed.png


BIN
src/views/hot-music-more/images/staff/staff-active.png


BIN
src/views/hot-music-more/images/staff/staff.png


BIN
src/views/hot-music-more/images/tag-tip.png


+ 94 - 25
src/views/hot-music-more/index.module.less

@@ -5,7 +5,7 @@
 
   :global {
     .van-search {
-      padding-top: 20px;
+      padding-top: 1px;
     }
 
     .van-sticky--fixed {
@@ -22,31 +22,81 @@
 
   .leftArrow {
     padding: 0 var(--k-padding-md);
+    margin-right: 0;
   }
 
-  .title {
-    position: relative;
-    z-index: 1;
-
-    i {
-      width: 78px;
-      height: 20px;
-      display: inline-block;
-      background: url('./images/woring-title.png') no-repeat center;
-      background-size: contain;
+  // .title {
+  //   position: relative;
+  //   z-index: 1;
+
+  //   i {
+  //     width: 78px;
+  //     height: 20px;
+  //     display: inline-block;
+  //     background: url('./images/woring-title.png') no-repeat center;
+  //     background-size: contain;
+  //   }
+
+  //   &::after {
+  //     content: ' ';
+  //     display: inline-block;
+  //     position: absolute;
+  //     left: 0;
+  //     bottom: -2px;
+  //     width: 48px;
+  //     height: 6px;
+  //     background: linear-gradient(270deg, rgba(119, 255, 239, 0.59) 0%, #42CDFF 100%);
+  //     opacity: 0.5;
+  //     z-index: -1;
+  //   }
+  // }
+
+  .tabSection {
+    // padding: 0 32px;
+    flex: 1;
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    --van-tab-font-size: 16px;
+    --van-tabs-line-height: 28px;
+    --van-tab-text-color: rgba(51, 51, 51, .5);
+    --van-tab-active-text-color: #333333;
+    --van-tabs-nav-background: transparent;
+    --van-padding-xs: 0;
+
+    .moreIcon {
+      display: flex;
+      align-items: center;
+      span {
+        padding-right: 4px;
+      }
     }
 
-    &::after {
-      content: ' ';
-      display: inline-block;
-      position: absolute;
-      left: 0;
-      bottom: -2px;
-      width: 48px;
-      height: 6px;
-      background: linear-gradient(270deg, rgba(119, 255, 239, 0.59) 0%, #42CDFF 100%);
-      opacity: 0.5;
-      z-index: -1;
+    .iconArrow {
+      width: 9px;
+      height: 5px;
+    }
+    .iconArrowActive {
+      transform: rotate(180deg);
+    }
+    
+    :global {
+      .van-tabs__line {
+        display: inline-block;
+        width: 24px;
+        height: 11px;
+        background: url('./images/tag-tip.png') no-repeat center;
+        background-size: contain;
+        bottom: 16px;
+      }
+      .van-tab__text {
+        line-height: normal;
+        font-weight: 600;
+      }
+      .van-tab--shrink {
+        padding: 0 21px;
+        z-index: 9;
+      }
     }
   }
 }
@@ -94,11 +144,19 @@
 
 .musicList {
   margin: 8px 13px 13px;
-  background: #FFFFFF;
+  background: rgba(255,255,255,0.28);
   border-radius: 16px;
+  border: 2px solid #FFFFFF;
+  // backdrop-filter: blur(5px);
   overflow: hidden;
   // min-height: 50vh;
 
+  :global {
+    .van-cell {
+      background: transparent;
+    }
+  }
+
   .musicItem {
     padding: 15px 12px;
   }
@@ -269,7 +327,7 @@
   display: flex;
   align-items: center;
   flex-wrap: wrap;
-  padding-top: 18px;
+  padding-top: 9px;
 
   &.subjectContainerTwo {
     .subjectItem {
@@ -296,7 +354,7 @@
     line-height: 34px;
     text-align: center;
     background: #F6F6F6;
-    border-radius: 50px;
+    border-radius: 6px;
     font-size: 13px;
     color: #333333;
     border: 1px solid #F6F6F6;
@@ -337,3 +395,14 @@
     }
   }
 }
+
+.popupMusicDetail {
+  :global {
+    .van-popup__close-icon {
+      font-size: 16px;
+      color: #aaa;
+      top: 29px;
+      right: 20px;
+    }
+  }
+}

+ 129 - 26
src/views/hot-music-more/index.tsx

@@ -13,15 +13,18 @@ import MSticky from '@/components/m-sticky';
 import MHeader from '@/components/m-header';
 import { useRouter } from 'vue-router';
 import MSearch from '@/components/m-search';
-import { Cell, Image, List, Popup } from 'vant';
+import { Cell, Image, List, Popup, Tab, Tabs } from 'vant';
 import iconPlayer from './images/icon-player.png';
 import iconFire from './images/icon-fire.png';
+import iconTitleArrow from './images/icon-title-arrow.png'
 import { api_musicSheetCategoriesPage, api_musicSheetPage } from '../co-ai/api';
 import { state as baseState } from '@/state';
 import request from '@/helpers/request';
 import MEmpty from '@/components/m-empty';
 import { postMessage } from '@/helpers/native-message';
 import { audioPlayType } from '@/helpers/constant';
+import MusicDetail from './music-detail';
+import TheVip from '@/components/the-vip';
 
 const ChildNodeSearch = defineComponent({
   name: 'ChildNodeSearch',
@@ -113,6 +116,9 @@ export default defineComponent({
       loading: false,
       finished: false,
       searchPopup: false,
+      musicDetailPopup: false,
+      showVip: false,
+      tabActive: '1',
       musicTagList: [] as any,
       gradeList: [] as any,
       musicCategory: [] as any,
@@ -124,7 +130,8 @@ export default defineComponent({
       sMSCI: '',
       sMII: '',
       sBookId: '' as any,
-      sGrade: '' as any
+      sGrade: '' as any,
+      item: {} as any
     });
 
     const musicForms = reactive({
@@ -247,24 +254,23 @@ export default defineComponent({
     };
 
     const onDetail = (item: any) => {
-      const src = `${vaildMusicScoreUrl()}/instrument/?id=${
-        item?.id
-      }&showGuide=true&modelType=practise`;
+      // const src = `${vaildMusicScoreUrl()}/instrument/?id=${
+      //   item?.id
+      // }&showGuide=true&modelType=practise`;
 
-      // if (item.paymentType === 'FREE') {
-      //   src += `&showCourseMember=true`;
-      // }
-      postMessage({
-        api: 'openAccompanyWebView',
-        content: {
-          url: src,
-          orientation: 0,
-          isHideTitle: true,
-          statusBarTextColor: false,
-          isOpenLight: true,
-          c_orientation: 0 // 0 横屏 1 竖屏
-        }
-      });
+      // postMessage({
+      //   api: 'openAccompanyWebView',
+      //   content: {
+      //     url: src,
+      //     orientation: 0,
+      //     isHideTitle: true,
+      //     statusBarTextColor: false,
+      //     isOpenLight: true,
+      //     c_orientation: 0 // 0 横屏 1 竖屏
+      //   }
+      // });
+      state.item = item;
+      state.musicDetailPopup = true
     };
     const getMusicTagTree = async () => {
       try {
@@ -339,6 +345,42 @@ export default defineComponent({
       return data.tags.length > 0 ? true : false;
     });
 
+    const handleGoto = (item: any, showMusicImg: string, selectMusicInstrumentIndex: number) => {
+      const vipMember = baseState.user.data.vipMember
+      if (
+        !vipMember &&
+        item?.paymentType === 'VIP'
+      ) {
+        state.showVip = true;
+        return;
+      }
+      // 默认进页面显示对应的曲谱
+      let lineType = 'staff';
+      if (showMusicImg === 'first') {
+        lineType = 'firstTone';
+      } else if (showMusicImg === 'fixed') {
+        lineType = 'fixedTone';
+      } else if (showMusicImg === 'staff') {
+        lineType = 'staff';
+      }
+      let src = `${vaildMusicScoreUrl()}/instrument/?id=${
+        item?.id
+      }&musicRenderType=${lineType}&showGuide=true&part-index=${
+        selectMusicInstrumentIndex
+      }`;
+      postMessage({
+        api: 'openAccompanyWebView',
+        content: {
+          url: src,
+          orientation: 0,
+          isHideTitle: true,
+          statusBarTextColor: false,
+          isOpenLight: true,
+          c_orientation: 0 // 0 横屏 1 竖屏
+        }
+      });
+    }
+
     onMounted(async () => {
       // 场景
       const tempAudio = Object.keys(audioPlayType).map(key => {
@@ -358,6 +400,7 @@ export default defineComponent({
     return () => (
       // sortType: 2
       <div
+        id="hotMusicMore"
         class={[
           styles.hotMusicMore,
           browser().isTablet ? styles.hotMusicMoreTablet : ''
@@ -381,9 +424,26 @@ export default defineComponent({
                       'van-badge__wrapper van-icon van-icon-arrow-left van-nav-bar__arrow',
                       styles.leftArrow
                     ]}></i>
-                  <span class={styles.title}>
+                  {/* <span class={styles.title}>
                     <i></i>
-                  </span>
+                  </span> */}
+                  <Tabs class={styles.tabSection} v-model:active={state.tabActive} shrink  onClickTab={() => {
+                      console.log(state.tabActive)
+
+                      if(state.tabActive === "1") {
+                        state.searchPopup = true
+                      }
+                    }}>
+                    <Tab name="1">
+                      {{ title: () => <div class={styles.moreIcon}>
+                        <span>全部</span>
+                        <img src={iconTitleArrow} class={[styles.iconArrow, state.searchPopup && styles.iconArrowActive]} />
+                      </div> }}
+                    </Tab>
+                    <Tab name="2" title="推荐"></Tab>
+                    <Tab name="3" title="热门"></Tab>
+                    <Tab name="4" title="最新"></Tab>
+                  </Tabs>
                 </div>
               )
             }}
@@ -399,10 +459,9 @@ export default defineComponent({
               state.finished = false;
               getMusicList();
             }}>
-            {{
+            {/* {{
               left: () => (
-                // 由于添加了场景,必然有搜索条件
-                // isSearch.value && (
+                
                 <div
                   class={[
                     styles.searchContent,
@@ -420,8 +479,7 @@ export default defineComponent({
                   <i></i>
                 </div>
               )
-              // )
-            }}
+            }} */}
           </MSearch>
         </MSticky>
 
@@ -526,6 +584,26 @@ export default defineComponent({
             </div>
 
             <div class={styles.changeSubjectContainer}>
+            {state.audioPlayTypeList.length > 0 && (
+                <>
+                  <div class={styles.title}>标签</div>
+                  <div class={styles.subjectContainer}>
+                    {state.audioPlayTypeList.map((subject: any) => (
+                      <div
+                        class={[
+                          styles.subjectItem,
+                          subject.id === state.sAPT && styles.active
+                        ]}
+                        onClick={() => {
+                          state.sAPT = subject.id;
+                        }}>
+                        {subject.name}
+                      </div>
+                    ))}
+                  </div>
+                </>
+              )}
+
               {state.audioPlayTypeList.length > 0 && (
                 <>
                   <div class={styles.title}>场景</div>
@@ -622,6 +700,31 @@ export default defineComponent({
             </div>
           </div>
         </Popup>
+
+        <Popup position='bottom' class={styles.popupMusicDetail} closeable round v-model:show={state.musicDetailPopup}>
+          <MusicDetail item={state.item} onHandleGoto={handleGoto} />
+        </Popup>
+
+        <Popup
+          class="popup-custom van-scale"
+          transition="van-scale"
+          closeOnClickOverlay={false}
+          v-model:show={state.showVip}>
+          <TheVip
+            onClose={val => {
+              if (val) {
+                postMessage({
+                  api: 'openWebView',
+                  content: {
+                    url: `${location.origin}${location.pathname}#/member-center`,
+                    orientation: 1
+                  }
+                });
+              }
+              state.showVip = false;
+            }}
+          />
+        </Popup>
       </div>
     );
   }

+ 107 - 0
src/views/hot-music-more/music-detail/index.module.less

@@ -0,0 +1,107 @@
+.musicDetail {
+  .musicContainer {
+    position: relative;
+    &::before {
+      pointer-events: none;
+      content: ' ';
+      position: absolute;
+      top: 0;
+      left: 0;
+      right: 0;
+      display: block;
+      height: 38px;
+      background: linear-gradient(180deg, #e3f4fa 0%, #ffffff 100%);
+    }
+    &::after {
+      pointer-events: none;
+      content: ' ';
+      position: absolute;
+      bottom: 0;
+      left: 0;
+      right: 0;
+      display: block;
+      height: 50px;
+      background: linear-gradient(
+        180deg,
+        rgba(255, 255, 255, 0) 0%,
+        rgba(255, 255, 255, 0.83) 100%
+      );
+    }
+  }
+  .container {
+    position: relative;
+    height: 300px;
+    display: flex;
+    flex-direction: column;
+
+    .iframeSection {
+      flex: 1 auto;
+      height: 100%;
+
+      iframe {
+        height: 100%;
+      }
+    }
+
+    .imgSection {
+      flex: 1 auto;
+      overflow-x: hidden;
+      overflow-y: auto;
+      height: 100%;
+      padding: 0 18px;
+    }
+
+    .right-musicName {
+      position: relative;
+      text-align: center;
+      padding: 25px 0 8px;
+      font-weight: 600;
+      font-size: 18px;
+      color: #131415;
+      line-height: 25px;
+    }
+
+    .staff {
+      width: 100%;
+    }
+  }
+}
+
+.btnGroup {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  padding: 20px 20px 34px;
+  border-top: 1px solid #f2f2f2;
+
+  .item {
+    margin-right: 20px;
+    text-align: center;
+    .icon {
+      width: 28px;
+      height: 28px;
+      display: block;
+      margin-bottom: 2px;
+    }
+    font-size: 12px;
+    color: #777777;
+  }
+
+  .operation {
+    display: flex;
+    align-items: center;
+  }
+
+  .goBtn {
+    margin-left: 12px;
+    background: linear-gradient(90deg, #44c9ff 0%, #259cfe 100%);
+    font-weight: 500;
+    font-size: 18px;
+    color: #ffffff;
+    line-height: 25px;
+    flex: 1 auto;
+    &::after {
+      display: none;
+    }
+  }
+}

+ 635 - 0
src/views/hot-music-more/music-detail/index.tsx

@@ -0,0 +1,635 @@
+import {
+  computed,
+  defineComponent,
+  onMounted,
+  reactive,
+  ref,
+  toRef,
+  TransitionGroup,
+  watch
+} from 'vue';
+import styles from './index.module.less';
+import iconChange from '../images/icon-change.png';
+import iconDownload from '../images/icon-download.png';
+import iconStaff from '../images/icon-staff.png';
+import staff from '../images/staff/staff.png'
+import staffActive from '../images/staff/staff-active.png'
+import first from '../images/staff/first.png'
+import firstActive from '../images/staff/first-active.png'
+import fixed from '../images/staff/fixed.png'
+import fixedActive from '../images/staff/fixed-active.png'
+import { Button, Popover, showLoadingToast, showToast } from 'vant';
+import { state } from '@/state';
+import {
+  getInstrumentName,
+  sortMusical,
+  vaildMusicScoreUrl
+} from '@/helpers/utils';
+import { storage } from '@/helpers/storage';
+import { ACCESS_TOKEN } from '@/store/mutation-types';
+import { promisefiyPostMessage } from '@/helpers/native-message';
+import html2canvas from 'html2canvas';
+import { addWatermark, convasToImg } from '@/views/co-ai/imageFunction';
+
+export default defineComponent({
+  name: 'music-detail',
+  props: {
+    item: {
+      type: Object,
+      default: () => ({})
+    }
+  },
+  emits: ['handleGoto'],
+  setup(props, { emit }) {
+    const item = toRef(props.item);
+    const data = reactive({
+      musicPdfUrl: '',
+      iframeSrc: '',
+      selectMusicInstrumentIndex: 0,
+      popoverShow: false,
+      showChangeVoice: false,
+      /** 显示哪种曲谱 */
+      showMusicImg: 'staff' as 'staff' | 'first' | 'fixed',
+      trackList: [] as any, // 可筛选的分轨信息
+      showTransBtn: true // 是否显示转谱按钮
+    });
+    const downRef = ref();
+
+    watch(
+      () => props.item,
+      () => {
+        item.value = props.item;
+        __init();
+      }
+    );
+
+    const _actions = computed(() => {
+      const details = item.value;
+      let { scoreType, isConvertibleScore } = details || {};
+
+      let action: any[] = [
+        {
+          value: 'first',
+          text: '首调',
+          icon: first
+        },
+        {
+          value: 'fixed',
+          text: '固定调',
+          icon: fixed
+        }
+      ];
+
+      if (
+        !(
+          ['JIAN', 'FIRST'].includes(scoreType) && isConvertibleScore === false
+        ) &&
+        !(isConvertibleScore === undefined || isConvertibleScore === null)
+      ) {
+        action.unshift({
+          value: 'staff',
+          text: '五线谱',
+          icon: staff
+        });
+      }
+      action.forEach((item: any) => {
+        if(item.value === data.showMusicImg) {
+          if(item.value === 'first') {
+            item.icon = firstActive
+          } else if(item.value == 'fixed') {
+            item.icon = fixedActive
+          } else if(item.value === 'staff') {
+            item.icon = staffActive
+          }
+        }
+      })
+
+      return action.map((item, index) => {
+        return {
+          ...item,
+          color:
+            data.showMusicImg === item.value ? 'var(--van-primary-color)' : '',
+          className: data.showMusicImg === item.value ? 'fontBlod' : ''
+        };
+      });
+    });
+
+    /** 保存图片 */
+    const handleSave = async () => {
+      if (data.musicPdfUrl) {
+        const songName = item.value?.musicSheetName;
+        promisefiyPostMessage({
+          api: 'downloadFile',
+          content: {
+            downloadUrl: data.musicPdfUrl,
+            fileName: songName
+          }
+        });
+        return;
+      }
+      showLoadingToast({ message: '正在保存', duration: 0 });
+      try {
+        html2canvas(downRef.value, {
+          backgroundColor: '#fff',
+          allowTaint: true,
+          useCORS: true
+        })
+          .then(async canvas => {
+            // 添加水印
+            const waterCanvasImg = await addWatermark(canvas);
+            // canvas转图片
+            const dataURL = await convasToImg(waterCanvasImg);
+            console.log(dataURL, 'dataURL');
+            setTimeout(() => {
+              showToast('已保存到相册');
+            }, 500);
+            await promisefiyPostMessage({
+              api: 'savePicture',
+              content: {
+                base64: dataURL
+              }
+            });
+          })
+          .catch(() => {
+            setTimeout(() => {
+              showToast('保存失败');
+            }, 500);
+          });
+      } catch (error) {
+        setTimeout(() => {
+          showToast('保存失败');
+        }, 500);
+      }
+    };
+
+    // 根据musicSheetType返回的值,判断是否显示切换声轨按钮
+    const isEnsemble = computed(() => {
+      if (item.value) {
+        const musicSheetType = item.value?.musicSheetType;
+        if (musicSheetType === 'SINGLE') {
+          return false;
+        } else {
+          return true;
+        }
+      } else {
+        return false;
+      }
+    });
+
+    // 判断 值当前有没有图片
+    const isMusicImg = computed(() => {
+      const musicsData = item.value;
+      if (data.showMusicImg === 'first' && musicsData?.musicFirstImg) {
+        return true;
+      }
+      if (data.showMusicImg === 'fixed' && musicsData?.musicJianImg) {
+        return true;
+      }
+      if (musicsData?.musicImg) {
+        return true;
+      }
+      return false;
+    });
+
+    // 判断是否可转谱 - 为空也可以转谱
+    const checkConverTible = (isConvertibleScore: any, scoreType: string) => {
+      if (
+        isConvertibleScore ||
+        isConvertibleScore === '' ||
+        isConvertibleScore === undefined ||
+        isConvertibleScore === null ||
+        (['JIAN', 'FIRST'].includes(scoreType) && !isConvertibleScore)
+      ) {
+        return true;
+      } else {
+        return false;
+      }
+    };
+
+    // 解析xml,获取分轨信息
+    const analyzeXml = async () => {
+      const details = item.value;
+      console.log(details?.musicSheetType, 'details?.musicSheetType');
+      if (details?.musicSheetType === 'CONCERT') {
+        if (details.xmlFileUrl) {
+          const res = await fetch(details.xmlFileUrl).then(response =>
+            response.text()
+          );
+          filterTracks(res);
+        }
+      } else {
+        // showMusicImg: 'first' as 'staff' | 'first' | 'fixed',
+        const { scoreType, isConvertibleScore } = details || {};
+        let musicImgType: 'staff' | 'first' | 'fixed' = 'first';
+        musicImgType =
+          scoreType === 'STAVE'
+            ? 'staff'
+            : scoreType === 'JIAN'
+            ? 'fixed'
+            : scoreType === 'FIRST'
+            ? 'first'
+            : 'first';
+        data.showMusicImg = musicImgType;
+        data.showTransBtn = checkConverTible(isConvertibleScore, scoreType);
+      }
+    };
+
+    /** 获取分轨名称 */
+    const getInstrumentNameCode = (instruments: any, name = '') => {
+      name = name.toLocaleLowerCase().replace(/ /g, '').replace(/\d*/gi, '');
+      if (!name) return '';
+      for (let key of instruments) {
+        const _key = key.toLocaleLowerCase().replace(/ /g, '');
+        // if (_key.includes(name)) {
+        //   return key
+        // }
+        if (_key === name) {
+          return _key;
+        }
+      }
+      // for (let key of instruments) {
+      //   const _key = key.toLocaleLowerCase().replace(/ /g, '')
+      //   if (name.includes(_key)) {
+      //     return key
+      //   }
+      // }
+      return '';
+    };
+    // 通过乐器编码返回乐器编号
+    const instrumentCodeToInstrumentId = (
+      subjectList: Array<any>,
+      code: string
+    ) => {
+      const codeIdMap = new Map<string, []>() as any;
+      const codeMapKeys: string[] = [];
+      subjectList.forEach((data: any) => {
+        if (data.enableFlag) {
+          const codes = data.code?.split(/[,,]/);
+          codes.forEach((code: string) => {
+            let codeTemp = code?.replace(/ /g, '').toLowerCase();
+            codeMapKeys.push(codeTemp);
+            if (codeIdMap.has(codeTemp)) {
+              codeIdMap.get(codeTemp).push(data.id + '');
+            } else {
+              const arr = [] as any;
+              arr.push(data.id + '');
+              codeIdMap.set(codeTemp, arr);
+            }
+          });
+        }
+      });
+
+      if (!code) {
+        return '';
+      }
+      code = code && code?.replace(/ /g, '').toLowerCase();
+      const tempCode = getInstrumentNameCode(codeMapKeys, code);
+      if (codeIdMap.has(tempCode)) {
+        const result = codeIdMap.get(tempCode);
+        console.log('result:', result);
+        return result[0] || '';
+      }
+      return '';
+    };
+
+    // 初始化编号
+    const initUserDefaultInstrument = () => {
+      const userInstrumentId = state.user.data.instrumentId;
+      const item = data.trackList.find(
+        (track: any) => track.instrumentId === userInstrumentId + ''
+      );
+      data.selectMusicInstrumentIndex = item ? item.value : 0;
+    };
+
+    // 过滤出能切换的分轨
+    const filterTracks = (xml: any) => {
+      const xmlParse = new DOMParser().parseFromString(xml, 'text/xml');
+      const partList: any =
+        xmlParse
+          .getElementsByTagName('part-list')?.[0]
+          ?.getElementsByTagName('score-part') || [];
+      const partListNames = Array.from(partList).map(
+        (item: any) =>
+          item.getElementsByTagName('part-name')?.[0]?.textContent?.trim() ||
+          item.getAttribute('id') ||
+          ''
+      );
+      const parts: any = xmlParse.getElementsByTagName('part');
+
+      /** 第一分谱如果是约定的配置分谱则跳过 */
+      if (partListNames[0]?.toLocaleUpperCase?.() === 'COMMON') {
+        partListNames.shift();
+      }
+      // 根据后台已选择的分轨筛选出能切换的声轨
+      const multiTracksSelection = item.value?.multiTracksSelection;
+      const canSelectTracks = multiTracksSelection
+        ? multiTracksSelection?.split(',')
+        : [];
+      const musicalInstruments = item.value?.musicalInstruments || [];
+      const arr = partListNames
+        .map((item: any, index: number) => {
+          // 该声轨能否被选
+          const canselect =
+            canSelectTracks.length == 0 || canSelectTracks.includes(item)
+              ? true
+              : false;
+
+          const instrumentName = getInstrumentName(item);
+          const instrumentId = instrumentCodeToInstrumentId(
+            musicalInstruments,
+            item
+          );
+          const sortId = sortMusical(instrumentName, index);
+          return {
+            text: item + (instrumentName ? `(${instrumentName})` : ''),
+            value: index,
+            instrumentId,
+            sortId,
+            canselect,
+            track: item
+          };
+        })
+        .filter((item: any) => item.canselect);
+      //.sort((a: any, b: any) => a.sortId - b.sortId);
+      data.trackList = arr;
+
+      // 是否显示总谱
+      const selectMusic = item.value;
+      if (selectMusic) {
+        const musicalInstruments = selectMusic.musicalInstruments || [];
+        if (selectMusic.isScoreRender) {
+          data.trackList.unshift({
+            text: '总谱',
+            value: 999,
+            sortId: 0,
+            canselect: true,
+            track: 999
+          });
+
+          if (selectMusic.defaultScoreRender) {
+            data.selectMusicInstrumentIndex = 999;
+          } else {
+            initUserDefaultInstrument();
+          }
+        } else {
+          initUserDefaultInstrument();
+        }
+      }
+
+      const details = item.value;
+      const { scoreType, isConvertibleScore } = details || {};
+      let musicImgType: 'staff' | 'first' | 'fixed' = 'first';
+      musicImgType =
+        scoreType === 'STAVE'
+          ? 'staff'
+          : scoreType === 'JIAN'
+          ? 'fixed'
+          : scoreType === 'FIRST'
+          ? 'first'
+          : 'first';
+      data.showMusicImg = musicImgType;
+      data.showTransBtn = checkConverTible(isConvertibleScore, scoreType);
+    };
+
+    const musicIframeLoad = () => {
+      const token = storage.get(ACCESS_TOKEN);
+      const details = item.value;
+      if (!details?.id) {
+        data.iframeSrc = '';
+        return;
+      }
+      // 如果在配置里面匹配不到,则默认显示五线谱
+      const musicRenderType =
+        data.showMusicImg === 'first'
+          ? 'firstTone'
+          : data.showMusicImg === 'fixed'
+          ? 'fixedTone'
+          : data.showMusicImg === 'staff'
+          ? 'staff'
+          : 'staff';
+
+      // pdf
+      const musicSheetType = details?.musicSheetType;
+      let musicPdfUrl = '';
+
+      if (
+        musicSheetType === 'SINGLE' ||
+        data.selectMusicInstrumentIndex === 999
+      ) {
+        if (data.showMusicImg === 'first') {
+          musicPdfUrl = details.firstPdfUrl;
+        } else if (data.showMusicImg === 'fixed') {
+          musicPdfUrl = details.jianPdfUrl;
+        } else {
+          musicPdfUrl = details.musicPdfUrl;
+        }
+      } else {
+        const trackList = data.trackList || [];
+        const selectTrack = trackList.find(
+          (item: any) => item.value === data.selectMusicInstrumentIndex
+        );
+        const background = details.background || [];
+        const selectItem = background.find(
+          (item: any) =>
+            item.track === selectTrack?.track && item.audioPlayType === 'PLAY'
+        );
+        if (selectItem) {
+          if (data.showMusicImg === 'first') {
+            musicPdfUrl = selectItem.firstPdfUrl;
+          } else if (data.showMusicImg === 'fixed') {
+            musicPdfUrl = selectItem.jianPdfUrl;
+          } else {
+            musicPdfUrl = selectItem.musicPdfUrl;
+          }
+        }
+      }
+      data.musicPdfUrl = musicPdfUrl;
+      if (musicPdfUrl) {
+        // data.iframeSrc = `/pdf/web/viewer.html?file=${encodeURIComponent(data.musicPdfUrl)}&t=${Date.now()}`;
+        data.iframeSrc = `${location.origin}${
+          location.pathname
+        }pdf/web/viewer.html?file=${encodeURIComponent(
+          data.musicPdfUrl
+        )}&t=${Date.now()}`;
+      } else {
+        // const origin = /(localhost|192)/.test(location.host)
+        // ? 'https://test.lexiaoya.cn'
+        // : location.origin;
+        // data.iframeSrc = `${origin}/instrument/?id=${details.id}&modelType=practise&modeType=json&Authorization=${token}&isPreView=true&part-index=${data.selectMusicInstrumentIndex}&musicRenderType=${musicRenderType}`;
+        data.iframeSrc = `${vaildMusicScoreUrl()}/instrument/?id=${
+          details?.id
+        }&modelType=practise&modeType=json&Authorization=${token}&isPreView=true&part-index=${
+          data.selectMusicInstrumentIndex
+        }&musicRenderType=${musicRenderType}&zoom=0.6`;
+      }
+
+      console.log('地址', data.iframeSrc);
+    };
+
+    const __init = async () => {
+      await analyzeXml();
+      musicIframeLoad();
+    };
+
+
+    /** 去云练习 */
+    const handleGoto = () => {
+      emit('handleGoto', item.value, data.showMusicImg, data.selectMusicInstrumentIndex)
+    };
+
+    onMounted(() => {
+      __init();
+    });
+    return () => (
+      <div class={styles.musicDetail}>
+        <div class={styles.musicContainer}>
+          <div class={styles.container} ref={downRef}>
+            <div
+              class={styles['right-musicName']}
+              style={{
+                opacity: !data.musicPdfUrl ? '1' : '0',
+                height: !data.musicPdfUrl ? 'auto' : '0'
+              }}>
+              {item.value?.musicSheetName}
+            </div>
+            {data.iframeSrc &&
+            (isEnsemble.value || data.musicPdfUrl || !isMusicImg.value) ? (
+              <div class={styles.iframeSection}>
+                <>
+                  {item.value?.id ? (
+                    data.musicPdfUrl ? (
+                      <iframe
+                        id="staffIframeRef"
+                        style={{
+                          width: '100%'
+                          // opacity: loading.value ? 0 : 1
+                        }}
+                        src={data.iframeSrc}></iframe>
+                    ) : (
+                      <iframe
+                        id="staffIframeRef"
+                        style={{
+                          width: '100%'
+                          // opacity: loading.value ? 0 : 1
+                        }}
+                        src={data.iframeSrc}></iframe>
+                    )
+                  ) : (
+                    ''
+                  )}
+                </>
+              </div>
+            ) : (
+              <div class={styles.imgSection}>
+                {data.showMusicImg === 'first' ? (
+                  <>
+                    {item.value?.musicFirstImg
+                      ?.split(',')
+                      .map((item: any, index: number) => {
+                        return (
+                          <img
+                            class={styles.staff}
+                            src={item}
+                            key={item}
+                            crossorigin="anonymous"
+                          />
+                        );
+                      })}
+                  </>
+                ) : data.showMusicImg === 'fixed' ? (
+                  <>
+                    <TransitionGroup name="van-fade">
+                      {item.value?.musicJianImg
+                        ?.split(',')
+                        .map((item: any, index: number) => {
+                          return (
+                            <img
+                              class={styles.staff}
+                              src={item}
+                              key={item}
+                              crossorigin="anonymous"
+                            />
+                          );
+                        })}
+                    </TransitionGroup>
+                  </>
+                ) : (
+                  <>
+                    {item.value?.musicImg
+                      ?.split(',')
+                      .map((item: any, index: number) => {
+                        return (
+                          <img
+                            class={styles.staff}
+                            src={item + '?v=' + Date.now()}
+                            key={item}
+                            crossorigin="anonymous"
+                          />
+                        );
+                      })}
+                  </>
+                )}
+              </div>
+            )}
+          </div>
+        </div>
+        <div class={styles.btnGroup}>
+          <div class={styles.operation}>
+            {isEnsemble.value && (
+              <Popover
+                v-model:show={data.showChangeVoice}
+                class={styles.popover}
+                actions={data.trackList}
+                placement="top-start"
+                onSelect={(item: any) => {
+                  console.log(item, 'item')
+                  // data.showMusicImg = item.value;
+                  data.showChangeVoice = false;
+                  // musicIframeLoad();
+                }}>
+                {{
+                  reference: () => (
+                    <div class={styles.item}>
+                      <img src={iconChange} class={styles.icon} />
+                      <span>声部</span>
+                    </div>
+                  )
+                }}
+              </Popover>
+            )}
+            {data.showTransBtn && (
+              <Popover
+                v-model:show={data.popoverShow}
+                class={styles.popover}
+                actions={_actions.value}
+                placement="top-start"
+                onSelect={(item: any) => {
+                  data.showMusicImg = item.value;
+                  data.popoverShow = false;
+                  musicIframeLoad();
+                }}>
+                {{
+                  reference: () => (
+                    <div class={styles.item}>
+                      <img src={iconStaff} class={styles.icon} />
+                      <span>转谱</span>
+                    </div>
+                  )
+                }}
+              </Popover>
+            )}
+            {!isEnsemble.value && (isMusicImg.value || data.musicPdfUrl) && (
+              <div class={styles.item} onClick={handleSave}>
+                <img src={iconDownload} class={styles.icon} />
+                <span>下载</span>
+              </div>
+            )}
+          </div>
+          <Button round class={styles.goBtn} onClick={handleGoto}>
+            立即练习
+          </Button>
+        </div>
+      </div>
+    );
+  }
+});