liushengqiang před 1 rokem
rodič
revize
bd6f9c7d4e

binární
src/components/m-empty/images/icon_empty.png


+ 4 - 3
src/components/m-empty/index.tsx

@@ -4,6 +4,7 @@ import { Button, Empty } from 'vant';
 import iconEmpty from './images/empty.png';
 import iconNetwork from './images/network.png';
 import icon404 from './images/404.png';
+import icon_empty from './images/icon_empty.png';
 
 export default defineComponent({
   name: 'm-empty',
@@ -13,8 +14,8 @@ export default defineComponent({
       default: ''
     },
     image: {
-      type: String as PropType<'empty' | 'network' | '404'>,
-      default: 'empty'
+      type: String as PropType<'empty' | 'network' | '404' | 'icon_empty'>,
+      default: 'icon_empty'
     },
     showButton: {
       type: Boolean,
@@ -28,7 +29,7 @@ export default defineComponent({
   emits: ['click'],
   setup(props, { emit }) {
     const forms = reactive({
-      image: iconEmpty
+      image: icon_empty
     });
 
     onMounted(() => {

+ 1 - 7
src/router/router-root.ts

@@ -37,13 +37,7 @@ export default [
       title: '课件播放'
     }
   },
-  {
-    path: '/co-ai',
-    component: () => import('@/views/co-ai/index'),
-    meta: {
-      title: '小酷AI'
-    }
-  },
+  
   {
     path: '/payment-result',
     name: 'payment-result',

+ 8 - 1
src/router/routes-common.ts

@@ -98,7 +98,14 @@ export default [
         meta: {
           title: '领取详情'
         }
-      }
+      },
+      {
+        path: '/co-ai',
+        component: () => import('@/views/co-ai/index'),
+        meta: {
+          title: '小酷AI'
+        }
+      },
     ]
   },
   ...rootRouter

+ 17 - 0
src/views/co-ai/api.ts

@@ -0,0 +1,17 @@
+import request from '@/helpers/request';
+
+/** 获取教材列表 */
+export const api_musicSheetCategoriesPage = (params: any) => {
+  return request.post('/edu-app/musicSheetCategories/page', {
+    data: params
+  });
+};
+
+/**
+ * 曲谱列表分页
+ */
+export const api_musicSheetPage = (params: any) => {
+  return request.post('/edu-app/musicSheet/page', {
+    data: params
+  });
+};

+ 27 - 0
src/views/co-ai/index.module.less

@@ -87,6 +87,7 @@
 
         &.typeActive {
             .typeImg {
+                padding: 6px;
                 border-color: #99FFD0;
                 animation: scaleBtn 1s ease-in-out;
             }
@@ -109,6 +110,11 @@
         width: 100%;
         height: 100%;
         object-fit: cover;
+        opacity: 0;
+        transition: opacity .3s;
+    }
+    .typeIcon[loaded="true"] {
+        opacity: 1;
     }
 }
 
@@ -182,6 +188,11 @@
         object-fit: cover;
         flex-shrink: 0;
         margin-right: 1vw;
+        opacity: 0;
+        transition: opacity .3s;
+    }
+    .musicAvtor[loaded="true"] {
+        opacity: 1;
     }
 
     .musicInfo {
@@ -300,4 +311,20 @@
     to {
         opacity: 1;
     }
+}
+.loadingWrap {
+    display: flex;
+    justify-content: center;
+    min-height: 80Px;
+}
+.empty{
+    :global{
+        .van-empty__image{
+            width: 50%;
+            height: initial;
+        }
+        .van-empty__description{
+            color: #fff;
+        }
+    }
 }

+ 144 - 23
src/views/co-ai/index.tsx

@@ -1,8 +1,22 @@
-import { TransitionGroup, defineComponent, reactive, ref } from 'vue';
+import {
+  TransitionGroup,
+  defineComponent,
+  nextTick,
+  onMounted,
+  reactive,
+  ref
+} from 'vue';
 import styles from './index.module.less';
 import MSearch from '@/components/m-search';
 import icon_play from '@/common/images/icon_play.svg';
-import { NoticeBar, showLoadingToast, showToast } from 'vant';
+import {
+  Empty,
+  List,
+  Loading,
+  NoticeBar,
+  showLoadingToast,
+  showToast
+} from 'vant';
 import icon_back from './image/icon_back.svg';
 import icon_down from '@/common/images/icon_down.svg';
 import icon_jianpu from '@/common/images/icon_jianpu.svg';
@@ -11,16 +25,24 @@ import icons from '@/common/images/index.json';
 import { postMessage, promisefiyPostMessage } from '@/helpers/native-message';
 import { rows } from './data.json';
 import html2canvas from 'html2canvas';
+import { api_musicSheetCategoriesPage, api_musicSheetPage } from './api';
+import { state } from '@/state';
+import MEmpty from '@/components/m-empty';
 export default defineComponent({
   name: 'co-ai',
   setup() {
-    const types = [
-      { src: 'https://daya.ks3-cn-beijing.ksyuncs.com/16880147803671.png' },
-      { src: 'https://daya.ks3-cn-beijing.ksyuncs.com/16880147833062.png' },
-      { src: 'https://daya.ks3-cn-beijing.ksyuncs.com/16880147854153.png' },
-      { src: 'https://daya.ks3-cn-beijing.ksyuncs.com/16880147881254.png' },
-      { src: 'https://daya.ks3-cn-beijing.ksyuncs.com/16880147939485.png' }
-    ];
+    const categorForms = reactive({
+      page: 1,
+      rows: 999,
+      subjectId: state.user.data?.subjectId || ''
+    });
+    const musicForms = reactive({
+      page: 1,
+      rows: 20,
+      status: true,
+      keyword: '', // 关键词
+      musicSheetCategoriesId: ''
+    });
     const titles = rows;
     const data = reactive({
       /** 教材Index */
@@ -28,7 +50,13 @@ export default defineComponent({
       /** 音乐Index */
       musicIndex: 0,
       /** 显示简谱 */
-      isShowJianpu: false
+      isShowJianpu: false,
+      /** 教材列表 */
+      types: [] as any[],
+      /** 音乐列表 */
+      musics: [] as any[],
+      loading: true,
+      finshed: false
     });
     const downRef = ref();
     // 返回
@@ -38,8 +66,9 @@ export default defineComponent({
     /** 去云教练 */
     const handleGoto = () => {
       let src = `${location.origin}/instrument?id=${
-        titles[data.musicIndex]?.id
+        data.musics[data.musicIndex]?.id
       }`;
+      console.log(src)
       postMessage({
         api: 'openAccompanyWebView',
         content: {
@@ -83,6 +112,66 @@ export default defineComponent({
         }, 500);
       }
     };
+
+    /** 获取音乐教材列表 */
+    const getMusicSheetCategories = async () => {
+      try {
+        const res = await api_musicSheetCategoriesPage({
+          ...categorForms
+        });
+        if (res.code === 200 && Array.isArray(res?.data?.rows)) {
+          data.types = res.data.rows;
+          if (!musicForms.musicSheetCategoriesId && data.types.length > 0) {
+            musicForms.musicSheetCategoriesId = data.types[0].id;
+          }
+        }
+      } catch (error) {
+        console.log('🚀 ~ error:', error);
+      }
+    };
+
+    /** 获取曲谱列表 */
+    const getMusicList = async () => {
+      data.loading = true;
+      try {
+        const res = await api_musicSheetPage({
+          ...musicForms
+        });
+        if (res.code === 200 && Array.isArray(res?.data?.rows)) {
+          data.musics = [...data.musics, ...res.data.rows];
+          data.finshed = !res.data.next;
+        }
+      } catch (error) {
+        console.log('🚀 ~ error:', error);
+      }
+      data.loading = false;
+    };
+    const handleReset = () => {
+      musicForms.page = 1;
+      data.musics = [];
+      getMusicList();
+    };
+
+    const spinRef = ref();
+    const handleResh = () => {
+      if (data.loading || data.finshed) return;
+      musicForms.page = musicForms.page + 1;
+      getMusicList();
+    };
+
+    onMounted(async () => {
+      await getMusicSheetCategories();
+      getMusicList();
+
+      const obv = new IntersectionObserver(entries => {
+        if (entries[0].intersectionRatio > 0) {
+          handleResh();
+        }
+      });
+      nextTick(() => {
+        obv.observe(spinRef.value);
+      });
+    });
     return () => (
       <div class={styles.container}>
         <div class={styles.back} onClick={goback}>
@@ -93,16 +182,27 @@ export default defineComponent({
             <div class={styles.leftBg2}></div>
             <div class={styles.leftBg}></div>
             <div class={styles.types}>
-              {types.map((item, index) => {
+              {data.types.map((item, index) => {
                 return (
                   <div
                     class={[
                       styles.type,
-                      data.typeIndex === index && styles.typeActive
+                      musicForms.musicSheetCategoriesId === item.id &&
+                        styles.typeActive
                     ]}
-                    onClick={() => (data.typeIndex = index)}>
+                    onClick={() => {
+                      musicForms.musicSheetCategoriesId = item.id;
+                      handleReset();
+                    }}>
                     <div class={styles.typeImg}>
-                      <img class={styles.typeIcon} src={item.src} />
+                      <img
+                        class={styles.typeIcon}
+                        src={item.coverImg}
+                        onLoad={(e: Event) => {
+                          const el = e.target as HTMLImageElement;
+                          el.setAttribute('loaded', 'true');
+                        }}
+                      />
                     </div>
                   </div>
                 );
@@ -113,9 +213,13 @@ export default defineComponent({
                 shape="round"
                 background="transparent"
                 placeholder="请输入曲目名称"
+                onSearch={val => {
+                  musicForms.keyword = val;
+                  handleReset();
+                }}
               />
               <div class={styles.musicContent}>
-                {titles.map((item, index) => {
+                {data.musics.map((item: any, index: number) => {
                   return (
                     <div
                       class={[
@@ -125,7 +229,14 @@ export default defineComponent({
                           : styles.disableNotic
                       ]}
                       onClick={() => (data.musicIndex = index)}>
-                      <img class={styles.musicAvtor} src={item.titleImg} />
+                      <img
+                        class={styles.musicAvtor}
+                        src={item.titleImg}
+                        onLoad={(e: Event) => {
+                          const el = e.target as HTMLImageElement;
+                          el.setAttribute('loaded', 'true');
+                        }}
+                      />
                       <div class={styles.musicInfo}>
                         <div class={styles.musicName}>
                           <NoticeBar
@@ -136,7 +247,7 @@ export default defineComponent({
                           />
                         </div>
                         <div class={styles.musicDes}>
-                          <div class={styles.musicFavitor}>{item.updateBy}</div>
+                          <div class={styles.musicFavitor}>{item.usedNum}</div>
                           <div class={[styles.musicAuthor, 'van-ellipsis']}>
                             {item.composer}
                           </div>
@@ -146,20 +257,30 @@ export default defineComponent({
                     </div>
                   );
                 })}
+                {!data.finshed && (
+                  <div ref={spinRef} class={styles.loadingWrap}>
+                    <Loading color="#259CFE" />
+                  </div>
+                )}
+                {!data.loading && data.musics.length === 0 && (
+                  <div class={styles.empty}>
+                    <MEmpty description="暂无曲谱" />
+                  </div>
+                )}
               </div>
             </div>
           </div>
           <div class={[styles.opacityBg, styles.right]}>
             <div ref={downRef}>
               <div class={styles['right-musicName']}>
-                {titles[data.musicIndex].musicSheetName}
+                {data.musics[data.musicIndex]?.musicSheetName}
               </div>
               {data.isShowJianpu ? (
                 <>
                   <TransitionGroup name="van-fade">
-                    {titles[data.musicIndex]?.firstTone
+                    {data.musics[data.musicIndex]?.firstTone
                       ?.split(',')
-                      .map((item, index) => {
+                      .map((item: any, index: number) => {
                         return (
                           <img
                             class={styles.staff}
@@ -173,9 +294,9 @@ export default defineComponent({
               ) : (
                 <>
                   <TransitionGroup name="van-fade">
-                    {titles[data.musicIndex]?.musicImg
+                    {data.musics[data.musicIndex]?.musicImg
                       ?.split(',')
-                      .map((item, index) => {
+                      .map((item: any, index: number) => {
                         return (
                           <img
                             class={styles.staff}