index.tsx 50 KB

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