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
b23fca45
Commit
b23fca45
authored
Jul 01, 2021
by
guomingpang
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'master' of
ssh://xmgit.ixm5.cn:10022/xiaomai-cloud-class/xiaomai-cloud-class-web
parents
f803fff4
2c1b9ce7
Show whitespace changes
Inline
Side-by-side
Showing
20 changed files
with
1663 additions
and
2361 deletions
+1663
-2361
src/bu-components/PreviewFileModal.jsx
+0
-0
src/bu-components/PreviewFileModal.less
+0
-0
src/data-source/aidTool/request-apis.ts
+2
-2
src/data-source/base/request-apis.ts
+14
-3
src/domains/basic-domain/baseService.ts
+18
-4
src/domains/basic-domain/constants.ts
+6
-1
src/index.tsx
+24
-3
src/modules/course-manage/components/LiveCourseList.jsx
+468
-431
src/modules/course-manage/modal/ManageCoursewareModal.jsx
+68
-24
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/prepare-lesson/components/FolderList.jsx
+0
-703
src/modules/prepare-lesson/components/FolderManage.jsx
+0
-22
src/modules/resource-disk/components/FolderList.jsx
+34
-61
src/modules/root/Login.jsx
+0
-17
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/resource-disk/modal
/PreviewFileModal.jsx
→
src/
bu-components
/PreviewFileModal.jsx
View file @
b23fca45
File moved
src/
modules/resource-disk/modal
/PreviewFileModal.less
→
src/
bu-components
/PreviewFileModal.less
View file @
b23fca45
File moved
src/data-source/aidTool/request-apis.ts
View file @
b23fca45
/*
* @Author: yuananting
* @Date: 2021-03-03 15:13:12
* @LastEditors:
fusanqiasng
* @LastEditTime: 2021-06-
16 09:57:18
* @LastEditors:
Please set LastEditors
* @LastEditTime: 2021-06-
22 14:31:46
* @Description: 助学工具接口
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
...
...
src/data-source/base/request-apis.ts
View file @
b23fca45
/*
* @Author: wufan
* @Date: 2020-12-01 17:21:21
* @LastEditors:
zhangleyuan
* @LastEditTime: 2021-0
4-09 14:28:09
* @LastEditors:
Please set LastEditors
* @LastEditTime: 2021-0
6-22 14:56:34
* @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import
Service
from
"@/common/js/service"
;
import
axios
from
'axios'
;
export
function
sendLoginAuthCode
(
params
:
object
)
{
return
Service
.
Hades
(
"anon/hades/sendLoginAuthCode"
,
params
);
}
...
...
@@ -47,6 +47,16 @@ export function getEnterpriseUser(params: object) {
export
function
getWXWorkLoginNoCheck
(
params
:
object
)
{
return
Service
.
Hades
(
'anon/hades/getWXWorkLoginNoCheck'
,
params
);
}
export
function
getYoZoSign
(
params
:
object
)
{
return
Service
.
Apollo
(
'public/apollo/getYoZoSign'
,
params
);
}
export
function
saveYoZoFileVersionId
(
params
:
object
)
{
return
Service
.
Apollo
(
'public/apollo/saveYoZoFileVersionId'
,
params
);
}
export
function
yoZoUpload
(
ossUrl
:
String
,
appId
:
String
,
uploadSign
:
String
){
return
axios
.
post
(
`https://dmc.yozocloud.cn/api/file/http?fileUrl=
${
ossUrl
}
&appId=
${
appId
}
&sign=
${
uploadSign
}
`
)
}
export
const
getOssClient
=
(
data
:
object
,
instId
:
string
,
...
...
@@ -63,3 +73,4 @@ export const getOssClient = (
});
}
src/domains/basic-domain/baseService.ts
View file @
b23fca45
/*
* @Author: wufan
* @Date: 2020-12-01 17:20:49
* @LastEditors:
zhangleyuan
* @LastEditTime: 2021-0
4-09 14:28:59
* @LastEditors:
Please set LastEditors
* @LastEditTime: 2021-0
6-22 14:57:01
* @Description: Description
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import
{
getUserStore
,
getUserPermission
,
logout
,
getStoreUser
,
sendBizAuthCode
,
editUserPhone
,
checkBizAuthCode
,
sendNewPhoneAuthCode
,
sendLoginAuthCode
,
login
,
getLastedVersion
,
getEnterpriseUser
,
getWXWorkLoginNoCheck
}
from
'@/data-source/base/request-apis'
;
import
{
getUserStore
,
getUserPermission
,
logout
,
getStoreUser
,
sendBizAuthCode
,
editUserPhone
,
checkBizAuthCode
,
sendNewPhoneAuthCode
,
sendLoginAuthCode
,
login
,
getLastedVersion
,
getEnterpriseUser
,
getWXWorkLoginNoCheck
,
getYoZoSign
,
saveYoZoFileVersionId
,
yoZoUpload
}
from
'@/data-source/base/request-apis'
;
export
default
class
StoreService
{
// 获取员工列表
...
...
@@ -55,5 +55,18 @@ export default class StoreService {
static
getWXWorkLoginNoCheck
(
params
:
any
){
return
getWXWorkLoginNoCheck
(
params
);
}
static
getYoZoSign
(
params
:
any
){
return
new
Promise
((
resolve
)
=>
{
getYoZoSign
(
params
).
then
(
res
=>
{
const
{
result
=
[]
}
=
res
;
resolve
(
result
)
});
})
}
static
saveYoZoFileVersionId
(
params
:
any
){
return
saveYoZoFileVersionId
(
params
);
}
static
yoZoUpload
(
ossUrl
:
String
,
appId
:
String
,
uploadSign
:
String
){
return
yoZoUpload
(
ossUrl
,
appId
,
uploadSign
);
}
}
\ No newline at end of file
src/domains/basic-domain/constants.ts
View file @
b23fca45
/*
* @Author: 陈剑宇
* @Date: 2020-05-07 14:43:01
* @LastEditTime: 2021-06-
11 16:44:17
* @LastEditTime: 2021-06-
22 16:49:06
* @LastEditors: Please set LastEditors
* @Description:
* @FilePath: /wheat-web-demo/src/domains/basic-domain/constants.ts
...
...
@@ -26,6 +26,10 @@ const PATH_MAP: MapInterface = {
prod
:
'https://res.xiaomai0.com/xiaomai-cloud-class-web/h5.html'
,
}
export
const
YZ_APPId
=
"yozoqvpO2Hvz8346"
;
export
const
YZ_PREVIEW_URL
:
string
=
'http://eic.yozocloud.cn/api/view/file'
export
const
OFFICE_PREVIEW_URL
:
string
=
'https://view.officeapps.live.com/op/view.aspx'
// axios headers config
export
const
TIME_OUT
:
number
=
20000
export
const
USER_TYPE
:
string
=
'B'
...
...
@@ -37,3 +41,4 @@ export const USER_PREFIX = 'store-live'
// host
export
const
BASIC_HOST
:
string
=
BASIC_HOST_MAP
[
ENV
]
export
const
PATH
:
string
=
PATH_MAP
[
ENV
]
src/index.tsx
View file @
b23fca45
...
...
@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-04-27 20:35:34
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-06-2
3 14:14:20
* @LastEditTime: 2021-06-2
8 16:15:59
* @Description:
*/
...
...
@@ -21,6 +21,7 @@ import '@/core/function';
import
'@/core/xmTD'
;
import
User
from
'@/common/js/user'
;
import
Service
from
"@/common/js/service"
;
import
BaseService
from
'@/domains/basic-domain/baseService'
;
declare
var
getParameterByName
:
any
;
declare
var
window
:
any
;
...
...
@@ -71,7 +72,27 @@ if (getParameterByName('code') && isWeiXin()) {
window
.
currentStoreUserInfo
.
enterpriseId
=
res
.
result
.
enterpriseId
;
mount
()
})
}
else
{
}
else
if
(
getParameterByName
(
'from'
)
===
'customer'
&&
getParameterByName
(
'enterpriseId'
)
&&
getParameterByName
(
'userId'
)){
User
.
setCustomerStoreId
(
getParameterByName
(
'storeId'
));
getWXWorkLoginNoCheck
(
getParameterByName
(
'enterpriseId'
),
getParameterByName
(
'userId'
));
//从C端跳转过来的学院自动执行免登录
}
else
{
mount
()
}
function
getWXWorkLoginNoCheck
(
enterpriseId
:
string
,
userId
:
string
)
{
const
params
=
{
appTermEnum
:
'XIAOMAI_CLOUD_CLASS_PC_WEB_ADMIN'
,
enterpriseId
,
userId
,
};
BaseService
.
getWXWorkLoginNoCheck
(
params
).
then
((
res
:
any
)
=>
{
User
.
setUserId
(
res
.
result
.
loginInfo
.
userId
)
User
.
setToken
(
res
.
result
.
loginInfo
.
xmToken
)
User
.
setEnterpriseId
(
res
.
result
.
enterpriseId
)
window
.
currentStoreUserInfo
=
{}
window
.
currentStoreUserInfo
.
userId
=
res
.
result
.
loginInfo
.
userId
;
window
.
currentStoreUserInfo
.
token
=
res
.
result
.
loginInfo
.
xmToken
;
window
.
currentStoreUserInfo
.
enterpriseId
=
res
.
result
.
enterpriseId
;
User
.
setIdentifier
(
res
.
result
.
identifier
)
mount
();
});
}
src/modules/course-manage/components/LiveCourseList.jsx
View file @
b23fca45
...
...
@@ -7,47 +7,45 @@
*/
import
React
from
'react'
;
import
{
Table
,
Modal
,
message
,
Dropdown
,
Button
,
Switch
,
Tooltip
}
from
'antd'
;
import
{
Table
,
Modal
,
message
,
Dropdown
,
Switch
,
Tooltip
}
from
'antd'
;
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
{
PageControl
}
from
"@/components"
;
import
{
PageControl
}
from
'@/components'
;
import
DownloadLiveModal
from
'@/components/DownloadLiveModal'
;
import
ManageCoursewareModal
from
'../modal/ManageCoursewareModal'
;
import
ShareLiveModal
from
'../modal/ShareLiveModal'
;
import
RelatedPlanModal
from
'../modal/RelatedPlanModal'
;
import
'./LiveCourseList.less'
;
import
{
QuestionCircleOutlined
}
from
'@ant-design/icons'
;
import
{
appId
,
shareUrl
,
LIVE_SHARE
,
LIVE_REPLAY_MAP
}
from
'@/domains/course-domain/constants'
;
import
CourseService
from
"@/domains/course-domain/CourseService"
;
import
BaseService
from
"@/domains/basic-domain/baseService"
;
import
{
appId
,
LIVE_SHARE
}
from
'@/domains/course-domain/constants'
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
BaseService
from
'@/domains/basic-domain/baseService'
;
import
DataList
from
'../DataList/DataList'
;
import
User
from
'@/common/js/user'
;
import
_
from
"underscore"
;
import
_
from
'underscore'
;
const
{
confirm
}
=
Modal
;
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
LiveCourseList
extends
React
.
Component
{
...
...
@@ -55,18 +53,17 @@ class LiveCourseList extends React.Component {
super
(
props
);
this
.
state
=
{
columns
:
[],
openDownloadModal
:
false
,
url
:
''
,
RelatedPlanModalVisible
:
false
,
selectPlanList
:
{}
}
openDownloadModal
:
false
,
url
:
''
,
RelatedPlanModalVisible
:
false
,
selectPlanList
:
{},
}
;
}
componentWillMount
(){
componentWillMount
()
{
this
.
parseColumns
();
}
componentDidMount
()
{
this
.
getDownloadVersion
()
this
.
getDownloadVersion
()
;
}
// 显示分享弹窗
handleShowShareModal
=
(
item
,
needStr
=
false
)
=>
{
...
...
@@ -74,555 +71,596 @@ class LiveCourseList extends React.Component {
const
{
liveCourseId
}
=
item
;
const
htmlUrl
=
`
${
LIVE_SHARE
}
live_detail/
${
liveCourseId
}
?id=
${
User
.
getStoreId
()}
`
;
const
longUrl
=
htmlUrl
console
.
log
(
'htmlUrl'
,
htmlUrl
,
longUrl
);
const
longUrl
=
htmlUrl
;
console
.
log
(
'htmlUrl'
,
htmlUrl
,
longUrl
);
const
shareData
=
{
...
item
,
longUrl
};
const
shareLiveModal
=
(
<
ShareLiveModal
needStr=
{
needStr
}
data=
{
shareData
}
type=
"liveClass"
title=
"直播课"
type=
'liveClass'
title=
'直播课'
close=
{
()
=>
{
this
.
setState
({
shareLiveModal
:
null
shareLiveModal
:
null
,
});
localStorage
.
setItem
(
'largeLiveCourseItem'
,
''
);
}
}
/>
)
)
;
this
.
setState
({
shareLiveModal
})
}
this
.
setState
({
shareLiveModal
})
;
}
;
//改变上架状态
changeShelfState
=
(
item
)
=>
{
let
_shelfState
=
item
.
shelfState
if
(
_shelfState
===
'NO'
){
_shelfState
=
"YES"
;
item
.
shelfState
=
"YES"
}
else
{
_shelfState
=
"NO"
item
.
shelfState
=
"NO"
}
const
params
=
{
"liveCourseId"
:
item
.
liveCourseId
,
"shelfState"
:
_shelfState
}
CourseService
.
turnOnOrOffLiveCloudCourse
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
){
if
(
_shelfState
===
"YES"
){
message
.
success
(
"已开启展示"
);
}
else
{
message
.
success
(
"已取消展示"
);
changeShelfState
=
(
item
)
=>
{
let
_shelfState
=
item
.
shelfState
;
if
(
_shelfState
===
'NO'
)
{
_shelfState
=
'YES'
;
item
.
shelfState
=
'YES'
;
}
else
{
_shelfState
=
'NO'
;
item
.
shelfState
=
'NO'
;
}
const
params
=
{
liveCourseId
:
item
.
liveCourseId
,
shelfState
:
_shelfState
,
};
CourseService
.
turnOnOrOffLiveCloudCourse
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
_shelfState
===
'YES'
)
{
message
.
success
(
'已开启展示'
);
}
else
{
message
.
success
(
'已取消展示'
);
}
})
}
});
};
// 前往上课数据页面
handleLinkToClassData
=
(
item
)
=>
{
const
{
match
}
=
this
.
props
;
window
.
RCHistory
.
push
({
pathname
:
`
${
match
.
url
}
/live-course-data?type=large&id=
${
item
.
liveCourseId
}
`
pathname
:
`
${
match
.
url
}
/live-course-data?type=large&id=
${
item
.
liveCourseId
}
`
,
});
}
}
;
parseColumns
=
()
=>
{
const
menu
=
(
item
)
=>
(
<
div
className=
"live-course-more-menu"
>
<
div
>
上课记录
</
div
>
<
div
className=
'live-course-more-menu'
>
<
div
>
上课记录
</
div
>
<
div
onClick=
{
()
=>
{
this
.
handleShowRepeatModal
(
item
);
}
}
>
}
}
>
回放记录
</
div
>
</
div
>
);
let
columns
let
columns
;
const
userRole
=
User
.
getUserRole
();
if
(
userRole
!==
"CloudLecturer"
)
{
if
(
userRole
!==
'CloudLecturer'
)
{
columns
=
[
{
title
:
"直播课"
,
width
:
"23%"
,
key
:
"course"
,
dataIndex
:
"courseName"
,
title
:
'直播课'
,
width
:
'23%'
,
key
:
'course'
,
dataIndex
:
'courseName'
,
render
:
(
val
,
record
)
=>
{
let
hasCover
=
false
;
return
(
<
div
className=
"record__item"
>
{
record
.
courseMediaVOS
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentType
===
"COVER"
){
<
div
className=
'record__item'
>
{
record
.
courseMediaVOS
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentType
===
'COVER'
)
{
hasCover
=
true
;
return
<
img
className=
"course-cover"
src=
{
item
.
mediaUrl
}
/>
}
})
}
{
!
hasCover
&&
<
img
className=
"course-cover"
src=
{
'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'
}
/>
return
<
img
className=
'course-cover'
src=
{
item
.
mediaUrl
}
/>;
}
})
}
{
!
hasCover
&&
<
img
className=
'course-cover'
src=
{
'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'
}
/>
}
<
div
>
{
record
.
courseName
.
length
>
17
?
{
record
.
courseName
.
length
>
17
?
(
<
Tooltip
title=
{
record
.
courseName
}
>
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
</
Tooltip
>
:
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
}
)
:
(
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
)
}
<
div
>
<
span
className=
"course-time"
>
{
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
record
.
startTime
))
}
~
{
formatDate
(
"H:i"
,
parseInt
(
record
.
endTime
))
}
</
span
>
<
span
className=
"course-status"
style=
{
{
color
:
courseStateShow
[
record
.
courseState
].
color
,
border
:
`1px solid ${courseStateShow[record.courseState].color}`
}
}
>
{
courseStateShow
[
record
.
courseState
].
title
}
</
span
>
<
span
className=
'course-time'
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
record
.
startTime
))
}
~
{
formatDate
(
'H:i'
,
parseInt
(
record
.
endTime
))
}
</
span
>
<
span
className=
'course-status'
style=
{
{
color
:
courseStateShow
[
record
.
courseState
].
color
,
border
:
`1px solid ${courseStateShow[record.courseState].color}`
}
}
>
{
courseStateShow
[
record
.
courseState
].
title
}
</
span
>
</
div
>
<
div
className=
"teacher-assistant"
>
{
record
.
teacherName
.
length
>
4
?
<
div
className=
'teacher-assistant'
>
{
record
.
teacherName
&&
record
.
teacherName
.
length
>
4
?
(
<
Tooltip
title=
{
record
.
teacherName
}
>
<
span
className=
"teacher"
>
讲师:
{
record
.
teacherName
}
</
span
>
<
span
className=
'teacher'
>
讲师:
{
record
.
teacherName
}
</
span
>
</
Tooltip
>
:
<
span
className=
"teacher"
>
讲师:
{
record
.
teacherName
}
</
span
>
}
)
:
(
<
span
className=
'teacher'
>
讲师:
{
record
.
teacherName
}
</
span
>
)
}
{
record
.
admins
.
length
>
0
&&
{
record
.
admins
.
length
>
0
&&
(
<>
<
span
className=
"split"
>
|
</
span
>
{
this
.
handleAdminName
(
record
.
admins
).
length
>
4
?
<
span
className=
'split'
>
|
</
span
>
{
this
.
handleAdminName
(
record
.
admins
).
length
>
4
?
(
<
Tooltip
title=
{
this
.
handleAdminName
(
record
.
admins
)
}
>
<
span
className=
"assistant"
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
adminName
}
{
(
index
<
record
.
admins
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
<
span
className=
'assistant'
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
adminName
}
{
index
<
record
.
admins
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
);
})
}
</
span
>
</
Tooltip
>
:
<
span
className=
"assistant"
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
adminName
}
{
(
index
<
record
.
admins
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
)
:
(
<
span
className=
'assistant'
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
adminName
}
{
index
<
record
.
admins
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
}
);
})
}
</
span
>
)
}
</>
}
)
}
</
div
>
</
div
>
</
div
>
)
}
)
;
}
,
},
{
title
:
"课程分类"
,
width
:
"10%"
,
key
:
"couseCatalog"
,
dataIndex
:
"couseCatalog"
,
title
:
'课程分类'
,
width
:
'10%'
,
key
:
'couseCatalog'
,
dataIndex
:
'couseCatalog'
,
render
:
(
val
,
item
)
=>
{
return
(
<
div
className=
"categoryName"
>
{
item
.
categoryName
}
</
div
>
)
return
<
div
className=
'categoryName'
>
{
item
.
categoryName
}
</
div
>;
},
},
{
title
:
"课件管理"
,
width
:
"8%"
,
key
:
"courseware"
,
dataIndex
:
"courseware"
,
title
:
'课件管理'
,
width
:
'8%'
,
key
:
'courseware'
,
dataIndex
:
'courseware'
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
className=
"courseware"
<
span
className=
'courseware'
onClick=
{
()
=>
{
this
.
setState
({
editData
:
item
,
openCoursewareModal
:
true
,
});
}
}
>
{
item
.
courseDocumentCount
}
个
</
span
>
}
}
>
{
item
.
courseDocumentCount
}
个
</
span
>
);
},
},
{
title
:
'上课数据'
,
width
:
"9%"
,
key
:
"quota"
,
dataIndex
:
"quota"
,
width
:
'9%'
,
key
:
'quota'
,
dataIndex
:
'quota'
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
className=
"iconfont icon quota-icon"
onClick=
{
()
=>
{
this
.
handleLinkToClassData
(
item
)
}
}
>

</
span
>
<
span
className=
'iconfont icon quota-icon'
onClick=
{
()
=>
{
this
.
handleLinkToClassData
(
item
);
}
}
>

</
span
>
);
},
},
{
title
:
<
span
>
title
:
(
<
span
>
<
span
>
学院展示
</
span
>
<
Tooltip
title=
{
<
div
>
开启后,学员可在学院内查看到此课程。若课程“未成功开课”,则系统会自动“关闭”学院展示。
<
br
/>
关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。
</
div
>
}
><
i
className=
"icon iconfont"
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'normal'
}
}
>

</
i
></
Tooltip
>
</
span
>,
width
:
"9%"
,
key
:
"shelfState"
,
dataIndex
:
"shelfState"
,
<
Tooltip
title=
{
<
div
>
开启后,学员可在学院内查看到此课程。若课程“未成功开课”,则系统会自动“关闭”学院展示。
<
br
/>
关闭后,学院内不再展示此课程,但学员仍可通过分享的海报/链接查看此课程。
</
div
>
}
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'normal'
}
}
>

</
i
>
</
Tooltip
>
</
span
>
),
width
:
'9%'
,
key
:
'shelfState'
,
dataIndex
:
'shelfState'
,
render
:
(
val
,
item
,
index
)
=>
{
return
(
<
Switch
defaultChecked=
{
item
.
shelfState
===
"YES"
?
true
:
false
}
onChange=
{
()
=>
this
.
changeShelfState
(
item
)
}
/>
)
return
<
Switch
defaultChecked=
{
item
.
shelfState
===
'YES'
?
true
:
false
}
onChange=
{
()
=>
this
.
changeShelfState
(
item
)
}
/>;
},
},
{
title
:
'创建时间'
,
width
:
"9%"
,
key
:
"created"
,
dataIndex
:
"created"
,
width
:
'9%'
,
key
:
'created'
,
dataIndex
:
'created'
,
sorter
:
true
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
span
>
);
// -29000:与后端约定 在初始化学院时,创建时间(标志位-29000)默认展示为'-'
return
<
span
>
{
val
===
-
29000
?
'-'
:
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
span
>;
},
},
{
title
:
'关联项'
,
width
:
"15%"
,
key
:
"planList"
,
dataIndex
:
"planList"
,
width
:
'15%'
,
key
:
'planList'
,
dataIndex
:
'planList'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"related-task"
>
{
record
.
relatedPlanList
?
<
Tooltip
title=
{
this
.
handlePlanName
(
record
.
relatedPlanList
)
}
placement=
"top"
arrowPointAtCenter
>
{
record
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
planName
}
{
(
index
<
record
.
relatedPlanList
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
<
div
className=
'related-task'
>
{
record
.
relatedPlanList
?
(
<
Tooltip
title=
{
this
.
handlePlanName
(
record
.
relatedPlanList
)
}
placement=
'top'
arrowPointAtCenter
>
{
record
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
planName
}
{
index
<
record
.
relatedPlanList
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
);
})
}
</
Tooltip
>
:
)
:
(
<
span
></
span
>
}
)
}
</
div
>
)
)
;
},
},
{
title
:
"操作"
,
width
:
"15%"
,
key
:
"operate"
,
dataIndex
:
"operate"
,
title
:
'操作'
,
width
:
'15%'
,
key
:
'operate'
,
dataIndex
:
'operate'
,
render
:
(
val
,
item
)
=>
{
return
(
<
div
className=
"operate"
>
{
((
item
.
courseState
===
"UN_START"
||
item
.
courseState
===
"STARTING"
)
&&
(
item
.
teacherId
===
User
.
getUserId
()
||
_
.
pluck
(
item
.
admins
,
"adminId"
).
includes
(
User
.
getUserId
())))
&&
<
div
className=
'operate'
>
{
(
item
.
courseState
===
'UN_START'
||
item
.
courseState
===
'STARTING'
)
&&
(
item
.
teacherId
===
User
.
getUserId
()
||
_
.
pluck
(
item
.
admins
,
'adminId'
).
includes
(
User
.
getUserId
()))
&&
(
<>
<
div
key=
"enter_live_room1"
className=
"operate__item"
onClick=
{
()
=>
{
this
.
handleEnterLiveRoom
(
item
)
}
}
>
进入直播间
key=
'enter_live_room1'
className=
'operate__item'
onClick=
{
()
=>
{
this
.
handleEnterLiveRoom
(
item
);
}
}
>
进入直播间
</
div
>
<
span
className=
"operate__item split"
key=
"view_play_back_split"
>
|
</
span
>
<
span
className=
'operate__item split'
key=
'view_play_back_split'
>
{
' '
}
|
{
' '
}
</
span
>
</>
}
{
(
item
.
courseState
===
"FINISH"
&&
item
.
haveRecord
===
"YES"
)
&&
)
}
{
item
.
courseState
===
'FINISH'
&&
item
.
haveRecord
===
'YES'
&&
(
<>
<
div
key=
"view_play_back"
className=
"operate__item"
onClick=
{
()
=>
{
this
.
handleViewPlayBack
(
item
)}
}
>
查看回放
</
div
>
<
span
className=
"operate__item split"
key=
"view_play_back_split"
>
|
</
span
>
key=
'view_play_back'
className=
'operate__item'
onClick=
{
()
=>
{
this
.
handleViewPlayBack
(
item
);
}
}
>
查看回放
</
div
>
<
span
className=
'operate__item split'
key=
'view_play_back_split'
>
{
' '
}
|
{
' '
}
</
span
>
</>
}
{
item
.
courseState
!==
"EXPIRED"
&&
)
}
{
item
.
courseState
!==
'EXPIRED'
&&
(
<>
<
div
key=
"share"
className=
"operate__item"
onClick=
{
()
=>
{
this
.
handleShowShareModal
(
item
);
}
}
>
key=
'share'
className=
'operate__item'
onClick=
{
()
=>
{
this
.
handleShowShareModal
(
item
);
}
}
>
分享
</
div
>
</>
}
{
item
.
courseState
!==
"EXPIRED"
&&
)
}
{
item
.
courseState
!==
'EXPIRED'
&&
(
<>
<
span
key=
"split1"
className=
"operate__item split"
>
|
</
span
>
<
div
className=
"big-live"
>
<
span
key=
'split1'
className=
'operate__item split'
>
{
' '
}
|
{
' '
}
</
span
>
<
div
className=
'big-live'
>
<
Dropdown
overlay=
{
this
.
renderMoreOperate
(
item
)
}
>
<
span
className=
"more-operate"
>
<
span
className=
"operate-text"
>
更多
</
span
>
<
span
className=
"iconfont icon"
style=
{
{
color
:
"#2966FF"
}
}
>
<
span
className=
'more-operate'
>
<
span
className=
'operate-text'
>
更多
</
span
>
<
span
className=
'iconfont icon'
style=
{
{
color
:
'#2966FF'
}
}
>

</
span
>
</
span
>
</
Dropdown
>
</
div
>
</>
}
{
item
.
courseState
===
"EXPIRED"
&&
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
handleDelete
(
item
)
}
>
删除
</
div
>
}
)
}
{
item
.
courseState
===
'EXPIRED'
&&
(
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleDelete
(
item
)
}
>
删除
</
div
>
)
}
}
)
}
</
div
>
);
},
},
];
}
else
{
}
else
{
columns
=
[
{
title
:
"直播课"
,
width
:
"25%"
,
key
:
"course"
,
dataIndex
:
"courseName"
,
title
:
'直播课'
,
width
:
'25%'
,
key
:
'course'
,
dataIndex
:
'courseName'
,
render
:
(
val
,
record
)
=>
{
let
hasCover
=
false
;
return
(
<
div
className=
"record__item"
>
{
record
.
courseMediaVOS
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentType
===
"COVER"
){
<
div
className=
'record__item'
>
{
record
.
courseMediaVOS
.
map
((
item
,
index
)
=>
{
if
(
item
.
contentType
===
'COVER'
)
{
hasCover
=
true
;
return
<
img
className=
"course-cover"
src=
{
item
.
mediaUrl
}
/>
}
})
}
{
!
hasCover
&&
<
img
className=
"course-cover"
src=
{
'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'
}
/>
return
<
img
className=
'course-cover'
src=
{
item
.
mediaUrl
}
/>;
}
})
}
{
!
hasCover
&&
<
img
className=
'course-cover'
src=
{
'https://image.xiaomaiketang.com/xm/Yip2YtFDwH.png'
}
/>
}
<
div
>
{
record
.
courseName
.
length
>
17
?
{
record
.
courseName
.
length
>
17
?
(
<
Tooltip
title=
{
record
.
courseName
}
>
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
</
Tooltip
>
:
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
}
)
:
(
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
)
}
<
div
>
<
span
className=
"course-time"
>
{
formatDate
(
"YYYY-MM-DD H:i"
,
parseInt
(
record
.
startTime
))
}
~
{
formatDate
(
"H:i"
,
parseInt
(
record
.
endTime
))
}
</
span
>
<
span
className=
"course-status"
style=
{
{
color
:
courseStateShow
[
record
.
courseState
].
color
,
border
:
`1px solid ${courseStateShow[record.courseState].color}`
}
}
>
{
courseStateShow
[
record
.
courseState
].
title
}
</
span
>
<
span
className=
'course-time'
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
parseInt
(
record
.
startTime
))
}
~
{
formatDate
(
'H:i'
,
parseInt
(
record
.
endTime
))
}
</
span
>
<
span
className=
'course-status'
style=
{
{
color
:
courseStateShow
[
record
.
courseState
].
color
,
border
:
`1px solid ${courseStateShow[record.courseState].color}`
}
}
>
{
courseStateShow
[
record
.
courseState
].
title
}
</
span
>
</
div
>
<
div
className=
"teacher-assistant"
>
{
record
.
teacherName
.
length
>
4
?
<
div
className=
'teacher-assistant'
>
{
record
.
teacherName
&&
record
.
teacherName
.
length
>
4
?
(
<
Tooltip
title=
{
record
.
teacherName
}
>
<
span
className=
"teacher"
>
讲师:
{
record
.
teacherName
}
</
span
>
<
span
className=
'teacher'
>
讲师:
{
record
.
teacherName
}
</
span
>
</
Tooltip
>
:
<
span
className=
"teacher"
>
讲师:
{
record
.
teacherName
}
</
span
>
}
)
:
(
<
span
className=
'teacher'
>
讲师:
{
record
.
teacherName
}
</
span
>
)
}
{
record
.
admins
.
length
>
0
&&
{
record
.
admins
.
length
>
0
&&
(
<>
<
span
className=
"split"
>
|
</
span
>
{
this
.
handleAdminName
(
record
.
admins
).
length
>
4
?
<
span
className=
'split'
>
|
</
span
>
{
this
.
handleAdminName
(
record
.
admins
).
length
>
4
?
(
<
Tooltip
title=
{
this
.
handleAdminName
(
record
.
admins
)
}
>
<
span
className=
"assistant"
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
adminName
}
{
(
index
<
record
.
admins
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
<
span
className=
'assistant'
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
adminName
}
{
index
<
record
.
admins
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
);
})
}
</
span
>
</
Tooltip
>
:
<
span
className=
"assistant"
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
adminName
}
{
(
index
<
record
.
admins
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
)
:
(
<
span
className=
'assistant'
>
助教:
{
record
.
admins
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
adminName
}
{
index
<
record
.
admins
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
}
);
})
}
</
span
>
)
}
</>
}
)
}
</
div
>
</
div
>
</
div
>
)
}
)
;
}
,
},
{
title
:
"课程分类"
,
width
:
"10%"
,
key
:
"couseCatalog"
,
dataIndex
:
"couseCatalog"
,
title
:
'课程分类'
,
width
:
'10%'
,
key
:
'couseCatalog'
,
dataIndex
:
'couseCatalog'
,
render
:
(
val
,
item
)
=>
{
return
(
<
div
className=
"categoryName"
>
{
item
.
categoryName
}
</
div
>
)
return
<
div
className=
'categoryName'
>
{
item
.
categoryName
}
</
div
>;
},
},
{
title
:
"课件管理"
,
width
:
"8%"
,
key
:
"courseware"
,
dataIndex
:
"courseware"
,
title
:
'课件管理'
,
width
:
'8%'
,
key
:
'courseware'
,
dataIndex
:
'courseware'
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
className=
"courseware"
<
span
className=
'courseware'
onClick=
{
()
=>
{
this
.
setState
({
editData
:
item
,
openCoursewareModal
:
true
,
});
}
}
>
{
item
.
courseDocumentCount
}
个
</
span
>
}
}
>
{
item
.
courseDocumentCount
}
个
</
span
>
);
},
},
{
title
:
'上课数据'
,
width
:
"9%"
,
key
:
"quota"
,
dataIndex
:
"quota"
,
width
:
'9%'
,
key
:
'quota'
,
dataIndex
:
'quota'
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
className=
"iconfont icon quota-icon"
onClick=
{
()
=>
{
this
.
handleLinkToClassData
(
item
)
}
}
>

</
span
>
<
span
className=
'iconfont icon quota-icon'
onClick=
{
()
=>
{
this
.
handleLinkToClassData
(
item
);
}
}
>

</
span
>
);
},
},
{
title
:
'创建时间'
,
width
:
"9%"
,
key
:
"created"
,
dataIndex
:
"created"
,
width
:
'9%'
,
key
:
'created'
,
dataIndex
:
'created'
,
sorter
:
true
,
render
:
(
val
,
item
)
=>
{
return
(
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
span
>
);
return
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
val
)
}
</
span
>;
},
},
{
title
:
'关联项'
,
width
:
"15%"
,
key
:
"planList"
,
dataIndex
:
"planList"
,
width
:
'15%'
,
key
:
'planList'
,
dataIndex
:
'planList'
,
render
:
(
val
,
record
)
=>
{
return
(
<
div
className=
"related-task"
>
{
record
.
relatedPlanList
?
<
Tooltip
title=
{
this
.
handlePlanName
(
record
.
relatedPlanList
)
}
placement=
"top"
arrowPointAtCenter
>
{
record
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
return
<
span
>
{
item
.
planName
}
{
(
index
<
record
.
relatedPlanList
.
length
-
1
)
&&
(<
span
>
、
</
span
>)
}
</
span
>
})
}
<
div
className=
'related-task'
>
{
record
.
relatedPlanList
?
(
<
Tooltip
title=
{
this
.
handlePlanName
(
record
.
relatedPlanList
)
}
placement=
'top'
arrowPointAtCenter
>
{
record
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
{
item
.
planName
}
{
index
<
record
.
relatedPlanList
.
length
-
1
&&
<
span
>
、
</
span
>
}{
' '
}
</
span
>
);
})
}
</
Tooltip
>
:
)
:
(
<
span
></
span
>
}
)
}
</
div
>
)
)
;
},
},
];
}
this
.
setState
({
columns
})
}
handleAdminName
=
(
adminArray
)
=>
{
let
adminStr
=
""
;
adminArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
adminArray
.
length
-
1
)
{
this
.
setState
({
columns
})
;
}
;
handleAdminName
=
(
adminArray
)
=>
{
let
adminStr
=
''
;
adminArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
adminArray
.
length
-
1
)
{
adminStr
=
adminStr
+
item
.
adminName
+
'、'
;
}
else
{
adminStr
=
adminStr
+
item
.
adminName
}
})
return
adminStr
}
else
{
adminStr
=
adminStr
+
item
.
adminName
;
}
});
return
adminStr
;
};
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
""
;
planArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
planArray
.
length
-
1
)
{
handlePlanName
=
(
planArray
)
=>
{
let
planStr
=
''
;
planArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
planArray
.
length
-
1
)
{
planStr
=
planStr
+
item
.
planName
+
'、'
;
}
else
{
planStr
=
planStr
+
item
.
planName
}
})
return
planStr
}
else
{
planStr
=
planStr
+
item
.
planName
;
}
});
return
planStr
;
};
renderMoreOperate
=
(
item
)
=>
{
return
(
<
div
className=
"live-course-more-menu"
>
{
(
User
.
getUserRole
()
===
"CloudManager"
||
User
.
getUserRole
()
===
"StoreManager"
)
&&
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
handleRelatedModalShow
(
item
)
}
>
关联培训计划
</
div
>
}
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
toEditCoursePage
(
item
)
}
>
编辑
</
div
>
{
item
.
courseState
!==
"STARTING"
&&
<
div
className=
"operate__item"
onClick=
{
()
=>
this
.
handleDelete
(
item
)
}
>
删除
</
div
>
}
<
div
className=
'live-course-more-menu'
>
{
(
User
.
getUserRole
()
===
'CloudManager'
||
User
.
getUserRole
()
===
'StoreManager'
)
&&
(
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleRelatedModalShow
(
item
)
}
>
关联培训计划
</
div
>
)
}
handleDelete
=
(
record
)
=>
{
)
}
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
toEditCoursePage
(
item
)
}
>
编辑
</
div
>
{
item
.
courseState
!==
'STARTING'
&&
(
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleDelete
(
item
)
}
>
删除
</
div
>
)
}
</
div
>
);
};
handleDelete
=
(
record
)
=>
{
return
confirm
({
title
:
'你确定要删除直播课?'
,
content
:
'删除后,学员将不能观看直播课/回放'
,
icon
:
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
okText
:
'删除'
,
okType
:
'danger'
,
cancelText
:
'取消'
,
width
:
440
,
height
:
188
,
width
:
440
,
height
:
188
,
onOk
:
()
=>
{
this
.
deleteConfirm
(
record
);
}
})
}
deleteConfirm
=
(
item
)
=>
{
const
params
=
{
"liveCourseId"
:
item
.
liveCourseId
,
}
CourseService
.
delLiveCloudCourse
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
message
.
success
(
"已删除"
);
}
,
})
;
}
;
deleteConfirm
=
(
item
)
=>
{
const
params
=
{
liveCourseId
:
item
.
liveCourseId
,
}
;
CourseService
.
delLiveCloudCourse
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
message
.
success
(
'已删除'
);
this
.
props
.
onChange
();
}
})
}
toEditCoursePage
=
(
item
)
=>
{
})
;
}
;
toEditCoursePage
=
(
item
)
=>
{
window
.
RCHistory
.
push
({
pathname
:
`/create-live-course?type=edit&id=
${
item
.
liveCourseId
}
`
,
})
}
refreshCourseList
=
()
=>
{
})
;
}
;
refreshCourseList
=
()
=>
{
this
.
props
.
onChange
(
this
.
props
.
query
);
}
}
;
//进入直播间
handleEnterLiveRoom
=
(
item
)
=>
{
if
(
item
.
startTime
-
Date
.
now
()
>
1800000
)
{
Modal
.
warning
({
title
:
"你来得太早了"
,
title
:
'你来得太早了'
,
okText
:
'我知道了'
,
content
:
"请于开始上课前30分钟来直播上课。"
,
content
:
'请于开始上课前30分钟来直播上课。'
,
icon
:
(
<
span
className=
"icon iconfont default-confirm-icon"
style=
{
{
color
:
"#FFBB54 !important"
}
}
>
<
span
className=
'icon iconfont default-confirm-icon'
style=
{
{
color
:
'#FFBB54 !important'
}
}
>

</
span
>
),
...
...
@@ -630,127 +668,126 @@ class LiveCourseList extends React.Component {
}
else
{
CourseService
.
getLiveCloudCourseDetail
({
liveCourseId
:
item
.
liveCourseId
,
})
.
then
((
res
)
=>
{
}).
then
((
res
)
=>
{
const
url
=
`xmqx://liveCourseId=
${
item
.
liveCourseId
}
`
;
if
(
res
.
result
.
courseState
===
"FINISH"
)
{
if
(
res
.
result
.
courseState
===
'FINISH'
)
{
Modal
.
warning
({
title
:
"刷新页面"
,
title
:
'刷新页面'
,
icon
:
<
QuestionCircleOutlined
/>,
content
:
"课次已结束,请刷新一下"
,
content
:
'课次已结束,请刷新一下'
,
onOk
:
()
=>
{
this
.
refreshCourseList
();
}
},
});
}
else
{
this
.
setState
({
url
,
openDownloadModal
:
true
});
}
});
}
}
}
;
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
return
return
;
}
let
_query
=
this
.
props
.
query
let
_query
=
this
.
props
.
query
;
_query
.
size
=
size
;
this
.
props
.
onChange
(
_query
)
}
this
.
props
.
onChange
(
_query
)
;
}
;
getDownloadVersion
()
{
const
isMac
=
/macintosh|mac os x/i
.
test
(
navigator
.
userAgent
);
// 判断学员系统
let
platform
;
if
(
!
isMac
)
{
platform
=
1
}
else
{
platform
=
4
if
(
!
isMac
)
{
platform
=
1
;
}
else
{
platform
=
4
;
}
BaseService
.
getLastedVersion
({
model
:
5
,
platform
})
.
then
((
res
)
=>
{
BaseService
.
getLastedVersion
({
model
:
5
,
platform
}).
then
((
res
)
=>
{
const
{
result
=
{}
}
=
res
;
this
.
setState
({
downloadUrl
:
result
.
releaseUrl
});
})
});
}
handleViewPlayBack
=
(
item
)
=>
{
let
htmlUrl
;
if
(
item
.
teacherId
===
User
.
getUserId
())
{
if
(
item
.
teacherId
===
User
.
getUserId
())
{
htmlUrl
=
`
${
LIVE_SHARE
}
replay/
${
item
.
liveCourseId
}
?teacherId=
${
User
.
getUserId
()}
&id=
${
User
.
getStoreId
()}
`
;
}
else
if
(
_
.
pluck
(
item
.
admins
,
"adminId"
).
includes
(
User
.
getUserId
()))
{
}
else
if
(
_
.
pluck
(
item
.
admins
,
'adminId'
).
includes
(
User
.
getUserId
()))
{
htmlUrl
=
`
${
LIVE_SHARE
}
replay/
${
item
.
liveCourseId
}
?userId=
${
User
.
getUserId
()}
&id=
${
User
.
getStoreId
()}
`
;
}
else
{
}
else
{
htmlUrl
=
`
${
LIVE_SHARE
}
replay/
${
item
.
liveCourseId
}
?id=
${
User
.
getStoreId
()}
`
;
}
window
.
open
(
htmlUrl
);
}
handleRelatedModalShow
=
(
item
)
=>
{
};
handleRelatedModalShow
=
(
item
)
=>
{
const
selectPlanList
=
{};
if
(
item
.
relatedPlanList
)
{
item
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
selectPlanList
[
item
.
planId
]
=
{}
if
(
item
.
relatedPlanList
)
{
item
.
relatedPlanList
.
map
((
item
,
index
)
=>
{
selectPlanList
[
item
.
planId
]
=
{}
;
selectPlanList
[
item
.
planId
].
planId
=
item
.
planId
;
selectPlanList
[
item
.
planId
].
taskBaseVOList
=
[{
taskId
:
item
.
taskId
}];
return
item
})
selectPlanList
[
item
.
planId
].
taskBaseVOList
=
[{
taskId
:
item
.
taskId
}];
return
item
;
})
;
}
this
.
setState
({
RelatedPlanModalVisible
:
true
,
selectCourseId
:
item
.
liveCourseId
,
selectPlanList
:
selectPlanList
})
}
closeRelatedPlanModalVisible
=
()
=>
{
this
.
setState
({
RelatedPlanModalVisible
:
false
})
}
onChangeSelectPlanList
=
(
selectPlanList
)
=>
{
RelatedPlanModalVisible
:
true
,
selectCourseId
:
item
.
liveCourseId
,
selectPlanList
:
selectPlanList
,
});
};
closeRelatedPlanModalVisible
=
()
=>
{
this
.
setState
({
selectPlanList
:
selectPlanList
})
}
onC
onfirmSelectPlanList
=
()
=>
{
RelatedPlanModalVisible
:
false
,
})
;
}
;
onC
hangeSelectPlanList
=
(
selectPlanList
)
=>
{
this
.
setState
({
RelatedPlanModalVisible
:
false
},()
=>
{
this
.
props
.
onChange
();})
selectPlanList
:
selectPlanList
,
});
};
onConfirmSelectPlanList
=
()
=>
{
this
.
setState
(
{
RelatedPlanModalVisible
:
false
,
},
()
=>
{
this
.
props
.
onChange
();
}
);
};
handleChangeTable
=
(
pagination
,
filters
,
sorter
)
=>
{
const
{
columnKey
,
order
}
=
sorter
;
const
{
query
}
=
this
.
props
;
let
_columnKey
;
let
_order
;
// 按创建时间升序排序
if
(
columnKey
===
'created'
&&
order
===
'ascend'
)
{
_columnKey
=
"CREATED"
;
_order
=
'SORT_ASC'
;
}
if
(
columnKey
===
'created'
&&
order
===
'ascend'
)
{
_columnKey
=
'CREATED'
;
_order
=
'SORT_ASC'
;
}
// 按创建时间降序排序
if
(
columnKey
===
'created'
&&
order
===
'descend'
)
{
_columnKey
=
"CREATED"
;
_order
=
'SORT_DESC'
;}
if
(
columnKey
===
'created'
&&
order
===
'descend'
)
{
_columnKey
=
'CREATED'
;
_order
=
'SORT_DESC'
;
}
const
_query
=
{
...
query
,
sortMap
:
{}
sortMap
:
{},
};
_query
.
sortMap
[
_columnKey
]
=
_order
;
_query
.
sortMap
[
_columnKey
]
=
_order
;
this
.
props
.
onChange
(
_query
);
}
}
;
render
()
{
const
{
total
,
query
,
courseList
,
loading
}
=
this
.
props
;
const
{
total
,
query
,
courseList
,
loading
}
=
this
.
props
;
const
{
current
,
size
}
=
query
;
const
{
openDownloadModal
,
downloadUrl
,
url
,
columns
,
openCoursewareModal
,
editData
,
RelatedPlanModalVisible
,
selectCourseId
,
selectPlanList
}
=
this
.
state
;
const
{
openDownloadModal
,
downloadUrl
,
url
,
columns
,
openCoursewareModal
,
editData
,
RelatedPlanModalVisible
,
selectCourseId
,
selectPlanList
}
=
this
.
state
;
const
{
match
}
=
this
.
props
;
return
(
<
div
className=
"live-course-list"
>
<
div
className=
'live-course-list'
>
<
Table
bordered
size=
"middle"
size=
'middle'
pagination=
{
false
}
columns=
{
columns
}
loading=
{
loading
}
...
...
@@ -758,21 +795,21 @@ class LiveCourseList extends React.Component {
onChange=
{
this
.
handleChangeTable
}
rowKey=
{
(
row
)
=>
row
.
liveCourseId
}
/>
{
total
>
0
&&
<
div
className=
"box-footer"
>
{
total
>
0
&&
(
<
div
className=
'box-footer'
>
<
PageControl
current=
{
current
-
1
}
pageSize=
{
size
}
total=
{
parseInt
(
total
)
}
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
props
.
onChange
(
_query
)
const
_query
=
{
...
query
,
current
:
page
+
1
};
this
.
props
.
onChange
(
_query
)
;
}
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
/>
</
div
>
}
{
this
.
state
.
shareLiveModal
}
)
}
{
this
.
state
.
shareLiveModal
}
{
openCoursewareModal
&&
(
<
ManageCoursewareModal
data=
{
editData
}
...
...
@@ -789,12 +826,12 @@ class LiveCourseList extends React.Component {
onCancel=
{
()
=>
{
this
.
setState
({
url
:
''
,
openDownloadModal
:
false
});
openDownloadModal
:
false
,
});
}
}
/>
)
}
{
RelatedPlanModalVisible
&&
{
RelatedPlanModalVisible
&&
(
<
RelatedPlanModal
onClose=
{
this
.
closeRelatedPlanModalVisible
}
visible=
{
RelatedPlanModalVisible
}
...
...
@@ -803,11 +840,11 @@ class LiveCourseList extends React.Component {
onChange=
{
this
.
onChangeSelectPlanList
}
onConfirm=
{
this
.
onConfirmSelectPlanList
}
/>
}
<
iframe
src=
{
url
}
style=
{
{
display
:
"none"
}
}
/>
)
}
<
iframe
src=
{
url
}
style=
{
{
display
:
'none'
}
}
/>
<
Route
path=
{
`${match.url}/live-course-data`
}
component=
{
DataList
}
/>
</
div
>
)
)
;
}
}
...
...
src/modules/course-manage/modal/ManageCoursewareModal.jsx
View file @
b23fca45
...
...
@@ -16,6 +16,9 @@ import { FileVerifyMap, FileTypeIcon } from '@/common/constants/academic/lessonE
import
ScanFileModal
from
'@/modules/prepare-lesson/modal/ScanFileModal'
import
SelectPrepareFileModal
from
'@/modules/prepare-lesson/modal/SelectPrepareFileModal'
;
import
Service
from
'@/common/js/service'
;
import
BaseService
from
"@/domains/basic-domain/baseService"
;
import
PreviewFileModal
from
'@/bu-components/PreviewFileModal'
;
import
{
YZ_APPId
,
YZ_PREVIEW_URL
,
OFFICE_PREVIEW_URL
}
from
'@/domains/basic-domain/constants'
;
import
'./ManageCoursewareModal.less'
;
...
...
@@ -33,7 +36,10 @@ class ManageCoursewareModal extends React.Component {
scanFileModal
:
false
,
isLessonPermission
:
false
,
diskList
:
[],
// 机构可见的磁盘目录
selectedFileList
:
[]
selectedFileList
:
[],
showPreviewModal
:
false
,
//是否显示loading
previewing
:
false
,
//是否正在预览
previewStatus
:
'UPLOAD'
//预览文件的生成状态
}
}
...
...
@@ -164,17 +170,15 @@ class ManageCoursewareModal extends React.Component {
}
// 预览文件
handleScanFile
(
item
)
{
handleScanFile
=
async
(
item
)
=>
{
if
(
!
item
.
srcDocUrl
)
return
null
;
const
suffix
=
_
.
last
(
item
.
fileName
.
split
(
'.'
)).
toLowerCase
();
const
type
=
suffixType
[
suffix
]
const
fileType
=
FileVerifyMap
[
type
].
type
;
const
that
=
this
;
switch
(
fileType
)
{
case
"PDF"
:
window
.
open
(
item
.
srcDocUrl
,
"_blank"
);
break
;
case
"Excel"
:
case
"EXCEL"
:
case
"PPT"
:
...
...
@@ -183,25 +187,57 @@ class ManageCoursewareModal extends React.Component {
case
"WORD"
:
case
"DOCX"
:
case
"DOC"
:
let
size
=
parseFloat
(
item
.
fileSize
.
replace
(
/M$|KB$/g
,
''
));
if
(
item
.
fileSize
.
includes
(
'KB'
))
{
size
=
0
;
if
(
!
item
.
fileVersionId
){
this
.
setState
({
previewing
:
true
,
showPreviewModal
:
true
,
previewStatus
:
'UPLOAD'
},
async
()
=>
{
const
uploadParams
=
{
fileUrl
:
item
.
srcDocUrl
,
instId
:
User
.
getStoreId
(),
yoZoTypeEnum
:
'UPLOAD'
}
const
uploadSign
=
await
BaseService
.
getYoZoSign
(
uploadParams
);
BaseService
.
yoZoUpload
(
item
.
srcDocUrl
,
YZ_APPId
,
uploadSign
).
then
(
async
function
(
response
){
const
saveParams
=
{
fileVersionId
:
response
.
data
.
data
.
fileVersionId
,
folderId
:
item
.
folderId
,
instId
:
User
.
getStoreId
(),
}
BaseService
.
saveYoZoFileVersionId
(
saveParams
);
const
{
previewing
}
=
that
.
state
;
if
(
previewing
){
const
previewParams
=
{
fileVersionId
:
response
.
data
.
data
.
fileVersionId
,
instId
:
User
.
getStoreId
(),
yoZoTypeEnum
:
'VIEW'
,
htmlTitle
:
item
.
fileName
}
const
previewSign
=
await
BaseService
.
getYoZoSign
(
previewParams
);
const
url
=
`
${
YZ_PREVIEW_URL
}
?fileVersionId=
${
response
.
data
.
data
.
fileVersionId
}
&appId=
${
YZ_APPId
}
&sign=
${
previewSign
}
&htmlTitle=
${
item
.
fileName
}
`
that
.
setState
({
previewStatus
:
'UPLOAD_SUCCESS'
,
url
})
}
})
})
}
else
{
const
previewParams
=
{
fileVersionId
:
item
.
fileVersionId
,
instId
:
User
.
getStoreId
(),
yoZoTypeEnum
:
'VIEW'
,
htmlTitle
:
item
.
fileName
}
if
(((
fileType
==
'word'
||
fileType
==
'PPT'
)
&&
size
>
10
)
||
((
fileType
==
'Excel'
)
&&
size
>
5
))
{
Modal
.
confirm
({
title
:
'抱歉,不能在线预览'
,
content
:
'由于文件较大,不支持在线预览,请下载后再查看'
,
icon
:
<
QuestionCircleOutlined
/>,
okText
:
"下载"
,
onOk
:()
=>
{
const
previewSign
=
await
BaseService
.
getYoZoSign
(
previewParams
);
const
url
=
`
${
YZ_PREVIEW_URL
}
?fileVersionId=
${
item
.
fileVersionId
}
&appId=
${
YZ_APPId
}
&sign=
${
previewSign
}
&htmlTitle=
${
item
.
fileName
}
`
const
a
=
document
.
createElement
(
'a'
);
a
.
href
=
item
.
srcDocUrl
;
document
.
body
.
appendChild
(
a
);
a
.
setAttribute
(
'href'
,
url
);
a
.
setAttribute
(
'target'
,
'_blank'
);
a
.
click
();
}
});
}
else
{
const
scanUrl
=
"https://view.officeapps.live.com/op/view.aspx?src="
+
encodeURIComponent
(
item
.
srcDocUrl
);
window
.
open
(
scanUrl
,
"_blank"
);
document
.
body
.
removeChild
(
a
)
}
break
;
case
"JPG"
:
...
...
@@ -214,8 +250,13 @@ class ManageCoursewareModal extends React.Component {
break
;
}
};
cancelPreview
=
()
=>
{
this
.
setState
({
previewing
:
false
,
showPreviewModal
:
false
,
previewStatus
:
'UPLOAD'
})
}
render
()
{
const
columns
=
[
{
...
...
@@ -299,7 +340,7 @@ class ManageCoursewareModal extends React.Component {
const
{
list
,
scanFileModal
,
editData
,
cancelObject
,
showSelectFileModal
,
selectedFileList
,
diskList
diskList
,
showPreviewModal
,
previewStatus
,
url
}
=
this
.
state
;
const
_list
=
_
.
reject
(
list
,
(
item
)
=>
cancelObject
[
item
.
id
]);
return
(
...
...
@@ -365,6 +406,9 @@ class ManageCoursewareModal extends React.Component {
}
}
onSelect=
{
this
.
handleAddFile
}
/>
{
showPreviewModal
&&
<
PreviewFileModal
onCancel=
{
()
=>
this
.
cancelPreview
()
}
previewStatus=
{
previewStatus
}
url=
{
url
}
/>
}
</
Modal
>
)
}
...
...
src/modules/course-manage/modal/ShareLiveModal.jsx
View file @
b23fca45
...
...
@@ -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 @
b23fca45
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 @
b23fca45
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 @
b23fca45
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/prepare-lesson/components/FolderList.jsx
deleted
100644 → 0
View file @
f803fff4
/*
* @Author: 吴文洁
* @Date: 2020-06-09 10:47:51
* @Last Modified by: 吴文洁
* @Last Modified time: 2020-07-23 09:33:09
* @Description: 文件夹列表
*/
import
React
from
'react'
;
import
{
Table
,
Menu
,
Dropdown
,
Upload
,
Modal
,
message
,
Tooltip
,
Icon
}
from
'antd'
;
import
{
PageControl
}
from
'@/components'
;
import
DefaultIcon
from
'@/modules/common/DefaultIcon'
;
import
{
QuestionCircleOutlined
}
from
'@ant-design/icons'
;
import
{
FileTypeIcon
,
SupportFileType
,
DEFAULT_SIZE_UNIT
}
from
"@/common/constants/academic/lessonEnum"
;
import
ScanFileModal
from
'../modal/ScanFileModal'
;
import
CreateFolderModal
from
'../modal/CreateFolderModal'
;
import
UploadProgressModal
from
'../modal/UploadProgressModal'
;
import
SelectPrepareFileModal
from
'../modal/SelectPrepareFileModal'
;
const
DEL_FOLDER_URL_MAP
=
{
'MYSELF'
:
'public/apollo/delFolder'
,
'COMMON'
:
'public/apollo/delCommonFolder'
}
let
count
=
0
;
class
FolderList
extends
React
.
Component
{
constructor
(
props
)
{
super
(
props
);
this
.
state
=
{
localFileList
:
[],
// 本地文件列表(待上传)
currentFolder
:
{},
// 当前文件/文件夹(操作列表中的文件/文件夹的时候需要用到)
uploadFolderPath
:
{},
// 上传文件的目录,防止中途切换文件夹
renameModalData
:
{},
// 重命名弹窗
scanFileModal
:
null
,
// 预览文件弹窗
showUploadModal
:
false
,
// 上传进度弹窗,
nonCompliantFileList
:
[]
}
}
componentWillReceiveProps
(
nextProps
)
{
const
{
folderPathList
}
=
nextProps
const
currentFolder
=
folderPathList
[
folderPathList
.
length
-
1
];
this
.
setState
({
currentFolder
})
}
//预览文件
handleSelect
=
(
folder
)
=>
{
// 只有文件才有预览功能
if
(
folder
.
folderType
===
'FOLDER'
)
{
this
.
handleSelectFolder
(
folder
);
}
else
{
this
.
handleScanFile
(
folder
);
}
}
// 埋点
handleDataDot
=
(
folderFormat
)
=>
{
switch
(
folderFormat
)
{
case
'PDF'
:
window
.
WEBTRACING
(
'resource_disk_file_preview_pdf'
,
'资料云盘_点击预览_pdf'
);
break
;
case
'WORD'
:
case
'DOCX'
:
case
'DOC'
:
window
.
WEBTRACING
(
'resource_disk_file_preview_word'
,
'资料云盘_点击预览_word'
);
break
;
case
'EXCEL'
:
window
.
WEBTRACING
(
'resource_disk_file_preview_excel'
,
'资料云盘_点击预览_excel'
);
break
;
case
'PPT'
:
case
'PPTX'
:
window
.
WEBTRACING
(
'resource_disk_file_preview_ppt'
,
'资料云盘_点击预览_ppt'
);
break
;
default
:
break
;
}
}
// 预览文件
handleScanFile
=
(
folder
)
=>
{
const
{
folderFormat
,
folderSize
,
ossUrl
}
=
folder
;
switch
(
folderFormat
)
{
case
'PDF'
:
window
.
open
(
ossUrl
,
"_blank"
);
break
;
case
"WORD"
:
case
"DOCX"
:
case
"DOC"
:
case
"EXCEL"
:
case
"PPT"
:
case
"PPTX"
:
case
"PDF"
:
if
((
folderFormat
===
'PPT'
||
folderFormat
===
'PPTX'
||
folderFormat
===
'DOCX'
||
folderFormat
===
'WORD'
||
folderFormat
===
'DOC'
)
&&
folderSize
>
10
*
DEFAULT_SIZE_UNIT
)
{
Modal
.
confirm
({
title
:
'抱歉,不能在线预览'
,
content
:
'由于文件较大,不支持在线预览,请下载后再查看'
,
icon
:
<
QuestionCircleOutlined
/>,
okText
:
"下载"
,
onOk
:()
=>
{
const
a
=
document
.
createElement
(
'a'
);
a
.
href
=
ossUrl
;
a
.
click
();
}
});
break
;
}
if
(
folderFormat
===
'EXCEL'
&&
folderSize
>
5
*
DEFAULT_SIZE_UNIT
)
{
Modal
.
confirm
({
title
:
'抱歉,不能在线预览'
,
content
:
'由于文件较大,不支持在线预览,请下载后再查看'
,
icon
:
<
QuestionCircleOutlined
/>,
okText
:
"下载"
,
onOk
:()
=>
{
const
a
=
document
.
createElement
(
'a'
);
a
.
href
=
ossUrl
;
a
.
click
();
}
});
break
;
}
const
prefixUrl
=
"https://view.officeapps.live.com/op/view.aspx?src="
;
const
scanUrl
=
`
${
prefixUrl
}${
encodeURIComponent
(
ossUrl
)}
`
window
.
open
(
scanUrl
,
"_blank"
);
break
;
default
:
const
scanFileModal
=
<
ScanFileModal
fileType=
{
folderFormat
}
item=
{
folder
}
close=
{
()
=>
{
this
.
setState
({
scanFileModal
:
null
})
}
}
/>
this
.
setState
({
scanFileModal
});
break
;
}
// 预览文件埋点
this
.
handleDataDot
(
folderFormat
);
}
// 选择文件夹
handleSelectFolder
=
(
folder
)
=>
{
const
{
folderPathList
,
showResultPage
,
currentRootDisk
}
=
this
.
props
;
// 判断是否是员工文件的根目录
const
employeeDisk
=
currentRootDisk
.
disk
===
'EMPLOYEE'
&&
folderPathList
.
length
===
1
;
if
(
showResultPage
)
{
folderPathList
.
pop
();
}
folderPathList
.
push
({
id
:
folder
.
id
,
folderName
:
folder
.
folderName
});
this
.
props
.
onChangeFolderPath
(
folderPathList
);
this
.
props
.
onRefresh
({
parentId
:
folder
.
id
,
folderIdType
:
employeeDisk
?
'USER'
:
'FOLDER'
});
}
// 修改文件路径
handleChangeFolderPath
=
(
folder
)
=>
{
const
{
instId
}
=
window
.
currentUserInstInfo
;
const
{
id
}
=
folder
;
const
{
currentRootDisk
}
=
this
.
props
;
const
params
=
{
id
,
instId
:
instId
||
LS
.
get
(
'instId'
),
disk
:
currentRootDisk
.
disk
,
}
axios
.
Apollo
(
'public/apollo/folderPath'
,
params
).
then
((
res
)
=>
{
const
{
result
=
[]
}
=
res
;
this
.
props
.
onChangeFolderPath
(
result
,
false
);
})
}
parseColumns
=
()
=>
{
const
{
currentRootDisk
,
showResultPage
,
folderPathList
}
=
this
.
props
;
const
hasManagementAuthority
=
currentRootDisk
.
uploadPower
;
// 判断是否是员工文件的根目录
const
employeeDisk
=
currentRootDisk
.
disk
===
'EMPLOYEE'
&&
folderPathList
.
length
===
1
;
const
columns
=
[
{
title
:
'名称'
,
key
:
'folderName'
,
dataIndex
:
'folderName'
,
width
:
'28%'
,
sorter
:
(
employeeDisk
||
!
hasManagementAuthority
)
?
false
:
true
,
render
:
(
value
,
record
)
=>
{
const
{
folderType
,
folderFormat
}
=
record
;
const
isFolder
=
folderType
===
'FOLDER'
;
let
imgSrc
=
!
isFolder
?
FileTypeIcon
[
folderFormat
]
:
'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1594871430788.png'
;
if
(
employeeDisk
)
{
imgSrc
=
'https://xiaomai-image.oss-cn-hangzhou.aliyuncs.com/1594871440736.png'
}
return
(
<
div
className=
"file-name"
onClick=
{
()
=>
this
.
handleSelect
(
record
)
}
>
{
<
img
alt=
"img-src"
className=
"file-name__icon"
src=
{
imgSrc
}
/>
}
<
span
className=
{
`file-name__text ${!isFolder ? 'highlight' : ''}`
}
>
{
value
}
</
span
>
</
div
>
)
}
},
{
title
:
'更新时间'
,
key
:
'updated'
,
dataIndex
:
'updated'
,
sorter
:
(
employeeDisk
||
!
hasManagementAuthority
)
?
false
:
true
,
render
:
(
value
)
=>
{
return
<
span
>
{
formatDate
(
'YYYY-MM-DD H:i'
,
value
)
}
</
span
>
}
},
{
title
:
'大小'
,
key
:
'folderSize'
,
dataIndex
:
'folderSize'
,
width
:
'10%'
,
sorter
:
(
employeeDisk
||
!
hasManagementAuthority
)
?
false
:
true
,
render
:
(
value
,
record
)
=>
{
const
{
folderType
}
=
record
;
const
_fileSize
=
Number
(
value
);
let
_size
=
`
${(
_fileSize
/
DEFAULT_SIZE_UNIT
).
toFixed
(
1
)}
M`
;
if
(
_fileSize
<
0.1
*
DEFAULT_SIZE_UNIT
)
{
_size
=
`
${(
_fileSize
/
1024
).
toFixed
(
1
)}
kb`
;
}
return
(
<
span
>
{
folderType
===
'FILE'
?
_size
:
'-'
}
</
span
>
)
}
},
{
title
:
'操作'
,
key
:
'operate'
,
render
:
(
value
,
record
)
=>
{
if
(
!
(
currentRootDisk
.
disk
===
'EMPLOYEE'
&&
(
folderPathList
.
length
===
1
||
record
.
folderType
===
'FOLDER'
))
||
hasManagementAuthority
)
{
return
(
<
Dropdown
overlay=
{
this
.
renderMenu
(
record
)
}
trigger=
{
[
'hover'
]
}
>
<
span
className=
"icon iconfont"
>

</
span
>
</
Dropdown
>
)
}
return
<
span
>
-
</
span
>
}
}
]
// 公共文件需要显示创建者
if
(
currentRootDisk
.
disk
===
'COMMON'
)
{
columns
.
splice
(
1
,
0
,
{
title
:
'创建者'
,
key
:
'createName'
,
dataIndex
:
'createName'
});
}
// 搜索结果需要显示所在目录
if
(
showResultPage
)
{
columns
.
push
({
title
:
'所在目录'
,
key
:
'parentName'
,
dataIndex
:
'parentName'
,
render
:
(
value
,
record
)
=>
{
return
<
span
className=
"file-path"
onClick=
{
()
=>
this
.
handleChangeFolderPath
(
record
)
}
>
{
value
||
currentRootDisk
.
folderName
}
</
span
>
}
})
}
return
columns
;
}
// 删除文件
handleDeleteFolder
=
(
folder
)
=>
{
const
{
currentRootDisk
:
{
disk
}
}
=
this
.
props
;
const
{
instId
}
=
window
.
currentUserInstInfo
;
// 判断此文件是否有关联的课次
axios
.
Apollo
(
'public/apollo/judgeRelation'
,
{
folderIds
:
[
folder
.
id
],
instId
:
instId
||
LS
.
get
(
'instId'
)
}).
then
((
res
)
=>
{
// 如果有关联的文件,二次弹窗确认
const
hasRelative
=
!!
res
.
result
;
Modal
.
confirm
({
title
:
'确认删除所选的文件吗?'
,
content
:
hasRelative
?
'此文件已关联了课次,删除后,学员将不能查看到此文件。'
:
'删除后,数据将无法恢复。'
,
icon
:<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>,
okType
:
'danger'
,
onOk
:
()
=>
{
const
{
currentFolder
}
=
this
.
state
;
axios
.
Apollo
(
DEL_FOLDER_URL_MAP
[
disk
],
{
ids
:
[
folder
.
id
],
instId
:
instId
||
LS
.
get
(
'instId'
)
}).
then
(()
=>
{
message
.
success
(
'删除成功'
);
this
.
props
.
onRefresh
({
parentId
:
currentFolder
.
id
||
null
});
})
}
});
})
}
// 重命名
handleRename
=
(
folder
)
=>
{
this
.
setState
({
renameModalData
:
{
visible
:
true
,
id
:
folder
.
id
,
folderName
:
folder
.
folderName
,
}
});
}
// 重命名完成或者取消重命名之后隐藏重命名弹窗
handleRenameDone
=
(
folderName
)
=>
{
const
{
renameModalData
,
currentFolder
}
=
this
.
state
;
// 名称未修改不发送请求
if
(
folderName
===
renameModalData
.
folderName
)
{
this
.
setState
({
renameModalData
:
{}
});
return
;
}
// 判断是否有同名文件
this
.
handleGetSameNameFiles
(
folderName
).
then
((
res
)
=>
{
if
(
res
)
{
message
.
warning
(
'此目录下已存在同名文件'
);
return
;
}
axios
.
Apollo
(
'public/apollo/renameFolder'
,
{
id
:
renameModalData
.
id
,
name
:
folderName
}).
then
(()
=>
{
message
.
success
(
'重命名成功'
);
this
.
setState
({
renameModalData
:
{}
});
this
.
props
.
onRefresh
({
parentId
:
currentFolder
.
id
||
null
});
})
});
}
// 获取同名文件
handleGetSameNameFiles
=
async
(
folderName
)
=>
{
const
{
currentRootDisk
,
folderPathList
}
=
this
.
props
;
const
currentFolder
=
folderPathList
[
folderPathList
.
length
-
1
];
const
{
instId
}
=
window
.
currentUserInstInfo
;
const
params
=
{
name
:
folderName
,
disk
:
currentRootDisk
.
disk
,
parentId
:
currentFolder
.
id
,
folderType
:
'FOLDER'
,
instId
:
instId
||
LS
.
get
(
'instId'
)
}
const
res
=
await
axios
.
Apollo
(
'public/apollo/sameNameFile'
,
params
);
const
{
result
}
=
res
;
return
!!
result
||
result
&&
Object
.
keys
(
result
).
length
;
}
// 显示移动文件弹窗
handleShowSelectFileModal
=
(
file
)
=>
{
this
.
setState
({
currentFile
:
file
,
showSelectFileModal
:
true
});
}
getBlob
=
(
url
)
=>
{
return
new
Promise
((
resolve
)
=>
{
const
xhr
=
new
XMLHttpRequest
()
xhr
.
open
(
'GET'
,
url
,
true
)
xhr
.
responseType
=
'blob'
xhr
.
onload
=
()
=>
{
if
(
xhr
.
status
===
200
)
{
resolve
(
xhr
.
response
)
}
}
xhr
.
send
()
})
}
saveAs
=
(
blob
,
filename
)
=>
{
if
(
window
.
navigator
.
msSaveOrOpenBlob
)
{
navigator
.
msSaveBlob
(
blob
,
filename
)
}
else
{
const
link
=
document
.
createElement
(
'a'
)
const
body
=
document
.
querySelector
(
'body'
)
// 创建对象url
link
.
href
=
window
.
URL
.
createObjectURL
(
blob
)
link
.
download
=
filename
body
.
appendChild
(
link
)
link
.
click
()
body
.
removeChild
(
link
)
// 通过调用 URL.createObjectURL() 创建的 URL 对象
window
.
URL
.
revokeObjectURL
(
link
.
href
)
}
}
// 下载文件
handleDownload
=
(
folder
)
=>
{
this
.
getBlob
(
folder
.
ossUrl
).
then
((
blob
)
=>
{
this
.
saveAs
(
blob
,
folder
.
folderName
)
})
}
handleChooseFile
=
async
()
=>
{
// 判断是否欠费,旗舰版用户不需要校验余额
const
{
instId
}
=
window
.
currentUserInstInfo
;
const
ultimateRes
=
await
axios
.
Business
(
'public/inst/checkInstProduct'
,
{
instId
:
instId
||
LS
.
get
(
"instId"
),
productCodeList
:
[
'ULTIMATESELL'
,
'PIP_TO_ULTIMATE'
,
'HIGH_TO_ULTIMATE'
]
});
const
{
balance
}
=
this
.
props
;
if
(
balance
<=
0
&&
!
ultimateRes
.
result
)
{
this
.
handleShowNoticeModal
();
return
;
}
const
dom
=
document
.
querySelector
(
'#detailFileInput'
);
dom
.
click
();
}
// 准备上传
handleUpload
=
(
event
)
=>
{
const
fileList
=
event
.
target
.
files
;
// 判断文件的大小是否超出了限制
const
nonCompliantFileList
=
[];
const
_fileList
=
[...
fileList
];
_fileList
.
map
((
file
,
index
)
=>
{
let
{
size
,
type
,
name
}
=
file
;
if
(
!
type
)
{
type
=
getFileTypeByName
(
name
);
}
if
(
type
.
indexOf
(
'image'
)
>
-
1
&&
size
>
50
*
DEFAULT_SIZE_UNIT
)
{
nonCompliantFileList
.
push
(
file
);
_fileList
.
splice
(
index
,
1
);
}
if
(
type
.
indexOf
(
'audio'
)
>
-
1
&&
size
>
50
*
DEFAULT_SIZE_UNIT
)
{
nonCompliantFileList
.
push
(
file
);
_fileList
.
splice
(
index
,
1
);
}
if
(
type
.
indexOf
(
'video'
)
>
-
1
&&
size
>
2000
*
DEFAULT_SIZE_UNIT
)
{
nonCompliantFileList
.
push
(
file
);
_fileList
.
splice
(
index
,
1
);
}
if
(
localFileType
.
indexOf
(
type
)
>
-
1
&&
size
>
100
*
DEFAULT_SIZE_UNIT
)
{
nonCompliantFileList
.
push
(
file
);
_fileList
.
splice
(
index
,
1
);
}
file
.
key
=
count
++
;
});
// 不符合规则的文件列表
if
(
nonCompliantFileList
.
length
>
0
)
{
this
.
setState
({
nonCompliantFileList
,
showNonCompliantFileModal
:
true
,
})
}
else
{
this
.
handleShowUploadModal
(
_fileList
);
}
// 清空文件,防止第二次无法上传同一个文件
const
dom
=
document
.
querySelector
(
'#detailFileInput'
);
dom
.
value
=
''
;
}
// 显示上传进度弹窗
handleShowUploadModal
=
(
fileList
)
=>
{
// 保存当前路径
const
{
folderPathList
}
=
this
.
props
;
if
(
fileList
.
length
)
{
this
.
setState
({
showUploadModal
:
true
,
localFileList
:
fileList
,
uploadFolderPath
:
folderPathList
[
folderPathList
.
length
-
1
]
});
}
}
// 上传成功
handleUploadDone
=
(
file
,
resourceId
)
=>
{
this
.
props
.
onCreate
(
file
,
resourceId
);
}
// 取消上传
handleHiddenUploadModal
=
()
=>
{
this
.
setState
({
showUploadModal
:
false
,
localFileList
:
[]
});
}
// 余额欠费提示弹窗
handleShowNoticeModal
=
()
=>
{
const
{
balance
}
=
this
.
props
;
Modal
.
info
({
title
:
'无法继续操作'
,
content
:
'直播服务已升级,请联系运营老师。'
,
icon
:
<
span
className=
"icon iconfont default-confirm-icon"
>

</
span
>
})
}
// 排序
handleChangeTable
=
(
pagination
,
filters
,
sorter
)
=>
{
const
{
columnKey
,
order
}
=
sorter
;
let
sort
=
null
;
if
(
columnKey
===
'folderName'
&&
order
===
'ascend'
)
{
sort
=
'NAME_ASC'
;
}
if
(
columnKey
===
'folderName'
&&
order
===
'descend'
)
{
sort
=
'NAME_DESC'
;
}
if
(
columnKey
===
'folderSize'
&&
order
===
'ascend'
)
{
sort
=
'SIZE_ASC'
;
}
if
(
columnKey
===
'folderSize'
&&
order
===
'descend'
)
{
sort
=
'SIZE_DESC'
;
}
if
(
columnKey
===
'updated'
&&
order
===
'ascend'
)
{
sort
=
'UPDATE_ASC'
;
}
if
(
columnKey
===
'updated'
&&
order
===
'descend'
)
{
sort
=
'UPDATE_DESC'
;
}
const
{
currentFolder
}
=
this
.
state
;
this
.
props
.
onRefresh
({
sort
,
parentId
:
currentFolder
.
id
||
null
});
}
renderMenu
=
(
record
)
=>
{
const
{
currentRootDisk
}
=
this
.
props
;
// 是否有编辑权限
const
hasManagementAuthority
=
currentRootDisk
.
uploadPower
;
const
{
folderType
}
=
record
;
const
menu
=
(
<
Menu
>
{
folderType
===
'FILE'
&&
<
Menu
.
Item
key=
"download"
>
<
span
onClick=
{
()
=>
{
this
.
handleDownload
(
record
)
}
}
>
下载
</
span
>
</
Menu
.
Item
>
}
{
hasManagementAuthority
&&
[
<
Menu
.
Item
key=
"move"
>
<
span
onClick=
{
()
=>
this
.
handleShowSelectFileModal
(
record
)
}
>
移动
</
span
>
</
Menu
.
Item
>,
<
Menu
.
Item
key=
"rename"
>
<
span
onClick=
{
()
=>
this
.
handleRename
(
record
)
}
>
重命名
</
span
>
</
Menu
.
Item
>,
<
Menu
.
Item
key=
"delete"
>
<
span
onClick=
{
()
=>
this
.
handleDeleteFolder
(
record
)
}
>
删除
</
span
>
</
Menu
.
Item
>
]
}
</
Menu
>
);
return
menu
;
}
render
()
{
const
{
currentFolder
,
showScanFileModal
,
currentFile
,
renameModalData
,
showSelectFileModal
,
showUploadModal
,
localFileList
,
currentFolderName
}
=
this
.
state
;
const
{
selectedFileIds
,
folderList
,
showResultPage
,
folderPathList
,
currentRootDisk
,
balance
,
query
,
totalCount
}
=
this
.
props
;
// 是否有编辑权限
const
hasManagementAuthority
=
currentRootDisk
.
uploadPower
;
// 是否已经欠费
const
hasOwnedFee
=
balance
<=
0
;
return
(
<
div
className=
"file-list"
>
{
!
_
.
isEmpty
(
folderList
)
?
[<
Table
key=
"table"
rowKey=
{
(
record
)
=>
record
.
id
}
columns=
{
this
.
parseColumns
()
}
dataSource=
{
folderList
}
rowSelection=
{
hasManagementAuthority
?
{
selectedRowKeys
:
selectedFileIds
,
onChange
:
this
.
props
.
onChangeRow
}
:
null
}
pagination=
{
false
}
onChange=
{
this
.
handleChangeTable
}
/>,
<
div
className=
"box-footer"
key=
"pagination"
>
<
PageControl
current=
{
query
.
current
-
1
}
pageSize=
{
query
.
size
}
total=
{
totalCount
}
showSizeChanger=
{
true
}
toPage=
{
(
page
)
=>
this
.
props
.
onChangePage
(
'current'
,
page
+
1
)
}
onShowSizeChange=
{
(
current
,
size
)
=>
this
.
props
.
onChangePage
(
'size'
,
size
)
}
/>
</
div
>]
:
<
DefaultIcon
type=
'student'
title=
{
!
showResultPage
?
<
div
className=
"desc"
>
<
input
multiple
type=
"file"
style=
{
{
display
:
'none'
}
}
id=
"detailFileInput"
accept=
".ppt,.pptx,.doc,.docx,.pdf,.jpg,.jpeg,.png,.mp3,.mp4,.xlsx,.xls"
onChange=
{
(
e
)
=>
this
.
handleUpload
(
e
)
}
/>
{
hasManagementAuthority
?
<
div
>
你还没有上传文件,点击
<
Tooltip
title=
"支持文件类型:ppt、word、excel、pdf、jpg、mp3、mp4"
>
<
span
className=
"upload-btn"
onClick=
{
this
.
handleChooseFile
}
>
上传文件
</
span
>
</
Tooltip
>
按钮
</
div
>
:
<
span
>
这个文件夹是空的
</
span
>
}
</
div
>
:
<
div
className=
"desc"
>
搜索无结果
</
div
>
}
/>
}
<
CreateFolderModal
title=
"重命名"
folderName=
{
renameModalData
.
folderName
}
isOpen=
{
renameModalData
.
visible
}
onClose=
{
()
=>
{
this
.
setState
({
renameModalData
:
{}
})}
}
onOk=
{
this
.
handleRenameDone
}
/>
<
UploadProgressModal
isOpen=
{
showUploadModal
}
currentFolder=
{
currentFolder
}
fileList=
{
localFileList
}
onUpload=
{
this
.
handleUploadDone
}
onCancel=
{
this
.
handleHiddenUploadModal
}
/>
<
SelectPrepareFileModal
multiple=
{
true
}
isOpen=
{
showSelectFileModal
}
currentRootDisk=
{
currentRootDisk
}
onClose=
{
()
=>
{
this
.
setState
({
showSelectFileModal
:
false
});
}
}
onMove=
{
(
targetFolder
)
=>
{
this
.
setState
({
showSelectFileModal
:
false
});
this
.
props
.
onMove
(
targetFolder
,
[
currentFile
.
id
]);
}
}
/>
{
this
.
state
.
scanFileModal
}
{
this
.
state
.
chargeModal
}
</
div
>
)
}
}
export
default
FolderList
;
\ No newline at end of file
src/modules/prepare-lesson/components/FolderManage.jsx
View file @
b23fca45
...
...
@@ -13,7 +13,6 @@ import { Spin, message } from 'antd';
import
User
from
'@/common/js/user'
;
import
OperateArea
from
'./OperateArea'
;
import
FolderList
from
'./FolderList'
;
import
{
DISK_MAP
,
suffixMap
}
from
"@/common/constants/academic/lessonEnum"
;
...
...
@@ -301,27 +300,6 @@ class FolderManage extends React.Component {
onChangeFolderPath=
{
this
.
handleChangeFolderPath
}
onRefresh=
{
this
.
handleFetchFolderList
}
/>
{
/* 文件夹列表 */
}
<
FolderList
query=
{
query
}
totalCount=
{
totalCount
}
balance=
{
balance
}
showResultPage=
{
showResultPage
}
currentRootDisk=
{
currentRootDisk
}
hasManagementAuthority=
{
hasManagementAuthority
}
folderList=
{
folderList
}
folderPathList=
{
folderPathList
}
selectedFileIds=
{
selectedFileIds
}
onChangeRow=
{
this
.
handleChangeRow
}
onChangeFolderPath=
{
this
.
handleChangeFolderPath
}
onMove=
{
this
.
handleMove
}
onUpload=
{
this
.
handleUploadDone
}
onChangePage=
{
this
.
handleChangePage
}
onRefresh=
{
this
.
handleFetchFolderList
}
/>
</
div
>
</
Spin
>
...
...
src/modules/resource-disk/components/FolderList.jsx
View file @
b23fca45
...
...
@@ -21,9 +21,9 @@ import UploadProgressModal from '@/bu-components/UploadProgressModal';
import
SelectPrepareFileModal
from
'@/bu-components/SelectPrepareFileModal'
;
import
CopyFileModal
from
'@/bu-components/CopyFileModal'
;
import
ManagingMembersModal
from
'@/bu-components/ManagingMembersModal'
;
import
PreviewFileModal
from
'
../modal/PreviewFileModal'
import
PreviewFileModal
from
'
@/bu-components/PreviewFileModal'
;
import
{
YZ_APPId
,
YZ_PREVIEW_URL
,
OFFICE_PREVIEW_URL
}
from
'@/domains/basic-domain/constants'
;
import
BaseService
from
"@/domains/basic-domain/baseService"
;
import
ScanFileModal
from
'../modal/ScanFileModal'
;
import
CreateFolderModal
from
'../modal/CreateFolderModal'
;
import
User
from
'@/common/js/user'
;
...
...
@@ -121,40 +121,6 @@ class FolderList extends React.Component {
break
;
}
}
getYoZoSign
=
(
data
,
type
,
folderName
)
=>
{
return
new
Promise
((
resolve
)
=>
{
let
uploadParams
;
if
(
type
===
"UPLOAD"
){
uploadParams
=
{
fileUrl
:
data
,
instId
:
window
.
currentUserInstInfo
.
instId
,
yoZoTypeEnum
:
'UPLOAD'
}
}
else
{
uploadParams
=
{
fileVersionId
:
data
,
instId
:
window
.
currentUserInstInfo
.
instId
,
yoZoTypeEnum
:
'VIEW'
,
htmlTitle
:
folderName
}
}
Service
.
Apollo
(
'public/apollo/getYoZoSign'
,
uploadParams
).
then
(
res
=>
{
const
{
result
=
[]
}
=
res
;
resolve
(
result
)
});
})
}
saveYoZoFileVersionId
=
(
fileVersionId
,
folderId
)
=>
{
const
params
=
{
fileVersionId
,
folderId
,
instId
:
window
.
currentUserInstInfo
.
instId
,
}
Service
.
Apollo
(
'public/apollo/saveYoZoFileVersionId'
,
params
).
then
(
res
=>
{
});
}
// 预览文件
handleScanFile
=
async
(
folder
)
=>
{
const
{
folderFormat
,
folderSize
,
ossUrl
,
rights
,
fileVersionId
,
id
,
folderName
}
=
folder
;
...
...
@@ -177,24 +143,46 @@ class FolderList extends React.Component {
showPreviewModal
:
true
,
previewStatus
:
'UPLOAD'
},
async
()
=>
{
const
uploadSign
=
await
that
.
getYoZoSign
(
ossUrl
,
"UPLOAD"
);
axios
.
post
(
`https://dmc.yozocloud.cn/api/file/http?fileUrl=
${
ossUrl
}
&appId=
${
appId
}
&sign=
${
uploadSign
}
`
)
.
then
(
async
function
(
response
){
that
.
saveYoZoFileVersionId
(
response
.
data
.
data
.
fileVersionId
,
id
);
const
uploadParams
=
{
fileUrl
:
ossUrl
,
instId
:
User
.
getStoreId
(),
yoZoTypeEnum
:
'UPLOAD'
}
const
uploadSign
=
await
BaseService
.
getYoZoSign
(
uploadParams
);
BaseService
.
yoZoUpload
(
ossUrl
,
YZ_APPId
,
uploadSign
).
then
(
async
function
(
response
){
const
saveParams
=
{
fileVersionId
:
response
.
data
.
data
.
fileVersionId
,
folderId
:
id
,
instId
:
User
.
getStoreId
(),
}
BaseService
.
saveYoZoFileVersionId
(
saveParams
);
const
{
previewing
}
=
that
.
state
;
if
(
previewing
){
const
previewSign
=
await
that
.
getYoZoSign
(
response
.
data
.
data
.
fileVersionId
,
"VIEW"
,
folderName
);
const
url
=
`https://eic.yozocloud.cn/api/view/file?fileVersionId=
${
response
.
data
.
data
.
fileVersionId
}
&appId=
${
appId
}
&sign=
${
previewSign
}
&htmlTitle=
${
folderName
}
`
const
previewParams
=
{
fileVersionId
:
response
.
data
.
data
.
fileVersionId
,
instId
:
User
.
getStoreId
(),
yoZoTypeEnum
:
'VIEW'
,
htmlTitle
:
folderName
}
const
previewSign
=
await
BaseService
.
getYoZoSign
(
previewParams
);
const
url
=
`
${
YZ_PREVIEW_URL
}
?fileVersionId=
${
response
.
data
.
data
.
fileVersionId
}
&appId=
${
YZ_APPId
}
&sign=
${
previewSign
}
&htmlTitle=
${
folderName
}
`
that
.
setState
({
previewStatus
:
'UPLOAD_SUCCESS'
,
url
})
}
})
})
}
else
{
const
previewSign
=
await
that
.
getYoZoSign
(
fileVersionId
,
"VIEW"
,
folderName
);
const
url
=
`http://eic.yozocloud.cn/api/view/file?fileVersionId=
${
fileVersionId
}
&appId=
${
appId
}
&sign=
${
previewSign
}
&htmlTitle=
${
folderName
}
`
const
previewParams
=
{
fileVersionId
,
instId
:
User
.
getStoreId
(),
yoZoTypeEnum
:
'VIEW'
,
htmlTitle
:
folderName
}
const
previewSign
=
await
BaseService
.
getYoZoSign
(
previewParams
);
const
url
=
`
${
YZ_PREVIEW_URL
}
?fileVersionId=
${
fileVersionId
}
&appId=
${
YZ_APPId
}
&sign=
${
previewSign
}
&htmlTitle=
${
folderName
}
`
const
a
=
document
.
createElement
(
'a'
);
document
.
body
.
appendChild
(
a
);
a
.
setAttribute
(
'href'
,
url
);
...
...
@@ -234,7 +222,6 @@ class FolderList extends React.Component {
Modal
.
confirm
({
title
:
'抱歉,不能在线预览'
,
content
:
'由于文件较大,不支持在线预览,请下载后再查看'
,
// icon: <Icon type="question-circle" theme="filled" style={{ color: '#FF8534' }}></Icon>,
okText
:
"下载"
,
onOk
:
()
=>
{
const
a
=
document
.
createElement
(
'a'
);
...
...
@@ -244,21 +231,7 @@ class FolderList extends React.Component {
});
break
;
}
// if (folderFormat === 'EXCEL') {
// Modal.confirm({
// title: '抱歉,不能在线预览',
// content: ' 该文件类型不支持在线预览,请下载后再查看',
// // icon: <Icon type="question-circle" theme="filled" style={{ color: '#FF8534' }}></Icon>,
// okText: "下载",
// onOk: () => {
// const a = document.createElement('a');
// a.href = ossUrl;
// a.click();
// }
// });
// break;
// }
const
prefixUrl
=
"https://view.officeapps.live.com/op/view.aspx?src="
;
const
prefixUrl
=
`
${
OFFICE_PREVIEW_URL
}
?src=`
;
const
scanUrl
=
`
${
prefixUrl
}${
encodeURIComponent
(
ossUrl
)}
`
window
.
open
(
scanUrl
,
"_blank"
);
break
;
...
...
src/modules/root/Login.jsx
View file @
b23fca45
...
...
@@ -31,26 +31,9 @@ function Login(props) {
*/
useEffect
(()
=>
{
const
enterpriseId
=
getParameterByName
(
'enterpriseId'
);
const
userId
=
getParameterByName
(
'userId'
);
const
from
=
getParameterByName
(
'from'
);
const
storeId
=
getParameterByName
(
'storeId'
);
if
(
storeId
)
{
User
.
setCustomerStoreId
(
storeId
);
}
if
(
from
===
'customer'
&&
enterpriseId
&&
userId
)
{
if
(
!
user
.
getToken
()
||
enterpriseId
!==
user
.
getEnterpriseId
()
||
userId
!==
User
.
getUserId
())
{
getWXWorkLoginNoCheck
(
enterpriseId
,
userId
);
}
else
{
window
.
RCHistory
.
push
({
pathname
:
`/switch-route`
,
});
}
}
else
{
User
.
removeUserId
();
User
.
removeToken
();
User
.
removeEnterpriseId
();
}
},
[]);
function
getWXWorkLoginNoCheck
(
enterpriseId
,
userId
)
{
const
params
=
{
...
...
src/modules/teach-tool/examination-manager/ExamData.tsx
View file @
b23fca45
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 @
b23fca45
/*
* @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 @
b23fca45
...
...
@@ -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