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
510254f6
Commit
510254f6
authored
Jun 29, 2021
by
guomingpang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:课程管理缺省图替换,导航栏收起高亮
parent
f803fff4
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
3036 additions
and
2917 deletions
+3036
-2917
src/modules/course-manage/DataList/CourseData.jsx
+107
-131
src/modules/course-manage/DataList/PlaybackData.jsx
+66
-67
src/modules/course-manage/components/LiveCourseList.jsx
+553
-515
src/modules/course-manage/graphics-course/components/GraphicsCourseList.jsx
+252
-232
src/modules/course-manage/graphics-course/modal/WatchDataModal.jsx
+113
-90
src/modules/course-manage/modal/AccountChargeRecords.jsx
+35
-34
src/modules/course-manage/modal/ChargingDetailModal.jsx
+50
-44
src/modules/course-manage/modal/ClassRecordModal.jsx
+197
-182
src/modules/course-manage/modal/LiveStudentListModal.jsx
+131
-158
src/modules/course-manage/modal/ManageCoursewareModal.jsx
+155
-178
src/modules/course-manage/modal/PlayBackRecordModal.jsx
+94
-96
src/modules/course-manage/modal/RelatedPlanModal.jsx
+107
-98
src/modules/course-manage/modal/select-student/StudentList.jsx
+282
-277
src/modules/course-manage/offline-course/OfflineCourseData.jsx
+194
-167
src/modules/course-manage/offline-course/components/OfflineCourseList.jsx
+226
-192
src/modules/course-manage/video-course/components/VideoCourseList.jsx
+196
-183
src/modules/course-manage/video-course/modal/WatchDataModal.jsx
+111
-88
src/modules/root/Menu.tsx
+87
-104
src/routes/config/menuList.tsx
+80
-81
No files found.
src/modules/course-manage/DataList/CourseData.jsx
View file @
510254f6
import
React
from
"react"
;
import
{
withRouter
}
from
"react-router-dom"
;
import
{
Table
,
Popover
,
message
,
Button
,
Spin
}
from
"antd"
;
import
dealTimeDuration
from
"../utils/dealTimeDuration"
;
import
{
PageControl
}
from
"@/components"
;
import
CourseService
from
"@/domains/course-domain/CourseService"
;
import
User
from
"@/common/js/user"
;
import
"./DataList.less"
;
import
User
from
'@/common/js/user'
;
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
{
Button
,
message
,
Popover
,
Spin
}
from
'antd'
;
import
React
from
'react'
;
import
{
withRouter
}
from
'react-router-dom'
;
import
dealTimeDuration
from
'../utils/dealTimeDuration'
;
import
'./DataList.less'
;
class
DataList
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
const
courseId
=
getParameterByName
(
"id"
);
// 课程ID
const
type
=
getParameterByName
(
"type"
);
// 来源: 大班直播 large 互动班课 interactive
const
courseId
=
getParameterByName
(
'id'
);
// 课程ID
const
type
=
getParameterByName
(
'type'
);
// 来源: 大班直播 large 互动班课 interactive
this
.
state
=
{
type
,
teacherData
:
[],
// 老师上课数据
...
...
@@ -68,34 +69,30 @@ class DataList extends React.Component {
getVisiterColumns
()
{
const
columns
=
[
{
title
:
"序号"
,
dataIndex
:
"index"
,
title
:
'序号'
,
dataIndex
:
'index'
,
width
:
50
,
render
:
(
text
,
record
,
index
)
=>
{
return
<
span
>
{
index
+
1
}
</
span
>;
},
},
{
title
:
"进入时间"
,
dataIndex
:
"entryTime"
,
title
:
'进入时间'
,
dataIndex
:
'entryTime'
,
width
:
150
,
render
:
(
text
)
=>
(
<
span
>
{
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
text
))
}
</
span
>
),
render
:
(
text
)
=>
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
text
))
}
</
span
>,
},
{
title
:
"离开时间"
,
dataIndex
:
"leaveTime"
,
title
:
'离开时间'
,
dataIndex
:
'leaveTime'
,
width
:
150
,
render
:
(
text
)
=>
(
<
span
>
{
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
text
))
}
</
span
>
),
render
:
(
text
)
=>
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
text
))
}
</
span
>,
},
{
title
:
"在线时长"
,
dataIndex
:
"lookingDuration"
,
title
:
'在线时长'
,
dataIndex
:
'lookingDuration'
,
render
:
(
text
,
record
)
=>
{
return
<
span
>
{
text
?
dealTimeDuration
(
text
)
:
"-"
}
</
span
>;
return
<
span
>
{
text
?
dealTimeDuration
(
text
)
:
'-'
}
</
span
>;
},
},
];
...
...
@@ -106,43 +103,44 @@ class DataList extends React.Component {
getStudentColumns
()
{
const
columns
=
[
{
title
:
"学员姓名"
,
dataIndex
:
"userName"
,
title
:
'学员姓名'
,
dataIndex
:
'userName'
,
},
{
title
:
"手机号"
,
dataIndex
:
"phone"
,
title
:
'手机号'
,
dataIndex
:
'phone'
,
render
:
(
text
,
record
)
=>
{
const
{
phone
=
""
,
bindingWeChat
}
=
record
;
const
{
phone
=
''
,
bindingWeChat
}
=
record
;
return
<
div
>
{
phone
}
</
div
>;
},
},
{
title
:
"观看次数"
,
dataIndex
:
"entryNum"
,
title
:
'观看次数'
,
dataIndex
:
'entryNum'
,
render
:
(
text
,
record
)
=>
{
if
(
text
>
0
)
{
if
(
record
.
visitorInfoVOList
&&
record
.
visitorInfoVOList
.
length
>
0
)
{
if
(
record
.
visitorInfoVOList
&&
record
.
visitorInfoVOList
.
length
>
0
)
{
const
table
=
(
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
columns=
{
this
.
getVisiterColumns
()
}
dataSource=
{
record
.
visitorInfoVOList
}
scroll=
{
{
y
:
75
}
}
size=
{
"small"
}
size=
{
'small'
}
style=
{
{
width
:
450
}
}
pagination=
{
false
}
/>
);
return
(
<
Popover
content=
{
table
}
trigger=
"click"
>
<
span
className=
"handel-btn"
>
{
text
}
</
span
>
<
Popover
content=
{
table
}
trigger=
'click'
>
<
span
className=
'handel-btn'
>
{
text
}
</
span
>
</
Popover
>
);
}
else
{
return
<
div
className=
"live-table--empty"
>
暂无观看数据
</
div
>;
return
<
div
className=
'live-table--empty'
>
暂无观看数据
</
div
>;
}
}
else
{
return
<
span
>
{
text
}
</
span
>;
...
...
@@ -150,13 +148,13 @@ class DataList extends React.Component {
},
},
{
title
:
"累计在线时长"
,
dataIndex
:
"totalDuration"
,
title
:
'累计在线时长'
,
dataIndex
:
'totalDuration'
,
sorter
:
(
a
,
b
)
=>
a
.
totalDuration
-
b
.
totalDuration
,
sortDirections
:
[
"descend"
,
"ascend"
],
sortDirections
:
[
'descend'
,
'ascend'
],
render
:
(
text
,
record
)
=>
{
//如无离开时间,就置空
return
<
span
>
{
text
?
dealTimeDuration
(
text
)
:
"00:00:00"
}
</
span
>;
return
<
span
>
{
text
?
dealTimeDuration
(
text
)
:
'00:00:00'
}
</
span
>;
},
},
];
...
...
@@ -169,17 +167,17 @@ class DataList extends React.Component {
CourseService
.
exportStudentCourseData
({
liveCourseId
:
liveCourseId
,
exportLiveType
:
"VISITOR"
,
exportLiveType
:
'VISITOR'
,
storeId
,
}).
then
((
res
)
=>
{
const
link
=
res
.
result
;
this
.
setState
({
link
link
,
});
document
.
getElementById
(
"loadExcel"
).
click
();
document
.
getElementById
(
'loadExcel'
).
click
();
if
(
res
.
success
)
{
message
.
success
(
"导出成功!"
);
message
.
success
(
'导出成功!'
);
}
});
};
...
...
@@ -187,27 +185,28 @@ class DataList extends React.Component {
handleCheckEnterTimes
=
()
=>
{
const
{
teacherData
}
=
this
.
state
;
if
(
teacherData
.
entryNum
>
0
)
{
if
(
teacherData
.
visitorInfoVOList
&&
teacherData
.
visitorInfoVOList
.
length
>
0
)
{
if
(
teacherData
.
visitorInfoVOList
&&
teacherData
.
visitorInfoVOList
.
length
>
0
)
{
const
table
=
(
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
columns=
{
this
.
getVisiterColumns
()
}
dataSource=
{
teacherData
.
visitorInfoVOList
}
scroll=
{
{
y
:
75
}
}
size=
{
"small"
}
size=
{
'small'
}
style=
{
{
width
:
450
}
}
pagination=
{
false
}
/>
);
return
(
<
Popover
content=
{
table
}
trigger=
"click"
>
<
span
className=
"times-num"
>
{
teacherData
.
entryNum
}
</
span
>
<
Popover
content=
{
table
}
trigger=
'click'
>
<
span
className=
'times-num'
>
{
teacherData
.
entryNum
}
</
span
>
</
Popover
>
);
}
else
{
return
<
div
className=
"live-table--empty"
>
暂无观看数据
</
div
>;
return
<
div
className=
'live-table--empty'
>
暂无观看数据
</
div
>;
}
}
else
{
return
<
span
>
{
teacherData
.
entryNum
}
</
span
>;
...
...
@@ -216,130 +215,107 @@ class DataList extends React.Component {
showTable
=
()
=>
{
return
(
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
columns=
{
this
.
getVisiterColumns
()
}
dataSource=
{
this
.
state
.
teacherData
.
visitorInfoVOList
}
scroll=
{
{
y
:
80
}
}
size=
{
"small"
}
size=
{
'small'
}
style=
{
{
width
:
450
}
}
pagination=
{
false
}
className=
"visitor-num-table"
className=
'visitor-num-table'
/>
);
};
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
return
;
}
this
.
setState
({
size
},
this
.
fetchUserData
)
}
this
.
setState
({
size
},
this
.
fetchUserData
)
;
}
;
render
()
{
const
{
teacherData
,
studentData
,
current
,
size
,
total
,
loading
,
link
}
=
this
.
state
;
const
{
teacherData
,
studentData
,
current
,
size
,
total
,
loading
,
link
}
=
this
.
state
;
return
(
<
Spin
spinning=
{
loading
}
>
<
a
href=
{
link
}
target=
"_blank"
download
id=
"loadExcel"
style=
{
{
position
:
"absolute"
,
left
:
"-10000px"
}
}
>
<
a
href=
{
link
}
target=
'_blank'
download
id=
'loadExcel'
style=
{
{
position
:
'absolute'
,
left
:
'-10000px'
}
}
>
111
</
a
>
{
/* 讲师上课数据 */
}
<
div
className=
"courseData-teacher"
>
<
p
className=
"title"
>
讲师上课数据
</
p
>
<
div
className=
"teacher-course-data"
>
<
div
className=
"avatar-name-phone item-block"
>
<
img
src=
{
teacherData
.
avatar
||
"https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png"
}
alt=
""
className=
"avatar"
/>
<
div
className=
"right"
>
<
div
className=
"name"
>
{
teacherData
.
userName
}
</
div
>
<
div
className=
"phone"
>
{
teacherData
.
phone
}
</
div
>
<
div
className=
'courseData-teacher'
>
<
p
className=
'title'
>
讲师上课数据
</
p
>
<
div
className=
'teacher-course-data'
>
<
div
className=
'avatar-name-phone item-block'
>
<
img
src=
{
teacherData
.
avatar
||
'https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png'
}
alt=
''
className=
'avatar'
/>
<
div
className=
'right'
>
<
div
className=
'name'
>
{
teacherData
.
userName
}
</
div
>
<
div
className=
'phone'
>
{
teacherData
.
phone
}
</
div
>
</
div
>
</
div
>
<
div
className=
"times item-block"
>
<
div
className=
{
`times-num ${
Number(teacherData.entryNum) > 0 ? "can-click" : ""
}`
}
>
{
Number
(
teacherData
.
entryNum
)
>
0
?
<
Popover
content=
{
this
.
showTable
()
}
trigger=
"click"
>
<
span
className=
"times-num"
>
{
teacherData
.
entryNum
||
0
}
</
span
>
</
Popover
>:
<
span
className=
"times-num"
>
{
0
}
</
span
>
}
<
div
className=
'times item-block'
>
<
div
className=
{
`times-num ${Number(teacherData.entryNum) > 0 ? 'can-click' : ''}`
}
>
{
Number
(
teacherData
.
entryNum
)
>
0
?
(
<
Popover
content=
{
this
.
showTable
()
}
trigger=
'click'
>
<
span
className=
'times-num'
>
{
teacherData
.
entryNum
||
0
}
</
span
>
</
Popover
>
)
:
(
<
span
className=
'times-num'
>
{
0
}
</
span
>
)
}
</
div
>
<
div
className=
"text"
>
进入直播间次数
</
div
>
<
div
className=
'text'
>
进入直播间次数
</
div
>
</
div
>
<
div
className=
"online-duration item-block"
>
<
div
className=
"duration"
>
{
teacherData
.
totalDuration
?
dealTimeDuration
(
teacherData
.
totalDuration
)
:
"00:00:00"
}
</
div
>
<
div
className=
"text"
>
累计在线时长
</
div
>
<
div
className=
'online-duration item-block'
>
<
div
className=
'duration'
>
{
teacherData
.
totalDuration
?
dealTimeDuration
(
teacherData
.
totalDuration
)
:
'00:00:00'
}
</
div
>
<
div
className=
'text'
>
累计在线时长
</
div
>
</
div
>
</
div
>
</
div
>
{
/* 学员上课数据 */
}
<
div
className=
"courseData-student"
>
<
p
className=
"title"
>
学员上课数据
</
p
>
<
div
className=
"filter-wrap"
>
<
div
className=
"filter"
>
<
div
className=
'courseData-student'
>
<
p
className=
'title'
>
学员上课数据
</
p
>
<
div
className=
'filter-wrap'
>
<
div
className=
'filter'
>
<
Button
style=
{
{
height
:
32
}
}
style=
{
{
height
:
32
}
}
onClick=
{
_
.
debounce
(
()
=>
{
if
(
!
studentData
.
length
)
{
message
.
warning
(
"暂无数据可导出"
);
message
.
warning
(
'暂无数据可导出'
);
return
;
}
this
.
handleExportV5
();
},
500
,
true
)
}
>
)
}
>
导出
</
Button
>
</
div
>
</
div
>
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
bordered
size=
"small"
size=
'small'
scroll=
{
{
y
:
600
}
}
columns=
{
this
.
getStudentColumns
()
}
dataSource=
{
studentData
}
pagination=
{
false
}
style=
{
{
margin
:
"16px 0"
}
}
style=
{
{
margin
:
'16px 0'
}
}
/>
{
total
>
0
&&
{
total
>
0
&&
(
<
PageControl
size=
"small"
size=
'small'
current=
{
current
-
1
}
pageSize=
{
size
}
total=
{
total
}
...
...
@@ -348,7 +324,7 @@ class DataList extends React.Component {
this
.
fetchUserData
(
page
+
1
);
}
}
/>
}
)
}
</
div
>
</
Spin
>
);
...
...
src/modules/course-manage/DataList/PlaybackData.jsx
View file @
510254f6
import
User
from
'@/common/js/user'
;
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
{
Button
,
message
}
from
'antd'
;
import
React
from
'react'
;
import
{
withRouter
}
from
"react-router-dom"
;
import
{
Table
,
Button
,
Modal
,
message
}
from
'antd'
;
import
{
withRouter
}
from
'react-router-dom'
;
import
dealTimeDuration
from
'../utils/dealTimeDuration'
;
import
{
PageControl
}
from
"@/components"
;
import
'./DataList.less'
;
import
CourseService
from
"@/domains/course-domain/CourseService"
;
import
User
from
'@/common/js/user'
;
const
liveTypeMap
=
{
USER
:
"普通用户"
,
ANCHOR
:
"讲师"
,
ADMIN
:
"管理员(助教)"
,
GUEST
:
"游客"
USER
:
'普通用户'
,
ANCHOR
:
'讲师'
,
ADMIN
:
'管理员(助教)'
,
GUEST
:
'游客'
,
};
class
PlaybackData
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
const
courseId
=
getParameterByName
(
"id"
);
// 课程ID
const
courseId
=
getParameterByName
(
'id'
);
// 课程ID
this
.
state
=
{
playbackData
:
[],
...
...
@@ -24,8 +25,8 @@ class PlaybackData extends React.Component {
size
:
10
,
total
:
0
,
liveCourseId
:
courseId
,
storeId
:
User
.
getStoreId
()
}
storeId
:
User
.
getStoreId
()
,
}
;
}
componentDidMount
()
{
...
...
@@ -33,12 +34,12 @@ class PlaybackData extends React.Component {
}
fetchPlaybackList
=
(
page
=
1
)
=>
{
const
{
size
,
liveCourseId
}
=
this
.
state
const
{
size
,
liveCourseId
}
=
this
.
state
;
const
params
=
{
liveCourseId
,
current
:
page
,
size
}
size
,
}
;
CourseService
.
fetchPlaybackList
(
params
).
then
((
res
)
=>
{
if
(
res
.
result
)
{
...
...
@@ -47,38 +48,35 @@ class PlaybackData extends React.Component {
playbackData
:
records
,
current
,
size
,
total
total
,
});
}
});
};
getPlaybackColumns
()
{
const
columns
=
[
{
title
:
"观看学员"
,
dataIndex
:
"userName"
,
title
:
'观看学员'
,
dataIndex
:
'userName'
,
},
{
title
:
"手机号"
,
dataIndex
:
"phone"
title
:
'手机号'
,
dataIndex
:
'phone'
,
},
{
title
:
"观看者类型"
,
dataIndex
:
"userRole"
,
title
:
'观看者类型'
,
dataIndex
:
'userRole'
,
render
:
(
text
)
=>
<
span
>
{
liveTypeMap
[
text
]
}
</
span
>,
},
{
title
:
"开始观看时间"
,
dataIndex
:
"entryTime"
,
render
:
(
text
)
=>
(
<
span
>
{
text
?
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
text
))
:
'-'
}
</
span
>
),
title
:
'开始观看时间'
,
dataIndex
:
'entryTime'
,
render
:
(
text
)
=>
<
span
>
{
text
?
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
text
))
:
'-'
}
</
span
>,
},
{
title
:
"观看时长"
,
dataIndex
:
"lookingDuration"
,
title
:
'观看时长'
,
dataIndex
:
'lookingDuration'
,
render
:
(
text
)
=>
{
return
<
span
>
{
text
?
dealTimeDuration
(
text
)
:
'-'
}
</
span
>;
},
...
...
@@ -92,65 +90,67 @@ class PlaybackData extends React.Component {
CourseService
.
exportPlayBackCourseData
({
liveCourseId
,
exportLiveType
:
"PLAY_BACK"
,
storeId
exportLiveType
:
'PLAY_BACK'
,
storeId
,
}).
then
((
res
)
=>
{
const
link
=
res
.
result
;
this
.
setState
({
link
link
,
});
document
.
getElementById
(
"load-play-back-excel"
).
click
();
document
.
getElementById
(
'load-play-back-excel'
).
click
();
if
(
res
.
success
)
{
message
.
success
(
"导出成功!"
)
if
(
res
.
success
)
{
message
.
success
(
'导出成功!'
);
}
})
})
;
}
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
return
;
}
this
.
setState
({
size
},
this
.
fetchUserData
)
}
this
.
setState
({
size
},
this
.
fetchUserData
)
;
}
;
render
()
{
const
{
playbackData
,
total
,
current
,
size
,
link
}
=
this
.
state
const
{
playbackData
,
total
,
current
,
size
,
link
}
=
this
.
state
;
return
(
<
div
>
<
a
href=
{
link
}
target=
"_blank"
download
id=
"load-play-back-excel"
style=
{
{
position
:
"absolute"
,
left
:
"-10000px"
}
}
>
<
a
href=
{
link
}
target=
'_blank'
download
id=
'load-play-back-excel'
style=
{
{
position
:
'absolute'
,
left
:
'-10000px'
}
}
>
111
</
a
>
<
Button
onClick=
{
()
=>
{
this
.
handleplaybackExport
()}
}
>
导出
</
Button
>
<
Table
<
Button
onClick=
{
()
=>
{
this
.
handleplaybackExport
();
}
}
>
导出
</
Button
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
bordered
size=
"small"
size=
'small'
columns=
{
this
.
getPlaybackColumns
()
}
dataSource=
{
playbackData
}
pagination=
{
false
}
style=
{
{
margin
:
'16px 0'
}
}
>
</
Table
>
{
total
>
0
&&
<
PageControl
size=
"small"
current=
{
current
-
1
}
pageSize=
{
size
}
total=
{
total
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
toPage=
{
(
page
)
=>
{
this
.
fetchPlaybackList
(
page
+
1
);
}
}
/>
}
style=
{
{
margin
:
'16px 0'
}
}
></
XMTable
>
{
total
>
0
&&
(
<
PageControl
size=
'small'
current=
{
current
-
1
}
pageSize=
{
size
}
total=
{
total
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
toPage=
{
(
page
)
=>
{
this
.
fetchPlaybackList
(
page
+
1
);
}
}
/>
)
}
</
div
>
)
)
;
}
}
export
default
withRouter
(
PlaybackData
);
\ No newline at end of file
export
default
withRouter
(
PlaybackData
);
src/modules/course-manage/components/LiveCourseList.jsx
View file @
510254f6
/*
* @Author: 吴文洁
* @Date: 2020-07-14 15:43:00
* @Author: 吴文洁
* @Date: 2020-07-14 15:43:00
* @Last Modified by: chenshu
* @Last Modified time: 2021-03-16 17:37:23
* @Description: 大班直播、互动班课的直播课列表
*/
import
User
from
'@/common/js/user'
;
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
DownloadLiveModal
from
'@/components/DownloadLiveModal'
;
import
BaseService
from
'@/domains/basic-domain/baseService'
;
import
{
appId
,
LIVE_SHARE
}
from
'@/domains/course-domain/constants'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
{
QuestionCircleOutlined
}
from
'@ant-design/icons'
;
import
{
Dropdown
,
message
,
Modal
,
Switch
,
Tooltip
}
from
'antd'
;
import
React
from
'react'
;
import
{
Table
,
Modal
,
message
,
Dropdown
,
Button
,
Switch
,
Tooltip
}
from
'antd'
;
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
{
PageControl
}
from
"@/components"
;
import
DownloadLiveModal
from
'@/components/DownloadLiveModal'
;
import
_
from
'underscore'
;
import
DataList
from
'../DataList/DataList'
;
import
ManageCoursewareModal
from
'../modal/ManageCoursewareModal'
;
import
ShareLiveModal
from
'../modal/ShareLiveModal'
;
import
RelatedPlanModal
from
'../modal/RelatedPlanModal'
;
import
ShareLiveModal
from
'../modal/ShareLiveModal'
;
import
'./LiveCourseList.less'
;
import
{
QuestionCircleOutlined
}
from
'@ant-design/icons'
;
import
{
appId
,
shareUrl
,
LIVE_SHARE
,
LIVE_REPLAY_MAP
}
from
'@/domains/course-domain/constants'
;
import
CourseService
from
"@/domains/course-domain/CourseService"
;
import
BaseService
from
"@/domains/basic-domain/baseService"
;
import
DataList
from
'../DataList/DataList'
;
import
User
from
'@/common/js/user'
;
import
_
from
"underscore"
;
const
{
confirm
}
=
Modal
;
const
courseStateShow
=
{
UN_START
:
{
code
:
1
,
title
:
"待开课"
,
color
:
"#FFB129"
,
title
:
'待开课'
,
color
:
'#FFB129'
,
},
STARTING
:
{
code
:
2
,
title
:
"上课中"
,
color
:
"#238FFF"
,
title
:
'上课中'
,
color
:
'#238FFF'
,
},
FINISH
:
{
code
:
3
,
title
:
"已完成"
,
color
:
"#3BBDAA"
,
title
:
'已完成'
,
color
:
'#3BBDAA'
,
},
EXPIRED
:
{
code
:
4
,
title
:
"未成功开课"
,
color
:
"#999"
,
title
:
'未成功开课'
,
color
:
'#999'
,
},
};
class
LiveCourseList
extends
React
.
Component
{
...
...
@@ -55,702 +52,744 @@ class LiveCourseList extends React.Component {
super
(
props
);
this
.
state
=
{
columns
:
[],
openDownloadModal
:
false
,
url
:
''
,
RelatedPlanModalVisible
:
false
,
selectPlanList
:
{}
}
openDownloadModal
:
false
,
url
:
''
,
RelatedPlanModalVisible
:
false
,
selectPlanList
:
{},
}
;
}
componentWillMount
(){
componentWillMount
()
{
this
.
parseColumns
();
}
componentDidMount
()
{
this
.
getDownloadVersion
()
this
.
getDownloadVersion
()
;
}
// 显示分享弹窗
handleShowShareModal
=
(
item
,
needStr
=
false
)
=>
{
const
_appId
=
appId
;
const
_appId
=
appId
;
const
{
liveCourseId
}
=
item
;
const
htmlUrl
=
`
${
LIVE_SHARE
}
live_detail/
${
liveCourseId
}
?id=
${
User
.
getStoreId
()}
`
;
const
longUrl
=
htmlUrl
console
.
log
(
'htmlUrl'
,
htmlUrl
,
longUrl
);
const
longUrl
=
htmlUrl
;
console
.
log
(
'htmlUrl'
,
htmlUrl
,
longUrl
);
const
shareData
=
{
...
item
,
longUrl
};
const
shareLiveModal
=
(
<
ShareLiveModal
needStr=
{
needStr
}
data=
{
shareData
}
type=
"liveClass"
title=
"直播课"
type=
'liveClass'
title=
'直播课'
close=
{
()
=>
{
this
.
setState
({
shareLiveModal
:
null
shareLiveModal
:
null
,
});
localStorage
.
setItem
(
'largeLiveCourseItem'
,
''
);
}
}
/>
)
)
;
this
.
setState
({
shareLiveModal
})
}
this
.
setState
({
shareLiveModal
})
;
}
;
//改变上架状态
changeShelfState
=
(
item
)
=>
{
let
_shelfState
=
item
.
shelfState
if
(
_shelfState
===
'NO'
){
_shelfState
=
"YES"
;
item
.
shelfState
=
"YES"
}
else
{
_shelfState
=
"NO"
item
.
shelfState
=
"NO"
}
const
params
=
{
"liveCourseId"
:
item
.
liveCourseId
,
"shelfState"
:
_shelfState
changeShelfState
=
(
item
)
=>
{
let
_shelfState
=
item
.
shelfState
;
if
(
_shelfState
===
'NO'
)
{
_shelfState
=
'YES'
;
item
.
shelfState
=
'YES'
;
}
else
{
_shelfState
=
'NO'
;
item
.
shelfState
=
'NO'
;
}
CourseService
.
turnOnOrOffLiveCloudCourse
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
){
if
(
_shelfState
===
"YES"
){
message
.
success
(
"已开启展示"
);
}
else
{
message
.
success
(
"已取消展示"
);
const
params
=
{
liveCourseId
:
item
.
liveCourseId
,
shelfState
:
_shelfState
,
};
CourseService
.
turnOnOrOffLiveCloudCourse
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
_shelfState
===
'YES'
)
{
message
.
success
(
'已开启展示'
);
}
else
{
message
.
success
(
'已取消展示'
);
}
}
})
}
})
;
}
;
// 前往上课数据页面
handleLinkToClassData
=
(
item
)
=>
{
const
{
match
}
=
this
.
props
;
window
.
RCHistory
.
push
({
pathname
:
`
${
match
.
url
}
/live-course-data?type=large&id=
${
item
.
liveCourseId
}
`
pathname
:
`
${
match
.
url
}
/live-course-data?type=large&id=
${
item
.
liveCourseId
}
`
,
});
}
}
;
parseColumns
=
()
=>
{
const
menu
=
(
item
)
=>
(
<
div
className=
"live-course-more-menu"
>
<
div
>
上课记录
</
div
>
<
div
className=
'live-course-more-menu'
>
<
div
>
上课记录
</
div
>
<
div
onClick=
{
()
=>
{
this
.
handleShowRepeatModal
(
item
);
}
}
>
}
}
>
回放记录
</
div
>
</
div
>
);
let
columns
const
userRole
=
User
.
getUserRole
();
if
(
userRole
!==
"CloudLecturer"
)
{
let
columns
;
const
userRole
=
User
.
getUserRole
();
if
(
userRole
!==
'CloudLecturer'
)
{
columns
=
[
{
title
:
"直播课"
,
width
:
"23%"
,
key
:
"course"
,
dataIndex
:
"courseName"
,
title
:
'直播课'
,
width
:
'23%'
,
key
:
'course'
,
dataIndex
:
'courseName'
,
render
:
(
val
,
record
)
=>
{
let
hasCover
=
false
;
return
(
<
div
className=
"record__item"
>
{
record
.
courseMediaVOS
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentType
===
"COVER"
){
hasCover
=
true
;
return
<
img
className=
"course-cover"
src=
{
item
.
mediaUrl
}
/>
}
})
}
{
!
hasCover
&&
<
img
className=
"course-cover"
src=
{
'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'
}
/>
}
<
div
className=
'record__item'
>
{
record
.
courseMediaVOS
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentType
===
'COVER'
)
{
hasCover
=
true
;
return
<
img
className=
'course-cover'
src=
{
item
.
mediaUrl
}
/>;
}
})
}
{
!
hasCover
&&
<
img
className=
'course-cover'
src=
{
'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'
}
/>
}
<
div
>
{
record
.
courseName
.
length
>
17
?
<
Tooltip
title=
{
record
.
courseName
}
>
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
{
record
.
courseName
.
length
>
17
?
(
<
Tooltip
title=
{
record
.
courseName
}
>
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
</
Tooltip
>
)
:
(
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
)
}
<
div
>
<
span
className=
'course-time'
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
record
.
startTime
))
}
~
{
formatDate
(
'H:i'
,
parseInt
(
record
.
endTime
))
}
</
span
>
<
span
className=
'course-status'
style=
{
{
color
:
courseStateShow
[
record
.
courseState
].
color
,
border
:
`1px solid ${courseStateShow[record.courseState].color}`
}
}
>
{
courseStateShow
[
record
.
courseState
].
title
}
</
span
>
</
div
>
<
div
className=
'teacher-assistant'
>
{
record
.
teacherName
.
length
>
4
?
(
<
Tooltip
title=
{
record
.
teacherName
}
>
<
span
className=
'teacher'
>
讲师:
{
record
.
teacherName
}
</
span
>
</
Tooltip
>
:
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
}
<
div
>
<
span
className=
"course-time"
>
{
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
record
.
startTime
))
}
~
{
formatDate
(
"H:i"
,
parseInt
(
record
.
endTime
))
}
</
span
>
<
span
className=
"course-status"
style=
{
{
color
:
courseStateShow
[
record
.
courseState
].
color
,
border
:
`1px solid ${courseStateShow[record.courseState].color}`
}
}
>
{
courseStateShow
[
record
.
courseState
].
title
}
</
span
>
</
div
>
<
div
className=
"teacher-assistant"
>
{
record
.
teacherName
.
length
>
4
?
<
Tooltip
title=
{
record
.
teacherName
}
>
<
span
className=
"teacher"
>
讲师:
{
record
.
teacherName
}
</
span
>
</
Tooltip
>
:
<
span
className=
"teacher"
>
讲师:
{
record
.
teacherName
}
</
span
>
}
{
record
.
admins
.
length
>
0
&&
<>
<
span
className=
"split"
>
|
</
span
>
{
this
.
handleAdminName
(
record
.
admins
).
length
>
4
?
<
Tooltip
title=
{
this
.
handleAdminName
(
record
.
admins
)
}
>
<
span
className=
"assistant"
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
adminName
}
{
(
index
<
record
.
admins
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
)
:
(
<
span
className=
'teacher'
>
讲师:
{
record
.
teacherName
}
</
span
>
)
}
{
record
.
admins
.
length
>
0
&&
(
<>
<
span
className=
'split'
>
|
</
span
>
{
this
.
handleAdminName
(
record
.
admins
).
length
>
4
?
(
<
Tooltip
title=
{
this
.
handleAdminName
(
record
.
admins
)
}
>
<
span
className=
'assistant'
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
adminName
}
{
index
<
record
.
admins
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
);
})
}
</
span
>
</
Tooltip
>
)
:
(
<
span
className=
'assistant'
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
adminName
}
{
index
<
record
.
admins
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
</
Tooltip
>
:
<
span
className=
"assistant"
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
adminName
}
{
(
index
<
record
.
admins
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
</
span
>
}
</>
}
</
div
>
);
})
}
</
span
>
)
}
</>
)
}
</
div
>
</
div
>
</
div
>
)
}
)
;
}
,
},
{
title
:
"课程分类"
,
width
:
"10%"
,
key
:
"couseCatalog"
,
dataIndex
:
"couseCatalog"
,
title
:
'课程分类'
,
width
:
'10%'
,
key
:
'couseCatalog'
,
dataIndex
:
'couseCatalog'
,
render
:
(
val
,
item
)
=>
{
return
(
<
div
className=
"categoryName"
>
{
item
.
categoryName
}
</
div
>
)
return
<
div
className=
'categoryName'
>
{
item
.
categoryName
}
</
div
>;
},
},
{
title
:
"课件管理"
,
width
:
"8%"
,
key
:
"courseware"
,
dataIndex
:
"courseware"
,
title
:
'课件管理'
,
width
:
'8%'
,
key
:
'courseware'
,
dataIndex
:
'courseware'
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
className=
"courseware"
<
span
className=
'courseware'
onClick=
{
()
=>
{
this
.
setState
({
editData
:
item
,
openCoursewareModal
:
true
,
});
}
}
>
{
item
.
courseDocumentCount
}
个
</
span
>
this
.
setState
({
editData
:
item
,
openCoursewareModal
:
true
,
});
}
}
>
{
item
.
courseDocumentCount
}
个
</
span
>
);
},
},
{
title
:
'上课数据'
,
width
:
"9%"
,
key
:
"quota"
,
dataIndex
:
"quota"
,
width
:
'9%'
,
key
:
'quota'
,
dataIndex
:
'quota'
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
className=
"iconfont icon quota-icon"
onClick=
{
()
=>
{
this
.
handleLinkToClassData
(
item
)
}
}
>

</
span
>
<
span
className=
'iconfont icon quota-icon'
onClick=
{
()
=>
{
this
.
handleLinkToClassData
(
item
);
}
}
>

</
span
>
);
},
},
{
title
:
<
span
>
<
span
>
学院展示
</
span
>
<
Tooltip
title=
{
<
div
>
开启后,学员可在学院内查看到此课程。若课程“未成功开课”,则系统会自动“关闭”学院展示。
<
br
/>
关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。
</
div
>
}
><
i
className=
"icon iconfont"
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'normal'
}
}
>

</
i
></
Tooltip
>
</
span
>,
width
:
"9%"
,
key
:
"shelfState"
,
dataIndex
:
"shelfState"
,
title
:
(
<
span
>
<
span
>
学院展示
</
span
>
<
Tooltip
title=
{
<
div
>
开启后,学员可在学院内查看到此课程。若课程“未成功开课”,则系统会自动“关闭”学院展示。
<
br
/>
关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。
</
div
>
}
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'normal'
}
}
>

</
i
>
</
Tooltip
>
</
span
>
),
width
:
'9%'
,
key
:
'shelfState'
,
dataIndex
:
'shelfState'
,
render
:
(
val
,
item
,
index
)
=>
{
return
(
<
Switch
defaultChecked=
{
item
.
shelfState
===
"YES"
?
true
:
false
}
onChange=
{
()
=>
this
.
changeShelfState
(
item
)
}
/>
)
return
<
Switch
defaultChecked=
{
item
.
shelfState
===
'YES'
?
true
:
false
}
onChange=
{
()
=>
this
.
changeShelfState
(
item
)
}
/>;
},
},
{
title
:
'创建时间'
,
width
:
"9%"
,
key
:
"created"
,
dataIndex
:
"created"
,
width
:
'9%'
,
key
:
'created'
,
dataIndex
:
'created'
,
sorter
:
true
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
span
>
);
return
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
span
>;
},
},
{
title
:
'关联项'
,
width
:
"15%"
,
key
:
"planList"
,
dataIndex
:
"planList"
,
width
:
'15%'
,
key
:
'planList'
,
dataIndex
:
'planList'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"related-task"
>
{
record
.
relatedPlanList
?
<
Tooltip
title=
{
this
.
handlePlanName
(
record
.
relatedPlanList
)
}
placement=
"top"
arrowPointAtCenter
>
{
record
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
planName
}
{
(
index
<
record
.
relatedPlanList
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
</
Tooltip
>
:
<
span
></
span
>
}
return
(
<
div
className=
'related-task'
>
{
record
.
relatedPlanList
?
(
<
Tooltip
title=
{
this
.
handlePlanName
(
record
.
relatedPlanList
)
}
placement=
'top'
arrowPointAtCenter
>
{
record
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
planName
}
{
index
<
record
.
relatedPlanList
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
);
})
}
</
Tooltip
>
)
:
(
<
span
></
span
>
)
}
</
div
>
)
)
;
},
},
{
title
:
"操作"
,
width
:
"15%"
,
key
:
"operate"
,
dataIndex
:
"operate"
,
title
:
'操作'
,
width
:
'15%'
,
key
:
'operate'
,
dataIndex
:
'operate'
,
render
:
(
val
,
item
)
=>
{
return
(
<
div
className=
"operate"
>
{
((
item
.
courseState
===
"UN_START"
||
item
.
courseState
===
"STARTING"
)
&&
(
item
.
teacherId
===
User
.
getUserId
()
||
_
.
pluck
(
item
.
admins
,
"adminId"
).
includes
(
User
.
getUserId
())))
&&
<>
<
div
key=
"enter_live_room1"
className=
"operate__item"
onClick=
{
()
=>
{
this
.
handleEnterLiveRoom
(
item
)
}
}
>
进入直播间
</
div
>
<
span
className=
"operate__item split"
key=
"view_play_back_split"
>
|
</
span
>
</>
}
{
(
item
.
courseState
===
"FINISH"
&&
item
.
haveRecord
===
"YES"
)
&&
<
div
className=
'operate'
>
{
(
item
.
courseState
===
'UN_START'
||
item
.
courseState
===
'STARTING'
)
&&
(
item
.
teacherId
===
User
.
getUserId
()
||
_
.
pluck
(
item
.
admins
,
'adminId'
).
includes
(
User
.
getUserId
()))
&&
(
<>
<
div
key=
"view_play_back"
className=
"operate__item"
onClick=
{
()
=>
{
this
.
handleViewPlayBack
(
item
)}
}
>
查看回放
</
div
>
<
span
className=
"operate__item split"
key=
"view_play_back_split"
>
|
</
span
>
</>
}
{
item
.
courseState
!==
"EXPIRED"
&&
<>
<
div
key=
"share"
className=
"operate__item"
onClick=
{
()
=>
{
this
.
handleShowShareModal
(
item
);
}
}
>
分享
key=
'enter_live_room1'
className=
'operate__item'
onClick=
{
()
=>
{
this
.
handleEnterLiveRoom
(
item
);
}
}
>
进入直播间
</
div
>
<
span
className=
'operate__item split'
key=
'view_play_back_split'
>
{
' '
}
|
{
' '
}
</
span
>
</>
}
{
item
.
courseState
!==
"EXPIRED"
&&
)
}
{
item
.
courseState
===
'FINISH'
&&
item
.
haveRecord
===
'YES'
&&
(
<>
<
div
key=
'view_play_back'
className=
'operate__item'
onClick=
{
()
=>
{
this
.
handleViewPlayBack
(
item
);
}
}
>
查看回放
</
div
>
<
span
className=
'operate__item split'
key=
'view_play_back_split'
>
{
' '
}
|
{
' '
}
</
span
>
</>
)
}
{
item
.
courseState
!==
'EXPIRED'
&&
(
<>
<
div
key=
'share'
className=
'operate__item'
onClick=
{
()
=>
{
this
.
handleShowShareModal
(
item
);
}
}
>
分享
</
div
>
</>
)
}
{
item
.
courseState
!==
'EXPIRED'
&&
(
<>
<
span
key=
"split1"
className=
"operate__item split"
>
|
</
span
>
<
div
className=
"big-live"
>
<
span
key=
'split1'
className=
'operate__item split'
>
{
' '
}
|
{
' '
}
</
span
>
<
div
className=
'big-live'
>
<
Dropdown
overlay=
{
this
.
renderMoreOperate
(
item
)
}
>
<
span
className=
"more-operate"
>
<
span
className=
"operate-text"
>
更多
</
span
>
<
span
className=
"iconfont icon"
style=
{
{
color
:
"#2966FF"
}
}
>

<
span
className=
'more-operate'
>
<
span
className=
'operate-text'
>
更多
</
span
>
<
span
className=
'iconfont icon'
style=
{
{
color
:
'#2966FF'
}
}
>

</
span
>
</
span
>
</
Dropdown
>
</
div
>
</>
}
{
item
.
courseState
===
"EXPIRED"
&&
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
handleDelete
(
item
)
}
>
删除
</
div
>
}
)
}
{
item
.
courseState
===
'EXPIRED'
&&
(
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleDelete
(
item
)
}
>
删除
</
div
>
)
}
</
div
>
)
}
}
)
;
}
,
}
,
];
}
else
{
}
else
{
columns
=
[
{
title
:
"直播课"
,
width
:
"25%"
,
key
:
"course"
,
dataIndex
:
"courseName"
,
title
:
'直播课'
,
width
:
'25%'
,
key
:
'course'
,
dataIndex
:
'courseName'
,
render
:
(
val
,
record
)
=>
{
let
hasCover
=
false
;
return
(
<
div
className=
"record__item"
>
{
record
.
courseMediaVOS
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentType
===
"COVER"
){
hasCover
=
true
;
return
<
img
className=
"course-cover"
src=
{
item
.
mediaUrl
}
/>
}
})
}
{
!
hasCover
&&
<
img
className=
"course-cover"
src=
{
'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'
}
/>
}
<
div
className=
'record__item'
>
{
record
.
courseMediaVOS
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentType
===
'COVER'
)
{
hasCover
=
true
;
return
<
img
className=
'course-cover'
src=
{
item
.
mediaUrl
}
/>;
}
})
}
{
!
hasCover
&&
<
img
className=
'course-cover'
src=
{
'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'
}
/>
}
<
div
>
{
record
.
courseName
.
length
>
17
?
<
Tooltip
title=
{
record
.
courseName
}
>
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
</
Tooltip
>
:
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
}
<
div
>
<
span
className=
"course-time"
>
{
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
record
.
startTime
))
}
~
{
formatDate
(
"H:i"
,
parseInt
(
record
.
endTime
))
}
</
span
>
<
span
className=
"course-status"
style=
{
{
color
:
courseStateShow
[
record
.
courseState
].
color
,
border
:
`1px solid ${courseStateShow[record.courseState].color}`
}
}
>
{
courseStateShow
[
record
.
courseState
].
title
}
</
span
>
</
div
>
<
div
className=
"teacher-assistant"
>
{
record
.
teacherName
.
length
>
4
?
{
record
.
courseName
.
length
>
17
?
(
<
Tooltip
title=
{
record
.
courseName
}
>
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
</
Tooltip
>
)
:
(
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
)
}
<
div
>
<
span
className=
'course-time'
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
record
.
startTime
))
}
~
{
formatDate
(
'H:i'
,
parseInt
(
record
.
endTime
))
}
</
span
>
<
span
className=
'course-status'
style=
{
{
color
:
courseStateShow
[
record
.
courseState
].
color
,
border
:
`1px solid ${courseStateShow[record.courseState].color}`
}
}
>
{
courseStateShow
[
record
.
courseState
].
title
}
</
span
>
</
div
>
<
div
className=
'teacher-assistant'
>
{
record
.
teacherName
.
length
>
4
?
(
<
Tooltip
title=
{
record
.
teacherName
}
>
<
span
className=
"teacher"
>
讲师:
{
record
.
teacherName
}
</
span
>
<
span
className=
'teacher'
>
讲师:
{
record
.
teacherName
}
</
span
>
</
Tooltip
>
:
<
span
className=
"teacher"
>
讲师:
{
record
.
teacherName
}
</
span
>
}
{
record
.
admins
.
length
>
0
&&
<>
<
span
className=
"split"
>
|
</
span
>
{
this
.
handleAdminName
(
record
.
admins
).
length
>
4
?
<
Tooltip
title=
{
this
.
handleAdminName
(
record
.
admins
)
}
>
<
span
className=
"assistant"
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
adminName
}
{
(
index
<
record
.
admins
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
)
:
(
<
span
className=
'teacher'
>
讲师:
{
record
.
teacherName
}
</
span
>
)
}
{
record
.
admins
.
length
>
0
&&
(
<>
<
span
className=
'split'
>
|
</
span
>
{
this
.
handleAdminName
(
record
.
admins
).
length
>
4
?
(
<
Tooltip
title=
{
this
.
handleAdminName
(
record
.
admins
)
}
>
<
span
className=
'assistant'
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
adminName
}
{
index
<
record
.
admins
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
);
})
}
</
span
>
</
Tooltip
>
)
:
(
<
span
className=
'assistant'
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
adminName
}
{
index
<
record
.
admins
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
</
Tooltip
>
:
<
span
className=
"assistant"
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
adminName
}
{
(
index
<
record
.
admins
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
</
span
>
}
</>
}
</
div
>
);
})
}
</
span
>
)
}
</>
)
}
</
div
>
</
div
>
</
div
>
)
}
)
;
}
,
},
{
title
:
"课程分类"
,
width
:
"10%"
,
key
:
"couseCatalog"
,
dataIndex
:
"couseCatalog"
,
title
:
'课程分类'
,
width
:
'10%'
,
key
:
'couseCatalog'
,
dataIndex
:
'couseCatalog'
,
render
:
(
val
,
item
)
=>
{
return
(
<
div
className=
"categoryName"
>
{
item
.
categoryName
}
</
div
>
)
return
<
div
className=
'categoryName'
>
{
item
.
categoryName
}
</
div
>;
},
},
{
title
:
"课件管理"
,
width
:
"8%"
,
key
:
"courseware"
,
dataIndex
:
"courseware"
,
title
:
'课件管理'
,
width
:
'8%'
,
key
:
'courseware'
,
dataIndex
:
'courseware'
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
className=
"courseware"
<
span
className=
'courseware'
onClick=
{
()
=>
{
this
.
setState
({
editData
:
item
,
openCoursewareModal
:
true
,
});
}
}
>
{
item
.
courseDocumentCount
}
个
</
span
>
this
.
setState
({
editData
:
item
,
openCoursewareModal
:
true
,
});
}
}
>
{
item
.
courseDocumentCount
}
个
</
span
>
);
},
},
{
title
:
'上课数据'
,
width
:
"9%"
,
key
:
"quota"
,
dataIndex
:
"quota"
,
width
:
'9%'
,
key
:
'quota'
,
dataIndex
:
'quota'
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
className=
"iconfont icon quota-icon"
onClick=
{
()
=>
{
this
.
handleLinkToClassData
(
item
)
}
}
>

</
span
>
<
span
className=
'iconfont icon quota-icon'
onClick=
{
()
=>
{
this
.
handleLinkToClassData
(
item
);
}
}
>

</
span
>
);
},
},
{
title
:
'创建时间'
,
width
:
"9%"
,
key
:
"created"
,
dataIndex
:
"created"
,
width
:
'9%'
,
key
:
'created'
,
dataIndex
:
'created'
,
sorter
:
true
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
span
>
);
return
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
span
>;
},
},
{
title
:
'关联项'
,
width
:
"15%"
,
key
:
"planList"
,
dataIndex
:
"planList"
,
width
:
'15%'
,
key
:
'planList'
,
dataIndex
:
'planList'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"related-task"
>
{
record
.
relatedPlanList
?
<
Tooltip
title=
{
this
.
handlePlanName
(
record
.
relatedPlanList
)
}
placement=
"top"
arrowPointAtCenter
>
{
record
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
planName
}
{
(
index
<
record
.
relatedPlanList
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
</
Tooltip
>
:
<
span
></
span
>
}
return
(
<
div
className=
'related-task'
>
{
record
.
relatedPlanList
?
(
<
Tooltip
title=
{
this
.
handlePlanName
(
record
.
relatedPlanList
)
}
placement=
'top'
arrowPointAtCenter
>
{
record
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
planName
}
{
index
<
record
.
relatedPlanList
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
);
})
}
</
Tooltip
>
)
:
(
<
span
></
span
>
)
}
</
div
>
)
)
;
},
},
];
}
this
.
setState
({
columns
})
}
handleAdminName
=
(
adminArray
)
=>
{
let
adminStr
=
""
;
adminArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
adminArray
.
length
-
1
)
{
this
.
setState
({
columns
})
;
}
;
handleAdminName
=
(
adminArray
)
=>
{
let
adminStr
=
''
;
adminArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
adminArray
.
length
-
1
)
{
adminStr
=
adminStr
+
item
.
adminName
+
'、'
;
}
else
{
adminStr
=
adminStr
+
item
.
adminName
}
else
{
adminStr
=
adminStr
+
item
.
adminName
;
}
})
return
adminStr
}
})
;
return
adminStr
;
}
;
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
""
;
planArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
planArray
.
length
-
1
)
{
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
''
;
planArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
planArray
.
length
-
1
)
{
planStr
=
planStr
+
item
.
planName
+
'、'
;
}
else
{
planStr
=
planStr
+
item
.
planName
}
else
{
planStr
=
planStr
+
item
.
planName
;
}
})
return
planStr
}
})
;
return
planStr
;
}
;
renderMoreOperate
=
(
item
)
=>
{
return
(
<
div
className=
"live-course-more-menu"
>
{
(
User
.
getUserRole
()
===
"CloudManager"
||
User
.
getUserRole
()
===
"StoreManager"
)
&&
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
handleRelatedModalShow
(
item
)
}
>
关联培训计划
</
div
>
}
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
toEditCoursePage
(
item
)
}
>
编辑
</
div
>
{
item
.
courseState
!==
"STARTING"
&&
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
handleDelete
(
item
)
}
>
删除
</
div
>
}
<
div
className=
'live-course-more-menu'
>
{
(
User
.
getUserRole
()
===
'CloudManager'
||
User
.
getUserRole
()
===
'StoreManager'
)
&&
(
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleRelatedModalShow
(
item
)
}
>
关联培训计划
</
div
>
)
}
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
toEditCoursePage
(
item
)
}
>
编辑
</
div
>
{
item
.
courseState
!==
'STARTING'
&&
(
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleDelete
(
item
)
}
>
删除
</
div
>
)
}
</
div
>
)
}
handleDelete
=
(
record
)
=>
{
return
confirm
({
)
;
}
;
handleDelete
=
(
record
)
=>
{
return
confirm
({
title
:
'你确定要删除直播课?'
,
content
:
'删除后,学员将不能观看直播课/回放'
,
icon
:
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
okText
:
'删除'
,
okType
:
'danger'
,
cancelText
:
'取消'
,
width
:
440
,
height
:
188
,
width
:
440
,
height
:
188
,
onOk
:
()
=>
{
this
.
deleteConfirm
(
record
);
}
})
}
deleteConfirm
=
(
item
)
=>
{
const
params
=
{
"liveCourseId"
:
item
.
liveCourseId
,
}
CourseService
.
delLiveCloudCourse
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
message
.
success
(
"已删除"
);
}
,
})
;
}
;
deleteConfirm
=
(
item
)
=>
{
const
params
=
{
liveCourseId
:
item
.
liveCourseId
,
}
;
CourseService
.
delLiveCloudCourse
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
message
.
success
(
'已删除'
);
this
.
props
.
onChange
();
}
})
}
toEditCoursePage
=
(
item
)
=>
{
})
;
}
;
toEditCoursePage
=
(
item
)
=>
{
window
.
RCHistory
.
push
({
pathname
:
`/create-live-course?type=edit&id=
${
item
.
liveCourseId
}
`
,
})
}
refreshCourseList
=
()
=>
{
})
;
}
;
refreshCourseList
=
()
=>
{
this
.
props
.
onChange
(
this
.
props
.
query
);
}
//进入直播间
}
;
//进入直播间
handleEnterLiveRoom
=
(
item
)
=>
{
if
(
item
.
startTime
-
Date
.
now
()
>
1800000
)
{
Modal
.
warning
({
title
:
"你来得太早了"
,
title
:
'你来得太早了'
,
okText
:
'我知道了'
,
content
:
"请于开始上课前30分钟来直播上课。"
,
content
:
'请于开始上课前30分钟来直播上课。'
,
icon
:
(
<
span
className=
"icon iconfont default-confirm-icon"
style=
{
{
color
:
"#FFBB54 !important"
}
}
>

<
span
className=
'icon iconfont default-confirm-icon'
style=
{
{
color
:
'#FFBB54 !important'
}
}
>

</
span
>
),
});
}
else
{
CourseService
.
getLiveCloudCourseDetail
({
liveCourseId
:
item
.
liveCourseId
,
})
.
then
((
res
)
=>
{
const
url
=
`xmqx://liveCourseId=
${
item
.
liveCourseId
}
`
;
if
(
res
.
result
.
courseState
===
"FINISH"
)
{
Modal
.
warning
({
title
:
"刷新页面"
,
icon
:
<
QuestionCircleOutlined
/>,
content
:
"课次已结束,请刷新一下"
,
onOk
:
()
=>
{
this
.
refreshCourseList
();
}
});
}
else
{
this
.
setState
({
url
,
openDownloadModal
:
true
});
}
});
CourseService
.
getLiveCloudCourseDetail
({
liveCourseId
:
item
.
liveCourseId
,
}).
then
((
res
)
=>
{
const
url
=
`xmqx://liveCourseId=
${
item
.
liveCourseId
}
`
;
if
(
res
.
result
.
courseState
===
'FINISH'
)
{
Modal
.
warning
({
title
:
'刷新页面'
,
icon
:
<
QuestionCircleOutlined
/>,
content
:
'课次已结束,请刷新一下'
,
onOk
:
()
=>
{
this
.
refreshCourseList
();
},
});
}
else
{
this
.
setState
({
url
,
openDownloadModal
:
true
});
}
});
}
}
}
;
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
return
return
;
}
let
_query
=
this
.
props
.
query
let
_query
=
this
.
props
.
query
;
_query
.
size
=
size
;
this
.
props
.
onChange
(
_query
)
}
this
.
props
.
onChange
(
_query
)
;
}
;
getDownloadVersion
()
{
const
isMac
=
/macintosh|mac os x/i
.
test
(
navigator
.
userAgent
);
// 判断学员系统
let
platform
;
if
(
!
isMac
)
{
platform
=
1
}
else
{
platform
=
4
if
(
!
isMac
)
{
platform
=
1
;
}
else
{
platform
=
4
;
}
BaseService
.
getLastedVersion
({
model
:
5
,
platform
})
.
then
((
res
)
=>
{
BaseService
.
getLastedVersion
({
model
:
5
,
platform
}).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
this
.
setState
({
downloadUrl
:
result
.
releaseUrl
});
})
});
}
handleViewPlayBack
=
(
item
)
=>
{
let
htmlUrl
;
if
(
item
.
teacherId
===
User
.
getUserId
())
{
if
(
item
.
teacherId
===
User
.
getUserId
())
{
htmlUrl
=
`
${
LIVE_SHARE
}
replay/
${
item
.
liveCourseId
}
?teacherId=
${
User
.
getUserId
()}
&id=
${
User
.
getStoreId
()}
`
;
}
else
if
(
_
.
pluck
(
item
.
admins
,
"adminId"
).
includes
(
User
.
getUserId
()))
{
}
else
if
(
_
.
pluck
(
item
.
admins
,
'adminId'
).
includes
(
User
.
getUserId
()))
{
htmlUrl
=
`
${
LIVE_SHARE
}
replay/
${
item
.
liveCourseId
}
?userId=
${
User
.
getUserId
()}
&id=
${
User
.
getStoreId
()}
`
;
}
else
{
}
else
{
htmlUrl
=
`
${
LIVE_SHARE
}
replay/
${
item
.
liveCourseId
}
?id=
${
User
.
getStoreId
()}
`
;
}
window
.
open
(
htmlUrl
);
}
handleRelatedModalShow
=
(
item
)
=>
{
};
handleRelatedModalShow
=
(
item
)
=>
{
const
selectPlanList
=
{};
if
(
item
.
relatedPlanList
)
{
item
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
selectPlanList
[
item
.
planId
]
=
{}
if
(
item
.
relatedPlanList
)
{
item
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
selectPlanList
[
item
.
planId
]
=
{}
;
selectPlanList
[
item
.
planId
].
planId
=
item
.
planId
;
selectPlanList
[
item
.
planId
].
taskBaseVOList
=
[{
taskId
:
item
.
taskId
}];
return
item
})
selectPlanList
[
item
.
planId
].
taskBaseVOList
=
[{
taskId
:
item
.
taskId
}];
return
item
;
})
;
}
this
.
setState
({
RelatedPlanModalVisible
:
true
,
selectCourseId
:
item
.
liveCourseId
,
selectPlanList
:
selectPlanList
})
}
closeRelatedPlanModalVisible
=
()
=>
{
this
.
setState
({
RelatedPlanModalVisible
:
false
})
}
onChangeSelectPlanList
=
(
selectPlanList
)
=>
{
RelatedPlanModalVisible
:
true
,
selectCourseId
:
item
.
liveCourseId
,
selectPlanList
:
selectPlanList
,
});
};
closeRelatedPlanModalVisible
=
()
=>
{
this
.
setState
({
selectPlanList
:
selectPlanList
})
}
onC
onfirmSelectPlanList
=
()
=>
{
RelatedPlanModalVisible
:
false
,
})
;
}
;
onC
hangeSelectPlanList
=
(
selectPlanList
)
=>
{
this
.
setState
({
RelatedPlanModalVisible
:
false
},()
=>
{
this
.
props
.
onChange
();})
}
selectPlanList
:
selectPlanList
,
});
};
onConfirmSelectPlanList
=
()
=>
{
this
.
setState
(
{
RelatedPlanModalVisible
:
false
,
},
()
=>
{
this
.
props
.
onChange
();
}
);
};
handleChangeTable
=
(
pagination
,
filters
,
sorter
)
=>
{
const
{
columnKey
,
order
}
=
sorter
;
const
{
query
}
=
this
.
props
;
let
_columnKey
;
let
_columnKey
;
let
_order
;
// 按创建时间升序排序
if
(
columnKey
===
'created'
&&
order
===
'ascend'
)
{
_columnKey
=
"CREATED"
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'created'
&&
order
===
'ascend'
)
{
_columnKey
=
'CREATED'
;
_order
=
'SORT_ASC'
;
}
// 按创建时间降序排序
if
(
columnKey
===
'created'
&&
order
===
'descend'
)
{
_columnKey
=
"CREATED"
;
_order
=
'SORT_DESC'
;}
if
(
columnKey
===
'created'
&&
order
===
'descend'
)
{
_columnKey
=
'CREATED'
;
_order
=
'SORT_DESC'
;
}
const
_query
=
{
...
query
,
sortMap
:
{}
sortMap
:
{},
};
_query
.
sortMap
[
_columnKey
]
=
_order
;
_query
.
sortMap
[
_columnKey
]
=
_order
;
this
.
props
.
onChange
(
_query
);
}
}
;
render
()
{
const
{
total
,
query
,
courseList
,
loading
}
=
this
.
props
;
const
{
total
,
query
,
courseList
,
loading
}
=
this
.
props
;
const
{
current
,
size
}
=
query
;
const
{
openDownloadModal
,
downloadUrl
,
url
,
columns
,
openCoursewareModal
,
editData
,
RelatedPlanModalVisible
,
selectCourseId
,
selectPlanList
}
=
this
.
state
;
const
{
openDownloadModal
,
downloadUrl
,
url
,
columns
,
openCoursewareModal
,
editData
,
RelatedPlanModalVisible
,
selectCourseId
,
selectPlanList
}
=
this
.
state
;
const
{
match
}
=
this
.
props
;
return
(
<
div
className=
"live-course-list"
>
<
Table
<
div
className=
'live-course-list'
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
bordered
size=
"middle"
size=
'middle'
pagination=
{
false
}
columns=
{
columns
}
loading=
{
loading
}
...
...
@@ -758,21 +797,21 @@ class LiveCourseList extends React.Component {
onChange=
{
this
.
handleChangeTable
}
rowKey=
{
(
row
)
=>
row
.
liveCourseId
}
/>
{
total
>
0
&&
<
div
className=
"box-footer"
>
{
total
>
0
&&
(
<
div
className=
'box-footer'
>
<
PageControl
current=
{
current
-
1
}
pageSize=
{
size
}
total=
{
parseInt
(
total
)
}
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
props
.
onChange
(
_query
)
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
props
.
onChange
(
_query
)
;
}
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
/>
</
div
>
}
{
this
.
state
.
shareLiveModal
}
)
}
{
this
.
state
.
shareLiveModal
}
{
openCoursewareModal
&&
(
<
ManageCoursewareModal
data=
{
editData
}
...
...
@@ -789,13 +828,13 @@ class LiveCourseList extends React.Component {
onCancel=
{
()
=>
{
this
.
setState
({
url
:
''
,
openDownloadModal
:
false
});
openDownloadModal
:
false
,
});
}
}
/>
)
}
{
RelatedPlanModalVisible
&&
<
RelatedPlanModal
{
RelatedPlanModalVisible
&&
(
<
RelatedPlanModal
onClose=
{
this
.
closeRelatedPlanModalVisible
}
visible=
{
RelatedPlanModalVisible
}
selectCourseId=
{
selectCourseId
}
...
...
@@ -803,12 +842,12 @@ class LiveCourseList extends React.Component {
onChange=
{
this
.
onChangeSelectPlanList
}
onConfirm=
{
this
.
onConfirmSelectPlanList
}
/>
}
<
iframe
src=
{
url
}
style=
{
{
display
:
"none"
}
}
/>
)
}
<
iframe
src=
{
url
}
style=
{
{
display
:
'none'
}
}
/>
<
Route
path=
{
`${match.url}/live-course-data`
}
component=
{
DataList
}
/>
</
div
>
)
)
;
}
}
export
default
withRouter
(
LiveCourseList
);
\ No newline at end of file
export
default
withRouter
(
LiveCourseList
);
src/modules/course-manage/graphics-course/components/GraphicsCourseList.jsx
View file @
510254f6
...
...
@@ -6,37 +6,29 @@
* @Description: 视频课-列表模块
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
import
React
from
'react'
;
import
{
Table
,
Modal
,
message
,
Tooltip
,
Switch
,
Dropdown
}
from
'antd'
;
import
{
PageControl
}
from
"@/components"
;
import
{
LIVE_SHARE_MAP
}
from
'@/common/constants/academic/cloudClass'
;
import
{
appId
,
shareUrl
,
LIVE_SHARE
}
from
'@/domains/course-domain/constants'
;
import
User
from
'@/common/js/user'
;
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
{
appId
,
LIVE_SHARE
}
from
'@/domains/course-domain/constants'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
ShareLiveModal
from
'@/modules/course-manage/modal/ShareLiveModal'
;
import
WatchDataModal
from
'../modal/WatchDataModal'
import
CourseService
from
"@/domains/course-domain/CourseService"
;
import
{
Dropdown
,
message
,
Modal
,
Switch
,
Tooltip
}
from
'antd'
;
import
React
from
'react'
;
import
RelatedPlanModal
from
'../../modal/RelatedPlanModal'
;
import
User
from
'@/common/js/user'
import
WatchDataModal
from
'../modal/WatchDataModal'
;
import
'./GraphicsCourseList.less'
;
const
ENV
=
process
.
env
.
DEPLOY_ENV
||
'dev'
;
const
defaultCoverUrl
=
'https://image.xiaomaiketang.com/xm/wFnpZtp2yB.png'
;
class
GraphicsCourseList
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
id
:
''
,
// 视频课ID
studentIds
:[],
RelatedPlanModalVisible
:
false
,
selectPlanList
:
{}
}
studentIds
:
[],
RelatedPlanModalVisible
:
false
,
selectPlanList
:
{},
}
;
}
componentDidMount
()
{
...
...
@@ -46,7 +38,7 @@ class GraphicsCourseList extends React.Component {
this
.
handleShowShareModal
(
_videoCourseItem
,
true
);
}
}
// 观看数据弹窗
handleShowWatchDataModal
=
(
record
)
=>
{
const
watchDataModal
=
(
...
...
@@ -55,25 +47,25 @@ class GraphicsCourseList extends React.Component {
data=
{
record
}
close=
{
()
=>
{
this
.
setState
({
watchDataModal
:
null
watchDataModal
:
null
,
});
}
}
/>
);
this
.
setState
({
watchDataModal
});
}
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
""
;
planArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
planArray
.
length
-
1
)
{
}
;
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
''
;
planArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
planArray
.
length
-
1
)
{
planStr
=
planStr
+
item
.
planName
+
'、'
;
}
else
{
planStr
=
planStr
+
item
.
planName
}
else
{
planStr
=
planStr
+
item
.
planName
;
}
})
return
planStr
}
})
;
return
planStr
;
}
;
// 请求表头
parseColumns
=
()
=>
{
const
columns
=
[
...
...
@@ -81,24 +73,24 @@ class GraphicsCourseList extends React.Component {
title
:
'图文课'
,
key
:
'scheduleName'
,
dataIndex
:
'scheduleName'
,
width
:
321
,
width
:
321
,
fixed
:
'left'
,
render
:
(
val
,
record
)
=>
{
const
{
coverUrl
,
scheduleVideoUrl
}
=
record
;
return
(
<
div
className=
"record__item"
>
<
div
className=
'record__item'
>
{
/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */
}
<
img
className=
"course-cover"
src=
{
coverUrl
||
defaultCoverUrl
}
/>
{
record
.
courseName
.
length
>
25
?
<
img
className=
'course-cover'
src=
{
coverUrl
||
defaultCoverUrl
}
/>
{
record
.
courseName
.
length
>
25
?
(
<
Tooltip
title=
{
record
.
courseName
}
>
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
</
Tooltip
>
:
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
}
)
:
(
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
)
}
</
div
>
)
}
)
;
}
,
},
{
title
:
'课程分类'
,
...
...
@@ -107,11 +99,12 @@ class GraphicsCourseList extends React.Component {
width
:
120
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"record__item"
>
{
record
.
categoryOneName
}{
record
.
categoryTwoName
?
`-${record.categoryTwoName}`
:
''
}
<
div
className=
'record__item'
>
{
record
.
categoryOneName
}
{
record
.
categoryTwoName
?
`-${record.categoryTwoName}`
:
''
}
</
div
>
)
}
)
;
}
,
},
{
title
:
'创建人'
,
...
...
@@ -120,42 +113,47 @@ class GraphicsCourseList extends React.Component {
width
:
100
,
render
:
(
val
)
=>
{
return
(
<
div
>
{
val
&&
<
Tooltip
title=
{
val
}
>
<
div
>
{
val
.
length
>
4
?
`${val.slice(0,4)}
...
`
:
val
}
</
div
>
<
div
>
{
val
&&
(
<
Tooltip
title=
{
val
}
>
<
div
>
{
val
.
length
>
4
?
`${val.slice(0, 4)}
...
`
:
val
}
</
div
>
</
Tooltip
>
}
</
div
>
)
}
)
}
</
div
>
)
;
}
,
},
{
title
:
<
span
>
<
span
>
学院展示
</
span
>
<
Tooltip
title=
{
<
div
>
开启后,学员可在学院内查看到此课程。
<
br
/>
关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。
</
div
>
}
><
i
className=
"icon iconfont"
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'normal'
}
}
>

</
i
></
Tooltip
>
</
span
>,
title
:
(
<
span
>
<
span
>
学院展示
</
span
>
<
Tooltip
title=
{
<
div
>
开启后,学员可在学院内查看到此课程。
<
br
/>
关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。
</
div
>
}
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'normal'
}
}
>

</
i
>
</
Tooltip
>
</
span
>
),
width
:
120
,
dataIndex
:
"courseware"
,
dataIndex
:
'courseware'
,
render
:
(
val
,
item
,
index
)
=>
{
return
(
<
Switch
defaultChecked=
{
item
.
shelfState
===
"YES"
?
true
:
false
}
onChange=
{
()
=>
this
.
changeShelfState
(
item
)
}
/>
)
return
<
Switch
defaultChecked=
{
item
.
shelfState
===
'YES'
?
true
:
false
}
onChange=
{
()
=>
this
.
changeShelfState
(
item
)
}
/>;
},
},
{
title
:
"观看学员数"
,
title
:
'观看学员数'
,
width
:
110
,
key
:
"watchUserCount"
,
dataIndex
:
"watchUserCount"
,
key
:
'watchUserCount'
,
dataIndex
:
'watchUserCount'
,
render
:
(
val
,
item
)
=>
{
return
(
<
div
className=
"watchUserCount"
>
{
val
}
</
div
>
)
return
<
div
className=
'watchUserCount'
>
{
val
}
</
div
>;
},
},
{
...
...
@@ -165,8 +163,8 @@ class GraphicsCourseList extends React.Component {
dataIndex
:
'created'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
;
}
,
},
{
title
:
'最近修改时间'
,
...
...
@@ -175,30 +173,33 @@ class GraphicsCourseList extends React.Component {
dataIndex
:
'updated'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
;
}
,
},
{
title
:
'关联项'
,
width
:
200
,
key
:
"planList"
,
dataIndex
:
"planList"
,
key
:
'planList'
,
dataIndex
:
'planList'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"related-task"
>
{
record
.
relatedPlanList
?
<
Tooltip
title=
{
this
.
handlePlanName
(
record
.
relatedPlanList
)
}
placement=
"top"
arrowPointAtCenter
>
{
record
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
planName
}
{
(
index
<
record
.
relatedPlanList
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
</
Tooltip
>
:
<
span
></
span
>
}
</
div
>
)
}
return
(
<
div
className=
'related-task'
>
{
record
.
relatedPlanList
?
(
<
Tooltip
title=
{
this
.
handlePlanName
(
record
.
relatedPlanList
)
}
placement=
'top'
arrowPointAtCenter
>
{
record
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
planName
}
{
index
<
record
.
relatedPlanList
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
);
})
}
</
Tooltip
>
)
:
(
<
span
></
span
>
)
}
</
div
>
);
},
},
{
title
:
'操作'
,
...
...
@@ -208,148 +209,150 @@ class GraphicsCourseList extends React.Component {
fixed
:
'right'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"operate"
>
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
handleShowWatchDataModal
(
record
)
}
>
观看数据
</
div
>
<
span
className=
"operate__item split"
>
|
</
span
>
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
handleShowShareModal
(
record
)
}
>
分享
</
div
>
<
span
className=
"operate__item split"
>
|
</
span
>
<
div
className=
'operate'
>
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleShowWatchDataModal
(
record
)
}
>
观看数据
</
div
>
<
span
className=
'operate__item split'
>
|
</
span
>
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleShowShareModal
(
record
)
}
>
分享
</
div
>
<
span
className=
'operate__item split'
>
|
</
span
>
<
Dropdown
overlay=
{
this
.
renderMoreOperate
(
record
)
}
>
<
span
className=
"more-operate"
>
<
span
className=
"operate-text"
>
更多
</
span
>
<
span
className=
"iconfont icon"
style=
{
{
color
:
"#2966FF"
}
}
>
<
span
className=
'more-operate'
>
<
span
className=
'operate-text'
>
更多
</
span
>
<
span
className=
'iconfont icon'
style=
{
{
color
:
'#2966FF'
}
}
>

</
span
>
</
span
>
</
Dropdown
>
</
div
>
)
}
}
)
;
}
,
}
,
];
return
columns
;
}
}
;
handleRelatedModalShow
=
(
item
)
=>
{
const
selectPlanList
=
{};
if
(
item
.
relatedPlanList
)
{
if
(
item
.
relatedPlanList
)
{
item
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
selectPlanList
[
item
.
planId
]
=
{}
selectPlanList
[
item
.
planId
]
=
{}
;
selectPlanList
[
item
.
planId
].
planId
=
item
.
planId
;
selectPlanList
[
item
.
planId
].
taskBaseVOList
=
[{
taskId
:
item
.
taskId
}];
return
item
})
return
item
;
})
;
}
this
.
setState
({
RelatedPlanModalVisible
:
true
,
selectCourseId
:
item
.
id
,
selectPlanList
:
selectPlanList
,
})
}
})
;
}
;
closeRelatedPlanModalVisible
=
()
=>
{
closeRelatedPlanModalVisible
=
()
=>
{
this
.
setState
({
RelatedPlanModalVisible
:
false
})
}
RelatedPlanModalVisible
:
false
,
})
;
}
;
onChangeSelectPlanList
=
(
selectPlanList
)
=>
{
this
.
setState
({
selectPlanList
:
selectPlanList
})
}
selectPlanList
:
selectPlanList
,
})
;
}
;
onConfirmSelectPlanList
=
()
=>
{
this
.
setState
({
RelatedPlanModalVisible
:
false
},
()
=>
{
this
.
props
.
onChange
();
});
}
this
.
setState
(
{
RelatedPlanModalVisible
:
false
,
},
()
=>
{
this
.
props
.
onChange
();
}
);
};
renderMoreOperate
=
(
item
)
=>
{
return
(
<
div
className=
"live-course-more-menu"
>
{
(
User
.
getUserRole
()
===
"CloudManager"
||
User
.
getUserRole
()
===
"StoreManager"
)
&&
<
div
className=
'live-course-more-menu'
>
{
(
User
.
getUserRole
()
===
'CloudManager'
||
User
.
getUserRole
()
===
'StoreManager'
)
&&
(
<
div
className=
"operate__item"
key=
"plan"
className=
'operate__item'
key=
'plan'
onClick=
{
()
=>
{
this
.
handleRelatedModalShow
(
item
);
}
}
>
关联培训计划
</
div
>
}
}
}
>
关联培训计划
</
div
>
)
}
<
div
className=
"operate__item"
key=
"edit"
className=
'operate__item'
key=
'edit'
onClick=
{
()
=>
{
RCHistory
.
push
(
`/create-graphics-course?type=edit&id=${item.id}`
);
}
}
>
编辑
</
div
>
<
div
className=
"operate__item"
key=
"delete"
onClick=
{
()
=>
this
.
handleDeleteGraphicsCourse
(
item
.
id
)
}
>
删除
</
div
>
}
}
>
编辑
</
div
>
<
div
className=
'operate__item'
key=
'delete'
onClick=
{
()
=>
this
.
handleDeleteGraphicsCourse
(
item
.
id
)
}
>
删除
</
div
>
</
div
>
)
}
//改变上架状态
changeShelfState
=
(
item
)
=>
{
let
_shelfState
=
item
.
shelfState
if
(
_shelfState
===
'NO'
)
{
_shelfState
=
"YES"
;
item
.
shelfState
=
"YES"
}
else
{
_shelfState
=
"NO"
item
.
shelfState
=
"NO"
)
;
}
;
//改变上架状态
changeShelfState
=
(
item
)
=>
{
let
_shelfState
=
item
.
shelfState
;
if
(
_shelfState
===
'NO'
)
{
_shelfState
=
'YES'
;
item
.
shelfState
=
'YES'
;
}
else
{
_shelfState
=
'NO'
;
item
.
shelfState
=
'NO'
;
}
const
params
=
{
const
params
=
{
courseId
:
item
.
id
,
shelfState
:
_shelfState
}
CourseService
.
changeVideoShelfState
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
_shelfState
===
"YES"
)
{
message
.
success
(
"已开启展示"
);
}
else
{
message
.
success
(
"已取消展示"
);
shelfState
:
_shelfState
,
}
;
CourseService
.
changeVideoShelfState
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
_shelfState
===
'YES'
)
{
message
.
success
(
'已开启展示'
);
}
else
{
message
.
success
(
'已取消展示'
);
}
}
})
}
})
;
}
;
// 删除视频课
handleDeleteGraphicsCourse
=
(
scheduleId
)
=>
{
Modal
.
confirm
({
title
:
'你确定要删除此视频课吗?'
,
content
:
'删除后,学员将不能进行观看。'
,
icon
:
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
okText
:
'确定'
,
okType
:
'danger'
,
cancelText
:
'取消'
,
onOk
:
()
=>
{
const
param
=
{
courseId
:
scheduleId
,
storeId
:
User
.
getStoreId
()
}
CourseService
.
delVideoSchedule
(
param
).
then
(()
=>
{
const
param
=
{
courseId
:
scheduleId
,
storeId
:
User
.
getStoreId
(),
};
CourseService
.
delVideoSchedule
(
param
).
then
(()
=>
{
message
.
success
(
'删除成功'
);
this
.
props
.
onChange
();
})
}
})
;
}
,
});
}
};
// 显示分享弹窗
handleShowShareModal
=
(
record
,
needStr
=
false
)
=>
{
const
{
id
,
scheduleVideoUrl
}
=
record
;
const
_appId
=
appId
;
const
_appId
=
appId
;
const
htmlUrl
=
`
${
LIVE_SHARE
}
graphics_detail/
${
id
}
?id=
${
User
.
getStoreId
()}
`
;
const
longUrl
=
htmlUrl
;
const
{
coverUrl
,
courseName
}
=
record
;
...
...
@@ -364,11 +367,11 @@ class GraphicsCourseList extends React.Component {
<
ShareLiveModal
needStr=
{
needStr
}
data=
{
shareData
}
type=
"graphicsClass"
title=
"图文课"
type=
'graphicsClass'
title=
'图文课'
close=
{
()
=>
{
this
.
setState
({
shareLiveModal
:
null
shareLiveModal
:
null
,
});
localStorage
.
setItem
(
'videoCourseItem'
,
''
);
}
}
...
...
@@ -376,89 +379,106 @@ class GraphicsCourseList extends React.Component {
);
this
.
setState
({
shareLiveModal
});
}
}
;
handleChangeTable
=
(
pagination
,
filters
,
sorter
)
=>
{
const
{
columnKey
,
order
}
=
sorter
;
const
{
query
}
=
this
.
props
;
let
{
order
:
_order
}
=
query
;
let
{
order
:
_order
}
=
query
;
// 按创建时间升序排序
if
(
columnKey
===
'created'
&&
order
===
'ascend'
)
{
_order
=
'CREATED_ASC'
;
}
if
(
columnKey
===
'created'
&&
order
===
'ascend'
)
{
_order
=
'CREATED_ASC'
;
}
// 按创建时间降序排序
if
(
columnKey
===
'created'
&&
order
===
'descend'
)
{
_order
=
'CREATED_DESC'
;
}
if
(
columnKey
===
'created'
&&
order
===
'descend'
)
{
_order
=
'CREATED_DESC'
;
}
// 按更新时间升序排序
if
(
columnKey
===
'updated'
&&
order
===
'ascend'
)
{
_order
=
'UPDATED_ASC'
;
}
if
(
columnKey
===
'updated'
&&
order
===
'ascend'
)
{
_order
=
'UPDATED_ASC'
;
}
// 按更新时间降序排序
if
(
columnKey
===
'updated'
&&
order
===
'descend'
)
{
_order
=
'UPDATED_DESC'
;
}
if
(
columnKey
===
'updated'
&&
order
===
'descend'
)
{
_order
=
'UPDATED_DESC'
;
}
const
_query
=
{
...
query
,
orderEnum
:
_order
orderEnum
:
_order
,
};
this
.
props
.
onChange
(
_query
);
}
handleRelatedModalShow
=
(
item
)
=>
{
}
;
handleRelatedModalShow
=
(
item
)
=>
{
const
selectPlanList
=
{};
if
(
item
.
relatedPlanList
)
{
item
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
selectPlanList
[
item
.
planId
]
=
{}
if
(
item
.
relatedPlanList
)
{
item
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
selectPlanList
[
item
.
planId
]
=
{}
;
selectPlanList
[
item
.
planId
].
planId
=
item
.
planId
;
selectPlanList
[
item
.
planId
].
taskBaseVOList
=
[{
taskId
:
item
.
taskId
}];
return
item
})
selectPlanList
[
item
.
planId
].
taskBaseVOList
=
[{
taskId
:
item
.
taskId
}];
return
item
;
})
;
}
this
.
setState
({
RelatedPlanModalVisible
:
true
,
selectCourseId
:
item
.
id
,
selectPlanList
:
selectPlanList
})
}
closeRelatedPlanModalVisible
=
()
=>
{
this
.
setState
({
RelatedPlanModalVisible
:
false
})
}
onChangeSelectPlanList
=
(
selectPlanList
)
=>
{
RelatedPlanModalVisible
:
true
,
selectCourseId
:
item
.
id
,
selectPlanList
:
selectPlanList
,
});
};
closeRelatedPlanModalVisible
=
()
=>
{
this
.
setState
({
selectPlanList
:
selectPlanList
})
}
onC
onfirmSelectPlanList
=
()
=>
{
RelatedPlanModalVisible
:
false
,
})
;
}
;
onC
hangeSelectPlanList
=
(
selectPlanList
)
=>
{
this
.
setState
({
RelatedPlanModalVisible
:
false
},()
=>
{
this
.
props
.
onChange
();})
}
selectPlanList
:
selectPlanList
,
});
};
onConfirmSelectPlanList
=
()
=>
{
this
.
setState
(
{
RelatedPlanModalVisible
:
false
,
},
()
=>
{
this
.
props
.
onChange
();
}
);
};
render
()
{
const
{
RelatedPlanModalVisible
,
selectCourseId
,
selectPlanList
}
=
this
.
state
;
const
{
dataSource
=
[],
totalCount
,
query
}
=
this
.
props
;
const
{
current
,
size
}
=
query
;
return
(
<
div
className=
"video-course-list"
>
<
Table
rowKey=
{
record
=>
record
.
id
}
<
div
className=
'video-course-list'
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
id
}
dataSource=
{
dataSource
}
columns=
{
this
.
parseColumns
()
}
onChange=
{
this
.
handleChangeTable
}
pagination=
{
false
}
scroll=
{
{
x
:
1500
}
}
scroll=
{
{
x
:
1500
}
}
bordered
className=
"video-list-table"
className=
'video-list-table'
/>
<
div
className=
"box-footer"
>
<
div
className=
'box-footer'
>
<
PageControl
current=
{
current
-
1
}
pageSize=
{
size
}
total=
{
totalCount
}
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
props
.
onChange
(
_query
)
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
props
.
onChange
(
_query
)
;
}
}
/>
</
div
>
{
RelatedPlanModalVisible
&&
<
RelatedPlanModal
</
div
>
{
RelatedPlanModalVisible
&&
(
<
RelatedPlanModal
onClose=
{
this
.
closeRelatedPlanModalVisible
}
visible=
{
RelatedPlanModalVisible
}
selectCourseId=
{
selectCourseId
}
...
...
@@ -466,9 +486,9 @@ class GraphicsCourseList extends React.Component {
onChange=
{
this
.
onChangeSelectPlanList
}
onConfirm=
{
this
.
onConfirmSelectPlanList
}
/>
}
{
RelatedPlanModalVisible
&&
<
RelatedPlanModal
)
}
{
RelatedPlanModalVisible
&&
(
<
RelatedPlanModal
onClose=
{
this
.
closeRelatedPlanModalVisible
}
visible=
{
RelatedPlanModalVisible
}
selectCourseId=
{
selectCourseId
}
...
...
@@ -476,11 +496,11 @@ class GraphicsCourseList extends React.Component {
onChange=
{
this
.
onChangeSelectPlanList
}
onConfirm=
{
this
.
onConfirmSelectPlanList
}
/>
}
{
this
.
state
.
shareLiveModal
}
{
this
.
state
.
watchDataModal
}
)
}
{
this
.
state
.
shareLiveModal
}
{
this
.
state
.
watchDataModal
}
</
div
>
)
)
;
}
}
...
...
src/modules/course-manage/graphics-course/modal/WatchDataModal.jsx
View file @
510254f6
/*
* @Author: 吴文洁
* @Date: 2020-05-19 11:01:31
* @Author: 吴文洁
* @Date: 2020-05-19 11:01:31
* @Last Modified by: chenshu
* @Last Modified time: 2021-03-24 15:13:38
* @Description 余额异常弹窗
*/
import
React
from
'react'
;
import
{
Table
,
Modal
,
Input
}
from
'antd'
;
import
{
PageControl
}
from
"@/components"
;
import
Service
from
"@/common/js/service"
;
import
User
from
'@/common/js/user'
import
{
Modal
,
Input
}
from
'antd'
;
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
Service
from
'@/common/js/service'
;
import
User
from
'@/common/js/user'
;
import
'./WatchDataModal.less'
;
import
dealTimeDuration
from
"../../utils/dealTimeDuration"
;
import
dealTimeDuration
from
'../../utils/dealTimeDuration'
;
const
{
Search
}
=
Input
;
class
WatchDataModal
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
visible
:
true
,
dataSource
:[],
size
:
10
,
visible
:
true
,
dataSource
:
[],
size
:
10
,
query
:
{
current
:
1
,
},
totalCount
:
0
totalCount
:
0
,
};
}
componentDidMount
()
{
this
.
handleFetchDataList
();
}
onClose
=
()
=>
{
onClose
=
()
=>
{
this
.
props
.
close
();
}
}
;
// 获取观看视频数据列表
// 获取观看视频数据列表
handleFetchDataList
=
()
=>
{
const
{
query
,
size
,
totalCount
}
=
this
.
state
const
{
query
,
size
,
totalCount
}
=
this
.
state
;
const
{
id
}
=
this
.
props
.
data
;
const
params
=
{
const
params
=
{
...
query
,
size
,
courseId
:
id
,
storeId
:
User
.
getStoreId
()
}
courseId
:
id
,
storeId
:
User
.
getStoreId
(),
}
;
Service
.
Hades
(
'public/hades/mediaCourseWatchInfo'
,
params
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
result
=
{}
}
=
res
;
const
{
records
=
[],
total
=
0
}
=
result
;
this
.
setState
({
dataSource
:
records
,
totalCount
:
Number
(
total
)
totalCount
:
Number
(
total
)
,
});
});
}
handleChangNickname
=
(
value
)
=>
{
}
;
handleChangNickname
=
(
value
)
=>
{
const
isPhone
=
(
value
||
''
).
match
(
/^
\d
+$/
);
const
{
query
}
=
this
.
state
;
if
(
isPhone
)
{
const
{
query
}
=
this
.
state
;
if
(
isPhone
)
{
query
.
phone
=
value
;
query
.
nickName
=
null
;
}
else
{
}
else
{
query
.
nickName
=
value
;
query
.
phone
=
null
;
}
query
.
current
=
1
;
this
.
setState
({
query
})
}
query
,
})
;
}
;
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
return
return
;
}
this
.
setState
({
size
},()
=>
{
this
.
handleFetchDataList
()})
}
this
.
setState
(
{
size
,
},
()
=>
{
this
.
handleFetchDataList
();
}
);
};
// 请求表头
parseColumns
=
()
=>
{
...
...
@@ -86,92 +92,110 @@ class WatchDataModal extends React.Component {
{
title
:
'观看学员'
,
key
:
'name'
,
dataIndex
:
'name'
dataIndex
:
'name'
,
},
{
title
:
'手机号'
,
key
:
'phone'
,
dataIndex
:
'phone'
dataIndex
:
'phone'
,
},
{
title
:
'观看者类型'
,
key
:
'userRole'
,
dataIndex
:
'userRole'
dataIndex
:
'userRole'
,
},
{
title
:
'首次观看时间'
,
key
:
'firstWatch'
,
dataIndex
:
'firstWatch'
,
render
:
(
val
)
=>
{
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
;
}
,
},
{
title
:
'观看总时长'
,
key
:
'watchDuration'
,
dataIndex
:
'watchDuration'
,
render
:
(
val
)
=>
{
return
<
span
>
{
val
?
dealTimeDuration
(
val
)
:
"00:00:00"
}
</
span
>
}
return
<
span
>
{
val
?
dealTimeDuration
(
val
)
:
'00:00:00'
}
</
span
>;
}
,
},
{
title
:
'学习进度'
,
key
:
'progress'
,
dataIndex
:
'progress'
,
render
:
(
val
)
=>
{
return
<
span
>
{
val
===
100
?
'已完成'
:
`${val || 0}%`
}
</
span
>
}
}
return
<
span
>
{
val
===
100
?
'已完成'
:
`${val || 0}%`
}
</
span
>;
}
,
}
,
];
return
columns
;
}
}
;
render
()
{
const
{
visible
,
size
,
dataSource
,
totalCount
,
query
}
=
this
.
state
;
const
{
visible
,
size
,
dataSource
,
totalCount
,
query
}
=
this
.
state
;
return
(
<
Modal
title=
"图文课观看数据"
visible=
{
visible
}
footer=
{
null
}
onCancel=
{
this
.
onClose
}
maskClosable=
{
false
}
className=
"watch-data-modal"
closable=
{
true
}
width=
{
800
}
closeIcon=
{
<
span
className=
"icon iconfont modal-close-icon"
>

</
span
>
}
>
<
div
className=
"search-container"
>
<
Search
placeholder=
"搜索学员姓名/手机号"
style=
{
{
width
:
200
}
}
onChange=
{
(
e
)
=>
{
this
.
handleChangNickname
(
e
.
target
.
value
)}
}
onSearch=
{
()
=>
{
this
.
handleFetchDataList
()}
}
enterButton=
{
<
span
className=
"icon iconfont"
>

</
span
>
}
/>
</
div
>
<
div
>
<
Table
rowKey=
{
record
=>
record
.
id
}
dataSource=
{
dataSource
}
columns=
{
this
.
parseColumns
()
}
pagination=
{
false
}
bordered
/>
{
dataSource
.
length
>
0
&&
<
div
className=
"box-footer"
>
<
PageControl
current=
{
query
.
current
-
1
}
pageSize=
{
size
}
total=
{
totalCount
}
size=
"small"
toPage=
{
(
page
)
=>
{
const
_query
=
{...
query
,
current
:
page
+
1
};
this
.
setState
({
query
:
_query
},()
=>
{
this
.
handleFetchDataList
()})
}
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
/>
</
div
>
}
</
div
>
</
Modal
>
)
<
Modal
title=
'图文课观看数据'
visible=
{
visible
}
footer=
{
null
}
onCancel=
{
this
.
onClose
}
maskClosable=
{
false
}
className=
'watch-data-modal'
closable=
{
true
}
width=
{
800
}
closeIcon=
{
<
span
className=
'icon iconfont modal-close-icon'
>

</
span
>
}
>
<
div
className=
'search-container'
>
<
Search
placeholder=
'搜索学员姓名/手机号'
style=
{
{
width
:
200
}
}
onChange=
{
(
e
)
=>
{
this
.
handleChangNickname
(
e
.
target
.
value
);
}
}
onSearch=
{
()
=>
{
this
.
handleFetchDataList
();
}
}
enterButton=
{
<
span
className=
'icon iconfont'
>

</
span
>
}
/>
</
div
>
<
div
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
id
}
dataSource=
{
dataSource
}
columns=
{
this
.
parseColumns
()
}
pagination=
{
false
}
bordered
/>
{
dataSource
.
length
>
0
&&
(
<
div
className=
'box-footer'
>
<
PageControl
current=
{
query
.
current
-
1
}
pageSize=
{
size
}
total=
{
totalCount
}
size=
'small'
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
setState
(
{
query
:
_query
,
},
()
=>
{
this
.
handleFetchDataList
();
}
);
}
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
/>
</
div
>
)
}
</
div
>
</
Modal
>
);
}
}
export
default
WatchDataModal
;
\ No newline at end of file
export
default
WatchDataModal
;
src/modules/course-manage/modal/AccountChargeRecords.jsx
View file @
510254f6
import
college
from
'@/common/lottie/college'
;
import
{
XMTable
}
from
'@/components'
;
import
{
Modal
}
from
'antd'
;
import
React
from
'react'
;
import
{
Modal
,
Table
}
from
"antd"
;
import
ChargeArgeement
from
"./ChargeArgeement"
;
import
"./AccountChargeModal.less"
;
class
AccountChargeRecords
extends
React
.
Component
{
import
'./AccountChargeModal.less'
;
import
ChargeArgeement
from
'./ChargeArgeement'
;
class
AccountChargeRecords
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
...
...
@@ -15,14 +17,12 @@ class AccountChargeRecords extends React.Component{
getList
=
()
=>
{
const
{
instId
}
=
window
.
currentUserInstInfo
;
axios
.
Business
(
"public/liveAssets/rechargeProtocol"
,
{
instId
})
.
then
((
res
)
=>
{
const
list
=
res
.
result
;
this
.
setState
({
list
,
});
axios
.
Business
(
'public/liveAssets/rechargeProtocol'
,
{
instId
}).
then
((
res
)
=>
{
const
list
=
res
.
result
;
this
.
setState
({
list
,
});
});
};
handleProtcol
=
(
id
)
=>
{
const
agreement
=
(
...
...
@@ -42,29 +42,28 @@ class AccountChargeRecords extends React.Component{
render
()
{
const
columns
=
[
{
title
:
"签订人"
,
dataIndex
:
"operatorName"
,
width
:
140
title
:
'签订人'
,
dataIndex
:
'operatorName'
,
width
:
140
,
},
{
title
:
"关联订单ID"
,
dataIndex
:
"orderId"
},
{
title
:
'关联订单ID'
,
dataIndex
:
'orderId'
},
{
title
:
"签订时间"
,
dataIndex
:
"createTime"
,
title
:
'签订时间'
,
dataIndex
:
'createTime'
,
render
:
(
text
,
record
)
=>
{
return
<
span
>
{
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
text
))
}
</
span
>;
return
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
text
))
}
</
span
>;
},
},
{
title
:
"签订协议"
,
dataIndex
:
"operate"
,
title
:
'签订协议'
,
dataIndex
:
'operate'
,
render
:
(
text
,
record
)
=>
{
return
(
<
div
style=
{
{
cursor
:
"pointer"
,
color
:
"#FC9C6B"
}
}
style=
{
{
cursor
:
'pointer'
,
color
:
'#FC9C6B'
}
}
onClick=
{
()
=>
{
this
.
handleProtcol
(
record
.
protocolId
);
}
}
>
}
}
>
《服务协议》
</
div
>
);
...
...
@@ -74,29 +73,31 @@ class AccountChargeRecords extends React.Component{
const
{
list
}
=
this
.
state
;
return
(
<
Modal
title=
"服务协议签订记录"
title=
'服务协议签订记录'
visible=
{
true
}
width=
{
680
}
footer=
{
null
}
maskClosable=
{
false
}
closeIcon=
{
<
span
className=
"icon iconfont modal-close-icon"
>

</
span
>
}
closeIcon=
{
<
span
className=
'icon iconfont modal-close-icon'
>

</
span
>
}
onCancel=
{
()
=>
{
this
.
props
.
close
();
}
}
>
}
}
>
<
div
>
<
div
style=
{
{
fontSize
:
"14px"
,
color
:
"#666666"
,
lineHeight
:
"20px"
,
fontSize
:
'14px'
,
color
:
'#666666'
,
lineHeight
:
'20px'
,
marginBottom
:
16
,
}
}
>
}
}
>
以下是本校区自助充值时签订协议的记录
</
div
>
<
Table
size=
"middle"
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
size=
'middle'
columns=
{
columns
}
dataSource=
{
list
}
pagination=
{
false
}
...
...
src/modules/course-manage/modal/ChargingDetailModal.jsx
View file @
510254f6
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
{
Modal
,
Tooltip
}
from
'antd'
;
import
React
from
'react'
;
import
{
Modal
,
Table
,
Tooltip
}
from
"antd"
;
import
{
ShowTips
,
PageControl
}
from
"@/components"
;
import
"./AccountChargeModal.less"
;
import
'./AccountChargeModal.less'
;
class
ChargingDetailModal
extends
React
.
Component
{
constructor
(
props
)
{
...
...
@@ -25,22 +26,20 @@ class ChargingDetailModal extends React.Component {
handleToPage
=
(
page
=
1
)
=>
{
const
params
=
_
.
clone
(
this
.
state
.
query
);
params
.
current
=
page
;
axios
.
Apollo
(
"public/businessLive/queryStudentVisitData"
,
params
)
.
then
((
res
)
=>
{
if
(
res
.
result
)
{
const
{
records
=
[],
total
}
=
res
.
result
;
this
.
setState
({
list
:
records
,
totalCount
:
total
,
query
:
params
,
});
}
});
axios
.
Apollo
(
'public/businessLive/queryStudentVisitData'
,
params
).
then
((
res
)
=>
{
if
(
res
.
result
)
{
const
{
records
=
[],
total
}
=
res
.
result
;
this
.
setState
({
list
:
records
,
totalCount
:
total
,
query
:
params
,
});
}
});
};
getTeacherData
=
()
=>
{
window
.
axios
.
Apollo
(
"public/businessLive/queryTeacherVisitData"
,
{
.
Apollo
(
'public/businessLive/queryTeacherVisitData'
,
{
liveCourseId
:
this
.
props
.
liveCourseId
,
})
.
then
((
res
)
=>
{
...
...
@@ -57,27 +56,27 @@ class ChargingDetailModal extends React.Component {
let
hours
=
Math
.
floor
(
time
/
3600
);
let
mins
=
Math
.
floor
(
diff
/
60
);
let
seconds
=
Math
.
floor
(
time
%
60
);
hours
=
hours
<
10
?
"0"
+
hours
:
hours
;
mins
=
mins
<
10
?
"0"
+
mins
:
mins
;
seconds
=
seconds
<
10
?
"0"
+
seconds
:
seconds
;
return
hours
+
":"
+
mins
+
":"
+
seconds
;
hours
=
hours
<
10
?
'0'
+
hours
:
hours
;
mins
=
mins
<
10
?
'0'
+
mins
:
mins
;
seconds
=
seconds
<
10
?
'0'
+
seconds
:
seconds
;
return
hours
+
':'
+
mins
+
':'
+
seconds
;
};
getColumns
=
(
type
)
=>
{
const
columns
=
[
{
title
:
type
==
"student"
?
"学生姓名"
:
"老师姓名"
,
dataIndex
:
"userName"
,
title
:
type
==
'student'
?
'学生姓名'
:
'老师姓名'
,
dataIndex
:
'userName'
,
},
{
title
:
"手机号"
,
dataIndex
:
"phone"
,
title
:
'手机号'
,
dataIndex
:
'phone'
,
render
:
(
text
,
record
)
=>
{
return
<
p
>
{
text
}
</
p
>;
},
},
{
title
:
"累计在线时长"
,
dataIndex
:
"totalDuration"
,
title
:
'累计在线时长'
,
dataIndex
:
'totalDuration'
,
render
:
(
text
,
record
)
=>
{
return
<
span
>
{
text
?
this
.
dealTimeDuration
(
text
)
:
'-'
}
</
span
>;
},
...
...
@@ -86,14 +85,14 @@ class ChargingDetailModal extends React.Component {
title
:
(
<
span
>
是否计费
<
Tooltip
title=
"仅对累计在线时长≥10分钟的老师或学员计费"
>
<
span
className=
"icon iconfont"
>

</
span
>
<
Tooltip
title=
'仅对累计在线时长≥10分钟的老师或学员计费'
>
<
span
className=
'icon iconfont'
>

</
span
>
</
Tooltip
>
</
span
>
),
dataIndex
:
"type"
,
dataIndex
:
'type'
,
render
:
(
text
,
record
)
=>
{
return
<
span
>
{
record
.
totalDuration
>
600
?
"计费"
:
"不计费"
}
</
span
>;
//大于十分钟的计费
return
<
span
>
{
record
.
totalDuration
>
600
?
'计费'
:
'不计费'
}
</
span
>;
//大于十分钟的计费
},
},
];
...
...
@@ -103,38 +102,45 @@ class ChargingDetailModal extends React.Component {
const
{
list
,
query
,
totalCount
,
teacherList
}
=
this
.
state
;
return
(
<
Modal
title=
"计费人数详情"
title=
'计费人数详情'
visible=
{
true
}
width=
{
680
}
maskClosable=
{
false
}
closeIcon=
{
<
span
className=
"icon iconfont modal-close-icon"
>

</
span
>
}
className=
"charging-detail-modal"
closeIcon=
{
<
span
className=
'icon iconfont modal-close-icon'
>

</
span
>
}
className=
'charging-detail-modal'
footer=
{
null
}
onCancel=
{
()
=>
{
this
.
props
.
close
();
}
}
>
}
}
>
<
div
>
<
div
style=
{
{
marginBottom
:
16
}
}
>
<
div
className=
"detail-title"
>
老师详情
</
div
>
<
Table
size=
"middle"
columns=
{
this
.
getColumns
(
"teacher"
)
}
<
div
className=
'detail-title'
>
老师详情
</
div
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
size=
'middle'
columns=
{
this
.
getColumns
(
'teacher'
)
}
dataSource=
{
teacherList
}
pagination=
{
false
}
bordered
/>
</
div
>
<
div
className=
"detail-title"
>
学生详情
</
div
>
<
Table
size=
"middle"
columns=
{
this
.
getColumns
(
"student"
)
}
<
div
className=
'detail-title'
>
学生详情
</
div
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
size=
'middle'
columns=
{
this
.
getColumns
(
'student'
)
}
dataSource=
{
list
}
pagination=
{
false
}
bordered
/>
<
PageControl
size=
"small"
size=
'small'
current=
{
query
.
current
-
1
}
pageSize=
{
query
.
size
}
total=
{
totalCount
}
...
...
src/modules/course-manage/modal/ClassRecordModal.jsx
View file @
510254f6
...
...
@@ -6,16 +6,14 @@
* @LastEditTime: 2021-02-01 14:00:19
*/
import
React
,
{
useState
,
useEffect
}
from
"react"
;
import
{
Modal
,
Table
,
Input
,
Button
,
message
,
Checkbox
,
Tooltip
}
from
"antd"
;
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
Bus
from
'@/core/bus'
;
import
{
PageControl
}
from
"@/components"
;
import
hasExportPermission
from
'../utils/hasExportPermission'
;
import
{
Button
,
Checkbox
,
Input
,
message
,
Modal
,
Tooltip
}
from
'antd'
;
import
React
from
'react'
;
import
dealTimeDuration
from
'../utils/dealTimeDuration'
;
import
"./ClassRecordModal.less"
;
import
hasExportPermission
from
'../utils/hasExportPermission'
;
import
'./ClassRecordModal.less'
;
const
{
Search
}
=
Input
;
...
...
@@ -28,7 +26,7 @@ class ClassRecordModal extends React.Component {
query
:
{
current
:
1
,
size
:
10
,
nameOrPhone
:
""
,
nameOrPhone
:
''
,
liveSignState
:
''
,
durationSort
:
null
,
liveCourseId
:
props
.
liveItem
.
liveCourseId
,
...
...
@@ -42,35 +40,31 @@ class ClassRecordModal extends React.Component {
fetchClassList
=
(
page
=
1
)
=>
{
const
params
=
_
.
clone
(
this
.
state
.
query
);
if
(
!
params
.
liveSignState
)
{
if
(
!
params
.
liveSignState
)
{
delete
params
.
liveSignState
;
}
params
.
current
=
page
;
window
.
axios
.
Apollo
(
"public/businessLive/queryStudentVisitData"
,
params
)
.
then
((
res
)
=>
{
if
(
res
.
result
)
{
const
{
records
=
[],
total
}
=
res
.
result
;
this
.
setState
({
classList
:
records
,
total
,
query
:
params
,
});
}
});
window
.
axios
.
Apollo
(
'public/businessLive/queryStudentVisitData'
,
params
).
then
((
res
)
=>
{
if
(
res
.
result
)
{
const
{
records
=
[],
total
}
=
res
.
result
;
this
.
setState
({
classList
:
records
,
total
,
query
:
params
,
});
}
});
};
fetchTeacherData
=
()
=>
{
const
{
liveCourseId
}
=
this
.
props
.
liveItem
;
window
.
axios
.
Apollo
(
"public/businessLive/queryTeacherVisitData"
,
{
liveCourseId
})
.
then
((
res
)
=>
{
if
(
res
.
result
)
{
const
teacherData
=
[
res
.
result
];
this
.
setState
({
teacherData
,
});
}
});
window
.
axios
.
Apollo
(
'public/businessLive/queryTeacherVisitData'
,
{
liveCourseId
}).
then
((
res
)
=>
{
if
(
res
.
result
)
{
const
teacherData
=
[
res
.
result
];
this
.
setState
({
teacherData
,
});
}
});
};
getColumns
=
(
type
)
=>
{
...
...
@@ -78,83 +72,85 @@ class ClassRecordModal extends React.Component {
const
source
=
this
.
props
.
type
;
const
columns
=
[
{
title
:
type
==
"student"
?
"学生姓名"
:
"老师姓名"
,
dataIndex
:
"userName"
,
title
:
type
==
'student'
?
'学生姓名'
:
'老师姓名'
,
dataIndex
:
'userName'
,
},
{
title
:
"手机号"
,
dataIndex
:
"phone"
,
title
:
'手机号'
,
dataIndex
:
'phone'
,
render
:
(
text
,
record
)
=>
{
return
(
<
p
>
{
!
(
(
!
window
.
NewVersion
&&
!
window
.
currentUserInstInfo
.
teacherId
)
||
(
window
.
NewVersion
&&
Permission
.
hasEduStudentPhone
())
)
&&
type
==
"student"
?
(
text
||
""
).
replace
(
/
(\d
{3}
)(\d
{4}
)(\d
{4}
)
/
,
"$1****$3"
)
{
!
((
!
window
.
NewVersion
&&
!
window
.
currentUserInstInfo
.
teacherId
)
||
(
window
.
NewVersion
&&
Permission
.
hasEduStudentPhone
()))
&&
type
==
'student'
?
(
text
||
''
).
replace
(
/
(\d
{3}
)(\d
{4}
)(\d
{4}
)
/
,
'$1****$3'
)
:
text
}
</
p
>
);
},
},
{
title
:
type
==
"student"
?
"观看直播次数"
:
"进入直播间次数"
,
dataIndex
:
"entryNum"
,
align
:
'right'
title
:
type
==
'student'
?
'观看直播次数'
:
'进入直播间次数'
,
dataIndex
:
'entryNum'
,
align
:
'right'
,
},
{
title
:
"累计上课时长"
,
dataIndex
:
type
==
"student"
?
"watchDuration"
:
"totalDuration"
,
sorter
:
type
==
"student"
?
(
a
,
b
)
=>
a
.
watchDuration
-
b
.
watchDuration
:
null
,
sortDirections
:
[
"descend"
,
"ascend"
],
title
:
'累计上课时长'
,
dataIndex
:
type
==
'student'
?
'watchDuration'
:
'totalDuration'
,
sorter
:
type
==
'student'
?
(
a
,
b
)
=>
a
.
watchDuration
-
b
.
watchDuration
:
null
,
sortDirections
:
[
'descend'
,
'ascend'
],
render
:
(
text
,
record
)
=>
{
//如无离开时间,就置空
return
(
<
span
>
{
text
?
dealTimeDuration
(
text
)
:
'00:00:00'
}
</
span
>
);
return
<
span
>
{
text
?
dealTimeDuration
(
text
)
:
'00:00:00'
}
</
span
>;
},
},
];
if
(
type
==
"student"
)
{
if
(
type
==
'student'
)
{
columns
.
push
({
title
:
<
span
>
到课状态
<
Tooltip
title=
{
<
div
>
学员累计上课时长达到
<
span
className=
"bulge"
>
{
consumeClassTime
}
</
span
>
分钟,即视为学员“到课”
</
div
>
}
><
span
className=
"iconfont"
>

</
span
></
Tooltip
></
span
>,
title
:
(
<
span
>
到课状态
<
Tooltip
title=
{
<
div
>
学员累计上课时长达到
<
span
className=
'bulge'
>
{
consumeClassTime
}
</
span
>
分钟,即视为学员“到课”
</
div
>
}
>
<
span
className=
'iconfont'
>

</
span
>
</
Tooltip
>
</
span
>
),
width
:
100
,
dataIndex
:
"signState"
,
dataIndex
:
'signState'
,
render
:
(
text
)
=>
{
if
(
text
)
{
return
<
span
>
{
text
===
'ABSENT'
?
'未到'
:
'到课'
}
</
span
>
if
(
text
)
{
return
<
span
>
{
text
===
'ABSENT'
?
'未到'
:
'到课'
}
</
span
>
;
}
else
{
return
<
span
>
-
</
span
>
return
<
span
>
-
</
span
>
;
}
}
})
if
(
source
)
{
}
,
})
;
if
(
source
)
{
columns
.
push
({
title
:
"获得奖杯数"
,
dataIndex
:
"trophyNum"
,
align
:
'right'
,
title
:
'获得奖杯数'
,
dataIndex
:
'trophyNum'
,
align
:
'right'
,
render
:
(
text
)
=>
{
return
<
span
>
{
text
?
text
:
0
}
</
span
>
}
})
return
<
span
>
{
text
?
text
:
0
}
</
span
>
;
}
,
})
;
}
}
return
columns
;
};
handleTableChange
=
(
pagination
,
filters
,
sorter
)
=>
{
const
query
=
this
.
state
.
query
;
if
(
!
_
.
isEmpty
(
sorter
))
{
if
(
sorter
.
columnKey
===
"totalDuration"
)
{
if
(
sorter
.
order
===
"ascend"
)
{
query
.
durationSort
=
"SORT_ASC"
;
}
else
if
(
sorter
.
order
===
"descend"
)
{
query
.
durationSort
=
"SORT_DESC"
;
if
(
sorter
.
columnKey
===
'totalDuration'
)
{
if
(
sorter
.
order
===
'ascend'
)
{
query
.
durationSort
=
'SORT_ASC'
;
}
else
if
(
sorter
.
order
===
'descend'
)
{
query
.
durationSort
=
'SORT_DESC'
;
}
this
.
setState
({
query
},
this
.
fetchClassList
);
}
...
...
@@ -165,20 +161,22 @@ class ClassRecordModal extends React.Component {
handleExportV5
=
()
=>
{
const
{
liveItem
,
type
}
=
this
.
props
;
const
{
liveCourseId
}
=
liveItem
;
const
url
=
!
type
?
'public/businessLive/exportLargeClassLiveAsync'
:
'public/businessLive/exportClassInteractionLiveSync'
const
url
=
!
type
?
'public/businessLive/exportLargeClassLiveAsync'
:
'public/businessLive/exportClassInteractionLiveSync'
;
window
.
axios
.
Apollo
(
url
,
{
liveCourseId
,
exportLiveType
:
'VISITOR'
}).
then
((
res
)
=>
{
Bus
.
trigger
(
'get_download_count'
);
Modal
.
success
({
title
:
'导出任务提交成功'
,
content
:
'请前往右上角的“任务中心”进行下载'
,
okText
:
'我知道了'
,
window
.
axios
.
Apollo
(
url
,
{
liveCourseId
,
exportLiveType
:
'VISITOR'
,
})
.
then
((
res
)
=>
{
Bus
.
trigger
(
'get_download_count'
);
Modal
.
success
({
title
:
'导出任务提交成功'
,
content
:
'请前往右上角的“任务中心”进行下载'
,
okText
:
'我知道了'
,
});
});
})
}
};
// 4.0导出
handleExport
=
()
=>
{
...
...
@@ -186,43 +184,41 @@ class ClassRecordModal extends React.Component {
const
{
liveCourseId
}
=
liveItem
;
const
url
=
!
type
?
'api-b/b/lesson/exportLargeClassLiveAsync'
:
'api-b/b/lesson/exportClassInteractionLiveSync'
;
window
.
axios
.
post
(
url
,
{
liveCourseId
,
exportLiveType
:
1
}).
then
((
res
)
=>
{
Bus
.
trigger
(
'get_download_count'
);
Modal
.
success
({
title
:
'导出任务提交成功'
,
content
:
'请前往右上角的“导出中心”进行下载'
,
okText
:
'我知道了'
,
window
.
axios
.
post
(
url
,
{
liveCourseId
,
exportLiveType
:
1
,
})
.
then
((
res
)
=>
{
Bus
.
trigger
(
'get_download_count'
);
Modal
.
success
({
title
:
'导出任务提交成功'
,
content
:
'请前往右上角的“导出中心”进行下载'
,
okText
:
'我知道了'
,
});
});
})
}
};
render
()
{
const
{
type
}
=
this
.
props
;
const
{
query
,
total
,
teacherData
,
classList
}
=
this
.
state
;
const
expandedColumns
=
[
{
title
:
"进入时间"
,
dataIndex
:
"entryTime"
,
key
:
"entryTime"
,
render
:
(
text
)
=>
(
<
span
>
{
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
text
))
}
</
span
>
),
title
:
'进入时间'
,
dataIndex
:
'entryTime'
,
key
:
'entryTime'
,
render
:
(
text
)
=>
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
text
))
}
</
span
>,
},
{
title
:
"离开时间"
,
dataIndex
:
"leaveTime"
,
key
:
"leaveTime"
,
render
:
(
text
)
=>
(
<
span
>
{
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
text
))
}
</
span
>
),
title
:
'离开时间'
,
dataIndex
:
'leaveTime'
,
key
:
'leaveTime'
,
render
:
(
text
)
=>
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
text
))
}
</
span
>,
},
{
title
:
"上课时长"
,
dataIndex
:
"lookingDuration"
,
key
:
"lookingDuration"
,
title
:
'上课时长'
,
dataIndex
:
'lookingDuration'
,
key
:
'lookingDuration'
,
render
:
(
text
,
record
)
=>
{
return
<
span
>
{
text
?
dealTimeDuration
(
text
)
:
'-'
}
</
span
>;
},
...
...
@@ -230,64 +226,73 @@ class ClassRecordModal extends React.Component {
];
return
(
<
Modal
title=
"上课记录"
title=
'上课记录'
visible=
{
true
}
footer=
{
null
}
width=
{
680
}
maskClosable=
{
false
}
closeIcon=
{
<
span
className=
"icon iconfont modal-close-icon"
>

</
span
>
}
className=
"class-record-modal"
closeIcon=
{
<
span
className=
'icon iconfont modal-close-icon'
>

</
span
>
}
className=
'class-record-modal'
onCancel=
{
()
=>
{
this
.
props
.
close
();
}
}
>
}
}
>
<
div
>
<
p
className=
"class-record-title"
style=
{
{
marginBottom
:
18
}
}
>
老师上课数据
<
p
className=
'class-record-title'
style=
{
{
marginBottom
:
18
}
}
>
老师上课数据
</
p
>
<
Table
size=
"small"
columns=
{
this
.
getColumns
(
"teacher"
)
}
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
size=
'small'
columns=
{
this
.
getColumns
(
'teacher'
)
}
dataSource=
{
teacherData
}
pagination=
{
false
}
className=
"table-no-scrollbar"
className=
'table-no-scrollbar'
expandedRowRender=
{
(
record
)
=>
{
if
(
record
.
visitorInfoVOList
&&
record
.
visitorInfoVOList
.
length
>
0
)
{
if
(
record
.
visitorInfoVOList
&&
record
.
visitorInfoVOList
.
length
>
0
)
{
return
(
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
columns=
{
expandedColumns
}
dataSource=
{
record
.
visitorInfoVOList
}
size=
{
"small"
}
className=
"no-scrollbar expanded-table"
size=
{
'small'
}
className=
'no-scrollbar expanded-table'
pagination=
{
false
}
></
Table
>
/
>
);
}
else
{
return
<
div
className=
"live-table--empty"
>
暂无上课数据
</
div
>;
return
<
div
className=
'live-table--empty'
>
暂无上课数据
</
div
>;
}
}
}
></
Table
>
<
div
className=
"student-wrapper"
>
<
section
className=
"class-record-title"
>
学员上课数据
</
section
>
/
>
<
div
className=
'student-wrapper'
>
<
section
className=
'class-record-title'
>
学员上课数据
</
section
>
<
section
>
<
Checkbox
style=
{
{
lineHeight
:
'33px'
}
}
onChange=
{
(
e
)
=>
{
const
param
=
_
.
clone
(
this
.
state
.
query
);
param
.
current
=
1
;
param
.
liveSignState
=
e
.
target
.
checked
?
'SIGN'
:
''
;
this
.
setState
({
query
:
param
},
()
=>
{
this
.
fetchClassList
();
})
}
}
>
只看“到课”学员
</
Checkbox
>
<
Checkbox
style=
{
{
lineHeight
:
'33px'
}
}
onChange=
{
(
e
)
=>
{
const
param
=
_
.
clone
(
this
.
state
.
query
);
param
.
current
=
1
;
param
.
liveSignState
=
e
.
target
.
checked
?
'SIGN'
:
''
;
this
.
setState
(
{
query
:
param
,
},
()
=>
{
this
.
fetchClassList
();
}
);
}
}
>
只看“到课”学员
</
Checkbox
>
<
Search
className=
"student-wrapper__search"
placeholder=
"搜索学员姓名/手机号"
className=
'student-wrapper__search'
placeholder=
'搜索学员姓名/手机号'
style=
{
{
width
:
200
,
marginBottom
:
0
}
}
onSearch=
{
(
value
)
=>
{
const
param
=
_
.
clone
(
this
.
state
.
query
);
...
...
@@ -303,52 +308,62 @@ class ClassRecordModal extends React.Component {
);
}
}
/>
{
hasExportPermission
(
type
)
&&
<
Button
onClick=
{
_
.
debounce
(()
=>
{
if
(
!
classList
.
length
)
{
message
.
warning
(
'暂无数据可导出'
);
return
;
}
if
(
window
.
NewVersion
)
{
this
.
handleExportV5
();
}
else
{
this
.
handleExport
();
}
},
500
,
true
)
}
>
导出
</
Button
>
}
{
hasExportPermission
(
type
)
&&
(
<
Button
onClick=
{
_
.
debounce
(
()
=>
{
if
(
!
classList
.
length
)
{
message
.
warning
(
'暂无数据可导出'
);
return
;
}
if
(
window
.
NewVersion
)
{
this
.
handleExportV5
();
}
else
{
this
.
handleExport
();
}
},
500
,
true
)
}
>
导出
</
Button
>
)
}
</
section
>
</
div
>
<
div
>
<
Table
size=
"small"
columns=
{
this
.
getColumns
(
"student"
)
}
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
size=
'small'
columns=
{
this
.
getColumns
(
'student'
)
}
dataSource=
{
classList
}
pagination=
{
false
}
className=
"table-no-scrollbar"
className=
'table-no-scrollbar'
onChange=
{
this
.
handleTableChange
}
expandedRowRender=
{
(
record
)
=>
{
if
(
record
.
visitorInfoVOList
&&
record
.
visitorInfoVOList
.
length
>
0
)
{
if
(
record
.
visitorInfoVOList
&&
record
.
visitorInfoVOList
.
length
>
0
)
{
return
(
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
columns=
{
expandedColumns
}
dataSource=
{
record
.
visitorInfoVOList
}
size=
{
"small"
}
className=
"no-scrollbar expanded-table"
size=
{
'small'
}
className=
'no-scrollbar expanded-table'
pagination=
{
false
}
></
Table
>
/
>
);
}
else
{
return
<
div
className=
"live-table--empty"
>
暂无上课数据
</
div
>;
return
<
div
className=
'live-table--empty'
>
暂无上课数据
</
div
>;
}
}
}
></
Table
>
/
>
<
PageControl
size=
"small"
size=
'small'
current=
{
query
.
current
-
1
}
pageSize=
{
query
.
size
}
total=
{
total
}
...
...
src/modules/course-manage/modal/LiveStudentListModal.jsx
View file @
510254f6
...
...
@@ -5,61 +5,49 @@
* @Last Modified time: 2020-07-22 16:25:30
* 查看学员名单
*/
import
React
from
"react"
;
import
{
Modal
,
Button
,
Input
,
Table
,
Popconfirm
,
message
,
Tooltip
,
}
from
"antd"
;
import
PropTypes
from
"prop-types"
;
import
{
PageControl
}
from
"@/components"
;
import
SelectStudent
from
"./select-student/index"
;
import
"./LiveStudentListModal.less"
;
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
{
Button
,
Input
,
message
,
Modal
,
Popconfirm
,
Tooltip
}
from
'antd'
;
import
PropTypes
from
'prop-types'
;
import
React
from
'react'
;
import
'./LiveStudentListModal.less'
;
import
SelectStudent
from
'./select-student/index'
;
const
{
Search
}
=
Input
;
const
isTeacher
=
!!
window
.
currentUserInstInfo
.
teacherId
;
const
liveTypeMap
=
{
LIVE
:
"直播"
,
PLAYBACK
:
"回放"
,
LIVE
:
'直播'
,
PLAYBACK
:
'回放'
,
};
const
expandedColumns
=
[
{
title
:
"类型"
,
dataIndex
:
"liveType"
,
key
:
"liveType"
,
title
:
'类型'
,
dataIndex
:
'liveType'
,
key
:
'liveType'
,
render
:
(
text
)
=>
<
span
>
{
liveTypeMap
[
text
]
}
</
span
>,
},
{
title
:
"进入时间"
,
dataIndex
:
"entryTime"
,
key
:
"entryTime"
,
render
:
(
text
)
=>
(
<
span
>
{
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
text
))
}
</
span
>
),
title
:
'进入时间'
,
dataIndex
:
'entryTime'
,
key
:
'entryTime'
,
render
:
(
text
)
=>
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
text
))
}
</
span
>,
},
{
title
:
"离开时间"
,
dataIndex
:
"leaveTime"
,
key
:
"leaveTime"
,
render
:
(
text
)
=>
(
<
span
>
{
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
text
))
}
</
span
>
),
title
:
'离开时间'
,
dataIndex
:
'leaveTime'
,
key
:
'leaveTime'
,
render
:
(
text
)
=>
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
text
))
}
</
span
>,
},
{
title
:
"观看时长"
,
dataIndex
:
"lookingTime"
,
key
:
"lookingTime"
},
{
title
:
'观看时长'
,
dataIndex
:
'lookingTime'
,
key
:
'lookingTime'
},
];
const
STATUS_ENUM
=
{
'NORMAL'
:
'在读'
,
'POTENTIAL'
:
'潜在'
,
'HISTORY'
:
'历史'
,
'ABANDON'
:
'废弃'
,
NORMAL
:
'在读'
,
POTENTIAL
:
'潜在'
,
HISTORY
:
'历史'
,
ABANDON
:
'废弃'
,
};
class
LiveStudentListModal
extends
React
.
Component
{
...
...
@@ -86,76 +74,72 @@ class LiveStudentListModal extends React.Component {
fetchStudentList
=
(
current
=
1
)
=>
{
const
query
=
_
.
clone
(
this
.
state
.
query
);
query
.
current
=
current
;
window
.
axios
.
Apollo
(
"public/businessLive/getStudentList"
,
query
)
.
then
((
res
)
=>
{
const
{
records
=
[],
total
}
=
res
.
result
;
window
.
axios
.
Apollo
(
'public/businessLive/getStudentList'
,
query
).
then
((
res
)
=>
{
const
{
records
=
[],
total
}
=
res
.
result
;
this
.
setState
({
studentList
:
records
,
total
,
query
,
});
this
.
setState
({
studentList
:
records
,
total
,
query
,
});
});
};
hanldSelect
=
()
=>
{
const
{
query
:
{
liveCourseId
}
}
=
this
.
state
;
axios
.
Apollo
(
'public/businessLive/getCourseDetail'
,
{
liveCourseId
})
.
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
consumeStudentIds
,
studentIds
}
=
result
;
const
studentList
=
[];
const
excludeStudentIds
=
studentIds
;
const
excludeConsumeStudentIds
=
_
.
pluck
(
consumeStudentIds
,
'studentId'
);
this
.
setState
({
excludeStudentIds
,
excludeConsumeStudentIds
});
const
{
query
:
{
liveCourseId
},
}
=
this
.
state
;
axios
.
Apollo
(
'public/businessLive/getCourseDetail'
,
{
liveCourseId
}).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
consumeStudentIds
,
studentIds
}
=
result
;
const
studentList
=
[];
const
excludeStudentIds
=
studentIds
;
const
excludeConsumeStudentIds
=
_
.
pluck
(
consumeStudentIds
,
'studentId'
);
this
.
setState
({
excludeStudentIds
,
excludeConsumeStudentIds
});
_
.
each
(
studentIds
,
(
item
)
=>
{
studentList
.
push
({
studentId
:
item
});
});
const
studentModal
=
(
<
SelectStudent
liveCourseId=
{
liveCourseId
}
studentList=
{
studentList
}
excludeStudentIds=
{
excludeStudentIds
}
after=
{
true
}
close=
{
()
=>
{
this
.
setState
({
studentModal
:
null
});
}
}
onSelect=
{
(
studentIds
)
=>
{
this
.
handleSelectStudent
(
studentIds
)
}
}
/>
)
_
.
each
(
studentIds
,
(
item
)
=>
{
studentList
.
push
({
studentId
:
item
});
});
this
.
setState
({
studentModal
});
})
const
studentModal
=
(
<
SelectStudent
liveCourseId=
{
liveCourseId
}
studentList=
{
studentList
}
excludeStudentIds=
{
excludeStudentIds
}
after=
{
true
}
close=
{
()
=>
{
this
.
setState
({
studentModal
:
null
});
}
}
onSelect=
{
(
studentIds
)
=>
{
this
.
handleSelectStudent
(
studentIds
);
}
}
/>
);
this
.
setState
({
studentModal
});
});
};
handleSelectStudent
=
(
studentIds
)
=>
{
const
{
liveType
,
liveCourseId
,
podium
,
quota
,
}
=
this
.
props
.
liveItem
;
const
{
liveType
,
liveCourseId
,
podium
,
quota
}
=
this
.
props
.
liveItem
;
if
(
liveType
!==
"SMALL_CLASS_INTERACTION"
&&
(
studentIds
.
length
)
>
1000
)
{
if
(
liveType
!==
'SMALL_CLASS_INTERACTION'
&&
studentIds
.
length
>
1000
)
{
message
.
info
(
`最多选择1000人`
);
return
;
}
else
if
(
liveType
==
"SMALL_CLASS_INTERACTION"
&&
(
studentIds
.
length
)
>
podium
)
{
}
else
if
(
liveType
==
'SMALL_CLASS_INTERACTION'
&&
studentIds
.
length
>
podium
)
{
message
.
info
(
`最多选择
${
podium
}
人`
);
return
;
}
else
{
const
param
=
{
liveCourseId
:
liveCourseId
,
studentIds
:
studentIds
studentIds
:
studentIds
,
};
axios
.
Apollo
(
"public/businessLive/addCourseStu"
,
param
).
then
(
res
=>
{
axios
.
Apollo
(
'public/businessLive/addCourseStu'
,
param
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
this
.
setState
({
studentModal
:
null
studentModal
:
null
,
});
message
.
success
(
"学员变更成功"
);
message
.
success
(
'学员变更成功'
);
this
.
fetchStudentList
();
this
.
props
.
refresh
();
}
...
...
@@ -170,59 +154,51 @@ class LiveStudentListModal extends React.Component {
liveCourseId
,
studentId
,
};
window
.
axios
.
Apollo
(
"public/businessLive/moveCourseStu"
,
param
)
.
then
((
res
)
=>
{
message
.
success
(
"移除学员成功"
);
this
.
fetchStudentList
(
1
);
this
.
props
.
refresh
();
});
window
.
axios
.
Apollo
(
'public/businessLive/moveCourseStu'
,
param
).
then
((
res
)
=>
{
message
.
success
(
'移除学员成功'
);
this
.
fetchStudentList
(
1
);
this
.
props
.
refresh
();
});
};
parseColumns
=
()
=>
{
const
{
type
,
liveItem
}
=
this
.
props
;
const
columns
=
[
{
title
:
"姓名"
,
dataIndex
:
"studentName"
,
key
:
"studentName"
},
{
title
:
'姓名'
,
dataIndex
:
'studentName'
,
key
:
'studentName'
},
{
title
:
"手机号"
,
dataIndex
:
"phone"
,
title
:
'手机号'
,
dataIndex
:
'phone'
,
width
:
150
,
key
:
"phone"
,
key
:
'phone'
,
render
:
(
text
,
record
)
=>
{
return
(
<
p
>
{
!
(
(
!
window
.
NewVersion
&&
!
window
.
currentUserInstInfo
.
teacherId
)
||
(
window
.
NewVersion
&&
Permission
.
hasEduStudentPhone
())
)
?
(
text
||
""
).
replace
(
/
(\d
{3}
)(\d
{4}
)(\d
{4}
)
/
,
"$1****$3"
)
{
!
((
!
window
.
NewVersion
&&
!
window
.
currentUserInstInfo
.
teacherId
)
||
(
window
.
NewVersion
&&
Permission
.
hasEduStudentPhone
()))
?
(
text
||
''
).
replace
(
/
(\d
{3}
)(\d
{4}
)(\d
{4}
)
/
,
'$1****$3'
)
:
text
}
<
Tooltip
title=
{
`${record.wechatStatus ? "已绑定微信" : "未绑定微信"}`
}
>
<
Tooltip
title=
{
`${record.wechatStatus ? '已绑定微信' : '未绑定微信'}`
}
>
<
span
className=
"icon iconfont"
className=
'icon iconfont'
style=
{
record
.
wechatStatus
?
{
color
:
"#00D20D"
,
fontSize
:
"16px"
,
color
:
'#00D20D'
,
fontSize
:
'16px'
,
marginLeft
:
6
,
}
:
{
color
:
"#BFBFBF"
,
fontSize
:
"16px"
,
color
:
'#BFBFBF'
,
fontSize
:
'16px'
,
marginLeft
:
6
,
}
}
>
}
>

</
span
>
</
Tooltip
>
</
p
>
);
},
}
}
,
];
// 非互动班课类型增加学员类型
...
...
@@ -233,100 +209,97 @@ class LiveStudentListModal extends React.Component {
dataIndex
:
'statusEnum'
,
render
:
(
val
)
=>
{
return
STATUS_ENUM
[
val
];
}
}
,
});
}
// 如果是非视频课, 显示操作的条件是课程未开始,且不是T端
// 如果是视频课,那么只要满足不是T端就可以了
if
((
liveItem
.
courseState
===
"UN_START"
||
type
===
'videoCourse'
)
&&
!
isTeacher
)
{
if
((
liveItem
.
courseState
===
'UN_START'
||
type
===
'videoCourse'
)
&&
!
isTeacher
)
{
// 未开始
columns
.
push
({
title
:
"操作"
,
dataIndex
:
"operate"
,
key
:
"operate"
,
align
:
'right'
,
title
:
'操作'
,
dataIndex
:
'operate'
,
key
:
'operate'
,
align
:
'right'
,
render
:
(
text
,
record
)
=>
{
return
(
<
Popconfirm
title=
"你确定要移出这个学员吗?"
title=
'你确定要移出这个学员吗?'
onConfirm=
{
()
=>
{
// 如果是非视频课,且直播间类型是自研, 且晚于开课前30分钟, 不允许移出
if
(
liveItem
.
channel
==
"XIAOMAI"
&&
liveItem
.
startTime
-
Date
.
now
()
<
1800000
)
{
if
(
liveItem
.
channel
==
'XIAOMAI'
&&
liveItem
.
startTime
-
Date
.
now
()
<
1800000
)
{
Modal
.
warning
({
title
:
"不可移出"
,
icon
:
(
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>
),
content
:
"晚于开课前30分钟,不能移出学员"
,
title
:
'不可移出'
,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
content
:
'晚于开课前30分钟,不能移出学员'
,
});
}
else
{
this
.
removeStudent
(
record
.
studentId
);
}
}
}
>
<
span
className=
"live-operate"
>
移出
</
span
>
}
}
>
<
span
className=
'live-operate'
>
移出
</
span
>
</
Popconfirm
>
);
},
});
}
return
columns
;
}
}
;
render
()
{
const
{
studentList
,
query
,
total
}
=
this
.
state
;
const
{
current
,
size
}
=
query
;
return
(
<
Modal
title=
"查看学员名单"
title=
'查看学员名单'
visible=
{
true
}
width=
{
680
}
footer=
{
null
}
maskClosable=
{
false
}
closeIcon=
{
<
span
className=
"icon iconfont modal-close-icon"
>

</
span
>
}
className=
"live-student-list-modal"
onCancel=
{
this
.
props
.
close
}
>
closeIcon=
{
<
span
className=
'icon iconfont modal-close-icon'
>

</
span
>
}
className=
'live-student-list-modal'
onCancel=
{
this
.
props
.
close
}
>
{
/* 任意状态都可以添加学员 */
}
<
div
className=
"live-student-list-modal__operate"
>
{
!
isTeacher
&&
<
Button
type=
"primary"
onClick=
{
this
.
hanldSelect
}
>
<
div
className=
'live-student-list-modal__operate'
>
{
!
isTeacher
&&
(
<
Button
type=
'primary'
onClick=
{
this
.
hanldSelect
}
>
添加上课学员
</
Button
>
}
)
}
<
Search
placeholder=
"搜索学员姓名/手机号"
placeholder=
'搜索学员姓名/手机号'
style=
{
{
width
:
200
}
}
onSearch=
{
(
value
)
=>
{
this
.
setState
({
query
:
{
...
this
.
state
.
query
,
nameOrPhone
:
value
this
.
setState
(
{
query
:
{
...
this
.
state
.
query
,
nameOrPhone
:
value
,
},
},
()
=>
{
this
.
fetchStudentList
(
1
);
}
},
()
=>
{
this
.
fetchStudentList
(
1
);
});
);
}
}
className=
"search"
className=
'search'
/>
</
div
>
<
Table
size=
"small"
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
size=
'small'
columns=
{
this
.
parseColumns
()
}
dataSource=
{
studentList
}
pagination=
{
false
}
scroll=
{
{
y
:
400
}
}
className=
"live-student-table table-no-scrollbar"
className=
'live-student-table table-no-scrollbar'
/>
<
PageControl
size=
"small"
size=
'small'
current=
{
current
-
1
}
pageSize=
{
size
}
total=
{
Number
(
total
)
}
...
...
src/modules/course-manage/modal/ManageCoursewareModal.jsx
View file @
510254f6
/*
* @Author: 吴文洁
* @Date: 2020-06-22 14:26:37
* @Author: 吴文洁
* @Date: 2020-06-22 14:26:37
* @Last Modified by: chenshu
* @Last Modified time: 2021-06-08 18:18:46
*/
import
React
from
'react'
;
import
{
Modal
,
Button
,
Table
,
message
,
Tooltip
,
Spin
,
Popconfirm
}
from
'antd'
;
import
{
QuestionCircleOutlined
,
LoadingOutlined
}
from
"@ant-design/icons"
;
import
_
from
'underscore'
;
import
moment
from
'moment'
;
import
Lottie
from
"lottie-web"
;
import
{
FileTypeIcon
,
FileVerifyMap
}
from
'@/common/constants/academic/lessonEnum'
;
import
{
DEFAULT_SIZE_UNIT
,
suffixType
}
from
'@/common/constants/academic/liveEnum'
;
import
Service
from
'@/common/js/service'
;
import
User
from
'@/common/js/user'
;
import
{
suffixType
,
DEFAULT_SIZE_UNIT
}
from
'@/common/constants/academic/liveEnum
'
;
import
{
FileVerifyMap
,
FileTypeIcon
}
from
'@/common/constants/academic/lessonEnum
'
;
import
ScanFileModal
from
'@/modules/prepare-lesson/modal/ScanFileModal'
import
college
from
'@/common/lottie/college
'
;
import
{
XMTable
}
from
'@/components
'
;
import
ScanFileModal
from
'@/modules/prepare-lesson/modal/ScanFileModal'
;
import
SelectPrepareFileModal
from
'@/modules/prepare-lesson/modal/SelectPrepareFileModal'
;
import
Service
from
'@/common/js/service'
;
import
{
LoadingOutlined
,
QuestionCircleOutlined
}
from
'@ant-design/icons'
;
import
{
Button
,
message
,
Modal
,
Popconfirm
,
Spin
,
Tooltip
}
from
'antd'
;
import
Lottie
from
'lottie-web'
;
import
moment
from
'moment'
;
import
React
from
'react'
;
import
_
from
'underscore'
;
import
'./ManageCoursewareModal.less'
;
class
ManageCoursewareModal
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
)
super
(
props
)
;
this
.
state
=
{
list
:
[],
uploadObject
:
{},
...
...
@@ -32,36 +31,34 @@ class ManageCoursewareModal extends React.Component {
editData
:
{},
scanFileModal
:
false
,
isLessonPermission
:
false
,
diskList
:
[],
// 机构可见的磁盘目录
selectedFileList
:
[]
}
diskList
:
[],
// 机构可见的磁盘目录
selectedFileList
:
[]
,
}
;
}
componentDidMount
()
{
this
.
getCoursewareList
();
var
animation
=
Lottie
.
loadAnimation
({
path
:
"https://image.xiaomaiketang.com/xm/SDBkP7mbJX.json"
,
name
:
"test"
,
renderer
:
"svg"
,
path
:
'https://image.xiaomaiketang.com/xm/SDBkP7mbJX.json'
,
name
:
'test'
,
renderer
:
'svg'
,
loop
:
true
,
autoplay
:
true
,
container
:
document
.
getElementById
(
"lottie-box"
)
container
:
document
.
getElementById
(
'lottie-box'
),
});
}
// 获取课件列表
getCoursewareList
(
id
)
{
const
{
liveCourseId
}
=
this
.
props
.
data
;
const
params
=
{
const
params
=
{
liveCourseId
,
storeId
:
User
.
getStoreId
()
}
storeId
:
User
.
getStoreId
(),
}
;
Service
.
Hades
(
'/anon/courseWare/getCourseWareDocList'
,
params
).
then
((
res
)
=>
{
let
newList
=
[];
const
{
list
}
=
this
.
state
;
const
data
=
_
.
find
(
res
.
result
,
item
=>
item
.
docId
==
id
);
const
data
=
_
.
find
(
res
.
result
,
(
item
)
=>
item
.
docId
==
id
);
if
(
id
&&
!
_
.
isEmpty
(
data
))
{
newList
=
list
.
map
((
item
)
=>
{
if
(
item
.
id
==
id
)
{
...
...
@@ -80,7 +77,7 @@ class ManageCoursewareModal extends React.Component {
}
else
{
return
item
;
}
})
})
;
}
else
{
newList
=
res
.
result
.
map
((
item
)
=>
{
item
.
id
=
item
.
docId
;
...
...
@@ -98,47 +95,42 @@ class ManageCoursewareModal extends React.Component {
});
}
this
.
setState
({
list
:
newList
});
})
})
;
}
// 上传文件
addFile
()
{
// 判断是否早于开课前30分钟
const
{
startTime
}
=
this
.
props
.
data
;
const
currentTime
=
new
Date
().
getTime
();
if
(
currentTime
>=
startTime
-
30
*
60
*
1000
)
{
Modal
.
info
({
title
:
"不能再上传课件了"
,
icon
:
(
<
span
className=
"icon iconfont default-confirm-icon"
style=
{
{
color
:
"#FFBB54 !important"
}
}
>

</
span
>
),
content
:
"请在开课前30分钟前上传课件,开课后可在客户端中进行上传。"
,
okText
:
'我知道了'
});
return
;
}
// 判断是否早于开课前30分钟
const
{
startTime
}
=
this
.
props
.
data
;
const
currentTime
=
new
Date
().
getTime
();
if
(
currentTime
>=
startTime
-
30
*
60
*
1000
)
{
Modal
.
info
({
title
:
'不能再上传课件了'
,
icon
:
(
<
span
className=
'icon iconfont default-confirm-icon'
style=
{
{
color
:
'#FFBB54 !important'
}
}
>

</
span
>
),
content
:
'请在开课前30分钟前上传课件,开课后可在客户端中进行上传。'
,
okText
:
'我知道了'
,
});
return
;
}
const
{
list
}
=
this
.
state
;
if
(
list
.
length
>=
20
)
{
message
.
warning
(
'最多上传20个课件'
);
return
null
;
}
this
.
setState
({
selectedFileList
:
list
,
showSelectFileModal
:
true
,
// 选择文件弹窗
})
const
{
list
}
=
this
.
state
;
if
(
list
.
length
>=
20
)
{
message
.
warning
(
'最多上传20个课件'
);
return
null
;
}
this
.
setState
({
selectedFileList
:
list
,
showSelectFileModal
:
true
,
// 选择文件弹窗
});
}
handleAddFile
=
(
addFolderIds
)
=>
{
this
.
setState
({
showSelectFileModal
:
false
showSelectFileModal
:
false
,
});
const
{
liveCourseId
}
=
this
.
props
.
data
;
...
...
@@ -151,14 +143,14 @@ class ManageCoursewareModal extends React.Component {
Service
.
Hades
(
'public/courseWare/uploadCourseWareFile'
,
params
).
then
((
res
)
=>
{
this
.
getCoursewareList
();
});
}
}
;
// 删除文件
deleteFile
(
item
)
{
const
{
list
}
=
this
.
state
;
Service
.
Hades
(
'public/courseWare/delCourseDoc'
,
{
docId
:
item
.
id
}).
then
(()
=>
{
item
.
docId
&&
message
.
success
(
'删除成功'
)
})
item
.
docId
&&
message
.
success
(
'删除成功'
)
;
})
;
const
_list
=
_
.
reject
(
list
,
(
data
)
=>
data
.
id
==
item
.
id
);
this
.
setState
({
list
:
_list
});
}
...
...
@@ -168,206 +160,192 @@ class ManageCoursewareModal extends React.Component {
if
(
!
item
.
srcDocUrl
)
return
null
;
const
suffix
=
_
.
last
(
item
.
fileName
.
split
(
'.'
)).
toLowerCase
();
const
type
=
suffixType
[
suffix
]
const
type
=
suffixType
[
suffix
]
;
const
fileType
=
FileVerifyMap
[
type
].
type
;
switch
(
fileType
)
{
case
"PDF"
:
window
.
open
(
item
.
srcDocUrl
,
"_blank"
);
case
'PDF'
:
window
.
open
(
item
.
srcDocUrl
,
'_blank'
);
break
;
case
"Excel"
:
case
"EXCEL"
:
case
"PPT"
:
case
"PPTX"
:
case
"word"
:
case
"WORD"
:
case
"DOCX"
:
case
"DOC"
:
case
'Excel'
:
case
'EXCEL'
:
case
'PPT'
:
case
'PPTX'
:
case
'word'
:
case
'WORD'
:
case
'DOCX'
:
case
'DOC'
:
let
size
=
parseFloat
(
item
.
fileSize
.
replace
(
/M$|KB$/g
,
''
));
if
(
item
.
fileSize
.
includes
(
'KB'
))
{
size
=
0
;
}
if
(((
fileType
==
'word'
||
fileType
==
'PPT'
)
&&
size
>
10
)
||
(
(
fileType
==
'Excel'
)
&&
size
>
5
))
{
if
(((
fileType
==
'word'
||
fileType
==
'PPT'
)
&&
size
>
10
)
||
(
fileType
==
'Excel'
&&
size
>
5
))
{
Modal
.
confirm
({
title
:
'抱歉,不能在线预览'
,
content
:
'由于文件较大,不支持在线预览,请下载后再查看'
,
icon
:
<
QuestionCircleOutlined
/>,
okText
:
"下载"
,
onOk
:()
=>
{
okText
:
'下载'
,
onOk
:
()
=>
{
const
a
=
document
.
createElement
(
'a'
);
a
.
href
=
item
.
srcDocUrl
;
a
.
click
();
}
}
,
});
}
else
{
const
scanUrl
=
"https://view.officeapps.live.com/op/view.aspx?src="
+
encodeURIComponent
(
item
.
srcDocUrl
);
window
.
open
(
scanUrl
,
"_blank"
);
const
scanUrl
=
'https://view.officeapps.live.com/op/view.aspx?src='
+
encodeURIComponent
(
item
.
srcDocUrl
);
window
.
open
(
scanUrl
,
'_blank'
);
}
break
;
case
"JPG"
:
case
"PNG"
:
case
"MP4"
:
case
"MP3"
:
this
.
setState
({
scanFileModal
:
true
,
editData
:
{
fileType
,
ossAddress
:
item
.
srcDocUrl
}
})
case
'JPG'
:
case
'PNG'
:
case
'MP4'
:
case
'MP3'
:
this
.
setState
({
scanFileModal
:
true
,
editData
:
{
fileType
,
ossAddress
:
item
.
srcDocUrl
}
})
;
break
;
default
:
break
;
}
};
}
render
()
{
const
columns
=
[
{
title
:
"名称"
,
width
:
"25%"
,
dataIndex
:
"name"
,
title
:
'名称'
,
width
:
'25%'
,
dataIndex
:
'name'
,
render
:
(
_value
,
item
)
=>
{
const
suffix
=
_
.
last
(
item
.
fileName
.
split
(
'.'
)).
toLowerCase
();
const
fileType
=
suffixType
[
suffix
]
const
antIcon
=
<
LoadingOutlined
/>;
const
fileType
=
suffixType
[
suffix
]
;
const
antIcon
=
<
LoadingOutlined
/>;
const
type
=
FileVerifyMap
[
fileType
].
type
;
return
<
div
className=
"courseware-name"
onClick=
{
()
=>
this
.
handleScanFile
(
item
)
}
>
return
(
<
div
className=
'courseware-name'
onClick=
{
()
=>
this
.
handleScanFile
(
item
)
}
>
<
Choose
>
<
When
condition=
{
(
type
===
'JPG'
||
type
===
'PNG'
)
&&
item
.
progress
}
>
<
Spin
indicator=
{
antIcon
}
/>
</
When
>
<
Otherwise
>
<
img
src=
{
FileTypeIcon
[
FileVerifyMap
[
fileType
].
type
]
||
(
item
.
docUrls
[
0
]
||
{}).
conversionFileUrl
}
alt=
""
className=
"item-img"
/>
<
img
src=
{
FileTypeIcon
[
FileVerifyMap
[
fileType
].
type
]
||
(
item
.
docUrls
[
0
]
||
{}).
conversionFileUrl
}
alt=
''
className=
'item-img'
/>
</
Otherwise
>
</
Choose
>
<
Tooltip
title=
{
item
.
fileName
}
><
span
className=
"name"
>
{
item
.
fileName
}
</
span
></
Tooltip
>
</
div
>
<
Tooltip
title=
{
item
.
fileName
}
>
<
span
className=
'name'
>
{
item
.
fileName
}
</
span
>
</
Tooltip
>
</
div
>
);
},
},
{
title
:
"创建人"
,
width
:
"12%"
,
dataIndex
:
"adminName"
,
title
:
'创建人'
,
width
:
'12%'
,
dataIndex
:
'adminName'
,
render
:
(
_value
,
item
)
=>
{
return
<
span
>
{
item
.
operatorName
}
</
span
>
return
<
span
>
{
item
.
operatorName
}
</
span
>
;
},
},
{
title
:
"上传时间"
,
width
:
"20%"
,
dataIndex
:
"created"
,
title
:
'上传时间'
,
width
:
'20%'
,
dataIndex
:
'created'
,
render
:
(
_value
,
item
)
=>
{
return
item
.
failState
?
'-'
:
<
span
>
{
moment
(
item
.
created
).
format
(
'YYYY-MM-DD HH:mm'
)
}
</
span
>
return
item
.
failState
?
'-'
:
<
span
>
{
moment
(
item
.
created
).
format
(
'YYYY-MM-DD HH:mm'
)
}
</
span
>
;
},
},
{
title
:
"大小"
,
width
:
"12%"
,
dataIndex
:
"size"
,
title
:
'大小'
,
width
:
'12%'
,
dataIndex
:
'size'
,
render
:
(
_value
,
item
)
=>
{
return
<
span
>
{
item
.
fileSize
}
</
span
>
return
<
span
>
{
item
.
fileSize
}
</
span
>
;
},
},
{
title
:
"操作"
,
width
:
"16%"
,
dataIndex
:
"control"
,
title
:
'操作'
,
width
:
'16%'
,
dataIndex
:
'control'
,
render
:
(
_value
,
item
)
=>
{
const
{
failObject
}
=
this
.
state
;
const
uploadFail
=
failObject
[
item
.
id
];
// 上课前45分钟/上课中/已结束的情况下都不可操作
if
(
this
.
props
.
data
.
startTime
<
Date
.
now
()
+
1800000
||
item
.
progress
||
uploadFail
)
{
return
<
span
>
-
</
span
>
return
<
span
>
-
</
span
>
;
}
return
(
<
Popconfirm
title=
"你确定要删除这个课件吗?"
onConfirm=
{
()
=>
this
.
deleteFile
(
item
)
}
onCancel=
{
()
=>
{
}
}
>
<
span
style=
{
{
color
:
'#2966FF'
,
cursor
:
'pointer'
}
}
>
删除
</
span
>
<
Popconfirm
title=
'你确定要删除这个课件吗?'
onConfirm=
{
()
=>
this
.
deleteFile
(
item
)
}
onCancel=
{
()
=>
{}
}
>
<
span
style=
{
{
color
:
'#2966FF'
,
cursor
:
'pointer'
,
}
}
>
删除
</
span
>
</
Popconfirm
>
)
)
;
},
},
]
const
{
list
,
scanFileModal
,
editData
,
cancelObject
,
showSelectFileModal
,
selectedFileList
,
diskList
}
=
this
.
state
;
];
const
{
list
,
scanFileModal
,
editData
,
cancelObject
,
showSelectFileModal
,
selectedFileList
,
diskList
}
=
this
.
state
;
const
_list
=
_
.
reject
(
list
,
(
item
)
=>
cancelObject
[
item
.
id
]);
return
(
<
Modal
visible=
{
true
}
title=
"课件管理"
title=
'课件管理'
footer=
{
null
}
maskClosable=
{
false
}
closeIcon=
{
<
span
className=
"icon iconfont modal-close-icon"
>

</
span
>
}
className=
"manage-courseware-modal"
closeIcon=
{
<
span
className=
'icon iconfont modal-close-icon'
>

</
span
>
}
className=
'manage-courseware-modal'
width=
{
_
.
isEmpty
(
_list
)
?
680
:
800
}
onCancel=
{
()
=>
{
this
.
props
.
onCancel
()
}
}
>
{
_
.
isEmpty
(
_list
)
?
<
div
className=
"empty-body"
>
<
div
id=
"lottie-box"
className=
"empty-image"
>
</
div
>
<
Button
className=
"empty-button"
type=
"primary"
onClick=
{
()
=>
this
.
addFile
()
}
>
上传课件
</
Button
>
<
p
className=
"empty-tip"
>
提前上传直播需要的课件和素材,直播将会变得更便捷!
</
p
>
this
.
props
.
onCancel
();
}
}
>
{
_
.
isEmpty
(
_list
)
?
(
<
div
className=
'empty-body'
>
<
div
id=
'lottie-box'
className=
'empty-image'
></
div
>
<
Button
className=
'empty-button'
type=
'primary'
onClick=
{
()
=>
this
.
addFile
()
}
>
上传课件
</
Button
>
<
p
className=
'empty-tip'
>
提前上传直播需要的课件和素材,直播将会变得更便捷!
</
p
>
</
div
>
:
<
div
className=
"manage-body"
>
<
div
id=
"lottie-box"
className=
"empty-image"
style=
{
{
display
:
'none'
}
}
></
div
>
<
div
className=
"header"
>
<
Button
className=
"header-button"
type=
"primary"
onClick=
{
()
=>
this
.
addFile
()
}
>
上传课件
</
Button
>
)
:
(
<
div
className=
'manage-body'
>
<
div
id=
'lottie-box'
className=
'empty-image'
style=
{
{
display
:
'none'
}
}
></
div
>
<
div
className=
'header'
>
<
Button
className=
'header-button'
type=
'primary'
onClick=
{
()
=>
this
.
addFile
()
}
>
上传课件
</
Button
>
</
div
>
<
Table
size=
"small"
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
size=
'small'
pagination=
{
false
}
rowKey=
{
record
=>
record
.
id
}
rowKey=
{
(
record
)
=>
record
.
id
}
dataSource=
{
_list
}
columns=
{
columns
}
bordered
/>
</
div
>
}
{
scanFileModal
&&
<
ScanFileModal
item=
{
editData
}
fileType=
{
editData
.
fileType
}
close=
{
()
=>
this
.
setState
({
scanFileModal
:
false
})
}
/>
}
)
}
{
scanFileModal
&&
<
ScanFileModal
item=
{
editData
}
fileType=
{
editData
.
fileType
}
close=
{
()
=>
this
.
setState
({
scanFileModal
:
false
})
}
/>
}
<
SelectPrepareFileModal
multiple=
{
true
}
scene=
"liveCourse"
operateType=
"select"
scene=
'liveCourse'
operateType=
'select'
isOpen=
{
showSelectFileModal
}
diskList=
{
diskList
}
selectedFileList=
{
selectedFileList
}
onClose=
{
()
=>
{
this
.
setState
({
showSelectFileModal
:
false
})
this
.
setState
({
showSelectFileModal
:
false
})
;
}
}
onSelect=
{
this
.
handleAddFile
}
/>
</
Modal
>
)
)
;
}
}
export
default
ManageCoursewareModal
;
\ No newline at end of file
export
default
ManageCoursewareModal
;
src/modules/course-manage/modal/PlayBackRecordModal.jsx
View file @
510254f6
...
...
@@ -6,21 +6,19 @@
* @LastEditTime: 2021-02-01 14:00:36
*/
import
React
,
{
useState
,
useEffect
}
from
"react"
;
import
{
Modal
,
Table
,
Button
,
message
}
from
"antd"
;
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
Bus
from
'@/core/bus'
;
import
{
PageControl
}
from
"@/components"
;
import
hasExportPermission
from
'../utils/hasExportPermission'
;
import
{
Button
,
message
,
Modal
}
from
'antd'
;
import
React
from
'react'
;
import
dealTimeDuration
from
'../utils/dealTimeDuration'
;
import
"./ClassRecordModal.less"
;
import
hasExportPermission
from
'../utils/hasExportPermission'
;
import
'./ClassRecordModal.less'
;
const
liveTypeMap
=
{
USER
:
"学生"
,
ANCHOR
:
"老师"
,
ADMIN
:
"助教"
,
USER
:
'学生'
,
ANCHOR
:
'老师'
,
ADMIN
:
'助教'
,
};
class
PlayBackRecordModal
extends
React
.
Component
{
...
...
@@ -38,7 +36,7 @@ class PlayBackRecordModal extends React.Component {
totalWatchNum
:
0
,
};
}
componentDidMount
()
{
this
.
fetchPlayBackList
();
}
...
...
@@ -46,22 +44,20 @@ class PlayBackRecordModal extends React.Component {
fetchPlayBackList
=
(
page
=
1
)
=>
{
const
params
=
_
.
clone
(
this
.
state
.
query
);
params
.
current
=
page
;
window
.
axios
.
Apollo
(
"public/businessLive/queryUserReplayRecordPage"
,
params
)
.
then
((
res
)
=>
{
const
{
records
=
[],
total
}
=
res
.
result
;
this
.
setState
({
query
:
params
,
total
,
playBackList
:
records
,
});
window
.
axios
.
Apollo
(
'public/businessLive/queryUserReplayRecordPage'
,
params
).
then
((
res
)
=>
{
const
{
records
=
[],
total
}
=
res
.
result
;
this
.
setState
({
query
:
params
,
total
,
playBackList
:
records
,
});
});
};
fetchAllStatistics
=
()
=>
{
const
{
liveCourseId
}
=
this
.
props
.
liveItem
;
window
.
axios
.
Apollo
(
"public/businessLive/queryReplayStatistics"
,
{
.
Apollo
(
'public/businessLive/queryReplayStatistics'
,
{
liveCourseId
,
})
.
then
((
res
)
=>
{
...
...
@@ -80,7 +76,7 @@ class PlayBackRecordModal extends React.Component {
const
hours
=
Math
.
floor
(
time
/
3600
);
const
mins
=
Math
.
floor
(
diff
/
60
);
const
seconds
=
Math
.
floor
(
time
%
60
);
return
hours
+
"小时"
+
mins
+
"分"
;
return
hours
+
'小时'
+
mins
+
'分'
;
};
// 导出
...
...
@@ -88,126 +84,128 @@ class PlayBackRecordModal extends React.Component {
const
{
liveItem
,
type
}
=
this
.
props
;
const
{
liveCourseId
}
=
liveItem
;
const
url
=
!
type
?
'api-b/b/lesson/exportLargeClassLiveAsync'
:
'api-b/b/lesson/exportClassInteractionLiveSync'
;
window
.
axios
.
post
(
url
,
{
liveCourseId
,
exportLiveType
:
0
}).
then
((
res
)
=>
{
Bus
.
trigger
(
'get_download_count'
);
Modal
.
success
({
title
:
'导出任务提交成功'
,
content
:
'请前往右上角的“导出中心”进行下载'
,
okText
:
'我知道了'
,
window
.
axios
.
post
(
url
,
{
liveCourseId
,
exportLiveType
:
0
,
})
.
then
((
res
)
=>
{
Bus
.
trigger
(
'get_download_count'
);
Modal
.
success
({
title
:
'导出任务提交成功'
,
content
:
'请前往右上角的“导出中心”进行下载'
,
okText
:
'我知道了'
,
});
});
});
}
};
handleExportV5
=
()
=>
{
const
{
liveItem
,
type
}
=
this
.
props
;
const
{
liveCourseId
}
=
liveItem
;
const
url
=
!
type
?
'public/businessLive/exportLargeClassLiveAsync'
:
'public/businessLive/exportClassInteractionLiveSync'
;
window
.
axios
.
Apollo
(
url
,
{
liveCourseId
,
exportLiveType
:
'PLAY_BACK'
}).
then
((
res
)
=>
{
Bus
.
trigger
(
'get_download_count'
);
Modal
.
success
({
title
:
'导出任务提交成功'
,
content
:
'请前往右上角的“任务中心”进行下载'
,
okText
:
'我知道了'
,
window
.
axios
.
Apollo
(
url
,
{
liveCourseId
,
exportLiveType
:
'PLAY_BACK'
,
})
.
then
((
res
)
=>
{
Bus
.
trigger
(
'get_download_count'
);
Modal
.
success
({
title
:
'导出任务提交成功'
,
content
:
'请前往右上角的“任务中心”进行下载'
,
okText
:
'我知道了'
,
});
});
});
}
};
render
()
{
const
columns
=
[
{
title
:
"观看者姓名"
,
dataIndex
:
"userName"
,
title
:
'观看者姓名'
,
dataIndex
:
'userName'
,
},
{
title
:
"观看者手机号"
,
dataIndex
:
"phone"
,
title
:
'观看者手机号'
,
dataIndex
:
'phone'
,
render
:
(
text
,
record
)
=>
{
return
(
<
p
>
{
!
(
(
!
window
.
NewVersion
&&
!
window
.
currentUserInstInfo
.
teacherId
)
||
(
window
.
NewVersion
&&
Permission
.
hasEduStudentPhone
())
)
?
(
text
||
""
).
replace
(
/
(\d
{3}
)(\d
{4}
)(\d
{4}
)
/
,
"$1****$3"
)
{
!
((
!
window
.
NewVersion
&&
!
window
.
currentUserInstInfo
.
teacherId
)
||
(
window
.
NewVersion
&&
Permission
.
hasEduStudentPhone
()))
?
(
text
||
''
).
replace
(
/
(\d
{3}
)(\d
{4}
)(\d
{4}
)
/
,
'$1****$3'
)
:
text
}
</
p
>
);
},
},
{
title
:
"观看者类型"
,
dataIndex
:
"liveRole"
,
key
:
"liveRole"
,
title
:
'观看者类型'
,
dataIndex
:
'liveRole'
,
key
:
'liveRole'
,
render
:
(
text
)
=>
<
span
>
{
liveTypeMap
[
text
]
}
</
span
>,
},
{
title
:
"开始观看时间"
,
dataIndex
:
"entryTime"
,
key
:
"entryTime"
,
render
:
(
text
)
=>
(
<
span
>
{
text
?
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
text
))
:
'-'
}
</
span
>
),
title
:
'开始观看时间'
,
dataIndex
:
'entryTime'
,
key
:
'entryTime'
,
render
:
(
text
)
=>
<
span
>
{
text
?
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
text
))
:
'-'
}
</
span
>,
},
{
title
:
"观看时长"
,
dataIndex
:
"lookingDuration"
,
key
:
"lookingDuration"
,
title
:
'观看时长'
,
dataIndex
:
'lookingDuration'
,
key
:
'lookingDuration'
,
render
:
(
text
)
=>
{
return
<
span
>
{
text
?
dealTimeDuration
(
text
)
:
'-'
}
</
span
>;
},
},
];
const
{
query
,
total
,
playBackList
,
totalWatchNum
,
recordDuration
,
}
=
this
.
state
;
const
{
query
,
total
,
playBackList
,
totalWatchNum
,
recordDuration
}
=
this
.
state
;
const
{
type
}
=
this
.
props
;
return
(
<
Modal
title=
"回放记录"
className=
"play-back-modal"
title=
'回放记录'
className=
'play-back-modal'
width=
{
680
}
visible=
{
true
}
maskClosable=
{
false
}
closeIcon=
{
<
span
className=
"icon iconfont modal-close-icon"
>

</
span
>
}
closeIcon=
{
<
span
className=
'icon iconfont modal-close-icon'
>

</
span
>
}
footer=
{
null
}
onCancel=
{
()
=>
{
this
.
props
.
close
();
}
}
>
{
hasExportPermission
(
type
)
&&
<
Button
onClick=
{
_
.
debounce
(()
=>
{
if
(
!
playBackList
.
length
)
{
message
.
warning
(
'暂无数据可导出'
);
return
;
}
if
(
window
.
NewVersion
)
{
this
.
handleExportV5
();
}
else
{
this
.
handleExport
();
}
},
500
,
true
)
}
>
导出
</
Button
>
}
<
Table
size=
"small"
}
}
>
{
hasExportPermission
(
type
)
&&
(
<
Button
onClick=
{
_
.
debounce
(
()
=>
{
if
(
!
playBackList
.
length
)
{
message
.
warning
(
'暂无数据可导出'
);
return
;
}
if
(
window
.
NewVersion
)
{
this
.
handleExportV5
();
}
else
{
this
.
handleExport
();
}
},
500
,
true
)
}
>
导出
</
Button
>
)
}
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
size=
'small'
columns=
{
columns
}
dataSource=
{
playBackList
}
pagination=
{
false
}
className=
"table-no-scrollbar"
className=
'table-no-scrollbar'
/>
<
PageControl
size=
"small"
size=
'small'
current=
{
query
.
current
-
1
}
pageSize=
{
query
.
size
}
total=
{
total
}
...
...
src/modules/course-manage/modal/RelatedPlanModal.jsx
View file @
510254f6
import
React
from
'react'
import
{
Table
,
Modal
,
Input
}
from
'antd'
import
{
PageControl
}
from
'@/components'
import
CourseService
from
'@/domains/course-domain/CourseService'
import
PlanService
from
'@/domains/plan-domain/planService'
import
User
from
'@/common/js/user'
import
'./RelatedPlanModal.less'
import
_
from
'underscore'
const
{
Search
}
=
Input
import
User
from
'@/common/js/user'
;
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
PlanService
from
'@/domains/plan-domain/planService'
;
import
{
Input
,
Modal
}
from
'antd'
;
import
React
from
'react'
;
import
_
from
'underscore'
;
import
'./RelatedPlanModal.less'
;
const
{
Search
}
=
Input
;
class
RelatedPlanModal
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
)
super
(
props
)
;
this
.
state
=
{
dataSource
:
[],
size
:
10
,
query
:
{
current
:
1
current
:
1
,
},
totalCount
:
0
,
selectPlanList
:
{}
}
selectPlanList
:
{}
,
}
;
}
componentDidMount
()
{
this
.
handleFetchDataList
()
this
.
handleFetchDataList
()
;
}
// 获取培训计划列表
handleFetchDataList
=
()
=>
{
const
{
query
,
size
}
=
this
.
state
const
{
query
,
size
}
=
this
.
state
;
const
params
=
{
...
query
,
size
,
storeId
:
User
.
getStoreId
()
}
storeId
:
User
.
getStoreId
()
,
}
;
PlanService
.
getStorePlanAll
(
params
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
const
{
records
=
[],
total
=
0
}
=
result
const
{
result
=
{}
}
=
res
;
const
{
records
=
[],
total
=
0
}
=
result
;
this
.
setState
({
dataSource
:
records
,
totalCount
:
Number
(
total
)
})
})
}
totalCount
:
Number
(
total
)
,
})
;
})
;
}
;
handleChangePlanName
=
(
value
)
=>
{
const
{
query
}
=
this
.
state
query
.
planName
=
value
query
.
current
=
1
const
{
query
}
=
this
.
state
;
query
.
planName
=
value
;
query
.
current
=
1
;
this
.
setState
({
query
})
}
query
,
})
;
}
;
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
return
return
;
}
this
.
setState
(
{
size
size
,
},
()
=>
{
this
.
handleFetchDataList
()
this
.
handleFetchDataList
()
;
}
)
}
)
;
}
;
// 请求表头
parsePlanColumns
=
()
=>
{
...
...
@@ -72,12 +73,12 @@ class RelatedPlanModal extends React.Component {
key
:
'planName'
,
dataIndex
:
'planName'
,
render
:
(
val
,
record
)
=>
{
return
<
span
>
{
val
}
</
span
>
}
}
]
return
columns
}
return
<
span
>
{
val
}
</
span
>
;
}
,
}
,
]
;
return
columns
;
}
;
parseTaskColumns
=
(
parentIndex
)
=>
{
const
columns
=
[
...
...
@@ -86,76 +87,76 @@ class RelatedPlanModal extends React.Component {
key
:
'taskName'
,
dataIndex
:
'taskName'
,
render
:
(
val
,
record
)
=>
{
return
<
span
>
{
val
}
</
span
>
}
}
]
return
columns
}
return
<
span
>
{
val
}
</
span
>
;
}
,
}
,
]
;
return
columns
;
}
;
selectPlanList
=
(
record
,
selected
,
planId
)
=>
{
const
{
selectPlanList
}
=
this
.
props
let
_selectPlanList
=
{
...
selectPlanList
}
const
{
selectPlanList
}
=
this
.
props
;
let
_selectPlanList
=
{
...
selectPlanList
}
;
if
(
selected
)
{
if
(
!
_selectPlanList
[
planId
])
{
_selectPlanList
[
planId
]
=
{}
_selectPlanList
[
planId
]
=
{}
;
}
_selectPlanList
[
planId
].
taskBaseVOList
=
[]
_selectPlanList
[
planId
].
planId
=
planId
_selectPlanList
[
planId
].
taskBaseVOList
.
push
(
record
)
_selectPlanList
[
planId
].
taskBaseVOList
=
[]
;
_selectPlanList
[
planId
].
planId
=
planId
;
_selectPlanList
[
planId
].
taskBaseVOList
.
push
(
record
)
;
}
else
{
if
(
!
_selectPlanList
[
planId
])
{
_selectPlanList
[
planId
]
=
{}
_selectPlanList
[
planId
]
=
{}
;
}
_selectPlanList
[
planId
].
taskBaseVOList
=
[]
_selectPlanList
[
planId
].
planId
=
planId
_selectPlanList
[
planId
].
taskBaseVOList
=
[]
;
_selectPlanList
[
planId
].
planId
=
planId
;
}
this
.
props
.
onChange
(
_selectPlanList
)
this
.
props
.
onChange
(
_selectPlanList
)
;
// this.setState({selectPlanList:_selectPlanList});
}
}
;
handleSelectPlanListData
(
selectPlanList
)
{
let
_selectPlanList
=
[]
let
_selectPlanList
=
[]
;
for
(
let
key
in
selectPlanList
)
{
let
item
=
{}
let
item
=
{}
;
if
(
selectPlanList
[
key
].
taskBaseVOList
)
{
item
.
planId
=
selectPlanList
[
key
].
planId
item
.
planId
=
selectPlanList
[
key
].
planId
;
if
(
selectPlanList
[
key
].
taskBaseVOList
[
0
])
{
item
.
taskId
=
selectPlanList
[
key
].
taskBaseVOList
[
0
].
taskId
item
.
taskId
=
selectPlanList
[
key
].
taskBaseVOList
[
0
].
taskId
;
}
}
if
(
item
.
taskId
)
{
_selectPlanList
.
push
(
item
)
_selectPlanList
.
push
(
item
)
;
}
}
return
_selectPlanList
return
_selectPlanList
;
}
confirmRelatedPlan
=
()
=>
{
const
{
selectPlanList
}
=
this
.
props
const
{
selectPlanList
}
=
this
.
props
;
const
params
=
{
courseId
:
this
.
props
.
selectCourseId
,
relatedPlanList
:
this
.
handleSelectPlanListData
(
selectPlanList
),
storeId
:
User
.
getStoreId
()
}
storeId
:
User
.
getStoreId
()
,
}
;
CourseService
.
relatedCourseToPlan
(
params
).
then
((
res
)
=>
{
this
.
props
.
onConfirm
()
})
}
this
.
props
.
onConfirm
()
;
})
;
}
;
getSelectLength
=
(
selectList
)
=>
{
let
num
=
0
let
num
=
0
;
for
(
let
key
in
selectList
)
{
if
(
selectList
[
key
].
taskBaseVOList
.
length
>
0
)
{
num
=
num
+
1
num
=
num
+
1
;
}
}
return
num
}
return
num
;
}
;
clearSelect
=
()
=>
{
const
_selectPlanList
=
{}
this
.
props
.
onChange
(
_selectPlanList
)
}
const
_selectPlanList
=
{}
;
this
.
props
.
onChange
(
_selectPlanList
)
;
}
;
render
()
{
const
{
size
,
dataSource
,
totalCount
,
query
}
=
this
.
state
const
{
visible
,
selectPlanList
}
=
this
.
props
const
{
size
,
dataSource
,
totalCount
,
query
}
=
this
.
state
;
const
{
visible
,
selectPlanList
}
=
this
.
props
;
return
(
<
Modal
title=
'关联培训计划'
...
...
@@ -172,10 +173,10 @@ class RelatedPlanModal extends React.Component {
placeholder=
'搜索培训计划名称'
style=
{
{
width
:
207
}
}
onChange=
{
(
e
)
=>
{
this
.
handleChangePlanName
(
e
.
target
.
value
)
this
.
handleChangePlanName
(
e
.
target
.
value
)
;
}
}
onSearch=
{
()
=>
{
this
.
handleFetchDataList
()
this
.
handleFetchDataList
()
;
}
}
enterButton=
{
<
span
className=
'icon iconfont'
>

</
span
>
}
/>
...
...
@@ -194,7 +195,11 @@ class RelatedPlanModal extends React.Component {
</
span
>
</
div
>
<
div
>
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
planId
}
className=
'plan-table'
dataSource=
{
dataSource
}
...
...
@@ -202,20 +207,24 @@ class RelatedPlanModal extends React.Component {
pagination=
{
false
}
expandedRowRender=
{
(
_record
,
index
)
=>
{
if
(
!
_record
.
taskBaseVOList
)
{
return
return
;
}
if
(
_record
.
taskBaseVOList
.
length
!==
0
)
{
const
selectPlan
=
selectPlanList
[
_record
.
planId
]
let
taskBaseVOList
=
[]
const
selectPlan
=
selectPlanList
[
_record
.
planId
]
;
let
taskBaseVOList
=
[]
;
if
(
selectPlan
)
{
taskBaseVOList
=
selectPlan
.
taskBaseVOList
taskBaseVOList
=
selectPlan
.
taskBaseVOList
;
}
console
.
log
(
'taskBaseVOList'
,
taskBaseVOList
)
console
.
log
(
'taskBaseVOList'
,
taskBaseVOList
)
;
return
(
<
div
>
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
taskId
}
pagination=
{
false
}
dataSource=
{
_record
.
taskBaseVOList
}
...
...
@@ -225,20 +234,20 @@ class RelatedPlanModal extends React.Component {
type
:
'checkbox'
,
selectedRowKeys
:
_
.
pluck
(
taskBaseVOList
,
'taskId'
),
onSelect
:
(
record
,
selected
)
=>
{
this
.
selectPlanList
(
record
,
selected
,
_record
.
planId
)
this
.
selectPlanList
(
record
,
selected
,
_record
.
planId
)
;
},
onSelectAll
:
(
selected
,
_selectedRows
,
changeRows
)
=>
{}
onSelectAll
:
(
selected
,
_selectedRows
,
changeRows
)
=>
{}
,
}
}
/>
</
div
>
)
)
;
}
}
}
rowClassName=
{
(
record
,
index
)
=>
{
if
(
index
%
2
===
0
)
{
return
'odd-row'
return
'odd-row'
;
}
else
{
return
'even-row'
return
'even-row'
;
}
}
}
/>
...
...
@@ -250,15 +259,15 @@ class RelatedPlanModal extends React.Component {
total=
{
totalCount
}
size=
'small'
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
query
,
current
:
page
+
1
}
const
_query
=
{
...
query
,
current
:
page
+
1
}
;
this
.
setState
(
{
query
:
_query
query
:
_query
,
},
()
=>
{
this
.
handleFetchDataList
()
this
.
handleFetchDataList
()
;
}
)
)
;
}
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
/>
...
...
@@ -266,8 +275,8 @@ class RelatedPlanModal extends React.Component {
)
}
</
div
>
</
Modal
>
)
)
;
}
}
export
default
RelatedPlanModal
export
default
RelatedPlanModal
;
src/modules/course-manage/modal/select-student/StudentList.jsx
View file @
510254f6
...
...
@@ -7,41 +7,43 @@
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
{
Dropdown
,
Menu
,
Tooltip
}
from
'antd'
;
import
React
from
'react'
;
import
{
Table
,
Tooltip
,
Menu
,
Dropdown
}
from
'antd'
;
import
_
from
'underscore'
;
import
Bus
from
'@/core/bus'
;
import
{
PageControl
}
from
'@/components'
;
let
resourceData
=
{};
_
.
map
(
window
.
RESOURCE
,
item
=>
{
resourceData
[
item
.
code
]
=
item
.
name
_
.
map
(
window
.
RESOURCE
,
(
item
)
=>
{
resourceData
[
item
.
code
]
=
item
.
name
;
});
const
isNewVersion
=
window
.
NewVersion
;
class
StudentList
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
showDegiest
:
false
,
selectedRows
:
[],
prevSelectRows
:
props
.
savedSelectedRows
||
[],
savedSelectedRows
:
props
.
savedSelectedRows
||
[]
}
savedSelectedRows
:
props
.
savedSelectedRows
||
[]
,
}
;
}
parseColumns
=
()
=>
{
const
{
query
:
{
status
},
type
,
studentType
}
=
this
.
props
;
const
{
query
:
{
status
},
type
,
studentType
,
}
=
this
.
props
;
// 是否是在读学员
const
isNormal
=
(
status
===
'NORMAL'
||
status
===
1
)
;
const
isNormal
=
status
===
'NORMAL'
||
status
===
1
;
// 是否是潜在学员
const
isPotential
=
(
status
===
'POTENTIAL'
||
status
===
2
)
;
const
isPotential
=
status
===
'POTENTIAL'
||
status
===
2
;
// 是否是历史学员
const
isHistory
=
(
status
===
'HISTORY'
||
status
===
4
)
;
const
isHistory
=
status
===
'HISTORY'
||
status
===
4
;
const
columns
=
[
{
title
:
'姓名'
,
...
...
@@ -50,7 +52,7 @@ class StudentList extends React.Component {
render
:
(
text
,
record
)
=>
{
const
{
studentBasicVO
=
{},
name
}
=
record
;
return
studentBasicVO
.
name
||
name
;
}
}
,
},
{
title
:
'手机号'
,
...
...
@@ -58,150 +60,150 @@ class StudentList extends React.Component {
render
:
(
text
,
record
)
=>
{
const
{
type
}
=
this
.
props
;
const
{
studentBasicVO
=
{},
phone
,
weChatStatus
,
wechatStatus
}
=
record
;
const
{
NewVersion
,
currentUserInstInfo
:
{
teacherId
}
}
=
window
;
const
{
NewVersion
,
currentUserInstInfo
:
{
teacherId
},
}
=
window
;
return
(
<
div
className=
"record__item"
>
{
!
((
!
NewVersion
&&
!
teacherId
)
||
(
NewVersion
&&
Permission
.
hasEduStudentPhone
()))
?
(
studentBasicVO
.
phone
||
phone
).
replace
(
/
(\d
{3}
)(\d
{4}
)(\d
{4}
)
/
,
'$1****$3'
)
:
studentBasicVO
.
phone
||
phone
}
{
type
!==
'videoCourse'
&&
// 此处为了兼容4.0 和 5.0的扣课 不扣课学员的绑定微信
<
Tooltip
title=
{
`${(studentBasicVO.weChatStatus || weChatStatus || wechatStatus) ? '已绑定微信' : '未绑定微信'}`
}
>
<
div
className=
'record__item'
>
{
!
((
!
NewVersion
&&
!
teacherId
)
||
(
NewVersion
&&
Permission
.
hasEduStudentPhone
()))
?
(
studentBasicVO
.
phone
||
phone
).
replace
(
/
(\d
{3}
)(\d
{4}
)(\d
{4}
)
/
,
'$1****$3'
)
:
studentBasicVO
.
phone
||
phone
}
{
type
!==
'videoCourse'
&&
(
// 此处为了兼容4.0 和 5.0的扣课 不扣课学员的绑定微信
<
Tooltip
title=
{
`${studentBasicVO.weChatStatus || weChatStatus || wechatStatus ? '已绑定微信' : '未绑定微信'}`
}
>
<
span
className=
"iconfont icon"
style=
{
(
studentBasicVO
.
weChatStatus
||
weChatStatus
||
wechatStatus
)
?
{
color
:
'#00D20D'
,
fontSize
:
'16px'
,
marginLeft
:
6
}
:
{
fontSize
:
'16px'
,
color
:
'#BFBFBF'
,
marginLeft
:
6
}
}
>

</
span
>
className=
'iconfont icon'
style=
{
studentBasicVO
.
weChatStatus
||
weChatStatus
||
wechatStatus
?
{
color
:
'#00D20D'
,
fontSize
:
'16px'
,
marginLeft
:
6
,
}
:
{
fontSize
:
'16px'
,
color
:
'#BFBFBF'
,
marginLeft
:
6
,
}
}
>

</
span
>
</
Tooltip
>
}
)
}
</
div
>
)
}
}
)
;
}
,
}
,
];
// 扣课时学员显示消耗课程和剩余课时
if
(
studentType
===
'DEDUCTION'
)
{
const
{
consumeStudentList
}
=
this
.
props
;
columns
.
push
({
title
:
(
<
div
className=
"consumption-course"
>
<
span
className=
"text"
>
消耗课程
</
span
>
<
Tooltip
title=
"学员在这上课所消耗的课程"
>
<
span
className=
"icon iconfont"
>

</
span
>
</
Tooltip
>
</
div
>
),
key
:
'courseName'
,
dataIndex
:
'courseName'
,
render
:
(
val
,
record
)
=>
{
const
{
consumeStudentList
}
=
this
.
props
;
const
{
digestHourVOS
,
studentId
}
=
record
;
if
(
!
digestHourVOS
||
!
digestHourVOS
.
length
)
{
return
<
span
className=
"digest-hour--empty"
>
无可消耗课程
</
span
>
}
else
if
(
digestHourVOS
.
length
===
1
)
{
return
<
span
className=
"course-name"
>
{
digestHourVOS
[
0
].
courseName
}
</
span
>
}
else
{
const
{
showDegiest
,
currentCourse
}
=
this
.
state
;
// 默认显示第一个课程包的名称
let
_currentCourse
=
digestHourVOS
[
0
];
// 判断学员是否被勾选了
const
hasSelect
=
_
.
find
(
consumeStudentList
,
item
=>
{
return
item
.
studentId
===
studentId
;
});
// 如果被勾选了,再判断选中的课时包是哪个
if
(
hasSelect
)
{
const
hasSelectCourse
=
_
.
find
(
digestHourVOS
,
item
=>
{
return
item
.
courseId
===
hasSelect
.
classHourId
columns
.
push
(
{
title
:
(
<
div
className=
'consumption-course'
>
<
span
className=
'text'
>
消耗课程
</
span
>
<
Tooltip
title=
'学员在这上课所消耗的课程'
>
<
span
className=
'icon iconfont'
>

</
span
>
</
Tooltip
>
</
div
>
),
key
:
'courseName'
,
dataIndex
:
'courseName'
,
render
:
(
val
,
record
)
=>
{
const
{
consumeStudentList
}
=
this
.
props
;
const
{
digestHourVOS
,
studentId
}
=
record
;
if
(
!
digestHourVOS
||
!
digestHourVOS
.
length
)
{
return
<
span
className=
'digest-hour--empty'
>
无可消耗课程
</
span
>;
}
else
if
(
digestHourVOS
.
length
===
1
)
{
return
<
span
className=
'course-name'
>
{
digestHourVOS
[
0
].
courseName
}
</
span
>;
}
else
{
const
{
showDegiest
,
currentCourse
}
=
this
.
state
;
// 默认显示第一个课程包的名称
let
_currentCourse
=
digestHourVOS
[
0
];
// 判断学员是否被勾选了
const
hasSelect
=
_
.
find
(
consumeStudentList
,
(
item
)
=>
{
return
item
.
studentId
===
studentId
;
});
if
(
hasSelectCourse
)
{
_currentCourse
=
hasSelectCourse
// 如果被勾选了,再判断选中的课时包是哪个
if
(
hasSelect
)
{
const
hasSelectCourse
=
_
.
find
(
digestHourVOS
,
(
item
)
=>
{
return
item
.
courseId
===
hasSelect
.
classHourId
;
});
if
(
hasSelectCourse
)
{
_currentCourse
=
hasSelectCourse
;
}
}
// 选择课时包之后, 根据学员ID判断选择的是哪个学员的课时包
if
(
currentCourse
&&
currentCourse
.
studentId
===
studentId
)
{
_currentCourse
=
currentCourse
;
}
if
(
this
.
isDisabledRow
(
record
))
{
return
<
span
className=
'course-name'
>
{
_currentCourse
.
courseName
}
</
span
>;
}
else
{
return
(
<
Dropdown
overlay=
{
this
.
renderCourseMenu
(
digestHourVOS
)
}
placement=
'bottomCenter'
arrow
>
<
div
className=
'digest-hour'
onMouseEnter=
{
()
=>
{
this
.
setState
({
showDegiest
:
true
});
}
}
>
<
span
className=
'course-name'
>
{
_currentCourse
.
courseName
}
</
span
>
{
digestHourVOS
.
length
>
1
&&
!
this
.
isDisabledRow
(
record
)
&&
(
<
span
className=
{
`icon iconfont ${showDegiest ? 'show' : 'hidden'}`
}
>

</
span
>
)
}
</
div
>
</
Dropdown
>
);
}
}
// 选择课时包之后, 根据学员ID判断选择的是哪个学员的课时包
if
(
currentCourse
&&
currentCourse
.
studentId
===
studentId
)
{
_currentCourse
=
currentCourse
;
}
},
},
{
title
:
'剩余课时'
,
key
:
'leftLessons'
,
dataIndex
:
'leftLessons'
,
render
:
(
val
,
record
)
=>
{
const
{
consumeStudentList
}
=
this
.
props
;
const
{
digestHourVOS
,
studentId
}
=
record
;
if
(
this
.
isDisabledRow
(
record
))
{
return
<
span
className=
"course-name"
>
{
_currentCourse
.
courseName
}
</
span
>
if
(
!
digestHourVOS
||
!
digestHourVOS
.
length
)
{
return
'-'
;
}
else
if
(
digestHourVOS
.
length
===
1
)
{
return
digestHourVOS
[
0
].
leftLessons
;
}
else
{
return
(
<
Dropdown
overlay=
{
this
.
renderCourseMenu
(
digestHourVOS
)
}
placement=
"bottomCenter"
arrow
>
<
div
className=
"digest-hour"
onMouseEnter=
{
()
=>
{
this
.
setState
({
showDegiest
:
true
});
}
}
>
<
span
className=
"course-name"
>
{
_currentCourse
.
courseName
}
</
span
>
{
digestHourVOS
.
length
>
1
&&
!
this
.
isDisabledRow
(
record
)
&&
<
span
className=
{
`icon iconfont ${showDegiest ? 'show' : 'hidden'}`
}
>

</
span
>
}
</
div
>
</
Dropdown
>
)
}
}
}
},
{
title
:
'剩余课时'
,
key
:
'leftLessons'
,
dataIndex
:
'leftLessons'
,
render
:
(
val
,
record
)
=>
{
const
{
consumeStudentList
}
=
this
.
props
;
const
{
digestHourVOS
,
studentId
}
=
record
;
if
(
!
digestHourVOS
||
!
digestHourVOS
.
length
)
{
return
'-'
}
else
if
(
digestHourVOS
.
length
===
1
)
{
return
digestHourVOS
[
0
].
leftLessons
;
}
else
{
const
{
currentCourse
}
=
this
.
state
;
let
_currentCourse
=
digestHourVOS
[
0
];
// 判断学员是否被选中了
const
hasSelect
=
_
.
find
(
consumeStudentList
,
item
=>
{
return
item
.
studentId
===
studentId
;
});
// 如果学员被勾选了,再判断该学员选择的课程包是哪个
if
(
hasSelect
)
{
const
hasSelectCourse
=
_
.
find
(
digestHourVOS
,
item
=>
{
return
item
.
courseId
===
hasSelect
.
classHourId
const
{
currentCourse
}
=
this
.
state
;
let
_currentCourse
=
digestHourVOS
[
0
];
// 判断学员是否被选中了
const
hasSelect
=
_
.
find
(
consumeStudentList
,
(
item
)
=>
{
return
item
.
studentId
===
studentId
;
});
if
(
hasSelectCourse
)
{
_currentCourse
=
hasSelectCourse
// 如果学员被勾选了,再判断该学员选择的课程包是哪个
if
(
hasSelect
)
{
const
hasSelectCourse
=
_
.
find
(
digestHourVOS
,
(
item
)
=>
{
return
item
.
courseId
===
hasSelect
.
classHourId
;
});
if
(
hasSelectCourse
)
{
_currentCourse
=
hasSelectCourse
;
}
}
// 选择课时包之后, 根据学员ID判断选择的是哪个学员的课时包
if
(
currentCourse
&&
currentCourse
.
studentId
===
studentId
)
{
_currentCourse
=
currentCourse
;
}
return
_currentCourse
.
leftLessons
;
}
// 选择课时包之后, 根据学员ID判断选择的是哪个学员的课时包
if
(
currentCourse
&&
currentCourse
.
studentId
===
studentId
)
{
_currentCourse
=
currentCourse
;
}
return
_currentCourse
.
leftLessons
;
}
},
}
})
);
}
// 在读学员显示年级
if
(
type
===
'videoCourse'
&&
isNormal
)
{
...
...
@@ -210,110 +212,120 @@ class StudentList extends React.Component {
dataIndex
:
'gradeName'
,
render
:
(
text
,
record
)
=>
{
const
{
studentBasicVO
=
{},
gradeName
}
=
record
;
return
studentBasicVO
.
gradeName
||
gradeName
;
}
})
return
studentBasicVO
.
gradeName
||
gradeName
;
}
,
})
;
}
// 潜在学员显示跟进人和学员来源
if
(
isPotential
)
{
columns
.
push
({
title
:
'跟进人'
,
dataIndex
:
'saleName'
,
render
:
(
val
,
record
)
=>
{
const
{
studentSaleVO
=
{},
saleName
}
=
record
;
return
studentSaleVO
.
saleName
||
saleName
;
}
},
{
title
:
'学员来源'
,
dataIndex
:
'resourceType'
,
render
:
(
val
,
record
)
=>
{
const
{
studentSaleVO
=
{},
resourceType
}
=
record
;
return
resourceData
[
studentSaleVO
.
resourceType
||
resourceType
];
columns
.
push
(
{
title
:
'跟进人'
,
dataIndex
:
'saleName'
,
render
:
(
val
,
record
)
=>
{
const
{
studentSaleVO
=
{},
saleName
}
=
record
;
return
studentSaleVO
.
saleName
||
saleName
;
},
},
{
title
:
'学员来源'
,
dataIndex
:
'resourceType'
,
render
:
(
val
,
record
)
=>
{
const
{
studentSaleVO
=
{},
resourceType
}
=
record
;
return
resourceData
[
studentSaleVO
.
resourceType
||
resourceType
];
},
}
}
);
);
}
// 历史学员显示结业时间和报读课程
if
(
isHistory
)
{
columns
.
push
({
title
:
'结业时间'
,
key
:
'graduationTime'
,
dataIndex
:
'graduationTime'
,
width
:
200
,
render
:
(
val
,
record
)
=>
{
const
{
studentHistoryVO
=
{},
graduationTime
}
=
record
;
return
formatDate
(
'YYYY-MM-DD'
,
(
studentHistoryVO
.
graduationTime
||
graduationTime
))
}
},
{
title
:
'报读课程'
,
key
:
'lostCourseName'
,
dataIndex
:
'lostCourseName'
,
width
:
150
,
render
:
(
val
,
record
)
=>
{
const
{
studentHistoryVO
=
{},
lostCourseName
}
=
record
;
return
studentHistoryVO
.
lostCourseName
||
lostCourseName
columns
.
push
(
{
title
:
'结业时间'
,
key
:
'graduationTime'
,
dataIndex
:
'graduationTime'
,
width
:
200
,
render
:
(
val
,
record
)
=>
{
const
{
studentHistoryVO
=
{},
graduationTime
}
=
record
;
return
formatDate
(
'YYYY-MM-DD'
,
studentHistoryVO
.
graduationTime
||
graduationTime
);
},
},
{
title
:
'报读课程'
,
key
:
'lostCourseName'
,
dataIndex
:
'lostCourseName'
,
width
:
150
,
render
:
(
val
,
record
)
=>
{
const
{
studentHistoryVO
=
{},
lostCourseName
}
=
record
;
return
studentHistoryVO
.
lostCourseName
||
lostCourseName
;
},
}
}
);
);
}
return
columns
;
}
}
;
// 课程下拉选项
renderCourseMenu
=
(
courseList
)
=>
{
return
(
<
Menu
>
{
_
.
map
(
courseList
,
(
item
)
=>
{
return
(
<
Menu
.
Item
onClick=
{
(
e
)
=>
{
this
.
handleSelectCourse
(
e
,
item
)}
}
>
{
item
.
courseName
}
</
Menu
.
Item
>
)
})
}
{
_
.
map
(
courseList
,
(
item
)
=>
{
return
(
<
Menu
.
Item
onClick=
{
(
e
)
=>
{
this
.
handleSelectCourse
(
e
,
item
);
}
}
>
{
item
.
courseName
}
</
Menu
.
Item
>
);
})
}
</
Menu
>
)
}
)
;
}
;
// 选择当前课程
handleSelectCourse
=
(
e
,
currentCourse
)
=>
{
e
.
domEvent
.
stopPropagation
();
this
.
setState
({
currentCourse
,
showDegiest
:
false
,
},
()
=>
{
const
{
consumeStudentList
=
[],
studentIds
,
excludeIds
}
=
this
.
props
;
const
{
prevSelectRows
}
=
this
.
state
;
const
{
studentId
,
courseId
,
leftLessons
,
name
,
phone
}
=
currentCourse
;
let
_consumeStudentList
=
consumeStudentList
;
// 选完课时包之后,自动勾选当前学员
const
_studentIds
=
[...
studentIds
,
studentId
];
const
hasExist
=
_
.
find
(
consumeStudentList
,
item
=>
{
return
item
.
studentId
===
studentId
});
this
.
setState
(
{
currentCourse
,
showDegiest
:
false
,
},
()
=>
{
const
{
consumeStudentList
=
[],
studentIds
,
excludeIds
}
=
this
.
props
;
const
{
prevSelectRows
}
=
this
.
state
;
const
{
studentId
,
courseId
,
leftLessons
,
name
,
phone
}
=
currentCourse
;
let
_consumeStudentList
=
consumeStudentList
;
// 选完课时包之后,自动勾选当前学员
const
_studentIds
=
[...
studentIds
,
studentId
];
if
(
hasExist
)
{
_consumeStudentList
=
_
.
map
(
consumeStudentList
,
item
=>
{
if
(
item
.
studentId
===
studentId
)
{
item
.
classHourId
=
courseId
;
}
return
item
;
const
hasExist
=
_
.
find
(
consumeStudentList
,
(
item
)
=>
{
return
item
.
studentId
===
studentId
;
});
}
else
{
_consumeStudentList
.
push
({
name
,
phone
,
studentId
,
classHourId
:
courseId
,
consumeHourNum
:
leftLessons
})
}
this
.
props
.
onSelect
(
_studentIds
,
_consumeStudentList
,
prevSelectRows
);
});
}
if
(
hasExist
)
{
_consumeStudentList
=
_
.
map
(
consumeStudentList
,
(
item
)
=>
{
if
(
item
.
studentId
===
studentId
)
{
item
.
classHourId
=
courseId
;
}
return
item
;
});
}
else
{
_consumeStudentList
.
push
({
name
,
phone
,
studentId
,
classHourId
:
courseId
,
consumeHourNum
:
leftLessons
,
});
}
this
.
props
.
onSelect
(
_studentIds
,
_consumeStudentList
,
prevSelectRows
);
}
);
};
handleSelect
=
(
selectedRowKeys
,
selectedRows
)
=>
{
const
{
studentType
,
allstudentList
,
consumeStudentList
}
=
this
.
props
;
...
...
@@ -325,121 +337,113 @@ class StudentList extends React.Component {
let
{
currentCourse
,
prevSelectRows
}
=
this
.
state
;
prevSelectRows
=
_
.
filter
(
prevSelectRows
,
(
item
)
=>
{
return
allStudentIds
.
indexOf
(
item
.
studentId
)
===
-
1
return
allStudentIds
.
indexOf
(
item
.
studentId
)
===
-
1
;
});
const
savedSelectedRows
=
[...
prevSelectRows
,
...
selectedRows
];
allSelectRows
=
savedSelectedRows
.
map
((
item
)
=>
{
const
{
studentId
,
digestHourVOS
=
[],
name
,
phone
}
=
item
;
// 如果该学员已经被选择了
const
hasSelectItem
=
_
.
find
(
consumeStudentList
,
_item
=>
{
const
hasSelectItem
=
_
.
find
(
consumeStudentList
,
(
_item
)
=>
{
return
_item
.
studentId
===
item
.
studentId
;
});
if
(
hasSelectItem
)
{
return
hasSelectItem
;
}
return
{
name
,
name
,
phone
,
studentId
,
classHourId
:
digestHourVOS
[
0
].
courseId
,
consumeHourNum
:
digestHourVOS
[
0
].
leftLessons
}
consumeHourNum
:
digestHourVOS
[
0
].
leftLessons
,
}
;
});
this
.
setState
({
selectedRows
,
savedSelectedRows
},
()
=>
{
this
.
props
.
onSelect
(
studentIds
,
allSelectRows
,
savedSelectedRows
);
});
this
.
setState
(
{
selectedRows
,
savedSelectedRows
,
},
()
=>
{
this
.
props
.
onSelect
(
studentIds
,
allSelectRows
,
savedSelectedRows
);
}
);
}
else
{
this
.
props
.
onSelect
(
studentIds
);
}
}
}
;
isDisabledRow
=
(
record
)
=>
{
// 扣课时的情况下, 无消耗课程的禁用
const
{
after
,
excludeIds
,
studentType
,
studentList
=
[],
consumeStudentList
=
[]
}
=
this
.
props
;
const
{
after
,
excludeIds
,
studentType
,
studentList
=
[],
consumeStudentList
=
[]
}
=
this
.
props
;
const
{
digestHourVOS
}
=
record
;
const
hasDigestHours
=
digestHourVOS
&&
digestHourVOS
.
length
;
// 已经入库的学员不可再选择
const
hasSelect
=
_
.
find
(
excludeIds
,
item
=>
{
return
item
==
record
.
studentId
const
hasSelect
=
_
.
find
(
excludeIds
,
(
item
)
=>
{
return
item
==
record
.
studentId
;
});
let
disabled
=
false
;
// 扣课时学员课时为0的情况下禁止选择
if
(
studentType
===
'DEDUCTION'
)
{
// 判断是否已经在不扣课时里
if
(
_
.
find
(
studentList
,
item
=>
item
.
studentId
===
record
.
studentId
))
{
if
(
_
.
find
(
studentList
,
(
item
)
=>
item
.
studentId
===
record
.
studentId
))
{
disabled
=
true
;
}
else
if
(
!
hasDigestHours
||
(
after
&&
!!
hasSelect
))
{
disabled
=
true
;
}
}
else
{
if
(
_
.
find
(
consumeStudentList
,
item
=>
item
.
studentId
===
record
.
studentId
))
{
if
(
_
.
find
(
consumeStudentList
,
(
item
)
=>
item
.
studentId
===
record
.
studentId
))
{
disabled
=
true
;
}
else
if
(
after
&&
!!
hasSelect
)
{
disabled
=
true
disabled
=
true
;
}
}
return
disabled
}
return
disabled
;
}
;
render
()
{
const
{
after
,
query
,
totalCount
,
studentIds
,
allstudentList
,
}
=
this
.
props
;
const
{
after
,
query
,
totalCount
,
studentIds
,
allstudentList
}
=
this
.
props
;
const
{
prevSelectRows
,
selectedRows
}
=
this
.
state
;
const
{
current
,
size
,
pageNo
,
pageSize
,
}
=
query
;
const
{
current
,
size
,
pageNo
,
pageSize
}
=
query
;
const
rowSelection
=
{
selectedRowKeys
:
studentIds
,
onChange
:
this
.
handleSelect
,
getCheckboxProps
:
(
record
)
=>
{
return
{
disabled
:
this
.
isDisabledRow
(
record
)
}
}
disabled
:
this
.
isDisabledRow
(
record
)
,
}
;
}
,
};
return
(
<
div
className=
"student-list"
>
<
Table
<
div
className=
'student-list'
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
bordered
size=
{
'small'
}
rowKey=
{
item
=>
item
.
studentId
}
rowKey=
{
(
item
)
=>
item
.
studentId
}
dataSource=
{
allstudentList
}
columns=
{
this
.
parseColumns
()
}
rowSelection=
{
rowSelection
}
onRow=
{
record
=>
({
onClick
:
e
=>
{
e
.
currentTarget
.
getElementsByClassName
(
"ant-checkbox-wrapper"
)[
0
]
.
click
();
}
onRow=
{
(
record
)
=>
({
onClick
:
(
e
)
=>
{
e
.
currentTarget
.
getElementsByClassName
(
'ant-checkbox-wrapper'
)[
0
].
click
();
},
})
}
scroll=
{
{
y
:
350
}
}
pagination=
{
false
}
/>
{
isNewVersion
?
{
isNewVersion
?
(
<
PageControl
size=
"small"
size=
'small'
current=
{
current
-
1
}
pageSize=
{
size
}
total=
{
totalCount
}
...
...
@@ -451,9 +455,10 @@ class StudentList extends React.Component {
onShowSizeChange=
{
(
current
,
size
)
=>
{
this
.
props
.
onChange
(
'size'
,
size
);
}
}
/>
:
/>
)
:
(
<
PageControl
size=
"small"
size=
'small'
current=
{
pageNo
}
pageSize=
{
pageSize
}
total=
{
totalCount
}
...
...
@@ -464,10 +469,10 @@ class StudentList extends React.Component {
onShowSizeChange=
{
(
pageNo
,
pageSize
)
=>
{
this
.
props
.
onChange
(
'pageNo'
,
pageSize
);
}
}
/>
}
/>
)
}
</
div
>
)
)
;
}
}
...
...
src/modules/course-manage/offline-course/OfflineCourseData.jsx
View file @
510254f6
import
React
from
'react'
;
import
{
Tooltip
,
Input
,
Radio
,
Table
,
Checkbox
}
from
'antd'
;
import
Service
from
'@/common/js/service'
;
import
User
from
'@/common/js/user'
;
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
Breadcrumbs
from
'@/components/Breadcrumbs'
;
import
{
Checkbox
,
Input
,
Tooltip
}
from
'antd'
;
import
moment
from
'moment'
;
import
React
from
'react'
;
import
_
from
'underscore'
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
PageControl
from
'@/components/PageControl'
;
import
Service
from
"@/common/js/service"
;
import
User
from
'@/common/js/user'
;
import
'./OfflineCourseData.less'
;
const
{
Search
}
=
Input
;
...
...
@@ -34,7 +35,7 @@ export default class OfflineCourseData extends React.Component {
joinInNum
:
0
,
joinNum
:
0
,
joinOutNum
:
0
,
}
}
;
}
componentDidMount
()
{
...
...
@@ -46,24 +47,27 @@ export default class OfflineCourseData extends React.Component {
Service
.
Hades
(
'public/hades/getOfflineCourseJoinBase'
,
{
courseId
}).
then
((
res
)
=>
{
if
(
res
.
success
)
{
const
{
result
}
=
res
;
const
group
=
_
.
groupBy
(
result
.
calendarTime
,
item
=>
moment
(
item
).
format
(
'YYYY-MM'
));
const
group
=
_
.
groupBy
(
result
.
calendarTime
,
(
item
)
=>
moment
(
item
).
format
(
'YYYY-MM'
));
const
calendarTime
=
_
.
map
(
group
,
(
value
,
key
)
=>
({
key
,
value
}));
const
currentDate
=
calendarTime
[
currentIndex
].
value
[
0
];
this
.
setState
({
courseName
:
result
.
courseName
,
fullJoin
:
result
.
fullJoin
||
0
,
totalJoin
:
result
.
totalJoin
||
0
,
calendarTime
,
currentDate
,
offlineCourseType
:
result
.
offlineCourseType
,
whetherSetSignIn
:
result
.
whetherSetSignIn
,
whetherSetSignOut
:
result
.
whetherSetSignOut
,
whetherSetSignInOut
:
result
.
whetherSetSignInOut
,
whetherSetApply
:
result
.
whetherSetApply
,
},
()
=>
this
.
getDateDetail
());
this
.
setState
(
{
courseName
:
result
.
courseName
,
fullJoin
:
result
.
fullJoin
||
0
,
totalJoin
:
result
.
totalJoin
||
0
,
calendarTime
,
currentDate
,
offlineCourseType
:
result
.
offlineCourseType
,
whetherSetSignIn
:
result
.
whetherSetSignIn
,
whetherSetSignOut
:
result
.
whetherSetSignOut
,
whetherSetSignInOut
:
result
.
whetherSetSignInOut
,
whetherSetApply
:
result
.
whetherSetApply
,
},
()
=>
this
.
getDateDetail
()
);
}
})
}
})
;
}
;
getDateDetail
=
(
current
=
1
)
=>
{
const
{
query
,
currentDate
,
courseId
}
=
this
.
state
;
...
...
@@ -75,9 +79,9 @@ export default class OfflineCourseData extends React.Component {
joinInNum
:
res
.
result
.
joinInNum
||
0
,
joinNum
:
res
.
result
.
joinNum
||
0
,
joinOutNum
:
res
.
result
.
joinOutNum
||
0
,
})
})
;
}
})
})
;
}
query
.
current
=
current
;
query
.
date
=
currentDate
;
...
...
@@ -85,8 +89,8 @@ export default class OfflineCourseData extends React.Component {
if
(
res
.
success
)
{
this
.
setState
({
data
:
res
.
result
.
records
,
total
:
res
.
result
.
total
});
}
})
}
})
;
}
;
getColumns
=
()
=>
{
const
{
whetherSetSignIn
,
whetherSetSignOut
,
whetherSetApply
}
=
this
.
state
;
...
...
@@ -96,50 +100,49 @@ export default class OfflineCourseData extends React.Component {
key
:
'name'
,
dataIndex
:
'name'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
record
.
name
}
</
div
>
)
}
return
<
div
>
{
record
.
name
}
</
div
>;
},
},
{
title
:
"手机号"
,
key
:
"phone"
,
dataIndex
:
"phone"
,
title
:
'手机号'
,
key
:
'phone'
,
dataIndex
:
'phone'
,
render
:
(
val
,
item
)
=>
{
return
(
<
div
>
{
item
.
phone
||
'-'
}
</
div
>
)
return
<
div
>
{
item
.
phone
||
'-'
}
</
div
>;
},
},
];
whetherSetApply
===
'YES'
&&
columns
.
push
({
title
:
'报名时间'
,
key
:
'joinTime'
,
dataIndex
:
'joinTime'
,
render
:
(
val
,
item
)
=>
{
return
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
item
.
joinTime
)
}
</
div
>
}
});
whetherSetSignIn
===
'YES'
&&
columns
.
push
({
title
:
'签到时间'
,
key
:
'joinInTime'
,
dataIndex
:
'joinInTime'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
val
?
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
:
'-'
;
}
})
whetherSetSignOut
===
'YES'
&&
columns
.
push
({
title
:
'签退时间'
,
key
:
'joinOutTime'
,
dataIndex
:
'joinOutTime'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
val
?
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
:
'-'
;
}
})
whetherSetApply
===
'YES'
&&
columns
.
push
({
title
:
'报名时间'
,
key
:
'joinTime'
,
dataIndex
:
'joinTime'
,
render
:
(
val
,
item
)
=>
{
return
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
item
.
joinTime
)
}
</
div
>;
},
});
whetherSetSignIn
===
'YES'
&&
columns
.
push
({
title
:
'签到时间'
,
key
:
'joinInTime'
,
dataIndex
:
'joinInTime'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
val
?
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
:
'-'
;
},
});
whetherSetSignOut
===
'YES'
&&
columns
.
push
({
title
:
'签退时间'
,
key
:
'joinOutTime'
,
dataIndex
:
'joinOutTime'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
val
?
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
:
'-'
;
},
});
return
columns
;
}
}
;
handleChangeTable
=
(
pagination
,
filters
,
sorter
)
=>
{
const
{
columnKey
,
order
}
=
sorter
;
...
...
@@ -161,8 +164,8 @@ export default class OfflineCourseData extends React.Component {
};
this
.
setState
({
query
:
_query
},
()
=>
{
this
.
getDateDetail
(
_query
.
current
);
})
}
})
;
}
;
render
()
{
const
{
...
...
@@ -189,26 +192,32 @@ export default class OfflineCourseData extends React.Component {
const
calendarLength
=
calendarTime
.
length
;
const
dateList
=
(
calendarTime
[
currentIndex
]
||
{}).
value
||
[];
return
(
<
div
className=
"page offline-course-data"
>
<
div
className=
'page offline-course-data'
>
<
Breadcrumbs
navList=
"参与数据"
navList=
'参与数据'
goBack=
{
()
=>
{
window
.
RCHistory
.
goBack
();
}
}
/>
<
div
className=
"box"
>
<
div
className=
"offline-name"
>
课程名称:
{
courseName
}
</
div
>
{
whetherSetApply
===
'YES'
&&
<
div
className=
"offline-application"
>
报名总人数:
{
totalJoin
}
</
div
>
}
{
whetherSetSignInOut
===
'YES'
&&
<
div
className=
"offline-application"
>
完成考勤总人数
<
Tooltip
title=
"根据上课日期,在规定时间内完成签到和签退的学员数"
><
span
className=
"icon iconfont"
>

</
span
></
Tooltip
>
:
{
fullJoin
}
</
div
>
}
<
div
className=
'box'
>
<
div
className=
'offline-name'
>
课程名称:
{
courseName
}
</
div
>
{
whetherSetApply
===
'YES'
&&
<
div
className=
'offline-application'
>
报名总人数:
{
totalJoin
}
</
div
>
}
{
whetherSetSignInOut
===
'YES'
&&
(
<
div
className=
'offline-application'
>
完成考勤总人数
<
Tooltip
title=
'根据上课日期,在规定时间内完成签到和签退的学员数'
>
<
span
className=
'icon iconfont'
>

</
span
>
</
Tooltip
>
:
{
fullJoin
}
</
div
>
)
}
</
div
>
<
div
className=
"box data-box"
>
<
div
className=
"left-box"
>
<
div
className=
"left-title"
>
上课日期
</
div
>
<
div
className=
"left-calendar"
>
<
div
className=
'box data-box'
>
<
div
className=
'left-box'
>
<
div
className=
'left-title'
>
上课日期
</
div
>
<
div
className=
'left-calendar'
>
<
div
className=
"icon-box"
className=
'icon-box'
onClick=
{
()
=>
{
const
index
=
currentIndex
-
1
;
if
(
index
>=
0
&&
index
<
calendarLength
)
{
...
...
@@ -216,13 +225,12 @@ export default class OfflineCourseData extends React.Component {
this
.
getDateDetail
();
});
}
}
}
>
<
span
className=
"icon iconfont"
>

</
span
>
}
}
>
<
span
className=
'icon iconfont'
>

</
span
>
</
div
>
<
div
className=
"calendar-text"
>
{
(
calendarTime
[
currentIndex
]
||
{}).
key
}
</
div
>
<
div
className=
'calendar-text'
>
{
(
calendarTime
[
currentIndex
]
||
{}).
key
}
</
div
>
<
div
className=
"icon-box"
className=
'icon-box'
onClick=
{
()
=>
{
const
index
=
currentIndex
+
1
;
if
(
index
>=
0
&&
index
<
calendarLength
)
{
...
...
@@ -230,112 +238,132 @@ export default class OfflineCourseData extends React.Component {
this
.
getDateDetail
();
});
}
}
}
>
<
span
className=
"icon iconfont"
>

</
span
>
}
}
>
<
span
className=
'icon iconfont'
>

</
span
>
</
div
>
</
div
>
<
div
className=
"date-list"
>
{
dateList
.
map
(
item
=>
(
<
div
className=
'date-list'
>
{
dateList
.
map
(
(
item
)
=>
(
<
div
className=
{
`date-item${item === currentDate ? ' selected' : ''}`
}
key=
{
item
}
onClick=
{
()
=>
{
this
.
setState
({
currentDate
:
item
},
()
=>
{
this
.
getDateDetail
();
})
}
}
>
{
window
.
formatDate
(
'MM月DD日(WW)'
,
item
)
}
</
div
>
});
}
}
>
{
window
.
formatDate
(
'MM月DD日(WW)'
,
item
)
}
</
div
>
))
}
</
div
>
</
div
>
<
div
className=
"right-box"
>
<
div
className=
"selected-date"
>
{
moment
(
currentDate
).
format
(
'MM-DD'
)
}
</
div
>
<
div
className=
"detail-data"
>
{
offlineCourseType
!==
'ALL_DAY_OFFLINE'
&&
whetherSetApply
===
'YES'
&&
<
span
className=
"icon iconfont"
>

</
span
>
}
{
offlineCourseType
!==
'ALL_DAY_OFFLINE'
&&
whetherSetApply
===
'YES'
&&
<
span
className=
"data-text"
>
报名人数:
{
joinNum
}
</
span
>
}
{
whetherSetSignInOut
===
'YES'
&&
<
span
className=
"icon iconfont"
>

</
span
>
}
{
whetherSetSignInOut
===
'YES'
&&
<
span
className=
"data-text"
>
完成考勤数
<
Tooltip
title=
"当日在规定时间内完成签到和签退的学员数"
><
span
className=
"icon iconfont"
>

</
span
></
Tooltip
>
:
{
fullJoinNum
}
</
span
>
}
{
whetherSetSignIn
===
'YES'
&&
<
span
className=
"icon iconfont"
>

</
span
>
}
{
whetherSetSignIn
===
'YES'
&&
<
span
className=
"data-text"
>
签到人数:
{
joinInNum
}
</
span
>
}
{
whetherSetSignOut
===
'YES'
&&
<
span
className=
"icon iconfont"
>

</
span
>
}
{
whetherSetSignOut
===
'YES'
&&
<
span
className=
"data-text"
>
签退人数:
{
joinOutNum
}
</
span
>
}
<
div
className=
'right-box'
>
<
div
className=
'selected-date'
>
{
moment
(
currentDate
).
format
(
'MM-DD'
)
}
</
div
>
<
div
className=
'detail-data'
>
{
offlineCourseType
!==
'ALL_DAY_OFFLINE'
&&
whetherSetApply
===
'YES'
&&
<
span
className=
'icon iconfont'
>

</
span
>
}
{
offlineCourseType
!==
'ALL_DAY_OFFLINE'
&&
whetherSetApply
===
'YES'
&&
<
span
className=
'data-text'
>
报名人数:
{
joinNum
}
</
span
>
}
{
whetherSetSignInOut
===
'YES'
&&
<
span
className=
'icon iconfont'
>

</
span
>
}
{
whetherSetSignInOut
===
'YES'
&&
(
<
span
className=
'data-text'
>
完成考勤数
<
Tooltip
title=
'当日在规定时间内完成签到和签退的学员数'
>
<
span
className=
'icon iconfont'
>

</
span
>
</
Tooltip
>
:
{
fullJoinNum
}
</
span
>
)
}
{
whetherSetSignIn
===
'YES'
&&
<
span
className=
'icon iconfont'
>

</
span
>
}
{
whetherSetSignIn
===
'YES'
&&
<
span
className=
'data-text'
>
签到人数:
{
joinInNum
}
</
span
>
}
{
whetherSetSignOut
===
'YES'
&&
<
span
className=
'icon iconfont'
>

</
span
>
}
{
whetherSetSignOut
===
'YES'
&&
<
span
className=
'data-text'
>
签退人数:
{
joinOutNum
}
</
span
>
}
</
div
>
<
div
className=
"detail-filter"
>
<
div
className=
'detail-filter'
>
<
Search
className=
"search-input"
placeholder=
"搜索学员姓名/手机号"
className=
'search-input'
placeholder=
'搜索学员姓名/手机号'
style=
{
{
width
:
200
,
marginRight
:
24
}
}
enterButton=
{
<
span
className=
"icon iconfont"
>

</
span
>
}
enterButton=
{
<
span
className=
'icon iconfont'
>

</
span
>
}
onSearch=
{
(
value
)
=>
{
const
_query
=
{
...
query
};
if
(
value
)
{
const
isPhone
=
(
value
||
""
).
match
(
/^
\d
+$/
);
const
name
=
isPhone
?
"storeCustomerPhone"
:
"storeCustomerName"
;
_query
.
storeCustomerName
=
""
;
_query
.
storeCustomerPhone
=
""
;
const
isPhone
=
(
value
||
''
).
match
(
/^
\d
+$/
);
const
name
=
isPhone
?
'storeCustomerPhone'
:
'storeCustomerName'
;
_query
.
storeCustomerName
=
''
;
_query
.
storeCustomerPhone
=
''
;
_query
[
name
]
=
value
;
}
else
{
_query
.
storeCustomerName
=
""
;
_query
.
storeCustomerPhone
=
""
;
_query
.
storeCustomerName
=
''
;
_query
.
storeCustomerPhone
=
''
;
}
this
.
setState
({
query
:
_query
},
()
=>
this
.
getDateDetail
());
}
}
/>
{
whetherSetSignInOut
===
'YES'
&&
<
div
className=
"filter-box"
>
<
span
className=
"label"
>
签到情况:
</
span
>
<
Checkbox
checked=
{
query
.
joinInState
===
'YES'
}
onChange=
{
(
e
)
=>
{
if
(
e
.
target
.
checked
)
{
this
.
setState
({
query
:
{
...
query
,
joinInState
:
'YES'
}
},
()
=>
this
.
getDateDetail
());
}
else
{
delete
query
.
joinInState
;
this
.
setState
({
query
},
()
=>
this
.
getDateDetail
())
}
}
}
>
已签到
</
Checkbox
>
<
Checkbox
checked=
{
query
.
joinInState
===
'NO'
}
onChange=
{
(
e
)
=>
{
if
(
e
.
target
.
checked
)
{
this
.
setState
({
query
:
{
...
query
,
joinInState
:
'NO'
}
},
()
=>
this
.
getDateDetail
());
}
else
{
delete
query
.
joinInState
;
this
.
setState
({
query
},
()
=>
this
.
getDateDetail
())
}
}
}
>
未签到
</
Checkbox
>
</
div
>
}
{
whetherSetSignOut
===
'YES'
&&
<
div
className=
"filter-box"
>
<
span
className=
"label"
>
签退情况:
</
span
>
<
Checkbox
checked=
{
query
.
joinOutState
===
'YES'
}
onChange=
{
(
e
)
=>
{
if
(
e
.
target
.
checked
)
{
this
.
setState
({
query
:
{
...
query
,
joinOutState
:
'YES'
}
},
()
=>
this
.
getDateDetail
());
}
else
{
delete
query
.
joinOutState
;
this
.
setState
({
query
},
()
=>
this
.
getDateDetail
())
}
}
}
>
已签退
</
Checkbox
>
<
Checkbox
checked=
{
query
.
joinOutState
===
'NO'
}
onChange=
{
(
e
)
=>
{
if
(
e
.
target
.
checked
)
{
this
.
setState
({
query
:
{
...
query
,
joinOutState
:
'NO'
}
},
()
=>
this
.
getDateDetail
());
}
else
{
delete
query
.
joinOutState
;
this
.
setState
({
query
},
()
=>
this
.
getDateDetail
())
}
}
}
>
未签退
</
Checkbox
>
</
div
>
}
{
whetherSetSignInOut
===
'YES'
&&
(
<
div
className=
'filter-box'
>
<
span
className=
'label'
>
签到情况:
</
span
>
<
Checkbox
checked=
{
query
.
joinInState
===
'YES'
}
onChange=
{
(
e
)
=>
{
if
(
e
.
target
.
checked
)
{
this
.
setState
({
query
:
{
...
query
,
joinInState
:
'YES'
}
},
()
=>
this
.
getDateDetail
());
}
else
{
delete
query
.
joinInState
;
this
.
setState
({
query
},
()
=>
this
.
getDateDetail
());
}
}
}
>
已签到
</
Checkbox
>
<
Checkbox
checked=
{
query
.
joinInState
===
'NO'
}
onChange=
{
(
e
)
=>
{
if
(
e
.
target
.
checked
)
{
this
.
setState
({
query
:
{
...
query
,
joinInState
:
'NO'
}
},
()
=>
this
.
getDateDetail
());
}
else
{
delete
query
.
joinInState
;
this
.
setState
({
query
},
()
=>
this
.
getDateDetail
());
}
}
}
>
未签到
</
Checkbox
>
</
div
>
)
}
{
whetherSetSignOut
===
'YES'
&&
(
<
div
className=
'filter-box'
>
<
span
className=
'label'
>
签退情况:
</
span
>
<
Checkbox
checked=
{
query
.
joinOutState
===
'YES'
}
onChange=
{
(
e
)
=>
{
if
(
e
.
target
.
checked
)
{
this
.
setState
({
query
:
{
...
query
,
joinOutState
:
'YES'
}
},
()
=>
this
.
getDateDetail
());
}
else
{
delete
query
.
joinOutState
;
this
.
setState
({
query
},
()
=>
this
.
getDateDetail
());
}
}
}
>
已签退
</
Checkbox
>
<
Checkbox
checked=
{
query
.
joinOutState
===
'NO'
}
onChange=
{
(
e
)
=>
{
if
(
e
.
target
.
checked
)
{
this
.
setState
({
query
:
{
...
query
,
joinOutState
:
'NO'
}
},
()
=>
this
.
getDateDetail
());
}
else
{
delete
query
.
joinOutState
;
this
.
setState
({
query
},
()
=>
this
.
getDateDetail
());
}
}
}
>
未签退
</
Checkbox
>
</
div
>
)
}
</
div
>
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
bordered
size=
"middle"
size=
'middle'
pagination=
{
false
}
columns=
{
this
.
getColumns
()
}
loading=
{
loading
}
...
...
@@ -354,6 +382,6 @@ export default class OfflineCourseData extends React.Component {
</
div
>
</
div
>
</
div
>
)
)
;
}
}
\ No newline at end of file
}
src/modules/course-manage/offline-course/components/OfflineCourseList.jsx
View file @
510254f6
...
...
@@ -6,35 +6,32 @@
* @Description: 视频课-列表模块
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
import
Service
from
'@/common/js/service'
;
import
User
from
'@/common/js/user'
;
import
college
from
'@/common/lottie/college'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
{
appId
,
LIVE_SHARE
}
from
'@/domains/course-domain/constants'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
ShareLiveModal
from
'@/modules/course-manage/modal/ShareLiveModal'
;
import
OfflineCourseData
from
'@/modules/course-manage/offline-course/OfflineCourseData'
;
import
{
Dropdown
,
message
,
Modal
,
Switch
,
Tooltip
}
from
'antd'
;
import
moment
from
'moment'
;
import
React
from
'react'
;
import
{
Table
,
Modal
,
message
,
Tooltip
,
Switch
,
Dropdown
}
from
'antd'
;
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
moment
from
'moment'
;
import
$
from
'jquery'
;
import
{
PageControl
}
from
"@/components"
;
import
{
appId
,
shareUrl
,
LIVE_SHARE
}
from
'@/domains/course-domain/constants'
;
import
OfflineCourseData
from
'@/modules/course-manage/offline-course/OfflineCourseData'
;
import
ShareLiveModal
from
'@/modules/course-manage/modal/ShareLiveModal'
;
import
Service
from
"@/common/js/service"
;
import
CourseService
from
"@/domains/course-domain/CourseService"
;
import
RelatedPlanModal
from
'../../modal/RelatedPlanModal'
;
import
ENUM
from
'../../../knowledge-base/ENUM.js'
;
import
PreviewOfflineModal
from
'../modal/PreviewOfflineModal'
;
import
ENUM
from
"../../../knowledge-base/ENUM.js"
;
import
User
from
'@/common/js/user'
import
QRCodeModal
from
'../modal/QRCodeModal'
;
import
'./OfflineCourseList.less'
;
const
ENV
=
process
.
env
.
DEPLOY_ENV
||
'dev'
;
const
defaultCoverUrl
=
'https://image.xiaomaiketang.com/xm/pxbWKsYA87.png'
;
class
OfflineCourseList
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
id
:
''
,
// 视频课ID
studentIds
:
[],
}
}
;
}
componentDidMount
()
{
...
...
@@ -44,18 +41,18 @@ class OfflineCourseList extends React.Component {
this
.
handleShowShareModal
(
_videoCourseItem
,
true
);
}
}
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
""
;
planArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
planArray
.
length
-
1
)
{
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
''
;
planArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
planArray
.
length
-
1
)
{
planStr
=
planStr
+
item
.
planName
+
'、'
;
}
else
{
planStr
=
planStr
+
item
.
planName
}
else
{
planStr
=
planStr
+
item
.
planName
;
}
})
return
planStr
}
})
;
return
planStr
;
}
;
// 请求表头
parseColumns
=
()
=>
{
const
columns
=
[
...
...
@@ -63,35 +60,39 @@ class OfflineCourseList extends React.Component {
title
:
'线下课'
,
key
:
'scheduleName'
,
dataIndex
:
'scheduleName'
,
width
:
321
,
width
:
321
,
fixed
:
'left'
,
render
:
(
val
,
record
)
=>
{
const
{
courseMediaVOS
,
courseName
,
offlinePlace
,
calendarTime
,
startTime
,
endTime
}
=
record
;
const
coverUrl
=
(
_
.
find
(
courseMediaVOS
,
data
=>
data
.
contentType
===
'COVER'
)
||
{}).
mediaUrl
;
const
coverUrl
=
(
_
.
find
(
courseMediaVOS
,
(
data
)
=>
data
.
contentType
===
'COVER'
)
||
{}).
mediaUrl
;
let
isContinue
=
calendarTime
.
length
>
1
;
_
.
reduce
(
calendarTime
,
(
a
,
b
)
=>
{
isContinue
=
isContinue
&&
(
b
-
a
===
86400000
)
;
isContinue
=
isContinue
&&
b
-
a
===
86400000
;
return
b
;
})
})
;
const
lastTime
=
_
.
last
(
calendarTime
);
const
time
=
`
${
!
isContinue
?
calendarTime
.
map
(
item
=>
moment
(
item
).
format
(
'MM-DD'
)).
join
(
'、'
)
:
`
${
moment
(
calendarTime
[
0
]).
format
(
'MM-DD'
)}
~
${
moment
(
lastTime
).
format
(
'MM-DD'
)}
`
}
${
moment
(
startTime
).
format
(
'HH:mm'
)}
~
${
moment
(
endTime
).
format
(
'HH:mm'
)}
`
;
const
time
=
`
${
!
isContinue
?
calendarTime
.
map
((
item
)
=>
moment
(
item
).
format
(
'MM-DD'
)).
join
(
'、'
)
:
`
${
moment
(
calendarTime
[
0
]).
format
(
'MM-DD'
)}
~
${
moment
(
lastTime
).
format
(
'MM-DD'
)}
`
}
${
moment
(
startTime
).
format
(
'HH:mm'
)}
~
${
moment
(
endTime
).
format
(
'HH:mm'
)}
`
;
return
(
<
div
className=
"record__item"
>
<
img
className=
"course-cover"
src=
{
coverUrl
||
defaultCoverUrl
}
/>
<
div
className=
'record__item'
>
<
img
className=
'course-cover'
src=
{
coverUrl
||
defaultCoverUrl
}
/>
<
div
style=
{
{
width
:
175
}
}
>
<
Tooltip
title=
{
courseName
}
>
<
div
className=
"course-name"
>
{
courseName
}
</
div
>
<
div
className=
'course-name'
>
{
courseName
}
</
div
>
</
Tooltip
>
<
Tooltip
title=
{
`地点:${offlinePlace}`
}
>
<
div
className=
"course-text"
>
地点:
{
offlinePlace
}
</
div
>
<
div
className=
'course-text'
>
地点:
{
offlinePlace
}
</
div
>
</
Tooltip
>
<
Tooltip
title=
{
time
}
>
<
div
className=
"course-text"
>
{
time
}
</
div
>
<
div
className=
'course-text'
>
{
time
}
</
div
>
</
Tooltip
>
</
div
>
</
div
>
)
}
)
;
}
,
},
{
title
:
'课程状态'
,
...
...
@@ -100,12 +101,12 @@ class OfflineCourseList extends React.Component {
width
:
120
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"course-state"
>
<
div
className=
'course-state'
>
<
div
style=
{
{
width
:
6
,
height
:
6
,
borderRadius
:
'50%'
,
background
:
ENUM
.
offlineStateShow
[
val
].
color
,
marginRight
:
8
}
}
></
div
>
{
ENUM
.
offlineStateShow
[
val
].
title
}
</
div
>
)
}
)
;
}
,
},
{
title
:
'课程分类'
,
...
...
@@ -113,39 +114,40 @@ class OfflineCourseList extends React.Component {
dataIndex
:
'categoryName'
,
width
:
120
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"record__item"
>
{
record
.
categorySonName
}
</
div
>
)
}
return
<
div
className=
'record__item'
>
{
record
.
categorySonName
}
</
div
>;
},
},
{
title
:
<
span
>
<
span
>
学院展示
</
span
>
<
Tooltip
title=
{
<
div
>
开启后,学员可在学院内查看到此课程。若课程“取消”,则系统会自动“关闭”学院展示。
<
br
/>
关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。
</
div
>
}
><
i
className=
"icon iconfont"
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'normal'
}
}
>

</
i
></
Tooltip
>
</
span
>,
title
:
(
<
span
>
<
span
>
学院展示
</
span
>
<
Tooltip
title=
{
<
div
>
开启后,学员可在学院内查看到此课程。若课程“取消”,则系统会自动“关闭”学院展示。
<
br
/>
关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。
</
div
>
}
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'normal'
}
}
>

</
i
>
</
Tooltip
>
</
span
>
),
width
:
120
,
dataIndex
:
"courseware"
,
dataIndex
:
'courseware'
,
render
:
(
val
,
item
,
index
)
=>
{
return
(
<
Switch
disabled=
{
item
.
courseState
===
'EXPIRED'
}
checked=
{
item
.
shelfState
===
"YES"
}
onChange=
{
()
=>
this
.
changeShelfState
(
item
)
}
/>
)
return
<
Switch
disabled=
{
item
.
courseState
===
'EXPIRED'
}
checked=
{
item
.
shelfState
===
'YES'
}
onChange=
{
()
=>
this
.
changeShelfState
(
item
)
}
/>;
},
},
{
title
:
"讲师"
,
title
:
'讲师'
,
width
:
200
,
key
:
"teacher"
,
dataIndex
:
"teacher"
,
key
:
'teacher'
,
dataIndex
:
'teacher'
,
render
:
(
val
,
item
)
=>
{
return
(
<
div
>
{
item
.
teacherName
}
</
div
>
)
return
<
div
>
{
item
.
teacherName
}
</
div
>;
},
},
{
...
...
@@ -155,22 +157,26 @@ class OfflineCourseList extends React.Component {
dataIndex
:
'apply'
,
sorter
:
true
,
render
:
(
val
,
item
)
=>
{
return
<
div
>
{
item
.
startTimeApply
?
`${formatDate('MM-DD H:i', item.startTimeApply)} ~ ${formatDate('MM-DD H:i', item.endTimeApply)}`
:
'-'
}
{
item
.
whetherApplyFull
===
'YES'
&&
<
span
style=
{
{
marginLeft
:
4
,
color
:
'#FF4F4F'
,
background
:
'rgba(255, 79, 79, 0.1)'
,
padding
:
'0 8px'
,
fontSize
:
'12px'
,
height
:
'18px'
,
lineHeight
:
'18px'
,
}
}
>
已报满
</
span
>
}
</
div
>
}
return
(
<
div
>
{
item
.
startTimeApply
?
`${formatDate('MM-DD H:i', item.startTimeApply)} ~ ${formatDate('MM-DD H:i', item.endTimeApply)}`
:
'-'
}
{
item
.
whetherApplyFull
===
'YES'
&&
(
<
span
style=
{
{
marginLeft
:
4
,
color
:
'#FF4F4F'
,
background
:
'rgba(255, 79, 79, 0.1)'
,
padding
:
'0 8px'
,
fontSize
:
'12px'
,
height
:
'18px'
,
lineHeight
:
'18px'
,
}
}
>
已报满
</
span
>
)
}
</
div
>
);
},
},
{
title
:
'创建时间'
,
...
...
@@ -179,8 +185,8 @@ class OfflineCourseList extends React.Component {
dataIndex
:
'created'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
;
}
,
},
{
title
:
'操作'
,
...
...
@@ -190,30 +196,33 @@ class OfflineCourseList extends React.Component {
fixed
:
'right'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"operate"
>
<
div
className=
"operate__item"
onClick=
{
()
=>
window
.
RCHistory
.
push
(
`/offline-course/data?id=${record.courseId}`
)
}
>
参与数据
</
div
>
{
record
.
courseState
!==
'EXPIRED'
&&
<
span
className=
"operate__item split"
>
|
</
span
>
}
{
record
.
courseState
!==
'EXPIRED'
&&
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
handleShowShareModal
(
record
)
}
>
分享
</
div
>
}
<
span
className=
"operate__item split"
>
|
</
span
>
<
div
className=
'operate'
>
<
div
className=
'operate__item'
onClick=
{
()
=>
window
.
RCHistory
.
push
(
`/offline-course/data?id=${record.courseId}`
)
}
>
参与数据
</
div
>
{
record
.
courseState
!==
'EXPIRED'
&&
<
span
className=
'operate__item split'
>
|
</
span
>
}
{
record
.
courseState
!==
'EXPIRED'
&&
(
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleShowShareModal
(
record
)
}
>
分享
</
div
>
)
}
<
span
className=
'operate__item split'
>
|
</
span
>
<
Dropdown
overlay=
{
this
.
renderMoreOperate
(
record
)
}
>
<
span
className=
"more-operate"
>
<
span
className=
"operate-text"
>
更多
</
span
>
<
span
className=
"iconfont icon"
style=
{
{
color
:
"#2966FF"
}
}
>
<
span
className=
'more-operate'
>
<
span
className=
'operate-text'
>
更多
</
span
>
<
span
className=
'iconfont icon'
style=
{
{
color
:
'#2966FF'
}
}
>

</
span
>
</
span
>
</
Dropdown
>
</
div
>
)
}
}
)
;
}
,
}
,
];
return
columns
;
}
}
;
// 显示预览弹窗
handleShowPreviewModal
=
(
courseId
)
=>
{
const
previewOfflineModal
=
(
...
...
@@ -221,133 +230,142 @@ class OfflineCourseList extends React.Component {
courseId=
{
courseId
}
close=
{
()
=>
{
this
.
setState
({
previewOfflineModal
:
null
})
previewOfflineModal
:
null
,
})
;
}
}
/>
);
this
.
setState
({
previewOfflineModal
});
}
}
;
renderMoreOperate
=
(
item
)
=>
{
return
(
<
div
className=
"live-course-more-menu"
>
{
item
.
courseState
!==
'EXPIRED'
&&
(
item
.
whetherSetSignIn
===
'YES'
||
item
.
whetherSetSignOut
===
'YES'
)
&&
<
div
className=
"operate__item"
key=
"qrcode"
onClick=
{
()
=>
{
this
.
setState
({
openQRCodeModal
:
true
,
qrcodeData
:
item
})
}
}
>
考勤二维码
</
div
>
}
<
div
className=
'live-course-more-menu'
>
{
item
.
courseState
!==
'EXPIRED'
&&
(
item
.
whetherSetSignIn
===
'YES'
||
item
.
whetherSetSignOut
===
'YES'
)
&&
(
<
div
className=
'operate__item'
key=
'qrcode'
onClick=
{
()
=>
{
this
.
setState
({
openQRCodeModal
:
true
,
qrcodeData
:
item
});
}
}
>
考勤二维码
</
div
>
)
}
<
div
className=
"operate__item"
key=
"preview"
className=
'operate__item'
key=
'preview'
onClick=
{
()
=>
{
this
.
handleShowPreviewModal
(
item
.
courseId
);
}
}
>
预览
</
div
>
{
(
User
.
getUserRole
()
===
'CloudManager'
||
User
.
getUserRole
()
===
'StoreManager'
)
&&
(
item
.
courseState
===
'UN_START'
||
item
.
courseState
===
'STARTING'
)
&&
<
div
className=
"operate__item"
key=
"cancel"
onClick=
{
()
=>
{
this
.
handleDeleteOfflineCourse
(
item
.
courseId
);
}
}
>
取消课程
</
div
>
}
{
item
.
courseState
===
'UN_START'
&&
window
.
ctx
.
xmState
.
storeUserPermissionList
.
includes
(
'EditOfflineClass'
)
&&
<
div
className=
"operate__item"
key=
"edit"
onClick=
{
()
=>
{
RCHistory
.
push
(
`/create-offline-course?type=edit&id=${item.courseId}`
);
}
}
>
编辑
</
div
>
}
{
(
User
.
getUserRole
()
===
'CloudManager'
||
User
.
getUserRole
()
===
'StoreManager'
)
&&
<
div
className=
"operate__item"
key=
"delete"
onClick=
{
()
=>
this
.
handleDeleteOfflineCourse
(
item
.
courseId
,
true
)
}
>
删除
</
div
>
}
}
}
>
预览
</
div
>
{
(
User
.
getUserRole
()
===
'CloudManager'
||
User
.
getUserRole
()
===
'StoreManager'
)
&&
(
item
.
courseState
===
'UN_START'
||
item
.
courseState
===
'STARTING'
)
&&
(
<
div
className=
'operate__item'
key=
'cancel'
onClick=
{
()
=>
{
this
.
handleDeleteOfflineCourse
(
item
.
courseId
);
}
}
>
取消课程
</
div
>
)
}
{
item
.
courseState
===
'UN_START'
&&
window
.
ctx
.
xmState
.
storeUserPermissionList
.
includes
(
'EditOfflineClass'
)
&&
(
<
div
className=
'operate__item'
key=
'edit'
onClick=
{
()
=>
{
RCHistory
.
push
(
`/create-offline-course?type=edit&id=${item.courseId}`
);
}
}
>
编辑
</
div
>
)
}
{
(
User
.
getUserRole
()
===
'CloudManager'
||
User
.
getUserRole
()
===
'StoreManager'
)
&&
(
<
div
className=
'operate__item'
key=
'delete'
onClick=
{
()
=>
this
.
handleDeleteOfflineCourse
(
item
.
courseId
,
true
)
}
>
删除
</
div
>
)
}
</
div
>
)
}
//改变上架状态
)
;
}
;
//改变上架状态
changeShelfState
=
(
item
)
=>
{
if
(
!
window
.
ctx
.
xmState
.
storeUserPermissionList
.
includes
(
'EditOfflineClass'
))
{
message
.
warning
(
'无【编辑线下课】权限,请联系管理员'
)
message
.
warning
(
'无【编辑线下课】权限,请联系管理员'
)
;
return
;
}
let
_shelfState
=
item
.
shelfState
if
(
_shelfState
===
'NO'
)
{
_shelfState
=
"YES"
;
item
.
shelfState
=
"YES"
}
else
{
_shelfState
=
"NO"
item
.
shelfState
=
"NO"
let
_shelfState
=
item
.
shelfState
;
if
(
_shelfState
===
'NO'
)
{
_shelfState
=
'YES'
;
item
.
shelfState
=
'YES'
;
}
else
{
_shelfState
=
'NO'
;
item
.
shelfState
=
'NO'
;
}
const
params
=
{
const
params
=
{
courseId
:
item
.
courseId
,
shelfState
:
_shelfState
}
CourseService
.
changeVideoShelfState
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
_shelfState
===
"YES"
)
{
message
.
success
(
"已开启展示"
);
}
else
{
message
.
success
(
"已取消展示"
);
shelfState
:
_shelfState
,
}
;
CourseService
.
changeVideoShelfState
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
_shelfState
===
'YES'
)
{
message
.
success
(
'已开启展示'
);
}
else
{
message
.
success
(
'已取消展示'
);
}
this
.
props
.
onChange
();
}
})
}
})
;
}
;
// 删除视频课
handleDeleteOfflineCourse
=
(
courseId
,
isDelete
)
=>
{
if
(
isDelete
)
{
Modal
.
confirm
({
title
:
'删除课程'
,
content
:
'确定删除该课程吗?删除后学员数据和课程数据将无法恢复。'
,
icon
:
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
okText
:
'确定'
,
okType
:
'danger'
,
cancelText
:
'取消'
,
onOk
:
()
=>
{
const
param
=
{
const
param
=
{
courseId
:
courseId
,
}
}
;
Service
.
Hades
(
'public/hades/delOfflineCourse'
,
param
).
then
(()
=>
{
message
.
success
(
'删除成功'
);
this
.
props
.
onChange
();
})
}
})
;
}
,
});
}
else
{
Modal
.
confirm
({
title
:
'取消课程'
,
content
:
'确定要取消该课程吗?取消后课程将失效,仅保留已有数据。'
,
icon
:
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
okText
:
'确定'
,
cancelText
:
'取消'
,
onOk
:
()
=>
{
const
param
=
{
const
param
=
{
courseId
:
courseId
,
}
}
;
Service
.
Hades
(
'public/hades/cancelOfflineCourse'
,
param
).
then
(()
=>
{
message
.
success
(
'取消成功'
);
this
.
props
.
onChange
();
})
}
})
;
}
,
});
}
}
};
// 显示分享弹窗
handleShowShareModal
=
(
record
,
needStr
=
false
)
=>
{
const
{
courseId
}
=
record
;
const
_appId
=
appId
;
const
_appId
=
appId
;
const
htmlUrl
=
`
${
LIVE_SHARE
}
offline_detail/
${
courseId
}
?id=
${
User
.
getStoreId
()}
`
;
const
longUrl
=
htmlUrl
;
const
{
courseName
,
courseMediaVOS
}
=
record
;
const
coverUrl
=
(
_
.
find
(
courseMediaVOS
,
data
=>
data
.
contentType
===
'COVER'
)
||
{}).
mediaUrl
;
const
coverUrl
=
(
_
.
find
(
courseMediaVOS
,
(
data
)
=>
data
.
contentType
===
'COVER'
)
||
{}).
mediaUrl
;
const
shareData
=
{
longUrl
,
coverUrl
,
...
...
@@ -358,11 +376,11 @@ class OfflineCourseList extends React.Component {
<
ShareLiveModal
needStr=
{
needStr
}
data=
{
shareData
}
type=
"offlineClass"
title=
"线下课"
type=
'offlineClass'
title=
'线下课'
close=
{
()
=>
{
this
.
setState
({
shareLiveModal
:
null
shareLiveModal
:
null
,
});
localStorage
.
setItem
(
'videoCourseItem'
,
''
);
}
}
...
...
@@ -370,67 +388,83 @@ class OfflineCourseList extends React.Component {
);
this
.
setState
({
shareLiveModal
});
}
}
;
handleChangeTable
=
(
pagination
,
filters
,
sorter
)
=>
{
const
{
columnKey
,
order
}
=
sorter
;
const
{
query
}
=
this
.
props
;
let
_columnKey
;
let
_columnKey
;
let
_order
;
// 按创建时间升序排序
if
(
columnKey
===
'apply'
&&
order
===
'ascend'
)
{
_columnKey
=
"START_APPLY_DESC"
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'created'
&&
order
===
'ascend'
)
{
_columnKey
=
"CREATED"
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'apply'
&&
order
===
'ascend'
)
{
_columnKey
=
'START_APPLY_DESC'
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'created'
&&
order
===
'ascend'
)
{
_columnKey
=
'CREATED'
;
_order
=
'SORT_ASC'
;
}
// 按创建时间降序排序
if
(
columnKey
===
'apply'
&&
order
===
'descend'
)
{
_columnKey
=
"START_APPLY_DESC"
;
_order
=
'SORT_DESC'
;}
if
(
columnKey
===
'created'
&&
order
===
'descend'
)
{
_columnKey
=
"CREATED"
;
_order
=
'SORT_DESC'
;}
if
(
columnKey
===
'apply'
&&
order
===
'descend'
)
{
_columnKey
=
'START_APPLY_DESC'
;
_order
=
'SORT_DESC'
;
}
if
(
columnKey
===
'created'
&&
order
===
'descend'
)
{
_columnKey
=
'CREATED'
;
_order
=
'SORT_DESC'
;
}
const
_query
=
{
...
query
,
sortMap
:
{}
sortMap
:
{},
};
_query
.
sortMap
[
_columnKey
]
=
_order
;
_query
.
sortMap
[
_columnKey
]
=
_order
;
this
.
props
.
onChange
(
_query
);
}
}
;
render
()
{
const
{
openQRCodeModal
,
qrcodeData
}
=
this
.
state
;
const
{
dataSource
=
[],
totalCount
,
query
,
match
}
=
this
.
props
;
const
{
current
,
size
}
=
query
;
return
(
<
div
className=
"offline-course-list"
>
<
Table
rowKey=
{
record
=>
record
.
courseId
}
<
div
className=
'offline-course-list'
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
courseId
}
dataSource=
{
dataSource
}
columns=
{
this
.
parseColumns
()
}
onChange=
{
this
.
handleChangeTable
}
pagination=
{
false
}
scroll=
{
{
x
:
1500
}
}
scroll=
{
{
x
:
1500
}
}
bordered
className=
"offline-list-table"
className=
'offline-list-table'
/>
<
div
className=
"box-footer"
>
<
div
className=
'box-footer'
>
<
PageControl
current=
{
current
-
1
}
pageSize=
{
size
}
total=
{
totalCount
}
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
props
.
onChange
(
_query
)
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
props
.
onChange
(
_query
)
;
}
}
/>
</
div
>
</
div
>
{
this
.
state
.
shareLiveModal
}
{
this
.
state
.
previewOfflineModal
}
<
QRCodeModal
visible=
{
openQRCodeModal
}
data=
{
qrcodeData
}
onCancel=
{
()
=>
{
this
.
setState
({
openQRCodeModal
:
false
})
this
.
setState
({
openQRCodeModal
:
false
})
;
}
}
/>
<
Route
path=
{
`${match.url}/data`
}
component=
{
OfflineCourseData
}
/>
</
div
>
)
)
;
}
}
...
...
src/modules/course-manage/video-course/components/VideoCourseList.jsx
View file @
510254f6
import
React
from
"react"
import
{
Table
,
Modal
,
message
,
Tooltip
,
Switch
,
Dropdown
}
from
"antd"
import
_
from
"underscore"
import
{
PageControl
}
from
"@/components"
import
{
LIVE_SHARE
}
from
"@/domains/course-domain/constants"
import
ShareLiveModal
from
"@/modules/course-manage/modal/ShareLiveModal"
import
WatchDataModal
from
"../modal/WatchDataModal"
import
CourseService
from
"@/domains/course-domain/CourseService"
import
RelatedPlanModal
from
"../../modal/RelatedPlanModal"
import
User
from
"@/common/js/user"
import
"./VideoCourseList.less"
import
{
Dropdown
,
message
,
Modal
,
Switch
,
Table
,
Tooltip
}
from
'antd'
;
import
User
from
'@/common/js/user'
;
import
{
PageControl
}
from
'@/components'
;
import
{
LIVE_SHARE
}
from
'@/domains/course-domain/constants'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
ShareLiveModal
from
'@/modules/course-manage/modal/ShareLiveModal'
;
import
React
from
'react'
;
import
RelatedPlanModal
from
'../../modal/RelatedPlanModal'
;
import
WatchDataModal
from
'../modal/WatchDataModal'
;
import
{
XMTable
}
from
'@/components'
;
import
college
from
'@/common/lottie/college'
;
import
'./VideoCourseList.less'
;
class
VideoCourseList
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
)
super
(
props
)
;
this
.
state
=
{
id
:
""
,
// 视频课ID
id
:
''
,
// 视频课ID
studentIds
:
[],
RelatedPlanModalVisible
:
false
,
selectPlanList
:
{},
ShelfLoading
:
false
ShelfLoading
:
false
,
// dataSource: [],
}
}
;
}
componentDidMount
()
{
const
videoCourseItem
=
localStorage
.
getItem
(
"videoCourseItem"
)
const
videoCourseItem
=
localStorage
.
getItem
(
'videoCourseItem'
);
if
(
videoCourseItem
)
{
const
_videoCourseItem
=
JSON
.
parse
(
videoCourseItem
)
this
.
handleShowShareModal
(
_videoCourseItem
,
true
)
const
_videoCourseItem
=
JSON
.
parse
(
videoCourseItem
)
;
this
.
handleShowShareModal
(
_videoCourseItem
,
true
)
;
}
}
...
...
@@ -41,27 +40,27 @@ class VideoCourseList extends React.Component {
data=
{
record
}
close=
{
()
=>
{
this
.
setState
({
watchDataModal
:
null
})
watchDataModal
:
null
,
})
;
}
}
/>
)
this
.
setState
({
watchDataModal
})
}
)
;
this
.
setState
({
watchDataModal
})
;
}
;
// 请求表头
parseColumns
=
()
=>
{
const
{
type
}
=
this
.
props
const
{
ShelfLoading
}
=
this
.
state
const
{
type
}
=
this
.
props
;
const
{
ShelfLoading
}
=
this
.
state
;
const
columns
=
[
{
title
:
"视频课"
,
key
:
"scheduleName"
,
dataIndex
:
"scheduleName"
,
title
:
'视频课'
,
key
:
'scheduleName'
,
dataIndex
:
'scheduleName'
,
width
:
321
,
fixed
:
"left"
,
fixed
:
'left'
,
render
:
(
val
,
record
)
=>
{
const
{
coverUrl
,
scheduleVideoUrl
}
=
record
const
{
coverUrl
,
scheduleVideoUrl
}
=
record
;
return
(
<
div
className=
'record__item'
>
{
/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */
}
...
...
@@ -69,7 +68,7 @@ class VideoCourseList extends React.Component {
className=
'course-cover'
src=
{
coverUrl
||
(
type
===
"internal"
?
`${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast`
:
"https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png"
)
(
type
===
'internal'
?
`${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast`
:
'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png'
)
}
alt=
''
/>
...
...
@@ -84,45 +83,45 @@ class VideoCourseList extends React.Component {
</
Otherwise
>
</
Choose
>
</
div
>
)
}
)
;
}
,
},
{
title
:
(
<
span
>
<
span
>
课程分类
</
span
>
<
If
condition=
{
type
!==
"internal"
}
>
<
If
condition=
{
type
!==
'internal'
}
>
<
Tooltip
title=
{
<
div
>
外部课程的分类由系统提供,不影响企业课程分类。
</
div
>
}
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
"5px"
,
cursor
:
"pointer"
,
color
:
"#bfbfbf"
,
fontSize
:
"14px"
,
fontWeight
:
"normal"
}
}
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'normal'
}
}
>

</
i
>
</
Tooltip
>
</
If
>
</
span
>
),
key
:
"categoryName"
,
dataIndex
:
"categoryName"
,
key
:
'categoryName'
,
dataIndex
:
'categoryName'
,
width
:
200
,
render
:
(
val
,
record
)
=>
{
return
(
<
Choose
>
<
When
condition=
{
type
===
"internal"
}
>
<
When
condition=
{
type
===
'internal'
}
>
<
div
className=
'record__item'
>
{
record
.
categoryOneName
}
{
record
.
categoryTwoName
?
`-${record.categoryTwoName}`
:
""
}
{
record
.
categoryTwoName
?
`-${record.categoryTwoName}`
:
''
}
</
div
>
</
When
>
<
Otherwise
>
<
div
className=
'record__item'
>
{
record
.
categorySonName
}
</
div
>
</
Otherwise
>
</
Choose
>
)
}
)
;
}
,
},
{
title
:
"创建人"
,
key
:
"createName"
,
dataIndex
:
"createName"
,
title
:
'创建人'
,
key
:
'createName'
,
dataIndex
:
'createName'
,
width
:
100
,
render
:
(
val
)
=>
{
return
(
...
...
@@ -133,8 +132,8 @@ class VideoCourseList extends React.Component {
</
Tooltip
>
)
}
</
div
>
)
}
)
;
}
,
},
{
title
:
(
...
...
@@ -148,62 +147,62 @@ class VideoCourseList extends React.Component {
关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。
</
div
>
}
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
"5px"
,
cursor
:
"pointer"
,
color
:
"#bfbfbf"
,
fontSize
:
"14px"
}
}
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
}
}
>

</
i
>
</
Tooltip
>
</
span
>
),
width
:
120
,
key
:
"shelfState"
,
dataIndex
:
"shelfState"
,
key
:
'shelfState'
,
dataIndex
:
'shelfState'
,
render
:
(
val
,
item
,
index
)
=>
{
return
(
<
Switch
loading=
{
ShelfLoading
}
checked=
{
item
.
shelfState
===
"YES"
}
checked=
{
item
.
shelfState
===
'YES'
}
defaultChecked=
{
item
.
shelfState
}
onClick=
{
(
checked
)
=>
{
this
.
changeShelfState
(
checked
,
item
,
index
)
this
.
changeShelfState
(
checked
,
item
,
index
)
;
}
}
/>
)
}
)
;
}
,
},
{
title
:
"观看学员数"
,
title
:
'观看学员数'
,
width
:
110
,
key
:
"watchUserCount"
,
dataIndex
:
"watchUserCount"
,
key
:
'watchUserCount'
,
dataIndex
:
'watchUserCount'
,
render
:
(
val
,
item
)
=>
{
return
<
div
className=
'watchUserCount'
>
{
val
||
0
}
</
div
>
}
return
<
div
className=
'watchUserCount'
>
{
val
||
0
}
</
div
>
;
}
,
},
{
title
:
"创建时间"
,
title
:
'创建时间'
,
width
:
181
,
key
:
"created"
,
dataIndex
:
"created"
,
key
:
'created'
,
dataIndex
:
'created'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
formatDate
(
"YYYY-MM-DD H:i"
,
val
)
}
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
);
}
,
},
{
title
:
"更新时间"
,
title
:
'更新时间'
,
width
:
181
,
key
:
"updated"
,
dataIndex
:
"updated"
,
key
:
'updated'
,
dataIndex
:
'updated'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
formatDate
(
"YYYY-MM-DD H:i"
,
val
)
}
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
);
}
,
},
{
title
:
"关联项"
,
title
:
'关联项'
,
width
:
200
,
key
:
"planList"
,
dataIndex
:
"planList"
,
key
:
'planList'
,
dataIndex
:
'planList'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
'related-task'
>
...
...
@@ -215,7 +214,7 @@ class VideoCourseList extends React.Component {
<
span
>
{
item
.
planName
}
{
index
<
record
.
relatedPlanList
.
length
-
1
&&
<
span
>
、
</
span
>
}
</
span
>
)
)
;
})
}
</
Tooltip
>
</
When
>
...
...
@@ -224,15 +223,15 @@ class VideoCourseList extends React.Component {
</
Otherwise
>
</
Choose
>
</
div
>
)
}
)
;
}
,
},
{
title
:
"操作"
,
key
:
"operate"
,
dataIndex
:
"operate"
,
title
:
'操作'
,
key
:
'operate'
,
dataIndex
:
'operate'
,
width
:
210
,
fixed
:
"right"
,
fixed
:
'right'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
'operate'
>
...
...
@@ -240,7 +239,7 @@ class VideoCourseList extends React.Component {
观看数据
</
div
>
<
If
condition=
{
type
===
"internal"
}
>
<
If
condition=
{
type
===
'internal'
}
>
<
span
className=
'operate__item split'
>
|
</
span
>
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleShowShareModal
(
record
)
}
>
分享
...
...
@@ -250,40 +249,40 @@ class VideoCourseList extends React.Component {
<
Dropdown
overlay=
{
this
.
renderMoreOperate
(
record
)
}
>
<
span
className=
'more-operate'
>
<
span
className=
'operate-text'
>
更多
</
span
>
<
span
className=
'iconfont icon'
style=
{
{
color
:
"#2966FF"
}
}
>
<
span
className=
'iconfont icon'
style=
{
{
color
:
'#2966FF'
}
}
>

</
span
>
</
span
>
</
Dropdown
>
</
div
>
)
}
}
]
)
;
}
,
}
,
]
;
type
!==
"internal"
&&
columns
.
splice
(
2
,
1
)
return
columns
}
type
!==
'internal'
&&
columns
.
splice
(
2
,
1
);
return
columns
;
}
;
renderMoreOperate
=
(
item
)
=>
{
const
{
type
}
=
this
.
props
const
{
type
}
=
this
.
props
;
return
(
<
div
className=
'live-course-more-menu'
>
<
If
condition=
{
type
!==
"internal"
}
>
<
If
condition=
{
type
!==
'internal'
}
>
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleShowShareModal
(
item
)
}
>
分享
</
div
>
</
If
>
{
(
User
.
getUserRole
()
===
"CloudManager"
||
User
.
getUserRole
()
===
"StoreManager"
)
&&
(
{
(
User
.
getUserRole
()
===
'CloudManager'
||
User
.
getUserRole
()
===
'StoreManager'
)
&&
(
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleRelatedModalShow
(
item
)
}
>
关联培训计划
</
div
>
)
}
<
If
condition=
{
type
===
"internal"
}
>
<
If
condition=
{
type
===
'internal'
}
>
<
div
className=
'operate__item'
onClick=
{
()
=>
{
window
.
RCHistory
.
push
(
`/create-video-course?type=edit&id=${item.id}`
)
window
.
RCHistory
.
push
(
`/create-video-course?type=edit&id=${item.id}`
)
;
}
}
>
编辑
</
div
>
...
...
@@ -292,77 +291,77 @@ class VideoCourseList extends React.Component {
</
div
>
</
If
>
</
div
>
)
}
)
;
}
;
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
""
let
planStr
=
''
;
planArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
planArray
.
length
-
1
)
{
planStr
=
planStr
+
item
.
planName
+
"、"
planStr
=
planStr
+
item
.
planName
+
'、'
;
}
else
{
planStr
=
planStr
+
item
.
planName
planStr
=
planStr
+
item
.
planName
;
}
})
return
planStr
}
})
;
return
planStr
;
}
;
//改变上架状态
changeShelfState
=
(
checked
,
item
,
index
)
=>
{
let
_shelfState
=
checked
?
"YES"
:
"NO"
let
_shelfState
=
checked
?
'YES'
:
'NO'
;
if
(
checked
)
{
_shelfState
=
"YES"
_shelfState
=
'YES'
;
}
else
{
_shelfState
=
"NO"
_shelfState
=
'NO'
;
}
const
params
=
{
courseId
:
item
.
id
,
shelfState
:
_shelfState
}
shelfState
:
_shelfState
,
}
;
CourseService
.
changeVideoShelfState
(
params
).
then
(()
=>
{
if
(
_shelfState
===
"YES"
)
{
message
.
success
(
"已开启展示"
)
if
(
_shelfState
===
'YES'
)
{
message
.
success
(
'已开启展示'
);
}
else
{
message
.
success
(
"已取消展示"
)
message
.
success
(
'已取消展示'
);
}
this
.
props
.
changeShelfState
(
index
,
_shelfState
)
})
}
this
.
props
.
changeShelfState
(
index
,
_shelfState
)
;
})
;
}
;
// 删除视频课
handleDeleteVideoCourse
=
(
scheduleId
)
=>
{
Modal
.
confirm
({
title
:
"你确定要删除此视频课吗?"
,
content
:
"删除后,学员将不能进行观看。"
,
title
:
'你确定要删除此视频课吗?'
,
content
:
'删除后,学员将不能进行观看。'
,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
okText
:
"确定"
,
okType
:
"danger"
,
cancelText
:
"取消"
,
okText
:
'确定'
,
okType
:
'danger'
,
cancelText
:
'取消'
,
onOk
:
()
=>
{
const
param
=
{
courseId
:
scheduleId
,
storeId
:
User
.
getStoreId
()
}
storeId
:
User
.
getStoreId
()
,
}
;
CourseService
.
delVideoSchedule
(
param
).
then
(()
=>
{
message
.
success
(
"删除成功"
)
this
.
props
.
onChange
()
})
}
})
}
message
.
success
(
'删除成功'
);
this
.
props
.
onChange
()
;
})
;
}
,
})
;
}
;
// 显示分享弹窗
handleShowShareModal
=
(
record
,
needStr
=
false
)
=>
{
const
{
type
}
=
this
.
props
const
{
id
,
scheduleVideoUrl
}
=
record
const
htmlUrl
=
`
${
LIVE_SHARE
}
video_detail/
${
id
}
?id=
${
User
.
getStoreId
()}
`
const
longUrl
=
htmlUrl
const
{
coverUrl
,
courseName
}
=
record
const
{
type
}
=
this
.
props
;
const
{
id
,
scheduleVideoUrl
}
=
record
;
const
htmlUrl
=
`
${
LIVE_SHARE
}
video_detail/
${
id
}
?id=
${
User
.
getStoreId
()}
`
;
const
longUrl
=
htmlUrl
;
const
{
coverUrl
,
courseName
}
=
record
;
const
shareData
=
{
longUrl
,
coverUrl
,
scheduleVideoUrl
,
courseName
}
courseName
,
}
;
const
shareLiveModal
=
(
<
ShareLiveModal
...
...
@@ -373,95 +372,109 @@ class VideoCourseList extends React.Component {
title=
'视频课'
close=
{
()
=>
{
this
.
setState
({
shareLiveModal
:
null
})
localStorage
.
setItem
(
"videoCourseItem"
,
""
)
shareLiveModal
:
null
,
})
;
localStorage
.
setItem
(
'videoCourseItem'
,
''
);
}
}
/>
)
)
;
this
.
setState
({
shareLiveModal
})
}
this
.
setState
({
shareLiveModal
})
;
}
;
handleChangeTable
=
(
pagination
,
filters
,
sorter
)
=>
{
const
{
columnKey
,
order
}
=
sorter
const
{
query
}
=
this
.
props
let
{
order
:
_order
}
=
query
const
{
columnKey
,
order
}
=
sorter
;
const
{
query
}
=
this
.
props
;
let
{
order
:
_order
}
=
query
;
// 按创建时间升序排序
if
(
columnKey
===
"created"
&&
order
===
"ascend"
)
{
_order
=
"CREATED_ASC"
if
(
columnKey
===
'created'
&&
order
===
'ascend'
)
{
_order
=
'CREATED_ASC'
;
}
// 按创建时间降序排序
if
(
columnKey
===
"created"
&&
order
===
"descend"
)
{
_order
=
"CREATED_DESC"
if
(
columnKey
===
'created'
&&
order
===
'descend'
)
{
_order
=
'CREATED_DESC'
;
}
// 按更新时间升序排序
if
(
columnKey
===
"updated"
&&
order
===
"ascend"
)
{
_order
=
"UPDATED_ASC"
if
(
columnKey
===
'updated'
&&
order
===
'ascend'
)
{
_order
=
'UPDATED_ASC'
;
}
// 按更新时间降序排序
if
(
columnKey
===
"updated"
&&
order
===
"descend"
)
{
_order
=
"UPDATED_DESC"
if
(
columnKey
===
'updated'
&&
order
===
'descend'
)
{
_order
=
'UPDATED_DESC'
;
}
const
_query
=
{
...
query
,
orderEnum
:
_order
}
this
.
props
.
onChange
(
_query
)
}
orderEnum
:
_order
,
}
;
this
.
props
.
onChange
(
_query
)
;
}
;
handleRelatedModalShow
=
(
item
)
=>
{
const
selectPlanList
=
{}
const
selectPlanList
=
{}
;
if
(
item
.
relatedPlanList
)
{
item
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
selectPlanList
[
item
.
planId
]
=
{}
selectPlanList
[
item
.
planId
].
planId
=
item
.
planId
selectPlanList
[
item
.
planId
].
taskBaseVOList
=
[{
taskId
:
item
.
taskId
}]
return
item
})
selectPlanList
[
item
.
planId
]
=
{}
;
selectPlanList
[
item
.
planId
].
planId
=
item
.
planId
;
selectPlanList
[
item
.
planId
].
taskBaseVOList
=
[{
taskId
:
item
.
taskId
}]
;
return
item
;
})
;
}
this
.
setState
({
RelatedPlanModalVisible
:
true
,
selectCourseId
:
item
.
id
,
selectPlanList
:
selectPlanList
})
}
selectPlanList
:
selectPlanList
,
})
;
}
;
closeRelatedPlanModalVisible
=
()
=>
{
this
.
setState
({
RelatedPlanModalVisible
:
false
})
}
RelatedPlanModalVisible
:
false
,
})
;
}
;
onChangeSelectPlanList
=
(
selectPlanList
)
=>
{
this
.
setState
({
selectPlanList
:
selectPlanList
})
}
selectPlanList
:
selectPlanList
,
})
;
}
;
onConfirmSelectPlanList
=
()
=>
{
this
.
setState
(
{
RelatedPlanModalVisible
:
false
RelatedPlanModalVisible
:
false
,
},
()
=>
{
this
.
props
.
onChange
()
this
.
props
.
onChange
()
;
}
)
}
)
;
}
;
render
()
{
const
{
dataSource
=
[],
totalCount
,
query
,
type
}
=
this
.
props
const
{
current
,
size
}
=
query
const
{
RelatedPlanModalVisible
,
selectPlanList
,
selectCourseId
}
=
this
.
state
const
{
dataSource
=
[],
totalCount
,
query
,
type
}
=
this
.
props
;
const
{
current
,
size
}
=
query
;
const
{
RelatedPlanModalVisible
,
selectPlanList
,
selectCourseId
}
=
this
.
state
;
return
(
<
div
className=
{
`video-course-list ${type !== "internal" ? "video-course-list-mt" : ""}`
}
>
<
Table
<
div
className=
{
`video-course-list ${type !== 'internal' ? 'video-course-list-mt' : ''}`
}
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
id
}
dataSource=
{
dataSource
}
columns=
{
this
.
parseColumns
()
}
onChange=
{
this
.
handleChangeTable
}
pagination=
{
false
}
scroll=
{
{
x
:
1500
}
}
bordered
scroll=
{
{
x
:
1500
}
}
className=
'video-list-table'
/>
{
/* <Table
rowKey={(record) => record.id}
dataSource={dataSource}
columns={this.parseColumns()}
onChange={this.handleChangeTable}
pagination={false}
scroll={{ x: 1500 }}
bordered
className='video-list-table'
/> */
}
<
div
className=
'box-footer'
>
<
PageControl
...
...
@@ -469,8 +482,8 @@ class VideoCourseList extends React.Component {
pageSize=
{
size
}
total=
{
totalCount
}
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
query
,
current
:
page
+
1
}
this
.
props
.
onChange
(
_query
)
const
_query
=
{
...
query
,
current
:
page
+
1
}
;
this
.
props
.
onChange
(
_query
)
;
}
}
/>
</
div
>
...
...
@@ -487,8 +500,8 @@ class VideoCourseList extends React.Component {
{
this
.
state
.
shareLiveModal
}
{
this
.
state
.
watchDataModal
}
</
div
>
)
)
;
}
}
export
default
VideoCourseList
export
default
VideoCourseList
;
src/modules/course-manage/video-course/modal/WatchDataModal.jsx
View file @
510254f6
/*
* @Author: 吴文洁
* @Date: 2020-05-19 11:01:31
* @Author: 吴文洁
* @Date: 2020-05-19 11:01:31
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-05-25 16:50:47
* @Description 余额异常弹窗
*/
import
User
from
'@/common/js/user'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
{
Input
,
Modal
}
from
'antd'
;
import
college
from
'@/common/lottie/college'
;
import
React
from
'react'
;
import
{
Table
,
Modal
,
Input
}
from
'antd'
;
import
{
PageControl
}
from
"@/components"
;
import
CourseService
from
"@/domains/course-domain/CourseService"
;
import
User
from
'@/common/js/user'
import
dealTimeDuration
from
'../../utils/dealTimeDuration'
;
import
'./WatchDataModal.less'
;
import
dealTimeDuration
from
"../../utils/dealTimeDuration"
;
const
{
Search
}
=
Input
;
class
WatchDataModal
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
visible
:
true
,
dataSource
:[],
size
:
10
,
visible
:
true
,
dataSource
:
[],
size
:
10
,
query
:
{
current
:
1
,
},
totalCount
:
0
totalCount
:
0
,
};
}
componentDidMount
()
{
this
.
handleFetchDataList
();
}
onClose
=
()
=>
{
onClose
=
()
=>
{
this
.
props
.
close
();
}
}
;
// 获取观看视频数据列表
// 获取观看视频数据列表
handleFetchDataList
=
()
=>
{
const
{
query
,
size
,
totalCount
}
=
this
.
state
const
{
query
,
size
,
totalCount
}
=
this
.
state
;
const
{
id
}
=
this
.
props
.
data
;
const
params
=
{
const
params
=
{
...
query
,
size
,
courseId
:
id
,
storeId
:
User
.
getStoreId
()
}
courseId
:
id
,
storeId
:
User
.
getStoreId
(),
}
;
CourseService
.
videoWatchInfo
(
params
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
result
=
{}
}
=
res
;
const
{
records
=
[],
total
=
0
}
=
result
;
this
.
setState
({
dataSource
:
records
,
totalCount
:
Number
(
total
)
totalCount
:
Number
(
total
)
,
});
});
}
handleChangNickname
=
(
value
)
=>
{
}
;
handleChangNickname
=
(
value
)
=>
{
const
isPhone
=
(
value
||
''
).
match
(
/^
\d
+$/
);
const
{
query
}
=
this
.
state
;
if
(
isPhone
)
{
const
{
query
}
=
this
.
state
;
if
(
isPhone
)
{
query
.
phone
=
value
;
query
.
nickName
=
null
;
}
else
{
}
else
{
query
.
nickName
=
value
;
query
.
phone
=
null
;
}
query
.
current
=
1
;
this
.
setState
({
query
})
}
query
,
})
;
}
;
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
return
return
;
}
this
.
setState
({
size
},()
=>
{
this
.
handleFetchDataList
()})
}
this
.
setState
(
{
size
,
},
()
=>
{
this
.
handleFetchDataList
();
}
);
};
// 请求表头
parseColumns
=
()
=>
{
...
...
@@ -86,84 +92,102 @@ class WatchDataModal extends React.Component {
{
title
:
'观看学员'
,
key
:
'name'
,
dataIndex
:
'name'
dataIndex
:
'name'
,
},
{
title
:
'手机号'
,
key
:
'phone'
,
dataIndex
:
'phone'
dataIndex
:
'phone'
,
},
{
title
:
'观看者类型'
,
key
:
'userRole'
,
dataIndex
:
'userRole'
dataIndex
:
'userRole'
,
},
{
title
:
'首次观看时间'
,
key
:
'firstWatch'
,
dataIndex
:
'firstWatch'
,
render
:
(
val
)
=>
{
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
;
}
,
},
{
title
:
'观看时长'
,
key
:
'watchDuration'
,
dataIndex
:
'watchDuration'
,
render
:
(
val
)
=>
{
return
<
span
>
{
val
?
dealTimeDuration
(
val
)
:
"00:00:00"
}
</
span
>
}
}
return
<
span
>
{
val
?
dealTimeDuration
(
val
)
:
'00:00:00'
}
</
span
>;
}
,
}
,
];
return
columns
;
}
}
;
render
()
{
const
{
visible
,
size
,
dataSource
,
totalCount
,
query
}
=
this
.
state
;
const
{
visible
,
size
,
dataSource
,
totalCount
,
query
}
=
this
.
state
;
return
(
<
Modal
title=
"视频课观看数据"
visible=
{
visible
}
footer=
{
null
}
onCancel=
{
this
.
onClose
}
maskClosable=
{
false
}
className=
"watch-data-modal"
closable=
{
true
}
width=
{
800
}
closeIcon=
{
<
span
className=
"icon iconfont modal-close-icon"
>

</
span
>
}
>
<
div
className=
"search-container"
>
<
Search
placeholder=
"搜索学员姓名/手机号"
style=
{
{
width
:
200
}
}
onChange=
{
(
e
)
=>
{
this
.
handleChangNickname
(
e
.
target
.
value
)}
}
onSearch=
{
()
=>
{
this
.
handleFetchDataList
()}
}
enterButton=
{
<
span
className=
"icon iconfont"
>

</
span
>
}
/>
</
div
>
<
div
>
<
Table
rowKey=
{
record
=>
record
.
id
}
dataSource=
{
dataSource
}
columns=
{
this
.
parseColumns
()
}
pagination=
{
false
}
bordered
/>
{
dataSource
.
length
>
0
&&
<
div
className=
"box-footer"
>
<
PageControl
current=
{
query
.
current
-
1
}
pageSize=
{
size
}
total=
{
totalCount
}
size=
"small"
toPage=
{
(
page
)
=>
{
const
_query
=
{...
query
,
current
:
page
+
1
};
this
.
setState
({
query
:
_query
},()
=>
{
this
.
handleFetchDataList
()})
}
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
/>
</
div
>
}
</
div
>
</
Modal
>
)
<
Modal
title=
'视频课观看数据'
visible=
{
visible
}
footer=
{
null
}
onCancel=
{
this
.
onClose
}
maskClosable=
{
false
}
className=
'watch-data-modal'
closable=
{
true
}
width=
{
800
}
closeIcon=
{
<
span
className=
'icon iconfont modal-close-icon'
>

</
span
>
}
>
<
div
className=
'search-container'
>
<
Search
placeholder=
'搜索学员姓名/手机号'
style=
{
{
width
:
200
}
}
onChange=
{
(
e
)
=>
{
this
.
handleChangNickname
(
e
.
target
.
value
);
}
}
onSearch=
{
()
=>
{
this
.
handleFetchDataList
();
}
}
enterButton=
{
<
span
className=
'icon iconfont'
>

</
span
>
}
/>
</
div
>
<
div
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
id
}
dataSource=
{
dataSource
}
columns=
{
this
.
parseColumns
()
}
pagination=
{
false
}
bordered
/>
{
dataSource
.
length
>
0
&&
(
<
div
className=
'box-footer'
>
<
PageControl
current=
{
query
.
current
-
1
}
pageSize=
{
size
}
total=
{
totalCount
}
size=
'small'
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
setState
(
{
query
:
_query
,
},
()
=>
{
this
.
handleFetchDataList
();
}
);
}
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
/>
</
div
>
)
}
</
div
>
</
Modal
>
);
}
}
export
default
WatchDataModal
;
\ No newline at end of file
export
default
WatchDataModal
;
src/modules/root/Menu.tsx
View file @
510254f6
import
React
,
{
Key
,
useContext
,
useEffect
,
useRef
,
useState
,
useMemo
}
from
'react'
;
import
{
withRouter
,
}
from
'react-router-dom'
;
import
User
from
'@/common/js/user'
;
import
StoreService
from
'@/domains/store-domain/storeService'
;
import
{
Menu
}
from
'antd'
;
import
{
menuList
}
from
'../../routes//config/menuList'
import
{
XMContext
}
from
'../../store/context'
;
import
Service
from
"@/common/js/service"
;
import
StoreService
from
"@/domains/store-domain/storeService"
;
import
User
from
"@/common/js/user"
;
import
React
,
{
Key
,
useContext
,
useEffect
,
useMemo
,
useState
}
from
'react'
;
import
{
withRouter
}
from
'react-router-dom'
;
import
_
from
'underscore'
;
import
"./Menu.less"
;
import
{
menuList
}
from
'../../routes//config/menuList'
;
import
{
XMContext
}
from
'../../store/context'
;
import
'./Menu.less'
;
const
{
SubMenu
}
=
Menu
;
function
Aside
(
props
:
any
)
{
const
{
menuType
,
handleMenuType
}
=
props
const
{
menuType
,
handleMenuType
}
=
props
;
const
ctx
:
any
=
useContext
(
XMContext
);
const
[
selectKey
,
setSelectKey
]
=
useState
();
const
[
selectKeyParent
,
setSelectKeyParent
]
=
useState
();
const
[
openKeys
,
setOpenKeys
]
=
useState
([
''
]);
const
[
topLogoUrl
,
setTopLogoUrl
]
=
useState
(
""
)
const
[
collapsed
,
setCollapsed
]
=
useState
(
false
)
const
[
topLogoUrl
,
setTopLogoUrl
]
=
useState
(
''
);
const
[
collapsed
,
setCollapsed
]
=
useState
(
false
)
;
const
rootSubmenuKeys
=
_
.
pluck
(
menuList
,
'groupCode'
);
useEffect
(()
=>
{
...
...
@@ -26,44 +24,46 @@ function Aside(props: any) {
menuList
.
map
((
item
:
any
,
index
:
any
)
=>
{
if
(
link
.
indexOf
(
item
.
link
)
!==
-
1
)
{
setSelectKey
(
item
.
groupCode
);
setOpenKeys
([])
setSelectKeyParent
(
item
.
groupCode
);
setOpenKeys
([]);
}
else
if
(
item
.
children
)
{
item
.
children
.
map
((
_item
:
any
,
_index
:
any
)
=>
{
if
(
link
.
indexOf
(
_item
.
link
)
!==
-
1
)
{
setSelectKeyParent
(
item
.
groupCode
);
setSelectKey
(
_item
.
groupCode
+
index
+
_index
);
}
})
})
;
}
return
item
;
})
},
[
props
.
location
.
pathname
])
})
;
},
[
props
.
location
.
pathname
])
;
useEffect
(()
=>
{
getTopLeftLogo
()
},
[])
getTopLeftLogo
()
;
},
[])
;
function
getTopLeftLogo
()
{
if
(
User
.
getToken
())
{
StoreService
.
getStoreDetail
({
storeId
:
User
.
getStoreId
()
})
.
then
(
res
=>
{
if
(
_
.
isEmpty
(
res
.
result
.
logo
))
{
setTopLogoUrl
(
"https://image.xiaomaiketang.com/xm/fe4NCjr7XF.png"
)
}
else
{
setTopLogoUrl
(
res
.
result
.
logo
)
}
})
StoreService
.
getStoreDetail
({
storeId
:
User
.
getStoreId
()
}).
then
((
res
)
=>
{
if
(
_
.
isEmpty
(
res
.
result
.
logo
))
{
setTopLogoUrl
(
'https://image.xiaomaiketang.com/xm/fe4NCjr7XF.png'
);
}
else
{
setTopLogoUrl
(
res
.
result
.
logo
);
}
});
}
}
function
toggleMenu
(
item
:
any
)
{
window
.
RCHistory
.
push
(
item
.
link
)
function
toggleMenu
(
item
:
any
,
selectKey
:
any
)
{
console
.
log
(
'item'
,
item
,
selectKey
);
setSelectKeyParent
(
selectKey
);
window
.
RCHistory
.
push
(
item
.
link
);
if
(
!
menuType
)
{
setOpenKeys
([])
setOpenKeys
([])
;
}
}
function
onOpenChange
(
key
:
Key
[])
{
if
(
typeof
key
===
"string"
)
{
if
(
typeof
key
===
'string'
)
{
if
(
openKeys
.
includes
(
key
))
{
setOpenKeys
([]);
}
else
{
...
...
@@ -74,9 +74,9 @@ function Aside(props: any) {
function
onOpenChangeForHover
(
key
:
Key
[])
{
if
(
menuType
)
{
return
return
;
}
if
(
typeof
key
===
"string"
)
{
if
(
typeof
key
===
'string'
)
{
if
(
openKeys
.
includes
(
key
))
{
setOpenKeys
([]);
}
else
{
...
...
@@ -87,94 +87,78 @@ function Aside(props: any) {
function
handleMenu
()
{
handleMenuType
();
setCollapsed
(
!
collapsed
)
setCollapsed
(
!
collapsed
)
;
}
const
openKeysConstrol
=
useMemo
(()
=>
{
return
{
[
menuType
?
'openKeys'
:
'defaultOpenKeys'
]:
openKeys
[
menuType
?
'openKeys'
:
'defaultOpenKeys'
]:
openKeys
,
};
},
[
menuType
,
openKeys
])
},
[
menuType
,
openKeys
])
;
return
(
<
div
id=
"left-container"
className=
{
menuType
?
"left-container"
:
"left-container left-container-vertical"
}
>
<
div
className=
"top-ctrl"
>
<
div
className=
"topLogo"
>
{
menuType
&&
<
img
src=
{
topLogoUrl
}
alt=
""
className=
"img1"
></
img
>
}
</
div
>
<
div
className=
"menu-type-icon"
onClick=
{
handleMenu
}
>
{
menuType
?
(
<
span
className=
"icon iconfont"
>

</
span
>
)
:
(
<
span
className=
"icon iconfont"
>

</
span
>
)
}
<
div
id=
'left-container'
className=
{
menuType
?
'left-container'
:
'left-container left-container-vertical'
}
>
<
div
className=
'top-ctrl'
>
<
div
className=
'topLogo'
>
{
menuType
&&
<
img
src=
{
topLogoUrl
}
alt=
''
className=
'img1'
></
img
>
}
</
div
>
<
div
className=
'menu-type-icon'
onClick=
{
handleMenu
}
>
{
menuType
?
<
span
className=
'icon iconfont'
>

</
span
>
:
<
span
className=
'icon iconfont'
>

</
span
>
}
</
div
>
</
div
>
<
div
className=
"left"
>
<
div
className=
"nav"
>
<
div
className=
'left'
>
<
div
className=
'nav'
>
<
Menu
{
...
openKeysConstrol
}
style=
{
menuType
?
{
minHeight
:
"100%"
,
background
:
'#0E1935'
}
:
{
minHeight
:
"100%"
,
background
:
'#0E1935'
,
width
:
"56px"
}
}
style=
{
menuType
?
{
minHeight
:
'100%'
,
background
:
'#0E1935'
}
:
{
minHeight
:
'100%'
,
background
:
'#0E1935'
,
width
:
'56px'
}
}
selectedKeys=
{
selectKey
}
onOpenChange=
{
onOpenChange
}
inlineCollapsed=
{
collapsed
}
mode=
{
menuType
?
"inline"
:
"vertical"
}
>
{
menuList
.
map
((
item
:
any
,
index
:
any
)
=>
{
if
(
ctx
.
xmState
.
storeUserPermissionList
.
indexOf
(
item
.
groupCode
)
===
-
1
)
{
return
null
;
}
if
(
item
.
children
)
{
return
<
SubMenu
mode=
{
menuType
?
'inline'
:
'vertical'
}
>
{
menuList
.
map
((
item
:
any
,
index
:
any
)
=>
{
if
(
ctx
.
xmState
.
storeUserPermissionList
.
indexOf
(
item
.
groupCode
)
===
-
1
)
{
return
null
;
}
// console.log('selectKe===>', selectKey);
// console.log('item===>', item);
if
(
item
.
children
)
{
return
(
<
SubMenu
key=
{
item
.
groupCode
}
style=
{
{
marginTop
:
0
}
}
icon=
{
<
img
src=
{
item
.
img
}
className=
"icon-img"
></
img
>
}
title=
{
menuType
?
<
span
>
{
item
.
groupName
}
</
span
>
:
""
}
onTitleClick=
{
()
=>
onOpenChange
(
item
.
groupCode
)
}
>
{
item
.
children
.
map
((
_item
:
any
,
_index
:
any
)
=>
{
if
(
ctx
.
xmState
.
storeUserPermissionList
.
indexOf
(
_item
.
groupCode
)
===
-
1
)
{
return
null
;
}
return
<
Menu
.
Item
onClick=
{
()
=>
{
toggleMenu
(
_item
)
}
}
style=
{
{
marginTop
:
0
}
}
key=
{
_item
.
groupCode
+
index
+
_index
}
>
<
span
className=
"name"
>
{
_item
.
groupName
}
</
span
>
style=
{
{
marginTop
:
0
,
backgroundColor
:
!
menuType
&&
item
.
groupCode
===
selectKeyParent
?
'#2966FF'
:
'#fff'
}
}
icon=
{
<
img
src=
{
item
.
img
}
className=
'icon-img'
></
img
>
}
title=
{
menuType
?
<
span
>
{
item
.
groupName
}
</
span
>
:
''
}
onTitleClick=
{
()
=>
onOpenChange
(
item
.
groupCode
)
}
>
{
item
.
children
.
map
((
_item
:
any
,
_index
:
any
)
=>
{
if
(
ctx
.
xmState
.
storeUserPermissionList
.
indexOf
(
_item
.
groupCode
)
===
-
1
)
{
return
null
;
}
return
(
<
Menu
.
Item
onClick=
{
()
=>
{
toggleMenu
(
_item
,
item
.
groupCode
);
}
}
style=
{
{
marginTop
:
0
}
}
key=
{
_item
.
groupCode
+
index
+
_index
}
>
<
span
className=
'name'
>
{
_item
.
groupName
}
</
span
>
</
Menu
.
Item
>
})
}
);
})
}
</
SubMenu
>
}
else
{
return
<
Menu
.
Item
onClick=
{
()
=>
{
toggleMenu
(
item
)
}
}
);
}
else
{
return
(
<
Menu
.
Item
onClick=
{
()
=>
{
toggleMenu
(
item
,
item
.
groupCode
);
}
}
key=
{
item
.
groupCode
}
icon=
{
<
img
src=
{
selectKey
===
item
.
groupCode
?
item
.
selectImg
:
item
.
img
}
className=
"icon-img"
></
img
>
}
>
{
menuType
?
item
.
groupName
:
""
}
icon=
{
<
img
src=
{
selectKey
===
item
.
groupCode
?
item
.
selectImg
:
item
.
img
}
className=
'icon-img'
></
img
>
}
>
{
menuType
?
item
.
groupName
:
''
}
</
Menu
.
Item
>
}
}
)
}
);
}
}
)
}
</
Menu
>
</
div
>
</
div
>
...
...
@@ -182,4 +166,4 @@ function Aside(props: any) {
);
}
export
default
withRouter
(
Aside
);
\ No newline at end of file
export
default
withRouter
(
Aside
);
src/routes/config/menuList.tsx
View file @
510254f6
...
...
@@ -8,142 +8,142 @@
*/
export
const
menuList
:
any
=
[
{
groupName
:
"中心首页"
,
groupCode
:
"CloudPage"
,
groupName
:
'中心首页'
,
groupCode
:
'CloudPage'
,
icon
:
''
,
link
:
'/home'
,
img
:
'https://image.xiaomaiketang.com/xm/ni3BFJDT3a.png'
,
selectImg
:
'https://image.xiaomaiketang.com/xm/GRDztTAWaM.png'
img
:
'https://image.xiaomaiketang.com/xm/ni3BFJDT3a.png'
,
selectImg
:
'https://image.xiaomaiketang.com/xm/GRDztTAWaM.png'
,
},
{
groupName
:
"课程管理"
,
groupCode
:
"CloudCourse"
,
groupName
:
'课程管理'
,
groupCode
:
'CloudCourse'
,
icon
:
''
,
img
:
'https://image.xiaomaiketang.com/xm/jBGrGjM7HQ.png'
,
img
:
'https://image.xiaomaiketang.com/xm/jBGrGjM7HQ.png'
,
children
:
[
{
groupName
:
"直播课"
,
groupCode
:
"CourseLiveClass"
,
link
:
'/live-course'
groupName
:
'直播课'
,
groupCode
:
'CourseLiveClass'
,
link
:
'/live-course'
,
},
{
groupName
:
"视频课"
,
groupCode
:
"CourseVideoClass"
,
link
:
'/video-course'
groupName
:
'视频课'
,
groupCode
:
'CourseVideoClass'
,
link
:
'/video-course'
,
},
{
groupName
:
"图文课"
,
groupCode
:
"GraphicLesson"
,
link
:
'/graphics-course'
groupName
:
'图文课'
,
groupCode
:
'GraphicLesson'
,
link
:
'/graphics-course'
,
},
{
groupName
:
"线下课"
,
groupCode
:
"OfflineClass"
,
link
:
'/offline-course'
groupName
:
'线下课'
,
groupCode
:
'OfflineClass'
,
link
:
'/offline-course'
,
},
]
]
,
},
{
groupName
:
"培训管理"
,
groupCode
:
"TrainManage"
,
groupName
:
'培训管理'
,
groupCode
:
'TrainManage'
,
icon
:
''
,
img
:
'https://image.xiaomaiketang.com/xm/Yy6pZ6G6kS.png'
,
img
:
'https://image.xiaomaiketang.com/xm/Yy6pZ6G6kS.png'
,
children
:
[
{
groupName
:
"培训计划"
,
groupCode
:
"TrainPlan"
,
link
:
'/plan'
}
groupName
:
'培训计划'
,
groupCode
:
'TrainPlan'
,
link
:
'/plan'
,
}
,
],
},
{
groupName
:
"助学工具"
,
groupCode
:
"AidTool"
,
groupName
:
'助学工具'
,
groupCode
:
'AidTool'
,
icon
:
''
,
img
:
'https://image.xiaomaiketang.com/xm/xsma4hx3b3.png'
,
img
:
'https://image.xiaomaiketang.com/xm/xsma4hx3b3.png'
,
children
:
[
{
groupName
:
"题库"
,
groupCode
:
"QuestionBank"
,
link
:
'/question-manage-index'
groupName
:
'题库'
,
groupCode
:
'QuestionBank'
,
link
:
'/question-manage-index'
,
},
{
groupName
:
"试卷"
,
groupCode
:
"ExamPaper"
,
link
:
'/paper-manage-index'
groupName
:
'试卷'
,
groupCode
:
'ExamPaper'
,
link
:
'/paper-manage-index'
,
},
{
groupName
:
"考试"
,
groupCode
:
"CloudExam"
,
link
:
'/examination-manage-index'
groupName
:
'考试'
,
groupCode
:
'CloudExam'
,
link
:
'/examination-manage-index'
,
},
]
]
,
},
{
groupName
:
"知识库"
,
groupCode
:
"CloudKnowledge"
,
groupName
:
'知识库'
,
groupCode
:
'CloudKnowledge'
,
icon
:
''
,
link
:
'/knowledge-base'
,
img
:
'https://image.xiaomaiketang.com/xm/8sbP5rGQWh.png'
,
selectImg
:
'https://image.xiaomaiketang.com/xm/hJKCfibC22.png'
img
:
'https://image.xiaomaiketang.com/xm/8sbP5rGQWh.png'
,
selectImg
:
'https://image.xiaomaiketang.com/xm/hJKCfibC22.png'
,
},
{
groupName
:
"资料云盘"
,
groupCode
:
"CloudDisk"
,
groupName
:
'资料云盘'
,
groupCode
:
'CloudDisk'
,
icon
:
''
,
link
:
'/resource-disk'
,
img
:
'https://image.xiaomaiketang.com/xm/zGKbXJPzXx.png'
,
selectImg
:
'https://image.xiaomaiketang.com/xm/5sN4MzjxYc.png'
,
img
:
'https://image.xiaomaiketang.com/xm/zGKbXJPzXx.png'
,
selectImg
:
'https://image.xiaomaiketang.com/xm/5sN4MzjxYc.png'
,
},
{
groupName
:
"人员管理"
,
groupCode
:
"PersonManage"
,
groupName
:
'人员管理'
,
groupCode
:
'PersonManage'
,
icon
:
''
,
img
:
'https://image.xiaomaiketang.com/xm/PRCnrt35y8.png'
,
img
:
'https://image.xiaomaiketang.com/xm/PRCnrt35y8.png'
,
children
:
[
{
groupName
:
"员工管理"
,
groupCode
:
"ShopStaff"
,
link
:
'/college-employee'
groupName
:
'员工管理'
,
groupCode
:
'ShopStaff'
,
link
:
'/college-employee'
,
},
{
groupName
:
"学员管理"
,
groupCode
:
"ShopUser"
,
link
:
'/college-user'
}
]
groupName
:
'学员管理'
,
groupCode
:
'ShopUser'
,
link
:
'/college-user'
,
}
,
]
,
},
{
groupName
:
"学院管理"
,
groupCode
:
"CloudShop"
,
groupName
:
'学院管理'
,
groupCode
:
'CloudShop'
,
icon
:
''
,
img
:
'https://image.xiaomaiketang.com/xm/Q8i5RSMKNc.png'
,
img
:
'https://image.xiaomaiketang.com/xm/Q8i5RSMKNc.png'
,
children
:
[
{
groupName
:
"学院信息"
,
groupCode
:
"ShopInfo"
,
link
:
'/college-info'
groupName
:
'学院信息'
,
groupCode
:
'ShopInfo'
,
link
:
'/college-info'
,
},
{
groupName
:
"学院装修"
,
groupCode
:
"ShopDecoration"
,
link
:
'/store-decoration'
groupName
:
'学院装修'
,
groupCode
:
'ShopDecoration'
,
link
:
'/store-decoration'
,
},
{
groupName
:
"分类管理"
,
groupCode
:
"CourseCategory"
,
link
:
'/course-category-manage'
groupName
:
'分类管理'
,
groupCode
:
'CourseCategory'
,
link
:
'/course-category-manage'
,
},
{
groupName
:
"H5学院"
,
groupCode
:
"ShopDecorationH5"
,
link
:
'/store-decoration/h5'
groupName
:
'H5学院'
,
groupCode
:
'ShopDecorationH5'
,
link
:
'/store-decoration/h5'
,
},
{
groupName
:
"网页端学院"
,
groupCode
:
"ShopDecorationWeb"
,
link
:
'/store-decoration/web'
}
]
groupName
:
'网页端学院'
,
groupCode
:
'ShopDecorationWeb'
,
link
:
'/store-decoration/web'
,
}
,
]
,
},
]
\ No newline at end of file
];
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