index.tsx 49 KB

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