import { Transition, TransitionGroup, computed, defineComponent, nextTick, onMounted, onUnmounted, reactive, ref, watch } from 'vue'; import styles from './index.module.less'; import icon_back from './images/icon_back.png'; import icon_separator from './images/icon_separator.png'; import { NBreadcrumb, NBreadcrumbItem, NButton, NEmpty, NImage, NModal, NPopselect, NSpace, NSpin, NPopover } from 'naive-ui'; import TheSearch from '/src/components/TheSearch'; import { IMusicItem } from './type'; import icon_arrow from './images/icon_arrow.png'; // import icon_play from './images/icon_play.png'; // import icon_pause from './images/icon_pause.png'; import icon_goXiaoku from './images/icon_goXiaoku.png'; import icon_favitor from './images/icon-collect-default.png'; import icon_favitorActive from './images/icon-collect-active.png'; import icon_default from './images/icon_default.png'; import icon_close from './images/icon-close.png'; // import icon_trans from './images/icon_trans.png'; import icon_trans_default from './images/icon_trans_default.png'; import { useRoute, useRouter } from 'vue-router'; import PlayItem from './component/play-item'; import PlayLoading from './component/play-loading'; import TheNoticeBar from '/src/components/TheNoticeBar'; import { useCatchStore } from '/src/store/modules/catchData'; import { api_materialFavorite, api_materialFavoriteStatus, api_musicSheetPage // api_subjectList } from '../xiaoku-ai/api'; import { useUserStore } from '/src/store/modules/users'; import Musicguide from '@/custom-plugins/guide-page/music-guide'; import TheEmpty from '/src/components/TheEmpty'; import { modalClickMask, state } from '/src/state'; import { useResizeObserver } from '@vueuse/core'; import { vaildMusicScoreUrl } from '/src/utils/urlUtils'; import { getInstrumentName, sortMusical } from '/src/utils'; import { audioPlayType } from '/src/utils/contants'; import CCascader from '/src/components/CCascader'; export default defineComponent({ name: 'XiaokuMusic', setup() { const catchStore = useCatchStore(); const user = useUserStore(); const route = useRoute(); const router = useRouter(); const forms = reactive({ page: 1, rows: 20, status: true, name: '', // 关键词 audioPlayTypes: '', musicSheetCategoriesId: route.query.id || '' }); const data = reactive({ loading: false, finshed: false, reshing: false, tags: [] as any[], tagIndex: 0, musicalInstrumentId: '', musicSubject: '', list: [] as unknown as IMusicItem[], listActive: 0, musicInstrumentIndex: 0, playState: 'pause' as 'play' | 'pause', showPlayer: false, previewModal: false, showPreivew: false, previewUrl: '', showCloseBtn: true, audioPlayTypeList: [] as any, iframeSrc: '', showMusicImg: 'staff' as 'staff' | 'first' | 'fixed', // 显示哪种曲谱 trackList: [] as any, // 可筛选的分轨信息 showTransBtn: true, // 是否显示转谱按钮 trackName: '切换声部' as any // 分轨名字 }); const subjects = ref(''); const showGuide = ref(false); const userStore = useUserStore(); let musicsrc = ''; const formatParentCurrentValue = (list: any) => { for (const item of list) { if (item.instruments && item.instruments.length > 0) { item.instruments.forEach((child: any) => { child.columnName = '乐器'; }); item.children = item.instruments; formatParentCurrentValue(item.instruments); } } }; const getSubjects = async () => { // const res = await api_subjectList(); // if (Array.isArray(res?.data)) { const tempSubjectList = catchStore.getSubjectList; const subjectList = sessionStorage.getItem('musicSubjectList') ? JSON.parse(sessionStorage.getItem('musicSubjectList') as any) : []; const resultList: any[] = []; // console.log(tempSubjectList, subjectList, 'subjectList'); tempSubjectList.forEach((item: any) => { const hasItem = subjectList.find((s: any) => s.id === item.id); if (hasItem) { resultList.push(item); } }); // data.tags = [ // { name: '全部', id: 0, value: 0, label: '全部' }, // ...resultList // ]; formatParentCurrentValue(resultList); data.tags = [ { columnName: '声部', name: '全部声部', id: '' }, ...resultList ]; // } }; const getList = async () => { data.loading = true; let res = {} as any; try { const { audioPlayTypes, ...result } = forms; res = await api_musicSheetPage({ ...result, audioPlayTypes: audioPlayTypes ? audioPlayTypes === 'PLAY_SING' ? ['PLAY', 'SING'] : [audioPlayTypes] : [], musicSubject: data.musicSubject, musicalInstrumentId: data.musicalInstrumentId }); } catch (error) { console.log(error); } // console.log(res, 'data', data.reshing, 'musicSubject'); if (data.reshing) { data.list = []; data.reshing = false; } if (res?.code === 200 && Array.isArray(res?.data?.rows)) { // console.log(res?.data?.rows); const tempResult = res?.data?.rows || []; tempResult.forEach((item: any) => { item.audioPlayTypeArray = item.audioPlayTypes ? item.audioPlayTypes.split(',') : []; }); data.list = [...data.list, ...res.data.rows]; data.finshed = forms.page >= res.data.pages //res.data.rows.length < forms.rows; // 是否显示总谱 const selectMusic = data.list[data.listActive]; if (selectMusic && selectMusic.isScoreRender && data.listActive === 0) { data.musicInstrumentIndex = 999; } await analyzeXml(); musicIframeLoad(); } else { data.finshed = true; } if (data.list[data.listActive]) { getFavitor(data.list[data.listActive]); } data.loading = false; setTimeout(() => { showGuide.value = true; }, 500); }; const handleGetList = async () => { data.listActive = 0; data.showPlayer = false; data.playState = 'pause'; forms.page = 1; data.finshed = false; await getList(); }; const spinRef = ref(); const handleResh = () => { if (data.loading || data.finshed) return; forms.page = forms.page + 1; getList(); }; // ifram事件处理 const iframeHandle = (ev: MessageEvent) => { if (ev.data?.api === 'api_fingerPreView') { data.showCloseBtn = !ev.data.state; } }; onMounted(async () => { // 场景 const tempAudio = Object.keys(audioPlayType).map(key => { return { value: key, label: audioPlayType[key] }; }); data.audioPlayTypeList = [{ label: '全部', value: '' }, ...tempAudio]; // 获取声部列表 await catchStore.getSubjects(); // musicList-container useResizeObserver( document.querySelector('.musicList-container') as HTMLElement, (entries: any) => { const entry = entries[0]; const { height } = entry.contentRect; // console.log(height, 'height - 11'); document.documentElement.style.setProperty( '--xiaoku-music-height', height + 'px' ); } ); getSubjects(); await getList(); const obv = new IntersectionObserver(entries => { if (entries[0].intersectionRatio > 0) { handleResh(); } }); obv.observe(spinRef.value); // analyzeXml(); // musicIframeLoad(); window.addEventListener('message', iframeHandle); }); onUnmounted(() => { window.removeEventListener('message', iframeHandle); }); /** 查看收藏状态 */ const getFavitor = async (item: any) => { const res = await api_materialFavoriteStatus({ type: 'MUSIC', materialId: item.id }); if (res?.code === 200) { item.favitor = res.data; } }; /** 改变模仿的曲谱 */ const handleChange = (item: IMusicItem) => { const index = data.list.findIndex(_item => _item.id === item.id); if (index > -1) { data.listActive = index; } getFavitor(item); }; const selectChildObj = (item: any) => { const obj: any = {}; item?.forEach((child: any) => { if (child.id === data.tagIndex) { obj.selected = true; obj.name = child.name; } }); return obj; }; /** 选中的item */ const activeItem = computed(() => { if (data.list[data.listActive]) { // const origin = /(localhost|192)/.test(location.host) // ? 'https://dev.kt.colexiu.com' // : location.origin; // console.log( // data.list[data.listActive].xmlFileUrl, // 'data.list[data.listActive]' // ); musicsrc = `${vaildMusicScoreUrl()}/instrument/?modelType=practise&id=${ data.list[data.listActive]?.xmlFileUrl }&Authorization=${userStore.getToken}/#/preview`; } else { musicsrc = ''; } return data.list[data.listActive] || {}; }); /** 收藏曲谱 */ const handleFavitor = () => { data.list[data.listActive].favitor = !data.list[data.listActive].favitor; api_materialFavorite({ favoriteFlag: data.list[data.listActive].favitor, type: 'MUSIC', materialId: data.list[data.listActive].id }); }; /** 播放曲目 */ const handlePlay = (item: IMusicItem) => { const index = data.list.findIndex(_item => _item.id === item.id); if (index > -1) { if (data.listActive === index) { data.playState = data.playState === 'play' ? 'pause' : 'play'; } else { data.playState = 'play'; } data.showPlayer = true; data.listActive = index; } }; const musicalInstruments = computed(() => { const details: any = data.list[data.listActive]; const musics = details?.musicalInstruments || []; const temp: any = []; musics.forEach((item: any, index: number) => { temp.push({ label: item.name, value: index }); }); return temp; }); // 根据musicSheetType返回的值,判断是否显示切换声部按钮 const isEnsemble = computed(() => { // const details: any = data.list[data.listActive]; // const musics: any = details?.musicalInstruments; // if (musics && musics.length > 1) { // return true; // } else { // return false; // } if (data.list.length) { const musicSheetType: any = data.list[data.listActive]?.musicSheetType; if (musicSheetType === 'SINGLE') { return false; } else { return true; } } else { 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; } }; const musicIframeLoad = () => { const token = userStore.getToken; const details = data.list[data.listActive]; if(!details?.id) { data.iframeSrc = "" return } // const origin = /(localhost|192)/.test(location.host) // ? 'https://test.lexiaoya.cn' // : location.origin; // console.log( // origin, // 'origin', // `${origin}/instrument/?id=${details.id}&modelType=practise&modeType=json&Authorization=${token}&isPreView=true&part-index=${data.musicInstrumentIndex}` // ); const musicRenderType = data.showMusicImg === 'first' ? 'firstTone' : data.showMusicImg === 'fixed' ? 'fixedTone' : data.showMusicImg === 'staff' ? 'staff' : 'staff'; data.iframeSrc = `${vaildMusicScoreUrl()}/instrument/?id=${ details?.id }&modelType=practise&modeType=json&Authorization=${token}&isPreView=true&part-index=${ data.musicInstrumentIndex }&musicRenderType=${musicRenderType}`; console.log(data.iframeSrc, 'iframeSrc'); }; /** 音频控制 */ const handleChangeAudio = ( type: 'play' | 'pause' | 'pre' | 'next' | 'favitor' ) => { if (type === 'play') { data.playState = 'play'; } else if (type === 'pause') { data.playState = 'pause'; } else if (type === 'pre') { if (data.list[data.listActive - 1]) { handlePlay(data.list[data.listActive - 1]); } } else if (type === 'next') { if (data.list[data.listActive + 1]) { handlePlay(data.list[data.listActive + 1]); } } else if (type === 'favitor') { handleFavitor(); } }; const _actions = computed(() => { const details = data.list[data.listActive]; const { scoreType, isConvertibleScore } = details || {}; const action: any[] = [ { value: 'first', label: '首调' }, { value: 'fixed', label: '固定调' } ]; // 首调 固定调 并且 不显示可转谱 则不显示五线谱 if ( !( ['JIAN', 'FIRST'].includes(scoreType) && isConvertibleScore === false ) && !(isConvertibleScore === undefined || isConvertibleScore === null) ) { action.unshift({ value: 'staff', label: '五线谱' }); } return action; }); // 解析xml,获取分轨信息 const analyzeXml = async () => { const details: any = data.list[data.listActive]; if (details?.musicSheetType === 'CONCERT') { if (details.xmlFileUrl) { const res = await fetch(details.xmlFileUrl).then(response => response.text() ); filterTracks(res); } } else { // if (details.xmlFileUrl) { // const res = await fetch(details.xmlFileUrl).then(response => // response.text() // ); // console.log(res, '23233'); // const xmlParse = new DOMParser().parseFromString(res, 'text/xml'); // const partList = // xmlParse // .getElementsByTagName('part-list')?.[0] // ?.getElementsByTagName('score-part') || []; // const partListNames = Array.from(partList).map( // item => // item // .getElementsByTagName('part-name')?.[0] // ?.textContent?.trim() || '' // ); // } // showMusicImg: 'first' as 'staff' | 'first' | 'fixed', // const { defaultScore, transferFlag } = // details.musicalInstruments[0] || {}; // let musicImgType: 'staff' | 'first' | 'fixed' = 'staff'; // musicImgType = // defaultScore === 'STAVE' // ? 'staff' // : defaultScore === 'JIAN' // ? 'fixed' // : defaultScore === 'FIRST' // ? 'first' // : 'staff'; // console.log(musicImgType, 'musicImgType1'); // data.showMusicImg = musicImgType; // data.showTransBtn = transferFlag; 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 filterTracks = (xml: any) => { const xmlParse = new DOMParser().parseFromString(xml, 'text/xml'); const partList = xmlParse .getElementsByTagName('part-list')?.[0] ?.getElementsByTagName('score-part') || []; const partListNames = Array.from(partList).map( item => 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: any = data.list[data.listActive]?.multiTracksSelection; const canSelectTracks = multiTracksSelection ? multiTracksSelection?.split(',') : []; const arr = partListNames .map((item: any, index: number) => { // 该声轨能否被选 const canselect = canSelectTracks.length == 0 || canSelectTracks.includes(item) ? true : false; // console.log(canselect,index) const instrumentName = getInstrumentName(item); const sortId = sortMusical(instrumentName, index); return { label: item + (instrumentName ? `(${instrumentName})` : ''), value: index, sortId, canselect, track: item }; }) .filter((item: any) => item.canselect) .sort((a: any, b: any) => a.sortId - b.sortId); data.trackList = arr; // 是否显示总谱 const selectMusic = data.list[data.listActive]; if (selectMusic) { selectMusic.isScoreRender && data.trackList.unshift({ label: '总谱', value: 999, sortId: 0, canselect: true, track: 999 }); } // let track = arr.find( // (item: any) => item.value === data.musicInstrumentIndex // )?.track; // track = track // .replace(/[0-9]+/g, '') // .replace(/\s/g, '') // .toLocaleLowerCase(); // track = trackToCode(track); // let musicRenderType: 'staff' | 'first' | 'fixed' = 'staff'; // let canTrans = true; // data.list[data.listActive]?.musicalInstruments.forEach((item: any) => { // if (item.code.toLocaleLowerCase() === track.toLocaleLowerCase()) { // musicRenderType = // item.defaultScore === 'STAVE' // ? 'staff' // : item.defaultScore === 'JIAN' // ? 'fixed' // : item.defaultScore === 'FIRST' // ? 'first' // : 'staff'; // canTrans = item.transferFlag; // } // }); // data.showTransBtn = canTrans; // data.showMusicImg = musicRenderType; const details = data.list[data.listActive]; 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); }; watch( () => data.listActive, async () => { data.musicInstrumentIndex = 0; analyzeXml(); } ); // watch( // () => data.musicInstrumentIndex, // async () => { // data.trackName = // data.trackList.find( // (item: any) => item.value === data.musicInstrumentIndex // )?.label || '切换声部'; // musicIframeLoad(); // } // ); // 合奏曲谱转换时,更新曲谱信息 // watch( // () => data.showMusicImg, // () => { // if (isEnsemble.value) { // musicIframeLoad(); // } // } // ); const musicImg = computed(() => { let imgs: any = []; if (data.showMusicImg === 'first') { const img = activeItem.value?.musicFirstImg; imgs = img ? img.split(',') : []; } else if (data.showMusicImg === 'fixed') { const img = activeItem.value?.musicJianImg; imgs = img ? img.split(',') : []; } else if (data.showMusicImg === 'staff') { const img = activeItem.value?.musicImg || activeItem.value?.musicSvg; imgs = img ? img.split(',') : []; } return imgs; }); return () => (
router.push({ path: '/xiaoku-ai' })} /> router.push({ path: '/xiaoku-ai' })}> 全部列表 {route.query.name}
{data.audioPlayTypeList.map((item: any) => ( { forms.audioPlayTypes = item.value || ''; if (item.value === 'SING') { data.musicalInstrumentId = ''; data.musicSubject = ''; } data.reshing = true; document .querySelector('.musicList-container') ?.scroll(0, 0); await handleGetList(); }}> {item.label} ))} {/*
{data.tags.map(item => item.instruments && item.instruments.length > 1 ? ( { // onSearch(); data.reshing = true; document .querySelector('.musicList-container') ?.scroll(0, 0); handleGetList(); }} key={item.value} class={[styles.popSelect1]}> {selectChildObj(item.instruments).name || item.name} ) : ( { data.tagIndex = item.value || 0; data.reshing = true; document .querySelector('.musicList-container') ?.scroll(0, 0); handleGetList(); }}> {item.name} ) )}
*/}
{forms.audioPlayTypes !== 'SING' && ( { if (data.loading) return; data.musicalInstrumentId = val.childId; data.musicSubject = val.parentId; data.reshing = true; document .querySelector('.musicList-container') ?.scroll(0, 0); await handleGetList(); }} /> )} { if (data.loading) return; forms.name = val; data.reshing = true; document .querySelector('.musicList-container') ?.scroll(0, 0); handleGetList(); }} />
{data.list.map((item: IMusicItem, index) => { return (
{ handleChange(item); await analyzeXml(); // 是否显示总谱 const selectMusic = data.list[data.listActive]; // console.log(selectMusic, 'selected music'); if (selectMusic && selectMusic.isScoreRender) { data.musicInstrumentIndex = 999; } else { data.musicInstrumentIndex = 0; } musicIframeLoad(); }}>
{ (e.target as any).dataset.loaded = 'true'; }} />
{item.audioPlayTypeArray?.includes('SING') && ( 演唱 )} {item.audioPlayTypeArray?.includes('PLAY') && ( 演奏 )} {item.composer}
{/* {index == 0 ? ( { e.stopPropagation(); handlePlay(item); if ( data.listActive === index && data.playState === 'play' && isEnsemble.value ) { musicIframeLoad(); } }}> 试听 ) : ( { e.stopPropagation(); handlePlay(item); if ( data.listActive === index && data.playState === 'play' && isEnsemble.value ) { musicIframeLoad(); } }}> 试听 )} */}
); })}
{!data.loading && data.list.length === 0 && (
)}
{activeItem.value.musicSheetName}
{ handleChangeAudio('pause'); // const origin = /(localhost|192)/.test(location.host) // ? 'https://test.lexiaoya.cn' // : location.origin; // 默认进页面显示对应的曲谱 let lineType = 'staff'; if (data.showMusicImg === 'first') { lineType = 'firstTone'; } else if (data.showMusicImg === 'fixed') { lineType = 'fixedTone'; } else if (data.showMusicImg === 'staff') { lineType = 'staff'; } let src = `${vaildMusicScoreUrl()}/instrument?v=${+new Date()}&platform=pc&id=${ activeItem.value.id }&Authorization=${ user.getToken }&musicRenderType=${lineType}&showGuide=true&part-index=${ data.musicInstrumentIndex }`; if (data.musicalInstrumentId) { src += '&instrumentId=' + data.musicalInstrumentId; } if ( window.matchMedia('(display-mode: standalone)').matches ) { state.application = window.matchMedia( '(display-mode: standalone)' ).matches; data.previewModal = true; data.previewUrl = src; data.showPreivew = false; } else { window.open(src); } }} />
{isEnsemble.value && ( { await analyzeXml(); // data.trackName = data.trackList.find( (item: any) => item.value === data.musicInstrumentIndex )?.label || '切换声部'; musicIframeLoad(); }} // key={item.id} class={[styles.popSelect]}> {data.trackList.find( (item: any) => item.value === data.musicInstrumentIndex )?.label || '切换声部'} )} {/* 转谱按钮 */} {data.showTransBtn && ( { data.showMusicImg = val; // musicIframeLoad(); if (isEnsemble.value) { musicIframeLoad(); } }} // key={item.id} class={[styles.popTrans]}> {/* */} )}
handleFavitor()}> {activeItem.value.favitor ? ( ) : ( )}
{data.iframeSrc && (isEnsemble.value || musicImg.value.length === 0) ? ( ) : ( <> {/* */} {musicImg.value.length > 0 ? ( musicImg.value.map((item: string) => { return ; }) ) : ( )} {/* */} )}
{data.list.length !== 0 && ( handleChangeAudio(value)} /> )} {showGuide.value ? : null} { if (!val) { data.previewUrl = ''; } }} class={styles.previewWindow} showIcon={false} displayDirective="show"> { data.previewModal = false; data.previewUrl = ''; }} />
); } });