Merge branch 'dev_aliyun' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun
@ -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.num
|
||||
json.total_time v.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,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 |
Before Width: | Height: | Size: 404 KiB After Width: | Height: | Size: 407 KiB |
@ -0,0 +1,258 @@
|
||||
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 {
|
||||
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:[],
|
||||
course_groups:[{id:"全部",name:"全部"}],
|
||||
spal:false,
|
||||
}
|
||||
}
|
||||
getdata=(group_id)=>{
|
||||
this.setState({
|
||||
spal:true
|
||||
})
|
||||
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,
|
||||
city:"到课率",
|
||||
temperature: (item.normal_rate).toFixed(0)
|
||||
})
|
||||
newlists.push({
|
||||
month: item.index,
|
||||
city: "旷课率",
|
||||
temperature: (item.absence_rate).toFixed(0)
|
||||
})
|
||||
newlists.push({
|
||||
month: item.index,
|
||||
city: "请假率",
|
||||
temperature: (item.leave_rate).toFixed(0)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
this.setState({
|
||||
datas:response.data,
|
||||
newlist:newlists
|
||||
})
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
this.setState({
|
||||
spal:false
|
||||
})
|
||||
}).catch((error) => {
|
||||
this.setState({
|
||||
spal:false
|
||||
})
|
||||
|
||||
})
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
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: {
|
||||
range: [0, 1]
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
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>
|
||||
|
||||
<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"}}>
|
||||
{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"]]}
|
||||
/>
|
||||
<Geom
|
||||
type="point"
|
||||
position="month*temperature"
|
||||
size={4}
|
||||
shape={"circle"}
|
||||
color={["city", ["#26C7C9", "#FF835C","#EDBA6F"]]}
|
||||
style={{
|
||||
stroke: "#fff",
|
||||
lineWidth: 1
|
||||
}}
|
||||
/>
|
||||
</Chart>
|
||||
</div>
|
||||
|
||||
</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;
|
@ -0,0 +1,33 @@
|
||||
import React,{ Component } from "react";
|
||||
import '../../css/signincdi.css';
|
||||
//在线学习
|
||||
class Histeacomponent extends Component{
|
||||
//教师历史签到
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
this.state={
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
componentDidUpdate = (prevProps) => {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
render(){
|
||||
return(
|
||||
<React.Fragment>
|
||||
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default Histeacomponent;
|
@ -0,0 +1,33 @@
|
||||
import React,{ Component } from "react";
|
||||
import '../../css/signincdi.css';
|
||||
//在线学习
|
||||
class Signteacomponent extends Component{
|
||||
//教师签到统计
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
this.state={
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
componentDidUpdate = (prevProps) => {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
render(){
|
||||
return(
|
||||
<React.Fragment>
|
||||
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default Signteacomponent;
|
@ -0,0 +1,176 @@
|
||||
import React,{ Component } from "react";
|
||||
import '../../css/signincdi.css';
|
||||
import axios from 'axios';
|
||||
import Teacherentry from "../Teacherentry";
|
||||
import NoneDatas from '../NoneDatas';
|
||||
import LoadingSpin from '../../../../../common/LoadingSpin';
|
||||
|
||||
import Listjihe from "../../../../question/component/Listjihe";
|
||||
|
||||
//在线学习
|
||||
class Teaccomponent extends Component{
|
||||
//教师正在签到
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
this.state={
|
||||
mydatas:[]
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.setState({
|
||||
mydatas:this.props.datas
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
componentDidUpdate = (prevProps) => {
|
||||
|
||||
|
||||
}
|
||||
//截止
|
||||
thisEnd=(attendance_id)=>{
|
||||
const url = `/weapps/attendances/${attendance_id}/end.json`;
|
||||
var data={
|
||||
|
||||
}
|
||||
axios.post(url, data)
|
||||
.then((result) => {
|
||||
if (result.data.status === 0) {
|
||||
// try {
|
||||
// this.props.showNotification(`截止成功`);
|
||||
// }catch (e) {
|
||||
//
|
||||
// }
|
||||
this.props.getsetdatas();
|
||||
}else{
|
||||
this.props.showNotification(result.data.message);
|
||||
|
||||
}
|
||||
}).catch((error) => {
|
||||
//console.log(error);
|
||||
})
|
||||
}
|
||||
//删除
|
||||
thisdelete=(attendance_id)=>{
|
||||
const url = `/weapps/attendances/${attendance_id}.json`;
|
||||
var data={
|
||||
|
||||
}
|
||||
axios.delete(url, data)
|
||||
.then((result) => {
|
||||
if (result.data.status === 0) {
|
||||
// try {
|
||||
// this.props.showNotification(`删除成功`);
|
||||
// }catch (e) {
|
||||
//
|
||||
// }
|
||||
|
||||
this.props.getsetdatas();
|
||||
}else{
|
||||
this.props.showNotification(result.data.message);
|
||||
|
||||
}
|
||||
}).catch((error) => {
|
||||
//console.log(error);
|
||||
})
|
||||
}
|
||||
|
||||
//学生签到
|
||||
Signin=(attendance_mode,attendance_id,code)=>{
|
||||
debugger
|
||||
const url = `/weapps/course_member_attendances.json`;
|
||||
var data={
|
||||
|
||||
}
|
||||
if(attendance_mode==="QUICK"){
|
||||
//快捷签到
|
||||
data={
|
||||
attendance_mode:"QUICK",
|
||||
attendance_id:attendance_id,
|
||||
}
|
||||
axios.post(url, data)
|
||||
.then((result) => {
|
||||
if (result.data.status === 0) {
|
||||
try {
|
||||
this.props.showNotification(`签到成功`);
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
|
||||
this.props.getsetdatas();
|
||||
}else{
|
||||
this.props.showNotification(result.data.message);
|
||||
|
||||
}
|
||||
}).catch((error) => {
|
||||
})
|
||||
}else if(attendance_mode==="QRCODE"){
|
||||
//二维码签到
|
||||
data={
|
||||
attendance_mode:"QRCODE",
|
||||
attendance_id:attendance_id,
|
||||
code:code,
|
||||
}
|
||||
this.props.GotomQrcodesodesy(data,true)
|
||||
}else if(attendance_mode==="NUMBER"){
|
||||
//数字签到
|
||||
data={
|
||||
attendance_mode:"NUMBER",
|
||||
attendance_id:attendance_id,
|
||||
code:code,
|
||||
}
|
||||
this.props.Gotomodes(data,true)
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
render(){
|
||||
let mydatas=this.props.datas?this.props.datas:[];
|
||||
let Spin= this.props.Spin;
|
||||
return(
|
||||
<React.Fragment>
|
||||
<div className="ws100s mt20 h500">
|
||||
{
|
||||
Spin&&Spin===true?
|
||||
<LoadingSpin></LoadingSpin>
|
||||
:
|
||||
|
||||
(
|
||||
mydatas&&mydatas.length>0?
|
||||
mydatas.map((object, index) => {
|
||||
return (
|
||||
<Teacherentry
|
||||
Signinnamestypes={(id,b,a)=>this.props.Signinnamestypes(id,b,a)}
|
||||
Signin={(a,b,c)=>this.Signin(a,b,c)}
|
||||
qiandaoxiangq={(b,id)=>this.props.qiandaoxiangq(b,id)}
|
||||
thisdelete={(id)=>this.thisdelete(id)}
|
||||
thisEnd={(id)=>this.thisEnd(id)}
|
||||
item={object} key={index}
|
||||
index={index}
|
||||
defaultActiveKey={this.props.defaultActiveKey}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
></Teacherentry>
|
||||
|
||||
)
|
||||
})
|
||||
:
|
||||
<NoneDatas></NoneDatas>
|
||||
)
|
||||
|
||||
}
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default Teaccomponent;
|
@ -0,0 +1,164 @@
|
||||
.gutterrowbox{
|
||||
height:150px;
|
||||
border: none !important;
|
||||
}
|
||||
.gutterrowbox .ant-card-body{
|
||||
height:150px;
|
||||
position: relative;
|
||||
}
|
||||
.gutterrowboxcontent{
|
||||
position: absolute;
|
||||
bottom: 20px;
|
||||
font-size:36px;
|
||||
font-weight:400;
|
||||
color:rgba(255,255,255,1);
|
||||
}
|
||||
.ml14{
|
||||
margin-left: 14px !important;
|
||||
}
|
||||
.ml8{
|
||||
margin-left: 8px !important;
|
||||
}
|
||||
.ml20{
|
||||
margin-left: 20px !important;
|
||||
}
|
||||
.lishiqiandao{
|
||||
|
||||
height: 150px;
|
||||
|
||||
background-size: cover !important;
|
||||
background-position: center !important;
|
||||
background-repeat: no-repeat !important;
|
||||
}
|
||||
.daokeqiandao{
|
||||
|
||||
height: 150px;
|
||||
|
||||
background-size: cover !important;
|
||||
background-position: center !important;
|
||||
background-repeat: no-repeat !important;
|
||||
}
|
||||
.kuangkeqiandao{
|
||||
|
||||
height: 150px;
|
||||
|
||||
background-size: cover !important;
|
||||
background-position: center !important;
|
||||
background-repeat: no-repeat !important;
|
||||
}
|
||||
.qingjiaqiandao{
|
||||
|
||||
height: 150px;
|
||||
|
||||
background-size: cover !important;
|
||||
background-position: center !important;
|
||||
background-repeat: no-repeat !important;
|
||||
}
|
||||
|
||||
.SigninstatisticsChart{
|
||||
height:519px;
|
||||
background:rgba(255,255,255,1);
|
||||
box-shadow:0px 3px 7px 0px rgba(0, 0, 0, 0.05);
|
||||
}
|
||||
.pd30{
|
||||
padding:30px;
|
||||
}
|
||||
.padding03000{
|
||||
padding: 0px 30px 0px 0px;
|
||||
}
|
||||
|
||||
.mindaoke{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-image: url(./dot-green@2x.png);
|
||||
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.minkuangke{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-image: url(./dot-orange@2x.png);
|
||||
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.minqingjia{
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
background-image: url(./dot-orange@2x1.png);
|
||||
|
||||
background-size: cover;
|
||||
background-position: center;
|
||||
background-repeat: no-repeat;
|
||||
}
|
||||
|
||||
.Signinstatisticsfont{
|
||||
font-weight: 400;
|
||||
color: rgba(153,153,153,1);
|
||||
text-align: right;
|
||||
margin-right: 20px;
|
||||
line-height: 32px;
|
||||
}
|
||||
|
||||
#form_in_modal_group_ids .ant-select-selection{
|
||||
background: #fafafa !important;
|
||||
}
|
||||
|
||||
#form_in_modal_attendance_date .ant-calendar-picker-input {
|
||||
height:40px;
|
||||
}
|
||||
|
||||
#form_in_modal_start_time{
|
||||
height:40px;
|
||||
background: #fafafa !important;
|
||||
}
|
||||
|
||||
#form_in_modal_end_time{
|
||||
height:40px;
|
||||
background: #fafafa !important;
|
||||
}
|
||||
|
||||
.Signedinlistbox .ant-select-selection--single{
|
||||
height:40px !important;
|
||||
background:rgba(255,255,255,1);
|
||||
border:1px solid rgba(234,234,234,1);
|
||||
border-radius:4px;
|
||||
}
|
||||
|
||||
.Signedinlistbox .ant-select-selection__rendered{
|
||||
line-height: 40px !important;
|
||||
}
|
||||
|
||||
.Signedintextright{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.color26C7C9{
|
||||
color:#26C7C9;
|
||||
}
|
||||
|
||||
.colorEAAE4E{
|
||||
color:#EAAE4E;
|
||||
}
|
||||
|
||||
.colorFF835C{
|
||||
color:#FF835C;
|
||||
}
|
||||
|
||||
.color1890FF{
|
||||
color:#1890FF;
|
||||
}
|
||||
|
||||
.backfff .ant-table-thead tr th{
|
||||
background: #fff;
|
||||
border-bottom:1px solid #EBEBEB !important;
|
||||
}
|
||||
|
||||
.textcenter{
|
||||
text-align: center !important;
|
||||
}
|
After Width: | Height: | Size: 740 B |
After Width: | Height: | Size: 729 B |
After Width: | Height: | Size: 777 B |
@ -0,0 +1,354 @@
|
||||
/* 中间居中 */
|
||||
.intermediatecenter{
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
/* 简单居中 */
|
||||
.intermediatecenterysls{
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
/* 头顶部居中 */
|
||||
.topcenter{
|
||||
display: -webkit-flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
/* 均匀分开 */
|
||||
.spacearound{
|
||||
display: flex;
|
||||
justify-content: space-around;
|
||||
|
||||
}
|
||||
/* 两边靠墙中间均匀分开 */
|
||||
.spacebetween{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
/* 从左分开 */
|
||||
.spacearoundflexstart{
|
||||
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.spacebetween{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.unpsysls{
|
||||
display: inline-block;
|
||||
text-align: justify;
|
||||
font-size: 28px;
|
||||
}
|
||||
|
||||
/* x轴正方向排序 */
|
||||
/* 一 二 三 四 五 六 七 八 */
|
||||
.sortinxdirection{
|
||||
display: flex;
|
||||
flex-direction:row;
|
||||
}
|
||||
/* x轴反方向排序 */
|
||||
/* 八 七 六 五 四 三 二 一 */
|
||||
.xaxisreverseorder{
|
||||
display: flex;
|
||||
flex-direction:row-reverse;
|
||||
}
|
||||
/* 垂直布局 正方向*/
|
||||
/* 一
|
||||
二
|
||||
三
|
||||
四
|
||||
五
|
||||
六
|
||||
七
|
||||
八 */
|
||||
.verticallayout{
|
||||
display: flex;
|
||||
flex-direction:column;
|
||||
}
|
||||
/* 垂直布局 反方向*/
|
||||
.reversedirection{
|
||||
display: flex;
|
||||
flex-direction:column-reverse;
|
||||
}
|
||||
/* 两端对齐 */
|
||||
.alignmentatbothends{
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
}
|
||||
.file_path_input{
|
||||
position: absolute;
|
||||
right: -50%;
|
||||
}
|
||||
.ws100s{
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.ws70s{
|
||||
width: 70%;
|
||||
}
|
||||
|
||||
.ws75s{
|
||||
width: 75%;
|
||||
}
|
||||
.ws80s{
|
||||
width: 80%;
|
||||
}
|
||||
.ws50s{
|
||||
width: 50%;
|
||||
}
|
||||
.hs30s{
|
||||
height: 30%;
|
||||
}
|
||||
.ws20s{
|
||||
width: 20%;
|
||||
}
|
||||
.ws25s{
|
||||
width: 25%;
|
||||
}
|
||||
.yslmaxheigthk{
|
||||
|
||||
}
|
||||
.mysligtes{
|
||||
font-size:16px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:bold;
|
||||
color:rgba(144,147,153,1);
|
||||
padding-left: 34px;
|
||||
}
|
||||
.yslmaxheigthk .ws100s .ant-tabs .ant-tabs-bar {
|
||||
border-bottom: 1px solid #ffffff !important;
|
||||
background: #ffffff !important;
|
||||
background-color: #ffffff !important;
|
||||
margin: 0 !important;
|
||||
}
|
||||
.yslmaxheigthk .ws100s .ant-tabs .ant-tabs-bar .ant-tabs-nav-container {
|
||||
padding-left: 25px;
|
||||
}
|
||||
.yslmaxheigthk .ws100s .ant-tabs .ant-tabs-bar .ant-tabs-nav-container .ant-tabs-ink-bar{
|
||||
width: 68px !important;
|
||||
left: 14px;
|
||||
|
||||
}
|
||||
|
||||
.yslmaxheigthk .ws100s .ant-tabs .ant-tabs-bar .ant-tabs-tab{
|
||||
padding: 25px 16px !important;
|
||||
font-size: 16px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
|
||||
}
|
||||
.positiondivs{
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
}
|
||||
.posiivs{
|
||||
padding: 30px 5px !important;
|
||||
font-size: 16px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
color: #1890ff;
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.posiivsicon{
|
||||
padding: 22px 0px !important;
|
||||
font-size: 16px;
|
||||
font-family: Microsoft YaHei;
|
||||
font-weight: bold;
|
||||
color: #1890ff;
|
||||
}
|
||||
.posiivsiconmyss{
|
||||
font-size: 14px;
|
||||
font-family: Microsoft YaHei;
|
||||
color: #999999;
|
||||
}
|
||||
.xiaoshou{
|
||||
cursor:pointer !important;
|
||||
}
|
||||
.xiaoshout{
|
||||
cursor:default !important;
|
||||
}
|
||||
|
||||
.teacherentrydiv{
|
||||
padding-left: 32px;
|
||||
padding-right: 32px;
|
||||
padding-top: 20px;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
|
||||
.teachedivp{
|
||||
font-size:16px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:bold;
|
||||
color:rgba(51,51,51,1);
|
||||
}
|
||||
.ymaxnamewidthdivp{
|
||||
max-width:100%;
|
||||
width: 100%;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
cursor: default;
|
||||
}
|
||||
.teachedivps{
|
||||
font-size:14px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:400;
|
||||
color:rgba(144,147,153,1);
|
||||
}
|
||||
.teachedivpsy{
|
||||
font-size:14px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:400;
|
||||
color:#333333;
|
||||
|
||||
}
|
||||
.progressivps{
|
||||
width:200px;
|
||||
margin-left: 10px;
|
||||
|
||||
}
|
||||
.progressivpss{
|
||||
font-size:12px;
|
||||
line-height: 23px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:400;
|
||||
color:rgba(64,158,255,1);
|
||||
margin-left: 15px;
|
||||
}
|
||||
.w60ys{
|
||||
width: 60px;
|
||||
}
|
||||
|
||||
.ymaxnamewidth60{
|
||||
max-width: 70px;
|
||||
width: 70px;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
cursor: default;
|
||||
}
|
||||
.ymaxnamewidth80{
|
||||
max-width: 80px;
|
||||
width: 80px;
|
||||
overflow:hidden;
|
||||
text-overflow:ellipsis;
|
||||
white-space:nowrap;
|
||||
cursor: default;
|
||||
}
|
||||
.w80ys{
|
||||
width: 80px;
|
||||
}
|
||||
|
||||
.jiezhis{
|
||||
font-size:14px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:400;
|
||||
color:rgba(64,158,255,1);
|
||||
}
|
||||
.shanchu{
|
||||
font-size:14px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:400;
|
||||
color:rgba(245,108,108,1);
|
||||
margin-right: 30px;
|
||||
}
|
||||
|
||||
.qiandaobutton{
|
||||
font-size:16px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:400;
|
||||
color:rgba(255,255,255,1);
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
width:100px;
|
||||
height:40px;
|
||||
background:rgba(64,158,255,1);
|
||||
border-radius:4px;
|
||||
}
|
||||
|
||||
.zcqiandao{
|
||||
width:100px;
|
||||
height:40px;
|
||||
border:1px solid rgba(38,199,201,1);
|
||||
border-radius:4px;
|
||||
font-size:16px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:400;
|
||||
color:rgba(38,199,201,1);
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
|
||||
}
|
||||
.qjqiandao{
|
||||
width:100px;
|
||||
height:40px;
|
||||
border:1px solid #EAAE4E;
|
||||
border-radius:4px;
|
||||
font-size:16px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:400;
|
||||
color:#EAAE4E;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
|
||||
|
||||
}
|
||||
|
||||
.kkqiandao{
|
||||
width:100px;
|
||||
height:40px;
|
||||
border:1px solid #FF835C;
|
||||
border-radius:4px;
|
||||
font-size:16px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:400;
|
||||
color:#FF835C;
|
||||
text-align: center;
|
||||
line-height: 40px;
|
||||
|
||||
}
|
||||
.h40s{
|
||||
line-height: 40px !important;
|
||||
}
|
||||
.h28s{
|
||||
line-height: 28px !important;
|
||||
}
|
||||
.mt40{
|
||||
margin-top: 40px !important;
|
||||
}
|
||||
|
||||
.h500{
|
||||
min-height: 500px;
|
||||
}
|
||||
.kkp{
|
||||
font-size:14px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:400;
|
||||
}
|
||||
.pr32{
|
||||
padding-right: 32px;
|
||||
}
|
||||
|
||||
.mr20r{
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.color-reds{
|
||||
color:rgba(245,108,108,1) !important;
|
||||
}
|
||||
|
||||
.fh{
|
||||
font-size:16px;
|
||||
font-family:Microsoft YaHei;
|
||||
font-weight:400;
|
||||
color:rgba(153,153,153,1);
|
||||
|
||||
}
|
@ -0,0 +1,295 @@
|
||||
import "../css/Signinstatistics.css"
|
||||
import React from 'react'
|
||||
import { Modal , Form, Input, Radio,DatePicker, TimePicker,Select,Button} from 'antd';
|
||||
import moment from 'moment';
|
||||
import axios from 'axios';
|
||||
function range(start, end) {
|
||||
const result = [];
|
||||
for (let i = start; i < end; i++) {
|
||||
result.push(i);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function disabledDateTime() {
|
||||
return {
|
||||
disabledMinutes: () => range(1, 30).concat(range(31, 60)),
|
||||
// disabledSeconds: () => range(0,60)
|
||||
}
|
||||
}
|
||||
|
||||
function disabledDate(current) {
|
||||
return current && current < moment().endOf('day').subtract(1, 'days');
|
||||
}
|
||||
|
||||
const CollectionCreateForm = Form.create({ name: 'form_in_modal' })(
|
||||
|
||||
class extends React.Component {
|
||||
constructor(props){
|
||||
super(props);
|
||||
this.state = {
|
||||
course_groups:[],
|
||||
type:false,
|
||||
dateString:null
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
const coursesId=this.props.match.params.coursesId;
|
||||
let newurl=`/courses/${coursesId}/all_course_groups.json`;
|
||||
axios.get(newurl).then((response) => {
|
||||
|
||||
this.setState({
|
||||
course_groups:response.data.course_groups
|
||||
})
|
||||
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
hideCreatesign=(e)=>{
|
||||
e.preventDefault();
|
||||
const {settabsdata,hideCreatesign} = this.props;
|
||||
const coursesId=this.props.match.params.coursesId;
|
||||
this.setState({
|
||||
type:true
|
||||
})
|
||||
this.props.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
if(moment(values.end_time).format('HH:mm')<moment(values.start_time).format('HH:mm')){
|
||||
this.props.showNotification(`结束时间不能小于起始时间`);
|
||||
this.setState({
|
||||
type:false
|
||||
})
|
||||
return
|
||||
}
|
||||
if( moment(values.start_time).format('HH:mm')===moment(values.end_time).format('HH:mm')){
|
||||
this.props.showNotification(`结束时间不能与起始时间相同`);
|
||||
this.setState({
|
||||
type:false
|
||||
})
|
||||
return
|
||||
}
|
||||
let url=`/weapps/courses/${coursesId}/attendances.json`;
|
||||
|
||||
axios.post(url, {
|
||||
attendance_date:moment(values.attendance_date).format('YYYY-MM-DD'),
|
||||
end_time: moment(values.end_time).format('HH:mm'),
|
||||
group_ids:values.group_ids,
|
||||
mode: values.mode,
|
||||
name: values.name,
|
||||
start_time:moment(values.start_time).format('HH:mm'),
|
||||
})
|
||||
.then((response) => {
|
||||
if (response.data.status == 0) {
|
||||
this.props.showNotification(`创建签到成功`);
|
||||
this.setState({
|
||||
type:false
|
||||
})
|
||||
hideCreatesign()
|
||||
settabsdata()
|
||||
}
|
||||
})
|
||||
.catch(function (error) {
|
||||
console.log(error);
|
||||
});
|
||||
}else{
|
||||
this.setState({
|
||||
type:false
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
}
|
||||
getDisabledHours=()=> {
|
||||
let hours = []
|
||||
if(this.state.dateString===moment().format('YYYY-MM-DD')){
|
||||
let time = moment().format('HH:mm')
|
||||
let timeArr = time.split(':')
|
||||
for (var i = 0; i < parseInt(timeArr[0]); i++) {
|
||||
hours.push(i)
|
||||
}
|
||||
}
|
||||
|
||||
return hours
|
||||
}
|
||||
|
||||
getDisabledMinutes=(selectedHour)=>{
|
||||
let minutes = []
|
||||
if(this.state.dateString===moment().format('YYYY-MM-DD')){
|
||||
let time = moment().format('HH:mm')
|
||||
let timeArr = time.split(':')
|
||||
if (selectedHour == parseInt(timeArr[0])) {
|
||||
for(var i = 0; i < parseInt(timeArr[1]); i++) {
|
||||
minutes.push(i)
|
||||
}
|
||||
}
|
||||
}
|
||||
return minutes
|
||||
}
|
||||
|
||||
onChange=(date, dateString)=>{
|
||||
this.setState({
|
||||
dateString:dateString
|
||||
})
|
||||
}
|
||||
render() {
|
||||
const { visible, form ,setRadio,Radiolist,hideCreatesign} = this.props;
|
||||
let {course_groups}=this.state;
|
||||
const { getFieldDecorator } = form;
|
||||
const { Option } = Select;
|
||||
const formItemLayout = {
|
||||
labelCol: { span: 4 },
|
||||
wrapperCol: { span: 19},
|
||||
};
|
||||
|
||||
const leftbuton={
|
||||
"width":"130px",
|
||||
"height":"40px",
|
||||
"border":"1px solid rgba(76,172,255,1)",
|
||||
"border-radius":"4px",
|
||||
}
|
||||
|
||||
const rightbuton={
|
||||
"width":"130px",
|
||||
"height":"40px",
|
||||
"background":"#4CACFF",
|
||||
"border-radius":"4px",
|
||||
}
|
||||
const format = 'HH:mm';
|
||||
|
||||
return (
|
||||
<Modal
|
||||
visible={visible}
|
||||
title="创建签到"
|
||||
closable={false}
|
||||
footer={null}
|
||||
width={600}
|
||||
destroyOnClose={true}
|
||||
>
|
||||
<Form {...formItemLayout}>
|
||||
|
||||
<Form.Item label="签到名称:">
|
||||
{getFieldDecorator('name', {
|
||||
rules: [{ required: true, message: '请输入签到名称' },{whitespace:true,message: '请勿输入空格'}],
|
||||
})(<Input placeholder="请输入签到名称" style={{height:"40px"}} />)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="签到班级:">
|
||||
{getFieldDecorator('group_ids')(
|
||||
<Select mode="multiple" placeholder={course_groups.length>0?"不选择分班时默认选择全部学生":'暂无分班,将默认选择课堂全部学生'} getPopupContainer={trigger => trigger.parentNode}>
|
||||
|
||||
{course_groups.map((item,key)=>{
|
||||
return(
|
||||
<Option value={item.id}>{item.name}</Option>
|
||||
)
|
||||
})}
|
||||
|
||||
</Select>,
|
||||
)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="签到方式:" >
|
||||
{getFieldDecorator('mode', {
|
||||
rules: [{ required: true, message: '请选择签到方式' }],
|
||||
})(
|
||||
<Radio.Group onChange={setRadio} getPopupContainer={trigger => trigger.parentNode}>
|
||||
<Radio value="QUICK">快捷签到</Radio>
|
||||
<Radio value="NUMBER">签到码签到</Radio>
|
||||
<Radio value="QRCODE">二维码签到</Radio>
|
||||
</Radio.Group>,
|
||||
)}
|
||||
{Radiolist==="QUICK"?<div
|
||||
style={{color:"#E6A23C",
|
||||
height:"15px",
|
||||
lineHeight: "15px"}}>学生点击签到按钮即可完成签到</div>:""}
|
||||
|
||||
{Radiolist==="NUMBER"?<div
|
||||
style={{color:"#E6A23C",
|
||||
height:"15px",
|
||||
lineHeight: "15px"}}
|
||||
>学生需要输入签到码才能完成签到</div>:""}
|
||||
|
||||
{Radiolist==="QRCODE"?<div
|
||||
style={{color:"#E6A23C",
|
||||
height:"15px",
|
||||
lineHeight: "15px"}}
|
||||
>学生需从小程序进入课堂扫码才能完成签到</div>:""}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="签到日期:">
|
||||
{getFieldDecorator('attendance_date', {
|
||||
rules: [{ type: 'object', required: true, message: '请选择签到日期',}],
|
||||
})(<DatePicker style={{width:"413px"}} getPopupContainer={trigger => trigger.parentNode}
|
||||
disabledTime={disabledDateTime}
|
||||
disabledDate={disabledDate}
|
||||
onChange={this.onChange}
|
||||
/>)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="开始时间:">
|
||||
{getFieldDecorator('start_time', {
|
||||
rules: [{ type: 'object', required: true, message: '请选择开始时间' }],
|
||||
})(<TimePicker style={{width:"413px"}} format={format} getPopupContainer={trigger => trigger.parentNode}/>)}
|
||||
</Form.Item>
|
||||
|
||||
<Form.Item label="结束时间:">
|
||||
{getFieldDecorator('end_time', {
|
||||
rules: [{ type: 'object', required: true, message: '请选择结束时间' }],
|
||||
})(<TimePicker style={{width:"413px"}} format={format} getPopupContainer={trigger => trigger.parentNode}
|
||||
disabledHours={this.getDisabledHours}
|
||||
disabledMinutes={this.getDisabledMinutes}
|
||||
|
||||
/>)}
|
||||
</Form.Item>
|
||||
|
||||
|
||||
<div className={"mt20 marginauto clearfix edu-txt-center"}>
|
||||
<a>
|
||||
<Button type="primary" ghost style={leftbuton} onClick={hideCreatesign}>
|
||||
取消
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
<a>
|
||||
<Button type="primary" className={"ml20"} style={rightbuton} onClick={(e)=>this.hideCreatesign(e)} loading={this.state.type}>
|
||||
确定
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</Form>
|
||||
</Modal>
|
||||
);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
class Createsignmodel extends React.Component {
|
||||
state = {
|
||||
Radiolist: "",
|
||||
};
|
||||
setRadio=(e)=>{
|
||||
|
||||
this.setState({
|
||||
Radiolist:e.target.value
|
||||
})
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<CollectionCreateForm
|
||||
{...this.state}
|
||||
{...this.props}
|
||||
setRadio={(e)=>this.setRadio(e)}
|
||||
/>
|
||||
</React.Fragment>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default Createsignmodel;
|
||||
|
||||
|
@ -0,0 +1,77 @@
|
||||
import React,{ Component } from "react";
|
||||
import { Modal , Button} from 'antd';
|
||||
import QRCode from 'qrcode.react';
|
||||
|
||||
class Qrcodesignin extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
render() {
|
||||
|
||||
const leftbuton={
|
||||
"width":"130px",
|
||||
"height":"40px",
|
||||
"border":"1px solid rgba(76,172,255,1)",
|
||||
"border-radius":"4px",
|
||||
}
|
||||
|
||||
const rightbuton={
|
||||
"width":"130px",
|
||||
"height":"40px",
|
||||
"background":"#4CACFF",
|
||||
"border-radius":"4px",
|
||||
}
|
||||
return(
|
||||
<React.Fragment>
|
||||
{this.props.Qrcodesignintype?<Modal
|
||||
title="二维码签到"
|
||||
visible={this.props.Qrcodesignintype}
|
||||
closable={false}
|
||||
footer={null}
|
||||
>
|
||||
|
||||
<div>
|
||||
<div className={" marginauto clearfix edu-txt-center"}>
|
||||
<QRCode
|
||||
value={this.props.Qrcodesignintypedata.code} //value参数为生成二维码的链接
|
||||
size={200} //二维码的宽高尺寸
|
||||
fgColor="#000000" //二维码的颜色
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
<div className={"mt20 marginauto clearfix edu-txt-center"}>
|
||||
<a>请打开小程序在课堂的签到模块扫码签到</a>
|
||||
</div>
|
||||
|
||||
<div className={"mt20 marginauto clearfix edu-txt-center"}>
|
||||
<a>
|
||||
<Button type="primary" ghost style={leftbuton} onClick={()=>this.props.GotomQrcodesodesy(null,false)}>
|
||||
取消
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
<a>
|
||||
<Button type="primary" className={"ml20"} style={rightbuton} onClick={()=>this.props.GotomQrcodesodesy(null,false)}>
|
||||
确定
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
</Modal>:""}
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export default Qrcodesignin
|
@ -0,0 +1,105 @@
|
||||
import React,{ Component } from "react";
|
||||
|
||||
import { Modal , Form, Input,Button} from 'antd';
|
||||
import axios from 'axios';
|
||||
|
||||
class Signinname extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
setdatas=()=>{
|
||||
this.props.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
const url = `/weapps/attendances/${this.props.switattendance_id}.json`;
|
||||
let data={
|
||||
name:values.name,
|
||||
}
|
||||
axios.put(url, data)
|
||||
.then((result) => {
|
||||
if (result.data.status === 0) {
|
||||
try {
|
||||
this.props.showNotification(`修改成功`);
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
this.props.getsetdatas();
|
||||
this.props.Signinnamestypes(null,false,"")
|
||||
}else{
|
||||
this.props.showNotification(result.data.message);
|
||||
|
||||
}
|
||||
}).catch((error) => {
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const formItemLayout = {
|
||||
wrapperCol: { span: 25},
|
||||
};
|
||||
|
||||
const leftbuton={
|
||||
"width":"130px",
|
||||
"height":"40px",
|
||||
"border":"1px solid rgba(76,172,255,1)",
|
||||
"border-radius":"4px",
|
||||
}
|
||||
|
||||
const rightbuton={
|
||||
"width":"130px",
|
||||
"height":"40px",
|
||||
"background":"#4CACFF",
|
||||
"border-radius":"4px",
|
||||
}
|
||||
return(
|
||||
<React.Fragment>
|
||||
{this.props.Signinnamestype?<Modal
|
||||
title="提示"
|
||||
visible={this.props.Signinnamestype}
|
||||
closable={false}
|
||||
footer={null}
|
||||
>
|
||||
|
||||
<Form {...formItemLayout}>
|
||||
|
||||
<Form.Item>
|
||||
{getFieldDecorator('name', {initialValue: this.props.mybianjiname,
|
||||
rules: [{ required: true, message: '请输入签到名称' }],
|
||||
})(<Input placeholder="请输入签到名称"/>)}
|
||||
</Form.Item>
|
||||
|
||||
<div className={"mt20 marginauto clearfix edu-txt-center"}>
|
||||
<a>
|
||||
<Button type="primary" ghost style={leftbuton} onClick={()=>this.props.Signinnamestypes(null,false,"")}>
|
||||
取消
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
<a>
|
||||
<Button type="primary" className={"ml20"} style={rightbuton} onClick={()=>this.setdatas()}>
|
||||
确定
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</Form>
|
||||
</Modal>:""}
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const Signinnames = Form.create({ name: 'Signinnames' })(Signinname);
|
||||
|
||||
export default Signinnames
|
@ -0,0 +1,107 @@
|
||||
import React,{ Component } from "react";
|
||||
|
||||
import { Modal , Form, Input,Button} from 'antd';
|
||||
import axios from 'axios';
|
||||
|
||||
class Studentssignmodel extends Component {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
}
|
||||
setdatas=()=>{
|
||||
this.props.form.validateFields((err, values) => {
|
||||
if (!err) {
|
||||
const url = `/weapps/course_member_attendances.json`;
|
||||
let data={
|
||||
code:values.name,
|
||||
attendance_mode:"NUMBER",
|
||||
attendance_id:this.props.Studentssigntypedata.attendance_id,
|
||||
}
|
||||
axios.post(url, data)
|
||||
.then((result) => {
|
||||
if (result.data.status === 0) {
|
||||
try {
|
||||
this.props.showNotification(`签到成功`);
|
||||
}catch (e) {
|
||||
|
||||
}
|
||||
this.props.getsetdatas();
|
||||
this.props.Gotomodes(null,false)
|
||||
}else{
|
||||
this.props.showNotification(result.data.message);
|
||||
|
||||
}
|
||||
}).catch((error) => {
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
}
|
||||
render() {
|
||||
const { getFieldDecorator } = this.props.form;
|
||||
const formItemLayout = {
|
||||
wrapperCol: { span: 25},
|
||||
};
|
||||
|
||||
const leftbuton={
|
||||
"width":"130px",
|
||||
"height":"40px",
|
||||
"border":"1px solid rgba(76,172,255,1)",
|
||||
"border-radius":"4px",
|
||||
}
|
||||
|
||||
const rightbuton={
|
||||
"width":"130px",
|
||||
"height":"40px",
|
||||
"background":"#4CACFF",
|
||||
"border-radius":"4px",
|
||||
}
|
||||
return(
|
||||
<React.Fragment>
|
||||
{this.props.Studentssigntype?<Modal
|
||||
title="签到码签到"
|
||||
visible={this.props.Studentssigntype}
|
||||
closable={false}
|
||||
footer={null}
|
||||
>
|
||||
|
||||
<Form {...formItemLayout}>
|
||||
|
||||
<Form.Item>
|
||||
{getFieldDecorator('name', {
|
||||
rules: [{ required: true, message: '请输入签到码' }],
|
||||
})(<Input placeholder="请输入签到码"/>)}
|
||||
</Form.Item>
|
||||
|
||||
<div className={"mt20 marginauto clearfix edu-txt-center"}>
|
||||
<a>
|
||||
<Button type="primary" ghost style={leftbuton} onClick={()=>this.props.Gotomodes(null,false)}>
|
||||
取消
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
<a>
|
||||
<Button type="primary" className={"ml20"} style={rightbuton} onClick={()=>this.setdatas()}>
|
||||
确定
|
||||
</Button>
|
||||
</a>
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</Form>
|
||||
</Modal>:""}
|
||||
</React.Fragment>
|
||||
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
const Studentssignmodels = Form.create({ name: 'Studentssignmodel' })(Studentssignmodel);
|
||||
|
||||
export default Studentssignmodels
|
@ -0,0 +1,44 @@
|
||||
import React,{ Component } from "react";
|
||||
import '../css/signincdi.css';
|
||||
import { Tabs } from 'antd';
|
||||
import Teachers_signin from '../teacher/Teachers_signin';
|
||||
import Students_signin from '../student/Signindetails';
|
||||
import axios from 'axios';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
// 主签到目录 主签到目录
|
||||
class Signinmain extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
this.state={
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
|
||||
}
|
||||
|
||||
componentDidUpdate = (prevProps) => {
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// 主签到目录
|
||||
render(){
|
||||
const isAdmin = this.props.isAdmin()
|
||||
|
||||
return(
|
||||
<React.Fragment>
|
||||
<div>
|
||||
<Teachers_signin {...this.state} {...this.props}>
|
||||
|
||||
</Teachers_signin>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default Signinmain;
|
@ -0,0 +1,87 @@
|
||||
import React,{ Component } from "react";
|
||||
import '../css/signincdi.css';
|
||||
import Detailss from '../component/Detailss';
|
||||
import Signedinlist from './Signedinlist'
|
||||
import axios from 'axios';
|
||||
|
||||
//在线学习
|
||||
class Signindetails extends Component{
|
||||
constructor(props){
|
||||
super(props);
|
||||
|
||||
this.state={
|
||||
headdata:null
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.mygetdatas()
|
||||
}
|
||||
mygetdatas=()=>{
|
||||
const switattendance_id=this.props.switattendance_id;
|
||||
let urls = `/weapps/attendances/${switattendance_id}.json`;
|
||||
axios.get(urls).then((response) => {
|
||||
//.log(response);
|
||||
if(response){
|
||||
if(response.data){
|
||||
console.log("头部数据")
|
||||
console.log(response.data)
|
||||
this.setState({
|
||||
headdata:response.data
|
||||
})
|
||||
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
componentDidUpdate = (prevProps) => {
|
||||
console.log("componentDidUpdate");
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
render(){
|
||||
let {headdata}= this.state;
|
||||
return(
|
||||
<React.Fragment>
|
||||
<div className="ws100s" style={{
|
||||
position: "relative",
|
||||
}}>
|
||||
<div className="ws100s xaxisreverseorder" style={{
|
||||
position: "absolute",
|
||||
top: "-29px",
|
||||
}}>
|
||||
<p className="sortinxdirection xiaoshou" onClick={()=>this.props.qiandaoxiangq(false)}>
|
||||
<i className="iconfont icon-zuojiantou posiivsiconmyss mr5"></i>
|
||||
<p className="fh mr20"> 返回</p>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
<Detailss
|
||||
defaultActiveKey={this.props.defaultActiveKey}
|
||||
headdata={headdata}
|
||||
switattendance_id={this.props.switattendance_id}
|
||||
{...this.props}
|
||||
{...this.state}></Detailss>
|
||||
|
||||
|
||||
{/* 列表+筛选 */}
|
||||
<div>
|
||||
<Signedinlist
|
||||
defaultActiveKey={this.props.defaultActiveKey}
|
||||
switattendance_id={this.props.switattendance_id}
|
||||
headdata={headdata}
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</React.Fragment>
|
||||
)
|
||||
}
|
||||
}
|
||||
export default Signindetails;
|
Before Width: | Height: | Size: 394 KiB After Width: | Height: | Size: 407 KiB |