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
e64090ea
Commit
e64090ea
authored
May 12, 2021
by
chenshu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:初始化
parent
6a5d8f97
Show whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
508 additions
and
242 deletions
+508
-242
src/h5.html
+1
-1
src/index.html
+1
-1
src/modules/course-manage/modal/ShareLiveModal.jsx
+2
-2
src/modules/course-manage/offline-course/AddOfflineCourse.jsx
+1
-0
src/modules/course-manage/offline-course/OfflineCourseData.jsx
+219
-0
src/modules/course-manage/offline-course/OfflineCourseData.less
+132
-0
src/modules/course-manage/offline-course/components/OfflineCourseList.jsx
+59
-53
src/modules/course-manage/offline-course/modal/PreviewModal.jsx
+32
-0
src/modules/course-manage/offline-course/modal/PreviewModal.less
+4
-0
src/modules/course-manage/offline-course/modal/QRCodeModal.jsx
+44
-0
src/modules/course-manage/offline-course/modal/QRCodeModal.less
+13
-0
src/modules/course-manage/offline-course/modal/WatchDataModal.jsx
+0
-178
src/modules/course-manage/offline-course/modal/WatchDataModal.less
+0
-7
No files found.
src/h5.html
View file @
e64090ea
...
...
@@ -25,7 +25,7 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link
rel=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
boiin24pch6
.css"
>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
e0vkqcd8igi
.css"
>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
...
...
src/index.html
View file @
e64090ea
...
...
@@ -25,7 +25,7 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link
rel=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
boiin24pch6
.css"
>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
e0vkqcd8igi
.css"
>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
...
...
src/modules/course-manage/modal/ShareLiveModal.jsx
View file @
e64090ea
...
...
@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-07-20 19:12:49
* @Last Modified by: chenshu
* @Last Modified time: 2021-0
3-16 17:41:40
* @Last Modified time: 2021-0
5-11 12:00:05
* @Description: 大班直播分享弹窗
*/
...
...
@@ -139,7 +139,7 @@ class ShareLiveModal extends React.Component {
let
coverImgSrc
=
coverUrl
;
if
(
type
===
'videoClass'
){
if
((
!
coverUrl
||
isDefaultCover
)
&&
title
!==
'图文课'
){
if
((
!
coverUrl
||
isDefaultCover
)
&&
title
!==
'图文课'
&&
title
!=
'线下课'
){
coverImgSrc
=
`
${
scheduleVideoUrl
}
?x-oss-process=video/snapshot,t_0,m_fast&anystring=anystring`
}
}
else
{
...
...
src/modules/course-manage/offline-course/AddOfflineCourse.jsx
View file @
e64090ea
...
...
@@ -840,6 +840,7 @@ class AddOfflineCourse extends React.Component {
<
GraphicsEditor
id=
"intro"
isIntro=
{
true
}
maxLimit=
{
1000
}
detail=
{
{
content
:
introduce
}
}
...
...
src/modules/course-manage/offline-course/OfflineCourseData.jsx
0 → 100644
View file @
e64090ea
import
React
from
'react'
;
import
{
Tooltip
,
Input
,
Radio
,
Table
}
from
'antd'
;
import
moment
from
'moment'
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
PageControl
from
'@/components/PageControl'
;
import
Service
from
"@/common/js/service"
;
import
'./OfflineCourseData.less'
;
const
{
Search
}
=
Input
;
export
default
class
OfflineCourseData
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
courseId
:
window
.
getParameterByName
(
'id'
),
query
:
{
size
:
10
,
current
:
1
,
},
loading
:
false
,
data
:
[],
total
:
0
,
courseName
:
''
,
calendarTime
:
[],
fullJoin
:
0
,
}
}
componentDidMount
()
{
this
.
getOfflineBasic
();
this
.
getOfflineCalendar
();
}
getOfflineBasic
=
()
=>
{
const
{
courseId
}
=
this
.
state
;
Service
.
Hades
(
'public/hades/getOfflineCourseJoinBase'
,
{
courseId
}).
then
((
res
)
=>
{
if
(
res
.
success
)
{
const
{
result
}
=
res
;
this
.
setState
({
courseName
:
result
.
courseName
,
fullJoin
:
result
.
fullJoin
,
});
}
})
}
getOfflineCalendar
=
()
=>
{
const
{
courseId
}
=
this
.
state
;
Service
.
Hades
(
'public/customerHades/offlineDateList'
,
{
courseId
}).
then
((
res
)
=>
{
if
(
res
.
success
)
{
console
.
log
(
result
.
calendarTime
,
_
.
groupBy
(
result
.
calendarTime
,
item
=>
moment
(
item
).
format
(
'YYYY-MM'
)),
1111111
)
this
.
setState
({
calendarTime
:
_
.
pluck
(
res
.
result
,
'date'
),
})
}
});
}
getColumns
=
()
=>
{
const
columns
=
[
{
title
:
'用户姓名'
,
key
:
'name'
,
dataIndex
:
'name'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
record
.
name
}
</
div
>
)
}
},
{
title
:
"手机号"
,
key
:
"teacher"
,
dataIndex
:
"teacher"
,
render
:
(
val
,
item
)
=>
{
return
(
<
div
>
{
item
.
teacherName
}
</
div
>
)
},
},
{
title
:
'报名时间'
,
key
:
'updated'
,
dataIndex
:
'updated'
,
render
:
(
val
,
item
)
=>
{
return
item
.
startTimeApply
?
`
${
formatDate
(
'MM-DD H:i'
,
item
.
startTimeApply
)}
~
${
formatDate
(
'MM-DD H:i'
,
item
.
endTimeApply
)}
`
:
'-'
}
},
{
title
:
'签到时间'
,
key
:
'signIn'
,
dataIndex
:
'signIn'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
},
{
title
:
'签退时间'
,
key
:
'signOut'
,
dataIndex
:
'signOut'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
},
];
return
columns
;
}
handleChangeTable
=
()
=>
{
}
render
()
{
const
{
query
,
loading
,
data
,
total
,
courseName
,
fullJoin
,
}
=
this
.
state
;
return
(
<
div
className=
"page offline-course-data"
>
<
Breadcrumbs
navList=
"参与数据"
goBack=
{
()
=>
{
window
.
RCHistory
.
goBack
();
}
}
/>
<
div
className=
"box"
>
<
div
className=
"offline-name"
>
课程名称:
{
courseName
}
</
div
>
<
div
className=
"offline-application"
>
报名总人数:100
</
div
>
<
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=
"icon-box"
>
<
span
className=
"icon iconfont"
>

</
span
>
</
div
>
<
div
className=
"calendar-text"
>
2021年5月
</
div
>
<
div
className=
"icon-box"
>
<
span
className=
"icon iconfont"
>

</
span
>
</
div
>
</
div
>
<
div
className=
"date-list"
>
<
div
className=
"date-item"
>
5月1日(周五)
</
div
>
</
div
>
</
div
>
<
div
className=
"right-box"
>
<
div
className=
"selected-date"
>
5月1日
</
div
>
<
div
className=
"detail-data"
>
<
span
className=
"icon iconfont"
>

</
span
>
<
span
className=
"data-text"
>
报名人数:100
</
span
>
<
span
className=
"icon iconfont"
>

</
span
>
<
span
className=
"data-text"
>
完成考勤数
<
Tooltip
title=
"当日在规定时间内完成签到和签退的用户数"
><
span
className=
"icon iconfont"
>

</
span
></
Tooltip
>
:99
</
span
>
<
span
className=
"icon iconfont"
>

</
span
>
<
span
className=
"data-text"
>
签到人数:99
</
span
>
<
span
className=
"icon iconfont"
>

</
span
>
<
span
className=
"data-text"
>
签退人数:99
</
span
>
</
div
>
<
div
className=
"detail-filter"
>
<
Search
className=
"search-input"
placeholder=
"搜索用户姓名/手机号"
style=
{
{
width
:
200
,
marginRight
:
24
}
}
enterButton=
{
<
span
className=
"icon iconfont"
>

</
span
>
}
/>
<
div
className=
"filter-box"
>
<
span
className=
"label"
>
签到情况:
</
span
>
<
Radio
.
Group
defaultValue=
"YES"
>
<
Radio
value=
"YES"
>
已签到
</
Radio
>
<
Radio
value=
"NO"
>
未签到
</
Radio
>
</
Radio
.
Group
>
</
div
>
<
div
className=
"filter-box"
>
<
span
className=
"label"
>
签退情况:
</
span
>
<
Radio
.
Group
defaultValue=
"YES"
>
<
Radio
value=
"YES"
>
已签退
</
Radio
>
<
Radio
value=
"NO"
>
未签退
</
Radio
>
</
Radio
.
Group
>
</
div
>
</
div
>
<
Table
bordered
size=
"middle"
pagination=
{
false
}
columns=
{
this
.
getColumns
()
}
loading=
{
loading
}
dataSource=
{
data
}
onChange=
{
this
.
handleChangeTable
}
rowKey=
{
(
row
)
=>
row
.
liveCourseId
}
/>
<
PageControl
current=
{
query
.
current
}
pageSize=
{
query
.
size
}
total=
{
total
}
toPage=
{
(
page
)
=>
{
const
queryStates
=
_
.
clone
(
query
);
queryStates
.
current
=
page
;
this
.
setState
({
query
:
queryStates
});
}
}
/>
</
div
>
</
div
>
</
div
>
)
}
}
\ No newline at end of file
src/modules/course-manage/offline-course/OfflineCourseData.less
0 → 100644
View file @
e64090ea
.offline-course-data {
min-width: 1100px;
.box {
.offline-name {
font-size: 19px;
color: #333;
line-height: 26px;
font-weight: 500;
padding-left: 8px;
position: relative;
&::after {
position: absolute;
width: 4px;
height: 16px;
content: '';
background: #FFB714;
left: 0;
top: 5px;
}
}
.offline-application {
color: #333;
font-size: 14px;
line-height: 20px;
margin-top: 8px;
.iconfont {
color: #BFBFBF;
font-size: 14px;
margin: 0 4px;
}
}
}
.data-box {
padding: 16px 0 !important;
display: flex;
.left-box {
width: 260px;
border-right: 1px solid #EEEEEE;
.left-title {
color: #000;
font-size: 16px;
font-weight: 500;
line-height: 22px;
padding-left: 8px;
padding-bottom: 16px;
margin: 0 8px;
border-bottom: 1px solid #E8E8E8;
}
.left-calendar {
margin-top: 16px;
margin-left: 20px;
display: flex;
align-items: center;
.icon-box {
width: 32px;
height: 32px;
border-radius: 4px;
border: 1px solid #E8E8E8;
display: flex;
align-items: center;
justify-content: center;
color: #BFBFBF;
cursor: pointer;
.iconfont {
font-size: 12px;
}
}
.calendar-text {
color: #FF9D14;
line-height: 20px;
margin: 0 44px;
}
}
.date-list {
width: 100%;
margin-top: 16px;
.date-item {
height: 44px;
width: 100%;
display: flex;
padding: 12px 32px;
color: #666;
&:hover {
background: #F3F6FA;
cursor: pointer;
}
}
}
}
.right-box {
padding: 0 16px;
width: ~'calc(100% - 261px)';
.selected-date {
font-size: 16px;
color: #333;
line-height: 22px;
font-weight: 500;
}
.detail-data {
display: flex;
margin-top: 10px;
align-items: center;
.iconfont {
font-size: 15px;
color: #999999;
margin-right: 6px;
}
.data-text {
color: #333;
font-size: 14px;
line-height: 20px;
margin-right: 24px;
.iconfont {
font-size: 14px;
color: #BFBFBF;
margin: 0 4px;
}
}
}
.detail-filter {
display: flex;
margin-top: 16px;
margin-bottom: 16px;
align-items: center;
.filter-box {
margin-right: 36px;
}
}
}
}
}
\ No newline at end of file
src/modules/course-manage/offline-course/components/OfflineCourseList.jsx
View file @
e64090ea
...
...
@@ -8,14 +8,12 @@
*/
import
React
from
'react'
;
import
{
Table
,
Modal
,
message
,
Tooltip
,
Switch
,
Dropdown
}
from
'antd'
;
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
{
PageControl
}
from
"@/components"
;
import
{
LIVE_SHARE_MAP
}
from
'@/common/constants/academic/cloudClass'
;
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
WatchDataModal
from
'../modal/WatchDataModal'
import
Service
from
"@/common/js/service"
;
import
CourseService
from
"@/domains/course-domain/CourseService"
;
import
RelatedPlanModal
from
'../../modal/RelatedPlanModal'
;
...
...
@@ -25,6 +23,7 @@ import User from '@/common/js/user'
import
'./OfflineCourseList.less'
;
import
moment
from
'moment'
;
import
QRCodeModal
from
'../modal/QRCodeModal'
;
const
ENV
=
process
.
env
.
DEPLOY_ENV
||
'dev'
;
const
defaultCoverUrl
=
'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png'
;
...
...
@@ -49,22 +48,6 @@ class OfflineCourseList extends React.Component {
}
}
// 观看数据弹窗
handleShowWatchDataModal
=
(
record
)
=>
{
const
watchDataModal
=
(
<
WatchDataModal
type=
'videoCourseList'
data=
{
record
}
close=
{
()
=>
{
this
.
setState
({
watchDataModal
:
null
});
}
}
/>
);
this
.
setState
({
watchDataModal
});
}
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
""
;
planArray
.
map
((
item
,
index
)
=>
{
...
...
@@ -181,7 +164,7 @@ class OfflineCourseList extends React.Component {
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"operate"
>
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
handleShowWatchDataModal
(
record
)
}
>
参与数据
</
div
>
<
div
className=
"operate__item"
onClick=
{
()
=>
window
.
RCHistory
.
push
(
`/offline-course/data?id=${record.courseId}`
)
}
>
参与数据
</
div
>
<
span
className=
"operate__item split"
>
|
</
span
>
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
handleShowShareModal
(
record
)
}
>
分享
</
div
>
<
span
className=
"operate__item split"
>
|
</
span
>
...
...
@@ -243,15 +226,27 @@ class OfflineCourseList extends React.Component {
renderMoreOperate
=
(
item
)
=>
{
return
(
<
div
className=
"live-course-more-menu"
>
{
(
User
.
getUserRole
()
===
"CloudManager"
||
User
.
getUserRole
()
===
"StoreManager"
)
&&
<
div
className=
"operate__item"
key=
"plan
"
key=
"qrcode
"
onClick=
{
()
=>
{
this
.
handleRelatedModalShow
(
item
);
this
.
setState
({
openQRCodeModal
:
true
})
}
}
>
关联培训计划
</
div
>
}
>
考勤二维码
</
div
>
<
div
className=
"operate__item"
key=
"preview"
onClick=
{
()
=>
{
this
.
setState
({
openQRCodeModal
:
true
})
}
}
>
预览
</
div
>
<
div
className=
"operate__item"
key=
"cancel"
onClick=
{
()
=>
{
this
.
handleDeleteOfflineCourse
(
item
.
courseId
);
}
}
>
取消课程
</
div
>
<
div
className=
"operate__item"
key=
"edit"
...
...
@@ -262,7 +257,7 @@ class OfflineCourseList extends React.Component {
<
div
className=
"operate__item"
key=
"delete"
onClick=
{
()
=>
this
.
handleDeleteOfflineCourse
(
item
.
courseId
)
}
onClick=
{
()
=>
this
.
handleDeleteOfflineCourse
(
item
.
courseId
,
true
)
}
>
删除
</
div
>
</
div
>
)
...
...
@@ -292,43 +287,58 @@ class OfflineCourseList extends React.Component {
})
}
// 删除视频课
handleDeleteOfflineCourse
=
(
scheduleId
)
=>
{
handleDeleteOfflineCourse
=
(
courseId
,
isDelete
)
=>
{
if
(
isDelete
)
{
Modal
.
confirm
({
title
:
'你确定要删除此视频课吗?
'
,
content
:
'删除后,学员将不能进行观看
。'
,
title
:
'删除课程
'
,
content
:
'确定删除该学员吗?删除后用户数据和课程数据将无法恢复
。'
,
icon
:
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>,
okText
:
'确定'
,
okType
:
'danger'
,
cancelText
:
'取消'
,
onOk
:
()
=>
{
const
param
=
{
courseId
:
scheduleId
,
storeId
:
User
.
getStoreId
()
courseId
:
courseId
,
}
CourseService
.
delVideoSchedule
(
param
).
then
(()
=>
{
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
>,
okText
:
'确定'
,
cancelText
:
'取消'
,
onOk
:
()
=>
{
const
param
=
{
courseId
:
courseId
,
}
Service
.
Hades
(
'public/hades/cancelOfflineCourse'
,
param
).
then
(()
=>
{
message
.
success
(
'取消成功'
);
this
.
props
.
onChange
();
})
}
});
}
}
// 显示分享弹窗
handleShowShareModal
=
(
record
,
needStr
=
false
)
=>
{
const
{
id
,
scheduleVideoUrl
}
=
record
;
const
{
courseId
}
=
record
;
const
_appId
=
appId
;
const
htmlUrl
=
`
${
LIVE_SHARE
}
graphics_detail/
${
i
d
}
?id=
${
User
.
getStoreId
()}
`
;
const
htmlUrl
=
`
${
LIVE_SHARE
}
offline_detail/
${
courseI
d
}
?id=
${
User
.
getStoreId
()}
`
;
const
longUrl
=
htmlUrl
;
const
{
coverUrl
,
courseName
}
=
record
;
const
shareData
=
{
longUrl
,
coverUrl
,
scheduleVideoUrl
,
courseName
,
};
...
...
@@ -401,8 +411,8 @@ class OfflineCourseList extends React.Component {
},()
=>
{
this
.
props
.
onChange
();})
}
render
()
{
const
{
RelatedPlanModalVisible
,
selectCourseId
,
selectPlanList
}
=
this
.
state
;
const
{
dataSource
=
[],
totalCount
,
query
}
=
this
.
props
;
const
{
RelatedPlanModalVisible
,
selectCourseId
,
selectPlanList
,
openQRCodeModal
}
=
this
.
state
;
const
{
dataSource
=
[],
totalCount
,
query
,
match
}
=
this
.
props
;
const
{
current
,
size
}
=
query
;
return
(
<
div
className=
"offline-course-list"
>
...
...
@@ -438,21 +448,17 @@ class OfflineCourseList extends React.Component {
onConfirm=
{
this
.
onConfirmSelectPlanList
}
/>
}
{
RelatedPlanModalVisible
&&
<
RelatedPlanModal
onClose=
{
this
.
closeRelatedPlanModalVisible
}
visible=
{
RelatedPlanModalVisible
}
selectCourseId=
{
selectCourseId
}
selectPlanList=
{
selectPlanList
}
onChange=
{
this
.
onChangeSelectPlanList
}
onConfirm=
{
this
.
onConfirmSelectPlanList
}
{
this
.
state
.
shareLiveModal
}
<
QRCodeModal
visible=
{
openQRCodeModal
}
onCancel=
{
()
=>
{
this
.
setState
({
openQRCodeModal
:
false
})
}
}
/>
}
{
this
.
state
.
shareLiveModal
}
{
this
.
state
.
watchDataModal
}
<
Route
path=
{
`${match.url}/data`
}
component=
{
OfflineCourseData
}
/>
</
div
>
)
}
}
export
default
OfflineCourseList
;
export
default
withRouter
(
OfflineCourseList
)
;
src/modules/course-manage/offline-course/modal/PreviewModal.jsx
0 → 100644
View file @
e64090ea
import
React
from
'react'
;
import
{
Button
,
Modal
,
Select
}
from
'antd'
;
import
'./PreviewModal.less'
;
const
{
Option
}
=
Select
;
export
default
class
PreviewModal
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
}
render
()
{
const
{
visible
,
onCancel
}
=
this
.
props
;
return
(
<
Modal
title=
"预览"
width=
{
680
}
visible=
{
visible
}
footer=
{
null
}
onCancel=
{
()
=>
onCancel
()
}
className=
"offline-preview-modal"
>
<
div
className=
"image-box"
>
<
img
src=
"https://image.xiaomaiketang.com/xm/xYSpX2y6ri.png"
className=
"image"
/>
</
div
>
</
Modal
>
)
}
}
\ No newline at end of file
src/modules/course-manage/offline-course/modal/PreviewModal.less
0 → 100644
View file @
e64090ea
.offline-preview-modal {
}
\ No newline at end of file
src/modules/course-manage/offline-course/modal/QRCodeModal.jsx
0 → 100644
View file @
e64090ea
import
React
from
'react'
;
import
{
Button
,
Modal
,
Select
}
from
'antd'
;
import
'./QRCodeModal.less'
;
const
{
Option
}
=
Select
;
export
default
class
QRCodeModal
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
}
render
()
{
const
{
visible
,
onCancel
}
=
this
.
props
;
return
(
<
Modal
title=
"考勤二维码"
width=
{
560
}
visible=
{
visible
}
footer=
{
<
Button
onClick=
{
()
=>
onCancel
()
}
>
关闭
</
Button
>
}
onCancel=
{
()
=>
onCancel
()
}
className=
"offline-qrcode-modal"
>
<
div
>
<
Select
style=
{
{
width
:
200
}
}
placeholder=
"请选择"
>
</
Select
>
<
Button
type=
"primary"
style=
{
{
marginLeft
:
8
}
}
>
下载二维码
</
Button
>
</
div
>
<
div
className=
"image-box"
>
<
img
src=
"https://image.xiaomaiketang.com/xm/xYSpX2y6ri.png"
className=
"image"
/>
</
div
>
</
Modal
>
)
}
}
\ No newline at end of file
src/modules/course-manage/offline-course/modal/QRCodeModal.less
0 → 100644
View file @
e64090ea
.offline-qrcode-modal {
.image-box {
margin: 16px auto 0;
width: 380px;
height: 350px;
.image {
width: 100%;
height: 100%;
object-fit: cover;
}
}
}
\ No newline at end of file
src/modules/course-manage/offline-course/modal/WatchDataModal.jsx
deleted
100644 → 0
View file @
6a5d8f97
/*
* @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
'./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
,
query
:
{
current
:
1
,
},
totalCount
:
0
};
}
componentDidMount
()
{
this
.
handleFetchDataList
();
}
onClose
=
()
=>
{
this
.
props
.
close
();
}
// 获取观看视频数据列表
handleFetchDataList
=
()
=>
{
const
{
query
,
size
,
totalCount
}
=
this
.
state
const
{
id
}
=
this
.
props
.
data
;
const
params
=
{
...
query
,
size
,
courseId
:
id
,
storeId
:
User
.
getStoreId
()
}
Service
.
Hades
(
'public/hades/mediaCourseWatchInfo'
,
params
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
records
=
[],
total
=
0
}
=
result
;
this
.
setState
({
dataSource
:
records
,
totalCount
:
Number
(
total
)
});
});
}
handleChangNickname
=
(
value
)
=>
{
const
isPhone
=
(
value
||
''
).
match
(
/^
\d
+$/
);
const
{
query
}
=
this
.
state
;
if
(
isPhone
){
query
.
phone
=
value
;
query
.
nickName
=
null
;
}
else
{
query
.
nickName
=
value
;
query
.
phone
=
null
;
}
query
.
current
=
1
;
this
.
setState
({
query
})
}
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
return
}
this
.
setState
({
size
},()
=>
{
this
.
handleFetchDataList
()})
}
// 请求表头
parseColumns
=
()
=>
{
const
columns
=
[
{
title
:
'观看用户'
,
key
:
'name'
,
dataIndex
:
'name'
},
{
title
:
'手机号'
,
key
:
'phone'
,
dataIndex
:
'phone'
},
{
title
:
'观看者类型'
,
key
:
'userRole'
,
dataIndex
:
'userRole'
},
{
title
:
'首次观看时间'
,
key
:
'firstWatch'
,
dataIndex
:
'firstWatch'
,
render
:
(
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
>
}
},
{
title
:
'学习进度'
,
key
:
'progress'
,
dataIndex
:
'progress'
,
render
:
(
val
)
=>
{
return
<
span
>
{
val
===
100
?
'已完成'
:
`${val || 0}%`
}
</
span
>
}
}
];
return
columns
;
}
render
()
{
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
>
)
}
}
export
default
WatchDataModal
;
\ No newline at end of file
src/modules/course-manage/offline-course/modal/WatchDataModal.less
deleted
100644 → 0
View file @
6a5d8f97
.watch-data-modal{
.search-container{
text-align:right;
margin-bottom:17px;
}
}
\ 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