|
@@ -1,1541 +1,1595 @@
|
|
|
-import { computed, defineComponent, nextTick, onMounted, reactive, ref, shallowRef, watch } from "vue"
|
|
|
-import styles from "./index.module.scss"
|
|
|
-import NavContainer from "@/businessComponents/navContainer"
|
|
|
-import { ElEmpty, ElMessage, ElScrollbar } from "element-plus"
|
|
|
-import Dictionary from "@/components/dictionary"
|
|
|
-import MyInput from "@/components/myInput"
|
|
|
-import { NImage, NPopselect, NSpin, NTooltip } from "naive-ui"
|
|
|
-import PlayItem from "./component/play-item"
|
|
|
-import icon_default from "../../img/cloudPractice/icon_default.png"
|
|
|
-import iconBtnPause from "../../img/cloudPractice/icon-btn-pause.png"
|
|
|
-import iconBtnPlay from "../../img/cloudPractice/icon-btn-play.png"
|
|
|
-import btnSubmit from "../../img/cloudPractice/btn-submit.png"
|
|
|
-import iconTransfer from "../../img/cloudPractice/icon-transfer.png"
|
|
|
-import iconDownload from "../../img/cloudPractice/icon-download.png"
|
|
|
-import { httpAjaxErrMsg } from "@/plugin/httpAjax"
|
|
|
-import {
|
|
|
- queryPage2_gym,
|
|
|
- queryPage2_gyt,
|
|
|
- queryPage2_klx,
|
|
|
- querySubjectIds_gym,
|
|
|
- querySubjectIds_gyt,
|
|
|
- querySubjectIds_klx,
|
|
|
- queryTree_gym,
|
|
|
- queryTree_gyt,
|
|
|
- queryTree_klx,
|
|
|
- selectCondition_klx,
|
|
|
- cbsDetail_gym
|
|
|
-} from "@/api/cloudPractice.api"
|
|
|
-import axios from "axios"
|
|
|
-import { getInstrumentName } from "@/libs/instruments"
|
|
|
-import { formatXML, getCustomInfo, onlyVisible } from "./instrument"
|
|
|
-import { useFunction } from "./useData"
|
|
|
-import userStore from "@/store/modules/user"
|
|
|
-import PlayLoading from "./component/play-loading"
|
|
|
-import PracticeForm from "@/businessComponents/practiceForm"
|
|
|
-import { saveAs } from "file-saver"
|
|
|
-import JSZip from "jszip"
|
|
|
-import { svgtoblob } from "./formatSvgToImg"
|
|
|
-import { penShow, whitePenShow } from "@/businessComponents/globalTools/globalTools"
|
|
|
-import { handleFullscreen } from "@/libs/fullscreen"
|
|
|
-
|
|
|
-export default defineComponent({
|
|
|
- name: "cloudPractice",
|
|
|
- setup() {
|
|
|
- const userStoreHook = userStore()
|
|
|
- const { goToCloud, getPreViewCloud, isPracticeShow, practiceUrl, handlePracticeClose } = useFunction()
|
|
|
- const navs = [
|
|
|
- {
|
|
|
- name: "主页",
|
|
|
- url: "/"
|
|
|
- },
|
|
|
- {
|
|
|
- name: "云练习"
|
|
|
- }
|
|
|
- ]
|
|
|
- const spinRef = ref()
|
|
|
- const state = reactive({
|
|
|
- finshed: false,
|
|
|
- reshing: false,
|
|
|
- page: 1,
|
|
|
- rows: 20,
|
|
|
- details: {} as any,
|
|
|
- iframeSrc: "",
|
|
|
- listActive: 0, // 当前选中的对象
|
|
|
- firstTreeId: null as any, // 左侧
|
|
|
- categoryId: null as any, // 类型
|
|
|
- categoryName: "" as any, // 类型名称
|
|
|
- categoryList: [] as any[],
|
|
|
- levelList: [] as any[], // 级别
|
|
|
- levelId: null as any,
|
|
|
- typeList: [] as any[], // 类型
|
|
|
- typeId: -1 as any,
|
|
|
- subjectList: [] as any[], // 声部列表
|
|
|
- subjectId: -1 as any,
|
|
|
- list: [] as any[],
|
|
|
- searchStatus: false,
|
|
|
- queryStr: "", // 搜索条件
|
|
|
- partList: [] as any[],
|
|
|
- partNames: [] as any[],
|
|
|
- selectedPartName: "" as any,
|
|
|
- selectedTrack: "" as any,
|
|
|
- selectedPartIndex: 0,
|
|
|
- partXmlIndex: 0,
|
|
|
- musicPdfUrl: "", // 五线谱文件
|
|
|
- imgs: [] as any[], // 图片列表
|
|
|
- categoryShow: false, // 是否展开
|
|
|
- playState: "pause" as "play" | "pause", // 播放状态
|
|
|
- showPlayer: false // 是否显示播放器
|
|
|
- })
|
|
|
- const partColumns = ref<any>([])
|
|
|
-
|
|
|
- /** 选中的item */
|
|
|
- const activeItem = computed(() => {
|
|
|
- const list = state.list[state.listActive] || {}
|
|
|
- let tempList: any = {}
|
|
|
-
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- // const item = list.background?.[0]
|
|
|
- // const audioFileUrl = item?.musicSheetType === "CONCERT" ? item?.metronomeUrl : item?.metronomeMp3Url || item?.mp3Url
|
|
|
- tempList = {
|
|
|
- id: list?.id,
|
|
|
- name: list?.name,
|
|
|
- // background: list?.background,
|
|
|
- // xmlUrl: item?.xmlUrl,
|
|
|
- // musicSheetType: item?.musicSheetType,
|
|
|
- audioFileUrl: list.audioFileUrl,
|
|
|
- titleImg: list?.titleImg
|
|
|
- // musicImg: list.titleImg
|
|
|
- // musicJianImg: list.musicJianSvg,
|
|
|
- // musicFirstImg: list.musicFirstSvg,
|
|
|
- // isScoreRender: item?.isScoreRender,
|
|
|
- // defaultScoreRender: item?.defaultScoreRender,
|
|
|
- // musicPdfUrl: item?.musicPdfUrl // 独奏使用PDF
|
|
|
- }
|
|
|
- } else if (userStoreHook.roles === "GYT") {
|
|
|
- tempList = {
|
|
|
- id: list?.id,
|
|
|
- name: list?.musicSheetName,
|
|
|
- background: list?.background,
|
|
|
- xmlUrl: list?.xmlFileUrl,
|
|
|
- musicSheetType: list?.musicSheetType,
|
|
|
- audioFileUrl: list?.audioFileUrl,
|
|
|
- titleImg: list?.titleImg,
|
|
|
- musicImg: list.musicImg,
|
|
|
- musicJianImg: list.musicJianSvg,
|
|
|
- musicFirstImg: list.musicFirstSvg,
|
|
|
- isScoreRender: list?.isScoreRender,
|
|
|
- defaultScoreRender: list?.defaultScoreRender,
|
|
|
- musicPdfUrl: list?.musicPdfUrl
|
|
|
- }
|
|
|
- } else if (userStoreHook.roles === "KLX") {
|
|
|
- const item: any = list.background?.[0]
|
|
|
- tempList = {
|
|
|
- id: list?.id,
|
|
|
- name: list?.musicSheetName,
|
|
|
- background: list?.background,
|
|
|
- xmlUrl: list?.xmlFileUrl,
|
|
|
- musicSheetType: list?.musicSheetType,
|
|
|
- audioFileUrl: item?.audioFileUrl,
|
|
|
- titleImg: list?.titleImg,
|
|
|
- musicImg: list.musicImg,
|
|
|
- musicJianImg: list.musicJianSvg,
|
|
|
- musicFirstImg: list.musicFirstSvg,
|
|
|
- isScoreRender: false,
|
|
|
- defaultScoreRender: false,
|
|
|
- musicPdfUrl: list?.musicPdfUrl
|
|
|
- }
|
|
|
- }
|
|
|
- return tempList
|
|
|
- })
|
|
|
-
|
|
|
- const songPrevNextStatus = computed(() => {
|
|
|
- let prev = true,
|
|
|
- next = true
|
|
|
- if (state.listActive === 0) {
|
|
|
- prev = false
|
|
|
- }
|
|
|
-
|
|
|
- if (state.listActive >= state.list.length - 1) {
|
|
|
- next = false
|
|
|
- }
|
|
|
-
|
|
|
- return {
|
|
|
- prev,
|
|
|
- next
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- const downloadStatus = ref(false)
|
|
|
- const loading = ref(false)
|
|
|
- const staffLoading = ref(false)
|
|
|
- const storeData = shallowRef<any[]>([])
|
|
|
- const handleSearchList_gym = async () => {
|
|
|
- loading.value = true
|
|
|
- await httpAjaxErrMsg(queryTree_gym).then(async res => {
|
|
|
- loading.value = false
|
|
|
- if (res.code === 200) {
|
|
|
- storeData.value = res.data || []
|
|
|
-
|
|
|
- await setDefaultData()
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- const handleGetSubject_gym = async () => {
|
|
|
- loading.value = true
|
|
|
- await httpAjaxErrMsg(querySubjectIds_gym, { categoriesId: state.categoryId || state.firstTreeId }).then(res => {
|
|
|
- loading.value = false
|
|
|
- if (res.code === 200) {
|
|
|
- const result = res.data || []
|
|
|
-
|
|
|
- state.subjectList = result.map((item: any) => {
|
|
|
- return {
|
|
|
- label: item.name,
|
|
|
- value: item.id,
|
|
|
- instrumentIds: item.instrumentIds
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- state.subjectList.unshift({
|
|
|
- label: "全部声部",
|
|
|
- value: -1
|
|
|
- })
|
|
|
-
|
|
|
- const userSubjectId = userStoreHook.userInfo.subjectId
|
|
|
- if (userSubjectId) {
|
|
|
- const tempSubjectId = userSubjectId.split(",")[0]
|
|
|
- state.subjectList.forEach((item: any) => {
|
|
|
- // 判断是否存在声部编号
|
|
|
- if (item.value === Number(tempSubjectId)) {
|
|
|
- state.subjectId = Number(tempSubjectId)
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- const handleGetList_gym = async () => {
|
|
|
- loading.value = true
|
|
|
- const params = {
|
|
|
- page: state.page,
|
|
|
- rows: state.rows,
|
|
|
- subjectId: state.subjectId === -1 ? null : state.subjectId,
|
|
|
- categoriesId: state.typeId === -1 ? state.levelId : state.typeId,
|
|
|
- search: state.queryStr
|
|
|
- }
|
|
|
-
|
|
|
- await httpAjaxErrMsg(queryPage2_gym, params).then(res => {
|
|
|
- loading.value = false
|
|
|
- if (res.code === 200) {
|
|
|
- const result = res.data || []
|
|
|
-
|
|
|
- if (state.reshing) {
|
|
|
- state.list = []
|
|
|
- state.reshing = false
|
|
|
- }
|
|
|
- if (Array.isArray(result.rows)) {
|
|
|
- state.list = [...state.list, ...result.rows]
|
|
|
- state.finshed = state.page >= result.totalPage
|
|
|
- } else {
|
|
|
- state.finshed = true
|
|
|
- }
|
|
|
- } else {
|
|
|
- state.finshed = true
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- const handleGetDetail_gym = async () => {
|
|
|
- loading.value = true
|
|
|
- const { id } = state.list[state.listActive] || {}
|
|
|
- if (!id) return (loading.value = false)
|
|
|
- await httpAjaxErrMsg(cbsDetail_gym, id, { simpleFlag: "1" }).then(res => {
|
|
|
- loading.value = false
|
|
|
- if (res.code === 200) {
|
|
|
- const result = res.data || {}
|
|
|
- state.details = result
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- /** 管乐团数据查询 */
|
|
|
- const handleSearchList_gyt = async () => {
|
|
|
- loading.value = true
|
|
|
- await httpAjaxErrMsg(queryTree_gyt, {
|
|
|
- enable: true,
|
|
|
- page: 1,
|
|
|
- parentId: 0,
|
|
|
- rows: 10
|
|
|
- }).then(res => {
|
|
|
- loading.value = false
|
|
|
- if (res.code === 200) {
|
|
|
- storeData.value = res.data || []
|
|
|
-
|
|
|
- setDefaultData()
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- const handleGetSubject_gyt = async () => {
|
|
|
- loading.value = true
|
|
|
- await httpAjaxErrMsg(querySubjectIds_gyt, {
|
|
|
- enableFlag: true,
|
|
|
- page: 1,
|
|
|
- rows: 100
|
|
|
- }).then(res => {
|
|
|
- loading.value = false
|
|
|
- if (res.code === 200) {
|
|
|
- const result = res.data || []
|
|
|
-
|
|
|
- state.subjectList = result.map((item: any) => {
|
|
|
- return {
|
|
|
- label: item.name,
|
|
|
- value: item.id,
|
|
|
- instrumentIds: item.instrumentIds
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- state.subjectList.unshift({
|
|
|
- label: "全部声部",
|
|
|
- value: -1
|
|
|
- })
|
|
|
-
|
|
|
- const userSubjectId = userStoreHook.userInfo.subjectId
|
|
|
- if (userSubjectId) {
|
|
|
- const tempSubjectId = userSubjectId.split(",")[0]
|
|
|
- state.subjectList.forEach((item: any) => {
|
|
|
- // 判断是否存在声部编号
|
|
|
- if (item.value === Number(tempSubjectId)) {
|
|
|
- state.subjectId = Number(tempSubjectId)
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- const handleGetList_gyt = async () => {
|
|
|
- loading.value = true
|
|
|
- const params = {
|
|
|
- page: state.page,
|
|
|
- rows: state.rows,
|
|
|
- musicSubject: state.subjectId === -1 ? null : state.subjectId,
|
|
|
- musicSheetCategoriesId: state.typeId === -1 ? state.levelId : state.typeId,
|
|
|
- keyword: state.queryStr,
|
|
|
- detailFlag: true,
|
|
|
- status: 1
|
|
|
- }
|
|
|
- await httpAjaxErrMsg(queryPage2_gyt, params).then(res => {
|
|
|
- loading.value = false
|
|
|
- if (res.code === 200) {
|
|
|
- const result = res.data || {}
|
|
|
-
|
|
|
- if (state.reshing) {
|
|
|
- state.list = []
|
|
|
- state.reshing = false
|
|
|
- }
|
|
|
-
|
|
|
- if (Array.isArray(result.rows)) {
|
|
|
- result.rows.forEach((item: any) => {
|
|
|
- item.name = item.musicSheetName
|
|
|
- })
|
|
|
- state.list = [...state.list, ...result.rows]
|
|
|
- state.finshed = state.page >= result.pages
|
|
|
- } else {
|
|
|
- state.finshed = true
|
|
|
- }
|
|
|
- } else {
|
|
|
- state.finshed = true
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- /** 酷乐秀机构数据查询 */
|
|
|
- const handleSearchList_klx = async () => {
|
|
|
- loading.value = true
|
|
|
- await httpAjaxErrMsg(queryTree_klx, {
|
|
|
- enable: true,
|
|
|
- page: 1,
|
|
|
- parentId: 0,
|
|
|
- rows: 10
|
|
|
- }).then(async res => {
|
|
|
- loading.value = false
|
|
|
- if (res.code === 200) {
|
|
|
- const result = res.data || []
|
|
|
-
|
|
|
- const tempList: any = []
|
|
|
- result.forEach((item: any) => {
|
|
|
- if (item.musicNum > 0) {
|
|
|
- const subjectCounts = item.subjectCounts ? true : false
|
|
|
- const musicCounts = item.musicCounts ? true : false
|
|
|
- const ensembleCounts = item.ensembleCounts ? true : false
|
|
|
- const list: any = []
|
|
|
- if (subjectCounts) {
|
|
|
- list.push({
|
|
|
- label: "基础云练",
|
|
|
- value: "SUBJECT"
|
|
|
- })
|
|
|
- }
|
|
|
- if (musicCounts) {
|
|
|
- list.push({
|
|
|
- label: "独奏云练",
|
|
|
- value: "MUSIC"
|
|
|
- })
|
|
|
- }
|
|
|
- if (ensembleCounts) {
|
|
|
- list.push({
|
|
|
- label: "合奏云练",
|
|
|
- value: "ENSEMBLE"
|
|
|
- })
|
|
|
- }
|
|
|
- tempList.push({
|
|
|
- value: item.id,
|
|
|
- label: item.name,
|
|
|
- musicSheetCategoriesList: list
|
|
|
- })
|
|
|
- }
|
|
|
- })
|
|
|
- state.categoryList = tempList
|
|
|
-
|
|
|
- await setDefaultData()
|
|
|
- } else {
|
|
|
- state.finshed = true
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- const handleGetSubject_klx = async () => {
|
|
|
- loading.value = true
|
|
|
- await httpAjaxErrMsg(querySubjectIds_klx, {
|
|
|
- queryType: "list",
|
|
|
- page: 1,
|
|
|
- rows: 100
|
|
|
- }).then(res => {
|
|
|
- loading.value = false
|
|
|
- if (res.code === 200) {
|
|
|
- const result = res.data?.rows || []
|
|
|
- state.subjectList = result.map((item: any) => {
|
|
|
- return {
|
|
|
- label: item.name,
|
|
|
- value: item.id,
|
|
|
- instrumentIds: item.instrumentIds
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- state.subjectList.unshift({
|
|
|
- label: "全部声部",
|
|
|
- value: -1
|
|
|
- })
|
|
|
-
|
|
|
- const userSubjectId = userStoreHook.userInfo.subjectId
|
|
|
- if (userSubjectId) {
|
|
|
- const tempSubjectId = userSubjectId.split(",")[0]
|
|
|
- state.subjectList.forEach((item: any) => {
|
|
|
- // 判断是否存在声部编号
|
|
|
- if (item.value === Number(tempSubjectId)) {
|
|
|
- state.subjectId = Number(tempSubjectId)
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- const handleGetList_klx = async () => {
|
|
|
- if (!state.categoryId) return
|
|
|
- loading.value = true
|
|
|
- const params = {
|
|
|
- page: state.page,
|
|
|
- rows: state.rows,
|
|
|
- albumId: state.categoryId,
|
|
|
- subjectId: state.subjectId === -1 ? null : state.subjectId,
|
|
|
- subjectType: state.firstTreeId,
|
|
|
- level: state.levelId === -1 ? null : state.levelId,
|
|
|
- type: state.typeId === -1 ? null : state.typeId,
|
|
|
- keyword: state.queryStr
|
|
|
- }
|
|
|
- await httpAjaxErrMsg(queryPage2_klx, params).then(res => {
|
|
|
- loading.value = false
|
|
|
- if (res.code === 200) {
|
|
|
- const result = res.data || {}
|
|
|
-
|
|
|
- if (state.reshing) {
|
|
|
- state.list = []
|
|
|
- state.reshing = false
|
|
|
- }
|
|
|
-
|
|
|
- if (Array.isArray(result.rows)) {
|
|
|
- result.rows.forEach((item: any) => {
|
|
|
- item.name = item.musicSheetName
|
|
|
- })
|
|
|
- state.list = [...state.list, ...result.rows]
|
|
|
- state.finshed = state.page >= result.totalPage
|
|
|
- } else {
|
|
|
- state.finshed = true
|
|
|
- }
|
|
|
- } else {
|
|
|
- state.finshed = true
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- const handleSelectCondition_klx = async () => {
|
|
|
- if (!state.categoryId || !state.firstTreeId) return
|
|
|
- loading.value = true
|
|
|
- const params = {
|
|
|
- tenantAlbumId: state.categoryId,
|
|
|
- subjectType: state.firstTreeId
|
|
|
- }
|
|
|
- await httpAjaxErrMsg(selectCondition_klx, params).then(res => {
|
|
|
- loading.value = false
|
|
|
- if (res.code === 200) {
|
|
|
- const result = res.data || {}
|
|
|
-
|
|
|
- if (result.levelList && result.levelList.length > 0) {
|
|
|
- state.levelList = result.levelList.map((item: any) => {
|
|
|
- return {
|
|
|
- label: item.value,
|
|
|
- value: item.id
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- state.levelList.unshift({
|
|
|
- label: "全部级别",
|
|
|
- value: -1
|
|
|
- })
|
|
|
- state.levelId = -1
|
|
|
- } else {
|
|
|
- state.levelList = []
|
|
|
- }
|
|
|
-
|
|
|
- if (result.typeList && result.typeList.length > 0) {
|
|
|
- state.typeList = result.typeList.map((item: any) => {
|
|
|
- return {
|
|
|
- label: item.value,
|
|
|
- value: item.id
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- state.typeList.unshift({
|
|
|
- label: "全部类型",
|
|
|
- value: -1
|
|
|
- })
|
|
|
- state.typeId = -1
|
|
|
- } else {
|
|
|
- state.typeList = []
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- /** 条件查询 */
|
|
|
- const handleAllSearchList = async () => {
|
|
|
- // GYM,GYT,KLX 区分 查询搜索条件数据
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- await handleSearchList_gym()
|
|
|
- } else if (userStoreHook.roles === "GYT") {
|
|
|
- await handleSearchList_gyt()
|
|
|
- } else if (userStoreHook.roles === "KLX") {
|
|
|
- await handleSearchList_klx()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const handleAllGetSubject = async () => {
|
|
|
- // GYM,GYT,KLX 区分 查询声部数据
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- await handleGetSubject_gym()
|
|
|
- } else if (userStoreHook.roles === "GYT") {
|
|
|
- await handleGetSubject_gyt()
|
|
|
- } else if (userStoreHook.roles === "KLX") {
|
|
|
- await handleGetSubject_klx()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const handleAllGetList = async () => {
|
|
|
- // GYM,GYT,KLX 区分 查询声部数据·
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- await handleGetList_gym()
|
|
|
- } else if (userStoreHook.roles === "GYT") {
|
|
|
- await handleGetList_gyt()
|
|
|
- } else if (userStoreHook.roles === "KLX") {
|
|
|
- await handleGetList_klx()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const handleGetDetail = async () => {
|
|
|
- // GYM,GYT,KLX 区分 查询声部数据·
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- await handleGetDetail_gym()
|
|
|
- } else if (userStoreHook.roles === "GYT") {
|
|
|
- // await handleGetList_gyt()
|
|
|
- } else if (userStoreHook.roles === "KLX") {
|
|
|
- // await handleGetList_klx()
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /** 初始化数据 */
|
|
|
- const setDefaultData = async (type?: "first" | "category" | "level" | "type") => {
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- await initCategories_gym(type)
|
|
|
- } else if (userStoreHook.roles === "GYT") {
|
|
|
- initCategories_gyt(type)
|
|
|
- } else if (userStoreHook.roles === "KLX") {
|
|
|
- await initCategories_klx(type)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const initCategories_gym = async (type?: "first" | "category" | "level" | "type") => {
|
|
|
- if (storeData.value.length > 0 && !["category", "level", "type"].includes(type as any)) {
|
|
|
- let result: any = []
|
|
|
- if (type === "first" && state.firstTreeId) {
|
|
|
- result = storeData.value.find((item: any) => item.id === state.firstTreeId)?.sysMusicScoreCategoriesList || []
|
|
|
- } else {
|
|
|
- state.firstTreeId = storeData.value[0]?.id
|
|
|
- result = storeData.value[0]?.sysMusicScoreCategoriesList || []
|
|
|
- }
|
|
|
- state.categoryList = result.map((item: any) => {
|
|
|
- return {
|
|
|
- label: item.name,
|
|
|
- value: item.id,
|
|
|
- sysMusicScoreCategoriesList: item.sysMusicScoreCategoriesList || []
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- state.categoryId = null
|
|
|
- state.categoryName = null
|
|
|
- state.levelId = null
|
|
|
- state.typeId = -1
|
|
|
- }
|
|
|
- if (state.categoryList.length > 0 && !["level", "type"].includes(type as any)) {
|
|
|
- let result: any = []
|
|
|
- if (type === "category" && state.categoryId) {
|
|
|
- result = state.categoryList.find((item: any) => item.value === state.categoryId)?.sysMusicScoreCategoriesList || []
|
|
|
- } else {
|
|
|
- state.categoryId = state.categoryList[0]?.value
|
|
|
- state.categoryName = state.categoryList[0]?.label
|
|
|
- result = state.categoryList[0]?.sysMusicScoreCategoriesList || []
|
|
|
- }
|
|
|
- state.levelList = result.map((item: any) => {
|
|
|
- return {
|
|
|
- label: item.name,
|
|
|
- value: item.id,
|
|
|
- sysMusicScoreCategoriesList: item.sysMusicScoreCategoriesList || []
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- type && (await handleGetSubject_gym())
|
|
|
- }
|
|
|
-
|
|
|
- if (state.levelList.length > 0) {
|
|
|
- let result: any = []
|
|
|
- if (type === "level" && state.levelId) {
|
|
|
- result = state.levelList.find((item: any) => item.value === state.levelId)?.sysMusicScoreCategoriesList
|
|
|
- state.typeId = -1
|
|
|
- } else {
|
|
|
- state.levelId = state.levelList[0]?.value
|
|
|
- result = state.levelList[0]?.sysMusicScoreCategoriesList || []
|
|
|
- }
|
|
|
-
|
|
|
- state.typeList = result.map((item: any) => {
|
|
|
- return {
|
|
|
- label: item.name,
|
|
|
- value: item.id
|
|
|
- }
|
|
|
- })
|
|
|
- state.typeList.unshift({
|
|
|
- label: "全部",
|
|
|
- value: -1
|
|
|
- })
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const initCategories_gyt = (type?: "first" | "category" | "level" | "type") => {
|
|
|
- if (storeData.value.length > 0 && !["level", "type"].includes(type as any)) {
|
|
|
- let result: any = []
|
|
|
- if (type === "first" && state.firstTreeId) {
|
|
|
- result = storeData.value.find((item: any) => item.id === state.firstTreeId)?.musicSheetCategoriesList || []
|
|
|
- } else {
|
|
|
- state.firstTreeId = storeData.value[0]?.id
|
|
|
- result = storeData.value[0]?.musicSheetCategoriesList || []
|
|
|
- }
|
|
|
-
|
|
|
- state.levelList = result.map((item: any) => {
|
|
|
- return {
|
|
|
- label: item.name,
|
|
|
- value: item.id,
|
|
|
- musicSheetCategoriesList: item.musicSheetCategoriesList || []
|
|
|
- }
|
|
|
- })
|
|
|
- state.levelId = null
|
|
|
- state.typeId = -1
|
|
|
- }
|
|
|
-
|
|
|
- if (state.levelList.length > 0) {
|
|
|
- let result: any = []
|
|
|
- if (type === "level" && state.levelId) {
|
|
|
- result = state.levelList.find((item: any) => item.value === state.levelId)?.musicSheetCategoriesList
|
|
|
- } else {
|
|
|
- state.levelId = state.levelList[0]?.value
|
|
|
- result = state.levelList[0]?.musicSheetCategoriesList || []
|
|
|
- }
|
|
|
-
|
|
|
- state.typeList = result.map((item: any) => {
|
|
|
- return {
|
|
|
- label: item.name,
|
|
|
- value: item.id
|
|
|
- }
|
|
|
- })
|
|
|
- state.typeList.unshift({
|
|
|
- label: "全部",
|
|
|
- value: -1
|
|
|
- })
|
|
|
- state.typeId = -1
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const initCategories_klx = async (type?: "first" | "category" | "level" | "type") => {
|
|
|
- if (state.categoryList.length > 0 && !["level", "type", "first"].includes(type as any)) {
|
|
|
- let result: any = []
|
|
|
- if (type === "category" && state.categoryId) {
|
|
|
- result = state.categoryList.find((item: any) => item.value === state.categoryId)?.musicSheetCategoriesList || []
|
|
|
- } else {
|
|
|
- state.categoryId = state.categoryList[0]?.value
|
|
|
- state.categoryName = state.categoryList[0]?.label
|
|
|
- result = state.categoryList[0]?.musicSheetCategoriesList || []
|
|
|
- }
|
|
|
- storeData.value = result.map((item: any) => {
|
|
|
- return {
|
|
|
- id: item.value,
|
|
|
- name: item.label
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
-
|
|
|
- if (storeData.value.length > 0 && !["level", "type"].includes(type as any)) {
|
|
|
- if (type === "first" && state.firstTreeId) {
|
|
|
- await handleSelectCondition_klx()
|
|
|
- } else {
|
|
|
- //
|
|
|
- state.firstTreeId = storeData.value[0]?.id
|
|
|
- await handleSelectCondition_klx()
|
|
|
- }
|
|
|
- state.levelId = -1
|
|
|
- state.typeId = -1
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const __init = async () => {
|
|
|
- await handleAllSearchList()
|
|
|
- await handleAllGetSubject()
|
|
|
- await handleAllGetList()
|
|
|
- await handleGetDetail() // 默认获取数据
|
|
|
- await toDetail()
|
|
|
- renderStaff()
|
|
|
- }
|
|
|
-
|
|
|
- // 全屏显示
|
|
|
- handleFullscreen(true, false)
|
|
|
- __init()
|
|
|
-
|
|
|
- const handleResh = () => {
|
|
|
- if (loading.value || state.finshed) return
|
|
|
- state.page = state.page + 1
|
|
|
- handleAllGetList()
|
|
|
- }
|
|
|
-
|
|
|
- const handleGetList = async () => {
|
|
|
- if (loading.value) return
|
|
|
- state.listActive = 0
|
|
|
- state.showPlayer = false
|
|
|
- state.playState = "pause"
|
|
|
- state.partNames = []
|
|
|
- state.partList = []
|
|
|
- state.details = {}
|
|
|
- state.selectedPartName = ""
|
|
|
- state.selectedTrack = ""
|
|
|
- state.selectedPartIndex = 0
|
|
|
- // state.musicPdfUrl = ""
|
|
|
- state.partXmlIndex = 0
|
|
|
- document.querySelector(".musicList-container")?.scroll(0, 0)
|
|
|
- state.page = 1
|
|
|
- state.finshed = false
|
|
|
- state.reshing = true
|
|
|
- state.list = []
|
|
|
- await handleAllGetList()
|
|
|
- }
|
|
|
-
|
|
|
- const toDetailGYM = async () => {
|
|
|
- // const row: any = activeItem.value
|
|
|
- const details: any = state.details
|
|
|
- state.imgs = []
|
|
|
- if (details.musicSheetType === "SINGLE") {
|
|
|
- loading.value = false
|
|
|
- state.musicPdfUrl = details.musicPdfUrl
|
|
|
- return
|
|
|
- }
|
|
|
- // state.partNames = await getPartNames(row.xmlUrl)
|
|
|
- let partList = details.musicSheetSoundList || []
|
|
|
- partList = partList.filter((item: any) => item.audioPlayType === "PLAY")
|
|
|
- partList = partList.filter((item: any) => !item.track?.toLocaleUpperCase()?.includes("COMMON"))
|
|
|
- partColumns.value = partList.map((item: any, index: number) => {
|
|
|
- const instrumentName = getInstrumentName(item.track)
|
|
|
- // const xmlIndex = state.partNames.findIndex((name: any) => name.trim() === item.track)
|
|
|
- return {
|
|
|
- label: item.track + (instrumentName ? `(${instrumentName})` : ""),
|
|
|
- instrumentName: instrumentName,
|
|
|
- track: item.track,
|
|
|
- musicPdfUrl: item.musicPdfUrl,
|
|
|
- // xmlIndex: -1,
|
|
|
- value: index
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- // 初始化数据
|
|
|
- // 是否显示总谱
|
|
|
- if (details.isScoreRender) {
|
|
|
- partColumns.value.unshift({
|
|
|
- label: "总谱",
|
|
|
- instrumentName: null,
|
|
|
- track: null,
|
|
|
- musicPdfUrl: "",
|
|
|
- xmlIndex: 999,
|
|
|
- value: 999
|
|
|
- })
|
|
|
- }
|
|
|
- // gym 现在单独处理 管乐迷根据查询条件来筛选谱面
|
|
|
- let defaultShowStaff
|
|
|
-
|
|
|
- if (details.defaultScoreRender) {
|
|
|
- state.selectedPartIndex = 999
|
|
|
- } else {
|
|
|
- // 这里筛选当前的声轨
|
|
|
- const soundCodes = filterSoundCodes()
|
|
|
- if (soundCodes) {
|
|
|
- const soundCodesArr = soundCodes.split(",").map((code: string) => {
|
|
|
- return code
|
|
|
- .toLowerCase()
|
|
|
- .replace(/^\d+|\d+$/g, "")
|
|
|
- .trim()
|
|
|
- })
|
|
|
- defaultShowStaff = partColumns.value.find((item: any) =>
|
|
|
- soundCodesArr.includes(
|
|
|
- item.track &&
|
|
|
- item.track
|
|
|
- .toLowerCase()
|
|
|
- .replace(/^\d+|\d+$/g, "")
|
|
|
- .trim()
|
|
|
- )
|
|
|
- )
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- defaultShowStaff || (defaultShowStaff = partColumns.value.find((item: any) => item.value === state.selectedPartIndex))
|
|
|
-
|
|
|
- state.selectedPartName = defaultShowStaff?.instrumentName
|
|
|
- state.selectedTrack = defaultShowStaff?.track
|
|
|
- state.partXmlIndex = defaultShowStaff?.xmlIndex
|
|
|
- state.selectedPartIndex = defaultShowStaff?.value
|
|
|
- if (details.isScoreRender && details.defaultScoreRender) {
|
|
|
- state.musicPdfUrl = details?.musicPdfUrl || ""
|
|
|
- } else {
|
|
|
- state.musicPdfUrl = defaultShowStaff?.musicPdfUrl || ""
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const toDetail = async () => {
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- await toDetailGYM()
|
|
|
- return
|
|
|
- }
|
|
|
- const row: any = activeItem.value
|
|
|
- state.imgs = []
|
|
|
- if (row.musicSheetType === "SINGLE") {
|
|
|
- loading.value = false
|
|
|
- state.musicPdfUrl = row.musicPdfUrl
|
|
|
-
|
|
|
- // if (userStoreHook.roles === "GYM") {
|
|
|
- // const imgs = row.musicImg ? row.musicImg.split(",") : []
|
|
|
- // imgs.forEach(async (item: string, index: number) => {
|
|
|
- // const imgCanvas = await imgToCanvas(item)
|
|
|
- // const img = await canvasAddTitle(imgCanvas, row.name)
|
|
|
- // state.imgs.push({
|
|
|
- // name: index + 1 + ".png",
|
|
|
- // url: img
|
|
|
- // })
|
|
|
- // })
|
|
|
- // }
|
|
|
- }
|
|
|
- state.partNames = await getPartNames(row.xmlUrl)
|
|
|
- let partList = row.background || []
|
|
|
- partList = partList.filter((item: any) => !item.track?.toLocaleUpperCase()?.includes("COMMON"))
|
|
|
- partColumns.value = partList.map((item: any, index: number) => {
|
|
|
- const instrumentName = getInstrumentName(item.track)
|
|
|
- const xmlIndex = state.partNames.findIndex((name: any) => name.trim() === item.track)
|
|
|
- let musicPdfUrl = ""
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- musicPdfUrl = item.soundMusicPdfUrl
|
|
|
- } else if (userStoreHook.roles === "GYT") {
|
|
|
- musicPdfUrl = item.musicPdfUrl
|
|
|
- } else if (userStoreHook.roles === "KLX") {
|
|
|
- musicPdfUrl = item.musicPdfUrl
|
|
|
- }
|
|
|
- return {
|
|
|
- label: item.track + (instrumentName ? `(${instrumentName})` : ""),
|
|
|
- instrumentName: instrumentName,
|
|
|
- track: item.track,
|
|
|
- musicPdfUrl,
|
|
|
- xmlIndex,
|
|
|
- value: index
|
|
|
- }
|
|
|
- })
|
|
|
- // 初始化数据
|
|
|
- // 是否显示总谱
|
|
|
- if (row.isScoreRender) {
|
|
|
- partColumns.value.unshift({
|
|
|
- label: "总谱",
|
|
|
- instrumentName: null,
|
|
|
- track: null,
|
|
|
- musicPdfUrl: "",
|
|
|
- xmlIndex: 999,
|
|
|
- value: 999
|
|
|
- })
|
|
|
-
|
|
|
- if (row.defaultScoreRender) {
|
|
|
- state.selectedPartIndex = 999
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const defaultShowStaff = partColumns.value.find((item: any) => item.value === state.selectedPartIndex)
|
|
|
-
|
|
|
- state.selectedPartName = defaultShowStaff?.instrumentName
|
|
|
- state.selectedTrack = defaultShowStaff?.track
|
|
|
- state.partXmlIndex = defaultShowStaff?.xmlIndex
|
|
|
- state.selectedPartIndex = defaultShowStaff?.value
|
|
|
- if (row.isScoreRender && row.defaultScoreRender) {
|
|
|
- state.musicPdfUrl = row?.musicPdfUrl || ""
|
|
|
- } else {
|
|
|
- state.musicPdfUrl = defaultShowStaff?.musicPdfUrl || ""
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const getPartNames = async (xmlUrl: string) => {
|
|
|
- const partNames: string[] = []
|
|
|
- try {
|
|
|
- const res: any = await axios.get(xmlUrl)
|
|
|
- const xml: any = new DOMParser().parseFromString(res.data, "text/xml")
|
|
|
- for (const item of xml.getElementsByTagName("part-name")) {
|
|
|
- if (item.textContent) {
|
|
|
- partNames.push(item.textContent)
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- //
|
|
|
- }
|
|
|
- return partNames.filter((text: string) => text.toLocaleUpperCase() !== "COMMON") || []
|
|
|
- }
|
|
|
-
|
|
|
- const musicIframeLoad = async () => {
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- // 判断是用哪个渲染的
|
|
|
- loading.value = false
|
|
|
- staffLoading.value = false
|
|
|
- return
|
|
|
- }
|
|
|
- const iframeRef: any = document.getElementById("staffIframeRef")
|
|
|
- if (iframeRef && iframeRef.contentWindow?.renderXml) {
|
|
|
- staffLoading.value = true
|
|
|
- const res: any = await axios.get(activeItem.value.xmlUrl)
|
|
|
- const parseXmlInfo = getCustomInfo(res.data)
|
|
|
- const xml = formatXML(parseXmlInfo.parsedXML)
|
|
|
- if (activeItem.value.isScoreRender) {
|
|
|
- const canSelectTracks: any = []
|
|
|
- const background = activeItem.value.background || []
|
|
|
- background.forEach((item: any) => {
|
|
|
- canSelectTracks.push(item.track)
|
|
|
- })
|
|
|
- iframeRef.contentWindow.renderXml(xml, activeItem.value.isScoreRender)
|
|
|
- } else {
|
|
|
- const currentXml = onlyVisible(xml, state.partXmlIndex)
|
|
|
- iframeRef.contentWindow.renderXml(currentXml)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- const resetRender = async () => {
|
|
|
- const iframeRef: any = document.getElementById("staffIframeRef")
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- iframeRef.contentWindow.location.replace(getPreViewCloud(activeItem.value.id, state.partXmlIndex, state.selectedTrack))
|
|
|
- // state.iframeSrc = getPreViewCloud(activeItem.value.id, state.partXmlIndex)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- if (iframeRef && iframeRef.contentWindow?.renderXml) {
|
|
|
- staffLoading.value = true
|
|
|
- const res: any = await axios.get(activeItem.value.xmlUrl)
|
|
|
- const parseXmlInfo = getCustomInfo(res.data)
|
|
|
- const xml = formatXML(parseXmlInfo.parsedXML)
|
|
|
- if (activeItem.value.isScoreRender) {
|
|
|
- iframeRef.contentWindow.renderXml(xml, activeItem.value.isScoreRender)
|
|
|
- } else {
|
|
|
- const currentXml = onlyVisible(xml, state.partXmlIndex)
|
|
|
- iframeRef.contentWindow.renderXml(currentXml)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const renderStaff = async () => {
|
|
|
- try {
|
|
|
- if (state.musicPdfUrl) {
|
|
|
- state.iframeSrc = "/pdf/web/viewer.html?file=" + encodeURIComponent(state.musicPdfUrl) + "&t=" + Date.now()
|
|
|
- // https://cdn.oss.dayaedu.com/daya202409/UOFW4q5.pdf
|
|
|
- // https://cdn.oss.dayaedu.com/daya202409/UOFVK2A.pdf
|
|
|
- // https://cdn.oss.dayaedu.com/daya202409/UODQffO.pdf
|
|
|
- } else {
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- console.log(state.partXmlIndex, state.selectedTrack, "----------")
|
|
|
- state.iframeSrc = getPreViewCloud(activeItem.value.id, state.partXmlIndex, state.selectedTrack)
|
|
|
- } else {
|
|
|
- state.iframeSrc = `/osmd/index.html`
|
|
|
- }
|
|
|
- }
|
|
|
- } catch (error) {
|
|
|
- //
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /** 音频控制 */
|
|
|
- const handleChangeAudio = (type: "play" | "pause" | "pre" | "next") => {
|
|
|
- if (type === "play") {
|
|
|
- state.playState = "play"
|
|
|
- } else if (type === "pause") {
|
|
|
- state.playState = "pause"
|
|
|
- } else if (type === "pre") {
|
|
|
- if (state.list[state.listActive - 1]) {
|
|
|
- handlePlay(state.list[state.listActive - 1])
|
|
|
- }
|
|
|
- } else if (type === "next") {
|
|
|
- if (state.list[state.listActive + 1]) {
|
|
|
- handlePlay(state.list[state.listActive + 1])
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /** 播放曲目 */
|
|
|
- const handlePlay = (item: any) => {
|
|
|
- const index = state.list.findIndex((_item: any) => _item.id === item.id)
|
|
|
- if (index > -1) {
|
|
|
- if (state.listActive === index) {
|
|
|
- state.playState = state.playState === "play" ? "pause" : "play"
|
|
|
- } else {
|
|
|
- state.playState = "play"
|
|
|
- }
|
|
|
- state.showPlayer = true
|
|
|
- state.listActive = index
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // // 多个文件下载
|
|
|
- const downLoadMultiFile = (files: any, filesName: string) => {
|
|
|
- const zip = new JSZip()
|
|
|
- for (const i in files) {
|
|
|
- zip.file(files[i].name, files[i].url, { binary: true })
|
|
|
- }
|
|
|
- zip.generateAsync({ type: "blob" }).then(res => {
|
|
|
- saveAs(res, filesName ? filesName + ".zip" : `文件夹${Date.now()}.zip`)
|
|
|
- })
|
|
|
- downloadStatus.value = false
|
|
|
- }
|
|
|
-
|
|
|
- const showLoading = async (e: any) => {
|
|
|
- if (e.data?.api === "musicStaffRender") {
|
|
|
- const musicName =
|
|
|
- activeItem.value.name +
|
|
|
- (((activeItem.value.musicSheetType === "CONCERT" || state.details.musicSheetType === "CONCERT") && state.selectedPartName) ||
|
|
|
- state.selectedTrack
|
|
|
- ? `(${state.selectedPartName || state.selectedTrack})`
|
|
|
- : "")
|
|
|
- try {
|
|
|
- const osmdImg = e.data.osmdImg
|
|
|
- const imgs = []
|
|
|
- for (let i = 0; i < osmdImg.length; i++) {
|
|
|
- const img = await svgtoblob(osmdImg[i].img, osmdImg[i].width, osmdImg[i].height, musicName)
|
|
|
- imgs.push({
|
|
|
- url: img,
|
|
|
- name: i + 1 + ".png"
|
|
|
- })
|
|
|
- }
|
|
|
- state.imgs = imgs
|
|
|
- } catch (e) {
|
|
|
- // console.log(e);
|
|
|
- }
|
|
|
- staffLoading.value = e.data.loading
|
|
|
- loading.value = e.data.loading
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- const searchContent = async () => {
|
|
|
- await toDetail()
|
|
|
- if (activeItem.value?.id) {
|
|
|
- if (state.musicPdfUrl) {
|
|
|
- staffLoading.value = true
|
|
|
- renderStaff()
|
|
|
- } else {
|
|
|
- // 为了处理,之前是使用pdf渲染,现在又用osmd,iframe没有重新加载
|
|
|
- if (state.iframeSrc.indexOf("pdf/web") !== -1) {
|
|
|
- renderStaff()
|
|
|
- } else {
|
|
|
- resetRender()
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /** 下载图片 */
|
|
|
- const onDownload = () => {
|
|
|
- if (downloadStatus.value || staffLoading.value) return
|
|
|
- const musicName =
|
|
|
- activeItem.value.name +
|
|
|
- ((activeItem.value.musicSheetType === "CONCERT" && state.selectedPartName) || state.selectedTrack
|
|
|
- ? `(${state.selectedPartName || state.selectedTrack})`
|
|
|
- : "")
|
|
|
- downloadStatus.value = true
|
|
|
- if (state.musicPdfUrl) {
|
|
|
- // 发起Fetch请求
|
|
|
- fetch(state.musicPdfUrl)
|
|
|
- .then(response => response.blob())
|
|
|
- .then(blob => {
|
|
|
- saveAs(blob, musicName)
|
|
|
- downloadStatus.value = false
|
|
|
- })
|
|
|
- .catch(() => {
|
|
|
- ElMessage.error("下载失败")
|
|
|
- downloadStatus.value = false
|
|
|
- })
|
|
|
- } else {
|
|
|
- downLoadMultiFile(state.imgs, musicName)
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // 根据当前选中的声部和曲目筛选出对应的声轨
|
|
|
- function filterSoundCodes() {
|
|
|
- // const { id } = state.list[state.listActive] || {}
|
|
|
- // if (!id) {
|
|
|
- // return undefined
|
|
|
- // }
|
|
|
- const { instrumentIds } =
|
|
|
- state.subjectList.find((item: any) => {
|
|
|
- return item.value === state.subjectId
|
|
|
- }) || {}
|
|
|
- if (instrumentIds) {
|
|
|
- // GYM,GYT,KLX 区分 查询声部数据
|
|
|
- let cbsDetails: any = []
|
|
|
- if (userStoreHook.roles === "GYM") {
|
|
|
- cbsDetails = state.details.musicalInstruments || []
|
|
|
- } else if (userStoreHook.roles === "GYT") {
|
|
|
- //
|
|
|
- } else if (userStoreHook.roles === "KLX") {
|
|
|
- //
|
|
|
- }
|
|
|
- const { code } =
|
|
|
- cbsDetails.find((item: any) => {
|
|
|
- return instrumentIds == item.id
|
|
|
- }) || {}
|
|
|
- return code
|
|
|
- }
|
|
|
- return undefined
|
|
|
- }
|
|
|
-
|
|
|
- // 白板的批注打开时暂停播放
|
|
|
- watch(
|
|
|
- () => [whitePenShow.value, penShow.value],
|
|
|
- () => {
|
|
|
- if (whitePenShow.value || penShow.value) {
|
|
|
- handleChangeAudio("pause")
|
|
|
- }
|
|
|
- }
|
|
|
- )
|
|
|
-
|
|
|
- onMounted(() => {
|
|
|
- const obv = new IntersectionObserver(entries => {
|
|
|
- if (entries[0].intersectionRatio > 0) {
|
|
|
- handleResh()
|
|
|
- }
|
|
|
- })
|
|
|
- obv.observe(spinRef.value)
|
|
|
-
|
|
|
- window.addEventListener("message", showLoading)
|
|
|
- })
|
|
|
- return () => (
|
|
|
- <NavContainer navs={navs}>
|
|
|
- {/* <ElScrollbar class="elScrollbar"> */}
|
|
|
- <div class={styles.cloudPractice}>
|
|
|
- <div class={styles.leftContainer}>
|
|
|
- <div class={styles.details}>
|
|
|
- {storeData.value.length > 0 && (
|
|
|
- <ElScrollbar class={styles.leftSection}>
|
|
|
- {/* 基 础 云 练 */}
|
|
|
- {storeData.value.map((item: any) => (
|
|
|
- <div
|
|
|
- class={[styles.leftSection_item, item.id === state.firstTreeId && styles.leftSection_item__active]}
|
|
|
- onClick={async () => {
|
|
|
- if (loading.value) return
|
|
|
- state.firstTreeId = item.id
|
|
|
- await setDefaultData("first")
|
|
|
- await handleGetList()
|
|
|
- await handleGetDetail()
|
|
|
- searchContent()
|
|
|
- }}
|
|
|
- >
|
|
|
- {item.name}
|
|
|
- </div>
|
|
|
- ))}
|
|
|
- </ElScrollbar>
|
|
|
- )}
|
|
|
-
|
|
|
- <div class={[styles.musicList, "musicList-container"]}>
|
|
|
- <div class={styles.searchHeader}>
|
|
|
- {state.categoryList.length > 1 && (
|
|
|
- <div class={[styles.categorySection]}>
|
|
|
- <NPopselect
|
|
|
- placement="bottom-start"
|
|
|
- disabled={loading.value}
|
|
|
- options={state.categoryList}
|
|
|
- v-model:value={state.categoryId}
|
|
|
- onUpdate:value={async (val: any) => {
|
|
|
- const item = state.categoryList.find((item: any) => item.value === val)
|
|
|
- if (item) {
|
|
|
- state.categoryName = item.label
|
|
|
- state.categoryId = item.value
|
|
|
- await setDefaultData("category")
|
|
|
- await handleGetList()
|
|
|
- await handleGetDetail()
|
|
|
- searchContent()
|
|
|
- }
|
|
|
- }}
|
|
|
- onUpdate:show={(value: any) => {
|
|
|
- state.categoryShow = value
|
|
|
- }}
|
|
|
- trigger="click"
|
|
|
- class={"PopSelect"}
|
|
|
- >
|
|
|
- <span class={[styles.iconTagName, state.categoryShow && styles.show]}>
|
|
|
- <span>{state.categoryName}</span>
|
|
|
- </span>
|
|
|
- </NPopselect>
|
|
|
- </div>
|
|
|
- )}
|
|
|
-
|
|
|
- <div class={styles.searchMore}>
|
|
|
- <div class={styles.searchSection}>
|
|
|
- <Dictionary
|
|
|
- clearable={false}
|
|
|
- popperClass="classTypePopper"
|
|
|
- v-model={state.subjectId}
|
|
|
- height={42}
|
|
|
- // disabled={loading.value}
|
|
|
- options={state.subjectList}
|
|
|
- placeholder="全部声部"
|
|
|
- onChange={async () => {
|
|
|
- await handleGetList()
|
|
|
- await handleGetDetail()
|
|
|
- searchContent()
|
|
|
- }}
|
|
|
- />
|
|
|
- {state.levelList.length ? (
|
|
|
- <Dictionary
|
|
|
- clearable={false}
|
|
|
- popperClass="classTypePopper"
|
|
|
- v-model={state.levelId}
|
|
|
- height={42}
|
|
|
- // disabled={loading.value}
|
|
|
- options={state.levelList}
|
|
|
- placeholder="级别"
|
|
|
- onChange={async () => {
|
|
|
- setDefaultData("level")
|
|
|
- await handleGetList()
|
|
|
- await handleGetDetail()
|
|
|
- searchContent()
|
|
|
- }}
|
|
|
- />
|
|
|
- ) : null}
|
|
|
- {state.typeList.length > 0 ? (
|
|
|
- <Dictionary
|
|
|
- clearable={false}
|
|
|
- popperClass="classTypePopper"
|
|
|
- v-model={state.typeId}
|
|
|
- height={42}
|
|
|
- // disabled={loading.value}
|
|
|
- options={state.typeList}
|
|
|
- propsOpt={{
|
|
|
- labelField: "name",
|
|
|
- valueField: "id"
|
|
|
- }}
|
|
|
- placeholder="分类"
|
|
|
- onChange={async () => {
|
|
|
- await handleGetList()
|
|
|
- await handleGetDetail()
|
|
|
- searchContent()
|
|
|
- }}
|
|
|
- />
|
|
|
- ) : null}
|
|
|
- </div>
|
|
|
- <div
|
|
|
- class={[styles.btnSearch, state.searchStatus && styles.btnSearchActive]}
|
|
|
- onClick={() => (state.searchStatus = !state.searchStatus)}
|
|
|
- ></div>
|
|
|
- </div>
|
|
|
- {state.searchStatus && (
|
|
|
- <MyInput
|
|
|
- class="queryCp"
|
|
|
- v-model={state.queryStr}
|
|
|
- height={42}
|
|
|
- placeholder="请输入曲目关键词"
|
|
|
- onKeyup={async (e: any) => {
|
|
|
- if (e.code === "Enter" || e.key === "Enter") {
|
|
|
- await handleGetList()
|
|
|
- await handleGetDetail()
|
|
|
- searchContent()
|
|
|
- }
|
|
|
- }}
|
|
|
- onHandleQuery={async () => {
|
|
|
- await handleGetList()
|
|
|
- await handleGetDetail()
|
|
|
- searchContent()
|
|
|
- }}
|
|
|
- clearable
|
|
|
- />
|
|
|
- )}
|
|
|
- </div>
|
|
|
-
|
|
|
- <div class={[styles.wrapList, !state.list.length && !loading.value && styles.wrapListEmpty]}>
|
|
|
- {state.list.map((item: any, index: number) => (
|
|
|
- <div
|
|
|
- class={[styles.item, index === state.listActive && styles.active]}
|
|
|
- onClick={async () => {
|
|
|
- if (index === state.listActive) {
|
|
|
- return
|
|
|
- }
|
|
|
- state.listActive = index
|
|
|
- state.selectedPartIndex = 0
|
|
|
- state.partXmlIndex = 0
|
|
|
- await handleGetDetail()
|
|
|
- searchContent()
|
|
|
- }}
|
|
|
- >
|
|
|
- <div class={styles.itemInfo}>
|
|
|
- <div class={styles.img}>
|
|
|
- <NImage
|
|
|
- lazy
|
|
|
- objectFit="cover"
|
|
|
- previewDisabled={true}
|
|
|
- src={item.titleImg || icon_default}
|
|
|
- onLoad={(e: any) => {
|
|
|
- ;(e.target as any).dataset.loaded = "true"
|
|
|
- }}
|
|
|
- />
|
|
|
- <PlayLoading
|
|
|
- class={[state.listActive === index && state.playState === "play" ? "" : styles.showPlayLoading]}
|
|
|
- />
|
|
|
- </div>
|
|
|
- <div class={styles.title}>
|
|
|
- <div class={styles.titleName}>
|
|
|
- <ellipsisScroll title={item.name} />
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class={styles.btnSection}>
|
|
|
- <div
|
|
|
- class={styles.btn}
|
|
|
- onClick={(e: any) => {
|
|
|
- e.stopPropagation()
|
|
|
- handlePlay(item)
|
|
|
- if (state.listActive !== index) {
|
|
|
- resetRender()
|
|
|
- }
|
|
|
- }}
|
|
|
- >
|
|
|
- {state.listActive === index && (
|
|
|
- <>
|
|
|
- {state.playState === "pause" ? "播放" : "暂停"}
|
|
|
- <img src={state.playState === "pause" ? iconBtnPlay : (iconBtnPause as any)} />
|
|
|
- </>
|
|
|
- )}
|
|
|
- {state.listActive !== index && (
|
|
|
- <>
|
|
|
- 播放
|
|
|
- <img src={iconBtnPlay as any} />
|
|
|
- </>
|
|
|
- )}
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- ))}
|
|
|
-
|
|
|
- {!state.list.length && !loading.value && (
|
|
|
- <ElEmpty class={styles.empty} image={require("@/img/layout/empty.png")} description="暂无内容" />
|
|
|
- )}
|
|
|
-
|
|
|
- <div ref={spinRef} class={[styles.loadingWrap, state.finshed && styles.showLoading]}>
|
|
|
- <NSpin show={true} stroke="#FF531C"></NSpin>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- <div class={styles.rightContainer}>
|
|
|
- {/* <i class={styles.leftArrow}></i> */}
|
|
|
-
|
|
|
- <NSpin show={staffLoading.value} stroke="#FF531C">
|
|
|
- {activeItem.value?.id ? (
|
|
|
- state.musicPdfUrl ? (
|
|
|
- <div class={[styles.staffImgs]}>
|
|
|
- <iframe
|
|
|
- style={{
|
|
|
- // opacity: loading.value ? 0 : 1,
|
|
|
- width: "100%",
|
|
|
- height: "100%"
|
|
|
- }}
|
|
|
- src={state.iframeSrc}
|
|
|
- onLoad={() => {
|
|
|
- // 判断是用哪个渲染的
|
|
|
- loading.value = false
|
|
|
- staffLoading.value = false
|
|
|
- }}
|
|
|
- ></iframe>
|
|
|
- </div>
|
|
|
- ) : (
|
|
|
- <>
|
|
|
- <div class={styles.musicName}>
|
|
|
- {activeItem.value.name}
|
|
|
- {activeItem.value.musicSheetType === "CONCERT" &&
|
|
|
- (state.selectedPartName || state.selectedTrack ? `(${state.selectedPartName || state.selectedTrack})` : "")}
|
|
|
- </div>
|
|
|
- <div class={[styles.staffImgs]}>
|
|
|
- <iframe
|
|
|
- id="staffIframeRef"
|
|
|
- style={{
|
|
|
- // opacity: loading.value ? 0 : 1,
|
|
|
- width: "100%",
|
|
|
- height: "100%"
|
|
|
- }}
|
|
|
- src={state.iframeSrc}
|
|
|
- onLoad={musicIframeLoad}
|
|
|
- ></iframe>
|
|
|
- </div>
|
|
|
- </>
|
|
|
- )
|
|
|
- ) : (
|
|
|
- <div class={[styles.staffImgs, !loading.value && !activeItem.value?.id && styles.staffImgsEmpty]}>
|
|
|
- {!loading.value && !activeItem.value?.id && (
|
|
|
- <ElEmpty class={styles.empty} image={require("@/img/layout/empty.png")} description="暂无内容" />
|
|
|
- )}
|
|
|
- </div>
|
|
|
- )}
|
|
|
- </NSpin>
|
|
|
-
|
|
|
- <img
|
|
|
- style={{
|
|
|
- display: activeItem.value?.id ? "" : "none"
|
|
|
- }}
|
|
|
- class={[styles.goBtn]}
|
|
|
- src={btnSubmit as any}
|
|
|
- onClick={() => {
|
|
|
- handleChangeAudio("pause")
|
|
|
- goToCloud(activeItem.value.id, state.partXmlIndex)
|
|
|
- }}
|
|
|
- />
|
|
|
-
|
|
|
- <div class={styles.rightBtns} style={{ display: activeItem.value.id ? "" : "none" }}>
|
|
|
- <div style={{ display: state.musicPdfUrl || state.imgs.length > 0 ? "" : "none" }}>
|
|
|
- <NTooltip showArrow={false}>
|
|
|
- {{
|
|
|
- trigger: () => (
|
|
|
- <img
|
|
|
- onClick={onDownload}
|
|
|
- class={[styles.transBtn, (downloadStatus.value || staffLoading.value) && styles.disableBtn]}
|
|
|
- src={iconDownload as any}
|
|
|
- />
|
|
|
- ),
|
|
|
- default: "下载曲谱"
|
|
|
- }}
|
|
|
- </NTooltip>
|
|
|
- </div>
|
|
|
- <div
|
|
|
- style={{ display: activeItem.value.musicSheetType === "CONCERT" || state.details.musicSheetType === "CONCERT" ? "" : "none" }}
|
|
|
- >
|
|
|
- <NPopselect
|
|
|
- options={partColumns.value}
|
|
|
- placement="bottom-end"
|
|
|
- trigger="click"
|
|
|
- v-model:value={state.selectedPartIndex}
|
|
|
- scrollable
|
|
|
- onUpdate:value={async (value: any) => {
|
|
|
- const item = partColumns.value.find((item: any) => item.value === value)
|
|
|
- state.selectedPartIndex = value
|
|
|
- state.selectedPartName = item.instrumentName
|
|
|
- state.selectedTrack = item.track
|
|
|
- state.partXmlIndex = item.xmlIndex
|
|
|
- state.imgs = []
|
|
|
- nextTick(() => {
|
|
|
- let tempPdf = ""
|
|
|
- if (activeItem.value?.isScoreRender && value === 999) {
|
|
|
- if (activeItem.value?.musicPdfUrl) {
|
|
|
- tempPdf = activeItem.value?.musicPdfUrl
|
|
|
- }
|
|
|
- } else {
|
|
|
- tempPdf = item.musicPdfUrl
|
|
|
- }
|
|
|
- if (tempPdf) {
|
|
|
- state.musicPdfUrl = tempPdf
|
|
|
- staffLoading.value = true
|
|
|
- renderStaff()
|
|
|
- } else {
|
|
|
- state.musicPdfUrl = ""
|
|
|
- loading.value = true
|
|
|
- // 为了处理,之前是使用pdf渲染,现在又用osmd,iframe没有重新加载
|
|
|
- if (state.iframeSrc.indexOf("pdf/web") !== -1) {
|
|
|
- renderStaff()
|
|
|
- } else {
|
|
|
- resetRender()
|
|
|
- }
|
|
|
- }
|
|
|
- })
|
|
|
- }}
|
|
|
- class={["PopSelect", "PopSelectPart"]}
|
|
|
- >
|
|
|
- {{
|
|
|
- empty: () => "暂无数据",
|
|
|
- default: () => (
|
|
|
- <NTooltip showArrow={false}>
|
|
|
- {{
|
|
|
- trigger: () => <img class={styles.transBtn} src={iconTransfer as any} />,
|
|
|
- default: "切换声轨"
|
|
|
- }}
|
|
|
- </NTooltip>
|
|
|
- )
|
|
|
- }}
|
|
|
- </NPopselect>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- </div>
|
|
|
- {/* </ElScrollbar> */}
|
|
|
-
|
|
|
- {state.list.length !== 0 && activeItem.value.audioFileUrl && (
|
|
|
- <PlayItem
|
|
|
- show={state.showPlayer}
|
|
|
- playState={state.playState}
|
|
|
- songPrevNextStatus={songPrevNextStatus.value}
|
|
|
- item={activeItem.value}
|
|
|
- onChange={value => handleChangeAudio(value)}
|
|
|
- onShow={(status: boolean) => {
|
|
|
- state.showPlayer = status
|
|
|
- }}
|
|
|
- />
|
|
|
- )}
|
|
|
- <PracticeForm v-model={isPracticeShow.value} practiceUrl={practiceUrl.value} onClose={handlePracticeClose} />
|
|
|
- </NavContainer>
|
|
|
- )
|
|
|
- }
|
|
|
-})
|
|
|
+import { computed, defineComponent, nextTick, onMounted, reactive, ref, shallowRef, watch } from "vue"
|
|
|
+import styles from "./index.module.scss"
|
|
|
+import NavContainer from "@/businessComponents/navContainer"
|
|
|
+import { ElEmpty, ElMessage, ElScrollbar } from "element-plus"
|
|
|
+import Dictionary from "@/components/dictionary"
|
|
|
+import MyInput from "@/components/myInput"
|
|
|
+import { NImage, NPopselect, NSpin, NTooltip } from "naive-ui"
|
|
|
+import PlayItem from "./component/play-item"
|
|
|
+import icon_default from "../../img/cloudPractice/icon_default.png"
|
|
|
+import iconBtnPause from "../../img/cloudPractice/icon-btn-pause.png"
|
|
|
+import iconBtnPlay from "../../img/cloudPractice/icon-btn-play.png"
|
|
|
+import btnSubmit from "../../img/cloudPractice/btn-submit.png"
|
|
|
+import iconTransfer from "../../img/cloudPractice/icon-transfer.png"
|
|
|
+import iconDownload from "../../img/cloudPractice/icon-download.png"
|
|
|
+import { httpAjaxErrMsg } from "@/plugin/httpAjax"
|
|
|
+import {
|
|
|
+ queryPage2_gym,
|
|
|
+ queryPage2_gyt,
|
|
|
+ queryPage2_klx,
|
|
|
+ querySubjectIds_gym,
|
|
|
+ querySubjectIds_gyt,
|
|
|
+ querySubjectIds_klx,
|
|
|
+ queryTree_gym,
|
|
|
+ queryTree_gyt,
|
|
|
+ queryTree_klx,
|
|
|
+ selectCondition_klx,
|
|
|
+ cbsDetail_gym,
|
|
|
+ cbsDetail_klx
|
|
|
+} from "@/api/cloudPractice.api"
|
|
|
+import axios from "axios"
|
|
|
+import { getInstrumentName } from "@/libs/instruments"
|
|
|
+import { formatXML, getCustomInfo, onlyVisible } from "./instrument"
|
|
|
+import { useFunction } from "./useData"
|
|
|
+import userStore from "@/store/modules/user"
|
|
|
+import PlayLoading from "./component/play-loading"
|
|
|
+import PracticeForm from "@/businessComponents/practiceForm"
|
|
|
+import { saveAs } from "file-saver"
|
|
|
+import JSZip from "jszip"
|
|
|
+import { svgtoblob } from "./formatSvgToImg"
|
|
|
+import { penShow, whitePenShow } from "@/businessComponents/globalTools/globalTools"
|
|
|
+import { handleFullscreen } from "@/libs/fullscreen"
|
|
|
+
|
|
|
+export default defineComponent({
|
|
|
+ name: "cloudPractice",
|
|
|
+ setup() {
|
|
|
+ const userStoreHook = userStore()
|
|
|
+ const { goToCloud, getPreViewCloud, isPracticeShow, practiceUrl, handlePracticeClose, instrumentCodes, getInstrumentCodes } = useFunction()
|
|
|
+ const navs = [
|
|
|
+ {
|
|
|
+ name: "主页",
|
|
|
+ url: "/"
|
|
|
+ },
|
|
|
+ {
|
|
|
+ name: "云练习"
|
|
|
+ }
|
|
|
+ ]
|
|
|
+ const spinRef = ref()
|
|
|
+ const state = reactive({
|
|
|
+ finshed: false,
|
|
|
+ reshing: false,
|
|
|
+ page: 1,
|
|
|
+ rows: 20,
|
|
|
+ details: {} as any,
|
|
|
+ iframeSrc: "",
|
|
|
+ listActive: 0, // 当前选中的对象
|
|
|
+ firstTreeId: null as any, // 左侧
|
|
|
+ categoryId: null as any, // 类型
|
|
|
+ categoryName: "" as any, // 类型名称
|
|
|
+ categoryList: [] as any[],
|
|
|
+ levelList: [] as any[], // 级别
|
|
|
+ levelId: null as any,
|
|
|
+ typeList: [] as any[], // 类型
|
|
|
+ typeId: -1 as any,
|
|
|
+ subjectList: [] as any[], // 声部列表
|
|
|
+ subjectId: -1 as any,
|
|
|
+ list: [] as any[],
|
|
|
+ searchStatus: false,
|
|
|
+ queryStr: "", // 搜索条件
|
|
|
+ partList: [] as any[],
|
|
|
+ partNames: [] as any[],
|
|
|
+ selectedPartName: "" as any,
|
|
|
+ selectedTrack: "" as any,
|
|
|
+ selectedPartIndex: 0,
|
|
|
+ partXmlIndex: 0,
|
|
|
+ musicPdfUrl: "", // 五线谱文件
|
|
|
+ imgs: [] as any[], // 图片列表
|
|
|
+ categoryShow: false, // 是否展开
|
|
|
+ playState: "pause" as "play" | "pause", // 播放状态
|
|
|
+ showPlayer: false // 是否显示播放器
|
|
|
+ })
|
|
|
+ const partColumns = ref<any>([])
|
|
|
+
|
|
|
+ const musicRenderType = computed(() => {
|
|
|
+ const details = state.details
|
|
|
+ const template: any = {
|
|
|
+ STAVE: "staff",
|
|
|
+ JIAN: "fixedTone",
|
|
|
+ FIRST: "firstTone"
|
|
|
+ }
|
|
|
+ if (details.scoreType) {
|
|
|
+ return template[details.scoreType] || "staff"
|
|
|
+ }
|
|
|
+ return "staff"
|
|
|
+ })
|
|
|
+
|
|
|
+ /** 选中的item */
|
|
|
+ const activeItem = computed(() => {
|
|
|
+ const list = state.list[state.listActive] || {}
|
|
|
+ let tempList: any = {}
|
|
|
+
|
|
|
+ if (userStoreHook.roles === "GYM") {
|
|
|
+ // const item = list.background?.[0]
|
|
|
+ // const audioFileUrl = item?.musicSheetType === "CONCERT" ? item?.metronomeUrl : item?.metronomeMp3Url || item?.mp3Url
|
|
|
+ tempList = {
|
|
|
+ id: list?.id,
|
|
|
+ name: list?.name,
|
|
|
+ // background: list?.background,
|
|
|
+ // xmlUrl: item?.xmlUrl,
|
|
|
+ // musicSheetType: item?.musicSheetType,
|
|
|
+ audioFileUrl: list.audioFileUrl,
|
|
|
+ titleImg: list?.titleImg
|
|
|
+ // musicImg: list.titleImg
|
|
|
+ // musicJianImg: list.musicJianSvg,
|
|
|
+ // musicFirstImg: list.musicFirstSvg,
|
|
|
+ // isScoreRender: item?.isScoreRender,
|
|
|
+ // defaultScoreRender: item?.defaultScoreRender,
|
|
|
+ // musicPdfUrl: item?.musicPdfUrl // 独奏使用PDF
|
|
|
+ }
|
|
|
+ } else if (userStoreHook.roles === "GYT") {
|
|
|
+ tempList = {
|
|
|
+ id: list?.id,
|
|
|
+ name: list?.musicSheetName,
|
|
|
+ background: list?.background,
|
|
|
+ xmlUrl: list?.xmlFileUrl,
|
|
|
+ musicSheetType: list?.musicSheetType,
|
|
|
+ audioFileUrl: list?.audioFileUrl,
|
|
|
+ titleImg: list?.titleImg,
|
|
|
+ musicImg: list.musicImg,
|
|
|
+ musicJianImg: list.musicJianSvg,
|
|
|
+ musicFirstImg: list.musicFirstSvg,
|
|
|
+ isScoreRender: list?.isScoreRender,
|
|
|
+ defaultScoreRender: list?.defaultScoreRender,
|
|
|
+ musicPdfUrl: list?.musicPdfUrl
|
|
|
+ }
|
|
|
+ // console.log(tempList, "tempList --- tempList")
|
|
|
+ } else if (userStoreHook.roles === "KLX") {
|
|
|
+ // const item: any = list.background?.[0]
|
|
|
+ tempList = {
|
|
|
+ id: list?.id,
|
|
|
+ name: list?.name,
|
|
|
+ // background: list?.background,
|
|
|
+ // xmlUrl: list?.xmlFileUrl,
|
|
|
+ // musicSheetType: list?.musicSheetType,
|
|
|
+ audioFileUrl: list?.audioFileUrl,
|
|
|
+ titleImg: list?.titleImg
|
|
|
+ // musicImg: list.musicImg,
|
|
|
+ // musicJianImg: list.musicJianSvg,
|
|
|
+ // musicFirstImg: list.musicFirstSvg,
|
|
|
+ // isScoreRender: false,
|
|
|
+ // defaultScoreRender: false,
|
|
|
+ // musicPdfUrl: list?.musicPdfUrl
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return tempList
|
|
|
+ })
|
|
|
+
|
|
|
+ const songPrevNextStatus = computed(() => {
|
|
|
+ let prev = true,
|
|
|
+ next = true
|
|
|
+ if (state.listActive === 0) {
|
|
|
+ prev = false
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state.listActive >= state.list.length - 1) {
|
|
|
+ next = false
|
|
|
+ }
|
|
|
+
|
|
|
+ return {
|
|
|
+ prev,
|
|
|
+ next
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ const downloadStatus = ref(false)
|
|
|
+ const loading = ref(false)
|
|
|
+ const staffLoading = ref(false)
|
|
|
+ const storeData = shallowRef<any[]>([])
|
|
|
+ const handleSearchList_gym = async () => {
|
|
|
+ loading.value = true
|
|
|
+ await httpAjaxErrMsg(queryTree_gym).then(async res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ storeData.value = res.data || []
|
|
|
+
|
|
|
+ await setDefaultData()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleGetSubject_gym = async () => {
|
|
|
+ loading.value = true
|
|
|
+ await httpAjaxErrMsg(querySubjectIds_gym, { categoriesId: state.categoryId || state.firstTreeId }).then(res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ const result = res.data || []
|
|
|
+
|
|
|
+ state.subjectList = result.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.name,
|
|
|
+ value: item.id,
|
|
|
+ instrumentIds: item.instrumentIds
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ state.subjectList.unshift({
|
|
|
+ label: "全部声部",
|
|
|
+ value: -1
|
|
|
+ })
|
|
|
+
|
|
|
+ const userSubjectId = userStoreHook.userInfo.subjectId
|
|
|
+ if (userSubjectId) {
|
|
|
+ const tempSubjectId = userSubjectId.split(",")[0]
|
|
|
+ state.subjectList.forEach((item: any) => {
|
|
|
+ // 判断是否存在声部编号
|
|
|
+ if (item.value === Number(tempSubjectId)) {
|
|
|
+ state.subjectId = Number(tempSubjectId)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleGetList_gym = async () => {
|
|
|
+ loading.value = true
|
|
|
+ const params = {
|
|
|
+ page: state.page,
|
|
|
+ rows: state.rows,
|
|
|
+ subjectId: state.subjectId === -1 ? null : state.subjectId,
|
|
|
+ categoriesId: state.typeId === -1 ? state.levelId : state.typeId,
|
|
|
+ search: state.queryStr
|
|
|
+ }
|
|
|
+
|
|
|
+ await httpAjaxErrMsg(queryPage2_gym, params).then(res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ const result = res.data || []
|
|
|
+
|
|
|
+ if (state.reshing) {
|
|
|
+ state.list = []
|
|
|
+ state.reshing = false
|
|
|
+ }
|
|
|
+ if (Array.isArray(result.rows)) {
|
|
|
+ state.list = [...state.list, ...result.rows]
|
|
|
+ state.finshed = state.page >= result.totalPage
|
|
|
+ } else {
|
|
|
+ state.finshed = true
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ state.finshed = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleGetDetail_gym = async () => {
|
|
|
+ loading.value = true
|
|
|
+ const { id } = state.list[state.listActive] || {}
|
|
|
+ if (!id) return (loading.value = false)
|
|
|
+ await httpAjaxErrMsg(cbsDetail_gym, id, { simpleFlag: "1" }).then(res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ const result = res.data || {}
|
|
|
+ state.details = result
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 管乐团数据查询 */
|
|
|
+ const handleSearchList_gyt = async () => {
|
|
|
+ loading.value = true
|
|
|
+ await httpAjaxErrMsg(queryTree_gyt, {
|
|
|
+ enable: true,
|
|
|
+ page: 1,
|
|
|
+ parentId: 0,
|
|
|
+ rows: 10
|
|
|
+ }).then(res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ storeData.value = res.data || []
|
|
|
+
|
|
|
+ setDefaultData()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleGetSubject_gyt = async () => {
|
|
|
+ loading.value = true
|
|
|
+ await httpAjaxErrMsg(querySubjectIds_gyt, {
|
|
|
+ enableFlag: true,
|
|
|
+ page: 1,
|
|
|
+ rows: 100
|
|
|
+ }).then(res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ const result = res.data || []
|
|
|
+
|
|
|
+ state.subjectList = result.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.name,
|
|
|
+ value: item.id,
|
|
|
+ instrumentIds: item.instrumentIds
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ state.subjectList.unshift({
|
|
|
+ label: "全部声部",
|
|
|
+ value: -1
|
|
|
+ })
|
|
|
+
|
|
|
+ const userSubjectId = userStoreHook.userInfo.subjectId
|
|
|
+ if (userSubjectId) {
|
|
|
+ const tempSubjectId = userSubjectId.split(",")[0]
|
|
|
+ state.subjectList.forEach((item: any) => {
|
|
|
+ // 判断是否存在声部编号
|
|
|
+ if (item.value === Number(tempSubjectId)) {
|
|
|
+ state.subjectId = Number(tempSubjectId)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleGetList_gyt = async () => {
|
|
|
+ loading.value = true
|
|
|
+ const params = {
|
|
|
+ page: state.page,
|
|
|
+ rows: state.rows,
|
|
|
+ musicSubject: state.subjectId === -1 ? null : state.subjectId,
|
|
|
+ musicSheetCategoriesId: state.typeId === -1 ? state.levelId : state.typeId,
|
|
|
+ keyword: state.queryStr,
|
|
|
+ detailFlag: true,
|
|
|
+ status: 1
|
|
|
+ }
|
|
|
+ await httpAjaxErrMsg(queryPage2_gyt, params).then(res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ const result = res.data || {}
|
|
|
+
|
|
|
+ if (state.reshing) {
|
|
|
+ state.list = []
|
|
|
+ state.reshing = false
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Array.isArray(result.rows)) {
|
|
|
+ result.rows.forEach((item: any) => {
|
|
|
+ item.name = item.musicSheetName
|
|
|
+ })
|
|
|
+ state.list = [...state.list, ...result.rows]
|
|
|
+ state.finshed = state.page >= result.pages
|
|
|
+ } else {
|
|
|
+ state.finshed = true
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ state.finshed = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 酷乐秀机构数据查询 */
|
|
|
+ const handleSearchList_klx = async () => {
|
|
|
+ loading.value = true
|
|
|
+ await httpAjaxErrMsg(queryTree_klx, {
|
|
|
+ enable: true,
|
|
|
+ page: 1,
|
|
|
+ parentId: 0,
|
|
|
+ rows: 10
|
|
|
+ }).then(async res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ const result = res.data || []
|
|
|
+
|
|
|
+ const tempList: any = []
|
|
|
+ result.forEach((item: any) => {
|
|
|
+ if (item.musicNum > 0) {
|
|
|
+ const subjectCounts = item.subjectCounts ? true : false
|
|
|
+ const musicCounts = item.musicCounts ? true : false
|
|
|
+ const ensembleCounts = item.ensembleCounts ? true : false
|
|
|
+ const list: any = []
|
|
|
+ if (subjectCounts) {
|
|
|
+ list.push({
|
|
|
+ label: "基础云练",
|
|
|
+ value: "SUBJECT"
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (musicCounts) {
|
|
|
+ list.push({
|
|
|
+ label: "独奏云练",
|
|
|
+ value: "MUSIC"
|
|
|
+ })
|
|
|
+ }
|
|
|
+ if (ensembleCounts) {
|
|
|
+ list.push({
|
|
|
+ label: "合奏云练",
|
|
|
+ value: "ENSEMBLE"
|
|
|
+ })
|
|
|
+ }
|
|
|
+ tempList.push({
|
|
|
+ value: item.id,
|
|
|
+ label: item.name,
|
|
|
+ musicSheetCategoriesList: list
|
|
|
+ })
|
|
|
+ }
|
|
|
+ })
|
|
|
+ state.categoryList = tempList
|
|
|
+
|
|
|
+ await setDefaultData()
|
|
|
+ } else {
|
|
|
+ state.finshed = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleGetSubject_klx = async () => {
|
|
|
+ loading.value = true
|
|
|
+ await httpAjaxErrMsg(querySubjectIds_klx, {
|
|
|
+ queryType: "list",
|
|
|
+ page: 1,
|
|
|
+ rows: 100
|
|
|
+ }).then(res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ const result = res.data?.rows || []
|
|
|
+ state.subjectList = result.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.name,
|
|
|
+ value: item.id,
|
|
|
+ instrumentIds: item.instrumentId
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ state.subjectList.unshift({
|
|
|
+ label: "全部声部",
|
|
|
+ value: -1
|
|
|
+ })
|
|
|
+
|
|
|
+ const userSubjectId = userStoreHook.userInfo.subjectId
|
|
|
+ if (userSubjectId) {
|
|
|
+ const tempSubjectId = userSubjectId.split(",")[0]
|
|
|
+ state.subjectList.forEach((item: any) => {
|
|
|
+ // 判断是否存在声部编号
|
|
|
+ if (item.value === Number(tempSubjectId)) {
|
|
|
+ state.subjectId = Number(tempSubjectId)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleGetList_klx = async () => {
|
|
|
+ if (!state.categoryId) return
|
|
|
+ loading.value = true
|
|
|
+ const params = {
|
|
|
+ page: state.page,
|
|
|
+ rows: state.rows,
|
|
|
+ albumId: state.categoryId,
|
|
|
+ subjectId: state.subjectId === -1 ? null : state.subjectId,
|
|
|
+ subjectType: state.firstTreeId,
|
|
|
+ level: state.levelId === -1 ? null : state.levelId,
|
|
|
+ type: state.typeId === -1 ? null : state.typeId,
|
|
|
+ keyword: state.queryStr
|
|
|
+ }
|
|
|
+ await httpAjaxErrMsg(queryPage2_klx, params).then(res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ const result = res.data || {}
|
|
|
+
|
|
|
+ if (state.reshing) {
|
|
|
+ state.list = []
|
|
|
+ state.reshing = false
|
|
|
+ }
|
|
|
+ if (Array.isArray(result.rows)) {
|
|
|
+ state.list = [...state.list, ...result.rows]
|
|
|
+ state.finshed = state.page >= result.totalPage
|
|
|
+ } else {
|
|
|
+ state.finshed = true
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ state.finshed = true
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleGetDetail_klx = async () => {
|
|
|
+ loading.value = true
|
|
|
+ const { id } = state.list[state.listActive] || {}
|
|
|
+ if (!id) return (loading.value = false)
|
|
|
+ await httpAjaxErrMsg(cbsDetail_klx, id, { simpleFlag: "1", providerType: "TENANT" }).then(res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ const result = res.data || {}
|
|
|
+ state.details = result
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleSelectCondition_klx = async () => {
|
|
|
+ if (!state.categoryId || !state.firstTreeId) return
|
|
|
+ loading.value = true
|
|
|
+ const params = {
|
|
|
+ tenantAlbumId: state.categoryId,
|
|
|
+ subjectType: state.firstTreeId
|
|
|
+ }
|
|
|
+ await httpAjaxErrMsg(selectCondition_klx, params).then(res => {
|
|
|
+ loading.value = false
|
|
|
+ if (res.code === 200) {
|
|
|
+ const result = res.data || {}
|
|
|
+
|
|
|
+ if (result.levelList && result.levelList.length > 0) {
|
|
|
+ state.levelList = result.levelList.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.value,
|
|
|
+ value: item.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ state.levelList.unshift({
|
|
|
+ label: "全部级别",
|
|
|
+ value: -1
|
|
|
+ })
|
|
|
+ state.levelId = -1
|
|
|
+ } else {
|
|
|
+ state.levelList = []
|
|
|
+ }
|
|
|
+
|
|
|
+ if (result.typeList && result.typeList.length > 0) {
|
|
|
+ state.typeList = result.typeList.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.value,
|
|
|
+ value: item.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ state.typeList.unshift({
|
|
|
+ label: "全部类型",
|
|
|
+ value: -1
|
|
|
+ })
|
|
|
+ state.typeId = -1
|
|
|
+ } else {
|
|
|
+ state.typeList = []
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 条件查询 */
|
|
|
+ const handleAllSearchList = async () => {
|
|
|
+ // GYM,GYT,KLX 区分 查询搜索条件数据
|
|
|
+ if (userStoreHook.roles === "GYM") {
|
|
|
+ await handleSearchList_gym()
|
|
|
+ } else if (userStoreHook.roles === "GYT") {
|
|
|
+ await handleSearchList_gyt()
|
|
|
+ } else if (userStoreHook.roles === "KLX") {
|
|
|
+ await handleSearchList_klx()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleAllGetSubject = async () => {
|
|
|
+ // GYM,GYT,KLX 区分 查询声部数据
|
|
|
+ if (userStoreHook.roles === "GYM") {
|
|
|
+ await handleGetSubject_gym()
|
|
|
+ } else if (userStoreHook.roles === "GYT") {
|
|
|
+ await handleGetSubject_gyt()
|
|
|
+ } else if (userStoreHook.roles === "KLX") {
|
|
|
+ await handleGetSubject_klx()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleAllGetList = async () => {
|
|
|
+ // GYM,GYT,KLX 区分 查询声部数据·
|
|
|
+ if (userStoreHook.roles === "GYM") {
|
|
|
+ await handleGetList_gym()
|
|
|
+ } else if (userStoreHook.roles === "GYT") {
|
|
|
+ await handleGetList_gyt()
|
|
|
+ } else if (userStoreHook.roles === "KLX") {
|
|
|
+ await handleGetList_klx()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleGetDetail = async () => {
|
|
|
+ // GYM,GYT,KLX 区分 查询声部数据·
|
|
|
+ if (userStoreHook.roles === "GYM") {
|
|
|
+ await handleGetDetail_gym()
|
|
|
+ } else if (userStoreHook.roles === "GYT") {
|
|
|
+ //
|
|
|
+ } else if (userStoreHook.roles === "KLX") {
|
|
|
+ await handleGetDetail_klx()
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 初始化数据 */
|
|
|
+ const setDefaultData = async (type?: "first" | "category" | "level" | "type") => {
|
|
|
+ if (userStoreHook.roles === "GYM") {
|
|
|
+ await initCategories_gym(type)
|
|
|
+ } else if (userStoreHook.roles === "GYT") {
|
|
|
+ initCategories_gyt(type)
|
|
|
+ } else if (userStoreHook.roles === "KLX") {
|
|
|
+ await initCategories_klx(type)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const initCategories_gym = async (type?: "first" | "category" | "level" | "type") => {
|
|
|
+ if (storeData.value.length > 0 && !["category", "level", "type"].includes(type as any)) {
|
|
|
+ let result: any = []
|
|
|
+ if (type === "first" && state.firstTreeId) {
|
|
|
+ result = storeData.value.find((item: any) => item.id === state.firstTreeId)?.sysMusicScoreCategoriesList || []
|
|
|
+ } else {
|
|
|
+ state.firstTreeId = storeData.value[0]?.id
|
|
|
+ result = storeData.value[0]?.sysMusicScoreCategoriesList || []
|
|
|
+ }
|
|
|
+ state.categoryList = result.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.name,
|
|
|
+ value: item.id,
|
|
|
+ sysMusicScoreCategoriesList: item.sysMusicScoreCategoriesList || []
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ state.categoryId = null
|
|
|
+ state.categoryName = null
|
|
|
+ state.levelId = null
|
|
|
+ state.typeId = -1
|
|
|
+ }
|
|
|
+ if (state.categoryList.length > 0 && !["level", "type"].includes(type as any)) {
|
|
|
+ let result: any = []
|
|
|
+ if (type === "category" && state.categoryId) {
|
|
|
+ result = state.categoryList.find((item: any) => item.value === state.categoryId)?.sysMusicScoreCategoriesList || []
|
|
|
+ } else {
|
|
|
+ state.categoryId = state.categoryList[0]?.value
|
|
|
+ state.categoryName = state.categoryList[0]?.label
|
|
|
+ result = state.categoryList[0]?.sysMusicScoreCategoriesList || []
|
|
|
+ }
|
|
|
+ state.levelList = result.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.name,
|
|
|
+ value: item.id,
|
|
|
+ sysMusicScoreCategoriesList: item.sysMusicScoreCategoriesList || []
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ type && (await handleGetSubject_gym())
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state.levelList.length > 0) {
|
|
|
+ let result: any = []
|
|
|
+ if (type === "level" && state.levelId) {
|
|
|
+ result = state.levelList.find((item: any) => item.value === state.levelId)?.sysMusicScoreCategoriesList
|
|
|
+ state.typeId = -1
|
|
|
+ } else {
|
|
|
+ state.levelId = state.levelList[0]?.value
|
|
|
+ result = state.levelList[0]?.sysMusicScoreCategoriesList || []
|
|
|
+ }
|
|
|
+
|
|
|
+ state.typeList = result.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.name,
|
|
|
+ value: item.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+ state.typeList.unshift({
|
|
|
+ label: "全部",
|
|
|
+ value: -1
|
|
|
+ })
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const initCategories_gyt = (type?: "first" | "category" | "level" | "type") => {
|
|
|
+ if (storeData.value.length > 0 && !["level", "type"].includes(type as any)) {
|
|
|
+ let result: any = []
|
|
|
+ if (type === "first" && state.firstTreeId) {
|
|
|
+ result = storeData.value.find((item: any) => item.id === state.firstTreeId)?.musicSheetCategoriesList || []
|
|
|
+ } else {
|
|
|
+ state.firstTreeId = storeData.value[0]?.id
|
|
|
+ result = storeData.value[0]?.musicSheetCategoriesList || []
|
|
|
+ }
|
|
|
+
|
|
|
+ state.levelList = result.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.name,
|
|
|
+ value: item.id,
|
|
|
+ musicSheetCategoriesList: item.musicSheetCategoriesList || []
|
|
|
+ }
|
|
|
+ })
|
|
|
+ state.levelId = null
|
|
|
+ state.typeId = -1
|
|
|
+ }
|
|
|
+
|
|
|
+ if (state.levelList.length > 0) {
|
|
|
+ let result: any = []
|
|
|
+ if (type === "level" && state.levelId) {
|
|
|
+ result = state.levelList.find((item: any) => item.value === state.levelId)?.musicSheetCategoriesList
|
|
|
+ } else {
|
|
|
+ state.levelId = state.levelList[0]?.value
|
|
|
+ result = state.levelList[0]?.musicSheetCategoriesList || []
|
|
|
+ }
|
|
|
+
|
|
|
+ state.typeList = result.map((item: any) => {
|
|
|
+ return {
|
|
|
+ label: item.name,
|
|
|
+ value: item.id
|
|
|
+ }
|
|
|
+ })
|
|
|
+ state.typeList.unshift({
|
|
|
+ label: "全部",
|
|
|
+ value: -1
|
|
|
+ })
|
|
|
+ state.typeId = -1
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const initCategories_klx = async (type?: "first" | "category" | "level" | "type") => {
|
|
|
+ if (state.categoryList.length > 0 && !["level", "type", "first"].includes(type as any)) {
|
|
|
+ let result: any = []
|
|
|
+ if (type === "category" && state.categoryId) {
|
|
|
+ result = state.categoryList.find((item: any) => item.value === state.categoryId)?.musicSheetCategoriesList || []
|
|
|
+ } else {
|
|
|
+ state.categoryId = state.categoryList[0]?.value
|
|
|
+ state.categoryName = state.categoryList[0]?.label
|
|
|
+ result = state.categoryList[0]?.musicSheetCategoriesList || []
|
|
|
+ }
|
|
|
+ storeData.value = result.map((item: any) => {
|
|
|
+ return {
|
|
|
+ id: item.value,
|
|
|
+ name: item.label
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ if (storeData.value.length > 0 && !["level", "type"].includes(type as any)) {
|
|
|
+ if (type === "first" && state.firstTreeId) {
|
|
|
+ await handleSelectCondition_klx()
|
|
|
+ } else {
|
|
|
+ //
|
|
|
+ state.firstTreeId = storeData.value[0]?.id
|
|
|
+ await handleSelectCondition_klx()
|
|
|
+ }
|
|
|
+ state.levelId = -1
|
|
|
+ state.typeId = -1
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const __init = async () => {
|
|
|
+ getInstrumentCodes()
|
|
|
+ await handleAllSearchList()
|
|
|
+ await handleAllGetSubject()
|
|
|
+ await handleAllGetList()
|
|
|
+ await handleGetDetail() // 默认获取数据
|
|
|
+ await toDetail()
|
|
|
+ renderStaff()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 全屏显示
|
|
|
+ handleFullscreen(true, false)
|
|
|
+ __init()
|
|
|
+
|
|
|
+ const handleResh = () => {
|
|
|
+ if (loading.value || state.finshed) return
|
|
|
+ state.page = state.page + 1
|
|
|
+ handleAllGetList()
|
|
|
+ }
|
|
|
+
|
|
|
+ const handleGetList = async () => {
|
|
|
+ if (loading.value) return
|
|
|
+ state.listActive = 0
|
|
|
+ state.showPlayer = false
|
|
|
+ state.playState = "pause"
|
|
|
+ state.partNames = []
|
|
|
+ state.partList = []
|
|
|
+ state.details = {}
|
|
|
+ state.selectedPartName = ""
|
|
|
+ state.selectedTrack = ""
|
|
|
+ state.selectedPartIndex = 0
|
|
|
+ // state.musicPdfUrl = ""
|
|
|
+ state.partXmlIndex = 0
|
|
|
+ document.querySelector(".musicList-container")?.scroll(0, 0)
|
|
|
+ state.page = 1
|
|
|
+ state.finshed = false
|
|
|
+ state.reshing = true
|
|
|
+ state.list = []
|
|
|
+ await handleAllGetList()
|
|
|
+ }
|
|
|
+
|
|
|
+ // 获取PDF
|
|
|
+ const getCurrentPdf = (item: any, scoreType: string) => {
|
|
|
+ let pdfUrl = ""
|
|
|
+ if (scoreType === "FIRST") {
|
|
|
+ pdfUrl = item.firstPdfUrl
|
|
|
+ } else if (scoreType === "JIAN") {
|
|
|
+ pdfUrl = item.jianPdfUrl
|
|
|
+ } else if (scoreType === "STAVE") {
|
|
|
+ pdfUrl = item.musicPdfUrl
|
|
|
+ }
|
|
|
+ return pdfUrl || ""
|
|
|
+ }
|
|
|
+
|
|
|
+ const toDetailGYM = () => {
|
|
|
+ // const row: any = activeItem.value
|
|
|
+ const details: any = state.details
|
|
|
+ state.imgs = []
|
|
|
+ if (details.musicSheetType === "SINGLE") {
|
|
|
+ loading.value = false
|
|
|
+ state.musicPdfUrl = getCurrentPdf(details, details.scoreType)
|
|
|
+ return
|
|
|
+ }
|
|
|
+ // state.partNames = await getPartNames(row.xmlUrl)
|
|
|
+ let partList = details.musicSheetSoundList || []
|
|
|
+ partList = partList.filter((item: any) => item.audioPlayType === "PLAY")
|
|
|
+ partList = partList.filter((item: any) => !item.track?.toLocaleUpperCase()?.includes("COMMON"))
|
|
|
+ partColumns.value = partList.map((item: any, index: number) => {
|
|
|
+ const instrumentName = getInstrumentName(instrumentCodes.value, item.track)
|
|
|
+ // const xmlIndex = state.partNames.findIndex((name: any) => name.trim() === item.track)
|
|
|
+ return {
|
|
|
+ label: item.track + (instrumentName ? `(${instrumentName})` : ""),
|
|
|
+ instrumentName: instrumentName,
|
|
|
+ track: item.track,
|
|
|
+ musicPdfUrl: getCurrentPdf(item, details.scoreType),
|
|
|
+ // xmlIndex: -1,
|
|
|
+ value: index
|
|
|
+ }
|
|
|
+ })
|
|
|
+
|
|
|
+ // 初始化数据
|
|
|
+ // 是否显示总谱
|
|
|
+ if (details.isScoreRender) {
|
|
|
+ partColumns.value.unshift({
|
|
|
+ label: "总谱",
|
|
|
+ instrumentName: null,
|
|
|
+ track: null,
|
|
|
+ musicPdfUrl: getCurrentPdf(details, details.scoreType),
|
|
|
+ xmlIndex: 999,
|
|
|
+ value: 999
|
|
|
+ })
|
|
|
+ }
|
|
|
+ // gym 现在单独处理 管乐迷根据查询条件来筛选谱面
|
|
|
+ let defaultShowStaff
|
|
|
+
|
|
|
+ if (details.defaultScoreRender) {
|
|
|
+ state.selectedPartIndex = 999
|
|
|
+ } else {
|
|
|
+ // 这里筛选当前的声轨
|
|
|
+ const soundCodes = filterSoundCodes()
|
|
|
+ if (soundCodes) {
|
|
|
+ const soundCodesArr = soundCodes.split(",").map((code: string) => {
|
|
|
+ return code
|
|
|
+ .toLowerCase()
|
|
|
+ .replace(/^\d+|\d+$/g, "")
|
|
|
+ .trim()
|
|
|
+ })
|
|
|
+ defaultShowStaff = partColumns.value.find((item: any) =>
|
|
|
+ soundCodesArr.includes(
|
|
|
+ item.track &&
|
|
|
+ item.track
|
|
|
+ .toLowerCase()
|
|
|
+ .replace(/^\d+|\d+$/g, "")
|
|
|
+ .trim()
|
|
|
+ )
|
|
|
+ )
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ defaultShowStaff || (defaultShowStaff = partColumns.value.find((item: any) => item.value === state.selectedPartIndex))
|
|
|
+ state.selectedPartName = defaultShowStaff?.instrumentName
|
|
|
+ state.selectedTrack = defaultShowStaff?.track
|
|
|
+ state.partXmlIndex = defaultShowStaff?.xmlIndex
|
|
|
+ state.selectedPartIndex = defaultShowStaff?.value
|
|
|
+ if (details.isScoreRender && details.defaultScoreRender) {
|
|
|
+ state.musicPdfUrl = getCurrentPdf(details, details.scoreType)
|
|
|
+ } else {
|
|
|
+ state.musicPdfUrl = defaultShowStaff?.musicPdfUrl || ""
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const toDetail = async () => {
|
|
|
+ if (userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX") {
|
|
|
+ toDetailGYM()
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const row: any = activeItem.value
|
|
|
+ state.imgs = []
|
|
|
+ if (row.musicSheetType === "SINGLE") {
|
|
|
+ loading.value = false
|
|
|
+ state.musicPdfUrl = row.musicPdfUrl
|
|
|
+ return
|
|
|
+ }
|
|
|
+ state.partNames = await getPartNames(row.xmlUrl)
|
|
|
+ let partList = row.background || []
|
|
|
+ partList = partList.filter((item: any) => !item.track?.toLocaleUpperCase()?.includes("COMMON"))
|
|
|
+ partColumns.value = partList.map((item: any, index: number) => {
|
|
|
+ const instrumentName = getInstrumentName(instrumentCodes.value, item.track)
|
|
|
+ const xmlIndex = state.partNames.findIndex((name: any) => name.trim() === item.track)
|
|
|
+ let musicPdfUrl = ""
|
|
|
+ if (userStoreHook.roles === "GYM") {
|
|
|
+ musicPdfUrl = item.soundMusicPdfUrl
|
|
|
+ } else if (userStoreHook.roles === "GYT") {
|
|
|
+ musicPdfUrl = item.musicPdfUrl
|
|
|
+ } else if (userStoreHook.roles === "KLX") {
|
|
|
+ musicPdfUrl = item.musicPdfUrl
|
|
|
+ }
|
|
|
+ return {
|
|
|
+ label: item.track + (instrumentName ? `(${instrumentName})` : ""),
|
|
|
+ instrumentName: instrumentName,
|
|
|
+ track: item.track,
|
|
|
+ musicPdfUrl,
|
|
|
+ xmlIndex,
|
|
|
+ value: index
|
|
|
+ }
|
|
|
+ })
|
|
|
+ // 初始化数据
|
|
|
+ // 是否显示总谱
|
|
|
+ if (row.isScoreRender) {
|
|
|
+ partColumns.value.unshift({
|
|
|
+ label: "总谱",
|
|
|
+ instrumentName: null,
|
|
|
+ track: null,
|
|
|
+ musicPdfUrl: "",
|
|
|
+ xmlIndex: 999,
|
|
|
+ value: 999
|
|
|
+ })
|
|
|
+
|
|
|
+ if (row.defaultScoreRender) {
|
|
|
+ state.selectedPartIndex = 999
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const defaultShowStaff = partColumns.value.find((item: any) => item.value === state.selectedPartIndex)
|
|
|
+
|
|
|
+ state.selectedPartName = defaultShowStaff?.instrumentName
|
|
|
+ state.selectedTrack = defaultShowStaff?.track
|
|
|
+ state.partXmlIndex = defaultShowStaff?.xmlIndex
|
|
|
+ state.selectedPartIndex = defaultShowStaff?.value
|
|
|
+ if (row.isScoreRender && row.defaultScoreRender) {
|
|
|
+ state.musicPdfUrl = row?.musicPdfUrl || ""
|
|
|
+ } else {
|
|
|
+ state.musicPdfUrl = defaultShowStaff?.musicPdfUrl || ""
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const getPartNames = async (xmlUrl: string) => {
|
|
|
+ const partNames: string[] = []
|
|
|
+ try {
|
|
|
+ const res: any = await axios.get(xmlUrl)
|
|
|
+ const xml: any = new DOMParser().parseFromString(res.data, "text/xml")
|
|
|
+ for (const item of xml.getElementsByTagName("part-name")) {
|
|
|
+ if (item.textContent) {
|
|
|
+ partNames.push(item.textContent)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ return partNames.filter((text: string) => text.toLocaleUpperCase() !== "COMMON") || []
|
|
|
+ }
|
|
|
+
|
|
|
+ const musicIframeLoad = async () => {
|
|
|
+ if (userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX") {
|
|
|
+ // 判断是用哪个渲染的
|
|
|
+ loading.value = false
|
|
|
+ staffLoading.value = false
|
|
|
+ return
|
|
|
+ }
|
|
|
+ const iframeRef: any = document.getElementById("staffIframeRef")
|
|
|
+ if (iframeRef && iframeRef.contentWindow?.renderXml) {
|
|
|
+ staffLoading.value = true
|
|
|
+ const res: any = await axios.get(activeItem.value.xmlUrl)
|
|
|
+ const parseXmlInfo = getCustomInfo(res.data)
|
|
|
+ const xml = formatXML(parseXmlInfo.parsedXML)
|
|
|
+ if (activeItem.value.isScoreRender) {
|
|
|
+ const canSelectTracks: any = []
|
|
|
+ const background = activeItem.value.background || []
|
|
|
+ background.forEach((item: any) => {
|
|
|
+ canSelectTracks.push(item.track)
|
|
|
+ })
|
|
|
+ iframeRef.contentWindow.renderXml(xml, activeItem.value.isScoreRender)
|
|
|
+ } else {
|
|
|
+ const currentXml = onlyVisible(xml, state.partXmlIndex)
|
|
|
+ iframeRef.contentWindow.renderXml(currentXml)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ const resetRender = async () => {
|
|
|
+ const iframeRef: any = document.getElementById("staffIframeRef")
|
|
|
+ if (userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX") {
|
|
|
+ iframeRef.contentWindow.location.replace(
|
|
|
+ getPreViewCloud(activeItem.value.id, state.partXmlIndex, state.selectedTrack, musicRenderType.value)
|
|
|
+ )
|
|
|
+ // state.iframeSrc = getPreViewCloud(activeItem.value.id, state.partXmlIndex)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (iframeRef && iframeRef.contentWindow?.renderXml) {
|
|
|
+ staffLoading.value = true
|
|
|
+ const res: any = await axios.get(activeItem.value.xmlUrl)
|
|
|
+ const parseXmlInfo = getCustomInfo(res.data)
|
|
|
+ const xml = formatXML(parseXmlInfo.parsedXML)
|
|
|
+ if (activeItem.value.isScoreRender) {
|
|
|
+ iframeRef.contentWindow.renderXml(xml, activeItem.value.isScoreRender)
|
|
|
+ } else {
|
|
|
+ const currentXml = onlyVisible(xml, state.partXmlIndex)
|
|
|
+ iframeRef.contentWindow.renderXml(currentXml)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const renderStaff = async () => {
|
|
|
+ try {
|
|
|
+ if (state.musicPdfUrl) {
|
|
|
+ state.iframeSrc = "/pdf/web/viewer.html?file=" + encodeURIComponent(state.musicPdfUrl) + "&t=" + Date.now()
|
|
|
+ // https://cdn.oss.dayaedu.com/daya202409/UOFW4q5.pdf
|
|
|
+ // https://cdn.oss.dayaedu.com/daya202409/UOFVK2A.pdf
|
|
|
+ // https://cdn.oss.dayaedu.com/daya202409/UODQffO.pdf
|
|
|
+ } else {
|
|
|
+ if (userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX") {
|
|
|
+ nextTick(() => {
|
|
|
+ const iframeRef: any = document.getElementById("staffIframeRef")
|
|
|
+ if (iframeRef) {
|
|
|
+ iframeRef.contentWindow.location.replace(
|
|
|
+ getPreViewCloud(activeItem.value.id, state.partXmlIndex, state.selectedTrack, musicRenderType.value)
|
|
|
+ )
|
|
|
+ } else {
|
|
|
+ state.iframeSrc = getPreViewCloud(activeItem.value.id, state.partXmlIndex, state.selectedTrack, musicRenderType.value)
|
|
|
+ }
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ state.iframeSrc = `/osmd/index.html`
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (error) {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 音频控制 */
|
|
|
+ const handleChangeAudio = async (type: "play" | "pause" | "pre" | "next") => {
|
|
|
+ if (type === "play") {
|
|
|
+ state.playState = "play"
|
|
|
+ } else if (type === "pause") {
|
|
|
+ state.playState = "pause"
|
|
|
+ } else if (type === "pre") {
|
|
|
+ if (state.list[state.listActive - 1]) {
|
|
|
+ handlePlay(state.list[state.listActive - 1])
|
|
|
+
|
|
|
+ await handleGetDetail()
|
|
|
+ searchContent()
|
|
|
+ }
|
|
|
+ } else if (type === "next") {
|
|
|
+ if (state.list[state.listActive + 1]) {
|
|
|
+ handlePlay(state.list[state.listActive + 1])
|
|
|
+
|
|
|
+ await handleGetDetail()
|
|
|
+ searchContent()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 播放曲目 */
|
|
|
+ const handlePlay = (item: any) => {
|
|
|
+ const index = state.list.findIndex((_item: any) => _item.id === item.id)
|
|
|
+ if (index > -1) {
|
|
|
+ if (state.listActive === index) {
|
|
|
+ state.playState = state.playState === "play" ? "pause" : "play"
|
|
|
+ } else {
|
|
|
+ state.playState = "play"
|
|
|
+ }
|
|
|
+ state.showPlayer = true
|
|
|
+ state.listActive = index
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // // 多个文件下载
|
|
|
+ const downLoadMultiFile = (files: any, filesName: string) => {
|
|
|
+ const zip = new JSZip()
|
|
|
+ for (const i in files) {
|
|
|
+ zip.file(files[i].name, files[i].url, { binary: true })
|
|
|
+ }
|
|
|
+ zip.generateAsync({ type: "blob" }).then(res => {
|
|
|
+ saveAs(res, filesName ? filesName + ".zip" : `文件夹${Date.now()}.zip`)
|
|
|
+ })
|
|
|
+ downloadStatus.value = false
|
|
|
+ }
|
|
|
+
|
|
|
+ const showLoading = async (e: any) => {
|
|
|
+ if (e.data?.api === "musicStaffRender") {
|
|
|
+ const musicName =
|
|
|
+ activeItem.value.name +
|
|
|
+ (((activeItem.value.musicSheetType === "CONCERT" || state.details.musicSheetType === "CONCERT") && state.selectedPartName) ||
|
|
|
+ state.selectedTrack
|
|
|
+ ? `(${state.selectedPartName || state.selectedTrack})`
|
|
|
+ : "")
|
|
|
+ try {
|
|
|
+ const osmdImg = e.data.osmdImg
|
|
|
+ const imgs = []
|
|
|
+ for (let i = 0; i < osmdImg.length; i++) {
|
|
|
+ const img = await svgtoblob(
|
|
|
+ osmdImg[i].img,
|
|
|
+ osmdImg[i].width,
|
|
|
+ osmdImg[i].height,
|
|
|
+ musicName,
|
|
|
+ userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX" ? false : true
|
|
|
+ )
|
|
|
+ imgs.push({
|
|
|
+ url: img,
|
|
|
+ name: i + 1 + ".png"
|
|
|
+ })
|
|
|
+ }
|
|
|
+ state.imgs = imgs
|
|
|
+ } catch (e) {
|
|
|
+ // console.log(e);
|
|
|
+ }
|
|
|
+ staffLoading.value = e.data.loading
|
|
|
+ loading.value = e.data.loading
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ const searchContent = async () => {
|
|
|
+ await toDetail()
|
|
|
+ if (activeItem.value?.id) {
|
|
|
+ if (state.musicPdfUrl) {
|
|
|
+ staffLoading.value = true
|
|
|
+ renderStaff()
|
|
|
+ } else {
|
|
|
+ // 为了处理,之前是使用pdf渲染,现在又用osmd,iframe没有重新加载
|
|
|
+ if (state.iframeSrc.indexOf("pdf/web") !== -1) {
|
|
|
+ renderStaff()
|
|
|
+ } else {
|
|
|
+ resetRender()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /** 下载图片 */
|
|
|
+ const onDownload = () => {
|
|
|
+ if (downloadStatus.value || staffLoading.value) return
|
|
|
+ const musicName =
|
|
|
+ activeItem.value.name +
|
|
|
+ ((activeItem.value.musicSheetType === "CONCERT" && state.selectedPartName) || state.selectedTrack
|
|
|
+ ? `(${state.selectedPartName || state.selectedTrack})`
|
|
|
+ : "")
|
|
|
+ downloadStatus.value = true
|
|
|
+ if (state.musicPdfUrl) {
|
|
|
+ // 发起Fetch请求
|
|
|
+ fetch(state.musicPdfUrl)
|
|
|
+ .then(response => response.blob())
|
|
|
+ .then(blob => {
|
|
|
+ saveAs(blob, musicName)
|
|
|
+ downloadStatus.value = false
|
|
|
+ })
|
|
|
+ .catch(() => {
|
|
|
+ ElMessage.error("下载失败")
|
|
|
+ downloadStatus.value = false
|
|
|
+ })
|
|
|
+ } else {
|
|
|
+ downLoadMultiFile(state.imgs, musicName)
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // 根据当前选中的声部和曲目筛选出对应的声轨
|
|
|
+ function filterSoundCodes() {
|
|
|
+ // const { id } = state.list[state.listActive] || {}
|
|
|
+ // if (!id) {
|
|
|
+ // return undefined
|
|
|
+ // }
|
|
|
+ const { instrumentIds } =
|
|
|
+ state.subjectList.find((item: any) => {
|
|
|
+ return item.value === state.subjectId
|
|
|
+ }) || {}
|
|
|
+ if (instrumentIds) {
|
|
|
+ // GYM,GYT,KLX 区分 查询声部数据
|
|
|
+ let cbsDetails: any = []
|
|
|
+ if (userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX") {
|
|
|
+ cbsDetails = state.details.musicSheetSoundList || []
|
|
|
+ } else if (userStoreHook.roles === "GYT") {
|
|
|
+ //
|
|
|
+ }
|
|
|
+ const { track } =
|
|
|
+ cbsDetails.find((item: any) => {
|
|
|
+ return instrumentIds == item.musicalInstrumentId
|
|
|
+ }) || {}
|
|
|
+ return track
|
|
|
+ }
|
|
|
+ return undefined
|
|
|
+ }
|
|
|
+
|
|
|
+ // 白板的批注打开时暂停播放
|
|
|
+ watch(
|
|
|
+ () => [whitePenShow.value, penShow.value],
|
|
|
+ () => {
|
|
|
+ if (whitePenShow.value || penShow.value) {
|
|
|
+ handleChangeAudio("pause")
|
|
|
+ }
|
|
|
+ }
|
|
|
+ )
|
|
|
+
|
|
|
+ onMounted(() => {
|
|
|
+ const obv = new IntersectionObserver(entries => {
|
|
|
+ if (entries[0].intersectionRatio > 0) {
|
|
|
+ handleResh()
|
|
|
+ }
|
|
|
+ })
|
|
|
+ obv.observe(spinRef.value)
|
|
|
+
|
|
|
+ window.addEventListener("message", showLoading)
|
|
|
+ })
|
|
|
+ return () => (
|
|
|
+ <NavContainer navs={navs}>
|
|
|
+ {/* <ElScrollbar class="elScrollbar"> */}
|
|
|
+ <div class={styles.cloudPractice}>
|
|
|
+ <div class={styles.leftContainer}>
|
|
|
+ <div class={styles.details}>
|
|
|
+ {storeData.value.length > 0 && (
|
|
|
+ <ElScrollbar class={styles.leftSection}>
|
|
|
+ {/* 基 础 云 练 */}
|
|
|
+ {storeData.value.map((item: any) => (
|
|
|
+ <div
|
|
|
+ class={[styles.leftSection_item, item.id === state.firstTreeId && styles.leftSection_item__active]}
|
|
|
+ onClick={async () => {
|
|
|
+ if (loading.value) return
|
|
|
+ state.firstTreeId = item.id
|
|
|
+ await setDefaultData("first")
|
|
|
+ await handleGetList()
|
|
|
+ await handleGetDetail()
|
|
|
+ searchContent()
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {item.name}
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+ </ElScrollbar>
|
|
|
+ )}
|
|
|
+
|
|
|
+ <div class={[styles.musicList, "musicList-container"]}>
|
|
|
+ <div class={styles.searchHeader}>
|
|
|
+ {state.categoryList.length > 1 && (
|
|
|
+ <div class={[styles.categorySection]}>
|
|
|
+ <NPopselect
|
|
|
+ placement="bottom-start"
|
|
|
+ disabled={loading.value}
|
|
|
+ options={state.categoryList}
|
|
|
+ v-model:value={state.categoryId}
|
|
|
+ onUpdate:value={async (val: any) => {
|
|
|
+ const item = state.categoryList.find((item: any) => item.value === val)
|
|
|
+ if (item) {
|
|
|
+ state.categoryName = item.label
|
|
|
+ state.categoryId = item.value
|
|
|
+ await setDefaultData("category")
|
|
|
+ await handleGetList()
|
|
|
+ await handleGetDetail()
|
|
|
+ searchContent()
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ onUpdate:show={(value: any) => {
|
|
|
+ state.categoryShow = value
|
|
|
+ }}
|
|
|
+ trigger="click"
|
|
|
+ class={"PopSelect"}
|
|
|
+ >
|
|
|
+ <span class={[styles.iconTagName, state.categoryShow && styles.show]}>
|
|
|
+ <span>{state.categoryName}</span>
|
|
|
+ </span>
|
|
|
+ </NPopselect>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ <div class={styles.searchMore}>
|
|
|
+ <div class={styles.searchSection}>
|
|
|
+ <Dictionary
|
|
|
+ clearable={false}
|
|
|
+ popperClass="classTypePopper"
|
|
|
+ v-model={state.subjectId}
|
|
|
+ height={42}
|
|
|
+ // disabled={loading.value}
|
|
|
+ options={state.subjectList}
|
|
|
+ placeholder="全部声部"
|
|
|
+ onChange={async () => {
|
|
|
+ await handleGetList()
|
|
|
+ await handleGetDetail()
|
|
|
+ searchContent()
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ {state.levelList.length ? (
|
|
|
+ <Dictionary
|
|
|
+ clearable={false}
|
|
|
+ popperClass="classTypePopper"
|
|
|
+ v-model={state.levelId}
|
|
|
+ height={42}
|
|
|
+ // disabled={loading.value}
|
|
|
+ options={state.levelList}
|
|
|
+ placeholder="级别"
|
|
|
+ onChange={async () => {
|
|
|
+ setDefaultData("level")
|
|
|
+ await handleGetList()
|
|
|
+ await handleGetDetail()
|
|
|
+ searchContent()
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ ) : null}
|
|
|
+ {state.typeList.length > 0 ? (
|
|
|
+ <Dictionary
|
|
|
+ clearable={false}
|
|
|
+ popperClass="classTypePopper"
|
|
|
+ v-model={state.typeId}
|
|
|
+ height={42}
|
|
|
+ // disabled={loading.value}
|
|
|
+ options={state.typeList}
|
|
|
+ propsOpt={{
|
|
|
+ labelField: "name",
|
|
|
+ valueField: "id"
|
|
|
+ }}
|
|
|
+ placeholder="分类"
|
|
|
+ onChange={async () => {
|
|
|
+ await handleGetList()
|
|
|
+ await handleGetDetail()
|
|
|
+ searchContent()
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ ) : null}
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ class={[styles.btnSearch, state.searchStatus && styles.btnSearchActive]}
|
|
|
+ onClick={() => (state.searchStatus = !state.searchStatus)}
|
|
|
+ ></div>
|
|
|
+ </div>
|
|
|
+ {state.searchStatus && (
|
|
|
+ <MyInput
|
|
|
+ class="queryCp"
|
|
|
+ v-model={state.queryStr}
|
|
|
+ height={42}
|
|
|
+ placeholder="请输入曲目关键词"
|
|
|
+ onKeyup={async (e: any) => {
|
|
|
+ if (e.code === "Enter" || e.key === "Enter") {
|
|
|
+ await handleGetList()
|
|
|
+ await handleGetDetail()
|
|
|
+ searchContent()
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ onHandleQuery={async () => {
|
|
|
+ await handleGetList()
|
|
|
+ await handleGetDetail()
|
|
|
+ searchContent()
|
|
|
+ }}
|
|
|
+ clearable
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ <div class={[styles.wrapList, !state.list.length && !loading.value && styles.wrapListEmpty]}>
|
|
|
+ {state.list.map((item: any, index: number) => (
|
|
|
+ <div
|
|
|
+ class={[styles.item, index === state.listActive && styles.active]}
|
|
|
+ onClick={async () => {
|
|
|
+ if (index === state.listActive) {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ state.listActive = index
|
|
|
+ state.selectedPartIndex = 0
|
|
|
+ state.partXmlIndex = 0
|
|
|
+ await handleGetDetail()
|
|
|
+ searchContent()
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ <div class={styles.itemInfo}>
|
|
|
+ <div class={styles.img}>
|
|
|
+ <NImage
|
|
|
+ lazy
|
|
|
+ objectFit="cover"
|
|
|
+ previewDisabled={true}
|
|
|
+ src={item.titleImg || icon_default}
|
|
|
+ onLoad={(e: any) => {
|
|
|
+ ;(e.target as any).dataset.loaded = "true"
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ <PlayLoading
|
|
|
+ class={[state.listActive === index && state.playState === "play" ? "" : styles.showPlayLoading]}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ <div class={styles.title}>
|
|
|
+ <div class={styles.titleName}>
|
|
|
+ <ellipsisScroll title={item.name} />
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class={styles.btnSection}>
|
|
|
+ <div
|
|
|
+ class={styles.btn}
|
|
|
+ onClick={async (e: any) => {
|
|
|
+ e.stopPropagation()
|
|
|
+ const status = state.listActive !== index
|
|
|
+ handlePlay(item)
|
|
|
+ if (status) {
|
|
|
+ await handleGetDetail()
|
|
|
+ searchContent()
|
|
|
+ }
|
|
|
+ }}
|
|
|
+ >
|
|
|
+ {state.listActive === index && (
|
|
|
+ <>
|
|
|
+ {state.playState === "pause" ? "播放" : "暂停"}
|
|
|
+ <img src={state.playState === "pause" ? iconBtnPlay : (iconBtnPause as any)} />
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ {state.listActive !== index && (
|
|
|
+ <>
|
|
|
+ 播放
|
|
|
+ <img src={iconBtnPlay as any} />
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ ))}
|
|
|
+
|
|
|
+ {!state.list.length && !loading.value && (
|
|
|
+ <ElEmpty class={styles.empty} image={require("@/img/layout/empty.png")} description="暂无内容" />
|
|
|
+ )}
|
|
|
+
|
|
|
+ <div ref={spinRef} class={[styles.loadingWrap, state.finshed && styles.showLoading]}>
|
|
|
+ <NSpin show={true} stroke="#FF531C"></NSpin>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ <div class={styles.rightContainer}>
|
|
|
+ {/* <i class={styles.leftArrow}></i> */}
|
|
|
+
|
|
|
+ <NSpin show={staffLoading.value} stroke="#FF531C">
|
|
|
+ {(userStoreHook.roles === "GYT" && activeItem.value?.id) ||
|
|
|
+ ((userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX") && state.details?.id) ? (
|
|
|
+ state.musicPdfUrl ? (
|
|
|
+ <div class={[styles.staffImgs]}>
|
|
|
+ <iframe
|
|
|
+ style={{
|
|
|
+ // opacity: loading.value ? 0 : 1,
|
|
|
+ width: "100%",
|
|
|
+ height: "100%"
|
|
|
+ }}
|
|
|
+ src={state.iframeSrc}
|
|
|
+ onLoad={() => {
|
|
|
+ // 判断是用哪个渲染的
|
|
|
+ loading.value = false
|
|
|
+ staffLoading.value = false
|
|
|
+ }}
|
|
|
+ ></iframe>
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <>
|
|
|
+ <div class={styles.musicName}>
|
|
|
+ {activeItem.value.name}
|
|
|
+ {activeItem.value.musicSheetType === "CONCERT" &&
|
|
|
+ (state.selectedPartName || state.selectedTrack ? `(${state.selectedPartName || state.selectedTrack})` : "")}
|
|
|
+ </div>
|
|
|
+ <div class={[styles.staffImgs]}>
|
|
|
+ <iframe
|
|
|
+ id="staffIframeRef"
|
|
|
+ style={{
|
|
|
+ // opacity: loading.value ? 0 : 1,
|
|
|
+ width: "100%",
|
|
|
+ height: "100%"
|
|
|
+ }}
|
|
|
+ src={state.iframeSrc}
|
|
|
+ onLoad={musicIframeLoad}
|
|
|
+ ></iframe>
|
|
|
+ </div>
|
|
|
+ </>
|
|
|
+ )
|
|
|
+ ) : (
|
|
|
+ <div class={[styles.staffImgs, !loading.value && !activeItem.value?.id && styles.staffImgsEmpty]}>
|
|
|
+ {!loading.value && !activeItem.value?.id && (
|
|
|
+ <ElEmpty class={styles.empty} image={require("@/img/layout/empty.png")} description="暂无内容" />
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </NSpin>
|
|
|
+
|
|
|
+ <img
|
|
|
+ style={{
|
|
|
+ display: activeItem.value?.id ? "" : "none"
|
|
|
+ }}
|
|
|
+ class={[styles.goBtn]}
|
|
|
+ src={btnSubmit as any}
|
|
|
+ onClick={() => {
|
|
|
+ handleChangeAudio("pause")
|
|
|
+ goToCloud(activeItem.value.id, state.partXmlIndex, state.selectedTrack, musicRenderType.value)
|
|
|
+ }}
|
|
|
+ />
|
|
|
+
|
|
|
+ <div class={styles.rightBtns} style={{ display: activeItem.value.id ? "" : "none" }}>
|
|
|
+ <div style={{ display: state.musicPdfUrl || state.imgs.length > 0 ? "" : "none" }}>
|
|
|
+ <NTooltip showArrow={false}>
|
|
|
+ {{
|
|
|
+ trigger: () => (
|
|
|
+ <img
|
|
|
+ onClick={onDownload}
|
|
|
+ class={[styles.transBtn, (downloadStatus.value || staffLoading.value) && styles.disableBtn]}
|
|
|
+ src={iconDownload as any}
|
|
|
+ />
|
|
|
+ ),
|
|
|
+ default: "下载曲谱"
|
|
|
+ }}
|
|
|
+ </NTooltip>
|
|
|
+ </div>
|
|
|
+ <div
|
|
|
+ style={{ display: activeItem.value.musicSheetType === "CONCERT" || state.details.musicSheetType === "CONCERT" ? "" : "none" }}
|
|
|
+ >
|
|
|
+ <NPopselect
|
|
|
+ options={partColumns.value}
|
|
|
+ placement="bottom-end"
|
|
|
+ trigger="click"
|
|
|
+ v-model:value={state.selectedPartIndex}
|
|
|
+ scrollable
|
|
|
+ onUpdate:value={async (value: any) => {
|
|
|
+ const item = partColumns.value.find((item: any) => item.value === value)
|
|
|
+ state.selectedPartIndex = value
|
|
|
+ state.selectedPartName = item.instrumentName
|
|
|
+ state.selectedTrack = item.track
|
|
|
+ state.partXmlIndex = item.xmlIndex
|
|
|
+ state.imgs = []
|
|
|
+ nextTick(() => {
|
|
|
+ let tempPdf = ""
|
|
|
+ if (userStoreHook.roles === "GYM" || userStoreHook.roles === "KLX") {
|
|
|
+ tempPdf = item.musicPdfUrl
|
|
|
+ } else {
|
|
|
+ if (activeItem.value?.isScoreRender && value === 999) {
|
|
|
+ if (activeItem.value?.musicPdfUrl) {
|
|
|
+ tempPdf = activeItem.value?.musicPdfUrl
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ tempPdf = item.musicPdfUrl
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (tempPdf) {
|
|
|
+ state.musicPdfUrl = tempPdf
|
|
|
+ staffLoading.value = true
|
|
|
+ renderStaff()
|
|
|
+ } else {
|
|
|
+ state.musicPdfUrl = ""
|
|
|
+ loading.value = true
|
|
|
+ // 为了处理,之前是使用pdf渲染,现在又用osmd,iframe没有重新加载
|
|
|
+ if (state.iframeSrc.indexOf("pdf/web") !== -1) {
|
|
|
+ renderStaff()
|
|
|
+ } else {
|
|
|
+ resetRender()
|
|
|
+ }
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }}
|
|
|
+ class={["PopSelect", "PopSelectPart"]}
|
|
|
+ >
|
|
|
+ {{
|
|
|
+ empty: () => "暂无数据",
|
|
|
+ default: () => (
|
|
|
+ <NTooltip showArrow={false}>
|
|
|
+ {{
|
|
|
+ trigger: () => <img class={styles.transBtn} src={iconTransfer as any} />,
|
|
|
+ default: "切换声轨"
|
|
|
+ }}
|
|
|
+ </NTooltip>
|
|
|
+ )
|
|
|
+ }}
|
|
|
+ </NPopselect>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ {/* </ElScrollbar> */}
|
|
|
+
|
|
|
+ {state.list.length !== 0 && activeItem.value.audioFileUrl && (
|
|
|
+ <PlayItem
|
|
|
+ show={state.showPlayer}
|
|
|
+ playState={state.playState}
|
|
|
+ songPrevNextStatus={songPrevNextStatus.value}
|
|
|
+ item={activeItem.value}
|
|
|
+ onChange={value => handleChangeAudio(value)}
|
|
|
+ onShow={(status: boolean) => {
|
|
|
+ state.showPlayer = status
|
|
|
+ }}
|
|
|
+ />
|
|
|
+ )}
|
|
|
+ <PracticeForm v-model={isPracticeShow.value} practiceUrl={practiceUrl.value} onClose={handlePracticeClose} />
|
|
|
+ </NavContainer>
|
|
|
+ )
|
|
|
+ }
|
|
|
+})
|