Merge branch 'courseware' of http://bdgit.educoder.net/Hjqreturn/educoder into courseware
@ -0,0 +1,12 @@
|
||||
json.data do
|
||||
json.array! @watch_course_videos do |d|
|
||||
json.user_name d.user&.real_name
|
||||
json.is_finished d.is_finished ? true : false
|
||||
json.total_duration d.total_duration.round(2)
|
||||
json.feq d['freq']
|
||||
json.start_at d.start_at.to_s
|
||||
json.end_at d.end_at.to_s
|
||||
end
|
||||
end
|
||||
|
||||
json.count @count
|
@ -0,0 +1,6 @@
|
||||
json.category_id category.id
|
||||
json.category_name category.name
|
||||
json.position category.position
|
||||
json.category_count category_task_count(@course, category, @user)
|
||||
json.category_type category.category_type_str
|
||||
json.second_category_url category_url(category, @course)
|
@ -1,10 +1,17 @@
|
||||
json.has_course_groups @has_course_groups
|
||||
json.course_modules do
|
||||
json.array! @course_modules do |course_module|
|
||||
json.id course_module.id
|
||||
json.module_name course_module.module_name
|
||||
json.course_second_categories do
|
||||
json.array! course_module.course_second_categories, :id, :name
|
||||
json.value course_module.id
|
||||
json.title course_module.module_name
|
||||
json.children course_module.first_categories do |category|
|
||||
json.title category.name
|
||||
json.value category.id
|
||||
unless @no_child
|
||||
json.children category.children do |child|
|
||||
json.title child.name
|
||||
json.value child.id
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -0,0 +1,13 @@
|
||||
json.data do
|
||||
json.array! @videos.each do |d|
|
||||
json.title d.title
|
||||
json.user_name @current_user&.real_name
|
||||
json.is_finished d.is_finished ? true : false
|
||||
json.total_duration d.total_duration.round(2)
|
||||
json.freq d['freq']
|
||||
json.start_at d.start_at.to_s
|
||||
json.end_at d.end_at.to_s
|
||||
end
|
||||
end
|
||||
|
||||
json.count @count
|
@ -0,0 +1,10 @@
|
||||
json.videos do
|
||||
json.array! @videos do |v|
|
||||
json.id v.id
|
||||
json.title v.title
|
||||
json.user_name v.user&.real_name
|
||||
json.people_num v['people_num']
|
||||
json.total_time v['total_time']
|
||||
end
|
||||
end
|
||||
json.count @count
|
@ -0,0 +1,16 @@
|
||||
class AddAttendanceToCourseModule < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
Course.all.each do |course|
|
||||
unless course.course_modules.exists?(module_type: "attendance")
|
||||
atta_position = course.course_modules.find_by(module_type: 'course_group')&.position.to_i
|
||||
attendance_position = atta_position != 0 ? (atta_position + 1) : 14
|
||||
course.course_modules.where("position >= #{attendance_position}").update_all("position = position + 1")
|
||||
if course.is_end
|
||||
course.course_modules << CourseModule.new(module_type: "attendance", hidden: 1, module_name: "签到", position: attendance_position)
|
||||
else
|
||||
course.course_modules << CourseModule.new(module_type: "attendance", hidden: 0, module_name: "签到", position: attendance_position)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,7 @@
|
||||
class AddParentIdToSecondCategory < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :course_second_categories, :parent_id, :integer, default: 0
|
||||
|
||||
add_index :course_second_categories, :parent_id
|
||||
end
|
||||
end
|
@ -0,0 +1,8 @@
|
||||
class AddTotalDurationToWatchCourseDuration < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
#add_column :watch_course_videos, :total_duration, :float, default: 0
|
||||
#WatchVideoHistory.where("created_at < '2020-03-14 00:00:00'").each do |d|
|
||||
# d.watch_course_video.increment!(:total_duration, d.total_duration) if d.watch_course_video.present?
|
||||
#end
|
||||
end
|
||||
end
|
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 11 KiB |
After Width: | Height: | Size: 9.8 KiB |
After Width: | Height: | Size: 82 KiB |
After Width: | Height: | Size: 84 KiB |
After Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 404 KiB After Width: | Height: | Size: 410 KiB |
@ -0,0 +1,9 @@
|
||||
import React from 'react'
|
||||
import MiniPagination from './components/mini-pagination'
|
||||
|
||||
export default () => {
|
||||
function onPageChange(page) {
|
||||
console.log(page, '-----------')
|
||||
}
|
||||
return <MiniPagination onChange={onPageChange} current={1} total={100} pageSize={16} />
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
import React, { useState } from 'react'
|
||||
import './index.scss'
|
||||
function noop() { }
|
||||
|
||||
export default ({ current, defaultCurrent, total, pageSize, onChange = noop }) => {
|
||||
const maxPage = Math.ceil(total / pageSize)
|
||||
const [page, setPage] = useState(current || defaultCurrent)
|
||||
|
||||
function next() {
|
||||
if (page < maxPage) {
|
||||
let value = page + 1
|
||||
setPage(value)
|
||||
onChange(value)
|
||||
}
|
||||
}
|
||||
|
||||
function prev() {
|
||||
if (page > 1) {
|
||||
let value = page - 1
|
||||
setPage(value)
|
||||
onChange(value)
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="mini-pagination">
|
||||
<a class={page === 1 ? 'disabled' : 'normal'} onClick={prev}>上一页</a>
|
||||
<a class={page === maxPage ? 'disabled' : 'normal'} onClick={next} >下一页</a>
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
.mini-pagination {
|
||||
display: flex;
|
||||
flex-flow: row nowrap;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
|
||||
a {
|
||||
display: block;
|
||||
padding: 0 10px 0 22px;
|
||||
border-width: 1px;
|
||||
border-radius: 3px;
|
||||
margin-right: 4px;
|
||||
font-size: 12px;
|
||||
line-height: 30px;
|
||||
cursor: pointer;
|
||||
border-style: solid;
|
||||
outline: none;
|
||||
border-color: #c4c6cf;
|
||||
background: #fff;
|
||||
color: #333;
|
||||
|
||||
position: relative;
|
||||
|
||||
&:hover {
|
||||
background-color: #f2f3f7;
|
||||
border-color: #a0a2ad;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
&:before {
|
||||
position: absolute;
|
||||
content: ' ';
|
||||
width: 8px;
|
||||
top: 10px;
|
||||
left: 10px;
|
||||
height: 8px;
|
||||
transform: rotate(-45deg);
|
||||
border-top: 1px solid #333;
|
||||
border-left: 1px solid #333;
|
||||
}
|
||||
|
||||
&:last-child {
|
||||
padding: 0 22px 0 10px;
|
||||
margin: 0 0 0 4px;
|
||||
|
||||
&:before {
|
||||
left: auto;
|
||||
right: 10px;
|
||||
transform: rotate(135deg);
|
||||
}
|
||||
}
|
||||
|
||||
&.disabled {
|
||||
cursor: not-allowed;
|
||||
background-color: #f7f8fa;
|
||||
border-color: #e6e7eb;
|
||||
color: #e0e0e0;
|
||||
|
||||
&:before {
|
||||
border-top: 1px solid #e0e0e0;
|
||||
border-left: 1px solid #e0e0e0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,117 @@
|
||||
import * as monaco from 'monaco-editor'
|
||||
import { union } from 'lodash'
|
||||
const ifelse = {
|
||||
label: 'ifelse',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'if (${1:condition}) {',
|
||||
'\t$0',
|
||||
'} else {',
|
||||
'\t',
|
||||
'}'
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'If-Else Statement'
|
||||
}
|
||||
|
||||
|
||||
function getWordsInString(string) {
|
||||
return string.match(/[A-z]+/g)
|
||||
}
|
||||
|
||||
const cArray = ['auto', 'break', 'case', 'char', 'const', 'continue', 'default', 'do', 'double', 'else', 'enum', 'extern',
|
||||
'float', 'for', 'goto', 'if', 'int', 'long', 'register', 'return', 'short', 'signed', 'sizeof', 'static', 'struct',
|
||||
'switch', 'typedef', 'union', 'unsigned', 'void', 'volatile', 'while', 'inline', 'restrict', '_Bool', '_Complex',
|
||||
'_Imaginary', '_Alignas', '_Alignof', '_Atomic', '_Static_assert', '_Noreturn', '_Thread_local', '_Generic']
|
||||
|
||||
monaco.languages.registerCompletionItemProvider('cpp', {
|
||||
provideCompletionItems: (model) => {
|
||||
const currentFileWords = getWordsInString(model.getValue());
|
||||
const all = union(cArray, currentFileWords)
|
||||
var suggestions = all.map((item) => {
|
||||
return {
|
||||
label: item,
|
||||
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||
insertText: item,
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
|
||||
}
|
||||
});
|
||||
suggestions.push(ifelse)
|
||||
|
||||
return { suggestions: suggestions };
|
||||
}
|
||||
});
|
||||
|
||||
// https://www.programiz.com/python-programming/keyword-list
|
||||
const pythonArray = ['False', 'None', 'True', 'and', 'as', 'assert', 'break', 'class', 'continue', 'def', 'del', 'elif',
|
||||
'else', 'except', 'finally', 'for', 'from', 'global', 'if', 'import', 'in', 'is', 'lambda', 'nonlocal', 'not', 'or',
|
||||
'pass', 'raise', 'return', 'try', 'while', 'with', 'yield']
|
||||
|
||||
monaco.languages.registerCompletionItemProvider('python', {
|
||||
provideCompletionItems: (model) => {
|
||||
const currentFileWords = getWordsInString(model.getValue());
|
||||
const all = union(pythonArray, currentFileWords)
|
||||
var suggestions = all.map((item) => {
|
||||
return {
|
||||
label: item,
|
||||
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||
insertText: item,
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
|
||||
}
|
||||
});
|
||||
suggestions.push({
|
||||
label: 'print',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'print($0)',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'print'
|
||||
})
|
||||
return { suggestions: suggestions };
|
||||
}
|
||||
});
|
||||
|
||||
const javaArray = ['abstract', 'assert', 'boolean', 'break', 'byte', 'case', 'catch', 'char', 'class', 'const',
|
||||
'continue', 'default', 'do', 'double', 'else', 'enum', 'extends', 'final', 'finally', 'float', 'for', 'goto', 'if',
|
||||
'implements', 'import', 'instance of', 'int', 'interface', 'long', 'native',
|
||||
'new', 'package', 'private', 'protected', 'public', 'return', 'strictfp', 'short', 'static', 'super', 'switch',
|
||||
'synchronized', 'this', 'throw', 'throws', 'transient', 'try', 'void', 'volatile', 'while']
|
||||
|
||||
monaco.languages.registerCompletionItemProvider('java', {
|
||||
provideCompletionItems: (model) => {
|
||||
const currentFileWords = getWordsInString(model.getValue());
|
||||
const all = _.union(javaArray, currentFileWords)
|
||||
|
||||
var suggestions = all.map((item) => {
|
||||
return {
|
||||
label: item,
|
||||
kind: monaco.languages.CompletionItemKind.Keyword,
|
||||
insertText: item,
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet
|
||||
}
|
||||
});
|
||||
suggestions.push(ifelse)
|
||||
suggestions.push({
|
||||
label: 'main',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'public static void main(String[] args) {',
|
||||
'\t$0',
|
||||
'}',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'main function'
|
||||
})
|
||||
suggestions.push({
|
||||
label: 'System.out.print',
|
||||
kind: monaco.languages.CompletionItemKind.Snippet,
|
||||
insertText: [
|
||||
'System.out.print($0)',
|
||||
].join('\n'),
|
||||
insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet,
|
||||
documentation: 'system print'
|
||||
})
|
||||
return { suggestions: suggestions };
|
||||
}
|
||||
});
|
@ -0,0 +1,296 @@
|
||||
import "../css/Signinstatistics.css";
|
||||
import React,{ Component } from "react";
|
||||
import { Row, Col,Card,Select} from 'antd';
|
||||
import {getImageUrl} from 'educoder';
|
||||
import axios from 'axios';
|
||||
import NoneDatas from "../component/NoneDatas";
|
||||
import {
|
||||
Chart,
|
||||
Geom,
|
||||
Axis,
|
||||
Tooltip,
|
||||
} from "bizcharts";
|
||||
import LoadingSpin from "../../../../common/LoadingSpin";
|
||||
const { Option } = Select;
|
||||
|
||||
class Signinstatistics extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state={
|
||||
datas:null,
|
||||
newlist:undefined,
|
||||
course_groups:[{id:"全部",name:"全部"}],
|
||||
spal:false,
|
||||
}
|
||||
}
|
||||
getdata=(group_id)=>{
|
||||
|
||||
const coursesId=this.props.match.params.coursesId;
|
||||
let url=`/weapps/courses/${coursesId}/attendances.json`
|
||||
axios.get(url,{params:{
|
||||
group_id:group_id==="全部"?undefined:group_id
|
||||
}
|
||||
}).then((response) => {
|
||||
|
||||
if(response){
|
||||
if(response.data){
|
||||
let newlists=[]
|
||||
|
||||
if(response.data.history_attendances.length>0){
|
||||
response.data.history_attendances.map((item,key)=>{
|
||||
newlists.push({
|
||||
month: item.index,
|
||||
name: item.name+" "+item.attendance_date+" "+item.start_time+"-"+item.end_time,
|
||||
// month:item.name,
|
||||
city:"到课率",
|
||||
temperature: (item.normal_rate*100).toFixed(0)
|
||||
})
|
||||
newlists.push({
|
||||
month: item.index,
|
||||
name: item.name+" "+item.attendance_date+" "+item.start_time+"-"+item.end_time,
|
||||
// month:item.name,
|
||||
city: "旷课率",
|
||||
temperature: (item.absence_rate*100).toFixed(0)
|
||||
})
|
||||
newlists.push({
|
||||
month: item.index,
|
||||
name: item.name+" "+item.attendance_date+" "+item.start_time+"-"+item.end_time,
|
||||
// month:item.name,
|
||||
city: "请假率",
|
||||
temperature: (item.leave_rate*100).toFixed(0)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
this.setState({
|
||||
datas:response.data,
|
||||
newlist:newlists
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
spal:false
|
||||
})
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
spal:false
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
spal:true
|
||||
})
|
||||
const coursesId=this.props.match.params.coursesId;
|
||||
let newurl=`/courses/${coursesId}/all_course_groups.json`;
|
||||
axios.get(newurl).then((response) => {
|
||||
let newlist=this.state.course_groups;
|
||||
response.data.course_groups.map((item,key)=>{
|
||||
newlist.push(item)
|
||||
})
|
||||
this.setState({
|
||||
course_groups:newlist
|
||||
})
|
||||
})
|
||||
|
||||
this.getdata()
|
||||
}
|
||||
|
||||
handleChange=(value)=>{
|
||||
this.getdata(value)
|
||||
}
|
||||
|
||||
render() {
|
||||
let {datas,newlist,course_groups,spal}=this.state;
|
||||
|
||||
const cols = {
|
||||
month: {
|
||||
type: 'pow',
|
||||
// nice: true,
|
||||
exponent:1,
|
||||
// minLimit:1,
|
||||
// tickInterval:1,
|
||||
// minTickInterval:2
|
||||
},
|
||||
temperature:{
|
||||
type: 'linear',
|
||||
nice:[0,100],
|
||||
minTickInterval:2
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
return(
|
||||
<React.Fragment >
|
||||
<div>
|
||||
{
|
||||
spal===true?
|
||||
<div style={{
|
||||
minHeight:"500px",
|
||||
}}>
|
||||
<LoadingSpin></LoadingSpin>
|
||||
</div>
|
||||
|
||||
:
|
||||
<div>
|
||||
|
||||
<Row type="flex" justify="space-between" className={"mt20"}>
|
||||
<style>
|
||||
{
|
||||
`
|
||||
.lishiqiandao{
|
||||
background-image: url(${getImageUrl(`images/qiandao/lishi.png`)});
|
||||
}
|
||||
.daokeqiandao{
|
||||
background-image: url(${getImageUrl(`images/qiandao/daoke.png`)});
|
||||
}
|
||||
.kuangkeqiandao{
|
||||
background-image: url(${getImageUrl(`images/qiandao/kuangke.png`)});
|
||||
}
|
||||
.qingjiaqiandao{
|
||||
background-image: url(${getImageUrl(`images/qiandao/qingjia.png`)});
|
||||
}
|
||||
`
|
||||
}
|
||||
</style>
|
||||
<Col span={6}>
|
||||
<Card style={{ width: 209 }} className={"gutterrowbox lishiqiandao"}>
|
||||
<div className={"gutterrowboxcontent ml5"}>{datas&&datas.all_history_count}</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Card style={{ width: 209 }} className={"ml8 gutterrowbox daokeqiandao"}>
|
||||
<div className={"gutterrowboxcontent ml5"}>{datas?(datas&&datas.avg_normal_rate*100).toFixed(0)+"%":""}</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6}>
|
||||
<Card style={{ width: 209 }} className={"ml14 gutterrowbox kuangkeqiandao"}>
|
||||
<div className={"gutterrowboxcontent ml5"}>{datas?(datas&&datas.avg_absence_rate*100).toFixed(0)+"%":""}</div>
|
||||
</Card>
|
||||
</Col>
|
||||
<Col span={6} >
|
||||
<Card style={{ width: 209 }} className={"ml20 gutterrowbox qingjiaqiandao"}>
|
||||
<div className={"gutterrowboxcontent ml5"}>{datas?(datas&&datas.avg_leave_rate*100).toFixed(0)+"%":""}</div>
|
||||
</Card>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
{newlist&&newlist.length>0?<div className={"SigninstatisticsChart mt20"}>
|
||||
<div className={"pd30"}>
|
||||
<Row>
|
||||
<Col span={14}>
|
||||
<Row type="flex" justify="start">
|
||||
<Col span={5}>
|
||||
<Row>
|
||||
<Col span={12} className={"mindaoke mr5"}></Col>
|
||||
<Col>到课率</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Row>
|
||||
<Col span={12} className={"minkuangke mr5"}></Col>
|
||||
<Col>旷课率</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={5}>
|
||||
<Row>
|
||||
<Col span={12} className={"minqingjia mr5"}></Col>
|
||||
<Col>请假率</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
</Row>
|
||||
</Col>
|
||||
<Col span={10}><Row type="flex" justify="end">
|
||||
<Col span={8} className={"Signinstatisticsfont"}>显示最近十次签到</Col>
|
||||
<Col span={10}>
|
||||
<Select defaultValue={"全部"} onChange={(e)=>this.handleChange(e)} style={{width:"130px"}} className={"Signinstatisticsfontselect"}>
|
||||
{course_groups&&course_groups.map((item,key)=>{
|
||||
return(
|
||||
<Option value={item.id} title={item.name} >{item.name}</Option>
|
||||
)
|
||||
})}
|
||||
</Select>
|
||||
</Col>
|
||||
</Row></Col>
|
||||
</Row>
|
||||
</div>
|
||||
|
||||
<div className={"padding03000"}>
|
||||
<Chart height={400} data={newlist} scale={cols} forceFit>
|
||||
{/*<Legend />*/}
|
||||
<Axis name="month" />
|
||||
<Axis
|
||||
name="temperature"
|
||||
label={{
|
||||
formatter: val => `${val}%`
|
||||
}}
|
||||
/>
|
||||
<Tooltip
|
||||
crosshairs={{
|
||||
type: "y"
|
||||
}}
|
||||
/>
|
||||
<Geom
|
||||
type="line"
|
||||
position="month*temperature"
|
||||
size={2}
|
||||
// color={"city"}
|
||||
shape={"smooth"}
|
||||
color={["city", ["#26C7C9", "#FF835C","#EDBA6F"]]}
|
||||
tooltip={['name*temperature*city', (name, temperature,city) => {
|
||||
return {
|
||||
//自定义 tooltip 上显示的 title 显示内容等。
|
||||
name: city,
|
||||
title: name,
|
||||
value: temperature+"%"
|
||||
};
|
||||
}]}
|
||||
/>
|
||||
<Geom
|
||||
type="point"
|
||||
position="month*temperature"
|
||||
size={4}
|
||||
shape={"circle"}
|
||||
color={["city", ["#26C7C9", "#FF835C","#EDBA6F"]]}
|
||||
style={{
|
||||
stroke: "#fff",
|
||||
lineWidth: 1
|
||||
}}
|
||||
// tooltip={['month*sold', (month, temperature) => {
|
||||
// return {
|
||||
// //自定义 tooltip 上显示的 title 显示内容等。
|
||||
// name: 'sold1',
|
||||
// title: 'dddd' + month,
|
||||
// value: temperature
|
||||
// };
|
||||
// }]}
|
||||
/>
|
||||
</Chart>
|
||||
</div>
|
||||
|
||||
</div>:<div style={{
|
||||
minHeight:"400px",
|
||||
}}>
|
||||
<NoneDatas></NoneDatas>
|
||||
</div>}
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default Signinstatistics;
|
@ -0,0 +1,36 @@
|
||||
import React, { Component } from 'react';
|
||||
import { getImageUrl , getUrl } from 'educoder';
|
||||
|
||||
class NoneDatas extends Component{
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
render(){
|
||||
const { style } = this.props;
|
||||
return(
|
||||
<div className="edu-tab-con-box clearfix edu-txt-center intermediatecenter" style={ style || { width:"100%",height:"100%"}}>
|
||||
<style>
|
||||
{`
|
||||
.edu-tab-con-box{
|
||||
padding:100px 0px;
|
||||
}
|
||||
.ant-modal-body .edu-tab-con-box{
|
||||
padding:0px!important;
|
||||
}
|
||||
img.edu-nodata-img{
|
||||
margin: 40px auto 20px;
|
||||
}
|
||||
.zenwuxgsj{
|
||||
font-size:17px;
|
||||
font-family:MicrosoftYaHei;
|
||||
color:rgba(136,136,136,1);
|
||||
}
|
||||
`}
|
||||
</style>
|
||||
<img className="edu-nodata-img mb20" src={getUrl("/images/educoder/nodata.png")}/>
|
||||
<p className="edu-nodata-p mb10 zenwuxgsj">暂无相关数据</p>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default NoneDatas;
|