import { TransitionGroup, computed, defineComponent, nextTick, onMounted, reactive, ref, watch } from 'vue'; import styles from './index.module.less'; import MSearch from '@/components/m-search'; // import icon_play from '@/common/images/icon_play.svg'; import { Empty, Icon, List, Loading, NoticeBar, Popover, Popup, showLoadingToast, showToast } from 'vant'; import icon_back from './image/icon_back.svg'; import icon_down from '@/common/images/icon_down.svg'; // import icon_jianpu from '@/common/images/icon_jianpu.svg'; import icon_jianpuActive from '@/common/images/icon_jianpuActive.svg'; import iconFire from './image/icon_hot.png'; import icons from '@/common/images/index.json'; import { listenerMessage, postMessage, promisefiyPostMessage } from '@/helpers/native-message'; import html2canvas from 'html2canvas'; import { api_musicSheetCategoriesPage, api_musicSheetPage, api_subjectList } from './api'; import { state } from '@/state'; import MEmpty from '@/components/m-empty'; import Coaiguide from '@/custom-plugins/guide-page/coai-guide'; import TheVip from '@/components/the-vip'; import request from '@/helpers/request'; import { useRoute } from 'vue-router'; import { addWatermark, convasToImg, imgToCanvas } from './imageFunction'; import ChangeVoice from './change-voice'; import { storage } from '@/helpers/storage'; import { ACCESS_TOKEN } from '@/store/mutation-types'; import { sortMusical, getInstrumentName, vaildMusicScoreUrl, trackToCode } from '@/helpers/utils'; import { audioPlayType } from '@/helpers/constant'; export default defineComponent({ name: 'co-ai', setup() { const route = useRoute(); const categorForms = reactive({ page: 1, rows: 999, enable: true, // subjectId: state.user.data?.subjectId || '', musicTagIds: route.query.musicTagId ? [route.query.musicTagId] : [] }); const musicForms = reactive({ page: 1, rows: 20, status: 1, keyword: '', // 关键词 audioPlayTypes: [], musicSheetCategoriesId: route.query.id as any // musicalInstrumentId: '' }); const data = reactive({ musicSheetCategoriesName: route.query.name as any, audioPlayTypeItem: {} as any, /** 教材Index */ typeIndex: 0, /** 音乐Index */ musicIndex: 0, /** 显示哪种曲谱 */ showMusicImg: 'staff' as 'staff' | 'first' | 'fixed', popoverShow: false, popoverMusicShow: false, /** 教材列表 */ types: [] as any[], /** 音乐列表 */ musics: [] as any[], loading: true, finshed: false, showChangeVoice: false, selectMusicInstrumentIndex: 0, iframeSrc: '', searchNoticeShow: false, searchNotice: { left: '', top: '', width: '', height: '' }, showVip: false, vipMember: state.user.data?.vipMember, subjectStatus: false, audioPlayTypeList: [] as any, // 场景 subjectList: [], subjectItem: {} as any, // 当前乐器, trackList: [] as any, // 可筛选的分轨信息 showTransBtn: true // 是否显示转谱按钮 }); const downRef = ref(); const showGuide = ref(false); const _actions = computed(() => { const details = data.musics[data.musicIndex]; let { scoreType, isConvertibleScore } = details || {}; let action: any[] = [ { value: 'first', text: '首调' }, { value: 'fixed', text: '固定调' } ]; if ( !( ['JIAN', 'FIRST'].includes(scoreType) && isConvertibleScore === false ) && !(isConvertibleScore === undefined || isConvertibleScore === null) ) { action.unshift({ value: 'staff', text: '五线谱' }); } return action.map((item, index) => { return { ...item, color: data.showMusicImg === item.value ? 'var(--van-primary-color)' : '', className: data.showMusicImg === item.value ? 'fontBlod' : '' }; }); }); const _types = computed(() => { return data.types.map((item: any) => { return { ...item, color: musicForms.musicSheetCategoriesId == item.value ? 'var(--van-primary-color)' : '', className: musicForms.musicSheetCategoriesId == item.value ? 'fontBlod' : '' }; }); }); // 返回 const goback = () => { postMessage({ api: 'back' }); }; /** 去云练习 */ const handleGoto = () => { if ( !data.vipMember && data.musics[data.musicIndex]?.paymentType === 'VIP' ) { data.showVip = true; return; } // 默认进页面显示对应的曲谱 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/?id=${ data.musics[data.musicIndex]?.id }&musicRenderType=${lineType}&showGuide=true&part-index=${ data.selectMusicInstrumentIndex }`; // if (data.musics[data.musicIndex]?.paymentType === 'FREE') { // src += `showCourseMember=true`; // } postMessage({ api: 'openAccompanyWebView', content: { url: src, orientation: 0, isHideTitle: true, statusBarTextColor: false, isOpenLight: true, c_orientation: 0 // 0 横屏 1 竖屏 } }); }; /** 保存图片 */ const handleSave = async () => { 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); } }; /** 获取音乐教材列表 */ const getMusicSheetCategories = async () => { try { const res = await api_musicSheetCategoriesPage({ ...categorForms }); if (res.code === 200 && Array.isArray(res?.data?.rows)) { const temp: any = []; res.data.rows.forEach((item: any) => { temp.push({ value: item.id, text: item.name }); }); data.types = temp; } } catch (error) { console.log('🚀 ~ error:', error); } }; /** 获取曲谱列表 */ const getMusicList = async () => { data.loading = true; try { const res = await api_musicSheetPage({ ...musicForms, audioPlayTypes: data.audioPlayTypeItem.value ? data.audioPlayTypeItem.value === 'PLAY_SING' ? ['PLAY', 'SING'] : [data.audioPlayTypeItem.value] : [] // musicalInstrumentId: data.subjectItem.value || null }); if (res.code === 200) { if (Array.isArray(res?.data?.rows)) { data.musics = [...data.musics, ...res.data.rows]; data.finshed = !res.data.next; // 是否显示总谱 const selectMusic = data.musics[data.musicIndex]; if ( selectMusic && selectMusic.isScoreRender && data.musicIndex === 0 ) { data.selectMusicInstrumentIndex = 999; } } else { data.finshed = true; } } else showGuide.value = true; } catch (error) { console.log('🚀 ~ error:', error); } data.loading = false; }; const handleReset = async () => { musicForms.page = 1; data.musics = []; await getMusicList(); initLoadingObv(); }; const spinRef = ref(); const handleResh = () => { if (data.loading || data.finshed) return; musicForms.page = musicForms.page + 1; getMusicList(); }; const musicIframeLoad = () => { const token = storage.get(ACCESS_TOKEN); const details = data.musics[data.musicIndex]; if(!details?.id){ data.iframeSrc = "" return } // 如果在配置里面匹配不到,则默认显示五线谱 const musicRenderType = data.showMusicImg === 'first' ? 'firstTone' : data.showMusicImg === 'fixed' ? 'fixedTone' : data.showMusicImg === 'staff' ? 'staff' : 'staff'; 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 setSearchBox = () => { const el = document.querySelector('.searchNotice .van-field__control'); if (el) { const rect = el.getBoundingClientRect(); data.searchNotice.left = rect.x + 'px'; data.searchNotice.top = rect.y + 'px'; data.searchNotice.width = rect.width + 'px'; data.searchNotice.height = rect.height + 'px'; } }; // 根据musicSheetType返回的值,判断是否显示切换声轨按钮 const isEnsemble = computed(() => { if (data.musics.length) { const musicSheetType = data.musics[data.musicIndex]?.musicSheetType; if (musicSheetType === 'SINGLE') { return false; } else { return true; } } else { return false; } }); // 判断 值当前有没有图片 const isMusicImg = computed(() => { const musicsData = data.musics[data.musicIndex] 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; } }; const getSubjecList = async () => { try { let subjectIds = state.user.data?.subjectId || ''; subjectIds = subjectIds.split(','); const subjectId = subjectIds[0] || ''; const res = await api_subjectList({ enableFlag: true, delFlag: 0, page: 1, subjectId: subjectId || '', rows: 999 }); if (subjectId) { const result = res.data || []; let tempSubjects: any = []; result.forEach((item: any) => { const instruments = item.instruments || []; if (Number(subjectId) === item.id && instruments.length > 0) { instruments.forEach((child: any, index: number) => { tempSubjects.push({ text: child.name, value: child.id, className: index === 0 ? 'selected' : '' }); }); } }); data.subjectList = tempSubjects; if (tempSubjects.length > 0) { data.subjectItem = tempSubjects[0]; } } } catch { // } }; // 解析xml,获取分轨信息 const analyzeXml = async () => { const details = data.musics[data.musicIndex]; 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 = data.musics[data.musicIndex]?.multiTracksSelection; const canSelectTracks = multiTracksSelection ? multiTracksSelection?.split(',') : []; const musicalInstruments = data.musics[data.musicIndex]?.musicalInstruments || []; // console.log(canSelectTracks, partListNames); 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 = data.musics[data.musicIndex]; 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(); } } // let track = arr.find( // (item: any) => item.value === data.selectMusicInstrumentIndex // )?.track; // track = trackToCode(track); // let musicRenderType: 'staff' | 'first' | 'fixed' = 'staff'; // let canTrans = true; // data.musics[data.musicIndex]?.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.musics[data.musicIndex]; 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.musicIndex, async () => { data.selectMusicInstrumentIndex = 0; analyzeXml(); } ); const formatUsedNum = (num: number) => { if (num < 10000) { return num; } else { const n = num / 10000; return Number(n.toFixed(1)) + '万'; } }; const initLoadingObv = () => { const obv = new IntersectionObserver(entries => { if (entries[0].intersectionRatio > 0) { handleResh(); } }); nextTick(() => { spinRef.value && obv.observe(spinRef.value); }); }; onMounted(async () => { // 场景 const tempAudio = Object.keys(audioPlayType).map(key => { return { value: key, text: audioPlayType[key] }; }); data.audioPlayTypeList = [ { text: '全部场景', value: '', className: 'selected' }, ...tempAudio ]; data.audioPlayTypeItem = data.audioPlayTypeList[0]; // 安卓的状态栏 postMessage({ api: 'setStatusBarVisibility', content: { isVisibility: 0 } }); await getSubjecList(); await getMusicSheetCategories(); await getMusicList(); initLoadingObv(); console.log(state.user.data); const getUserInfo = async () => { const res = await request.get('/edu-app/user/getUserInfo', { initRequest: true, // 初始化接口 requestType: 'form', hideLoading: true }); if (res?.code === 200) { data.vipMember = res.data.vipMember; } }; await analyzeXml(); musicIframeLoad(); listenerMessage('webViewOnResume', () => { console.log('页面显示', data.iframeSrc); getUserInfo(); // 为了处理返回显示刷新的问题 // data.typeIndex = 0; // data.musicIndex = 0; // handleReset(); }); setSearchBox(); }); return () => (
{ // data.showMusicImg = item.value; if (item.value == musicForms.musicSheetCategoriesId) { return; } data.musics = []; musicForms.musicSheetCategoriesId = item.value; data.musicSheetCategoriesName = item.text; data.popoverMusicShow = false; // getMusicList(); handleReset(); }}> {{ reference: () => ( {data.musicSheetCategoriesName} ) }}
(data.searchNoticeShow = false)} onBlur={val => { musicForms.keyword = val?.trim() || ''; }} onSearch={async val => { if (!data.loading) { musicForms.keyword = val; data.musicIndex = 0 await handleReset(); await analyzeXml(); musicIframeLoad(); } }}> {{ left: () => (
{ data.audioPlayTypeList.forEach((c: any) => { c.className = ''; if (c.value === item.value) { c.className = 'selected'; } }); data.audioPlayTypeItem = { ...item, className: 'selected' }; handleReset(); }}> {{ reference: () => (
{data.audioPlayTypeItem.text}
) }}
) }}
{data.musics.map((item: any, index: number) => { return (
{ data.musicIndex = index; await analyzeXml(); // 是否显示总谱 const selectMusic = data.musics[data.musicIndex]; if (selectMusic && selectMusic.isScoreRender) { if (selectMusic.defaultScoreRender) { data.selectMusicInstrumentIndex = 999; } else { initUserDefaultInstrument(); } } else { initUserDefaultInstrument(); } musicIframeLoad(); }}>
{ const el = e.target as HTMLImageElement; el.setAttribute('loaded', 'true'); }} />
{/*
{item.usedNum}
*/} {formatUsedNum(item.usedNum)} {item.audioPlayTypes?.includes('SING') && ( 演唱 )} {item.audioPlayTypes?.includes('PLAY') && ( 演奏 )}
{item.composer || '佚名'}
{/* */}
); })} {!data.finshed && (
)} {!data.loading && data.musics.length === 0 && (
)}
{isEnsemble.value && (
(data.showChangeVoice = true)}> 切换声部
)}
{data.musics[data.musicIndex]?.musicSheetName}
{/* ensembleDetail */} {data.iframeSrc && (isEnsemble.value || !isMusicImg.value) ? (
<> {/* {loading.value && (

加载中...

)} */} {data.musics[data.musicIndex]?.id && ( )} {/* */}
) : (
{data.showMusicImg === 'first' ? ( <> {data.musics[data.musicIndex]?.musicFirstImg ?.split(',') .map((item: any, index: number) => { return ( {data.musics[data.musicIndex]?.musicJianImg ?.split(',') .map((item: any, index: number) => { return ( { return ( {{ reference: () => }} )} {(!isEnsemble.value && isMusicImg.value) && ( )} {data.musics[data.musicIndex]?.id && (
handleGoto()} />
)}
{data.searchNotice.width && data.searchNoticeShow && (
)} {showGuide.value && } { if (val) { postMessage({ api: 'openWebView', content: { url: `${location.origin}${location.pathname}#/member-center`, orientation: 1 } }); } data.showVip = false; }} /> { if (val) { postMessage({ api: 'openWebView', content: { url: `${location.origin}${location.pathname}#/member-center`, orientation: 1 } }); } data.showVip = false; }} /> {data.showChangeVoice && ( (data.showChangeVoice = false)} onConfirm={async (index: number) => { data.selectMusicInstrumentIndex = index; console.log(index, 'index-------------------') // await analyzeXml(); // data.iframeSrc = ''; musicIframeLoad(); data.showChangeVoice = false; }} /> )}
); } });