Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
X
xiaomai-cloud-class-web
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xiaomai-cloud-class
xiaomai-cloud-class-web
Commits
f985047c
Commit
f985047c
authored
Jul 01, 2021
by
wufan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:完成线上课列表页字段展示顺序调整
parent
229c6a77
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
311 additions
and
25 deletions
+311
-25
src/modules/course-manage/video-course/VideoCourseDetail.less
+91
-0
src/modules/course-manage/video-course/VideoCourseDetail.tsx
+172
-0
src/modules/course-manage/video-course/components/VideoCourseList.jsx
+41
-24
src/modules/course-manage/video-course/components/VideoCourseList.less
+6
-0
src/modules/resource-disk/modal/ScanFileModal.jsx
+1
-1
No files found.
src/modules/course-manage/video-course/VideoCourseDetail.less
0 → 100644
View file @
f985047c
.video-course-detail {
.box {
.course-detail {
display: flex;
border-bottom: 2px solid #E8E8E8;
padding-bottom: 24px;
&__img {
margin-right: 24px;
width: 300px;
height: 170px;
background: #FFFFFF;
border-radius: 4px;
img {
width: 300px;
height: 170px;
border-radius: 4px;
}
}
&__info {
display: flex;
flex-direction: column;
.info__title {
width: 680px;
height: 28px;
font-size: 20px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 28px;
margin-bottom: 16px;
}
.info__category, .info__chapterNum {
width: 100%;
height: 20px;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 20px;
margin-bottom: 10px;
}
}
}
.course-chapter {
padding-top: 24px;
&__total {
width: 100%;
height: 20px;
font-size: 14px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 20px;
margin-bottom: 24px;
}
&__list {
.course-ware {
display: flex;
height: 20px;
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
line-height: 20px;
margin-bottom: 28px;
cursor: pointer;
&:hover {
color: #2966FF;
}
&__index {
width: 20px;
}
&__img {
width: 20px;
height: 20px;
margin-left: 16px;
margin-right: 8px;
}
&__name {
width: 700px;
}
}
}
}
}
}
\ No newline at end of file
src/modules/course-manage/video-course/VideoCourseDetail.tsx
0 → 100644
View file @
f985047c
/*
* @Author: wufan
* @Date: 2020-04-28 18:05:30
* @LastEditors: wufan
* @LastEditTime: 2021-06-25 11:49:55
* @Description: 线上课课程课节详情
*/
import
React
,{
useEffect
,
useState
}
from
'react'
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
{
withRouter
}
from
"react-router-dom"
;
import
CourseService
from
'@/domains/course-domain/CourseService'
import
underscore
from
'underscore'
;
import
ScanFileModal
from
'@/modules/resource-disk/modal/ScanFileModal.jsx'
;
import
'./VideoCourseDetail.less'
;
declare
var
getParameterByName
:
any
;
declare
var
window
:
any
;
function
VideoCourseDetail
(){
const
courseId
=
window
.
getParameterByName
(
"courseId"
);
// 课程ID
const
[
coverUrl
,
setCoverUrl
]
=
useState
(
""
);
const
[
videoName
,
setVideoName
]
=
useState
(
""
);
const
[
scheduleVideoUrl
,
setScheduleVideoUrl
]
=
useState
(
""
);
const
[
courseChapterList
,
setCourseChapterList
]
=
useState
<
Array
<
Object
>>
([
{
mediaContent
:
1408354568285888514
,
contentType
:
'SCHEDULE'
,
mediaType
:
"VIDEO"
,
name
:
'发生科技快快快规划的开发规划狂热结构化可如何改了如何更好润肤露萨科技股份考试'
,
videoDuration
:
200
,
id
:
1408354568285888514
,
mediaUrl
:
'http://xmdev-resource-pub.oss-cn-hangzhou.aliyuncs.com/inst/22222222222222222/lesson/upload/0/20210630163635/AM4Mbf66P2hrEFPd.mp4'
},
{
mediaContent
:
1408354568285888514
,
contentType
:
'SCHEDULE'
,
mediaType
:
"VIDEO"
,
name
:
'发生科技快快快规划的开发规试'
,
videoDuration
:
200
,
id
:
1408354568285888515
,
mediaUrl
:
'http://xmdev-resource-pub.oss-cn-hangzhou.aliyuncs.com/inst/22222222222222222/lesson/upload/0/20210630163635/AM4Mbf66P2hrEFPd.mp4'
},
{
mediaContent
:
1408354568285888514
,
contentType
:
'SCHEDULE'
,
mediaType
:
"VIDEO"
,
name
:
'发生科技快快快规划的开发规划狂热结构化可如何改了如何更好润肤露萨科技股份考试'
,
videoDuration
:
200
,
id
:
1408354568285888516
,
mediaUrl
:
'http://xmdev-resource-pub.oss-cn-hangzhou.aliyuncs.com/inst/22222222222222222/lesson/upload/0/20210630163635/AM4Mbf66P2hrEFPd.mp4'
},
{
mediaContent
:
1408354568285888514
,
contentType
:
'SCHEDULE'
,
mediaType
:
"VIDEO"
,
name
:
'发生科技快快快规划的开发规试'
,
videoDuration
:
200
,
id
:
1408354568285888517
,
mediaUrl
:
'http://xmdev-resource-pub.oss-cn-hangzhou.aliyuncs.com/inst/22222222222222222/lesson/upload/0/20210630163635/AM4Mbf66P2hrEFPd.mp4'
}
]);
const
[
courseName
,
setCourseName
]
=
useState
(
""
);
const
[
categoryName
,
setCategoryName
]
=
useState
(
""
);
const
[
scanFileModal
,
setScanFileModal
]
=
useState
<
any
>
(
null
);
useEffect
(()
=>
{
handleFetchScheudleDetail
(
courseId
);
},[
courseId
])
// 获取线上课详情
function
handleFetchScheudleDetail
(
courseId
:
string
){
CourseService
.
videoScheduleDetail
({
courseId
}).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
||
{}
const
{
courseName
,
courseMediaVOS
,
categoryName
,
courseChapterVOList
=
[]
}
=
result
let
coverId
:
string
=
""
;
let
coverUrl
:
string
=
""
;
let
videoType
:
string
=
""
;
let
videoDuration
:
number
=
0
;
let
videoName
:
string
=
""
;
let
scheduleVideoUrl
:
string
=
""
;
courseMediaVOS
.
map
((
item
:
any
)
=>
{
switch
(
item
.
contentType
)
{
case
'COVER'
:
coverId
=
item
.
mediaContent
coverUrl
=
item
.
mediaUrl
break
case
'SCHEDULE'
:
videoDuration
=
item
.
videoDuration
videoName
=
item
.
mediaName
scheduleVideoUrl
=
item
.
mediaUrl
videoType
=
item
.
mediaType
break
default
:
break
}
return
item
})
setCoverUrl
(
coverUrl
);
setVideoName
(
videoName
);
setScheduleVideoUrl
(
scheduleVideoUrl
);
setCourseName
(
courseName
);
setCategoryName
(
categoryName
);
// setCourseChapterList(courseChapterVOList);
})
}
function
handleScanFileModal
(
fileType
:
string
=
"MP4"
,
fileObj
:
Object
){
const
scanFileModal
=
(
<
ScanFileModal
fileType=
{
fileType
}
item=
{
fileObj
}
close=
{
()
=>
{
setScanFileModal
(
null
);
}
}
/>
);
setScanFileModal
(
scanFileModal
)
}
return
<
div
className=
"page video-course-detail"
>
<
Breadcrumbs
navList=
"课程详情"
goBack=
{
()
=>
{
window
.
RCHistory
.
goBack
();
}
}
/>
<
div
className=
"box"
>
<
div
className=
"course-detail"
>
<
div
className=
'course-detail__img'
>
{
/* 如果视频和封面都没有上传的话, 那么就显示缺省, 如果上传了视频, 那么封面图就默认显示视频的第一帧, 如果上传了封面图, 那么就显示上传的封面图 */
}
<
img
src=
{
coverUrl
||
`https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png`
}
alt=
''
/>
</
div
>
<
div
className=
"course-detail__info"
>
<
div
className=
"info__title"
>
{
courseName
}
</
div
>
<
div
className=
"info__category"
>
{
`分类:${categoryName}`
}
</
div
>
<
div
className=
"info__chapterNum"
>
{
`课节数量:${courseChapterList.length}`
}
</
div
>
</
div
>
</
div
>
<
div
className=
"course-chapter"
>
<
div
className=
"course-chapter__total"
>
{
`共${courseChapterList.length}个课节`
}
</
div
>
<
div
className=
"course-chapter__list"
>
<
If
condition=
{
courseChapterList
.
length
>
0
}
>
{
underscore
.
map
(
courseChapterList
,(
item
:
any
,
index
:
number
)
=>
{
return
<
div
className=
'course-ware'
onClick=
{
()
=>
{
handleScanFileModal
(
"MP4"
,
item
)}
}
key=
{
index
}
>
<
div
className=
"course-ware__index"
>
{
`${index > 9 ? index + 1 : `
0
$
{
index
+
1
}
`} `
}
</
div
>
<
img
className=
'course-ware__img'
src=
'https://image.xiaomaiketang.com/xm/TKwbQGYDBR.png'
alt=
''
/>
<
div
className=
'course-ware__name'
>
{
item
.
name
}
</
div
>
</
div
>
})
}
</
If
>
</
div
>
</
div
>
</
div
>
{
scanFileModal
}
</
div
>
}
export
default
withRouter
(
VideoCourseDetail
);
\ No newline at end of file
src/modules/course-manage/video-course/components/VideoCourseList.jsx
View file @
f985047c
...
@@ -3,12 +3,13 @@ import { Table, Modal, message, Tooltip, Switch, Dropdown } from "antd"
...
@@ -3,12 +3,13 @@ import { Table, Modal, message, Tooltip, Switch, Dropdown } from "antd"
import
_
from
"underscore"
import
_
from
"underscore"
import
{
PageControl
}
from
"@/components"
import
{
PageControl
}
from
"@/components"
import
{
LIVE_SHARE
}
from
"@/domains/course-domain/constants"
import
{
LIVE_SHARE
}
from
"@/domains/course-domain/constants"
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
ShareLiveModal
from
"@/modules/course-manage/modal/ShareLiveModal"
import
ShareLiveModal
from
"@/modules/course-manage/modal/ShareLiveModal"
import
WatchDataModal
from
"../modal/WatchDataModal"
import
WatchDataModal
from
"../modal/WatchDataModal"
import
CourseService
from
"@/domains/course-domain/CourseService"
import
CourseService
from
"@/domains/course-domain/CourseService"
import
RelatedPlanModal
from
"../../modal/RelatedPlanModal"
import
RelatedPlanModal
from
"../../modal/RelatedPlanModal"
import
User
from
"@/common/js/user"
import
User
from
"@/common/js/user"
import
VideoCourseDetail
from
'../VideoCourseDetail'
;
import
"./VideoCourseList.less"
import
"./VideoCourseList.less"
...
@@ -33,6 +34,13 @@ class VideoCourseList extends React.Component {
...
@@ -33,6 +34,13 @@ class VideoCourseList extends React.Component {
}
}
}
}
// 跳转课程详情页
handleLinkToCourseDetail
=
(
courseId
)
=>
{
const
{
match
}
=
this
.
props
;
window
.
RCHistory
.
push
(
`
${
match
.
url
}
/video-course-detail?courseId=
${
courseId
}
`
)
}
// 观看数据弹窗
// 观看数据弹窗
handleShowWatchDataModal
=
(
record
)
=>
{
handleShowWatchDataModal
=
(
record
)
=>
{
const
watchDataModal
=
(
const
watchDataModal
=
(
...
@@ -102,7 +110,7 @@ class VideoCourseList extends React.Component {
...
@@ -102,7 +110,7 @@ class VideoCourseList extends React.Component {
),
),
key
:
"categoryName"
,
key
:
"categoryName"
,
dataIndex
:
"categoryName"
,
dataIndex
:
"categoryName"
,
width
:
20
0
,
width
:
15
0
,
render
:
(
val
,
record
)
=>
{
render
:
(
val
,
record
)
=>
{
return
(
return
(
<
Choose
>
<
Choose
>
...
@@ -120,20 +128,14 @@ class VideoCourseList extends React.Component {
...
@@ -120,20 +128,14 @@ class VideoCourseList extends React.Component {
}
}
},
},
{
{
title
:
"创建人"
,
title
:
'课节数'
,
key
:
"createName"
,
key
:
'chapterNum'
,
dataIndex
:
"createName"
,
dataIndex
:
'chapterNum'
,
className
:
"chapterNum"
,
width
:
100
,
width
:
100
,
render
:
(
val
)
=>
{
align
:
'right'
,
return
(
render
:
(
val
,
item
)
=>
{
<
div
>
return
<
div
onClick=
{
()
=>
this
.
handleLinkToCourseDetail
(
item
.
id
)
}
>
{
val
||
1
}
</
div
>
{
val
&&
(
<
Tooltip
title=
{
val
}
>
<
div
>
{
val
.
length
>
4
?
`${val.slice(0, 4)}
...
`
:
val
}
</
div
>
</
Tooltip
>
)
}
</
div
>
)
}
}
},
},
{
{
...
@@ -172,11 +174,29 @@ class VideoCourseList extends React.Component {
...
@@ -172,11 +174,29 @@ class VideoCourseList extends React.Component {
},
},
{
{
title
:
"观看学员数"
,
title
:
"观看学员数"
,
width
:
1
1
0
,
width
:
1
5
0
,
key
:
"watchUserCount"
,
key
:
"watchUserCount"
,
dataIndex
:
"watchUserCount"
,
dataIndex
:
"watchUserCount"
,
align
:
'right'
,
render
:
(
val
,
item
)
=>
{
render
:
(
val
,
item
)
=>
{
return
<
div
className=
'watchUserCount'
>
{
val
||
0
}
</
div
>
return
<
div
className=
'watchUserCount'
onClick=
{
()
=>
this
.
handleShowWatchDataModal
(
item
)
}
>
{
val
||
0
}
</
div
>
}
},
{
title
:
"创建人"
,
key
:
"createName"
,
dataIndex
:
"createName"
,
width
:
100
,
render
:
(
val
)
=>
{
return
(
<
div
>
{
val
&&
(
<
Tooltip
title=
{
val
}
>
<
div
>
{
val
.
length
>
4
?
`${val.slice(0, 4)}
...
`
:
val
}
</
div
>
</
Tooltip
>
)
}
</
div
>
)
}
}
},
},
{
{
...
@@ -236,12 +256,7 @@ class VideoCourseList extends React.Component {
...
@@ -236,12 +256,7 @@ class VideoCourseList extends React.Component {
render
:
(
val
,
record
)
=>
{
render
:
(
val
,
record
)
=>
{
return
(
return
(
<
div
className=
'operate'
>
<
div
className=
'operate'
>
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleShowWatchDataModal
(
record
)
}
>
观看数据
</
div
>
<
If
condition=
{
type
===
"internal"
}
>
<
If
condition=
{
type
===
"internal"
}
>
<
span
className=
'operate__item split'
>
|
</
span
>
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleShowShareModal
(
record
)
}
>
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleShowShareModal
(
record
)
}
>
分享
分享
</
div
>
</
div
>
...
@@ -447,9 +462,10 @@ class VideoCourseList extends React.Component {
...
@@ -447,9 +462,10 @@ class VideoCourseList extends React.Component {
)
)
}
}
render
()
{
render
()
{
const
{
dataSource
=
[],
totalCount
,
query
,
type
}
=
this
.
props
const
{
dataSource
=
[],
totalCount
,
query
,
type
,
match
}
=
this
.
props
const
{
current
,
size
}
=
query
const
{
current
,
size
}
=
query
const
{
RelatedPlanModalVisible
,
selectPlanList
,
selectCourseId
}
=
this
.
state
const
{
RelatedPlanModalVisible
,
selectPlanList
,
selectCourseId
}
=
this
.
state
return
(
return
(
<
div
className=
{
`video-course-list ${type !== "internal" ? "video-course-list-mt" : ""}`
}
>
<
div
className=
{
`video-course-list ${type !== "internal" ? "video-course-list-mt" : ""}`
}
>
<
Table
<
Table
...
@@ -486,9 +502,10 @@ class VideoCourseList extends React.Component {
...
@@ -486,9 +502,10 @@ class VideoCourseList extends React.Component {
)
}
)
}
{
this
.
state
.
shareLiveModal
}
{
this
.
state
.
shareLiveModal
}
{
this
.
state
.
watchDataModal
}
{
this
.
state
.
watchDataModal
}
<
Route
path=
{
`${match.url}/video-course-detail`
}
component=
{
VideoCourseDetail
}
/>
</
div
>
</
div
>
)
)
}
}
}
}
export
default
VideoCourseList
export
default
withRouter
(
VideoCourseList
);
src/modules/course-manage/video-course/components/VideoCourseList.less
View file @
f985047c
...
@@ -24,11 +24,17 @@
...
@@ -24,11 +24,17 @@
}
}
}
}
}
}
.chapterNum {
color: #2966ff;
cursor: pointer;
}
}
}
}
}
.watchUserCount {
.watchUserCount {
text-align: right;
text-align: right;
padding: 16px;
padding: 16px;
color: #2966ff;
cursor: pointer;
}
}
.operate-text {
.operate-text {
color: #2966FF;
color: #2966FF;
...
...
src/modules/resource-disk/modal/ScanFileModal.jsx
View file @
f985047c
...
@@ -37,7 +37,7 @@ class ScanFileModal extends React.Component {
...
@@ -37,7 +37,7 @@ class ScanFileModal extends React.Component {
{
fileType
===
"MP4"
&&
(
{
fileType
===
"MP4"
&&
(
<
div
>
<
div
>
<
Player
<
Player
src=
{
item
.
ossAddress
||
item
.
ossUrl
}
src=
{
item
.
mediaUrl
||
item
.
ossAddress
||
item
.
ossUrl
}
fluid=
{
false
}
fluid=
{
false
}
height=
{
306
}
height=
{
306
}
width=
{
"100%"
}
width=
{
"100%"
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment