Browse Source

管乐团initiate

liushengqiang 2 years ago
parent
commit
82ddd3fffa
100 changed files with 2690 additions and 0 deletions
  1. 48 0
      src/page-orchestra/App.tsx
  2. 30 0
      src/page-orchestra/api.ts
  3. 1 0
      src/page-orchestra/component/the-comfirm/index.json
  4. 44 0
      src/page-orchestra/component/the-comfirm/index.module.less
  5. 28 0
      src/page-orchestra/component/the-comfirm/index.tsx
  6. 75 0
      src/page-orchestra/detail/index.module.less
  7. 271 0
      src/page-orchestra/detail/index.tsx
  8. 0 0
      src/page-orchestra/evaluat-model/data/start.json
  9. 0 0
      src/page-orchestra/evaluat-model/data/starting.json
  10. 37 0
      src/page-orchestra/evaluat-model/earphone/index.module.less
  11. 20 0
      src/page-orchestra/evaluat-model/earphone/index.tsx
  12. 1 0
      src/page-orchestra/evaluat-model/evaluat-audio/index.json
  13. 43 0
      src/page-orchestra/evaluat-model/evaluat-audio/index.module.less
  14. 22 0
      src/page-orchestra/evaluat-model/evaluat-audio/index.tsx
  15. 16 0
      src/page-orchestra/evaluat-model/evaluat-result/img/cadence.svg
  16. 43 0
      src/page-orchestra/evaluat-model/evaluat-result/img/icon-badge.svg
  17. 8 0
      src/page-orchestra/evaluat-model/evaluat-result/img/integrity.svg
  18. 8 0
      src/page-orchestra/evaluat-model/evaluat-result/img/intonation.svg
  19. 1 0
      src/page-orchestra/evaluat-model/evaluat-result/index.json
  20. 226 0
      src/page-orchestra/evaluat-model/evaluat-result/index.module.less
  21. 79 0
      src/page-orchestra/evaluat-model/evaluat-result/index.tsx
  22. 30 0
      src/page-orchestra/evaluat-model/evaluat-share/index.module.less
  23. 75 0
      src/page-orchestra/evaluat-model/evaluat-share/index.tsx
  24. BIN
      src/page-orchestra/evaluat-model/icons/1.png
  25. BIN
      src/page-orchestra/evaluat-model/icons/2.png
  26. BIN
      src/page-orchestra/evaluat-model/icons/3.png
  27. BIN
      src/page-orchestra/evaluat-model/icons/4.png
  28. BIN
      src/page-orchestra/evaluat-model/icons/5.png
  29. 9 0
      src/page-orchestra/evaluat-model/icons/arrow-left-background.svg
  30. BIN
      src/page-orchestra/evaluat-model/icons/bad.png
  31. 15 0
      src/page-orchestra/evaluat-model/icons/close.svg
  32. 12 0
      src/page-orchestra/evaluat-model/icons/close2.svg
  33. BIN
      src/page-orchestra/evaluat-model/icons/erji.png
  34. 1 0
      src/page-orchestra/evaluat-model/icons/evaluating.json
  35. BIN
      src/page-orchestra/evaluat-model/icons/good.png
  36. BIN
      src/page-orchestra/evaluat-model/icons/great.png
  37. 2 0
      src/page-orchestra/evaluat-model/icons/index.json
  38. BIN
      src/page-orchestra/evaluat-model/icons/left-bg.png
  39. BIN
      src/page-orchestra/evaluat-model/icons/perfect.png
  40. BIN
      src/page-orchestra/evaluat-model/icons/student.png
  41. 9 0
      src/page-orchestra/evaluat-model/icons/task-bg.svg
  42. BIN
      src/page-orchestra/evaluat-model/icons/title.png
  43. 96 0
      src/page-orchestra/evaluat-model/index.module.less
  44. 272 0
      src/page-orchestra/evaluat-model/index.tsx
  45. 54 0
      src/page-orchestra/evaluat-model/sound-effect/data.ts
  46. BIN
      src/page-orchestra/evaluat-model/sound-effect/icons/bg-note.png
  47. BIN
      src/page-orchestra/evaluat-model/sound-effect/icons/bg.png
  48. BIN
      src/page-orchestra/evaluat-model/sound-effect/icons/child.png
  49. BIN
      src/page-orchestra/evaluat-model/sound-effect/icons/content-bg.png
  50. BIN
      src/page-orchestra/evaluat-model/sound-effect/icons/dot-active.png
  51. BIN
      src/page-orchestra/evaluat-model/sound-effect/icons/dot-error.png
  52. BIN
      src/page-orchestra/evaluat-model/sound-effect/icons/dot.png
  53. 11 0
      src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_120.svg
  54. 11 0
      src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_12_4.svg
  55. 10 0
      src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_13.svg
  56. 11 0
      src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_14_15.svg
  57. 11 0
      src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_5_6.svg
  58. 11 0
      src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_default.svg
  59. BIN
      src/page-orchestra/evaluat-model/sound-effect/icons/notes.png
  60. 104 0
      src/page-orchestra/evaluat-model/sound-effect/index.module.less
  61. 84 0
      src/page-orchestra/evaluat-model/sound-effect/index.tsx
  62. 1 0
      src/page-orchestra/follow-model/icons.json
  63. 36 0
      src/page-orchestra/follow-model/index.module.less
  64. 50 0
      src/page-orchestra/follow-model/index.tsx
  65. 9 0
      src/page-orchestra/header-top/image/arrow.svg
  66. 12 0
      src/page-orchestra/header-top/image/close2.svg
  67. 16 0
      src/page-orchestra/header-top/image/down.svg
  68. 12 0
      src/page-orchestra/header-top/image/guding-active.svg
  69. 12 0
      src/page-orchestra/header-top/image/guding.svg
  70. 1 0
      src/page-orchestra/header-top/image/headerTop.json
  71. 8 0
      src/page-orchestra/header-top/image/icon-back.svg
  72. 13 0
      src/page-orchestra/header-top/image/icon-staff-active.svg
  73. 13 0
      src/page-orchestra/header-top/image/icon-staff.svg
  74. 9 0
      src/page-orchestra/header-top/image/icon-zhuanpu.svg
  75. BIN
      src/page-orchestra/header-top/image/iconStep.png
  76. 5 0
      src/page-orchestra/header-top/image/index.ts
  77. 19 0
      src/page-orchestra/header-top/image/info.svg
  78. 8 0
      src/page-orchestra/header-top/image/menu.svg
  79. BIN
      src/page-orchestra/header-top/image/minus.png
  80. 15 0
      src/page-orchestra/header-top/image/modeType.svg
  81. BIN
      src/page-orchestra/header-top/image/music.png
  82. 36 0
      src/page-orchestra/header-top/image/off.svg
  83. 39 0
      src/page-orchestra/header-top/image/on.svg
  84. BIN
      src/page-orchestra/header-top/image/plus.png
  85. 25 0
      src/page-orchestra/header-top/image/replay.svg
  86. 11 0
      src/page-orchestra/header-top/image/section0.svg
  87. 11 0
      src/page-orchestra/header-top/image/section1.svg
  88. 11 0
      src/page-orchestra/header-top/image/section2.svg
  89. 11 0
      src/page-orchestra/header-top/image/shuodiao-active.svg
  90. 11 0
      src/page-orchestra/header-top/image/shuodiao.svg
  91. 41 0
      src/page-orchestra/header-top/image/speed.svg
  92. 9 0
      src/page-orchestra/header-top/image/task-bg.svg
  93. BIN
      src/page-orchestra/header-top/image/tickoff.png
  94. BIN
      src/page-orchestra/header-top/image/tickon.png
  95. 20 0
      src/page-orchestra/header-top/image/tv.svg
  96. 21 0
      src/page-orchestra/header-top/image/yijian.svg
  97. 128 0
      src/page-orchestra/header-top/index.module.less
  98. 219 0
      src/page-orchestra/header-top/index.tsx
  99. 12 0
      src/page-orchestra/header-top/mode-type-mode/index.module.less
  100. 17 0
      src/page-orchestra/header-top/mode-type-mode/index.tsx

+ 48 - 0
src/page-orchestra/App.tsx

@@ -0,0 +1,48 @@
+import request from "umi-request";
+import { computed, defineComponent, onBeforeMount, onMounted } from "vue";
+import { RouterView } from "vue-router";
+import TheError from "../components/The-error";
+import { setUserInfo, storeData } from "../store";
+import { getRandomKey, setToken } from "../utils";
+import { getQuery } from "../utils/queryString";
+import Notfind from "../view/notfind";
+import { employeeQueryUserInfo, studentQueryUserInfo, teacherQueryUserInfo } from "./api";
+
+export default defineComponent({
+	name: "App",
+	setup() {
+		const query: any = getQuery()
+		/** 获取用户信息 */
+		const getUserInfo = async () => {
+			// const a = await request.get(`/student/queryUserInfo`)
+			// console.log(a)
+			if (storeData.platformType === "WEB") {
+				return await employeeQueryUserInfo();
+			} else if (storeData.platformType === "TEACHER") {
+				return await teacherQueryUserInfo();
+			}
+			return await studentQueryUserInfo();
+		};
+		const setUser = async () => {
+			const res = await getUserInfo();
+			const student = res?.data || {};
+			setUserInfo(student);
+			// console.log("🚀 ~ res:", student);
+		};
+		onBeforeMount(() => {
+			if (query.Authorization) {
+				setToken(query.Authorization);
+			}
+			setUser();
+			localStorage.setItem("behaviorId", getRandomKey());
+		});
+		onMounted(() => {
+			document.getElementById("loading")!.className = "";
+		})
+
+		const inited = computed(() => {
+			return storeData.status === "login";
+		});
+		return () => <>{storeData.status === "error" ? <TheError /> : inited.value ? <RouterView /> : null}</>;
+	},
+});

+ 30 - 0
src/page-orchestra/api.ts

@@ -0,0 +1,30 @@
+import request from "../utils/request";
+
+/** 获取学生信息 */
+export const studentQueryUserInfo = async () => {
+	return await request.get(`/student/queryUserInfo`);
+};
+/** 获取老师信息 */
+export const teacherQueryUserInfo = () => {
+	return request.get(`/student/queryUserInfo`);
+};
+/** 后台用户信息 */
+export const employeeQueryUserInfo = () => {
+	return request.get(`/employee/queryUserInfo`);
+};
+
+/** 获取曲谱信息 */
+export const sysMusicScoreAccompanimentQueryPage = (sysMusicScoreId: string) => {
+	return request.get("/music/sheet/detail/" + sysMusicScoreId);
+};
+
+/** 获取曲谱分类 */
+export const sysMusicScoreCategoriesQueryTree = (enable = false) => {
+	return request.get(`/sysMusicScoreCategories/queryTree`, {
+		params: {
+			parentId: 0,
+			// 后台详情忽略是否启用分类
+			enable,
+		},
+	});
+};

File diff suppressed because it is too large
+ 1 - 0
src/page-orchestra/component/the-comfirm/index.json


+ 44 - 0
src/page-orchestra/component/the-comfirm/index.module.less

@@ -0,0 +1,44 @@
+.fraction {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    color: #fff;
+    background-color: #fff;
+    border-radius: 18px;
+    min-width: 244px;
+}
+
+.title {
+    position: relative;
+    width: 100px;
+    height: 30px;
+    top: -4.5px;
+
+    img {
+        display: block;
+        width: 100%;
+        height: 100%;
+    }
+}
+
+.tip {
+    font-size: 13px;
+    color: #808080;
+    padding: 20px 0;
+}
+.btns{
+    display: flex;
+    justify-content: space-evenly;
+    align-items: center;
+    width: 100%;
+    max-width: 244px;
+}
+.btn {
+    width: 40%;
+    height: 31px;
+    margin: 11px 0 17px 0;
+    line-height: 31px;
+    text-align: center;
+    border-radius: 36px;
+    font-size: 13px;
+}

+ 28 - 0
src/page-orchestra/component/the-comfirm/index.tsx

@@ -0,0 +1,28 @@
+import { defineComponent } from "vue";
+import styles from "./index.module.less";
+import icons from "./index.json";
+
+export default defineComponent({
+	name: "evaluat-audio",
+	props: {
+		tip: {
+			type: String,
+			default: () => ''
+		}
+	},
+	emits: ["close"],
+	setup(props, { emit }) {
+		return () => (
+			<div class={styles.fraction}>
+				<div class={styles.title}>
+					<img src={icons.title} />
+				</div>
+				<div class={styles.tip}>{props.tip}</div>
+				<div class={styles.btns}>
+					<img src={icons.cancel} class={styles.btn} onClick={() => emit("close")} />
+					<img src={icons.confirm} class={styles.btn} onClick={() => emit("close", true)} />
+				</div>
+			</div>
+		);
+	},
+});

+ 75 - 0
src/page-orchestra/detail/index.module.less

@@ -0,0 +1,75 @@
+.skeleton {
+    position: fixed;
+    left: 0;
+    top: 0;
+    width: 100vw;
+    height: 100vh;
+    padding: 20px 30px;
+    background-color: #fff;
+    z-index: 10;
+    --van-skeleton-paragraph-height: .8rem;
+}
+
+.detail {
+    width: 100vw;
+    height: 100vh;
+    overflow: hidden;
+    --header-height: 62px;
+    background: var(--container-background);
+
+    .headHeight {
+        position: fixed;
+        left: 0;
+        top: 0;
+        width: 100%;
+        height: var(--header-height);
+        transition: margin .3s;
+        z-index: 10;
+        &.headHide{
+            margin-top: calc(0Px - var(--header-height));
+        }
+    }
+
+    .container {
+        position: relative;
+        height: 100vh;
+        margin: 0 10px;
+        border-radius: 10px;
+        padding-top: var(--header-height);
+        overflow-x: hidden;
+        overflow-y: auto;
+        &::-webkit-scrollbar {
+            width: 0;
+            display: none;
+        }
+        :global{
+            #musicAndSelection{
+                overflow: auto;
+                height: initial;
+                max-height: initial;
+            }
+        }
+    }
+}
+
+.plugins {
+    display: none;
+}
+
+:global {
+    #cursorImg-0 {
+        min-height: 58PX;
+        content: url(data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7);
+        margin-top: -14PX;
+        border-radius: 4Px;
+        background-color: var(--van-primary-color);
+        width: 8Px;
+        transform: translateX(8Px);
+        opacity: var(--corsor-opacity);
+    }
+    .eyeProtection{
+        #cursorImg-0{
+            background-color: rgb(255, 159, 88);
+        }
+    }
+}

+ 271 - 0
src/page-orchestra/detail/index.tsx

@@ -0,0 +1,271 @@
+import { Skeleton } from "vant";
+import { computed, defineComponent, nextTick, onBeforeMount, onBeforeUnmount, onMounted, reactive, Transition, watch, watchEffect } from "vue";
+import { useRoute } from "vue-router";
+import { formateTimes } from "../../helpers/formateMusic";
+import Metronome, { metronomeData } from "../../helpers/metronome";
+import state, { isRhythmicExercises } from "../../state";
+import { storeData } from "../../store";
+import { setGlobalData } from "../../utils";
+import AudioList from "../../view/audio-list";
+import MusicScore, { resetMusicScore } from "../../view/music-score";
+import { sysMusicScoreAccompanimentQueryPage, sysMusicScoreCategoriesQueryTree } from "../api";
+import EvaluatModel from "../evaluat-model";
+import HeaderTop from "../header-top";
+import styles from "./index.module.less";
+import { api_cloudLoading, api_openCamera, api_setStatusBarVisibility, isSpecialShapedScreen } from "/src/helpers/communication";
+import { getQuery } from "/src/utils/queryString";
+import Evaluating, { evaluatingData } from "/src/view/evaluating";
+import MeasureSpeed from "/src/view/plugins/measure-speed";
+import { mappingVoicePart, subjectFingering } from "/src/view/fingering/fingering-config";
+import Fingering from "/src/view/fingering";
+import store from "store";
+import Tick, { handleInitTick } from "/src/view/tick";
+import FollowPractice from "/src/view/follow-practice";
+import FollowModel from "../follow-model";
+
+export default defineComponent({
+	name: "music-list",
+	setup() {
+		const query: any = getQuery();
+
+		const detailData = reactive({
+			isLoading: true,
+			paddingLeft: "",
+			headerHide: false,
+		});
+		const getAPPData = async () => {
+			const screenData = await isSpecialShapedScreen();
+			if (screenData?.content) {
+				// console.log("🚀 ~ screenData:", screenData.content);
+				const { isSpecialShapedScreen, notchHeight } = screenData.content;
+				if (isSpecialShapedScreen) {
+					detailData.paddingLeft = 25 + "px";
+				}
+			}
+		};
+		onBeforeMount(() => {
+			getAPPData();
+			api_setStatusBarVisibility();
+			const settting = store.get("musicscoresetting");
+			if (settting) {
+				state.setting = settting;
+				if (state.setting.camera) {
+					api_openCamera();
+				}
+				// console.log("🚀 ~ settting:", settting)
+			}
+		});
+		// console.log(route.params, query)
+		/** 获取曲谱数据 */
+		const getMusicInfo = (res: any) => {
+			const index = query["part-index"] ? parseInt(query["part-index"] as string) : 0;
+			const musicInfo = {
+				...res.data,
+				...res.data.background[index],
+			};
+			// console.log("🚀 ~ musicInfo:", musicInfo);
+			setState(musicInfo, index);
+			setCustom();
+			detailData.isLoading = false;
+		};
+
+		const setState = (data: any, index: number) => {
+			state.scrollContainer = "scrollContainer";
+			state.appName = "COLEXIU";
+			state.detailId = data.id;
+			state.xmlUrl = data.xmlFileUrl;
+			state.partIndex = index;
+			state.subjectId = data.musicSubject;
+			state.categoriesId = data.categoriesId;
+			state.categoriesName = data.musicTagNames;
+			state.enableEvaluation = data.canEvaluate ? true : false;
+			state.examSongId = data.id + "";
+			state.examSongName = data.musicSheetName;
+			// 解析扩展字段
+			if (data.extConfigJson) {
+				try {
+					state.extConfigJson = JSON.parse(data.extConfigJson as string);
+				} catch (error) {
+					console.error("解析扩展字段错误:", error);
+				}
+			}
+			state.isOpenMetronome = data.mp3Type === "MP3_METRONOME" ? true : false;
+			state.needTick = true; // data.isOpenMetronome;
+			state.isShowFingering = data.showFingering ? true : false;
+			state.music = data.audioFileUrl;
+			state.accompany = data.metronomeUrl || data.metronomeUrl;
+			state.midiUrl = data.midiUrl;
+			state.parentCategoriesId = data.musicTag;
+			state.playMode = data.audioType === "MP3" ? "mp3" : "midi";
+			state.originSpeed = state.speed = data.playSpeed;
+			state.track = data.track;
+			state.enableNotation = data.notation ? true : false;
+
+			// 映射声部ID
+			state.subjectId = mappingVoicePart(state.track as any, "COLEXIU");
+			// 是否打击乐
+			state.isPercussion = state.subjectId == 23 || state.subjectId == 113 || state.subjectId == 121 || isRhythmicExercises();
+
+			// 设置指法
+			state.fingeringInfo = subjectFingering(state.subjectId);
+			// console.log("🚀 ~ state.fingeringInfo:", state.fingeringInfo, state.subjectId, state.track)
+		};
+
+		const setCustom = () => {
+			if (state.extConfigJson.multitrack) {
+				setGlobalData("multitrack", state.extConfigJson.multitrack);
+			}
+		};
+
+		onMounted(() => {
+			(window as any).appName = "colexiu";
+			Promise.all([sysMusicScoreAccompanimentQueryPage(query.id)]).then((values) => {
+				getMusicInfo(values[0]);
+			});
+		});
+
+		/** 渲染完成 */
+		const handleRendered = (osmd: any) => {
+			state.musicRendered = true;
+			state.osmd = osmd;
+			const saveSpeed = (store.get("speeds") || {})[state.examSongId];
+			const bpm = (osmd as any).bpm || osmd.Sheet.userStartTempoInBPM;
+			state.originSpeed = state.speed = saveSpeed || bpm || 100;
+			state.times = formateTimes(osmd);
+			console.log("🚀 ~ state.times:", state.times);
+			try {
+				metronomeData.metro = new Metronome();
+				metronomeData.metro.init(state.times);
+			} catch (error) {}
+			// 设置节拍器
+			if (state.needTick) {
+				const beatLengthInMilliseconds = osmd?.Sheet?.SheetPlaybackSetting?.beatLengthInMilliseconds || (60 / bpm) * 1000;
+				handleInitTick(beatLengthInMilliseconds, osmd?.Sheet?.SheetPlaybackSetting?.Rhythm?.Numerator || 4);
+			}
+			api_cloudLoading()
+		};
+		/** 指法配置 */
+		const fingerConfig = computed<any>(() => {
+			if (state.setting.displayFingering && state.fingeringInfo?.name) {
+				if (state.fingeringInfo.direction === "transverse") {
+					return {
+						container: {
+							paddingBottom: state.fingeringInfo.height,
+						},
+						fingerBox: {
+							height: state.fingeringInfo.height,
+						},
+					};
+				} else {
+					return {
+						container: {
+							paddingRight: state.fingeringInfo.width,
+						},
+						fingerBox: {
+							position: "absolute",
+							width: state.fingeringInfo.width,
+							height: "100%",
+							right: 0,
+							top: 0,
+						},
+					};
+				}
+			}
+			return {
+				container: {},
+				fingerBox: {},
+			};
+		});
+
+		// 监听指法显示
+		watch(
+			() => state.setting.displayFingering,
+			() => {
+				if (state.fingeringInfo.direction === "vertical") {
+					if (state.setting.displayFingering) {
+						document.getElementById("musicAndSelection")?.style.removeProperty("--music-zoom");
+					} else {
+						nextTick(() => {
+							resetMusicScore();
+						});
+					}
+				}
+			}
+		);
+		// 监听播放状态
+		watch(
+			() => state.playState,
+			() => {
+				detailData.headerHide = state.playState === "play" ? true : false;
+			}
+		);
+		onMounted(() => {
+			window.addEventListener("resize", resetMusicScore);
+		});
+		onBeforeUnmount(() => {
+			window.removeEventListener("resize", resetMusicScore);
+		});
+		return () => (
+			<div
+				class={[styles.detail, state.setting.eyeProtection && "eyeProtection"]}
+				style={{ paddingLeft: detailData.paddingLeft, opacity:  state.setting.camera ? `${state.setting.cameraOpacity / 100}` : ''}}
+			>
+				{!state.musicRendered && (
+					<div class={styles.skeleton}>
+						<Skeleton class={styles.skeleton} row={8} />
+					</div>
+				)}
+				<div class={[styles.headHeight, detailData.headerHide && styles.headHide]}>
+					<Transition name="van-slide-down">{state.musicRendered && <HeaderTop />}</Transition>
+				</div>
+				<div
+					id="scrollContainer"
+					style={{ ...fingerConfig.value.container }}
+					class={[styles.container, !state.setting.displayCursor && "hideCursor"]}
+					onClick={(e: Event) => {
+						if (state.playState === "play") {
+							detailData.headerHide = !detailData.headerHide;
+						}
+					}}
+				>
+					{/* 曲谱渲染 */}
+					{!detailData.isLoading && <MusicScore onRendered={handleRendered} />}
+					{/* 播放 */}
+					{!detailData.isLoading && <AudioList />}
+					{/* 评测 */}
+					{state.modeType === "evaluating" && (
+						<>
+							<Evaluating />
+							{evaluatingData.rendered && <EvaluatModel />}
+						</>
+					)}
+					{/* 指法 */}
+					{state.setting.displayFingering && state.fingeringInfo?.name && (
+						<div style={{ ...fingerConfig.value.fingerBox }}>
+							<Fingering />
+						</div>
+					)}
+				</div>
+
+				{/* 公用的插件 */}
+				<div class={styles.plugins}>
+					{state.musicRendered && (
+						<>
+							<MeasureSpeed />
+						</>
+					)}
+				</div>
+				{/* 节拍器 */}
+				{state.needTick && <Tick />}
+
+				{/* 跟练模式 */}
+				{state.modeType === "follow" && (
+					<>
+						<FollowPractice />
+						<FollowModel />
+					</>
+				)}
+			</div>
+		);
+	},
+});

File diff suppressed because it is too large
+ 0 - 0
src/page-orchestra/evaluat-model/data/start.json


File diff suppressed because it is too large
+ 0 - 0
src/page-orchestra/evaluat-model/data/starting.json


+ 37 - 0
src/page-orchestra/evaluat-model/earphone/index.module.less

@@ -0,0 +1,37 @@
+.fraction {
+    
+    color: #fff;
+    border-radius: 18px;
+    width: 244px;
+    overflow: hidden;
+}
+.content{
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    width: 100%;
+    background-color: #fff;
+}
+.title {
+    color: #1A1A1A;
+    font-size: 17px;
+    padding: 16px 0 10px 0;
+    font-weight: bold;
+}
+
+.erji {
+    width: 100%;
+    display: block;
+}
+
+.tip {
+    font-size: 13px;
+    color: #808080;
+}
+
+.btn {
+    display: block;
+    width: 106px;
+    height: 31px;
+    margin: 11px 0 17px 0;
+}

+ 20 - 0
src/page-orchestra/evaluat-model/earphone/index.tsx

@@ -0,0 +1,20 @@
+import { defineComponent } from "vue";
+import styles from "./index.module.less";
+import icons from "../icons/index.json";
+
+export default defineComponent({
+	name: "earphone",
+	emits: ["close"],
+	setup(props, { emit }) {
+		return () => (
+			<div class={styles.fraction}>
+				<img class={styles.erji} src={icons.erji} />
+				<div class={styles.content}>
+					<div class={styles.title}>请佩戴耳机</div>
+					<div class={styles.tip}>佩戴耳机以保证测评准确率~</div>
+					<img src={icons.erjibtn} class={styles.btn} onClick={() => emit("close")} />
+				</div>
+			</div>
+		);
+	},
+});

File diff suppressed because it is too large
+ 1 - 0
src/page-orchestra/evaluat-model/evaluat-audio/index.json


+ 43 - 0
src/page-orchestra/evaluat-model/evaluat-audio/index.module.less

@@ -0,0 +1,43 @@
+.fraction {
+    display: flex;
+    flex-direction: column;
+    align-items: center;
+    color: #fff;
+    background-color: #fff;
+    border-radius: 18px;
+    min-width: 244px;
+}
+
+.title {
+    position: relative;
+    width: 100px;
+    height: 30px;
+    top: -4.5px;
+
+    img {
+        display: block;
+        width: 100%;
+        height: 100%;
+    }
+}
+
+.tip {
+    font-size: 13px;
+    color: #808080;
+    padding: 20px 0;
+}
+.btns{
+    display: flex;
+    justify-content: space-evenly;
+    align-items: center;
+    width: 100%;
+}
+.btn {
+    width: 40%;
+    height: 31px;
+    margin: 11px 0 17px 0;
+    line-height: 31px;
+    text-align: center;
+    border-radius: 36px;
+    font-size: 13px;
+}

+ 22 - 0
src/page-orchestra/evaluat-model/evaluat-audio/index.tsx

@@ -0,0 +1,22 @@
+import { defineComponent } from "vue";
+import styles from "./index.module.less";
+import icons from "./index.json";
+
+export default defineComponent({
+	name: "evaluat-audio",
+	emits: ["close"],
+	setup(props, { emit }) {
+		return () => (
+			<div class={styles.fraction}>
+				<div class={styles.title}>
+					<img src={icons.title} />
+				</div>
+				<div class={styles.tip}>评测{false ? "音视频" : "音频"}是否上传到云端?</div>
+				<div class={styles.btns}>
+					<img src={icons.cancel} class={styles.btn} onClick={() => emit("close")} />
+					<img src={icons.confirm} class={styles.btn} onClick={() => emit("close", true)} />
+				</div>
+			</div>
+		);
+	},
+});

+ 16 - 0
src/page-orchestra/evaluat-model/evaluat-result/img/cadence.svg

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="23px" height="21px" viewBox="0 0 23 21" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组备份 10</title>
+    <g id="修改" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="评测" transform="translate(-373.000000, -163.000000)">
+            <g id="编组-10" transform="translate(211.000000, 63.000000)">
+                <g id="编组-4" transform="translate(18.000000, 34.411322)">
+                    <g id="编组-5" transform="translate(144.200000, 65.588678)">
+                        <path d="M16.0007214,10.5467681 L15.4185357,10.5467681 L14.7313532,11.6196168 C14.6473534,11.7509497 14.5002017,11.8281126 14.3444036,11.8225241 C14.1886055,11.8169356 14.0473606,11.729428 13.9729864,11.5924143 L13.1708921,10.115849 L11.9394042,13.1368588 C11.7705957,13.5509988 11.1634955,13.479306 11.0956162,13.0372008 L10.396485,8.46539068 L9.78684248,11.6864792 C9.70599748,12.1143475 9.11974411,12.1781592 8.94864762,11.7780018 L8.15367179,9.91805838 L7.75453138,10.3904169 C7.67088986,10.4895664 7.54784275,10.5467681 7.41793145,10.5467681 L6.44474069,10.5467681 C6.24527423,10.8922541 5.8386268,11.060693 5.45328718,10.9574416 C5.06794756,10.8541901 4.8,10.5049941 4.8,10.1060611 C4.8,9.70712821 5.06794756,9.35793214 5.45328718,9.2546807 C5.8386268,9.15142927 6.24527423,9.31986815 6.44474069,9.6653542 L7.21353088,9.6653542 L7.94139011,8.80351599 C8.04003843,8.68670104 8.19219714,8.62938263 8.34339939,8.65207851 C8.49460164,8.67477439 8.62322675,8.77423924 8.68323196,8.91486854 L9.18991147,10.1000867 L10.0092933,5.77004889 C10.1013244,5.28319929 10.802998,5.2954023 10.8777415,5.78530266 L11.7255971,11.3264901 L12.7059063,8.92147851 C12.846241,8.57725168 13.3236841,8.55081181 13.5011363,8.87749679 L14.3914483,10.5162605 L14.8060967,9.86848361 C14.8870846,9.74190553 15.0270019,9.66533439 15.1772718,9.6653542 L15.8886061,9.6653542 C16.0443893,9.29876579 16.4266137,9.08215459 16.8211538,9.1368681 C17.2156939,9.1915816 17.5245501,9.50402956 17.5746985,9.89917587 C17.6248469,10.2943222 17.403831,10.6740167 17.035466,10.8255511 C16.6671011,10.9770856 16.2428849,10.8628205 16.0004671,10.5467681 L16.0007214,10.5467681 Z" id="路径" fill="#2DC7AA" fill-rule="nonzero"></path>
+                        <rect id="矩形" stroke="#2DC7AA" x="3.3" y="3.91132219" width="15" height="11" rx="2"></rect>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 43 - 0
src/page-orchestra/evaluat-model/evaluat-result/img/icon-badge.svg

@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="78px" height="87px" viewBox="0 0 78 87" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>徽章</title>
+    <defs>
+        <path d="M3.68074224,3.34475119 L26.209171,3.34475119 L26.209171,20.9920204 C26.209171,23.1071787 24.4944964,24.8218533 22.3793381,24.8218533 C21.7507061,24.8218533 21.1317391,24.6671115 20.5770638,24.3712847 L19.1802507,23.6263177 C16.5331919,22.214553 13.3567213,22.214553 10.7096625,23.6263177 L9.31284943,24.3712847 C7.44653328,25.3666533 5.12667942,24.6606108 4.13131081,22.7942947 C3.835484,22.2396194 3.68074224,21.6206524 3.68074224,20.9920204 L3.68074224,3.34475119 L3.68074224,3.34475119 Z" id="path-1"></path>
+        <path d="M4.41275563,3.95453496 L26.9411844,3.95453496 L26.9411844,21.6018042 C26.9411844,23.7169625 25.2265098,25.431637 23.1113515,25.431637 C22.4827195,25.431637 21.8637525,25.2768953 21.3090772,24.9810685 L19.9122641,24.2361015 C17.2652053,22.8243368 14.0887347,22.8243368 11.4416759,24.2361015 L10.0448628,24.9810685 C8.17854667,25.9764371 5.85869282,25.2703946 4.86332421,23.4040785 C4.5674974,22.8494032 4.41275563,22.2304361 4.41275563,21.6018042 L4.41275563,3.95453496 L4.41275563,3.95453496 Z" id="path-3"></path>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-5">
+            <stop stop-color="#FDB927" offset="0%"></stop>
+            <stop stop-color="#FFBF69" offset="100%"></stop>
+        </linearGradient>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-6">
+            <stop stop-color="#FFE593" offset="0%"></stop>
+            <stop stop-color="#FFEEB9" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="修改" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="评测" transform="translate(-219.000000, -63.000000)">
+            <g id="编组-10" transform="translate(211.000000, 63.000000)">
+                <g id="徽章" transform="translate(47.000000, 43.047686) rotate(-14.000000) translate(-47.000000, -43.047686) translate(16.000000, 6.411322)">
+                    <g id="矩形" transform="translate(4.131729, 41.943117)">
+                        <mask id="mask-2" fill="white">
+                            <use xlink:href="#path-1"></use>
+                        </mask>
+                        <use id="蒙版" fill="#FA753E" transform="translate(14.944957, 15.359913) rotate(22.000000) translate(-14.944957, -15.359913) " xlink:href="#path-1"></use>
+                        <polygon fill="#FFA673" mask="url(#mask-2)" transform="translate(15.929541, 12.922980) rotate(22.000000) translate(-15.929541, -12.922980) " points="12.1748032 1.28329221 19.6842795 1.28329221 19.6842795 24.5626686 12.1748032 24.5626686"></polygon>
+                    </g>
+                    <g id="矩形备份" transform="translate(29.308827, 41.333333)">
+                        <mask id="mask-4" fill="white">
+                            <use xlink:href="#path-3"></use>
+                        </mask>
+                        <use id="蒙版" fill="#FA753E" transform="translate(15.676970, 15.969697) rotate(-29.000000) translate(-15.676970, -15.969697) " xlink:href="#path-3"></use>
+                        <polygon id="矩形" fill="#FFA673" mask="url(#mask-4)" transform="translate(14.402737, 13.670919) rotate(-29.000000) translate(-14.402737, -13.670919) " points="10.6479987 2.03123121 18.1574749 2.03123121 18.1574749 25.3106076 10.6479987 25.3106076"></polygon>
+                    </g>
+                    <g id="编组-7" transform="translate(-0.000000, 0.000000)">
+                        <path d="M29.6849268,58.2640829 L24.274802,58.5609751 C20.088091,58.79073 16.0757964,56.8585107 13.6450543,53.4419584 L10.5040164,49.0270432 C9.9953911,48.3121402 9.44794612,47.6256659 8.86414698,46.970712 L5.25886961,42.9260154 C2.4688684,39.7959627 1.47791348,35.4543055 2.63353872,31.4236893 L4.12685332,26.2152724 C4.36866433,25.3718783 4.56404519,24.5158589 4.71211593,23.6510693 L5.62653338,18.3105229 C6.33416986,14.1776561 9.11076385,10.6959174 12.9825471,9.08637347 L17.9857178,7.006499 C18.7958765,6.6697069 19.5869574,6.28874241 20.3553978,5.86532128 L25.100935,3.2504654 C28.7733445,1.2269176 33.2266555,1.2269176 36.899065,3.2504654 L41.6446022,5.86532128 C42.4130426,6.28874241 43.2041235,6.6697069 44.0142822,7.006499 L49.0174529,9.08637347 C52.8892362,10.6959174 55.6658301,14.1776561 56.3734666,18.3105229 L57.2878841,23.6510693 C57.4359548,24.5158589 57.6313357,25.3718783 57.8731467,26.2152724 L59.3664613,31.4236893 C60.5220865,35.4543055 59.5311316,39.7959627 56.7411304,42.9260154 L53.135853,46.970712 C52.5520539,47.6256659 52.0046089,48.3121402 51.4959836,49.0270432 L48.3549457,53.4419584 C45.9242036,56.8585107 41.911909,58.79073 37.725198,58.5609751 L32.3150732,58.2640829 C31.4390168,58.2160074 30.5609832,58.2160074 29.6849268,58.2640829 Z" id="星形" fill="url(#linearGradient-5)"></path>
+                        <path d="M27.2931075,52.5100945 L25.5367564,52.796914 C22.2564324,53.3326045 18.991192,51.7601475 17.3647631,48.8614894 L16.4939406,47.3094898 C15.2767176,45.1401277 13.7156354,43.1825924 11.8715212,41.5131593 L10.5522098,40.3188178 C8.08814151,38.0881547 7.28169372,34.5548761 8.53389413,31.475999 L9.20434726,29.8275066 C10.1414968,27.5232682 10.6986406,25.0822617 10.8540696,22.5996007 L10.9652662,20.8234617 C11.1729474,17.5061799 13.4325639,14.6727104 16.6204611,13.7320717 L18.327325,13.2284349 C20.7131543,12.5244587 22.9689836,11.4381086 25.0069145,10.0117141 L26.4648858,8.99124657 C29.1879283,7.08532683 32.8120717,7.08532683 35.5351142,8.99124657 L36.9930855,10.0117141 C39.0310164,11.4381086 41.2868457,12.5244587 43.672675,13.2284349 L45.3795389,13.7320717 C48.5674361,14.6727104 50.8270526,17.5061799 51.0347338,20.8234617 L51.1459304,22.5996007 C51.3013594,25.0822617 51.8585032,27.5232682 52.7956527,29.8275066 L53.4661059,31.475999 C54.7183063,34.5548761 53.9118585,38.0881547 51.4477902,40.3188178 L50.1284788,41.5131593 C48.2843646,43.1825924 46.7232824,45.1401277 45.5060594,47.3094898 L44.6352369,48.8614894 C43.008808,51.7601475 39.7435676,53.3326045 36.4632436,52.796914 L34.7068925,52.5100945 C32.2518908,52.1091826 29.7481092,52.1091826 27.2931075,52.5100945 Z" id="星形" fill="url(#linearGradient-6)"></path>
+                        <path d="M30.1394164,18.3657398 C31.0076456,18.1454972 31.9598946,18.256473 32.7903706,18.7508702 C33.2910341,19.0489241 33.7093657,19.4672557 34.0074197,19.9679192 L34.0074197,19.9679192 L36.262776,23.7564102 L40.5627885,24.7306735 C41.5053953,24.944242 42.2721998,25.5196588 42.7499605,26.2773352 C43.2277212,27.0350116 43.4164382,27.9749476 43.2028697,28.9175544 C43.0741171,29.4858174 42.8055316,30.012946 42.4214761,30.4511256 L42.4214761,30.4511256 L39.5153505,33.7668051 L39.917548,38.1574239 C40.0057138,39.1198925 39.6954155,40.0269805 39.1224586,40.7154928 C38.5495017,41.4040052 37.7138862,41.8739418 36.7514176,41.9621076 C36.1711806,42.0152596 35.5868541,41.9227113 35.0514408,41.6928578 L35.0514408,41.6928578 L31,39.9535693 L26.9485592,41.6928578 C26.060442,42.0741276 25.1018625,42.059322 24.269995,41.7271696 C23.4381274,41.3950172 22.7329717,40.745518 22.3517019,39.8574007 C22.1218483,39.3219874 22.0293001,38.7376609 22.082452,38.1574239 L22.082452,38.1574239 L22.4846495,33.7668051 L19.5785239,30.4511256 C18.9414714,29.7242948 18.6593351,28.8080564 18.7181695,27.9142626 C18.777004,27.0204688 19.1768093,26.1491196 19.9036402,25.5120671 C20.3418199,25.1280115 20.8689485,24.8594261 21.4372115,24.7306735 L21.4372115,24.7306735 L25.737224,23.7564102 L27.9925803,19.9679192 C28.4869775,19.1374432 29.2711871,18.5859824 30.1394164,18.3657398 Z" id="星形" stroke="#FFDB86" stroke-width="3" fill="#FF9F21"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

File diff suppressed because it is too large
+ 8 - 0
src/page-orchestra/evaluat-model/evaluat-result/img/integrity.svg


File diff suppressed because it is too large
+ 8 - 0
src/page-orchestra/evaluat-model/evaluat-result/img/intonation.svg


File diff suppressed because it is too large
+ 1 - 0
src/page-orchestra/evaluat-model/evaluat-result/index.json


+ 226 - 0
src/page-orchestra/evaluat-model/evaluat-result/index.module.less

@@ -0,0 +1,226 @@
+.evaluatResult {
+    position: relative;
+    width: 100vw;
+    height: 100vh;
+    display: flex;
+    justify-content: center;
+    align-items: center;
+}
+
+.closeBtn {
+    position: absolute;
+    left: 30px;
+    top: 18px;
+    width: 40px;
+    height: 40px;
+    z-index: 1;
+
+    img {
+        width: 100%;
+        height: 100%;
+        display: block;
+    }
+
+    &:active {
+        opacity: .8;
+    }
+}
+
+.headerButton {
+    position: absolute;
+    right: 18px;
+    top: 18px;
+    display: flex;
+    justify-content: space-between;
+    align-items: center;
+    padding: 12px;
+    z-index: 1;
+
+    .headBtn {
+        background-color: #fff;
+        border-radius: 12px;
+        height: 26px;
+        line-height: 26px;
+        font-size: 13px;
+        color: var(--van-primary-color);
+        padding: 0 10px;
+        min-width: 61px;
+        text-align: center;
+
+        &+.headBtn {
+            margin-left: 8px;
+        }
+
+        &:active {
+            opacity: .8;
+        }
+    }
+}
+
+.fraction {
+    position: relative;
+    border-radius: 18px;
+    width: 361px;
+    height: 238px;
+    display: flex;
+    flex-direction: column;
+    justify-content: space-between;
+    max-height: 310px;
+
+    .bg {
+        position: absolute;
+        left: 0;
+        top: 0;
+        width: 100%;
+        height: 100%;
+        display: block;
+        z-index: -1;
+
+    }
+
+    .top {
+        position: relative;
+        display: flex;
+        align-items: center;
+        height: 50px;
+
+        .badge {
+            width: 72px;
+            transform: translateY(-7px);
+        }
+
+        .text {
+            position: relative;
+            display: flex;
+            font-size: 20px;
+            font-family: DIN-Bold, DIN;
+            font-weight: bold;
+            color: #2DC7AA;
+            line-height: 41px;
+            align-items: flex-end;
+            padding-left: 16px;
+            z-index: 1;
+            white-space: nowrap;
+            margin-left: auto;
+
+            &::before {
+                content: '';
+                position: absolute;
+                bottom: 8px;
+                left: 6px;
+                right: 0;
+                height: 8px;
+                background: #fcd660;
+                border-radius: 10px;
+                opacity: 0.59;
+                z-index: -1;
+            }
+        }
+
+        .num {
+            font-size: 30px;
+        }
+
+        .rightBadge {
+            position: relative;
+            top: -8px;
+            right: -8px;
+            margin-left: auto;
+            max-width: 146px;
+            max-height: 105px;
+            align-self: flex-end;
+            z-index: -3;
+        }
+    }
+
+}
+
+
+.tips {
+    padding: 0 20px;
+    font-size: 13px;
+    color: #808080;
+}
+
+.ctrls {
+    display: flex;
+    justify-content: space-evenly;
+    align-items: center;
+    margin: 0 20px 12px 20px;
+    padding-top: 12px;
+
+    .ctrlsBtn {
+        width: 94px;
+    }
+}
+
+.detail {
+    display: flex;
+    align-items: center;
+    margin: 0 16px;
+    padding: 0 12px;
+    background: #fff;
+    border-radius: 12px;
+    padding: 10px 0;
+}
+
+.progressitem {
+    flex: 1;
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+    text-align: center;
+    color: #1A1A1A;
+    font-weight: 500;
+    font-size: 14px;
+    
+    &>div {
+        padding-left: 24px;
+        background-repeat: no-repeat;
+        background-position: left center;
+        background-size: auto 100%;
+        margin-bottom: 4px;
+    }
+    .intonation{
+        background-image: url('./img/intonation.svg');
+    }
+    .cadence{
+        background-image: url('./img/cadence.svg'); 
+    }
+    .integrity{
+        background-image: url('./img/integrity.svg');
+    }
+    &:nth-child(2){
+        border-left: 1px solid #F2F2F2;
+        border-right: 1px solid #F2F2F2;
+    }
+    &>span {
+        font-size: 16px;
+        font-weight: 600;
+        color: #FF6729;
+    }
+
+}
+
+.percussion {
+    display: flex;
+    flex-direction: column;
+    justify-content: center;
+    align-items: center;
+
+    &>img {
+        height: 74px;
+        margin-bottom: 10px;
+    }
+
+    .scoreDes {
+        color: var(--van-primary-color);
+        font-size: 18px;
+
+        .scoreNum {
+            font-weight: bold;
+            font-size: 28px;
+        }
+    }
+}

+ 79 - 0
src/page-orchestra/evaluat-model/evaluat-result/index.tsx

@@ -0,0 +1,79 @@
+import { Popup } from "@varlet/ui";
+import { defineComponent, ref } from "vue";
+import styles from "./index.module.less";
+import state from "/src/state";
+import icon1 from "../icons/1.png";
+import { storeData } from "/src/store";
+import { Progress } from "vant";
+import { evaluatingData } from "/src/view/evaluating";
+import icons from "../icons/index.json";
+import imgs from "./index.json";
+import iconBadge from "./img/icon-badge.svg";
+
+export default defineComponent({
+	name: "evaluatResult",
+	emits: ["close"],
+	setup(props, { emit }) {
+		return () => (
+			<div class={styles.evaluatResult}>
+				<div class={styles.closeBtn} onClick={() => emit("close")}>
+					<img src={icons["arrow-left-background"]} />
+				</div>
+
+				<div class={styles.headerButton}>
+					<div class={styles.headBtn} onClick={() => emit("close", "update")}>
+						保存演奏
+					</div>
+					<div class={styles.headBtn} style={{ display: storeData.platformType === "STUDENT" ? "block" : "" }} onClick={() => emit("close", "share")}>
+						分享
+					</div>
+				</div>
+
+				<div class={styles.fraction}>
+					<img class={styles.bg} src={imgs.bg} />
+					<div class={styles.top}>
+						{evaluatingData.resultData.score > 79 && <img style={{}} class={styles.badge} src={iconBadge} />}
+						<div class={styles.text}>
+							<div>
+								<span class={styles.num}>{evaluatingData.resultData.score}</span>分
+							</div>
+							<div style={{marginLeft: '6px'}}>{evaluatingData.resultData.clxmome}</div>
+						</div>
+						<img class={styles.rightBadge} src={evaluatingData.resultData.clxImg} />
+					</div>
+					{state.isPercussion ? (
+						<div class={styles.percussion}>
+							<img class={styles.leftIcon} src={evaluatingData.resultData.img || icon1} />
+							<div class={styles.scoreDes}>
+								<span class={styles.scoreNum}>{evaluatingData.resultData.score}</span>分
+								<span style={{ marginLeft: "8px" }}>{evaluatingData.resultData.mome}</span>
+							</div>
+						</div>
+					) : (
+						<div class={styles.detail}>
+							<div class={styles.progressitem}>
+								<div class={styles.intonation}>音准</div>
+								<span>{evaluatingData.resultData.intonation}分</span>
+							</div>
+							<div class={styles.progressitem}>
+								<div class={styles.cadence}>节奏</div>
+								<span>{evaluatingData.resultData.cadence}分</span>
+							</div>
+							<div class={styles.progressitem}>
+								<div class={styles.integrity}>完成度</div>
+								<span>{evaluatingData.resultData.integrity}分</span>
+							</div>
+						</div>
+					)}
+
+					<div class={styles.tips}>{evaluatingData.resultData.clxtip}</div>
+					<div class={styles.ctrls}>
+						<img src={imgs.btn1} class={styles.ctrlsBtn} onClick={() => emit("close", "practise")} />
+						<img src={imgs.btn2} class={styles.ctrlsBtn} onClick={() => emit("close", "tryagain")} />
+						<img src={imgs.btn3} class={styles.ctrlsBtn} onClick={() => emit("close", "look")} />
+					</div>
+				</div>
+			</div>
+		);
+	},
+});

+ 30 - 0
src/page-orchestra/evaluat-model/evaluat-share/index.module.less

@@ -0,0 +1,30 @@
+.iframe {
+    border: none;
+    width: 500PX;
+    height: 80vh;
+}
+
+.btns {
+    display: flex;
+    font-size: 18PX;
+    align-items: center;
+    position: absolute;
+    right: 10PX;
+    top: 12PX;
+
+    >.sbtn {
+        background-color: rgba(0, 0, 0, .23);
+        width: 68PX;
+        height: 32PX;
+        border-radius: 19PX;
+        text-align: center;
+        line-height: 32PX;
+        color: #fff;
+        margin-left: 10PX;
+    }
+}
+
+.disabled {
+    opacity: .5;
+    pointer-events: none;
+}

+ 75 - 0
src/page-orchestra/evaluat-model/evaluat-share/index.tsx

@@ -0,0 +1,75 @@
+import { Snackbar } from "@varlet/ui";
+import { defineComponent, onMounted, ref } from "vue";
+import styles from "./index.module.less";
+import { api_shareAchievements } from "/src/helpers/communication";
+import state from "/src/state";
+import { storeData } from "/src/store";
+import { evaluatingData } from "/src/view/evaluating";
+import qs from 'query-string'
+
+export default defineComponent({
+	name: "evaluat-share",
+	emits: ["close"],
+	setup(props, { emit }) {
+		const src = ref("");
+		const shareLoadedPngData = ref("");
+		const shareDisabeled = ref(true);
+		const getShareUrl = () => {
+			const data: any = {
+				name: storeData.user?.username || "",
+				subjectName: (storeData.user?.subjectNames || "").split(",")[0] || "",
+				avatar: encodeURIComponent(storeData.user?.avatar || ""),
+				score: evaluatingData.resultData?.score || 0,
+				examSongName: state.examSongName || "",
+			};
+			if (!state.isPercussion) {
+				data.intonation = evaluatingData.resultData?.intonation;
+				data.cadence = evaluatingData.resultData?.cadence;
+				data.integrity = evaluatingData.resultData?.integrity;
+			}
+			// src.value = `${location.origin}/accompany/share-evaluating/index.html?${qs.stringify(data)}`;
+			src.value = `${location.origin}/share-colexiu-evaluating/index.html?${qs.stringify(data)}`;
+		};
+		const shareLoaded = (evt: Event) => {
+			const el = evt.target as HTMLIFrameElement;
+			if (el) {
+				// @ts-ignore
+				el.contentWindow.setPng = (data: string) => {
+					shareLoadedPngData.value = data;
+                    shareDisabeled.value = false
+				};
+			}
+		};
+		const shareNext = async () => {
+			const res = await api_shareAchievements({
+				title: "分享我的乐器练习进度,一起见证我的成长!",
+				desc: "晒一下我的评测分数,快来“小酷AI”上和我PK一下吧!",
+				image: shareLoadedPngData.value,
+				video: "",
+				type: "image",
+				button: ['copy'],
+            	url: getShareUrl(),
+			});
+			if (!res?.content?.status && res?.content?.message) {
+                Snackbar(res?.content?.message);
+			}
+            emit("close");
+		};
+		onMounted(() => {
+			getShareUrl();
+		});
+		return () => (
+			<div>
+				<div class={styles.btns}>
+					<div class={styles.sbtn} onClick={() => emit("close")}>
+						取消
+					</div>
+					<div class={[styles.sbtn, shareDisabeled.value && styles.disabled]} onClick={shareNext}>
+						继续
+					</div>
+				</div>
+				<iframe class={styles.iframe} src={src.value} onLoad={shareLoaded} />
+			</div>
+		);
+	},
+});

BIN
src/page-orchestra/evaluat-model/icons/1.png


BIN
src/page-orchestra/evaluat-model/icons/2.png


BIN
src/page-orchestra/evaluat-model/icons/3.png


BIN
src/page-orchestra/evaluat-model/icons/4.png


BIN
src/page-orchestra/evaluat-model/icons/5.png


+ 9 - 0
src/page-orchestra/evaluat-model/icons/arrow-left-background.svg

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="15px" height="24px" viewBox="0 0 15 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>形状</title>
+    <g id="确定版" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g transform="translate(-40.000000, -22.000000)" fill="#494949" fill-rule="nonzero" id="形状" stroke="#494949">
+            <path d="M42.2681508,32.7499394 C42.5890877,32.7499394 42.9114702,32.8699082 43.168798,33.0950183 L53.620931,42.6520856 C53.8607785,42.8704624 53.997204,43.1690827 53.9999596,43.4816468 C54.0026326,43.7942108 53.8714111,44.0948519 53.6353876,44.3168215 C53.138464,44.7783404 52.3366638,44.7837362 51.8326476,44.3289532 L41.379069,34.7718859 C41.1392215,34.5535091 41.002796,34.2548888 41.0000404,33.9423247 C40.9973673,33.6297606 41.1285889,33.3291196 41.3646123,33.1071499 C41.5948722,32.8710256 41.9246144,32.7409471 42.2667051,32.7512873 L42.2681508,32.7499394 Z M52.7106158,23 C53.0356188,23 53.3591643,23.117702 53.6185837,23.3424057 C53.8599334,23.5590403 53.9971822,23.8550613 53.9999596,24.1648752 C54.0026536,24.474689 53.8706502,24.7727125 53.6331578,24.9929083 L43.1980856,34.5695682 C42.6976948,35.027014 41.8904764,35.0329595 41.3821498,34.5829434 C41.1403528,34.3662582 41.0028184,34.0699512 41.0000404,33.7598084 C40.9973456,33.4496656 41.1296337,33.1513535 41.3675757,32.9311033 L51.8026479,23.3544434 C52.0474932,23.117702 52.3856129,23 52.7106158,23 Z"></path>
+        </g>
+    </g>
+</svg>

BIN
src/page-orchestra/evaluat-model/icons/bad.png


+ 15 - 0
src/page-orchestra/evaluat-model/icons/close.svg

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <!-- Generator: Sketch 62 (91390) - https://sketch.com -->
+    <title>编组</title>
+    <desc>Created with Sketch.</desc>
+    <g id="智能打分" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="81-100备份" transform="translate(-493.000000, -57.000000)" fill="#DBDBDB" fill-rule="nonzero">
+            <g id="弹窗" transform="translate(143.000000, 40.000000)">
+                <g id="编组" transform="translate(350.000000, 17.000000)">
+                    <path d="M1.05548433,1.07092551 L0.973890205,1.16134969 C0.666012474,1.54828454 0.694001358,2.11481906 1.05785686,2.46909941 L6.537,7.949 L1.05548433,13.4315873 C0.672191496,13.8148801 0.672191496,14.4441272 1.05548433,14.8274201 L1.08636669,14.8583024 L1.17896103,14.9399506 C1.56501142,15.2393273 2.12839072,15.2121112 2.48219949,14.8583024 L7.964,9.376 L13.4470285,14.8583024 C13.8303213,15.2415953 14.4595684,15.2415953 14.8428613,14.8583024 L14.8737436,14.8274201 L14.9553918,14.7348257 C15.2547684,14.3487753 15.2275524,13.785396 14.8737436,13.4315873 L9.391,7.949 L14.8737436,2.46675831 C15.2570364,2.08346548 15.2570364,1.45421835 14.8737436,1.07092551 L14.8428613,1.04004316 L14.7502669,0.958394979 C14.3642165,0.659018325 13.8008372,0.686234384 13.4470285,1.04004316 L7.964,6.53 L2.48231995,1.0401637 C2.09890665,0.65675032 1.46965952,0.65675032 1.08636669,1.04004316 L1.05548433,1.07092551 Z" id="路径"></path>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 12 - 0
src/page-orchestra/evaluat-model/icons/close2.svg

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g transform="translate(-493.000000, -57.000000)" fill="#01C1B5" fill-rule="nonzero">
+            <g transform="translate(143.000000, 40.000000)">
+                <g transform="translate(350.000000, 17.000000)">
+                    <path d="M1.05548433,1.07092551 L0.973890205,1.16134969 C0.666012474,1.54828454 0.694001358,2.11481906 1.05785686,2.46909941 L6.537,7.949 L1.05548433,13.4315873 C0.672191496,13.8148801 0.672191496,14.4441272 1.05548433,14.8274201 L1.08636669,14.8583024 L1.17896103,14.9399506 C1.56501142,15.2393273 2.12839072,15.2121112 2.48219949,14.8583024 L7.964,9.376 L13.4470285,14.8583024 C13.8303213,15.2415953 14.4595684,15.2415953 14.8428613,14.8583024 L14.8737436,14.8274201 L14.9553918,14.7348257 C15.2547684,14.3487753 15.2275524,13.785396 14.8737436,13.4315873 L9.391,7.949 L14.8737436,2.46675831 C15.2570364,2.08346548 15.2570364,1.45421835 14.8737436,1.07092551 L14.8428613,1.04004316 L14.7502669,0.958394979 C14.3642165,0.659018325 13.8008372,0.686234384 13.4470285,1.04004316 L7.964,6.53 L2.48231995,1.0401637 C2.09890665,0.65675032 1.46965952,0.65675032 1.08636669,1.04004316 L1.05548433,1.07092551 Z" id="路径"></path>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
src/page-orchestra/evaluat-model/icons/erji.png


File diff suppressed because it is too large
+ 1 - 0
src/page-orchestra/evaluat-model/icons/evaluating.json


BIN
src/page-orchestra/evaluat-model/icons/good.png


BIN
src/page-orchestra/evaluat-model/icons/great.png


File diff suppressed because it is too large
+ 2 - 0
src/page-orchestra/evaluat-model/icons/index.json


BIN
src/page-orchestra/evaluat-model/icons/left-bg.png


BIN
src/page-orchestra/evaluat-model/icons/perfect.png


BIN
src/page-orchestra/evaluat-model/icons/student.png


+ 9 - 0
src/page-orchestra/evaluat-model/icons/task-bg.svg

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="208px" height="70px" viewBox="0 0 208 70" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>矩形</title>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="曲谱评测" transform="translate(-582.000000, -215.000000)" fill="#FFE1B8" stroke="#FFFFFF" stroke-width="2">
+            <path d="M591,216.506546 L781,216.506546 C785.418278,216.506546 789,220.088268 789,224.506546 L789,278.353946 C789,281.11537 786.761424,283.353946 784,283.353946 C783.212178,283.353946 782.435504,283.167782 781.733289,282.810629 L768.300488,275.978581 L768.300488,275.978581 L591,275.978581 C586.581722,275.978581 583,272.396859 583,267.978581 L583,224.506546 C583,220.088268 586.581722,216.506546 591,216.506546 Z" id="矩形"></path>
+        </g>
+    </g>
+</svg>

BIN
src/page-orchestra/evaluat-model/icons/title.png


+ 96 - 0
src/page-orchestra/evaluat-model/index.module.less

@@ -0,0 +1,96 @@
+:global {
+    .var-popup .var-popup--center {
+        overflow: initial;
+    }
+}
+
+.startBtn {
+    position: fixed;
+    left: 50%;
+    top: 50%;
+    margin-left: -70px;
+    margin-top: -70px;
+    width: 140px;
+    height: 140px;
+    z-index: 11;
+    & > img {
+      display: block;
+      width: 100%;
+      height: 100%;
+    }
+  }
+  .endBtn{
+    position: fixed;
+    left: 50%;
+    top: 16px;
+    width: 120px;
+    height: 40px;
+    margin-left: -70px;
+    z-index: 11;
+    & > img {
+      display: block;
+      width: 100%;
+      height: 100%;
+    }
+  }
+
+.dialogueBox {
+    position: fixed;
+    bottom: -1px;
+    right: 0;
+    z-index: 9;
+    display: flex;
+    flex-direction: column;
+    align-items: flex-end;
+
+    .dialogue {
+        position: relative;
+        right: 21px;
+        top: 15px;
+        width: 190px;
+        height: 50px;
+
+        .dialoguebg {
+            position: absolute;
+            left: 0;
+            top: 0;
+            width: 100%;
+        }
+
+        &>div {
+            position: relative;
+            z-index: 1;
+            padding: 10px;
+            font-size: 11px;
+            font-weight: 400;
+            color: #6F4900;
+            line-height: 18px;
+        }
+    }
+
+    .dialogueing {
+        position: absolute;
+        bottom: 10px;
+        right: 70%;
+        width: 54px;
+        line-height: 23px;
+        background: #FFE1B8;
+        border-radius: 12px;
+        border: 1px solid #FFFFFF;
+        font-size: 11px;
+        color: #6F4900;
+        text-align: center;
+        z-index: 1;
+    }
+
+    .dialogueIcon {
+        width: 100px;
+        height: 100px;
+    }
+
+    .inRadioIcon {
+        width: 66px;
+        height: 72px;
+        margin-right: 6px;
+    }
+}

+ 272 - 0
src/page-orchestra/evaluat-model/index.tsx

@@ -0,0 +1,272 @@
+import { Popup, Snackbar } from "@varlet/ui";
+import { Transition, defineComponent, onMounted, reactive, watch } from "vue";
+import {
+	connectWebsocket,
+	evaluatingData,
+	handleEndBegin,
+	handleEndSoundCheck,
+	handlePerformDetection,
+	handleStartBegin,
+	handleStartEvaluat,
+	handleViewReport,
+} from "/src/view/evaluating";
+import Earphone from "./earphone";
+import styles from "./index.module.less";
+import SoundEffect from "./sound-effect";
+import state from "/src/state";
+import { storeData } from "/src/store";
+import { browser } from "/src/utils";
+import { getNoteByMeasuresSlursStart } from "/src/helpers/formateMusic";
+import { Icon } from "vant";
+import EvaluatResult from "./evaluat-result";
+import EvaluatAudio from "./evaluat-audio";
+import { api_openWebView, api_proxyServiceMessage, api_videoUpdate } from "/src/helpers/communication";
+import EvaluatShare from "./evaluat-share";
+import { Vue3Lottie } from "vue3-lottie";
+import startData from "./data/start.json";
+import startingData from "./data/starting.json";
+import iconTastBg from "./icons/task-bg.svg";
+import iconEvaluat from "./icons/evaluating.json";
+
+// frequency 频率, amplitude 振幅, decibels 分贝
+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,
+		});
+		/**
+		 * 木管(长笛 萨克斯 单簧管)乐器一级的2、3、6测评要放原音音频
+		 * 铜管乐器一级的1a,1b,5,6测评要放原音音频
+		 */
+		const getMusicMode = () => {
+			return "music";
+		};
+		const browserInfo = browser();
+		/** 是否是节奏练习 */
+		const isRhythmicExercises = () => {
+			const examSongName = state.examSongName || "";
+			return examSongName.indexOf("节奏练习") > -1;
+		};
+
+		/** 获取评测标准 */
+		const getEvaluationCriteria = () => {
+			let criteria: TCriteria = "frequency";
+			// 声部打击乐
+			if ([23, 113, 121].includes(state.subjectId)) {
+				criteria = "amplitude";
+			} else if (isRhythmicExercises()) {
+				// 分类为节奏练习
+				criteria = "decibels";
+			}
+			return criteria;
+		};
+
+		/** 生成评测曲谱数据 */
+		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";
+		};
+
+		/** 评测结果按钮处理 */
+		const handleEvaluatResult = (type: "practise" | "tryagain" | "look" | "share" | "update") => {
+			if (type === "update") {
+				// 上传云端
+				evaluatModel.evaluatUpdateAudio = true;
+				return;
+			} else if (type === "share") {
+				// 分享
+				evaluatModel.shareMode = true;
+				return;
+			} else if (type === "look") {
+				// 跳转
+				handleViewReport();
+				return;
+			} else if (type === "practise") {
+				// 去练习
+				handleStartEvaluat();
+			} else if (type === "tryagain") {
+				// 再来一次
+				handleStartBegin();
+			}
+			evaluatingData.resulstMode = false;
+		};
+		/** 上传音视频 */
+		const hanldeUpdateVideoAndAudio = async (update = false) => {
+			if (!update) {
+				evaluatModel.evaluatUpdateAudio = false;
+				return;
+			}
+			let res = null;
+			if (evaluatModel.isSaveVideo) {
+				res = await api_videoUpdate();
+			}
+			api_proxyServiceMessage({
+				header: {
+					commond: "videoUpload",
+					status: 200,
+					type: "SOUND_COMPARE",
+				},
+				body: {
+					filePath: res?.content?.filePath,
+					recordId: res?.recordId,
+				},
+			});
+			Snackbar.success("上传成功");
+			evaluatModel.evaluatUpdateAudio = false;
+		};
+
+		onMounted(() => {
+			handlePerformDetection();
+		});
+		watch(
+			() => evaluatingData.checkEnd,
+			() => {
+				if (evaluatingData.checkEnd) {
+					console.log("检测结束,连接websocket");
+					handleConnect();
+				}
+			}
+		);
+		return () => (
+			<div>
+				<Transition name="pop-center">
+					{evaluatingData.websocketState && !evaluatingData.startBegin && (
+						<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(false)}>
+							<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>
+
+				<Popup teleport="body" closeOnClickOverlay={false} defaultStyle={false} v-model:show={evaluatingData.earphoneMode}>
+					<Earphone
+						onClose={() => {
+							evaluatingData.earphoneMode = false;
+							handlePerformDetection();
+						}}
+					/>
+				</Popup>
+				<Popup teleport="body" closeOnClickOverlay={false} defaultStyle={false} v-model:show={evaluatingData.soundEffectMode}>
+					<SoundEffect
+						onClose={(value: any) => {
+							evaluatingData.soundEffectMode = false;
+							if (value) {
+								state.setting.soundEffect = false;
+							}
+							handleEndSoundCheck();
+							handlePerformDetection();
+						}}
+					/>
+				</Popup>
+
+				<Popup teleport="body" closeOnClickOverlay={false} defaultStyle={false} v-model:show={evaluatingData.resulstMode}>
+					<EvaluatResult onClose={handleEvaluatResult} />
+				</Popup>
+				<Popup teleport="body" closeOnClickOverlay={false} defaultStyle={false} v-model:show={evaluatModel.evaluatUpdateAudio}>
+					<EvaluatAudio onClose={hanldeUpdateVideoAndAudio} />
+				</Popup>
+				<Popup teleport="body" defaultStyle={false} v-model:show={evaluatModel.shareMode}>
+					<EvaluatShare onClose={() => (evaluatModel.shareMode = false)} />
+				</Popup>
+			</div>
+		);
+	},
+});

+ 54 - 0
src/page-orchestra/evaluat-model/sound-effect/data.ts

@@ -0,0 +1,54 @@
+import iconSound_12_4 from "./icons/icon-sound_12_4.svg";
+import iconsound_5_6 from "./icons/icon-sound_5_6.svg";
+import iconsound_13 from "./icons/icon-sound_13.svg";
+import iconsound_14_15 from "./icons/icon-sound_14_15.svg";
+import iconsound_120 from "./icons/icon-sound_120.svg";
+import iconsound_default from "./icons/icon-sound_default.svg";
+export const getScoreData = (subjectId: number) => {
+	// 小号、单簧管
+	if (subjectId == 12 || subjectId == 4) {
+		return {
+			src: iconSound_12_4,
+			text: "",
+			frequency: 525.6295448312027,
+		};
+	}
+	// 萨克斯
+	if (subjectId == 5 || subjectId == 6) {
+		return {
+			src: iconsound_5_6,
+			text: "C",
+			frequency: 525.6295448312027,
+		};
+	}
+	// 圆号
+	if (subjectId == 13) {
+		return {
+			src: iconsound_13,
+			text: "F",
+			frequency: 350.8156324849721,
+		};
+	}
+	// 长号 上低音号
+	if (subjectId == 14 || subjectId == 15) {
+		return {
+			src: iconsound_14_15,
+			text: "S",
+			frequency: 117.07067192670213,
+		};
+	}
+	// 长号 上低音号
+	if (subjectId == 120) {
+		return {
+			src: iconsound_120,
+			text: "A",
+			frequency: 884,
+		};
+	}
+	// 剩余声部
+	return {
+		src: iconsound_default,
+		text: "Bb",
+		frequency: 468.28268770680853,
+	};
+};

BIN
src/page-orchestra/evaluat-model/sound-effect/icons/bg-note.png


BIN
src/page-orchestra/evaluat-model/sound-effect/icons/bg.png


BIN
src/page-orchestra/evaluat-model/sound-effect/icons/child.png


BIN
src/page-orchestra/evaluat-model/sound-effect/icons/content-bg.png


BIN
src/page-orchestra/evaluat-model/sound-effect/icons/dot-active.png


BIN
src/page-orchestra/evaluat-model/sound-effect/icons/dot-error.png


BIN
src/page-orchestra/evaluat-model/sound-effect/icons/dot.png


File diff suppressed because it is too large
+ 11 - 0
src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_120.svg


File diff suppressed because it is too large
+ 11 - 0
src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_12_4.svg


File diff suppressed because it is too large
+ 10 - 0
src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_13.svg


File diff suppressed because it is too large
+ 11 - 0
src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_14_15.svg


File diff suppressed because it is too large
+ 11 - 0
src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_5_6.svg


File diff suppressed because it is too large
+ 11 - 0
src/page-orchestra/evaluat-model/sound-effect/icons/icon-sound_default.svg


BIN
src/page-orchestra/evaluat-model/sound-effect/icons/notes.png


+ 104 - 0
src/page-orchestra/evaluat-model/sound-effect/index.module.less

@@ -0,0 +1,104 @@
+.sound-effect {
+  position: relative;
+  width: 100vw;
+  height: 100vh;
+  display: flex;
+  flex-direction: column;
+  background-image: url('./icons/bg.png');
+  background-size: 100% 100%;
+  background-repeat: no-repeat;
+  background-position: center;
+
+}
+
+.top {
+  display: flex;
+  justify-content: space-between;
+  padding: 18px 34px 10px 30px;
+  flex-shrink: 0;
+}
+
+.back {
+  width: 40px;
+  height: 40px;
+
+  img {
+    width: 100%;
+    height: 100%;
+    display: block;
+  }
+}
+
+.skibtns {
+  z-index: 9999 !important;
+  :global {
+    --van-popover-action-width: 100px;
+    --van-popover-action-font-size: 14px;
+    --van-popover-light-text-color: #999999;
+  }
+}
+
+.rightSkipBtn {
+  font-size: 15px;
+  padding: 6px 16px;
+  background-color: #fff;
+  border-radius: 20px;
+  &:active{
+    opacity: .8;
+  }
+  .tran {
+    margin-left: 2px;
+    transform: rotate(90deg);
+  }
+}
+
+.content {
+  flex: 1;
+  display: flex;
+  justify-content: center;
+  background-image: url('./icons/bg-note.png');
+  background-repeat: no-repeat;
+  background-size: 76%;
+  background-position: center 30%;
+}
+
+.heiban {
+  position: relative;
+  width: 60%;
+  height: 61vh;
+  background-image: url('./icons/content-bg.png');
+  background-repeat: no-repeat;
+  background-size: 100% 100%;
+  background-position: center;
+  max-height: 370PX;
+  display: flex;
+  flex-direction: column;
+  justify-content: center;
+}
+
+.iconChild {
+  position: absolute;
+  bottom: -30%;
+  left: -6%;
+  width: 26vw;
+}
+.scoreContent{
+  text-align: center;
+}
+.tips{
+  text-align: center;
+  color: #fff;
+  font-size: 13px;
+  padding: 4px 0;
+}
+.steps{
+  margin: 0 auto;
+  padding: 10px 0;
+  width: 40%;
+  display: flex;
+  justify-content: space-evenly;
+  & > img {
+    width: 20px;
+    height: 20px;
+  }
+}

+ 84 - 0
src/page-orchestra/evaluat-model/sound-effect/index.tsx

@@ -0,0 +1,84 @@
+import { defineComponent, reactive, ref, watch } from "vue";
+import { Popover, Icon } from "vant";
+import icons from "../icons/index.json";
+import iconChild from "./icons/child.png";
+import DotIcon from "./icons/dot.png";
+import DotActiveIcon from "./icons/dot-active.png";
+import DotErrorIcon from "./icons/dot-error.png";
+
+import styles from "./index.module.less";
+import state from "/src/state";
+import { evaluatingData } from "/src/view/evaluating";
+import { getScoreData } from "./data";
+
+export default defineComponent({
+	name: "sound-effect",
+	emits: ["close"],
+	setup(props, { emit }) {
+		const scoreData = getScoreData(state.subjectId);
+		const soundEffectData = reactive({
+			step: 0,
+			tips: ["左边红灯表示吹奏的音过低", "吹奏时请保持中间绿灯亮起", "右边红灯表示吹奏的音过高"],
+			time: 1,
+		});
+		watch(
+			() => evaluatingData.soundEffectFrequency,
+			() => {
+        // console.log('吹奏',evaluatingData.soundEffectFrequency , scoreData.frequency)
+				const trend =
+					Math.abs(evaluatingData.soundEffectFrequency - scoreData.frequency) <= 10 ? 1 : evaluatingData.soundEffectFrequency > scoreData.frequency ? 2 : 0;
+				soundEffectData.step = trend;
+				if (trend !== 1) {
+					soundEffectData.time = Date.now();
+				}
+        // 持续时间达到3秒钟,效音成功
+				if (Date.now() - soundEffectData.time > 3000) {
+					// console.log("效音完成");
+          emit('close')
+				}
+			}
+		);
+
+		/** 跳过本次 */
+		const handleSelect = (e: {text: string}) => {
+      if (e.text === '关闭校音'){
+        emit('close', true)
+        return
+      } 
+      emit('close')
+		};
+		return () => (
+			<div class={styles["sound-effect"]}>
+				<div class={styles.top}>
+					<div class={styles.back} onClick={() => emit('close')}>
+						<img src={icons["arrow-left-background"]} />
+					</div>
+					<Popover trigger="click" class={styles.skibtns} actions={[{ text: "跳过本次" }, { text: "关闭校音" }]} onSelect={handleSelect}>
+						{{
+							reference: () => (
+								<div class={styles.rightSkipBtn}>
+									<span>跳过本次</span>
+									<Icon name="play" color="var(--van-primary-color)" class={styles.tran}/>
+								</div>
+							),
+						}}
+					</Popover>
+				</div>
+				<div class={styles.content}>
+					<div class={styles.heiban}>
+						<img class={styles.iconChild} src={iconChild} />
+						<div class={styles.scoreContent}>
+							<img src={scoreData.src} />
+						</div>
+						<div class={styles.tips}>{soundEffectData.tips[soundEffectData.step]}</div>
+						<div class={styles.steps}>
+							<img src={soundEffectData.step === 0 ? DotErrorIcon : DotIcon} />
+							<img src={soundEffectData.step === 1 ? DotActiveIcon : DotIcon} />
+							<img src={soundEffectData.step === 2 ? DotErrorIcon : DotIcon} />
+						</div>
+					</div>
+				</div>
+			</div>
+		);
+	},
+});

File diff suppressed because it is too large
+ 1 - 0
src/page-orchestra/follow-model/icons.json


+ 36 - 0
src/page-orchestra/follow-model/index.module.less

@@ -0,0 +1,36 @@
+:global{
+    .green{
+        .vf-notehead > path {
+            fill: green;
+        }
+    }
+}
+.startBtn {
+  position: fixed;
+  left: 50%;
+  top: 50%;
+  margin-left: -70px;
+  margin-top: -70px;
+  width: 140px;
+  height: 140px;
+  z-index: 11;
+  & > img {
+    display: block;
+    width: 100%;
+    height: 100%;
+  }
+}
+.endBtn{
+  position: fixed;
+  left: 50%;
+  top: 16px;
+  width: 120px;
+  height: 40px;
+  margin-left: -70px;
+  z-index: 11;
+  & > img {
+    display: block;
+    width: 100%;
+    height: 100%;
+  }
+}

+ 50 - 0
src/page-orchestra/follow-model/index.tsx

@@ -0,0 +1,50 @@
+import { Transition, defineComponent, onBeforeUnmount, onMounted, ref } from "vue";
+import styles from "./index.module.less";
+import icons from "./icons.json";
+import { handleFollowEnd, handleFollowStart } from "/src/view/follow-practice";
+
+export default defineComponent({
+	name: "follow-model",
+	setup() {
+		const startBtn = ref(false);
+		const endBtn = ref(false);
+		onMounted(() => {
+			startBtn.value = true;
+		});
+		onBeforeUnmount(() => {
+			startBtn.value = false;
+		});
+		return () => (
+			<>
+				<Transition name="pop-center">
+					{startBtn.value && (
+						<div class={styles.startBtn} key="start">
+							<img
+								src={icons.start}
+								onClick={() => {
+									startBtn.value = false;
+									endBtn.value = true;
+									handleFollowStart();
+								}}
+							/>
+						</div>
+					)}
+				</Transition>
+				<Transition name="pop-center">
+					{endBtn.value && (
+						<div class={styles.endBtn} key="end">
+							<img
+								src={icons.end}
+								onClick={() => {
+									startBtn.value = true;
+                                    endBtn.value = false;
+									handleFollowEnd();
+								}}
+							/>
+						</div>
+					)}
+				</Transition>
+			</>
+		);
+	},
+});

File diff suppressed because it is too large
+ 9 - 0
src/page-orchestra/header-top/image/arrow.svg


+ 12 - 0
src/page-orchestra/header-top/image/close2.svg

@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g transform="translate(-493.000000, -57.000000)" fill="#01C1B5" fill-rule="nonzero">
+            <g transform="translate(143.000000, 40.000000)">
+                <g transform="translate(350.000000, 17.000000)">
+                    <path d="M1.05548433,1.07092551 L0.973890205,1.16134969 C0.666012474,1.54828454 0.694001358,2.11481906 1.05785686,2.46909941 L6.537,7.949 L1.05548433,13.4315873 C0.672191496,13.8148801 0.672191496,14.4441272 1.05548433,14.8274201 L1.08636669,14.8583024 L1.17896103,14.9399506 C1.56501142,15.2393273 2.12839072,15.2121112 2.48219949,14.8583024 L7.964,9.376 L13.4470285,14.8583024 C13.8303213,15.2415953 14.4595684,15.2415953 14.8428613,14.8583024 L14.8737436,14.8274201 L14.9553918,14.7348257 C15.2547684,14.3487753 15.2275524,13.785396 14.8737436,13.4315873 L9.391,7.949 L14.8737436,2.46675831 C15.2570364,2.08346548 15.2570364,1.45421835 14.8737436,1.07092551 L14.8428613,1.04004316 L14.7502669,0.958394979 C14.3642165,0.659018325 13.8008372,0.686234384 13.4470285,1.04004316 L7.964,6.53 L2.48231995,1.0401637 C2.09890665,0.65675032 1.46965952,0.65675032 1.08636669,1.04004316 L1.05548433,1.07092551 Z" id="路径"></path>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 16 - 0
src/page-orchestra/header-top/image/down.svg

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="22px" height="23px" viewBox="0 0 22 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组</title>
+    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="全局设置" transform="translate(-269.000000, -299.000000)" fill-rule="nonzero">
+            <g id="编组-22" transform="translate(246.000000, 23.000000)">
+                <g id="编组-16" transform="translate(16.000000, 272.000000)">
+                    <g id="编组" transform="translate(7.000000, 4.500000)">
+                        <path d="M15.5714286,14.2142857 L15.5714286,15.0714286 C15.5714286,15.1472047 15.5413266,15.2198773 15.4877448,15.2734591 C15.434163,15.3270409 15.3614904,15.3571429 15.2857143,15.3571429 L6.71428572,15.3571429 C6.63850958,15.3571429 6.56583703,15.3270409 6.5122552,15.2734591 C6.45867338,15.2198773 6.42857142,15.1472047 6.42857142,15.0714286 L6.42857142,14.2142857 C6.42857142,13.5831031 5.91689685,13.0714286 5.28571428,13.0714286 L4.14285714,13.0714286 C3.51167457,13.0714286 3,13.5831031 3,14.2142857 L3,16.7857143 C3,17.7324881 3.76751186,18.5 4.71428572,18.5 L17.2857143,18.5 C18.2324881,18.5 19,17.7324881 19,16.7857143 L19,14.2142857 C19,13.5831031 18.4883254,13.0714286 17.8571429,13.0714286 L16.7142857,13.0714286 C16.0831031,13.0714286 15.5714286,13.5831031 15.5714286,14.2142857 Z" id="路径" fill="#07D085"></path>
+                        <path d="M13,4.64285714 C13,4.01167457 12.4883254,3.5 11.8571429,3.5 L10.1428571,3.5 C9.51167457,3.5 9,4.01167457 9,4.64285714 L9,8.02285714 C9,8.18065278 8.87208136,8.30857142 8.71428572,8.30857142 L7.37714286,8.30857142 C7.15520126,8.30949809 6.95387202,8.43885339 6.8607871,8.64033324 C6.76770218,8.84181309 6.79970163,9.07896767 6.94285714,9.24857142 L10.5657143,13.5114286 C10.6741903,13.6344288 10.8302854,13.7048927 10.9942857,13.7048927 C11.158286,13.7048927 11.3143811,13.6344288 11.4228571,13.5114286 L15.0571429,9.24857142 C15.2002984,9.07896767 15.2322978,8.84181309 15.1392129,8.64033324 C15.046128,8.43885339 14.8447987,8.30949809 14.6228571,8.30857142 L13.2857143,8.30857142 C13.1279186,8.30857142 13,8.18065278 13,8.02285714 L13,4.64285714 Z" id="路径" fill="#F9BA48"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

File diff suppressed because it is too large
+ 12 - 0
src/page-orchestra/header-top/image/guding-active.svg


File diff suppressed because it is too large
+ 12 - 0
src/page-orchestra/header-top/image/guding.svg


File diff suppressed because it is too large
+ 1 - 0
src/page-orchestra/header-top/image/headerTop.json


+ 8 - 0
src/page-orchestra/header-top/image/icon-back.svg

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="15px" height="24px" viewBox="0 0 15 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <g stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g transform="translate(-40.000000, -22.000000)" fill="#494949" fill-rule="nonzero" id="形状" stroke="#494949">
+            <path d="M42.2681508,32.7499394 C42.5890877,32.7499394 42.9114702,32.8699082 43.168798,33.0950183 L53.620931,42.6520856 C53.8607785,42.8704624 53.997204,43.1690827 53.9999596,43.4816468 C54.0026326,43.7942108 53.8714111,44.0948519 53.6353876,44.3168215 C53.138464,44.7783404 52.3366638,44.7837362 51.8326476,44.3289532 L41.379069,34.7718859 C41.1392215,34.5535091 41.002796,34.2548888 41.0000404,33.9423247 C40.9973673,33.6297606 41.1285889,33.3291196 41.3646123,33.1071499 C41.5948722,32.8710256 41.9246144,32.7409471 42.2667051,32.7512873 L42.2681508,32.7499394 Z M52.7106158,23 C53.0356188,23 53.3591643,23.117702 53.6185837,23.3424057 C53.8599334,23.5590403 53.9971822,23.8550613 53.9999596,24.1648752 C54.0026536,24.474689 53.8706502,24.7727125 53.6331578,24.9929083 L43.1980856,34.5695682 C42.6976948,35.027014 41.8904764,35.0329595 41.3821498,34.5829434 C41.1403528,34.3662582 41.0028184,34.0699512 41.0000404,33.7598084 C40.9973456,33.4496656 41.1296337,33.1513535 41.3675757,32.9311033 L51.8026479,23.3544434 C52.0474932,23.117702 52.3856129,23 52.7106158,23 Z"></path>
+        </g>
+    </g>
+</svg>

File diff suppressed because it is too large
+ 13 - 0
src/page-orchestra/header-top/image/icon-staff-active.svg


File diff suppressed because it is too large
+ 13 - 0
src/page-orchestra/header-top/image/icon-staff.svg


File diff suppressed because it is too large
+ 9 - 0
src/page-orchestra/header-top/image/icon-zhuanpu.svg


BIN
src/page-orchestra/header-top/image/iconStep.png


+ 5 - 0
src/page-orchestra/header-top/image/index.ts

@@ -0,0 +1,5 @@
+const icons = import.meta.glob("./*", { import: "default", eager: true });
+export const headImg = (name: string) => {
+    const src = icons[`./${name}`] as unknown as string || ''
+	return src;
+};

+ 19 - 0
src/page-orchestra/header-top/image/info.svg

@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="16px" height="16px" viewBox="0 0 16 16" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组</title>
+    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="全局设置" transform="translate(-274.000000, -87.000000)" fill-rule="nonzero">
+            <g id="编组-22" transform="translate(246.000000, 23.000000)">
+                <g id="编组-3" transform="translate(15.000000, 54.000000)">
+                    <g id="编组" transform="translate(13.000000, 10.000000)">
+                        <path d="M8.00000178,0 C3.59200139,0 1.77986584e-06,3.59199961 1.77986584e-06,8 C1.77986584e-06,12.4079986 3.59200137,16 8.00000178,16 C12.4080004,16 16.0000018,12.4079986 16.0000018,8 C16.0000018,3.59199959 12.4080004,0 8.00000178,0 Z" id="路径" fill="#FEAC13"></path>
+                        <path d="M13.6672003,2.36159974 C14.6589912,3.35644003 15.3716365,4.59467148 15.7336,5.95199933 L5.95200111,15.7335982 C4.59467326,15.3716347 3.35644181,14.6589894 2.36160152,13.6671985 L7.44960095,8.57919905 C7.59360093,8.71599904 7.78800091,8.79999903 8.00000089,8.79999903 C8.44000085,8.79999903 8.80000081,8.43999907 8.80000081,7.99999911 L8.80000081,7.22879919 L13.6672003,2.36159974 Z M8.00000089,10.3999988 C7.56000093,10.3999988 7.20000097,10.7599988 7.20000097,11.1999988 C7.20000097,11.6399987 7.56000093,11.9999987 8.00000089,11.9999987 C8.44000085,11.9999987 8.80000081,11.6399987 8.80000081,11.1999988 C8.80000081,10.7599988 8.44000085,10.3999988 8.00000089,10.3999988 L8.00000089,10.3999988 Z" id="形状" fill="#FFB936"></path>
+                        <path d="M10.0936007,0.278399969 C11.4466535,0.647925598 12.6789481,1.36628136 13.6672003,2.36159974 L8.80000081,7.22879919 L8.80000081,4.79999946 C8.80000081,4.39199951 8.48960084,4.05199955 8.09280087,4.00559955 L8.00000089,3.99999956 C7.56000093,3.99999956 7.20000097,4.35999952 7.20000097,4.79999946 L7.20000097,7.99999911 C7.20000097,8.22719908 7.29600096,8.43359906 7.44960095,8.57919905 L2.36160152,13.6671985 C1.36628314,12.6789463 0.647927378,11.4466517 0.278401749,10.0935989 L10.0936007,0.278399969 Z" id="路径" fill="#FFC964"></path>
+                        <path d="M8,0 C8.7240008,0 9.42560073,0.0967999954 10.0936007,0.278399969 L0.278401749,10.0935989 C0.0931508027,9.4111699 -0.000470761078,8.70712498 0,8 C0,3.59199961 3.59200139,0 8,0 Z" id="路径" fill="#FFD78C"></path>
+                        <path d="M8.16000087,10.7199987 C8.68800081,10.7199987 9.12000076,11.1519987 9.12000076,11.6799986 C9.12000076,12.2079986 8.68800081,12.6399985 8.16000087,12.6399985 C7.63200092,12.6399985 7.20000097,12.2079986 7.20000097,11.6799986 C7.20000097,11.1519987 7.63200092,10.7199987 8.16000087,10.7199987 Z M8.16000087,3.03999967 C8.68800081,3.03999967 9.12000076,3.47199962 9.12000076,3.99999954 L9.12000076,7.83999909 C9.12000076,8.36799903 8.68800081,8.79999898 8.16000087,8.79999898 C7.63200092,8.79999898 7.20000097,8.36799903 7.20000097,7.83999909 L7.20000097,3.99999954 C7.20000097,3.4719996 7.63200092,3.03999967 8.16000087,3.03999967 Z" id="形状结合" fill="#FFFFFF"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

File diff suppressed because it is too large
+ 8 - 0
src/page-orchestra/header-top/image/menu.svg


BIN
src/page-orchestra/header-top/image/minus.png


+ 15 - 0
src/page-orchestra/header-top/image/modeType.svg

@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="29px" height="29px" viewBox="0 0 29 29" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>切片</title>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="曲谱评测(按钮合集)" transform="translate(-346.000000, -218.000000)">
+            <g id="示范" transform="translate(346.000000, 218.000000)">
+                <rect id="矩形备份-37" fill="#2DC7AA" x="0" y="0" width="29" height="29" rx="14.5"></rect>
+                <path d="M11,8 C12.6568542,8 14,9.34314575 14,11 L14,13 C14,13.5522847 13.5522847,14 13,14 L11,14 C9.34314575,14 8,12.6568542 8,11 C8,9.34314575 9.34314575,8 11,8 Z" id="矩形" fill="#FFFFFF"></path>
+                <path d="M11,15 L13,15 C13.5522847,15 14,15.4477153 14,16 L14,18 C14,19.6568542 12.6568542,21 11,21 C9.34314575,21 8,19.6568542 8,18 C8,16.3431458 9.34314575,15 11,15 Z" id="矩形备份-2" fill="#FFFFFF"></path>
+                <rect id="矩形备份" fill-opacity="0.8" fill="#FFFFFF" x="15" y="8" width="6" height="6" rx="3"></rect>
+                <path d="M16,15 L18,15 C19.6568542,15 21,16.3431458 21,18 C21,19.6568542 19.6568542,21 18,21 C16.3431458,21 15,19.6568542 15,18 L15,16 C15,15.4477153 15.4477153,15 16,15 Z" id="矩形备份-3" fill="#FFFFFF"></path>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
src/page-orchestra/header-top/image/music.png


+ 36 - 0
src/page-orchestra/header-top/image/off.svg

@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="46px" height="24px" viewBox="0 0 46 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>switch off备份@2x</title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
+            <stop stop-color="#FFFFFF" offset="0%"></stop>
+            <stop stop-color="#F2F2F2" offset="100%"></stop>
+        </linearGradient>
+        <rect id="path-2" x="15.6818182" y="2.09090909" width="27.1818182" height="18.8181818" rx="7"></rect>
+        <filter x="-12.9%" y="-13.3%" width="125.8%" height="137.2%" filterUnits="objectBoundingBox" id="filter-3">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.63062408   0 0 0 0 0.63062408   0 0 0 0 0.63062408  0 0 0 0.746606787 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="全局设置" transform="translate(-495.000000, -122.000000)">
+            <g id="编组-22" transform="translate(246.000000, 23.000000)">
+                <g id="编组-19" transform="translate(25.000000, 99.000000)">
+                    <g id="switch-off备份" transform="translate(247.000000, 11.500000) scale(-1, 1) translate(-247.000000, -11.500000) translate(224.000000, 0.000000)">
+                        <rect id="矩形" fill="#D2D2D2" x="0" y="0" width="46" height="23" rx="9"></rect>
+                        <g id="矩形">
+                            <use fill="black" fill-opacity="1" filter="url(#filter-3)" xlink:href="#path-2"></use>
+                            <use fill="url(#linearGradient-1)" fill-rule="evenodd" xlink:href="#path-2"></use>
+                        </g>
+                        <g id="OFF" transform="translate(29.712631, 11.412864) scale(-1, 1) translate(-29.712631, -11.412864) translate(20.609807, 7.359364)" fill="#D0D0D0" fill-rule="nonzero">
+                            <path d="M3.476,0 C4.07,0 4.58516667,0.1045 5.0215,0.3135 C5.45783333,0.5225 5.819,0.8085 6.105,1.1715 C6.391,1.5345 6.60366667,1.96166667 6.743,2.453 C6.88233333,2.94433333 6.952,3.476 6.952,4.048 C6.952,4.62 6.88233333,5.1535 6.743,5.6485 C6.60366667,6.1435 6.391,6.5725 6.105,6.9355 C5.819,7.2985 5.45783333,7.5845 5.0215,7.7935 C4.58516667,8.0025 4.07,8.107 3.476,8.107 C2.904,8.107 2.40166667,8.00616667 1.969,7.8045 C1.53633333,7.60283333 1.17333333,7.32233333 0.88,6.963 C0.586666667,6.60366667 0.366666667,6.17466667 0.22,5.676 C0.0733333333,5.17733333 0,4.63466667 0,4.048 C0,3.48333333 0.066,2.9535 0.198,2.4585 C0.33,1.9635 0.537166667,1.5345 0.8195,1.1715 C1.10183333,0.8085 1.46116667,0.5225 1.8975,0.3135 C2.33383333,0.1045 2.86,0 3.476,0 Z M3.476,6.853 C3.86466667,6.853 4.18916667,6.7815 4.4495,6.6385 C4.70983333,6.4955 4.92066667,6.29933333 5.082,6.05 C5.24333333,5.80066667 5.357,5.50733333 5.423,5.17 C5.489,4.83266667 5.522,4.46966667 5.522,4.081 C5.522,3.69233333 5.48533333,3.32566667 5.412,2.981 C5.33866667,2.63633333 5.22133333,2.33566667 5.06,2.079 C4.89866667,1.82233333 4.68783333,1.62066667 4.4275,1.474 C4.16716667,1.32733333 3.85,1.254 3.476,1.254 C3.102,1.254 2.78483333,1.32916667 2.5245,1.4795 C2.26416667,1.62983333 2.05333333,1.8315 1.892,2.0845 C1.73066667,2.3375 1.61333333,2.63266667 1.54,2.97 C1.46666667,3.30733333 1.43,3.66666667 1.43,4.048 C1.43,4.39266667 1.463,4.73366667 1.529,5.071 C1.595,5.40833333 1.70866667,5.709 1.87,5.973 C2.03133333,6.237 2.24216667,6.44966667 2.5025,6.611 C2.76283333,6.77233333 3.08733333,6.853 3.476,6.853 Z" id="形状"></path>
+                            <path d="M11.671,3.311 C11.8836667,3.311 12.0523333,3.36233333 12.177,3.465 C12.2796667,3.56766667 12.331,3.72533333 12.331,3.938 C12.331,4.158 12.2796667,4.31383333 12.177,4.4055 C12.0743333,4.49716667 11.9056667,4.543 11.671,4.543 L9.339,4.543 L9.339,7.546 C9.339,7.64866667 9.28216667,7.7495 9.1685,7.8485 C9.05483333,7.9475 8.86966667,7.997 8.613,7.997 C8.35633333,7.997 8.17483333,7.9475 8.0685,7.8485 C7.96216667,7.7495 7.909,7.64866667 7.909,7.546 L7.909,0.825 C7.909,0.597666667 7.96766667,0.44 8.085,0.352 C8.20233333,0.264 8.37833333,0.22 8.613,0.22 L12.012,0.22 C12.2246667,0.22 12.3841667,0.265833333 12.4905,0.3575 C12.5968333,0.449166667 12.6536667,0.608666667 12.661,0.836 C12.6683333,1.06333333 12.6133333,1.22283333 12.496,1.3145 C12.3786667,1.40616667 12.2136667,1.452 12.001,1.452 L9.339,1.452 L9.339,3.311 L11.671,3.311 Z" id="路径"></path>
+                            <path d="M17.215,3.311 C17.4276667,3.311 17.5963333,3.36233333 17.721,3.465 C17.8236667,3.56766667 17.875,3.72533333 17.875,3.938 C17.875,4.158 17.8236667,4.31383333 17.721,4.4055 C17.6183333,4.49716667 17.4496667,4.543 17.215,4.543 L14.883,4.543 L14.883,7.546 C14.883,7.64866667 14.8261667,7.7495 14.7125,7.8485 C14.5988333,7.9475 14.4136667,7.997 14.157,7.997 C13.9003333,7.997 13.7188333,7.9475 13.6125,7.8485 C13.5061667,7.7495 13.453,7.64866667 13.453,7.546 L13.453,0.825 C13.453,0.597666667 13.5116667,0.44 13.629,0.352 C13.7463333,0.264 13.9223333,0.22 14.157,0.22 L17.556,0.22 C17.7686667,0.22 17.9281667,0.265833333 18.0345,0.3575 C18.1408333,0.449166667 18.1976667,0.608666667 18.205,0.836 C18.2123333,1.06333333 18.1573333,1.22283333 18.04,1.3145 C17.9226667,1.40616667 17.7576667,1.452 17.545,1.452 L14.883,1.452 L14.883,3.311 L17.215,3.311 Z" id="路径"></path>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 39 - 0
src/page-orchestra/header-top/image/on.svg

@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="46px" height="24px" viewBox="0 0 46 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>switch off@2x</title>
+    <defs>
+        <linearGradient x1="78.0181074%" y1="0%" x2="78.0181074%" y2="100%" id="linearGradient-1">
+            <stop stop-color="#39F3D0" offset="0%"></stop>
+            <stop stop-color="#2DC7AA" offset="100%"></stop>
+        </linearGradient>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-2">
+            <stop stop-color="#FFFFFF" offset="0%"></stop>
+            <stop stop-color="#DAFFF8" offset="100%"></stop>
+        </linearGradient>
+        <rect id="path-3" x="2.09090909" y="2.09090909" width="27.1818182" height="18.8181818" rx="7"></rect>
+        <filter x="-12.9%" y="-13.3%" width="125.8%" height="137.2%" filterUnits="objectBoundingBox" id="filter-4">
+            <feOffset dx="0" dy="1" in="SourceAlpha" result="shadowOffsetOuter1"></feOffset>
+            <feGaussianBlur stdDeviation="1" in="shadowOffsetOuter1" result="shadowBlurOuter1"></feGaussianBlur>
+            <feColorMatrix values="0 0 0 0 0.093603643   0 0 0 0 0.694167427   0 0 0 0 0.581074247  0 0 0 1 0" type="matrix" in="shadowBlurOuter1"></feColorMatrix>
+        </filter>
+    </defs>
+    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="全局设置" transform="translate(-495.000000, -254.000000)">
+            <g id="编组-22" transform="translate(246.000000, 23.000000)">
+                <g id="编组-19" transform="translate(25.000000, 99.000000)">
+                    <g id="switch-off" transform="translate(247.000000, 143.500000) scale(-1, 1) translate(-247.000000, -143.500000) translate(224.000000, 132.000000)">
+                        <rect id="矩形" fill="url(#linearGradient-1)" x="0" y="0" width="46" height="23" rx="9"></rect>
+                        <g id="矩形">
+                            <use fill="black" fill-opacity="1" filter="url(#filter-4)" xlink:href="#path-3"></use>
+                            <use fill="url(#linearGradient-2)" fill-rule="evenodd" xlink:href="#path-3"></use>
+                        </g>
+                        <g id="ON" transform="translate(16.680955, 11.412864) scale(-1, 1) translate(-16.680955, -11.412864) translate(9.668455, 7.359364)" fill="#2DC7AA" fill-rule="nonzero">
+                            <path d="M3.476,0 C4.07,0 4.58516667,0.1045 5.0215,0.3135 C5.45783333,0.5225 5.819,0.8085 6.105,1.1715 C6.391,1.5345 6.60366667,1.96166667 6.743,2.453 C6.88233333,2.94433333 6.952,3.476 6.952,4.048 C6.952,4.62 6.88233333,5.1535 6.743,5.6485 C6.60366667,6.1435 6.391,6.5725 6.105,6.9355 C5.819,7.2985 5.45783333,7.5845 5.0215,7.7935 C4.58516667,8.0025 4.07,8.107 3.476,8.107 C2.904,8.107 2.40166667,8.00616667 1.969,7.8045 C1.53633333,7.60283333 1.17333333,7.32233333 0.88,6.963 C0.586666667,6.60366667 0.366666667,6.17466667 0.22,5.676 C0.0733333333,5.17733333 0,4.63466667 0,4.048 C0,3.48333333 0.066,2.9535 0.198,2.4585 C0.33,1.9635 0.537166667,1.5345 0.8195,1.1715 C1.10183333,0.8085 1.46116667,0.5225 1.8975,0.3135 C2.33383333,0.1045 2.86,0 3.476,0 Z M3.476,6.853 C3.86466667,6.853 4.18916667,6.7815 4.4495,6.6385 C4.70983333,6.4955 4.92066667,6.29933333 5.082,6.05 C5.24333333,5.80066667 5.357,5.50733333 5.423,5.17 C5.489,4.83266667 5.522,4.46966667 5.522,4.081 C5.522,3.69233333 5.48533333,3.32566667 5.412,2.981 C5.33866667,2.63633333 5.22133333,2.33566667 5.06,2.079 C4.89866667,1.82233333 4.68783333,1.62066667 4.4275,1.474 C4.16716667,1.32733333 3.85,1.254 3.476,1.254 C3.102,1.254 2.78483333,1.32916667 2.5245,1.4795 C2.26416667,1.62983333 2.05333333,1.8315 1.892,2.0845 C1.73066667,2.3375 1.61333333,2.63266667 1.54,2.97 C1.46666667,3.30733333 1.43,3.66666667 1.43,4.048 C1.43,4.39266667 1.463,4.73366667 1.529,5.071 C1.595,5.40833333 1.70866667,5.709 1.87,5.973 C2.03133333,6.237 2.24216667,6.44966667 2.5025,6.611 C2.76283333,6.77233333 3.08733333,6.853 3.476,6.853 Z" id="形状"></path>
+                            <path d="M9.339,7.425 C9.339,7.57166667 9.284,7.70366667 9.174,7.821 C9.064,7.93833333 8.88066667,7.997 8.624,7.997 C8.36733333,7.997 8.184,7.93466667 8.074,7.81 C7.964,7.68533333 7.909,7.557 7.909,7.425 L7.909,0.627 C7.909,0.495 7.94566667,0.375833333 8.019,0.2695 C8.09233333,0.163166667 8.261,0.11 8.525,0.11 C8.67166667,0.11 8.79083333,0.154 8.8825,0.242 C8.97416667,0.33 9.053,0.418 9.119,0.506 L12.595,5.181 L12.595,0.682 C12.595,0.55 12.65,0.421666667 12.76,0.297 C12.87,0.172333333 13.0533333,0.11 13.31,0.11 C13.5666667,0.11 13.75,0.168666667 13.86,0.286 C13.97,0.403333333 14.025,0.535333333 14.025,0.682 L14.025,7.502 C14.025,7.62666667 13.9883333,7.74033333 13.915,7.843 C13.8416667,7.94566667 13.6766667,7.997 13.42,7.997 C13.2733333,7.997 13.1505,7.953 13.0515,7.865 C12.9525,7.777 12.87,7.689 12.804,7.601 L9.339,3.08 L9.339,7.425 Z" id="路径"></path>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
src/page-orchestra/header-top/image/plus.png


+ 25 - 0
src/page-orchestra/header-top/image/replay.svg

@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="40px" height="40px" viewBox="0 0 40 40" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>暂停备份</title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="99.3846973%" id="linearGradient-1">
+            <stop stop-color="#FFFFFF" offset="0%"></stop>
+            <stop stop-color="#FFFFFF" stop-opacity="0.589416077" offset="100%"></stop>
+        </linearGradient>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="99.3846973%" id="linearGradient-2">
+            <stop stop-color="#FFFFFF" offset="0%"></stop>
+            <stop stop-color="#FFFFFF" stop-opacity="0.589416077" offset="100%"></stop>
+        </linearGradient>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="主界面暂停" transform="translate(-677.000000, -301.000000)">
+            <g id="暂停备份" transform="translate(677.000000, 301.000000)">
+                <rect id="矩形" fill="#2DC7AA" x="0" y="0" width="40" height="40" rx="20"></rect>
+                <g id="编组" transform="translate(19.522776, 19.799926) scale(-1, 1) translate(-19.522776, -19.799926) translate(5.000000, 6.000000)">
+                    <path d="M13.3725568,0 L13.3563443,0 C7.68145471,0.0653974039 2.6664899,3.70847155 0.847834102,9.08655422 L0.817617962,9.15122482 C0.797302775,9.20165727 0.777069364,9.26566714 0.759461507,9.33689435 L0.732063087,9.4749694 L0.753800649,9.40595609 C0.272209238,10.8185203 0.0184121264,12.2987613 0.00193173024,13.7911355 C-0.123254569,21.2877541 5.85181356,27.4712437 13.3499838,27.5998518 L13.7189868,27.5922013 C17.2787984,27.468538 20.6206322,25.9074407 22.9897078,23.2690016 L23.2070631,23.0189694 L23.1449335,23.0794585 C23.2603529,22.9795146 23.362263,22.8649591 23.4480926,22.7386843 C23.6720399,22.329715 23.7570443,21.9501401 23.7376485,21.5686354 C23.6254619,20.6372478 22.888075,19.9766574 22.0070416,19.9661689 L21.8305569,19.9837288 C21.3964214,20.0763739 20.9897811,20.2687516 20.64277,20.5456526 L20.5375202,20.6466519 C18.7304559,22.7291273 16.1140168,23.9314266 13.357623,23.9459806 C7.96780108,23.8535225 3.63958992,19.4689892 3.57989406,14.0920329 L3.58062942,13.8130463 C3.49162395,8.28356315 7.87660023,3.74893628 13.3772597,3.65571168 L13.6826276,3.66341095 C16.9313146,3.79699016 19.8952317,5.57049175 21.5651633,8.35089652 L21.6090631,8.4259694 L21.1341843,8.63175621 L20.925866,8.71400596 C18.6892851,9.56846024 18.1787287,11.0457946 20.1238869,12.0193514 L20.5442371,12.2181679 L21.0321057,12.4617975 L21.6313166,12.7737254 L22.2220542,13.0890242 C22.5238873,13.2515877 22.8360126,13.4216673 23.1493276,13.5939227 L24.2374418,14.1981448 C25.8107445,15.0427057 27.0707432,14.4070096 27.5034432,12.6071061 L27.6808279,11.9061013 C27.9271949,10.9739797 28.2129083,10.0522959 28.537129,9.14382584 L28.5970631,8.9799694 L28.7969478,8.46456175 C29.623868,6.28961617 28.2971865,5.51302702 26.159053,6.46427584 L25.6914434,6.67968867 L24.9420631,6.9949694 L24.8465083,6.8181108 C22.5404703,2.66770793 18.1686454,0.041949839 13.3725568,0 Z" id="路径" fill="url(#linearGradient-1)"></path>
+                    <path d="M12.5618308,10.560238 L16.242904,16.2863518 C16.6908822,16.9832069 16.4891277,17.9112777 15.7922727,18.3592559 C15.5503267,18.5147926 15.2687637,18.5974882 14.9811363,18.5974882 L7.61898991,18.5974882 C6.79056278,18.5974882 6.11898991,17.9259153 6.11898991,17.0974882 C6.11898991,16.8098608 6.20168548,16.5282978 6.35722219,16.2863518 L10.0382954,10.560238 C10.4862736,9.86338291 11.4143444,9.66162839 12.1111995,10.1096066 C12.2919535,10.2258056 12.4456318,10.379484 12.5618308,10.560238 Z" id="三角形" fill="url(#linearGradient-2)" transform="translate(11.300063, 13.597488) rotate(-90.000000) translate(-11.300063, -13.597488) "></path>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

File diff suppressed because it is too large
+ 11 - 0
src/page-orchestra/header-top/image/section0.svg


File diff suppressed because it is too large
+ 11 - 0
src/page-orchestra/header-top/image/section1.svg


File diff suppressed because it is too large
+ 11 - 0
src/page-orchestra/header-top/image/section2.svg


File diff suppressed because it is too large
+ 11 - 0
src/page-orchestra/header-top/image/shuodiao-active.svg


File diff suppressed because it is too large
+ 11 - 0
src/page-orchestra/header-top/image/shuodiao.svg


+ 41 - 0
src/page-orchestra/header-top/image/speed.svg

@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="29px" height="29px" viewBox="0 0 29 29" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>速度</title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
+            <stop stop-color="#1D8270" offset="0%"></stop>
+            <stop stop-color="#105548" offset="100%"></stop>
+        </linearGradient>
+        <path d="M7.39092163,3.03294464 C7.39092163,3.72564768 7.56508899,4.37722505 7.87156676,4.94536012 L1.5,4.94501223 C0.671572875,4.94501223 1.01453063e-16,4.27343935 0,3.44501223 C-1.01453063e-16,2.6165851 0.671572875,1.94501223 1.5,1.94501223 L7.53933813,1.94388547 C7.44265229,2.29012358 7.39092163,2.6554266 7.39092163,3.03294464 Z M17.1949452,1.94501223 C18.0233723,1.94501223 18.6949452,2.6165851 18.6949452,3.44501223 C18.6949452,4.27343935 18.0233723,4.94501223 17.1949452,4.94501223 L14.8233784,4.94536012 C15.1298562,4.37722505 15.3040235,3.72564768 15.3040235,3.03294464 C15.3040235,2.6554266 15.2522929,2.29012358 15.155607,1.94388547 L17.1949452,1.94501223 Z" id="path-2"></path>
+        <path d="M3.42,12.4830669 C3.42,13.17577 3.59416736,13.8273473 3.90064512,14.3954824 L1.5,14.3951345 C0.671572875,14.3951345 1.01453063e-16,13.7235616 0,12.8951345 C-1.01453063e-16,12.0667074 0.671572875,11.3951345 1.5,11.3951345 L3.5684165,11.3940078 C3.47173066,11.7402459 3.42,12.1055489 3.42,12.4830669 Z M17.1949452,11.3951345 C18.0233723,11.3951345 18.6949452,12.0667074 18.6949452,12.8951345 C18.6949452,13.7235616 18.0233723,14.3951345 17.1949452,14.3951345 L10.8524568,14.3954824 C11.1589345,13.8273473 11.3331019,13.17577 11.3331019,12.4830669 C11.3331019,12.1055489 11.2813712,11.7402459 11.1846854,11.3940078 L17.1949452,11.3951345 Z" id="path-3"></path>
+        <ellipse id="path-4" cx="11.3474726" cy="3.03294464" rx="3" ry="3.03294464"></ellipse>
+        <ellipse id="path-5" cx="7.32" cy="12.4830669" rx="3" ry="3.03294464"></ellipse>
+    </defs>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="主界面" transform="translate(-611.000000, -13.000000)">
+            <g id="速度" transform="translate(611.000000, 13.000000)">
+                <rect id="矩形备份-31" fill="#2DC7AA" x="0" y="0" width="29" height="29" rx="14.5"></rect>
+                <g id="编组-4" transform="translate(5.180000, 6.900000)">
+                    <g id="形状结合">
+                        <use fill="url(#linearGradient-1)" xlink:href="#path-2"></use>
+                        <use fill="#166B5B" xlink:href="#path-2"></use>
+                        <use fill="#FFFFFF" xlink:href="#path-2"></use>
+                    </g>
+                    <g id="形状结合">
+                        <use fill="url(#linearGradient-1)" xlink:href="#path-3"></use>
+                        <use fill="#166B5B" xlink:href="#path-3"></use>
+                        <use fill="#FFFFFF" xlink:href="#path-3"></use>
+                    </g>
+                    <g id="椭圆形备份-8">
+                        <use fill="#FFBB39" xlink:href="#path-4"></use>
+                        <ellipse stroke="#2DC7AA" stroke-width="1" fill="#FFFFFF" cx="11.3474726" cy="3.03294464" rx="3.5" ry="3.53294464"></ellipse>
+                    </g>
+                    <g id="椭圆形备份-9">
+                        <use fill="#FFBB39" xlink:href="#path-5"></use>
+                        <ellipse stroke="#2DC7AA" stroke-width="1" fill="#FFFFFF" cx="7.32" cy="12.4830669" rx="3.5" ry="3.53294464"></ellipse>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 9 - 0
src/page-orchestra/header-top/image/task-bg.svg

@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="208px" height="70px" viewBox="0 0 208 70" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>矩形</title>
+    <g id="页面-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="曲谱评测" transform="translate(-582.000000, -215.000000)" fill="#FFE1B8" stroke="#FFFFFF" stroke-width="2">
+            <path d="M591,216.506546 L781,216.506546 C785.418278,216.506546 789,220.088268 789,224.506546 L789,278.353946 C789,281.11537 786.761424,283.353946 784,283.353946 C783.212178,283.353946 782.435504,283.167782 781.733289,282.810629 L768.300488,275.978581 L768.300488,275.978581 L591,275.978581 C586.581722,275.978581 583,272.396859 583,267.978581 L583,224.506546 C583,220.088268 586.581722,216.506546 591,216.506546 Z" id="矩形"></path>
+        </g>
+    </g>
+</svg>

BIN
src/page-orchestra/header-top/image/tickoff.png


BIN
src/page-orchestra/header-top/image/tickon.png


+ 20 - 0
src/page-orchestra/header-top/image/tv.svg

@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="22px" height="23px" viewBox="0 0 22 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组备份 6</title>
+    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="全局设置" transform="translate(-367.000000, -299.000000)">
+            <g id="编组-22" transform="translate(246.000000, 23.000000)">
+                <g id="编组-17" transform="translate(114.000000, 272.000000)">
+                    <g id="编组-46" transform="translate(7.000000, 4.500000)">
+                        <rect id="矩形" stroke="#F9BA48" stroke-width="2" fill-opacity="0" fill="#FFFFFF" x="1.978125" y="5" width="18" height="12.5454545" rx="4"></rect>
+                        <path d="M14.9070724,20.854067 L6.78601974,20.854067 C6.2541593,20.8534219 5.77499033,20.5326466 5.57171716,20.0411632 C5.36844399,19.5496798 5.48104637,18.9841531 5.85707237,18.6080144 L9.91628289,14.547488 C10.1630832,14.300413 10.4979813,14.1615845 10.8472039,14.1615845 C11.1964266,14.1615845 11.5313247,14.300413 11.778125,14.547488 L15.8373355,18.6080144 C16.2135302,18.9843226 16.3260486,19.5501678 16.1224381,20.0417704 C15.9188277,20.5333729 15.4391722,20.8539534 14.9070724,20.854067 L14.9070724,20.854067 Z" id="路径" fill="#FFE2A5" fill-rule="nonzero"></path>
+                        <path d="M10.4301429,16.5045441 L8.72688718,18.2974605 C8.49865673,18.5377051 8.50839618,18.9174792 8.74864084,19.1457097 C8.8601504,19.2516429 9.00808287,19.3107082 9.16188863,19.3107082 L12.5887484,19.3107082 C12.9201192,19.3107082 13.1887484,19.0420791 13.1887484,18.7107082 C13.1887484,18.5556719 13.1287365,18.4066537 13.0212909,18.2948874 L11.2976869,16.501971 C11.0680354,16.2630844 10.6882102,16.2555978 10.4493236,16.4852493 C10.442785,16.4915351 10.4363898,16.4979683 10.4301429,16.5045441 Z" id="路径" fill="#07D085"></path>
+                        <g id="编组" transform="translate(4.741975, 8.100000)" fill="#07D085">
+                            <path d="M7.30434783,0.0673211781 C7.47265077,0.134642356 7.64095372,0.269284712 7.70827489,0.437587658 L9.2230014,3.43338008 L10.7377279,0.437587658 C10.8050491,0.269284712 10.973352,0.134642356 11.141655,0.0673211781 C11.3099579,1.35759459e-13 11.5119215,0.0336605891 11.6802244,0.100981767 C12.0841515,0.302945302 12.2187938,0.740532959 12.0504909,1.07713885 L9.89621318,5.35203366 C9.76157083,5.58765778 9.5259467,5.75596073 9.25666199,5.75596073 C8.98737728,5.75596073 8.75175316,5.58765778 8.6171108,5.35203366 L6.4628331,1.07713885 C6.29453015,0.70687237 6.42917251,0.302945302 6.7657784,0.100981767 C6.93408135,1.35759459e-13 7.13604488,1.35759459e-13 7.30434783,0.0673211781 Z M5.01542777,-7.32747196e-14 C5.41935484,0.0336605891 5.72230014,0.336605891 5.72230014,0.740532959 C5.75596073,1.14446003 5.45301543,1.48106592 5.04908836,1.48106592 L3.63534362,1.48106592 L3.63534362,5.01542777 C3.63534362,5.28471248 3.50070126,5.52033661 3.26507714,5.65497896 C3.02945302,5.78962132 2.7601683,5.78962132 2.52454418,5.65497896 C2.28892006,5.52033661 2.1542777,5.28471248 2.1542777,5.01542777 L2.1542777,1.48106592 L0.740532959,1.48106592 C0.471248247,1.48106592 0.235624123,1.34642356 0.100981767,1.11079944 C-0.0336605891,0.875175316 -0.0336605891,0.605890603 0.100981767,0.37026648 C0.235624123,0.134642356 0.471248247,-7.32747196e-14 0.740532959,-7.32747196e-14 L5.01542777,-7.32747196e-14 Z" id="形状结合"></path>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 21 - 0
src/page-orchestra/header-top/image/yijian.svg

@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="22px" height="23px" viewBox="0 0 22 23" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>编组备份 7</title>
+    <g id="页面-2" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="全局设置" transform="translate(-465.000000, -299.000000)" fill-rule="nonzero">
+            <g id="编组-22" transform="translate(246.000000, 23.000000)">
+                <g id="编组-18" transform="translate(212.000000, 272.000000)">
+                    <g id="编组-14" transform="translate(7.000000, 4.500000)">
+                        <g id="编组-13" transform="translate(9.952353, 10.596238) rotate(-8.000000) translate(-9.952353, -10.596238) translate(3.605818, 4.124997)">
+                            <polygon id="路径" fill="#F9BA48" points="9.31976279 6.46978235 6.20608798 3.28933727 1.71549835 8.04841031 1.65504464 8.43169573 4.85596707 11.157485 5.00773643 11.1420884"></polygon>
+                            <polygon id="路径" fill="#FFA623" points="12.5538987 3.18607507 12.6930693 2.30867243 10.3745787 -1.22408265e-12 9.44707258 0.0467735195 7.16794043 2.32640346 10.389941 5.38357242"></polygon>
+                            <polygon id="路径" fill="#07D085" points="3.40396243 11.5455765 1.19290507 9.73299521 0.278444075 11.9264589 1.42108547e-14 12.9424828 0.695406418 12.7114988"></polygon>
+                        </g>
+                        <path d="M5.37182153,18.276632 C4.88982252,18.276632 4.499019,18.6674184 4.499019,19.1494174 C4.499019,19.6315537 4.88982252,20.0223229 5.37182153,20.0223229 L16.5857686,20 C17.0677676,20 17.4585711,19.6092136 17.4585711,19.1270945 C17.4585711,18.6450955 17.0677676,18.2543091 16.5857686,18.2543091 L5.37182153,18.276632 Z" id="路径" fill="#07D085"></path>
+                        <path d="M16.5771176,16.0636433 C17.0638026,16.0636433 17.4585883,15.6688748 17.4585883,15.1822585 C17.4585883,14.6956422 17.0638026,14.3009252 16.5771176,14.3009252 L12.3904933,14.3232481 C11.903877,14.3232481 11.5091257,14.7179651 11.5091257,15.2045814 C11.5091257,15.6911977 11.903877,16.0859662 12.3904933,16.0859662 L16.5771176,16.0636433 Z" id="路径" fill="#07D085"></path>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 128 - 0
src/page-orchestra/header-top/index.module.less

@@ -0,0 +1,128 @@
+.headerTop {
+    display: flex;
+    align-items: center;
+    width: 100%;
+    height: 100%;
+    flex-shrink: 0;
+    padding: 8px 10px;
+    background: var(--container-background);
+    padding-bottom: 0;
+}
+
+.back {
+    display: flex;
+    align-items: center;
+    height: 100%;
+    padding: 0 11px 0 6px;
+
+    img {
+        display: block;
+        width: 24px;
+        height: 24px;
+    }
+}
+
+.headRight {
+    display: flex;
+    align-items: center;
+    margin-left: auto;
+
+    .btn {
+        position: relative;
+        display: flex;
+        flex-direction: column;
+        justify-content: center;
+        align-items: center;
+        font-size: 11px;
+        line-height: 16px;
+        font-weight: 400;
+        padding: 0 6px;
+
+        .iconBtn {
+            display: block;
+            width: 25px;
+            height: 25px;
+        }
+
+        span {
+            white-space: nowrap;
+        }
+
+        .btnWrap {
+            position: relative;
+            width: 25px;
+            height: 25px;
+        }
+
+        .progress {
+            position: absolute;
+            left: 50%;
+            top: 50%;
+            transform: translate(-50%, -50%);
+            width: 85%;
+            height: 85%;
+        }
+
+        &.disabled {
+            opacity: .8;
+        }
+    }
+
+    .badge {
+        :global {
+            .van-badge {
+                border: none;
+                color: #135D4F;
+                background: linear-gradient(180deg, #FFD689 0%, #FEBD41 100%);
+                border: 1px solid #FFFFFF;
+                font-weight: 400;
+            }
+        }
+    }
+
+    .playBtn {
+        position: fixed;
+        right: 32px;
+        bottom: 32px;
+
+        .btnWrap {
+            width: 36px;
+            height: 36px;
+
+            .iconBtn {
+                display: block;
+                width: 100%;
+                height: 100%;
+            }
+        }
+    }
+
+    .resetBtn {
+        position: fixed;
+        right: 88px;
+        bottom: 32px;
+        padding: 0;
+
+        .iconBtn {
+            display: block;
+            width: 36px;
+            height: 36px;
+        }
+    }
+}
+
+.disable {
+    pointer-events: none;
+    opacity: .6;
+}
+
+:global {
+    .var-popup {
+        overflow: hidden;
+        pointer-events: none;
+        .var-popup__overlay,
+        .var-popup__content{
+            pointer-events: auto;
+        }
+    }
+}

+ 219 - 0
src/page-orchestra/header-top/index.tsx

@@ -0,0 +1,219 @@
+import { computed, defineComponent, onMounted, reactive, ref } from "vue";
+import styles from "./index.module.less";
+
+import iconBack from "./image/icon-back.svg";
+import Title from "./title";
+import { headImg } from "./image";
+import icons from "./image/headerTop.json";
+import { Badge, Circle, Popover } from "vant";
+import { metronomeData } from "../../helpers/metronome";
+import Speed from "./speed";
+import { evaluatingData, handleStartEvaluat } from "/src/view/evaluating";
+import { Popup } from "@varlet/ui";
+import Settting from "./settting";
+import ModeTypeMode from "./mode-type-mode";
+import state, { handleChangeSection, handleResetPlay, handleRessetState, togglePlay } from "/src/state";
+import { getAudioCurrentTime } from "/src/view/audio-list";
+import { toggleFollow } from "/src/view/follow-practice";
+import { api_back } from "/src/helpers/communication";
+import MusicType from "./music-type";
+
+export const headData = reactive({
+	speedShow: false,
+	musicTypeShow: false,
+});
+
+export default defineComponent({
+	name: "header-top",
+	setup() {
+		const headerData = reactive({
+			settingMode: false,
+			modeMode: true, // 模式弹框
+		});
+		const headRef = ref();
+
+		const toggleEvaluat = () => {
+			handleStartEvaluat();
+		};
+
+		/** 切换模式 */
+		const handleChangeModeType = (value: "practise" | "follow" | "evaluating") => {
+			if (value === "evaluating") {
+				toggleEvaluat();
+			} else if (value === "follow") {
+				toggleFollow();
+			}
+			headerData.modeMode = false;
+		};
+		const disabledList = ["evaluating"];
+
+		/** 按钮禁用 */
+
+		/** 重播按钮显示条件 */
+		const resetBtnDisplay = computed(() => {
+			const currentTime = getAudioCurrentTime();
+			const playState = state.playState;
+			const modeType = state.modeType;
+			return currentTime !== 0 && playState !== "play" && modeType === "practise";
+		});
+		/** 播放按钮显示条件 */
+		const playBtnDisplay = computed(() => {
+			const modeType = state.modeType;
+			return modeType === "practise";
+		});
+		/** 指法显示条件 */
+		const fingeringDisplay = computed(() => {
+			return state.fingeringInfo.name;
+		});
+
+		/** 返回 */
+		const handleBack = () => {
+			api_back();
+		};
+
+		return () => (
+			<div ref={headRef} class={styles.headerTop}>
+				<div class={styles.back} onClick={handleBack}>
+					<img src={iconBack} />
+				</div>
+				<Title text={state.examSongName} rightView={false} />
+
+				<div class={styles.headRight} style={{ display: headerData.modeMode ? "none" : "" }}>
+					<div
+						class={styles.btn}
+						onClick={() => {
+							handleRessetState();
+							headerData.modeMode = true;
+						}}
+					>
+						<img class={styles.iconBtn} src={headImg(`modeType.svg`)} />
+						<span>模式</span>
+					</div>
+
+					<div
+						class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
+						id="tips-step-6"
+						onClick={() => {
+							state.playSource = state.playSource === "music" ? "background" : "music";
+						}}
+					>
+						<img class={styles.iconBtn} src={state.playSource === "music" ? icons.music : icons.background} />
+						<span>{state.playSource === "music" ? "原声" : "伴奏"}</span>
+					</div>
+					<div class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]} id="tips-step-4" onClick={() => handleChangeSection()}>
+						<img class={styles.iconBtn} src={headImg(`section${state.section.length}.svg`)} />
+						<span>选段</span>
+					</div>
+					<div
+						style={{ display: fingeringDisplay.value ? "" : "none" }}
+						class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
+						onClick={() => {
+							state.setting.displayFingering = !state.setting.displayFingering;
+						}}
+					>
+						<img class={styles.iconBtn} src={state.setting.displayFingering ? icons.fingeringOn : icons.fingeringOff} />
+						<span>指法</span>
+					</div>
+
+					{/* <div
+						class={[styles.btn]}
+						onClick={async () => {
+							metronomeData.lineShow = !metronomeData.lineShow;
+						}}
+					>
+						<img class={styles.iconBtn} src={headImg("iconStep.png")} />
+						<span>{metronomeData.lineShow ? "高级" : "初级"}</span>
+					</div> */}
+					{/* <div
+						class={styles.btn}
+						onClick={async () => {
+							metronomeData.disable = !metronomeData.disable;
+							metronomeData.metro?.initPlayer();
+						}}
+					>
+						<img style={{ display: metronomeData.disable ? "block" : "none" }} class={styles.iconBtn} src={headImg("tickoff.png")} />
+						<img style={{ display: !metronomeData.disable ? "block" : "none" }} class={styles.iconBtn} src={headImg("tickon.png")} />
+						<span style={{ whiteSpace: "nowrap" }}>节拍器</span>
+					</div> */}
+
+					<Popover trigger="manual" v-model:show={headData.speedShow} placement="bottom" overlay={false}>
+						{{
+							reference: () => (
+								<div
+									id="tips-step-8"
+									class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
+									onClick={(e: Event) => {
+										e.stopPropagation();
+										headData.speedShow = !headData.speedShow;
+									}}
+								>
+									<Badge class={styles.badge} content={state.speed}>
+										<img class={styles.iconBtn} src={headImg("speed.svg")} />
+									</Badge>
+									<span>速度</span>
+								</div>
+							),
+							default: () => <Speed />,
+						}}
+					</Popover>
+					<Popover trigger="manual" v-model:show={headData.musicTypeShow} placement="bottom-end" overlay={false}>
+						{{
+							reference: () => (
+								<div
+									class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]}
+									onClick={(e: Event) => {
+										e.stopPropagation();
+										headData.musicTypeShow = !headData.musicTypeShow;
+									}}
+								>
+									<img class={styles.iconBtn} src={headImg("icon-zhuanpu.svg")} />
+									<span>转简谱</span>
+								</div>
+							),
+							default: () => <MusicType />,
+						}}
+					</Popover>
+
+					<div class={[styles.btn, disabledList.includes(state.modeType) && styles.disable]} onClick={() => (headerData.settingMode = true)}>
+						<img class={styles.iconBtn} src={headImg("menu.svg")} />
+						<span>设置</span>
+					</div>
+
+					<div
+						style={{ display: playBtnDisplay.value ? "" : "none" }}
+						class={[styles.btn, styles.playBtn, disabledList.includes(state.modeType) && styles.disable]}
+						id="tips-step-5"
+						onClick={() => togglePlay()}
+					>
+						<div class={styles.btnWrap}>
+							<img class={styles.iconBtn} src={state.playState === "paused" ? icons.play : icons.pause} />
+							<Circle
+								style={{ opacity: state.playState === "play" ? 1 : 0 }}
+								class={styles.progress}
+								stroke-width={80}
+								currentRate={state.playProgress}
+								rate={100}
+								color="#FFC830"
+							/>
+						</div>
+					</div>
+					<div
+						style={{ display: resetBtnDisplay.value ? "" : "none" }}
+						class={[styles.btn, styles.resetBtn, disabledList.includes(state.modeType) && styles.disable]}
+						id="tips-step-7"
+						onClick={() => handleResetPlay()}
+					>
+						<img class={styles.iconBtn} src={headImg("replay.svg")} />
+					</div>
+				</div>
+
+				<Popup teleport="body" defaultStyle={false} v-model:show={headerData.settingMode}>
+					<Settting onClose={() => (headerData.settingMode = false)} />
+				</Popup>
+				<Popup teleport="body" position="bottom" closeOnClickOverlay={false} overlay={false} defaultStyle={false} v-model:show={headerData.modeMode}>
+					<ModeTypeMode onClose={(value) => handleChangeModeType(value)} />
+				</Popup>
+			</div>
+		);
+	},
+});

+ 12 - 0
src/page-orchestra/header-top/mode-type-mode/index.module.less

@@ -0,0 +1,12 @@
+.wrap {
+  height: 110px;
+  display: flex;
+  justify-content: space-evenly;
+  align-items: center;
+  background: linear-gradient(to top, rgba(255,255,255,1), rgba(255,255,255, .7));
+  padding: 0 40px;
+  img {
+    width: 127px;
+    height: 46px;
+  }
+}

+ 17 - 0
src/page-orchestra/header-top/mode-type-mode/index.tsx

@@ -0,0 +1,17 @@
+import { defineComponent, Teleport, Transition } from "vue";
+import styles from "./index.module.less";
+import { model1, model2, model3 } from "../image/headerTop.json";
+
+export default defineComponent({
+	name: "modelWraper",
+	emits: ["close"],
+	setup(props, { emit }) {
+		return () => (
+			<div class={styles.wrap}>
+				<img onClick={() => emit("close", "practise")} src={model1} />
+				<img onClick={() => emit("close", "follow")} src={model3} />
+				<img onClick={() => emit("close", "evaluating")} src={model2} />
+			</div>
+		);
+	},
+});

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