feat: 动效初始化
parent
1c26b8d4ad
commit
426e7f789b
File diff suppressed because one or more lines are too long
@ -0,0 +1,3 @@
|
|||||||
|
import AnimateDevice from "./src/AnimateDevice.vue";
|
||||||
|
|
||||||
|
export { AnimateDevice };
|
@ -0,0 +1,38 @@
|
|||||||
|
<!--
|
||||||
|
* @Author: donghao donghao@supervision.ltd
|
||||||
|
* @Date: 2024-01-16 13:49:37
|
||||||
|
* @LastEditors: donghao donghao@supervision.ltd
|
||||||
|
* @LastEditTime: 2024-01-16 13:53:47
|
||||||
|
* @FilePath: \General-AI-Platform-Web-Client\src\components\Animate\src\animateDevice.vue
|
||||||
|
* @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
|
||||||
|
-->
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, onMounted } from "vue"; //引入相关api
|
||||||
|
import lottie from "lottie-web"; //引入动效库
|
||||||
|
import json01 from "@/assets/animate/device/01.json"; //引入下载的动效json
|
||||||
|
|
||||||
|
defineOptions({
|
||||||
|
name: "AnimateDevice"
|
||||||
|
});
|
||||||
|
|
||||||
|
const animation1 = ref(null); //获取dom
|
||||||
|
function initAnimate() {
|
||||||
|
console.log(lottie, "lottie");
|
||||||
|
lottie.loadAnimation({
|
||||||
|
container: animation1.value, //选择渲染dom
|
||||||
|
renderer: "svg", //渲染格式
|
||||||
|
loop: true, //循环播放
|
||||||
|
autoplay: true, //是否i自动播放,
|
||||||
|
animationData: json01 //渲染动效json
|
||||||
|
});
|
||||||
|
}
|
||||||
|
onMounted(() => {
|
||||||
|
initAnimate();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div style="width: 100px">
|
||||||
|
<div ref="animation1" />
|
||||||
|
</div>
|
||||||
|
</template>
|
@ -0,0 +1,472 @@
|
|||||||
|
<template>
|
||||||
|
<div class="courseCat_wrap courseLession_wrap" v-if="pageMode == 'courseCat'">
|
||||||
|
<van-sticky>
|
||||||
|
<div class="bg-white title_box">
|
||||||
|
<p class=" fs18 fw5 text_color title_centent flex-rb flex-ac">
|
||||||
|
{{ detailInfo.name }}
|
||||||
|
</p>
|
||||||
|
<p class="fs12 text-gray progress_box">
|
||||||
|
已学习<span class="theme_color">{{ totalLesson.learnedCount }}</span
|
||||||
|
>节/共{{ totalLesson.totalCount }}节
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<HTab
|
||||||
|
ref="HTabComp"
|
||||||
|
class="bg-white"
|
||||||
|
:options="csTabOptions"
|
||||||
|
:tabList="tabOptions"
|
||||||
|
@change="menuChange"
|
||||||
|
>
|
||||||
|
</HTab>
|
||||||
|
</van-sticky>
|
||||||
|
|
||||||
|
<div class="catalogTree fs14" ref="CSCatTreeRefs">
|
||||||
|
<ul class="bg-white root_cat_box pdx15">
|
||||||
|
<li v-for="(v, index) in state.courseTreeData" :key="v.id">
|
||||||
|
<div
|
||||||
|
class="chapter_box flex-ac flex-rb"
|
||||||
|
v-if="v.type == 0"
|
||||||
|
@click="handleExpend(v)"
|
||||||
|
>
|
||||||
|
<span class="chapter_label fw5 single-line">
|
||||||
|
{{ v.name }}
|
||||||
|
</span>
|
||||||
|
<div class="collapseIcon_box flex-cc">
|
||||||
|
<div class="arrow" :class="v.expended ? '' : 'activeUp'"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="courseware_box" v-if="v.type == 2">
|
||||||
|
<!-- 课 -->
|
||||||
|
<CSLessonsBox
|
||||||
|
:lessonDownProgress="lessonDownProgress"
|
||||||
|
:info="v"
|
||||||
|
:courseDetail="detailInfo"
|
||||||
|
:lessonStudyProgress="lessonStudyProgress"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="section_box flex-ac flex-rb" v-if="v.type == 1">
|
||||||
|
<span>{{ v.name }}</span>
|
||||||
|
</div>
|
||||||
|
<transition name="mybox">
|
||||||
|
<div class="box" v-show="v.expended">
|
||||||
|
<ul v-if="isArray(v.childrenList) && v.childrenList.length">
|
||||||
|
<li v-for="(item, index) in [...v.childrenList]" :key="item.id">
|
||||||
|
<CSLessonsBox
|
||||||
|
:info="item"
|
||||||
|
:courseDetail="detailInfo"
|
||||||
|
:lessonDownProgress="lessonDownProgress"
|
||||||
|
:lessonStudyProgress="lessonStudyProgress"
|
||||||
|
/>
|
||||||
|
<hr
|
||||||
|
class="mdy20"
|
||||||
|
v-if="index !== [...v.childrenList].length - 1"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<CSLessonPracticeBox
|
||||||
|
:info="v.coursePaperVOS"
|
||||||
|
:courseInfo="v"
|
||||||
|
:courseDetail="detailInfo"
|
||||||
|
v-if="
|
||||||
|
v.type == 0 &&
|
||||||
|
isArray(v.coursePaperVOS) &&
|
||||||
|
v.coursePaperVOS.length &&
|
||||||
|
v.coursePaperVOS != ['']
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</transition>
|
||||||
|
</li>
|
||||||
|
<li v-for="v in practiceList" :key="v.id" class="bg-white exam_box">
|
||||||
|
<p
|
||||||
|
class="fs14 pdy12"
|
||||||
|
v-if="v.type == 0 && detailInfo.joinStatus >= 1"
|
||||||
|
>
|
||||||
|
课后练习
|
||||||
|
</p>
|
||||||
|
<div
|
||||||
|
class="flex pdy12"
|
||||||
|
v-if="v.type == 0 && detailInfo.joinStatus >= 1"
|
||||||
|
>
|
||||||
|
<span class="flex-cc exam_tag fs10">
|
||||||
|
<span class="exam_tag_icon"></span>
|
||||||
|
<span class="fss10">练习</span>
|
||||||
|
</span>
|
||||||
|
<div class="exam_title">
|
||||||
|
<p class="paperName_label fw5 single-line">
|
||||||
|
{{ v.paperName }}
|
||||||
|
</p>
|
||||||
|
<div class="flex-rb exam_status fs12 theme_color">
|
||||||
|
<span class=" single-line" v-if="v.status == 0">
|
||||||
|
未开始
|
||||||
|
</span>
|
||||||
|
<span class=" single-line paper_name" v-if="v.status == 1">
|
||||||
|
<span v-if="v.pass">已通过</span>
|
||||||
|
<span v-else>未通过</span>
|
||||||
|
</span>
|
||||||
|
<span
|
||||||
|
:class="[`${fetchDetailCatBtn(v).statusType}_tags`]"
|
||||||
|
@click="doTabCoursePractice(v, {...detailInfo})"
|
||||||
|
>
|
||||||
|
{{ fetchDetailCatBtn(v).practiceLabel }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<HEmpty v-if="!state.courseTreeData.length && !isLoading" />
|
||||||
|
<div ref="CSDetailCommentRefs">
|
||||||
|
<CSDetailComment
|
||||||
|
ref="detailCommentRefs"
|
||||||
|
:info="detailInfo"
|
||||||
|
:courseConf="courseConf"
|
||||||
|
@tenantComment="doTenantComment"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- {{ pageMode }} -->
|
||||||
|
<div v-if="pageMode == 'courseDot'">
|
||||||
|
<CSLessonPoint
|
||||||
|
ref="CSLessonPointRefs"
|
||||||
|
:stepData="pointData"
|
||||||
|
@closeDot="openCat"
|
||||||
|
@dotTab="doDotTab"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<!-- 评论 -->
|
||||||
|
<CComment
|
||||||
|
ref="commentRefs"
|
||||||
|
:ocInfo="courseConf"
|
||||||
|
:isNeedClose="true"
|
||||||
|
@successComment="successComment"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
reactive,
|
||||||
|
nextTick,
|
||||||
|
computed,
|
||||||
|
ref,
|
||||||
|
onMounted,
|
||||||
|
onActivated,
|
||||||
|
getCurrentInstance,
|
||||||
|
} from "vue";
|
||||||
|
import { useRouter, useRoute } from "vue-router";
|
||||||
|
//
|
||||||
|
// 组件区
|
||||||
|
import {
|
||||||
|
CSLessonsBox,
|
||||||
|
CSLessonPracticeBox,
|
||||||
|
CSDetailComment,
|
||||||
|
CSLessonPoint,
|
||||||
|
} from "../components";
|
||||||
|
import { HTab, HEmpty } from "@/components/HVant/index";
|
||||||
|
import { CComment } from "@/components/common";
|
||||||
|
// hooks
|
||||||
|
import { clientChangeVideo, clientChangeVideoDot } from "@/hooks/web/useClientFc"
|
||||||
|
import { useWebFunc } from "@/hooks/web/useWebFunc";
|
||||||
|
import { useCourseCat } from "../hooks/useCourseCat";
|
||||||
|
import { useCourseDetail } from "../hooks/useCourseDetail";
|
||||||
|
import { useConf, useReqApi, useCourseMain } from "../hooks/useMain";
|
||||||
|
import {
|
||||||
|
fetchNextCoursewareNode,
|
||||||
|
fetchCurrentCourseNode,
|
||||||
|
} from "../hooks/format";
|
||||||
|
// 其它
|
||||||
|
import { isArray } from "@/utils/is/isString";
|
||||||
|
//数据
|
||||||
|
import { testFlag } from "../hooks/test";
|
||||||
|
import { testData } from "@/testData/courseDot";
|
||||||
|
const { appContext } = getCurrentInstance();
|
||||||
|
const route = useRoute();
|
||||||
|
const router = useRouter();
|
||||||
|
const {
|
||||||
|
getCourseCatalogApi,
|
||||||
|
getCourseInfoApi,
|
||||||
|
updateLastLearnCatalogIdCourseApi,
|
||||||
|
getCourseProgressApi,
|
||||||
|
} = useReqApi;
|
||||||
|
const { courseVideoDetailTabConf } = useConf;
|
||||||
|
|
||||||
|
const {
|
||||||
|
doTabExam,
|
||||||
|
clientCourseCatPracticeAlertView,
|
||||||
|
doLoadCoursePractice,
|
||||||
|
practiceList,
|
||||||
|
doTabCoursePractice
|
||||||
|
} = useCourseCat();
|
||||||
|
const { setWebFunc } = useWebFunc();
|
||||||
|
const { fetchDetailCatBtn } = useCourseDetail();
|
||||||
|
|
||||||
|
// 初始值
|
||||||
|
const lessonDownProgress = ref({}); // 课件下载进度
|
||||||
|
const courseRecordInfo = ref({
|
||||||
|
totalProgress: 0,
|
||||||
|
}); // 课程端数据汇总
|
||||||
|
const lessonStudyProgress = ref({}); // 课件学习进度
|
||||||
|
const totalLesson = ref({
|
||||||
|
learnedCount: 0,
|
||||||
|
totalCount: 0,
|
||||||
|
});
|
||||||
|
|
||||||
|
const state = reactive({
|
||||||
|
currMenuIndex: 0,
|
||||||
|
activeLesson: [],
|
||||||
|
courseListOptions: {
|
||||||
|
// isCustom: true
|
||||||
|
},
|
||||||
|
courseTreeData: [], //courseCatData
|
||||||
|
});
|
||||||
|
const detailInfo = ref({});
|
||||||
|
const pageMode = ref("courseCat");
|
||||||
|
const isLoading = ref(false);
|
||||||
|
const courseConf = reactive({
|
||||||
|
operationType: 0,
|
||||||
|
});
|
||||||
|
const csTabOptions = reactive({
|
||||||
|
defaultValue: 0,
|
||||||
|
});
|
||||||
|
const tabOptions = computed(() => {
|
||||||
|
return courseVideoDetailTabConf.filter((item) => {
|
||||||
|
if (item.id === "1") {
|
||||||
|
item.name = `评论(${detailInfo.value.commentCount || 0})`;
|
||||||
|
}
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
const pointData = ref([]); // 知识点
|
||||||
|
const currentCatData = ref({}); // 当前学习目录项
|
||||||
|
// 实例
|
||||||
|
const CSCatTreeRefs = ref("");
|
||||||
|
const CSDetailCommentRefs = ref("");
|
||||||
|
const commentRefs = ref("");
|
||||||
|
const detailCommentRefs = ref("");
|
||||||
|
const CSLessonPointRefs = ref("");
|
||||||
|
|
||||||
|
/**step1 目录、评论模块切换 */
|
||||||
|
function menuChange(record) {
|
||||||
|
state.currMenuIndex = record;
|
||||||
|
nextTick(() => {
|
||||||
|
switch (record) {
|
||||||
|
case "0":
|
||||||
|
window.scrollTo(
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
case "1":
|
||||||
|
// CSDetailCommentRefs.value.scrollIntoView({
|
||||||
|
// behavior: "smooth",
|
||||||
|
// });
|
||||||
|
window.scrollTo(
|
||||||
|
0,
|
||||||
|
CSDetailCommentRefs.value.offsetTop - CSCatTreeRefs.value.offsetTop
|
||||||
|
);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**step2 目录详情数据 评论数据 推荐课程数据*/
|
||||||
|
// 目录数据
|
||||||
|
async function loadCatData(nextCat, nextCatId) {
|
||||||
|
isLoading.value = true;
|
||||||
|
const res = await getCourseCatalogApi({ id: route.query.id }).finally(() => {
|
||||||
|
isLoading.value = false;
|
||||||
|
});
|
||||||
|
// console.log(res, "loadCatData");
|
||||||
|
if (isArray(res)) {
|
||||||
|
state.courseTreeData = res.filter((item) => {
|
||||||
|
item.expended = true;
|
||||||
|
return item;
|
||||||
|
});
|
||||||
|
if (nextCatId) {
|
||||||
|
// 下一课已经解锁 广播下一节点id
|
||||||
|
let params = {
|
||||||
|
...nextCat,
|
||||||
|
courseTrainId: route.query.id,
|
||||||
|
};
|
||||||
|
appContext.config.globalProperties.Bus.emit(
|
||||||
|
"changeCurrentCatId",
|
||||||
|
nextCatId
|
||||||
|
);
|
||||||
|
clientChangeVideo(params, (_) => {});
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
state.courseTreeData = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**step3 目录交互完善 展开收起 对接端 */
|
||||||
|
//收起/展开
|
||||||
|
function handleExpend(record) {
|
||||||
|
record.expended = !record.expended;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**step4 other */
|
||||||
|
// 关闭知识点-打开目录
|
||||||
|
function openKnowledge() {
|
||||||
|
if (testFlag.isOpenDot) {
|
||||||
|
pointData.value = testData;
|
||||||
|
openDot();
|
||||||
|
} else {
|
||||||
|
setWebFunc("webOpenKnowledge", (res) => {
|
||||||
|
pointData.value = JSON.parse(res);
|
||||||
|
console.info("pointData", pointData.value);
|
||||||
|
openDot();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 从端获取下载进度
|
||||||
|
function fetchDownloadProgress() {
|
||||||
|
setWebFunc("changeDownloadProgress", (res) => {
|
||||||
|
lessonDownProgress.value = res;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 从端获取学习进度
|
||||||
|
function fetchStudyProgress() {
|
||||||
|
setWebFunc("changeStudyProgress", (res) => {
|
||||||
|
// console.log(res, "changeStudyProgress");
|
||||||
|
lessonStudyProgress.value = res.studyCourseware;
|
||||||
|
courseRecordInfo.value = res;
|
||||||
|
// // 播报课程总进度
|
||||||
|
lessonStudyProgress.value.learningProgress>=1 && loadCourseProgress()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// 从接口获取学习进度 获取总进度
|
||||||
|
async function loadCourseProgress() {
|
||||||
|
const res = await getCourseProgressApi({ id: route.query.id });
|
||||||
|
// console.log(res, "loadCourseProgress_res");
|
||||||
|
totalLesson.value = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 完成本节播放,后续处理 (练习提醒、下一节自动切换) completeStatus 练习完成状态
|
||||||
|
function webFnPlayNextVideo() {
|
||||||
|
setWebFunc("playNextVideo", (res) => {
|
||||||
|
const currentCat = fetchCurrentCourseNode(
|
||||||
|
state.courseTreeData,
|
||||||
|
res.catalogId
|
||||||
|
);
|
||||||
|
// 播报课程总进度
|
||||||
|
loadCourseProgress();
|
||||||
|
console.log("currentCat_coursePaperVOS", currentCat);
|
||||||
|
// 确认是练习提醒还是进入下一节
|
||||||
|
if (
|
||||||
|
currentCat.coursePaperVOS &&
|
||||||
|
(![1, 2].includes(currentCat.coursePaperVOS?.status) ||
|
||||||
|
![1].includes(currentCat?.completeStatus))
|
||||||
|
) {
|
||||||
|
// 课节练习提醒 练习提醒 课程状态处理 completeStatus 0 未完成 2 音视频完成 1 全部完成含练习
|
||||||
|
currentCatData.value = {
|
||||||
|
...currentCat,
|
||||||
|
coursePracticeType: "coursewarePractice",
|
||||||
|
};
|
||||||
|
clientCourseCatPracticeAlertView({}, () => {
|
||||||
|
const { coursePaperVOS } = currentCatData.value;
|
||||||
|
doTabExam(coursePaperVOS[0]);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
// 直接跳下一节课
|
||||||
|
fetchNextCourse(res);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 判断当前课是否有练习
|
||||||
|
function fetchNextCourse(res) {
|
||||||
|
// 弹下一课提醒
|
||||||
|
const nextCat = fetchNextCoursewareNode(state.courseTreeData, res.catalogId);
|
||||||
|
const nextCatId = nextCat.id;
|
||||||
|
//有下一课, 自动播放下一课,没有不处理
|
||||||
|
if (nextCatId != res.catalogId) {
|
||||||
|
updateChangeLessonApi(nextCatId);
|
||||||
|
loadCatData(nextCat, nextCatId);
|
||||||
|
} else {
|
||||||
|
// 广播下一节点id
|
||||||
|
// appContext.config.globalProperties.Bus.emit("changeCurrentCatId", nextCatId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 汇报上次学到的课
|
||||||
|
function updateChangeLessonApi(nextCatId) {
|
||||||
|
updateLastLearnCatalogIdCourseApi({
|
||||||
|
courseCatalogId: nextCatId,
|
||||||
|
resourceId: route.query.id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开目录
|
||||||
|
function openCat() {
|
||||||
|
pageMode.value = "courseCat";
|
||||||
|
}
|
||||||
|
// 打开知识点
|
||||||
|
function openDot() {
|
||||||
|
pageMode.value = "courseDot";
|
||||||
|
}
|
||||||
|
// 切换知识点
|
||||||
|
function doDotTab(params) {
|
||||||
|
clientChangeVideoDot(params, (res) => {
|
||||||
|
if (res == 1) {
|
||||||
|
CSLessonPointRefs.value.initChangePoint();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadDetail() {
|
||||||
|
nextTick(() => {
|
||||||
|
detailCommentRefs.value.initData();
|
||||||
|
});
|
||||||
|
if (isLoading.value) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
doLoadData();
|
||||||
|
loadCatData();
|
||||||
|
doLoadCoursePractice();
|
||||||
|
loadCourseProgress();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 详情数据
|
||||||
|
async function doLoadData() {
|
||||||
|
const res = await getCourseInfoApi({
|
||||||
|
id: Number(route.query.id),
|
||||||
|
});
|
||||||
|
detailInfo.value = res;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadWebFunc() {
|
||||||
|
openKnowledge();
|
||||||
|
fetchDownloadProgress();
|
||||||
|
fetchStudyProgress();
|
||||||
|
webFnPlayNextVideo();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 打开评论
|
||||||
|
function doTenantComment() {
|
||||||
|
commentRefs.value.initPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 评论成功
|
||||||
|
function successComment() {
|
||||||
|
loadDetail();
|
||||||
|
}
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
loadWebFunc();
|
||||||
|
loadDetail();
|
||||||
|
});
|
||||||
|
|
||||||
|
onActivated(() => {
|
||||||
|
loadDetail();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
@import url("../style/courseCat.less");
|
||||||
|
@import url("../style/courseDetail.less");
|
||||||
|
</style>
|
@ -0,0 +1,347 @@
|
|||||||
|
<template>
|
||||||
|
<div class="course_lessonsBox fs14 text_1">
|
||||||
|
<!-- 节 -->
|
||||||
|
<div class="section_box flex-ac flex-rb" v-if="catLatestInfo.type == 1">
|
||||||
|
<span>{{ catLatestInfo.name }}</span>
|
||||||
|
</div>
|
||||||
|
<!-- 课 -->
|
||||||
|
<!-- filter_gray -->
|
||||||
|
<div class="lesson_box flex-rb" :class="{'filter_gray': fetchIsNoneEffect(catLatestInfo)}" v-if="catLatestInfo.type == 2" @click="handelTab">
|
||||||
|
<div class="flex-re">
|
||||||
|
<span class="lesson_tag courseCat_tag theme_color flex-cc fs10">
|
||||||
|
<span class="icon_cat" :class="activeClass(catLatestInfo).iconClass"></span>
|
||||||
|
<span class="fss10">{{ activeClass(catLatestInfo).label }}</span>
|
||||||
|
</span>
|
||||||
|
<!-- 课件内容 -->
|
||||||
|
<div class="lesson_content_box">
|
||||||
|
<div class="flex cat_title_box">
|
||||||
|
<p class="lesson_infoName text_2 flex-wr">{{ catLatestInfo.name }}</p>
|
||||||
|
<span class="fss11" v-if="currentCatId == catLatestInfo.id">正在学</span>
|
||||||
|
<span class="fss11" v-if="!currentCatId && catLatestInfo.lastLearn"
|
||||||
|
>上次学到</span
|
||||||
|
>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="course_status_box text_3">
|
||||||
|
<csLessonStatus
|
||||||
|
:isLock="currentIsLock"
|
||||||
|
:courseInfo="catLatestInfo"
|
||||||
|
:courseDetail="courseDetail"
|
||||||
|
:lessonStudyProgress="lessonStudyProgress"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div @click.stop="doDownLoadEvent()">
|
||||||
|
<!-- 课件下载 -->
|
||||||
|
<div
|
||||||
|
class="flex-cc lesson_down"
|
||||||
|
v-if="currentIsLock == 0 && [3, 4].includes(catLatestInfo.courseType)"
|
||||||
|
|
||||||
|
>
|
||||||
|
<!-- 下载进度为0 -->
|
||||||
|
<span v-if="courseDetail.joinStatus < 1"></span>
|
||||||
|
<!-- @click.stop="doDownLoad" -->
|
||||||
|
<span
|
||||||
|
class="lesson_down_icon"
|
||||||
|
v-else-if="downloadProgress == 0"
|
||||||
|
></span>
|
||||||
|
<!-- 正在下载 | 暂停 -->
|
||||||
|
<div
|
||||||
|
class="tc"
|
||||||
|
v-else-if="downloadProgress < 100 && downloadProgress > 0"
|
||||||
|
>
|
||||||
|
<!-- @click.stop="changeDownLoadMode" -->
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="lesson_down_loading_icon"
|
||||||
|
:class="isDownload ? 'downloadPause' : 'downLoading'"
|
||||||
|
></span>
|
||||||
|
<p class="w-8 fss11 theme_color">下载 {{ downloadProgress }} %</p>
|
||||||
|
</div>
|
||||||
|
<!-- <div v-if="!isDownload" @click.stop="doDownLoad">
|
||||||
|
<span class="lesson_down_loading_icon"></span>
|
||||||
|
<p class="fss11 theme_color">已暂停</p>
|
||||||
|
</div> -->
|
||||||
|
</div>
|
||||||
|
<!-- 下载完成 -->
|
||||||
|
<span v-else class="theme_color">已下载</span>
|
||||||
|
</div>
|
||||||
|
<div class="flex-cc noeffect_box" v-if="fetchIsNoneEffect(info)">
|
||||||
|
<div class="icon_noEffect"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ul>
|
||||||
|
<li v-for="v in catLatestInfo.childrenList">
|
||||||
|
<courseLessonsBox
|
||||||
|
:info="v"
|
||||||
|
:courseDetail="courseDetail"
|
||||||
|
color="#21CC64"
|
||||||
|
:lessonDownProgress="lessonDownProgress"
|
||||||
|
:lessonStudyProgress="lessonStudyProgress"
|
||||||
|
/>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
<csLessonPracticeBox
|
||||||
|
:info="catLatestInfo.coursePaperVOS"
|
||||||
|
:courseInfo="info"
|
||||||
|
v-if="
|
||||||
|
catLatestInfo.type == 1 &&
|
||||||
|
isArray(catLatestInfo.coursePaperVOS) &&
|
||||||
|
catLatestInfo.coursePaperVOS.length &&
|
||||||
|
catLatestInfo.coursePaperVOS != ['']
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {
|
||||||
|
defineComponent,
|
||||||
|
ref,
|
||||||
|
nextTick,
|
||||||
|
getCurrentInstance,
|
||||||
|
onMounted,
|
||||||
|
watch,
|
||||||
|
computed,
|
||||||
|
} from "vue";
|
||||||
|
import { useRouter, useRoute } from "vue-router";
|
||||||
|
// 组件
|
||||||
|
import csLessonStatus from "./csLessonStatus.vue";
|
||||||
|
import csLessonPracticeBox from "./csLessonPracticeBox.vue";
|
||||||
|
// hooks
|
||||||
|
import { clientChangeVideo, clientDownloadVideo, clientMediaDownloadProgress,
|
||||||
|
clientCancelDownloadMedia } from "@/hooks/web/useClientFc"
|
||||||
|
import { formatIsUnLock } from "@/hooks/format/comm";
|
||||||
|
import { useCourseMain, useReqApi } from "../hooks/useMain";
|
||||||
|
import { useCourseDetail } from "../hooks/useCourseDetail";
|
||||||
|
import { debounceFun } from "@/hooks/core/useLodash.js";
|
||||||
|
import {globalDebounceTime} from "@/config/settingConfig/core.js"
|
||||||
|
|
||||||
|
//方法
|
||||||
|
import { isArray } from "@/utils/is/isString";
|
||||||
|
const { appContext } = getCurrentInstance();
|
||||||
|
const {
|
||||||
|
activeClass
|
||||||
|
} = useCourseMain();
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
info: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {
|
||||||
|
id: "",
|
||||||
|
name: "",
|
||||||
|
childrenList: [],
|
||||||
|
isLastLearnCatalog: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
courseDetail: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
lessonDownProgress: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
lessonStudyProgress: {
|
||||||
|
type: Object,
|
||||||
|
default() {
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
defineComponent({ name: "courseLessonsBox" });
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
const route = useRoute();
|
||||||
|
const currentCatId = ref(""); // 课件目录id (正在学)
|
||||||
|
const currentDownloadCatId = ref(""); // 课件目录id (下载)
|
||||||
|
const { fetchCourseTipByRecord , fetchIsNoneEffect} = useCourseDetail();
|
||||||
|
const { updateLastLearnCatalogIdCourseApi } = useReqApi;
|
||||||
|
|
||||||
|
const isDownload = ref(true); //控制下载课件的暂停
|
||||||
|
const currCatFullData = ref({}); //当前目录课节更新所有数据
|
||||||
|
|
||||||
|
const catLatestInfo = computed(() => { //实时的课程目录课件数据
|
||||||
|
return {...props.info ,...currCatFullData.value}
|
||||||
|
})
|
||||||
|
// 下载进度
|
||||||
|
const downloadProgress = ref(0);
|
||||||
|
// const currentIsLock = ref(1);
|
||||||
|
const currentIsLock = computed(()=>{
|
||||||
|
return props.info?.isLock
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
// 跳转播放视频
|
||||||
|
const handelTab =
|
||||||
|
debounceFun(function() {
|
||||||
|
console.log('debounceFun_handelTab')
|
||||||
|
if(fetchIsNoneEffect(props.info)){ // 课节已失效
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(props.info.id == currentCatId.value){ // 相同目录事件不处理
|
||||||
|
return
|
||||||
|
}
|
||||||
|
updateChangeLessonApi();
|
||||||
|
}, globalDebounceTime);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// 汇报上次学到的课 拿到当前实时的返回进度
|
||||||
|
async function updateChangeLessonApi() {
|
||||||
|
const resData = await updateLastLearnCatalogIdCourseApi({
|
||||||
|
courseCatalogId: props.info.id,
|
||||||
|
resourceId: route.query.id,
|
||||||
|
});
|
||||||
|
let params = {
|
||||||
|
...props.info,
|
||||||
|
courseTrainId: route.query.id,
|
||||||
|
};
|
||||||
|
if(resData){
|
||||||
|
params = {...params, ...resData.data}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (formatIsUnLock({ ...params })) {
|
||||||
|
currCatFullData.value = params // 本课节接口数据更新
|
||||||
|
appContext.config.globalProperties.Bus.emit(
|
||||||
|
"changeCurrentCatId",
|
||||||
|
props.info.id
|
||||||
|
);
|
||||||
|
//判断是否有锁
|
||||||
|
clientChangeVideo(params, (res) => {});
|
||||||
|
} else {
|
||||||
|
// 报名、锁状态提示
|
||||||
|
fetchCourseTipByRecord(props.courseDetail, "课件");
|
||||||
|
}
|
||||||
|
console.log(params, "updateChangeLessonApi");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载相关
|
||||||
|
function doDownLoadEvent() {
|
||||||
|
if(currentIsLock.value == 0 && [3, 4].includes(catLatestInfo.value?.courseType)){
|
||||||
|
if(props.courseDetail.joinStatus < 1){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(downloadProgress.value == 0){
|
||||||
|
doDownLoad()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if(downloadProgress.value < 100 && downloadProgress.value > 0){
|
||||||
|
changeDownLoadMode()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// 下载课件
|
||||||
|
const doDownLoad = debounceFun(function() {
|
||||||
|
if(fetchIsNoneEffect(props.info)){
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let params = {
|
||||||
|
...props.info,
|
||||||
|
courseTrainId: route.query.id,
|
||||||
|
};
|
||||||
|
currentDownloadCatId.value = props.info.id;
|
||||||
|
console.log(params, "clientDownloadVideo");
|
||||||
|
clientDownloadVideo(params, (res) => {});
|
||||||
|
}, globalDebounceTime);
|
||||||
|
|
||||||
|
//停止下载正在下载的课件
|
||||||
|
const changeDownLoadMode = debounceFun(function() {
|
||||||
|
let params = {
|
||||||
|
...props.info,
|
||||||
|
courseTrainId: route.query.id,
|
||||||
|
};
|
||||||
|
currentDownloadCatId.value = props.info.id;
|
||||||
|
console.log(params, "clientCancelDownloadMedia");
|
||||||
|
if (isDownload.value) {
|
||||||
|
doDownLoad();
|
||||||
|
} else {
|
||||||
|
clientCancelDownloadMedia(params, (res) => {});
|
||||||
|
}
|
||||||
|
changeIsDownload();
|
||||||
|
}, globalDebounceTime);
|
||||||
|
|
||||||
|
// 切换暂停 | 继续 下载模式
|
||||||
|
function changeIsDownload() {
|
||||||
|
isDownload.value = !isDownload.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
function initChangeDownloadProgress() {
|
||||||
|
console.log(
|
||||||
|
props.info.id,
|
||||||
|
props.lessonDownProgress,
|
||||||
|
"initChangeDownloadProgress"
|
||||||
|
);
|
||||||
|
const { progress } = props.lessonDownProgress;
|
||||||
|
fetchDownloadProgressVal(progress);
|
||||||
|
}
|
||||||
|
|
||||||
|
function fetchDownloadProgressVal(progress) {
|
||||||
|
let currProgress = Math.floor(100 * progress);
|
||||||
|
if (currProgress <= 0) {
|
||||||
|
currProgress = 0;
|
||||||
|
}
|
||||||
|
if (currProgress >= 100) {
|
||||||
|
currProgress = 100;
|
||||||
|
isDownload.value = false;
|
||||||
|
}
|
||||||
|
downloadProgress.value = currProgress;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextTick(() => {
|
||||||
|
// if (props.info) {
|
||||||
|
// currentIsLock.value = props.info?.isLock;
|
||||||
|
// }
|
||||||
|
if (props.info.isLastLearnCatalog) {
|
||||||
|
currentCatId.value = props.info.id;
|
||||||
|
}
|
||||||
|
// console.log(props.info.lessonId, "isLastLearnCatalog");
|
||||||
|
appContext.config.globalProperties.Bus.on("changeCurrentCatId", (data) => {
|
||||||
|
console.log("接收到的内容是:" + data);
|
||||||
|
currentCatId.value = data;
|
||||||
|
// if(){
|
||||||
|
// currentIsLock.value = 0; //解锁
|
||||||
|
// }
|
||||||
|
});
|
||||||
|
if (props.info.type == 2) {
|
||||||
|
// 只有课才调用获取初始加载进度
|
||||||
|
clientMediaDownloadProgress(
|
||||||
|
{ ...props.info, courseTrainId: route.query.id },
|
||||||
|
(res) => {
|
||||||
|
// initChangeDownloadProgress(res)
|
||||||
|
isDownload.value = res?.progress > 0 && res?.progress < 1;
|
||||||
|
fetchDownloadProgressVal(res?.progress);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
watch(
|
||||||
|
() => props.lessonDownProgress,
|
||||||
|
() => {
|
||||||
|
if (props.lessonDownProgress.catalogId == props.info.id) {
|
||||||
|
initChangeDownloadProgress();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ deep: true }
|
||||||
|
);
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less">
|
||||||
|
@import url("../style/courseCat.less");
|
||||||
|
</style>
|
Loading…
Reference in New Issue