|
@@ -1,269 +1,287 @@
|
|
|
import { defineComponent, nextTick, onMounted, onUnmounted, reactive, ref, watch } from "vue";
|
|
|
-import {
|
|
|
- api_musicSheetCreationWav2mp3,
|
|
|
- api_musicSheetCreationSaveMusic,
|
|
|
- api_subjectList,
|
|
|
-} from "../../api";
|
|
|
-import {
|
|
|
- NButton,
|
|
|
- NForm,
|
|
|
- NFormItem,
|
|
|
- NIcon,
|
|
|
- NModal,
|
|
|
- NProgress,
|
|
|
- NSelect,
|
|
|
- NSpace,
|
|
|
- useMessage,
|
|
|
-} from "naive-ui";
|
|
|
+import ABCJS, { AbcElem, AbcVisualParams, ClickListenerAnalysis, ClickListenerDrag, NoteTimingEvent, SynthObjectController } from "abcjs";
|
|
|
+import { api_musicSheetCreationWav2mp3, api_musicSheetCreationSaveMusic, api_subjectList, api_musicSheetCreationUpdate } from "../../api";
|
|
|
+import { NButton, NForm, NFormItem, NIcon, NModal, NProgress, NSelect, NSpace, useMessage } from "naive-ui";
|
|
|
import styles from "./index.module.less";
|
|
|
import { Close } from "@vicons/ionicons5";
|
|
|
import { SelectMixedOption } from "naive-ui/es/select/src/interface";
|
|
|
import { api_uploadFile } from "/src/utils/uploadFile";
|
|
|
+import { bufferToWave } from "/src/helpers/parseABC";
|
|
|
+import { decodeUrl, downloadFile } from "/src/utils";
|
|
|
+import { renderMeasures } from "../../home/runtime";
|
|
|
+import cleanDeep from "clean-deep";
|
|
|
|
|
|
export default defineComponent({
|
|
|
- name: "UploadToResources",
|
|
|
- props: {
|
|
|
- show: {
|
|
|
- type: Boolean,
|
|
|
- default: false,
|
|
|
- },
|
|
|
- item: {
|
|
|
- type: Object,
|
|
|
- default: () => ({}),
|
|
|
- },
|
|
|
- },
|
|
|
- emits: ["update:show", "success"],
|
|
|
- setup(props, { emit }) {
|
|
|
- const message = useMessage();
|
|
|
- const model = reactive({
|
|
|
- subjects: [] as SelectMixedOption[],
|
|
|
- saveLoading: false,
|
|
|
- saveProgress: 0,
|
|
|
- productOpen: false,
|
|
|
- productIfameSrc: "",
|
|
|
- });
|
|
|
- const froms = reactive({
|
|
|
- subjectId: null,
|
|
|
- isPublic: 0,
|
|
|
- mp3: "",
|
|
|
- musicImg: "",
|
|
|
- musicSvg: "",
|
|
|
- musicJianSvg: "",
|
|
|
- });
|
|
|
- const getSubjects = async () => {
|
|
|
- const { data } = await api_subjectList();
|
|
|
- model.subjects = data.map((item: any) => {
|
|
|
- return {
|
|
|
- label: item.name,
|
|
|
- value: item.id,
|
|
|
- };
|
|
|
- });
|
|
|
- };
|
|
|
+ name: "UploadToResources",
|
|
|
+ props: {
|
|
|
+ show: {
|
|
|
+ type: Boolean,
|
|
|
+ default: false,
|
|
|
+ },
|
|
|
+ item: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({}),
|
|
|
+ },
|
|
|
+ },
|
|
|
+ emits: ["update:show", "success"],
|
|
|
+ setup(props, { emit }) {
|
|
|
+ const message = useMessage();
|
|
|
+ const model = reactive({
|
|
|
+ subjects: [] as SelectMixedOption[],
|
|
|
+ saveLoading: false,
|
|
|
+ saveProgress: 0,
|
|
|
+ productOpen: false,
|
|
|
+ productIfameSrc: "",
|
|
|
+ });
|
|
|
+ const froms = reactive({
|
|
|
+ subjectId: null,
|
|
|
+ isPublic: 0,
|
|
|
+ mp3: "",
|
|
|
+ musicImg: "",
|
|
|
+ musicSvg: "",
|
|
|
+ musicJianSvg: "",
|
|
|
+ });
|
|
|
+ const getSubjects = async () => {
|
|
|
+ const { data } = await api_subjectList();
|
|
|
+ model.subjects = data.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.name,
|
|
|
+ value: item.id,
|
|
|
+ };
|
|
|
+ });
|
|
|
+ };
|
|
|
|
|
|
- const handleProductResult = (res: MessageEvent) => {
|
|
|
- const data = res.data;
|
|
|
- if (data?.api === "webApi_renderSvg") {
|
|
|
- let imgs: any = [];
|
|
|
- try {
|
|
|
- imgs = JSON.parse(data.product);
|
|
|
- } catch (error) {
|
|
|
- console.log("🚀 ~ error:", error);
|
|
|
- }
|
|
|
- imgs = imgs.filter((item: any) => item.base64);
|
|
|
- if (imgs.length === 3) {
|
|
|
- handleUploadImg(imgs);
|
|
|
- }
|
|
|
- console.log("🚀 ~ 上传之前", [...imgs]);
|
|
|
- }
|
|
|
- };
|
|
|
- const handleUploadImg = async (imgs: any[]) => {
|
|
|
- if (!props.show) return;
|
|
|
- for (let i = 0; i < imgs.length; i++) {
|
|
|
- const fileName = `${Date.now()}p${i}.png`;
|
|
|
- const file = dataURLtoFile(imgs[i].base64, fileName);
|
|
|
- imgs[i].url = await api_uploadFile(file, fileName, () => {});
|
|
|
- model.saveProgress = (i + 1) * 20;
|
|
|
- }
|
|
|
- froms.musicImg = imgs[0]?.url || "";
|
|
|
- froms.musicSvg = imgs[1]?.url || "";
|
|
|
- froms.musicJianSvg = imgs[2]?.url || "";
|
|
|
- model.productOpen = false;
|
|
|
- imgs = [];
|
|
|
- if (!props.show) return;
|
|
|
- handleSubmit();
|
|
|
- };
|
|
|
- /** base64转file */
|
|
|
- const dataURLtoFile = (dataurl: string, filename: string) => {
|
|
|
- let arr = dataurl.split(",") || [],
|
|
|
- mime = arr[0].match(/:(.*?);/)?.[1],
|
|
|
- bstr = atob(arr[1]),
|
|
|
- n = bstr.length,
|
|
|
- u8arr = new Uint8Array(n);
|
|
|
- while (n--) {
|
|
|
- u8arr[n] = bstr.charCodeAt(n);
|
|
|
- }
|
|
|
- return new File([u8arr], filename, { type: mime });
|
|
|
- };
|
|
|
- onMounted(() => {
|
|
|
- getSubjects();
|
|
|
- window.addEventListener("message", handleProductResult);
|
|
|
- });
|
|
|
- onUnmounted(() => {
|
|
|
- window.removeEventListener("message", handleProductResult);
|
|
|
- });
|
|
|
- watch(
|
|
|
- () => props.item,
|
|
|
- () => {
|
|
|
- console.log(props.item);
|
|
|
- froms.subjectId = props.item.subjectId ?? null;
|
|
|
- }
|
|
|
- );
|
|
|
+ const handleProductResult = (res: MessageEvent) => {
|
|
|
+ const data = res.data;
|
|
|
+ if (data?.api === "webApi_renderSvg") {
|
|
|
+ let imgs: any = [];
|
|
|
+ try {
|
|
|
+ imgs = JSON.parse(data.product);
|
|
|
+ } catch (error) {
|
|
|
+ console.log("🚀 ~ error:", error);
|
|
|
+ }
|
|
|
+ imgs = imgs.filter((item: any) => item.base64);
|
|
|
+ if (imgs.length === 3) {
|
|
|
+ handleUploadImg(imgs);
|
|
|
+ }
|
|
|
+ console.log("🚀 ~ 上传之前", [...imgs]);
|
|
|
+ }
|
|
|
+ };
|
|
|
+ const handleUploadImg = async (imgs: any[]) => {
|
|
|
+ if (!props.show) return;
|
|
|
+ for (let i = 0; i < imgs.length; i++) {
|
|
|
+ const fileName = `${Date.now()}p${i}.png`;
|
|
|
+ const file = dataURLtoFile(imgs[i].base64, fileName);
|
|
|
+ imgs[i].url = await api_uploadFile(file, fileName, () => {});
|
|
|
+ model.saveProgress = (i + 1) * 20;
|
|
|
+ }
|
|
|
+ froms.musicImg = imgs[0]?.url || "";
|
|
|
+ froms.musicSvg = imgs[1]?.url || "";
|
|
|
+ froms.musicJianSvg = imgs[2]?.url || "";
|
|
|
+ model.productOpen = false;
|
|
|
+ imgs = [];
|
|
|
+ if (!props.show) return;
|
|
|
+ handleSubmit();
|
|
|
+ };
|
|
|
+ /** base64转file */
|
|
|
+ const dataURLtoFile = (dataurl: string, filename: string) => {
|
|
|
+ let arr = dataurl.split(",") || [],
|
|
|
+ mime = arr[0].match(/:(.*?);/)?.[1],
|
|
|
+ bstr = atob(arr[1]),
|
|
|
+ n = bstr.length,
|
|
|
+ u8arr = new Uint8Array(n);
|
|
|
+ while (n--) {
|
|
|
+ u8arr[n] = bstr.charCodeAt(n);
|
|
|
+ }
|
|
|
+ return new File([u8arr], filename, { type: mime });
|
|
|
+ };
|
|
|
+ onMounted(() => {
|
|
|
+ getSubjects();
|
|
|
+ window.addEventListener("message", handleProductResult);
|
|
|
+ });
|
|
|
+ onUnmounted(() => {
|
|
|
+ window.removeEventListener("message", handleProductResult);
|
|
|
+ });
|
|
|
+ watch(
|
|
|
+ () => props.item,
|
|
|
+ () => {
|
|
|
+ // console.log(props.item, model.subjects);
|
|
|
+ const subjectId = model.subjects.length > 0 ? model.subjects[0].value : null;
|
|
|
+ froms.subjectId = props.item.subjectId ?? subjectId;
|
|
|
+ }
|
|
|
+ );
|
|
|
|
|
|
- const createMusic = async () => {
|
|
|
- console.log()
|
|
|
- await api_musicSheetCreationSaveMusic({
|
|
|
- musicSheetCreationId: props.item.id,
|
|
|
- musicSheetName: props.item.name || "曲谱名称",
|
|
|
- musicSheetCategoriesId: "",
|
|
|
- audioType: "MP3",
|
|
|
- mp3Type: "MP3",
|
|
|
- xmlFileUrl: props.item.xml,
|
|
|
- musicSubject: froms.subjectId,
|
|
|
- showFingering: 1,
|
|
|
- canEvaluate: 1,
|
|
|
- notation: 1,
|
|
|
- playSpeed: props.item?.visualObj?.metaText?.tempo?.bpm || "",
|
|
|
- background: [
|
|
|
- {
|
|
|
- audioFileUrl: froms.mp3,
|
|
|
- track: "P1",
|
|
|
- },
|
|
|
- ],
|
|
|
- musicImg: froms.musicImg,
|
|
|
- musicSvg: froms.musicSvg,
|
|
|
- musicJianSvg: froms.musicJianSvg,
|
|
|
- extConfigJson: "",
|
|
|
- });
|
|
|
- };
|
|
|
- const wav2mp3 = async () => {
|
|
|
- try {
|
|
|
- const { data } = await api_musicSheetCreationWav2mp3(props.item.filePath);
|
|
|
- froms.mp3 = data;
|
|
|
- } catch (error) {
|
|
|
- message.error("wav转mp3失败");
|
|
|
- handleClose();
|
|
|
- }
|
|
|
- };
|
|
|
+ const createMusic = async () => {
|
|
|
+ await api_musicSheetCreationSaveMusic({
|
|
|
+ musicSheetCreationId: props.item.id,
|
|
|
+ musicSheetName: props.item.name || "曲谱名称",
|
|
|
+ musicSheetCategoriesId: "",
|
|
|
+ audioType: "MP3",
|
|
|
+ mp3Type: "MP3",
|
|
|
+ xmlFileUrl: props.item.xml,
|
|
|
+ musicSubject: froms.subjectId,
|
|
|
+ showFingering: 1,
|
|
|
+ canEvaluate: 1,
|
|
|
+ notation: 1,
|
|
|
+ playSpeed: props.item?.visualObj?.metaText?.tempo?.bpm || "",
|
|
|
+ background: [
|
|
|
+ {
|
|
|
+ audioFileUrl: froms.mp3,
|
|
|
+ track: "P1",
|
|
|
+ },
|
|
|
+ ],
|
|
|
+ musicImg: froms.musicImg,
|
|
|
+ musicSvg: froms.musicSvg,
|
|
|
+ musicJianSvg: froms.musicJianSvg,
|
|
|
+ extConfigJson: "",
|
|
|
+ });
|
|
|
+ };
|
|
|
+ const wav2mp3 = async () => {
|
|
|
+ try {
|
|
|
+ const { data } = await api_musicSheetCreationWav2mp3(props.item.filePath);
|
|
|
+ froms.mp3 = data;
|
|
|
+ } catch (error) {
|
|
|
+ message.error("wav转mp3失败");
|
|
|
+ handleClose();
|
|
|
+ }
|
|
|
+ };
|
|
|
|
|
|
- const handleClose = () => {
|
|
|
- model.saveLoading = false;
|
|
|
- model.saveProgress = 0;
|
|
|
- };
|
|
|
+ const handleClose = () => {
|
|
|
+ model.saveLoading = false;
|
|
|
+ model.saveProgress = 0;
|
|
|
+ };
|
|
|
|
|
|
- /** 自动生成图片 */
|
|
|
- const handleAutoProduct = async () => {
|
|
|
- model.saveProgress = 0;
|
|
|
- const xml = props.item.xml;
|
|
|
- const res = await fetch(xml);
|
|
|
- if (res.status > 299 || res.status < 200) {
|
|
|
- message.error("xml文件不存在");
|
|
|
- handleClose();
|
|
|
- return;
|
|
|
- }
|
|
|
- const origin = /(localhost|192)/.test(location.host)
|
|
|
- ? "https://test.lexiaoya.cn"
|
|
|
- : location.origin;
|
|
|
- model.productIfameSrc = `${origin}/instrument/#/product-img?xmlUrl=${xml}&productXmlImg=1`;
|
|
|
- model.productOpen = true;
|
|
|
- setTimeout(() => {
|
|
|
- model.saveProgress = 10;
|
|
|
- }, 800);
|
|
|
- };
|
|
|
- const fromRef = ref();
|
|
|
- const handleUpload = () => {
|
|
|
- fromRef.value.validate((err: any) => {
|
|
|
- if (err) {
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!props.item.xml) {
|
|
|
- message.error("没有生成xml文件");
|
|
|
- handleClose();
|
|
|
- return;
|
|
|
- }
|
|
|
- if (!props.item.filePath) {
|
|
|
- message.error("没有生成wav文件");
|
|
|
- handleClose();
|
|
|
- return;
|
|
|
- }
|
|
|
- model.saveLoading = true;
|
|
|
- handleAutoProduct();
|
|
|
- });
|
|
|
- };
|
|
|
- const handleSubmit = async () => {
|
|
|
- await wav2mp3();
|
|
|
- model.saveProgress = 70;
|
|
|
- if (!props.show) return;
|
|
|
- await createMusic();
|
|
|
- model.saveProgress = 100;
|
|
|
- emit("success");
|
|
|
- if (!props.show) return;
|
|
|
- message.success("上传成功");
|
|
|
- setTimeout(() => {
|
|
|
- model.saveLoading = false;
|
|
|
- emit("update:show", false);
|
|
|
- }, 300);
|
|
|
- };
|
|
|
- return () => (
|
|
|
- <>
|
|
|
- <NModal
|
|
|
- autoFocus={false}
|
|
|
- show={props.show}
|
|
|
- onUpdate:show={(val) => {
|
|
|
- model.productOpen = false;
|
|
|
- emit("update:show", val);
|
|
|
- }}
|
|
|
- >
|
|
|
- <div class={styles.setbox}>
|
|
|
- <div class={styles.head}>
|
|
|
- <div>上传到我的资源</div>
|
|
|
- <NButton
|
|
|
- class={styles.close}
|
|
|
- quaternary
|
|
|
- circle
|
|
|
- size="small"
|
|
|
- onClick={() => {
|
|
|
- model.productOpen = false;
|
|
|
- emit("update:show", false);
|
|
|
- }}
|
|
|
- >
|
|
|
- <NIcon component={Close} size={18} />
|
|
|
- </NButton>
|
|
|
- </div>
|
|
|
- <NForm
|
|
|
- ref={fromRef}
|
|
|
- model={froms}
|
|
|
- class={styles.form}
|
|
|
- labelPlacement="left"
|
|
|
- showRequireMark={false}
|
|
|
- >
|
|
|
- <NFormItem
|
|
|
- label="可用声部"
|
|
|
- path="subjectId"
|
|
|
- rule={{
|
|
|
- required: true,
|
|
|
- type: "number",
|
|
|
- message: "请选择素材可用乐器",
|
|
|
- trigger: "change",
|
|
|
- }}
|
|
|
- >
|
|
|
- <NSelect
|
|
|
- to="body"
|
|
|
- placeholder="请选择素材可用乐器"
|
|
|
- options={model.subjects}
|
|
|
- v-model:value={froms.subjectId}
|
|
|
- ></NSelect>
|
|
|
- </NFormItem>
|
|
|
- {/* <NFormItem label="是否公开">
|
|
|
+ /** 自动生成图片 */
|
|
|
+ const handleAutoProduct = async () => {
|
|
|
+ model.saveProgress = 0;
|
|
|
+ const xml = props.item.xml;
|
|
|
+ const res = await fetch(xml);
|
|
|
+ if (res.status > 299 || res.status < 200) {
|
|
|
+ message.error("xml文件不存在");
|
|
|
+ handleClose();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ const origin = /(localhost|192)/.test(location.host) ? "https://test.lexiaoya.cn" : location.origin;
|
|
|
+ model.productIfameSrc = `${origin}/instrument/#/product-img?xmlUrl=${xml}&productXmlImg=1`;
|
|
|
+ model.productOpen = true;
|
|
|
+ setTimeout(() => {
|
|
|
+ model.saveProgress = 10;
|
|
|
+ }, 800);
|
|
|
+ };
|
|
|
+
|
|
|
+ // 生成wav
|
|
|
+ const productWav = async (isUrl = true) => {
|
|
|
+ return new Promise((resolve) => {
|
|
|
+ const midiBuffer = new ABCJS.synth.CreateSynth();
|
|
|
+ midiBuffer
|
|
|
+ .init({
|
|
|
+ visualObj: props.item.visualObj,
|
|
|
+ options: {
|
|
|
+ program: 0,
|
|
|
+ soundFontUrl: "https://oss.dayaedu.com/musicSheet/",
|
|
|
+ // soundFontUrl: "https://paulrosen.github.io/midi-js-soundfonts/FluidR3_GM/", // 默认 FluidR3_GM
|
|
|
+ // soundFontUrl: "https://paulrosen.github.io/midi-js-soundfonts/MusyngKite/", // Musyng Kite
|
|
|
+ },
|
|
|
+ })
|
|
|
+ .then(() => {
|
|
|
+ midiBuffer.prime().then(async () => {
|
|
|
+ if (isUrl) {
|
|
|
+ downloadFile(midiBuffer.download(), (props.item.name || "曲谱") + ".wav");
|
|
|
+ } else {
|
|
|
+ const blob = bufferToWave((midiBuffer as any).getAudioBuffer());
|
|
|
+ const wavurl = await api_uploadFile(blob, props.item.id + ".wav");
|
|
|
+ resolve(wavurl);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const fromRef = ref();
|
|
|
+ const handleUpload = () => {
|
|
|
+ fromRef.value.validate(async (err: any) => {
|
|
|
+ if (err) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ console.log(props.item, "112");
|
|
|
+ if (!props.item.xml) {
|
|
|
+ message.error("没有生成xml文件");
|
|
|
+ handleClose();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 判断是否有wav文件,如果没有则生成保存
|
|
|
+ if (!props.item.filePath) {
|
|
|
+ const url = await productWav(false);
|
|
|
+ props.item.filePath = url;
|
|
|
+ }
|
|
|
+ if (!props.item.filePath) {
|
|
|
+ message.error("没有生成wav文件");
|
|
|
+ handleClose();
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ model.saveLoading = true;
|
|
|
+ handleAutoProduct();
|
|
|
+ });
|
|
|
+ };
|
|
|
+ const handleSubmit = async () => {
|
|
|
+ await api_musicSheetCreationUpdate({
|
|
|
+ id: props.item.id,
|
|
|
+ subjectId: froms.subjectId,
|
|
|
+ filePath: props.item.filePath,
|
|
|
+ });
|
|
|
+ await wav2mp3();
|
|
|
+ model.saveProgress = 70;
|
|
|
+ if (!props.show) return;
|
|
|
+ await createMusic();
|
|
|
+ model.saveProgress = 100;
|
|
|
+ emit("success");
|
|
|
+ if (!props.show) return;
|
|
|
+ message.success("上传成功");
|
|
|
+ setTimeout(() => {
|
|
|
+ model.saveLoading = false;
|
|
|
+ emit("update:show", false);
|
|
|
+ }, 300);
|
|
|
+ };
|
|
|
+ return () => (
|
|
|
+ <>
|
|
|
+ <NModal
|
|
|
+ autoFocus={false}
|
|
|
+ show={props.show}
|
|
|
+ onUpdate:show={(val) => {
|
|
|
+ model.productOpen = false;
|
|
|
+ emit("update:show", val);
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <div class={styles.setbox}>
|
|
|
+ <div class={styles.head}>
|
|
|
+ <div>上传到我的资源</div>
|
|
|
+ <NButton
|
|
|
+ class={styles.close}
|
|
|
+ quaternary
|
|
|
+ circle
|
|
|
+ size="small"
|
|
|
+ onClick={() => {
|
|
|
+ model.productOpen = false;
|
|
|
+ emit("update:show", false);
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <NIcon component={Close} size={18} />
|
|
|
+ </NButton>
|
|
|
+ </div>
|
|
|
+ <NForm ref={fromRef} model={froms} class={styles.form} labelPlacement="left" showRequireMark={false}>
|
|
|
+ <NFormItem
|
|
|
+ label="可用声部"
|
|
|
+ path="subjectId"
|
|
|
+ rule={{
|
|
|
+ required: true,
|
|
|
+ type: "number",
|
|
|
+ message: "请选择素材可用乐器",
|
|
|
+ trigger: "change",
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <NSelect to="body" placeholder="请选择素材可用乐器" options={model.subjects} v-model:value={froms.subjectId}></NSelect>
|
|
|
+ </NFormItem>
|
|
|
+ {/* <NFormItem label="是否公开">
|
|
|
<NSpace class={styles.checkbox} wrapItem={false}>
|
|
|
<NButton
|
|
|
secondary
|
|
@@ -283,29 +301,29 @@ export default defineComponent({
|
|
|
</NButton>
|
|
|
</NSpace>
|
|
|
</NFormItem> */}
|
|
|
- <NFormItem label="上传进度" style={{ display: model.saveLoading ? "" : "none" }}>
|
|
|
- <div style={{display: 'flex', width: '100%', height: '46px', alignItems: 'center'}}>
|
|
|
- <NProgress percentage={model.saveProgress} />
|
|
|
- </div>
|
|
|
- </NFormItem>
|
|
|
- </NForm>
|
|
|
- <div class={styles.btns}>
|
|
|
- <NButton
|
|
|
- onClick={() => {
|
|
|
- model.productOpen = false;
|
|
|
- emit("update:show", false);
|
|
|
- }}
|
|
|
- >
|
|
|
- 取消
|
|
|
- </NButton>
|
|
|
- <NButton type="primary" loading={model.saveLoading} onClick={() => handleUpload()}>
|
|
|
- 确定
|
|
|
- </NButton>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </NModal>
|
|
|
- {model.productOpen && <iframe class={styles.productIframe} src={model.productIfameSrc}></iframe>}
|
|
|
- </>
|
|
|
- );
|
|
|
- },
|
|
|
+ <NFormItem label="上传进度" style={{ display: model.saveLoading ? "" : "none" }}>
|
|
|
+ <div style={{ display: "flex", width: "100%", height: "46px", alignItems: "center" }}>
|
|
|
+ <NProgress percentage={model.saveProgress} />
|
|
|
+ </div>
|
|
|
+ </NFormItem>
|
|
|
+ </NForm>
|
|
|
+ <div class={styles.btns}>
|
|
|
+ <NButton
|
|
|
+ onClick={() => {
|
|
|
+ model.productOpen = false;
|
|
|
+ emit("update:show", false);
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ 取消
|
|
|
+ </NButton>
|
|
|
+ <NButton type="primary" loading={model.saveLoading} onClick={() => handleUpload()}>
|
|
|
+ 确定
|
|
|
+ </NButton>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </NModal>
|
|
|
+ {model.productOpen && <iframe class={styles.productIframe} src={model.productIfameSrc}></iframe>}
|
|
|
+ </>
|
|
|
+ );
|
|
|
+ },
|
|
|
});
|