Jelajahi Sumber

Merge branch 'iteration-music-list'

lex 1 tahun lalu
induk
melakukan
8128c51290

+ 7 - 0
src/router/routes-common.ts

@@ -221,6 +221,13 @@ export default [
         meta: {
           title: '音乐家详情'
         }
+      },
+      {
+        path: '/hotMusicMore',
+        component: () => import('@/views/hot-music-more'),
+        meta: {
+          title: '曲谱列表'
+        }
       }
     ]
   },

TEMPAT SAMPAH
src/views/hot-music-more/images/icon-arrow.png


TEMPAT SAMPAH
src/views/hot-music-more/images/icon-player.png


TEMPAT SAMPAH
src/views/hot-music-more/images/woring-bg-tablet.png


TEMPAT SAMPAH
src/views/hot-music-more/images/woring-bg.png


TEMPAT SAMPAH
src/views/hot-music-more/images/woring-title.png


+ 246 - 0
src/views/hot-music-more/index.module.less

@@ -0,0 +1,246 @@
+.hotMusicMore {
+  min-height: 100vh;
+  background: url('./images/woring-bg.png') no-repeat top center;
+  background-size: contain;
+
+  :global {
+    .van-search {
+      padding-top: 20px;
+    }
+
+    // .van-sticky--fixed {
+    //   background: url('./images/woring-bg.png') no-repeat top center;
+    //   background-size: 100%;
+    // }
+  }
+}
+
+.woringHeader {
+  display: flex;
+  align-items: center;
+  height: var(--van-nav-bar-height);
+
+  .leftArrow {
+    padding: 0 var(--k-padding-md);
+  }
+
+  .title {
+    position: relative;
+    z-index: 1;
+
+    i {
+      width: 78px;
+      height: 20px;
+      display: inline-block;
+      background: url('./images/woring-title.png') no-repeat center;
+      background-size: contain;
+    }
+
+    &::after {
+      content: ' ';
+      display: inline-block;
+      position: absolute;
+      left: 0;
+      bottom: -2px;
+      width: 48px;
+      height: 6px;
+      background: linear-gradient(270deg, rgba(119, 255, 239, 0.59) 0%, #42CDFF 100%);
+      opacity: 0.5;
+      z-index: -1;
+    }
+  }
+}
+
+.searchContent {
+  font-size: 14px;
+  color: rgba(0, 0, 0, 0.8);
+  line-height: 20px;
+  margin-right: 12px;
+  display: flex;
+  align-items: center;
+
+  span {
+    padding-right: 4px;
+  }
+
+  i {
+    display: inline-block;
+    background: url('./images/icon-arrow.png') no-repeat center;
+    background-size: contain;
+    width: 9px;
+    height: 5px;
+    transition: transform 0.2s ease;
+  }
+
+  &.active {
+    i {
+      transform: rotate(180deg);
+      transition: transform 0.2s ease;
+    }
+  }
+}
+
+// .hotMusicMoreTablet {
+//   background: url('./images/woring-bg-tablet.png') no-repeat top center;
+//   background-size: contain;
+// }
+.emptyGroup {
+  height: calc(100vh - var(--header-height));
+}
+
+.musicList {
+  margin: 8px 13px 13px;
+  background: #FFFFFF;
+  border-radius: 16px;
+  overflow: hidden;
+  // min-height: 50vh;
+
+  .musicItem {
+    padding: 15px 12px;
+  }
+
+  .musicImg {
+    width: 51px;
+    height: 51px;
+    margin-right: 10px;
+  }
+
+  .musicPlayIcon {
+    width: 24px;
+    height: 24px;
+  }
+
+  .musicContnet {
+    h2 {
+      font-size: 16px;
+      font-weight: 600;
+      color: #333333;
+      line-height: 22px;
+    }
+
+    p {
+      padding-top: 8px;
+      font-size: 13px;
+      color: #777777;
+      line-height: 1;
+    }
+  }
+}
+
+.changeSubjectContainer {
+  min-height: 217px;
+  max-height: 367px;
+  overflow-x: hidden;
+  overflow-y: auto;
+  padding: 0 15px 30px;
+
+
+  &::-webkit-scrollbar {
+    display: none;
+  }
+
+
+  .title {
+    padding-top: 18px;
+    display: flex;
+    align-items: center;
+
+    font-size: 16px;
+    font-weight: 500;
+    color: #333333;
+    line-height: 22px;
+
+    &::before {
+      content: '';
+      display: inline-block;
+      width: 4px;
+      height: 11px;
+      background: #1CACF1;
+      border-radius: 3px;
+      margin-right: 6px;
+    }
+  }
+}
+
+
+.searchHead {
+  display: flex;
+  align-items: center;
+  justify-content: space-between;
+  font-size: 16px;
+  font-weight: 500;
+  color: #333333;
+  height: 55px;
+  line-height: 55px;
+  border-bottom: 1px solid #F2F2F2;
+  margin: 0 15px;
+
+  .cancel,
+  .confirm {
+    font-size: 14px;
+    font-weight: 400;
+    line-height: 20px;
+    color: #777777;
+    padding: 0 7px;
+  }
+
+  .confirm {
+    color: #1CACF1;
+  }
+
+}
+
+.subjectContainer {
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  padding-top: 18px;
+
+  .subjectItem {
+    width: 31%;
+    height: 34px;
+    padding: 0 8px;
+    line-height: 34px;
+    text-align: center;
+    background: #F6F6F6;
+    border-radius: 50px;
+    font-size: 13px;
+    color: #333333;
+    border: 1px solid #F6F6F6;
+    margin-bottom: 12px;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+
+
+    &:nth-child(3n + 2) {
+      margin-left: 2.333%;
+      margin-right: 2.333%;
+    }
+
+    &.arrow::after {
+      content: '';
+      display: inline-block;
+      margin-left: 3px;
+      width: 0;
+      height: 0;
+      border-left: 4px solid transparent;
+      border-right: 4px solid transparent;
+      border-top: 4px solid transparent;
+      border-bottom: 4px solid #777777;
+      transform: translateY(3px) rotate(180deg);
+    }
+
+
+    &.active {
+      border: 1px solid #1CACF1;
+      background: #EBF8FF;
+      color: #1CACF1;
+
+      &::after {
+        border-bottom: 4px solid #1CACF1;
+        transform: translateY(-2px) rotate(0deg);
+      }
+    }
+  }
+}

+ 337 - 0
src/views/hot-music-more/index.tsx

@@ -0,0 +1,337 @@
+import { computed, defineComponent, onMounted, reactive } from 'vue';
+import styles from './index.module.less';
+import { browser } from '@/helpers/utils';
+import MSticky from '@/components/m-sticky';
+import MHeader from '@/components/m-header';
+import { useRouter } from 'vue-router';
+import MSearch from '@/components/m-search';
+import { Cell, Image, List, Popup } from 'vant';
+import iconPlayer from './images/icon-player.png';
+import { api_musicSheetCategoriesPage, api_musicSheetPage } from '../co-ai/api';
+import { state as baseState } from '@/state';
+import { useEventListener, useWindowScroll } from '@vueuse/core';
+import request from '@/helpers/request';
+import MEmpty from '@/components/m-empty';
+import { postMessage } from '@/helpers/native-message';
+
+export default defineComponent({
+  name: 'hot-music-more',
+  setup() {
+    const router = useRouter();
+    const state = reactive({
+      background: 'transparent',
+      loading: false,
+      finished: false,
+      searchPopup: false,
+      musics: [] as any,
+      types: [] as any,
+      subjectList: [] as any,
+      sMSCI: '',
+      sMII: ''
+    });
+
+    const musicForms = reactive({
+      page: 1,
+      rows: 20,
+      status: 1,
+      keyword: '', // 关键词
+      musicSheetCategoriesId: '',
+      musicalInstrumentId: ''
+    });
+
+    const getMusicList = async () => {
+      state.loading = true;
+      try {
+        const res = await api_musicSheetPage({
+          ...musicForms
+        });
+        if (res.code === 200 && Array.isArray(res?.data?.rows)) {
+          state.musics = [...state.musics, ...res.data.rows];
+          state.finished = !res.data.next;
+        }
+      } catch (error) {
+        // console.log('🚀 ~ error:', error);
+      }
+      state.loading = false;
+    };
+
+    const getSubjecList = 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 || [];
+          let 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);
+      } 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,
+          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 onDetail = (item: any) => {
+      let src = `${location.origin}/instrument?id=${item?.id}&showGuide=true`;
+      postMessage({
+        api: 'openAccompanyWebView',
+        content: {
+          url: src,
+          orientation: 0,
+          isHideTitle: true,
+          statusBarTextColor: false,
+          isOpenLight: true,
+          c_orientation: 0 // 0 横屏 1 竖屏
+        }
+      });
+    };
+
+    // 判断是否有数据
+    const isSearch = computed(() => {
+      return state.subjectList.length > 2 && state.types.length > 0
+        ? true
+        : false;
+    });
+
+    onMounted(async () => {
+      useEventListener(document, 'scroll', () => {
+        const { y } = useWindowScroll();
+        if (y.value > 32) {
+          state.background = '#fff';
+        } else {
+          state.background = 'transparent';
+        }
+      });
+      state.loading = true;
+      await getSubjecList();
+      await getMusicSheetCategories();
+      getMusicList();
+    });
+    return () => (
+      // sortType: 2
+      <div
+        class={[
+          styles.hotMusicMore,
+          browser().isTablet ? styles.hotMusicMoreTablet : ''
+        ]}>
+        <MSticky position="top">
+          <MHeader border={false} background={state.background}>
+            {{
+              content: () => (
+                <div class={styles.woringHeader}>
+                  <i
+                    onClick={() => {
+                      if (browser().isApp) {
+                        postMessage({
+                          api: 'goBack'
+                        });
+                      } else {
+                        router.back();
+                      }
+                    }}
+                    class={[
+                      'van-badge__wrapper van-icon van-icon-arrow-left van-nav-bar__arrow',
+                      styles.leftArrow
+                    ]}></i>
+                  <span class={styles.title}>
+                    <i></i>
+                  </span>
+                </div>
+              )
+            }}
+          </MHeader>
+
+          <MSearch background={state.background}>
+            {{
+              left: () =>
+                isSearch.value && (
+                  <div
+                    class={[
+                      styles.searchContent,
+                      state.searchPopup && styles.active
+                    ]}
+                    onClick={() => {
+                      state.sMSCI = musicForms.musicSheetCategoriesId;
+                      state.sMII = musicForms.musicalInstrumentId;
+                      state.searchPopup = true;
+                    }}>
+                    <span>筛选</span>
+                    <i></i>
+                  </div>
+                )
+            }}
+          </MSearch>
+        </MSticky>
+
+        <List
+          loading={state.loading}
+          finished={state.finished}
+          finishedText=" "
+          onLoad={getMusicList}
+          immediateCheck={false}>
+          {state.musics.length > 0 && (
+            <div class={styles.musicList}>
+              {state.musics.map((item: any) => (
+                <Cell
+                  class={styles.musicItem}
+                  border={false}
+                  center
+                  onClick={(item: any) => onDetail(item)}>
+                  {{
+                    icon: () => (
+                      <Image class={styles.musicImg} src={item.titleImg} />
+                    ),
+                    title: () => (
+                      <div class={styles.musicContnet}>
+                        <h2>{item.musicSheetName}</h2>
+                        {item.composer && <p>{item.composer}</p>}
+                      </div>
+                    ),
+                    'right-icon': () => (
+                      <Image class={styles.musicPlayIcon} src={iconPlayer} />
+                    )
+                  }}
+                </Cell>
+              ))}
+            </div>
+          )}
+        </List>
+
+        {!state.loading && state.musics.length === 0 && (
+          <div class={styles.emptyGroup}>
+            <MEmpty description="暂无曲谱" />
+          </div>
+        )}
+
+        <Popup position="bottom" round v-model:show={state.searchPopup}>
+          <div class={styles.searchContainer}>
+            <div class={styles.searchHead}>
+              <span
+                class={styles.cancel}
+                onClick={() => (state.searchPopup = false)}>
+                取消
+              </span>
+              <span>筛选</span>
+              <span
+                class={styles.confirm}
+                onClick={() => {
+                  musicForms.musicSheetCategoriesId = state.sMSCI;
+                  musicForms.musicalInstrumentId = state.sMII;
+                  state.searchPopup = false;
+                  musicForms.page = 1;
+                  state.musics = [];
+                  state.finished = false;
+                  getMusicList();
+                }}>
+                确定
+              </span>
+            </div>
+
+            <div class={styles.changeSubjectContainer}>
+              {state.subjectList.length > 2 && (
+                <>
+                  <div class={styles.title}>乐器</div>
+                  <div class={styles.subjectContainer}>
+                    {state.subjectList.map((subject: any) => (
+                      <div
+                        class={[
+                          styles.subjectItem,
+                          subject.value === state.sMII && styles.active
+                        ]}
+                        onClick={() => {
+                          state.sMII = subject.value;
+                        }}>
+                        {subject.text}
+                      </div>
+                    ))}
+                  </div>
+                </>
+              )}
+
+              {state.types.length > 0 && (
+                <>
+                  <div class={styles.title}>曲谱教材</div>
+                  <div class={styles.subjectContainer}>
+                    <div
+                      class={[
+                        styles.subjectItem,
+                        state.sMSCI === '' && styles.active
+                      ]}
+                      onClick={() => {
+                        state.sMSCI = '';
+                      }}>
+                      全部
+                    </div>
+                    {state.types.map((item: any) => (
+                      <div
+                        class={[
+                          styles.subjectItem,
+                          item.value === state.sMSCI && styles.active
+                        ]}
+                        onClick={() => {
+                          state.sMSCI = item.value;
+                        }}>
+                        {item.text}
+                      </div>
+                    ))}
+                  </div>
+                </>
+              )}
+            </div>
+          </div>
+        </Popup>
+      </div>
+    );
+  }
+});

+ 2 - 2
vite.config.ts

@@ -13,8 +13,8 @@ function resolve(dir: string) {
 }
 // https://vitejs.dev/config/
 // https://github.com/vitejs/vite/issues/1930 .env
-const proxyUrl = 'https://test.lexiaoya.cn/';
-// const proxyUrl = 'https://dev.kt.colexiu.com/';
+// const proxyUrl = 'https://test.lexiaoya.cn/';
+const proxyUrl = 'https://dev.kt.colexiu.com/';
 // const proxyUrl = 'http://192.168.3.143:7989/';
 export default defineConfig({
   base: './',