index.tsx 49 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432
  1. import {
  2. computed,
  3. defineComponent,
  4. nextTick,
  5. onBeforeUnmount,
  6. onMounted,
  7. onUnmounted,
  8. reactive,
  9. ref,
  10. watch
  11. } from 'vue'
  12. import umiRequest from 'umi-request'
  13. import { useRoute, useRouter } from 'vue-router'
  14. import request from '@/helpers/request'
  15. import ColHeader from '@/components/col-header'
  16. import { postMessage, promisefiyPostMessage } from '@/helpers/native-message'
  17. import {
  18. Button,
  19. Cell,
  20. CellGroup,
  21. Checkbox,
  22. Dialog,
  23. Icon,
  24. Image,
  25. Popup,
  26. RadioGroup,
  27. Sticky,
  28. Tag,
  29. Radio,
  30. Toast,
  31. Picker
  32. } from 'vant'
  33. import qs from 'query-string'
  34. import styles from './index.module.less'
  35. // import Item from '../list/item'
  36. import { useRect } from '@vant/use'
  37. import { Vue3Lottie } from 'vue3-lottie'
  38. import { getRandomKey, musicBuy } from '../music'
  39. import { getOssUploadUrl, state } from '@/state'
  40. // import { useEventTracking } from '@/helpers/hooks'
  41. import ColSticky from '@/components/col-sticky'
  42. import { browser, getHttpOrigin, moneyFormat } from '@/helpers/utils'
  43. import { orderStatus } from '@/views/order-detail/orderStatus'
  44. import iconShare from '@/views/music/album/icon_share.svg'
  45. import iconAlbum from './images/icon_album.png'
  46. import iconAlbum2 from './images/icon_album2.png'
  47. import iconDownload from './images/icon_download.png'
  48. import iconChange from './images/icon-change.png'
  49. import iconAddCourse from './images/icon-add-course.png'
  50. import iconRemoveCourse from './images/icon-remove-course.png'
  51. import AstronautJSON from './animate/bigLoad.json'
  52. import ColShare from '@/components/col-share'
  53. import iconCollect from './images/icon_collect.png'
  54. import iconCollectActive from './images/icon_collect_active.png'
  55. import iconListen from './images/icon_listen.png'
  56. import emtpy from './images/emtpy.png'
  57. import activeButtonIcon from '@common/images/icon_checkbox.png'
  58. import inactiveButtonIcon from '@common/images/icon_checkbox_default.png'
  59. import staffDetafult from './images/staff-default.png'
  60. import firstDefault from './images/first-default.png'
  61. import fixedDefault from './images/fixed-default.png'
  62. import Plyr from 'plyr'
  63. import 'plyr/dist/plyr.css'
  64. import Download from './download'
  65. import { getInstrumentName } from '@/constant/instruments'
  66. import { svgtopng } from '@/tenant/music/music-detail/formatSvgToImg'
  67. import { useThrottleFn } from '@vueuse/core'
  68. // import {
  69. // formatXML,
  70. // getCustomInfo,
  71. // onlyVisible
  72. // } from '@/tenant/music/music-detail/instrument'
  73. export const getAssetsHomeFile = (fileName: string) => {
  74. const path = `../component/images/${fileName}`
  75. const modules = import.meta.globEager('../component/images/*')
  76. return modules[path].default
  77. }
  78. export default defineComponent({
  79. name: 'MusicDetail',
  80. setup() {
  81. const behaviorId = ref(getRandomKey())
  82. localStorage.setItem('behaviorId', behaviorId.value)
  83. const router = useRouter()
  84. const route = useRoute()
  85. const loading = ref(false)
  86. const aId = Number(route.query.activityId) || 0
  87. const studentActivityId = ref(aId)
  88. const isError = ref(false)
  89. const headers = ref(null)
  90. const footers = ref(null)
  91. const heightInfo = ref<any>('0')
  92. const audioFileUrl = ref('')
  93. const staffData = reactive({
  94. musicId: route.query.id as any,
  95. instrumentId: '', // 声部编号
  96. subjectId: '',
  97. isConcert: false, // 是否合奏
  98. details: {} as any,
  99. list: [], // 列表数据
  100. open: false,
  101. closed: true,
  102. audioReady: false,
  103. iframeSrc: "",
  104. musicXml: "",
  105. instrumentName: "",
  106. iframeRef: null as any,
  107. imgs: [] as any,
  108. musicPdfUrl: "", // 当前声轨PDF
  109. partList: [] as any[],
  110. partNames: [] as string[],
  111. selectedPartName: "" as any,
  112. selectedPartIndex: 0,
  113. isComberRender: false, // 是否合并谱显示
  114. metronomeUrl: "", // 合奏使用链接
  115. metronomeMp3Url: "", // 独奏使用链接
  116. })
  117. // 当前先中的数据
  118. const currentColumn = computed(() => {
  119. console.log(1, partColumns.value, staffData.selectedPartIndex)
  120. return partColumns.value.find((item: any) => item.value === staffData.selectedPartIndex)
  121. })
  122. const downloadStatus = ref<boolean>(false)
  123. const staff = reactive({
  124. status: false,
  125. radio: 'STAVE' // STAVE: 五线谱; JIAN: 固定调; FIRST: 首调
  126. })
  127. const colors: any = {
  128. FREE: {
  129. color: '#01B84F',
  130. text: '免费'
  131. },
  132. VIP: {
  133. color: '#CD863E',
  134. text: '会员'
  135. },
  136. CHARGE: {
  137. color: '#3591CE',
  138. text: '点播'
  139. }
  140. }
  141. // 更改预览状态
  142. const onChangeStaff = (type: string) => {
  143. staff.radio = type
  144. staff.status = false
  145. if (type == 'FIRST') {
  146. loading.value = false
  147. const tempPdf = staffData.details?.firstPdfUrl
  148. initIframe(tempPdf, 'FIRST', staffData.musicXml)
  149. } else if (type == 'JIAN') {
  150. loading.value = false
  151. const tempPdf = staffData.details?.jianPdfUrl
  152. console.log(tempPdf, 'tempPdf')
  153. initIframe(tempPdf, 'JIAN', staffData.musicXml)
  154. } else {
  155. loading.value = false
  156. const tempPdf = staffData.details?.musicPdfUrl
  157. initIframe(tempPdf, 'STAVE', staffData.musicXml)
  158. }
  159. }
  160. const initIframe = (tempPdf: string, staff: string, xml: string) => {
  161. if (tempPdf) {
  162. staffData.musicPdfUrl = tempPdf
  163. } else {
  164. staffData.musicPdfUrl = ''
  165. }
  166. renderStaff()
  167. }
  168. const FetchList = async (id?: any) => {
  169. if (loading.value) {
  170. return
  171. }
  172. loading.value = true
  173. isError.value = false
  174. try {
  175. const {data} = await request.post('/musicSheet/detailSmall', {
  176. prefix:
  177. state.platformType === 'TEACHER' ? '/api-teacher' : '/api-student',
  178. data: {
  179. musicSheetId: route.query.id,
  180. tenantAlbumId: route.query.tenantAlbumId,
  181. providerType: route.query.providerType,
  182. instrumentId: staffData.instrumentId,
  183. subjectId: staffData.subjectId
  184. }
  185. })
  186. staffData.details = data
  187. await toDetail(data)
  188. if (data.auditStatus === 'DOING') {
  189. Dialog.confirm({
  190. message: '曲目审核中',
  191. showConfirmButton: true,
  192. showCancelButton: false,
  193. confirmButtonColor: 'var(--van-primary)'
  194. }).then(() => {
  195. if (browser().isApp) {
  196. postMessage({ api: 'goBack' })
  197. } else {
  198. router.back()
  199. }
  200. })
  201. }
  202. } catch (error) {
  203. isError.value = true
  204. }
  205. loading.value = false
  206. }
  207. const player = ref<any>(null)
  208. const audio = ref<any>(null)
  209. const freeRate = ref<any>(0)
  210. const initAudio = async () => {
  211. const controls = [
  212. 'play-large',
  213. 'play',
  214. 'progress',
  215. 'captions',
  216. // 'fullscreen',
  217. 'duration'
  218. ]
  219. player.value = new Plyr(audio.value, {
  220. controls: controls
  221. })
  222. const config = await request.get(
  223. '/sysConfig/queryByParamNameList',
  224. {
  225. prefix: state.platformType === 'TEACHER' ? '/api-teacher' : '/api-student',
  226. params: {
  227. paramNames: 'music_sheet_free_rate'
  228. }
  229. }
  230. )
  231. freeRate.value = config.data[0]?.paramValue || 0
  232. // player.value.on("ready", () => {
  233. // staffData.audioReady = true;
  234. // nextTick(async () => {
  235. // console.log('1111')
  236. // renderStaff();
  237. // });
  238. // });
  239. nextTick(async () => {
  240. renderStaff();
  241. });
  242. player.value.on('timeupdate', () => {
  243. // 允许播放时间
  244. const players = player.value
  245. const playTime = (players.duration * freeRate.value) / 100 || 0
  246. // 时间,不能播放
  247. if (players.currentTime >= playTime && !buyState.value.play) {
  248. players.stop()
  249. // players.pause()
  250. }
  251. })
  252. }
  253. const showLoading = async (e: any) => {
  254. if (e.data?.api === 'musicStaffRender') {
  255. const osmdImg = e.data.osmdImg
  256. // showImg.value = []
  257. const imgs: any = []
  258. for (let i = 0; i < osmdImg.length; i++) {
  259. const img = await svgtopng(
  260. osmdImg[i].img,
  261. osmdImg[i].width,
  262. osmdImg[i].height
  263. )
  264. imgs.push(img)
  265. }
  266. staffData.imgs = imgs
  267. loading.value = e.data.loading
  268. }
  269. }
  270. onMounted(async () => {
  271. if(route.query.instrumentId) {
  272. staffData.instrumentId = route.query.instrumentId as any
  273. } else {
  274. const instrumentIds = state.user.data?.instrumentId
  275. if(instrumentIds) {
  276. const instrumentId = instrumentIds.split(',')[0]
  277. staffData.instrumentId = instrumentId
  278. }
  279. }
  280. const subjectIds = state.user.data?.subjectId
  281. if(subjectIds) {
  282. const subjectId = subjectIds.split(',')[0]
  283. staffData.subjectId = subjectId
  284. }
  285. postMessage({
  286. api: 'setStatusBarTextColor',
  287. content: { statusBarTextColor: true }
  288. })
  289. await FetchList()
  290. const { height } = useRect(headers as any)
  291. const footer = useRect(footers as any)
  292. heightInfo.value = height + footer.height
  293. // // 初始化音频
  294. // if (audioFileUrl.value) {
  295. // initAudio()
  296. // }
  297. window.addEventListener('message', showLoading)
  298. })
  299. onBeforeUnmount(() => {
  300. postMessage({
  301. api: 'setStatusBarTextColor',
  302. content: { statusBarTextColor: false }
  303. })
  304. })
  305. onUnmounted(() => {
  306. window.removeEventListener('message', showLoading)
  307. })
  308. const toggleFavorite = async () => {
  309. /**
  310. * 酷乐秀老师端 收藏曲目 music/sheet/favorite/id?providerType=?? 添加参数
  311. * @ApiModelProperty("曲目评测来源 TENANT 机构 PLATFORM 平台")
  312. * private String providerType;
  313. * 表示收藏的是机构曲目,还是平台曲目,
  314. */
  315. let apiUrl = '', providerType = ''
  316. if (browser().isTeacher) {
  317. providerType = route.query.tenantAlbumId || route.query.providerType == 'TENANT' ? 'TENANT' : 'PLATFORM'
  318. }
  319. apiUrl = `/music/sheet/favorite/${staffData.details?.bizId}`
  320. try {
  321. await request.post(apiUrl, {
  322. requestType: 'form',
  323. data: {
  324. providerType
  325. },
  326. prefix:
  327. state.platformType === 'TEACHER' ? '/api-teacher' : '/api-student'
  328. })
  329. staffData.details.favorite = staffData.details?.favorite ? 0 : 1
  330. staffData.details.favoriteCount = staffData.details?.favorite
  331. ? staffData.details.favoriteCount + 1
  332. : staffData.details.favoriteCount - 1 < 0
  333. ? 0
  334. : staffData.details.favoriteCount - 1
  335. setTimeout(() => {
  336. Toast(staffData.details?.favorite ? '收藏成功' : '取消收藏成功')
  337. }, 100)
  338. } catch (error) {
  339. //
  340. }
  341. }
  342. const onAddCourse = async () => {
  343. try {
  344. const res = await request.post('/api-teacher/courseCourseware/submit', {
  345. data: {
  346. musicSheetId: staffData.details.bizId,
  347. clientType: 'TEACHER',
  348. userId: state.user.data?.userId
  349. }
  350. })
  351. // console.log(res)
  352. setTimeout(() => {
  353. staffData.details.coursewareId = res.data.id || ''
  354. Toast('已将曲目添加到课件')
  355. staffData.details.coursewareStatus = 1
  356. }, 100)
  357. } catch {
  358. //
  359. }
  360. }
  361. const removeCourse = async () => {
  362. Dialog.confirm({
  363. title: '提示',
  364. message: '您是否确定移出课件',
  365. confirmButtonColor: '#269a93',
  366. cancelButtonText: '取消',
  367. confirmButtonText: '确定'
  368. }).then(async () => {
  369. try {
  370. await request.post(
  371. '/api-teacher/courseCourseware/remove/' +
  372. staffData.details.coursewareId,
  373. {
  374. data: {}
  375. }
  376. )
  377. setTimeout(() => {
  378. Toast('移出成功')
  379. staffData.details.coursewareStatus = 0
  380. }, 100)
  381. } catch {
  382. //
  383. }
  384. })
  385. }
  386. const onBuy = async () => {
  387. const music = staffData.details
  388. orderStatus.orderObject.orderType = 'MUSIC'
  389. orderStatus.orderObject.orderName = music.name
  390. orderStatus.orderObject.orderDesc = music.name
  391. orderStatus.orderObject.actualPrice = music.musicPrice
  392. orderStatus.orderObject.recomUserId = route.query.recomUserId || 0
  393. orderStatus.orderObject.activityId = route.query.activityId || 0
  394. orderStatus.orderObject.orderNo = ''
  395. orderStatus.orderObject.orderList = [
  396. {
  397. orderType: 'MUSIC',
  398. goodsName: music.name,
  399. actualPrice: music.musicPrice,
  400. price: music.musicPrice,
  401. ...music
  402. }
  403. ]
  404. const res = await request.post('/userOrder/getPendingOrder', {
  405. prefix: state.platformType === 'TEACHER' ? '/api-teacher' : '/api-student',
  406. data: {
  407. goodType: 'MUSIC',
  408. bizId: music.bizId
  409. }
  410. })
  411. const result = res.data
  412. if (result) {
  413. Dialog.confirm({
  414. title: '提示',
  415. message: '您有一个未支付的订单,是否继续支付?',
  416. confirmButtonColor: '#269a93',
  417. cancelButtonText: '取消订单',
  418. confirmButtonText: '继续支付'
  419. })
  420. .then(async () => {
  421. orderStatus.orderObject.orderNo = result.orderNo
  422. orderStatus.orderObject.actualPrice = result.actualPrice
  423. orderStatus.orderObject.discountPrice = result.discountPrice
  424. orderStatus.orderObject.paymentConfig = {
  425. ...result.paymentConfig,
  426. paymentVendor: result.paymentVendor,
  427. paymentVersion: result.paymentVersion
  428. }
  429. routerTo()
  430. })
  431. .catch(() => {
  432. Dialog.close()
  433. // 只用取消订单,不用做其它处理
  434. cancelPayment(result.orderNo)
  435. })
  436. } else {
  437. routerTo()
  438. }
  439. }
  440. const routerTo = () => {
  441. const music = staffData.details
  442. router.push({
  443. path: '/orderDetail',
  444. query: {
  445. orderType: 'MUSIC',
  446. musicId: music.bizId
  447. }
  448. })
  449. }
  450. const cancelPayment = async (orderNo: string) => {
  451. try {
  452. await request.post('/userOrder/orderCancel', {
  453. prefix: state.platformType === 'TEACHER' ? '/api-teacher' : '/api-student',
  454. data: {
  455. orderNo
  456. }
  457. })
  458. } catch {}
  459. }
  460. const paymentType = computed(() => {
  461. let paymentType = staffData.details?.paymentType
  462. if (typeof paymentType === 'string') {
  463. paymentType = paymentType.split(',')
  464. return paymentType
  465. }
  466. return []
  467. })
  468. const buyState = computed(() => {
  469. const music = staffData.details
  470. return {
  471. hasTenantAlbum: route.query?.tenantAlbumId ? true : false, // 是否从专辑来的
  472. play: music.play ? true : false, // 是否可以播放
  473. free: music?.paymentType.includes('FREE'),
  474. charge: music?.paymentType.includes('CHARGE'),
  475. vip: music?.paymentType.includes('VIP'),
  476. buy: music?.orderStatus === 'PAID' // 是否已买
  477. }
  478. })
  479. const shareStatus = ref(false)
  480. const shareUrl = ref('')
  481. const shareDiscount = ref(0)
  482. const partColumns = ref<any>([]);
  483. // console.log(data)
  484. const onShare = async () => {
  485. try {
  486. const res = await request.post('/api-teacher/open/musicShareProfit', {
  487. data: {
  488. bizId: staffData.details?.bizId,
  489. userId: state.user.data?.userId
  490. }
  491. })
  492. let url =
  493. location.origin +
  494. `/teacher/#/shareMusic?id=${staffData.details?.bizId}&recomUserId=${state.user.data?.userId}&userType=${state.platformType}`
  495. // 判断是否有活动
  496. if (res.data.discount === 1) {
  497. url += `&activityId=${res.data.activityId}`
  498. }
  499. shareDiscount.value = res.data.discount || 0
  500. shareUrl.value = url
  501. shareStatus.value = true
  502. return
  503. } catch {}
  504. }
  505. /** 获取分轨信息 */
  506. const getInstrumentItem = (instruments: any, name = "") => {
  507. name = name.toLocaleLowerCase().replace(/ /g, ""); //.replace(/\d*/gi, '')
  508. if (!name) return "";
  509. for (let key in instruments) {
  510. const item = instruments[key];
  511. const _key = item.track?.toLocaleLowerCase().replace(/ /g, ""); //.replace(/\d*/gi, '')
  512. if (_key === name) {
  513. return item;
  514. }
  515. }
  516. return "";
  517. };
  518. // 根据当前选中的声部和曲目筛选出对应的声轨
  519. function filterSoundCodes(musicalInstruments: any) {
  520. // 老师端,加上乐器id
  521. const instrumentIds = staffData.instrumentId // appState.instrumentId || appState.user?.instrumentId || route.query.instrumentId
  522. if (instrumentIds) {
  523. const { track } = musicalInstruments.find((item: any) => {
  524. return instrumentIds == item.musicalInstrumentId
  525. }) || {}
  526. return track
  527. }
  528. return null
  529. }
  530. // 根据当前选中的声部和曲目筛选出对应的声轨
  531. function filterSoundInfo(musicalInstruments: any) {
  532. if(musicalInstruments.length <= 0) return null
  533. // 老师端,加上乐器id
  534. const instrumentIds = staffData.instrumentId //appState.instrumentId || appState.user?.instrumentId || route.query.instrumentId
  535. if (instrumentIds) {
  536. const item = musicalInstruments.find((item: any) => {
  537. return instrumentIds == item.musicalInstrumentId && item.audioPlayType == 'PLAY'
  538. }) || null
  539. return item
  540. }
  541. return null
  542. }
  543. // 获取PDF
  544. const getCurrentPdf = (item: any, scoreType: string) => {
  545. let pdfUrl = ''
  546. if(scoreType === 'FIRST') {
  547. pdfUrl = item.firstPdfUrl
  548. } else if(scoreType === 'JIAN') {
  549. pdfUrl = item.jianPdfUrl
  550. } else if(scoreType === 'STAVE') {
  551. pdfUrl = item.musicPdfUrl
  552. }
  553. return pdfUrl || ''
  554. }
  555. const toDetail = async (row: any) => {
  556. staff.radio = row.scoreType // 默认是什么谱页
  557. const tempSongList = row.musicSheetSoundList || []
  558. let partList = tempSongList
  559. staffData.list = tempSongList
  560. partList = partList.filter(
  561. (item: any) => !item.track?.toLocaleUpperCase()?.includes("COMMON")
  562. );
  563. partColumns.value = partList.map((item: any, index: number) => {
  564. // 因为合奏的,显示总谱会加一个声轨
  565. const defaultIndex = row.musicSheetType !== "SINGLE" && row.isScoreRender ? index + 1 : index
  566. const cnName = getInstrumentName(item.track)
  567. return {
  568. text: item.track + (cnName ? `(${cnName})` : ''),
  569. name: item.track + (cnName ? `(${cnName})` : ''), // true
  570. track: item.track,
  571. musicPdfUrl: item.musicPdfUrl,
  572. firstPdfUrl: item.firstPdfUrl,
  573. jianPdfUrl: item.jianPdfUrl,
  574. // xmlIndex,
  575. value: defaultIndex,
  576. };
  577. });
  578. staffData.details = row || {};
  579. staffData.musicXml = staffData.details?.xmlFileUrl;
  580. staffData.isComberRender = staffData.details?.isScoreRender;
  581. let defaultShowStaff: any
  582. if(staffData.details?.musicSheetSoundList) {
  583. const soundCodes = filterSoundCodes(staffData.details?.musicSheetSoundList)
  584. if (soundCodes) {
  585. const soundCodesArr = soundCodes.split(",").map((code: string) => {
  586. return code
  587. .toLowerCase()
  588. .replace(/^\d+|\d+$/g, "")
  589. .trim()
  590. })
  591. defaultShowStaff = partColumns.value.find((item: any) =>
  592. soundCodesArr.includes(
  593. item.track &&
  594. item.track
  595. .toLowerCase()
  596. .replace(/^\d+|\d+$/g, "")
  597. .trim()
  598. )
  599. )
  600. if(defaultShowStaff) {
  601. staffData.selectedPartIndex = defaultShowStaff.value
  602. }
  603. }
  604. }
  605. if (row.musicSheetType === "SINGLE") {
  606. staffData.musicPdfUrl = row.musicPdfUrl;
  607. // 生成的图片
  608. // staffData.imgs = row.musicImg ? row.musicImg.split(',') : [];
  609. } else {
  610. // 初始化数据
  611. // 是否显示总谱
  612. if (staffData.isComberRender) {
  613. partColumns.value.unshift({
  614. text: "总谱",
  615. value: 0,
  616. xmlIndex: 999,
  617. track: "",
  618. name: "总谱",
  619. });
  620. // 如果是总谱则默认选中,否则选择
  621. // staffData.selectedPartIndex = row.defaultScoreRender ? 0 : defaultShowStaff ? defaultShowStaff.value : 1
  622. staffData.selectedPartIndex = defaultShowStaff ? defaultShowStaff.value : 1
  623. let pdfUrl = ''
  624. if(row.defaultScoreRender) {
  625. pdfUrl = getCurrentPdf(row, row.scoreType)
  626. } else {
  627. staffData.musicPdfUrl = getCurrentPdf(defaultShowStaff, row.scoreType)
  628. }
  629. staffData.musicPdfUrl = pdfUrl
  630. } else {
  631. const item = partColumns.value.find((item: any) => item.value === staffData.selectedPartIndex)
  632. if (item) {
  633. staffData.musicPdfUrl = getCurrentPdf(item, row.scoreType) //item.musicPdfUrl;
  634. } else {
  635. staffData.musicPdfUrl = "";
  636. }
  637. }
  638. }
  639. // 通过isScoreRender判断是否合并渲染
  640. // 多声轨, 不是单声部多声轨, 不是老师布置作业选择曲谱
  641. // if (row.musicSheetType === "SINGLE") {
  642. // staffData.isConcert = false;
  643. // const musicSheetSoundList = staffData.details?.musicSheetSoundList || []
  644. // const songs = filterSoundInfo(musicSheetSoundList)
  645. // if(songs) {
  646. // staffData.metronomeMp3Url = songs.audioFileUrl
  647. // } else {
  648. // // 为了处理节奏练习
  649. // if(musicSheetSoundList.length > 0) {
  650. // staffData.metronomeMp3Url = musicSheetSoundList[0].audioFileUrl
  651. // }
  652. // }
  653. // } else {
  654. // staffData.isConcert = true;
  655. // const { audioFileUrl } = row.musicSheetAccompanimentList.find((item: any) => item.audioPlayType == 'PLAY')
  656. // staffData.metronomeUrl = audioFileUrl
  657. // }
  658. audioFileUrl.value = row.mp3Url
  659. if (
  660. audioFileUrl.value
  661. ) {
  662. // audioFileUrl.value = staffData.isConcert ? staffData.metronomeUrl : staffData.metronomeMp3Url
  663. nextTick(async () => {
  664. initAudio();
  665. });
  666. } else {
  667. renderStaff();
  668. }
  669. }
  670. const getPreViewCloud = (musicId: string, partIndex: number, track: string) => {
  671. const Authorization = sessionStorage.getItem("Authorization") || "";
  672. const musicScorePath = "/klx-music-score/";
  673. const musicScoreUrl = getHttpOrigin() + musicScorePath;
  674. // const musicScoreUrl = "https://test.colexiu.com" + musicScorePath;
  675. // const musicScoreUrl = 'http://192.168.3.68:3000/instrument.html';
  676. let href = `${musicScoreUrl}?t=${Date.now()}#/?id=${musicId}&Authorization=${Authorization}&isPreView=true&zoom=0.5&downPng=A4`;
  677. // // 老师端加上systemType=teacher
  678. href += ('&systemType=' +( state.platformType === "STUDENT" ? `student` : 'teacher'));
  679. // 总谱还是什么
  680. if(partIndex === 999) {
  681. href += `&part-index=${partIndex}`
  682. } else {
  683. href += `&part-name=${track}`
  684. }
  685. // musicRenderType
  686. // /** 五线谱 */
  687. // staff = "staff",
  688. // /** 简谱(首调) */
  689. // firstTone = "firstTone",
  690. // /** 固定音高 */
  691. // fixedTone = "fixedTone",
  692. if(staff.radio === "STAVE") {
  693. href += '&musicRenderType=staff'
  694. } else if(staff.radio === 'JIAN') {
  695. href += '&musicRenderType=fixedTone'
  696. } else if(staff.radio === 'FIRST') {
  697. href += '&musicRenderType=firstTone'
  698. }
  699. return href
  700. };
  701. const renderStaff = async () => {
  702. try {
  703. nextTick(() => {
  704. console.log(staffData.musicPdfUrl, 'staffData.musicPdfUrl')
  705. if (staffData.musicPdfUrl) {
  706. const url = `${location.origin}${
  707. location.pathname
  708. }pdf/web/viewer-pdf.html?file=${encodeURIComponent(
  709. staffData.musicPdfUrl
  710. )}&t=${Date.now()}`
  711. const iframeRef = document.querySelector('#staffIframeRef') as any
  712. iframeRef.contentWindow.location.replace(url)
  713. // staffData.iframeSrc = url
  714. } else {
  715. const url = getPreViewCloud(staffData.musicId, currentColumn.value.xmlIndex, currentColumn.value.track)
  716. console.log(url, 'staffIframeRef')
  717. const iframeRef = document.querySelector('#staffIframeRef') as any
  718. iframeRef.contentWindow.location.replace(url)
  719. // staffData.iframeSrc = url
  720. }
  721. })
  722. } catch (error) {
  723. //
  724. }
  725. }
  726. const resetRender = () => {
  727. const iframeRef: any = document.getElementById("staffIframeRef")
  728. console.log(currentColumn.value, "currentColumn.value")
  729. iframeRef.contentWindow.location.replace(getPreViewCloud(staffData.musicId, currentColumn.value?.xmlIndex, currentColumn.value.track))
  730. }
  731. return () => {
  732. return (
  733. <div class={styles.detail}>
  734. <ColSticky position="top">
  735. <div ref={headers}>
  736. <ColHeader
  737. background="transparent"
  738. hideHeader={false}
  739. border={false}
  740. isFixed={false}
  741. color="#fff"
  742. title={staffData.details?.name}
  743. backIconColor="white"
  744. v-slots={{
  745. right: () => (
  746. <div
  747. class={styles.shareBtn}
  748. style={{
  749. color: '#fff'
  750. }}
  751. onClick={onShare}
  752. >
  753. <Image src={iconShare} />
  754. 分享
  755. </div>
  756. )
  757. }}
  758. />
  759. </div>
  760. </ColSticky>
  761. <img class={styles.bgImg} src={staffData.details?.musicCover} />
  762. <div class={styles.bgContent}></div>
  763. <div
  764. class={styles.musicContainer}
  765. style={{
  766. marginTop: '16px',
  767. height: `calc(100vh - var(--header-height) - var(--bottom-height) - 16px)`
  768. }}
  769. >
  770. <div>
  771. <Cell
  772. border={false}
  773. center
  774. class={styles.musicInfo}
  775. v-slots={{
  776. icon: () => (
  777. <Image
  778. class={styles.pImg}
  779. src={ staffData.details?.musicCover}
  780. />
  781. ),
  782. title: () => (
  783. <div class={styles.info}>
  784. <h4
  785. class="van-ellipsis"
  786. // onClick={() => handleGotoMusicScore( staffData.details)}
  787. >
  788. { staffData.details?.name}
  789. </h4>
  790. <p
  791. style={{
  792. display: 'flex',
  793. alignItems: 'center'
  794. }}
  795. >
  796. {paymentType.value.map(
  797. tag =>
  798. tag && (
  799. <Tag
  800. style={{ color: colors[tag]?.color }}
  801. class={styles.tag}
  802. type="success"
  803. plain
  804. >
  805. {colors[tag].text}
  806. </Tag>
  807. )
  808. )}
  809. { staffData.details?.exquisiteFlag === 1 && (
  810. <Image
  811. class={styles.exquisiteFlag}
  812. src={getAssetsHomeFile('icon_exquisite.png')}
  813. />
  814. )}
  815. { staffData.details?.albumNums > 0 && (
  816. <Image
  817. class={styles.songAlbum}
  818. src={getAssetsHomeFile('icon_album_active.png')}
  819. />
  820. )}
  821. <span
  822. class={[
  823. styles.coomposer,
  824. browser().isApp &&
  825. staffData.details?.sourceType === 'TEACHER' &&
  826. state.platformType === 'STUDENT' &&
  827. styles.links
  828. ]}
  829. onClick={() => {
  830. if (
  831. browser().isApp &&
  832. staffData.details?.sourceType === 'TEACHER' &&
  833. state.platformType === 'STUDENT'
  834. ) {
  835. router.push({
  836. path: '/teacherHome',
  837. query: {
  838. teacherId: staffData.details?.userId,
  839. tabs: 'music'
  840. }
  841. })
  842. }
  843. }}
  844. >
  845. <img class={styles.iconAlbum2} src={iconAlbum2} />
  846. <span>
  847. { staffData.details?.userName ||
  848. '游客' + ( staffData.details?.userId || '')}
  849. </span>
  850. </span>
  851. </p>
  852. </div>
  853. ),
  854. value: () => (
  855. <>
  856. <span
  857. style={{
  858. visibility:
  859. state.platformType === 'TEACHER'
  860. ? 'visible'
  861. : 'hidden'
  862. }}
  863. class={styles.download}
  864. onClick={() => {
  865. if ( staffData.details?.coursewareStatus) {
  866. removeCourse()
  867. } else {
  868. onAddCourse()
  869. }
  870. }}
  871. >
  872. <img
  873. src={
  874. staffData.details?.coursewareStatus
  875. ? iconRemoveCourse
  876. : iconAddCourse
  877. }
  878. />
  879. <span>
  880. { staffData.details?.coursewareStatus
  881. ? '移出课件'
  882. : '添加课件'}
  883. </span>
  884. </span>
  885. <span
  886. class={styles.download}
  887. onClick={() => toggleFavorite()}
  888. >
  889. <img
  890. src={
  891. staffData.details?.favorite
  892. ? iconCollectActive
  893. : iconCollect
  894. }
  895. />
  896. <span>收藏</span>
  897. </span>
  898. </>
  899. )
  900. }}
  901. />
  902. <div class={styles.functionSection}>
  903. <div
  904. class={styles.functionItem}
  905. onClick={() => {
  906. router.push({
  907. path: '/look-album-list',
  908. query: {
  909. id: staffData.details?.bizId,
  910. musicSubject: staffData.details?.musicSubject
  911. }
  912. })
  913. }}
  914. >
  915. <img src={iconAlbum} />
  916. <span>专辑</span>
  917. </div>
  918. <div
  919. class={styles.functionItem}
  920. style={{
  921. display:
  922. staffData.details?.musicSheetType === 'CONCERT'
  923. ? ''
  924. : 'none'
  925. }}
  926. onClick={() => {
  927. if ( staffData.details?.musicSheetType === 'CONCERT') {
  928. staffData.open = true
  929. }
  930. }}
  931. >
  932. <img src={iconChange} />
  933. <span>切换乐器</span>
  934. </div>
  935. {/* 独奏的才有转谱功能 */}
  936. {staffData.details?.isConvertibleScore && staffData.details?.musicSheetType === 'SINGLE' ? (
  937. <div
  938. class={styles.functionItem}
  939. style={{
  940. display:
  941. staffData.details?.musicSheetType === 'SINGLE'
  942. ? ''
  943. : 'none'
  944. }}
  945. onClick={() => {
  946. staff.status = true
  947. }}
  948. >
  949. <img src={iconChange} />
  950. <span>转谱</span>
  951. </div>
  952. ) : null}
  953. <div
  954. class={[styles.functionItem, (loading.value ||
  955. (!staffData.musicPdfUrl && staffData.imgs.length <= 0)) ? styles.disabled : '']}
  956. onClick={() => {
  957. // console.log(loading.value, staffData.musicPdfUrl, staffData.imgs, '---------------')
  958. if((loading.value ||
  959. (!staffData.musicPdfUrl && staffData.imgs.length <= 0))) return
  960. if (staffData.musicPdfUrl) {
  961. const songName =
  962. staffData.details?.name +
  963. (staffData.isConcert &&
  964. currentColumn.value?.name
  965. ? `(${
  966. currentColumn.value
  967. ?.name || ""
  968. })`
  969. : "");
  970. promisefiyPostMessage({
  971. api: "downloadFile",
  972. content: {
  973. downloadUrl: staffData.musicPdfUrl,
  974. fileName: songName,
  975. },
  976. });
  977. } else {
  978. downloadStatus.value = true;
  979. }
  980. }}
  981. >
  982. <img src={iconDownload} />
  983. <span>下载</span>
  984. </div>
  985. </div>
  986. </div>
  987. <div class={styles.musicContent}>
  988. {staffData.details.id ? (
  989. <>
  990. {staffData.musicPdfUrl ? (
  991. <>
  992. {/* {loading.value && (
  993. <>
  994. <Vue3Lottie
  995. animationData={AstronautJSON}
  996. class={styles.finch}
  997. ></Vue3Lottie>
  998. <p class={styles.finchLoad}>加载中...</p>
  999. </>
  1000. )} */}
  1001. <iframe
  1002. style={{
  1003. opacity: loading.value ? 0 : 1,
  1004. }}
  1005. id="staffIframeRef"
  1006. src={staffData.iframeSrc}
  1007. onLoad={() => {
  1008. // 判断是用哪个渲染的
  1009. loading.value = false;
  1010. }}
  1011. ></iframe>
  1012. </>
  1013. ) : (
  1014. <>
  1015. <p class={styles.musicTitle}>
  1016. {staffData.details?.name && (
  1017. <>
  1018. {staffData.details?.name}
  1019. {staffData.isConcert &&
  1020. currentColumn.value?.name
  1021. ? `(${
  1022. currentColumn.value
  1023. ?.name || ""
  1024. })`
  1025. : ""}
  1026. </>
  1027. )}
  1028. </p>
  1029. {/* {loading.value && (
  1030. <>
  1031. <Vue3Lottie
  1032. animationData={AstronautJSON}
  1033. class={styles.finch}
  1034. ></Vue3Lottie>
  1035. <p class={styles.finchLoad}>加载中...</p>
  1036. </>
  1037. )} */}
  1038. <iframe
  1039. id="staffIframeRef"
  1040. style={{
  1041. opacity: loading.value ? 0 : 1,
  1042. }}
  1043. src={staffData.iframeSrc}
  1044. onLoad={() => {
  1045. loading.value = false;
  1046. // musicIframeLoad();
  1047. }}
  1048. ></iframe>
  1049. </>
  1050. )}
  1051. </>
  1052. ) : null}
  1053. </div>
  1054. </div>
  1055. {staffData.details?.bizId && (
  1056. <ColSticky
  1057. position="bottom"
  1058. background="white"
  1059. varName="--bottom-height"
  1060. >
  1061. <div ref={footers}>
  1062. <div class={styles.videoOperation}>
  1063. {audioFileUrl.value && (
  1064. <>
  1065. {!buyState.value.play &&
  1066. freeRate.value != 100 &&
  1067. freeRate.value != 0 && (
  1068. <div class={[styles.audition]}>
  1069. <img src={iconListen} />
  1070. <span>每首曲目可试听{freeRate.value}%</span>
  1071. </div>
  1072. )}
  1073. <div class={[styles.audio, styles.collectCell]}>
  1074. <audio id="player" controls ref={audio}>
  1075. <source src={audioFileUrl.value} type="audio/mp3" />
  1076. </audio>
  1077. </div>
  1078. </>
  1079. )}
  1080. </div>
  1081. {/* 判断是否是免费的,或者已经购买过,是否从专辑过来的 */}
  1082. {buyState.value.play ||
  1083. (state.platformType === 'TEACHER' &&
  1084. buyState.value.hasTenantAlbum) ? (
  1085. <Button
  1086. round
  1087. block
  1088. type="primary"
  1089. color="linear-gradient(180deg, #59E5D5 0%, #2DC7AA 100%)"
  1090. onClick={() => {
  1091. const throttleFn = useThrottleFn(() => {
  1092. player.value && player.value.stop()
  1093. // 新版云教练的谱面类型使用musicRenderType字段
  1094. let musicRenderType = ''
  1095. if(staff.radio === "STAVE") {
  1096. musicRenderType = 'staff'
  1097. } else if(staff.radio === 'JIAN') {
  1098. musicRenderType = 'fixedTone'
  1099. } else if(staff.radio === 'FIRST') {
  1100. musicRenderType = 'firstTone'
  1101. }
  1102. let extraParam: any = {
  1103. // 'part-index': currentColumn.value.track || 0,
  1104. 'part-name': currentColumn.value.track?.trim(),
  1105. musicRenderType,
  1106. instrumentId: staffData.instrumentId
  1107. }
  1108. // 有专辑id
  1109. if (route.query.tenantAlbumId) {
  1110. extraParam.albumId = route.query.tenantAlbumId
  1111. } else if (browser().isTeacher && route.query.providerType == 'TENANT') {
  1112. // 机构老师端
  1113. extraParam.albumId = 1
  1114. }
  1115. musicBuy({
  1116. id: staffData.details.bizId
  1117. }, () => {}, extraParam)
  1118. }, 300)
  1119. throttleFn()
  1120. }}
  1121. >
  1122. 立即练习
  1123. </Button>
  1124. ) : (
  1125. <div class={styles.colSticky}>
  1126. {/* 只有,有点播类型的才显示价格 */}
  1127. {buyState.value.charge && (
  1128. <div class={styles.priceSection}>
  1129. <span>点播价:</span>
  1130. <span class={styles.price}>
  1131. <i>¥</i>
  1132. {moneyFormat(staffData.details?.musicPrice)}
  1133. </span>
  1134. </div>
  1135. )}
  1136. <div class={[styles.buyBtn]}>
  1137. {/* 判断是否是需要收费的 */}
  1138. {buyState.value.charge && (
  1139. <Button
  1140. round
  1141. type="primary"
  1142. color="linear-gradient(180deg, #59E5D5 0%, #2DC7AA 100%)"
  1143. class={styles.primary}
  1144. onClick={onBuy}
  1145. >
  1146. 立即点播
  1147. </Button>
  1148. )}
  1149. {/* 判断是否有会员的 */}
  1150. {buyState.value.vip && (
  1151. <Button
  1152. round
  1153. block={!buyState.value.charge ? true : false}
  1154. type="primary"
  1155. color="linear-gradient(180deg, #F7BD8D 0%, #CD8806 100%)"
  1156. class={styles.memeber}
  1157. onClick={() => {
  1158. router.push({
  1159. path: '/memberCenter',
  1160. query: {
  1161. ...route.query
  1162. }
  1163. })
  1164. }}
  1165. >
  1166. {studentActivityId.value > 0 && (
  1167. <div class={[styles.buttonDiscount]}>专属优惠</div>
  1168. )}
  1169. 开通会员
  1170. </Button>
  1171. )}
  1172. </div>
  1173. </div>
  1174. )}
  1175. </div>
  1176. </ColSticky>
  1177. )}
  1178. <Popup
  1179. v-model:show={shareStatus.value}
  1180. style={{ background: 'transparent' }}
  1181. teleport="body"
  1182. >
  1183. <ColShare
  1184. teacherId={state.user.data?.userId}
  1185. shareUrl={shareUrl.value}
  1186. shareType="music"
  1187. >
  1188. <div class={styles.shareMate}>
  1189. {shareDiscount.value === 1 && (
  1190. <div class={styles.tagDiscount}>专属优惠</div>
  1191. )}
  1192. <img
  1193. class={styles.icon}
  1194. crossorigin="anonymous"
  1195. src={staffData.details?.musicCover}
  1196. />
  1197. <div class={styles.info}>
  1198. <h4 class="van-multi-ellipsis--l2">
  1199. {staffData.details?.name}
  1200. </h4>
  1201. <p>作曲人:{staffData.details?.composer}</p>
  1202. </div>
  1203. </div>
  1204. </ColShare>
  1205. </Popup>
  1206. <Popup v-model:show={downloadStatus.value} position="bottom" round>
  1207. {downloadStatus.value && (
  1208. <Download
  1209. imgList={JSON.parse(JSON.stringify(staffData.imgs))}
  1210. musicSheetName={
  1211. staffData.details.name +
  1212. (staffData.isConcert &&
  1213. currentColumn.value?.name
  1214. ? `(${
  1215. currentColumn.value?.name || ""
  1216. })`
  1217. : "")
  1218. }
  1219. />
  1220. )}
  1221. </Popup>
  1222. <Popup
  1223. v-model:show={staff.status}
  1224. teleport="body"
  1225. closeable
  1226. style={{ width: '80%' }}
  1227. round
  1228. >
  1229. <div class={styles.staffContainer}>
  1230. <div class={styles.staffTitle}>选择转换曲谱</div>
  1231. <RadioGroup v-model={staff.radio}>
  1232. <CellGroup border={false}>
  1233. <Cell
  1234. center
  1235. border={false}
  1236. class={staff.radio === 'STAVE' ? styles.active : ''}
  1237. onClick={() => onChangeStaff('STAVE')}
  1238. >
  1239. {{
  1240. icon: () => (
  1241. <Image src={staffDetafult} class={styles.staffImg} />
  1242. ),
  1243. title: () => <span class={styles.name}>五线谱</span>,
  1244. value: () => (
  1245. <Radio name="STAVE">
  1246. {{
  1247. icon: (props: any) => (
  1248. <Icon
  1249. class={styles.boxStyle}
  1250. size={16}
  1251. name={
  1252. props.checked
  1253. ? activeButtonIcon
  1254. : inactiveButtonIcon
  1255. }
  1256. />
  1257. )
  1258. }}
  1259. </Radio>
  1260. )
  1261. }}
  1262. </Cell>
  1263. <Cell
  1264. center
  1265. border={false}
  1266. class={staff.radio === 'FIRST' ? styles.active : ''}
  1267. onClick={() => onChangeStaff('FIRST')}
  1268. >
  1269. {{
  1270. icon: () => (
  1271. <Image src={firstDefault} class={styles.staffImg} />
  1272. ),
  1273. title: () => <span class={styles.name}>简谱-首调</span>,
  1274. value: () => (
  1275. <Radio name="FIRST">
  1276. {{
  1277. icon: (props: any) => (
  1278. <Icon
  1279. class={styles.boxStyle}
  1280. size={16}
  1281. name={
  1282. props.checked
  1283. ? activeButtonIcon
  1284. : inactiveButtonIcon
  1285. }
  1286. />
  1287. )
  1288. }}
  1289. </Radio>
  1290. )
  1291. }}
  1292. </Cell>
  1293. <Cell
  1294. center
  1295. border={false}
  1296. class={staff.radio === 'JIAN' ? styles.active : ''}
  1297. onClick={() => onChangeStaff('JIAN')}
  1298. >
  1299. {{
  1300. icon: () => (
  1301. <Image src={fixedDefault} class={styles.staffImg} />
  1302. ),
  1303. title: () => <span class={styles.name}>简谱-固定调</span>,
  1304. value: () => (
  1305. <Radio name="JIAN">
  1306. {{
  1307. icon: (props: any) => (
  1308. <Icon
  1309. class={styles.boxStyle}
  1310. size={16}
  1311. name={
  1312. props.checked
  1313. ? activeButtonIcon
  1314. : inactiveButtonIcon
  1315. }
  1316. />
  1317. )
  1318. }}
  1319. </Radio>
  1320. )
  1321. }}
  1322. </Cell>
  1323. </CellGroup>
  1324. </RadioGroup>
  1325. </div>
  1326. </Popup>
  1327. <Popup
  1328. teleport="body"
  1329. position="bottom"
  1330. round
  1331. v-model:show={staffData.open}
  1332. >
  1333. <Picker
  1334. columns={partColumns.value}
  1335. defaultIndex={staffData.selectedPartIndex}
  1336. onConfirm={value => {
  1337. staffData.open = false;
  1338. staffData.selectedPartIndex = value.value;
  1339. staffData.imgs = [];
  1340. nextTick(() => {
  1341. let tempPdf = "";
  1342. if (staffData.isComberRender && value.xmlIndex === 999) {
  1343. if (getCurrentPdf(staffData.list, staff.radio)) {
  1344. tempPdf = getCurrentPdf(staffData.list, staff.radio);
  1345. }
  1346. } else {
  1347. const item = getInstrumentItem(staffData.list, value.track);
  1348. if (item && getCurrentPdf(item, staff.radio)) {
  1349. tempPdf = getCurrentPdf(item, staff.radio);
  1350. }
  1351. }
  1352. staffData.musicPdfUrl = tempPdf;
  1353. if (tempPdf) {
  1354. renderStaff();
  1355. } else {
  1356. loading.value = true;
  1357. if (staffData.musicPdfUrl) {
  1358. staffData.musicPdfUrl = "";
  1359. renderStaff();
  1360. } else {
  1361. resetRender();
  1362. }
  1363. }
  1364. });
  1365. }}
  1366. onCancel={() => (staffData.open = false)}
  1367. />
  1368. </Popup>
  1369. </div>
  1370. )
  1371. }
  1372. }
  1373. })