mirror of
https://codeup.aliyun.com/67762337eccfc218f6110e0e/vue/learning-system-mobile.git
synced 2025-12-06 09:26:45 +08:00
2287 lines
74 KiB
Vue
2287 lines
74 KiB
Vue
<template>
|
||
<!--新的课程学习页面,没有中间的详细页面了,课程点过来就是这个,用户未报名就直接报名-->
|
||
<view>
|
||
<watermark></watermark>
|
||
<u-toast ref="messager"></u-toast>
|
||
<!-- <page-title :showBack="true"></page-title> -->
|
||
<view class="playbox" v-if="isShowPdt"><!--内容播放区域-->
|
||
<view style="min-height: 440upx;" >
|
||
<view v-if="curContent.contentType==10" style="background-color: #000000;">
|
||
<!--视频-->
|
||
<view style="position: relative;">
|
||
<video-player
|
||
:url="blobUrl"
|
||
:blobId="blobId"
|
||
controls
|
||
:enable-play-gesture="true"
|
||
:inittime="curContent.lastStudyTime"
|
||
@play="onPlayerPlay"
|
||
@pause="onPlayerPause"
|
||
@ended="onPlayerEnded"
|
||
@timeupdate="onPlayerPlaying"
|
||
@fullscreenchange="onFullScreen"
|
||
:drag="curriculumData.isDrag"
|
||
style="width: 100%; object-fit: fill">
|
||
></video-player>
|
||
<view class="player-box" v-if="playerBoxShow">
|
||
<view class="player-praise">
|
||
<view @click="praiseContent" style="cursor: pointer;">
|
||
<image class="icon-small" v-if="isPraise" src="/static/images/icon/praise-active.png" />
|
||
<image class="icon-small" v-else src="/static/images/icon/praise1.png" />
|
||
<!-- {{ courseInfo.praises }} -->
|
||
<view style="color:#fff;cursor: pointer;">赞</view>
|
||
</view>
|
||
<view style="margin-left: 15px;cursor: pointer;" @click="treadContent">
|
||
<image class="icon-small" v-if="isTrample" src="/static/images/icon/trample-active.png" />
|
||
<image class="icon-small" v-else src="/static/images/icon/trample.png" />
|
||
<!-- {{ courseInfo.trampleCount }} -->
|
||
<view style="color:#fff;cursor: pointer;">踩</view>
|
||
</view>
|
||
</view>
|
||
<!--以下部分,已经移到下面了-->
|
||
<!-- <view v-if="!scoreInfo.has" class="player-rate">
|
||
<u-rate v-model="scoreInfo.score" active-color="#f7ba2a" text-color="#ff9900" score-template="{value}" void-color="#fff" @change="addScore"></u-rate>
|
||
</view>
|
||
<view v-if="scoreInfo.has" style="padding-top: 5px;display: flex;">
|
||
<view class="player-rate" style="padding-left: 5px;">
|
||
<u-rate readonly :count="5" active-color="#f7ba2a" v-model="scoreInfo.score"></u-rate>
|
||
</view>
|
||
<view class="score-text" style="margin-top:20px">
|
||
<text style="color:#ffb30f;">{{ toScore(scoreInfo.score) }}</text>
|
||
<text style="font-size: 12px;color: #fff">分</text>
|
||
</view>
|
||
</view> -->
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!---->
|
||
<view v-if="curContent.contentType==20">
|
||
<!--音频播放-->
|
||
<view style="text-align: center;padding-top: 40px;background-color: #FFFFFF;">
|
||
<audio-player
|
||
:src="blobUrl"
|
||
:name="curContent.contentName"
|
||
:drag="curriculumData.isDrag"
|
||
@onPlay="audioPlay"
|
||
@onPause="audioPause"
|
||
@onPlaying="audioPlaying"
|
||
@onEnded="audioEnd">
|
||
</audio-player>
|
||
</view>
|
||
</view>
|
||
<view v-if="curContent.contentType==30">
|
||
<image :src="fileBaseUrl+curContent.content" style="width: 100%;"></image>
|
||
</view>
|
||
<view v-if="curContent.contentType==40">
|
||
<!--pdf文档-->
|
||
<view style="min-height: 500px;padding-top: 200upx;position: relative;">
|
||
<pdf-preview v-if="curContent.content && curContent.content!=''" :src="curContent.content ? fileBaseUrl+curContent.content : ''"></pdf-preview>
|
||
</view>
|
||
</view>
|
||
<view v-if="curContent.contentType==41">
|
||
<view class="about-gongsi-info" :style="{height:articleMore? '500upx':'auto'}" style="padding: 15px;text-indent:40px;line-height: 28px;position: relative;">
|
||
<u-parse :content="curContent.content"></u-parse>
|
||
</view>
|
||
<view v-if="articleMore" @click="showMore" style="text-align: center;color: #387DF7;"><text>查看更多∨</text> </view>
|
||
</view>
|
||
<div v-if="curContent.contentType == 50" style="min-height: 500px;">
|
||
<!--因为web-view 动态切换地址不好用,所以这里先使用iframe-->
|
||
<iframe id="iframe-scorm" v-if="scormUrl" :src="scormUrl" @load="iframeScormLoad()" frameborder="0" scrolling="no" border="0px" style="width:100%;min-height:500px;border:0px;"></iframe>
|
||
</div>
|
||
<view v-if="curContent.contentType==52">
|
||
<!--外连接-->
|
||
<view v-if="conLink.openType == 1">
|
||
<view v-if="conLink.url!=''" style="min-height: 400px;position: relative;">
|
||
<web-view :src="conLink.url"></web-view>
|
||
</view>
|
||
</view>
|
||
<view v-else>
|
||
<div style="text-align: center;padding: 20px;">{{ curContent.contentName }}</div>
|
||
<div style="text-align: center;padding: 20px;">{{ conLink.url }}</div>
|
||
</view>
|
||
</view>
|
||
<!--作业-->
|
||
<view v-if="curContent.contentType==60">
|
||
<course-homework :content="curContent" :studyId="studyId"></course-homework>
|
||
</view>
|
||
<!--考试-->
|
||
<view v-if="curContent.contentType==61">
|
||
<course-exam :courseType="courseInfo.type" :content="curContent" :studyId="studyId"></course-exam>
|
||
</view>
|
||
<!--评估-->
|
||
<view v-if="curContent.contentType==62">
|
||
<course-assess :content="curContent" :studyId="studyId"></course-assess>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="contentbox" v-if="courseInfo.name">
|
||
<view v-if="!catalogShow">
|
||
<view class="tabrow">
|
||
<view class="tabrow-item" @click="goTop">目录({{totalContent}})</view>
|
||
<view class="tabrow-item" @click="changeTab(1)"><text :class="{'tabrow-active':tabIndex==1}">简介</text></view>
|
||
<view class="tabrow-item" @click="changeTab(2)"><text :class="{'tabrow-active':tabIndex==2}">评论</text></view>
|
||
<view class="player-box-tabrow">
|
||
<view class="player-praise">
|
||
<view @click="praiseContent" style="cursor: pointer;">
|
||
<image class="icon-small" v-if="isPraise" src="/static/images/icon/praise-active.png" />
|
||
<image class="icon-small" v-else src="/static/images/icon/praise1.png" />
|
||
<!-- {{ courseInfo.praises }} -->
|
||
<text style="cursor: pointer;">赞</text>
|
||
</view>
|
||
<view style="margin-left: 15px;cursor: pointer;" @click="treadContent">
|
||
<image class="icon-small" v-if="isTrample" src="/static/images/icon/trample-active.png" />
|
||
<image class="icon-small" v-else src="/static/images/icon/trample.png" />
|
||
<!-- {{ courseInfo.trampleCount }} -->
|
||
<text style="cursor: pointer;">踩</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!--简介内容-->
|
||
<view v-if="tabIndex==1" class="cinfo">
|
||
<view class="cinfo-title" style="display: flex;flex-wrap: wrap;">
|
||
<view >
|
||
{{courseInfo.name}}
|
||
</view>
|
||
<view>
|
||
<text class="cinfo-tag1">{{convertTypeName(courseInfo.sysType1)}}</text>
|
||
<text v-if="courseInfo.sysType2!= '' && courseInfo.sysType2!= '0'" class="cinfo-tag2">{{convertTypeName(courseInfo.sysType2)}}</text>
|
||
<text v-if="courseInfo.sysType3!= '' && courseInfo.sysType3!= '0'" class="cinfo-tag2">{{convertTypeName(courseInfo.sysType3)}}</text>
|
||
|
||
</view>
|
||
</view>
|
||
<view class="desrow">
|
||
<view>
|
||
<text class="desrow-name">目标人群:</text>
|
||
<text class="desrow-value">{{courseInfo.forUsers}}</text>
|
||
</view>
|
||
<view style="color: #999999;min-width: 160upx;text-align: right;font-size: 24upx;">{{formatUserNumber(courseInfo.studys)}}人学习</view>
|
||
</view>
|
||
<view class="desrow" style="justify-content: flex-start;">
|
||
<view style="line-height: 60upx;"><text class="desrow-name">讲师:</text></view>
|
||
<view style="flex: 1;">
|
||
<view v-for="(tea,teaIdx) in teachers" :key="tea.id" style="display: flex;justify-content: space-between;line-height: 60upx;">
|
||
<view>
|
||
<text class="desrow-value">{{tea.teacherName}}</text>
|
||
<text class="desrow-value" style="font-size: 24upx;margin-left: 6upx;color: #999999;">({{tea.orgInfo}})</text>
|
||
</view>
|
||
<view @click="followUser(tea)" style="color: #387DF7;">
|
||
<text class="concern" v-if="tea.followed">已关注</text>
|
||
<text v-else class="concern">+关注</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view class="desrow">
|
||
<view style="display: flex;">
|
||
<text class="desrow-name">课程评分:</text>
|
||
<u-rate readonly v-if="courseInfo.score>0" :count="5" activeColor="#F37101" :size="16" v-model="courseInfo.score"></u-rate>
|
||
<text class="score">{{toScore(courseInfo.score)}}</text>
|
||
</view>
|
||
|
||
</view>
|
||
<view class="desrow" v-if="myScore>0">
|
||
<view style="display: flex;">
|
||
<text class="desrow-name">我的评分:</text>
|
||
<u-rate readonly :count="5" activeColor="#F37101" :size="16" v-model="myScore"></u-rate>
|
||
<text class="score">{{toScore(myScore)}}</text>
|
||
</view>
|
||
</view>
|
||
<view v-if="totalContent>1" class="desrow">
|
||
<view style="font-size: 32upx;color: #333333;">目录</view>
|
||
<view v-if="totalContent>2" @click="showAllCatalog" style="font-size: 28upx;color: #666666;">全部></view>
|
||
</view>
|
||
<view v-if="totalContent>1"><!--单个内容时,不显示内容名称-->
|
||
<view v-if="totalContent==2">
|
||
<view v-if="courseInfo.type==10">
|
||
<view class="citembox1">
|
||
<view v-for="(con,conIdx) in contentList" :key="conIdx" class="citembox1-item">
|
||
<view class="citem" @click="playContent(con,conIdx,0)">
|
||
<view class="citem-body" :class="{'box-studying':con.id==curContent.id}">
|
||
<text :class="{'color-studying':con.id==curContent.id}">{{con.contentName}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-else><!--有目录的,但是只有两项内容-->
|
||
<view class="citembox1">
|
||
<view v-for="(con,conIdx) in scrollList" :key="conIdx" class="citembox1-item">
|
||
<view class="citem" @click="playContent(con,conIdx,0)">
|
||
<view class="citem-body" :class="{'box-studying':con.id==curContent.id}">
|
||
<text :class="{'color-studying':con.id==curContent.id}">{{con.contentName}}</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-else >
|
||
<view v-if="courseInfo.type==10">
|
||
<view v-if="scrollItemWidth>0" class="main-cata-active">
|
||
<scroll-view scroll-x :scroll-y="false" style="min-height:180upx;white-space: nowrap;overflow: hidden;" :scroll-left="scrollInfo.scrollLeft" @scroll="scrollHandler">
|
||
<!-- <view class="mycrollcontent" style="display: flex;justify-content:flex-start;"> -->
|
||
<view v-for="(con,conIdx) in contentList" :key="conIdx" style="display: inline-block;" :id="con.id" @click="playContent(con,conIdx,0)">
|
||
<!---->
|
||
<view :style="{width:scrollItemWidth+'px'}" class="scroll-item" :class="{'box-studying':curContent.id==con.id}">
|
||
<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>
|
||
<view v-else>
|
||
<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" @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,conIdx,0)">
|
||
<!---->
|
||
<view :style="{width:scrollItemWidth+'px'}" class="scroll-item" :class="{'color-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" :class="{'box-studying':curContent.id==con.id}">
|
||
<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>
|
||
</view>
|
||
</view>
|
||
<!--交互-->
|
||
<view class="cinfo-btns">
|
||
<view class="cinfo-btn" @click="openScore()">
|
||
<view><image src="/static/images/course/c_comment.png" style="width: 80upx;height: 80upx;"></image> </view>
|
||
<view>评价</view>
|
||
</view>
|
||
<view class="cinfo-btn" @click="addFavorite()">
|
||
<view>
|
||
<image v-if="isFavorite" src="/static/images/course/c_favorite_2.png" style="width: 80upx;height: 80upx;">
|
||
<image v-else src="/static/images/course/c_favorite.png" style="width: 80upx;height: 80upx;">
|
||
</view>
|
||
<view><text v-if="isFavorite">已收藏</text><text v-else>收藏</text> </view>
|
||
</view>
|
||
<view class="cinfo-btn" @click="openShare()">
|
||
<view>
|
||
<image src="/static/images/course/c_share.png" style="width: 80upx;height: 80upx;">
|
||
</view>
|
||
<view>转发</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<!--评论-->
|
||
<view v-show="tabIndex==2" class="pinglun">
|
||
<comments ref="comments" v-if="courseId && courseId!=''" :objType="1" :objId="courseId"></comments>
|
||
<interact-fixed ref="fiexdbar" :type="1" :data="courseInfo" :users="teachers" :praises="false" :favorites="false" :shares="false" :comments="false" @comment-success="refreshComments" @share-success="shareSuccess"></interact-fixed>
|
||
</view>
|
||
</view>
|
||
<!--全部目录-->
|
||
<view v-else >
|
||
<view class="tabrow" style="justify-content: space-between;">
|
||
<view class="tabrow-item"><text class="tabrow-active">目录</text></view>
|
||
<view @click="closeAllCatalog"> <image src="/static/images/close.png" style="width: 50upx;height: 50upx;"></image> </view>
|
||
</view>
|
||
<view class="catalogbox">
|
||
<view v-if="courseInfo.type>10" class="catalog">
|
||
<view v-for="(cata,catIdx) in catalogTree" :key="catIdx" style="border-bottom: 1px solid #ebebeb;padding-bottom: 30upx;">
|
||
<view class="catalog-sec" style="margin-bottom: 20rpx;">
|
||
<view class="catalog-sec-name" >
|
||
<!-- <text>{{catIdx+1}}, </text> -->
|
||
<text class="text-ellipsis">{{cata.section.name}}</text>
|
||
</view>
|
||
<view :class="{'color-studying':cata.section.status==2}">
|
||
<text v-if="cata.section.status==1" style="font-size: 14px;">未开始</text>
|
||
<text v-if="cata.section.status==2" style="font-size: 14px;">进行中</text>
|
||
<text v-if="cata.section.status==9" style="font-size: 14px;">已完成</text>
|
||
</view>
|
||
</view>
|
||
<view >
|
||
<view v-for="(con,conIdx) in cata.children" :key="conIdx" class="catalog-con" @click="playContent(con,conIdx,catIdx)">
|
||
<view class="catalog-con-name" :class="{'color-studying':curContent.id==con.id}">
|
||
<text>{{catIdx+1}}.{{conIdx+1}}. </text>
|
||
<!-- <text class="square-border">{{getConType(con.contentType)}}</text> -->
|
||
<text class="text-ellipsis" style="font-size: 14px;">{{con.contentName}}</text>
|
||
</view>
|
||
<view>
|
||
<text v-if="con.status==1" class="status-tag tag-nostart" style="font-size: 14px;">未开始</text>
|
||
<text v-if="con.status==2" class="status-tag tag-studying" style="font-size: 14px;">进行中</text>
|
||
<text v-if="con.status==9" class="status-tag tag-finish" style="font-size: 14px;">已完成</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
<view v-else class="catalog">
|
||
<view >
|
||
<view v-for="(con,conIdx) in contentList" :key="conIdx" class="catalog-con" @click="playContent(con,conIdx)">
|
||
<view class="catalog-con-name" :class="{'color-studying':curContent.id==con.id}">
|
||
<text>{{conIdx+1}}. </text>
|
||
<!-- <text class="square-border">{{getConType(con.contentType)}}</text> -->
|
||
<text class="text-ellipsis" style="font-size: 14px;">{{con.contentName}}</text>
|
||
</view>
|
||
<view>
|
||
<text v-if="con.status==1" class="status-tag tag-nostart" style="font-size: 14px;">未开始</text>
|
||
<text v-if="con.status==2" class="status-tag tag-studying" style="font-size: 14px;">进行中</text>
|
||
<text v-if="con.status==9" class="status-tag tag-finish" style="font-size: 14px;">已完成</text>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
</view>
|
||
|
||
</view>
|
||
<!--推荐课程-->
|
||
<view v-if="tabIndex==1 && !catalogShow" style="padding: 30upx;background-color: #fff;">
|
||
<view style="color: #333333; font-size: 32upx;font-weight: 600;padding-bottom: 20upx;">课程推荐</view>
|
||
<course-list :items="recommendCourses"></course-list>
|
||
</view>
|
||
<!--弹出窗口-->
|
||
<!--课程简介-->
|
||
<u-popup :show="summarylogShow" mode="right" @close="summaryCatalog" :safeAreaInsetTop="true" :closeable="true">
|
||
<view class="summary-log" :style="`width: ${treePopupWidth};padding-top: 20px;`" style="height: 100vh; overflow: auto;">
|
||
<!-- <view class=""> -->
|
||
<view class="particulars">课程详情</view>
|
||
<view class="matter">
|
||
<u-parse v-if="courseInfo.summary" :content="courseInfo.summary"></u-parse>
|
||
<text v-else>暂无</text>
|
||
</view>
|
||
<!-- </view> -->
|
||
</view>
|
||
</u-popup>
|
||
<!-- 评分,赞和踩 -->
|
||
<u-popup :show="scoreInfo.dlgShow" mode="center" :closeable="false" :closeOnClickOverlay="false" :round="14" @close="closeScore" @open="openScore">
|
||
<view class="dlgscore">
|
||
<view class="dlgscore-top">
|
||
<view class="dlgscore-title">课程评价</view>
|
||
<view class="dlgscore-desc">对课程进行评分吧!</view>
|
||
<view class="dlgscore-score">
|
||
<u-rate :count="5" :size="35" activeColor="#F37101" v-model="scoreInfo.score"></u-rate>
|
||
</view>
|
||
</view>
|
||
<view class="dlgscore-btns">
|
||
<view class="dlgscore-cancel">
|
||
<text @click="closeScore">取消</text>
|
||
</view>
|
||
<view class="dlgscore-submit">
|
||
<text @click="addScore()">提交</text>
|
||
</view>
|
||
<!-- <u-button type="primary" @click="addScore()" text="提交评分"></u-button> -->
|
||
</view>
|
||
</view>
|
||
</u-popup>
|
||
<interact-share ref="comShare" :data="courseInfo":type="1"></interact-share>
|
||
</view>
|
||
</template>
|
||
|
||
<script>
|
||
import config from '@/config/index.js'
|
||
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 apiUserFollow from '@/api/phase2/userfollow.js'
|
||
import apiStat from '@/api/phase2/stat.js'
|
||
import apiResOwner from '@/api/modules/resowner.js'
|
||
import apiPraises from "@/api/modules/praises.js";
|
||
import apiTrample from "@/api/modules/trample.js";
|
||
import apiMessage from '@/api/system/message.js'
|
||
import apiFavorites from '@/api/modules/favorites.js'
|
||
import {getContentType} from "@/utils/tools.js";
|
||
import studyUtil from '@/utils/study.js';
|
||
import {toScore,cutOrgNamePath,formatUserNumber} from '@/utils/tools.js';
|
||
import {mapGetters,mapActions} from 'vuex'
|
||
export default {
|
||
data(){
|
||
return{
|
||
tentative: false,
|
||
isShowPdt: true,
|
||
progressData: 0,
|
||
contentTypeV: '',
|
||
trueFalse: true,
|
||
loading:false,//加载中
|
||
courseId:'',//当前课程的id
|
||
studyId: '',//当前学习的id
|
||
initContentId:'',//初始化的内容id
|
||
courseInfo:{id:'',name:'',score:0},//课程信息
|
||
teachers:[],//课程老师列表
|
||
recommendCourses:[],//推荐课程列表
|
||
catalogShow:false,//是否显示目录
|
||
totalContent:0,//课程内容数量
|
||
hasSection:false,//是否有目录
|
||
tabIndex:1,//显示的tab内容
|
||
scoreInfo:{dlgShow:false, score:0, has:false},//评分控制项
|
||
isPraise:false,//是否已点赞
|
||
isTrample:false,//是否已踩
|
||
isFavorite:false,//是否已收藏
|
||
isFollow:false,//是否已关注
|
||
myScore:0,//我的评分,如果是0表未评分
|
||
toScore:toScore,
|
||
formatUserNumber:formatUserNumber,
|
||
getConType:getContentType,
|
||
onplay:false,
|
||
touchNum : 0,
|
||
playerBoxShow:false,
|
||
summarylogShow: false,
|
||
scrollItemWidth:this.$width,
|
||
treePopupWidth:'400px',
|
||
fileBaseUrl:this.$config.fileUrl,
|
||
curSection:{},//当前所在的章
|
||
curContent:{id:'',studyItemId:'',status:1},//当前的内容
|
||
conLink:{openType:1,url:''},//外连接内容
|
||
curriculumData:{url:'',isDrag:true,completeSetup:1,setupTage:0,second:0},// 课件内容
|
||
|
||
authorInfo:{aid:'',name:'',code:'',orgInfo:''},
|
||
|
||
sectionList:[],
|
||
contentList:[],
|
||
videoScore:3,
|
||
videoPlayingTime:0,
|
||
speedListShow:false,
|
||
speedList:["2.0", "1.5", "1.25", "1.0", "0.75", "0.5"],
|
||
videoSpeed: 1.0, // 当前倍速:
|
||
|
||
interactRuning:false,
|
||
scrollInfo:{
|
||
scrollLeft: 0,
|
||
scrollWidth: 0
|
||
},
|
||
handleTimeout:null,
|
||
isAppendTime:true,
|
||
appendStartTime: null, //记录追加的开始时间
|
||
appendHandle:null,//追加学习时长的timeout句柄
|
||
appentId:'',//当前追加的学习时长的id
|
||
appentInterval:15,//追加学习时间的间隔 3秒加一次
|
||
preTime:-1,
|
||
blobUrl:'',//音视频的播放地址
|
||
blobId: '',
|
||
localTimeKey:'boeu-study-time' ,//本地存储的学习时长的key json格式
|
||
localTimeValue:0,//计算的时间
|
||
appendStudyOtherHandle:null,
|
||
articleMore:true,
|
||
scormUrl:'',
|
||
maxDuration:0, //非音频最大时长
|
||
cumulativeDuration:0, //非音频累计时长
|
||
defaultMaxTime:1800 //非音频默认最大时间
|
||
}
|
||
},
|
||
computed: {
|
||
...mapGetters(['userInfo','sysTypeMap']),
|
||
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();//加载课程数据
|
||
this.getSysTypeTree();
|
||
this.loadSysTypes();
|
||
this.loadReCourses();//加载推荐课程
|
||
this.loadIsData();//加载关注,收藏,评价等信息
|
||
this.loadMyScore();
|
||
},
|
||
onShow(){
|
||
uni.setNavigationBarTitle({ title:'\u200E' })
|
||
|
||
//实时渲染当前的播放状态
|
||
},
|
||
onReady() {
|
||
|
||
},
|
||
onHide(){
|
||
//清除定时任务,隐藏的时候不清除,因为没有停止播放
|
||
// this.clearTimeHandle();
|
||
console.log('触发onHide');
|
||
},
|
||
destroyed() {
|
||
this.clearTimeHandle();
|
||
},
|
||
methods:{
|
||
...mapActions({
|
||
// getResOwnerTree:'resOwner/getResOwnerTree',
|
||
// loadResOwners:'resOwner/loadResOwners',
|
||
getSysTypeTree:'sysType/getSysTypeTree',
|
||
loadSysTypes:'sysType/loadSysTypes'
|
||
}),
|
||
|
||
// 没有写播放时间
|
||
onPlayerPlay() {
|
||
this.playerBoxShow = false;
|
||
this.isAppendTime=true;
|
||
this.appendStudyTime();//启动追加学习时长
|
||
},
|
||
convertTypeName(code){
|
||
if(!code){return '';}
|
||
return this.sysTypeMap.get(code);
|
||
},
|
||
clearTimeHandle(){
|
||
if(this.appendStudyOtherHandle!=null){
|
||
window.clearTimeout(this.appendStudyOtherHandle);
|
||
}
|
||
if(this.appendHandle!=null){
|
||
window.clearTimeout(this.appendHandle);
|
||
}
|
||
if(this.handleTimeout!=null){
|
||
window.clearTimeout(this.handleTimeout);
|
||
}
|
||
},
|
||
iframeScormLoad(){
|
||
setTimeout(function(){
|
||
var scormIframe=document.getElementById('iframe-scorm');
|
||
if (scormIframe) {
|
||
let iframeWin = scormIframe.contentWindow;
|
||
let iframeDoc = scormIframe.contentDocument || scormIframe.document;
|
||
|
||
let cHeight = Math.max(iframeDoc.body.clientHeight,iframeDoc.documentElement.clientHeight);
|
||
let sHeight = Math.max(iframeDoc.body. scrollHeight,iframeDoc.documentElement.scrollHeight);
|
||
let winHeight = iframeWin.document.documentElement.scrollHeight || iframeWin.document.body.scrollHeight;
|
||
|
||
let lheight = Math.max(cHeight, sHeight);
|
||
let finalHeight = Math.max(lheight, winHeight );
|
||
|
||
scormIframe.height =finalHeight;
|
||
console.log('scormIframe.height',scormIframe.height);
|
||
}
|
||
},1500);
|
||
|
||
},
|
||
loadMyScore(){
|
||
apiCourseGrade.score({courseId:this.courseId}).then(rs=>{
|
||
if(rs.status==200){
|
||
this.myScore=rs.result.scores;
|
||
this.scoreInfo.has=true;
|
||
}
|
||
})
|
||
},
|
||
loadDetail(){
|
||
let $this=this;
|
||
uni.showLoading({title:'加载中...'})
|
||
apiCourseStudy.studyIndex(this.courseId).then(rs=>{
|
||
if(rs.status != 200) {
|
||
uni.hideLoading();
|
||
uni.showToast({title:rs.message,type:'fail'});
|
||
//$this.$refs.messager.show({message:rs.message,type:'error'});
|
||
return;
|
||
}
|
||
if(rs.result.contents.length==0){
|
||
//$this.$refs.messager.show({message:'课程内容已删除或课程已不再使用',type:'error'});
|
||
uni.showToast({title:'课程内容已删除或课程已不再使用',type:'fail'});
|
||
return;
|
||
}
|
||
if(!rs.result.course.enabled){
|
||
uni.showToast({title:'十分抱歉,此课程已停用,如需使用,请联系管理员。',type:'fail'});
|
||
//$this.$refs.messager.show({message:'十分抱歉,此课程已停用,如需使用,请联系管理员。',type:'error'});
|
||
return;
|
||
}
|
||
$this.courseInfo=rs.result.course;
|
||
//$this.scoreInfo.score=rs.result.course.score;
|
||
//处理老师数据
|
||
if(rs.result.teachers && rs.result.teachers.length > 0) {
|
||
let userIds = [];
|
||
//let ctoUsers = [];
|
||
rs.result.teachers.forEach(item => {
|
||
item.followed=false;
|
||
item.name= '';
|
||
item.orgInfo= '';
|
||
item.avatar= '';
|
||
item.code= '';
|
||
item.sex=null;
|
||
userIds.push(item.teacherId);
|
||
//检查是否已关注
|
||
apiUserFollow.has(item.teacherId).then(followRs=>{
|
||
if(followRs.status==200 && followRs.result){
|
||
item.followed=true;
|
||
}
|
||
})
|
||
});
|
||
|
||
$this.loadAuthorInfo(rs.result.teachers, userIds);
|
||
$this.teachers=rs.result.teachers;
|
||
}
|
||
|
||
let showConId=this.initContentId;
|
||
//console.log(showConId,'showConId');
|
||
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);
|
||
})
|
||
}
|
||
//定位初始化数据
|
||
rs.result.contents.forEach((c,cidx) => {
|
||
if(showConId!='' && c.id==showConId){
|
||
$this.curContent=c;
|
||
}
|
||
})
|
||
|
||
}
|
||
this.contentList=rs.result.contents;//内容列表
|
||
this.totalContent=rs.result.contents.length;//一共有向个可以播放的内容
|
||
this.sectionList=rs.result.sections;
|
||
//处理学习内容
|
||
this.studyId = rs.result.studyId;
|
||
this.contentList.forEach(con=>{
|
||
rs.result.contentStudys.forEach((scon,sconIdx)=>{
|
||
//第一条就是最近学习的
|
||
if(sconIdx==0 && $this.initContentId==''){
|
||
//$this.curContent=con;
|
||
//查询对应的章节
|
||
}
|
||
if(scon.contentId==con.id){
|
||
con.lastStudyTime = scon.lastStudyTime;
|
||
//以下判断是为了兼容之前的问题,学习状态
|
||
if(scon.status){
|
||
con.status = scon.status;
|
||
}else{
|
||
con.status = 9;
|
||
}
|
||
con.studyItemId=scon.id;//这个就是学习内容(条目)的id
|
||
}
|
||
})
|
||
});
|
||
//设置正在学习的章节
|
||
if(this.curContent.id){
|
||
this.playContent(this.curContent,0);
|
||
//this.curSection=this.sectionList[0];
|
||
}else{
|
||
let treelist=this.catalogTree;
|
||
//console.log(treelist,'treelist')
|
||
if(treelist.length>0){
|
||
this.curSection=treelist[0].sec;
|
||
this.curContent=treelist[0].children[0];
|
||
}else{
|
||
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;
|
||
// }
|
||
// }
|
||
//this.curContent=this.contentList[0];
|
||
this.playContent(this.curContent,0);
|
||
}
|
||
uni.hideLoading();
|
||
|
||
});
|
||
},
|
||
playContent(con,conIndex,catIndex){
|
||
this.isShowPdt = true
|
||
// 视频设置禁用处理逻辑,如果用户已全部观看完该视频,则设置为能全部拖动的逻辑,把isDrag设置为true即可,同时删除本地存储的数据
|
||
if(con.progressVideo ===1){
|
||
var obj = JSON.parse(con.content)
|
||
obj.isDrag = true
|
||
con.content = JSON.stringify(obj)
|
||
|
||
var time = localStorage.getItem('videoProgressData')
|
||
var arr = time&&JSON.parse(time) || {}
|
||
//alert(con.progressVideo+'--'+con.id + '--'+JSON.stringify(arr))
|
||
delete arr[con.id];
|
||
localStorage.setItem('videoProgressData',JSON.stringify(arr))
|
||
}
|
||
if(con.progressVideo>0 && con.progressVideo !==1){
|
||
var time = localStorage.getItem('videoProgressData')
|
||
var arr = time&&JSON.parse(time) || {}
|
||
arr[con.id] = con.progressVideo
|
||
localStorage.setItem('videoProgressData',JSON.stringify(arr))
|
||
}
|
||
|
||
console.log('更换播放内容 playContent::',con,conIndex,catIndex)
|
||
//对于需要控制学习顺序的
|
||
if(conIndex!=undefined && catIndex!=undefined) {
|
||
if(this.courseInfo.orderStudy) {
|
||
let hasIndex=-1;
|
||
this.scrollList.some((one,idx)=>{
|
||
if(one.id==con.id){
|
||
hasIndex=idx;
|
||
return true;
|
||
}
|
||
return false;
|
||
})
|
||
if(hasIndex>0){
|
||
let pre=this.scrollList[hasIndex-1];
|
||
if(pre.status!=9){
|
||
//uni.showToast({title:'请按顺序学习',type:'fail'});
|
||
this.$refs.messager.show({message:'请按顺序学习',type:'error'});
|
||
return;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//切换播放内容
|
||
this.changePlayRes(con);
|
||
},
|
||
loadReCourses(){
|
||
let dto={
|
||
sysType1:this.courseInfo.sysType1,
|
||
sysType2:this.courseInfo.sysType2,
|
||
sysType3:this.courseInfo.sysType3
|
||
}
|
||
apiCoursePortal.recommendList(dto).then(rs=>{
|
||
if(rs.status==200){
|
||
this.recommendCourses=rs.result;
|
||
}
|
||
})
|
||
},
|
||
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.name= author.name;
|
||
item.orgInfo=cutOrgNamePath(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];
|
||
}
|
||
})
|
||
},
|
||
loadIsData(){
|
||
//加载是否关注,是否收藏,是否评价等
|
||
apiFavorites.has(1,this.courseId).then(rs=>{
|
||
if(rs.status==200 && rs.result){
|
||
this.isFavorite=true;
|
||
}else{
|
||
this.isFavorite=false;
|
||
}
|
||
})
|
||
// 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;
|
||
}
|
||
});
|
||
|
||
},
|
||
//更换播放内容
|
||
changePlayRes(con){
|
||
this.tentative = false;
|
||
this.trueFalse = true;
|
||
this.videoPlayingTime = 0
|
||
this.scormUrl='';//清空地址
|
||
this.articleMore=true;
|
||
this.clearTimeHandle();
|
||
//this.curContent=0;
|
||
// console.log(con,'con');
|
||
this.playerBoxShow=false;
|
||
if(con.contentType==40){
|
||
//如果是文档,需要再次加载pdf
|
||
if(con.content!='' && con.content.indexOf('.pdf')==-1){
|
||
// 先置空,否则会有延迟
|
||
con.content = '';
|
||
apiCourseFile.detail(con.contentRefId).then(cfrs=>{
|
||
if(cfrs.status==200){
|
||
con.content=cfrs.result.previewFilePath;
|
||
//console.log(r.content);
|
||
}else{
|
||
$this.$refs.messager.show({message:'加载pdf课件文件失败',type:'error'});
|
||
}
|
||
});
|
||
}
|
||
}else if(con.contentType==50){ //scorm课件的内容
|
||
|
||
apiCourseFile.detail(con.contentRefId).then(cfrs => {
|
||
if(cfrs.status==200){
|
||
//this.curCFile = cfrs.result;
|
||
//this.scormUrl=cfrs
|
||
let pars='?mode=normal&r='+Math.random();
|
||
pars+='&scormId='+cfrs.result.id;
|
||
pars+='&courseId='+this.courseId;
|
||
pars+='&contentId='+con.id;
|
||
pars+='&studentId='+this.userInfo.aid;
|
||
pars+='&studentName='+encodeURIComponent(this.userInfo.name);
|
||
pars+='&lmsId='+this.studyId;
|
||
pars+='&scoId=';//不指定,scorm模块自动根据学习记录定位
|
||
pars+='&r='+Math.random();//加一个随机数,以便重新加载
|
||
let urlPre=window.location.protocol;
|
||
let configUrl=config.scormPlayer;
|
||
configUrl=urlPre+configUrl.substring(configUrl.indexOf(':')+1);
|
||
|
||
this.scormUrl=configUrl+pars;//播放的首页
|
||
console.log(this.scormUrl,'this.scormUrl')
|
||
|
||
}
|
||
});
|
||
|
||
}else if(con.contentType==52){
|
||
if(con.content.startsWith('\{')){
|
||
this.conLink=JSON.parse(con.content);
|
||
}else{
|
||
this.conLink.url=con.content;
|
||
this.conLink.openType=1;
|
||
}
|
||
if (this.conLink.openType == 2) {
|
||
//新的窗口直接打开
|
||
location.href=this.conLink.url
|
||
}
|
||
} else if(con.contentType==10 || con.contentType==20) {
|
||
if(con.content.startsWith('\{')){
|
||
var d = JSON.parse(con.content)
|
||
// if(d.url=="/course/2024/4/1224670812274712576.mp4") d.isDrag = false
|
||
this.curriculumData=d;
|
||
}else{
|
||
this.curriculumData.url=con.content;
|
||
}
|
||
console.log('this.curriculumData:::',this.curriculumData)
|
||
|
||
this.blobUrl=this.fileBaseUrl+this.curriculumData.url;
|
||
this.blobId = con.id;
|
||
}
|
||
//console.log(con.contentType,'con.contentType');
|
||
this.curContent=con;
|
||
this.catalogShow=false;
|
||
this.scoreInfo.itemId=con.id;
|
||
if(this.curContent.status<2){
|
||
this.curContent.status=2; //设置状态 进行中
|
||
}
|
||
//横向滚动条定位
|
||
let len=0;
|
||
this.scrollList.some((sitem,idx)=>{
|
||
if(sitem.id==con.id){
|
||
len=idx;
|
||
return true;
|
||
}
|
||
return false;
|
||
})
|
||
this.scrollInfo.scrollLeft=len*this.scrollItemWidth+len*6;
|
||
//50事scorm项目单独计时
|
||
if(con.contentType>20 && con.contentType !== 50){
|
||
let $this=this;
|
||
//用户的学习时长,音视频课程学习,单独的处理,不再追加学习时长
|
||
this.isAppendTime = false;
|
||
this.appendStudyOtherHandle = setTimeout(function() {
|
||
// 开始之前把响应式清空
|
||
$this.maxDuration = 0;
|
||
$this.cumulativeDuration = 0;
|
||
// 没有设置默认时长三十分钟,
|
||
$this.maxDuration = con.duration !== 0 ? con.duration * 2 : $this.defaultMaxTime;
|
||
//静默处理
|
||
apiStat.sendEvent({
|
||
"key": "StudyCourse",//课程学习的key
|
||
"title": "学习课程",//事件的标题
|
||
"parameters":"second:15",//second:value,total:value 本次的学习时长
|
||
"content": "学习课程【"+$this.courseInfo.name+"】",//事件的内容
|
||
"objId": $this.courseInfo.id,//课程的id
|
||
"objType": "1",//类型
|
||
"source":"h5",
|
||
"objInfo": ""+$this.courseInfo.name,
|
||
"aid":$this.userInfo.aid, //当前登录人的id
|
||
"aname":$this.userInfo.name,//当前人的姓名
|
||
"status": 1 //状态
|
||
}).then(rs=>{
|
||
if(rs.status !== 200) {
|
||
console.log(rs.message);
|
||
}
|
||
});
|
||
$this.appendStudyOtherTime();
|
||
}, 1000 * 15); //非音视频课程学习,15秒后记录,因为一次记录是60秒
|
||
//this.appendStudyTime();
|
||
//非视频,音频的5秒后学习完成
|
||
if(con.contentType!=50){
|
||
this.handleTimeout = setTimeout(function(){$this.saveStudyInfo();},5000);//5秒后记录学习完成
|
||
}else{
|
||
//scorm课件不记录完成情况,由播放回调记录完成情况
|
||
//当前先保存学习记录,未学习状态
|
||
this.saveScormStudy();
|
||
}
|
||
|
||
}
|
||
},
|
||
followUser(tea){
|
||
//实现关注处理
|
||
if(tea.followed){
|
||
apiUserFollow.remove(tea.teacherId).then(rs=>{
|
||
if(rs.status==200){
|
||
tea.followed=false;
|
||
this.$refs.messager.show({message:'取消关注',type:'success'});
|
||
}else{
|
||
this.$refs.messager.show({message:rs.message,type:'error'});
|
||
}
|
||
})
|
||
}else{
|
||
apiUserFollow.save(tea.teacherId).then(rs=>{
|
||
if(rs.status==200){
|
||
tea.followed=true;
|
||
this.$refs.messager.show({message:'关注成功',type:'success'});
|
||
}else{
|
||
this.$refs.messager.show({message:rs.message,type:'error'});
|
||
}
|
||
})
|
||
}
|
||
|
||
},
|
||
goTop(){
|
||
window.scrollTo(0, 0);
|
||
this.showAllCatalog()
|
||
this.isShowPdt = false
|
||
},
|
||
changeTab(idx){
|
||
this.tabIndex=idx;
|
||
},
|
||
showAllCatalog(){
|
||
this.catalogShow=true;
|
||
//定位目录
|
||
},
|
||
closeAllCatalog(){
|
||
this.catalogShow=false;
|
||
this.isShowPdt = true
|
||
//定位目录
|
||
},
|
||
openScore(){
|
||
//显示评分弹窗
|
||
if(this.scoreInfo.has){
|
||
this.$refs.messager.show({message:'您已评过分',type:'error'});
|
||
return;
|
||
}
|
||
this.scoreInfo.dlgShow=true;
|
||
},
|
||
closeScore(){
|
||
this.scoreInfo.dlgShow=false;
|
||
},
|
||
addScore(){
|
||
if(this.scoreInfo.has){
|
||
this.$refs.messager.show({message:'您已评过分',type:'error'});
|
||
this.scoreInfo.dlgShow=false;
|
||
return;
|
||
}
|
||
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.scoreInfo.dlgShow=false;
|
||
this.scoreInfo.has=true;
|
||
if(this.courseInfo.score==0){
|
||
this.courseInfo.score=postData.score;
|
||
}
|
||
if(this.myScore==0){
|
||
this.myScore=postData.score;
|
||
}
|
||
this.$refs.messager.show({message:'评分成功,谢谢您的评分',type:'success'});
|
||
//发送评分事件
|
||
let event = {
|
||
key: "ScoreCourse", //后台的事件key 发布文章且审核通过
|
||
title: "完成课程评分", //事件的标题
|
||
source:"h5",//移动端是2
|
||
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
|
||
}
|
||
apiStat.sendEvent(event);
|
||
}else{
|
||
this.$refs.messager.show({message:'评分分处理失败,请稍后再试',type:'error'});
|
||
}
|
||
});
|
||
}
|
||
},
|
||
openComment(){
|
||
//打开评论窗口,调用组件内事件
|
||
this.$refs.fiexdbar.openInput();
|
||
},
|
||
refreshComments(){
|
||
this.$refs.comments.loadData(false);
|
||
},
|
||
openShare(){
|
||
//console.log(this.$refs.fiexdbar,'this.$refs.fiexdbar');
|
||
//因为开始是v-if控制的,所以这里获取不到,必须显示时才会获取到,所以需要单独的弄一个分享组件
|
||
this.$refs.comShare.openShare();
|
||
|
||
},
|
||
shareSuccess(rs){
|
||
this.$refs.messager.show({message:'分享成功',type:'success'});
|
||
},
|
||
addFavorite(){
|
||
if(this.loading){
|
||
return;
|
||
}
|
||
this.loading=true;
|
||
uni.showLoading({title:'处理中...'})
|
||
let firstTeacher={};
|
||
if(this.teachers.length>0){
|
||
firstTeacher=this.teachers[0];
|
||
}
|
||
//需要判断是否已点赞,已点赞的不再加
|
||
let postData={
|
||
objType:1,
|
||
objId:this.courseId,
|
||
title:this.courseInfo.name,
|
||
}
|
||
if(this.isFavorite) {// 已经收藏,再次点击取消收藏
|
||
apiFavorites.remove(1,this.courseId).then(res=>{
|
||
this.loading=false;
|
||
if(res.status==200){
|
||
this.isFavorite=false;
|
||
this.$refs.messager.show({message:'已取消收藏',type:'success'});
|
||
}else{
|
||
console.log('取消收藏失败:'+res.message);
|
||
}
|
||
uni.hideLoading();
|
||
})
|
||
} else {
|
||
apiFavorites.save(postData).then(res=>{
|
||
this.loading=false;
|
||
if(res.status==200 && res.result){
|
||
this.isFavorite=true;
|
||
this.$refs.messager.show({message:'已加入收藏',type:'success'});
|
||
//发送消息
|
||
let message={
|
||
content:this.userInfo.name+'收藏了我的课程-'+this.courseInfo.name,
|
||
refId:this.courseInfo.id,
|
||
refType:1,
|
||
source:1,
|
||
pageType:1,
|
||
pageParams:this.courseInfo.id,
|
||
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.$refs.messager.show({message:'收藏失败',type:'error'});
|
||
console.log('加入收藏失败:'+res.message);
|
||
}
|
||
uni.hideLoading();
|
||
})
|
||
}
|
||
},
|
||
praiseContent(){
|
||
//赞和踩只能是一个
|
||
if(this.isTrample){
|
||
this.$refs.messager.show({message:'已踩不能赞了',type:'error'});
|
||
return;
|
||
}
|
||
let postData={
|
||
objType:1,
|
||
objId:this.courseInfo.id,
|
||
title:this.courseInfo.name
|
||
}
|
||
if(this.interactRuning){
|
||
return;
|
||
}
|
||
this.interactRuning=true;
|
||
let firstTeacher={};
|
||
if(this.teachers.length>0){
|
||
firstTeacher=this.teachers[0];
|
||
}
|
||
|
||
if(this.isPraise){
|
||
apiPraises.remove(1,this.courseInfo.id).then(rs=>{
|
||
this.interactRuning=false;
|
||
if(rs.status==200){
|
||
this.$refs.messager.show({message:'已取消点赞',type:'success'});
|
||
this.isPraise=false;
|
||
this.courseInfo.praises--;
|
||
let event = {
|
||
key: "CancelPraise",//点赞
|
||
title: "取消点赞",//事件的标题
|
||
parameters:"author:"+firstTeacher.teacherId,//用户自定义参数 name:value,name:value
|
||
content: "取消点赞课程",//事件的内容
|
||
source:"h5",//移动端是2
|
||
objId: this.courseId,//关联的id
|
||
objType: "1",//关联的类型
|
||
objInfo: this.courseInfo.name,
|
||
aid: this.userInfo.aid, //当前登录人的id
|
||
aname: this.userInfo.name,//当前人的姓名
|
||
status: 1 //状态,直接写1
|
||
}
|
||
apiStat.sendEvent(event);
|
||
}else{
|
||
this.$refs.messager.show({message:'取消点赞失败,请稍后再试',type:'success'});
|
||
}
|
||
})
|
||
}else{
|
||
apiPraises.save(postData).then(rs=>{
|
||
this.interactRuning=false;
|
||
if(rs.status==200){
|
||
this.$refs.messager.show({message:'点赞成功',type:'success'});
|
||
this.isPraise=true;
|
||
this.courseInfo.praises++;
|
||
|
||
let event = {
|
||
key: "Praise",//点赞
|
||
title: "点赞",//事件的标题
|
||
parameters:"author:"+firstTeacher.teacherId,//用户自定义参数 name:value,name:value
|
||
content: "点赞了课程",//事件的内容
|
||
source:"h5",//移动端是2
|
||
objId: this.courseInfo.id,//关联的id
|
||
objType: "1",//关联的类型
|
||
objInfo: this.courseInfo.name,
|
||
aid: this.userInfo.aid, //当前登录人的id
|
||
aname: this.userInfo.name,//当前人的姓名
|
||
status: 1 //状态,直接写1
|
||
}
|
||
apiStat.sendEvent(event);
|
||
let message={
|
||
content:this.userInfo.name+'点赞了我的课程-'+this.courseInfo.name,
|
||
refId:this.courseInfo.id,
|
||
refType:1,
|
||
source:1,
|
||
pageType:1,
|
||
pageParams:this.courseInfo.id,
|
||
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.$refs.messager.show({message:'点赞失败,请稍后再试',type:'success'});
|
||
}
|
||
})
|
||
}
|
||
},
|
||
treadContent(){
|
||
//赞和踩只能是一个
|
||
if(this.isPraise){
|
||
this.$refs.messager.show({message:'已赞不能踩了',type:'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.$refs.messager.show({message:'已取消踩',type:'success'});
|
||
this.isTrample=false;
|
||
this.courseInfo.trampleCount--;
|
||
}else{
|
||
this.$refs.messager.show({message:'取消踩失败,请稍后再试',type:'error'});
|
||
}
|
||
})
|
||
}else{
|
||
apiTrample.trample(this.courseInfo.id).then(rs=>{
|
||
this.interactRuning=false;
|
||
if(rs.status==200){
|
||
this.$refs.messager.show({message:'已踩',type:'success'});
|
||
this.isTrample=true;
|
||
this.courseInfo.trampleCount++;
|
||
}else{
|
||
this.$refs.messager.show({message:'踩失败,请稍后再试',type:'error'});
|
||
}
|
||
})
|
||
}
|
||
},
|
||
scrollHandler(e) {
|
||
//console.log(e);
|
||
this.scrollInfo = e.detail;
|
||
},
|
||
//以下是播放相关的处理
|
||
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":"h5",
|
||
"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);
|
||
}
|
||
});
|
||
}
|
||
},
|
||
//结束追加学习时长
|
||
stopStudyTime(){
|
||
//console.log('停止追加学习时长');
|
||
this.isAppendTime=false;
|
||
//暂停让他为空 从新计时
|
||
this.appendStartTime = null
|
||
if (this.appendHandle != null) {
|
||
window.clearTimeout(this.appendHandle);
|
||
}
|
||
},
|
||
//追加学习时长, flag是否提交到后台
|
||
appendStudyTime() {
|
||
// 暂停的时候重新从十五秒开始
|
||
if(!this.appendStartTime){
|
||
this.appentInterval = 15
|
||
}
|
||
//重新覆盖时间
|
||
this.appendStartTime = new Date();
|
||
//console.log('开始追加学习时长',this.isAppendTime);
|
||
if (this.studyId == '') {
|
||
return;
|
||
}
|
||
if (!this.curContent.id) {
|
||
return;
|
||
}
|
||
//清除之前的
|
||
if(this.appendHandle != null) {
|
||
window.clearTimeout(this.appendHandle);
|
||
}
|
||
if (!this.isAppendTime) {
|
||
return;
|
||
}
|
||
//启动下次追加学习时长
|
||
this.appendHandle = setTimeout(() => {
|
||
let endTime = new Date().getTime();
|
||
this.appentInterval = 60;
|
||
let duration = Math.round((endTime - this.appendStartTime) / 1000);
|
||
this.appendStudyTime();
|
||
this.saveStudyDuration(duration);
|
||
}, this.appentInterval * 1000);
|
||
},
|
||
// appendStudyTime() {
|
||
// //console.log('开始追加学习时长',this.isAppendTime);
|
||
// if (this.studyId == '') {
|
||
// return;
|
||
// }
|
||
// if (!this.curContent.id) {
|
||
// return;
|
||
// }
|
||
// //清除之前的
|
||
// if(this.appendHandle != null) {
|
||
// window.clearTimeout(this.appendHandle);
|
||
// }
|
||
// if (!this.isAppendTime) {
|
||
// this.appendStartTime = null;
|
||
// return;
|
||
// }
|
||
// //首先从本地读取
|
||
// 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 >= 60 ) {
|
||
// this.saveStudyDuration(duration);
|
||
// }
|
||
// return;
|
||
// }
|
||
// //如果当前追加开始时间不为空
|
||
// let now = new Date();
|
||
// let m = now.getTime() - this.appendStartTime.getTime(); //相差的毫秒数
|
||
// let sen = Math.round(m / 1000); //计算秒数
|
||
// // 每次添加的是定时器计时的时间
|
||
// duration = duration + sen;//追加的是秒
|
||
// if (duration >= 60) { //一分钟保存一次
|
||
// this.saveStudyDuration(duration);
|
||
// } else {
|
||
// studyUtil.setStudyDuration(duration); //添加到本地存储中
|
||
// }
|
||
// //重新覆盖时间
|
||
// this.appendStartTime = new Date();
|
||
// //启动下次追加学习时长
|
||
// this.appendHandle = setTimeout(function() {
|
||
// $this.appendStudyTime();
|
||
// }, $this.appentInterval);
|
||
// },
|
||
appendStudyOtherTime() { //非音视频课学习时长的增加,每一分钟保存一次
|
||
//console.log('开始追加学习时长',this.isAppendTime);
|
||
if (this.studyId == '') {
|
||
return;
|
||
}
|
||
|
||
if (!this.curContent.id) {
|
||
return;
|
||
}
|
||
//每一分钟保存一次
|
||
// 取消阅读的每分钟六十秒的计时,最多是设置的时间或默认时间
|
||
let $this=this;
|
||
let startTime = new Date().getTime();
|
||
this.appendStudyOtherHandle = setTimeout(function() {
|
||
let endTime = new Date().getTime();
|
||
let totalTime = Math.round((endTime - startTime) / 1000);
|
||
$this.cumulativeDuration += totalTime;
|
||
if($this.cumulativeDuration <= $this.maxDuration){
|
||
//静默处理
|
||
$this.sendOtherTime(totalTime)
|
||
$this.appendStudyOtherTime();
|
||
}else{
|
||
clearTimeout(this.appendStudyOtherHandle);
|
||
$this.cumulativeDuration = 0;
|
||
$this.maxDuration = 0;
|
||
}
|
||
}, 1000*60);
|
||
|
||
},
|
||
sendOtherTime(totalTime){
|
||
apiStat.sendEvent({
|
||
"key": "StudyCourseOther",//课程学习的key
|
||
"title": "非音视频课内容",//事件的标题
|
||
"parameters":"second:" + totalTime,//second:value 本次的学习时长
|
||
"content": "学习课程",//事件的内容
|
||
"objId": this.courseInfo.id,//课程的id
|
||
"objType": "1",//类型
|
||
"source":"h5",
|
||
"objInfo": ""+this.courseInfo.name,
|
||
"aid":this.userInfo.aid, //当前登录人的id
|
||
"aname":this.userInfo.name,//当前人的姓名
|
||
"status": 1 //状态
|
||
}).then(rs=>{
|
||
if(rs.status != 200) {
|
||
console.log(rs.message);
|
||
}
|
||
});
|
||
},
|
||
//先保存学习的内容,针对于音视频的内容
|
||
saveStudyItem(){
|
||
if(this.curContent.studyItemId) {
|
||
return;//已经有记录的,不需要再保存了
|
||
}
|
||
let params = {
|
||
studyId: this.studyId, //学习id,
|
||
courseId: this.courseId, //课程id,
|
||
contentId: this.curContent.id, //内容id,
|
||
contentType:this.curContent.contentType, //内容id,
|
||
contentName: this.curContent.contentName, //内容名称
|
||
progress: 0,
|
||
lastStudyTime:0,
|
||
status:2,
|
||
studyDuration:0,
|
||
contentTotal: this.totalContent
|
||
};
|
||
apiVideoStudy.saveStudyItem(params).then(res=>{
|
||
if(res.status == 200){
|
||
this.curContent.studyItemId=res.result.id;
|
||
this.curContent.status = 2;//进行中状态
|
||
}else{
|
||
console.log("记录学习失败:" + res.message + "," + res.error);
|
||
}
|
||
});
|
||
},
|
||
finishStudyItem(){ //设置完成学习的内容,针对于音视频的内容
|
||
if(!this.curContent.studyItemId){ //临时方案避免重复调用
|
||
//这种可能没有,不过这里也是为了万中那个1
|
||
!this.tentative && this.saveStudyInfo();
|
||
}else{
|
||
let params={
|
||
itemId:this.curContent.studyItemId,
|
||
studyId:this.studyId,
|
||
courseId:this.courseId,
|
||
cnum:this.totalContent
|
||
}
|
||
apiVideoStudy.finishStudyItem(params).then(res=>{
|
||
if(res.status == 200){
|
||
this.curContent.status = 9;
|
||
this.curContent.progress = 100;
|
||
}else{
|
||
console.log("记录完成学习失败:" + res.message + "," + res.error);
|
||
}
|
||
});
|
||
}
|
||
},
|
||
onFullScreen(e){
|
||
//console.log(e,'e');
|
||
|
||
},
|
||
|
||
onPlayerPause(){
|
||
this.stopStudyTime();
|
||
},
|
||
onPlayerEnded(){
|
||
this.playerBoxShow=true;
|
||
this.stopStudyTime();
|
||
if(this.curContent.status<9){
|
||
this.finishStudyItem();
|
||
}
|
||
},
|
||
onPlayerPlaying(e){
|
||
if(e.detail.currentTime > 2 && this.trueFalse && this.curContent.status < 9){
|
||
let params ={
|
||
studyId: this.studyId,//学习id,
|
||
courseId: this.courseId,//课程id,
|
||
contentId: this.curContent.id,//内容id,
|
||
contentType: this.curContent.contentType,
|
||
contentName: this.curContent.contentName,//内容名称
|
||
progress: 1,
|
||
status: 2,
|
||
contentTotal:this.totalContent
|
||
}
|
||
apiCourseStudy.studyContent(params)
|
||
this.trueFalse = false
|
||
}
|
||
//console.log("当前播放11",itme);
|
||
//console.log("当前播放11"+itme);
|
||
let intTime=parseInt(e.detail.currentTime);
|
||
if(intTime>this.videoPlayingTime){
|
||
this.videoPlayingTime=intTime;
|
||
//判断是否完成
|
||
let completeType=this.curriculumData.completeSetup;
|
||
let completeSecond=this.curriculumData.second;
|
||
if (!completeSecond || completeType == 0) {
|
||
completeSecond = 5; //如果没有就采用默认的时间了
|
||
}
|
||
if (this.curContent.status < 9) { //因为1按进度,2按时长都是计算时间,所以这里直接大于0处理
|
||
if (completeType == 1) {
|
||
let finishPercent=this.curriculumData.setupTage;
|
||
let videDuration=this.curContent.duration;
|
||
let percent =intTime*100/videDuration;
|
||
if (percent >= finishPercent) {
|
||
this.finishStudyItem();
|
||
}
|
||
} else {
|
||
if (intTime >= completeSecond) {
|
||
this.finishStudyItem();
|
||
}
|
||
}
|
||
}
|
||
|
||
}
|
||
//以下是每隔10秒存储一下进度
|
||
let saveTime=Math.floor(intTime%10);
|
||
// console.log(intTime,saveTime,'aa',this.curContent.studyItemId)
|
||
if(this.preTime!=intTime && saveTime==0 && this.curContent.studyItemId!=''){
|
||
this.preTime=intTime;
|
||
this.curContent.lastStudyTime=intTime;
|
||
//记录播放时间
|
||
//console.log('记录播放时间:'+intTime);
|
||
let postData={
|
||
itemId:this.curContent.studyItemId,
|
||
videoTime:intTime
|
||
}
|
||
|
||
//alert(3+'--'+this.curriculumData.isDrag +'---'+this.curContent.progressVideo)
|
||
if(!this.curriculumData.isDrag && this.curContent.progressVideo !=1){
|
||
var time = localStorage.getItem('videoProgressData')
|
||
var arr = time&&JSON.parse(time) || {}
|
||
console.log('this.curContent.progressVideo::',arr[this.blobId],this.curContent.progressVideo,arr[this.blobId])
|
||
if(arr[this.blobId] && this.curContent.progressVideo<arr[this.blobId]) {
|
||
postData.progressVideo = arr[this.blobId]
|
||
postData.contentId = this.curContent.id
|
||
postData.courseId = this.curContent.courseId
|
||
}
|
||
}
|
||
//alert(intTime+'----'+this.videoPlayingTime)
|
||
apiCourseStudy.studyVideoTime(postData).then(rs=>{
|
||
if(rs.status!=200){
|
||
console.log('记录播放时间错误');
|
||
}
|
||
})
|
||
}
|
||
},
|
||
audioPlay(){
|
||
this.isAppendTime=true;//开始记录音视频的学习时长
|
||
this.appendStudyTime();//开始追加学习时长
|
||
// let $this=this;
|
||
// if(this.curContent.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();
|
||
// }
|
||
// }
|
||
},
|
||
audioEnd(){
|
||
this.stopStudyTime();
|
||
if(this.curContent.status<9){
|
||
this.finishStudyItem();
|
||
}
|
||
},
|
||
audioPause(){
|
||
this.stopStudyTime();
|
||
},
|
||
audioPlaying(e,second){
|
||
this.isAppendTime=true;//打开追加载学习时长
|
||
|
||
let intTime=second;//当前播放时间
|
||
let videDuration=e.duration;//音频总时长,秒
|
||
if(!videDuration){
|
||
videDuration=this.curContent.duration;
|
||
}
|
||
//判断是否完成
|
||
let completeType=this.curriculumData.completeSetup;
|
||
let completeSecond=this.curriculumData.second;
|
||
if(!completeSecond){
|
||
completeSecond=5;//如果没有就采用默认的时间了
|
||
}
|
||
if(completeType>0 && this.curContent.status<9){ //因为1按进度,2按时长都是计算时间,所以这里直接大于0处理
|
||
if(completeType==1){
|
||
let finishPercent=this.curriculumData.setupTage;
|
||
let percent =intTime*100/videDuration;
|
||
if(percent>=finishPercent){
|
||
this.finishStudyItem();
|
||
}
|
||
}else{
|
||
if(intTime>=completeSecond){
|
||
this.finishStudyItem();
|
||
}
|
||
}
|
||
}
|
||
//以下是每隔10秒存储一下进度
|
||
let saveTime=Math.floor(intTime%10);
|
||
//console.log(intTime,saveTime,'aa',this.curContent.studyItemId)
|
||
|
||
if(this.preTime!=intTime && saveTime==0 && this.curContent.studyItemId!=''){
|
||
|
||
this.preTime=intTime;
|
||
this.curContent.lastStudyTime=intTime;
|
||
//记录播放时间
|
||
//console.log('记录播放时间:'+intTime);
|
||
let postData={
|
||
itemId:this.curContent.studyItemId,
|
||
videoTime:intTime
|
||
}
|
||
if(!this.curriculumData.isDrag && this.curContent.progressVideo !=1){
|
||
var time = localStorage.getItem('videoProgressData')
|
||
var arr = time&&JSON.parse(time) || {}
|
||
if(arr[this.blobId] && this.curContent.progressVideo<arr[this.blobId]) {
|
||
postData.progressVideo = arr[this.blobId]
|
||
postData.contentId = this.curContent.id
|
||
postData.courseId = this.curContent.courseId
|
||
}
|
||
}
|
||
//alert(this.preTime!=intTime +'---'+ saveTime +'---'+ this.curContent.studyItemId)
|
||
apiCourseStudy.studyVideoTime(postData).then(rs=>{
|
||
if(rs.status!=200){
|
||
console.log('记录播放时间错误');
|
||
}
|
||
})
|
||
}
|
||
},
|
||
saveScormStudy() {
|
||
//只记录SCORM课件的学习
|
||
if(this.curContent.contentType!=50){
|
||
return;
|
||
}
|
||
if(this.curContent.status==9){
|
||
//已学习完的,不用再添加
|
||
return;
|
||
}
|
||
let params ={
|
||
studyId: this.studyId,//学习id,
|
||
courseId: this.courseId,//课程id,
|
||
contentId: this.curContent.id,//内容id,
|
||
contentType: this.curContent.contentType,
|
||
contentName: this.curContent.contentName,//内容名称
|
||
progress: 1,
|
||
status: 2,
|
||
contentTotal:this.totalContent
|
||
}
|
||
apiCourseStudy.studyContent(params).then(res=>{
|
||
if(res.status == 200) {
|
||
this.curContent.status=2;//完成
|
||
this.curContent.studyItemId=res.result;//学习记录id
|
||
}else{
|
||
console.log('记录学习失败:'+res.message+','+res.error);
|
||
}
|
||
})
|
||
},
|
||
//还需要记录播放时间
|
||
saveStudyInfo() { //记录课件学习信息
|
||
this.tentative = true;
|
||
if(this.curContent.contentType>=60){
|
||
//只有在课件页面停留超过5秒才会记录
|
||
return;
|
||
}
|
||
if(this.curContent.status==9){
|
||
//已学习完的,不用再添加
|
||
return;
|
||
}
|
||
let params ={
|
||
studyId: this.studyId,//学习id,
|
||
courseId: this.courseId,//课程id,
|
||
contentId: this.curContent.id,//内容id,
|
||
contentType: this.curContent.contentType,
|
||
contentName: this.curContent.contentName,//内容名称
|
||
progress: 100,
|
||
status: 9,
|
||
contentTotal:this.totalContent
|
||
}
|
||
apiCourseStudy.studyContent(params).then(res=>{
|
||
if(res.status == 200) {
|
||
this.curContent.status=9;//完成
|
||
this.curContent.studyItemId=res.result;//学习记录id
|
||
}else{
|
||
console.log('记录学习失败:'+res.message+','+res.error);
|
||
}
|
||
})
|
||
},
|
||
statusClass(status){
|
||
let statusObj={
|
||
1:'nostart',
|
||
2:'studying',
|
||
9:'finish',
|
||
}
|
||
return statusObj[status]
|
||
},
|
||
showMore(){
|
||
this.articleMore=false;
|
||
}
|
||
}
|
||
}
|
||
</script>
|
||
|
||
<style lang="scss" scoped>
|
||
.concern{
|
||
font-size: 24upx;
|
||
border: 1upx solid #387DF7;
|
||
padding: 3upx 20upx;
|
||
border-radius: 30upx;
|
||
}
|
||
.pinglun{
|
||
/deep/ .comments{
|
||
padding: 0;
|
||
.comments-top{
|
||
display: none;
|
||
}
|
||
|
||
|
||
}
|
||
/deep/ .interact-fixed {
|
||
.interact-bar{
|
||
padding-right: 40upx;
|
||
}
|
||
}
|
||
/deep/ .interact-bar{
|
||
padding-left: 0 !important;
|
||
|
||
}
|
||
/deep/ .field-right{
|
||
width: 0 !important;
|
||
}
|
||
/deep/ .interact-bar-item{
|
||
width: 100% !important;
|
||
.field{
|
||
width: 100% !important;
|
||
}
|
||
}
|
||
// /deep/ .interact-bar{
|
||
// // padding-left: 0;
|
||
// }
|
||
// /deep/ .field{
|
||
// width: 448upx;
|
||
// }
|
||
// /deep/ .field-right{
|
||
// margin-right: 60upx;
|
||
// }
|
||
}
|
||
body{
|
||
background-color: #fff;
|
||
}
|
||
.playbox{
|
||
//padding: 10upx;
|
||
background-color: #fff;
|
||
}
|
||
.contentbox{
|
||
padding: 34upx;
|
||
background-color: #fff;
|
||
}
|
||
.player-box{
|
||
position: absolute;
|
||
// top: 62px;
|
||
// left: 184px;
|
||
width: 200px;
|
||
left: 50%;
|
||
top: 50%;
|
||
transform: translate(-50%, -50%);
|
||
height: 147px;
|
||
background:#a9abb3;
|
||
opacity: 0.8;
|
||
border-radius: 33px;
|
||
text-align: center;
|
||
padding: 20px;
|
||
box-sizing: border-box;
|
||
image{
|
||
width: 40px;
|
||
height: 40px;
|
||
margin: 0px 10px;
|
||
}
|
||
.player-praise{
|
||
margin-top: 5px;
|
||
display: flex;
|
||
// justify-items: center;
|
||
justify-content: center;
|
||
}
|
||
.player-rate{
|
||
margin-top: 20px;
|
||
text-align: center;
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
}
|
||
.tabrow{
|
||
display: flex;
|
||
border-bottom:1px solid rgba(153,153,153,0.14);
|
||
font-size: 28upx;
|
||
position: relative;
|
||
.tabrow-active{
|
||
font-size: 32upx;
|
||
color: #387DF7;
|
||
border-bottom: 4upx solid #007DFF;
|
||
}
|
||
.tabrow-item{
|
||
margin-right: 30upx;
|
||
line-height: 60upx;
|
||
font-weight: 600;
|
||
text{
|
||
padding-bottom: 10upx;
|
||
}
|
||
}
|
||
.player-box-tabrow{
|
||
position: absolute;
|
||
top: -20px;
|
||
right:-20px;
|
||
// left: 184px;
|
||
// width: 200px;
|
||
// left: 50%;
|
||
// top: 50%;
|
||
// transform: translate(-50%, -50%);
|
||
// height: 147px;
|
||
// background:#a9abb3;
|
||
// opacity: 0.8;
|
||
// border-radius: 33px;
|
||
// text-align: center;
|
||
padding: 20px;
|
||
box-sizing: border-box;
|
||
image{
|
||
width: 20px;
|
||
height: 20px;
|
||
vertical-align: middle;
|
||
margin-right: 4px;
|
||
// margin: 0px 10px;
|
||
}
|
||
.player-praise{
|
||
margin-top: 5px;
|
||
display: flex;
|
||
// justify-items: center;
|
||
justify-content: center;
|
||
}
|
||
.player-rate{
|
||
margin-top: 20px;
|
||
text-align: center;
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
}
|
||
}
|
||
.cinfo{
|
||
.cinfo-title{
|
||
min-height: 18upx;
|
||
color:#333333;
|
||
font-size: 32upx;
|
||
padding: 28upx 0upx;
|
||
}
|
||
.cinfo-tag1{
|
||
font-size: 22upx;
|
||
color: #528CEC;
|
||
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: #333333;
|
||
font-size: 28upx;
|
||
}
|
||
.desrow-value{
|
||
color: #666666;
|
||
font-size: 28upx;
|
||
}
|
||
.score{
|
||
color:#FB7303;
|
||
margin-left: 10upx;
|
||
font-weight: 700;
|
||
font-size: 32upx;
|
||
}
|
||
}
|
||
.cinfo-btns{
|
||
display: flex;
|
||
justify-content: center;
|
||
margin-top: 66upx;
|
||
.cinfo-btn{
|
||
flex: 1;
|
||
font-size: 28upx;
|
||
text-align: center;
|
||
color:#999999;
|
||
}
|
||
}
|
||
}
|
||
.citembox1{
|
||
display: flex;
|
||
.citembox1-item{
|
||
width: 50%;
|
||
}
|
||
}
|
||
.citem{
|
||
margin: 10upx;
|
||
.citem-title{
|
||
color: #333333;
|
||
word-break: break-all;
|
||
text-overflow: ellipsis;
|
||
display: -webkit-box;
|
||
overflow: hidden;
|
||
}
|
||
.citem-body{
|
||
background-color: #F7F8F9;
|
||
border-radius: 4upx;
|
||
color: #333333;
|
||
height: 100upx;
|
||
padding: 20upx 30upx;
|
||
word-break: break-all;
|
||
text-overflow: ellipsis;
|
||
display: -webkit-box;
|
||
overflow: hidden;
|
||
-webkit-box-orient: vertical;
|
||
-webkit-line-clamp: 2;
|
||
|
||
}
|
||
|
||
}
|
||
.scroll-item{
|
||
// margin: 3px;
|
||
margin-right: 20upx;
|
||
.scroll-item-sec{
|
||
height: 20px;
|
||
// padding: 10upx;
|
||
margin-bottom: 30upx;
|
||
margin-right: 20upx;
|
||
// word-wrap: break-word;
|
||
// word-break:break-all;
|
||
overflow: hidden;
|
||
text-overflow:ellipsis;
|
||
-webkit-box-orient: vertical;
|
||
-webkit-line-clamp: 1
|
||
}
|
||
.scroll-item-con{
|
||
width: 220rpx;
|
||
display:inline-flex;
|
||
border-radius: 8upx;
|
||
padding: 20upx 30upx;
|
||
min-height: 100upx;
|
||
// line-height: 60rpx;
|
||
background-color: #f4f5f7;
|
||
.scroll-item-name{
|
||
width: 100%;
|
||
height: 76rpx;
|
||
// white-space: pre-wrap;
|
||
word-break:break-all;
|
||
line-height: 40rpx;
|
||
overflow: hidden;
|
||
white-space: pre-wrap;
|
||
text-overflow: ellipsis;
|
||
-webkit-box-orient: vertical;
|
||
display: -webkit-box;
|
||
-webkit-line-clamp: 2;
|
||
font-size: 28upx;
|
||
// margin-bottom: 20upx;
|
||
}
|
||
.scroll-item-type{
|
||
font-size: 26upx;
|
||
display: flex;
|
||
justify-content: flex-start;
|
||
align-items: center;
|
||
line-height: 1;
|
||
.square-border{
|
||
margin-right: 20upx;
|
||
display: flex;
|
||
justify-content: center;
|
||
align-items: center;
|
||
border:1px solid;
|
||
padding: 3px 5px;
|
||
.finish{
|
||
padding: 5upx;
|
||
}
|
||
.nostart{
|
||
padding: 5upx;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
.box-studying{
|
||
//color:#FFB30F;
|
||
color: #387DF7;
|
||
border: 1upx solid rgba(56,125,247,0.14);
|
||
}
|
||
.box-finish{
|
||
color: #3C7EFF;
|
||
}
|
||
.box-nostart{
|
||
color:#EE474A;
|
||
}
|
||
.color-studying{
|
||
// background: #FDF1D7;
|
||
//color: #FFB30F;
|
||
color: #387DF7;
|
||
}
|
||
.color-finish{
|
||
// background: #f3f9ff;
|
||
color: #666666;
|
||
}
|
||
.color-nostart{
|
||
// background: #ffe8e7;
|
||
color: #666666;
|
||
}
|
||
.status-tag{
|
||
height: 40upx;
|
||
width: 44px;
|
||
white-space: nowrap;
|
||
display: inline-block;
|
||
text-align: center;
|
||
line-height: 40upx;
|
||
padding: 2upx 10upx;
|
||
border-radius: 14upx;
|
||
}
|
||
.tag-studying{
|
||
// color: #FFB30F;
|
||
color: #588AFC;
|
||
}
|
||
.tag-finish{
|
||
// color: #00aaff;
|
||
color: #08A890;
|
||
}
|
||
.tag-nostart{
|
||
// color: #ff0000;
|
||
color: #787878;
|
||
}
|
||
.text-ellipsis{
|
||
//display: inline-block;
|
||
max-width: 80%;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
.player-controls-btn {
|
||
position: absolute;
|
||
right: 10px;
|
||
top: 10px;
|
||
display: inline-block;
|
||
color: #e5e5e5;
|
||
padding: 0 0.4rem;
|
||
transition: color 0.3s;
|
||
height: 22px;
|
||
}
|
||
.btn-speed:hover .speed-control {
|
||
// visibility: visible;
|
||
}
|
||
.speed-control {
|
||
position: absolute;
|
||
top: 180px;
|
||
right: -20px;
|
||
transition: visibility 0.3s;
|
||
transform: translate(-50%, -100%);
|
||
}
|
||
.speed-control .speed-control-list {
|
||
list-style: none;
|
||
color: #e5e5e5;
|
||
width: 50px;
|
||
font-size: 12px;
|
||
text-align: left;
|
||
padding: 0px 0px 0px 5px;
|
||
margin: 0;
|
||
overflow: hidden;
|
||
border-radius: 4px;
|
||
background: rgba(21, 21, 21, 0.8);
|
||
}
|
||
.speed-control .speed-control-list .li {
|
||
position: relative;
|
||
display: block;
|
||
height: 25px;
|
||
line-height: 25px;
|
||
}
|
||
.speed-control .speed-control-list .li:hover {
|
||
color: #fff;
|
||
background: rgba(99, 99, 99, 0.8);
|
||
}
|
||
.speed-control .speed-control-list .li.current {
|
||
color: var(--primaryColor);
|
||
}
|
||
.catalog{
|
||
background: #FFFFFF;
|
||
padding:20upx;
|
||
.catalog-sec{
|
||
display: flex;
|
||
justify-content: space-between;
|
||
// border-bottom: 2upx solid #FAFAFA;
|
||
// padding:20upx;
|
||
line-height: 40upx;
|
||
.catalog-sec-name{
|
||
max-width: 90%;
|
||
font-weight: 600;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
}
|
||
.catalog-con:last-child{
|
||
border: none;
|
||
}
|
||
.catalog-con{
|
||
display: flex;
|
||
justify-content: space-between;
|
||
padding:30upx 0upx 30upx 30upx;
|
||
padding-right: 0;
|
||
|
||
border-bottom: 1px solid rgba(153,153,153,0.08);
|
||
.square-border{
|
||
display: inline-block;
|
||
border:1px solid;
|
||
padding: 4upx 6upx;
|
||
font-size: 0.8em;
|
||
margin: 0upx 8upx;
|
||
}
|
||
.catalog-con-name{
|
||
padding-left: 0upx;
|
||
white-space: nowrap;
|
||
overflow: hidden;
|
||
text-overflow: ellipsis;
|
||
}
|
||
}
|
||
}
|
||
.dlgscore{ //评分的样式
|
||
.dlgscore-top{
|
||
text-align: center;
|
||
padding: 50upx 100upx 0upx 100upx;
|
||
.dlgscore-title{
|
||
text-align: center;
|
||
font-size: 36upx;
|
||
}
|
||
.dlgscore-desc{
|
||
text-align: center;
|
||
color: #999999;
|
||
font-size: 24upx;
|
||
padding-top: 10upx;
|
||
}
|
||
.dlgscore-score{
|
||
padding-top: 40upx;
|
||
display: flex;
|
||
justify-content: center;
|
||
}
|
||
}
|
||
.dlgscore-btns{
|
||
margin-top: 60upx;
|
||
height: 100upx;
|
||
display: flex;
|
||
justify-content: center;
|
||
border-top: 1px solid rgba(153,153,153,0.14);
|
||
.dlgscore-cancel{
|
||
text-align: center;
|
||
width: 49%;
|
||
border-right:1px solid rgba(153,153,153,0.14);
|
||
line-height: 100upx;
|
||
color: #666666;
|
||
}
|
||
.dlgscore-submit{
|
||
text-align: center;
|
||
width: 50%;
|
||
line-height: 100upx;
|
||
color: #387DF7;
|
||
}
|
||
}
|
||
}
|
||
.about-gongsi-info{overflow: hidden; position: relative;}
|
||
.about-gongsi-info::after{
|
||
content: '';
|
||
position: absolute;
|
||
width: 100%;
|
||
height: 30px;
|
||
background: -webkit-gradient(linear, 0 0, 0 100%, from(rgba(255, 255, 255, 0)), to(rgba(255, 255, 255, 1)));
|
||
background: -moz-linear-gradient(top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
|
||
background: -o-linear-gradient(top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
|
||
background: linear-gradient(top, rgba(255, 255, 255, 0), rgba(255, 255, 255, 1));
|
||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#0ff, endColorstr=#fff, GradientType=0);
|
||
bottom: 0;
|
||
left: 0;
|
||
}
|
||
</style>
|