Skip to content
项目
群组
代码片段
帮助
当前项目
正在载入...
登录 / 注册
切换导航面板
L
learn-online-pc
项目
项目
详情
活动
周期分析
仓库
仓库
文件
提交
分支
标签
贡献者
图表
比较
统计图
议题
0
议题
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
CI / CD
CI / CD
流水线
作业
日程
统计图
Wiki
Wiki
代码片段
代码片段
成员
成员
折叠边栏
关闭边栏
活动
图像
聊天
创建新问题
作业
提交
问题看板
Open sidebar
EzijingWeb
learn-online-pc
Commits
413dd4a1
提交
413dd4a1
authored
3月 10, 2020
作者:
GOD_ZYX
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
合并 直播部分 进入 sofia
上级
2c8ba80e
全部展开
隐藏空白字符变更
内嵌
并排
正在显示
21 个修改的文件
包含
721 行增加
和
27 行删除
+721
-27
chapterWork.vue
client/client/components/player/chapterWork/chapterWork.vue
+16
-2
index.vue
client/client/components/player/index.vue
+46
-2
live.vue
client/client/components/player/live/live.vue
+100
-0
sideChapterList.vue
...nt/client/components/player/rightSide/sideChapterList.vue
+18
-2
chapter_api.js
client/client/components/services/api/chapter_api.js
+12
-0
login_api.js
client/client/components/services/api/login_api.js
+2
-0
ChapterAction.js
client/client/project/actions/ChapterAction.js
+40
-2
CourseAction.js
client/client/project/actions/CourseAction.js
+32
-1
LoginAction.js
client/client/project/actions/LoginAction.js
+4
-0
sidebar.vue
client/client/project/components/layout/sidebar.vue
+2
-2
index.html
client/client/project/index.html
+4
-0
main.js
client/client/project/main.js
+5
-1
index.vue
client/client/project/pages/mobile/index.vue
+5
-0
list.vue
client/client/project/pages/mobile/list.vue
+304
-0
studentHelp.vue
client/client/project/pages/mobile/studentHelp.vue
+0
-0
teacherHelp.vue
client/client/project/pages/mobile/teacherHelp.vue
+0
-0
rebuild.vue
client/client/project/pages/myGrade/rebuild.vue
+1
-1
course.vue
client/client/project/pages/myLearn/course.vue
+50
-4
courseDetail.vue
client/client/project/pages/myLearn/courseDetail.vue
+43
-5
routes.js
client/client/project/router/routes.js
+33
-1
package.json
client/package.json
+4
-4
没有找到文件。
client/client/components/player/chapterWork/chapterWork.vue
浏览文件 @
413dd4a1
...
...
@@ -43,8 +43,11 @@
<!--
<p
class=
"no-data"
>
暂无数据
</p>
-->
</
template
>
<!-- <p class="text-danger">{this.state.error}</p> -->
<
template
v-if=
"this.deadLine"
>
<p
style=
"color: red"
>
请于截止日期
{{
this
.
deadLine
}}
前提交
</p>
</
template
>
<div
class=
"area-btns"
>
<el-button
type=
"primary"
@
click=
"submitWork"
:disabled=
"
homeData.checker_time
"
>
{{homeData.checker_time ? '已批改' : '提交'}}
</el-button>
<el-button
type=
"primary"
@
click=
"submitWork"
:disabled=
"
!!homeData.checker_time || deadLineFlag
"
>
{{homeData.checker_time ? '已批改' : '提交'}}
</el-button>
<span
class=
"help-info"
>
  
在获老师批改之前,可以多次提交,将以最后一次提交为准
</span>
<
template
v-if=
"homeData.checker_time"
>
<div
class=
"play-paper-check"
>
...
...
@@ -96,7 +99,9 @@ export default {
homeData
:
{},
/* 设置是否可以初始化 ckeditor */
setTime
:
null
,
isInit
:
false
isInit
:
false
,
deadLine
:
''
,
deadLineFlag
:
false
}
},
/* 本组件 仅支持 单个 ckeditor 存在 */
...
...
@@ -143,6 +148,15 @@ export default {
},
50
)
loading
.
close
()
})
setTimeout
(()
=>
{
cAction
.
chapterAction
.
getHomeworkStopTime
(
this
.
sid
,
this
.
cid
,
this
.
chapterId
).
then
(
data
=>
{
this
.
deadLine
=
data
.
dead_line
||
''
let
deadLine
=
data
.
dead_line
?
new
Date
(
data
.
dead_line
).
getTime
()
:
''
// deadLine = new Date().getTime() - 100
this
.
deadLineFlag
=
((
new
Date
().
getTime
()
>
deadLine
)
&&
!!
deadLine
)
// console.log(this.deadLine)
}).
catch
(
e
=>
{
this
.
$message
.
error
(
e
.
message
)
}).
finally
(()
=>
{})
},
500
)
},
submitWork
()
{
if
(
!
this
.
ckeditor
.
getData
())
{
...
...
client/client/components/player/index.vue
浏览文件 @
413dd4a1
...
...
@@ -4,6 +4,16 @@
<div
class=
"play-top cl"
:style=
"(state.sideBar ?
{} : { marginRight: 0 })">
<router-link
class=
"router-link-class"
:to=
"
{ path: `/app/my-learn/course-detail/${sid}/${cid}` }">
<i
class=
"play-back el-icon-arrow-left"
></i></router-link>
<p>
{{
chapterList
.
title
}}
</p>
<router-link
class=
"router-link-class"
id=
"sys-help"
:to=
"
{ path: `/mobile/help/student` }" target="_blank">
<el-tooltip
effect=
"light"
content=
"帮助"
placement=
"bottom-start"
>
<i
class=
"el-icon-self-icon-test"
></i>
</el-tooltip>
</router-link>
<router-link
class=
"router-link-class"
id=
"sys-callback"
:to=
"
{ path: `/app/account/feedbackCreate` }" target="_blank">
<el-tooltip
effect=
"light"
content=
"意见反馈"
placement=
"bottom-start"
>
<i
class=
"el-icon-self-fankuiyijian"
></i>
</el-tooltip>
</router-link>
</div>
<div
class=
"play-content"
>
<router-view
...
...
@@ -21,6 +31,7 @@
@
changeVideoArr=
"changeVideoArr"
@
handlePlayTime=
"handlePlayTime"
@
updateProgress=
"updateProgress"
@
changeSideBar=
"changeSideBar"
></router-view>
</div>
</div>
...
...
@@ -53,7 +64,7 @@
</div>
</div>
<
template
v-if=
"!state.sideBar"
>
<div
class=
"switch"
>
<div
class=
"switch"
id=
"switch-btn"
>
<a
:href=
"('#' + SIDEBAR_CHAPTER)"
class=
"switch-chapter"
@
click=
"changeSideBar(SIDEBAR_CHAPTER)"
>
<i
class=
"el-icon-self-wenjian"
></i>
<div>
章节
</div>
...
...
@@ -385,5 +396,38 @@ export default {
}
}
}
#sys-help
{
display
:
none
;
position
:
absolute
;
top
:
6px
;
right
:
50px
;
/* width: 40px; */
height
:
40px
;
overflow
:
hidden
;
color
:
#fff
;
font-size
:
16px
;
line-height
:
40px
;
text-align
:
center
;
text-decoration
:
none
;
i
{
font-size
:
20px
;
}
}
#sys-callback
{
display
:
none
;
position
:
absolute
;
top
:
6px
;
right
:
15px
;
/* width: 40px; */
height
:
40px
;
overflow
:
hidden
;
color
:
#fff
;
font-size
:
16px
;
line-height
:
40px
;
text-align
:
center
;
text-decoration
:
none
;
i
{
font-size
:
20px
;
}
}
</
style
>
client/client/components/player/live/live.vue
0 → 100644
浏览文件 @
413dd4a1
<
template
>
<iframe
id=
"myIframe"
:src=
"live.url"
frameborder=
"0"
width=
"100%"
height=
"100%"
allow=
"autoplay;geolocation;microphone;camera;midi;encrypted-media;"
></iframe>
</div>
</
template
>
<
script
>
import
cAction
from
'@actions'
export
default
{
props
:
{
sid
:
{
type
:
String
,
require
:
false
},
cid
:
{
type
:
String
,
require
:
false
},
id
:
{
type
:
String
,
require
:
false
}
},
data
()
{
return
{
live
:
{},
ccLive
:
null
}
},
mounted
()
{
this
.
loadAjax
()
},
destroyed
()
{
if
(
window
.
document
.
getElementById
(
'switch-btn'
))
{
window
.
document
.
getElementById
(
'switch-btn'
).
style
.
display
=
'block'
window
.
document
.
getElementById
(
'sys-help'
).
style
.
display
=
'none'
window
.
document
.
getElementById
(
'sys-callback'
).
style
.
display
=
'none'
}
if
(
this
.
ccLive
)
{
this
.
ccLive
.
logout
({
success
:
function
(
res
)
{
},
error
:
function
(
res
)
{
}
})
}
},
methods
:
{
loadAjax
()
{
/* 只能清除本域名下的cookie,不能清除其他域名下的cookie */
// cAction.loginAction.clearCookie({
// cookies: [{
// name: 'sessionid',
// obj: { path: '/', domain: '.csslcloud.net' }
// }, {
// name: 'TGC',
// obj: { path: '/', domain: '.ezijing.com' }
// }]
// }).then().finally(() => {})
const
loading
=
this
.
$loading
({
lock
:
true
,
text
:
''
,
spinner
:
''
,
background
:
'rgba(255, 255, 255, 0.9)'
})
cAction
.
chapterAction
.
getChapterList
(
this
.
cid
,
this
.
sid
,
this
.
id
).
then
(
json
=>
{
this
.
live
=
(
json
.
curJson
&&
json
.
curJson
.
live
)
||
{}
if
(
this
.
live
.
id
)
{
if
(
this
.
live
.
record_id
&&
this
.
live
.
live_status
===
103
)
{
this
.
live
.
url
=
'https://view.csslcloud.net/api/view/callback?recordid='
+
this
.
live
.
record_id
+
'&roomid='
+
this
.
live
.
room_id
+
'&userid='
+
this
.
live
.
user_id
+
'&autoLogin=true&viewername='
+
this
.
live
.
viewer_name
+
'&viewertoken='
+
this
.
live
.
viewer_token
// + '&groupid=xxx'
}
else
{
this
.
$emit
(
'changeSideBar'
,
''
)
setTimeout
(()
=>
{
if
(
window
.
document
.
getElementById
(
'switch-btn'
))
{
window
.
document
.
getElementById
(
'switch-btn'
).
style
.
display
=
'none'
window
.
document
.
getElementById
(
'sys-help'
).
style
.
display
=
'block'
window
.
document
.
getElementById
(
'sys-callback'
).
style
.
display
=
'block'
}
},
1000
)
this
.
live
.
viewer_name
=
window
.
G
.
UserInfo
.
student_info
.
personal_name
||
window
.
G
.
UserInfo
.
nickname
this
.
live
.
url
=
'https://view.csslcloud.net/api/view/index?roomid='
+
this
.
live
.
room_id
+
'&userid='
+
this
.
live
.
user_id
+
'&autoLogin=true&viewername='
+
this
.
live
.
viewer_name
+
'&viewertoken='
+
this
.
live
.
viewer_token
// + '&groupid=xxx'
}
this
.
CCLiveInit
(
this
.
live
)
}
loading
.
close
()
}).
catch
(
e
=>
{
this
.
$message
.
error
(
e
.
message
)
}).
finally
(()
=>
{
})
},
CCLiveInit
(
live
)
{
window
.
DWLive
.
init
({
userid
:
live
.
user_id
,
// 必须参数
roomid
:
live
.
room_id
,
// 必须参数
// groupid: "groupid", // 可选
viewername
:
live
.
viewer_name
,
// 可选
viewertoken
:
live
.
viewer_token
// 如果直播间设置为密码验证,必选
// viewercustomua: 'android', // 可选
// language: 'en', // 可选
// viewercustominfo: '{"exportInfos": [ {"key": "城市", "value": "北京"}, {"key": "姓名", "value": "哈哈"}]}', // 可选
// fastMode:true // 可选参数,默认为true
})
this
.
ccLive
=
window
.
DWLive
}
},
watch
:
{
id
:
{
handler
()
{
this
.
loadAjax
()
}
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
</
style
>
client/client/components/player/rightSide/sideChapterList.vue
浏览文件 @
413dd4a1
...
...
@@ -7,8 +7,12 @@
<ul
class=
"knot-list"
>
<template
v-for=
"(_item, _index) in item.chapters"
>
<li
v-bind:key=
"_index"
:class=
"['knob-item', (_item.id === list.currentChapterId ? 'on' : '')]"
>
<a
:data-vid=
"_item.id"
:data-type=
"_item.video_provider"
:data-hasVA=
'_item.time'
@
click=
'jumpToOtherVA'
:data-index=
'index'
:data-count=
'_index'
class=
"knot-name"
>
{{
_item
.
name
}}
</a>
<i
:class=
"['el-icon', (_item.time ? 'el-icon-self-iconset0481' : (_item.type === 3 ? 'el-icon-edit-outline' : 'el-icon-self-cc-book'))]"
></i>
<a
:data-vid=
"_item.id"
:data-type=
"_item.video_provider"
:data-hasVA=
'_item.time'
@
click=
'jumpToOtherVA'
:data-index=
'index'
:data-count=
'_index'
class=
"knot-name"
>
{{
_item
.
name
+
(
_item
.
type
===
5
?
(
"("
+
_item
.
live
.
statusStr
+
")"
)
:
""
)
}}
</a>
<template
v-if=
"_item.type !== 5"
>
<i
:class=
"['el-icon', (_item.time ? 'el-icon-self-iconset0481' : (_item.type === 3 ? 'el-icon-edit-outline' : 'el-icon-self-cc-book'))]"
></i>
</
template
>
</li>
</template>
</ul>
...
...
@@ -64,6 +68,18 @@ export default {
this
.
$router
.
push
({
path
:
`/survey/
${
sid
}
/
${
cid
}
`
})
}
else
if
(
_course
.
chapters
[
i2
].
type
===
'exam'
)
{
this
.
$router
.
push
({
path
:
`/player/
${
sid
}
/
${
cid
}
/exam/
${
_id
}
`
})
}
else
if
(
_course
.
chapters
[
i2
].
type
===
5
)
{
let
status
=
_course
.
chapters
[
i2
].
live
.
live_status
if
(
status
!==
0
&&
status
!==
1
&&
status
!==
103
)
{
this
.
$message
.
error
(
_course
.
chapters
[
i2
].
live
.
statusStr
)
return
}
let
enableRecord
=
_course
.
chapters
[
i2
].
live
.
enable_record
if
(
status
===
103
&&
enableRecord
!==
undefined
&&
enableRecord
!==
null
&&
!
enableRecord
)
{
this
.
$message
.
info
(
'该直播没有回放'
)
return
}
this
.
$router
.
push
({
path
:
`/player/
${
sid
}
/
${
cid
}
/live/
${
_id
}
`
})
}
return
}
...
...
client/client/components/services/api/chapter_api.js
浏览文件 @
413dd4a1
...
...
@@ -66,6 +66,10 @@ export default class ChapterAPI extends BaseAPI {
* 提交课程 作业或问题
*/
updateHomework
=
(
obj
=
{})
=>
this
.
post
(
'/v2/education/homeworks'
,
obj
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
})
/**
* 课程作业截止时间
*/
getHomeworkStopTime
=
(
sid
,
cid
,
chapterId
)
=>
this
.
get
(
`/v2/education/homeworks/
${
sid
}
/
${
cid
}
/
${
chapterId
}
/deadline`
,
{})
/**
* 获取对应 大作业 回答
* @param {[string]} sid
...
...
@@ -85,4 +89,12 @@ export default class ChapterAPI extends BaseAPI {
* @param {[string]} obj.raw (base64)
*/
updateSurveyAnswer
=
(
obj
)
=>
this
.
post
(
`/v2/education/survey/answer`
,
obj
)
/**
* 手机端 获取实时最新直播接口
*/
getNewLiveMsg
=
(
obj
=
{})
=>
this
.
get
(
`/v2/education/lives/latest`
,
obj
)
/**
* 手机端 获取列表接口
*/
getLiveList
=
(
obj
=
{})
=>
this
.
get
(
`/v2/education/lives/courses`
,
obj
)
}
client/client/components/services/api/login_api.js
浏览文件 @
413dd4a1
...
...
@@ -65,4 +65,6 @@ export default class LoginAPI extends BaseAPI {
* 个人信息 - 上传头像
*/
updatePic
=
(
obj
=
{})
=>
this
.
post
(
'/v3/storage/upload/avatar'
,
obj
,
{
headers
:
{
'Content-Type'
:
'multipart/form-data'
}
})
/* 清cookie - 只能清除请求的同域名下cookie */
clearCookie
=
(
obj
=
{})
=>
this
.
post
(
'/clear/cookie'
,
obj
,
{
headers
:
{
'Content-Type'
:
'application/json'
}
})
}
client/client/project/actions/ChapterAction.js
浏览文件 @
413dd4a1
...
...
@@ -82,9 +82,40 @@ export default class ChapterAction {
homework
:
_homework
,
chapterRead
:
_chapterRead
,
chapterWork
:
_chapterWork
,
chapterVideo
:
_chapterVideo
chapterVideo
:
_chapterVideo
,
live
:
__
.
live
||
''
}
}
if
(
__
.
live
&&
__
.
live
.
id
)
{
let
str
=
''
switch
(
__
.
live
.
live_status
)
{
case
0
:
str
=
'直播未开始'
;
break
case
1
:
str
=
'正在直播'
;
break
case
2
:
str
=
'直播结束'
;
break
case
101
:
str
=
'直播结束,视频剪辑中'
;
break
// 录制开始
case
102
:
str
=
'直播结束,视频剪辑中'
;
break
// 录制结束
case
103
:
str
=
'观看回放'
;
break
default
:
str
=
'直播未开始'
}
// 5分钟内显示“即将开始”,5~1小时内“N分钟后开始”,1~24小时内“N小时后开始”,1天以上“N天后开始”天就显示年月日
if
(
__
.
live
.
live_status
===
0
&&
__
.
live
.
start_time
)
{
let
time
=
(
new
Date
(
__
.
live
.
start_time
).
getTime
()
-
new
Date
().
getTime
())
/
1000
if
(
time
<=
5
*
60
)
{
str
=
'即将开始'
}
else
if
(
time
<=
1
*
60
*
60
)
{
str
=
parseInt
(
time
/
60
)
+
'分钟后开始'
}
else
if
(
time
<=
24
*
60
*
60
)
{
str
=
parseInt
(
time
/
(
60
*
60
))
+
'小时'
+
parseInt
(
time
/
60
%
60
)
+
'分钟后开始'
}
else
{
str
=
parseInt
(
time
/
(
24
*
60
*
60
))
+
'天后开始'
}
}
if
(
__
.
live
.
live_status
===
103
&&
__
.
live
.
enable_record
!==
undefined
&&
__
.
live
.
enable_record
!==
null
&&
!
__
.
live
.
enable_record
)
{
str
=
''
}
__
.
live
.
statusStr
=
str
}
return
{
id
:
__
.
resource_id
,
video_provider
:
(
__
.
video
&&
__
.
video
.
video_provider
)
||
''
,
...
...
@@ -95,7 +126,8 @@ export default class ChapterAction {
homework
:
_homework
,
chapterRead
:
_chapterRead
,
chapterWork
:
_chapterWork
,
chapterVideo
:
_chapterVideo
chapterVideo
:
_chapterVideo
,
live
:
__
.
live
||
''
}
})
}
...
...
@@ -231,8 +263,14 @@ export default class ChapterAction {
updateHomework
(
obj
)
{
return
chapterApi
.
updateHomework
(
obj
).
then
(
res
=>
res
)
}
/* 获取大作业 回答 */
getCourseHomework
(
sid
,
cid
)
{
return
chapterApi
.
getCourseHomework
(
sid
,
cid
).
then
(
res
=>
res
)
}
/* 获取作业截止时间 */
getHomeworkStopTime
(
sid
,
cid
,
chapterId
)
{
return
chapterApi
.
getHomeworkStopTime
(
sid
,
cid
,
chapterId
).
then
(
res
=>
res
)
}
/* 提交大作业 */
updateCourseHomework
(
sid
,
cid
,
obj
)
{
return
chapterApi
.
updateCourseHomework
(
sid
,
cid
,
obj
).
then
(
res
=>
res
)
}
/* 提交课程考核 */
updateSurveyAnswer
(
obj
)
{
return
chapterApi
.
updateSurveyAnswer
(
obj
).
then
(
res
=>
res
)
}
/* 获取当前最新直播提醒 */
getNewLiveMsg
()
{
return
chapterApi
.
getNewLiveMsg
().
then
(
res
=>
res
)
}
/* 获取手机直播列表 */
getLiveList
()
{
return
chapterApi
.
getLiveList
().
then
(
res
=>
res
)
}
}
client/client/project/actions/CourseAction.js
浏览文件 @
413dd4a1
...
...
@@ -108,6 +108,36 @@ export default class CourseAction {
_homework
.
work_id
=
__
.
resource_id
_homework
.
semester_id
=
data
.
semester_id
}
if
(
__
.
live
&&
__
.
live
.
id
)
{
let
str
=
''
switch
(
__
.
live
.
live_status
)
{
case
0
:
str
=
'直播未开始'
;
break
case
1
:
str
=
'正在直播'
;
break
case
2
:
str
=
'直播结束'
;
break
case
101
:
str
=
'直播结束,视频剪辑中'
;
break
// 录制开始
case
102
:
str
=
'直播结束,视频剪辑中'
;
break
// 录制结束
case
103
:
str
=
'观看回放'
;
break
default
:
str
=
'直播未开始'
}
// 5分钟内显示“即将开始”,5~1小时内“N分钟后开始”,1~24小时内“N小时后开始”,1天以上“N天后开始”天就显示年月日
if
(
__
.
live
.
live_status
===
0
&&
__
.
live
.
start_time
)
{
let
time
=
(
new
Date
(
__
.
live
.
start_time
).
getTime
()
-
new
Date
().
getTime
())
/
1000
if
(
time
<=
5
*
60
)
{
str
=
'即将开始'
}
else
if
(
time
<=
1
*
60
*
60
)
{
str
=
parseInt
(
time
/
60
)
+
'分钟后开始'
}
else
if
(
time
<=
24
*
60
*
60
)
{
str
=
parseInt
(
time
/
(
60
*
60
))
+
'小时'
+
parseInt
(
time
/
60
%
60
)
+
'分钟后开始'
}
else
{
str
=
parseInt
(
time
/
(
24
*
60
*
60
))
+
'天后开始'
}
}
if
(
__
.
live
.
live_status
===
103
&&
__
.
live
.
enable_record
!==
undefined
&&
__
.
live
.
enable_record
!==
null
&&
!
__
.
live
.
enable_record
)
{
str
=
''
}
__
.
live
.
statusStr
=
str
}
return
{
cid
:
cur
.
course_id
,
sid
:
cur
.
semester_id
,
...
...
@@ -119,7 +149,8 @@ export default class CourseAction {
name
:
__
.
name
,
type
:
__
.
type
,
work_type
:
(
__
.
homework
&&
__
.
homework
.
work_type
)
||
''
,
homework
:
_homework
homework
:
_homework
,
live
:
__
.
live
||
''
}
})
}
...
...
client/client/project/actions/LoginAction.js
浏览文件 @
413dd4a1
...
...
@@ -99,4 +99,8 @@ export default class LoginAction {
* 调用个人信息 - 上传头像
*/
updatePic
(
obj
)
{
return
loginApi
.
updatePic
(
obj
).
then
(
res
=>
res
)
}
/**
* 清除cookie
*/
clearCookie
(
obj
)
{
return
loginApi
.
clearCookie
(
obj
).
then
(
res
=>
res
)
}
}
client/client/project/components/layout/sidebar.vue
浏览文件 @
413dd4a1
...
...
@@ -85,8 +85,8 @@ export default {
]
},
{
name
:
'
系统
反馈'
,
iconClass
:
'el-icon-
bell
'
,
name
:
'
意见
反馈'
,
iconClass
:
'el-icon-
self-fankuiyijian
'
,
index
:
'3'
}
]
...
...
client/client/project/index.html
浏览文件 @
413dd4a1
...
...
@@ -41,6 +41,10 @@
<!-- 直接引入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://player.alicdn.com/aliplayer/presentation/js/aliplayercomponents.min.js"
></script>
<!-- 解决iframe嵌套,CC视频在safri中打开免登陆兼容问题 -->
<script
src=
"//view.csslcloud.net/js/_fix_.js"
></script>
<script
src=
"//view.csslcloud.net/js/jquery-1.9.0.min.js"
type=
"text/javascript"
></script>
<script
src=
"//view.csslcloud.net/js/sdk/3.1.0/liveSDK.js"
type=
"text/javascript"
></script>
<!--[if lt IE 9]>
<script src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/compatible/console-polyfill.js"></script>
<script src="https://zws-imgs-pub.ezijing.com/static/build/learn-mba/static/compatible/html5shiv.min.js"></script>
...
...
client/client/project/main.js
浏览文件 @
413dd4a1
...
...
@@ -2,6 +2,7 @@ import Vue from 'vue' // 引入vue框架
import
Element
from
'element-ui'
// 引入 element-ui 框架
import
'./components/style/_com.scss'
// 定义 element-ui主题色 + 公共样式
import
VueRouter
from
'vue-router'
// 使用 vue-router
import
MetaInfo
from
'vue-meta-info'
import
createRouter
from
'./router'
// router定义
import
Main
from
'./main.vue'
// 初始化 vue页面
import
UploadForm
from
'../components/upload-form'
...
...
@@ -19,6 +20,7 @@ require('promise.prototype.finally').shim()
Vue
.
use
(
Element
)
Vue
.
use
(
VueRouter
)
Vue
.
use
(
MetaInfo
)
Vue
.
use
(
UploadForm
)
Vue
.
component
(
UploadForm
.
name
,
UploadForm
)
const
router
=
createRouter
()
...
...
@@ -31,7 +33,9 @@ Vue.prototype.$md5 = md5
router
.
beforeEach
((
to
,
from
,
next
)
=>
{
/* 设置 全局变量 */
BeforeRouter
.
globalVariable
.
init
(
Vue
,
{
to
,
from
,
next
})
if
(
to
.
name
!==
'normalLogin'
&&
to
.
name
!==
'codeLogin'
&&
to
.
name
!==
'forgetPwd'
)
{
// 所有登录页 不进行登录校验
if
(
to
.
name
===
'studentHelp'
||
to
.
name
===
'teacherHelp'
)
{
next
()
}
else
if
(
to
.
name
!==
'normalLogin'
&&
to
.
name
!==
'codeLogin'
&&
to
.
name
!==
'forgetPwd'
)
{
// 所有登录页 不进行登录校验
BeforeRouter
.
loginInfo
.
isLogin
(
Vue
).
then
(
str
=>
{
if
(
/^login/gi
.
test
(
str
))
{
next
()
...
...
client/client/project/pages/mobile/index.vue
0 → 100644
浏览文件 @
413dd4a1
<
template
>
<div>
<router-view></router-view>
</div>
</
template
>
client/client/project/pages/mobile/list.vue
0 → 100644
浏览文件 @
413dd4a1
<
template
>
<div
class=
"pages"
>
<div
class=
"head"
>
<img
class=
"logo5"
alt=
"logo"
src=
"../../assets/img/logo-header.png"
>
<div
class=
"userinfo"
>
<div
class=
"login-out"
@
click=
"goOutLogin()"
>
退出
</div>
<div
class=
"name"
>
{{
name
}}
</div>
</div>
</div>
<div
class=
"hint"
v-show=
"latest && latest.live"
@
click=
"opencc(latest)"
>
<div
class=
"left"
>
<div
class=
"left-1"
>
直播提醒
</div>
<div
class=
"left-2"
>
《
{{
latest
.
course_name
}}
》将于
{{
latest
.
live
&&
latest
.
live
.
start_time
.
slice
(
5
)
}}
开始
</div>
</div>
<div
class=
"right"
>
进入直播 >
</div>
</div>
<div
class=
"tips"
>
提示语:已参加的课程请到电脑端学习系统观看回放
</div>
<div
class=
"list-box"
>
<div
class=
"curriculum"
v-for=
"(item, index) in obj"
v-bind:key=
"index"
>
<h4
class=
"curriculum-name"
>
{{
item
.
course_name
}}
</h4>
<div
class=
"curriculum-box"
@
click=
"opencc(item)"
>
<img
class=
"curriculum-picture"
:src=
"item.curriculum.curriculum_picture"
/>
<div
class=
"curriculum-introduce"
>
<div
class=
"title"
>
{{
item
.
curriculum
.
curriculum_name
}}
</div>
<div
class=
"time"
>
{{
item
.
live
?
item
.
live
.
time
:
''
}}
</div>
</div>
</div>
</div>
</div>
</div>
</
template
>
<
script
>
import
cAction
from
'@actions'
export
default
{
data
()
{
return
{
name
:
(
window
.
G
.
UserInfo
&&
window
.
G
.
UserInfo
.
student_info
&&
window
.
G
.
UserInfo
.
student_info
.
personal_name
)
||
'匿名'
,
latest
:
''
,
obj
:
[],
loading
:
null
}
},
metaInfo
()
{
return
{
title
:
'清华大学五道口金融学院'
,
meta
:
[
// { vmid: 'description', name: 'description', content: this.description }
]
}
},
mounted
()
{
const
_this
=
this
this
.
loading
=
this
.
$loading
({
lock
:
true
,
text
:
''
,
spinner
:
''
,
background
:
'rgba(255, 255, 255, 0.9)'
})
this
.
dealRender
()
_this
.
getNewLiveMsg
()
_this
.
getLiveLis
()
setInterval
(
function
()
{
_this
.
getNewLiveMsg
()
_this
.
getLiveLis
()
},
3000
)
},
methods
:
{
/* 退出登录 - 跳转方法 */
goOutLogin
()
{
cAction
.
loginAction
.
outLogin
().
then
(
str
=>
{
if
(
/^login/gi
.
test
(
str
))
{
window
.
G
.
UserInfo
=
{}
// this.$router.push({ path: '/login/index' })
// this.$router.push({ path: '/' })
window
.
location
.
href
=
'https://pbcsf.ezijing.com/login/index'
}
else
{
/* 出错 */
}
}).
catch
(
e
=>
{
this
.
$message
.
error
(
e
.
message
)
})
/* 清空一下记录,然后调整到登录页 */
// this.$router.push({ path: '/login/index' })
},
getNewLiveMsg
:
function
()
{
// 获取最新直播提醒
const
_this
=
this
// const loading = this.$loading({ lock: true, text: '', spinner: '', background: 'rgba(255, 255, 255, 0.9)' })
cAction
.
chapterAction
.
getNewLiveMsg
().
then
(
json
=>
{
if
(
json
.
status
===
200
)
{
_this
.
latest
=
json
.
data
window
.
console
.
log
(
_this
.
latest
)
}
if
(
_this
.
loading
)
{
_this
.
loading
.
close
()
_this
.
loading
=
null
}
}).
catch
(
e
=>
{
this
.
$message
.
error
(
e
.
message
)
}).
finally
(()
=>
{
})
},
getLiveLis
:
function
()
{
// 获取最新直播列表
const
_this
=
this
cAction
.
chapterAction
.
getLiveList
().
then
(
json
=>
{
if
(
json
.
status
===
200
)
{
json
.
data
.
map
(
function
(
item
,
index
,
arr
)
{
if
(
item
.
live
&&
(
item
.
live
.
length
||
item
.
live
.
user_id
))
{
let
_time
=
item
.
live
.
start_time
let
_status
=
item
.
live
.
live_status
let
enableRecord
=
item
.
live
.
enable_record
// 0: 不启用回放 1: 开启回放
let
str
=
''
switch
(
_status
)
{
case
0
:
str
=
'直播未开始'
;
break
case
1
:
str
=
'正在直播'
;
break
case
2
:
str
=
'直播结束'
;
break
case
101
:
str
=
'直播结束,视频剪辑中'
;
break
// 录制开始
case
102
:
str
=
'直播结束,视频剪辑中'
;
break
// 录制结束
case
103
:
str
=
'观看回放'
;
break
default
:
str
=
'直播未开始'
}
if
(
_status
===
103
&&
!
enableRecord
)
str
=
''
if
(
_status
===
0
&&
_time
)
{
_time
=
_time
.
replace
(
/-/g
,
'/'
)
let
time
=
(
new
Date
(
_time
).
getTime
()
-
new
Date
().
getTime
())
/
1000
if
(
time
<=
5
*
60
)
{
str
=
'即将开始'
}
else
if
(
time
<=
1
*
60
*
60
)
{
str
=
parseInt
(
time
/
60
)
+
'分钟后开始'
}
else
if
(
time
<=
24
*
60
*
60
)
{
str
=
parseInt
(
time
/
(
60
*
60
))
+
'小时'
+
parseInt
(
time
/
60
%
60
)
+
'分钟后开始'
}
else
{
str
=
parseInt
(
time
/
(
24
*
60
*
60
))
+
'天后开始'
}
}
item
.
live
.
time
=
str
}
return
item
})
_this
.
obj
=
json
.
data
}
if
(
_this
.
loading
)
{
_this
.
loading
.
close
()
_this
.
loading
=
null
}
}).
catch
(
e
=>
{
this
.
$message
.
error
(
e
.
message
)
}).
finally
(()
=>
{
})
},
dealRender
:
()
=>
{
(
function
(
win
,
doc
)
{
let
wWidth
=
(
win
.
screen
.
width
>
0
)
?
(
win
.
innerWidth
>=
win
.
screen
.
width
||
win
.
innerWidth
===
0
)
?
win
.
screen
.
width
:
win
.
innerWidth
:
win
.
innerWidth
,
wFsize
// eslint-disable-line
wFsize
=
(
wWidth
>
640
?
640
:
wWidth
)
/
375
*
100
// wFsize = wFsize > 32 ? wFsize : 32;
doc
.
documentElement
.
style
.
fontSize
=
wFsize
+
'px'
})(
window
,
document
)
},
opencc
:
function
(
obj
)
{
let
_live
=
obj
.
live
if
(
!
_live
||
!
_live
.
user_id
)
{
this
.
$message
.
error
(
'网络错误,刷新重试'
)
return
}
let
userid
=
_live
.
user_id
let
roomid
=
_live
.
room_id
let
viewertoken
=
_live
.
viewer_token
let
recordid
=
_live
.
record_id
let
liveStatus
=
_live
.
live_status
let
enableRecord
=
_live
.
enable_record
// 0: 不启用回放 1: 开启回放
let
viewername
=
this
.
name
let
_url
=
'https://view.csslcloud.net/api/view'
if
(
recordid
&&
liveStatus
===
103
)
{
if
(
!
enableRecord
)
{
this
.
$message
.
warning
(
'该直播没有回放'
)
return
}
// 可以回放
// https://view.csslcloud.net/api/view/callback?recordid=xxx&roomid=xxx&userid=xxx&autoLogin=true&viewername=xxx&viewertoken=xxx&groupid=xxx
_url
=
_url
+
'/callback?autoLogin=true&roomid='
+
roomid
+
'&userid='
+
userid
+
'&recordid='
+
recordid
+
'&viewername='
+
viewername
+
'&viewertoken='
+
viewertoken
}
else
{
// 可以直播
// https://view.csslcloud.net/api/view/index?roomid=xxx&userid=xxx&autoLogin=true&viewername=xxx&viewertoken=xxx&groupid=xxx
_url
=
_url
+
'/index?autoLogin=true&roomid='
+
roomid
+
'&userid='
+
userid
+
'&viewername='
+
viewername
+
'&viewertoken='
+
viewertoken
}
window
.
console
.
log
(
_url
)
window
.
open
(
_url
,
'_blank'
)
}
}
}
</
script
>
<
style
>
html
{
font-size
:
100px
;
}
body
{
padding
:
0
;
margin
:
0
;
}
.float-left
{
float
:
left
;
}
.float-right
{
float
:
right
;
}
</
style
>
<
style
scoped
>
.pages
{
font-size
:
.14rem
;
padding-top
:
.2rem
;
}
.head
{
height
:
0.48rem
;
padding
:
0
0.2rem
;
}
.head
.logo5
{
width
:
1.18rem
;
height
:
.3rem
;
float
:
left
;
}
.name
{
padding
:
0
0.1rem
;
width
:
1.1rem
;
overflow
:
hidden
;
white-space
:
nowrap
;
text-overflow
:
ellipsis
;
}
.login-out
{
color
:
#999
;
}
.userinfo
{
height
:
0.68rem
;
}
.userinfo
>
div
{
float
:
right
;
}
.hint
{
min-height
:
0.7rem
;
display
:
flex
;
background
:
rgba
(
176
,
28
,
61
,
.1
)
;
padding
:
0
0.2rem
.1rem
;
justify-content
:
space-between
;
font-size
:
.14rem
;
}
.hint
.left
{
flex-grow
:
1
;
display
:
flex
;
flex-direction
:
column
;
padding-right
:
.08rem
;
}
.hint
.left
.left-1
{
height
:
.4rem
;
line-height
:
.4rem
;
}
.hint
.left
.left-2
{
margin-left
:
-
0.08rem
;
}
.hint
.right
{
width
:
.78rem
;
flex-shrink
:
0
;
color
:
#b01c3d
;
align-self
:
center
;
}
.tips
{
height
:
.4rem
;
line-height
:
.4rem
;
padding
:
0
.2rem
;
color
:
#999
;
font-size
:
.14rem
;
overflow
:
hidden
;
}
.list-box
{
padding
:
0
.2rem
;
}
.curriculum
{
width
:
100%
;
padding-top
:
.05rem
;
height
:
1.2rem
;
border-bottom
:
1px
solid
#ccc
;
}
.curriculum-name
{
padding
:
0
;
margin
:
0
;
height
:
.4rem
;
line-height
:
.4rem
;
color
:
#333
;
}
.curriculum-box
{
display
:
flex
;
width
:
100%
;
height
:
.6rem
;
cursor
:
pointer
;
}
.curriculum-picture
{
width
:
.86rem
;
height
:
.6rem
;
}
.curriculum-introduce
{
padding-left
:
10px
;
flex-grow
:
1
;
display
:
flex
;
flex-direction
:
column
;
justify-content
:
space-between
;
}
.curriculum-introduce
.time
{
color
:
#b01c3d
;
text-align
:
right
;
}
</
style
>
client/client/project/pages/mobile/studentHelp.vue
0 → 100644
浏览文件 @
413dd4a1
差异被折叠。
点击展开。
client/client/project/pages/mobile/teacherHelp.vue
0 → 100644
浏览文件 @
413dd4a1
差异被折叠。
点击展开。
client/client/project/pages/myGrade/rebuild.vue
浏览文件 @
413dd4a1
...
...
@@ -55,7 +55,7 @@
:http-request=
"uploadFile1"
:file-list=
"filesArr1"
>
<el-button
size=
"mini"
type=
"primary"
>
点击上传
</el-button>
<div
slot=
"tip"
class=
"el-upload__tip"
>
(请下载重修申请表,填写完整再上传)
<a
href=
"http://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/static/public/713efef7718281271b2ad3eea135e327.docx"
>
模板下载
</a></div>
<div
slot=
"tip"
class=
"el-upload__tip"
>
(请下载重修申请表,填写完整再上传)
<a
href=
"http
s
://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/static/public/713efef7718281271b2ad3eea135e327.docx"
>
模板下载
</a></div>
<template
v-if=
"successFileUrl1"
>
{{
successFileUrl1
.
replace
(
/.*
\/([^\/]
*
\.[^
.
]
+
)
$/gi
,
'$1'
)
}}
</
template
>
...
...
client/client/project/pages/myLearn/course.vue
浏览文件 @
413dd4a1
<
template
>
<div>
<template
v-if=
"newLiveMsg.live"
>
<div
class=
"live-msg"
>
<div
class=
"txt"
>
直播提醒:
</div>
<div
class=
"txt"
>
您的直播课程 《
{{
newLiveMsg
.
course_name
}}
》 将于
{{
newLiveMsg
.
live
.
start_time
}}
开始
</div>
<el-button
class=
"in-btn"
type=
"primary"
size=
"small"
round
@
click=
"goLive"
>
进入直播
</el-button>
</div>
</
template
>
<div
class=
"con-title"
>
我的课程
</div>
<div
class=
"con-box"
>
<
template
v-for=
"(item, index) in find"
>
...
...
@@ -26,14 +33,14 @@
<li
v-bind:key=
"index"
class=
"item"
>
<div
class=
"left-pic"
>
<template
v-if=
"item.src"
>
<img
:src=
"item.src"
alt=
""
>
<img
:src=
"item.src"
alt=
""
@
click=
"goCourseContent"
:data-cid=
'item.id'
:data-sid=
'item.sid'
>
</
template
>
<
template
v-else
>
<div
class=
"no-img"
><i
class=
"el-icon-self-13"
></i></div>
</
template
>
</div>
<div
class=
"right-bd"
>
<div
class=
"title"
>
{{item.title}}
</div>
<div
class=
"title"
@
click=
"goCourseContent"
:data-cid=
'item.id'
:data-sid=
'item.sid'
>
{{item.title}}
</div>
<div
class=
"tags"
>
<
template
v-for=
"(item1, index) in item.arrTab"
>
<span
v-bind:key=
"index"
>
{{
item1
}}
</span>
...
...
@@ -105,16 +112,36 @@ export default {
// progress: 0
// }
],
param
:
{}
param
:
{},
timeInterval
:
null
,
newLiveMsg
:
{}
}
},
mounted
()
{
if
(
this
.
timeInterval
)
{
clearInterval
(
this
.
timeInterval
)
this
.
timeInterval
=
null
}
this
.
timeInterval
=
setInterval
(()
=>
{
cAction
.
chapterAction
.
getNewLiveMsg
().
then
(
json
=>
{
if
(
json
.
status
===
200
)
{
this
.
newLiveMsg
=
json
.
data
}
}).
catch
(
e
=>
{
this
.
$message
.
error
(
e
.
message
)
}).
finally
(()
=>
{
})
},
3000
)
const
loading
=
this
.
$loading
({
lock
:
true
,
text
:
''
,
spinner
:
''
,
background
:
'rgba(255, 255, 255, 0.9)'
})
cAction
.
courseAction
.
getlearnFindList
().
then
(
data
=>
{
this
.
find
[
0
].
arrItem
=
data
this
.
getAjaxList
(
true
,
'请去选课广场选课'
)
}).
catch
(
e
=>
{
this
.
$message
.
error
(
e
.
message
)
}).
finally
(()
=>
{
loading
.
close
()
})
},
destroyed
()
{
if
(
this
.
timeInterval
)
{
clearInterval
(
this
.
timeInterval
)
this
.
timeInterval
=
null
}
},
methods
:
{
goCourseAll
()
{
this
.
$router
.
push
({
path
:
'/app/my-learn/course-all'
})
...
...
@@ -178,12 +205,29 @@ export default {
}
this
.
getAjaxList
(
true
,
'请去选课广场选课'
)
},
/* 直接进直播 */
goLive
()
{
this
.
$router
.
push
({
path
:
`/player/
${
this
.
newLiveMsg
.
semester_id
}
/
${
this
.
newLiveMsg
.
course_id
}
/live/
${
this
.
newLiveMsg
.
live
.
id
}
`
})
}
}
}
</
script
>
<
style
lang=
"scss"
scoped
>
.live-msg
{
position
:
relative
;
padding
:
15px
;
box-shadow
:
0
1px
8px
rgba
(
0
,
0
,
0
,
0
.1
);
.txt
{
padding-right
:
100px
;
}
.in-btn
{
position
:
absolute
;
right
:
20px
;
top
:
50%
;
transform
:
translateY
(
-50%
);
}
}
/* 列表 筛选 */
ul
.tabs-list
{
float
:
left
;
...
...
@@ -280,6 +324,7 @@ ul.course-list {
width
:
100%
;
// height: 100%;
// transform: translate(-50%, -50%);
cursor
:
pointer
;
}
}
.right-bd
{
...
...
@@ -293,6 +338,7 @@ ul.course-list {
overflow
:
hidden
;
text-overflow
:
ellipsis
;
white-space
:
nowrap
;
cursor
:
pointer
;
}
.tags
{
margin
:
0
.05rem
0
;
...
...
client/client/project/pages/myLearn/courseDetail.vue
浏览文件 @
413dd4a1
...
...
@@ -48,9 +48,14 @@
</div>
<template
v-for=
"(item1, index1) in _item.chapters"
>
<div
v-bind:key=
"index1"
:class=
'["body", (item1.id === tabs[1].chapterList.currentChapterId && "on")]'
>
<div
class=
'name'
:data-vid=
'item1.vid'
:data-cid=
'item1.cid'
:data-sid=
'item1.sid'
:data-hasVA=
'item1.time'
:data-type=
"item1.video_provider"
:data-name=
'item1.name'
@
click=
'jumpToOtherVA'
:data-index=
'index'
:data-count=
'index1
'
>
<div
class=
'name'
:data-vid=
'item1.vid'
:data-cid=
'item1.cid'
:data-sid=
'item1.sid'
:data-hasVA=
'item1.time'
:data-type=
"item1.video_provider"
:data-name=
'item1.name'
:data-index=
'index'
:data-count=
'index1'
@
click=
'jumpToOtherVA
'
>
{{
item1
.
name
}}
<div
class=
'time'
>
{{
item1
.
time
}}
</div>
<template
v-if=
'item1.type === 5'
>
<div
class=
'time'
>
{{
item1
.
live
.
statusStr
}}
</div>
</
template
>
<
template
v-else
>
<div
class=
'time'
>
{{
item1
.
time
}}
</div>
</
template
>
</div>
</div>
</template>
...
...
@@ -293,7 +298,7 @@ export default {
},
{
title
:
'课程考核'
,
isShow
:
false
,
richText
:
"<div class='h1'>一、最终成绩计算</div> <div class='p'>课程表现得分*30%+每章试题得分*30%+结业大作业得分*40%=该门课程总得分,满分100分,低于80分为不及格,需重修此门课程。84分以上方可申请学位。</div> <img class='b1' src='http://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/static/build/www/course-check.png' mode='aspectFill' /> <div class='h1'>二、具体细则</div> <div class='h2'>课程表现:总分100分(占科目总成绩的30%)</div> <div class='p'>1、每个视频观看完成度50分:以后台数据统计为准,全部看完视频满分50分,其它酌情给分。</div> <div class='em'>注:视频观看考核的是实际播放时长,不是进度条的显示状态,进度条满格并不一定表示观看完这个视频。以下方每日学习时长为准。</div> <div class='p'>2、课程反馈建设性问题及课程完成情况50分:反馈问题以教务老师统计为准,课程完成情况以后台数据为准,是否按时完成视频观看、测试、作业提交,满分50分,酌情给分。</div> <div class='h2'>每章试题:总分100分(占科目总成绩的30%)</div> <div class='p'>本课程所有试题的平均正确率*100分*占总成绩30%=此项得分。(比如正确度为80%,则此项得分:80%*100*30%=24分)</div> <div class='h2'>结业大作业:总分100分(占科目总成绩的40%)</div> <div class='p'>结业大作业满分为100分,以助教老师给分为准。</div>"
,
richText
:
"<div class='h1'>一、最终成绩计算</div> <div class='p'>课程表现得分*30%+每章试题得分*30%+结业大作业得分*40%=该门课程总得分,满分100分,低于80分为不及格,需重修此门课程。84分以上方可申请学位。</div> <img class='b1' src='http
s
://zws-imgs-pub.oss-cn-beijing.aliyuncs.com/static/build/www/course-check.png' mode='aspectFill' /> <div class='h1'>二、具体细则</div> <div class='h2'>课程表现:总分100分(占科目总成绩的30%)</div> <div class='p'>1、每个视频观看完成度50分:以后台数据统计为准,全部看完视频满分50分,其它酌情给分。</div> <div class='em'>注:视频观看考核的是实际播放时长,不是进度条的显示状态,进度条满格并不一定表示观看完这个视频。以下方每日学习时长为准。</div> <div class='p'>2、课程反馈建设性问题及课程完成情况50分:反馈问题以教务老师统计为准,课程完成情况以后台数据为准,是否按时完成视频观看、测试、作业提交,满分50分,酌情给分。</div> <div class='h2'>每章试题:总分100分(占科目总成绩的30%)</div> <div class='p'>本课程所有试题的平均正确率*100分*占总成绩30%=此项得分。(比如正确度为80%,则此项得分:80%*100*30%=24分)</div> <div class='h2'>结业大作业:总分100分(占科目总成绩的40%)</div> <div class='p'>结业大作业满分为100分,以助教老师给分为准。</div>"
,
assess
:
{
score
:
'20'
,
duration
:
'00:01:20'
,
...
...
@@ -358,7 +363,8 @@ export default {
'
title
': [
{ required: true, message: '
请输入标题
', trigger: '
blur
' }
]
}
},
timeHeart: null
}
},
mounted () {
...
...
@@ -403,12 +409,18 @@ export default {
}).catch(e => { this.$message.error(e.message) }).finally(() => { })
}).catch(e => { this.$message.error(e.message); loading.close() }).finally(() => { })
window.addEventListener('
resize
', this.resizeRoot.bind(this), false)
/* 实时刷新数据 */
if (this.timeHeart) { clearInterval(this.timeHeart); this.timeHeart = null }
this.timeHeart = setInterval(() => {
this.updatePages()
}, 3000)
},
destroyed () {
window.removeEventListener('
resize
', this.resizeRoot.bind(this), false)
/* 清空 ckeditor 需要调用方法删除 并 在DOM结构中也移除 */
this.ckeditor && this.ckeditor.destroy(true)
this.ckeditor = null
if (this.timeHeart) { clearInterval(this.timeHeart); this.timeHeart = null }
},
updated () {
this.resizeRoot()
...
...
@@ -448,6 +460,20 @@ export default {
]
}))
},
updatePages () {
cAction.courseAction.getCourseDetail(this.cid, this.sid).then(json => {
/* 更新直播状态 */
let course = json.tabs1ChapterList.course
for (let i = 0; i < course.length; i++) {
let chapters = course[i].chapters
for (let j = 0; j < chapters.length; j++) {
if (chapters[j].type === 5) {
this.tabs[1].chapterList.course[i].chapters[j].live = chapters[j].live
}
}
}
}).catch(e => { this.$message.error(e.message) }).finally(() => { })
},
/**
* 课程内容 - 列表展开或者跳转
*/
...
...
@@ -523,10 +549,22 @@ export default {
}
} else if (_course.chapters[i2].type === 4) {
this.$router.push({ path: `/player/${sid}/${cid}/chapter-read/${_id}` })
} else if (_course.chapters[i2].type === 5) {
let status = _course.chapters[i2].live.live_status
if (status !== 0 && status !== 1 && status !== 103) {
this.$message.error(_course.chapters[i2].live.statusStr)
return
}
let enableRecord = _course.chapters[i2].live.enable_record
if (status === 103 && enableRecord !== undefined && enableRecord !== null && !enableRecord) {
this.$message.info('
该直播没有回放
')
return
}
this.$router.push({ path: `/player/${sid}/${cid}/live/${_id}` })
}
return
}
this.$message.error('
系统未知错误
,
003
')
this.$message.error('
点击频率过快,系统反应不过来,请稍后再试
,
003
')
return
}
this.$router.push({ path: `/player/${sid}/${cid}/chapter-video/${_id}/${type}` })
...
...
client/client/project/router/routes.js
浏览文件 @
413dd4a1
...
...
@@ -2,7 +2,7 @@ import App from '../app.vue'
import
container
from
'../components/layout/container.vue'
export
default
[
{
path
:
'/'
,
redirect
:
'/app/my-learn/course
'
},
{
path
:
'/'
,
redirect
:
window
.
document
.
documentElement
.
clientWidth
>
799
?
'/app/my-learn/course'
:
'/mobile/list
'
},
{
path
:
'/login'
,
redirect
:
'/login/index'
,
...
...
@@ -126,6 +126,12 @@ export default [
name
:
'exam'
,
component
:
()
=>
import
(
'../../components/player/exam/exam.vue'
),
props
:
true
},
{
path
:
'live/:id'
,
name
:
'live'
,
component
:
()
=>
import
(
'../../components/player/live/live.vue'
),
props
:
true
}
]
},
...
...
@@ -145,6 +151,32 @@ export default [
component
:
()
=>
import
(
'../../components/survey/surveyPhone.vue'
),
props
:
true
},
/* mobile 移动端 - 指向 */
{
path
:
'/mobile'
,
redirect
:
'/mobile/0/0/error/404'
,
component
:
()
=>
import
(
'../pages/mobile/index.vue'
),
props
:
true
,
children
:
[
{
path
:
'error/404'
,
component
:
()
=>
import
(
'../components/error/404.vue'
)
},
{
path
:
'list'
,
name
:
'list'
,
component
:
()
=>
import
(
'../pages/mobile/list.vue'
),
props
:
true
},
{
path
:
'help/student'
,
name
:
'studentHelp'
,
component
:
()
=>
import
(
'../pages/mobile/studentHelp.vue'
)
},
{
path
:
'help/teacher'
,
name
:
'teacherHelp'
,
component
:
()
=>
import
(
'../pages/mobile/teacherHelp.vue'
)
}
]
},
/* survey-phone 内未找到页面时 - 指向 */
{
path
:
'/survey-phone/*'
,
redirect
:
'/learn-error/learn-error'
},
/* 静态测试页面 */
...
...
client/package.json
浏览文件 @
413dd4a1
...
...
@@ -73,9 +73,9 @@
"js-md5"
:
"^0.7.3"
,
"lodash"
:
"^4.17.11"
,
"promise.prototype.finally"
:
"^3.1.0"
,
"vue"
:
"^2.
5.17
"
,
"vue-loader"
:
"^15.
4.2
"
,
"vue-router"
:
"^3.
0.7
"
,
"vue-template-compiler"
:
"^2.
5.17
"
"vue"
:
"^2.
6.11
"
,
"vue-loader"
:
"^15.
9.0
"
,
"vue-router"
:
"^3.
1.6
"
,
"vue-template-compiler"
:
"^2.
6.11
"
}
}
编写
预览
Markdown
格式
0%
重试
或
添加新文件
添加附件
取消
您添加了
0
人
到此讨论。请谨慎行事。
请先完成此评论的编辑!
取消
请
注册
或者
登录
后发表评论