dev_auth
杨树林 5 years ago
commit 87ba748a4e

@ -32,7 +32,7 @@ module.exports = {
// See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s
// devtool: "cheap-module-eval-source-map",
// 开启调试
devtool: "source-map", // 开启调试
//devtool: "source-map", // 开启调试
// These are the "entry points" to our application.
// This means they will be the "root" imports that are included in JS bundle.
// The first two entry points enable "hot" CSS and auto-refreshes for JS.

@ -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",

@ -96,10 +96,16 @@ class Exercisestatisticalresult extends Component {
exercise_group_id:checkedValues
})
}
this.updatefun(sort,checkedValues,page,limit)
}
alldatalist = () => {
let {sort, page, limit} = this.state;
this.setState({
exercise_group_id: []
})
this.updatefun(sort, [], page, limit)
}
PaginationCourse=(pageNumber)=>{
let{sort,exercise_group_id,limit}=this.state;
@ -136,7 +142,9 @@ class Exercisestatisticalresult extends Component {
<li className="clearfix mt10">
<span className="fl mr10 color-grey-8">分班情况</span>
<span className="fl ">
<a id="graduation_comment_no_limit" className={this.state.exercise_group_id.length===0?"pl10 pr10 mr20 check_on":"pl10 pr10 mr20" }>不限</a>
<a id="graduation_comment_no_limit"
className={this.state.exercise_group_id.length === 0 ? "pl10 pr10 mr20 check_on" : "pl10 pr10 mr20"}
onClick={() => this.alldatalist()}>不限</a>
</span>
<CheckboxGroup onChange={(e)=>this.funtaskstatustwo(e,data&&data.course_groups)} value={this.state.exercise_group_id} style={{width:'87%',paddingTop: '4px'}}>
{ data&&data.course_groups.map((item, key) => {

@ -704,6 +704,7 @@ class ShixunStudentWork extends Component {
title: '序号',
dataIndex: 'number',
key: 'number',
width: '176px',
render: (text, record) => (
<span>
<a style={{"color": '#07111B', "text-align": "center","margin-left": "10px"}}>{record.number}</a>
@ -714,6 +715,7 @@ class ShixunStudentWork extends Component {
title: '姓名',
dataIndex: 'name',
key: 'name',
width: '218px',
render: (text, record) => (
<span>
<a style={{"color": '#07111B', "text-align": "center"}}>{record.name}</a>
@ -726,6 +728,7 @@ class ShixunStudentWork extends Component {
key: 'stduynumber',
sorter: true,
sortDirections: sortDirections,
width: '351px',
render: (text, record) => (
<span>
<a style={{"color": '#9A9A9A', "text-align": "center"}}>{record.stduynumber}</a>
@ -739,6 +742,7 @@ class ShixunStudentWork extends Component {
sorter: true,
defaultSortOrder: 'descend',
sortDirections: sortDirections,
width: '277',
render: (text, record) => (
<span>
<a style={{"color": record.classroom>=90?'#FF6800':"#747A7F", "text-align": "center"}}>{isNaN(record.classroom)?"--":record.classroom}%</a>
@ -749,6 +753,7 @@ class ShixunStudentWork extends Component {
title: '操作',
dataIndex: 'operating',
key: 'operating',
width: '178px',
render: (text, record) => (
<span>
<a onClick={()=>this.Viewstudenttraininginformation("/courses/"+this.props.match.params.coursesId+"/"+this.state.shixuntypes+"/"+this.props.match.params.homeworkid+"/review_detail/"+record.operating)} >查看</a>

@ -0,0 +1,128 @@
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 = (
<Checkbox.Group style={{width: 220}} className={"StatisticsMenubox"} value={this.state.checkedValues}
onChange={(checkedValues) => this.CheckboxonChange(checkedValues)}>
<Menu className="Statisticslibox">
<li className={"Statisticsli"}>
{course_groups && course_groups.length > 10 ? <Search
placeholder="请输入名称搜索"
onSearch={(value) => this.onSearch(value)}
onChange={(e) => this.onSearchonChange(e)}
value={this.state.onSearchvalue}
style={{width: 200}}
/> : ""}
</li>
{course_groups && course_groups.map((item, key) => {
if (this.state.onSearchvalue) {
if (item.name.indexOf(this.state.onSearchvalue) != -1) {
return (
<Menu.Item key={key}>
<Checkbox value={item.id} key={item.id}> {item.name}</Checkbox>
</Menu.Item>
)
}
} else {
return (
<Menu.Item key={key}>
<Checkbox value={item.id} key={item.id}> {item.name}</Checkbox>
</Menu.Item>
)
}
})}
<Menu.Divider/>
<li className={"Statisticsli"}>
<span onClick={() => this.SaveChange()} className={"ant-btn-link"}>确定</span>
<span className={"ml20 ant-btn-link"} onClick={() => this.unCheckboxonChange()}>重置</span>
</li>
</Menu>
</Checkbox.Group>
);
return (
<React.Fragment>
<Dropdown overlay={menu}
onVisibleChange={this.handleVisibleChange}
visible={this.state.visible}
>
<a className="ant-dropdown-link">
分班 <Icon type="down"/>
</a>
</Dropdown>
</React.Fragment>
)
}
}
export default Dropdownbox;

@ -0,0 +1,89 @@
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 = (
<div className={"Statisticscircle"}>
<p>
作业完成数*10
</p>
<p>
试卷完成数*10
</p>
<p>
问卷完成数*7
</p>
<p>
资源发布数*5
</p>
<p>
帖子发布数*2
</p>
<p>
帖子回复数*1
</p>
<p>
作业回复数*1
</p>
</div>
);
return (
<React.Fragment>
<Row>
<Col span={12} className={"top10s"}>Top 10</Col>
<Col span={12} className={"Statisticsliboxjsgz"}>
<span className={"mr10"}>计算规则</span>
<Popover placement="bottom" content={content} trigger="hover">
<Icon type="exclamation-circle"/>
</Popover>
</Col>
</Row>
{/*scale={cols}*/}
<Chart height={400} data={data} forceFit>
<Axis name="name"/>
<Axis name="活跃度"/>
<Tooltip
crosshairs={{
type: "y"
}}
/>
<Geom type="interval" position="name*活跃度"/>
</Chart>
</React.Fragment>
)
}
}
export default Dynamiclist;

@ -63,5 +63,66 @@
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;
}

@ -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,11 +19,20 @@ 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() {
this.getdatas()
}
getdatas = () => {
let {page, group_ids, sort} = this.state;
let courseId = this.props.match.params.coursesId;
let url = `/courses/${courseId}/statistics.json`;
@ -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,26 +65,60 @@ class Statistics extends Component{
}
}).catch((error) => {
console.log(error);
})
}
getwork_scoredata = (page, group_ids, sort) => {
getDynamiclistdatas = (group_ids) => {
let courseId = this.props.match.params.coursesId;
let url = `/courses/${courseId}/work_score.json`;
let url = `/courses/${courseId}/act_score.json`;
let data = {
limit: 20,
page: page,
group_ids: group_ids,
sort: sort
}
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 = {
limit: 20,
page: page,
group_ids: group_ids,
sort: sort
}
axios.get(url, {
params:
data
}).then((result) => {
if (result) {
this.setState({
bomdata: result.data.course_members,
all_count: result.data.all_count,
bomisSpin: false
})
}
@ -86,16 +128,160 @@ class Statistics extends Component{
bomisSpin: false,
})
})
} else {
this.getDynamiclistdatas(group_ids)
}
}
activeKey = (key) => {
if (key === "1") {
let {page, group_ids, sort} = this.state;
// this.getdatas()
this.getwork_scoredata(page, group_ids, sort)
} 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)
});
}
callback=(key)=>{
console.log(key);
}
// 筛选
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
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) => (
<span>{record.user_name}</span>
)
},
{
title: '分班',
dataIndex: 'course_group',
render: (text, record) => (
<span>{record.course_group}</span>
)
},
{
title: '实训作业',
dataIndex: 'practice_score',
render: (text, record) => (
<span>{record.practice_score.toFixed(2)}</span>
)
},
{
title: '普通作业',
dataIndex: 'common_score',
render: (text, record) => (
<span>{record.common_score.toFixed(2)}</span>
)
},
{
title: '分组作业',
dataIndex: 'group_score',
render: (text, record) => (
<span>{record.group_score.toFixed(2)}</span>
)
},
{
title: '毕设任务',
dataIndex: 'graduation_score',
render: (text, record) => (
<span>{record.graduation_score.toFixed(2)}</span>
)
},
{
title: '试卷',
dataIndex: 'exercise_score',
render: (text, record) => (
<span>{record.exercise_score}</span>
)
},
{
title: '总成绩',
dataIndex: 'total_score',
sorter: this.props.isAdmin() === true ? true : false,
defaultSortOrder: 'descend',
sortDirections: sortDirections,
render: (text, record) => (
<span>{record.total_score.toFixed(2)}</span>
)
},
];
let course_grouptype = false;
if (this.props && this.props.course_modules != undefined) {
{
this.props && this.props.course_modules.map((item, key) => {
@ -105,46 +291,39 @@ class Statistics extends Component{
})
}
}
// 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 = <React.Fragment>
<Dropdownbox
{...this.props}
{...this.state}
postwork_scoredata={(group_idss) => this.getwork_scoredata(1, group_idss, 'desc')}
/>
<a className={"ml20 ant-btn-link"}
onClick={() => this.derivefun(`/courses/${this.props.match.params.coursesId}/export_member_scores_excel.xlsx`)}>导出</a>
</React.Fragment>;
return(
<React.Fragment >
<div>
<React.Fragment>
<div className="edu-back-white">
<Spin size="large" spinning={this.state.topisSpin}>
<p className="clearfix padding30">
@ -305,22 +484,55 @@ class Statistics extends Component{
<div className="mt20 edu-back-white">
<Spin size="large" spinning={this.state.bomisSpin}>
<Tabs className="statisticsTabs" defaultActiveKey="1" onChange={this.callback}>
<style>{
`
.ant-select-dropdown-menu {
max-height: 320px;
}
.ant-tabs-extra-content{
margin-top:20px;
}
.ant-table-thead > tr > th, .ant-table-tbody > tr > td {
padding: 16px 0px;
}
`
}</style>
<Tabs className="statisticsTabs" activeKey={this.state.activeKey} onChange={this.activeKey}
tabBarExtraContent={this.props.isAdmin() === true ? operations : ""}>
<TabPane tab="学习成绩" key="1" className={"statisticsTabs1"}>
{/*<Table*/}
{/*columns={columns}*/}
{/*dataSource={bomdata}*/}
{/*onChange={this.handleTableChange}*/}
{/*/>*/}
<Table
columns={columns}
dataSource={bomdata}
pagination={false}
onChange={this.handleTableChange}
/>
</TabPane>
<TabPane tab="课堂活跃度" key="2">
Content of Tab Pane 2
<Dynamiclist
{...this.state}
{...this.props}
/>
</TabPane>
</Tabs>
</Spin>
</div>
</div>
{this.state.all_count === undefined || this.state.all_count === null || this.state.activeKey === "2" ? '' : this.state.all_count > 20 && this.props.isAdmin() === true ?
<div className="mb40 edu-txt-center padding20-30"
>
<Pagination
showQuickJumper
defaultCurrent={1}
pageSize={20}
total={this.state.all_count === undefined ? 0 : this.state.all_count === null ? 0 : this.state.all_count}
current={this.state.page}
onChange={this.PaginationCourse}
/>
</div> : ""}
</React.Fragment>
)
}

Loading…
Cancel
Save