|
@@ -0,0 +1,635 @@
|
|
|
+import {
|
|
|
+ computed,
|
|
|
+ defineComponent,
|
|
|
+ onMounted,
|
|
|
+ reactive,
|
|
|
+ ref,
|
|
|
+ toRef,
|
|
|
+ TransitionGroup,
|
|
|
+ watch
|
|
|
+} from 'vue';
|
|
|
+import styles from './index.module.less';
|
|
|
+import iconChange from '../images/icon-change.png';
|
|
|
+import iconDownload from '../images/icon-download.png';
|
|
|
+import iconStaff from '../images/icon-staff.png';
|
|
|
+import staff from '../images/staff/staff.png'
|
|
|
+import staffActive from '../images/staff/staff-active.png'
|
|
|
+import first from '../images/staff/first.png'
|
|
|
+import firstActive from '../images/staff/first-active.png'
|
|
|
+import fixed from '../images/staff/fixed.png'
|
|
|
+import fixedActive from '../images/staff/fixed-active.png'
|
|
|
+import { Button, Popover, showLoadingToast, showToast } from 'vant';
|
|
|
+import { state } from '@/state';
|
|
|
+import {
|
|
|
+ getInstrumentName,
|
|
|
+ sortMusical,
|
|
|
+ vaildMusicScoreUrl
|
|
|
+} from '@/helpers/utils';
|
|
|
+import { storage } from '@/helpers/storage';
|
|
|
+import { ACCESS_TOKEN } from '@/store/mutation-types';
|
|
|
+import { promisefiyPostMessage } from '@/helpers/native-message';
|
|
|
+import html2canvas from 'html2canvas';
|
|
|
+import { addWatermark, convasToImg } from '@/views/co-ai/imageFunction';
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: 'music-detail',
|
|
|
+ props: {
|
|
|
+ item: {
|
|
|
+ type: Object,
|
|
|
+ default: () => ({})
|
|
|
+ }
|
|
|
+ },
|
|
|
+ emits: ['handleGoto'],
|
|
|
+ setup(props, { emit }) {
|
|
|
+ const item = toRef(props.item);
|
|
|
+ const data = reactive({
|
|
|
+ musicPdfUrl: '',
|
|
|
+ iframeSrc: '',
|
|
|
+ selectMusicInstrumentIndex: 0,
|
|
|
+ popoverShow: false,
|
|
|
+ showChangeVoice: false,
|
|
|
+ /** 显示哪种曲谱 */
|
|
|
+ showMusicImg: 'staff' as 'staff' | 'first' | 'fixed',
|
|
|
+ trackList: [] as any, // 可筛选的分轨信息
|
|
|
+ showTransBtn: true // 是否显示转谱按钮
|
|
|
+ });
|
|
|
+ const downRef = ref();
|
|
|
+
|
|
|
+ watch(
|
|
|
+ () => props.item,
|
|
|
+ () => {
|
|
|
+ item.value = props.item;
|
|
|
+ __init();
|
|
|
+ }
|
|
|
+ );
|
|
|
+
|
|
|
+ const _actions = computed(() => {
|
|
|
+ const details = item.value;
|
|
|
+ let { scoreType, isConvertibleScore } = details || {};
|
|
|
+
|
|
|
+ let action: any[] = [
|
|
|
+ {
|
|
|
+ value: 'first',
|
|
|
+ text: '首调',
|
|
|
+ icon: first
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 'fixed',
|
|
|
+ text: '固定调',
|
|
|
+ icon: fixed
|
|
|
+ }
|
|
|
+ ];
|
|
|
+
|
|
|
+ if (
|
|
|
+ !(
|
|
|
+ ['JIAN', 'FIRST'].includes(scoreType) && isConvertibleScore === false
|
|
|
+ ) &&
|
|
|
+ !(isConvertibleScore === undefined || isConvertibleScore === null)
|
|
|
+ ) {
|
|
|
+ action.unshift({
|
|
|
+ value: 'staff',
|
|
|
+ text: '五线谱',
|
|
|
+ icon: staff
|
|
|
+ });
|
|
|
+ }
|
|
|
+ action.forEach((item: any) => {
|
|
|
+ if(item.value === data.showMusicImg) {
|
|
|
+ if(item.value === 'first') {
|
|
|
+ item.icon = firstActive
|
|
|
+ } else if(item.value == 'fixed') {
|
|
|
+ item.icon = fixedActive
|
|
|
+ } else if(item.value === 'staff') {
|
|
|
+ item.icon = staffActive
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ return action.map((item, index) => {
|
|
|
+ return {
|
|
|
+ ...item,
|
|
|
+ color:
|
|
|
+ data.showMusicImg === item.value ? 'var(--van-primary-color)' : '',
|
|
|
+ className: data.showMusicImg === item.value ? 'fontBlod' : ''
|
|
|
+ };
|
|
|
+ });
|
|
|
+ });
|
|
|
+
|
|
|
+ /** 保存图片 */
|
|
|
+ const handleSave = async () => {
|
|
|
+ if (data.musicPdfUrl) {
|
|
|
+ const songName = item.value?.musicSheetName;
|
|
|
+ promisefiyPostMessage({
|
|
|
+ api: 'downloadFile',
|
|
|
+ content: {
|
|
|
+ downloadUrl: data.musicPdfUrl,
|
|
|
+ fileName: songName
|
|
|
+ }
|
|
|
+ });
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ showLoadingToast({ message: '正在保存', duration: 0 });
|
|
|
+ try {
|
|
|
+ html2canvas(downRef.value, {
|
|
|
+ backgroundColor: '#fff',
|
|
|
+ allowTaint: true,
|
|
|
+ useCORS: true
|
|
|
+ })
|
|
|
+ .then(async canvas => {
|
|
|
+ // 添加水印
|
|
|
+ const waterCanvasImg = await addWatermark(canvas);
|
|
|
+ // canvas转图片
|
|
|
+ const dataURL = await convasToImg(waterCanvasImg);
|
|
|
+ console.log(dataURL, 'dataURL');
|
|
|
+ setTimeout(() => {
|
|
|
+ showToast('已保存到相册');
|
|
|
+ }, 500);
|
|
|
+ await promisefiyPostMessage({
|
|
|
+ api: 'savePicture',
|
|
|
+ content: {
|
|
|
+ base64: dataURL
|
|
|
+ }
|
|
|
+ });
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ setTimeout(() => {
|
|
|
+ showToast('保存失败');
|
|
|
+ }, 500);
|
|
|
+ });
|
|
|
+ } catch (error) {
|
|
|
+ setTimeout(() => {
|
|
|
+ showToast('保存失败');
|
|
|
+ }, 500);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 根据musicSheetType返回的值,判断是否显示切换声轨按钮
|
|
|
+ const isEnsemble = computed(() => {
|
|
|
+ if (item.value) {
|
|
|
+ const musicSheetType = item.value?.musicSheetType;
|
|
|
+ if (musicSheetType === 'SINGLE') {
|
|
|
+ return false;
|
|
|
+ } else {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // 判断 值当前有没有图片
|
|
|
+ const isMusicImg = computed(() => {
|
|
|
+ const musicsData = item.value;
|
|
|
+ if (data.showMusicImg === 'first' && musicsData?.musicFirstImg) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (data.showMusicImg === 'fixed' && musicsData?.musicJianImg) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ if (musicsData?.musicImg) {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+ return false;
|
|
|
+ });
|
|
|
+
|
|
|
+ // 判断是否可转谱 - 为空也可以转谱
|
|
|
+ const checkConverTible = (isConvertibleScore: any, scoreType: string) => {
|
|
|
+ if (
|
|
|
+ isConvertibleScore ||
|
|
|
+ isConvertibleScore === '' ||
|
|
|
+ isConvertibleScore === undefined ||
|
|
|
+ isConvertibleScore === null ||
|
|
|
+ (['JIAN', 'FIRST'].includes(scoreType) && !isConvertibleScore)
|
|
|
+ ) {
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // 解析xml,获取分轨信息
|
|
|
+ const analyzeXml = async () => {
|
|
|
+ const details = item.value;
|
|
|
+ console.log(details?.musicSheetType, 'details?.musicSheetType');
|
|
|
+ if (details?.musicSheetType === 'CONCERT') {
|
|
|
+ if (details.xmlFileUrl) {
|
|
|
+ const res = await fetch(details.xmlFileUrl).then(response =>
|
|
|
+ response.text()
|
|
|
+ );
|
|
|
+ filterTracks(res);
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ // showMusicImg: 'first' as 'staff' | 'first' | 'fixed',
|
|
|
+ const { scoreType, isConvertibleScore } = details || {};
|
|
|
+ let musicImgType: 'staff' | 'first' | 'fixed' = 'first';
|
|
|
+ musicImgType =
|
|
|
+ scoreType === 'STAVE'
|
|
|
+ ? 'staff'
|
|
|
+ : scoreType === 'JIAN'
|
|
|
+ ? 'fixed'
|
|
|
+ : scoreType === 'FIRST'
|
|
|
+ ? 'first'
|
|
|
+ : 'first';
|
|
|
+ data.showMusicImg = musicImgType;
|
|
|
+ data.showTransBtn = checkConverTible(isConvertibleScore, scoreType);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 获取分轨名称 */
|
|
|
+ const getInstrumentNameCode = (instruments: any, name = '') => {
|
|
|
+ name = name.toLocaleLowerCase().replace(/ /g, '').replace(/\d*/gi, '');
|
|
|
+ if (!name) return '';
|
|
|
+ for (let key of instruments) {
|
|
|
+ const _key = key.toLocaleLowerCase().replace(/ /g, '');
|
|
|
+ // if (_key.includes(name)) {
|
|
|
+ // return key
|
|
|
+ // }
|
|
|
+ if (_key === name) {
|
|
|
+ return _key;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // for (let key of instruments) {
|
|
|
+ // const _key = key.toLocaleLowerCase().replace(/ /g, '')
|
|
|
+ // if (name.includes(_key)) {
|
|
|
+ // return key
|
|
|
+ // }
|
|
|
+ // }
|
|
|
+ return '';
|
|
|
+ };
|
|
|
+ // 通过乐器编码返回乐器编号
|
|
|
+ const instrumentCodeToInstrumentId = (
|
|
|
+ subjectList: Array<any>,
|
|
|
+ code: string
|
|
|
+ ) => {
|
|
|
+ const codeIdMap = new Map<string, []>() as any;
|
|
|
+ const codeMapKeys: string[] = [];
|
|
|
+ subjectList.forEach((data: any) => {
|
|
|
+ if (data.enableFlag) {
|
|
|
+ const codes = data.code?.split(/[,,]/);
|
|
|
+ codes.forEach((code: string) => {
|
|
|
+ let codeTemp = code?.replace(/ /g, '').toLowerCase();
|
|
|
+ codeMapKeys.push(codeTemp);
|
|
|
+ if (codeIdMap.has(codeTemp)) {
|
|
|
+ codeIdMap.get(codeTemp).push(data.id + '');
|
|
|
+ } else {
|
|
|
+ const arr = [] as any;
|
|
|
+ arr.push(data.id + '');
|
|
|
+ codeIdMap.set(codeTemp, arr);
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ if (!code) {
|
|
|
+ return '';
|
|
|
+ }
|
|
|
+ code = code && code?.replace(/ /g, '').toLowerCase();
|
|
|
+ const tempCode = getInstrumentNameCode(codeMapKeys, code);
|
|
|
+ if (codeIdMap.has(tempCode)) {
|
|
|
+ const result = codeIdMap.get(tempCode);
|
|
|
+ console.log('result:', result);
|
|
|
+ return result[0] || '';
|
|
|
+ }
|
|
|
+ return '';
|
|
|
+ };
|
|
|
+
|
|
|
+ // 初始化编号
|
|
|
+ const initUserDefaultInstrument = () => {
|
|
|
+ const userInstrumentId = state.user.data.instrumentId;
|
|
|
+ const item = data.trackList.find(
|
|
|
+ (track: any) => track.instrumentId === userInstrumentId + ''
|
|
|
+ );
|
|
|
+ data.selectMusicInstrumentIndex = item ? item.value : 0;
|
|
|
+ };
|
|
|
+
|
|
|
+ // 过滤出能切换的分轨
|
|
|
+ const filterTracks = (xml: any) => {
|
|
|
+ const xmlParse = new DOMParser().parseFromString(xml, 'text/xml');
|
|
|
+ const partList: any =
|
|
|
+ xmlParse
|
|
|
+ .getElementsByTagName('part-list')?.[0]
|
|
|
+ ?.getElementsByTagName('score-part') || [];
|
|
|
+ const partListNames = Array.from(partList).map(
|
|
|
+ (item: any) =>
|
|
|
+ item.getElementsByTagName('part-name')?.[0]?.textContent?.trim() ||
|
|
|
+ item.getAttribute('id') ||
|
|
|
+ ''
|
|
|
+ );
|
|
|
+ const parts: any = xmlParse.getElementsByTagName('part');
|
|
|
+
|
|
|
+ /** 第一分谱如果是约定的配置分谱则跳过 */
|
|
|
+ if (partListNames[0]?.toLocaleUpperCase?.() === 'COMMON') {
|
|
|
+ partListNames.shift();
|
|
|
+ }
|
|
|
+ // 根据后台已选择的分轨筛选出能切换的声轨
|
|
|
+ const multiTracksSelection = item.value?.multiTracksSelection;
|
|
|
+ const canSelectTracks = multiTracksSelection
|
|
|
+ ? multiTracksSelection?.split(',')
|
|
|
+ : [];
|
|
|
+ const musicalInstruments = item.value?.musicalInstruments || [];
|
|
|
+ const arr = partListNames
|
|
|
+ .map((item: any, index: number) => {
|
|
|
+ // 该声轨能否被选
|
|
|
+ const canselect =
|
|
|
+ canSelectTracks.length == 0 || canSelectTracks.includes(item)
|
|
|
+ ? true
|
|
|
+ : false;
|
|
|
+
|
|
|
+ const instrumentName = getInstrumentName(item);
|
|
|
+ const instrumentId = instrumentCodeToInstrumentId(
|
|
|
+ musicalInstruments,
|
|
|
+ item
|
|
|
+ );
|
|
|
+ const sortId = sortMusical(instrumentName, index);
|
|
|
+ return {
|
|
|
+ text: item + (instrumentName ? `(${instrumentName})` : ''),
|
|
|
+ value: index,
|
|
|
+ instrumentId,
|
|
|
+ sortId,
|
|
|
+ canselect,
|
|
|
+ track: item
|
|
|
+ };
|
|
|
+ })
|
|
|
+ .filter((item: any) => item.canselect);
|
|
|
+ //.sort((a: any, b: any) => a.sortId - b.sortId);
|
|
|
+ data.trackList = arr;
|
|
|
+
|
|
|
+ // 是否显示总谱
|
|
|
+ const selectMusic = item.value;
|
|
|
+ if (selectMusic) {
|
|
|
+ const musicalInstruments = selectMusic.musicalInstruments || [];
|
|
|
+ if (selectMusic.isScoreRender) {
|
|
|
+ data.trackList.unshift({
|
|
|
+ text: '总谱',
|
|
|
+ value: 999,
|
|
|
+ sortId: 0,
|
|
|
+ canselect: true,
|
|
|
+ track: 999
|
|
|
+ });
|
|
|
+
|
|
|
+ if (selectMusic.defaultScoreRender) {
|
|
|
+ data.selectMusicInstrumentIndex = 999;
|
|
|
+ } else {
|
|
|
+ initUserDefaultInstrument();
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ initUserDefaultInstrument();
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const details = item.value;
|
|
|
+ const { scoreType, isConvertibleScore } = details || {};
|
|
|
+ let musicImgType: 'staff' | 'first' | 'fixed' = 'first';
|
|
|
+ musicImgType =
|
|
|
+ scoreType === 'STAVE'
|
|
|
+ ? 'staff'
|
|
|
+ : scoreType === 'JIAN'
|
|
|
+ ? 'fixed'
|
|
|
+ : scoreType === 'FIRST'
|
|
|
+ ? 'first'
|
|
|
+ : 'first';
|
|
|
+ data.showMusicImg = musicImgType;
|
|
|
+ data.showTransBtn = checkConverTible(isConvertibleScore, scoreType);
|
|
|
+ };
|
|
|
+
|
|
|
+ const musicIframeLoad = () => {
|
|
|
+ const token = storage.get(ACCESS_TOKEN);
|
|
|
+ const details = item.value;
|
|
|
+ if (!details?.id) {
|
|
|
+ data.iframeSrc = '';
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ // 如果在配置里面匹配不到,则默认显示五线谱
|
|
|
+ const musicRenderType =
|
|
|
+ data.showMusicImg === 'first'
|
|
|
+ ? 'firstTone'
|
|
|
+ : data.showMusicImg === 'fixed'
|
|
|
+ ? 'fixedTone'
|
|
|
+ : data.showMusicImg === 'staff'
|
|
|
+ ? 'staff'
|
|
|
+ : 'staff';
|
|
|
+
|
|
|
+ // pdf
|
|
|
+ const musicSheetType = details?.musicSheetType;
|
|
|
+ let musicPdfUrl = '';
|
|
|
+
|
|
|
+ if (
|
|
|
+ musicSheetType === 'SINGLE' ||
|
|
|
+ data.selectMusicInstrumentIndex === 999
|
|
|
+ ) {
|
|
|
+ if (data.showMusicImg === 'first') {
|
|
|
+ musicPdfUrl = details.firstPdfUrl;
|
|
|
+ } else if (data.showMusicImg === 'fixed') {
|
|
|
+ musicPdfUrl = details.jianPdfUrl;
|
|
|
+ } else {
|
|
|
+ musicPdfUrl = details.musicPdfUrl;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ const trackList = data.trackList || [];
|
|
|
+ const selectTrack = trackList.find(
|
|
|
+ (item: any) => item.value === data.selectMusicInstrumentIndex
|
|
|
+ );
|
|
|
+ const background = details.background || [];
|
|
|
+ const selectItem = background.find(
|
|
|
+ (item: any) =>
|
|
|
+ item.track === selectTrack?.track && item.audioPlayType === 'PLAY'
|
|
|
+ );
|
|
|
+ if (selectItem) {
|
|
|
+ if (data.showMusicImg === 'first') {
|
|
|
+ musicPdfUrl = selectItem.firstPdfUrl;
|
|
|
+ } else if (data.showMusicImg === 'fixed') {
|
|
|
+ musicPdfUrl = selectItem.jianPdfUrl;
|
|
|
+ } else {
|
|
|
+ musicPdfUrl = selectItem.musicPdfUrl;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ data.musicPdfUrl = musicPdfUrl;
|
|
|
+ if (musicPdfUrl) {
|
|
|
+ // data.iframeSrc = `/pdf/web/viewer.html?file=${encodeURIComponent(data.musicPdfUrl)}&t=${Date.now()}`;
|
|
|
+ data.iframeSrc = `${location.origin}${
|
|
|
+ location.pathname
|
|
|
+ }pdf/web/viewer.html?file=${encodeURIComponent(
|
|
|
+ data.musicPdfUrl
|
|
|
+ )}&t=${Date.now()}`;
|
|
|
+ } else {
|
|
|
+ // const origin = /(localhost|192)/.test(location.host)
|
|
|
+ // ? 'https://test.lexiaoya.cn'
|
|
|
+ // : location.origin;
|
|
|
+ // data.iframeSrc = `${origin}/instrument/?id=${details.id}&modelType=practise&modeType=json&Authorization=${token}&isPreView=true&part-index=${data.selectMusicInstrumentIndex}&musicRenderType=${musicRenderType}`;
|
|
|
+ data.iframeSrc = `${vaildMusicScoreUrl()}/instrument/?id=${
|
|
|
+ details?.id
|
|
|
+ }&modelType=practise&modeType=json&Authorization=${token}&isPreView=true&part-index=${
|
|
|
+ data.selectMusicInstrumentIndex
|
|
|
+ }&musicRenderType=${musicRenderType}&zoom=0.6`;
|
|
|
+ }
|
|
|
+
|
|
|
+ console.log('地址', data.iframeSrc);
|
|
|
+ };
|
|
|
+
|
|
|
+ const __init = async () => {
|
|
|
+ await analyzeXml();
|
|
|
+ musicIframeLoad();
|
|
|
+ };
|
|
|
+
|
|
|
+
|
|
|
+ /** 去云练习 */
|
|
|
+ const handleGoto = () => {
|
|
|
+ emit('handleGoto', item.value, data.showMusicImg, data.selectMusicInstrumentIndex)
|
|
|
+ };
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ __init();
|
|
|
+ });
|
|
|
+ return () => (
|
|
|
+ <div class={styles.musicDetail}>
|
|
|
+ <div class={styles.musicContainer}>
|
|
|
+ <div class={styles.container} ref={downRef}>
|
|
|
+ <div
|
|
|
+ class={styles['right-musicName']}
|
|
|
+ style={{
|
|
|
+ opacity: !data.musicPdfUrl ? '1' : '0',
|
|
|
+ height: !data.musicPdfUrl ? 'auto' : '0'
|
|
|
+ }}>
|
|
|
+ {item.value?.musicSheetName}
|
|
|
+ </div>
|
|
|
+ {data.iframeSrc &&
|
|
|
+ (isEnsemble.value || data.musicPdfUrl || !isMusicImg.value) ? (
|
|
|
+ <div class={styles.iframeSection}>
|
|
|
+ <>
|
|
|
+ {item.value?.id ? (
|
|
|
+ data.musicPdfUrl ? (
|
|
|
+ <iframe
|
|
|
+ id="staffIframeRef"
|
|
|
+ style={{
|
|
|
+ width: '100%'
|
|
|
+ // opacity: loading.value ? 0 : 1
|
|
|
+ }}
|
|
|
+ src={data.iframeSrc}></iframe>
|
|
|
+ ) : (
|
|
|
+ <iframe
|
|
|
+ id="staffIframeRef"
|
|
|
+ style={{
|
|
|
+ width: '100%'
|
|
|
+ // opacity: loading.value ? 0 : 1
|
|
|
+ }}
|
|
|
+ src={data.iframeSrc}></iframe>
|
|
|
+ )
|
|
|
+ ) : (
|
|
|
+ ''
|
|
|
+ )}
|
|
|
+ </>
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <div class={styles.imgSection}>
|
|
|
+ {data.showMusicImg === 'first' ? (
|
|
|
+ <>
|
|
|
+ {item.value?.musicFirstImg
|
|
|
+ ?.split(',')
|
|
|
+ .map((item: any, index: number) => {
|
|
|
+ return (
|
|
|
+ <img
|
|
|
+ class={styles.staff}
|
|
|
+ src={item}
|
|
|
+ key={item}
|
|
|
+ crossorigin="anonymous"
|
|
|
+ />
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </>
|
|
|
+ ) : data.showMusicImg === 'fixed' ? (
|
|
|
+ <>
|
|
|
+ <TransitionGroup name="van-fade">
|
|
|
+ {item.value?.musicJianImg
|
|
|
+ ?.split(',')
|
|
|
+ .map((item: any, index: number) => {
|
|
|
+ return (
|
|
|
+ <img
|
|
|
+ class={styles.staff}
|
|
|
+ src={item}
|
|
|
+ key={item}
|
|
|
+ crossorigin="anonymous"
|
|
|
+ />
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </TransitionGroup>
|
|
|
+ </>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ {item.value?.musicImg
|
|
|
+ ?.split(',')
|
|
|
+ .map((item: any, index: number) => {
|
|
|
+ return (
|
|
|
+ <img
|
|
|
+ class={styles.staff}
|
|
|
+ src={item + '?v=' + Date.now()}
|
|
|
+ key={item}
|
|
|
+ crossorigin="anonymous"
|
|
|
+ />
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class={styles.btnGroup}>
|
|
|
+ <div class={styles.operation}>
|
|
|
+ {isEnsemble.value && (
|
|
|
+ <Popover
|
|
|
+ v-model:show={data.showChangeVoice}
|
|
|
+ class={styles.popover}
|
|
|
+ actions={data.trackList}
|
|
|
+ placement="top-start"
|
|
|
+ onSelect={(item: any) => {
|
|
|
+ console.log(item, 'item')
|
|
|
+ // data.showMusicImg = item.value;
|
|
|
+ data.showChangeVoice = false;
|
|
|
+ // musicIframeLoad();
|
|
|
+ }}>
|
|
|
+ {{
|
|
|
+ reference: () => (
|
|
|
+ <div class={styles.item}>
|
|
|
+ <img src={iconChange} class={styles.icon} />
|
|
|
+ <span>声部</span>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </Popover>
|
|
|
+ )}
|
|
|
+ {data.showTransBtn && (
|
|
|
+ <Popover
|
|
|
+ v-model:show={data.popoverShow}
|
|
|
+ class={styles.popover}
|
|
|
+ actions={_actions.value}
|
|
|
+ placement="top-start"
|
|
|
+ onSelect={(item: any) => {
|
|
|
+ data.showMusicImg = item.value;
|
|
|
+ data.popoverShow = false;
|
|
|
+ musicIframeLoad();
|
|
|
+ }}>
|
|
|
+ {{
|
|
|
+ reference: () => (
|
|
|
+ <div class={styles.item}>
|
|
|
+ <img src={iconStaff} class={styles.icon} />
|
|
|
+ <span>转谱</span>
|
|
|
+ </div>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </Popover>
|
|
|
+ )}
|
|
|
+ {!isEnsemble.value && (isMusicImg.value || data.musicPdfUrl) && (
|
|
|
+ <div class={styles.item} onClick={handleSave}>
|
|
|
+ <img src={iconDownload} class={styles.icon} />
|
|
|
+ <span>下载</span>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ <Button round class={styles.goBtn} onClick={handleGoto}>
|
|
|
+ 立即练习
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|