lex-xin 5 月之前
父節點
當前提交
66e56af2ac

+ 1 - 1
dev-dist/sw.js

@@ -82,7 +82,7 @@ define(['./workbox-88bf3160'], (function (workbox) { 'use strict';
     "revision": "3ca0b8505b4bec776b69afdba2768812"
   }, {
     "url": "index.html",
-    "revision": "0.phhl6vcc60g"
+    "revision": "0.07uic5uubv8"
   }], {});
   workbox.cleanupOutdatedCaches();
   workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {

+ 1 - 1
public/version.json

@@ -1 +1 @@
-{"version":1727674273374}
+{"version":1728350859844}

+ 4 - 0
src/components/layout/index.module.less

@@ -17,6 +17,10 @@
     height: calc(100vh - 64px);
     overflow-y: auto;
     // overflow: hidden;
+
+    &.isNotPadding {
+      padding: 0;
+    }
   }
 }
 

+ 11 - 1
src/components/layout/index.tsx

@@ -372,6 +372,7 @@ export default defineComponent({
         '/classStudentDetail',
         '/notation',
         '/xiaoku-ai',
+        '/xiaoku-list',
         '/studentDetail',
         '/classStudentRecode',
         '/afterWorkDetail'
@@ -390,6 +391,15 @@ export default defineComponent({
       return hidePath.includes(routePath) ? false : true;
     });
 
+    const isNotPadding = computed(() => {
+      const routePath = route.path;
+      const hidePath = [
+        '/xiaoku-list',
+      ];
+      
+      return hidePath.includes(routePath) ? true : false;
+    })
+
     onMounted(() => {
       initMoveable();
       // // initMoveableClass();
@@ -644,7 +654,7 @@ export default defineComponent({
         </div>
         <div class={styles.Wrapcore}>
           <LayoutTop></LayoutTop>
-          <div class={styles.WrapcoreView} id="WrapcoreViewWrap">
+          <div class={[styles.WrapcoreView, isNotPadding.value ? styles.isNotPadding : '']} id="WrapcoreViewWrap">
             {/* <div class={styles.WrapcoreViewInfo}> */}
             <router-view>
               {(obj: any) => (

+ 1 - 1
src/components/layout/layoutSilder.tsx

@@ -105,7 +105,7 @@ export default defineComponent({
         isActive: false,
         id: 5,
         lightList: ['/xiaoku-music'], //AI学练的灯光列表
-        path: '/xiaoku-ai'
+        path: '/xiaoku-list'
       },
       {
         activeIcon: resourceIcon,

+ 1 - 0
src/components/layout/layoutTop.tsx

@@ -206,6 +206,7 @@ export default defineComponent({
         '/classStudentDetail',
         '/notation',
         '/xiaoku-ai',
+        '/xiaoku-list',
         '/studentDetail',
         '/classStudentRecode',
         '/afterWorkDetail'

+ 1 - 1
src/hooks/useErrorLog/index.ts

@@ -36,7 +36,7 @@ export default function useErrorLog() {
     '/classroom/studentDetail',
     '/classroom/afterWorkDetail',
     '/classroom/classStudentRecode',
-    '/classroom/xiaoku-ai',
+    '/classroom/xiaoku-list',
     '/classroom/xiaoku-music',
     '/classroom/natural-resources',
     '/classroom/notation',

+ 16 - 3
src/router/routes/index.ts

@@ -101,9 +101,6 @@ export const constantRoutes: RouteRecordRaw[] = [
           singleLayout: 'blank'
         }
       },
-
-      //
-
       {
         path: '/xiaoku-ai',
         name: 'xiaoku-ai',
@@ -121,6 +118,22 @@ export const constantRoutes: RouteRecordRaw[] = [
         }
       },
       {
+        path: '/xiaoku-list',
+        name: 'xiaoku-list',
+        component: () => import('@/views/xiaoku-list/index'),
+        meta: {
+          title: 'AI学练'
+        }
+      },
+      {
+        path: '/xiaoku-detail',
+        name: 'xiaoku-detail',
+        component: () => import('@/views/xiaoku-list/detail'),
+        meta: {
+          title: 'AI学练'
+        }
+      },
+      {
         path: '/setting',
         name: 'base-setting',
         component: () => import('@/views/setting/index'),

+ 352 - 0
src/views/xiaoku-list/detail.module.less

@@ -0,0 +1,352 @@
+.detailContainer {
+  background: #ffffff;
+  border-radius: 20px;
+  :global {
+    .n-tabs-tab-pad {
+      width: 40px !important;
+    }
+
+    .n-tabs-nav {
+      padding: 12px 32px 20px;
+    }
+
+    .n-tabs-tab {
+      color: #8b8d98;
+      font-size: max(20px, 14px);
+      padding-top: 8px;
+      padding-bottom: 8px;
+      line-height: 28px;
+
+      &.n-tabs-tab--active {
+        font-weight: 600 !important;
+        color: #131415 !important;
+      }
+    }
+
+    .n-tabs-tab__label {
+      z-index: 10;
+    }
+
+    .n-tabs-bar {
+      height: 10px;
+      background: linear-gradient(
+        90deg,
+        #77bbff 0%,
+        rgba(163, 231, 255, 0.22) 100%
+      );
+      z-index: 0;
+      bottom: 8px;
+      transition-duration: 0.03;
+    }
+
+    .n-tabs-bar--disabled {
+      background-color: #fff !important;
+    }
+
+    .n-tab-pane {
+      padding-top: 4px !important;
+    }
+  }
+
+  .inputSearch {
+    width: 480px;
+  }
+
+  .searchSection {
+    position: relative;
+    margin: 0 32px;
+  }
+}
+
+.searchGroup {
+  background: #f7f8f9;
+  border-radius: 12px;
+  padding: 24px 24px 34px;
+  position: relative;
+
+  .btnType {
+    gap: 0px 24px !important;
+
+    :global {
+      .n-button {
+        height: 37px;
+        padding: 0 24px;
+        font-size: max(18px, 13px);
+        color: rgba(0, 0, 0, 0.6);
+
+        &.n-button--primary-type {
+          font-weight: bold;
+          color: #fff;
+        }
+      }
+    }
+  }
+
+  :global {
+    .n-form {
+      position: relative;
+    }
+
+    .n-form-item {
+      .n-form-item-label {
+        font-size: max(17px, 13px);
+        font-weight: 600;
+        color: #131415;
+        line-height: 24px;
+      }
+
+      .n-button {
+        height: 32px;
+        font-size: max(17px, 12px);
+        border-radius: 8px;
+        color: rgba(0, 0, 0, 0.6);
+      }
+
+      .n-button--primary-type {
+        color: #131415;
+        background-color: #d2ecff !important;
+      }
+    }
+
+    .n-form-item-feedback-wrapper {
+      min-height: 14px;
+    }
+  }
+
+  .moreSearch {
+    position: absolute;
+    bottom: 0;
+    left: 50%;
+    transform: translateX(-50%);
+    font-size: 17px;
+    color: #000000;
+    line-height: 24px;
+    cursor: pointer;
+  }
+}
+
+.teachingModal {
+  width: 1100px;
+}
+
+.spaceSection {
+  width: 75%;
+  transition: 1s all ease-in;
+
+  & > div {
+    height: 34px !important;
+    display: flex !important;
+    align-items: center;
+    line-height: var(--n-blank-height);
+  }
+}
+
+.collapseWrap {
+  width: 98%;
+  display: flex;
+  flex-direction: row;
+  align-items: flex-end;
+}
+
+.collaoseGroup {
+  position: absolute;
+  display: flex;
+  align-items: center;
+  padding-left: 8px;
+}
+
+.collaoseBtn {
+  width: 32px;
+  height: 32px;
+  cursor: pointer;
+}
+
+.collaoseBtn.isStart {
+  transform: rotate(-180deg);
+}
+
+.collapsSection {
+  // padding-top: 10px;
+}
+
+.isHidden {
+  overflow: hidden;
+  transition: 1s all ease-in;
+}
+
+.hideButton {
+  visibility: hidden;
+  height: 0 !important;
+  line-height: 0 !important;
+}
+
+.popSelect {
+  font-size: 16px;
+  width: 200px;
+  box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.08);
+  border-radius: 11px;
+  --n-option-height: 34px;
+
+  :global {
+    .n-base-select-option__content {
+      width: 80% !important;
+    }
+  }
+}
+
+.spaceSection2 {
+  width: 76%;
+  transition: 1s all ease-in;
+  padding-right: 40px;
+
+  & > div {
+    // height: 34Px !important;
+    // display: flex !important;
+    // align-items: center;
+    &:last-child {
+      // margin-left: -12Px;
+    }
+  }
+}
+
+.textBtn {
+  background: #fff;
+  border-radius: 8px;
+  padding: 4px 20px;
+  font-size: max(17px, 12px);
+  color: rgba(0, 0, 0, 0.6);
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  font-weight: 500;
+  line-height: 24px;
+
+  .iconArrow {
+    display: inline-block;
+    margin-left: 8px;
+    width: 8px;
+    height: 5px;
+    background: url('../content-information/images/icon-arrow2.png') no-repeat
+      center center / contain;
+    transform: rotate(180deg);
+  }
+
+  &:hover,
+  &.textBtnActive {
+    background: #d2ecff;
+    font-weight: 500;
+    color: #131415;
+  }
+
+  &:hover {
+    .iconArrow {
+      transform: rotate(0deg);
+    }
+  }
+}
+
+.sectionContainer {
+  padding: 24px 32px;
+  gap: 24px;
+  flex: 1 auto;
+  display: flex;
+  flex-wrap: wrap;
+}
+
+.sectionItem {
+  display: flex;
+  align-items: center;
+  cursor: pointer;
+  padding: 20px;
+  border-radius: 12px;
+  width: 402px;
+  background: #f7f8f9;
+  cursor: pointer;
+
+  .img {
+    width: 60px;
+    height: 60px;
+    background: #ddf2ff;
+    border-radius: 8px;
+    overflow: hidden;
+    margin-right: 16px;
+    img {
+      width: inherit;
+      height: inherit;
+    }
+  }
+
+  .infos {
+    display: flex;
+    flex-direction: column;
+
+    .topName {
+      font-weight: 600;
+      font-size: 20px;
+      color: #131415;
+      line-height: 28px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      max-width: 270px;
+
+      span {
+        color: #198cfe;
+        font-weight: bold;
+      }
+    }
+
+    .types {
+      display: flex;
+      padding-top: 4px;
+      & > div {
+        margin-right: 4px;
+      }
+
+      .hot {
+        background: #fff3f3;
+        border-radius: 3px;
+        border: 1px solid rgba(254, 67, 67, 0.5);
+        font-size: max(12px, 11px);
+        color: #fe4343;
+        padding: 0 5px;
+        &::before {
+          content: '';
+          display: inline-block;
+          width: 10px;
+          height: 12px;
+          background: url('./images/icon-fire.png') no-repeat center;
+          background-size: contain;
+          margin-right: 3px;
+          vertical-align: middle;
+        }
+        span {
+          line-height: 1;
+          vertical-align: text-bottom;
+        }
+      }
+      .sing,
+      .song {
+        background: #ffffff;
+        font-size: max(12px, 11px);
+        border-radius: 3px;
+        padding: 0 4px;
+        line-height: 1;
+        display: flex;
+        align-items: center;
+      }
+      .sing {
+        border: 1px solid rgba(243, 130, 26, 0.5);
+        color: #f3821a;
+      }
+      .song {
+        border: 1px solid rgba(21, 178, 253, 0.5);
+        color: #00adff;
+      }
+      .author {
+        color: #777777;
+        font-size: max(14px, 12px);
+      }
+    }
+  }
+}

+ 78 - 0
src/views/xiaoku-list/detail.tsx

@@ -0,0 +1,78 @@
+import { defineComponent, reactive, ref } from 'vue';
+import styles from './detail.module.less';
+import CBreadcrumb from '/src/components/CBreadcrumb';
+import { useRoute } from 'vue-router';
+import { NForm, NFormItem, NTabPane, NTabs } from 'naive-ui';
+import SearchGroupResources from './search-group-resources';
+import TheSearch from '/src/components/TheSearch';
+
+export default defineComponent({
+  name: 'xiaoku-detail',
+  setup() {
+    const route = useRoute();
+    const routerList = ref([
+      { name: 'AI学练', path: '/xiaoku-list' },
+      { name: '全部曲目', path: '' }
+    ]);
+    const state = reactive({
+      tabName: 'name'
+    });
+    return () => (
+      <div>
+        <CBreadcrumb list={routerList.value}></CBreadcrumb>
+        <div class={styles.detailContainer}>
+          <NTabs
+            paneClass={styles.paneTitle}
+            justifyContent="start"
+            // animated
+            paneWrapperClass={styles.paneWrapperContainer}
+            v-model:value={state.tabName}
+            v-slots={{
+              suffix: () => <TheSearch
+              round
+              class={styles.inputSearch}
+              onSearch={val => {
+                // forms.keyword = val;
+                // getList();
+              }}
+            />
+            }}>
+            <NTabPane name={`name`} tab={'全部曲目'}></NTabPane>
+            <NTabPane name={`name1`} tab={'推荐曲目'}></NTabPane>
+            <NTabPane name={`name2`} tab={'热门曲目'}></NTabPane>
+            <NTabPane name={`name3`} tab={'最新曲目'}></NTabPane>
+          </NTabs>
+
+          <div class={styles.searchSection}>
+            <SearchGroupResources />
+          </div>
+
+          <div class={styles.sectionContainer}>
+            {[1,2,3,4,4,5,6,7,8,9].map(() => <div class={styles.sectionItem}>
+              <div class={styles.img}>
+                <img
+                  referrerpolicy="no-referrer"
+                  src="https://lanhu-oss.lanhuapp.com/SketchPnge5215a88a6a2d4a1aba30956f78102bf01fac5e63f33b045c1427d94330297dd"
+                />
+              </div>
+              <div class={styles.infos}>
+                <div class={styles.topName}>
+                  <span>玩具</span>
+                  兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲
+                </div>
+                <div class={styles.types}>
+                  <div class={styles.hot}>
+                    <span>1.8万</span>
+                  </div>
+                  <div class={styles.sing}>演唱</div>
+                  <div class={styles.song}>演奏</div>
+                  <div class={styles.author}>耶寒尔</div>
+                </div>
+              </div>
+            </div>)}
+          </div>
+        </div>
+      </div>
+    );
+  }
+});

二進制
src/views/xiaoku-list/images/bg.png


二進制
src/views/xiaoku-list/images/hot_bg.png


二進制
src/views/xiaoku-list/images/hot_title.png


二進制
src/views/xiaoku-list/images/icon-arrow.png


二進制
src/views/xiaoku-list/images/icon-fire.png


二進制
src/views/xiaoku-list/images/new_bg.png


二進制
src/views/xiaoku-list/images/new_title.png


二進制
src/views/xiaoku-list/images/recommon_bg.png


二進制
src/views/xiaoku-list/images/reommon_title.png


+ 367 - 0
src/views/xiaoku-list/index.module.less

@@ -0,0 +1,367 @@
+.list {
+  background: url('./images/bg.png') no-repeat top center;
+  background-size: contain;
+  width: 100%;
+  height: 100%;
+  display: flex;
+  flex-direction: column;
+}
+
+.topTitle {
+  padding-top: 30px;
+  padding-bottom: 24px;
+  font-size: 50px;
+  color: #131415;
+  line-height: 60px;
+  letter-spacing: 1px;
+  text-align: center;
+  font-style: normal;
+  color: #004aff;
+}
+
+.searchSection {
+  position: relative;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  .searchInput {
+    width: 700px;
+    --n-height: 50px !important;
+    :global {
+      .n-button {
+        padding: 0 24px;
+        font-size: 18px !important;
+        color: #ffffff;
+      }
+      .n-input__input-el {
+        font-size: 18px !important;
+        color: #000000;
+      }
+
+      input::placeholder {
+        font-size: 18px !important;
+      }
+    }
+  }
+  .moreMusic {
+    position: absolute;
+    right: 60px;
+    padding: 9px 25px;
+    background: rgba(255, 255, 255, 0.7);
+    border-radius: 22px;
+    font-weight: 600;
+    font-size: 18px;
+    color: #131415;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    cursor: pointer;
+    line-height: 1.5;
+
+    &::after {
+      content: '';
+      display: inline-block;
+      width: 6px;
+      height: 10px;
+      background: url('./images/icon-arrow.png') no-repeat center;
+      background-size: contain;
+      margin-left: 6px;
+    }
+  }
+}
+
+.container {
+  padding: 24px 60px;
+  display: flex;
+  gap: 0 30px;
+  flex: 1 auto;
+  .section {
+    flex: 1;
+    border-radius: 16px;
+    background: #ffffff;
+    overflow: hidden;
+    height: 100%;
+
+    .sectionTitle {
+      padding: 18px 24px;
+      display: flex;
+      align-items: center;
+      justify-content: space-between;
+      .imgTitle {
+        height: 45px;
+      }
+      .moreBtn {
+        border-radius: 20px;
+        font-weight: 600;
+        font-size: 18px;
+        color: #131415;
+        padding: 7px 20px;
+        display: flex;
+        align-items: center;
+        justify-content: center;
+        cursor: pointer;
+        line-height: 1;
+        &::after {
+          content: '';
+          display: inline-block;
+          width: 6px;
+          height: 10px;
+          background: url('./images/icon-arrow.png') no-repeat center;
+          background-size: contain;
+          margin-left: 6px;
+        }
+      }
+    }
+  }
+  .recommendSection {
+    background: url('./images/recommon_bg.png') no-repeat top center #fff;
+    background-size: contain;
+
+    .moreBtn {
+      background: #d1e8ff;
+    }
+  }
+
+  .hotSection {
+    background: url('./images/hot_bg.png') no-repeat top center #fff;
+    background-size: contain;
+
+    .moreBtn {
+      background: #f8e5f1;
+    }
+  }
+  .newSection {
+    background: url('./images/new_bg.png') no-repeat top center #fff;
+    background-size: contain;
+
+    .moreBtn {
+      background: #d4f1e7;
+    }
+  }
+
+  :global {
+    .n-scrollbar {
+      max-height: calc(100vh - 64px - 154px - 48px - 91px);
+    }
+  }
+}
+
+.item {
+  display: flex;
+  align-items: center;
+  margin: 0 12px 10px;
+  cursor: pointer;
+  padding: 15px 12px;
+  border-radius: 12px;
+  cursor: pointer;
+
+  &:hover {
+    background: #f5f6fa;
+  }
+
+  .num {
+    font-family: DINAlternate, DINAlternate;
+    font-weight: bold;
+    font-size: 18px;
+    color: #7e8287;
+    line-height: 22px;
+    text-align: center;
+
+    &.num1 {
+      color: #f72626;
+    }
+    &.num2 {
+      color: #fd6633;
+    }
+    &.num3 {
+      color: #ffac37;
+    }
+  }
+
+  .img {
+    width: 60px;
+    height: 60px;
+    background: #ddf2ff;
+    border-radius: 8px;
+    overflow: hidden;
+    margin: 0 16px;
+    img {
+      width: inherit;
+      height: inherit;
+    }
+  }
+
+  .infos {
+    display: flex;
+    flex-direction: column;
+
+    .topName {
+      font-weight: 600;
+      font-size: 20px;
+      color: #131415;
+      line-height: 28px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      max-width: 370px;
+    }
+
+    .types {
+      display: flex;
+      padding-top: 4px;
+      & > div {
+        margin-right: 4px;
+      }
+
+      .hot {
+        background: #fff3f3;
+        border-radius: 3px;
+        border: 1px solid rgba(254, 67, 67, 0.5);
+        font-size: max(12px, 11px);
+        color: #fe4343;
+        padding: 0 5px;
+        &::before {
+          content: '';
+          display: inline-block;
+          width: 10px;
+          height: 12px;
+          background: url('./images/icon-fire.png') no-repeat center;
+          background-size: contain;
+          margin-right: 3px;
+          vertical-align: middle;
+        }
+        span {
+          line-height: 1;
+          vertical-align: text-bottom;
+        }
+      }
+      .sing,
+      .song {
+        background: #ffffff;
+        font-size: max(12px, 11px);
+        border-radius: 3px;
+        padding: 0 4px;
+        line-height: 1;
+        display: flex;
+        align-items: center;
+      }
+      .sing {
+        border: 1px solid rgba(243, 130, 26, 0.5);
+        color: #f3821a;
+      }
+      .song {
+        border: 1px solid rgba(21, 178, 253, 0.5);
+        color: #00adff;
+      }
+      .author {
+        color: #777777;
+        font-size: max(14px, 12px);
+      }
+    }
+  }
+}
+
+.sectionContainer {
+  padding: 24px 60px;
+  gap: 0 30px;
+  flex: 1 auto;
+}
+
+.sectionItem {
+  display: flex;
+  align-items: center;
+  margin: 0 12px 10px;
+  cursor: pointer;
+  padding: 15px 12px;
+  border-radius: 12px;
+  width: 407px;
+  background: #FFFFFF;
+  cursor: pointer;
+
+  .img {
+    width: 60px;
+    height: 60px;
+    background: #ddf2ff;
+    border-radius: 8px;
+    overflow: hidden;
+    margin: 0 16px;
+    img {
+      width: inherit;
+      height: inherit;
+    }
+  }
+
+  .infos {
+    display: flex;
+    flex-direction: column;
+
+    .topName {
+      font-weight: 600;
+      font-size: 20px;
+      color: #131415;
+      line-height: 28px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      max-width: 270px;
+
+      span {
+        color: #198CFE;
+        font-weight: bold;
+      }
+    }
+
+    .types {
+      display: flex;
+      padding-top: 4px;
+      & > div {
+        margin-right: 4px;
+      }
+
+      .hot {
+        background: #fff3f3;
+        border-radius: 3px;
+        border: 1px solid rgba(254, 67, 67, 0.5);
+        font-size: max(12px, 11px);
+        color: #fe4343;
+        padding: 0 5px;
+        &::before {
+          content: '';
+          display: inline-block;
+          width: 10px;
+          height: 12px;
+          background: url('./images/icon-fire.png') no-repeat center;
+          background-size: contain;
+          margin-right: 3px;
+          vertical-align: middle;
+        }
+        span {
+          line-height: 1;
+          vertical-align: text-bottom;
+        }
+      }
+      .sing,
+      .song {
+        background: #ffffff;
+        font-size: max(12px, 11px);
+        border-radius: 3px;
+        padding: 0 4px;
+        line-height: 1;
+        display: flex;
+        align-items: center;
+      }
+      .sing {
+        border: 1px solid rgba(243, 130, 26, 0.5);
+        color: #f3821a;
+      }
+      .song {
+        border: 1px solid rgba(21, 178, 253, 0.5);
+        color: #00adff;
+      }
+      .author {
+        color: #777777;
+        font-size: max(14px, 12px);
+      }
+    }
+  }
+}

+ 166 - 0
src/views/xiaoku-list/index.tsx

@@ -0,0 +1,166 @@
+import {
+  defineComponent
+} from 'vue';
+import styles from './index.module.less';
+import TheSearch from '/src/components/TheSearch';
+import recommendTitle from './images/reommon_title.png';
+import newTitle from './images/new_title.png';
+import hotTitle from './images/hot_title.png';
+import { NScrollbar } from 'naive-ui';
+import TheNoticeBar from '/src/components/TheNoticeBar';
+import { useRouter } from 'vue-router';
+
+export default defineComponent({
+  name: 'xiaoku-list',
+  setup() {
+    const router = useRouter()
+    return () => (
+      <div class={styles.list}>
+        <h2 class={styles.topTitle}>海量曲目 任你选择</h2>
+
+        <div class={styles.searchSection}>
+          <TheSearch
+            round
+            class={styles.searchInput}
+            onSearch={val => {
+              // forms.keyword = val;
+              // getList();
+            }}
+          />
+
+          <div class={styles.moreMusic}>全部曲目</div>
+        </div>
+
+         <div class={styles.container}>
+          <>
+          <div class={[styles.section, styles.recommendSection]}>
+            <div class={styles.sectionTitle}>
+              <img src={recommendTitle} class={styles.imgTitle} />
+
+              <div class={styles.moreBtn}>更多</div>
+            </div>
+
+            <NScrollbar>
+              {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(() => (
+                <div class={styles.item} onClick={() => {
+                  router.push({
+                    path: '/xiaoku-detail'
+                  })
+                }}>
+                  <div class={[styles.num]}>01</div>
+                  <div class={styles.img}>
+                    <img
+                      referrerpolicy="no-referrer"
+                      src="https://lanhu-oss.lanhuapp.com/SketchPnge5215a88a6a2d4a1aba30956f78102bf01fac5e63f33b045c1427d94330297dd"
+                    />
+                  </div>
+                  <div class={styles.infos}>
+                    <div class={styles.topName}>
+                      <TheNoticeBar text='玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲' />
+                    </div>
+                    <div class={styles.types}>
+                      <div class={styles.hot}>
+                        <span>1.8万</span>
+                      </div>
+                      <div class={styles.sing}>演唱</div>
+                      <div class={styles.song}>演奏</div>
+                      <div class={styles.author}>耶寒尔</div>
+                    </div>
+                  </div>
+                </div>
+              ))}
+            </NScrollbar>
+          </div>
+          <div class={[styles.section, styles.hotSection]}>
+            <div class={styles.sectionTitle}>
+              <img src={hotTitle} class={styles.imgTitle} />
+
+              <div class={styles.moreBtn}>更多</div>
+            </div>
+
+            <NScrollbar>
+              {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(() => (
+                <div class={styles.item}>
+                  <div class={[styles.num]}>01</div>
+                  <div class={styles.img}>
+                    <img
+                      referrerpolicy="no-referrer"
+                      src="https://lanhu-oss.lanhuapp.com/SketchPnge5215a88a6a2d4a1aba30956f78102bf01fac5e63f33b045c1427d94330297dd"
+                    />
+                  </div>
+                  <div class={styles.infos}>
+                    <div class={styles.topName}>玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲</div>
+                    <div class={styles.types}>
+                      <div class={styles.hot}>
+                        <span>1.8万</span>
+                      </div>
+                      <div class={styles.sing}>演唱</div>
+                      <div class={styles.song}>演奏</div>
+                      <div class={styles.author}>耶寒尔</div>
+                    </div>
+                  </div>
+                </div>
+              ))}
+            </NScrollbar>
+          </div>
+          <div class={[styles.section, styles.newSection]}>
+            <div class={styles.sectionTitle}>
+              <img src={newTitle} class={styles.imgTitle} />
+
+              <div class={styles.moreBtn}>更多</div>
+            </div>
+
+            <NScrollbar>
+              {[1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(() => (
+                <div class={styles.item}>
+                  <div class={[styles.num]}>01</div>
+                  <div class={styles.img}>
+                    <img
+                      referrerpolicy="no-referrer"
+                      src="https://lanhu-oss.lanhuapp.com/SketchPnge5215a88a6a2d4a1aba30956f78102bf01fac5e63f33b045c1427d94330297dd"
+                    />
+                  </div>
+                  <div class={styles.infos}>
+                    <div class={styles.topName}>玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲</div>
+                    <div class={styles.types}>
+                      <div class={styles.hot}>
+                        <span>1.8万</span>
+                      </div>
+                      <div class={styles.sing}>演唱</div>
+                      <div class={styles.song}>演奏</div>
+                      <div class={styles.author}>耶寒尔</div>
+                    </div>
+                  </div>
+                </div>
+              ))}
+            </NScrollbar>
+          </div></> 
+        </div>
+
+        {/* <div class={styles.sectionContainer}>
+          <div class={styles.sectionItem}>
+            <div class={styles.img}>
+              <img
+                referrerpolicy="no-referrer"
+                src="https://lanhu-oss.lanhuapp.com/SketchPnge5215a88a6a2d4a1aba30956f78102bf01fac5e63f33b045c1427d94330297dd"
+              />
+            </div>
+            <div class={styles.infos}>
+              <div class={styles.topName}>
+                <span>玩具</span>兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲玩具兵进行曲
+              </div>
+              <div class={styles.types}>
+                <div class={styles.hot}>
+                  <span>1.8万</span>
+                </div>
+                <div class={styles.sing}>演唱</div>
+                <div class={styles.song}>演奏</div>
+                <div class={styles.author}>耶寒尔</div>
+              </div>
+            </div>
+          </div>
+        </div> */}
+      </div>
+    );
+  }
+});

+ 338 - 0
src/views/xiaoku-list/search-group-resources.tsx

@@ -0,0 +1,338 @@
+import {
+  defineComponent,
+  nextTick,
+  onMounted,
+  reactive,
+  ref,
+  watch,
+  toRefs
+} from 'vue';
+import styles from './detail.module.less';
+import {
+  NButton,
+  NForm,
+  NFormItem,
+  NImage,
+  NPopselect,
+  NSpace
+} from 'naive-ui';
+// import iconAdd from '../../images/icon-add.png';
+import TheSearch from '/src/components/TheSearch';
+import { resourceTypeArray } from '/src/utils/searchArray';
+import { useCatchStore } from '/src/store/modules/catchData';
+import { audioPlayType } from '/src/utils/contants';
+// import isCollaose from '../../images/isCollaose.png';
+
+const ChildNodeSearch = defineComponent({
+  name: 'ChildNodeSearch',
+  props: {
+    activeRow: {
+      type: Object,
+      default: () => ({})
+    },
+    list: {
+      type: Array,
+      default: () => []
+    }
+  },
+  emits: ['selectChildTag'],
+  setup(props, { emit }) {
+    const { activeRow } = toRefs(props);
+    const selectItem = ref({});
+
+    watch(
+      () => props.activeRow,
+      () => {
+        activeRow.value = props.activeRow;
+        selectItem.value = {};
+      }
+    );
+    return () => (
+      <>
+        {activeRow.value?.id && (
+          <>
+            <NFormItem label={activeRow.value.columnName + ':'}>
+              <NSpace class={styles.spaceSection}>
+                {activeRow.value?.children.map((subject: any) => (
+                  <span
+                    class={[
+                      styles.textBtn,
+                      (activeRow.value.activeIndex || '') == subject.id &&
+                        styles.textBtnActive
+                    ]}
+                    onClick={() => {
+                      activeRow.value.activeIndex = subject.id;
+                      let children: any;
+                      let columnName = '';
+                      if (subject.children) {
+                        children = [
+                          {
+                            columnName: subject.children[0].columnName,
+                            name: '全部',
+                            id: ''
+                          },
+                          ...subject.children
+                        ];
+                        columnName = subject.children[0].columnName;
+
+                        selectItem.value = {
+                          ...subject,
+                          columnName,
+                          activeIndex: '',
+                          children
+                        };
+                      } else {
+                        selectItem.value = {};
+                      }
+                      emit('selectChildTag', activeRow.value.activeIndex);
+                    }}>
+                    {subject.name}
+                  </span>
+                ))}
+              </NSpace>
+            </NFormItem>
+
+            <ChildNodeSearch
+              activeRow={selectItem.value}
+              onSelectChildTag={(item: any) => {
+                emit('selectChildTag', item || activeRow.value.activeIndex);
+              }}
+            />
+          </>
+        )}
+      </>
+    );
+  }
+});
+
+export default defineComponent({
+  name: 'search-group',
+  emits: ['search', 'add'],
+  expose: ['init'],
+  setup(props, { emit }) {
+    const catchStore = useCatchStore();
+    const forms = reactive({
+      type: 'MUSIC', //
+      name: '',
+      // grade: null as any,
+      audioPlayTypes: '',
+      bookVersionId: null as any,
+      subjectId: null
+    });
+    const state = reactive({
+      tempSubjectId: null
+    });
+    const data = reactive({
+      audioPlayTypeList: [] as any, // 场景
+      selectParents: {}, // 选中的数据
+      tags: [] as any[],
+      tagActiveId: '' as any,
+      tagActive: {} as any,
+      childSelectId: null as any
+    });
+
+    const onSearch = () => {
+      emit('search', {
+        ...forms,
+        subjectId: forms.audioPlayTypes !== 'SING' ? forms.subjectId : null,
+        audioPlayTypes: forms.audioPlayTypes
+          ? forms.audioPlayTypes === 'PLAY_SING'
+            ? ['PLAY', 'SING']
+            : [forms.audioPlayTypes]
+          : [],
+        bookVersionId: data.childSelectId || data.tagActiveId
+      });
+    };
+
+    const selectChildObj = (item: any) => {
+      const obj: any = {};
+      item?.forEach((child: any) => {
+        if (child.id === forms.subjectId) {
+          obj.selected = true;
+          obj.name = child.name;
+        }
+      });
+      return obj;
+    };
+
+    const _initTags = () => {
+      const tags = catchStore.getMusicTagTree;
+      data.tags = [
+        {
+          columnName: tags[0].columnName,
+          name: '全部',
+          id: ''
+        },
+        ...tags
+      ];
+      data.tagActiveId = data.tags[0].id;
+    };
+
+    const changeTag = (item: any) => {
+      data.tagActiveId = item.id;
+      data.childSelectId = null;
+      let children: any;
+      let columnName = '';
+      if (item.children) {
+        children = [
+          {
+            columnName: item.children[0].columnName,
+            name: '全部',
+            id: ''
+          },
+          ...item.children
+        ];
+        columnName = item.children[0].columnName;
+        data.selectParents = {
+          ...item,
+          columnName,
+          activeIndex: '',
+          children
+        };
+      } else {
+        data.selectParents = {};
+      }
+
+      onSearch();
+    };
+
+    /** 默认选中第一个声部 */
+    const formatFirstSubject = () => {
+      const tempSubjects = catchStore.getSubjectInstrumentOnly;
+      if (tempSubjects.length > 0) {
+        const firstSubject = tempSubjects[0];
+        if (firstSubject.instruments && firstSubject.instruments.length > 1) {
+          state.tempSubjectId = firstSubject.instruments[0]?.value;
+          forms.subjectId = firstSubject.instruments[0]?.value;
+        } else {
+          forms.subjectId = firstSubject.value;
+        }
+      }
+    };
+    onMounted(async () => {
+      // 场景
+      const tempAudio = Object.keys(audioPlayType).map(key => {
+        return {
+          value: key,
+          name: audioPlayType[key]
+        };
+      });
+      data.audioPlayTypeList = [{ name: '全部', value: '' }, ...tempAudio];
+
+      // console.log('加载');
+      // 获取教材分类列表
+      // await catchStore.getMusicSheetCategory();
+      await catchStore.getMusicTagTreeApi();
+      _initTags();
+      // console.log(data, 'data');
+      // 获取声部列表
+      await catchStore.getSubjects();
+
+      formatFirstSubject();
+      onSearch();
+    });
+    return () => (
+      <div class={styles.searchGroup}>
+        <NForm labelAlign="left" labelPlacement="left">
+          {data.tags.length > 0 && (
+            <NFormItem label={data.tags[0]?.columnName + ':'}>
+              <NSpace class={styles.spaceSection}>
+                {data.tags.map((subject: any) => (
+                  <span
+                    class={[
+                      styles.textBtn,
+                      data.tagActiveId === subject.id && styles.textBtnActive
+                    ]}
+                    onClick={() => {
+                      changeTag(subject);
+                    }}>
+                    {subject.name}
+                  </span>
+                ))}
+              </NSpace>
+            </NFormItem>
+          )}
+
+          <ChildNodeSearch
+            activeRow={data.selectParents}
+            onSelectChildTag={(val: any) => {
+              data.childSelectId = val;
+              onSearch();
+            }}
+          />
+
+          <NFormItem label="场景:">
+            <NSpace class={styles.spaceSection}>
+              {data.audioPlayTypeList.map((subject: any) => (
+                <span
+                  class={[
+                    styles.textBtn,
+
+                    forms.audioPlayTypes === subject.value &&
+                      styles.textBtnActive
+                  ]}
+                  onClick={() => {
+                    forms.audioPlayTypes = subject.value;
+                    onSearch();
+                  }}>
+                  {subject.name}
+                </span>
+              ))}
+            </NSpace>
+          </NFormItem>
+
+          {forms.audioPlayTypes !== 'SING' && (
+            <NFormItem label="乐器:">
+              <NSpace class={styles.spaceSection}>
+                {catchStore.getSubjectInstrumentOnly.map((subject: any) =>
+                  subject.instruments && subject.instruments.length > 1 ? (
+                    <NPopselect
+                      options={subject.instruments}
+                      trigger="hover"
+                      scrollable
+                      v-model:value={state.tempSubjectId}
+                      onUpdate:value={() => {
+                        forms.subjectId = state.tempSubjectId;
+                        onSearch();
+                      }}
+                      key={subject.value}
+                      class={[styles.popSelect]}>
+                      <span
+                        class={[
+                          styles.textBtn,
+                          selectChildObj(subject.instruments).selected &&
+                            styles.textBtnActive
+                        ]}>
+                        {selectChildObj(subject.instruments).name ||
+                          subject.name}
+                        <i class={styles.iconArrow}></i>
+                      </span>
+                    </NPopselect>
+                  ) : (
+                    <span
+                      class={[
+                        styles.textBtn,
+
+                        forms.subjectId === subject.value &&
+                          styles.textBtnActive
+                      ]}
+                      onClick={() => {
+                        forms.subjectId = subject.value;
+
+                        state.tempSubjectId = null;
+                        onSearch();
+                      }}>
+                      {subject.name}
+                    </span>
+                  )
+                )}
+              </NSpace>
+            </NFormItem>
+          )}
+        </NForm>
+
+        <div class={styles.moreSearch}>展开更多</div>
+      </div>
+    );
+  }
+});