import { Transition, computed, defineComponent, onMounted, onUnmounted, reactive, ref, watch, toRef,ComputedRef } from "vue"; import styles from "./index.module.less"; import iconBack from "./image/icon-back.png"; import listImg from "./image/list.png"; import iconMode from "./image/mode.png"; import { headImg } from "./image"; import { Badge, Circle, Popover, Popup, showConfirmDialog, showToast, NoticeBar } from "vant"; import Speed from "./speed"; import { evaluatingData, handleStartEvaluat } from "/src/view/evaluating"; import Settting from "./settting"; import state, { IPlatform, handleChangeSection, handleResetPlay, handleRessetState, togglePlay, IPlayState, refreshMusicSvg } from "/src/state"; import { getAudioCurrentTime } from "/src/view/audio-list"; import { followData, toggleFollow } from "/src/view/follow-practice"; import { api_back } from "/src/helpers/communication"; import MusicType from "./music-type"; import ModeTypeMode from "../component/mode-type-mode"; import { getQuery } from "/src/utils/queryString"; import { storeData } from "/src/store"; import TeacherTop from "../custom-plugins/guide-page/teacher-top"; import StudentTop from "../custom-plugins/guide-page/student-top"; import { HANDLE_WORK_ADD } from "../custom-plugins/work-index"; import { browser } from "/src/utils"; import store from "store"; import "../component/the-modal-tip/index.module.less"; import { metronomeData } from "../../helpers/metronome"; import { toggleMusicSheet } from "/src/view/plugins/toggleMusicSheet"; import useDrag from "/src/view/plugins/useDrag/index"; import Dragbom from "/src/view/plugins/useDrag/dragbom"; import { getGuidance, setGuidance } from "../custom-plugins/guide-page/api"; import ModeView from "./modeView" import { smoothAnimationState } from "../view-detail/smoothAnimation" import { isMusicList, musicListShow } from "../component/the-music-list"; /** 头部数据和方法 */ export const headTopData = reactive({ /** 模式 */ modeType: "" as "init" | "show", /** 显示返回按钮 */ showBack: true, /** 设置弹窗 */ settingMode: false, /** 切换模式 */ handleChangeModeType(value: "practise" | "follow" | "evaluating") { // 后台设置为不能评测 if (value === "evaluating" && !state.enableEvaluation) return; // 打击乐&节奏练习不支持跟练模式 if (value === "follow" && state.isPercussion) return; // 跟练模式,光标只有音符模式,无节拍模式 if (value === "follow" && metronomeData.cursorMode === 2) { metronomeData.cursorMode = 1; } if (value === "practise") { // state.playIngSpeed = state.speed } if (value === "evaluating") { // 如果延迟检测资源还在加载中,给出提示 if (!evaluatingData.jsonLoadDone) { evaluatingData.jsonLoading = true; state.audioDone && showToast("资源加载中,请稍后"); //音频资源加载完之后才提示 return; } // 如果是pc端, 评测模式暂不可用 if (state.platform === IPlatform.PC) { showConfirmDialog({ className: "modalTip", title: "温馨提示", message: "该功能暂未开放,敬请期待!", showCancelButton: false, }); return; } // 评测模式,只有一行谱模式 if (!state.isSingleLine) { state.isSingleLine = true refreshMusicSvg() } smoothAnimationState.isShow.value = false; // 隐藏旋律线 state.playIngSpeed = state.originSpeed; handleStartEvaluat(); // 开发模式,把此处打开 // state.modeType = "evaluating" // evaluatingData.rendered = true; // evaluatingData.soundEffectMode = true; } else if (value === "follow") { // 跟练模式,只有一行谱模式 if (!state.isSingleLine) { state.isSingleLine = true refreshMusicSvg() } smoothAnimationState.isShow.value = false; toggleFollow(); } headTopData.modeType = "show"; }, }); export const headData = reactive({ speedShow: false, musicTypeShow: false, }); let resetBtn:ComputedRef<{ display: boolean; disabled: boolean; }> /** * 处理模式切换 * @param oldPlayType 没改变之前的播放模式 * @param oldPlaySource 没改变之前的播放类型 * @param isforceReset 是否强制刷新播放状态 模式times时值改变时候也刷新 */ export function handlerModeChange(oldPlayType:"play"|"sing", oldPlaySource:IPlayState,isforceReset?:boolean) { const isModeChange = modeChangeHandleTimes(oldPlayType, oldPlaySource) // 没有切换的时候 不处理下面的 if(isModeChange){ try { metronomeData.metro.calculation(state.times); } catch (error) {} console.log("重新之后的times", state.times, state.fixtime) } if(isModeChange||isforceReset){ // 重置播放状态 handleRessetState() // 隐藏重播按钮 resetBtn && (resetBtn.value.display = false) } } // 模式切换之后重新给times赋值 function modeChangeHandleTimes(oldPlayType:"play"|"sing", oldPlaySource:IPlayState){ const playType = state.playType const playSource = state.playSource const {notBeatFixtime, xmlMp3BeatFixTime, difftime} = state.times[0] const { isOpenMetronome, isSingOpenMetronome } = state // 演奏向演唱切 if(oldPlayType === "play"&&playType === "sing"){ if(playSource === "mingSong"){ // 唱名文件也要加上弱起时间 他们制作曲子加了弱起时间 state.fixtime = difftime state.times.map(item => { item.time = item.xmlNoteTime + difftime item.endtime = item.xmlNoteEndTime + difftime item.fixtime = difftime }) return true }else{ //演奏开了节拍器,演唱没开节拍器 if(isOpenMetronome&&!isSingOpenMetronome){ state.fixtime = notBeatFixtime state.times.map(item => { item.time = item.notBeatTime item.endtime = item.notBeatEndTime item.fixtime = notBeatFixtime }) return true }else if(!isOpenMetronome&&isSingOpenMetronome){ state.fixtime = notBeatFixtime + xmlMp3BeatFixTime state.times.map(item => { item.time = item.notBeatTime + xmlMp3BeatFixTime item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime item.fixtime = notBeatFixtime + xmlMp3BeatFixTime }) return true } } }else if(oldPlayType === "sing"&&playType === "play"){ // 演唱向演奏切 if(oldPlaySource === "mingSong"){ // 有节拍器 if(isOpenMetronome){ state.fixtime = notBeatFixtime + xmlMp3BeatFixTime state.times.map(item => { item.time = item.notBeatTime + xmlMp3BeatFixTime item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime item.fixtime = notBeatFixtime + xmlMp3BeatFixTime }) return true }else{ state.fixtime = notBeatFixtime state.times.map(item => { item.time = item.notBeatTime item.endtime = item.notBeatEndTime item.fixtime = notBeatFixtime }) return true } } // 演奏开了节拍器,演唱没开节拍器 if(isOpenMetronome&&!isSingOpenMetronome){ state.fixtime = notBeatFixtime + xmlMp3BeatFixTime state.times.map(item => { item.time = item.notBeatTime + xmlMp3BeatFixTime item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime item.fixtime = notBeatFixtime + xmlMp3BeatFixTime }) return true }else if(!isOpenMetronome&&isSingOpenMetronome){ state.fixtime = notBeatFixtime state.times.map(item => { item.time = item.notBeatTime item.endtime = item.notBeatEndTime item.fixtime = notBeatFixtime }) return true } }else if(oldPlayType === "sing"&&playType === "sing"){ // 演唱之间切换 // 切到唱名时候 if(playSource === "mingSong"){ // 唱名文件也要加上弱起时间 他们制作曲子加了弱起时间 state.fixtime = difftime state.times.map(item => { item.time = item.xmlNoteTime + difftime item.endtime = item.xmlNoteEndTime + difftime item.fixtime = difftime }) return true }else if(oldPlaySource === "mingSong"){ // 有节拍器 if(isSingOpenMetronome){ state.fixtime = notBeatFixtime + xmlMp3BeatFixTime state.times.map(item => { item.time = item.notBeatTime + xmlMp3BeatFixTime item.endtime = item.notBeatEndTime + xmlMp3BeatFixTime item.fixtime = notBeatFixtime + xmlMp3BeatFixTime }) return true }else{ state.fixtime = notBeatFixtime state.times.map(item => { item.time = item.notBeatTime item.endtime = item.notBeatEndTime item.fixtime = notBeatFixtime }) return true } } } return false } export default defineComponent({ name: "header-top", emits: ["close"], setup(props, { emit }) { const query = getQuery(); // 是否显示引导 const showGuide = ref(false); const showStudentGuide = ref(false); /** 设置按钮 */ const settingBtn = computed(() => { // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; // 评测开始 禁用, 跟练开始 禁用 if (evaluatingData.startBegin || followData.start) return { display: true, disabled: true }; return { display: true, disabled: false, }; }); /** 转谱按钮 */ const converBtn = computed(() => { // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; // 评测开始 禁用 if (evaluatingData.startBegin || followData.start) return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 速度按钮 */ const speedBtn = computed(() => { // 选择模式, 跟练模式 不显示 if (headTopData.modeType !== "show" || state.modeType === "follow") return { display: false, disabled: true }; // 评测模式, 音频播放中 禁用 if (state.modeType === "evaluating" || state.playState === "play") return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 节拍器按钮 */ const metronomeBtn = computed(() => { // 选择模式 不显示 if (headTopData.modeType !== "show") return { display: false, disabled: true }; // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 指法按钮 */ const fingeringBtn = computed(() => { // 后台设置不显示指法 if (!state.isShowFingering) return { display: true, disabled: true }; // 没有指法 选择模式 评测模式 跟练模式 不显示 if (headTopData.modeType !== "show" || !state.fingeringInfo.name || ["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true }; // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 摄像头按钮 */ const cameraBtn = computed(() => { // 选择模式 不显示 if (headTopData.modeType !== "show" || state.modeType !== "evaluating") return { display: false, disabled: true }; // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 选段按钮 */ const selectBtn = computed(() => { // 选择模式 不显示 if (headTopData.modeType !== "show" || ["follow"].includes(state.modeType)) return { display: false, disabled: true }; // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; return { disabled: false, display: true, }; }); /** 原声按钮 */ const originBtn = computed(() => { // 选择模式,跟练模式 不显示 if (headTopData.modeType !== "show" || state.modeType === "follow") return { display: false, disabled: false }; // 评测开始 禁用 if (state.modeType === "evaluating") return { display: false, disabled: true }; if (!state.isAppPlay) { if(state.playType === "play"){ // 原声, 伴奏 少一个,就不能切换 if (state.music && state.accompany) return { display: true, disabled: false }; } else { // 播放过程中不能切换 if (state.playState === "play"){ return { display: true, disabled: true }; } // 范唱 let index = 0 state.fanSong && index++ state.banSong && index++ state.mingSong && index++ if(index > 1) { return { display: true, disabled: false }; } } } return { disabled: true, display: true, }; }); /** 播放类型按钮 */ const playTypeBtn = computed(() => { // 选择模式,跟练模式 不显示 if (headTopData.modeType !== "show" || state.modeType === "follow") return { display: false, disabled: false }; // 评测开始 禁用 if (state.modeType === "evaluating") return { display: false, disabled: true }; // 音频播放中 禁用 if (state.playState === "play") return { display: true, disabled: true }; if (!state.isAppPlay) { let index = 0 state.music && index++ state.accompany && index++ let songIndex = 0 state.fanSong && songIndex++ state.banSong && songIndex++ state.mingSong && songIndex++ // 演唱和演奏 都有数据的时间不禁用 if(songIndex>0&&index>0) { return { display: true, disabled: false }; } } return { disabled: true, display: true, }; }) /** 模式切换按钮 */ const toggleBtn = computed(() => { // 选择模式, url设置模式 不显示 if (headTopData.modeType !== "show" || !headTopData.showBack) return { display: false, disabled: false }; // 跟练开始, 评测开始 播放开始 隐藏 if (state.playState == "play" || followData.start || evaluatingData.startBegin) return { display: false, disabled: false }; return { display: true, disabled: false, }; }); /** 播放按钮 */ const playBtn = computed(() => { // 选择模式 不显示 if (headTopData.modeType !== "show") return { display: false, disabled: false }; // 评测模式 不显示,跟练模式 不显示 if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true }; // midi音频未初始化完成不可点击 if (state.isAppPlay && state.midiPlayIniting) return { display: true, disabled: true }; return { display: true, disabled: false, }; }); /** 重播按钮 */ resetBtn = computed(() => { // 选择模式 不显示 if (headTopData.modeType !== "show") return { display: false, disabled: false }; // 评测模式 不显示,跟练模式 不显示 if (["evaluating", "follow"].includes(state.modeType)) return { display: false, disabled: true }; // 播放状态 不显示 if (state.playState === "play") return { display: false, disabled: true }; // 播放进度为0 不显示 const currentTime = getAudioCurrentTime(); // midi音频未初始化完成不可点击 if (state.isAppPlay && state.midiPlayIniting) return { display: false, disabled: true }; if (!currentTime) return { display: false, disabled: true }; return { display: true, disabled: false, }; }); const isAllBtns = computed(() => { const flag = converBtn.value.display && speedBtn.value.display && selectBtn.value.display && originBtn.value.display && toggleBtn.value.display && showGuide.value; return flag; }); const isAllBtnsStudent = computed(() => { const flag = converBtn.value.display && speedBtn.value.display && selectBtn.value.display && originBtn.value.display && toggleBtn.value.display && showStudentGuide.value; return flag; }); const showGuideIndex = computed(() => { // 从课堂乐器学生端课件预览默认不显示会员 if (storeData.user.vipMember || state.paymentType === "FREE" || query.showCourseMember === "true") { // 学生端 return true; } else { // vip return false; } }); const browInfo = browser(); /** 返回 */ const handleBack = () => { HANDLE_WORK_ADD(); // 不在APP中, if (!storeData.isApp) { window.close(); return; } if ((browInfo.iPhone || browInfo.ios) && query.workRecord) { setTimeout(() => { api_back(); }, 550); return; } api_back(); }; /** 根据参数设置模式 */ const getQueryModelSetModelType = () => { /** 作业模式 start, 如果为作业模式不处理,让作业模块处理 */ if (query.workRecord) { return; } /** 作业模式 end */ if (state.defaultModeType == 1) { headTopData.handleChangeModeType("practise"); if (state.platform === IPlatform.PC || state.isPreView) { headTopData.showBack = false; } } else { if (query.modelType) { if (query.modelType === "practise") { headTopData.handleChangeModeType("practise"); } else if (query.modelType === "evaluating") { headTopData.handleChangeModeType("evaluating"); } headTopData.showBack = false; } else { setTimeout(() => { headTopData.modeType = "init"; }, 500); } } }; /** 课件播放 */ const changePlay = (res: any) => { // console.log('监听上课页面message',res) if (res?.data?.api === "setPlayState") { togglePlay("paused", "courseware"); } // 上课页面,按钮方向 if (res?.data?.api === "imagePos") { if (res?.data.data) { state.playBtnDirection = res.data.data === "right" ? "right" : "left"; // if (state.fingeringInfo.direction === "vertical" && state.setting.displayFingering) { // state.musicScoreBtnDirection = state.playBtnDirection === 'right' ? 'left' : 'right'; // } else { // state.musicScoreBtnDirection = state.playBtnDirection; // } state.musicScoreBtnDirection = state.playBtnDirection; } } }; const parentClassName = "settingBoxClass_drag"; const userId = storeData.user?.id ? String(storeData.user?.id) : ""; const positionInfo = state.platform !== IPlatform.PC ? { styleDrag: { value: null }, } : useDrag([`${parentClassName} .top_drag`, `${parentClassName} .bom_drag`], parentClassName, toRef(headTopData, "settingMode"), userId); onMounted(() => { getQueryModelSetModelType(); window.addEventListener("message", changePlay); if (state.platform === IPlatform.PC) { showGuide.value = true; } else { showStudentGuide.value = true; } }); onUnmounted(() => { window.removeEventListener("message", changePlay); }); // 设置改变触发 watch(state.setting, () => { console.log(state.setting, "state.setting"); store.set("musicscoresetting", state.setting); }); // 获取引导页信息 const getAllGuidance = async () => { let guideInfo: any = null; try { const res = await getGuidance({ guideTag: "guideInfo" }); if (res.data) { guideInfo = JSON.parse(res.data?.guideValue) || null; } else { guideInfo = {}; } state.guideInfo = guideInfo; } catch (e) { console.log(e); } }; getAllGuidance(); // 完成拖动弹窗引导页 const handleGuide = async () => { state.guideInfo.teacherDrag = true; try { const res = await setGuidance({ guideTag: "guideInfo", guideValue: JSON.stringify(state.guideInfo) }); } catch (e) { console.log(e); } }; return () => ( <>
{ e.stopPropagation(); if (state.platform === IPlatform.PC) { // 显示隐藏菜单 window.parent.postMessage( { api: "onAttendToggleMenu", }, "*" ); } }} > {/* 返回和标题 */} { !(state.playState == "play" || followData.start || evaluatingData.startBegin) &&
{ smoothAnimationState.isShow.value ?
{ isMusicList.value && (musicListShow.value = true) }}>
: isMusicList.value && { musicListShow.value = true }} /> }
} {/* 模式切换 */} { state.playType === "play" &&
{ handleRessetState(); headTopData.modeType = "init"; }} >
{state.modeType==="practise" ? '练习模式' : state.modeType==="follow" ? "跟练模式" : state.modeType==="evaluating" ? "评测模式" : ""}
} {/* 模式提醒 */} { state.modeType === "practise" &&
{state.playType === "play" ? "演奏场景" : "演唱场景"}
} {/* 功能按钮 */}
{ e.stopPropagation(); }} > {/* 一行谱模式,暂不支持节拍指针 */} {/* {!state.isSingleLine ? (
{ // 切换光标模式 let mode = metronomeData.cursorMode; if (["follow"].includes(state.modeType)) { mode = metronomeData.cursorMode === 1 ? 3 : 1; } else { mode = metronomeData.cursorMode === 3 ? 1 : metronomeData.cursorMode + 1; } metronomeData.cursorMode = mode; }} > {metronomeData.cursorMode === 1 ? "音符指针" : metronomeData.cursorMode === 2 ? "节拍指针" : metronomeData.cursorMode === 3 ? "关闭指针" : ""} {metronomeData.cursorTips && ( <>
{metronomeData.cursorTips}
)}
) : null} */}
{ const oldPlayType = state.playType const oldPlaySource = state.playSource if(state.playType === "play"){ state.playType = "sing" state.playSource = state.fanSong?"music":state.banSong?"background":"mingSong" } else { state.playType = "play" state.playSource = state.music?"music":"background" } handlerModeChange(oldPlayType, oldPlaySource, true) }} > {state.playType === "play" ? "演奏" : "演唱"}
{ const oldPlayType = state.playType const oldPlaySource = state.playSource if(state.playType === 'play'){ state.playSource = state.playSource === "music" ? "background" : "music"; }else{ if(state.playSource === "music"){ state.playSource = state.banSong ? "background" :"mingSong" }else if(state.playSource === "background"){ state.playSource = state.mingSong ? "mingSong" :"music" }else { state.playSource = state.fanSong ? "music" :"background" } } handlerModeChange(oldPlayType, oldPlaySource) }} > {state.playSource === "music" ? (state.playType ==="play" ? "原声" : "范唱") : state.playSource === "background" ? (state.playType ==="play" ? "伴奏" : "伴唱") : "唱名"}
handleChangeSection()}> 选段
{( <>
{ headData.speedShow = !headData.speedShow; }} > 节拍
{state.speed}
{ {state.platform === IPlatform.PC && } } )} {/* {state.enableNotation ? ( {{ reference: () => (
{ e.stopPropagation(); headData.musicTypeShow = !headData.musicTypeShow; }} > {state.musicRenderType === "staff" ? "转简谱" : "转五线谱"}
), default: () => , }}
) : null} */} {state.musicRendered && !query.lessonTrainingId && !query.questionId && state.isConcert && (
{ toggleMusicSheet.toggle(true); }} > 声部
)}
(headTopData.settingMode = true)}> 设置
{/* 播放按钮 */}
togglePlay()} >
{/* 重播按钮 */}
handleResetPlay()} >
{state.platform === IPlatform.PC && } {/* 模式切换 */} {/* */} {/* isAllBtns */} {isAllBtns.value && !query.isCbs && showGuideIndex.value && } {isAllBtnsStudent.value && !query.isCbs && showGuideIndex.value && } ); }, });