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
4de4930c
Commit
4de4930c
authored
Jul 01, 2021
by
zhangleyuan
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' into feature/zhangleyuan/20210619/yongzong-optimize
parents
dbbb5ea8
c380d5ba
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1029 additions
and
1090 deletions
+1029
-1090
src/modules/course-manage/modal/ShareLiveModal.jsx
+52
-46
src/modules/plan-manage/components/EmployeeShareData.jsx
+127
-96
src/modules/plan-manage/components/UserLearningData.jsx
+118
-101
src/modules/plan-manage/modal/relatedCourseModal.jsx
+390
-351
src/modules/teach-tool/examination-manager/ExamData.tsx
+141
-156
src/modules/teach-tool/paper-manage/OperatePaper.jsx
+200
-340
src/modules/teach-tool/paper-manage/OperatePaper.less
+1
-0
No files found.
src/modules/course-manage/modal/ShareLiveModal.jsx
View file @
4de4930c
...
...
@@ -6,67 +6,67 @@
* @Description: 大班直播分享弹窗
*/
import
React
from
'react'
import
{
Modal
,
Button
,
message
}
from
'antd'
import
domtoimage
from
'dom-to-image'
import
React
from
'react'
;
import
{
Modal
,
Button
,
message
}
from
'antd'
;
import
domtoimage
from
'dom-to-image'
;
import
qrcode
from
'@/libs/qrcode/qrcode.js'
import
User
from
'@/common/js/user'
import
$
from
'jquery'
import
_
from
'underscore'
import
CourseService
from
'@/domains/course-domain/CourseService'
import
qrcode
from
'@/libs/qrcode/qrcode.js'
;
import
User
from
'@/common/js/user'
;
import
$
from
'jquery'
;
import
_
from
'underscore'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
'./ShareLiveModal.less'
import
'./ShareLiveModal.less'
;
class
ShareLiveModal
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
)
super
(
props
)
;
this
.
state
=
{
shareUrl
:
'https://xiaomai5.com/liveShare?courseId=12'
,
}
}
;
}
componentDidMount
()
{
// 获取短链接
this
.
handleConvertShortUrl
()
this
.
handleConvertShortUrl
()
;
}
handleConvertShortUrl
=
()
=>
{
const
{
longUrl
}
=
this
.
props
.
data
const
{
longUrl
}
=
this
.
props
.
data
;
// 发请求
CourseService
.
getQrcode
({
urls
:
[
longUrl
],
}).
then
((
res
)
=>
{
const
{
result
=
[]
}
=
res
const
{
result
=
[]
}
=
res
;
this
.
setState
(
{
shareUrl
:
result
[
0
].
shortUrl
,
},
()
=>
{
const
qrcodeWrapDom
=
document
.
querySelector
(
'#qrcodeWrap'
)
const
qrcodeWrapDom
=
document
.
querySelector
(
'#qrcodeWrap'
)
;
const
qrcodeNode
=
new
qrcode
({
text
:
this
.
state
.
shareUrl
,
size
:
98
,
})
qrcodeWrapDom
.
appendChild
(
qrcodeNode
)
})
;
qrcodeWrapDom
.
appendChild
(
qrcodeNode
)
;
const
qrcodeWrapDomDownload
=
document
.
querySelector
(
'#qrcodeWrap-dowload'
)
const
qrcodeWrapDomDownload
=
document
.
querySelector
(
'#qrcodeWrap-dowload'
)
;
const
qrcodeNodeDownLoad
=
new
qrcode
({
text
:
this
.
state
.
shareUrl
,
size
:
196
,
})
qrcodeWrapDomDownload
.
appendChild
(
qrcodeNodeDownLoad
)
}
)
})
});
qrcodeWrapDomDownload
.
appendChild
(
qrcodeNodeDownLoad
);
}
);
});
};
componentWillUnmount
()
{
// 页面销毁之前清空定时器
clearTimeout
(
this
.
timer
)
clearTimeout
(
this
.
timer
)
;
}
// 下载海报
...
...
@@ -79,31 +79,31 @@ class ShareLiveModal extends React.Component {
()
=>
{
this
.
setState
({
time
:
new
Date
().
valueOf
()
},
()
=>
{
setTimeout
(()
=>
{
let
node
=
document
.
getElementById
(
'poster-dowload'
)
let
node
=
document
.
getElementById
(
'poster-dowload'
)
;
domtoimage
.
toPng
(
node
).
then
((
imgData
)
=>
{
console
.
log
(
imgData
)
const
download
=
document
.
createElement
(
'a'
)
const
{
courseName
}
=
this
.
props
.
data
$
(
download
).
attr
(
'href'
,
imgData
).
attr
(
'download'
,
`
${
courseName
}
.png`
).
get
(
0
).
click
()
})
},
1000
)
})
}
)
console
.
log
(
imgData
);
const
download
=
document
.
createElement
(
'a'
);
const
{
courseName
}
=
this
.
props
.
data
;
$
(
download
).
attr
(
'href'
,
imgData
).
attr
(
'download'
,
`
${
courseName
}
.png`
).
get
(
0
).
click
();
});
},
1000
);
});
}
);
};
// 复制分享链接
handleCopy
=
()
=>
{
const
textContent
=
document
.
getElementById
(
'shareUrl'
).
innerText
const
textContent
=
document
.
getElementById
(
'shareUrl'
).
innerText
;
window
.
copyText
(
textContent
)
message
.
success
(
'复制成功!'
)
}
window
.
copyText
(
textContent
)
;
message
.
success
(
'复制成功!'
)
;
}
;
render
()
{
const
{
courseDivision
,
data
,
type
,
title
}
=
this
.
props
const
{
courseName
,
scheduleVideoUrl
,
courseMediaVOS
,
coverUrl
}
=
data
const
{
shareUrl
,
showImg
,
time
}
=
this
.
state
const
{
courseDivision
,
data
,
type
,
title
}
=
this
.
props
;
const
{
courseName
,
scheduleVideoUrl
,
courseMediaVOS
,
coverUrl
}
=
data
;
const
{
shareUrl
,
showImg
,
time
}
=
this
.
state
;
// 判断是否是默认图, 默认图不需要在URL后面增加字符串
let
coverImgSrc
=
''
;
switch
(
type
)
{
...
...
@@ -111,15 +111,21 @@ class ShareLiveModal extends React.Component {
if
(
courseMediaVOS
&&
courseMediaVOS
.
length
>
0
)
{
data
.
courseMediaVOS
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentType
===
'COVER'
)
{
coverImgSrc
=
item
.
mediaUrl
coverImgSrc
=
item
.
mediaUrl
;
}
else
{
coverImgSrc
=
'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'
;
}
})
})
;
}
else
{
coverImgSrc
=
'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'
;
}
break
;
case
'videoClass'
:
// 视频课
coverImgSrc
=
coverUrl
||
(
courseDivision
===
'internal'
?
`
${
scheduleVideoUrl
}
?x-oss-process=video/snapshot,t_0,m_fast&anystring=anystring`
:
'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png'
)
coverImgSrc
=
coverUrl
||
(
courseDivision
===
'internal'
?
`
${
scheduleVideoUrl
}
?x-oss-process=video/snapshot,t_0,m_fast&anystring=anystring`
:
'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png'
);
break
;
case
'graphicsClass'
:
// 图文课
coverImgSrc
=
coverUrl
||
'https://image.xiaomaiketang.com/xm/wFnpZtp2yB.png'
;
...
...
@@ -214,8 +220,8 @@ class ShareLiveModal extends React.Component {
</
div
>
</
div
>
</
Modal
>
)
)
;
}
}
export
default
ShareLiveModal
export
default
ShareLiveModal
;
src/modules/plan-manage/components/EmployeeShareData.jsx
View file @
4de4930c
import
React
from
'react'
;
import
{
withRouter
}
from
"react-router-dom"
;
import
{
Table
,
Modal
,
Input
,
message
}
from
'antd'
;
import
{
PageControl
}
from
"@/components"
;
import
PlanService
from
'@/domains/plan-domain/planService'
import
{
withRouter
}
from
'react-router-dom'
;
import
{
Input
}
from
'antd'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
college
from
'@/common/lottie/college'
;
import
PlanService
from
'@/domains/plan-domain/planService'
;
import
User
from
'@/common/js/user'
;
import
Bus
from
'@/core/bus'
;
import
'./EmployeeShareData.less'
;
...
...
@@ -10,103 +11,129 @@ import './EmployeeShareData.less';
const
{
Search
}
=
Input
;
const
UserRole
=
{
Store_Manager
:
{
text
:
"学院管理员"
text
:
'学院管理员'
,
},
Cloud_Manager
:
{
text
:
"管理员"
text
:
'管理员'
,
},
Cloud_Operator
:
{
text
:
'运营师'
text
:
'运营师'
,
},
Cloud_Lecture
:
{
text
:
"讲师"
text
:
'讲师'
,
},
};
class
EmployeeShareData
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
const
id
=
getParameterByName
(
"id"
);
const
id
=
getParameterByName
(
'id'
);
this
.
state
=
{
id
,
dataSource
:[],
size
:
10
,
dataSource
:
[],
size
:
10
,
query
:
{
current
:
1
,
},
totalCount
:
0
,
}
totalCount
:
0
,
}
;
}
componentDidMount
(){
componentDidMount
()
{
this
.
handleFetchDataList
();
}
handleFetchDataList
=
()
=>
{
const
{
query
,
size
,
id
}
=
this
.
state
;
const
params
=
{
handleFetchDataList
=
()
=>
{
const
{
query
,
size
,
id
}
=
this
.
state
;
const
params
=
{
...
query
,
size
,
planId
:
id
,
storeId
:
User
.
getStoreId
(),
}
planId
:
id
,
storeId
:
User
.
getStoreId
(),
}
;
PlanService
.
getPlanUserRecordPage
(
params
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
result
=
{}
}
=
res
;
const
{
records
=
[],
total
=
0
}
=
result
;
this
.
setState
({
dataSource
:
records
,
totalCount
:
Number
(
total
)
totalCount
:
Number
(
total
),
});
});
}
}
;
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
return
return
;
}
this
.
setState
({
size
},()
=>
{
this
.
handleFetchDataList
()})
this
.
setState
(
{
size
,
},
()
=>
{
this
.
handleFetchDataList
();
}
handleChangeTable
=
(
pagination
,
filters
,
sorter
)
=>
{
);
};
handleChangeTable
=
(
pagination
,
filters
,
sorter
)
=>
{
const
{
columnKey
,
order
}
=
sorter
;
const
{
query
}
=
this
.
state
;
let
_columnKey
;
let
_order
;
if
(
columnKey
===
'learnNum'
&&
order
===
'ascend'
)
{
_columnKey
=
"LEARN_NUM"
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'learnNum'
&&
order
===
'descend'
)
{
_columnKey
=
"LEARN_NUM"
;
_order
=
'SORT_DESC'
;
}
if
(
columnKey
===
'learnNum'
&&
order
===
'ascend'
)
{
_columnKey
=
'LEARN_NUM'
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'learnNum'
&&
order
===
'descend'
)
{
_columnKey
=
'LEARN_NUM'
;
_order
=
'SORT_DESC'
;
}
if
(
columnKey
===
'learnFinishNum'
&&
order
===
'ascend'
)
{
_columnKey
=
"FINISH_NUM"
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'learnFinishNum'
&&
order
===
'descend'
)
{
_columnKey
=
"FINISH_NUM"
;
_order
=
'SORT_DESC'
;
}
if
(
columnKey
===
'learnFinishNum'
&&
order
===
'ascend'
)
{
_columnKey
=
'FINISH_NUM'
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'learnFinishNum'
&&
order
===
'descend'
)
{
_columnKey
=
'FINISH_NUM'
;
_order
=
'SORT_DESC'
;
}
if
(
columnKey
===
'learnNoFinishNum'
&&
order
===
'ascend'
)
{
_columnKey
=
"NOT_NUM"
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'learnNoFinishNum'
&&
order
===
'descend'
)
{
_columnKey
=
"NOT_NUM"
;
_order
=
'SORT_DESC'
;
}
if
(
columnKey
===
'learnNoFinishNum'
&&
order
===
'ascend'
)
{
_columnKey
=
'NOT_NUM'
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'learnNoFinishNum'
&&
order
===
'descend'
)
{
_columnKey
=
'NOT_NUM'
;
_order
=
'SORT_DESC'
;
}
const
_query
=
{
...
query
,
sortMap
:
{}
sortMap
:
{},
};
_query
.
sortMap
[
_columnKey
]
=
_order
;
this
.
setState
({
query
:
_query
},()
=>
this
.
handleFetchDataList
())
}
handleChangNickname
=
(
value
)
=>
{
_query
.
sortMap
[
_columnKey
]
=
_order
;
this
.
setState
(
{
query
:
_query
,
},
()
=>
this
.
handleFetchDataList
()
);
};
handleChangNickname
=
(
value
)
=>
{
const
isPhone
=
(
value
||
''
).
match
(
/^
\d
+$/
);
const
{
query
}
=
this
.
state
;
if
(
isPhone
)
{
if
(
isPhone
)
{
query
.
userPhone
=
value
;
query
.
userName
=
null
;
}
else
{
}
else
{
query
.
userName
=
value
;
query
.
userPhone
=
null
;
}
query
.
current
=
1
;
this
.
setState
({
query
})
}
watchDataView
=
(
record
)
=>
{
Bus
.
trigger
(
'watchDataView'
,
record
);
}
query
,
});
}
;
watchDataView
=
(
record
)
=>
{
Bus
.
trigger
(
'watchDataView'
,
record
);
}
;
// 请求表头
parselumns
=
()
=>
{
const
columns
=
[
...
...
@@ -115,24 +142,16 @@ class EmployeeShareData extends React.Component {
key
:
'storeUserName'
,
dataIndex
:
'storeUserName'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
val
}
</
div
>
)
}
return
<
div
>
{
val
}
</
div
>;
},
},
{
title
:
'角色'
,
key
:
'roleEnum'
,
dataIndex
:
'roleEnum'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
UserRole
[
record
.
roleEnum
].
text
}
</
div
>
)
}
return
<
div
>
{
UserRole
[
record
.
roleEnum
].
text
}
</
div
>;
},
},
//产品暂时性隐藏
// {
...
...
@@ -151,28 +170,20 @@ class EmployeeShareData extends React.Component {
title
:
'最近分享成功时间'
,
key
:
'recentlyForwardTime'
,
dataIndex
:
'recentlyForwardTime'
,
width
:
240
,
width
:
240
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
div
>
)
}
return
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
div
>;
},
},
{
title
:
'学习人数'
,
key
:
'learnNum'
,
dataIndex
:
'learnNum'
,
width
:
110
,
sorter
:
true
,
width
:
110
,
sorter
:
true
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"learn-num"
>
{
val
}
</
div
>
)
}
return
<
div
className=
'learn-num'
>
{
val
}
</
div
>;
},
},
// {
// title: '已学完',
...
...
@@ -208,24 +219,39 @@ class EmployeeShareData extends React.Component {
dataIndex
:
'operate'
,
render
:
(
val
,
record
)
=>
{
return
(
<
span
className=
"operate-item"
onClick=
{
()
=>
this
.
watchDataView
(
record
)
}
>
数据详情
</
span
>
)
}
}
<
span
className=
'operate-item'
onClick=
{
()
=>
this
.
watchDataView
(
record
)
}
>
数据详情
</
span
>
);
},
},
];
return
columns
;
}
}
;
render
()
{
const
{
dataSource
,
query
,
size
,
totalCount
}
=
this
.
state
;
const
{
dataSource
,
query
,
size
,
totalCount
}
=
this
.
state
;
return
(
<
div
className=
"employee-share-data"
>
<
div
className=
"search-container"
>
<
Search
placeholder=
"搜索员工姓名或手机号"
onChange=
{
(
e
)
=>
{
this
.
handleChangNickname
(
e
.
target
.
value
)}
}
onSearch=
{
()
=>
{
this
.
handleFetchDataList
()}
}
style=
{
{
width
:
200
}
}
enterButton=
{
<
span
className=
"icon iconfont"
>

</
span
>
}
/>
<
div
className=
'employee-share-data'
>
<
div
className=
'search-container'
>
<
Search
placeholder=
'搜索员工姓名或手机号'
onChange=
{
(
e
)
=>
{
this
.
handleChangNickname
(
e
.
target
.
value
);
}
}
onSearch=
{
()
=>
{
this
.
handleFetchDataList
();
}
}
style=
{
{
width
:
200
}
}
enterButton=
{
<
span
className=
'icon iconfont'
>

</
span
>
}
/>
</
div
>
<
div
>
<
Table
rowKey=
{
record
=>
record
.
id
}
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
id
}
dataSource=
{
dataSource
}
columns=
{
this
.
parselumns
()
}
pagination=
{
false
}
...
...
@@ -233,25 +259,30 @@ class EmployeeShareData extends React.Component {
showSorterTooltip=
{
false
}
bordered
/>
{
dataSource
.
length
>
0
&&
<
div
className=
"box-footer"
>
{
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
()})
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
setState
(
{
query
:
_query
,
},
()
=>
{
this
.
handleFetchDataList
();
}
);
}
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
/>
</
div
>
}
)
}
</
div
>
</
div
>
)
)
;
}
}
...
...
src/modules/plan-manage/components/UserLearningData.jsx
View file @
4de4930c
import
React
from
'react'
import
{
withRouter
}
from
'react-router-dom'
import
{
Table
,
Modal
,
message
,
Tooltip
}
from
'antd'
import
{
PageControl
}
from
'@/components'
import
UserLearningDataFilter
from
'./UserLearningDataFilter'
import
PlanService
from
'@/domains/plan-domain/planService'
import
UserLearnDetailModal
from
'../modal/UserLearnDetailModal'
import
UnbundEmployeeModal
from
'../modal/UnbundEmployeeModal'
import
User
from
'@/common/js/user'
import
'./UserLearningData.less'
const
{
confirm
}
=
Modal
import
React
from
'react'
;
import
{
withRouter
}
from
'react-router-dom'
;
import
{
Modal
,
message
,
Tooltip
}
from
'antd'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
college
from
'@/common/lottie/college'
;
import
UserLearningDataFilter
from
'./UserLearningDataFilter'
;
import
PlanService
from
'@/domains/plan-domain/planService'
;
import
UserLearnDetailModal
from
'../modal/UserLearnDetailModal'
;
import
UnbundEmployeeModal
from
'../modal/UnbundEmployeeModal'
;
import
User
from
'@/common/js/user'
;
import
'./UserLearningData.less'
;
const
{
confirm
}
=
Modal
;
const
LearnState
=
{
UN_PLAY
:
{
text
:
'未开始'
,
...
...
@@ -19,12 +20,12 @@ const LearnState = {
FINISH
:
{
text
:
'已完成'
,
},
}
}
;
class
UserLearningData
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
)
const
id
=
getParameterByName
(
'id'
)
super
(
props
)
;
const
id
=
getParameterByName
(
'id'
)
;
this
.
state
=
{
id
,
dataSource
:
[],
...
...
@@ -35,13 +36,13 @@ class UserLearningData extends React.Component {
totalCount
:
0
,
userLearnDetailModalSHow
:
false
,
unbundEmployeeModalVisible
:
false
,
}
}
;
}
componentDidMount
()
{
this
.
handleFetchDataList
()
this
.
handleFetchDataList
()
;
}
handleFetchDataList
=
(
_query
)
=>
{
const
{
query
,
size
,
id
}
=
this
.
state
const
{
query
,
size
,
id
}
=
this
.
state
;
const
params
=
{
...
query
,
...
_query
,
...
...
@@ -49,88 +50,88 @@ class UserLearningData extends React.Component {
planId
:
id
,
storeId
:
User
.
getStoreId
(),
storeUserId
:
User
.
getStoreUserId
(),
}
this
.
setState
({
query
:
params
})
}
;
this
.
setState
({
query
:
params
})
;
PlanService
.
getPlanCustomerRecordPage
(
params
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
const
{
records
=
[],
total
=
0
}
=
result
const
{
result
=
{}
}
=
res
;
const
{
records
=
[],
total
=
0
}
=
result
;
this
.
setState
({
dataSource
:
records
,
totalCount
:
Number
(
total
),
})
})
}
})
;
})
;
}
;
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
return
return
;
}
this
.
setState
(
{
size
,
},
()
=>
{
this
.
handleFetchDataList
()
}
)
this
.
handleFetchDataList
();
}
);
};
handleChangeTable
=
(
pagination
,
filters
,
sorter
)
=>
{
const
{
columnKey
,
order
}
=
sorter
const
{
query
}
=
this
.
state
let
_columnKey
let
_order
const
{
columnKey
,
order
}
=
sorter
;
const
{
query
}
=
this
.
state
;
let
_columnKey
;
let
_order
;
if
(
columnKey
===
'latelyLearnTime'
&&
order
===
'ascend'
)
{
_columnKey
=
'LATE_LEARN_TIME'
_order
=
'SORT_ASC'
_columnKey
=
'LATE_LEARN_TIME'
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'latelyLearnTime'
&&
order
===
'descend'
)
{
_columnKey
=
'LATE_LEARN_TIME'
_order
=
'SORT_DESC'
_columnKey
=
'LATE_LEARN_TIME'
;
_order
=
'SORT_DESC'
;
}
if
(
columnKey
===
'startLearnTime'
&&
order
===
'ascend'
)
{
_columnKey
=
'START_LEARN_TIME'
_order
=
'SORT_ASC'
_columnKey
=
'START_LEARN_TIME'
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'startLearnTime'
&&
order
===
'descend'
)
{
_columnKey
=
'START_LEARN_TIME'
_order
=
'SORT_DESC'
_columnKey
=
'START_LEARN_TIME'
;
_order
=
'SORT_DESC'
;
}
if
(
columnKey
===
'learnNum'
&&
order
===
'ascend'
)
{
_columnKey
=
'LEARN_NUM'
_order
=
'SORT_ASC'
_columnKey
=
'LEARN_NUM'
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'learnNum'
&&
order
===
'descend'
)
{
_columnKey
=
'LEARN_NUM'
_order
=
'SORT_DESC'
_columnKey
=
'LEARN_NUM'
;
_order
=
'SORT_DESC'
;
}
const
_query
=
{
...
query
,
sortMap
:
{},
}
_query
.
sortMap
[
_columnKey
]
=
_order
}
;
_query
.
sortMap
[
_columnKey
]
=
_order
;
this
.
setState
(
{
query
:
_query
,
},
()
=>
this
.
handleFetchDataList
()
)
}
)
;
}
;
watchDetail
=
(
record
)
=>
{
this
.
setState
({
userLearnDetailModalSHow
:
true
,
storeCustomerId
:
record
.
storeCustomerId
,
planId
:
record
.
planId
,
})
}
})
;
}
;
closeUserLearnDetailModal
=
()
=>
{
this
.
setState
({
userLearnDetailModalSHow
:
false
,
})
}
})
;
}
;
UnbundEmployee
=
(
record
)
=>
{
if
(
User
.
getUserRole
()
===
'CloudOperator'
)
{
return
confirm
({
...
...
@@ -141,40 +142,40 @@ class UserLearningData extends React.Component {
okType
:
'danger'
,
cancelText
:
'取消'
,
onOk
:
()
=>
{
this
.
handleConfirmUnbundEmployee
(
record
.
storeCustomerId
)
this
.
handleConfirmUnbundEmployee
(
record
.
storeCustomerId
)
;
},
})
})
;
}
else
{
this
.
setState
({
unbundEmployeeModalVisible
:
true
,
storeCustomerId
:
record
.
storeCustomerId
,
})
}
});
}
};
handleConfirmUnbundEmployee
=
(
storeCustomerId
)
=>
{
let
removeUserIds
=
[]
removeUserIds
.
push
(
storeCustomerId
)
let
removeUserIds
=
[]
;
removeUserIds
.
push
(
storeCustomerId
)
;
const
params
=
{
planId
:
getParameterByName
(
'id'
),
removeUserIds
,
storeCustomerId
:
storeCustomerId
,
storeId
:
User
.
getStoreId
(),
storeUserId
:
User
.
getStoreUserId
(),
}
}
;
PlanService
.
removePlanCustomer
(
params
).
then
((
res
)
=>
{
this
.
handleFetchDataList
()
message
.
success
(
'解绑成功'
)
})
}
this
.
handleFetchDataList
()
;
message
.
success
(
'解绑成功'
)
;
})
;
}
;
handleCloseUnbundEmployeeModal
=
()
=>
{
this
.
setState
({
unbundEmployeeModalVisible
:
false
,
})
}
})
;
}
;
// 请求表头
parselumns
=
()
=>
{
let
columns
let
columns
;
if
(
User
.
getUserRole
()
===
'CloudManager'
||
User
.
getUserRole
()
===
'StoreManager'
)
{
columns
=
[
{
...
...
@@ -182,7 +183,7 @@ class UserLearningData extends React.Component {
key
:
'storeCustomerName'
,
dataIndex
:
'storeCustomerName'
,
render
:
(
val
,
record
)
=>
{
return
<
div
>
{
val
}
</
div
>
return
<
div
>
{
val
}
</
div
>
;
},
},
{
...
...
@@ -190,14 +191,20 @@ class UserLearningData extends React.Component {
key
:
'learnState'
,
dataIndex
:
'learnState'
,
render
:
(
val
,
record
)
=>
{
return
<
div
>
{
LearnState
[
val
].
text
}
</
div
>
return
<
div
>
{
LearnState
[
val
].
text
}
</
div
>
;
},
},
{
title
:
<
span
>
title
:
(
<
span
>
<
span
>
负责人
</
span
>
<
Tooltip
title=
"培训计划的分享者/跟进人"
><
i
className=
"icon iconfont"
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
"400"
}
}
>

</
i
></
Tooltip
>
</
span
>,
<
Tooltip
title=
'培训计划的分享者/跟进人'
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'400'
}
}
>

</
i
>
</
Tooltip
>
</
span
>
),
key
:
'userNameList'
,
dataIndex
:
'userNameList'
,
render
:
(
val
,
record
)
=>
{
...
...
@@ -208,10 +215,10 @@ class UserLearningData extends React.Component {
<
span
>
{
item
}
{
index
<
record
.
userNameList
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
)
)
;
})
}
</
div
>
)
)
;
},
},
{
...
...
@@ -221,7 +228,7 @@ class UserLearningData extends React.Component {
sorter
:
true
,
width
:
240
,
render
:
(
val
,
record
)
=>
{
return
`
${
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
record
.
latelyLearnTime
))}
`
return
`
${
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
record
.
latelyLearnTime
))}
`
;
},
},
{
...
...
@@ -231,14 +238,20 @@ class UserLearningData extends React.Component {
width
:
240
,
sorter
:
true
,
render
:
(
val
,
record
)
=>
{
return
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
div
>
return
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
div
>
;
},
},
{
title
:
<
span
>
title
:
(
<
span
>
<
span
>
学习进度
</
span
>
<
Tooltip
title=
"学员培训计划中达到“已完成”状态的课程数/总课程数"
><
i
className=
"icon iconfont"
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
"400"
}
}
>

</
i
></
Tooltip
>
</
span
>,
<
Tooltip
title=
'学员培训计划中达到“已完成”状态的课程数/总课程数'
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'400'
}
}
>

</
i
>
</
Tooltip
>
</
span
>
),
key
:
'learnNum'
,
dataIndex
:
'learnNum'
,
width
:
130
,
...
...
@@ -250,7 +263,7 @@ class UserLearningData extends React.Component {
<
span
>
/
</
span
>
<
span
>
{
record
.
courseNum
}
</
span
>
</
div
>
)
)
;
},
},
{
...
...
@@ -267,15 +280,15 @@ class UserLearningData extends React.Component {
<
span
className=
'operate-item'
onClick=
{
()
=>
{
this
.
UnbundEmployee
(
record
)
this
.
UnbundEmployee
(
record
)
;
}
}
>
解绑
</
span
>
</
div
>
)
)
;
},
},
]
]
;
}
else
{
columns
=
[
{
...
...
@@ -283,7 +296,7 @@ class UserLearningData extends React.Component {
key
:
'storeCustomerName'
,
dataIndex
:
'storeCustomerName'
,
render
:
(
val
,
record
)
=>
{
return
<
div
>
{
val
}
</
div
>
return
<
div
>
{
val
}
</
div
>
;
},
},
{
...
...
@@ -291,7 +304,7 @@ class UserLearningData extends React.Component {
key
:
'learnState'
,
dataIndex
:
'learnState'
,
render
:
(
val
,
record
)
=>
{
return
<
div
>
{
LearnState
[
val
].
text
}
</
div
>
return
<
div
>
{
LearnState
[
val
].
text
}
</
div
>
;
},
},
{
...
...
@@ -300,7 +313,7 @@ class UserLearningData extends React.Component {
dataIndex
:
'latelyLearnTime'
,
sorter
:
true
,
render
:
(
val
,
record
)
=>
{
return
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
div
>
return
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
div
>
;
},
},
{
...
...
@@ -309,7 +322,7 @@ class UserLearningData extends React.Component {
dataIndex
:
'startLearnTime'
,
sorter
:
true
,
render
:
(
val
,
record
)
=>
{
return
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
div
>
return
<
div
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
div
>
;
},
},
{
...
...
@@ -333,7 +346,7 @@ class UserLearningData extends React.Component {
<
span
>
/
</
span
>
<
span
>
{
record
.
courseNum
}
</
span
>
</
div
>
)
)
;
},
},
{
...
...
@@ -350,28 +363,32 @@ class UserLearningData extends React.Component {
<
span
className=
'operate-item'
onClick=
{
()
=>
{
this
.
UnbundEmployee
(
record
)
this
.
UnbundEmployee
(
record
)
;
}
}
>
解绑
</
span
>
</
div
>
)
)
;
},
},
]
]
;
}
return
columns
}
return
columns
;
}
;
render
()
{
const
{
dataSource
,
query
,
size
,
totalCount
,
userLearnDetailModalSHow
,
storeCustomerId
,
planId
,
unbundEmployeeModalVisible
}
=
this
.
state
const
{
dataSource
,
query
,
size
,
totalCount
,
userLearnDetailModalSHow
,
storeCustomerId
,
planId
,
unbundEmployeeModalVisible
}
=
this
.
state
;
return
(
<
div
className=
'user-learning-data'
>
<
div
className=
'search-container'
>
<
UserLearningDataFilter
onChange=
{
this
.
handleFetchDataList
}
/>
</
div
>
<
div
>
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
storeCustomerId
}
dataSource=
{
dataSource
}
columns=
{
this
.
parselumns
()
}
...
...
@@ -388,15 +405,15 @@ class UserLearningData extends React.Component {
pageSize=
{
size
}
total=
{
totalCount
}
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
query
,
current
:
page
+
1
}
const
_query
=
{
...
query
,
current
:
page
+
1
}
;
this
.
setState
(
{
query
:
_query
,
},
()
=>
{
this
.
handleFetchDataList
()
this
.
handleFetchDataList
()
;
}
)
)
;
}
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
/>
...
...
@@ -412,14 +429,14 @@ class UserLearningData extends React.Component {
onClose=
{
this
.
handleCloseUnbundEmployeeModal
}
storeCustomerId=
{
storeCustomerId
}
onConfirm=
{
()
=>
{
this
.
handleFetchDataList
()
this
.
handleCloseUnbundEmployeeModal
()
this
.
handleFetchDataList
()
;
this
.
handleCloseUnbundEmployeeModal
()
;
}
}
/>
)
}
</
div
>
)
)
;
}
}
export
default
withRouter
(
UserLearningData
)
export
default
withRouter
(
UserLearningData
)
;
src/modules/plan-manage/modal/relatedCourseModal.jsx
View file @
4de4930c
import
React
from
"react"
import
_
from
"underscore"
import
{
Table
,
Radio
,
Tabs
,
Modal
,
Input
,
message
,
Button
,
Tooltip
}
from
"antd"
import
React
from
'react'
;
import
_
from
'underscore'
;
import
{
Table
,
Radio
,
Tabs
,
Modal
,
Input
,
message
,
Button
,
Tooltip
}
from
'antd'
;
import
{
PageControl
}
from
"@/components"
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
college
from
'@/common/lottie/college'
;
import
CourseService
from
"@/domains/course-domain/CourseService"
import
User
from
"@/common/js/user"
import
Service
from
"@/common/js/service"
import
dealTimeDuration
from
"../../course-manage/utils/dealTimeDuration"
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
User
from
'@/common/js/user'
;
import
Service
from
'@/common/js/service'
;
import
dealTimeDuration
from
'../../course-manage/utils/dealTimeDuration'
;
import
"./relatedCourseModal.less"
import
'./relatedCourseModal.less'
;
const
{
Search
}
=
Input
const
{
TabPane
}
=
Tabs
const
{
Search
}
=
Input
;
const
{
TabPane
}
=
Tabs
;
const
courseStateShow
=
{
UN_START
:
{
code
:
1
,
title
:
"待开课"
,
color
:
"#FFB129"
,
title
:
'待开课'
,
color
:
'#FFB129'
,
},
STARTING
:
{
code
:
2
,
title
:
"上课中"
,
color
:
"#238FFF"
title
:
'上课中'
,
color
:
'#238FFF'
,
},
FINISH
:
{
code
:
3
,
title
:
"已完成"
,
color
:
"#3BBDAA"
title
:
'已完成'
,
color
:
'#3BBDAA'
,
},
EXPIRED
:
{
code
:
4
,
title
:
"未成功开课"
,
color
:
"#999"
}
}
title
:
'未成功开课'
,
color
:
'#999'
,
}
,
}
;
class
SelectOperatorModal
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
)
super
(
props
)
;
this
.
state
=
{
liveDataSource
:
[],
liveSize
:
10
,
liveQuery
:
{
current
:
1
current
:
1
,
},
liveTotalCount
:
0
,
selectLive
:
[],
//弹窗内已选择的直播课程
currentCourseListData
:
[],
currentLiveCourseListData
:
[],
//页面中已关联的直播课程
videoCourseDivision
:
"internal"
,
videoCourseDivision
:
'internal'
,
videoDataSource
:
{
external
:
[],
internal
:
[]
internal
:
[]
,
},
videoSize
:
{
external
:
10
,
internal
:
10
internal
:
10
,
},
videoSearchName
:
{
external
:
""
,
internal
:
""
external
:
''
,
internal
:
''
,
},
videoSearchDefalt
:
""
,
videoSearchDefalt
:
''
,
videoQuery
:
{
external
:
{
current
:
1
current
:
1
,
},
internal
:
{
current
:
1
}
current
:
1
,
}
,
},
videoTotalCount
:
{
external
:
0
,
internal
:
0
internal
:
0
,
},
selectVideo
:
{
external
:
[],
internal
:
[]
internal
:
[]
,
},
//弹窗内已选择的视频课程
currentVideoCourseListData
:
{
external
:
[],
internal
:
[]
internal
:
[]
,
},
//页面中已关联的视频课程
pictureDataSource
:
[],
pictureSize
:
10
,
pictureQuery
:
{
current
:
1
current
:
1
,
},
pictureTotalCount
:
0
,
selectPicture
:
[],
//弹窗内已选择的视频课程
currentPictureCourseListData
:
[],
//页面中已关联的视频课程
activeKey
:
"video"
,
currentTaskCourseData
:
this
.
props
.
data
[
this
.
props
.
selectedTaskIndex
].
courseList
||
[]
}
activeKey
:
'video'
,
currentTaskCourseData
:
this
.
props
.
data
[
this
.
props
.
selectedTaskIndex
].
courseList
||
[]
,
}
;
}
componentDidMount
()
{
this
.
handleFetchLiveDataList
()
this
.
handleFetchVideoDataList
()
this
.
handleFetchPictureDataList
()
this
.
handleFetchLiveDataList
()
;
this
.
handleFetchVideoDataList
()
;
this
.
handleFetchPictureDataList
()
;
}
// 获取直播课列表
handleFetchLiveDataList
=
()
=>
{
const
{
liveQuery
,
liveSize
}
=
this
.
state
const
_data
=
[...
this
.
props
.
data
]
let
currentLiveCourseListData
=
[]
const
{
liveQuery
,
liveSize
}
=
this
.
state
;
const
_data
=
[...
this
.
props
.
data
]
;
let
currentLiveCourseListData
=
[]
;
_data
.
map
((
item
)
=>
{
item
.
courseList
.
map
((
childItem
,
childIndex
)
=>
{
if
(
childItem
.
courseType
===
"LIVE"
)
{
currentLiveCourseListData
.
push
(
childItem
.
courseId
)
if
(
childItem
.
courseType
===
'LIVE'
)
{
currentLiveCourseListData
.
push
(
childItem
.
courseId
)
;
}
return
childItem
})
return
item
})
return
childItem
;
})
;
return
item
;
})
;
const
params
=
{
...
liveQuery
,
size
:
liveSize
,
excludeCourseIdList
:
currentLiveCourseListData
}
excludeCourseIdList
:
currentLiveCourseListData
,
}
;
CourseService
.
getLiveCloudCourseBasePage
(
params
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
const
{
records
=
[],
total
=
0
}
=
result
const
{
result
=
{}
}
=
res
;
const
{
records
=
[],
total
=
0
}
=
result
;
this
.
setState
({
liveDataSource
:
records
,
liveTotalCount
:
Number
(
total
),
currentLiveCourseListData
})
})
}
currentLiveCourseListData
,
})
;
})
;
}
;
// 获取视频课列表
handleFetchVideoDataList
=
()
=>
{
const
{
videoQuery
,
videoSize
,
videoDataSource
,
videoTotalCount
,
videoCourseDivision
}
=
this
.
state
const
{
videoQuery
,
videoSize
,
videoDataSource
,
videoTotalCount
,
videoCourseDivision
}
=
this
.
state
;
const
_data
=
[...
this
.
props
.
data
]
let
currentVideoCourseListData
=
[]
const
_data
=
[...
this
.
props
.
data
]
;
let
currentVideoCourseListData
=
[]
;
_data
.
map
((
item
,
index
)
=>
{
item
.
courseList
.
map
((
childItem
,
childIndex
)
=>
{
if
(
childItem
.
courseType
===
"VOICE"
)
{
currentVideoCourseListData
.
push
(
childItem
.
courseId
)
if
(
childItem
.
courseType
===
'VOICE'
)
{
currentVideoCourseListData
.
push
(
childItem
.
courseId
)
;
}
return
childItem
})
return
item
})
return
childItem
;
})
;
return
item
;
})
;
const
params
=
{
...
videoQuery
[
videoCourseDivision
],
size
:
videoSize
[
videoCourseDivision
],
courseDivision
:
videoCourseDivision
===
"internal"
?
"INTERNAL"
:
"EXTERNAL"
,
excludeCourseIdList
:
currentVideoCourseListData
}
courseDivision
:
videoCourseDivision
===
'internal'
?
'INTERNAL'
:
'EXTERNAL'
,
excludeCourseIdList
:
currentVideoCourseListData
,
}
;
CourseService
.
videoScheduleBasePage
(
params
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
console
.
log
(
"result"
,
result
)
const
{
result
=
{}
}
=
res
;
console
.
log
(
'result'
,
result
);
const
{
records
=
[],
total
=
0
}
=
result
const
{
records
=
[],
total
=
0
}
=
result
;
this
.
setState
({
videoDataSource
:
{
...
videoDataSource
,
[
videoCourseDivision
]:
records
[
videoCourseDivision
]:
records
,
},
videoTotalCount
:
{
...
videoTotalCount
,
[
videoCourseDivision
]:
Number
(
total
)
[
videoCourseDivision
]:
Number
(
total
)
,
},
currentVideoCourseListData
})
})
}
currentVideoCourseListData
,
})
;
})
;
}
;
// 获取图文课列表
handleFetchPictureDataList
=
()
=>
{
const
{
pictureQuery
,
pictureSize
}
=
this
.
state
const
_data
=
[...
this
.
props
.
data
]
let
currentPictureCourseListData
=
[]
const
{
pictureQuery
,
pictureSize
}
=
this
.
state
;
const
_data
=
[...
this
.
props
.
data
]
;
let
currentPictureCourseListData
=
[]
;
_data
.
map
((
item
,
index
)
=>
{
item
.
courseList
.
map
((
childItem
,
childIndex
)
=>
{
if
(
childItem
.
courseType
===
"PICTURE"
)
{
currentPictureCourseListData
.
push
(
childItem
.
courseId
)
if
(
childItem
.
courseType
===
'PICTURE'
)
{
currentPictureCourseListData
.
push
(
childItem
.
courseId
)
;
}
return
childItem
})
return
item
})
return
childItem
;
})
;
return
item
;
})
;
const
params
=
{
...
pictureQuery
,
size
:
pictureSize
,
courseType
:
"PICTURE"
,
courseType
:
'PICTURE'
,
storeId
:
User
.
getStoreId
(),
excludeCourseIdList
:
currentPictureCourseListData
}
excludeCourseIdList
:
currentPictureCourseListData
,
}
;
Service
.
Hades
(
"public/hades/mediaCoursePage"
,
params
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
const
{
records
=
[],
total
=
0
}
=
result
Service
.
Hades
(
'public/hades/mediaCoursePage'
,
params
).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
const
{
records
=
[],
total
=
0
}
=
result
;
this
.
setState
({
pictureDataSource
:
records
,
pictureTotalCount
:
Number
(
total
),
currentPictureCourseListData
})
})
}
currentPictureCourseListData
,
})
;
})
;
}
;
handleChangVideoCourseName
=
(
value
)
=>
{
const
{
videoQuery
,
videoCourseDivision
,
videoSearchName
}
=
this
.
state
videoQuery
[
videoCourseDivision
].
courseName
=
value
videoQuery
[
videoCourseDivision
].
current
=
1
const
{
videoQuery
,
videoCourseDivision
,
videoSearchName
}
=
this
.
state
;
videoQuery
[
videoCourseDivision
].
courseName
=
value
;
videoQuery
[
videoCourseDivision
].
current
=
1
;
this
.
setState
({
...
videoQuery
,
videoSearchDefalt
:
value
,
videoSearchName
:
{
...
videoSearchName
,
[
videoCourseDivision
]:
value
}
})
}
[
videoCourseDivision
]:
value
,
}
,
})
;
}
;
handleChangLiveCourseName
=
(
value
)
=>
{
const
{
liveQuery
}
=
this
.
state
liveQuery
.
courseName
=
value
liveQuery
.
current
=
1
const
{
liveQuery
}
=
this
.
state
;
liveQuery
.
courseName
=
value
;
liveQuery
.
current
=
1
;
this
.
setState
({
liveQuery
})
}
liveQuery
,
})
;
}
;
handleChangPictureCourseName
=
(
value
)
=>
{
const
{
pictureQuery
}
=
this
.
state
pictureQuery
.
courseName
=
value
pictureQuery
.
current
=
1
const
{
pictureQuery
}
=
this
.
state
;
pictureQuery
.
courseName
=
value
;
pictureQuery
.
current
=
1
;
this
.
setState
({
pictureQuery
})
}
pictureQuery
,
})
;
}
;
onShowLiveSizeChange
=
(
current
,
size
)
=>
{
if
(
current
===
size
)
{
return
return
;
}
this
.
setState
(
{
liveSize
:
size
liveSize
:
size
,
},
()
=>
{
this
.
handleFetchLiveDataList
()
}
)
this
.
handleFetchLiveDataList
();
}
);
};
onShowVideoSizeChange
=
(
current
,
size
)
=>
{
if
(
current
===
size
)
{
return
return
;
}
this
.
setState
(
{
videoSize
:
size
videoSize
:
size
,
},
()
=>
{
this
.
handleFetchLiveDataList
()
}
)
this
.
handleFetchLiveDataList
();
}
);
};
onShowPictureSizeChange
=
(
current
,
size
)
=>
{
if
(
current
===
size
)
{
return
return
;
}
this
.
setState
(
{
pictureSize
:
size
pictureSize
:
size
,
},
()
=>
{
this
.
handleFetchPictureDataList
()
}
)
this
.
handleFetchPictureDataList
();
}
);
};
// 请求表头
parseLiveColumns
=
()
=>
{
const
columns
=
[
{
title
:
<
span
><
span
>
课程信息
</
span
><
Tooltip
title=
"仅显示未关联课程,已关联课程不支持重复选择"
><
i
className=
"icon iconfont"
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
"400"
}
}
>

</
i
></
Tooltip
></
span
>,
title
:
(
<
span
>
<
span
>
课程信息
</
span
>
<
Tooltip
title=
'仅显示未关联课程,已关联课程不支持重复选择'
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'400'
}
}
>

</
i
>
</
Tooltip
>
</
span
>
),
key
:
'course'
,
dataIndex
:
'course'
,
width
:
'40%'
,
width
:
'40%'
,
render
:
(
val
,
record
)
=>
{
let
hasCover
=
false
let
hasCover
=
false
;
return
(
<
div
className=
'course-info'
>
{
record
.
courseMediaVOS
.
map
((
item
)
=>
{
if
(
item
.
contentType
===
"COVER"
)
{
hasCover
=
true
return
<
img
className=
'course-cover'
src=
{
item
.
mediaUrl
}
alt=
''
/>
if
(
item
.
contentType
===
'COVER'
)
{
hasCover
=
true
;
return
<
img
className=
'course-cover'
src=
{
item
.
mediaUrl
}
alt=
''
/>
;
}
return
null
return
null
;
})
}
<
If
condition=
{
!
hasCover
}
>
<
img
className=
'course-cover'
src=
{
"https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png"
}
alt=
''
/>
<
img
className=
'course-cover'
src=
{
'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'
}
alt=
''
/>
</
If
>
<
div
>
...
...
@@ -316,35 +325,35 @@ class SelectOperatorModal extends React.Component {
</
span
>
</
div
>
</
div
>
)
}
)
;
}
,
},
{
title
:
"上课时间"
,
key
:
"courseTime"
,
dataIndex
:
"courseTime"
,
width
:
"40%"
,
title
:
'上课时间'
,
key
:
'courseTime'
,
dataIndex
:
'courseTime'
,
width
:
'40%'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
>
<
div
>
{
formatDate
(
"YYYY-MM-DD"
,
record
.
startTime
)
}
</
div
>
<
div
>
{
formatDate
(
'YYYY-MM-DD'
,
record
.
startTime
)
}
</
div
>
<
div
>
{
formatDate
(
"H:i"
,
record
.
startTime
)
}
~
{
formatDate
(
"H:i"
,
record
.
endTime
)
}
{
formatDate
(
'H:i'
,
record
.
startTime
)
}
~
{
formatDate
(
'H:i'
,
record
.
endTime
)
}
</
div
>
</
div
>
)
}
)
;
}
,
},
{
title
:
"学院展示"
,
key
:
"shelfState"
,
dataIndex
:
"shelfState"
,
width
:
"20%"
,
title
:
'学院展示'
,
key
:
'shelfState'
,
dataIndex
:
'shelfState'
,
width
:
'20%'
,
render
:
(
val
,
record
)
=>
{
return
(
<
span
>
<
Choose
>
<
When
condition=
{
record
.
shelfState
===
"YES"
}
>
<
When
condition=
{
record
.
shelfState
===
'YES'
}
>
<
span
>
开启
</
span
>
</
When
>
<
Otherwise
>
...
...
@@ -352,24 +361,33 @@ class SelectOperatorModal extends React.Component {
</
Otherwise
>
</
Choose
>
</
span
>
)
}
}
]
return
columns
}
)
;
}
,
}
,
]
;
return
columns
;
}
;
// 请求表头
parseVideoColumns
=
()
=>
{
const
{
videoCourseDivision
}
=
this
.
state
const
{
videoCourseDivision
}
=
this
.
state
;
const
columns
=
[
{
title
:
<
span
><
span
>
课程信息
</
span
><
Tooltip
title=
"仅显示未关联课程,已关联课程不支持重复选择"
><
i
className=
"icon iconfont"
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
"400"
}
}
>

</
i
></
Tooltip
></
span
>,
title
:
(
<
span
>
<
span
>
课程信息
</
span
>
<
Tooltip
title=
'仅显示未关联课程,已关联课程不支持重复选择'
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'400'
}
}
>

</
i
>
</
Tooltip
>
</
span
>
),
key
:
'course'
,
dataIndex
:
'course'
,
width
:
'60%'
,
width
:
'60%'
,
render
:
(
val
,
record
)
=>
{
const
{
coverUrl
,
scheduleVideoUrl
}
=
record
const
{
coverUrl
,
scheduleVideoUrl
}
=
record
;
return
(
<
div
className=
'course-info'
>
{
/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */
}
...
...
@@ -377,242 +395,251 @@ class SelectOperatorModal extends React.Component {
className=
'course-cover'
src=
{
coverUrl
||
(
videoCourseDivision
===
"internal"
(
videoCourseDivision
===
'internal'
?
`${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast`
:
"https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png"
)
:
'https://image.xiaomaiketang.com/xm/mt3ZQRxGKB.png'
)
}
alt=
''
/>
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
</
div
>
)
}
)
;
}
,
},
{
title
:
"课程时长"
,
key
:
"courseTime"
,
dataIndex
:
"courseTime"
,
width
:
"20%"
,
title
:
'课程时长'
,
key
:
'courseTime'
,
dataIndex
:
'courseTime'
,
width
:
'20%'
,
render
:
(
val
,
record
)
=>
{
return
<
span
className=
'course-status'
>
{
dealTimeDuration
(
record
.
videoDuration
)
}
</
span
>
}
return
<
span
className=
'course-status'
>
{
dealTimeDuration
(
record
.
videoDuration
)
}
</
span
>
;
}
,
},
{
title
:
"学院展示"
,
key
:
"shelfState"
,
dataIndex
:
"shelfState"
,
width
:
"20%"
,
title
:
'学院展示'
,
key
:
'shelfState'
,
dataIndex
:
'shelfState'
,
width
:
'20%'
,
render
:
(
val
,
record
)
=>
{
return
(
<
Choose
>
<
When
condition=
{
record
.
shelfState
===
"YES"
}
>
<
When
condition=
{
record
.
shelfState
===
'YES'
}
>
<
span
>
开启
</
span
>
</
When
>
<
Otherwise
>
<
span
>
关闭
</
span
>
</
Otherwise
>
</
Choose
>
)
}
}
]
return
columns
}
)
;
}
,
}
,
]
;
return
columns
;
}
;
// 请求表头
parsePictureColumns
=
()
=>
{
const
columns
=
[
{
title
:
<
span
><
span
>
课程信息
</
span
><
Tooltip
title=
"仅显示未关联课程,已关联课程不支持重复选择"
><
i
className=
"icon iconfont"
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
"400"
}
}
>

</
i
></
Tooltip
></
span
>,
title
:
(
<
span
>
<
span
>
课程信息
</
span
>
<
Tooltip
title=
'仅显示未关联课程,已关联课程不支持重复选择'
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'400'
}
}
>

</
i
>
</
Tooltip
>
</
span
>
),
key
:
'course'
,
dataIndex
:
'course'
,
width
:
'55%'
,
width
:
'55%'
,
render
:
(
val
,
record
)
=>
{
const
{
coverUrl
}
=
record
const
{
coverUrl
}
=
record
;
return
(
<
div
className=
'course-info'
>
<
img
className=
'course-cover'
src=
{
coverUrl
||
"https://image.xiaomaiketang.com/xm/wFnpZtp2yB.png"
}
alt=
''
/>
<
img
className=
'course-cover'
src=
{
coverUrl
||
'https://image.xiaomaiketang.com/xm/wFnpZtp2yB.png'
}
alt=
''
/>
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
</
div
>
)
}
)
;
}
,
},
{
title
:
"更新时间"
,
key
:
"updated"
,
dataIndex
:
"updated"
,
width
:
"25%"
,
title
:
'更新时间'
,
key
:
'updated'
,
dataIndex
:
'updated'
,
width
:
'25%'
,
render
:
(
val
,
record
)
=>
{
return
<
span
className=
'course-status'
>
{
formatDate
(
"YYYY-MM-DD"
,
record
.
updated
)
}
</
span
>
}
return
<
span
className=
'course-status'
>
{
formatDate
(
'YYYY-MM-DD'
,
record
.
updated
)
}
</
span
>;
}
,
},
{
title
:
"学院展示"
,
key
:
"shelfState"
,
dataIndex
:
"shelfState"
,
width
:
"20%"
,
title
:
'学院展示'
,
key
:
'shelfState'
,
dataIndex
:
'shelfState'
,
width
:
'20%'
,
render
:
(
val
,
record
)
=>
{
return
<
span
>
{
record
.
shelfState
===
"YES"
?
"开启"
:
"关闭"
}
</
span
>
}
}
]
return
columns
}
return
<
span
>
{
record
.
shelfState
===
'YES'
?
'开启'
:
'关闭'
}
</
span
>;
}
,
}
,
]
;
return
columns
;
}
;
selectLiveList
=
(
record
,
selected
)
=>
{
const
{
selectVideo
,
currentTaskCourseData
,
selectLive
,
selectPicture
}
=
this
.
state
let
_list
=
[]
const
{
selectVideo
,
currentTaskCourseData
,
selectLive
,
selectPicture
}
=
this
.
state
;
let
_list
=
[]
;
if
(
selected
||
!
_
.
find
(
selectLive
,
(
item
)
=>
item
.
liveCourseId
===
record
.
liveCourseId
))
{
_list
=
_
.
uniq
(
selectLive
.
concat
([
record
]),
false
,
(
item
)
=>
item
.
liveCourseId
)
_list
=
_
.
uniq
(
selectLive
.
concat
([
record
]),
false
,
(
item
)
=>
item
.
liveCourseId
)
;
}
else
{
_list
=
_
.
reject
(
selectLive
,
(
item
)
=>
item
.
liveCourseId
===
record
.
liveCourseId
)
_list
=
_
.
reject
(
selectLive
,
(
item
)
=>
item
.
liveCourseId
===
record
.
liveCourseId
)
;
}
if
(
_list
.
length
+
currentTaskCourseData
.
length
+
selectVideo
.
length
+
selectPicture
.
length
>
20
)
{
message
.
warning
(
"无法继续选择,一个任务最多关联20个课程"
)
return
}
this
.
setState
({
selectLive
:
_list
})
message
.
warning
(
'无法继续选择,一个任务最多关联20个课程'
);
return
;
}
this
.
setState
({
selectLive
:
_list
});
};
selectVideoList
=
(
record
,
selected
)
=>
{
const
{
selectVideo
,
currentTaskCourseData
,
selectLive
,
selectPicture
,
videoCourseDivision
}
=
this
.
state
const
{
selectVideo
,
currentTaskCourseData
,
selectLive
,
selectPicture
,
videoCourseDivision
}
=
this
.
state
;
let
{
[
videoCourseDivision
]:
selectList
}
=
selectVideo
let
{
[
videoCourseDivision
]:
selectList
}
=
selectVideo
;
let
_list
=
[]
let
_list
=
[]
;
if
(
selected
||
!
_
.
find
(
selectList
,
(
item
)
=>
item
.
id
===
record
.
id
))
{
_list
=
_
.
uniq
(
selectList
.
concat
([
record
]),
false
,
(
item
)
=>
item
.
id
)
_list
=
_
.
uniq
(
selectList
.
concat
([
record
]),
false
,
(
item
)
=>
item
.
id
)
;
}
else
{
_list
=
_
.
reject
(
selectList
,
(
item
)
=>
item
.
id
===
record
.
id
)
_list
=
_
.
reject
(
selectList
,
(
item
)
=>
item
.
id
===
record
.
id
)
;
}
if
(
_list
.
length
+
currentTaskCourseData
.
length
+
selectLive
.
length
+
selectPicture
.
length
>
20
)
{
message
.
warning
(
"无法继续选择,一个任务最多关联20个课程"
)
return
message
.
warning
(
'无法继续选择,一个任务最多关联20个课程'
);
return
;
}
this
.
setState
({
selectVideo
:
{
...
selectVideo
,
[
videoCourseDivision
]:
_list
}
})
}
[
videoCourseDivision
]:
_list
,
}
,
})
;
}
;
selectPictureList
=
(
record
,
selected
)
=>
{
const
{
selectVideo
,
currentTaskCourseData
,
selectLive
,
selectPicture
}
=
this
.
state
let
_list
=
[]
const
{
selectVideo
,
currentTaskCourseData
,
selectLive
,
selectPicture
}
=
this
.
state
;
let
_list
=
[]
;
if
(
selected
||
!
_
.
find
(
selectPicture
,
(
item
)
=>
item
.
id
===
record
.
id
))
{
_list
=
_
.
uniq
(
selectPicture
.
concat
([
record
]),
false
,
(
item
)
=>
item
.
id
)
_list
=
_
.
uniq
(
selectPicture
.
concat
([
record
]),
false
,
(
item
)
=>
item
.
id
)
;
}
else
{
_list
=
_
.
reject
(
selectPicture
,
(
item
)
=>
item
.
id
===
record
.
id
)
_list
=
_
.
reject
(
selectPicture
,
(
item
)
=>
item
.
id
===
record
.
id
)
;
}
if
(
_list
.
length
+
currentTaskCourseData
.
length
+
selectLive
.
length
+
selectVideo
.
length
>
20
)
{
message
.
warning
(
"无法继续选择,一个任务最多关联20个课程"
)
return
}
this
.
setState
({
selectPicture
:
_list
})
message
.
warning
(
'无法继续选择,一个任务最多关联20个课程'
);
return
;
}
this
.
setState
({
selectPicture
:
_list
});
};
clearSelectCourse
=
()
=>
{
this
.
setState
({
selectLive
:
[],
selectVideo
:
{
internal
:
[],
external
:
[]
external
:
[]
,
},
selectPicture
:
[]
})
}
selectPicture
:
[]
,
})
;
}
;
handleSelectVideo
=
(
selectVideo
)
=>
{
return
selectVideo
.
map
((
item
)
=>
{
let
_item
=
{}
_item
.
courseId
=
item
.
id
_item
.
courseType
=
"VOICE"
_item
.
courseName
=
item
.
courseName
let
_item
=
{}
;
_item
.
courseId
=
item
.
id
;
_item
.
courseType
=
'VOICE'
;
_item
.
courseName
=
item
.
courseName
;
return
_item
})
}
return
_item
;
})
;
}
;
handleSelectLive
=
(
selectLive
)
=>
{
return
selectLive
.
map
((
item
,
index
)
=>
{
let
_item
=
{}
_item
.
courseId
=
item
.
liveCourseId
_item
.
courseType
=
"LIVE"
_item
.
courseName
=
item
.
courseName
_item
.
courseState
=
item
.
courseState
return
_item
})
}
let
_item
=
{}
;
_item
.
courseId
=
item
.
liveCourseId
;
_item
.
courseType
=
'LIVE'
;
_item
.
courseName
=
item
.
courseName
;
_item
.
courseState
=
item
.
courseState
;
return
_item
;
})
;
}
;
videoCourseDivisionChange
=
(
e
)
=>
{
const
{
videoSearchName
}
=
this
.
state
const
{
videoSearchName
}
=
this
.
state
;
this
.
setState
(
{
videoCourseDivision
:
e
.
target
.
value
,
videoSearchDefalt
:
videoSearchName
[
e
.
target
.
value
]
videoSearchDefalt
:
videoSearchName
[
e
.
target
.
value
]
,
},
()
=>
{
this
.
handleFetchVideoDataList
()
}
)
this
.
handleFetchVideoDataList
();
}
);
};
handleSelectPicture
=
(
selectPicture
)
=>
{
return
selectPicture
.
map
((
item
,
index
)
=>
{
let
_item
=
{}
_item
.
courseId
=
item
.
id
_item
.
courseType
=
"PICTURE"
_item
.
courseName
=
item
.
courseName
return
_item
})
}
let
_item
=
{}
;
_item
.
courseId
=
item
.
id
;
_item
.
courseType
=
'PICTURE'
;
_item
.
courseName
=
item
.
courseName
;
return
_item
;
})
;
}
;
renderFooter
=
()
=>
{
const
{
activeKey
}
=
this
.
state
let
href
=
""
const
{
activeKey
}
=
this
.
state
;
let
href
=
''
;
switch
(
activeKey
)
{
case
"live"
:
case
'live'
:
href
=
(
<
a
target=
'_blank'
rel=
'noopener noreferrer'
className=
'link-create-course'
href=
{
window
.
location
.
origin
+
window
.
location
.
pathname
+
"#/create-live-course?type=add"
}
href=
{
window
.
location
.
origin
+
window
.
location
.
pathname
+
'#/create-live-course?type=add'
}
onClick=
{
this
.
props
.
onClose
}
>
没有找到需要的直播课?
<
span
>
去创建
</
span
>
</
a
>
)
break
case
"video"
:
)
;
break
;
case
'video'
:
href
=
(
<
a
target=
'_blank'
rel=
'noopener noreferrer'
className=
'link-create-course'
href=
{
window
.
location
.
origin
+
window
.
location
.
pathname
+
"#/create-video-course?type=add"
}
href=
{
window
.
location
.
origin
+
window
.
location
.
pathname
+
'#/create-video-course?type=add'
}
onClick=
{
this
.
props
.
onClose
}
>
没有找到需要的视频课?
<
span
>
去创建
</
span
>
</
a
>
)
break
case
"picture"
:
)
;
break
;
case
'picture'
:
href
=
(
<
a
target=
'_blank'
rel=
'noopener noreferrer'
className=
'link-create-course'
href=
{
window
.
location
.
origin
+
window
.
location
.
pathname
+
"#/create-graphics-course?type=add"
}
href=
{
window
.
location
.
origin
+
window
.
location
.
pathname
+
'#/create-graphics-course?type=add'
}
onClick=
{
this
.
props
.
onClose
}
>
没有找到需要的图文课?
<
span
>
去创建
</
span
>
</
a
>
)
break
)
;
break
;
default
:
break
}
return
href
break
;
}
return
href
;
};
render
()
{
const
{
visible
}
=
this
.
props
const
{
visible
}
=
this
.
props
;
const
{
liveDataSource
,
liveSize
,
...
...
@@ -632,8 +659,8 @@ class SelectOperatorModal extends React.Component {
pictureQuery
,
pictureTotalCount
,
videoCourseDivision
}
=
this
.
state
videoCourseDivision
,
}
=
this
.
state
;
return
(
<
Modal
title=
'关联课程'
...
...
@@ -649,7 +676,7 @@ class SelectOperatorModal extends React.Component {
this.renderFooter(),
<
Button
onClick=
{
()
=>
{
this
.
props
.
onClose
()
this
.
props
.
onClose
()
;
}
}
>
取消
</
Button
>
,
...
...
@@ -660,18 +687,18 @@ class SelectOperatorModal extends React.Component {
...
this
.
handleSelectVideo
(
selectVideo
.
internal
),
...
this
.
handleSelectVideo
(
selectVideo
.
external
),
...
this
.
handleSelectLive
(
selectLive
),
...
this
.
handleSelectPicture
(
selectPicture
)
...
this
.
handleSelectPicture
(
selectPicture
)
,
])
}
>
确定
</
Button
>
</
Button
>
,
]
}
>
<
div
>
<
Tabs
type=
'line'
defaultActiveKey=
'live'
onChange=
{
(
activeKey
)
=>
{
this
.
setState
({
activeKey
:
activeKey
})
this
.
setState
({
activeKey
:
activeKey
})
;
}
}
>
<
TabPane
tab=
'直播课'
key=
'live'
>
<
div
className=
'search-container'
>
...
...
@@ -680,10 +707,10 @@ class SelectOperatorModal extends React.Component {
placeholder=
'搜索课程名称'
style=
{
{
width
:
200
}
}
onChange=
{
(
e
)
=>
{
this
.
handleChangLiveCourseName
(
e
.
target
.
value
)
this
.
handleChangLiveCourseName
(
e
.
target
.
value
)
;
}
}
onSearch=
{
()
=>
{
this
.
handleFetchLiveDataList
()
this
.
handleFetchLiveDataList
()
;
}
}
/>
</
div
>
...
...
@@ -707,32 +734,36 @@ class SelectOperatorModal extends React.Component {
</
div
>
</
div
>
<
div
>
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
liveCourseId
}
dataSource=
{
liveDataSource
}
columns=
{
this
.
parseLiveColumns
()
}
pagination=
{
false
}
bordered
rowSelection=
{
{
type
:
"checkbox"
,
selectedRowKeys
:
_
.
pluck
(
selectLive
,
"liveCourseId"
),
type
:
'checkbox'
,
selectedRowKeys
:
_
.
pluck
(
selectLive
,
'liveCourseId'
),
onSelect
:
(
record
,
selected
)
=>
{
this
.
selectLiveList
(
record
,
selected
)
this
.
selectLiveList
(
record
,
selected
)
;
},
onSelectAll
:
(
selected
,
_selectedRows
,
changeRows
)
=>
{
let
_list
=
[]
let
_list
=
[]
;
if
(
selected
)
{
_list
=
_
.
uniq
(
selectLive
.
concat
(
changeRows
),
false
,
(
item
)
=>
item
.
liveCourseId
)
_list
=
_
.
uniq
(
selectLive
.
concat
(
changeRows
),
false
,
(
item
)
=>
item
.
liveCourseId
)
;
}
else
{
_list
=
_
.
reject
(
selectLive
,
(
item
)
=>
_
.
find
(
changeRows
,
(
data
)
=>
data
.
liveCourseId
===
item
.
liveCourseId
))
_list
=
_
.
reject
(
selectLive
,
(
item
)
=>
_
.
find
(
changeRows
,
(
data
)
=>
data
.
liveCourseId
===
item
.
liveCourseId
))
;
}
if
(
_list
.
length
+
currentTaskCourseData
.
length
+
selectVideo
.
length
+
selectPicture
.
length
>
20
)
{
message
.
warning
(
"无法继续选择,一个任务最多关联20个课程"
)
const
extraLength
=
_list
.
length
+
currentTaskCourseData
.
length
+
selectVideo
.
length
+
selectPicture
.
length
-
20
_list
.
splice
(
_list
.
length
-
extraLength
,
extraLength
)
}
this
.
setState
({
selectLive
:
_list
})
message
.
warning
(
'无法继续选择,一个任务最多关联20个课程'
);
const
extraLength
=
_list
.
length
+
currentTaskCourseData
.
length
+
selectVideo
.
length
+
selectPicture
.
length
-
20
;
_list
.
splice
(
_list
.
length
-
extraLength
,
extraLength
);
}
this
.
setState
({
selectLive
:
_list
});
},
}
}
/>
{
liveDataSource
.
length
>
0
&&
(
...
...
@@ -743,15 +774,15 @@ class SelectOperatorModal extends React.Component {
size=
'small'
total=
{
liveTotalCount
}
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
liveQuery
,
current
:
page
+
1
}
const
_query
=
{
...
liveQuery
,
current
:
page
+
1
}
;
this
.
setState
(
{
liveQuery
:
_query
liveQuery
:
_query
,
},
()
=>
{
this
.
handleFetchLiveDataList
()
this
.
handleFetchLiveDataList
()
;
}
)
)
;
}
}
onShowSizeChange=
{
this
.
onShowLiveSizeChange
}
/>
...
...
@@ -772,10 +803,10 @@ class SelectOperatorModal extends React.Component {
placeholder=
'搜索课程名称'
style=
{
{
width
:
200
}
}
onChange=
{
(
e
)
=>
{
this
.
handleChangVideoCourseName
(
e
.
target
.
value
)
this
.
handleChangVideoCourseName
(
e
.
target
.
value
)
;
}
}
onSearch=
{
()
=>
{
this
.
handleFetchVideoDataList
()
this
.
handleFetchVideoDataList
()
;
}
}
/>
</
div
>
...
...
@@ -798,37 +829,41 @@ class SelectOperatorModal extends React.Component {
</
div
>
</
div
>
<
div
>
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
id
}
dataSource=
{
videoDataSource
[
videoCourseDivision
]
}
columns=
{
this
.
parseVideoColumns
()
}
pagination=
{
false
}
bordered
rowSelection=
{
{
type
:
"checkbox"
,
selectedRowKeys
:
_
.
pluck
(
selectVideo
[
videoCourseDivision
],
"id"
),
type
:
'checkbox'
,
selectedRowKeys
:
_
.
pluck
(
selectVideo
[
videoCourseDivision
],
'id'
),
onSelect
:
(
record
,
selected
)
=>
{
this
.
selectVideoList
(
record
,
selected
)
this
.
selectVideoList
(
record
,
selected
)
;
},
onSelectAll
:
(
selected
,
_selectedRows
,
changeRows
)
=>
{
let
_list
=
[]
let
_list
=
[]
;
if
(
selected
)
{
_list
=
_
.
uniq
(
selectVideo
[
videoCourseDivision
].
concat
(
changeRows
),
false
,
(
item
)
=>
item
.
id
)
_list
=
_
.
uniq
(
selectVideo
[
videoCourseDivision
].
concat
(
changeRows
),
false
,
(
item
)
=>
item
.
id
)
;
}
else
{
_list
=
_
.
reject
(
selectVideo
[
videoCourseDivision
],
(
item
)
=>
_
.
find
(
changeRows
,
(
data
)
=>
data
.
id
===
item
.
id
))
_list
=
_
.
reject
(
selectVideo
[
videoCourseDivision
],
(
item
)
=>
_
.
find
(
changeRows
,
(
data
)
=>
data
.
id
===
item
.
id
))
;
}
if
(
_list
.
length
+
currentTaskCourseData
.
length
+
selectLive
.
length
+
selectPicture
.
length
>
20
)
{
message
.
warning
(
"无法继续选择,一个任务最多关联20个课程"
)
const
extraLength
=
_list
.
length
+
currentTaskCourseData
.
length
+
selectLive
.
length
+
selectPicture
.
length
-
20
_list
.
splice
(
_list
.
length
-
extraLength
,
extraLength
)
message
.
warning
(
'无法继续选择,一个任务最多关联20个课程'
);
const
extraLength
=
_list
.
length
+
currentTaskCourseData
.
length
+
selectLive
.
length
+
selectPicture
.
length
-
20
;
_list
.
splice
(
_list
.
length
-
extraLength
,
extraLength
)
;
}
this
.
setState
({
selectVideo
:
{
...
selectVideo
,
[
videoCourseDivision
]:
_list
}
})
}
[
videoCourseDivision
]:
_list
,
}
,
})
;
}
,
}
}
/>
{
videoDataSource
[
videoCourseDivision
].
length
>
0
&&
(
...
...
@@ -839,19 +874,19 @@ class SelectOperatorModal extends React.Component {
size=
'small'
total=
{
videoTotalCount
[
videoCourseDivision
]
}
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
videoQuery
[
videoCourseDivision
],
current
:
page
+
1
}
const
_query
=
{
...
videoQuery
[
videoCourseDivision
],
current
:
page
+
1
}
;
this
.
setState
(
{
videoQuery
:
{
...
videoQuery
,
[
videoCourseDivision
]:
_query
}
[
videoCourseDivision
]:
_query
,
}
,
},
()
=>
{
this
.
handleFetchVideoDataList
()
this
.
handleFetchVideoDataList
()
;
}
)
)
;
}
}
onShowSizeChange=
{
this
.
onShowVideoSizeChange
}
/>
...
...
@@ -866,10 +901,10 @@ class SelectOperatorModal extends React.Component {
placeholder=
'搜索课程名称'
style=
{
{
width
:
200
}
}
onChange=
{
(
e
)
=>
{
this
.
handleChangPictureCourseName
(
e
.
target
.
value
)
this
.
handleChangPictureCourseName
(
e
.
target
.
value
)
;
}
}
onSearch=
{
()
=>
{
this
.
handleFetchPictureDataList
()
this
.
handleFetchPictureDataList
()
;
}
}
/>
</
div
>
...
...
@@ -893,32 +928,36 @@ class SelectOperatorModal extends React.Component {
</
div
>
</
div
>
<
div
>
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
,
}
}
rowKey=
{
(
record
)
=>
record
.
id
}
dataSource=
{
pictureDataSource
}
columns=
{
this
.
parsePictureColumns
()
}
pagination=
{
false
}
bordered
rowSelection=
{
{
type
:
"checkbox"
,
selectedRowKeys
:
_
.
pluck
(
selectPicture
,
"id"
),
type
:
'checkbox'
,
selectedRowKeys
:
_
.
pluck
(
selectPicture
,
'id'
),
onSelect
:
(
record
,
selected
)
=>
{
this
.
selectPictureList
(
record
,
selected
)
this
.
selectPictureList
(
record
,
selected
)
;
},
onSelectAll
:
(
selected
,
_selectedRows
,
changeRows
)
=>
{
let
_list
=
[]
let
_list
=
[]
;
if
(
selected
)
{
_list
=
_
.
uniq
(
selectPicture
.
concat
(
changeRows
),
false
,
(
item
)
=>
item
.
id
)
_list
=
_
.
uniq
(
selectPicture
.
concat
(
changeRows
),
false
,
(
item
)
=>
item
.
id
)
;
}
else
{
_list
=
_
.
reject
(
selectPicture
,
(
item
)
=>
_
.
find
(
changeRows
,
(
data
)
=>
data
.
id
===
item
.
id
))
_list
=
_
.
reject
(
selectPicture
,
(
item
)
=>
_
.
find
(
changeRows
,
(
data
)
=>
data
.
id
===
item
.
id
))
;
}
if
(
_list
.
length
+
currentTaskCourseData
.
length
+
selectVideo
.
length
+
selectLive
.
length
>
20
)
{
message
.
warning
(
"无法继续选择,一个任务最多关联20个课程"
)
const
extraLength
=
_list
.
length
+
currentTaskCourseData
.
length
+
selectVideo
.
length
+
selectLive
.
length
-
20
_list
.
splice
(
_list
.
length
-
extraLength
,
extraLength
)
}
this
.
setState
({
selectPicture
:
_list
})
message
.
warning
(
'无法继续选择,一个任务最多关联20个课程'
);
const
extraLength
=
_list
.
length
+
currentTaskCourseData
.
length
+
selectVideo
.
length
+
selectLive
.
length
-
20
;
_list
.
splice
(
_list
.
length
-
extraLength
,
extraLength
);
}
this
.
setState
({
selectPicture
:
_list
});
},
}
}
/>
{
pictureDataSource
.
length
>
0
&&
(
...
...
@@ -929,15 +968,15 @@ class SelectOperatorModal extends React.Component {
size=
'small'
total=
{
pictureTotalCount
}
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
pictureQuery
,
current
:
page
+
1
}
const
_query
=
{
...
pictureQuery
,
current
:
page
+
1
}
;
this
.
setState
(
{
pictureQuery
:
_query
pictureQuery
:
_query
,
},
()
=>
{
this
.
handleFetchPictureDataList
()
this
.
handleFetchPictureDataList
()
;
}
)
)
;
}
}
onShowSizeChange=
{
this
.
onShowPictureSizeChange
}
/>
...
...
@@ -948,8 +987,8 @@ class SelectOperatorModal extends React.Component {
</
Tabs
>
</
div
>
</
Modal
>
)
)
;
}
}
export
default
SelectOperatorModal
export
default
SelectOperatorModal
;
src/modules/teach-tool/examination-manager/ExamData.tsx
View file @
4de4930c
import
React
,
{
useState
,
useRef
,
useEffect
,
useContext
}
from
'react'
import
Service
from
"@/common/js/service"
;
import
{
PageControl
}
from
"@/components"
;
import
React
,
{
useState
,
useRef
,
useEffect
,
useContext
}
from
'react'
;
import
Service
from
'@/common/js/service'
;
import
{
PageControl
}
from
'@/components'
;
import
{
Input
,
Select
,
Tooltip
,
Button
,
Table
}
from
'antd'
;
import
User
from
"@/common/js/user"
;
import
User
from
'@/common/js/user'
;
import
moment
from
'moment'
;
import
'./userData.less'
import
'./userData.less'
;
const
{
Search
}
=
Input
;
const
{
Option
}
=
Select
;
interface
sortType
{
type
:
"ascend"
|
"descend"
|
null
|
undefined
type
:
'ascend'
|
'descend'
|
null
|
undefined
;
}
function
ExamData
(
props
:
any
)
{
const
sortStatus
:
sortType
=
{
type
:
undefined
}
type
:
undefined
,
};
const
examDataInit
:
any
=
{};
const
queryInit
:
any
=
{
current
:
1
,
size
:
10
,
order
:
'SORT_ASC'
};
...
...
@@ -28,165 +27,152 @@ function ExamData(props: any) {
const
[
allData
,
setAllData
]
=
useState
(
0
);
const
[
order
,
setOrder
]
=
useState
(
sortStatus
.
type
);
const
questionTypeList
=
{
SINGLE_CHOICE
:
"单选题"
,
MULTI_CHOICE
:
"多选题"
,
JUDGE
:
"判断题"
,
GAP_FILLING
:
"填空题"
,
INDEFINITE_CHOICE
:
"不定项选择题"
,
SINGLE_CHOICE
:
'单选题'
,
MULTI_CHOICE
:
'多选题'
,
JUDGE
:
'判断题'
,
GAP_FILLING
:
'填空题'
,
INDEFINITE_CHOICE
:
'不定项选择题'
,
};
const
userTypeEnum
=
{
WORK_WE_CHAT
:
'企业微信'
,
WE_CHAT
:
'微信'
}
WE_CHAT
:
'微信'
,
};
const
userExamStateEnum
=
{
EXAM
:
'进行中'
,
LACK_EXAM
:
'缺考'
,
FINISH_EXAM
:
'已考试'
}
FINISH_EXAM
:
'已考试'
,
};
const
orderEnum
=
{
currentAccuracy
:
{
ascend
:
'ACCURACY_ASC'
,
descend
:
'ACCURACY_DESC'
descend
:
'ACCURACY_DESC'
,
},
}
};
const
queryRef
=
useRef
({});
useEffect
(()
=>
{
queryExamUserData
();
},
[])
},
[]);
useEffect
(()
=>
{
queryRef
.
current
=
query
;
queryExamUserDataList
();
},
[
query
])
},
[
query
]);
function
queryExamUserData
()
{
Service
.
Hades
(
'public/hades/queryExamQuestionData'
,
{
examId
:
props
.
examId
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
source
:
0
,
}).
then
((
res
)
=>
{
setUserData
(
res
.
result
)
})
setUserData
(
res
.
result
);
});
}
function
queryExamUserDataList
()
{
Service
.
Hades
(
'public/hades/queryExamQuestionDataList'
,
{
...
query
,
examId
:
props
.
examId
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
source
:
0
,
}).
then
((
res
)
=>
{
setList
(
res
.
result
.
records
);
setTotal
(
parseInt
(
res
.
result
.
total
))
setTotal
(
parseInt
(
res
.
result
.
total
));
if
(
!
allData
)
{
setAllData
(
parseInt
(
res
.
result
.
total
))
setAllData
(
parseInt
(
res
.
result
.
total
));
}
})
});
}
const
columns
=
[
{
title
:
"序号"
,
dataIndex
:
"sort"
,
title
:
'序号'
,
dataIndex
:
'sort'
,
width
:
60
,
render
:
(
text
:
any
)
=>
<
span
>
{
text
+
1
}
</
span
>,
render
:
(
text
:
any
,
record
:
any
,
index
:
any
)
=>
<
span
>
{
index
+
1
}
</
span
>,
},
{
title
:
"题目"
,
dataIndex
:
"questionStem"
,
title
:
'题目'
,
dataIndex
:
'questionStem'
,
ellipsis
:
true
,
width
:
350
,
render
:
(
val
:
any
)
=>
{
var
handleVal
=
val
;
handleVal
=
handleVal
.
replace
(
/<
(?!
img|input
)
.*
?
>/g
,
""
);
handleVal
=
handleVal
.
replace
(
/<
\s?
input
[^
>
]
*>/gi
,
"_、"
);
handleVal
=
handleVal
.
replace
(
/
\&
nbsp
\;
/gi
,
" "
);
handleVal
=
handleVal
.
replace
(
/<
(?!
img|input
)
.*
?
>/g
,
''
);
handleVal
=
handleVal
.
replace
(
/<
\s?
input
[^
>
]
*>/gi
,
'_、'
);
handleVal
=
handleVal
.
replace
(
/
\&
nbsp
\;
/gi
,
' '
);
return
(
<
Tooltip
overlayClassName=
"aid-tool-list"
title=
{
<
div
style=
{
{
maxWidth
:
700
,
width
:
"auto"
}
}
>
{
handleVal
}
</
div
>
}
placement=
"topLeft"
overlayStyle=
{
{
maxWidth
:
700
}
}
>
overlayClassName=
'aid-tool-list'
title=
{
<
div
style=
{
{
maxWidth
:
700
,
width
:
'auto'
}
}
>
{
handleVal
}
</
div
>
}
placement=
'topLeft'
overlayStyle=
{
{
maxWidth
:
700
}
}
>
{
handleVal
}
</
Tooltip
>
);
},
},
{
title
:
"题型"
,
dataIndex
:
"questionType"
,
title
:
'题型'
,
dataIndex
:
'questionType'
,
render
:
(
text
:
any
)
=>
<
span
>
{
(
questionTypeList
as
any
)[
text
]
}
</
span
>,
filters
:
Object
.
keys
(
questionTypeList
).
map
((
key
)
=>
{
return
{
text
:
(
questionTypeList
as
any
)[
key
],
value
:
key
}
value
:
key
,
};
}),
},
{
title
:
"本次正确率"
,
dataIndex
:
"currentAccuracy"
,
title
:
'本次正确率'
,
dataIndex
:
'currentAccuracy'
,
sorter
:
true
,
sortOrder
:
field
===
"currentAccuracy"
?
order
:
sortStatus
.
type
,
render
:
(
text
:
any
)
=>
<
span
>
{
parseInt
(
text
*
100
as
any
)
}
%
</
span
>,
sortOrder
:
field
===
'currentAccuracy'
?
order
:
sortStatus
.
type
,
render
:
(
text
:
any
)
=>
<
span
>
{
parseInt
((
text
*
100
)
as
any
)
}
%
</
span
>,
},
{
title
:
<
div
>
历史正确率
<
Tooltip
overlayClassName=
"tool-list"
title=
'包含本次考试正确率'
placement=
"top"
overlayStyle=
{
{
maxWidth
:
700
}
}
>
<
span
style=
{
{
color
:
'rgba(191, 191, 191, 1)'
}
}
className=
"icon iconfont"
>

</
span
>
title
:
(
<
div
>
历史正确率
{
' '
}
<
Tooltip
overlayClassName=
'tool-list'
title=
'包含本次考试正确率'
placement=
'top'
overlayStyle=
{
{
maxWidth
:
700
}
}
>
{
' '
}
<
span
style=
{
{
color
:
'rgba(191, 191, 191, 1)'
}
}
className=
'icon iconfont'
>

</
span
>
</
Tooltip
>
</
div
>,
dataIndex
:
"totalAccuracy"
,
render
:
(
text
:
any
)
=>
<
span
>
{
parseInt
(
text
*
100
as
any
)
}
%
</
span
>
,
</
div
>
)
,
dataIndex
:
'totalAccuracy'
,
render
:
(
text
:
any
)
=>
<
span
>
{
parseInt
((
text
*
100
)
as
any
)
}
%
</
span
>,
},
];
function
onChange
(
pagination
:
any
,
filters
:
any
,
sorter
:
any
,
extra
:
any
)
{
console
.
log
(
filters
,
sorter
);
setfield
(
sorter
.
field
);
setOrder
(
sorter
.
order
)
console
.
log
(
sorter
.
field
,
sorter
.
order
,
(
orderEnum
as
any
)[
sorter
.
field
])
setOrder
(
sorter
.
order
);
console
.
log
(
sorter
.
field
,
sorter
.
order
,
(
orderEnum
as
any
)[
sorter
.
field
]);
let
_query
:
any
=
{
...
queryRef
.
current
};
console
.
log
(
filters
.
questionType
)
console
.
log
(
filters
.
questionType
);
if
(
filters
.
questionType
)
{
console
.
log
(
233232
)
console
.
log
(
233232
);
_query
.
questionType
=
filters
.
questionType
;
_query
.
current
=
1
;
}
else
{
delete
_query
.
questionType
delete
_query
.
questionType
;
}
_query
.
order
=
(
orderEnum
as
any
)[
sorter
.
field
][
sorter
.
order
]
setQuery
(
_query
)
_query
.
order
=
(
orderEnum
as
any
)[
sorter
.
field
][
sorter
.
order
];
setQuery
(
_query
);
}
function
download
()
{
Service
.
Hades
(
'public/hades/exportExamData'
,
{
// ...query,
...
...
@@ -194,103 +180,102 @@ function ExamData(props: any) {
exportDataType
:
'EXAM_QUESTION_DATA'
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
source
:
0
,
}).
then
((
res
)
=>
{
const
dom
=
(
document
as
any
).
getElementById
(
"load-play-back-excel"
)
const
dom
=
(
document
as
any
).
getElementById
(
'load-play-back-excel'
);
dom
.
setAttribute
(
'href'
,
res
.
result
);
dom
.
click
();
})
});
}
return
<
div
className=
"rr"
>
<
a
download
id=
"load-play-back-excel"
style=
{
{
position
:
"absolute"
,
left
:
"-10000px"
}
}
></
a
>
<
div
className=
"dataPanal"
>
{
!!
examData
.
singleChoiceCnt
&&
<
div
className=
"item"
>
<
div
className=
"num"
>
{
Math
.
round
((
examData
.
singleChoiceAccuracy
||
0
)
*
100
)
}
%
</
div
>
<
div
className=
"percent"
>
正确率
</
div
>
<
div
className=
"subTitle"
><
div
className=
"type"
><
span
className=
"icon iconfont"
>

</
span
>
单选题
<
span
>
(共
{
examData
.
singleChoiceCnt
}
题)
</
span
></
div
></
div
>
return
(
<
div
className=
'rr'
>
<
a
download
id=
'load-play-back-excel'
style=
{
{
position
:
'absolute'
,
left
:
'-10000px'
}
}
></
a
>
<
div
className=
'dataPanal'
>
{
!!
examData
.
singleChoiceCnt
&&
(
<
div
className=
'item'
>
<
div
className=
'num'
>
{
Math
.
round
((
examData
.
singleChoiceAccuracy
||
0
)
*
100
)
}
%
</
div
>
<
div
className=
'percent'
>
正确率
</
div
>
<
div
className=
'subTitle'
>
<
div
className=
'type'
>
<
span
className=
'icon iconfont'
>

</
span
>
单选题
<
span
>
(共
{
examData
.
singleChoiceCnt
}
题)
</
span
>
</
div
>
}
{
!!
examData
.
multiChoiceCnt
&&
<
div
className=
"item"
>
<
div
className=
"num"
>
{
Math
.
round
((
examData
.
multiChoiceAccuracy
||
0
)
*
100
)
}
%
</
div
>
<
div
className=
"percent"
>
正确率
</
div
>
<
div
className=
"subTitle"
><
div
className=
"type"
><
span
className=
"icon iconfont"
>

</
span
>
多选题
<
span
>
(共
{
examData
.
multiChoiceCnt
}
题)
</
span
></
div
></
div
>
</
div
>
}
{
!!
examData
.
judgeCnt
&&
<
div
className=
"item"
>
<
div
className=
"num"
>
{
Math
.
round
((
examData
.
judgeAccuracy
||
0
)
*
100
)
}
%
</
div
>
<
div
className=
"percent"
>
正确率
</
div
>
<
div
className=
"subTitle"
><
div
className=
"type"
><
span
className=
"icon iconfont"
>

</
span
>
判断题
<
span
>
(共
{
examData
.
judgeCnt
}
题)
</
span
></
div
></
div
>
</
div
>
}
{
!!
examData
.
gapFillingCnt
&&
<
div
className=
"item"
>
<
div
className=
"num"
>
{
Math
.
round
((
examData
.
gapFillingAccuracy
||
0
)
*
100
)
}
%
</
div
>
<
div
className=
"percent"
>
正确率
</
div
>
<
div
className=
"subTitle"
><
div
className=
"type"
><
span
className=
"icon iconfont"
>

</
span
>
填空题
<
span
>
(共
{
examData
.
gapFillingCnt
}
题)
</
span
></
div
></
div
>
)
}
{
!!
examData
.
multiChoiceCnt
&&
(
<
div
className=
'item'
>
<
div
className=
'num'
>
{
Math
.
round
((
examData
.
multiChoiceAccuracy
||
0
)
*
100
)
}
%
</
div
>
<
div
className=
'percent'
>
正确率
</
div
>
<
div
className=
'subTitle'
>
<
div
className=
'type'
>
<
span
className=
'icon iconfont'
>

</
span
>
多选题
<
span
>
(共
{
examData
.
multiChoiceCnt
}
题)
</
span
>
</
div
>
}
{
!!
examData
.
indefiniteChoiceCnt
&&
<
div
className=
"item"
>
<
div
className=
"num"
>
{
Math
.
round
((
examData
.
indefiniteChoiceAccuracy
||
0
)
*
100
)
}
%
</
div
>
<
div
className=
"percent"
>
正确率
</
div
>
<
div
className=
"subTitle"
><
div
className=
"type"
><
span
className=
"icon iconfont"
>

</
span
>
不定项选择题
<
span
>
(共
{
examData
.
indefiniteChoiceCnt
}
题)
</
span
></
div
></
div
>
</
div
>
}
</
div
>
{
!!
allData
&&
<
Button
style=
{
{
marginBottom
:
12
,
marginTop
:
12
}
}
onClick=
{
download
}
>
导出
</
Button
>
}
<
div
className=
"content"
>
<
Table
bordered
size=
"small"
columns=
{
columns
}
dataSource=
{
list
}
onChange=
{
onChange
}
pagination=
{
false
}
>
</
Table
>
{
total
>
0
&&
)
}
{
!!
examData
.
judgeCnt
&&
(
<
div
className=
'item'
>
<
div
className=
'num'
>
{
Math
.
round
((
examData
.
judgeAccuracy
||
0
)
*
100
)
}
%
</
div
>
<
div
className=
'percent'
>
正确率
</
div
>
<
div
className=
'subTitle'
>
<
div
className=
'type'
>
<
span
className=
'icon iconfont'
>

</
span
>
判断题
<
span
>
(共
{
examData
.
judgeCnt
}
题)
</
span
>
</
div
>
</
div
>
</
div
>
)
}
{
!!
examData
.
gapFillingCnt
&&
(
<
div
className=
'item'
>
<
div
className=
'num'
>
{
Math
.
round
((
examData
.
gapFillingAccuracy
||
0
)
*
100
)
}
%
</
div
>
<
div
className=
'percent'
>
正确率
</
div
>
<
div
className=
'subTitle'
>
<
div
className=
'type'
>
<
span
className=
'icon iconfont'
>

</
span
>
填空题
<
span
>
(共
{
examData
.
gapFillingCnt
}
题)
</
span
>
</
div
>
</
div
>
</
div
>
)
}
{
!!
examData
.
indefiniteChoiceCnt
&&
(
<
div
className=
'item'
>
<
div
className=
'num'
>
{
Math
.
round
((
examData
.
indefiniteChoiceAccuracy
||
0
)
*
100
)
}
%
</
div
>
<
div
className=
'percent'
>
正确率
</
div
>
<
div
className=
'subTitle'
>
<
div
className=
'type'
>
<
span
className=
'icon iconfont'
>

</
span
>
不定项选择题
<
span
>
(共
{
examData
.
indefiniteChoiceCnt
}
题)
</
span
>
</
div
>
</
div
>
</
div
>
)
}
</
div
>
{
!!
allData
&&
(
<
Button
style=
{
{
marginBottom
:
12
,
marginTop
:
12
}
}
onClick=
{
download
}
>
导出
</
Button
>
)
}
<
div
className=
'content'
>
<
Table
bordered
size=
'small'
columns=
{
columns
}
dataSource=
{
list
}
onChange=
{
onChange
}
pagination=
{
false
}
></
Table
>
{
total
>
0
&&
(
<
PageControl
size=
"small"
size=
'small'
current=
{
query
.
current
-
1
}
pageSize=
{
query
.
size
}
total=
{
total
}
toPage=
{
(
page
:
any
)
=>
{
console
.
log
(
page
)
console
.
log
(
page
);
let
_query
:
any
=
{
...
queryRef
.
current
};
_query
.
current
=
page
+
1
;
setQuery
(
_query
)
setQuery
(
_query
);
}
}
/>
}
)
}
</
div
>
</
div
>
);
}
export
default
ExamData
;
src/modules/teach-tool/paper-manage/OperatePaper.jsx
View file @
4de4930c
/*
* @Author: yuananting
* @Date: 2021-03-27 16:15:13
* @LastEditors:
yuananti
ng
* @LastEditTime: 2021-0
6-10 19:57:55
* @LastEditors:
fusanqias
ng
* @LastEditTime: 2021-0
7-01 16:30:38
* @Description: 助学工具-新建/复制/编辑试卷
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import
React
,
{
Component
}
from
"react"
;
import
{
Form
,
Button
,
Input
,
Table
,
InputNumber
,
ConfigProvider
,
Empty
,
Tooltip
,
message
,
Modal
,
Spin
,
Space
,
Radio
,
}
from
"antd"
;
import
{
PlusOutlined
}
from
"@ant-design/icons"
;
import
{
XMTable
}
from
"@/components"
;
import
ShowTips
from
"@/components/ShowTips"
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
"./OperatePaper.less"
;
import
SelectQuestionModal
from
"./modal/SelectQuestionModal"
;
import
PaperPreviewModal
from
"./modal/PreviewPaperModal"
;
import
User
from
"@/common/js/user"
;
import
AidToolService
from
"@/domains/aid-tool-domain/AidToolService"
;
import
Bus
from
"@/core/bus"
;
import
_
from
"underscore"
;
import
{
Route
,
withRouter
}
from
"react-router-dom"
;
import
React
,
{
Component
}
from
'react'
;
import
{
Form
,
Button
,
Input
,
Table
,
InputNumber
,
ConfigProvider
,
Empty
,
Tooltip
,
message
,
Modal
,
Spin
,
Space
,
Radio
}
from
'antd'
;
import
{
PlusOutlined
}
from
'@ant-design/icons'
;
import
{
XMTable
}
from
'@/components'
;
import
ShowTips
from
'@/components/ShowTips'
;
import
Breadcrumbs
from
'@/components/Breadcrumbs'
;
import
'./OperatePaper.less'
;
import
SelectQuestionModal
from
'./modal/SelectQuestionModal'
;
import
PaperPreviewModal
from
'./modal/PreviewPaperModal'
;
import
User
from
'@/common/js/user'
;
import
AidToolService
from
'@/domains/aid-tool-domain/AidToolService'
;
import
Bus
from
'@/core/bus'
;
import
_
from
'underscore'
;
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
*
as
paperEmpty
from
'../../lottie/paperEmpty/data.json'
;
import
AddExam
from
"@/modules/teach-tool/examination-manager/AddExam"
;
import
AddExam
from
'@/modules/teach-tool/examination-manager/AddExam'
;
const
questionTypeEnum
=
{
SINGLE_CHOICE
:
"单选题"
,
MULTI_CHOICE
:
"多选题"
,
JUDGE
:
"判断题"
,
GAP_FILLING
:
"填空题"
,
INDEFINITE_CHOICE
:
"不定项选择题"
,
SINGLE_CHOICE
:
'单选题'
,
MULTI_CHOICE
:
'多选题'
,
JUDGE
:
'判断题'
,
GAP_FILLING
:
'填空题'
,
INDEFINITE_CHOICE
:
'不定项选择题'
,
};
class
OperatePaper
extends
Component
{
formRef
=
React
.
createRef
();
...
...
@@ -50,7 +36,7 @@ class OperatePaper extends Component {
super
(
props
);
this
.
state
=
{
formData
:
{
categoryId
:
getParameterByName
(
"categoryId"
),
// 分类ID
categoryId
:
getParameterByName
(
'categoryId'
),
// 分类ID
singleChoiceCnt
:
0
,
// 单选题数量
multiChoiceCnt
:
0
,
// 多选题数量
judgeCnt
:
0
,
// 判断题数量
...
...
@@ -75,34 +61,28 @@ class OperatePaper extends Component {
paperPreviewModal
:
null
,
quickSortModalVisible
:
false
,
// 快捷排序弹窗显隐
selectQuestionList
:
[],
currentOperate
:
""
,
currentNav
:
""
,
currentOperate
:
''
,
currentNav
:
''
,
currentCategoryPapers
:
[],
loading
:
false
,
check
:
false
,
sorterMethod
:
"addOrder"
,
sorterBy
:
[
"SINGLE_CHOICE"
,
"MULTI_CHOICE"
,
"JUDGE"
,
"GAP_FILLING"
,
"INDEFINITE_CHOICE"
,
],
sorterMethod
:
'addOrder'
,
sorterBy
:
[
'SINGLE_CHOICE'
,
'MULTI_CHOICE'
,
'JUDGE'
,
'GAP_FILLING'
,
'INDEFINITE_CHOICE'
],
sorterTypeList
:
[
{
typeKey
:
"SINGLE_CHOICE"
,
typeKey
:
'SINGLE_CHOICE'
,
},
{
typeKey
:
"MULTI_CHOICE"
,
typeKey
:
'MULTI_CHOICE'
,
},
{
typeKey
:
"JUDGE"
,
typeKey
:
'JUDGE'
,
},
{
typeKey
:
"GAP_FILLING"
,
typeKey
:
'GAP_FILLING'
,
},
{
typeKey
:
"INDEFINITE_CHOICE"
,
typeKey
:
'INDEFINITE_CHOICE'
,
},
],
};
...
...
@@ -110,30 +90,26 @@ class OperatePaper extends Component {
componentDidMount
()
{
this
.
queryCurrentCategoryPapers
();
switch
(
getParameterByName
(
"type"
))
{
case
"new"
:
this
.
setState
({
currentOperate
:
"new"
,
currentNav
:
"新建试卷"
});
switch
(
getParameterByName
(
'type'
))
{
case
'new'
:
this
.
setState
({
currentOperate
:
'new'
,
currentNav
:
'新建试卷'
});
break
;
case
"edit"
:
this
.
setState
({
currentOperate
:
"edit"
,
currentNav
:
"编辑试卷"
},
()
=>
this
.
queryPaperDetail
()
);
case
'edit'
:
this
.
setState
({
currentOperate
:
'edit'
,
currentNav
:
'编辑试卷'
},
()
=>
this
.
queryPaperDetail
(
'edit'
));
break
;
case
"copy"
:
this
.
setState
({
currentOperate
:
"copy"
,
currentNav
:
"复制试卷"
},
()
=>
this
.
queryPaperDetail
()
);
case
'copy'
:
this
.
setState
({
currentOperate
:
'copy'
,
currentNav
:
'复制试卷'
},
()
=>
this
.
queryPaperDetail
(
'copy'
));
break
;
}
}
// 获取当前分类下的所有试卷
queryCurrentCategoryPapers
=
()
=>
{
const
categoryId
=
getParameterByName
(
"categoryId"
);
const
categoryId
=
getParameterByName
(
'categoryId'
);
let
params
=
{
current
:
1
,
size
:
9999
,
categoryId
:
categoryId
===
"null"
?
null
:
categoryId
,
categoryId
:
categoryId
===
'null'
?
null
:
categoryId
,
paperName
:
null
,
// 试卷名称
source
:
0
,
tenantId
:
User
.
getStoreId
(),
...
...
@@ -146,14 +122,15 @@ class OperatePaper extends Component {
};
// 编辑/复制试卷时获取相应试卷详情
queryPaperDetail
=
async
()
=>
{
queryPaperDetail
=
async
(
flag
)
=>
{
this
.
setState
({
loading
:
true
});
const
{
currentOperate
}
=
this
.
state
;
let
query
=
{
paperId
:
getParameterByName
(
"paperId"
),
paperId
:
getParameterByName
(
'paperId'
),
source
:
0
,
userId
:
User
.
getStoreUserId
(),
tenantId
:
User
.
getStoreId
(),
flag
:
flag
===
'copy'
,
};
const
res
=
await
AidToolService
.
queryPaperDetail
(
query
);
const
{
result
}
=
res
;
...
...
@@ -163,9 +140,8 @@ class OperatePaper extends Component {
selectQuestionList
:
questionList
,
formData
:
{
...
result
,
paperId
:
getParameterByName
(
"paperId"
),
paperName
:
currentOperate
===
"copy"
?
paperName
+
"(复制)"
:
paperName
,
paperId
:
getParameterByName
(
'paperId'
),
paperName
:
currentOperate
===
'copy'
?
paperName
+
'(复制)'
:
paperName
,
},
loading
:
false
,
},
...
...
@@ -188,26 +164,11 @@ class OperatePaper extends Component {
const
_selectQuestionList
=
[...
list
];
// 各类型题目汇总
const
singleQuestion
=
_
.
filter
(
_selectQuestionList
,
(
item
)
=>
item
.
questionType
===
"SINGLE_CHOICE"
);
const
multiQuestion
=
_
.
filter
(
_selectQuestionList
,
(
item
)
=>
item
.
questionType
===
"MULTI_CHOICE"
);
const
judgeQuestion
=
_
.
filter
(
_selectQuestionList
,
(
item
)
=>
item
.
questionType
===
"JUDGE"
);
const
gapQuestion
=
_
.
filter
(
_selectQuestionList
,
(
item
)
=>
item
.
questionType
===
"GAP_FILLING"
);
const
indefiniteQuestion
=
_
.
filter
(
_selectQuestionList
,
(
item
)
=>
item
.
questionType
===
"INDEFINITE_CHOICE"
);
const
singleQuestion
=
_
.
filter
(
_selectQuestionList
,
(
item
)
=>
item
.
questionType
===
'SINGLE_CHOICE'
);
const
multiQuestion
=
_
.
filter
(
_selectQuestionList
,
(
item
)
=>
item
.
questionType
===
'MULTI_CHOICE'
);
const
judgeQuestion
=
_
.
filter
(
_selectQuestionList
,
(
item
)
=>
item
.
questionType
===
'JUDGE'
);
const
gapQuestion
=
_
.
filter
(
_selectQuestionList
,
(
item
)
=>
item
.
questionType
===
'GAP_FILLING'
);
const
indefiniteQuestion
=
_
.
filter
(
_selectQuestionList
,
(
item
)
=>
item
.
questionType
===
'INDEFINITE_CHOICE'
);
// 各类型题目总分值
const
singleChoiceScore
=
singleQuestion
.
reduce
((
prev
,
cur
)
=>
{
...
...
@@ -277,9 +238,7 @@ class OperatePaper extends Component {
const
selectQuestionList
=
[...
this
.
state
.
selectQuestionList
];
const
item
=
selectQuestionList
.
splice
(
index
+
moveLength
,
1
);
selectQuestionList
.
splice
(
index
,
0
,
item
[
0
]);
this
.
setState
({
selectQuestionList
},
()
=>
this
.
setFormData
(
this
.
state
.
selectQuestionList
)
);
this
.
setState
({
selectQuestionList
},
()
=>
this
.
setFormData
(
this
.
state
.
selectQuestionList
));
};
// 移除已选题目
...
...
@@ -287,9 +246,7 @@ class OperatePaper extends Component {
const
{
selectQuestionList
}
=
this
.
state
;
this
.
setState
(
{
selectQuestionList
:
[...
selectQuestionList
].
filter
(
(
item
)
=>
item
.
questionId
!==
delQuestionId
),
selectQuestionList
:
[...
selectQuestionList
].
filter
((
item
)
=>
item
.
questionId
!==
delQuestionId
),
},
()
=>
this
.
setFormData
(
this
.
state
.
selectQuestionList
)
);
...
...
@@ -303,15 +260,12 @@ class OperatePaper extends Component {
if
(
result
!=
null
)
{
return
result
;
}
if
([
"new"
,
"copy"
].
includes
(
currentOperate
))
{
if
([
'new'
,
'copy'
].
includes
(
currentOperate
))
{
if
(
item
.
paperName
===
paperName
)
{
result
=
item
;
}
}
else
if
(
currentOperate
===
"edit"
)
{
if
(
item
.
paperName
===
paperName
&&
item
.
paperId
!==
getParameterByName
(
"paperId"
)
)
{
}
else
if
(
currentOperate
===
'edit'
)
{
if
(
item
.
paperName
===
paperName
&&
item
.
paperId
!==
getParameterByName
(
'paperId'
))
{
result
=
item
;
}
}
...
...
@@ -321,15 +275,15 @@ class OperatePaper extends Component {
validatePaperName
=
(
paperName
)
=>
{
if
(
this
.
state
.
check
&&
!
paperName
)
{
return
"请输入试卷名称"
;
return
'请输入试卷名称'
;
}
if
(
this
.
checkExist
(
paperName
))
{
return
"该试卷名称已存在"
;
return
'该试卷名称已存在'
;
}
if
(
paperName
&&
paperName
.
length
>
40
)
{
return
"试卷名称最多40字"
;
return
'试卷名称最多40字'
;
}
};
...
...
@@ -337,19 +291,14 @@ class OperatePaper extends Component {
savePaper
=
(
saveType
)
=>
{
this
.
setState
({
check
:
true
});
const
{
selectQuestionList
,
formData
,
currentOperate
}
=
this
.
state
;
const
categoryId
=
getParameterByName
(
"categoryId"
);
const
categoryId
=
getParameterByName
(
'categoryId'
);
const
{
match
}
=
this
.
props
;
let
questionList
=
[];
if
(
!
formData
.
passRate
||
!
formData
.
paperName
||
this
.
checkExist
(
formData
.
paperName
)
||
(
formData
.
paperName
&&
formData
.
paperName
.
length
>
40
)
)
{
if
(
!
formData
.
passRate
||
!
formData
.
paperName
||
this
.
checkExist
(
formData
.
paperName
)
||
(
formData
.
paperName
&&
formData
.
paperName
.
length
>
40
))
{
return
;
}
if
(
selectQuestionList
.
length
===
0
)
{
return
message
.
warning
(
"请选择题目"
);
return
message
.
warning
(
'请选择题目'
);
}
selectQuestionList
.
forEach
((
item
,
index
)
=>
{
...
...
@@ -370,29 +319,23 @@ class OperatePaper extends Component {
},
},
()
=>
{
if
([
"new"
,
"copy"
].
includes
(
currentOperate
))
{
if
([
'new'
,
'copy'
].
includes
(
currentOperate
))
{
AidToolService
.
createPaper
(
this
.
state
.
formData
)
.
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
saveType
===
"saveToAddExam"
)
{
this
.
setState
({
formData
:{
...
formData
,
paperId
:
res
.
result
}},
()
=>
{
if
(
saveType
===
'saveToAddExam'
)
{
this
.
setState
({
formData
:
{
...
formData
,
paperId
:
res
.
result
}
},
()
=>
{
window
.
RCHistory
.
push
({
pathname
:
`
${
match
.
url
}
/exam-operate-page`
,
});
})
})
;
}
else
{
message
.
success
(
currentOperate
===
"new"
?
"新建成功"
:
"复制成功"
);
message
.
success
(
currentOperate
===
'new'
?
'新建成功'
:
'复制成功'
);
window
.
RCHistory
.
push
({
pathname
:
`/paper-manage-index?categoryId=
${
categoryId
}
`
,
});
Bus
.
trigger
(
"queryPaperPageList"
,
categoryId
,
selectQuestionList
.
length
);
Bus
.
trigger
(
"queryCategoryTree"
,
"remain"
);
Bus
.
trigger
(
'queryPaperPageList'
,
categoryId
,
selectQuestionList
.
length
);
Bus
.
trigger
(
'queryCategoryTree'
,
'remain'
);
}
}
})
...
...
@@ -400,34 +343,26 @@ class OperatePaper extends Component {
window
.
RCHistory
.
push
({
pathname
:
`/paper-manage-index?categoryId=
${
categoryId
}
`
,
});
Bus
.
trigger
(
"queryPaperPageList"
,
categoryId
,
selectQuestionList
.
length
);
Bus
.
trigger
(
"queryCategoryTree"
,
"remain"
);
Bus
.
trigger
(
'queryPaperPageList'
,
categoryId
,
selectQuestionList
.
length
);
Bus
.
trigger
(
'queryCategoryTree'
,
'remain'
);
});
}
else
if
(
currentOperate
===
"edit"
)
{
}
else
if
(
currentOperate
===
'edit'
)
{
AidToolService
.
editPaper
({
...
this
.
state
.
formData
,
paperId
:
getParameterByName
(
"paperId"
),
paperId
:
getParameterByName
(
'paperId'
),
})
.
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
saveType
===
"saveToAddExam"
)
{
if
(
saveType
===
'saveToAddExam'
)
{
window
.
RCHistory
.
push
({
pathname
:
`
${
match
.
url
}
/exam-operate-page`
,
});
}
else
{
message
.
success
(
"编辑成功"
);
message
.
success
(
'编辑成功'
);
window
.
RCHistory
.
push
({
pathname
:
`/paper-manage-index?categoryId=
${
categoryId
}
`
,
});
Bus
.
trigger
(
"queryPaperPageList"
,
categoryId
,
selectQuestionList
.
length
);
Bus
.
trigger
(
'queryPaperPageList'
,
categoryId
,
selectQuestionList
.
length
);
}
}
})
...
...
@@ -435,11 +370,7 @@ class OperatePaper extends Component {
window
.
RCHistory
.
push
({
pathname
:
`/paper-manage-index?categoryId=
${
categoryId
}
`
,
});
Bus
.
trigger
(
"queryPaperPageList"
,
categoryId
,
selectQuestionList
.
length
);
Bus
.
trigger
(
'queryPaperPageList'
,
categoryId
,
selectQuestionList
.
length
);
});
}
}
...
...
@@ -451,7 +382,7 @@ class OperatePaper extends Component {
const
{
selectQuestionList
,
formData
}
=
this
.
state
;
const
m
=
(
<
PaperPreviewModal
previewPage=
"paper-operate"
previewPage=
'paper-operate'
paperInfo=
{
{
...
formData
,
questionList
:
selectQuestionList
}
}
close=
{
()
=>
{
this
.
setState
({
...
...
@@ -466,21 +397,17 @@ class OperatePaper extends Component {
// 取消/返回
handleGoBack
=
()
=>
{
Modal
.
confirm
({
title
:
"确定要返回吗?"
,
content
:
"返回后,本次编辑的内容将不被保存"
,
okText
:
"确认返回"
,
cancelText
:
"留在本页"
,
icon
:
(
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>
),
title
:
'确定要返回吗?'
,
content
:
'返回后,本次编辑的内容将不被保存'
,
okText
:
'确认返回'
,
cancelText
:
'留在本页'
,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
onOk
:
()
=>
{
window
.
RCHistory
.
push
({
pathname
:
`/paper-manage-index?categoryId=
${
getParameterByName
(
"categoryId"
)}
`
,
pathname
:
`/paper-manage-index?categoryId=
${
getParameterByName
(
'categoryId'
)}
`
,
});
Bus
.
trigger
(
"queryCategoryTree"
,
"remain"
);
Bus
.
trigger
(
"queryPaperPageList"
,
getParameterByName
(
"categoryId"
),
0
);
Bus
.
trigger
(
'queryCategoryTree'
,
'remain'
);
Bus
.
trigger
(
'queryPaperPageList'
,
getParameterByName
(
'categoryId'
),
0
);
},
});
};
...
...
@@ -490,39 +417,39 @@ class OperatePaper extends Component {
const
{
selectQuestionList
}
=
this
.
state
;
const
columns
=
[
{
title
:
"序号"
,
dataIndex
:
"index"
,
key
:
"index"
,
width
:
"10%"
,
title
:
'序号'
,
dataIndex
:
'index'
,
key
:
'index'
,
width
:
'10%'
,
render
:
(
val
,
record
,
index
)
=>
{
return
<
span
>
{
index
+
1
}
</
span
>;
},
},
{
title
:
"题型"
,
dataIndex
:
"questionType"
,
key
:
"questionType"
,
width
:
"12%"
,
title
:
'题型'
,
dataIndex
:
'questionType'
,
key
:
'questionType'
,
width
:
'12%'
,
filters
:
[
{
text
:
"单选题"
,
value
:
"SINGLE_CHOICE"
,
text
:
'单选题'
,
value
:
'SINGLE_CHOICE'
,
},
{
text
:
"多选题"
,
value
:
"MULTI_CHOICE"
,
text
:
'多选题'
,
value
:
'MULTI_CHOICE'
,
},
{
text
:
"判断题"
,
value
:
"JUDGE"
,
text
:
'判断题'
,
value
:
'JUDGE'
,
},
{
text
:
"填空题"
,
value
:
"GAP_FILLING"
,
text
:
'填空题'
,
value
:
'GAP_FILLING'
,
},
{
text
:
"不定项选择题"
,
value
:
"INDEFINITE_CHOICE"
,
text
:
'不定项选择题'
,
value
:
'INDEFINITE_CHOICE'
,
},
],
filterMultiple
:
true
,
...
...
@@ -530,26 +457,23 @@ class OperatePaper extends Component {
render
:
(
val
)
=>
questionTypeEnum
[
val
],
},
{
title
:
"题目"
,
dataIndex
:
"questionStem"
,
key
:
"questionStem"
,
title
:
'题目'
,
dataIndex
:
'questionStem'
,
key
:
'questionStem'
,
ellipsis
:
{
showTitle
:
false
,
},
render
:
(
val
)
=>
{
var
handleVal
=
val
;
handleVal
=
handleVal
.
replace
(
/<
(?!
img|input
)
.*
?
>/g
,
""
);
handleVal
=
handleVal
.
replace
(
/<
\s?
input
[^
>
]
*>/gi
,
"_、"
);
handleVal
=
handleVal
.
replace
(
/
\&
nbsp
\;
/gi
,
" "
);
handleVal
=
handleVal
.
replace
(
/<
(?!
img|input
)
.*
?
>/g
,
''
);
handleVal
=
handleVal
.
replace
(
/<
\s?
input
[^
>
]
*>/gi
,
'_、'
);
handleVal
=
handleVal
.
replace
(
/
\&
nbsp
\;
/gi
,
' '
);
return
(
<
Tooltip
overlayClassName=
"aid-tool-list"
title=
{
<
div
style=
{
{
maxWidth
:
700
,
width
:
"auto"
}
}
>
{
handleVal
}
</
div
>
}
placement=
"topLeft"
overlayStyle=
{
{
maxWidth
:
700
}
}
>
overlayClassName=
'aid-tool-list'
title=
{
<
div
style=
{
{
maxWidth
:
700
,
width
:
'auto'
}
}
>
{
handleVal
}
</
div
>
}
placement=
'topLeft'
overlayStyle=
{
{
maxWidth
:
700
}
}
>
{
handleVal
}
</
Tooltip
>
);
...
...
@@ -558,20 +482,17 @@ class OperatePaper extends Component {
{
title
:
(
<
span
>
分值
{
" "
}
<
Tooltip
title=
"多选题和填空题的漏选/半对得分不能高于题目本身分值"
>
<
span
className=
"icon iconfont"
style=
{
{
color
:
"#BFBFBF"
,
fontSize
:
14
,
fontWeight
:
"400"
}
}
>
分值
{
' '
}
<
Tooltip
title=
'多选题和填空题的漏选/半对得分不能高于题目本身分值'
>
<
span
className=
'icon iconfont'
style=
{
{
color
:
'#BFBFBF'
,
fontSize
:
14
,
fontWeight
:
'400'
}
}
>

</
span
>
</
Tooltip
>
</
span
>
),
dataIndex
:
"score"
,
key
:
"score"
,
width
:
"12%"
,
dataIndex
:
'score'
,
key
:
'score'
,
width
:
'12%'
,
render
:
(
val
,
record
,
index
)
=>
{
return
(
<
InputNumber
...
...
@@ -582,11 +503,7 @@ class OperatePaper extends Component {
const
_selectQuestionList
=
[...
selectQuestionList
];
this
.
setState
(
{
selectQuestionList
:
_selectQuestionList
.
map
((
item
)
=>
item
.
questionId
===
record
.
questionId
?
{
...
item
,
score
:
value
}
:
item
),
selectQuestionList
:
_selectQuestionList
.
map
((
item
)
=>
(
item
.
questionId
===
record
.
questionId
?
{
...
item
,
score
:
value
}
:
item
)),
},
()
=>
this
.
setFormData
(
this
.
state
.
selectQuestionList
)
);
...
...
@@ -596,20 +513,14 @@ class OperatePaper extends Component {
},
},
{
dataIndex
:
"portionScore"
,
key
:
"portionScore"
,
width
:
"18%"
,
dataIndex
:
'portionScore'
,
key
:
'portionScore'
,
width
:
'18%'
,
render
:
(
val
,
record
,
index
)
=>
{
return
(
[
"MULTI_CHOICE"
,
"GAP_FILLING"
,
"INDEFINITE_CHOICE"
].
includes
(
record
.
questionType
)
&&
(
[
'MULTI_CHOICE'
,
'GAP_FILLING'
,
'INDEFINITE_CHOICE'
].
includes
(
record
.
questionType
)
&&
(
<
div
>
{
record
.
questionType
===
"GAP_FILLING"
?
(
<
span
>
半对得
</
span
>
)
:
(
<
span
>
漏选得
</
span
>
)
}{
" "
}
{
record
.
questionType
===
'GAP_FILLING'
?
<
span
>
半对得
</
span
>
:
<
span
>
漏选得
</
span
>
}{
' '
}
<
InputNumber
min=
{
0
}
max=
{
record
.
score
-
1
}
...
...
@@ -619,9 +530,7 @@ class OperatePaper extends Component {
this
.
setState
(
{
selectQuestionList
:
_selectQuestionList
.
map
((
item
)
=>
item
.
questionId
===
record
.
questionId
?
{
...
item
,
portionScore
:
value
}
:
item
item
.
questionId
===
record
.
questionId
?
{
...
item
,
portionScore
:
value
}
:
item
),
},
()
=>
this
.
setFormData
(
this
.
state
.
selectQuestionList
)
...
...
@@ -634,43 +543,34 @@ class OperatePaper extends Component {
},
},
{
title
:
"操作"
,
dataIndex
:
"operate"
,
key
:
"operate"
,
width
:
"16%"
,
title
:
'操作'
,
dataIndex
:
'operate'
,
key
:
'operate'
,
width
:
'16%'
,
render
:
(
val
,
record
,
index
)
=>
{
return
(
<
div
className=
"record-operate"
>
<
div
className=
'record-operate'
>
<
div
className=
{
index
>
0
?
"record-operate__item"
:
"record-operate__ban"
}
className=
{
index
>
0
?
'record-operate__item'
:
'record-operate__ban'
}
onClick=
{
()
=>
{
this
.
handleMoveItem
(
index
,
-
1
);
}
}
>
}
}
>
上移
</
div
>
<
span
className=
"record-operate__item split"
>
|
</
span
>
<
span
className=
'record-operate__item split'
>
|
</
span
>
<
div
className=
{
index
<
selectQuestionList
.
length
-
1
?
"record-operate__item"
:
"record-operate__ban"
}
className=
{
index
<
selectQuestionList
.
length
-
1
?
'record-operate__item'
:
'record-operate__ban'
}
onClick=
{
()
=>
{
this
.
handleMoveItem
(
index
,
1
);
}
}
>
}
}
>
下移
</
div
>
<
span
className=
"record-operate__item split"
>
|
</
span
>
<
span
className=
'record-operate__item split'
>
|
</
span
>
<
div
className=
"record-operate__item"
className=
'record-operate__item'
onClick=
{
()
=>
{
this
.
handleDelItem
(
record
.
questionId
);
}
}
>
}
}
>
移除
</
div
>
</
div
>
...
...
@@ -686,7 +586,7 @@ class OperatePaper extends Component {
const
sorterTypeList
=
[...
this
.
state
.
sorterTypeList
];
const
item
=
sorterTypeList
.
splice
(
index
+
moveLength
,
1
);
sorterTypeList
.
splice
(
index
,
0
,
item
[
0
]);
const
sorterBy
=
_
.
pluck
(
sorterTypeList
,
"typeKey"
);
const
sorterBy
=
_
.
pluck
(
sorterTypeList
,
'typeKey'
);
this
.
setState
({
sorterTypeList
,
sorterBy
});
};
...
...
@@ -694,13 +594,9 @@ class OperatePaper extends Component {
quickSorter
=
(
list
,
sorterMethod
,
sorterBy
)
=>
{
this
.
setState
({
selectQuestionList
:
sorterMethod
===
"addOrder"
sorterMethod
===
'addOrder'
?
list
.
sort
((
a
,
b
)
=>
a
.
sorterIndex
-
b
.
sorterIndex
)
:
list
.
sort
(
(
a
,
b
)
=>
sorterBy
.
indexOf
(
a
.
questionTypeEnum
||
a
.
questionType
)
-
sorterBy
.
indexOf
(
b
.
questionTypeEnum
||
b
.
questionType
)
),
:
list
.
sort
((
a
,
b
)
=>
sorterBy
.
indexOf
(
a
.
questionTypeEnum
||
a
.
questionType
)
-
sorterBy
.
indexOf
(
b
.
questionTypeEnum
||
b
.
questionType
)),
});
};
...
...
@@ -739,41 +635,39 @@ class OperatePaper extends Component {
const
selectQuestionList
=
[...
this
.
state
.
selectQuestionList
];
const
questionTypeEnum
=
{
SINGLE_CHOICE
:
"【单选题】"
,
MULTI_CHOICE
:
"【多选题】"
,
JUDGE
:
"【判断题】"
,
GAP_FILLING
:
"【填空题】"
,
INDEFINITE_CHOICE
:
"【不定项选择题】"
,
SINGLE_CHOICE
:
'【单选题】'
,
MULTI_CHOICE
:
'【多选题】'
,
JUDGE
:
'【判断题】'
,
GAP_FILLING
:
'【填空题】'
,
INDEFINITE_CHOICE
:
'【不定项选择题】'
,
};
const
typeColumns
=
[
{
title
:
"题型"
,
dataIndex
:
"typeKey"
,
key
:
"typeKey"
,
render
:
(
text
,
record
,
index
)
=>
<
span
style=
{
{
color
:
'#333333'
}
}
>
{
questionTypeEnum
[
text
]
}
</
span
>,
title
:
'题型'
,
dataIndex
:
'typeKey'
,
key
:
'typeKey'
,
render
:
(
text
,
record
,
index
)
=>
<
span
style=
{
{
color
:
'#333333'
}
}
>
{
questionTypeEnum
[
text
]
}
</
span
>,
},
{
title
:
"操作"
,
key
:
"action"
,
title
:
'操作'
,
key
:
'action'
,
align
:
'right'
,
render
:
(
text
,
record
,
index
)
=>
(
<
Space
size=
"middle"
>
<
Space
size=
'middle'
>
<
span
style=
{
{
color
:
index
>
0
?
'#2966FF'
:
'#CCCCCC'
,
cursor
:
'pointer'
}
}
style=
{
{
color
:
index
>
0
?
'#2966FF'
:
'#CCCCCC'
,
cursor
:
'pointer'
}
}
onClick=
{
()
=>
{
index
>
0
&&
this
.
handleMoveTypeSorter
(
index
,
-
1
);
}
}
>
}
}
>
上移
</
span
>
<
span
style=
{
{
color
:
'#BFBFBF'
}
}
>
|
</
span
>
<
span
style=
{
{
color
:
'#BFBFBF'
}
}
>
|
</
span
>
<
span
style=
{
{
color
:
index
<
4
?
'#2966FF'
:
'#CCCCCC'
,
cursor
:
'pointer'
}
}
style=
{
{
color
:
index
<
4
?
'#2966FF'
:
'#CCCCCC'
,
cursor
:
'pointer'
}
}
onClick=
{
()
=>
{
index
<
4
&&
this
.
handleMoveTypeSorter
(
index
,
1
);
}
}
>
}
}
>
下移
</
span
>
</
Space
>
...
...
@@ -782,32 +676,26 @@ class OperatePaper extends Component {
];
return
(
<
div
>
<
div
className=
"page operate-paper-page"
>
<
Breadcrumbs
navList=
{
currentNav
}
goBack=
{
()
=>
this
.
handleGoBack
()
}
/>
<
div
className=
'page operate-paper-page'
>
<
Breadcrumbs
navList=
{
currentNav
}
goBack=
{
()
=>
this
.
handleGoBack
()
}
/>
<
Spin
spinning=
{
loading
}
>
<
div
className=
"box"
>
<
div
className=
"show-tips"
>
<
ShowTips
message=
"请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利"
/>
<
div
className=
'box'
>
<
div
className=
'show-tips'
>
<
ShowTips
message=
'请遵守国家相关规定,切勿上传低俗色情、暴力恐怖、谣言诈骗、侵权盗版等相关内容,小麦企学院保有依据国家规定及平台规则进行处理的权利'
/>
</
div
>
<
Form
ref=
{
this
.
formRef
}
style=
{
{
marginTop
:
24
}
}
>
<
Form
.
Item
name=
"paperName"
label=
"试卷名称:"
name=
'paperName'
label=
'试卷名称:'
required
validateStatus=
{
this
.
validatePaperName
(
paperName
)
?
"error"
:
""
}
help=
{
this
.
validatePaperName
(
paperName
)
}
>
validateStatus=
{
this
.
validatePaperName
(
paperName
)
?
'error'
:
''
}
help=
{
this
.
validatePaperName
(
paperName
)
}
>
<
Input
value=
{
paperName
}
autoComplete=
"off"
autoComplete=
'off'
maxLength=
{
40
}
style=
{
{
width
:
300
}
}
placeholder=
"请输入试卷名称(40字以内)"
placeholder=
'请输入试卷名称(40字以内)'
onChange=
{
(
e
)
=>
{
this
.
setState
({
formData
:
{
...
...
@@ -820,12 +708,11 @@ class OperatePaper extends Component {
</
Form
.
Item
>
<
Form
.
Item
name=
"passRate"
label=
"及格线:"
name=
'passRate'
label=
'及格线:'
required
validateStatus=
{
check
&&
!
passRate
?
"error"
:
""
}
help=
{
check
&&
!
passRate
&&
"请输入及格线"
}
>
validateStatus=
{
check
&&
!
passRate
?
'error'
:
''
}
help=
{
check
&&
!
passRate
&&
'请输入及格线'
}
>
<
div
>
<
InputNumber
min=
{
1
}
...
...
@@ -842,9 +729,9 @@ class OperatePaper extends Component {
()
=>
this
.
setFormData
(
selectQuestionList
)
);
}
}
/>
{
" "
}
/>
{
' '
}
%
<
span
className=
"score-info"
>
<
span
className=
'score-info'
>
总分(
{
Number
(
totalScore
)
||
0
}
)*及格线(
{
Number
(
passRate
)
||
0
}
%)=及格分数(
...
...
@@ -853,47 +740,33 @@ class OperatePaper extends Component {
</
div
>
</
Form
.
Item
>
<
Space
size=
{
8
}
>
<
Button
className=
"choose-btn"
type=
"primary"
icon=
{
<
PlusOutlined
/>
}
onClick=
{
this
.
chooseQuestion
}
>
<
Button
className=
'choose-btn'
type=
'primary'
icon=
{
<
PlusOutlined
/>
}
onClick=
{
this
.
chooseQuestion
}
>
自选题目
</
Button
>
<
Button
className=
"choose-btn"
className=
'choose-btn'
onClick=
{
()
=>
{
this
.
setState
({
quickSortModalVisible
:
true
,
});
}
}
>
}
}
>
快捷排序
</
Button
>
</
Space
>
{
questionCnt
>
0
&&
(
<
div
className=
"paper-info-tip"
style=
{
{
margin
:
"0 auto 12px"
}
}
>
<
div
className=
'paper-info-tip'
style=
{
{
margin
:
'0 auto 12px'
}
}
>
总计
<
span
>
{
totalScore
}
</
span
>
分,共
<
span
>
{
questionCnt
}
</
span
>
题。
{
" "
}
{
singleChoiceCnt
>
0
&&
`单选题${singleChoiceCnt}题,共${singleChoiceScore}分;`
}
{
multiChoiceCnt
>
0
&&
`多选题${multiChoiceCnt}题,共${multiChoiceScore}分;`
}
题。
{
singleChoiceCnt
>
0
&&
`单选题${singleChoiceCnt}题,共${singleChoiceScore}分;`
}
{
multiChoiceCnt
>
0
&&
`多选题${multiChoiceCnt}题,共${multiChoiceScore}分;`
}
{
judgeCnt
>
0
&&
`判断题${judgeCnt}题,共${judgeScore}分,`
}
{
gapFillingCnt
>
0
&&
`填空题${gapFillingCnt}题,共${gapFillingScore}分,`
}
{
indefiniteChoiceCnt
>
0
&&
`不定项选择题${indefiniteChoiceCnt}题,共${indefiniteChoiceScore}分`
}
{
gapFillingCnt
>
0
&&
`填空题${gapFillingCnt}题,共${gapFillingScore}分,`
}
{
indefiniteChoiceCnt
>
0
&&
`不定项选择题${indefiniteChoiceCnt}题,共${indefiniteChoiceScore}分`
}
</
div
>
)
}
<
XMTable
className=
"table-style"
className=
'table-style'
scroll=
{
{
y
:
350
}
}
columns=
{
this
.
parseColumns
()
}
dataSource=
{
selectQuestionList
}
...
...
@@ -901,18 +774,16 @@ class OperatePaper extends Component {
onChange=
{
this
.
sortByQuestionType
}
renderEmpty=
{
{
image
:
paperEmpty
,
description
:
<
span
style=
{
{
display
:
'block'
,
paddingBottom
:
24
}
}
>
请在左上角添加题目
</
span
>
description
:
<
span
style=
{
{
display
:
'block'
,
paddingBottom
:
24
}
}
>
请在左上角添加题目
</
span
>
,
}
}
/>
</
Form
>
</
div
>
<
div
className=
"footer"
>
<
div
className=
'footer'
>
<
Button
onClick=
{
this
.
handleGoBack
}
>
取消
</
Button
>
<
Button
onClick=
{
this
.
previewPaper
}
>
预览
</
Button
>
<
Button
onClick=
{
()
=>
this
.
savePaper
(
"saveToAddExam"
)
}
>
保存并组织考试
</
Button
>
<
Button
type=
"primary"
onClick=
{
()
=>
this
.
savePaper
()
}
>
<
Button
onClick=
{
()
=>
this
.
savePaper
(
'saveToAddExam'
)
}
>
保存并组织考试
</
Button
>
<
Button
type=
'primary'
onClick=
{
()
=>
this
.
savePaper
()
}
>
保存
</
Button
>
</
div
>
...
...
@@ -921,8 +792,8 @@ class OperatePaper extends Component {
{
paperPreviewModal
}
<
Modal
maskClosable=
{
false
}
className=
"type-order-modal"
title=
"快捷排序"
className=
'type-order-modal'
title=
'快捷排序'
width=
{
560
}
visible=
{
quickSortModalVisible
}
onOk=
{
()
=>
{
...
...
@@ -935,23 +806,21 @@ class OperatePaper extends Component {
}
}
onCancel=
{
()
=>
{
this
.
setState
({
quickSortModalVisible
:
false
});
}
}
>
}
}
>
<
Radio
.
Group
onChange=
{
(
e
)
=>
this
.
setState
({
sorterMethod
:
e
.
target
.
value
,
})
}
value=
{
sorterMethod
}
>
<
Radio
value=
{
"addOrder"
}
>
按添加顺序排序
</
Radio
>
<
Radio
value=
{
"typeOrder"
}
>
按题型排序
</
Radio
>
value=
{
sorterMethod
}
>
<
Radio
value=
{
'addOrder'
}
>
按添加顺序排序
</
Radio
>
<
Radio
value=
{
'typeOrder'
}
>
按题型排序
</
Radio
>
</
Radio
.
Group
>
{
sorterMethod
===
"typeOrder"
&&
(
{
sorterMethod
===
'typeOrder'
&&
(
<
Table
className=
"type-order-table"
style=
{
{
marginTop
:
'24px'
}
}
className=
'type-order-table'
style=
{
{
marginTop
:
'24px'
}
}
showHeader=
{
false
}
columns=
{
typeColumns
}
dataSource=
{
sorterTypeList
}
...
...
@@ -964,16 +833,7 @@ class OperatePaper extends Component {
<
Route
path=
{
`${match.url}/exam-operate-page`
}
render=
{
()
=>
{
return
(
<
AddExam
paperInfo=
{
formData
}
type=
{
currentOperate
===
"edit"
?
"editPaperToAddExam"
:
"newPaperToAddExam"
}
/>
);
return
<
AddExam
paperInfo=
{
formData
}
type=
{
currentOperate
===
'edit'
?
'editPaperToAddExam'
:
'newPaperToAddExam'
}
/>;
}
}
/>
</
div
>
...
...
src/modules/teach-tool/paper-manage/OperatePaper.less
View file @
4de4930c
...
...
@@ -6,6 +6,7 @@
}
.table-style {
border: 1px solid #f0f0f0 !important;
margin-bottom: 70px;
}
.ant-tabs {
color: #666666;
...
...
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