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
c4c91386
Commit
c4c91386
authored
Jul 29, 2021
by
yuananting
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:培训任务初始化
parent
4f646be7
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
730 additions
and
4 deletions
+730
-4
src/modules/task-center/TrainTaskPage.jsx
+65
-0
src/modules/task-center/components/TrainFilter.jsx
+197
-0
src/modules/task-center/components/TrainFilter.less
+39
-0
src/modules/task-center/components/TrainList.jsx
+284
-0
src/modules/task-center/components/TrainList.less
+88
-0
src/modules/task-center/components/TrainOpt.jsx
+33
-0
src/routes/config/mainRoutes.tsx
+8
-2
src/routes/config/menuList.tsx
+16
-2
No files found.
src/modules/task-center/TrainTaskPage.jsx
0 → 100644
View file @
c4c91386
/*
* @Author: yuananting
* @Date: 2021-07-28 11:25:58
* @LastEditors: yuananting
* @LastEditTime: 2021-07-28 15:41:00
* @Description: 任务中心-培训任务
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import
React
,
{
useEffect
,
useState
}
from
'react'
import
TrainFilter
from
'./components/TrainFilter'
import
TrainOpt
from
'./components/TrainOpt'
import
TrainList
from
'./components/TrainList'
// import PlanList from './components/PlanList'
import
PlanService
from
'@/domains/plan-domain/planService'
import
User
from
'@/common/js/user'
function
TrainTaskPage
()
{
const
[
trainListData
,
setTrainListData
]
=
useState
([])
// 培训任务列表
const
[
query
,
setQuery
]
=
useState
({
current
:
1
,
size
:
10
})
const
[
totalCount
,
setTotalCount
]
=
useState
(
0
)
// 总数
useEffect
(()
=>
{
handleFetchTrainList
()
},
[
query
])
function
handleFetchTrainList
(
_query
)
{
const
params
=
{
...
query
,
...
_query
,
storeUserId
:
User
.
getStoreUserId
()
}
//动态获取计划列表
PlanService
.
getTrainingPlanPage
(
params
).
then
((
res
)
=>
{
const
{
result
:
{
records
=
[],
total
}
}
=
res
setTrainListData
(
records
)
setTotalCount
(
total
)
})
}
function
queryChange
(
_query
)
{
const
params
=
{
...
query
,
...
_query
}
setQuery
(
params
)
}
return
(
<
div
className=
'page'
>
<
div
className=
'content-header'
>
培训任务
</
div
>
<
div
className=
'box'
>
<
TrainFilter
/>
<
TrainOpt
/>
<
TrainList
trainListData=
{
trainListData
}
/>
{
/* <PlanList planListData={planListData} query={query} totalCount={totalCount} onChange={queryChange} /> */
}
</
div
>
</
div
>
)
}
export
default
TrainTaskPage
\ No newline at end of file
src/modules/task-center/components/TrainFilter.jsx
0 → 100644
View file @
c4c91386
/*
* @Author: 吴文洁
* @Date: 2020-07-14 15:41:30
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-07-23 13:45:16
* @Description: 大班直播、互动班课列表的筛选组件
*/
import
React
,
{
useState
,
useEffect
}
from
'react'
;
import
{
withRouter
}
from
'react-router-dom'
;
import
{
Row
,
Input
,
Select
,
Tooltip
}
from
'antd'
;
import
RangePicker
from
"@/modules/common/DateRangePicker"
;
import
moment
from
'moment'
;
import
StoreService
from
"@/domains/store-domain/storeService"
;
import
'./TrainFilter.less'
;
const
{
Search
}
=
Input
;
const
{
Option
}
=
Select
;
const
DEFAULT_QUERY
=
{
// 头部筛选默认值
planName
:
null
,
startTime
:
null
,
endTime
:
null
,
enableState
:
null
,
createId
:
null
}
const
DEFAULT_CREATOR_QUERY
=
{
// 创建人列表筛选默认值
size
:
10
,
current
:
1
,
nickName
:
null
}
function
TrainFilter
(
props
)
{
const
[
expandFilter
,
setExpandFilter
]
=
useState
(
false
);
const
[
query
,
setQuery
]
=
useState
(
DEFAULT_QUERY
);
const
[
hasNext
,
setHasNext
]
=
useState
(
false
);
const
[
creatorQuery
,
setCreatorQuery
]
=
useState
(
DEFAULT_CREATOR_QUERY
);
const
[
creatorList
,
setCreatorList
]
=
useState
([]);
useEffect
(()
=>
{
getCreatorList
();
},
[]);
// 获取创建人列表
function
getCreatorList
(
current
=
1
,
selectList
){
const
_query
=
{
...
creatorQuery
,
current
,
};
StoreService
.
getStoreUserBasicPage
(
_query
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
records
=
[],
hasNext
}
=
result
;
const
list
=
current
>
1
?
creatorList
.
concat
(
records
)
:
records
;
setHasNext
(
hasNext
);
setCreatorList
(
list
);
});
}
// 滑动加载更多讲师列表
function
handleScrollCreatorList
(
e
){
const
container
=
e
.
target
;
const
scrollToBottom
=
container
&&
container
.
scrollHeight
<=
container
.
clientHeight
+
container
.
scrollTop
;
if
(
scrollToBottom
&&
hasNext
)
{
const
_creatorQuery
=
{...
creatorQuery
};
_creatorQuery
.
current
=
creatorQuery
.
current
+
1
;
setCreatorQuery
(
_creatorQuery
);
getCreatorList
(
creatorQuery
.
current
+
1
);
}
}
// 改变搜索条件
function
handleChangeQuery
(
field
,
value
){
const
_query
=
{
...
query
,
[
field
]:
value
,
current
:
1
,
}
setQuery
(
_query
);
if
(
field
===
'planName'
)
return
;
// props.onChange( _query);
}
function
handleChangeDates
(
dates
){
const
_query
=
_
.
clone
(
query
);
if
(
_
.
isEmpty
(
dates
))
{
delete
_query
.
startTime
;
delete
_query
.
endTime
;
}
else
{
_query
.
startTime
=
dates
[
0
].
valueOf
();
_query
.
endTime
=
dates
[
1
].
valueOf
();
}
const
param
=
{
...
_query
,
current
:
1
,
}
setQuery
(
param
);
props
.
onChange
(
param
);
}
// 重置搜索条件
function
handleReset
(){
setQuery
(
DEFAULT_QUERY
);
// props.onChange(DEFAULT_QUERY);
}
return
(
<
div
className=
"train-filter-page"
>
<
Row
>
<
div
className=
"search-condition"
>
<
div
className=
"search-condition__item"
>
<
span
>
培训任务:
</
span
>
<
Search
value=
{
query
.
planName
}
placeholder=
"搜索培训任务名称"
onChange=
{
(
e
)
=>
{
handleChangeQuery
(
'planName'
,
e
.
target
.
value
.
trim
())}
}
// onSearch={ () => { props.onChange(query) } }
style=
{
{
width
:
"calc(100% - 70px)"
}
}
enterButton=
{
<
span
className=
"icon iconfont"
>

</
span
>
}
/>
</
div
>
<
div
className=
"search-condition__item"
>
<
span
>
创建人:
</
span
>
<
Select
placeholder=
"请选择创建人"
style=
{
{
width
:
"calc(100% - 70px)"
}
}
showSearch
allowClear
filterOption=
{
(
input
,
option
)
=>
option
}
suffixIcon=
{
<
span
className=
"icon iconfont"
style=
{
{
fontSize
:
'12px'
,
color
:
'#BFBFBF'
}
}
>

</
span
>
}
onPopupScroll=
{
handleScrollCreatorList
}
value=
{
query
.
createId
}
// onChange={(value) => {
// handleChangeQuery('createId', value)
// }}
// onSearch={(value) => {
// creatorQuery.nickName = value
// setCreatorQuery(creatorQuery)
// getCreatorList()
// }
// }
// onClear ={(value)=>{
// setCreatorQuery({
// size: 10,
// current: 1,
// nickName:null
// })
// getCreatorList()
// }
// }
>
{
_
.
map
(
creatorList
,
(
item
,
index
)
=>
{
return
(
<
Select
.
Option
value=
{
item
.
id
}
key=
{
item
.
id
}
>
{
item
.
nickName
}
</
Select
.
Option
>
);
})
}
</
Select
>
</
div
>
<
div
className=
"search-condition__item"
>
<
span
className=
"search-date"
>
创建日期:
</
span
>
<
RangePicker
id=
"course_date_picker"
allowClear=
{
false
}
value=
{
query
.
startTime
?
[
moment
(
query
.
startTime
),
moment
(
query
.
endTime
)]
:
null
}
format=
{
"YYYY-MM-DD"
}
onChange=
{
(
dates
)
=>
{
handleChangeDates
(
dates
)
}
}
style=
{
{
width
:
"calc(100% - 70px)"
}
}
/>
</
div
>
{
expandFilter
&&
<
div
className=
"search-condition__item"
>
<
span
className=
"shelf-status"
>
当前状态:
</
span
>
<
Select
style=
{
{
width
:
"calc(100% - 70px)"
}
}
placeholder=
"请选择当前状态"
allowClear=
{
true
}
value=
{
query
.
enableState
}
onChange=
{
(
value
)
=>
{
handleChangeQuery
(
'enableState'
,
value
)
}
}
suffixIcon=
{
<
span
className=
"icon iconfont"
style=
{
{
fontSize
:
'12px'
,
color
:
'#BFBFBF'
}
}
>

</
span
>
}
>
<
Option
value=
"YES"
>
开启
</
Option
>
<
Option
value=
"NO"
>
关闭
</
Option
>
</
Select
>
</
div
>
}
</
div
>
<
div
className=
"reset-fold-area"
>
<
Tooltip
title=
"清空筛选"
><
span
className=
"resetBtn iconfont icon"
onClick=
{
handleReset
}
>

</
span
></
Tooltip
>
<
span
style=
{
{
cursor
:
'pointer'
}
}
className=
"fold-btn"
onClick=
{
()
=>
{
setExpandFilter
(
!
expandFilter
)
}
}
>
{
expandFilter
?
<
span
><
span
>
收起
</
span
><
span
className=
"iconfont icon fold-icon"
>

</
span
>
</
span
>
:
<
span
>
展开
<
span
className=
"iconfont icon fold-icon"
>

</
span
></
span
>
}
</
span
>
</
div
>
</
Row
>
</
div
>
)
}
export
default
withRouter
(
TrainFilter
);
\ No newline at end of file
src/modules/task-center/components/TrainFilter.less
0 → 100644
View file @
c4c91386
.train-filter-page {
position: relative;
margin-bottom: 4px;
.ant-input-search-button{
border-left:none;
}
.search-condition {
width: calc(100% - 80px);
display: flex;
align-items: center;
flex-wrap: wrap;
&__item {
width: 30%;
margin-right: 3%;
margin-bottom: 12px;
line-height: 32px;
}
}
.reset-fold-area {
position: absolute;
right: 12px;
}
.resetBtn {
color: #999999;
font-size: 18px;
margin-right: 8px;
}
.fold-btn {
font-size: 14px;
color: #666666;
line-height: 20px;
.fold-icon {
font-size: 12px;
margin-left:4px;
}
}
}
\ No newline at end of file
src/modules/task-center/components/TrainList.jsx
0 → 100644
View file @
c4c91386
/*
* @Author: yuananting
* @Date: 2021-07-28 14:56:52
* @LastEditors: yuananting
* @LastEditTime: 2021-07-29 09:42:01
* @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import
React
,
{
useState
,
useEffect
}
from
"react"
;
import
{
Tabs
,
Tooltip
,
Switch
,
Dropdown
}
from
"antd"
;
import
"./TrainList.less"
;
import
{
XMTable
,
PageControl
}
from
"@/components"
;
import
User
from
"@/common/js/user"
;
const
{
TabPane
}
=
Tabs
;
function
renderMoreOperate
(
item
)
{
return
(
<
div
className=
"live-course-more-menu"
>
<
div
className=
"operate__item"
>
编辑
</
div
>
<
div
className=
"operate__item"
>
分享
</
div
>
<
div
className=
"operate__item"
>
审批作业
</
div
>
<
div
className=
"operate__item"
>
删除
</
div
>
</
div
>
);
}
function
parseColumns
()
{
const
columns
=
[
{
title
:
"培训任务"
,
key
:
"planName"
,
dataIndex
:
"planName"
,
width
:
"18%"
,
fixed
:
"left"
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"plan_name_item"
>
<
img
className=
"plan-cover"
src=
{
record
.
coverUrl
||
"https://image.xiaomaiketang.com/xm/rEAetaTEh3.png"
}
alt=
""
/>
<
Choose
>
<
When
condition=
{
record
.
planName
.
length
>
25
}
>
<
Tooltip
title=
{
record
.
planName
}
>
<
div
className=
"plan-name"
>
{
val
}
</
div
>
</
Tooltip
>
</
When
>
<
Otherwise
>
<
div
className=
"plan-name"
>
{
val
}
</
div
>
</
Otherwise
>
</
Choose
>
</
div
>
);
},
},
{
title
:
"任务状态"
,
width
:
"10%"
,
key
:
"status"
,
dataIndex
:
"status"
,
render
:
(
val
,
record
)
=>
{
return
<
div
className=
"course-number"
>
{
"未开始"
}
</
div
>;
},
},
{
title
:
"任务数"
,
width
:
"10%"
,
key
:
"courseNum"
,
dataIndex
:
"courseNum"
,
render
:
(
val
,
record
)
=>
{
return
<
div
className=
"course-number"
>
{
val
}
</
div
>;
},
},
{
title
:
"学习人数"
,
width
:
"10%"
,
align
:
"right"
,
key
:
"cultureCustomerNum"
,
dataIndex
:
"cultureCustomerNum"
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
<
div
className=
"join-number"
>
{
val
}
</
div
>;
},
},
{
title
:
(
<
span
>
完成率
<
Tooltip
title=
"完成培训任务的人数/学习总人数"
>
<
i
className=
"icon iconfont"
style=
{
{
marginLeft
:
"5px"
,
cursor
:
"pointer"
,
color
:
"#bfbfbf"
,
fontSize
:
"14px"
,
fontWeight
:
"normal"
,
}
}
>

</
i
>
</
Tooltip
>
</
span
>
),
width
:
"10%"
,
key
:
"rate"
,
dataIndex
:
"rate"
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
<
span
>
100%
</
span
>
},
},
{
title
:
"培训时间"
,
width
:
"12.5%"
,
key
:
"created"
,
dataIndex
:
"created"
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
(
<
span
style=
{
{
whiteSpace
:
"nowrap"
}
}
>
{
window
.
formatDate
(
"YYYY-MM-DD H:i"
,
val
)
}
</
span
>
);
},
},
{
title
:
"创建人"
,
key
:
"createName"
,
dataIndex
:
"createName"
,
width
:
"11%"
,
render
:
(
val
)
=>
{
return
<
div
className=
"create-name"
>
{
val
}
</
div
>;
},
},
{
title
:
"创建时间"
,
width
:
"12.5%"
,
key
:
"created"
,
dataIndex
:
"created"
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
(
<
span
style=
{
{
whiteSpace
:
"nowrap"
}
}
>
{
window
.
formatDate
(
"YYYY-MM-DD H:i"
,
val
)
}
</
span
>
);
},
},
{
title
:
"更新时间"
,
width
:
"10%"
,
key
:
"updated"
,
dataIndex
:
"updated"
,
sorter
:
true
,
render
:
(
val
)
=>
{
return
(
<
span
style=
{
{
whiteSpace
:
"nowrap"
}
}
>
{
window
.
formatDate
(
"YYYY-MM-DD H:i"
,
val
)
}
</
span
>
);
},
},
{
title
:
"操作"
,
key
:
"operate"
,
dataIndex
:
"operate"
,
fixed
:
"right"
,
width
:
"18%"
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"operate"
>
<
div
className=
"operate__item"
onClick=
{
()
=>
toLearningDataPage
(
record
)
}
>
数据
</
div
>
{
record
.
enableState
===
"YES"
&&
(
<>
<
span
className=
"operate__item split"
>
|
</
span
>
<
div
className=
"operate__item"
onClick=
{
()
=>
{
handleShowShareModal
(
record
);
}
}
>
指派
</
div
>
</>
)
}
{
record
.
enableState
===
"YES"
&&
(
<>
<
span
className=
"operate__item split"
>
|
</
span
>
<
div
className=
"operate__item"
onClick=
{
()
=>
{
handleShowShareModal
(
record
);
}
}
>
发布
</
div
>
</>
)
}
{
(
User
.
getUserRole
()
===
"CloudManager"
||
User
.
getUserRole
()
===
"StoreManager"
)
&&
(
<>
<
span
className=
"operate__item split"
>
|
</
span
>
<
Dropdown
overlay=
{
renderMoreOperate
(
record
)
}
>
<
span
className=
"more-operate"
>
<
span
className=
"operate-text"
>
更多
</
span
>
<
span
className=
"iconfont icon"
style=
{
{
color
:
"#2966FF"
}
}
>

</
span
>
</
span
>
</
Dropdown
>
</>
)
}
</
div
>
);
},
},
];
return
columns
;
}
function
TrainList
(
props
)
{
console
.
log
(
props
.
trainListData
);
return
(
<
div
className=
"train-list-page"
>
<
div
className=
"search-box"
>
<
Tabs
type=
"card"
>
<
TabPane
tab=
"全部"
key=
"all"
/>
<
TabPane
tab=
"已发布"
key=
"published"
/>
<
TabPane
tab=
"未发布"
key=
"unpublished"
/>
</
Tabs
>
</
div
>
<
div
className=
"list-content"
>
<
XMTable
rowKey=
{
(
record
)
=>
record
.
id
}
showSorterTooltip=
{
false
}
dataSource=
{
props
.
trainListData
}
columns=
{
parseColumns
()
}
pagination=
{
false
}
// onChange={handleChangeTable}
bordered
size=
"middle"
scroll=
{
{
x
:
1400
}
}
// className='plan-list-table'
renderEmpty=
{
{
description
:
(
<
span
style=
{
{
display
:
"block"
,
paddingBottom
:
24
}
}
>
暂无数据
</
span
>
),
}
}
/>
{
/* <div className='box-footer'>
<PageControl
current={props.query.current - 1}
pageSize={props.query.size}
total={props.totalCount}
toPage={(page) => {
// const _query = { ...props.query, current: page + 1 };
// props.onChange(_query);
}}
// onShowSizeChange={onShowSizeChange}
/> */
}
{
/* </div> */
}
</
div
>
</
div
>
);
}
export
default
TrainList
;
src/modules/task-center/components/TrainList.less
0 → 100644
View file @
c4c91386
.train-list-page {
margin-top: 12px;
.ant-tabs-nav {
margin: 0 !important;
}
.course-number {
margin-right: 45px;
}
.plan-list-table {
thead.ant-table-thead {
tr {
th {
padding: 10px 12px;
}
}
}
tbody {
tr {
td.ant-table-cell {
padding: 16px 12px;
color: #333;
}
&:nth-child(even) {
background: transparent;
td {
background: #fff;
}
}
&:nth-child(odd) {
background: #fafafa;
td {
background: #fafafa;
}
}
&:hover {
td {
background: #f3f6fa;
}
}
}
}
}
.plan_name_item {
display: flex;
align-items: center;
.plan-cover {
width: 106px;
height: 60px;
border-radius: 2px;
margin-right: 8px;
}
.plan-name {
width: 188px;
overflow: hidden;
text-overflow: ellipsis;
display: -webkit-box;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
height: 40px;
}
}
.operate-text {
color: #2966ff;
cursor: pointer;
}
.operate {
display: flex;
&__item {
color: #2966ff;
cursor: pointer;
&.split {
margin: 0 8px;
color: #bfbfbf;
}
}
}
.join-number {
text-align: right;
margin-right: 12px;
}
.more-operate {
line-height: 20px;
}
}
src/modules/task-center/components/TrainOpt.jsx
0 → 100644
View file @
c4c91386
/*
* @Author: zhangleyuan
* @Date: 2021-02-20 16:45:51
* @LastEditors: yuananting
* @LastEditTime: 2021-07-28 14:46:51
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import
React
from
'react'
;
import
{
Button
}
from
'antd'
;
import
{
withRouter
}
from
'react-router-dom'
;
import
User
from
'@/common/js/user'
;
// import './PlanOpt.less';
function
PlanOpt
()
{
function
handleCreatePlan
(){
window
.
RCHistory
.
push
({
pathname
:
'/create-plan?type=add'
,
})
}
return
(
<
div
className=
"plan-opt-page"
>
{
(
User
.
getUserRole
()
===
"CloudManager"
||
User
.
getUserRole
()
===
"StoreManager"
)
&&
<
Button
type=
"primary"
className=
"mr12"
onClick=
{
handleCreatePlan
}
>
新建培训任务
</
Button
>
}
</
div
>
);
}
export
default
withRouter
(
PlanOpt
)
\ No newline at end of file
src/routes/config/mainRoutes.tsx
View file @
c4c91386
/*
* @Author: 吴文洁
* @Date: 2020-04-29 10:26:32
* @LastEditors:
wufan
* @LastEditTime: 2021-0
5-13 16:39:51
* @LastEditors:
yuananting
* @LastEditTime: 2021-0
7-28 11:33:13
* @Description: 内容线路由配置
*/
import
Home
from
'@/modules/home/Home'
;
...
...
@@ -36,6 +36,7 @@ import ExaminationManagerIndex from '@/modules/teach-tool/examination-manager/In
import
ExaminationManagerTestDetail
from
'@/modules/teach-tool/examination-manager/TestDetailPage'
;
import
KnowledgeBase
from
'@/modules/knowledge-base/index'
;
import
CollegeInfoPage
from
'@/modules/college-manage/CollegeInfoPage'
;
import
TrainTaskPage
from
'@/modules/task-center/TrainTaskPage'
;
const
mainRoutes
=
[
{
...
...
@@ -161,6 +162,11 @@ const mainRoutes = [
name
:
'培训计划'
,
},
{
path
:
'/train-task'
,
component
:
TrainTaskPage
,
name
:
'培训任务'
,
},
{
path
:
'/create-plan'
,
component
:
AddPlanPage
,
name
:
'创建线上课'
,
...
...
src/routes/config/menuList.tsx
View file @
c4c91386
/*
* @Author: yuananting
* @Date: 2021-02-21 15:53:31
* @LastEditors:
wufan
* @LastEditTime: 2021-07-
05 10:29:23
* @LastEditors:
yuananting
* @LastEditTime: 2021-07-
28 11:29:17
* @Description: 描述一下咯
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
...
...
@@ -59,6 +59,20 @@ export const menuList: any = [
],
},
{
groupName
:
'任务中心'
,
groupCode
:
'TrainManage'
,
icon
:
''
,
img
:
'https://image.xiaomaiketang.com/xm/Yy6pZ6G6kS.png'
,
selectImg
:
'https://image.xiaomaiketang.com/xm/Z8G6NMQhaH.png'
,
children
:
[
{
groupName
:
'培训任务'
,
groupCode
:
'TrainPlan'
,
link
:
'/train-task'
,
},
],
},
{
groupName
:
'助学工具'
,
groupCode
:
'AidTool'
,
icon
:
''
,
...
...
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