Explorar el Código

Merge branch 'iteration-20240408-autoplay' into online

lex hace 1 año
padre
commit
5c37d4b448
Se han modificado 29 ficheros con 1299 adiciones y 700 borrados
  1. 46 37
      dev-dist/sw.js
  2. 4 1
      src/components/card-preview/song-modal/index.module.less
  3. 16 16
      src/components/card-preview/song-modal/index.tsx
  4. 15 14
      src/components/card-preview/video-modal/index.module.less
  5. 59 59
      src/components/card-preview/video-modal/index.tsx
  6. 58 23
      src/views/attend-class/component/audio-pay.tsx
  7. 4 1
      src/views/attend-class/component/audio.module.less
  8. 97 64
      src/views/attend-class/component/video-play.tsx
  9. 6 5
      src/views/attend-class/component/video.module.less
  10. BIN
      src/views/attend-class/image/icon-speed.png
  11. 11 9
      src/views/attend-class/index.tsx
  12. 1 1
      src/views/natural-resources/components/my-resources/index.module.less
  13. BIN
      src/views/prepare-lessons/components/directory-main/images/arrow-active.png
  14. BIN
      src/views/prepare-lessons/components/directory-main/images/arrow-default.png
  15. BIN
      src/views/prepare-lessons/components/directory-main/images/icon-d-active.png
  16. BIN
      src/views/prepare-lessons/components/directory-main/images/icon-d.png
  17. 137 4
      src/views/prepare-lessons/components/directory-main/index.module.less
  18. 107 38
      src/views/prepare-lessons/components/directory-main/index.tsx
  19. 106 0
      src/views/prepare-lessons/components/lesson-main/courseware-head/index.module.less
  20. 141 0
      src/views/prepare-lessons/components/lesson-main/courseware-head/index.tsx
  21. 148 148
      src/views/prepare-lessons/components/lesson-main/courseware/addCourseware.module.less
  22. 98 162
      src/views/prepare-lessons/components/lesson-main/courseware/addCourseware.tsx
  23. 88 0
      src/views/prepare-lessons/components/lesson-main/index.module.less
  24. 122 108
      src/views/prepare-lessons/components/lesson-main/index.tsx
  25. 4 2
      src/views/prepare-lessons/components/resource-main/components/resource-item/index.tsx
  26. BIN
      src/views/prepare-lessons/images/icon-book.png
  27. BIN
      src/views/prepare-lessons/images/icon-question.png
  28. 26 2
      src/views/prepare-lessons/index.module.less
  29. 5 6
      src/views/prepare-lessons/index.tsx

+ 46 - 37
dev-dist/sw.js

@@ -13,31 +13,29 @@
 
 // If the loader is already loaded, just stop.
 if (!self.define) {
-  let registry = {};
+  const registry = {};
 
   // Used for `eval` and `importScripts` where we can't get script URL by other means.
   // In both cases, it's safe to use a global var because those functions are synchronous.
   let nextDefineUri;
 
   const singleRequire = (uri, parentUri) => {
-    uri = new URL(uri + ".js", parentUri).href;
-    return registry[uri] || (
-      
-        new Promise(resolve => {
-          if ("document" in self) {
-            const script = document.createElement("script");
-            script.src = uri;
-            script.onload = resolve;
-            document.head.appendChild(script);
-          } else {
-            nextDefineUri = uri;
-            importScripts(uri);
-            resolve();
-          }
-        })
-      
-      .then(() => {
-        let promise = registry[uri];
+    uri = new URL(uri + '.js', parentUri).href;
+    return (
+      registry[uri] ||
+      new Promise(resolve => {
+        if ('document' in self) {
+          const script = document.createElement('script');
+          script.src = uri;
+          script.onload = resolve;
+          document.head.appendChild(script);
+        } else {
+          nextDefineUri = uri;
+          importScripts(uri);
+          resolve();
+        }
+      }).then(() => {
+        const promise = registry[uri];
         if (!promise) {
           throw new Error(`Module ${uri} didn’t register its module`);
         }
@@ -47,27 +45,31 @@ if (!self.define) {
   };
 
   self.define = (depsNames, factory) => {
-    const uri = nextDefineUri || ("document" in self ? document.currentScript.src : "") || location.href;
+    const uri =
+      nextDefineUri ||
+      ('document' in self ? document.currentScript.src : '') ||
+      location.href;
     if (registry[uri]) {
       // Module is already loading or loaded.
       return;
     }
-    let exports = {};
+    const exports = {};
     const require = depUri => singleRequire(depUri, uri);
     const specialDeps = {
       module: { uri },
       exports,
       require
     };
-    registry[uri] = Promise.all(depsNames.map(
-      depName => specialDeps[depName] || require(depName)
-    )).then(deps => {
+    registry[uri] = Promise.all(
+      depsNames.map(depName => specialDeps[depName] || require(depName))
+    ).then(deps => {
       factory(...deps);
       return exports;
     });
   };
 }
-define(['./workbox-5357ef54'], (function (workbox) { 'use strict';
+define(['./workbox-5357ef54'], function (workbox) {
+  'use strict';
 
   self.skipWaiting();
   workbox.clientsClaim();
@@ -77,16 +79,23 @@ define(['./workbox-5357ef54'], (function (workbox) { 'use strict';
    * requests for URLs in the manifest.
    * See https://goo.gl/S9QRab
    */
-  workbox.precacheAndRoute([{
-    "url": "registerSW.js",
-    "revision": "3ca0b8505b4bec776b69afdba2768812"
-  }, {
-    "url": "index.html",
-    "revision": "0.usf6gnl94f"
-  }], {});
+  workbox.precacheAndRoute(
+    [
+      {
+        url: 'registerSW.js',
+        revision: '3ca0b8505b4bec776b69afdba2768812'
+      },
+      {
+        url: 'index.html',
+        revision: '0.dm3q4j1upco'
+      }
+    ],
+    {}
+  );
   workbox.cleanupOutdatedCaches();
-  workbox.registerRoute(new workbox.NavigationRoute(workbox.createHandlerBoundToURL("index.html"), {
-    allowlist: [/^\/$/]
-  }));
-
-}));
+  workbox.registerRoute(
+    new workbox.NavigationRoute(workbox.createHandlerBoundToURL('index.html'), {
+      allowlist: [/^\/$/]
+    })
+  );
+});

+ 4 - 1
src/components/card-preview/song-modal/index.module.less

@@ -90,6 +90,7 @@
 
   .actionWrap {
     display: flex;
+    align-items: center;
   }
 
   .actionBtn {
@@ -112,6 +113,8 @@
     height: 29px;
     background-color: transparent;
     cursor: pointer;
+    margin-left: 22px;
+    margin-right: 10px;
 
     &>img {
       width: 100%;
@@ -122,7 +125,7 @@
 
 .slider {
   width: 100%;
-  padding: 0 20px 0 12px;
+  padding: 0 8px 0 12px;
 
   :global {
 

+ 16 - 16
src/components/card-preview/song-modal/index.tsx

@@ -187,19 +187,9 @@ export default defineComponent({
                   <img class={styles.playIcon} src={iconpause} />
                 )}
               </button>
-            </div>
-            <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>
+              <button class={styles.iconReplay} onClick={onReplay}>
+                <img src={iconReplay} />
+              </button>
             </div>
           </div>
 
@@ -218,10 +208,20 @@ export default defineComponent({
           </div>
 
           <div class={styles.actions}>
+            <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>
             <div class={styles.actionWrap}>
-              <button class={styles.iconReplay} onClick={onReplay}>
-                <img src={iconReplay} />
-              </button>
               {props.isDownload && (
                 <button
                   class={styles.iconReplay}

+ 15 - 14
src/components/card-preview/video-modal/index.module.less

@@ -23,11 +23,12 @@
       display: flex;
       justify-content: space-between;
       color: #fff;
-      padding: 4px 12px 4px;
+      padding: 4px 0 4px 12px;
       font-size: max(24px, 14Px);
       font-weight: 600;
       line-height: 33px;
-      min-width: 150px;
+      // min-width: 150px;
+      flex-shrink: 0;
 
       .line {
         font-size: 20px;
@@ -35,9 +36,7 @@
 
       :global {
         .plyr__time {
-
           font-size: max(22px, 12Px);
-
         }
 
         .plyr__time+.plyr__time:before {
@@ -55,6 +54,7 @@
     color: #fff;
     font-size: 12px;
     align-items: center;
+    flex-shrink: 0;
 
     .actionWrap {
       display: flex;
@@ -77,8 +77,9 @@
 
 
     .actionBtnSpeed {
-      width: 40px;
-      height: 40px;
+      position: relative;
+      width: 32px;
+      height: 32px;
       background-color: transparent;
       cursor: pointer;
 
@@ -90,8 +91,8 @@
 
 
     .iconReplay {
-      width: 40px;
-      height: 40px;
+      width: 32px;
+      height: 32px;
       background-color: transparent;
       cursor: pointer;
       margin: 0 22px;
@@ -105,7 +106,7 @@
     .iconDownload {
       width: 40px;
       height: 40px;
-      margin-left: 5px;
+      margin-left: 12px;
       background-color: transparent;
       cursor: pointer;
 
@@ -141,13 +142,13 @@
 .sliderPopup {
   position: absolute;
   z-index: 9999;
-  left: 144px;
-  bottom: 82px;
+  left: -13px;
+  bottom: 35px;
   display: flex;
   align-items: center;
   flex-direction: column;
   height: 252px;
-  width: 59Px;
+  width: 59px;
   padding: 12Px 0 15Px;
   background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAI4AAAJcCAMAAAAYSmw3AAAAaVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnbPKNAAAAI3RSTlOzAAUJiqaplqF6V0c4nSevpJN+GAZtX1EQGpqDPTQVc2QhqyTybJ0AAAKuSURBVHja7NRJVsJQAAXRRxMg9BwgGWX/2xT0KCKII5M/uHcFNaqMntm25+mm2uVf7KrN9NxuR8885ozX9Sw9mNXr8Z85p2WV3lTL0+uc1SK9Wqxe5HTz9G7e/ZbTZBDN05xJnYHUk8ec4yGDORx/5hz3GdD+eJ8zOWRQh8ldTp2B1d9zmgyuueV0KUD3lTNPAeafOasUYfWRc1qkCIvTe84yhVhec8ZVClGNLznrFGM9yvAHvKkvObMUYzbKNgXZpk1B2pxTkHOmKcg0mxRkk2ImeFVll4IUFQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAG3twIAAAAAAA5P/aCKqqqqqqqqqqqqqqqtJ+nSQ3CgVRFH2XjwCjHnWoCTXe/yJrUlEljCz7R9riD/Ks4E7yRaRzzjnnnHPOOeecc845zZWQuUZKyEhTJWSqXAnJtVFCNtopITvNlJCZKJSMAvGmZLwhJkrGBJElM4SjDEGtRNQgCJWSUAUQMFYSxoAASiWgBBCQxnFN/uWw1eC2/M+h0cAa7nNCqUGVoZPDaqEBLVZ0c9iXGky552MOodFAmkA/B64axBUe5jA56OUOE+6IjvFCL7UY0yG6Ql3oZYo68DwH1qfmXS/w3pzWfCQeyGb1Ja8K/ZKiyi/1LOMB8UTWFzcH4+wBnhCRsmNEDbFErPW3e3ZEE9FCrm+p6THkWHu29BlyjD1XIthyCEt9YUMEaw7tFz0XIthzaMvnz3YUew7tQZ86ZsSx53Ce6hP5mqcsOfE9eSCePYdVpQeWhhqEwX6hnrLFQFjcej2HFgthchupY3rGRNjcCt2pVtgIo1lxV7PHSFjtl/orP2Ml7E7HuTRvTtiJH9G2/AiRlD84lRqqt/0KYQAAAABJRU5ErkJggg==') no-repeat top center;
   background-size: contain;
@@ -174,13 +175,13 @@
 
   .sliderPoint {
     background: #FFFFFF;
-    box-shadow: 0px 2px 4px 0px rgba(102, 102, 102, 0.77);
+    box-shadow: 0 2px 4px 0px rgba(102, 102, 102, 0.77);
     border-radius: 14px;
     font-size: 14Px;
     font-weight: 500;
     height: 22Px;
     color: #198CFE;
-    min-width: 40Px;
+    min-width: 40px;
     text-align: center;
     vertical-align: text-bottom;
 

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

@@ -199,6 +199,65 @@ export default defineComponent({
                   videoFroms.speedControl = !videoFroms.speedControl;
                 }}>
                 <img src={iconSpeed} />
+
+                <div
+                  style={{
+                    display: videoFroms.speedControl ? 'block' : 'none'
+                  }}>
+                  <div
+                    class={styles.sliderPopup}
+                    onClick={(e: Event) => {
+                      e.stopPropagation();
+                    }}>
+                    <i
+                      class={styles.iconAdd}
+                      onClick={() => {
+                        if (videoFroms.defaultSpeed >= 1.5) {
+                          return;
+                        }
+
+                        if (videoItem.value) {
+                          videoFroms.defaultSpeed =
+                            (videoFroms.defaultSpeed * 10 + 1) / 10;
+                          videoItem.value.playbackRate(videoFroms.defaultSpeed);
+                        }
+                      }}></i>
+                    <NSlider
+                      value={videoFroms.defaultSpeed}
+                      step={0.1}
+                      max={1.5}
+                      min={0.5}
+                      vertical
+                      tooltip={false}
+                      onUpdate:value={(val: number) => {
+                        videoFroms.defaultSpeed = val;
+                        if (videoItem.value) {
+                          videoItem.value.playbackRate(videoFroms.defaultSpeed);
+                        }
+                      }}>
+                      {{
+                        thumb: () => (
+                          <div class={styles.sliderPoint}>
+                            {videoFroms.defaultSpeed}
+                            <span>x</span>
+                          </div>
+                        )
+                      }}
+                    </NSlider>
+                    <i
+                      class={[styles.iconCut]}
+                      onClick={() => {
+                        if (videoFroms.defaultSpeed <= 0.5) {
+                          return;
+                        }
+                        if (videoItem.value) {
+                          videoFroms.defaultSpeed =
+                            (videoFroms.defaultSpeed * 10 - 1) / 10;
+                          videoItem.value.playbackRate(videoFroms.defaultSpeed);
+                        }
+                      }}></i>
+                  </div>
+                </div>
               </div>
             </div>
           </div>
@@ -241,65 +300,6 @@ export default defineComponent({
             </div>
           </div>
         </div>
-
-        <div
-          style={{
-            display: videoFroms.speedControl ? 'block' : 'none'
-          }}>
-          <div
-            class={styles.sliderPopup}
-            onClick={(e: Event) => {
-              e.stopPropagation();
-            }}>
-            <i
-              class={styles.iconAdd}
-              onClick={() => {
-                if (videoFroms.defaultSpeed >= 1.5) {
-                  return;
-                }
-
-                if (videoItem.value) {
-                  videoFroms.defaultSpeed =
-                    (videoFroms.defaultSpeed * 10 + 1) / 10;
-                  videoItem.value.playbackRate(videoFroms.defaultSpeed);
-                }
-              }}></i>
-            <NSlider
-              value={videoFroms.defaultSpeed}
-              step={0.1}
-              max={1.5}
-              min={0.6}
-              vertical
-              tooltip={false}
-              onUpdate:value={(val: number) => {
-                videoFroms.defaultSpeed = val;
-                if (videoItem.value) {
-                  videoItem.value.playbackRate(videoFroms.defaultSpeed);
-                }
-              }}>
-              {{
-                thumb: () => (
-                  <div class={styles.sliderPoint}>
-                    {videoFroms.defaultSpeed}
-                    <span>x</span>
-                  </div>
-                )
-              }}
-            </NSlider>
-            <i
-              class={[styles.iconCut]}
-              onClick={() => {
-                if (videoFroms.defaultSpeed <= 0.6) {
-                  return;
-                }
-                if (videoItem.value) {
-                  videoFroms.defaultSpeed =
-                    (videoFroms.defaultSpeed * 10 - 1) / 10;
-                  videoItem.value.playbackRate(videoFroms.defaultSpeed);
-                }
-              }}></i>
-          </div>
-        </div>
       </div>
     );
   }

+ 58 - 23
src/views/attend-class/component/audio-pay.tsx

@@ -1,4 +1,11 @@
-import { defineComponent, reactive, ref, nextTick } from 'vue';
+import {
+  defineComponent,
+  reactive,
+  ref,
+  nextTick,
+  onMounted,
+  watch
+} from 'vue';
 import styles from './audio.module.less';
 import iconplay from '../image/icon-pause.png';
 import iconpause from '../image/icon-play.png';
@@ -16,6 +23,10 @@ export default defineComponent({
         return {};
       }
     },
+    activeStatus: {
+      type: Boolean,
+      default: false
+    },
     isEmtry: {
       type: Boolean,
       default: false
@@ -30,7 +41,8 @@ export default defineComponent({
       durationNum: 0,
       duration: '00:00',
       showBar: true,
-      afterMa3: true
+      afterMa3: true,
+      count: 0
     });
     const canvas: any = ref();
     const audio: any = ref();
@@ -39,15 +51,15 @@ export default defineComponent({
     // 切换音频播放
     const onToggleAudio = (e?: any) => {
       e?.stopPropagation();
+      // console.log(audio.value.paused, 'audio.value.paused');
       if (audio.value.paused) {
-        onInit(audio.value, canvas.value);
         audio.value.play();
         audioForms.afterMa3 = false;
       } else {
         audio.value?.pause();
       }
       audioForms.paused = audio.value?.paused;
-      e.target?.focus();
+      e?.target?.focus();
       emit('togglePlay', audioForms.paused);
     };
 
@@ -116,6 +128,25 @@ export default defineComponent({
       });
       vudio1.dance();
     });
+
+    watch(
+      () => props.activeStatus,
+      (val: any) => {
+        // console.log(val, 'val');
+        audioForms.count = 0;
+        if (val) {
+          vudio = null;
+          onToggleAudio();
+        } else {
+          audio.value.pause();
+        }
+      }
+    );
+
+    // onMounted(() => {
+    //   console.log(props.item, 'eeeee');
+    // });
+
     expose({
       toggleHideControl
     });
@@ -136,6 +167,11 @@ export default defineComponent({
                 Math.round(audio.value?.currentTime || 0)
               );
               audioForms.currentTimeNum = audio.value?.currentTime || 0;
+
+              if (audioForms.count <= 1) {
+                audioForms.count += 1;
+                onInit(audio.value, canvas.value);
+              }
             }}
             onLoadedmetadata={() => {
               audioForms.duration = timeFormat(
@@ -143,8 +179,9 @@ export default defineComponent({
               );
               audioForms.durationNum = audio.value?.duration;
 
-              if (props.item.autoPlay && audio.value) {
-                audio.value.play();
+              if (props.item.autoPlay && audio.value && props.activeStatus) {
+                // audio.value.play();
+                onToggleAudio();
               }
               if (audio.value) {
                 audio.value.stop = () => {
@@ -191,19 +228,9 @@ export default defineComponent({
                   <img class={styles.playIcon} src={iconpause} />
                 )}
               </div>
-            </div>
-            <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>
+              <button class={styles.iconReplay} onClick={onReplay}>
+                <img src={iconReplay} />
+              </button>
             </div>
           </div>
 
@@ -222,10 +249,18 @@ export default defineComponent({
           </div>
 
           <div class={styles.actions}>
-            <div class={styles.actionWrap}>
-              <button class={styles.iconReplay} onClick={onReplay}>
-                <img src={iconReplay} />
-              </button>
+            <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>
           </div>
         </div>

+ 4 - 1
src/views/attend-class/component/audio.module.less

@@ -96,6 +96,7 @@
 
   .actionWrap {
     display: flex;
+    align-items: center;
   }
 
   .actionBtn {
@@ -118,6 +119,8 @@
     height: 39px;
     background-color: transparent;
     cursor: pointer;
+    margin-left: 22px;
+    margin-right: 10px;
 
     &>img {
       width: 100%;
@@ -128,7 +131,7 @@
 
 .slider {
   width: 100%;
-  padding: 0 20px 0 12px;
+  padding: 0 8px 0 12px;
 
   :global {
 

+ 97 - 64
src/views/attend-class/component/video-play.tsx

@@ -115,6 +115,27 @@ export default defineComponent({
       emit('togglePlay', videoFroms.paused);
     };
 
+    const videoTimer = null as any;
+    let videoTimerErrorCount = 0;
+    const handlePlayVideo = () => {
+      if (videoTimerErrorCount > 5) {
+        return;
+      }
+      clearTimeout(videoTimer);
+      nextTick(() => {
+        videoItem.value?.play().catch((err: any) => {
+          // console.log('🚀 ~ err:', err)
+          // videoTimer = setTimeout(() => {
+          //   if (err?.message?.includes('play()')) {
+          //     // emit('play');
+          //   }
+          //   handlePlayVideo();
+          // }, 1000);
+        });
+      });
+      videoTimerErrorCount++;
+    };
+
     const __init = () => {
       if (videoItem.value) {
         videoItem.value.poster(props.item.coverImg); // 封面
@@ -133,6 +154,15 @@ export default defineComponent({
 
           emit('canplay');
           emit('loadedmetadata', videoItem.value);
+
+          if (item.value.autoPlay && videoItem.value) {
+            // videoItem.value?.play()
+            nextTick(() => {
+              videoTimerErrorCount = 0;
+              videoItem.value.currentTime(0);
+              nextTick(handlePlayVideo);
+            });
+          }
         });
 
         // 视频开始播放
@@ -215,13 +245,16 @@ export default defineComponent({
     watch(
       () => props.item,
       () => {
+        // console.log(item.value, 'value----');
         videoItem.value.pause();
         videoItem.value.currentTime(0);
-        // videoItem.value.poster(props.item.coverImg); // 封面
-        // videoItem.value.src(item.value.content); // url 播放地址
-        __init();
+        if (item.value?.id) {
+          // videoItem.value.poster(props.item.coverImg); // 封面
+          // videoItem.value.src(item.value.content); // url 播放地址
+          __init();
 
-        videoFroms.paused = true;
+          videoFroms.paused = true;
+        }
       }
     );
     watch(
@@ -283,6 +316,66 @@ export default defineComponent({
 
               <div class={styles.actionBtnSpeed} id={speedBtnId}>
                 <img src={iconSpeed} />
+
+                <div
+                  style={{
+                    display: videoFroms.speedControl ? 'block' : 'none'
+                  }}>
+                  <div
+                    class={styles.sliderPopup}
+                    onClick={(e: Event) => {
+                      e.stopPropagation();
+                    }}>
+                    <i
+                      class={styles.iconAdd}
+                      onClick={() => {
+                        if (videoFroms.defaultSpeed >= 1.5) {
+                          return;
+                        }
+
+                        if (videoItem.value) {
+                          videoFroms.defaultSpeed =
+                            (videoFroms.defaultSpeed * 10 + 1) / 10;
+                          videoItem.value.playbackRate(videoFroms.defaultSpeed);
+                        }
+                      }}></i>
+                    <NSlider
+                      value={videoFroms.defaultSpeed}
+                      step={0.1}
+                      max={1.5}
+                      min={0.5}
+                      vertical
+                      tooltip={false}
+                      onUpdate:value={(val: number) => {
+                        videoFroms.defaultSpeed = val;
+
+                        if (videoItem.value) {
+                          videoItem.value.playbackRate(videoFroms.defaultSpeed);
+                        }
+                      }}>
+                      {{
+                        thumb: () => (
+                          <div class={styles.sliderPoint}>
+                            {videoFroms.defaultSpeed}
+                            <span>x</span>
+                          </div>
+                        )
+                      }}
+                    </NSlider>
+                    <i
+                      class={[styles.iconCut]}
+                      onClick={() => {
+                        if (videoFroms.defaultSpeed <= 0.5) {
+                          return;
+                        }
+                        if (videoItem.value) {
+                          videoFroms.defaultSpeed =
+                            (videoFroms.defaultSpeed * 10 - 1) / 10;
+                          videoItem.value.playbackRate(videoFroms.defaultSpeed);
+                        }
+                      }}></i>
+                  </div>
+                </div>
               </div>
             </div>
           </div>
@@ -320,66 +413,6 @@ export default defineComponent({
             </div>
           </div>
         </div>
-
-        <div
-          style={{
-            display: videoFroms.speedControl ? 'block' : 'none'
-          }}>
-          <div
-            class={styles.sliderPopup}
-            onClick={(e: Event) => {
-              e.stopPropagation();
-            }}>
-            <i
-              class={styles.iconAdd}
-              onClick={() => {
-                if (videoFroms.defaultSpeed >= 1.5) {
-                  return;
-                }
-
-                if (videoItem.value) {
-                  videoFroms.defaultSpeed =
-                    (videoFroms.defaultSpeed * 10 + 1) / 10;
-                  videoItem.value.playbackRate(videoFroms.defaultSpeed);
-                }
-              }}></i>
-            <NSlider
-              value={videoFroms.defaultSpeed}
-              step={0.1}
-              max={1.5}
-              min={0.6}
-              vertical
-              tooltip={false}
-              onUpdate:value={(val: number) => {
-                videoFroms.defaultSpeed = val;
-
-                if (videoItem.value) {
-                  videoItem.value.playbackRate(videoFroms.defaultSpeed);
-                }
-              }}>
-              {{
-                thumb: () => (
-                  <div class={styles.sliderPoint}>
-                    {videoFroms.defaultSpeed}
-                    <span>x</span>
-                  </div>
-                )
-              }}
-            </NSlider>
-            <i
-              class={[styles.iconCut]}
-              onClick={() => {
-                if (videoFroms.defaultSpeed <= 0.6) {
-                  return;
-                }
-                if (videoItem.value) {
-                  videoFroms.defaultSpeed =
-                    (videoFroms.defaultSpeed * 10 - 1) / 10;
-                  videoItem.value.playbackRate(videoFroms.defaultSpeed);
-                }
-              }}></i>
-          </div>
-        </div>
       </div>
     );
   }

+ 6 - 5
src/views/attend-class/component/video.module.less

@@ -53,7 +53,7 @@
       }
 
       .line {
-        font-size: 12px;
+        font-size: 20px;
       }
 
       :global {
@@ -94,6 +94,7 @@
     }
 
     .actionBtnSpeed {
+      position: relative;
       width: 40px;
       height: 40px;
       background-color: transparent;
@@ -140,13 +141,13 @@
 .sliderPopup {
   position: absolute;
   z-index: 9999;
-  left: 184px;
-  bottom: 90px;
+  left: -10px;
+  bottom: 55px;
   display: flex;
   align-items: center;
   flex-direction: column;
   height: 252px;
-  width: 59Px;
+  width: 59px;
   padding: 12Px 0 15Px;
   background: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAI4AAAJcCAMAAAAYSmw3AAAAaVBMVEUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAnbPKNAAAAI3RSTlOzAAUJiqaplqF6V0c4nSevpJN+GAZtX1EQGpqDPTQVc2QhqyTybJ0AAAKuSURBVHja7NRJVsJQAAXRRxMg9BwgGWX/2xT0KCKII5M/uHcFNaqMntm25+mm2uVf7KrN9NxuR8885ozX9Sw9mNXr8Z85p2WV3lTL0+uc1SK9Wqxe5HTz9G7e/ZbTZBDN05xJnYHUk8ec4yGDORx/5hz3GdD+eJ8zOWRQh8ldTp2B1d9zmgyuueV0KUD3lTNPAeafOasUYfWRc1qkCIvTe84yhVhec8ZVClGNLznrFGM9yvAHvKkvObMUYzbKNgXZpk1B2pxTkHOmKcg0mxRkk2ImeFVll4IUFQMAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAG3twIAAAAAAA5P/aCKqqqqqqqqqqqqqqqtJ+nSQ3CgVRFH2XjwCjHnWoCTXe/yJrUlEljCz7R9riD/Ks4E7yRaRzzjnnnHPOOeecc845zZWQuUZKyEhTJWSqXAnJtVFCNtopITvNlJCZKJSMAvGmZLwhJkrGBJElM4SjDEGtRNQgCJWSUAUQMFYSxoAASiWgBBCQxnFN/uWw1eC2/M+h0cAa7nNCqUGVoZPDaqEBLVZ0c9iXGky552MOodFAmkA/B64axBUe5jA56OUOE+6IjvFCL7UY0yG6Ql3oZYo68DwH1qfmXS/w3pzWfCQeyGb1Ja8K/ZKiyi/1LOMB8UTWFzcH4+wBnhCRsmNEDbFErPW3e3ZEE9FCrm+p6THkWHu29BlyjD1XIthyCEt9YUMEaw7tFz0XIthzaMvnz3YUew7tQZ86ZsSx53Ce6hP5mqcsOfE9eSCePYdVpQeWhhqEwX6hnrLFQFjcej2HFgthchupY3rGRNjcCt2pVtgIo1lxV7PHSFjtl/orP2Ml7E7HuTRvTtiJH9G2/AiRlD84lRqqt/0KYQAAAABJRU5ErkJggg==') no-repeat top center;
   background-size: contain;
@@ -179,7 +180,7 @@
     font-weight: 500;
     height: 22Px;
     color: #198CFE;
-    min-width: 40Px;
+    min-width: 40px;
     text-align: center;
     vertical-align: text-bottom;
 

BIN
src/views/attend-class/image/icon-speed.png


+ 11 - 9
src/views/attend-class/index.tsx

@@ -205,7 +205,7 @@ export default defineComponent({
       animationState: 'start' as 'start' | 'end'
     });
     const activeData = reactive({
-      // isAutoPlay: false, // 是否自动播放
+      isAutoPlay: false, // 是否自动播放
       nowTime: 0,
       model: true, // 遮罩
       isAnimation: true, // 是否动画
@@ -228,6 +228,7 @@ export default defineComponent({
         data.teacherChapterName = res.data.name || '';
         // 布置的作业编号
         data.lessonPreTrainingId = res.data.lessonPreTrainingId;
+        // activeData.isAutoPlay = res.data.autoPlay || false; // 自动播放
         const tempRows = res.data.chapterKnowledgeList || [];
         const temp: any = [];
         const allItem: any = [];
@@ -266,7 +267,7 @@ export default defineComponent({
             iframeRef: null,
             videoEle: null,
             audioEle: null,
-            autoPlay: false, //加载完成是否自动播放
+            autoPlay: res.data.autoPlay || false, //加载完成是否自动播放
             isprepare: false, // 视频是否加载完成
             isRender: false // 是否渲染了
           };
@@ -463,7 +464,7 @@ export default defineComponent({
 
     /**停止所有的播放 */
     const handleStop = (isStop = true) => {
-      console.log(isStop, 'stop');
+      // console.log(isStop, 'stop');
       for (let i = 0; i < data.itemList.length; i++) {
         const activeItem = data.itemList[i];
         if (activeItem.type === 'VIDEO' && activeItem.videoEle) {
@@ -496,7 +497,7 @@ export default defineComponent({
           activeItem.iframeRef?.handleChangeAudio('pause');
         }
 
-        console.log(activeItem.type, 'activeItem.type');
+        // console.log(activeItem.type, 'activeItem.type');
         if (activeItem.type === 'RHYTHM') {
           activeItem.iframeRef?.contentWindow?.postMessage(
             { api: 'setPlayState', data: false },
@@ -1585,13 +1586,14 @@ export default defineComponent({
                       ) : m.type === 'SONG' ? (
                         <AudioPay
                           item={m}
+                          activeStatus={popupData.activeIndex === mIndex}
                           ref={(v: any) => (data.audioRefs[mIndex] = v)}
                           onLoadedmetadata={(audioItem: any) => {
                             m.audioEle = audioItem;
                             m.isprepare = true;
                           }}
                           onTogglePlay={(paused: boolean) => {
-                            m.autoPlay = false;
+                            // m.autoPlay = false;
                             if (paused || popupData.open) {
                               clearTimeout(activeData.timer);
                             } else {
@@ -1599,10 +1601,10 @@ export default defineComponent({
                             }
                           }}
                           onEnded={() => {
-                            const _index = popupData.activeIndex + 1;
-                            if (_index < data.itemList.length) {
-                              handleSwipeChange(_index);
-                            }
+                            // const _index = popupData.activeIndex + 1;
+                            // if (_index < data.itemList.length) {
+                            //   handleSwipeChange(_index);
+                            // }
                           }}
                           onReset={() => {
                             if (!m.audioEle?.paused) {

+ 1 - 1
src/views/natural-resources/components/my-resources/index.module.less

@@ -246,7 +246,7 @@
     padding: 20px 40px 0;
 
     p {
-      font-size: max(18px, 14px);
+      font-size: max(18px, 14Px);
       color: #777777;
       line-height: 30px;
       text-align: center;

BIN
src/views/prepare-lessons/components/directory-main/images/arrow-active.png


BIN
src/views/prepare-lessons/components/directory-main/images/arrow-default.png


BIN
src/views/prepare-lessons/components/directory-main/images/icon-d-active.png


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


+ 137 - 4
src/views/prepare-lessons/components/directory-main/index.module.less

@@ -11,7 +11,7 @@
   .scrollBar {
     margin-top: 12px;
     padding: 0 20px;
-    max-height: calc(100% - 49px - 12px);
+    max-height: calc(100% - 152px - 12px);
   }
 }
 
@@ -40,6 +40,132 @@
   }
 }
 
+.select-directory-info {
+  display: flex;
+  align-items: center;
+  padding: 0 0 32px 0;
+  margin: 0 24px;
+  border-bottom: 1px solid #F2F2F2;
+
+  .itemImg {
+    position: relative;
+    width: 85px;
+    height: 120px;
+    // margin: auto;
+    background-color: #EDEFF2;
+    background-image: url('./images/icon_default.svg');
+    background-repeat: no-repeat;
+    background-position: center center;
+    margin-right: 18px;
+    flex-shrink: 0;
+    transition: transform .2s ease;
+    cursor: pointer;
+
+    &:hover {
+      transform: scale(1.02);
+      transition: transform .2s ease;
+    }
+
+    &::before {
+      content: '';
+      position: absolute;
+      top: 4px;
+      right: -4px;
+      width: 4px;
+      height: calc(100% - 8px);
+      background-color: #C5C5C5;
+      z-index: 1;
+    }
+
+    &::after {
+      content: '';
+      position: absolute;
+      top: 2px;
+      right: -2px;
+      width: 4px;
+      height: calc(100% - 4px);
+      background-color: #E7E7E7;
+      z-index: 2;
+    }
+
+    .itemBg {
+      position: absolute;
+      top: 0;
+      left: 0;
+      width: 100%;
+      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-size: 50% 100%, 50% 100%;
+      background-position: 0% top, 9% top;
+    }
+
+    :global {
+      .n-image {
+        position: relative;
+        width: 100%;
+        height: 100%;
+        z-index: 3;
+      }
+    }
+
+    img {
+      transition: opacity .3s;
+      opacity: 0;
+    }
+
+    img[data-loaded="true"] {
+      opacity: 1;
+    }
+
+  }
+
+  .itemContent {
+    h2 {
+      font-weight: 600;
+      font-size: max(18px, 14Px);
+      color: #131415;
+      line-height: 25px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      max-width: 200px;
+    }
+
+    .subjects {
+      font-size: max(14px, 11Px);
+      color: #777777;
+      line-height: 20px;
+      padding: 11px 0 15px;
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      max-width: 200px;
+    }
+
+    .changeDir {
+      background: #E8F4FF;
+      border-radius: 18px;
+      font-weight: 500;
+      font-size: max(14px, 11Px);
+      color: #0378EC;
+      line-height: 20px;
+      padding: 4px 12px;
+      display: inline-flex;
+      align-items: center;
+      cursor: pointer;
+
+      svg {
+        width: max(11px, 9Px);
+        height: max(10px, 8Px);
+        margin-right: 4px;
+        flex-shrink: 0;
+      }
+    }
+  }
+}
+
 .treeParent {
   transition: height 1s ease-in-out;
 }
@@ -57,9 +183,15 @@
   cursor: pointer;
   border-radius: 10px;
   font-size: max(17px, 12Px);
+  margin-bottom: 8px;
+
+  &.childItem:hover {
+
+    // background: #E8F4FF;
 
-  &:hover {
-    background: #F5F6FA;
+    .title {
+      color: var(--n-color);
+    }
   }
 
   .title {
@@ -114,13 +246,14 @@
     padding-left: 30px;
     font-size: max(15px, 12Px);
 
+
     .title {
       color: #131415;
     }
   }
 
   &.childSelect {
-    background: #F5F6FA;
+    background: #E8F4FF;
 
     .title {
       color: var(--n-color);

+ 107 - 38
src/views/prepare-lessons/components/directory-main/index.tsx

@@ -1,6 +1,6 @@
-import { defineComponent, onMounted, reactive, ref } from 'vue';
+import { computed, defineComponent, onMounted, reactive, ref } from 'vue';
 import styles from './index.module.less';
-import { NIcon, NSpin, NScrollbar, NModal } from 'naive-ui';
+import { NIcon, NSpin, NScrollbar, NModal, NImage } from 'naive-ui';
 import {
   lessonCoursewareDetail,
   lessonCoursewarePage,
@@ -172,6 +172,14 @@ export default defineComponent({
       setLastUseCoursewareId(item.id);
     };
 
+    const formatSubjectNames = computed(() => {
+      const names = prepareStore.getBaseCourseware.subjectNames;
+      if (!names) {
+        return '';
+      }
+      return names.split(',').join('、');
+    });
+
     onMounted(async () => {
       show.value = true;
       await getLessonCourseware();
@@ -182,47 +190,108 @@ export default defineComponent({
       eventGlobal.on('onChangeClass', async (item: any) => {
         onChangeClass(item);
       });
+
+      console.log(
+        prepareStore.getBaseCourseware,
+        'prepareStore.getBaseCourseware'
+      );
     });
     return () => (
       <div class={styles.directoryList}>
-        {forms.showSelectBookStatus && (
-          <div
-            id="lessons-0"
-            class={styles['select-directory']}
-            onClick={() => (forms.coursewareStatus = true)}>
-            <span
-              class={['cr-ellipsis']}
-              title={prepareStore.getBaseCourseware.name}>
-              {prepareStore.getBaseCourseware.name || '请选择教材'}
-            </span>
-            <NIcon class={styles.iconArrow}>
-              <svg
-                width="11px"
-                height="15px"
-                viewBox="0 0 11 15"
-                version="1.1"
-                xmlns="http://www.w3.org/2000/svg">
-                <g
-                  stroke="none"
-                  stroke-width="1"
-                  fill="none"
-                  fill-rule="evenodd"
-                  opacity="0.699999988">
+        {forms.showSelectBookStatus &&
+          (prepareStore.getBaseCourseware.id ? (
+            <div id="lessons-0" class={styles['select-directory-info']}>
+              <div
+                class={styles.itemImg}
+                onClick={() => (forms.coursewareStatus = true)}>
+                <NImage
+                  objectFit="cover"
+                  src={prepareStore.getBaseCourseware.coverImg}
+                  lazy
+                  previewDisabled={true}
+                  onLoad={e => {
+                    (e.target as any).dataset.loaded = 'true';
+                  }}
+                />
+              </div>
+              <div class={styles.itemContent}>
+                <h2>{prepareStore.getBaseCourseware.name}</h2>
+                <div class={styles.subjects}>{formatSubjectNames.value}</div>
+                <div
+                  class={styles.changeDir}
+                  onClick={() => (forms.coursewareStatus = true)}>
+                  <svg
+                    width="11px"
+                    height="10px"
+                    viewBox="0 0 11 10"
+                    version="1.1"
+                    xmlns="http://www.w3.org/2000/svg">
+                    <title>切片</title>
+                    <g
+                      stroke="none"
+                      stroke-width="1"
+                      fill="none"
+                      fill-rule="evenodd">
+                      <g
+                        transform="translate(-279.000000, -210.000000)"
+                        fill="#0378EC"
+                        fill-rule="nonzero">
+                        <g transform="translate(132.000000, 96.000000)">
+                          <g transform="translate(32.000000, 24.000000)">
+                            <g transform="translate(103.000000, 10.000000)">
+                              <g transform="translate(0.000000, 71.000000)">
+                                <g transform="translate(12.000000, 9.000000)">
+                                  <path d="M10.4116565,3.89985699 C10.6551462,3.89985699 10.8747497,3.75140792 10.9680437,3.52360884 C11.0613377,3.29606287 11.0096883,3.03384082 10.8376072,2.85944797 L8.08018279,0.0692888872 C7.98888976,-0.0230962957 7.8410701,-0.0230962957 7.74977708,0.0692888872 L7.22840639,0.59689687 C7.13711336,0.689282053 7.13711336,0.838996672 7.22840639,0.931255299 L8.95772133,2.68113191 L0.230858792,2.68113191 C0.103423738,2.68113191 0,2.78566638 0,2.91475252 L0,3.66636293 C0,3.79532253 0.10329868,3.89998355 0.230858792,3.89998355 L10.4116565,3.89998355 L10.4116565,3.89985699 Z M10.877501,6.10001645 L0.699579677,6.10001645 C0.456089932,6.10001645 0.236486444,6.24846552 0.143192479,6.4762646 C0.0498985147,6.70381057 0.101547854,6.96603263 0.273628948,7.14042548 L3.03105338,9.93071111 C3.12234641,10.0230963 3.27016607,10.0230963 3.36145909,9.93071111 L3.88282978,9.40310313 C3.97412281,9.31071795 3.97412281,9.16100333 3.88282978,9.0687447 L2.15351484,7.31874154 L10.877501,7.31874154 C11.0065618,7.31874154 11.1111111,7.21281496 11.1111111,7.08233671 L11.1111111,6.33654783 C11.1111111,6.20594302 11.0065618,6.10001645 10.877501,6.10001645 Z"></path>
+                                </g>
+                              </g>
+                            </g>
+                          </g>
+                        </g>
+                      </g>
+                    </g>
+                  </svg>
+                  <span>切换教材</span>
+                </div>
+              </div>
+            </div>
+          ) : (
+            <div
+              id="lessons-0"
+              class={styles['select-directory']}
+              onClick={() => (forms.coursewareStatus = true)}>
+              <span
+                class={['cr-ellipsis']}
+                title={prepareStore.getBaseCourseware.name}>
+                {prepareStore.getBaseCourseware.name || '请选择教材'}
+              </span>
+              <NIcon class={styles.iconArrow}>
+                <svg
+                  width="11px"
+                  height="15px"
+                  viewBox="0 0 11 15"
+                  version="1.1"
+                  xmlns="http://www.w3.org/2000/svg">
                   <g
-                    transform="translate(-445.000000, -137.000000)"
-                    fill="#131415">
-                    <g transform="translate(152.000000, 120.000000)">
-                      <path
-                        d="M299.326227,20.2118001 L304.934089,28.4366632 C305.245211,28.8929759 305.127511,29.515105 304.671198,29.8262273 C304.505147,29.9394437 304.308836,30 304.107861,30 L292.892139,30 C292.339854,30 291.892139,29.5522847 291.892139,29 C291.892139,28.7990254 291.952695,28.6027139 292.065911,28.4366632 L297.673773,20.2118001 C297.984895,19.7554873 298.607024,19.6377872 299.063337,19.9489096 C299.16663,20.0193364 299.255801,20.1085074 299.326227,20.2118001 Z"
-                        id="三角形"
-                        transform="translate(298.500000, 24.500000) rotate(-270.000000) translate(-298.500000, -24.500000) "></path>
+                    stroke="none"
+                    stroke-width="1"
+                    fill="none"
+                    fill-rule="evenodd"
+                    opacity="0.699999988">
+                    <g
+                      transform="translate(-445.000000, -137.000000)"
+                      fill="#131415">
+                      <g transform="translate(152.000000, 120.000000)">
+                        <path
+                          d="M299.326227,20.2118001 L304.934089,28.4366632 C305.245211,28.8929759 305.127511,29.515105 304.671198,29.8262273 C304.505147,29.9394437 304.308836,30 304.107861,30 L292.892139,30 C292.339854,30 291.892139,29.5522847 291.892139,29 C291.892139,28.7990254 291.952695,28.6027139 292.065911,28.4366632 L297.673773,20.2118001 C297.984895,19.7554873 298.607024,19.6377872 299.063337,19.9489096 C299.16663,20.0193364 299.255801,20.1085074 299.326227,20.2118001 Z"
+                          id="三角形"
+                          transform="translate(298.500000, 24.500000) rotate(-270.000000) translate(-298.500000, -24.500000) "></path>
+                      </g>
                     </g>
                   </g>
-                </g>
-              </svg>
-            </NIcon>
-          </div>
-        )}
+                </svg>
+              </NIcon>
+            </div>
+          ))}
 
         <NScrollbar class={styles.scrollBar}>
           <NSpin show={show.value}>
@@ -307,7 +376,7 @@ export default defineComponent({
           preset="card"
           showIcon={false}
           class={['modalTitle background', styles.coursewareModal]}
-          title={'选择教材'}
+          title={'切换教材'}
           blockScroll={false}>
           <SelectLessonware
             onClose={() => (forms.coursewareStatus = false)}

+ 106 - 0
src/views/prepare-lessons/components/lesson-main/courseware-head/index.module.less

@@ -0,0 +1,106 @@
+.headerTitle {
+  display: flex;
+  align-items: center;
+  font-weight: 600;
+  font-size: max(18px, 14Px);
+  color: #000000;
+  line-height: 21px;
+  padding: 21px 0;
+  margin: 0 17px;
+  border-bottom: 1px solid #F0F0F0;
+
+  .iconBook {
+    width: 14Px;
+    height: 19Px;
+    margin-right: 5px;
+    flex-shrink: 0;
+    background: url('../../../images/icon-book.png') no-repeat center;
+    background-size: contain;
+    vertical-align: middle;
+    display: inline-block;
+  }
+
+  span {
+    flex: 1;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+    max-width: 290px;
+  }
+}
+
+.formContainer {
+  padding: 20px 17px;
+
+  .btnSubjectList {
+    :global {
+      .n-base-selection-tag-wrapper .n-tag {
+        font-size: max(14px, 12Px);
+      }
+    }
+  }
+
+  :global {
+
+    .n-input,
+    .n-base-selection {
+      --n-height: max(40px, 36Px) !important;
+      width: 100% !important;
+      font-size: 15px;
+      border-radius: 8px !important;
+    }
+
+    .n-base-selection-input__content {
+      font-size: max(15px, 13Px);
+    }
+
+    .n-switch {
+      --n-height: 20Px !important;
+      --n-width: 38Px !important;
+      --n-rail-height: 20Px !important;
+      --n-button-width-pressed: 16Px !important;
+      --n-button-height: 16Px !important;
+      --n-button-width: 16Px !important;
+      --n-rail-color: #CCCCCC !important;
+      --n-rail-color-active: #2089FF !important;
+    }
+  }
+
+  .btnItem {
+    display: flex;
+    align-items: center;
+    justify-content: space-between;
+    margin-bottom: 38px;
+
+    &.block {
+      flex-direction: column;
+      align-items: flex-start;
+
+      .btnTitle {
+        padding-bottom: 8px;
+      }
+    }
+
+    .btnTitle {
+      flex-shrink: 0;
+      font-size: max(18px, 13Px);
+      font-weight: 600;
+      display: flex;
+      align-items: center;
+
+      span {
+        color: #EA4132;
+      }
+    }
+
+    .iconQuestion {
+      display: inline-block;
+      margin-left: 3px;
+      width: 13Px;
+      height: 14Px;
+      background: url('../../../images/icon-question.png') no-repeat center;
+      background-size: contain;
+      cursor: pointer;
+    }
+  }
+}

+ 141 - 0
src/views/prepare-lessons/components/lesson-main/courseware-head/index.tsx

@@ -0,0 +1,141 @@
+import { defineComponent, onMounted, reactive } from 'vue';
+import styles from './index.module.less';
+import { NButton, NInput, NSelect, NSwitch, NTooltip } from 'naive-ui';
+import { usePrepareStore } from '/src/store/modules/prepareLessons';
+import { eventGlobal } from '/src/utils';
+
+export default defineComponent({
+  name: 'courseware-head',
+  setup(props, { emit, expose }) {
+    const prepareStore = usePrepareStore();
+    const forms = reactive({
+      subjects: [] as any,
+      openFlagEnable: true, // 是否支持修改公开状态
+      autoPlay: true,
+      name: '',
+      openFlag: false
+    });
+
+    // 全选
+    const chioseAll = (list: any) => {
+      forms.subjects = list.map((child: any) => {
+        return child.id;
+      }) as any;
+    };
+
+    const getForms = () => {
+      return forms;
+    };
+
+    onMounted(() => {
+      eventGlobal.on('updateCoursewareHeadInfo', (item: any) => {
+        forms.subjects = item.subjects;
+        forms.openFlagEnable = item.openFlagEnable;
+        forms.autoPlay = item.autoPlay;
+        forms.name = item.name;
+        forms.openFlag = item.openFlag;
+      });
+    });
+
+    expose({
+      getForms
+    });
+
+    return () => (
+      <>
+        <div class={styles.headerTitle}>
+          <i class={styles.iconBook}></i>
+          <span>{prepareStore.getSelectName}</span>
+        </div>
+
+        <div class={styles.formContainer}>
+          <div class={[styles.btnItem, styles.block]}>
+            <span class={[styles.btnTitle]}>
+              <span>*</span>课件标题
+            </span>
+            <NInput
+              placeholder="请输入课件标题"
+              v-model:value={forms.name}
+              maxlength={20}
+              clearable
+            />
+          </div>
+          <div class={[styles.btnItem, styles.block]}>
+            <span class={[styles.btnTitle]}>
+              <span>*</span>课件声部
+            </span>
+            <NSelect
+              placeholder="请选择声部(可多选)"
+              class={styles.btnSubjectList}
+              options={prepareStore.getSubjectList}
+              labelField="name"
+              valueField="id"
+              multiple
+              maxTagCount={2}
+              size="small"
+              v-model:value={forms.subjects}
+              clearable
+              v-slots={{
+                action: () => (
+                  <>
+                    <NButton
+                      text
+                      style=" --n-width: 100% "
+                      size="small"
+                      onClick={() => chioseAll(prepareStore.getSubjectList)}>
+                      全选
+                    </NButton>
+                  </>
+                )
+              }}
+            />
+          </div>
+          <div class={styles.btnItem}>
+            <span class={styles.btnTitle}>
+              自动播放
+              <NTooltip style={{ maxWidth: '200px' }} showArrow={false}>
+                {{
+                  trigger: () => <i class={styles.iconQuestion}></i>,
+                  default: () =>
+                    '开启自动播放后,课件内视频、音频资源将自动播放'
+                }}
+              </NTooltip>
+            </span>
+
+            <NSwitch v-model:value={forms.autoPlay} />
+          </div>
+          <div class={styles.btnItem}>
+            <span class={styles.btnTitle}>
+              公开课件
+              <NTooltip style={{ maxWidth: '200px' }} showArrow={false}>
+                {{
+                  trigger: () => <i class={styles.iconQuestion}></i>,
+                  default: () => '公开课件后,其它老师可以使用该课件上课'
+                }}
+              </NTooltip>
+            </span>
+            {!forms.openFlagEnable ? (
+              <NTooltip style={{ maxWidth: '200px' }} showArrow={false}>
+                {{
+                  trigger: () => (
+                    <NSwitch
+                      v-model:value={forms.openFlag}
+                      disabled={!forms.openFlagEnable}
+                    />
+                  ),
+                  default: () =>
+                    '为尊重课件原作者,在“相关课件”中添加的课件不支持公开'
+                }}
+              </NTooltip>
+            ) : (
+              <NSwitch
+                v-model:value={forms.openFlag}
+                disabled={!forms.openFlagEnable}
+              />
+            )}
+          </div>
+        </div>
+      </>
+    );
+  }
+});

+ 148 - 148
src/views/prepare-lessons/components/lesson-main/courseware/addCourseware.module.less

@@ -1,148 +1,148 @@
-.btnGroup {
-  display: flex;
-  align-items: center;
-  justify-content: space-between;
-  margin-left: 22px !important;
-  margin-right: 22px !important;
-  // height: 40px;
-  padding-bottom: 25px;
-  border-bottom: 1px solid #F0F0F0;
-  margin-bottom: 10px;
-
-
-  .btnClassList {
-    :global {
-      .n-base-selection {
-        width: 200px !important;
-      }
-
-      .n-base-selection-label {
-        &::before {
-          margin-left: 12px;
-          content: ' ';
-          width: max(20px, 14Px);
-          height: max(20px, 14Px);
-          flex-shrink: 0;
-          background: url('../../../images/icon-class-name.png') no-repeat center;
-          background-size: contain;
-        }
-      }
-
-      .n-base-selection-input {
-        padding-left: 8px;
-      }
-
-      .n-base-selection.n-base-selection--disabled {
-        cursor: pointer;
-      }
-
-      .n-base-selection.n-base-selection--disabled .n-base-selection-label {
-        background-color: #fff;
-        cursor: pointer;
-      }
-
-      .n-base-selection.n-base-selection--disabled .n-base-selection-label .n-base-selection-input {
-        color: var(--n-text-color);
-        cursor: pointer;
-      }
-
-      .n-base-selection .n-base-selection-overlay {
-        left: 24px;
-      }
-    }
-  }
-
-
-  .btnSubjectList {
-    :global {
-      .n-base-selection-tag-wrapper .n-tag {
-        font-size: max(14px, 12Px);
-      }
-    }
-  }
-
-  :global {
-
-    .n-input,
-    .n-base-selection {
-      --n-height: max(40px, 36Px) !important;
-      width: 200px !important;
-      font-size: 15px;
-      border-radius: 8px !important;
-    }
-
-    .n-base-selection-input__content {
-      font-size: max(15px, 13Px);
-    }
-
-    .n-button {
-      border-radius: 8px;
-      height: 38px;
-      font-size: max(18px, 13Px);
-      font-weight: 600 !important;
-      padding: 0 27px;
-    }
-
-    .n-button--default-type {
-      background: #E8F4FF;
-      color: #0378EC;
-
-      &:not(.n-button--disabled):hover {
-        background: #E8F4FF;
-      }
-
-      .n-button__border {
-        border: 1px solid #198CFE;
-      }
-    }
-
-    .n-button--error-type {
-      background: #FDEBED !important;
-      color: #EC3A4E !important;
-
-      &:not(.n-button--disabled):hover,
-      &:not(.n-button--disabled):active {
-        background: #FDEBED;
-        color: #EC3A4E;
-      }
-
-      .n-button__border {
-        border: 1px solid #EC3A4E;
-      }
-    }
-  }
-
-  .btnClassStart {
-    background: #F44541 !important;
-    color: #fff !important;
-
-    :global {
-      .n-button__border {
-        border: 1px solid #F44541;
-      }
-    }
-  }
-
-  .btnItem {
-    display: flex;
-    align-items: center;
-    height: max(40px, 36Px) !important;
-
-    .btnTitle {
-      flex-shrink: 0;
-      font-size: max(18px, 13Px);
-      font-weight: 600;
-
-      span {
-        color: #EA4132;
-      }
-    }
-
-    // &:last-child {
-    //   margin-left: 12px;
-    // }
-  }
-}
+// .btnGroup {
+//   display: flex;
+//   align-items: center;
+//   justify-content: space-between;
+//   margin-left: 22px !important;
+//   margin-right: 22px !important;
+//   // height: 40px;
+//   padding-bottom: 25px;
+//   border-bottom: 1px solid #F0F0F0;
+//   margin-bottom: 10px;
+
+
+//   .btnClassList {
+//     :global {
+//       .n-base-selection {
+//         width: 200px !important;
+//       }
+
+//       .n-base-selection-label {
+//         &::before {
+//           margin-left: 12px;
+//           content: ' ';
+//           width: max(20px, 14Px);
+//           height: max(20px, 14Px);
+//           flex-shrink: 0;
+//           background: url('../../../images/icon-class-name.png') no-repeat center;
+//           background-size: contain;
+//         }
+//       }
+
+//       .n-base-selection-input {
+//         padding-left: 8px;
+//       }
+
+//       .n-base-selection.n-base-selection--disabled {
+//         cursor: pointer;
+//       }
+
+//       .n-base-selection.n-base-selection--disabled .n-base-selection-label {
+//         background-color: #fff;
+//         cursor: pointer;
+//       }
+
+//       .n-base-selection.n-base-selection--disabled .n-base-selection-label .n-base-selection-input {
+//         color: var(--n-text-color);
+//         cursor: pointer;
+//       }
+
+//       .n-base-selection .n-base-selection-overlay {
+//         left: 24px;
+//       }
+//     }
+//   }
+
+
+//   .btnSubjectList {
+//     :global {
+//       .n-base-selection-tag-wrapper .n-tag {
+//         font-size: max(14px, 12Px);
+//       }
+//     }
+//   }
+
+//   :global {
+
+//     .n-input,
+//     .n-base-selection {
+//       --n-height: max(40px, 36Px) !important;
+//       width: 200px !important;
+//       font-size: 15px;
+//       border-radius: 8px !important;
+//     }
+
+//     .n-base-selection-input__content {
+//       font-size: max(15px, 13Px);
+//     }
+
+//     .n-button {
+//       border-radius: 8px;
+//       height: 38px;
+//       font-size: max(18px, 13Px);
+//       font-weight: 600 !important;
+//       padding: 0 27px;
+//     }
+
+//     .n-button--default-type {
+//       background: #E8F4FF;
+//       color: #0378EC;
+
+//       &:not(.n-button--disabled):hover {
+//         background: #E8F4FF;
+//       }
+
+//       .n-button__border {
+//         border: 1px solid #198CFE;
+//       }
+//     }
+
+//     .n-button--error-type {
+//       background: #FDEBED !important;
+//       color: #EC3A4E !important;
+
+//       &:not(.n-button--disabled):hover,
+//       &:not(.n-button--disabled):active {
+//         background: #FDEBED;
+//         color: #EC3A4E;
+//       }
+
+//       .n-button__border {
+//         border: 1px solid #EC3A4E;
+//       }
+//     }
+//   }
+
+//   .btnClassStart {
+//     background: #F44541 !important;
+//     color: #fff !important;
+
+//     :global {
+//       .n-button__border {
+//         border: 1px solid #F44541;
+//       }
+//     }
+//   }
+
+//   .btnItem {
+//     display: flex;
+//     align-items: center;
+//     height: max(40px, 36Px) !important;
+
+//     .btnTitle {
+//       flex-shrink: 0;
+//       font-size: max(18px, 13Px);
+//       font-weight: 600;
+
+//       span {
+//         color: #EA4132;
+//       }
+//     }
+
+//     // &:last-child {
+//     //   margin-left: 12px;
+//     // }
+//   }
+// }
 
 .tipsContainer {
   display: flex;
@@ -187,7 +187,7 @@
 }
 
 .listContainer {
-  margin-top: 12px;
+  margin: 20px 0 20px;
   // // 52 + 28 + 38 + 38 多余10像素空间
   // max-height: calc(var(--window-page-lesson-height) - 196px);
 
@@ -202,10 +202,10 @@
   //     min-height: calc(var(--window-page-lesson-height) - 148px);
   //   }
   // }
-  max-height: calc(var(--window-page-lesson-height) - 184px);
+  max-height: calc(var(--window-page-lesson-height) - 40px);
 
   .listSection {
-    min-height: calc(var(--window-page-lesson-height) - 184px);
+    min-height: calc(var(--window-page-lesson-height) - 40px);
   }
 
   .emptySection {

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

@@ -75,6 +75,7 @@ export default defineComponent({
     const forms = reactive({
       subjects: [] as any,
       openFlagEnable: true, // 是否支持修改公开状态
+      autoPlay: true,
       name: '',
       openFlag: false,
       createId: null,
@@ -85,6 +86,12 @@ export default defineComponent({
           list: [] as any
         }
       ] as any, // 基础数据
+      baseInfo: {
+        subjects: [] as any,
+        autoPlay: true,
+        name: '',
+        openFlag: false
+      }, // 基础数据
       coursewareList: [
         {
           name: '',
@@ -142,6 +149,7 @@ export default defineComponent({
           : [];
         forms.openFlag = data.openFlag;
         forms.openFlagEnable = data.openFlagEnable;
+        forms.autoPlay = data.autoPlay;
         const temp: any = [];
         tempRows.forEach((row: any) => {
           const child: any = row.chapterKnowledgeMaterialList;
@@ -170,6 +178,22 @@ export default defineComponent({
         });
         forms.coursewareList = temp;
         forms.baseCoursewareList = deepClone(temp);
+
+        forms.baseInfo = deepClone({
+          subjects: forms.subjects,
+          autoPlay: forms.autoPlay,
+          name: forms.name,
+          openFlag: forms.openFlag
+        });
+
+        /** 给头部组件分发消息 */
+        eventGlobal.emit('updateCoursewareHeadInfo', {
+          name: forms.name,
+          subjects: forms.subjects,
+          openFlag: forms.openFlag,
+          openFlagEnable: forms.openFlagEnable,
+          autoPlay: forms.autoPlay
+        });
       } catch (e) {
         //
         console.log(e);
@@ -184,41 +208,6 @@ export default defineComponent({
       coursewareItem.list.splice(j, 1);
     };
 
-    // 完成编辑
-    // const onOverEdit = async () => {
-    //   try {
-    //     const temp: any = [];
-    //     forms.coursewareList.forEach((item: any) => {
-    //       temp.push({
-    //         materialName: item.name,
-    //         materialType: item.type,
-    //         materialId: item.materialId,
-    //         id: item.id
-    //       });
-    //     });
-    //     // 保存课件
-    //     // 判断是否编辑,如果编辑则取选择的声部
-    //     await saveCourseware({
-    //       coursewareDetailKnowledgeId: prepareStore.getSelectKey,
-    //       lessonCoursewareId: prepareStore.getLessonCoursewareId,
-    //       lessonCoursewareDetailId: prepareStore.getLessonCoursewareDetailId,
-    //       // subjectId: forms.isEdit
-    //       //   ? forms.editSubjectIds
-    //       //   : prepareStore.getSubjectId,
-    //       materialList: [...temp]
-    //     });
-
-    //     message.success('编辑成功');
-    //     // forms.removeVisiable = false;
-    //     prepareStore.setIsEditResource(false);
-    //     // 重置临时删除编号
-    //     forms.removeIds = [];
-    //     await getList();
-    //   } catch {
-    //     //
-    //   }
-    // };
-
     const isPointInsideElement = (element: any, x: number, y: number) => {
       const rect = element.getBoundingClientRect();
       return (
@@ -423,6 +412,7 @@ export default defineComponent({
           name: forms.name,
           subjectIds: forms.subjects.join(','),
           openFlag: forms.openFlag,
+          autoPlay: forms.autoPlay,
           coursewareDetailKnowledgeId: prepareStore.getSelectKey,
           chapterKnowledgeList: [] as any
         };
@@ -498,7 +488,14 @@ export default defineComponent({
     const onPageBeforeLeave = (event: any) => {
       const objA = JSON.stringify(forms.coursewareList);
       const objB = JSON.stringify(forms.baseCoursewareList);
-      if (objA === objB) {
+      const baseA = JSON.stringify({
+        subjects: forms.subjects,
+        autoPlay: forms.autoPlay,
+        name: forms.name,
+        openFlag: forms.openFlag
+      });
+      const baseB = JSON.stringify(forms.baseInfo);
+      if (objA === objB && baseA === baseB) {
         if (typeof event === 'function') {
           event();
 
@@ -527,6 +524,60 @@ export default defineComponent({
         };
       }
     };
+
+    const onCancelCourseware = (item: any) => {
+      forms.subjects = item.subjects;
+      forms.openFlagEnable = item.openFlagEnable;
+      forms.autoPlay = item.autoPlay;
+      forms.name = item.name;
+      forms.openFlag = item.openFlag;
+
+      const objA = JSON.stringify(forms.coursewareList);
+      const objB = JSON.stringify(forms.baseCoursewareList);
+      const baseA = JSON.stringify({
+        subjects: forms.subjects,
+        autoPlay: forms.autoPlay,
+        name: forms.name,
+        openFlag: forms.openFlag
+      });
+      const baseB = JSON.stringify(forms.baseInfo);
+
+      if (objA === objB && baseA === baseB) {
+        emit('change', {
+          status: false,
+          addParam: {
+            isAdd: false,
+            name: forms.name,
+            id: forms.createId
+          }
+        });
+
+        eventGlobal.emit('teacher-slideshow', false);
+      } else {
+        forms.messageOperation = {
+          visiable: true,
+          type: 'save',
+          loading: false,
+          contentDirection: 'center',
+          title: '保存课件',
+          content: '当前课件暂未保存,是否保存?',
+          cancelButtonText: '不保存',
+          confirmButtonText: '保存',
+          index: 0
+        };
+      }
+    };
+
+    const onSubmitCourseware = (item: any) => {
+      forms.subjects = item.subjects;
+      forms.openFlagEnable = item.openFlagEnable;
+      forms.autoPlay = item.autoPlay;
+      forms.name = item.name;
+      forms.openFlag = item.openFlag;
+
+      onSubmit();
+    };
+
     onMounted(async () => {
       // 修改时重置默认数据
       if (props.groupItem?.id) {
@@ -538,11 +589,18 @@ export default defineComponent({
       // 动态添加数据
       eventGlobal.on('onPrepareAddItem', addItem);
       eventGlobal.on('pageBeforeLeave', onPageBeforeLeave);
+
+      // 取消
+      eventGlobal.on('coursewareClosed', onCancelCourseware);
+      // 保存
+      eventGlobal.on('coursewareSave', onSubmitCourseware);
     });
 
     onUnmounted(() => {
       eventGlobal.off('onPrepareAddItem', addItem);
       eventGlobal.off('pageBeforeLeave', onPageBeforeLeave);
+      eventGlobal.off('coursewareClosed', onCancelCourseware);
+      eventGlobal.off('coursewareSave', onSubmitCourseware);
     });
 
     // 当列表数据更新时同步缓存数据
@@ -556,135 +614,13 @@ export default defineComponent({
       }
     );
 
-    // 全选
-    const chioseAll = (list: any) => {
-      forms.subjects = list.map((child: any) => {
-        return child.id;
-      }) as any;
-    };
     return () => (
       <div class={styles.coursewareModal}>
-        <div class={styles.btnGroup}>
-          <NSpace>
-            <div class={styles.btnItem}>
-              <span class={styles.btnTitle}>
-                <span>*</span>标题:
-              </span>
-              <NInput
-                placeholder="请输入课件标题"
-                v-model:value={forms.name}
-                maxlength={20}
-                clearable
-              />
-            </div>
-            <div class={styles.btnItem}>
-              <span class={styles.btnTitle}>
-                <span>*</span>声部:
-              </span>
-              <NSelect
-                placeholder="请选择声部(可多选)"
-                class={styles.btnSubjectList}
-                options={prepareStore.getSubjectList}
-                labelField="name"
-                valueField="id"
-                multiple
-                maxTagCount={1}
-                size="small"
-                v-model:value={forms.subjects}
-                clearable
-                v-slots={{
-                  action: () => (
-                    <>
-                      <NButton
-                        text
-                        style=" --n-width: 100% "
-                        size="small"
-                        onClick={() => chioseAll(prepareStore.getSubjectList)}>
-                        全选
-                      </NButton>
-                    </>
-                  )
-                }}
-              />
-            </div>
-            <div class={styles.btnItem}>
-              <span class={styles.btnTitle}>公开:</span>
-              {!forms.openFlagEnable ? (
-                <NTooltip style={{ maxWidth: '200px' }} showArrow={false}>
-                  {{
-                    trigger: () => (
-                      <NSwitch
-                        v-model:value={forms.openFlag}
-                        disabled={!forms.openFlagEnable}
-                      />
-                    ),
-                    default: () =>
-                      '为尊重课件原作者,在“相关课件”中添加的课件不支持公开'
-                  }}
-                </NTooltip>
-              ) : (
-                <NSwitch
-                  v-model:value={forms.openFlag}
-                  disabled={!forms.openFlagEnable}
-                />
-              )}
-            </div>
-          </NSpace>
-
-          {/* 编辑 */}
-          <NSpace>
-            <NButton
-              type="error"
-              bordered={false}
-              onClick={() => {
-                const objA = JSON.stringify(forms.coursewareList);
-                const objB = JSON.stringify(forms.baseCoursewareList);
-                if (objA === objB) {
-                  emit('change', {
-                    status: false,
-                    addParam: {
-                      isAdd: false,
-                      name: forms.name,
-                      id: forms.createId
-                    }
-                  });
-
-                  eventGlobal.emit('teacher-slideshow', false);
-                } else {
-                  forms.messageOperation = {
-                    visiable: true,
-                    type: 'save',
-                    loading: false,
-                    contentDirection: 'center',
-                    title: '保存课件',
-                    content: '当前课件暂未保存,是否保存?',
-                    cancelButtonText: '不保存',
-                    confirmButtonText: '保存',
-                    index: 0
-                  };
-                }
-              }}>
-              取消
-            </NButton>
-            <NButton
-              type="primary"
-              onClick={onSubmit}
-              disabled={forms.coursewareList.length <= 0}>
-              保存课件
-            </NButton>
-            {/* <NButton
-              type="primary"
-              onClick={() => {
-                forms.coursewareList = [{ name: '', list: [] }];
-              }}>
-              请空
-            </NButton> */}
-          </NSpace>
-        </div>
-
-        <NScrollbar class={[styles.listContainer]} {...{ id: 'lessons-2' }}>
+        <NScrollbar
+          class={[styles.listContainer, 'listContainerWrap']}
+          {...{ id: 'lessons-2' }}>
           <NSpin show={forms.loadingStatus}>
-            <div class={[styles.listSection]}>
+            <div class={[styles.listSection, 'listSectionWrap']}>
               {forms.coursewareList.map((item: any, index: number) => (
                 <div
                   class={[styles.listItems, 'row-group']}

+ 88 - 0
src/views/prepare-lessons/components/lesson-main/index.module.less

@@ -1,5 +1,54 @@
+.coursewareSection {
+  display: flex;
+  height: 100%;
+
+  .coursewareHeader {
+    flex: 0 0 360px;
+    background-color: #fff;
+    border-radius: 20px;
+
+    padding-bottom: 40px;
+  }
+
+  .lesson-main {
+    flex: 1;
+    margin-left: 20px
+  }
+
+  :global {
+    .listContainerWrap {
+      max-height: calc(var(--window-page-lesson-height) - 40px - 20px);
+
+      .listSectionWrap {
+        min-height: calc(var(--window-page-lesson-height) - 40px - 20px);
+      }
+    }
+  }
+}
+
+:global {
+  .listContainerResource {
+    max-height: calc(var(--window-page-lesson-height) - 244px - 40px) !important;
+    // overflow-x: auto;
+
+    &.listNoMusicResource {
+      max-height: calc(var(--window-page-lesson-height) - 184px - 40px) !important;
+
+      .listSectionResource {
+        min-height: calc(var(--window-page-lesson-height) - 184px - 40px) !important;
+      }
+    }
+
+    .listSectionResource {
+      min-height: calc(var(--window-page-lesson-height) - 204px - 40px) !important;
+    }
+  }
+}
+
 .lesson-main {
   height: 100%;
+  background-color: #fff;
+  border-radius: 20px;
 
   :global {
     .n-tabs-tab-pad {
@@ -38,4 +87,43 @@
       padding-top: 4px !important;
     }
   }
+}
+
+.coursewareFooter {
+  position: absolute;
+  bottom: 0;
+  left: 100px;
+  right: 0;
+  z-index: 100;
+  background: #FFFFFF;
+  box-shadow: 0 2px 10px 0px rgba(0, 0, 0, 0.12);
+  height: 68px;
+  display: flex;
+  align-items: center;
+  justify-content: center;
+
+  :global {
+    .n-button {
+      border-radius: 8px;
+      height: 42px;
+      font-size: max(18px, 14Px);
+      font-weight: 600 !important;
+      padding: 0 32px;
+    }
+
+    .n-button--error-type {
+      background: #FDEBED !important;
+      color: #EC3A4E !important;
+
+      &:not(.n-button--disabled):hover,
+      &:not(.n-button--disabled):active {
+        background: #FDEBED;
+        color: #EC3A4E;
+      }
+
+      .n-button__border {
+        border: 1px solid #EC3A4E;
+      }
+    }
+  }
 }

+ 122 - 108
src/views/prepare-lessons/components/lesson-main/index.tsx

@@ -1,12 +1,14 @@
 import { defineComponent, nextTick, reactive, ref, watch } from 'vue';
 import styles from './index.module.less';
-import { NTabPane, NTabs } from 'naive-ui';
+// import { NTabPane, NTabs } from 'naive-ui';
 import Courseware from './courseware/addCourseware';
-import Train from './train';
+// import Train from './train';
 import { usePrepareStore } from '/src/store/modules/prepareLessons';
-import TrainPresets from './train-presets';
+// import TrainPresets from './train-presets';
 import { eventGlobal } from '/src/utils';
 import CoursewarePresets from './courseware-presets';
+import CoursewareHead from './courseware-head';
+import { NButton, NSpace } from 'naive-ui';
 
 export default defineComponent({
   name: 'lesson-main',
@@ -21,119 +23,131 @@ export default defineComponent({
         addName: '' // 添加的名称
       },
       editCourseware: {} as any, //
-      editWorkShow: false, // 是否编辑预设
+      // editWorkShow: false, // 是否编辑预设
       editWork: {} as any // 预设模板编号
     });
-    const lessonMainRef = ref();
+    const coursewareHeadRef = ref();
 
-    // watch(
-    //   () => [state.editWorkShow, state.editCoursewareShow],
-    //   () => {
-    //     nextTick(() => {
-    //       lessonMainRef.value?.syncBarPosition();
-    //     });
-    //   }
-    // );
+    // 取消
+    const onCancelCourseware = () => {
+      eventGlobal.emit('coursewareClosed', coursewareHeadRef.value?.getForms());
+    };
 
-    return () => (
-      <div class={styles['lesson-main']}>
-        {state.editCoursewareShow ? (
-          <NTabs
-            ref={lessonMainRef}
-            defaultValue="courseware"
-            paneClass={styles.paneTitle}
-            justifyContent="center"
-            paneWrapperClass={styles.paneWrapperContainer}
-            value={prepareStore.getTabType}
-            onUpdate:value={(val: string) => {
-              prepareStore.setTabType(val);
-              // 重置编辑状态
-              prepareStore.setIsEditResource(false);
-              prepareStore.setIsEditTrain(false);
+    const onSaveCourseware = () => {
+      // console.log(
+      //   coursewareHeadRef.value,
+      //   coursewareHeadRef.value?.getForms(),
+      //   '12'
+      // );
+      eventGlobal.emit('coursewareSave', coursewareHeadRef.value?.getForms());
+    };
 
-              eventGlobal.emit('teacher-slideshow', false);
-              if (val !== 'train') {
-                state.editWorkShow = false;
-              }
-            }}>
-            {!state.editWorkShow && (
-              <NTabPane
-                name="courseware"
-                tab={
-                  state.editCoursewareShow
-                    ? state.coursewareType === 'create'
-                      ? '创建课件'
-                      : '编辑课件'
-                    : '课件'
-                }
-                displayDirective="if">
-                <Courseware
-                  groupItem={state.editCourseware}
-                  onChange={(val: any) => {
-                    if (val.addParam) {
-                      state.addParam = val.addParam;
-                    }
-                    state.editCoursewareShow = val.status;
-                    prepareStore.setIsEditResource(val.status);
-                    if (!val.status) {
-                      eventGlobal.emit('teacher-slideshow', false);
-                    }
-                  }}
-                />
-              </NTabPane>
-            )}
-          </NTabs>
-        ) : (
-          <CoursewarePresets
-            addParam={state.addParam}
-            onChange={(val: any) => {
-              state.coursewareType = val.type;
-              state.editCoursewareShow = val.status;
-              prepareStore.setIsEditResource(val.status);
-              state.editCourseware = val.groupItem;
-              state.addParam = {
-                isAdd: false, // 是否添加
-                id: null,
-                addName: '' // 添加的名称
-              };
-            }}
-          />
+    return () => (
+      <div
+        class={[state.editCoursewareShow && styles.coursewareSection]}
+        style={{ height: '100%' }}>
+        {/* 编辑作业头部标题 */}
+        {state.editCoursewareShow && (
+          <div class={styles.coursewareHeader}>
+            <CoursewareHead ref={coursewareHeadRef} />
+          </div>
         )}
 
-        {/* {!state.editCoursewareShow && (
-          <NTabPane
-            name="train"
-            // tab="作业"
-            tab={state.editWorkShow ? '编辑作业' : '作业'}
-            displayDirective="if">
-            <div>
-              {state.editWorkShow ? (
-                <Train
-                  lessonPreTraining={state.editWork}
-                  onChange={(val: any) => {
-                    state.editWorkShow = val.status;
+        <div class={styles['lesson-main']}>
+          {state.editCoursewareShow ? (
+            // <NTabs
+            //   ref={lessonMainRef}
+            //   defaultValue="courseware"
+            //   paneClass={styles.paneTitle}
+            //   justifyContent="center"
+            //   paneWrapperClass={styles.paneWrapperContainer}
+            //   value={prepareStore.getTabType}
+            //   onUpdate:value={(val: string) => {
+            //     prepareStore.setTabType(val);
+            //     // 重置编辑状态
+            //     prepareStore.setIsEditResource(false);
+            //     prepareStore.setIsEditTrain(false);
+
+            //     eventGlobal.emit('teacher-slideshow', false);
+            //     if (val !== 'train') {
+            //       state.editWorkShow = false;
+            //     }
+            //   }}>
+            //   {!state.editWorkShow && (
+            //     <NTabPane
+            //       name="courseware"
+            //       tab={
+            //         state.editCoursewareShow
+            //           ? state.coursewareType === 'create'
+            //             ? '创建课件'
+            //             : '编辑课件'
+            //           : '课件'
+            //       }
+            //       displayDirective="if">
+            //       <Courseware
+            //         groupItem={state.editCourseware}
+            //         onChange={(val: any) => {
+            //           if (val.addParam) {
+            //             state.addParam = val.addParam;
+            //           }
+            //           state.editCoursewareShow = val.status;
+            //           prepareStore.setIsEditResource(val.status);
+            //           if (!val.status) {
+            //             eventGlobal.emit('teacher-slideshow', false);
+            //           }
+            //         }}
+            //       />
+            //     </NTabPane>
+            //   )}
+            // </NTabs>
 
-                    if (!val.status) {
-                      eventGlobal.emit('teacher-slideshow', false);
-                    }
-                  }}
-                />
-              ) : (
-                <TrainPresets
-                  onChange={(val: any) => {
-                    state.editWorkShow = val.status;
-                    state.editWork = {
-                      ...val.lessonPreTraining,
-                      title:
-                        val.lessonPreTraining?.title ||
-                        prepareStore.getSelectName + '课后作业'
-                    };
-                  }}
-                />
-              )}
-            </div>
-          </NTabPane>
-        )} */}
+            <Courseware
+              groupItem={state.editCourseware}
+              onChange={(val: any) => {
+                if (val.addParam) {
+                  state.addParam = val.addParam;
+                }
+                state.editCoursewareShow = val.status;
+                prepareStore.setIsEditResource(val.status);
+                if (!val.status) {
+                  eventGlobal.emit('teacher-slideshow', false);
+                }
+              }}
+            />
+          ) : (
+            <CoursewarePresets
+              addParam={state.addParam}
+              onChange={(val: any) => {
+                state.coursewareType = val.type;
+                state.editCoursewareShow = val.status;
+                prepareStore.setIsEditResource(val.status);
+                state.editCourseware = val.groupItem;
+                state.addParam = {
+                  isAdd: false, // 是否添加
+                  id: null,
+                  addName: '' // 添加的名称
+                };
+              }}
+            />
+          )}
+        </div>
+
+        {/* 编辑作业底部操作 */}
+        {state.editCoursewareShow && (
+          <div class={styles.coursewareFooter}>
+            <NSpace>
+              <NButton
+                bordered={false}
+                type="error"
+                onClick={onCancelCourseware}>
+                取消
+              </NButton>
+              <NButton type="primary" onClick={onSaveCourseware}>
+                保存课件
+              </NButton>
+            </NSpace>
+          </div>
+        )}
       </div>
     );
   }

+ 4 - 2
src/views/prepare-lessons/components/resource-main/components/resource-item/index.tsx

@@ -190,9 +190,10 @@ export default defineComponent({
         <NScrollbar
           class={[
             styles.listContainer,
+            'listContainerResource',
             state.searchGroup.type !== 'MUSIC' ||
             ['myResources', 'myCollect', 'relateResources'].includes(props.type)
-              ? styles.listNoMusic
+              ? [styles.listNoMusic, 'listNoMusicResource']
               : ''
           ]}
           onScroll={(e: any) => {
@@ -212,8 +213,9 @@ export default defineComponent({
             <div
               class={[
                 styles.listSection,
+                'listSectionResource',
                 !state.loading && state.tableList.length <= 0
-                  ? styles.emptySection
+                  ? [styles.emptySection, 'emptySectionResource']
                   : ''
               ]}>
               {state.tableList.length > 0 && (

BIN
src/views/prepare-lessons/images/icon-book.png


BIN
src/views/prepare-lessons/images/icon-question.png


+ 26 - 2
src/views/prepare-lessons/index.module.less

@@ -4,6 +4,7 @@
   // padding-bottom: 32px;
   height: calc(100vh - 118px);
   overflow: hidden;
+  border-radius: 20px;
 
   .directoryMain,
   .resourceMain {
@@ -12,10 +13,16 @@
     border-radius: 20px;
   }
 
+
+  .directoryMain {
+    margin-right: 20px;
+  }
+
+
   .lessonMain {
-    margin: 0 20px;
+    margin: 0 20px 0 0;
     flex: 1;
-    background-color: #fff;
+    // background-color: #fff;
     border-radius: 20px;
     transition: all .2s ease;
   }
@@ -32,6 +39,22 @@
     }
   }
 
+  &.showSideBar {
+    .directoryMain {
+      width: 360px;
+      transition: all .2s ease;
+      opacity: 0;
+      position: absolute;
+      right: 0;
+      transform: translateX(100%);
+    }
+
+    .lessonMain {
+      transition: all .2s ease;
+      margin-left: 0;
+    }
+  }
+
   &.hideSideBar {
     position: relative;
     overflow: hidden;
@@ -45,6 +68,7 @@
       transform: translateX(100%);
     }
 
+
     .lessonMain {
       transition: all .2s ease;
       margin-right: 0;

+ 5 - 6
src/views/prepare-lessons/index.tsx

@@ -53,6 +53,7 @@ export default defineComponent({
     };
 
     const onSlideChange = (val: boolean) => {
+      console.log(val, 'val');
       state.sidebarShow = val;
       resourceMainRef.value?.resetTabPosition();
     };
@@ -109,13 +110,11 @@ export default defineComponent({
       <div
         class={[
           styles.prepareLessons,
-          !state.sidebarShow && styles.hideSideBar
-        ]}>
+          state.sidebarShow ? styles.showSideBar : styles.hideSideBar
+        ]}
+        id="lessons-height">
         {/* 左侧目录 */}
-        <div
-          class={styles.directoryMain}
-          ref={directroyRef.value}
-          id="lessons-height">
+        <div class={styles.directoryMain} ref={directroyRef.value}>
           <DirectoryList />
         </div>
         {/* 中间排课 */}