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
711245c2
Commit
711245c2
authored
May 08, 2021
by
chenshu
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:初始化
parent
49debeec
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
468 additions
and
12 deletions
+468
-12
src/modules/course-manage/offline-course/AddOfflineCourse.jsx
+416
-8
src/modules/course-manage/offline-course/AddOfflineCourse.less
+52
-4
No files found.
src/modules/course-manage/offline-course/AddOfflineCourse.jsx
View file @
711245c2
...
...
@@ -8,11 +8,23 @@
*/
import
React
from
'react'
;
import
{
Button
,
Input
,
Radio
,
message
,
Modal
,
Cascader
}
from
'antd'
;
import
{
Button
,
Input
,
Radio
,
message
,
Modal
,
Cascader
,
Select
,
Switch
,
TimePicker
,
InputNumber
,
}
from
'antd'
;
import
$
from
'jquery'
;
import
{
DISK_MAP
,
FileTypeIcon
,
FileVerifyMap
}
from
'@/common/constants/academic/lessonEnum'
;
import
{
ImgCutModalNew
}
from
'@/components'
;
import
RangePicker
from
"@/modules/common/DateRangePicker"
;
import
ShowTips
from
"@/components/ShowTips"
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
AddGraphicsIntro
from
'./components/AddGraphicsIntro'
;
...
...
@@ -25,16 +37,23 @@ import { randomString } from '@/domains/basic-domain/utils';
import
User
from
'@/common/js/user'
;
import
_
from
"underscore"
;
import
Upload
from
'@/core/upload'
;
import
GraphicsEditor
from
'../components/GraphicsEditor'
;
import
MultipleDatePicker
from
'@/components/MultipleDatePicker'
;
import
'./AddOfflineCourse.less'
;
const
EDIT_BOX_KEY
=
Math
.
random
();
const
fieldNames
=
{
label
:
'categoryName'
,
value
:
'id'
,
children
:
'sonCategoryList'
};
const
{
Option
}
=
Select
;
//添加课程时课程默认的一些值
const
defaultShelfState
=
'YES'
;
const
whetherVisitorsJoin
=
'NO'
const
defaultCoverUrl
=
'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png'
;
let
cutFlag
=
false
;
const
unitList
=
[
{
key
:
'DAY'
,
value
:
'天'
},
{
key
:
'HOUR'
,
value
:
'小时'
},
{
key
:
'MINUTE'
,
value
:
'分钟'
},
]
class
AddOfflineCourse
extends
React
.
Component
{
...
...
@@ -66,12 +85,33 @@ class AddOfflineCourse extends React.Component {
categoryId
:
null
,
//分类的Id值
whetherVisitorsJoin
:
'NO'
,
// 是否允许游客加入
isContent
:
true
,
teacherList
:
[],
teacherQuery
:
{
size
:
15
,
current
:
1
,
nickName
:
null
},
calendarTime
:
[],
offlineCourseType
:
'ANY_DAY_POFFLINE'
,
signInType
:
'START_AGO'
,
signOutType
:
'START_AGO'
,
quota
:
1
,
signInTimeNum
:
1
,
signOutEndTimeNum
:
1
,
signOutStartTimeNum
:
1
,
signInTimeUnit
:
'MINUTE'
,
signOutStartTimeUnit
:
'MINUTE'
,
signOutEndTimeUnit
:
'MINUTE'
,
whetherSetApply
:
'YES'
,
whetherSetSignIn
:
'YES'
,
whetherSetSignOut
:
'YES'
,
}
}
componentWillMount
()
{
const
{
id
,
pageType
}
=
this
.
state
;
this
.
getCourseCatalogList
();
this
.
getTeacherList
();
if
(
pageType
===
'edit'
)
{
this
.
handleFetchScheudleDetail
(
id
);
}
...
...
@@ -513,6 +553,64 @@ class AddOfflineCourse extends React.Component {
this
.
setState
({
coverUrl
:
defaultCoverUrl
});
}
// 滑动加载更多讲师列表
handleScrollTeacherList
=
(
e
)
=>
{
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
_query
=
{
...
teacherQuery
,
current
,
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
}
})
});
}
changeIntro
=
(
value
)
=>
{
this
.
setState
({
introduce
:
value
});
}
selectMultiDate
=
(
calendarTime
)
=>
{
this
.
setState
({
calendarTime
})
}
handleChangeDates
=
(
dates
)
=>
{
const
data
=
{};
if
(
_
.
isEmpty
(
dates
))
{
data
.
startTimeApply
=
undefined
;
data
.
endTimeApply
=
undefined
;
}
else
{
data
.
startTimeApply
=
dates
[
0
].
valueOf
();
data
.
endTimeApply
=
dates
[
1
].
valueOf
();
}
this
.
setState
(
data
);
}
render
()
{
const
{
id
,
...
...
@@ -536,6 +634,27 @@ class AddOfflineCourse extends React.Component {
visible
,
hasImgReady
,
cutImageBlob
,
teacherName
,
teacherId
,
teacherList
,
calendarTime
,
startTime
,
endTime
,
offlineCourseType
,
whetherSetApply
,
whetherSetSignIn
,
whetherSetSignOut
,
startTimeApply
,
endTimeApply
,
signInTimeUnit
,
signInTimeNum
,
signOutEndTimeNum
,
signOutEndTimeUnit
,
signOutStartTimeNum
,
signOutStartTimeUnit
,
signInType
,
signOutType
,
quota
,
}
=
this
.
state
;
// 已选择的上课学员数量
const
hasSelectedStu
=
studentList
.
length
;
...
...
@@ -558,8 +677,8 @@ class AddOfflineCourse extends React.Component {
<
div
className=
"form"
>
<
div
className=
"basic-info__wrap"
>
<
div
className=
"title"
>
基本信息
</
div
>
<
div
className=
"course-name
required
"
>
<
span
className=
"label"
>
课程名称:
</
span
>
<
div
className=
"course-name"
>
<
span
className=
"label"
>
<
span
className=
"require"
>
*
</
span
>
课程名称:
</
span
>
<
Input
value=
{
courseName
}
placeholder=
"请输入线下课的名称(40字以内)"
...
...
@@ -593,19 +712,308 @@ class AddOfflineCourse extends React.Component {
</
div
>
</
div
>
</
div
>
<
div
className=
"course-catalog
required
"
>
<
span
className=
"label"
>
课程分类:
</
span
>
<
div
className=
"course-catalog"
>
<
span
className=
"label"
>
<
span
className=
"require"
>
*
</
span
>
课程分类:
</
span
>
{
(
pageType
===
'add'
)
&&
<
Cascader
defaultValue=
{
[
categoryName
]
}
options=
{
courseCatalogList
}
displayRender=
{
label
=>
label
.
join
(
'-'
)
}
fieldNames=
{
fieldNames
}
onChange=
{
this
.
catalogChange
}
style=
{
{
width
:
240
}
}
placeholder=
"请选择课程分类"
suffixIcon=
{
<
span
className=
"icon iconfont"
style=
{
{
fontSize
:
'12px'
,
color
:
'#BFBFBF'
}
}
>

</
span
>
}
/>
<
Cascader
defaultValue=
{
categoryName
?
[
categoryName
]
:
undefined
}
options=
{
courseCatalogList
}
displayRender=
{
label
=>
label
.
join
(
'-'
)
}
fieldNames=
{
fieldNames
}
onChange=
{
this
.
catalogChange
}
style=
{
{
width
:
240
}
}
placeholder=
"请选择课程分类"
suffixIcon=
{
<
span
className=
"icon iconfont"
style=
{
{
fontSize
:
'12px'
,
color
:
'#BFBFBF'
}
}
>

</
span
>
}
/>
}
{
(
pageType
===
'edit'
&&
categoryName
)
&&
<
Cascader
defaultValue=
{
[
categoryName
]
}
options=
{
courseCatalogList
}
displayRender=
{
label
=>
label
.
join
(
'-'
)
}
fieldNames=
{
fieldNames
}
onChange=
{
this
.
catalogChange
}
style=
{
{
width
:
240
}
}
placeholder=
"请选择课程分类"
suffixIcon=
{
<
span
className=
"icon iconfont"
style=
{
{
fontSize
:
'12px'
,
color
:
'#BFBFBF'
}
}
>

</
span
>
}
/>
}
</
div
>
<
div
className=
"course-catalog"
>
<
span
className=
"label"
><
span
className=
"require"
>
*
</
span
>
上课地点:
</
span
>
<
Select
style=
{
{
width
:
240
}
}
placeholder=
"请输入上课地点(40字以内)"
>
</
Select
>
</
div
>
<
div
className=
"course-catalog"
id=
"teacher"
>
<
span
className=
"label"
><
span
className=
"require"
>
*
</
span
>
讲师:
</
span
>
<
Select
placeholder=
"请选择讲师"
value=
{
teacherName
}
style=
{
{
width
:
240
}
}
disabled=
{
pageType
===
'edit'
?
true
:
false
}
showSearch
allowClear
filterOption=
{
(
input
,
option
)
=>
option
}
onPopupScroll=
{
this
.
handleScrollTeacherList
}
suffixIcon=
{
<
span
className=
"icon iconfont"
style=
{
{
fontSize
:
'12px'
,
color
:
'#BFBFBF'
}
}
>

</
span
>
}
onChange=
{
(
value
,
option
)
=>
{
if
(
option
)
{
this
.
setState
({
teacherId
:
value
,
teacherType
:
option
.
children
});
}
else
{
this
.
setState
({
teacherId
:
value
,
teacherType
:
""
});
}
}
}
onSearch=
{
(
value
)
=>
{
teacherQuery
.
nickName
=
value
this
.
setState
({
teacherQuery
},
()
=>
{
this
.
getTeacherList
()
})
}
}
onClear
={(
value
)=
>
{
this
.
setState
({
teacherQuery
:{
size
:
15
,
current
:
1
,
nickName
:
null
}
},
()
=>
{
this
.
getTeacherList
()
})
}
}
getPopupContainer=
{
()
=>
document
.
getElementById
(
"teacher"
)
}
>
{
_
.
map
(
teacherList
,
(
item
,
index
)
=>
{
return
(
<
Option
value=
{
item
.
userId
}
key=
{
item
.
userId
}
>
{
item
.
nickName
}
</
Option
>
);
})
}
</
Select
>
</
div
>
<
div
className=
"allow-tourist-join"
>
<
span
className=
"label"
>
观看设置:
</
span
>
<
div
className=
"content"
>
<
div
>
<
Switch
checked=
{
whetherVisitorsJoin
===
"YES"
?
true
:
false
}
onChange=
{
this
.
whetherVisitorsJoinChange
}
/>
</
div
>
<
div
>
<
div
className=
"desc"
>
<
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"
>
{
(
!
id
||
loadintroduce
)
&&
<
GraphicsEditor
id=
"intro"
isIntro=
{
true
}
detail=
{
{
content
:
introduce
}
}
onChange=
{
(
val
)
=>
{
this
.
changeIntro
(
val
)
}
}
/>
}
</
div
>
</
div
>
</
div
>
</
div
>
<
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
>
天
</
div
>
<
MultipleDatePicker
selectDateList=
{
calendarTime
}
onSelect=
{
this
.
selectMultiDate
}
canSelectTodayBefore=
{
false
}
/>
</
div
>
<
div
className=
"intro-info mt16"
>
</
div
>
<
div
className=
"hour"
id=
"hour"
>
<
span
className=
"label"
><
span
className=
"require"
>
*
</
span
>
上课时间:
</
span
>
<
TimePicker
className=
"time-picker"
format=
"HH:mm"
value=
{
startTime
?
moment
(
startTime
)
:
null
}
placeholder=
"开始时间"
showNow=
{
false
}
style=
{
{
width
:
100
,
minWidth
:
100
}
}
onSelect=
{
(
time
)
=>
{
this
.
setState
({
startTime
:
time
});
}
}
getPopupContainer=
{
()
=>
document
.
getElementById
(
"hour"
)
}
/>
~
<
TimePicker
className=
"time-picker"
format=
"HH:mm"
value=
{
endTime
?
moment
(
endTime
)
:
null
}
placeholder=
"结束时间"
showNow=
{
false
}
style=
{
{
width
:
100
,
minWidth
:
100
}
}
onSelect=
{
(
time
)
=>
{
this
.
setState
({
endTime
:
time
});
}
}
getPopupContainer=
{
()
=>
document
.
getElementById
(
"hour"
)
}
/>
</
div
>
<
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"
>
<
Radio
value=
"ANY_DAY_POFFLINE"
className=
"mr-16"
>
<
span
style=
{
{
color
:
"#333"
}
}
>
所选日期都要上课
</
span
>
</
Radio
>
<
Radio
value=
"ALL_DAY_OFFLINE"
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"
>
<
Switch
checked=
{
whetherSetApply
}
onChange=
{
(
value
)
=>
this
.
setState
({
whetherSetApply
:
value
})
}
/>
<
span
className=
"switch-tip"
>
开启后可设置课程报名时间,获取报名数据
</
span
>
</
div
>
{
whetherSetApply
&&
<
div
className=
"switch-item"
key=
"2"
>
<
span
className=
"switch-label"
>
报名日期:
</
span
>
<
RangePicker
id=
"course_date_picker"
allowClear=
{
false
}
value=
{
startTimeApply
?
[
moment
(
startTimeApply
),
moment
(
endTimeApply
)]
:
null
}
format=
{
"YYYY-MM-DD"
}
onChange=
{
(
dates
)
=>
{
this
.
handleChangeDates
(
dates
)
}
}
style=
{
{
width
:
"calc(100% - 70px)"
}
}
/>
</
div
>
}
{
whetherSetApply
&&
<
div
className=
"switch-item"
key=
"3"
>
<
span
className=
"switch-label"
>
报名人数:最多
</
span
>
<
InputNumber
value=
{
signInTimeNum
}
style=
{
{
margin
:
'0 4px'
}
}
/>
<
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"
>
<
Switch
checked=
{
whetherSetSignIn
}
onChange=
{
(
value
)
=>
this
.
setState
({
whetherSetSignIn
:
value
})
}
/>
<
span
className=
"switch-tip"
>
开启后可设置获取签到考勤数据
</
span
>
</
div
>
{
whetherSetSignIn
&&
<
div
className=
"switch-item"
key=
"2"
>
<
span
className=
"switch-label"
>
签到时间:
</
span
>
<
Radio
.
Group
style=
{
{
display
:
'inline-block'
}
}
value=
{
signInType
}
onChange=
{
(
e
)
=>
{
this
.
setState
({
offlineCourseType
:
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
&&
<
div
className=
"switch-item"
key=
"3"
>
<
span
className=
"switch-label"
>
课程开始前
</
span
>
<
InputNumber
value=
{
quota
}
style=
{
{
margin
:
'0 4px'
}
}
onChange=
{
(
value
)
=>
{
this
.
setState
({
signInTimeNum
:
value
});
}
}
/>
<
Select
style=
{
{
width
:
72
,
marginRight
:
4
}
}
value=
{
signInTimeUnit
}
onChange=
{
(
value
)
=>
{
this
.
setState
({
signInTimeUnit
:
value
});
}
}
>
{
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"
>
<
Switch
checked=
{
whetherSetSignOut
}
onChange=
{
(
value
)
=>
this
.
setState
({
whetherSetSignOut
:
value
})
}
/>
<
span
className=
"switch-tip"
>
开启后可设置获取签退考勤数据
</
span
>
</
div
>
{
whetherSetSignOut
&&
<
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_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
>
}
{
whetherSetSignOut
&&
<
div
className=
"switch-item"
key=
"3"
>
<
span
className=
"switch-label"
>
课程开始后
</
span
>
<
InputNumber
value=
{
signOutStartTimeNum
}
style=
{
{
margin
:
'0 4px'
}
}
/>
<
Select
style=
{
{
width
:
72
,
marginRight
:
4
}
}
value=
{
signOutStartTimeUnit
}
>
{
unitList
.
map
(
item
=>
(
<
Option
value=
{
item
.
key
}
key=
{
item
.
key
}
>
{
item
.
value
}
</
Option
>
))
}
</
Select
>
<
span
className=
"switch-label"
>
就可签退,截止签退时间为下课后
</
span
>
<
InputNumber
value=
{
signOutEndTimeNum
}
style=
{
{
margin
:
'0 4px'
}
}
/>
<
Select
style=
{
{
width
:
72
,
marginRight
:
4
}
}
value=
{
signOutEndTimeUnit
}
>
{
unitList
.
map
(
item
=>
(
<
Option
value=
{
item
.
key
}
key=
{
item
.
key
}
>
{
item
.
value
}
</
Option
>
))
}
</
Select
>
</
div
>
}
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
src/modules/course-manage/offline-course/AddOfflineCourse.less
View file @
711245c2
...
...
@@ -39,9 +39,10 @@
}
}
.label{
display:inline-block;
text-align:right;
width:85px;
display: inline-block;
text-align: right;
width: 120px;
flex-shrink: 0;
}
.required {
position: relative;
...
...
@@ -58,9 +59,56 @@
top: 0;
}
}
.course-catalog{
.course-catalog
{
margin-bottom:16px;
margin-top:16px;
display: flex;
.switch-box {
.switch-item {
display: flex;
align-items: center;
margin-bottom: 16px;
&:last-child {
margin-bottom: 0;
}
.switch-label {
color: #666;
}
.switch-tip {
color: #999;
margin-left: 4px;
}
}
}
}
.require {
color: red;
}
.introduce {
display: flex;
flex-direction: row;
}
.day {
display: flex;
flex-direction: row;
margin-bottom: 16px;
.select-day {
margin-bottom: 4px;
.mark-day {
color: #FFB714;
}
}
}
.allow-tourist-join{
display:flex;
margin-bottom:16px;
.desc {
color:#999;
margin-left:12px;
}
.content{
display:flex;
}
}
.course-ware {
display: flex;
...
...
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