Pārlūkot izejas kodu

Merge branch '2023-9-1_多选' into online

liushengqiang 1 gadu atpakaļ
vecāks
revīzija
0132cd4c83

+ 7 - 2
src/pc/component/upload-to-resources/index.tsx

@@ -146,8 +146,13 @@ export default defineComponent({
 			});
 		};
 		const wav2mp3 = async () => {
-			const { data } = await api_musicSheetCreationWav2mp3(props.item.filePath);
-			froms.mp3 = data;
+			try {
+				const { data } = await api_musicSheetCreationWav2mp3(props.item.filePath);
+				froms.mp3 = data;
+			} catch (error) {
+				message.error("wav转mp3失败");	
+				handleClose();
+			}
 		};
 
 		const handleClose = () => {

+ 4 - 0
src/pc/home/component/the-setting/index.tsx

@@ -99,6 +99,10 @@ export default defineComponent({
 				label: "撤回",
 				value: "Ctrl + z",
 			},
+			{
+				label: "多选",
+				value: "Shift",
+			},
 		];
 		return () => (
 			<NModal autoFocus={false} show={props.show} onUpdate:show={(val) => emit("update:show", val)}>

+ 151 - 56
src/pc/home/index.tsx

@@ -188,6 +188,11 @@ export default defineComponent({
 			uploadShow: false, // 上传弹窗
 			item: {} as any, // 上传数据
 			uploadClick: false, // 上传点击
+
+			/** 多选 */
+			multiSelect: false,
+			multiSelectList: [] as any[],
+			multilList: [] as any[],
 		});
 		const noteTypes = ABC_DATA.types.map((item) => item.value).filter(Boolean);
 		const accidentals = ABC_DATA.accidentals.map((item) => item.value).filter(Boolean);
@@ -200,16 +205,16 @@ export default defineComponent({
 		const barTypes = ABC_DATA.bar.map((item) => item.value).filter(Boolean);
 		console.log("🚀 ~ noteTypes:", noteTypes, accidentals, clefs, playTypes, dynamics);
 		const setNoteColor = () => {
-			const gs = document.querySelectorAll(`#paper svg g[fill="#0f81ff"]`);
-			Array.from(gs).forEach((g) => {
-				g.classList.remove("note_selected");
-				g.setAttribute('fill', 'currentColor')
-			})
+			// const gs = document.querySelectorAll(`#paper svg g[fill="#0f81ff"]`);
+			// Array.from(gs).forEach((g) => {
+			// 	g.classList.remove("note_selected");
+			// 	g.setAttribute("fill", "currentColor");
+			// });
 			const gs1 = document.querySelectorAll(`#paper svg g.note_selected`);
 			Array.from(gs1).forEach((g) => {
 				g.classList.remove("note_selected");
-			})
-		}
+			});
+		};
 		/** 点击音符 */
 		const clickListener = (
 			abcElem: AbcElem,
@@ -228,10 +233,10 @@ export default defineComponent({
 				noteIndex: indexStr[1],
 				isFirstChecked: true,
 			};
-			if (abcElem){
-				if (abcElem.startChar && abcElem.endChar){
+			if (abcElem) {
+				if (abcElem.startChar && abcElem.endChar) {
 					abcData.visualObj.engraver.rangeHighlight(abcElem.startChar, abcElem.endChar);
-					abcElem?.abselem?.elemset?.[0]?.classList?.add('note_selected')
+					abcElem?.abselem?.elemset?.[0]?.classList?.add("note_selected");
 				}
 			}
 
@@ -250,6 +255,30 @@ export default defineComponent({
 			}
 			data.active = active;
 
+			if (data.multiSelect) {
+				if (data.multiSelectList.length === 0) {
+					data.multiSelectList.push(active);
+				}
+				if (data.multiSelectList.length > 0) {
+					data.multilList = [];
+					if (data.multiSelectList[0].startChar > active.startChar) {
+						const start = data.multiSelectList[1] || data.multiSelectList[0];
+						data.multiSelectList = [cleanDeep(start), cleanDeep(active)];
+					} else {
+						data.multiSelectList = [cleanDeep(data.multiSelectList[0]), cleanDeep(active)];
+					}
+					console.log(data.multiSelectList[0].startChar, data.multiSelectList[1].startChar);
+					data.multiSelectList = data.multiSelectList.sort((a, b) => a.startChar - b.startChar);
+					data.multilList = getmutilList();
+					handleChange({ type: "multiSelect", value: "" });
+					return;
+				}
+			} else {
+				if (data.multiSelectList.length || data.multilList.length) {
+					handleClearMultiSelect();
+				}
+			}
+
 			console.log(
 				"🚀 ~ abcElem:",
 				abcElem,
@@ -274,6 +303,37 @@ export default defineComponent({
 			ABCJS.synth.playEvent(abcElem.midiPitches, abcElem.midiGraceNotePitches, 1000);
 		};
 
+		const getmutilList = () => {
+			const start = data.multiSelectList[0];
+			const end = data.multiSelectList[1];
+			const list = [] as any[];
+			// console.log("🚀 ~ start:", start.noteIndex, end.noteIndex);
+			for (let i = start.measureIndex; i < end.measureIndex + 1; i++) {
+				const measure = abcData.abc.measures[i];
+				for (let j = 0; j < measure.notes.length; j++) {
+					const abcElem = useIndexGetNote(`${i}.${j}`);
+					const active = {
+						...cloneDeep(abcElem),
+						measureIndex: i,
+						noteIndex: j,
+					};
+					if (start.measureIndex != end.measureIndex) {
+						if (start.measureIndex === i) {
+							j >= start.noteIndex && list.push(active);
+						} else if (i === end.measureIndex) {
+							j <= end.noteIndex && list.push(active);
+						} else {
+							list.push(active);
+						}
+					} else {
+						j >= start.noteIndex && j <= end.noteIndex && list.push(active);
+					}
+				}
+			}
+			// console.log(list);
+			return list;
+		};
+
 		const textAreaRef = ref();
 		const abcData = reactive({
 			visualObj: null as any,
@@ -669,7 +729,8 @@ export default defineComponent({
 			// console.log(data.active.endChar, abcData.visualObj.getElementFromChar(data.active.startChar));
 			const abcElem: AbcElem = abcData.visualObj.getElementFromChar(startChar);
 			if (abcElem) {
-				abcData.visualObj.engraver.rangeHighlight(abcElem.startChar, abcElem.endChar);
+				// abcData.visualObj.engraver.rangeHighlight(abcElem.startChar, abcElem.endChar);
+				abcElem?.abselem?.elemset?.[0]?.classList?.add("note_selected");
 			}
 			return abcElem;
 		};
@@ -777,7 +838,12 @@ export default defineComponent({
 			const value = params.value;
 			const activeNote =
 				abcData.abc.measures[data.active?.measureIndex]?.notes[data.active?.noteIndex] || null;
-
+			if (type === "multiSelect") {
+				data.multilList.forEach((item: any) => {
+					item?.abselem?.elemset?.[0]?.classList?.add("note_selected");
+				});
+				return;
+			}
 			if (type === "exit") {
 				if (!data.isSave) {
 					clearTimeout(saveTimer);
@@ -977,6 +1043,7 @@ export default defineComponent({
 						abcData.abc.key = value;
 						abcData.abc.visualTranspose = 0;
 						abcData.abc.visualKey = "K:C";
+						abcData.abc.visualKey = value;
 						await handleResetRender();
 					} else {
 						if (!activeNote) return;
@@ -988,6 +1055,7 @@ export default defineComponent({
 					abcData.abc.key = value;
 					abcData.abc.visualTranspose = 0;
 					abcData.abc.visualKey = "K:C";
+					abcData.abc.visualKey = value;
 					await handleResetRender();
 				}
 			}
@@ -1186,6 +1254,22 @@ export default defineComponent({
 			// 移动音符
 			if (type === "move") {
 				const step = value.action === "drag" ? value.step : value.action === "up" ? -1 : 1;
+				if (data.multilList.length) {
+					for (let i = 0; i < data.multilList.length; i++) {
+						const item = data.multilList[i];
+						const note = abcData.abc.measures[item.measureIndex].notes[item.noteIndex];
+						note.content = moveNote(note.content, step);
+					}
+					await handleResetRender();
+					for (let i = 0; i < data.multilList.length; i++) {
+						const item = data.multilList[i];
+						const abcElem = useIndexGetNote(`${item.measureIndex}.${item.noteIndex}`);
+						abcElem?.abselem?.elemset?.[0]?.classList?.add("note_selected");
+						if (!abcElem?.midiPitches) return;
+						ABCJS.synth.playEvent(abcElem.midiPitches, abcElem.midiGraceNotePitches, 1000);
+					}
+					return;
+				}
 				if (!activeNote) return;
 				activeNote.content = moveNote(activeNote.content, step);
 				// arr now contains elements that are either a chord, a decoration, a note name, or anything else. It can be put back to its original string with .join("").
@@ -1198,20 +1282,49 @@ export default defineComponent({
 
 			// 删除音符
 			if (type === "delete") {
-				if (!data.active) return;
-				if (data.active.startChar === 0) return;
-				abcData.abc.measures[data.active.measureIndex].notes.splice(data.active.noteIndex, 1);
-				if (abcData.abc.measures[data.active.measureIndex].notes.length === 0) {
-					abcData.abc.measures.splice(data.active.measureIndex, 1);
+				if (data.multilList.length) {
+					for (let i = 0; i < data.multilList.length; i++) {
+						const item = data.multilList[i];
+						abcData.abc.measures[item.measureIndex].notes[item.noteIndex].is_delete = true;
+					}
+					for (let i = 0; i < abcData.abc.measures.length; i++) {
+						abcData.abc.measures[i].notes = abcData.abc.measures[i].notes.filter(
+							(n) => n.is_delete !== true
+						);
+					}
+					for (let i = 0; i < abcData.abc.measures.length; i++) {
+						if (!abcData.abc.measures[i].notes.length) {
+							abcData.abc.measures[i].notes.push(
+								createNote({
+									content: "z",
+									noteType: "4",
+								})
+							);
+						}
+					}
+				} else {
+					if (!data.active) return;
+					if (data.active.startChar === 0) return;
+					abcData.abc.measures[data.active.measureIndex].notes.splice(data.active.noteIndex, 1);
+					if (abcData.abc.measures[data.active.measureIndex].notes.length === 0) {
+						abcData.abc.measures.splice(data.active.measureIndex, 1);
+					}
 				}
 				await handleResetRender();
 				data.active = null as unknown as INoteActive;
 			}
+			handleClearMultiSelect();
+		};
+		const handleClearMultiSelect = async () => {
+			data.multilList = [];
+			data.multiSelectList = [];
+			data.multiSelect = false;
 		};
 
 		const getNextNote = (index: number): AbcElem => {
 			const abcElem = abcData.visualObj.getElementFromChar(index);
-			if (abcElem.el_type === "note") {
+			// console.log("🚀 ~ abcElem:", index);
+			if (abcElem?.el_type === "note") {
 				return abcElem;
 			} else {
 				return getNextNote(abcElem.endChar);
@@ -1288,38 +1401,11 @@ export default defineComponent({
 
 		/** 移调 */
 		const handleMoveKey = async (item: (typeof ABC_DATA.key)[0]) => {
-			// const moveData = getKeyStep(item.value, abcData.abc.key, data.moveKeyType);
-			// console.log("🚀 ~ item:", abcData.abc.key, "=>", item.value, moveData);
-			// 将所有的音符移调
-			// for (let i = 0; i < abcData.abc.measures.length; i++) {
-			// 	const measure = abcData.abc.measures[i];
-			// 	for (let j = 0; j < measure.notes.length; j++) {
-			// 		const note = measure.notes[j];
-			// 		if (note.content == "z") continue;
-			// 		const content = moveNoteKey(note.content, moveData);
-			// 		const _a = content.substring(0, 1);
-			// 		if (_a === "^" || _a === "_") {
-			// 			note.content = content.substring(1);
-			// 		} else {
-			// 			note.content = content;
-			// 		}
-			// 		console.log("🚀 ~ note.content:", note.content);
-			// 	}
-			// }
-			// // console.log(abcData.abc.visualTranspose, item.step, item.value)
-			// abcData.abc.key = item.value;
-			// const step =
-			// 	data.moveKeyType === "up"
-			// 		? item.step > 0
-			// 			? item.step
-			// 			: item.step + 12
-			// 		: data.moveKeyType === "down"
-			// 		? item.step < 0
-			// 			? item.step
-			// 			: item.step + 12
-			// 		: item.step;
 			console.log(item);
-			abcData.abc.visualTranspose = item.step;
+			const moveData = getKeyStep(item.value, abcData.abc.key, data.moveKeyType);
+			console.log("🚀 ~ item:", abcData.abc.key, "=>", item.value, moveData);
+			(window as any).visual_Key = item.value.split(":")[1];
+			abcData.abc.visualTranspose = moveData.step;
 			abcData.abc.visualKey = item.value;
 			popup.moveKeyShow = false;
 			if (data.playState) {
@@ -1350,11 +1436,22 @@ export default defineComponent({
 					});
 				}
 			}
+
+			if (e.key.toLocaleLowerCase() === "shift") {
+				if (!data.multiSelect && data.active?.el_type === "note") {
+					console.log("shift 按下");
+					data.multiSelectList = [cleanDeep(data.active)];
+				}
+				data.multiSelect = true;
+			}
 		};
 
 		const handleKeyUp = (e: KeyboardEvent) => {
 			if ((e.target as HTMLElement).nodeName === "INPUT") return;
-			console.log(e.key);
+			if (e.key.toLocaleLowerCase() === "shift") {
+				console.log("shift 抬起");
+				data.multiSelect = false;
+			}
 
 			if (e.key === "Control" || e.key === "Meta") {
 				keyDownData.control = false;
@@ -1838,10 +1935,10 @@ export default defineComponent({
 					data.item = { ...res.data, visualObj: abcData.visualObj };
 					data.uploadShow = true;
 				} else {
-					message.info('已是最新版本')
+					message.info("已是最新版本");
 				}
 			}
-		};	
+		};
 
 		return () => (
 			<>
@@ -2656,6 +2753,7 @@ export default defineComponent({
 						</div>
 
 						<div class={styles.box}>
+							{/* <NButton type={data.multiSelect ? "primary" : "default"}>多选</NButton> */}
 							<div class={styles.titleBox}>
 								<div class={styles.titleName} style={{ width: "50%", margin: "0 auto" }}>
 									<NInput
@@ -2699,10 +2797,7 @@ export default defineComponent({
 								<NSpin description="资源加载中..."></NSpin>
 							</div>
 						)}
-						{data.saveLoadingText && (
-							<div class={styles.loading}>
-							</div>
-						)}
+						{data.saveLoadingText && <div class={styles.loading}></div>}
 					</div>
 					<div ref={downRef}></div>
 

+ 14 - 1
src/pc/home/noteData.ts

@@ -247,7 +247,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 9, down: -3, move: 0 },
 		"K:Bb": { up: 10, down: -2, move: 1 },
 		"K:B": { up: 11, down: -1, move: 0 },
-		"K:C": { up: 0, down: 0, move: 0 },
+		"K:Cb": { up: 0, down: 0, move: 0 },
 	},
 	"K:C#": {
 		"K:D": { up: 1, down: -11, move: 0 },
@@ -261,6 +261,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 8, down: -4, move: 0 },
 		"K:Bb": { up: 9, down: -3, move: 1 },
 		"K:B": { up: 10, down: -2, move: 0 },
+		"K:Cb": { up: 10, down: -2, move: 0 },
 		"K:C": { up: 11, down: -1, move: 1 },
 		"K:C#": { up: 0, down: 0, move: 0 },
 		"K:Db": { up: 0, down: 0, move: 0 },
@@ -277,6 +278,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 8, down: -4, move: 0 },
 		"K:Bb": { up: 9, down: -3, move: 1 },
 		"K:B": { up: 10, down: -2, move: 0 },
+		"K:Cb": { up: 10, down: -2, move: 0 },
 		"K:C": { up: 11, down: -1, move: 1 },
 		"K:C#": { up: 0, down: 0, move: 0 },
 		"K:Db": { up: 0, down: 0, move: 1 },
@@ -292,6 +294,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 7, down: -5, move: 1 },
 		"K:Bb": { up: 8, down: -4, move: 0 },
 		"K:B": { up: 9, down: -3, move: 1 },
+		"K:Cb": { up: 9, down: -3, move: 1 },
 		"K:C": { up: 10, down: -2, move: 0 },
 		"K:C#": { up: 11, down: -1, move: 1 },
 		"K:Db": { up: 11, down: -1, move: 0 },
@@ -307,6 +310,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 6, down: -6, move: 0 },
 		"K:Bb": { up: 7, down: -5, move: 1 },
 		"K:B": { up: 8, down: -4, move: 0 },
+		"K:Cb": { up: 8, down: -4, move: 0 },
 		"K:C": { up: 9, down: -3, move: 1 },
 		"K:C#": { up: 10, down: -2, move: 0 },
 		"K:Db": { up: 10, down: -2, move: 1 },
@@ -322,6 +326,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 5, down: -7, move: 1 },
 		"K:Bb": { up: 6, down: -6, move: 0 },
 		"K:B": { up: 7, down: -5, move: 1 },
+		"K:Cb": { up: 7, down: -5, move: 1 },
 		"K:C": { up: 8, down: -4, move: 0 },
 		"K:C#": { up: 9, down: -3, move: 1 },
 		"K:Db": { up: 9, down: -3, move: 0 },
@@ -337,6 +342,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 4, down: -8, move: 0 },
 		"K:Bb": { up: 5, down: -7, move: 1 },
 		"K:B": { up: 6, down: -6, move: 0 },
+		"K:Cb": { up: 6, down: -6, move: 0 },
 		"K:C": { up: 7, down: -5, move: 1 },
 		"K:C#": { up: 8, down: -4, move: 0 },
 		"K:Db": { up: 8, down: -4, move: 1 },
@@ -351,6 +357,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 3, down: -9, move: 0 },
 		"K:Bb": { up: 4, down: -8, move: 1 },
 		"K:B": { up: 5, down: -7, move: 0 },
+		"K:Cb": { up: 5, down: -7, move: 0 },
 		"K:C": { up: 6, down: -6, move: 1 },
 		"K:C#": { up: 7, down: -5, move: 0 },
 		"K:Db": { up: 7, down: -5, move: 1 },
@@ -367,6 +374,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 3, down: -9, move: 0 },
 		"K:Bb": { up: 4, down: -8, move: 1 },
 		"K:B": { up: 5, down: -7, move: 0 },
+		"K:Cb": { up: 5, down: -7, move: 0 },
 		"K:C": { up: 6, down: -6, move: 1 },
 		"K:C#": { up: 7, down: -5, move: 0 },
 		"K:Db": { up: 7, down: -5, move: 1 },
@@ -382,6 +390,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 2, down: -10, move: 1 },
 		"K:Bb": { up: 3, down: -9, move: 0 },
 		"K:B": { up: 4, down: -8, move: 1 },
+		"K:Cb": { up: 4, down: -8, move: 1 },
 		"K:C": { up: 5, down: -7, move: 0 },
 		"K:C#": { up: 6, down: -6, move: 1 },
 		"K:Db": { up: 6, down: -6, move: 0 },
@@ -397,6 +406,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 1, down: -11, move: 0 },
 		"K:Bb": { up: 2, down: -10, move: 1 },
 		"K:B": { up: 3, down: -9, move: 0 },
+		"K:Cb": { up: 3, down: -9, move: 0 },
 		"K:C": { up: 4, down: -8, move: 1 },
 		"K:C#": { up: 5, down: -7, move: 0 },
 		"K:Db": { up: 5, down: -7, move: 1 },
@@ -412,6 +422,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 	"K:A": {
 		"K:Bb": { up: 1, down: -11, move: 0 },
 		"K:B": { up: 2, down: -10, move: 1 },
+		"K:Cb": { up: 2, down: -10, move: 1 },
 		"K:C": { up: 3, down: -9, move: 0 },
 		"K:C#": { up: 4, down: -8, move: 1 },
 		"K:Db": { up: 4, down: -8, move: 0 },
@@ -427,6 +438,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 	},
 	"K:Bb": {
 		"K:B": { up: 1, down: -11, move: 0 },
+		"K:Cb": { up: 1, down: -11, move: 0 },
 		"K:C": { up: 2, down: -10, move: 1 },
 		"K:C#": { up: 3, down: -9, move: 0 },
 		"K:Db": { up: 3, down: -9, move: 1 },
@@ -456,6 +468,7 @@ export const ABC_KEYS: { [_: string]: any } = {
 		"K:A": { up: 10, down: -2, move: 1 },
 		"K:Bb": { up: 11, down: -1, move: 0 },
 		"K:B": { up: 0, down: 0, move: 0 },
+		"K:Cb": { up: 0, down: 0, move: 0 },
 	},
 };
 

+ 2 - 2
src/pc/home/runtime.ts

@@ -34,13 +34,13 @@ export const ABC_DATA = {
 	],
 	/** 调号 */
 	key: [
+		{ name: "C大调", value: "K:C", step: 0, icon: "icon-a-diaohao-cdadiaoaxiaodiao1" },
 		{ name: "F#大调", value: "K:F#", step: 6, icon: "icon-a-diaohao-fdadiaodxiaodiao" },
 		{ name: "F大调", value: "K:F", step: 5, icon: "icon-a-diaohao-fdadiaodxiaodiao1" },
 		{ name: "E大调", value: "K:E", step: 4, icon: "icon-a-diaohao-edadiaocxiaodiao" },
 		{ name: "Eb大调", value: "K:Eb", step: 3, icon: "icon-a-diaohao-ebdadiaocxiaodiao" },
 		{ name: "D大调", value: "K:D", step: 2, icon: "icon-a-diaohao-Ddaxiaoexiaodiao" },
 		{ name: "C#大调", value: "K:C#", step: 1, icon: "icon-a-diaohao-cdadiaoaxiaodiao" },
-		{ name: "C大调", value: "K:C", step: 0, icon: "icon-a-diaohao-cdadiaoaxiaodiao1" },
 		{ name: "B大调", value: "K:B", step: -1, icon: "icon-a-diaohao-bdadiaogxiaodiao" },
 		{ name: "Cb大调", value: "K:Cb", step: -1, icon: "icon-a-diaohao-cbdadiaoabxiaodiao" },
 		{ name: "Db大调", value: "K:Db", step: -1, icon: "icon-a-diaohao-dbdadiaobbxiaodiao" },
@@ -220,7 +220,7 @@ export const renderMeasures = (abc: IAbc, option?: IRenderMeasuresOption) => {
 		
 		text += "\n";
 	}
-	text += "V:1 style=jianpu" + "\n";
+	// text += "V:1 style=jianpu" + "\n";
 
 	const measures = abc.measures;
 	for (let i = 0; i < measures.length; i++) {

+ 1 - 0
src/pc/types.ts

@@ -31,6 +31,7 @@ export interface INote {
 	tieline: string
 	/** 分割 */
 	segno: string
+	is_delete?: boolean
 }
 export interface IMeasure {
 	/** 小节号 */