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
1bf6cc7a
Commit
1bf6cc7a
authored
Jul 13, 2021
by
guomingpang
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
style:表格中的滑动开关使用small 型号
parent
7b685e7a
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
1434 additions
and
1351 deletions
+1434
-1351
src/modules/course-manage/components/LiveCourseList.jsx
+2
-1
src/modules/course-manage/graphics-course/components/GraphicsCourseList.jsx
+47
-41
src/modules/course-manage/offline-course/AddOfflineCourse.jsx
+592
-538
src/modules/course-manage/offline-course/components/AddGraphicsIntro.jsx
+92
-93
src/modules/course-manage/offline-course/components/OfflineCourseList.jsx
+8
-5
src/modules/course-manage/video-course/components/AddVideoIntro.jsx
+100
-104
src/modules/course-manage/video-course/components/VideoCourseList.jsx
+1
-0
src/modules/plan-manage/components/BasicInfo.jsx
+14
-8
src/modules/plan-manage/components/PlanList.jsx
+1
-0
src/modules/teach-tool/examination-manager/AddExam.tsx
+513
-475
src/routes/index.tsx
+64
-86
No files found.
src/modules/course-manage/components/LiveCourseList.jsx
View file @
1bf6cc7a
...
...
@@ -125,7 +125,7 @@ class LiveCourseList extends React.Component {
columns
=
[
{
title
:
'直播课'
,
width
:
'23%'
,
key
:
'course'
,
fixed
:
'left'
,
dataIndex
:
'courseName'
,
...
...
@@ -284,6 +284,7 @@ class LiveCourseList extends React.Component {
render
:
(
val
,
item
,
index
)
=>
{
return
(
<
Switch
size=
'small'
checked=
{
item
.
shelfState
===
'YES'
}
defaultChecked=
{
item
.
shelfState
===
'YES'
?
true
:
false
}
onChange=
{
(
checked
)
=>
this
.
changeShelfState
(
index
,
item
,
checked
)
}
...
...
src/modules/course-manage/graphics-course/components/GraphicsCourseList.jsx
View file @
1bf6cc7a
...
...
@@ -9,7 +9,7 @@
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
{
LIVE_SHARE
}
from
'@/domains/course-domain/constants'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
ShareLiveModal
from
'@/modules/course-manage/modal/ShareLiveModal'
;
import
{
Dropdown
,
message
,
Modal
,
Switch
,
Tooltip
}
from
'antd'
;
...
...
@@ -57,7 +57,7 @@ class GraphicsCourseList extends React.Component {
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
''
;
planArray
.
map
((
item
,
index
)
=>
{
planArray
.
forEach
((
item
,
index
)
=>
{
if
(
index
<
planArray
.
length
-
1
)
{
planStr
=
planStr
+
item
.
planName
+
'、'
;
}
else
{
...
...
@@ -76,18 +76,21 @@ class GraphicsCourseList extends React.Component {
width
:
321
,
fixed
:
'left'
,
render
:
(
val
,
record
)
=>
{
const
{
coverUrl
,
scheduleVideoUrl
}
=
record
;
const
{
coverUrl
}
=
record
;
return
(
<
div
className=
'record__item'
>
{
/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */
}
<
img
className=
'course-cover'
src=
{
coverUrl
||
defaultCoverUrl
}
/>
{
record
.
courseName
.
length
>
25
?
(
<
Tooltip
title=
{
record
.
courseName
}
>
<
img
className=
'course-cover'
src=
{
coverUrl
||
defaultCoverUrl
}
alt=
''
/>
<
Choose
>
<
When
condition=
{
record
.
courseName
.
length
>
25
}
>
<
Tooltip
title=
{
record
.
courseName
}
>
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
</
Tooltip
>
</
When
>
<
Otherwise
>
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
</
Tooltip
>
)
:
(
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
)
}
</
Otherwise
>
</
Choose
>
</
div
>
);
},
...
...
@@ -144,12 +147,14 @@ class GraphicsCourseList extends React.Component {
width
:
120
,
dataIndex
:
'courseware'
,
render
:
(
val
,
item
,
index
)
=>
{
return
(
<
Switch
checked=
{
item
.
shelfState
===
"YES"
}
defaultChecked=
{
item
.
shelfState
===
"YES"
?
true
:
false
}
onChange=
{
(
checked
)
=>
this
.
changeShelfState
(
index
,
item
,
checked
)
}
/>
)
return
(
<
Switch
size=
'small'
checked=
{
item
.
shelfState
===
'YES'
}
defaultChecked=
{
item
.
shelfState
===
'YES'
?
true
:
false
}
onChange=
{
(
checked
)
=>
this
.
changeShelfState
(
index
,
item
,
checked
)
}
/>
);
},
},
{
...
...
@@ -168,7 +173,7 @@ class GraphicsCourseList extends React.Component {
dataIndex
:
'created'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
);
return
window
.
formatDate
(
'YYYY-MM-DD H:i'
,
val
);
},
},
{
...
...
@@ -178,7 +183,7 @@ class GraphicsCourseList extends React.Component {
dataIndex
:
'updated'
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
formatDate
(
'YYYY-MM-DD H:i'
,
val
);
return
window
.
formatDate
(
'YYYY-MM-DD H:i'
,
val
);
},
},
{
...
...
@@ -189,19 +194,22 @@ class GraphicsCourseList extends React.Component {
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
>
)
}
<
Choose
>
<
When
condition=
{
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
>
</
When
>
<
Otherwise
>
<
span
></
span
>
</
Otherwise
>
</
Choose
>
</
div
>
);
},
...
...
@@ -297,7 +305,7 @@ class GraphicsCourseList extends React.Component {
className=
'operate__item'
key=
'edit'
onClick=
{
()
=>
{
RCHistory
.
push
(
`/create-graphics-course?type=edit&id=${item.id}`
);
window
.
RCHistory
.
push
(
`/create-graphics-course?type=edit&id=${item.id}`
);
}
}
>
编辑
</
div
>
...
...
@@ -305,17 +313,17 @@ class GraphicsCourseList extends React.Component {
删除
</
div
>
</
div
>
)
}
//改变上架状态
changeShelfState
=
(
index
,
item
,
checked
)
=>
{
let
_shelfState
=
checked
?
"YES"
:
"NO"
)
;
}
;
//改变上架状态
changeShelfState
=
(
index
,
item
,
checked
)
=>
{
let
_shelfState
=
checked
?
'YES'
:
'NO'
;
// if(_shelfState==='NO'){
// _shelfState = "YES";
// }else{
// _shelfState = "NO"
// }
const
params
=
{
const
params
=
{
courseId
:
item
.
id
,
shelfState
:
_shelfState
,
};
...
...
@@ -326,7 +334,7 @@ class GraphicsCourseList extends React.Component {
}
else
{
message
.
success
(
'已取消展示'
);
}
this
.
props
.
changeShelfState
(
index
,
_shelfState
)
this
.
props
.
changeShelfState
(
index
,
_shelfState
);
}
});
};
...
...
@@ -355,8 +363,6 @@ class GraphicsCourseList extends React.Component {
// 显示分享弹窗
handleShowShareModal
=
(
record
,
needStr
=
false
)
=>
{
const
{
id
,
scheduleVideoUrl
}
=
record
;
const
_appId
=
appId
;
const
htmlUrl
=
`
${
LIVE_SHARE
}
graphics_detail/
${
id
}
?id=
${
User
.
getStoreId
()}
`
;
const
longUrl
=
htmlUrl
;
const
{
coverUrl
,
courseName
}
=
record
;
...
...
src/modules/course-manage/offline-course/AddOfflineCourse.jsx
View file @
1bf6cc7a
...
...
@@ -8,80 +8,65 @@
*/
import
React
from
'react'
;
import
{
Button
,
Input
,
Radio
,
message
,
Modal
,
TreeSelect
,
Select
,
Switch
,
TimePicker
,
InputNumber
,
Tooltip
,
}
from
'antd'
;
import
{
Button
,
Input
,
Radio
,
message
,
Modal
,
TreeSelect
,
Select
,
Switch
,
TimePicker
,
InputNumber
,
Tooltip
}
from
'antd'
;
import
$
from
'jquery'
;
import
RangePicker
from
"@/modules/common/DateRangePicker"
;
import
ShowTips
from
"@/components/ShowTips"
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
SelectStudent
from
'../modal/select-student'
;
import
Bus
from
'@/core/bus'
;
import
RangePicker
from
'@/modules/common/DateRangePicker'
;
import
ShowTips
from
'@/components/ShowTips'
;
import
Breadcrumbs
from
'@/components/Breadcrumbs'
;
import
SelectPrepareFileModal
from
'../../prepare-lesson/modal/SelectPrepareFileModal'
;
import
PreviewOfflineModal
from
'./modal/PreviewOfflineModal'
;
import
StoreService
from
"@/domains/store-domain/storeService"
;
import
StoreService
from
'@/domains/store-domain/storeService'
;
import
Service
from
'@/common/js/service'
;
import
{
randomString
}
from
'@/domains/basic-domain/utils'
;
import
User
from
'@/common/js/user'
;
import
_
from
"underscore"
;
import
_
from
'underscore'
;
import
moment
from
'moment'
;
import
Upload
from
'@/core/upload'
;
import
GraphicsEditor
from
'../components/GraphicsEditor'
;
import
MultipleDatePicker
from
'@/components/MultipleDatePicker'
;
import
ImgClipModal
from
'@/components/ImgClipModal'
import
ImgClipModal
from
'@/components/ImgClipModal'
;
import
'./AddOfflineCourse.less'
;
const
{
Option
}
=
Select
;
const
defaultCoverUrl
=
'https://image.xiaomaiketang.com/xm/pxbWKsYA87.png'
;
let
cutFlag
=
false
;
const
unitList
=
[
{
key
:
'HOUR'
,
value
:
'小时'
},
{
key
:
'MINUTE'
,
value
:
'分钟'
},
]
]
;
class
AddOfflineCourse
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
const
courseId
=
getParameterByName
(
"id"
);
const
pageType
=
getParameterByName
(
"type"
);
const
courseId
=
window
.
getParameterByName
(
'id'
);
const
pageType
=
window
.
getParameterByName
(
'type'
);
this
.
state
=
{
courseId
,
// 线下课ID,编辑的时候从URL上带过来
pageType
,
// 页面类型: add->新建 edit->编辑
imageFile
:
null
,
// 需要被截取的图片
courseName
:
null
,
// 线下课名称
courseId
,
// 线下课ID,编辑的时候从URL上带过来
pageType
,
// 页面类型: add->新建 edit->编辑
imageFile
:
null
,
// 需要被截取的图片
courseName
:
null
,
// 线下课名称
courseMedia
:
''
,
introduce
:
''
,
coverId
:
null
,
// 线下封面的recourceId
coverUrl
:
defaultCoverUrl
,
// 线下课封面
studentList
:
[],
// 上课学员列表
diskList
:
[],
// 机构可见磁盘目录
selectedFileList
:
[],
// 已经从资料云盘中勾选的文件
showCutModal
:
false
,
// 是否显示截图弹窗
coverId
:
null
,
// 线下封面的recourceId
coverUrl
:
defaultCoverUrl
,
// 线下课封面
studentList
:
[],
// 上课学员列表
diskList
:
[],
// 机构可见磁盘目录
selectedFileList
:
[],
// 已经从资料云盘中勾选的文件
showCutModal
:
false
,
// 是否显示截图弹窗
studentModal
:
false
,
categoryName
:
null
,
//分类名称
categoryName
:
null
,
//分类名称
categoryList
:
[],
courseCatalogList
:[],
//分类列表
categoryId
:
null
,
//分类的Id值
courseCatalogList
:
[],
//分类列表
categoryId
:
null
,
//分类的Id值
whetherVisitorsJoin
:
'NO'
,
// 是否允许游客加入
isContent
:
true
,
teacherList
:
[],
teacherQuery
:
{
size
:
15
,
current
:
1
,
nickName
:
null
nickName
:
null
,
},
calendarTime
:
[],
offlineCourseType
:
'ALL_DAY_OFFLINE'
,
...
...
@@ -101,7 +86,7 @@ class AddOfflineCourse extends React.Component {
isEditDisablie
:
false
,
startTime
:
new
Date
().
getTime
()
+
300000
,
// 批量开始时分
endTime
:
new
Date
().
getTime
()
+
300000
,
// 批量结束时分
}
}
;
}
componentWillMount
()
{
...
...
@@ -114,27 +99,27 @@ class AddOfflineCourse extends React.Component {
}
initBus
=
()
=>
{
Bus
.
bind
(
'offlineEditorImage'
,
this
.
uploadImage
)
}
Bus
.
bind
(
'offlineEditorImage'
,
this
.
uploadImage
)
;
}
;
removeBus
=
()
=>
{
Bus
.
unbind
(
'offlineEditorImage'
,
this
.
uploadImage
)
}
Bus
.
unbind
(
'offlineEditorImage'
,
this
.
uploadImage
)
;
}
;
uploadImage
=
()
=>
{
this
.
setState
({
showSelectImageModal
:
true
})
}
this
.
setState
({
showSelectImageModal
:
true
})
;
}
;
//获取分类列表
getCourseCatalogList
=
()
=>
{
getCourseCatalogList
=
()
=>
{
Service
.
Hades
(
'public/hades/queryCategoryTree'
,
{
source
:
0
,
tenantId
:
User
.
getStoreId
(),
count
:
false
,
userId
:
User
.
getUserId
()
}).
then
((
res
)
=>
{
const
{
categoryList
=
[]
}
=
res
.
result
;
this
.
setState
({
categoryList
,
courseCatalogList
:
this
.
renderTreeNodes
(
categoryList
),
})
})
;
});
}
}
;
renderTreeNodes
=
(
data
)
=>
{
let
newTreeData
=
data
.
map
((
item
)
=>
{
...
...
@@ -151,22 +136,21 @@ class AddOfflineCourse extends React.Component {
checkDetail
=
(
courseId
)
=>
{
return
Service
.
Hades
(
'public/hades/getOfflineCourseDetail'
,
{
courseId
courseId
,
}).
then
((
res
)
=>
{
const
{
courseState
}
=
res
.
result
;
return
courseState
===
'UN_START'
;
});
}
}
;
// 获取线下课详情
handleFetchScheudleDetail
=
(
courseId
)
=>
{
return
Service
.
Hades
(
'public/hades/getOfflineCourseDetail'
,{
courseId
return
Service
.
Hades
(
'public/hades/getOfflineCourseDetail'
,
{
courseId
,
}).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
||
{};
const
{
courseName
,
courseState
,
categoryId
,
offlinePlace
,
whetherVisitorsJoin
,
...
...
@@ -197,25 +181,25 @@ class AddOfflineCourse extends React.Component {
let
coverId
;
let
coverUrl
=
this
.
state
.
coverUrl
;
let
hasIntro
=
false
;
courseMediaVOS
.
map
((
item
)
=>
{
switch
(
item
.
contentType
){
case
"COVER"
:
switch
(
item
.
contentType
)
{
case
'COVER'
:
coverId
=
item
.
mediaContent
;
coverUrl
=
item
.
mediaUrl
;
break
;
case
"SCHEDULE"
:
break
;
case
'SCHEDULE'
:
this
.
getTextDetail
(
'courseMedia'
,
item
.
mediaUrl
);
break
;
case
"INTRO"
:
case
'INTRO'
:
hasIntro
=
true
;
this
.
getTextDetail
(
'introduce'
,
item
.
mediaUrl
);
break
;
break
;
default
:
break
;
}
return
item
;
})
})
;
this
.
setState
({
loadintroduce
:
!
hasIntro
,
coverId
,
...
...
@@ -248,50 +232,43 @@ class AddOfflineCourse extends React.Component {
signOutType
,
isEditDisablie
:
whetherHaveApply
===
'YES'
,
});
})
}
})
;
}
;
getTextDetail
=
(
key
,
url
)
=>
{
$
.
ajax
({
data
:
{},
type
:
'GET'
,
url
,
contentType
:
'application/x-www-form-urlencoded; charset=UTF-8'
,
contentType
:
'application/x-www-form-urlencoded; charset=UTF-8'
,
success
:
(
res
)
=>
{
this
.
setState
({
[
key
]:
res
,
[
`load
${
key
}
`
]:
true
});
}
})
}
}
,
})
;
}
;
handleGoBack
=
()
=>
{
const
{
coverId
,
videoName
,
videoDuration
,
courseName
,
categoryId
,
whetherVisitorsJoin
}
=
this
.
state
;
if
(
videoName
||
videoDuration
||
categoryId
||
courseName
||
coverId
||
whetherVisitorsJoin
!==
whetherVisitorsJoin
){
const
{
coverId
,
videoName
,
videoDuration
,
courseName
,
categoryId
,
whetherVisitorsJoin
}
=
this
.
state
;
if
(
videoName
||
videoDuration
||
categoryId
||
courseName
||
coverId
||
whetherVisitorsJoin
!==
whetherVisitorsJoin
)
{
Modal
.
confirm
({
title
:
'确认要返回吗?'
,
content
:
'返回后,本次编辑的内容将不被保存。'
,
okText
:
'确认返回'
,
cancelText
:
'留在本页'
,
icon
:
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
onOk
:
()
=>
{
window
.
RCHistory
.
push
({
pathname
:
`/offline-course`
,
});
}
}
,
});
}
else
{
}
else
{
window
.
RCHistory
.
push
({
pathname
:
`/offline-course`
,
});
}
}
}
;
// 显示预览弹窗
handleShowPreviewModal
=
()
=>
{
const
{
...
...
@@ -339,68 +316,69 @@ class AddOfflineCourse extends React.Component {
signOutStartTimeNum
,
signOutStartTimeUnit
,
signOutEndTimeNum
,
signOutEndTimeUnit
,
}
signOutEndTimeUnit
,
}
;
const
previewOfflineModal
=
(
<
PreviewOfflineModal
data=
{
data
}
close=
{
()
=>
{
this
.
setState
({
previewOfflineModal
:
null
})
previewOfflineModal
:
null
,
})
;
}
}
/>
);
this
.
setState
({
previewOfflineModal
});
}
}
;
handleSelectCover
=
(
file
)
=>
{
handleSelectCover
=
(
file
)
=>
{
this
.
setState
({
visible
:
true
,
imageFile
:
file
imageFile
:
file
,
});
}
};
//获取resourceId
getSignature
=
(
blob
,
fileName
)
=>
{
Upload
.
uploadBlobToOSS
(
blob
,
'cover'
+
(
new
Date
()).
valueOf
(),
null
,
'signInfo'
).
then
((
signInfo
)
=>
{
this
.
setState
({
coverClicpPath
:
signInfo
.
fileUrl
,
coverId
:
signInfo
.
resourceId
,
visible
:
false
},()
=>
this
.
updateCover
())
Upload
.
uploadBlobToOSS
(
blob
,
'cover'
+
new
Date
().
valueOf
(),
null
,
'signInfo'
).
then
((
signInfo
)
=>
{
this
.
setState
(
{
coverClicpPath
:
signInfo
.
fileUrl
,
coverId
:
signInfo
.
resourceId
,
visible
:
false
,
},
()
=>
this
.
updateCover
()
);
});
};
updateCover
=
()
=>
{
const
{
coverClicpPath
,
coverId
}
=
this
.
state
updateCover
=
()
=>
{
const
{
coverClicpPath
,
coverId
}
=
this
.
state
;
this
.
setState
({
showSelectCoverModal
:
false
,
coverUrl
:
coverClicpPath
,
coverId
:
coverId
})
}
coverUrl
:
coverClicpPath
,
coverId
:
coverId
,
})
;
}
;
preSubmit
=
()
=>
{
//过期判断
if
(
User
.
getExpirationTime
()
&&
moment
().
valueOf
()
>
Number
(
User
.
getExpirationTime
()))
{
Modal
.
warning
({
title
:
"服务已到期"
,
content
:
"当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买"
,
okText
:
"我知道了"
})
return
title
:
'服务已到期'
,
content
:
'当前企业购买的小麦企学院服务已到期,如需继续使用学院功能,请尽快续费购买'
,
okText
:
'我知道了'
,
})
;
return
;
}
const
{
courseId
}
=
this
.
state
;
if
(
courseId
)
{
this
.
checkDetail
(
courseId
).
then
(
bool
=>
bool
?
this
.
handleSubmit
()
:
message
.
warning
(
'课程已开始,无法继续编辑'
))
this
.
checkDetail
(
courseId
).
then
(
(
bool
)
=>
(
bool
?
this
.
handleSubmit
()
:
message
.
warning
(
'课程已开始,无法继续编辑'
)));
}
else
{
this
.
handleSubmit
();
}
}
}
;
// 保存
handleSubmit
=
()
=>
{
...
...
@@ -436,20 +414,20 @@ class AddOfflineCourse extends React.Component {
isMore
,
}
=
this
.
state
;
let
coverObj
=
{
contentType
:
'COVER'
,
let
coverObj
=
{
contentType
:
'COVER'
,
mediaContent
:
coverId
,
mediaType
:
'PICTURE'
,
mediaType
:
'PICTURE'
,
mediaUrl
:
coverUrl
,
}
}
;
let
scheduleMediaRequests
=
[];
if
(
coverId
)
{
scheduleMediaRequests
=
[
coverObj
]
if
(
coverId
)
{
scheduleMediaRequests
=
[
coverObj
]
;
}
// 编辑且使用默认图时不传
if
(
pageType
===
'edit'
&&
coverUrl
===
defaultCoverUrl
)
{
scheduleMediaRequests
=
[]
scheduleMediaRequests
=
[]
;
}
const
commonParams
=
{
categoryId
,
...
...
@@ -494,16 +472,21 @@ class AddOfflineCourse extends React.Component {
// 校验必填字段:课程名称, 课程线下
this
.
handleValidate
(
commonParams
).
then
((
res
)
=>
{
if
(
!
res
)
return
;
Upload
.
uploadTextToOSS
(
introduce
,
`
${
randomString
()}
.txt`
,
(
introduceId
)
=>
{
this
.
submitRemote
({
courseId
,
pageType
,
commonParams
,
introduceId
,
});
},
()
=>
message
.
warning
(
'上传课程简介失败'
));
Upload
.
uploadTextToOSS
(
introduce
,
`
${
randomString
()}
.txt`
,
(
introduceId
)
=>
{
this
.
submitRemote
({
courseId
,
pageType
,
commonParams
,
introduceId
,
});
},
()
=>
message
.
warning
(
'上传课程简介失败'
)
);
});
}
}
;
submitRemote
=
(
data
)
=>
{
const
{
courseId
,
pageType
,
commonParams
,
introduceId
}
=
data
;
...
...
@@ -511,65 +494,68 @@ class AddOfflineCourse extends React.Component {
if
(
pageType
===
'add'
)
{
Service
.
Hades
(
'public/hades/createOfflineCourse'
,
commonParams
).
then
((
res
)
=>
{
if
(
!
res
)
return
;
message
.
success
(
"新建成功"
);
message
.
success
(
'新建成功'
);
window
.
RCHistory
.
push
({
pathname
:
`/offline-course`
,
});
})
})
;
}
else
{
const
editParams
=
{
courseId
:
courseId
,
courseId
:
courseId
,
...
commonParams
,
}
}
;
Service
.
Hades
(
'public/hades/updateOfflineCourse'
,
editParams
).
then
((
res
)
=>
{
if
(
!
res
)
return
;
message
.
success
(
"保存成功"
);
message
.
success
(
'保存成功'
);
window
.
RCHistory
.
push
({
pathname
:
`/offline-course`
,
});
});
}
}
}
;
handleValidate
=
(
data
)
=>
{
return
new
Promise
((
resolve
)
=>
{
if
(
!
data
.
courseName
)
{
message
.
warning
(
'请输入课程名称'
);
resolve
(
false
);
}
else
if
(
!
data
.
categoryId
)
{
}
else
if
(
!
data
.
categoryId
)
{
message
.
warning
(
'请选择课程分类'
);
resolve
(
false
);
}
else
if
(
!
data
.
offlinePlace
)
{
}
else
if
(
!
data
.
offlinePlace
)
{
message
.
warning
(
'请输入上课地点'
);
resolve
(
false
);
}
else
if
(
!
data
.
teacherId
)
{
}
else
if
(
!
data
.
teacherId
)
{
message
.
warning
(
'请选择讲师'
);
resolve
(
false
);
}
else
if
(
_
.
isEmpty
(
data
.
calendarTime
))
{
}
else
if
(
_
.
isEmpty
(
data
.
calendarTime
))
{
message
.
warning
(
'请选择上课日期'
);
resolve
(
false
);
}
else
if
(
!
data
.
startTime
||
!
data
.
endTime
)
{
}
else
if
(
!
data
.
startTime
||
!
data
.
endTime
)
{
message
.
warning
(
'请选择上课时间'
);
resolve
(
false
);
}
else
if
(
moment
(
moment
(
data
.
calendarTime
[
0
]).
format
(
'YYYY-MM-DD'
)
+
moment
(
data
.
startTime
).
format
(
' HH:mm'
)).
valueOf
()
<
Date
.
now
())
{
}
else
if
(
moment
(
moment
(
data
.
calendarTime
[
0
]).
format
(
'YYYY-MM-DD'
)
+
moment
(
data
.
startTime
).
format
(
' HH:mm'
)).
valueOf
()
<
Date
.
now
())
{
message
.
warning
(
'上课时间不能早于现在'
);
resolve
(
false
);
}
else
if
(
data
.
startTime
>=
data
.
endTime
)
{
}
else
if
(
data
.
startTime
>=
data
.
endTime
)
{
message
.
warning
(
'上课结束时间不能早于上课开始时间'
);
resolve
(
false
);
}
else
if
(
data
.
whetherSetApply
===
'YES'
&&
!
data
.
startTimeApply
)
{
}
else
if
(
data
.
whetherSetApply
===
'YES'
&&
!
data
.
startTimeApply
)
{
message
.
warning
(
'请选择报名时间'
);
resolve
(
false
);
}
else
if
(
data
.
whetherSetApply
===
'YES'
&&
data
.
startTimeApply
>=
data
.
endTimeApply
)
{
}
else
if
(
data
.
whetherSetApply
===
'YES'
&&
data
.
startTimeApply
>=
data
.
endTimeApply
)
{
message
.
warning
(
'报名结束时间需大于报名开始时间'
);
resolve
(
false
);
}
else
if
(
data
.
whetherSetApply
===
'YES'
&&
data
.
endTimeApply
>
moment
(
moment
(
data
.
calendarTime
[
0
]).
format
(
'YYYY-MM-DD'
)
+
moment
(
data
.
endTime
).
format
(
' HH:mm:ss'
)).
valueOf
()){
}
else
if
(
data
.
whetherSetApply
===
'YES'
&&
data
.
endTimeApply
>
moment
(
moment
(
data
.
calendarTime
[
0
]).
format
(
'YYYY-MM-DD'
)
+
moment
(
data
.
endTime
).
format
(
' HH:mm:ss'
)).
valueOf
()
)
{
message
.
warning
(
'报名结束时间需小于上课开始时间'
);
resolve
(
false
);
}
else
if
(
data
.
whetherSetSignIn
===
'YES'
&&
!
data
.
signInTimeNum
)
{
}
else
if
(
data
.
whetherSetSignIn
===
'YES'
&&
!
data
.
signInTimeNum
)
{
message
.
warning
(
'请输入签到时间'
);
resolve
(
false
);
}
else
if
(
data
.
whetherSetSignOut
===
'YES'
&&
((
data
.
signOutType
===
'START_LATER'
&&
!
data
.
signOutStartTimeNum
)
||
!
data
.
signOutEndTimeNum
))
{
}
else
if
(
data
.
whetherSetSignOut
===
'YES'
&&
((
data
.
signOutType
===
'START_LATER'
&&
!
data
.
signOutStartTimeNum
)
||
!
data
.
signOutEndTimeNum
))
{
message
.
warning
(
'请输入签退时间'
);
resolve
(
false
);
}
else
if
(
data
.
isMore
)
{
...
...
@@ -579,7 +565,7 @@ class AddOfflineCourse extends React.Component {
resolve
(
true
);
}
});
}
}
;
// 使用默认封面图
handleResetCoverUrl
=
()
=>
{
...
...
@@ -589,41 +575,46 @@ class AddOfflineCourse extends React.Component {
if
(
isDefaultCover
)
return
;
message
.
success
(
'已替换为默认图'
);
this
.
setState
({
coverUrl
:
defaultCoverUrl
});
}
}
;
// 滑动加载更多讲师列表
handleScrollTeacherList
=
(
e
)
=>
{
const
{
hasNext
}
=
this
.
state
;
const
container
=
e
.
target
;
const
{
hasNext
}
=
this
.
state
;
const
container
=
e
.
target
;
//判定元素是否滚动到底部
const
scrollToBottom
=
container
&&
container
.
scrollHeight
<=
container
.
clientHeight
+
container
.
scrollTop
;
if
(
scrollToBottom
&&
hasNext
)
{
const
{
teacherQuery
}
=
this
.
state
;
let
_teacherQuery
=
teacherQuery
;
_teacherQuery
.
current
=
_teacherQuery
.
current
+
1
this
.
setState
({
teacherQuery
:{...
_teacherQuery
}
},()
=>
{
this
.
getTeacherList
(
_teacherQuery
.
current
)})
}
}
getTeacherList
(
current
=
1
,
selectList
){
const
{
teacherQuery
,
teacherList
}
=
this
.
state
;
//判定元素是否滚动到底部
const
scrollToBottom
=
container
&&
container
.
scrollHeight
<=
container
.
clientHeight
+
container
.
scrollTop
;
if
(
scrollToBottom
&&
hasNext
)
{
const
{
teacherQuery
}
=
this
.
state
;
let
_teacherQuery
=
teacherQuery
;
_teacherQuery
.
current
=
_teacherQuery
.
current
+
1
;
this
.
setState
(
{
teacherQuery
:
{
...
_teacherQuery
},
},
()
=>
{
this
.
getTeacherList
(
_teacherQuery
.
current
);
}
);
}
};
getTeacherList
(
current
=
1
,
selectList
)
{
const
{
teacherQuery
,
teacherList
}
=
this
.
state
;
const
_query
=
{
...
teacherQuery
,
current
,
size
:
15
size
:
15
,
};
StoreService
.
getStoreUserBasicPage
(
_query
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
records
=
[],
total
=
0
,
hasNext
}
=
result
;
const
list
=
current
>
1
?
teacherList
.
concat
(
records
)
:
records
;
this
.
setState
({
hasNext
,
teacherList
:
list
,
teacherQuery
:{...
_query
}
})
StoreService
.
getStoreUserBasicPage
(
_query
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
records
=
[]
,
hasNext
}
=
result
;
const
list
=
current
>
1
?
teacherList
.
concat
(
records
)
:
records
;
this
.
setState
({
hasNext
,
teacherList
:
list
,
teacherQuery
:
{
...
_query
},
});
});
}
...
...
@@ -633,14 +624,14 @@ class AddOfflineCourse extends React.Component {
message
.
warning
(
'内容过长,不能超过1000字'
);
}
this
.
setState
({
introduce
:
value
,
isMore
});
}
}
;
selectMultiDate
=
(
calendarTime
)
=>
{
const
dateList
=
_
.
sortBy
(
calendarTime
);
this
.
setState
({
calendarTime
:
dateList
,
})
}
})
;
}
;
handleChangeDates
=
(
dates
)
=>
{
const
data
=
{};
...
...
@@ -652,15 +643,15 @@ class AddOfflineCourse extends React.Component {
data
.
endTimeApply
=
dates
[
1
].
startOf
(
'minute'
).
valueOf
()
+
59000
;
}
this
.
setState
(
data
);
}
}
;
whetherVisitorsJoinChange
=
()
=>
{
if
(
this
.
state
.
whetherVisitorsJoin
===
"NO"
)
{
whetherVisitorsJoinChange
=
()
=>
{
if
(
this
.
state
.
whetherVisitorsJoin
===
'NO'
)
{
this
.
setState
({
whetherVisitorsJoin
:
'YES'
});
}
else
{
}
else
{
this
.
setState
({
whetherVisitorsJoin
:
'NO'
});
}
}
}
;
handleChangeCatalogList
=
(
value
,
label
)
=>
{
this
.
setState
({
categoryId
:
value
,
categoryName
:
label
[
0
]
});
...
...
@@ -674,14 +665,11 @@ class AddOfflineCourse extends React.Component {
coverUrl
,
introduce
,
categoryId
,
categoryList
,
courseCatalogList
,
whetherVisitorsJoin
,
loadintroduce
,
showSelectCoverModal
,
visible
,
hasImgReady
,
cutImageBlob
,
teacherId
,
teacherList
,
calendarTime
,
...
...
@@ -709,64 +697,66 @@ class AddOfflineCourse extends React.Component {
}
=
this
.
state
;
const
isDefaultCover
=
coverUrl
===
defaultCoverUrl
;
return
(
<
div
className=
"page add-offline-course-page"
>
<
Breadcrumbs
navList=
{
pageType
===
"add"
?
"新建线下课"
:
"编辑线下课"
}
goBack=
{
this
.
handleGoBack
}
/>
<
div
className=
'page add-offline-course-page'
>
<
Breadcrumbs
navList=
{
pageType
===
'add'
?
'新建线下课'
:
'编辑线下课'
}
goBack=
{
this
.
handleGoBack
}
/>
<
div
className=
"box"
>
<
div
className=
"show-tips"
>
<
ShowTips
message=
"请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利"
/>
<
div
className=
'box'
>
<
div
className=
'show-tips'
>
<
ShowTips
message=
'请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利'
/>
</
div
>
<
div
className=
"form"
>
<
div
className=
"basic-info__wrap"
>
<
div
className=
"title"
>
基本信息
</
div
>
<
div
className=
"course-name"
>
<
span
className=
"label"
><
span
className=
"require"
>
*
</
span
>
课程名称:
</
span
>
<
div
className=
'form'
>
<
div
className=
'basic-info__wrap'
>
<
div
className=
'title'
>
基本信息
</
div
>
<
div
className=
'course-name'
>
<
span
className=
'label'
>
<
span
className=
'require'
>
*
</
span
>
课程名称:
</
span
>
<
Input
value=
{
courseName
}
placeholder=
"请输入线下课的名称(40字以内)"
placeholder=
'请输入线下课的名称(40字以内)'
maxLength=
{
40
}
style=
{
{
width
:
240
}
}
onChange=
{
(
e
)
=>
{
this
.
setState
({
courseName
:
e
.
target
.
value
})
}
}
onChange=
{
(
e
)
=>
{
this
.
setState
({
courseName
:
e
.
target
.
value
});
}
}
/>
</
div
>
<
div
className=
"course-cover"
>
<
span
className=
"label"
>
封面图:
</
span
>
<
div
className=
'course-cover'
>
<
span
className=
'label'
>
封面图:
</
span
>
<
div
className=
"course-cover__wrap"
>
<
div
className=
"img-content"
>
{
isDefaultCover
&&
<
span
className=
"tag"
>
默认图
</
span
>
}
<
img
src=
{
coverUrl
}
/>
<
div
className=
'course-cover__wrap'
>
<
div
className=
'img-content'
>
{
isDefaultCover
&&
<
span
className=
'tag'
>
默认图
</
span
>
}
<
img
src=
{
coverUrl
}
alt=
''
/>
</
div
>
<
div
className=
"opt-btns"
>
<
Button
onClick=
{
()
=>
{
this
.
setState
({
showSelectCoverModal
:
true
})
}
}
>
上传图片
</
Button
>
<
span
className=
{
`default-btn ${isDefaultCover ? 'disabled' : ''}`
}
onClick=
{
this
.
handleResetCoverUrl
}
>
使用默认图
</
span
>
<
div
className=
"tips"
>
建议尺寸1280*720px,图片支持jpg、jpeg、png格式。
</
div
>
<
div
className=
'opt-btns'
>
<
Button
onClick=
{
()
=>
{
this
.
setState
({
showSelectCoverModal
:
true
,
});
}
}
>
上传图片
</
Button
>
<
span
className=
{
`default-btn ${isDefaultCover ? 'disabled' : ''}`
}
onClick=
{
this
.
handleResetCoverUrl
}
>
使用默认图
</
span
>
<
div
className=
'tips'
>
建议尺寸1280*720px,图片支持jpg、jpeg、png格式。
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"course-catalog"
>
<
span
className=
"label special"
><
span
className=
"require"
>
*
</
span
>
课程分类:
</
span
>
<
div
className=
'course-catalog'
>
<
span
className=
'label special'
>
<
span
className=
'require'
>
*
</
span
>
课程分类:
</
span
>
<
TreeSelect
showSearch
treeNodeFilterProp=
"title"
treeNodeFilterProp=
'title'
style=
{
{
width
:
240
}
}
dropdownStyle=
{
{
maxHeight
:
300
,
overflow
:
"auto"
}
}
dropdownStyle=
{
{
maxHeight
:
300
,
overflow
:
'auto'
}
}
treeData=
{
courseCatalogList
}
placeholder=
"请选择课程类型"
placeholder=
'请选择课程类型'
allowClear
value=
{
categoryId
}
treeDefaultExpandAll
...
...
@@ -775,184 +765,189 @@ class AddOfflineCourse extends React.Component {
}
}
/>
</
div
>
<
div
className=
"course-catalog"
>
<
span
className=
"label special"
><
span
className=
"require"
>
*
</
span
>
上课地点:
</
span
>
<
div
className=
'course-catalog'
>
<
span
className=
'label special'
>
<
span
className=
'require'
>
*
</
span
>
上课地点:
</
span
>
<
Input
value=
{
offlinePlace
}
maxLength=
{
40
}
style=
{
{
width
:
240
}
}
placeholder=
"请输入上课地点(40字以内)"
placeholder=
'请输入上课地点(40字以内)'
onChange=
{
(
e
)
=>
{
this
.
setState
({
offlinePlace
:
e
.
target
.
value
})
this
.
setState
({
offlinePlace
:
e
.
target
.
value
})
;
}
}
/>
</
div
>
<
div
className=
"course-catalog"
id=
"teacher"
>
<
span
className=
"label special"
><
span
className=
"require"
>
*
</
span
>
讲师:
</
span
>
<
div
className=
'course-catalog'
id=
'teacher'
>
<
span
className=
'label special'
>
<
span
className=
'require'
>
*
</
span
>
讲师:
</
span
>
<
Select
placeholder=
"请选择讲师"
placeholder=
'请选择讲师'
value=
{
teacherId
}
style=
{
{
width
:
240
}
}
showSearch
allowClear
filterOption=
{
(
input
,
option
)
=>
option
}
dropdownClassName=
"offline-dropdown-box"
dropdownClassName=
'offline-dropdown-box'
onPopupScroll=
{
this
.
handleScrollTeacherList
}
suffixIcon=
{
<
span
className=
"icon iconfont"
style=
{
{
fontSize
:
'12px'
,
color
:
'#BFBFBF'
}
}
>

</
span
>
}
suffixIcon=
{
<
span
className=
'icon iconfont'
style=
{
{
fontSize
:
'12px'
,
color
:
'#BFBFBF'
}
}
>

</
span
>
}
onChange=
{
(
value
,
option
)
=>
{
if
(
option
)
{
this
.
setState
({
teacherId
:
value
,
teacherName
:
option
.
children
});
}
else
{
this
.
setState
({
teacherId
:
value
,
teacherName
:
""
});
}
else
{
this
.
setState
({
teacherId
:
value
,
teacherName
:
''
});
}
}
}
onSearch=
{
(
value
)
=>
{
let
_teacherQuery
=
{...
this
.
state
.
teacherQuery
};
_teacherQuery
.
nickName
=
value
this
.
setState
({
teacherQuery
:
_teacherQuery
},
()
=>
{
this
.
getTeacherList
()
})
let
_teacherQuery
=
{
...
this
.
state
.
teacherQuery
};
_teacherQuery
.
nickName
=
value
;
this
.
setState
(
{
teacherQuery
:
_teacherQuery
,
},
()
=>
{
this
.
getTeacherList
();
}
);
}
}
onClear
={(
value
)=
>
{
this
.
setState
({
teacherQuery
:{
size
:
15
,
current
:
1
,
nickName
:
null
onClear=
{
(
value
)
=>
{
this
.
setState
(
{
teacherQuery
:
{
size
:
15
,
current
:
1
,
nickName
:
null
,
},
},
()
=>
{
this
.
getTeacherList
();
}
},
()
=>
{
this
.
getTeacherList
()
})
}
}
getPopupContainer=
{
()
=>
document
.
getElementById
(
"teacher"
)
}
>
{
_
.
map
(
teacherList
,
(
item
,
index
)
=>
{
);
}
}
getPopupContainer=
{
()
=>
document
.
getElementById
(
'teacher'
)
}
>
{
_
.
map
(
teacherList
,
(
item
)
=>
{
return
(
<
Option
value=
{
item
.
id
}
key=
{
item
.
id
}
>
{
item
.
nickName
}
</
Option
>
<
Option
value=
{
item
.
id
}
key=
{
item
.
id
}
>
{
item
.
nickName
}
</
Option
>
);
})
}
</
Select
>
</
div
>
<
div
className=
"allow-tourist-join"
>
<
span
className=
"label"
>
观看设置:
</
span
>
<
div
className=
"content"
>
<
div
className=
'allow-tourist-join'
>
<
span
className=
'label'
>
观看设置:
</
span
>
<
div
className=
'content'
>
<
div
>
<
Switch
checked=
{
whetherVisitorsJoin
===
"YES"
?
true
:
false
}
onChange=
{
this
.
whetherVisitorsJoinChange
}
/>
</
div
>
<
Switch
checked=
{
whetherVisitorsJoin
===
'YES'
?
true
:
false
}
onChange=
{
this
.
whetherVisitorsJoinChange
}
/>
</
div
>
<
div
>
<
div
className=
"desc"
>
<
div
className=
'desc'
>
<
div
>
开启:允许未绑定手机号的学员观看
</
div
>
<
div
>
关闭:仅限绑定了手机号的学员可以进入观看线下课
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"introduce"
>
<
span
className=
"label"
>
课程简介:
</
span
>
<
div
className=
"content"
>
<
div
className=
"intro-list"
>
<
div
className=
"intro-list__item introduce-editor"
>
{
(
!
courseId
||
loadintroduce
)
&&
<
div
className=
'introduce'
>
<
span
className=
'label'
>
课程简介:
</
span
>
<
div
className=
'content'
>
<
div
className=
'intro-list'
>
<
div
className=
'intro-list__item introduce-editor'
>
{
(
!
courseId
||
loadintroduce
)
&&
(
<
GraphicsEditor
id=
"intro"
id=
'intro'
isIntro=
{
true
}
maxLimit=
{
1000
}
detail=
{
{
content
:
introduce
content
:
introduce
,
}
}
onChange=
{
(
val
,
textLength
)
=>
{
this
.
changeIntro
(
val
,
textLength
)
this
.
changeIntro
(
val
,
textLength
)
;
}
}
/>
}
)
}
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"title"
style=
{
{
marginTop
:
24
}
}
>
课程设置
</
div
>
<
div
className=
"day"
>
<
span
className=
"label"
>
<
span
className=
"require"
>
*
</
span
>
上课日期:
</
span
>
<
div
className=
'title'
style=
{
{
marginTop
:
24
}
}
>
课程设置
</
div
>
<
div
className=
'day'
>
<
span
className=
'label'
>
<
span
className=
'require'
>
*
</
span
>
上课日期:
</
span
>
<
div
>
<
div
className=
'select-day'
>
已选
<
span
className=
"mark-day"
>
{
isLongArr
(
calendarTime
)
?
calendarTime
.
length
:
0
}
</
span
>
天
已选
<
span
className=
'mark-day'
>
{
window
.
isLongArr
(
calendarTime
)
?
calendarTime
.
length
:
0
}
</
span
>
天
</
div
>
<
MultipleDatePicker
disabled=
{
isEditDisablie
}
selectDateList=
{
calendarTime
}
onSelect=
{
this
.
selectMultiDate
}
canSelectTodayBefore=
{
false
}
/>
<
MultipleDatePicker
disabled=
{
isEditDisablie
}
selectDateList=
{
calendarTime
}
onSelect=
{
this
.
selectMultiDate
}
canSelectTodayBefore=
{
false
}
/>
</
div
>
</
div
>
<
div
className=
"hour"
id=
"hour"
>
<
span
className=
"label"
><
span
className=
"require"
>
*
</
span
>
上课时间:
</
span
>
<
div
className=
'hour'
id=
'hour'
>
<
span
className=
'label'
>
<
span
className=
'require'
>
*
</
span
>
上课时间:
</
span
>
<
TimePicker
disabled=
{
isEditDisablie
}
className=
"time-picker"
format=
"HH:mm"
className=
'time-picker'
format=
'HH:mm'
value=
{
startTime
?
moment
(
startTime
)
:
null
}
placeholder=
"开始时间"
placeholder=
'开始时间'
showNow=
{
false
}
style=
{
{
width
:
100
,
minWidth
:
100
}
}
style=
{
{
width
:
100
,
minWidth
:
100
}
}
onSelect=
{
(
time
)
=>
{
this
.
setState
({
startTime
:
time
});
}
}
getPopupContainer=
{
()
=>
document
.
getElementById
(
"hour"
)
}
/>
~
getPopupContainer=
{
()
=>
document
.
getElementById
(
'hour'
)
}
/>
~
<
TimePicker
disabled=
{
isEditDisablie
}
className=
"time-picker"
format=
"HH:mm"
className=
'time-picker'
format=
'HH:mm'
value=
{
endTime
?
moment
(
endTime
)
:
null
}
placeholder=
"结束时间"
placeholder=
'结束时间'
showNow=
{
false
}
style=
{
{
width
:
100
,
minWidth
:
100
}
}
onSelect=
{
(
time
)
=>
{
this
.
setState
({
endTime
:
time
});
}
}
getPopupContainer=
{
()
=>
document
.
getElementById
(
"hour"
)
}
getPopupContainer=
{
()
=>
document
.
getElementById
(
'hour'
)
}
/>
</
div
>
<
div
className=
"course-catalog"
>
<
span
className=
"label"
><
span
className=
"require"
>
*
</
span
>
学员上课方式:
</
span
>
<
div
className=
'course-catalog'
>
<
span
className=
'label'
>
<
span
className=
'require'
>
*
</
span
>
学员上课方式:
</
span
>
<
Radio
.
Group
style=
{
{
display
:
'inline-block'
}
}
value=
{
offlineCourseType
}
onChange=
{
(
e
)
=>
{
this
.
setState
({
offlineCourseType
:
e
.
target
.
value
});
}
}
className=
"mt5"
disabled=
{
isEditDisablie
}
>
<
Radio
value=
"ALL_DAY_OFFLINE"
className=
"mr-16"
>
<
span
style=
{
{
color
:
"#333"
}
}
>
所选日期都要上课
</
span
>
className=
'mt5'
disabled=
{
isEditDisablie
}
>
<
Radio
value=
'ALL_DAY_OFFLINE'
className=
'mr-16'
>
<
span
style=
{
{
color
:
'#333'
}
}
>
所选日期都要上课
</
span
>
</
Radio
>
<
Radio
value=
"ANY_DAY_POFFLINE"
className=
"mr-16"
>
<
span
style=
{
{
color
:
"#333"
}
}
>
选择任意1天上课
</
span
>
<
Radio
value=
'ANY_DAY_POFFLINE'
className=
'mr-16'
>
<
span
style=
{
{
color
:
'#333'
}
}
>
选择任意1天上课
</
span
>
</
Radio
>
</
Radio
.
Group
>
</
div
>
<
div
className=
"course-catalog"
>
<
span
className=
"label"
>
课程报名:
</
span
>
<
div
className=
"switch-box"
>
<
div
className=
"switch-item"
key=
"1"
>
<
div
className=
'course-catalog'
>
<
span
className=
'label'
>
课程报名:
</
span
>
<
div
className=
'switch-box'
>
<
div
className=
'switch-item'
key=
'1'
>
<
Switch
disabled=
{
isEditDisablie
}
checked=
{
whetherSetApply
===
'YES'
}
...
...
@@ -965,79 +960,118 @@ class AddOfflineCourse extends React.Component {
});
}
}
/>
<
span
className=
"switch-tip"
>
开启后可设置课程报名时间,获取报名数据
</
span
>
<
span
className=
'switch-tip'
>
开启后可设置课程报名时间,获取报名数据
</
span
>
</
div
>
{
whetherSetApply
===
'YES'
&&
<
div
className=
"switch-item"
key=
"2"
>
<
span
className=
"switch-label"
>
报名日期:
</
span
>
<
RangePicker
id=
"course_date_picker"
showTime=
{
{
showTime
:
'HH:mm'
}
}
allowClear=
{
false
}
value=
{
startTimeApply
?
[
moment
(
startTimeApply
),
moment
(
endTimeApply
)]
:
null
}
format=
{
"YYYY-MM-DD HH:mm"
}
onChange=
{
(
dates
)
=>
{
this
.
handleChangeDates
(
dates
)
}
}
renderExtraFooter=
{
()
=>
calendarTime
[
0
]
?
<
div
style=
{
{
position
:
'absolute'
,
bottom
:
8
,
cursor
:
'pointer'
}
}
>
<
span
onClick=
{
()
=>
this
.
setState
({
startTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
).
subtract
(
1
,
'days'
).
valueOf
(),
endTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
).
valueOf
()
-
1000
})
}
style=
{
{
color
:
'#2966FF'
,
border
:
'1px solid #2966FF'
,
padding
:
'2px 8px'
,
borderRadius
:
'2px'
,
marginRight
:
8
,
}
}
>
上课前1天
</
span
>
<
span
onClick=
{
()
=>
this
.
setState
({
startTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
).
subtract
(
2
,
'days'
).
valueOf
(),
endTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
).
valueOf
()
-
1000
})
}
style=
{
{
color
:
'#2966FF'
,
border
:
'1px solid #2966FF'
,
padding
:
'2px 8px'
,
borderRadius
:
'2px'
,
marginRight
:
8
,
}
}
>
上课前2天
</
span
>
<
span
onClick=
{
()
=>
this
.
setState
({
startTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
).
subtract
(
3
,
'days'
).
valueOf
(),
endTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
).
valueOf
()
-
1000
})
}
style=
{
{
color
:
'#2966FF'
,
border
:
'1px solid #2966FF'
,
padding
:
'2px 8px'
,
borderRadius
:
'2px'
,
marginRight
:
8
,
}
}
>
上课前3天
</
span
>
</
div
>
:
null
}
/>
</
div
>
}
{
whetherSetApply
===
'YES'
&&
<
div
className=
"switch-item"
key=
"3"
>
<
span
className=
"switch-label"
>
报名人数
<
Tooltip
title=
"报名一旦开始,报名人数不支持减少"
>
<
span
style=
{
{
margin
:
'0 4px'
,
color
:
'#999'
}
}
className=
"icon iconfont"
>

</
span
>
</
Tooltip
>
:最多
</
span
>
<
InputNumber
value=
{
quota
}
min=
{
oldQuta
||
1
}
max=
{
100000
}
precision=
{
0
}
style=
{
{
margin
:
'0 4px'
,
width
:
90
}
}
disabled=
{
oldQuta
<
0
}
onChange=
{
(
value
)
=>
{
this
.
setState
({
quota
:
value
})
}
}
/>
<
span
className=
"switch-label"
>
人
</
span
>
<
span
className=
"switch-tip"
>
未填写时默认为不限制
</
span
>
</
div
>
}
{
whetherSetApply
===
'YES'
&&
(
<
div
className=
'switch-item'
key=
'2'
>
<
span
className=
'switch-label'
>
报名日期:
</
span
>
<
RangePicker
id=
'course_date_picker'
showTime=
{
{
showTime
:
'HH:mm'
}
}
allowClear=
{
false
}
value=
{
startTimeApply
?
[
moment
(
startTimeApply
),
moment
(
endTimeApply
)]
:
null
}
format=
{
'YYYY-MM-DD HH:mm'
}
onChange=
{
(
dates
)
=>
{
this
.
handleChangeDates
(
dates
);
}
}
renderExtraFooter=
{
()
=>
(
<
If
condition=
{
calendarTime
[
0
]
}
>
<
div
style=
{
{
position
:
'absolute'
,
bottom
:
8
,
cursor
:
'pointer'
}
}
>
<
span
onClick=
{
()
=>
this
.
setState
({
startTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
)
.
subtract
(
1
,
'days'
)
.
valueOf
(),
endTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
).
valueOf
()
-
1000
,
})
}
style=
{
{
color
:
'#2966FF'
,
border
:
'1px solid #2966FF'
,
padding
:
'2px 8px'
,
borderRadius
:
'2px'
,
marginRight
:
8
,
}
}
>
上课前1天
</
span
>
<
span
onClick=
{
()
=>
this
.
setState
({
startTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
)
.
subtract
(
2
,
'days'
)
.
valueOf
(),
endTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
).
valueOf
()
-
1000
,
})
}
style=
{
{
color
:
'#2966FF'
,
border
:
'1px solid #2966FF'
,
padding
:
'2px 8px'
,
borderRadius
:
'2px'
,
marginRight
:
8
,
}
}
>
上课前2天
</
span
>
<
span
onClick=
{
()
=>
this
.
setState
({
startTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
)
.
subtract
(
3
,
'days'
)
.
valueOf
(),
endTimeApply
:
moment
(
`${moment(calendarTime[0]).format('YYYY-MM-DD')} ${moment(startTime).format('HH:mm')}`
).
valueOf
()
-
1000
,
})
}
style=
{
{
color
:
'#2966FF'
,
border
:
'1px solid #2966FF'
,
padding
:
'2px 8px'
,
borderRadius
:
'2px'
,
marginRight
:
8
,
}
}
>
上课前3天
</
span
>
</
div
>
</
If
>
)
}
/>
</
div
>
)
}
{
whetherSetApply
===
'YES'
&&
(
<
div
className=
'switch-item'
key=
'3'
>
<
span
className=
'switch-label'
>
报名人数
<
Tooltip
title=
'报名一旦开始,报名人数不支持减少'
>
<
span
style=
{
{
margin
:
'0 4px'
,
color
:
'#999'
}
}
className=
'icon iconfont'
>

</
span
>
</
Tooltip
>
:最多
</
span
>
<
InputNumber
value=
{
quota
}
min=
{
oldQuta
||
1
}
max=
{
100000
}
precision=
{
0
}
style=
{
{
margin
:
'0 4px'
,
width
:
90
}
}
disabled=
{
oldQuta
<
0
}
onChange=
{
(
value
)
=>
{
this
.
setState
({
quota
:
value
});
}
}
/>
<
span
className=
'switch-label'
>
人
</
span
>
<
span
className=
'switch-tip'
>
未填写时默认为不限制
</
span
>
</
div
>
)
}
</
div
>
</
div
>
<
div
className=
"course-catalog"
>
<
span
className=
"label"
>
考勤签到:
</
span
>
<
div
className=
"switch-box"
>
<
div
className=
"switch-item"
key=
"1"
>
<
div
className=
'course-catalog'
>
<
span
className=
'label'
>
考勤签到:
</
span
>
<
div
className=
'switch-box'
>
<
div
className=
'switch-item'
key=
'1'
>
<
Switch
checked=
{
whetherSetSignIn
===
'YES'
}
onChange=
{
(
value
)
=>
{
...
...
@@ -1046,64 +1080,68 @@ class AddOfflineCourse extends React.Component {
signInType
:
'START_AGO'
,
signInTimeNum
:
null
,
signInTimeUnit
:
'MINUTE'
,
})
})
;
}
}
/>
<
span
className=
"switch-tip"
>
开启后可设置获取签到考勤数据
</
span
>
<
span
className=
'switch-tip'
>
开启后可设置获取签到考勤数据
</
span
>
</
div
>
{
whetherSetSignIn
===
'YES'
&&
<
div
className=
"switch-item"
key=
"2"
>
<
span
className=
"switch-label"
>
签到时间:
</
span
>
<
Radio
.
Group
style=
{
{
display
:
'inline-block'
}
}
value=
{
signInType
}
onChange=
{
(
e
)
=>
{
this
.
setState
({
signInType
:
e
.
target
.
value
});
}
}
className=
"mt5"
>
<
Radio
value=
"START_AGO"
className=
"mr-16"
>
<
span
style=
{
{
color
:
"#333"
}
}
>
课程开始前
</
span
>
</
Radio
>
<
Radio
value=
"END_AGO"
className=
"mr-16"
>
<
span
style=
{
{
color
:
"#333"
}
}
>
课程结束前
</
span
>
</
Radio
>
</
Radio
.
Group
>
</
div
>
}
{
whetherSetSignIn
===
'YES'
&&
<
div
className=
"switch-item"
key=
"3"
>
<
span
className=
"switch-label"
>
课程
{
signInType
===
'START_AGO'
?
'开始'
:
'结束'
}
前
</
span
>
<
InputNumber
value=
{
signInTimeNum
}
min=
{
1
}
max=
{
signInTimeUnit
===
'MINUTE'
?
1440
:
24
}
precision=
{
0
}
style=
{
{
margin
:
'0 4px'
,
width
:
90
}
}
onChange=
{
(
value
)
=>
{
this
.
setState
({
signInTimeNum
:
value
})
}
}
/>
<
Select
style=
{
{
width
:
72
,
marginRight
:
4
}
}
value=
{
signInTimeUnit
}
onChange=
{
(
value
)
=>
{
const
data
=
{
signInTimeUnit
:
value
}
if
(
value
===
'HOUR'
&&
signInTimeNum
>
24
)
{
data
.
signInTimeNum
=
24
;
}
this
.
setState
(
data
);
}
}
>
{
unitList
.
map
(
item
=>
(
<
Option
value=
{
item
.
key
}
key=
{
item
.
key
}
>
{
item
.
value
}
</
Option
>
))
}
</
Select
>
<
span
className=
"switch-label"
>
内可签到
</
span
>
</
div
>
}
{
whetherSetSignIn
===
'YES'
&&
(
<
div
className=
'switch-item'
key=
'2'
>
<
span
className=
'switch-label'
>
签到时间:
</
span
>
<
Radio
.
Group
style=
{
{
display
:
'inline-block'
}
}
value=
{
signInType
}
onChange=
{
(
e
)
=>
{
this
.
setState
({
signInType
:
e
.
target
.
value
});
}
}
className=
'mt5'
>
<
Radio
value=
'START_AGO'
className=
'mr-16'
>
<
span
style=
{
{
color
:
'#333'
}
}
>
课程开始前
</
span
>
</
Radio
>
<
Radio
value=
'END_AGO'
className=
'mr-16'
>
<
span
style=
{
{
color
:
'#333'
}
}
>
课程结束前
</
span
>
</
Radio
>
</
Radio
.
Group
>
</
div
>
)
}
{
whetherSetSignIn
===
'YES'
&&
(
<
div
className=
'switch-item'
key=
'3'
>
<
span
className=
'switch-label'
>
课程
{
signInType
===
'START_AGO'
?
'开始'
:
'结束'
}
前
</
span
>
<
InputNumber
value=
{
signInTimeNum
}
min=
{
1
}
max=
{
signInTimeUnit
===
'MINUTE'
?
1440
:
24
}
precision=
{
0
}
style=
{
{
margin
:
'0 4px'
,
width
:
90
}
}
onChange=
{
(
value
)
=>
{
this
.
setState
({
signInTimeNum
:
value
});
}
}
/>
<
Select
style=
{
{
width
:
72
,
marginRight
:
4
}
}
value=
{
signInTimeUnit
}
onChange=
{
(
value
)
=>
{
const
data
=
{
signInTimeUnit
:
value
};
if
(
value
===
'HOUR'
&&
signInTimeNum
>
24
)
{
data
.
signInTimeNum
=
24
;
}
this
.
setState
(
data
);
}
}
>
{
unitList
.
map
((
item
)
=>
(
<
Option
value=
{
item
.
key
}
key=
{
item
.
key
}
>
{
item
.
value
}
</
Option
>
))
}
</
Select
>
<
span
className=
'switch-label'
>
内可签到
</
span
>
</
div
>
)
}
</
div
>
</
div
>
<
div
className=
"course-catalog"
>
<
span
className=
"label"
>
考勤签退:
</
span
>
<
div
className=
"switch-box"
>
<
div
className=
"switch-item"
key=
"1"
>
<
div
className=
'course-catalog'
>
<
span
className=
'label'
>
考勤签退:
</
span
>
<
div
className=
'switch-box'
>
<
div
className=
'switch-item'
key=
'1'
>
<
Switch
checked=
{
whetherSetSignOut
===
'YES'
}
onChange=
{
(
value
)
=>
{
...
...
@@ -1114,119 +1152,135 @@ class AddOfflineCourse extends React.Component {
signOutStartTimeUnit
:
'MINUTE'
,
signOutEndTimeNum
:
null
,
signOutEndTimeUnit
:
'MINUTE'
,
})
})
;
}
}
/>
<
span
className=
"switch-tip"
>
开启后可设置获取签退考勤数据
</
span
>
<
span
className=
'switch-tip'
>
开启后可设置获取签退考勤数据
</
span
>
</
div
>
{
whetherSetSignOut
===
'YES'
&&
<
div
className=
"switch-item"
key=
"2"
>
<
span
className=
"switch-label"
>
签退时间:
</
span
>
<
Radio
.
Group
style=
{
{
display
:
'inline-block'
}
}
value=
{
signOutType
}
onChange=
{
(
e
)
=>
{
this
.
setState
({
signOutType
:
e
.
target
.
value
});
}
}
className=
"mt5"
>
<
Radio
value=
"START_LATER"
className=
"mr-16"
>
<
span
style=
{
{
color
:
"#333"
}
}
>
课程开始后
</
span
>
</
Radio
>
<
Radio
value=
"END_LATER"
className=
"mr-16"
>
<
span
style=
{
{
color
:
"#333"
}
}
>
课程结束后
</
span
>
</
Radio
>
</
Radio
.
Group
>
</
div
>
}
{
whetherSetSignOut
===
'YES'
&&
<
div
className=
"switch-item"
key=
"3"
>
<
span
className=
"switch-label"
>
课程
{
signOutType
===
'START_LATER'
?
'开始'
:
'结束'
}
后
</
span
>
{
signOutType
===
'START_LATER'
&&
<
InputNumber
value=
{
signOutStartTimeNum
}
min=
{
1
}
max=
{
signOutStartTimeUnit
===
'MINUTE'
?
1440
:
24
}
precision=
{
0
}
style=
{
{
margin
:
'0 4px'
,
width
:
90
}
}
onChange=
{
(
value
)
=>
{
this
.
setState
({
signOutStartTimeNum
:
value
})
}
}
/>
}
{
signOutType
===
'START_LATER'
&&
<
Select
style=
{
{
width
:
72
,
marginRight
:
4
}
}
value=
{
signOutStartTimeUnit
}
onChange=
{
(
value
)
=>
{
const
data
=
{
signOutStartTimeUnit
:
value
}
if
(
value
===
'HOUR'
&&
signOutStartTimeNum
>
24
)
{
data
.
signOutStartTimeNum
=
24
;
}
this
.
setState
(
data
);
}
}
>
{
unitList
.
map
(
item
=>
(
<
Option
value=
{
item
.
key
}
key=
{
item
.
key
}
>
{
item
.
value
}
</
Option
>
))
}
</
Select
>
}
{
signOutType
===
'START_LATER'
&&
<
span
className=
"switch-label"
>
就可签退,截止签退时间为下课后
</
span
>
}
<
InputNumber
value=
{
signOutEndTimeNum
}
min=
{
1
}
max=
{
signOutEndTimeUnit
===
'MINUTE'
?
1440
:
24
}
precision=
{
0
}
style=
{
{
margin
:
'0 4px'
,
width
:
90
}
}
onChange=
{
(
value
)
=>
{
this
.
setState
({
signOutEndTimeNum
:
value
})
}
}
/>
<
Select
style=
{
{
width
:
72
,
marginRight
:
4
}
}
value=
{
signOutEndTimeUnit
}
onChange=
{
(
value
)
=>
{
const
data
=
{
signOutEndTimeUnit
:
value
}
if
(
value
===
'HOUR'
&&
signOutEndTimeNum
>
24
)
{
data
.
signOutEndTimeNum
=
24
;
}
this
.
setState
(
data
);
}
}
>
{
unitList
.
map
(
item
=>
(
<
Option
value=
{
item
.
key
}
key=
{
item
.
key
}
>
{
item
.
value
}
</
Option
>
))
}
</
Select
>
{
signOutType
!==
'START_LATER'
&&
<
span
className=
"switch-label"
>
内可签退
</
span
>
}
</
div
>
}
{
whetherSetSignOut
===
'YES'
&&
(
<
div
className=
'switch-item'
key=
'2'
>
<
span
className=
'switch-label'
>
签退时间:
</
span
>
<
Radio
.
Group
style=
{
{
display
:
'inline-block'
}
}
value=
{
signOutType
}
onChange=
{
(
e
)
=>
{
this
.
setState
({
signOutType
:
e
.
target
.
value
});
}
}
className=
'mt5'
>
<
Radio
value=
'START_LATER'
className=
'mr-16'
>
<
span
style=
{
{
color
:
'#333'
}
}
>
课程开始后
</
span
>
</
Radio
>
<
Radio
value=
'END_LATER'
className=
'mr-16'
>
<
span
style=
{
{
color
:
'#333'
}
}
>
课程结束后
</
span
>
</
Radio
>
</
Radio
.
Group
>
</
div
>
)
}
{
whetherSetSignOut
===
'YES'
&&
(
<
div
className=
'switch-item'
key=
'3'
>
<
span
className=
'switch-label'
>
课程
{
signOutType
===
'START_LATER'
?
'开始'
:
'结束'
}
后
</
span
>
{
signOutType
===
'START_LATER'
&&
(
<
InputNumber
value=
{
signOutStartTimeNum
}
min=
{
1
}
max=
{
signOutStartTimeUnit
===
'MINUTE'
?
1440
:
24
}
precision=
{
0
}
style=
{
{
margin
:
'0 4px'
,
width
:
90
}
}
onChange=
{
(
value
)
=>
{
this
.
setState
({
signOutStartTimeNum
:
value
});
}
}
/>
)
}
{
signOutType
===
'START_LATER'
&&
(
<
Select
style=
{
{
width
:
72
,
marginRight
:
4
}
}
value=
{
signOutStartTimeUnit
}
onChange=
{
(
value
)
=>
{
const
data
=
{
signOutStartTimeUnit
:
value
};
if
(
value
===
'HOUR'
&&
signOutStartTimeNum
>
24
)
{
data
.
signOutStartTimeNum
=
24
;
}
this
.
setState
(
data
);
}
}
>
{
unitList
.
map
((
item
)
=>
(
<
Option
value=
{
item
.
key
}
key=
{
item
.
key
}
>
{
item
.
value
}
</
Option
>
))
}
</
Select
>
)
}
{
signOutType
===
'START_LATER'
&&
<
span
className=
'switch-label'
>
就可签退,截止签退时间为下课后
</
span
>
}
<
InputNumber
value=
{
signOutEndTimeNum
}
min=
{
1
}
max=
{
signOutEndTimeUnit
===
'MINUTE'
?
1440
:
24
}
precision=
{
0
}
style=
{
{
margin
:
'0 4px'
,
width
:
90
}
}
onChange=
{
(
value
)
=>
{
this
.
setState
({
signOutEndTimeNum
:
value
});
}
}
/>
<
Select
style=
{
{
width
:
72
,
marginRight
:
4
}
}
value=
{
signOutEndTimeUnit
}
onChange=
{
(
value
)
=>
{
const
data
=
{
signOutEndTimeUnit
:
value
};
if
(
value
===
'HOUR'
&&
signOutEndTimeNum
>
24
)
{
data
.
signOutEndTimeNum
=
24
;
}
this
.
setState
(
data
);
}
}
>
{
unitList
.
map
((
item
)
=>
(
<
Option
value=
{
item
.
key
}
key=
{
item
.
key
}
>
{
item
.
value
}
</
Option
>
))
}
</
Select
>
{
signOutType
!==
'START_LATER'
&&
<
span
className=
'switch-label'
>
内可签退
</
span
>
}
</
div
>
)
}
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"footer"
>
<
div
className=
'footer'
>
<
Button
onClick=
{
this
.
handleGoBack
}
>
取消
</
Button
>
<
Button
onClick=
{
this
.
handleShowPreviewModal
}
>
预览
</
Button
>
<
Button
type=
"primary"
onClick=
{
_
.
debounce
(()
=>
this
.
preSubmit
(),
3000
,
true
)
}
>
保存
</
Button
>
<
Button
type=
'primary'
onClick=
{
_
.
debounce
(()
=>
this
.
preSubmit
(),
3000
,
true
)
}
>
保存
</
Button
>
</
div
>
{
showSelectCoverModal
&&
{
showSelectCoverModal
&&
(
<
SelectPrepareFileModal
key=
"basic"
operateType=
"select"
key=
'basic'
operateType=
'select'
multiple=
{
false
}
accept=
"image/jpeg,image/png,image/jpg"
accept=
'image/jpeg,image/png,image/jpg'
selectTypeList=
{
[
'JPG'
,
'JPEG'
,
'PNG'
]
}
tooltip=
'支持文件类型:jpg、jpeg、png'
isOpen=
{
showSelectCoverModal
}
onClose=
{
()
=>
{
this
.
setState
({
showSelectCoverModal
:
false
})
this
.
setState
({
showSelectCoverModal
:
false
})
;
}
}
onSelect=
{
this
.
handleSelectCover
}
/>
}
{
visible
&&
<
ImgClipModal
visible=
{
visible
}
imgUrl=
{
imageFile
.
ossUrl
}
onConfirm=
{
this
.
getSignature
}
onClose=
{
()
=>
{
this
.
setState
({
visible
:
false
});}
}
/>
}
{
this
.
state
.
previewOfflineModal
}
)
}
{
visible
&&
(
<
ImgClipModal
visible=
{
visible
}
imgUrl=
{
imageFile
.
ossUrl
}
onConfirm=
{
this
.
getSignature
}
onClose=
{
()
=>
{
this
.
setState
({
visible
:
false
});
}
}
/>
)
}
{
this
.
state
.
previewOfflineModal
}
</
div
>
)
)
;
}
}
...
...
src/modules/course-manage/offline-course/components/AddGraphicsIntro.jsx
View file @
1bf6cc7a
/*
* @Author: 吴文洁
* @Date: 2020-07-16 11:05:17
* @Author: 吴文洁
* @Date: 2020-07-16 11:05:17
* @Last Modified by: chenshu
* @Last Modified time: 2021-04-06 16:17:57
* @Description: 添加直播-简介
*/
import
SelectPrepareFileModal
from
'@/modules/prepare-lesson/modal/SelectPrepareFileModal'
;
import
{
Col
,
message
,
Row
,
Switch
}
from
'antd'
;
import
React
from
'react'
;
import
{
Input
,
message
,
Upload
,
Radio
,
Row
,
Col
,
Button
,
Popover
,
Switch
}
from
'antd'
;
import
Service
from
'@/common/js/service'
;
import
GraphicsEditor
from
'../../components/GraphicsEditor'
;
import
User
from
'@/common/js/user'
;
import
UploadOss
from
'@/core/upload'
;
import
'./AddGraphicsIntro.less'
;
import
SelectPrepareFileModal
from
'@/modules/prepare-lesson/modal/SelectPrepareFileModal'
;
import
{
DISK_MAP
}
from
'@/common/constants/academic/lessonEnum'
;
import
{
ImgCutModalNew
}
from
'@/components'
;
const
{
TextArea
}
=
Input
;
class
AddGraphicsIntro
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
showSelectFileModal
:
false
,
diskList
:
[],
selectType
:
null
,
}
}
;
}
// 上传封面图
handleShowImgCutModal
=
(
event
)
=>
{
const
imageFile
=
event
.
target
.
files
[
0
];
if
(
!
imageFile
)
return
;
if
(
!
imageFile
)
return
;
this
.
setState
({
imageFile
,
showCutModal
:
true
,
});
}
}
;
// 选择暖场资源
handleSelectVideo
=
(
file
)
=>
{
const
{
selectType
}
=
this
.
state
;
// 选择暖场资源
handleSelectVideo
=
(
file
)
=>
{
const
{
selectType
}
=
this
.
state
;
this
.
setState
({
showSelectFileModal
:
false
})
showSelectFileModal
:
false
,
})
;
const
{
ossUrl
,
resourceId
,
folderName
,
folderFormat
,
folderSize
}
=
file
;
if
(
selectType
===
'WARMUP'
)
{
if
(
selectType
===
'WARMUP'
)
{
const
liveCourseWarmMedia
=
{
contentType
:
'WARMUP'
,
mediaType
:
folderFormat
===
'MP4'
?
'VIDEO'
:
'PICTURE'
,
mediaContent
:
resourceId
,
mediaUrl
:
ossUrl
,
mediaName
:
folderName
,
size
:
folderSize
}
size
:
folderSize
,
}
;
this
.
props
.
onChange
(
'liveCourseWarmMedia'
,
liveCourseWarmMedia
);
}
else
{
}
else
{
// 最多添加九图片
const
{
liveCourseMediaRequests
}
=
this
.
props
.
data
;
const
list
=
_
.
filter
(
liveCourseMediaRequests
,
(
item
)
=>
{
return
item
.
mediaType
==
"PICTURE"
;
return
item
.
mediaType
==
'PICTURE'
;
});
if
(
list
.
length
>
8
)
{
message
.
warning
(
"最多添加9张图片"
);
message
.
warning
(
'最多添加9张图片'
);
return
;
}
liveCourseMediaRequests
.
push
({
...
...
@@ -78,121 +70,128 @@ class AddGraphicsIntro extends React.Component {
});
this
.
props
.
onChange
(
'liveCourseMediaRequests'
,
liveCourseMediaRequests
);
}
}
};
changeDetail
=
(
value
)
=>
{
this
.
props
.
onChange
(
'courseMedia'
,
value
);
}
}
;
changeIntro
=
(
value
)
=>
{
this
.
props
.
onChange
(
'introduce'
,
value
);
}
}
;
whetherVisitorsJoinChange
=
()
=>
{
if
(
this
.
props
.
data
.
whetherVisitorsJoin
===
"NO"
)
{
this
.
props
.
onChange
(
'whetherVisitorsJoin'
,
'YES'
)
}
else
{
this
.
props
.
onChange
(
'whetherVisitorsJoin'
,
'NO'
)
whetherVisitorsJoinChange
=
()
=>
{
if
(
this
.
props
.
data
.
whetherVisitorsJoin
===
'NO'
)
{
this
.
props
.
onChange
(
'whetherVisitorsJoin'
,
'YES'
);
}
else
{
this
.
props
.
onChange
(
'whetherVisitorsJoin'
,
'NO'
);
}
}
}
;
shelfStateChange
=
()
=>
{
if
(
this
.
props
.
data
.
shelfState
===
"NO"
)
{
this
.
props
.
onChange
(
'shelfState'
,
'YES'
)
}
else
{
this
.
props
.
onChange
(
'shelfState'
,
'NO'
)
shelfStateChange
=
()
=>
{
if
(
this
.
props
.
data
.
shelfState
===
'NO'
)
{
this
.
props
.
onChange
(
'shelfState'
,
'YES'
);
}
else
{
this
.
props
.
onChange
(
'shelfState'
,
'NO'
);
}
}
}
;
render
()
{
const
{
data
:
{
id
,
whetherVisitorsJoin
,
courseMedia
,
introduce
,
shelfState
,
loadcourseMedia
,
loadintroduce
}
}
=
this
.
props
;
const
{
data
:
{
id
,
whetherVisitorsJoin
,
courseMedia
,
introduce
,
shelfState
,
loadcourseMedia
,
loadintroduce
},
}
=
this
.
props
;
const
{
showSelectFileModal
,
selectType
}
=
this
.
state
;
return
(
<
div
className=
"add-video__intro-info"
>
<
div
className=
"allow-tourist-join"
>
<
span
className=
"label"
>
观看设置:
</
span
>
<
div
className=
"content"
>
<
div
className=
'add-video__intro-info'
>
<
div
className=
'allow-tourist-join'
>
<
span
className=
'label'
>
观看设置:
</
span
>
<
div
className=
'content'
>
<
div
>
<
Switch
checked=
{
whetherVisitorsJoin
===
"YES"
?
true
:
false
}
onChange=
{
this
.
whetherVisitorsJoinChange
}
/>
</
div
>
<
Switch
checked=
{
whetherVisitorsJoin
===
'YES'
?
true
:
false
}
onChange=
{
this
.
whetherVisitorsJoinChange
}
/>
</
div
>
<
div
>
<
div
className=
"desc"
>
<
div
className=
'desc'
>
<
div
>
开启:允许未绑定手机号的学员观看
</
div
>
<
div
>
关闭:仅限绑定了手机号的学员可以进入观看图文课
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"store-show"
>
<
span
className=
"label"
>
学院展示:
</
span
>
<
div
className=
"content"
>
<
Row
>
<
Col
span=
{
3
}
>
<
Switch
checked=
{
shelfState
===
"YES"
?
true
:
false
}
onChange=
{
this
.
shelfStateChange
}
/>
</
Col
>
<
Col
span=
{
21
}
>
<
div
className=
"desc"
>
<
div
>
开启:图文课将在学员学院图文课列表中展示
</
div
>
<
div
>
关闭:图文课将在学员学院图文课列表中隐藏
</
div
>
</
div
>
</
Col
>
</
Row
>
<
div
className=
'store-show'
>
<
span
className=
'label'
>
学院展示:
</
span
>
<
div
className=
'content'
>
<
Row
>
<
Col
span=
{
3
}
>
<
Switch
checked=
{
shelfState
===
'YES'
?
true
:
false
}
onChange=
{
this
.
shelfStateChange
}
/>
</
Col
>
<
Col
span=
{
21
}
>
<
div
className=
'desc'
>
<
div
>
开启:图文课将在学员学院图文课列表中展示
</
div
>
<
div
>
关闭:图文课将在学员学院图文课列表中隐藏
</
div
>
</
div
>
</
Col
>
</
Row
>
</
div
>
</
div
>
<
div
className=
"introduce required"
>
<
span
className=
"label"
style=
{
{
marginTop
:
5
}
}
>
课程内容:
</
span
>
<
div
className=
"content"
>
<
div
className=
"intro-list"
>
<
div
className=
"intro-list__item content-editor"
>
{
(
!
id
||
loadcourseMedia
)
&&
<
div
className=
'introduce required'
>
<
span
className=
'label'
style=
{
{
marginTop
:
5
}
}
>
课程内容:
</
span
>
<
div
className=
'content'
>
<
div
className=
'intro-list'
>
<
div
className=
'intro-list__item content-editor'
>
{
(
!
id
||
loadcourseMedia
)
&&
(
<
GraphicsEditor
id=
"content"
id=
'content'
detail=
{
{
content
:
courseMedia
content
:
courseMedia
,
}
}
onChange=
{
(
val
)
=>
{
this
.
changeDetail
(
val
);
}
}
onChange=
{
(
val
)
=>
{
this
.
changeDetail
(
val
)
}
}
/>
}
)
}
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"introduce"
>
<
span
className=
"label"
>
课程简介:
</
span
>
<
div
className=
"content"
>
<
div
className=
"intro-list"
>
<
div
className=
"intro-list__item introduce-editor"
>
{
(
!
id
||
loadintroduce
)
&&
<
div
className=
'introduce'
>
<
span
className=
'label'
>
课程简介:
</
span
>
<
div
className=
'content'
>
<
div
className=
'intro-list'
>
<
div
className=
'intro-list__item introduce-editor'
>
{
(
!
id
||
loadintroduce
)
&&
(
<
GraphicsEditor
id=
"intro"
id=
'intro'
isIntro=
{
true
}
detail=
{
{
content
:
introduce
content
:
introduce
,
}
}
onChange=
{
(
val
)
=>
{
this
.
changeIntro
(
val
);
}
}
onChange=
{
(
val
)
=>
{
this
.
changeIntro
(
val
)
}
}
/>
}
)
}
</
div
>
</
div
>
</
div
>
</
div
>
{
/* 选择暖场图文件弹窗 */
}
{
showSelectFileModal
&&
{
showSelectFileModal
&&
(
<
SelectPrepareFileModal
operateType=
"select"
accept=
{
selectType
===
"INTRO"
?
"image/jpeg,image/png,image/jpg"
:
"video/mp4,image/jpeg,image/png,image/jpg"
}
selectTypeList=
{
selectType
===
"INTRO"
?
[
'JPG'
,
'JPEG'
,
'PNG'
]:
[
'MP4'
,
'JPG'
,
'JPEG'
,
'PNG'
]
}
tooltip=
{
selectType
===
"INTRO"
?
'支持文件类型:jpg、jpeg、png'
:
'支持文件类型:jpg、jpeg、png、mp4'
}
operateType=
'select'
accept=
{
selectType
===
'INTRO'
?
'image/jpeg,image/png,image/jpg'
:
'video/mp4,image/jpeg,image/png,image/jpg'
}
selectTypeList=
{
selectType
===
'INTRO'
?
[
'JPG'
,
'JPEG'
,
'PNG'
]
:
[
'MP4'
,
'JPG'
,
'JPEG'
,
'PNG'
]
}
tooltip=
{
selectType
===
'INTRO'
?
'支持文件类型:jpg、jpeg、png'
:
'支持文件类型:jpg、jpeg、png、mp4'
}
isOpen=
{
showSelectFileModal
}
onClose=
{
()
=>
{
this
.
setState
({
showSelectFileModal
:
false
})
this
.
setState
({
showSelectFileModal
:
false
})
;
}
}
onSelect=
{
this
.
handleSelectVideo
}
/>
}
)
}
</
div
>
)
)
;
}
}
...
...
src/modules/course-manage/offline-course/components/OfflineCourseList.jsx
View file @
1bf6cc7a
...
...
@@ -17,6 +17,7 @@ import OfflineCourseData from '@/modules/course-manage/offline-course/OfflineCou
import
{
Dropdown
,
message
,
Modal
,
Switch
,
Tooltip
}
from
'antd'
;
import
moment
from
'moment'
;
import
React
from
'react'
;
import
{
find
,
reduce
,
last
}
from
'underscore'
;
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
ENUM
from
'../../../knowledge-base/ENUM.js'
;
import
PreviewOfflineModal
from
'../modal/PreviewOfflineModal'
;
...
...
@@ -44,7 +45,7 @@ class OfflineCourseList extends React.Component {
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
''
;
planArray
.
map
((
item
,
index
)
=>
{
planArray
.
forEach
((
item
,
index
)
=>
{
if
(
index
<
planArray
.
length
-
1
)
{
planStr
=
planStr
+
item
.
planName
+
'、'
;
}
else
{
...
...
@@ -64,13 +65,13 @@ class OfflineCourseList extends React.Component {
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
)
=>
{
reduce
(
calendarTime
,
(
a
,
b
)
=>
{
isContinue
=
isContinue
&&
b
-
a
===
86400000
;
return
b
;
});
const
lastTime
=
_
.
last
(
calendarTime
);
const
lastTime
=
last
(
calendarTime
);
const
time
=
`
${
!
isContinue
?
calendarTime
.
map
((
item
)
=>
moment
(
item
).
format
(
'MM-DD'
)).
join
(
'、'
)
...
...
@@ -138,7 +139,9 @@ class OfflineCourseList extends React.Component {
width
:
120
,
dataIndex
:
'courseware'
,
render
:
(
val
,
item
,
index
)
=>
{
return
<
Switch
disabled=
{
item
.
courseState
===
'EXPIRED'
}
checked=
{
item
.
shelfState
===
'YES'
}
onChange=
{
()
=>
this
.
changeShelfState
(
item
)
}
/>;
return
(
<
Switch
size=
'small'
disabled=
{
item
.
courseState
===
'EXPIRED'
}
checked=
{
item
.
shelfState
===
'YES'
}
onChange=
{
()
=>
this
.
changeShelfState
(
item
)
}
/>
);
},
},
{
...
...
src/modules/course-manage/video-course/components/AddVideoIntro.jsx
View file @
1bf6cc7a
/*
* @Author: 吴文洁
* @Date: 2020-07-16 11:05:17
* @Author: 吴文洁
* @Date: 2020-07-16 11:05:17
* @Last Modified by: chenshu
* @Last Modified time: 2021-04-06 16:44:09
* @Description: 添加直播-简介
*/
import
SelectPrepareFileModal
from
'@/modules/prepare-lesson/modal/SelectPrepareFileModal'
;
import
{
Col
,
message
,
Row
,
Switch
}
from
'antd'
;
import
React
from
'react'
;
import
{
Input
,
message
,
Upload
,
Radio
,
Row
,
Col
,
Button
,
Popover
,
Switch
}
from
'antd'
;
import
Service
from
'@/common/js/service'
;
import
GraphicsEditor
from
'../../components/GraphicsEditor'
;
import
User
from
'@/common/js/user'
;
import
UploadOss
from
'@/core/upload'
;
import
{
filter
}
from
'underscore'
;
import
'./AddVideoIntro.less'
;
import
SelectPrepareFileModal
from
'@/modules/prepare-lesson/modal/SelectPrepareFileModal'
;
import
{
DISK_MAP
}
from
'@/common/constants/academic/lessonEnum'
;
import
{
ImgCutModalNew
}
from
'@/components'
;
const
{
TextArea
}
=
Input
;
const
defaultCover
=
'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1599635741526.png'
;
class
AddVideoIntro
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
warmUrl
:
defaultCover
,
showSelectFileModal
:
false
,
diskList
:
[],
selectType
:
null
}
selectType
:
null
,
}
;
}
// 上传封面图
handleShowImgCutModal
=
(
event
)
=>
{
const
imageFile
=
event
.
target
.
files
[
0
];
if
(
!
imageFile
)
return
;
if
(
!
imageFile
)
return
;
this
.
setState
({
imageFile
,
showCutModal
:
true
,
});
}
}
;
// 选择暖场资源
handleSelectVideo
=
(
file
)
=>
{
const
{
selectType
}
=
this
.
state
;
// 选择暖场资源
handleSelectVideo
=
(
file
)
=>
{
const
{
selectType
}
=
this
.
state
;
this
.
setState
({
showSelectFileModal
:
false
})
showSelectFileModal
:
false
,
})
;
const
{
ossUrl
,
resourceId
,
folderName
,
folderFormat
,
folderSize
}
=
file
;
if
(
selectType
===
'WARMUP'
)
{
if
(
selectType
===
'WARMUP'
)
{
const
liveCourseWarmMedia
=
{
contentType
:
'WARMUP'
,
mediaType
:
folderFormat
===
'MP4'
?
'VIDEO'
:
'PICTURE'
,
mediaContent
:
resourceId
,
mediaUrl
:
ossUrl
,
mediaName
:
folderName
,
size
:
folderSize
}
size
:
folderSize
,
}
;
this
.
props
.
onChange
(
'liveCourseWarmMedia'
,
liveCourseWarmMedia
);
}
else
{
// 最多添加九图片
const
{
liveCourseMediaRequests
}
=
this
.
props
.
data
;
}
else
{
// 最多添加九图片
const
{
liveCourseMediaRequests
}
=
this
.
props
.
data
;
const
list
=
_
.
filter
(
liveCourseMediaRequests
,
(
item
)
=>
{
return
item
.
mediaType
==
"PICTURE"
;
});
if
(
list
.
length
>
8
)
{
message
.
warning
(
"最多添加9张图片"
);
return
;
}
liveCourseMediaRequests
.
push
({
contentType
:
'INTRO'
,
size
:
folderSize
,
mediaName
:
folderName
,
mediaContent
:
resourceId
,
mediaType
:
'PICTURE'
,
mediaUrl
:
ossUrl
,
});
this
.
props
.
onChange
(
'liveCourseMediaRequests'
,
liveCourseMediaRequests
);
const
list
=
filter
(
liveCourseMediaRequests
,
(
item
)
=>
{
return
item
.
mediaType
===
'PICTURE'
;
});
if
(
list
.
length
>
8
)
{
message
.
warning
(
'最多添加9张图片'
);
return
;
}
liveCourseMediaRequests
.
push
({
contentType
:
'INTRO'
,
size
:
folderSize
,
mediaName
:
folderName
,
mediaContent
:
resourceId
,
mediaType
:
'PICTURE'
,
mediaUrl
:
ossUrl
,
});
this
.
props
.
onChange
(
'liveCourseMediaRequests'
,
liveCourseMediaRequests
);
}
}
};
changeIntro
=
(
value
)
=>
{
this
.
props
.
onChange
(
'introduce'
,
value
);
}
}
;
handleUpload
=
(
Blob
)
=>
{
this
.
setState
({
showSelectFileModal
:
true
,
selectType
:
'INTRO'
})
}
whetherVisitorsJoinChange
=
()
=>
{
if
(
this
.
props
.
data
.
whetherVisitorsJoin
===
"NO"
)
{
this
.
props
.
onChange
(
'whetherVisitorsJoin'
,
'YES'
)
}
else
{
this
.
props
.
onChange
(
'whetherVisitorsJoin'
,
'NO'
)
selectType
:
'INTRO'
,
})
;
}
;
whetherVisitorsJoinChange
=
()
=>
{
if
(
this
.
props
.
data
.
whetherVisitorsJoin
===
'NO'
)
{
this
.
props
.
onChange
(
'whetherVisitorsJoin'
,
'YES'
);
}
else
{
this
.
props
.
onChange
(
'whetherVisitorsJoin'
,
'NO'
);
}
}
shelfStateChange
=
()
=>
{
if
(
this
.
props
.
data
.
shelfState
===
"NO"
)
{
this
.
props
.
onChange
(
'shelfState'
,
'YES'
)
}
else
{
this
.
props
.
onChange
(
'shelfState'
,
'NO'
)
}
;
shelfStateChange
=
()
=>
{
if
(
this
.
props
.
data
.
shelfState
===
'NO'
)
{
this
.
props
.
onChange
(
'shelfState'
,
'YES'
);
}
else
{
this
.
props
.
onChange
(
'shelfState'
,
'NO'
);
}
}
}
;
render
()
{
const
{
data
:
{
whetherVisitorsJoin
,
liveCourseMediaRequests
=
[],
shelfState
,
id
,
introduce
,
loadintroduce
}
}
=
this
.
props
;
const
{
showSelectFileModal
,
selectType
}
=
this
.
state
const
{
data
:
{
whetherVisitorsJoin
,
shelfState
,
id
,
introduce
,
loadintroduce
},
}
=
this
.
props
;
const
{
showSelectFileModal
,
selectType
}
=
this
.
state
;
return
(
<
div
className=
"add-video__intro-info"
>
<
div
className=
"allow-tourist-join"
>
<
span
className=
"label"
>
观看设置:
</
span
>
<
div
className=
"content"
>
<
div
className=
'add-video__intro-info'
>
<
div
className=
'allow-tourist-join'
>
<
span
className=
'label'
>
观看设置:
</
span
>
<
div
className=
'content'
>
<
div
>
<
Switch
checked=
{
whetherVisitorsJoin
===
"YES"
?
true
:
false
}
onChange=
{
this
.
whetherVisitorsJoinChange
}
/>
</
div
>
<
Switch
checked=
{
whetherVisitorsJoin
===
'YES'
?
true
:
false
}
onChange=
{
this
.
whetherVisitorsJoinChange
}
/>
</
div
>
<
div
>
<
div
className=
"desc"
>
<
div
className=
'desc'
>
<
div
>
开启:允许未绑定手机号的学员观看
</
div
>
<
div
>
关闭:仅限绑定了手机号的学员可以进入观看视频
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
<
div
className=
"store-show"
>
<
span
className=
"label"
>
学院展示:
</
span
>
<
div
className=
"content"
>
<
Row
>
<
Col
span=
{
3
}
>
<
Switch
checked=
{
shelfState
===
"YES"
?
true
:
false
}
onChange=
{
this
.
shelfStateChange
}
/>
</
Col
>
<
Col
span=
{
21
}
>
<
div
className=
"desc"
>
<
div
>
开启:此视频将在学员学院的视频列表中出现
</
div
>
<
div
>
关闭:此视频将在学员学院的视频列表中隐藏
</
div
>
</
div
>
</
Col
>
</
Row
>
<
div
className=
'store-show'
>
<
span
className=
'label'
>
学院展示:
</
span
>
<
div
className=
'content'
>
<
Row
>
<
Col
span=
{
3
}
>
<
Switch
checked=
{
shelfState
===
'YES'
?
true
:
false
}
onChange=
{
this
.
shelfStateChange
}
/>
</
Col
>
<
Col
span=
{
21
}
>
<
div
className=
'desc'
>
<
div
>
开启:此视频将在学员学院的视频列表中出现
</
div
>
<
div
>
关闭:此视频将在学员学院的视频列表中隐藏
</
div
>
</
div
>
</
Col
>
</
Row
>
</
div
>
</
div
>
<
div
className=
"introduce"
>
<
span
className=
"label"
>
视频课简介:
</
span
>
<
div
className=
"content"
>
<
div
className=
"intro-list"
>
<
div
className=
"intro-list__item introduce-editor"
>
{
(
!
id
||
loadintroduce
)
&&
<
div
className=
'introduce'
>
<
span
className=
'label'
>
视频课简介:
</
span
>
<
div
className=
'content'
>
<
div
className=
'intro-list'
>
<
div
className=
'intro-list__item introduce-editor'
>
{
(
!
id
||
loadintroduce
)
&&
(
<
GraphicsEditor
id=
"intro"
id=
'intro'
isIntro=
{
true
}
detail=
{
{
content
:
introduce
content
:
introduce
,
}
}
onChange=
{
(
val
)
=>
{
this
.
changeIntro
(
val
);
}
}
onChange=
{
(
val
)
=>
{
this
.
changeIntro
(
val
)
}
}
/>
}
)
}
</
div
>
</
div
>
</
div
>
</
div
>
{
/* 选择暖场图文件弹窗 */
}
{
showSelectFileModal
&&
{
showSelectFileModal
&&
(
<
SelectPrepareFileModal
operateType=
"select"
accept=
{
selectType
===
"INTRO"
?
"image/jpeg,image/png,image/jpg"
:
"video/mp4,image/jpeg,image/png,image/jpg"
}
selectTypeList=
{
selectType
===
"INTRO"
?
[
'JPG'
,
'JPEG'
,
'PNG'
]:
[
'MP4'
,
'JPG'
,
'JPEG'
,
'PNG'
]
}
tooltip=
{
selectType
===
"INTRO"
?
'支持文件类型:jpg、jpeg、png'
:
'支持文件类型:jpg、jpeg、png、mp4'
}
operateType=
'select'
accept=
{
selectType
===
'INTRO'
?
'image/jpeg,image/png,image/jpg'
:
'video/mp4,image/jpeg,image/png,image/jpg'
}
selectTypeList=
{
selectType
===
'INTRO'
?
[
'JPG'
,
'JPEG'
,
'PNG'
]
:
[
'MP4'
,
'JPG'
,
'JPEG'
,
'PNG'
]
}
tooltip=
{
selectType
===
'INTRO'
?
'支持文件类型:jpg、jpeg、png'
:
'支持文件类型:jpg、jpeg、png、mp4'
}
isOpen=
{
showSelectFileModal
}
onClose=
{
()
=>
{
this
.
setState
({
showSelectFileModal
:
false
})
this
.
setState
({
showSelectFileModal
:
false
})
;
}
}
onSelect=
{
this
.
handleSelectVideo
}
/>
}
)
}
</
div
>
)
)
;
}
}
...
...
src/modules/course-manage/video-course/components/VideoCourseList.jsx
View file @
1bf6cc7a
...
...
@@ -159,6 +159,7 @@ class VideoCourseList extends React.Component {
render
:
(
val
,
item
,
index
)
=>
{
return
(
<
Switch
size=
'small'
loading=
{
ShelfLoading
}
checked=
{
item
.
shelfState
===
'YES'
}
defaultChecked=
{
item
.
shelfState
}
...
...
src/modules/plan-manage/components/BasicInfo.jsx
View file @
1bf6cc7a
...
...
@@ -7,17 +7,16 @@
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import
React
from
'react'
;
import
{
Button
,
Input
,
Switch
,
Radio
,
Row
,
Col
,
Modal
,
message
,
Tooltip
}
from
'antd'
;
import
{
Button
,
Input
,
Switch
,
Radio
,
Row
,
Col
,
message
,
Tooltip
}
from
'antd'
;
import
{
withRouter
}
from
'react-router-dom'
;
import
SelectOperatorModal
from
'../modal/SelectOperatorModal'
;
import
SelectPrepareFileModal
from
'@/modules/prepare-lesson/modal/SelectPrepareFileModal'
;
import
Upload
from
'@/core/upload'
;
import
ImgClipModal
from
'@/components/ImgClipModal'
import
ImgClipModal
from
'@/components/ImgClipModal'
;
import
'./BasicInfo.less'
;
const
{
TextArea
}
=
Input
;
const
defaultCover
=
'https://image.xiaomaiketang.com/xm/rEAetaTEh3.png'
;
let
cutFlag
=
false
;
class
BasicInfo
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
...
...
@@ -74,7 +73,7 @@ class BasicInfo extends React.Component {
handleSelectCover
=
(
file
)
=>
{
this
.
setState
({
visible
:
true
,
imageFile
:
file
imageFile
:
file
,
});
};
//获取resourceId
...
...
@@ -125,7 +124,7 @@ class BasicInfo extends React.Component {
};
render
()
{
const
{
operatorModalVisible
,
showSelectFileModal
,
visible
,
hasImgReady
,
cutImageBlob
,
imageFile
}
=
this
.
state
;
const
{
operatorModalVisible
,
showSelectFileModal
,
visible
,
imageFile
}
=
this
.
state
;
const
{
data
}
=
this
.
props
;
const
{
planName
,
coverUrl
,
instro
,
enableState
,
operateType
,
selectOperatorList
,
percentCompleteLive
,
percentCompleteVideo
,
percentCompletePicture
}
=
data
;
...
...
@@ -325,9 +324,16 @@ class BasicInfo extends React.Component {
onSelect=
{
this
.
handleSelectCover
}
/>
)
}
{
visible
&&
<
ImgClipModal
visible=
{
visible
}
imgUrl=
{
imageFile
.
ossUrl
}
onConfirm=
{
this
.
getSignature
}
onClose=
{
()
=>
{
this
.
setState
({
visible
:
false
});}
}
/>
}
{
visible
&&
(
<
ImgClipModal
visible=
{
visible
}
imgUrl=
{
imageFile
.
ossUrl
}
onConfirm=
{
this
.
getSignature
}
onClose=
{
()
=>
{
this
.
setState
({
visible
:
false
});
}
}
/>
)
}
</
div
>
);
}
...
...
src/modules/plan-manage/components/PlanList.jsx
View file @
1bf6cc7a
...
...
@@ -64,6 +64,7 @@ function PlanList(props) {
render
:
(
val
,
item
,
index
)
=>
{
return
(
<
Switch
size=
'small'
checked=
{
item
.
enableState
===
'NO'
?
false
:
true
}
onChange=
{
()
=>
changeEnableState
(
item
)
}
disabled=
{
User
.
getUserRole
()
===
'CloudManager'
||
User
.
getUserRole
()
===
'StoreManager'
?
false
:
true
}
...
...
src/modules/teach-tool/examination-manager/AddExam.tsx
View file @
1bf6cc7a
import
React
,
{
useState
,
useRef
,
useEffect
,
useContext
}
from
'react'
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
{
Form
,
Alert
,
Input
,
Button
,
InputNumber
,
DatePicker
,
Switch
,
Radio
,
message
,
Modal
,
Tooltip
}
from
'antd
'
;
import
{
Route
,
withRouter
}
from
'react-router-dom
'
;
import
User
from
"@/common/js/user"
;
import
moment
from
'moment'
import
Service
from
"@/common/js/service"
;
import
_
from
'underscore'
import
Service
from
'@/common/js/service'
;
import
User
from
'@/common/js/user'
;
import
Breadcrumbs
from
'@/components/Breadcrumbs
'
;
import
ShowTips
from
'@/components/ShowTips
'
;
import
{
Button
,
DatePicker
,
Form
,
Input
,
InputNumber
,
message
,
Modal
,
Radio
,
Switch
,
Tooltip
}
from
'antd'
;
import
moment
from
'moment'
;
import
React
,
{
useEffect
,
useRef
,
useState
}
from
'react'
;
import
{
withRouter
}
from
'react-router-dom'
;
import
GraphicsEditor
from
'../../course-manage/components/GraphicsEditor'
;
import
SelectPaperModal
from
'./SelectPaperModal'
import
PreviewModal
from
'./PreviewModal'
import
ShowTips
from
"@/components/ShowTips"
;
import
'./AddExam.less'
;
import
PreviewModal
from
'./PreviewModal'
;
import
SelectPaperModal
from
'./SelectPaperModal'
;
const
{
RangePicker
}
=
DatePicker
;
function
AddExam
(
props
:
any
)
{
const
paperInfoInit
:
any
=
{
passScore
:
60
};
const
[
showModal
,
setShowModal
]
=
useState
(
false
);
const
[
paperInfo
,
setPaperInfo
]
=
useState
(
paperInfoInit
);
const
[
paperId
,
setPaperId
]
=
useState
(
''
);
const
[
passRate
,
setPassRate
]
=
useState
(
60
);
//及格线
const
[
examStartTime
,
setStartTime
]
=
useState
(
''
);
const
[
examEndTime
,
setExamEndTime
]
=
useState
(
''
);
const
[
examName
,
setExamName
]
=
useState
(
''
);
const
[
needPhone
,
setNeedPhone
]
=
useState
(
'DO_NOT_NEED_PHONE_VERIFY'
);
const
[
needOptionDisorder
,
setNeedOptionDisorder
]
=
useState
(
'OPTION_SORT'
);
const
[
resultContent
,
setResultContent
]
=
useState
(
'PASS_AND_SCORE'
);
const
[
answerAnalysis
,
setAnswerAnalysis
]
=
useState
(
'RIGHT_OR_WRONG'
);
const
[
resultShow
,
setResultShow
]
=
useState
(
'IMMEDIATELY'
);
const
[
examDesc
,
setExamDesc
]
=
useState
(
''
);
const
[
passScore
,
setPassScore
]
=
useState
(
100
);
const
[
desclen
,
setDescLen
]
=
useState
(
0
);
const
[
check
,
setCheck
]
=
useState
(
false
);
const
[
getData
,
setGetData
]
=
useState
(
false
);
const
[
preview
,
setPreview
]
=
useState
(
false
);
const
[
examTotal
,
setExamTotal
]
=
useState
(
0
);
const
request
=
useRef
(
false
);
const
{
match
}
=
props
;
const
[
examDuration
,
setExamDuration
]
=
useState
(
undefined
);
useEffect
(()
=>
{
switch
(
props
.
type
)
{
case
"copy"
:
// 考试列表-复制考试进入
case
"edit"
:
// 考试列表-编辑考试进入
queryExamDetail
();
break
;
case
"organizeExam"
:
// 试卷列表-组织考试进入
case
"newPaperToAddExam"
:
// 组卷页面-新建保存试卷并组织考试
case
"editPaperToAddExam"
:
// 组卷页面-编辑保存试卷并组织考试
setGetData
(
true
);
setPaperInfo
(
props
.
paperInfo
);
break
;
}
},
[])
useEffect
(()
=>
{
setPaperId
(
paperInfo
.
paperId
)
setPassRate
(
paperInfo
.
passRate
)
},
[
paperInfo
.
paperId
])
useEffect
(()
=>
{
setPassScore
(
Math
.
round
((
paperInfo
.
totalScore
||
0
)
*
(
passRate
||
0
)
as
any
/
100
))
setExamTotal
(
paperInfo
.
singleChoiceCnt
+
paperInfo
.
multiChoiceCnt
+
paperInfo
.
judgeCnt
+
paperInfo
.
gapFillingCnt
+
paperInfo
.
indefiniteChoiceCnt
||
0
)
},
[
paperInfo
.
paperId
,
passRate
])
function
disabledDate
(
current
:
any
)
{
// Can not select days before today and today
return
current
&&
current
<
moment
().
startOf
(
'day'
);
const
paperInfoInit
:
any
=
{
passScore
:
60
};
const
[
showModal
,
setShowModal
]
=
useState
(
false
);
const
[
paperInfo
,
setPaperInfo
]
=
useState
(
paperInfoInit
);
const
[
paperId
,
setPaperId
]
=
useState
(
''
);
const
[
passRate
,
setPassRate
]
=
useState
(
60
);
//及格线
const
[
examStartTime
,
setStartTime
]
=
useState
(
''
);
const
[
examEndTime
,
setExamEndTime
]
=
useState
(
''
);
const
[
examName
,
setExamName
]
=
useState
(
''
);
const
[
needPhone
,
setNeedPhone
]
=
useState
(
'DO_NOT_NEED_PHONE_VERIFY'
);
const
[
needOptionDisorder
,
setNeedOptionDisorder
]
=
useState
(
'OPTION_SORT'
);
const
[
resultContent
,
setResultContent
]
=
useState
(
'PASS_AND_SCORE'
);
const
[
answerAnalysis
,
setAnswerAnalysis
]
=
useState
(
'RIGHT_OR_WRONG'
);
const
[
resultShow
,
setResultShow
]
=
useState
(
'IMMEDIATELY'
);
const
[
examDesc
,
setExamDesc
]
=
useState
(
''
);
const
[
passScore
,
setPassScore
]
=
useState
(
100
);
const
[
desclen
,
setDescLen
]
=
useState
(
0
);
const
[
check
,
setCheck
]
=
useState
(
false
);
const
[
getData
,
setGetData
]
=
useState
(
false
);
const
[
preview
,
setPreview
]
=
useState
(
false
);
const
[
examTotal
,
setExamTotal
]
=
useState
(
0
);
const
request
=
useRef
(
false
);
const
{
match
}
=
props
;
const
[
examDuration
,
setExamDuration
]
=
useState
(
undefined
);
useEffect
(()
=>
{
switch
(
props
.
type
)
{
case
'copy'
:
// 考试列表-复制考试进入
case
'edit'
:
// 考试列表-编辑考试进入
queryExamDetail
();
break
;
case
'organizeExam'
:
// 试卷列表-组织考试进入
case
'newPaperToAddExam'
:
// 组卷页面-新建保存试卷并组织考试
case
'editPaperToAddExam'
:
// 组卷页面-编辑保存试卷并组织考试
setGetData
(
true
);
setPaperInfo
(
props
.
paperInfo
);
break
;
}
},
[
props
.
paperInfo
,
props
.
type
,
queryExamDetail
]);
useEffect
(()
=>
{
setPaperId
(
paperInfo
.
paperId
);
setPassRate
(
paperInfo
.
passRate
);
},
[
paperInfo
.
paperId
,
paperInfo
.
passRate
]);
useEffect
(()
=>
{
setPassScore
(
Math
.
round
((((
paperInfo
.
totalScore
||
0
)
*
(
passRate
||
0
))
as
any
)
/
100
));
setExamTotal
(
paperInfo
.
singleChoiceCnt
+
paperInfo
.
multiChoiceCnt
+
paperInfo
.
judgeCnt
+
paperInfo
.
gapFillingCnt
+
paperInfo
.
indefiniteChoiceCnt
||
0
);
},
[
paperInfo
.
gapFillingCnt
,
paperInfo
.
indefiniteChoiceCnt
,
paperInfo
.
judgeCnt
,
paperInfo
.
multiChoiceCnt
,
paperInfo
.
paperId
,
paperInfo
.
singleChoiceCnt
,
paperInfo
.
totalScore
,
passRate
,
]);
function
disabledDate
(
current
:
any
)
{
// Can not select days before today and today
return
current
&&
current
<
moment
().
startOf
(
'day'
);
}
function
queryExamDetail
()
{
Service
.
Hades
(
'public/hades/queryExamDetail'
,
{
examId
:
match
.
params
.
id
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
,
}).
then
((
res
)
=>
{
const
{
result
}
=
res
;
setPaperInfo
(
result
.
examPaper
);
setPaperId
(
result
.
examPaper
.
paperId
);
setStartTime
(
props
.
type
===
'edit'
?
result
.
examStartTime
:
''
);
setExamEndTime
(
props
.
type
===
'edit'
?
result
.
examEndTime
:
''
);
setExamName
(
props
.
type
===
'edit'
?
result
.
examName
:
`
${
result
.
examName
}
(复制)`
);
setPassRate
(
result
.
passRate
*
100
);
setNeedPhone
(
result
.
needPhone
);
setExamDesc
(
result
.
examDesc
);
setExamDuration
((
result
.
examDuration
/
60
/
1000
)
as
any
);
setAnswerAnalysis
(
result
.
answerAnalysis
);
setNeedOptionDisorder
(
result
.
needOptionDisorder
);
setPassScore
(
result
.
passScore
);
setResultContent
(
result
.
resultContent
);
setResultShow
(
result
.
resultShow
);
setGetData
(
true
);
});
}
function
handleSave
()
{
if
(
request
.
current
)
{
return
;
}
setCheck
(
true
);
const
param
=
{
paperId
,
startTime
:
examStartTime
,
endTime
:
examEndTime
,
examName
,
passRate
:
passRate
/
100
,
examStartTime
,
examEndTime
,
examDesc
,
needPhone
,
needOptionDisorder
,
resultContent
,
answerAnalysis
,
resultShow
,
examDuration
:
(
examDuration
||
0
)
*
60
*
1000
,
passScore
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
,
examId
:
''
,
};
if
(
!
param
.
examName
)
{
message
.
warning
(
'请输入考试名称'
);
return
;
}
if
(
param
.
examName
&&
param
.
examName
.
length
>
40
)
{
message
.
warning
(
'考试名称最多40字'
);
return
;
}
function
queryExamDetail
()
{
Service
.
Hades
(
"public/hades/queryExamDetail"
,
{
examId
:
match
.
params
.
id
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
}).
then
((
res
)
=>
{
const
{
result
}
=
res
setPaperInfo
(
result
.
examPaper
)
setPaperId
(
result
.
examPaper
.
paperId
)
setStartTime
(
props
.
type
===
'edit'
?
result
.
examStartTime
:
''
)
setExamEndTime
(
props
.
type
===
'edit'
?
result
.
examEndTime
:
''
)
setExamName
(
props
.
type
===
'edit'
?
result
.
examName
:
`
${
result
.
examName
}
(复制)`
)
setPassRate
(
result
.
passRate
*
100
)
setNeedPhone
(
result
.
needPhone
)
setExamDesc
(
result
.
examDesc
)
setExamDuration
(
result
.
examDuration
/
60
/
1000
as
any
)
setAnswerAnalysis
(
result
.
answerAnalysis
)
setNeedOptionDisorder
(
result
.
needOptionDisorder
)
setPassScore
(
result
.
passScore
)
setResultContent
(
result
.
resultContent
)
setResultShow
(
result
.
resultShow
)
setGetData
(
true
)
})
if
(
!
paperId
)
{
message
.
warning
(
'请选择试卷'
);
return
;
}
function
handleSave
()
{
if
(
request
.
current
)
{
return
}
if
(
!
passRate
)
{
message
.
warning
(
'请输入及格线'
);
return
;
}
if
(
!
examStartTime
||
!
examEndTime
)
{
message
.
warning
(
'请选择考试起止时间'
);
return
;
}
if
(
Number
(
examStartTime
)
<
moment
().
valueOf
())
{
message
.
warning
(
'开始时间不能早于现在'
);
return
;
}
if
(
!
examDuration
)
{
message
.
warning
(
'请输入考试时长'
);
return
;
}
setCheck
(
true
);
const
param
=
{
if
(
examStartTime
+
(
examDuration
as
any
)
*
60
*
1000
>
examEndTime
)
{
message
.
warning
(
'考试时长不得超过考试有效期时长'
);
return
;
}
if
(
desclen
>
1000
)
{
message
.
warning
(
'内容过长,不能超过1000字'
);
return
;
}
request
.
current
=
true
;
setTimeout
(()
=>
{
request
.
current
=
false
;
},
2000
);
if
(
props
.
type
===
'edit'
)
{
param
.
examId
=
match
.
params
.
id
;
}
Service
.
Hades
(
props
.
type
===
'edit'
?
'public/hades/editExam'
:
'public/hades/createExam'
,
param
).
then
((
res
)
=>
{
message
.
success
(
props
.
type
===
'edit'
?
'编辑成功'
:
'创建成功'
);
switch
(
props
.
type
)
{
case
'organizeExam'
:
// 试卷列表-组织考试进入
case
'newPaperToAddExam'
:
// 组卷保存组织考试
case
'editPaperToAddExam'
:
window
.
RCHistory
.
push
(
'/examination-manage-index'
);
break
;
case
'add'
:
case
'edit'
:
// 考试列表-新建或编辑
case
'copy'
:
// 考试列表-新建或编辑
props
.
freshList
();
props
.
history
.
goBack
();
break
;
}
});
}
function
disabledRangeTime
(
date
:
any
,
type
:
any
)
{
if
(
moment
(
date
).
isSame
(
moment
(),
'day'
))
{
return
{
disabledHours
:
()
=>
{
const
hours
=
[];
for
(
let
i
=
0
;
i
<
moment
().
hour
();
i
++
)
{
hours
.
push
(
i
);
}
return
hours
;
},
disabledMinutes
:
()
=>
{
const
currentMinute
=
moment
().
minute
();
const
currentHour
=
moment
(
date
).
hour
();
const
minutes
=
[];
if
(
currentHour
===
moment
().
hour
())
{
for
(
let
i
=
0
;
i
<
currentMinute
;
i
++
)
{
minutes
.
push
(
i
);
}
}
return
minutes
;
},
};
}
return
{
disabledHours
:
()
=>
[],
disabledMinutes
:
()
=>
[],
disabledSeconds
:
()
=>
[],
};
}
function
handleGoBack
()
{
Modal
.
confirm
({
title
:
'确定要返回吗?'
,
content
:
'返回后,本次编辑的内容将不被保存'
,
okText
:
'确认返回'
,
cancelText
:
'留在本页'
,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
onOk
:
()
=>
{
window
.
RCHistory
.
push
(
'/examination-manage-index'
);
},
});
}
let
title
=
''
;
switch
(
props
.
type
)
{
case
'add'
:
case
'organizeExam'
:
case
'newPaperToAddExam'
:
case
'editPaperToAddExam'
:
title
=
'新建考试'
;
break
;
case
'edit'
:
title
=
'编辑考试'
;
break
;
case
'copy'
:
title
=
'复制考试'
;
break
;
default
:
break
;
}
return
(
<
div
className=
'page examPage'
>
<
Breadcrumbs
navList=
{
title
}
goBack=
{
handleGoBack
}
/>
<
div
className=
'box'
>
<
div
className=
'show-tips'
>
<
ShowTips
message=
'请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利'
/>
</
div
>
{
' '
}
<
div
className=
'form'
>
<
div
className=
'title'
>
基本信息
</
div
>
<
Form
labelCol=
{
{
span
:
3
}
}
wrapperCol=
{
{
span
:
14
}
}
layout=
'horizontal'
>
<
Form
.
Item
label=
'考试名称'
validateStatus=
{
check
&&
(
!
examName
?
'请输入考试名称'
:
examName
.
length
>
40
&&
'考试名称最多40字'
)
?
'error'
:
''
}
help=
{
check
&&
(
!
examName
?
'请输入考试名称'
:
examName
.
length
>
40
&&
'考试名称最多40字'
)
}
required
>
<
Input
placeholder=
'请输入考试名称(40字以内)'
maxLength=
{
40
}
value=
{
examName
}
onChange=
{
(
e
)
=>
{
setExamName
(
e
.
target
.
value
);
}
}
style=
{
{
width
:
320
}
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'选择试卷'
validateStatus=
{
check
&&
!
paperId
?
'error'
:
''
}
help=
{
check
&&
!
paperId
&&
'请选择试卷'
}
required
>
<
Button
onClick=
{
()
=>
{
setShowModal
(
true
);
}
}
>
{
paperInfo
.
paperId
?
'重新选择'
:
'选择试卷'
}
</
Button
>
{
paperInfo
.
paperId
&&
(
<
div
className=
'paperTitle'
>
<
img
src=
'https://image.xiaomaiketang.com/xm/pY5imEhjzw.png'
alt=
''
/>
{
paperInfo
.
paperName
}
</
div
>
)
}
{
paperInfo
.
paperId
&&
(
<
div
className=
'table'
>
<
div
className=
'header'
>
<
div
className=
'item'
>
单选题
</
div
>
<
div
className=
'item'
>
多选题
</
div
>
<
div
className=
'item'
>
判断题
</
div
>
<
div
className=
'item'
>
填空题
</
div
>
<
div
className=
'item long'
>
不定项选择题
</
div
>
<
div
className=
'item'
>
合计
</
div
>
</
div
>
<
div
className=
'body-list'
>
<
div
className=
'item'
>
{
paperInfo
.
singleChoiceCnt
||
0
}
题
</
div
>
<
div
className=
'item'
>
{
paperInfo
.
multiChoiceCnt
||
0
}
题
</
div
>
<
div
className=
'item'
>
{
paperInfo
.
judgeCnt
||
0
}
题
</
div
>
<
div
className=
'item'
>
{
paperInfo
.
gapFillingCnt
||
0
}
题
</
div
>
<
div
className=
'item long'
>
{
paperInfo
.
indefiniteChoiceCnt
||
0
}
题
</
div
>
<
div
className=
'item'
>
{
examTotal
}
题
</
div
>
</
div
>
<
div
className=
'body-list'
>
<
div
className=
'item'
>
{
paperInfo
.
singleChoiceScore
||
0
}
分
</
div
>
<
div
className=
'item'
>
{
paperInfo
.
multiChoiceScore
||
0
}
分
</
div
>
<
div
className=
'item'
>
{
paperInfo
.
judgeScore
||
0
}
分
</
div
>
<
div
className=
'item'
>
{
paperInfo
.
gapFillingScore
||
0
}
分
</
div
>
<
div
className=
'item long'
>
{
paperInfo
.
indefiniteChoiceScore
||
0
}
分
</
div
>
<
div
className=
'item'
>
{
paperInfo
.
totalScore
||
0
}
分
</
div
>
</
div
>
</
div
>
)
}
</
Form
.
Item
>
<
Form
.
Item
label=
{
<
div
>
<
span
>
及格线
</
span
>
<
Tooltip
title=
'默认为选中试卷所设置的及格线,可修改'
>
<
span
className=
'icon iconfont'
style=
{
{
color
:
'#BFBFBF'
,
marginLeft
:
4
}
}
>

</
span
>
</
Tooltip
>
</
div
>
}
style=
{
{
marginTop
:
24
}
}
validateStatus=
{
check
&&
!
passRate
?
'error'
:
''
}
help=
{
check
&&
!
passRate
&&
'请输入及格线'
}
required
>
<
InputNumber
value=
{
passRate
}
min=
{
0
}
max=
{
100
}
onChange=
{
(
value
:
any
)
=>
{
setPassRate
(
parseInt
(
value
));
}
}
style=
{
{
width
:
100
}
}
/>
<
span
style=
{
{
marginLeft
:
4
}
}
>
%
</
span
>
<
span
style=
{
{
marginLeft
:
16
,
color
:
'#999'
}
}
>
{
` 总分(${paperInfo.totalScore || 0})*及格线(${passRate || 0}%)=及格分数(${passScore})`
}
</
span
>
</
Form
.
Item
>
<
Form
.
Item
label=
'考试有效期'
validateStatus=
{
check
&&
!
examStartTime
?
'error'
:
''
}
help=
{
check
&&
!
examStartTime
&&
'请选择考试起止时间'
}
required
>
<
RangePicker
style=
{
{
width
:
320
}
}
showTime=
{
{
defaultValue
:
[
moment
().
add
(
5
,
'minutes'
),
moment
().
add
(
5
,
'minutes'
)]
}
}
ranges=
{
{
近七天
:
[
moment
().
add
(
5
,
'minute'
),
moment
().
add
(
6
,
'day'
).
endOf
(
'day'
)],
近
1
个月
:
[
moment
().
add
(
5
,
'minute'
),
moment
().
add
(
1
,
'month'
).
endOf
(
'day'
)],
近
3
个月
:
[
moment
().
add
(
5
,
'minute'
),
moment
().
add
(
3
,
'month'
).
endOf
(
'day'
)],
}
}
disabledDate=
{
disabledDate
}
value=
{
[
examStartTime
?
moment
(
Number
(
examStartTime
))
:
null
,
examEndTime
?
moment
(
Number
(
examEndTime
))
:
null
]
}
disabledTime=
{
disabledRangeTime
}
format=
'YYYY/MM/DD HH:mm'
onChange=
{
(
date
:
any
)
=>
{
setStartTime
(
date
&&
date
[
0
]?.
valueOf
());
setExamEndTime
(
date
&&
date
[
1
]?.
valueOf
());
}
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
'考试时长'
validateStatus=
{
check
&&
!
examDuration
?
'error'
:
''
}
help=
{
check
&&
!
examDuration
&&
'请输入考试时长'
}
required
>
<
InputNumber
value=
{
examDuration
}
max=
{
1440
}
min=
{
1
}
onChange=
{
(
value
:
any
)
=>
{
setExamDuration
(
parseInt
(
value
)
as
any
);
}
}
style=
{
{
width
:
100
}
}
/>
<
span
style=
{
{
marginLeft
:
4
}
}
>
分钟
</
span
>
<
span
style=
{
{
marginLeft
:
16
,
color
:
'#999'
}
}
>
{
` 时长不能超过1440分钟(24小时)`
}
</
span
>
</
Form
.
Item
>
<
Form
.
Item
label=
'考试说明'
validateStatus=
{
check
&&
desclen
>
1000
?
'error'
:
''
}
help=
{
check
&&
desclen
>
1000
&&
'最多只能输入1000个字'
}
>
{
(
getData
||
props
.
type
===
'add'
)
&&
(
<
GraphicsEditor
maxLimit=
{
1000
}
isIntro=
{
true
}
detail=
{
{
content
:
examDesc
,
}
}
onChange=
{
(
val
:
any
,
len
:
any
)
=>
{
setExamDesc
(
val
);
setDescLen
(
len
);
}
}
/>
)
}
</
Form
.
Item
>
<
div
className=
'title'
style=
{
{
marginTop
:
40
}
}
>
考试设置
</
div
>
<
Form
.
Item
label=
'身份验证'
required
>
<
div
style=
{
{
display
:
'flex'
,
marginLeft
:
4
}
}
>
<
Switch
style=
{
{
position
:
'relative'
,
top
:
6
}
}
checked=
{
needPhone
===
'NEED_PHONE_VERIFY'
}
onChange=
{
(
val
)
=>
{
setNeedPhone
(
val
?
'NEED_PHONE_VERIFY'
:
'DO_NOT_NEED_PHONE_VERIFY'
);
}
}
></
Switch
>
<
div
style=
{
{
position
:
'relative'
,
top
:
3
,
left
:
8
,
color
:
'#999'
}
}
>
<
p
>
开启:需要绑定手机号的学员才能参加考试
</
p
>
<
p
>
关闭:微信/企业微信登陆直接参加考试
</
p
>
</
div
>
</
div
>
</
Form
.
Item
>
<
Form
.
Item
label=
'选项乱序'
required
>
<
div
style=
{
{
display
:
'flex'
,
marginLeft
:
4
}
}
>
<
Switch
style=
{
{
position
:
'relative'
,
top
:
6
}
}
checked=
{
needOptionDisorder
===
'OPTION_RANDOM'
}
onChange=
{
(
val
)
=>
{
setNeedOptionDisorder
(
val
?
'OPTION_RANDOM'
:
'OPTION_SORT'
);
}
}
></
Switch
>
<
div
style=
{
{
position
:
'relative'
,
top
:
3
,
left
:
8
,
color
:
'#999'
}
}
>
<
p
>
开启:选择题的选项随机排序
</
p
>
<
p
>
关闭:选择题按题目原有顺序展示
</
p
>
</
div
>
</
div
>
</
Form
.
Item
>
<
Form
.
Item
label=
'考试结果查看'
required
>
<
Radio
.
Group
onChange=
{
(
e
:
any
)
=>
{
setResultShow
(
e
.
target
.
value
);
}
}
value=
{
resultShow
}
>
<
Radio
value=
{
'IMMEDIATELY'
}
>
交卷后立即显示考试结果
</
Radio
>
<
Radio
value=
{
'AFTER_EXAM_END'
}
>
到达考试截止日期才显示结果
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
<
Form
.
Item
label=
' 考试结果内容'
required
>
<
Radio
.
Group
onChange=
{
(
e
:
any
)
=>
{
setResultContent
(
e
.
target
.
value
);
}
}
value=
{
resultContent
}
>
<
Radio
value=
{
'PASS_AND_SCORE'
}
>
显示考试分数和是否及格
</
Radio
>
<
Radio
value=
{
'ONLY_SCORE'
}
>
仅显示考试分数
</
Radio
>
<
Radio
value=
{
'ONLY_PASS'
}
>
仅显示是否及格
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
<
Form
.
Item
label=
'答案与解析'
required
>
<
Radio
.
Group
onChange=
{
(
e
:
any
)
=>
{
setAnswerAnalysis
(
e
.
target
.
value
);
}
}
value=
{
answerAnalysis
}
>
<
Radio
value=
{
'ANALYSE_AND_RIGHT_OR_WRONG'
}
>
显示对错与解析
</
Radio
>
<
Radio
value=
{
'RIGHT_OR_WRONG'
}
>
仅显示对错
</
Radio
>
<
Radio
value=
{
'CAN_NOT_CHECK'
}
>
都不显示
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
</
Form
>
</
div
>
</
div
>
{
showModal
&&
(
<
SelectPaperModal
onSelect=
{
(
info
:
any
)
=>
{
setPaperInfo
(
info
);
}
}
paperInfo=
{
paperInfo
}
close=
{
()
=>
{
setShowModal
(
false
);
}
}
></
SelectPaperModal
>
)
}
<
div
className=
'footer shrink-footer'
>
<
Button
onClick=
{
handleGoBack
}
>
取消
</
Button
>
<
Button
onClick=
{
()
=>
{
setPreview
(
true
);
}
}
>
预览
</
Button
>
<
Button
type=
'primary'
onClick=
{
handleSave
}
>
保存
</
Button
>
</
div
>
{
preview
&&
(
<
PreviewModal
info=
{
{
paperId
,
startTime
:
examStartTime
,
endTime
:
examEndTime
,
...
...
@@ -119,384 +525,17 @@ function AddExam(props: any) {
resultContent
,
answerAnalysis
,
resultShow
,
examDuration
:
(
examDuration
||
0
)
*
60
*
1000
,
examDuration
,
passScore
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
,
examId
:
''
}
if
(
!
param
.
examName
)
{
message
.
warning
(
'请输入考试名称'
);
return
}
if
(
param
.
examName
&&
param
.
examName
.
length
>
40
)
{
message
.
warning
(
'考试名称最多40字'
);
return
}
if
(
!
paperId
)
{
message
.
warning
(
'请选择试卷'
);
return
}
if
(
!
passRate
)
{
message
.
warning
(
'请输入及格线'
);
return
}
if
(
!
examStartTime
||
!
examEndTime
)
{
message
.
warning
(
'请选择考试起止时间'
);
return
}
if
(
Number
(
examStartTime
)
<
moment
().
valueOf
())
{
message
.
warning
(
'开始时间不能早于现在'
);
return
}
if
(
!
examDuration
)
{
message
.
warning
(
'请输入考试时长'
);
return
}
if
(
examStartTime
+
(
examDuration
as
any
)
*
60
*
1000
>
examEndTime
)
{
message
.
warning
(
'考试时长不得超过考试有效期时长'
);
return
}
if
(
desclen
>
1000
)
{
message
.
warning
(
'内容过长,不能超过1000字'
);
return
}
request
.
current
=
true
;
setTimeout
(()
=>
{
request
.
current
=
false
},
2000
)
if
(
props
.
type
===
'edit'
)
{
param
.
examId
=
match
.
params
.
id
;
}
Service
.
Hades
(
props
.
type
===
'edit'
?
'public/hades/editExam'
:
"public/hades/createExam"
,
param
).
then
((
res
)
=>
{
message
.
success
(
props
.
type
===
'edit'
?
'编辑成功'
:
'创建成功'
);
switch
(
props
.
type
)
{
case
"organizeExam"
:
// 试卷列表-组织考试进入
case
"newPaperToAddExam"
:
// 组卷保存组织考试
case
"editPaperToAddExam"
:
window
.
RCHistory
.
push
(
"/examination-manage-index"
)
break
;
case
"add"
:
case
"edit"
:
// 考试列表-新建或编辑
case
"copy"
:
// 考试列表-新建或编辑
props
.
freshList
()
props
.
history
.
goBack
();
break
;
}
})
}
function
disabledRangeTime
(
date
:
any
,
type
:
any
)
{
if
(
moment
(
date
).
isSame
(
moment
(),
'day'
))
{
return
{
disabledHours
:
()
=>
{
const
hours
=
[];
for
(
let
i
=
0
;
i
<
moment
().
hour
();
i
++
)
{
hours
.
push
(
i
);
}
return
hours
;
},
disabledMinutes
:
()
=>
{
const
currentMinute
=
moment
().
minute
();
const
currentHour
=
moment
(
date
).
hour
();
const
minutes
=
[];
if
(
currentHour
===
moment
().
hour
())
{
for
(
let
i
=
0
;
i
<
currentMinute
;
i
++
)
{
minutes
.
push
(
i
);
}
}
return
minutes
;
},
};
}
return
{
disabledHours
:
()
=>
[],
disabledMinutes
:
()
=>
[],
disabledSeconds
:
()
=>
[],
};
}
function
handleGoBack
()
{
Modal
.
confirm
({
title
:
'确定要返回吗?'
,
content
:
'返回后,本次编辑的内容将不被保存'
,
okText
:
'确认返回'
,
cancelText
:
'留在本页'
,
icon
:
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>,
onOk
:
()
=>
{
window
.
RCHistory
.
push
(
"/examination-manage-index"
)
}
})
}
let
title
=
''
;
switch
(
props
.
type
)
{
case
'add'
:
case
"organizeExam"
:
case
"newPaperToAddExam"
:
case
"editPaperToAddExam"
:
title
=
'新建考试'
;
break
;
case
'edit'
:
title
=
'编辑考试'
;
break
;
case
'copy'
:
title
=
'复制考试'
;
break
;
default
:
break
;
}
return
<
div
className=
"page examPage"
>
<
Breadcrumbs
navList=
{
title
}
goBack=
{
handleGoBack
}
/>
<
div
className=
"box"
>
<
div
className=
"show-tips"
>
<
ShowTips
message=
"请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利"
/>
</
div
>
<
div
className=
"form"
>
<
div
className=
"title"
>
基本信息
</
div
>
<
Form
labelCol=
{
{
span
:
3
}
}
wrapperCol=
{
{
span
:
14
}
}
layout=
"horizontal"
>
<
Form
.
Item
label=
"考试名称"
validateStatus=
{
(
check
&&
(
!
examName
?
'请输入考试名称'
:
(
examName
.
length
>
40
)
&&
'考试名称最多40字'
))
?
'error'
:
''
}
help=
{
check
&&
(
!
examName
?
'请输入考试名称'
:
(
examName
.
length
>
40
)
&&
'考试名称最多40字'
)
}
required
>
<
Input
placeholder=
'请输入考试名称(40字以内)'
maxLength=
{
40
}
value=
{
examName
}
onChange=
{
(
e
)
=>
{
setExamName
(
e
.
target
.
value
)
}
}
style=
{
{
width
:
320
}
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"选择试卷"
validateStatus=
{
(
check
&&
!
paperId
)
?
'error'
:
''
}
help=
{
check
&&
!
paperId
&&
'请选择试卷'
}
required
>
<
Button
onClick=
{
()
=>
{
setShowModal
(
true
)
}
}
>
{
paperInfo
.
paperId
?
'重新选择'
:
'选择试卷'
}
</
Button
>
{
paperInfo
.
paperId
&&
<
div
className=
"paperTitle"
><
img
src=
"https://image.xiaomaiketang.com/xm/pY5imEhjzw.png"
alt=
""
/>
{
paperInfo
.
paperName
}
</
div
>
}
{
paperInfo
.
paperId
&&
<
div
className=
"table"
>
<
div
className=
"header"
>
<
div
className=
"item"
>
单选题
</
div
>
<
div
className=
"item"
>
多选题
</
div
>
<
div
className=
"item"
>
判断题
</
div
>
<
div
className=
"item"
>
填空题
</
div
>
<
div
className=
"item long"
>
不定项选择题
</
div
>
<
div
className=
"item"
>
合计
</
div
>
</
div
>
<
div
className=
"body-list"
>
<
div
className=
"item"
>
{
paperInfo
.
singleChoiceCnt
||
0
}
题
</
div
>
<
div
className=
"item"
>
{
paperInfo
.
multiChoiceCnt
||
0
}
题
</
div
>
<
div
className=
"item"
>
{
paperInfo
.
judgeCnt
||
0
}
题
</
div
>
<
div
className=
"item"
>
{
paperInfo
.
gapFillingCnt
||
0
}
题
</
div
>
<
div
className=
"item long"
>
{
paperInfo
.
indefiniteChoiceCnt
||
0
}
题
</
div
>
<
div
className=
"item"
>
{
examTotal
}
题
</
div
>
</
div
>
<
div
className=
"body-list"
>
<
div
className=
"item"
>
{
paperInfo
.
singleChoiceScore
||
0
}
分
</
div
>
<
div
className=
"item"
>
{
paperInfo
.
multiChoiceScore
||
0
}
分
</
div
>
<
div
className=
"item"
>
{
paperInfo
.
judgeScore
||
0
}
分
</
div
>
<
div
className=
"item"
>
{
paperInfo
.
gapFillingScore
||
0
}
分
</
div
>
<
div
className=
"item long"
>
{
paperInfo
.
indefiniteChoiceScore
||
0
}
分
</
div
>
<
div
className=
"item"
>
{
paperInfo
.
totalScore
||
0
}
分
</
div
>
</
div
>
</
div
>
}
</
Form
.
Item
>
<
Form
.
Item
label=
{
<
div
>
<
span
>
及格线
</
span
>
<
Tooltip
title=
"默认为选中试卷所设置的及格线,可修改"
>
<
span
className=
"icon iconfont"
style=
{
{
color
:
'#BFBFBF'
,
marginLeft
:
4
}
}
>

</
span
>
</
Tooltip
>
</
div
>
}
style=
{
{
marginTop
:
24
}
}
validateStatus=
{
(
check
&&
!
passRate
)
?
'error'
:
''
}
help=
{
check
&&
!
passRate
&&
'请输入及格线'
}
required
>
<
InputNumber
value=
{
passRate
}
min=
{
0
}
max=
{
100
}
onChange=
{
(
value
:
any
)
=>
{
setPassRate
(
parseInt
(
value
))
}
}
style=
{
{
width
:
100
}
}
/>
<
span
style=
{
{
marginLeft
:
4
}
}
>
%
</
span
>
<
span
style=
{
{
marginLeft
:
16
,
color
:
"#999"
}
}
>
{
` 总分(${paperInfo.totalScore || 0})*及格线(${passRate || 0}%)=及格分数(${passScore})`
}
</
span
>
</
Form
.
Item
>
<
Form
.
Item
label=
"考试有效期"
validateStatus=
{
(
check
&&
!
examStartTime
)
?
'error'
:
''
}
help=
{
check
&&
!
examStartTime
&&
'请选择考试起止时间'
}
required
>
<
RangePicker
style=
{
{
width
:
320
}
}
showTime=
{
{
defaultValue
:
[
moment
().
add
(
5
,
'minutes'
),
moment
().
add
(
5
,
'minutes'
)]
}
}
ranges=
{
{
'近七天'
:
[
moment
().
add
(
5
,
'minute'
),
moment
().
add
(
6
,
'day'
).
endOf
(
'day'
)],
'近1个月'
:
[
moment
().
add
(
5
,
'minute'
),
moment
().
add
(
1
,
'month'
).
endOf
(
'day'
)],
'近3个月'
:
[
moment
().
add
(
5
,
'minute'
),
moment
().
add
(
3
,
'month'
).
endOf
(
'day'
)],
}
}
disabledDate=
{
disabledDate
}
value=
{
[
examStartTime
?
moment
(
Number
(
examStartTime
))
:
null
,
examEndTime
?
moment
(
Number
(
examEndTime
))
:
null
]
}
disabledTime=
{
disabledRangeTime
}
format=
"YYYY/MM/DD HH:mm"
onChange=
{
(
date
:
any
)
=>
{
setStartTime
(
date
&&
date
[
0
]?.
valueOf
());
setExamEndTime
(
date
&&
date
[
1
]?.
valueOf
());
}
}
/>
</
Form
.
Item
>
<
Form
.
Item
label=
"考试时长"
validateStatus=
{
(
check
&&
!
examDuration
)
?
'error'
:
''
}
help=
{
check
&&
!
examDuration
&&
'请输入考试时长'
}
required
>
<
InputNumber
value=
{
examDuration
}
max=
{
1440
}
min=
{
1
}
onChange=
{
(
value
:
any
)
=>
{
setExamDuration
(
parseInt
(
value
)
as
any
)
}
}
style=
{
{
width
:
100
}
}
/>
<
span
style=
{
{
marginLeft
:
4
}
}
>
分钟
</
span
>
<
span
style=
{
{
marginLeft
:
16
,
color
:
"#999"
}
}
>
{
` 时长不能超过1440分钟(24小时)`
}
</
span
>
</
Form
.
Item
>
<
Form
.
Item
label=
"考试说明"
validateStatus=
{
(
check
&&
(
desclen
>
1000
))
?
'error'
:
''
}
help=
{
check
&&
(
desclen
>
1000
)
&&
'最多只能输入1000个字'
}
>
{
(
getData
||
(
props
.
type
===
'add'
))
&&
<
GraphicsEditor
maxLimit=
{
1000
}
isIntro=
{
true
}
detail=
{
{
content
:
examDesc
}
}
onChange=
{
(
val
:
any
,
len
:
any
)
=>
{
setExamDesc
(
val
);
setDescLen
(
len
)
}
}
/>
}
</
Form
.
Item
>
<
div
className=
"title"
style=
{
{
marginTop
:
40
}
}
>
考试设置
</
div
>
<
Form
.
Item
label=
"身份验证"
required
>
<
div
style=
{
{
display
:
'flex'
,
marginLeft
:
4
,
}
}
>
<
Switch
style=
{
{
position
:
'relative'
,
top
:
6
}
}
checked=
{
needPhone
==
'NEED_PHONE_VERIFY'
}
onChange=
{
(
val
)
=>
{
setNeedPhone
(
val
?
'NEED_PHONE_VERIFY'
:
'DO_NOT_NEED_PHONE_VERIFY'
)
}
}
></
Switch
>
<
div
style=
{
{
position
:
'relative'
,
top
:
3
,
left
:
8
,
color
:
"#999"
}
}
><
p
>
开启:需要绑定手机号的学员才能参加考试
</
p
>
<
p
>
关闭:微信/企业微信登陆直接参加考试
</
p
></
div
>
</
div
>
</
Form
.
Item
>
<
Form
.
Item
label=
"选项乱序"
required
>
<
div
style=
{
{
display
:
'flex'
,
marginLeft
:
4
,
}
}
>
<
Switch
style=
{
{
position
:
'relative'
,
top
:
6
}
}
checked=
{
needOptionDisorder
==
'OPTION_RANDOM'
}
onChange=
{
(
val
)
=>
{
setNeedOptionDisorder
(
val
?
'OPTION_RANDOM'
:
'OPTION_SORT'
)
}
}
></
Switch
>
<
div
style=
{
{
position
:
'relative'
,
top
:
3
,
left
:
8
,
color
:
"#999"
}
}
><
p
>
开启:选择题的选项随机排序
</
p
>
<
p
>
关闭:选择题按题目原有顺序展示
</
p
></
div
>
</
div
>
</
Form
.
Item
>
<
Form
.
Item
label=
"考试结果查看"
required
>
<
Radio
.
Group
onChange=
{
(
e
:
any
)
=>
{
setResultShow
(
e
.
target
.
value
)
}
}
value=
{
resultShow
}
>
<
Radio
value=
{
'IMMEDIATELY'
}
>
交卷后立即显示考试结果
</
Radio
>
<
Radio
value=
{
'AFTER_EXAM_END'
}
>
到达考试截止日期才显示结果
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
<
Form
.
Item
label=
" 考试结果内容"
required
>
<
Radio
.
Group
onChange=
{
(
e
:
any
)
=>
{
setResultContent
(
e
.
target
.
value
)
}
}
value=
{
resultContent
}
>
<
Radio
value=
{
'PASS_AND_SCORE'
}
>
显示考试分数和是否及格
</
Radio
>
<
Radio
value=
{
'ONLY_SCORE'
}
>
仅显示考试分数
</
Radio
>
<
Radio
value=
{
'ONLY_PASS'
}
>
仅显示是否及格
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
<
Form
.
Item
label=
"答案与解析"
required
>
<
Radio
.
Group
onChange=
{
(
e
:
any
)
=>
{
setAnswerAnalysis
(
e
.
target
.
value
)
}
}
value=
{
answerAnalysis
}
>
<
Radio
value=
{
'ANALYSE_AND_RIGHT_OR_WRONG'
}
>
显示对错与解析
</
Radio
>
<
Radio
value=
{
'RIGHT_OR_WRONG'
}
>
仅显示对错
</
Radio
>
<
Radio
value=
{
'CAN_NOT_CHECK'
}
>
都不显示
</
Radio
>
</
Radio
.
Group
>
</
Form
.
Item
>
</
Form
>
</
div
>
</
div
>
{
showModal
&&
<
SelectPaperModal
onSelect=
{
(
info
:
any
)
=>
{
setPaperInfo
(
info
)
}
}
paperInfo=
{
paperInfo
}
close=
{
()
=>
{
setShowModal
(
false
)
}
}
></
SelectPaperModal
>
}
<
div
className=
"footer shrink-footer"
>
<
Button
onClick=
{
handleGoBack
}
>
取消
</
Button
>
<
Button
onClick=
{
()
=>
{
setPreview
(
true
)
}
}
>
预览
</
Button
>
<
Button
type=
"primary"
onClick=
{
handleSave
}
>
保存
</
Button
>
</
div
>
{
preview
&&
<
PreviewModal
info=
{
{
paperId
,
startTime
:
examStartTime
,
endTime
:
examEndTime
,
examName
,
passRate
:
passRate
/
100
,
examStartTime
,
examEndTime
,
examDesc
,
needPhone
,
needOptionDisorder
,
resultContent
,
answerAnalysis
,
resultShow
,
examDuration
,
passScore
,
examTotal
,
totalScore
:
paperInfo
.
totalScore
}
}
onClose=
{
()
=>
{
setPreview
(
false
)
}
}
></
PreviewModal
>
}
examTotal
,
totalScore
:
paperInfo
.
totalScore
,
}
}
onClose=
{
()
=>
{
setPreview
(
false
);
}
}
></
PreviewModal
>
)
}
</
div
>
);
}
export
default
withRouter
(
AddExam
);
\ No newline at end of file
export
default
withRouter
(
AddExam
);
src/routes/index.tsx
View file @
1bf6cc7a
...
...
@@ -3,108 +3,86 @@
* @Date: 2020-04-28 18:05:30
* @LastEditors: wufan
* @LastEditTime: 2020-12-26 14:37:23
* @Description:
* @Description:
*/
import
mainRoutes
from
'./config/mainRoutes'
;
import
redirectRoutes
from
'./config/redirectRoutes'
;
import
React
from
'react'
import
{
Redirect
,
HashRouter
as
Router
,
Route
,
Switch
}
from
'react-router-dom'
;
import
React
from
'react'
;
import
{
HashRouter
as
Router
,
Route
,
Switch
}
from
'react-router-dom'
;
import
{
createHashHistory
}
from
'history'
;
import
App
from
'../modules/root/App'
;
import
AppContext
from
'@/modules/root/AppContent'
;
import
Login
from
'../modules/root/Login'
;
import
CollegeManagePage
from
'../modules/root/CollegeManagePage'
;
import
CreateCollege
from
'../modules/root/CreateCollege'
;
import
_
from
'underscore'
;
import
{
asyncComponent
}
from
'react-async-component'
import
SwitchRoute
from
'@/modules/root/SwitchRoute'
;
import
ErrorCollege
from
'@/modules/root/ErrorCollege'
;
const
history
=
createHashHistory
();
window
.
RCHistory
=
_
.
extend
({},
history
,
{
push
:
(
obj
:
any
)
=>
{
history
.
push
(
obj
)
},
pushState
:
(
obj
:
any
)
=>
{
history
.
push
(
obj
)
},
pushStateWithStatus
:
(
obj
:
any
)
=>
{
history
.
push
(
obj
)
},
goBack
:
history
.
goBack
,
location
:
history
.
location
,
replace
:
(
obj
:
any
)
=>
{
history
.
replace
(
obj
)
}
push
:
(
obj
:
any
)
=>
{
history
.
push
(
obj
);
},
pushState
:
(
obj
:
any
)
=>
{
history
.
push
(
obj
);
},
pushStateWithStatus
:
(
obj
:
any
)
=>
{
history
.
push
(
obj
);
},
goBack
:
history
.
goBack
,
location
:
history
.
location
,
replace
:
(
obj
:
any
)
=>
{
history
.
replace
(
obj
);
},
});
const
cache
:
any
=
{
path
:
''
,
component
:
null
}
function
dynamic
(
component
:
any
)
{
const
resolveComponent
=
component
return
asyncComponent
({
resolve
:
()
=>
{
const
ts
=
resolveComponent
()
return
ts
},
})
}
export
const
RootRouter
=
()
=>
{
return
(
<
Router
{
...
history
}
>
<
Switch
>
<
Route
key=
"1"
exact
path=
"/login"
render=
{
()
=>
<
Login
/>
}
/>
<
Route
key=
"2"
exact
path=
"/switch-route"
render=
{
()
=>
<
SwitchRoute
/>
}
/>
<
Route
key=
"3"
exact
path=
"/college-manage"
render=
{
()
=>
<
CollegeManagePage
/>
}
/>
<
Route
key=
"4"
exact
path=
"/college-manage/create"
render=
{
()
=>
<
CreateCollege
/>
}
/>
<
Route
key=
"6"
exact
path=
"/error-college"
render=
{
()
=>
<
ErrorCollege
/>
}
/>
<
Route
key=
"5"
path=
"/"
render=
{
()
=>
<
AppContext
/>
}
/>
</
Switch
>
</
Router
>
)
}
return
(
<
Router
{
...
history
}
>
<
Switch
>
<
Route
key=
'1'
exact
path=
'/login'
render=
{
()
=>
<
Login
/>
}
/>
<
Route
key=
'2'
exact
path=
'/switch-route'
render=
{
()
=>
<
SwitchRoute
/>
}
/>
<
Route
key=
'3'
exact
path=
'/college-manage'
render=
{
()
=>
<
CollegeManagePage
/>
}
/>
<
Route
key=
'4'
exact
path=
'/college-manage/create'
render=
{
()
=>
<
CreateCollege
/>
}
/>
<
Route
key=
'6'
exact
path=
'/error-college'
render=
{
()
=>
<
ErrorCollege
/>
}
/>
<
Route
key=
'5'
path=
'/'
render=
{
()
=>
<
AppContext
/>
}
/>
</
Switch
>
</
Router
>
);
}
;
export
const
MainRoutes
=
()
=>
{
return
(
<
Switch
>
{
_
.
map
(
mainRoutes
,
({
path
,
component
,
},
key
)
=>
{
return
<
Route
key=
{
key
}
path=
{
path
}
render=
{
()
=>
{
const
Component
=
component
;
return
<
Component
/>
}
}
/>
})
}
</
Switch
>
)
}
return
(
<
Switch
>
{
_
.
map
(
mainRoutes
,
({
path
,
component
},
key
)
=>
{
return
(
<
Route
key=
{
key
}
path=
{
path
}
render=
{
()
=>
{
const
Component
=
component
;
return
<
Component
/>;
}
}
/>
);
})
}
</
Switch
>
);
};
export
const
RedirectRoutes
=
()
=>
{
return
(
<
Switch
>
{
_
.
map
(
redirectRoutes
,
({
path
,
component
,
},
key
)
=>
{
return
<
Route
key=
{
key
}
path=
{
path
}
render=
{
()
=>
{
const
Component
=
component
;
return
<
Component
/>
}
}
/>
})
}
</
Switch
>
)
}
return
(
<
Switch
>
{
_
.
map
(
redirectRoutes
,
({
path
,
component
},
key
)
=>
{
return
(
<
Route
key=
{
key
}
path=
{
path
}
render=
{
()
=>
{
const
Component
=
component
;
return
<
Component
/>;
}
}
/>
);
})
}
</
Switch
>
);
};
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