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
a700bfe2
Commit
a700bfe2
authored
Jul 15, 2021
by
wufan
Browse files
Options
Browse Files
Download
Plain Diff
fix:合并周优化
parents
aab45bf5
4025c3cf
Show whitespace changes
Inline
Side-by-side
Showing
27 changed files
with
389 additions
and
445 deletions
+389
-445
src/components/ImgClipModal.jsx
+0
-9
src/index.html
+3
-162
src/index.tsx
+1
-1
src/modules/college-manage/CollegeInfoPage.jsx
+1
-3
src/modules/course-manage/components/AddLiveBasic.jsx
+0
-1
src/modules/course-manage/components/AddLiveBasic.less
+0
-6
src/modules/course-manage/components/AddLiveClass.jsx
+4
-1
src/modules/course-manage/components/LiveCourseOpt.jsx
+1
-1
src/modules/course-manage/graphics-course/AddGraphicsCourse.jsx
+1
-2
src/modules/course-manage/offline-course/AddOfflineCourse.jsx
+0
-1
src/modules/course-manage/video-course/AddVideoCourse.jsx
+7
-8
src/modules/knowledge-base/components/Classification.jsx
+1
-1
src/modules/plan-manage/components/BasicInfo.jsx
+0
-1
src/modules/plan-manage/components/UserLearningData.jsx
+1
-1
src/modules/root/Menu.less
+38
-11
src/modules/root/Menu.tsx
+5
-4
src/modules/store-manage/StoreH5DecorationTab.jsx
+1
-5
src/modules/store-manage/StoreInfo.jsx
+0
-1
src/modules/store-manage/StoreWebDecorationTab.jsx
+1
-5
src/modules/teach-tool/components/CourseCategoryManage.jsx
+3
-3
src/modules/teach-tool/components/CourseCategorySiderTree.jsx
+1
-1
src/modules/teach-tool/examination-manager/ExamData.tsx
+127
-87
src/modules/teach-tool/examination-manager/Index.tsx
+3
-0
src/modules/teach-tool/examination-manager/UserData.tsx
+175
-113
src/modules/teach-tool/paper-manage/components/PaperList.jsx
+4
-0
src/modules/teach-tool/paper-manage/components/SelectQuestionList.jsx
+7
-16
src/modules/teach-tool/question-manage/components/QuestionList.jsx
+4
-1
No files found.
src/components/ImgClipModal.jsx
View file @
a700bfe2
...
...
@@ -88,8 +88,6 @@ class ImgClipModal extends React.Component {
checkOrientation=
{
false
}
cropBoxResizable=
{
false
}
center=
{
true
}
// minCropBoxWidth={cropBoxWidth}
// minCropBoxHeight={cropBoxHeight}
cropBoxMovable=
{
false
}
dragMode=
'move'
onInitialized=
{
(
instance
)
=>
{
...
...
@@ -108,13 +106,6 @@ class ImgClipModal extends React.Component {
console
.
log
(
"ratio++++"
,
ratio
);
this
.
state
.
cropperInstace
.
setCanvasData
({
width
:
500
});
const
that
=
this
;
// const containerData = this.state.cropperInstace.getContainerData();
// // Zoom to 50% from the center of the container.
// this.state.cropperInstace.zoomTo(.5,
{
// x: containerData.width / 2,
// y: containerData.height / 2,
//
});
document
.
querySelector
(
'.cropper__box'
).
addEventListener
(
'dblclick'
,
function
(
e
)
{
that
.
state
.
cropperInstace
.
rotate
(
90
)
...
...
src/index.html
View file @
a700bfe2
<!--
* @Author: 吴文洁
* @Date: 2020-08-24 12:20:57
* @LastEditors:
Please set LastEditors
* @LastEditTime: 2021-07-
08 15:07:03
* @LastEditors:
wufan
* @LastEditTime: 2021-07-
15 16:41:14
* @Description:
* @Copyright: 杭州杰竞科技有限公司 版权所有
-->
...
...
@@ -45,6 +45,7 @@
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div
id=
"root"
></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
...
...
@@ -55,166 +56,6 @@
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
<script>
// (function (root, factory) {
// if (typeof define === 'function' && define.amd) {
// // AMD. Register as an anonymous module.
// define([], factory);
// } else if (typeof exports === 'object') {
// // Node. Does not work with strict CommonJS, but
// // only CommonJS-like environments that support module.exports,
// // like Node.
// module.exports = factory();
// } else {
// // Browser globals (root is window)
// root.download = factory();
// }
// })(this, function () {
// return function download(data, strFileName, strMimeType) {
// var self = window, // this script is only for browsers anyway...
// defaultMime = 'application/octet-stream', // this default mime also triggers iframe downloads
// mimeType = strMimeType || defaultMime,
// payload = data,
// url = !strFileName && !strMimeType && payload,
// anchor = document.createElement('a'),
// toString = function (a) {
// return String(a);
// },
// myBlob = self.Blob || self.MozBlob || self.WebKitBlob || toString,
// fileName = strFileName || 'download',
// blob,
// reader;
// myBlob = myBlob.call ? myBlob.bind(self) : Blob;
// if (String(this) === 'true') {
// //reverse arguments, allowing download.bind(true, "text/xml", "export.xml") to act as a callback
// payload = [payload, mimeType];
// mimeType = payload[0];
// payload = payload[1];
// }
// if (url && url.length
<
2048
)
{
// // if no filename and no mime, assume a url was passed as the only argument
// fileName = url.split('/').pop().split('?')[0];
// anchor.href = url; // assign href prop to temp anchor
// if (anchor.href.indexOf(url) !== -1) {
// // if the browser determines that it's a potentially valid url path:
// var ajax = new XMLHttpRequest();
// ajax.open('GET', url, true);
// ajax.responseType = 'blob';
// ajax.onload = function (e) {
// download(e.target.response, fileName, defaultMime);
// };
// setTimeout(function () {
// ajax.send();
// }, 0); // allows setting custom ajax headers using the return:
// return ajax;
// } // end if valid url?
// } // end if url?
// //go ahead and download dataURLs right away
// if (/^data\:[\w+\-]+\/[\w+\-]+[,;]/.test(payload)) {
// if (payload.length > 1024 * 1024 * 1.999 && myBlob !== toString) {
// payload = dataUrlToBlob(payload);
// mimeType = payload.type || defaultMime;
// } else {
// return navigator.msSaveBlob // IE10 can't do a[download], only Blobs:
// ? navigator.msSaveBlob(dataUrlToBlob(payload), fileName)
// : saver(payload); // everyone else can save dataURLs un-processed
// }
// } //end if dataURL passed?
// blob = payload instanceof myBlob ? payload : new myBlob([payload], { type: mimeType });
// function dataUrlToBlob(strUrl) {
// var parts = strUrl.split(/[:;,]/),
// type = parts[1],
// decoder = parts[2] == 'base64' ? atob : decodeURIComponent,
// binData = decoder(parts.pop()),
// mx = binData.length,
// i = 0,
// uiArr = new Uint8Array(mx);
// for (i; i
<
mx
;
++
i
)
uiArr
[
i
]
=
binData
.
charCodeAt
(
i
);
// return new myBlob([uiArr], { type: type });
// }
// function saver(url, winMode) {
// if ('download' in anchor) {
// //html5 A[download]
// anchor.href = url;
// anchor.setAttribute('download', fileName);
// anchor.className = 'download-js-link';
// anchor.innerHTML = 'downloading...';
// anchor.style.display = 'none';
// document.body.appendChild(anchor);
// setTimeout(function () {
// anchor.click();
// document.body.removeChild(anchor);
// if (winMode === true) {
// setTimeout(function () {
// self.URL.revokeObjectURL(anchor.href);
// }, 250);
// }
// }, 66);
// return true;
// }
// // handle non-a[download] safari as best we can:
// if (/(Version)\/(\d+)\.(\d+)(?:\.(\d+))?.*Safari\//.test(navigator.userAgent)) {
// url = url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
// if (!window.open(url)) {
// // popup blocked, offer direct download:
// if (confirm('Displaying New Document\n\nUse Save As... to download, then click back to return to this page.')) {
// location.href = url;
// }
// }
// return true;
// }
// //do iframe dataURL download (old ch+FF):
// var f = document.createElement('iframe');
// document.body.appendChild(f);
// if (!winMode) {
// // force a mime that will download:
// url = 'data:' + url.replace(/^data:([\w\/\-\+]+)/, defaultMime);
// }
// f.src = url;
// setTimeout(function () {
// document.body.removeChild(f);
// }, 333);
// } //end saver
// if (navigator.msSaveBlob) {
// // IE10+ : (has Blob, but not a[download] or URL)
// return navigator.msSaveBlob(blob, fileName);
// }
// if (self.URL) {
// // simple fast and modern way using Blob and URL:
// saver(self.URL.createObjectURL(blob), true);
// } else {
// // handle non-Blob()+non-URL browsers:
// if (typeof blob === 'string' || blob.constructor === toString) {
// try {
// return saver('data:' + mimeType + ';base64,' + self.btoa(blob));
// } catch (y) {
// return saver('data:' + mimeType + ',' + encodeURIComponent(blob));
// }
// }
// // Blob but not URL support:
// reader = new FileReader();
// reader.onload = function (e) {
// saver(this.result);
// };
// reader.readAsDataURL(blob);
// }
// return true;
// }; /* end download() */
// });
</script>
</body>
</html>
src/index.tsx
View file @
a700bfe2
...
...
@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-04-27 20:35:34
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-07-0
4 16:59:14
* @LastEditTime: 2021-07-0
8 19:22:18
* @Description:
*/
...
...
src/modules/college-manage/CollegeInfoPage.jsx
View file @
a700bfe2
...
...
@@ -53,7 +53,6 @@ class CollegeInfoPage extends React.Component {
})
}
handleSelectCover
=
(
file
)
=>
{
// this.uploadImage(file);
this
.
setState
({
visible
:
true
,
imageFile
:
file
...
...
@@ -112,9 +111,8 @@ class CollegeInfoPage extends React.Component {
}
=
this
.
state
;
return
(
<
div
className=
"page college-info-page"
>
<
div
className=
"content-header"
>
学院
基本
信息
</
div
>
<
div
className=
"content-header"
>
学院信息
</
div
>
<
div
className=
"box"
>
<
div
className=
"college-info-header"
>
学院基本信息
</
div
>
<
div
className=
"college-info-page-form"
>
<
Form
ref=
{
this
.
formRef
}
>
...
...
src/modules/course-manage/components/AddLiveBasic.jsx
View file @
a700bfe2
...
...
@@ -83,7 +83,6 @@ class AddLiveBasic extends React.Component {
visible
:
true
,
imageFile
:
file
});
// this.uploadImage(file);
}
...
...
src/modules/course-manage/components/AddLiveBasic.less
View file @
a700bfe2
...
...
@@ -84,9 +84,4 @@
}
.preview-url-box{
overflow: hidden;
// img{
// width:500px !important;
// height:282px !important;
// transform:none !important;
// }
}
\ No newline at end of file
src/modules/course-manage/components/AddLiveClass.jsx
View file @
a700bfe2
...
...
@@ -175,7 +175,10 @@ class AddLiveClass extends React.Component {
<
Tooltip
overlayStyle=
{
{
maxWidth
:
300
,
zIndex
:
'9999'
}
}
title=
{
<
div
style=
{
{
width
:
'266px'
}
}
>
支持按上课日期批量创建直播课,创建后按“课程名称_日期”命名,例如:
<
br
/>
张三的语文课_9月18日
<
br
/>
张三的语文课_9月19日......
</
div
>
}
>
<
span
className=
"iconfont"
>

</
span
>
<
span
style=
{
{
color
:
"rgba(191, 191, 191, 1)"
,
fontWeight
:
400
}
}
className=
"iconfont"
>

</
span
>
</
Tooltip
>
:
</
span
>
<
div
>
...
...
src/modules/course-manage/components/LiveCourseOpt.jsx
View file @
a700bfe2
...
...
@@ -53,7 +53,7 @@ class LiveCourseOpt extends React.Component {
{
userRole
!==
"CloudLecturer"
&&
<
Button
type=
"primary"
onClick=
{
this
.
handleCreateLiveCouese
}
>
新建直播课
</
Button
>
}
{
!
this
.
state
.
isMac
&&
<
Button
onClick=
{
this
.
handleDownloadClient
}
>
下载直播客户端
</
Button
>
}
<
Button
onClick=
{
this
.
handleDownloadClient
}
>
下载直播客户端
</
Button
>
</
div
>
</
div
>
)
...
...
src/modules/course-manage/graphics-course/AddGraphicsCourse.jsx
View file @
a700bfe2
...
...
@@ -2,7 +2,7 @@
* @Author: 吴文洁
* @Date: 2020-08-05 10:07:47
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-07-0
6 14:46:4
0
* @LastEditTime: 2021-07-0
8 19:32:5
0
* @Description: 图文课新增/编辑页
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
...
...
@@ -280,7 +280,6 @@ class AddGraphicsCourse extends React.Component {
};
handleSelectCover
=
(
file
)
=>
{
// this.uploadCoverImage(file);
this
.
setState
({
visible
:
true
,
imageFile
:
file
...
...
src/modules/course-manage/offline-course/AddOfflineCourse.jsx
View file @
a700bfe2
...
...
@@ -356,7 +356,6 @@ class AddOfflineCourse extends React.Component {
}
handleSelectCover
=
(
file
)
=>
{
// this.uploadCoverImage(file);
this
.
setState
({
visible
:
true
,
imageFile
:
file
...
...
src/modules/course-manage/video-course/AddVideoCourse.jsx
View file @
a700bfe2
/*
* @Author: 吴文洁
* @Date: 2020-08-05 10:07:47
* @LastEditors:
Please set LastEditors
* @LastEditTime: 2021-07-
08 15:07:46
* @LastEditors:
wufan
* @LastEditTime: 2021-07-
15 16:41:48
* @Description: 视频课新增/编辑页
* @Copyright: 杭州杰竞科技有限公司 版权所有
*/
...
...
@@ -259,12 +259,11 @@ class AddVideoCourse extends React.Component {
handleSelectStudent
=
(
studentIds
)
=>
{
let
studentList
=
[];
_
.
each
(
studentIds
,
(
item
)
=>
{
studentList
.
push
({
studentId
:
item
});
});
// this.setState({ studentModal: null });
this
.
setState
({
studentList
});
this
.
setState
({
studentModal
:
false
});
};
studentList
.
push
({
studentId
:
item
})
})
this
.
setState
({
studentList
})
this
.
setState
({
studentModal
:
false
})
}
// 显示预览弹窗
handleShowPreviewModal
=
()
=>
{
...
...
src/modules/knowledge-base/components/Classification.jsx
View file @
a700bfe2
...
...
@@ -188,7 +188,7 @@ class Classification extends Component {
<
div
className=
'sider-title'
>
知识分类
</
div
>
<
Search
className=
'sider-search'
placeholder=
'搜索
名称分类
'
placeholder=
'搜索
分类名称
'
onSearch=
{
(
value
)
=>
{
this
.
queryCategoryTree
(
value
);
}
}
...
...
src/modules/plan-manage/components/BasicInfo.jsx
View file @
a700bfe2
...
...
@@ -72,7 +72,6 @@ class BasicInfo extends React.Component {
},
1000
);
};
handleSelectCover
=
(
file
)
=>
{
// this.uploadImage(file);
this
.
setState
({
visible
:
true
,
imageFile
:
file
...
...
src/modules/plan-manage/components/UserLearningData.jsx
View file @
a700bfe2
...
...
@@ -330,7 +330,7 @@ class UserLearningData extends React.Component {
<
span
>
<
span
>
学习进度
</
span
>
<
Tooltip
title=
'学员培训计划中达到“已完成”状态的课程数/总课程数'
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
}
}
>
<
i
className=
'icon iconfont'
style=
{
{
marginLeft
:
'5px'
,
cursor
:
'pointer'
,
color
:
'#bfbfbf'
,
fontSize
:
'14px'
,
fontWeight
:
'normal'
}
}
>

</
i
>
</
Tooltip
>
...
...
src/modules/root/Menu.less
View file @
a700bfe2
...
...
@@ -97,7 +97,7 @@
margin: 6px 8px;
width: calc(100% - 15px);
&:hover {
background:
#f3f6fa
;
background:
rgba(41, 102, 255, .05)
;
border-radius: 2px;
color: #333;
}
...
...
@@ -106,8 +106,10 @@
background-color: @active-color;
color: #fff;
border-radius: 2px;
&:hover {
color: #fff;
&.single-menu {
background: rgba(41, 102, 255, .1) !important;
color: @active-color;
font-weight:500;
}
}
.ant-menu-submenu {
...
...
@@ -117,6 +119,9 @@
}
.ant-menu-item {
padding-left: 46px !important;
&:hover {
color: #333!important;
}
}
}
...
...
@@ -124,14 +129,22 @@
color: @active-color;
.ant-menu-item-selected {
color: #fff;
color: @active-color;
font-weight: 500;
&:hover {
color: @active-color!important;
}
.listType {
background: @active-color;
}
}
.ant-menu-submenu-arrow {
right: 10px!important;
color: @active-color;
}
}
.ant-menu-submenu-arrow {
right:
22px
;
right:
10px!important
;
color: #5e606a;
}
}
...
...
@@ -266,16 +279,30 @@
.shink-footer {
left: 74px;
}
// &:hover{
// .menu-type-icon{
// display:inline-block;
// }
// }
}
.ant-menu-inline .ant-menu-item, .ant-menu-inline .ant-menu-submenu-title {
width: calc(100% - 15px)!important;
}
.ant-menu-submenu:hover {
// background: rgba(41, 102, 255, .05) !important;
&.ant-menu-submenu-title:hover {
color: #333333!important;
}
.ant-menu-submenu-title > .ant-menu-submenu-arrow {
color: #5e606a!important;
}
&.icon-img-box {
background-color: rgba(41, 102, 255, .05)!important;
}
}
.ant-menu-light .ant-menu-submenu-title:hover {
color: #333!important;
background: rgba(41, 102, 255, .05) !important;
}
.ant-menu:not(.ant-menu-horizontal) .ant-menu-item-selected {
background:
@active-color
!important;
background:
rgba(41, 102, 255, .1)
!important;
}
.ant-menu.ant-menu-dark,
.ant-menu-dark .ant-menu-sub,
...
...
src/modules/root/Menu.tsx
View file @
a700bfe2
...
...
@@ -239,10 +239,10 @@ function Aside(props: any) {
icon=
{
!
menuType
&&
item
.
groupCode
===
selectKeyParent
?
(
<
div
className=
'icon-img-box'
style=
{
{
backgroundColor
:
'#2966FF'
,
width
:
'40px'
,
height
:
'40px'
}
}
>
<
img
src=
{
item
.
selectI
mg
}
className=
'icon-img'
/>
<
img
src=
{
item
.
i
mg
}
className=
'icon-img'
/>
</
div
>
)
:
(
<
div
className=
'icon-img-box'
style=
{
{
backgroundColor
:
'#fff'
,
width
:
'40px'
,
height
:
'40px'
,
display
:
'inline-block'
}
}
>
<
div
className=
'icon-img-box'
style=
{
{
width
:
'40px'
,
height
:
'40px'
,
display
:
'inline-block'
}
}
>
<
img
src=
{
item
.
img
}
className=
'icon-img'
/>
</
div
>
)
...
...
@@ -269,6 +269,7 @@ function Aside(props: any) {
}
else
{
return
(
<
Menu
.
Item
className=
"single-menu"
onClick=
{
()
=>
{
toggleMenu
(
item
,
item
.
groupCode
);
}
}
...
...
@@ -276,11 +277,11 @@ function Aside(props: any) {
icon=
{
!
menuType
&&
item
.
groupCode
===
selectKeyParent
?
(
<
div
className=
'icon-img-box'
style=
{
{
backgroundColor
:
'#2966FF'
}
}
>
<
img
src=
{
item
.
selectI
mg
}
className=
'icon-img'
/>
<
img
src=
{
item
.
i
mg
}
className=
'icon-img'
/>
</
div
>
)
:
(
<
div
className=
'icon-img-box'
>
<
img
src=
{
selectKey
===
item
.
groupCode
?
item
.
selectImg
:
item
.
img
}
className=
'icon-img'
/>
<
img
src=
{
item
.
img
}
className=
'icon-img'
/>
</
div
>
)
}
>
...
...
src/modules/store-manage/StoreH5DecorationTab.jsx
View file @
a700bfe2
...
...
@@ -2,7 +2,7 @@
* @Author: wufan
* @Date: 2020-11-30 10:47:38
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-07-08 1
4:25:58
* @LastEditTime: 2021-07-08 1
9:35:17
* @Description: web学院banner页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
...
...
@@ -210,10 +210,6 @@ class StoreH5Decoration extends React.Component {
// 选择云盘资源
handleSelectImg
=
(
file
)
=>
{
// this.setState({
// showSelectFileModal: false,
// });
// this.uploadImage(file);
if
(
file
){
this
.
setState
({
visible
:
true
,
...
...
src/modules/store-manage/StoreInfo.jsx
View file @
a700bfe2
...
...
@@ -74,7 +74,6 @@ class StoreInfo extends React.Component {
})
}
handleSelectCover
=
(
file
)
=>
{
// this.uploadImage(file);
this
.
setState
({
visible
:
true
,
imageFile
:
file
...
...
src/modules/store-manage/StoreWebDecorationTab.jsx
View file @
a700bfe2
...
...
@@ -2,7 +2,7 @@
* @Author: wufan
* @Date: 2020-11-30 10:47:38
* @LastEditors: Please set LastEditors
* @LastEditTime: 2021-07-08 1
4:26:11
* @LastEditTime: 2021-07-08 1
9:35:27
* @Description: web学院banner页面
* @@Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
...
...
@@ -209,10 +209,6 @@ class StoreWebDecoration extends React.Component {
// 选择云盘资源
handleSelectImg
=
(
file
)
=>
{
// this.setState({
// showSelectFileModal: false,
// });
// this.uploadImage(file);
if
(
file
){
this
.
setState
({
visible
:
true
,
...
...
src/modules/teach-tool/components/CourseCategoryManage.jsx
View file @
a700bfe2
...
...
@@ -539,15 +539,15 @@ class CourseCategoryManage extends Component {
return
(
<
div
className=
'page course-category-manage'
>
{
[
'aid'
,
'knowledge'
].
includes
(
getParameterByName
(
'from'
))
?
(
<
Breadcrumbs
navList=
'
课程分类
'
goBack=
{
()
=>
window
.
RCHistory
.
goBack
()
}
/>
<
Breadcrumbs
navList=
'
分类管理
'
goBack=
{
()
=>
window
.
RCHistory
.
goBack
()
}
/>
)
:
(
<
div
className=
'content-header'
>
课程分类
</
div
>
<
div
className=
'content-header'
>
分类管理
</
div
>
)
}
<
div
className=
'box'
>
<
div
className=
'search-condition'
>
<
span
className=
'search-label'
>
搜索名称:
</
span
>
<
Search
placeholder=
'
请输入
名称'
placeholder=
'
搜索分类
名称'
style=
{
{
width
:
'300px'
}
}
onSearch=
{
(
value
)
=>
this
.
queryCategoryTree
(
'init'
,
value
)
}
className=
'search-input'
...
...
src/modules/teach-tool/components/CourseCategorySiderTree.jsx
View file @
a700bfe2
...
...
@@ -189,7 +189,7 @@ class CourseCategorySiderTree extends Component {
)
}
<
Search
className=
'sider-search'
placeholder=
'搜索
名称分类
'
placeholder=
'搜索
分类名称
'
onSearch=
{
(
value
)
=>
{
this
.
queryCategoryTree
(
'init'
,
value
);
}
}
...
...
src/modules/teach-tool/examination-manager/ExamData.tsx
View file @
a700bfe2
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
moment
from
'moment'
;
import
'./userData.less'
;
const
{
Search
}
=
Input
;
const
{
Option
}
=
Select
;
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
;
type
:
"ascend"
|
"descend"
|
null
|
undefined
;
}
function
ExamData
(
props
:
any
)
{
...
...
@@ -18,37 +17,37 @@ function ExamData(props: any) {
};
const
examDataInit
:
any
=
{};
const
queryInit
:
any
=
{
current
:
1
,
size
:
10
,
order
:
'SORT_ASC'
};
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
[
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
:
'不定项选择题'
,
SINGLE_CHOICE
:
"单选题"
,
MULTI_CHOICE
:
"多选题"
,
JUDGE
:
"判断题"
,
GAP_FILLING
:
"填空题"
,
INDEFINITE_CHOICE
:
"不定项选择题"
,
};
const
userTypeEnum
=
{
WORK_WE_CHAT
:
'企业微信'
,
WE_CHAT
:
'微信'
,
WORK_WE_CHAT
:
"企业微信"
,
WE_CHAT
:
"微信"
,
};
const
userExamStateEnum
=
{
EXAM
:
'进行中'
,
LACK_EXAM
:
'缺考'
,
FINISH_EXAM
:
'已考试'
,
EXAM
:
"进行中"
,
LACK_EXAM
:
"缺考"
,
FINISH_EXAM
:
"已考试"
,
};
const
orderEnum
=
{
currentAccuracy
:
{
ascend
:
'ACCURACY_ASC'
,
descend
:
'ACCURACY_DESC'
,
ascend
:
"ACCURACY_ASC"
,
descend
:
"ACCURACY_DESC"
,
},
};
...
...
@@ -64,7 +63,7 @@ function ExamData(props: any) {
},
[
query
]);
function
queryExamUserData
()
{
Service
.
Hades
(
'public/hades/queryExamQuestionData'
,
{
Service
.
Hades
(
"public/hades/queryExamQuestionData"
,
{
examId
:
props
.
examId
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
...
...
@@ -75,7 +74,7 @@ function ExamData(props: any) {
}
function
queryExamUserDataList
()
{
Service
.
Hades
(
'public/hades/queryExamQuestionDataList'
,
{
Service
.
Hades
(
"public/hades/queryExamQuestionDataList"
,
{
...
query
,
examId
:
props
.
examId
,
tenantId
:
User
.
getStoreId
(),
...
...
@@ -92,35 +91,38 @@ function ExamData(props: any) {
const
columns
=
[
{
title
:
'序号'
,
dataIndex
:
'sort'
,
title
:
"序号"
,
dataIndex
:
"sort"
,
width
:
60
,
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
{
...
...
@@ -130,25 +132,33 @@ function ExamData(props: any) {
}),
},
{
title
:
'本次正确率'
,
dataIndex
:
'currentAccuracy'
,
title
:
"本次正确率"
,
dataIndex
:
"currentAccuracy"
,
sorter
:
true
,
sortOrder
:
field
===
'currentAccuracy'
?
order
:
sortStatus
.
type
,
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'
>
历史正确率
{
" "
}
<
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'
,
dataIndex
:
"totalAccuracy"
,
render
:
(
text
:
any
)
=>
<
span
>
{
parseInt
((
text
*
100
)
as
any
)
}
%
</
span
>,
},
];
...
...
@@ -174,78 +184,97 @@ function ExamData(props: any) {
}
function
download
()
{
Service
.
Hades
(
'public/hades/exportExamData'
,
{
Service
.
Hades
(
"public/hades/exportExamData"
,
{
// ...query,
examId
:
props
.
examId
,
exportDataType
:
'EXAM_QUESTION_DATA'
,
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
);
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'
>
<
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
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
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
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
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
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
>
...
...
@@ -257,11 +286,22 @@ function ExamData(props: any) {
</
Button
>
)
}
<
div
className=
'content'
>
<
Table
bordered
size=
'small'
columns=
{
columns
}
dataSource=
{
list
}
onChange=
{
onChange
}
pagination=
{
false
}
></
Table
>
<
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'
size=
"small"
current=
{
query
.
current
-
1
}
pageSize=
{
query
.
size
}
total=
{
total
}
...
...
src/modules/teach-tool/examination-manager/Index.tsx
View file @
a700bfe2
...
...
@@ -11,6 +11,8 @@ import { XMContext } from '@/store/context';
import
ExamShareModal
from
'./ExamShareModal'
;
import
DataAnalysic
from
'./DataAnalysic'
;
import
PreviewModal
from
'./PreviewModal'
;
import
college
from
'@/common/lottie/college.json'
;
import
'./index.less'
;
const
{
RangePicker
}
=
DatePicker
;
const
{
Search
}
=
Input
;
...
...
@@ -426,6 +428,7 @@ function ExaminationManager(props: any) {
pagination=
{
false
}
style=
{
{
margin
:
'0px 0 16px'
}
}
renderEmpty=
{
{
image
:
college
,
description
:
<
span
style=
{
{
display
:
'block'
,
paddingBottom
:
24
}
}
>
暂无数据
</
span
>,
}
}
></
XMTable
>
{
total
>
0
&&
(
...
...
src/modules/teach-tool/examination-manager/UserData.tsx
View file @
a700bfe2
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
'./userData.less'
;
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
;
type
:
"ascend"
|
"descend"
|
null
|
undefined
;
}
interface
User
{
key
:
number
;
...
...
@@ -29,45 +31,45 @@ function DataAnalysic(props: any) {
const
[
list
,
setList
]
=
useState
([]);
const
[
query
,
setQuery
]
=
useState
(
queryInit
);
const
[
total
,
setTotal
]
=
useState
(
0
);
const
[
field
,
setfield
]
=
useState
(
''
);
const
[
field
,
setfield
]
=
useState
(
""
);
const
[
allData
,
setAllData
]
=
useState
(
0
);
const
[
order
,
setOrder
]
=
useState
(
sortStatus
.
type
);
const
userTypeEnum
=
{
WORK_WE_CHAT
:
'企业微信'
,
WE_CHAT
:
'微信'
,
WORK_WE_CHAT
:
"企业微信"
,
WE_CHAT
:
"微信"
,
};
const
userExamStateEnum
=
{
EXAM
:
'进行中'
,
LACK_EXAM
:
'缺考'
,
FINISH_EXAM
:
'已考试'
,
EXAM
:
"进行中"
,
LACK_EXAM
:
"缺考"
,
FINISH_EXAM
:
"已考试"
,
};
const
ExamPassColorEnum
=
{
EXAM_FAIL
:
'rgba(255, 79, 79, 1)'
,
EXAM_PASS
:
'rgba(59, 189, 170, 1)'
,
EXAM_FAIL
:
"rgba(255, 79, 79, 1)"
,
EXAM_PASS
:
"rgba(59, 189, 170, 1)"
,
};
const
ExamPassEnum
=
{
EXAM_FAIL
:
'不及格'
,
EXAM_PASS
:
'及格'
,
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)'
,
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'
,
ascend
:
"EXAM_SCORE_ASC"
,
descend
:
"EXAM_SCORE_DESC"
,
},
userDuration
:
{
ascend
:
'USER_DURATION_ASC'
,
descend
:
'USER_DURATION_DESC'
,
ascend
:
"USER_DURATION_ASC"
,
descend
:
"USER_DURATION_DESC"
,
},
};
...
...
@@ -83,7 +85,7 @@ function DataAnalysic(props: any) {
},
[
query
]);
function
queryExamUserData
()
{
Service
.
Hades
(
'public/hades/queryExamUserData'
,
{
Service
.
Hades
(
"public/hades/queryExamUserData"
,
{
examId
:
props
.
examId
,
tenantId
:
User
.
getStoreId
(),
userId
:
User
.
getStoreUserId
(),
...
...
@@ -94,7 +96,7 @@ function DataAnalysic(props: any) {
}
function
queryExamUserDataList
()
{
Service
.
Hades
(
'public/hades/queryExamUserDataList'
,
{
Service
.
Hades
(
"public/hades/queryExamUserDataList"
,
{
...
query
,
examId
:
props
.
examId
,
tenantId
:
User
.
getStoreId
(),
...
...
@@ -111,79 +113,102 @@ function DataAnalysic(props: any) {
const
columns
:
ColumnsType
<
User
>
=
[
{
title
:
'学员'
,
dataIndex
:
'userName'
,
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)'
}
}
>
<
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
:
"phone"
,
},
{
title
:
'考试状态'
,
dataIndex
:
'userExamState'
,
title
:
"考试状态"
,
dataIndex
:
"userExamState"
,
render
:
(
text
:
any
)
=>
(
<
span
>
{
' '
}
<
span
className=
'exstatus'
style=
{
{
background
:
(
userExamStateColorEnum
as
any
)[
text
]
}
}
></
span
>
{
(
userExamStateEnum
as
any
)[
text
]
}
{
" "
}
<
span
className=
"exstatus"
style=
{
{
background
:
(
userExamStateColorEnum
as
any
)[
text
]
}
}
></
span
>
{
" "
}
{
(
userExamStateEnum
as
any
)[
text
]
}
</
span
>
),
},
{
title
:
'考试成绩'
,
dataIndex
:
'score'
,
title
:
"考试成绩"
,
dataIndex
:
"score"
,
sorter
:
true
,
sortOrder
:
field
===
'score'
?
order
:
sortStatus
.
type
,
sortOrder
:
field
===
"score"
?
order
:
sortStatus
.
type
,
render
:
(
text
:
any
,
record
:
any
)
=>
(
<
span
>
{
' '
}
{
text
}{
' '
}
{
" "
}
{
text
}{
" "
}
<
span
style=
{
{
border
:
`1px solid ${(ExamPassColorEnum as any)[record.examPass]}`
,
border
:
`1px solid ${
(ExamPassColorEnum as any)[record.examPass]
}`
,
fontSize
:
12
,
color
:
(
ExamPassColorEnum
as
any
)[
record
.
examPass
],
display
:
'inline-block'
,
padding
:
'0px 2px'
,
}
}
>
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
:
"examStartTime"
,
render
:
(
text
:
any
)
=>
(
<
span
>
{
moment
(
text
).
format
(
"YYYY-MM-DD HH:mm"
)
}
</
span
>
),
},
{
title
:
'考试用时'
,
dataIndex
:
'userDuration'
,
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
>,
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'
,
title
:
"操作"
,
key
:
""
,
dataIndex
:
"edit"
,
render
:
(
value
:
any
,
record
:
any
)
=>
{
return
(
<
Choose
>
<
When
condition=
{
record
.
userExamState
===
'FINISH_EXAM'
}
>
<
When
condition=
{
record
.
userExamState
===
"FINISH_EXAM"
}
>
<
div
className=
'answer-detail'
className=
"answer-detail"
onClick=
{
()
=>
{
checkAnswerDetail
(
record
);
}
}
>
}
}
>
答题详情
</
div
>
</
When
>
...
...
@@ -204,16 +229,16 @@ function DataAnalysic(props: any) {
}
function
download
()
{
Service
.
Hades
(
'public/hades/exportExamData'
,
{
Service
.
Hades
(
"public/hades/exportExamData"
,
{
// ...query,
examId
:
props
.
examId
,
exportDataType
:
'EXAM_USER_DATA'
,
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
);
const
dom
=
(
document
as
any
).
getElementById
(
"load-play-back-excel"
);
dom
.
setAttribute
(
"href"
,
res
.
result
);
dom
.
click
();
});
}
...
...
@@ -227,69 +252,92 @@ function DataAnalysic(props: any) {
}
return
(
<
div
className=
'rr'
>
<
a
target=
'_blank'
download
id=
'load-play-back-excel'
style=
{
{
position
:
'absolute'
,
left
:
'-10000px'
}
}
>
<
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
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
.
finishCnt
||
0
}
</
div
>
<
div
className=
'percent'
>
占比
{
parseInt
(((
useData
.
finishCnt
||
0
)
/
(
useData
.
joinCnt
||
1
))
*
100
+
''
)
}
%
</
div
>
<
div
className=
'subTitle'
>
完成考试数 (人)
</
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=
'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
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
className=
"item"
>
<
div
className=
"num"
>
{
" "
}
{
window
.
formatHourTime
(
useData
.
averageDuration
||
0
)
}{
" "
}
</
div
>
<
div
className=
'item'
>
<
div
className=
'num'
>
{
window
.
formatHourTime
(
useData
.
averageDuration
||
0
)
}
</
div
>
<
div
className=
'percent'
></
div
>
<
div
className=
'subTitle'
>
平均用时
</
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
>
<
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=
'搜索学员名或手机号'
className=
"search-input"
placeholder=
"搜索学员名或手机号"
onChange=
{
(
e
)
=>
{
const
_query
=
{
...
query
};
_query
.
searchKey
=
e
.
target
.
value
;
setQuery
(
_query
);
}
}
onSearch=
{
()
=>
{}
}
enterButton=
{
<
span
className=
'icon iconfont'
>

</
span
>
}
enterButton=
{
<
span
className=
"icon iconfont"
>

</
span
>
}
/>
</
div
>
<
div
className=
'search-condition__item'
>
<
span
className=
'search-name'
>
学员类型:
</
span
>
<
div
className=
"search-condition__item"
>
<
span
className=
"search-name"
>
学员类型:
</
span
>
<
Select
value=
{
query
.
userSource
}
placeholder=
'请选择学员类型'
placeholder=
"请选择学员类型"
onChange=
{
(
val
)
=>
{
const
_query
=
{
...
query
};
_query
.
userSource
=
val
;
setQuery
(
_query
);
}
}
className=
'search-input'
allowClear
>
className=
"search-input"
allowClear
>
{
Object
.
keys
(
userTypeEnum
).
map
((
key
:
any
)
=>
{
return
(
<
Option
value=
{
key
}
key=
{
key
}
>
...
...
@@ -300,18 +348,19 @@ function DataAnalysic(props: any) {
</
Select
>
</
div
>
<
div
className=
'search-condition__item'
>
<
span
className=
'search-name'
>
考试状态:
</
span
>
<
div
className=
"search-condition__item"
>
<
span
className=
"search-name"
>
考试状态:
</
span
>
<
Select
value=
{
query
.
userExamState
}
placeholder=
'请选择考试状态'
placeholder=
"请选择考试状态"
onChange=
{
(
val
)
=>
{
const
_query
=
{
...
query
};
_query
.
userExamState
=
val
;
setQuery
(
_query
);
}
}
className=
'search-input'
allowClear
>
className=
"search-input"
allowClear
>
{
Object
.
keys
(
userExamStateEnum
).
map
((
key
:
any
)
=>
{
return
(
<
Option
value=
{
key
}
key=
{
key
}
>
...
...
@@ -322,15 +371,16 @@ function DataAnalysic(props: any) {
</
Select
>
</
div
>
</
div
>
<
div
className=
'reset-fold-area'
>
<
Tooltip
title=
'清空筛选'
>
<
div
className=
"reset-fold-area"
>
<
Tooltip
title=
"清空筛选"
>
<
span
className=
'resetBtn iconfont icon'
className=
"resetBtn iconfont icon"
onClick=
{
()
=>
{
setfield
(
''
);
setfield
(
""
);
setQuery
({
current
:
1
,
size
:
10
});
}
}
>

{
' '
}
}
}
>

{
" "
}
</
span
>
</
Tooltip
>
</
div
>
...
...
@@ -342,11 +392,23 @@ function DataAnalysic(props: any) {
</
Button
>
)
}
<
div
className=
'content analysic-content'
>
<
Table
bordered
size=
'small'
rowClassName=
'analysic-content-row'
columns=
{
columns
}
dataSource=
{
list
}
onChange=
{
onChange
}
pagination=
{
false
}
></
Table
>
<
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'
size=
"small"
current=
{
query
.
current
-
1
}
pageSize=
{
query
.
size
}
total=
{
total
}
...
...
src/modules/teach-tool/paper-manage/components/PaperList.jsx
View file @
a700bfe2
...
...
@@ -31,6 +31,8 @@ import _ from "underscore";
import
PaperPreviewModal
from
"../modal/PreviewPaperModal"
;
import
MoveModal
from
'../../modal/MoveModal'
;
import
Bus
from
"@/core/bus"
;
import
college
from
'@/common/lottie/college'
;
const
{
Search
}
=
Input
;
...
...
@@ -625,6 +627,7 @@ class PaperList extends Component {
bordered
loading=
{
loading
}
renderEmpty=
{
{
image
:
college
,
description
:
<
span
style=
{
{
display
:
'block'
,
paddingBottom
:
24
}
}
>
还没有试卷
</
span
>
}
}
/>
...
...
@@ -641,6 +644,7 @@ class PaperList extends Component {
pagination=
{
false
}
bordered
renderEmpty=
{
{
image
:
college
,
description
:
<
span
style=
{
{
display
:
'block'
,
paddingBottom
:
24
}
}
>
还没有试卷
</
span
>
}
}
/>
...
...
src/modules/teach-tool/paper-manage/components/SelectQuestionList.jsx
View file @
a700bfe2
...
...
@@ -25,6 +25,8 @@ import AidToolService from "@/domains/aid-tool-domain/AidToolService";
import
_
from
"underscore"
;
import
Bus
from
"@/core/bus"
;
import
moment
from
'moment'
;
import
{
XMTable
}
from
'@/components'
;
import
college
from
'@/common/lottie/college'
;
const
{
Search
}
=
Input
;
const
{
RangePicker
}
=
DatePicker
;
...
...
@@ -201,19 +203,6 @@ class SelectQuestionList extends Component {
return
columns
;
};
// 自定义表格空状态
customizeRenderEmpty
=
()
=>
{
return
(
<
Empty
image=
"https://image.xiaomaiketang.com/xm/emptyTable.png"
imageStyle=
{
{
height
:
100
,
}
}
description=
{
"还没有题目"
}
></
Empty
>
);
};
onShowSizeChange
=
(
current
,
size
)
=>
{
if
(
current
==
size
)
{
return
;
...
...
@@ -431,8 +420,11 @@ class SelectQuestionList extends Component {
)
}
</
div
>
<
div
className=
"select-question-content"
>
<
ConfigProvider
renderEmpty=
{
this
.
customizeRenderEmpty
}
>
<
Table
<
XMTable
renderEmpty=
{
{
image
:
college
,
description
:
'还没有题目'
}
}
rowSelection=
{
rowSelection
}
rowKey=
{
(
record
)
=>
record
.
id
}
dataSource=
{
dataSource
}
...
...
@@ -441,7 +433,6 @@ class SelectQuestionList extends Component {
onChange=
{
this
.
handleChangeTable
}
bordered
/>
</
ConfigProvider
>
<
div
className=
"box-footer"
>
<
PageControl
current=
{
current
-
1
}
...
...
src/modules/teach-tool/question-manage/components/QuestionList.jsx
View file @
a700bfe2
...
...
@@ -7,7 +7,7 @@
* @Copyrigh: © 2020 杭州杰竞科技有限公司 版权所有
*/
import
React
,
{
Component
}
from
'react'
;
import
{
Table
,
ConfigProvider
,
Empty
,
Row
,
Input
,
Select
,
Tooltip
,
Space
,
Button
,
Modal
,
message
,
Menu
,
Dropdown
,
DatePicker
}
from
'antd'
;
import
{
Row
,
Input
,
Select
,
Tooltip
,
Space
,
Button
,
Modal
,
message
,
Menu
,
Dropdown
,
DatePicker
}
from
'antd'
;
import
_
from
'underscore'
;
import
{
Route
,
withRouter
}
from
'react-router-dom'
;
import
{
DownOutlined
}
from
'@ant-design/icons'
;
...
...
@@ -21,6 +21,8 @@ import Bus from '@/core/bus';
import
moment
from
'moment'
;
import
Service
from
'@/common/js/service'
;
import
MoveModal
from
'../../modal/MoveModal'
;
import
college
from
'@/common/lottie/college'
;
import
'./QuestionList.less'
;
const
{
RangePicker
}
=
DatePicker
;
...
...
@@ -671,6 +673,7 @@ class QuestionList extends Component {
onChange=
{
this
.
handleChangeTable
}
rowSelection=
{
rowSelection
}
renderEmpty=
{
{
image
:
college
,
description
:
(
<
span
style=
{
{
display
:
'block'
,
paddingBottom
:
24
}
}
>
<
span
>
还没有题目
</
span
>
...
...
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