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
2d3a9245
Commit
2d3a9245
authored
Mar 02, 2021
by
zhangleyuan
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
feat:处理创建培训计划
parent
4e8a79af
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
24 changed files
with
1010 additions
and
159 deletions
+1010
-159
src/common/less/icon-font.less
+6
-6
src/data-source/plan/request-apis.ts
+7
-1
src/domains/plan-domain/planService.ts
+9
-2
src/h5.html
+2
-2
src/index.html
+2
-2
src/modules/course-manage/components/AddLiveBasic.jsx
+15
-15
src/modules/plan-manage/AddPlan.jsx
+124
-13
src/modules/plan-manage/LearningData.jsx
+65
-0
src/modules/plan-manage/LearningData.less
+58
-0
src/modules/plan-manage/components/BasicInfo.jsx
+0
-0
src/modules/plan-manage/components/BasicInfo.less
+1
-1
src/modules/plan-manage/components/EmployeeShareData.jsx
+179
-0
src/modules/plan-manage/components/EmployeeShareData.less
+6
-0
src/modules/plan-manage/components/PlanList.jsx
+7
-3
src/modules/plan-manage/components/TrainingTask.jsx
+43
-101
src/modules/plan-manage/components/UserLearningData.jsx
+173
-0
src/modules/plan-manage/components/UserLearningData.less
+0
-0
src/modules/plan-manage/components/UserLearningDataFilter.jsx
+198
-0
src/modules/plan-manage/components/UserLearningDataFilter.less
+43
-0
src/modules/plan-manage/modal/SelectOperatorModal.jsx
+2
-1
src/modules/plan-manage/modal/relatedCourseModal.jsx
+27
-8
src/modules/store-manage/EmployeeAddOrEditModal.tsx
+3
-3
src/routes/config/mainRoutes.tsx
+15
-1
src/routes/config/menuList.tsx
+25
-0
No files found.
src/common/less/icon-font.less
View file @
2d3a9245
@font-face {
@font-face {
font-family: 'iconfont'; /* project id 2223403 */
font-family: 'iconfont'; /* project id 2223403 */
src: url('//at.alicdn.com/t/font_2223403_
fad4h32dwuo
.eot');
src: url('//at.alicdn.com/t/font_2223403_
325yz7wxu2d
.eot');
src: url('//at.alicdn.com/t/font_2223403_
fad4h32dwuo
.eot?#iefix') format('embedded-opentype'),
src: url('//at.alicdn.com/t/font_2223403_
325yz7wxu2d
.eot?#iefix') format('embedded-opentype'),
url('//at.alicdn.com/t/font_2223403_
fad4h32dwuo
.woff2') format('woff2'),
url('//at.alicdn.com/t/font_2223403_
325yz7wxu2d
.woff2') format('woff2'),
url('//at.alicdn.com/t/font_2223403_
fad4h32dwuo
.woff') format('woff'),
url('//at.alicdn.com/t/font_2223403_
325yz7wxu2d
.woff') format('woff'),
url('//at.alicdn.com/t/font_2223403_
fad4h32dwuo
.ttf') format('truetype'),
url('//at.alicdn.com/t/font_2223403_
325yz7wxu2d
.ttf') format('truetype'),
url('//at.alicdn.com/t/font_2223403_
fad4h32dwuo
.svg#iconfont') format('svg');
url('//at.alicdn.com/t/font_2223403_
325yz7wxu2d
.svg#iconfont') format('svg');
}
}
.iconfont{
.iconfont{
font-family:"iconfont" !important;
font-family:"iconfont" !important;
...
...
src/data-source/plan/request-apis.ts
View file @
2d3a9245
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: zhangleyuan
* @Author: zhangleyuan
* @Date: 2021-02-21 16:08:38
* @Date: 2021-02-21 16:08:38
* @LastEditors: zhangleyuan
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-03-0
1 10:21:33
* @LastEditTime: 2021-03-0
2 13:49:32
* @Description: 描述一下
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -17,3 +17,9 @@ export function createTrainingPlan(params: object) {
...
@@ -17,3 +17,9 @@ export function createTrainingPlan(params: object) {
export
function
updateStateTrainingPlan
(
params
:
object
)
{
export
function
updateStateTrainingPlan
(
params
:
object
)
{
return
Service
.
Hades
(
"public/hades/updateStateTrainingPlan"
,
params
);
return
Service
.
Hades
(
"public/hades/updateStateTrainingPlan"
,
params
);
}
}
export
function
getTrainingPlanDetail
(
params
:
object
)
{
return
Service
.
Hades
(
"public/hades/getTrainingPlanDetail"
,
params
);
}
export
function
updateTrainingPlan
(
params
:
object
)
{
return
Service
.
Hades
(
"public/hades/updateTrainingPlan"
,
params
);
}
src/domains/plan-domain/planService.ts
View file @
2d3a9245
...
@@ -2,11 +2,11 @@
...
@@ -2,11 +2,11 @@
* @Author: zhangleyuan
* @Author: zhangleyuan
* @Date: 2021-02-21 16:15:38
* @Date: 2021-02-21 16:15:38
* @LastEditors: zhangleyuan
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-03-0
1 10:22:19
* @LastEditTime: 2021-03-0
2 13:50:18
* @Description: 描述一下
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
import
{
getTrainingPlanPage
,
createTrainingPlan
,
updateStateTrainingPlan
}
from
'@/data-source/plan/request-apis'
;
import
{
getTrainingPlanPage
,
createTrainingPlan
,
updateStateTrainingPlan
,
getTrainingPlanDetail
,
updateTrainingPlan
}
from
'@/data-source/plan/request-apis'
;
export
default
class
PlanService
{
export
default
class
PlanService
{
// 获取员工列表
// 获取员工列表
static
getTrainingPlanPage
(
params
:
any
)
{
static
getTrainingPlanPage
(
params
:
any
)
{
...
@@ -18,4 +18,10 @@ export default class PlanService {
...
@@ -18,4 +18,10 @@ export default class PlanService {
static
updateStateTrainingPlan
(
params
:
any
)
{
static
updateStateTrainingPlan
(
params
:
any
)
{
return
updateStateTrainingPlan
(
params
);
return
updateStateTrainingPlan
(
params
);
}
}
static
getTrainingPlanDetail
(
params
:
any
)
{
return
getTrainingPlanDetail
(
params
);
}
static
updateTrainingPlan
(
params
:
any
)
{
return
updateTrainingPlan
(
params
);
}
}
}
\ No newline at end of file
src/h5.html
View file @
2d3a9245
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Author: 吴文洁
* @Date: 2020-08-24 12:20:57
* @Date: 2020-08-24 12:20:57
* @LastEditors: zhangleyuan
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-0
2-24 15:31:49
* @LastEditTime: 2021-0
3-02 15:16:04
* @Description:
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
* @Copyright: 杭州杰竞科技有限公司 版权所有
-->
-->
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
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=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
fad4h32dwuo
.css"
>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
325yz7wxu2d
.css"
>
<!--
<!--
Notice the use of %PUBLIC_URL% in the tags above.
Notice the use of %PUBLIC_URL% in the tags above.
...
...
src/index.html
View file @
2d3a9245
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Author: 吴文洁
* @Date: 2020-08-24 12:20:57
* @Date: 2020-08-24 12:20:57
* @LastEditors: zhangleyuan
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-0
2-24 15:31:42
* @LastEditTime: 2021-0
3-02 15:16:11
* @Description:
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
* @Copyright: 杭州杰竞科技有限公司 版权所有
-->
-->
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
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=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
fad4h32dwuo
.css"
>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
325yz7wxu2d
.css"
>
<!--
<!--
Notice the use of %PUBLIC_URL% in the tags above.
Notice the use of %PUBLIC_URL% in the tags above.
...
...
src/modules/course-manage/components/AddLiveBasic.jsx
View file @
2d3a9245
...
@@ -272,21 +272,21 @@ class AddLiveBasic extends React.Component {
...
@@ -272,21 +272,21 @@ class AddLiveBasic extends React.Component {
onClose=
{
()
=>
this
.
setState
({
showCutModal
:
false
})
}
onClose=
{
()
=>
this
.
setState
({
showCutModal
:
false
})
}
reUpload=
{
()
=>
{
this
.
state
.
currentInputFile
.
click
()
}
}
reUpload=
{
()
=>
{
this
.
state
.
currentInputFile
.
click
()
}
}
/>
/>
{
showSelectFileModal
&&
{
showSelectFileModal
&&
<
SelectPrepareFileModal
<
SelectPrepareFileModal
key=
"basic"
key=
"basic"
operateType=
"select"
operateType=
"select"
multiple=
{
false
}
multiple=
{
false
}
accept=
"image/jpeg,image/png,image/jpg"
accept=
"image/jpeg,image/png,image/jpg"
selectTypeList=
{
[
'JPG'
,
'JPEG'
,
'PNG'
]
}
selectTypeList=
{
[
'JPG'
,
'JPEG'
,
'PNG'
]
}
tooltip=
'支持文件类型:jpg、jpeg、png'
tooltip=
'支持文件类型:jpg、jpeg、png'
isOpen=
{
showSelectFileModal
}
isOpen=
{
showSelectFileModal
}
onClose=
{
()
=>
{
onClose=
{
()
=>
{
this
.
setState
({
showSelectFileModal
:
false
})
this
.
setState
({
showSelectFileModal
:
false
})
}
}
}
}
onSelect=
{
this
.
handleSelectCover
}
onSelect=
{
this
.
handleSelectCover
}
/>
/>
}
}
<
Modal
<
Modal
title=
"设置图片"
title=
"设置图片"
width=
{
1080
}
width=
{
1080
}
...
...
src/modules/plan-manage/AddPlan.jsx
View file @
2d3a9245
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: zhangleyuan
* @Author: zhangleyuan
* @Date: 2021-02-20 16:13:39
* @Date: 2021-02-20 16:13:39
* @LastEditors: zhangleyuan
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-0
2-28 19:05:50
* @LastEditTime: 2021-0
3-02 20:11:09
* @Description: 描述一下
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -16,8 +16,11 @@ import PlanService from '@/domains/plan-domain/planService'
...
@@ -16,8 +16,11 @@ import PlanService from '@/domains/plan-domain/planService'
import
User
from
'@/common/js/user'
;
import
User
from
'@/common/js/user'
;
import
_
from
"underscore"
;
import
_
from
"underscore"
;
import
'./AddPlan.less'
import
'./AddPlan.less'
const
DEFAULT_BASIC_DATA
=
{
const
defaultCover
=
'https://image.xiaomaiketang.com/xm/YNfi45JwFA.png'
;
const
defaultBasicData
=
{
planName
:
""
,
planName
:
""
,
coverUrl
:
defaultCover
,
coverId
:
null
,
enableState
:
"YES"
,
enableState
:
"YES"
,
selectOperatorList
:[],
selectOperatorList
:[],
instro
:
''
,
instro
:
''
,
...
@@ -25,9 +28,63 @@ const DEFAULT_BASIC_DATA = {
...
@@ -25,9 +28,63 @@ const DEFAULT_BASIC_DATA = {
percentCompleteLive
:
80
,
percentCompleteLive
:
80
,
percentCompleteVideo
:
80
percentCompleteVideo
:
80
}
}
const
defaultTaskList
=
[];
function
AddPlan
()
{
function
AddPlan
()
{
const
[
basicData
,
setBasicData
]
=
useState
(
DEFAULT_BASIC_DATA
);
const
id
=
getParameterByName
(
"id"
);
const
[
taskList
,
setTaskList
]
=
useState
([]);
const
type
=
getParameterByName
(
"type"
);
const
[
basicData
,
setBasicData
]
=
useState
(
defaultBasicData
);
const
[
taskList
,
setTaskList
]
=
useState
(
defaultTaskList
);
useEffect
(()
=>
{
if
(
type
===
'edit'
){
getPlanDetail
();
}
},
id
)
function
getPlanDetail
(){
PlanService
.
getTrainingPlanDetail
({
planId
:
id
}).
then
((
res
)
=>
{
const
{
planName
,
enableState
,
operateType
,
operateIds
,
percentCompleteLive
,
percentCompleteVideo
,
courseMediaVOS
,
trainingTaskList
}
=
res
.
result
;
let
coverId
;
let
coverUrl
;
let
instro
;
courseMediaVOS
.
map
((
item
)
=>
{
switch
(
item
.
contentType
){
case
"COVER"
:
coverId
=
item
.
mediaContent
;
coverUrl
=
item
.
mediaUrl
;
break
;
case
"INTRO"
:
instro
=
item
.
mediaContent
;
break
;
default
:
break
;
}
return
item
;
})
setBasicData
({
planName
,
coverUrl
,
coverId
,
enableState
,
selectOperatorList
:
operateIds
||
[],
instro
,
operateType
,
percentCompleteLive
,
percentCompleteVideo
})
setTaskList
(
trainingTaskList
)
})
}
function
handleChangeBasicInfo
(
field
,
value
){
function
handleChangeBasicInfo
(
field
,
value
){
setBasicData
(
{
setBasicData
(
{
...
basicData
,
...
basicData
,
...
@@ -40,7 +97,7 @@ function AddPlan() {
...
@@ -40,7 +97,7 @@ function AddPlan() {
}
}
function
submitInfo
(){
function
submitInfo
(){
const
{
planName
,
enableState
,
selectOperatorList
,
instro
,
operateType
,
percentCompleteLive
,
percentCompleteVideo
}
=
basicData
;
const
{
planName
,
enableState
,
selectOperatorList
,
instro
,
operateType
,
percentCompleteLive
,
percentCompleteVideo
,
coverId
,
coverUrl
}
=
basicData
;
if
(
!
planName
){
if
(
!
planName
){
message
.
warning
(
'请输入的培训计划名称'
);
message
.
warning
(
'请输入的培训计划名称'
);
return
;
return
;
...
@@ -49,7 +106,25 @@ function AddPlan() {
...
@@ -49,7 +106,25 @@ function AddPlan() {
message
.
warning
(
'请输入培训计划内容'
);
message
.
warning
(
'请输入培训计划内容'
);
return
;
return
;
}
}
let
scheduleMediaRequests
=
[];
let
coverObj
=
{
contentType
:
'COVER'
,
mediaContent
:
coverId
,
mediaType
:
'PICTURE'
,
mediaUrl
:
coverUrl
,
}
if
(
coverId
){
scheduleMediaRequests
=
[...
scheduleMediaRequests
,
coverObj
];
}
let
instroObj
=
{
contentType
:
"INTRO"
,
mediaType
:
'TEXT'
,
mediaContent
:
instro
,
}
if
(
instro
){
scheduleMediaRequests
=
[...
scheduleMediaRequests
,
instroObj
];
}
const
params
=
{
const
params
=
{
createId
:
User
.
getStoreUserId
(),
createId
:
User
.
getStoreUserId
(),
enableState
,
enableState
,
...
@@ -58,20 +133,56 @@ function AddPlan() {
...
@@ -58,20 +133,56 @@ function AddPlan() {
percentCompleteLive
,
percentCompleteLive
,
percentCompleteVideo
,
percentCompleteVideo
,
planName
,
planName
,
scheduleMediaRequests
:[]
,
scheduleMediaRequests
,
storeId
:
User
.
getStoreId
(),
storeId
:
User
.
getStoreId
(),
trainingTaskList
:
taskList
trainingTaskList
:
taskList
}
}
PlanService
.
createTrainingPlan
(
params
).
then
((
res
)
=>
{
if
(
type
===
'add'
)
{
PlanService
.
createTrainingPlan
(
params
).
then
((
res
)
=>
{
});
if
(
res
.
success
){
message
.
success
(
"新建成功"
);
window
.
RCHistory
.
goBack
();
}
});
}
else
{
const
_params
=
{
...
params
,
id
}
PlanService
.
updateTrainingPlan
(
_params
).
then
((
res
)
=>
{
if
(
res
.
success
){
message
.
success
(
"更新成功"
);
window
.
RCHistory
.
goBack
();
}
});
}
}
}
// 取消编辑并返回上一级路由
function
handleGoBack
(){
if
(
!
_
.
isEqual
(
basicData
,
defaultBasicData
)
||
!
_
.
isEqual
(
taskList
,
defaultTaskList
)
)
{
Modal
.
confirm
({
title
:
'确定要返回吗?'
,
content
:
'返回后,本次编辑的内容将不被保存'
,
okText
:
'确认返回'
,
cancelText
:
'留在本页'
,
icon
:
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>,
onOk
:
()
=>
{
window
.
RCHistory
.
goBack
();
}
})
}
else
{
window
.
RCHistory
.
goBack
();
}
}
return
(
return
(
<
div
className=
"page add-plan-page"
>
<
div
className=
"page add-plan-page"
>
<
Breadcrumbs
<
Breadcrumbs
navList=
{
type
==
"add"
?
"新建培训计划"
:
"编辑培训计划"
}
navList=
{
type
==
"add"
?
"新建培训计划"
:
"编辑培训计划"
}
goBack=
{
handleGoBack
}
/>
/>
<
div
className=
"box"
>
<
div
className=
"box"
>
<
div
className=
"show-tips"
>
<
div
className=
"show-tips"
>
...
@@ -87,7 +198,7 @@ function AddPlan() {
...
@@ -87,7 +198,7 @@ function AddPlan() {
</
div
>
</
div
>
<
div
className=
"basic-info__wrap"
>
<
div
className=
"basic-info__wrap"
>
<
div
className=
"title"
>
培训任务
</
div
>
<
div
className=
"title"
>
培训任务
</
div
>
<
TrainingTask
onChange=
{
handleChangeTaskInfo
}
/>
<
TrainingTask
data=
{
taskList
}
onChange=
{
handleChangeTaskInfo
}
/>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
</
div
>
...
...
src/modules/plan-manage/LearningData.jsx
0 → 100644
View file @
2d3a9245
import
React
from
'react'
;
import
{
withRouter
}
from
"react-router-dom"
;
import
{
Tabs
}
from
'antd'
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
EmployeeShareData
from
'./components/EmployeeShareData'
;
import
UserLearningData
from
'./components/UserLearningData'
;
import
'./LearningData.less'
;
class
LearningData
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
}
}
render
()
{
return
(
<
div
className=
"page plan-learn-data-list"
>
<
Breadcrumbs
navList=
"学习数据"
goBack=
{
()
=>
{
RCHistory
.
goBack
();
}
}
/>
<
div
className=
"plan-info"
>
<
div
className=
"plan-intro"
>
<
div
className=
"plan-img-con"
>
<
img
src=
"https://image.xiaomaiketang.com/xm/YNfi45JwFA.png"
/>
</
div
>
<
div
>
<
div
className=
"plan-name"
>
六年级数学精品公开课快来参加二十个字展示
</
div
>
<
div
className=
"create-course"
>
<
span
className=
"createUser"
>
创建人:张老师
</
span
>
<
span
className=
"split"
>
|
</
span
>
<
span
className=
"course-total"
>
课程总数量:88
</
span
>
</
div
>
<
div
className=
"create-time"
>
创建时间:2020-01-01 09:00
</
div
>
</
div
>
</
div
>
<
div
className=
"join"
>
<
div
className=
"number"
>
1999
</
div
>
<
div
className=
"text"
>
参培人数
</
div
>
</
div
>
</
div
>
<
div
className=
"box"
>
<
Tabs
defaultActiveKey=
"employeeShareData"
>
<
Tabs
.
TabPane
tab=
"员工分享数据"
key=
"employeeShareData"
>
<
EmployeeShareData
/>
</
Tabs
.
TabPane
>
<
Tabs
.
TabPane
tab=
"用户学习数据"
key=
"userLearningData"
>
<
UserLearningData
/>
</
Tabs
.
TabPane
>
</
Tabs
>
</
div
>
</
div
>
)
}
}
export
default
withRouter
(
LearningData
);
\ No newline at end of file
src/modules/plan-manage/LearningData.less
0 → 100644
View file @
2d3a9245
.plan-learn-data-list{
.plan-info{
margin:16px;
padding:16px;
background: #FFF;
display:flex;
justify-content: space-between;
align-items: center;
.plan-intro{
display: flex;
align-items: center;
.plan-img-con{
margin-right:8px;
img{
width:136px;
height:77px;
}
}
.plan-name{
font-size: 16px;
font-weight: 500;
color: #333333;
line-height: 22px;
margin-bottom:8px;
}
.create-course{
font-size: 14px;
color: #666666;
.split{
margin:0 8px;
color:#666;
}
margin-bottom:4px;
}
.create-time{
font-size:14px;
color:#666;
}
}
.join{
margin-right:144px;
min-width:54px;
text-align:center;
.number{
font-size: 26px;
font-weight: 500;
color: #333333;
margin-botttom:4px;
}
.text{
font-size: 14px;
color:#999;
}
}
}
}
\ No newline at end of file
src/modules/plan-manage/components/BasicInfo.jsx
View file @
2d3a9245
This diff is collapsed.
Click to expand it.
src/modules/plan-manage/components/BasicInfo.less
View file @
2d3a9245
.plan-basic-info{
.plan-basic-info{
.label {
.label {
width: 1
0
0px;
width: 1
1
0px;
text-align: right;
text-align: right;
display:inline-block;
display:inline-block;
.require {
.require {
...
...
src/modules/plan-manage/components/EmployeeShareData.jsx
0 → 100644
View file @
2d3a9245
import
React
from
'react'
;
import
{
withRouter
}
from
"react-router-dom"
;
import
{
Table
,
Modal
,
Input
,
message
}
from
'antd'
;
import
{
PageControl
}
from
"@/components"
;
import
'./EmployeeShareData.less'
;
const
{
Search
}
=
Input
;
const
UserRole
=
{
StoreManager
:
{
name
:
"店铺管理员"
},
CloudManager
:
{
name
:
"管理员"
},
CloudOperator
:
{
name
:
'运营师'
},
CloudLecturer
:
{
name
:
"讲师"
},
};
class
EmployeeShareData
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
dataSource
:[],
size
:
10
,
query
:
{
current
:
1
,
},
totalCount
:
0
,
}
}
handleFetchDataList
=
()
=>
{
}
// 请求表头
parselumns
=
()
=>
{
const
columns
=
[
{
title
:
'员工'
,
key
:
'storeUserName'
,
dataIndex
:
'storeUserName'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
val
}
</
div
>
)
}
},
{
title
:
'角色'
,
key
:
'roleEnum'
,
dataIndex
:
'roleEnum'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
UserRole
[
val
].
name
}
</
div
>
)
}
},
{
title
:
'手机号'
,
key
:
'storeUserPhone'
,
dataIndex
:
'storeUserPhone'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
val
}
</
div
>
)
}
},
{
title
:
'最近分享成功时间'
,
key
:
'recentlyForwardTime'
,
dataIndex
:
'recentlyForwardTime'
,
sorter
:
true
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
div
>
)
}
},
{
title
:
'学习人数'
,
key
:
'learnNum'
,
dataIndex
:
'learnNum'
,
sorter
:
true
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
val
}
</
div
>
)
}
},
{
title
:
'已学完'
,
key
:
'learnFinishNum'
,
dataIndex
:
'learnFinishNum'
,
sorter
:
true
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
val
}
</
div
>
)
}
},
{
title
:
'未学完'
,
key
:
'learnNoFinishNum'
,
dataIndex
:
'learnNoFinishNum'
,
sorter
:
true
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
val
}
</
div
>
)
}
},
{
title
:
'操作'
,
key
:
'operate'
,
dataIndex
:
'operate'
,
render
:
(
val
,
record
)
=>
{
return
(
<
span
>
数据详情
</
span
>
)
}
}
];
return
columns
;
}
render
()
{
const
{
dataSource
,
query
,
size
,
totalCount
}
=
this
.
state
;
return
(
<
div
className=
"employee-share-data"
>
<
div
className=
"search-container"
>
<
Search
placeholder=
"搜索员工姓名手机号"
style=
{
{
width
:
200
}
}
enterButton=
{
<
span
className=
"icon iconfont"
>

</
span
>
}
/>
</
div
>
<
div
>
<
Table
rowKey=
{
record
=>
record
.
id
}
dataSource=
{
dataSource
}
columns=
{
this
.
parselumns
()
}
pagination=
{
false
}
/>
{
dataSource
.
length
>
0
&&
<
div
className=
"box-footer"
>
<
PageControl
current=
{
query
.
current
-
1
}
pageSize=
{
size
}
total=
{
totalCount
}
toPage=
{
(
page
)
=>
{
const
_query
=
{...
query
,
current
:
page
+
1
};
this
.
setState
({
query
:
_query
},()
=>
{
this
.
handleFetchDataList
()})
}
}
/>
</
div
>
}
</
div
>
</
div
>
)
}
}
export
default
withRouter
(
EmployeeShareData
);
\ No newline at end of file
src/modules/plan-manage/components/EmployeeShareData.less
0 → 100644
View file @
2d3a9245
.employee-share-data{
.search-container{
margin-bottom:12px;
}
}
\ No newline at end of file
src/modules/plan-manage/components/PlanList.jsx
View file @
2d3a9245
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: zhangleyuan
* @Author: zhangleyuan
* @Date: 2021-02-20 16:46:46
* @Date: 2021-02-20 16:46:46
* @LastEditors: zhangleyuan
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-03-0
1 16:48:31
* @LastEditTime: 2021-03-0
2 15:55:04
* @Description: 描述一下
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -115,7 +115,7 @@ function PlanList(props) {
...
@@ -115,7 +115,7 @@ function PlanList(props) {
render
:
(
val
,
record
)
=>
{
render
:
(
val
,
record
)
=>
{
return
(
return
(
<
div
className=
"operate"
>
<
div
className=
"operate"
>
<
div
className=
"operate__item"
>
学习数据
</
div
>
<
div
className=
"operate__item"
onClick=
{
()
=>
toLearningDataPage
(
record
)
}
>
学习数据
</
div
>
<
span
className=
"operate__item split"
>
|
</
span
>
<
span
className=
"operate__item split"
>
|
</
span
>
<
div
className=
"operate__item"
onClick=
{
()
=>
{
handleShowShareModal
(
record
);
}
}
>
分享
</
div
>
<
div
className=
"operate__item"
onClick=
{
()
=>
{
handleShowShareModal
(
record
);
}
}
>
分享
</
div
>
<
span
className=
"operate__item split"
>
|
</
span
>
<
span
className=
"operate__item split"
>
|
</
span
>
...
@@ -246,7 +246,11 @@ function PlanList(props) {
...
@@ -246,7 +246,11 @@ function PlanList(props) {
pathname
:
`/create-plan?type=edit&id=
${
item
.
planId
}
`
,
pathname
:
`/create-plan?type=edit&id=
${
item
.
planId
}
`
,
})
})
}
}
function
toLearningDataPage
(
item
){
window
.
RCHistory
.
push
({
pathname
:
`/learning-data?id=
${
item
.
planId
}
`
,
})
}
return
(
return
(
<
div
className=
"plan-list"
>
<
div
className=
"plan-list"
>
<
Table
<
Table
...
...
src/modules/plan-manage/components/TrainingTask.jsx
View file @
2d3a9245
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: zhangleyuan
* @Author: zhangleyuan
* @Date: 2021-02-20 16:45:51
* @Date: 2021-02-20 16:45:51
* @LastEditors: zhangleyuan
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-0
2-28 17:49:30
* @LastEditTime: 2021-0
3-02 20:20:28
* @Description: 描述一下
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -21,80 +21,23 @@ const DragHandle = sortableHandle(() => (
...
@@ -21,80 +21,23 @@ const DragHandle = sortableHandle(() => (
<
span
>
移动
</
span
>
<
span
>
移动
</
span
>
</
span
>
</
span
>
));
));
const
data
=
[
// {
// taskName: '培训计划名称A',
// index:0,
// type:'text',
// courserList:[
// {
// courseName:'培训计划课程A-1',
// type:'text',
// index:0,
// id:'00'
// },
// {
// courseName:'培训计划课程A-2',
// type:'text',
// index:1,
// id:'01'
// },
// {
// courseName:'培训计划课程A-3',
// type:'text',
// index:2,
// id:'02'
// }
// ]
// },
// {
// taskName: '培训计划名称B',
// index:1,
// type:'text',
// courserList:[
// {
// courseName:'培训计划课程B-1',
// index:0,
// type:'text',
// id:'10'
// },
// {
// courseName:'培训计划课程B-2',
// index:1,
// type:'text',
// id:'11'
// }
// ]
// },
// {
// taskName: '培训计划名称C',
// index:2,
// type:'text',
// courserList:[
// {
// courseName:'培训计划课程c-1',
// index:0,
// type:'text',
// id:'20'
// }
// ]
// },
];
const
SortableItem
=
sortableElement
(
props
=>
<
tr
{
...
props
}
/>);
const
SortableItem
=
sortableElement
(
props
=>
<
tr
{
...
props
}
/>);
const
SortableContainer
=
sortableContainer
(
props
=>
<
tbody
{
...
props
}
/>);
const
SortableContainer
=
sortableContainer
(
props
=>
<
tbody
{
...
props
}
/>);
class
TrainingTask
extends
React
.
Component
{
class
TrainingTask
extends
React
.
Component
{
constructor
(
props
)
{
constructor
(
props
)
{
super
(
props
);
super
(
props
);
this
.
state
=
{
this
.
state
=
{
dataSource
:
data
,
dataSource
:
[]
,
selectedTaskIndex
:
0
,
selectedTaskIndex
:
0
,
relatedCourseModalVisible
:
false
relatedCourseModalVisible
:
false
};
};
}
}
componentDidMount
(){
console
.
log
(
'data'
,
this
.
props
.
data
);
}
parseTaskColumns
=
()
=>
{
parseTaskColumns
=
()
=>
{
const
columns
=
[
const
columns
=
[
{
{
...
@@ -133,7 +76,7 @@ class TrainingTask extends React.Component {
...
@@ -133,7 +76,7 @@ class TrainingTask extends React.Component {
<
DragHandle
/>
<
DragHandle
/>
<
span
className=
"operate__item"
>
<
span
className=
"operate__item"
>
<
span
className=
"icon iconfont"
>

</
span
>
<
span
className=
"icon iconfont"
>

</
span
>
<
span
onClick=
{
(
e
)
=>
{
const
{
dataSource
}
=
this
.
state
;
record
.
type
=
"input"
;
this
.
setState
(
dataSource
)
}
}
>
重命名
</
span
>
<
span
onClick=
{
(
e
)
=>
{
const
{
data
}
=
this
.
props
;
record
.
type
=
"input"
;
this
.
props
.
onChange
(
data
);
}
}
>
重命名
</
span
>
</
span
>
</
span
>
<
span
className=
"operate__item"
onClick=
{
()
=>
{
this
.
handleDeleteTask
(
index
)}
}
>
<
span
className=
"operate__item"
onClick=
{
()
=>
{
this
.
handleDeleteTask
(
index
)}
}
>
<
span
className=
"icon iconfont"
>

</
span
>
<
span
className=
"icon iconfont"
>

</
span
>
...
@@ -186,7 +129,7 @@ class TrainingTask extends React.Component {
...
@@ -186,7 +129,7 @@ class TrainingTask extends React.Component {
<
DragHandle
/>
<
DragHandle
/>
<
span
className=
"operate__item"
>
<
span
className=
"operate__item"
>
<
span
className=
"icon iconfont"
>

</
span
>
<
span
className=
"icon iconfont"
>

</
span
>
<
span
onClick=
{
(
e
)
=>
{
const
{
dataSource
}
=
this
.
state
;
record
.
type
=
"input"
;
this
.
setState
(
dataSource
)
}
}
>
重命名
</
span
>
<
span
onClick=
{
(
e
)
=>
{
const
{
data
}
=
this
.
props
;
record
.
type
=
"input"
;
this
.
props
.
onChange
(
data
);
}
}
>
重命名
</
span
>
</
span
>
</
span
>
<
span
className=
"operate__item"
onClick=
{
()
=>
{
this
.
handleDeleteCourse
(
parentIndex
,
index
)}
}
>
<
span
className=
"operate__item"
onClick=
{
()
=>
{
this
.
handleDeleteCourse
(
parentIndex
,
index
)}
}
>
<
span
className=
"icon iconfont"
>

</
span
>
<
span
className=
"icon iconfont"
>

</
span
>
...
@@ -227,61 +170,61 @@ class TrainingTask extends React.Component {
...
@@ -227,61 +170,61 @@ class TrainingTask extends React.Component {
// };
// };
addTask
=
()
=>
{
addTask
=
()
=>
{
const
{
data
Source
}
=
this
.
state
;
const
{
data
}
=
this
.
props
;
const
taskObj
=
{
const
taskObj
=
{
taskName
:
''
,
taskName
:
''
,
index
:
data
Source
.
length
,
index
:
data
.
length
,
type
:
'input'
,
type
:
'input'
,
course
r
List
:[
courseList
:[
]
]
}
}
const
newData
=
[...
data
Source
,
taskObj
];
const
newData
=
[...
data
,
taskObj
];
this
.
setState
({
dataSource
:
newData
}
);
this
.
props
.
onChange
(
newData
);
}
}
handleRenameTaskName
=
(
e
,
record
)
=>
{
handleRenameTaskName
=
(
e
,
record
)
=>
{
const
{
value
}
=
e
.
target
;
const
{
value
}
=
e
.
target
;
const
{
data
Source
}
=
this
.
state
;
const
{
data
}
=
this
.
props
;
record
.
taskName
=
value
;
record
.
taskName
=
value
;
this
.
props
.
onChange
(
data
Source
);
this
.
props
.
onChange
(
data
);
}
}
handleTaskNameBlur
=
(
e
,
record
)
=>
{
handleTaskNameBlur
=
(
e
,
record
)
=>
{
const
{
value
}
=
e
.
target
;
const
{
value
}
=
e
.
target
;
const
{
data
Source
}
=
this
.
state
;
const
{
data
}
=
this
.
props
;
if
(
value
){
if
(
value
){
record
.
type
=
"text"
;
record
.
type
=
"text"
;
this
.
setState
({
dataSource
}
);
this
.
props
.
onChange
(
data
);
}
}
}
}
handleRenameCourseName
=
(
e
,
record
)
=>
{
handleRenameCourseName
=
(
e
,
record
)
=>
{
const
{
value
}
=
e
.
target
;
const
{
value
}
=
e
.
target
;
const
{
data
Source
}
=
this
.
state
;
const
{
data
}
=
this
.
props
;
record
.
courseName
=
value
;
record
.
courseName
=
value
;
this
.
props
.
onChange
(
this
.
state
.
dataSource
);
this
.
props
.
onChange
(
data
);
}
}
handleCourseNameBlur
=
(
e
,
record
)
=>
{
handleCourseNameBlur
=
(
e
,
record
)
=>
{
const
{
value
}
=
e
.
target
;
const
{
value
}
=
e
.
target
;
const
{
dataSource
}
=
this
.
state
;
const
{
data
}
=
this
.
props
;
if
(
value
){
if
(
value
){
record
.
type
=
"text"
;
record
.
type
=
"text"
;
this
.
setState
({
data
Source
});
this
.
setState
({
data
});
}
}
}
}
handleDeleteTask
=
(
index
)
=>
{
handleDeleteTask
=
(
index
)
=>
{
const
{
data
Source
}
=
this
.
state
;
const
{
data
}
=
this
.
props
;
const
newData
=
[...
data
Source
];
const
newData
=
[...
data
];
newData
.
splice
(
index
,
1
);
newData
.
splice
(
index
,
1
);
this
.
setState
({
dataSource
:
newData
},()
=>
{
this
.
props
.
onChange
(
this
.
state
.
dataSource
);}
);
this
.
props
.
onChange
(
newData
);
}
}
handleDeleteCourse
=
(
parentIndex
,
index
)
=>
{
handleDeleteCourse
=
(
parentIndex
,
index
)
=>
{
const
{
data
Source
}
=
this
.
state
;
const
{
data
}
=
this
.
props
;
const
newData
=
[...
data
Source
];
const
newData
=
[...
data
];
const
selectData
=
[...
newData
[
parentIndex
].
course
r
List
]
const
selectData
=
[...
newData
[
parentIndex
].
courseList
]
selectData
.
splice
(
index
,
1
)
selectData
.
splice
(
index
,
1
)
newData
[
parentIndex
].
course
r
List
=
selectData
;
newData
[
parentIndex
].
courseList
=
selectData
;
this
.
setState
({
dataSource
:
newData
},()
=>
{
this
.
props
.
onChange
(
this
.
state
.
dataSource
);}
);
this
.
props
.
onChange
(
newData
);
}
}
showRelatedCourseModal
=
(
index
)
=>
{
showRelatedCourseModal
=
(
index
)
=>
{
...
@@ -296,35 +239,35 @@ class TrainingTask extends React.Component {
...
@@ -296,35 +239,35 @@ class TrainingTask extends React.Component {
})
})
}
}
confirmSelectCourse
=
(
selectList
)
=>
{
confirmSelectCourse
=
(
selectList
)
=>
{
const
{
selectedTaskIndex
}
=
this
.
state
;
const
{
dataSource
,
selectedTaskIndex
}
=
this
.
state
;
const
{
data
}
=
this
.
props
const
newData
=
[...
data
Source
];
const
newData
=
[...
data
];
const
selectData
=
[...
newData
[
selectedTaskIndex
].
course
r
List
]
const
selectData
=
[...
newData
[
selectedTaskIndex
].
courseList
]
const
_selectData
=
[...
selectData
,...
selectList
];
const
_selectData
=
[...
selectData
,...
selectList
];
newData
[
selectedTaskIndex
].
course
r
List
=
_selectData
;
newData
[
selectedTaskIndex
].
courseList
=
_selectData
;
this
.
setState
({
this
.
setState
({
relatedCourseModalVisible
:
false
,
relatedCourseModalVisible
:
false
,
dataSource
:
newData
},()
=>
{
},()
=>
{
this
.
props
.
onChange
(
dataSource
);
this
.
props
.
onChange
(
newData
);
})
})
}
}
render
()
{
render
()
{
const
{
dataSource
,
selectedTaskIndex
,
relatedCourseModalVisible
}
=
this
.
state
;
const
{
dataSource
,
selectedTaskIndex
,
relatedCourseModalVisible
}
=
this
.
state
;
const
{
data
}
=
this
.
props
;
return
(
return
(
<
div
className=
"training-task"
>
<
div
className=
"training-task"
>
<
Table
<
Table
pagination=
{
false
}
pagination=
{
false
}
dataSource=
{
data
Source
}
dataSource=
{
data
}
columns=
{
this
.
parseTaskColumns
()
}
columns=
{
this
.
parseTaskColumns
()
}
rowKey=
"index"
rowKey=
"index"
expandedRowRender=
{
(
record
,
index
)
=>
{
expandedRowRender=
{
(
record
,
index
)
=>
{
if
(
record
.
course
rList
.
length
!==
0
){
if
(
record
.
course
List
.
length
!==
0
){
return
<
div
>
return
<
div
>
<
Table
<
Table
pagination=
{
false
}
pagination=
{
false
}
dataSource=
{
record
.
course
r
List
}
dataSource=
{
record
.
courseList
}
columns=
{
this
.
parseCoursecolumns
(
index
)
}
columns=
{
this
.
parseCoursecolumns
(
index
)
}
rowKey=
"index"
rowKey=
"index"
// components=
{{
// components=
{{
...
@@ -339,6 +282,7 @@ class TrainingTask extends React.Component {
...
@@ -339,6 +282,7 @@ class TrainingTask extends React.Component {
}
else
{
}
else
{
return
<
div
><
Button
onClick=
{
()
=>
{
this
.
showRelatedCourseModal
(
index
)}
}
><
span
>
+
</
span
><
span
>
关联课程
</
span
></
Button
></
div
>;
return
<
div
><
Button
onClick=
{
()
=>
{
this
.
showRelatedCourseModal
(
index
)}
}
><
span
>
+
</
span
><
span
>
关联课程
</
span
></
Button
></
div
>;
}
}
}
}
}
}
// components={{
// components={{
// body: {
// body: {
...
@@ -351,14 +295,12 @@ class TrainingTask extends React.Component {
...
@@ -351,14 +295,12 @@ class TrainingTask extends React.Component {
{
relatedCourseModalVisible
&&
{
relatedCourseModalVisible
&&
<
RelatedCourseModal
<
RelatedCourseModal
selectedTaskIndex=
{
selectedTaskIndex
}
selectedTaskIndex=
{
selectedTaskIndex
}
data=
{
data
Source
}
data=
{
data
}
visible=
{
relatedCourseModalVisible
}
visible=
{
relatedCourseModalVisible
}
onClose=
{
this
.
closeRelatedCourseModal
}
onClose=
{
this
.
closeRelatedCourseModal
}
onSelect=
{
this
.
confirmSelectCourse
}
onSelect=
{
this
.
confirmSelectCourse
}
/>
/>
}
}
</
div
>
</
div
>
);
);
}
}
...
...
src/modules/plan-manage/components/UserLearningData.jsx
0 → 100644
View file @
2d3a9245
import
React
from
'react'
;
import
{
withRouter
}
from
"react-router-dom"
;
import
{
Table
,
Modal
,
Input
,
message
}
from
'antd'
;
import
{
PageControl
}
from
"@/components"
;
import
UserLearningDataFilter
from
'./UserLearningDataFilter'
;
import
'./EmployeeShareData.less'
;
import
Item
from
'antd/lib/list/Item'
;
const
{
Search
}
=
Input
;
const
LearnState
=
{
UN_PLAY
:
{
text
:
"未开始"
},
UNDER_WAY
:
{
text
:
"进行中"
},
FINISH
:
{
text
:
'已完成'
}
};
class
UserLearningData
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
dataSource
:[],
size
:
10
,
query
:
{
current
:
1
,
},
totalCount
:
0
,
}
}
handleFetchDataList
=
()
=>
{
}
// 请求表头
parselumns
=
()
=>
{
const
columns
=
[
{
title
:
'用户'
,
key
:
'storeCustomerName'
,
dataIndex
:
'storeCustomerName'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
val
}
</
div
>
)
}
},
{
title
:
'学习状态'
,
key
:
'roleEnum'
,
dataIndex
:
'roleEnum'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
LearnState
[
val
].
text
}
</
div
>
)
}
},
{
title
:
'负责人'
,
key
:
'userNameList'
,
dataIndex
:
'userNameList'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
record
.
userNameList
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
}
{
(
index
<
record
.
userNameList
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
</
div
>
)
}
},
{
title
:
'最近学习时间'
,
key
:
'latelyLearnTime'
,
dataIndex
:
'latelyLearnTime'
,
sorter
:
true
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
div
>
)
}
},
{
title
:
'开始学习时间'
,
key
:
'startLearnTime'
,
dataIndex
:
'startLearnTime'
,
sorter
:
true
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
div
>
)
}
},
{
title
:
'学习进度'
,
key
:
'learnNum'
,
dataIndex
:
'learnNum'
,
sorter
:
true
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
<
span
>
{
record
.
courseFinishNum
}
</
span
>
<
span
>
/
</
span
>
<
span
>
{
record
.
courseNum
}
</
span
>
</
div
>
)
}
},
{
title
:
'操作'
,
key
:
'operate'
,
dataIndex
:
'operate'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
<
span
>
学习详情
</
span
>
<
span
>
|
</
span
>
<
span
>
解绑
</
span
>
</
div
>
)
}
}
];
return
columns
;
}
render
()
{
const
{
dataSource
,
query
,
size
,
totalCount
}
=
this
.
state
;
return
(
<
div
className=
"user-learning-data"
>
<
div
className=
"search-container"
>
<
UserLearningDataFilter
/>
</
div
>
<
div
>
<
Table
rowKey=
{
record
=>
record
.
id
}
dataSource=
{
dataSource
}
columns=
{
this
.
parselumns
()
}
pagination=
{
false
}
/>
{
dataSource
.
length
>
0
&&
<
div
className=
"box-footer"
>
<
PageControl
current=
{
query
.
current
-
1
}
pageSize=
{
size
}
total=
{
totalCount
}
toPage=
{
(
page
)
=>
{
const
_query
=
{...
query
,
current
:
page
+
1
};
this
.
setState
({
query
:
_query
},()
=>
{
this
.
handleFetchDataList
()})
}
}
/>
</
div
>
}
</
div
>
</
div
>
)
}
}
export
default
withRouter
(
UserLearningData
);
\ No newline at end of file
src/modules/plan-manage/components/UserLearningData.less
0 → 100644
View file @
2d3a9245
src/modules/plan-manage/components/UserLearningDataFilter.jsx
0 → 100644
View file @
2d3a9245
/*
* @Author: 吴文洁
* @Date: 2020-07-14 15:41:30
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-07-23 13:45:16
* @Description: 大班直播、互动班课列表的筛选组件
*/
import
React
,
{
useState
,
useRef
,
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
'./UserLearningDataFilter.less'
;
const
{
Search
}
=
Input
;
const
{
Option
}
=
Select
;
const
DEFAULT_QUERY
=
{
customerName
:
null
,
startTime
:
null
,
endTime
:
null
,
learnState
:
null
,
operateId
:
null
}
const
defaultCreatorQuery
=
{
size
:
10
,
current
:
1
,
nickName
:
null
}
function
UserLearningDataFilter
(
props
)
{
const
[
expandFilter
,
setExpandFilter
]
=
useState
(
false
);
const
[
query
,
setQuery
]
=
useState
(
DEFAULT_QUERY
);
const
[
hasNext
,
setHasNext
]
=
useState
(
false
);
const
[
creatorQuery
,
setCreatorQuery
]
=
useState
(
defaultCreatorQuery
);
const
[
creatorList
,
setCreatorList
]
=
useState
([]);
useEffect
(()
=>
{
getCreatorList
();
},
[
creatorQuery
]);
// 改变搜索条件
function
handleChangeQuery
(
field
,
value
){
const
_query
=
{
...
query
,
[
field
]:
value
,
current
:
1
,
}
setQuery
(
_query
);
if
(
field
===
'customerName'
)
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
);
}
function
getCreatorList
(
current
=
1
,
selectList
){
const
_query
=
{
...
creatorQuery
,
current
,
size
:
10
};
StoreService
.
getStoreUserBasicPage
(
_query
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
records
=
[],
total
=
0
,
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
)
{
getCreatorList
(
creatorQuery
.
current
+
1
);
}
}
return
(
<
div
className=
"user-learn-data-filter"
>
<
Row
>
<
div
className=
"search-condition"
>
<
div
className=
"search-condition__item"
>
<
span
className=
"search-name"
>
用户:
</
span
>
<
Search
value=
{
query
.
customerName
}
placeholder=
"搜索用户名称"
onChange=
{
(
e
)
=>
{
handleChangeQuery
(
'customerName'
,
e
.
target
.
value
)}
}
onSearch=
{
()
=>
{
props
.
onChange
(
query
)
}
}
style=
{
{
width
:
"calc(100% - 70px)"
}
}
/>
</
div
>
<
div
className=
"search-condition__item"
>
<
span
>
负责人:
</
span
>
<
Select
placeholder=
"请选择创建人"
style=
{
{
width
:
"calc(100% - 70px)"
}
}
showSearch
allowClear
filterOption=
{
(
input
,
option
)
=>
option
}
onPopupScroll=
{
handleScrollCreatorList
}
value=
{
query
.
operateId
}
onChange=
{
(
value
)
=>
{
handleChangeQuery
(
'operateId'
,
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
.
learnState
}
onChange=
{
(
value
)
=>
{
handleChangeQuery
(
'learnState'
,
value
)
}
}
>
<
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
(
UserLearningDataFilter
);
\ No newline at end of file
src/modules/plan-manage/components/UserLearningDataFilter.less
0 → 100644
View file @
2d3a9245
.user-learn-data-filter {
position: relative;
.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;
.search-name{
vertical-align: middle;
display:inline-block;
height:32px;
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/plan-manage/modal/SelectOperatorModal.jsx
View file @
2d3a9245
...
@@ -28,7 +28,8 @@ class SelectOperatorModal extends React.Component {
...
@@ -28,7 +28,8 @@ class SelectOperatorModal extends React.Component {
const
{
query
,
size
,
totalCount
}
=
this
.
state
const
{
query
,
size
,
totalCount
}
=
this
.
state
const
params
=
{
const
params
=
{
...
query
,
...
query
,
size
size
,
roleCodes
:[
'CloudOperator'
]
}
}
StoreService
.
getStoreUserBasicPage
(
params
).
then
((
res
)
=>
{
StoreService
.
getStoreUserBasicPage
(
params
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
result
=
{}
}
=
res
;
...
...
src/modules/plan-manage/modal/relatedCourseModal.jsx
View file @
2d3a9245
...
@@ -64,7 +64,8 @@ class SelectOperatorModal extends React.Component {
...
@@ -64,7 +64,8 @@ class SelectOperatorModal extends React.Component {
handleFetchLiveDataList
=
()
=>
{
handleFetchLiveDataList
=
()
=>
{
const
{
liveQuery
,
liveSize
}
=
this
.
state
;
const
{
liveQuery
,
liveSize
}
=
this
.
state
;
const
{
selectedTaskIndex
}
=
this
.
props
;
const
{
selectedTaskIndex
}
=
this
.
props
;
const
currentLiveCourseListData
=
[...
this
.
props
.
data
[
selectedTaskIndex
].
courserList
]
console
.
log
(
'selectedTaskIndex'
,
selectedTaskIndex
);
const
currentLiveCourseListData
=
[...
this
.
props
.
data
[
selectedTaskIndex
].
courseList
]
const
_currentLiveCourseListData
=
currentLiveCourseListData
.
map
((
item
,
index
)
=>
{
const
_currentLiveCourseListData
=
currentLiveCourseListData
.
map
((
item
,
index
)
=>
{
if
(
item
.
liveCourseId
){
if
(
item
.
liveCourseId
){
return
item
return
item
...
@@ -74,7 +75,7 @@ class SelectOperatorModal extends React.Component {
...
@@ -74,7 +75,7 @@ class SelectOperatorModal extends React.Component {
const
params
=
{
const
params
=
{
...
liveQuery
,
...
liveQuery
,
liveSize
,
liveSize
,
excludeCourseIdList
:
_
.
pluck
(
_currentLiveCourseListData
,
'
liveC
ourseId'
)
excludeCourseIdList
:
_
.
pluck
(
_currentLiveCourseListData
,
'
c
ourseId'
)
}
}
CourseService
.
getLiveCloudCourseBasePage
(
params
).
then
((
res
)
=>
{
CourseService
.
getLiveCloudCourseBasePage
(
params
).
then
((
res
)
=>
{
...
@@ -92,7 +93,7 @@ class SelectOperatorModal extends React.Component {
...
@@ -92,7 +93,7 @@ class SelectOperatorModal extends React.Component {
handleFetchVideoDataList
=
()
=>
{
handleFetchVideoDataList
=
()
=>
{
const
{
videoQuery
,
videoSize
,
videoTotalCount
}
=
this
.
state
;
const
{
videoQuery
,
videoSize
,
videoTotalCount
}
=
this
.
state
;
const
{
selectedTaskIndex
}
=
this
.
props
;
const
{
selectedTaskIndex
}
=
this
.
props
;
const
currentVideoCourseListData
=
[...
this
.
props
.
data
[
selectedTaskIndex
].
course
r
List
];
const
currentVideoCourseListData
=
[...
this
.
props
.
data
[
selectedTaskIndex
].
courseList
];
const
_currentVideoCourseListData
=
currentVideoCourseListData
.
map
((
item
,
index
)
=>
{
const
_currentVideoCourseListData
=
currentVideoCourseListData
.
map
((
item
,
index
)
=>
{
if
(
!
item
.
liveCourseId
){
if
(
!
item
.
liveCourseId
){
return
item
return
item
...
@@ -101,7 +102,7 @@ class SelectOperatorModal extends React.Component {
...
@@ -101,7 +102,7 @@ class SelectOperatorModal extends React.Component {
const
params
=
{
const
params
=
{
...
videoQuery
,
...
videoQuery
,
videoSize
,
videoSize
,
excludeCourseIdList
:
_
.
pluck
(
_currentVideoCourseListData
,
'
i
d'
)
excludeCourseIdList
:
_
.
pluck
(
_currentVideoCourseListData
,
'
courseI
d'
)
}
}
CourseService
.
videoScheduleBasePage
(
params
).
then
((
res
)
=>
{
CourseService
.
videoScheduleBasePage
(
params
).
then
((
res
)
=>
{
...
@@ -256,7 +257,7 @@ class SelectOperatorModal extends React.Component {
...
@@ -256,7 +257,7 @@ class SelectOperatorModal extends React.Component {
message
.
warning
(
'无法继续选择,一个任务最多关联20个课程'
);
message
.
warning
(
'无法继续选择,一个任务最多关联20个课程'
);
return
;
return
;
}
}
this
.
setState
({
selectLive
:
_list
});
this
.
setState
({
selectLive
:
_list
});
}
}
selectVideoList
=
(
record
,
selected
)
=>
{
selectVideoList
=
(
record
,
selected
)
=>
{
...
@@ -274,11 +275,29 @@ class SelectOperatorModal extends React.Component {
...
@@ -274,11 +275,29 @@ class SelectOperatorModal extends React.Component {
this
.
setState
({
selectVideo
:
_list
});
this
.
setState
({
selectVideo
:
_list
});
}
}
clearSelectCourse
=
()
=>
{
clearSelectCourse
=
()
=>
{
this
.
setState
({
this
.
setState
({
selectLive
:[],
selectLive
:[],
selectVideo
:[]
selectVideo
:[]
})
})
}
handleSelectVideo
=
(
selectVideo
)
=>
{
return
selectVideo
.
map
((
item
,
index
)
=>
{
let
_item
=
{};
_item
.
courseId
=
item
.
id
;
_item
.
courseType
=
"VOICE"
;
_item
.
courseName
=
item
.
courseName
;
return
_item
;
})
}
}
handleSelectLive
=
(
selectLive
)
=>
{
return
selectLive
.
map
((
item
,
index
)
=>
{
let
_item
=
{};
_item
.
courseId
=
item
.
liveCourseId
;
_item
.
courseType
=
"LIVE"
;
_item
.
courseName
=
item
.
courseName
;
return
_item
;
})
}
render
()
{
render
()
{
const
{
visible
}
=
this
.
props
;
const
{
visible
}
=
this
.
props
;
const
{
liveDataSource
,
liveSize
,
liveQuery
,
liveTotalCount
,
selectLive
,
currentLiveCourseListData
,
videoDataSource
,
videoSize
,
videoQuery
,
videoTotalCount
,
selectVideo
,
currentVideoCourseListData
}
=
this
.
state
;
const
{
liveDataSource
,
liveSize
,
liveQuery
,
liveTotalCount
,
selectLive
,
currentLiveCourseListData
,
videoDataSource
,
videoSize
,
videoQuery
,
videoTotalCount
,
selectVideo
,
currentVideoCourseListData
}
=
this
.
state
;
...
@@ -292,7 +311,7 @@ class SelectOperatorModal extends React.Component {
...
@@ -292,7 +311,7 @@ class SelectOperatorModal extends React.Component {
className=
"select-operator-modal"
className=
"select-operator-modal"
closable=
{
true
}
closable=
{
true
}
width=
{
800
}
width=
{
800
}
onOk=
{
()
=>
this
.
props
.
onSelect
([...
selectVideo
,...
selectLive
])
}
onOk=
{
()
=>
this
.
props
.
onSelect
([...
this
.
handleSelectVideo
(
selectVideo
),...
this
.
handleSelectLive
(
selectLive
)
])
}
>
>
<
div
>
<
div
>
...
...
src/modules/store-manage/EmployeeAddOrEditModal.tsx
View file @
2d3a9245
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: wufan
* @Author: wufan
* @Date: 2020-11-27 16:21:49
* @Date: 2020-11-27 16:21:49
* @LastEditors: zhangleyuan
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-03-0
1 19:22:10
* @LastEditTime: 2021-03-0
2 13:40:27
* @Description: Description
* @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
...
@@ -43,7 +43,7 @@ interface AddEmployeeModalProps {
...
@@ -43,7 +43,7 @@ interface AddEmployeeModalProps {
function
AddEmployeeModal
(
props
:
AddEmployeeModalProps
)
{
function
AddEmployeeModal
(
props
:
AddEmployeeModalProps
)
{
const
[
nickName
,
setName
]
=
useState
(
""
);
const
[
nickName
,
setName
]
=
useState
(
""
);
const
[
phone
,
setPhone
]
=
useState
(
""
);
const
[
phone
,
setPhone
]
=
useState
(
""
);
const
[
role
,
setRole
]
=
useState
(
"CloudOperat
ion
"
);
const
[
role
,
setRole
]
=
useState
(
"CloudOperat
or
"
);
const
[
avatar
,
setAvatar
]
=
useState
(
const
[
avatar
,
setAvatar
]
=
useState
(
"https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png"
"https://image.xiaomaiketang.com/xm/rJeQaZxtc7.png"
);
);
...
@@ -282,7 +282,7 @@ function AddEmployeeModal(props: AddEmployeeModalProps) {
...
@@ -282,7 +282,7 @@ function AddEmployeeModal(props: AddEmployeeModalProps) {
}
}
}
}
className=
"mt5"
className=
"mt5"
>
>
<
Radio
value=
{
"CloudOperat
ion
"
}
className=
"mt-4"
>
<
Radio
value=
{
"CloudOperat
or
"
}
className=
"mt-4"
>
<
span
style=
{
{
color
:
"#333"
}
}
>
运营师
</
span
>
<
span
style=
{
{
color
:
"#333"
}
}
>
运营师
</
span
>
<
p
className=
"radio-tip"
>
<
p
className=
"radio-tip"
>
仅可查看/转发培训计划内容,并查看其负责的用户学习进度
仅可查看/转发培训计划内容,并查看其负责的用户学习进度
...
...
src/routes/config/mainRoutes.tsx
View file @
2d3a9245
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Author: 吴文洁
* @Date: 2020-04-29 10:26:32
* @Date: 2020-04-29 10:26:32
* @LastEditors: zhangleyuan
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-0
2-22 11:36:41
* @LastEditTime: 2021-0
3-02 15:56:22
* @Description: 内容线路由配置
* @Description: 内容线路由配置
*/
*/
import
EmployeesManagePage
from
'@/modules/store-manage/EmployeesManagePage'
;
import
EmployeesManagePage
from
'@/modules/store-manage/EmployeesManagePage'
;
...
@@ -21,6 +21,8 @@ import ResourceDisk from '@/modules/resource-disk';
...
@@ -21,6 +21,8 @@ import ResourceDisk from '@/modules/resource-disk';
import
SwitchRoute
from
'@/modules/root/SwitchRoute'
;
import
SwitchRoute
from
'@/modules/root/SwitchRoute'
;
import
PlanPage
from
'@/modules/plan-manage/PlanPage'
;
import
PlanPage
from
'@/modules/plan-manage/PlanPage'
;
import
AddPlanPage
from
'@/modules/plan-manage/AddPlan'
;
import
AddPlanPage
from
'@/modules/plan-manage/AddPlan'
;
import
LearningDataPage
from
'@/modules/plan-manage/LearningData'
;
import
StoreInfoPage
from
'@/modules/store-manage/StoreInfo'
;
const
mainRoutes
=
[
const
mainRoutes
=
[
{
{
...
@@ -87,7 +89,18 @@ const mainRoutes = [
...
@@ -87,7 +89,18 @@ const mainRoutes = [
path
:
'/create-plan'
,
path
:
'/create-plan'
,
component
:
AddPlanPage
,
component
:
AddPlanPage
,
name
:
'创建视频课'
name
:
'创建视频课'
},
{
path
:
'/store-info'
,
component
:
StoreInfoPage
,
name
:
'店铺信息'
},
{
path
:
'/learning-data'
,
component
:
LearningDataPage
,
name
:
'学习数据'
}
}
]
]
export
default
mainRoutes
;
export
default
mainRoutes
;
\ No newline at end of file
src/routes/config/menuList.tsx
View file @
2d3a9245
/*
* @Author: zhangleyuan
* @Date: 2021-01-19 11:27:56
* @LastEditors: zhangleyuan
* @LastEditTime: 2021-03-02 15:18:12
* @Description: 描述一下
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
export
const
menuList
:
any
=
[
export
const
menuList
:
any
=
[
{
{
groupName
:
"课程管理"
,
groupName
:
"课程管理"
,
...
@@ -23,11 +31,28 @@ export const menuList: any = [
...
@@ -23,11 +31,28 @@ export const menuList: any = [
link
:
'/resource-disk'
link
:
'/resource-disk'
},
},
{
{
groupName
:
"培训管理"
,
groupCode
:
"TrainManage"
,
icon
:
''
,
children
:
[
{
groupName
:
"培训计划"
,
groupCode
:
"TrainPlan"
,
link
:
'/plan'
}
]
},
{
groupName
:
"店铺管理"
,
groupName
:
"店铺管理"
,
groupCode
:
"CloudShop"
,
groupCode
:
"CloudShop"
,
icon
:
''
,
icon
:
''
,
children
:
[
children
:
[
{
{
groupName
:
"店铺信息"
,
groupCode
:
"ShopInfo"
,
link
:
'/store-info'
},
{
groupName
:
"员工管理"
,
groupName
:
"员工管理"
,
groupCode
:
"ShopStaff"
,
groupCode
:
"ShopStaff"
,
link
:
'/employees-manage'
link
:
'/employees-manage'
...
...
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