lex-xin 5 месяцев назад
Родитель
Сommit
d3e3a82020
2 измененных файлов с 292 добавлено и 275 удалено
  1. 48 2
      src/views/hot-music-more/index.module.less
  2. 244 273
      src/views/hot-music-more/index.tsx

+ 48 - 2
src/views/hot-music-more/index.module.less

@@ -285,6 +285,7 @@
     padding-top: 18px;
     display: flex;
     align-items: center;
+    position: relative;
 
     font-size: 16px;
     font-weight: 500;
@@ -300,6 +301,20 @@
       border-radius: 3px;
       margin-right: 6px;
     }
+
+    span {
+      position: absolute;
+      right: 0;
+      font-size: 12px;
+      color: #333333;
+      font-weight: 400;
+
+      :global {
+        .van-icon {
+          margin-left: 4px;
+        }
+      }
+    }
   }
 }
 
@@ -350,8 +365,9 @@
         margin-left: 2.333%;
         margin-right: 0;
       }
-
-
+    }
+    .subjectItem4 {
+      width: 18%;
     }
   }
 
@@ -402,6 +418,20 @@
       }
     }
   }
+
+  .subjectItem4 {
+    width: 23%;
+    margin-left: 0 !important;
+    margin-right: 2.333% !important;
+
+    &:nth-child(4n) {
+      margin-right: 0 !important;
+    }
+  }
+
+  .subjectItemHide {
+    display: none;
+  }
 }
 
 .popupMusicDetail {
@@ -413,4 +443,20 @@
       right: 20px;
     }
   }
+}
+
+.searchBodySection {
+  position: fixed;
+  right: 0;
+  left: 0;
+  bottom: 0;
+  z-index: 999;
+  overflow: hidden;
+  top: var(--header-height);
+
+  :global {
+    .van-overlay, .van-popup {
+      position: absolute
+    }
+  }
 }

+ 244 - 273
src/views/hot-music-more/index.tsx

@@ -4,6 +4,7 @@ import {
   onMounted,
   reactive,
   ref,
+  Teleport,
   toRefs,
   watch
 } from 'vue';
@@ -11,12 +12,12 @@ import styles from './index.module.less';
 import { browser, vaildMusicScoreUrl } from '@/helpers/utils';
 import MSticky from '@/components/m-sticky';
 import MHeader from '@/components/m-header';
-import { useRouter } from 'vue-router';
+import { useRoute, useRouter } from 'vue-router';
 import MSearch from '@/components/m-search';
-import { Cell, Image, List, Popup, Tab, Tabs } from 'vant';
+import { Cell, DropdownItem, DropdownMenu, Icon, Image, List, Popup, Tab, Tabs } from 'vant';
 import iconPlayer from './images/icon-player.png';
 import iconFire from './images/icon-fire.png';
-import iconTitleArrow from './images/icon-title-arrow.png'
+import iconTitleArrow from './images/icon-title-arrow.png';
 import { api_musicSheetCategoriesPage, api_musicSheetPage } from '../co-ai/api';
 import { state as baseState } from '@/state';
 import request from '@/helpers/request';
@@ -60,6 +61,7 @@ const ChildNodeSearch = defineComponent({
                 <div
                   class={[
                     styles.subjectItem,
+                    styles.subjectItem4,
                     (activeRow.value.activeIndex || '') == subject.id &&
                       styles.active
                   ]}
@@ -111,28 +113,41 @@ export default defineComponent({
   name: 'hot-music-more',
   setup() {
     const router = useRouter();
+    const route = useRoute()
     const state = reactive({
       background: 'transparent',
       loading: false,
       finished: false,
+      isAllStatus: true, // 当前是否已经为全部了
       searchPopup: false,
       musicDetailPopup: false,
       showVip: false,
-      tabActive: '1',
+      tabActive: '' as any,
       newTags: [] as any,
-      musicTagList: [] as any,
-      gradeList: [] as any,
-      musicCategory: [] as any,
+      isTagExpand: false,
       musics: [] as any,
       types: [] as any,
       subjectList: [] as any,
       audioPlayTypeList: [] as any, // 场景
+      sNt: '' as any, // 标签
       sAPT: '', // 场景
-      sMSCI: '',
-      sMII: '',
-      sBookId: '' as any,
-      sGrade: '' as any,
-      item: {} as any
+      item: {} as any,
+      allSearch: {
+        name: '',
+        musicTagIds: '' as any,
+        audioPlayTypes: [] as any,
+        bookVersionId: null as any,
+        musicalInstrumentId: ''
+      },
+      hotSearch: {
+        name: '',
+      },
+      newSearch: {
+        name: '',
+      },
+      recommendSearch: {
+        name: '',
+      }
     });
 
     const musicForms = reactive({
@@ -141,11 +156,6 @@ export default defineComponent({
       status: 1,
       sortType: 2, // 默认热度排序
       keyword: '', // 关键词
-      grade: '',
-      audioPlayTypes: [] as any,
-      bookVersionId: null as any,
-      musicSheetCategoriesId: '',
-      musicalInstrumentId: ''
     });
 
     const data = reactive({
@@ -155,15 +165,41 @@ export default defineComponent({
       tagActive: {} as any,
       childSelectId: null as any
     });
-    let isClick = false
+
+    const searchValue = computed(() => {
+      if(state.tabActive === 'RECOMMEND') {
+        return state.recommendSearch.name
+      } else if(state.tabActive === 'HOT') {
+        return state.hotSearch.name
+      } else if(state.tabActive === 'NEW') {
+        return state.newSearch.name
+      } else {
+        return state.allSearch.name
+      }
+    })
+
+    let isClick = false;
     const getMusicList = async () => {
       if (isClick) return;
       isClick = true;
       state.loading = true;
       try {
-        const res = await api_musicSheetPage({
-          ...musicForms
-        });
+        const { ...result } = musicForms;
+        let params = {
+          ...result,
+          searchType: state.tabActive
+        } as any
+        if(state.tabActive === 'RECOMMEND') {
+          params = Object.assign(params, state.recommendSearch);
+        } else if(state.tabActive === 'HOT') {
+          params = Object.assign(params, state.hotSearch);
+        } else if(state.tabActive === 'NEW') {
+          params = Object.assign(params, state.newSearch);
+        } else {
+          params.name = state.allSearch.name
+          params = Object.assign(params, state.allSearch);
+        }
+        const res = await api_musicSheetPage(params);
         if (res.code === 200 && Array.isArray(res?.data?.rows)) {
           const result = res.data.rows || [];
           result.forEach((item: any) => {
@@ -183,94 +219,35 @@ export default defineComponent({
         state.finished = true;
       }
       state.loading = false;
-      isClick = false
+      isClick = false;
     };
 
-    const getSubjecList = async () => {
+    const getTags = async () => {
       try {
-        let subjectIds = baseState.user.data?.subjectId || '';
-        subjectIds = subjectIds.split(',');
-        const subjectId = subjectIds[0] || '';
-        const res = await request.post('/edu-app/subject/list', {
-          enableFlag: true,
-          delFlag: 0,
-          page: 1,
-          subjectId: subjectId || '',
-          rows: 999
-        });
-
-        if (subjectId) {
-          const result = res.data || [];
-          const tempSubjects: any = [];
-          result.forEach((item: any) => {
-            const instruments = item.instruments || [];
-            if (Number(subjectId) === item.id && instruments.length > 0) {
-              instruments.forEach((child: any, index: number) => {
-                tempSubjects.push({
-                  text: child.name,
-                  value: child.id,
-                  className: index === 0 ? 'selected' : ''
-                });
-              });
-            }
-          });
-
-          if (tempSubjects.length > 0) {
-            state.subjectList = [{ text: '全部', value: '' }, ...tempSubjects];
-            // musicForms.musicalInstrumentId = tempSubjects[0].value;
-          }
-        }
-        // console.log(state.subjectList, state.subjectItem);
+        const res = await request.get('/edu-app/musicSheetTag/queryList');
+        const result = res.data || [];
+        state.newTags = [
+          {
+            name: '全部',
+            id: ''
+          },
+          ...result.map((item: any) => {
+            return {
+              name: item.name,
+              id: item.id
+            };
+          })
+        ];
       } catch {
         //
       }
     };
 
-    /** 获取音乐教材列表 */
-    const getMusicSheetCategories = async () => {
-      try {
-        // let subjectIds = baseState.user.data?.subjectId || '';
-        // subjectIds = subjectIds.split(',');
-        // const subjectId = subjectIds[0] || '';
-        const res = await api_musicSheetCategoriesPage({
-          page: 1,
-          rows: 999,
-          enable: true
-          // subjectId: subjectId
-          // musicTagIds: route.query.musicTagId ? [route.query.musicTagId] : []
-        });
-        if (res.code === 200 && Array.isArray(res?.data?.rows)) {
-          const temp: any = [];
-          res.data.rows.forEach((item: any) => {
-            temp.push({
-              value: item.id,
-              text: item.name
-            });
-          });
-          state.types = temp;
-        }
-      } catch (error) {
-        console.log('🚀 ~ error:', error);
-      }
-    };
-
-    
-    const getTags = async () => {
-      try {
-        const res = await request.get('/edu-app/musicSheetTag/queryList')
-        const result = res.data || []
-        state.newTags = [{
-            text: '全部',
-            value: ''
-        }, ...result.map((item: any) => {
-          return {
-            text: item.name,
-            value: item.id
-          }
-        })]
-      } catch {
-        // 
-      }
+    const onSearch = () => {
+      musicForms.page = 1;
+      state.musics = [];
+      state.finished = false;
+      getMusicList();
     }
 
     const onDetail = (item: any) => {
@@ -290,7 +267,7 @@ export default defineComponent({
       //   }
       // });
       state.item = item;
-      state.musicDetailPopup = true
+      state.musicDetailPopup = true;
     };
     const getMusicTagTree = async () => {
       try {
@@ -353,12 +330,13 @@ export default defineComponent({
       return data.tags.length > 0 ? true : false;
     });
 
-    const handleGoto = (item: any, showMusicImg: string, selectMusicInstrumentIndex: number) => {
-      const vipMember = baseState.user.data.vipMember
-      if (
-        !vipMember &&
-        item?.paymentType === 'VIP'
-      ) {
+    const handleGoto = (
+      item: any,
+      showMusicImg: string,
+      selectMusicInstrumentIndex: number
+    ) => {
+      const vipMember = baseState.user.data.vipMember;
+      if (!vipMember && item?.paymentType === 'VIP') {
         state.showVip = true;
         return;
       }
@@ -373,9 +351,7 @@ export default defineComponent({
       }
       let src = `${vaildMusicScoreUrl()}/instrument/?id=${
         item?.id
-      }&musicRenderType=${lineType}&showGuide=true&part-index=${
-        selectMusicInstrumentIndex
-      }`;
+      }&musicRenderType=${lineType}&showGuide=true&part-index=${selectMusicInstrumentIndex}`;
       postMessage({
         api: 'openAccompanyWebView',
         content: {
@@ -387,9 +363,13 @@ export default defineComponent({
           c_orientation: 0 // 0 横屏 1 竖屏
         }
       });
-    }
+    };
 
     onMounted(async () => {
+      if(route.query.type) {
+        state.tabActive = route.query.type
+        state.isAllStatus = false
+      }
       // 场景
       const tempAudio = Object.keys(audioPlayType).map(key => {
         return {
@@ -401,7 +381,7 @@ export default defineComponent({
 
       state.loading = true;
 
-      await getTags()
+      await getTags();
       // await getSubjecList();
       // await getMusicSheetCategories();
       await getMusicTagTree();
@@ -434,22 +414,44 @@ export default defineComponent({
                       'van-badge__wrapper van-icon van-icon-arrow-left van-nav-bar__arrow',
                       styles.leftArrow
                     ]}></i>
-                  <Tabs class={styles.tabSection} v-model:active={state.tabActive} shrink  onClickTab={() => {
-                      console.log(state.tabActive)
-
-                      if(state.tabActive === "1") {
-                        state.searchPopup = true
+                  <Tabs
+                    class={styles.tabSection}
+                    v-model:active={state.tabActive}
+                    shrink
+                    onClickTab={() => {
+                      if (state.tabActive === '') {
+                        if(state.isAllStatus) {
+                          state.searchPopup = !state.searchPopup
+                        } else {
+                          state.isAllStatus = true;
+                          onSearch()
+                        }
+                      } else {
+                        state.isAllStatus = false;
+                        onSearch()
                       }
+
+                      
                     }}>
-                    <Tab name="1">
-                      {{ title: () => <div class={styles.moreIcon}>
-                        <span>全部</span>
-                        <img src={iconTitleArrow} class={[styles.iconArrow, state.searchPopup && styles.iconArrowActive]} />
-                      </div> }}
+                    <Tab name="">
+                      {{
+                        title: () => (
+                          <div class={styles.moreIcon}>
+                            <span>全部</span>
+                            <img
+                              src={iconTitleArrow}
+                              class={[
+                                styles.iconArrow,
+                                state.searchPopup && styles.iconArrowActive
+                              ]}
+                            />
+                          </div>
+                        )
+                      }}
                     </Tab>
-                    <Tab name="2" title="推荐"></Tab>
-                    <Tab name="3" title="热门"></Tab>
-                    <Tab name="4" title="最新"></Tab>
+                    <Tab name="RECOMMEND" title="推荐"></Tab>
+                    <Tab name="HOT" title="热门"></Tab>
+                    <Tab name="NEW" title="最新"></Tab>
                   </Tabs>
                 </div>
               )
@@ -458,38 +460,22 @@ export default defineComponent({
 
           <MSearch
             // background={state.background}
+            v-model:modelValue={searchValue.value}
             background={'transparent'}
             onSearch={(val: any) => {
-              musicForms.keyword = val;
-              musicForms.page = 1;
-              state.musics = [];
-              state.finished = false;
-              getMusicList();
-            }}>
-            {/* {{
-              left: () => (
-                
-                <div
-                  class={[
-                    styles.searchContent,
-                    state.searchPopup && styles.active
-                  ]}
-                  onClick={() => {
-                    state.sBookId = musicForms.bookVersionId;
-                    state.sAPT =
-                      musicForms.audioPlayTypes.length > 1
-                        ? 'PLAY_SING'
-                        : musicForms.audioPlayTypes.join('');
-                    state.searchPopup = true;
-                  }}>
-                  <span>筛选</span>
-                  <i></i>
-                </div>
-              )
-            }} */}
-          </MSearch>
+              // musicForms.keyword = val;
+              if(state.tabActive === 'RECOMMEND') {
+                state.recommendSearch.name = val
+              } else if(state.tabActive === 'HOT') {
+                state.hotSearch.name = val
+              } else if(state.tabActive === 'NEW') {
+                state.newSearch.name = val
+              } else {
+                state.allSearch.name = val
+              }
+              onSearch()
+            }}></MSearch>
         </MSticky>
-
         <List
           loading={state.loading}
           finished={state.finished}
@@ -499,55 +485,55 @@ export default defineComponent({
           {state.musics.length > 0 && (
             <div class={styles.musicListSection}>
               <div class={styles.musicList}>
-              {state.musics.map((item: any) => (
-                <Cell
-                  class={styles.musicItem}
-                  border={false}
-                  center
-                  onClick={() => onDetail(item)}>
-                  {{
-                    icon: () => (
-                      <div class={styles.musicImg}>
-                        <i
-                          class={[
-                            styles.iconType,
-                            styles[item.paymentType]
-                          ]}></i>
-                        <Image class={styles.musicImg} src={item.titleImg} />
-                      </div>
-                    ),
-                    title: () => (
-                      <div class={styles.musicContnet}>
-                        <h2>{item.musicSheetName}</h2>
-                        <div class={styles.allStatus}>
-                          <span class={styles.hotNum}>
-                            <img src={iconFire} class={styles.iconFire} />
-                            {formatUsedNum(item.usedNum)}
-                          </span>
-                          {item.audioPlayTypes?.includes('SING') && (
-                            <span
-                              class={[styles.iconPlayType, styles.iconSing]}>
-                              演唱
-                            </span>
-                          )}
-                          {item.audioPlayTypes?.includes('PLAY') && (
-                            <span
-                              class={[styles.iconPlayType, styles.iconPlay]}>
-                              演奏
+                {state.musics.map((item: any) => (
+                  <Cell
+                    class={styles.musicItem}
+                    border={false}
+                    center
+                    onClick={() => onDetail(item)}>
+                    {{
+                      icon: () => (
+                        <div class={styles.musicImg}>
+                          <i
+                            class={[
+                              styles.iconType,
+                              styles[item.paymentType]
+                            ]}></i>
+                          <Image class={styles.musicImg} src={item.titleImg} />
+                        </div>
+                      ),
+                      title: () => (
+                        <div class={styles.musicContnet}>
+                          <h2>{item.musicSheetName}</h2>
+                          <div class={styles.allStatus}>
+                            <span class={styles.hotNum}>
+                              <img src={iconFire} class={styles.iconFire} />
+                              {formatUsedNum(item.usedNum)}
                             </span>
-                          )}
-
-                          {item.composer && <p>{item.composer}</p>}
+                            {item.audioPlayTypes?.includes('SING') && (
+                              <span
+                                class={[styles.iconPlayType, styles.iconSing]}>
+                                演唱
+                              </span>
+                            )}
+                            {item.audioPlayTypes?.includes('PLAY') && (
+                              <span
+                                class={[styles.iconPlayType, styles.iconPlay]}>
+                                演奏
+                              </span>
+                            )}
+
+                            {item.composer && <p>{item.composer}</p>}
+                          </div>
                         </div>
-                      </div>
-                    ),
-                    'right-icon': () => (
-                      <Image class={styles.musicPlayIcon} src={iconPlayer} />
-                    )
-                  }}
-                </Cell>
-              ))}
-            </div>
+                      ),
+                      'right-icon': () => (
+                        <Image class={styles.musicPlayIcon} src={iconPlayer} />
+                      )
+                    }}
+                  </Cell>
+                ))}
+              </div>
             </div>
           )}
         </List>
@@ -558,7 +544,9 @@ export default defineComponent({
           </div>
         )}
 
-        <Popup position="bottom" round v-model:show={state.searchPopup}>
+        <Teleport to={'body'}>
+          <div class={styles.searchBodySection}>
+          <Popup position="top" round v-model:show={state.searchPopup}>
           <div class={styles.searchContainer}>
             <div class={styles.searchHead}>
               <span
@@ -570,39 +558,35 @@ export default defineComponent({
               <span
                 class={styles.confirm}
                 onClick={() => {
-                  // musicForms.musicSheetCategoriesId = state.sMSCI;
-                  // musicForms.musicalInstrumentId = state.sMII;
-                  musicForms.bookVersionId =
+                  state.allSearch.bookVersionId =
                     data.childSelectId || data.tagActiveId;
-                  // musicForms.grade = state.sGrade;
-                  musicForms.audioPlayTypes = state.sAPT
+                  state.allSearch.audioPlayTypes = state.sAPT
                     ? state.sAPT === 'PLAY_SING'
                       ? ['SING', 'PLAY']
                       : [state.sAPT]
                     : [];
+                  state.allSearch.musicTagIds = state.sNt;
                   state.searchPopup = false;
-                  musicForms.page = 1;
-                  state.musics = [];
-                  state.finished = false;
-                  getMusicList();
+                  onSearch()
                 }}>
                 确定
               </span>
             </div>
 
             <div class={styles.changeSubjectContainer}>
-            {state.audioPlayTypeList.length > 0 && (
+              {state.newTags.length > 0 && (
                 <>
                   <div class={styles.title}>标签</div>
                   <div class={styles.subjectContainer}>
-                    {state.audioPlayTypeList.map((subject: any) => (
+                    {state.newTags.map((subject: any) => (
                       <div
                         class={[
                           styles.subjectItem,
-                          subject.id === state.sAPT && styles.active
+                          styles.subjectItem4,
+                          subject.id === state.sNt && styles.active
                         ]}
                         onClick={() => {
-                          state.sAPT = subject.id;
+                          state.sNt = subject.id;
                         }}>
                         {subject.name}
                       </div>
@@ -619,6 +603,7 @@ export default defineComponent({
                       <div
                         class={[
                           styles.subjectItem,
+                          styles.subjectItem4,
                           subject.id === state.sAPT && styles.active
                         ]}
                         onClick={() => {
@@ -633,82 +618,68 @@ export default defineComponent({
 
               {data.tags.length > 0 && (
                 <>
-                  <div class={styles.title}>{data.tags[0]?.columnName}</div>
+                  <div class={styles.title}>
+                    {data.tags[0]?.columnName}
+
+                    {state.isTagExpand && (
+                      <span onClick={() => (state.isTagExpand = false)}>
+                        收起
+                        <Icon name="arrow-up" />
+                      </span>
+                    )}
+                  </div>
                   <div class={styles.subjectContainer}>
-                    {data.tags.map((subject: any) => (
+                    {data.tags.map(
+                      (subject: any, index: number) =>
+                        ((!state.isTagExpand && index <= 4) ||
+                          state.isTagExpand) && (
+                          <div
+                            class={[
+                              styles.subjectItem,
+                              // !state.isTagExpand && index > 4 && styles.subjectItemHide,
+                              (subject.id || '') === (data.tagActiveId || '') &&
+                                styles.active
+                            ]}
+                            onClick={() => {
+                              changeTag(subject);
+                            }}>
+                            {subject.name}
+                          </div>
+                        )
+                    )}
+
+                    {!state.isTagExpand && (
                       <div
-                        class={[
-                          styles.subjectItem,
-                          (subject.id || '') === (data.tagActiveId || '') &&
-                            styles.active
-                        ]}
+                        class={[styles.subjectItem]}
                         onClick={() => {
-                          changeTag(subject);
+                          // changeTag(subject);
+                          state.isTagExpand = true;
                         }}>
-                        {subject.name}
+                        更多 <Icon name="arrow-down" />
                       </div>
-                    ))}
+                    )}
                   </div>
                   <ChildNodeSearch
                     activeRow={data.selectParents}
                     onSelectChildTag={(val: any) => {
                       data.childSelectId = val;
                       // onSearch();
-                      console.log(data.childSelectId);
                     }}
                   />
                 </>
               )}
-
-              {/* {state.gradeList.length > 0 && (
-                <>
-                  <div class={styles.title}>年级</div>
-                  <div class={styles.subjectContainer}>
-                    {state.gradeList.map((subject: any) => (
-                      <div
-                        class={[
-                          styles.subjectItem,
-                          subject.id === state.sGrade && styles.active
-                        ]}
-                        onClick={() => {
-                          state.sGrade = subject.id;
-                          onChangeSearch('grade', subject.children, true);
-                        }}>
-                        {subject.name}
-                      </div>
-                    ))}
-                  </div>
-                </>
-              )}
-
-              {state.musicCategory.length > 0 && (
-                <>
-                  <div class={styles.title}>曲谱教材</div>
-                  <div
-                    class={[
-                      styles.subjectContainer,
-                      styles.subjectContainerTwo
-                    ]}>
-                    {state.musicCategory.map((item: any) => (
-                      <div
-                        class={[
-                          styles.subjectItem,
-                          item.id === state.sMSCI && styles.active
-                        ]}
-                        onClick={() => {
-                          state.sMSCI = item.id;
-                        }}>
-                        {item.name}
-                      </div>
-                    ))}
-                  </div>
-                </>
-              )} */}
             </div>
           </div>
         </Popup>
+          </div>
+        </Teleport>
 
-        <Popup position='bottom' class={styles.popupMusicDetail} closeable round v-model:show={state.musicDetailPopup}>
+        <Popup
+          position="bottom"
+          class={styles.popupMusicDetail}
+          closeable
+          round
+          v-model:show={state.musicDetailPopup}>
           <MusicDetail item={state.item} onHandleGoto={handleGoto} />
         </Popup>