|
@@ -1,938 +1,938 @@
|
|
|
-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 '/src/common/images/icon-collect-default.png';
|
|
|
-import icon_favitorActive from '/src/common/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 { 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 { state } from '/src/state';
|
|
|
-import { useResizeObserver } from '@vueuse/core';
|
|
|
-import { vaildMusicScoreUrl } from '/src/utils/urlUtils';
|
|
|
-import { getInstrumentName, sortMusical, trackToCode } from '/src/utils';
|
|
|
-
|
|
|
-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: '', // 关键词
|
|
|
- musicSheetCategoriesId: route.query.id || ''
|
|
|
- });
|
|
|
- const data = reactive({
|
|
|
- loading: false,
|
|
|
- finshed: false,
|
|
|
- reshing: false,
|
|
|
- tags: [] as any[],
|
|
|
- tagIndex: 0,
|
|
|
- list: [] as unknown as IMusicItem[],
|
|
|
- listActive: 0,
|
|
|
- musicInstrumentIndex: 0,
|
|
|
- playState: 'pause' as 'play' | 'pause',
|
|
|
- showPlayer: false,
|
|
|
- previewModal: false,
|
|
|
- showPreivew: false,
|
|
|
- previewUrl: '',
|
|
|
- showCloseBtn: true,
|
|
|
- iframeSrc: '',
|
|
|
- showMusicImg: 'staff' as 'staff' | 'first' | 'fixed', // 显示哪种曲谱
|
|
|
- trackList: [] as any, // 可筛选的分轨信息
|
|
|
- showTransBtn: true, // 是否显示转谱按钮
|
|
|
- trackName: '切换声轨' as any // 分轨名字
|
|
|
- });
|
|
|
- const showGuide = ref(false);
|
|
|
- const userStore = useUserStore();
|
|
|
- let musicsrc = '';
|
|
|
- const getSubjects = async () => {
|
|
|
- // const res = await api_subjectList();
|
|
|
- // if (Array.isArray(res?.data)) {
|
|
|
- const tempSubjectList = catchStore.getSubjectInstruments;
|
|
|
- const subjectList = sessionStorage.getItem('musicSubjectList')
|
|
|
- ? JSON.parse(sessionStorage.getItem('musicSubjectList') as any)
|
|
|
- : [];
|
|
|
- const resultList: any[] = [];
|
|
|
- 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
|
|
|
- ];
|
|
|
- // }
|
|
|
- };
|
|
|
- const getList = async () => {
|
|
|
- data.loading = true;
|
|
|
- let res = {} as any;
|
|
|
- try {
|
|
|
- res = await api_musicSheetPage({
|
|
|
- ...forms,
|
|
|
- // musicSubject: data.tagIndex ? data.tagIndex : ''
|
|
|
- musicalInstrumentId: data.tagIndex ? data.tagIndex : ''
|
|
|
- });
|
|
|
- } 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)) {
|
|
|
- data.list = [...data.list, ...res.data.rows];
|
|
|
- data.finshed = res.data.rows.length < forms.rows;
|
|
|
- } else {
|
|
|
- data.finshed = true;
|
|
|
- }
|
|
|
- if (data.list[data.listActive]) {
|
|
|
- getFavitor(data.list[data.listActive]);
|
|
|
- }
|
|
|
- data.loading = false;
|
|
|
- setTimeout(() => {
|
|
|
- showGuide.value = true;
|
|
|
- }, 500);
|
|
|
- };
|
|
|
-
|
|
|
- const handleGetList = () => {
|
|
|
- data.listActive = 0;
|
|
|
- data.showPlayer = false;
|
|
|
- data.playState = 'pause';
|
|
|
- forms.page = 1;
|
|
|
- data.finshed = false;
|
|
|
- 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 () => {
|
|
|
- // 获取声部列表
|
|
|
- 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();
|
|
|
- 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 musicIframeLoad = () => {
|
|
|
- const token = userStore.getToken;
|
|
|
- const details = data.list[data.listActive];
|
|
|
- // 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}`;
|
|
|
- };
|
|
|
-
|
|
|
- /** 音频控制 */
|
|
|
- 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 = [
|
|
|
- {
|
|
|
- value: 'staff',
|
|
|
- label: '五线谱'
|
|
|
- },
|
|
|
- {
|
|
|
- value: 'first',
|
|
|
- label: '首调'
|
|
|
- },
|
|
|
- {
|
|
|
- value: 'fixed',
|
|
|
- label: '固定调'
|
|
|
- }
|
|
|
- ];
|
|
|
-
|
|
|
- // 解析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] || {};
|
|
|
- // console.log(
|
|
|
- // details.musicalInstruments[0],
|
|
|
- // '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 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() || ''
|
|
|
- );
|
|
|
- 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;
|
|
|
- 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;
|
|
|
- };
|
|
|
- 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 () => (
|
|
|
- <div class={styles.container}>
|
|
|
- <NSpace align="center" wrapItem={false} size={16}>
|
|
|
- <img
|
|
|
- style={{ cursor: 'pointer' }}
|
|
|
- src={icon_back}
|
|
|
- class={styles.iconBack}
|
|
|
- onClick={() => router.push({ path: '/xiaoku-ai' })}
|
|
|
- />
|
|
|
- <NBreadcrumb separator="">
|
|
|
- <NBreadcrumbItem
|
|
|
- onClick={() => router.push({ path: '/xiaoku-ai' })}>
|
|
|
- 全部列表
|
|
|
- </NBreadcrumbItem>
|
|
|
- <img class={styles.separator} src={icon_separator} />
|
|
|
- <NBreadcrumbItem>{route.query.name}</NBreadcrumbItem>
|
|
|
- </NBreadcrumb>
|
|
|
- </NSpace>
|
|
|
- <div class={[styles.wrap, data.showPlayer ? styles.wrapBottom : '']}>
|
|
|
- <div class={styles.content}>
|
|
|
- <div class={styles.tools}>
|
|
|
- <NSpace
|
|
|
- style={{ width: '100%' }}
|
|
|
- size={[24, 12]}
|
|
|
- wrapItem={false}>
|
|
|
- <div
|
|
|
- {...{
|
|
|
- id: 'music-0'
|
|
|
- }}>
|
|
|
- <NSpace
|
|
|
- style={{ width: '100%' }}
|
|
|
- size={[24, 12]}
|
|
|
- wrapItem={false}>
|
|
|
- {data.tags.map(item =>
|
|
|
- item.instruments && item.instruments.length > 1 ? (
|
|
|
- <NPopselect
|
|
|
- options={item.instruments}
|
|
|
- trigger="hover"
|
|
|
- v-model:value={data.tagIndex}
|
|
|
- scrollable
|
|
|
- onUpdate:value={() => {
|
|
|
- // onSearch();
|
|
|
- data.reshing = true;
|
|
|
- document
|
|
|
- .querySelector('.musicList-container')
|
|
|
- .scroll(0, 0);
|
|
|
- handleGetList();
|
|
|
- }}
|
|
|
- key={item.value}
|
|
|
- class={[styles.popSelect1]}>
|
|
|
- <NButton
|
|
|
- round
|
|
|
- textColor={
|
|
|
- selectChildObj(item.instruments).selected
|
|
|
- ? '#fff'
|
|
|
- : '#000'
|
|
|
- }
|
|
|
- color={
|
|
|
- selectChildObj(item.instruments).selected
|
|
|
- ? '#198CFE'
|
|
|
- : '#fff'
|
|
|
- }
|
|
|
- type={
|
|
|
- selectChildObj(item.instruments).selected
|
|
|
- ? 'primary'
|
|
|
- : 'default'
|
|
|
- }
|
|
|
- class={[
|
|
|
- styles.textBtn,
|
|
|
- selectChildObj(item.instruments).selected &&
|
|
|
- styles.textBtnActive
|
|
|
- ]}>
|
|
|
- {selectChildObj(item.instruments).name || item.name}
|
|
|
- <i class={styles.iconArrow}></i>
|
|
|
- </NButton>
|
|
|
- </NPopselect>
|
|
|
- ) : (
|
|
|
- <NButton
|
|
|
- round
|
|
|
- textColor={
|
|
|
- data.tagIndex === item.value ? '#fff' : '#000'
|
|
|
- }
|
|
|
- color={
|
|
|
- data.tagIndex === item.value ? '#198CFE' : '#fff'
|
|
|
- }
|
|
|
- type={
|
|
|
- data.tagIndex === item.value ? 'primary' : 'default'
|
|
|
- }
|
|
|
- onClick={() => {
|
|
|
- data.tagIndex = item.value || 0;
|
|
|
- data.reshing = true;
|
|
|
- document
|
|
|
- .querySelector('.musicList-container')
|
|
|
- .scroll(0, 0);
|
|
|
- handleGetList();
|
|
|
- }}>
|
|
|
- {item.name}
|
|
|
- </NButton>
|
|
|
- )
|
|
|
- )}
|
|
|
- </NSpace>
|
|
|
- </div>
|
|
|
- </NSpace>
|
|
|
- <TheSearch
|
|
|
- style={{ marginLeft: 'auto' }}
|
|
|
- round
|
|
|
- border={false}
|
|
|
- onSearch={val => {
|
|
|
- forms.name = val;
|
|
|
- data.reshing = true;
|
|
|
- handleGetList();
|
|
|
- }}
|
|
|
- />
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class={styles.contentWrap}>
|
|
|
- <div class={[styles.musicList, 'musicList-container']}>
|
|
|
- <div class={[styles.wrapList, 'music-wrap-list']}>
|
|
|
- {data.list.map((item: IMusicItem, index) => {
|
|
|
- return (
|
|
|
- <div class={styles.itemContainer}>
|
|
|
- <div
|
|
|
- class={[
|
|
|
- styles.item,
|
|
|
- data.listActive === index && styles.active
|
|
|
- ]}
|
|
|
- onClick={() => {
|
|
|
- handleChange(item);
|
|
|
- musicIframeLoad();
|
|
|
- }}>
|
|
|
- <div class={styles.img}>
|
|
|
- <NImage
|
|
|
- lazy
|
|
|
- objectFit="cover"
|
|
|
- previewDisabled={true}
|
|
|
- src={item.titleImg || icon_default}
|
|
|
- onLoad={e => {
|
|
|
- (e.target as any).dataset.loaded = 'true';
|
|
|
- }}
|
|
|
- />
|
|
|
- <PlayLoading
|
|
|
- class={[
|
|
|
- data.listActive === index &&
|
|
|
- data.playState === 'play'
|
|
|
- ? ''
|
|
|
- : styles.showPlayLoading
|
|
|
- ]}
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class={styles.title}>
|
|
|
- <div class={styles.titleName}>
|
|
|
- <TheNoticeBar text={item.musicSheetName} />
|
|
|
- </div>
|
|
|
- <div class={styles.titleDes}>{item.composer}</div>
|
|
|
- </div>
|
|
|
- {index == 0 ? (
|
|
|
- <NButton
|
|
|
- color="#259CFE"
|
|
|
- textColor="#fff"
|
|
|
- {...{ id: 'music-1' }}
|
|
|
- round
|
|
|
- class={styles.btn}
|
|
|
- type="primary"
|
|
|
- onClick={(e: Event) => {
|
|
|
- e.stopPropagation();
|
|
|
- handlePlay(item);
|
|
|
- if (
|
|
|
- data.listActive === index &&
|
|
|
- data.playState === 'play' &&
|
|
|
- isEnsemble.value
|
|
|
- ) {
|
|
|
- musicIframeLoad();
|
|
|
- }
|
|
|
- }}>
|
|
|
- 试听
|
|
|
- <img
|
|
|
- src={
|
|
|
- data.listActive === index &&
|
|
|
- data.playState === 'play'
|
|
|
- ? icon_pause
|
|
|
- : icon_play
|
|
|
- }
|
|
|
- />
|
|
|
- </NButton>
|
|
|
- ) : (
|
|
|
- <NButton
|
|
|
- color="#259CFE"
|
|
|
- textColor="#fff"
|
|
|
- round
|
|
|
- class={styles.btn}
|
|
|
- type="primary"
|
|
|
- onClick={(e: Event) => {
|
|
|
- e.stopPropagation();
|
|
|
- handlePlay(item);
|
|
|
- if (
|
|
|
- data.listActive === index &&
|
|
|
- data.playState === 'play' &&
|
|
|
- isEnsemble.value
|
|
|
- ) {
|
|
|
- musicIframeLoad();
|
|
|
- }
|
|
|
- }}>
|
|
|
- 试听
|
|
|
- <img
|
|
|
- src={
|
|
|
- data.listActive === index &&
|
|
|
- data.playState === 'play'
|
|
|
- ? icon_pause
|
|
|
- : icon_play
|
|
|
- }
|
|
|
- />
|
|
|
- </NButton>
|
|
|
- )}
|
|
|
-
|
|
|
- <img class={styles.arrow} src={icon_arrow} />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- );
|
|
|
- })}
|
|
|
-
|
|
|
- <div
|
|
|
- ref={spinRef}
|
|
|
- class={[
|
|
|
- styles.loadingWrap,
|
|
|
- data.finshed && styles.showLoading
|
|
|
- ]}>
|
|
|
- <NSpin show={true}></NSpin>
|
|
|
- </div>
|
|
|
-
|
|
|
- {!data.loading && data.list.length === 0 && (
|
|
|
- <div class={styles.empty}>
|
|
|
- <TheEmpty></TheEmpty>
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class={styles.musicStaff}>
|
|
|
- <div class={styles.musicName}>
|
|
|
- {activeItem.value.musicSheetName}
|
|
|
- </div>
|
|
|
-
|
|
|
- <img
|
|
|
- id="music-2"
|
|
|
- style={{
|
|
|
- display: activeItem.value.id ? '' : 'none'
|
|
|
- }}
|
|
|
- class={[styles.goBtn]}
|
|
|
- src={icon_goXiaoku}
|
|
|
- onClick={() => {
|
|
|
- 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';
|
|
|
- }
|
|
|
- const src = `${vaildMusicScoreUrl()}/instrument?v=${+new Date()}&platform=pc&showGuide=true&id=${
|
|
|
- activeItem.value.id
|
|
|
- }&Authorization=${
|
|
|
- user.getToken
|
|
|
- }&musicRenderType=${lineType}&showGuide=true&part-index=${
|
|
|
- data.musicInstrumentIndex
|
|
|
- }`;
|
|
|
- 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);
|
|
|
- }
|
|
|
- }}
|
|
|
- />
|
|
|
- <div
|
|
|
- class={styles.rightBtns}
|
|
|
- style={{ display: activeItem.value.id ? '' : 'none' }}>
|
|
|
- {isEnsemble.value && (
|
|
|
- <NPopselect
|
|
|
- options={data.trackList}
|
|
|
- trigger="hover"
|
|
|
- v-model:value={data.musicInstrumentIndex}
|
|
|
- onUpdate:value={async (val: any) => {
|
|
|
- await analyzeXml();
|
|
|
- //
|
|
|
- }}
|
|
|
- // key={item.id}
|
|
|
- class={[styles.popSelect]}>
|
|
|
- <NButton round class={[styles.textBtn]}>
|
|
|
- {data.trackName}
|
|
|
- <i class={styles.iconArrow}></i>
|
|
|
- </NButton>
|
|
|
- </NPopselect>
|
|
|
- )}
|
|
|
- {/* 转谱按钮 */}
|
|
|
- {data.showTransBtn && (
|
|
|
- <NPopselect
|
|
|
- options={_actions}
|
|
|
- trigger="hover"
|
|
|
- v-model:value={data.showMusicImg}
|
|
|
- onUpdate:value={async (val: any) => {
|
|
|
- data.showMusicImg = val;
|
|
|
- // musicIframeLoad();
|
|
|
- }}
|
|
|
- // key={item.id}
|
|
|
- class={[styles.popTrans]}>
|
|
|
- <img class={[styles.transBtn]} src={icon_trans} />
|
|
|
- </NPopselect>
|
|
|
- )}
|
|
|
- <div class={styles.favitor} onClick={() => handleFavitor()}>
|
|
|
- <Transition name="favitor" mode="out-in">
|
|
|
- {activeItem.value.favitor ? (
|
|
|
- <img src={icon_favitorActive} key="1" />
|
|
|
- ) : (
|
|
|
- <img src={icon_favitor} key="2" />
|
|
|
- )}
|
|
|
- </Transition>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class={styles.staffImgs}>
|
|
|
- {isEnsemble.value ? (
|
|
|
- <iframe
|
|
|
- id="staffIframeRef"
|
|
|
- style={{
|
|
|
- width: '100%',
|
|
|
- height: '100%',
|
|
|
- paddingTop: '20px'
|
|
|
- // opacity: loading.value ? 0 : 1
|
|
|
- }}
|
|
|
- src={data.iframeSrc}
|
|
|
- onLoad={musicIframeLoad}></iframe>
|
|
|
- ) : (
|
|
|
- <>
|
|
|
- {/* <TransitionGroup name="van-fade"> */}
|
|
|
- {musicImg.value.length > 0 ? (
|
|
|
- musicImg.value.map((item: string) => {
|
|
|
- return <img src={item} key={item} />;
|
|
|
- })
|
|
|
- ) : (
|
|
|
- <TheEmpty></TheEmpty>
|
|
|
- )}
|
|
|
- {/* </TransitionGroup> */}
|
|
|
- </>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- {data.list.length !== 0 && (
|
|
|
- <PlayItem
|
|
|
- show={data.showPlayer}
|
|
|
- playState={data.playState}
|
|
|
- item={activeItem.value}
|
|
|
- onChange={value => handleChangeAudio(value)}
|
|
|
- />
|
|
|
- )}
|
|
|
- {showGuide.value ? <Musicguide></Musicguide> : null}
|
|
|
-
|
|
|
- <NModal
|
|
|
- v-model:show={data.previewModal}
|
|
|
- onUpdate:show={(val: any) => {
|
|
|
- if (!val) {
|
|
|
- data.previewUrl = '';
|
|
|
- }
|
|
|
- }}
|
|
|
- class={styles.previewWindow}
|
|
|
- showIcon={false}
|
|
|
- displayDirective="show">
|
|
|
- <NSpin show={data.showPreivew} style="--n-opacity-spinning: 1;">
|
|
|
- <img
|
|
|
- style={{ display: data.showCloseBtn ? '' : 'none' }}
|
|
|
- src={icon_close}
|
|
|
- class={styles.previewClose}
|
|
|
- onClick={() => {
|
|
|
- data.previewModal = false;
|
|
|
- data.previewUrl = '';
|
|
|
- }}
|
|
|
- />
|
|
|
-
|
|
|
- <iframe
|
|
|
- class={styles.previewIframe}
|
|
|
- onLoad={() => {
|
|
|
- data.showPreivew = false;
|
|
|
- }}
|
|
|
- frameborder="0"
|
|
|
- src={data.previewUrl}></iframe>
|
|
|
- </NSpin>
|
|
|
- </NModal>
|
|
|
- </div>
|
|
|
- );
|
|
|
- }
|
|
|
-});
|
|
|
+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 '/src/common/images/icon-collect-default.png';
|
|
|
+import icon_favitorActive from '/src/common/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 { 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 { state } from '/src/state';
|
|
|
+import { useResizeObserver } from '@vueuse/core';
|
|
|
+import { vaildMusicScoreUrl } from '/src/utils/urlUtils';
|
|
|
+import { getInstrumentName, sortMusical, trackToCode } from '/src/utils';
|
|
|
+
|
|
|
+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: '', // 关键词
|
|
|
+ musicSheetCategoriesId: route.query.id || ''
|
|
|
+ });
|
|
|
+ const data = reactive({
|
|
|
+ loading: false,
|
|
|
+ finshed: false,
|
|
|
+ reshing: false,
|
|
|
+ tags: [] as any[],
|
|
|
+ tagIndex: 0,
|
|
|
+ list: [] as unknown as IMusicItem[],
|
|
|
+ listActive: 0,
|
|
|
+ musicInstrumentIndex: 0,
|
|
|
+ playState: 'pause' as 'play' | 'pause',
|
|
|
+ showPlayer: false,
|
|
|
+ previewModal: false,
|
|
|
+ showPreivew: false,
|
|
|
+ previewUrl: '',
|
|
|
+ showCloseBtn: true,
|
|
|
+ iframeSrc: '',
|
|
|
+ showMusicImg: 'staff' as 'staff' | 'first' | 'fixed', // 显示哪种曲谱
|
|
|
+ trackList: [] as any, // 可筛选的分轨信息
|
|
|
+ showTransBtn: true, // 是否显示转谱按钮
|
|
|
+ trackName: '切换声轨' as any // 分轨名字
|
|
|
+ });
|
|
|
+ const showGuide = ref(false);
|
|
|
+ const userStore = useUserStore();
|
|
|
+ let musicsrc = '';
|
|
|
+ const getSubjects = async () => {
|
|
|
+ // const res = await api_subjectList();
|
|
|
+ // if (Array.isArray(res?.data)) {
|
|
|
+ const tempSubjectList = catchStore.getSubjectInstruments;
|
|
|
+ const subjectList = sessionStorage.getItem('musicSubjectList')
|
|
|
+ ? JSON.parse(sessionStorage.getItem('musicSubjectList') as any)
|
|
|
+ : [];
|
|
|
+ const resultList: any[] = [];
|
|
|
+ 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
|
|
|
+ ];
|
|
|
+ // }
|
|
|
+ };
|
|
|
+ const getList = async () => {
|
|
|
+ data.loading = true;
|
|
|
+ let res = {} as any;
|
|
|
+ try {
|
|
|
+ res = await api_musicSheetPage({
|
|
|
+ ...forms,
|
|
|
+ // musicSubject: data.tagIndex ? data.tagIndex : ''
|
|
|
+ musicalInstrumentId: data.tagIndex ? data.tagIndex : ''
|
|
|
+ });
|
|
|
+ } 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)) {
|
|
|
+ data.list = [...data.list, ...res.data.rows];
|
|
|
+ data.finshed = res.data.rows.length < forms.rows;
|
|
|
+ } else {
|
|
|
+ data.finshed = true;
|
|
|
+ }
|
|
|
+ if (data.list[data.listActive]) {
|
|
|
+ getFavitor(data.list[data.listActive]);
|
|
|
+ }
|
|
|
+ data.loading = false;
|
|
|
+ setTimeout(() => {
|
|
|
+ showGuide.value = true;
|
|
|
+ }, 500);
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleGetList = () => {
|
|
|
+ data.listActive = 0;
|
|
|
+ data.showPlayer = false;
|
|
|
+ data.playState = 'pause';
|
|
|
+ forms.page = 1;
|
|
|
+ data.finshed = false;
|
|
|
+ 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 () => {
|
|
|
+ // 获取声部列表
|
|
|
+ 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();
|
|
|
+ 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 musicIframeLoad = () => {
|
|
|
+ const token = userStore.getToken;
|
|
|
+ const details = data.list[data.listActive];
|
|
|
+ // 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}`;
|
|
|
+ };
|
|
|
+
|
|
|
+ /** 音频控制 */
|
|
|
+ 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 = [
|
|
|
+ {
|
|
|
+ value: 'staff',
|
|
|
+ label: '五线谱'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 'first',
|
|
|
+ label: '首调'
|
|
|
+ },
|
|
|
+ {
|
|
|
+ value: 'fixed',
|
|
|
+ label: '固定调'
|
|
|
+ }
|
|
|
+ ];
|
|
|
+
|
|
|
+ // 解析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] || {};
|
|
|
+ // console.log(
|
|
|
+ // details.musicalInstruments[0],
|
|
|
+ // '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 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() || ''
|
|
|
+ );
|
|
|
+ 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;
|
|
|
+ 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;
|
|
|
+ };
|
|
|
+ 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 () => (
|
|
|
+ <div class={styles.container}>
|
|
|
+ <NSpace align="center" wrapItem={false} size={16}>
|
|
|
+ <img
|
|
|
+ style={{ cursor: 'pointer' }}
|
|
|
+ src={icon_back}
|
|
|
+ class={styles.iconBack}
|
|
|
+ onClick={() => router.push({ path: '/xiaoku-ai' })}
|
|
|
+ />
|
|
|
+ <NBreadcrumb separator="">
|
|
|
+ <NBreadcrumbItem
|
|
|
+ onClick={() => router.push({ path: '/xiaoku-ai' })}>
|
|
|
+ 全部列表
|
|
|
+ </NBreadcrumbItem>
|
|
|
+ <img class={styles.separator} src={icon_separator} />
|
|
|
+ <NBreadcrumbItem>{route.query.name}</NBreadcrumbItem>
|
|
|
+ </NBreadcrumb>
|
|
|
+ </NSpace>
|
|
|
+ <div class={[styles.wrap, data.showPlayer ? styles.wrapBottom : '']}>
|
|
|
+ <div class={styles.content}>
|
|
|
+ <div class={styles.tools}>
|
|
|
+ <NSpace
|
|
|
+ style={{ width: '100%' }}
|
|
|
+ size={[24, 12]}
|
|
|
+ wrapItem={false}>
|
|
|
+ <div
|
|
|
+ {...{
|
|
|
+ id: 'music-0'
|
|
|
+ }}>
|
|
|
+ <NSpace
|
|
|
+ style={{ width: '100%' }}
|
|
|
+ size={[24, 12]}
|
|
|
+ wrapItem={false}>
|
|
|
+ {data.tags.map(item =>
|
|
|
+ item.instruments && item.instruments.length > 1 ? (
|
|
|
+ <NPopselect
|
|
|
+ options={item.instruments}
|
|
|
+ trigger="hover"
|
|
|
+ v-model:value={data.tagIndex}
|
|
|
+ scrollable
|
|
|
+ onUpdate:value={() => {
|
|
|
+ // onSearch();
|
|
|
+ data.reshing = true;
|
|
|
+ document
|
|
|
+ .querySelector('.musicList-container')
|
|
|
+ .scroll(0, 0);
|
|
|
+ handleGetList();
|
|
|
+ }}
|
|
|
+ key={item.value}
|
|
|
+ class={[styles.popSelect1]}>
|
|
|
+ <NButton
|
|
|
+ round
|
|
|
+ textColor={
|
|
|
+ selectChildObj(item.instruments).selected
|
|
|
+ ? '#fff'
|
|
|
+ : '#000'
|
|
|
+ }
|
|
|
+ color={
|
|
|
+ selectChildObj(item.instruments).selected
|
|
|
+ ? '#198CFE'
|
|
|
+ : '#fff'
|
|
|
+ }
|
|
|
+ type={
|
|
|
+ selectChildObj(item.instruments).selected
|
|
|
+ ? 'primary'
|
|
|
+ : 'default'
|
|
|
+ }
|
|
|
+ class={[
|
|
|
+ styles.textBtn,
|
|
|
+ selectChildObj(item.instruments).selected &&
|
|
|
+ styles.textBtnActive
|
|
|
+ ]}>
|
|
|
+ {selectChildObj(item.instruments).name || item.name}
|
|
|
+ <i class={styles.iconArrow}></i>
|
|
|
+ </NButton>
|
|
|
+ </NPopselect>
|
|
|
+ ) : (
|
|
|
+ <NButton
|
|
|
+ round
|
|
|
+ textColor={
|
|
|
+ data.tagIndex === item.value ? '#fff' : '#000'
|
|
|
+ }
|
|
|
+ color={
|
|
|
+ data.tagIndex === item.value ? '#198CFE' : '#fff'
|
|
|
+ }
|
|
|
+ type={
|
|
|
+ data.tagIndex === item.value ? 'primary' : 'default'
|
|
|
+ }
|
|
|
+ onClick={() => {
|
|
|
+ data.tagIndex = item.value || 0;
|
|
|
+ data.reshing = true;
|
|
|
+ document
|
|
|
+ .querySelector('.musicList-container')
|
|
|
+ .scroll(0, 0);
|
|
|
+ handleGetList();
|
|
|
+ }}>
|
|
|
+ {item.name}
|
|
|
+ </NButton>
|
|
|
+ )
|
|
|
+ )}
|
|
|
+ </NSpace>
|
|
|
+ </div>
|
|
|
+ </NSpace>
|
|
|
+ <TheSearch
|
|
|
+ style={{ marginLeft: 'auto' }}
|
|
|
+ round
|
|
|
+ border={false}
|
|
|
+ onSearch={val => {
|
|
|
+ forms.name = val;
|
|
|
+ data.reshing = true;
|
|
|
+ handleGetList();
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class={styles.contentWrap}>
|
|
|
+ <div class={[styles.musicList, 'musicList-container']}>
|
|
|
+ <div class={[styles.wrapList, 'music-wrap-list']}>
|
|
|
+ {data.list.map((item: IMusicItem, index) => {
|
|
|
+ return (
|
|
|
+ <div class={styles.itemContainer}>
|
|
|
+ <div
|
|
|
+ class={[
|
|
|
+ styles.item,
|
|
|
+ data.listActive === index && styles.active
|
|
|
+ ]}
|
|
|
+ onClick={() => {
|
|
|
+ handleChange(item);
|
|
|
+ musicIframeLoad();
|
|
|
+ }}>
|
|
|
+ <div class={styles.img}>
|
|
|
+ <NImage
|
|
|
+ lazy
|
|
|
+ objectFit="cover"
|
|
|
+ previewDisabled={true}
|
|
|
+ src={item.titleImg || icon_default}
|
|
|
+ onLoad={e => {
|
|
|
+ (e.target as any).dataset.loaded = 'true';
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <PlayLoading
|
|
|
+ class={[
|
|
|
+ data.listActive === index &&
|
|
|
+ data.playState === 'play'
|
|
|
+ ? ''
|
|
|
+ : styles.showPlayLoading
|
|
|
+ ]}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class={styles.title}>
|
|
|
+ <div class={styles.titleName}>
|
|
|
+ <TheNoticeBar text={item.musicSheetName} />
|
|
|
+ </div>
|
|
|
+ <div class={styles.titleDes}>{item.composer}</div>
|
|
|
+ </div>
|
|
|
+ {index == 0 ? (
|
|
|
+ <NButton
|
|
|
+ color="#259CFE"
|
|
|
+ textColor="#fff"
|
|
|
+ {...{ id: 'music-1' }}
|
|
|
+ round
|
|
|
+ class={styles.btn}
|
|
|
+ type="primary"
|
|
|
+ onClick={(e: Event) => {
|
|
|
+ e.stopPropagation();
|
|
|
+ handlePlay(item);
|
|
|
+ if (
|
|
|
+ data.listActive === index &&
|
|
|
+ data.playState === 'play' &&
|
|
|
+ isEnsemble.value
|
|
|
+ ) {
|
|
|
+ musicIframeLoad();
|
|
|
+ }
|
|
|
+ }}>
|
|
|
+ 试听
|
|
|
+ <img
|
|
|
+ src={
|
|
|
+ data.listActive === index &&
|
|
|
+ data.playState === 'play'
|
|
|
+ ? icon_pause
|
|
|
+ : icon_play
|
|
|
+ }
|
|
|
+ />
|
|
|
+ </NButton>
|
|
|
+ ) : (
|
|
|
+ <NButton
|
|
|
+ color="#259CFE"
|
|
|
+ textColor="#fff"
|
|
|
+ round
|
|
|
+ class={styles.btn}
|
|
|
+ type="primary"
|
|
|
+ onClick={(e: Event) => {
|
|
|
+ e.stopPropagation();
|
|
|
+ handlePlay(item);
|
|
|
+ if (
|
|
|
+ data.listActive === index &&
|
|
|
+ data.playState === 'play' &&
|
|
|
+ isEnsemble.value
|
|
|
+ ) {
|
|
|
+ musicIframeLoad();
|
|
|
+ }
|
|
|
+ }}>
|
|
|
+ 试听
|
|
|
+ <img
|
|
|
+ src={
|
|
|
+ data.listActive === index &&
|
|
|
+ data.playState === 'play'
|
|
|
+ ? icon_pause
|
|
|
+ : icon_play
|
|
|
+ }
|
|
|
+ />
|
|
|
+ </NButton>
|
|
|
+ )}
|
|
|
+
|
|
|
+ <img class={styles.arrow} src={icon_arrow} />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+
|
|
|
+ <div
|
|
|
+ ref={spinRef}
|
|
|
+ class={[
|
|
|
+ styles.loadingWrap,
|
|
|
+ data.finshed && styles.showLoading
|
|
|
+ ]}>
|
|
|
+ <NSpin show={true}></NSpin>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {!data.loading && data.list.length === 0 && (
|
|
|
+ <div class={styles.empty}>
|
|
|
+ <TheEmpty></TheEmpty>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class={styles.musicStaff}>
|
|
|
+ <div class={styles.musicName}>
|
|
|
+ {activeItem.value.musicSheetName}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <img
|
|
|
+ id="music-2"
|
|
|
+ style={{
|
|
|
+ display: activeItem.value.id ? '' : 'none'
|
|
|
+ }}
|
|
|
+ class={[styles.goBtn]}
|
|
|
+ src={icon_goXiaoku}
|
|
|
+ onClick={() => {
|
|
|
+ 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';
|
|
|
+ }
|
|
|
+ const src = `${vaildMusicScoreUrl()}/instrument?v=${+new Date()}&platform=pc&showGuide=true&id=${
|
|
|
+ activeItem.value.id
|
|
|
+ }&Authorization=${
|
|
|
+ user.getToken
|
|
|
+ }&musicRenderType=${lineType}&showGuide=true&part-index=${
|
|
|
+ data.musicInstrumentIndex
|
|
|
+ }`;
|
|
|
+ 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);
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <div
|
|
|
+ class={styles.rightBtns}
|
|
|
+ style={{ display: activeItem.value.id ? '' : 'none' }}>
|
|
|
+ {isEnsemble.value && (
|
|
|
+ <NPopselect
|
|
|
+ options={data.trackList}
|
|
|
+ trigger="hover"
|
|
|
+ v-model:value={data.musicInstrumentIndex}
|
|
|
+ onUpdate:value={async (val: any) => {
|
|
|
+ await analyzeXml();
|
|
|
+ //
|
|
|
+ }}
|
|
|
+ // key={item.id}
|
|
|
+ class={[styles.popSelect]}>
|
|
|
+ <NButton round class={[styles.textBtn]}>
|
|
|
+ {data.trackName}
|
|
|
+ <i class={styles.iconArrow}></i>
|
|
|
+ </NButton>
|
|
|
+ </NPopselect>
|
|
|
+ )}
|
|
|
+ {/* 转谱按钮 */}
|
|
|
+ {data.showTransBtn && (
|
|
|
+ <NPopselect
|
|
|
+ options={_actions}
|
|
|
+ trigger="hover"
|
|
|
+ v-model:value={data.showMusicImg}
|
|
|
+ onUpdate:value={async (val: any) => {
|
|
|
+ data.showMusicImg = val;
|
|
|
+ // musicIframeLoad();
|
|
|
+ }}
|
|
|
+ // key={item.id}
|
|
|
+ class={[styles.popTrans]}>
|
|
|
+ <img class={[styles.transBtn]} src={icon_trans} />
|
|
|
+ </NPopselect>
|
|
|
+ )}
|
|
|
+ <div class={styles.favitor} onClick={() => handleFavitor()}>
|
|
|
+ <Transition name="favitor" mode="out-in">
|
|
|
+ {activeItem.value.favitor ? (
|
|
|
+ <img src={icon_favitorActive} key="1" />
|
|
|
+ ) : (
|
|
|
+ <img src={icon_favitor} key="2" />
|
|
|
+ )}
|
|
|
+ </Transition>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class={styles.staffImgs}>
|
|
|
+ {isEnsemble.value ? (
|
|
|
+ <iframe
|
|
|
+ id="staffIframeRef"
|
|
|
+ style={{
|
|
|
+ width: '100%',
|
|
|
+ height: '100%',
|
|
|
+ paddingTop: '20px'
|
|
|
+ // opacity: loading.value ? 0 : 1
|
|
|
+ }}
|
|
|
+ src={data.iframeSrc}
|
|
|
+ onLoad={musicIframeLoad}></iframe>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ {/* <TransitionGroup name="van-fade"> */}
|
|
|
+ {musicImg.value.length > 0 ? (
|
|
|
+ musicImg.value.map((item: string) => {
|
|
|
+ return <img src={item} key={item} />;
|
|
|
+ })
|
|
|
+ ) : (
|
|
|
+ <TheEmpty></TheEmpty>
|
|
|
+ )}
|
|
|
+ {/* </TransitionGroup> */}
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {data.list.length !== 0 && (
|
|
|
+ <PlayItem
|
|
|
+ show={data.showPlayer}
|
|
|
+ playState={data.playState}
|
|
|
+ item={activeItem.value}
|
|
|
+ onChange={value => handleChangeAudio(value)}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ {showGuide.value ? <Musicguide></Musicguide> : null}
|
|
|
+
|
|
|
+ <NModal
|
|
|
+ v-model:show={data.previewModal}
|
|
|
+ onUpdate:show={(val: any) => {
|
|
|
+ if (!val) {
|
|
|
+ data.previewUrl = '';
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ class={styles.previewWindow}
|
|
|
+ showIcon={false}
|
|
|
+ displayDirective="show">
|
|
|
+ <NSpin show={data.showPreivew} style="--n-opacity-spinning: 1;">
|
|
|
+ <img
|
|
|
+ style={{ display: data.showCloseBtn ? '' : 'none' }}
|
|
|
+ src={icon_close}
|
|
|
+ class={styles.previewClose}
|
|
|
+ onClick={() => {
|
|
|
+ data.previewModal = false;
|
|
|
+ data.previewUrl = '';
|
|
|
+ }}
|
|
|
+ />
|
|
|
+
|
|
|
+ <iframe
|
|
|
+ class={styles.previewIframe}
|
|
|
+ onLoad={() => {
|
|
|
+ data.showPreivew = false;
|
|
|
+ }}
|
|
|
+ frameborder="0"
|
|
|
+ src={data.previewUrl}></iframe>
|
|
|
+ </NSpin>
|
|
|
+ </NModal>
|
|
|
+ </div>
|
|
|
+ );
|
|
|
+ }
|
|
|
+});
|