123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403 |
- import OEmpty from '@/components/o-empty'
- import { postMessage } from '@/helpers/native-message'
- import request from '@/helpers/request'
- import { state } from '@/state'
- import OFullRefresh from '@/components/o-full-refresh'
- import {
- Cell,
- CellGroup,
- DropdownItem,
- DropdownMenu,
- Icon,
- List,
- Picker,
- Popup,
- Toast,
- closeToast,
- showLoadingToast
- } from 'vant'
- import { defineComponent, reactive, ref, onMounted, nextTick, computed } from 'vue'
- import { useRoute, useRouter } from 'vue-router'
- import { getImage } from './images'
- import styles from './index.module.less'
- import OSticky from '@/components/o-sticky'
- import OSearch from '@/components/o-search'
- import OHeader from '@/components/o-header'
- import { getInstrumentName } from '@/constant/instruments'
- import { browser } from '@/helpers/utils'
- export default defineComponent({
- name: 'accompany-music-list',
- props: {
- musicTree: {
- type: Array,
- default: () => []
- }
- },
- setup() {
- const route = useRoute()
- const router = useRouter()
- const imgDefault = getImage('icon-music.svg')
- const userInfo = ref<any>({})
- const subjectKey = state.user?.data?.phone || 'accompany-music-list-subject'
- const subjectId =
- localStorage.getItem(subjectKey) || state.user?.data?.subjectId?.split(',')?.[0] || ''
- const data = reactive({
- loading: false,
- firstRender: false,
- finished: false,
- refreshing: false,
- musicTree: [] as any,
- pagenation: {
- page: 1,
- rows: 20
- },
- value1: null,
- value2: null,
- PopoverOpen: false,
- list: [] as any,
- keyword: '',
- musicSubject: subjectId,
- subjectList: [] as any
- })
- const getTree = async () => {
- try {
- // const res: any = await request.get(
- // state.platformApi + '/musicSheetCategories/queryTree?enable=true&parentId=' + route.query.categorieid
- // )
- const res: any = await request.post(
- state.platformApi + '/musicSheetCategories/queryTreeByParentId', {
- data: {
- parentId: route.query.categorieid,
- enable: true
- }
- }
- )
- if (Array.isArray(res?.data)) {
- data.musicTree = res.data
- }
- nextTick(() => {
- getList()
- })
- } catch (error) {
- console.log(error)
- }
- }
- // 获取声部信息
- const getSubjects = async () => {
- try {
- const subjects = await request.get(state.platformApi + '/subject/musicList', {
- params: {
- enableFlag: true,
- page: 1,
- rows: 100
- }
- })
- const rows = subjects.data || []
- rows.forEach((item: any) => {
- data.subjectList.push({
- text: item.name,
- value: item.id + ''
- })
- })
- } catch {
- //
- }
- }
- /**获取会员购买记录 */
- const getUserInfo = async () => {
- try {
- const res: any = await request.get(`/api-student/student/member`)
- userInfo.value = res.data || {}
- } catch (error) {
- console.log(error)
- }
- }
- const option1 = computed(() => {
- const v1: any = data.musicTree
- //.find((n: any) => n.id == route.query.categorieid)
- if (Array.isArray(v1)) {
- const list = v1.map((m: any) => {
- if (!data.value1) {
- data.value1 = m.id
- data.value2 = null
- }
- return {
- text: m.name,
- value: m.id
- }
- })
- return list
- }
- return []
- })
- const option2 = computed(() => {
- const v1: any = data.musicTree
- // .find((n: any) => n.id == route.query.categorieid)
- console.log(v1, '---')
- if (Array.isArray(v1)) {
- const v2: any = v1?.find((n: any) => n.id == data.value1)
- if (Array.isArray(v2?.musicSheetCategoriesList)) {
- const list = [{ text: '全部', value: null }].concat(
- v2.musicSheetCategoriesList.map((m: any) => {
- return {
- text: m.name,
- value: m.id
- }
- })
- )
- return list
- }
- }
- return [{ text: '全部', value: null }]
- })
- const getList = async () => {
- if (data.loading) return
- data.loading = true
- const bodyData: any = {
- ...data.pagenation,
- keyword: data.keyword,
- musicSheetCategoriesId: data.value2 || data.value1,
- status: 1
- }
- if (state.platformType == 'TEACHER') {
- bodyData.musicSubject = data.musicSubject
- }
- try {
- const res: any = await request.post(state.platformApi + '/musicSheet/page', {
- data: bodyData,
- hideLoading: true
- })
- if (Array.isArray(res?.data?.rows)) {
- data.list = [].concat(data.list, res.data.rows)
- data.pagenation.page += 1
- data.finished = res.data.rows.length < data.pagenation.rows ? true : false
- } else {
- data.finished = true
- }
- } catch (error) {
- data.finished = true
- }
- data.loading = false
- data.refreshing = false
- data.firstRender = true
- }
- // 重置搜索
- const onSearch = () => {
- data.pagenation.page = 1
- data.list = []
- data.finished = false
- data.list = []
- getList()
- }
- //进入云练习
- const openView = async (item: any) => {
- const src = `${location.origin}/orchestra-music-score/?id=${item.id}&part-index=${staffData.partIndex}`
- console.log('🚀 ~ src:', src)
- postMessage({
- api: 'openAccompanyWebView',
- content: {
- url: src,
- orientation: 0,
- isHideTitle: true,
- statusBarTextColor: false,
- isOpenLight: true
- }
- })
- }
- onMounted(() => {
- if (state.platformType == 'STUDENT') {
- getUserInfo()
- }
- if (state.platformType == 'TEACHER') {
- getSubjects()
- }
- getTree()
- })
- const staffData = reactive({
- open: false,
- musicXml: {} as any,
- instrumentName: '',
- partIndex: 0,
- partList: [] as any[]
- })
- const getPartNames = async (item: any) => {
- let partNames: any[] = []
- // showLoadingToast('加载中...')
- // try {
- // const res = await fetch(xmlUrl).then((response) => response.text())
- // const xml = new DOMParser().parseFromString(res, 'text/xml')
- // let parts = Array.from(xml.getElementsByTagName('part-name'))
- // parts = parts.filter((n) => !n.textContent?.toLocaleUpperCase()?.includes('COMMON'))
- // for (let i = 0; i < parts.length; i++) {
- // const name = getInstrumentName(parts[i].textContent || '')
- // partNames.push({ text: name ? parts[i].textContent + `(${name})` : parts[i].textContent || '', value: i })
- // }
- // closeToast()
- // } catch (error) {
- // console.log(error)
- // }
- try {
- const { data } = await request.get(state.platformApi + '/musicSheet/detail/' + item.id)
- let partList = data.background || []
- partList = partList.filter(
- (item: any) => !item.track?.toLocaleUpperCase()?.includes('COMMON')
- )
- partNames = partList.map((item: any, index: number) => {
- const instrumentName = getInstrumentName(item.track)
- return {
- text: item.track + (instrumentName ? `(${instrumentName})` : ''),
- value: index
- }
- })
- } catch (error) {
- console.log(error)
- }
- console.log('🚀 ~ partNames:', partNames)
- return partNames
- }
- const openMutilPart = async (item: any) => {
- if (staffData.musicXml[item.id]) {
- staffData.instrumentName = item.id
- staffData.open = true
- return Promise.resolve()
- }
- staffData.musicXml[item.id] = await getPartNames(item)
- staffData.instrumentName = item.id
- staffData.open = true
- }
- return () => (
- <div class={styles['accompany-music-list']}>
- <OSticky
- mode="sticky"
- class={styles.heade}
- onGetHeight={(height: number) => {
- document.documentElement.style.setProperty('--header-height', height + 'px')
- }}
- >
- <OHeader border={false} />
- <div>
- <DropdownMenu activeColor="var(--van-primary)">
- <DropdownItem
- v-model:modelValue={data.value1}
- options={option1.value}
- onChange={() => {
- data.value2 = null
- onSearch()
- }}
- ></DropdownItem>
- <DropdownItem
- v-model:modelValue={data.value2}
- options={option2.value as any}
- onChange={() => onSearch()}
- ></DropdownItem>
- </DropdownMenu>
- <div class={styles.filter}>
- <OSearch
- class={styles.filterBox}
- onSearch={(keyword: string) => {
- data.keyword = keyword
- onSearch()
- }}
- >
- {{
- left: () => (
- <>
- {state.platformType == 'TEACHER' ? (
- <DropdownMenu activeColor="var(--van-primary)">
- <DropdownItem
- v-model:modelValue={data.musicSubject}
- options={data.subjectList}
- onChange={() => {
- localStorage.setItem(subjectKey, data.musicSubject)
- onSearch()
- }}
- ></DropdownItem>
- </DropdownMenu>
- ) : null}
- </>
- )
- }}
- </OSearch>
- </div>
- </div>
- </OSticky>
- <OFullRefresh
- v-model:modelValue={data.refreshing}
- onRefresh={onSearch}
- style="min-height: calc(100vh - var(--header-height))"
- >
- <List
- loading-text=" "
- immediateCheck={false}
- loading={data.loading}
- v-model:finished={data.finished}
- finishedText=" "
- onLoad={() => {
- getList()
- }}
- >
- <CellGroup inset>
- {data.list.map((item: any) => {
- return (
- <Cell
- size="large"
- center
- title={item.musicSheetName}
- isLink
- onClick={() => {
- if (browser().isApp) {
- const url = `${location.origin}${location.pathname}#/musicDetail?id=${item.id}`
- postMessage({
- api: 'openWebView',
- content: {
- url,
- orientation: 1,
- isHideTitle: true,
- statusBarTextColor: false,
- isOpenLight: false
- }
- })
- } else {
- router.push({
- path: '/musicDetail',
- query: {
- id: item.id
- }
- })
- }
- }}
- >
- {{
- icon: () => (
- <Icon style={{ marginRight: '12px' }} size={40} name={imgDefault} />
- )
- }}
- </Cell>
- )
- })}
- </CellGroup>
- <div style={{ height: '40px' }}></div>
- </List>
- {data.firstRender && !data.loading && !data.list.length && <OEmpty tips="暂无曲谱" />}
- </OFullRefresh>
- <Popup teleport="body" position="bottom" round v-model:show={staffData.open}>
- <Picker
- columns={staffData.musicXml[staffData.instrumentName]}
- onConfirm={(value) => {
- staffData.open = false
- staffData.partIndex = value.selectedValues[0]
- openView({ id: staffData.instrumentName })
- }}
- onCancel={() => (staffData.open = false)}
- />
- </Popup>
- </div>
- )
- }
- })
|