Bladeren bron

Merge branch 'iteration-20250313' into online

lex-xin 4 maanden geleden
bovenliggende
commit
ae2b9f861b
1 gewijzigde bestanden met toevoegingen van 147 en 52 verwijderingen
  1. 147 52
      src/pc/home/index.tsx

+ 147 - 52
src/pc/home/index.tsx

@@ -625,49 +625,112 @@ export default defineComponent({
     };
 
     /** 生成曲谱节拍器数据 */
-    const productMetronomeData = () => {
+    const productMetronomeData = async () => {
       const times = new ABCJS.TimingCallbacks(abcData.visualObj);
       data.times = times.noteTimings;
       const list: any[] = [];
       let meter = abcData.abc.meter || "";
-      // length - 1是为了去除最后一个空的结束事件
-      for (let i = 0; i < times.noteTimings.length - 1; i++) {
-        const timeNote = times.noteTimings[i];
-        const abcNote = getNextNote(timeNote.startChar as number);
-        let indexStr: any = abcNote.chord?.find((n) => n.position === "left")?.name || "";
-        indexStr = indexStr.split(".").map((n: string) => Number(n));
-        if (indexStr.length === 2) {
-          const measure = abcData.abc.measures[indexStr[0]];
-          // 如果小节里面有拍号,后面一直延用这个拍号,以此类推, ps: 下个版本
-          // if (measure.meter){
-          // 	meter = measure.meter;
-          // }
-          const reg = new RegExp(/M:(\d+)\/\d+/);
-          const numerator = Number(meter.match(reg)?.[1]);
-          // console.log("🚀 ~ reg:", meter.match(reg)?.[1], abcData.abc.meter)
-          // console.log("🚀 ~ measure:", measure)
-          const note = measure.notes[indexStr[1]];
-          list.push({
-            ...note,
-            timeNote,
-            abcNote,
-            measure: {
-              numerator,
-            },
-          });
-        }
-      }
-      // console.log("abcData.abc.measures", list);
-      if (!metronomeData.metro) {
-        metronomeData.metro = new Metronome();
-      }
-      try {
-        metronomeData.activeIndex = -1;
-        metronomeData.metro.init(list);
-      } catch (error) {
-        console.log("🚀 ~ 生成节拍器数据错误:", error);
-      }
+
+      // 分帧计算:每帧处理 100 条数据(可根据性能调整)
+      const chunkSize = 5;
+      const totalItems = times.noteTimings.length - 1; // 去掉最后一个空事件
+      let currentIndex = 0;
+
+      // 使用 Promise 包装,方便 await 等待计算完成
+      await new Promise<void>((resolve) => {
+        const processChunk = () => {
+          const endIndex = Math.min(currentIndex + chunkSize, totalItems);
+
+          // 处理当前 chunk 的数据
+          for (let i = currentIndex; i < endIndex; i++) {
+            const timeNote = times.noteTimings[i];
+            const abcNote = getNextNote(timeNote.startChar as number);
+            let indexStr: any = abcNote.chord?.find((n) => n.position === "left")?.name || "";
+            indexStr = indexStr.split(".").map((n: string) => Number(n));
+
+            if (indexStr.length === 2) {
+              const measure = abcData.abc.measures[indexStr[0]];
+              const reg = new RegExp(/M:(\d+)\/\d+/);
+              const numerator = Number(meter.match(reg)?.[1]);
+              const note = measure.notes[indexStr[1]];
+              list.push({
+                ...note,
+                timeNote,
+                abcNote,
+                measure: {
+                  numerator,
+                },
+              });
+            }
+          }
+
+          currentIndex = endIndex;
+
+          // 如果还有数据,继续下一帧处理
+          if (currentIndex < totalItems) {
+            requestAnimationFrame(processChunk);
+          } else {
+            // 所有数据处理完成,初始化 Metronome
+            if (!metronomeData.metro) {
+              metronomeData.metro = new Metronome();
+            }
+            try {
+              metronomeData.activeIndex = -1;
+              metronomeData.metro.init(list);
+            } catch (error) {
+              console.log("🚀 ~ 生成节拍器数据错误:", error);
+            }
+            resolve(); // 完成 Promise
+          }
+        };
+
+        // 开始处理
+        requestAnimationFrame(processChunk);
+      });
     };
+    // const productMetronomeData = () => {
+    //   const times = new ABCJS.TimingCallbacks(abcData.visualObj);
+    //   data.times = times.noteTimings;
+    //   const list: any[] = [];
+    //   let meter = abcData.abc.meter || "";
+    //   // length - 1是为了去除最后一个空的结束事件
+    //   for (let i = 0; i < times.noteTimings.length - 1; i++) {
+    //     const timeNote = times.noteTimings[i];
+    //     const abcNote = getNextNote(timeNote.startChar as number);
+    //     let indexStr: any = abcNote.chord?.find((n) => n.position === "left")?.name || "";
+    //     indexStr = indexStr.split(".").map((n: string) => Number(n));
+    //     if (indexStr.length === 2) {
+    //       const measure = abcData.abc.measures[indexStr[0]];
+    //       // 如果小节里面有拍号,后面一直延用这个拍号,以此类推, ps: 下个版本
+    //       // if (measure.meter){
+    //       // 	meter = measure.meter;
+    //       // }
+    //       const reg = new RegExp(/M:(\d+)\/\d+/);
+    //       const numerator = Number(meter.match(reg)?.[1]);
+    //       // console.log("🚀 ~ reg:", meter.match(reg)?.[1], abcData.abc.meter)
+    //       // console.log("🚀 ~ measure:", measure)
+    //       const note = measure.notes[indexStr[1]];
+    //       list.push({
+    //         ...note,
+    //         timeNote,
+    //         abcNote,
+    //         measure: {
+    //           numerator,
+    //         },
+    //       });
+    //     }
+    //   }
+    //   // console.log("abcData.abc.measures", list);
+    //   if (!metronomeData.metro) {
+    //     metronomeData.metro = new Metronome();
+    //   }
+    //   try {
+    //     metronomeData.activeIndex = -1;
+    //     metronomeData.metro.init(list);
+    //   } catch (error) {
+    //     console.log("🚀 ~ 生成节拍器数据错误:", error);
+    //   }
+    // };
 
     // 高亮选中的音符
     const rangeHighlight = (startChar: number) => {
@@ -726,7 +789,15 @@ export default defineComponent({
     const handleClickExit = async () => {
       if (data.saveLoading) return;
       const msg = message.loading("保存中...", { duration: 0 });
-      await handleSaveMusic(false);
+      const result = await handleSaveMusic(false);
+      if(result === 'noName') {
+        msg.destroy();
+
+        message.destroyAll();
+        message.error("请输入曲谱名称");
+        return;
+      };
+      console.log(result, "result")
       setTimeout(async () => {
         msg.type = "success";
         msg.content = "保存成功";
@@ -1535,7 +1606,7 @@ export default defineComponent({
           message.destroyAll();
           message.error("请输入曲谱名称");
         }
-        return
+        return 'noName';
       }
       if (musicLock) return;
       musicLock = true;
@@ -1761,6 +1832,7 @@ export default defineComponent({
         rect.setAttribute("fill", "#fff");
         svg.prepend(rect);
         if (svg) {
+          console.log(svg.outerHTML, 'svg.outerHTML')
           const _canvas = svg2canvas(svg.outerHTML);
           if (isUrl) {
             // document.body.appendChild(_canvas);
@@ -1774,8 +1846,13 @@ export default defineComponent({
             el.dispatchEvent(event);
           } else {
             _canvas.toBlob(async (blob) => {
-              const pngUrl = await api_uploadFile(blob, data.musicId + ".png");
-              resolve(pngUrl);
+              if(blob) {
+                const pngUrl = await api_uploadFile(blob, data.musicId + ".png");
+                resolve(pngUrl);
+              } else {
+                // reject('bolb is null')
+                resolve('')
+              }
             }, "image/png");
           }
         }
@@ -1832,7 +1909,14 @@ export default defineComponent({
 
     const downXML = async () => {
       const msg = message.loading("导出中...");
-      await handleSaveMusic(false);
+      const result = await handleSaveMusic(false);
+      if(result === 'noName') {
+        msg.destroy();
+
+        message.destroyAll();
+        message.error("请输入曲谱名称");
+        return;
+      };
       const res = await getDetailData();
       if (!res?.data?.xml) {
         msg.type = "error";
@@ -1882,6 +1966,13 @@ export default defineComponent({
 
         const file = e.target.files[0];
         if (val === "xml") {
+          const size = file.size || 0
+          const isLt2M = size / 1024 / 1024 < 3;
+          if (!isLt2M) {
+            message.error(`文件大小不能超过3M`);
+            data.loadingAudioSrouce2 = false;
+            return;
+          }
           const reader = new FileReader();
           reader.onload = async (e: any) => {
             // let abc = e.target.result;
@@ -1994,6 +2085,7 @@ export default defineComponent({
         let abc = reuslt;
         abc = new DOMParser().parseFromString(abc, "text/xml");
         // // console.log("🚀 ~ abc:", abc);
+
         abc = (window as any).vertaal(abc, { p: "f", t: 1, u: 0, v: 3, mnum: 0 });
         // console.log('abc', abc);
         const parseData = ABCJS.renderAbc("importRef", abc[0], { responsive: "resize" });
@@ -2008,14 +2100,16 @@ export default defineComponent({
 
     // 取消
     const onCancelExport = async () => {
-      data = Object.assign(data, importTemp.value.data);
-      abcData = Object.assign(abcData, importTemp.value.abcData);
-      clearInterval(importTemp.value.timer);
-      // 判断是否有编号,有则取消
-      if (importTemp.value.importFileId) {
-        await api_musicalScoreConversionRecordRemove(importTemp.value.importFileId);
-      }
-      data.loadingAudioSrouce2 = false;
+      requestAnimationFrame(async () => {
+        data = Object.assign(data, importTemp.value.data);
+        abcData = Object.assign(abcData, importTemp.value.abcData);
+        clearInterval(importTemp.value.timer);
+        // 判断是否有编号,有则取消
+        if (importTemp.value.importFileId) {
+          await api_musicalScoreConversionRecordRemove(importTemp.value.importFileId);
+        }
+        data.loadingAudioSrouce2 = false;
+      })
     };
 
     /** 设置选段小节 */
@@ -2057,7 +2151,8 @@ export default defineComponent({
       const query = getQuery();
       // 判断是否有id,如果没有则先保存
       if (!query.id) {
-        await handleSaveMusic(true);
+        const result = await handleSaveMusic(true);
+        if(result === 'noName') return
       }
       const query2 = getQuery();
       const res = await api_musicSheetCreationDetail(query2.id);