lex-xin 7 ماه پیش
والد
کامیت
321968c145

+ 6 - 4
public/osmd/index.html

@@ -111,18 +111,20 @@
       }, '*');
     }
 
-    function renderXml(xmlUrl, partIndex, isComberRender) {
+    function renderXml(xmlUrl, isComberRender, canSelectTracks) {
       osmd
         .load(xmlUrl)
         .then(
           function () {
             // 是否合并显示
-            // if (!isComberRender) {
+            // console.log(osmd.Sheet.Instruments, isComberRender, canSelectTracks, 'osmd.Sheet.Instruments')
+            // if (isComberRender) {
             //   for (let i = 0; i < osmd.Sheet.Instruments.length; i++) {
-            //     osmd.Sheet.Instruments[i].Visible = i === partIndex;
+            //     const trackName = osmd.Sheet.Instruments[i].Name || '';
+            //     console.log(trackName, 'trackName', canSelectTracks.includes(trackName))
+            //     osmd.Sheet.Instruments[i].Visible = canSelectTracks.includes(trackName)
             //   }
             // }
-
             osmd.zoom = .5
             render();
           }

تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 0 - 0
public/osmd/opensheetmusicdisplay.min.js


تفاوت فایلی نمایش داده نمی شود زیرا این فایل بسیار بزرگ است
+ 1 - 0
public/osmd/opensheetmusicdisplay.min1.js


+ 48 - 17
src/views/cloudPractice/cloudPractice.tsx

@@ -27,7 +27,7 @@ import {
 } from "@/api/cloudPractice.api"
 import axios from "axios"
 import { getInstrumentName } from "@/libs/instruments"
-import { formatXML, getCustomInfo, onlyVisible } from "./instrument"
+import { formatXML, getCustomInfo, onlyMutVisible, onlyVisible } from "./instrument"
 import { useFunction } from "./useData"
 import userStore from "@/store/modules/user"
 import PlayLoading from "./component/play-loading"
@@ -41,7 +41,7 @@ export default defineComponent({
    name: "cloudPractice",
    setup() {
       const userStoreHook = userStore()
-      const { goToCloud, isPracticeShow, practiceUrl, handlePracticeClose } = useFunction()
+      const { goToCloud, getPreViewCloud, isPracticeShow, practiceUrl, handlePracticeClose } = useFunction()
       const navs = [
          {
             name: "主页",
@@ -102,7 +102,8 @@ export default defineComponent({
                musicSheetType: item?.musicSheetType,
                audioFileUrl,
                // titleImg: list?.titleImg,
-               isComberRender: item?.isScoreRender,
+               isScoreRender: item?.isScoreRender,
+               defaultScoreRender: item?.defaultScoreRender,
                musicPdfUrl: item?.musicPdfUrl // 独奏使用PDF
             }
          } else if (userStoreHook.roles === "GYT") {
@@ -114,7 +115,8 @@ export default defineComponent({
                musicSheetType: list?.musicSheetType,
                audioFileUrl: list?.audioFileUrl,
                titleImg: list?.titleImg,
-               isComberRender: list?.musicSubjectId === "1",
+               isScoreRender: list?.isScoreRender,
+               defaultScoreRender: list?.defaultScoreRender,
                musicPdfUrl: list?.musicPdfUrl
             }
          } else if (userStoreHook.roles === "KLX") {
@@ -127,7 +129,8 @@ export default defineComponent({
                musicSheetType: list?.musicSheetType,
                audioFileUrl: item?.audioFileUrl,
                titleImg: list?.titleImg,
-               isComberRender: false,
+               isScoreRender: false,
+               defaultScoreRender: false,
                musicPdfUrl: list?.musicPdfUrl
             }
          }
@@ -751,12 +754,28 @@ export default defineComponent({
             }
          })
          // 初始化数据
+         // 是否显示总谱
+         console.log(row, "rows")
+         if (row.isScoreRender) {
+            partColumns.value.unshift({
+               label: "总谱",
+               instrumentName: null,
+               track: null,
+               musicPdfUrl: "",
+               xmlIndex: 999,
+               value: 999
+            })
+
+            if (row.defaultScoreRender) {
+               state.selectedPartIndex = 999
+            }
+         }
 
-         const defaultShowStaff = partColumns.value[state.selectedPartIndex]
+         const defaultShowStaff = partColumns.value.find((item: any) => item.value === state.selectedPartIndex)
          state.selectedPartName = defaultShowStaff?.instrumentName
          state.selectedTrack = defaultShowStaff?.track
          state.partXmlIndex = defaultShowStaff?.xmlIndex
-         if (row.isComberRender) {
+         if (row.isScoreRender && row.defaultScoreRender) {
             state.musicPdfUrl = row?.musicPdfUrl || ""
          } else {
             state.musicPdfUrl = defaultShowStaff?.musicPdfUrl || ""
@@ -780,32 +799,40 @@ export default defineComponent({
       }
 
       const musicIframeLoad = async () => {
+         if (userStoreHook.roles === "GYM") return
          const iframeRef: any = document.getElementById("staffIframeRef")
-         if (iframeRef && iframeRef.contentWindow.renderXml) {
+         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.isComberRender) {
-               iframeRef.contentWindow.renderXml(xml, state.partXmlIndex, activeItem.value.isComberRender)
+            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, state.partXmlIndex, activeItem.value.isComberRender)
+               iframeRef.contentWindow.renderXml(currentXml)
             }
          }
       }
       const resetRender = async () => {
+         if (userStoreHook.roles === "GYM") return
          const iframeRef: any = document.getElementById("staffIframeRef")
-         if (iframeRef && iframeRef.contentWindow.renderXml) {
+         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.isComberRender) {
-               iframeRef.contentWindow.renderXml(xml, state.partXmlIndex, activeItem.value.isComberRender)
+            if (activeItem.value.isScoreRender) {
+               iframeRef.contentWindow.renderXml(xml, activeItem.value.isScoreRender)
             } else {
                const currentXml = onlyVisible(xml, state.partXmlIndex)
-               iframeRef.contentWindow.renderXml(currentXml, 0, activeItem.value.isComberRender)
+               iframeRef.contentWindow.renderXml(currentXml)
             }
          }
       }
@@ -818,7 +845,11 @@ export default defineComponent({
                // https://cdn.oss.dayaedu.com/daya202409/UOFVK2A.pdf
                // https://cdn.oss.dayaedu.com/daya202409/UODQffO.pdf
             } else {
-               state.iframeSrc = `/osmd/index.html`
+               if (userStoreHook.roles === "GYM") {
+                  state.iframeSrc = getPreViewCloud(activeItem.value.id, state.partXmlIndex)
+               } else {
+                  state.iframeSrc = `/osmd/index.html`
+               }
             }
          } catch (error) {
             //
@@ -1264,7 +1295,7 @@ export default defineComponent({
                               state.partXmlIndex = item.xmlIndex
                               nextTick(() => {
                                  let tempPdf = ""
-                                 if (activeItem.value?.isComberRender) {
+                                 if (activeItem.value?.isScoreRender) {
                                     if (activeItem.value?.musicPdfUrl) {
                                        tempPdf = activeItem.value?.musicPdfUrl
                                     }

+ 88 - 68
src/views/cloudPractice/instrument.ts

@@ -49,6 +49,94 @@ export const formatXML = (xml: string): string => {
    return new XMLSerializer().serializeToString(xmlParse)
 }
 
+export const onlyMutVisible = (xml: string, partIndexs: number[]): string => {
+   if (!xml) return ""
+   const xmlParse = new DOMParser().parseFromString(xml, "text/xml")
+   const partList = xmlParse.getElementsByTagName("part-list")?.[0]?.getElementsByTagName("score-part") || []
+   const partListNames = Array.from(partList).map(item => item.getElementsByTagName("part-name")?.[0].textContent || "")
+   const parts: any = xmlParse.getElementsByTagName("part")
+   const part: any = parts[0]
+   const firstMeasures = [...part.getElementsByTagName("measure")]
+   const metronomes = [...part.getElementsByTagName("metronome")]
+
+   /** 第一分谱如果是约定的配置分谱则跳过 */
+   if (partListNames[0]?.toLocaleUpperCase?.() === "COMMON") {
+      // partIndex++
+      partIndexs.forEach((item: any) => {
+         item++
+      })
+      partListNames.shift()
+   }
+   const ids: any = []
+   partIndexs.forEach((partIndex: any) => {
+      const visiblePartInfo = partList[partIndex]
+      console.log(visiblePartInfo, partIndex)
+      if (visiblePartInfo) {
+         const id = visiblePartInfo.getAttribute("id")
+         ids.push(id)
+      }
+   })
+   if (ids.length > 0) {
+      Array.from(parts).forEach((part: any) => {
+         const attrId = part?.getAttribute("id")
+         if (part && !ids.includes(attrId)) {
+            part.parentNode?.removeChild(part)
+            // 不等于第一行才添加避免重复添加
+         } else if (part && attrId !== "P1") {
+            // 速度标记仅保留最后一个
+            const metronomeData: {
+               [key in string]: Element
+            } = {}
+            for (let i = 0; i < metronomes.length; i++) {
+               const metronome = metronomes[i]
+               const metronomeContainer = metronome.parentElement?.parentElement?.parentElement
+               if (metronomeContainer) {
+                  const index = firstMeasures.indexOf(metronomeContainer)
+                  metronomeData[index] = metronome
+               }
+            }
+            Object.values(metronomeData).forEach(metronome => {
+               const metronomeContainer: any = metronome.parentElement?.parentElement
+               const parentMeasure: any = metronomeContainer?.parentElement
+               const measureMetronomes = [...(parentMeasure?.childNodes || [])]
+               const metronomesIndex = metronomeContainer ? measureMetronomes.indexOf(metronomeContainer) : -1
+               // console.log(parentMeasure)
+               if (parentMeasure && metronomesIndex > -1) {
+                  const index = firstMeasures.indexOf(parentMeasure)
+                  const activeMeasure = part.getElementsByTagName("measure")[index]
+                  setElementNoteBefore(metronomeContainer, parentMeasure, activeMeasure)
+               }
+            })
+         }
+
+         // 最后一个小节的结束线元素不在最后 调整
+         if (part && ids.includes(attrId)) {
+            const barlines = part.getElementsByTagName("barline")
+            const lastParent = barlines[barlines.length - 1]?.parentElement
+            if (lastParent?.lastElementChild?.tagName !== "barline") {
+               const children: any = lastParent?.children || []
+               for (const el of children) {
+                  if (el.tagName === "barline") {
+                     // 将结束线元素放到最后
+                     lastParent?.appendChild(el)
+                     break
+                  }
+               }
+            }
+         }
+      })
+      Array.from(partList).forEach(part => {
+         const attrId = part?.getAttribute("id")
+         if (part && !ids.includes(attrId)) {
+            part.parentNode?.removeChild(part)
+         }
+      })
+   }
+
+   console.log(xmlParse)
+   return new XMLSerializer().serializeToString(appoggianceFormate(xmlParse))
+}
+
 export const onlyVisible = (xml: string, partIndex: number): string => {
    if (!xml) return ""
    const xmlParse = new DOMParser().parseFromString(xml, "text/xml")
@@ -99,76 +187,8 @@ export const onlyVisible = (xml: string, partIndex: number): string => {
                   const index = firstMeasures.indexOf(parentMeasure)
                   const activeMeasure = part.getElementsByTagName("measure")[index]
                   setElementNoteBefore(metronomeContainer, parentMeasure, activeMeasure)
-                  //   console.log(measureMetronomes, metronomesIndex, activeMeasure?.childNodes, activeMeasure?.childNodes[metronomesIndex])
-                  //   activeMeasure?.insertBefore(metronomeContainer.cloneNode(true), activeMeasure?.childNodes[metronomesIndex])
-                  //   // part.getElementsByTagName('measure')[index]?.appendChild(metronomeContainer.cloneNode(true))
-                  //   // console.log(index, parentMeasure, firstMeasures.indexOf(parentMeasure))
                }
             })
-            /** word比较特殊需要精确到note位置 */
-            // words.forEach((word) => {
-            //   let text = word.textContent || ""
-            //   text = ["cresc."].includes(text) ? "" : text
-            //   if ((isSpecialMark(text) || isSpeedKeyword(text) || isGradientWords(text) || isRepeatWord(text) || GRADIENT_SPEED_RESET_TAG) && text) {
-            //     const wordContainer = word.parentElement?.parentElement
-            //     const parentMeasure = wordContainer?.parentElement
-            //     const measureWords = [...(parentMeasure?.childNodes || [])]
-            //     const wordIndex = wordContainer ? measureWords.indexOf(wordContainer) : -1
-            //     if (wordContainer && parentMeasure && wordIndex > -1) {
-            //       const index = firstMeasures.indexOf(parentMeasure)
-            //       const activeMeasure = part.getElementsByTagName("measure")[index]
-            //       // 找当前小节是否包含word标签
-            //       const _words: any = Array.from(activeMeasure?.getElementsByTagName("words") || [])
-            //       // 遍历word标签,检查是否和第一小节重复,如果有重复则不平移word
-            //       const total = _words.reduce((total: any, _word) => {
-            //         if (_word.textContent?.includes(text)) {
-            //           total++
-            //         }
-            //         return total
-            //       }, 0)
-            //       if (total === 0) {
-            //         setElementNoteBefore(wordContainer, parentMeasure, activeMeasure)
-
-            //       }
-            //     }
-            //   }
-            // })
-            /** word比较特殊需要精确到note位置 */
-            // codas.forEach((coda) => {
-            //   const wordContainer = coda.parentElement?.parentElement
-            //   const parentMeasure = wordContainer?.parentElement
-            //   const measureWords = [...(parentMeasure?.childNodes || [])]
-            //   const wordIndex = wordContainer ? measureWords.indexOf(wordContainer) : -1
-            //   if (wordContainer && parentMeasure && wordIndex > -1) {
-            //     const index = firstMeasures.indexOf(parentMeasure)
-            //     const activeMeasure = part.getElementsByTagName("measure")[index]
-
-            //     setElementNoteBefore(wordContainer, parentMeasure, activeMeasure)
-
-            //   }
-            // })
-            // rehearsals.forEach((rehearsal) => {
-            //   const container = rehearsal.parentElement?.parentElement
-            //   const parentMeasure = container?.parentElement
-            //   // console.log(rehearsal)
-            //   if (parentMeasure) {
-            //     const index = firstMeasures.indexOf(parentMeasure)
-            //     part.getElementsByTagName("measure")[index]?.appendChild(container.cloneNode(true))
-            //     // console.log(index, parentMeasure, firstMeasures.indexOf(parentMeasure))
-            //   }
-            // })
-         } else {
-            // words.forEach((word) => {
-            //   const text = word.textContent || ""
-            //   if (isSpeedKeyword(text) && text) {
-            //     const wordContainer = word.parentElement?.parentElement?.parentElement
-            //     if (wordContainer && wordContainer.firstElementChild && wordContainer.firstElementChild !== word) {
-            //       const wordParent = word.parentElement?.parentElement
-            //       const fisrt = wordContainer.firstElementChild
-            //       wordContainer.insertBefore(wordParent, fisrt)
-            //     }
-            //   }
-            // })
          }
 
          // 最后一个小节的结束线元素不在最后 调整

+ 11 - 1
src/views/cloudPractice/useData.ts

@@ -36,7 +36,17 @@ export const useFunction = () => {
       isPracticeShow.value = false
       practiceUrl.value = ""
    }
-   return { loading, goToCloud, isPracticeShow, practiceUrl, handlePracticeClose }
+
+   function getPreViewCloud(musicId: string, partIndex = 0) {
+      //  GYM,GYT,KLX 区分   云教练
+      const urlObj = {
+         GYT: `${URL_TEACH_GYT}?id=${musicId}&modelType=practice&modeType=json&part-index=${partIndex}&Authorization=${getToken()}&isYjt=1&&isHideBack=false`,
+         GYM: `${URL_TEACH_GYM}#/detail/${musicId}?Authorization=${getToken()}&platform=web&part-index=${partIndex}&isPreView=true`,
+         KLX: `${URL_TEACH_KLX}?Authorization=${getToken()}&id=${musicId}&limitModel=practice&part-index=${partIndex}&isYjt=1&client=teacher`
+      }
+      return urlObj[userStoreHook.roles!]
+   }
+   return { loading, goToCloud, getPreViewCloud, isPracticeShow, practiceUrl, handlePracticeClose }
 }
 
 // function chunkArray(array: any[], size: number) {

برخی فایل ها در این مقایسه diff نمایش داده نمی شوند زیرا تعداد فایل ها بسیار زیاد است