import { computed, defineComponent, nextTick, onMounted, reactive, ref, shallowRef, watch } from "vue" import styles from "./index.module.scss" import NavContainer from "@/businessComponents/navContainer" import { ElEmpty, ElMessage, ElScrollbar } from "element-plus" import Dictionary from "@/components/dictionary" import MyInput from "@/components/myInput" import { NImage, NPopselect, NSpin, NTooltip } from "naive-ui" import PlayItem from "./component/play-item" import icon_default from "../../img/cloudPractice/icon_default.png" import iconBtnPause from "../../img/cloudPractice/icon-btn-pause.png" import iconBtnPlay from "../../img/cloudPractice/icon-btn-play.png" import btnSubmit from "../../img/cloudPractice/btn-submit.png" import iconTransfer from "../../img/cloudPractice/icon-transfer.png" import iconDownload from "../../img/cloudPractice/icon-download.png" import { httpAjax, httpAjaxErrMsg } from "@/plugin/httpAjax" import { queryPage2_gym, queryPage2_gyt, queryPage2_klx, querySubjectIds_gym, querySubjectIds_gyt, querySubjectIds_klx, queryTree_gym, queryTree_gyt, queryTree_klx, selectCondition_klx, cbsDetail_gym } from "@/api/cloudPractice.api" import axios from "axios" import { getInstrumentName } from "@/libs/instruments" import { formatXML, getCustomInfo, onlyVisible } from "./instrument" import { useFunction } from "./useData" import userStore from "@/store/modules/user" import PlayLoading from "./component/play-loading" import PracticeForm from "@/businessComponents/practiceForm" import { saveAs } from "file-saver" import JSZip from "jszip" import { canvasAddTitle, imgToCanvas, svgtoblob } from "./formatSvgToImg" import { penShow, whitePenShow } from "@/businessComponents/globalTools/globalTools" import { handleFullscreen } from "@/libs/fullscreen" export default defineComponent({ name: "cloudPractice", setup() { const userStoreHook = userStore() const { goToCloud, getPreViewCloud, isPracticeShow, practiceUrl, handlePracticeClose } = useFunction() const navs = [ { name: "主页", url: "/" }, { name: "云练习" } ] const spinRef = ref() const state = reactive({ finshed: false, reshing: false, page: 1, rows: 20, iframeSrc: "", listActive: 0, // 当前选中的对象 firstTreeId: null as any, // 左侧 categoryId: null as any, // 类型 categoryName: "" as any, // 类型名称 categoryList: [] as any[], levelList: [] as any[], // 级别 levelId: null as any, typeList: [] as any[], // 类型 typeId: -1 as any, subjectList: [] as any[], // 声部列表 subjectId: -1 as any, list: [] as any[], searchStatus: false, queryStr: "", // 搜索条件 partList: [] as any[], partNames: [] as any[], selectedPartName: "" as any, selectedTrack: "" as any, selectedPartIndex: 0, partXmlIndex: 0, musicPdfUrl: "", // 五线谱文件 imgs: [] as any[], // 图片列表 categoryShow: false, // 是否展开 playState: "pause" as "play" | "pause", // 播放状态 showPlayer: false // 是否显示播放器 }) const partColumns = ref([]) /** 选中的item */ const activeItem = computed(() => { const list = state.list[state.listActive] || {} let tempList: any = {} if (userStoreHook.roles === "GYM") { const item = list.background?.[0] const audioFileUrl = item?.musicSheetType === "CONCERT" ? item?.metronomeUrl : item?.metronomeMp3Url || item?.mp3Url tempList = { id: item?.id, name: item?.examSongName, background: list?.background, xmlUrl: item?.xmlUrl, musicSheetType: item?.musicSheetType, audioFileUrl, // titleImg: list?.titleImg, musicImg: list.musicImg, musicJianImg: list.musicJianSvg, musicFirstImg: list.musicFirstSvg, isScoreRender: item?.isScoreRender, defaultScoreRender: item?.defaultScoreRender, musicPdfUrl: item?.musicPdfUrl // 独奏使用PDF } } else if (userStoreHook.roles === "GYT") { tempList = { id: list?.id, name: list?.musicSheetName, background: list?.background, xmlUrl: list?.xmlFileUrl, musicSheetType: list?.musicSheetType, audioFileUrl: list?.audioFileUrl, titleImg: list?.titleImg, musicImg: list.musicImg, musicJianImg: list.musicJianSvg, musicFirstImg: list.musicFirstSvg, isScoreRender: list?.isScoreRender, defaultScoreRender: list?.defaultScoreRender, musicPdfUrl: list?.musicPdfUrl } } else if (userStoreHook.roles === "KLX") { const item: any = list.background?.[0] tempList = { id: list?.id, name: list?.musicSheetName, background: list?.background, xmlUrl: list?.xmlFileUrl, musicSheetType: list?.musicSheetType, audioFileUrl: item?.audioFileUrl, titleImg: list?.titleImg, musicImg: list.musicImg, musicJianImg: list.musicJianSvg, musicFirstImg: list.musicFirstSvg, isScoreRender: false, defaultScoreRender: false, musicPdfUrl: list?.musicPdfUrl } } return tempList }) const songPrevNextStatus = computed(() => { let prev = true, next = true if (state.listActive === 0) { prev = false } if (state.listActive >= state.list.length - 1) { next = false } return { prev, next } }) const downloadStatus = ref(false) const loading = ref(false) const staffLoading = ref(false) const storeData = shallowRef([]) const handleSearchList_gym = async () => { loading.value = true await httpAjaxErrMsg(queryTree_gym).then(async res => { loading.value = false if (res.code === 200) { storeData.value = res.data || [] await setDefaultData() } }) } const handleGetSubject_gym = async () => { loading.value = true await httpAjaxErrMsg(querySubjectIds_gym, { categoriesId: state.categoryId || state.firstTreeId }).then(res => { loading.value = false if (res.code === 200) { const result = res.data || [] state.subjectList = result.map((item: any) => { return { label: item.name, value: item.id, instrumentIds: item.instrumentIds } }) state.subjectList.unshift({ label: "全部声部", value: -1 }) const userSubjectId = userStoreHook.userInfo.subjectId if (userSubjectId) { const tempSubjectId = userSubjectId.split(",")[0] state.subjectList.forEach((item: any) => { // 判断是否存在声部编号 if (item.value === Number(tempSubjectId)) { state.subjectId = Number(tempSubjectId) } }) } } }) } const handleGetList_gym = async () => { loading.value = true const params = { page: state.page, rows: state.rows, subjectId: state.subjectId === -1 ? null : state.subjectId, categoriesId: state.typeId === -1 ? state.levelId : state.typeId, search: state.queryStr } await httpAjaxErrMsg(queryPage2_gym, params).then(res => { loading.value = false if (res.code === 200) { const result = res.data || [] if (state.reshing) { state.list = [] state.reshing = false } if (Array.isArray(result.rows)) { state.list = [...state.list, ...result.rows] state.finshed = state.page >= result.totalPage } else { state.finshed = true } } else { state.finshed = true } }) } /** 管乐团数据查询 */ const handleSearchList_gyt = async () => { loading.value = true await httpAjaxErrMsg(queryTree_gyt, { enable: true, page: 1, parentId: 0, rows: 10 }).then(res => { loading.value = false if (res.code === 200) { storeData.value = res.data || [] setDefaultData() } }) } const handleGetSubject_gyt = async () => { loading.value = true await httpAjaxErrMsg(querySubjectIds_gyt, { enableFlag: true, page: 1, rows: 100 }).then(res => { loading.value = false if (res.code === 200) { const result = res.data || [] state.subjectList = result.map((item: any) => { return { label: item.name, value: item.id, instrumentIds: item.instrumentIds } }) state.subjectList.unshift({ label: "全部声部", value: -1 }) const userSubjectId = userStoreHook.userInfo.subjectId if (userSubjectId) { const tempSubjectId = userSubjectId.split(",")[0] state.subjectList.forEach((item: any) => { // 判断是否存在声部编号 if (item.value === Number(tempSubjectId)) { state.subjectId = Number(tempSubjectId) } }) } } }) } const handleGetList_gyt = async () => { loading.value = true const params = { page: state.page, rows: state.rows, musicSubject: state.subjectId === -1 ? null : state.subjectId, musicSheetCategoriesId: state.typeId === -1 ? state.levelId : state.typeId, keyword: state.queryStr, detailFlag: true, status: 1 } await httpAjaxErrMsg(queryPage2_gyt, params).then(res => { loading.value = false if (res.code === 200) { const result = res.data || {} if (state.reshing) { state.list = [] state.reshing = false } if (Array.isArray(result.rows)) { result.rows.forEach((item: any) => { item.name = item.musicSheetName }) state.list = [...state.list, ...result.rows] state.finshed = state.page >= result.pages } else { state.finshed = true } } else { state.finshed = true } }) } /** 酷乐秀机构数据查询 */ const handleSearchList_klx = async () => { loading.value = true await httpAjaxErrMsg(queryTree_klx, { enable: true, page: 1, parentId: 0, rows: 10 }).then(async res => { loading.value = false if (res.code === 200) { const result = res.data || [] const tempList: any = [] result.forEach((item: any) => { if (item.musicNum > 0) { const subjectCounts = item.subjectCounts ? true : false const musicCounts = item.musicCounts ? true : false const ensembleCounts = item.ensembleCounts ? true : false const list: any = [] if (subjectCounts) { list.push({ label: "基础云练", value: "SUBJECT" }) } if (musicCounts) { list.push({ label: "独奏云练", value: "MUSIC" }) } if (ensembleCounts) { list.push({ label: "合奏云练", value: "ENSEMBLE" }) } tempList.push({ value: item.id, label: item.name, musicSheetCategoriesList: list }) } }) state.categoryList = tempList await setDefaultData() } else { state.finshed = true } }) } const handleGetSubject_klx = async () => { loading.value = true await httpAjaxErrMsg(querySubjectIds_klx, { queryType: "list", page: 1, rows: 100 }).then(res => { loading.value = false if (res.code === 200) { const result = res.data?.rows || [] state.subjectList = result.map((item: any) => { return { label: item.name, value: item.id, instrumentIds: item.instrumentIds } }) state.subjectList.unshift({ label: "全部声部", value: -1 }) const userSubjectId = userStoreHook.userInfo.subjectId if (userSubjectId) { const tempSubjectId = userSubjectId.split(",")[0] state.subjectList.forEach((item: any) => { // 判断是否存在声部编号 if (item.value === Number(tempSubjectId)) { state.subjectId = Number(tempSubjectId) } }) } } }) } const handleGetList_klx = async () => { if (!state.categoryId) return loading.value = true const params = { page: state.page, rows: state.rows, albumId: state.categoryId, subjectId: state.subjectId === -1 ? null : state.subjectId, subjectType: state.firstTreeId, level: state.levelId === -1 ? null : state.levelId, type: state.typeId === -1 ? null : state.typeId, keyword: state.queryStr } await httpAjaxErrMsg(queryPage2_klx, params).then(res => { loading.value = false if (res.code === 200) { const result = res.data || {} if (state.reshing) { state.list = [] state.reshing = false } if (Array.isArray(result.rows)) { result.rows.forEach((item: any) => { item.name = item.musicSheetName }) state.list = [...state.list, ...result.rows] state.finshed = state.page >= result.totalPage } else { state.finshed = true } } else { state.finshed = true } }) } const handleSelectCondition_klx = async () => { if (!state.categoryId || !state.firstTreeId) return loading.value = true const params = { tenantAlbumId: state.categoryId, subjectType: state.firstTreeId } await httpAjaxErrMsg(selectCondition_klx, params).then(res => { loading.value = false if (res.code === 200) { const result = res.data || {} if (result.levelList && result.levelList.length > 0) { state.levelList = result.levelList.map((item: any) => { return { label: item.value, value: item.id } }) state.levelList.unshift({ label: "全部级别", value: -1 }) state.levelId = -1 } else { state.levelList = [] } if (result.typeList && result.typeList.length > 0) { state.typeList = result.typeList.map((item: any) => { return { label: item.value, value: item.id } }) state.typeList.unshift({ label: "全部类型", value: -1 }) state.typeId = -1 } else { state.typeList = [] } } }) } /** 条件查询 */ const handleAllSearchList = async () => { // GYM,GYT,KLX 区分 查询搜索条件数据 if (userStoreHook.roles === "GYM") { await handleSearchList_gym() } else if (userStoreHook.roles === "GYT") { await handleSearchList_gyt() } else if (userStoreHook.roles === "KLX") { await handleSearchList_klx() } } const handleAllGetSubject = async () => { // GYM,GYT,KLX 区分 查询声部数据 if (userStoreHook.roles === "GYM") { await handleGetSubject_gym() } else if (userStoreHook.roles === "GYT") { await handleGetSubject_gyt() } else if (userStoreHook.roles === "KLX") { await handleGetSubject_klx() } } const handleAllGetList = async () => { // GYM,GYT,KLX 区分 查询声部数据· if (userStoreHook.roles === "GYM") { await handleGetList_gym() } else if (userStoreHook.roles === "GYT") { await handleGetList_gyt() } else if (userStoreHook.roles === "KLX") { await handleGetList_klx() } } /** 初始化数据 */ const setDefaultData = async (type?: "first" | "category" | "level" | "type") => { if (userStoreHook.roles === "GYM") { await initCategories_gym(type) } else if (userStoreHook.roles === "GYT") { initCategories_gyt(type) } else if (userStoreHook.roles === "KLX") { await initCategories_klx(type) } } const initCategories_gym = async (type?: "first" | "category" | "level" | "type") => { if (storeData.value.length > 0 && !["category", "level", "type"].includes(type as any)) { let result: any = [] if (type === "first" && state.firstTreeId) { result = storeData.value.find((item: any) => item.id === state.firstTreeId)?.sysMusicScoreCategoriesList || [] } else { state.firstTreeId = storeData.value[0]?.id result = storeData.value[0]?.sysMusicScoreCategoriesList || [] } state.categoryList = result.map((item: any) => { return { label: item.name, value: item.id, sysMusicScoreCategoriesList: item.sysMusicScoreCategoriesList || [] } }) state.categoryId = null state.categoryName = null state.levelId = null state.typeId = -1 } if (state.categoryList.length > 0 && !["level", "type"].includes(type as any)) { let result: any = [] if (type === "category" && state.categoryId) { result = state.categoryList.find((item: any) => item.value === state.categoryId)?.sysMusicScoreCategoriesList || [] } else { state.categoryId = state.categoryList[0]?.value state.categoryName = state.categoryList[0]?.label result = state.categoryList[0]?.sysMusicScoreCategoriesList || [] } state.levelList = result.map((item: any) => { return { label: item.name, value: item.id, sysMusicScoreCategoriesList: item.sysMusicScoreCategoriesList || [] } }) await handleGetSubject_gym() } if (state.levelList.length > 0) { let result: any = [] if (type === "level" && state.levelId) { result = state.levelList.find((item: any) => item.value === state.levelId)?.sysMusicScoreCategoriesList state.typeId = -1 } else { state.levelId = state.levelList[0]?.value result = state.levelList[0]?.sysMusicScoreCategoriesList || [] } state.typeList = result.map((item: any) => { return { label: item.name, value: item.id } }) state.typeList.unshift({ label: "全部", value: -1 }) } } const initCategories_gyt = (type?: "first" | "category" | "level" | "type") => { if (storeData.value.length > 0 && !["level", "type"].includes(type as any)) { let result: any = [] if (type === "first" && state.firstTreeId) { result = storeData.value.find((item: any) => item.id === state.firstTreeId)?.musicSheetCategoriesList || [] } else { state.firstTreeId = storeData.value[0]?.id result = storeData.value[0]?.musicSheetCategoriesList || [] } state.levelList = result.map((item: any) => { return { label: item.name, value: item.id, musicSheetCategoriesList: item.musicSheetCategoriesList || [] } }) state.levelId = null state.typeId = -1 } if (state.levelList.length > 0) { let result: any = [] if (type === "level" && state.levelId) { result = state.levelList.find((item: any) => item.value === state.levelId)?.musicSheetCategoriesList } else { state.levelId = state.levelList[0]?.value result = state.levelList[0]?.musicSheetCategoriesList || [] } state.typeList = result.map((item: any) => { return { label: item.name, value: item.id } }) state.typeList.unshift({ label: "全部", value: -1 }) state.typeId = -1 } } const initCategories_klx = async (type?: "first" | "category" | "level" | "type") => { if (state.categoryList.length > 0 && !["level", "type", "first"].includes(type as any)) { let result: any = [] if (type === "category" && state.categoryId) { result = state.categoryList.find((item: any) => item.value === state.categoryId)?.musicSheetCategoriesList || [] } else { state.categoryId = state.categoryList[0]?.value state.categoryName = state.categoryList[0]?.label result = state.categoryList[0]?.musicSheetCategoriesList || [] } storeData.value = result.map((item: any) => { return { id: item.value, name: item.label } }) } if (storeData.value.length > 0 && !["level", "type"].includes(type as any)) { if (type === "first" && state.firstTreeId) { await handleSelectCondition_klx() } else { // state.firstTreeId = storeData.value[0]?.id await handleSelectCondition_klx() } state.levelId = -1 state.typeId = -1 } } const __init = async () => { await handleAllSearchList() await handleAllGetSubject() await handleAllGetList() await toDetail() renderStaff() } // 全屏显示 handleFullscreen(true, false) __init() const handleResh = () => { if (loading.value || state.finshed) return state.page = state.page + 1 handleAllGetList() } const handleGetList = async () => { if (loading.value) return state.listActive = 0 state.showPlayer = false state.playState = "pause" state.partNames = [] state.partList = [] state.selectedPartName = "" state.selectedTrack = "" state.selectedPartIndex = 0 // state.musicPdfUrl = "" state.partXmlIndex = 0 document.querySelector(".musicList-container")?.scroll(0, 0) state.page = 1 state.finshed = false state.reshing = true state.list = [] await handleAllGetList() } const toDetail = async () => { const row: any = activeItem.value state.imgs = [] if (row.musicSheetType === "SINGLE") { loading.value = false state.musicPdfUrl = row.musicPdfUrl if (userStoreHook.roles === "GYM") { const imgs = row.musicImg ? row.musicImg.split(",") : [] imgs.forEach(async (item: string, index: number) => { const imgCanvas = await imgToCanvas(item) const img = await canvasAddTitle(imgCanvas, row.name) state.imgs.push({ name: index + 1 + ".png", url: img }) }) } return } state.partNames = await getPartNames(row.xmlUrl) let partList = row.background || [] partList = partList.filter((item: any) => !item.track?.toLocaleUpperCase()?.includes("COMMON")) partColumns.value = partList.map((item: any, index: number) => { const instrumentName = getInstrumentName(item.track) const xmlIndex = state.partNames.findIndex((name: any) => name.trim() === item.track) let musicPdfUrl = "" if (userStoreHook.roles === "GYM") { musicPdfUrl = item.soundMusicPdfUrl } else if (userStoreHook.roles === "GYT") { musicPdfUrl = item.musicPdfUrl } else if (userStoreHook.roles === "KLX") { musicPdfUrl = item.musicPdfUrl } return { label: item.track + (instrumentName ? `(${instrumentName})` : ""), instrumentName: instrumentName, track: item.track, musicPdfUrl, xmlIndex, value: index } }) // 初始化数据 // 是否显示总谱 if (row.isScoreRender) { partColumns.value.unshift({ label: "总谱", instrumentName: null, track: null, musicPdfUrl: "", xmlIndex: 999, value: 999 }) if (row.defaultScoreRender) { state.selectedPartIndex = 999 } } // gym 现在单独处理 管乐迷根据查询条件来筛选谱面 let defaultShowStaff if (userStoreHook.roles === "GYM") { // 这里筛选当前的声轨 const soundCodes = await filterSoundCodes() if (soundCodes) { const soundCodesArr = soundCodes.split(",").map((code: string) => { return code .toLowerCase() .replace(/^\d+|\d+$/g, "") .trim() }) defaultShowStaff = partColumns.value.find((item: any) => soundCodesArr.includes( item.track && item.track .toLowerCase() .replace(/^\d+|\d+$/g, "") .trim() ) ) } defaultShowStaff || (defaultShowStaff = partColumns.value.find((item: any) => item.value === state.selectedPartIndex)) } else { defaultShowStaff = partColumns.value.find((item: any) => item.value === state.selectedPartIndex) } state.selectedPartName = defaultShowStaff?.instrumentName state.selectedTrack = defaultShowStaff?.track state.partXmlIndex = defaultShowStaff?.xmlIndex state.selectedPartIndex = defaultShowStaff?.value if (row.isScoreRender && row.defaultScoreRender) { state.musicPdfUrl = row?.musicPdfUrl || "" } else { state.musicPdfUrl = defaultShowStaff?.musicPdfUrl || "" } } const getPartNames = async (xmlUrl: string) => { const partNames: string[] = [] try { const res: any = await axios.get(xmlUrl) const xml: any = new DOMParser().parseFromString(res.data, "text/xml") for (const item of xml.getElementsByTagName("part-name")) { if (item.textContent) { partNames.push(item.textContent) } } } catch (error) { // } return partNames.filter((text: string) => text.toLocaleUpperCase() !== "COMMON") || [] } const musicIframeLoad = async () => { if (userStoreHook.roles === "GYM") { // 判断是用哪个渲染的 loading.value = false staffLoading.value = false return } const iframeRef: any = document.getElementById("staffIframeRef") if (iframeRef && iframeRef.contentWindow?.renderXml) { staffLoading.value = true const res: any = await axios.get(activeItem.value.xmlUrl) const parseXmlInfo = getCustomInfo(res.data) const xml = formatXML(parseXmlInfo.parsedXML) console.log(activeItem.value, "activeItem.value") if (activeItem.value.isScoreRender) { const canSelectTracks: any = [] const background = activeItem.value.background || [] background.forEach((item: any) => { canSelectTracks.push(item.track) }) iframeRef.contentWindow.renderXml(xml, activeItem.value.isScoreRender) } else { const currentXml = onlyVisible(xml, state.partXmlIndex) iframeRef.contentWindow.renderXml(currentXml) } } } const resetRender = async () => { const iframeRef: any = document.getElementById("staffIframeRef") if (userStoreHook.roles === "GYM") { iframeRef.contentWindow.location.replace(getPreViewCloud(activeItem.value.id, state.partXmlIndex)) // state.iframeSrc = getPreViewCloud(activeItem.value.id, state.partXmlIndex) return } if (iframeRef && iframeRef.contentWindow?.renderXml) { staffLoading.value = true const res: any = await axios.get(activeItem.value.xmlUrl) const parseXmlInfo = getCustomInfo(res.data) const xml = formatXML(parseXmlInfo.parsedXML) if (activeItem.value.isScoreRender) { iframeRef.contentWindow.renderXml(xml, activeItem.value.isScoreRender) } else { const currentXml = onlyVisible(xml, state.partXmlIndex) iframeRef.contentWindow.renderXml(currentXml) } } } const renderStaff = async () => { try { if (state.musicPdfUrl) { state.iframeSrc = "/pdf/web/viewer.html?file=" + encodeURIComponent(state.musicPdfUrl) + "&t=" + Date.now() // https://cdn.oss.dayaedu.com/daya202409/UOFW4q5.pdf // https://cdn.oss.dayaedu.com/daya202409/UOFVK2A.pdf // https://cdn.oss.dayaedu.com/daya202409/UODQffO.pdf } else { if (userStoreHook.roles === "GYM") { state.iframeSrc = getPreViewCloud(activeItem.value.id, state.partXmlIndex) } else { state.iframeSrc = `/osmd/index.html` } } } catch (error) { // } } /** 音频控制 */ const handleChangeAudio = (type: "play" | "pause" | "pre" | "next") => { if (type === "play") { state.playState = "play" } else if (type === "pause") { state.playState = "pause" } else if (type === "pre") { if (state.list[state.listActive - 1]) { handlePlay(state.list[state.listActive - 1]) } } else if (type === "next") { if (state.list[state.listActive + 1]) { handlePlay(state.list[state.listActive + 1]) } } } /** 播放曲目 */ const handlePlay = (item: any) => { const index = state.list.findIndex((_item: any) => _item.id === item.id) if (index > -1) { if (state.listActive === index) { state.playState = state.playState === "play" ? "pause" : "play" } else { state.playState = "play" } state.showPlayer = true state.listActive = index } } // // 多个文件下载 const downLoadMultiFile = (files: any, filesName: string) => { const zip = new JSZip() for (const i in files) { zip.file(files[i].name, files[i].url, { binary: true }) } zip.generateAsync({ type: "blob" }).then(res => { saveAs(res, filesName ? filesName + ".zip" : `文件夹${Date.now()}.zip`) }) downloadStatus.value = false } const showLoading = async (e: any) => { if (e.data?.api === "musicStaffRender") { const musicName = activeItem.value.name + ((activeItem.value.musicSheetType === "CONCERT" && state.selectedPartName) || state.selectedTrack ? `(${state.selectedPartName || state.selectedTrack})` : "") try { const osmdImg = e.data.osmdImg const imgs = [] for (let i = 0; i < osmdImg.length; i++) { const img = await svgtoblob(osmdImg[i].img, osmdImg[i].width, osmdImg[i].height, musicName) imgs.push({ url: img, name: i + 1 + ".png" }) } state.imgs = imgs } catch (e) { // console.log(e); } staffLoading.value = e.data.loading loading.value = e.data.loading } } const searchContent = async () => { await toDetail() if (activeItem.value?.id) { if (state.musicPdfUrl) { staffLoading.value = true renderStaff() } else { // 为了处理,之前是使用pdf渲染,现在又用osmd,iframe没有重新加载 if (state.iframeSrc.indexOf("pdf/web") !== -1) { renderStaff() } else { resetRender() } } } } /** 下载图片 */ const onDownload = () => { if (downloadStatus.value || staffLoading.value) return const musicName = activeItem.value.name + ((activeItem.value.musicSheetType === "CONCERT" && state.selectedPartName) || state.selectedTrack ? `(${state.selectedPartName || state.selectedTrack})` : "") downloadStatus.value = true if (state.musicPdfUrl) { // 发起Fetch请求 fetch(state.musicPdfUrl) .then(response => response.blob()) .then(blob => { saveAs(blob, musicName) downloadStatus.value = false }) .catch(() => { ElMessage.error("下载失败") downloadStatus.value = false }) } else { downLoadMultiFile(state.imgs, musicName) } } // 根据当前选中的声部和曲目筛选出对应的声轨 async function filterSoundCodes() { const { id } = state.list[state.listActive] || {} if (!id) { return undefined } const { instrumentIds } = state.subjectList.find((item: any) => { return item.value === state.subjectId }) || {} if (instrumentIds) { // GYM,GYT,KLX 区分 查询声部数据 let cbsDetails: any = [] if (userStoreHook.roles === "GYM") { const resData = await httpAjax(cbsDetail_gym, id) if (resData.code === 200) { cbsDetails = resData.data.musicalInstruments } } else if (userStoreHook.roles === "GYT") { // } else if (userStoreHook.roles === "KLX") { // } const { code } = cbsDetails.find((item: any) => { return instrumentIds == item.id }) || {} return code } return undefined } // 白板的批注打开时暂停播放 watch( () => [whitePenShow.value, penShow.value], () => { if (whitePenShow.value || penShow.value) { handleChangeAudio("pause") } } ) onMounted(() => { const obv = new IntersectionObserver(entries => { if (entries[0].intersectionRatio > 0) { handleResh() } }) obv.observe(spinRef.value) window.addEventListener("message", showLoading) }) return () => ( {/* */}
{storeData.value.length > 0 && ( {/* 基 础 云 练 */} {storeData.value.map((item: any) => (
{ if (loading.value) return state.firstTreeId = item.id await setDefaultData("first") await handleGetList() searchContent() }} > {item.name}
))}
)}
{state.categoryList.length > 1 && (
{ const item = state.categoryList.find((item: any) => item.value === val) if (item) { state.categoryName = item.label state.categoryId = item.value await setDefaultData("category") await handleGetList() searchContent() } }} onUpdate:show={(value: any) => { state.categoryShow = value }} trigger="click" class={"PopSelect"} > {state.categoryName}
)}
{ await handleGetList() searchContent() }} /> {state.levelList.length ? ( { setDefaultData("level") await handleGetList() searchContent() }} /> ) : null} {state.typeList.length > 0 ? ( { await handleGetList() searchContent() }} /> ) : null}
(state.searchStatus = !state.searchStatus)} >
{state.searchStatus && ( { if (e.code === "Enter" || e.key === "Enter") { await handleGetList() searchContent() } }} onHandleQuery={async () => { await handleGetList() searchContent() }} clearable /> )}
{state.list.map((item: any, index: number) => (
{ if (index === state.listActive) { return } state.listActive = index state.selectedPartIndex = 0 state.partXmlIndex = 0 searchContent() }} >
{ ;(e.target as any).dataset.loaded = "true" }} />
{ e.stopPropagation() handlePlay(item) if (state.listActive !== index) { resetRender() } }} > {state.listActive === index && ( <> {state.playState === "pause" ? "播放" : "暂停"} )} {state.listActive !== index && ( <> 播放 )}
))} {!state.list.length && !loading.value && ( )}
{/* */} {activeItem.value?.id ? ( state.musicPdfUrl ? (
) : ( <>
{activeItem.value.name} {activeItem.value.musicSheetType === "CONCERT" && (state.selectedPartName || state.selectedTrack ? `(${state.selectedPartName || state.selectedTrack})` : "")}
) ) : (
{!loading.value && !activeItem.value?.id && ( )}
)}
{ handleChangeAudio("pause") goToCloud(activeItem.value.id, state.partXmlIndex) }} />
0 ? "" : "none" }}> {{ trigger: () => ( ), default: "下载曲谱" }}
{ const item = partColumns.value.find((item: any) => item.value === value) state.selectedPartIndex = value state.selectedPartName = item.instrumentName state.selectedTrack = item.track state.partXmlIndex = item.xmlIndex nextTick(() => { let tempPdf = "" if (activeItem.value?.isScoreRender && value === 999) { if (activeItem.value?.musicPdfUrl) { tempPdf = activeItem.value?.musicPdfUrl } } else { tempPdf = item.musicPdfUrl } if (tempPdf) { state.musicPdfUrl = tempPdf staffLoading.value = true renderStaff() } else { state.musicPdfUrl = "" loading.value = true // 为了处理,之前是使用pdf渲染,现在又用osmd,iframe没有重新加载 if (state.iframeSrc.indexOf("pdf/web") !== -1) { renderStaff() } else { resetRender() } } }) }} class={["PopSelect", "PopSelectPart"]} > {{ empty: () => "暂无数据", default: () => ( {{ trigger: () => , default: "切换声轨" }} ) }}
{/*
*/} {state.list.length !== 0 && activeItem.value.audioFileUrl && ( handleChangeAudio(value)} onShow={(status: boolean) => { state.showPlayer = status }} /> )}
) } })