|
|
@@ -10,26 +10,26 @@
|
|
|
<coursewareComponent ref="coursewareComponent"></coursewareComponent>
|
|
|
</div>
|
|
|
<div class="right-max-big-box">
|
|
|
- <p class="title-p">{{learningData.data1}}</p>
|
|
|
- <div class="text-p" style="color:#666;">{{learningData.data2}}分钟丨{{learningData.data3}}学时丨{{learningData.data4}}积分</div>
|
|
|
- <div class="text-p">已学 {{learningData.data5}} / 总 {{learningData.data6}} 课件</div>
|
|
|
+ <p class="title-p">{{newData.courseName}}</p>
|
|
|
+ <div class="text-p" style="color:#666;">{{secondsToMinutes(newData.totalDuration)}}分钟丨{{newData.totalCreditHours}}学时丨{{newData.totalPoints}}积分</div>
|
|
|
+ <div class="text-p">已学 {{newData.learnedCoursewareCount}} / 总 {{newData.totalCoursewareCount}} 课件</div>
|
|
|
<div class="progress-box">
|
|
|
<p class="progress-title-box">学习进度</p>
|
|
|
<div class="progress-min-box">
|
|
|
- <el-progress :stroke-width="12" :percentage="learningData.data7"></el-progress>
|
|
|
+ <el-progress :stroke-width="12" :percentage="newData.coursewares[0].progress?newData.coursewares[0].progress:0"></el-progress>
|
|
|
</div>
|
|
|
</div>
|
|
|
<div class="learning-for-max-big-box scrollbar-box">
|
|
|
<div class="for-max-big-box"
|
|
|
- v-for="(item,index) in learningData.dataList" :key="index">
|
|
|
+ v-for="(item,index) in newData.coursewares" :key="index">
|
|
|
<div class="for-big-box" @click="checkLearningButton(index)"
|
|
|
:class="checkLearningIndex == index ?'check-for-box':''">
|
|
|
- <p>{{item.listData1}}</p>
|
|
|
- <p>已学习:{{formatTime(item.listData3)}} / {{formatTime(item.listData4)}}</p>
|
|
|
- <p :class="item.listData5 ==1 ?'colorA':''">{{item.listData5==1?'已学完':'未学完'}}</p>
|
|
|
+ <p>{{item.coursewareName}}</p>
|
|
|
+ <p>已学习:{{formatTime(item.learnedDuration)}} / {{formatTime(item.minLearningDuration)}}</p>
|
|
|
+ <p :class="item.learnStatus ==2 ?'colorA':''">{{item.learnStatus==2?'已学完':'未学完'}}</p>
|
|
|
</div>
|
|
|
<p class="for-button" @click="finishStudying(index)"
|
|
|
- v-if="item.listData5 == 0 && item.listData3 == item.listData4 && checkLearningIndex == index">
|
|
|
+ v-if="item.learnStatus != 2 && item.learnedDuration == item.minLearningDuration && checkLearningIndex == index">
|
|
|
若已完成学习,请点此确认
|
|
|
</p>
|
|
|
</div>
|
|
|
@@ -59,6 +59,10 @@
|
|
|
import CountdownTimer from '@/utils/timerUtils/CountdownTimer';
|
|
|
import { VerifySlider } from 'vue-verify-slider';
|
|
|
import coursewareComponent from "@/views/safetyEducationExaminationNew/components/coursewareComponent.vue";
|
|
|
+ import {
|
|
|
+ examUserCourseLearningCoursewareList,examUserCoursewareLearningReportProgress,
|
|
|
+ examUserCoursewareLearningConfirmCompletion,examUserCoursewareLearningRestart
|
|
|
+ } from "@/api/safetyEducationExaminationNew/index";
|
|
|
export default {
|
|
|
name: 'index',
|
|
|
components: {
|
|
|
@@ -67,78 +71,80 @@
|
|
|
},
|
|
|
data() {
|
|
|
return {
|
|
|
- learningData:{
|
|
|
- data1:"课程名称",
|
|
|
- data2:"20",
|
|
|
- data3:"1",
|
|
|
- data4:"3",
|
|
|
- data5:"0",
|
|
|
- data6:"2",
|
|
|
- data7:20,
|
|
|
- dataList:[
|
|
|
+ examId:null,
|
|
|
+ courseId:null,
|
|
|
+ newData:{
|
|
|
+ courseName:"",
|
|
|
+ totalDuration:0,
|
|
|
+ totalCreditHours:0,
|
|
|
+ totalPoints:0,
|
|
|
+ learnedCoursewareCount:0,
|
|
|
+ totalCoursewareCount:0,
|
|
|
+ progress:0,
|
|
|
+ coursewares:[
|
|
|
{
|
|
|
- listData1:'视频课件名称',
|
|
|
+ coursewareName:'视频课件名称',
|
|
|
listData2:1,
|
|
|
- listData3:590,
|
|
|
- listData4:600,
|
|
|
- listData5:0,
|
|
|
- listData6:'http://192.168.1.8/statics/bigFile/20260801/0731dbcb-622b-4468-ade2-e20820b122eb.mp4',
|
|
|
- listData7:'mp4',
|
|
|
+ learnedDuration:590,
|
|
|
+ minLearningDuration:600,
|
|
|
+ learnStatus:2,
|
|
|
+ attachmentPath:'http://192.168.1.8/statics/bigFile/20260801/0731dbcb-622b-4468-ade2-e20820b122eb.mp4',
|
|
|
+ attachmentType:'mp4',
|
|
|
materialType:'1',
|
|
|
articleContent:'',
|
|
|
},
|
|
|
{
|
|
|
- listData1:'docx课件名称',
|
|
|
+ coursewareName:'docx课件名称',
|
|
|
listData2:1,
|
|
|
- listData3:600,
|
|
|
- listData4:600,
|
|
|
- listData5:0,
|
|
|
- listData6:'http://192.168.1.8/statics/2026/08/01/b68f1b1d-99ea-44e0-94b5-4bad4ac3ff1f.docx',
|
|
|
- listData7:'.docx',
|
|
|
+ learnedDuration:600,
|
|
|
+ minLearningDuration:600,
|
|
|
+ learnStatus:0,
|
|
|
+ attachmentPath:'http://192.168.1.8/statics/2026/08/01/b68f1b1d-99ea-44e0-94b5-4bad4ac3ff1f.docx',
|
|
|
+ attachmentType:'.docx',
|
|
|
materialType:'3',
|
|
|
articleContent:'',
|
|
|
},
|
|
|
{
|
|
|
- listData1:'xlsx课件名称',
|
|
|
+ coursewareName:'xlsx课件名称',
|
|
|
listData2:1,
|
|
|
- listData3:600,
|
|
|
- listData4:600,
|
|
|
- listData5:1,
|
|
|
- listData6:'http://192.168.1.8/statics/2026/08/01/270eb79e-627b-4fdf-9f1a-397bd9784d39.xlsx',
|
|
|
- listData7:'.xlsx',
|
|
|
+ learnedDuration:600,
|
|
|
+ minLearningDuration:600,
|
|
|
+ learnStatus:1,
|
|
|
+ attachmentPath:'http://192.168.1.8/statics/2026/08/01/270eb79e-627b-4fdf-9f1a-397bd9784d39.xlsx',
|
|
|
+ attachmentType:'.xlsx',
|
|
|
materialType:'3',
|
|
|
articleContent:'',
|
|
|
},
|
|
|
{
|
|
|
- listData1:'pdf课件名称',
|
|
|
+ coursewareName:'pdf课件名称',
|
|
|
listData2:1,
|
|
|
- listData3:600,
|
|
|
- listData4:600,
|
|
|
- listData5:1,
|
|
|
- listData6:'http://192.168.1.8/statics/2026/08/01/b251bd69-120c-48d5-b662-c28e308cd61b.pdf',
|
|
|
- listData7:'.pdf',
|
|
|
+ learnedDuration:600,
|
|
|
+ minLearningDuration:600,
|
|
|
+ learnStatus:1,
|
|
|
+ attachmentPath:'http://192.168.1.8/statics/2026/08/01/b251bd69-120c-48d5-b662-c28e308cd61b.pdf',
|
|
|
+ attachmentType:'.pdf',
|
|
|
materialType:'3',
|
|
|
articleContent:'',
|
|
|
},
|
|
|
{
|
|
|
- listData1:'富文本课件名称',
|
|
|
+ coursewareName:'富文本课件名称',
|
|
|
listData2:1,
|
|
|
- listData3:600,
|
|
|
- listData4:600,
|
|
|
- listData5:1,
|
|
|
- listData6:'',
|
|
|
- listData7:'',
|
|
|
+ learnedDuration:600,
|
|
|
+ minLearningDuration:600,
|
|
|
+ learnStatus:1,
|
|
|
+ attachmentPath:'',
|
|
|
+ attachmentType:'',
|
|
|
materialType:'4',
|
|
|
articleContent:"<p><img style=\"max-width: 100%;\" src=\"../statics/2026/08/01/e2788e82-745c-4b49-82e0-ebb6f2a30713.jpeg\" alt=\"1.jpeg\"> </p>"
|
|
|
},
|
|
|
{
|
|
|
- listData1:'xlsx课件名称',
|
|
|
+ coursewareName:'xlsx课件名称',
|
|
|
listData2:1,
|
|
|
- listData3:600,
|
|
|
- listData4:600,
|
|
|
- listData5:1,
|
|
|
- listData6:'http://192.168.1.8/statics/2026/08/01/270eb79e-627b-4fdf-9f1a-397bd9784d39.xlsx',
|
|
|
- listData7:'.xlsx',
|
|
|
+ learnedDuration:600,
|
|
|
+ minLearningDuration:600,
|
|
|
+ learnStatus:1,
|
|
|
+ attachmentPath:'http://192.168.1.8/statics/2026/08/01/270eb79e-627b-4fdf-9f1a-397bd9784d39.xlsx',
|
|
|
+ attachmentType:'.xlsx',
|
|
|
materialType:'3',
|
|
|
articleContent:'',
|
|
|
},
|
|
|
@@ -153,7 +159,7 @@
|
|
|
//验证器弹窗状态
|
|
|
dialogVisible:false,
|
|
|
//验证器弹窗间隔时间
|
|
|
- verificationTime:120,
|
|
|
+ verificationTime:0,
|
|
|
//心跳回报时间
|
|
|
heartbeatValue:30,
|
|
|
}
|
|
|
@@ -165,22 +171,29 @@
|
|
|
this.initialization();
|
|
|
},
|
|
|
methods: {
|
|
|
- /*
|
|
|
- this.$router.push({
|
|
|
- name: 'Detail',
|
|
|
- params: {
|
|
|
- id: 1,
|
|
|
- title: '消息标题'
|
|
|
- }
|
|
|
- })
|
|
|
- this.$route.params.title
|
|
|
- */
|
|
|
//初始化
|
|
|
initialization(){
|
|
|
-
|
|
|
- this.initTimer();
|
|
|
- this.startCountdown();
|
|
|
- this.courseRendering(0);
|
|
|
+ this.$set(this,'courseId',this.$route.params.courseId)
|
|
|
+ this.$set(this,'examId',this.$route.params.examId)
|
|
|
+ this.$nextTick(()=>{
|
|
|
+ this.examUserCourseLearningCoursewareList();
|
|
|
+ })
|
|
|
+ },
|
|
|
+ //获取课程下的课件列表
|
|
|
+ examUserCourseLearningCoursewareList(){
|
|
|
+ examUserCourseLearningCoursewareList({ courseId:this.courseId,examId:this.examId }).then(response => {
|
|
|
+ this.$set(this, 'newData', response.data)
|
|
|
+ if(response.data.popupVerifyEnabled == 1){
|
|
|
+ if (this.countdown) {
|
|
|
+ this.countdown.clear();
|
|
|
+ this.countdown = null;
|
|
|
+ }
|
|
|
+ this.$set(this,'verificationTime',this.accMul(response.data.popupIntervalMinutes,60));
|
|
|
+ this.startCountdown();//验证码倒计时
|
|
|
+ }
|
|
|
+ this.initTimer();//学习计时器
|
|
|
+ this.courseRendering(this.checkLearningIndex);//课件渲染
|
|
|
+ })
|
|
|
},
|
|
|
//返回
|
|
|
backPage() {
|
|
|
@@ -195,58 +208,93 @@
|
|
|
type: "warning"
|
|
|
}).then(function() {
|
|
|
}).then(() => {
|
|
|
-
|
|
|
+ self.examUserCoursewareLearningConfirmCompletion();
|
|
|
}).catch(() => {});
|
|
|
},
|
|
|
//切换课件
|
|
|
checkLearningButton(index){
|
|
|
let self = this;
|
|
|
- self.handleToggle();
|
|
|
- self.verificationHandleToggle();
|
|
|
- if(this.checkLearningIndex != index){
|
|
|
- this.$confirm('确认切换课件?', "警告", {
|
|
|
- confirmButtonText: "确认",
|
|
|
- cancelButtonText: "取消",
|
|
|
- type: "warning"
|
|
|
- }).then(function() {
|
|
|
- }).then(() => {
|
|
|
- self.$set(self,'checkLearningIndex',index);
|
|
|
- self.initTimer();
|
|
|
- self.verificationHandleToggle();
|
|
|
- self.courseRendering(index);
|
|
|
- }).catch(() => {
|
|
|
- self.handleToggle();
|
|
|
- self.verificationHandleToggle();
|
|
|
- });
|
|
|
+ if(this.newData.coursewares[this.checkLearningIndex].learnStatus == 2){
|
|
|
+ self.$set(self,'checkLearningIndex',index);
|
|
|
+ self.initTimer();
|
|
|
+ self.courseRendering(index);
|
|
|
+ }else{
|
|
|
+ self.handleToggle();
|
|
|
+ self.verificationHandleToggle();
|
|
|
+ if(this.checkLearningIndex != index){
|
|
|
+ this.$confirm('确认切换课件?', "警告", {
|
|
|
+ confirmButtonText: "确认",
|
|
|
+ cancelButtonText: "取消",
|
|
|
+ type: "warning"
|
|
|
+ }).then(function() {
|
|
|
+ }).then(() => {
|
|
|
+ self.$set(self,'checkLearningIndex',index);
|
|
|
+ self.initTimer();
|
|
|
+ self.verificationHandleToggle();
|
|
|
+ self.courseRendering(index);
|
|
|
+ }).catch(() => {
|
|
|
+ self.handleToggle();
|
|
|
+ self.verificationHandleToggle();
|
|
|
+ });
|
|
|
+ }
|
|
|
}
|
|
|
},
|
|
|
//课件渲染
|
|
|
courseRendering(index){
|
|
|
- let name = this.learningData.dataList[index].listData1;
|
|
|
+ let name = this.newData.coursewares[index].coursewareName;
|
|
|
let url = '';
|
|
|
let type = '';
|
|
|
- if(this.learningData.dataList[index].materialType == 1){
|
|
|
+ if(this.newData.coursewares[index].materialType == 1){
|
|
|
//视频
|
|
|
type = 'video'
|
|
|
- url = this.learningData.dataList[index].listData6;
|
|
|
- }else if(this.learningData.dataList[index].materialType == 3){
|
|
|
+ url = this.newData.coursewares[index].attachmentPath;
|
|
|
+ }else if(this.newData.coursewares[index].materialType == 3){
|
|
|
//文档
|
|
|
- if(this.learningData.dataList[index].listData7 == '.docx'){
|
|
|
+ if(this.newData.coursewares[index].attachmentType == '.docx'){
|
|
|
type = 'docx'
|
|
|
- }else if(this.learningData.dataList[index].listData7 == '.xlsx'){
|
|
|
+ }else if(this.newData.coursewares[index].attachmentType == '.xlsx'){
|
|
|
type = 'excel'
|
|
|
- }else if(this.learningData.dataList[index].listData7 == '.pdf'){
|
|
|
+ }else if(this.newData.coursewares[index].attachmentType == '.pdf'){
|
|
|
type = 'pdf'
|
|
|
}
|
|
|
- url = this.learningData.dataList[index].listData6;
|
|
|
- }else if(this.learningData.dataList[index].materialType == 4){
|
|
|
+ url = this.newData.coursewares[index].attachmentPath;
|
|
|
+ }else if(this.newData.coursewares[index].materialType == 4){
|
|
|
//文章
|
|
|
type = 'text'
|
|
|
- url = this.learningData.dataList[index].articleContent;
|
|
|
+ url = this.newData.coursewares[index].articleContent;
|
|
|
}
|
|
|
this.$refs['coursewareComponent'].initialize(name,url,type);
|
|
|
},
|
|
|
- //时间换算
|
|
|
+ //学习完成
|
|
|
+ examUserCoursewareLearningConfirmCompletion(){
|
|
|
+ let self = this;
|
|
|
+ let obj = {
|
|
|
+ coursewareId:this.newData.coursewares[this.checkLearningIndex].coursewareId,
|
|
|
+ courseId:this.courseId,
|
|
|
+ examId:this.examId,
|
|
|
+ }
|
|
|
+ examUserCoursewareLearningConfirmCompletion(obj).then(response => {
|
|
|
+ for(let i=0;i<self.newData.coursewares.length;i++){
|
|
|
+ if(self.newData.coursewares[i].learnStatus!=2 && i!=this.checkLearningIndex){
|
|
|
+ this.$set(this,'checkLearningIndex',i);
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ this.examUserCourseLearningCoursewareList();
|
|
|
+ this.msgSuccess(response.message)
|
|
|
+ })
|
|
|
+ },
|
|
|
+ //心跳接口
|
|
|
+ examUserCoursewareLearningReportProgress(){
|
|
|
+ let obj = {
|
|
|
+ coursewareId:this.newData.coursewares[this.checkLearningIndex].coursewareId,
|
|
|
+ courseId:this.courseId,
|
|
|
+ examId:this.examId,
|
|
|
+ duration:this.heartbeatValue,
|
|
|
+ }
|
|
|
+ examUserCoursewareLearningReportProgress(obj).then(response => {})
|
|
|
+ },
|
|
|
+ //倒计时时间换算
|
|
|
formatTime(totalSeconds) {
|
|
|
if (typeof totalSeconds !== 'number' || totalSeconds <= 0) {
|
|
|
return '0秒';
|
|
|
@@ -261,6 +309,13 @@
|
|
|
return `${seconds}秒`;
|
|
|
}
|
|
|
},
|
|
|
+ //展示时间换算
|
|
|
+ secondsToMinutes(totalSeconds) {
|
|
|
+ if (typeof totalSeconds !== 'number' || totalSeconds <= 0) {
|
|
|
+ return 1;
|
|
|
+ }
|
|
|
+ return Math.ceil(totalSeconds / 60);
|
|
|
+ },
|
|
|
/*=================================== 验证器 ===================================*/
|
|
|
onVerifySuccess() {
|
|
|
this.$message.success('验证成功');
|
|
|
@@ -268,7 +323,7 @@
|
|
|
this.handleToggle();
|
|
|
this.startCountdown();
|
|
|
//如果是视频课件 则继续播放视频
|
|
|
- if(this.learningData.dataList[this.checkLearningIndex].materialType == 1){
|
|
|
+ if(this.newData.coursewares[this.checkLearningIndex].materialType == 1){
|
|
|
this.$refs['coursewareComponent'].resumeVideo();
|
|
|
}
|
|
|
},
|
|
|
@@ -276,26 +331,26 @@
|
|
|
// 初始化定时器
|
|
|
initTimer() {
|
|
|
let self = this;
|
|
|
- if(this.learningData.dataList[this.checkLearningIndex].listData3 == this.learningData.dataList[this.checkLearningIndex].listData4){
|
|
|
+ if(this.newData.coursewares[this.checkLearningIndex].learnedDuration == this.newData.coursewares[this.checkLearningIndex].minLearningDuration){
|
|
|
return
|
|
|
}
|
|
|
this.studyTimer = new StudyTimer({
|
|
|
- initialSeconds: self.learningData.dataList[self.checkLearningIndex].listData3,
|
|
|
- maxSeconds: self.learningData.dataList[self.checkLearningIndex].listData4,
|
|
|
+ initialSeconds: self.newData.coursewares[self.checkLearningIndex].learnedDuration,
|
|
|
+ maxSeconds: self.newData.coursewares[self.checkLearningIndex].minLearningDuration,
|
|
|
onTick: (elapsedSeconds) => {
|
|
|
//每次计时
|
|
|
- this.$set(self.learningData.dataList[self.checkLearningIndex],'listData3',elapsedSeconds);
|
|
|
+ this.$set(self.newData.coursewares[self.checkLearningIndex],'learnedDuration',elapsedSeconds);
|
|
|
//心跳判断
|
|
|
if (elapsedSeconds % this.heartbeatValue === 0) {
|
|
|
//调用心跳方法
|
|
|
-
|
|
|
+ this.examUserCoursewareLearningReportProgress();
|
|
|
}
|
|
|
},
|
|
|
onMaxTimeReached: (elapsedSeconds) => {
|
|
|
//达到最大值
|
|
|
- this.$set(self.learningData.dataList[self.checkLearningIndex],'listData3',elapsedSeconds);
|
|
|
+ this.$set(self.newData.coursewares[self.checkLearningIndex],'learnedDuration',elapsedSeconds);
|
|
|
//调用心跳方法
|
|
|
-
|
|
|
+ this.examUserCoursewareLearningReportProgress();
|
|
|
}
|
|
|
});
|
|
|
this.studyTimer.resume();
|
|
|
@@ -331,7 +386,7 @@
|
|
|
this.verificationHandleToggle();
|
|
|
this.$set(this,'dialogVisible',true);
|
|
|
//如果是视频课件 则暂停播放视频
|
|
|
- if(this.learningData.dataList[this.checkLearningIndex].materialType == 1){
|
|
|
+ if(this.newData.coursewares[this.checkLearningIndex].materialType == 1){
|
|
|
this.$refs['coursewareComponent'].pauseVideo();
|
|
|
}
|
|
|
}
|
|
|
@@ -352,6 +407,13 @@
|
|
|
this.countdown = null;
|
|
|
}
|
|
|
},
|
|
|
+ //乘法
|
|
|
+ accMul(arg1,arg2){
|
|
|
+ var m=0,s1=arg1.toString(),s2=arg2.toString();
|
|
|
+ try{m+=s1.split(".")[1].length}catch(e){}
|
|
|
+ try{m+=s2.split(".")[1].length}catch(e){}
|
|
|
+ return Number(s1.replace(".",""))*Number(s2.replace(".",""))/Math.pow(10,m)
|
|
|
+ },
|
|
|
},
|
|
|
beforeDestroy() {
|
|
|
if (this.studyTimer) {
|
|
|
@@ -376,6 +438,10 @@
|
|
|
padding:0;
|
|
|
box-shadow: 0 0 8px 1px rgba(0, 0, 0, 0.1);
|
|
|
margin:10px;
|
|
|
+ ::v-deep .el-progress .el-progress__text{
|
|
|
+ margin-left:10px;
|
|
|
+ margin-top:1px;
|
|
|
+ }
|
|
|
.content-box{
|
|
|
flex: 1;
|
|
|
display: flex;
|