|  | @@ -3,7 +3,10 @@ import {
 | 
	
		
			
				|  |  |    TransitionGroup,
 | 
	
		
			
				|  |  |    computed,
 | 
	
		
			
				|  |  |    defineComponent,
 | 
	
		
			
				|  |  | -  reactive
 | 
	
		
			
				|  |  | +  nextTick,
 | 
	
		
			
				|  |  | +  onMounted,
 | 
	
		
			
				|  |  | +  reactive,
 | 
	
		
			
				|  |  | +  ref
 | 
	
		
			
				|  |  |  } from 'vue';
 | 
	
		
			
				|  |  |  import styles from './index.module.less';
 | 
	
		
			
				|  |  |  import icon_back from './images/icon_back.svg';
 | 
	
	
		
			
				|  | @@ -12,11 +15,12 @@ import {
 | 
	
		
			
				|  |  |    NBreadcrumb,
 | 
	
		
			
				|  |  |    NBreadcrumbItem,
 | 
	
		
			
				|  |  |    NButton,
 | 
	
		
			
				|  |  | +  NEmpty,
 | 
	
		
			
				|  |  |    NImage,
 | 
	
		
			
				|  |  | -  NSpace
 | 
	
		
			
				|  |  | +  NSpace,
 | 
	
		
			
				|  |  | +  NSpin
 | 
	
		
			
				|  |  |  } from 'naive-ui';
 | 
	
		
			
				|  |  |  import TheSearch from '/src/components/TheSearch';
 | 
	
		
			
				|  |  | -import listData from './data.json';
 | 
	
		
			
				|  |  |  import { IMusicItem } from './type';
 | 
	
		
			
				|  |  |  import icon_arrow from './images/icon_arrow.svg';
 | 
	
		
			
				|  |  |  import icon_play from './images/icon_play.svg';
 | 
	
	
		
			
				|  | @@ -24,30 +28,89 @@ 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 { useRouter } from 'vue-router';
 | 
	
		
			
				|  |  | +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_musicSheetPage, api_subjectList } from '../xiaoku-ai/api';
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  export default defineComponent({
 | 
	
		
			
				|  |  |    name: 'XiaokuMusic',
 | 
	
		
			
				|  |  |    setup() {
 | 
	
		
			
				|  |  | +    const route = useRoute();
 | 
	
		
			
				|  |  |      const router = useRouter();
 | 
	
		
			
				|  |  | +    const forms = reactive({
 | 
	
		
			
				|  |  | +      page: 1,
 | 
	
		
			
				|  |  | +      rows: 20,
 | 
	
		
			
				|  |  | +      status: true,
 | 
	
		
			
				|  |  | +      keyword: '' // 关键词
 | 
	
		
			
				|  |  | +      // musicSheetCategoriesId: route.query.id || ''
 | 
	
		
			
				|  |  | +    });
 | 
	
		
			
				|  |  |      const data = reactive({
 | 
	
		
			
				|  |  | -      tags: [
 | 
	
		
			
				|  |  | -        { name: '全部', id: 0 },
 | 
	
		
			
				|  |  | -        { name: '竖笛', id: 1 },
 | 
	
		
			
				|  |  | -        { name: '排箫', id: 2 },
 | 
	
		
			
				|  |  | -        { name: '口风琴', id: 3 },
 | 
	
		
			
				|  |  | -        { name: '陶笛', id: 4 },
 | 
	
		
			
				|  |  | -        { name: '葫芦丝', id: 5 }
 | 
	
		
			
				|  |  | -      ],
 | 
	
		
			
				|  |  | +      loading: false,
 | 
	
		
			
				|  |  | +      finshed: false,
 | 
	
		
			
				|  |  | +      reshing: false,
 | 
	
		
			
				|  |  | +      tags: [] as any[],
 | 
	
		
			
				|  |  |        tagIndex: 0,
 | 
	
		
			
				|  |  | -      list: listData.rows as unknown as IMusicItem[],
 | 
	
		
			
				|  |  | +      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);
 | 
	
		
			
				|  |  | +      }
 | 
	
		
			
				|  |  | +      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 handleChange = (item: IMusicItem) => {
 | 
	
	
		
			
				|  | @@ -114,90 +177,115 @@ export default defineComponent({
 | 
	
		
			
				|  |  |                曲谱列表
 | 
	
		
			
				|  |  |              </NBreadcrumbItem>
 | 
	
		
			
				|  |  |              <img class={styles.separator} src={icon_separator} />
 | 
	
		
			
				|  |  | -            <NBreadcrumbItem>一年级上册人教版(2013版)</NBreadcrumbItem>
 | 
	
		
			
				|  |  | +            <NBreadcrumbItem>{route.query.name}</NBreadcrumbItem>
 | 
	
		
			
				|  |  |            </NBreadcrumb>
 | 
	
		
			
				|  |  |          </NSpace>
 | 
	
		
			
				|  |  | -        <div class={styles.wrap}>
 | 
	
		
			
				|  |  | +        <div
 | 
	
		
			
				|  |  | +          class={styles.wrap}
 | 
	
		
			
				|  |  | +          style={{ paddingBottom: data.showPlayer ? '108Px' : '' }}>
 | 
	
		
			
				|  |  |            <div class={styles.content}>
 | 
	
		
			
				|  |  |              <div class={styles.tools}>
 | 
	
		
			
				|  |  | -              <div class={styles.tags}>
 | 
	
		
			
				|  |  | -                <NSpace size={[24, 12]} wrap={false}>
 | 
	
		
			
				|  |  | -                  {data.tags.map((item, index) => (
 | 
	
		
			
				|  |  | -                    <NButton
 | 
	
		
			
				|  |  | -                      round
 | 
	
		
			
				|  |  | -                      textColor={data.tagIndex === index ? '#fff' : '#000'}
 | 
	
		
			
				|  |  | -                      color={data.tagIndex === index ? '#198CFE' : '#fff'}
 | 
	
		
			
				|  |  | -                      onClick={() => (data.tagIndex = index)}>
 | 
	
		
			
				|  |  | -                      {item.name}
 | 
	
		
			
				|  |  | -                    </NButton>
 | 
	
		
			
				|  |  | -                  ))}
 | 
	
		
			
				|  |  | -                </NSpace>
 | 
	
		
			
				|  |  | -              </div>
 | 
	
		
			
				|  |  | -              <TheSearch round />
 | 
	
		
			
				|  |  | +              <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}
 | 
	
		
			
				|  |  | -              style={{ paddingBottom: data.showPlayer ? '90px' : '' }}>
 | 
	
		
			
				|  |  | +            <div class={styles.contentWrap}>
 | 
	
		
			
				|  |  |                <div class={styles.musicList}>
 | 
	
		
			
				|  |  |                  <div class={styles.wrapList}>
 | 
	
		
			
				|  |  |                    {data.list.map((item: IMusicItem, index) => {
 | 
	
		
			
				|  |  |                      return (
 | 
	
		
			
				|  |  | -                      <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 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>
 | 
	
		
			
				|  |  | -                          <div class={styles.titleDes}>{item.composer}</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>
 | 
	
		
			
				|  |  | -                        <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>
 | 
	
		
			
				|  |  |                      );
 | 
	
		
			
				|  |  |                    })}
 | 
	
		
			
				|  |  | +                  {!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>
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -206,18 +294,22 @@ export default defineComponent({
 | 
	
		
			
				|  |  |                    {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://dev.kt.colexiu.com'
 | 
	
		
			
				|  |  | +                      ? 'https://test.lexiaoya.cn'
 | 
	
		
			
				|  |  |                        : location.origin;
 | 
	
		
			
				|  |  |                      const src = `${origin}/instrument?platform=pc&id=${activeItem.value.id}`;
 | 
	
		
			
				|  |  |                      window.open(src);
 | 
	
		
			
				|  |  |                    }}
 | 
	
		
			
				|  |  |                  />
 | 
	
		
			
				|  |  | -                <div class={styles.favitor} onClick={() => handleFavitor()}>
 | 
	
		
			
				|  |  | +                <div
 | 
	
		
			
				|  |  | +                  style={{ display: activeItem.value.id ? '' : 'none' }}
 | 
	
		
			
				|  |  | +                  class={styles.favitor}
 | 
	
		
			
				|  |  | +                  onClick={() => handleFavitor()}>
 | 
	
		
			
				|  |  |                    <Transition name="favitor" mode="out-in">
 | 
	
		
			
				|  |  |                      {activeItem.value.delFlag ? (
 | 
	
		
			
				|  |  |                        <img src={icon_favitorActive} key="1" />
 |