Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
L
learn-online-pc
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
learn-online-pc
Commits
8fd66672
提交
8fd66672
authored
4月 14, 2020
作者:
王鹏飞
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
add viewer module
上级
2e07d544
隐藏空白字符变更
内嵌
并排
正在显示
14 个修改的文件
包含
791 行增加
和
10 行删除
+791
-10
.eslintrc
client/.eslintrc
+2
-1
index.html
client/src/index.html
+2
-2
index.js
client/src/modules/viewer/api/index.js
+35
-0
play-icons.png
client/src/modules/viewer/assets/play-icons.png
+0
-0
aside.vue
client/src/modules/viewer/components/aside/aside.vue
+81
-0
asideChapter.vue
client/src/modules/viewer/components/aside/asideChapter.vue
+132
-0
asideLecture.vue
client/src/modules/viewer/components/aside/asideLecture.vue
+48
-0
player.vue
client/src/modules/viewer/components/player/player.vue
+138
-0
pptPlayer.vue
client/src/modules/viewer/components/player/pptPlayer.vue
+152
-0
videoPlayer.vue
client/src/modules/viewer/components/player/videoPlayer.vue
+60
-0
index.vue
client/src/modules/viewer/index.vue
+133
-0
courseDetail.vue
client/src/pages/learn/courseDetail.vue
+4
-4
index.vue
client/src/pages/player/index.vue
+2
-2
routes.js
client/src/router/routes.js
+2
-1
没有找到文件。
client/.eslintrc
浏览文件 @
8fd66672
...
@@ -10,7 +10,8 @@
...
@@ -10,7 +10,8 @@
},
},
"rules": {
"rules": {
"no-new": "off",
"no-new": "off",
"no-debugger": "off"
"no-debugger": "off",
"space-before-function-paren": "off"
},
},
"globals": {
"globals": {
"CKEDITOR": false,
"CKEDITOR": false,
...
...
client/src/index.html
浏览文件 @
8fd66672
...
@@ -7,7 +7,7 @@
...
@@ -7,7 +7,7 @@
<title></title>
<title></title>
<meta
name=
"viewport"
id=
"viewport"
content=
"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, shrink-to-fit=no"
>
<meta
name=
"viewport"
id=
"viewport"
content=
"width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, shrink-to-fit=no"
>
<!-- 直接引入aliyun播放插件 CSS -->
<!-- 直接引入aliyun播放插件 CSS -->
<link
rel=
"stylesheet"
href=
"https://g.alicdn.com/de/prismplayer/2.8.
2
/skins/default/aliplayer-min.css"
/>
<link
rel=
"stylesheet"
href=
"https://g.alicdn.com/de/prismplayer/2.8.
8
/skins/default/aliplayer-min.css"
/>
</head>
</head>
<body>
<body>
<div
id=
"app"
></div>
<div
id=
"app"
></div>
...
@@ -23,7 +23,7 @@
...
@@ -23,7 +23,7 @@
<script
type=
"text/javascript"
src=
"https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/common/jQuery-2.1.4.min.js"
></script>
<script
type=
"text/javascript"
src=
"https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/common/jQuery-2.1.4.min.js"
></script>
<script
type=
"text/javascript"
src=
"https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/common/runtime.js"
></script>
<script
type=
"text/javascript"
src=
"https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/common/runtime.js"
></script>
<!-- 直接引入aliyun播放插件 JS -->
<!-- 直接引入aliyun播放插件 JS -->
<script
type=
"text/javascript"
charset=
"utf-8"
src=
"https://g.alicdn.com/de/prismplayer/2.8.
2
/aliplayer-min.js"
></script>
<script
type=
"text/javascript"
charset=
"utf-8"
src=
"https://g.alicdn.com/de/prismplayer/2.8.
8
/aliplayer-min.js"
></script>
<script
type=
"text/javascript"
charset=
"utf-8"
src=
"https://player.alicdn.com/aliplayer/presentation/js/aliplayercomponents.min.js"
></script>
<script
type=
"text/javascript"
charset=
"utf-8"
src=
"https://player.alicdn.com/aliplayer/presentation/js/aliplayercomponents.min.js"
></script>
<!-- 解决iframe嵌套,CC视频在safri中打开免登陆兼容问题 -->
<!-- 解决iframe嵌套,CC视频在safri中打开免登陆兼容问题 -->
<script
src=
"//view.csslcloud.net/js/_fix_.js"
></script>
<script
src=
"//view.csslcloud.net/js/_fix_.js"
></script>
...
...
client/src/modules/viewer/api/index.js
0 → 100644
浏览文件 @
8fd66672
import
BaseAPI
from
'@/api/base_api'
const
httpRequest
=
new
BaseAPI
(
webConf
)
/**
* 获取课程详情
* @param {string} courseId 课程ID
* @param {string} semesterId 学期ID
*/
export
function
getCourse
(
courseId
,
semesterId
)
{
return
httpRequest
.
get
(
`/v2/education/courses/
${
courseId
}
/
${
semesterId
}
`
)
}
/**
* 获取章节资源详情
* @param {string} vid 资源ID
*/
export
function
getChapterVideo
(
vid
)
{
return
httpRequest
.
post
(
'/v2/education/video-streaming'
,
{
vid
},
{
headers
:
{
'Content-Type'
:
'application/json'
}
}
)
}
/**
* 获取章节资源详情
* @param {string} vid 章节的资源ID
*/
export
function
getChapterVideoAliyun
(
vid
)
{
return
httpRequest
.
post
(
'/v2/education/aliyun-video-streaming'
,
{
vid
},
{
headers
:
{
'Content-Type'
:
'application/json'
}
}
)
}
client/src/modules/viewer/assets/play-icons.png
0 → 100644
浏览文件 @
8fd66672
2.7 KB
client/src/modules/viewer/components/aside/aside.vue
0 → 100644
浏览文件 @
8fd66672
<
template
>
<div
class=
"course-viewer-aside"
>
<el-tabs
v-model=
"activeName"
>
<el-tab-pane
label=
"章节"
name=
"0"
>
<div
class=
"tab-pane"
>
<aside-chapter
:data=
"chapters"
></aside-chapter>
</div>
</el-tab-pane>
<el-tab-pane
label=
"讲义"
name=
"1"
>
<div
class=
"tab-pane"
>
<aside-lecture
:data=
"ppts"
></aside-lecture>
</div>
</el-tab-pane>
</el-tabs>
</div>
</
template
>
<
script
>
import
AsideChapter
from
'./asideChapter.vue'
import
AsideLecture
from
'./asideLecture.vue'
export
default
{
props
:
{
// 章节
chapters
:
{
type
:
Array
,
default
()
{
return
[]
}
},
// 讲义
ppts
:
{
type
:
Array
,
default
()
{
return
[]
}
}
},
components
:
{
AsideChapter
,
AsideLecture
},
data
()
{
return
{
activeName
:
'0'
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.course-viewer-aside
{
width
:
350px
;
min-height
:
100vh
;
background-color
:
#232323
;
}
.tab-pane
{
height
:
calc
(
100vh
-
56px
);
overflow-y
:
auto
;
}
::v-deep
.el-tabs__header
{
margin
:
0
;
}
::v-deep
.el-tabs__nav
{
float
:
none
;
display
:
flex
;
}
::v-deep
.el-tabs__item
{
flex
:
1
;
height
:
56px
;
font-size
:
16px
;
line-height
:
56px
;
color
:
#909090
;
text-align
:
center
;
&
.is-active
{
color
:
#b49441
;
}
}
::v-deep
.el-tabs__active-bar
,
::v-deep
.el-tabs__nav-wrap
::after
{
display
:
none
;
}
</
style
>
client/src/modules/viewer/components/aside/asideChapter.vue
0 → 100644
浏览文件 @
8fd66672
<
template
>
<ul
class=
"chapter-list"
>
<li
class=
"chapter-item"
v-for=
"item in list"
:key=
"item.id"
>
<h4>
{{
item
.
name
}}
</h4>
<ul
class=
"knot-list"
>
<li
v-for=
"subItem in item.children"
:key=
"subItem.id"
@
click=
"onClick(subItem)"
>
<span
class=
"knot-name"
>
{{
subItem
.
name
|
showName
(
subItem
.
type
)
}}
</span>
</li>
</ul>
</li>
</ul>
</
template
>
<
script
>
export
default
{
props
:
{
data
:
{
type
:
Array
,
default
()
{
return
[]
}
}
},
data
()
{
return
{
otherList
:
[
{
name
:
'大作业及资料'
,
children
:
[
{
name
:
'课程大作业'
,
id
:
'course_work'
},
{
name
:
'课程资料'
,
id
:
'course_info'
},
{
name
:
'教学评估'
,
id
:
'teach_evaluation'
}
]
}
]
}
},
computed
:
{
list
()
{
return
this
.
data
.
concat
(
this
.
otherList
)
}
},
filters
:
{
showName
(
name
,
type
)
{
return
name
}
},
methods
:
{
onClick
(
data
)
{
console
.
log
(
data
)
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
/* 章列表样式 */
.chapter-list
{
margin
:
0
;
padding
:
0
;
line-height
:
1
.6
;
overflow
:
hidden
;
.chapter-item
{
h4
{
padding
:
10px
32px
;
margin
:
0
;
font-size
:
15px
;
color
:
#b0b0b0
;
background-color
:
#2f2f2f
;
}
/* 节列表样式 */
.knot-list
{
margin
:
0
;
padding
:
0
;
line-height
:
1
.6
;
overflow
:
hidden
;
li
{
position
:
relative
;
&
.on
{
background
:
#3c3c3c
;
a
{
color
:
#b49441
;
}
}
&
:hover
{
background
:
#3c3c3c
;
}
&
:before
{
display
:
block
;
content
:
''
;
position
:
absolute
;
left
:
13px
;
top
:
16px
;
z-index
:
10
;
width
:
18px
;
height
:
18px
;
background
:
#5b5b5b
;
border
:
2px
solid
#5b5b5b
;
border-radius
:
50%
;
}
&
:after
{
display
:
block
;
content
:
''
;
position
:
absolute
;
left
:
22px
;
top
:
0
;
z-index
:
5
;
width
:
1px
;
height
:
100px
;
background
:
#616161
;
}
}
.knot-name
{
display
:
block
;
padding
:
15px
35px
15px
40px
;
font-size
:
14px
;
color
:
#909090
;
text-decoration
:
none
;
cursor
:
pointer
;
}
}
/* 章节后面小图标的样式 */
.el-icon
{
position
:
absolute
;
font-size
:
16px
;
right
:
10px
;
top
:
50%
;
transform
:
translateY
(
-50%
);
}
}
}
</
style
>
client/src/modules/viewer/components/aside/asideLecture.vue
0 → 100644
浏览文件 @
8fd66672
<
template
>
<ul
class=
"lecture-list"
>
<li
v-for=
"item in data"
:key=
"item.id"
@
click=
"onClick(item)"
>
<img
:src=
"item.ppt_url"
/>
</li>
</ul>
</
template
>
<
script
>
export
default
{
props
:
{
data
:
{
type
:
Array
,
default
()
{
return
[]
}
}
},
data
()
{
return
{
activeIndex
:
0
}
},
methods
:
{
// 点击PPT
onClick
(
data
)
{
this
.
activeIndex
=
data
.
id
this
.
$emit
(
'clickPPT'
,
data
)
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.lecture-list
{
padding
:
0
16px
;
li
{
padding
:
8px
16px
;
cursor
:
pointer
;
&
.is-active
{
background
:
#888
;
}
img
{
width
:
100%
;
}
}
}
</
style
>
client/src/modules/viewer/components/player/player.vue
0 → 100644
浏览文件 @
8fd66672
<
template
>
<div
class=
"player"
>
<div
class=
"player-main"
>
<div
class=
"player-column"
v-show=
"videoVisible"
>
<!-- 视频 -->
<video-player
:video=
"video"
></video-player>
</div>
<div
class=
"player-column"
v-if=
"pptVisible"
>
<!-- ppt -->
<ppt-player
:ppts=
"ppts"
@
close=
"pptVisible = false"
@
fullscreen=
"onPPTFullscreen"
></ppt-player>
</div>
</div>
<div
class=
"player-footer"
>
<em
class=
"player-button player-button-download"
v-if=
"pdf"
>
<a
:href=
"pdf"
target=
"_blank"
>
下载PPT
</a>
</em>
<em
:class=
"pptClass"
@
click=
"togglePPTVisible"
v-if=
"ppts.length"
>
同步显示PPT
</em>
<em
:class=
"skipClass"
@
click=
"toggleSkip"
>
始终跳过片头
</em>
</div>
</div>
</
template
>
<
script
>
import
videoPlayer
from
'./videoPlayer.vue'
import
pptPlayer
from
'./pptPlayer.vue'
export
default
{
name
:
'Player'
,
components
:
{
videoPlayer
,
pptPlayer
},
props
:
{
video
:
{
type
:
Object
},
pdf
:
{
type
:
String
},
ppts
:
{
type
:
Array
,
default
()
{
return
[]
}
}
},
data
()
{
return
{
videoVisible
:
true
,
pptVisible
:
false
,
isSkip
:
false
}
},
computed
:
{
pptClass
()
{
return
{
'player-button'
:
true
,
'player-button-ppt'
:
!
this
.
pptVisible
,
'player-button-ppt__active'
:
this
.
pptVisible
}
},
skipClass
()
{
return
{
'player-button'
:
true
,
'player-button-skip'
:
!
this
.
isSkip
,
'player-button-skip__active'
:
this
.
isSkip
}
}
},
methods
:
{
// 同步显示PPT
togglePPTVisible
()
{
this
.
videoVisible
=
true
this
.
pptVisible
=
!
this
.
pptVisible
},
// 始终跳过片头
toggleSkip
()
{
this
.
isSkip
=
!
this
.
isSkip
},
// PPT全屏
onPPTFullscreen
(
value
)
{
this
.
videoVisible
=
!
value
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.player
{
display
:
flex
;
flex-direction
:
column
;
width
:
100%
;
height
:
100%
;
}
.player-main
{
display
:
flex
;
flex
:
1
;
}
.player-column
{
flex
:
1
;
height
:
100%
;
}
.player-footer
{
display
:
flex
;
align-items
:
center
;
height
:
54px
;
padding
:
0
20px
;
font-size
:
14px
;
color
:
#a0a0a0
;
a
{
color
:
#a0a0a0
;
text-decoration
:
none
;
}
em
{
margin-right
:
40px
;
cursor
:
pointer
;
}
}
.player-button
{
display
:
inline-block
;
color
:
#a0a0a0
;
padding-left
:
25px
;
font-size
:
14px
;
line-height
:
18px
;
margin
:
0
20px
;
background
:
url(../../assets/play-icons.png)
no-repeat
0
0
;
cursor
:
pointer
;
}
.player-button-download
{
background-position
:
0
-240px
;
}
.player-button-ppt
{
background-position
:
0
-240px
;
}
.player-button-ppt__active
{
background-position
:
0
-280px
;
color
:
#b19241
;
}
.player-button-skip
{
background-position
:
0
-160px
;
}
.player-button-skip__active
{
background-position
:
0
-200px
;
color
:
#b19241
;
}
</
style
>
client/src/modules/viewer/components/player/pptPlayer.vue
0 → 100644
浏览文件 @
8fd66672
<
template
>
<div
class=
"ppt-player"
>
<template
v-if=
"ppts.length"
>
<div
class=
"ppt-player-preview"
>
<img
:src=
"pptUrl"
v-if=
"pptUrl"
/>
</div>
<div
class=
"ppt-player-controls"
>
<div
class=
"ppt-player-controls__page"
>
<template
v-if=
"currentIndex >= 0"
>
<i
class=
"el-icon-arrow-left"
@
click=
"prev"
></i>
</
template
>
<
template
v-if=
"currentIndex + 1 < ppts.length"
>
<i
class=
"el-icon-arrow-right"
@
click=
"next"
></i>
</
template
>
</div>
<div
class=
"ppt-player-controls__pages"
>
<span
class=
"is-active"
>
{{currentIndex + 1}}
</span>
/
<span>
{{ppts.length}}
</span>
页
</div>
<div
class=
"ppt-player-controls__tools"
>
<i
:class=
"['el-icon-self-xuexiao', (currentSync ? 'active' : '')]"
@
click=
"onToggleSync"
></i>
<i
class=
"el-icon-self-quanping"
@
click=
"fullscreen"
></i>
<i
class=
"el-icon-self-shipin"
@
click=
"setVideoTime"
></i>
<i
class=
"el-icon-self-guanbi"
@
click=
"$emit('close')"
></i>
</div>
</div>
</template>
</div>
</template>
<
script
>
export
default
{
name
:
'ppt-player'
,
props
:
{
ppts
:
{
type
:
Array
},
index
:
{
type
:
Number
,
default
:
0
},
isSync
:
{
type
:
Boolean
,
default
:
false
}
},
data
()
{
return
{
currentIndex
:
this
.
index
,
currentSync
:
this
.
isSync
,
isFullscreen
:
false
}
},
watch
:
{
index
:
{
handler
(
value
)
{
this
.
currentIndex
=
value
}
}
},
computed
:
{
pptUrl
()
{
return
this
.
ppts
[
this
.
currentIndex
]
?
this
.
ppts
[
this
.
currentIndex
].
ppt_url
:
''
}
},
methods
:
{
gotoIndex
(
index
)
{
this
.
currentIndex
=
index
},
getIndex
(
index
)
{
return
Math
.
min
(
this
.
ppts
.
length
-
1
,
Math
.
max
(
0
,
index
))
},
prev
()
{
this
.
currentIndex
=
this
.
getIndex
(
this
.
currentIndex
-
1
)
this
.
currentSync
=
false
},
next
(
e
)
{
this
.
currentIndex
=
this
.
getIndex
(
this
.
currentIndex
+
1
)
this
.
currentSync
=
false
},
onToggleSync
(
e
)
{
this
.
currentSync
=
!
this
.
currentSync
this
.
currentIndex
=
this
.
currentSync
?
this
.
currentIndex
:
this
.
currentIndex
},
setVideoTime
(
e
)
{
this
.
$emit
(
'onVideoSyncTime'
,
this
.
ppts
[
this
.
currentIndex
].
ppt_point
)
},
// 全屏
fullscreen
()
{
this
.
isFullscreen
=
!
this
.
isFullscreen
this
.
$emit
(
'fullscreen'
,
this
.
isFullscreen
)
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.ppt-player
{
position
:
relative
;
width
:
100%
;
height
:
100%
;
background-color
:
#000
;
}
.ppt-player-preview
{
height
:
100%
;
img
{
width
:
100%
;
height
:
100%
;
object-fit
:
contain
;
}
}
.ppt-player-controls
{
position
:
absolute
;
left
:
0
;
right
:
0
;
bottom
:
0
;
height
:
44px
;
line-height
:
44px
;
padding
:
0
14px
;
background-color
:
rgba
(
0
,
0
,
0
,
0
.5
);
display
:
flex
;
}
.ppt-player-controls__page
{
width
:
90px
;
color
:
#fff
;
i
{
padding
:
0
10px
;
font-size
:
18px
;
cursor
:
pointer
;
}
}
.ppt-player-controls__pages
{
flex
:
1
;
color
:
#fff
;
text-align
:
center
;
}
.ppt-player-controls__pages
.is-active
{
color
:
#d29f29
;
}
.ppt-player-controls__tools
{
float
:
right
;
}
.ppt-player-controls__tools
i
{
color
:
#fff
;
margin
:
0
10px
;
cursor
:
pointer
;
}
.ppt-player-controls__tools
i
.active
,
.ppt-player-controls__tools
i
:hover
{
color
:
#d29f29
;
}
.ppt-player-controls__tools
.icon-rotate
{
font-size
:
1
.125em
;
}
</
style
>
client/src/modules/viewer/components/player/videoPlayer.vue
0 → 100644
浏览文件 @
8fd66672
<
template
>
<div
class=
"video-player"
id=
"player"
></div>
</
template
>
<
script
>
export
default
{
name
:
'VideoPlayer'
,
props
:
{
video
:
Object
},
data
()
{
return
{
player
:
null
}
},
methods
:
{
createPlayer
()
{
const
{
FD
,
LD
,
SD
}
=
this
.
video
this
.
player
=
new
Aliplayer
(
{
id
:
'player'
,
source
:
JSON
.
stringify
({
FD
,
LD
,
SD
}),
width
:
'100%'
,
height
:
'100%'
,
autoplay
:
true
,
isLive
:
false
,
controlBarVisibility
:
'always'
,
components
:
[
{
name
:
'QualityComponent'
,
type
:
AliPlayerComponent
.
QualityComponent
}
]
},
function
(
player
)
{
console
.
log
(
'The player is created'
)
/* Register the sourceloaded of the player, query the resolution of the video, invoke the resolution component, and call the setCurrentQuality method to set the resolution. */
player
.
on
(
'sourceloaded'
,
function
(
params
)
{
var
paramData
=
params
.
paramData
var
desc
=
paramData
.
desc
var
definition
=
paramData
.
definition
player
.
getComponent
(
'QualityComponent'
)
.
setCurrentQuality
(
desc
,
definition
)
})
}
)
}
},
mounted
()
{
this
.
createPlayer
()
},
beforeDestroy
()
{
this
.
player
&&
this
.
player
.
dispose
()
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.video-player
{
width
:
100%
;
height
:
100%
;
}
</
style
>
client/src/modules/viewer/index.vue
0 → 100644
浏览文件 @
8fd66672
<
template
>
<div
class=
"course-viewer"
>
<div
class=
"course-viewer-main"
>
<!-- 顶部区域 -->
<div
class=
"course-viewer-hd"
>
<router-link
to=
"/mobile/help/student"
>
<i
class=
"el-icon-arrow-left"
></i>
</router-link>
<h1
class=
"course-viewer-hd__title"
>
{{
detail
.
course_name
}}
</h1>
<router-link
to=
"/app/account/feedbackCreate"
target=
"_blank"
>
<el-tooltip
effect=
"light"
content=
"意见反馈"
>
<i
class=
"el-icon-self-fankuiyijian"
></i>
</el-tooltip>
</router-link>
<router-link
to=
"/mobile/help/student"
target=
"_blank"
>
<el-tooltip
effect=
"light"
content=
"帮助"
>
<i
class=
"el-icon-self-icon-test"
></i>
</el-tooltip>
</router-link>
</div>
<!-- 主体区域 -->
<div
class=
"course-viewer-bd"
>
<player
:video=
"chatperResources.video"
pdf=
"https://img1.ezijing.com/ppts/6437335122927681536/PPT_3.2%20%E6%A1%88%E4%BE%8B%E7%A0%94%E7%A9%B6%E6%96%B9%E6%B3%95%EF%BC%88%E4%B8%80%EF%BC%89.pdf"
:ppts=
"chatperResources.ppts"
v-if=
"chatperResources.video"
/>
</div>
</div>
<!-- 侧边栏 -->
<v-aside
:chapters=
"detail.chapters"
:ppts=
"chatperResources.ppts"
></v-aside>
</div>
</
template
>
<
script
>
// api
import
*
as
api
from
'./api/index'
// components
import
VAside
from
'./components/aside/aside.vue'
import
Player
from
'./components/player/player.vue'
export
default
{
name
:
'CourseViewer'
,
components
:
{
VAside
,
Player
},
data
()
{
return
{
detail
:
{},
chatperResources
:
{}
}
},
computed
:
{
// 当前章节
activeChapter
()
{
return
{
resource_id
:
'6414747439944695808'
}
},
// 视频资源ID
resourceId
()
{
return
this
.
activeChapter
.
resource_id
},
/**
* 视频提供者
* @return 1是CC加密; 2是非加密; 3是阿里云
*/
videoProvider
()
{
const
video
=
this
.
activeChapter
.
video
||
{}
return
video
.
video_provider
||
3
}
},
methods
:
{
// 获取课程详情
getCourse
()
{
api
.
getCourse
(
'6437296642994470912'
,
'6437335122927681536'
)
.
then
(
response
=>
{
this
.
detail
=
response
})
},
// 获取章节视频详情
getChapterVideo
()
{
// 视频播放类型 1是CC加密; 2是非加密; 3是阿里云
if
(
this
.
videoProvider
===
3
)
{
api
.
getChapterVideoAliyun
(
this
.
resourceId
).
then
(
response
=>
{
this
.
chatperResources
=
response
})
}
else
{
api
.
getChapterVideo
(
this
.
resourceId
).
then
(
response
=>
{
this
.
chatperResources
=
response
})
}
}
},
beforeMount
()
{
this
.
getCourse
()
this
.
getChapterVideo
()
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.course-viewer
{
display
:
flex
;
background-color
:
#3f3f3f
;
}
.course-viewer-main
{
flex
:
1
;
display
:
flex
;
flex-direction
:
column
;
}
.course-viewer-hd
{
display
:
flex
;
align-items
:
center
;
height
:
56px
;
a
{
color
:
#fff
;
padding
:
10px
;
}
i
{
font-size
:
24px
;
}
}
.course-viewer-hd__title
{
flex
:
1
;
font-size
:
1
.5em
;
text-align
:
center
;
color
:
#a0a0a0
;
}
.course-viewer-bd
{
flex
:
1
;
}
</
style
>
client/src/pages/learn/courseDetail.vue
浏览文件 @
8fd66672
...
@@ -385,10 +385,10 @@ export default {
...
@@ -385,10 +385,10 @@ export default {
}).
catch
(
e
=>
{
this
.
$message
.
error
(
e
.
message
);
loading
.
close
()
}).
finally
(()
=>
{
})
}).
catch
(
e
=>
{
this
.
$message
.
error
(
e
.
message
);
loading
.
close
()
}).
finally
(()
=>
{
})
window
.
addEventListener
(
'resize'
,
this
.
resizeRoot
.
bind
(
this
),
false
)
window
.
addEventListener
(
'resize'
,
this
.
resizeRoot
.
bind
(
this
),
false
)
/* 实时刷新数据 */
/* 实时刷新数据 */
if
(
this
.
timeHeart
)
{
clearInterval
(
this
.
timeHeart
);
this
.
timeHeart
=
null
}
//
if (this.timeHeart) { clearInterval(this.timeHeart); this.timeHeart = null }
this
.
timeHeart
=
setInterval
(()
=>
{
//
this.timeHeart = setInterval(() => {
this
.
updatePages
()
//
this.updatePages()
},
3000
)
//
}, 3000)
},
},
destroyed
()
{
destroyed
()
{
window
.
removeEventListener
(
'resize'
,
this
.
resizeRoot
.
bind
(
this
),
false
)
window
.
removeEventListener
(
'resize'
,
this
.
resizeRoot
.
bind
(
this
),
false
)
...
...
client/src/pages/player/index.vue
浏览文件 @
8fd66672
...
@@ -155,7 +155,7 @@ export default {
...
@@ -155,7 +155,7 @@ export default {
},
},
beforeRouteUpdate
(
to
,
from
,
next
)
{
beforeRouteUpdate
(
to
,
from
,
next
)
{
/* 只有 视频时 才有PPT */
/* 只有 视频时 才有PPT */
if
(
to
.
name
===
'
chapterV
ideo'
)
{
if
(
to
.
name
===
'
v
ideo'
)
{
this
.
state
.
isChapterVideo
=
true
this
.
state
.
isChapterVideo
=
true
const
loading
=
this
.
$loading
({
lock
:
true
,
text
:
''
,
spinner
:
''
,
background
:
'rgba(255, 255, 255, 0.9)'
})
const
loading
=
this
.
$loading
({
lock
:
true
,
text
:
''
,
spinner
:
''
,
background
:
'rgba(255, 255, 255, 0.9)'
})
const
str
=
to
.
params
.
videoType
!==
'3'
?
'getCurrentChapterDetail'
:
'getCurrentChapterDetailAliyun'
const
str
=
to
.
params
.
videoType
!==
'3'
?
'getCurrentChapterDetail'
:
'getCurrentChapterDetailAliyun'
...
@@ -198,7 +198,7 @@ export default {
...
@@ -198,7 +198,7 @@ export default {
},
},
mounted
()
{
mounted
()
{
/* 只有 视频时 才有PPT */
/* 只有 视频时 才有PPT */
if
(
this
.
$route
.
name
===
'
chapterV
ideo'
)
{
if
(
this
.
$route
.
name
===
'
v
ideo'
)
{
this
.
state
.
isChapterVideo
=
true
this
.
state
.
isChapterVideo
=
true
const
loading
=
this
.
$loading
({
lock
:
true
,
text
:
''
,
spinner
:
''
,
background
:
'rgba(255, 255, 255, 0.9)'
})
const
loading
=
this
.
$loading
({
lock
:
true
,
text
:
''
,
spinner
:
''
,
background
:
'rgba(255, 255, 255, 0.9)'
})
const
str
=
this
.
videoType
!==
'3'
?
'getCurrentChapterDetail'
:
'getCurrentChapterDetailAliyun'
const
str
=
this
.
videoType
!==
'3'
?
'getCurrentChapterDetail'
:
'getCurrentChapterDetailAliyun'
...
...
client/src/router/routes.js
浏览文件 @
8fd66672
...
@@ -192,5 +192,6 @@ export default [
...
@@ -192,5 +192,6 @@ export default [
// /* survey-phone 内未找到页面时 - 指向 */
// /* survey-phone 内未找到页面时 - 指向 */
// { path: '/survey-phone/*', redirect: '/learn-error/learn-error' },
// { path: '/survey-phone/*', redirect: '/learn-error/learn-error' },
/* 如果所有页面都没找到 - 指向 */
/* 如果所有页面都没找到 - 指向 */
{
path
:
'*'
,
component
:
()
=>
import
(
'@/components/errorPages/404.vue'
)
}
{
path
:
'*'
,
component
:
()
=>
import
(
'@/components/errorPages/404.vue'
)
},
{
path
:
'/viewer'
,
component
:
()
=>
import
(
'@/modules/viewer/index.vue'
)
}
]
]
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论