瀏覽代碼

添加演唱、演奏搜索条件

lex 9 月之前
父節點
當前提交
d3e8254ce0
共有 39 個文件被更改,包括 1418 次插入788 次删除
  1. 1 1
      dev-dist/sw.js
  2. 二進制
      src/common/images/icon-play-active.png
  3. 二進制
      src/common/images/icon-play-default.png
  4. 二進制
      src/common/images/icon-sing-active.png
  5. 二進制
      src/common/images/icon-sing-default.png
  6. 二進制
      src/components/CCascader/images/icon-arrow-down_small.png
  7. 二進制
      src/components/CCascader/images/icon-arrow-up_small.png
  8. 9 1
      src/components/CCascader/index.module.less
  9. 87 6
      src/components/CCascader/index.tsx
  10. 63 62
      src/components/TheSearch/index.module.less
  11. 69 65
      src/components/TheSearch/index.tsx
  12. 293 249
      src/components/card-type/index.module.less
  13. 53 7
      src/components/card-type/index.tsx
  14. 83 74
      src/utils/contants.ts
  15. 1 1
      src/views/attend-class/index.module.less
  16. 3 0
      src/views/attend-class/index.tsx
  17. 105 104
      src/views/attend-class/model/source-list/index.tsx
  18. 38 1
      src/views/attend-class/model/train-type/index.module.less
  19. 24 0
      src/views/attend-class/model/train-type/index.tsx
  20. 4 1
      src/views/attend-class/model/train-update/index.tsx
  21. 3 0
      src/views/natural-resources/components/my-collect/index.tsx
  22. 87 39
      src/views/natural-resources/components/my-collect/search-group-resources.tsx
  23. 3 0
      src/views/natural-resources/components/my-resources/index.tsx
  24. 2 0
      src/views/natural-resources/components/my-resources/search-group-resources.tsx
  25. 4 0
      src/views/natural-resources/components/share-resources/index.tsx
  26. 84 51
      src/views/natural-resources/components/share-resources/search-group-resources.tsx
  27. 4 0
      src/views/prepare-lessons/components/lesson-main/courseware/addCourseware.tsx
  28. 5 0
      src/views/prepare-lessons/components/resource-main/components/resource-item/index.tsx
  29. 19 1
      src/views/prepare-lessons/components/resource-main/components/resource-item/resource-search-group/index.tsx
  30. 7 0
      src/views/prepare-lessons/components/resource-main/components/select-music/index.tsx
  31. 1 0
      src/views/prepare-lessons/components/resource-main/index.tsx
  32. 9 1
      src/views/prepare-lessons/model/select-music/index.tsx
  33. 16 4
      src/views/prepare-lessons/model/select-music/select-item/index.tsx
  34. 1 1
      src/views/prepare-lessons/model/select-resources/index.tsx
  35. 94 37
      src/views/prepare-lessons/model/select-resources/select-item/class-search-group/index.tsx
  36. 5 0
      src/views/prepare-lessons/model/select-resources/select-item/index.tsx
  37. 88 39
      src/views/prepare-lessons/model/select-resources/select-item/resource-search-group/index.tsx
  38. 32 1
      src/views/xiaoku-music/index.module.less
  39. 121 42
      src/views/xiaoku-music/index.tsx

+ 1 - 1
dev-dist/sw.js

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

二進制
src/common/images/icon-play-active.png


二進制
src/common/images/icon-play-default.png


二進制
src/common/images/icon-sing-active.png


二進制
src/common/images/icon-sing-default.png


二進制
src/components/CCascader/images/icon-arrow-down_small.png


二進制
src/components/CCascader/images/icon-arrow-up_small.png


+ 9 - 1
src/components/CCascader/index.module.less

@@ -74,6 +74,14 @@
         height: inherit;
       }
     }
+
+    .arrowSmall {
+      margin-top: 2px;
+      width: 9Px;
+      height: 5Px;
+      display: flex;
+      align-items: center;
+    }
   }
 
   .n-base-selection-placeholder {
@@ -192,4 +200,4 @@
     background: linear-gradient(312deg, #1B7AF8 0%, #3CBBFF 100%);
     color: #FFFFFF;
   }
-}
+}

+ 87 - 6
src/components/CCascader/index.tsx

@@ -12,10 +12,18 @@ import {
 import styles from './index.module.less';
 import arrowDown from './images/icon-arrow-down.png';
 import arrowUp from './images/icon-arrow-up.png';
+import arrowDownSmall from './images/icon-arrow-down_small.png';
+import arrowUpSmall from './images/icon-arrow-up_small.png';
+import { audioPlayType } from '/src/utils/contants';
 
 export default defineComponent({
   name: 'c-cascader',
   props: {
+    /** 是否显示场景搜索条件 */
+    showAudioPlayType: {
+      type: Boolean,
+      default: false
+    },
     value: {
       type: String,
       default: ''
@@ -24,6 +32,10 @@ export default defineComponent({
       type: Array as PropType<any[]>,
       default: () => []
     },
+    arrowType: {
+      type: String as PropType<'default' | 'small'>,
+      default: 'default'
+    },
     placeholder: {
       type: String,
       default: '请选择'
@@ -42,12 +54,15 @@ export default defineComponent({
     const state = reactive({
       popoverShow: false,
       selectParents: {}, // 选中的数据
+      tempAudioPlayTypes: '',
+      audioPlayTypes: '',
       tagActiveId: '' as any,
       tagActive: {} as any,
       childSelectId: null as any,
       x: 0,
       y: 0
     });
+    const audioPlayTypeList = ref([] as any);
 
     // const formatParentCurrentValue = (ids: any, list: any) => {
     //   for (const item of list) {
@@ -120,6 +135,11 @@ export default defineComponent({
       const id = props.value;
       const values = getValues(id);
       const names: any = [];
+      audioPlayTypeList.value.forEach((item: any) => {
+        if (item.id === state.tempAudioPlayTypes && state.tempAudioPlayTypes) {
+          names.push(item.name);
+        }
+      });
       values.forEach((item: any) => {
         names.push(item.name);
       });
@@ -172,11 +192,14 @@ export default defineComponent({
     const onReset = () => {
       state.childSelectId = null;
       state.tagActiveId = '';
+      state.audioPlayTypes = '';
+      state.tempAudioPlayTypes = '';
       state.selectParents = {};
       emit('update:value', '');
       emit('moreId', {
         childId: '',
-        parentId: ''
+        parentId: '',
+        audioPlayTypes: ''
       });
       state.popoverShow = false;
     };
@@ -186,10 +209,22 @@ export default defineComponent({
       emit('update:value', state.childSelectId || state.tagActiveId);
       emit('moreId', {
         childId: state.childSelectId,
-        parentId: state.tagActiveId
+        parentId: state.tagActiveId,
+        audioPlayTypes: state.audioPlayTypes
       });
+      state.tempAudioPlayTypes = state.audioPlayTypes;
       state.popoverShow = false;
     };
+    onMounted(() => {
+      // 场景
+      const tempAudio = Object.keys(audioPlayType).map(key => {
+        return {
+          id: key,
+          name: audioPlayType[key]
+        };
+      });
+      audioPlayTypeList.value = [{ name: '全部场景', id: '' }, ...tempAudio];
+    });
     return () => (
       <>
         <NPopover
@@ -204,10 +239,15 @@ export default defineComponent({
               <div
                 class={[
                   styles.nBaseCascaser,
+                  'nBaseCascaser',
                   state.popoverShow ? styles.nBaseCascaserActive : ''
                 ]}
                 title={valueText.value}>
-                <div class={styles['n-base-selection-tags']}>
+                <div
+                  class={[
+                    styles['n-base-selection-tags'],
+                    'n-base-selection-tags'
+                  ]}>
                   <div class={styles['n-base-selection-input']}>
                     <div class={styles['n-base-selection-input__content']}>
                       {valueText.value}
@@ -215,8 +255,21 @@ export default defineComponent({
                   </div>
 
                   <div class={[styles['n-base-suffix']]}>
-                    <div class={[styles.arrow]}>
-                      <img src={state.popoverShow ? arrowUp : arrowDown} />
+                    <div
+                      class={[
+                        styles.arrow,
+                        props.arrowType === 'small' ? styles.arrowSmall : ''
+                      ]}>
+                      {props.arrowType === 'default' && (
+                        <img src={state.popoverShow ? arrowUp : arrowDown} />
+                      )}
+                      {props.arrowType === 'small' && (
+                        <img
+                          src={
+                            state.popoverShow ? arrowUpSmall : arrowDownSmall
+                          }
+                        />
+                      )}
                     </div>
                   </div>
                 </div>
@@ -229,7 +282,11 @@ export default defineComponent({
                     <div class={styles.inner}>{props.placeholder}</div>
                   )}
                 </div>
-                <div class={styles['n-base-selection__border']}></div>
+                <div
+                  class={[
+                    styles['n-base-selection__border'],
+                    'n-base-selection__border'
+                  ]}></div>
                 <div class={styles['n-base-selection__state-border']}></div>
               </div>
             ),
@@ -238,6 +295,30 @@ export default defineComponent({
                 <NScrollbar
                   class={styles.baseScrollBar}
                   style={{ maxHeight: '400px' }}>
+                  {props.showAudioPlayType && (
+                    <>
+                      <div class={styles.baseContentTitle}>场景</div>
+                      <div class={styles.baseContentWrap}>
+                        {audioPlayTypeList.value.map((subject: any) => (
+                          <span
+                            class={[
+                              styles.tag,
+                              (state.audioPlayTypes || '') == subject.id &&
+                                styles.tagActive
+                            ]}
+                            onClick={() => {
+                              if (state.audioPlayTypes !== subject.id) {
+                                state.childSelectId = null;
+                              }
+                              state.audioPlayTypes = subject.id;
+                            }}>
+                            {subject.name}
+                          </span>
+                        ))}
+                      </div>
+                    </>
+                  )}
+
                   <div class={styles.baseContentTitle}>
                     {props.options[0].columnName}
                   </div>

+ 63 - 62
src/components/TheSearch/index.module.less

@@ -1,62 +1,63 @@
-.TheSearch {
-  border-radius: 20px !important;
-
-  &.noBorder {
-    --n-border: none !important;
-  }
-
-
-  :global {
-    .n-input-wrapper {
-      padding-left: 12px;
-      padding-right: 4px;
-      height: 42px !important;
-    }
-
-    .n-button {
-      height: 34px;
-      font-size: max(16px, 13Px);
-      font-weight: 500;
-      width: auto;
-      opacity: 0.7;
-    }
-
-    .n-input__placeholder {
-      font-size: max(15px, 13Px);
-    }
-  }
-
-  .active {
-    display: none;
-  }
-
-  .active,
-  .default {
-    width: max(16px, 14Px);
-    height: max(16px, 14Px);
-  }
-
-  &:global(.n-input--focus) {
-    .active {
-      display: block;
-    }
-
-    .default {
-      display: none;
-    }
-
-    :global {
-      .n-button {
-        opacity: 1;
-      }
-    }
-  }
-
-  &:hover {
-    :global {
-      .n-button {
-        opacity: 1;
-      }
-    }
-  }
-}
+.TheSearch {
+  border-radius: 20px !important;
+
+  &.noBorder {
+    --n-border: none !important;
+  }
+
+
+  :global {
+    .n-input-wrapper {
+      padding-left: 12px;
+      padding-right: 4px;
+      height: 42px !important;
+      --n-height: 42px !important;
+    }
+
+    .n-button {
+      height: 34px;
+      font-size: max(16px, 13Px);
+      font-weight: 500;
+      width: auto;
+      opacity: 0.7;
+    }
+
+    .n-input__placeholder {
+      font-size: max(15px, 13Px);
+    }
+  }
+
+  .active {
+    display: none;
+  }
+
+  .active,
+  .default {
+    width: max(16px, 14Px);
+    height: max(16px, 14Px);
+  }
+
+  &:global(.n-input--focus) {
+    .active {
+      display: block;
+    }
+
+    .default {
+      display: none;
+    }
+
+    :global {
+      .n-button {
+        opacity: 1;
+      }
+    }
+  }
+
+  &:hover {
+    :global {
+      .n-button {
+        opacity: 1;
+      }
+    }
+  }
+}

+ 69 - 65
src/components/TheSearch/index.tsx

@@ -1,65 +1,69 @@
-import { PropType, defineComponent, reactive } from 'vue';
-import styles from './index.module.less';
-import { InputProps, NButton, NInput } from 'naive-ui';
-import icon_search from '/src/common/images/icon_search.png';
-import icon_searchActive from '/src/common/images/icon_searchActive.png';
-
-export default defineComponent({
-  name: 'TheSearch',
-  props: {
-    /** 圆角 */
-    round: {
-      type: Boolean as PropType<InputProps['round']>,
-      default: false
-    },
-    border: {
-      type: Boolean,
-      default: true
-    },
-    placeholder: {
-      type: String,
-      default: '请输入搜索关键词'
-    }
-  },
-  emits: ['search'],
-  setup(props, { emit }) {
-    const searchData = reactive({
-      value: ''
-    });
-    return () => (
-      <NInput
-        class={[styles.TheSearch, props.border ? '' : styles.noBorder]}
-        round={props.round}
-        placeholder={props.placeholder}
-        clearable
-        v-model:value={searchData.value}
-        onClear={() => emit('search', '')}
-        onKeyup={(e: KeyboardEvent) => {
-          e.stopPropagation();
-          if (e.code === 'Enter') {
-            emit('search', searchData.value ? searchData.value.trim() : '');
-          }
-        }}>
-        {{
-          prefix: () => (
-            <>
-              <img class={styles.default} src={icon_search} />
-              <img class={styles.active} src={icon_searchActive} />
-            </>
-          ),
-          suffix: () => (
-            <NButton
-              size="small"
-              round
-              type="primary"
-              onClick={() =>
-                emit('search', searchData.value ? searchData.value.trim() : '')
-              }>
-              搜索
-            </NButton>
-          )
-        }}
-      </NInput>
-    );
-  }
-});
+import { PropType, defineComponent, reactive } from 'vue';
+import styles from './index.module.less';
+import { InputProps, NButton, NInput } from 'naive-ui';
+import icon_search from '/src/common/images/icon_search.png';
+import icon_searchActive from '/src/common/images/icon_searchActive.png';
+
+export default defineComponent({
+  name: 'TheSearch',
+  props: {
+    /** 圆角 */
+    round: {
+      type: Boolean as PropType<InputProps['round']>,
+      default: false
+    },
+    border: {
+      type: Boolean,
+      default: true
+    },
+    placeholder: {
+      type: String,
+      default: '请输入搜索关键词'
+    }
+  },
+  emits: ['search'],
+  setup(props, { emit }) {
+    const searchData = reactive({
+      value: ''
+    });
+    return () => (
+      <NInput
+        class={[
+          styles.TheSearch,
+          props.border ? '' : styles.noBorder,
+          'TheSearch'
+        ]}
+        round={props.round}
+        placeholder={props.placeholder}
+        clearable
+        v-model:value={searchData.value}
+        onClear={() => emit('search', '')}
+        onKeyup={(e: KeyboardEvent) => {
+          e.stopPropagation();
+          if (e.code === 'Enter') {
+            emit('search', searchData.value ? searchData.value.trim() : '');
+          }
+        }}>
+        {{
+          prefix: () => (
+            <>
+              <img class={styles.default} src={icon_search} />
+              <img class={styles.active} src={icon_searchActive} />
+            </>
+          ),
+          suffix: () => (
+            <NButton
+              size="small"
+              round
+              type="primary"
+              onClick={() =>
+                emit('search', searchData.value ? searchData.value.trim() : '')
+              }>
+              搜索
+            </NButton>
+          )
+        }}
+      </NInput>
+    );
+  }
+});

+ 293 - 249
src/components/card-type/index.module.less

@@ -1,249 +1,293 @@
-:global {
-  .n-card--bordered {
-    border: 1Px solid rgba(202, 228, 244, 1) !important;
-
-    &:hover {
-      border: 1Px solid rgba(0, 122, 254, 1) !important;
-    }
-  }
-}
-
-.card-section-content {
-  border-radius: 14px;
-  background: linear-gradient(270deg, #DBF1FF 0%, #E7F9FF 100%) !important;
-
-  // :global {
-  //   .n-card-cover {
-  //     border-radius: 14px !important;
-  //   }
-  // }
-
-  // 图片禁止拖动
-  img {
-    -moz-user-select: none;
-    /* 火狐浏览器 */
-    -webkit-user-drag: none;
-    /* 谷歌、Safari和Opera浏览器 */
-    -webkit-user-select: none;
-    /* 谷歌、Safari和Opera浏览器 */
-    -ms-user-select: none;
-    /* IE10+浏览器 */
-    user-select: none;
-    /* 通用 */
-    -webkit-touch-callout: none;
-    /* iOS Safari */
-  }
-
-  &.isActive {
-    border: 2px solid rgba(0, 122, 254, 1) !important;
-  }
-
-}
-
-.card-section {
-  position: relative;
-  box-sizing: border-box;
-  width: 300px;
-  height: 220px;
-  border-radius: 14px;
-  background: linear-gradient(270deg, #DBF1FF 0%, #E7F9FF 100%) !important;
-  display: inline-flex;
-  transition: all .3s ease-in-out;
-
-  &.cardDrag {
-    cursor: move;
-
-    :global {
-      .n-image:not(.n-image--preview-disabled) {
-        cursor: move !important;
-      }
-    }
-  }
-
-  &.course {
-    cursor: pointer;
-  }
-
-
-
-  // 鼠标经过时样式
-  &:hover,
-  &.showAddBtn {
-    transform: scale(1.01);
-    transition: all .3s ease-in-out;
-
-
-    .addBtn {
-      display: block;
-      opacity: 1;
-      transition: all .3s ease-in-out;
-    }
-  }
-
-
-  // 封面样式
-  .cover {
-    width: 100%;
-    height: 100%;
-    background-color: #fff;
-    border-radius: 14px 14px 0 0;
-    overflow: hidden;
-
-    img {
-      height: fit-content;
-      min-height: 100%;
-    }
-  }
-
-
-  :global {
-    .n-card__footer {
-      padding: 10px 12px;
-    }
-
-    .n-card-cover {
-      // height: 170px;
-      flex: 1 auto;
-    }
-  }
-
-  .footer {
-    display: flex;
-    align-items: center;
-    justify-content: space-between;
-    // padding: 3px 0;
-  }
-
-  .title {
-    display: flex;
-    align-items: center;
-
-    .titleType {
-      width: 13Px;
-      height: 13Px;
-      margin-top: 1px;
-    }
-
-    .titleContent {
-      padding-left: 6px;
-      font-size: max(16px, 12Px);
-      max-width: 160px;
-      color: #131415;
-      font-weight: 600 !important;
-      flex: 1;
-    }
-  }
-
-  // 收藏按钮
-  .btnGroup {
-    position: absolute;
-    right: 12px;
-    display: flex;
-    align-items: center;
-
-    :global {
-      .n-spin-content {
-        display: flex;
-        align-items: center;
-      }
-    }
-  }
-
-
-  .btnItem+.btnItem {
-    margin-left: 12px;
-  }
-
-  .iconCollect {
-    width: 34px;
-    height: 34px;
-    // background: url('../../common/images/icon-collect-default.png') no-repeat center;
-    // background-size: contain;
-    // position: absolute;
-    // right: 0;
-    transition: transform .2s ease;
-
-    &:hover {
-      transform: scale(1.1);
-      transition: transform .2s ease;
-    }
-
-    &.isCollect {
-      cursor: pointer;
-    }
-  }
-
-  .iconDiv {
-    right: 12px;
-  }
-
-  // 精选
-  .iconSelected {
-    background: url('../../common/images/icon-selected.png') no-repeat center;
-    background-size: contain;
-    position: absolute;
-    top: 0px;
-    left: 0px;
-    z-index: 9;
-    width: 58px;
-    height: 29px;
-    border-top-left-radius: 14px;
-  }
-
-  // 添加
-  .addBtn {
-    position: absolute;
-    top: 6px;
-    right: 6px;
-    font-size: max(16px, 12Px);
-    font-weight: 600 !important;
-    height: 32px;
-    border-radius: 8px;
-    // display: none;
-    // opacity: 0;
-    z-index: 99;
-    transition: all .3s ease-in-out;
-
-    &.addBtnDisabled {
-      background-color: #fff;
-      color: #999;
-      font-weight: bold !important;
-      --n-border: 1px solid #fff !important;
-      --n-border-hover: 1px solid #fff !important;
-      --n-border-pressed: 1px solid #fff !important;
-      --n-border-focus: 1px solid #fff !important;
-      --n-border-disabled: 1px solid #fff !important;
-      --n-opacity-disabled: 1 !important;
-    }
-  }
-
-
-  .offShelfBg {
-    position: absolute;
-    top: 0;
-    left: 0;
-    width: 100%;
-    height: 100%;
-    border-radius: 14px;
-    background-color: rgba(0, 0, 0, 0.7);
-    z-index: 10;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    flex-direction: column;
-
-    .offShelfTips {
-      font-size: 22px;
-      font-weight: 600;
-      color: #FFFFFF;
-      line-height: 30px;
-      padding-bottom: 32px;
-    }
-
-    .offShelfBtn {
-      height: 44px;
-      border-radius: 10px;
-      min-width: 124px;
-    }
-  }
-}
+:global {
+  .n-card--bordered {
+    border: 1Px solid rgba(202, 228, 244, 1) !important;
+
+    &:hover {
+      border: 1Px solid rgba(0, 122, 254, 1) !important;
+    }
+  }
+}
+
+.card-section-content {
+  border-radius: 14px;
+  background: linear-gradient(270deg, #DBF1FF 0%, #E7F9FF 100%) !important;
+
+  // :global {
+  //   .n-card-cover {
+  //     border-radius: 14px !important;
+  //   }
+  // }
+
+  // 图片禁止拖动
+  img {
+    -moz-user-select: none;
+    /* 火狐浏览器 */
+    -webkit-user-drag: none;
+    /* 谷歌、Safari和Opera浏览器 */
+    -webkit-user-select: none;
+    /* 谷歌、Safari和Opera浏览器 */
+    -ms-user-select: none;
+    /* IE10+浏览器 */
+    user-select: none;
+    /* 通用 */
+    -webkit-touch-callout: none;
+    /* iOS Safari */
+  }
+
+  &.isActive {
+    border: 2px solid rgba(0, 122, 254, 1) !important;
+  }
+
+}
+
+.card-section {
+  position: relative;
+  box-sizing: border-box;
+  width: 300px;
+  height: 220px;
+  border-radius: 14px;
+  background: linear-gradient(270deg, #DBF1FF 0%, #E7F9FF 100%) !important;
+  display: inline-flex;
+  transition: all .3s ease-in-out;
+
+  &.cardDrag {
+    cursor: move;
+
+    :global {
+      .n-image:not(.n-image--preview-disabled) {
+        cursor: move !important;
+      }
+    }
+  }
+
+  &.course {
+    cursor: pointer;
+  }
+
+
+
+  // 鼠标经过时样式
+  &:hover,
+  &.showAddBtn {
+    transform: scale(1.01);
+    transition: all .3s ease-in-out;
+
+
+    .addBtn {
+      display: block;
+      opacity: 1;
+      transition: all .3s ease-in-out;
+    }
+  }
+
+
+  // 封面样式
+  .cover {
+    width: 100%;
+    height: 100%;
+    background-color: #fff;
+    border-radius: 14px 14px 0 0;
+    overflow: hidden;
+
+    img {
+      height: fit-content;
+      min-height: 100%;
+    }
+  }
+
+
+  :global {
+    .n-card__footer {
+      padding: 10px 12px;
+    }
+
+    .n-card-cover {
+      // height: 170px;
+      position: relative;
+      flex: 1 auto;
+    }
+  }
+
+  .audioPlayTypeSection {
+    position: absolute;
+    bottom: 10px;
+    right: 12px;
+    font-size: 0;
+    gap: 8px 10px !important;
+
+    &.audioPlayTypeSmall {
+      .iconType {
+        display: inline-block;
+        width: 22px;
+        height: 22px;
+      }
+
+    }
+
+    .iconType {
+      display: inline-block;
+      width: 24px;
+      height: 24px;
+    }
+
+    .iconPlay {
+      background: url('../../common/images/icon-play-default.png');
+      background-size: contain;
+
+      &:hover {
+        background: url('../../common/images/icon-play-active.png');
+        background-size: contain;
+      }
+    }
+
+    .iconSing {
+      background: url('../../common/images/icon-sing-default.png');
+      background-size: contain;
+
+      &:hover {
+        background: url('../../common/images/icon-sing-active.png');
+        background-size: contain;
+      }
+    }
+  }
+
+  .footer {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    // padding: 3px 0;
+  }
+
+  .title {
+    display: flex;
+    align-items: center;
+
+    .titleType {
+      width: 13Px;
+      height: 13Px;
+      margin-top: 1px;
+    }
+
+    .titleContent {
+      padding-left: 6px;
+      font-size: max(16px, 12Px);
+      max-width: 160px;
+      color: #131415;
+      font-weight: 600 !important;
+      flex: 1;
+    }
+  }
+
+  // 收藏按钮
+  .btnGroup {
+    position: absolute;
+    right: 12px;
+    display: flex;
+    align-items: center;
+
+    :global {
+      .n-spin-content {
+        display: flex;
+        align-items: center;
+      }
+    }
+  }
+
+
+  .btnItem+.btnItem {
+    margin-left: 12px;
+  }
+
+  .iconCollect {
+    width: 34px;
+    height: 34px;
+    // background: url('../../common/images/icon-collect-default.png') no-repeat center;
+    // background-size: contain;
+    // position: absolute;
+    // right: 0;
+    transition: transform .2s ease;
+
+    &:hover {
+      transform: scale(1.1);
+      transition: transform .2s ease;
+    }
+
+    &.isCollect {
+      cursor: pointer;
+    }
+  }
+
+  .iconDiv {
+    right: 12px;
+  }
+
+  // 精选
+  .iconSelected {
+    background: url('../../common/images/icon-selected.png') no-repeat center;
+    background-size: contain;
+    position: absolute;
+    top: 0px;
+    left: 0px;
+    z-index: 9;
+    width: 58px;
+    height: 29px;
+    border-top-left-radius: 14px;
+  }
+
+  // 添加
+  .addBtn {
+    position: absolute;
+    top: 6px;
+    right: 6px;
+    font-size: max(16px, 12Px);
+    font-weight: 600 !important;
+    height: 32px;
+    border-radius: 8px;
+    // display: none;
+    // opacity: 0;
+    z-index: 99;
+    transition: all .3s ease-in-out;
+
+    &.addBtnDisabled {
+      background-color: #fff;
+      color: #999;
+      font-weight: bold !important;
+      --n-border: 1px solid #fff !important;
+      --n-border-hover: 1px solid #fff !important;
+      --n-border-pressed: 1px solid #fff !important;
+      --n-border-focus: 1px solid #fff !important;
+      --n-border-disabled: 1px solid #fff !important;
+      --n-opacity-disabled: 1 !important;
+    }
+  }
+
+
+  .offShelfBg {
+    position: absolute;
+    top: 0;
+    left: 0;
+    width: 100%;
+    height: 100%;
+    border-radius: 14px;
+    background-color: rgba(0, 0, 0, 0.7);
+    z-index: 10;
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    flex-direction: column;
+
+    .offShelfTips {
+      font-size: 22px;
+      font-weight: 600;
+      color: #FFFFFF;
+      line-height: 30px;
+      padding-bottom: 32px;
+    }
+
+    .offShelfBtn {
+      height: 44px;
+      border-radius: 10px;
+      min-width: 124px;
+    }
+  }
+}

+ 53 - 7
src/components/card-type/index.tsx

@@ -6,7 +6,9 @@ import {
   NCard,
   NImage,
   NModal,
+  NSpace,
   NSpin,
+  NTooltip,
   useMessage
 } from 'naive-ui';
 import iconImage from '@common/images/icon-image.png';
@@ -45,6 +47,7 @@ type itemType = {
   content?: string;
   title: string;
   isCollect: boolean;
+  audioPlayTypeArray?: string[];
   isSelected: boolean; // 精选
   exist?: boolean; // 是否已经选
 };
@@ -105,6 +108,10 @@ export default defineComponent({
     isDownload: {
       type: Boolean,
       default: false
+    },
+    audioPlayTypeSize: {
+      type: String as PropType<'default' | 'small'>,
+      deafult: 'default'
     }
   },
   /**
@@ -323,13 +330,52 @@ export default defineComponent({
                 )}
                 {/* 乐谱 */}
                 {props.item.type === 'MUSIC' && (
-                  <NImage
-                    class={[styles.cover, styles.image]}
-                    lazy
-                    previewDisabled={true}
-                    objectFit="contain"
-                    src={props.item.coverImg}
-                  />
+                  <>
+                    <NImage
+                      class={[styles.cover, styles.image]}
+                      lazy
+                      previewDisabled={true}
+                      objectFit="contain"
+                      src={props.item.coverImg}
+                    />
+                    <NSpace
+                      class={[
+                        styles.audioPlayTypeSection,
+                        props.audioPlayTypeSize === 'small'
+                          ? styles.audioPlayTypeSmall
+                          : ''
+                      ]}>
+                      {props.item.audioPlayTypeArray?.includes('PLAY') && (
+                        <NTooltip trigger="hover" showArrow={false}>
+                          {{
+                            trigger: () => (
+                              <span
+                                class={[
+                                  styles.iconType,
+                                  styles.iconPlay
+                                ]}></span>
+                            ),
+                            default: '演奏场景'
+                          }}
+                        </NTooltip>
+                      )}
+
+                      {props.item.audioPlayTypeArray?.includes('SING') && (
+                        <NTooltip trigger="hover" showArrow={false}>
+                          {{
+                            trigger: () => (
+                              <span
+                                class={[
+                                  styles.iconType,
+                                  styles.iconSing
+                                ]}></span>
+                            ),
+                            default: '演唱场景'
+                          }}
+                        </NTooltip>
+                      )}
+                    </NSpace>
+                  </>
                 )}
                 {/* 音频 */}
                 {props.item.type === 'SONG' && (

+ 83 - 74
src/utils/contants.ts

@@ -1,74 +1,83 @@
-/**
- * @description: 教材
- */
-export const teaching = {
-  1: '人教版',
-  2: '声部训练',
-  3: '小曲目',
-  4: '考级曲目'
-};
-
-/**
- * @description: 乐器
- */
-export const instrument = {
-  1: '坚笛',
-  2: '排萧',
-  3: '口风琴',
-  4: '陶笛',
-  5: '葫芦丝'
-};
-
-/**
- * @description: 资源类型
- */
-export const resourceType = {
-  MUSIC: '乐谱',
-  IMG: '图片',
-  SONG: '音频',
-  VIDEO: '视频',
-  PPT: 'PPT'
-};
-
-/**
- * @description: 评测难度
- * 入门:BEGINNER/进阶:ADVANCED/大师:PERFORMER")
- */
-export const evaluateDifficult = {
-  BEGINNER: '入门级',
-  ADVANCED: '进阶级',
-  PERFORMER: '大师级'
-} as any;
-
-/**
- * 训练完成状态
- */
-export const trainingStatus = {
-  UNSUBMITTED: '未提交',
-  SUBMITTED: '不合格',
-  TARGET: '合格'
-} as any;
-
-/** 周 */
-export const weekToCN = {
-  0: '星期天',
-  1: '星期一',
-  2: '星期二',
-  3: '星期三',
-  4: '星期四',
-  5: '星期五',
-  6: '星期六'
-} as any;
-
-/** 年级 */
-export const gradeToCN = {
-  1: '一年级',
-  2: '二年级',
-  3: '三年级',
-  4: '四年级',
-  5: '五年级',
-  6: '六年级',
-  7: '七年级',
-  8: '八年级',
-  9: '九年级'
-} as any;
+/**
+ * @description: 教材
+ */
+export const teaching = {
+  1: '人教版',
+  2: '声部训练',
+  3: '小曲目',
+  4: '考级曲目'
+};
+
+/**
+ * @description: 乐器
+ */
+export const instrument = {
+  1: '坚笛',
+  2: '排萧',
+  3: '口风琴',
+  4: '陶笛',
+  5: '葫芦丝'
+};
+
+/**
+ * @description: 资源类型
+ */
+export const resourceType = {
+  MUSIC: '乐谱',
+  IMG: '图片',
+  SONG: '音频',
+  VIDEO: '视频',
+  PPT: 'PPT'
+};
+
+/**
+ * @description: 评测难度
+ * 入门:BEGINNER/进阶:ADVANCED/大师:PERFORMER")
+ */
+export const evaluateDifficult = {
+  BEGINNER: '入门级',
+  ADVANCED: '进阶级',
+  PERFORMER: '大师级'
+} as any;
+
+/**
+ * 训练完成状态
+ */
+export const trainingStatus = {
+  UNSUBMITTED: '未提交',
+  SUBMITTED: '不合格',
+  TARGET: '合格'
+} as any;
+
+/** 周 */
+export const weekToCN = {
+  0: '星期天',
+  1: '星期一',
+  2: '星期二',
+  3: '星期三',
+  4: '星期四',
+  5: '星期五',
+  6: '星期六'
+} as any;
+
+/** 年级 */
+export const gradeToCN = {
+  1: '一年级',
+  2: '二年级',
+  3: '三年级',
+  4: '四年级',
+  5: '五年级',
+  6: '六年级',
+  7: '七年级',
+  8: '八年级',
+  9: '九年级'
+} as any;
+
+/**
+ * 场景
+ */
+export const audioPlayType = {
+  PLAY: '演奏',
+  SING: '演唱',
+  PLAY_SING: '演奏+演唱'
+} as any;

+ 1 - 1
src/views/attend-class/index.module.less

@@ -929,4 +929,4 @@
       }
     }
   }
-}
+}

+ 3 - 0
src/views/attend-class/index.tsx

@@ -260,6 +260,9 @@ export default defineComponent({
                 dataJson: child.dataJson,
                 isCollect: !!child.favoriteFlag,
                 isSelected: child.source === 'PLATFORM' ? true : false,
+                audioPlayTypeArray: child.audioPlayTypes
+                  ? child.audioPlayTypes.split(',')
+                  : [],
                 content: child.bizInfo.content,
                 parentIndex: index
               });

+ 105 - 104
src/views/attend-class/model/source-list/index.tsx

@@ -1,104 +1,105 @@
-import { NCollapse, NCollapseItem, NScrollbar } from 'naive-ui';
-import { computed, defineComponent, ref, watch } from 'vue';
-import CardType from '/src/components/card-type';
-import styles from './index.module.less';
-
-export default defineComponent({
-  name: 'source-list',
-  props: {
-    knowledgePointList: {
-      type: Array,
-      default: () => []
-    },
-    activeItem: {
-      type: Object,
-      default: () => ({})
-    },
-    /** 当前播放的是第几个知识点组 */
-    courseActiveIndex: {
-      type: Number,
-      default: 0
-    },
-    teacherChapterName: {
-      type: String,
-      default: ''
-    }
-  },
-  emits: ['confirm'],
-  setup(props, { emit }) {
-    const parentIndex = ref(props.courseActiveIndex);
-
-    watch(
-      () => props.courseActiveIndex,
-      () => {
-        parentIndex.value = props.courseActiveIndex;
-      }
-    );
-
-    const childIndex = computed(() => {
-      let index = 0;
-      props.knowledgePointList.forEach((item: any) => {
-        item.list.forEach((child: any, j: number) => {
-          if (child.id === props.activeItem.id) {
-            index = j;
-          }
-        });
-      });
-      return index;
-    });
-    return () => (
-      <div class={styles.sourcelistBox}>
-        <div class={styles.treeBox}>
-          <div class={[styles.listSectionLeft]}>
-            <NScrollbar class={styles.leftscrollBar}>
-              {props.teacherChapterName && (
-                <div class={styles.className}>
-                  <i class={styles.classNameIcon}></i>
-                  <p class={styles.classNameContent}>
-                    {props.teacherChapterName}
-                  </p>
-                </div>
-              )}
-              {props.knowledgePointList.map((item: any, index: number) => (
-                <div
-                  class={[
-                    styles.treeParent,
-                    parentIndex.value === index && styles.parentSelect
-                  ]}
-                  key={'parent' + index}
-                  onClick={() => {
-                    parentIndex.value = index;
-                  }}>
-                  {item.title}
-                </div>
-              ))}
-            </NScrollbar>
-          </div>
-          <div class={[styles.listSectionRight]}>
-            <NScrollbar class={styles.rightscrollBar}>
-              {(props.knowledgePointList[parentIndex.value] as any)?.list &&
-                (props.knowledgePointList[parentIndex.value] as any).list.map(
-                  (child: any, j: number) => (
-                    <div class={[styles.cardContainer, 'drawerCardItemRef']}>
-                      <CardType
-                        item={child}
-                        isActive={
-                          childIndex.value === j &&
-                          parentIndex.value === props.courseActiveIndex
-                        }
-                        isCollect={false}
-                        isShowCollect={false}
-                        onClick={() => {
-                          emit('confirm', child);
-                        }}
-                      />
-                    </div>
-                  )
-                )}
-            </NScrollbar>
-          </div>
-        </div>
-      </div>
-    );
-  }
-});
+import { NCollapse, NCollapseItem, NScrollbar } from 'naive-ui';
+import { computed, defineComponent, ref, watch } from 'vue';
+import CardType from '/src/components/card-type';
+import styles from './index.module.less';
+
+export default defineComponent({
+  name: 'source-list',
+  props: {
+    knowledgePointList: {
+      type: Array,
+      default: () => []
+    },
+    activeItem: {
+      type: Object,
+      default: () => ({})
+    },
+    /** 当前播放的是第几个知识点组 */
+    courseActiveIndex: {
+      type: Number,
+      default: 0
+    },
+    teacherChapterName: {
+      type: String,
+      default: ''
+    }
+  },
+  emits: ['confirm'],
+  setup(props, { emit }) {
+    const parentIndex = ref(props.courseActiveIndex);
+
+    watch(
+      () => props.courseActiveIndex,
+      () => {
+        parentIndex.value = props.courseActiveIndex;
+      }
+    );
+
+    const childIndex = computed(() => {
+      let index = 0;
+      props.knowledgePointList.forEach((item: any) => {
+        item.list.forEach((child: any, j: number) => {
+          if (child.id === props.activeItem.id) {
+            index = j;
+          }
+        });
+      });
+      return index;
+    });
+    return () => (
+      <div class={styles.sourcelistBox}>
+        <div class={styles.treeBox}>
+          <div class={[styles.listSectionLeft]}>
+            <NScrollbar class={styles.leftscrollBar}>
+              {props.teacherChapterName && (
+                <div class={styles.className}>
+                  <i class={styles.classNameIcon}></i>
+                  <p class={styles.classNameContent}>
+                    {props.teacherChapterName}
+                  </p>
+                </div>
+              )}
+              {props.knowledgePointList.map((item: any, index: number) => (
+                <div
+                  class={[
+                    styles.treeParent,
+                    parentIndex.value === index && styles.parentSelect
+                  ]}
+                  key={'parent' + index}
+                  onClick={() => {
+                    parentIndex.value = index;
+                  }}>
+                  {item.title}
+                </div>
+              ))}
+            </NScrollbar>
+          </div>
+          <div class={[styles.listSectionRight]}>
+            <NScrollbar class={styles.rightscrollBar}>
+              {(props.knowledgePointList[parentIndex.value] as any)?.list &&
+                (props.knowledgePointList[parentIndex.value] as any).list.map(
+                  (child: any, j: number) => (
+                    <div class={[styles.cardContainer, 'drawerCardItemRef']}>
+                      <CardType
+                        item={child}
+                        audioPlayTypeSize="small"
+                        isActive={
+                          childIndex.value === j &&
+                          parentIndex.value === props.courseActiveIndex
+                        }
+                        isCollect={false}
+                        isShowCollect={false}
+                        onClick={() => {
+                          emit('confirm', child);
+                        }}
+                      />
+                    </div>
+                  )
+                )}
+            </NScrollbar>
+          </div>
+        </div>
+      </div>
+    );
+  }
+});

+ 38 - 1
src/views/attend-class/model/train-type/index.module.less

@@ -209,6 +209,8 @@
     }
   }
 
+
+
   &:hover {
     .preview {
       opacity: 1;
@@ -236,6 +238,41 @@
     height: 27px;
     cursor: pointer;
   }
+
+
+  .audioPlayTypeSection {
+    position: absolute;
+    bottom: 10px;
+    right: 10px;
+    font-size: 0;
+    gap: 8px 10px !important;
+
+    .iconType {
+      display: inline-block;
+      width: 26px;
+      height: 26px;
+    }
+
+    .iconPlay {
+      background: url('@/common/images/icon-play-default.png');
+      background-size: contain;
+
+      &:hover {
+        background: url('@/common/images/icon-play-active.png');
+        background-size: contain;
+      }
+    }
+
+    .iconSing {
+      background: url('@/common/images/icon-sing-default.png');
+      background-size: contain;
+
+      &:hover {
+        background: url('@/common/images/icon-sing-active.png');
+        background-size: contain;
+      }
+    }
+  }
 }
 
 .train-footer {
@@ -425,4 +462,4 @@
 .reportModel {
   width: 1200px;
   overflow: hidden;
-}
+}

+ 24 - 0
src/views/attend-class/model/train-type/index.tsx

@@ -31,6 +31,7 @@ type ItemType = {
   coverImg: string;
   musicName: string;
   typeList: string[];
+  audioPlayTypeArray?: string[];
   allTimes?: number;
   trainingTimes?: number;
   recordId?: string | number; // 评测记录编号
@@ -202,6 +203,29 @@ export default defineComponent({
             previewDisabled
             objectFit="contain"
           />
+          <NSpace class={styles.audioPlayTypeSection}>
+            {props.item.audioPlayTypeArray?.includes('PLAY') && (
+              <NTooltip trigger="hover" showArrow={false}>
+                {{
+                  trigger: () => (
+                    <span class={[styles.iconType, styles.iconPlay]}></span>
+                  ),
+                  default: '演奏场景'
+                }}
+              </NTooltip>
+            )}
+
+            {props.item.audioPlayTypeArray?.includes('SING') && (
+              <NTooltip trigger="hover" showArrow={false}>
+                {{
+                  trigger: () => (
+                    <span class={[styles.iconType, styles.iconSing]}></span>
+                  ),
+                  default: '演唱场景'
+                }}
+              </NTooltip>
+            )}
+          </NSpace>
           {props.isDisabled && !props.isCLassWork ? (
             <div class={styles.disPreview}>
               <NProgress

+ 4 - 1
src/views/attend-class/model/train-update/index.tsx

@@ -53,6 +53,7 @@ export default defineComponent({
       maxScore: null as any,
       subjectId: '',
       coverImg: '',
+      audioPlayTypeArray: [] as any,
       practiceSpeed: null as any, // 练习速度
       practiceTimes: null as any, // 练习时长
       difficulty: 'BEGINNER', // 评测难度
@@ -72,6 +73,7 @@ export default defineComponent({
             trainingType: forms.type,
             musicId: forms.musicId,
             musicName: forms.musicName,
+            audioPlayTypeArray: forms.audioPlayTypeArray,
             coursewareKnowledgeDetailId: forms.coursewareKnowledgeDetailId,
             subjectId: forms.subjectId,
             id: forms.id,
@@ -112,7 +114,6 @@ export default defineComponent({
 
     onMounted(() => {
       const item = props.item;
-      console.log(item, 'item');
       if (item.trainId) {
         forms.id = item.trainId;
         forms.practiceSpeed = Number(item.practiceSpeed);
@@ -130,6 +131,8 @@ export default defineComponent({
         forms.minScore = 1;
         forms.maxScore = item.practiceChapterMax ? item.practiceChapterMax : 1;
       }
+      forms.audioPlayTypeArray = item.audioPlayTypeArray || [];
+
       forms.baseMaxScore = item.practiceChapterMax || 99;
       forms.musicId = item.id;
       forms.musicName = item.musicName;

+ 3 - 0
src/views/natural-resources/components/my-collect/index.tsx

@@ -66,6 +66,9 @@ export default defineComponent({
             content: row.content,
             subjectId: row.subjectIds,
             background: row.background,
+            audioPlayTypeArray: row.audioPlayTypes
+              ? row.audioPlayTypes.split(',')
+              : [],
             enableFlag: row.enableFlag ? 1 : 0,
             openFlag: row.openFlag
           });

+ 87 - 39
src/views/natural-resources/components/my-collect/search-group-resources.tsx

@@ -12,6 +12,7 @@ import TheSearch from '/src/components/TheSearch';
 import { resourceTypeArray } from '/src/utils/searchArray';
 import { useCatchStore } from '/src/store/modules/catchData';
 import isCollaose from '../../images/isCollaose.png';
+import { audioPlayType } from '/src/utils/contants';
 
 export default defineComponent({
   name: 'search-group',
@@ -22,15 +23,26 @@ export default defineComponent({
     const forms = reactive({
       type: 'MUSIC', //
       name: '',
+      audioPlayTypes: '',
       bookVersionId: null,
       subjectId: null
     });
     const state = reactive({
       tempSubjectId: null
     });
+    const data = reactive({
+      audioPlayTypeList: [] as any
+    });
 
     const onSearch = () => {
-      emit('search', forms);
+      emit('search', {
+        ...forms,
+        audioPlayTypes: forms.audioPlayTypes
+          ? forms.audioPlayTypes === 'PLAY_SING'
+            ? ['PLAY', 'SING']
+            : [forms.audioPlayTypes]
+          : []
+      });
     };
 
     const collapseWrapRef = ref();
@@ -90,6 +102,14 @@ export default defineComponent({
     };
 
     onMounted(async () => {
+      // 场景
+      const tempAudio = Object.keys(audioPlayType).map(key => {
+        return {
+          value: key,
+          name: audioPlayType[key]
+        };
+      });
+      data.audioPlayTypeList = [{ name: '全部', value: '' }, ...tempAudio];
       resourceList.value = [
         // {
         //   label: '全部',
@@ -125,6 +145,7 @@ export default defineComponent({
                   forms.type = item.value;
                   forms.subjectId = null;
                   state.tempSubjectId = null;
+                  forms.audioPlayTypes = '';
                   onSearch();
 
                   nextTick(() => {
@@ -197,50 +218,77 @@ export default defineComponent({
               </NFormItem>
             </div>
           )} */}
-          <NFormItem label="乐器:">
-            <NSpace class={styles.spaceSection2}>
-              {catchStore.getSubjectInstruments.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;
+          <NFormItem label="场景:">
+            <NSpace class={styles.spaceSection}>
+              {data.audioPlayTypeList.map((subject: any) => (
+                <span
+                  class={[
+                    styles.textBtn,
 
-                      onSearch();
-                    }}
-                    key={subject.value}
-                    class={[styles.popSelect]}>
+                    forms.audioPlayTypes === subject.value &&
+                      styles.textBtnActive
+                  ]}
+                  onClick={() => {
+                    forms.audioPlayTypes = subject.value;
+                    if (subject.value === 'SING') {
+                      state.tempSubjectId = null;
+                      forms.subjectId = null;
+                    }
+                    onSearch();
+                  }}>
+                  {subject.name}
+                </span>
+              ))}
+            </NSpace>
+          </NFormItem>
+          {forms.audioPlayTypes !== 'SING' && (
+            <NFormItem label="乐器:">
+              <NSpace class={styles.spaceSection2}>
+                {catchStore.getSubjectInstruments.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,
-                        selectChildObj(subject.instruments).selected &&
+                        forms.subjectId === subject.value &&
                           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;
+                      ]}
+                      onClick={() => {
+                        forms.subjectId = subject.value;
 
-                      state.tempSubjectId = null;
-                      onSearch();
-                    }}>
-                    {subject.name}
-                  </span>
-                )
-              )}
-            </NSpace>
-          </NFormItem>
+                        state.tempSubjectId = null;
+                        onSearch();
+                      }}>
+                      {subject.name}
+                    </span>
+                  )
+                )}
+              </NSpace>
+            </NFormItem>
+          )}
 
           <TheSearch
             class={styles.inputSearch}

+ 3 - 0
src/views/natural-resources/components/my-resources/index.tsx

@@ -90,6 +90,9 @@ export default defineComponent({
             instrumentIds: row.instrumentIds,
             sourceFrom: row.sourceFrom,
             background: row.background,
+            audioPlayTypeArray: row.audioPlayTypes
+              ? row.audioPlayTypes.split(',')
+              : [],
             enableFlag: row.enableFlag ? 1 : 0,
             openFlag: row.openFlag
           });

+ 2 - 0
src/views/natural-resources/components/my-resources/search-group-resources.tsx

@@ -29,6 +29,7 @@ export default defineComponent({
     const forms = reactive({
       type: 'MUSIC', //
       name: '',
+      audioPlayTypes: ['PLAY'],
       bookVersionId: null,
       subjectId: null
     });
@@ -97,6 +98,7 @@ export default defineComponent({
                     state.isSelectAll = false;
                     emit('edit', state.isEdit);
                   }
+                  forms.audioPlayTypes = item.value === 'MUSIC' ? ['PLAY'] : [];
                   forms.type = item.value;
                   forms.subjectId = null;
                   state.tempSubjectId = null;

+ 4 - 0
src/views/natural-resources/components/share-resources/index.tsx

@@ -25,6 +25,7 @@ export default defineComponent({
       searchGroup: {
         type: 'MUSIC', //
         name: '',
+        audioPlayTypes: [] as any,
         bookVersionId: null,
         subjectId: null,
         sourceType: 2
@@ -56,6 +57,9 @@ export default defineComponent({
             isCollect: !!row.favoriteFlag,
             isSelected: row.sourceFrom === 'PLATFORM' ? true : false,
             refFlag: row.refFlag,
+            audioPlayTypeArray: row.audioPlayTypes
+              ? row.audioPlayTypes.split(',')
+              : [],
             background: row.background,
             content: row.content
           });

+ 84 - 51
src/views/natural-resources/components/share-resources/search-group-resources.tsx

@@ -20,6 +20,7 @@ import {
 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({
@@ -118,6 +119,7 @@ export default defineComponent({
       type: 'MUSIC', //
       name: '',
       // grade: null as any,
+      audioPlayTypes: '',
       bookVersionId: null as any,
       // musicSheetCategoriesId: null as any,
       subjectId: null
@@ -126,6 +128,7 @@ export default defineComponent({
       tempSubjectId: null
     });
     const data = reactive({
+      audioPlayTypeList: [] as any, // 场景
       selectParents: {}, // 选中的数据
       tags: [] as any[],
       tagActiveId: '' as any,
@@ -136,6 +139,11 @@ export default defineComponent({
     const onSearch = () => {
       emit('search', {
         ...forms,
+        audioPlayTypes: forms.audioPlayTypes
+          ? forms.audioPlayTypes === 'PLAY_SING'
+            ? ['PLAY', 'SING']
+            : [forms.audioPlayTypes]
+          : [],
         bookVersionId: data.childSelectId || data.tagActiveId
       });
     };
@@ -237,6 +245,15 @@ export default defineComponent({
     };
 
     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();
@@ -251,19 +268,6 @@ export default defineComponent({
         // hiddenHeight.value = collapseWrapRef.value.offsetHeight / line.value;
         // 默认隐藏
         getLive();
-
-        // const musicTagTreeList = catchStore.getMusicTagTree;
-        // if (musicTagTreeList.length > 0) {
-        //   forms.bookVersionId = musicTagTreeList[0].id;
-        //   state.gradeList = musicTagTreeList[0].children || [];
-        //   if (state.gradeList.length > 0) {
-        //     forms.grade = state.gradeList[0].id;
-        //     state.musicCategory = state.gradeList[0].children || [];
-        //     if (state.musicCategory.length > 0) {
-        //       forms.musicSheetCategoriesId = state.musicCategory[0].id;
-        //     }
-        //   }
-        // }
       }
 
       onSearch();
@@ -282,6 +286,7 @@ export default defineComponent({
                 onClick={() => {
                   forms.type = item.value;
                   forms.subjectId = null;
+                  forms.audioPlayTypes = '';
                   state.tempSubjectId = null;
                   data.tagActiveId = '';
                   data.childSelectId = null;
@@ -349,50 +354,78 @@ export default defineComponent({
             </>
           )}
 
-          <NFormItem label="乐器:">
+          <NFormItem label="场景:">
             <NSpace class={styles.spaceSection}>
-              {catchStore.getSubjectInstruments.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]}>
+              {data.audioPlayTypeList.map((subject: any) => (
+                <span
+                  class={[
+                    styles.textBtn,
+
+                    forms.audioPlayTypes === subject.value &&
+                      styles.textBtnActive
+                  ]}
+                  onClick={() => {
+                    forms.audioPlayTypes = subject.value;
+                    if (subject.value === 'SING') {
+                      state.tempSubjectId = null;
+                      forms.subjectId = null;
+                    }
+                    onSearch();
+                  }}>
+                  {subject.name}
+                </span>
+              ))}
+            </NSpace>
+          </NFormItem>
+
+          {forms.audioPlayTypes !== 'SING' && (
+            <NFormItem label="乐器:">
+              <NSpace class={styles.spaceSection}>
+                {catchStore.getSubjectInstruments.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,
-                        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;
+                        forms.subjectId === subject.value &&
+                          styles.textBtnActive
+                      ]}
+                      onClick={() => {
+                        forms.subjectId = subject.value;
 
-                      state.tempSubjectId = null;
-                      onSearch();
-                    }}>
-                    {subject.name}
-                  </span>
-                )
-              )}
-            </NSpace>
-          </NFormItem>
+                        state.tempSubjectId = null;
+                        onSearch();
+                      }}>
+                      {subject.name}
+                    </span>
+                  )
+                )}
+              </NSpace>
+            </NFormItem>
+          )}
 
           <TheSearch
             class={styles.inputSearch}

+ 4 - 0
src/views/prepare-lessons/components/lesson-main/courseware/addCourseware.tsx

@@ -170,6 +170,9 @@ export default defineComponent({
                 dataJson: sub.dataJson,
                 // isCollect: !!sub.favoriteFlag,
                 isSelected: sub.source === 'PLATFORM' ? true : false,
+                audioPlayTypeArray: sub.audioPlayTypes
+                  ? sub.audioPlayTypes.split(',')
+                  : [],
                 content: sub.bizInfo.content,
                 removeFlag: sub.removeFlag
               });
@@ -715,6 +718,7 @@ export default defineComponent({
                           refFlag: dropItem.refFlag,
                           isCollect: dropItem.isCollect,
                           isSelected: dropItem.isSelected,
+                          audioPlayTypeArray: dropItem.audioPlayTypeArray,
                           content: dropItem.content,
                           removeFlag: false,
                           index,

+ 5 - 0
src/views/prepare-lessons/components/resource-main/components/resource-item/index.tsx

@@ -56,6 +56,7 @@ export default defineComponent({
         bookVersionId: null,
         musicalInstrumentId: null,
         subjectId: null,
+        audioPlayTypes: [], // 场景
         sourceType: formatType(props.type),
         enableFlag: true
       },
@@ -95,6 +96,9 @@ export default defineComponent({
             refFlag: row.refFlag,
             isSelected: row.sourceFrom === 'PLATFORM' ? true : false,
             containAccompaniment: row.containAccompaniment,
+            audioPlayTypeArray: row.audioPlayTypes
+              ? row.audioPlayTypes.split(',')
+              : [],
             content: row.content
             // exist: index !== -1 ? true : false // 是否存在
           });
@@ -150,6 +154,7 @@ export default defineComponent({
           title: item.title,
           isCollect: item.isCollect,
           isSelected: item.isSelected,
+          audioPlayTypeArray: item.audioPlayTypeArray,
           content: item.content,
           removeFlag: false
         });

+ 19 - 1
src/views/prepare-lessons/components/resource-main/components/resource-item/resource-search-group/index.tsx

@@ -34,13 +34,24 @@ export default defineComponent({
       name: '',
       bookVersionId: null as any,
       subjectId: null as any,
+      audioPlayTypes: props.type === 'myResources' ? 'PLAY' : '',
       // musicSheetCategoriesId: null,
       musicalInstrumentId: ''
     });
     const resourceType = ref([] as any);
 
     const onSearch = () => {
-      emit('search', forms);
+      emit('search', {
+        ...forms,
+        audioPlayTypes:
+          forms.type === 'MUSIC'
+            ? forms.audioPlayTypes
+              ? forms.audioPlayTypes === 'PLAY_SING'
+                ? ['PLAY', 'SING']
+                : [forms.audioPlayTypes]
+              : []
+            : []
+      });
     };
 
     const debouncedRequest = useThrottleFn(() => onSearch(), 500);
@@ -80,6 +91,8 @@ export default defineComponent({
         },
         ...tags
       ];
+
+      console.log(tagSubjectList.value, 'tagSubjectList.value');
     };
     onMounted(async () => {
       // await catchStore.getMusicSheetCategory();
@@ -133,11 +146,16 @@ export default defineComponent({
             )}
             <CCascader
               placeholder="全部声部"
+              showPath
+              showAudioPlayType={props.type === 'myResources' ? false : true}
               v-model:value={subjects.value}
               options={tagSubjectList.value}
               onMoreId={(val: any) => {
                 forms.musicalInstrumentId = val.childId;
                 forms.subjectId = val.parentId;
+                if (props.type !== 'myResources') {
+                  forms.audioPlayTypes = val.audioPlayTypes;
+                }
                 onSearch();
               }}
             />

+ 7 - 0
src/views/prepare-lessons/components/resource-main/components/select-music/index.tsx

@@ -89,6 +89,10 @@ export default defineComponent({
         type: 'MUSIC', //
         musicSheetCategoriesId: '',
         musicalInstrumentId: '',
+        audioPlayTypes:
+          props.cardType === 'homerowk-record' || props.cardType === 'prepare'
+            ? ['PLAY']
+            : [],
         sourceType: formatType(props.type),
         status: 1,
         versionFlag: false,
@@ -137,6 +141,9 @@ export default defineComponent({
             refFlag: row.refFlag,
             isSelected: row.sourceFrom === 'PLATFORM' ? true : false,
             content: row.id,
+            audioPlayTypeArray: row.audioPlayTypes
+              ? row.audioPlayTypes.split(',')
+              : [],
             containAccompaniment: row.containAccompaniment,
             xmlFileUrl: row.xmlFileUrl
             // exist: index !== -1 ? true : false // 是否存在

+ 1 - 0
src/views/prepare-lessons/components/resource-main/index.tsx

@@ -290,6 +290,7 @@ export default defineComponent({
           title={'选择曲目'}>
           <SelectMusicModal
             from={props.from}
+            cardType={props.cardType}
             onAdd={(item: any) => onAdd(item)}
           />
           {props.from === 'class' && <Dragbom></Dragbom>}

+ 9 - 1
src/views/prepare-lessons/model/select-music/index.tsx

@@ -1,5 +1,5 @@
 import { NTabPane, NTabs } from 'naive-ui';
-import { defineComponent, onMounted, ref, toRefs } from 'vue';
+import { PropType, defineComponent, onMounted, ref, toRefs } from 'vue';
 import styles from './index.module.less';
 import SelectItem from './select-item';
 import { useResizeObserver } from '@vueuse/core';
@@ -13,6 +13,11 @@ export default defineComponent({
       type: String,
       default: 'myResources'
     },
+    /** 类型 */
+    cardType: {
+      type: String as PropType<'' | 'homerowk-record' | 'prepare'>,
+      default: ''
+    },
     /** 从哪里使用 */
     from: {
       type: String,
@@ -56,6 +61,7 @@ export default defineComponent({
           }}>
           <NTabPane name="myResources" tab={'我的曲目'}>
             <SelectItem
+              cardType={props.cardType}
               from={props.from}
               type="myResources"
               onAdd={(item: any) => emit('add', item)}
@@ -64,6 +70,7 @@ export default defineComponent({
           <NTabPane name="shareResources" tab={'共享曲目'}>
             <SelectItem
               from={props.from}
+              cardType={props.cardType}
               type="shareResources"
               onAdd={(item: any) => emit('add', item)}
             />
@@ -71,6 +78,7 @@ export default defineComponent({
           <NTabPane name="myCollect" tab="收藏曲目">
             <SelectItem
               from={props.from}
+              cardType={props.cardType}
               type="myCollect"
               onAdd={(item: any) => emit('add', item)}
             />

+ 16 - 4
src/views/prepare-lessons/model/select-music/select-item/index.tsx

@@ -1,5 +1,5 @@
 import { NScrollbar, NSpin, NTabPane, NTabs } from 'naive-ui';
-import { defineComponent, onMounted, reactive, watch } from 'vue';
+import { PropType, defineComponent, onMounted, reactive, watch } from 'vue';
 import styles from './index.module.less';
 import CardType from '@/components/card-type';
 import SearchGroup from './search-group';
@@ -23,6 +23,11 @@ const formatType = (type: string) => {
 export default defineComponent({
   name: 'select-music',
   props: {
+    /** 类型 */
+    cardType: {
+      type: String as PropType<'' | 'homerowk-record' | 'prepare'>,
+      default: ''
+    },
     type: {
       type: String,
       default: ''
@@ -48,6 +53,10 @@ export default defineComponent({
         type: 'MUSIC', //
         musicSheetCategoriesId: '',
         musicalInstrumentId: '',
+        audioPlayTypes:
+          props.cardType === 'homerowk-record' || props.cardType === 'prepare'
+            ? ['PLAY']
+            : [],
         sourceType: formatType(props.type),
         status: 1,
         versionFlag: false,
@@ -86,6 +95,9 @@ export default defineComponent({
             refFlag: row.refFlag,
             content: row.id,
             xmlFileUrl: row.xmlFileUrl,
+            audioPlayTypeArray: row.audioPlayTypes
+              ? row.audioPlayTypes.split(',')
+              : [],
             containAccompaniment: row.containAccompaniment
             // exist: index !== -1 ? true : false // 是否存在
           });
@@ -155,7 +167,7 @@ export default defineComponent({
       if (props.type === 'homework') {
         state.isShowAddDisabled = false;
       }
-      getList();
+      // getList();
     });
     return () => (
       <div class={styles.selectMusic}>
@@ -183,9 +195,9 @@ export default defineComponent({
               onSearch={(item: any, type: any) => {
                 if (type) {
                   onSearch(item);
-                  return;
+                } else {
+                  throttledFnSearch(item);
                 }
-                throttledFnSearch(item);
               }}
             />
           </div>

+ 1 - 1
src/views/prepare-lessons/model/select-resources/index.tsx

@@ -57,7 +57,7 @@ export default defineComponent({
           }}>
           {props.from !== 'class' && (
             <NTabPane name="relateResources" tab={'相关资源'}>
-              <SelectItem type="relateResources" />
+              <SelectItem type="relateResources" from={props.from} />
             </NTabPane>
           )}
           <NTabPane

+ 94 - 37
src/views/prepare-lessons/model/select-resources/select-item/class-search-group/index.tsx

@@ -21,6 +21,7 @@ import { useCatchStore } from '/src/store/modules/catchData';
 import { useThrottleFn } from '@vueuse/core';
 import TheSearch from '/src/components/TheSearch';
 import isCollaose from '/src/views/natural-resources/images/isCollaose.png';
+import { audioPlayType } from '/src/utils/contants';
 
 export default defineComponent({
   name: 'resource-search-group',
@@ -34,6 +35,11 @@ export default defineComponent({
     subjectId: {
       type: String,
       default: ''
+    },
+    // 从哪里来的
+    from: {
+      type: String,
+      default: ''
     }
   },
   emits: ['search'],
@@ -43,13 +49,23 @@ export default defineComponent({
     const forms = reactive({
       type: 'MUSIC', //
       name: '',
+      audioPlayTypes:
+        props.type === 'myResources' && props.from === 'class' ? 'PLAY' : '',
       subjectId: subjectId.value as any,
       bookVersionId: null
     });
     const resourceType = ref([] as any);
+    const audioPlayTypeList = ref([] as any);
 
     const onSearch = () => {
-      emit('search', forms);
+      emit('search', {
+        ...forms,
+        audioPlayTypes: forms.audioPlayTypes
+          ? forms.audioPlayTypes === 'PLAY_SING'
+            ? ['PLAY', 'SING']
+            : [forms.audioPlayTypes]
+          : []
+      });
     };
 
     const throttleFn = useThrottleFn(() => onSearch(), 500);
@@ -65,6 +81,14 @@ export default defineComponent({
       return obj;
     };
     onMounted(async () => {
+      // 场景
+      const tempAudio = Object.keys(audioPlayType).map(key => {
+        return {
+          value: key,
+          name: audioPlayType[key]
+        };
+      });
+      audioPlayTypeList.value = [{ name: '全部', value: '' }, ...tempAudio];
       resourceTypeArray.forEach((item: any) => {
         resourceType.value.push(item);
       });
@@ -86,51 +110,84 @@ export default defineComponent({
     return () => (
       <div class={styles.searchGroup}>
         <NForm labelAlign="left" labelPlacement="left">
-          <NFormItem label="乐器:">
-            <NSpace
-              class={[
-                styles.spaceSection,
-                styles.spaceSection2,
-                'spaceSectionBox'
-              ]}>
-              {catchStore.getSubjectInstruments.map((subject: any) =>
-                subject.instruments && subject.instruments.length > 1 ? (
-                  <NPopselect
-                    options={subject.instruments}
-                    trigger="hover"
-                    scrollable
-                    v-model:value={forms.subjectId}
-                    onUpdate:value={() => {
-                      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>
-                ) : (
+          {props.type !== 'myResources' && (
+            <NFormItem label="场景:">
+              <NSpace
+                class={[
+                  styles.spaceSection,
+                  styles.spaceSection2,
+                  'spaceSectionBox'
+                ]}>
+                {audioPlayTypeList.value.map((subject: any) => (
                   <span
                     class={[
                       styles.textBtn,
-                      forms.subjectId === subject.value && styles.textBtnActive
+
+                      forms.audioPlayTypes === subject.value &&
+                        styles.textBtnActive
                     ]}
                     onClick={() => {
-                      forms.subjectId = subject.value;
+                      forms.audioPlayTypes = subject.value;
+                      if (subject.value === 'SING') {
+                        forms.subjectId = null;
+                      }
                       onSearch();
                     }}>
                     {subject.name}
                   </span>
-                )
-              )}
-            </NSpace>
-          </NFormItem>
+                ))}
+              </NSpace>
+            </NFormItem>
+          )}
+          {forms.audioPlayTypes !== 'SING' && (
+            <NFormItem label="乐器:">
+              <NSpace
+                class={[
+                  styles.spaceSection,
+                  styles.spaceSection2,
+                  'spaceSectionBox'
+                ]}>
+                {catchStore.getSubjectInstruments.map((subject: any) =>
+                  subject.instruments && subject.instruments.length > 1 ? (
+                    <NPopselect
+                      options={subject.instruments}
+                      trigger="hover"
+                      scrollable
+                      v-model:value={forms.subjectId}
+                      onUpdate:value={() => {
+                        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;
+                        onSearch();
+                      }}>
+                      {subject.name}
+                    </span>
+                  )
+                )}
+              </NSpace>
+            </NFormItem>
+          )}
 
           <TheSearch
             class={styles.inputSearch}

+ 5 - 0
src/views/prepare-lessons/model/select-resources/select-item/index.tsx

@@ -66,6 +66,7 @@ export default defineComponent({
         name: '',
         bookVersionId: null,
         subjectId: null,
+        audioPlayTypes: props.type === 'myResources' ? ['PLAY'] : [],
         sourceType: formatType(type.value),
         musicalInstrumentId: null as any,
         enableFlag: true
@@ -102,6 +103,9 @@ export default defineComponent({
             isCollect: !!row.favoriteFlag,
             isSelected: row.sourceFrom === 'PLATFORM' ? true : false,
             refFlag: row.refFlag,
+            audioPlayTypeArray: row.audioPlayTypes
+              ? row.audioPlayTypes.split(',')
+              : [],
             containAccompaniment: row.containAccompaniment,
             content: row.content
           });
@@ -254,6 +258,7 @@ export default defineComponent({
           <div class={className2}>
             {props.from === 'class' ? (
               <ClassSearchGroup
+                from={props.from}
                 type={props.type}
                 subjectId={prepareStore.getSubjectId as any}
                 onSearch={(item: any) => throttledFnSearch(item)}

+ 88 - 39
src/views/prepare-lessons/model/select-resources/select-item/resource-search-group/index.tsx

@@ -23,6 +23,7 @@ import { useCatchStore } from '/src/store/modules/catchData';
 import { useThrottleFn } from '@vueuse/core';
 import TheSearch from '/src/components/TheSearch';
 import isCollaose from '/src/views/natural-resources/images/isCollaose.png';
+import { audioPlayType } from '/src/utils/contants';
 
 const ChildNodeSearch = defineComponent({
   name: 'ChildNodeSearch',
@@ -129,6 +130,7 @@ export default defineComponent({
       name: '',
       subjectId: subjectId.value as any,
       // grade: null as any,
+      audioPlayTypes: props.type == 'myResources' ? 'PLAY' : '',
       bookVersionId: null as any
       // musicSheetCategoriesId: null as any
     });
@@ -146,12 +148,18 @@ export default defineComponent({
     });
 
     const resourceType = ref([] as any);
+    const audioPlayTypeList = ref([] as any);
 
     const onSearch = (type?: string) => {
       emit(
         'search',
         {
           ...forms,
+          audioPlayTypes: forms.audioPlayTypes
+            ? forms.audioPlayTypes === 'PLAY_SING'
+              ? ['PLAY', 'SING']
+              : [forms.audioPlayTypes]
+            : [],
           bookVersionId: data.childSelectId || data.tagActiveId
         },
         type
@@ -260,6 +268,14 @@ export default defineComponent({
     };
 
     onMounted(async () => {
+      // 场景
+      const tempAudio = Object.keys(audioPlayType).map(key => {
+        return {
+          value: key,
+          name: audioPlayType[key]
+        };
+      });
+      audioPlayTypeList.value = [{ name: '全部', value: '' }, ...tempAudio];
       resourceTypeArray.forEach((item: any) => {
         resourceType.value.push(item);
       });
@@ -300,9 +316,12 @@ export default defineComponent({
                 onClick={() => {
                   forms.type = item.value;
                   forms.subjectId = null;
+
                   data.tagActiveId = '';
                   data.childSelectId = null;
                   data.selectParents = {};
+                  forms.audioPlayTypes =
+                    props.type === 'myResources' ? 'PLAY' : '';
                   onSearch();
 
                   try {
@@ -368,9 +387,36 @@ export default defineComponent({
             </>
           )}
 
-          <NFormItem label="乐器:">
-            <NSpace class={styles.spaceSection2}>
-              {/* {catchStore.getSubjectAllList.map((music: any) => (
+          {props.type !== 'myResources' && forms.type === 'MUSIC' && (
+            <NFormItem label="场景:">
+              <NSpace class={styles.spaceSection}>
+                {audioPlayTypeList.value.map((subject: any) => (
+                  <span
+                    class={[
+                      styles.textBtn,
+
+                      forms.audioPlayTypes === subject.value &&
+                        styles.textBtnActive
+                    ]}
+                    onClick={() => {
+                      forms.audioPlayTypes = subject.value;
+                      if (subject.value === 'SING') {
+                        state.tempSubjectId = null;
+                        forms.subjectId = null;
+                      }
+                      onSearch();
+                    }}>
+                    {subject.name}
+                  </span>
+                ))}
+              </NSpace>
+            </NFormItem>
+          )}
+
+          {forms.audioPlayTypes !== 'SING' && (
+            <NFormItem label="乐器:">
+              <NSpace class={styles.spaceSection2}>
+                {/* {catchStore.getSubjectAllList.map((music: any) => (
                 <NButton
                   secondary={forms.subjectId === music.id}
                   quaternary={forms.subjectId !== music.id}
@@ -384,47 +430,50 @@ export default defineComponent({
                   {music.name}
                 </NButton>
               ))} */}
-              {catchStore.getSubjectInstruments.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]}>
+                {catchStore.getSubjectInstruments.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,
-                        selectChildObj(subject.instruments).selected &&
+
+                        forms.subjectId === subject.value &&
                           styles.textBtnActive
-                      ]}>
-                      {selectChildObj(subject.instruments).name || subject.name}
-                      <i class={styles.iconArrow}></i>
+                      ]}
+                      onClick={() => {
+                        forms.subjectId = subject.value;
+                        state.tempSubjectId = null;
+                        onSearch();
+                      }}>
+                      {subject.name}
                     </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>
+                  )
+                )}
+              </NSpace>
+            </NFormItem>
+          )}
         </NForm>
       </div>
     );

+ 32 - 1
src/views/xiaoku-music/index.module.less

@@ -183,6 +183,37 @@
   }
 }
 
+.searchSection {
+  position: sticky;
+  top: 0;
+  left: 0;
+  z-index: 9;
+
+  padding: 24px;
+  background-color: #fff;
+
+  display: flex;
+  align-items: center;
+
+  :global {
+    .TheSearch {
+      background: #F5F6FA;
+      --n-color-focus: #F5F6FA !important;
+    }
+
+    .nBaseCascaser {
+      border-radius: 100px;
+      width: 201px;
+      background: #F5F6FA;
+      margin-right: 16px;
+
+      .n-base-selection__border {
+        border-color: #F5F6FA;
+      }
+    }
+  }
+}
+
 .itemContainer {
   width: 100%;
   border-radius: 16px;
@@ -532,4 +563,4 @@
       margin-top: 0;
     }
   }
-}
+}

+ 121 - 42
src/views/xiaoku-music/index.tsx

@@ -28,8 +28,8 @@ import {
 import TheSearch from '/src/components/TheSearch';
 import { IMusicItem } from './type';
 import icon_arrow from './images/icon_arrow.png';
-import icon_play from './images/icon_play.png';
-import icon_pause from './images/icon_pause.png';
+// import icon_play from './images/icon_play.png';
+// import icon_pause from './images/icon_pause.png';
 import icon_goXiaoku from './images/icon_goXiaoku.png';
 import icon_favitor from '/src/common/images/icon-collect-default.png';
 import icon_favitorActive from '/src/common/images/icon-collect-active.png';
@@ -44,8 +44,8 @@ import { useCatchStore } from '/src/store/modules/catchData';
 import {
   api_materialFavorite,
   api_materialFavoriteStatus,
-  api_musicSheetPage,
-  api_subjectList
+  api_musicSheetPage
+  // api_subjectList
 } from '../xiaoku-ai/api';
 import { useUserStore } from '/src/store/modules/users';
 import Musicguide from '@/custom-plugins/guide-page/music-guide';
@@ -53,7 +53,9 @@ import TheEmpty from '/src/components/TheEmpty';
 import { modalClickMask, state } from '/src/state';
 import { useResizeObserver } from '@vueuse/core';
 import { vaildMusicScoreUrl } from '/src/utils/urlUtils';
-import { getInstrumentName, sortMusical, trackToCode } from '/src/utils';
+import { getInstrumentName, sortMusical } from '/src/utils';
+import { audioPlayType } from '/src/utils/contants';
+import CCascader from '/src/components/CCascader';
 
 export default defineComponent({
   name: 'XiaokuMusic',
@@ -67,6 +69,7 @@ export default defineComponent({
       rows: 20,
       status: true,
       name: '', // 关键词
+      audioPlayTypes: '',
       musicSheetCategoriesId: route.query.id || ''
     });
     const data = reactive({
@@ -75,6 +78,8 @@ export default defineComponent({
       reshing: false,
       tags: [] as any[],
       tagIndex: 0,
+      musicalInstrumentId: '',
+      musicSubject: '',
       list: [] as unknown as IMusicItem[],
       listActive: 0,
       musicInstrumentIndex: 0,
@@ -84,31 +89,54 @@ export default defineComponent({
       showPreivew: false,
       previewUrl: '',
       showCloseBtn: true,
+      audioPlayTypeList: [] as any,
       iframeSrc: '',
       showMusicImg: 'staff' as 'staff' | 'first' | 'fixed', // 显示哪种曲谱
       trackList: [] as any, // 可筛选的分轨信息
       showTransBtn: true, // 是否显示转谱按钮
       trackName: '切换声轨' as any // 分轨名字
     });
+    const subjects = ref('');
     const showGuide = ref(false);
     const userStore = useUserStore();
     let musicsrc = '';
+    const formatParentCurrentValue = (list: any) => {
+      for (const item of list) {
+        if (item.instruments && item.instruments.length > 0) {
+          item.instruments.forEach((child: any) => {
+            child.columnName = '乐器';
+          });
+          item.children = item.instruments;
+          formatParentCurrentValue(item.instruments);
+        }
+      }
+    };
     const getSubjects = async () => {
       // const res = await api_subjectList();
       // if (Array.isArray(res?.data)) {
-      const tempSubjectList = catchStore.getSubjectInstruments;
+      const tempSubjectList = catchStore.getSubjectList;
       const subjectList = sessionStorage.getItem('musicSubjectList')
         ? JSON.parse(sessionStorage.getItem('musicSubjectList') as any)
         : [];
       const resultList: any[] = [];
+      console.log(tempSubjectList, subjectList, 'subjectList');
       tempSubjectList.forEach((item: any) => {
         const hasItem = subjectList.find((s: any) => s.id === item.id);
         if (hasItem) {
           resultList.push(item);
         }
       });
+      // data.tags = [
+      //   { name: '全部', id: 0, value: 0, label: '全部' },
+      //   ...resultList
+      // ];
+      formatParentCurrentValue(resultList);
       data.tags = [
-        { name: '全部', id: 0, value: 0, label: '全部' },
+        {
+          columnName: '声部',
+          name: '全部声部',
+          id: ''
+        },
         ...resultList
       ];
       // }
@@ -117,10 +145,16 @@ export default defineComponent({
       data.loading = true;
       let res = {} as any;
       try {
+        const { audioPlayTypes, ...result } = forms;
         res = await api_musicSheetPage({
-          ...forms,
-          // musicSubject: data.tagIndex ? data.tagIndex : ''
-          musicalInstrumentId: data.tagIndex ? data.tagIndex : ''
+          ...result,
+          audioPlayTypes: audioPlayTypes
+            ? audioPlayTypes === 'PLAY_SING'
+              ? ['PLAY', 'SING']
+              : [audioPlayTypes]
+            : [],
+          musicSubject: data.musicSubject,
+          musicalInstrumentId: data.musicalInstrumentId
         });
       } catch (error) {
         console.log(error);
@@ -170,6 +204,15 @@ export default defineComponent({
     };
 
     onMounted(async () => {
+      // 场景
+      const tempAudio = Object.keys(audioPlayType).map(key => {
+        return {
+          value: key,
+          label: audioPlayType[key]
+        };
+      });
+      data.audioPlayTypeList = [{ label: '全部', value: '' }, ...tempAudio];
+
       // 获取声部列表
       await catchStore.getSubjects();
       // musicList-container
@@ -399,20 +442,6 @@ export default defineComponent({
       }
       return action;
     });
-    // const _actions = [
-    //   {
-    //     value: 'staff',
-    //     label: '五线谱'
-    //   },
-    //   {
-    //     value: 'first',
-    //     label: '首调'
-    //   },
-    //   {
-    //     value: 'fixed',
-    //     label: '固定调'
-    //   }
-    // ];
 
     // 解析xml,获取分轨信息
     const analyzeXml = async () => {
@@ -618,11 +647,39 @@ export default defineComponent({
         <div class={[styles.wrap, data.showPlayer ? styles.wrapBottom : '']}>
           <div class={styles.content}>
             <div class={styles.tools}>
-              <NSpace
-                style={{ width: '100%' }}
-                size={[24, 12]}
-                wrapItem={false}>
-                <div
+              <NSpace style={{ width: '100%' }} size={[12, 6]} wrapItem={false}>
+                {data.audioPlayTypeList.map((item: any) => (
+                  <NButton
+                    round
+                    textColor={
+                      forms.audioPlayTypes === item.value ? '#fff' : '#000'
+                    }
+                    color={
+                      forms.audioPlayTypes === item.value ? '#198CFE' : '#fff'
+                    }
+                    type={
+                      forms.audioPlayTypes === item.value
+                        ? 'primary'
+                        : 'default'
+                    }
+                    onClick={() => {
+                      forms.audioPlayTypes = item.value || '';
+                      if (item.value === 'SING') {
+                        data.musicalInstrumentId = '';
+                        data.musicSubject = '';
+                      }
+
+                      data.reshing = true;
+                      document
+                        .querySelector('.musicList-container')
+                        ?.scroll(0, 0);
+                      handleGetList();
+                    }}>
+                    {item.label}
+                  </NButton>
+                ))}
+
+                {/* <div
                   {...{
                     id: 'music-0'
                   }}>
@@ -642,7 +699,7 @@ export default defineComponent({
                             data.reshing = true;
                             document
                               .querySelector('.musicList-container')
-                              .scroll(0, 0);
+                              ?.scroll(0, 0);
                             handleGetList();
                           }}
                           key={item.value}
@@ -690,7 +747,7 @@ export default defineComponent({
                             data.reshing = true;
                             document
                               .querySelector('.musicList-container')
-                              .scroll(0, 0);
+                              ?.scroll(0, 0);
                             handleGetList();
                           }}>
                           {item.name}
@@ -698,22 +755,44 @@ export default defineComponent({
                       )
                     )}
                   </NSpace>
-                </div>
+                </div> */}
               </NSpace>
-              <TheSearch
-                style={{ marginLeft: 'auto' }}
-                round
-                border={false}
-                onSearch={val => {
-                  forms.name = val;
-                  data.reshing = true;
-                  handleGetList();
-                }}
-              />
             </div>
 
             <div class={styles.contentWrap}>
               <div class={[styles.musicList, 'musicList-container']}>
+                <div class={styles.searchSection}>
+                  {forms.audioPlayTypes !== 'SING' && (
+                    <CCascader
+                      placeholder="全部乐器"
+                      showPath
+                      arrowType="small"
+                      class={styles.instrumentSection}
+                      v-model:value={subjects.value}
+                      options={data.tags}
+                      onMoreId={(val: any) => {
+                        data.musicalInstrumentId = val.childId;
+                        data.musicSubject = val.parentId;
+                        data.reshing = true;
+                        document
+                          .querySelector('.musicList-container')
+                          ?.scroll(0, 0);
+                        handleGetList();
+                      }}
+                    />
+                  )}
+
+                  <TheSearch
+                    style={{ marginLeft: 'auto' }}
+                    round
+                    border={false}
+                    onSearch={val => {
+                      forms.name = val;
+                      data.reshing = true;
+                      handleGetList();
+                    }}
+                  />
+                </div>
                 <div class={[styles.wrapList, 'music-wrap-list']}>
                   {data.list.map((item: IMusicItem, index) => {
                     return (