Browse Source

Update index.tsx

lex 1 year ago
parent
commit
6ec08e28c2
1 changed files with 265 additions and 305 deletions
  1. 265 305
      src/page-instrument/evaluat-model/index.tsx

+ 265 - 305
src/page-instrument/evaluat-model/index.tsx

@@ -1,12 +1,5 @@
 import { Transition, defineComponent, onMounted, reactive, watch } from "vue";
-import {
-	connectWebsocket,
-	evaluatingData,
-	handleEndBegin,
-	handleStartBegin,
-	handleStartEvaluat,
-	handleViewReport,
-} from "/src/view/evaluating";
+import { connectWebsocket, evaluatingData, handleEndBegin, handleStartBegin, handleStartEvaluat, handleViewReport } from "/src/view/evaluating";
 import Earphone from "./earphone";
 import styles from "./index.module.less";
 import SoundEffect from "./sound-effect";
@@ -31,282 +24,266 @@ import DelayCheck from "./delay-check";
 type TCriteria = "frequency" | "amplitude" | "decibels";
 
 export default defineComponent({
-	name: "evaluat-model",
-	setup() {
-		const evaluatModel = reactive({
-			tips: true,
-			evaluatUpdateAudio: false,
-			isSaveVideo: state.setting.camera && state.setting.saveToAlbum,
-			shareMode: false,
-		});
-		
-		/**
-		 * 执行检测
-		 */
-		const handlePerformDetection = async () => {
-			// 检测完成不检测了
-			if (evaluatingData.checkEnd) return;
-			// 延迟检测
-			if (evaluatingData.checkStep === 0) {
-				evaluatingData.checkStep = 10;
-				// 没有设备延迟数据 或 开启了效音 显示检测组件,并持续检测耳机状态
-				if (state.setting.soundEffect) {
-					evaluatingData.soundEffectMode = true;
-					return;
-				}
-				const delayData = await api_getDeviceDelay();
-				// console.log("🚀 ~ delayTime:", delayData);
-				if (delayData && delayData.content?.value < 0) {	
-					evaluatingData.soundEffectMode = true;
-					return;
-				}
-				handlePerformDetection();
-				return;
-			}
-			// 效验完成
-			if (evaluatingData.checkStep === 10) {
-				evaluatingData.checkEnd = true;
-				console.log("检测结束,生成数据");
-				handleConnect();
-			}
-		};
-		const browserInfo = browser();
-		/** 是否是节奏练习 */
-		const isRhythmicExercises = () => {
-			const examSongName = state.examSongName || "";
-			return examSongName.indexOf("节奏练习") > -1;
-		};
+  name: "evaluat-model",
+  setup() {
+    const evaluatModel = reactive({
+      tips: true,
+      evaluatUpdateAudio: false,
+      isSaveVideo: state.setting.camera && state.setting.saveToAlbum,
+      shareMode: false,
+    });
 
-		/** 获取评测标准 */
-		const getEvaluationCriteria = () => {
-			let criteria: TCriteria = "frequency";
-			// 声部打击乐
-			if ([23, 113, 121].includes(state.subjectId)) {
-				criteria = "amplitude";
-			} else if (isRhythmicExercises()) {
-				// 分类为节奏练习
-				criteria = "decibels";
-			}
-			return criteria;
-		};
+    /**
+     * 执行检测
+     */
+    const handlePerformDetection = async () => {
+      console.log(evaluatingData.checkStep, evaluatingData, "检测");
+      // 检测完成不检测了
+      if (evaluatingData.checkEnd) return;
+      // 延迟检测
 
-		/** 生成评测曲谱数据 */
-		const formatTimes = () => {
-			let ListenMode = false;
-			let dontEvaluatingMode = false;
-			let skip = false;
-			const datas = [];
-			for (let index = 0; index < state.times.length; index++) {
-				const item = state.times[index];
-				const note = getNoteByMeasuresSlursStart(item);
-				const rate = state.speed / state.originSpeed;
-				const difftime = item.difftime;
-				const start = difftime + (item.sourceRelativeTime || item.relativeTime);
-				const end = difftime + (item.sourceRelaEndtime || item.relaEndtime);
-				const isStaccato = note.noteElement.voiceEntry.isStaccato();
-				const noteRate = isStaccato ? 0.5 : 1;
-				if (note.formatLyricsEntries.contains("Play") || note.formatLyricsEntries.contains("Play...")) {
-					ListenMode = false;
-				}
-				if (note.formatLyricsEntries.contains("Listen")) {
-					ListenMode = true;
-				}
-				if (note.formatLyricsEntries.contains("纯律结束")) {
-					dontEvaluatingMode = false;
-				}
-				if (note.formatLyricsEntries.contains("纯律")) {
-					dontEvaluatingMode = true;
-				}
-				const nextNote = state.times[index + 1];
-				// console.log("noteinfo", note.noteElement.isRestFlag && !!note.stave && !!nextNote)
-				if (
-					skip &&
-					(note.stave || !item.noteElement.isRestFlag || (nextNote && !nextNote.noteElement.isRestFlag))
-				) {
-					skip = false;
-				}
-				if (
-					note.noteElement.isRestFlag &&
-					!!note.stave &&
-					!!nextNote &&
-					nextNote.noteElement.isRestFlag
-				) {
-					skip = true;
-				}
-				// console.log(note.measureOpenIndex, item.measureOpenIndex, note);
-				// console.log("skip", skip)
-				const data = {
-					timeStamp: (start * 1000) / rate,
-					duration: ((end * 1000) / rate - (start * 1000) / rate) * noteRate,
-					frequency: item.frequency,
-					nextFrequency: item.nextFrequency,
-					prevFrequency: item.prevFrequency,
-					// 重复的情况index会自然累加,render的index是谱面渲染的index
-					measureIndex: note.measureOpenIndex,
-					measureRenderIndex: item.measureListIndex,
-					dontEvaluating: ListenMode || dontEvaluatingMode || item.skipMode,
-					musicalNotesIndex: item.i,
-					denominator: note.noteElement?.Length.denominator,
-					isOrnament: !!note?.voiceEntry?.ornamentContainer,
-				};
-				datas.push(data);
-			}
-			return datas;
-		};
-		/** 连接websocket */
-		const handleConnect = async () => {
-			const behaviorId = localStorage.getItem("behaviorId") || undefined;
-			const rate = state.speed / state.originSpeed;
-			const content = {
-				musicXmlInfos: formatTimes(),
-				subjectId: state.subjectId,
-				detailId: state.detailId,
-				examSongId: state.examSongId,
-				xmlUrl: state.xmlUrl,
-				partIndex: state.partIndex,
-				behaviorId,
-				platform: browserInfo.ios ? "IOS" : browserInfo.android ? "ANDROID" : "WEB",
-				clientId:
-					storeData.platformType === "STUDENT"
-						? "student"
-						: storeData.platformType === "TEACHER"
-						? "teacher"
-						: "education",
-				hertz: state.setting.frequency,
-				reactionTimeMs: state.setting.reactionTimeMs,
-				speed: state.speed,
-				heardLevel: state.setting.evaluationDifficulty,
-				beatLength: Math.round((state.fixtime * 1000) / rate),
-				evaluationCriteria: getEvaluationCriteria(),
-			};
-			await connectWebsocket(content);
-			// state.playSource = "music";
-		};
+      if (evaluatingData.checkStep === 0) {
+        evaluatingData.checkStep = 10;
+        // 没有设备延迟数据 或 开启了效音 显示检测组件,并持续检测耳机状态
 
-		/** 评测结果按钮处理 */
-		const handleEvaluatResult = (type: "practise" | "tryagain" | "look" | "share" | "update") => {
-			if (type === "update") {
-				if (evaluatingData.resultData?.recordIdStr || evaluatingData.resultData?.recordId) {
-					// 上传云端
-					// evaluatModel.evaluatUpdateAudio = true;
-					api_openAdjustRecording({
-						recordId: evaluatingData.resultData?.recordIdStr || evaluatingData.resultData?.recordId,
-						title: state.examSongName || '曲谱演奏',
-						coverImg: state.coverImg,
-					});
-					return;
-				}
-			} else if (type === "share") {
-				// 分享
-				evaluatModel.shareMode = true;
-				return;
-			} else if (type === "look") {
-				// 跳转
-				handleViewReport("recordId", "instrument");
-				return;
-			} else if (type === "practise") {
-				// 去练习
-				handleStartEvaluat();
-			} else if (type === "tryagain") {
-				// 再来一次
-				handleStartBegin();
-			}
-			evaluatingData.resulstMode = false;
-		};
+        if (state.setting.soundEffect) {
+          evaluatingData.soundEffectMode = true;
+          return;
+        }
+        // 判断只有开始了设备检测之后才去调用api
+        if (state.setting.soundEffect) {
+          const delayData = await api_getDeviceDelay();
+          // console.log("🚀 ~ delayTime:", delayData);
+          if (delayData && delayData.content?.value < 0) {
+            evaluatingData.soundEffectMode = true;
+            return;
+          }
+        }
 
-		/** 上传音视频 */
-		const hanldeUpdateVideoAndAudio = async (update = false) => {
-			if (!update) {
-				evaluatModel.evaluatUpdateAudio = false;
-				return;
-			}
-			if (state.setting.camera && state.setting.saveToAlbum) {
-				evaluatModel.evaluatUpdateAudio = false;
-				api_videoUpdate((res: any) => {
-					if (res) {
-						if (res?.content?.type === "success") {
-							handleSaveResult({
-								id: evaluatingData.resultData?.recordId,
-								videoFilePath: res?.content?.filePath,
-							});
-						} else if (res?.content?.type === "error") {
-							showToast({
-								message: res.content?.message || "上传失败",
-							});
-						}
-					}
-				});
-				return;
-			}
-			evaluatModel.evaluatUpdateAudio = false;
-			showToast("上传成功");
-		};
-		const handleSaveResult = async (_body: any) => {
-			await api_musicPracticeRecordVideoUpload(_body);
-			showToast("上传成功");
-		};
+        handlePerformDetection();
+        return;
+      }
+      // 效验完成
+      if (evaluatingData.checkStep === 10) {
+        evaluatingData.checkEnd = true;
+        console.log("检测结束,生成数据");
+        handleConnect();
+      }
+    };
+    const browserInfo = browser();
+    /** 是否是节奏练习 */
+    const isRhythmicExercises = () => {
+      const examSongName = state.examSongName || "";
+      return examSongName.indexOf("节奏练习") > -1;
+    };
 
-		onMounted(() => {
-			evaluatingData.isDisabledPlayMusic = true
-			handlePerformDetection();
-		});
-		return () => (
-			<div>
-				<Transition name="pop-center">
-					{evaluatingData.websocketState && !evaluatingData.startBegin && evaluatingData.checkEnd && (
-						<div class={styles.startBtn} onClick={handleStartBegin}>
-							<img src={iconEvaluat.evaluatingStart} />
-						</div>
-					)}
-				</Transition>
-				<Transition name="pop-center">
-					{evaluatingData.websocketState && evaluatingData.startBegin && (
-						<div class={styles.endBtn} onClick={() => handleEndBegin()}>
-							<img src={iconEvaluat.evaluatingEnd} />
-						</div>
-					)}
-				</Transition>
+    /** 获取评测标准 */
+    const getEvaluationCriteria = () => {
+      let criteria: TCriteria = "frequency";
+      // 声部打击乐
+      if ([23, 113, 121].includes(state.subjectId)) {
+        criteria = "amplitude";
+      } else if (isRhythmicExercises()) {
+        // 分类为节奏练习
+        criteria = "decibels";
+      }
+      return criteria;
+    };
 
-				<div
-					style={{ display: !evaluatingData.startBegin ? "" : "none" }}
-					class={styles.dialogueBox}
-					key="start"
-				>
-					<div class={styles.dialogue}>
-						<img class={styles.dialoguebg} src={iconTastBg} />
-						<div>演奏前请调整好乐器,保证最佳演奏状态。</div>
-					</div>
-					<Vue3Lottie class={styles.dialogueIcon} animationData={startData}></Vue3Lottie>
-				</div>
-				<div
-					style={{ display: evaluatingData.startBegin ? "" : "none" }}
-					class={styles.dialogueBox}
-					key="start"
-				>
-					<div class={styles.dialogueing}>收音中...</div>
-					<Vue3Lottie class={styles.dialogueIcon} animationData={startingData}></Vue3Lottie>
-				</div>
+    /** 生成评测曲谱数据 */
+    const formatTimes = () => {
+      let ListenMode = false;
+      let dontEvaluatingMode = false;
+      let skip = false;
+      const datas = [];
+      for (let index = 0; index < state.times.length; index++) {
+        const item = state.times[index];
+        const note = getNoteByMeasuresSlursStart(item);
+        const rate = state.speed / state.originSpeed;
+        const difftime = item.difftime;
+        const start = difftime + (item.sourceRelativeTime || item.relativeTime);
+        const end = difftime + (item.sourceRelaEndtime || item.relaEndtime);
+        const isStaccato = note.noteElement.voiceEntry.isStaccato();
+        const noteRate = isStaccato ? 0.5 : 1;
+        if (note.formatLyricsEntries.contains("Play") || note.formatLyricsEntries.contains("Play...")) {
+          ListenMode = false;
+        }
+        if (note.formatLyricsEntries.contains("Listen")) {
+          ListenMode = true;
+        }
+        if (note.formatLyricsEntries.contains("纯律结束")) {
+          dontEvaluatingMode = false;
+        }
+        if (note.formatLyricsEntries.contains("纯律")) {
+          dontEvaluatingMode = true;
+        }
+        const nextNote = state.times[index + 1];
+        // console.log("noteinfo", note.noteElement.isRestFlag && !!note.stave && !!nextNote)
+        if (skip && (note.stave || !item.noteElement.isRestFlag || (nextNote && !nextNote.noteElement.isRestFlag))) {
+          skip = false;
+        }
+        if (note.noteElement.isRestFlag && !!note.stave && !!nextNote && nextNote.noteElement.isRestFlag) {
+          skip = true;
+        }
+        // console.log(note.measureOpenIndex, item.measureOpenIndex, note);
+        // console.log("skip", skip)
+        const data = {
+          timeStamp: (start * 1000) / rate,
+          duration: ((end * 1000) / rate - (start * 1000) / rate) * noteRate,
+          frequency: item.frequency,
+          nextFrequency: item.nextFrequency,
+          prevFrequency: item.prevFrequency,
+          // 重复的情况index会自然累加,render的index是谱面渲染的index
+          measureIndex: note.measureOpenIndex,
+          measureRenderIndex: item.measureListIndex,
+          dontEvaluating: ListenMode || dontEvaluatingMode || item.skipMode,
+          musicalNotesIndex: item.i,
+          denominator: note.noteElement?.Length.denominator,
+          isOrnament: !!note?.voiceEntry?.ornamentContainer,
+        };
+        datas.push(data);
+      }
+      return datas;
+    };
+    /** 连接websocket */
+    const handleConnect = async () => {
+      const behaviorId = localStorage.getItem("behaviorId") || undefined;
+      const rate = state.speed / state.originSpeed;
+      const content = {
+        musicXmlInfos: formatTimes(),
+        subjectId: state.subjectId,
+        detailId: state.detailId,
+        examSongId: state.examSongId,
+        xmlUrl: state.xmlUrl,
+        partIndex: state.partIndex,
+        behaviorId,
+        platform: browserInfo.ios ? "IOS" : browserInfo.android ? "ANDROID" : "WEB",
+        clientId: storeData.platformType === "STUDENT" ? "student" : storeData.platformType === "TEACHER" ? "teacher" : "education",
+        hertz: state.setting.frequency,
+        reactionTimeMs: state.setting.reactionTimeMs,
+        speed: state.speed,
+        heardLevel: state.setting.evaluationDifficulty,
+        beatLength: Math.round((state.fixtime * 1000) / rate),
+        evaluationCriteria: getEvaluationCriteria(),
+      };
+      await connectWebsocket(content);
+      // state.playSource = "music";
+    };
 
-				{evaluatingData.soundEffectMode && <DelayCheck onClose={() => {
-					evaluatingData.soundEffectMode = false;
-					handlePerformDetection();
-				}} />}
+    /** 评测结果按钮处理 */
+    const handleEvaluatResult = (type: "practise" | "tryagain" | "look" | "share" | "update") => {
+      if (type === "update") {
+        if (evaluatingData.resultData?.recordIdStr || evaluatingData.resultData?.recordId) {
+          // 上传云端
+          // evaluatModel.evaluatUpdateAudio = true;
+          api_openAdjustRecording({
+            recordId: evaluatingData.resultData?.recordIdStr || evaluatingData.resultData?.recordId,
+            title: state.examSongName || "曲谱演奏",
+            coverImg: state.coverImg,
+          });
+          return;
+        }
+      } else if (type === "share") {
+        // 分享
+        evaluatModel.shareMode = true;
+        return;
+      } else if (type === "look") {
+        // 跳转
+        handleViewReport("recordId", "instrument");
+        return;
+      } else if (type === "practise") {
+        // 去练习
+        handleStartEvaluat();
+      } else if (type === "tryagain") {
+        // 再来一次
+        handleStartBegin();
+      }
+      evaluatingData.resulstMode = false;
+    };
 
-				<Popup
-					teleport="body"
-					closeOnClickOverlay={false}
-					class={["popup-custom", "van-scale"]}
-					transition="van-scale"
-					v-model:show={evaluatingData.earphoneMode}
-				>
-					<Earphone
-						onClose={() => {
-							evaluatingData.earphoneMode = false;
-							handlePerformDetection();
-						}}
-					/>
-				</Popup>
-				{/* <Popup
+    /** 上传音视频 */
+    const hanldeUpdateVideoAndAudio = async (update = false) => {
+      if (!update) {
+        evaluatModel.evaluatUpdateAudio = false;
+        return;
+      }
+      if (state.setting.camera && state.setting.saveToAlbum) {
+        evaluatModel.evaluatUpdateAudio = false;
+        api_videoUpdate((res: any) => {
+          if (res) {
+            if (res?.content?.type === "success") {
+              handleSaveResult({
+                id: evaluatingData.resultData?.recordId,
+                videoFilePath: res?.content?.filePath,
+              });
+            } else if (res?.content?.type === "error") {
+              showToast({
+                message: res.content?.message || "上传失败",
+              });
+            }
+          }
+        });
+        return;
+      }
+      evaluatModel.evaluatUpdateAudio = false;
+      showToast("上传成功");
+    };
+    const handleSaveResult = async (_body: any) => {
+      await api_musicPracticeRecordVideoUpload(_body);
+      showToast("上传成功");
+    };
+
+    onMounted(() => {
+      evaluatingData.isDisabledPlayMusic = true;
+      handlePerformDetection();
+    });
+    return () => (
+      <div>
+        <Transition name="pop-center">
+          {evaluatingData.websocketState && !evaluatingData.startBegin && evaluatingData.checkEnd && (
+            <div class={styles.startBtn} onClick={handleStartBegin}>
+              <img src={iconEvaluat.evaluatingStart} />
+            </div>
+          )}
+        </Transition>
+        <Transition name="pop-center">
+          {evaluatingData.websocketState && evaluatingData.startBegin && (
+            <div class={styles.endBtn} onClick={() => handleEndBegin()}>
+              <img src={iconEvaluat.evaluatingEnd} />
+            </div>
+          )}
+        </Transition>
+
+        <div style={{ display: !evaluatingData.startBegin ? "" : "none" }} class={styles.dialogueBox} key="start">
+          <div class={styles.dialogue}>
+            <img class={styles.dialoguebg} src={iconTastBg} />
+            <div>演奏前请调整好乐器,保证最佳演奏状态。</div>
+          </div>
+          <Vue3Lottie class={styles.dialogueIcon} animationData={startData}></Vue3Lottie>
+        </div>
+        <div style={{ display: evaluatingData.startBegin ? "" : "none" }} class={styles.dialogueBox} key="start">
+          <div class={styles.dialogueing}>收音中...</div>
+          <Vue3Lottie class={styles.dialogueIcon} animationData={startingData}></Vue3Lottie>
+        </div>
+
+        {evaluatingData.soundEffectMode && (
+          <DelayCheck
+            onClose={() => {
+              evaluatingData.soundEffectMode = false;
+              handlePerformDetection();
+            }}
+          />
+        )}
+
+        <Popup teleport="body" closeOnClickOverlay={false} class={["popup-custom", "van-scale"]} transition="van-scale" v-model:show={evaluatingData.earphoneMode}>
+          <Earphone
+            onClose={() => {
+              evaluatingData.earphoneMode = false;
+              handlePerformDetection();
+            }}
+          />
+        </Popup>
+        {/* <Popup
 					teleport="body"
 					closeOnClickOverlay={false}
 					class={["popup-custom", "van-scale"]}
@@ -325,33 +302,16 @@ export default defineComponent({
 					/>
 				</Popup> */}
 
-				<Popup
-					teleport="body"
-					closeOnClickOverlay={false}
-					class={["popup-custom", "van-scale"]}
-					transition="van-scale"
-					v-model:show={evaluatingData.resulstMode}
-				>
-					<EvaluatResult onClose={handleEvaluatResult} />
-				</Popup>
-				<Popup
-					teleport="body"
-					closeOnClickOverlay={false}
-					class={["popup-custom", "van-scale"]}
-					transition="van-scale"
-					v-model:show={evaluatModel.evaluatUpdateAudio}
-				>
-					<EvaluatAudio onClose={hanldeUpdateVideoAndAudio} />
-				</Popup>
-				<Popup
-					teleport="body"
-					class={["popup-custom", "van-scale"]}
-					transition="van-scale"
-					v-model:show={evaluatModel.shareMode}
-				>
-					<EvaluatShare onClose={() => (evaluatModel.shareMode = false)} />
-				</Popup>
-			</div>
-		);
-	},
+        <Popup teleport="body" closeOnClickOverlay={false} class={["popup-custom", "van-scale"]} transition="van-scale" v-model:show={evaluatingData.resulstMode}>
+          <EvaluatResult onClose={handleEvaluatResult} />
+        </Popup>
+        <Popup teleport="body" closeOnClickOverlay={false} class={["popup-custom", "van-scale"]} transition="van-scale" v-model:show={evaluatModel.evaluatUpdateAudio}>
+          <EvaluatAudio onClose={hanldeUpdateVideoAndAudio} />
+        </Popup>
+        <Popup teleport="body" class={["popup-custom", "van-scale"]} transition="van-scale" v-model:show={evaluatModel.shareMode}>
+          <EvaluatShare onClose={() => (evaluatModel.shareMode = false)} />
+        </Popup>
+      </div>
+    );
+  },
 });