|
@@ -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")} />
|