Browse Source

修改逻辑判断

lex 1 year ago
parent
commit
1c1eb3f3cd

+ 11 - 2
src/views/curriculum/components/curriculumList/curriculumList_gym.vue

@@ -82,7 +82,7 @@
             </div>
          </div>
          <div class="btnGoClass" v-if="item.status === 'UNDERWAY'" @click.stop="handleStartClass(item.id, item.teachMode)">开始上课</div>
-         <div class="btnDetail" v-else @click.stop="handleClickDetail(item.id, item.teachMode)">
+         <div class="btnDetail" v-else @click.stop="handleClickDetail(item.id, item.teachMode, item.coursewareEnable)">
             <div>查看详情</div>
             <img class="jtImg" src="@/img/curriculum/jt.png" />
          </div>
@@ -95,6 +95,7 @@ import { format } from "@/libs/tools"
 import { useCurriculumDetail, useSetUpCourseware } from "../../index"
 import { handleStartClass_gym, isONLINE_gym } from "@/views/curriculum/hooks/useStartClass"
 import { classImgType, classNameType } from "@/views/curriculum/type"
+import { ElMessage } from "element-plus"
 
 const props = defineProps<{
    curriculumData: any[]
@@ -104,10 +105,18 @@ const emits = defineEmits<{
 }>()
 
 //查看详情
-function handleClickDetail(id: string, teachMode: string) {
+function handleClickDetail(id: string, teachMode: string, coursewareEnable: boolean) {
    if (isONLINE_gym(teachMode)) {
       return
    }
+   if (!coursewareEnable) {
+      ElMessage({
+         showClose: true,
+         message: "该资源已失效",
+         type: "error"
+      })
+      return
+   }
    useCurriculumDetail(id)
 }
 // 开始上课

+ 250 - 241
src/views/curriculum/components/curriculumList/curriculumList_gyt.vue

@@ -1,241 +1,250 @@
-<!--
-* @FileDescription: 管乐团课表list
-* @Author: 黄琪勇
-* @Date:2024-03-29 15:29:06
--->
-<template>
-   <div class="curriculumList_gyt" v-for="item in props.curriculumData" :key="item.id" @click="handleClickDetail(item.id)">
-      <div class="head">
-         <div class="timeBox">
-            <img class="timeImg" src="@/img/curriculum/sj.png" />
-            <div class="time">{{ item.classDate && format(item.classDate) }}</div>
-         </div>
-         <div class="operateBox">
-            <template v-if="item.coursewareFlag && !item.lessonCoursewareId && item.status !== 'COMPLETE'">
-               <img class="dangerImg" src="@/img/curriculum/jg.png" />
-               <div class="operateBtn" @click.stop="handleSetUpCourseware(item.id)">配置课件</div>
-            </template>
-            <template v-else-if="item.status === 'NOT_START'">
-               <div class="noStart">未开始</div>
-            </template>
-            <template v-else-if="item.status === 'ING'">
-               <div class="ing">进行中</div>
-            </template>
-            <template v-else>
-               <div class="end">已结束</div>
-            </template>
-         </div>
-      </div>
-      <div class="curriculumName">
-         <div class="leftCon">{{ item.startTime && format(item.startTime, "hh:ii") }}-{{ item.endTime && format(item.endTime, "hh:ii") }}</div>
-         <div class="rightCon">
-            <img :src="item.signIn ? require('@/img/curriculum/qd1.png') : require('@/img/curriculum/qd.png')" />
-            <div :class="{ signIn: item.signIn }">{{ item.signIn ? "已签到" : "未签到" }}</div>
-            <img class="qtImg" :src="item.signOut ? require('@/img/curriculum/qt1.png') : require('@/img/curriculum/qt.png')" />
-            <div :class="{ signOut: item.signOut }">{{ item.signOut ? "已签退" : "未签退" }}</div>
-         </div>
-      </div>
-      <div class="endCon">
-         <div class="addressCon">
-            <div class="adressBox"><ellipsisScroll :title="`${item.className}-${item.teacherName}`" /></div>
-            <div><ellipsisScroll :title="item.orchestraName" /></div>
-         </div>
-         <div class="btnGoClass" v-if="item.status === 'ING'" @click.stop="handleStartClass(item.id)">开始上课</div>
-         <div class="btnDetail" v-else @click.stop="handleClickDetail(item.id)">
-            <div>查看详情</div>
-            <img class="jtImg" src="@/img/curriculum/jt.png" />
-         </div>
-      </div>
-   </div>
-</template>
-
-<script setup lang="ts">
-import { format } from "@/libs/tools"
-import { useCurriculumDetail, useSetUpCourseware } from "@/views/curriculum"
-import { handleStartClass_gyt } from "@/views/curriculum/hooks/useStartClass"
-
-const emits = defineEmits<{
-   (e: "update"): void
-}>()
-const props = defineProps<{
-   curriculumData: any[]
-}>()
-// 开始上课
-function handleStartClass(id: string) {
-   handleStartClass_gyt(id)
-}
-//查看详情
-function handleClickDetail(id: string) {
-   useCurriculumDetail(id)
-}
-// 配置课表
-function handleSetUpCourseware(id: string) {
-   useSetUpCourseware(id, () => {
-      emits("update")
-   })
-}
-</script>
-
-<style lang="scss" scoped>
-.curriculumList_gyt {
-   background: #ffffff;
-   border-radius: 35px;
-   padding: 0 30px;
-   margin-bottom: 18px;
-   cursor: pointer;
-   &:last-child {
-      margin-bottom: 0;
-   }
-   .head {
-      padding: 20px 0 16px 0;
-      border-bottom: 1px solid #eaeaea;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      .timeBox {
-         display: flex;
-         align-items: center;
-         .timeImg {
-            width: 24px;
-            height: 24px;
-         }
-         .time {
-            margin-left: 6px;
-            font-weight: 500;
-            font-size: 22px;
-            color: #777777;
-         }
-      }
-      .operateBox {
-         display: flex;
-         align-items: center;
-         .dangerImg {
-            width: 22px;
-            height: 22px;
-         }
-         .operateBtn {
-            margin-left: 8px;
-            font-weight: 500;
-            font-size: 20px;
-            color: #f44541;
-            cursor: pointer;
-            &:hover {
-               opacity: $opacity-hover;
-            }
-         }
-         .noStart {
-            font-weight: 500;
-            font-size: 20px;
-            color: #777777;
-         }
-         .ing {
-            font-weight: 500;
-            font-size: 20px;
-            color: #f67146;
-         }
-         .end {
-            font-weight: 500;
-            font-size: 20px;
-            color: #aaaaaa;
-         }
-      }
-   }
-   .curriculumName {
-      margin-top: 24px;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      .leftCon {
-         flex-grow: 1;
-         font-family: DINAlternate, DINAlternate;
-         font-weight: bold;
-         font-size: 38px;
-         color: #333333;
-         overflow: hidden;
-      }
-      .rightCon {
-         display: flex;
-         align-items: center;
-         flex-shrink: 0;
-         & > img {
-            width: 22px;
-            height: 22px;
-         }
-         & > div {
-            margin-left: 6px;
-            font-weight: 500;
-            font-size: 20px;
-            color: #aaaaaa;
-            &.signIn,
-            &.signOut {
-               color: #01c199;
-            }
-         }
-         .qtImg {
-            margin-left: 34px;
-         }
-      }
-   }
-   .endCon {
-      margin-top: 18px;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      padding-bottom: 22px;
-      .addressCon {
-         flex-grow: 1;
-         overflow: hidden;
-         & > div {
-            font-weight: 500;
-            font-size: 16px;
-            color: #777777;
-         }
-         & > div:nth-child(2) {
-            margin-right: 116px;
-            overflow: hidden;
-            margin-top: 12px;
-         }
-         .adressBox {
-            margin-right: 56px;
-            overflow: hidden;
-            font-weight: 600;
-            font-size: 20px;
-            color: #333333;
-         }
-      }
-      .btnGoClass {
-         flex-shrink: 0;
-         font-weight: 500;
-         font-size: 20px;
-         color: #ffffff;
-         padding: 11px 14px;
-         background: #ff8057;
-         border-radius: 21px;
-         text-align: center;
-         cursor: pointer;
-         &:hover {
-            opacity: $opacity-hover;
-         }
-      }
-      .btnDetail {
-         flex-shrink: 0;
-         display: flex;
-         align-items: center;
-         cursor: pointer;
-         &:hover {
-            opacity: $opacity-hover;
-         }
-         & > div {
-            font-weight: 500;
-            font-size: 20px;
-            color: #f67146;
-         }
-         .jtImg {
-            margin-left: 6px;
-            width: 6px;
-            height: 13px;
-         }
-      }
-   }
-}
-</style>
+<!--
+* @FileDescription: 管乐团课表list
+* @Author: 黄琪勇
+* @Date:2024-03-29 15:29:06
+-->
+<template>
+   <div class="curriculumList_gyt" v-for="item in props.curriculumData" :key="item.id" @click="handleClickDetail(item.id)">
+      <div class="head">
+         <div class="timeBox">
+            <img class="timeImg" src="@/img/curriculum/sj.png" />
+            <div class="time">{{ item.classDate && format(item.classDate) }}</div>
+         </div>
+         <div class="operateBox">
+            <template v-if="item.coursewareFlag && !item.lessonCoursewareId && item.status !== 'COMPLETE'">
+               <img class="dangerImg" src="@/img/curriculum/jg.png" />
+               <div class="operateBtn" @click.stop="handleSetUpCourseware(item.id)">配置课件</div>
+            </template>
+            <template v-else-if="item.status === 'NOT_START'">
+               <div class="noStart">未开始</div>
+            </template>
+            <template v-else-if="item.status === 'ING'">
+               <div class="ing">进行中</div>
+            </template>
+            <template v-else>
+               <div class="end">已结束</div>
+            </template>
+         </div>
+      </div>
+      <div class="curriculumName">
+         <div class="leftCon">{{ item.startTime && format(item.startTime, "hh:ii") }}-{{ item.endTime && format(item.endTime, "hh:ii") }}</div>
+         <div class="rightCon">
+            <img :src="item.signIn ? require('@/img/curriculum/qd1.png') : require('@/img/curriculum/qd.png')" />
+            <div :class="{ signIn: item.signIn }">{{ item.signIn ? "已签到" : "未签到" }}</div>
+            <img class="qtImg" :src="item.signOut ? require('@/img/curriculum/qt1.png') : require('@/img/curriculum/qt.png')" />
+            <div :class="{ signOut: item.signOut }">{{ item.signOut ? "已签退" : "未签退" }}</div>
+         </div>
+      </div>
+      <div class="endCon">
+         <div class="addressCon">
+            <div class="adressBox"><ellipsisScroll :title="`${item.className}-${item.teacherName}`" /></div>
+            <div><ellipsisScroll :title="item.orchestraName" /></div>
+         </div>
+         <div class="btnGoClass" v-if="item.status === 'ING'" @click.stop="handleStartClass(item.id)">开始上课</div>
+         <div class="btnDetail" v-else @click.stop="handleClickDetail(item.id, item.applyStatus)">
+            <div>查看详情</div>
+            <img class="jtImg" src="@/img/curriculum/jt.png" />
+         </div>
+      </div>
+   </div>
+</template>
+
+<script setup lang="ts">
+import { format } from "@/libs/tools"
+import { useCurriculumDetail, useSetUpCourseware } from "@/views/curriculum"
+import { handleStartClass_gyt } from "@/views/curriculum/hooks/useStartClass"
+import { ElMessage } from "element-plus"
+
+const emits = defineEmits<{
+   (e: "update"): void
+}>()
+const props = defineProps<{
+   curriculumData: any[]
+}>()
+// 开始上课
+function handleStartClass(id: string) {
+   handleStartClass_gyt(id)
+}
+//查看详情
+function handleClickDetail(id: string, applyStatus: boolean) {
+   if (!applyStatus) {
+      ElMessage({
+         showClose: true,
+         message: "该资源已失效",
+         type: "error"
+      })
+      return
+   }
+   useCurriculumDetail(id)
+}
+// 配置课表
+function handleSetUpCourseware(id: string) {
+   useSetUpCourseware(id, () => {
+      emits("update")
+   })
+}
+</script>
+
+<style lang="scss" scoped>
+.curriculumList_gyt {
+   background: #ffffff;
+   border-radius: 35px;
+   padding: 0 30px;
+   margin-bottom: 18px;
+   cursor: pointer;
+   &:last-child {
+      margin-bottom: 0;
+   }
+   .head {
+      padding: 20px 0 16px 0;
+      border-bottom: 1px solid #eaeaea;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      .timeBox {
+         display: flex;
+         align-items: center;
+         .timeImg {
+            width: 24px;
+            height: 24px;
+         }
+         .time {
+            margin-left: 6px;
+            font-weight: 500;
+            font-size: 22px;
+            color: #777777;
+         }
+      }
+      .operateBox {
+         display: flex;
+         align-items: center;
+         .dangerImg {
+            width: 22px;
+            height: 22px;
+         }
+         .operateBtn {
+            margin-left: 8px;
+            font-weight: 500;
+            font-size: 20px;
+            color: #f44541;
+            cursor: pointer;
+            &:hover {
+               opacity: $opacity-hover;
+            }
+         }
+         .noStart {
+            font-weight: 500;
+            font-size: 20px;
+            color: #777777;
+         }
+         .ing {
+            font-weight: 500;
+            font-size: 20px;
+            color: #f67146;
+         }
+         .end {
+            font-weight: 500;
+            font-size: 20px;
+            color: #aaaaaa;
+         }
+      }
+   }
+   .curriculumName {
+      margin-top: 24px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      .leftCon {
+         flex-grow: 1;
+         font-family: DINAlternate, DINAlternate;
+         font-weight: bold;
+         font-size: 38px;
+         color: #333333;
+         overflow: hidden;
+      }
+      .rightCon {
+         display: flex;
+         align-items: center;
+         flex-shrink: 0;
+         & > img {
+            width: 22px;
+            height: 22px;
+         }
+         & > div {
+            margin-left: 6px;
+            font-weight: 500;
+            font-size: 20px;
+            color: #aaaaaa;
+            &.signIn,
+            &.signOut {
+               color: #01c199;
+            }
+         }
+         .qtImg {
+            margin-left: 34px;
+         }
+      }
+   }
+   .endCon {
+      margin-top: 18px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      padding-bottom: 22px;
+      .addressCon {
+         flex-grow: 1;
+         overflow: hidden;
+         & > div {
+            font-weight: 500;
+            font-size: 16px;
+            color: #777777;
+         }
+         & > div:nth-child(2) {
+            margin-right: 116px;
+            overflow: hidden;
+            margin-top: 12px;
+         }
+         .adressBox {
+            margin-right: 56px;
+            overflow: hidden;
+            font-weight: 600;
+            font-size: 20px;
+            color: #333333;
+         }
+      }
+      .btnGoClass {
+         flex-shrink: 0;
+         font-weight: 500;
+         font-size: 20px;
+         color: #ffffff;
+         padding: 11px 14px;
+         background: #ff8057;
+         border-radius: 21px;
+         text-align: center;
+         cursor: pointer;
+         &:hover {
+            opacity: $opacity-hover;
+         }
+      }
+      .btnDetail {
+         flex-shrink: 0;
+         display: flex;
+         align-items: center;
+         cursor: pointer;
+         &:hover {
+            opacity: $opacity-hover;
+         }
+         & > div {
+            font-weight: 500;
+            font-size: 20px;
+            color: #f67146;
+         }
+         .jtImg {
+            margin-left: 6px;
+            width: 6px;
+            height: 13px;
+         }
+      }
+   }
+}
+</style>

+ 410 - 409
src/views/curriculum/curriculumDetail.vue

@@ -1,409 +1,410 @@
-<!--
-* @FileDescription: 课程详情
-* @Author: 黄琪勇
-* @Date:2024-04-01 16:27:48
--->
-<template>
-   <div class="curriculumDetail">
-      <div class="close" @click="close"></div>
-      <div v-loading="loading" class="curriculumDetailCon">
-         <img class="imgMid" src="@/img/curriculum/mid.png" />
-         <div class="curriculumDetailBox">
-            <div class="teachingObjectives">
-               <div class="head">
-                  <div class="leftTit">
-                     <img src="@/img/curriculum/jxmb.png" />
-                     <div>教学目标</div>
-                  </div>
-                  <div v-if="coursewareShow" class="rightBtn" @click="handleSetUpCourseware(props.modalData.id)">
-                     <div>{{ curriculumDetailData.id ? "更换课件" : "配置课件" }}</div>
-                     <img src="@/img/curriculum/jt1.png" />
-                  </div>
-               </div>
-               <div class="content">
-                  <ElScrollbar class="elScrollbar">
-                     <div class="title" v-for="tit in curriculumDetailData.targetDesc.split('\n')" :key="tit">{{ tit }}</div>
-                  </ElScrollbar>
-                  <el-empty
-                     v-if="!curriculumDetailData.targetDesc && !loading"
-                     class="empty"
-                     :image="require('@/img/layout/empty.png')"
-                     description="暂无教学目标"
-                  />
-               </div>
-            </div>
-         </div>
-         <div class="curriculumDetailBox">
-            <div class="knowledgePoints">
-               <div class="head">
-                  <div class="points">
-                     <img src="@/img/curriculum/zsd.png" />
-                     <div>知识点</div>
-                  </div>
-               </div>
-               <div class="content">
-                  <ElScrollbar class="elScrollbar">
-                     <courseCollapse :courseList="curriculumDetailData.pointList" @handleClick="handleCourseClick" />
-                  </ElScrollbar>
-                  <el-empty
-                     v-if="!curriculumDetailData.pointList.length && !loading"
-                     class="empty"
-                     :image="require('@/img/layout/empty.png')"
-                     description="暂无知识点"
-                  />
-               </div>
-            </div>
-         </div>
-      </div>
-      <div class="curriculumStart" v-if="['ING', 'UNDERWAY'].includes(statusVal) && !loading">
-         <div class="startBtn" @click="handleStartClass(modalData.id)">开始上课</div>
-      </div>
-   </div>
-</template>
-
-<script setup lang="ts">
-import courseCollapse from "./components/courseCollapse"
-import { useSetUpCourseware } from "./index"
-import {
-   getCourseScheduleDetail_gyt,
-   getLessonCoursewareDetail_gyt,
-   getCurrentCourseDetail_gym,
-   getLessonCourseDetail_gym
-} from "@/api/curriculum.api"
-import { httpAjaxErrMsg } from "@/plugin/httpAjax"
-import { ref, shallowRef, computed } from "vue"
-import { handleStartClass_gyt, handleStartClass_gym, isONLINE_gym } from "./hooks/useStartClass"
-import userStore from "@/store/modules/user"
-import router from "@/router"
-
-const userStoreHook = userStore()
-const props = defineProps<{
-   modalData: {
-      id: string
-   }
-}>()
-const emits = defineEmits<{
-   (e: "onClose"): void
-}>()
-
-function close() {
-   emits("onClose")
-}
-const loading = ref(false)
-const statusVal = ref("") //课程状态 ING 和 UNDERWAY 代表可以上课
-const teachModeVal = ref("") //课程类型 ONLINE课的时候提示去app
-const coursewareFlagVal = ref(false) // 管乐团能否配置课件 coursewareFlag字段为true并且不是结束就能配置
-const coursewareShow = computed(() => {
-   if (userStoreHook.roles === "GYM") {
-      return statusVal.value === "UNDERWAY"
-   } else {
-      return coursewareFlagVal.value && statusVal.value !== "COMPLETE"
-   }
-})
-const curriculumDetailData = shallowRef<{
-   pointList: any[]
-   targetDesc: string
-   id: string
-}>({
-   pointList: [],
-   targetDesc: "",
-   id: ""
-})
-
-getCurriculumDetailData()
-function getCurriculumDetailData() {
-   userStoreHook.roles === "GYM" ? getCurriculumDetailData_gym() : getCurriculumDetailData_gyt()
-}
-/* 处理管乐迷 */
-function getCurriculumDetailData_gym() {
-   loading.value = true
-   httpAjaxErrMsg(getCurrentCourseDetail_gym, props.modalData.id).then(res => {
-      if (res.code === 200) {
-         const { coursewareDetailId, courseStatus, teachMode } = res.data || {}
-         statusVal.value = courseStatus
-         teachModeVal.value = teachMode
-         if (coursewareDetailId) {
-            httpAjaxErrMsg(getLessonCourseDetail_gym, coursewareDetailId).then(resData => {
-               loading.value = false
-               if (resData.code === 200) {
-                  const { lessonTargetDesc, id, knowledgePointList } = resData.data || {}
-                  curriculumDetailData.value = {
-                     pointList: knowledgePointList || [],
-                     targetDesc: lessonTargetDesc,
-                     id
-                  }
-               }
-            })
-         } else {
-            loading.value = false
-         }
-      } else {
-         loading.value = false
-      }
-   })
-}
-/* 处理管乐团 */
-function getCurriculumDetailData_gyt() {
-   loading.value = true
-   httpAjaxErrMsg(getCourseScheduleDetail_gyt, props.modalData.id).then(res => {
-      if (res.code === 200) {
-         const { lessonCoursewareDetailId, status, coursewareFlag } = res.data || {}
-         statusVal.value = status
-         coursewareFlagVal.value = coursewareFlag
-         if (lessonCoursewareDetailId) {
-            httpAjaxErrMsg(getLessonCoursewareDetail_gyt, lessonCoursewareDetailId).then(resData => {
-               loading.value = false
-               if (resData.code === 200) {
-                  const { lessonTargetDesc, id, knowledgePointList } = resData.data || {}
-                  curriculumDetailData.value = {
-                     pointList: knowledgePointList || [],
-                     targetDesc: lessonTargetDesc,
-                     id
-                  }
-               }
-            })
-         } else {
-            loading.value = false
-         }
-      } else {
-         loading.value = false
-      }
-   })
-}
-
-// 开始上课
-function handleStartClass(id: string) {
-   if (userStoreHook.roles === "GYM") {
-      if (isONLINE_gym(teachModeVal.value)) {
-         return
-      }
-      handleStartClass_gym(id)
-   } else {
-      handleStartClass_gyt(id)
-   }
-}
-
-// 选择更换课件
-function handleSetUpCourseware(id: string) {
-   useSetUpCourseware(id, () => {
-      //选择课件成功后的回调
-      // 刷新数据
-      getCurriculumDetailData()
-   })
-}
-function handleCourseClick(item: any) {
-   const url = router.resolve({
-      name: "coursewarePlay",
-      params: { id: curriculumDetailData.value.id },
-      query: {
-         materialId: item.id
-      }
-   }).href
-   window.open(url, "_blank")
-}
-</script>
-
-<style lang="scss" scoped>
-.curriculumDetail {
-   width: 100%;
-   height: 100%;
-   padding: 20px 20px 30px 20px;
-   display: flex;
-   flex-direction: column;
-   .close {
-      position: absolute;
-      top: -9px;
-      right: -9px;
-      width: 47px;
-      height: 49px;
-      cursor: pointer;
-      background: url("@/img/useDialogConfirm/close.png") no-repeat;
-      background-size: cover;
-      z-index: 1;
-      &:hover {
-         background: url("@/img/useDialogConfirm/closeHover.png") no-repeat;
-         background-size: cover;
-      }
-   }
-   .curriculumDetailCon {
-      flex-grow: 1;
-      overflow: hidden;
-      display: flex;
-      position: relative;
-      & > :deep(.el-loading-mask) {
-         border-radius: 35px;
-      }
-      .imgMid {
-         width: 62px;
-         height: 470px;
-         position: absolute;
-         left: 50%;
-         top: 50%;
-         transform: translate(-50%, -50%);
-         z-index: 1;
-      }
-      .curriculumDetailBox {
-         width: 50%;
-         height: 100%;
-         background: #fff2e1;
-         border-radius: 35px;
-         padding: 10px;
-         overflow: hidden;
-         &:nth-child(3) {
-            margin-left: 10px;
-         }
-         .teachingObjectives,
-         .knowledgePoints {
-            width: 100%;
-            height: 100%;
-            background: #ffffff;
-            border-radius: 35px;
-            .content {
-               position: relative;
-               padding-top: 18px;
-               padding-left: 18px;
-               height: calc(100% - 57px);
-               & > :deep(.elScrollbar) {
-                  .el-scrollbar__view {
-                     width: 100%;
-                  }
-                  .el-scrollbar__wrap {
-                     overflow-x: hidden;
-                  }
-               }
-               &:deep(.empty) {
-                  position: absolute;
-                  top: 50%;
-                  left: 50%;
-                  transform: translate(-50%, -50%);
-                  .el-empty__image {
-                     width: 278px;
-                  }
-               }
-            }
-         }
-         .teachingObjectives {
-            padding: 16px 16px 20px;
-            .head {
-               width: 100%;
-               height: 57px;
-               background: #fff2e1;
-               border-radius: 12px;
-               display: flex;
-               justify-content: space-between;
-               align-items: center;
-               padding: 0 18px;
-               .leftTit {
-                  display: flex;
-                  align-items: center;
-                  & > img {
-                     width: 27px;
-                     height: 27px;
-                  }
-                  & > div {
-                     margin-left: 8px;
-                     font-weight: 500;
-                     font-size: 24px;
-                     color: #333333;
-                  }
-               }
-               .rightBtn {
-                  display: flex;
-                  align-items: center;
-                  cursor: pointer;
-                  &:hover {
-                     opacity: $opacity-hover;
-                  }
-                  & > img {
-                     margin-left: 4px;
-                     width: 10px;
-                     height: 17px;
-                  }
-                  & > div {
-                     margin-left: 8px;
-                     font-weight: 500;
-                     font-size: 20px;
-                     color: #f67146;
-                  }
-               }
-            }
-            .title {
-               line-height: 34px;
-               font-weight: 400;
-               font-size: 18px;
-               color: #333333;
-            }
-         }
-         .knowledgePoints {
-            padding: 16px 0 20px 16px;
-            .head {
-               margin-right: 33px;
-               height: 57px;
-               background: #fff2e1;
-               border-radius: 12px;
-               display: flex;
-               align-items: center;
-               padding: 0 18px;
-               .points {
-                  display: flex;
-                  align-items: center;
-                  & > img {
-                     width: 28px;
-                     height: 27px;
-                  }
-                  & > div {
-                     margin-left: 8px;
-                     font-weight: 500;
-                     font-size: 24px;
-                     color: #333333;
-                  }
-               }
-            }
-            .content {
-               & > :deep(.elScrollbar) {
-                  .el-scrollbar__view {
-                     padding-right: 33px;
-                  }
-               }
-            }
-         }
-      }
-   }
-   .curriculumStart {
-      flex-shrink: 0;
-      padding-top: 20px;
-      display: flex;
-      justify-content: center;
-      .startBtn {
-         width: 363px;
-         height: 68px;
-         background: linear-gradient(180deg, #ffffff 0%, #ffdbc1 100%);
-         box-shadow: 4px 6px 0px 0px rgba(236, 102, 52, 0.45), inset 0px -8px 3px 0px rgba(254, 163, 138, 0.46);
-         border-radius: 41px;
-         font-weight: 500;
-         font-size: 24px;
-         color: #f67146;
-         line-height: 68px;
-         text-align: center;
-         cursor: pointer;
-         &:hover {
-            opacity: $opacity-hover;
-         }
-      }
-   }
-}
-</style>
-<style lang="scss">
-.h-modalFrame.curriculumDetail {
-   /* prettier-ignore */
-   --modalFrameTitHeight: 0PX;
-   .modalFrameBox {
-      background: linear-gradient(180deg, #ffdd5d 0%, #ffb93b 100%);
-      border-radius: 57px;
-      box-shadow: none;
-      .modalFrameTitle {
-         display: none;
-      }
-   }
-}
-</style>
+<!--
+* @FileDescription: 课程详情
+* @Author: 黄琪勇
+* @Date:2024-04-01 16:27:48
+-->
+<template>
+   <div class="curriculumDetail">
+      <div class="close" @click="close"></div>
+      <div v-loading="loading" class="curriculumDetailCon">
+         <img class="imgMid" src="@/img/curriculum/mid.png" />
+         <div class="curriculumDetailBox">
+            <div class="teachingObjectives">
+               <div class="head">
+                  <div class="leftTit">
+                     <img src="@/img/curriculum/jxmb.png" />
+                     <div>教学目标</div>
+                  </div>
+                  <div v-if="coursewareShow" class="rightBtn" @click="handleSetUpCourseware(props.modalData.id)">
+                     <div>{{ curriculumDetailData.id ? "更换课件" : "配置课件" }}</div>
+                     <img src="@/img/curriculum/jt1.png" />
+                  </div>
+               </div>
+               <div class="content">
+                  <ElScrollbar class="elScrollbar">
+                     <div class="title" v-for="tit in curriculumDetailData.targetDesc.split('\n')" :key="tit">{{ tit }}</div>
+                  </ElScrollbar>
+                  <el-empty
+                     v-if="!curriculumDetailData.targetDesc && !loading"
+                     class="empty"
+                     :image="require('@/img/layout/empty.png')"
+                     description="暂无教学目标"
+                  />
+               </div>
+            </div>
+         </div>
+         <div class="curriculumDetailBox">
+            <div class="knowledgePoints">
+               <div class="head">
+                  <div class="points">
+                     <img src="@/img/curriculum/zsd.png" />
+                     <div>知识点</div>
+                  </div>
+               </div>
+               <div class="content">
+                  <ElScrollbar class="elScrollbar">
+                     <courseCollapse :courseList="curriculumDetailData.pointList" @handleClick="handleCourseClick" />
+                  </ElScrollbar>
+                  <el-empty
+                     v-if="!curriculumDetailData.pointList.length && !loading"
+                     class="empty"
+                     :image="require('@/img/layout/empty.png')"
+                     description="暂无知识点"
+                  />
+               </div>
+            </div>
+         </div>
+      </div>
+      <div class="curriculumStart" v-if="['ING', 'UNDERWAY'].includes(statusVal) && !loading">
+         <div class="startBtn" @click="handleStartClass(modalData.id)">开始上课</div>
+      </div>
+   </div>
+</template>
+
+<script setup lang="ts">
+import { ElMessage } from "element-plus"
+import courseCollapse from "./components/courseCollapse"
+import { useSetUpCourseware } from "./index"
+import {
+   getCourseScheduleDetail_gyt,
+   getLessonCoursewareDetail_gyt,
+   getCurrentCourseDetail_gym,
+   getLessonCourseDetail_gym
+} from "@/api/curriculum.api"
+import { httpAjaxErrMsg } from "@/plugin/httpAjax"
+import { ref, shallowRef, computed } from "vue"
+import { handleStartClass_gyt, handleStartClass_gym, isONLINE_gym } from "./hooks/useStartClass"
+import userStore from "@/store/modules/user"
+import router from "@/router"
+
+const userStoreHook = userStore()
+const props = defineProps<{
+   modalData: {
+      id: string
+   }
+}>()
+const emits = defineEmits<{
+   (e: "onClose"): void
+}>()
+
+function close() {
+   emits("onClose")
+}
+const loading = ref(false)
+const statusVal = ref("") //课程状态 ING 和 UNDERWAY 代表可以上课
+const teachModeVal = ref("") //课程类型 ONLINE课的时候提示去app
+const coursewareFlagVal = ref(false) // 管乐团能否配置课件 coursewareFlag字段为true并且不是结束就能配置
+const coursewareShow = computed(() => {
+   if (userStoreHook.roles === "GYM") {
+      return statusVal.value === "UNDERWAY"
+   } else {
+      return coursewareFlagVal.value && statusVal.value !== "COMPLETE"
+   }
+})
+const curriculumDetailData = shallowRef<{
+   pointList: any[]
+   targetDesc: string
+   id: string
+}>({
+   pointList: [],
+   targetDesc: "",
+   id: ""
+})
+
+getCurriculumDetailData()
+function getCurriculumDetailData() {
+   userStoreHook.roles === "GYM" ? getCurriculumDetailData_gym() : getCurriculumDetailData_gyt()
+}
+/* 处理管乐迷 */
+function getCurriculumDetailData_gym() {
+   loading.value = true
+   httpAjaxErrMsg(getCurrentCourseDetail_gym, props.modalData.id).then(res => {
+      if (res.code === 200) {
+         const { coursewareDetailId, courseStatus, teachMode } = res.data || {}
+         statusVal.value = courseStatus
+         teachModeVal.value = teachMode
+         if (coursewareDetailId) {
+            httpAjaxErrMsg(getLessonCourseDetail_gym, coursewareDetailId).then(resData => {
+               loading.value = false
+               if (resData.code === 200) {
+                  const { lessonTargetDesc, id, knowledgePointList } = resData.data || {}
+                  curriculumDetailData.value = {
+                     pointList: knowledgePointList || [],
+                     targetDesc: lessonTargetDesc,
+                     id
+                  }
+               }
+            })
+         } else {
+            loading.value = false
+         }
+      } else {
+         loading.value = false
+      }
+   })
+}
+/* 处理管乐团 */
+function getCurriculumDetailData_gyt() {
+   loading.value = true
+   httpAjaxErrMsg(getCourseScheduleDetail_gyt, props.modalData.id).then(res => {
+      if (res.code === 200) {
+         const { lessonCoursewareDetailId, status, coursewareFlag } = res.data || {}
+         statusVal.value = status
+         coursewareFlagVal.value = coursewareFlag
+         if (lessonCoursewareDetailId) {
+            httpAjaxErrMsg(getLessonCoursewareDetail_gyt, lessonCoursewareDetailId).then(resData => {
+               loading.value = false
+               if (resData.code === 200) {
+                  const { lessonTargetDesc, id, knowledgePointList } = resData.data || {}
+                  curriculumDetailData.value = {
+                     pointList: knowledgePointList || [],
+                     targetDesc: lessonTargetDesc,
+                     id
+                  }
+               }
+            })
+         } else {
+            loading.value = false
+         }
+      } else {
+         loading.value = false
+      }
+   })
+}
+
+// 开始上课
+function handleStartClass(id: string) {
+   if (userStoreHook.roles === "GYM") {
+      if (isONLINE_gym(teachModeVal.value)) {
+         return
+      }
+      handleStartClass_gym(id)
+   } else {
+      handleStartClass_gyt(id)
+   }
+}
+
+// 选择更换课件
+function handleSetUpCourseware(id: string) {
+   useSetUpCourseware(id, () => {
+      //选择课件成功后的回调
+      // 刷新数据
+      getCurriculumDetailData()
+   })
+}
+function handleCourseClick(item: any) {
+   const url = router.resolve({
+      name: "coursewarePlay",
+      params: { id: curriculumDetailData.value.id },
+      query: {
+         materialId: item.id
+      }
+   }).href
+   window.open(url, "_blank")
+}
+</script>
+
+<style lang="scss" scoped>
+.curriculumDetail {
+   width: 100%;
+   height: 100%;
+   padding: 20px 20px 30px 20px;
+   display: flex;
+   flex-direction: column;
+   .close {
+      position: absolute;
+      top: -9px;
+      right: -9px;
+      width: 47px;
+      height: 49px;
+      cursor: pointer;
+      background: url("@/img/useDialogConfirm/close.png") no-repeat;
+      background-size: cover;
+      z-index: 1;
+      &:hover {
+         background: url("@/img/useDialogConfirm/closeHover.png") no-repeat;
+         background-size: cover;
+      }
+   }
+   .curriculumDetailCon {
+      flex-grow: 1;
+      overflow: hidden;
+      display: flex;
+      position: relative;
+      & > :deep(.el-loading-mask) {
+         border-radius: 35px;
+      }
+      .imgMid {
+         width: 62px;
+         height: 470px;
+         position: absolute;
+         left: 50%;
+         top: 50%;
+         transform: translate(-50%, -50%);
+         z-index: 1;
+      }
+      .curriculumDetailBox {
+         width: 50%;
+         height: 100%;
+         background: #fff2e1;
+         border-radius: 35px;
+         padding: 10px;
+         overflow: hidden;
+         &:nth-child(3) {
+            margin-left: 10px;
+         }
+         .teachingObjectives,
+         .knowledgePoints {
+            width: 100%;
+            height: 100%;
+            background: #ffffff;
+            border-radius: 35px;
+            .content {
+               position: relative;
+               padding-top: 18px;
+               padding-left: 18px;
+               height: calc(100% - 57px);
+               & > :deep(.elScrollbar) {
+                  .el-scrollbar__view {
+                     width: 100%;
+                  }
+                  .el-scrollbar__wrap {
+                     overflow-x: hidden;
+                  }
+               }
+               &:deep(.empty) {
+                  position: absolute;
+                  top: 50%;
+                  left: 50%;
+                  transform: translate(-50%, -50%);
+                  .el-empty__image {
+                     width: 278px;
+                  }
+               }
+            }
+         }
+         .teachingObjectives {
+            padding: 16px 16px 20px;
+            .head {
+               width: 100%;
+               height: 57px;
+               background: #fff2e1;
+               border-radius: 12px;
+               display: flex;
+               justify-content: space-between;
+               align-items: center;
+               padding: 0 18px;
+               .leftTit {
+                  display: flex;
+                  align-items: center;
+                  & > img {
+                     width: 27px;
+                     height: 27px;
+                  }
+                  & > div {
+                     margin-left: 8px;
+                     font-weight: 500;
+                     font-size: 24px;
+                     color: #333333;
+                  }
+               }
+               .rightBtn {
+                  display: flex;
+                  align-items: center;
+                  cursor: pointer;
+                  &:hover {
+                     opacity: $opacity-hover;
+                  }
+                  & > img {
+                     margin-left: 4px;
+                     width: 10px;
+                     height: 17px;
+                  }
+                  & > div {
+                     margin-left: 8px;
+                     font-weight: 500;
+                     font-size: 20px;
+                     color: #f67146;
+                  }
+               }
+            }
+            .title {
+               line-height: 34px;
+               font-weight: 400;
+               font-size: 18px;
+               color: #333333;
+            }
+         }
+         .knowledgePoints {
+            padding: 16px 0 20px 16px;
+            .head {
+               margin-right: 33px;
+               height: 57px;
+               background: #fff2e1;
+               border-radius: 12px;
+               display: flex;
+               align-items: center;
+               padding: 0 18px;
+               .points {
+                  display: flex;
+                  align-items: center;
+                  & > img {
+                     width: 28px;
+                     height: 27px;
+                  }
+                  & > div {
+                     margin-left: 8px;
+                     font-weight: 500;
+                     font-size: 24px;
+                     color: #333333;
+                  }
+               }
+            }
+            .content {
+               & > :deep(.elScrollbar) {
+                  .el-scrollbar__view {
+                     padding-right: 33px;
+                  }
+               }
+            }
+         }
+      }
+   }
+   .curriculumStart {
+      flex-shrink: 0;
+      padding-top: 20px;
+      display: flex;
+      justify-content: center;
+      .startBtn {
+         width: 363px;
+         height: 68px;
+         background: linear-gradient(180deg, #ffffff 0%, #ffdbc1 100%);
+         box-shadow: 4px 6px 0px 0px rgba(236, 102, 52, 0.45), inset 0px -8px 3px 0px rgba(254, 163, 138, 0.46);
+         border-radius: 41px;
+         font-weight: 500;
+         font-size: 24px;
+         color: #f67146;
+         line-height: 68px;
+         text-align: center;
+         cursor: pointer;
+         &:hover {
+            opacity: $opacity-hover;
+         }
+      }
+   }
+}
+</style>
+<style lang="scss">
+.h-modalFrame.curriculumDetail {
+   /* prettier-ignore */
+   --modalFrameTitHeight: 0PX;
+   .modalFrameBox {
+      background: linear-gradient(180deg, #ffdd5d 0%, #ffb93b 100%);
+      border-radius: 57px;
+      box-shadow: none;
+      .modalFrameTitle {
+         display: none;
+      }
+   }
+}
+</style>

+ 308 - 299
src/views/homePage/components/curriculum/curriculum_gym.vue

@@ -1,299 +1,308 @@
-<!--
-* @FileDescription: 管乐迷课表
-* @Author: 黄琪勇
-* @Date:2024-03-29 17:31:26
--->
-<template>
-   <div class="curriculum_gym">
-      <div class="head">
-         <div class="timeBox">
-            <img class="timeImg" src="@/img/curriculum/sj.png" />
-            <div class="time">{{ classData.classDate && format(classData.classDate) }}</div>
-         </div>
-         <div class="operateBox">
-            <template v-if="classData.status === 'UNDERWAY' && !classData.coursewareDetailId && props.classData.teachMode !== 'ONLINE'">
-               <img class="dangerImg" src="@/img/curriculum/jg.png" />
-               <div class="operateBtn" @click="handleSetUpCourseware(classData.id)">配置课件</div>
-            </template>
-            <template v-else-if="classData.status === 'NOT_START'">
-               <div class="noStart">未开始</div>
-            </template>
-            <template v-else-if="classData.status === 'UNDERWAY'">
-               <div class="ing">进行中</div>
-            </template>
-            <template v-else>
-               <div class="end">已结束</div>
-            </template>
-         </div>
-      </div>
-      <div class="timeTitBox">
-         {{ classData.startClassTime && format(classData.startClassTime, "hh:ii") }}-{{
-            classData.endClassTime && format(classData.endClassTime, "hh:ii")
-         }}
-      </div>
-      <div class="classNameBox">
-         <img class="xxImg" :src="classData.teachMode === 'ONLINE' ? require('@/img/curriculum/xs.png') : require('@/img/curriculum/xx.png')" />
-         <img class="typeImg" :src="require(`@/img/curriculum/${classImgType[classData.type as keyof typeof classImgType]}.png`)" />
-         <div class="className">
-            <ellipsisScroll :title="`${classNameType[classData.type as keyof typeof classNameType]}·${classData.name}`" />
-         </div>
-      </div>
-      <div class="addressCon">
-         <div class="adressBox">
-            <div>上课地点:</div>
-            <div class="adress">
-               <ellipsisScroll :title="classData.teachMode === 'ONLINE' ? '网络教室' : classData.schoolName" />
-            </div>
-         </div>
-         <div class="adressBox">
-            <div>上课学生:</div>
-            <div class="adress">
-               <ellipsisScroll :title="classData.studentNames" />
-            </div>
-         </div>
-      </div>
-      <div class="stateBox">
-         <div>
-            <img
-               :src="
-                  classData.signInStatusEnum === 1
-                     ? require('@/img/curriculum/qd1.png')
-                     : classData.signInStatusEnum === 0
-                     ? require('@/img/curriculum/qd2.png')
-                     : require('@/img/curriculum/qd.png')
-               "
-            />
-            <div :class="[classData.signInStatusEnum === 1 ? 'signIn' : classData.signInStatusEnum === 0 && 'abnormalSignIn']">
-               {{ classData.signInStatusEnum === 1 ? "正常签到" : classData.signInStatusEnum === 0 ? "异常签到" : "未签到" }}
-            </div>
-         </div>
-         <div>
-            <img
-               :src="
-                  classData.signOutStatusEnum === 1
-                     ? require('@/img/curriculum/qt1.png')
-                     : classData.signOutStatusEnum === 0
-                     ? require('@/img/curriculum/qt2.png')
-                     : require('@/img/curriculum/qt.png')
-               "
-            />
-            <div :class="[classData.signOutStatusEnum === 1 ? 'signOut' : classData.signOutStatusEnum === 0 && 'abnormalSignOut']">
-               {{ classData.signOutStatusEnum === 1 ? "正常签退" : classData.signOutStatusEnum === 0 ? "异常签退" : "未签退" }}
-            </div>
-         </div>
-      </div>
-      <div class="btnCon">
-         <div class="btnDetail" @click="handleClickDetail(classData.id)">查看详情</div>
-         <div class="btnGoClass" v-if="classData.status === 'UNDERWAY'" @click="handleStartClass(classData.id)">开始上课</div>
-      </div>
-   </div>
-</template>
-
-<script setup lang="ts">
-import { format } from "@/libs/tools"
-import { useCurriculumDetail, useSetUpCourseware } from "@/views/curriculum"
-import { handleStartClass_gym, isONLINE_gym } from "@/views/curriculum/hooks/useStartClass"
-import { classImgType, classNameType } from "@/views/curriculum/type"
-
-const props = defineProps<{
-   classData: Record<string, any>
-}>()
-const emits = defineEmits<{
-   (e: "update"): void
-}>()
-
-// 开始上课
-function handleStartClass(id: string) {
-   if (isONLINE_gym(props.classData.teachMode)) {
-      return
-   }
-   handleStartClass_gym(id)
-}
-
-//查看详情
-function handleClickDetail(id: string) {
-   if (isONLINE_gym(props.classData.teachMode)) {
-      return
-   }
-   useCurriculumDetail(id)
-}
-// 配置课表
-function handleSetUpCourseware(id: string) {
-   if (isONLINE_gym(props.classData.teachMode)) {
-      return
-   }
-   useSetUpCourseware(id, () => {
-      emits("update")
-   })
-}
-</script>
-
-<style lang="scss" scoped>
-.curriculum_gym {
-   padding: 0 30px;
-   .head {
-      padding-top: 25px;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      .timeBox {
-         display: flex;
-         align-items: center;
-         .timeImg {
-            width: 28px;
-            height: 28px;
-         }
-         .time {
-            margin-left: 8px;
-            font-weight: 500;
-            font-size: 24px;
-            color: #777777;
-         }
-      }
-      .operateBox {
-         display: flex;
-         align-items: center;
-         .dangerImg {
-            width: 24px;
-            height: 24px;
-         }
-         .operateBtn {
-            margin-left: 10px;
-            font-weight: 500;
-            font-size: 24px;
-            color: #f44541;
-            cursor: pointer;
-            &:hover {
-               opacity: $opacity-hover;
-            }
-         }
-         .noStart {
-            font-weight: 500;
-            font-size: 24px;
-            color: #777777;
-         }
-         .ing {
-            font-weight: 500;
-            font-size: 24px;
-            color: #f67146;
-         }
-         .end {
-            font-weight: 500;
-            font-size: 24px;
-            color: #aaaaaa;
-         }
-      }
-   }
-   .timeTitBox {
-      text-align: center;
-      margin-top: 68px;
-      font-family: DINAlternate, DINAlternate;
-      font-weight: bold;
-      font-size: 52px;
-      color: #f67146;
-   }
-   .classNameBox {
-      margin-top: 46px;
-      width: 100%;
-      display: flex;
-      align-items: center;
-      .xxImg {
-         flex-shrink: 0;
-         width: 46px;
-         height: 24px;
-      }
-      .typeImg {
-         flex-shrink: 0;
-         margin-left: 6px;
-         width: 55px;
-         height: 24px;
-      }
-      .className {
-         flex-grow: 1;
-         overflow: hidden;
-         margin-left: 6px;
-         font-weight: 600;
-         font-size: 24px;
-         color: #333333;
-      }
-   }
-   .addressCon {
-      margin-top: 16px;
-      width: 100%;
-      & > div {
-         font-weight: 500;
-         font-size: 18px;
-         color: #777777;
-      }
-      & > div:nth-child(2) {
-         margin-top: 14px;
-      }
-      .adressBox {
-         display: flex;
-         align-items: center;
-         & > div:nth-child(1) {
-            flex-shrink: 0;
-         }
-         .adress {
-            overflow: hidden;
-         }
-      }
-   }
-   .stateBox {
-      margin-top: 48px;
-      display: flex;
-      justify-content: space-between;
-      & > div {
-         width: 216px;
-         height: 65px;
-         background: #f2f2f2;
-         border-radius: 18px;
-         display: flex;
-         justify-content: center;
-         align-items: center;
-         & > img {
-            width: 27px;
-            height: 27px;
-         }
-         & > div {
-            margin-left: 6px;
-            font-weight: 500;
-            font-size: 22px;
-            color: #aaaaaa;
-            &.signIn,
-            &.signOut {
-               color: #01c199;
-            }
-            &.abnormalSignIn,
-            &.abnormalSignOut {
-               color: #ff0000;
-            }
-         }
-      }
-   }
-   .btnCon {
-      margin-top: 58px;
-      display: flex;
-      .btnGoClass,
-      .btnDetail {
-         flex-grow: 1;
-         height: 74px;
-         background: linear-gradient(180deg, #ffffff 0%, #ffdbc1 100%);
-         box-shadow: 4px 5px 0px 0px rgba(236, 102, 52, 0.45), inset 0px -7px 3px 0px rgba(254, 163, 138, 0.46);
-         border-radius: 37px;
-         font-weight: 500;
-         font-size: 24px;
-         color: #f67146;
-         line-height: 74px;
-         text-align: center;
-         cursor: pointer;
-         &:hover {
-            opacity: $opacity-hover;
-         }
-      }
-      .btnGoClass {
-         margin-left: 20px;
-      }
-   }
-}
-</style>
+<!--
+* @FileDescription: 管乐迷课表
+* @Author: 黄琪勇
+* @Date:2024-03-29 17:31:26
+-->
+<template>
+   <div class="curriculum_gym">
+      <div class="head">
+         <div class="timeBox">
+            <img class="timeImg" src="@/img/curriculum/sj.png" />
+            <div class="time">{{ classData.classDate && format(classData.classDate) }}</div>
+         </div>
+         <div class="operateBox">
+            <template v-if="classData.status === 'UNDERWAY' && !classData.coursewareDetailId && props.classData.teachMode !== 'ONLINE'">
+               <img class="dangerImg" src="@/img/curriculum/jg.png" />
+               <div class="operateBtn" @click="handleSetUpCourseware(classData.id)">配置课件</div>
+            </template>
+            <template v-else-if="classData.status === 'NOT_START'">
+               <div class="noStart">未开始</div>
+            </template>
+            <template v-else-if="classData.status === 'UNDERWAY'">
+               <div class="ing">进行中</div>
+            </template>
+            <template v-else>
+               <div class="end">已结束</div>
+            </template>
+         </div>
+      </div>
+      <div class="timeTitBox">
+         {{ classData.startClassTime && format(classData.startClassTime, "hh:ii") }}-{{
+            classData.endClassTime && format(classData.endClassTime, "hh:ii")
+         }}
+      </div>
+      <div class="classNameBox">
+         <img class="xxImg" :src="classData.teachMode === 'ONLINE' ? require('@/img/curriculum/xs.png') : require('@/img/curriculum/xx.png')" />
+         <img class="typeImg" :src="require(`@/img/curriculum/${classImgType[classData.type as keyof typeof classImgType]}.png`)" />
+         <div class="className">
+            <ellipsisScroll :title="`${classNameType[classData.type as keyof typeof classNameType]}·${classData.name}`" />
+         </div>
+      </div>
+      <div class="addressCon">
+         <div class="adressBox">
+            <div>上课地点:</div>
+            <div class="adress">
+               <ellipsisScroll :title="classData.teachMode === 'ONLINE' ? '网络教室' : classData.schoolName" />
+            </div>
+         </div>
+         <div class="adressBox">
+            <div>上课学生:</div>
+            <div class="adress">
+               <ellipsisScroll :title="classData.studentNames" />
+            </div>
+         </div>
+      </div>
+      <div class="stateBox">
+         <div>
+            <img
+               :src="
+                  classData.signInStatusEnum === 1
+                     ? require('@/img/curriculum/qd1.png')
+                     : classData.signInStatusEnum === 0
+                     ? require('@/img/curriculum/qd2.png')
+                     : require('@/img/curriculum/qd.png')
+               "
+            />
+            <div :class="[classData.signInStatusEnum === 1 ? 'signIn' : classData.signInStatusEnum === 0 && 'abnormalSignIn']">
+               {{ classData.signInStatusEnum === 1 ? "正常签到" : classData.signInStatusEnum === 0 ? "异常签到" : "未签到" }}
+            </div>
+         </div>
+         <div>
+            <img
+               :src="
+                  classData.signOutStatusEnum === 1
+                     ? require('@/img/curriculum/qt1.png')
+                     : classData.signOutStatusEnum === 0
+                     ? require('@/img/curriculum/qt2.png')
+                     : require('@/img/curriculum/qt.png')
+               "
+            />
+            <div :class="[classData.signOutStatusEnum === 1 ? 'signOut' : classData.signOutStatusEnum === 0 && 'abnormalSignOut']">
+               {{ classData.signOutStatusEnum === 1 ? "正常签退" : classData.signOutStatusEnum === 0 ? "异常签退" : "未签退" }}
+            </div>
+         </div>
+      </div>
+      <div class="btnCon">
+         <div class="btnDetail" @click="handleClickDetail(classData.id, classData.coursewareEnable)">查看详情</div>
+         <div class="btnGoClass" v-if="classData.status === 'UNDERWAY'" @click="handleStartClass(classData.id)">开始上课</div>
+      </div>
+   </div>
+</template>
+
+<script setup lang="ts">
+import { format } from "@/libs/tools"
+import { useCurriculumDetail, useSetUpCourseware } from "@/views/curriculum"
+import { handleStartClass_gym, isONLINE_gym } from "@/views/curriculum/hooks/useStartClass"
+import { classImgType, classNameType } from "@/views/curriculum/type"
+import { ElMessage } from "element-plus"
+
+const props = defineProps<{
+   classData: Record<string, any>
+}>()
+const emits = defineEmits<{
+   (e: "update"): void
+}>()
+
+// 开始上课
+function handleStartClass(id: string) {
+   if (isONLINE_gym(props.classData.teachMode)) {
+      return
+   }
+   handleStartClass_gym(id)
+}
+
+//查看详情
+function handleClickDetail(id: string, coursewareEnable: boolean) {
+   if (isONLINE_gym(props.classData.teachMode)) {
+      return
+   }
+   if (!coursewareEnable) {
+      ElMessage({
+         showClose: true,
+         message: "该资源已失效",
+         type: "error"
+      })
+      return
+   }
+   useCurriculumDetail(id)
+}
+// 配置课表
+function handleSetUpCourseware(id: string) {
+   if (isONLINE_gym(props.classData.teachMode)) {
+      return
+   }
+   useSetUpCourseware(id, () => {
+      emits("update")
+   })
+}
+</script>
+
+<style lang="scss" scoped>
+.curriculum_gym {
+   padding: 0 30px;
+   .head {
+      padding-top: 25px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      .timeBox {
+         display: flex;
+         align-items: center;
+         .timeImg {
+            width: 28px;
+            height: 28px;
+         }
+         .time {
+            margin-left: 8px;
+            font-weight: 500;
+            font-size: 24px;
+            color: #777777;
+         }
+      }
+      .operateBox {
+         display: flex;
+         align-items: center;
+         .dangerImg {
+            width: 24px;
+            height: 24px;
+         }
+         .operateBtn {
+            margin-left: 10px;
+            font-weight: 500;
+            font-size: 24px;
+            color: #f44541;
+            cursor: pointer;
+            &:hover {
+               opacity: $opacity-hover;
+            }
+         }
+         .noStart {
+            font-weight: 500;
+            font-size: 24px;
+            color: #777777;
+         }
+         .ing {
+            font-weight: 500;
+            font-size: 24px;
+            color: #f67146;
+         }
+         .end {
+            font-weight: 500;
+            font-size: 24px;
+            color: #aaaaaa;
+         }
+      }
+   }
+   .timeTitBox {
+      text-align: center;
+      margin-top: 68px;
+      font-family: DINAlternate, DINAlternate;
+      font-weight: bold;
+      font-size: 52px;
+      color: #f67146;
+   }
+   .classNameBox {
+      margin-top: 46px;
+      width: 100%;
+      display: flex;
+      align-items: center;
+      .xxImg {
+         flex-shrink: 0;
+         width: 46px;
+         height: 24px;
+      }
+      .typeImg {
+         flex-shrink: 0;
+         margin-left: 6px;
+         width: 55px;
+         height: 24px;
+      }
+      .className {
+         flex-grow: 1;
+         overflow: hidden;
+         margin-left: 6px;
+         font-weight: 600;
+         font-size: 24px;
+         color: #333333;
+      }
+   }
+   .addressCon {
+      margin-top: 16px;
+      width: 100%;
+      & > div {
+         font-weight: 500;
+         font-size: 18px;
+         color: #777777;
+      }
+      & > div:nth-child(2) {
+         margin-top: 14px;
+      }
+      .adressBox {
+         display: flex;
+         align-items: center;
+         & > div:nth-child(1) {
+            flex-shrink: 0;
+         }
+         .adress {
+            overflow: hidden;
+         }
+      }
+   }
+   .stateBox {
+      margin-top: 48px;
+      display: flex;
+      justify-content: space-between;
+      & > div {
+         width: 216px;
+         height: 65px;
+         background: #f2f2f2;
+         border-radius: 18px;
+         display: flex;
+         justify-content: center;
+         align-items: center;
+         & > img {
+            width: 27px;
+            height: 27px;
+         }
+         & > div {
+            margin-left: 6px;
+            font-weight: 500;
+            font-size: 22px;
+            color: #aaaaaa;
+            &.signIn,
+            &.signOut {
+               color: #01c199;
+            }
+            &.abnormalSignIn,
+            &.abnormalSignOut {
+               color: #ff0000;
+            }
+         }
+      }
+   }
+   .btnCon {
+      margin-top: 58px;
+      display: flex;
+      .btnGoClass,
+      .btnDetail {
+         flex-grow: 1;
+         height: 74px;
+         background: linear-gradient(180deg, #ffffff 0%, #ffdbc1 100%);
+         box-shadow: 4px 5px 0px 0px rgba(236, 102, 52, 0.45), inset 0px -7px 3px 0px rgba(254, 163, 138, 0.46);
+         border-radius: 37px;
+         font-weight: 500;
+         font-size: 24px;
+         color: #f67146;
+         line-height: 74px;
+         text-align: center;
+         cursor: pointer;
+         &:hover {
+            opacity: $opacity-hover;
+         }
+      }
+      .btnGoClass {
+         margin-left: 20px;
+      }
+   }
+}
+</style>

+ 224 - 215
src/views/homePage/components/curriculum/curriculum_gyt.vue

@@ -1,215 +1,224 @@
-<!--
-* @FileDescription: 管乐团课表
-* @Author: 黄琪勇
-* @Date:2024-03-29 17:31:26
--->
-<template>
-   <div class="curriculum_gyt">
-      <div class="head">
-         <div class="timeBox">
-            <img class="timeImg" src="@/img/curriculum/sj.png" />
-            <div class="time">{{ classData.classDate && format(classData.classDate) }}</div>
-         </div>
-         <div class="operateBox">
-            <template v-if="classData.coursewareFlag && !classData.lessonCoursewareId && classData.status !== 'COMPLETE'">
-               <img class="dangerImg" src="@/img/curriculum/jg.png" />
-               <div class="operateBtn" @click="handleSetUpCourseware(classData.id)">配置课件</div>
-            </template>
-            <template v-else-if="classData.status === 'NOT_START'">
-               <div class="noStart">未开始</div>
-            </template>
-            <template v-else-if="classData.status === 'ING'">
-               <div class="ing">进行中</div>
-            </template>
-            <template v-else>
-               <div class="end">已结束</div>
-            </template>
-         </div>
-      </div>
-      <div class="timeTitBox">
-         {{ classData.startTime && format(classData.startTime, "hh:ii") }}-{{ classData.endTime && format(classData.endTime, "hh:ii") }}
-      </div>
-      <div class="nameTitBox">
-         <ellipsisScroll :title="`${classData.className}-${classData.teacherName}`" />
-      </div>
-      <div class="schoolTitBox">
-         <ellipsisScroll :title="'·' + classData.orchestraName + '·'" />
-      </div>
-      <div class="stateBox">
-         <div>
-            <img :src="classData.signIn ? require('@/img/curriculum/qd1.png') : require('@/img/curriculum/qd.png')" />
-            <div :class="{ signIn: classData.signIn }">{{ classData.signIn ? "已签到" : "未签到" }}</div>
-         </div>
-         <div>
-            <img :src="classData.signOut ? require('@/img/curriculum/qt1.png') : require('@/img/curriculum/qt.png')" />
-            <div :class="{ signOut: classData.signOut }">{{ classData.signOut ? "已签退" : "未签退" }}</div>
-         </div>
-      </div>
-      <div class="btnCon">
-         <div class="btnDetail" @click="handleClickDetail(classData.id)">查看详情</div>
-         <div class="btnGoClass" v-if="classData.status === 'ING'" @click="handleStartClass(classData.id)">开始上课</div>
-      </div>
-   </div>
-</template>
-
-<script setup lang="ts">
-import { format } from "@/libs/tools"
-import { useCurriculumDetail, useSetUpCourseware } from "@/views/curriculum"
-import { handleStartClass_gyt } from "@/views/curriculum/hooks/useStartClass"
-const emits = defineEmits<{
-   (e: "update"): void
-}>()
-defineProps<{
-   classData: Record<string, any>
-}>()
-
-// 开始上课
-function handleStartClass(id: string) {
-   handleStartClass_gyt(id)
-}
-//查看详情
-function handleClickDetail(id: string) {
-   useCurriculumDetail(id)
-}
-// 配置课表
-function handleSetUpCourseware(id: string) {
-   useSetUpCourseware(id, () => {
-      emits("update")
-   })
-}
-</script>
-
-<style lang="scss" scoped>
-.curriculum_gyt {
-   padding: 0 30px;
-   .head {
-      padding-top: 25px;
-      display: flex;
-      justify-content: space-between;
-      align-items: center;
-      .timeBox {
-         display: flex;
-         align-items: center;
-         .timeImg {
-            width: 28px;
-            height: 28px;
-         }
-         .time {
-            margin-left: 8px;
-            font-weight: 500;
-            font-size: 24px;
-            color: #777777;
-         }
-      }
-      .operateBox {
-         display: flex;
-         align-items: center;
-         .dangerImg {
-            width: 24px;
-            height: 24px;
-         }
-         .operateBtn {
-            margin-left: 10px;
-            font-weight: 500;
-            font-size: 24px;
-            color: #f44541;
-            cursor: pointer;
-            &:hover {
-               opacity: $opacity-hover;
-            }
-         }
-         .noStart {
-            font-weight: 500;
-            font-size: 24px;
-            color: #777777;
-         }
-         .ing {
-            font-weight: 500;
-            font-size: 24px;
-            color: #f67146;
-         }
-         .end {
-            font-weight: 500;
-            font-size: 24px;
-            color: #aaaaaa;
-         }
-      }
-   }
-   .timeTitBox {
-      text-align: center;
-      margin-top: 68px;
-      font-family: DINAlternate, DINAlternate;
-      font-weight: bold;
-      font-size: 52px;
-      color: #f67146;
-   }
-   .nameTitBox {
-      margin: 34px 30px 0;
-      font-weight: 600;
-      font-size: 25px;
-      color: #333333;
-      text-align: center;
-      overflow: hidden;
-   }
-   .schoolTitBox {
-      margin: 32px 38px 0;
-      font-weight: 500;
-      font-size: 22px;
-      color: #777777;
-      text-align: center;
-      overflow: hidden;
-   }
-   .stateBox {
-      margin-top: 76px;
-      display: flex;
-      justify-content: space-between;
-      & > div {
-         width: 216px;
-         height: 65px;
-         background: #f2f2f2;
-         border-radius: 18px;
-         display: flex;
-         justify-content: center;
-         align-items: center;
-         & > img {
-            width: 27px;
-            height: 27px;
-         }
-         & > div {
-            margin-left: 6px;
-            font-weight: 500;
-            font-size: 22px;
-            color: #aaaaaa;
-            &.signIn,
-            &.signOut {
-               color: #01c199;
-            }
-         }
-      }
-   }
-   .btnCon {
-      margin-top: 58px;
-      display: flex;
-      .btnGoClass,
-      .btnDetail {
-         flex-grow: 1;
-         height: 74px;
-         background: linear-gradient(180deg, #ffffff 0%, #ffdbc1 100%);
-         box-shadow: 4px 5px 0px 0px rgba(236, 102, 52, 0.45), inset 0px -7px 3px 0px rgba(254, 163, 138, 0.46);
-         border-radius: 37px;
-         font-weight: 500;
-         font-size: 24px;
-         color: #f67146;
-         line-height: 74px;
-         text-align: center;
-         cursor: pointer;
-         &:hover {
-            opacity: $opacity-hover;
-         }
-      }
-      .btnGoClass {
-         margin-left: 20px;
-      }
-   }
-}
-</style>
+<!--
+* @FileDescription: 管乐团课表
+* @Author: 黄琪勇
+* @Date:2024-03-29 17:31:26
+-->
+<template>
+   <div class="curriculum_gyt">
+      <div class="head">
+         <div class="timeBox">
+            <img class="timeImg" src="@/img/curriculum/sj.png" />
+            <div class="time">{{ classData.classDate && format(classData.classDate) }}</div>
+         </div>
+         <div class="operateBox">
+            <template v-if="classData.coursewareFlag && !classData.lessonCoursewareId && classData.status !== 'COMPLETE'">
+               <img class="dangerImg" src="@/img/curriculum/jg.png" />
+               <div class="operateBtn" @click="handleSetUpCourseware(classData.id)">配置课件</div>
+            </template>
+            <template v-else-if="classData.status === 'NOT_START'">
+               <div class="noStart">未开始</div>
+            </template>
+            <template v-else-if="classData.status === 'ING'">
+               <div class="ing">进行中</div>
+            </template>
+            <template v-else>
+               <div class="end">已结束</div>
+            </template>
+         </div>
+      </div>
+      <div class="timeTitBox">
+         {{ classData.startTime && format(classData.startTime, "hh:ii") }}-{{ classData.endTime && format(classData.endTime, "hh:ii") }}
+      </div>
+      <div class="nameTitBox">
+         <ellipsisScroll :title="`${classData.className}-${classData.teacherName}`" />
+      </div>
+      <div class="schoolTitBox">
+         <ellipsisScroll :title="'·' + classData.orchestraName + '·'" />
+      </div>
+      <div class="stateBox">
+         <div>
+            <img :src="classData.signIn ? require('@/img/curriculum/qd1.png') : require('@/img/curriculum/qd.png')" />
+            <div :class="{ signIn: classData.signIn }">{{ classData.signIn ? "已签到" : "未签到" }}</div>
+         </div>
+         <div>
+            <img :src="classData.signOut ? require('@/img/curriculum/qt1.png') : require('@/img/curriculum/qt.png')" />
+            <div :class="{ signOut: classData.signOut }">{{ classData.signOut ? "已签退" : "未签退" }}</div>
+         </div>
+      </div>
+      <div class="btnCon">
+         <div class="btnDetail" @click="handleClickDetail(classData.id, classData.applyStatus)">查看详情</div>
+         <div class="btnGoClass" v-if="classData.status === 'ING'" @click="handleStartClass(classData.id)">开始上课</div>
+      </div>
+   </div>
+</template>
+
+<script setup lang="ts">
+import { format } from "@/libs/tools"
+import { useCurriculumDetail, useSetUpCourseware } from "@/views/curriculum"
+import { handleStartClass_gyt } from "@/views/curriculum/hooks/useStartClass"
+import { ElMessage } from "element-plus"
+const emits = defineEmits<{
+   (e: "update"): void
+}>()
+defineProps<{
+   classData: Record<string, any>
+}>()
+
+// 开始上课
+function handleStartClass(id: string) {
+   handleStartClass_gyt(id)
+}
+//查看详情
+function handleClickDetail(id: string, applyStatus: boolean) {
+   if (!applyStatus) {
+      ElMessage({
+         showClose: true,
+         message: "该资源已失效",
+         type: "error"
+      })
+      return
+   }
+   useCurriculumDetail(id)
+}
+// 配置课表
+function handleSetUpCourseware(id: string) {
+   useSetUpCourseware(id, () => {
+      emits("update")
+   })
+}
+</script>
+
+<style lang="scss" scoped>
+.curriculum_gyt {
+   padding: 0 30px;
+   .head {
+      padding-top: 25px;
+      display: flex;
+      justify-content: space-between;
+      align-items: center;
+      .timeBox {
+         display: flex;
+         align-items: center;
+         .timeImg {
+            width: 28px;
+            height: 28px;
+         }
+         .time {
+            margin-left: 8px;
+            font-weight: 500;
+            font-size: 24px;
+            color: #777777;
+         }
+      }
+      .operateBox {
+         display: flex;
+         align-items: center;
+         .dangerImg {
+            width: 24px;
+            height: 24px;
+         }
+         .operateBtn {
+            margin-left: 10px;
+            font-weight: 500;
+            font-size: 24px;
+            color: #f44541;
+            cursor: pointer;
+            &:hover {
+               opacity: $opacity-hover;
+            }
+         }
+         .noStart {
+            font-weight: 500;
+            font-size: 24px;
+            color: #777777;
+         }
+         .ing {
+            font-weight: 500;
+            font-size: 24px;
+            color: #f67146;
+         }
+         .end {
+            font-weight: 500;
+            font-size: 24px;
+            color: #aaaaaa;
+         }
+      }
+   }
+   .timeTitBox {
+      text-align: center;
+      margin-top: 68px;
+      font-family: DINAlternate, DINAlternate;
+      font-weight: bold;
+      font-size: 52px;
+      color: #f67146;
+   }
+   .nameTitBox {
+      margin: 34px 30px 0;
+      font-weight: 600;
+      font-size: 25px;
+      color: #333333;
+      text-align: center;
+      overflow: hidden;
+   }
+   .schoolTitBox {
+      margin: 32px 38px 0;
+      font-weight: 500;
+      font-size: 22px;
+      color: #777777;
+      text-align: center;
+      overflow: hidden;
+   }
+   .stateBox {
+      margin-top: 76px;
+      display: flex;
+      justify-content: space-between;
+      & > div {
+         width: 216px;
+         height: 65px;
+         background: #f2f2f2;
+         border-radius: 18px;
+         display: flex;
+         justify-content: center;
+         align-items: center;
+         & > img {
+            width: 27px;
+            height: 27px;
+         }
+         & > div {
+            margin-left: 6px;
+            font-weight: 500;
+            font-size: 22px;
+            color: #aaaaaa;
+            &.signIn,
+            &.signOut {
+               color: #01c199;
+            }
+         }
+      }
+   }
+   .btnCon {
+      margin-top: 58px;
+      display: flex;
+      .btnGoClass,
+      .btnDetail {
+         flex-grow: 1;
+         height: 74px;
+         background: linear-gradient(180deg, #ffffff 0%, #ffdbc1 100%);
+         box-shadow: 4px 5px 0px 0px rgba(236, 102, 52, 0.45), inset 0px -7px 3px 0px rgba(254, 163, 138, 0.46);
+         border-radius: 37px;
+         font-weight: 500;
+         font-size: 24px;
+         color: #f67146;
+         line-height: 74px;
+         text-align: center;
+         cursor: pointer;
+         &:hover {
+            opacity: $opacity-hover;
+         }
+      }
+      .btnGoClass {
+         margin-left: 20px;
+      }
+   }
+}
+</style>

+ 358 - 358
src/views/homePage/homePage.vue

@@ -1,358 +1,358 @@
-<!--
-* @FileDescription: 首页
-* @Author: 黄琪勇
-* @Date:2024-03-29 17:20:39
--->
-<template>
-   <navContainer class="homePageNav" :headImg="headImg" :navs="navs">
-      <div class="homePage">
-         <ElScrollbar class="elScrollbar">
-            <div class="classTypes">
-               <div
-                  class="classType"
-                  v-for="item in userStoreHook.roles === 'GYM' ? classTypes_gym : classTypes_gyt"
-                  :key="item.name"
-                  @click="handleRouter(item.url)"
-               >
-                  <img :src="item.img" />
-                  <div>{{ item.name }}</div>
-               </div>
-            </div>
-            <div class="courseBoard" :class="{ isEmpty: isEmptyClassData && !classDataLoading }">
-               <div class="details">
-                  <div class="head">
-                     <div class="leftCon">
-                        <div class="line"></div>
-                        <div class="title">下次课程</div>
-                     </div>
-                     <img class="rightRouter" @click="handleRouterCurriculum" src="@/img/homePage/back.png" />
-                  </div>
-                  <el-skeleton class="elSkeleton" :loading="classDataLoading">
-                     <template #template>
-                        <el-skeleton-item class="elSkeletonItem" variant="p" />
-                        <el-skeleton-item class="elSkeletonItem" variant="p" />
-                        <el-skeleton-item class="elSkeletonItem" variant="h1" />
-                        <el-skeleton-item class="elSkeletonItem" variant="h1" />
-                        <div class="elSkeletonBtnCon">
-                           <el-skeleton-item class="elSkeletonItem" variant="button" />
-                           <el-skeleton-item class="elSkeletonItem" variant="button" />
-                        </div>
-                        <el-skeleton-item class="elSkeletonItem" variant="button" />
-                     </template>
-                     <template #default>
-                        <component
-                           v-if="!isEmptyClassData"
-                           :classData="classData"
-                           :is="userStoreHook.roles === 'GYM' ? curriculum_gym : curriculum_gyt"
-                           @update="handleClassData"
-                        />
-                        <el-empty v-else class="empty" :image="require('@/img/layout/empty1.png')" description="您还没有待上课程哦~" />
-                     </template>
-                  </el-skeleton>
-               </div>
-            </div>
-         </ElScrollbar>
-      </div>
-   </navContainer>
-</template>
-<script setup lang="ts">
-import navContainer from "@/businessComponents/navContainer"
-import { useRouter } from "vue-router"
-import { ref, computed } from "vue"
-import useDialogConfirm from "@/hooks/useDialogConfirm"
-import userStore from "@/store/modules/user"
-import curriculum_gym from "./components/curriculum/curriculum_gym.vue"
-import curriculum_gyt from "./components/curriculum/curriculum_gyt.vue"
-import { getRemind_gyt, getRecentCourseSchedule_gym } from "@/api/homePage.api"
-import { httpAjax } from "@/plugin/httpAjax"
-import { format } from "@/libs/tools"
-
-const userStoreHook = userStore()
-const router = useRouter()
-
-const headImg = {
-   img: require("@/img/homePage/home.png")
-}
-const navs = [
-   {
-      name: "主页"
-   }
-]
-const classTypes_gym = [
-   {
-      img: require("@/img/homePage/kb.png"),
-      name: "课表",
-      url: "/curriculum"
-   },
-   {
-      img: require("@/img/homePage/xl.png"),
-      name: "训练",
-      url: ""
-   },
-   {
-      img: require("@/img/homePage/jdcp.png"),
-      name: "进度测评",
-      url: ""
-   },
-   {
-      img: require("@/img/homePage/xltj.png"),
-      name: "训练统计",
-      url: ""
-   },
-   {
-      img: require("@/img/homePage/yjl.png"),
-      name: "云练习",
-      url: ""
-   },
-   {
-      img: require("@/img/homePage/yjc.png"),
-      name: "云课堂",
-      url: "/cloudTextbooks"
-   }
-]
-const classTypes_gyt = [
-   {
-      img: require("@/img/homePage/kb.png"),
-      name: "课表",
-      url: "/curriculum"
-   },
-   {
-      img: require("@/img/homePage/xl.png"),
-      name: "课后作业",
-      url: ""
-   },
-   {
-      img: require("@/img/homePage/jdzc.png"),
-      name: "阶段自测",
-      url: ""
-   },
-   {
-      img: require("@/img/homePage/xltj.png"),
-      name: "练习情况",
-      url: ""
-   },
-   {
-      img: require("@/img/homePage/yjl.png"),
-      name: "云练习",
-      url: ""
-   },
-   {
-      img: require("@/img/homePage/yjc.png"),
-      name: "云课堂",
-      url: "/cloudTextbooks"
-   }
-]
-
-/* 下次课程信息 */
-const classData = ref<Record<string, any>>({})
-const classDataLoading = ref(true)
-const isEmptyClassData = computed(() => {
-   return !Object.keys(classData.value).length
-})
-handleClassData()
-function handleClassData() {
-   if (userStoreHook.roles === "GYM") {
-      classDataLoading.value = true
-      httpAjax(getRecentCourseSchedule_gym).then(res => {
-         classDataLoading.value = false
-         if (res.code === 200) {
-            classData.value = res.data || {}
-         }
-      })
-   } else {
-      classDataLoading.value = true
-      httpAjax(getRemind_gyt).then(res => {
-         classDataLoading.value = false
-         if (res.code === 200) {
-            classData.value = res.data || {}
-         }
-      })
-   }
-}
-
-function handleRouter(url?: string) {
-   url
-      ? router.push(url)
-      : useDialogConfirm({
-           headImg: require("@/img/homePage/ts.png"),
-           text: "该功能暂未开放,请敬请期待哦~",
-           btnShow: [true]
-        })
-}
-function handleRouterCurriculum() {
-   router.push({
-      path: "/curriculum",
-      query: {
-         date: classData.value.classDate ? format(classData.value.classDate) : ""
-      }
-   })
-}
-</script>
-<style lang="scss" scoped>
-.homePageNav.navContainer {
-   &:deep(.navCon) {
-      .navImg {
-         margin-left: 50px;
-         > img {
-            width: 91px;
-            height: 92px;
-            top: 70%;
-         }
-      }
-      .nav {
-         font-size: 28px;
-         font-family: AlimamaFangYuanTiVF, AlimamaFangYuanTiVF;
-         &:last-child {
-            margin-right: 30px;
-         }
-      }
-   }
-}
-.homePage {
-   width: 100%;
-   height: 100%;
-   & > :deep(.elScrollbar) {
-      .el-scrollbar__view {
-         width: 100%;
-         display: flex;
-         padding: 50px 50px 0;
-      }
-      .el-scrollbar__wrap {
-         overflow-x: hidden;
-      }
-   }
-   .classTypes {
-      flex-grow: 1;
-      display: flex;
-      flex-wrap: wrap;
-      justify-content: space-between;
-      height: 729px;
-      align-content: space-between;
-      .classType {
-         background: #feffff;
-         box-shadow: 0px 2px 14px 0 #f1e3cc;
-         border-radius: 34px;
-         width: 360px;
-         height: 350px;
-         display: flex;
-         justify-content: center;
-         align-items: center;
-         flex-direction: column;
-         cursor: pointer;
-         padding: 44px 53px;
-         &:hover {
-            transform: scale(1.02);
-            box-shadow: 0px 2px 14px 0px #e4d7c2;
-         }
-         > div {
-            margin-top: 10px;
-            font-family: AlimamaFangYuanTiVF, AlimamaFangYuanTiVF;
-            font-weight: bold;
-            font-size: 28px;
-            color: #393939;
-         }
-         > img {
-            width: 100%;
-         }
-      }
-   }
-   .courseBoard {
-      flex-shrink: 0;
-      margin-left: 50px;
-      margin-top: -35px;
-      width: 572px;
-      height: 764px;
-      background: url("@/img/homePage/bg1.png") no-repeat;
-      background-size: 100% 100%;
-      position: relative;
-      &.isEmpty {
-         background: url("@/img/homePage/bg.png") no-repeat;
-         background-size: 100% 100%;
-      }
-      .details {
-         width: 100%;
-         position: absolute;
-         top: 88px;
-         left: 0;
-         padding: 0 30px;
-         .head {
-            height: 81px;
-            display: flex;
-            justify-content: space-between;
-            align-items: center;
-            padding: 0 30px;
-            .leftCon {
-               display: flex;
-               align-items: center;
-               .line {
-                  width: 8px;
-                  height: 28px;
-                  background: linear-gradient(180deg, #ffcb35 0%, #fea60a 100%), #ff6a67;
-                  border-radius: 7px;
-               }
-               .title {
-                  margin-left: 12px;
-                  font-family: AlimamaFangYuanTiVF, AlimamaFangYuanTiVF;
-                  font-weight: bold;
-                  font-size: 28px;
-                  color: #994d1c;
-               }
-            }
-            .rightRouter {
-               width: 38px;
-               height: 38px;
-               cursor: pointer;
-               &:hover {
-                  opacity: $opacity-hover;
-               }
-            }
-         }
-         .elSkeleton {
-            padding: 0 30px;
-            display: flex;
-            flex-direction: column;
-            align-items: center;
-            > .elSkeletonItem {
-               &:nth-child(1) {
-                  margin-top: 25px;
-                  height: 34px;
-               }
-               &:nth-child(2) {
-                  width: 50%;
-                  margin-top: 58px;
-                  height: 60px;
-               }
-               &:nth-child(3) {
-                  margin-top: 34px;
-               }
-               &:nth-child(4) {
-                  margin-top: 34px;
-               }
-               &:nth-child(6) {
-                  width: 100%;
-                  height: 74px;
-                  margin-top: 58px;
-               }
-            }
-            .elSkeletonBtnCon {
-               width: 100%;
-               margin-top: 76px;
-               display: flex;
-               justify-content: space-between;
-               > .elSkeletonItem {
-                  width: 216px;
-                  height: 65px;
-               }
-            }
-         }
-         :deep(.empty) {
-            margin-top: 114px;
-            padding: 0;
-            .el-empty__image {
-               width: 360px;
-            }
-         }
-      }
-   }
-}
-</style>
+<!--
+* @FileDescription: 首页
+* @Author: 黄琪勇
+* @Date:2024-03-29 17:20:39
+-->
+<template>
+   <navContainer class="homePageNav" :headImg="headImg" :navs="navs">
+      <div class="homePage">
+         <ElScrollbar class="elScrollbar">
+            <div class="classTypes">
+               <div
+                  class="classType"
+                  v-for="item in userStoreHook.roles === 'GYM' ? classTypes_gym : classTypes_gyt"
+                  :key="item.name"
+                  @click="handleRouter(item.url)"
+               >
+                  <img :src="item.img" />
+                  <div>{{ item.name }}</div>
+               </div>
+            </div>
+            <div class="courseBoard" :class="{ isEmpty: isEmptyClassData && !classDataLoading }">
+               <div class="details">
+                  <div class="head">
+                     <div class="leftCon">
+                        <div class="line"></div>
+                        <div class="title">下次课程</div>
+                     </div>
+                     <img class="rightRouter" @click="handleRouterCurriculum" src="@/img/homePage/back.png" />
+                  </div>
+                  <el-skeleton class="elSkeleton" :loading="classDataLoading">
+                     <template #template>
+                        <el-skeleton-item class="elSkeletonItem" variant="p" />
+                        <el-skeleton-item class="elSkeletonItem" variant="p" />
+                        <el-skeleton-item class="elSkeletonItem" variant="h1" />
+                        <el-skeleton-item class="elSkeletonItem" variant="h1" />
+                        <div class="elSkeletonBtnCon">
+                           <el-skeleton-item class="elSkeletonItem" variant="button" />
+                           <el-skeleton-item class="elSkeletonItem" variant="button" />
+                        </div>
+                        <el-skeleton-item class="elSkeletonItem" variant="button" />
+                     </template>
+                     <template #default>
+                        <component
+                           v-if="!isEmptyClassData"
+                           :classData="classData"
+                           :is="userStoreHook.roles === 'GYM' ? curriculum_gym : curriculum_gyt"
+                           @update="handleClassData"
+                        />
+                        <el-empty v-else class="empty" :image="require('@/img/layout/empty1.png')" description="您还没有待上课程哦~" />
+                     </template>
+                  </el-skeleton>
+               </div>
+            </div>
+         </ElScrollbar>
+      </div>
+   </navContainer>
+</template>
+<script setup lang="ts">
+import navContainer from "@/businessComponents/navContainer"
+import { useRouter } from "vue-router"
+import { ref, computed } from "vue"
+import useDialogConfirm from "@/hooks/useDialogConfirm"
+import userStore from "@/store/modules/user"
+import curriculum_gym from "./components/curriculum/curriculum_gym.vue"
+import curriculum_gyt from "./components/curriculum/curriculum_gyt.vue"
+import { getRemind_gyt, getRecentCourseSchedule_gym } from "@/api/homePage.api"
+import { httpAjax } from "@/plugin/httpAjax"
+import { format } from "@/libs/tools"
+
+const userStoreHook = userStore()
+const router = useRouter()
+
+const headImg = {
+   img: require("@/img/homePage/home.png")
+}
+const navs = [
+   {
+      name: "主页"
+   }
+]
+const classTypes_gym = [
+   {
+      img: require("@/img/homePage/kb.png"),
+      name: "课表",
+      url: "/curriculum"
+   },
+   {
+      img: require("@/img/homePage/xl.png"),
+      name: "训练",
+      url: ""
+   },
+   {
+      img: require("@/img/homePage/jdcp.png"),
+      name: "进度测评",
+      url: ""
+   },
+   {
+      img: require("@/img/homePage/xltj.png"),
+      name: "训练统计",
+      url: ""
+   },
+   {
+      img: require("@/img/homePage/yjl.png"),
+      name: "云练习",
+      url: ""
+   },
+   {
+      img: require("@/img/homePage/yjc.png"),
+      name: "云课堂",
+      url: "/cloudTextbooks"
+   }
+]
+const classTypes_gyt = [
+   {
+      img: require("@/img/homePage/kb.png"),
+      name: "课表",
+      url: "/curriculum"
+   },
+   {
+      img: require("@/img/homePage/xl.png"),
+      name: "课后作业",
+      url: ""
+   },
+   {
+      img: require("@/img/homePage/jdzc.png"),
+      name: "阶段自测",
+      url: ""
+   },
+   {
+      img: require("@/img/homePage/xltj.png"),
+      name: "练习情况",
+      url: ""
+   },
+   {
+      img: require("@/img/homePage/yjl.png"),
+      name: "云练习",
+      url: ""
+   },
+   {
+      img: require("@/img/homePage/yjc.png"),
+      name: "云课堂",
+      url: "/cloudTextbooks"
+   }
+]
+
+/* 下次课程信息 */
+const classData = ref<Record<string, any>>({})
+const classDataLoading = ref(true)
+const isEmptyClassData = computed(() => {
+   return !Object.keys(classData.value).length
+})
+handleClassData()
+function handleClassData() {
+   if (userStoreHook.roles === "GYM") {
+      classDataLoading.value = true
+      httpAjax(getRecentCourseSchedule_gym).then(res => {
+         classDataLoading.value = false
+         if (res.code === 200) {
+            classData.value = res.data || {}
+         }
+      })
+   } else {
+      classDataLoading.value = true
+      httpAjax(getRemind_gyt).then(res => {
+         classDataLoading.value = false
+         if (res.code === 200) {
+            classData.value = res.data || {}
+         }
+      })
+   }
+}
+
+function handleRouter(url?: string) {
+   url
+      ? router.push(url)
+      : useDialogConfirm({
+           headImg: require("@/img/homePage/ts.png"),
+           text: "该功能暂未开放,请敬请期待哦~",
+           btnShow: [true]
+        })
+}
+function handleRouterCurriculum() {
+   router.push({
+      path: "/curriculum",
+      query: {
+         date: classData.value.classDate ? format(classData.value.classDate) : ""
+      }
+   })
+}
+</script>
+<style lang="scss" scoped>
+.homePageNav.navContainer {
+   &:deep(.navCon) {
+      .navImg {
+         margin-left: 50px;
+         > img {
+            width: 91px;
+            height: 92px;
+            top: 70%;
+         }
+      }
+      .nav {
+         font-size: 28px;
+         font-family: AlimamaFangYuanTiVF, AlimamaFangYuanTiVF;
+         &:last-child {
+            margin-right: 30px;
+         }
+      }
+   }
+}
+.homePage {
+   width: 100%;
+   height: 100%;
+   & > :deep(.elScrollbar) {
+      .el-scrollbar__view {
+         width: 100%;
+         display: flex;
+         padding: 50px 50px 0;
+      }
+      .el-scrollbar__wrap {
+         overflow-x: hidden;
+      }
+   }
+   .classTypes {
+      flex-grow: 1;
+      display: flex;
+      flex-wrap: wrap;
+      justify-content: space-between;
+      height: 729px;
+      align-content: space-between;
+      .classType {
+         background: #feffff;
+         box-shadow: 0px 2px 14px 0 #f1e3cc;
+         border-radius: 34px;
+         width: 360px;
+         height: 350px;
+         display: flex;
+         justify-content: center;
+         align-items: center;
+         flex-direction: column;
+         cursor: pointer;
+         padding: 44px 53px;
+         &:hover {
+            transform: scale(1.02);
+            box-shadow: 0px 2px 14px 0px #e4d7c2;
+         }
+         > div {
+            margin-top: 10px;
+            font-family: AlimamaFangYuanTiVF, AlimamaFangYuanTiVF;
+            font-weight: bold;
+            font-size: 28px;
+            color: #393939;
+         }
+         > img {
+            width: 100%;
+         }
+      }
+   }
+   .courseBoard {
+      flex-shrink: 0;
+      margin-left: 50px;
+      margin-top: -35px;
+      width: 572px;
+      height: 764px;
+      background: url("@/img/homePage/bg1.png") no-repeat;
+      background-size: 100% 100%;
+      position: relative;
+      &.isEmpty {
+         background: url("@/img/homePage/bg.png") no-repeat;
+         background-size: 100% 100%;
+      }
+      .details {
+         width: 100%;
+         position: absolute;
+         top: 88px;
+         left: 0;
+         padding: 0 30px;
+         .head {
+            height: 81px;
+            display: flex;
+            justify-content: space-between;
+            align-items: center;
+            padding: 0 30px;
+            .leftCon {
+               display: flex;
+               align-items: center;
+               .line {
+                  width: 8px;
+                  height: 28px;
+                  background: linear-gradient(180deg, #ffcb35 0%, #fea60a 100%), #ff6a67;
+                  border-radius: 7px;
+               }
+               .title {
+                  margin-left: 12px;
+                  font-family: AlimamaFangYuanTiVF, AlimamaFangYuanTiVF;
+                  font-weight: bold;
+                  font-size: 28px;
+                  color: #994d1c;
+               }
+            }
+            .rightRouter {
+               width: 38px;
+               height: 38px;
+               cursor: pointer;
+               &:hover {
+                  opacity: $opacity-hover;
+               }
+            }
+         }
+         .elSkeleton {
+            padding: 0 30px;
+            display: flex;
+            flex-direction: column;
+            align-items: center;
+            > .elSkeletonItem {
+               &:nth-child(1) {
+                  margin-top: 25px;
+                  height: 34px;
+               }
+               &:nth-child(2) {
+                  width: 50%;
+                  margin-top: 58px;
+                  height: 60px;
+               }
+               &:nth-child(3) {
+                  margin-top: 34px;
+               }
+               &:nth-child(4) {
+                  margin-top: 34px;
+               }
+               &:nth-child(6) {
+                  width: 100%;
+                  height: 74px;
+                  margin-top: 58px;
+               }
+            }
+            .elSkeletonBtnCon {
+               width: 100%;
+               margin-top: 76px;
+               display: flex;
+               justify-content: space-between;
+               > .elSkeletonItem {
+                  width: 216px;
+                  height: 65px;
+               }
+            }
+         }
+         :deep(.empty) {
+            margin-top: 114px;
+            padding: 0;
+            .el-empty__image {
+               width: 360px;
+            }
+         }
+      }
+   }
+}
+</style>