mirror of
https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/learning-system-mobile.git
synced 2025-12-09 19:06:46 +08:00
496 lines
15 KiB
Vue
496 lines
15 KiB
Vue
<template>
|
||
<!--新的课程学习页面,没有中间的详细页面了,课程点过来就是这个,用户未报名就直接报名-->
|
||
<view>
|
||
<watermark></watermark>
|
||
<u-toast ref="messager"></u-toast>
|
||
<page-title :showBack="true">{{courseInfo.name}}</page-title>
|
||
<view class="playbox"><!--内容播放区域-->
|
||
<view style="min-height: 400upx;">
|
||
内容插入区域
|
||
</view>
|
||
</view>
|
||
<view class="contentbox">
|
||
<view class="tabrow">
|
||
<view class="tabrow-item"><text class="tabrow-active">简介</text></view>
|
||
<view class="tabrow-item"><text>评论</text></view>
|
||
</view>
|
||
<!--简介内容-->
|
||
<view class="cinfo">
|
||
<view class="cinfo-title">
|
||
{{courseInfo.name}}
|
||
<text class="cinfo-tag1">通用力</text>
|
||
<text class="cinfo-tag2">职场技能</text>
|
||
</view>
|
||
<view class="desrow">
|
||
<view>
|
||
<text class="desrow-name">目标人群:</text><text>所有群体</text>
|
||
</view>
|
||
<view style="color: #999999;;">200+人学习</view>
|
||
</view>
|
||
<view class="desrow">
|
||
<view>
|
||
<text class="desrow-name">讲师:</text><text>李玉冰</text><text>(显示事件)</text>
|
||
</view>
|
||
<view style="color: #387DF7;;">+关注</view>
|
||
</view>
|
||
<view class="desrow">
|
||
<view style="display: flex;">
|
||
<text class="desrow-name">课程评分:</text>
|
||
<u-rate :count="5" color="#FB7303" :size="16" v-model="scoreInfo.score"></u-rate>
|
||
<text class="score">4.9</text>
|
||
</view>
|
||
</view>
|
||
<view class="desrow">
|
||
<view style="font-size: 32upx;color: #333333;">目录</view>
|
||
<view style="font-size: 28upx;color: #666666;">全部></view>
|
||
</view>
|
||
<view v-if="scrollItemWidth>0" class="main-cata-active">
|
||
<scroll-view scroll-x :scroll-y="false" style="height:115px;white-space: nowrap;overflow: hidden;" :scroll-left="scrollInfo.scrollLeft" @scrolltoupper="scrollLeft" @scrolltolower="scrollRight" @scroll="scrollHandler">
|
||
<!-- <view class="mycrollcontent" style="display: flex;justify-content:flex-start;"> -->
|
||
<view v-for="(con,conIdx) in scrollList" :key="conIdx" style="display: inline-block;" :id="con.id" @click="playContent(con.cataName,con,conIdx,0)">
|
||
<!---->
|
||
<view :style="{width:scrollItemWidth+'px'}" class="scroll-item" :class="{'studying':curContent.id==con.id}">
|
||
<view class="scroll-item-sec">{{con.cataName}}
|
||
<!-- <text v-if="con.cataStatus && con.cataStatus==1" class="status-tag" :class="statusClass(con.cataStatus)">未开始</text>
|
||
<text v-if="con.cataStatus && con.cataStatus==2" class="status-tag" :class="statusClass(con.cataStatus)">进行中</text>
|
||
<text v-if="con.cataStatus && con.cataStatus==9" class="status-tag" :class="statusClass(con.cataStatus)">已完成</text> -->
|
||
</view>
|
||
<view class="scroll-item-con">
|
||
<view class="scroll-item-name">
|
||
{{con.contentName}}
|
||
</view>
|
||
<!-- <view class="scroll-item-type">
|
||
<view class="square-border">
|
||
<view :class="statusClass(con.status)">
|
||
{{getConType(con.contentType)}}
|
||
</view>
|
||
</view>
|
||
<text v-if="con.status==1" class="status-tag" :class="statusClass(con.status)">未开始</text>
|
||
<text v-if="con.status==2" class="status-tag" :class="statusClass(con.status)">进行中</text>
|
||
<text v-if="con.status==9" class="status-tag" :class="statusClass(con.status)">已完成</text>
|
||
</view> -->
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!-- </view> -->
|
||
</scroll-view>
|
||
</view>
|
||
<!--推荐课程-->
|
||
<view>
|
||
<course-list :items="recommendCourse"></course-list>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import apiCoursePortal from '@/api/modules/coursePortal.js'
|
||
import apiCourseStudy from '@/api/modules/courseStudy.js'
|
||
import apiVideoStudy from "@/api/modules/videoStudy.js";
|
||
import apiCourseGrade from "@/api/modules/courseGrade.js";
|
||
import apiCourseFile from "@/api/modules/courseFile.js";
|
||
import apiUser from '@/api/system/user.js'
|
||
import apiResOwner from '@/api/modules/resowner.js'
|
||
import apiPraises from "@/api/modules/praises.js";
|
||
import apiTrample from "@/api/modules/trample.js";
|
||
import {getContentType} from "@/utils/tools.js";
|
||
import studyUtil from '@/utils/study.js';
|
||
import {toScore} from '@/utils/tools.js';
|
||
import {mapGetters} from 'vuex'
|
||
export default {
|
||
data(){
|
||
return{
|
||
courseId:'',//当前课程的id
|
||
studyId: '',//当前学习的id
|
||
initContentId:'',//初始化的内容id
|
||
courseInfo:{id:'',name:''},//课程信息
|
||
teachers:[],//课程老师列表
|
||
recommendCourse:[],//推荐课程列表
|
||
isPlaying:false,
|
||
onplay:false,
|
||
touchNum : 0,
|
||
playerBoxShow:false,
|
||
toScore:toScore,
|
||
summarylogShow: false,
|
||
scrollItemWidth:this.$width,
|
||
treePopupWidth:'400px',
|
||
fileBaseUrl:this.$config.fileUrl,
|
||
getConType:getContentType,
|
||
|
||
curSection:{},//当前所在的章
|
||
curContent:{
|
||
studyItemId:'',
|
||
status:1
|
||
},//当前的内容
|
||
conLink:{openType:1,url:''},//外连接内容
|
||
curriculumData:{url:'',isDrag:true,completeSetup:1,setupTage:0,second:0},// 课件内容
|
||
|
||
totalContent:0,//课程内容数量
|
||
authorInfo:{aid:'',name:'',code:'',orgInfo:''},
|
||
|
||
sectionList:[],
|
||
contentList:[],
|
||
videoScore:3,
|
||
videoPlayer:null,
|
||
videoPlayingTime:0,
|
||
speedListShow:false,
|
||
speedList:["2.0", "1.5", "1.25", "1.0", "0.75", "0.5"],
|
||
videoSpeed: 1.0, // 当前倍速:
|
||
tabIndex:0,
|
||
catalogShow:false,//是否显示目录
|
||
scoreInfo:{
|
||
dlgShow:false,
|
||
score:5,
|
||
has:false,
|
||
},
|
||
isPraise:false,
|
||
isTrample:false,
|
||
interactRuning:false,
|
||
scrollInfo:{
|
||
scrollLeft: 0,
|
||
scrollWidth: 0
|
||
},
|
||
handleTimeout:null,
|
||
isAppendTime:true,
|
||
appendStartTime: null, //记录追加的开始时间
|
||
appendHandle:null,
|
||
appentId:'',//当前追加的学习时长的id
|
||
appentInterval:30000,//追加学习时间的间隔 30秒加一次
|
||
preTime:-1
|
||
}
|
||
},
|
||
computed: {
|
||
...mapGetters(['userInfo']),
|
||
catalogTree(){
|
||
let treeList=[];
|
||
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++;
|
||
}
|
||
}
|
||
treeNode.children.push(c);
|
||
}
|
||
});
|
||
if (finishCount == treeNode.children.length) {
|
||
sec.status = 9;
|
||
}
|
||
treeList.push(treeNode);
|
||
})
|
||
return treeList;
|
||
},
|
||
scrollList(){
|
||
let list=[];
|
||
this.catalogTree.forEach((cata)=>{
|
||
cata.children.forEach((child,childIdx)=>{
|
||
if(childIdx==0){
|
||
child.cataName=cata.section.name;
|
||
child.cataStatus=cata.section.status;
|
||
}else{
|
||
child.cataName='';
|
||
}
|
||
list.push(child)
|
||
})
|
||
});
|
||
return list;
|
||
},
|
||
},
|
||
onLoad(options) {
|
||
//this.$watermark.set(this.userInfo.name+ this.userInfo.loginName);
|
||
this.scrollItemWidth=(this.$width-100)/2;//横向滚动的内容块宽度
|
||
this.treePopupWidth=(this.$width-100)+'px'; //右边出来的抽屉宽度控制
|
||
if(options.contentId){
|
||
this.initContentId=options.contentId;
|
||
}
|
||
this.courseId=options.id;
|
||
this.courseInfo.id=options.id;
|
||
this.loadDetail();
|
||
},
|
||
onShow(){
|
||
uni.setNavigationBarTitle({ title:'\u200E' })
|
||
//实时渲染当前的播放状态
|
||
},
|
||
onReady() {
|
||
this.videoPlayer=uni.createVideoContext("myVideo", this);
|
||
},
|
||
methods:{
|
||
loadDetail(){
|
||
let $this=this;
|
||
uni.showLoading({title:'加载中...'})
|
||
apiCourseStudy.studyIndex(this.courseId).then(rs=>{
|
||
if(rs.status != 200) {
|
||
uni.hideLoading();
|
||
$this.$refs.messager.show({message:rs.message,type:'error'});
|
||
return;
|
||
}
|
||
if(rs.result.contents.length==0){
|
||
$this.$refs.messager.show({message:'课程内容已删除或课程已不再使用',type:'error'});
|
||
return;
|
||
}
|
||
if(!rs.result.course.enabled){
|
||
$this.$refs.messager.show({message:'十分抱歉,此课程已停用,如需使用,请联系管理员。',type:'error'});
|
||
return;
|
||
}
|
||
$this.courseInfo=rs.result.course;
|
||
//处理老师数据
|
||
$this.teachers=rs.result.teachers;
|
||
if(rs.result.teachers && rs.result.teachers.length > 0) {
|
||
let userIds = [];
|
||
let ctoUsers = [];
|
||
rs.result.teachers.forEach(item => {
|
||
// item.aid='';
|
||
item.name= '';
|
||
item.orgInfo= '';
|
||
item.avatar= '';
|
||
item.code= '';
|
||
item.sex=null;
|
||
userIds.push(item.teacherId);
|
||
ctoUsers.push({ aid: item.teacherId, name: item.teacherName });
|
||
});
|
||
//this.toUsers = ctoUsers;
|
||
this.loadAuthorInfo(rs.result.teachers, userIds);
|
||
}
|
||
let showConId=this.initContentId;
|
||
if(rs.result.course.type >10){
|
||
rs.result.sections.forEach(sec=>{
|
||
sec.status=1;//加入状态表未开始
|
||
rs.result.contents.forEach(c=>{
|
||
c.status=1;//初始化状态 ,未开始
|
||
c.studyItemId='';//初始化字段,学习条目id
|
||
c.lastStudyTime=0;
|
||
if(showConId!='' && c.id==showConId){
|
||
$this.curContent=c;
|
||
$this.curSection=sec;
|
||
}
|
||
});
|
||
})
|
||
}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.contentList=rs.result.contents;
|
||
this.totalContent=rs.result.contents.length;
|
||
this.sectionList=rs.result.sections;
|
||
//设置正在学习的章节
|
||
if(showConId==''){
|
||
this.curContent=this.contentList[0];
|
||
this.curSection=this.sectionList[0];
|
||
//要不要在这里处理?
|
||
if(this.curContent.contentType==10 || this.curContent.contentType==20){
|
||
if(this.contentList[0].content.startsWith('\{')){
|
||
this.curriculumData=JSON.parse(this.contentList[0].content);
|
||
}else{
|
||
this.curriculumData.url=this.contentList[0].content;
|
||
}
|
||
}
|
||
|
||
}
|
||
uni.hideLoading();
|
||
|
||
});
|
||
apiCoursePortal.detail(this.courseId).then(rs=>{
|
||
setTimeout(function(){uni.hideLoading()},1000);
|
||
if(rs.status==200){
|
||
// uni.setNavigationBarTitle({ title:rs.result.course.name })
|
||
this.courseInfo=rs.result.course;
|
||
this.teachers=rs.result.teachers;
|
||
if(rs.result.teachers && rs.result.teachers.length > 0) {
|
||
let userIds = [];
|
||
let ctoUsers = [];
|
||
rs.result.teachers.forEach(item => {
|
||
// item.aid='';
|
||
item.name= '';
|
||
item.orgInfo= '';
|
||
item.avatar= '';
|
||
item.code= '';
|
||
item.sex=null;
|
||
userIds.push(item.teacherId);
|
||
ctoUsers.push({ aid: item.teacherId, name: item.teacherName });
|
||
});
|
||
// this.toUsers = ctoUsers;
|
||
this.loadAuthorInfo(rs.result.teachers, userIds);
|
||
}
|
||
this.loadUserInfo(this.courseInfo.sysCreateAid);
|
||
//设置必须的字段
|
||
let showConId=this.initContentId;
|
||
rs.result.sections.forEach(sec=>{
|
||
sec.status=1;//加入状态表未开始
|
||
rs.result.contents.forEach(c=>{
|
||
c.status=1;//初始化状态 ,未开始
|
||
c.studyItemId='';//初始化字段,学习条目id
|
||
c.lastStudyTime=0;
|
||
if(showConId!='' && c.id==showConId){
|
||
$this.curContent=c;
|
||
$this.curSection=sec;
|
||
}
|
||
});
|
||
})
|
||
this.contentList=rs.result.contents;
|
||
this.totalContent=rs.result.contents.length;
|
||
this.sectionList=rs.result.sections;
|
||
//设置正在学习的章节
|
||
if(showConId==''){
|
||
this.curContent=this.contentList[0];
|
||
this.curSection=this.sectionList[0];
|
||
//要不要在这里处理?
|
||
if(this.curContent.contentType==10 || this.curContent.contentType==20){
|
||
if(this.contentList[0].content.startsWith('\{')){
|
||
this.curriculumData=JSON.parse(this.contentList[0].content);
|
||
}else{
|
||
this.curriculumData.url=this.contentList[0].content;
|
||
}
|
||
}
|
||
|
||
}
|
||
}else{
|
||
this.$refs.messager.show({message:rs.message,type:'error'});
|
||
}
|
||
|
||
})
|
||
},
|
||
loadReCourses(){
|
||
//apiCoursePortal.
|
||
},
|
||
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;
|
||
// item.aid=author;
|
||
item.name= author.name;
|
||
item.orgInfo= author.orgInfo;
|
||
item.avatar= author.avatar;
|
||
item.code= author.code;
|
||
item.sex=author.sex;
|
||
if(author.avatar != '') {
|
||
item.avatar=this.$config.fileUrl + author.avatar;
|
||
}
|
||
return true;
|
||
}else{
|
||
return false;
|
||
}
|
||
});
|
||
});
|
||
} else {
|
||
//console.log('加载课程信息失败:'+res.error);
|
||
//this.$message.error(res.message);
|
||
}
|
||
});
|
||
},
|
||
loadUserInfo(uid){
|
||
apiUser.getByIds([uid]).then(res=>{
|
||
if(res.status==200){
|
||
this.authorInfo=res.result[0];
|
||
}
|
||
})
|
||
},
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
body{
|
||
background-color: #fff;
|
||
}
|
||
.playbox{
|
||
padding: 34upx;
|
||
background-color: #000000;
|
||
}
|
||
.contentbox{
|
||
padding: 34upx;
|
||
background-color: #fff;
|
||
}
|
||
.tabrow{
|
||
display: flex;
|
||
border-bottom:1px solid #999999;
|
||
font-size: 28upx;
|
||
.tabrow-active{
|
||
font-size: 32upx;
|
||
color: #387DF7;
|
||
border-bottom: 4upx solid #007DFF;
|
||
}
|
||
.tabrow-item{
|
||
margin-right: 20upx;
|
||
line-height: 60upx;
|
||
text{
|
||
padding-bottom: 10upx;
|
||
}
|
||
}
|
||
}
|
||
.cinfo{
|
||
.cinfo-title{
|
||
color:#333333;
|
||
font-size: 32upx;
|
||
padding: 28upx 0upx;
|
||
}
|
||
.cinfo-tag1{
|
||
font-size: 22upx;
|
||
color: #6E7B84;
|
||
background: rgba($color: #387DF7, $alpha: 0.1);
|
||
border-radius: 16upx;
|
||
margin-left: 12upx;
|
||
margin-right: 12upx;
|
||
padding: 2upx 12upx;
|
||
}
|
||
.cinfo-tag2{
|
||
font-size: 22upx;
|
||
color: #D98135;
|
||
background: rgba($color: #FF7900, $alpha: 0.1);
|
||
border-radius: 16upx;
|
||
margin-right: 12upx;
|
||
padding: 4upx 12upx;
|
||
}
|
||
.desrow{
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding: 26upx 0upx;
|
||
.desrow-name{
|
||
color: #666666;
|
||
font-size: 28upx;
|
||
}
|
||
.score{
|
||
color:#FB7303;
|
||
margin-left: 10upx;
|
||
font-weight: 700; font-size: 32upx;
|
||
}
|
||
}
|
||
}
|
||
</style> |