|  | @@ -18,7 +18,7 @@ import { decodeUrl, downloadFile } from "/src/utils";
 | 
	
		
			
				|  |  |  import FileBtn, { IFileBtnType } from "./component/file-btn";
 | 
	
		
			
				|  |  |  import TheSetting from "./component/the-setting";
 | 
	
		
			
				|  |  |  import { useRoute } from "vue-router";
 | 
	
		
			
				|  |  | -import { api_musicSheetCreationDetail, api_musicSheetCreationSave, api_musicSheetCreationUpdate, api_xmlToAbc } from "../api";
 | 
	
		
			
				|  |  | +import { api_musicSheetCreationDetail, api_musicSheetCreationSave, api_musicSheetCreationUpdate, api_musicalScoreConversionRecordPage, api_musicalScoreConversionRecordRemove, api_musicalScoreConversionRecordSave, api_xmlToAbc } from "../api";
 | 
	
		
			
				|  |  |  import instrumentsNames from "/src/constant/instrmentsNames.json";
 | 
	
		
			
				|  |  |  import { ALL_NOTES, ALL_Pitches } from "./noteData";
 | 
	
		
			
				|  |  |  import { Close } from "@vicons/ionicons5";
 | 
	
	
		
			
				|  | @@ -34,6 +34,7 @@ import { api_uploadFile } from "/src/utils/uploadFile";
 | 
	
		
			
				|  |  |  import { bufferToWave } from "/src/helpers/parseABC";
 | 
	
		
			
				|  |  |  import UploadToResources from "../component/upload-to-resources";
 | 
	
		
			
				|  |  |  import TheJianpu from "./component/the-jianpu";
 | 
	
		
			
				|  |  | +import { getUploadSign, onOnlyFileUpload } from "/src/utils/oss-file-upload";
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  export const initMusic = (total: number): IMeasure[] => {
 | 
	
		
			
				|  |  |    return new Array(total).fill(0).map((item, index) => {
 | 
	
	
		
			
				|  | @@ -101,7 +102,8 @@ export default defineComponent({
 | 
	
		
			
				|  |  |        selectMearesShow: false, // 选择小节弹窗
 | 
	
		
			
				|  |  |        jianpuShow: false, // 简谱弹窗
 | 
	
		
			
				|  |  |      });
 | 
	
		
			
				|  |  | -    const data = reactive({
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    let data = reactive({
 | 
	
		
			
				|  |  |        uploadStatus: "",
 | 
	
		
			
				|  |  |        saveLoading: false,
 | 
	
		
			
				|  |  |        saveLoadingText: false,
 | 
	
	
		
			
				|  | @@ -144,6 +146,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |        deleteMearseType: "ing" as "ing" | "finish", // 删除小节类型
 | 
	
		
			
				|  |  |        loadingAudioSrouce: false, // 加载音频资源
 | 
	
		
			
				|  |  | +      loadingAudioSrouce2: false,
 | 
	
		
			
				|  |  |        /** 移调类型 */
 | 
	
		
			
				|  |  |        moveKeyType: "inset" as "inset" | "up" | "down", // 移调类型
 | 
	
		
			
				|  |  |        activePlayNote: null as any, // 当前演奏音符
 | 
	
	
		
			
				|  | @@ -292,7 +295,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |      const textAreaRef = ref();
 | 
	
		
			
				|  |  | -    const abcData = reactive({
 | 
	
		
			
				|  |  | +    let abcData = reactive({
 | 
	
		
			
				|  |  |        visualObj: null as any,
 | 
	
		
			
				|  |  |        midiBuffer: null as unknown as ABCJS.MidiBuffer,
 | 
	
		
			
				|  |  |        abcOptions: {
 | 
	
	
		
			
				|  | @@ -1842,39 +1845,168 @@ export default defineComponent({
 | 
	
		
			
				|  |  |        }
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -    const handleExport = () => {
 | 
	
		
			
				|  |  | +    const importTemp = ref({
 | 
	
		
			
				|  |  | +      timer: null as any, // 定时任务
 | 
	
		
			
				|  |  | +      importFileId: null, // 导入文件时的编号
 | 
	
		
			
				|  |  | +      data: {} as any,
 | 
	
		
			
				|  |  | +      abcData: {} as any,
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  | +    const handleExport = (val = "xml") => {
 | 
	
		
			
				|  |  |        data.active = null as unknown as INoteActive;
 | 
	
		
			
				|  |  |        const input = document.createElement("input");
 | 
	
		
			
				|  |  |        input.type = "file";
 | 
	
		
			
				|  |  | -      input.accept = ".xml,.musicxml";
 | 
	
		
			
				|  |  | +      // 处理对应不同的类型
 | 
	
		
			
				|  |  | +      if (val === "xml") {
 | 
	
		
			
				|  |  | +        input.accept = ".xml,.musicxml";
 | 
	
		
			
				|  |  | +      } else if (val === "import-image") {
 | 
	
		
			
				|  |  | +        input.accept = ".jpg,.png,.jpeg";
 | 
	
		
			
				|  |  | +      } else if (val === "import-pdf") {
 | 
	
		
			
				|  |  | +        input.accept = "application/pdf";
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  |        input.onchange = async (e: any) => {
 | 
	
		
			
				|  |  | -        data.loadingAudioSrouce = true;
 | 
	
		
			
				|  |  | +        data.loadingAudioSrouce2 = true;
 | 
	
		
			
				|  |  | +        // importTemp 缓存数据
 | 
	
		
			
				|  |  | +        importTemp.value.abcData = cloneDeep(abcData);
 | 
	
		
			
				|  |  | +        importTemp.value.data = cloneDeep(data);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |          const file = e.target.files[0];
 | 
	
		
			
				|  |  | -        // const formData = new FormData();
 | 
	
		
			
				|  |  | -        // formData.append("xmlFile", file);
 | 
	
		
			
				|  |  | -        // const res = await api_xmlToAbc(formData);
 | 
	
		
			
				|  |  | -        // console.log("🚀 ~ res:", res.data)
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  | -        const reader = new FileReader();
 | 
	
		
			
				|  |  | -        reader.onload = async (e: any) => {
 | 
	
		
			
				|  |  | -          let abc = e.target.result;
 | 
	
		
			
				|  |  | -          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" });
 | 
	
		
			
				|  |  | -          console.log("🚀 ~ parseData:", parseData);
 | 
	
		
			
				|  |  | -          abcData.abc = formateAbc(parseData[0], { subjectCode: abcData.abc.subjectCode });
 | 
	
		
			
				|  |  | -          data.musicName = abcData.abc.title || data.musicName;
 | 
	
		
			
				|  |  | -          data.creator = abcData.abc.creator || data.creator;
 | 
	
		
			
				|  |  | -          await handleResetRender();
 | 
	
		
			
				|  |  | -          data.loadingAudioSrouce = false;
 | 
	
		
			
				|  |  | -        };
 | 
	
		
			
				|  |  | -        reader.readAsText(file);
 | 
	
		
			
				|  |  | +        if (val === "xml") {
 | 
	
		
			
				|  |  | +          const reader = new FileReader();
 | 
	
		
			
				|  |  | +          reader.onload = async (e: any) => {
 | 
	
		
			
				|  |  | +            // let abc = e.target.result;
 | 
	
		
			
				|  |  | +            // 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" });
 | 
	
		
			
				|  |  | +            // console.log("🚀 ~ parseData:", parseData);
 | 
	
		
			
				|  |  | +            // abcData.abc = formateAbc(parseData[0], { subjectCode: abcData.abc.subjectCode });
 | 
	
		
			
				|  |  | +            // data.musicName = abcData.abc.title || data.musicName;
 | 
	
		
			
				|  |  | +            // data.creator = abcData.abc.creator || data.creator;
 | 
	
		
			
				|  |  | +            // await handleResetRender();
 | 
	
		
			
				|  |  | +            // data.loadingAudioSrouce2 = false;
 | 
	
		
			
				|  |  | +            onRenderingXml(e.target.result);
 | 
	
		
			
				|  |  | +          };
 | 
	
		
			
				|  |  | +          reader.readAsText(file);
 | 
	
		
			
				|  |  | +        } else if (["import-image", "import-pdf"].includes(val)) {
 | 
	
		
			
				|  |  | +          handleExportImageOrPdf(file);
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  |        };
 | 
	
		
			
				|  |  |        input.click();
 | 
	
		
			
				|  |  |      };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | +    // 生成
 | 
	
		
			
				|  |  | +    const handleExportImageOrPdf = async (file: File) => {
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        console.log(file, "file");
 | 
	
		
			
				|  |  | +        const name = file.name;
 | 
	
		
			
				|  |  | +        // const suffix = name.slice(name.lastIndexOf("."));
 | 
	
		
			
				|  |  | +        const fileName = name;
 | 
	
		
			
				|  |  | +        const obj = {
 | 
	
		
			
				|  |  | +          filename: fileName,
 | 
	
		
			
				|  |  | +          bucketName: "gyt",
 | 
	
		
			
				|  |  | +          postData: {
 | 
	
		
			
				|  |  | +            filename: fileName,
 | 
	
		
			
				|  |  | +            acl: "public-read",
 | 
	
		
			
				|  |  | +            key: fileName,
 | 
	
		
			
				|  |  | +            unknowValueField: [],
 | 
	
		
			
				|  |  | +          },
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        const { data } = await getUploadSign(obj);
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const fileParams = {
 | 
	
		
			
				|  |  | +          policy: data.policy,
 | 
	
		
			
				|  |  | +          signature: data.signature,
 | 
	
		
			
				|  |  | +          key: fileName,
 | 
	
		
			
				|  |  | +          KSSAccessKeyId: data.kssAccessKeyId,
 | 
	
		
			
				|  |  | +          acl: "public-read",
 | 
	
		
			
				|  |  | +          name: fileName,
 | 
	
		
			
				|  |  | +          file: file,
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +        onOnlyFileUpload("action", fileParams).then(async (res: any) => {
 | 
	
		
			
				|  |  | +          // 判断xml是否生成失败
 | 
	
		
			
				|  |  | +          const result = await api_musicalScoreConversionRecordSave([{ fileName, fileUrl: res, creationFlag: false }]);
 | 
	
		
			
				|  |  | +          // 缓存数据
 | 
	
		
			
				|  |  | +          if (result.data && result.data.length > 0) {
 | 
	
		
			
				|  |  | +            importTemp.value.importFileId = result.data[0];
 | 
	
		
			
				|  |  | +            importTemp.value.timer = setInterval(() => {
 | 
	
		
			
				|  |  | +              getRecordList();
 | 
	
		
			
				|  |  | +            }, 5000);
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +      } catch {
 | 
	
		
			
				|  |  | +        //
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +    const getRecordList = async () => {
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        const params: any = {
 | 
	
		
			
				|  |  | +          page: 1,
 | 
	
		
			
				|  |  | +          rows: -1,
 | 
	
		
			
				|  |  | +          idList: [importTemp.value.importFileId],
 | 
	
		
			
				|  |  | +        };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        const res = await api_musicalScoreConversionRecordPage(params);
 | 
	
		
			
				|  |  | +        const temps = res.data.rows || [];
 | 
	
		
			
				|  |  | +        let recordItem: any = {};
 | 
	
		
			
				|  |  | +        temps.forEach((record: any) => {
 | 
	
		
			
				|  |  | +          if (record.id === importTemp.value.importFileId) {
 | 
	
		
			
				|  |  | +            recordItem = record;
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        });
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +        if (recordItem.status === "SUCCESS") {
 | 
	
		
			
				|  |  | +          clearInterval(importTemp.value.timer);
 | 
	
		
			
				|  |  | +          // xmlFileUrl;
 | 
	
		
			
				|  |  | +          if (recordItem.xmlFileUrl) {
 | 
	
		
			
				|  |  | +            const result = await requestOrigin.get(recordItem.xmlFileUrl, {
 | 
	
		
			
				|  |  | +              mode: "cors",
 | 
	
		
			
				|  |  | +            });
 | 
	
		
			
				|  |  | +            onRenderingXml(result);
 | 
	
		
			
				|  |  | +          } else {
 | 
	
		
			
				|  |  | +            data.loadingAudioSrouce2 = false;
 | 
	
		
			
				|  |  | +            message.error("上传失败");
 | 
	
		
			
				|  |  | +          }
 | 
	
		
			
				|  |  | +        } else if (recordItem.status === "FAIL") {
 | 
	
		
			
				|  |  | +          clearInterval(importTemp.value.timer);
 | 
	
		
			
				|  |  | +          data.loadingAudioSrouce2 = false;
 | 
	
		
			
				|  |  | +          message.error("上传失败");
 | 
	
		
			
				|  |  | +        }
 | 
	
		
			
				|  |  | +      } catch (e) {
 | 
	
		
			
				|  |  | +        //
 | 
	
		
			
				|  |  | +        console.log(e, "e");
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    const onRenderingXml = async (reuslt: any) => {
 | 
	
		
			
				|  |  | +      try {
 | 
	
		
			
				|  |  | +        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" });
 | 
	
		
			
				|  |  | +        console.log("🚀 ~ parseData:", parseData);
 | 
	
		
			
				|  |  | +        abcData.abc = formateAbc(parseData[0], { subjectCode: abcData.abc.subjectCode });
 | 
	
		
			
				|  |  | +        data.musicName = abcData.abc.title || data.musicName;
 | 
	
		
			
				|  |  | +        data.creator = abcData.abc.creator || data.creator;
 | 
	
		
			
				|  |  | +        await handleResetRender();
 | 
	
		
			
				|  |  | +      } catch {}
 | 
	
		
			
				|  |  | +      data.loadingAudioSrouce2 = false;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +    // 取消
 | 
	
		
			
				|  |  | +    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;
 | 
	
		
			
				|  |  | +    };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |      /** 设置选段小节 */
 | 
	
		
			
				|  |  |      const handleSetSelectMeares = (index: number | null, type: "start" | "end") => {
 | 
	
		
			
				|  |  |        console.log("🚀 ~ index:", index);
 | 
	
	
		
			
				|  | @@ -1942,8 +2074,8 @@ export default defineComponent({
 | 
	
		
			
				|  |  |                        handleCreateMusic();
 | 
	
		
			
				|  |  |                      } else if (val === "save") {
 | 
	
		
			
				|  |  |                        handleSaveMusic(true);
 | 
	
		
			
				|  |  | -                    } else if (["xml"].includes(val)) {
 | 
	
		
			
				|  |  | -                      handleExport();
 | 
	
		
			
				|  |  | +                    } else if (["xml", "import-image", "import-pdf"].includes(val)) {
 | 
	
		
			
				|  |  | +                      handleExport(val);
 | 
	
		
			
				|  |  |                      } else if (val === "upload") {
 | 
	
		
			
				|  |  |                        handleUpdate();
 | 
	
		
			
				|  |  |                      } else if (["png", "midi", "wav", "down-xml"].includes(val)) {
 | 
	
	
		
			
				|  | @@ -2344,7 +2476,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |                <div class={styles.topLine}></div>
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |                <div style={{ marginLeft: "auto" }} class={styles.topBtn}>
 | 
	
		
			
				|  |  | -                <NSpin show={data.loadingAudioSrouce} size="small">
 | 
	
		
			
				|  |  | +                <NSpin show={data.loadingAudioSrouce || data.loadingAudioSrouce2} size="small" stroke="#20BDFF">
 | 
	
		
			
				|  |  |                    <div class={styles.btnImg} onClick={() => togglePlay("reset")}>
 | 
	
		
			
				|  |  |                      <img class={styles.topBtnIcon} src={getImage("icon_20.png")} />
 | 
	
		
			
				|  |  |                    </div>
 | 
	
	
		
			
				|  | @@ -2353,7 +2485,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |                  <div>重播</div>
 | 
	
		
			
				|  |  |                </div>
 | 
	
		
			
				|  |  |                <div class={styles.topBtn}>
 | 
	
		
			
				|  |  | -                <NSpin show={data.loadingAudioSrouce} size="small">
 | 
	
		
			
				|  |  | +                <NSpin show={data.loadingAudioSrouce || data.loadingAudioSrouce2} size="small" stroke="#20BDFF">
 | 
	
		
			
				|  |  |                    <div class={styles.btnImg} onClick={() => togglePlay(data.playState ? "pause" : "play")}>
 | 
	
		
			
				|  |  |                      <img style={{ display: data.playState ? "" : "none" }} class={styles.topBtnIcon} src={getImage("icon_21_1.png")} />
 | 
	
		
			
				|  |  |                      <img style={{ display: data.playState ? "none" : "" }} class={styles.topBtnIcon} src={getImage("icon_21.png")} />
 | 
	
	
		
			
				|  | @@ -2558,7 +2690,25 @@ export default defineComponent({
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |              {data.loadingAudioSrouce && (
 | 
	
		
			
				|  |  |                <div class={styles.loading}>
 | 
	
		
			
				|  |  | -                <NSpin description="资源加载中..."></NSpin>
 | 
	
		
			
				|  |  | +                <NSpin description="资源加载中..." stroke="#20BDFF"></NSpin>
 | 
	
		
			
				|  |  | +              </div>
 | 
	
		
			
				|  |  | +            )}
 | 
	
		
			
				|  |  | +            {data.loadingAudioSrouce2 && (
 | 
	
		
			
				|  |  | +              <div class={styles.loading}>
 | 
	
		
			
				|  |  | +                <NSpin description="" stroke="#20BDFF">
 | 
	
		
			
				|  |  | +                  {{
 | 
	
		
			
				|  |  | +                    description: () => (
 | 
	
		
			
				|  |  | +                      <div>
 | 
	
		
			
				|  |  | +                        <div class={styles.tips}>正在识别曲目文件,请耐心等待...</div>
 | 
	
		
			
				|  |  | +                        <div class={styles.btnGroup}>
 | 
	
		
			
				|  |  | +                          <NButton round onClick={onCancelExport}>
 | 
	
		
			
				|  |  | +                            取消上传
 | 
	
		
			
				|  |  | +                          </NButton>
 | 
	
		
			
				|  |  | +                        </div>
 | 
	
		
			
				|  |  | +                      </div>
 | 
	
		
			
				|  |  | +                    ),
 | 
	
		
			
				|  |  | +                  }}
 | 
	
		
			
				|  |  | +                </NSpin>
 | 
	
		
			
				|  |  |                </div>
 | 
	
		
			
				|  |  |              )}
 | 
	
		
			
				|  |  |              {data.saveLoadingText && <div class={styles.loading}></div>}
 | 
	
	
		
			
				|  | @@ -2582,7 +2732,7 @@ export default defineComponent({
 | 
	
		
			
				|  |  |                      <NInputNumber min={data.selectMeasures.start} max={data.selectMeasures.max} bordered={false} placeholder="结束小节" showButton={false} onUpdate:value={(val) => handleSetSelectMeares(val, "end")}></NInputNumber>
 | 
	
		
			
				|  |  |                    </div>
 | 
	
		
			
				|  |  |                    <div class={styles.topBtn}>
 | 
	
		
			
				|  |  | -                    <NSpin show={data.loadingAudioSrouce} size="small">
 | 
	
		
			
				|  |  | +                    <NSpin show={data.loadingAudioSrouce} size="small" stroke="#20BDFF">
 | 
	
		
			
				|  |  |                        <div class={styles.btnImg} onClick={() => togglePlay(data.playState ? "pause" : "play")}>
 | 
	
		
			
				|  |  |                          <img style={{ display: data.playState ? "" : "none" }} class={styles.topBtnIcon} src={getImage("icon_21_1.png")} />
 | 
	
		
			
				|  |  |                          <img style={{ display: data.playState ? "none" : "" }} class={styles.topBtnIcon} src={getImage("icon_21.png")} />
 |