Browse Source

添加上课记录

lex-xin 1 month ago
parent
commit
a7804501f0

+ 0 - 4
src/views/courseware-list/component/book/index.tsx

@@ -16,10 +16,6 @@ import { listenerMessage, postMessage } from '@/helpers/native-message';
 import { showToast } from 'vant';
 import queryString from 'query-string';
 import { state } from '@/state';
-import {
-  api_lessonCoursewareStudentDetail,
-  api_lessonDetailCourseware
-} from '../../api';
 import { browser } from '@/helpers/utils';
 
 export default defineComponent({

BIN
src/views/courseware-list/image/table-center.png


BIN
src/views/courseware-list/image/table-left.png


BIN
src/views/courseware-list/image/table-right.png


+ 0 - 635
src/views/courseware-list/index copy.tsx

@@ -1,635 +0,0 @@
-import { defineComponent, onMounted, reactive, ref } from 'vue';
-import styles from './index.module.less';
-import icon_back from './image/icon_back.svg';
-import icon_arrow from './image/icon_arrow.svg';
-import { Button, Popup, Tab, Tabs, Tag } from 'vant';
-import {
-  api_lessonCoursewareFavoriteRemove,
-  api_lessonCoursewareFavoriteSave,
-  api_lessonCoursewareFavoriteage,
-  api_lessonCoursewarePage,
-  api_lessonCoursewareDetail,
-  api_classLessonCoursewarePage,
-  api_classLessonCoursewareDetail,
-  api_subjectList,
-  api_bookVersionPage
-} from './api';
-import { NImage } from 'naive-ui';
-import { state } from '@/state';
-import TheFavorite from '@/components/the-favorite';
-import { useRouter } from 'vue-router';
-import TheBook from './component/book';
-import { postMessage } from '@/helpers/native-message';
-import CoursewareList from '@/custom-plugins/guide-page/courseware-list';
-import './jquery.min.1.7.js';
-import './turn.js';
-import MEmpty from '@/components/m-empty';
-import deepClone from '@/helpers/deep-clone';
-import book from './component/book';
-import { browser } from '@/helpers/utils';
-import CoursewareReload from './courseware-reload';
-
-export const BOOK_DATA = {
-  grades: [
-    // { text: '全部年级', value: '' },
-    { text: '一年级', value: 1 },
-    { text: '二年级', value: 2 },
-    { text: '三年级', value: 3 },
-    { text: '四年级', value: 4 },
-    { text: '五年级', value: 5 },
-    { text: '六年级', value: 6 },
-    { text: '七年级', value: 7 },
-    { text: '八年级', value: 8 },
-    { text: '九年级', value: 9 }
-  ],
-  bookTypes: {
-    LAST: '上册',
-    NEXT: '下册'
-  } as { [key: string]: string }
-};
-
-export default defineComponent({
-  name: 'courseware-list',
-  setup() {
-    const router = useRouter();
-    const popoverShow = ref(false);
-    const reloadStatus = ref(false);
-    const baseBookVerionList = ref([] as any);
-    const bookVersionList = ref([] as any);
-    // 返回
-    const goback = () => {
-      postMessage({ api: 'goBack' });
-    };
-    const coursewareStorage = localStorage.getItem('courseware-list')
-      ? JSON.parse(localStorage.getItem('courseware-list') as any)
-      : {};
-    const forms = reactive({
-      currentGradeNum: coursewareStorage.currentGradeNum || null,
-      bookVersionId: coursewareStorage.bookVersionId || (null as any),
-      // instrumentId:
-      //   coursewareStorage.instrumentId ||
-      //   state.user.data?.instrumentId ||
-      //   (null as any),
-      // subjectId:
-      //   coursewareStorage.subjectId ||
-      //   state.user.data?.subjectId ||
-      //   (null as any),
-      page: 1,
-      rows: 999,
-      type: 'COURSEWARE'
-    });
-    // const _actions = computed(() => {
-    //   return BOOK_DATA.grades.map((item, index) => {
-    //     return {
-    //       ...item,
-    //       color:
-    //         forms.currentGradeNum === index ? 'var(--van-primary-color)' : '',
-    //       className: forms.currentGradeNum === index ? 'fontBlod' : ''
-    //     };
-    //   });
-    // });
-    // const onSelect = (action: any, index: number) => {
-    //   forms.currentGradeNum = index;
-    //   handleChange();
-    // };
-    const isShowGuide = ref(false);
-    const data = reactive({
-      list: [] as any[],
-      loading: false,
-      favoriteList: [] as any[],
-      tab: 'all',
-      details: [] as any[],
-      bookData: {} as any,
-      bookLessonId: '',
-      subjectList: [] as any,
-      instrumentList: [] as any, // 乐器列表
-      showBook: false,
-      book: {} as DOMRect
-    });
-
-    const getTanentList = async () => {
-      try {
-        // const schoolInfos = state.user.data.schoolInfos;
-        // const schoolId =
-        //   schoolInfos && schoolInfos.length > 0 ? schoolInfos[0].id : null;
-        // if (!schoolId) return;
-        // await api_schoolDetail({
-        //   id: schoolId
-        // });
-        const { data } = await api_bookVersionPage({ type: 'COURSEWARE' });
-        const result = data.rows || [];
-        baseBookVerionList.value = result.map((item: any) => {
-          return {
-            bookVersionId: item.id,
-            bookVersionName: item.name
-          };
-        });
-        bookVersionList.value = deepClone(baseBookVerionList.value);
-        const index = baseBookVerionList.value.findIndex(
-          (item: any) => item.bookVersionId == coursewareStorage.bookVersionId
-        );
-        // 判断列表中是存在,缓存的教材数据
-        if (index < 0) {
-          forms.bookVersionId = null;
-        }
-      } catch (e) {
-        //
-        console.log(e);
-      }
-    };
-
-    const getList = async () => {
-      data.loading = true;
-      const { bookVersionId, currentGradeNum, ...more } = forms;
-      const res = await api_lessonCoursewarePage({
-        ...more,
-        bookVersionId: bookVersionId == -1 ? null : bookVersionId,
-        currentGradeNum: currentGradeNum ? currentGradeNum : ''
-      });
-      if (res?.code === 200 && Array.isArray(res?.data?.rows)) {
-        data.list = res.data.rows.map((item: any) => {
-          item.load = false;
-          item.key = Date.now() + item.id;
-          return item;
-        });
-      }
-      data.loading = false;
-      setTimeout(() => {
-        isShowGuide.value = true;
-      }, 100);
-    };
-    const getFavoriteList = async () => {
-      data.loading = true;
-      const res = await api_lessonCoursewareFavoriteage({
-        clientType: 'STUDENT',
-        userId: state.user?.data?.id,
-        page: forms.page,
-        rows: forms.rows,
-        // subjectId: forms.subjectId,
-        bookVersionId: forms.bookVersionId != -1 ? forms.bookVersionId : '',
-        currentGradeNum: forms.currentGradeNum ? forms.currentGradeNum : ''
-      });
-      if (res?.code === 200 && Array.isArray(res?.data?.rows)) {
-        data.list = res.data.rows.map((item: any) => {
-          item.name = `${item.name}`;
-          item.load = false;
-          item.favoriteFlag = true;
-          item.key = Date.now() + item.id;
-          return item;
-        });
-      }
-      data.loading = false;
-    };
-    const getLessonCourseware = async () => {
-      data.loading = true;
-      const res = await api_classLessonCoursewarePage({
-        // clientType: 'STUDENT',
-        // userId: state.user?.data?.id,
-        bookVersionId: forms.bookVersionId ? forms.bookVersionId : '',
-        page: forms.page,
-        rows: forms.rows,
-        // subjectId: forms.subjectId,
-        currentGradeNum: forms.currentGradeNum ? forms.currentGradeNum : ''
-      });
-      if (res?.code === 200 && Array.isArray(res?.data?.rows)) {
-        data.list = res.data.rows.map((item: any) => {
-          item.load = false;
-          item.key = Date.now() + item.id;
-          return item;
-        });
-      }
-      data.loading = false;
-      // isShowGuide.value = true;
-    };
-    const getData = () => {
-      if (data.tab === 'all') {
-        getList();
-      }
-      if (data.tab === 'favorite') {
-        getFavoriteList();
-      }
-      if (data.tab === 'course') {
-        getLessonCourseware();
-      }
-    };
-    const contentContainerRef = ref();
-    const handleChange = () => {
-      if (data.tab === 'course') {
-        bookVersionList.value = [
-          ...deepClone(baseBookVerionList.value),
-          {
-            bookVersionId: -1,
-            bookVersionName: '自定义'
-          }
-        ];
-      } else {
-        bookVersionList.value = deepClone(baseBookVerionList.value);
-      }
-
-      getData();
-
-      if (contentContainerRef.value && browser().isTablet) {
-        contentContainerRef.value.scrollTo(0, 0);
-      }
-    };
-
-    const getSubjectList = async () => {
-      try {
-        const res = await api_subjectList({
-          enableFlag: true,
-          delFlag: 0,
-          page: 1,
-          rows: 999
-        });
-        // console.log(res.data, ' subjectList');
-        data.subjectList = res.data.rows || [];
-      } catch {}
-    };
-    onMounted(async () => {
-      window.addEventListener('error', (e: any) => {
-        console.log(e, 'error');
-      });
-      // console.log(browser().isTablet, 'browser().isTablet');
-      await getTanentList();
-      await getSubjectList();
-
-      // if (forms.subjectId && data.subjectList.length > 0) {
-      //   data.subjectList.forEach((item: any) => {
-      //     if (item.id == forms.subjectId) {
-      //       data.instrumentList = item.instruments || [];
-      //     }
-      //   });
-      // }
-      getData();
-      // 安卓的状态栏
-      postMessage({
-        api: 'setStatusBarVisibility',
-        content: {
-          isVisibility: 0
-        }
-      });
-    });
-
-    const handleFavorite = async (item: any) => {
-      if (item.favoriteFlag) {
-        await api_lessonCoursewareFavoriteSave({
-          lessonCoursewareId: item.id
-        });
-      } else {
-        await api_lessonCoursewareFavoriteRemove({
-          lessonCoursewareId: item.id
-        });
-        if (data.tab === 'favorite') {
-          // getData();
-          // item.favoriteFlag = !item.favoriteFlag;
-        }
-      }
-    };
-
-    let timer: any = null;
-    const dubounce = (fn: any, delay: number = 300) => {
-      if (timer) {
-        clearTimeout(timer);
-      }
-      timer = setTimeout(fn, delay);
-    };
-
-    /** 学生端根据教材编号获取关联的单元、章节 */
-    const getDetail = async (item: any) => {
-      if (data.tab === 'course') {
-        const res = await api_classLessonCoursewareDetail({
-          id: item.id
-          // subjectId: forms.subjectId
-        });
-        if (res?.code == 200 && Array.isArray(res?.data?.lessonList)) {
-          data.details = res.data.lessonList || [];
-          data.bookData = res.data;
-          data.bookLessonId = item.id;
-          console.log('🚀 ~ data.details course:', data.details);
-        } else {
-          // showConfirmDialog({
-          //   title: '提示',
-          //   message: '课程教材已更新,是否重新加载?'
-          // })
-          //   .then(() => {
-          //     // on confirm
-          //     getData();
-          //   })
-          //   .catch(() => {
-          //     // on cancel
-          //   });
-          reloadStatus.value = true;
-          return;
-        }
-      } else {
-        const res = await api_lessonCoursewareDetail({
-          id: item.id
-          // subjectId: forms.subjectId
-        });
-        if (res?.code == 200 && Array.isArray(res?.data?.lessonList)) {
-          data.details = res.data.lessonList || [];
-          data.bookData = res.data;
-          data.bookLessonId = item.id;
-          console.log('🚀 ~ data.details:', data.details);
-        }
-      }
-
-      handleCreateContainer(item.id);
-      handleRender(() => {
-        data.showBook = true;
-      });
-    };
-
-    const handleCreateContainer = (id: string) => {
-      const box = document.querySelector(
-        `[data-id="${id}"]`
-      ) as unknown as HTMLElement;
-      if (!box) return;
-      const rect = box.getBoundingClientRect();
-      data.book = rect;
-    };
-    const handleRender = (fn: any) => {
-      requestAnimationFrame(() => {
-        requestAnimationFrame(() => {
-          fn();
-        });
-      });
-    };
-    const handleOpen = async (item: any) => {
-      await getDetail(item);
-    };
-
-    return () => (
-      <div
-        class={[
-          styles.container,
-          // styles.containerTablet,
-          browser().isTablet ? styles.containerTablet : ''
-        ]}>
-        <div class={styles.head} style={{ opacity: data.showBook ? 0 : '' }}>
-          <div class={styles.back} onClick={goback}>
-            <img src={icon_back} />
-          </div>
-          <Tabs
-            class={styles.tabs}
-            v-model:active={data.tab}
-            onChange={() => handleChange()}>
-            <Tab title="全部教材" name="all"></Tab>
-            <Tab title="课程教材" name="course"></Tab>
-            <Tab
-              name="favorite"
-              v-slots={{
-                title: () => <div id="courseware-2">我的收藏</div>
-              }}></Tab>
-          </Tabs>
-          <Button
-            class={[
-              styles.downBtn,
-              (data.tab != 'course' && forms.bookVersionId > 0) ||
-              (data.tab == 'course' && forms.bookVersionId) ||
-              forms.currentGradeNum
-                ? styles.activeBtn
-                : ''
-            ]}
-            round
-            size="small"
-            onClick={() => (popoverShow.value = true)}
-            {...{ id: 'courseware-3' }}>
-            筛选
-            <svg
-              class={[styles.icon, popoverShow.value ? styles.iconUp : '']}
-              width="9px"
-              height="5px"
-              viewBox="0 0 9 5"
-              version="1.1"
-              xmlns="http://www.w3.org/2000/svg">
-              <title>三角形</title>
-              <g
-                id="演示用"
-                stroke="none"
-                stroke-width="1"
-                fill="currentColor"
-                fill-rule="evenodd">
-                <g
-                  id="全部教材-筛选"
-                  transform="translate(-769.000000, -35.000000)"
-                  fill="currentColor">
-                  <g id="编组-3" transform="translate(696.000000, 20.000000)">
-                    <g
-                      id="筛选目录备份-2"
-                      transform="translate(13.000000, 7.000000)">
-                      <path
-                        d="M64.8716471,8.41294119 L68.2489659,12.1655176 C68.4336954,12.3707726 68.4170562,12.6869176 68.2118012,12.8716471 C68.1199888,12.9542782 68.0008397,13 67.8773188,13 L61.1226812,13 C60.8465388,13 60.6226812,12.7761424 60.6226812,12.5 C60.6226812,12.3764791 60.668403,12.25733 60.7510341,12.1655176 L64.1283529,8.41294119 C64.3130824,8.20768618 64.6292274,8.19104698 64.8344824,8.37577649 C64.8475136,8.38750459 64.859919,8.39990996 64.8716471,8.41294119 Z"
-                        id="三角形"
-                        transform="translate(64.500000, 10.500000) rotate(-180.000000) translate(-64.500000, -10.500000) "></path>
-                    </g>
-                  </g>
-                </g>
-              </g>
-            </svg>
-          </Button>
-        </div>
-
-        <div
-          ref={contentContainerRef}
-          class={[
-            styles.content,
-            data.list.length <= 0 && !data.loading ? styles.contentEmpty : ''
-          ]}>
-          <div
-            class={[
-              styles.wrap,
-              data.list.length <= 0 && !data.loading ? styles.emtpyWrap : ''
-            ]}>
-            {data.list.map((item, index) => {
-              return (
-                <div
-                  class={[
-                    styles.wrapItem,
-                    data.bookData.id === item.id && data.showBook
-                      ? styles.wrapItemHide
-                      : ''
-                  ]}
-                  key={item.key}
-                  onClick={() => handleOpen(item)}>
-                  {/* courseware- */}
-
-                  <div class={styles.item}>
-                    <NImage
-                      data-id={item.id}
-                      {...{ id: index == 0 ? 'courseware-0' : '' }}
-                      class={[styles.cover, item.load ? styles.loaded : '']}
-                      objectFit="cover"
-                      src={item.coverImg}
-                      onLoad={() => {
-                        item.load = true;
-                      }}
-                    />
-                  </div>
-
-                  <div class={styles.name}>{item.name}</div>
-                  {/* 课程教材不需要收藏 */}
-                  {!data.loading && data.tab !== 'course' && (
-                    <div
-                      id={index === 0 ? 'courseware-1' : ''}
-                      class={styles.favoriteBtn}
-                      onClick={(e: Event) => {
-                        e.stopPropagation();
-                        item.favoriteFlag = !item.favoriteFlag;
-                        dubounce(() => handleFavorite(item));
-                      }}>
-                      <TheFavorite isFavorite={item.favoriteFlag} />
-                    </div>
-                  )}
-                </div>
-              );
-            })}
-
-            {data.list.length <= 0 && !data.loading && (
-              <MEmpty image="list" description="暂无数据" />
-            )}
-          </div>
-        </div>
-        <TheBook
-          show={data.showBook}
-          bookData={data.bookData}
-          bookLessonId={data.bookLessonId}
-          // subjectId={forms.subjectId}
-          tab={data.tab}
-          rect={data.book}
-          onClose={() => {
-            data.showBook = false;
-          }}
-          onConfirm={() => {
-            getData();
-          }}
-        />
-
-        {isShowGuide.value ? <CoursewareList></CoursewareList> : null}
-
-        <Popup v-model:show={popoverShow.value} class={styles.popupContainer}>
-          <div class={styles.popoverContainer}>
-            <div class={styles.searchList}>
-              {bookVersionList.value.length > 0 && (
-                <>
-                  <div class={styles.popoverTitle}>教材版本</div>
-                  <div class={[styles.popupList, styles.versionList]}>
-                    {bookVersionList.value.map((item: any) => (
-                      <Tag
-                        plain={forms.bookVersionId == item.bookVersionId}
-                        round
-                        onClick={() =>
-                          (forms.bookVersionId = item.bookVersionId)
-                        }>
-                        {item.bookVersionName}
-                      </Tag>
-                    ))}
-                  </div>
-                </>
-              )}
-
-              <div class={styles.popoverTitle}>选择年级</div>
-              <div class={[styles.popupList, styles.versionList]}>
-                {BOOK_DATA.grades.map((item: any) => (
-                  <Tag
-                    plain={forms.currentGradeNum === item.value}
-                    round
-                    onClick={() => (forms.currentGradeNum = item.value)}>
-                    {item.text}
-                  </Tag>
-                ))}
-              </div>
-
-              {/* <div class={styles.popoverTitle}>选择声部</div>
-              <div class={[styles.popupList, styles.versionList]}>
-                {data.subjectList.map((item: any) => (
-                  <span
-                    // plain={forms.subjectId == item.id}
-                    class={[
-                      styles.subjectItem,
-                      forms.subjectId == item.id && styles.active,
-                      item.instruments?.length > 0 && styles.arrow
-                    ]}
-                    onClick={() => {
-                      forms.subjectId = item.id;
-                      data.instrumentList = item.instruments || [];
-                      if (data.instrumentList.length > 0) {
-                        forms.instrumentId = data.instrumentList[0].id;
-                      }
-                    }}>
-                    {item.name}
-                  </span>
-                ))}
-              </div>
-
-              {data.instrumentList.length > 0 && (
-                <>
-                  <div class={styles.popoverTitle}>选择乐器</div>
-                  <div class={[styles.popupList, styles.versionList]}>
-                    {data.instrumentList.map((item: any) => (
-                      <Tag
-                        plain={forms.instrumentId == item.id}
-                        round
-                        onClick={() => (forms.instrumentId = item.id)}>
-                        {item.name}
-                      </Tag>
-                    ))}
-                  </div>
-                </>
-              )}*/}
-            </div>
-
-            <div class={styles.btnGroup}>
-              <Button
-                round
-                onClick={() => {
-                  forms.bookVersionId = null;
-                  forms.currentGradeNum = null;
-                  // forms.subjectId = state.user.data?.subjectId || null;
-                  // forms.instrumentId = state.user.data?.instrumentId || null;
-                  // if (forms.subjectId && data.subjectList.length > 0) {
-                  //   data.subjectList.forEach((item: any) => {
-                  //     if (item.id == forms.subjectId) {
-                  //       data.instrumentList = item.instruments || [];
-                  //     }
-                  //   });
-                  // }
-                }}>
-                重置
-              </Button>
-              <Button
-                round
-                class={styles.btnSure}
-                onClick={() => {
-                  // 保存缓存
-                  localStorage.setItem(
-                    'courseware-list',
-                    JSON.stringify({
-                      bookVersionId: forms.bookVersionId,
-                      currentGradeNum: forms.currentGradeNum
-                      // subjectId: forms.subjectId,
-                      // instrumentId: forms.instrumentId
-                    })
-                  );
-                  getData();
-                  popoverShow.value = false;
-                }}>
-                确认
-              </Button>
-            </div>
-          </div>
-        </Popup>
-
-        {reloadStatus.value && (
-          <CoursewareReload
-            onClose={() => {
-              reloadStatus.value = false;
-            }}
-            onConfirm={() => {
-              getData();
-            }}></CoursewareReload>
-        )}
-      </div>
-    );
-  }
-});

+ 5 - 4
src/views/courseware-list/index.module.less

@@ -150,7 +150,7 @@
     &::after {
       content: '';
       position: absolute;
-      width: 68%;
+      width: 55%;
       background: url('./image/table-center.png') repeat-x center;
       background-size: contain;
       height: 26px;
@@ -186,8 +186,10 @@
     margin-bottom: 28px;
     width: 100%;
     height: 150px;
-    background-color: #edeff2;
-    box-shadow: 0 5px 14px rgba(0, 0, 0, 0.4);
+    // background-color: #edeff2;
+    background: linear-gradient(180deg, #fff4e8 0%, #fff0dc 100%);
+    // box-shadow: 0 5px 14px rgba(0, 0, 0, 0.4);
+    box-shadow: 0px 6px 5px 0px rgba(0, 0, 0, 0.24);
 
     img {
       position: absolute;
@@ -521,7 +523,6 @@
   }
 }
 
-
 @media screen and(max-width: 800px) {
   .content {
     .warpSection {

+ 17 - 0
src/views/courseware-play/api.ts

@@ -15,3 +15,20 @@ export const api_classLessonCoursewareQuery = (params: any): Promise<any> => {
     data: params
   });
 };
+
+
+
+
+/** 获取学生上课记录 */
+export const api_courseScheduleStudentPage = (params: any): Promise<any> => {
+  return request.post('/edu-app/courseSchedule/studentPage', {
+    data: params
+  });
+};
+
+/** 根据课程编号获取课件详情 */
+export const api_classChapterExpendDetailCourseware = (params: any): Promise<any> => {
+  return request.post('/edu-app/classChapterExpend/detailCourseware', {
+    params
+  });
+};

+ 139 - 0
src/views/courseware-play/component/chapter-course.module.less

@@ -0,0 +1,139 @@
+.container {
+  display: flex;
+  flex-direction: column;
+  min-width: 266px;
+  max-width: 266px;
+  height: 100vh;
+  color: #333;
+  font-size: 12px;
+  box-sizing: border-box;
+  background: #fff;
+}
+
+.pointHead {
+  display: flex;
+  align-items: center;
+  padding: 16px 0 12px 0;
+  margin: 0 14px 0 14px;
+  flex-shrink: 0;
+  font-size: 14px;
+  font-weight: 500;
+  border-bottom: 1px solid #f2f2f2;
+
+  img {
+    width: 16px;
+    height: 16px;
+    margin-right: 7px;
+  }
+}
+
+.content {
+  position: relative;
+  flex: 1;
+  overflow-x: hidden;
+  overflow-y: auto;
+  padding: 12px 14px 12px 36px;
+
+  &::-webkit-scrollbar {
+    width: 0;
+    display: none;
+  }
+
+  .list {
+    position: relative;
+    &::before {
+      content: '';
+      position: absolute;
+      width: 0;
+      height: 100%;
+      top: 0;
+      bottom: 0;
+      left: -10px;
+      border-left: 2px dashed #dbdbdb;
+    }
+  }
+
+  .item {
+    position: relative;
+    margin-bottom: 8px;
+    h2 {
+      font-size: 18px;
+      color: #333333;
+      line-height: 21px;
+      font-family: DINAlternate-Bold, DINAlternate;
+      span {
+        font-size: 12px;
+      }
+    }
+    h3 {
+      position: relative;
+      padding-top: 2px;
+      font-family: DINAlternate, DINAlternate;
+      font-size: 14px;
+      color: #777777;
+      line-height: 16px;
+
+      &::before {
+        content: '';
+        position: absolute;
+        left: -12px;
+        top: 50%;
+        margin-top: -3px;
+        width: 6px;
+        height: 6px;
+        background: #AAAAAA;
+        border-radius: 50%;
+      }
+    }
+
+    .item_inner {
+      position: relative;
+      background: #ffffff;
+      border-radius: 6px;
+      border: 2px solid #f2f2f2;
+      padding: 10px;
+      margin: 4px 0;
+
+      &.active {
+        border: 2px solid #daecff;
+        background: #f2f8ff;
+        .title {
+          color: #1CACF1;
+        }
+      }
+      .currentImg {
+        position: absolute;
+        top: 5px;
+        right: 5px;
+        width: 30px;
+        height: 16px;
+      }
+
+      .title {
+        font-weight: 600;
+        font-size: 13px;
+        color: #333333;
+        line-height: 18px;
+        max-width: 165px;
+        overflow: hidden;
+        text-overflow: ellipsis;
+        white-space: nowrap;
+      }
+
+      .timers {
+        padding-top: 6px;
+        display: flex;
+        align-items: center;
+        font-size: 12px;
+        color: #777777;
+        line-height: 17px;
+        .courseTimer {
+          width: 18px;
+          height: 18px;
+          margin-right: 2px;
+          padding-top: 0px;
+        }
+      }
+    }
+  }
+}

+ 91 - 0
src/views/courseware-play/component/chapter-course.tsx

@@ -0,0 +1,91 @@
+import { defineComponent, reactive, toRefs, watch } from 'vue';
+import styles from './chapter-course.module.less';
+import iconMenuChapter from '../image/icon-course-c.svg';
+import iconCourseTimer from '../image/icon-course-timer.svg';
+import iconCurrentImg from '../image/icon-current-img.png';
+
+export default defineComponent({
+  name: 'chapter',
+  props: {
+    detail: {
+      type: Object,
+      default: () => []
+    },
+    itemActive: {
+      type: String,
+      default: ''
+    },
+    popShow: {
+      type: Boolean,
+      default: false
+    }
+  },
+  emits: ['handleSelect'],
+  setup(props, { emit }) {
+    const { detail, itemActive } = toRefs(props);
+
+    // watch(
+    //   () => props.popShow,
+    //   () => {
+    //     if (props.popShow) {
+    //       // pointData.active = props.active;
+    //     }
+    //   }
+    // );
+    return () => (
+      <div class={styles.container}>
+        <div class={styles.pointHead}>
+          <img src={iconMenuChapter} />
+          上课记录
+        </div>
+        <div class={styles.content}>
+          <div class={styles.list}>
+            {detail.value.map((year: any) => (
+              <div class={styles.item}>
+                <h2>
+                  {year.year}
+                  <span>年</span>
+                </h2>
+                {year.list.map((month: any) => (
+                  <div>
+                    <h3>{month.month}月</h3>
+
+                    {month.list.map((item: any) => (
+                      <div
+                        class={[
+                          styles.item_inner,
+                          itemActive.value === item.courseId
+                            ? styles.active
+                            : ''
+                        ]}
+                        onClick={() => {
+                          emit('handleSelect', {
+                            itemActive: item.courseId
+                          })
+                        }}>
+                        {itemActive.value === item.courseId ? (
+                          <img src={iconCurrentImg} class={styles.currentImg} />
+                        ) : (
+                          ''
+                        )}
+
+                        <div class={styles.title}>{item.courseName}</div>
+                        <div class={styles.timers}>
+                          <img
+                            src={iconCourseTimer}
+                            class={styles.courseTimer}
+                          />
+                          <span>上课时间:{item.classDate}</span>
+                        </div>
+                      </div>
+                    ))}
+                  </div>
+                ))}
+              </div>
+            ))}
+          </div>
+        </div>
+      </div>
+    );
+  }
+});

+ 28 - 0
src/views/courseware-play/image/icon-course-c.svg

@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="20px" height="20px" viewBox="0 0 20 20" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>课程目录</title>
+    <defs>
+        <linearGradient x1="50%" y1="0%" x2="50%" y2="100%" id="linearGradient-1">
+            <stop stop-color="#FFB790" offset="0%"></stop>
+            <stop stop-color="#FF8057" offset="100%"></stop>
+        </linearGradient>
+        <linearGradient x1="50%" y1="26.807622%" x2="50%" y2="100%" id="linearGradient-2">
+            <stop stop-color="#ACD7FF" offset="0%"></stop>
+            <stop stop-color="#FFB469" offset="100%"></stop>
+        </linearGradient>
+        <path d="M0,10 C0.045380368,6.68544475 0.62101804,3.94093846 2.30411553,2.30411553 C3.94093846,0.62101804 6.68544475,0.045380368 10,0 C13.3145553,0.045380368 16.0590615,0.62101804 17.6958845,2.30411553 C19.378982,3.94093846 19.9546196,6.68544475 20,10 C19.9546196,13.3145553 19.378982,16.0590615 17.6958845,17.6958845 C16.0590615,19.378982 13.3145553,19.9546196 10,20 C6.68544475,19.9546196 3.94093846,19.378982 2.30411553,17.6958845 C0.62101804,16.0590615 0.045380368,13.3145553 0,10 Z" id="path-3"></path>
+    </defs>
+    <g id="2025.1.8-作业-首页-我的教材" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="上课记录弹框" transform="translate(-528, -18)" fill-rule="nonzero">
+            <g id="编组-14" transform="translate(514, 0)">
+                <g id="课程目录" transform="translate(14, 18)">
+                    <g id="路径">
+                        <use fill="url(#linearGradient-1)" xlink:href="#path-3"></use>
+                        <use fill="url(#linearGradient-2)" xlink:href="#path-3"></use>
+                    </g>
+                    <path d="M12.2884566,12.4793285 C12.5956603,12.1721247 12.5956603,11.674049 12.2884566,11.3668453 L10.9375841,10.0159729 L10.9375841,10.0159729 L10.9375841,7.47315419 C10.9375841,7.0342917 10.5818158,6.67852335 10.1429533,6.67852335 C9.70409079,6.67852335 9.34832244,7.0342917 9.34832244,7.47315419 L9.34832244,10.6516776 L9.34832244,10.6516776 L11.1759734,12.4793285 C11.4831771,12.7865322 11.9812528,12.7865322 12.2884566,12.4793285 Z M3.76993368,6.66255047 L4.97785283,7.87046961 L4.97785283,7.87046961 L5.53409441,8.4267112 C6.16979909,6.51959719 7.99745002,5.08926167 10.1429533,5.08926167 C12.7652351,5.08926167 14.9107383,7.23476494 14.9107383,9.85704671 C14.9107383,12.4793285 12.7652351,14.6248318 10.1429533,14.6248318 C7.75906077,14.6248318 5.77248366,12.8766439 5.45463134,10.5722145 L3.86536964,8.9829528 C3.78590655,9.30080514 3.78590655,9.53919439 3.78590657,9.85704671 C3.78590657,13.3534224 6.6465776,16.2140934 10.1429533,16.2140934 C13.639329,16.2140934 16.5,13.3534224 16.5,9.85704671 C16.5,6.36067102 13.639329,3.5 10.1429533,3.5 C8.15637618,3.5 6.40818834,4.45355701 5.21624208,5.88389252 L4.42161124,5.08926167 C3.91261941,5.08926167 3.5,5.50188108 3.5,6.01087291 C3.5,6.25529941 3.59709805,6.48971483 3.76993368,6.66255047 Z" id="形状" fill="#FFFFFF"></path>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

+ 26 - 0
src/views/courseware-play/image/icon-course-timer.svg

@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="18px" height="18px" viewBox="0 0 18 18" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+    <title>直播</title>
+    <defs>
+        <path d="M0,7.20283723 C0,3.23729414 3.22777882,0.00568944489 7.18862713,0 C11.1665236,0 14.4056678,3.23729414 14.3999926,7.20852668 C14.3943024,11.1683803 11.1551581,14.3999925 7.19430983,14.3999925 C3.23346153,14.4056745 0.00568270919,11.1740698 0,7.20283723 Z M7.21135796,1.53045108 C4.06313707,1.52477123 1.52863926,4.05088476 1.52863926,7.19714779 C1.52296606,10.3377214 4.06313707,12.8809032 7.19999254,12.8809032 C10.3197999,12.8809032 12.8656536,10.3434108 12.8713744,7.22559501 C12.8827017,4.08502143 10.3482134,1.53615012 7.21135796,1.53045108 Z" id="path-1"></path>
+    </defs>
+    <g id="2025.1.8-作业-首页-我的教材" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="上课记录弹框" transform="translate(-560, -148)" fill-rule="nonzero">
+            <g id="编组-14" transform="translate(514, 0)">
+                <g id="编组-10" transform="translate(36, 114)">
+                    <g transform="translate(10, 34)" id="编组-5">
+                        <g id="直播" transform="translate(0, 1.8)">
+                            <g id="编组" transform="translate(1.8, 0)">
+                                <g id="形状">
+                                    <use fill="#1CACF1" xlink:href="#path-1"></use>
+                                    <use fill="#9CCFFF" xlink:href="#path-1"></use>
+                                </g>
+                                <path d="M7.71711908,6.43476217 L8.05239892,6.43476217 C8.84797821,6.43476217 9.63787479,6.42907273 10.4334541,6.44045162 C11.0642348,6.44614106 11.4279282,6.91836499 11.2403988,7.4645517 C11.1324273,7.77747117 10.8994362,7.94815451 10.5812045,7.95384396 C9.42761455,7.96522285 8.27970729,7.97091229 7.12611732,7.95384396 C6.58057724,7.94246507 6.19983573,7.5157567 6.19415302,6.93543332 C6.1827876,5.84874935 6.1827876,4.76206537 6.19415302,3.6753814 C6.19983573,3.18608914 6.52375015,2.86748022 6.96700147,2.87316967 C7.41025278,2.87885911 7.71143637,3.20315747 7.71711908,3.69244973 C7.72280179,4.49466146 7.71711908,5.29687319 7.71711908,6.10477437 L7.71711908,6.43476217 L7.71711908,6.43476217 Z" id="路径" fill="#FFAD17"></path>
+                            </g>
+                        </g>
+                    </g>
+                </g>
+            </g>
+        </g>
+    </g>
+</svg>

BIN
src/views/courseware-play/image/icon-current-img.png


BIN
src/views/courseware-play/image/icon-record.png


+ 5 - 0
src/views/courseware-play/index.module.less

@@ -218,6 +218,11 @@
   border-radius: 6px;
   overflow: hidden;
 
+  img {
+    width: 24px;
+    height: 24px;
+  }
+
   &:not(:last-child):not(:first-child) {
     margin: 8px 0;
   }

+ 253 - 74
src/views/courseware-play/index.tsx

@@ -21,6 +21,7 @@ import {
 import MusicScore from './component/musicScore';
 import iconMenu from './image/icon-menu.svg';
 import iconChange from './image/icon-change.svg';
+import iconRecord from './image/icon-record.png';
 // import iconDian from './image/icon-dian.svg';
 // import iconPoint from './image/icon-point.svg';
 import iconUp from './image/icon-up.svg';
@@ -46,6 +47,11 @@ import ListenItem from './component/listen-item';
 import request from '@/helpers/request';
 import PptList from './component/PptList';
 import SelectCoursewareTip from './select-courseware-tip';
+import {
+  api_classChapterExpendDetailCourseware,
+  api_courseScheduleStudentPage
+} from './api';
+import ChapterCourse from './component/chapter-course';
 
 export default defineComponent({
   name: 'CoursewarePlay',
@@ -115,19 +121,6 @@ export default defineComponent({
       window.removeEventListener('offline', handleOffline);
     });
 
-    const getCourseDetail = async () => {
-      try {
-        const res = await api_lessonCoursewareDetail({
-          id: activeData.lessonCoursewareId as any
-        });
-        if (res?.code == 200 && Array.isArray(res?.data?.lessonList)) {
-          data.courseDetails = res.data.lessonList || [];
-        }
-      } catch {
-        //
-      }
-    };
-
     const route = useRoute();
     const headeRef = ref();
     const loadingClass = ref(false); // 重新加载课件
@@ -135,11 +128,12 @@ export default defineComponent({
       disableScreenRecordingFlag: '0',
       allList: [] as any, // 所选章节下的所有课件列表
       id: route.query.id as string, // 章节ID
-
       kjId: route.query.id as string, // 所选的课件id
+      courseId: route.query.courseId as string, // 上课记录
       currentCourse: {} as any, // 当前选中的课件
       zsdId: '' as string, // 知识点id
       courseDetails: [] as any,
+      formatCourseList: [] as any, // 格式化课程数据
       itemList: [] as any,
       videoRefs: {} as any[],
       videoState: 'init' as 'init' | 'play',
@@ -180,6 +174,10 @@ export default defineComponent({
       if (res?.code !== 200) return;
 
       // data.allList = [res.data];
+      _initDefaultData(res);
+    };
+
+    const _initDefaultData = (res: any) => {
       const currentCourse = res?.data;
       const knowledgeList = currentCourse?.knowledgeList || [];
 
@@ -240,6 +238,7 @@ export default defineComponent({
           isRender: false // 是否渲染了
         };
       });
+
       const resourceIndex = data.itemList.findIndex(
         (resource: any) => resource.id === resourceId
       );
@@ -257,6 +256,90 @@ export default defineComponent({
       }, 500);
     };
 
+    const getCourseWareDetail = async () => {
+      try {
+        const res = await api_lessonCoursewareDetail({
+          id: activeData.lessonCoursewareId as any,
+          rows: -1
+        });
+        if (res?.code == 200 && Array.isArray(res?.data?.lessonList)) {
+          data.courseDetails = res.data.lessonList || [];
+        }
+      } catch {
+        //
+      }
+    };
+
+    const getStudentCourseDetail = async () => {
+      try {
+        const res = await api_classChapterExpendDetailCourseware({
+          courseId: data.courseId
+        });
+        if (res?.code === 200) {
+          _initDefaultData(res);
+        }
+      } catch {
+        //
+      }
+    };
+
+    // 上课记录
+    const getCourseScheduleDetail = async () => {
+      try {
+        const res = await api_courseScheduleStudentPage({});
+        if (res?.code === 200 && Array.isArray(res?.data.rows)) {
+          const result = res?.data.rows || [];
+
+          const tempObj: any = {};
+          // 格式化成年的数组
+          result.forEach((item: any) => {
+            item.lessonCourseware = item.lessonCoursewareJson
+              ? JSON.parse(item.lessonCoursewareJson)
+              : {};
+            const tempItem = item;
+            if (tempObj[item.year]) {
+              tempObj[item.year].push(tempItem);
+            } else {
+              tempObj[item.year] = [tempItem];
+            }
+          });
+
+          data.courseDetails = result || [];
+
+          const formatList: any[] = [];
+          for (let key in tempObj) {
+            const tempY = tempObj[key];
+            const tempResult: any = [];
+
+            if (Array.isArray(tempY)) {
+              tempY.forEach((y: any) => {
+                const index = tempResult.findIndex(
+                  (r: any) => r.month === y.month
+                );
+                if (index !== -1) {
+                  tempResult[index].list.push(y);
+                } else {
+                  tempResult.push({
+                    month: y.month,
+                    list: [{ ...y }]
+                  });
+                }
+              });
+            }
+
+            formatList.push({
+              year: key,
+              list: tempResult
+            });
+          }
+
+          data.formatCourseList = formatList;
+        }
+      } catch (e) {
+        //
+      }
+    };
+
     // ifram事件处理
     const iframeHandle = (ev: MessageEvent) => {
       if (ev.data?.api === 'headerTogge') {
@@ -366,8 +449,15 @@ export default defineComponent({
           type: 'fullscreen'
         }
       });
-      getDetail();
-      getCourseDetail();
+      // 上课记录
+      if (data.courseId) {
+        getStudentCourseDetail();
+        getCourseScheduleDetail();
+      } else {
+        getDetail();
+        getCourseWareDetail();
+      }
+
       window.addEventListener('message', iframeHandle);
 
       if (data.disableScreenRecordingFlag === '1') {
@@ -413,7 +503,8 @@ export default defineComponent({
       itemActive: '',
       itemName: '',
       itemPointName: '' as any,
-      chapterOpen: false
+      chapterOpen: false,
+      chapterCourseOpen: false
     });
 
     // 切换素材
@@ -601,6 +692,22 @@ export default defineComponent({
           return;
         }
 
+        if (data.courseId) {
+          const detailIndex = data.courseDetails.findIndex(
+            (item: any) => item.courseId === data.courseId
+          );
+          // 是否为第一节课
+          if (detailIndex - 1 >= 0) {
+            changeCourseWareItem(
+              {
+                id: data.courseDetails[detailIndex - 1].courseId
+              },
+              type
+            );
+          }
+          return;
+        }
+
         // 获取当前是哪个章节
         let detailIndex = data.courseDetails.findIndex(
           (item: any) => item.id == activeData.lessonCoursewareDetailId
@@ -694,6 +801,21 @@ export default defineComponent({
           return;
         }
 
+        if (data.courseId) {
+          const detailIndex = data.courseDetails.findIndex(
+            (item: any) => item.courseId === data.courseId
+          );
+          if (detailIndex + 1 >= data.courseDetails.length - 1) {
+            changeCourseWareItem(
+              {
+                id: data.courseDetails[detailIndex + 1].courseId
+              },
+              type
+            );
+          }
+          return;
+        }
+
         // 获取当前是哪个单元
         let detailIndex = data.courseDetails.findIndex(
           (item: any) => item.id == activeData.lessonCoursewareDetailId
@@ -795,67 +917,80 @@ export default defineComponent({
           return true;
         }
       }
-      /**
-       * 1,判断当前课程中是否处在第一个资源;
-       * 2,判断当前课程是否在当前章节的第一个;
-       * 3,判断当前章节,当前课程上面还没有其它课程,是否有资源;
-       * 4,判断当前章节上面还没有其它章节;
-       * 5,判断上面章节里面课程是否有资源;
-       */
+
       if (popupData.activeIndex > 0) {
         return true;
       }
 
-      // 获取当前是哪个章节
-      let detailIndex = data.courseDetails.findIndex(
-        (item: any) => item.id == activeData.lessonCoursewareDetailId
-      );
-      const detailItem = data.courseDetails[detailIndex]?.knowledgeList || [];
-      let lessonIndex = detailItem.findIndex((item: any) => item.id == data.id);
+      // 判断是否是从课程进来的
+      if (data.courseId) {
+        const detailIndex = data.courseDetails.findIndex(
+          (item: any) => item.courseId === data.courseId
+        );
+        // 是否为第一节课
+        return detailIndex - 1 >= 0 ? true : false;
+      } else {
+        /**
+         * 1,判断当前课程中是否处在第一个资源;
+         * 2,判断当前课程是否在当前章节的第一个;
+         * 3,判断当前章节,当前课程上面还没有其它课程,是否有资源;
+         * 4,判断当前章节上面还没有其它章节;
+         * 5,判断上面章节里面课程是否有资源;
+         */
+        // 获取当前是哪个章节
+        let detailIndex = data.courseDetails.findIndex(
+          (item: any) => item.id == activeData.lessonCoursewareDetailId
+        );
+        const detailItem = data.courseDetails[detailIndex]?.knowledgeList || [];
+        let lessonIndex = detailItem.findIndex(
+          (item: any) => item.id == data.id
+        );
 
-      // 说明已经是第一单元,第一课
-      if (detailIndex <= 0 && lessonIndex <= 0) {
-        return false;
-      }
+        // 说明已经是第一单元,第一课
+        if (detailIndex <= 0 && lessonIndex <= 0) {
+          return false;
+        }
 
-      let lessonStatus = false; // 当前章节上面是否有内容
-      while (lessonIndex >= 0) {
-        lessonIndex--;
+        let lessonStatus = false; // 当前章节上面是否有内容
+        while (lessonIndex >= 0) {
+          lessonIndex--;
 
-        if (lessonIndex >= 0) {
-          if (detailItem[lessonIndex].containMaterial) {
-            lessonStatus = true;
+          if (lessonIndex >= 0) {
+            if (detailItem[lessonIndex].containMaterial) {
+              lessonStatus = true;
+            }
           }
         }
-      }
-      // 判断当前章节下面课程是否有内容,否则往上一个章节走
-      if (lessonStatus) {
-        return true;
-      }
+        // 判断当前章节下面课程是否有内容,否则往上一个章节走
+        if (lessonStatus) {
+          return true;
+        }
 
-      // 已经是第一个章节了
-      if (detailIndex <= 0) {
-        return false;
-      }
+        // 已经是第一个章节了
+        if (detailIndex <= 0) {
+          return false;
+        }
 
-      let prevLessonStatus = false;
-      while (detailIndex >= 0) {
-        detailIndex--;
-        const tempDetail = data.courseDetails[detailIndex]?.knowledgeList || [];
-        let tempLessonLength = tempDetail.length;
-        while (tempLessonLength > 0) {
-          if (tempDetail[tempLessonLength - 1].containMaterial) {
-            prevLessonStatus = true;
+        let prevLessonStatus = false;
+        while (detailIndex >= 0) {
+          detailIndex--;
+          const tempDetail =
+            data.courseDetails[detailIndex]?.knowledgeList || [];
+          let tempLessonLength = tempDetail.length;
+          while (tempLessonLength > 0) {
+            if (tempDetail[tempLessonLength - 1].containMaterial) {
+              prevLessonStatus = true;
+            }
+            tempLessonLength--;
           }
-          tempLessonLength--;
-        }
 
-        if (prevLessonStatus) {
-          return true;
+          if (prevLessonStatus) {
+            return true;
+          }
         }
-      }
 
-      return false;
+        return false;
+      }
     });
 
     // 是否允许下一页
@@ -873,6 +1008,14 @@ export default defineComponent({
         return true;
       }
 
+      if (data.courseId) {
+        const detailIndex = data.courseDetails.findIndex(
+          (item: any) => item.courseId === data.courseId
+        );
+        // 是否为第一节课
+        return detailIndex + 1 >= data.courseDetails.length - 1 ? true : false;
+      }
+
       // 获取当前是哪个章节
       let detailIndex = data.courseDetails.findIndex(
         (item: any) => item.id == activeData.lessonCoursewareDetailId
@@ -951,12 +1094,19 @@ export default defineComponent({
 
       popupData.chapterOpen = false;
       showSelectCourseware.value = false;
-      data.kjId = item.id;
-      data.id = item.id;
+      popupData.chapterCourseOpen = false;
 
       popupData.itemActive = '';
       popupData.itemName = '';
-      await getDetail();
+      if (data.courseId) {
+        data.courseId = item.id;
+        await getStudentCourseDetail();
+      } else {
+        data.kjId = item.id;
+        data.id = item.id;
+        await getDetail();
+      }
+
       popupData.activeIndex = 0;
       loadingClass.value = false;
       debounceSkip.value = false;
@@ -1245,7 +1395,7 @@ export default defineComponent({
                         }}
                         pptData={m}
                         fromType={
-                          route.query.tab == 'course' ? 'CLASS' : 'PLATFORM'
+                          data.courseId ? 'CLASS' : 'PLATFORM'
                         }></PptList>
                     )}
                   </div>
@@ -1279,12 +1429,21 @@ export default defineComponent({
                   e.stopPropagation();
                   clearTimeout(activeData.timer);
                 }}>
-                <div
-                  class={[styles.fullBtn, styles.point]}
-                  onClick={() => (popupData.chapterOpen = true)}>
-                  <img src={iconChange} />
-                  <span>切换</span>
-                </div>
+                {data.courseId ? (
+                  <div
+                    class={[styles.fullBtn, styles.point]}
+                    onClick={() => (popupData.chapterCourseOpen = true)}>
+                    <img src={iconRecord} />
+                    <span>记录</span>
+                  </div>
+                ) : (
+                  <div
+                    class={[styles.fullBtn, styles.point]}
+                    onClick={() => (popupData.chapterOpen = true)}>
+                    <img src={iconChange} />
+                    <span>切换</span>
+                  </div>
+                )}
 
                 <div
                   class={[
@@ -1308,7 +1467,6 @@ export default defineComponent({
                   <img src={iconMenu} />
                   <span>课件</span>
                 </div>
-
                 <div
                   class={[
                     styles.fullBtn,
@@ -1392,6 +1550,27 @@ export default defineComponent({
             }}
           />
         </Popup>
+
+        {/* 上课记录 */}
+        <Popup
+          class={styles.popup}
+          style={{ background: 'rgba(0,0,0, 0.75)' }}
+          overlayClass={styles.overlayClass}
+          position="right"
+          round
+          v-model:show={popupData.chapterCourseOpen}
+          onClose={handleClosePopup}>
+          <ChapterCourse
+            detail={data.formatCourseList}
+            itemActive={data.courseId as any}
+            popShow={popupData.chapterCourseOpen}
+            onHandleSelect={async (item: any) => {
+              loadNewCourseware({
+                id: item.itemActive
+              });
+            }}
+          />
+        </Popup>
         {showSelectCourseware.value && (
           <SelectCoursewareTip
             message={changeLessonCourseWare.value.tipMessage}