소스 검색

fix:生成缓存

liushengqiang 1 년 전
부모
커밋
0f5e1b3cc7

+ 4 - 0
src/page-instrument/router.ts

@@ -8,6 +8,10 @@ const routes: RouteRecordRaw[] = [
 		component: Home,
 	},
 	{
+		path: "/product-img",
+		component: () => import("./view-product-img/index"),
+	},
+	{
 		path: "/evaluat-report",
 		component: () => import("./view-evaluat-report/index"),
 	},

+ 32 - 0
src/page-instrument/view-product-img/index.module.less

@@ -0,0 +1,32 @@
+.skeleton {
+    position: fixed;
+    left: 0;
+    top: 0;
+    width: 100vw;
+    height: 100vh;
+    padding: 20px 30px;
+    background-color: #fff;
+    z-index: 1000;
+    --van-skeleton-paragraph-height: .8rem;
+}
+
+.detail {
+    width: 100vw;
+    height: 100vh;
+    overflow: hidden;
+    overflow-y: auto;
+    --header-height: 62px;
+    background: var(--container-background);
+
+    .container {
+        margin: 0 10px;
+        border-radius: 10px;
+    }
+    :global{
+        #musicAndSelection{
+            overflow: initial !important;
+            height: initial !important;
+            max-height: initial !important;
+        }
+    }
+}

+ 190 - 0
src/page-instrument/view-product-img/index.tsx

@@ -0,0 +1,190 @@
+import { defineComponent, onMounted, reactive } from "vue";
+import state, { EnumMusicRenderType } from "/src/state";
+import { setGlobalData } from "../../utils";
+import MusicScore from "../../view/music-score";
+import { sysMusicScoreAccompanimentQueryPage } from "../api";
+import styles from "./index.module.less";
+import { getQuery } from "/src/utils/queryString";
+import { Toast, closeToast, showLoadingToast, showToast } from "vant";
+import { svg2canvas } from "/src/utils/svg2canvas";
+
+export default defineComponent({
+	name: "music-list",
+	setup() {
+		const query: any = getQuery();
+
+		const detailData = reactive({
+			isLoading: true,
+			isProductLoading: false,
+			product: [
+				{
+					state: false,
+					name: "五线谱",
+					type: EnumMusicRenderType.staff,
+					base64: "" as any,
+				},
+				{
+					state: false,
+					name: "首调",
+					type: EnumMusicRenderType.firstTone,
+					base64: "" as any,
+				},
+				{
+					state: false,
+					name: "固定调",
+					type: EnumMusicRenderType.fixedTone,
+					base64: "" as any,
+				},
+			],
+		});
+		// console.log(route.params, query)
+		/** 获取曲谱数据 */
+		const getMusicInfo = (res: any) => {
+			const index = query["part-index"] ? parseInt(query["part-index"] as string) : 0;
+			const musicData = res.data.background[index] || {};
+			const musicInfo = {
+				...res.data,
+				music: musicData.audioFileUrl || res.data.audioFileUrl,
+				accompany: musicData.metronomeUrl || res.data.metronomeUrl,
+				musicSheetId: musicData.musicSheetId || res.data.id,
+				track: musicData.track || res.data.track,
+			};
+			console.log("🚀 ~ musicInfo:", musicInfo);
+			setState(musicInfo, index);
+			setCustom();
+			detailData.isLoading = false;
+		};
+
+		const setState = (data: any, index: number) => {
+			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 = data.mp3Type === "MP3_METRONOME" ? false : true;
+			state.isShowFingering = data.showFingering ? true : false;
+			state.music = data.music;
+			state.accompany = data.accompany;
+			state.midiUrl = data.midiUrl;
+			state.parentCategoriesId = data.musicTag;
+			state.musicSheetCategoriesId = data.musicSheetCategoriesId;
+			state.playMode = data.audioType === "MP3" ? "MP3" : "MIDI";
+			state.originSpeed = state.speed = data.playSpeed;
+			state.track = data.code || data.track;
+			state.enableNotation = data.notation ? true : false;
+
+			//课堂乐器,默认简谱
+			state.musicRenderType = EnumMusicRenderType.staff;
+		};
+
+		const setCustom = () => {
+			if (state.extConfigJson.multitrack) {
+				setGlobalData("multitrack", state.extConfigJson.multitrack);
+			}
+		};
+
+		onMounted(() => {
+			(window as any).appName = "colexiu";
+			const id = query.id;
+			Promise.all([sysMusicScoreAccompanimentQueryPage(id)]).then((values) => {
+				getMusicInfo(values[0]);
+			});
+			showLoadingToast({ message: "生成中", duration: 0 });
+		});
+
+		/** 渲染完成 */
+		const handleRendered = async () => {
+			const item = detailData.product.find((item) => item.type === state.musicRenderType);
+			if (!item) return;
+			item.state = true;
+			item.base64 = await downPng();
+			const nextItem = detailData.product.find((item: any) => !item.state);
+			if (nextItem) {
+				state.musicRenderType = nextItem.type;
+				detailData.isLoading = true;
+				setTimeout(() => (detailData.isLoading = false), 500);
+				return;
+			}
+			closeToast();
+			console.log(detailData.product);
+			window.parent?.postMessage(
+				{
+					api: "webApi_renderSvg",
+					product: JSON.stringify(detailData.product),
+				},
+				"*"
+			);
+		};
+		const downPng = () => {
+			return new Promise((resolve) => {
+				setTimeout(async () => {
+					const svg: any = document.getElementById("osmdSvgPage1")?.cloneNode(true);
+					if (!svg) {
+						resolve("");
+						return;
+					}
+					const cw = svg.width.animVal.value;
+					const ch = svg.height.animVal.value;
+					const rect = document.createElementNS("http://www.w3.org/2000/svg", "rect");
+					rect.setAttribute("x", "0");
+					rect.setAttribute("y", "0");
+					rect.setAttribute("width", `${cw * 2}`);
+					rect.setAttribute("height", `${ch * 2}`);
+					rect.setAttribute("fill", "#fff");
+					svg.prepend(rect);
+					const _canvas = svg2canvas(svg.outerHTML);
+					const base64 = _canvas.toDataURL("image/png", 1);
+					resolve(base64);
+					// if (state.platform === IPlatform.PC) {
+					// 	let el: any = document.createElement("a");
+					// 	// 设置 href 为图片经过 base64 编码后的字符串,默认为 png 格式
+					// 	el.href = _canvas.toDataURL();
+					// 	el.download = state.examSongName;
+
+					// 	// 创建一个点击事件并对 a 标签进行触发
+					// 	const event = new MouseEvent("click");
+					// 	el.dispatchEvent(event);
+					// 	setTimeout(() => {
+					// 		showToast({ message: "保存成功", type: "success" });
+					// 		el = null;
+					// 	}, 300);
+					// } else {
+
+					// 	const res = await api_savePicture({
+					// 		base64,
+					// 	});
+					// 	if (res?.content?.status === "success") {
+					// 		showToast({ message: "保存成功", type: "success" });
+					// 	} else {
+					// 		showToast({ message: "保存失败", type: "fail" });
+					// 	}
+					// }
+				}, 500);
+			});
+		};
+
+		return () => (
+			<div class={styles.detail}>
+				<div id="scrollContainer" class={[styles.container, "hideCursor"]}>
+					{/* 曲谱渲染 */}
+					{!detailData.isLoading && <MusicScore showSelection={false} onRendered={handleRendered} />}
+				</div>
+			</div>
+		);
+	},
+});

+ 21 - 11
src/view/music-score/index.tsx

@@ -14,13 +14,13 @@ const musicData = reactive({
 	showSelection: false, // 可以加载点击浮层
 	isRenderLoading: true,
 	score: "",
-	containerWidth: 0
+	containerWidth: 0,
 });
 
 /** 重新计算曲谱渲染比例 */
 export const resetMusicScore = () => {
-	const contaienrWidth = document.getElementById('musicAndSelection')?.offsetWidth || 625
-	state.musicZoom = contaienrWidth / musicData.containerWidth
+	const contaienrWidth = document.getElementById("musicAndSelection")?.offsetWidth || 625;
+	state.musicZoom = contaienrWidth / musicData.containerWidth;
 };
 
 /** 重新渲染曲谱 */
@@ -36,14 +36,19 @@ export const resetRenderMusicScore = () => {
 export default defineComponent({
 	name: "music-score",
 	emits: ["rendered"],
-	setup(prop, { emit }) {
+	props: {
+		showSelection: {
+			type: Boolean,
+			default: true,
+		},
+	},
+	setup(props, { emit }) {
 		/** 设置 曲谱模式,五线谱还是简谱 */
 		const setRenderType = () => {
 			const musicRenderType: any = sessionStorage.getItem(musicRenderTypeKey);
 			if (musicRenderType in EnumMusicRenderType) {
 				state.musicRenderType = musicRenderType;
 			}
-			
 		};
 		const getXML = async () => {
 			const res = await fetch(state.xmlUrl).then((response) => response.text());
@@ -76,7 +81,8 @@ export default defineComponent({
 			osmd.EngravingRules.PageTopMarginNarrow = 3;
 			osmd.EngravingRules.PageLeftMargin = 2;
 			osmd.EngravingRules.PageBottomMargin = 2;
-			osmd.EngravingRules.DYMusicScoreType = state.musicRenderType === EnumMusicRenderType.staff ? "staff" : "jianpu";
+			osmd.EngravingRules.DYMusicScoreType =
+				state.musicRenderType === EnumMusicRenderType.staff ? "staff" : "jianpu";
 			// 如果为固定调,需要加入全局
 			if (state.musicRenderType === EnumMusicRenderType.fixedTone) {
 				(window as any).sett = {
@@ -92,11 +98,11 @@ export default defineComponent({
 		};
 		/** 获取渲染容器的宽度 */
 		const getContainerWidth = () => {
-			musicData.containerWidth = document.getElementById('musicAndSelection')?.offsetWidth || 625
+			musicData.containerWidth = document.getElementById("musicAndSelection")?.offsetWidth || 625;
 			// console.log(musicData.containerWidth)
-		}
+		};
 		onMounted(async () => {
-			getContainerWidth()
+			getContainerWidth();
 			setRenderType();
 			await getXML();
 			await init();
@@ -117,8 +123,12 @@ export default defineComponent({
 			return result;
 		});
 		return () => (
-			<div id="musicAndSelection" style={{"--music-zoom" : state.musicZoom}} class={[isInTheGradualRange.value && styles.inGradualRange]}>
-				{musicData.showSelection && <Selection />}
+			<div
+				id="musicAndSelection"
+				style={{ "--music-zoom": state.musicZoom }}
+				class={[isInTheGradualRange.value && styles.inGradualRange]}
+			>
+				{props.showSelection && musicData.showSelection && <Selection />}
 			</div>
 		);
 	},