123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- import {
- Transition,
- TransitionGroup,
- computed,
- defineComponent,
- nextTick,
- onMounted,
- reactive,
- ref
- } from 'vue';
- import styles from './index.module.less';
- import icon_back from './images/icon_back.svg';
- import icon_separator from './images/icon_separator.svg';
- import {
- NBreadcrumb,
- NBreadcrumbItem,
- NButton,
- NEmpty,
- NImage,
- NSpace,
- NSpin
- } from 'naive-ui';
- import TheSearch from '/src/components/TheSearch';
- import { IMusicItem } from './type';
- import icon_arrow from './images/icon_arrow.svg';
- import icon_play from './images/icon_play.svg';
- import icon_pause from './images/icon_pause.svg';
- import icon_goXiaoku from './images/icon_goXiaoku.svg';
- import icon_favitor from '/src/common/images/icon-collect-default.png';
- import icon_favitorActive from '/src/common/images/icon-collect-active.png';
- import { useRoute, useRouter } from 'vue-router';
- import PlayItem from './component/play-item';
- import PlayLoading from './component/play-loading';
- import TheNoticeBar from '/src/components/TheNoticeBar';
- import {
- api_materialFavorite,
- api_materialFavoriteStatus,
- api_musicSheetPage,
- api_subjectList
- } from '../xiaoku-ai/api';
- import { useUserStore } from '/src/store/modules/users';
- export default defineComponent({
- name: 'XiaokuMusic',
- setup() {
- const user = useUserStore();
- const route = useRoute();
- const router = useRouter();
- const forms = reactive({
- page: 1,
- rows: 20,
- status: true,
- keyword: '', // 关键词
- musicSheetCategoriesId: route.query.id || ''
- });
- const data = reactive({
- loading: false,
- finshed: false,
- reshing: false,
- tags: [] as any[],
- tagIndex: 0,
- list: [] as unknown as IMusicItem[],
- listActive: 0,
- playState: 'pause' as 'play' | 'pause',
- showPlayer: false
- });
- const getSubjects = async () => {
- const res = await api_subjectList();
- if (Array.isArray(res?.data)) {
- data.tags = [{ name: '全部', id: 0 }, ...res.data];
- }
- };
- const getList = async () => {
- data.loading = true;
- let res = {} as any;
- try {
- res = await api_musicSheetPage({
- ...forms,
- musicSubject: data.tagIndex ? data.tagIndex : ''
- });
- } catch (error) {
- console.log(error);
- }
- if (data.reshing) {
- data.list = [];
- data.reshing = false;
- }
- if (res?.code === 200 && Array.isArray(res?.data?.rows)) {
- data.list = [...data.list, ...res.data.rows];
- data.finshed = res.data.rows.length < forms.rows;
- console.log('🚀 ~ data.finshed:', data.finshed);
- }
- if (data.list[data.listActive]) {
- getFavitor(data.list[data.listActive]);
- }
- data.loading = false;
- };
- const handleGetList = () => {
- forms.page = 1;
- data.finshed = false;
- getList();
- };
- const spinRef = ref();
- const handleResh = () => {
- console.log(data.finshed);
- if (data.loading || data.finshed) return;
- forms.page = forms.page + 1;
- getList();
- };
- onMounted(async () => {
- getSubjects();
- await getList();
- const obv = new IntersectionObserver(entries => {
- if (entries[0].intersectionRatio > 0) {
- handleResh();
- }
- });
- nextTick(() => {
- obv.observe(spinRef.value);
- });
- });
- /** 查看收藏状态 */
- const getFavitor = async (item: any) => {
- const res = await api_materialFavoriteStatus({
- type: 'MUSIC',
- materialId: item.id
- });
- if (res?.code === 200) {
- item.favitor = res.data;
- }
- };
- /** 改变模仿的曲谱 */
- const handleChange = (item: IMusicItem) => {
- const index = data.list.findIndex(_item => _item.id === item.id);
- if (index > -1) {
- data.listActive = index;
- }
- getFavitor(item);
- };
- /** 选中的item */
- const activeItem = computed(() => {
- return data.list[data.listActive] || {};
- });
- /** 收藏曲谱 */
- const handleFavitor = () => {
- data.list[data.listActive].favitor = !data.list[data.listActive].favitor;
- api_materialFavorite({
- favoriteFlag: data.list[data.listActive].favitor,
- type: 'MUSIC',
- materialId: data.list[data.listActive].id
- });
- };
- /** 播放曲目 */
- const handlePlay = (item: IMusicItem) => {
- const index = data.list.findIndex(_item => _item.id === item.id);
- if (index > -1) {
- if (data.listActive === index) {
- data.playState = data.playState === 'play' ? 'pause' : 'play';
- } else {
- data.playState = 'play';
- }
- data.showPlayer = true;
- data.listActive = index;
- }
- };
- /** 音频控制 */
- const handleChangeAudio = (
- type: 'play' | 'pause' | 'pre' | 'next' | 'favitor'
- ) => {
- if (type === 'play') {
- data.playState = 'play';
- } else if (type === 'pause') {
- data.playState = 'pause';
- } else if (type === 'pre') {
- if (data.list[data.listActive - 1]) {
- handlePlay(data.list[data.listActive - 1]);
- }
- } else if (type === 'next') {
- if (data.list[data.listActive + 1]) {
- handlePlay(data.list[data.listActive + 1]);
- }
- } else if (type === 'favitor') {
- handleFavitor();
- }
- };
- return () => (
- <div class={styles.container}>
- <NSpace align="center" wrapItem={false} size={16}>
- <img
- style={{ cursor: 'pointer' }}
- src={icon_back}
- onClick={() => router.push({ path: '/xiaoku-ai' })}
- />
- <NBreadcrumb separator="">
- <NBreadcrumbItem
- onClick={() => router.push({ path: '/xiaoku-ai' })}>
- 曲谱列表
- </NBreadcrumbItem>
- <img class={styles.separator} src={icon_separator} />
- <NBreadcrumbItem>{route.query.name}</NBreadcrumbItem>
- </NBreadcrumb>
- </NSpace>
- <div
- class={styles.wrap}
- style={{ paddingBottom: data.showPlayer ? '108Px' : '' }}>
- <div class={styles.content}>
- <div class={styles.tools}>
- <NSpace
- style={{ width: '100%' }}
- size={[24, 12]}
- wrapItem={false}>
- {data.tags.map(item => (
- <NButton
- round
- textColor={data.tagIndex === item.id ? '#fff' : '#000'}
- color={data.tagIndex === item.id ? '#198CFE' : '#fff'}
- onClick={() => {
- data.tagIndex = item.id;
- data.reshing = true;
- handleGetList();
- }}>
- {item.name}
- </NButton>
- ))}
- </NSpace>
- <TheSearch
- style={{ marginLeft: 'auto' }}
- round
- onSearch={val => {
- forms.keyword = val;
- data.reshing = true;
- handleGetList();
- }}
- />
- </div>
- <div class={styles.contentWrap}>
- <div class={styles.musicList}>
- <div class={styles.wrapList}>
- {data.list.map((item: IMusicItem, index) => {
- return (
- <div class={styles.itemContainer}>
- <div
- class={[
- styles.item,
- data.listActive === index && styles.active
- ]}
- onClick={() => handleChange(item)}>
- <div class={styles.img}>
- <NImage
- lazy
- objectFit="cover"
- previewDisabled={true}
- src={item.titleImg}
- onLoad={e => {
- (e.target as any).dataset.loaded = 'true';
- }}
- />
- <PlayLoading
- class={[
- data.listActive === index &&
- data.playState === 'play'
- ? ''
- : styles.showPlayLoading
- ]}
- />
- </div>
- <div class={styles.title}>
- <div class={styles.titleName}>
- <TheNoticeBar text={item.musicSheetName} />
- </div>
- <div class={styles.titleDes}>{item.composer}</div>
- </div>
- <NButton
- color="#259CFE"
- textColor="#fff"
- round
- class={styles.btn}
- type="primary"
- onClick={(e: Event) => {
- e.stopPropagation();
- handlePlay(item);
- }}>
- 试听
- <img
- src={
- data.listActive === index &&
- data.playState === 'play'
- ? icon_pause
- : icon_play
- }
- />
- </NButton>
- <img class={styles.arrow} src={icon_arrow} />
- </div>
- </div>
- );
- })}
- {!data.finshed && (
- <div ref={spinRef} class={styles.loadingWrap}>
- <NSpin show={true}></NSpin>
- </div>
- )}
- {!data.loading && data.list.length === 0 && (
- <div class={styles.empty}>
- <NEmpty />
- </div>
- )}
- </div>
- </div>
- <div class={styles.musicStaff}>
- <div class={styles.musicName}>
- {activeItem.value.musicSheetName}
- </div>
- <img
- style={{ display: activeItem.value.id ? '' : 'none' }}
- class={styles.goBtn}
- src={icon_goXiaoku}
- onClick={() => {
- handleChangeAudio('pause');
- const origin = /(localhost|192)/.test(location.host)
- ? 'https://test.lexiaoya.cn'
- : location.origin;
- const src = `${origin}/instrument?platform=pc&id=${activeItem.value.id}&Authorization=${user.getToken}`;
- window.open(src);
- }}
- />
- <div
- style={{ display: activeItem.value.id ? '' : 'none' }}
- class={styles.favitor}
- onClick={() => handleFavitor()}>
- <Transition name="favitor" mode="out-in">
- {activeItem.value.favitor ? (
- <img src={icon_favitorActive} key="1" />
- ) : (
- <img src={icon_favitor} key="2" />
- )}
- </Transition>
- </div>
- <div class={styles.staffImgs}>
- <TransitionGroup name="van-fade">
- {activeItem.value?.firstTone
- ?.split(',')
- .map((item, index) => {
- return <img src={item} key={item} />;
- })}
- </TransitionGroup>
- </div>
- </div>
- </div>
- </div>
- </div>
- {data.list.length !== 0 && (
- <PlayItem
- show={data.showPlayer}
- playState={data.playState}
- item={activeItem.value}
- onChange={value => handleChangeAudio(value)}
- />
- )}
- </div>
- );
- }
- });
|