Browse Source

Merge branch 'main' of http://git.dayaedu.com/huangqiyong/classroom into dev

黄琪勇 1 week ago
parent
commit
fced5136be

+ 0 - 0
dist/css/627.0f4157b7.css → dist/css/126.0f4157b7.css


+ 0 - 0
dist/css/679.4f636f8d.css → dist/css/410.4f636f8d.css


File diff suppressed because it is too large
+ 0 - 0
dist/css/639.f7d42cc1.css


+ 0 - 0
dist/css/921.03d5f75b.css → dist/css/676.03d5f75b.css


+ 0 - 0
dist/css/818.b0bf11db.css → dist/css/715.b0bf11db.css


File diff suppressed because it is too large
+ 0 - 0
dist/css/857.2be7450b.css


File diff suppressed because it is too large
+ 0 - 0
dist/css/995.5c07b075.css


+ 0 - 0
dist/css/app.2ae84a6b.css → dist/css/app.4dfcdb65.css


+ 4 - 0
dist/index.html

@@ -1,6 +1,10 @@
 <!doctype html><html lang=""><head><meta charset="utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="renderer" content="webkit"/><meta name="force-rendering" content="webkit"/><link rel="icon" href="/favicon.ico"/><title>乐教通</title><script>if (!!window.ActiveXObject || "ActiveXObject" in window) {
             window.location.href = "./ieIncompatible/index.html"
+<<<<<<< HEAD
          }</script><script defer="defer" src="/js/chunk-vendors.2d4da3d8.js"></script><script defer="defer" src="/js/app.0e5b4c86.js"></script><link href="/css/app.2ae84a6b.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but classroom doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"><style>.firstLoading {
+=======
+         }</script><script defer="defer" src="/js/chunk-vendors.a8b6f822.js"></script><script defer="defer" src="/js/app.c6c94e11.js"></script><link href="/css/app.4dfcdb65.css" rel="stylesheet"></head><body><noscript><strong>We're sorry but classroom doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"><style>.firstLoading {
+>>>>>>> 2bcded3c9a4f3862373bfb367fa79e8fe83f6d39
                position: fixed;
                left: 50%;
                top: 50%;

+ 1 - 0
dist/js/126.a1bd90eb.js

@@ -0,0 +1 @@
+"use strict";(self["webpackChunkclassroom"]=self["webpackChunkclassroom"]||[]).push([[126],{364:function(s,a,c){c.r(a),c.d(a,{default:function(){return f}});c(8743);var e=c(6768),n=c.p+"img/404.ee28d6e3.png",r=c(1387);const t=s=>((0,e.Qi)("data-v-7de45d1a"),s=s(),(0,e.jt)(),s),i={class:"errorPage"},d=t((()=>(0,e.Lk)("img",{class:"img",src:n},null,-1))),l=t((()=>(0,e.Lk)("div",{class:"errName"},"糟糕,页面找不到了",-1))),o=t((()=>(0,e.Lk)("div",{class:"title"},"您可以通过以下方式继续访问",-1)));var u=(0,e.pM)({__name:"errorPage",setup(s){const a=(0,r.rd)();function c(){a.push({path:"/"})}function n(){a.back()}return(s,a)=>((0,e.uX)(),(0,e.CE)("div",i,[(0,e.Lk)("div",{class:"error"},[d,l,o,(0,e.Lk)("div",{class:"btnCon"},[(0,e.Lk)("div",{class:"btn",onClick:c},"跳转到首页"),(0,e.Lk)("div",{class:"btn",onClick:n},"返回上一步")])])]))}}),k=c(1241);const v=(0,k.A)(u,[["__scopeId","data-v-7de45d1a"]]);var p=v,f=p}}]);

File diff suppressed because it is too large
+ 0 - 0
dist/js/217.f3a46cb0.js


File diff suppressed because it is too large
+ 0 - 0
dist/js/410.c977ea99.js


+ 0 - 1
dist/js/627.863acaac.js

@@ -1 +0,0 @@
-"use strict";(self["webpackChunkclassroom"]=self["webpackChunkclassroom"]||[]).push([[627],{6688:function(s,a,c){c.r(a),c.d(a,{default:function(){return f}});c(7658);var n=c(3396),e=c.p+"img/404.ee28d6e3.png",r=c(2483);const t=s=>((0,n.dD)("data-v-7de45d1a"),s=s(),(0,n.Cn)(),s),i={class:"errorPage"},d=t((()=>(0,n._)("img",{class:"img",src:e},null,-1))),l=t((()=>(0,n._)("div",{class:"errName"},"糟糕,页面找不到了",-1))),o=t((()=>(0,n._)("div",{class:"title"},"您可以通过以下方式继续访问",-1)));var u=(0,n.aZ)({__name:"errorPage",setup(s){const a=(0,r.tv)();function c(){a.push({path:"/"})}function e(){a.back()}return(s,a)=>((0,n.wg)(),(0,n.iD)("div",i,[(0,n._)("div",{class:"error"},[d,l,o,(0,n._)("div",{class:"btnCon"},[(0,n._)("div",{class:"btn",onClick:c},"跳转到首页"),(0,n._)("div",{class:"btn",onClick:e},"返回上一步")])])]))}}),v=c(89);const _=(0,v.Z)(u,[["__scopeId","data-v-7de45d1a"]]);var p=_,f=p}}]);

File diff suppressed because it is too large
+ 0 - 0
dist/js/639.07073b8c.js


File diff suppressed because it is too large
+ 0 - 0
dist/js/676.0e117e8a.js


File diff suppressed because it is too large
+ 0 - 0
dist/js/679.60034639.js


File diff suppressed because it is too large
+ 0 - 0
dist/js/715.cbcc1d07.js


File diff suppressed because it is too large
+ 0 - 0
dist/js/857.edaf73ae.js


File diff suppressed because it is too large
+ 0 - 0
dist/js/929.5eee6bc2.js


File diff suppressed because it is too large
+ 0 - 0
dist/js/995.023672de.js


File diff suppressed because it is too large
+ 0 - 0
dist/js/app.c6c94e11.js


File diff suppressed because it is too large
+ 0 - 0
dist/js/chunk-vendors.a8b6f822.js


+ 132 - 100
src/api/cloudPractice.api.ts

@@ -1,100 +1,132 @@
-import {
-   httpAxios_gym,
-   httpAxios_gyt,
-   httpAxios_klx
-   // httpAxios_gyt
-} from "@/api/ApiInstance"
-
-/** 管乐迷 */
-export const queryTree_gym = () => {
-   return httpAxios_gym.axioseRquest({
-      method: "get",
-      url: "/api-teacher/sysMusicScoreCategories/queryTree"
-   })
-}
-
-export const querySubjectIds_gym = (data?: any) => {
-   return httpAxios_gym.axioseRquest({
-      method: "get",
-      url: "/api-teacher/sysMusicScoreAccompaniment/querySubjectIds",
-      params: data
-   })
-}
-
-export const queryPage2_gym = (data: any) => {
-   return httpAxios_gym.axioseRquest({
-      method: "get",
-      url: "/api-teacher/sysMusicScore/queryPageSimple",
-      params: data
-   })
-}
-
-export const cbsDetail_gym = (id: number, data = {}) => {
-   return httpAxios_gym.axioseRquest({
-      method: "get",
-      url: `/api-teacher/musicSheet/cbsDetail/${id}`,
-      params: data
-   })
-}
-
-/**
- * 管乐团
- */
-export const queryTree_gyt = (data: any) => {
-   return httpAxios_gyt.axioseRquest({
-      method: "post",
-      url: "/api-teacher/musicSheetCategories/page",
-      data
-   })
-}
-
-export const querySubjectIds_gyt = (data?: any) => {
-   return httpAxios_gyt.axioseRquest({
-      method: "get",
-      url: "/api-teacher/subject/musicList",
-      params: data
-   })
-}
-
-export const queryPage2_gyt = (data: any) => {
-   return httpAxios_gyt.axioseRquest({
-      method: "post",
-      url: "/api-teacher/musicSheet/page",
-      data
-   })
-}
-
-/**
- * 酷乐秀
- */
-export const queryTree_klx = (data?: any) => {
-   return httpAxios_klx.axioseRquest({
-      method: "get",
-      url: "/api-teacher/tenantGroupAlbum/buyAlbumInfo",
-      params: data
-   })
-}
-
-export const querySubjectIds_klx = (data?: any) => {
-   return httpAxios_klx.axioseRquest({
-      method: "get",
-      url: "/api-teacher/open/subject/queryPage",
-      params: data
-   })
-}
-
-export const queryPage2_klx = (data: any) => {
-   return httpAxios_klx.axioseRquest({
-      method: "post",
-      url: "/api-teacher/tenantAlbumMusic/page",
-      data
-   })
-}
-
-export const selectCondition_klx = (data: any) => {
-   return httpAxios_klx.axioseRquest({
-      method: "post",
-      url: "/api-teacher/tenantGroupAlbum/selectCondition",
-      data
-   })
-}
+import {
+   httpAxios_gym,
+   httpAxios_gyt,
+   httpAxios_klx
+   // httpAxios_gyt
+} from "@/api/ApiInstance"
+
+/** 管乐迷 */
+export const queryTree_gym = () => {
+   return httpAxios_gym.axioseRquest({
+      method: "get",
+      url: "/api-teacher/sysMusicScoreCategories/queryTree"
+   })
+}
+
+export const querySubjectIds_gym = (data?: any) => {
+   return httpAxios_gym.axioseRquest({
+      method: "get",
+      url: "/api-teacher/sysMusicScoreAccompaniment/querySubjectIds",
+      params: data
+   })
+}
+
+export const queryPage2_gym = (data: any) => {
+   return httpAxios_gym.axioseRquest({
+      method: "get",
+      url: "/api-teacher/sysMusicScore/queryPageSimple",
+      params: data
+   })
+}
+
+export const cbsDetail_gym = (id: number, data = {}) => {
+   return httpAxios_gym.axioseRquest({
+      method: "get",
+      url: `/api-teacher/musicSheet/cbsDetail/${id}`,
+      params: data
+   })
+}
+
+export const instrumentCode_gym = (data: any) => {
+   return httpAxios_gym.axioseRquest({
+      method: "get",
+      url: "/api-teacher/musicSheet/instrumentCode",
+      params: data
+   })
+}
+
+/**
+ * 管乐团
+ */
+export const queryTree_gyt = (data: any) => {
+   return httpAxios_gyt.axioseRquest({
+      method: "post",
+      url: "/api-teacher/musicSheetCategories/page",
+      data
+   })
+}
+
+export const querySubjectIds_gyt = (data?: any) => {
+   return httpAxios_gyt.axioseRquest({
+      method: "get",
+      url: "/api-teacher/subject/musicList",
+      params: data
+   })
+}
+
+export const queryPage2_gyt = (data: any) => {
+   return httpAxios_gyt.axioseRquest({
+      method: "post",
+      url: "/api-teacher/musicSheet/page",
+      data
+   })
+}
+
+export const instrumentCode_gyt = (data: any) => {
+   return httpAxios_gyt.axioseRquest({
+      method: "get",
+      url: "/api-teacher/musicSheet/instrumentCode",
+      params: data
+   })
+}
+
+/**
+ * 酷乐秀
+ */
+export const queryTree_klx = (data?: any) => {
+   return httpAxios_klx.axioseRquest({
+      method: "get",
+      url: "/api-teacher/tenantGroupAlbum/buyAlbumInfo",
+      params: data
+   })
+}
+
+export const querySubjectIds_klx = (data?: any) => {
+   return httpAxios_klx.axioseRquest({
+      method: "get",
+      url: "/api-teacher/open/subject/queryPage",
+      params: data
+   })
+}
+
+export const queryPage2_klx = (data: any) => {
+   return httpAxios_klx.axioseRquest({
+      method: "post",
+      url: "/api-teacher/tenantAlbumMusic/pageSimple",
+      data
+   })
+}
+
+export const selectCondition_klx = (data: any) => {
+   return httpAxios_klx.axioseRquest({
+      method: "post",
+      url: "/api-teacher/tenantGroupAlbum/selectCondition",
+      data
+   })
+}
+
+export const cbsDetail_klx = (id: number, data = {}) => {
+   return httpAxios_klx.axioseRquest({
+      method: "get",
+      url: `/api-teacher/musicSheet/cbsDetail/${id}`,
+      params: data
+   })
+}
+
+export const instrumentCode_klx = (data: any) => {
+   return httpAxios_klx.axioseRquest({
+      method: "get",
+      url: "/api-teacher/music/sheet/instrumentCode",
+      params: data
+   })
+}

BIN
src/img/coursewarePlay/back.png


+ 232 - 230
src/libs/instruments.ts

@@ -1,230 +1,232 @@
-const instruments: any = {
-   "Acoustic Grand Piano": "大钢琴",
-   "Bright Acoustic Piano": "明亮的钢琴",
-   "Electric Grand Piano": "电钢琴",
-   "Rhodes Piano": "柔和的电钢琴",
-   "Chorused Piano": "加合唱效果的电钢琴",
-   Harpsichord: "羽管键琴",
-   Clavichord: "科拉维科特琴",
-   Celesta: "钢片琴",
-   Glockenspiel: "钢片琴",
-   "Music box": "八音盒",
-   Vibraphone: "颤音琴",
-   Marimba: "马林巴",
-   Xylophone: "木琴",
-   "Tubular Bells": "管钟",
-   Dulcimer: "大扬琴",
-   "Hammond Organ": "击杆风琴",
-   "Percussive Organ": "打击式风琴",
-   "Rock Organ": "摇滚风琴",
-   "Church Organ": "教堂风琴",
-   "Reed Organ": "簧管风琴",
-   Accordian: "手风琴",
-   Harmonica: "口琴",
-   "Tango Accordian": "探戈手风琴",
-   "Acoustic Guitar": "钢弦吉他",
-   "Electric Guitar": "闷音电吉他",
-   "Overdriven Guitar": "加驱动效果的电吉他",
-   "Distortion Guitar": "加失真效果的电吉他",
-   "Guitar Harmonics": "吉他和音",
-   "Acoustic Bass": "大贝司",
-   "Electric Bass": "电贝司",
-   "Fretless Bass": "无品贝司",
-   "Slap Bass": "掌击",
-   "Synth Bass": "电子合成",
-   Violin: "小提琴",
-   Viola: "中提琴",
-   Cello: "大提琴",
-   Contrabass: "低音大提琴",
-   "Tremolo Strings": "弦乐群颤音音色",
-   "Pizzicato Strings": "弦乐群拨弦音色",
-   "Orchestral Harp": "竖琴",
-   Timpani: "定音鼓",
-   "String Ensemble": "弦乐合奏音色",
-   "Synth Strings": "合成弦乐合奏音色",
-   "Choir Aahs": "人声合唱",
-   "Voice Oohs": "人声",
-   "Synth Voice": "合成人声",
-   "Orchestra Hit": "管弦乐敲击齐奏",
-   Trumpet: "小号",
-   Trombone: "长号",
-   Tuba: "大号",
-   "Muted Trumpet": "加弱音器小号",
-   "French Horn": "法国号",
-   "Brass Section": "铜管组",
-   "Synth Brass": "合成铜管音色",
-   "Soprano Sax": "高音萨克斯管",
-   "Alto Sax": "中音萨克斯管",
-   "Tenor Sax": "次中音萨克斯管",
-   "Baritone Sax": "低音萨克斯管",
-   Oboe: "双簧管",
-   "English Horn": "英国管",
-   Bassoon: "巴松",
-   "Soprano Saxophone": "高音萨克斯管",
-   "Alto Saxophone": "中音萨克斯管",
-   "Tenor Saxophone": "次中音萨克斯管",
-   "Baritone Saxophone": "低音萨克斯管",
-   Piccolo: "短笛",
-   Flute: "长笛",
-   Recorder: "竖笛",
-   "Soprano Recorder": "高音竖笛",
-   "Pan Flute": "排箫",
-   "Bottle Blow": "瓶木管",
-   Whistle: "口哨声",
-   Ocarina: "陶笛",
-   Lead: "合成主音",
-   "Lead lead": "合成主音",
-   "Pad age": "合成音色",
-   Pad: "合成音色",
-   FX: "合成效果  科幻",
-   Sitar: "西塔尔",
-   Banjo: "班卓琴",
-   Shamisen: "三昧线",
-   Koto: "十三弦筝",
-   Kalimba: "卡林巴",
-   Bagpipe: "风笛",
-   Fiddle: "民族提琴",
-   Shanai: "山奈",
-   "Tinkle Bell": "叮当铃",
-   Agogos: "阿戈戈铃",
-   "Steel Drums": "钢鼓",
-   "Taiko Drum": "太鼓",
-   "Melodic Toms": "嗵嗵鼓",
-   "Synth Drums": "合成鼓",
-   "Reverse Cymbals": "反向镲",
-   "Agogo Bells": "阿戈戈铃",
-   "Taiko Drums": "太鼓",
-   Bongos: "邦戈鼓",
-   "Bongo Bell": "邦戈铃",
-   Congas: "康加鼓",
-   Guiro: "刮壶",
-   "Guitar Fret Noise": "吉他换把杂音",
-   "Breath Noise": "呼吸声",
-   Seashore: "海浪声",
-   "Bird Tweet": "鸟鸣",
-   "Telephone Ring": "电话铃",
-   Helicopter: "直升机",
-   Applause: "鼓掌声",
-   Gunshot: "枪声",
-   "Acoustic Bass Drum": "大鼓",
-   "Bass Drum": "大鼓",
-   "Side Drum": "小鼓鼓边",
-   "Acoustic Snare": "小鼓",
-   "Hand Claps": "拍手",
-   "Electric Snare": "小鼓",
-   "Low Floor Tom": "低音嗵鼓",
-   "Closed Hi-Hat": "闭合踩镲",
-   "High Floor Tom": "高音落地嗵鼓",
-   "Pedal Hi-Hat": "脚踏踩镲",
-   "Low Tom": "低音嗵鼓",
-   "Open Hi-Hat": "开音踩镲",
-   "Low-Mid Tom": "中低音嗵鼓",
-   "Hi Mid Tom": "高音鼓",
-   "Crash Cymbals": "对镲",
-   "High Tom": "高音嗵鼓",
-   "Ride Cymbals": "叮叮镲",
-   "Chinese Cymbals": "中国镲",
-   "Ride Bell": "圆铃",
-   Tambourine: "铃鼓",
-   "Splash Cymbal": "溅音镲",
-   Cowbell: "牛铃",
-   "Crash Cymbal": "强音钹",
-   "Vibra-Slap": "颤音器",
-   "Ride Cymbal": "打点钹",
-   "Hi Bongo": "高音邦戈鼓",
-   "Low Bongo": "低音邦戈鼓",
-   "Mute Hi Conga": "弱音高音康加鼓",
-   "Open Hi Conga": "强音高音康加鼓",
-   "Low Conga": "低音康加鼓",
-   "High Timbale": "高音天巴鼓",
-   "Low Timbale": "低音天巴鼓",
-   "High Agogo": "高音阿戈戈铃",
-   "Low Agogo": "低音阿戈戈铃",
-   Cabasa: "卡巴萨",
-   Maracas: "沙锤",
-   "Short Whistle": "短口哨",
-   "Long Whistle": "长口哨",
-   "Short Guiro": "短刮壶",
-   "Long Guiro": "长刮壶",
-   Claves: "响棒",
-   "Hi Wood Block": "高音木鱼",
-   "Low Wood Block": "低音木鱼",
-   "Mute Triangle": "弱音三角铁",
-   "Open Triangle": "强音三角铁",
-   "Drum Set": "架子鼓",
-   "Hulusi flute": "葫芦丝",
-   Melodica: "口风琴",
-   "Snare Drum": "小军鼓",
-   "Horn in F": "圆号",
-   Triangle: "三角铁",
-   Vibrato: "颤音琴",
-   "Suspend Cymbals": "吊镲",
-   "Suspended Cymbals": "吊镲",
-   "Tom-Toms": "嗵嗵鼓",
-   Bell: "铃铛",
-   Bells: "铃铛",
-   "Alto Clarinet": "中音单簧管",
-   "Bass Clarinet": "低音单簧管",
-   Clarinet: "单簧管",
-   Cornet: "短号",
-   Euphonium: "上低音号",
-   "crash cymbals": "对镲",
-   Castanets: "响板",
-   Shaker: "沙锤",
-   "Mark tree": "音树",
-   Chimes: "管钟",
-   "Mark Tree": "音树",
-   "Tom-toms": "嗵嗵鼓",
-   "Hi-Hat": "踩镲",
-   "Sleigh Bells": "雪橇铃",
-   Flexatone: "弹音器",
-   "Brake drum": "闸鼓",
-   Gong: "锣",
-   "concert tom": "音乐会嗵嗵鼓",
-   "brake drum": "车轮鼓",
-   "finger cymbal": "指钹",
-   "ride cymbal": "叮叮镲",
-   "Concert Toms": "音乐会嗵嗵鼓",
-   Vibraslap: "弹音器",
-   "Wood Blocks": "木鱼",
-   "Temple Blocks": "木鱼",
-   "Wood Block": "木鱼",
-   "Field Drum": "军鼓",
-   "Quad-Toms": "筒鼓",
-   Quads: "筒鼓",
-   "Drums set": "架子鼓",
-   "High Bongo": "邦戈",
-   Timbales: "天巴鼓",
-   "rain stick": "雨棒",
-   "String Bass": "弦乐低音",
-   "Floor Tom": "侧嗵鼓",
-   "Brake Drum": "闸鼓",
-   "Tam-tam": "大锣",
-   Cymbal: "镲",
-   Cymbals: "镲",
-   Whip: "乐鞭",
-   whip: "乐鞭"
-}
-
-/**
- * 获取乐器名称
- * @param instrumentName 乐器code
- * @returns
- */
-export const getInstrumentName = (instrumentName: string) => {
-   const _instrumentName = instrumentName.replace(/ /g, " ").toLocaleLowerCase()
-   const _instrument: any = Object.keys(instruments)
-   for (let i = 0; i < _instrument.length; i++) {
-      const _name = _instrument[i].replace(/ /g, " ").toLocaleLowerCase()
-      if (_name === _instrumentName) {
-         return instruments[_instrument[i]] || ""
-      }
-   }
-   for (let i = 0; i < _instrument.length; i++) {
-      const _name = _instrument[i].replace(/ /g, " ").toLocaleLowerCase()
-      if (_instrumentName.includes(_name)) {
-         return instruments[_instrument[i]] || ""
-      }
-   }
-   return ""
-}
+// const instruments: any = {
+//    "Acoustic Grand Piano": "大钢琴",
+//    "Bright Acoustic Piano": "明亮的钢琴",
+//    "Electric Grand Piano": "电钢琴",
+//    "Rhodes Piano": "柔和的电钢琴",
+//    "Chorused Piano": "加合唱效果的电钢琴",
+//    Harpsichord: "羽管键琴",
+//    Clavichord: "科拉维科特琴",
+//    Celesta: "钢片琴",
+//    Glockenspiel: "钢片琴",
+//    "Music box": "八音盒",
+//    Vibraphone: "颤音琴",
+//    Marimba: "马林巴",
+//    Xylophone: "木琴",
+//    "Tubular Bells": "管钟",
+//    Dulcimer: "大扬琴",
+//    "Hammond Organ": "击杆风琴",
+//    "Percussive Organ": "打击式风琴",
+//    "Rock Organ": "摇滚风琴",
+//    "Church Organ": "教堂风琴",
+//    "Reed Organ": "簧管风琴",
+//    Accordian: "手风琴",
+//    Harmonica: "口琴",
+//    "Tango Accordian": "探戈手风琴",
+//    "Acoustic Guitar": "钢弦吉他",
+//    "Electric Guitar": "闷音电吉他",
+//    "Overdriven Guitar": "加驱动效果的电吉他",
+//    "Distortion Guitar": "加失真效果的电吉他",
+//    "Guitar Harmonics": "吉他和音",
+//    "Acoustic Bass": "大贝司",
+//    "Electric Bass": "电贝司",
+//    "Fretless Bass": "无品贝司",
+//    "Slap Bass": "掌击",
+//    "Synth Bass": "电子合成",
+//    Violin: "小提琴",
+//    Viola: "中提琴",
+//    Cello: "大提琴",
+//    Contrabass: "低音大提琴",
+//    "Tremolo Strings": "弦乐群颤音音色",
+//    "Pizzicato Strings": "弦乐群拨弦音色",
+//    "Orchestral Harp": "竖琴",
+//    Timpani: "定音鼓",
+//    "String Ensemble": "弦乐合奏音色",
+//    "Synth Strings": "合成弦乐合奏音色",
+//    "Choir Aahs": "人声合唱",
+//    "Voice Oohs": "人声",
+//    "Synth Voice": "合成人声",
+//    "Orchestra Hit": "管弦乐敲击齐奏",
+//    Trumpet: "小号",
+//    Trombone: "长号",
+//    Tuba: "大号",
+//    "Muted Trumpet": "加弱音器小号",
+//    "French Horn": "法国号",
+//    "Brass Section": "铜管组",
+//    "Synth Brass": "合成铜管音色",
+//    "Soprano Sax": "高音萨克斯管",
+//    "Alto Sax": "中音萨克斯管",
+//    "Tenor Sax": "次中音萨克斯管",
+//    "Baritone Sax": "低音萨克斯管",
+//    Oboe: "双簧管",
+//    "English Horn": "英国管",
+//    Bassoon: "巴松",
+//    "Soprano Saxophone": "高音萨克斯管",
+//    "Alto Saxophone": "中音萨克斯管",
+//    "Tenor Saxophone": "次中音萨克斯管",
+//    "Baritone Saxophone": "低音萨克斯管",
+//    Piccolo: "短笛",
+//    Flute: "长笛",
+//    Recorder: "竖笛",
+//    "Soprano Recorder": "高音竖笛",
+//    "Pan Flute": "排箫",
+//    "Bottle Blow": "瓶木管",
+//    Whistle: "口哨声",
+//    Ocarina: "陶笛",
+//    Lead: "合成主音",
+//    "Lead lead": "合成主音",
+//    "Pad age": "合成音色",
+//    Pad: "合成音色",
+//    FX: "合成效果  科幻",
+//    Sitar: "西塔尔",
+//    Banjo: "班卓琴",
+//    Shamisen: "三昧线",
+//    Koto: "十三弦筝",
+//    Kalimba: "卡林巴",
+//    Bagpipe: "风笛",
+//    Fiddle: "民族提琴",
+//    Shanai: "山奈",
+//    "Tinkle Bell": "叮当铃",
+//    Agogos: "阿戈戈铃",
+//    "Steel Drums": "钢鼓",
+//    "Taiko Drum": "太鼓",
+//    "Melodic Toms": "嗵嗵鼓",
+//    "Synth Drums": "合成鼓",
+//    "Reverse Cymbals": "反向镲",
+//    "Agogo Bells": "阿戈戈铃",
+//    "Taiko Drums": "太鼓",
+//    Bongos: "邦戈鼓",
+//    "Bongo Bell": "邦戈铃",
+//    Congas: "康加鼓",
+//    Guiro: "刮壶",
+//    "Guitar Fret Noise": "吉他换把杂音",
+//    "Breath Noise": "呼吸声",
+//    Seashore: "海浪声",
+//    "Bird Tweet": "鸟鸣",
+//    "Telephone Ring": "电话铃",
+//    Helicopter: "直升机",
+//    Applause: "鼓掌声",
+//    Gunshot: "枪声",
+//    "Acoustic Bass Drum": "大鼓",
+//    "Bass Drum": "大鼓",
+//    "Side Drum": "小鼓鼓边",
+//    "Acoustic Snare": "小鼓",
+//    "Hand Claps": "拍手",
+//    "Electric Snare": "小鼓",
+//    "Low Floor Tom": "低音嗵鼓",
+//    "Closed Hi-Hat": "闭合踩镲",
+//    "High Floor Tom": "高音落地嗵鼓",
+//    "Pedal Hi-Hat": "脚踏踩镲",
+//    "Low Tom": "低音嗵鼓",
+//    "Open Hi-Hat": "开音踩镲",
+//    "Low-Mid Tom": "中低音嗵鼓",
+//    "Hi Mid Tom": "高音鼓",
+//    "Crash Cymbals": "对镲",
+//    "High Tom": "高音嗵鼓",
+//    "Ride Cymbals": "叮叮镲",
+//    "Chinese Cymbals": "中国镲",
+//    "Ride Bell": "圆铃",
+//    Tambourine: "铃鼓",
+//    "Splash Cymbal": "溅音镲",
+//    Cowbell: "牛铃",
+//    "Crash Cymbal": "强音钹",
+//    "Vibra-Slap": "颤音器",
+//    "Ride Cymbal": "打点钹",
+//    "Hi Bongo": "高音邦戈鼓",
+//    "Low Bongo": "低音邦戈鼓",
+//    "Mute Hi Conga": "弱音高音康加鼓",
+//    "Open Hi Conga": "强音高音康加鼓",
+//    "Low Conga": "低音康加鼓",
+//    "High Timbale": "高音天巴鼓",
+//    "Low Timbale": "低音天巴鼓",
+//    "High Agogo": "高音阿戈戈铃",
+//    "Low Agogo": "低音阿戈戈铃",
+//    Cabasa: "卡巴萨",
+//    Maracas: "沙锤",
+//    "Short Whistle": "短口哨",
+//    "Long Whistle": "长口哨",
+//    "Short Guiro": "短刮壶",
+//    "Long Guiro": "长刮壶",
+//    Claves: "响棒",
+//    "Hi Wood Block": "高音木鱼",
+//    "Low Wood Block": "低音木鱼",
+//    "Mute Triangle": "弱音三角铁",
+//    "Open Triangle": "强音三角铁",
+//    "Drum Set": "架子鼓",
+//    "Hulusi flute": "葫芦丝",
+//    Melodica: "口风琴",
+//    "Snare Drum": "小军鼓",
+//    "Horn in F": "圆号",
+//    "Horns in F": "圆号",
+//    Triangle: "三角铁",
+//    Vibrato: "颤音琴",
+//    "Suspend Cymbals": "吊镲",
+//    "Suspended Cymbals": "吊镲",
+//    "Tom-Toms": "嗵嗵鼓",
+//    Bell: "铃铛",
+//    Bells: "铃铛",
+//    "Alto Clarinet": "中音单簧管",
+//    "Bass Clarinet": "低音单簧管",
+//    Clarinet: "单簧管",
+//    Cornet: "短号",
+//    Euphonium: "上低音号",
+//    "crash cymbals": "对镲",
+//    Castanets: "响板",
+//    Shaker: "沙锤",
+//    "Mark tree": "音树",
+//    Chimes: "管钟",
+//    "Mark Tree": "音树",
+//    "Tom-toms": "嗵嗵鼓",
+//    "Hi-Hat": "踩镲",
+//    "Sleigh Bells": "雪橇铃",
+//    Flexatone: "弹音器",
+//    "Brake drum": "闸鼓",
+//    Gong: "锣",
+//    "concert tom": "音乐会嗵嗵鼓",
+//    "brake drum": "车轮鼓",
+//    "finger cymbal": "指钹",
+//    "ride cymbal": "叮叮镲",
+//    "Concert Toms": "音乐会嗵嗵鼓",
+//    Vibraslap: "弹音器",
+//    "Wood Blocks": "木鱼",
+//    "Temple Blocks": "木鱼",
+//    "Wood Block": "木鱼",
+//    "Field Drum": "军鼓",
+//    "Quad-Toms": "筒鼓",
+//    Quads: "筒鼓",
+//    "Drums set": "架子鼓",
+//    "High Bongo": "邦戈",
+//    Timbales: "天巴鼓",
+//    "rain stick": "雨棒",
+//    "String Bass": "弦乐低音",
+//    "Floor Tom": "侧嗵鼓",
+//    "Brake Drum": "闸鼓",
+//    "Tam-tam": "大锣",
+//    Cymbal: "镲",
+//    Cymbals: "镲",
+//    Whip: "乐鞭",
+//    whip: "乐鞭"
+// }
+
+/**
+ * 获取乐器名称
+ * @param instruments 乐器列表
+ * @param instrumentName 乐器code
+ * @returns
+ */
+export const getInstrumentName = (instruments: any, instrumentName: string) => {
+   const _instrumentName = instrumentName.replace(/ /g, "").trim().toLocaleLowerCase()
+   const _instrument = Object.keys(instruments)
+   for (let i = 0; i < _instrument.length; i++) {
+      const _name = _instrument[i].replace(/ /g, "").toLocaleLowerCase()
+      if (_name === _instrumentName) {
+         return instruments[_instrument[i]] || ""
+      }
+   }
+   for (let i = 0; i < _instrument.length; i++) {
+      const _name = _instrument[i].replace(/ /g, "").toLocaleLowerCase()
+      if (_instrumentName.includes(_name)) {
+         return instruments[_instrument[i]] || ""
+      }
+   }
+   return ""
+}

+ 1595 - 1541
src/views/cloudPractice/cloudPractice.tsx

@@ -1,1541 +1,1595 @@
-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 { 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 { 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,
-         details: {} as any,
-         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<any>([])
-
-      /** 选中的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: list?.id,
-               name: list?.name,
-               // background: list?.background,
-               // xmlUrl: item?.xmlUrl,
-               // musicSheetType: item?.musicSheetType,
-               audioFileUrl: list.audioFileUrl,
-               titleImg: list?.titleImg
-               // musicImg: list.titleImg
-               // 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<any[]>([])
-      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 handleGetDetail_gym = async () => {
-         loading.value = true
-         const { id } = state.list[state.listActive] || {}
-         if (!id) return (loading.value = false)
-         await httpAjaxErrMsg(cbsDetail_gym, id, { simpleFlag: "1" }).then(res => {
-            loading.value = false
-            if (res.code === 200) {
-               const result = res.data || {}
-               state.details = result
-            }
-         })
-      }
-
-      /** 管乐团数据查询 */
-      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 handleGetDetail = async () => {
-         //  GYM,GYT,KLX 区分   查询声部数据·
-         if (userStoreHook.roles === "GYM") {
-            await handleGetDetail_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 || []
-               }
-            })
-
-            type && (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 handleGetDetail() // 默认获取数据
-         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.details = {}
-         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 toDetailGYM = async () => {
-         // const row: any = activeItem.value
-         const details: any = state.details
-         state.imgs = []
-         if (details.musicSheetType === "SINGLE") {
-            loading.value = false
-            state.musicPdfUrl = details.musicPdfUrl
-            return
-         }
-         // state.partNames = await getPartNames(row.xmlUrl)
-         let partList = details.musicSheetSoundList || []
-         partList = partList.filter((item: any) => item.audioPlayType === "PLAY")
-         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)
-            return {
-               label: item.track + (instrumentName ? `(${instrumentName})` : ""),
-               instrumentName: instrumentName,
-               track: item.track,
-               musicPdfUrl: item.musicPdfUrl,
-               // xmlIndex: -1,
-               value: index
-            }
-         })
-
-         // 初始化数据
-         // 是否显示总谱
-         if (details.isScoreRender) {
-            partColumns.value.unshift({
-               label: "总谱",
-               instrumentName: null,
-               track: null,
-               musicPdfUrl: "",
-               xmlIndex: 999,
-               value: 999
-            })
-         }
-         // gym 现在单独处理 管乐迷根据查询条件来筛选谱面
-         let defaultShowStaff
-
-         if (details.defaultScoreRender) {
-            state.selectedPartIndex = 999
-         } else {
-            // 这里筛选当前的声轨
-            const soundCodes = 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))
-
-         state.selectedPartName = defaultShowStaff?.instrumentName
-         state.selectedTrack = defaultShowStaff?.track
-         state.partXmlIndex = defaultShowStaff?.xmlIndex
-         state.selectedPartIndex = defaultShowStaff?.value
-         if (details.isScoreRender && details.defaultScoreRender) {
-            state.musicPdfUrl = details?.musicPdfUrl || ""
-         } else {
-            state.musicPdfUrl = defaultShowStaff?.musicPdfUrl || ""
-         }
-      }
-
-      const toDetail = async () => {
-         if (userStoreHook.roles === "GYM") {
-            await toDetailGYM()
-            return
-         }
-         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
-            //       })
-            //    })
-            // }
-         }
-         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
-            }
-         }
-
-         const 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)
-            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.selectedTrack))
-            // 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") {
-                  console.log(state.partXmlIndex, state.selectedTrack, "----------")
-                  state.iframeSrc = getPreViewCloud(activeItem.value.id, state.partXmlIndex, state.selectedTrack)
-               } 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.details.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)
-         }
-      }
-
-      // 根据当前选中的声部和曲目筛选出对应的声轨
-      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") {
-               cbsDetails = state.details.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 () => (
-         <NavContainer navs={navs}>
-            {/* <ElScrollbar class="elScrollbar"> */}
-            <div class={styles.cloudPractice}>
-               <div class={styles.leftContainer}>
-                  <div class={styles.details}>
-                     {storeData.value.length > 0 && (
-                        <ElScrollbar class={styles.leftSection}>
-                           {/* 基 础 云 练 */}
-                           {storeData.value.map((item: any) => (
-                              <div
-                                 class={[styles.leftSection_item, item.id === state.firstTreeId && styles.leftSection_item__active]}
-                                 onClick={async () => {
-                                    if (loading.value) return
-                                    state.firstTreeId = item.id
-                                    await setDefaultData("first")
-                                    await handleGetList()
-                                    await handleGetDetail()
-                                    searchContent()
-                                 }}
-                              >
-                                 {item.name}
-                              </div>
-                           ))}
-                        </ElScrollbar>
-                     )}
-
-                     <div class={[styles.musicList, "musicList-container"]}>
-                        <div class={styles.searchHeader}>
-                           {state.categoryList.length > 1 && (
-                              <div class={[styles.categorySection]}>
-                                 <NPopselect
-                                    placement="bottom-start"
-                                    disabled={loading.value}
-                                    options={state.categoryList}
-                                    v-model:value={state.categoryId}
-                                    onUpdate:value={async (val: any) => {
-                                       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()
-                                          await handleGetDetail()
-                                          searchContent()
-                                       }
-                                    }}
-                                    onUpdate:show={(value: any) => {
-                                       state.categoryShow = value
-                                    }}
-                                    trigger="click"
-                                    class={"PopSelect"}
-                                 >
-                                    <span class={[styles.iconTagName, state.categoryShow && styles.show]}>
-                                       <span>{state.categoryName}</span>
-                                    </span>
-                                 </NPopselect>
-                              </div>
-                           )}
-
-                           <div class={styles.searchMore}>
-                              <div class={styles.searchSection}>
-                                 <Dictionary
-                                    clearable={false}
-                                    popperClass="classTypePopper"
-                                    v-model={state.subjectId}
-                                    height={42}
-                                    // disabled={loading.value}
-                                    options={state.subjectList}
-                                    placeholder="全部声部"
-                                    onChange={async () => {
-                                       await handleGetList()
-                                       await handleGetDetail()
-                                       searchContent()
-                                    }}
-                                 />
-                                 {state.levelList.length ? (
-                                    <Dictionary
-                                       clearable={false}
-                                       popperClass="classTypePopper"
-                                       v-model={state.levelId}
-                                       height={42}
-                                       // disabled={loading.value}
-                                       options={state.levelList}
-                                       placeholder="级别"
-                                       onChange={async () => {
-                                          setDefaultData("level")
-                                          await handleGetList()
-                                          await handleGetDetail()
-                                          searchContent()
-                                       }}
-                                    />
-                                 ) : null}
-                                 {state.typeList.length > 0 ? (
-                                    <Dictionary
-                                       clearable={false}
-                                       popperClass="classTypePopper"
-                                       v-model={state.typeId}
-                                       height={42}
-                                       // disabled={loading.value}
-                                       options={state.typeList}
-                                       propsOpt={{
-                                          labelField: "name",
-                                          valueField: "id"
-                                       }}
-                                       placeholder="分类"
-                                       onChange={async () => {
-                                          await handleGetList()
-                                          await handleGetDetail()
-                                          searchContent()
-                                       }}
-                                    />
-                                 ) : null}
-                              </div>
-                              <div
-                                 class={[styles.btnSearch, state.searchStatus && styles.btnSearchActive]}
-                                 onClick={() => (state.searchStatus = !state.searchStatus)}
-                              ></div>
-                           </div>
-                           {state.searchStatus && (
-                              <MyInput
-                                 class="queryCp"
-                                 v-model={state.queryStr}
-                                 height={42}
-                                 placeholder="请输入曲目关键词"
-                                 onKeyup={async (e: any) => {
-                                    if (e.code === "Enter" || e.key === "Enter") {
-                                       await handleGetList()
-                                       await handleGetDetail()
-                                       searchContent()
-                                    }
-                                 }}
-                                 onHandleQuery={async () => {
-                                    await handleGetList()
-                                    await handleGetDetail()
-                                    searchContent()
-                                 }}
-                                 clearable
-                              />
-                           )}
-                        </div>
-
-                        <div class={[styles.wrapList, !state.list.length && !loading.value && styles.wrapListEmpty]}>
-                           {state.list.map((item: any, index: number) => (
-                              <div
-                                 class={[styles.item, index === state.listActive && styles.active]}
-                                 onClick={async () => {
-                                    if (index === state.listActive) {
-                                       return
-                                    }
-                                    state.listActive = index
-                                    state.selectedPartIndex = 0
-                                    state.partXmlIndex = 0
-                                    await handleGetDetail()
-                                    searchContent()
-                                 }}
-                              >
-                                 <div class={styles.itemInfo}>
-                                    <div class={styles.img}>
-                                       <NImage
-                                          lazy
-                                          objectFit="cover"
-                                          previewDisabled={true}
-                                          src={item.titleImg || icon_default}
-                                          onLoad={(e: any) => {
-                                             ;(e.target as any).dataset.loaded = "true"
-                                          }}
-                                       />
-                                       <PlayLoading
-                                          class={[state.listActive === index && state.playState === "play" ? "" : styles.showPlayLoading]}
-                                       />
-                                    </div>
-                                    <div class={styles.title}>
-                                       <div class={styles.titleName}>
-                                          <ellipsisScroll title={item.name} />
-                                       </div>
-                                    </div>
-                                 </div>
-                                 <div class={styles.btnSection}>
-                                    <div
-                                       class={styles.btn}
-                                       onClick={(e: any) => {
-                                          e.stopPropagation()
-                                          handlePlay(item)
-                                          if (state.listActive !== index) {
-                                             resetRender()
-                                          }
-                                       }}
-                                    >
-                                       {state.listActive === index && (
-                                          <>
-                                             {state.playState === "pause" ? "播放" : "暂停"}
-                                             <img src={state.playState === "pause" ? iconBtnPlay : (iconBtnPause as any)} />
-                                          </>
-                                       )}
-                                       {state.listActive !== index && (
-                                          <>
-                                             播放
-                                             <img src={iconBtnPlay as any} />
-                                          </>
-                                       )}
-                                    </div>
-                                 </div>
-                              </div>
-                           ))}
-
-                           {!state.list.length && !loading.value && (
-                              <ElEmpty class={styles.empty} image={require("@/img/layout/empty.png")} description="暂无内容" />
-                           )}
-
-                           <div ref={spinRef} class={[styles.loadingWrap, state.finshed && styles.showLoading]}>
-                              <NSpin show={true} stroke="#FF531C"></NSpin>
-                           </div>
-                        </div>
-                     </div>
-                  </div>
-               </div>
-               <div class={styles.rightContainer}>
-                  {/* <i class={styles.leftArrow}></i> */}
-
-                  <NSpin show={staffLoading.value} stroke="#FF531C">
-                     {activeItem.value?.id ? (
-                        state.musicPdfUrl ? (
-                           <div class={[styles.staffImgs]}>
-                              <iframe
-                                 style={{
-                                    // opacity: loading.value ? 0 : 1,
-                                    width: "100%",
-                                    height: "100%"
-                                 }}
-                                 src={state.iframeSrc}
-                                 onLoad={() => {
-                                    // 判断是用哪个渲染的
-                                    loading.value = false
-                                    staffLoading.value = false
-                                 }}
-                              ></iframe>
-                           </div>
-                        ) : (
-                           <>
-                              <div class={styles.musicName}>
-                                 {activeItem.value.name}
-                                 {activeItem.value.musicSheetType === "CONCERT" &&
-                                    (state.selectedPartName || state.selectedTrack ? `(${state.selectedPartName || state.selectedTrack})` : "")}
-                              </div>
-                              <div class={[styles.staffImgs]}>
-                                 <iframe
-                                    id="staffIframeRef"
-                                    style={{
-                                       // opacity: loading.value ? 0 : 1,
-                                       width: "100%",
-                                       height: "100%"
-                                    }}
-                                    src={state.iframeSrc}
-                                    onLoad={musicIframeLoad}
-                                 ></iframe>
-                              </div>
-                           </>
-                        )
-                     ) : (
-                        <div class={[styles.staffImgs, !loading.value && !activeItem.value?.id && styles.staffImgsEmpty]}>
-                           {!loading.value && !activeItem.value?.id && (
-                              <ElEmpty class={styles.empty} image={require("@/img/layout/empty.png")} description="暂无内容" />
-                           )}
-                        </div>
-                     )}
-                  </NSpin>
-
-                  <img
-                     style={{
-                        display: activeItem.value?.id ? "" : "none"
-                     }}
-                     class={[styles.goBtn]}
-                     src={btnSubmit as any}
-                     onClick={() => {
-                        handleChangeAudio("pause")
-                        goToCloud(activeItem.value.id, state.partXmlIndex)
-                     }}
-                  />
-
-                  <div class={styles.rightBtns} style={{ display: activeItem.value.id ? "" : "none" }}>
-                     <div style={{ display: state.musicPdfUrl || state.imgs.length > 0 ? "" : "none" }}>
-                        <NTooltip showArrow={false}>
-                           {{
-                              trigger: () => (
-                                 <img
-                                    onClick={onDownload}
-                                    class={[styles.transBtn, (downloadStatus.value || staffLoading.value) && styles.disableBtn]}
-                                    src={iconDownload as any}
-                                 />
-                              ),
-                              default: "下载曲谱"
-                           }}
-                        </NTooltip>
-                     </div>
-                     <div
-                        style={{ display: activeItem.value.musicSheetType === "CONCERT" || state.details.musicSheetType === "CONCERT" ? "" : "none" }}
-                     >
-                        <NPopselect
-                           options={partColumns.value}
-                           placement="bottom-end"
-                           trigger="click"
-                           v-model:value={state.selectedPartIndex}
-                           scrollable
-                           onUpdate:value={async (value: any) => {
-                              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
-                              state.imgs = []
-                              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: () => (
-                                 <NTooltip showArrow={false}>
-                                    {{
-                                       trigger: () => <img class={styles.transBtn} src={iconTransfer as any} />,
-                                       default: "切换声轨"
-                                    }}
-                                 </NTooltip>
-                              )
-                           }}
-                        </NPopselect>
-                     </div>
-                  </div>
-               </div>
-            </div>
-            {/* </ElScrollbar> */}
-
-            {state.list.length !== 0 && activeItem.value.audioFileUrl && (
-               <PlayItem
-                  show={state.showPlayer}
-                  playState={state.playState}
-                  songPrevNextStatus={songPrevNextStatus.value}
-                  item={activeItem.value}
-                  onChange={value => handleChangeAudio(value)}
-                  onShow={(status: boolean) => {
-                     state.showPlayer = status
-                  }}
-               />
-            )}
-            <PracticeForm v-model={isPracticeShow.value} practiceUrl={practiceUrl.value} onClose={handlePracticeClose} />
-         </NavContainer>
-      )
-   }
-})
+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 { 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,
+   cbsDetail_klx
+} 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 { 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, instrumentCodes, getInstrumentCodes } = useFunction()
+      const navs = [
+         {
+            name: "主页",
+            url: "/"
+         },
+         {
+            name: "云练习"
+         }
+      ]
+      const spinRef = ref()
+      const state = reactive({
+         finshed: false,
+         reshing: false,
+         page: 1,
+         rows: 20,
+         details: {} as any,
+         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<any>([])
+
+      const musicRenderType = computed(() => {
+         const details = state.details
+         const template: any = {
+            STAVE: "staff",
+            JIAN: "fixedTone",
+            FIRST: "firstTone"
+         }
+         if (details.scoreType) {
+            return template[details.scoreType] || "staff"
+         }
+         return "staff"
+      })
+
+      /** 选中的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: list?.id,
+               name: list?.name,
+               // background: list?.background,
+               // xmlUrl: item?.xmlUrl,
+               // musicSheetType: item?.musicSheetType,
+               audioFileUrl: list.audioFileUrl,
+               titleImg: list?.titleImg
+               // musicImg: list.titleImg
+               // 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
+            }
+            // console.log(tempList, "tempList --- tempList")
+         } else if (userStoreHook.roles === "KLX") {
+            // const item: any = list.background?.[0]
+            tempList = {
+               id: list?.id,
+               name: list?.name,
+               // 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: 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<any[]>([])
+      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 handleGetDetail_gym = async () => {
+         loading.value = true
+         const { id } = state.list[state.listActive] || {}
+         if (!id) return (loading.value = false)
+         await httpAjaxErrMsg(cbsDetail_gym, id, { simpleFlag: "1" }).then(res => {
+            loading.value = false
+            if (res.code === 200) {
+               const result = res.data || {}
+               state.details = result
+            }
+         })
+      }
+
+      /** 管乐团数据查询 */
+      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.instrumentId
+                  }
+               })
+
+               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)) {
+                  state.list = [...state.list, ...result.rows]
+                  state.finshed = state.page >= result.totalPage
+               } else {
+                  state.finshed = true
+               }
+            } else {
+               state.finshed = true
+            }
+         })
+      }
+
+      const handleGetDetail_klx = async () => {
+         loading.value = true
+         const { id } = state.list[state.listActive] || {}
+         if (!id) return (loading.value = false)
+         await httpAjaxErrMsg(cbsDetail_klx, id, { simpleFlag: "1", providerType: "TENANT" }).then(res => {
+            loading.value = false
+            if (res.code === 200) {
+               const result = res.data || {}
+               state.details = result
+            }
+         })
+      }
+
+      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 handleGetDetail = async () => {
+         //  GYM,GYT,KLX 区分   查询声部数据·
+         if (userStoreHook.roles === "GYM") {
+            await handleGetDetail_gym()
+         } else if (userStoreHook.roles === "GYT") {
+            //
+         } else if (userStoreHook.roles === "KLX") {
+            await handleGetDetail_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 || []
+               }
+            })
+
+            type && (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 () => {
+         getInstrumentCodes()
+         await handleAllSearchList()
+         await handleAllGetSubject()
+         await handleAllGetList()
+         await handleGetDetail() // 默认获取数据
+         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.details = {}
+         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()
+      }
+
+      // 获取PDF
+      const getCurrentPdf = (item: any, scoreType: string) => {
+         let pdfUrl = ""
+         if (scoreType === "FIRST") {
+            pdfUrl = item.firstPdfUrl
+         } else if (scoreType === "JIAN") {
+            pdfUrl = item.jianPdfUrl
+         } else if (scoreType === "STAVE") {
+            pdfUrl = item.musicPdfUrl
+         }
+         return pdfUrl || ""
+      }
+
+      const toDetailGYM = () => {
+         // const row: any = activeItem.value
+         const details: any = state.details
+         state.imgs = []
+         if (details.musicSheetType === "SINGLE") {
+            loading.value = false
+            state.musicPdfUrl = getCurrentPdf(details, details.scoreType)
+            return
+         }
+         // state.partNames = await getPartNames(row.xmlUrl)
+         let partList = details.musicSheetSoundList || []
+         partList = partList.filter((item: any) => item.audioPlayType === "PLAY")
+         partList = partList.filter((item: any) => !item.track?.toLocaleUpperCase()?.includes("COMMON"))
+         partColumns.value = partList.map((item: any, index: number) => {
+            const instrumentName = getInstrumentName(instrumentCodes.value, item.track)
+            // const xmlIndex = state.partNames.findIndex((name: any) => name.trim() === item.track)
+            return {
+               label: item.track + (instrumentName ? `(${instrumentName})` : ""),
+               instrumentName: instrumentName,
+               track: item.track,
+               musicPdfUrl: getCurrentPdf(item, details.scoreType),
+               // xmlIndex: -1,
+               value: index
+            }
+         })
+
+         // 初始化数据
+         // 是否显示总谱
+         if (details.isScoreRender) {
+            partColumns.value.unshift({
+               label: "总谱",
+               instrumentName: null,
+               track: null,
+               musicPdfUrl: getCurrentPdf(details, details.scoreType),
+               xmlIndex: 999,
+               value: 999
+            })
+         }
+         // gym 现在单独处理 管乐迷根据查询条件来筛选谱面
+         let defaultShowStaff
+
+         if (details.defaultScoreRender) {
+            state.selectedPartIndex = 999
+         } else {
+            // 这里筛选当前的声轨
+            const soundCodes = 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))
+         state.selectedPartName = defaultShowStaff?.instrumentName
+         state.selectedTrack = defaultShowStaff?.track
+         state.partXmlIndex = defaultShowStaff?.xmlIndex
+         state.selectedPartIndex = defaultShowStaff?.value
+         if (details.isScoreRender && details.defaultScoreRender) {
+            state.musicPdfUrl = getCurrentPdf(details, details.scoreType)
+         } else {
+            state.musicPdfUrl = defaultShowStaff?.musicPdfUrl || ""
+         }
+      }
+
+      const toDetail = async () => {
+         if (userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX") {
+            toDetailGYM()
+            return
+         }
+         const row: any = activeItem.value
+         state.imgs = []
+         if (row.musicSheetType === "SINGLE") {
+            loading.value = false
+            state.musicPdfUrl = row.musicPdfUrl
+            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(instrumentCodes.value, 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
+            }
+         }
+
+         const 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" || userStoreHook.roles === "KLX") {
+            // 判断是用哪个渲染的
+            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)
+            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" || userStoreHook.roles === "KLX") {
+            iframeRef.contentWindow.location.replace(
+               getPreViewCloud(activeItem.value.id, state.partXmlIndex, state.selectedTrack, musicRenderType.value)
+            )
+            // 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" || userStoreHook.roles === "KLX") {
+                  nextTick(() => {
+                     const iframeRef: any = document.getElementById("staffIframeRef")
+                     if (iframeRef) {
+                        iframeRef.contentWindow.location.replace(
+                           getPreViewCloud(activeItem.value.id, state.partXmlIndex, state.selectedTrack, musicRenderType.value)
+                        )
+                     } else {
+                        state.iframeSrc = getPreViewCloud(activeItem.value.id, state.partXmlIndex, state.selectedTrack, musicRenderType.value)
+                     }
+                  })
+               } else {
+                  state.iframeSrc = `/osmd/index.html`
+               }
+            }
+         } catch (error) {
+            //
+         }
+      }
+
+      /** 音频控制 */
+      const handleChangeAudio = async (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])
+
+               await handleGetDetail()
+               searchContent()
+            }
+         } else if (type === "next") {
+            if (state.list[state.listActive + 1]) {
+               handlePlay(state.list[state.listActive + 1])
+
+               await handleGetDetail()
+               searchContent()
+            }
+         }
+      }
+
+      /** 播放曲目 */
+      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.details.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,
+                     userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX" ? false : true
+                  )
+                  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)
+         }
+      }
+
+      // 根据当前选中的声部和曲目筛选出对应的声轨
+      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" || userStoreHook.roles === "KLX") {
+               cbsDetails = state.details.musicSheetSoundList || []
+            } else if (userStoreHook.roles === "GYT") {
+               //
+            }
+            const { track } =
+               cbsDetails.find((item: any) => {
+                  return instrumentIds == item.musicalInstrumentId
+               }) || {}
+            return track
+         }
+         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 () => (
+         <NavContainer navs={navs}>
+            {/* <ElScrollbar class="elScrollbar"> */}
+            <div class={styles.cloudPractice}>
+               <div class={styles.leftContainer}>
+                  <div class={styles.details}>
+                     {storeData.value.length > 0 && (
+                        <ElScrollbar class={styles.leftSection}>
+                           {/* 基 础 云 练 */}
+                           {storeData.value.map((item: any) => (
+                              <div
+                                 class={[styles.leftSection_item, item.id === state.firstTreeId && styles.leftSection_item__active]}
+                                 onClick={async () => {
+                                    if (loading.value) return
+                                    state.firstTreeId = item.id
+                                    await setDefaultData("first")
+                                    await handleGetList()
+                                    await handleGetDetail()
+                                    searchContent()
+                                 }}
+                              >
+                                 {item.name}
+                              </div>
+                           ))}
+                        </ElScrollbar>
+                     )}
+
+                     <div class={[styles.musicList, "musicList-container"]}>
+                        <div class={styles.searchHeader}>
+                           {state.categoryList.length > 1 && (
+                              <div class={[styles.categorySection]}>
+                                 <NPopselect
+                                    placement="bottom-start"
+                                    disabled={loading.value}
+                                    options={state.categoryList}
+                                    v-model:value={state.categoryId}
+                                    onUpdate:value={async (val: any) => {
+                                       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()
+                                          await handleGetDetail()
+                                          searchContent()
+                                       }
+                                    }}
+                                    onUpdate:show={(value: any) => {
+                                       state.categoryShow = value
+                                    }}
+                                    trigger="click"
+                                    class={"PopSelect"}
+                                 >
+                                    <span class={[styles.iconTagName, state.categoryShow && styles.show]}>
+                                       <span>{state.categoryName}</span>
+                                    </span>
+                                 </NPopselect>
+                              </div>
+                           )}
+
+                           <div class={styles.searchMore}>
+                              <div class={styles.searchSection}>
+                                 <Dictionary
+                                    clearable={false}
+                                    popperClass="classTypePopper"
+                                    v-model={state.subjectId}
+                                    height={42}
+                                    // disabled={loading.value}
+                                    options={state.subjectList}
+                                    placeholder="全部声部"
+                                    onChange={async () => {
+                                       await handleGetList()
+                                       await handleGetDetail()
+                                       searchContent()
+                                    }}
+                                 />
+                                 {state.levelList.length ? (
+                                    <Dictionary
+                                       clearable={false}
+                                       popperClass="classTypePopper"
+                                       v-model={state.levelId}
+                                       height={42}
+                                       // disabled={loading.value}
+                                       options={state.levelList}
+                                       placeholder="级别"
+                                       onChange={async () => {
+                                          setDefaultData("level")
+                                          await handleGetList()
+                                          await handleGetDetail()
+                                          searchContent()
+                                       }}
+                                    />
+                                 ) : null}
+                                 {state.typeList.length > 0 ? (
+                                    <Dictionary
+                                       clearable={false}
+                                       popperClass="classTypePopper"
+                                       v-model={state.typeId}
+                                       height={42}
+                                       // disabled={loading.value}
+                                       options={state.typeList}
+                                       propsOpt={{
+                                          labelField: "name",
+                                          valueField: "id"
+                                       }}
+                                       placeholder="分类"
+                                       onChange={async () => {
+                                          await handleGetList()
+                                          await handleGetDetail()
+                                          searchContent()
+                                       }}
+                                    />
+                                 ) : null}
+                              </div>
+                              <div
+                                 class={[styles.btnSearch, state.searchStatus && styles.btnSearchActive]}
+                                 onClick={() => (state.searchStatus = !state.searchStatus)}
+                              ></div>
+                           </div>
+                           {state.searchStatus && (
+                              <MyInput
+                                 class="queryCp"
+                                 v-model={state.queryStr}
+                                 height={42}
+                                 placeholder="请输入曲目关键词"
+                                 onKeyup={async (e: any) => {
+                                    if (e.code === "Enter" || e.key === "Enter") {
+                                       await handleGetList()
+                                       await handleGetDetail()
+                                       searchContent()
+                                    }
+                                 }}
+                                 onHandleQuery={async () => {
+                                    await handleGetList()
+                                    await handleGetDetail()
+                                    searchContent()
+                                 }}
+                                 clearable
+                              />
+                           )}
+                        </div>
+
+                        <div class={[styles.wrapList, !state.list.length && !loading.value && styles.wrapListEmpty]}>
+                           {state.list.map((item: any, index: number) => (
+                              <div
+                                 class={[styles.item, index === state.listActive && styles.active]}
+                                 onClick={async () => {
+                                    if (index === state.listActive) {
+                                       return
+                                    }
+                                    state.listActive = index
+                                    state.selectedPartIndex = 0
+                                    state.partXmlIndex = 0
+                                    await handleGetDetail()
+                                    searchContent()
+                                 }}
+                              >
+                                 <div class={styles.itemInfo}>
+                                    <div class={styles.img}>
+                                       <NImage
+                                          lazy
+                                          objectFit="cover"
+                                          previewDisabled={true}
+                                          src={item.titleImg || icon_default}
+                                          onLoad={(e: any) => {
+                                             ;(e.target as any).dataset.loaded = "true"
+                                          }}
+                                       />
+                                       <PlayLoading
+                                          class={[state.listActive === index && state.playState === "play" ? "" : styles.showPlayLoading]}
+                                       />
+                                    </div>
+                                    <div class={styles.title}>
+                                       <div class={styles.titleName}>
+                                          <ellipsisScroll title={item.name} />
+                                       </div>
+                                    </div>
+                                 </div>
+                                 <div class={styles.btnSection}>
+                                    <div
+                                       class={styles.btn}
+                                       onClick={async (e: any) => {
+                                          e.stopPropagation()
+                                          const status = state.listActive !== index
+                                          handlePlay(item)
+                                          if (status) {
+                                             await handleGetDetail()
+                                             searchContent()
+                                          }
+                                       }}
+                                    >
+                                       {state.listActive === index && (
+                                          <>
+                                             {state.playState === "pause" ? "播放" : "暂停"}
+                                             <img src={state.playState === "pause" ? iconBtnPlay : (iconBtnPause as any)} />
+                                          </>
+                                       )}
+                                       {state.listActive !== index && (
+                                          <>
+                                             播放
+                                             <img src={iconBtnPlay as any} />
+                                          </>
+                                       )}
+                                    </div>
+                                 </div>
+                              </div>
+                           ))}
+
+                           {!state.list.length && !loading.value && (
+                              <ElEmpty class={styles.empty} image={require("@/img/layout/empty.png")} description="暂无内容" />
+                           )}
+
+                           <div ref={spinRef} class={[styles.loadingWrap, state.finshed && styles.showLoading]}>
+                              <NSpin show={true} stroke="#FF531C"></NSpin>
+                           </div>
+                        </div>
+                     </div>
+                  </div>
+               </div>
+               <div class={styles.rightContainer}>
+                  {/* <i class={styles.leftArrow}></i> */}
+
+                  <NSpin show={staffLoading.value} stroke="#FF531C">
+                     {(userStoreHook.roles === "GYT" && activeItem.value?.id) ||
+                     ((userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX") && state.details?.id) ? (
+                        state.musicPdfUrl ? (
+                           <div class={[styles.staffImgs]}>
+                              <iframe
+                                 style={{
+                                    // opacity: loading.value ? 0 : 1,
+                                    width: "100%",
+                                    height: "100%"
+                                 }}
+                                 src={state.iframeSrc}
+                                 onLoad={() => {
+                                    // 判断是用哪个渲染的
+                                    loading.value = false
+                                    staffLoading.value = false
+                                 }}
+                              ></iframe>
+                           </div>
+                        ) : (
+                           <>
+                              <div class={styles.musicName}>
+                                 {activeItem.value.name}
+                                 {activeItem.value.musicSheetType === "CONCERT" &&
+                                    (state.selectedPartName || state.selectedTrack ? `(${state.selectedPartName || state.selectedTrack})` : "")}
+                              </div>
+                              <div class={[styles.staffImgs]}>
+                                 <iframe
+                                    id="staffIframeRef"
+                                    style={{
+                                       // opacity: loading.value ? 0 : 1,
+                                       width: "100%",
+                                       height: "100%"
+                                    }}
+                                    src={state.iframeSrc}
+                                    onLoad={musicIframeLoad}
+                                 ></iframe>
+                              </div>
+                           </>
+                        )
+                     ) : (
+                        <div class={[styles.staffImgs, !loading.value && !activeItem.value?.id && styles.staffImgsEmpty]}>
+                           {!loading.value && !activeItem.value?.id && (
+                              <ElEmpty class={styles.empty} image={require("@/img/layout/empty.png")} description="暂无内容" />
+                           )}
+                        </div>
+                     )}
+                  </NSpin>
+
+                  <img
+                     style={{
+                        display: activeItem.value?.id ? "" : "none"
+                     }}
+                     class={[styles.goBtn]}
+                     src={btnSubmit as any}
+                     onClick={() => {
+                        handleChangeAudio("pause")
+                        goToCloud(activeItem.value.id, state.partXmlIndex, state.selectedTrack, musicRenderType.value)
+                     }}
+                  />
+
+                  <div class={styles.rightBtns} style={{ display: activeItem.value.id ? "" : "none" }}>
+                     <div style={{ display: state.musicPdfUrl || state.imgs.length > 0 ? "" : "none" }}>
+                        <NTooltip showArrow={false}>
+                           {{
+                              trigger: () => (
+                                 <img
+                                    onClick={onDownload}
+                                    class={[styles.transBtn, (downloadStatus.value || staffLoading.value) && styles.disableBtn]}
+                                    src={iconDownload as any}
+                                 />
+                              ),
+                              default: "下载曲谱"
+                           }}
+                        </NTooltip>
+                     </div>
+                     <div
+                        style={{ display: activeItem.value.musicSheetType === "CONCERT" || state.details.musicSheetType === "CONCERT" ? "" : "none" }}
+                     >
+                        <NPopselect
+                           options={partColumns.value}
+                           placement="bottom-end"
+                           trigger="click"
+                           v-model:value={state.selectedPartIndex}
+                           scrollable
+                           onUpdate:value={async (value: any) => {
+                              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
+                              state.imgs = []
+                              nextTick(() => {
+                                 let tempPdf = ""
+                                 if (userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX") {
+                                    tempPdf = item.musicPdfUrl
+                                 } else {
+                                    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: () => (
+                                 <NTooltip showArrow={false}>
+                                    {{
+                                       trigger: () => <img class={styles.transBtn} src={iconTransfer as any} />,
+                                       default: "切换声轨"
+                                    }}
+                                 </NTooltip>
+                              )
+                           }}
+                        </NPopselect>
+                     </div>
+                  </div>
+               </div>
+            </div>
+            {/* </ElScrollbar> */}
+
+            {state.list.length !== 0 && activeItem.value.audioFileUrl && (
+               <PlayItem
+                  show={state.showPlayer}
+                  playState={state.playState}
+                  songPrevNextStatus={songPrevNextStatus.value}
+                  item={activeItem.value}
+                  onChange={value => handleChangeAudio(value)}
+                  onShow={(status: boolean) => {
+                     state.showPlayer = status
+                  }}
+               />
+            )}
+            <PracticeForm v-model={isPracticeShow.value} practiceUrl={practiceUrl.value} onClose={handlePracticeClose} />
+         </NavContainer>
+      )
+   }
+})

+ 8 - 34
src/views/cloudPractice/formatSvgToImg.ts

@@ -54,7 +54,7 @@ export const addMusicTitle = (canvas: any, title: any) => {
 }
 
 let canvas = null as any
-export const svgtoblob = async (svg: any, width: any, height: any, name: string) => {
+export const svgtoblob = async (svg: any, width: any, height: any, name: string, isShowPadding = true) => {
    if (!canvas) {
       // eslint-disable-next-line @typescript-eslint/ban-ts-comment
       // @ts-ignore
@@ -77,38 +77,13 @@ export const svgtoblob = async (svg: any, width: any, height: any, name: string)
    await v.start()
    // const blob = await canvas.convertToBlob()
    // const base64 = await blobToBase64(blob)
-   const base64 = await canvasAddPadding(canvas, name)
+   const base64 = await canvasAddPadding(canvas, name, isShowPadding)
    ctx.clearRect(0, 0, canvas.width, canvas.height)
    await v.stop()
    v = null
    return base64
 }
 
-// export const svgtopng = async (svg: any, width: any, height: any) => {
-//    let canvas: any = new OffscreenCanvas(width, height);
-//    const ctx = canvas.getContext("2d")!;
-//    let v: any = await Canvg.fromString(ctx!, svg, preset);
-
-//    /**
-//     * Resize SVG to fit in given size.
-//     * @param width
-//     * @param height
-//     * @param preserveAspectRatio
-//     */
-//    v.resize(width / 1.2, height / 1.2, "xMidYMid meet");
-
-//    // Render only first frame, ignoring animations and mouse.
-//    await v.start();
-//    let blob: any = await canvas.convertToBlob();
-//    const base64 = await blobToBase64(blob);
-//    ctx.clearRect(0, 0, canvas.width, canvas.height);
-//    canvas = null;
-//    v.stop();
-//    v = null;
-//    blob = null;
-//    return base64;
-//  };
-
 const convertToBlob = (canvas: any, type = "image/png") => {
    return new Promise((resolve, reject) => {
       canvas.toBlob((blob: Blob) => {
@@ -121,10 +96,10 @@ const convertToBlob = (canvas: any, type = "image/png") => {
    })
 }
 
-const canvasAddPadding = async (sourceCanvas: any, name: string) => {
+const canvasAddPadding = async (sourceCanvas: any, name: string, isShowPadding = true) => {
    const targetCanvas = document.createElement("canvas")
-   targetCanvas.width = sourceCanvas.width + 400
-   targetCanvas.height = sourceCanvas.height + 200
+   targetCanvas.width = sourceCanvas.width + (isShowPadding ? 400 : 160)
+   targetCanvas.height = sourceCanvas.height + (isShowPadding ? 200 : 0)
 
    // 坐标(0,0) 表示从此处开始绘制,相当于偏移。
    const targetContext = targetCanvas.getContext("2d") as CanvasRenderingContext2D
@@ -145,14 +120,13 @@ const canvasAddPadding = async (sourceCanvas: any, name: string) => {
 
    // 小水印画布大小
    // const waterCtx = water.getContext("2d") as CanvasRenderingContext2D
-   targetContext.font = `66pt Calibri`
+   targetContext.font = `30pt Calibri`
    targetContext.fillStyle = "#000"
    targetContext.textAlign = "center"
-   targetContext.drawImage(sourceCanvas, 200, 240)
-   targetContext.fillText(name, targetCanvas.width / 2, 200)
+   targetContext.drawImage(sourceCanvas, isShowPadding ? 200 : 80, isShowPadding ? 240 : 40)
+   targetContext.fillText(name, targetCanvas.width / 2, isShowPadding ? 200 : 60)
 
    const blob = await convertToBlob(targetCanvas)
-   // const base64 = await blobToBase64(blob)
    targetContext.clearRect(0, 0, targetCanvas.width, targetCanvas.height)
    return blob
 }

+ 109 - 65
src/views/cloudPractice/useData.ts

@@ -1,65 +1,109 @@
-// 处理 区分处理管乐迷 管乐团的数据
-
-// import { queryTree_gym } from "@/api/cloudPractice.api"
-import { URL_TEACH_GYM, URL_TEACH_GYT, URL_TEACH_KLX } from "@/config"
-import { getToken } from "@/libs/auth"
-
-// import { httpAjaxErrMsg, httpAjax } from "@/plugin/httpAjax"
-// import { CODE_ERR_CANCELED } from "@/libs/auth"
-// import { ElMessage } from "element-plus"
-
-import userStore from "@/store/modules/user"
-import { ref } from "vue"
-
-/**
- * 搜索数据
- */
-export const useFunction = () => {
-   const userStoreHook = userStore()
-   const loading = ref(false)
-
-   /** 跳转云教练 */
-   const isPracticeShow = ref(false)
-   const practiceUrl = ref("")
-   function goToCloud(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}#/?id=${musicId}&Authorization=${getToken()}&platform=pc&part-index=${partIndex}&isYjt=1&isHideMusicList=true&systemType=teacher`,
-         KLX: `${URL_TEACH_KLX}#/?id=${musicId}&Authorization=${getToken()}&platform=pc&part-index=${partIndex}&isYjt=1&isHideMusicList=true&systemType=teacher`
-      }
-      isPracticeShow.value = true
-      practiceUrl.value = urlObj[userStoreHook.roles!]
-      //window.open(urlObj[userStoreHook.roles!], "_blank")
-   }
-   function handlePracticeClose() {
-      isPracticeShow.value = false
-      practiceUrl.value = ""
-   }
-
-   function getPreViewCloud(musicId: string, partIndex = 0, track = "") {
-      //  GYM,GYT,KLX 区分   云教练
-      let gymUrl = `${URL_TEACH_GYM}?t=${Date.now()}#/?id=${musicId}&Authorization=${getToken()}&isPreView=true&zoom=1&downPng=A4&systemType=teacher`
-      if (partIndex === 999) {
-         gymUrl += `&part-index=${partIndex}`
-      } else {
-         gymUrl += `&part-name=${track}`
-      }
-
-      const urlObj = {
-         GYT: `${URL_TEACH_GYT}?id=${musicId}&modelType=practice&modeType=json&part-index=${partIndex}&Authorization=${getToken()}&isYjt=1&&isHideBack=false`,
-         GYM: gymUrl,
-         KLX: `${URL_TEACH_KLX}?t=${Date.now()}#/?id=${musicId}&Authorization=${getToken()}&part-index=${partIndex}&isPreView=true&systemType=teacher`
-      }
-      return urlObj[userStoreHook.roles!]
-   }
-   return { loading, goToCloud, getPreViewCloud, isPracticeShow, practiceUrl, handlePracticeClose }
-}
-
-// function chunkArray(array: any[], size: number) {
-//    const result = []
-//    for (let i = 0; i < array.length; i += size) {
-//       result.push(array.slice(i, i + size))
-//    }
-//    return result
-// }
+// 处理 区分处理管乐迷 管乐团的数据
+import { instrumentCode_gym, instrumentCode_gyt, instrumentCode_klx } from "@/api/cloudPractice.api"
+import { URL_TEACH_GYM, URL_TEACH_GYT, URL_TEACH_KLX } from "@/config"
+import { getToken } from "@/libs/auth"
+
+import { httpAjax } from "@/plugin/httpAjax"
+
+import userStore from "@/store/modules/user"
+import { ref, shallowRef } from "vue"
+
+/**
+ * 搜索数据
+ */
+export const useFunction = () => {
+   const userStoreHook = userStore()
+   const loading = ref(false)
+   const instrumentCodes = shallowRef<any>({}) // 乐器code
+
+   /** 跳转云教练 */
+   const isPracticeShow = ref(false)
+   const practiceUrl = ref("")
+   function goToCloud(musicId: string, partIndex = 0, track = "", musicRenderType = "") {
+      //  GYM,GYT,KLX 区分   云教练
+      let gymUrl = `${URL_TEACH_GYM}#/?id=${musicId}&Authorization=${getToken()}&platform=pc&isYjt=1&isHideMusicList=true&systemType=teacher`
+      let klxUrl = `${URL_TEACH_KLX}#/?id=${musicId}&Authorization=${getToken()}&platform=pc&isYjt=1&isHideMusicList=true&systemType=teacher&musicRenderType=${musicRenderType}`
+      if (partIndex === 999) {
+         gymUrl += `&part-index=${partIndex}`
+         klxUrl += `&part-index=${partIndex}`
+      } else {
+         gymUrl += `&part-name=${track}`
+         klxUrl += `&part-name=${track}`
+      }
+      const urlObj = {
+         GYT: `${URL_TEACH_GYT}?id=${musicId}&modelType=practice&modeType=json&part-index=${partIndex}&Authorization=${getToken()}&isYjt=1&&isHideBack=false`,
+         GYM: gymUrl,
+         KLX: klxUrl
+      }
+      isPracticeShow.value = true
+      practiceUrl.value = urlObj[userStoreHook.roles!]
+      //window.open(urlObj[userStoreHook.roles!], "_blank")
+   }
+   function handlePracticeClose() {
+      isPracticeShow.value = false
+      practiceUrl.value = ""
+   }
+
+   function getPreViewCloud(musicId: string, partIndex = 0, track = "", musicRenderType = "") {
+      //  GYM,GYT,KLX 区分   云教练
+      let gymUrl = `${URL_TEACH_GYM}?t=${Date.now()}#/?id=${musicId}&Authorization=${getToken()}&isPreView=true&zoom=1&downPng=A4&systemType=teacher`
+      let klxUrl = `${URL_TEACH_KLX}?t=${Date.now()}#/?id=${musicId}&Authorization=${getToken()}&isPreView=true&zoom=1&downPng=A4&systemType=teacher&musicRenderType=${musicRenderType}`
+      if (partIndex === 999) {
+         gymUrl += `&part-index=${partIndex}`
+         klxUrl += `&part-index=${partIndex}`
+      } else {
+         gymUrl += `&part-name=${track}`
+         klxUrl += `&part-name=${track}`
+      }
+
+      const urlObj = {
+         GYT: `${URL_TEACH_GYT}?id=${musicId}&modelType=practice&modeType=json&part-index=${partIndex}&Authorization=${getToken()}&isYjt=1&&isHideBack=false`,
+         GYM: gymUrl,
+         KLX: klxUrl
+      }
+      return urlObj[userStoreHook.roles!]
+   }
+
+   function formatInstrumentCodes(data: any[]) {
+      if (Array.isArray(data)) {
+         const tempCodes: any = {}
+         data.forEach((item: any) => {
+            const codes = item.code?.split(",")
+            codes.forEach((code: any) => {
+               tempCodes[code] = item.name
+            })
+         })
+         return tempCodes
+      } else {
+         return {}
+      }
+   }
+
+   /**
+    * 获取乐器code
+    */
+   async function getInstrumentCodes() {
+      //  GYM,GYT,KLX 区分   查询接口
+      const instrumentCodesApi = {
+         GYT: instrumentCode_gyt,
+         GYM: instrumentCode_gym,
+         KLX: instrumentCode_klx
+      }
+      await httpAjax(instrumentCodesApi[userStoreHook.roles!], {}).then(res => {
+         loading.value = false
+         if (res.code === 200) {
+            instrumentCodes.value = formatInstrumentCodes(res.data)
+         }
+      })
+   }
+
+   return { loading, goToCloud, getPreViewCloud, isPracticeShow, practiceUrl, handlePracticeClose, instrumentCodes, getInstrumentCodes }
+}
+
+// function chunkArray(array: any[], size: number) {
+//    const result = []
+//    for (let i = 0; i < array.length; i += size) {
+//       result.push(array.slice(i, i + size))
+//    }
+//    return result
+// }

+ 3 - 1
src/views/cloudTextbooks/useData.ts

@@ -302,9 +302,10 @@ export const useDataDetailList = () => {
             const resultList = res.data || []
             resultList.forEach((item: any) => {
                item.children = item.knowledgePointList || []
-               item.id = item.coursewareDetailId
+               item.id = item.coursewareDetailId || item.lessonCoursewareDetailId
                item.name = item.coursewareDetailName
             })
+            flattenCoursewareListData = []
             listSearchData.value = filterPointList(resultList)
             flattenCoursewareList.value = flattenCoursewareListData
             if (flattenCoursewareList.value[0]) {
@@ -342,6 +343,7 @@ export const useDataDetailList = () => {
                item.id = item.coursewareDetailId
                item.name = item.coursewareDetailName
             })
+            flattenCoursewareListData = []
             listSearchData.value = filterPointList(resultList)
             flattenCoursewareList.value = flattenCoursewareListData
             if (flattenCoursewareList.value[0]) {

+ 19 - 14
src/views/coursewarePlay/coursewarePlay.vue

@@ -338,7 +338,7 @@ async function getLessCoursewareList(id?: string) {
          for (let i = 0; i < result.length; i++) {
             const itemResult = result[i]
             itemResult.name = itemResult.coursewareDetailName
-            itemResult.id = itemResult.coursewareDetailId
+            itemResult.id = itemResult.coursewareDetailId || itemResult.lessonCoursewareDetailId
             itemResult.lessonTargetDesc = itemResult.lessonTargetDesc ? itemResult.lessonTargetDesc.replace(/\n/g, "<br />") : ""
             itemResult.children = itemResult.knowledgePointList || []
             itemResult.knowledgePointList = []
@@ -436,19 +436,21 @@ function filterPointList(pointList: any[], parentData?: { ids: string[]; name: s
    })
 }
 function handleChangeCourseware(index: -1 | 1) {
-   console.log("parentId parentId  parentId")
    handleVideoPause()
    handleSongPause()
    const newIndex = index + activeCoursewareIndex.value
    if (newIndex < 0 || newIndex > flattenCoursewareList.value.length - 1) {
       return
    }
-   const newItem = flattenCoursewareList.value[newIndex]
-   const newParentId = newItem ? newItem.parentData?.ids[0] : ""
-   if (newParentId) {
-      const parentItem = coursewareList.value.find((item: any) => item.id === newParentId)
-      if (parentItem) {
-         lessonTargetDetail.value = parentItem.lessonTargetDesc
+
+   if (searchObj.source === "search") {
+      const newItem = flattenCoursewareList.value[newIndex]
+      const newParentId = newItem ? newItem.parentData?.ids[0] : ""
+      if (newParentId) {
+         const parentItem = coursewareList.value.find((item: any) => item.id === newParentId)
+         if (parentItem) {
+            lessonTargetDetail.value = parentItem.lessonTargetDesc
+         }
       }
    }
 
@@ -464,15 +466,18 @@ function handleCourseClick(value: any) {
       return value.id === item.id && value.knowledgePointId === item.knowledgePointId
    })
 
-   const newItem = flattenCoursewareList.value[newIndex]
-   const newParentId = newItem ? newItem.parentData?.ids[0] : ""
+   if (searchObj.source === "search") {
+      const newItem = flattenCoursewareList.value[newIndex]
+      const newParentId = newItem ? newItem.parentData?.ids[0] : ""
 
-   if (newParentId) {
-      const parentItem = coursewareList.value.find((item: any) => item.id === newParentId)
-      if (parentItem) {
-         lessonTargetDetail.value = parentItem.lessonTargetDesc
+      if (newParentId) {
+         const parentItem = coursewareList.value.find((item: any) => item.id === newParentId)
+         if (parentItem) {
+            lessonTargetDetail.value = parentItem.lessonTargetDesc
+         }
       }
    }
+
    activeCoursewareIndex.value = newIndex
    drawerShow.value = false
 }

+ 3 - 3
vue.config.js

@@ -36,19 +36,19 @@ module.exports = defineConfig({
    devServer: {
       proxy: {
          "/gym": {
-            target: "https://dev.gym.lexiaoya.cn",
+            target: "https://test.gym.lexiaoya.cn",
             pathRewrite: {
                "^/gym": ""
             }
          },
          "/gyt": {
-            target: "https://dev.lexiaoya.cn",
+            target: "https://test.lexiaoya.cn",
             pathRewrite: {
                "^/gyt": ""
             }
          },
          "/klx": {
-            target: "https://dev.colexiu.com",
+            target: "https://test.colexiu.com",
             pathRewrite: {
                "^/klx": ""
             }

Some files were not shown because too many files changed in this diff