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, NoticeBar, 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; data.musicPdfUrl = '' data.iframeSrc = '' console.log(props.item, '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 trackList = computed(() => { return data.trackList.map((item: any) => { return { ...item, color: data.selectMusicInstrumentIndex === item.value ? 'var(--van-primary-color)' : '', className: data.selectMusicInstrumentIndex === 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, code: string ) => { const codeIdMap = new Map() 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, isEnsemble.value , data.musicPdfUrl , !isMusicImg.value); }; const __init = async () => { await analyzeXml(); musicIframeLoad(); }; /** 去云练习 */ const handleGoto = () => { emit('handleGoto', item.value, data.showMusicImg, data.selectMusicInstrumentIndex) }; onMounted(() => { __init(); }); return () => (
{data.iframeSrc && (isEnsemble.value || data.musicPdfUrl || !isMusicImg.value) ? (
<> {item.value?.id ? ( data.musicPdfUrl ? ( ) : ( ) ) : ( '' )}
) : (
{data.showMusicImg === 'first' ? ( <> {item.value?.musicFirstImg ?.split(',') .map((item: any, index: number) => { return ( ); })} ) : data.showMusicImg === 'fixed' ? ( <> {item.value?.musicJianImg ?.split(',') .map((item: any, index: number) => { return ( ); })} ) : ( <> {item.value?.musicImg ?.split(',') .map((item: any, index: number) => { return (
{item.value?.musicSheetName}
{data.showMusicImg === 'first' ? ( <> {item.value?.musicFirstImg ?.split(',') .map((item: any, index: number) => { return ( ); })} ) : data.showMusicImg === 'fixed' ? ( <> {item.value?.musicJianImg ?.split(',') .map((item: any, index: number) => { return ( ); })} ) : ( <> {item.value?.musicImg ?.split(',') .map((item: any, index: number) => { return ( { // console.log(item, 'item') data.selectMusicInstrumentIndex = item.value data.showChangeVoice = false; musicIframeLoad(); }}> {{ reference: () => (
声部
) }} )} {data.showTransBtn && ( { data.showMusicImg = item.value; data.popoverShow = false; musicIframeLoad(); }}> {{ reference: () => (
转谱
) }}
)} {!isEnsemble.value && (isMusicImg.value || data.musicPdfUrl) && (
下载
)}
); } });