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
5314960e
Commit
5314960e
authored
Aug 16, 2021
by
yuananting
Browse files
Options
Browse Files
Download
Plain Diff
fix:解决合并代码的冲突
parents
ce5b164f
571796c7
Hide whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1389 additions
and
366 deletions
+1389
-366
src/common/less/icon-font.less
+4
-4
src/domains/basic-domain/constants.ts
+20
-20
src/domains/course-domain/constants.ts
+16
-19
src/h5.html
+2
-2
src/index.html
+2
-2
src/modules/knowledge-base/components/KnowledgeBaseList.jsx
+165
-167
src/modules/knowledge-base/modal/VideoList.jsx
+50
-73
src/modules/task-center/data-center/Index.tsx
+14
-5
src/modules/task-center/data-center/components/DataAnalysic.tsx
+63
-0
src/modules/task-center/data-center/components/ExamData.tsx
+321
-0
src/modules/task-center/data-center/components/ExamTable.tsx
+13
-5
src/modules/task-center/data-center/components/LeftStageList.jsx
+2
-2
src/modules/task-center/data-center/components/StudyTable.tsx
+2
-3
src/modules/task-center/data-center/components/UserData.tsx
+428
-0
src/modules/task-center/data-center/components/dataAnalysic.less
+22
-0
src/modules/task-center/data-center/components/userData.less
+90
-0
src/modules/task-center/train-task/components/RelatedExamDrawer.jsx
+2
-2
src/modules/task-center/train-task/modal/ChooseAssignorModal.jsx
+119
-60
src/modules/task-center/train-task/modal/ChooseAssignorModal.less
+54
-2
No files found.
src/common/less/icon-font.less
View file @
5314960e
@font-face {
@font-face {
font-family: 'iconfont'; /* Project id 2223403 */
font-family: 'iconfont';
/* Project id 2223403 */
src: url('//at.alicdn.com/t/font_2223403_
2digpsfgq8l.woff2?t=1628853864698
') format('woff2'),
src: url('//at.alicdn.com/t/font_2223403_
0b87tvtysw45.woff2?t=1629025918841
') format('woff2'),
url('//at.alicdn.com/t/font_2223403_2digpsfgq8l.woff?t=1628853864698
') format('woff'),
url('//at.alicdn.com/t/font_2223403_0b87tvtysw45.woff?t=1629025918841
') format('woff'),
url('//at.alicdn.com/t/font_2223403_2digpsfgq8l.ttf?t=1628853864698
') format('truetype');
url('//at.alicdn.com/t/font_2223403_0b87tvtysw45.ttf?t=1629025918841
') format('truetype');
}
}
.iconfont {
.iconfont {
font-family: 'iconfont' !important;
font-family: 'iconfont' !important;
...
...
src/domains/basic-domain/constants.ts
View file @
5314960e
/*
/*
* @Author: 陈剑宇
* @Author: 陈剑宇
* @Date: 2020-05-07 14:43:01
* @Date: 2020-05-07 14:43:01
* @LastEditTime: 2021-08-
09 15:52:49
* @LastEditTime: 2021-08-
16 16:39:13
* @LastEditors:
wufan
* @LastEditors:
yuananting
* @Description:
* @Description:
* @FilePath: /wheat-web-demo/src/domains/basic-domain/constants.ts
* @FilePath: /wheat-web-demo/src/domains/basic-domain/constants.ts
*/
*/
import
{
MapInterface
}
from
'@/domains/basic-domain/interface'
import
{
MapInterface
}
from
'@/domains/basic-domain/interface'
;
import
{
path
,
live
}
from
'@/domains/brand/constants'
import
{
path
,
live
}
from
'@/domains/brand/constants'
;
// 默认是 dev 环境
// 默认是 dev 环境
const
ENV
:
string
=
process
.
env
.
DEPLOY_ENV
||
'dev'
const
ENV
:
string
=
process
.
env
.
DEPLOY_ENV
||
'dev'
;
console
.
log
(
'process.env.DEPLOY_ENV'
,
process
.
env
,
ENV
,
'hjkkkk'
)
console
.
log
(
'process.env.DEPLOY_ENV'
,
process
.
env
,
ENV
,
'hjkkkk'
);
console
.
log
(
'process.env.DEPLOY_ENV'
,
process
);
const
BASIC_HOST_MAP
:
MapInterface
=
{
const
BASIC_HOST_MAP
:
MapInterface
=
{
dev
:
'https://dev-heimdall.xiaomai5.com/'
,
dev
:
'https://dev-heimdall.xiaomai5.com/'
,
dev1
:
'https://dev-heimdall.xiaomai5.com/'
,
dev1
:
'https://dev-heimdall.xiaomai5.com/'
,
rc
:
'https://rc-heimdall.xiaomai5.com/'
,
rc
:
'https://rc-heimdall.xiaomai5.com/'
,
gray
:
'https://gray-heimdall.xiaomai5.com/'
,
gray
:
'https://gray-heimdall.xiaomai5.com/'
,
prod
:
'https://gateway.xiaomai5.com/'
,
prod
:
'https://gateway.xiaomai5.com/'
,
}
}
;
const
PATH_MAP
:
MapInterface
=
{
const
PATH_MAP
:
MapInterface
=
{
dev
:
'https://dev.xiaomai5.com/xiaomai-cloud-class-web/h5.html'
,
dev
:
'https://dev.xiaomai5.com/xiaomai-cloud-class-web/h5.html'
,
dev1
:
'https://dev.xiaomai5.com/dev1/xiaomai-cloud-class-web/h5.html'
,
dev1
:
'https://dev.xiaomai5.com/dev1/xiaomai-cloud-class-web/h5.html'
,
rc
:
'https://rc.xiaomai5.com/xiaomai-cloud-class-web/h5.html'
,
rc
:
'https://rc.xiaomai5.com/xiaomai-cloud-class-web/h5.html'
,
gray
:
path
+
'/gray/h5.html'
,
gray
:
path
+
'/gray/h5.html'
,
prod
:
path
+
'/h5.html'
,
prod
:
path
+
'/h5.html'
,
}
}
;
export
const
YZ_APPId
=
"yozoqvpO2Hvz8346"
;
export
const
YZ_APPId
=
'yozoqvpO2Hvz8346'
;
export
const
YZ_PREVIEW_URL
:
string
=
'http://eic.yozocloud.cn/api/view/file'
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'
export
const
OFFICE_PREVIEW_URL
:
string
=
'https://view.officeapps.live.com/op/view.aspx'
;
// axios headers config
// axios headers config
export
const
TIME_OUT
:
number
=
20000
export
const
TIME_OUT
:
number
=
20000
;
export
const
USER_TYPE
:
string
=
'B'
export
const
USER_TYPE
:
string
=
'B'
;
export
const
PROJECT
=
'xmzj-web-b'
export
const
PROJECT
=
'xmzj-web-b'
;
export
const
VERSION
=
'5.4.8'
export
const
VERSION
=
'5.4.8'
;
export
const
PREFIX
=
'cloud-class'
export
const
PREFIX
=
'cloud-class'
;
export
const
USER_PREFIX
=
'store-live'
export
const
USER_PREFIX
=
'store-live'
;
// host
// host
export
const
BASIC_HOST
:
string
=
BASIC_HOST_MAP
[
ENV
]
export
const
BASIC_HOST
:
string
=
BASIC_HOST_MAP
[
ENV
];
export
const
PATH
:
string
=
PATH_MAP
[
ENV
]
export
const
PATH
:
string
=
PATH_MAP
[
ENV
];
src/domains/course-domain/constants.ts
View file @
5314960e
/*
/*
* @Author: 吴文洁
* @Author: 吴文洁
* @Date: 2020-08-20 09:21:40
* @Date: 2020-08-20 09:21:40
* @LastEditors:
Please set LastEditors
* @LastEditors:
yuananting
* @LastEditTime: 2021-08-1
1 22:50:48
* @LastEditTime: 2021-08-1
6 16:38:55
* @Description:
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
*/
import
{
MapInterface
}
from
'@/domains/basic-domain/interface'
import
{
MapInterface
}
from
'@/domains/basic-domain/interface'
;
import
{
path
,
live
}
from
'@/domains/brand/constants'
import
{
path
,
live
}
from
'@/domains/brand/constants'
;
const
ENV
:
string
=
process
.
env
.
DEPLOY_ENV
||
'dev'
;
const
ENV
:
string
=
process
.
env
.
DEPLOY_ENV
||
'dev'
;
const
appIdMap
:
MapInterface
=
{
const
appIdMap
:
MapInterface
=
{
dev
:
'wx3ea60e78ddfa277e'
,
dev
:
'wx3ea60e78ddfa277e'
,
dev1
:
'wx3ea60e78ddfa277e'
,
dev1
:
'wx3ea60e78ddfa277e'
,
rc
:
'wx5c5a1fb71ecab7bc'
,
rc
:
'wx5c5a1fb71ecab7bc'
,
gray
:
"wx3dda02036493ada6"
,
// 小麦校讯通
gray
:
'wx3dda02036493ada6'
,
// 小麦校讯通
prod
:
'wx3dda02036493ada6'
,
prod
:
'wx3dda02036493ada6'
,
}
}
;
const
shareUrlMap
:
MapInterface
=
{
const
shareUrlMap
:
MapInterface
=
{
'dev'
:
'https://dev.xiaomai5.com/share/show?appid='
,
dev
:
'https://dev.xiaomai5.com/share/show?appid='
,
'dev1'
:
'https://dev.xiaomai5.com/share/show?appid='
,
dev1
:
'https://dev.xiaomai5.com/share/show?appid='
,
'rc'
:
'https://rc.xiaomai5.com/share/show?appid='
,
rc
:
'https://rc.xiaomai5.com/share/show?appid='
,
'prod'
:
'https://prod.xiaomai5.com/share/show?appid='
,
prod
:
'https://prod.xiaomai5.com/share/show?appid='
,
'gray'
:
'https://prod.xiaomai5.com/share/show?appid='
,
gray
:
'https://prod.xiaomai5.com/share/show?appid='
,
}
}
;
const
LIVE_SHARE_MAP
:
MapInterface
=
{
const
LIVE_SHARE_MAP
:
MapInterface
=
{
dev
:
'https://dev.xiaomai5.com/store-live/index.html#/'
,
dev
:
'https://dev.xiaomai5.com/store-live/index.html#/'
,
dev1
:
'https://dev.xiaomai5.com/dev1/store-live/index.html#/'
,
dev1
:
'https://dev.xiaomai5.com/dev1/store-live/index.html#/'
,
rc
:
'https://rc.xiaomai5.com/store-live/index.html#/'
,
rc
:
'https://rc.xiaomai5.com/store-live/index.html#/'
,
gray
:
live
+
'/gray/index.html#/'
,
gray
:
live
+
'/gray/index.html#/'
,
prod
:
live
+
'/index.html#/'
,
prod
:
live
+
'/index.html#/'
,
}
};
export
const
appId
:
string
=
appIdMap
[
ENV
];
export
const
appId
:
string
=
appIdMap
[
ENV
];
export
const
shareUrl
:
string
=
shareUrlMap
[
ENV
];
export
const
shareUrl
:
string
=
shareUrlMap
[
ENV
];
...
...
src/h5.html
View file @
5314960e
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Author: 吴文洁
* @Date: 2020-08-24 12:20:57
* @Date: 2020-08-24 12:20:57
* @LastEditors: wufan
* @LastEditors: wufan
* @LastEditTime: 2021-08-1
3 19:25:12
* @LastEditTime: 2021-08-1
5 19:12:48
* @Description:
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
* @Copyright: 杭州杰竞科技有限公司 版权所有
-->
-->
...
@@ -25,7 +25,7 @@
...
@@ -25,7 +25,7 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
-->
<link
rel=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
2digpsfgq8l
.css"
>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
0b87tvtysw45
.css"
>
<!--
<!--
Notice the use of %PUBLIC_URL% in the tags above.
Notice the use of %PUBLIC_URL% in the tags above.
...
...
src/index.html
View file @
5314960e
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Author: 吴文洁
* @Date: 2020-08-24 12:20:57
* @Date: 2020-08-24 12:20:57
* @LastEditors: wufan
* @LastEditors: wufan
* @LastEditTime: 2021-08-1
3 19:25:18
* @LastEditTime: 2021-08-1
5 19:12:55
* @Description:
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
* @Copyright: 杭州杰竞科技有限公司 版权所有
-->
-->
...
@@ -30,7 +30,7 @@
...
@@ -30,7 +30,7 @@
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
-->
<link
rel=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"manifest"
href=
"%PUBLIC_URL%/manifest.json"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
2digpsfgq8l
.css"
/>
<link
rel=
"stylesheet"
href=
"//at.alicdn.com/t/font_2223403_
0b87tvtysw45
.css"
/>
<!--
<!--
Notice the use of %PUBLIC_URL% in the tags above.
Notice the use of %PUBLIC_URL% in the tags above.
...
...
src/modules/knowledge-base/components/KnowledgeBaseList.jsx
View file @
5314960e
...
@@ -3,198 +3,199 @@
...
@@ -3,198 +3,199 @@
* @Author: zangsuyun
* @Author: zangsuyun
* @Date: 2021-03-12 14:49:40
* @Date: 2021-03-12 14:49:40
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-0
7-18 16:58:23
* @LastEditTime: 2021-0
8-16 16:38:44
* @Copyright: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyright: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
import
React
from
"react"
;
import
React
from
'react'
;
import
{
Modal
,
message
,
Tooltip
,
Switch
,
Dropdown
,
Button
}
from
"antd"
;
import
{
Modal
,
message
,
Tooltip
,
Switch
,
Dropdown
,
Button
}
from
'antd'
;
import
{
FileTypeIcon
,
FileVerifyMap
}
from
'@/common/constants/academic/lessonEnum'
;
import
{
FileTypeIcon
,
FileVerifyMap
}
from
'@/common/constants/academic/lessonEnum'
;
import
{
Route
,
withRouter
}
from
"react-router-dom"
;
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
{
PageControl
,
XMTable
}
from
"@/components"
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
{
LIVE_SHARE_MAP
}
from
"@/common/constants/academic/cloudClass"
;
import
{
LIVE_SHARE_MAP
}
from
'@/common/constants/academic/cloudClass'
;
import
{
appId
,
shareUrl
,
LIVE_SHARE
}
from
"@/domains/course-domain/constants"
;
import
{
appId
,
shareUrl
,
LIVE_SHARE
}
from
'@/domains/course-domain/constants'
;
import
ScanFileModal
from
"../../resource-disk/modal/ScanFileModal"
;
import
ScanFileModal
from
'../../resource-disk/modal/ScanFileModal'
;
import
WatchData
from
"./WatchData"
;
import
WatchData
from
'./WatchData'
;
import
KnowledgeAPI
from
"@/data-source/knowledge/request-api"
;
import
KnowledgeAPI
from
'@/data-source/knowledge/request-api'
;
import
ENUM
from
"../ENUM.js"
;
import
ENUM
from
'../ENUM.js'
;
import
"./KnowledgeBaseList.less"
;
import
'./KnowledgeBaseList.less'
;
const
DEFAULT_SIZE_UNIT
=
1000
*
1000
// 将B转换成M
const
DEFAULT_SIZE_UNIT
=
1000
*
1000
;
// 将B转换成M
const
{
confirm
}
=
Modal
const
{
confirm
}
=
Modal
;
const
ENV
=
process
.
env
.
DEPLOY_ENV
||
'dev'
;
class
KnowledgeBaseList
extends
React
.
Component
{
class
KnowledgeBaseList
extends
React
.
Component
{
constructor
(
props
)
{
constructor
(
props
)
{
super
(
props
)
super
(
props
)
;
this
.
state
=
{
this
.
state
=
{
id
:
""
,
id
:
''
,
scanFileModal
:
null
scanFileModal
:
null
,
}
}
;
}
}
handleAdminName
=
(
adminArray
)
=>
{
handleAdminName
=
(
adminArray
)
=>
{
let
adminStr
=
""
let
adminStr
=
''
;
adminArray
.
map
((
item
,
index
)
=>
{
adminArray
.
map
((
item
,
index
)
=>
{
if
(
index
<
adminArray
.
length
-
1
)
{
if
(
index
<
adminArray
.
length
-
1
)
{
adminStr
=
adminStr
+
item
.
adminName
+
"、"
adminStr
=
adminStr
+
item
.
adminName
+
'、'
;
}
else
{
}
else
{
adminStr
=
adminStr
+
item
.
adminName
adminStr
=
adminStr
+
item
.
adminName
;
}
}
})
})
;
return
adminStr
return
adminStr
;
}
}
;
handleUp
=
(
index
,
record
)
=>
{
handleUp
=
(
index
,
record
)
=>
{
if
(
index
===
0
&&
this
.
props
.
query
.
current
===
1
)
{
if
(
index
===
0
&&
this
.
props
.
query
.
current
===
1
)
{
return
return
;
}
}
const
params
=
{
const
params
=
{
direction
:
"UP"
,
direction
:
'UP'
,
id
:
record
.
id
,
id
:
record
.
id
,
storeId
:
record
.
storeId
storeId
:
record
.
storeId
,
}
}
;
KnowledgeAPI
.
moveKnowledge
(
params
).
then
((
res
)
=>
{
KnowledgeAPI
.
moveKnowledge
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
res
.
success
)
{
message
.
success
(
"更新成功"
)
message
.
success
(
'更新成功'
);
this
.
props
.
onChange
()
this
.
props
.
onChange
()
;
}
}
})
})
;
}
}
;
handleDown
=
(
record
,
index
)
=>
{
handleDown
=
(
record
,
index
)
=>
{
const
{
query
,
totalCount
}
=
this
.
props
const
{
query
,
totalCount
}
=
this
.
props
;
const
{
current
,
size
}
=
query
const
{
current
,
size
}
=
query
;
if
(
totalCount
===
size
*
(
current
-
1
)
+
index
+
1
)
{
if
(
totalCount
===
size
*
(
current
-
1
)
+
index
+
1
)
{
return
return
;
}
}
const
params
=
{
const
params
=
{
direction
:
"DOWN"
,
direction
:
'DOWN'
,
id
:
record
.
id
,
id
:
record
.
id
,
storeId
:
record
.
storeId
storeId
:
record
.
storeId
,
}
}
;
KnowledgeAPI
.
moveKnowledge
(
params
).
then
((
res
)
=>
{
KnowledgeAPI
.
moveKnowledge
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
res
.
success
)
{
message
.
success
(
"更新成功"
)
message
.
success
(
'更新成功'
);
this
.
props
.
onChange
()
this
.
props
.
onChange
()
;
}
}
})
})
;
}
}
;
getBlob
=
(
url
)
=>
{
getBlob
=
(
url
)
=>
{
return
new
Promise
((
resolve
)
=>
{
return
new
Promise
((
resolve
)
=>
{
const
xhr
=
new
XMLHttpRequest
()
const
xhr
=
new
XMLHttpRequest
()
;
xhr
.
open
(
"GET"
,
url
,
true
)
xhr
.
open
(
'GET'
,
url
,
true
);
xhr
.
responseType
=
"blob"
xhr
.
responseType
=
'blob'
;
xhr
.
onload
=
()
=>
{
xhr
.
onload
=
()
=>
{
if
(
xhr
.
status
===
200
)
{
if
(
xhr
.
status
===
200
)
{
resolve
(
xhr
.
response
)
resolve
(
xhr
.
response
)
;
}
}
}
}
;
xhr
.
send
()
xhr
.
send
()
;
})
})
;
}
}
;
saveAs
=
(
blob
,
filename
)
=>
{
saveAs
=
(
blob
,
filename
)
=>
{
if
(
window
.
navigator
.
msSaveOrOpenBlob
)
{
if
(
window
.
navigator
.
msSaveOrOpenBlob
)
{
navigator
.
msSaveBlob
(
blob
,
filename
)
navigator
.
msSaveBlob
(
blob
,
filename
)
;
}
else
{
}
else
{
const
link
=
document
.
createElement
(
"a"
)
const
link
=
document
.
createElement
(
'a'
);
const
body
=
document
.
querySelector
(
"body"
)
const
body
=
document
.
querySelector
(
'body'
);
// 创建对象url
// 创建对象url
link
.
href
=
window
.
URL
.
createObjectURL
(
blob
)
link
.
href
=
window
.
URL
.
createObjectURL
(
blob
)
;
link
.
download
=
filename
link
.
download
=
filename
;
body
.
appendChild
(
link
)
body
.
appendChild
(
link
)
;
link
.
click
()
link
.
click
()
;
body
.
removeChild
(
link
)
body
.
removeChild
(
link
)
;
// 通过调用 URL.createObjectURL() 创建的 URL 对象
// 通过调用 URL.createObjectURL() 创建的 URL 对象
window
.
URL
.
revokeObjectURL
(
link
.
href
)
window
.
URL
.
revokeObjectURL
(
link
.
href
)
;
}
}
}
}
;
// 下载文件
// 下载文件
handleDownload
=
(
folder
)
=>
{
handleDownload
=
(
folder
)
=>
{
this
.
getBlob
(
folder
.
ossUrl
).
then
((
blob
)
=>
{
this
.
getBlob
(
folder
.
ossUrl
).
then
((
blob
)
=>
{
this
.
saveAs
(
blob
,
folder
.
folderName
)
this
.
saveAs
(
blob
,
folder
.
folderName
)
;
})
})
;
}
}
;
// 预览文件
// 预览文件
handleScanFile
=
(
folder
)
=>
{
handleScanFile
=
(
folder
)
=>
{
const
{
folderFormat
,
folderSize
,
ossUrl
}
=
folder
;
const
{
folderFormat
,
folderSize
,
ossUrl
}
=
folder
;
switch
(
folderFormat
)
{
switch
(
folderFormat
)
{
case
"PDF"
:
case
'PDF'
:
window
.
open
(
ossUrl
,
"_blank"
)
window
.
open
(
ossUrl
,
'_blank'
);
break
break
;
case
"WORD"
:
case
'WORD'
:
case
"DOCX"
:
case
'DOCX'
:
case
"DOC"
:
case
'DOC'
:
case
"EXCEL"
:
case
'EXCEL'
:
case
"PPT"
:
case
'PPT'
:
case
"PPTX"
:
case
'PPTX'
:
case
"PDF"
:
case
'PDF'
:
if
(
if
(
((
folderFormat
===
"PPT"
||
folderFormat
===
"PPTX"
||
folderFormat
===
"DOCX"
||
folderFormat
===
"WORD"
||
folderFormat
===
"DOC"
)
&&
((
folderFormat
===
'PPT'
||
folderFormat
===
'PPTX'
||
folderFormat
===
'DOCX'
||
folderFormat
===
'WORD'
||
folderFormat
===
'DOC'
)
&&
folderSize
>
10
*
DEFAULT_SIZE_UNIT
)
||
folderSize
>
10
*
DEFAULT_SIZE_UNIT
)
||
(
folderFormat
===
"EXCEL"
&&
folderSize
>
5
*
DEFAULT_SIZE_UNIT
)
(
folderFormat
===
'EXCEL'
&&
folderSize
>
5
*
DEFAULT_SIZE_UNIT
)
)
{
)
{
Modal
.
confirm
({
Modal
.
confirm
({
title
:
"抱歉,不能在线预览"
,
title
:
'抱歉,不能在线预览'
,
content
:
"由于文件较大,不支持在线预览,请下载后再查看"
,
content
:
'由于文件较大,不支持在线预览,请下载后再查看'
,
// icon: <Icon type="question-circle" theme="filled" style={{ color: '#FF8534' }}></Icon>,
// icon: <Icon type="question-circle" theme="filled" style={{ color: '#FF8534' }}></Icon>,
cancelText
:
"取消"
,
cancelText
:
'取消'
,
okText
:
"下载"
,
okText
:
'下载'
,
onOk
:
()
=>
{
onOk
:
()
=>
{
this
.
handleDownload
(
folder
)
this
.
handleDownload
(
folder
)
;
}
}
,
})
})
;
break
break
;
}
}
const
prefixUrl
=
"https://view.officeapps.live.com/op/view.aspx?src="
const
prefixUrl
=
'https://view.officeapps.live.com/op/view.aspx?src='
;
const
scanUrl
=
`
${
prefixUrl
}${
encodeURIComponent
(
ossUrl
)}
`
const
scanUrl
=
`
${
prefixUrl
}${
encodeURIComponent
(
ossUrl
)}
`
;
window
.
open
(
scanUrl
,
"_blank"
)
window
.
open
(
scanUrl
,
'_blank'
);
break
break
;
default
:
default
:
const
scanFileModal
=
(
const
scanFileModal
=
(
<
ScanFileModal
<
ScanFileModal
fileType=
{
folderFormat
}
fileType=
{
folderFormat
}
item=
{
folder
}
item=
{
folder
}
close=
{
()
=>
{
close=
{
()
=>
{
this
.
setState
({
scanFileModal
:
null
})
this
.
setState
({
scanFileModal
:
null
})
;
}
}
}
}
/>
/>
)
)
;
this
.
setState
({
scanFileModal
})
this
.
setState
({
scanFileModal
})
;
break
break
;
}
}
}
}
;
// 请求表头
// 请求表头
parseColumns
=
()
=>
{
parseColumns
=
()
=>
{
const
{
query
,
totalCount
}
=
this
.
props
const
{
query
,
totalCount
}
=
this
.
props
;
const
{
current
,
size
}
=
query
const
{
current
,
size
}
=
query
;
const
columns
=
[
const
columns
=
[
{
{
title
:
"名称"
,
title
:
'名称'
,
key
:
"name"
,
key
:
'name'
,
dataIndex
:
"name"
,
dataIndex
:
'name'
,
render
:
(
val
,
record
)
=>
{
render
:
(
val
,
record
)
=>
{
const
{
coverUrl
,
mediaCourseUrl
,
courseDivision
}
=
record
.
source
const
{
coverUrl
,
mediaCourseUrl
,
courseDivision
}
=
record
.
source
;
let
hasCover
=
false
let
hasCover
=
false
;
const
type
=
record
.
type
const
type
=
record
.
type
;
return
(
return
(
<
div
<
div
className=
'record__item'
className=
'record__item'
onClick=
{
()
=>
{
onClick=
{
()
=>
{
this
.
handleScanFile
(
record
.
source
)
this
.
handleScanFile
(
record
.
source
)
;
}
}
>
}
}
>
<
img
src=
{
FileTypeIcon
[
record
.
source
.
folderFormat
]
}
style=
{
{
width
:
24
,
height
:
24
}
}
alt=
''
className=
'item-img'
/>
<
img
src=
{
FileTypeIcon
[
record
.
source
.
folderFormat
]
}
style=
{
{
width
:
24
,
height
:
24
}
}
alt=
''
className=
'item-img'
/>
{
val
.
length
>
25
?
(
{
val
.
length
>
25
?
(
<
Tooltip
title=
{
val
}
>
<
Tooltip
title=
{
val
}
>
<
div
className=
'course-name clamp'
>
{
val
}
</
div
>
<
div
className=
'course-name clamp'
>
{
val
}
</
div
>
...
@@ -203,15 +204,14 @@ class KnowledgeBaseList extends React.Component {
...
@@ -203,15 +204,14 @@ class KnowledgeBaseList extends React.Component {
<
div
className=
'course-name clamp'
>
{
val
}
</
div
>
<
div
className=
'course-name clamp'
>
{
val
}
</
div
>
)
}
)
}
</
div
>
</
div
>
);
)
},
}
},
},
{
{
title
:
"创建人"
,
title
:
'创建人'
,
key
:
"createName"
,
key
:
'createName'
,
dataIndex
:
"createName"
,
dataIndex
:
'createName'
,
align
:
"center"
,
align
:
'center'
,
render
:
(
val
)
=>
{
render
:
(
val
)
=>
{
return
(
return
(
<
div
>
<
div
>
...
@@ -221,36 +221,35 @@ class KnowledgeBaseList extends React.Component {
...
@@ -221,36 +221,35 @@ class KnowledgeBaseList extends React.Component {
</
Tooltip
>
</
Tooltip
>
)
}
)
}
</
div
>
</
div
>
)
)
;
}
}
,
},
},
{
{
title
:
"观看学员数"
,
title
:
'观看学员数'
,
key
:
"watchUserCount"
,
key
:
'watchUserCount'
,
dataIndex
:
"watchUserCount"
,
dataIndex
:
'watchUserCount'
,
align
:
"right"
,
align
:
'right'
,
render
:
(
val
,
item
)
=>
{
render
:
(
val
,
item
)
=>
{
return
val
?
(
return
val
?
(
<
div
className=
'operate'
style=
{
{
display
:
"block"
}
}
onClick=
{
()
=>
this
.
handleLinkToClassData
(
item
)
}
>
<
div
className=
'operate'
style=
{
{
display
:
'block'
}
}
onClick=
{
()
=>
this
.
handleLinkToClassData
(
item
)
}
>
<
span
className=
'operate__item'
>
{
val
}
</
span
>
<
span
className=
'operate__item'
>
{
val
}
</
span
>
</
div
>
</
div
>
)
:
(
)
:
(
0
0
)
)
;
}
}
,
},
},
{
{
title
:
""
,
title
:
''
,
},
},
{
{
title
:
"操作"
,
title
:
'操作'
,
key
:
"operate"
,
key
:
'operate'
,
dataIndex
:
"operate"
,
dataIndex
:
'operate'
,
width
:
160
,
width
:
160
,
fixed
:
"right"
,
fixed
:
'right'
,
render
:
(
val
,
record
,
index
)
=>
{
render
:
(
val
,
record
,
index
)
=>
{
return
this
.
props
.
categoryId
===
"0"
?
(
return
this
.
props
.
categoryId
===
'0'
?
(
<
div
className=
'operate'
>
<
div
className=
'operate'
>
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleDelete
(
record
)
}
>
<
div
className=
'operate__item'
onClick=
{
()
=>
this
.
handleDelete
(
record
)
}
>
移出
移出
...
@@ -258,12 +257,12 @@ class KnowledgeBaseList extends React.Component {
...
@@ -258,12 +257,12 @@ class KnowledgeBaseList extends React.Component {
</
div
>
</
div
>
)
:
(
)
:
(
<
div
className=
'operate'
>
<
div
className=
'operate'
>
<
div
className=
{
index
===
0
&&
current
===
1
?
"operate__item disable"
:
"operate__item"
}
onClick=
{
()
=>
this
.
handleUp
(
index
,
record
)
}
>
<
div
className=
{
index
===
0
&&
current
===
1
?
'operate__item disable'
:
'operate__item'
}
onClick=
{
()
=>
this
.
handleUp
(
index
,
record
)
}
>
上移
上移
</
div
>
</
div
>
<
span
className=
'operate__item split'
>
|
</
span
>
<
span
className=
'operate__item split'
>
|
</
span
>
<
div
<
div
className=
{
totalCount
===
size
*
(
current
-
1
)
+
index
+
1
?
"operate__item disable"
:
"operate__item"
}
className=
{
totalCount
===
size
*
(
current
-
1
)
+
index
+
1
?
'operate__item disable'
:
'operate__item'
}
onClick=
{
()
=>
this
.
handleDown
(
record
,
index
)
}
>
onClick=
{
()
=>
this
.
handleDown
(
record
,
index
)
}
>
下移
下移
</
div
>
</
div
>
...
@@ -272,64 +271,64 @@ class KnowledgeBaseList extends React.Component {
...
@@ -272,64 +271,64 @@ class KnowledgeBaseList extends React.Component {
移出
移出
</
div
>
</
div
>
</
div
>
</
div
>
)
)
;
}
}
,
}
}
,
]
]
;
return
columns
return
columns
;
}
}
;
handleDelete
=
(
record
)
=>
{
handleDelete
=
(
record
)
=>
{
return
confirm
({
return
confirm
({
title
:
"移出知识"
,
title
:
'移出知识'
,
content
:
"确定将分类中此知识移出吗?"
,
content
:
'确定将分类中此知识移出吗?'
,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
icon
:
<
span
className=
'icon iconfont default-confirm-icon'
>

</
span
>,
okText
:
"删除"
,
okText
:
'删除'
,
okType
:
"danger"
,
okType
:
'danger'
,
cancelText
:
"取消"
,
cancelText
:
'取消'
,
width
:
440
,
width
:
440
,
height
:
188
,
height
:
188
,
onOk
:
()
=>
{
onOk
:
()
=>
{
this
.
deleteConfirm
(
record
)
this
.
deleteConfirm
(
record
)
;
}
}
,
})
})
;
}
}
;
// 前往上课数据页面
// 前往上课数据页面
handleLinkToClassData
=
(
item
)
=>
{
handleLinkToClassData
=
(
item
)
=>
{
const
{
match
}
=
this
.
props
;
const
{
match
}
=
this
.
props
;
localStorage
.
setItem
(
"WatchData_CourseName"
,
item
.
name
);
localStorage
.
setItem
(
'WatchData_CourseName'
,
item
.
name
);
window
.
RCHistory
.
push
({
window
.
RCHistory
.
push
({
pathname
:
`
${
match
.
url
}
/course-data?type=
${
item
.
type
}
&id=
${
item
.
id
}
`
pathname
:
`
${
match
.
url
}
/course-data?type=
${
item
.
type
}
&id=
${
item
.
id
}
`
,
})
})
;
}
}
;
deleteConfirm
=
(
item
)
=>
{
deleteConfirm
=
(
item
)
=>
{
const
params
=
{
const
params
=
{
id
:
item
.
id
,
id
:
item
.
id
,
storeId
:
item
.
storeId
storeId
:
item
.
storeId
,
}
}
;
KnowledgeAPI
.
delKnowledge
(
params
).
then
((
res
)
=>
{
KnowledgeAPI
.
delKnowledge
(
params
).
then
((
res
)
=>
{
if
(
res
.
success
)
{
if
(
res
.
success
)
{
const
{
onChange
,
updateCategoryTree
,
selectedRowKeys
,
onSelectChange
}
=
this
.
props
;
const
{
onChange
,
updateCategoryTree
,
selectedRowKeys
,
onSelectChange
}
=
this
.
props
;
message
.
success
(
"移出成功"
);
message
.
success
(
'移出成功'
);
onChange
();
onChange
();
updateCategoryTree
();
updateCategoryTree
();
if
(
selectedRowKeys
.
includes
(
item
.
id
))
{
if
(
selectedRowKeys
.
includes
(
item
.
id
))
{
onSelectChange
(
_
.
reject
(
selectedRowKeys
,
value
=>
value
===
item
.
id
));
onSelectChange
(
_
.
reject
(
selectedRowKeys
,
(
value
)
=>
value
===
item
.
id
));
}
}
}
}
})
})
;
}
}
;
onShowSizeChange
=
(
current
,
size
)
=>
{
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
if
(
current
==
size
)
{
return
return
;
}
}
let
_query
=
this
.
props
.
query
let
_query
=
this
.
props
.
query
;
_query
.
size
=
size
_query
.
size
=
size
;
this
.
props
.
onChange
(
_query
)
this
.
props
.
onChange
(
_query
)
;
}
}
;
render
()
{
render
()
{
const
{
dataSource
=
[],
totalCount
,
query
,
match
,
selectedRowKeys
,
onSelectChange
}
=
this
.
props
;
const
{
dataSource
=
[],
totalCount
,
query
,
match
,
selectedRowKeys
,
onSelectChange
}
=
this
.
props
;
...
@@ -338,21 +337,20 @@ class KnowledgeBaseList extends React.Component {
...
@@ -338,21 +337,20 @@ class KnowledgeBaseList extends React.Component {
selectedRowKeys
,
selectedRowKeys
,
preserveSelectedRowKeys
:
true
,
preserveSelectedRowKeys
:
true
,
onChange
:
onSelectChange
,
onChange
:
onSelectChange
,
}
}
;
return
(
return
(
<
div
className=
"knowledge-base-list"
>
<
div
className=
'knowledge-base-list'
>
<
XMTable
<
XMTable
rowKey=
{
(
record
)
=>
record
.
id
}
rowKey=
{
(
record
)
=>
record
.
id
}
rowSelection=
{
rowSelection
}
rowSelection=
{
rowSelection
}
size=
"middle"
size=
'middle'
dataSource=
{
dataSource
}
dataSource=
{
dataSource
}
columns=
{
this
.
parseColumns
()
}
columns=
{
this
.
parseColumns
()
}
pagination=
{
false
}
pagination=
{
false
}
bordered
bordered
className=
"knowledge-list-table"
className=
'knowledge-list-table'
renderEmpty=
{
{
renderEmpty=
{
{
description
:
<
span
style=
{
{
display
:
'block'
,
paddingBottom
:
24
}
}
>
暂无数据
</
span
>
description
:
<
span
style=
{
{
display
:
'block'
,
paddingBottom
:
24
}
}
>
暂无数据
</
span
>
,
}
}
}
}
/>
/>
...
@@ -363,8 +361,8 @@ class KnowledgeBaseList extends React.Component {
...
@@ -363,8 +361,8 @@ class KnowledgeBaseList extends React.Component {
pageSize=
{
size
}
pageSize=
{
size
}
total=
{
totalCount
}
total=
{
totalCount
}
toPage=
{
(
page
)
=>
{
toPage=
{
(
page
)
=>
{
const
_query
=
{
...
query
,
current
:
page
+
1
}
const
_query
=
{
...
query
,
current
:
page
+
1
}
;
this
.
props
.
onChange
(
_query
)
this
.
props
.
onChange
(
_query
)
;
}
}
}
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
onShowSizeChange=
{
this
.
onShowSizeChange
}
/>
/>
...
@@ -375,8 +373,8 @@ class KnowledgeBaseList extends React.Component {
...
@@ -375,8 +373,8 @@ class KnowledgeBaseList extends React.Component {
{
this
.
state
.
scanFileModal
}
{
this
.
state
.
scanFileModal
}
</
div
>
</
div
>
)
)
;
}
}
}
}
export
default
withRouter
(
KnowledgeBaseList
)
export
default
withRouter
(
KnowledgeBaseList
)
;
src/modules/knowledge-base/modal/VideoList.jsx
View file @
5314960e
...
@@ -2,29 +2,30 @@
...
@@ -2,29 +2,30 @@
* @Description:
* @Description:
* @Author: zangsuyun
* @Author: zangsuyun
* @Date: 2021-03-13 11:48:24
* @Date: 2021-03-13 11:48:24
* @LastEditors:
wufan
* @LastEditors:
yuananting
* @LastEditTime: 2021-08-
09 15:53:08
* @LastEditTime: 2021-08-
16 16:38:20
* @Copyright: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyright: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
import
React
from
"react"
;
import
React
from
'react'
;
import
{
Table
,
Modal
,
message
,
Tooltip
,
Switch
,
Dropdown
}
from
"antd"
;
import
{
Table
,
Modal
,
message
,
Tooltip
,
Switch
,
Dropdown
}
from
'antd'
;
import
{
PageControl
}
from
"@/components"
;
import
{
PageControl
}
from
'@/components'
;
import
_
from
"underscore"
;
import
_
from
'underscore'
;
import
{
LIVE_SHARE_MAP
}
from
"@/common/constants/academic/cloudClass"
;
import
{
LIVE_SHARE_MAP
}
from
'@/common/constants/academic/cloudClass'
;
import
{
appId
,
shareUrl
,
LIVE_SHARE
}
from
"@/domains/course-domain/constants"
;
import
{
appId
,
shareUrl
,
LIVE_SHARE
}
from
'@/domains/course-domain/constants'
;
import
TableSelectedData
from
"@/components/TableSelectedData"
;
import
TableSelectedData
from
'@/components/TableSelectedData'
;
import
"./LiveList.less"
;
import
'./LiveList.less'
;
import
CourseService
from
"@/domains/course-domain/CourseService"
;
import
CourseService
from
'@/domains/course-domain/CourseService'
;
import
User
from
"@/common/js/user"
;
import
User
from
'@/common/js/user'
;
const
ENV
=
process
.
env
.
DEPLOY_ENV
||
'dev'
;
class
VideoList
extends
React
.
Component
{
class
VideoList
extends
React
.
Component
{
constructor
(
props
)
{
constructor
(
props
)
{
super
(
props
);
super
(
props
);
this
.
state
=
{
this
.
state
=
{
id
:
""
,
// 线上课ID
id
:
''
,
// 线上课ID
studentIds
:
[],
studentIds
:
[],
selectedRowKeys
:
[],
selectedRowKeys
:
[],
query
:
{
query
:
{
...
@@ -40,8 +41,7 @@ class VideoList extends React.Component {
...
@@ -40,8 +41,7 @@ class VideoList extends React.Component {
componentDidUpdate
(
prevProps
,
prevState
)
{
componentDidUpdate
(
prevProps
,
prevState
)
{
//必须写在if里面并且重新进行一次this.props !== prevProps的判断
//必须写在if里面并且重新进行一次this.props !== prevProps的判断
if
(
if
(
((
this
.
props
.
courseName
||
this
.
props
.
courseType
)
&&
((
this
.
props
.
courseName
||
this
.
props
.
courseType
)
&&
this
.
props
.
courseName
!==
prevProps
.
courseName
)
||
this
.
props
.
courseName
!==
prevProps
.
courseName
)
||
this
.
props
.
courseType
!==
prevProps
.
courseType
this
.
props
.
courseType
!==
prevProps
.
courseType
)
{
)
{
this
.
handleFetchScheduleList
(
this
.
props
);
this
.
handleFetchScheduleList
(
this
.
props
);
...
@@ -78,10 +78,10 @@ class VideoList extends React.Component {
...
@@ -78,10 +78,10 @@ class VideoList extends React.Component {
let
hours
=
Math
.
floor
(
time
/
3600
);
let
hours
=
Math
.
floor
(
time
/
3600
);
let
mins
=
Math
.
floor
(
diff
/
60
);
let
mins
=
Math
.
floor
(
diff
/
60
);
let
seconds
=
Math
.
floor
(
time
%
60
);
let
seconds
=
Math
.
floor
(
time
%
60
);
hours
=
hours
<
10
?
"0"
+
hours
:
hours
;
hours
=
hours
<
10
?
'0'
+
hours
:
hours
;
mins
=
mins
<
10
?
"0"
+
mins
:
mins
;
mins
=
mins
<
10
?
'0'
+
mins
:
mins
;
seconds
=
seconds
<
10
?
"0"
+
seconds
:
seconds
;
seconds
=
seconds
<
10
?
'0'
+
seconds
:
seconds
;
return
hours
+
":"
+
mins
+
":"
+
seconds
;
return
hours
+
':'
+
mins
+
':'
+
seconds
;
};
};
// 请求表头
// 请求表头
parseColumns
=
()
=>
{
parseColumns
=
()
=>
{
...
@@ -90,71 +90,58 @@ class VideoList extends React.Component {
...
@@ -90,71 +90,58 @@ class VideoList extends React.Component {
title
:
(
title
:
(
<
span
>
<
span
>
<
span
>
课程信息
</
span
>
<
span
>
课程信息
</
span
>
<
Tooltip
<
Tooltip
title=
{
<
div
>
已加入该分类的课程不支持重复选择,因此不显示。
</
div
>
}
>
title=
{
<
div
>
已加入该分类的课程不支持重复选择,因此不显示。
</
div
>
}
>
<
i
<
i
className=
"icon iconfont"
className=
'icon iconfont'
style=
{
{
style=
{
{
marginLeft
:
"5px"
,
marginLeft
:
'5px'
,
cursor
:
"pointer"
,
cursor
:
'pointer'
,
color
:
"#bfbfbf"
,
color
:
'#bfbfbf'
,
fontSize
:
"14px"
,
fontSize
:
'14px'
,
fontWeight
:
"400"
fontWeight
:
'400'
,
}
}
}
}
>
>


</
i
>
</
i
>
</
Tooltip
>
</
Tooltip
>
</
span
>
</
span
>
),
),
key
:
"scheduleName"
,
key
:
'scheduleName'
,
dataIndex
:
"scheduleName"
,
dataIndex
:
'scheduleName'
,
width
:
371
,
width
:
371
,
render
:
(
val
,
record
)
=>
{
render
:
(
val
,
record
)
=>
{
const
{
coverUrl
,
scheduleVideoUrl
}
=
record
;
const
{
coverUrl
,
scheduleVideoUrl
}
=
record
;
return
(
return
(
<
div
className=
"record__item"
>
<
div
className=
'record__item'
>
{
/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */
}
{
/* 上传了封面的话就用上传的封面, 没有的话就取视频的第一帧 */
}
<
img
<
img
className=
'course-cover'
src=
{
coverUrl
||
`${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast`
}
/>
className=
"course-cover"
src=
{
coverUrl
||
`${scheduleVideoUrl}?x-oss-process=video/snapshot,t_0,m_fast`
}
/>
{
record
.
courseName
.
length
>
25
?
(
{
record
.
courseName
.
length
>
25
?
(
<
Tooltip
title=
{
record
.
courseName
}
>
<
Tooltip
title=
{
record
.
courseName
}
>
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
</
Tooltip
>
</
Tooltip
>
)
:
(
)
:
(
<
div
className=
"course-name"
>
{
record
.
courseName
}
</
div
>
<
div
className=
'course-name'
>
{
record
.
courseName
}
</
div
>
)
}
)
}
</
div
>
</
div
>
);
);
},
},
},
},
{
{
title
:
"课程时长"
,
title
:
'课程时长'
,
key
:
"videoDuration"
,
key
:
'videoDuration'
,
dataIndex
:
"videoDuration"
,
dataIndex
:
'videoDuration'
,
render
:
(
text
,
item
)
=>
{
render
:
(
text
,
item
)
=>
{
return
<
span
>
{
text
?
this
.
dealTimeDuration
(
text
)
:
"-"
}
</
span
>;
return
<
span
>
{
text
?
this
.
dealTimeDuration
(
text
)
:
'-'
}
</
span
>;
},
},
},
},
{
{
title
:
"课程分类"
,
title
:
'课程分类'
,
key
:
"categoryName"
,
key
:
'categoryName'
,
dataIndex
:
"categoryName"
,
dataIndex
:
'categoryName'
,
render
:
(
val
,
record
)
=>
{
render
:
(
val
,
record
)
=>
{
return
(
return
(
<
div
className=
"record__item"
>
<
div
className=
'record__item'
>
{
record
.
categoryOneName
}
{
record
.
categoryOneName
}
{
record
.
categoryTwoName
?
`-${record.categoryTwoName}`
:
""
}
{
record
.
categoryTwoName
?
`-${record.categoryTwoName}`
:
''
}
</
div
>
</
div
>
);
);
},
},
...
@@ -167,11 +154,7 @@ class VideoList extends React.Component {
...
@@ -167,11 +154,7 @@ class VideoList extends React.Component {
let
{
selectedRowKeys
}
=
this
.
state
;
let
{
selectedRowKeys
}
=
this
.
state
;
let
_list
=
[];
let
_list
=
[];
if
(
selected
||
!
_
.
find
(
selectedRowKeys
,
(
item
)
=>
item
.
id
==
record
.
id
))
{
if
(
selected
||
!
_
.
find
(
selectedRowKeys
,
(
item
)
=>
item
.
id
==
record
.
id
))
{
_list
=
_
.
uniq
(
_list
=
_
.
uniq
(
selectedRowKeys
.
concat
([
record
]),
false
,
(
item
)
=>
item
.
id
);
selectedRowKeys
.
concat
([
record
]),
false
,
(
item
)
=>
item
.
id
);
}
else
{
}
else
{
_list
=
_
.
reject
(
selectedRowKeys
,
(
item
)
=>
item
.
id
===
record
.
id
);
_list
=
_
.
reject
(
selectedRowKeys
,
(
item
)
=>
item
.
id
===
record
.
id
);
}
}
...
@@ -182,27 +165,21 @@ class VideoList extends React.Component {
...
@@ -182,27 +165,21 @@ class VideoList extends React.Component {
const
{
dataSource
=
[],
totalCount
,
query
,
selectedRowKeys
}
=
this
.
state
;
const
{
dataSource
=
[],
totalCount
,
query
,
selectedRowKeys
}
=
this
.
state
;
const
{
current
,
size
}
=
query
;
const
{
current
,
size
}
=
query
;
const
rowSelection
=
{
const
rowSelection
=
{
selectedRowKeys
:
_
.
pluck
(
selectedRowKeys
,
"id"
),
selectedRowKeys
:
_
.
pluck
(
selectedRowKeys
,
'id'
),
onSelect
:
this
.
selectLiveList
,
onSelect
:
this
.
selectLiveList
,
onSelectAll
:
(
selected
,
_selectedRows
,
changeRows
)
=>
{
onSelectAll
:
(
selected
,
_selectedRows
,
changeRows
)
=>
{
let
_list
=
[];
let
_list
=
[];
if
(
selected
)
{
if
(
selected
)
{
_list
=
_
.
uniq
(
_list
=
_
.
uniq
(
selectedRowKeys
.
concat
(
changeRows
),
false
,
(
item
)
=>
item
.
id
);
selectedRowKeys
.
concat
(
changeRows
),
false
,
(
item
)
=>
item
.
id
);
}
else
{
}
else
{
_list
=
_
.
reject
(
selectedRowKeys
,
(
item
)
=>
_list
=
_
.
reject
(
selectedRowKeys
,
(
item
)
=>
_
.
find
(
changeRows
,
(
data
)
=>
data
.
id
===
item
.
id
));
_
.
find
(
changeRows
,
(
data
)
=>
data
.
id
===
item
.
id
)
);
}
}
this
.
setState
({
selectedRowKeys
:
_list
});
this
.
setState
({
selectedRowKeys
:
_list
});
},
},
};
};
return
(
return
(
<
div
className=
"live-list"
>
<
div
className=
'live-list'
>
<
TableSelectedData
<
TableSelectedData
selectedNum=
{
selectedRowKeys
.
length
}
selectedNum=
{
selectedRowKeys
.
length
}
clearSelectedData=
{
()
=>
{
clearSelectedData=
{
()
=>
{
...
@@ -215,14 +192,14 @@ class VideoList extends React.Component {
...
@@ -215,14 +192,14 @@ class VideoList extends React.Component {
rowKey=
{
(
record
)
=>
record
.
id
}
rowKey=
{
(
record
)
=>
record
.
id
}
dataSource=
{
dataSource
}
dataSource=
{
dataSource
}
columns=
{
this
.
parseColumns
()
}
columns=
{
this
.
parseColumns
()
}
size=
"middle"
size=
'middle'
rowSelection=
{
rowSelection
}
rowSelection=
{
rowSelection
}
pagination=
{
false
}
pagination=
{
false
}
bordered
bordered
className=
"video-list-table"
className=
'video-list-table'
/>
/>
<
div
className=
"box-footer"
>
<
div
className=
'box-footer'
>
{
totalCount
>
0
&&
(
{
totalCount
>
0
&&
(
<
PageControl
<
PageControl
current=
{
current
-
1
}
current=
{
current
-
1
}
...
...
src/modules/task-center/data-center/Index.tsx
View file @
5314960e
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
withRouter
}
from
"react-router-dom"
;
import
{
Tabs
}
from
'antd'
;
import
{
Tabs
}
from
'antd'
;
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
Service
from
'@/common/js/service'
;
import
Service
from
'@/common/js/service'
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
UserLearningData
from
'./UserLearningData'
;
import
DataInfo
from
'./components/DataInfo'
import
DataInfo
from
'./components/DataInfo'
import
CourseTable
from
'./components/CourseTable'
;
import
CourseTable
from
'./components/CourseTable'
;
import
DataAnalysic
from
'./components/DataAnalysic'
;
import
ExamTable
from
'./components/ExamTable'
;
import
ExamTable
from
'./components/ExamTable'
;
import
StudyTable
from
'./components/StudyTable'
;
import
StudyTable
from
'./components/StudyTable'
;
import
'./index.less'
import
'./index.less'
const
{
TabPane
}
=
Tabs
;
const
{
TabPane
}
=
Tabs
;
function
DataCenter
(
props
:
any
)
{
function
DataCenter
(
props
:
any
)
{
const
{
match
:
{
params
:
{
taskId
}
}
}
=
props
;
const
{
match
}
=
props
;
const
{
params
:
{
taskId
}
}
=
match
;
const
[
info
,
setInfo
]
=
useState
<
any
>
({})
const
[
info
,
setInfo
]
=
useState
<
any
>
({})
const
[
tabKey
,
setTabKey
]
=
useState
<
any
>
(
''
)
const
[
tabKey
,
setTabKey
]
=
useState
<
any
>
(
''
)
...
@@ -44,8 +47,8 @@ function DataCenter(props: any) {
...
@@ -44,8 +47,8 @@ function DataCenter(props: any) {
res
.
result
.
trainingStageList
.
map
((
item
:
any
)
=>
{
res
.
result
.
trainingStageList
.
map
((
item
:
any
)
=>
{
item
.
open
=
true
item
.
open
=
true
})
})
res
.
result
.
cover
=
res
.
result
.
courseMediaVOS
.
filter
((
item
:
any
)
=>
item
.
contentType
===
'COVER'
)[
0
]
||
{};
res
.
result
.
cover
=
res
.
result
.
courseMediaVOS
.
filter
((
item
:
any
)
=>
item
.
contentType
===
'COVER'
)[
0
]
||
{};
res
.
result
.
intro
=
res
.
result
.
courseMediaVOS
.
filter
((
item
:
any
)
=>
item
.
contentType
===
'INTRO'
)[
0
]
||
{};
res
.
result
.
intro
=
res
.
result
.
courseMediaVOS
.
filter
((
item
:
any
)
=>
item
.
contentType
===
'INTRO'
)[
0
]
||
{};
setInfo
(
res
.
result
)
setInfo
(
res
.
result
)
})
})
}
}
...
@@ -72,7 +75,13 @@ function DataCenter(props: any) {
...
@@ -72,7 +75,13 @@ function DataCenter(props: any) {
</
Tabs
>
</
Tabs
>
</
div
>
</
div
>
<
Route
path=
{
`${match.url}/analysic/:id`
}
render=
{
()
=>
{
return
<
DataAnalysic
/>;
}
}
/>
<
Route
path=
{
`${props.match.url}/user-learning-data/:storeCustomerId`
}
render=
{
()
=>
<
UserLearningData
taskId=
{
taskId
}
/>
}
/>
</
div
>
</
div
>
}
}
...
...
src/modules/task-center/data-center/components/DataAnalysic.tsx
0 → 100644
View file @
5314960e
import
React
,
{
useState
,
useRef
,
useEffect
,
useContext
}
from
'react'
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
Breadcrumbs
from
"@/components/Breadcrumbs"
;
import
UserData
from
'./UserData'
;
import
ExamData
from
'./ExamData'
import
Service
from
"@/common/js/service"
;
import
{
Tabs
}
from
'antd'
;
import
User
from
"@/common/js/user"
;
import
'./dataAnalysic.less'
const
{
TabPane
}
=
Tabs
;
function
DataAnalysic
(
props
:
any
)
{
const
examDetailInit
:
any
=
{};
const
[
selectKey
,
setSelectKey
]
=
useState
(
'user'
)
const
[
examDetail
,
setExamDetail
]
=
useState
(
examDetailInit
);
const
{
match
}
=
props
;
const
examId
=
match
.
params
.
id
;
useEffect
(()
=>
{
queryExamDetail
();
},
[])
function
queryExamDetail
()
{
Service
.
Hades
(
"public/hades/queryExamDetail"
,
{
examId
:
examId
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
}).
then
((
res
)
=>
{
const
{
result
}
=
res
setExamDetail
(
result
)
})
}
return
<
div
className=
"page dataAnalysic"
>
<
Breadcrumbs
navList=
{
"考试数据"
}
goBack=
{
props
.
history
.
goBack
}
/>
<
div
className=
"box"
>
<
div
className=
"titleBox "
>
考试名称:
{
examDetail
.
examName
}
</
div
>
</
div
>
<
div
className=
"box"
style=
{
{
paddingTop
:
0
}
}
>
<
Tabs
activeKey=
{
selectKey
}
onChange=
{
(
key
:
any
)
=>
{
setSelectKey
(
key
)
}
}
>
<
TabPane
tab=
"考试人员数据"
key=
"user"
>
<
UserData
examDetail
={
examDetail
}
examId=
{
examId
}
/>
</
TabPane
>
<
TabPane
tab=
"题目数据"
key=
"exam"
>
<
ExamData
examDetail
={
examDetail
}
examId=
{
examId
}
></
ExamData
>
</
TabPane
>
</
Tabs
>
</
div
>
</
div
>
}
export
default
withRouter
(
DataAnalysic
);
\ No newline at end of file
src/modules/task-center/data-center/components/ExamData.tsx
0 → 100644
View file @
5314960e
import
React
,
{
useState
,
useRef
,
useEffect
}
from
"react"
;
import
Service
from
"@/common/js/service"
;
import
{
PageControl
}
from
"@/components"
;
import
{
Input
,
Select
,
Tooltip
,
Button
}
from
"antd"
;
import
User
from
"@/common/js/user"
;
import
{
XMTable
}
from
"@/components"
;
import
college
from
"@/common/lottie/college.json"
;
import
"./userData.less"
;
interface
sortType
{
type
:
"ascend"
|
"descend"
|
null
|
undefined
;
}
function
ExamData
(
props
:
any
)
{
const
sortStatus
:
sortType
=
{
type
:
undefined
,
};
const
examDataInit
:
any
=
{};
const
queryInit
:
any
=
{
current
:
1
,
size
:
10
,
order
:
"SORT_ASC"
};
const
[
examData
,
setUserData
]
=
useState
(
examDataInit
);
const
[
list
,
setList
]
=
useState
([]);
const
[
query
,
setQuery
]
=
useState
(
queryInit
);
const
[
total
,
setTotal
]
=
useState
(
0
);
const
[
field
,
setfield
]
=
useState
(
""
);
const
[
allData
,
setAllData
]
=
useState
(
0
);
const
[
order
,
setOrder
]
=
useState
(
sortStatus
.
type
);
const
questionTypeList
=
{
SINGLE_CHOICE
:
"单选题"
,
MULTI_CHOICE
:
"多选题"
,
JUDGE
:
"判断题"
,
GAP_FILLING
:
"填空题"
,
INDEFINITE_CHOICE
:
"不定项选择题"
,
};
const
userTypeEnum
=
{
WORK_WE_CHAT
:
"企业微信"
,
WE_CHAT
:
"微信"
,
};
const
userExamStateEnum
=
{
EXAM
:
"进行中"
,
LACK_EXAM
:
"缺考"
,
FINISH_EXAM
:
"已考试"
,
};
const
orderEnum
=
{
currentAccuracy
:
{
ascend
:
"ACCURACY_ASC"
,
descend
:
"ACCURACY_DESC"
,
},
};
const
queryRef
=
useRef
({});
useEffect
(()
=>
{
queryExamUserData
();
},
[]);
useEffect
(()
=>
{
queryRef
.
current
=
query
;
queryExamUserDataList
();
},
[
query
]);
function
queryExamUserData
()
{
Service
.
Hades
(
"public/hades/queryExamQuestionData"
,
{
examId
:
props
.
examId
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
,
}).
then
((
res
)
=>
{
setUserData
(
res
.
result
);
});
}
function
queryExamUserDataList
()
{
Service
.
Hades
(
"public/hades/queryExamQuestionDataList"
,
{
...
query
,
examId
:
props
.
examId
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
,
}).
then
((
res
)
=>
{
setList
(
res
.
result
.
records
);
setTotal
(
parseInt
(
res
.
result
.
total
));
if
(
!
allData
)
{
setAllData
(
parseInt
(
res
.
result
.
total
));
}
});
}
const
columns
=
[
{
title
:
"序号"
,
dataIndex
:
"sort"
,
width
:
60
,
render
:
(
text
:
any
,
record
:
any
,
index
:
any
)
=>
<
span
>
{
index
+
1
}
</
span
>,
},
{
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
,
" "
);
return
(
<
Tooltip
overlayClassName=
"aid-tool-list"
title=
{
<
div
style=
{
{
maxWidth
:
700
,
width
:
"auto"
}
}
>
{
handleVal
}
</
div
>
}
placement=
"topLeft"
overlayStyle=
{
{
maxWidth
:
700
}
}
>
{
handleVal
}
</
Tooltip
>
);
},
},
{
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
,
};
}),
},
{
title
:
"本次正确率"
,
dataIndex
:
"currentAccuracy"
,
sorter
:
true
,
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)"
,
fontWeight
:
400
}
}
className=
"icon iconfont"
>

</
span
>
</
Tooltip
>
</
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
]);
let
_query
:
any
=
{
...
queryRef
.
current
};
console
.
log
(
filters
.
questionType
);
if
(
filters
.
questionType
)
{
console
.
log
(
233232
);
_query
.
questionType
=
filters
.
questionType
;
_query
.
current
=
1
;
}
else
{
delete
_query
.
questionType
;
}
_query
.
order
=
(
orderEnum
as
any
)[
sorter
.
field
][
sorter
.
order
];
setQuery
(
_query
);
}
function
download
()
{
Service
.
Hades
(
"public/hades/exportExamData"
,
{
// ...query,
examId
:
props
.
examId
,
exportDataType
:
"EXAM_QUESTION_DATA"
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
,
}).
then
((
res
)
=>
{
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
>
</
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
>
</
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"
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
}
}
bordered
size=
"small"
columns=
{
columns
}
dataSource=
{
list
}
onChange=
{
onChange
}
pagination=
{
false
}
></
XMTable
>
{
total
>
0
&&
(
<
PageControl
size=
"small"
current=
{
query
.
current
-
1
}
pageSize=
{
query
.
size
}
total=
{
total
}
toPage=
{
(
page
:
any
)
=>
{
console
.
log
(
page
);
let
_query
:
any
=
{
...
queryRef
.
current
};
_query
.
current
=
page
+
1
;
setQuery
(
_query
);
}
}
/>
)
}
</
div
>
</
div
>
);
}
export
default
ExamData
;
src/modules/task-center/data-center/components/ExamTable.tsx
View file @
5314960e
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
React
,
{
useEffect
,
useState
}
from
'react'
;
import
{
withRouter
}
from
"react-router-dom"
;
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
{
PageControl
,
XMTable
}
from
'@/components'
;
import
Service
from
'@/common/js/service'
;
import
Service
from
'@/common/js/service'
;
import
User
from
'@/common/js/user'
;
import
User
from
'@/common/js/user'
;
function
ExamTable
(
props
:
any
)
{
function
ExamTable
(
props
:
any
)
{
const
{
match
}
=
props
;
console
.
log
(
match
)
const
[
query
,
setQuery
]
=
useState
<
any
>
({
const
[
query
,
setQuery
]
=
useState
<
any
>
({
current
:
1
,
size
:
10
,
current
:
1
,
size
:
10
,
taskId
:
props
.
taskId
,
taskId
:
props
.
taskId
,
...
@@ -22,8 +25,8 @@ function ExamTable(props: any) {
...
@@ -22,8 +25,8 @@ function ExamTable(props: any) {
function
getList
()
{
function
getList
()
{
Service
.
Hades
(
'public/hades/queryTrainingExamUserData'
,
query
).
then
((
res
:
any
)
=>
{
Service
.
Hades
(
'public/hades/queryTrainingExamUserData'
,
query
).
then
((
res
:
any
)
=>
{
setList
(
res
.
result
.
records
)
setList
(
res
.
result
.
records
)
;
setTotal
(
res
.
result
.
t
atal
)
setTotal
(
res
.
result
.
t
otal
);
})
})
}
}
...
@@ -79,7 +82,11 @@ function ExamTable(props: any) {
...
@@ -79,7 +82,11 @@ function ExamTable(props: any) {
render
:
(
val
:
any
,
record
:
any
)
=>
{
render
:
(
val
:
any
,
record
:
any
)
=>
{
return
(
return
(
<
div
className=
'operate-area'
>
<
div
className=
'operate-area'
>
<
span
className=
'operate-item'
onClick=
{
()
=>
{
}
}
>
<
span
className=
'operate-item'
style=
{
{
color
:
'rgba(41, 102, 255, 1)'
,
cursor
:
'pointer'
}
}
onClick=
{
()
=>
{
props
.
history
.
push
({
pathname
:
`${match.url}/analysic/${record.examId}`
,
});
}
}
>
查看数据
查看数据
</
span
>
</
span
>
...
@@ -90,6 +97,7 @@ function ExamTable(props: any) {
...
@@ -90,6 +97,7 @@ function ExamTable(props: any) {
];
];
return
<
div
className=
"study_Table"
>
return
<
div
className=
"study_Table"
>
<
div
style=
{
{
marginTop
:
12
}
}
>
<
div
style=
{
{
marginTop
:
12
}
}
>
...
@@ -121,7 +129,7 @@ function ExamTable(props: any) {
...
@@ -121,7 +129,7 @@ function ExamTable(props: any) {
</
div
>
</
div
>
)
}
)
}
</
div
>
</
div
>
</
div
>
</
div
>
}
}
...
...
src/modules/task-center/data-center/components/LeftStageList.jsx
View file @
5314960e
...
@@ -31,12 +31,12 @@ function LeftStageList(props) {
...
@@ -31,12 +31,12 @@ function LeftStageList(props) {
>
>
<
div
className=
"icon"
>
<
div
className=
"icon"
>
{
item
.
isShowMoreCourse
?
(
{
item
.
isShowMoreCourse
?
(
<
span
className=
"icon iconfont edit-icon"
>
æ
b2
;
</
span
>
<
span
className=
"icon iconfont edit-icon"
>
æ
77
;
</
span
>
)
:
(
)
:
(
<
span
className=
"icon iconfont edit-icon"
>

</
span
>
<
span
className=
"icon iconfont edit-icon"
>

</
span
>
)
}
)
}
</
div
>
</
div
>
<
div
className=
"stage-name"
>
<
div
className=
"stage-name
oneLineText
"
>
{
ENUM
.
IndexToSort
[
index
+
1
]
}
、
{
item
.
stageName
}
{
ENUM
.
IndexToSort
[
index
+
1
]
}
、
{
item
.
stageName
}
</
div
>
</
div
>
</
div
>
</
div
>
...
...
src/modules/task-center/data-center/components/StudyTable.tsx
View file @
5314960e
...
@@ -8,8 +8,7 @@ import Service from '@/common/js/service';
...
@@ -8,8 +8,7 @@ import Service from '@/common/js/service';
import
ENUM
from
'../../enum'
;
import
ENUM
from
'../../enum'
;
import
User
from
'@/common/js/user'
;
import
User
from
'@/common/js/user'
;
import
moment
from
'moment'
;
import
moment
from
'moment'
;
import
UserLearningData
from
'../UserLearningData'
;
import
{
timers
}
from
'jquery'
;
const
{
Search
}
=
Input
;
const
{
Search
}
=
Input
;
const
{
Option
}
=
Select
;
const
{
Option
}
=
Select
;
declare
var
formatDate
:
any
;
declare
var
formatDate
:
any
;
...
@@ -294,7 +293,7 @@ function StudyTable(props: any) {
...
@@ -294,7 +293,7 @@ function StudyTable(props: any) {
</
div
>
</
div
>
)
}
)
}
</
div
>
</
div
>
<
Route
path=
{
`${props.match.url}/user-learning-data/:storeCustomerId`
}
render=
{
()
=>
<
UserLearningData
taskId=
{
props
.
taskId
}
/>
}
/>
</
div
>
</
div
>
}
}
...
...
src/modules/task-center/data-center/components/UserData.tsx
0 → 100644
View file @
5314960e
import
React
,
{
useState
,
useRef
,
useEffect
}
from
"react"
;
import
Service
from
"@/common/js/service"
;
import
{
PageControl
}
from
"@/components"
;
import
{
Input
,
Select
,
Tooltip
,
Table
,
Button
}
from
"antd"
;
import
{
ColumnsType
}
from
"antd/es/table"
;
import
User
from
"@/common/js/user"
;
import
moment
from
"moment"
;
import
{
XMTable
}
from
"@/components"
;
import
college
from
"@/common/lottie/college.json"
;
import
"./userData.less"
;
const
{
Search
}
=
Input
;
const
{
Option
}
=
Select
;
declare
var
window
:
any
;
interface
sortType
{
type
:
"ascend"
|
"descend"
|
null
|
undefined
;
}
interface
User
{
key
:
number
;
name
:
string
;
}
function
DataAnalysic
(
props
:
any
)
{
const
sortStatus
:
sortType
=
{
type
:
undefined
,
};
const
useDataInit
:
any
=
{};
const
queryInit
:
any
=
{
current
:
1
,
size
:
10
};
const
[
useData
,
setUserData
]
=
useState
(
useDataInit
);
const
[
list
,
setList
]
=
useState
([]);
const
[
query
,
setQuery
]
=
useState
(
queryInit
);
const
[
total
,
setTotal
]
=
useState
(
0
);
const
[
field
,
setfield
]
=
useState
(
""
);
const
[
allData
,
setAllData
]
=
useState
(
0
);
const
[
order
,
setOrder
]
=
useState
(
sortStatus
.
type
);
const
userTypeEnum
=
{
WORK_WE_CHAT
:
"企业微信"
,
WE_CHAT
:
"微信"
,
};
const
userExamStateEnum
=
{
EXAM
:
"进行中"
,
LACK_EXAM
:
"缺考"
,
FINISH_EXAM
:
"已考试"
,
};
const
ExamPassColorEnum
=
{
EXAM_FAIL
:
"rgba(255, 79, 79, 1)"
,
EXAM_PASS
:
"rgba(59, 189, 170, 1)"
,
};
const
ExamPassEnum
=
{
EXAM_FAIL
:
"不及格"
,
EXAM_PASS
:
"及格"
,
};
const
userExamStateColorEnum
=
{
EXAM
:
"rgba(35, 143, 255, 1)"
,
LACK_EXAM
:
"rgba(204, 204, 204, 1)"
,
FINISH_EXAM
:
"rgba(47, 200, 60, 1)"
,
};
const
orderEnum
=
{
score
:
{
ascend
:
"EXAM_SCORE_ASC"
,
descend
:
"EXAM_SCORE_DESC"
,
},
userDuration
:
{
ascend
:
"USER_DURATION_ASC"
,
descend
:
"USER_DURATION_DESC"
,
},
};
const
queryRef
=
useRef
({});
useEffect
(()
=>
{
queryExamUserData
();
},
[]);
useEffect
(()
=>
{
queryRef
.
current
=
query
;
queryExamUserDataList
();
},
[
query
]);
function
queryExamUserData
()
{
Service
.
Hades
(
"public/hades/queryExamUserData"
,
{
examId
:
props
.
examId
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
,
}).
then
((
res
)
=>
{
setUserData
(
res
.
result
);
});
}
function
queryExamUserDataList
()
{
Service
.
Hades
(
"public/hades/queryExamUserDataList"
,
{
...
query
,
examId
:
props
.
examId
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
,
}).
then
((
res
)
=>
{
setList
(
res
.
result
.
records
);
setTotal
(
parseInt
(
res
.
result
.
total
));
if
(
!
allData
)
{
setAllData
(
parseInt
(
res
.
result
.
total
));
}
});
}
const
columns
:
ColumnsType
<
User
>
=
[
{
title
:
"学员"
,
dataIndex
:
"userName"
,
render
:
(
text
:
any
,
record
:
any
)
=>
(
<
span
>
{
text
}
<
span
style=
{
{
color
:
record
.
userSource
===
"WORK_WE_CHAT"
?
"rgba(255, 157, 20, 1)"
:
"rgba(29, 204, 101, 1)"
,
}
}
>
@
{
(
userTypeEnum
as
any
)[
record
.
userSource
]
}
</
span
>
</
span
>
),
},
{
title
:
"手机号"
,
dataIndex
:
"phone"
,
},
{
title
:
"考试状态"
,
dataIndex
:
"userExamState"
,
render
:
(
text
:
any
)
=>
(
<
span
>
{
" "
}
<
span
className=
"exstatus"
style=
{
{
background
:
(
userExamStateColorEnum
as
any
)[
text
]
}
}
></
span
>
{
" "
}
{
(
userExamStateEnum
as
any
)[
text
]
}
</
span
>
),
},
{
title
:
"考试成绩"
,
dataIndex
:
"score"
,
sorter
:
true
,
sortOrder
:
field
===
"score"
?
order
:
sortStatus
.
type
,
render
:
(
text
:
any
,
record
:
any
)
=>
(
<
span
>
{
" "
}
{
text
}{
" "
}
<
span
style=
{
{
border
:
`1px solid ${
(ExamPassColorEnum as any)[record.examPass]
}`
,
fontSize
:
12
,
color
:
(
ExamPassColorEnum
as
any
)[
record
.
examPass
],
display
:
"inline-block"
,
padding
:
"0px 2px"
,
}
}
>
{
(
ExamPassEnum
as
any
)[
record
.
examPass
]
}
</
span
>
</
span
>
),
},
{
title
:
"进入考试时间"
,
dataIndex
:
"examStartTime"
,
render
:
(
text
:
any
)
=>
(
<
span
>
{
moment
(
text
).
format
(
"YYYY-MM-DD HH:mm"
)
}
</
span
>
),
},
{
title
:
"考试用时"
,
dataIndex
:
"userDuration"
,
sorter
:
true
,
sortOrder
:
field
===
"userDuration"
?
order
:
sortStatus
.
type
,
render
:
(
text
:
any
,
record
:
any
)
=>
(
<
span
>
{
record
.
userExamState
===
"FINISH_EXAM"
?
window
.
formatHourTime
(
text
)
:
"-"
}{
" "
}
</
span
>
),
},
//TODO:
{
title
:
"操作"
,
key
:
""
,
dataIndex
:
"edit"
,
render
:
(
value
:
any
,
record
:
any
)
=>
{
return
(
<
Choose
>
<
When
condition=
{
record
.
userExamState
===
"FINISH_EXAM"
}
>
<
div
className=
"answer-detail"
onClick=
{
()
=>
{
checkAnswerDetail
(
record
);
}
}
>
答题详情
</
div
>
</
When
>
<
Otherwise
>
-
</
Otherwise
>
</
Choose
>
);
},
},
];
function
onChange
(
pagination
:
any
,
filters
:
any
,
sorter
:
any
,
extra
:
any
)
{
setfield
(
sorter
.
field
);
setOrder
(
sorter
.
order
);
console
.
log
(
sorter
.
field
,
sorter
.
order
,
(
orderEnum
as
any
)[
sorter
.
field
]);
let
_query
:
any
=
{
...
queryRef
.
current
};
_query
.
order
=
(
orderEnum
as
any
)[
sorter
.
field
][
sorter
.
order
];
setQuery
(
_query
);
}
function
download
()
{
Service
.
Hades
(
"public/hades/exportExamData"
,
{
// ...query,
examId
:
props
.
examId
,
exportDataType
:
"EXAM_USER_DATA"
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
source
:
0
,
}).
then
((
res
)
=>
{
const
dom
=
(
document
as
any
).
getElementById
(
"load-play-back-excel"
);
dom
.
setAttribute
(
"href"
,
res
.
result
);
dom
.
click
();
});
}
//查看答题详情
function
checkAnswerDetail
(
record
:
any
)
{
const
{
paperId
,
userExamState
}
=
props
.
examDetail
?.
examPaper
;
const
{
userId
}
=
record
;
window
.
RCHistory
.
push
({
pathname
:
`/test-detail/
${
props
.
examId
}
?paperId=
${
paperId
}
&userExamState=
${
userExamState
}
&userId=
${
userId
}
`
,
});
}
return
(
<
div
className=
"rr"
>
<
a
target=
"_blank"
download
id=
"load-play-back-excel"
style=
{
{
position
:
"absolute"
,
left
:
"-10000px"
}
}
>
111
</
a
>
<
div
className=
"dataPanal"
>
<
div
className=
"item"
>
<
div
className=
"num"
>
{
useData
.
joinCnt
||
0
}
</
div
>
<
div
className=
"percent"
></
div
>
<
div
className=
"subTitle"
>
参与人数
</
div
>
</
div
>
<
div
className=
"item"
>
<
div
className=
"num"
>
{
useData
.
finishCnt
||
0
}
</
div
>
<
div
className=
"percent"
>
占比
{
parseInt
(
((
useData
.
finishCnt
||
0
)
/
(
useData
.
joinCnt
||
1
))
*
100
+
""
)
}
%
</
div
>
<
div
className=
"subTitle"
>
完成考试数 (人)
</
div
>
</
div
>
<
div
className=
"item"
>
<
div
className=
"num"
>
{
useData
.
passCnt
||
0
}
</
div
>
<
div
className=
"percent"
>
占比
{
parseInt
(
((
useData
.
passCnt
||
0
)
/
(
useData
.
finishCnt
||
1
))
*
100
+
""
)
}
%
</
div
>
<
div
className=
"subTitle"
>
及格数 (人)
</
div
>
</
div
>
<
div
className=
"item"
>
<
div
className=
"num"
>
{
useData
.
averageScore
||
0
}
</
div
>
<
div
className=
"percent"
>
总分
{
props
.
examDetail
?.
examPaper
?.
totalScore
}
</
div
>
<
div
className=
"subTitle"
>
平均分
</
div
>
</
div
>
<
div
className=
"item"
>
<
div
className=
"num"
>
{
" "
}
{
window
.
formatHourTime
(
useData
.
averageDuration
||
0
)
}{
" "
}
</
div
>
<
div
className=
"percent"
></
div
>
<
div
className=
"subTitle"
>
平均用时
</
div
>
</
div
>
</
div
>
<
div
className=
"xm-search-filter"
style=
{
{
marginTop
:
"24px"
}
}
>
<
div
style=
{
{
display
:
"flex"
}
}
>
<
div
className=
"search-condition"
>
<
div
className=
"search-condition__item"
>
<
span
className=
"search-name"
>
学员:
</
span
>
<
Search
value=
{
query
.
examName
}
className=
"search-input"
placeholder=
"搜索学员名或手机号"
onChange=
{
(
e
)
=>
{
const
_query
=
{
...
query
};
_query
.
searchKey
=
e
.
target
.
value
;
setQuery
(
_query
);
}
}
onSearch=
{
()
=>
{}
}
enterButton=
{
<
span
className=
"icon iconfont"
>

</
span
>
}
/>
</
div
>
<
div
className=
"search-condition__item"
>
<
span
className=
"search-name"
>
学员类型:
</
span
>
<
Select
value=
{
query
.
userSource
}
placeholder=
"请选择学员类型"
onChange=
{
(
val
)
=>
{
const
_query
=
{
...
query
};
_query
.
userSource
=
val
;
setQuery
(
_query
);
}
}
className=
"search-input"
allowClear
>
{
Object
.
keys
(
userTypeEnum
).
map
((
key
:
any
)
=>
{
return
(
<
Option
value=
{
key
}
key=
{
key
}
>
{
(
userTypeEnum
as
any
)[
key
]
}
</
Option
>
);
})
}
</
Select
>
</
div
>
<
div
className=
"search-condition__item"
>
<
span
className=
"search-name"
>
考试状态:
</
span
>
<
Select
value=
{
query
.
userExamState
}
placeholder=
"请选择考试状态"
onChange=
{
(
val
)
=>
{
const
_query
=
{
...
query
};
_query
.
userExamState
=
val
;
setQuery
(
_query
);
}
}
className=
"search-input"
allowClear
>
{
Object
.
keys
(
userExamStateEnum
).
map
((
key
:
any
)
=>
{
return
(
<
Option
value=
{
key
}
key=
{
key
}
>
{
(
userExamStateEnum
as
any
)[
key
]
}
</
Option
>
);
})
}
</
Select
>
</
div
>
</
div
>
<
div
className=
"reset-fold-area"
>
<
Tooltip
title=
"清空筛选"
>
<
span
className=
"resetBtn iconfont icon"
onClick=
{
()
=>
{
setfield
(
""
);
setQuery
({
current
:
1
,
size
:
10
});
}
}
>

{
" "
}
</
span
>
</
Tooltip
>
</
div
>
</
div
>
</
div
>
{
!!
allData
&&
(
<
Button
style=
{
{
marginBottom
:
12
}
}
onClick=
{
download
}
>
导出
</
Button
>
)
}
<
div
className=
"content analysic-content"
>
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'暂无数据'
}
}
bordered
size=
"small"
rowClassName=
"analysic-content-row"
columns=
{
columns
}
dataSource=
{
list
}
onChange=
{
onChange
}
pagination=
{
false
}
></
XMTable
>
{
total
>
0
&&
(
<
PageControl
size=
"small"
current=
{
query
.
current
-
1
}
pageSize=
{
query
.
size
}
total=
{
total
}
toPage=
{
(
page
:
any
)
=>
{
console
.
log
(
page
);
let
_query
:
any
=
{
...
queryRef
.
current
};
_query
.
current
=
page
+
1
;
setQuery
(
_query
);
}
}
/>
)
}
</
div
>
</
div
>
);
}
export
default
DataAnalysic
;
src/modules/task-center/data-center/components/dataAnalysic.less
0 → 100644
View file @
5314960e
.dataAnalysic {
.titleBox {
position: relative;
font-size: 19px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 26px;
background: #ffffff;
&::before {
width: 4px;
height: 12px;
content: '';
background-image: linear-gradient(#2966ff 83.5%, #0acca4 16.5%);
display: inline-block;
margin-right: 8px;
}
}
.ant-tabs-content-holder {
margin-top: 8px;
}
}
src/modules/task-center/data-center/components/userData.less
0 → 100644
View file @
5314960e
.dataPanal {
border-radius: 4px;
border: 1px solid #e8e8e8;
display: flex;
.item {
text-align: center;
// width: 29.9%;
position: relative;
flex: 1;
.num {
font-size: 26px;
font-family: PingFangSC-Medium, PingFang SC;
font-weight: 500;
color: #333333;
line-height: 26px;
margin-top: 12px;
}
.percent {
margin-top: 6px;
font-size: 12px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #999999;
line-height: 17px;
height: 20px;
margin-bottom: 18px;
}
.subTitle {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #666666;
line-height: 20px;
margin-bottom: 12px;
}
.type {
font-size: 14px;
font-family: PingFangSC-Regular, PingFang SC;
font-weight: 400;
color: #333333;
line-height: 20px;
span {
color: rgba(153, 153, 153, 1);
}
.icon {
color: rgba(204, 204, 204, 1);
font-size: 16px;
margin-right: 4px;
position: relative;
top: 1px;
}
}
&:after {
content: '';
width: 0px;
height: 40px;
position: absolute;
width: 1px;
background-color: rgba(232, 232, 232, 1);
top: 40px;
right: 0px;
}
&:last-child {
&:after {
display: none;
}
}
}
.exstatus {
width: 4px;
height: 4px;
background: rgb(35, 143, 255);
display: inline-block;
border-radius: 50%;
position: relative;
top: -4px;
}
}
.answer-detail {
color: rgb(35, 143, 255);
}
.analysic-content {
.ant-table-bordered .ant-table-tbody tr {
&.analysic-content-row {
height: 50px;
}
}
}
src/modules/task-center/train-task/components/RelatedExamDrawer.jsx
View file @
5314960e
...
@@ -2,7 +2,7 @@
...
@@ -2,7 +2,7 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-08-03 17:05:32
* @Date: 2021-08-03 17:05:32
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-08-1
1 11:49:11
* @LastEditTime: 2021-08-1
6 16:36:59
* @Description: 新建培训任务-关联考试抽屉
* @Description: 新建培训任务-关联考试抽屉
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
...
@@ -65,7 +65,7 @@ function RelatedExamDrawer(props) {
...
@@ -65,7 +65,7 @@ function RelatedExamDrawer(props) {
paperId
,
paperId
,
examName
,
examName
,
passRate
,
passRate
,
examDuration
,
examDuration
:
(
examDuration
||
0
)
*
60
*
1000
,
examDesc
,
examDesc
,
needOptionDisorder
,
needOptionDisorder
,
resultShow
,
resultShow
,
...
...
src/modules/task-center/train-task/modal/ChooseAssignorModal.jsx
View file @
5314960e
...
@@ -2,13 +2,13 @@
...
@@ -2,13 +2,13 @@
* @Author: yuananting
* @Author: yuananting
* @Date: 2021-08-05 17:09:36
* @Date: 2021-08-05 17:09:36
* @LastEditors: yuananting
* @LastEditors: yuananting
* @LastEditTime: 2021-08-1
3 19:18:54
* @LastEditTime: 2021-08-1
6 14:47:51
* @Description: 新建培训任务-选择指派对象
* @Description: 新建培训任务-选择指派对象
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
*/
import
React
,
{
useState
,
useEffect
}
from
'react'
;
import
React
,
{
useState
,
useEffect
,
useRef
}
from
'react'
;
import
{
Modal
,
Tree
,
Tooltip
,
AutoComplete
,
Tabs
}
from
'antd'
;
import
{
Modal
,
Tree
,
Tooltip
,
AutoComplete
,
Tabs
,
Input
,
Checkbox
}
from
'antd'
;
import
User
from
'@/common/js/user'
;
import
User
from
'@/common/js/user'
;
import
{
DepType
}
from
'@/domains/store-domain/constants'
;
import
{
DepType
}
from
'@/domains/store-domain/constants'
;
import
StoreService
from
'@/domains/store-domain/storeService'
;
import
StoreService
from
'@/domains/store-domain/storeService'
;
...
@@ -17,22 +17,38 @@ import './ChooseAssignorModal.less';
...
@@ -17,22 +17,38 @@ import './ChooseAssignorModal.less';
const
{
TabPane
}
=
Tabs
;
const
{
TabPane
}
=
Tabs
;
const
{
DirectoryTree
}
=
Tree
;
const
{
DirectoryTree
}
=
Tree
;
const
{
Search
}
=
Input
;
function
ChooseAssignorModal
(
props
)
{
function
ChooseAssignorModal
(
props
)
{
const
AssignTypeEnum
=
{
departMentTab
:
'SECTION'
,
postGrouptab
:
'POST'
,
customGroupTab
:
'CUSTOM'
,
};
const
[
structureData
,
setStructureData
]
=
useState
([]);
const
[
structureData
,
setStructureData
]
=
useState
([]);
const
[
activeKey
,
setActiveKey
]
=
useState
(
'departMentTab'
);
const
[
activeKey
,
setActiveKey
]
=
useState
(
'departMentTab'
);
const
[
checkedAssignorList
,
setCheckedAssignorList
]
=
useState
(
props
.
currentAssignorList
||
[]);
// 勾选的指派对象
const
[
checkedAssignorList
,
setCheckedAssignorList
]
=
useState
(
props
.
currentAssignorList
||
[]);
// 勾选的指派对象
const
[
checkedAssignorKeys
,
setCheckedAssignorKeys
]
=
useState
(
props
.
currentAssignorList
.
map
((
item
)
=>
item
.
checkedId
)
||
[]);
const
[
checkedAssignorKeys
,
setCheckedAssignorKeys
]
=
useState
(
props
.
currentAssignorList
.
map
((
item
)
=>
item
.
checkedId
)
||
[]);
const
[
completeOptions
,
setCompleteOption
]
=
useState
([]);
const
[
completeOptions
,
setCompleteOption
]
=
useState
([]);
const
[
searchKey
,
setSearchKey
]
=
useState
(
''
);
const
[
open
,
setOpen
]
=
useState
(
false
);
const
[
open
,
setOpen
]
=
useState
(
false
);
const
[
queryName
,
setQueryName
]
=
useState
(
''
);
// 搜索框内的值
const
queryNameRef
=
useRef
(
null
);
const
timer
=
useRef
(
null
);
useEffect
(()
=>
{
queryNameRef
.
current
=
queryName
;
setOpen
(
!!
queryName
);
clearTimeout
(
timer
.
current
);
timer
.
current
=
setTimeout
(()
=>
{
if
(
!!
queryName
)
return
getCompleteOptionData
(
queryNameRef
.
current
);
setCompleteOption
([]);
},
500
);
},
[
queryName
]);
const
AssignTypeEnum
=
{
departMentTab
:
'SECTION'
,
postGrouptab
:
'POST'
,
customGroupTab
:
'CUSTOM'
,
};
useEffect
(()
=>
{
useEffect
(()
=>
{
setQueryName
(
''
);
// 切换tab时搜索置空
setCompleteOption
([]);
setStructureData
([]);
getStructureData
();
getStructureData
();
},
[
activeKey
]);
},
[
activeKey
]);
...
@@ -40,7 +56,7 @@ function ChooseAssignorModal(props) {
...
@@ -40,7 +56,7 @@ function ChooseAssignorModal(props) {
const
params
=
{
const
params
=
{
depType
:
DepType
[
activeKey
],
depType
:
DepType
[
activeKey
],
enterpriseId
:
User
.
getEnterpriseId
(),
enterpriseId
:
User
.
getEnterpriseId
(),
source
:
0
,
//0代表来自企培
source
:
0
,
//
0代表来自企培
storeId
:
User
.
getStoreId
(),
storeId
:
User
.
getStoreId
(),
userId
:
User
.
getUserId
(),
userId
:
User
.
getUserId
(),
whetherCount
:
false
,
whetherCount
:
false
,
...
@@ -117,43 +133,52 @@ function ChooseAssignorModal(props) {
...
@@ -117,43 +133,52 @@ function ChooseAssignorModal(props) {
}
}
function
renderTitle
(
title
)
{
function
renderTitle
(
title
)
{
return
<
span
>
{
title
}
</
span
>;
return
<
span
className=
'catalog-title'
>
{
title
}
</
span
>;
}
}
function
renderItem
(
record
,
type
)
{
function
renderItem
(
record
,
type
)
{
return
{
return
{
value
:
record
.
userName
||
record
.
name
,
value
:
record
.
userName
||
record
.
name
,
label
:
(
label
:
(
<
div
<
Checkbox
>
style=
{
{
<
div
display
:
'flex'
,
className=
'search-result-item'
justifyContent
:
'space-between'
,
style=
{
{
}
}
display
:
'flex'
,
depId=
{
record
.
id
}
justifyContent
:
'space-between'
,
type=
{
type
}
>
}
}
{
type
===
'user'
?
(
depId=
{
record
.
id
}
<
div
>
type=
{
type
}
>
<
WWOpenDataCom
type=
'userName'
openid=
{
record
.
userName
}
/>
{
type
===
'user'
?
(
</
div
>
<
div
className=
'search-result-item__left'
>
)
:
(
<
WWOpenDataCom
type=
'userName'
openid=
{
record
.
userName
}
/>
<
div
>
</
div
>
<
WWOpenDataCom
type=
'departmentName'
openid=
{
record
.
name
}
/>
)
:
(
</
div
>
<
div
className=
'search-result-item__left'
>
)
}
{
activeKey
===
'departMentTab'
?
<
WWOpenDataCom
type=
'departmentName'
openid=
{
record
.
name
}
/>
:
<
span
>
{
record
.
name
}
</
span
>
}
{
type
===
'user'
&&
</
div
>
record
.
postDepNamesList
.
map
((
item
,
index
)
=>
{
)
}
return
(
{
type
===
'user'
&&
(
<
span
>
<
div
className=
'search-result-item__right'
>
<
WWOpenDataCom
type=
'departmentName'
openid=
{
item
}
/>
<
Tooltip
title=
{
<
div
>
{
handleDepName
(
record
.
depNamesList
)
}
</
div
>
}
placement=
'top'
arrowPointAtCenter
>
</
span
>
{
record
.
depNamesList
.
map
((
item
,
index
)
=>
{
);
return
(
})
}
<
span
>
{
type
===
'post'
&&
(
<
WWOpenDataCom
type=
'departmentName'
openid=
{
item
}
/>
<
span
type=
'post'
openid=
{
record
.
parentName
}
>
{
index
<
record
.
depNamesList
.
length
-
1
?
';'
:
''
}
{
record
.
parentName
}
</
span
>
</
span
>
);
)
}
})
}
</
div
>
</
Tooltip
>
</
div
>
)
}
{
type
===
'post'
&&
(
<
span
type=
'post'
openid=
{
record
.
parentName
}
>
{
record
.
parentName
}
</
span
>
)
}
</
div
>
</
Checkbox
>
),
),
};
};
}
}
...
@@ -161,7 +186,7 @@ function ChooseAssignorModal(props) {
...
@@ -161,7 +186,7 @@ function ChooseAssignorModal(props) {
function
getCompleteOptionData
(
value
)
{
function
getCompleteOptionData
(
value
)
{
setCompleteOption
([]);
setCompleteOption
([]);
const
params
=
{
const
params
=
{
depType
:
DepType
[
props
.
treeType
],
depType
:
DepType
[
activeKey
],
queryName
:
value
,
queryName
:
value
,
enterpriseId
:
User
.
getEnterpriseId
(),
enterpriseId
:
User
.
getEnterpriseId
(),
source
:
0
,
//0代表来自企培
source
:
0
,
//0代表来自企培
...
@@ -185,7 +210,7 @@ function ChooseAssignorModal(props) {
...
@@ -185,7 +210,7 @@ function ChooseAssignorModal(props) {
});
});
}
}
if
(
departmentVOList
.
length
>
0
)
{
if
(
departmentVOList
.
length
>
0
)
{
switch
(
props
.
treeType
)
{
switch
(
activeKey
)
{
case
'departMentTab'
:
case
'departMentTab'
:
departmentGroupObj
.
label
=
renderTitle
(
'部门'
);
departmentGroupObj
.
label
=
renderTitle
(
'部门'
);
break
;
break
;
...
@@ -203,7 +228,7 @@ function ChooseAssignorModal(props) {
...
@@ -203,7 +228,7 @@ function ChooseAssignorModal(props) {
});
});
}
}
if
(
subLevelDepartmentVOList
.
length
>
0
)
{
if
(
subLevelDepartmentVOList
.
length
>
0
)
{
switch
(
props
.
treeType
)
{
switch
(
activeKey
)
{
case
'postGrouptab'
:
case
'postGrouptab'
:
postobj
.
label
=
renderTitle
(
'岗位'
);
postobj
.
label
=
renderTitle
(
'岗位'
);
break
;
break
;
...
@@ -220,27 +245,51 @@ function ChooseAssignorModal(props) {
...
@@ -220,27 +245,51 @@ function ChooseAssignorModal(props) {
if
(
Object
.
keys
(
userObj
).
length
!==
0
)
{
if
(
Object
.
keys
(
userObj
).
length
!==
0
)
{
_completeOptions
.
push
(
userObj
);
_completeOptions
.
push
(
userObj
);
}
}
if
(
Object
.
keys
(
departmentGroupObj
).
length
!==
0
)
{
_completeOptions
.
push
(
departmentGroupObj
);
}
if
(
Object
.
keys
(
postobj
).
length
!==
0
)
{
if
(
Object
.
keys
(
postobj
).
length
!==
0
)
{
_completeOptions
.
push
(
postobj
);
_completeOptions
.
push
(
postobj
);
}
}
if
(
Object
.
keys
(
departmentGroupObj
).
length
!==
0
)
{
_completeOptions
.
push
(
departmentGroupObj
);
}
setCompleteOption
(
_completeOptions
);
setCompleteOption
(
_completeOptions
);
});
});
}
}
// 搜索空状态渲染;
function
notFoundContentNode
()
{
return
(
<
div
className=
'empty-con'
>
<
img
src=
'https://image.xiaomaiketang.com/xm/wRDrb2pJFb.png'
className=
'empty-img'
/>
<
div
className=
'empty-text'
>
暂无数据
</
div
>
</
div
>
);
}
function
confirmSearchSelect
(
value
,
option
)
{
const
param
=
{};
setOpen
(
false
);
setQueryName
(
value
);
if
(
option
.
label
.
props
.
type
===
'user'
)
{
param
.
queryName
=
value
;
}
else
{
param
.
id
=
option
.
label
.
props
.
depId
;
}
props
.
searchUserList
(
param
,
activeKey
,
1
);
}
// 弱提示渲染
function
handlePlaceHolder
()
{
function
handlePlaceHolder
()
{
let
placeholder
=
''
;
let
placeholder
=
''
;
switch
(
props
.
treeType
)
{
switch
(
activeKey
)
{
case
'departMentTab'
:
case
'departMentTab'
:
placeholder
=
'搜索学员
姓名
、部门'
;
placeholder
=
'搜索学员、部门'
;
break
;
break
;
case
'postGrouptab'
:
case
'postGrouptab'
:
placeholder
=
'搜索学员
姓名/岗位/
岗位组'
;
placeholder
=
'搜索学员
、岗位、
岗位组'
;
break
;
break
;
case
'customGroupTab'
:
case
'customGroupTab'
:
placeholder
=
'搜索学员
姓名/自定义分组集合/自定义分组
'
;
placeholder
=
'搜索学员
、分组、分组集合
'
;
break
;
break
;
default
:
default
:
break
;
break
;
...
@@ -248,6 +297,17 @@ function ChooseAssignorModal(props) {
...
@@ -248,6 +297,17 @@ function ChooseAssignorModal(props) {
return
placeholder
;
return
placeholder
;
}
}
function
handleDepName
(
depArray
)
{
const
depArrayDom
=
depArray
.
map
((
item
,
index
)
=>
{
return
(
<
span
>
<
WWOpenDataCom
type=
'departmentName'
openid=
{
item
}
/>
;
</
span
>
);
});
return
depArrayDom
;
}
return
(
return
(
<
Modal
<
Modal
className=
'choose-assignor-modal'
className=
'choose-assignor-modal'
...
@@ -261,16 +321,13 @@ function ChooseAssignorModal(props) {
...
@@ -261,16 +321,13 @@ function ChooseAssignorModal(props) {
maskClosable=
{
false
}
>
maskClosable=
{
false
}
>
<
div
className=
'assignor-container'
>
<
div
className=
'assignor-container'
>
<
div
className=
'left-list'
>
<
div
className=
'left-list'
>
{
/*
<AutoComplete
<
AutoComplete
dropdownClassName='
certain-category
-search-dropdown'
dropdownClassName=
'
left
-search-dropdown'
dropdownMatchSelectWidth=
{
272
}
dropdownMatchSelectWidth=
{
272
}
allowClear
allowClear
onChange={(value) => setSearchKey(value)}
onChange=
{
(
value
)
=>
setQueryName
(
value
)
}
onSearch={(value) => {
notFoundContent=
{
notFoundContentNode
()
}
getCompleteOptionData(value);
value=
{
queryName
}
}}
// notFoundContent={notFoundContentNode()}
value={searchKey}
open=
{
open
}
open=
{
open
}
onFocus=
{
()
=>
{
onFocus=
{
()
=>
{
setOpen
(
true
);
setOpen
(
true
);
...
@@ -283,7 +340,9 @@ function ChooseAssignorModal(props) {
...
@@ -283,7 +340,9 @@ function ChooseAssignorModal(props) {
}
}
}
}
options=
{
completeOptions
}
options=
{
completeOptions
}
// onSelect={confirmSearchSelect}
// onSelect={confirmSearchSelect}
placeholder={handlePlaceHolder()}></AutoComplete> */
}
placeholder=
{
handlePlaceHolder
()
}
>
<
Search
style=
{
{
width
:
272
}
}
enterButton=
{
<
span
className=
'icon iconfont'
>

</
span
>
}
/>
</
AutoComplete
>
<
div
className=
'data-body'
>
<
div
className=
'data-body'
>
<
Tabs
size=
{
'small'
}
onChange=
{
(
key
)
=>
setActiveKey
(
key
)
}
>
<
Tabs
size=
{
'small'
}
onChange=
{
(
key
)
=>
setActiveKey
(
key
)
}
>
<
TabPane
key=
'departMentTab'
tab=
'部门'
></
TabPane
>
<
TabPane
key=
'departMentTab'
tab=
'部门'
></
TabPane
>
...
...
src/modules/task-center/train-task/modal/ChooseAssignorModal.less
View file @
5314960e
...
@@ -5,8 +5,12 @@
...
@@ -5,8 +5,12 @@
.left-list {
.left-list {
width: 50%;
width: 50%;
margin-right: 24px;
margin-right: 24px;
padding:
0
0 12px 16px;
padding:
12px
0 12px 16px;
border: 1px solid #e8e8e8;
border: 1px solid #e8e8e8;
.ant-select-auto-complete .ant-select-clear {
font-size: 14px;
right: 15px;
}
.data-body {
.data-body {
.ant-tabs-nav {
.ant-tabs-nav {
margin: 0 !important;
margin: 0 !important;
...
@@ -18,7 +22,7 @@
...
@@ -18,7 +22,7 @@
.tree-con {
.tree-con {
overflow-y: scroll;
overflow-y: scroll;
overflow-x: hidden;
overflow-x: hidden;
max-height: 3
67
px;
max-height: 3
23
px;
padding-right: 16px;
padding-right: 16px;
.ant-tree .ant-tree-treenode {
.ant-tree .ant-tree-treenode {
padding: 12px 0 !important;
padding: 12px 0 !important;
...
@@ -102,3 +106,51 @@
...
@@ -102,3 +106,51 @@
}
}
}
}
}
}
.left-search-dropdown {
.catalog-title {
font-size: 14px;
color: #666;
margin-bottom: 14px;
}
.search-result-item {
padding: 14px 0;
color: #333;
.title-icon {
color: #999;
margin-right: 3px;
}
.search-result-item__left {
font-size: 14px;
}
.search-result-item__right {
font-size: 14px;
width: 84px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
color: #999;
text-align: right;
}
}
.ant-select-dropdown-menu-item-group-title {
color: #666;
font-weight: bold;
}
.ant-select-item-option-grouped {
padding-left: 12px;
}
.ant-select-item-option-content {
padding-left: 24px;
}
.empty-con {
text-align: center;
.empty-img {
width: 150px;
height: 150px;
}
.empty-text {
color: #666;
}
}
}
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