lex 1 rok pred
rodič
commit
c7ad8f8565

+ 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


+ 37 - 97
src/views/attend-class/index.tsx

@@ -78,6 +78,7 @@ 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 = {
@@ -156,10 +157,9 @@ export default defineComponent({
       handleInit(1);
     });
 
-    const drawerCardRef = ref(); // 资源列表对象
     const data = reactive({
       type: 'class' as '' | 'preview' | 'class', // 预览类型
-      courseId: '', // 课件编号
+      courseId: '' as any, // 课件编号
       subjectId: '' as any, // 声部编号
       lessonCourseId: '' as any, // 教材编号
       lessonCoursewareDetailId: '' as any, // 章节
@@ -213,7 +213,8 @@ export default defineComponent({
 
         const tempRows = res.data.chapterKnowledgeList || [];
         const temp: any = [];
-        tempRows.forEach((row: any) => {
+        const allItem: any = [];
+        tempRows.forEach((row: any, index: number) => {
           if (!Array.isArray(row.chapterKnowledgeMaterialList)) {
             return;
           }
@@ -228,7 +229,8 @@ export default defineComponent({
                 title: child.bizInfo.name,
                 isCollect: !!child.favoriteFlag,
                 isSelected: child.source === 'PLATFORM' ? true : false,
-                content: child.bizInfo.content
+                content: child.bizInfo.content,
+                parentIndex: index
               });
             }
           });
@@ -236,10 +238,11 @@ export default defineComponent({
             title: row.name,
             list: childList
           });
+          allItem.push(...childList);
         });
 
         data.knowledgePointList = temp;
-        data.itemList = data.knowledgePointList[0].list?.map((m: any) => {
+        data.itemList = allItem?.map((m: any) => {
           return {
             ...m,
             iframeRef: null,
@@ -351,10 +354,11 @@ export default defineComponent({
     const popupData = reactive({
       open: false,
       activeIndex: 0,
+      courseActiveIndex: 0, // 课件选择的第几个
       toolOpen: false, // 工具弹窗控制
       chapterOpen: false, // 切换章节
       chapterDetails: [] as any,
-      courseId: null, // 章节编号
+      courseId: null as any, // 章节编号
       chapterLoading: false // 加载数据
     });
 
@@ -669,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) {
@@ -712,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;
         }
 
@@ -752,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 {
@@ -795,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;
         }
 
@@ -835,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;
         }
       }
@@ -921,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);
@@ -1062,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(
@@ -1434,7 +1410,6 @@ export default defineComponent({
                   // if (isRender) {
                   //   m.isRender = true;
                   // }
-                  // console.log(isRender, 'isRender', mIndex);
                   return isRender ? (
                     <div
                       key={'index' + mIndex}
@@ -1650,50 +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>
-                    );
-                  })} */}
-                  <NCollapse displayDirective="show">
-                    {data.knowledgePointList.map((item: any, index: number) => {
-                      return (
-                        <NCollapseItem title={item.title}>
-                          {item.list.map((child: any) => (
-                            <div
-                              class={[
-                                styles.cardContainer,
-                                'drawerCardItemRef'
-                              ]}>
-                              <CardType
-                                item={child}
-                                isActive={popupData.activeIndex === index}
-                                isCollect={false}
-                                isShowCollect={false}
-                                onClick={() => {
-                                  popupData.open = false;
-                                  toggleMaterial(item.id);
-                                }}
-                              />
-                            </div>
-                          ))}
-                        </NCollapseItem>
-                      );
-                    })}
-                  </NCollapse>
-                </div>
+                <SourceList
+                  knowledgePointList={data.knowledgePointList}
+                  courseActiveIndex={popupData.courseActiveIndex}
+                  activeItem={data.itemList[popupData.activeIndex]}
+                  onConfirm={(item: any) => {
+                    popupData.open = false;
+                    toggleMaterial(item.id);
+                  }}
+                />
               )
             }}
           </NDrawerContent>
@@ -1747,7 +1687,7 @@ export default defineComponent({
           />
         )}
 
-        {/* 训练设置 */}
+        {/* 选择课件 */}
         <NModal
           transformOrigin="center"
           v-model:show={data.selectClassStatus}
@@ -1765,7 +1705,7 @@ export default defineComponent({
               popupData.chapterLoading = true;
               try {
                 data.detailId = val.itemActive;
-                data.courseId = val.courseId;
+                data.courseId = val.chapterId;
                 const ids = formatParentId(
                   val.itemActive,
                   popupData.chapterDetails

+ 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>
+    );
+  }
+});

+ 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;
 }

+ 150 - 20
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,
@@ -21,12 +21,14 @@ 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_teacherChapterLessonCoursewareRemove,
   api_queryOpenCoursewareByPage,
   api_updateCoursewareInfo,
-  teacherChapterLessonCoursewareList
+  teacherChapterLessonCoursewareList,
+  courseScheduleStart
 } from '../../../api';
 import { useRoute, useRouter } from 'vue-router';
 import TheMessageDialog from '/src/components/TheMessageDialog';
@@ -53,6 +55,8 @@ export default defineComponent({
         ? Number(localStorageSubjectId)
         : null,
       courseScheduleSubjectId: route.query.courseScheduleSubjectId,
+      classGroupId: route.query.classGroupId,
+      preStudentNum: route.query.preStudentNum,
       bodyWidth: '100%',
       loading: false,
       openLoading: false,
@@ -65,6 +69,9 @@ export default defineComponent({
       editBtnLoading: false,
       preRemoveVisiable: false,
       carouselIndex: 0,
+      showAttendClass: false,
+      attendClassType: 'change', //
+      attendClassItem: {} as any,
       previewModal: false,
       previewParams: {
         type: '',
@@ -101,7 +108,6 @@ export default defineComponent({
             type: firstItem?.bizInfo.type
           });
         });
-
         forms.tableList = tempList;
       } catch {
         //
@@ -142,13 +148,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],
@@ -325,6 +339,64 @@ export default defineComponent({
         window.open(href, +new Date() + '');
       }
     };
+
+    const onStartClass = async (item: any, classGroupId: any) => {
+      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;
+      }
+      forms.showAttendClass = false;
+    };
+
+    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}>
@@ -389,6 +461,9 @@ export default defineComponent({
                             groupItem: { id: item.id }
                           });
                         }}
+                        onStartClass={() =>
+                          onStartClass(item, forms.classGroupId)
+                        }
                         onDelete={() => {
                           forms.selectItem = item;
                           forms.preRemoveVisiable = true;
@@ -408,7 +483,7 @@ export default defineComponent({
                 <div class={styles.titleLeft}>
                   <i class={[styles.icon, styles.iconCourseware]}></i>
                   相关课件
-                  {forms.openTableList.length > 4 && (
+                  {forms.openTableList.length > 1 && (
                     <span
                       class={styles.more}
                       onClick={() => (forms.showRelatedClass = true)}>
@@ -426,17 +501,27 @@ export default defineComponent({
                   )}
                 </div>
 
-                {forms.openTableList.length > 4 && (
+                {forms.openTableList.length > 1 && (
                   <NSpace class={styles.swipeControll}>
-                    <div>
+                    <div onClick={() => onChangeSlide('left')}>
                       <NImage
                         previewDisabled
-                        class={[styles.leftIcon]}
+                        class={[
+                          styles.leftIcon,
+                          forms.carouselIndex === 0 && styles.disabled
+                        ]}
                         src={iconSlideRight}
                       />
                     </div>
-                    <div>
-                      <NImage previewDisabled src={iconSlideRight} />
+                    <div onClick={() => onChangeSlide('right')}>
+                      <NImage
+                        class={
+                          forms.carouselIndex ==
+                            forms.openTableList.length - 4 && styles.disabled
+                        }
+                        previewDisabled
+                        src={iconSlideRight}
+                      />
                     </div>
                   </NSpace>
                 )}
@@ -444,19 +529,29 @@ export default defineComponent({
 
               <NSpin show={forms.openLoading} class={styles.openLoading}>
                 <NCarousel
-                  slidesPerView={4}
+                  slidesPerView={1}
                   loop={false}
+                  ref={carouselRef}
                   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 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>
@@ -469,7 +564,7 @@ export default defineComponent({
           v-model:show={forms.showRelatedClass}
           preset="card"
           showIcon={false}
-          class={['modalTitle background', styles.attendClassModal]}
+          class={['modalTitle background', styles.attendClassModal1]}
           title={'相关课件'}
           blockScroll={false}>
           <RelatedClass
@@ -535,6 +630,41 @@ export default defineComponent({
           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>
     );
   }

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

@@ -23,29 +23,29 @@ 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_teacherChapterLessonCoursewareAdd,
   api_teacherChapterLessonCoursewareUpdate,
   api_teacherChapterLessonCoursewareDetail,
-  courseScheduleStart,
-  queryCourseware,
+  // 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';
 export default defineComponent({
@@ -60,9 +60,9 @@ export default defineComponent({
   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({
@@ -84,10 +84,11 @@ export default defineComponent({
       editSubjectIds: '', // 声部编号
       addCoursewareVisiable: false,
       addCoursewareItem: {} as any,
+      messageCallBack: null as any,
       messageOperation: {
         visiable: false,
         loading: false, // 是否显示加载
-        type: 'delete' as 'delete' | 'addItem' | 'save',
+        type: 'delete' as 'delete' | 'addItem' | 'save' | 'pageLive',
         contentDirection: 'center' as 'left' | 'center' | 'right',
         title: '删除知识点',
         content: '请确认是否删除该知识点,删除知识点后将同步删除知识点下的资源',
@@ -252,11 +253,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;
     };
@@ -266,16 +276,17 @@ 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[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;
@@ -369,9 +380,6 @@ export default defineComponent({
           await api_teacherChapterLessonCoursewareAdd(params);
           message.success('添加成功');
         }
-
-        emit('change', { status: false });
-        eventGlobal.emit('teacher-slideshow', false);
       } catch {
         //
       }
@@ -399,10 +407,29 @@ export default defineComponent({
         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(() => {
@@ -488,6 +515,13 @@ export default defineComponent({
             <NButton type="primary" onClick={onSubmit}>
               保存课件
             </NButton>
+            {/* <NButton
+              type="primary"
+              onClick={() => {
+                forms.coursewareList = [{ name: '', list: [] }];
+              }}>
+              请空
+            </NButton> */}
           </NSpace>
         </div>
 
@@ -748,9 +782,18 @@ export default defineComponent({
             loading={forms.messageOperation.loading}
             onClose={() => {
               forms.messageOperation.visiable = false;
-              if (forms.messageOperation.type === 'save') {
+              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()}

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

@@ -59,6 +59,7 @@ export default defineComponent({
                   groupItem={state.editCourseware}
                   onChange={(val: any) => {
                     state.editCoursewareShow = val.status;
+                    prepareStore.setIsEditResource(val.status);
 
                     if (!val.status) {
                       eventGlobal.emit('teacher-slideshow', false);
@@ -69,6 +70,7 @@ export default defineComponent({
                 <CoursewarePresets
                   onChange={(val: any) => {
                     state.editCoursewareShow = val.status;
+                    prepareStore.setIsEditResource(val.status);
                     state.editCourseware = val.groupItem;
                   }}
                 />

+ 4 - 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 {