Bladeren bron

Merge branch 'iteration-classroom' into jenkins

lex 1 jaar geleden
bovenliggende
commit
5f3c20eee2
53 gewijzigde bestanden met toevoegingen van 1441 en 487 verwijderingen
  1. 1 1
      dev-dist/sw.js
  2. 1 1
      public/version.json
  3. BIN
      src/common/images/icon-audio.png
  4. BIN
      src/common/images/icon-image.png
  5. BIN
      src/common/images/icon-music.png
  6. BIN
      src/common/images/icon-other.png
  7. BIN
      src/common/images/icon-ppt.png
  8. BIN
      src/common/images/icon-video.png
  9. 3 2
      src/components/card-type/index.module.less
  10. 15 2
      src/components/card-type/index.tsx
  11. 16 1
      src/components/layout/layoutSilder.tsx
  12. 17 3
      src/components/layout/layoutTop.tsx
  13. 1 1
      src/store/modules/prepareLessons.ts
  14. BIN
      src/views/attend-class/image/arrow-active.png
  15. BIN
      src/views/attend-class/image/arrow-default.png
  16. 6 0
      src/views/attend-class/index.module.less
  17. 128 149
      src/views/attend-class/index.tsx
  18. 1 1
      src/views/attend-class/model/chapter/index.tsx
  19. 34 0
      src/views/attend-class/model/select-class/index.module.less
  20. 101 0
      src/views/attend-class/model/select-class/index.tsx
  21. 81 0
      src/views/attend-class/model/source-list/index.module.less
  22. 91 0
      src/views/attend-class/model/source-list/index.tsx
  23. 1 11
      src/views/home/components/trainData.tsx
  24. 11 4
      src/views/prepare-lessons/api.ts
  25. 37 21
      src/views/prepare-lessons/components/directory-main/index.tsx
  26. 12 1
      src/views/prepare-lessons/components/lesson-main/courseware-presets/index.module.less
  27. 276 75
      src/views/prepare-lessons/components/lesson-main/courseware-presets/index.tsx
  28. 22 52
      src/views/prepare-lessons/components/lesson-main/courseware/addCourseware.module.less
  29. 252 111
      src/views/prepare-lessons/components/lesson-main/courseware/addCourseware.tsx
  30. 5 0
      src/views/prepare-lessons/components/lesson-main/index.tsx
  31. 5 1
      src/views/prepare-lessons/components/resource-main/components/resource-item/index.tsx
  32. 15 0
      src/views/prepare-lessons/components/resource-main/index.module.less
  33. 1 0
      src/views/prepare-lessons/components/resource-main/index.tsx
  34. BIN
      src/views/prepare-lessons/images/addSource/icon1.png
  35. BIN
      src/views/prepare-lessons/images/addSource/icon2.png
  36. BIN
      src/views/prepare-lessons/images/addSource/icon3.png
  37. BIN
      src/views/prepare-lessons/images/addSource/icon4.png
  38. BIN
      src/views/prepare-lessons/images/addSource/icon5.png
  39. BIN
      src/views/prepare-lessons/images/addSource/icon6.png
  40. BIN
      src/views/prepare-lessons/images/addSource/icon7.png
  41. 26 0
      src/views/prepare-lessons/model/add-item-model/index.module.less
  42. 51 0
      src/views/prepare-lessons/model/add-item-model/index.tsx
  43. 34 0
      src/views/prepare-lessons/model/add-other-source/index.module.less
  44. 105 0
      src/views/prepare-lessons/model/add-other-source/index.tsx
  45. 41 3
      src/views/prepare-lessons/model/courseware-type/index.module.less
  46. 15 2
      src/views/prepare-lessons/model/courseware-type/index.tsx
  47. 5 4
      src/views/prepare-lessons/model/select-resources/index.tsx
  48. 3 1
      src/views/prepare-lessons/model/select-resources/select-item/class-search-group/index.tsx
  49. 14 39
      src/views/prepare-lessons/model/select-resources/select-item/index.tsx
  50. 3 1
      src/views/prepare-lessons/model/select-resources/select-item/resource-search-group/index.tsx
  51. 0 0
      src/views/prepare-lessons/model/source-rhythm/index.module.less
  52. 10 0
      src/views/prepare-lessons/model/source-rhythm/index.tsx
  53. 1 0
      src/views/preview-window/index.tsx

+ 1 - 1
dev-dist/sw.js

@@ -102,7 +102,7 @@ define(['./workbox-5357ef54'], (function (workbox) { 'use strict';
     "revision": "3ca0b8505b4bec776b69afdba2768812"
   }, {
     "url": "index.html",
-    "revision": "0.u2i0a8cqof"
+    "revision": "0.44rej4rp79g"
   }], {});
 >>>>>>> iteration-roll-call
   workbox.cleanupOutdatedCaches();

+ 1 - 1
public/version.json

@@ -1 +1 @@
-{"version":1709906643265}
+{ "version": 1709906643265 }

BIN
src/common/images/icon-audio.png


BIN
src/common/images/icon-image.png


BIN
src/common/images/icon-music.png


BIN
src/common/images/icon-other.png


BIN
src/common/images/icon-ppt.png


BIN
src/common/images/icon-video.png


+ 3 - 2
src/components/card-type/index.module.less

@@ -119,8 +119,9 @@
     align-items: center;
 
     .titleType {
-      width: max(36px, 28Px);
-      height: max(17px, 13Px);
+      width: 12Px;
+      height: 12Px;
+      margin-top: 1px;
     }
 
     .titleContent {

+ 15 - 2
src/components/card-type/index.tsx

@@ -6,6 +6,7 @@ import iconVideo from '@common/images/icon-video.png';
 import iconAudio from '@common/images/icon-audio.png';
 import iconMusic from '@common/images/icon-music.png';
 import iconPPT from '@common/images/icon-ppt.png';
+import iconOther from '@common/images/icon-other.png';
 import iconCollectDefault from '@common/images/icon-collect-default.png';
 import iconCollectActive from '@common/images/icon-collect-active.png';
 import iconDownload from '@common/images/icon-download.png';
@@ -17,9 +18,21 @@ import { api_musicSheetDetail } from '/src/api/user';
 import JSZip, { file } from 'jszip';
 import { saveAs } from 'file-saver';
 
+// LISTEN:听音,RHYTHM:节奏,THEORY:乐理知识,MUSIC:曲目 INSTRUMENT:乐器 MUSICIAN:音乐家)
 type itemType = {
   id: string | number;
-  type: 'IMG' | 'VIDEO' | 'SONG' | 'MUSIC' | 'PPT';
+  type:
+    | 'IMG'
+    | 'VIDEO'
+    | 'SONG'
+    | 'MUSIC'
+    | 'PPT'
+    | 'LISTEN'
+    | 'RHYTHM'
+    | 'THEORY'
+    | 'MUSIC'
+    | 'INSTRUMENT'
+    | 'MUSICIAN';
   coverImg: string;
   content?: string;
   title: string;
@@ -98,7 +111,7 @@ export default defineComponent({
     const isAnimation = ref(false);
     const downloadStatus = ref(false);
     const formatType = (type: string) => {
-      let typeImg = iconImage;
+      let typeImg = iconOther;
       switch (type) {
         case 'IMG':
           typeImg = iconImage;

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

@@ -24,9 +24,12 @@ import icon_1_2 from './images/icon_1_2.png';
 import iconHomeWork from './images/icon-homework.png';
 import iconHomeWorkActive from './images/icon-homework-active.png';
 import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router';
+import { usePrepareStore } from '/src/store/modules/prepareLessons';
+import { eventGlobal } from '/src/utils';
 export default defineComponent({
   name: 'layoutSilder',
   setup() {
+    const prepareStore = usePrepareStore();
     const router = useRouter();
     const route = useRoute();
     const itemInfoList = reactive([
@@ -168,7 +171,19 @@ export default defineComponent({
           </div>
           <NScrollbar class={styles.sliderList}>
             {itemInfoList.map((item: any) => (
-              <SilderItem onCheckNavBar={checkNavBar} item={item} />
+              <SilderItem
+                onCheckNavBar={() => {
+                  // 检测是否有未保存数据
+                  if (prepareStore.getIsEditResource) {
+                    eventGlobal.emit('pageBeforeLeave', () =>
+                      checkNavBar(item)
+                    );
+                  } else {
+                    checkNavBar(item);
+                  }
+                }}
+                item={item}
+              />
             ))}
           </NScrollbar>
         </div>

+ 17 - 3
src/components/layout/layoutTop.tsx

@@ -28,6 +28,7 @@ import dayjs from 'dayjs';
 import ClassModal from '/src/views/home/modals/class-modal';
 import { suggestMessageUnread } from '/src/api/user';
 import { eventGlobal } from '/src/utils';
+import { usePrepareStore } from '/src/store/modules/prepareLessons';
 export default defineComponent({
   name: 'layoutTop',
   setup() {
@@ -42,6 +43,15 @@ export default defineComponent({
     const { info } = storeToRefs(users);
     const userInfoStatus = ref(false);
     const classRecordStatus = ref(false);
+    const prepareStore = usePrepareStore();
+
+    const oncheckEditStatus = (callBack: any) => {
+      if (prepareStore.getIsEditResource) {
+        eventGlobal.emit('pageBeforeLeave', () => callBack());
+      } else {
+        callBack();
+      }
+    };
     const gotoPerson = () => {
       userInfoStatus.value = false;
       router.push({ path: '/setting', query: { activeTab: 'person' } });
@@ -283,7 +293,9 @@ export default defineComponent({
                   </NTooltip>
                 </div>
                 <div class={styles.propWrapList}>
-                  <div class={styles.propWrapItem} onClick={() => gotoPerson()}>
+                  <div
+                    class={styles.propWrapItem}
+                    onClick={() => oncheckEditStatus(gotoPerson)}>
                     <NImage
                       class={styles.smallIcon}
                       src={personIcon}
@@ -294,7 +306,7 @@ export default defineComponent({
                     <div
                       class={styles.propWrapItem}
                       onClick={() => {
-                        gotoSchool();
+                        oncheckEditStatus(gotoSchool);
                       }}>
                       <NImage
                         class={styles.smallIcon}
@@ -312,7 +324,9 @@ export default defineComponent({
                     <p class={styles.smallTitle}>修改密码</p>
                   </div>
 
-                  <div class={styles.propWrapItem} onClick={() => aboutUs()}>
+                  <div
+                    class={styles.propWrapItem}
+                    onClick={() => oncheckEditStatus(aboutUs)}>
                     <NImage
                       class={styles.smallIcon}
                       src={iconAboutus}

+ 1 - 1
src/store/modules/prepareLessons.ts

@@ -16,7 +16,7 @@ export const usePrepareStore = defineStore('prepare-lessons-store', {
     selectMusicStatus: false, // 乐谱状态
     selectResourceStatus: false, // 资源状态
     isAddResource: false, // 是否添加资源
-    isEditResource: false, // 是否编辑资源
+    isEditResource: false, // 是否编辑资源 - 课件编辑状态
     iseditTrain: false, // 是否编辑训练,
     isAddTrain: false, // 是否添加训练,
     classGroupId: null as any // 班级编号

BIN
src/views/attend-class/image/arrow-active.png


BIN
src/views/attend-class/image/arrow-default.png


+ 6 - 0
src/views/attend-class/index.module.less

@@ -419,6 +419,8 @@
     }
   }
 
+
+
   .modelAttendContent {
     font-size: max(18px, 16px);
     color: #777777;
@@ -850,3 +852,7 @@
     }
   }
 }
+
+.selectClassModal {
+  width: 900px;
+}

+ 128 - 149
src/views/attend-class/index.tsx

@@ -31,10 +31,9 @@ import {
   NDrawerContent,
   NModal,
   NSpace,
-  NButton
-  // NTooltip,
-  // NPopover,
-  // NImage
+  NButton,
+  NCollapse,
+  NCollapseItem
 } from 'naive-ui';
 import CardType from '@/components/card-type';
 import Pen from './component/tools/pen';
@@ -42,37 +41,22 @@ import AudioPay from './component/audio-pay';
 import TrainSettings from './model/train-settings';
 import { useRoute } from 'vue-router';
 import {
+  api_teacherChapterLessonCoursewareDetail,
   courseScheduleUpdate,
   lessonCoursewareDetail,
   lessonPreTrainingPage,
   queryCourseware
 } from '../prepare-lessons/api';
-// import Attentguide from '@/custom-plugins/guide-page/attent-guide';
 import { vaildUrl } from '/src/utils/urlUtils';
 import TimerMeter from '/src/components/timerMeter';
-// import toneImage from '/src/components/layout/images/toneImage.png';
-// import toolbox from '/src/components/layout/images/toolbox.png';
-// import setTimeIcon from '/src/components/layout/images/setTimeIcon.png';
-// import beatIcon from '/src/components/layout/images/beatIcon.png';
-// import toneIcon from '/src/components/layout/images/toneIcon.png';
 import { px2vw } from '/src/utils';
 import PlaceholderTone from '/src/components/layout/modals/placeholderTone';
 import { state as globalState } from '/src/state';
 import Chapter from './model/chapter';
 import { useRouter } from 'vue-router';
 import { useUserStore } from '@/store/modules/users';
-
-// import iconBeatIcon from './new-image/icon-beatIcon.png';
-// import iconChange from './new-image/icon-change.png';
-// import iconDown from './new-image/icon-down.png';
-// import iconMenu from './new-image/icon-menu.png';
 import iconNote from './new-image/icon-note.png';
-// import iconOverClass from './new-image/icon-overclass.png';
-// import iconSetTime from './new-image/icon-setTime.png';
-// import iconToneIcon from './new-image/icon-toneIcon.png';
-// import iconUp from './new-image/icon-up.png';
 import iconWhite from './new-image/icon-white.png';
-// import iconWork from './new-image/icon-work.png';
 
 import rightIconEnd from './image/right_icon1.png';
 import rightIconArrange from './image/right_icon2.png';
@@ -93,6 +77,8 @@ import SelectResources from '../prepare-lessons/model/select-resources';
 import { getStudentAfterWork, getStudentList } from '../studentList/api';
 import TheNoticeBar from '/src/components/TheNoticeBar';
 import ClassWork from './model/class-work';
+import SelectClass from './model/select-class';
+import SourceList from './model/source-list';
 
 export type ToolType = 'init' | 'pen' | 'whiteboard' | 'call';
 export type ToolItem = {
@@ -108,6 +94,10 @@ export default defineComponent({
       type: String,
       default: ''
     },
+    courseId: {
+      type: String,
+      default: ''
+    },
     subjectId: {
       type: [String, Number],
       default: ''
@@ -167,9 +157,9 @@ export default defineComponent({
       handleInit(1);
     });
 
-    const drawerCardRef = ref(); // 资源列表对象
     const data = reactive({
       type: 'class' as '' | 'preview' | 'class', // 预览类型
+      courseId: '' as any, // 课件编号
       subjectId: '' as any, // 声部编号
       lessonCourseId: '' as any, // 教材编号
       lessonCoursewareDetailId: '' as any, // 章节
@@ -188,6 +178,7 @@ export default defineComponent({
       modelAttendStatus: false, // 布置作业提示弹窗
       modalAttendMessage: '本节课未设置课后作业,是否继续?',
       modelTrainStatus: false, // 训练设置
+      selectClassStatus: false, // 选择课件
       homeworkStatus: true, // 布置作业完成时
       removeVisiable: false,
       removeTitle: '',
@@ -216,31 +207,42 @@ export default defineComponent({
 
     const getDetail = async () => {
       try {
-        const res = await queryCourseware({
-          coursewareDetailKnowledgeId: data.detailId,
-          subjectId: data.subjectId,
-          pag: 1,
-          rows: 99
-        });
-        const tempRows = res.data.rows || [];
+        const res = await api_teacherChapterLessonCoursewareDetail(
+          data.courseId
+        );
+
+        const tempRows = res.data.chapterKnowledgeList || [];
         const temp: any = [];
-        tempRows.forEach((row: any) => {
-          if (!row.removeFlag) {
-            temp.push({
-              id: row.id,
-              materialId: row.materialId,
-              coverImg: row.coverImg,
-              type: row.materialType,
-              title: row.materialName,
-              isCollect: !!row.favoriteFlag,
-              isSelected: row.source === 'PLATFORM' ? true : false,
-              content: row.content
-            });
+        const allItem: any = [];
+        tempRows.forEach((row: any, index: number) => {
+          if (!Array.isArray(row.chapterKnowledgeMaterialList)) {
+            return;
           }
+          const childList: any[] = [];
+          row.chapterKnowledgeMaterialList.forEach((child: any) => {
+            if (!child.removeFlag) {
+              childList.push({
+                id: child.id,
+                materialId: child.bizId,
+                coverImg: child.bizInfo.coverImg,
+                type: child.type,
+                title: child.bizInfo.name,
+                isCollect: !!child.favoriteFlag,
+                isSelected: child.source === 'PLATFORM' ? true : false,
+                content: child.bizInfo.content,
+                parentIndex: index
+              });
+            }
+          });
+          temp.push({
+            title: row.name,
+            list: childList
+          });
+          allItem.push(...childList);
         });
 
         data.knowledgePointList = temp;
-        data.itemList = data.knowledgePointList.map((m: any) => {
+        data.itemList = allItem?.map((m: any) => {
           return {
             ...m,
             iframeRef: null,
@@ -254,8 +256,9 @@ export default defineComponent({
         setTimeout(() => {
           data.animationState = 'end';
         }, 500);
-      } catch {
+      } catch (e) {
         //
+        console.log(e);
       }
     };
 
@@ -317,6 +320,7 @@ export default defineComponent({
       // console.log(query, props.preStudentNum, '学生人数');
       // 先取参数,
       data.type = props.type || (query.type as any);
+      data.courseId = props.courseId || query.courseId;
       data.subjectId = props.subjectId || query.subjectId;
       data.detailId = props.detailId || query.detailId;
       data.lessonCourseId = props.lessonCourseId || query.lessonCourseId;
@@ -350,9 +354,11 @@ export default defineComponent({
     const popupData = reactive({
       open: false,
       activeIndex: 0,
+      courseActiveIndex: 0, // 课件选择的第几个
       toolOpen: false, // 工具弹窗控制
       chapterOpen: false, // 切换章节
       chapterDetails: [] as any,
+      courseId: null as any, // 章节编号
       chapterLoading: false // 加载数据
     });
 
@@ -667,11 +673,6 @@ export default defineComponent({
 
     // 上一个知识点, 下一个知识点
     const handlePreAndNext = async (type: string) => {
-      // if (type === 'up') {
-      //   handleSwipeChange(popupData.activeIndex - 1);
-      // } else {
-      //   handleSwipeChange(popupData.activeIndex + 1);
-      // }
       if (type === 'up') {
         // 判断上面是否还有章节
         if (popupData.activeIndex > 0) {
@@ -696,7 +697,7 @@ export default defineComponent({
           lessonIndex--;
 
           if (lessonIndex >= 0) {
-            if (detailItem[lessonIndex].containMaterial) {
+            if (detailItem[lessonIndex].coursewareNum > 0) {
               lessonStatus = true;
               lessonCoursewareDetailId =
                 detailItem[lessonIndex].lessonCoursewareDetailId;
@@ -710,17 +711,8 @@ export default defineComponent({
         }
         // 判断当前章节下面课程是否有内容,否则往上一个章节走
         if (lessonStatus) {
-          popupData.chapterLoading = true;
-          data.detailId = coursewareDetailKnowledgeId;
-          data.lessonCoursewareDetailId = lessonCoursewareDetailId;
-          // 更新上课记录 上课的时候才更新
-          if (data.type !== 'preview') {
-            await classCourseScheduleUpdate();
-          }
-          await getDetail();
-          popupData.activeIndex = data.itemList.length - 1 || 0;
-          popupData.chapterOpen = false;
-          popupData.chapterLoading = false;
+          popupData.courseId = coursewareDetailKnowledgeId;
+          data.selectClassStatus = true;
           return;
         }
 
@@ -731,7 +723,7 @@ export default defineComponent({
             popupData.chapterDetails[detailIndex]?.knowledgeList || [];
           let tempLessonLength = tempDetail.length;
           while (tempLessonLength > 0) {
-            if (tempDetail[tempLessonLength - 1].containMaterial) {
+            if (tempDetail[tempLessonLength - 1].coursewareNum > 0) {
               prevLessonStatus = true;
               lessonCoursewareDetailId =
                 tempDetail[tempLessonLength - 1].lessonCoursewareDetailId;
@@ -750,12 +742,8 @@ export default defineComponent({
 
         // 判断当前章节下面课程是否有内容,否则往上一个章节走
         if (prevLessonStatus) {
-          popupData.chapterLoading = true;
-          data.detailId = coursewareDetailKnowledgeId;
-          data.lessonCoursewareDetailId = lessonCoursewareDetailId;
-          await getDetail();
-          popupData.activeIndex = data.itemList.length - 1 || 0;
-          popupData.chapterLoading = false;
+          popupData.courseId = coursewareDetailKnowledgeId;
+          data.selectClassStatus = true;
           return;
         }
       } else {
@@ -780,7 +768,7 @@ export default defineComponent({
         while (lessonIndex < detailItem.length - 1) {
           lessonIndex++;
           if (lessonIndex >= 0) {
-            if (detailItem[lessonIndex].containMaterial) {
+            if (detailItem[lessonIndex].coursewareNum > 0) {
               lessonStatus = true;
               lessonCoursewareDetailId =
                 detailItem[lessonIndex].lessonCoursewareDetailId;
@@ -793,17 +781,8 @@ export default defineComponent({
         }
         // 判断当前章节下面课程是否有内容,否则往下一个章节走
         if (lessonStatus) {
-          popupData.chapterLoading = true;
-          data.detailId = coursewareDetailKnowledgeId;
-          data.lessonCoursewareDetailId = lessonCoursewareDetailId;
-          // 更新上课记录 上课的时候才更新
-          if (data.type !== 'preview') {
-            await classCourseScheduleUpdate();
-          }
-          await getDetail();
-          popupData.activeIndex = 0;
-          popupData.chapterOpen = false;
-          popupData.chapterLoading = false;
+          popupData.courseId = coursewareDetailKnowledgeId;
+          data.selectClassStatus = true;
           return;
         }
 
@@ -814,7 +793,7 @@ export default defineComponent({
             popupData.chapterDetails[detailIndex]?.knowledgeList || [];
           let tempLessonLength = 0;
           while (tempLessonLength <= tempDetail.length - 1) {
-            if (tempDetail[tempLessonLength].containMaterial) {
+            if (tempDetail[tempLessonLength].coursewareNum > 0) {
               nextLessonStatus = true;
               lessonCoursewareDetailId =
                 tempDetail[tempLessonLength].lessonCoursewareDetailId;
@@ -833,17 +812,8 @@ export default defineComponent({
 
         // 判断当前章节下面课程是否有内容,否则往上一个章节走
         if (nextLessonStatus) {
-          popupData.chapterLoading = true;
-          data.detailId = coursewareDetailKnowledgeId;
-          data.lessonCoursewareDetailId = lessonCoursewareDetailId;
-          // 更新上课记录 上课的时候才更新
-          if (data.type !== 'preview') {
-            await classCourseScheduleUpdate();
-          }
-          await getDetail();
-          popupData.activeIndex = 0;
-          popupData.chapterOpen = false;
-          popupData.chapterLoading = false;
+          popupData.courseId = coursewareDetailKnowledgeId;
+          data.selectClassStatus = true;
           return;
         }
       }
@@ -919,6 +889,13 @@ export default defineComponent({
     //     !listenerKeyUpState.value && toggleListenerKeyUp('add')
     //   }
     // })
+    watch(
+      () => popupData.activeIndex,
+      () => {
+        const item = data.itemList[popupData.activeIndex];
+        popupData.courseActiveIndex = item.parentIndex;
+      }
+    );
 
     const setModalOpen = (status = true) => {
       clearTimeout(activeData.timer);
@@ -1014,7 +991,7 @@ export default defineComponent({
         lessonIndex--;
 
         if (lessonIndex >= 0) {
-          if (detailItem[lessonIndex].containMaterial) {
+          if (detailItem[lessonIndex].coursewareNum > 0) {
             lessonStatus = true;
           }
         }
@@ -1036,7 +1013,7 @@ export default defineComponent({
           popupData.chapterDetails[detailIndex]?.knowledgeList || [];
         let tempLessonLength = tempDetail.length;
         while (tempLessonLength > 0) {
-          if (tempDetail[tempLessonLength - 1].containMaterial) {
+          if (tempDetail[tempLessonLength - 1].coursewareNum > 0) {
             prevLessonStatus = true;
           }
           tempLessonLength--;
@@ -1060,6 +1037,7 @@ export default defineComponent({
       let detailIndex = popupData.chapterDetails.findIndex(
         (item: any) => item.id == data.lessonCoursewareDetailId
       );
+
       const detailItem =
         popupData.chapterDetails[detailIndex]?.knowledgeList || [];
       let lessonIndex = detailItem.findIndex(
@@ -1078,7 +1056,7 @@ export default defineComponent({
       while (lessonIndex < detailItem.length - 1) {
         lessonIndex++;
         if (lessonIndex >= 0) {
-          if (detailItem[lessonIndex].containMaterial) {
+          if (detailItem[lessonIndex].coursewareNum > 0) {
             lessonStatus = true;
           }
         }
@@ -1100,7 +1078,7 @@ export default defineComponent({
           popupData.chapterDetails[detailIndex]?.knowledgeList || [];
         let tempLessonLength = 0;
         while (tempLessonLength <= tempDetail.length - 1) {
-          if (tempDetail[tempLessonLength].containMaterial) {
+          if (tempDetail[tempLessonLength].coursewareNum > 0) {
             nextLessonStatus = true;
           }
           tempLessonLength++;
@@ -1432,7 +1410,6 @@ export default defineComponent({
                   // if (isRender) {
                   //   m.isRender = true;
                   // }
-                  // console.log(isRender, 'isRender', mIndex);
                   return isRender ? (
                     <div
                       key={'index' + mIndex}
@@ -1648,24 +1625,15 @@ export default defineComponent({
                 <TheNoticeBar text={activeName.value || '资源列表'} />
               ),
               default: () => (
-                <div ref={drawerCardRef} id="drawerCardRef">
-                  {data.knowledgePointList.map((item: any, index: number) => {
-                    return (
-                      <div class={[styles.cardContainer, 'drawerCardItemRef']}>
-                        <CardType
-                          item={item}
-                          isActive={popupData.activeIndex === index}
-                          isCollect={false}
-                          isShowCollect={false}
-                          onClick={(item: any) => {
-                            popupData.open = false;
-                            toggleMaterial(item.id);
-                          }}
-                        />
-                      </div>
-                    );
-                  })}
-                </div>
+                <SourceList
+                  knowledgePointList={data.knowledgePointList}
+                  courseActiveIndex={popupData.courseActiveIndex}
+                  activeItem={data.itemList[popupData.activeIndex]}
+                  onConfirm={(item: any) => {
+                    popupData.open = false;
+                    toggleMaterial(item.id);
+                  }}
+                />
               )
             }}
           </NDrawerContent>
@@ -1677,32 +1645,17 @@ export default defineComponent({
           class={styles.drawerContainer}
           onAfterLeave={handleClosePopup}
           showMask={false}
-          displayDirective="show">
+          displayDirective="show"
+          maskClosable={data.selectClassStatus ? false : true}>
           <NDrawerContent title="切换章节" closable>
             <Chapter
               treeList={popupData.chapterDetails}
               itemActive={data.detailId as any}
               onHandleSelect={async (val: any) => {
-                popupData.chapterLoading = true;
-
-                try {
-                  data.detailId = val.itemActive;
-                  const ids = formatParentId(
-                    val.itemActive,
-                    popupData.chapterDetails
-                  );
-                  data.lessonCoursewareDetailId = ids[0];
-                  // 更新上课记录 上课的时候才更新
-                  if (data.type !== 'preview') {
-                    await classCourseScheduleUpdate();
-                  }
-                  await getDetail();
-                  popupData.activeIndex = 0;
-                  popupData.chapterOpen = false;
-                } catch {
-                  //
-                }
-                popupData.chapterLoading = false;
+                // itemActive: child.id,
+                // itemName: child.name
+                popupData.courseId = val.itemActive;
+                data.selectClassStatus = true;
               }}
             />
           </NDrawerContent>
@@ -1734,19 +1687,56 @@ export default defineComponent({
           />
         )}
 
+        {/* 选择课件 */}
+        <NModal
+          transformOrigin="center"
+          v-model:show={data.selectClassStatus}
+          preset="card"
+          class={[
+            'modalTitle background',
+            // styles.attendClassModal,
+            styles.selectClassModal
+          ]}
+          title={'选择课件'}>
+          <SelectClass
+            classId={data.classId}
+            courseId={popupData.courseId}
+            subjectId={data.subjectId}
+            onConfirm={async (val: any) => {
+              popupData.chapterLoading = true;
+              try {
+                data.detailId = val.itemActive;
+                data.courseId = val.chapterId;
+                const ids = formatParentId(
+                  val.itemActive,
+                  popupData.chapterDetails
+                );
+                data.lessonCoursewareDetailId = ids[0];
+                // 更新上课记录 上课的时候才更新
+                if (data.type !== 'preview') {
+                  await classCourseScheduleUpdate();
+                }
+                await getDetail();
+                popupData.activeIndex = 0;
+                popupData.chapterOpen = false;
+                data.selectClassStatus = false;
+              } catch {
+                //
+              }
+              popupData.chapterLoading = false;
+            }}
+          />
+        </NModal>
+
         {/* 布置作业 */}
         <NModal
           transformOrigin="center"
           v-model:show={data.modelAttendStatus}
           preset="card"
-          // class={styles.attendClassModal}
           title={'课后作业'}
           class={['modalTitle', styles.removeVisiable]}>
           <div class={styles.studentRemove}>
             <p>{data.modalAttendMessage}</p>
-            {/* <div class={styles.modelAttendContent}>
-              {data.modalAttendMessage}
-            </div> */}
             <NSpace class={styles.btnGroupModal} justify="center">
               <NButton
                 type="default"
@@ -1777,17 +1767,6 @@ export default defineComponent({
           preset="card"
           class={[styles.attendClassModal, styles.trainClassModal]}
           title={'作业设置'}>
-          {/* <TrainSettings
-            detailId={data.detailId}
-            subjectId={data.subjectId}
-            courseScheduleId={data.classId}
-            classGroupId={data.classGroupId}
-            onClose={() => (data.modelTrainStatus = false)}
-            onConfirm={() => {
-              // 布置完作业之后直接关闭
-              data.modelTrainStatus = false;
-            }}
-          /> */}
           <ClassWork
             detailId={data.detailId}
             subjectId={data.subjectId}

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

@@ -115,7 +115,7 @@ export default defineComponent({
                       if (itemActive.value == child.id) {
                         return;
                       }
-                      if (!child.containMaterial) {
+                      if (child.coursewareNum <= 0) {
                         message.error('该章节暂无课件');
                         return;
                       }

+ 34 - 0
src/views/attend-class/model/select-class/index.module.less

@@ -0,0 +1,34 @@
+.selectClass {
+  padding: 27px 0;
+}
+
+.selectClassScroll {
+  min-height: 60vh;
+  max-height: 60vh;
+  padding: 0 33px
+}
+
+.list {
+  display: flex;
+  flex-flow: row wrap;
+  justify-content: flex-start;
+  padding: 0 0 12px;
+  gap: 20px 0;
+  margin: 0 -10px 0;
+  min-height: 300px;
+
+  &.listEmpty {
+    display: flex;
+    align-items: center;
+    min-height: 60vh;
+  }
+
+
+  .itemWrap {
+    width: calc(100% / 3);
+
+    .itemWrapBox {
+      padding: 0 10px;
+    }
+  }
+}

+ 101 - 0
src/views/attend-class/model/select-class/index.tsx

@@ -0,0 +1,101 @@
+import { PropType, defineComponent, onMounted, reactive } from 'vue';
+import styles from './index.module.less';
+import { teacherChapterLessonCoursewareList } from '/src/views/prepare-lessons/api';
+import { NScrollbar, NSpin } from 'naive-ui';
+import CoursewareType from '/src/views/prepare-lessons/model/courseware-type';
+import TheEmpty from '/src/components/TheEmpty';
+
+export default defineComponent({
+  name: 'select-class',
+  props: {
+    courseId: {
+      type: String as PropType<'' | null>,
+      default: ''
+    },
+    subjectId: {
+      type: String,
+      default: ''
+    },
+    classId: {
+      type: String,
+      default: ''
+    }
+  },
+  emits: ['confirm', 'close'],
+  setup(props, { emit }) {
+    const forms = reactive({
+      loading: false,
+      tableList: [] as any
+    });
+    const getDetail = async () => {
+      forms.loading = true;
+      try {
+        // 如果是上课则查询班级声部,预览查询全部
+        const { data } = await teacherChapterLessonCoursewareList({
+          coursewareDetailKnowledgeId: props.courseId,
+          subjectId: props.classId ? props.subjectId : null
+        });
+
+        if (!Array.isArray(data)) {
+          return;
+        }
+        const tempList: any = [];
+        data.forEach((item: any) => {
+          const firstItem: any =
+            item.chapterKnowledgeList[0]?.chapterKnowledgeMaterialList[0];
+          tempList.push({
+            id: item.id,
+            openFlag: item.openFlag,
+            openFlagEnable: item.openFlagEnable,
+            subjectNames: item.subjectNames,
+            fromChapterLessonCoursewareId: item.fromChapterLessonCoursewareId,
+            name: item.name,
+            coverImg: firstItem?.bizInfo.coverImg,
+            type: firstItem?.bizInfo.type
+          });
+        });
+        forms.tableList = tempList;
+      } catch {
+        //
+      }
+      forms.loading = false;
+    };
+
+    onMounted(() => {
+      getDetail();
+    });
+    return () => (
+      <div class={styles.selectClass}>
+        <NSpin show={forms.loading}>
+          <NScrollbar class={styles.selectClassScroll}>
+            <div
+              class={[
+                styles.list,
+                !forms.loading &&
+                  forms.tableList.length <= 0 &&
+                  styles.listEmpty
+              ]}>
+              {forms.tableList.map((item: any) => (
+                <div class={[styles.itemWrap, styles.itemBlock, 'row-nav']}>
+                  <div class={styles.itemWrapBox}>
+                    <CoursewareType
+                      isShowPreviewBtn
+                      item={item}
+                      onClick={() => {
+                        emit('confirm', {
+                          itemActive: props.courseId,
+                          chapterId: item.id
+                        });
+                      }}
+                    />
+                  </div>
+                </div>
+              ))}
+              {!forms.loading && forms.tableList.length <= 0 && <TheEmpty />}
+            </div>
+          </NScrollbar>
+        </NSpin>
+      </div>
+    );
+  }
+});

+ 81 - 0
src/views/attend-class/model/source-list/index.module.less

@@ -0,0 +1,81 @@
+.listSection {
+  padding: 20px;
+}
+
+.treeParent {
+  transition: height 1s ease-in-out;
+
+  .cardContainer {
+    margin-bottom: 17px;
+  }
+}
+
+.treeChild {
+  line-height: 54px;
+}
+
+.treeItem {
+  display: flex;
+  align-items: center;
+  line-height: 54px;
+  border-radius: 10px;
+  padding: 0 5px;
+  cursor: pointer;
+  border-radius: 10px;
+  font-size: max(17px, 12Px);
+
+  &:hover {
+    background: #F5F6FA;
+  }
+
+  .title {
+    padding-left: 8px;
+    overflow: hidden;
+    white-space: nowrap;
+    text-overflow: ellipsis;
+    max-width: 280px !important;
+    color: rgba(0, 0, 0, .5);
+    display: flex;
+    align-items: center;
+
+    &.titleSelect {
+      color: #1677FF;
+      font-weight: bold;
+    }
+  }
+
+  .arrow {
+    display: inline-block;
+    width: 14px;
+    height: 15px;
+    background: url('../../image/arrow-default.png') no-repeat center;
+    background-size: contain;
+
+    &.arrowSelect {
+      background: url('../../image/arrow-active.png') no-repeat center;
+      background-size: contain;
+    }
+  }
+
+  .childArrow {
+    width: 12px;
+  }
+
+  &.childItem {
+    padding-left: 30px;
+    font-size: max(15px, 12Px);
+
+    .title {
+      color: #131415;
+    }
+  }
+
+  &.childSelect {
+    background: #F5F6FA;
+
+    .title {
+      color: var(--n-color);
+      font-weight: bold;
+    }
+  }
+}

+ 91 - 0
src/views/attend-class/model/source-list/index.tsx

@@ -0,0 +1,91 @@
+import { NCollapse, NCollapseItem } from 'naive-ui';
+import { computed, defineComponent, ref, watch } from 'vue';
+import CardType from '/src/components/card-type';
+import styles from './index.module.less';
+
+export default defineComponent({
+  name: 'source-list',
+  props: {
+    knowledgePointList: {
+      type: Array,
+      default: () => []
+    },
+    activeItem: {
+      type: Object,
+      default: () => ({})
+    },
+    /** 当前播放的是第几个知识点组 */
+    courseActiveIndex: {
+      type: Number,
+      default: 0
+    }
+  },
+  emits: ['confirm'],
+  setup(props, { emit }) {
+    const parentIndex = ref(props.courseActiveIndex);
+
+    watch(
+      () => props.courseActiveIndex,
+      () => {
+        parentIndex.value = props.courseActiveIndex;
+      }
+    );
+
+    const childIndex = computed(() => {
+      let index = 0;
+      props.knowledgePointList.forEach((item: any) => {
+        item.list.forEach((child: any, j: number) => {
+          if (child.id === props.activeItem.id) {
+            index = j;
+          }
+        });
+      });
+      return index;
+    });
+    return () => (
+      <div class={[styles.listSection]} id="drawerCardRef">
+        {props.knowledgePointList.map((item: any, index: number) => (
+          <div class={styles.treeParent} key={'parent' + index}>
+            <div
+              class={[styles.treeItem, styles.parentItem]}
+              onClick={() => {
+                parentIndex.value = index;
+              }}>
+              <span
+                class={[
+                  styles.arrow,
+                  parentIndex.value === index ? styles.arrowSelect : ''
+                ]}></span>
+              <p
+                class={[
+                  styles.title,
+                  parentIndex.value === index ? styles.titleSelect : ''
+                ]}>
+                {item.title}
+              </p>
+            </div>
+
+            {parentIndex.value === index &&
+              item.list &&
+              item.list.map((child: any, j: number) => (
+                <div class={[styles.cardContainer, 'drawerCardItemRef']}>
+                  <CardType
+                    item={child}
+                    isActive={
+                      childIndex.value === j &&
+                      parentIndex.value === props.courseActiveIndex
+                    }
+                    isCollect={false}
+                    isShowCollect={false}
+                    onClick={() => {
+                      emit('confirm', child);
+                    }}
+                  />
+                </div>
+              ))}
+          </div>
+        ))}
+      </div>
+    );
+  }
+});

+ 1 - 11
src/views/home/components/trainData.tsx

@@ -1,22 +1,12 @@
-import {
-  Ref,
-  computed,
-  defineComponent,
-  onMounted,
-  reactive,
-  ref,
-  watch
-} from 'vue';
+import { Ref, computed, defineComponent, onMounted, reactive, ref } from 'vue';
 import styles from '../index2.module.less';
 import { NButton, NDataTable, NNumberAnimation, NSpace } from 'naive-ui';
-import numeral from 'numeral';
 import { useECharts } from '@/hooks/web/useECharts';
 import Pagination from '/src/components/pagination';
 import { getTimes } from '/src/utils/dateFormat';
 import { getTrainingStat } from '../../data-module/api';
 import { useRoute, useRouter } from 'vue-router';
 import { getTrainingList } from '../../classList/api';
-import dayjs from 'dayjs';
 import TheEmpty from '/src/components/TheEmpty';
 
 export default defineComponent({

+ 11 - 4
src/views/prepare-lessons/api.ts

@@ -254,8 +254,8 @@ export const api_addByOpenCourseware = (params: any) => {
 /**
  * 课件 新增课件
  */
-export const api_add = (params: any) => {
-  return request.post('/edu-app//teacherChapterLessonCourseware/add', {
+export const api_teacherChapterLessonCoursewareAdd = (params: any) => {
+  return request.post('/edu-app/teacherChapterLessonCourseware/add', {
     data: params
   });
 };
@@ -263,7 +263,7 @@ export const api_add = (params: any) => {
 /**
  * 课件 删除我的课件
  */
-export const api_eacherChapterLessonCoursewareRemove = (params: any) => {
+export const api_teacherChapterLessonCoursewareRemove = (params: any) => {
   return request.post(
     '/edu-app/teacherChapterLessonCourseware/remove?id=' + params.id,
     {
@@ -275,8 +275,15 @@ export const api_eacherChapterLessonCoursewareRemove = (params: any) => {
 /**
  * 课件 修改我的课件
  */
-export const api_eacherChapterLessonCoursewareUpdate = (params: any) => {
+export const api_teacherChapterLessonCoursewareUpdate = (params: any) => {
   return request.post('/edu-app/teacherChapterLessonCourseware/update', {
     data: params
   });
 };
+
+/**
+ * 课件 课件详情
+ */
+export const api_teacherChapterLessonCoursewareDetail = (id: string) => {
+  return request.get('/edu-app/teacherChapterLessonCourseware/detail/' + id);
+};

+ 37 - 21
src/views/prepare-lessons/components/directory-main/index.tsx

@@ -138,6 +138,12 @@ export default defineComponent({
       }
     };
 
+    const clickDetail = (child: any) => {
+      prepareStore.setSelectKey(child.id);
+      prepareStore.setLessonCoursewareId(child.lessonCoursewareId);
+      prepareStore.setLessonCoursewareDetailId(child.lessonCoursewareDetailId);
+    };
+
     const onChangeClass = async (item: any) => {
       show.value = true;
       forms.lastUseCoursewareId = item.lastUseCoursewareId;
@@ -147,6 +153,24 @@ export default defineComponent({
       show.value = false;
     };
 
+    const changeCourseware = (item: any) => {
+      prepareStore.setBaseCourseware(item);
+      prepareStore.setSubjectList(item.subjectList);
+      const index = item.subjectList.findIndex(
+        (subject: any) => subject.id == prepareStore.getSubjectId
+      );
+      // 判断教材里面是否有当前选择的声部,如果没有则默认选择第一个
+      if (index < 0) {
+        const subjectId = item.subjectList[0].id
+          ? Number(item.subjectList[0].id)
+          : '';
+        prepareStore.setSubjectId(subjectId);
+      }
+
+      getLessonCoursewareDetail();
+      setLastUseCoursewareId(item.id);
+    };
+
     onMounted(async () => {
       show.value = true;
       await getLessonCourseware();
@@ -255,13 +279,13 @@ export default defineComponent({
                             : ''
                         ]}
                         onClick={() => {
-                          prepareStore.setSelectKey(child.id);
-                          prepareStore.setLessonCoursewareId(
-                            child.lessonCoursewareId
-                          );
-                          prepareStore.setLessonCoursewareDetailId(
-                            child.lessonCoursewareDetailId
-                          );
+                          if (prepareStore.getIsEditResource) {
+                            eventGlobal.emit('pageBeforeLeave', () =>
+                              clickDetail(child)
+                            );
+                          } else {
+                            clickDetail(child);
+                          }
                         }}>
                         <span class={styles.childArrow}></span>
                         <p class={styles.title}>{child.name}</p>
@@ -287,21 +311,13 @@ export default defineComponent({
           <SelectLessonware
             onClose={() => (forms.coursewareStatus = false)}
             onConfirm={(item: any) => {
-              prepareStore.setBaseCourseware(item);
-              prepareStore.setSubjectList(item.subjectList);
-              const index = item.subjectList.findIndex(
-                (subject: any) => subject.id == prepareStore.getSubjectId
-              );
-              // 判断教材里面是否有当前选择的声部,如果没有则默认选择第一个
-              if (index < 0) {
-                const subjectId = item.subjectList[0].id
-                  ? Number(item.subjectList[0].id)
-                  : '';
-                prepareStore.setSubjectId(subjectId);
+              if (prepareStore.getIsEditResource) {
+                eventGlobal.emit('pageBeforeLeave', () =>
+                  changeCourseware(item)
+                );
+              } else {
+                changeCourseware(item);
               }
-
-              getLessonCoursewareDetail();
-              setLastUseCoursewareId(item.id);
             }}
           />
         </NModal>

+ 12 - 1
src/views/prepare-lessons/components/lesson-main/courseware-presets/index.module.less

@@ -112,6 +112,11 @@
         width: 25px;
         height: 25px;
       }
+
+      .disabled {
+        opacity: 0.4;
+        cursor: not-allowed;
+      }
     }
   }
 }
@@ -151,7 +156,7 @@
   padding: 0 10px;
 }
 
-.attendClassModal {
+.attendClassModal1 {
   width: 1200px;
   border-radius: 16px;
   overflow: hidden;
@@ -190,4 +195,10 @@
       }
     }
   }
+}
+
+.attendClassModal {
+  width: 800px;
+  border-radius: 16px;
+  overflow: hidden;
 }

+ 276 - 75
src/views/prepare-lessons/components/lesson-main/courseware-presets/index.tsx

@@ -1,4 +1,4 @@
-import { defineComponent, onMounted, reactive, watch } from 'vue';
+import { defineComponent, onMounted, reactive, ref, watch } from 'vue';
 import styles from './index.module.less';
 import {
   NButton,
@@ -19,17 +19,21 @@ import iconSlideRight from '../../../images/icon-slide-right.png';
 import CoursewareType from '../../../model/courseware-type';
 import TheEmpty from '/src/components/TheEmpty';
 import RelatedClass from '../../../model/related-class';
+import { state } from '/src/state';
 import { useResizeObserver } from '@vueuse/core';
+import AttendClass from '/src/views/prepare-lessons/model/attend-class';
 import {
   api_addByOpenCourseware,
-  api_eacherChapterLessonCoursewareRemove,
+  api_teacherChapterLessonCoursewareRemove,
   api_queryOpenCoursewareByPage,
   api_updateCoursewareInfo,
-  teacherChapterLessonCoursewareList
+  teacherChapterLessonCoursewareList,
+  courseScheduleStart
 } from '../../../api';
-import { useRoute } from 'vue-router';
+import { useRoute, useRouter } from 'vue-router';
 import TheMessageDialog from '/src/components/TheMessageDialog';
-import { eventGlobal } from '/src/utils';
+import { eventGlobal, fscreen } from '/src/utils';
+import PreviewWindow from '/src/views/preview-window';
 
 export default defineComponent({
   name: 'courseware-presets',
@@ -38,9 +42,11 @@ export default defineComponent({
     const prepareStore = usePrepareStore();
     const message = useMessage();
     const route = useRoute();
+    const router = useRouter();
     const localStorageSubjectId = localStorage.getItem(
       'prepareLessonSubjectId'
     );
+
     const forms = reactive({
       // 选取参数带的,后取缓存
       messageLoading: false,
@@ -48,8 +54,10 @@ export default defineComponent({
         ? Number(route.query.subjectId)
         : localStorageSubjectId
         ? Number(localStorageSubjectId)
-        : null,
+        : '',
       courseScheduleSubjectId: route.query.courseScheduleSubjectId,
+      classGroupId: route.query.classGroupId,
+      preStudentNum: route.query.preStudentNum,
       bodyWidth: '100%',
       loading: false,
       openLoading: false,
@@ -61,7 +69,17 @@ export default defineComponent({
       editTitle: null,
       editBtnLoading: false,
       preRemoveVisiable: false,
-      carouselIndex: 0
+      carouselIndex: 0,
+      showAttendClass: false,
+      attendClassType: 'change', //
+      attendClassItem: {} as any,
+      previewModal: false,
+      previewParams: {
+        type: '',
+        courseId: '',
+        subjectId: '',
+        detailId: ''
+      } as any
     });
 
     const getCoursewareList = async () => {
@@ -70,7 +88,7 @@ export default defineComponent({
         // 判断是否有选择对应的课件 或声部
         if (!prepareStore.getSelectKey) return (forms.loading = false);
         const { data } = await teacherChapterLessonCoursewareList({
-          subjectId: prepareStore.getSubjectId,
+          subjectId: forms.subjectId,
           coursewareDetailKnowledgeId: prepareStore.getSelectKey
         });
         if (!Array.isArray(data)) {
@@ -91,7 +109,6 @@ export default defineComponent({
             type: firstItem?.bizInfo.type
           });
         });
-
         forms.tableList = tempList;
       } catch {
         //
@@ -106,7 +123,7 @@ export default defineComponent({
         // 判断是否有选择对应的课件 或声部
         if (!prepareStore.getSelectKey) return (forms.openLoading = false);
         const { data } = await api_queryOpenCoursewareByPage({
-          subjectId: prepareStore.getSubjectId,
+          subjectId: forms.subjectId,
           coursewareDetailKnowledgeId: prepareStore.getSelectKey,
           page: 1,
           rows: 20
@@ -132,13 +149,21 @@ export default defineComponent({
           });
         });
 
-        forms.openTableList = tempList;
+        forms.openTableList = chunkArray(tempList, 4);
       } catch {
         //
       }
       forms.openLoading = false;
     };
 
+    const chunkArray = (array: any, size: number) => {
+      const result = [];
+      for (let i = 0; i < array.length; i += size) {
+        result.push(array.slice(i, i + size));
+      }
+      return result;
+    };
+
     // 监听选择的key 左侧选择了其它的课
     watch(
       () => [prepareStore.getSelectKey, prepareStore.getSubjectId],
@@ -162,6 +187,13 @@ export default defineComponent({
       }
     );
 
+    watch(
+      () => prepareStore.getSubjectList,
+      () => {
+        checkSubjectIds();
+      }
+    );
+
     const checkSubjectIds = () => {
       const subjectList = prepareStore.getSubjectList;
 
@@ -223,14 +255,14 @@ export default defineComponent({
       // 获取教材分类列表
       checkSubjectIds();
 
-      useResizeObserver(
-        document.querySelector('#coursewarePresets') as HTMLElement,
-        (entries: any) => {
-          const entry = entries[0];
-          const { width } = entry.contentRect;
-          forms.bodyWidth = width + 'px';
-        }
-      );
+      // useResizeObserver(
+      //   document.querySelector('#coursewarePresets') as HTMLElement,
+      //   (entries: any) => {
+      //     const entry = entries[0];
+      //     const { width } = entry.contentRect;
+      //     forms.bodyWidth = width + 'px';
+      //   }
+      // );
 
       await getCoursewareList();
       await getOpenCoursewareList();
@@ -255,7 +287,7 @@ export default defineComponent({
     const onRemove = async () => {
       forms.messageLoading = true;
       try {
-        await api_eacherChapterLessonCoursewareRemove({
+        await api_teacherChapterLessonCoursewareRemove({
           id: forms.selectItem.id
         });
         message.success('删除成功');
@@ -284,6 +316,95 @@ export default defineComponent({
         forms.messageLoading = false;
       }, 100);
     };
+
+    // 预览上课
+    const onPreviewAttend = (id: string) => {
+      // 判断是否在应用里面
+      if (window.matchMedia('(display-mode: standalone)').matches) {
+        state.application = window.matchMedia(
+          '(display-mode: standalone)'
+        ).matches;
+        forms.previewModal = true;
+        fscreen();
+        forms.previewParams = {
+          type: 'preview',
+          courseId: id,
+          subjectId: prepareStore.getSubjectId,
+          detailId: prepareStore.getSelectKey,
+          lessonCourseId: prepareStore.getBaseCourseware.id
+        };
+      } else {
+        const { href } = router.resolve({
+          path: '/attend-class',
+          query: {
+            type: 'preview',
+            courseId: id,
+            subjectId: prepareStore.getSubjectId,
+            detailId: prepareStore.getSelectKey,
+            lessonCourseId: prepareStore.getBaseCourseware.id
+          }
+        });
+        window.open(href, +new Date() + '');
+      }
+    };
+
+    const onStartClass = async (item: any, classGroupId: any) => {
+      console.log(item, classGroupId);
+      if (classGroupId) {
+        // 开始上课
+        const res = await courseScheduleStart({
+          lessonCoursewareKnowledgeDetailId: prepareStore.selectKey,
+          classGroupId: classGroupId,
+          useChapterLessonCoursewareId: item.id,
+          subjectId: prepareStore.getSubjectId
+        });
+        if (window.matchMedia('(display-mode: standalone)').matches) {
+          state.application = window.matchMedia(
+            '(display-mode: standalone)'
+          ).matches;
+          forms.previewModal = true;
+          fscreen();
+          forms.previewParams = {
+            type: 'class',
+            classGroupId: classGroupId,
+            courseId: item.id,
+            subjectId: prepareStore.getSubjectId,
+            detailId: prepareStore.getSelectKey,
+            classId: res.data,
+            lessonCourseId: prepareStore.getBaseCourseware.id,
+            preStudentNum: forms.preStudentNum
+          };
+        } else {
+          const { href } = router.resolve({
+            path: '/attend-class',
+            query: {
+              type: 'class',
+              classGroupId: classGroupId,
+              courseId: item.id,
+              subjectId: prepareStore.getSubjectId,
+              detailId: prepareStore.getSelectKey,
+              classId: res.data,
+              lessonCourseId: prepareStore.getBaseCourseware.id,
+              preStudentNum: forms.preStudentNum
+            }
+          });
+          window.open(href, +new Date() + '');
+        }
+      } else {
+        forms.showAttendClass = true;
+        forms.attendClassType = 'change';
+        forms.attendClassItem = item;
+      }
+    };
+
+    const carouselRef = ref();
+    const onChangeSlide = (type: 'left' | 'right') => {
+      if (type === 'left') {
+        carouselRef.value?.prev();
+      } else if (type === 'right') {
+        carouselRef.value?.next();
+      }
+    };
     return () => (
       <div class={styles.coursewarePresetsContainer}>
         <NScrollbar class={styles.coursewarePresets}>
@@ -304,7 +425,7 @@ export default defineComponent({
               ]}
               labelField="name"
               valueField="id"
-              value={prepareStore.getSubjectId}
+              v-model:value={forms.subjectId}
               onUpdate:value={(val: any) => {
                 prepareStore.setSubjectId(val);
                 // 保存
@@ -334,11 +455,23 @@ export default defineComponent({
                         operate
                         isEditName
                         item={item}
+                        onClick={() => onPreviewAttend(item.id)}
                         onEditName={() => {
                           forms.selectItem = item;
                           forms.editTitle = item.name;
                           forms.editTitleVisiable = true;
                         }}
+                        onEdit={() => {
+                          //
+                          eventGlobal.emit('teacher-slideshow', true);
+                          emit('change', {
+                            status: true,
+                            groupItem: { id: item.id }
+                          });
+                        }}
+                        onStartClass={() =>
+                          onStartClass(item, forms.classGroupId)
+                        }
                         onDelete={() => {
                           forms.selectItem = item;
                           forms.preRemoveVisiable = true;
@@ -352,68 +485,94 @@ export default defineComponent({
             </NSpin>
           </div>
 
-          <div class={[styles.title, styles.line]}>
-            <div class={styles.titleLeft}>
-              <i class={[styles.icon, styles.iconCourseware]}></i>
-              相关课件
-              {forms.openTableList.length > 4 && (
-                <span
-                  class={styles.more}
-                  onClick={() => (forms.showRelatedClass = true)}>
-                  查看更多
-                  <NIcon>
-                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
-                      <path
-                        d="M8.59 16.59L13.17 12L8.59 7.41L10 6l6 6l-6 6l-1.41-1.41z"
-                        fill="currentColor"></path>
-                    </svg>
-                  </NIcon>
-                </span>
-              )}
-            </div>
-
-            {forms.openTableList.length > 4 && (
-              <NSpace class={styles.swipeControll}>
-                <div>
-                  <NImage
-                    previewDisabled
-                    class={[styles.leftIcon]}
-                    src={iconSlideRight}
-                  />
-                </div>
-                <div>
-                  <NImage previewDisabled src={iconSlideRight} />
+          {forms.openTableList.length > 0 && (
+            <>
+              <div class={[styles.title, styles.line]}>
+                <div class={styles.titleLeft}>
+                  <i class={[styles.icon, styles.iconCourseware]}></i>
+                  相关课件
+                  {forms.openTableList.length > 1 && (
+                    <span
+                      class={styles.more}
+                      onClick={() => (forms.showRelatedClass = true)}>
+                      查看更多
+                      <NIcon>
+                        <svg
+                          xmlns="http://www.w3.org/2000/svg"
+                          viewBox="0 0 24 24">
+                          <path
+                            d="M8.59 16.59L13.17 12L8.59 7.41L10 6l6 6l-6 6l-1.41-1.41z"
+                            fill="currentColor"></path>
+                        </svg>
+                      </NIcon>
+                    </span>
+                  )}
                 </div>
-              </NSpace>
-            )}
-          </div>
 
-          <NSpin show={forms.openLoading} class={styles.openLoading}>
-            <NCarousel
-              slidesPerView={4}
-              loop={false}
-              style={{ width: forms.bodyWidth }}
-              v-model:currentIndex={forms.carouselIndex}>
-              {forms.openTableList.map((item: any) => (
-                <div class={[styles.itemWrap, styles.itemBlock, 'row-nav']}>
-                  <div class={styles.itemWrapBox}>
-                    <CoursewareType
-                      isShowAdd
-                      item={item}
-                      onAdd={() => onAddCourseware(item)}
-                    />
-                  </div>
-                </div>
-              ))}
-            </NCarousel>
-          </NSpin>
+                {forms.openTableList.length > 1 && (
+                  <NSpace class={styles.swipeControll}>
+                    <div onClick={() => onChangeSlide('left')}>
+                      <NImage
+                        previewDisabled
+                        class={[
+                          styles.leftIcon,
+                          forms.carouselIndex === 0 && styles.disabled
+                        ]}
+                        src={iconSlideRight}
+                      />
+                    </div>
+                    <div onClick={() => onChangeSlide('right')}>
+                      <NImage
+                        class={
+                          forms.carouselIndex ==
+                            forms.openTableList.length - 4 && styles.disabled
+                        }
+                        previewDisabled
+                        src={iconSlideRight}
+                      />
+                    </div>
+                  </NSpace>
+                )}
+              </div>
+
+              <NSpin show={forms.openLoading} class={styles.openLoading}>
+                <NCarousel
+                  slidesPerView={1}
+                  loop={false}
+                  ref={carouselRef}
+                  // style={{ width: forms.bodyWidth }}
+                  v-model:currentIndex={forms.carouselIndex}>
+                  {forms.openTableList.map((item: any) => (
+                    <div class={[styles.list, styles.listSame]}>
+                      {item.map((child: any) => (
+                        <div
+                          class={[
+                            styles.itemWrap,
+                            styles.itemBlock,
+                            'row-nav'
+                          ]}>
+                          <div class={styles.itemWrapBox}>
+                            <CoursewareType
+                              isShowAdd
+                              item={child}
+                              onAdd={() => onAddCourseware(child)}
+                            />
+                          </div>
+                        </div>
+                      ))}
+                    </div>
+                  ))}
+                </NCarousel>
+              </NSpin>
+            </>
+          )}
         </NScrollbar>
 
         <NModal
           v-model:show={forms.showRelatedClass}
           preset="card"
           showIcon={false}
-          class={['modalTitle background', styles.attendClassModal]}
+          class={['modalTitle background', styles.attendClassModal1]}
           title={'相关课件'}
           blockScroll={false}>
           <RelatedClass
@@ -472,6 +631,48 @@ export default defineComponent({
             onConfirm={() => onRemove()}
           />
         </NModal>
+
+        {/* 应用内预览或上课 */}
+        <PreviewWindow
+          v-model:show={forms.previewModal}
+          type="attend"
+          params={forms.previewParams}
+        />
+
+        <NModal
+          v-model:show={forms.showAttendClass}
+          preset="card"
+          showIcon={false}
+          class={['modalTitle background', styles.attendClassModal]}
+          title={'选择班级'}
+          blockScroll={false}>
+          <AttendClass
+            onClose={() => (forms.showAttendClass = false)}
+            type={forms.attendClassType}
+            onPreview={(item: any) => {
+              if (window.matchMedia('(display-mode: standalone)').matches) {
+                state.application = window.matchMedia(
+                  '(display-mode: standalone)'
+                ).matches;
+                forms.previewModal = true;
+                forms.previewParams = {
+                  ...item
+                };
+              } else {
+                const { href } = router.resolve({
+                  path: '/attend-class',
+                  query: {
+                    ...item
+                  }
+                });
+                window.open(href, +new Date() + '');
+              }
+            }}
+            onConfirm={async (item: any) => {
+              onStartClass(forms.attendClassItem, item.classGroupId);
+            }}
+          />
+        </NModal>
       </div>
     );
   }

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

@@ -322,6 +322,22 @@
       height: 100%;
       padding: 0 6px;
     }
+
+    .itemOperation {
+      position: absolute;
+      top: 0;
+      right: 10px;
+      z-index: 98;
+      cursor: move;
+    }
+
+    .iconDelete {
+      width: 27px;
+      height: 27px;
+      margin-top: 8px;
+      margin-right: 8px;
+      cursor: pointer;
+    }
   }
 
   :global {
@@ -338,65 +354,15 @@
   overflow: hidden;
 }
 
-.itemBlock {
-  position: relative;
-
-  .itemOperation {
-    position: absolute;
-    top: 0;
-    left: 10px;
-
-    width: calc(100% - 20px);
-    height: 100%;
-    text-align: right;
-    z-index: 98;
-    cursor: move;
-  }
-
-  .iconDelete {
-    width: 27px;
-    height: 27px;
-    margin-top: 8px;
-    margin-right: 8px;
-    cursor: pointer;
-  }
-}
 
-.removeVisiable {
-  width: 432px;
+.addCourseware {
+  width: 532px;
 
   :global {
     .n-card-header {
       font-size: max(22px, 16Px);
     }
   }
-
-
-  .studentRemove {
-    padding: 20px 40px 0;
-
-    p {
-      font-size: max(18px, 14Px);
-      color: #777777;
-      line-height: 30px;
-      text-align: center;
-
-      span {
-        color: #EA4132;
-      }
-    }
-  }
-
-  .btnGroupModal {
-    padding: 32px 0;
-
-    :global {
-      .n-button {
-        height: 47px;
-        min-width: 156px;
-      }
-    }
-  }
 }
 
 .removeVisiable1 {
@@ -472,4 +438,8 @@
 
 .subjectSyncModal {
   width: 1070px;
+}
+
+.addOtherSource {
+  width: 726px;
 }

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

@@ -23,47 +23,58 @@ import {
   NIcon
 } from 'naive-ui';
 import CardType from '/src/components/card-type';
-import AttendClass from '/src/views/prepare-lessons/model/attend-class';
+// import AttendClass from '/src/views/prepare-lessons/model/attend-class';
 import { usePrepareStore } from '/src/store/modules/prepareLessons';
 import { useCatchStore } from '/src/store/modules/catchData';
-import TheEmpty from '/src/components/TheEmpty';
+// import TheEmpty from '/src/components/TheEmpty';
 import {
-  api_add,
-  courseScheduleStart,
-  queryCourseware,
-  saveCourseware,
-  teacherKnowledgeMaterialDelete
+  api_teacherChapterLessonCoursewareAdd,
+  api_teacherChapterLessonCoursewareUpdate,
+  api_teacherChapterLessonCoursewareDetail,
+  // courseScheduleStart,
+  // queryCourseware,
+  saveCourseware
 } from '../../../api';
 import Draggable from 'vuedraggable';
 import iconDelete from '../../../images/icon-delete.png';
 import iconAddMusic from '../../../images/icon-add-music.png';
 import { onBeforeRouteUpdate, useRoute, useRouter } from 'vue-router';
-import deepClone from '/src/helpers/deep-clone';
+// import deepClone from '/src/helpers/deep-clone';
 import CardPreview from '/src/components/card-preview';
 import PreviewWindow from '/src/views/preview-window';
-import { state } from '/src/state';
+// import { state } from '/src/state';
 import SubjectSync from '../../../model/subject-sync';
 import { eventGlobal } from '/src/utils';
-import iconTips from '../../../images/icon-tips.png';
+// import iconTips from '../../../images/icon-tips.png';
 import TheMessageDialog from '/src/components/TheMessageDialog';
+import AddItemModel from '../../../model/add-item-model';
+import AddOtherSource from '../../../model/add-other-source';
 export default defineComponent({
   name: 'courseware-modal',
+  props: {
+    groupItem: {
+      type: Object,
+      default: () => ({})
+    }
+  },
   emits: ['change'],
   setup(props, { emit }) {
     const catchStore = useCatchStore();
     const prepareStore = usePrepareStore();
-    const route = useRoute();
+    // const route = useRoute();
     const router = useRouter();
-    const dialog = useDialog();
+    // const dialog = useDialog();
     const message = useMessage();
 
     const forms = reactive({
       subjects: [] as any,
+      openFlagEnable: true, // 是否支持修改公开状态
       name: '',
       openFlag: false,
       coursewareList: [
         {
           name: '',
+          id: null,
           list: [] as any
         }
       ] as any,
@@ -72,11 +83,13 @@ export default defineComponent({
       attendClassType: 'change', //
       removeIds: [] as any, // 临时删除的编号
       editSubjectIds: '', // 声部编号
-      removeVisiable: false,
+      addCoursewareVisiable: false,
       addCoursewareItem: {} as any,
+      messageCallBack: null as any,
       messageOperation: {
         visiable: false,
-        type: 'delete' as 'delete' | 'addItem' | 'save',
+        loading: false, // 是否显示加载
+        type: 'delete' as 'delete' | 'addItem' | 'save' | 'pageLive',
         contentDirection: 'center' as 'left' | 'center' | 'right',
         title: '删除知识点',
         content: '请确认是否删除该知识点,删除知识点后将同步删除知识点下的资源',
@@ -92,56 +105,69 @@ export default defineComponent({
         type: '',
         subjectId: '',
         detailId: ''
-      } as any
+      } as any,
+      addOtherSource: false
     });
 
     // 获取列表
     const getList = async () => {
       forms.loadingStatus = true;
       try {
-        // const { data } = await queryCourseware({
-        //   coursewareDetailKnowledgeId: prepareStore.getSelectKey,
-        //   subjectId: prepareStore.getSubjectId,
-        //   page: 1,
-        //   rows: 99
-        // });
-        // const tempRows = data.rows || [];
-        // const temp: any = [];
-        // tempRows.forEach((row: any) => {
-        //   temp.push({
-        //     id: row.id,
-        //     materialId: row.materialId,
-        //     coverImg: row.coverImg,
-        //     type: row.materialType,
-        //     title: row.materialName,
-        //     isCollect: !!row.favoriteFlag,
-        //     isSelected: row.source === 'PLATFORM' ? true : false,
-        //     content: row.content,
-        //     removeFlag: row.removeFlag
-        //   });
-        // });
-        // prepareStore.setCoursewareList(temp || []);
-        // const tempCourse: any = [];
-        // temp.forEach((item: any) => {
-        //   if (!forms.removeIds.includes(item.id)) {
-        //     tempCourse.push(item);
-        //   }
-        // });
-        // forms.coursewareList = tempCourse;
-      } catch {
+        if (!props.groupItem.id) return (forms.loadingStatus = false);
+
+        const { data } = await api_teacherChapterLessonCoursewareDetail(
+          props.groupItem.id
+        );
+        const tempRows = data.chapterKnowledgeList || [];
+        forms.name = data.name;
+        forms.subjects = data.subjectIds
+          ? data.subjectIds.split(',').map((s: any) => {
+              return Number(s);
+            })
+          : [];
+        forms.openFlag = data.openFlag;
+        forms.openFlagEnable = data.openFlagEnable;
+        const temp: any = [];
+        tempRows.forEach((row: any) => {
+          const child: any = row.chapterKnowledgeMaterialList;
+          const childList: any[] = [];
+          if (Array.isArray(child) && child.length > 0) {
+            child.forEach((sub: any) => {
+              childList.push({
+                id: sub.id,
+                materialId: sub.bizId,
+                coverImg: sub.bizInfo.coverImg,
+                type: sub.type,
+                title: sub.bizInfo.name,
+                // isCollect: !!sub.favoriteFlag,
+                isSelected: sub.source === 'PLATFORM' ? true : false,
+                content: sub.bizInfo.content,
+                removeFlag: sub.removeFlag
+              });
+            });
+          }
+          temp.push({
+            name: row.name,
+            id: row.id,
+            list: [...childList]
+          });
+        });
+        forms.coursewareList = temp;
+      } catch (e) {
         //
+        console.log(e);
       }
       forms.loadingStatus = false;
     };
 
     // 删除
-    const onDelete = (item: any) => {
-      //
-      forms.removeIds.push(item.id);
-      const index = forms.coursewareList.findIndex(
+    const onDelete = (item: any, index: number) => {
+      const coursewareItem = forms.coursewareList[index];
+      if (!coursewareItem) return;
+      const childIndex = coursewareItem.list.findIndex(
         (c: any) => c.id === item.id
       );
-      forms.coursewareList.splice(index, 1);
+      coursewareItem.list.splice(childIndex, 1);
     };
 
     // 完成编辑
@@ -169,7 +195,7 @@ export default defineComponent({
         });
 
         message.success('编辑成功');
-        forms.removeVisiable = false;
+        // forms.removeVisiable = false;
         prepareStore.setIsEditResource(false);
         // 重置临时删除编号
         forms.removeIds = [];
@@ -194,15 +220,24 @@ export default defineComponent({
     // 操作
     const onChangePoint = (type: string, index: number) => {
       if (type === 'up') {
-        //
+        // 向上移动
+        if (index === 0) return;
+        const temp = forms.coursewareList[index - 1];
+        forms.coursewareList[index - 1] = forms.coursewareList[index];
+        forms.coursewareList[index] = temp;
       } else if (type === 'down') {
-        //
+        // 向下移动
+        if (index >= forms.coursewareList.length - 1) return;
+        const temp = forms.coursewareList[index + 1];
+        forms.coursewareList[index + 1] = forms.coursewareList[index];
+        forms.coursewareList[index] = temp;
       } else if (type === 'remove') {
         forms.messageOperation = {
           visiable: true,
           type: 'delete',
           contentDirection: 'left',
           title: '删除知识点',
+          loading: false,
           content:
             '请确认是否删除该知识点,删除知识点后将同步删除知识点下的资源',
           cancelButtonText: '取消',
@@ -220,8 +255,20 @@ export default defineComponent({
       } else if (type === 'addItem') {
         forms.coursewareList.push({ name: '', list: [] });
         addCoursewareItem(forms.addCoursewareItem);
-      } else if (type === 'save') {
+      } else if (type === 'save' || type === 'pageLive') {
+        if (forms.messageOperation.loading) return;
+        forms.messageOperation.loading = true;
         await onSaveCourseWare();
+        forms.messageOperation.loading = false;
+
+        if (
+          type === 'pageLive' &&
+          typeof forms.messageCallBack === 'function'
+        ) {
+          forms.messageCallBack();
+        }
+        emit('change', { status: false });
+        eventGlobal.emit('teacher-slideshow', false);
       }
       forms.messageOperation.visiable = false;
     };
@@ -231,29 +278,28 @@ export default defineComponent({
         if (point) {
           const dom = document.querySelectorAll('.row-nav');
           let isAdd = false;
-          dom.forEach((child: any, index: number) => {
+          dom.forEach((child: any) => {
+            // console.log(child);
             const status = isPointInsideElement(child, point.x, point.y);
             if (status) {
-              const array: any = forms.coursewareList;
+              const array: any =
+                forms.coursewareList[item.index || 0].list || [];
               const left = isPointOnLeft(child, point.x);
               if (!left) {
-                array.splice(index + 1, 0, item);
+                array.splice(item.index + 1, 0, item);
               } else {
-                array.splice(index, 0, item);
+                array.splice(item.index, 0, item);
               }
               isAdd = true;
               forms.coursewareList[item.index || 0].list = array;
-              prepareStore.setCoursewareList(forms.coursewareList);
             }
           });
           if (!isAdd) {
             forms.coursewareList[item.index || 0].list.push(item);
-            prepareStore.setCoursewareList(forms.coursewareList);
           }
         } else {
-          forms.coursewareList[0].list.push(item);
-          console.log(forms.coursewareList);
-          prepareStore.setCoursewareList(forms.coursewareList);
+          forms.coursewareList[item.index || 0].list.push(item);
+          message.success('添加成功');
         }
       });
     };
@@ -288,6 +334,7 @@ export default defineComponent({
         forms.messageOperation = {
           visiable: true,
           type: 'save',
+          loading: false,
           contentDirection: 'center',
           title: '保存课件',
           content: '当前课件暂未保存,是否保存?',
@@ -299,11 +346,8 @@ export default defineComponent({
         //
       }
     };
-    let isLock = false;
     const onSaveCourseWare = async () => {
       try {
-        if (isLock) return;
-        isLock = true;
         const params = {
           name: forms.name,
           subjectIds: forms.subjects.join(','),
@@ -328,13 +372,16 @@ export default defineComponent({
             chapterKnowledgeMaterialList: tempItem
           });
         });
-        await api_add(params);
-        message.success('添加成功');
-        emit('change', { status: false });
-        eventGlobal.emit('teacher-slideshow', false);
-        setTimeout(() => {
-          isLock = false;
-        }, 100);
+        if (props.groupItem?.id) {
+          await api_teacherChapterLessonCoursewareUpdate({
+            id: props.groupItem.id,
+            ...params
+          });
+          message.success('修改成功');
+        } else {
+          await api_teacherChapterLessonCoursewareAdd(params);
+          message.success('添加成功');
+        }
       } catch {
         //
       }
@@ -349,26 +396,58 @@ export default defineComponent({
           type: 'addItem',
           contentDirection: 'center',
           title: '添加到知识点',
+          loading: false,
           content: '当前课件暂无知识点,请添加知识点后操作',
           cancelButtonText: '取消',
           confirmButtonText: '添加知识点',
           index: 0
         };
+      } else if (forms.coursewareList.length > 1 && item.addType !== 'drag') {
+        forms.addCoursewareVisiable = true;
+        forms.addCoursewareItem = item;
       } else {
         addCoursewareItem(item, point);
       }
     };
+
+    // 当页面离开时
+    const onPageBeforeLeave = (event: any) => {
+      console.log(event, typeof event);
+      forms.messageCallBack = event;
+      forms.messageOperation = {
+        visiable: true,
+        type: 'pageLive',
+        loading: false,
+        contentDirection: 'center',
+        title: '保存课件',
+        content: '当前课件暂未保存,是否保存?',
+        cancelButtonText: '不保存',
+        confirmButtonText: '保存',
+        index: 0
+      };
+    };
     onMounted(async () => {
       await getList();
-
       // 动态添加数据
       eventGlobal.on('onPrepareAddItem', addItem);
+
+      eventGlobal.on('pageBeforeLeave', onPageBeforeLeave);
     });
 
     onUnmounted(() => {
       eventGlobal.off('onPrepareAddItem', addItem);
     });
 
+    // 当列表数据更新时同步缓存数据
+    watch(
+      () => forms.coursewareList,
+      () => {
+        prepareStore.setCoursewareList = forms.coursewareList;
+      },
+      {
+        deep: true
+      }
+    );
     return () => (
       <div class={styles.coursewareModal}>
         <div class={styles.btnGroup}>
@@ -377,7 +456,12 @@ export default defineComponent({
               <span class={styles.btnTitle}>
                 <span>*</span>标题:
               </span>
-              <NInput placeholder="请输入课件标题" v-model:value={forms.name} />
+              <NInput
+                placeholder="请输入课件标题"
+                v-model:value={forms.name}
+                maxlength={15}
+                clearable
+              />
             </div>
             <div class={styles.btnItem}>
               <span class={styles.btnTitle}>
@@ -393,11 +477,30 @@ export default defineComponent({
                 maxTagCount={1}
                 size="small"
                 v-model:value={forms.subjects}
+                clearable
               />
             </div>
             <div class={styles.btnItem}>
               <span class={styles.btnTitle}>公开:</span>
-              <NSwitch v-model:value={forms.openFlag} />
+              {!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>
 
@@ -414,6 +517,13 @@ export default defineComponent({
             <NButton type="primary" onClick={onSubmit}>
               保存课件
             </NButton>
+            {/* <NButton
+              type="primary"
+              onClick={() => {
+                forms.coursewareList = [{ name: '', list: [] }];
+              }}>
+              请空
+            </NButton> */}
           </NSpace>
         </div>
 
@@ -431,7 +541,10 @@ export default defineComponent({
                   }}
                   onDrop={(e: any) => {
                     let dropItem = e.dataTransfer.getData('text');
-                    dropItem = dropItem ? JSON.parse(dropItem) : {};
+                    dropItem =
+                      dropItem && e.dataTransfer.effectAllowed === 'all'
+                        ? JSON.parse(dropItem)
+                        : {};
                     // 判断是否有数据
                     if (dropItem.id) {
                       // 获取拖拽的目标元素
@@ -441,12 +554,13 @@ export default defineComponent({
                           materialId: dropItem.id,
                           coverImg: dropItem.coverImg,
                           type: dropItem.type,
-                          title: dropItem.name,
+                          title: dropItem.title,
                           isCollect: dropItem.isCollect,
                           isSelected: dropItem.isSelected,
                           content: dropItem.content,
                           removeFlag: false,
-                          index
+                          index,
+                          addType: 'drag'
                         },
                         {
                           x: e.clientX,
@@ -463,6 +577,8 @@ export default defineComponent({
                       <NInput
                         placeholder="未命名知识点"
                         v-model:value={item.name}
+                        maxlength={15}
+                        clearable
                       />
                     </div>
                   </div>
@@ -476,7 +592,7 @@ export default defineComponent({
                               class={styles.iconCUp}
                               onClick={() => onChangePoint('up', index)}></i>
                           ),
-                          default: '上移知识点'
+                          default: () => '上移知识点'
                         }}
                       </NTooltip>
                     )}
@@ -488,7 +604,7 @@ export default defineComponent({
                               class={styles.iconCDown}
                               onClick={() => onChangePoint('down', index)}></i>
                           ),
-                          default: '下移知识点'
+                          default: () => '下移知识点'
                         }}
                       </NTooltip>
                     )}
@@ -499,7 +615,7 @@ export default defineComponent({
                             class={styles.iconCRemove}
                             onClick={() => onChangePoint('remove', index)}></i>
                         ),
-                        default: '删除知识点'
+                        default: () => '删除知识点'
                       }}
                     </NTooltip>
                   </NSpace>
@@ -534,6 +650,12 @@ export default defineComponent({
                                   offShelf={item.removeFlag ? true : false}
                                   // onOffShelf={() => onRemove(item)}
                                   item={item}
+                                  disabledMouseHover={false}
+                                  onClick={() => {
+                                    if (item.type === 'IMG') return;
+                                    forms.show = true;
+                                    forms.item = item;
+                                  }}
                                 />
                                 <div class={styles.itemOperation}>
                                   <img
@@ -541,7 +663,7 @@ export default defineComponent({
                                     class={styles.iconDelete}
                                     onClick={(e: MouseEvent) => {
                                       e.stopPropagation();
-                                      onDelete(item);
+                                      onDelete(item, index);
                                     }}
                                   />
                                 </div>
@@ -559,12 +681,7 @@ export default defineComponent({
                                   'handle'
                                 ]}
                                 onClick={() => {
-                                  // 直接跳转到制谱页面 (临时存储数据)
-                                  sessionStorage.setItem(
-                                    'notation-open-create',
-                                    '1'
-                                  );
-                                  router.push('/notation');
+                                  forms.addOtherSource = true;
                                 }}>
                                 <img src={iconAddMusic} />
 
@@ -587,12 +704,7 @@ export default defineComponent({
                               'handle'
                             ]}
                             onClick={() => {
-                              // 直接跳转到制谱页面 (临时存储数据)
-                              sessionStorage.setItem(
-                                'notation-open-create',
-                                '1'
-                              );
-                              router.push('/notation');
+                              forms.addOtherSource = true;
                             }}>
                             <img src={iconAddMusic} />
 
@@ -627,22 +739,26 @@ export default defineComponent({
         <CardPreview v-model:show={forms.show} item={forms.item} />
 
         <NModal
-          v-model:show={forms.removeVisiable}
+          v-model:show={forms.addCoursewareVisiable}
           preset="card"
-          class={['modalTitle', styles.removeVisiable]}
-          title={'提示'}>
-          <div class={styles.studentRemove}>
-            <p>是否完成编辑?</p>
-
-            <NSpace class={styles.btnGroupModal} justify="center">
-              <NButton round type="primary" onClick={onOverEdit}>
-                确定
-              </NButton>
-              <NButton round onClick={() => (forms.removeVisiable = false)}>
-                取消
-              </NButton>
-            </NSpace>
-          </div>
+          class={['modalTitle', styles.addCourseware]}
+          title={'添加知识点'}>
+          <AddItemModel
+            coursewareList={forms.coursewareList}
+            onClose={() => (forms.addCoursewareVisiable = false)}
+            onConfirm={(selects: number[]) => {
+              if (Array.isArray(selects) && selects.length > 0) {
+                selects.forEach(select => {
+                  addCoursewareItem({
+                    ...forms.addCoursewareItem,
+                    index: select
+                  });
+                });
+
+                forms.addCoursewareVisiable = false;
+              }
+            }}
+          />
         </NModal>
 
         <NModal
@@ -655,7 +771,23 @@ export default defineComponent({
             contentDirection={forms.messageOperation.contentDirection}
             cancelButtonText={forms.messageOperation.cancelButtonText}
             confirmButtonText={forms.messageOperation.confirmButtonText}
-            onClose={() => (forms.messageOperation.visiable = false)}
+            loading={forms.messageOperation.loading}
+            onClose={() => {
+              forms.messageOperation.visiable = false;
+              if (
+                forms.messageOperation.type === 'save' ||
+                forms.messageOperation.type === 'pageLive'
+              ) {
+                emit('change', { status: false });
+                eventGlobal.emit('teacher-slideshow', false);
+                if (
+                  forms.messageOperation.type === 'pageLive' &&
+                  typeof forms.messageCallBack === 'function'
+                ) {
+                  forms.messageCallBack();
+                }
+              }
+            }}
             onConfirm={() => onMessageConfirm()}
           />
         </NModal>
@@ -687,6 +819,15 @@ export default defineComponent({
             }}
           />
         </NModal>
+
+        {/* 添加其它类型的资源 */}
+        <NModal
+          v-model:show={forms.addOtherSource}
+          preset="card"
+          class={['modalTitle background', styles.addOtherSource]}
+          title={'添加功能'}>
+          <AddOtherSource />
+        </NModal>
       </div>
     );
   }

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

@@ -14,6 +14,7 @@ export default defineComponent({
     const prepareStore = usePrepareStore();
     const state = reactive({
       editCoursewareShow: false, // 是否编辑课件
+      editCourseware: {} as any, //
       editWorkShow: false, // 是否编辑预设
       editWork: {} as any // 预设模板编号
     });
@@ -55,8 +56,10 @@ export default defineComponent({
               displayDirective="if">
               {state.editCoursewareShow ? (
                 <Courseware
+                  groupItem={state.editCourseware}
                   onChange={(val: any) => {
                     state.editCoursewareShow = val.status;
+                    prepareStore.setIsEditResource(val.status);
 
                     if (!val.status) {
                       eventGlobal.emit('teacher-slideshow', false);
@@ -67,6 +70,8 @@ export default defineComponent({
                 <CoursewarePresets
                   onChange={(val: any) => {
                     state.editCoursewareShow = val.status;
+                    prepareStore.setIsEditResource(val.status);
+                    state.editCourseware = val.groupItem;
                   }}
                 />
               )}

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

@@ -63,7 +63,11 @@ export default defineComponent({
         }
         const { data } = await materialQueryPage({
           ...state.searchGroup,
-          ...state.pagination
+          ...state.pagination,
+          lessonCoursewareKnowledgeId:
+            props.type === 'relateResources' || props.type === 'shareResources'
+              ? prepareStore.getSelectKey
+              : null
           // subjectId: prepareStore.getSubjectId
         });
         state.loading = false;

+ 15 - 0
src/views/prepare-lessons/components/resource-main/index.module.less

@@ -42,6 +42,10 @@
     .n-tabs-nav__suffix {
       padding-left: 0 !important;
     }
+
+    .n-tabs.n-tabs--top .n-tabs-nav-scroll-wrapper::after {
+      box-shadow: none !important;
+    }
   }
 
   .iconScreen {
@@ -56,6 +60,17 @@
     cursor: pointer;
   }
 
+  .homerowkTabs {
+    :global {
+      .n-tabs-tab-pad {
+        width: 13px !important;
+      }
+
+      .v-x-scroll {
+        padding-right: 40px;
+      }
+    }
+  }
 
 }
 

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

@@ -96,6 +96,7 @@ export default defineComponent({
           <NTabs
             ref={tabRef}
             animated
+            class={styles.homerowkTabs}
             value={forms.tabType}
             paneClass={styles.paneTitle}
             paneWrapperClass={styles.paneWrapperContainer}

BIN
src/views/prepare-lessons/images/addSource/icon1.png


BIN
src/views/prepare-lessons/images/addSource/icon2.png


BIN
src/views/prepare-lessons/images/addSource/icon3.png


BIN
src/views/prepare-lessons/images/addSource/icon4.png


BIN
src/views/prepare-lessons/images/addSource/icon5.png


BIN
src/views/prepare-lessons/images/addSource/icon6.png


BIN
src/views/prepare-lessons/images/addSource/icon7.png


+ 26 - 0
src/views/prepare-lessons/model/add-item-model/index.module.less

@@ -0,0 +1,26 @@
+.addCoursewareItem {
+  padding: 20px 40px 0;
+
+
+  :global {
+    .n-checkbox__label {
+      white-space: nowrap;
+      overflow: hidden;
+      text-overflow: ellipsis;
+      width: 200px;
+      padding-left: 10px;
+      color: #777777;
+    }
+  }
+}
+
+.btnGroupModal {
+  padding: 32px 0;
+
+  :global {
+    .n-button {
+      height: 47px;
+      min-width: 156px;
+    }
+  }
+}

+ 51 - 0
src/views/prepare-lessons/model/add-item-model/index.tsx

@@ -0,0 +1,51 @@
+import { defineComponent, ref } from 'vue';
+import styles from './index.module.less';
+import {
+  NButton,
+  NCheckbox,
+  NCheckboxGroup,
+  NGi,
+  NGrid,
+  NSpace
+} from 'naive-ui';
+
+export default defineComponent({
+  name: 'add-courseware-item',
+  props: {
+    coursewareList: {
+      type: Array,
+      default: () => []
+    }
+  },
+  emits: ['close', 'confirm'],
+  setup(props, { emit }) {
+    const selects = ref<number[]>([]);
+    return () => (
+      <div class={styles.addCoursewareItem}>
+        <NCheckboxGroup v-model:value={selects.value}>
+          <NGrid yGap={12} cols={2}>
+            {props.coursewareList.map((courseware: any, index: number) => (
+              <NGi>
+                <NCheckbox value={index}>{courseware.name}</NCheckbox>
+              </NGi>
+            ))}
+          </NGrid>
+        </NCheckboxGroup>
+
+        <NSpace class={styles.btnGroupModal} justify="center">
+          <NButton round onClick={() => emit('close')}>
+            取消
+          </NButton>
+          <NButton
+            round
+            type="primary"
+            onClick={() => {
+              emit('confirm', selects.value);
+            }}>
+            确定
+          </NButton>
+        </NSpace>
+      </div>
+    );
+  }
+});

+ 34 - 0
src/views/prepare-lessons/model/add-other-source/index.module.less

@@ -0,0 +1,34 @@
+.addOtherSource {
+  padding: 42px 50px;
+  display: flex;
+  align-items: center;
+  flex-wrap: wrap;
+  gap: 30px 30px;
+
+  .sourceItem {
+    cursor: pointer;
+    transition: all .2s ease;
+
+    &:hover {
+      transform: scale(1.03);
+      transition: all .2s ease;
+    }
+
+    .coverImg {
+      width: 133px;
+      height: 133px;
+    }
+
+    .name {
+      text-align: center;
+      font-size: max(15px, 12Px);
+      color: #131415;
+      line-height: 21px;
+    }
+  }
+}
+
+
+.addOtherSourceModal {
+  width: 958px;
+}

+ 105 - 0
src/views/prepare-lessons/model/add-other-source/index.tsx

@@ -0,0 +1,105 @@
+import { defineComponent, reactive, ref } from 'vue';
+import { NImage, NModal } from 'naive-ui';
+import styles from './index.module.less';
+import icon1 from '../../images/addSource/icon1.png';
+import icon2 from '../../images/addSource/icon2.png';
+import icon3 from '../../images/addSource/icon3.png';
+import icon4 from '../../images/addSource/icon4.png';
+import icon5 from '../../images/addSource/icon5.png';
+import icon6 from '../../images/addSource/icon6.png';
+import icon7 from '../../images/addSource/icon7.png';
+import { useRouter } from 'vue-router';
+import SourceRhythm from '../source-rhythm';
+
+export default defineComponent({
+  name: 'add-other-source',
+  emits: ['close', 'comfirm'],
+  setup(props, { emit }) {
+    const router = useRouter();
+    const sourceList = ref([
+      {
+        image: icon1,
+        name: '听音练习',
+        index: 0
+      },
+      {
+        image: icon2,
+        name: '节奏练习',
+        index: 1
+      },
+      {
+        image: icon3,
+        name: '乐器百科',
+        index: 2
+      },
+      {
+        image: icon4,
+        name: '名曲鉴赏',
+        index: 3
+      },
+      {
+        image: icon5,
+        name: '音乐家',
+        index: 4
+      },
+      {
+        image: icon6,
+        name: '乐理知识',
+        index: 5
+      },
+      {
+        image: icon7,
+        name: '制作曲谱',
+        index: 6
+      }
+    ]);
+    const state = reactive({
+      listenStatus: false, // 听音练习
+      rhythmStatus: false, //节奏
+      theoryStatus: false, //
+      musicStatus: false, //
+      instrumentStatus: false, //
+      musicianStatus: false //
+    });
+    // LISTEN:听音,RHYTHM:节奏,THEORY:乐理知识,MUSIC:曲目 INSTRUMENT:乐器 MUSICIAN:音乐家)
+
+    const onDetail = (item: any) => {
+      switch (item.index) {
+        case 1:
+          state.rhythmStatus = true;
+          break;
+        case 6:
+          // 直接跳转到制谱页面 (临时存储数据)
+          sessionStorage.setItem('notation-open-create', '1');
+          router.push('/notation');
+          break;
+        default:
+          break;
+      }
+    };
+    return () => (
+      <>
+        <div class={styles.addOtherSource}>
+          {sourceList.value.map(source => (
+            <div class={styles.sourceItem} onClick={() => onDetail(source)}>
+              <NImage
+                class={styles.coverImg}
+                src={source.image}
+                previewDisabled
+              />
+              <p class={styles.name}>{source.name}</p>
+            </div>
+          ))}
+        </div>
+        {/* 节奏练习 */}
+        <NModal
+          v-model:show={state.rhythmStatus}
+          preset="card"
+          class={['modalTitle background', styles.addOtherSourceModal]}
+          title={'节奏练习'}>
+          <SourceRhythm />
+        </NModal>
+      </>
+    );
+  }
+});

+ 41 - 3
src/views/prepare-lessons/model/courseware-type/index.module.less

@@ -3,11 +3,11 @@
   background: #F5F6FA;
   border-radius: 13px;
   padding: 10px;
-  transition: all 0.3 ease;
+  transition: all 0.2s ease;
 
   &:hover {
     transform: scale(1.01);
-    transition: all 0.3 ease;
+    transition: all 0.2s ease;
   }
 
   &.coursewareTypeHover:hover {
@@ -18,6 +18,10 @@
   }
 
   &.coursewareTypeHocoursewareTypeShow {
+    .cover {
+      cursor: default;
+    }
+
     .addBtn {
       opacity: 1;
       visibility: visible;
@@ -54,6 +58,7 @@
     border-radius: 10px;
     overflow: hidden;
     background-color: #fff;
+    transition: all .2s ease;
 
     .status {
       position: absolute;
@@ -77,6 +82,37 @@
     img {
       width: 100%;
     }
+
+    &:hover .preview {
+      opacity: 1;
+      visibility: visible;
+      transition: all .2s ease;
+    }
+  }
+
+
+  .preview {
+    position: absolute;
+    opacity: 0;
+    visibility: hidden;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+    background-color: rgba(0, 0, 0, 0.4);
+    display: flex;
+    align-items: center;
+    justify-content: center;
+    transition: all 0.2s cubic-bezier(0.175, 0.885, 0.32, 1.275);
+    cursor: pointer;
+
+    .previewBtn {
+      background: #3D9EFF;
+      height: max(40px, 32Px);
+      padding: 0 30px;
+      border-radius: 12px;
+      color: #fff;
+    }
   }
 
   .coursewareText {
@@ -90,6 +126,7 @@
       align-items: center;
 
       span {
+        list-style: 16Px;
         max-width: 100%;
         display: inline-block;
         overflow: hidden;
@@ -137,9 +174,10 @@
     }
 
     .subjectName {
-      padding-top: 10px;
+      padding-top: 8px;
       font-size: 11Px;
       color: #777777;
+      line-height: 16Px;
     }
   }
 }

+ 15 - 2
src/views/prepare-lessons/model/courseware-type/index.tsx

@@ -31,10 +31,15 @@ export default defineComponent({
     operate: {
       type: Boolean,
       default: false
+    },
+    /** 是否显示预览按钮 */
+    isShowPreviewBtn: {
+      type: Boolean,
+      default: false
     }
   },
   /** add */
-  emits: ['add', 'editName', 'edit', 'delete', 'startClass'],
+  emits: ['add', 'editName', 'edit', 'delete', 'startClass', 'click'],
   setup(props, { emit }) {
     return () => (
       <div
@@ -57,9 +62,17 @@ export default defineComponent({
             {props.item.isAdd ? '已添加' : '添加'}
           </NButton>
         )}
-        <div class={styles.cover}>
+        <div class={styles.cover} onClick={() => emit('click')}>
           {props.item.openFlag && <span class={styles.status}>公开</span>}
           <NImage objectFit="cover" previewDisabled src={props.item.coverImg} />
+
+          {props.isShowPreviewBtn && (
+            <div class={styles.preview}>
+              <NButton strong secondary class={styles.previewBtn}>
+                使用课件
+              </NButton>
+            </div>
+          )}
         </div>
         <div class={styles.coursewareText}>
           <div class={[styles.name, props.isEditName && styles.editName]}>

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

@@ -23,10 +23,6 @@ export default defineComponent({
     const tabType = ref(type.value);
 
     onMounted(() => {
-      // console.log(
-      //   document.querySelector('.select-resource .n-tabs-nav--top'),
-      //   ''
-      // );
       useResizeObserver(
         document.querySelector(
           '.select-resource .n-tabs-nav--top'
@@ -53,6 +49,11 @@ export default defineComponent({
           onUpdate:value={(val: string) => {
             tabType.value = val;
           }}>
+          {props.from !== 'class' && (
+            <NTabPane name="relateResources" tab={'相关资源'}>
+              <SelectItem type="relateResources" />
+            </NTabPane>
+          )}
           <NTabPane
             name="myResources"
             tab={props.from === 'class' ? '我的曲目' : '我的资源'}>

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

@@ -26,7 +26,9 @@ export default defineComponent({
   name: 'resource-search-group',
   props: {
     type: {
-      type: String as PropType<'shareResources' | 'myResources' | 'myCollect'>,
+      type: String as PropType<
+        'relateResources' | 'shareResources' | 'myResources' | 'myCollect'
+      >,
       default: 'shareResources'
     },
     subjectId: {

+ 14 - 39
src/views/prepare-lessons/model/select-resources/select-item/index.tsx

@@ -1,13 +1,6 @@
-import {
-  PropType,
-  defineComponent,
-  onMounted,
-  reactive,
-  toRefs,
-  watch
-} from 'vue';
+import { PropType, defineComponent, onMounted, reactive, toRefs } from 'vue';
 import ResourceSearchGroup from './resource-search-group';
-import { NScrollbar, NSpin } from 'naive-ui';
+import { NScrollbar, NSpin, useMessage } from 'naive-ui';
 import styles from './index.module.less';
 import CardType from '/src/components/card-type';
 import { favorite, materialQueryPage } from '/src/views/natural-resources/api';
@@ -26,6 +19,8 @@ const formatType = (type: string) => {
     return 3;
   } else if (type === 'myCollect') {
     return 4;
+  } else if (type === 'relateResources') {
+    return 5;
   }
 };
 
@@ -33,7 +28,9 @@ export default defineComponent({
   name: 'share-resources',
   props: {
     type: {
-      type: String as PropType<'shareResources' | 'myResources' | 'myCollect'>,
+      type: String as PropType<
+        'relateResources' | 'shareResources' | 'myResources' | 'myCollect'
+      >,
       default: 'shareResources'
     },
     /** 从哪里使用 */
@@ -45,6 +42,7 @@ export default defineComponent({
   setup(props) {
     const prepareStore = usePrepareStore();
     const catchStore = useCatchStore();
+    const message = useMessage();
     const { type } = toRefs(props);
     const className = 'resourceSearchGroup' + +new Date();
     const state = reactive({
@@ -77,15 +75,16 @@ export default defineComponent({
         }
         const { data } = await materialQueryPage({
           ...state.searchGroup,
-          ...state.pagination
+          ...state.pagination,
+          lessonCoursewareKnowledgeId:
+            props.type === 'relateResources' || props.type === 'shareResources'
+              ? prepareStore.getSelectKey
+              : null
         });
         state.loading = false;
         const tempRows = data.rows || [];
         const temp: any = [];
         tempRows.forEach((row: any) => {
-          const index = prepareStore.getCoursewareList.findIndex(
-            (course: any) => course.materialId === row.id
-          );
           temp.push({
             id: row.id,
             coverImg: row.coverImg,
@@ -93,8 +92,7 @@ export default defineComponent({
             title: row.name,
             isCollect: !!row.favoriteFlag,
             isSelected: row.sourceFrom === 'PLATFORM' ? true : false,
-            content: row.content,
-            exist: index !== -1 ? true : false // 是否存在
+            content: row.content
           });
         });
         state.tableList.push(...temp);
@@ -142,22 +140,6 @@ export default defineComponent({
       }
     };
 
-    watch(
-      () => prepareStore.coursewareList,
-      () => {
-        state.tableList.forEach((item: any) => {
-          const index = prepareStore.getCoursewareList.findIndex(
-            (course: any) => course.materialId === item.id
-          );
-          item.exist = index !== -1 ? true : false; // 是否存在
-        });
-      },
-      {
-        deep: true,
-        immediate: true
-      }
-    );
-
     // 收藏
     const onCollect = async (item: any) => {
       try {
@@ -175,13 +157,6 @@ export default defineComponent({
     onMounted(async () => {
       // 获取声部
       await catchStore.getSubjects();
-      // catchStore.getSubjectInstruments.forEach((item: any) => {
-      //   if (item.id == prepareStore.getSubjectId) {
-      //     if (item.instruments && item.instruments.length > 0) {
-      //       state.searchGroup.musicalInstrumentId = item.instruments[0].value;
-      //     }
-      //   }
-      // });
 
       getList();
 

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

@@ -26,7 +26,9 @@ export default defineComponent({
   name: 'resource-search-group',
   props: {
     type: {
-      type: String as PropType<'shareResources' | 'myResources' | 'myCollect'>,
+      type: String as PropType<
+        'relateResources' | 'shareResources' | 'myResources' | 'myCollect'
+      >,
       default: 'shareResources'
     },
     subjectId: {

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


+ 10 - 0
src/views/prepare-lessons/model/source-rhythm/index.tsx

@@ -0,0 +1,10 @@
+import { defineComponent } from 'vue';
+import styles from './index.module.less';
+
+export default defineComponent({
+  name: 'source-rhythm',
+  emits: ['close', 'confirm'],
+  setup(props, { emit }) {
+    return () => <div class={styles.sourceRhythm}></div>;
+  }
+});

+ 1 - 0
src/views/preview-window/index.tsx

@@ -79,6 +79,7 @@ export default defineComponent({
                 <AttendClass
                   type={params.value.type || ''}
                   subjectId={params.value.subjectId || ''}
+                  courseId={params.value.courseId || ''}
                   detailId={params.value.detailId || ''}
                   classGroupId={params.value.classGroupId || ''}
                   lessonCourseId={params.value.lessonCourseId || ''}