Browse Source

Merge branch 'feature-tianyong-newVersion' into ktyq-test-new

TIANYONG 7 months ago
parent
commit
67f4f20c0f
45 changed files with 417 additions and 159 deletions
  1. 4 2
      src/helpers/customMusicScore.ts
  2. 1 1
      src/page-instrument/component/authorName/index.module.less
  3. 1 0
      src/page-instrument/custom-plugins/helper-model/recommendation/index.module.less
  4. 2 2
      src/page-instrument/custom-plugins/helper-model/recommendation/index.tsx
  5. 3 0
      src/page-instrument/follow-model/index.module.less
  6. 2 1
      src/page-instrument/follow-model/index.tsx
  7. BIN
      src/page-instrument/header-top/image/headImg2.png
  8. BIN
      src/page-instrument/header-top/image/speedBtn.png
  9. 3 3
      src/page-instrument/header-top/index.module.less
  10. 18 9
      src/page-instrument/header-top/index.tsx
  11. 10 0
      src/page-instrument/header-top/settting/index.module.less
  12. 20 0
      src/page-instrument/header-top/settting/index.tsx
  13. 2 1
      src/page-instrument/header-top/speed/index.module.less
  14. BIN
      src/page-instrument/view-detail/images/bg1.png
  15. BIN
      src/page-instrument/view-detail/images/bg2.png
  16. BIN
      src/page-instrument/view-detail/images/bg2_left_zs.png
  17. BIN
      src/page-instrument/view-detail/images/bg2_right_zs.png
  18. BIN
      src/page-instrument/view-detail/images/bg3.png
  19. 0 0
      src/page-instrument/view-detail/images/index.json
  20. 15 0
      src/page-instrument/view-detail/index.module.less
  21. 63 31
      src/page-instrument/view-detail/index.tsx
  22. 2 1
      src/page-instrument/view-detail/smoothAnimation/index.ts
  23. BIN
      src/page-instrument/view-evaluat-report/component/share-top/image/icon-huifang.png
  24. BIN
      src/page-instrument/view-evaluat-report/component/share-top/image/icon-shiyi.png
  25. 2 2
      src/page-instrument/view-evaluat-report/component/share-top/index.module.less
  26. 9 18
      src/page-instrument/view-evaluat-report/component/share-top/index.tsx
  27. 27 7
      src/page-instrument/view-evaluat-report/index.module.less
  28. 16 7
      src/page-instrument/view-evaluat-report/index.tsx
  29. 107 31
      src/state.ts
  30. 3 1
      src/store.ts
  31. 1 1
      src/style.css
  32. 3 1
      src/view/abnormal-pop/index.module.less
  33. 50 7
      src/view/audio-list/index.tsx
  34. 11 11
      src/view/fingering/fingering-config.ts
  35. 0 0
      src/view/fingering/fingering-img/baroque-recorder/index.json
  36. 0 0
      src/view/fingering/fingering-img/ocarina/index.json
  37. 0 0
      src/view/fingering/fingering-img/piccolo/index.json
  38. 0 0
      src/view/fingering/fingering-img/whistling/index.json
  39. 7 1
      src/view/fingering/index.tsx
  40. 3 0
      src/view/music-score/index.module.less
  41. 7 0
      src/view/music-score/index.tsx
  42. 2 0
      src/view/plugins/toggleMusicSheet/index.tsx
  43. 14 14
      src/view/plugins/useDrag/index.module.less
  44. 7 6
      src/view/selection/index.module.less
  45. 2 1
      src/view/selection/index.tsx

+ 4 - 2
src/helpers/customMusicScore.ts

@@ -557,8 +557,10 @@ export const resetFormate = () => {
 					}
 				} catch (error) {}
 				const bbox = stave?.getBBox() || {};
-				const rect = `<rect class="vf-custom-bg" x="${bbox.x}" y="${bbox.y}" width="${bbox.width}" height="${bbox.height}" fill="#609FCF" />`
-				const rectBottom = `<rect class="vf-custom-bot" x="${bbox.x}" y="${bbox.y+bbox.height}" width="${bbox.width}" height="7.5" fill="#2B70A5" />`
+				const bgColor = state.isEvaluatReport ? '#132D4C' : '#609FCF';
+				const botColor = state.isEvaluatReport ? '#040D1E' : '#2B70A5';
+				const rect = `<rect class="vf-custom-bg" x="${bbox.x}" y="${bbox.y}" width="${bbox.width}" height="${bbox.height}" fill=${bgColor} />`
+				const rectBottom = `<rect class="vf-custom-bot" x="${bbox.x}" y="${bbox.y+bbox.height}" width="${bbox.width}" height="7.5" fill=${botColor} />`
 				// const filterDom = `<defs>
 				// 						<filter id="shadow">
 				// 						<feDropShadow dx="5" dy="5" stdDeviation="3" flood-color="black" />

+ 1 - 1
src/page-instrument/component/authorName/index.module.less

@@ -2,7 +2,7 @@
     height: 1.8rem;
 }
 .title{
-    width: 216px;
+    width: 280px;
     margin: 0 auto;
     :global{
         .van-notice-bar{

+ 1 - 0
src/page-instrument/custom-plugins/helper-model/recommendation/index.module.less

@@ -133,6 +133,7 @@
                                     background: #F2FAFF;
                                     border-radius: 8px;
                                     color: #1CACF1;
+                                    font-weight: 600;
                                 }
                                 .van-cell__value{
                                     display: none;

+ 2 - 2
src/page-instrument/custom-plugins/helper-model/recommendation/index.tsx

@@ -106,7 +106,7 @@ export default defineComponent({
 			getTypeList();
 		});
 		function beforeRead(file:any[]){
-			if(file.length > 5){
+			if(file.length + fileList.value.length > 5){
 				showToast(`最多只能选择5张图片`);
 			}
 			return true
@@ -123,7 +123,7 @@ export default defineComponent({
 							<DropdownMenu class={[styles.dropdownMenu, currItem.value && styles.currItem]} overlay={false}>
 								<DropdownItem class={['recommendationDropdownItem']} title={ currItem.value?currItem.value.name:"请选择反馈类型"} v-model={recommenData.suggestId} options={suggestionTypeList.value}/>
 							</DropdownMenu>
-							<div class={styles.tit}>{`${recommenData.message.length}/200`}</div>
+							<div class={styles.tit}>{`${recommenData.message.length >= 200 ? 200 : recommenData.message.length }/200`}</div>
 						</div>
 						<Field
 							class={styles.field}

+ 3 - 0
src/page-instrument/follow-model/index.module.less

@@ -84,6 +84,9 @@
           margin-left: 20px;
       }
   }
+  &.operatingLeft {
+    left: 30px !important;
+  }
 }
 .beginMask{
   position: fixed;

+ 2 - 1
src/page-instrument/follow-model/index.tsx

@@ -41,12 +41,13 @@ export default defineComponent({
         {
           followData.isBeginMask && <div class={styles.beginMask}></div>
         }        
-        <div class={styles.operatingBtn}>
+        <div class={[styles.operatingBtn, state.playBtnDirection === "left" ? styles.operatingLeft : ""]}>
           {!followData.start && (
             <img
               class={[styles.iconBtn, "follow-1"]}
               src={headImg("icon_play.png")}
               onClick={() => {
+                followData.start = true;
                 handleFollowStart();
               }}
             />

BIN
src/page-instrument/header-top/image/headImg2.png


BIN
src/page-instrument/header-top/image/speedBtn.png


+ 3 - 3
src/page-instrument/header-top/index.module.less

@@ -364,7 +364,7 @@
     }
 
     &.pauseRightButton {
-        right: 88px !important;
+        right: 108px !important;
         left: auto !important;
         bottom: 12px !important;
     }
@@ -450,6 +450,6 @@
     opacity: 0;
 }
 
-.socketErrorStatus {
-    top: 10vh;
+.socketErrorStatus{
+    top: 20vh;
 }

+ 18 - 9
src/page-instrument/header-top/index.tsx

@@ -358,6 +358,8 @@ export default defineComponent({
 
     /** 原声按钮 */
     const originBtn = computed(() => {
+      // 没有音源不显示
+      if(state.noMusicSource) return { display: false, disabled: false };
       // 选择模式,跟练模式 不显示
       if (headTopData.modeType !== "show" || state.modeType === "follow") return { display: false, disabled: false };
       // 评测开始 禁用
@@ -414,6 +416,8 @@ export default defineComponent({
     });
     /** 模式切换按钮 */
     const toggleBtn = computed(() => {
+      // 没有音源不显示
+      if(state.noMusicSource) return { display: false, disabled: false };
       // 不是演奏模式 影藏
       if (state.playType !== "play") return { display: false, disabled: false };
       // 选择模式, url设置模式 不显示
@@ -429,6 +433,8 @@ export default defineComponent({
 
     /** 播放按钮 */
     const playBtn = computed(() => {
+      // 没有音源不显示
+      if(state.noMusicSource) return { display: false, disabled: false };
       // 选择模式 不显示
       if (headTopData.modeType !== "show") return { display: false, disabled: false };
       // 评测模式 不显示,跟练模式 不显示
@@ -443,6 +449,8 @@ export default defineComponent({
 
     /** 重播按钮 */
     resetBtn = computed(() => {
+      // 没有音源不显示
+      if(state.noMusicSource) return { display: false, disabled: false };
       // 选择模式 不显示
       if (headTopData.modeType !== "show") return { display: false, disabled: false };
       // 评测模式 不显示,跟练模式 不显示
@@ -627,7 +635,7 @@ export default defineComponent({
     return () => (
       <>
         <div
-          class={[styles.headerTop, state.platform === IPlatform.PC && state.musicScoreBtnDirection === "left" ? styles.headerTopRight : ""]}
+          class={[styles.headerTop]}
           onClick={(e: Event) => {
             e.stopPropagation();
             if (state.platform === IPlatform.PC) {
@@ -693,12 +701,13 @@ export default defineComponent({
           }
 
           {/* 模式提醒 */}
-          {state.modeType === "practise" && (
-            <div class={[styles.modeWarn, "practiseModeWarn", state.platform === IPlatform.PC && state.musicScoreBtnDirection === "left" ? styles.modeWarnRight : ""]}>
-              <img src={state.playType === "play" ? headImg("perform1.png") : headImg("sing1.png")} />
-              <div>{state.playType === "play" ? "演奏场景" : "演唱场景"}</div>
-            </div>
-          )}
+          {
+            state.modeType === "practise" &&
+              <div class={[styles.modeWarn, "practiseModeWarn"]}>
+                <img src={state.playType === "play" ? headImg("perform1.png") : headImg("sing1.png")} />
+                <div>{state.playType === "play" ? "演奏场景" : "演唱场景"}</div>
+              </div>
+          }
           {/* 功能按钮 */}
           <div
             class={[styles.headRight]}
@@ -895,7 +904,7 @@ export default defineComponent({
             "driver-1",
             styles.playBtn,
             playBtn.value.disabled && styles.disabled,
-            state.platform === IPlatform.PC && state.musicScoreBtnDirection === "left" ? styles.playLeftButton : state.platform === IPlatform.PC && state.musicScoreBtnDirection === "right" ? styles.playRightButton : "",
+            // state.platform === IPlatform.PC && state.musicScoreBtnDirection === "left" ? styles.playLeftButton : state.platform === IPlatform.PC && state.musicScoreBtnDirection === "right" ? styles.playRightButton : "",
           ]}
           onClick={() => togglePlay(state.playState === "play" ? "paused" : "play")}
         >
@@ -910,7 +919,7 @@ export default defineComponent({
         <div
           id="tips-step-9"
           style={{ display: resetBtn.value.display ? "" : "none" }}
-          class={[styles.resetBtn, resetBtn.value.disabled && styles.disabled, state.platform === IPlatform.PC && state.musicScoreBtnDirection === "left" ? styles.pauseLeftButton : state.platform === IPlatform.PC && state.musicScoreBtnDirection === "right" ? styles.pauseRightButton : ""]}
+          class={[styles.resetBtn, resetBtn.value.disabled && styles.disabled]}
           onClick={() => handleResetPlay()}
         >
           <img class={styles.iconBtn} src={headImg("icon_reset.png")} />

+ 10 - 0
src/page-instrument/header-top/settting/index.module.less

@@ -17,8 +17,18 @@
     }
     &.evaluating{
         .head{
+            width: 394px;
+            height: 62px;
+            margin-bottom: -3px;
             background: url("../image/headImg2.png") no-repeat;
             background-size: 100% 100%; 
+            .headTit{
+                bottom: 11px;
+            }
+            .closeImg{
+                top: 2px;
+                right: -26px;
+            }
         }
         .content{
             background: #B0CDFF;

+ 20 - 0
src/page-instrument/header-top/settting/index.tsx

@@ -11,6 +11,7 @@ import { resetRenderMusicScore } from "/src/view/music-score";
 import ScreenModel from "../../custom-plugins/helper-model/screen-model";
 import { getQuery } from "/src/utils/queryString";
 import { reCheckDelay } from "/src/page-instrument/evaluat-model"
+import { audioData, changeMingSongType } from "/src/view/audio-list"
 
 export default defineComponent({
 	name: "settting",
@@ -61,6 +62,25 @@ export default defineComponent({
                                     <div class={styles.tit}>循环播放</div>
                                     <Switch v-model={state.setting.repeatAutoPlay}></Switch>
                                 </div>
+                        }                        
+                        {
+                            state.modeType === 'practise' && state.mingSong && state.mingSongGirl &&
+                            <div class={styles.cellBox}>
+                                <div class={styles.tit}>唱名类型</div>
+                                <div class={styles.radioBox}>
+                                    {
+                                        [{name:'男生',value:1}, {name:'女生',value:0}].map(item=>{
+                                            return <div class={ audioData.mingSongType===item.value && styles.active } onClick={ ()=>{ 
+                                                if(audioData.mingSongType === item.value){
+                                                    return
+                                                }
+                                                audioData.mingSongType = item.value as 0|1
+                                                changeMingSongType()
+                                            } }>{item.name}</div>
+                                        })
+                                    }
+                                </div>
+                            </div>                     
                         }
                         {
                             state.isSingleLine && state.modeType === "practise" && !state.isCombineRender && !state.isPercussion && 

+ 2 - 1
src/page-instrument/header-top/speed/index.module.less

@@ -120,6 +120,7 @@
                                     height: 4px;
                                     background: url("../image/gg.png") no-repeat;
                                     background-size: 100% 100%;
+                                    transform: translate(-20%,-20%);
                                 }
                                 .van-slider__button-wrapper{
                                     bottom: 0;
@@ -146,7 +147,7 @@
                             padding-top: 3px;
                         }
                         .speedBtn{
-                            width: 16px;
+                            width: 20px;
                             height: 30px;
                             background: url("../image/speedBtn.png") no-repeat;
                             background-size: 100% 100%;

BIN
src/page-instrument/view-detail/images/bg1.png


BIN
src/page-instrument/view-detail/images/bg2.png


BIN
src/page-instrument/view-detail/images/bg2_left_zs.png


BIN
src/page-instrument/view-detail/images/bg2_right_zs.png


BIN
src/page-instrument/view-detail/images/bg3.png


File diff suppressed because it is too large
+ 0 - 0
src/page-instrument/view-detail/images/index.json


+ 15 - 0
src/page-instrument/view-detail/index.module.less

@@ -267,4 +267,19 @@
         font-size: 14px;
         color: #fff;
     }
+}
+
+.bg2Left {
+    width: 52px;
+    height: 125px;
+    position: absolute;
+    left: 0;
+    top: 0;
+}
+.bg2Right {
+    width: 52px;
+    height: 125px;
+    position: absolute;
+    right: 0;
+    top: 0;
 }

+ 63 - 31
src/page-instrument/view-detail/index.tsx

@@ -39,6 +39,8 @@ import EmptyMusic, { isEmptyMusicShow } from "./emptyMusic";
 import { position } from "html2canvas/dist/types/css/property-descriptors/position";
 import Loading from "./loading";
 import bgJson from "./images/index.json";
+import bg2Left from "./images/bg2_left_zs.png";
+import bg2Right from "./images/bg2_right_zs.png";
 
 // const DelayCheck = defineAsyncComponent(() =>
 //   import('/src/page-instrument/evaluat-model/delay-check')
@@ -317,35 +319,47 @@ export default defineComponent({
         } else {
           console.log("指法", state.playBtnDirection, state.platform);
           // 老师端,竖向指法,需要根据功能按钮方向进行设置
-          if (state.platform === IPlatform.PC) {
-            return {
-              container: {
-                paddingRight: state.playBtnDirection === "right" ? "initial" : state.fingeringInfo.width,
-                paddingLeft: state.playBtnDirection === "right" ? state.fingeringInfo.width : "initial",
-              },
-              fingerBox: {
-                position: "absolute",
-                width: state.fingeringInfo.width,
-                height: "80%",
-                right: state.playBtnDirection === "right" ? "initial" : 0,
-                left: state.playBtnDirection === "right" ? 0 : "initial",
-                top: 0,
-              },
-            };
-          } else {
-            return {
-              container: {
-                paddingLeft: state.fingeringInfo.width,
-              },
-              fingerBox: {
-                position: "absolute",
-                width: state.fingeringInfo.width,
-                height: "80%",
-                left: 0,
-                top: 0,
-              },
-            };
-          }
+          // if (state.platform === IPlatform.PC) {
+          //   return {
+          //     container: {
+          //       paddingRight: state.playBtnDirection === "right" ? "initial" : state.fingeringInfo.width,
+          //       paddingLeft: state.playBtnDirection === "right" ? state.fingeringInfo.width : "initial",
+          //     },
+          //     fingerBox: {
+          //       position: "absolute",
+          //       width: state.fingeringInfo.width,
+          //       height: state.fingeringInfo.name === "hulusi-flute" ? "86%" : "80%",
+          //       right: state.playBtnDirection === "right" ? "initial" : 0,
+          //       left: state.playBtnDirection === "right" ? 0 : "initial",
+          //       top: state.fingeringInfo.name === "ocarina" ? "60px" : 0,
+          //     },
+          //   };
+          // } else {
+          //   return {
+          //     container: {
+          //       paddingLeft: state.fingeringInfo.width,
+          //     },
+          //     fingerBox: {
+          //       position: "absolute",
+          //       width: state.fingeringInfo.width,
+          //       height: state.fingeringInfo.name === "hulusi-flute" ? "86%" : "80%",
+          //       left: 0,
+          //       top: state.fingeringInfo.name === "ocarina" ? "60px" : 0,
+          //     },
+          //   };
+          // }
+          return {
+            container: {
+              paddingLeft: state.fingeringInfo.width,
+            },
+            fingerBox: {
+              position: "absolute",
+              width: state.fingeringInfo.width,
+              height: state.fingeringInfo.name === "hulusi-flute" ? "86%" : "80%",
+              left: 0,
+              top: state.fingeringInfo.name === "ocarina" ? "60px" : 0,
+            },
+          };
         }
       }
       return {
@@ -395,6 +409,13 @@ export default defineComponent({
         sendParentMessage(state.playState);
       }
     );
+    // 监听跟练的开启状态
+    watch(
+      () => followData.start,
+      () => {
+        detailData.headerHide = followData.start;
+      }
+    );
     /** 指法预览切换 */
     watch(
       () => detailData.fingerPreView,
@@ -463,7 +484,17 @@ export default defineComponent({
           background: state.setting.camera ? `rgba(${state.setting.eyeProtection ? "253,244,229" : "255,255,255"} ,${state.setting.cameraOpacity / 100}) !important` : "",
         }}
       >
-        <img style={{ opacity: state.setting.camera && state.modeType === "evaluating" ? state.setting.cameraOpacity / 100 : 1 }} class={styles.pageBg} src={state.modeType === "practise" ? bgJson[1] : state.modeType === "evaluating" ? bgJson[2] : state.modeType === "follow" ? bgJson[3] : ""} />
+        <img 
+          style={{opacity: state.setting.camera && state.modeType === 'evaluating' ? state.setting.cameraOpacity / 100 : 1}} 
+          class={styles.pageBg} 
+          src={state.modeType === 'practise' ? bgJson[1] : state.modeType === 'evaluating' ? bgJson[2] : state.modeType === 'follow' ? bgJson[3] : ''} 
+        />
+        {
+          state.modeType === 'evaluating' ? <>
+            <img src={bg2Left} class={styles.bg2Left} />
+            <img src={bg2Right} class={styles.bg2Right} />
+          </> : null
+        }
         {/* 骨架屏 */}
         {/* <Transition name="van-fade">
           {detailData.skeletonLoading && (
@@ -485,7 +516,8 @@ export default defineComponent({
             // if (state.playState === "play" && state.platform != IPlatform.PC) {
             //   detailData.headerHide = !detailData.headerHide;
             // }
-            if (state.playState === "play") {
+            // 点击谱面跟练也需要切换显示按钮栏
+            if (state.playState === "play" || followData.start) {
               detailData.headerHide = !detailData.headerHide;
             }
           }}

+ 2 - 1
src/page-instrument/view-detail/smoothAnimation/index.ts

@@ -186,7 +186,8 @@ export function moveSmoothAnimation(progress: number, activeIndex: number, isMov
  * 谱面移动逻辑
  */
 function move_osmd(nowPointsPos: pointsPosType[0]) {
-   const speed = smoothAnimationState.aveSpeed * (state.speed / 60)
+   // 评测移动太快看不到前面小节的分数,评测改成0.5倍速移动谱面
+   const speed = (state.modeType === 'evaluating' ? smoothAnimationState.aveSpeed * 0.5 : smoothAnimationState.aveSpeed) * (state.speed / 60)
    // 视口宽度
    const clientWidth = smoothAnimationState.osdmScrollDomWith
    const clientMidWidth = clientWidth / 2

BIN
src/page-instrument/view-evaluat-report/component/share-top/image/icon-huifang.png


BIN
src/page-instrument/view-evaluat-report/component/share-top/image/icon-shiyi.png


+ 2 - 2
src/page-instrument/view-evaluat-report/component/share-top/index.module.less

@@ -48,7 +48,7 @@
             line-height: 20px;
             margin-bottom: 2px;
             padding: 0 !important;
-
+            width: 200px;
             :global {
                 .van-notice-bar {
                     height: 20px;
@@ -227,7 +227,7 @@
     box-shadow: inset 4px -3px 6px 0px #B2E8FF;
     border-radius: 20px;
     padding: 14px;
-
+    overflow: hidden;
     :global {
         .plyr {
             border-radius: 16px;

+ 9 - 18
src/page-instrument/view-evaluat-report/component/share-top/index.tsx

@@ -4,8 +4,8 @@ import styles from "./index.module.less";
 import { api_back } from "/src/helpers/communication";
 import state from "/src/state";
 import iconBack from "./image/back_icon.png";
-import iconShiyi from "./image/icon-shiyi.svg";
-import iconhuifang from "./image/icon-huifang.svg";
+import iconShiyi from "./image/icon-shiyi.png";
+import iconhuifang from "./image/icon-huifang.png";
 import shiyiTop from "./image/shiyi-top.png";
 import shiyiClose from "./image/closeImg.png";
 import { Grid, GridItem, Popup } from "vant";
@@ -42,9 +42,6 @@ export default defineComponent({
       isInitPlyr: false,
       _plrl: null as any,
     });
-    const lottieDom = ref<any>();
-    const lottieDom1 = ref<any>();
-    const lottieDom2 = ref<any>();
     const level: any = {
       BEGINNER: "入门级",
       ADVANCED: "进阶级",
@@ -56,7 +53,7 @@ export default defineComponent({
       low: "#FFB900",
       right: "#65FFAE",
       wrong: "#DA3736",
-      lack: "#A5CBFF",
+      lack: "#7AB2FF",
       not: "#FFFFFF",
       fast: "#B366FF",
       slow: "#FF7B00",
@@ -100,15 +97,9 @@ export default defineComponent({
 						const canvasDom = document.querySelector("#audioVisualizer") as HTMLCanvasElement
 						const { pauseVisualDraw, playVisualDraw } = audioVisualDraw(audioDom, canvasDom)
 						shareData._plrl.on('play', () => {
-							lottieDom.value?.play()
-							lottieDom1.value?.play()
-							lottieDom2.value?.play()
 							playVisualDraw()
 						});
 						shareData._plrl.on('pause', () => {
-							lottieDom.value?.pause()
-							lottieDom1.value?.pause()
-							lottieDom2.value?.pause()
 							pauseVisualDraw()
 						});
 					}, 300); // 弹窗动画是0.25秒 这里用定时器 确保canvas 能获取到宽高
@@ -230,7 +221,7 @@ export default defineComponent({
               {/* <div class={styles.lcName}>{state.examSongName}</div> */}
               <Title class={styles.lcName} text={state.examSongName} rightView={false} />
               <div class={styles.lcScore}>
-                {level[scoreData.value.heardLevel]}|速度:{scoreData.value.speed}|综合分数:{scoreData.value.score}分
+                {level[scoreData.value.heardLevel]}|速度:{Math.floor(scoreData.value.speed)}|综合分数:{scoreData.value.score}分
               </div>
             </div>
           </div>
@@ -352,7 +343,7 @@ export default defineComponent({
 
                   {itemType.value === "integrity" && (
                     <div>
-                      <Note fill="#A5CBFF" />
+                      <Note fill="#7AB2FF" />
                       <span>时值不足</span>
                     </div>
                   )}
@@ -444,9 +435,9 @@ export default defineComponent({
               {mediaType.value === "audio" ? (
                 <div class={styles.audioBox}>
                   <canvas class={styles.audioVisualizer} id="audioVisualizer"></canvas>
-                  <Vue3Lottie ref={lottieDom} class={styles.audioBga} animationData={audioBga} autoPlay={false} loop={true}></Vue3Lottie>
-                  <Vue3Lottie ref={lottieDom1} class={styles.audioBga1} animationData={audioBga1} autoPlay={false} loop={true}></Vue3Lottie>
-                  <Vue3Lottie ref={lottieDom2} class={styles.audioBga2} animationData={audioBga2} autoPlay={false} loop={true}></Vue3Lottie>
+                  <Vue3Lottie class={styles.audioBga} animationData={audioBga} autoPlay={false} loop={true}></Vue3Lottie>
+                  <Vue3Lottie class={styles.audioBga1} animationData={audioBga1} autoPlay={false} loop={true}></Vue3Lottie>
+                  <Vue3Lottie class={styles.audioBga2} animationData={audioBga2} autoPlay={false} loop={true}></Vue3Lottie>
                   <audio crossorigin="anonymous" id="audioSrc" src={scoreData.value.videoFilePath} controls="false" preload="metadata" playsinline />
                 </div>
               ) : (
@@ -484,7 +475,7 @@ export default defineComponent({
                     <span>紫色音符:节奏偏快</span>
                   </div>
                   <div class={styles.item}>
-                    <Note fill="#A5CBFF" />
+                    <Note fill="#7AB2FF" />
                     <span>浅蓝色音符:时值不足</span>
                   </div>
                   <div class={styles.item}>

+ 27 - 7
src/page-instrument/view-evaluat-report/index.module.less

@@ -28,9 +28,14 @@
   min-height: 100vh;
   --header-height: 62px;
   // background: rgba(248, 242, 232, 1);
-  background: url("../view-detail/images/bg2.png") no-repeat;
-  background-size: 100% 100%;
-
+  .pageBg {
+    position: absolute;
+    left: 0;
+    top: 0;
+    width: 100%;
+    height: 100%;
+    object-fit: cover; /* 保持宽高比 */
+  }
   :global {
 
     #cursorImg-0 {
@@ -87,8 +92,8 @@
 
 .beam {
   path {
-    fill: #ADADAD !important;
-    stroke: #ADADAD;
+    // fill: #ADADAD !important;
+    // stroke: #ADADAD;
   }
 }
 
@@ -171,8 +176,8 @@
 // 完成度
 .integrity_wrong {
   path {
-    fill: #A5CBFF;
-    stroke: #A5CBFF;
+    fill: #7AB2FF;
+    stroke: #7AB2FF;
   }
 }
 
@@ -181,4 +186,19 @@
   opacity: 0;
   width: 1;
   height: 1;
+}
+
+.bg2Left {
+  width: 52px;
+  height: 125px;
+  position: absolute;
+  left: 0;
+  top: 0;
+}
+.bg2Right {
+  width: 52px;
+  height: 125px;
+  position: absolute;
+  right: 0;
+  top: 0;
 }

+ 16 - 7
src/page-instrument/view-evaluat-report/index.tsx

@@ -16,6 +16,9 @@ import TopArrow from "./component/note/topArrow";
 import BottomArrow from "./component/note/bottomArrow";
 import LeftArrow from "./component/note/leftArrow";
 import RightArrow from "./component/note/rightArrow";
+import bgJson from "/src/page-instrument/view-detail/images/index.json";
+import bg2Left from "/src/page-instrument/view-detail/images/bg2_left_zs.png";
+import bg2Right from "/src/page-instrument/view-detail/images/bg2_right_zs.png";
 
 const colorsClass: any = {
   RIGHT: styles.right, // 正确
@@ -294,13 +297,13 @@ export default defineComponent({
           svgEl?.classList.add(colorsClass[errType]);
           // console.log(123456,'添加颜色',errType)
           // 评测过的音符,需要给小节添加背景色
-          if (errType !== "NOT_PLAYED") {
-            const staveNote = svgEl?.parentNode?.parentNode?.querySelector(".vf-stave");
-            if (staveNote) {
-              staveNote.querySelector(".vf-custom-bg")?.setAttribute("fill", "#132D4C");
-              staveNote.querySelector(".vf-custom-bot")?.setAttribute("fill", "#040D1E");
-            }
-          }
+          // if (errType !== "NOT_PLAYED") {
+          //   const staveNote = svgEl?.parentNode?.parentNode?.querySelector(".vf-stave");
+          //   if (staveNote) {
+          //     staveNote.querySelector(".vf-custom-bg")?.setAttribute("fill", "#132D4C");
+          //     staveNote.querySelector(".vf-custom-bot")?.setAttribute("fill", "#040D1E");
+          //   }
+          // }
           if (svgEl && isNeedCopyElement) {
             stemEl?.classList.remove(colorsClass[errType]);
             svgEl?.classList.remove(colorsClass[errType]);
@@ -426,6 +429,12 @@ export default defineComponent({
     );
     return () => (
       <div class={[styles.detail, state.setting.eyeProtection && "eyeProtection", styles.shareBox]} style={{ paddingLeft: detailData.paddingLeft }}>
+        <img 
+          class={styles.pageBg} 
+          src={bgJson[2]} 
+        />
+        <img src={bg2Left} class={styles.bg2Left} />
+        <img src={bg2Right} class={styles.bg2Right} />       
         <Transition name="van-fade">
           {!state.musicRendered && (
             <div class={styles.skeleton}>

+ 107 - 31
src/state.ts

@@ -333,13 +333,16 @@ const state = reactive({
   banSong: "",
   /** 唱名 */
   mingSong: "",
+  /** 唱名女 如果有男唱名的情况下*/
+  mingSongGirl:"",
   /** 节拍器音乐资源 */
   beatSong: {
     music: "",
     accompany: "",
     fanSong: "",
     banSong: "",
-    mingSong: ""
+    mingSong: "",
+    mingSongGirl: ""
   },
   /** midiURL */
   midiUrl: "",
@@ -481,7 +484,13 @@ const state = reactive({
   /** 乐器code,用于评测传参 */
   musicalCode: '' as any,
   /** 合奏曲目是否合并展示 */
-  isCombineRender: false,
+  isCombineRender: false,  
+  /** 是否支持总谱 */
+  isScoreRender: false,  
+  /** 是否默认显示总谱 */
+  defaultScoreRender: false,
+  /** 没有音源字段 */
+  noMusicSource: false,
   /** 小节的持续时长,以后台设置的播放速度计算 */
   measureTime: 0,
   /** 跟练模式,节拍器播放的时间 */
@@ -1313,17 +1322,20 @@ export const getMusicDetail = async (id: string, type?: string) => {
 
 
 const getMusicInfo = async (res: any) => {
+  // 是否支持总谱
+  state.isScoreRender = res.data?.isScoreRender
+  // 是否默认显示总谱
+  state.defaultScoreRender = res.data?.defaultScoreRender
+  const partIndex = query["part-index"] ? parseInt(query["part-index"]) : -1 // -1为partIndex没有值的时候
+  /* 获取声轨列表 */
   const xmlString = await fetch(res.data.xmlFileUrl).then((response) => response.text());
   downloadXmlStr.value = xmlString //给musice-score 赋值xmlString 以免加载2次
   const tracks = xmlToTracks(xmlString) //获取声轨列表
-  let index = query["part-index"] ? parseInt(query["part-index"]) : 0
-  const musicObj = state.isSimplePage ? {} : initMusicSource(res.data, tracks[index]) //当前part-index找不到声源的时候以第一个为准
-  index = tracks.findIndex(item => {  // 筛选出当前的index
-    return item === musicObj?.track
-  })
+  // 设置音源  track 为当前的声轨 index为当前的
+  const { track, index } = state.isSimplePage ? { track:tracks[0], index:0} : initMusicSource(res.data, tracks, partIndex)
   const musicInfo = {
     ...res.data,
-    track: musicObj?.track
+    track
   };
   console.log("🚀 ~ musicInfo:", musicInfo);
   setState(musicInfo, index);
@@ -1341,15 +1353,16 @@ function xmlToTracks(xmlString: string) {
   }, []);
 }
 // 设置音源
-function initMusicSource(data: any, track?: string) {
+function initMusicSource(data: any, tracks: string[], partIndex: number) {
+  let track:string,index:number
   const { instrumentId } = storeData.user
   let { musicSheetType, isAllSubject, musicSheetSoundList, musicSheetAccompanimentList } = data
   musicSheetSoundList || (musicSheetSoundList = [])
   musicSheetAccompanimentList || (musicSheetAccompanimentList = [])
   let musicObj, accompanyObj, fanSongObj, banSongObj
-  // 独奏
+   /* 独奏 */
   if (musicSheetType === "SINGLE") {
-    // 适用声部(instrumentId)为true 时候没有乐器只有一个原音;当前用户有乐器就匹配  不然取第一个原音
+    // 适用声部(isAllSubject)为true 时候没有乐器只有一个原音;当前用户有乐器就匹配  不然取第一个原音
     musicObj = musicSheetSoundList.find((item: any) => {
       return (isAllSubject || !instrumentId) ? item.audioPlayType === "PLAY" : (item.audioPlayType === "PLAY" && item.musicalInstrumentId == instrumentId)
     })
@@ -1363,22 +1376,70 @@ function initMusicSource(data: any, track?: string) {
     banSongObj = musicSheetAccompanimentList.find((item: any) => {
       return item.audioPlayType === "SING"
     })
+    accompanyObj = musicSheetAccompanimentList.find((item: any) => {
+      return item.audioPlayType === "PLAY"
+    })
+    track = musicObj?.track   //没有原音的时候track为空 不显示指法
+    index = tracks.findIndex(item => {
+      return item === track
+    })
   } else {
-    // 合奏  合奏根据声轨来区分原音
-    musicObj = track ? musicSheetSoundList.find((item: any) => {
-      return item.track === track
-    }) : musicSheetSoundList[0]
+    /* 合奏 */
+    // 支持总谱 并且当前是总谱。partIndex是999时候,或者默认是总谱并且partIndex为-1时候  -1就是partIndex没有值
+    if(state.isScoreRender && (partIndex===999 || (state.defaultScoreRender && partIndex===-1))){
+        // 总谱渲染
+        state.isCombineRender = true
+        state.partListNames = tracks
+        banSongObj = musicSheetAccompanimentList.find((item: any) => {
+          return item.audioPlayType === "SING"
+        })
+        // 先取scoreAudioFileUrl的值
+        if(banSongObj?.scoreAudioFileUrl){
+          banSongObj.audioFileUrl = banSongObj.scoreAudioFileUrl
+          banSongObj.audioBeatMixUrl = banSongObj.scoreAudioBeatMixUrl
+        }
+        accompanyObj = musicSheetAccompanimentList.find((item: any) => {
+          return item.audioPlayType === "PLAY"
+        })
+        // 先取scoreAudioFileUrl的值
+        if(accompanyObj?.scoreAudioFileUrl){
+          accompanyObj.audioFileUrl = accompanyObj.scoreAudioFileUrl
+          accompanyObj.audioBeatMixUrl = accompanyObj.scoreAudioBeatMixUrl
+        }
+        track = "总谱"
+        index = 999
+    }else{
+      // 合奏只显示一个声轨
+      track = tracks[partIndex===-1?0:partIndex]
+      // 根据当前的声轨 取数据
+      musicObj = musicSheetSoundList.find((item: any) => {
+        return item.audioPlayType === "PLAY" && item.track === track
+      })
+      fanSongObj = musicSheetSoundList.find((item: any) => {
+        return item.audioPlayType === "SING" && item.track === track
+      })
+      banSongObj = musicSheetAccompanimentList.find((item: any) => {
+        return item.audioPlayType === "SING"
+      })
+      accompanyObj = musicSheetAccompanimentList.find((item: any) => {
+        return item.audioPlayType === "PLAY"
+      })
+      index = tracks.findIndex(item => {
+        return item === track
+      })
+    }
   }
-  accompanyObj = musicSheetAccompanimentList.find((item: any) => {
-    return item.audioPlayType === "PLAY"
-  })
   // 当没有任何曲目的时候报错
-  if (!musicObj?.audioFileUrl && !accompanyObj?.audioFileUrl && !fanSongObj?.audioFileUrl && !banSongObj?.audioFileUrl && !fanSongObj?.solmizationFileUrl) {
-    // 并且是midi没有midi文件的时候
-    if(data.playMode === "MIDI" && !data.midiFileUrl) {
-      // 是预览的时候 不报错
-      if(!query.isPreView){
-        throw new Error("该曲目无任何音源");
+  if (!musicObj?.audioFileUrl && !accompanyObj?.audioFileUrl && !fanSongObj?.audioFileUrl && !banSongObj?.audioFileUrl && !fanSongObj?.solmizationFileUrl && !fanSongObj?.femaleSolmizationFileUrl) {
+    state.noMusicSource = true // 没有音源文件
+    // 独奏的时候
+    if(musicSheetType === "SINGLE"){
+      // 并且是midi没有midi文件的时候
+      if(data.playMode === "MIDI" && !data.midiFileUrl) {
+        // 是预览的时候 不报错
+        if(!query.isPreView){
+          throw new Error("该曲目无任何音源");
+        }
       }
     }
   }
@@ -1387,16 +1448,31 @@ function initMusicSource(data: any, track?: string) {
     accompany: accompanyObj?.audioFileUrl,
     fanSong: fanSongObj?.audioFileUrl,
     banSong: banSongObj?.audioFileUrl,
-    mingSong: fanSongObj?.solmizationFileUrl
   })
+  // 如果没有男唱名
+  if(!fanSongObj?.solmizationFileUrl){
+    state.mingSong = fanSongObj?.femaleSolmizationFileUrl
+  }else{
+    state.mingSong = fanSongObj?.solmizationFileUrl
+    state.mingSongGirl = fanSongObj?.femaleSolmizationFileUrl
+  }
   Object.assign(state.beatSong, {
     music: musicObj?.audioBeatMixUrl,
     accompany: accompanyObj?.audioBeatMixUrl,
     fanSong: fanSongObj?.audioBeatMixUrl,
-    banSong: banSongObj?.audioBeatMixUrl,
-    mingSong: fanSongObj?.solmizationBeatUrl
+    banSong: banSongObj?.audioBeatMixUrl
   })
-  return musicObj
+  // 如果没有男唱名
+  if(!fanSongObj?.solmizationBeatUrl){
+    state.beatSong.mingSong = fanSongObj?.femaleSolmizationBeatUrl
+  }else{
+    state.beatSong.mingSong = fanSongObj?.solmizationBeatUrl
+    state.beatSong.mingSongGirl = fanSongObj?.femaleSolmizationBeatUrl
+  }
+  return {
+    index,
+    track
+  }
 }
 const setState = (data: any, index: number) => {
   // 根据当前文件有没有 设置当前的播放模式
@@ -1443,8 +1519,6 @@ const setState = (data: any, index: number) => {
   state.cbsExamSongId = data.id + "";
   state.examSongName = data.name;
   state.coverImg = data.musicCover ?? "";
-  // 单声部多声轨合并展示
-  state.isCombineRender = data.musicSheetType === "SINGLE" && data.musicSheetSoundList?.length > 1
   // 如果是simple页面,只显示单轨
   if (state.isSimplePage) {
     state.isCombineRender = false;
@@ -1713,7 +1787,9 @@ export const fillWordColor = () => {
   const currentLyrics: SVGAElement[] = Array.from(document.querySelectorAll(`.lyric${currentNote?.noteId}`));
   currentLyrics.forEach((lyric, index) => {
     const lyricIndex = lyric.getAttribute('lyricIndex');
-    if ((index === currentNote.repeatIdx && currentNote.repeatIdx + 1 == lyricIndex) || (currentNote.repeatIdx > 0 && currentNote.formatLyricsEntries?.length === 1)) {
+    // bug:#10942,如果需要反复唱的小节,只有一遍歌词,反复唱的时候,歌词都需要高亮
+    const onlyOneLyric = currentNote.measures?.every((item: any) => item?.formatLyricsEntries?.length <= 1);
+    if ((index === currentNote.repeatIdx && currentNote.repeatIdx + 1 == lyricIndex) || (currentNote.repeatIdx != index && !onlyOneLyric && currentNote.repeatIdx + 1 == lyricIndex) || (currentNote.repeatIdx > 0 && currentNote.formatLyricsEntries?.length === 1 && onlyOneLyric)) {
       lyric?.classList.add('lyricActive')
     }
     // if ((index === currentNote.repeatIdx && currentNote.repeatIdx + 1 == lyricIndex)) {

+ 3 - 1
src/store.ts

@@ -22,7 +22,9 @@ type IUser = {
   phone?: string;
   schoolInfos?: any[];
   // 当前用户 绑定 的乐器
-  instrumentId: string 
+  instrumentId?: string;
+  // 性别
+  gender?: 1|0;
 };
 type IStatus = "init" | "login" | "logout" | "error";
 type IPlatformType = "STUDENT" | "TEACHER" | "WEB" | "";

+ 1 - 1
src/style.css

@@ -36,7 +36,7 @@ body {
 }
 
 .selectionToast {
-  top: 10vh;
+  top: 20vh;
 }
 
 .pop-center-enter-from,

+ 3 - 1
src/view/abnormal-pop/index.module.less

@@ -30,7 +30,7 @@
             font-size: 15px;
             font-family: PingFangSC, PingFang SC;
             font-weight: 400;
-            color: rgba(255, 255, 255, 0.8);     
+            color: rgba(255, 255, 255, 0.7);     
             margin: 20px 0 24px;
             text-align: center;  
         }
@@ -79,6 +79,7 @@
     flex-direction: column;
     justify-content: center;
     align-items: center;
+    transform: translateY(-14px);
     .loadingIcon {
         width: 118px;
     }
@@ -97,6 +98,7 @@
         text-align: center;
         width: 97px;
         height: 32px;
+        box-sizing: border-box;
         &:active{
             opacity: 0.8;
         }

+ 50 - 7
src/view/audio-list/index.tsx

@@ -33,7 +33,14 @@ export const audioData = reactive({
 	},
 	midiRender: false,
 	progress: 0, // midi播放进度(单位:秒)
-	duration: 0 // 音频总时长(单位:秒)
+	duration: 0, // 音频总时长(单位:秒)
+	mingSongType: 1 as 0 | 1,
+	mingSongTypeCollection: {
+		mingSongEle: null as HTMLAudioElement | null,
+		mingSongGirlEle: null as HTMLAudioElement | null,
+		beatMingSongEle: null as HTMLAudioElement | null,
+		beatMingSongGirlEle: null as HTMLAudioElement | null
+	}
 });
 const midiRef = ref();
 /** 播放或暂停 */
@@ -183,6 +190,16 @@ export const changeSongSourceByBate = (isDisBate:boolean) => {
 		audioData.mingSongEle && (audioData.mingSongEle.muted = false);
 	}
 }
+/** 切换男生女生唱名  */
+export const changeMingSongType = () =>{
+	// 当有男声女声都有值时候才能切换 
+	const { mingSongEle, mingSongGirlEle, beatMingSongEle, beatMingSongGirlEle } = audioData.mingSongTypeCollection
+	if(mingSongEle&&mingSongGirlEle){
+		const mingSongType = audioData.mingSongType
+		audioData.songCollection.mingSongEle = mingSongType === 1 ? mingSongEle : mingSongGirlEle
+		audioData.songCollection.betaMingSongEle = mingSongType === 1 ? beatMingSongEle : beatMingSongGirlEle
+	}
+}
 export default defineComponent({
 	name: "audio-list",
 	setup() {
@@ -299,11 +316,11 @@ export default defineComponent({
 		}
 		// 加载音源
 		function loadAudio(){
-			return Promise.all([createAudio(state.music), createAudio(state.accompany), createAudio(state.fanSong), createAudio(state.banSong), createAudio(state.mingSong)])
+			return Promise.all([createAudio(state.music), createAudio(state.accompany), createAudio(state.fanSong), createAudio(state.banSong), createAudio(state.mingSong), createAudio(state.mingSongGirl)])
 		}
 		// 加载节拍器音源
 		function loadBeatAudio(){
-			return Promise.all([createAudio(state.beatSong.music), createAudio(state.beatSong.accompany), createAudio(state.beatSong.fanSong), createAudio(state.beatSong.banSong), createAudio(state.beatSong.mingSong)])
+			return Promise.all([createAudio(state.beatSong.music), createAudio(state.beatSong.accompany), createAudio(state.beatSong.fanSong), createAudio(state.beatSong.banSong), createAudio(state.beatSong.mingSong), createAudio(state.beatSong.mingSongGirl)])
 		}
 		onMounted(async () => {
 			// 预览的时候不走音频加载逻辑
@@ -314,7 +331,7 @@ export default defineComponent({
 			if (state.playMode !== "MIDI") {
 				console.time("音频加载时间")
 				// 处理音源
-				const [music, accompany, fanSong, banSong, mingSong] = await loadAudio()
+				const [music, accompany, fanSong, banSong, mingSong, mingSongGirl] = await loadAudio()
 				audioData.backgroundEle = accompany;
 				audioData.songEle = music;
 				Object.assign(audioData.songCollection, {
@@ -324,6 +341,10 @@ export default defineComponent({
 					banSongEle:banSong,
 					mingSongEle:mingSong
 				})
+				Object.assign(audioData.mingSongTypeCollection, {
+					mingSongEle: mingSong,
+					mingSongGirlEle:mingSongGirl
+				})
 				if (music) {
 					music.addEventListener("play", onPlay);
 					music.addEventListener("ended", onEnded);
@@ -346,14 +367,22 @@ export default defineComponent({
 					mingSong.addEventListener("play", onPlay);
 					mingSong.addEventListener("ended", onEnded);
 				}
+				if(mingSongGirl){
+					mingSongGirl.addEventListener("play", onPlay);
+					mingSongGirl.addEventListener("ended", onEnded);
+				}
 				// 处理带节拍器的音源
-				const [beatMusic, beatAccompany, beatFanSong, beatBanSong, beatMingSong] = await loadBeatAudio()
+				const [beatMusic, beatAccompany, beatFanSong, beatBanSong, beatMingSong, beatMingSongGirl] = await loadBeatAudio()
 				Object.assign(audioData.songCollection, {
 					beatSongEle:beatMusic,
 					betaBackgroundEle:beatAccompany,
 					betaFanSongEle:beatFanSong,
 					betaBanSongEle:beatBanSong,
-					betaMingSongEle:beatMingSong
+					beatMingSongEle:beatMingSong
+				})
+				Object.assign(audioData.mingSongTypeCollection, {
+					beatMingSongEle: beatMingSong,
+					beatMingSongGirlEle: beatMingSongGirl
 				})
 				if (beatMusic) {
 					beatMusic.addEventListener("play", onPlay);
@@ -372,10 +401,24 @@ export default defineComponent({
 					beatBanSong.addEventListener("play", onPlay);
 					beatBanSong.addEventListener("ended", onEnded);
 					beatMingSong && (beatMingSong.muted = true);
-				} else if(beatMingSong){
+				} 
+				if(beatMingSong){
 					beatMingSong.addEventListener("play", onPlay);
 					beatMingSong.addEventListener("ended", onEnded);
+				}				
+				if(beatMingSongGirl){
+					beatMingSongGirl.addEventListener("play", onPlay);
+					beatMingSongGirl.addEventListener("ended", onEnded);
 				}
+				// 给男声女声赋值
+				const userGender = storeData.user.gender
+				// 当不为null 和undefined的时候 取userGender的值
+				if(userGender!==undefined && userGender!==null){
+					audioData.mingSongType = userGender
+				}
+				// 重新根据性别赋值
+				changeMingSongType()
+
 				state.audioDone = true;
 				state.isLoading = false
 				console.timeEnd("音频加载时间")

+ 11 - 11
src/view/fingering/fingering-config.ts

@@ -264,7 +264,7 @@ export const matchVoicePart = (id: number | string, type: "SINGLE" | "CONCERT"):
   } else {
     let code = id;
     const subject: { [_key: string | number]: any } = {
-      Piccolo: "piccolo",
+      Piccolo: 1,
       Flute: 2,
       "Flute 1": 2,
       "Flute 2": 2,
@@ -453,16 +453,16 @@ export const subjectFingering = (subjectId: number | string): IFingering => {
         hasTizhi: true,
         id: 2,
       };
-    // case "piccolo": // 德式竖笛
-    //   return {
-    //     name: "piccolo",
-    //     direction: "vertical",
-    //     width: "3rem",
-    //     orientation: 0,
-    //     code: "竖笛",
-    //     hasTizhi: true,
-    //     id: 37,
-    //   };
+    case "piccolo": // 德式竖笛
+      return {
+        name: "piccolo",
+        direction: "vertical",
+        width: "3rem",
+        orientation: 0,
+        code: "竖笛",
+        hasTizhi: true,
+        id: 37,
+      };
     case "hulusi-flute": // 葫芦丝
       return {
         name: "hulusi-flute",

File diff suppressed because it is too large
+ 0 - 0
src/view/fingering/fingering-img/baroque-recorder/index.json


File diff suppressed because it is too large
+ 0 - 0
src/view/fingering/fingering-img/ocarina/index.json


File diff suppressed because it is too large
+ 0 - 0
src/view/fingering/fingering-img/piccolo/index.json


File diff suppressed because it is too large
+ 0 - 0
src/view/fingering/fingering-img/whistling/index.json


+ 7 - 1
src/view/fingering/index.tsx

@@ -27,6 +27,12 @@ export default defineComponent({
       return state.times[state.activeNoteIndex]?.realKey || -1;
     });
 
+    // 竖笛、陶笛,云教练的乐器图片不需要正面两个字
+    const specialBgFinger = computed(() => {
+      const list: any = ['baroque-recorder', 'piccolo', 'ocarina', 'whistling']
+      return list.includes(state.fingeringInfo.name);
+    });
+
     const doubeClick = () => {
       const nowTime = Date.now();
       if (nowTime - fingerData.delay < 300) {
@@ -61,7 +67,7 @@ export default defineComponent({
           ) : (
             <div onClick={() => doubeClick()} class={[styles.fingeringContainer, styles.vertical, state.fingeringInfo.name, state.fingeringInfo.name === 'hulusi-flute' ? styles.hulusiTop : '']}>
               <div class={styles.imgs}>
-                <img class="driver-7" src={fingerData.subject?.json?.full} />
+                <img class="driver-7" src={specialBgFinger.value ? fingerData.subject?.json?.fullSpe : fingerData.subject?.json?.full} />
                 {rs.map((key: number | string, index: number) => {
                   const nk: string = typeof key === "string" ? key.replace("active-", "") : String(key);
                   return <img data-index={nk} src={fingerData.subject?.json?.[nk]} />;

+ 3 - 0
src/view/music-score/index.module.less

@@ -22,6 +22,9 @@
             left: 0;
             top: 0;
         }
+        // #osmdCanvasPage2 {
+        //     display: none;
+        // }
     }
     .noteActive {
         path {

+ 7 - 0
src/view/music-score/index.tsx

@@ -150,6 +150,13 @@ export default defineComponent({
 			if(state.isSimplePage){
 				state.zoom = 0.5
 			}
+			// 需要渲染总谱的云教练页面
+			if (!state.isSimplePage && state.isCombineRender) {
+				for (let i = 0; i < osmd.Sheet.Instruments.length; i++) {
+					const trackName = osmd.Sheet.Instruments[i].Name || '';
+					osmd.Sheet.Instruments[i].Visible = state.canSelectTracks.includes(trackName)
+				  }
+			}
 			osmd.zoom = state.zoom;
 			osmd.render();
 			console.log("🚀 ~ osmd:", osmd)

+ 2 - 0
src/view/plugins/toggleMusicSheet/index.tsx

@@ -38,6 +38,8 @@ export default defineComponent({
           canselect
         }
       }).filter((item: any) => item.canselect).sort((a: any, b: any) => a.sortId - b.sortId)
+      // 支持总谱渲染的时候 加上总谱字段
+      state.isScoreRender && arr.unshift({canselect:true, sortId:999, text: "总谱", value: 999})
       return arr
     })
 

+ 14 - 14
src/view/plugins/useDrag/index.module.less

@@ -7,20 +7,20 @@
   //overflow: hidden;
   position: absolute;
   bottom: 0;
-  .box {
-    position: relative;
-    bottom: 10px;
-    width: 20px;
-    height: 20px;
-    background: url('./img/left.png') no-repeat;
-    background-size: 100% 100%;
-    border-bottom-left-radius: 16Px;
-    &.right {
-      background: url('./img/right.png') no-repeat;
-      background-size: 100% 100%;
-      border-bottom-right-radius: 16Px;
-    }
-  }
+  // .box {
+  //   position: relative;
+  //   bottom: 10px;
+  //   width: 20px;
+  //   height: 20px;
+  //   background: url('./img/left.png') no-repeat;
+  //   background-size: 100% 100%;
+  //   border-bottom-left-radius: 16Px;
+  //   &.right {
+  //     background: url('./img/right.png') no-repeat;
+  //     background-size: 100% 100%;
+  //     border-bottom-right-radius: 16Px;
+  //   }
+  // }
 }
 .guide {
   position: absolute;

+ 7 - 6
src/view/selection/index.module.less

@@ -163,19 +163,20 @@
     align-items: center;
     background: rgba(0,0,0,0.6);
     position: relative;
-    padding: 3px 6px;
+    padding: 6px 10px;
     border-radius: 16px;
     width: fit-content;
     left: 50%;
-    top: -30px;
+    top: -42px;
     transform: translate(-50%);
     img {
-        width: 14px;
-        height: 14px;
-        margin-right: 4px;
+        width: 18px;
+        height: 18px;
+        margin-right: 6px;
     }
     span {
-        font-size: 12px;
+        font-size: 14px;
+        font-weight: 500;
         color: #fff;
         word-break: keep-all;
         display: flex;

+ 2 - 1
src/view/selection/index.tsx

@@ -236,6 +236,7 @@ export default defineComponent({
 				onClick={(e: Event) => e.stopPropagation()}
 			>
 				{selectData.staves.map((item: any) => {
+					// 评测得分
 					const scoreItem = item.id && evaluatingData.evaluatings[item.measureListIndex];
 					// for(let idx in evaluatingData.evaluatings) {
 					// 	const { show, measureIndex } = evaluatingData.evaluatings[idx]
@@ -260,7 +261,7 @@ export default defineComponent({
 								<div
 									class={[
 										styles.position,
-										scoreItem ? `scoreItemLeve${scoreItem.leve}` : "",
+										// scoreItem ? `scoreItemLeve${scoreItem.leve}` : "", // 去掉评测小节得分的背景色
 										item.multipleRestMeasures <= 1 ? styles.staveBg : "",
 										(state.platform === IPlatform.PC && state.zoom > 0.8) ? styles.linePC : '',
 									]}

Some files were not shown because too many files changed in this diff