Browse Source

Merge branch 'feature-tianyong' into gym-test

TIANYONG 2 months ago
parent
commit
1a42588a2a

+ 2 - 8
src/helpers/calcSpeed.ts

@@ -43,12 +43,6 @@ export const speedInfo: { [key in string]: number } = {
 	faster: 1.333333333,
 	"molto allargando": 1.333333333,
 	stringendo: 0.8,
-	"poco a poco rit.": 1.333333333,
-	"rit. poco a poco": 1.333333333,
-	"Ritardando": 1.333333333,
-	"Ritenuto": 1.333333333,
-	"accelerate": 0.8,
-	"poco a poco accel.": 0.8,
 };
 
 /**
@@ -123,9 +117,9 @@ export type GradualItem = {
  */
 export const getGradualLengthByXml = (xml: string) => {
 	const firstPartXml = onlyVisible(xml, 0, 'calc')
-	console.time('解析xml 耗时2')
+	//console.time('解析xml 耗时2')
 	const xmlParse = new DOMParser().parseFromString(firstPartXml, "text/xml");
-	console.timeEnd('解析xml 耗时2')
+	//console.timeEnd('解析xml 耗时2')
 	const measures = Array.from(xmlParse.querySelectorAll("measure"));
 	const notes = Array.from(xmlParse.querySelectorAll("note"));
 	const words = Array.from(xmlParse.querySelectorAll("words"));

+ 18 - 11
src/helpers/formateMusic.ts

@@ -15,6 +15,7 @@ import {
 } from "/osmd-extended/src";
 import { GradualChange, speedInfo } from "./calcSpeed";
 import { beatUnitTo, speedBeatTo } from "/src/helpers/beatConfig"
+import { xmlDocRef } from "/src/view/music-score"
 
 const browserInfo = browser();
 dayjs.extend(duration);
@@ -251,10 +252,11 @@ export const getCustomInfo = (xml: string): CustomInfo => {
 		showSpeed: true,
 		parsedXML: xml,
 	};
-	console.time('解析xml 耗时3')
-	const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
-	console.timeEnd('解析xml 耗时3')
-	const words: any = xmlParse.getElementsByTagName("words");
+	//console.time('解析xml 耗时3')
+	// const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
+	const xmlParse = xmlDocRef.value ? xmlDocRef.value : new DOMParser().parseFromString(xml, "text/xml");
+	//console.timeEnd('解析xml 耗时3')
+	const words: any = xmlParse?.getElementsByTagName("words");
 	for (const word of words) {
 		if (word && word.textContent?.trim() === "隐藏速度") {
 			data.showSpeed = false;
@@ -363,9 +365,10 @@ export const onlyVisible = (xml: string, partIndex: number, resourceType?: strin
 	if (!xml) return "";
 	// console.log('原始xml')
 	const detailId = state.examSongId + "";
-	console.time('解析xml 耗时4')
-	const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
-	console.timeEnd('解析xml 耗时4')
+	//console.time('解析xml 耗时4')
+	// const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
+	const xmlParse = xmlDocRef.value ? xmlDocRef.value : new DOMParser().parseFromString(xml, "text/xml");
+	//console.timeEnd('解析xml 耗时4')
 	const partList = xmlParse.getElementsByTagName("part-list")?.[0]?.getElementsByTagName("score-part") || [];
 	const partListNames = Array.from(partList).map((item) => item.getElementsByTagName("part-name")?.[0]?.textContent?.trim() || "");
 	const parts: any = xmlParse.getElementsByTagName("part");
@@ -379,7 +382,7 @@ export const onlyVisible = (xml: string, partIndex: number, resourceType?: strin
 	/** 第一分谱如果是约定的配置分谱则跳过 */
 	if (partListNames[0]?.toLocaleUpperCase?.() === "COMMON") {
 		partIndex++;
-		//partListNames.shift();
+		partListNames.shift();
 	}
 	const visiblePartInfo = partList[partIndex];
 	// console.log(visiblePartInfo, partIndex)
@@ -528,6 +531,7 @@ export const onlyVisible = (xml: string, partIndex: number, resourceType?: strin
 		});
 	}
 	// console.log(xmlParse)
+	
 	return new XMLSerializer().serializeToString(appoggianceFormate(xmlParse));
 };
 
@@ -646,6 +650,7 @@ export const xmlAddPartName = (xml: string) => {
 			scorePart.getElementsByTagName("part-name")[0].textContent = scorePart.getAttribute("id") || "";
 		}
 	}
+	xmlDocRef.value = xmlParse;
 	return new XMLSerializer().serializeToString(xmlParse);
 }
 
@@ -654,9 +659,10 @@ export const xmlAddPartName = (xml: string) => {
  */
 export const formatXML = (xml: string, xmlUrl?: string): string => {
 	if (!xml) return "";
-	console.time('解析xml 耗时7')
-	const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
-	console.timeEnd('解析xml 耗时7')
+	//console.time('解析xml 耗时7')
+	// const xmlParse = new DOMParser().parseFromString(xml, "text/xml");
+	const xmlParse = xmlDocRef.value ? xmlDocRef.value : new DOMParser().parseFromString(xml, "text/xml");
+	//console.timeEnd('解析xml 耗时7')
 	// 声调
 	const fifths = xmlParse.getElementsByTagName("fifths");
 	if (fifths && fifths.length) {
@@ -812,6 +818,7 @@ export const formatXML = (xml: string, xmlUrl?: string): string => {
 			transferJianNote(measure, divisions, preBeats, preBeatType)
 		}
 	}
+	xmlDocRef.value = xmlParse;
 	return new XMLSerializer().serializeToString(xmlParse);
 };
 

+ 33 - 32
src/page-instrument/App.tsx

@@ -8,6 +8,7 @@ import { studentQueryUserInfo } from "./api";
 import { api_cloudLoading, api_getToken } from "../helpers/communication";
 import { showToast } from "vant";
 import state from "/src/state"
+import { values } from "lodash";
 
 export default defineComponent({
   name: "App",
@@ -143,38 +144,38 @@ export default defineComponent({
         *重定向次数:performance.navigation.redirectCount
         *重定向耗时: redirectEnd - redirectStart
        */
-        window.onload = function() {
-          console.log('加载完成')
-          let timing: any = performance.getEntriesByType('navigation')[0];
-          const { domainLookupEnd, domainLookupStart, connectEnd, connectStart, responseStart,
-            requestStart, responseEnd, domInteractive, loadEventStart, domContentLoadedEventEnd,
-            fetchStart, secureConnectionStart, transferSize, encodedBodySize,
-            redirectEnd, redirectStart
-          } = timing
-          //console.log(timing.domInteractive);
-          //console.log(timing.fetchStart);
-          let diff = timing.domInteractive - timing.fetchStart;
-          //console.log("TTI: " + diff);
-          const timeInfo = [
-            { '类型': 'DNS 解析耗时', '耗时': domainLookupEnd - domainLookupStart},
-            { '类型': 'TCP 连接耗时', '耗时': connectEnd - connectStart},
-            { '类型': 'SSL 安全连接耗时', '耗时': connectEnd - secureConnectionStart},
-            { '类型': '网络请求耗时', '耗时': responseStart - requestStart},
-            { '类型': '数据传输耗时', '耗时': responseEnd - responseStart},
-            { '类型': 'DOM 解析耗时', '耗时': domInteractive - responseEnd},
-            { '类型': '资源加载耗时', '耗时': loadEventStart - domContentLoadedEventEnd},
-            { '类型': 'First Byte时间', '耗时': responseStart - domainLookupStart},
-            { '类型': '白屏时间', '耗时': responseEnd - fetchStart},
-            { '类型': '首次可交互时间', '耗时': domInteractive - fetchStart},
-            { '类型': 'DOM Ready 时间', '耗时': domContentLoadedEventEnd - fetchStart},
-            { '类型': '页面完全加载时间', '耗时': loadEventStart - fetchStart},
-            { '类型': 'http 头部大小', '耗时': transferSize - encodedBodySize},
-            { '类型': '重定向次数', '耗时': performance.navigation.redirectCount},
-            { '类型': '重定向耗时', '耗时': redirectEnd - redirectStart},
-          ];
-          console.table(timeInfo);
-          
-        };
+      window.onload = function() {
+        console.log('加载完成')
+        let timing: any = performance.getEntriesByType('navigation')[0];
+        const { domainLookupEnd, domainLookupStart, connectEnd, connectStart, responseStart,
+          requestStart, responseEnd, domInteractive, loadEventStart, domContentLoadedEventEnd,
+          fetchStart, secureConnectionStart, transferSize, encodedBodySize,
+          redirectEnd, redirectStart
+        } = timing
+        //console.log(timing.domInteractive);
+        //console.log(timing.fetchStart);
+        let diff = timing.domInteractive - timing.fetchStart;
+        //console.log("TTI: " + diff);
+        const timeInfo = [
+          { '类型': 'DNS 解析耗时', '耗时': domainLookupEnd - domainLookupStart},
+          { '类型': 'TCP 连接耗时', '耗时': connectEnd - connectStart},
+          { '类型': 'SSL 安全连接耗时', '耗时': connectEnd - secureConnectionStart},
+          { '类型': '网络请求耗时', '耗时': responseStart - requestStart},
+          { '类型': '数据传输耗时', '耗时': responseEnd - responseStart},
+          { '类型': 'DOM 解析耗时', '耗时': domInteractive - responseEnd},
+          { '类型': '资源加载耗时', '耗时': loadEventStart - domContentLoadedEventEnd},
+          { '类型': 'First Byte时间', '耗时': responseStart - domainLookupStart},
+          { '类型': '白屏时间', '耗时': responseEnd - fetchStart},
+          { '类型': '首次可交互时间', '耗时': domInteractive - fetchStart},
+          { '类型': 'DOM Ready 时间', '耗时': domContentLoadedEventEnd - fetchStart},
+          { '类型': '页面完全加载时间', '耗时': loadEventStart - fetchStart},
+          { '类型': 'http 头部大小', '耗时': transferSize - encodedBodySize},
+          { '类型': '重定向次数', '耗时': performance.navigation.redirectCount},
+          { '类型': '重定向耗时', '耗时': redirectEnd - redirectStart},
+        ];
+        console.table(timeInfo);
+        
+      };
     });
 
     onUnmounted(() => {

+ 7 - 4
src/page-instrument/view-detail/index.tsx

@@ -27,7 +27,7 @@ import TheMusicList, { isMusicList } from "../component/the-music-list";
 import { storeData } from "/src/store";
 import ViewFigner from "../view-figner";
 import ToggleMusicSheet from "/src/view/plugins/toggleMusicSheet";
-import { setCustomNoteRealValue } from "/src/helpers/customMusicScore";
+import { setCustomGradual, setCustomNoteRealValue } from "/src/helpers/customMusicScore";
 import { usePageVisibility } from "@vant/use";
 import { initMidi } from "/src/helpers/midiPlay";
 import TheAudio from "/src/components/the-audio";
@@ -208,9 +208,11 @@ export default defineComponent({
 
     /** 渲染完成 */
     const handleRendered = (osmd: any) => {
+      state.isLoading = false
       api_cloudLoading();
       console.timeEnd("渲染加载耗时");
       console.timeLog('加载过程','谱面渲染完成')
+      
       detailData.skeletonLoading = false;
       state.osmd = osmd;
       // 没有设置速度使用读取的速度
@@ -222,7 +224,8 @@ export default defineComponent({
       // if (saveSpeed) {
       //   handleSetSpeed(saveSpeed);
       // }
-      // setCustomNoteRealValue();
+      setCustomGradual();
+      setCustomNoteRealValue();
       state.times = formateTimes(osmd);
       // state.times = resetFrequency(state.times);
       state.times = setNoteHalfTone(state.times);
@@ -613,8 +616,8 @@ export default defineComponent({
           )}
         </div>
         {/* 曲目渲染完成,再去下载mp3资源 */}
-        {!detailData.isLoading && !detailData.skeletonLoading && <AudioList />}
-
+        {!detailData.isLoading && <AudioList />}
+        {/* {!detailData.isLoading && !detailData.skeletonLoading && <AudioList />} */}
         {/* {!detailData.isLoading && <TheAudio src={tickWav} />} */}
 
         {/* 预加载延迟检测组建 */}

+ 32 - 8
src/state.ts

@@ -17,13 +17,14 @@ import { followData, skipNotePractice } from "/src/view/follow-practice/index"
 import { changeSongSourceByBeat } from "/src/view/audio-list"
 import { moveSmoothAnimation, smoothAnimationState, moveSmoothAnimationByPlayTime, moveTranslateXNum, destroySmoothAnimation, calcClientWidth } from "/src/page-instrument/view-detail/smoothAnimation"
 import { storeData } from "/src/store";
-import { downloadXmlStr } from "./view/music-score"
+import { downloadXmlStr, xmlDocRef } from "./view/music-score"
 import { musicScoreRef, headerColumnHide } from "/src/page-instrument/view-detail/index"
 import { headTopData } from "/src/page-instrument/header-top/index";
 import { api_lessonTrainingTrainingStudentDetail } from "/src/page-instrument/api"
 import { undoData, moveData } from "/src/view/plugins/move-music-score"
 import { HANDLE_WORK_ADD } from "/src/page-instrument/custom-plugins/work-index";
 import { speedBeatTo, unitImgs } from "/src/helpers/beatConfig"
+import IndexedDBService from "/src/utils/indexedDB";
 
 const query: any = getQuery();
 
@@ -608,6 +609,8 @@ const state = reactive({
   firstMeasureNumber: 1,
   /** 是否是单声轨多声部的声轨 */
   isSingleMutliTrack: false,
+  /** 是否是来源于缓存的xml */
+  xmlFromStore: false,
 });
 const browserInfo = browser();
 let offset_duration = 0;
@@ -1467,16 +1470,36 @@ export const getMusicDetail = async (id: string, type?: string) => {
 };
 
 
+// 判断有没有xml缓存,有则直接使用
+const queryMusicXml = async (id: string, xmlUr: string) => {
+  let xmlString = ''
+  const dbService = new IndexedDBService("MyDatabase", "MyStore");
+  console.time('缓存获取xml')
+  const storeXmlData = await dbService.get(id).then((data) => data );
+  if (storeXmlData && storeXmlData.xmlString) {
+    xmlString = storeXmlData && storeXmlData.xmlString
+    state.xmlFromStore = true;
+    console.timeEnd('缓存获取xml')
+    // 使用完后删除数据
+    dbService.delete(id)
+  } else {
+    state.xmlFromStore = false;
+    xmlString = await fetch(xmlUr).then((response) => response.text());
+  }
+  return xmlString;
+}
+
 const getMusicInfo = async (res: any) => {
   // 是否支持总谱
   state.isScoreRender = res.data?.isScoreRender
   // 是否默认显示总谱
   state.defaultScoreRender = res.data?.defaultScoreRender
-  /* 获取声轨列表 */
-  let xmlString = await fetch(res.data.xmlFileUrl).then((response) => response.text());
+  // let xmlString = await fetch(res.data.xmlFileUrl).then((response) => response.text());
+  let xmlString: string = await queryMusicXml(res.data.bizId + "", res.data.xmlFileUrl);
   xmlString = xmlAddPartName(xmlString);
   downloadXmlStr.value = xmlString //给musice-score 赋值xmlString 以免加载2次
-  const tracks = xmlToTracks(xmlString) //获取声轨列表  
+  /* 获取声轨列表 */
+  const tracks = xmlToTracks(xmlString)
   // 是否显示节拍器  (管乐迷 默认显示节拍器)
   //state.isMixBeat = res.data?.isMixBeat  
   /* 设置partIndex */
@@ -1534,11 +1557,12 @@ const getMusicInfo = async (res: any) => {
 //获取xml中的音轨数据
 function xmlToTracks(xmlString: string) {
   //console.time('domparse')
-  console.time('解析xml 耗时1')
-  const xmlParse = new DOMParser().parseFromString(xmlString, "text/xml");
-  console.timeEnd('解析xml 耗时1')
+  // console.time('解析xml 耗时1')
+  // const xmlParse = new DOMParser().parseFromString(xmlString, "text/xml");
+  const xmlParse = xmlDocRef.value;
+  // console.timeEnd('解析xml 耗时1')
   //console.timeEnd('domparse')
-  const partNames = Array.from(xmlParse.getElementsByTagName('part-name'));
+  const partNames = xmlParse ? Array.from(xmlParse.getElementsByTagName('part-name')) : [];
   return partNames.reduce((arr: string[], item) => {
     const textContent = item?.textContent?.trim()
     if (textContent?.toLocaleLowerCase() === "common") {

+ 117 - 0
src/utils/indexedDB.ts

@@ -0,0 +1,117 @@
+interface DataInfo {
+    id: number | string; // 主键
+    xmlString: string;
+    xmlDoc: Document;
+}
+
+export default class IndexedDBService<T> {
+    private dbName: string;
+    private storeName: string;
+    private version: number;
+  
+    constructor(dbName: string, storeName: string, version: number = 1) {
+      this.dbName = dbName;
+      this.storeName = storeName;
+      this.version = version;
+    }
+  
+    // 初始化数据库
+    private async init(): Promise<IDBDatabase> {
+      return new Promise((resolve, reject) => {
+        const request = indexedDB.open(this.dbName, this.version);
+  
+        // 数据库第一次创建或版本号升级时触发
+        request.onupgradeneeded = () => {
+          const db = request.result;
+          // 创建对象存储(类似于表)
+          if (!db.objectStoreNames.contains(this.storeName)) {
+            db.createObjectStore(this.storeName, { keyPath: "id" });
+          }
+        };
+  
+        // 返回数据库实例
+        request.onsuccess = () => resolve(request.result);
+        // 捕获错误
+        request.onerror = () => reject(request.error);
+      });
+    }
+  
+    // 添加或者更新数据
+    async save(data: T): Promise<void> {
+      const db = await this.init();
+      return new Promise((resolve, reject) => {
+        const transaction = db.transaction(this.storeName, "readwrite");
+        const store = transaction.objectStore(this.storeName);
+        const request = store.put(data);
+  
+        request.onsuccess = () => resolve();
+        request.onerror = () => reject(request.error);
+      });
+    }
+  
+    // 获取某条数据
+    async get(id: number | string): Promise<T | undefined> {
+      const db = await this.init();
+      return new Promise((resolve, reject) => {
+        const transaction = db.transaction(this.storeName, "readonly");
+        const store = transaction.objectStore(this.storeName);
+        const request = store.get(id);
+  
+        request.onsuccess = () => resolve(request.result as T);
+        request.onerror = () => reject(request.error);
+      });
+    }
+  
+    // 删除数据
+    async delete(id: number | string): Promise<void> {
+      const db = await this.init();
+      return new Promise((resolve, reject) => {
+        const transaction = db.transaction(this.storeName, "readwrite");
+        const store = transaction.objectStore(this.storeName);
+        const request = store.delete(id);
+  
+        request.onsuccess = () => resolve();
+        request.onerror = () => reject(request.error);
+      });
+    }
+  
+    // 查询所有数据
+    async getAll(): Promise<T[]> {
+      const db = await this.init();
+      return new Promise((resolve, reject) => {
+        const transaction = db.transaction(this.storeName, "readonly");
+        const store = transaction.objectStore(this.storeName);
+        const request = store.getAll();
+  
+        request.onsuccess = () => resolve(request.result as T[]);
+        request.onerror = () => reject(request.error);
+      });
+    }
+
+    // 清空某个 Object Store 中的所有数据
+    async clearAllData(): Promise<void> {
+      const db = await this.init();
+    
+      return new Promise((resolve, reject) => {
+        const transaction = db.transaction(this.storeName, "readwrite");
+        const store = transaction.objectStore(this.storeName);
+    
+        const request = store.clear(); // 清空数据
+    
+        request.onsuccess = () => resolve();
+        request.onerror = () => reject(request.error);
+      });
+    }
+
+    // 删除整个数据库
+    async deleteDatabase(): Promise<void> {
+      return new Promise((resolve, reject) => {
+        const request = indexedDB.deleteDatabase(this.dbName); // 删除整个数据库
+    
+        request.onsuccess = () => resolve();
+        request.onerror = () => reject(request.error);
+      });
+    }
+}
+  
+  

+ 6 - 5
src/view/audio-list/index.tsx

@@ -214,7 +214,8 @@ const createAudio = (src?: string): Promise<HTMLAudioElement | null> => {
 		return Promise.resolve(null)
 	}
 	return new Promise((resolve) => {
-		const a = new Audio(src + '?v=' + Date.now());
+		// const a = new Audio(src + '?v=' + Date.now());
+		const a = new Audio(src);
 		a.onloadedmetadata = () => {
 			resolve(a);
 		};
@@ -253,7 +254,7 @@ async function mergeBeatAudio(music?:string){
 			CrunkerInstance = new Crunker()
 		}
 		console.time("音频加载时间")
-		const [musicBuff, tickBuff, tockBuff] = await CrunkerInstance.fetchAudio(music?`${music}?v=${Date.now()}`:undefined, tickMp3, tockMp3)
+		const [musicBuff, tickBuff, tockBuff] = await CrunkerInstance.fetchAudio(music?`${music}`:undefined, tickMp3, tockMp3)
 		console.timeEnd("音频加载时间")
 		// 计算音频空白时间
 		const silenceDuration = musicBuff&&!state.isEvxml ? CrunkerInstance.calculateSilenceDuration(musicBuff) : 0
@@ -380,7 +381,7 @@ export async function changeCombineAudio (combineIndex: number){
 		return
 	}
 	state.loadingText = "音频资源加载中,请稍后…";
-	state.isLoading = true;
+	//state.isLoading = true;
 	const musicUrl = audioData.combineMusics[combineIndex]
 	// 有就拿缓存,没有就加载
 	const cacheMusicIndex = audioData.combineMusicEles.findIndex(ele => {
@@ -545,7 +546,7 @@ export default defineComponent({
 			if(state.isPreView){
 				state.isLoading = false;
 				return
-			}			
+			}
 			if (state.playMode !== "MIDI") {
 				console.time("音频加载耗时")
 				// 处理音源
@@ -640,7 +641,7 @@ export default defineComponent({
 				changeMingSongType()
 
 				state.audioDone = true;
-				state.isLoading = false
+				// state.isLoading = false
 				console.timeEnd("音频加载耗时")
 				console.timeLog('加载过程','音频加载完成')
 				console.log("音频数据:",audioData)

+ 16 - 6
src/view/music-score/index.tsx

@@ -35,6 +35,9 @@ export const resetRenderMusicScore = (type?: string) => {
 // 下载后的xml
 export const downloadXmlStr = ref("")
 
+// xml的document对象
+export const xmlDocRef = ref<Document | null>(null);
+
 export default defineComponent({
 	name: "music-score",
 	emits: ["rendered"],
@@ -74,12 +77,19 @@ export default defineComponent({
 				downloadXmlStr.value = await fetch(state.xmlUrl).then((response) => response.text())
 			}
 			console.time('增删改查xml')
-			const xmlStr = downloadXmlStr.value;
-			const parseXmlInfo = getCustomInfo(xmlStr);
-			const xml = formatXML(parseXmlInfo.parsedXML);
-			musicData.score = state.isCombineRender ? xml : onlyVisible(xml, state.partIndex);
-			if (state.gradualTimes) {
-				state.gradual = getGradualLengthByXml(xml);
+			if (state.xmlFromStore) {
+				musicData.score = state.isCombineRender ? downloadXmlStr.value : onlyVisible(downloadXmlStr.value, state.partIndex);
+				if (state.gradualTimes) {
+					state.gradual = getGradualLengthByXml(downloadXmlStr.value);
+				}
+			} else {
+				const xmlStr = downloadXmlStr.value;
+				const parseXmlInfo = getCustomInfo(xmlStr);
+				const xml = formatXML(parseXmlInfo.parsedXML);
+				musicData.score = state.isCombineRender ? xml : onlyVisible(xml, state.partIndex);
+				if (state.gradualTimes) {
+					state.gradual = getGradualLengthByXml(xml);
+				}
 			}
 			console.timeEnd('增删改查xml')
 		};

+ 15 - 2
src/view/plugins/toggleMusicSheet/index.tsx

@@ -10,6 +10,8 @@ import useDrag from "/src/view/plugins/useDrag/index";
 import Dragbom from "/src/view/plugins/useDrag/dragbom";
 import { setGuidance } from "/src/page-instrument/custom-plugins/guide-page/api";
 import { storeData } from "/src/store";
+import { xmlDocRef, downloadXmlStr } from "/src/view/music-score"
+import IndexedDBService from "/src/utils/indexedDB";
 
 export const toggleMusicSheet = reactive({
   show: false,
@@ -51,7 +53,15 @@ export default defineComponent({
       }
     })
 
-    const switchMusic = (partIndexs: number[]) => {
+    // 切换的时候存储处理过后的xml
+    const storeXmlData = async () => {
+      const dbService = new IndexedDBService("MyDatabase", "MyStore");
+      await dbService.save({ id: state.examSongId, xmlString: downloadXmlStr.value })
+        .then(() => dbService.get(state.examSongId))
+        .then((data) => console.log("数据:", data));
+    }
+
+    const switchMusic = async (partIndexs: number[]) => {
       const index = partIndexs.join(",") as any
       // 暂停播放
       togglePlay("paused");
@@ -79,7 +89,10 @@ export default defineComponent({
           'part-index': index,
           'part-name': ''
         })
-      console.log(_url)
+      // const blob2 = new Blob([downloadXmlStr.value], { type: "text/html" });
+      // console.log(_url,xmlDocRef.value,downloadXmlStr.value)
+      
+      await storeXmlData()
       location.href = _url
     }
 

+ 21 - 0
vite.config.ts

@@ -14,6 +14,16 @@ export default defineConfig({
   // assetsInclude: ['**/*.html'],
   plugins: [
     // mkcert(), // 本地https
+    // viteCompression({
+    //   algorithm: "gzip", // 指定压缩算法为gzip,[ 'gzip' , 'brotliCompress' ,'deflate' , 'deflateRaw']
+    //   ext: ".gz", // 指定压缩后的文件扩展名为.gz
+    //   threshold: 10240, // 仅对文件大小大于threshold的文件进行压缩,默认为10KB
+    //   deleteOriginFile: false, // 是否删除原始文件,默认为false
+    //   filter: /\.(js|css|json|html|ico|svg)(\?.*)?$/i, // 匹配要压缩的文件的正则表达式,默认为匹配.js、.css、.json、.html、.ico和.svg文件
+    //   compressionOptions: { level: 9 }, // 指定gzip压缩级别,默认为9(最高级别)
+    //   verbose: true, //是否在控制台输出压缩结果
+    //   disable: false, //是否禁用插件
+    // }),
     legacy({
       targets: ["Chrome 63"],
       additionalLegacyPolyfills: ["regenerator-runtime/runtime"],
@@ -48,6 +58,17 @@ export default defineConfig({
         instrument: resolve(__dirname, "instrument.html"),
       },
       output: {
+        // 最小化拆分包
+        manualChunks(id) {
+          if (id.includes("osmd-extended")) {
+            // 通过拆分包的方式将所有来自osmd-extended的模块打包到单独的chunk中
+            return id
+              .toString()
+              .split("osmd-extended/")[1]
+              .split("/")[0]
+              .toString();
+          }
+        },
         chunkFileNames: "js/[name]-[hash].js", // 引入文件名的名称
         entryFileNames: "js/[name]-[hash].js", // 包的入口文件名称
         assetFileNames: "[ext]/[name]-[hash].[ext]", // 资源文件像 字体,图片等