提交 dc6a4b8d 编写于 作者: guangjun.yang's avatar guangjun.yang

Merge branch 'dev-coursedetail-0817' of...

Merge branch 'dev-coursedetail-0817' of http://192.168.110.53/com.pica.cloud.education.frontend/pica-professional-exam into dev-coursedetail-0817

* 'dev-coursedetail-0817' of http://192.168.110.53/com.pica.cloud.education.frontend/pica-professional-exam:
  排查冲突
  逻辑对接

# Conflicts:
#	src/store/modules/user.js
......@@ -2674,12 +2674,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
......@@ -2694,17 +2696,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"core-util-is": {
"version": "1.0.2",
......@@ -2821,7 +2826,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"ini": {
"version": "1.3.5",
......@@ -2833,6 +2839,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
......@@ -2847,6 +2854,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
......@@ -2854,12 +2862,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
......@@ -2878,6 +2888,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"minimist": "0.0.8"
}
......@@ -2958,7 +2969,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
"dev": true
"dev": true,
"optional": true
},
"object-assign": {
"version": "4.1.1",
......@@ -2970,6 +2982,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"wrappy": "1"
}
......@@ -3091,6 +3104,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
......
<template>
<div class="course-catalog">
<div class="chapter-box">
<div class="chapter-box" v-for="(chapter, index) in list" :key="index">
<div class="head">
<div class="name ellipsis">1.糖尿病的诊断与分型</div>
<div class="total">
4
<img class="arrow" src="~@/images/course/arrow_down.png" />
<div class="name ellipsis">{{ chapter.chapterNameText }}</div>
<div class="total" @click="onToggle(index)">
{{ chapter.lectureNum }}
<img class="arrow" :class="{'arrow-active': chapter.showAll}" src="~@/images/course/arrow_down.png" />
</div>
</div>
<div class="lecture-box">
<div class="item">
<img class="icon" src="~@/images/course/array-right.png" />
<div class="info line">
<p class="subname ellipsis">1.糖尿病的诊断</p>
<p class="time">时长: 03:56</p>
<div class="lecture-box" v-show="chapter.showAll">
<div class="item"
:class="{'item-active': curtId === lecture.lectureId}"
v-for="lecture in chapter.lectures"
:key="lecture.lectureId"
@click="onSelect(lecture, 1)">
<img class="icon" src="~@/images/course/icon_play.png" />
<div class="info-box line">
<div class="info">
<p class="subname ellipsis">{{ lecture.lectureNameText }}</p>
<p class="time">
时长: {{ lecture.totalTimeText }}
<span>{{ lecture.statusText }}</span>
</p>
</div>
<div class="btn" v-if="lecture.btnText">{{ lecture.btnText }}</div>
<img v-else class="lock" src="~@/images/course/lock.png" alt="" />
</div>
<div class="btn">学习</div>
</div>
</div>
</div>
......@@ -31,14 +41,18 @@ export default {
default() {
return []
}
},
curtId: {
type: Number,
default: 0,
},
onToggle: {
type: Function
},
onSelect: {
type: Function
}
},
mounted() {
},
methods: {
}
};
</script>
......@@ -82,24 +96,37 @@ export default {
height: 12px;
transition: all 0.3s;
}
.arrow-active{
transform: rotate(180deg);
}
}
.lecture-box{
.item{
position: relative;
display: flex;
padding: 15px 0 15px 30px;
align-items: center;
padding: 15px 0 0 25px;
}
.item-active{
.subname, .time{
color: #449284;
}
}
.icon{
position: absolute;
left: 0;
top: 18px;
top: 20px;
width: 12px;
}
.info-box{
position: relative;
display: flex;
align-items: center;
padding-bottom: 15px;
}
.info{
position: relative;
flex: 1;
width: 100px;
padding-right: 5px;
}
.line{
&::after{
......@@ -125,8 +152,8 @@ export default {
&::after{
position: absolute;
content: "";
left: 0;
top: 0;
left: -1px;
top: -1px;
width: 200%;
height: 200%;
border: 1px solid #449284;
......@@ -135,6 +162,11 @@ export default {
border-radius: 26px;
}
}
.lock{
display: block;
width: 16px;
margin: 0 22px;
}
.subname{
color: #676869;
font-size: 15px;
......
......@@ -23,6 +23,9 @@
</div>
</div>
</div>
<div class="go-app" @click="download">
<span>打开App,查看更多讨论内容</span>
</div>
</div>
</template>
......@@ -34,6 +37,9 @@ export default {
default() {
return []
}
},
download: {
type: Function
}
},
data() {
......@@ -151,5 +157,18 @@ export default {
.show-arrow-up{
transform: rotate(180deg);
}
.go-app{
color: #449284;
font-size: 14px;
line-height: 14px;
text-align: center;
padding: 20px 0;
span{
display: inline-block;
padding-right: 20px;
background: url('~@/images/course/array-right.png') no-repeat right center;
background-size: 14px auto;
}
}
}
</style>
<template>
<div class="course-covers-wrapper">
<span class="tips" v-html="coverTips"></span>
<div class="tips" v-html="coverTips"></div>
<div v-if="isShowBtn" class="course-button-group">
<CourseButton v-if="!isSingle" type="plain" @btnClick="btnClick(1)" :btnText="leftBtnText"></CourseButton>
<CourseButton @btnClick="btnClick(2)" :btnText="rightBtnText"></CourseButton>
......
......@@ -16,6 +16,10 @@ export default {
url: {
type: String,
default: ""
},
visible: {
type: Boolean,
default: true,
}
},
watch: {
......@@ -64,6 +68,18 @@ export default {
viewport: viewport,
});
box.appendChild(canvas);
if (!this.visible) {
let cover = document.createElement("div");
cover.className = 'canvas-cover';
cover.onclick = () => {
if (!this.$store.getter.logged) {
this.$store.dispatch('goLogin');
return;
}
this.$toast('前往APP购买查看')
}
box.appendChild(cover);
}
this.$el.appendChild(box);
}
}
......@@ -76,7 +92,17 @@ export default {
overflow: hidden;
/deep/ .canvas-box{
position: relative;
padding-bottom: 30px;
margin-bottom: 30px;
}
/deep/ .canvas-cover{
position: absolute;
left: 0;
top: 0;
width: 100%;
height: 100%;
background: url('~@/images/course/lock-big.png') no-repeat center center;
background-size: 50px auto;
background-color: rgba(255, 255, 255, .2);
}
/deep/ canvas{
display: block;
......
......@@ -21,9 +21,9 @@
@error="onError"
>
</video>
<div class="video-cover"></div>
<div class="video-cover" @click="showControl = !showControl"></div>
<!-- 控制栏 -->
<div class="control-box">
<div class="control-box" v-show="showControl">
<div class="control-bar">
<div class="btn-play" :class="{'btn-pause': isPaused}" @click="togglePlay"></div>
<div class="progress-box" @click="setProgress">
......@@ -39,7 +39,7 @@
</div>
</div>
<div class="time-box">{{ playTime }}/{{ totalTime }}</div>
<div class="rate-box" @click="showRate=true">
<!-- <div class="rate-box" @click="showRate=true">
倍速
<div class="rate-list" v-show="showRate">
<div
......@@ -49,7 +49,7 @@
:key="rate"
@click.stop="selectRate(rate)">{{ rate }}</div>
</div>
</div>
</div> -->
<div class="btn-screen" :class="{'btn-screen-mini': isFullScreen}" @click="onFullscreen"></div>
</div>
</div>
......@@ -73,9 +73,10 @@
<slot></slot>
<!-- 试看提示 -->
<div class="proved-box" v-show="showProved">
可试看{{ proved > 59 ? `${parseInt(proved / 60)}分钟` : `${proved}秒` }},激活/购买后可看完整课程
<div class="proved-close" @click="showProved=false"></div>
可试看{{ proved > 59 ? `${parseInt(proved / 60)}分钟` : `${proved}秒` }},观看完整版请来 <span @click="download">云鹊医App</span>
</div>
<!-- 重新播放,只有试看有 -->
<div class="replay-box" v-show="showReplay" @click="onReplay">重新播放</div>
</div>
</template>
......@@ -97,6 +98,12 @@ import { formatLeftTimeObj } from '@/utils';
export default {
name: 'pica-video',
props: {
download: {
type: Function,
default: () => {}
}
},
data() {
return {
url: '', // 视频链接
......@@ -109,6 +116,7 @@ export default {
totalTime: '00:00', // 总时长
isPaused: true, // 是否暂停
isFullScreen: false, // 是否全屏
showControl: true, // 显示控制栏
progressBar: {}, // 进度条
progressBall: 0, // 进度球
rates: [2, 1.5, 1, 0.5],
......@@ -117,6 +125,7 @@ export default {
showProved: false, // 试看提示文字
showError: false, // 播放错误
showResume: false, // 继续播放
showReplay: false, // 显示重播
}
},
computed: {
......@@ -157,10 +166,17 @@ export default {
}
if (isPaused) {
this.player.play();
if (this.opts.proved > 0) {
this.showProved = true;
this.provedTimer && clearTimeout(this.provedTimer);
this.provedTimer = setTimeout(() => {
this.showProved = false;
}, 5000)
}
} else {
this.player.pause();
}
// this.reportOnOff(isPaused ? 1 : 2);
this.reportOnOff(isPaused ? 1 : 2);
this.isPaused = !isPaused;
},
// 切换视频
......@@ -173,12 +189,12 @@ export default {
this.proved = proved;
this.history = history;
this.enable = enable;
this.showProved = proved > 0;
this.provedOver = false;
this.finish = false;
this.opts = opts;
this.currentTime = null;
this.duration = null;
this.showReplay = false;
if (this.showError) this.showError = false;
},
// 切换并播放
......@@ -205,6 +221,14 @@ export default {
}
this.timer = loop();
},
// 重播
onReplay() {
this.player.currentTime = 0;
this.player.play();
this.isPaused = false;
this.reportOnOff(1);
this.$emit('onReplay')
},
// 加载完毕,获取总时长和音量。问题:移动端点击播放才会触发,且不一定会获取时长
loadedMetaData() {
let duration = this.player.duration;
......@@ -275,7 +299,7 @@ export default {
if (this.isPaused) {
this.player.play();
this.isPaused = false;
// this.reportOnOff(1);
this.reportOnOff(1);
}
},
// 拖动进度条
......@@ -323,10 +347,10 @@ export default {
// 试看结束
provedEnd() {
this.provedOver = true;
this.showProved = false;
this.player.pause();
this.$emit('onVideoEnd', { type: 2 });
this.finish = true;
this.showReplay = true;
this.reportOnOff(2);
},
// 播放结束
......@@ -347,7 +371,10 @@ export default {
// 上报播放、暂停,status:1开始,2暂停
reportOnOff(status = 1) {
const { chapterId, courseId, lectureId } = this.opts;
this.$api.pauseCourse({
if (!chapterId || !courseId || !lectureId) {
return;
}
this.POST('/contents/files/resourceRecord', {
fileType: 1,
resourceInfo1: courseId,
resourceInfo2: chapterId,
......@@ -356,7 +383,6 @@ export default {
status,
systemType: 3,
timestamp: Date.now(),
showError: false,
})
},
// 上报离开
......@@ -365,7 +391,10 @@ export default {
return;
}
const { chapterId, courseId, lectureId } = this.opts;
this.$api.joinCourse({
if (!chapterId || !courseId || !lectureId) {
return;
}
this.POST('/contents/joinCourse/', {
requestList: [{
chapterId,
courseId,
......@@ -374,7 +403,6 @@ export default {
time: this.duration,
timeStamp: Date.now(),
}],
showError: false,
})
},
},
......@@ -530,24 +558,16 @@ export default {
position: absolute;
color: #fff;
font-size: 12px;
left: 20px;
bottom: 70px;
height: 30px;
line-height: 30px;
padding: 0 27px 0 31px;
border-radius: 15px;
background: url('~@/images/video/tip.png') no-repeat 12px center;
background-size: 14px auto;
background-color: #373839;
}
.proved-close{
position: absolute;
right: 0;
top: 0;
width: 30px;
height: 30px;
background: url('~@/images/video/close.png') no-repeat 10px center;
background-size: 10px auto;
left: 10px;
bottom: 44px;
height: 24px;
line-height: 24px;
padding: 0 12px;
border-radius: 12px;
background-color: rgba(0, 0, 0, .6);
span{
color: #FFA34B;
}
}
.cover-play{
background: url('~@/images/video/cover_play.png') no-repeat center center;
......@@ -565,6 +585,20 @@ export default {
transform: translate3d(0, -50%, 0);
}
}
.replay-box{
position: absolute;
color: #fff;
font-size: 12px;
right: 10px;
bottom: 44px;
height: 24px;
line-height: 24px;
padding: 0 12px 0 22px;
border-radius: 12px;
background: url('~@/images/video/replay.png') no-repeat left center;
background-size: 23px auto;
background-color: rgba(0, 0, 0, .6);
}
.cover{
position: absolute;
left: 0;
......
......@@ -53,13 +53,30 @@ const router = new VueRouter({
}
})
router.beforeEach((to, from, next) => {
let query = { ...to.query };
// 过滤路由
function fliterRoute(query, path) {
let has = false;
// 登录token保存并替换路径
if (query.token && query.token != 'undefined') {
store.dispatch('setToken', query.token);
delete query.token;
next({ path: to.path, query: query, replace: true });
has = true;
}
// 课程详情页去掉projectId
if (path === '/course-detail' && query.projectId) {
sessionStorage.setItem('projectId', query.projectId);
delete query.projectId;
has = true;
}
return [query, has];
}
router.beforeEach((to, from, next) => {
let query = { ...to.query };
// 登录token保存并替换路径
let [newQuery, has] = fliterRoute(query, to.path);
if (has) {
next({ path: to.path, query: newQuery, replace: true });
return;
}
next();
......
......@@ -42,16 +42,16 @@ const user = {
const { certifyDoc, isExist } = res.data;
const picapDoctor = res.data.picapDoctor || {};
if (picapDoctor.id) {
let avatar = picapDoctor.avatar_image_url || '';
// let avatar = picapDoctor.avatar_image_url || '';
let avatarUrl = '';
const img1 = await preLoadImg(`https://test-file.yunqueyi.com${avatar}`).catch(err => console.error(err));
const img2 = await preLoadImg(`https://file.yunqueyi.com${avatar}`).catch(err => console.error(err));
if (img1) {
avatarUrl = img1.src;
}
if (img2) {
avatarUrl = img2.src;
}
// const img1 = await preLoadImg(`https://test-file.yunqueyi.com${avatar}`).catch(err => console.log(err));
// const img2 = await preLoadImg(`https://file.yunqueyi.com${avatar}`).catch(err => console.log(err));
// if (img1) {
// avatarUrl = img1.src;
// }
// if (img2) {
// avatarUrl = img2.src;
// }
picapDoctor.avatar = avatarUrl || 'https://file.yunqueyi.com/File/doctor_default.png';
commit('SET_USER_INFO', { ...picapDoctor, isExist, certifyDoc });
}
......
此差异已折叠。
Markdown 格式
0% or
您添加了 0 到此讨论。请谨慎行事。
先完成此消息的编辑!
想要评论请 注册