Browse Source

Merge branch 'feature-tianyong-newVersion' of http://git.dayaedu.com/liushengqiang/music-score into hqyDevNewVersion

黄琪勇 11 tháng trước cách đây
mục cha
commit
ff88dfe230

+ 2 - 2
src/helpers/customMusicScore.ts

@@ -538,7 +538,7 @@ export const resetFormate = () => {
 		};
 
 		// 给小节添加背景色
-		if (!state.isCreateImg) {
+		if (!state.isCreateImg && !state.isPreView) {
 			staves.forEach((stave: any) => {
 				const list = [
 					Array.from(stave?.querySelectorAll(".vf-StaveSection") || []),
@@ -587,7 +587,7 @@ export const resetFormate = () => {
 
 // 一行谱时,五线谱/简谱的谱面staffLine,居中显示
 const transSinglePage = () => {
-	if (state.isSingleLine) {
+	if (state.isSingleLine && !state.isSimplePage) {
 		const svgPage = document?.getElementById('osmdSvgPage1')?.getBoundingClientRect();
 		const staffLine = document?.querySelector('.staffline')?.getBoundingClientRect();
 		if (svgPage && staffLine && svgPage.height > 130) {

+ 3 - 3
src/page-instrument/evaluat-model/earphone/index.module.less

@@ -1,7 +1,7 @@
 .earphoneBox {
     position: relative;
-    width: 100vw;
-    height: 100vh;
+    width: 600px;
+    height: 229px;
     .earphoneBg {
         position: absolute;
         left: 50%;
@@ -12,7 +12,7 @@
     .earphoneBtn {
         position: absolute;
         left: 50%;
-        bottom: 75px;
+        bottom: 13px;
         width: 133px;
         height: 39px;
         transform: translateX(-43%);

BIN
src/page-instrument/evaluat-model/icons/lanya_erji.png


BIN
src/page-instrument/evaluat-model/icons/no_erji.png


BIN
src/page-instrument/evaluat-model/icons/tip_btn.png


BIN
src/page-instrument/evaluat-model/icons/tip_erji.png


BIN
src/page-instrument/evaluat-model/icons/youxian_erji.png


+ 21 - 0
src/page-instrument/evaluat-model/index.module.less

@@ -127,4 +127,25 @@
     width: 100vw;
     height: 100vh;
     z-index: 10000;
+}
+
+.earphoneBox {
+    position: relative;
+    width: 600px;
+    height: 229px;
+    .earphoneBg {
+        position: absolute;
+        left: 50%;
+        top: 0;
+        height: 100%;
+        transform: translateX(-50%);
+    }
+    .earphoneBtn {
+        position: absolute;
+        left: 50%;
+        bottom: 13px;
+        width: 133px;
+        height: 39px;
+        transform: translateX(-43%);
+    }
 }

+ 46 - 13
src/page-instrument/evaluat-model/index.tsx

@@ -23,6 +23,8 @@ import { headTopData } from "../header-top/index";
 import { getQuery } from "/src/utils/queryString";
 import Countdown from "./countdown";
 import { IPostMessage } from "/src/utils/native-message";
+import tipErjiBg from "./icons/tip_erji.png"
+import tipErjiBtn from "./icons/tip_btn.png"
 
 // const DelayCheck = defineAsyncComponent(() =>
 //   import('./delay-check')
@@ -40,6 +42,12 @@ let actualBeatLength = 0;
 let calculateInfo: any = {};
 let checkErjiTimer: any = null
 
+export const reCheckDelay = () => {
+  headTopData.settingMode = false
+  state.setting.soundEffect = false
+  api_startDelayCheck({});
+}
+
 export default defineComponent({
   name: "evaluat-model",
   setup() {
@@ -188,6 +196,11 @@ export default defineComponent({
       }
       // 阶段评测beatLength需要加上预备小节的持续时长
       actualBeatLength = preTimes.length ? actualBeatLength + preTimes[preTimes.length - 1].relaMeasureLength * 1000 : actualBeatLength;
+      // 如果是弱起,并且预备小节是第一节
+      if (state.section.length && state.sectionFirst && state.sectionFirst.measureListIndex == 0) {
+        actualBeatLength = actualBeatLength < Math.round((state.times[0].fixtime * 1000) / 1) ? Math.round((state.times[0].fixtime * 1000) / 1) : actualBeatLength;
+      }
+      
       let firstNoteTime = unitTestIdx > 1 ? preTime : 0;
       let measureIndex = -1;
       let recordMeasure = -1;
@@ -198,7 +211,8 @@ export default defineComponent({
         // #8701 bug: 评测模式,是以曲谱本身的速度进行评测,所以rate取1,不需要转换
         // const rate = state.speed / state.originSpeed;
         const rate = state.basePlayRate * state.originAudioPlayRate; // 播放倍率
-        const difftime = item.difftime;
+        // const difftime = item.difftime;
+        const difftime = 0;
         const start = difftime + (item.sourceRelativeTime || item.relativeTime) - starTime;
         const end = difftime + (item.sourceRelaEndtime || item.relaEndtime) - starTime;
         const isStaccato = note.noteElement.voiceEntry.isStaccato();
@@ -405,6 +419,11 @@ export default defineComponent({
         });
       }
       // console.log('异常流程3')
+      // 非选段状态,从头开始评测,重置速度
+      if (!state.sectionStatus && state.section.length === 0) {
+        state.activeNoteIndex = 0;
+        state.speed = state.times[0].measureSpeed * state.basePlayRate
+      }
       initSetPlayRate();
       // 检测APP端socket状态
       const res: any = await startCheckDelay();
@@ -435,7 +454,7 @@ export default defineComponent({
       if (res?.content) {
         evaluatingData.checkEnd = true;
         state.setting.soundEffect = false;
-        checkEarphoneStatus();
+        evaluatingData.tipErjiShow = true;
       }
     };
 
@@ -448,15 +467,20 @@ export default defineComponent({
 			return evaluatingData.earphoneMode && !state.isLoading && !state.hasDriverPop;
 		});
 
-    watch(
-      () => state.setting.soundEffect,
-      (val) => {
-        if (val) {
-          headTopData.settingMode = false
-          api_startDelayCheck({});
-        }
-      }
-    );
+    const tipErjiPopShow = computed(() => {
+			return evaluatingData.tipErjiShow && !state.isLoading && !state.hasDriverPop;
+		});
+
+    // watch(
+    //   () => state.setting.soundEffect,
+    //   (val) => {
+    //     if (val) {
+    //       headTopData.settingMode = false
+    //       api_startDelayCheck({});
+    //       state.setting.soundEffect = false
+    //     }
+    //   }
+    // );
 
     // 手动取消评测,需要自动再次评测
     watch(
@@ -474,7 +498,7 @@ export default defineComponent({
       // 如果打开了延迟检测开关,需要先发送开始检测的消息
       const delayData = await api_getDeviceDelay();
       console.log('设备的延迟值',delayData.content?.value)
-      if (state.setting.soundEffect || (delayData && delayData.content?.value <= 0)) {
+      if (delayData && delayData.content?.value <= 0) {
         await api_startDelayCheck({});
       } else {
         evaluatingData.checkEnd = true;
@@ -546,6 +570,15 @@ export default defineComponent({
         {
           evaluatingData.isBeginMask && <div class={styles.beginMask}></div>
         }
+        <Popup teleport="body" closeOnClickOverlay={false} class={["popup-custom", "van-scale"]} transition="van-scale" v-model:show={tipErjiPopShow.value}>
+          <div class={styles.earphoneBox}>
+            <img class={styles.earphoneBg} src={tipErjiBg} />
+            <img class={styles.earphoneBtn} src={tipErjiBtn} onClick={() => {
+              evaluatingData.tipErjiShow = false;
+              checkEarphoneStatus();
+            }} />
+          </div>
+        </Popup>        
         <Popup teleport="body" closeOnClickOverlay={false} class={["popup-custom", "van-scale"]} transition="van-scale" v-model:show={earPhonePopShow.value}>
           <Earphone
             earphoneType={evaluatingData.earPhoneType}
@@ -555,7 +588,7 @@ export default defineComponent({
               // #11035,可能刚好关闭耳机弹窗的时候,第二次又出现了弹窗
               setTimeout(() => {
                 evaluatingData.earphoneMode = false;
-              }, 0);
+              }, 300);
               // handlePerformDetection();
               checkEarphoneStatus("start");
             }}

+ 1 - 1
src/page-instrument/header-top/index.tsx

@@ -345,7 +345,7 @@ export default defineComponent({
       // 选择模式 不显示
       if (headTopData.modeType !== "show" || ["follow"].includes(state.modeType)) return { display: false, disabled: true };
       // 音频播放中 禁用
-      if (state.playState === "play") return { display: true, disabled: true };
+      if (state.playState === "play" || query.workRecord) return { display: true, disabled: true };
 
       return {
         disabled: false,

+ 4 - 1
src/page-instrument/header-top/settting/index.tsx

@@ -10,6 +10,7 @@ import Recommendation from "../../custom-plugins/helper-model/recommendation";
 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"
 
 export default defineComponent({
 	name: "settting",
@@ -89,7 +90,9 @@ export default defineComponent({
                                 <div class={styles.cellBox}>
                                     <div class={styles.tit}>延迟检测</div>
                                     {/* <Switch v-model={state.setting.soundEffect}></Switch> */}
-                                    <div class={styles.titbtn} onClick={() => state.setting.soundEffect = true}>重新检测</div>
+                                    <div class={styles.titbtn} onClick={() => {
+                                        reCheckDelay();
+                                    }}>重新检测</div>
                                 </div> 
                                 <div class={[styles.cellBox, state.setting.camera && styles.isCamera]}>
                                     <div class={styles.tit}>摄像头</div>

+ 21 - 6
src/page-instrument/header-top/speed/index.tsx

@@ -8,6 +8,7 @@ import { metronomeData } from "../../../helpers/metronome";
 import { getQuery } from "/src/utils/queryString";
 import { api_createMusicPlayer, api_updateMusicPlayer, api_checkSocketStatus } from "/src/helpers/communication";
 import { storeData } from "/src/store";
+import { data as workData } from "/src/page-instrument/custom-plugins/work-index";
 
 export default defineComponent({
 	name: "speed",
@@ -62,7 +63,9 @@ export default defineComponent({
 		const toggleSwitch = async (res: any) => {
 			switchLoading.value = true;
 			try {
-			  if (storeData.isApp) {
+			  if (storeData.isApp && state.enableEvaluation) {
+				// 加载弹窗的开始时间
+				let startTime = +new Date();
 				state.loadingText = '节拍器准备中,请稍等…'
 				state.isLoading = true;
 				const targetSrc = res ? state.beatSong.accompany || state.beatSong.music : state.accompany || state.music;
@@ -73,9 +76,21 @@ export default defineComponent({
 				})
 				// console.log('切换节拍器音频',resData)
 				if (resData?.content) {
-					state.isLoading = false;
-					metronomeDisable.value = res;
-					switchLoading.value = false;
+					// 返回结果的时间
+					let intervalTime = +new Date() - startTime;
+					// 超过1秒直接关闭加载弹窗,小于1秒则最短显示1秒加载弹窗
+					if (intervalTime >= 1000) {
+						state.isLoading = false;
+						metronomeDisable.value = res;
+						switchLoading.value = false;
+					} else {
+						const continueTime = 1000 - intervalTime;
+						setTimeout(() => {
+							state.isLoading = false;
+							metronomeDisable.value = res;
+							switchLoading.value = false;
+						}, continueTime);
+					}
 				}
 				// api_checkSocketStatus();
 			  } else {
@@ -98,7 +113,7 @@ export default defineComponent({
 				<div class={styles.content}>
 					<div class={styles.conBox}>
 						<div class={styles.tit}>速度</div>
-						<div class={[styles.spendCon, query.workRecord && styles.disableSpend]}>
+						<div class={[styles.spendCon, workData.trainingType === "PRACTICE" && styles.disableSpend]}>
 							<img src={headImg("cutImg.png")} class={[styles.btn]} onClick={minusSpeed} />
 							<div class={styles.sliderCon}>
 								<Slider class={styles.slider} max={270} min={speed.value < 45 ? speed.value : 45} v-model={speed.value}>
@@ -113,7 +128,7 @@ export default defineComponent({
 							</div>
 							<img src={headImg("addImg.png")} class={[styles.btn]} onClick={plusSpeed} />	
 						</div>
-						<div class={[styles.speedSel, query.workRecord && styles.disableSpend]}>
+						<div class={[styles.speedSel, workData.trainingType === "PRACTICE" && styles.disableSpend]}>
 							<div onClick={resetCurrentSpeed}>原速</div>
 							<div onClick={()=>{ speed.value = 70 }}>70</div>
 							<div onClick={()=>{ speed.value = 80 }}>80</div>

+ 4 - 0
src/page-instrument/simple-detail/index.module.less

@@ -1,3 +1,7 @@
+body {
+    overflow: hidden;
+}
+
 .skeleton {
     position: fixed;
     left: 0;

+ 9 - 2
src/page-instrument/simple-detail/index.tsx

@@ -37,12 +37,19 @@ export default defineComponent({
 			}
 			// 暂停播放
 			if (resInfo?.api === "api_paused") {
-				console.log('暂停播放')
+				const currentTime = resInfo?.content?.currentTime
+				console.log('暂停播放',currentTime)
 				state.playState = 'paused';
+				if (currentTime === 0) {
+					// 坐标和小节都改为初始值
+					state.activeNoteIndex = 0
+					state.activeMeasureIndex = state.times[0].MeasureNumberXML;
+					handlePlaying(true);
+				}
 			}
 			// 暂停状态下,拖动进度
 			if (resInfo?.api === "api_updateProgress") {
-				console.log('拖动的进度')
+				console.log('拖动的进度',state.playState)
 				if (state.playState === 'paused') {
 					detailData.currentTime = resInfo?.content?.currentTime ?? detailData.currentTime;
 					// 坐标和小节都改为初始值

+ 13 - 1
src/page-instrument/view-detail/index.module.less

@@ -68,7 +68,7 @@
         overflow: hidden;
     }
     .pcContainer {
-        height: calc(100vh - var(--header-height) - var(--pc-header-height));
+        // height: calc(100vh - var(--header-height) - var(--pc-header-height));
     }
     .fingeringCon{
         transition: scale 0.2s;
@@ -171,6 +171,9 @@
 
 .preViewDetail {
     background: #fff !important;
+    >.pageBg {
+        display: none;
+    }
     .headHeight {
         background: #fff !important;
     }
@@ -186,6 +189,15 @@
         #cursorImg-0 {
             opacity: 0 !important;
         }
+        .noteActive {
+            path {
+                fill: #000000;
+                stroke: #000000;
+            }
+            rect {
+                stroke: #000000;
+            }
+        }
     }
 }
 

+ 5 - 1
src/page-instrument/view-detail/index.tsx

@@ -146,6 +146,9 @@ export default defineComponent({
       if (state.isPreView) {
         state.zoom = 0.65
       }
+      if (id == '1814218144844087298' && state.isSingleLine) {
+        state.zoom = 0.7
+      }
       // 只有总控平台和预览 默认是多行谱
       (state.isPreView || query.isCbs) && (state.isSingleLine = false)
       // Promise.all([sysMusicScoreAccompanimentQueryPage(id)]).then((values) => {
@@ -277,6 +280,7 @@ export default defineComponent({
 
       evaluatCreateMusicPlayer();
       resetPlaybackToStart();
+      // 需要重新设置作业选段
       if (state.workSectionNeedReset) {
         resetSection();
       }
@@ -494,7 +498,7 @@ export default defineComponent({
           {!detailData.isLoading && 
             <MusicScore 
               ref={musicScoreRef}
-              musicColor={'#FFFFFF'}
+              musicColor={state.isPreView ? '#000000' : '#FFFFFF'}
               showPartNames={state.isCombineRender}
               onRendered={handleRendered} 
             > 

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

@@ -410,7 +410,7 @@ export default defineComponent({
                       </div>
                     </>
                   )}
-                  {(itemType.value === "intonation" || itemType.value === "integrity") && (
+                  {itemType.value === "integrity" && (
                     <div>
                       <i style={{ background: bgColors.lack }}></i>
                       <span>时值不足</span>

+ 3 - 2
src/page-instrument/view-evaluat-report/index.tsx

@@ -251,7 +251,7 @@ export default defineComponent({
       if (scoreData.itemType === "cadence") {
         return detailData.musicalNotesPlayStats.filter((item: any) => include.includes(item.rhythmicAssessment.result));
       } else if (scoreData.itemType === "integrity") {
-        return detailData.musicalNotesPlayStats.filter((item: any) => include.includes(item.integrityAssessment.result));
+        return detailData.musicalNotesPlayStats.filter((item: any) => include.includes(item.integrityAssessment?.result));
       } else  {
         return detailData.musicalNotesPlayStats.filter((item: any) => {
           let result = item.pitchAssessment.result;
@@ -268,7 +268,8 @@ export default defineComponent({
       const notes = filterNotes();
       // console.log(1111,notes)
       for (const note of notes) {
-        const active = allNote.value[note.musicalNotesIndex];
+        const idx = note.musicalNotesIndex !== undefined ? note.musicalNotesIndex : note.index;
+        const active = allNote.value[idx];
         setTimeout(() => {
           if (useedid.value.includes(active.id)) {
             return;

+ 10 - 2
src/state.ts

@@ -1074,7 +1074,10 @@ export const handleResetPlay = () => {
   if (state.isAppPlay) {
     audioData.progress = 0
   }
-  resetBaseRate();
+  // 如果是作业模式,不还原速度
+  if (!query.workRecord) {
+    resetBaseRate();
+  }
   resetPlaybackToStart();
   // 如果是暂停, 直接播放
   togglePlay("play");
@@ -1102,6 +1105,8 @@ export const handleChangeSection = () => {
   if (state.sectionStatus) {
     togglePlay("paused");
     clearSelection();
+    // 重置速度和播放倍率
+    resetBaseRate(state.activeNoteIndex);
     //skipNotePlay(0, true);  取消选段的时候 不跳回开头
     state.sectionFirst = null;
     return;
@@ -1709,6 +1714,9 @@ export const fillWordColor = () => {
     if ((index === currentNote.repeatIdx && currentNote.repeatIdx + 1 == lyricIndex) || (currentNote.repeatIdx > 0 && currentNote.formatLyricsEntries?.length === 1)) {
       lyric?.classList.add('lyricActive')
     }
+    // if ((index === currentNote.repeatIdx && currentNote.repeatIdx + 1 == lyricIndex)) {
+    //   lyric?.classList.add('lyricActive')
+    // }
   })
 }
 
@@ -1785,7 +1793,7 @@ watch(
         item.querySelector('.vf-custom-bg')?.setAttribute("fill", "#132D4C")
         item.querySelector('.vf-custom-bot')?.setAttribute("fill", "#040D1E")
         // 预备小节
-        if(state.sectionFirst && measureNum === state.sectionFirst.MeasureNumberXML){
+        if(state.sectionFirst && measureNum === state.sectionFirst.MeasureNumberXML && state.section.length === 2){
           item?.querySelector('.vf-custom-bg')?.setAttribute("fill", "#71B8BD")
           item?.querySelector('.vf-custom-bot')?.setAttribute("fill", "#448F9C")
         }

+ 0 - 1
src/view/audio-list/index.tsx

@@ -248,7 +248,6 @@ export default defineComponent({
 		// 监听评测曲谱音频播放进度,返回
 		const progress = (res: any) => {
 			const currentTime = res?.currentTime || res?.content?.currentTime;
-			// console.log('app进度时间',currentTime)
 			const total = res?.totalDuration || res?.content?.totalDuration;
 			const time = currentTime / 1000;
 			audioData.progress = time;

+ 1 - 0
src/view/evaluating/index.tsx

@@ -113,6 +113,7 @@ export const evaluatingData = reactive({
   evaluatSpeed: 0, // 评测记录的速度
   needReplayEvaluat: false, // 手动取消评测,需要自动开始评测
   needPlayTick: false, // 评测时,mp3节拍器需要等待音频开始播放后再执行播放节拍器的圆点动画
+  tipErjiShow: false, // 评测提示弹窗
 });
 
 const sendOffsetTime = async (offsetTime: number) => {

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

@@ -138,6 +138,10 @@ export default defineComponent({
 				(window as any).sett = {
 					keySignature: true,
 				};
+			} else {
+				(window as any).sett = {
+					keySignature: false,
+				};
 			}
 			osmd.EngravingRules.DYMusicScoreId = state.examSongId || ''
 			osmd.EngravingRules.DYCustomRepeatCount = state.maxLyricNum || 0;
@@ -161,7 +165,7 @@ export default defineComponent({
 		};
 		onMounted(async () => {
 			getContainerWidth();
-			setRenderType();
+			//setRenderType();
 			await getXML();
 			await init();
 			musicData.isRenderLoading = false;
@@ -200,7 +204,7 @@ export default defineComponent({
 			// 在下一帧再执行,确保出现loading
 			requestAnimationFrame(async ()=>{
 				getContainerWidth();
-				setRenderType();
+				//setRenderType();
 				await getXML();
 				await init();
 				musicData.isRenderLoading = false;
@@ -221,7 +225,7 @@ export default defineComponent({
 					isInTheGradualRange.value && styles.inGradualRange,
 					state.musicRenderType == EnumMusicRenderType.staff ? "staff" : "jianpuTone",
 					state.isSingleLine && "singleLineMusicBox",
-					(!state.isCreateImg && state.musicRenderType === EnumMusicRenderType.staff) ? "blueMusicXml" : ""
+					(!state.isCreateImg && !state.isPreView && state.musicRenderType === EnumMusicRenderType.staff) ? "blueMusicXml" : ""
 				]}
 			>
 				{slots.default?.()}

+ 1 - 1
src/view/plugins/move-music-score/index.module.less

@@ -27,7 +27,7 @@
     border-radius: 4px;
     display: flex;
     flex-direction: column;
-    z-index: 10;
+    z-index: 9999;
     backdrop-filter: blur(10px);
     &>div,
     &>button {

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

@@ -336,7 +336,7 @@ export default defineComponent({
 					sectionPosData.value.map((item,index) =>{
 						return (
 							item && <div class={styles.selectBox} style={item}>
-								<div class={[styles.selectHandle,index>0&&styles.selectHandleRight,state.playState==="play"&&styles.playIng]} onClick={()=>{
+								<div class={[styles.selectHandle,index>0&&styles.selectHandleRight,(state.playState==="play" || query.workRecord)&&styles.playIng]} onClick={()=>{
 									// 如果选择了2个 删除左边的时候
 									if(state.section.length===2&&index === 0){
 										state.section = []

+ 2 - 1
src/view/transfer-to-img/index.tsx

@@ -51,7 +51,7 @@ export default defineComponent({
 			}
 			//课堂乐器,默认简谱
 			sessionStorage.setItem(productRenderType, detailData.product[detailData.step].type);
-
+			state.musicRenderType = detailData.product[detailData.step].type
 			showLoadingToast({ message: "生成中", duration: 0 });
 			setTimeout(() => {
 				detailData.isLoading = false;
@@ -75,6 +75,7 @@ export default defineComponent({
 			if (detailData.step !== detailData.product.length) {
 				//课堂乐器,默认简谱
 				sessionStorage.setItem(productRenderType, detailData.product[detailData.step].type);
+				state.musicRenderType = detailData.product[detailData.step].type
 				nextTick(() => {
 					detailData.isLoading = true;
 					setTimeout(() => {