Files
learning-system-portal/src/views/study/coursenew.vue
2023-11-03 14:56:19 +08:00

2202 lines
73 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<template>
<div>
<div class="xpage-coures-banner">
<portal-header current="course" textColor="#fff" :goSearch="1"></portal-header>
<div style="margin: 0px 80px;">
<div class="banner-crumbs">
<router-link to="/course"><span class="crumbs-first">课程列表</span></router-link>
<span class="crumbs-line"> &gt; </span>
<span class="crumbs-last">课程详情</span>
</div>
<div class="bcourse-title">
<span>{{courseInfo.name}}</span>
<!-- <span>{{courseInfo.summary}}</span> -->
<!--
<span class="bcourse-score" v-if="courseInfo.score>0">{{toScore(courseInfo.score)}} </span>
<span class="bcourse-score" v-else>无评分</span>
-->
</div>
</div>
</div>
<div class="course-content xcontent">
<div class="course-playbox" ref="coursePlayerBox" id="id_course_player_box">
<div class="course-player" ref="coursePlayer" id="id_course_player">
<div>
<div v-if="resType == null || resType == 0">
<!--先显示视频图片-->
<course-image v-if="courseInfo.id != ''" :course="courseInfo"></course-image>
</div>
<div v-if="resType == 10" style="position: relative;">
<videoPlayer ref="myVideoPlayer" id="myVideoPlayer" :src="blobUrl" @onPlayerPlaying="onPlayerPlaying"
:initTime="contentData.lastStudyTime" :notePlay="notePlay" @onPlayerPlay="onPlayerPlay"
:isDrag="curriculumData.isDrag" @onFullscreen="onFullscreen" @onPlayerPause="onPlayerPause"
@onPlayerEnded="onPlayerEnded" :isCrowd="isCrowd" @onPlayerSendTime="onPlayerSendTime"></videoPlayer>
<div class="player-box" v-if="playerBoxShow">
<div class="player-praise" style="cursor: pointer;">
<div @click="praiseContent">
<img class="icon-small" v-if="isPraise" :src="require('@/assets/images/icon/praise-active.png')" />
<img class="icon-small" v-else :src="require('@/assets/images/icon/zhan.png')" />
<!-- {{ courseInfo.praises }} -->
<div style="color:#fff;cursor: pointer;"></div>
</div>
<div style="margin-left: 15px;cursor: pointer;" @click="treadContent">
<img class="icon-small" v-if="isTrample"
:src="require('@/assets/images/icon/trample-active.png')" />
<img class="icon-small" v-else :src="require('@/assets/images/icon/cai.png')" />
<!-- {{ courseInfo.trampleCount }} -->
<div style="color:#fff;cursor: pointer;"></div>
</div>
</div>
<div v-if="!scoreInfo.has" class="player-rate">
<el-rate v-model="scoreInfo.score" text-color="#ff9900" score-template="{value}" void-color="#fff" @change="addScore"></el-rate>
</div>
<div v-if="scoreInfo.has" style="padding-top: 5px;display: flex;">
<div class="player-rate" style="padding-left: 35px;">
<el-rate disabled v-model="courseInfo.score" :allow-half="true"></el-rate>
</div>
<span class="score-text" style="margin-top:35px">
<span style="color:#ffb30f;">{{ toScore(courseInfo.score) }}</span>
<span style="font-size: 12px;color: #fff"></span>
</span>
</div>
</div>
</div>
<div v-if="resType == 20">
<div class="con-audio">
<div class="con-audio-title">{{ contentData.contentName }}</div>
<div class="con-audio-player">
<audioPlayer v-if="resType == 20" :url="blobUrl" :name="contentData.contentName" @onPlaying="audioPlaying" :isDrag="curriculumData.isDrag"
@onPlay="audioPlay" @onPause="audioPause" @onPlayEnd="audioEnd"></audioPlayer>
</div>
</div>
</div>
<div v-if="resType == 40">
<div style="padding: 10px;color: #ed0000; " v-if="curCFile.converStatus < 2 && !contentData.content">
<div>此课程内容无法预览请联系管理员</div>
</div>
<div style="padding: 10px;color: #ed0000;" v-if="curCFile.converStatus == 3 && !contentData.content">
此课程内容无法预览请联系管理员
</div>
<pdfPreview :autoScroll="true" v-if="resType == 40" :filePath="fileBaseUrl + contentData.content">
</pdfPreview>
</div>
<div v-if="resType == 41">
<div style="padding: 20px;" v-html="contentData.content"></div>
</div>
<div v-if="resType == 50" style="min-height: 500px;">
<iframe v-if="scormUrl" :src="scormUrl" frameborder="0" border="0px" style="width:100%;height:500px;border:0px;"></iframe>
</div>
<div v-if="resType == 52">
<div v-if="contentData.content != ''">
<div class="hyper-link" v-if="conLink.openType == 2">
<div class="hyper-link-row">{{ contentData.contentName }}</div>
<div class="hyper-link-row">{{ conLink.url }}</div>
</div>
<div v-if="conLink.openType == 1"><iframe :src="conLink.url"
style="width: 100%;border:0px;min-height: 473px;" frameborder="0"></iframe></div>
</div>
</div>
<div v-if="resType == 60">
<homework v-if="resType == 60 && studyId != ''" :studyId="studyId" :content="contentData"></homework>
</div>
<div v-if="resType == 61">
<exam v-if="resType == 61 && studyId != '' " :studyId="studyId" :content="contentData"></exam>
</div>
<div v-if="resType == 62" style="padding:5px">
<assess v-if="resType == 62 && studyId != '' && contentData.id" :studyId="studyId" :content="contentData">
</assess>
</div>
</div>
<!--交互部分-->
<div>
<div class="course-interact">
<div class="score" style="display: flex;">
<div v-if="!scoreInfo.has" style="margin-left:10px;cursor: pointer;padding-top:18px">
<!-- <el-popover placement="top" width="300" trigger="hover"> -->
<!-- <div style="text-align:center;line-height:50px;padding:20px 0px">
<div style="padding-top:30px"><el-button @click="addScore">提交评分</el-button></div>
</div> -->
<el-rate v-model="scoreInfo.score" @change="addScore"></el-rate>
<!-- <el-tag class="ref-score" slot="reference">去评分</el-tag> -->
<!-- </el-popover> -->
</div>
<div v-if="scoreInfo.has" style="padding-top: 5px;display: flex;">
<div style="padding-top: 16px;">
<el-rate disabled v-model="courseInfo.score" :allow-half="true" ></el-rate>
</div>
<div>
<span class="score-text">{{ toScore(courseInfo.score) }}</span>
<span style="font-size: 18px;"></span>
</div>
</div>
</div>
<div style="display: flex;justify-content: flex-end;cursor: pointer;padding-top: 5px;">
<div @click="praiseContent">
<el-tooltip class="item" effect="light" :content="isPraise?'取消点赞':'点赞'" placement="top-start" :visible-arrow="false" popper-class="text-tooltip">
<img class="icon-small" v-if="isPraise" :src="require('@/assets/images/icon/praise-active.png')" />
<img class="icon-small" v-else :src="require('@/assets/images/icon/praise.png')" />
</el-tooltip>
{{ courseInfo.praises }}
</div>
<div style="margin-left: 20px;" @click="treadContent">
<el-tooltip class="item" effect="light" :content="isTrample?'取消踩':'踩'" placement="top-start" :visible-arrow="false" popper-class="text-tooltip">
<img class="icon-small" v-if="isTrample" :src="require('@/assets/images/icon/trample-active.png')" />
<img class="icon-small" v-else :src="require('@/assets/images/icon/trample.png')" />
</el-tooltip>
{{ courseInfo.trampleCount }}
</div>
<div style="margin-left: 6px;">
<interactBar :size="16" :type="1" :aid="courseInfo.sysCreateAid" :data="courseInfo" :praises="false" :favorites="true" :shares="true" :comments="false" :views="false"></interactBar>
</div>
</div>
</div>
</div>
</div>
<div class="course-control">
<div class="control-tab" v-if="contentList.length>0" >
<div v-if="contentList.length>1" @click="heartabone" :class="tab == 1 ? 'control-tab-active' : ' '">
<i class="el-icon-reading" style="margin-right:9px;margin-left:9px"></i>课程单元
</div>
<div @click="heartabtwo" :class="tab == 2 ? 'control-tab-active' : ' '">
<i class="el-icon-edit" style="margin-right:9px;margin-left:9px"></i>我的笔记
</div>
</div>
<!-- 课程单元 -->
<div class="course-units" v-if="tab == 1">
<div :style="`height: ${controlHeight}px;overflow-y: auto;`">
<div class="catalog" v-if="courseInfo.type == 20">
<div v-for="(item, index) in catalogTree" :key="index" :name="index">
<div style="margin: 10px 0px;font-weight: 700;">{{item.section.name}}</div>
<div class="units-info" :class="{'units-active':contentData.id == ele.id}" v-for="(ele, i) in item.children" :key="i" @click="showRes(ele,i,index)">
<img v-if="contentData.id == ele.id" :src="`${webBaseUrl}/images/playicon.png`" alt=""> {{i+1}}.
<span>{{ ele.contentName }}</span>
</div>
</div>
</div>
<div v-else class="catalog">
<!-- contentList -->
<div class="units-info" v-for="(list, index) in contentList" :key="index" :name="index" @click="showRes(list,-1,index)" :class="{'units-active':contentData.id == list.id}">
<!-- <div class="units-info" :class="{'units-active':contentData.id == ele.id}" @click="showRes(ele,i,index)" v-for="(ele, i) in item.children" :key="i"> -->
<img v-if="contentData.id == list.id" :src="`${webBaseUrl}/images/playicon.png`" alt=""> {{index+1}}.
{{ list.contentName }}
<!-- </div> -->
</div>
</div>
</div>
</div>
<!-- 我的笔记 -->
<div class="mynote" v-show="tab == 2">
<my-note ref="mynote" :height="controlHeight" @change="noteChange" :data="courseInfo" @videoLocation="videoLocation" @onPlayVideo="onPlayVideo"
:score="courseInfo.score"></my-note>
</div>
</div>
</div>
<div class="course-infobox">
<div class="course-info">
<div style="background-color: #fff;">
<div class="course-info-tab">
<div @click="coutab(1)" :class="courestab == 1? 'course-info-tab-active' : ''">内容简介<span class=""></span> </div>
<div @click="coutab(2)" :class="courestab == 2? 'course-info-tab-active' : ''">课程评论<span class=""></span> </div>
<div @click="coutab(3)" :class="courestab == 3? 'course-info-tab-active' : ''">课程笔记<span class=""></span> </div>
</div>
<div v-show="courestab==1" style="margin-left:17px;padding-top: 20px;">
<div style="padding: 30px;">
<div class="course-info-row"><img src="@/assets/images/icon/remark-iocn.png" alt="" srcset=""> 目标人群<div class="course-info-text">{{courseInfo.forUsers}}</div></div>
<div class="course-info-row"><img src="@/assets/images/icon/remark-iocn.png" alt="" srcset=""> 课程价值<div class="course-info-text">{{courseInfo.value}}</div></div>
<div class="course-info-row"><img src="@/assets/images/icon/remark-iocn.png" alt="" srcset=""> 详细介绍<div class="course-info-text" v-html="courseInfo.summary"></div></div>
</div>
</div>
<div v-show="courestab==2" class="coures-comments" style="margin-left:17px">
<comments v-if="courseInfo.id && courseInfo.id != ''" :obj-type="1" :obj-id="courseInfo.id" :toUsers="toUsers"></comments>
</div>
<div v-show="courestab==3" class="coures-note">
<note-comments :key="timer" v-if="courseInfo.id && courseInfo.id != ''" :obj-type="6" :obj-id="courseInfo.id" :name="courseInfo.name"></note-comments>
</div>
</div>
</div>
<div class="course-teacher">
<div class="cteacher-top">
<div class="cteacher-top"><img width="100%" style="vertical-align: top;" height="10px" src="../../../public/images/tearch-top.png" alt=""></div>
<div class="cteacher-top-title">课程讲师</div>
</div>
<div class="cteacher-list">
<div class="teacher" v-for="(item, idx) in teachers" :key="idx">
<div class="teacher-avator" @click="toUserHome(item)" title="点击进入他的主页">
<!-- <div class="teacher-text" v-if="item.authorInfo.avatar == ''">{{userAvatarText(item.teacherName)}}</div> -->
<div v-if="item.authorInfo.avatar !== ''">
<el-avatar :src="fileBaseUrl + item.authorInfo.avatar" shape="circle" :size="50"></el-avatar>
</div>
<div v-else class="teacher-text">
<div v-if="item.authorInfo.sex === 1 "><img src="../../../public/images/Avatarman.png" alt=""></div>
<div v-else><img src="../../../public/images/Avatarwoman.png" alt=""></div>
</div>
</div>
<div class="teacher-info">
<div class="teacher-name">
<span> {{ item.teacherName }}</span>
<!-- <span style="font-size: 12px; color:#666666 ;">( {{cutOrgNamePath(item.authorInfo.orgInfo)}} )</span> -->
</div>
<!-- <div class="teacher-remark" v-html="item.authorInfo.sign"></div> -->
<div class="teacher-remark">{{cutOrgNamePath(item.authorInfo.orgInfo)}}</div>
</div>
<div style="padding-top:15px;width:70px;">
<followButton :auto="true" size="small" :aid="item.teacherId"></followButton>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- <div><portal-footer></portal-footer></div> -->
</div>
</template>
<script>
import { mapGetters } from 'vuex';
import followButton from "@/components/Follow/button.vue";
import portalHeader from "@/components/PortalHeader.vue";
import portalFooter from "@/components/PortalFooter.vue";
import comments from "@/components/Portal/comments.vue";
import noteComments from "@/components/Portal/noteComment.vue";
import interactBar from "@/components/Portal/interactBar.vue";
import audioPlayer from '@/components/AudioPlayer/index.vue';
import videoPlayer from '@/components/VideoPlayer/index.vue';
import hyperLink from '@/components/Course/hyperLink.vue';
import studyUtil from '@/utils/study.js';
import { encrypt } from '@/utils/jsencrypt.js';
import cookies from 'vue-cookies';
import apiStat from '@/api/phase2/stat.js';
import apiStudy from '@/api/modules/courseStudy.js';
import apiVideoStudy from "@/api/modules/videoStudy.js";
import apiCourseGrade from '@/api/modules/courseGrade.js';
import apiPraises from '@/api/modules/praises.js';
import apiTrample from '@/api/modules/trample.js';
import apiCoursePortal from '@/api/modules/coursePortal.js';
import apiUser from '@/api/system/user.js';
import apiCourseFile from '@/api/modules/courseFile.js';
import {
resListMap,
resOwnerListMap,
courseType,
getType,
toScore,
cutOrgNamePath,
userAvatarText
} from '@/utils/tools.js';
import pdfPreview from '@/components/PdfPreview/index.vue';
import courseImage from '@/components/Course/courseImage.vue';
import exam from '@/components/Course/exam';
import homework from '@/components/Course/homework';
import assess from '@/components/Course/assess';
import myNote from '../../components/Course/myNote.vue';
import apiFollow from "@/api/phase2/userfollow.js";
import apiMessage from '@/api/system/message.js'
// import Vue from 'vue';
// Vue.forceUpdate();
export default {
name: "atticle",
components: {
courseImage,
portalHeader,
hyperLink,
comments,
homework,
exam,
interactBar,
assess,
pdfPreview,
audioPlayer,
videoPlayer,
myNote,
noteComments,
portalFooter,
followButton
},
data() {
return {
audiences:'',
isCrowd:false,
cutOrgNamePath,
scormUrl:'',//当前播放的scormUrl
loading:false,
controlHeight:400,//左边控制区域的内容高度
timer: '',
notePlay: null,
intTimeNote: '',
courestab: 2,//默认是课程评论
curCFile: {
converStatus: 4,
},
radio: '',
interactRuning: false,
playerBoxShow: false,
userAvatarText,
publicPath: process.env.VUE_APP_PUBLIC_PATH,
showiframe: false,
toScore,
courseId: '', //当前课程的id
studyId: '', //当前学习的id
initContentId: '', //初始化当前学习的内容节
blobUrl: '', //播放的文件地址新添加采用blob方式
contentData: {
studyItemId: '',
status: 1
}, //当前的显示的内容
conLink: {
openType: 1,
url: ''
}, //对于超连接的内容
curriculumData: {
url: '',
isDrag: true,
completeSetup: 0,
setupTage: 0,
second: 0
}, // 课件内容
courseInfo: {
id: '',
name: ''
}, //课程信息
totalContent: 0, //课程内容数量
pageCount: 0,
currentPage: 0,
fileBaseUrl: this.$xpage.constants.fileBaseUrl,//使用动态的路径 不使用配置的路径了process.env.VUE_APP_FILE_BASE_URL,
contentList: [],
sectionList: [],
teachers: [],
toUsers: [], //对于@教师的处理
getType: getType,
ctabName: 'catalog',
resType: null,
activeNames: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
scoreInfo: {
dlgShow: false,
score: 5,
has: false
},
isPraise: false,
isTrample: false,
appendStartTime: null, //记录追加的开始时间
appendHandle: null, //追加学习时长的timeout句柄
isAppendTime: false, //是否追加学习时长
appentId: '', //当前追加的学习时长的id,此字段已经不再使用
appentInterval: 5000, //追加学习时间的间隔 5秒加一次
handleTimeout: null,
completed: [],
tab: 1,
notetab: 1,
localTimeKey:'boeu-study-time' ,//本地存储的学习时长的key json格式
localTimeValue:0,//计算的时间
appendStudyOtherHandle:null,
}
},
mounted() {
// 增加的用户受众id
let localKey = "user_" + this.userInfo.sysId + "_gids";
let hasIds = sessionStorage.getItem(localKey);
this.audiences = hasIds ?? ''
this.$watermark.set(this.userInfo.name + this.userInfo.loginName);
this.courseId = this.$route.query.id;
this.initContentId = this.$route.query.contentId;
this.stopStudyTime();//先关闭
this.cleanAppendTime();//
this.loadData();
//console.log(this.$xpage.constants.fileBaseUrl,'this.$xpage.constants.fileBaseUrl');
},
computed: {
...mapGetters(['userInfo']),
catalogTree(){
let treeList = [];
this.completed = [];
let $this = this;
$this.sectionList.forEach(sec => {
let treeNode = {
section: sec,
children: []
};
sec.status = 1;
let finishCount = 0;
$this.contentList.forEach(c => {
if (c.csectionId == sec.id) {
if (c.status > 1) {
sec.status = 2;
if (c.status == 9) {
finishCount++;
}
}
if (c.status == 9) {
$this.completed.push(c.id);
}
treeNode.children.push(c);
}
});
if (finishCount == treeNode.children.length) {
sec.status = 9;
}
treeList.push(treeNode);
});
return treeList;
}
},
destroyed(){
this.cleanAppendTime();
this.stopStudyTime();
},
methods: {
onPlayerSendTime(sendTime){
console.log(sendTime,'发送的时间');
let postData={
"key": "StudyCourseOther",//课程学习的key
"title": "非音视频课内容",//事件的标题
"parameters":"second:" + Math.floor(sendTime),//second:value 本次的学习时长
"content": "学习课程",//事件的内容
"objId": this.courseInfo.id,//课程的id
"objType": "1",//类型
"source":"page",
"objInfo": ""+this.courseInfo.name,
"aid":this.userInfo.aid, //当前登录人的id
"aname":this.userInfo.name,//当前人的姓名
"status": 1 //状态
}
//静默处理
apiStat.sendEvent(postData).then(rs=>{
if(rs.status != 200) {
console.log(rs.message);
}
});
},
toUserHome(tea){
this.$router.push({path:this.$xpage.getHomePath(tea.teacherId)})
},
noteChange(){
//视频点定位,直接到播放的视频位置
this.timer = new Date().getTime()
},
//清空追加学习时长事件
cleanAppendTime(){
if(this.appendStudyOtherHandle){
window.clearTimeout(this.appendStudyOtherHandle);
}
},
//非音视频课学习时长的增加,每一分钟保存一次
appendStudyOtherTime() {
//console.log('开始追加学习时长',this.isAppendTime);
if (this.studyId == '') {
return;
}
if (!this.contentData.id) {
return;
}
// 跳转scorm链接的时候不计时了
if(this.resType == 50) return
let postData={
"key": "StudyCourseOther",//课程学习的key
"title": "非音视频课内容",//事件的标题
"parameters":"second:60",//second:value 本次的学习时长
"content": "学习课程",//事件的内容
"objId": this.courseInfo.id,//课程的id
"objType": "1",//类型
"source":"page",
"objInfo": ""+this.courseInfo.name,
"aid":this.userInfo.aid, //当前登录人的id
"aname":this.userInfo.name,//当前人的姓名
"status": 1 //状态
}
//静默处理
apiStat.sendEvent(postData).then(rs=>{
if(rs.status != 200) {
console.log(rs.message);
}
});
//每一分钟保存一次
// 取消阅读的每分钟六十秒的计时
// let $this=this;
// this.appendStudyOtherHandle = setTimeout(function() {
// $this.appendStudyOtherTime();
// }, 1000*60);
},
//笔记组件触发,播放指定时间
onPlayVideo(contentId,time){
//这里需要根据contentId,是否切换到对应的内容的视频的时间
//如果 contentId已经不存在需要提示
console.log(contentId,this.contentData.id,'两个内容id');
let $this=this;
if(this.contentData.id==contentId){
this.onPlayerPause()
//this.audioPause();
this.contentData.lastStudyTime=time;
//this.onPlayerPlay();
setTimeout(() => {
$this.$refs.myVideoPlayer.startPlay(time);
}, 10)
console.log('开始播放1');
}else{
//通过contentId
let toResContent=null;
this.contentList.forEach(c => {
if(c.id==contentId){
c.lastStudyTime=time;
toResContent=c;
}
});
if(toResContent){
this.changePlayRes(toResContent);
//this.onPlayerPlay();
setTimeout(() => {
$this.$refs.myVideoPlayer.startPlay(time);
}, 10)
console.log('开始播放2');
}else{
this.$message.error('资源已不存在或更换过,已无法定位');
}
}
this.playerBoxShow = false;
//this.changePlayRes(r);
// this.playerBoxShow = false;
// this.notePlay = null;
// let $this=this;
// setTimeout(() => {
// $this.notePlay = time;
// }, 500)
},
//笔记组件触发,记录当前播放时间
videoLocation() {
//this.$store.dispatch("SetIntTimeNote", this.intTimeNote);
//console.log(this.contentData.id+'='+this.intTimeNote,'设置视频播放时间')
this.$refs.mynote.setVideoTime(this.contentData.id,this.intTimeNote);
},
coutab(n) {
this.courestab =n;
},
createPlayUrl(fid, u) {
let nowDate = new Date();
let ctime = parseInt(nowDate.getTime() / 1000);
let beforeUrl = parseInt(nowDate.getTime() / 1000) + '/' + fid;
//console.log(beforeUrl,'beforeUrl');
let urlSign = encodeURIComponent(encrypt(beforeUrl));
//console.log(urlSign,'urlSign');
cookies.set('PLAYSIGN_TIME', ctime); //写客户端的cookie保存
//以下判断是为了区分本地环境和服务器环境
if (process.env.NODE_ENV == 'development') {
this.blobUrl = process.env.VUE_APP_FILE_BASE_URL + u;
} else {
this.blobUrl = process.env.VUE_APP_BASE_API + '/xboe/m/course/cware/resource?sign=' + urlSign;
}
//console.log(this.blobUrl,'this.blobUrl');
},
widthOpen(url) {
window.open(url, '_blank');
},
//替换播放区域
changePlayRes(r){
if(this.appendStudyOtherHandle!=null){
window.clearTimeout(this.appendStudyOtherHandle);
}
this.playerBoxShow = false;
//显示内容部分
this.$refs.mynote.showVideoTimeBtn(false);
let $this = this;
this.resType = r.contentType;
this.contentData = r;
this.contentData.name = this.courseInfo.name;
this.saveStudyDuration();
if (r.contentType == 10 || r.contentType == 20) {
if (r.content.startsWith('\{')) {
this.curriculumData = JSON.parse(r.content);
} else {
this.curriculumData.url = r.content;
}
this.$refs.mynote.showVideoTimeBtn(true);
//let url=process.env.VUE_APP_BASE_API+'/xboe/m/course/file/show?cf='+this.curriculumData.url;
//let url=this.fileBaseUrl+this.curriculumData.url;
this.createPlayUrl(r.contentRefId, this.curriculumData.url);
} else if (r.contentType == 40) {
// if (r.content != '' && r.content.indexOf('.pdf') == -1) {
apiCourseFile.detail(r.contentRefId).then(cfrs => {
if (cfrs.status == 200) {
r.content = cfrs.result.previewFilePath;
this.curCFile = cfrs.result;
if (cfrs.result.previewFilePath == '' && cfrs.result.filePath.indexOf('pdf') > -1) {
r.content = cfrs.result.filePath;
this.curCFile.converStatus = 2;
}
if (r.content && r.content.indexOf('.pdf') > -1) {
this.curCFile.converStatus = 2;
}
} else {
$this.$message.error('加载pdf课件文件失败');
}
});
// }
}else if(r.contentType==50){ //scorm
this.scormUrl='';
apiCourseFile.detail(r.contentRefId).then(cfrs => {
if(cfrs.status==200){
this.curCFile = cfrs.result;
//this.scormUrl=cfrs
let pars='?mode=normal&r='+Math.random();
pars+='&scormId='+this.curCFile.id;
pars+='&courseId='+this.courseId;
pars+='&contentId='+r.id;
pars+='&studentId='+this.userInfo.aid;
pars+='&studentName='+encodeURIComponent(this.userInfo.name);
pars+='&lmsId='+this.studyId;
pars+='&scoId=';//不指定scorm模块自动根据学习记录定位
let urlPre=window.location.protocol;
let configUrl=process.env.VUE_APP_SCORM_URL;
configUrl=urlPre+configUrl.substring(configUrl.indexOf(':')+1);
this.scormUrl=configUrl+pars;//播放的首页
}
});
}else if (r.contentType == 52) {
this.isAppendTime = false;
if (r.content.startsWith('\{')) {
this.conLink = JSON.parse(r.content);
} else {
this.conLink.url = r.content;
this.conLink.openType = 1;
}
if (this.conLink.openType == 2) {
//直接设置完成状态
this.widthOpen(this.conLink.url);
}
//this.conLink=
} else if (r.contentType == 61) {
// 考试
} else if (r.contentType == 60) {
// 作业
} else if (r.contentType == 62) {
// 评估
//评估不需要查找因为内容就是content中
//console.log('评估处理');
}
if (this.contentData.status < 2) {
this.contentData.status = 2; //进行中
}
//以下是学习记录
if (this.contentData.contentType > 20) { //非视频类的
//用户的学习时长,非音视频课程学习,单独的处理
this.isAppendTime = false;
this.appendStudyOtherHandle = setTimeout(function() {
$this.appendStudyOtherTime();
}, 1000*60*2); //非音视频课程学习,2分钟后记录因为一次记录是60秒
//this.appendStudyTime();
if (this.contentData.contentType != 50) {
this.handleTimeout = setTimeout(function(){
$this.saveStudyInfo();
}, 5000); //5秒后记录学习完成
}else{
//scorm课件不记录完成情况由播放回调记录完成情况
//当前先保存学习记录,未学习状态
this.saveScormStudy();
}
}
this.$nextTick(function(){
//let h0=document.getElementById('id_course_player').offsetHeight;
let h=$this.$refs.coursePlayer.offsetHeight;
//let h1=$this.$refs.coursePlayer.clientHeight;
///console.log(h0,h,$this.controlHeight,'$this.controlHeight');
//解决获取高度不正的问题
if(h>400 && h<500){
h=h+40;
}else if(h>500){
h=h+60;
}
//$this.controlHeight=h-99;
$this.controlHeight=h-95;
//console.log(h,$this.controlHeight,'$this.controlHeight');
})
},
showRes(r, i, index) { //i:子节下标index:章下标
// 无权限查看不能点击
if(!this.isCrowd){
return
}
if (i != undefined && i!=-1 && index != undefined && r.status < 9) {
if (this.courseInfo.orderStudy) {
//判断上个是否学完
if (i == 0) {
if (index > 0) { //第一章 第一节
let preCatalog = this.catalogTree[index - 1];
let last = preCatalog.children[preCatalog.children.length - 1];
if (last.status != 9) {
this.$message.warning('请按顺序学习!');
return;
}
}
} else {
let pre = this.catalogTree[index].children[i - 1];
if (pre.status != 9) {
this.$message.warning('请按顺序学习!');
return;
}
}
//判断是否是第一个未学完的
let isAllow = false;
let has = this.catalogTree.some(treeNode => {
let hasNo = treeNode.children.some(child => {
if (child.status < 9) {
if (child.id == r.id) {
isAllow = true;
}
return true;
} else {
return false;
}
});
return hasNo;
});
if (has) {
if (!isAllow) {
this.$message.warning('请按顺序学习!');
return;
}
}
}
}
this.changePlayRes(r);
},
loadScorePraiseAndTrample() {
//加载是否请过分
apiCourseGrade.has(this.courseId).then(rs => {
if (rs.status == 200 && rs.result) {
this.scoreInfo.has = true;
}
});
apiPraises.has(1, this.courseId).then(rs => {
if (rs.status == 200 && rs.result) {
this.isPraise = true;
}
});
apiTrample.has(this.courseId).then(rs => {
if (rs.status == 200 && rs.result) {
this.isTrample = true;
}
});
},
addScore() {
let that = this;
let postData = {
courseId: this.courseInfo.id,
studyId: this.studyId,
score: this.scoreInfo.score
};
if (this.scoreInfo.score > 0) {
apiCourseGrade.grade(postData).then(rs => {
if (rs.status == 200) {
this.$message.success('打分成功,谢谢您的打分');
that.scoreInfo.has = true;
that.courseInfo.score = rs.result;
let event = {
key: "ScoreCourse", //后台的事件key 发布文章且审核通过
title: "完成课程评分", //事件的标题
parameters: "", //用户自定义参数 name:value,name:value
content: "给课程评分", //事件的内容
objId: this.courseInfo.id, //关联的id
objType: 1, //关联的类型
objInfo: this.courseInfo.name,
aid: this.userInfo.aid, //当前登录人的id
aname: this.userInfo.name, //当前人的姓名
status: 1 //状态直接写1
}
this.$store.dispatch("userTrigger", event);
} else {
this.$message.error('打分处理失败,请稍后再试');
}
});
}
},
praiseContent() {
if(this.isTrample) {
this.$message.error('您已踩过了,不能再赞了');
return;
}
if(this.interactRuning) {
return;
}
this.interactRuning = true;
let teacherId='';
if(this.teachers.length>0){
teacherId=this.teachers[0].teacherId;
}else{
teacherId=this.courseInfo.sysCreateAid
}
let postData = {
objType: 1,
objId: this.courseId,
title: this.courseInfo.name
};
if (this.isPraise) {
apiPraises.remove(1, this.courseInfo.id).then(res => {
this.interactRuning = false;
if (res.status == 200) {
this.$message.info('已取消点赞');
this.isPraise = false;
this.courseInfo.praises--;
let event = {
key: "CancelPraise",//点赞
title: "取消点赞",//事件的标题
parameters:"author:"+teacherId,//用户自定义参数 name:value,name:value
content: "取消点赞课程",//事件的内容
objId: this.courseId,//关联的id
objType: "1",//关联的类型
objInfo: this.courseInfo.name,
aid: this.userInfo.aid, //当前登录人的id
aname: this.userInfo.name,//当前人的姓名
status: 1 //状态直接写1
}
this.$store.dispatch("userTrigger", event);
} else {
this.$message.error('取消点赞失败,请稍后再试');
}
});
} else {
apiPraises.save(postData).then(rs => {
this.interactRuning = false;
if (rs.status == 200) {
this.$message.success('点赞成功');
this.isPraise = true;
this.courseInfo.praises++;
let event = {
key: "Praise",//点赞
title: "点赞",//事件的标题
parameters:"author:"+teacherId,//用户自定义参数 name:value,name:value
content: "点赞了课程",//事件的内容
objId: this.courseId,//关联的id
objType: "1",//关联的类型
objInfo: this.courseInfo.name,
aid: this.userInfo.aid, //当前登录人的id
aname: this.userInfo.name,//当前人的姓名
status: 1 //状态直接写1
}
this.$store.dispatch("userTrigger", event);
//发送点赞消息
let firstTeacher=this.teachers[0];
let message={
content:this.userInfo.name+'点赞了我的课程-'+this.courseInfo.name,
refId:this.courseInfo.id,
refType:1,
source:1,
pageType:1,
pageParams:this.courseInfo.id,
pageUrl:location.href,
sendAid:this.userInfo.aid,
sendName:this.userInfo.name,
acceptName:firstTeacher.teacherName,
acceptId:firstTeacher.teacherId,
title:'系统消息',
sendType:1,
conType:this.courseInfo.type,
}
apiMessage.save(message).then(res=>{
if(res.status!=200){ console.log('发送消息失败') }
})
} else {
this.$message.error('点赞失败,请稍后再试');
}
});
}
},
treadContent() {
if (this.isPraise) {
this.$message.error('您已赞过了,不能再踩了');
return;
}
if (this.interactRuning) {
return;
}
this.interactRuning = true;
if (this.isTrample) {
apiTrample.remove(this.courseInfo.id).then(rs => {
this.interactRuning = false;
if (rs.status == 200) {
this.$message.info('已取消踩');
this.isTrample = false;
this.courseInfo.trampleCount--;
} else {
this.$message.error('取消失败,请稍后再试');
}
});
} else {
apiTrample.trample(this.courseInfo.id).then(rs => {
this.interactRuning = false;
if (rs.status == 200) {
this.$message.success('已踩');
this.isTrample = true;
this.courseInfo.trampleCount++;
} else {
this.$message.error('踩失败,请稍后再试');
}
});
}
},
statusToContent(status) {
let data = null;
switch (status) {
case 1: {
data = {
text: '未开始',
class: 'catalog-cell-state1'
};
break;
}
case 2: {
data = {
text: '进行中',
class: 'catalog-cell-state2'
};
break;
}
case 9: {
data = {
text: '已完成',
class: 'catalog-cell-state9'
};
break;
}
default: {
data = {
text: '未开始',
class: 'catalog-cell-state1'
};
}
break;
}
return data;
},
loadAuthorInfo(list, ids) {
//加载作者信息,头像,机构信息
if (ids.length == 0) {
return;
}
apiUser.getByIds(ids).then(res => {
if (res.status == 200) {
list.forEach((item, index) => {
res.result.some(author => {
if (author.aid == item.teacherId) {
item.authorInfo = author;
if(author.avatar){
item.avatar=this.fileBaseUrl + author.avatar;
}
return true;
} else {
return false;
}
});
});
} else {
//console.log('加载课程信息失败:'+res.error);
//this.$message.error(res.message);
}
});
},
onPlayerPlay() {
//console.log("开始播放");
this.playerBoxShow = false;
let $this = this;
//这里有些不准备,如果文件未能加载,这个事件就是错误的
this.isAppendTime=true;
this.appendStudyTime();//启动追加学习时长
//console.log(this.contentData.status,'this.contentData.status');
// if(this.contentData.status<9){
// let completeType=this.curriculumData.completeSetup;
// //console.log(completeType,'completeType');
// if(completeType==0){
// //默认5秒后学习完成.
// $this.handleTimeout= setTimeout(function() {$this.saveStudyInfo();}, 5000); //5秒后记录学习完成
// }else{
// //先记录进行中的学习内容
// this.saveStudyItem();
// }
// }
},
onFullscreen(full) {
let divId = 'videowatermark';
var div = document.getElementById('myVideoPlayer')
if (full) {
var div3 = document.createElement("div");
div3.id = divId;
div3.setAttribute("class", "fullmark");
div3.innerHTML = '';
//从父组件传过来的水印内容
//div3.innerText =this.userInfo.name+this.userInfo.code;
for (var i = 0; i < 8; i++) {
div3.innerHTML +=
'<div style="color:#ffffff;width: 40%;height: 155px;padding-left:60px;padding-top:50px; display: flex;justify-content: center; transform: rotate(-36deg);font-size:20px;">' +
this.userInfo.name + this.userInfo.loginName + '</div>';
}
div3.style.cssText =
"position:absolute;pointer-events: none; width: 100%;height: 100%;top:0;left:0;bottom: 0;right: 0; display: flex;justify-content: center;flex-wrap: wrap;overflow: hidden; opacity:0.3;padding-top:10px";
div.appendChild(div3);
} else {
var markDiv = div.querySelector("#" + divId);
if (markDiv) {
div.removeChild(markDiv);
}
}
},
onPlayerPause() {
//console.log("暂停");
this.stopStudyTime();
},
onPlayerEnded() {
this.playerBoxShow = true;
this.stopStudyTime();
if(this.contentData.status < 9) {
this.finishStudyItem();
}
},
onPlayerPlaying(itme) {
this.isAppendTime = true;//可以追加学习时长
this.intTimeNote = parseInt(itme);
//console.log("当前播放"+itme);
//console.log("当前播放11"+itme);
if (this.contentData.contentType && this.contentData.contentType == 10) {
let intTime = parseInt(itme);
//判断是否完成
let completeType = this.curriculumData.completeSetup;
let completeSecond = this.curriculumData.second;
if (!completeSecond || completeType == 0) {
completeSecond = 5; //如果没有就采用默认的时间了
}
if (this.contentData.status < 9) { //因为1按进度2按时长都是计算时间所以这里直接大于0处理
if (completeType == 1) {
let finishPercent = this.curriculumData.setupTage;
let videDuration = this.contentData.duration;
let percent = intTime * 100 / videDuration;
if (percent >= finishPercent) {
this.finishStudyItem();
}
} else {
if (intTime >= completeSecond) {
this.finishStudyItem();
}
}
}
//下面是每隔10秒记录一下次
let saveTime = Math.floor(intTime % 10);
if (intTime > 10 && intTime != this.contentData.lastStudyTime && saveTime == 0 && this.contentData
.studyItemId != '') {
this.contentData.lastStudyTime = intTime;
let postData = {
itemId: this.contentData.studyItemId,
videoTime: intTime
};
//console.log('记录播放时间')
apiStudy.studyVideoTime(postData).then(rs => {
if (rs.status != 200) {
console.log('记录播放时间错误');
}
});
}
}
},
audioPlaying(item, currentTime) {
//console.log("当前播放"+item);
let intTime = parseInt(currentTime);
//判断是否完成
let completeType = this.curriculumData.completeSetup;
let completeSecond = this.curriculumData.second;
if (!completeSecond || completeType == 0) {
completeSecond = 5; //如果没有就采用默认的时间了
}
if (this.contentData.status < 9) { //因为1按进度2按时长都是计算时间所以这里直接大于0处理
if (completeType == 1) {
let finishPercent = this.curriculumData.setupTage;
let videDuration = this.contentData.duration;
let percent = intTime * 100 / videDuration;
if (percent >= finishPercent) {
this.finishStudyItem();
}
} else {
if (intTime >= completeSecond) {
this.finishStudyItem();
}
}
}
//下面是每隔10秒记录一下次
let saveTime = Math.floor(intTime % 10);
if (intTime > 10 && intTime != this.contentData.lastStudyTime && saveTime == 0 && this.contentData
.studyItemId) {
this.contentData.lastStudyTime = intTime;
let postData = {
itemId: this.contentData.studyItemId,
videoTime: intTime
};
//console.log('记录播放时间')
apiStudy.studyVideoTime(postData).then(rs => {
if (rs.status != 200) {
console.log('记录播放时间错误');
}
});
}
},
audioPlay() {
//console.log("开始播放");
let $this = this;
this.isAppendTime=true;
this.appendStudyTime();//启动追加学习时长
},
audioPause() {
//console.log("暂停");
this.stopStudyTime();//停止追加学习时长
},
audioEnd() {
//console.log("播放结束");
this.stopStudyTime();//启动追加学习时长
if (this.contentData.status < 9) {
this.finishStudyItem();
}
},
// 获取数据信息
loadData() {
let $this=this;
apiStudy.studyIndexPost({
cid: this.courseId,
addView:true,
audiences:this.audiences
}).then(rs => {
if (rs.status == 200) {
if(rs.result.contents.length==0){
$this.$message.error('课程内容已删除或课程已不再使用');
return;
}
if(!rs.result.course.enabled){
$this.$message.error('十分抱歉,此课程已停用,如需使用,请联系管理员。');
return;
}
//设置必须的字段
if(rs.result.contents.length==1){
$this.tab=2;
//console.log('内容只有一个');
}
if(!rs.result.isCrowd){
$this.$message.error('您没有查看该课程的权限');
}
// 是否播放
this.isCrowd = rs.result.isCrowd
if (rs.result.course.type == 20) { //有目录课程
rs.result.sections.forEach(sec => {
sec.status = 0; //加入状态表未开始
rs.result.contents.forEach(c => {
c.status = 0; //初始化状态 ,未开始
c.studyItemId = ''; //初始化字段学习条目id
c.lastStudyTime = 0; //初始化上次一学习的时间,作用于视频插放
});
});
this.sectionList = rs.result.sections;
}else if(rs.result.course.type==10){ //无目录课程
//如果是多个的话,就需要过滤一下
let indexNum=0;
let delIndexs=[];
rs.result.contents.forEach((c,cidx) => {
c.status = 0; //
c.studyItemId = '';
c.lastStudyTime = 0;
if(c.sortIndex==1){
c.contentName=rs.result.course.name;
indexNum++;
if(indexNum>1){
delIndexs.push(cidx);
}
}else if(c.sortIndex==2){
c.contentName='作业';
}else if(c.sortIndex==3){
c.contentName='考试';
}else if(c.sortIndex==4){
c.contentName='评估';
}
});
if(delIndexs.length>0){
delIndexs.forEach(delIdx=>{
rs.result.contents.splice(delIdx,1);
})
}
}
this.courseInfo = rs.result.course;
if (rs.result.teachers && rs.result.teachers.length > 0) {
let userIds = [];
let ctoUsers = [];
rs.result.teachers.forEach(item => {
item.authorInfo = {
aid: '',
name: '',
orgInfo: '',
avatar: '',
code: '',
sex: null,
sign:''
};
userIds.push(item.teacherId);
ctoUsers.push({
aid: item.teacherId,
name: item.teacherName
});
});
this.toUsers = ctoUsers;
this.loadAuthorInfo(rs.result.teachers, userIds);
this.teachers = rs.result.teachers;
}
this.contentList = rs.result.contents;
//处理内容的名称
this.totalContent = rs.result.contents.length;
//加载学习的数据
//this.loadStudyData();
this.loadStudyData(rs.result);
} else {
this.$message.error(rs.message);
}
});
},
loadStudyData(result) {
let $this=this;
this.loadScorePraiseAndTrample();
this.studyId = result.studyId;
//对已学习的内容进行比对,重要的字段, 学习内容id在后缀的
let playIndex = -1;
this.contentList.forEach((con, conIdx) => {
result.contentStudys.forEach((scon, sconIdx) => {
if (scon.contentId == con.id) {
//定位显示的内容
if ($this.initContentId != '' && $this.initContentId == scon.contentId) {
//定位当前学习的内容,是上一次学习的内容
playIndex = conIdx;
} else {
if (sconIdx == 0 && con.contentType < 52) {
playIndex = conIdx;
}
}
//console.log(scon.contentId,con.id);
con.lastStudyTime = scon.lastStudyTime;
//以下判断是为了兼容之前的问题,学习状态
if (scon.status) {
con.status = scon.status;
} else {
con.status = 9;
}
con.studyItemId = scon.id; //这个就是学习内容条目的id
//console.log(scon.id,"scon.id");
//console.log(con,"scon.id");
}
});
});
if (this.courseInfo.type == 10) {
///console.log(this.contentList[0],'ccccc11111')
this.showRes(this.contentList[0]);
} else {
//如果没有,就定位第一项内容
if (playIndex === -1) {
// this.showRes(this.contentList[0]);
//console.log(this.catalogTree,'ccccc22222')
this.showRes(this.catalogTree[0].children[0])
} else {
//console.log(this.contentList[0],'ccccc3333')
this.showRes(this.contentList[playIndex]);
}
}
},
saveScormStudy() {
//只记录SCORM课件的学习
if (this.contentData.contentType != 50) {
return;
}
if (this.contentData.status == 9) {
//已学习完的,不会再记录
return;
}
let params = {
studyId: this.studyId, //学习id,
courseId: this.courseId, //课程id,
contentId: this.contentData.id, //内容id,
contentType: this.contentData.contentType,
contentName: this.contentData.contentName, //内容名称
progress: 1,
status: 2,
contentTotal: this.totalContent
};
apiStudy.studyContent(params).then(res => {
if (res.status == 200) {
this.contentData.status = 2; //进行中
this.contentData.studyItemId = res.result; //学习记录id
} else {
console.log('记录学习失败:' + res.message + '' + res.error);
}
});
},
saveStudyInfo() {
//记录课件学习信息
if (this.contentData.contentType >= 60) {
//只有在课件页面停留超过5秒才会记录
return;
}
if (this.contentData.status == 9) {
//已学习完的,不用再添加
return;
}
let params = {
studyId: this.studyId, //学习id,
courseId: this.courseId, //课程id,
contentId: this.contentData.id, //内容id,
contentType: this.contentData.contentType,
contentName: this.contentData.contentName, //内容名称
progress: 100,
status: 9,
contentTotal: this.totalContent
};
apiStudy.studyContent(params).then(res => {
if (res.status == 200) {
this.contentData.status = 9; //完成
this.contentData.studyItemId = res.result; //学习记录id
} else {
console.log('记录学习失败:' + res.message + '' + res.error);
}
});
},
saveStudyDuration(duration) { //保存本地存储的学习时长
if (duration > 0) {
//发送用户学习事件
//console.log('保存到后台学习时长='+duration);
let postData={
"key": "StudyCourse",//课程学习的key
"title": "学习课程",//事件的标题
"parameters":"second:"+duration,//second:value,total:value 本次的学习时长
"content": "学习课程【"+this.courseInfo.name+"】",//事件的内容
"objId": this.courseInfo.id,//课程的id
"objType": "1",//类型
"source":"page",
"objInfo": ""+this.courseInfo.name,
"aid":this.userInfo.aid, //当前登录人的id
"aname":this.userInfo.name,//当前人的姓名
"status": 1 //状态
}
//静默处理
apiStat.sendEvent(postData).then(rs=>{
if(rs.status == 200) {
this.appendStartTime = new Date();//重新计时
studyUtil.clearStudyDuration(); //清除本地存储
} else {
console.log(rs.message);
}
});
let postAppendData = {
id: this.appentId,
studyId: this.studyId,
courseId: this.courseInfo.id,
contentId: this.contentData.id,
studyInfo: this.courseInfo.name +"-" +this.contentData.contentName,
duration: duration
};
apiStudy.appendStudyTime(postAppendData).then(rs => {
if (rs.status == 200) {
this.appentId = rs.result;
studyUtil.clearStudyDuration(); //清除本地存储
} else {
console.log(rs.message);
}
});
}
},
//结束追加学习时长
stopStudyTime(){
//console.log('停止追加学习时长');
this.isAppendTime=false;
if (this.appendHandle != null) {
window.clearTimeout(this.appendHandle);
}
},
//追加学习时长, flag是否提交到后台
appendStudyTime() {
//console.log('开始追加学习时长',this.isAppendTime);
if (this.studyId == '') {
return;
}
if (!this.contentData.id) {
return;
}
if (!this.isAppendTime) {
this.appendStartTime = null;
return;
}
if (this.appendHandle != null) {
window.clearTimeout(this.appendHandle);
}
//首先从本地读取
let duration = studyUtil.getStudyDuration();
//console.log('追加学习时长,当前本地积累的学习时长='+duration);
//追加学习长
let $this = this;
if (this.appendStartTime == null) {
this.appendStartTime = new Date();
this.appendHandle = setTimeout(function() {
$this.appendStudyTime();
}, $this.appentInterval); //设置定时追加学习时长
//保存之前的
if (duration >0 ) {
this.saveStudyDuration(duration);
}
return;
}
//如果当前追加开始时间不为空
let now = new Date();
let m = now.getTime() - this.appendStartTime.getTime(); //相差的毫秒数
let sen = parseInt(m / 1000); //计算秒数
duration = duration + $this.appentInterval/1000;//追加的是秒
if (sen>=60) { //一分钟保存一次
this.saveStudyDuration(duration);
} else {
studyUtil.setStudyDuration(duration); //添加到本地存储中
}
//启动下次追加学习时长
this.appendHandle = setTimeout(function() {
$this.appendStudyTime();
}, $this.appentInterval);
},
finishStudyItem() { //设置完成学习的内容,针对于音视频的内容
if (!this.contentData.studyItemId) {
//这种可能没有不过这里也是为了万中那个1
this.saveStudyInfo();
} else {
let params = {
itemId: this.contentData.studyItemId,
studyId: this.studyId,
courseId: this.courseId,
cnum: this.totalContent
}
apiVideoStudy.finishStudyItem(params).then(res => {
if (res.status == 200) {
this.contentData.status = 9;
this.contentData.progress = 100;
} else {
console.log("记录完成学习失败:" + res.message + "" + res.error);
}
});
}
},
saveStudyItem() { //先保存学习的内容,针对于音视频的内容
if (this.contentData.studyItemId) {
return; //已经有记录的,不需要再保存了
}
let params = {
studyId: this.studyId, //学习id,
courseId: this.courseId, //课程id,
contentId: this.contentData.id, //内容id,
contentType: this.contentData.contentType, //内容id,
contentName: this.contentData.contentName, //内容名称
progress: 0,
lastStudyTime: 0,
status: 2,
studyDuration: 0,
contentTotal: this.totalContent
};
apiVideoStudy.saveStudyItem(params).then(res => {
if (res.status == 200) {
this.contentData.studyItemId = res.result.id;
this.contentData.status = 2; //进行中状态
} else {
console.log("记录学习失败:" + res.message + "" + res.error);
}
});
},
formatTime(duration) {
let min = 0;
if (duration > 0) {
min = parseInt(duration / 60);
}
return min;
},
heartabone() {
this.tab = 1
},
heartabtwo() {
this.tab = 2
}
},
}
</script>
<style lang="scss" scoped>
//内容块样式定义
.course-content {
min-height: 745px;
margin: 20px auto;
.course-playbox {
background-color: #fff;
min-height: 400px;
display: flex;
justify-content: space-between;
.course-player{ //内容播放区域
flex:1;
min-width: 700px;
min-height: 400px;
max-height: 800px;
//height: 100%;
border: 1px solid #ffffff;
padding-right: 20px;
overflow: auto;
}
.course-control{ //内容控制区域
width: 420px;
}
}
.course-infobox {
margin-top: 20px;
display: flex;
justify-content: space-between;
.course-info {
flex:1;
min-width: 700px;
min-height: 710px;
box-sizing: border-box;
padding-right: 20px;
}
.course-teacher{
width: 420px;
}
}
}
.control-tab {
margin: 35px 30px 10px 30px;
border-bottom: 1px solid #D8D8D8;
display: flex;
justify-content: space-around;
padding-bottom: 12px;
div {
color: #666666;
cursor: pointer;
}
.control-tab-active {
color: #333333;
font-weight: 600;
}
}
.course-info-tab {
display: flex;
padding-top: 30px;
margin-left: 47px;
div {
color: #333333;
font-size: 16px;
cursor: pointer;
margin-right: 50px;
}
.course-info-tab-active {
color: #333333;
font-weight: 600;
position: relative;
span {
display: inline-block;
width: 69px;
height: 4px;
background: #387DF7;
border-radius: 5px;
position: absolute;
left: 0;
top: 128%;
}
}
}
.course-info-row{
padding: 10px 0;
font-size: 18px;
color: #343434;
img{
width:18px
}
.course-info-text{
margin: 10px 0;
font-size: 14px;
text-indent: 2em;
color: #666666;
word-break: break-all;
}
}
//右侧老师部分头部及标题
.cteacher-top {
background-color: #fff;
margin-top: 0px;
.cteacher-top-bar{
width: 100%;
height: 15px;
}
.cteacher-top-title{
padding-left:30px;
padding-top:10px;
font-size: 16px;
font-weight: 600;
line-height: 50px;
}
}
//右侧老师部分 老师列表
.cteacher-list {
background-color: #fff;
padding: 10px 30px 30px 30px;
}
//以下是未整理的样式,上面的整理之后的样式
.coures-note {
min-height: 500px;
padding-left: 17px;
padding-top: 10px;
.note-tole {
color: #333333;
font-size: 18px;
font-weight: 600;
}
.note-info {}
}
.player-box {
position: absolute;
// top: 62px;
// left: 184px;
width: 300px;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
height: 187px;
background: rgba(74, 74, 74, .5);
border-radius: 33px;
text-align: center;
padding: 20px;
box-sizing: border-box;
.player-praise {
margin-top: 25px;
display: flex;
// justify-items: center;
justify-content: center;
}
.player-rate {
margin-top: 35px;
}
}
.score-text {
font-size: 18px;
color: #ffb30f;
font-family: 'Arial';
margin-left: 23px;
// font-weight: 600;
}
// .score {
// display: flex;
// justify-content: center;
// align-items: center;
// .el-rate {
// display: inline-block;
// }
// // margin-bottom: 19px;
// .score-no {
// color: #ffb30f;
// padding: 5px 0;
// background: #efefef;
// border-radius: 20px;
// width: 65px;
// font-size: 12px;
// font-weight: 600;
// text-align: center;
// }
// }
.portal-content-title {
font-weight: 600;
padding: 10px;
font-size: 22px;
line-height: 40px;
color: #333333;
word-break: break-all;
}
.type-kuang {
color: #666666;
border: 1px solid #666666;
}
.type-click {
color: #ffb30f !important;
border: 1px solid #ffb30f !important;
}
::v-deep .el-rate__icon {
font-size: 22px;
margin-right: 6px;
color: #ff8e00;
transition: 0.3s;
}
.ref-score {
// background: #e4e4e4;
// width: 64px;
// height: 32px;
// border-radius: 17px;
// line-height: 32px;
// // opacity: 0.24;
// color: #000;
// font-size: 14px;
// border: none;
}
.icon-small {
width: 16px;
height: 16px;
line-height: 16px;
vertical-align: middle;
}
.con-audio {
padding: 50px;
text-align: center;
.con-audio-title {
font-size: 16px;
font-weight: 700;
}
.con-audio-player {
min-height: 300px;
padding: 60px 50px 80px 50px;
}
}
.hyper-link {
padding-left: 20px;
text-align: center;
padding-top: 100px;
.hyper-link-row {
padding: 20px;
}
}
.catalog-box {
background: #fff;
// padding: 15px 0px;
// box-shadow: 1px 1px 2px 2px #ededed;
.title {
font-size: 16px;
font-weight: 600;
color: #333333;
padding-left: 20px;
}
}
.collapse-title {
flex: 1 0 90%;
order: 1;
}
.el-collapse-item__header {
flex: 1 0 auto;
order: -1;
}
.course-interact {
height: 54px;
// padding-top: 10px;
// padding-right: 10px;
padding: 0 20px;
line-height: 54px;
background-color: #FFFFFF;
display: flex;
justify-content: space-between;
box-sizing: border-box;
}
.interact-btn {
margin-right: 10px;
}
.uc-badge {
margin-top: 10px;
margin-right: 40px;
}
.cres-list {
list-style-type: decimal;
margin: 0px;
li {
line-height: 30px;
}
.current {
color: #1ea0fa;
}
}
.uc-course {
display: flex;
justify-content: space-around;
border: 1px solid #f0f0f0;
padding: 10px;
.uc-course-img {
width: 200px;
img {
width: 200px;
border: 1px solid #f4f4f5;
}
}
.uc-course-info {
flex: 1;
line-height: 28px;
padding: 0px 10px;
.uc-course-name {
font-size: 18px;
font-weight: 700;
}
.uc-course-text {
color: #747474;
}
}
.uc-course-btns {
width: 150px;
}
}
.catalog-cell-state2 {
height: 24px;
width: 58px;
line-height: 20px;
border: 0px dotted #bed2f8;
padding: 3px 10px;
color: #ff8e00;
font-size: 12px;
border-radius: 6px;
margin-left: 2px;
background: #ffedd6;
}
.catalog-cell-state9 {
height: 24px;
width: 58px;
line-height: 20px;
border: 0px dotted #bed2f8;
padding: 3px 10px;
color: #3e7fff;
font-size: 12px;
border-radius: 6px;
margin-left: 2px;
background: #edf2fd;
// margin-left: 68%;
// background-color: #BED2F8;
}
.catalog-cell-state1 {
height: 24px;
width: 58px;
line-height: 20px;
border: 0px dotted #edf2fd;
border-radius: 6px;
padding: 3px 10px;
color: #ff3e3e;
font-size: 12px;
margin-left: 2px;
background: #fff0f0;
}
.catalog {
height: 100%;
max-width: 500px;
overflow: auto;
.catalog-row {
margin: 0px;
padding: 0px 10px 10px 10px;
.title-type {
width: 36px;
height: 24px;
padding: 2px 5px;
color: #666666;
border: 1px solid #666666;
margin-right: 8px;
}
ul {
padding: 0px;
margin: 0px;
li {
padding: 6px 0;
}
}
.catalog-cell {
line-height: 32px;
cursor: pointer;
list-style: none;
margin: 0px;
padding-left: 20px;
color: #5c5c5c;
}
}
}
.video-div {
position: absolute;
z-index: 999999999;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(101, 101, 101, 0.9);
.good {
display: flex;
justify-content: center;
align-items: center;
margin-top: 200px;
div {
line-height: 1;
margin: 0 15px;
.svg-icon {
width: 30px;
height: 30px;
}
}
div:nth-of-type(2) {
.svg-icon {
transform: scaleX(-1);
transform: rotate(180deg);
}
}
}
}
::v-deep .el-tag {
background-color: #ecf5ff;
border-color: #409EFF;
display: inline-block;
height: 28px;
padding: 0 10px;
line-height: 28px;
font-size: 12px;
color: #3e7fff;
border-width: 1px;
border-style: solid;
border-radius: 0px;
box-sizing: border-box;
white-space: nowrap;
}
::v-deep .teacher .teacher-avator .teacher-text {
background: none;
border: none;
}
.teacher {
background-color: #ffffff;
display: flex;
width: 100%;
border-top: none;
padding: 10px 0px;
.teacher-avator {
cursor: pointer;
::v-deep .el-avatar {
width: 60px !important;
height: 60px !important;
border-radius: 50%;
img{
width: 100% !important;
}
}
.teacher-text {
width: 68px;
height: 68px;
div {
img {
width: 68px;
height: 68px;
}
}
}
}
.teacher-info {
flex: 1;
.teacher-name {
padding: 5px 5px 10px 10px;
}
.teacher-remark {
padding: 0px 5px 0 10px;
font-size: 14px;
color: #666666;
line-height: 20px;
overflow:hidden;
text-overflow:ellipsis;
// white-space:nowrap;
word-break:break-all
}
}
}
.breadname {
margin-bottom: 15px;
}
//目录的样式更改
::v-deep .el-collapse-item {
.el-collapse-item__header {
// position: relative;
direction: rtl;
display: flex;
// justify-content;
justify-content: space-between;
// .el-collapse-item__arrow{
// float:right;
// }
// span{
// float:right;
// }
i {
display: none
}
}
}
.course-units {
padding: 10px 30px;
.units-info {
padding: 0 30px;
height: 60px;
line-height: 60px;
font-size: 16px;
cursor: pointer;
overflow: hidden;
white-space:nowrap;
word-break:break-all;
text-overflow:ellipsis;
}
.units-active {
background: #F6F6F6;
color: #387DF7;
font-weight: 600;
cursor: text;
img {
width: 18px;
height: 20px;
vertical-align: middle;
margin-right: 20px;
}
}
}
.more {
float: right;
}
.coures-title {
margin-left: 82px;
font-size: 20px;
font-weight: 600;
color: #FFFFFF;
margin-top: 25px;
div {
float: left;
font-size: 20px;
font-weight: 600;
color: #FFFFFF;
line-height: 20px;
}
span {
float: left;
font-size: 16px;
font-weight: 400;
color: #FFFFFF;
margin-left: 27px;
}
h6 {
float: left;
font-size: 16px;
font-weight: 600;
color: #FFFFFF;
margin: 0 20px;
}
}
::v-deep.el-breadcrumb__item:first-child .el-breadcrumb__inner a,
.el-breadcrumb__inner .is-link {
color: #fff !important;
}
::v-deep.el-breadcrumb__item:last-child .el-breadcrumb__inner {
color: #fff !important;
}
::v-deep.hear-nav {
color: #fff !important;
}
.breadcrumb-nav {
color: #FFFFFF;
}
.coures-bg {
width: 100%;
height: 200px;
background: url('../../../public/images/couresdetail.png');
}
</style>