Explorar o código

feat: 评测报告逻辑修改

TIANYONG hai 1 ano
pai
achega
fef1f2acde

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

@@ -24,7 +24,7 @@ export default defineComponent({
 			default: () => ({}),
 		},
 	},
-	setup(props) {
+	setup(props, {expose}) {
 		const browserInfo = browser();
 		const { scoreData } = toRefs(props);
 		const shareData = reactive({
@@ -47,6 +47,7 @@ export default defineComponent({
 
 		const handleChange = (type: IItemType) => {
 			itemType.value = type;
+			scoreData.value.itemType = type
 		};
 
 		// 资源类型
@@ -70,7 +71,6 @@ export default defineComponent({
 				shareData.isInitPlyr = true;
 			});
 		};
-
 		return () => (
 			<div class={[styles.headerTop, browserInfo.android && styles.android]}>
 				<div class={[styles.back, !storeData.isApp && styles.disabled]} onClick={handleBack}>
@@ -167,7 +167,7 @@ export default defineComponent({
 							</div>
 						)}
 						<div>
-							<Note fill="#000" />
+							<Note fill="#AEAEAE" />
 							<span>未演奏</span>
 						</div>
 					</div>

+ 49 - 0
src/page-instrument/view-evaluat-report/index.module.less

@@ -112,4 +112,53 @@
     fill: #CC75FF;
     stroke: #CC75FF;
   }
+}
+
+
+
+
+.right{
+  path{
+    fill: #01C1B5;
+    stroke: #01C1B5;
+  }
+}
+
+.wrong{
+  path{
+    fill: #FF4444;
+    stroke: #FF4444;
+  }
+}
+
+.notPlay{
+  path{
+    fill: #AEAEAE;
+    stroke: #AEAEAE;
+  }
+}
+
+.cadence_wrong,
+.cadence_fast,
+.cadence_slow {
+  path{
+    fill: #FF4444;
+    stroke: #FF4444;
+  }
+}
+
+.intonation_wrong,
+.intonation_high,
+.intonation_low{
+  path{
+    fill: #977CFF;
+    stroke: #977CFF;
+  }
+}
+
+.integrity_wrong{
+  path{
+    fill: #CC75FF;
+    stroke: #CC75FF;
+  }
 }

+ 164 - 12
src/page-instrument/view-evaluat-report/index.tsx

@@ -1,5 +1,5 @@
 import { Skeleton } from "vant";
-import { defineComponent, onBeforeMount, onBeforeUnmount, onMounted, reactive, Transition } from "vue";
+import { defineComponent, onBeforeMount, onBeforeUnmount, onMounted, reactive, Transition, watch, ref } from "vue";
 import { formateTimes } from "../../helpers/formateMusic";
 import state, { isRhythmicExercises, getMusicDetail, EnumMusicRenderType } from "../../state";
 import { setGlobalData } from "../../utils";
@@ -18,18 +18,53 @@ import ShareTop from "./component/share-top";
 import { addMeasureScore } from "/src/view/evaluating";
 
 const colorsClass: any = {
-	RIGHT: styles.right,
-	WRONG: styles.wrong,
-	NOT_PLAY: styles.notPlay,
-	CADENCE_WRONG: styles.cadence_wrong, // 节奏(快慢)
-	INTONATION_WRONG: styles.intonation_wrong, // 音准(高低)
-	INTEGRITY_WRONG: styles.integrity_wrong, // 完成度
-};
+	RIGHT: styles.right, // 正确
+	WRONG: styles.wrong, // 错误
+	NOT_PLAYED: styles.notPlay, // 未演奏
+	EARLY: styles.cadence_fast, // 节奏快
+	LATE: styles.cadence_slow, // 节奏慢
+	HIGH: styles.intonation_high, // 音准高
+	LOW: styles.intonation_low, // 音准低
+	DURATION_INSUFFICIENT: styles.integrity_wrong // 完整性(时值)不足
+}
+
+
+// const colorsClass: any = {
+// 	/** 音准 */
+// 	pitch: {
+// 		/** 高了 */
+// 		HIGH: styles.intonation_high,
+// 		/** 正常 */
+// 		RIGHT: styles.intonation_right,
+// 		/** 低了 */
+// 		LOW: styles.intonation_low,
+// 		/** 未演奏 */
+// 		NOT_PLAYED: styles.notPlay,
+// 		/** 错误 */
+// 		WRONG: styles.intonation_wrong,
+// 		/** 时值不足 */
+// 		DURATION_INSUFFICIENT: styles.integrity_wrong
+// 	},
+// 	/** 节奏 */
+// 	rhythmic: {
+// 		/** 过早 */
+// 		EARLY: styles.cadence_fast,
+// 		/** 正常 */
+// 		RIGHT: styles.cadence_right,
+// 		/** 过迟 */
+// 		LATE: styles.cadence_slow,
+// 		/** 未演奏 */
+// 		NOT_PLAYED: styles.notPlay,
+// 		/** 错误 */
+// 		WRONG: styles.cadence_wrong
+// 	}
+// }
 
 export default defineComponent({
 	name: "music-list",
 	setup() {
 		const query: any = getQuery();
+		const useedid = ref<string[]>([])
 		const scoreData = reactive({
 			videoFilePath: "", // 回放视频路径
 			cadence: 0,
@@ -37,6 +72,7 @@ export default defineComponent({
 			intonation: 0,
 			score: 0,
 			heardLevel: "",
+			itemType: "intonation",
 		});
 
 		const detailData = reactive({
@@ -161,11 +197,121 @@ export default defineComponent({
 			// });
 		});
 
+
+		const getOffsetPosition = (type: keyof typeof colorsClass): string => {
+			switch (type) {
+			  case 'EARLY':
+				return 'translateX(-2px)'
+			  case 'LATE':
+				return 'translateX(2px)'
+			  case 'HIGH':
+				return 'translateY(-2px)'
+			  case 'LOW':
+				return 'translateY(2px)'
+			  default:
+				return ''
+			}
+		  }
+	  
+		  const filterNotes = () => {
+			const include = ['RIGHT', 'WRONG', 'NOT_PLAYED']
+			if (scoreData.itemType === 'intonation') { // 音准
+			  include.push(...['HIGH', 'LOW'])
+			} else if (scoreData.itemType === 'cadence') { // 节奏
+			  include.push(...['EARLY', 'LATE'])
+			} else if (scoreData.itemType === 'integrity') { // 完整性
+			  include.push(...['DURATION_INSUFFICIENT'])
+			}
+			if (scoreData.itemType === 'cadence') {
+				return detailData.musicalNotesPlayStats.filter((item: any) => include.includes(item.rhythmicAssessment.result))
+			} else {
+				return detailData.musicalNotesPlayStats.filter((item: any) => include.includes(item.pitchAssessment.result))
+			}
+		  }
+	  
+		  const setViewColor = () => {
+			clearViewColor()
+			const notes = filterNotes()
+			//console.log(1111,notes)
+			for (const note of notes) {
+			  const active = state.times[note.index]
+			  setTimeout(() => {
+				if (useedid.value.includes(active.id)) {
+				  return
+				}
+				useedid.value.push(active.id)
+				const svgEl = document.getElementById('vf-' + active.id)
+				const stemEl = document.getElementById('vf-' + active.id + '-stem')
+				const errType = scoreData.itemType === 'cadence' ? note.rhythmicAssessment.result : note.pitchAssessment.result
+				//console.log(1111222,errType)
+				const isNeedCopyElement = ['HIGH', 'LOW', 'EARLY', 'LATE'].includes(
+				  errType
+				)
+				stemEl?.classList.add(colorsClass[errType])
+				svgEl?.classList.add(colorsClass[errType])
+				if (svgEl && isNeedCopyElement) {
+				  stemEl?.classList.remove(colorsClass[errType])
+				  stemEl?.classList.add(colorsClass.RIGHT)
+				  svgEl?.classList.remove(colorsClass[errType])
+				  svgEl?.classList.add(colorsClass.RIGHT)
+				  const copySvg = svgEl.querySelector('.vf-notehead')!.cloneNode(true) as SVGSVGElement
+				  copySvg.style.transform = getOffsetPosition(errType)
+				  svgEl.style.opacity = '.7'
+				  if (stemEl) {
+					stemEl.style.opacity = '.7'
+				  }
+				  copySvg.id = 'vf-' + active.id + '-copy'
+				  copySvg?.classList.add(colorsClass[errType])
+				  // stemEl?.classList.add(colorsClass.RIGHT)
+				  // @ts-ignore
+				  runtime.osmd?.container.querySelector('svg')!.insertAdjacentElement('afterbegin', copySvg)
+				  // svgEl?.parentElement?.appendChild(copySvg)
+				}
+			  }, 300)
+			}
+		  }
+	  
+		  const removeClass = (el?: HTMLElement | null) => {
+			if (!el) return
+			const classList = el.classList.values()
+			for (const val of classList) {
+			  if (val?.indexOf('vf-') !== 0) {
+				el.classList.remove(val)
+			  }
+			}
+		  }
+	  
+		  const clearViewColor = () => {
+			for (const id of useedid.value) {
+			  removeClass(document.getElementById('vf-' + id))
+			  removeClass(document.getElementById('vf-' + id + '-stem'))
+			  const qid = 'vf-' + id + '-copy'
+			  const copyEl = document.getElementById(qid)
+			  if (copyEl) {
+				copyEl.remove()
+			  }
+			}
+			useedid.value = []
+		  }
+		
 		const setPathColor = () => {
+			console.log(11111,detailData.musicalNotesPlayStats,scoreData.itemType)
 			for (const note of detailData.musicalNotesPlayStats) {
-				const active = state.times[note.musicalNotesIndex];
+				const active = state.times[note.index];
 				const svgEl = active?.id ? document.getElementById("vf-" + active?.id) : null;
-				svgEl?.classList.add(colorsClass[note.musicalErrorType]);
+				switch (scoreData.itemType) {
+					case "intonation":
+						svgEl?.classList.add(colorsClass.pitch[note.pitchAssessment.result]);
+						break;
+					case "cadence":
+						svgEl?.classList.add(colorsClass.rhythmic[note.rhythmicAssessment.result]);
+						break;	
+					case "integrity":
+						svgEl?.classList.add(colorsClass.pitch[note.pitchAssessment.result]);
+						break;								
+					default:
+						break;
+				}
 			}
 		};
 		const setMearureColor = () => {
@@ -180,7 +326,8 @@ export default defineComponent({
 			state.osmd = osmd;
 			state.times = formateTimes(osmd);
 			console.log("🚀 ~ state.times:", state.times);
-			setPathColor();
+			//setPathColor();
+			setViewColor();
 			setMearureColor();
 			api_cloudLoading();
 		};
@@ -190,7 +337,12 @@ export default defineComponent({
 		onBeforeUnmount(() => {
 			window.removeEventListener("resize", resetMusicScore);
 		});
-
+		watch(
+			() => scoreData.itemType,
+			() => {
+				setViewColor();
+			}
+		);
 		return () => (
 			<div
 				class={[styles.detail, state.setting.eyeProtection && "eyeProtection", styles.shareBox]}