Переглянути джерело

Merge branch 'iteration-20240909' into online

lex-xin 9 місяців тому
батько
коміт
64b377510e
56 змінених файлів з 1063 додано та 204 видалено
  1. 2 2
      dev-dist/sw.js
  2. 1 1
      public/version.json
  3. 16 0
      src/components/CDatePicker/index.tsx
  4. 10 2
      src/components/TheSearch/index.tsx
  5. 1 0
      src/components/card-preview/music-modal/index.module.less
  6. 5 0
      src/components/card-preview/video-modal/index.tsx
  7. 6 6
      src/components/card-type/index.tsx
  8. 2 2
      src/utils/contants.ts
  9. 5 0
      src/utils/searchArray.ts
  10. 59 16
      src/views/attend-class/component/audio-pay.tsx
  11. 35 18
      src/views/attend-class/component/audio.module.less
  12. 32 4
      src/views/attend-class/component/video-play.tsx
  13. 13 3
      src/views/attend-class/component/video.module.less
  14. 18 0
      src/views/attend-class/index.tsx
  15. 6 7
      src/views/attend-class/model/train-type/index.tsx
  16. 24 3
      src/views/content-information/content-instrument/components/list/index.tsx
  17. 14 5
      src/views/content-information/content-instrument/components/list/search-group-resources.tsx
  18. 8 2
      src/views/content-information/content-instrument/detail.module.less
  19. 3 2
      src/views/content-information/content-instrument/detail.tsx
  20. 1 0
      src/views/content-information/content-instrument/index.tsx
  21. 9 0
      src/views/content-information/content-knowledge/index.module.less
  22. 37 10
      src/views/content-information/content-music/components/list/index.tsx
  23. 46 5
      src/views/content-information/content-music/components/list/search-group-resources.tsx
  24. 9 0
      src/views/content-information/content-music/detail.module.less
  25. 3 0
      src/views/content-information/content-music/detail.tsx
  26. 1 1
      src/views/content-information/content-music/index.tsx
  27. 28 3
      src/views/content-information/content-musician/components/list/index.tsx
  28. 17 5
      src/views/content-information/content-musician/components/list/search-group-resources.tsx
  29. 1 0
      src/views/content-information/content-musician/index.tsx
  30. 1 1
      src/views/natural-resources/model/add-teaching/index.module.less
  31. 26 5
      src/views/natural-resources/model/add-teaching/index.tsx
  32. 10 1
      src/views/prepare-lessons/api.ts
  33. BIN
      src/views/prepare-lessons/components/directory-main/images/icon-upload-bg.png
  34. 6 0
      src/views/prepare-lessons/components/directory-main/index.module.less
  35. 17 5
      src/views/prepare-lessons/components/directory-main/index.tsx
  36. 121 21
      src/views/prepare-lessons/components/directory-main/select-lessonware/index.module.less
  37. 201 28
      src/views/prepare-lessons/components/directory-main/select-lessonware/index.tsx
  38. 4 3
      src/views/prepare-lessons/components/lesson-main/courseware-presets/index.tsx
  39. 1 1
      src/views/prepare-lessons/components/lesson-main/courseware/addCourseware.tsx
  40. 1 0
      src/views/prepare-lessons/components/lesson-main/train/assign-homework.tsx
  41. 3 0
      src/views/prepare-lessons/components/lesson-main/train/index.tsx
  42. 1 1
      src/views/prepare-lessons/model/attend-class/index.tsx
  43. 7 2
      src/views/prepare-lessons/model/source-instrument/detail.module.less
  44. 3 0
      src/views/prepare-lessons/model/source-instrument/detail.tsx
  45. 9 0
      src/views/prepare-lessons/model/source-knowledge/index.module.less
  46. 9 0
      src/views/prepare-lessons/model/source-music/detail.module.less
  47. 3 0
      src/views/prepare-lessons/model/source-music/detail.tsx
  48. 13 1
      src/views/setting/components/schoolInfo/index.tsx
  49. 127 12
      src/views/studentList/components/evaluationRecords.tsx
  50. 30 0
      src/views/studentList/index.module.less
  51. 32 3
      src/views/xiaoku-music/component/play-item/index.module.less
  52. 13 12
      src/views/xiaoku-music/component/play-item/index.tsx
  53. BIN
      src/views/xiaoku-music/images/song-arrow.png
  54. 1 1
      src/views/xiaoku-music/index.module.less
  55. 11 9
      src/views/xiaoku-music/index.tsx
  56. 1 1
      vite.config.ts

+ 2 - 2
dev-dist/sw.js

@@ -67,7 +67,7 @@ if (!self.define) {
     });
   };
 }
-define(['./workbox-bb0550c6'], (function (workbox) { 'use strict';
+define(['./workbox-88bf3160'], (function (workbox) { 'use strict';
 
   self.skipWaiting();
   workbox.clientsClaim();
@@ -82,7 +82,7 @@ define(['./workbox-bb0550c6'], (function (workbox) { 'use strict';
     "revision": "3ca0b8505b4bec776b69afdba2768812"
   }, {
     "url": "index.html",
-    "revision": "0.dc551p1sjbg"
+    "revision": "0.2kkppsecoao"
   }], {});
   workbox.cleanupOutdatedCaches();
   workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {

+ 1 - 1
public/version.json

@@ -1 +1 @@
-{"version":1725962701482}
+{"version":1726198296615}

+ 16 - 0
src/components/CDatePicker/index.tsx

@@ -17,6 +17,19 @@ export default defineComponent({
     timerValue: {
       type: Array,
       default: [] as any
+    },
+    // 
+    placeholder: {
+      type: String,
+      default: '选择日期时间'
+    },
+    startPlaceholder: {
+      type: String,
+      default: '结束日期时间'
+    },
+    endPlaceholder: {
+      type: String,
+      default: '开始日期时间'
     }
   },
   setup(props, { emit, attrs }) {
@@ -48,6 +61,9 @@ export default defineComponent({
             separator={props.separator}
             type={props.type as any}
             onUpdate:value={updateTimer}
+            placeholder={props.placeholder}
+            startPlaceholder={props.startPlaceholder}
+            endPlaceholder={props.endPlaceholder}
             onFocus={() => {
               isFocus.value = true;
             }}

+ 10 - 2
src/components/TheSearch/index.tsx

@@ -1,4 +1,4 @@
-import { PropType, defineComponent, reactive } from 'vue';
+import { PropType, defineComponent, reactive, watch } 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';
@@ -19,13 +19,21 @@ export default defineComponent({
     placeholder: {
       type: String,
       default: '请输入搜索关键词'
+    },
+    value: {
+      type: String,
+      default: ''
     }
   },
   emits: ['search'],
   setup(props, { emit }) {
     const searchData = reactive({
-      value: ''
+      value: props.value || ''
     });
+
+    watch(() => props.value, () => {
+      searchData.value = props.value
+    })
     return () => (
       <NInput
         class={[

+ 1 - 0
src/components/card-preview/music-modal/index.module.less

@@ -1,6 +1,7 @@
 .musicScore {
   width: 100%;
   height: 518px;
+  background-color: #234892;
 
   iframe {
     width: inherit;

+ 5 - 0
src/components/card-preview/video-modal/index.tsx

@@ -231,6 +231,11 @@ export default defineComponent({
     });
     onUnmounted(() => {
       window.removeEventListener('fullscreenchange', onFullScreenChange);
+      if(videoItem.value) {
+        videoItem.value.pause()
+        videoItem.value.dispose()
+        videoItem.value = null
+      }
     });
 
     expose({

+ 6 - 6
src/components/card-type/index.tsx

@@ -344,32 +344,32 @@ export default defineComponent({
                           ? styles.audioPlayTypeSmall
                           : ''
                       ]}>
-                      {props.item.audioPlayTypeArray?.includes('PLAY') && (
+                      {props.item.audioPlayTypeArray?.includes('SING') && (
                         <NTooltip trigger="hover" showArrow={false}>
                           {{
                             trigger: () => (
                               <span
                                 class={[
                                   styles.iconType,
-                                  styles.iconPlay
+                                  styles.iconSing
                                 ]}></span>
                             ),
-                            default: '演场景'
+                            default: '演场景'
                           }}
                         </NTooltip>
                       )}
 
-                      {props.item.audioPlayTypeArray?.includes('SING') && (
+                      {props.item.audioPlayTypeArray?.includes('PLAY') && (
                         <NTooltip trigger="hover" showArrow={false}>
                           {{
                             trigger: () => (
                               <span
                                 class={[
                                   styles.iconType,
-                                  styles.iconSing
+                                  styles.iconPlay
                                 ]}></span>
                             ),
-                            default: '演场景'
+                            default: '演场景'
                           }}
                         </NTooltip>
                       )}

+ 2 - 2
src/utils/contants.ts

@@ -77,9 +77,9 @@ export const gradeToCN = {
  * 场景
  */
 export const audioPlayType = {
-  PLAY: '演奏',
   SING: '演唱',
-  PLAY_SING: '演奏+演唱'
+  PLAY: '演奏',
+  PLAY_SING: '演唱+演奏'
 } as any;
 
 /**

+ 5 - 0
src/utils/searchArray.ts

@@ -22,3 +22,8 @@ export const resourceTypeArray = getValueForKey(constant.resourceType);
 
 // 训练状态
 export const trainingStatusArray = getValueForKey(constant.trainingStatus);
+/**
+ * @description: 评测难度
+ * 入门:BEGINNER/进阶:ADVANCED/大师:PERFORMER")
+ */
+export const evaluateDifficultArray = getValueForKey(constant.evaluateDifficult)

+ 59 - 16
src/views/attend-class/component/audio-pay.tsx

@@ -32,6 +32,10 @@ export default defineComponent({
       type: Boolean,
       default: false
     },
+    showModel: {
+      type: Boolean,
+      default: false
+    },
     imagePos: {
       type: String,
       default: 'left'
@@ -48,6 +52,7 @@ export default defineComponent({
       durationNum: 0,
       duration: '00:00',
       showBar: true,
+      showAction: true,
       afterMa3: true,
       count: 0,
       previousBytesLoaded: 0,
@@ -154,6 +159,14 @@ export default defineComponent({
       }
     );
 
+    watch(
+      () => props.showModel,
+      () => {
+        // console.log(props.showModel, 'props.showModel')
+        audioForms.showAction = props.showModel;
+      }
+    );
+
     const calculateSpeed = (element: any) => {
       let previousBytesLoaded = 0;
       let timer: any = null;
@@ -273,17 +286,17 @@ export default defineComponent({
         //     );
         //   }
         // }
-        console.log(
-          uncachedTime,
-          duration,
-          cachedDuration,
-          'duration',
-          buffterCatchArray,
-          element.currentTime,
-          currentLength + '%',
-          isWaiting,
-          currentBytesLoaded <= previousBytesLoaded
-        );
+        // console.log(
+        //   uncachedTime,
+        //   duration,
+        //   cachedDuration,
+        //   'duration',
+        //   buffterCatchArray,
+        //   element.currentTime,
+        //   currentLength + '%',
+        //   isWaiting,
+        //   currentBytesLoaded <= previousBytesLoaded
+        // );
 
         const isNoBuffer = currentBytesLoaded <= previousBytesLoaded;
         // console.log(
@@ -435,6 +448,7 @@ export default defineComponent({
     return () => (
       <div class={styles.audioWrap}>
         <div class={styles.audioContainer}>
+          <div class={styles.audioTitle}>{props.item.title}</div>
           <audio
             ref={audio}
             crossorigin="anonymous"
@@ -503,13 +517,27 @@ export default defineComponent({
         <div
           class={[
             styles.controls,
-            audioForms.showBar ? '' : styles.sectionAnimate
+            audioForms.showAction ? '' : styles.sectionAnimate
           ]}
           onClick={(e: MouseEvent) => {
             e.stopPropagation();
             emit('reset');
           }}>
           <div class={styles.slider}>
+          {props.imagePos !== 'right' &&  <div class={styles.time}>
+              <div
+                class="plyr__time plyr__time--current"
+                aria-label="Current time">
+                {audioForms.currentTime}
+              </div>
+              <span class={styles.line}>/</span>
+              <div
+                class="plyr__time plyr__time--duration"
+                aria-label="Duration">
+                {audioForms.duration}
+              </div>
+            </div>}
+
             <NSlider
               value={audioForms.currentTimeNum}
               step={0.01}
@@ -521,12 +549,26 @@ export default defineComponent({
                 audioForms.currentTime = timeFormat(Math.round(val || 0));
               }}
             />
+            {props.imagePos === 'right' &&  <div class={[styles.time, styles.rightTime]}>
+              <div
+                class="plyr__time plyr__time--current"
+                aria-label="Current time">
+                {audioForms.currentTime}
+              </div>
+              <span class={styles.line}>/</span>
+              <div
+                class="plyr__time plyr__time--duration"
+                aria-label="Duration">
+                {audioForms.duration}
+              </div>
+            </div>}
           </div>
           <div class={styles.tools}>
             {props.imagePos === 'right' ? (
               <>
                 <div class={styles.actions}>
-                  <div class={styles.time}>
+                  <div class={styles.title}>{props.item.title}</div>
+                  {/* <div class={styles.time}>
                     <div
                       class="plyr__time plyr__time--current"
                       aria-label="Current time">
@@ -538,7 +580,7 @@ export default defineComponent({
                       aria-label="Duration">
                       {audioForms.duration}
                     </div>
-                  </div>
+                  </div> */}
                 </div>
                 <div class={styles.actions}>
                   <div class={styles.actionWrap}>
@@ -578,7 +620,8 @@ export default defineComponent({
                   </div>
                 </div>
                 <div class={styles.actions}>
-                  <div class={styles.time}>
+                  <div class={styles.title}>{props.item.title}</div>
+                  {/* <div class={styles.time}>
                     <div
                       class="plyr__time plyr__time--current"
                       aria-label="Current time">
@@ -590,7 +633,7 @@ export default defineComponent({
                       aria-label="Duration">
                       {audioForms.duration}
                     </div>
-                  </div>
+                  </div> */}
                 </div>
               </>
             )}

+ 35 - 18
src/views/attend-class/component/audio.module.less

@@ -12,7 +12,15 @@
   height: 100%;
   padding: 0 240px;
 
-  &>div {
+  .audioTitle {
+    position: absolute;
+    top: 180px;
+    font-weight: 600;
+    font-size: 40px;
+    color: #131415;
+  }
+
+  & > div {
     flex: 1;
   }
 
@@ -41,7 +49,7 @@
   opacity: 0;
   pointer-events: none;
   transform: translateY(126px);
-  transition: all .2s;
+  transition: all 0.2s;
 }
 
 .controls {
@@ -65,22 +73,26 @@
     justify-content: space-between;
     color: #fff;
     // font-size: 10px;
-    padding: 4px 20px 4px;
-    font-size: 24px;
+    padding: 4px 20px 4px 0;
+    font-size: 20px;
     font-weight: 600;
     line-height: 33px;
 
-    &>div {
+    &.rightTime {
+      padding: 4px 0 4px 20px;
+    }
+
+    & > div {
       font-size: 20px !important;
-      color: rgba(255, 255, 255, 0.8);
+      color: rgba(255, 255, 255);
     }
 
     .line {
-      font-size: 12px;
+      font-size: 20px;
     }
 
     :global {
-      .plyr__time+.plyr__time:before {
+      .plyr__time + .plyr__time:before {
         content: '';
         margin-right: 0;
       }
@@ -91,7 +103,7 @@
 .tools {
   display: flex;
   justify-content: space-between;
-  padding: 0 10px;
+  padding: 0;
   margin-top: 10px;
 }
 
@@ -111,8 +123,8 @@
 
   .downloadSpeed {
     font-weight: 600;
-    font-size: max(18px, 14Px);
-    color: #FFFFFF;
+    font-size: max(18px, 14px);
+    color: #ffffff;
     line-height: 25px;
   }
 
@@ -122,13 +134,12 @@
     background: transparent;
     cursor: pointer;
 
-    &>img {
+    & > img {
       width: 100%;
       height: 100%;
     }
   }
 
-
   .iconReplay {
     width: 40px;
     height: 40px;
@@ -136,22 +147,28 @@
     cursor: pointer;
     margin: 0 22px;
 
-    &>img {
+    & > img {
       width: 100%;
       height: 100%;
     }
   }
+
+  .title {
+    font-size: max(20px, 16px);
+    color: #ffffff;
+  }
 }
 
 .slider {
   width: 100%;
   padding-top: 6px;
+  display: flex;
+  align-items: center;
 
   :global {
-
     .n-slider .n-slider-rail .n-slider-rail__fill,
     .n-slider .n-slider-handles .n-slider-handle-wrapper {
-      transition: all .2s;
+      transition: all 0.2s;
     }
 
     .n-slider .n-slider-rail .n-slider-rail__fill {
@@ -169,9 +186,9 @@
       border-radius: calc(var(--n-rail-height) / 2);
       top: 0;
       bottom: 0;
-      left: -8Px;
+      left: -8px;
       // right: -8Px;
       background-color: #909090;
     }
   }
-}
+}

+ 32 - 4
src/views/attend-class/component/video-play.tsx

@@ -582,6 +582,19 @@ export default defineComponent({
             emit('reset');
           }}>
           <div class={styles.slider}>
+            {props.imagePos !== 'right' && <div class={styles.time}>
+              <div
+                class="plyr__time plyr__time--current"
+                aria-label="Current time">
+                {videoFroms.currentTime}
+              </div>
+              <span class={styles.line}>/</span>
+              <div
+                class="plyr__time plyr__time--duration"
+                aria-label="Duration">
+                {videoFroms.duration}
+              </div>
+            </div>}
             <NSlider
               value={videoFroms.currentTimeNum}
               step={0.01}
@@ -594,13 +607,27 @@ export default defineComponent({
                 videoFroms.currentTime = timeFormat(Math.round(val || 0));
               }}
             />
+            {props.imagePos === 'right' && <div class={[styles.time, styles.rightTime]}>
+                      <div
+                        class="plyr__time plyr__time--current"
+                        aria-label="Current time">
+                        {videoFroms.currentTime}
+                      </div>
+                      <span class={styles.line}>/</span>
+                      <div
+                        class="plyr__time plyr__time--duration"
+                        aria-label="Duration">
+                        {videoFroms.duration}
+                      </div>
+                    </div>}
           </div>
           <div class={styles.tools}>
             {props.imagePos === 'right' ? (
               <>
                 <div class={styles.actions}>
                   <div class={styles.actionWrap}>
-                    <div class={styles.time}>
+                    <div class={styles.title}>{props.item.title}</div>
+                    {/* <div class={styles.time}>
                       <div
                         class="plyr__time plyr__time--current"
                         aria-label="Current time">
@@ -612,7 +639,7 @@ export default defineComponent({
                         aria-label="Duration">
                         {videoFroms.duration}
                       </div>
-                    </div>
+                    </div> */}
                   </div>
                 </div>
                 <div class={styles.actions}>
@@ -841,7 +868,8 @@ export default defineComponent({
                 </div>
                 <div class={styles.actions}>
                   <div class={styles.actionWrap}>
-                    <div class={styles.time}>
+                   <div class={styles.title}>{props.item.title}</div>
+                    {/* <div class={styles.time}>
                       <div
                         class="plyr__time plyr__time--current"
                         aria-label="Current time">
@@ -853,7 +881,7 @@ export default defineComponent({
                         aria-label="Duration">
                         {videoFroms.duration}
                       </div>
-                    </div>
+                    </div> */}
                   </div>
                 </div>
               </>

+ 13 - 3
src/views/attend-class/component/video.module.less

@@ -44,14 +44,17 @@
       justify-content: space-between;
       color: #fff;
       // font-size: 10px;
-      padding: 4px 20px 4px;
+      padding: 4px 20px 4px 0;
       font-size: 24px;
       font-weight: 600;
       line-height: 33px;
+      &.rightTime {
+        padding: 4px 0 4px 20px;
+      }
 
       &>div {
         font-size: 20px !important;
-        color: rgba(255, 255, 255, 0.8);
+        color: rgba(255, 255, 255);
       }
 
       .line {
@@ -70,7 +73,7 @@
   .tools {
     display: flex;
     justify-content: space-between;
-    padding: 0 10px;
+    padding: 0;
     margin-top: 10px;
   }
 
@@ -88,6 +91,11 @@
       align-items: center;
     }
 
+    .title {
+      font-size: max(20px, 16px);
+      color: #ffffff;
+    }
+
     .downloadSpeed {
       font-weight: 600;
       font-size: max(18px, 14Px);
@@ -139,6 +147,8 @@
   .slider {
     width: 100%;
     padding-top: 6px;
+    display: flex;
+    align-items: center;
 
     :global {
 

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

@@ -1360,10 +1360,25 @@ export default defineComponent({
       //   id: 6
       // }
     ];
+    const mirrorAddressCatch = (type: 'get' | 'set'  = 'get', value?: string): any => {
+      const localStorageName = 'mirrorAddressCatch';
+      
+      if(type === "get") {
+        const catchName = localStorage.getItem(localStorageName)
+        return catchName || null
+      } else if(type === "set") {
+        localStorage.setItem(localStorageName, value || '')
+      }
+    }
     // 默认收起菜单
     const columnShow = ref(true);
     // 菜单位置
     const columnPos = ref<'left' | 'right'>('left');
+
+    if(mirrorAddressCatch()) {
+      columnPos.value = mirrorAddressCatch()
+    }
+
     watch(columnPos, () => {
       for (let i = 0; i < data.itemList.length; i++) {
         const activeItem = data.itemList[i];
@@ -1819,6 +1834,7 @@ export default defineComponent({
                         <AudioPay
                           imagePos={columnPos.value}
                           item={m}
+                          showModel={activeData.model}
                           activeStatus={popupData.activeIndex === mIndex}
                           ref={(v: any) => (data.audioRefs[mIndex] = v)}
                           onLoadedmetadata={(audioItem: any) => {
@@ -1995,6 +2011,7 @@ export default defineComponent({
                 onClick={() => {
                   columnPos.value = 'right';
                   columnShow.value = true;
+                  mirrorAddressCatch('set', 'right')
                 }}
               />
             ),
@@ -2062,6 +2079,7 @@ export default defineComponent({
                 onClick={() => {
                   columnPos.value = 'left';
                   columnShow.value = true;
+                  mirrorAddressCatch('set', 'left')
                 }}
               />
             ),

+ 6 - 7
src/views/attend-class/model/train-type/index.tsx

@@ -204,24 +204,23 @@ export default defineComponent({
             objectFit="contain"
           />
           <NSpace class={styles.audioPlayTypeSection}>
-            {props.item.audioPlayTypeArray?.includes('PLAY') && (
+            {props.item.audioPlayTypeArray?.includes('SING') && (
               <NTooltip trigger="hover" showArrow={false}>
                 {{
                   trigger: () => (
-                    <span class={[styles.iconType, styles.iconPlay]}></span>
+                    <span class={[styles.iconType, styles.iconSing]}></span>
                   ),
-                  default: '演场景'
+                  default: '演场景'
                 }}
               </NTooltip>
             )}
-
-            {props.item.audioPlayTypeArray?.includes('SING') && (
+            {props.item.audioPlayTypeArray?.includes('PLAY') && (
               <NTooltip trigger="hover" showArrow={false}>
                 {{
                   trigger: () => (
-                    <span class={[styles.iconType, styles.iconSing]}></span>
+                    <span class={[styles.iconType, styles.iconPlay]}></span>
                   ),
-                  default: '演场景'
+                  default: '演场景'
                 }}
               </NTooltip>
             )}

+ 24 - 3
src/views/content-information/content-instrument/components/list/index.tsx

@@ -20,16 +20,28 @@ export default defineComponent({
     }
   },
   setup(props) {
+    // 保存数据
+    const operationCatch = (type: 'get'| 'set' = 'get', value: string = '') : any => {
+      const sessionName = 'content-instrument-catch'
+      if(type === "get") {
+        const result = sessionStorage.getItem(sessionName)
+        return result ? JSON.parse(result) : null
+      } else if(type === 'set') {
+        sessionStorage.setItem(sessionName, value)
+      }
+    }
+
     const router = useRouter();
+    const catchData = operationCatch('get')
     const state = reactive({
       searchWord: '',
       loading: false,
       pageTotal: 0,
-      pagination: {
+      pagination: catchData && catchData.pagination ? catchData.pagination : {
         page: 1,
         rows: 18
       },
-      searchGroup: {
+      searchGroup:  catchData && catchData.searchGroup ? catchData.searchGroup : {
         type: 'INSTRUMENT', //
         keyword: '',
         wikiCategoryId: props.categoryId
@@ -40,8 +52,15 @@ export default defineComponent({
       item: {} as any
     });
 
+    
+
     const getList = async () => {
       state.loading = true;
+      // 缓存
+      operationCatch('set', JSON.stringify({
+        pagination: state.pagination,
+        searchGroup: state.searchGroup
+      }))
       try {
         const { data } = await api_knowledgeWiki_page({
           ...state.pagination,
@@ -81,7 +100,9 @@ export default defineComponent({
         <SearchGroupResources
           categoryChildList={props.categoryChildList || []}
           onSearch={(item: any) => onSearch(item)}
-          wikiCategoryId={props.categoryId}
+          wikiCategoryId={state.searchGroup.wikiCategoryId}
+          defaultWikiCategoryId={props.categoryId}
+          searchValue={state.searchGroup.keyword}
         />
 
         <NSpin v-model:show={state.loading} style={{ 'min-height': '50vh' }}>

+ 14 - 5
src/views/content-information/content-instrument/components/list/search-group-resources.tsx

@@ -9,9 +9,17 @@ export default defineComponent({
       type: Array as PropType<any>,
       default: () => []
     },
+    defaultWikiCategoryId: {
+      type: String,
+      default: ''
+    },
     wikiCategoryId: {
       type: String,
       default: ''
+    },
+    searchValue: {
+      type: String,
+      default: ''
     }
   },
   emits: ['search', 'add'],
@@ -19,8 +27,8 @@ export default defineComponent({
   setup(props, { emit }) {
     // const catchStore = useCatchStore();
     const forms = reactive({
-      keyword: '',
-      wikiCategoryId: props.wikiCategoryId || ''
+      keyword: props.searchValue || '',
+      wikiCategoryId: props.wikiCategoryId || props.defaultWikiCategoryId || ''
     });
 
     const onSearch = () => {
@@ -37,18 +45,18 @@ export default defineComponent({
             {props.categoryChildList.length > 0 ? (
               <NButton
                 type={
-                  forms.wikiCategoryId === props.wikiCategoryId
+                  forms.wikiCategoryId === props.defaultWikiCategoryId
                     ? 'primary'
                     : 'default'
                 }
                 secondary={
-                  forms.wikiCategoryId === props.wikiCategoryId ? false : true
+                  forms.wikiCategoryId === props.defaultWikiCategoryId ? false : true
                 }
                 round
                 size="small"
                 focusable={false}
                 onClick={() => {
-                  forms.wikiCategoryId = props.wikiCategoryId;
+                  forms.wikiCategoryId = props.defaultWikiCategoryId;
                   onSearch();
                 }}>
                 全部
@@ -73,6 +81,7 @@ export default defineComponent({
           </NSpace>
           <TheSearch
             class={styles.inputSearch}
+            value={props.searchValue}
             placeholder="请输入乐器名称"
             round
             onSearch={(val: string) => {

+ 8 - 2
src/views/content-information/content-instrument/detail.module.less

@@ -39,6 +39,11 @@
 
     .highlight {
       color: #0378EC;
+      background-color: #E1F0FF;
+    }
+
+    .speak-label {
+      cursor: pointer;
     }
 
   }
@@ -434,9 +439,10 @@
     padding: 0 27px;
     user-select: text;
     position: relative;
+    cursor: pointer;
 
-    &::selection {
-      background-color: #dfdfdf;
+    ::selection {
+      background-color: #E1F0FF;
     }
 
     &>img {

+ 3 - 2
src/views/content-information/content-instrument/detail.tsx

@@ -11,7 +11,6 @@ import {
   computed,
   defineComponent,
   onMounted,
-  onUnmounted,
   reactive,
   watch
 } from 'vue';
@@ -31,7 +30,6 @@ import TheNoticeBar from '/src/components/TheNoticeBar';
 import TheEmpty from '/src/components/TheEmpty';
 import PlayItem from '../../xiaoku-music/component/play-item';
 import { api_knowledgeWiki_detail } from '../api';
-import { state } from '/src/state';
 import { useSpeak } from '../useSpeak';
 
 export default defineComponent({
@@ -385,6 +383,9 @@ export default defineComponent({
             playState={data.playState}
             item={activeItem.value}
             onChange={value => handleChangeAudio(value)}
+            onShow={(status: boolean) => {
+              data.showPlayer = status
+           }}
           />
         )}
       </div>

+ 1 - 0
src/views/content-information/content-instrument/index.tsx

@@ -80,6 +80,7 @@ export default defineComponent({
               paneWrapperClass={styles.paneWrapperContainer}
               onUpdate:value={(val: any) => {
                 sessionStorage.setItem('content-instrument-tab', val);
+                sessionStorage.removeItem('content-instrument-catch')
               }}
               v-model:value={state.tabValue}>
               {state.categoryList.map((category: any) => (

+ 9 - 0
src/views/content-information/content-knowledge/index.module.less

@@ -38,6 +38,11 @@
 
     .highlight {
       color: #0378EC;
+      background-color: #E1F0FF;
+    }
+
+    .speak-label {
+      cursor: pointer;
     }
   }
 
@@ -271,6 +276,10 @@
     user-select: text;
     position: relative;
 
+    ::selection {
+      background-color: #E1F0FF;
+    }
+
     &>img {
       width: 100%;
     }

+ 37 - 10
src/views/content-information/content-music/components/list/index.tsx

@@ -21,20 +21,40 @@ export default defineComponent({
     }
   },
   setup(props) {
+    // 保存数据
+    const operationCatch = (
+      type: 'get' | 'set' = 'get',
+      value: string = ''
+    ): any => {
+      const sessionName = 'content-music-catch';
+      if (type === 'get') {
+        const result = sessionStorage.getItem(sessionName);
+        return result ? JSON.parse(result) : null;
+      } else if (type === 'set') {
+        sessionStorage.setItem(sessionName, value);
+      }
+    };
     const router = useRouter();
+    const catchData = operationCatch('get');
     const state = reactive({
       searchWord: '',
       loading: false,
       pageTotal: 0,
-      pagination: {
-        page: 1,
-        rows: 18
-      },
-      searchGroup: {
-        type: 'MUSIC', //
-        keyword: '',
-        wikiCategoryId: props.categoryId
-      },
+      pagination:
+        catchData && catchData.pagination
+          ? catchData.pagination
+          : {
+              page: 1,
+              rows: 18
+            },
+      searchGroup:
+        catchData && catchData.searchGroup
+          ? catchData.searchGroup
+          : {
+              type: 'MUSIC', //
+              keyword: '',
+              wikiCategoryId: props.categoryId
+            },
       tableList: [] as any,
       teachingStatus: false,
       show: false,
@@ -43,6 +63,11 @@ export default defineComponent({
 
     const getList = async () => {
       state.loading = true;
+      // 缓存
+      operationCatch('set', JSON.stringify({
+        pagination: state.pagination,
+        searchGroup: state.searchGroup
+      }))
       try {
         const { data } = await api_knowledgeWiki_page({
           ...state.pagination,
@@ -74,7 +99,9 @@ export default defineComponent({
       <div class={styles.instrumentList}>
         <SearchGroupResources
           categoryChildList={props.categoryChildList || []}
-          wikiCategoryId={props.categoryId}
+          wikiCategoryId={state.searchGroup.wikiCategoryId}
+          defaultWikiCategoryId={props.categoryId}
+          searchValue={state.searchGroup.keyword}
           onSearch={(item: any) => onSearch(item)}
         />
 

+ 46 - 5
src/views/content-information/content-music/components/list/search-group-resources.tsx

@@ -10,9 +10,17 @@ export default defineComponent({
       type: Array as PropType<any>,
       default: () => []
     },
+    defaultWikiCategoryId: {
+      type: String,
+      default: ''
+    },
     wikiCategoryId: {
       type: String,
       default: ''
+    },
+    searchValue: {
+      type: String,
+      default: ''
     }
   },
   emits: ['search', 'add'],
@@ -20,8 +28,8 @@ export default defineComponent({
   setup(props, { emit }) {
     // const catchStore = useCatchStore();
     const forms = reactive({
-      keyword: '',
-      wikiCategoryId: props.wikiCategoryId || '',
+      keyword: props.searchValue || '',
+      wikiCategoryId: props.wikiCategoryId || props.defaultWikiCategoryId || '',
       wikiCategoryIdChild: '',
       childIds: [] as any
     });
@@ -93,6 +101,38 @@ export default defineComponent({
       return [];
     });
 
+    const formatParentId = (id: any, list: any, ids = [] as any) => {
+      for (const item of list) {
+        if (item.childrenList && item.childrenList.length > 0) {
+          const cIds: any = formatParentId(id, item.childrenList, [
+            ...ids,
+            item.id
+          ]);
+          if (cIds.includes(id)) {
+            return cIds;
+          }
+        }
+        if (item.id === id) {
+          return [...ids, id];
+        }
+      }
+      return ids;
+    };
+
+    onMounted(() => {
+      // 处理缓存反显
+      if(props.wikiCategoryId) {
+        const ids = formatParentId(props.wikiCategoryId, props.categoryChildList)
+        if(ids.length > 0) {
+          forms.wikiCategoryId = ids[0]
+          forms.wikiCategoryIdChild = ids[ids.length - 1]
+        }
+      } else {
+        forms.wikiCategoryId = props.defaultWikiCategoryId
+      }
+      
+    })
+
     return () => (
       <div class={styles.searchGroup}>
         <div
@@ -104,18 +144,18 @@ export default defineComponent({
             {props.categoryChildList.length > 0 ? (
               <NButton
                 type={
-                  forms.wikiCategoryId === props.wikiCategoryId
+                  forms.wikiCategoryId === props.defaultWikiCategoryId
                     ? 'primary'
                     : 'default'
                 }
                 secondary={
-                  forms.wikiCategoryId === props.wikiCategoryId ? false : true
+                  forms.wikiCategoryId === props.defaultWikiCategoryId ? false : true
                 }
                 round
                 size="small"
                 focusable={false}
                 onClick={() => {
-                  forms.wikiCategoryId = props.wikiCategoryId;
+                  forms.wikiCategoryId = props.defaultWikiCategoryId;
                   forms.wikiCategoryIdChild = '';
                   onSearch();
                 }}>
@@ -142,6 +182,7 @@ export default defineComponent({
           </NSpace>
           <TheSearch
             class={styles.inputSearch}
+            value={props.searchValue}
             placeholder="请输入曲目名称"
             round
             onSearch={(val: string) => {

+ 9 - 0
src/views/content-information/content-music/detail.module.less

@@ -38,6 +38,11 @@
 
     .highlight {
       color: #0378EC;
+      background-color: #E1F0FF;
+    }
+
+    .speak-label {
+      cursor: pointer;
     }
   }
 
@@ -421,6 +426,10 @@
     user-select: text;
     position: relative;
 
+    ::selection {
+      background-color: #E1F0FF;
+    }
+
     &>img {
       width: 100%;
     }

+ 3 - 0
src/views/content-information/content-music/detail.tsx

@@ -390,6 +390,9 @@ export default defineComponent({
             playState={data.playState}
             item={activeItem.value}
             onChange={value => handleChangeAudio(value)}
+            onShow={(status: boolean) => {
+              data.showPlayer = status
+            }}
           />
         )}
       </div>

+ 1 - 1
src/views/content-information/content-music/index.tsx

@@ -79,8 +79,8 @@ export default defineComponent({
               paneWrapperClass={styles.paneWrapperContainer}
               v-model:value={state.tabValue}
               onUpdate:value={(val: any) => {
-                console.log(val, 'val');
                 sessionStorage.setItem('content-music-tab', val);
+                sessionStorage.removeItem('content-music-catch')
               }}>
               {state.categoryList.map((category: any) => (
                 <NTabPane

+ 28 - 3
src/views/content-information/content-musician/components/list/index.tsx

@@ -20,16 +20,34 @@ export default defineComponent({
     }
   },
   setup(props) {
+    // 保存数据
+    const operationCatch = (
+      type: 'get' | 'set' = 'get',
+      value: string = ''
+    ): any => {
+      const sessionName = 'content-musician-catch';
+      if (type === 'get') {
+        const result = sessionStorage.getItem(sessionName);
+        return result ? JSON.parse(result) : null;
+      } else if (type === 'set') {
+        sessionStorage.setItem(sessionName, value);
+      }
+    };
     const router = useRouter();
+    const catchData = operationCatch('get');
     const state = reactive({
       searchWord: '',
       loading: false,
       pageTotal: 0,
-      pagination: {
+      pagination:catchData && catchData.pagination
+      ? catchData.pagination
+      : {
         page: 1,
         rows: 18
       },
-      searchGroup: {
+      searchGroup: catchData && catchData.searchGroup
+      ? catchData.searchGroup
+      :{
         type: 'MUSICIAN', //
         keyword: '',
         wikiCategoryId: props.categoryId
@@ -42,6 +60,11 @@ export default defineComponent({
 
     const getList = async () => {
       state.loading = true;
+      // 缓存
+      operationCatch('set', JSON.stringify({
+        pagination: state.pagination,
+        searchGroup: state.searchGroup
+      }))
       try {
         const { data } = await api_knowledgeWiki_page({
           ...state.pagination,
@@ -79,7 +102,9 @@ export default defineComponent({
       <div class={styles.instrumentList}>
         <SearchGroupResources
           categoryChildList={props.categoryChildList || []}
-          wikiCategoryId={props.categoryId}
+          wikiCategoryId={state.searchGroup.wikiCategoryId}
+          defaultWikiCategoryId={props.categoryId}
+          searchValue={state.searchGroup.keyword}
           onSearch={(item: any) => onSearch(item)}
         />
 

+ 17 - 5
src/views/content-information/content-musician/components/list/search-group-resources.tsx

@@ -9,9 +9,17 @@ export default defineComponent({
       type: Array as PropType<any>,
       default: () => []
     },
+    defaultWikiCategoryId: {
+      type: String,
+      default: ''
+    },
     wikiCategoryId: {
       type: String,
       default: ''
+    },
+    searchValue: {
+      type: String,
+      default: ''
     }
   },
   emits: ['search', 'add'],
@@ -19,9 +27,10 @@ export default defineComponent({
   setup(props, { emit }) {
     // const catchStore = useCatchStore();
     const forms = reactive({
-      keyword: '',
-      wikiCategoryId: props.wikiCategoryId || ''
+      keyword: props.searchValue || '',
+      wikiCategoryId: props.wikiCategoryId || props.defaultWikiCategoryId || ''
     });
+    
 
     const onSearch = () => {
       emit('search', forms);
@@ -29,6 +38,8 @@ export default defineComponent({
     onMounted(async () => {
       // 获取教材分类列表
       // await catchStore.getMusicSheetCategory()
+
+      console.log(forms, 'formsformsformsforms')
     });
     return () => (
       <div class={styles.searchGroup}>
@@ -37,18 +48,18 @@ export default defineComponent({
             {props.categoryChildList.length > 0 ? (
               <NButton
                 type={
-                  forms.wikiCategoryId === props.wikiCategoryId
+                  forms.wikiCategoryId === props.defaultWikiCategoryId
                     ? 'primary'
                     : 'default'
                 }
                 secondary={
-                  forms.wikiCategoryId === props.wikiCategoryId ? false : true
+                  forms.wikiCategoryId === props.defaultWikiCategoryId ? false : true
                 }
                 round
                 size="small"
                 focusable={false}
                 onClick={() => {
-                  forms.wikiCategoryId = props.wikiCategoryId;
+                  forms.wikiCategoryId = props.defaultWikiCategoryId;
                   onSearch();
                 }}>
                 全部
@@ -73,6 +84,7 @@ export default defineComponent({
           </NSpace>
           <TheSearch
             class={styles.inputSearch}
+            value={props.searchValue}
             placeholder="请输入音乐家名称"
             round
             onSearch={(val: string) => {

+ 1 - 0
src/views/content-information/content-musician/index.tsx

@@ -80,6 +80,7 @@ export default defineComponent({
               paneWrapperClass={styles.paneWrapperContainer}
               onUpdate:value={(val: any) => {
                 sessionStorage.setItem('content-musician-tab', val);
+                sessionStorage.removeItem('content-musician-catch')
               }}
               v-model:value={state.tabValue}>
               {state.categoryList.map((category: any) => (

+ 1 - 1
src/views/natural-resources/model/add-teaching/index.module.less

@@ -67,7 +67,7 @@
     p {
       padding-top: 32px;
       font-size: 18px;
-      color: #9EADD9;
+      color: #7799C0;
       line-height: 25px;
     }
   }

+ 26 - 5
src/views/natural-resources/model/add-teaching/index.tsx

@@ -73,6 +73,7 @@ const initState = () => ({
   coverImg: '', // 封面
   instruemntIds: [] as any,
   enableFlag: true, // 状态
+  bookTypes: [], // 册别
   type: 'COURSEWARE', // 教材类型:COURSEWARE,THEORY,可用值:COURSEWARE,THEORY
   lessonList: [] as any // 单元列表
 });
@@ -107,10 +108,11 @@ export default defineComponent({
     const handleSubmit = async () => {
       data.uploading = true;
       try {
-        const { currentGradeNum, instrumentIds, ...more } = form;
+        const { currentGradeNum, bookTypes, instrumentIds, ...more } = form;
         await api_lessonCoursewareSave({
-          currentGradeNum: currentGradeNum.join(','),
-          instrumentIds: instrumentIds.join(','),
+          currentGradeNum: currentGradeNum?.join(','),
+          bookTypes: bookTypes?.join(','),
+          instrumentIds: instrumentIds?.join(','),
           ...more
         });
         Object.assign(form, initState());
@@ -136,6 +138,7 @@ export default defineComponent({
         form.currentGradeNum = data.currentGradeNum
           ? data.currentGradeNum.split(',').map((item: any) => Number(item))
           : null;
+        form.bookTypes = data.bookTypes ? data.bookTypes.split(',') : null
         form.instrumentIds = data.instrumentIds
           ? data.instrumentIds.split(',').map((item: any) => item)
           : null;
@@ -249,6 +252,24 @@ export default defineComponent({
                   />
                 </NFormItem>
                 <NFormItem
+                  path="bookTypes">
+                  <NSelect
+                    style={{ minWidth: '360px' }}
+                    placeholder="请选择册别(选填)"
+                    options={[{
+                      label: '上册',
+                      value: 'LAST'
+                    }, {
+                      label: '下册',
+                      value: 'NEXT'
+                    }]}
+                    v-model:value={form.bookTypes}
+                    clearable
+                    multiple
+                    filterable
+                  />
+                </NFormItem>
+                <NFormItem
                   path="instrumentIds"
                   style={{ width: '360px' }}
                   rule={{
@@ -297,7 +318,7 @@ export default defineComponent({
               目录
             </div>
             <TransitionGroup name="list" tag="div">
-              {form.lessonList.map((item, index) => {
+              {form.lessonList.map((item: any, index: number) => {
                 return (
                   <NSpace
                     class={styles.lessonItem}
@@ -321,7 +342,7 @@ export default defineComponent({
                         clearable></NInput>
                     </NFormItem>
                     <TransitionGroup name="list" tag="div">
-                      {item.knowledgeList.map((know, knowIndex) => {
+                      {item.knowledgeList.map((know: any, knowIndex: number) => {
                         return (
                           <NFormItem
                             style={{

+ 10 - 1
src/views/prepare-lessons/api.ts

@@ -289,9 +289,18 @@ export const api_teacherChapterLessonCoursewareDetail = (id: string) => {
 };
 
 /**
- *  @description: 后台 素材详情
+ *  @description: 素材详情
  * @param params
  */
 export const api_materialDetail = (id: string) => {
   return request.get('/edu-app/material/detail/' + id);
 };
+
+
+/**
+ *  @description: 老师查询教材分类
+ * @param params
+ */
+export const api_lessonCoursewareTeacherCategory = () => {
+  return request.get('/edu-app/lessonCourseware/teacherCategory');
+};

BIN
src/views/prepare-lessons/components/directory-main/images/icon-upload-bg.png


+ 6 - 0
src/views/prepare-lessons/components/directory-main/index.module.less

@@ -40,6 +40,10 @@
   }
 }
 
+.theTooltip {
+  max-width: 300px !important;
+}
+
 .select-directory-info {
   display: flex;
   align-items: center;
@@ -133,6 +137,8 @@
       max-width: 200px;
     }
 
+    
+
     .subjects {
       font-size: max(14px, 11Px);
       color: #777777;

+ 17 - 5
src/views/prepare-lessons/components/directory-main/index.tsx

@@ -1,6 +1,6 @@
 import { computed, defineComponent, onMounted, reactive, ref } from 'vue';
 import styles from './index.module.less';
-import { NIcon, NSpin, NScrollbar, NModal, NImage } from 'naive-ui';
+import { NIcon, NSpin, NScrollbar, NModal, NImage, NTooltip } from 'naive-ui';
 import {
   lessonCoursewareDetail,
   lessonCoursewarePage,
@@ -12,7 +12,7 @@ import { usePrepareStore } from '/src/store/modules/prepareLessons';
 import { useUserStore } from '/src/store/modules/users';
 import { useRoute } from 'vue-router';
 import { eventGlobal } from '/src/utils';
-import TheNoticeBar from '/src/components/TheNoticeBar';
+// import TheNoticeBar from '/src/components/TheNoticeBar';
 import { getSubjectList2 } from '/src/api/user';
 import LessonsGuide from '@/custom-plugins/guide-page/lessons-guide';
 import { modalClickMask } from '/src/state';
@@ -273,17 +273,29 @@ export default defineComponent({
                     src={prepareStore.getBaseCourseware.coverImg}
                     lazy
                     previewDisabled={true}
-                    onLoad={e => {
+                    onLoad={(e: any) => {
                       (e.target as any).dataset.loaded = 'true';
                     }}
                   />
                 </div>
                 <div class={styles.itemContent}>
                   <h2>
-                    <TheNoticeBar text={prepareStore.getBaseCourseware.name} />
+                    {/* <TheNoticeBar text={prepareStore.getBaseCourseware.name} /> */}
+                    <NTooltip showArrow={false} class={styles.theTooltip} placement="top-start">
+                      {{
+                        trigger: () => prepareStore.getBaseCourseware.name,
+                        default: () => prepareStore.getBaseCourseware.name
+                      }}
+                    </NTooltip>
                   </h2>
                   <div class={styles.subjects}>
-                    <TheNoticeBar text={formatInstrumentNames.value} />
+                    {/* <TheNoticeBar text={formatInstrumentNames.value} /> */}
+                    <NTooltip showArrow={false} class={styles.theTooltip} placement="top-start">
+                      {{
+                        trigger: () => formatInstrumentNames.value,
+                        default: () => formatInstrumentNames.value
+                      }}
+                    </NTooltip>
                   </div>
                   <div
                     class={styles.changeDir}

+ 121 - 21
src/views/prepare-lessons/components/directory-main/select-lessonware/index.module.less

@@ -1,13 +1,12 @@
 .attendClassSearch {
   width: 100%;
-  display: flex;
-  align-items: center;
-  gap: 0 24px;
+  // display: flex;
+  // align-items: center;
+  // gap: 0 24px;
   margin-bottom: 6px;
-  padding: 32px 40px 0;
+  padding: 30px 40px 0;
 
   :global {
-
     .n-base-selection,
     .n-input {
       height: 52px;
@@ -20,20 +19,76 @@
     .n-cascader {
       min-width: 240px;
     }
+
+    .n-form {
+      position: relative;
+    }
+
+    .n-form-item {
+      .n-form-item-label {
+        font-size: max(17px, 13px);
+        font-weight: 600;
+        color: #131415;
+        line-height: 24px;
+      }
+
+      .n-button {
+        height: 32px;
+        font-size: max(17px, 12px);
+        border-radius: 8px;
+        color: rgba(0, 0, 0, 0.6);
+      }
+
+      .n-button--primary-type {
+        color: #131415;
+        background-color: #d2ecff !important;
+      }
+    }
+
+    .n-form-item-feedback-wrapper {
+      min-height: 14px;
+    }
   }
 
   .iconSearch {
     width: 16px;
     height: 17px;
   }
+
+  .spaceSection {
+    width: 98%;
+    transition: 1s all ease-in;
+  
+    &>div {
+      height: 34Px !important;
+      display: flex !important;
+      align-items: center;
+      line-height: var(--n-blank-height);
+    }
+  }
+  
+}
+
+.popSelect {
+  font-size: 16px;
+  width: 200px;
+  box-shadow: 0px 2px 16px 0px rgba(0, 0, 0, 0.08);
+  border-radius: 11px;
+  --n-option-height: 34px;
+
+  :global {
+    .n-base-select-option__content {
+      width: 80% !important;
+    }
+  }
 }
 
 .classList {
-  min-height: 60vh;
-  max-height: 60vh;
+  min-height: 70vh;
+  max-height: 70vh;
 
   .content {
-    min-height: 60vh;
+    // min-height: 60vh;
     padding: 22px 40px;
   }
 
@@ -46,7 +101,7 @@
   position: relative;
   width: 214px;
   cursor: pointer;
-  transition: all .3s;
+  transition: all 0.3s;
 
   .cover {
     position: relative;
@@ -59,7 +114,7 @@
       left: 0;
       width: 214px;
       height: 214px;
-      background: #DDF2FF;
+      background: #ddf2ff;
       border-radius: 50%;
     }
   }
@@ -136,7 +191,7 @@
     width: 158px;
     height: 223px;
     margin: auto;
-    background-color: #EDEFF2;
+    background-color: #edeff2;
     background-image: url('../images/icon_default.svg');
     background-repeat: no-repeat;
     background-position: center center;
@@ -149,7 +204,7 @@
       right: -4px;
       width: 4px;
       height: calc(100% - 8px);
-      background-color: #C5C5C5;
+      background-color: #c5c5c5;
       z-index: 1;
     }
 
@@ -160,7 +215,7 @@
       right: -2px;
       width: 4px;
       height: calc(100% - 4px);
-      background-color: #E7E7E7;
+      background-color: #e7e7e7;
       z-index: 2;
     }
 
@@ -172,7 +227,18 @@
       height: 100%;
       z-index: 4;
       background-repeat: no-repeat;
-      background-image: linear-gradient(to right, rgba(0, 0, 0, 0.2) 0, rgba(255, 255, 255, 0.08) 0%, transparent 0.5%), linear-gradient(to right, rgba(0, 0, 0, 0.1) 0.3%, rgba(255, 255, 255, 0.09) 1.1%, transparent 1.3%);
+      background-image: linear-gradient(
+          to right,
+          rgba(0, 0, 0, 0.2) 0,
+          rgba(255, 255, 255, 0.08) 0%,
+          transparent 0.5%
+        ),
+        linear-gradient(
+          to right,
+          rgba(0, 0, 0, 0.1) 0.3%,
+          rgba(255, 255, 255, 0.09) 1.1%,
+          transparent 1.3%
+        );
       background-size: 50% 100%, 50% 100%;
       background-position: 0% top, 9% top;
     }
@@ -187,15 +253,13 @@
     }
 
     img {
-      transition: opacity .3s;
+      transition: opacity 0.3s;
       opacity: 0;
     }
 
-    img[data-loaded="true"] {
+    img[data-loaded='true'] {
       opacity: 1;
     }
-
-
   }
 
   .itemName {
@@ -216,7 +280,7 @@
 
   :global {
     .n-card-header {
-      font-size: max(22px, 16Px);
+      font-size: max(22px, 16px);
     }
   }
 
@@ -224,13 +288,13 @@
     padding: 20px 40px 0;
 
     p {
-      font-size: max(18px, 14Px);
+      font-size: max(18px, 14px);
       color: #777777;
       line-height: 30px;
       text-align: center;
 
       span {
-        color: #EA4132;
+        color: #ea4132;
       }
     }
   }
@@ -246,3 +310,39 @@
     }
   }
 }
+
+.textBtn {
+  background: #fff;
+  border-radius: 8px;
+  padding: 4px 20px;
+  font-size: max(17px, 13Px);
+  color: rgba(0, 0, 0, 0.6);
+  cursor: pointer;
+  display: flex;
+  align-items: center;
+  font-weight: 500;
+  line-height: max(24px, 20Px);
+
+  .iconArrow {
+    display: inline-block;
+    margin-left: 8px;
+    width: 8px;
+    height: 5px;
+    background: url('../../../../content-information/images/icon-arrow2.png')
+      no-repeat center center / contain;
+    transform: rotate(180deg);
+  }
+
+  &:hover,
+  &.textBtnActive {
+    background: #d2ecff;
+    font-weight: 500;
+    color: #131415;
+  }
+
+  &:hover {
+    .iconArrow {
+      transform: rotate(0deg);
+    }
+  }
+}

+ 201 - 28
src/views/prepare-lessons/components/directory-main/select-lessonware/index.tsx

@@ -3,9 +3,12 @@ import styles from './index.module.less';
 import {
   NButton,
   NCascader,
+  NForm,
+  NFormItem,
   NImage,
   NInput,
   NModal,
+  NPopselect,
   NScrollbar,
   NSelect,
   NSpace,
@@ -19,7 +22,7 @@ import AddTeaching, {
 import {
   lessonCoursewarePage,
   lessonCoursewareRemove,
-  bookVersionPage
+  api_lessonCoursewareTeacherCategory
 } from '../../../api';
 import iconUploadBg from '../images/icon-upload-bg.png';
 import { useCatchStore } from '/src/store/modules/catchData';
@@ -43,26 +46,35 @@ export default defineComponent({
       selectItem: {} as any,
       bookVersionId: null,
       keyword: null,
-      currentGradeNum: null,
-      instrumentId: null,
+      currentGradeNum: '' as any,
+      instrumentId: '' as any,
       removeVisiable: false,
-      removeRow: {} as any
-      // bookType: null
+      removeRow: {} as any,
+      bookType: '' as any
+    });
+
+    const treeList = reactive({
+      tempSubjectId: null,
+      versionList: [] as any, // 教材
+      gradeList: [] as any, // 年级
+      bookTypeList: [] as any // 册别
     });
 
     const getLessonCourseware = async () => {
       forms.loading = true;
       try {
+        console.log(forms.bookVersionId, 'bookVersionId')
         const { data } = await lessonCoursewarePage({
           page: 1,
           rows: 99,
           type: 'COURSEWARE',
           enableFlag: 1,
-          bookVersionId: forms.bookVersionId,
+          bookVersionId: forms.bookVersionId === '0' ? null : forms.bookVersionId,
+          customFlag: forms.bookVersionId === '0' ? true : null,
           keyword: forms.keyword,
           currentGradeNum: forms.currentGradeNum,
-          instrumentId: forms.instrumentId
-          // bookType: forms.bookType
+          instrumentId: forms.instrumentId,
+          bookType: forms.bookType
         });
 
         forms.list = data.rows;
@@ -91,22 +103,50 @@ export default defineComponent({
       emit('close');
     };
 
+    const getSearchDetail = async () => {
+      try {
+        const { data } = await api_lessonCoursewareTeacherCategory();
+        console.log(data, 'data');
+
+        const result = data || []
+
+        treeList.versionList = [{
+          name: '全部',
+          id: ''
+        }, ...result]
+      } catch {
+        //
+      }
+    };
+
+    const selectChildObj = (item: any) => {
+      const obj: any = {};
+      item?.forEach((child: any) => {
+        if (child.id === forms.instrumentId) {
+          obj.selected = true;
+          obj.name = child.name;
+        }
+      });
+      return obj;
+    };
+
     onMounted(async () => {
       // 获取教材分类列表
       try {
         await catchStore.getSubjects();
-        const { data } = await bookVersionPage({
-          page: 1,
-          rows: 99,
-          type: 'COURSEWARE'
-        });
-        const temp = data.rows || [];
-        temp.forEach((item: any) => {
-          forms.musicTagList.push({
-            id: item.id,
-            name: item.name
-          });
-        });
+        // const { data } = await bookVersionPage({
+        //   page: 1,
+        //   rows: 99,
+        //   type: 'COURSEWARE'
+        // });
+        // const temp = data.rows || [];
+        // temp.forEach((item: any) => {
+        //   forms.musicTagList.push({
+        //     id: item.id,
+        //     name: item.name
+        //   });
+        // });
+        await getSearchDetail();
       } catch {
         //
       }
@@ -114,8 +154,142 @@ export default defineComponent({
     });
     return () => (
       <div class={styles.selectLessonware}>
-        <div class={styles.attendClassSearch}>
-          <NInput
+        <NScrollbar class={styles.classList}>
+          <div class={styles.attendClassSearch}>
+            <NForm labelAlign="left" labelPlacement="left">
+              {treeList.versionList.length > 0 && <NFormItem label="教程:">
+                <NSpace class={styles.spaceSection}>
+                  {treeList.versionList?.map((subject: any) => (
+                    <span
+                      class={[
+                        styles.textBtn,
+                        (forms.bookVersionId || '') ==
+                          subject.id && styles.textBtnActive
+                      ]}
+                      onClick={() => {
+                        treeList.bookTypeList = []
+                        forms.currentGradeNum = ''
+                        forms.bookType = ''
+                        if(subject.children && subject.children.length > 0) {
+                          const result = subject.children || []
+                          treeList.gradeList =  [{
+                            name: '全部',
+                            id: ''
+                          }, ...result]
+                        } else {
+                          treeList.gradeList = []
+                        }
+                        forms.bookVersionId = subject.id
+
+                        throttledFn()
+                      }}>
+                      {subject.name}
+                    </span>
+                  ))}
+                </NSpace>
+              </NFormItem>}
+              
+              {treeList.gradeList.length > 0 && <NFormItem label="年级:">
+                <NSpace class={styles.spaceSection}>
+                  {treeList.gradeList?.map((subject: any) => (
+                    <span
+                      class={[
+                        styles.textBtn,
+                        (forms.currentGradeNum || '') == subject.id &&
+                          styles.textBtnActive
+                      ]}
+                      onClick={() => {
+                        forms.bookType = ''
+                        if(subject.children && subject.children.length > 0) {
+                          treeList.bookTypeList = subject.children || []
+                          const result = subject.children || []
+                          treeList.bookTypeList =  [{
+                            name: '全部',
+                            id: ''
+                          }, ...result]
+                        } else {
+                          treeList.bookTypeList = []
+                        }
+                        forms.currentGradeNum = subject.id
+
+                        throttledFn()
+                      }}>
+                      {subject.name}
+                    </span>
+                  ))}
+                </NSpace>
+              </NFormItem>}
+              
+              {treeList.bookTypeList.length > 0 && <NFormItem label="册别:">
+                <NSpace class={styles.spaceSection}>
+                  {treeList.bookTypeList?.map((subject: any) => (
+                    <span
+                      class={[
+                        styles.textBtn,
+                        (forms.bookType || '') ==
+                          subject.id && styles.textBtnActive
+                      ]}
+                      onClick={() => {
+                        forms.bookType = subject.id
+
+                        throttledFn()
+                      }}>
+                      {subject.name}
+                    </span>
+                  ))}
+                </NSpace>
+              </NFormItem>}
+              
+
+              <NFormItem label="乐器:">
+                <NSpace class={styles.spaceSection}>
+                  {[
+                    { name: '全部乐器', value: '' },
+                    ...catchStore.getSubjectInstrumentOnly
+                  ].map((subject: any) =>
+                    subject.instruments && subject.instruments.length > 1 ? (
+                      <NPopselect
+                        options={subject.instruments}
+                        trigger="hover"
+                        scrollable
+                        v-model:value={treeList.tempSubjectId}
+                        onUpdate:value={() => {
+                          forms.instrumentId = treeList.tempSubjectId;
+                          throttledFn()
+                        }}
+                        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.instrumentId === subject.value &&
+                            styles.textBtnActive
+                        ]}
+                        onClick={() => {
+                          forms.instrumentId = subject.value;
+                          treeList.tempSubjectId = null;
+                          throttledFn()
+                        }}>
+                        {subject.name}
+                      </span>
+                    )
+                  )}
+                </NSpace>
+              </NFormItem>
+            </NForm>
+            {/* <NInput
             placeholder="请输入教材名称"
             clearable
             v-model:value={forms.keyword}
@@ -174,8 +348,8 @@ export default defineComponent({
             clearable
             filterable
             onUpdate:value={() => throttledFn()}
-          />
-          {/* <NSelect
+          /> */}
+            {/* <NSelect
             placeholder="全部册别"
             options={
               [
@@ -187,8 +361,7 @@ export default defineComponent({
             clearable
             onUpdate:value={() => throttledFn()}
           /> */}
-        </div>
-        <NScrollbar class={styles.classList}>
+          </div>
           <NSpin show={forms.loading} class={styles.content}>
             <NSpace class={styles.teachingSpace}>
               <div
@@ -206,7 +379,7 @@ export default defineComponent({
                       src={iconUploadBg}
                       lazy
                       previewDisabled={true}
-                      onLoad={e => {
+                      onLoad={(e: any) => {
                         (e.target as any).dataset.loaded = 'true';
                       }}
                     />
@@ -227,7 +400,7 @@ export default defineComponent({
                           src={item.coverImg}
                           lazy
                           previewDisabled={true}
-                          onLoad={e => {
+                          onLoad={(e: any) => {
                             (e.target as any).dataset.loaded = 'true';
                           }}
                         />

+ 4 - 3
src/views/prepare-lessons/components/lesson-main/courseware-presets/index.tsx

@@ -383,7 +383,8 @@ export default defineComponent({
             type: 'class',
             classGroupId: classGroupId,
             courseId: item.id,
-            instrumentId: instrumentId || route.query.instrumentId,
+            instrumentId: prepareStore.getInstrumentId, // 产品说预览和上课都取当前选中的乐器
+            // instrumentId: instrumentId || route.query.instrumentId,
             detailId: prepareStore.getSelectKey,
             classId: res.data,
             lessonCourseId: prepareStore.getBaseCourseware.id,
@@ -396,8 +397,8 @@ export default defineComponent({
               type: 'class',
               classGroupId: classGroupId,
               courseId: item.id,
-              // instrumentId: prepareStore.getInstrumentId,
-              instrumentId: instrumentId || route.query.instrumentId,
+              instrumentId: prepareStore.getInstrumentId,
+              // instrumentId: instrumentId || route.query.instrumentId,
               detailId: prepareStore.getSelectKey,
               classId: res.data,
               lessonCourseId: prepareStore.getBaseCourseware.id,

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

@@ -449,7 +449,6 @@ export default defineComponent({
         });
         forms.coursewareList[item.index || 0].list = array;
 
-        console.log(forms.coursewareList, 'courseware add drag');
         timer = setTimeout(() => {
           // 内容有更新 - 相关资源会刷新
           eventGlobal.emit('onCoursewareUpdate');
@@ -879,6 +878,7 @@ export default defineComponent({
                             isCollect: dropItem.isCollect,
                             isSelected: dropItem.isSelected,
                             content: dropItem.content,
+                            audioPlayTypeArray: dropItem.audioPlayTypeArray,
                             removeFlag: false,
                             index
                           },

+ 1 - 0
src/views/prepare-lessons/components/lesson-main/train/assign-homework.tsx

@@ -425,6 +425,7 @@ export default defineComponent({
               clearable
               onUpdate:value={() => {
                 forms.classGroupId = null;
+                forms.studentList = []
                 getClassList();
               }}
             />

+ 3 - 0
src/views/prepare-lessons/components/lesson-main/train/index.tsx

@@ -135,6 +135,9 @@ export default defineComponent({
           }
           temp.push({
             typeList: tList || [],
+            audioPlayTypeArray:row.audioPlayTypes
+            ? row.audioPlayTypes.split(',')
+            : [],
             ...row
           });
         });

+ 1 - 1
src/views/prepare-lessons/model/attend-class/index.tsx

@@ -50,7 +50,7 @@ export default defineComponent({
             emit('confirm', {
               lastUseCoursewareId: item.lessonCoursewareId,
               unit: item.lessonCoursewareKnowledgeDetailId,
-              instrumentId: item.instrumentId,
+              instrumentId: prepareStore.getInstrumentId, // item.instrumentId,
               courseScheduleSubjectId: item.courseScheduleSubjectId,
               name: item.name, // 班级名称
               classGroupId: item.id, // 班级编号

+ 7 - 2
src/views/prepare-lessons/model/source-instrument/detail.module.less

@@ -35,6 +35,11 @@
   :global {
     .highlight {
       color: #0378EC;
+      background-color: #E1F0FF;
+    }
+
+    .speak-label {
+      cursor: pointer;
     }
   }
 }
@@ -442,8 +447,8 @@
     user-select: text;
     position: relative;
 
-    &::selection {
-      background-color: #dfdfdf;
+    ::selection {
+      background-color: #E1F0FF;
     }
 
     &>img {

+ 3 - 0
src/views/prepare-lessons/model/source-instrument/detail.tsx

@@ -407,6 +407,9 @@ export default defineComponent({
             playState={data.playState}
             item={activeItem.value}
             onChange={value => handleChangeAudio(value)}
+            onShow={(status: boolean) => {
+              data.showPlayer = status
+            }}
           />
         )}
       </div>

+ 9 - 0
src/views/prepare-lessons/model/source-knowledge/index.module.less

@@ -269,6 +269,10 @@
     position: relative;
     user-select: text;
     position: relative;
+    
+    ::selection {
+      background-color: #E1F0FF;
+    }
 
     &:focus-visible {
       border: none !important;
@@ -279,6 +283,11 @@
     :global {
       .highlight {
         color: #0378EC;
+        background-color: #E1F0FF;
+      }
+  
+      .speak-label {
+        cursor: pointer;
       }
     }
 

+ 9 - 0
src/views/prepare-lessons/model/source-music/detail.module.less

@@ -23,6 +23,11 @@
   :global {
     .highlight {
       color: #0378EC;
+      background-color: #E1F0FF;
+    }
+
+    .speak-label {
+      cursor: pointer;
     }
   }
 }
@@ -395,6 +400,10 @@
     user-select: text;
     position: relative;
 
+    ::selection {
+      background-color: #E1F0FF;
+    }
+
     &>img {
       width: 100%;
     }

+ 3 - 0
src/views/prepare-lessons/model/source-music/detail.tsx

@@ -436,6 +436,9 @@ export default defineComponent({
             playState={data.playState}
             item={activeItem.value}
             onChange={value => handleChangeAudio(value)}
+            onShow={(status: boolean) => {
+              data.showPlayer = status
+            }}
           />
         )}
       </div>

+ 13 - 1
src/views/setting/components/schoolInfo/index.tsx

@@ -144,6 +144,7 @@ export default defineComponent({
               <NButton
                 type="primary"
                 text
+                disabled={row.id !== user.info.id && btnStatus(row)}
                 onClick={() => {
                   data.resetMessage = `重置"${row.nickname}"的密码,是否继续?`;
                   data.resetVisiable = true;
@@ -156,7 +157,7 @@ export default defineComponent({
               {row.status === 'ACTIVATION' ? (
                 <>
                   <NButton
-                    disabled={row.id === user.info.id}
+                    disabled={row.id === user.info.id || btnStatus(row)}
                     type="primary"
                     text
                     onClick={() => handleChange(row)}>
@@ -182,11 +183,22 @@ export default defineComponent({
                   解冻
                 </NButton>
               )}
+
             </NSpace>
           )
         }
       ];
     };
+
+
+    const btnStatus = (row: any, type?: string) => {
+      // 管理员
+      if(user.info.teacherJobType === "ADMIN" && ["ADMIN", "HEADMASTER"].includes(row.jobType)) {
+        return true
+      }
+      return false
+    }
+
     const getAreaList = async () => {
       const res = await api_sysAreaQueryAllProvince();
       if (res?.code === 200) {

+ 127 - 12
src/views/studentList/components/evaluationRecords.tsx

@@ -1,16 +1,17 @@
-import { Ref, defineComponent, onMounted, reactive, ref } from 'vue';
+import {  defineComponent, onMounted, reactive, ref } from 'vue';
 import styles from '../index.module.less';
 import {
   NButton,
   NDataTable,
   NForm,
   NFormItem,
+  NInput,
+  NInputNumber,
   NModal,
-  NNumberAnimation,
   NSpace,
   NTag
 } from 'naive-ui';
-import { useECharts } from '@/hooks/web/useECharts';
+// import { useECharts } from '@/hooks/web/useECharts';
 import Pagination from '/src/components/pagination';
 import { getPracticeRecordList } from '../api';
 import {
@@ -18,13 +19,16 @@ import {
   getNowDateAndSunday,
   getTimes
 } from '/src/utils/dateFormat';
-import { vaildMusicScoreUrl, vaildUrl } from '@/utils/urlUtils';
+import { vaildMusicScoreUrl } from '@/utils/urlUtils';
 import CDatePicker from '/src/components/CDatePicker';
 import { useUserStore } from '/src/store/modules/users';
 import TheEmpty from '/src/components/TheEmpty';
 import { initCache, setCache } from '/src/hooks/use-async';
 import { iframeDislableKeyboard } from '/src/utils';
 import { modalClickMask } from '/src/state';
+// import SearchInput from '/src/components/searchInput';
+import CSelect from '/src/components/CSelect';
+import { evaluateDifficultArray } from '/src/utils/searchArray';
 export default defineComponent({
   name: 'student-practiceData',
   props: {
@@ -40,8 +44,8 @@ export default defineComponent({
   setup(props) {
     const userStore = useUserStore();
     const chartRef = ref<HTMLDivElement | null>(null);
-    const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
-    const practiceFlag = ref(true);
+    // const { setOptions } = useECharts(chartRef as Ref<HTMLDivElement>);
+    // const practiceFlag = ref(true);
     const payForm = reactive({
       height: '360px',
       width: '100%',
@@ -60,6 +64,14 @@ export default defineComponent({
         rows: 10,
         pageTotal: 4
       },
+      searchForm: {
+        musicSheetName: '',
+        heardLevel: null, //
+        userMusicFlag: null, // 是否生成作品
+        minScore: null,
+        maxScore: null,
+        musicStartTime: []
+      },
       tableList: [] as any,
       goCourseVisiable: false
     });
@@ -130,6 +142,20 @@ export default defineComponent({
           }
         },
         {
+          title: '生成作品',
+          key: 'integrity',
+          render(row: any) {
+            return <span>{row.userMusicFlag ? '是' : '否'}</span>;
+          }
+        },
+        {
+          title: '生成时间',
+          key: 'userMusicTime',
+          render(row: any) {
+            return <span>{row.userMusicTime || '--'}</span>;
+          }
+        },
+        {
           title: '操作',
           key: 'id',
           render(row: any) {
@@ -148,9 +174,16 @@ export default defineComponent({
       ];
     };
     const getList = async () => {
+      const { musicStartTime, ...temp } = state.searchForm;
       const res = await getPracticeRecordList({
         userId: props.studentId,
         ...state.pagination,
+        ...temp,
+        ...getTimes(
+          musicStartTime,
+          ['userMusicStartTime', 'userMusicEndTime'],
+          'YYYY-MM-DD'
+        ),
         classGroupId: props.classGroupId,
         feature: 'EVALUATION',
         ...getTimes(timer.value, ['startTime', 'endTime'], 'YYYY-MM-DD')
@@ -159,13 +192,12 @@ export default defineComponent({
       state.pagination.pageTotal = res.data.total;
     };
     const gotoRecode = (row: any) => {
-      console.log(row.id, 'gotoRecode');
-      const tockn = userStore.getToken;
+      const token = userStore.getToken;
       reportSrc.value =
         vaildMusicScoreUrl() +
         `/instrument/?v=${+new Date()}#/evaluat-report?v=${+new Date()}&id=${
           row.id
-        }&platform=webTeacher&Authorization=${tockn}`;
+        }&platform=webTeacher&Authorization=${token}`;
       payForm.detailVisiable = true;
     };
     const search = () => {
@@ -181,6 +213,14 @@ export default defineComponent({
         getNowDateAndMonday(new Date().getTime()),
         getNowDateAndSunday(new Date().getTime())
       ];
+      state.searchForm = {
+        musicSheetName: '',
+        heardLevel: null, //
+        userMusicFlag: null, // 是否生成作品
+        minScore: null,
+        maxScore: null,
+        musicStartTime: []
+      };
       search();
       setCache({
         current: { timer: timer.value },
@@ -197,18 +237,94 @@ export default defineComponent({
     const iframeRef = ref();
     onMounted(() => {
       getList();
-      console.log(props.studentId);
     });
     return () => (
       <>
-        <NForm label-placement="left" inline>
+        <NForm label-placement="left" inline style="flex-wrap: wrap;">
           <NFormItem>
             <CDatePicker
               v-model:value={timer.value}
               separator={'至'}
               type="daterange"
+              class={styles.datePicker}
+              startPlaceholder="评测开始时间"
+              endPlaceholder="评测结束时间"
               timerValue={timer.value}></CDatePicker>
           </NFormItem>
+          <NFormItem>
+            <NInput
+              placeholder="请输入曲目名称"
+              v-model:value={state.searchForm.musicSheetName}
+            />
+            {/* v-model:value={state.searchForm.keyword} */}
+            {/* <SearchInput
+              {...{ placeholder: '请输入曲目名称' }}
+              class={styles.searchInput}
+              style={{ width: '160px' }}
+              // searchWord={state.searchForm.keyword}
+              // onChangeValue={(val: string) =>
+              //   (state.searchForm.keyword = val)
+              // }
+            ></SearchInput> */}
+          </NFormItem>
+
+          <NFormItem>
+            <CSelect
+              {...({
+                options: evaluateDifficultArray,
+                placeholder: '请输入评测难度',
+                clearable: true,
+                inline: true
+              } as any)}
+              v-model:value={state.searchForm.heardLevel}></CSelect>
+          </NFormItem>
+          <NFormItem>
+            <div class={styles.inputRangeSection}>
+              <NInputNumber
+                placeholder="最小分值"
+                min={0}
+                max={state.searchForm.maxScore || 100}
+                showButton={false}
+                precision={0}
+                v-model:value={state.searchForm.minScore}></NInputNumber>
+              <span class={styles.pair}>-</span>
+              <NInputNumber
+                placeholder="最大分值"
+                min={state.searchForm.minScore || 0}
+                max={100}
+                precision={0}
+                showButton={false}
+                v-model:value={state.searchForm.maxScore}></NInputNumber>
+            </div>
+          </NFormItem>
+
+          <NFormItem>
+            <CSelect
+              {...({
+                options: [
+                  { label: '是', value: true },
+                  { label: '否', value: false }
+                ],
+                placeholder: '请选择是否生成作品',
+                clearable: true,
+                inline: true
+              } as any)}
+              v-model:value={state.searchForm.userMusicFlag}></CSelect>
+          </NFormItem>
+
+          <NFormItem>
+            <CDatePicker
+              v-model:value={state.searchForm.musicStartTime}
+              separator={'至'}
+              class={styles.datePicker}
+              type="daterange"
+              startPlaceholder="生成开始时间"
+              endPlaceholder="生成结束时间"
+              {...({
+                clearable: true
+              } as any)}
+              timerValue={state.searchForm.musicStartTime}></CDatePicker>
+          </NFormItem>
 
           <NFormItem>
             <NSpace justify="end">
@@ -247,7 +363,6 @@ export default defineComponent({
           <div class={styles.reportContainer} style={{ lineHeight: 0 }}>
             <iframe
               width={'100%'}
-              height={'450px'}
               ref={iframeRef}
               frameborder="0"
               onLoad={(val: any) => {

+ 30 - 0
src/views/studentList/index.module.less

@@ -12,6 +12,32 @@
   }
 }
 
+.datePicker {
+  :global {
+    .n-input {
+      width: 320px !important;
+    }
+  }
+}
+
+.inputRangeSection {
+  display: flex;
+  align-items: center;
+
+  .pair {
+    font-size: max(15px, 13Px);
+    color: rgba(0, 0, 0, 0.4);
+    line-height: 21px;
+    padding: 0 6px;
+  }
+
+  :global {
+    .n-input-number {
+      width: 92px;
+    }
+  }
+}
+
 .infoListWrap {
   min-height: calc(100vh - 150px) !important
 }
@@ -293,6 +319,10 @@
   overflow: hidden;
 }
 
+.reportContainer iframe {
+  height: 64vh;
+}
+
 .addStudentWrap {
   position: relative;
   width: 378px;

+ 32 - 3
src/views/xiaoku-music/component/play-item/index.module.less

@@ -20,14 +20,15 @@
   &.containerModal {
     position: absolute;
     left: 0;
-
   }
 }
 
 .hidden {
   transform: translateY(100%);
-  opacity: 0;
-  display: none;
+  &.item {
+     opacity: 0;
+     display: none;
+  }
 }
 
 .item {
@@ -171,4 +172,32 @@
     white-space: nowrap;
     flex-shrink: 0;
   }
+}
+
+
+.iconArrow {
+  position: absolute;
+  top: -24px;
+  right: 30px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+  background-color: #fff;
+  cursor: pointer;
+  background: #ffffff;
+  border-radius: 100px 100px 0px 0px;
+  width: 44px;
+  height: 24px;
+  img {
+     margin-top: 3px;
+     width: 14px;
+     height: 14px;
+  }
+
+  &.down {
+     img {
+       margin-top: 0px;
+        transform: rotate(180deg);
+     }
+  }
 }

+ 13 - 12
src/views/xiaoku-music/component/play-item/index.tsx

@@ -1,12 +1,4 @@
-import {
-  PropType,
-  Transition,
-  computed,
-  defineComponent,
-  reactive,
-  ref,
-  watch
-} from 'vue';
+import { PropType, computed, defineComponent, reactive, ref, watch } from 'vue';
 import styles from './index.module.less';
 import { NButton, NImage, NProgress, NSlider } from 'naive-ui';
 import { IMusicItem } from '../../type';
@@ -14,6 +6,7 @@ import icon_pre from '../../images/icon_pre.png';
 import icon_next from '../../images/icon_next.png';
 import icon_play from '../../images/icon_play.png';
 import icon_pause from '../../images/icon_pause.png';
+import song_arrow from '../../images/song-arrow.png';
 import { getSecondRPM } from '/src/utils';
 import TheNoticeBar from '/src/components/TheNoticeBar';
 
@@ -37,7 +30,7 @@ export default defineComponent({
       default: ''
     }
   },
-  emits: ['change'],
+  emits: ['change', 'show'],
   setup(props, { emit }) {
     let timer = null as any;
     const audioData = reactive({
@@ -127,7 +120,7 @@ export default defineComponent({
                 props.item.titleImg ||
                 'https://oss.dayaedu.com/klx/16983720423251690789356356.png'
               }
-              onLoad={e => {
+              onLoad={(e: any) => {
                 (e.target as any).dataset.loaded = 'true';
               }}
             />
@@ -202,7 +195,7 @@ export default defineComponent({
               class={styles.timeProgress}
               value={audioData.currentTime}
               max={audioData.duration}
-              onUpdate:value={val => handleChangeTime(val)}
+              onUpdate:value={(val: any) => handleChangeTime(val)}
             />
             <div class={styles.time}>{time.value}</div>
             <audio
@@ -218,6 +211,14 @@ export default defineComponent({
               }}></audio>
           </div>
         </div>
+
+        <div
+          class={[styles.iconArrow, props.show ? '' : styles.down]}
+          onClick={() => {
+            emit('show', !props.show);
+          }}>
+          <img src={song_arrow as any} />
+        </div>
       </div>
     );
   }

BIN
src/views/xiaoku-music/images/song-arrow.png


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

@@ -530,7 +530,7 @@
   .previewIframe {
     width: 100%;
     height: 85vh;
-    background-color: #fff;
+    background-color: #234892;
     border-radius: 16px;
   }
 }

+ 11 - 9
src/views/xiaoku-music/index.tsx

@@ -569,7 +569,7 @@ export default defineComponent({
           };
         })
         .filter((item: any) => item.canselect)
-        .sort((a: any, b: any) => a.sortId - b.sortId);
+        //.sort((a: any, b: any) => a.sortId - b.sortId);
       data.trackList = arr;
 
       // 是否显示总谱
@@ -865,7 +865,7 @@ export default defineComponent({
                               objectFit="cover"
                               previewDisabled={true}
                               src={item.titleImg || icon_default}
-                              onLoad={e => {
+                              onLoad={(e: any) => {
                                 (e.target as any).dataset.loaded = 'true';
                               }}
                             />
@@ -883,19 +883,18 @@ export default defineComponent({
                               <TheNoticeBar text={item.musicSheetName} />
                             </div>
                             <div class={styles.titleDes}>
-                              {item.audioPlayTypeArray?.includes('PLAY') && (
-                                <span
-                                  class={[styles.iconType, styles.iconPlay]}>
-                                  演奏
-                                </span>
-                              )}
-
                               {item.audioPlayTypeArray?.includes('SING') && (
                                 <span
                                   class={[styles.iconType, styles.iconSing]}>
                                   演唱
                                 </span>
                               )}
+                              {item.audioPlayTypeArray?.includes('PLAY') && (
+                                <span
+                                  class={[styles.iconType, styles.iconPlay]}>
+                                  演奏
+                                </span>
+                              )}
 
                               <span class={styles.composer}>
                                 {item.composer}
@@ -1133,6 +1132,9 @@ export default defineComponent({
             playState={data.playState}
             item={activeItem.value}
             onChange={value => handleChangeAudio(value)}
+            onShow={(status: boolean) => {
+              data.showPlayer = status
+           }}
           />
         )}
         {showGuide.value ? <Musicguide></Musicguide> : null}

+ 1 - 1
vite.config.ts

@@ -23,7 +23,7 @@ function resolve(dir: string) {
 }
 // https://vitejs.dev/config/
 // https://github.com/vitejs/vite/issues/1930 .env
-const proxyUrl = 'https://test.kt.colexiu.com/';
+const proxyUrl = 'https://dev.kt.colexiu.com/';
 // const proxyUrl = 'https://test.kt.colexiu.com';
 // const proxyUrl = 'http://192.168.3.14:7989';
 const now = new Date().getTime();