Merge branch 'dev_aliyun' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun
commit
9dc6c68a09
@ -0,0 +1,80 @@
|
||||
/*
|
||||
* @Description:
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2020-01-14 13:39:12
|
||||
* @LastEditors : tangjiang
|
||||
* @LastEditTime : 2020-01-14 16:30:05
|
||||
*/
|
||||
import './index.scss';
|
||||
import React, { useRef, useState, useEffect } from 'react';
|
||||
import { Table } from 'antd';
|
||||
import ReactDom from 'react-dom';
|
||||
|
||||
const DisplayTableData = (props) => {
|
||||
const {columns, datas, fetchData, total} = props;
|
||||
let tableEl = useRef(null);
|
||||
const [loading, setLoading] = useState(false);
|
||||
|
||||
const renderFooter = (obj = {}) => {
|
||||
const {course_count, student_count, choice_shixun_num, choice_shixun_frequency, total} = obj;
|
||||
if (!obj) return ''
|
||||
else {
|
||||
return (
|
||||
<ul className="footer_list">
|
||||
<li className="footer_item footer-total">总计</li>
|
||||
<li className="footer_name">{total || '-'}</li>
|
||||
<li className="footer_item">{course_count || '-'}</li>
|
||||
<li className="footer_item">{student_count || '-'}</li>
|
||||
<li className="footer_item">{choice_shixun_num || '-'}</li>
|
||||
<li className="footer_item">{choice_shixun_frequency || '-'}</li>
|
||||
</ul>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
const table = ReactDom.findDOMNode(tableEl);
|
||||
// console.log(table);
|
||||
const tableBody = table.querySelector('.ant-table-body');
|
||||
let _scrollTop = 0;//保存上次滚动距离
|
||||
let isRun = false;//是否执行查询
|
||||
tableBody.addEventListener('scroll', () => {
|
||||
if(tableBody.scrollTop === 0 ){
|
||||
_scrollTop = 0;
|
||||
}
|
||||
// 上一次滚动高度与当前滚动高度不同则是纵向滚动
|
||||
if (_scrollTop !== tableBody.scrollTop) {
|
||||
//是否滑动到距离底部40px的位置
|
||||
const scorll = _scrollTop >= tableBody.scrollHeight-tableBody.clientHeight-40;
|
||||
//isRun为true时 代表已经执行查询
|
||||
if(isRun && scorll){
|
||||
return;
|
||||
}
|
||||
//_scrollTop < tableBody.scrollTop 判断是否向下滑动
|
||||
isRun = _scrollTop < tableBody.scrollTop && scorll;
|
||||
//保存当前滚动位置
|
||||
_scrollTop = tableBody.scrollTop;
|
||||
if (isRun) {
|
||||
fetchData && fetchData();
|
||||
}
|
||||
}
|
||||
})
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<Table
|
||||
className='static_table'
|
||||
rowKey={record => record.id}
|
||||
columns={columns}
|
||||
dataSource={datas}
|
||||
pagination={false}
|
||||
loading={loading}
|
||||
scroll={{y: 500}}
|
||||
ref={(ref)=>tableEl=ref}
|
||||
footer={total ? () => renderFooter(total) : ''}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
export default DisplayTableData;
|
@ -0,0 +1,43 @@
|
||||
/*
|
||||
* @Description: 数字及文字提示
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2020-01-10 10:26:57
|
||||
* @LastEditors : tangjiang
|
||||
* @LastEditTime : 2020-01-10 11:15:28
|
||||
*/
|
||||
import './index.scss';
|
||||
import React from 'react';
|
||||
import { Tooltip } from 'antd';
|
||||
const numberal = require('numeral');
|
||||
|
||||
const StaticNumberAndTxt = ({
|
||||
count = 0, // 总数
|
||||
txt, // 文字描述
|
||||
type = 'tishi1', // 字体类型
|
||||
desc // 描述信息
|
||||
}) => {
|
||||
|
||||
const formatNumber = (value, format = '0,0') => {
|
||||
return numberal(value).format(format);
|
||||
}
|
||||
|
||||
const _classes = `iconfont icon-${type} icon`;
|
||||
return (
|
||||
<div className="static-flex-item">
|
||||
<span className="item-count">{formatNumber(count)}</span>
|
||||
<span className="item-txt">
|
||||
{txt}
|
||||
<Tooltip
|
||||
placement='bottom'
|
||||
title={desc}
|
||||
overlayClassName='tool-clazz'
|
||||
>
|
||||
<span className={_classes}></span>
|
||||
</Tooltip>
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
export default StaticNumberAndTxt;
|
@ -0,0 +1,156 @@
|
||||
.static_wrap {
|
||||
.static_section_header,
|
||||
.static_section_table{
|
||||
background-color: #fff;
|
||||
border-radius: 5px;
|
||||
padding: 30px 20px 0;
|
||||
margin-top: 20px;
|
||||
}
|
||||
|
||||
.static_section_table{
|
||||
margin-bottom: 140px;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.static_section_header{
|
||||
.header_title{
|
||||
line-height: 1;
|
||||
.title-p,
|
||||
.title-sub{
|
||||
display: inline-block;
|
||||
vertical-align: bottom;
|
||||
color: #303133;
|
||||
}
|
||||
|
||||
.title-p{
|
||||
position: relative;
|
||||
font-size: 20px;
|
||||
height: 20px;
|
||||
line-height: 1;
|
||||
font-weight: bold;
|
||||
|
||||
&::before{
|
||||
position: absolute;
|
||||
content: '';
|
||||
border-left: 1px solid rgba(192,196,204,1);
|
||||
right: -10px;
|
||||
top: 2px;
|
||||
bottom: 0px;
|
||||
margin-left: 10px;
|
||||
}
|
||||
}
|
||||
.title-sub{
|
||||
margin-left: 20px;
|
||||
font-size: 16px;
|
||||
max-width: 1000px;
|
||||
overflow: hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: bottom;
|
||||
}
|
||||
}
|
||||
|
||||
.header-number{
|
||||
height: 158px;
|
||||
}
|
||||
.header-flex{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
align-items: center;
|
||||
|
||||
.static-flex-item{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
.item-count{
|
||||
font-size: 24px;
|
||||
color: #4CACFF;
|
||||
font-weight: bold;
|
||||
}
|
||||
.item-txt{
|
||||
font-size: 14px;
|
||||
line-height: 1.5;
|
||||
text-align: center;
|
||||
color: #909399;
|
||||
margin-top: 20px;
|
||||
.icon{
|
||||
margin-left: 5px;
|
||||
font-size: 16px !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// .static_table{
|
||||
// // .ant-table-header{
|
||||
// // overflow: hidden !important;
|
||||
// // margin-bottom: 0px !important;
|
||||
// // }
|
||||
// // .ant-table-row-cell-break-word{
|
||||
// // background: rgba(241,248,255,1) !important;
|
||||
// // }
|
||||
|
||||
// // .overflow_hidden{
|
||||
// // max-width: 280px;
|
||||
// // overflow: hidden;
|
||||
// // text-overflow:ellipsis;
|
||||
// // white-space: nowrap;
|
||||
// // }
|
||||
// }
|
||||
.static_table{
|
||||
.ant-table-header{
|
||||
margin-bottom: 0px !important;
|
||||
overflow: hidden !important;
|
||||
}
|
||||
.ant-table-thead{
|
||||
th{
|
||||
background: rgba(241,248,255,1);
|
||||
|
||||
}
|
||||
.ant-table-column-title{
|
||||
color: #303133;
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
.ant-table-tbody tr:nth-child(2n) {
|
||||
td{
|
||||
background: rgba(241,248,255,.4);
|
||||
}
|
||||
}
|
||||
.ant-table-tbody tr td{
|
||||
color: #303133;
|
||||
}
|
||||
}
|
||||
|
||||
.ant-table-footer{
|
||||
background-color: rgba(241,248,255,1);
|
||||
padding: 16px 0px;
|
||||
}
|
||||
.footer_list{
|
||||
display: flex;
|
||||
// background: #fff;
|
||||
box-sizing: border-box;
|
||||
text-align: center;
|
||||
|
||||
li{
|
||||
color: #303133;
|
||||
}
|
||||
// border-top: 1px solid green;
|
||||
.footer_item{
|
||||
width: 150px;
|
||||
}
|
||||
.footer_item:not(:first-child) {
|
||||
padding-right: 10px;
|
||||
}
|
||||
.footer-total{
|
||||
width: 100px;
|
||||
}
|
||||
.footer_name{
|
||||
flex: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.tool-clazz{
|
||||
max-width: 200px !important;
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/*
|
||||
* @Description: 模拟数据
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2020-01-11 10:55:33
|
||||
* @LastEditors : tangjiang
|
||||
* @LastEditTime : 2020-01-14 09:11:36
|
||||
*/
|
||||
import { random } from 'lodash';
|
||||
|
||||
const getGuid = () =>
|
||||
'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
||||
/* eslint-disable */
|
||||
let r = (Math.random() * 16) | 0,
|
||||
v = c == 'x' ? r : (r & 0x3) | 0x8;
|
||||
return v.toString(16);
|
||||
});
|
||||
|
||||
const fetchData = (startIndex = 0) =>
|
||||
new Promise(resolve => {
|
||||
setTimeout(() => {
|
||||
resolve(
|
||||
startIndex >= 500 // 总共只有500条数据
|
||||
? []
|
||||
: Array.from({ length: 50 }).map((_, i) => {
|
||||
// 每次返回100条
|
||||
const index = startIndex + i;
|
||||
return {
|
||||
key: getGuid(),
|
||||
index: `${index}`,
|
||||
name: '湖南长沙中南大学湖南长沙中南大学湖南长沙中南大学湖南长沙中南大学湖南长沙中南大学',
|
||||
age: i+1,
|
||||
address: 'New York No. ',
|
||||
address2: 'address2',
|
||||
bbb: 'address3'
|
||||
};
|
||||
}),
|
||||
);
|
||||
}, random(0, 1.0) * 1000);
|
||||
});
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: '序号',
|
||||
dataIndex: 'index',
|
||||
render: text => text + 1,
|
||||
width: 80,
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '使用单位',
|
||||
dataIndex: 'name',
|
||||
width: 300,
|
||||
className: 'overflow_hidden',
|
||||
align: 'center'
|
||||
},
|
||||
{
|
||||
title: '使用课堂/个',
|
||||
width: 200,
|
||||
dataIndex: 'age',
|
||||
align: 'center',
|
||||
// sorter: (a, b) => a.age - b.age
|
||||
},
|
||||
{
|
||||
title: '课堂学生/个',
|
||||
width: 200,
|
||||
dataIndex: 'address',
|
||||
align: 'center',
|
||||
// sorter: (a, b) => a.age - b.age
|
||||
},
|
||||
{
|
||||
title: '选用实训/个',
|
||||
width: 200,
|
||||
dataIndex: 'address2',
|
||||
align: 'center',
|
||||
// sorter: (a, b) => a.age - b.age
|
||||
},
|
||||
{
|
||||
title: '选用实训/个',
|
||||
width: 200,
|
||||
dataIndex: 'bbb',
|
||||
align: 'center',
|
||||
// sorter: (a, b) => a.bbb - b.bbb
|
||||
}
|
||||
];
|
||||
|
||||
const sumData = [
|
||||
{
|
||||
index: '合计',
|
||||
key: 6,
|
||||
name: 'Disabled User',
|
||||
age: 99,
|
||||
address: 'Sidney No.',
|
||||
address2: 'address2',
|
||||
bbb: 'address3',
|
||||
}
|
||||
];
|
||||
|
||||
export { columns, fetchData, sumData };
|
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* @Description:
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2020-01-14 09:44:02
|
||||
* @LastEditors : tangjiang
|
||||
* @LastEditTime : 2020-01-14 17:02:45
|
||||
*/
|
||||
import types from "./actionTypes";
|
||||
import { fetchStaticList } from "../../services/staticService";
|
||||
|
||||
export const staticList = (id) => {
|
||||
return (dispatch, getState) => {
|
||||
const { params, total_count, other_info } = getState().staticReducer;
|
||||
|
||||
if (total_count !== 0 && total_count === other_info.length) return;
|
||||
fetchStaticList(id, params).then(res => {
|
||||
// console.log('统计数据=====>>>>>', res);
|
||||
const {data} = res;
|
||||
if (data.status === 0) {
|
||||
dispatch({
|
||||
type: types.GET_STATIC_INFO,
|
||||
payload: data.data
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
export const changeParams = (params) => {
|
||||
return {
|
||||
type: types.CHANGE_STATIC_PARAMS,
|
||||
payload: params
|
||||
}
|
||||
}
|
||||
|
||||
export const initTotal = () => {
|
||||
return {
|
||||
type: types.CHANGE_STATIC_TOTAL
|
||||
}
|
||||
}
|
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* @Description: 统计
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2020-01-14 09:34:49
|
||||
* @LastEditors : tangjiang
|
||||
* @LastEditTime : 2020-01-14 15:49:55
|
||||
*/
|
||||
import types from "../actions/actionTypes";
|
||||
|
||||
// const maps = {
|
||||
// 1: 'shixun_info', // 实训使用情况
|
||||
// 2: 'user_info', // 用户使用情况
|
||||
// 3: 'subject_info' // 实践课程使用情况
|
||||
// }
|
||||
const initalState = {
|
||||
subject_info: {},
|
||||
other_info: [],
|
||||
total_count: 0,
|
||||
total: {},
|
||||
params: {
|
||||
// sort_by: '',
|
||||
// sort_direction: 'desc', // desc || asc
|
||||
limit: 20, // 一页多少条
|
||||
page: 1, // 第几页
|
||||
type: 'subject_info' // 类型: 实训 shixun_info,
|
||||
}
|
||||
};
|
||||
|
||||
// const getGuid = () =>
|
||||
// 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => {
|
||||
// /* eslint-disable */
|
||||
// let r = (Math.random() * 16) | 0,
|
||||
// v = c == 'x' ? r : (r & 0x3) | 0x8;
|
||||
// return v.toString(16);
|
||||
// });
|
||||
|
||||
const staticReducer = (state = initalState, action) => {
|
||||
const { payload = {}, type } = action;
|
||||
const {subject_info, other_info = [], total = {}, total_count} = payload;
|
||||
switch (type) {
|
||||
case types.GET_STATIC_INFO:
|
||||
return {
|
||||
...state,
|
||||
subject_info,
|
||||
other_info: state.other_info.concat(other_info),
|
||||
total,
|
||||
total_count,
|
||||
params: Object.assign({}, state.params, { page: state.params.page + 1 })
|
||||
}
|
||||
case types.CHANGE_STATIC_PARAMS: {
|
||||
return {
|
||||
...state,
|
||||
params: Object.assign({}, state.params, payload)
|
||||
};
|
||||
}
|
||||
case types.CHANGE_STATIC_TOTAL: {
|
||||
return {
|
||||
...state,
|
||||
other_info: [],
|
||||
total: {}
|
||||
}
|
||||
}
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
}
|
||||
|
||||
export default staticReducer;
|
@ -0,0 +1,14 @@
|
||||
import axios from "axios";
|
||||
|
||||
/*
|
||||
* @Description:
|
||||
* @Author: tangjiang
|
||||
* @Github:
|
||||
* @Date: 2020-01-14 09:40:53
|
||||
* @LastEditors : tangjiang
|
||||
* @LastEditTime : 2020-01-14 10:47:19
|
||||
*/
|
||||
export async function fetchStaticList (id, params) {
|
||||
const url = `/paths/${id}/statistics_info.json`;
|
||||
return axios.get(url, { params });
|
||||
}
|
Loading…
Reference in new issue