diff --git a/public/react/package.json b/public/react/package.json
index ac239dd0f..5bc10f627 100644
--- a/public/react/package.json
+++ b/public/react/package.json
@@ -16,6 +16,7 @@
"babel-plugin-syntax-dynamic-import": "^6.18.0",
"babel-preset-react-app": "^3.1.1",
"babel-runtime": "6.26.0",
+ "bizcharts": "^3.5.5",
"bundle-loader": "^0.5.6",
"case-sensitive-paths-webpack-plugin": "2.1.1",
"chalk": "1.1.3",
diff --git a/public/react/src/modules/courses/statistics/Dropdownbox.js b/public/react/src/modules/courses/statistics/Dropdownbox.js
new file mode 100644
index 000000000..548715993
--- /dev/null
+++ b/public/react/src/modules/courses/statistics/Dropdownbox.js
@@ -0,0 +1,123 @@
+import React,{ Component } from "react";
+import {Menu, Dropdown, Icon,Input,Checkbox} from "antd";
+import {getImageUrl} from 'educoder';
+const { Search } = Input;
+class Dropdownbox extends Component{
+ constructor(props){
+ super(props);
+ this.state={
+ activeKey:'1',
+ visible: false,
+ onSearchvalue:undefined,
+ checkedValues:[]
+ }
+ }
+
+ componentDidMount() {
+ let {group_ids}=this.props;
+ if(group_ids){
+ this.setState({
+ checkedValues:group_ids
+ })
+ }
+ }
+ componentDidUpdate=(prevProps)=>{
+ if(prevProps!=this.props){
+ let {group_ids}=this.props;
+ if(group_ids){
+ this.setState({
+ checkedValues:group_ids
+ })
+ }
+ }
+ }
+ SaveChange=()=>{
+ this.props.postwork_scoredata(this.state.checkedValues)
+ }
+
+
+ handleVisibleChange=flag=>{
+ this.setState({ visible: flag });
+ };
+
+ CheckboxonChange=(checkedValues)=>{
+ this.setState({
+ checkedValues:checkedValues
+ })
+ }
+
+ unCheckboxonChange=()=>{
+ this.setState({
+ checkedValues:[],
+ onSearchvalue:undefined
+ })
+ }
+
+ onSearch=(value)=>{
+ this.setState({
+ onSearchvalue:value
+ })
+ }
+
+ onSearchonChange=(e)=>{
+ this.setState({
+ onSearchvalue:e.target.value
+ })
+ }
+
+ render(){
+ let {course_groups}=this.props;
+
+ const menu = (
+ this.CheckboxonChange(checkedValues)}>
+
+
+ );
+
+ return(
+
+
+
+ 分班
+
+
+
+ )
+ }
+}
+export default Dropdownbox;
diff --git a/public/react/src/modules/courses/statistics/Dynamiclist.js b/public/react/src/modules/courses/statistics/Dynamiclist.js
new file mode 100644
index 000000000..0ea6eac1b
--- /dev/null
+++ b/public/react/src/modules/courses/statistics/Dynamiclist.js
@@ -0,0 +1,90 @@
+import React,{ Component } from "react";
+import {Row, Col,Popover,Button,Icon} from "antd";
+import {
+ G2,
+ Chart,
+ Geom,
+ Axis,
+ Tooltip,
+ Coord,
+ Label,
+ Legend,
+ View,
+ Guide,
+ Shape,
+ Facet,
+ Util
+} from "bizcharts";
+
+class Dynamiclist extends Component{
+ constructor(props){
+ super(props);
+ this.state={
+
+ }
+ }
+
+
+ render(){
+ const data = []
+ let {course_members}=this.props;
+ if(course_members){
+ if(course_members.length>0){
+ course_members.map((item,key)=>{
+ data.push({'name':item.user_name,'活跃度':item.total_score})
+ })
+ }
+ }
+
+ const content = (
+
+
+ 作业完成数(*10)
+
+
+ 试卷完成数(*10)
+
+
+ 问卷完成数(*7)
+
+
+ 资源发布数(*5)
+
+
+ 帖子发布数(*2)
+
+
+ 帖子回复数(*1)
+
+
+ 作业回复数(*1)
+
+
+ );
+ return(
+
+
+ Top 10
+
+ 计算规则
+
+
+
+
+
+ {/*scale={cols}*/}
+
+
+
+
+
+
+
+ )
+ }
+}
+export default Dynamiclist;
diff --git a/public/react/src/modules/courses/statistics/Statistics.css b/public/react/src/modules/courses/statistics/Statistics.css
index 686abd52e..cfae65597 100644
--- a/public/react/src/modules/courses/statistics/Statistics.css
+++ b/public/react/src/modules/courses/statistics/Statistics.css
@@ -63,5 +63,65 @@
text-align: center;
line-height: 61px;
font-size: 16px;
- color: rgba(80,145,255,1);
+}
+
+.Statisticsli{
+ clear: both;
+ margin: 0;
+ padding: 5px 12px;
+ color: rgba(0, 0, 0, 0.65);
+ font-weight: normal;
+ font-size: 14px;
+ line-height: 22px;
+ white-space: nowrap;
+ cursor: pointer;
+ -webkit-transition: all 0.3s;
+ -o-transition: all 0.3s;
+ transition: all 0.3s;
+}
+
+.StatisticsMenubox{
+ position: relative;
+ margin: 0;
+ padding: 4px 0;
+ text-align: left;
+ list-style-type: none;
+ background-color: #fff;
+ background-clip: padding-box;
+ border-radius: 4px;
+ outline: none;
+ -webkit-box-shadow: 0 2px 8px rgba(0,0,0,0.15);
+ box-shadow: 0 2px 8px rgba(0,0,0,0.15);
+ -webkit-transform: translate3d(0, 0, 0);
+}
+
+.Statisticslibox li label{
+ width: 200px;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+}
+.Statisticslibox .ant-menu-item{
+ height: 20px;
+ line-height: 20px;
+ text-overflow: clip;
+}
+
+.top10s{
+ font-size: 16px;
+ font-weight: bold;
+ color: rgba(51,51,51,1);
+}
+
+.Statisticsliboxjsgz{
+ font-size:12px;
+ color:rgba(51,51,51,1);
+ text-align: right;
+}
+
+.Statisticscircle p{
+ height: 30px;
+ font-size: 12px;
+ color: rgba(153,153,153,1);
+ line-height: 30px;
}
\ No newline at end of file
diff --git a/public/react/src/modules/courses/statistics/Statistics.js b/public/react/src/modules/courses/statistics/Statistics.js
index c4d5ddfa6..cb5cf9574 100644
--- a/public/react/src/modules/courses/statistics/Statistics.js
+++ b/public/react/src/modules/courses/statistics/Statistics.js
@@ -1,8 +1,9 @@
import React,{ Component } from "react";
-import {Table, Pagination,Tooltip,Spin, Row, Col ,Tabs} from "antd";
-import { WordsBtn,on, off, trigger ,getImageUrl} from 'educoder';
-import {BrowserRouter as Router,Route,Switch,Link} from 'react-router-dom';
+import {Table, Pagination,Tooltip,Spin, Row, Col ,Checkbox,Tabs,Menu, Dropdown, Icon,Input} from "antd";
+import { WordsBtn,on, off, trigger ,getImageUrl,sortDirections} from 'educoder';
import axios from'axios';
+import Dropdownbox from './Dropdownbox';
+import Dynamiclist from './Dynamiclist';
import './Statistics.css';
const { TabPane } = Tabs;
class Statistics extends Component{
@@ -18,20 +19,29 @@ class Statistics extends Component{
bomisSpin:true,
sort:'desc',
course_groups:[],
- page:1
+ page:1,
+ all_count:null,
+ activeKey:'1',
+ visible: false,
+ group_ids:[],
+ course_members:[]
}
}
componentDidMount() {
- let {page,group_ids,sort}=this.state;
+ this.getdatas()
+ }
+
+ getdatas=()=>{
+ let {page,group_ids,sort}=this.state;
let courseId=this.props.match.params.coursesId;
let url=`/courses/${courseId}/statistics.json`;
axios.get(url).then((result) => {
if (result) {
- this.setState({
- data:result.data.top_scores,
- topisSpin:false
- })
+ this.setState({
+ data:result.data.top_scores,
+ topisSpin:false
+ })
}
}).catch((error) => {
console.log(error);
@@ -39,8 +49,6 @@ class Statistics extends Component{
topisSpin:false,
})
})
-
-
let courseurl=`/courses/${courseId}/all_course_groups.json`;
axios.get(courseurl).then((result) => {
if (result) {
@@ -57,11 +65,43 @@ class Statistics extends Component{
}
}).catch((error) => {
console.log(error);
+ })
+ }
+
+ getDynamiclistdatas=(group_ids)=>{
+ let courseId=this.props.match.params.coursesId;
+ let url=`/courses/${courseId}/act_score.json`;
+ let data={
+ group_ids:group_ids,
+ }
+ axios.get(url,{params:
+ data
+ }).then((result) => {
+ if (result) {
+ this.setState({
+ course_members:result.data.course_members,
+ bomisSpin:false
+ })
+ }
+ }).catch((error) => {
+ console.log(error);
+ this.setState({
+ bomisSpin:false,
+ })
})
}
getwork_scoredata=(page,group_ids,sort)=>{
+ let {activeKey}=this.state;
+ this.setState({
+ page:page,
+ sort:sort,
+ group_ids:group_ids,
+ bomisSpin:true,
+ })
+
+ if(activeKey==='1'){
let courseId=this.props.match.params.coursesId;
let url=`/courses/${courseId}/work_score.json`;
let data={
@@ -76,6 +116,7 @@ class Statistics extends Component{
if (result) {
this.setState({
bomdata:result.data.course_members,
+ all_count:result.data.all_count,
bomisSpin:false
})
}
@@ -85,63 +126,196 @@ class Statistics extends Component{
bomisSpin:false,
})
})
+ }else{
+ this.getDynamiclistdatas(group_ids)
+ }
+
}
- callback=(key)=>{
- console.log(key);
+ activeKey=(key)=>{
+ if(key==="1"){
+ this.getdatas()
+ }else{
+ let{group_ids}=this.state;
+ this.getDynamiclistdatas(group_ids)
+ }
+ this.setState({
+ activeKey:key
+ })
}
+
+ PaginationCourse=(pageNumber)=>{
+ let {group_ids,sort}=this.state;
+
+ this.getwork_scoredata(pageNumber,group_ids,sort);
+ }
+
+ derivefun=(url)=>{
+ let{group_ids}=this.state;
+ let data={
+ group_id:group_ids
+ }
+ axios.get(url,{params:
+ data
+ }).then((response)=>{
+ if(response === undefined){
+ return
+ }
+ if(response.data.status&&response.data.status===-1){
+ this.props.showNotification(response.data.message);
+ }else if(response.data.status&&response.data.status===-2){
+ // if(response.data.message === "100"){
+ // // 已超出文件导出的上限数量(100 ),建议:
+ //
+ // this.setState({
+ // DownloadType:true,
+ // DownloadMessageval:100
+ // })
+ // }else {
+ // //因附件资料超过500M
+ // this.setState({
+ // DownloadType:true,
+ // DownloadMessageval:500
+ // })
+ // }
+ this.props.showNotification(response.data.message);
+ }else {
+ // this.props.showNotification(`正在下载中`);
+ // window.open("/api"+url, '_blank');
+ this.props.slowDownload(url);
+ }
+ }).catch((error) => {
+ console.log(error)
+ });
+ }
+
+
+ // 筛选
+ handleTableChange =(pagination, filters, data)=>{
+ let order=data.order;
+ let {page,group_ids}=this.state;
+ if(order==="descend"){
+ this.getwork_scoredata(page,group_ids,'desc')
+ }else{
+ this.getwork_scoredata(page,group_ids,'asc')
+ }
+
+ }
+
render(){
- let {nd1,nd2,nd3,data,bomdata,course_groups}=this.state;
- let course_grouptype=false
- if(this.props&&this.props.course_modules!=undefined){
+ let {nd1,nd2,nd3,data,bomdata}=this.state;
+
+ const columns = [
+ {
+ title: this.props.isAdmin()===true?'序号':'排名',
+ dataIndex: 'index',
+ render: (text, record,index) => {
+ return this.props.isAdmin()===true?(this.state.page - 1) * 20 + index + 1:record.rank
+ }
+ },
+ {
+ title: '姓名',
+ dataIndex:'user_name',
+ render: (text, record) => (
+ {record.user_name}
+ )
+ },
+ {
+ title: '分班',
+ dataIndex: 'course_group',
+ render: (text, record) => (
+ {record.course_group}
+ )
+ },
+ {
+ title: '实训作业',
+ dataIndex: 'practice_score',
+ render: (text, record) => (
+ {record.practice_score.toFixed(2)}
+ )
+ },
+ {
+ title: '普通作业',
+ dataIndex: 'common_score',
+ render: (text, record) => (
+ {record.common_score.toFixed(2)}
+ )
+ },
+ {
+ title: '分组作业',
+ dataIndex: 'group_score',
+ render: (text, record) => (
+ {record.group_score.toFixed(2)}
+ )
+ },
+ {
+ title: '毕设任务',
+ dataIndex: 'graduation_score',
+ render: (text, record) => (
+ {record.graduation_score.toFixed(2)}
+ )
+ },
+ {
+ title: '试卷',
+ dataIndex: 'exercise_score',
+ render: (text, record) => (
+ {record.exercise_score}
+ )
+ },
+ {
+ title: '总成绩',
+ dataIndex: 'total_score',
+ sorter: this.props.isAdmin()===true?true:false,
+ defaultSortOrder: 'descend',
+ sortDirections: sortDirections,
+ render: (text, record) => (
+ {record.total_score.toFixed(2)}
+ )
+ },
+ ];
+
+ let course_grouptype=false;
+ if(this.props&&this.props.course_modules!=undefined){
{this.props&&this.props.course_modules.map((item,key)=>{
if(item.type==="course_group"){
course_grouptype=true
}
})}
}
-
- // const columns = [
- // {
- // title: 'Name',
- // dataIndex: 'name',
- // sorter: true,
- // render: name => `${name.first} ${name.last}`,
- // width: '20%',
- // },
- // {
- // title: 'Gender',
- // dataIndex: 'gender',
- // filters: course_groups,
- // width: '20%',
- // },
- // {
- // title: 'Email',
- // dataIndex: 'email',
- // },
- // ];
-
-
- // console.log(bomdata)
-
-
- //common_score: 0
- // course_group: "威风威风急急急"
- // exercise_score: "0.0"
- // graduation_score: 0
- // group_score: 0
- // practice_score: 3232
- // total_score: 3232
- // user_login: "p40793521"
- // user_name: "李明霞"
-
-
+ if(course_grouptype===false){
+ columns.some((item,key)=> {
+ if (item.title === "分班") {
+ columns.splice(key, 1)
+ return true
+ }
+ }
+ )
+ }
+ // console.log(this.props.isAdmin)
+
+
+ // "user_login": "p94602358",
+ // "user_name": "卿前程",
+ // "course_group": "电气工程1805", // 分班
+ // "common_score": 0.0, // 普通作业
+ // "group_score": 0.0, // 分组作业
+ // "practice_score": 747.1000061035156, // 实训作业
+ // "exercise_score": 0.0, // 试卷成绩
+ // "graduation_score": 0.0, // 毕设成绩
+ // "total_score": 747.1000061035156, // 总成绩
+ // "rank": 1 // 排名,学生身份才传
+ const operations =
+ this.getwork_scoredata(1,group_idss,'desc')}
+ />
+ this.derivefun(`/courses/${this.props.match.params.coursesId}/export_member_scores_excel.xlsx`)}>导出
+ ;
return(
-
-
-
+
@@ -301,22 +475,53 @@ class Statistics extends Component{
-
-
- {/**/}
+
+
+
+
- Content of Tab Pane 2
+
-
+ {this.state.all_count===undefined||this.state.all_count===null||this.state.activeKey==="2"?'':this.state.all_count >20&&this.props.isAdmin()===true?:""}
+
)
}