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
bd6794c0
Commit
bd6794c0
authored
Aug 02, 2021
by
yuananting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:添加培训内容部分
parent
52a7b420
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
436 additions
and
12 deletions
+436
-12
src/common/less/icon-font.less
+3
-3
src/index.html
+1
-1
src/modules/task-center/train-task/AddTrainTask.jsx
+14
-2
src/modules/task-center/train-task/components/RelatedCourseDrawer.jsx
+0
-0
src/modules/task-center/train-task/components/RelatedCourseDrawer.less
+141
-0
src/modules/task-center/train-task/components/TrainContent.jsx
+218
-6
src/modules/task-center/train-task/components/TrainContent.less
+59
-0
No files found.
src/common/less/icon-font.less
View file @
bd6794c0
@font-face {
font-family: 'iconfont'; /* Project id 2223403 */
src: url('//at.alicdn.com/t/font_2223403_
oe5p510553.woff2?t=1624259078391
') format('woff2'),
url('//at.alicdn.com/t/font_2223403_
oe5p510553.woff?t=1624259078391
') format('woff'),
url('//at.alicdn.com/t/font_2223403_
oe5p510553.ttf?t=1624259078391
') format('truetype');
src: url('//at.alicdn.com/t/font_2223403_
e1xgcyaur7.woff2?t=1627810786858
') format('woff2'),
url('//at.alicdn.com/t/font_2223403_
e1xgcyaur7.woff?t=1627810786858
') format('woff'),
url('//at.alicdn.com/t/font_2223403_
e1xgcyaur7.ttf?t=1627810786858
') format('truetype');
}
.iconfont {
font-family: 'iconfont' !important;
...
...
src/index.html
View file @
bd6794c0
...
...
@@ -29,7 +29,7 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<link
rel=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_oe5p510553
.css"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_e1xgcyaur7
.css"
/>
<!--
Notice the use of %PUBLIC_URL% in the tags above.
...
...
src/modules/task-center/train-task/AddTrainTask.jsx
View file @
bd6794c0
...
...
@@ -2,7 +2,7 @@
* @Author: yuananting
* @Date: 2021-07-29 13:57:03
* @LastEditors: yuananting
* @LastEditTime: 2021-0
7-30 16:35:59
* @LastEditTime: 2021-0
8-02 10:42:28
* @Description: 任务中心-培训任务-新建页面
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
...
...
@@ -38,10 +38,18 @@ const DEFAULT_BASIC_INFO = {
percentCompletePicture
:
100
,
};
const
DEFAULT_TASK_LIST
=
[
{
taskName
:
'阶段一'
,
courseList
:
[],
},
];
function
AddTrainTask
()
{
const
type
=
getParameterByName
(
'type'
);
const
[
activeStep
,
setActiveStep
]
=
useState
(
'BASIC_INFO'
);
const
[
basicInfo
,
setBasicInfo
]
=
useState
(
DEFAULT_BASIC_INFO
);
const
[
taskList
,
setTaskList
]
=
useState
(
DEFAULT_TASK_LIST
);
function
renderFooter
()
{
return
(
...
...
@@ -81,6 +89,10 @@ function AddTrainTask() {
});
}
function
handleChangeTaskInfo
(
value
)
{
setTaskList
(
value
);
}
return
(
<
div
className=
'page add-train-task'
>
<
Breadcrumbs
navList=
{
type
==
'add'
?
'新建培训任务'
:
'编辑培训任务'
}
goBack=
{
handleGoBack
}
/>
...
...
@@ -93,7 +105,7 @@ function AddTrainTask() {
<
BasicInfo
data=
{
basicInfo
}
onChange=
{
handleChangeBasicInfo
}
/>
</
TabPane
>
<
TabPane
tab=
'2 培训内容'
key=
'TRAIN_CONTENT'
>
<
TrainContent
/>
<
TrainContent
data=
{
taskList
}
onChange=
{
handleChangeTaskInfo
}
/>
</
TabPane
>
</
Tabs
>
</
div
>
...
...
src/modules/task-center/train-task/components/RelatedCourseDrawer.jsx
0 → 100644
View file @
bd6794c0
This diff is collapsed.
Click to expand it.
src/modules/task-center/train-task/components/RelatedCourseDrawer.less
0 → 100644
View file @
bd6794c0
.related-course-drawer {
.link-create-course {
color: #666666;
font-size: 14px;
width: 638px;
text-align: left;
display: inline-block;
span {
color: #2966ff;
}
}
.search-container {
margin-bottom: 16px;
}
.select-area {
margin-bottom: 12px;
display: flex;
justify-content: space-between;
.select-box {
display: inline-box;
width: 186px;
background: #e9efff;
border-radius: 4px;
padding: 6px 16px;
margin-right: 8px;
display: flex;
justify-content: space-between;
.tip-icon {
color: #2966ff;
font-size: 14px;
margin-right: 4px;
}
.select-num {
color: #666666;
font-size: 14px;
}
.clear-btn {
text-align: right;
color: #2966ff;
font-size: 14px;
}
}
.related-box {
padding: 6px 16px;
background: #e9efff;
border-radius: 4px;
flex: 1;
color: #666666;
font-size: 14px;
}
}
.search-container {
margin-bottom: 16px;
}
.select-area {
margin-bottom: 12px;
display: flex;
justify-content: space-between;
.select-box {
display: inline-box;
width: 186px;
background: #e9efff;
border-radius: 4px;
padding: 6px 16px;
margin-right: 8px;
display: flex;
justify-content: space-between;
.tip-icon {
color: #2966ff;
font-size: 14px;
margin-right: 4px;
}
.select-num {
color: #666666;
font-size: 14px;
}
.clear-btn {
text-align: right;
color: #5289fa;
font-size: 14px;
}
}
.related-box {
padding: 6px 16px;
background: #e9efff;
border-radius: 4px;
flex: 1;
color: #666666;
font-size: 14px;
}
}
.course-info {
display: flex;
align-items: center;
.course-cover {
width: 97px;
height: 55px;
display: inline-block;
border-radius: 4px;
margin-right: 8px;
}
.course-name {
font-size: 14px;
color: #666;
text-overflow: -o-ellipsis-lastline;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
line-clamp: 2;
-webkit-box-orient: vertical;
width: 180px;
}
.course-status {
font-size: 12px;
line-height: 18px;
display: inline-block;
border-radius: 2px;
padding: 0 8px;
margin-top: 8px;
}
}
.footer {
position: fixed;
right: 0;
bottom: 0;
height: 50px;
width: 720px;
display: flex;
align-items: center;
justify-content: flex-end;
padding-right: 24px;
background: #fff;
border-top: 1px solid #e8e8e8;
z-index: 9999;
.ant-btn {
margin-left: 8px;
}
}
}
src/modules/task-center/train-task/components/TrainContent.jsx
View file @
bd6794c0
...
...
@@ -2,27 +2,239 @@
* @Author: yuananting
* @Date: 2021-07-30 16:33:58
* @LastEditors: yuananting
* @LastEditTime: 2021-0
7-30 16:58:03
* @LastEditTime: 2021-0
8-02 10:58:34
* @Description: 任务中心-培训任务-新建-培训内容
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import
React
from
'react'
;
import
{
Form
,
Button
,
Input
,
Space
,
DatePicker
,
Radio
,
Tag
,
Col
,
message
,
Tooltip
}
from
'antd'
;
import
React
,
{
Component
}
from
'react'
;
import
{
Form
,
Button
,
Input
,
Space
,
DatePicker
,
Radio
,
Tag
,
Col
,
message
,
Tooltip
,
Collapse
,
Dropdown
,
Menu
,
Drawer
}
from
'antd'
;
import
{
sortableContainer
,
sortableElement
,
sortableHandle
}
from
'react-sortable-hoc'
;
import
arrayMove
from
'array-move'
;
import
'./TrainContent.less'
;
import
RelatedCourseDrawer
from
'./RelatedCourseDrawer'
;
const
{
Panel
}
=
Collapse
;
const
SortableTaskContainer
=
sortableContainer
((
props
)
=>
<
div
{
...
props
}
></
div
>);
const
SortableTaskItem
=
sortableElement
((
props
)
=>
<
div
{
...
props
}
>
{
props
.
taskitem
}
</
div
>);
const
DragHandle
=
sortableHandle
(()
=>
<
span
className=
'drag-btn'
>
::
</
span
>);
class
TrainContent
extends
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
dataSource
:
props
.
data
,
showCourseDrawer
:
false
,
};
}
setTrianTypeOption
=
()
=>
{
return
(
<
Menu
>
<
Menu
.
Item
key=
'course'
onClick=
{
()
=>
this
.
setState
({
showCourseDrawer
:
true
})
}
>
<
img
className=
'type-option-icon'
src=
'https://image.xiaomaiketang.com/xm/6C2GjSpnDp.png'
/>
<
span
>
课程
</
span
>
</
Menu
.
Item
>
<
Menu
.
Item
key=
'exam'
>
<
img
className=
'type-option-icon'
src=
'https://image.xiaomaiketang.com/xm/M4BEXnRWbb.png'
/>
<
span
>
考试
</
span
>
</
Menu
.
Item
>
<
Menu
.
Item
key=
'homework'
>
<
img
className=
'type-option-icon'
src=
'https://image.xiaomaiketang.com/xm/ypWQcFWnxB.png'
/>
<
span
>
实操作业
</
span
>
</
Menu
.
Item
>
</
Menu
>
);
};
onTaskSortEnd
=
({
oldIndex
,
newIndex
})
=>
{
const
{
dataSource
}
=
this
.
state
;
if
(
oldIndex
!==
newIndex
)
{
const
newData
=
arrayMove
([].
concat
(
dataSource
),
oldIndex
,
newIndex
).
filter
((
el
)
=>
!!
el
);
this
.
setState
(
{
dataSource
:
newData
,
},
()
=>
{
this
.
props
.
onChange
(
newData
);
}
);
}
};
handleRenameTaskName
=
(
e
,
item
)
=>
{
const
{
value
}
=
e
.
target
;
const
{
dataSource
}
=
this
.
state
;
item
.
taskName
=
value
;
this
.
setState
(
{
dataSource
,
},
()
=>
{
this
.
props
.
onChange
(
dataSource
);
}
);
};
handleTaskNameBlur
=
(
e
,
item
)
=>
{
const
{
value
}
=
e
.
target
;
const
{
dataSource
}
=
this
.
state
;
let
input
=
/^
[\s]
*$/
;
if
(
value
&&
!
input
.
test
(
value
))
{
item
.
type
=
'text'
;
this
.
setState
(
{
dataSource
,
},
()
=>
{
this
.
props
.
onChange
(
dataSource
);
}
);
}
};
function
TrainContent
(
props
)
{
const
SortableTaskContainer
=
sortableContainer
((
props
)
=>
<
div
{
...
props
}
></
div
>);
handleValidatorTaskName
=
(
rule
,
value
)
=>
{
let
input
=
/^
[\s]
*$/
;
if
(
input
.
test
(
value
)
||
!
value
)
{
return
Promise
.
reject
(
new
Error
(
'请输入任务名称'
));
}
return
Promise
.
resolve
();
};
renderTaskInfo
=
(
item
,
index
)
=>
{
return
(
<
div
className=
'sort-task-item'
>
<
Choose
>
<
When
condition=
{
item
.
type
===
'input'
}
>
<
div
className=
'task-name-con'
>
{
/* <span className='number'>{index + 1}.</span> */
}
<
Form
>
<
Form
.
Item
initialValue=
{
item
.
taskName
}
validateTrigger=
{
[
'onChange'
,
'onBlur'
]
}
name=
{
[
'taskName'
]
}
rules=
{
[
{
validator
:
(
rule
,
value
)
=>
this
.
handleValidatorTaskName
(
rule
,
value
),
},
]
}
>
<
Input
className=
'task-name-input'
style=
{
{
width
:
300
}
}
placeholder=
'请输入阶段名称'
maxLength=
{
20
}
onChange=
{
(
e
)
=>
{
this
.
handleRenameTaskName
(
e
,
item
);
e
.
stopPropagation
();
}
}
onBlur=
{
(
e
)
=>
{
this
.
handleTaskNameBlur
(
e
,
item
);
e
.
stopPropagation
();
}
}
/>
</
Form
.
Item
>
</
Form
>
</
div
>
</
When
>
<
Otherwise
>
<
div
className=
'task-name-con'
>
{
/* <span className='number'>{index + 1}.</span> */
}
<
span
className=
'task-name'
>
{
item
.
taskName
}
</
span
>
</
div
>
</
Otherwise
>
</
Choose
>
<
span
className=
'item-operate'
>
<
span
className=
'operate__item'
onClick=
{
(
e
)
=>
{
const
{
dataSource
}
=
this
.
state
;
item
.
type
=
'input'
;
this
.
setState
({
dataSource
});
e
.
stopPropagation
();
}
}
>
<
span
className=
'icon iconfont'
>

</
span
>
<
span
className=
'text'
>
重命名
</
span
>
</
span
>
<
span
className=
'operate__item'
style=
{
{
marginLeft
:
16
}
}
onClick=
{
(
e
)
=>
{
this
.
handleDeleteTask
(
index
);
e
.
stopPropagation
();
}
}
>
<
span
className=
'icon iconfont'
>

</
span
>
<
span
className=
'text'
>
删除
</
span
>
</
span
>
</
span
>
<
DragHandle
/>
</
div
>
);
};
renderTaskItem
=
(
item
,
index
)
=>
{
return
(
<
Collapse
ghost
>
<
Panel
header=
{
this
.
renderTaskInfo
(
item
,
index
)
}
key=
{
index
}
>
{
/* {renderTaskItem(props.iteminfo, props.index)} */
}
<
Dropdown
overlay=
{
this
.
setTrianTypeOption
()
}
className=
'add-course-btn'
onClick=
{
()
=>
{
// this.showRelatedCourseModal(index);
}
}
>
<
span
>
+ 关联课程
</
span
>
</
Dropdown
>
</
Panel
>
</
Collapse
>
);
};
// 添加阶段
addStage
=
()
=>
{
const
{
dataSource
}
=
this
.
state
;
const
taskObj
=
{
taskName
:
''
,
index
:
dataSource
.
length
,
type
:
'input'
,
open
:
true
,
courseList
:
[],
};
const
newData
=
[...
dataSource
,
taskObj
];
this
.
setState
(
{
dataSource
:
newData
,
},
()
=>
{
this
.
props
.
onChange
(
newData
);
}
);
};
onCloseCourseDrawer
=
()
=>
{
this
.
setState
({
showCourseDrawer
:
false
,
});
};
render
()
{
const
{
dataSource
,
showCourseDrawer
}
=
this
.
state
;
return
(
<
div
className=
'train-content__warp'
>
<
SortableTaskContainer
useDragHandle
disableAutoscroll
helperClass=
'row-dragging'
onSortEnd=
{
this
.
onTaskSortEnd
}
className=
'plan-task-sort-container'
>
<
SortableTaskContainer
useDragHandle
disableAutoscroll
helperClass=
'row-dragging'
onSortEnd=
{
this
.
onTaskSortEnd
}
>
{
dataSource
.
map
((
item
,
index
)
=>
(
<
SortableTaskItem
taskitem=
{
this
.
renderTaskItem
(
item
,
index
)
}
index=
{
index
}
key=
{
index
}
></
SortableTaskItem
>
))
}
</
SortableTaskContainer
>
<
div
className=
'add-task-btn'
onClick=
{
()
=>
this
.
addStage
()
}
>
+ 添加阶段
</
div
>
<
RelatedCourseDrawer
data=
{
dataSource
}
onClose=
{
this
.
onCloseCourseDrawer
}
visible=
{
showCourseDrawer
}
/>
</
div
>
);
}
}
export
default
TrainContent
;
src/modules/task-center/train-task/components/TrainContent.less
0 → 100644
View file @
bd6794c0
.train-content__warp {
.ant-collapse-content {
padding-left: 24px !important;
}
}
.sort-task-item {
width: calc(100% - 24px);
display: inline-flex;
align-items: center;
.ant-form-item {
margin-bottom: 0 !important;
}
.item-name {
color: #333333;
}
.item-operate {
display: none;
margin-left: 30px;
.operate__item {
cursor: pointer;
.icon {
color: #bfbfbf;
font-size: 14px;
}
.text {
color: #666666;
margin-left: 8px;
}
}
}
&:hover {
.item-operate {
display: block;
}
}
.drag-btn {
margin-left: auto;
}
}
.add-course-btn {
color: #2966ff;
}
.add-task-btn {
color: #2966ff;
height: 52px;
background: #f7f8f9;
border-radius: 2px;
padding: 16px;
margin-top: 16px;
cursor: pointer;
}
.type-option-icon {
width: 20px;
height: 20px;
margin-right: 12px;
}
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