删除试卷、问卷模块代码

This commit is contained in:
caishi 2020-05-09 15:04:41 +08:00
parent e5927913f8
commit 6932fe697c
70 changed files with 619 additions and 28266 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,89 +0,0 @@
import React,{ Component } from "react";
import {Tooltip, Modal, Input } from 'antd'
import moment from 'moment'
import { getUrl, WordsBtn } from 'educoder'
import axios from 'axios'
class AddDirModal extends Component{
constructor(props){
super(props);
this.state = {
}
}
onInput = (e) => {
this.setState({
inputValue: e.target.value
})
}
open = () => {
this.setState({ visible: true, inputValue: '' })
}
onSave = () => {
let coursesId = this.props.match.params.coursesId;
const url = `/courses/${coursesId}/boards.json`
let { inputValue } = this.state;
if (!inputValue) {
this.setState({ errorMsg: '名称不能为空'})
return;
}
if (inputValue.length > 20) {
this.setState({ errorMsg: '名称不能超过20个字'})
return;
}
this.setState({ errorMsg: ''})
axios.post(url,{
name: inputValue
}).then((response)=>{
if (response.data.status == 0) {
this.onCancel()
this.props.showNotification('添加成功')
this.props.addSuccess && this.props.addSuccess()
}
}).catch((error)=>{
console.log(error)
})
}
onCancel = () => {
this.setState({ visible: false, inputValue: '', errorMsg: '' })
}
render(){
let { inputValue, visible, errorMsg } = this.state;
const { title } = this.props;
return(
<Modal
keyboard={false}
title={title}
visible={visible}
className={"Navmodal"}
closable={false}
footer={null}
destroyOnClose={true}
centered={true}
>
<div className="df">
<div className={"fl mt5"}>{this.props.label}</div>
<Input placeholder={this.props.inputPlaceholder || '示例讨论小组A'}
className={"input-flex-35 greyInput fl"}
maxLength="60"
value={inputValue}
onInput={this.onInput}
/>
</div>
{errorMsg && <span style={{color: 'red', marginTop: '2px', display: 'inline-block' }}>{errorMsg}</span>}
{/* {this.state.NavmodalValuetype===true?<span className={"color-red"}>
{this.state.NavmodalValues}
</span>:""} */}
{/* this.state.NavmodalValuetype===true?"clearfix mt20 edu-txt-center": */}
<div className={"clearfix mt50 edu-txt-center"}>
<a className="task-btn mr30" onClick={this.onCancel}>取消</a>
<a className="task-btn task-btn-orange" onClick={this.onSave}>确定</a>
</div>
</Modal>
)
}
}
export default AddDirModal;

View File

@ -1,112 +0,0 @@
import React, { Component } from "react";
import { Tooltip } from 'antd'
import moment from 'moment'
import { getUrl, WordsBtn, ConditionToolTip } from 'educoder'
import './boardsListItem.css';
class BoardsListItem extends Component {
constructor(props) {
super(props);
this.state = {
}
}
onTitleClick = (discussMessage) => {
if (this.props.checkIfLogin() === false) {
this.props.showLoginDialog()
return
}
const isAdminOrStudent = this.props.isAdminOrStudent();
if (!isAdminOrStudent && discussMessage.is_public == false) {
// 没有权限访问
return;
}
const cid = this.props.match.params.coursesId
const board_id = this.props.match.params.boardId
this.props.toDetailPage(cid, board_id, discussMessage.id)
}
render() {
const isAdmin = this.props.isAdmin()
const isAdminOrStudent = this.props.isAdminOrStudent()
const { checkBox, discussMessage, onSticky, onItemClick, current_user } = this.props;
if (!discussMessage || !discussMessage.author) {
return '';
}
let canNotLink = !isAdminOrStudent && discussMessage.is_public == false
return (
<div className="panel-inner-fourm boardsList">
<style>{`
.boardsList .panel-list-img {
width: 50px;
height: 50px;
}
`}</style>
{checkBox}
<a href={`/users/${discussMessage.author.login}`} alt="用户" style={{ "width": "50px", "height": "50px", "display": "block", margin: "0 10px" }}>
<img
alt="1?1529221779" className="panel-list-img mr15" height="50"
src={`${getUrl()}/images/${discussMessage.author.image_url}`} width="50"
></img>
</a>
<div className="clearfix ds pr pt5 contentSection" onClick={() => onItemClick(discussMessage)}>
<h6>
{canNotLink ? <span className="fl mt3 font-16 font-bd color-dark maxwidth580 pointer" title={canNotLink ? "私有属性,非课堂成员不能访问" : `${discussMessage.subject}`}>{discussMessage.subject}</span> : <a className="panel-list-title hide fl mt5 color-dark font-bd pointer"
style={{ fontWeight: 'bold', maxWidth: '700px' }}
title={discussMessage.subject}
onClick={canNotLink ? () => { } : () => this.onTitleClick(discussMessage)}
>{discussMessage.subject.length>=30?discussMessage.subject.slice(0,30)+"...":discussMessage.subject}</a>}
{!!discussMessage.sticky && <span className="btn-cir btn-cir-red fl mt5 ml5">置顶</span>}
{
discussMessage.is_public == false ? (<Tooltip title={'私有属性,非课堂成员不能访问'} placement="bottom">
<i className="iconfont icon-guansuo color-grey-c ml10 font-16 fl mt4"></i>
</Tooltip>) : ""
}
</h6>
<div className="fr">
{(isAdmin || discussMessage.author.login == current_user.login) &&
<WordsBtn style="blue" className="fr font-16 ml28"
onClick={(e) => { this.props.toEditPage(this.props.match.params.coursesId, this.props.match.params.boardId, discussMessage.id) }}>编辑</WordsBtn>}
{isAdmin && <WordsBtn style="blue" className="fr font-16 ml28"
onClick={(e) => { onSticky(discussMessage); e.cancelBubble = true; e.stopPropagation(); }}>
{discussMessage.sticky ? '取消置顶' : '置顶'}</WordsBtn>}
{canNotLink ? "" : <WordsBtn style="blue" className="font-16 fr " onClick={canNotLink ? () => { } : () => this.onTitleClick(discussMessage)}>查看详情</WordsBtn>}
</div>
<div className="cl"></div>
<p className="color-grey panel-lightgrey mt18 fl">
<span className="mr50">
<a href={`/users/${discussMessage.author.login}`} className="panel-name-small hide fl mr15 mr30 color-grey3 font-14">{discussMessage.author.name}</a>
{discussMessage.total_replies_count != 0 && <span className="mr15 color-grey9 font-14">{discussMessage.total_replies_count} 回复</span>}
{discussMessage.praises_count != 0 && <span className="mr15 color-grey9 font-14">{discussMessage.praises_count} 点赞</span>}
{discussMessage.visits != 0 && <span className="mr15 color-grey9 font-14">{discussMessage.visits} 浏览</span>}
<span className="mr15 color-light-grey-C font-14">{moment(discussMessage.created_on).fromNow()} </span>
</span>
</p>
{
discussMessage.category_name &&
<div className={'directory_style'}>
<ConditionToolTip title={discussMessage.category_name} condition={discussMessage.category_name}>
{<div className=" color-grey9 task-hide fr"
style={{ "maxWidth": "216px" }}
title={discussMessage.category_name}>
所属目录{discussMessage.category_name}
</div>
}
</ConditionToolTip>
</div>
}
</div>
</div>
)
}
}
export default BoardsListItem;

View File

@ -1,518 +0,0 @@
import React, { Component } from "react";
import {
Form, Input, InputNumber, Switch, Radio,
Slider, Button, Upload, Icon, Rate, Checkbox, message,
Row, Col, Select, Modal, Divider, Tooltip
} from 'antd';
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import axios from 'axios'
import './board.css'
import "../common/formCommon.css"
import AddDirModal from './AddDirModal'
import { RouteHOC } from './common.js'
import CBreadcrumb from '../common/CBreadcrumb'
import { getUploadActionUrl, bytesToSize, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll } from 'educoder';
import styled from "styled-components";
const SubBtn = styled(Button)`
display: block;
border: 1px solid #4CACFF;
background-color: #4CACFF;
color: #fff !important;
width: 120px;
text-align: center;
line-height: 40px;
border-radius: 2px;
width: 130px;
height: 40px;
background: rgba(76, 172, 255, 1);
border-radius: 4px;
font-size: 16px;
font-family: MicrosoftYaHei;
font-weight: 400;
color: rgba(255, 255, 255, 1);
`;
const confirm = Modal.confirm;
const $ = window.$
const { Option } = Select;
const MAX_TITLE_LENGTH = 60
// https://lanhuapp.com/web/#/item/project/board/detail?pid=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&project_id=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&image_id=71072679-b925-4824-aceb-4649535e3652
class BoardsNew extends Component {
constructor(props) {
super(props);
this.mdRef = React.createRef();
this.state = {
fileList: [],
boards: [],
title_num: 0,
email_notify: false,
isemail_notify: false,
isemail_notifys: false
}
}
addSuccess = () => {
this.fetchBoards()
}
fetchBoards = () => {
const isEdit = this.isEdit
const boardId = this.props.match.params.boardId
const boardsUrl = `/courses/board_list.json?board_id=${boardId}`
axios.get(boardsUrl, {})
.then((response) => {
if (response.data.status == 0) {
this.setState({
boards: response.data.data.boards || [],
boardsdata: response.data.data,
course_id: response.data.data.course_id
})
if (!isEdit) {
response.data.data.boards.forEach(board => {
if (board.id == boardId) {
this.setState({ board_name: board.name })
}
})
// board_name
}
}
})
.catch(function (error) {
console.log(error);
});
}
componentDidMount = () => {
const topicId = this.props.match.params.topicId
const isEdit = !!topicId
this.isEdit = isEdit
const boardId = this.props.match.params.boardId
this.fetchBoards()
if (isEdit) {
const url = `/messages/${topicId}.json`
axios.get(url, {
})
.then((response) => {
if (response.data.status == 0) {
const { id, data } = response.data;
if (data) {
this.editTopic = data;
this.props.form.setFieldsValue({
sticky: !!data.sticky,
content: data.content,
subject: data.subject,
select_board_id: data.board_id // TODO 没返回给前端
});
this.mdRef.current.setValue(data.content)
const _fileList = data.attachments.map(item => {
return {
id: item.id,
uid: item.id,
name: appendFileSizeToUploadFile(item),
url: item.url,
status: 'done'
}
})
this.setState({ fileList: _fileList, board_name: data.board_name, title_num: parseInt(data.subject.length), isemail_notifys: response.data.data.email_notify })
}
}
})
.catch(function (error) {
console.log(error);
});
} else {
const boardId = this.props.match.params.boardId
this.props.form.setFieldsValue({
select_board_id: parseInt(boardId)
});
}
}
handleSubmit = (e) => {
e.preventDefault();
const cid = this.state.course_id
const boardId = this.props.match.params.boardId
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
if (this.isEdit == true) {
const editTopic = this.editTopic
const editUrl = `/messages/${editTopic.id}.json`
let attachment_ids = undefined
if (this.state.fileList) {
attachment_ids = this.state.fileList.map(item => {
return item.response ? item.response.id : item.id
})
}
axios.put(editUrl, {
subject: values.subject,
select_board_id: values.select_board_id,
content: values.content,
sticky: values.sticky,
email_notify: this.state.isemail_notify,
attachment_ids,
})
.then((response) => {
if (response.data.status == 0) {
const { id } = response.data;
console.log('--- success')
this.props.toDetailPage(cid, values.select_board_id, editTopic.id)
}
})
.catch(function (error) {
console.log(error);
});
} else {
const url = `/boards/${boardId}/messages.json`
let attachment_ids = undefined
if (this.state.fileList) {
attachment_ids = this.state.fileList.map(item => {
return item.response.id
})
}
axios.post(url, {
...values,
email_notify: this.state.isemail_notify,
course_id: cid,
attachment_ids,
})
.then((response) => {
if (response.data.data && response.data.status == 0) {
const { id } = response.data.data;
if (id) {
console.log('--- success')
this.props.toDetailPage(cid, values.select_board_id, id)
}
}
})
.catch(function (error) {
console.log(error);
});
}
} else {
$("html").animate({ scrollTop: $('html').scrollTop() - 100 })
}
});
}
// 附件相关 START
handleChange = (info) => {
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
let fileList = info.fileList;
this.setState({ fileList: appendFileSizeToUploadFileAll(fileList) });
}
}
onAttachmentRemove = (file) => {
if (!file.percent || file.percent == 100) {
this.props.confirm({
// title: '确定要删除这个附件吗?',
content: '是否确认删除?',
okText: '确定',
cancelText: '取消',
// content: 'Some descriptions',
onOk: () => {
this.deleteAttachment(file)
},
onCancel() {
console.log('Cancel');
},
});
return false;
}
}
deleteAttachment = (file) => {
// 初次上传不能直接取uid
const url = `/attachments/${file.response ? file.response.id : file.uid}.json`
axios.delete(url, {
})
.then((response) => {
if (response.data) {
const { status } = response.data;
if (status == 0) {
console.log('--- success')
this.setState((state) => {
const index = state.fileList.indexOf(file);
const newFileList = state.fileList.slice();
newFileList.splice(index, 1);
return {
fileList: newFileList,
};
});
}
}
})
.catch(function (error) {
console.log(error);
});
}
// 附件相关 ------------ END
changeTitle = (e) => {
console.log(e.target.value.length);
this.setState({
title_num: parseInt(e.target.value.length)
})
}
goBack = () => {
// this.props.history.goBack()
const courseId = this.props.match.params.coursesId;
const boardId = this.props.match.params.boardId
this.props.toListPage(courseId, boardId)
}
setemailchange = (e) => {
this.setState({
isemail_notify: e.target.checked
})
}
render() {
let { addGroup, fileList, course_id, title_num } = this.state;
const { getFieldDecorator } = this.props.form;
const { current_user } = this.props
const formItemLayout = {
labelCol: {
xs: { span: 24 },
// sm: { span: 8 },
sm: { span: 24 },
},
wrapperCol: {
xs: { span: 24 },
// sm: { span: 16 },
sm: { span: 24 },
},
};
const uploadProps = {
width: 600,
fileList,
multiple: true,
// https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false,
action: `${getUploadActionUrl()}`,
onChange: this.handleChange,
onRemove: this.onAttachmentRemove,
beforeUpload: (file) => {
console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) {
this.props.showNotification('文件大小必须小于150MB!');
}
return isLt150M;
},
};
const isAdmin = this.props.isAdmin()
const courseId = this.props.match.params.coursesId;
const boardId = this.props.match.params.boardId
const isCourseEnd = this.props.isCourseEnd();
document.title = this.props.coursedata && this.props.coursedata.name;
// console.log(this.state)
return (
<div className="newMain ">
<AddDirModal {...this.props}
title="新建目录"
label="目录名称"
ref="addDirModal"
addSuccess={this.addSuccess}
></AddDirModal>
<style>{`
.courseForm .ant-form {
}
.courseForm .formBlock {
padding: 20px 30px 30px 30px;
border-bottom: 1px solid #EDEDED;
margin-bottom: 0px;
background: #fff;
}
.courseForm .noBorder {
border-bottom: none;
}
`}</style>
<div className="edu-class-container edu-position courseForm">
<CBreadcrumb items={[
{ to: current_user && current_user.first_category_url, name: this.props.coursedata ? this.props.coursedata.name : '' },
{ to: `/classrooms/${courseId}/boards/${boardId}`, name: this.state.board_name },
{ name: this.isEdit ? '帖子编辑' : '帖子新建' }
]}></CBreadcrumb>
<p className="clearfix mt20 mb20">
<span className="fl font-24 color-grey-3">{this.isEdit ? "编辑" : "新建"}帖子</span>
<a className="color-grey-6 fr font-16 mr2"
onClick={this.goBack}>
返回
</a>
</p>
{/* notRequired */}
<Form {...formItemLayout} onSubmit={this.handleSubmit}>
<div className="formBlock" style={{ paddingBottom: '0px', position: 'relative' }}>
{this.state.boardsdata && this.state.boardsdata.email_notify === true ? this.props.isAdminOrTeacher() === true ? <Tooltip placement="bottom" title={this.state.isemail_notifys === true ? "邮件只能发送一次" : ""}><span className={"setemail fr mr70 setemailposition"}>
<Checkbox onChange={this.setemailchange} checked={this.state.isemail_notifys === true ? this.state.isemail_notifys : this.state.isemail_notify} disabled={this.state.isemail_notifys}>发送邮件提醒</Checkbox>
</span></Tooltip> : "" : ""}
{isAdmin &&
<React.Fragment>
{getFieldDecorator('sticky', {
valuePropName: 'checked',
})(
isAdmin && <Checkbox style={{
right: '22px',
top: '17px',
position: 'absolute'
}}>置顶</Checkbox>
)}
{/* checkbox 有个边距样式 .ant-checkbox-wrapper + span, */}
<span style={{ "padding-left": 0, "padding-right": 0 }}></span>
</React.Fragment>
}
<style>
{
`
.yslboardsnewinputaddonAfter .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Form.Item
label="标题"
className="topicTitle "
>
{getFieldDecorator('subject', {
rules: [{
required: true, message: '请输入标题',
}, {
max: MAX_TITLE_LENGTH, message: `最大限制为${MAX_TITLE_LENGTH}个字符`,
}],
})(
<Input placeholder={`请输入帖子标题,最大限制${MAX_TITLE_LENGTH}个字符 `} className="searchViewAfter yslboardsnewinputaddonAfter" maxLength={MAX_TITLE_LENGTH}
onInput={this.changeTitle} addonAfter={`${title_num}/${MAX_TITLE_LENGTH}`} />
)}
</Form.Item>
<Form.Item
label=""
style={{ display: 'inline-block' }}
>
{getFieldDecorator('select_board_id', {
// initialValue: '3779',
})(
<Select style={{ width: 230 }}
dropdownRender={menu => (
<div>
{menu}
{
isAdmin && !isCourseEnd &&
<React.Fragment>
<Divider style={{ margin: '4px 0' }} />
<div style={{ padding: '8px', cursor: 'pointer' }} onMouseDown={() => this.refs['addDirModal'].open()}>
<Icon type="plus" /> 新建目录
</div>
</React.Fragment>
}
</div>
)}
>
{this.state.boards.map(item => {
return (
<Option value={item.id}>{item.name}</Option>
)
})}
</Select>
)}
</Form.Item>
{/* { isAdmin && <Form.Item
label=""
style={{ display: 'inline-block', marginLeft: "14px" }}
>
{getFieldDecorator('sticky', {
})(
<Checkbox>置顶</Checkbox>
)}
</Form.Item> } */}
</div>
<style>{`
.courseMessageMD {
width: 1140px;
}
.uploadBtn.ant-btn {
border: none;
color: #4CACFF;
box-shadow: none;
background: transparent;
padding: 0 6px;
}
.upload_1 .ant-upload-list {
width: 350px;
}
`}</style>
<div className="formBlock noBorder">
<Form.Item
label="内容"
className="mdInForm"
>
{getFieldDecorator('content', {
rules: [{
required: true, message: '请输入帖子内容',
}, {
max: 10000, message: '最大限制为10000个字符',
}],
})(
<TPMMDEditor ref={this.mdRef} placeholder={'请在此输入帖子详情最大限制为10000个字符'}
mdID={'courseMessageMD'} initValue={this.editTopic ? this.editTopic.content : ''} className="courseMessageMD"></TPMMDEditor>
)}
</Form.Item>
<Upload {...uploadProps} className="upload_1">
<Button className="uploadBtn">
<Icon type="upload" /> 上传附件
</Button>
(单个文件150M以内)
</Upload>
</div>
<Form.Item>
<div className="clearfix mt30 mb30">
<SubBtn type="primary" htmlType="submit" className="fl mr20">提交</SubBtn>
<a className="defalutCancelbtn fl"
onClick={() => this.isEdit ?
this.props.toDetailPage(Object.assign({}, this.props.match.params, { 'coursesId': course_id })) :
this.props.toListPage(Object.assign({}, this.props.match.params, { 'coursesId': course_id }))}>取消</ a>
</div>
</Form.Item>
</Form>
</div>
</div>
)
}
}
const WrappedBoardsNew = Form.create({ name: 'boardsNew' })(BoardsNew);
export default RouteHOC()(WrappedBoardsNew);

View File

@ -1,202 +0,0 @@
import React,{ Component } from "react";
import {
Form, Input, InputNumber, Switch, Radio,
Slider, Button, Upload, Icon, Rate, Checkbox,
Row, Col, Select
} from 'antd';
const $ = window.$
const { Option } = Select;
// 红点在输入框前面的版本
// https://lanhuapp.com/web/#/item/project/board/detail?pid=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&project_id=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&image_id=71072679-b925-4824-aceb-4649535e3652
class BoardsNew extends Component{
constructor(props){
super(props);
this.state = {
}
}
compareToFirstPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && value !== form.getFieldValue('password')) {
callback('Two passwords that you enter is inconsistent!');
} else {
callback();
}
}
validateToNextPassword = (rule, value, callback) => {
const form = this.props.form;
if (value && this.state.confirmDirty) {
form.validateFields(['confirm'], { force: true });
}
callback();
}
handleConfirmBlur = (e) => {
const value = e.target.value;
this.setState({ confirmDirty: this.state.confirmDirty || !!value });
}
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
} else {
$("html").animate({ scrollTop: $('html').scrollTop() - 100 })
}
});
}
render() {
let { addGroup } = this.state;
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
// sm: { span: 8 },
sm: { span: 24 },
},
wrapperCol: {
xs: { span: 24 },
// sm: { span: 16 },
sm: { span: 24 },
},
};
const tailFormItemLayout = {
wrapperCol: {
xs: {
span: 24,
offset: 0,
},
sm: {
span: 16,
offset: 8,
},
},
};
return(
<div className="newMain ">
<style>{`
.edu-class-container {
width: 1200px;
margin: 10px auto 20px;
}
/* form 样式 --------------------------------------------- */
/* 不知道被哪个样式影响,这里需要重置 */
.ant-input:focus {
border-color: #40a9ff;
}
@media (min-width: 576px) {
.ant-col-sm-24 {
text-align: left;
}
}
.ant-form-item-control-wrapper.ant-col-xs-24.ant-col-sm-24 {
margin-left: 2px;
}
/*必填*/
.ant-form-item-required::before {
display: none;
}
.ant-form-item-control-wrapper.ant-col-xs-24.ant-col-sm-24::before {
display: inline-block;
margin-right: 8px;
color: #f5222d;
font-size: 14px;
font-family: SimSun, sans-serif;
line-height: 1;
content: '*';
}
.ant-form-item-control {
display: inline-block;
}
/* form 样式 --------------------------------------------- */
.topicTitle.ant-form-item {
margin-bottom: 8px;
}
/* errorInline ----------- */
/* 这里需要指定form组件的宽度 style={{ width: 270 }} */
.errorInline .ant-form-item-children input {
width: auto
}
.errorInline .ant-form-explain {
display: inline;
margin-left: 10px;
}
/* errorInline ----------- */
`}</style>
<div className="edu-class-container edu-position">
<Form {...formItemLayout} onSubmit={this.handleSubmit}>
<Form.Item
label="E-mail"
className="topicTitle errorInline"
>
{getFieldDecorator('email', {
rules: [{
type: 'email', message: 'The input is not valid E-mail!',
}, {
required: true, message: 'Please input your E-mail!',
}],
})(
<Input style={{ width: 270 }} />
)}
</Form.Item>
<Form.Item
label=""
>
{getFieldDecorator('prefix', {
initialValue: '86',
})(
<Select style={{ width: 270 }}>
<Option value="86">+86</Option>
<Option value="87">+87</Option>
</Select>
)}
</Form.Item>
<Form.Item
label="Password"
>
{getFieldDecorator('password', {
rules: [{
required: true, message: 'Please input your password!',
}, {
validator: this.validateToNextPassword,
}],
})(
<Input type="password" />
)}
</Form.Item>
<Form.Item
label="Confirm Password"
>
{getFieldDecorator('confirm', {
rules: [{
required: true, message: 'Please confirm your password!',
}, {
validator: this.compareToFirstPassword,
}],
})(
<Input type="password" onBlur={this.handleConfirmBlur} />
)}
</Form.Item>
<Form.Item {...tailFormItemLayout}>
<Button type="primary" htmlType="submit">Register</Button>
</Form.Item>
</Form>
</div>
</div>
)
}
}
const WrappedBoardsNew = Form.create({ name: 'boardsNew' })(BoardsNew);
export default WrappedBoardsNew;

View File

@ -1,15 +0,0 @@
.edu-class-container {
width: 1200px;
margin: 10px auto 20px;
}
#forum_index_list {
margin-top: 90px;
margin-bottom: 320px;
}
#yslforum_index_list {
margin-top: 20px;
margin-bottom: 320px;
}
.uploadBtn {
margin-left: 0px;
}

View File

@ -1,746 +0,0 @@
import React, { Component } from 'react';
import axios from 'axios'
import moment from 'moment'
import Comments from '../../comment/Comments'
import { ImageLayerOfCommentHOC } from '../../page/layers/ImageLayerOfCommentHOC'
import MemoDetailMDEditor from '../../forums/MemoDetailMDEditor'
import { RouteHOC } from './common.js'
import '../../forums/RightSection.css'
import './TopicDetail.css'
import '../common/courseMessage.css'
import { Pagination, Tooltip, Button } from 'antd'
import { bytesToSize, ConditionToolTip, markdownToHTML, MarkdownToHtml, setImagesUrl } from 'educoder'
import SendToCourseModal from '../coursesPublic/modal/SendToCourseModal'
import CBreadcrumb from '../common/CBreadcrumb'
import {
generateComments, generateChildComments, _findById, handleContentBeforeCreateNew, addNewComment
, addSecondLevelComment, NEED_TO_WRITE_CONTENT, handleContentBeforeCreateSecondLevelComment
, handleDeleteComment, handleCommentPraise, handleHiddenComment
} from '../common/CommentsHelper'
const $ = window.$
const REPLY_PAGE_COUNT = 10;
let setTime;
function urlStringify(params) {
let noParams = true;
let paramsUrl = '';
for (let key in params) {
noParams = false;
paramsUrl += `${key}=${params[key]}&`
}
if (noParams) {
return '';
}
paramsUrl = paramsUrl.substring(0, paramsUrl.length - 1);
return paramsUrl;
}
class TopicDetail extends Component {
constructor(props) {
super(props)
this.state = {
memo: {},
memoLoading: true,
hasMoreComments: false,
pageCount: 1,
comments: [],
goldRewardDialogOpen: false,
author: undefined,
commentstype: false
}
}
componentDidMount() {
window.$("html,body").animate({ "scrollTop": 0 })
const topicId = this.props.match.params.topicId
const bid = this.props.match.params.boardId
const memoUrl = `/messages/${topicId}.json`;
this.setState({
memoLoading: true
})
axios.get(memoUrl, {
})
.then((response) => {
if (response.data.status === -1) {
setTimeout(() => {
this.props.showNotification('帖子不存在!')
}, 300)
// this.props.toListPage(response.data.data.course_id, bid)
return;
} else {
this.setState({
memo: Object.assign({}, {
...response.data.data,
replies_count: response.data.data.total_replies_count
}, { ...this.state.memo }),
author: response.data.data.author
}, () => {
})
// const { memo_replies, memo } = response.data;
// let hasMoreComments = false;
// if (memo_replies && memo_replies.length === 10 && memo.total_replies_count > 10) {
// // 遍历一遍,计算下是否还有评论未加载
// let totalCount = 10;
// memo_replies.forEach(item=>{
// totalCount += item.children.length
// })
// if (totalCount < memo.total_replies_count) {
// hasMoreComments = true;
// }
// }
// this.setState({
// hasMoreComments,
// pageCount: 1,
// comments: memo_replies
// })
// delete response.data.memo_replies;
// this.setState(response.data)
// const user = response.data.current_user;
// user.tidding_count = response.data.tidding_count;
// this.props.initCommonState(user)
}
this.setState({
memoLoading: false
})
}).catch((error) => {
console.log(error)
})
this.fetchReplies()
$('body>#root').on('onMemoDelete', (event) => {
// const val = $('body>#root').data('onMemoDelete')
const val = window.onMemoDelete;
this.onMemoDelete(JSON.parse(decodeURIComponent(val)))
})
}
onPaginationChange = (pageCount) => {
this.setState({ pageCount }, () => {
this.fetchReplies()
})
}
componentWillUnmount() {
$('body>#root').off('onMemoDelete')
}
onMemoDelete(memo) {
const deleteUrl = `/commons/delete.json`;
// 获取memo list
axios.delete(deleteUrl, {
data: {
object_id: memo.id,
object_type: 'message'
}
})
.then((response) => {
const status = response.data.status
if (status === 0) {
this.props.showNotification('删除成功');
const props = Object.assign({}, this.props, {})
this.props.toListPage(Object.assign({}, this.props.match.params, { 'coursesId': this.state.memo.course_id }))
} else if (status === -1) {
this.props.showNotification('帖子已被删除');
this.props.history.push(`/forums`)
}
}).catch((error) => {
console.log(error)
})
}
componentDidUpdate(prevProps, prevState, snapshot) {
// if (this.state.memo && this.state.memo.content
// && (!prevProps.memo || prevProps.memo.content != this.state.memo.content) ) {
if (this.state.memo && this.state.memo.content && prevState.memoLoading === true && this.state.memoLoading === false) {
// md渲染content等xhr执行完即memoLoading变化memo.content更新后初始化md
setTimeout(() => {
// var shixunDescr = window.editormd.markdownToHTML("memo_content_editorMd", {
// htmlDecode: "style,script,iframe", // you can filter tags decode
// taskList: true,
// tex: true, // 默认不解析
// flowChart: true, // 默认不解析
// sequenceDiagram: true // 默认不解析
// });
}, 200)
}
}
clickPraise() {
const { memo } = this.state;
// const url = `/api/v1/discusses/${memo.id}/plus`;
const url = memo.user_praise ? '/praise_tread/unlike.json' : `/praise_tread/like.json`;
const _method = memo.user_praise ? axios.delete : axios.post
let _data = {
object_id: memo.id,
object_type: 'message', //Discuss
}
if (memo.user_praise) {
_data = {
data: _data
}
}
_method(url, {
..._data
},
{
}
).then((response) => {
const newMemo = Object.assign({}, this.state.memo)
newMemo.praises_count = newMemo.user_praise ? newMemo.praises_count - 1 : newMemo.praises_count + 1
newMemo.total_praises_count = newMemo.user_praise ? newMemo.total_praises_count - 1 : newMemo.total_praises_count + 1
newMemo.user_praise = !newMemo.user_praise
this.setState({ memo: newMemo })
}).catch((error) => {
console.log(error)
})
}
renderAttachment() {
const { memo } = this.state;
const attachments = []
memo.attachments.forEach((item, index) => {
const ar = item.url.split('/')
const fileName = item.title || ar[ar.length - 1]
let filesize = 0
if (item.filesize) {
filesize = item.filesize
// filesize = bytesToSize(item.filesize)
}
attachments.push(
// <p className="clearfix" key={index} >
// <a href={item.url} className="color-green clearfix notefileDownload">
// <i className="iconfont icon-fujian color-green ml5 fl"></i>
// {fileName && <ConditionToolTip title={fileName} condition={fileName.length > 30 }>
// <span className="fl task-hide upload_item" style={{ color: '#333'}}>{fileName}</span>
// </ConditionToolTip>}
// <span className="fl" style={{ color: '#999', marginLeft: '6px'}}>{filesize? ` ${filesize.replace(' ', '')}` : ''}</span>
// </a>
// </p>
<div className="color-grey df" key={index}>
<a className="color-grey ">
<i className="font-14 color-green iconfont icon-fujian mr8" aria-hidden="true"></i>
</a>
{/* {fileName && <ConditionToolTip title={fileName} condition={fileName.length > 30 }> </ConditionToolTip>} */}
<a href={item.url} title={fileName.length > 30 ? fileName : ''}
className="mr12 color9B9B overflowHidden1" length="58" style={{ maxWidth: '480px' }}>
{fileName}
</a>
<span className="color656565 mt2 color-grey-6 font-12 mr8">{item.filesize}</span>
</div>
)
})
return attachments;
}
// ------------------------------------------------------------------------------------------- comments START
// ------------------------------------------------------------------------------------------- comments START
transformReply = (reply, children = []) => {
const isAdmin = this.props.isAdmin()
const isSuperAdmin = this.props.isSuperAdmin()
return {
isSuperAdmin: isSuperAdmin,
admin: isAdmin, //
permission: true, //
children: children,
child_message_count: reply.total_count,
hidden: reply.is_hidden,
id: reply.id,
image_url: reply.author.image_url,
reward: null, //
time: moment(reply.created_on).fromNow(),
user_id: reply.author.id,
user_login: reply.author.login,
user_praise: reply.liked,
username: reply.author.name,
content: reply.content,
praise_count: reply.praises_count
}
}
fetchReplies = () => {
const topicId = this.props.match.params.topicId
const url = `/messages/${topicId}/reply_list.json?page=${this.state.pageCount}&page_size=${REPLY_PAGE_COUNT}`
axios.get(url, {
})
.then((response) => {
const { replies, liked, total_replies_count, total_count } = response.data.data
const memo = Object.assign({}, this.state.memo)
memo.user_praise = liked
memo.total_replies_count = total_replies_count;
this.setState({
memo,
comments: generateComments(replies, this.transformReply, 'replies'),
// : this.state.comments.concat(comments),
total_count: total_count
})
}).catch((error) => {
console.log(error)
})
}
_getUser() {
const { current_user } = this.props;
current_user.user_url = `/users/${current_user.login}`;
return current_user;
}
_findById = _findById
replyComment = (commentContent, id, editor) => {
const { showNotification } = this.props;
// if (!commentContent || commentContent.length === 0) {
// showNotification(NEED_TO_WRITE_CONTENT)
// return;
// }
if (this.state.memo.id === id) { // 回复帖子
this.createNewComment(commentContent, id, editor);
return;
}
const url = `/messages/${id}/reply.json`;
const { comments } = this.state;
const user = this._getUser();
/*
移除末尾的空行
.replace(/(\n<p>\n\t<br \/>\n<\/p>)*$/g,'');
*/
commentContent = handleContentBeforeCreateSecondLevelComment(commentContent)
if (!commentContent) {
this.props.showNotification('不能为空')
return;
}
axios.post(url, {
content: commentContent
},
{
}
).then((response) => {
if (response.data.data.id) {
let newId = response.data.data.id;
const commentIndex = this._findById(id, comments);
const parentComment = comments[commentIndex]
this.setState({
// runTesting: false,
comments: addSecondLevelComment(comments, parentComment, commentIndex, newId, commentContent, user, editor)
}, () => {
// keditor代码美化
editor.html && window.prettyPrint()
})
const newMemo2 = Object.assign({}, this.state.memo);
newMemo2.total_replies_count = newMemo2.total_replies_count + 1;
this.setState({
memo: newMemo2
})
}
}).catch((error) => {
console.log(error)
})
}
// 公共接口 --- 删除回复
deleteComment = (parrentComment, childCommentId) => {
handleDeleteComment(this, parrentComment, childCommentId, 'message')
}
// 公共接口 --- 回复点赞
commentPraise = (discussId) => {
handleCommentPraise(this, discussId, 'message', (old_user_praise) => {
const newMemo2 = Object.assign({}, this.state.memo);
newMemo2.total_praises_count = old_user_praise
? newMemo2.total_praises_count - 1 : newMemo2.total_praises_count + 1;
this.setState({
memo: newMemo2
})
})
}
// 公共接口 --- 隐藏回复
hiddenComment = (item, childCommentId) => {
handleHiddenComment(this, item, childCommentId, 'message')
}
createNewComment = (commentContent, id, editor) => {
let content = handleContentBeforeCreateNew(commentContent);
const { memo } = this.props;
const url = `/messages/${id}/reply.json`;
// const url = `/api/v1/memos/${memo.id}/reply`;
let { comments } = this.state;
axios.post(url, {
content: content
},
{
}
).then((response) => {
if (response.data.status === -1) {
console.error('服务端异常')
return;
}
// this.props.showNotification('帖子发表成功')
if (response.data) {
const _id = response.data.data.id;
// ke
editor.html && editor.html('');
editor.afterBlur && editor.afterBlur()
// md
editor.setValue && editor.setValue('')
const user = this._getUser();
this.setState({
comments: addNewComment(comments, _id, content, user, this.props.isSuperAdmin(), this)
})
const newMemo2 = Object.assign({}, this.state.memo);
newMemo2.total_replies_count = newMemo2.total_replies_count + 1;
this.setState({
memo: newMemo2
})
this.refs.editor.showEditor();
this.refs.editor.close();
}
}).catch((error) => {
console.log(error)
})
}
/**
* parent.isAllChildrenLoaded true的时候表示已经没有更多子回复了
*/
loadMoreChildComments = (parent) => {
const url = `/messages/${parent.id}/reply_list.json?page=1&page_size=500`
axios.get(url, {
})
.then((response) => {
const { replies, liked, total_replies_count } = response.data.data
// const memo = Object.assign({}, this.state.memo)
// memo.total_replies_count = total_replies_count;
this.setState({
// memo,
comments: generateChildComments(replies, this.state.comments, parent, this.transformReply)
})
}).catch((error) => {
console.log(error)
})
}
// ------------------------------------------------------------------------------------------- comments END
// ------------------------------------------------------------------------------------------- comments END
// 置顶
setTop(memo) {
// const params = {
// sticky: memo.sticky ? 0 : 1,
// }
// if (this.state.p_s_order) {
// params.order = this.state.p_s_order;
// }
// if (this.state.p_forum_id) {
// params.forum_id = this.state.p_forum_id;
// }
// let paramsUrl = urlStringify(params)
const set_top_or_down_Url = `/messages/${memo.id}/sticky_top.json`;
// 获取memo list
axios.put(set_top_or_down_Url, {
})
.then((response) => {
const status = response.data.status
if (status === 0) {
this.props.showNotification(memo.sticky ? '取消置顶成功' : '置顶成功');
memo.sticky = memo.sticky ? false : true
this.setState({
memo: Object.assign({}, memo)
})
}
}).catch((error) => {
console.log(error)
})
}
setRewardDialogVisible = (visible) => {
this.setState({
goldRewardDialogOpen: visible
})
}
showRewardDialog = () => {
this.setState({
goldRewardDialogOpen: true
})
}
// --------------------------------------------------------------------------------------------帖子獎勵 END
showCommentInput = () => {
this.refs.editor.showEditor();
}
initReply = (parent) => {
if (!parent.isAllChildrenLoaded) {
this.loadMoreChildComments(parent)
}
}
startcomments = () => {
setTime = setInterval(() => {
this.fetchReplies()
}, 5000);
this.setState({
commentstype: true
})
}
clearcomments = () => {
clearInterval(setTime);
this.setState({
commentstype: false
})
}
render() {
const { match, history } = this.props
const { recommend_shixun, current_user, author_info } = this.props;
const { memo, comments, hasMoreComments, commentstype, pageCount, total_count, author } = this.state;
const messageId = match.params.topicId
if (this.state.memoLoading || !current_user) {
return <div className="edu-back-white" id="forum_index_list"></div>
}
current_user.user_url = `/users/${current_user.login}`;
const isCurrentUserTheAuthor = current_user.login == memo.author.login
const isAdmin = this.props.isAdmin()
// TODO 图片上传地址
const courseId = this.props.match.params.coursesId;
const boardId = this.props.match.params.boardId;
const isCourseEnd = this.props.isCourseEnd();
document.title = this.props.coursedata && this.props.coursedata.name;
return (
<div className="edu-back-white edu-class-container edu-position course-message topicDetail" id="yslforum_index_list"> {/* fl with100 */}
<style>{`
.topicDetail #forum_list .return_btn.no_mr {
margin-right: 1px;
}
/* 有内容时,编辑器下方的边框*/
.topicDetail .borderBottom.commentInputs {
border-bottom: 1px solid rgb(238, 238, 238);
}
.independent {
background: rgb(250, 250, 250);
padding-bottom: 20px;
margin-bottom: 0px !important;
}
.course-message.topicDetail .panel-comment_item .comment_orig_content {
width: 1072px;
}
`}</style>
<CBreadcrumb className={'independent'} items={[
{ to: current_user && current_user.first_category_url, name: this.props.coursedata.name },
{ to: `/classrooms/${courseId}/boards/${boardId}`, name: memo.board_name },
{ name: '帖子详情' }
]}></CBreadcrumb>
<SendToCourseModal
ref="sendToCourseModal"
{...this.props}
moduleName="帖子"
seletedMessageIds={[messageId]}
></SendToCourseModal>
<div className="clearfix">
<div id="forum_list" className="forum_table mh650">
<div className="padding30 bor-bottom-greyE" style={{ paddingBottom: '20px' }}>
<div className="font-16 cdefault clearfix pr pr35">
<span className="noteDetailTitle">{memo.subject}</span>
{!!memo.sticky && <span className="btn-cir btn-cir-red ml10"
style={{ position: 'relative', bottom: '4px' }}>置顶</span>}
{!!memo.reward && <span className="color-orange font-14 ml15"
data-tip-down={`获得平台奖励金币:${memo.reward}`} >
<i className="iconfont icon-gift mr5"></i>{memo.reward}
</span>}
{/* || current_user.user_id === author_info.user_id */}
{current_user && (isAdmin || isCurrentUserTheAuthor) &&
<div className="edu-position-hidebox" style={{ position: 'absolute', right: '2px', top: '4px' }}>
<a href="javascript:void(0);"><i className="fa fa-bars font-16"></i></a>
<ul className="edu-position-hide undis">
{(isCurrentUserTheAuthor || isAdmin) &&
<li><a
onClick={() => this.props.toEditPage(Object.assign({}, this.props.match.params, { 'coursesId': this.state.memo.course_id }))}
>&nbsp;&nbsp;</a></li>}
{isAdmin &&
(memo.sticky == true ?
<li><a href="javascript:void(0);" onClick={() => this.setTop(memo)}>取消置顶</a></li>
:
<li><a href="javascript:void(0);" onClick={() => this.setTop(memo)}>&nbsp;&nbsp;</a></li>)
}
{isAdmin &&
<li><a href="javascript:void(0);" onClick={() => this.refs.sendToCourseModal.setVisible(true)}>&nbsp;&nbsp;</a></li>
}
{(isCurrentUserTheAuthor || isAdmin) && <li>
<a onClick={() =>
window.delete_confirm_box_2_react(`onMemoDelete`, '您确定要删除吗?', memo)}>
&nbsp;&nbsp;</a>
</li>
}
</ul>
</div>
}
</div>
<div className="df mt20">
<img src={setImagesUrl(`/images/${author && author.image_url}`)} className="radius mr10 mt2" width="40px" height="40px" />
<div className="flex1">
<div className="color-grey-9 lineh-20">
<span className="color-grey-3 mr20 fl" style={{ "fontWeight": "400" }}>{author && author.name}</span>
<span className="fl">{moment(memo.created_on).fromNow()} 发布</span>
</div>
<div className="color-grey-9 clearfix">
<span className="fl" style={{ marginTop: '4px' }}>
{/* { current_user.admin && <Tooltip title={ "" }>
<span className="noteDetailNum rightline cdefault" style={{padding: '0 4px', cursor: 'pointer'}}>
<i className="iconfont icon-jiangli mr5" onClick={this.showRewardDialog}></i>
</span>
</Tooltip> } */}
<Tooltip title={"浏览数"}>
<span className={`noteDetailNum `} style={{ paddingLeft: '0px' }}>
<i className="iconfont icon-liulanyan mr5"></i>
<span style={{ top: "1px", position: "relative" }}>{memo.visits || '1'}</span>
</span>
</Tooltip>
{!!memo.total_replies_count &&
<Tooltip title={"回复数"}>
<a className="noteDetailNum">
<i className="iconfont icon-huifu1 mr5" onClick={this.showCommentInput}></i>
<span style={{ top: "2px", position: "relative" }}>{memo.total_replies_count}</span>
</a>
</Tooltip>
}
{!!memo.total_praises_count &&
<Tooltip title={"点赞数"}>
<span className={`noteDetailNum `} style={{}}>
<i className="iconfont icon-dianzan-xian mr5"></i>
<span style={{ top: "2px", position: "relative" }}>{memo.total_praises_count}</span>
</span>
</Tooltip>
}
</span>
<div className="fr">
{/* || current_user.user_id === author_info.user_id */}
<a className={`task-hide fr return_btn color-grey-6 ${current_user && (isAdmin
) ? '' : 'no_mr'} `} onClick={() => this.props.toListPage(Object.assign({}, this.props.match.params, { 'coursesId': this.state.memo.course_id }))} >
返回
</a>
</div>
</div>
</div>
</div>
</div>
<div className="padding30 memoContent new_li" style={{ paddingBottom: '10px' }}>
{/* <MarkdownToHtml content={memo.content}></MarkdownToHtml> */}
{memo.is_md == true ?
<MarkdownToHtml content={memo.content}></MarkdownToHtml>
:
<div dangerouslySetInnerHTML={{ __html: memo.content }}></div>
}
</div>
<div className="padding30 bor-bottom-greyE" style={{ paddingTop: '2px' }}>
<div className="mt10 mb20">
{/* ${memo.user_praise ? '' : ''} */}
<Tooltip title={`${memo.liked ? '取消点赞' : '点赞'}`}>
<p className={`noteDetailPoint ${memo.user_praise ? 'Pointed' : ''}`} onClick={() => { this.clickPraise() }} >
<i className="iconfont icon-dianzan"></i><br />
<span>{memo.praises_count}</span>
</p>
</Tooltip>
</div>
{memo.attachments && !!memo.attachments.length &&
<div>
{this.renderAttachment()}
</div>
}
</div>
{!isCourseEnd && <MemoDetailMDEditor ref="editor" memo={memo} usingMockInput={true} placeholder="说点什么"
{...this.props}
height={160} showError={true} buttonText={'发表'} className={comments && comments.length && 'borderBottom'}></MemoDetailMDEditor>}
{/* onClick={ this.createNewComment }
enableReplyTo={true}
*/}
<div className="padding20 memoReplies commentsDelegateParent comments_hideSecondReplyUserHeader"
style={{ display: (comments && !!comments.length) ? 'block' : 'none', paddingBottom: '0px' }}>
<div className="replies_count commentstypetop">
{this.props.isAdmin() === true ? <span className="commentstypebutton font-16 ">
{this.state.commentstype === false ? <Button type="primary" onClick={() => this.startcomments()}>开启刷新评论</Button>
: <Button type="danger" onClick={() => this.clearcomments()}>停止刷新</Button>}
</span> : ""}
<span className="labal font-16">全部回复</span>
<span className="count font-16">({memo.total_replies_count})</span>
</div>
<Comments comments={comments} user={current_user}
replyComment={this.replyComment}
deleteComment={this.deleteComment}
commentPraise={this.commentPraise}
rewardCode={this.rewardCode}
hiddenComment={this.hiddenComment}
buttonText={'发表'}
usingAntdModal={true}
isChildCommentPagination={true}
loadMoreChildComments={this.loadMoreChildComments}
initReply={this.initReply}
showRewardButton={false}
showReply={!isCourseEnd}
onlySuperAdminCouldHide={true}
></Comments>
{/* { true ? :
<div className="memoMore">
<div className="writeCommentBtn" onClick={this.showCommentInput}>写评论</div>
</div>} */}
</div>
<div className="memoMore" style={{ 'margin-top': '20px' }}>
{total_count > REPLY_PAGE_COUNT &&
<Pagination showQuickJumper onChange={this.onPaginationChange} current={pageCount} total={total_count} pageSize={10} />
}
{!isCourseEnd && <div className="writeCommentBtn" onClick={this.showCommentInput}>写评论</div>}
</div>
</div>
</div>
</div>
);
}
}
export default ImageLayerOfCommentHOC()(RouteHOC()(TopicDetail));

View File

@ -1,46 +0,0 @@
/*必填*/
/*
.ant-form-item-required::before {
display: none;
}
.ant-form-item-control-wrapper.ant-col-xs-24.ant-col-sm-24::before {
display: inline-block;
margin-right: 8px;
color: #f5222d;
font-size: 14px;
font-family: SimSun, sans-serif;
line-height: 1;
content: '*';
}*/
/*
.ant-form-item-control {
display: inline-block;
}*/
/* form 样式 --------------------------------------------- */
.topicTitle {
margin-bottom: 8px;
}
.topicTitle .ant-form-item-control-wrapper {
width: 100%;
}
.ant-pagination.coursePagination {
text-align: center;
margin-top: 16px;
}
.setemail{
margin-left: 20px;
}
.setemail .ant-checkbox-wrapper{
margin-top: 8px;
}

View File

@ -1,9 +0,0 @@
.directory_style {
position: absolute;
right: 0;
bottom: 0;
maxSize: 20px;
overflow: hidden;
whiteSpace: nowrap;
textOverflow: ellipsis
}

View File

@ -1,66 +0,0 @@
import React, { Component } from 'react';
export function RouteHOC(options = {}) {
return function wrap(WrappedComponent) {
return class Wrapper extends Component {
constructor(props) {
super(props);
this.state = {
}
}
toDetailPage = (_courseId, boardId, topicId) => {
if (typeof _courseId == "object") {
const topicId = _courseId.topicId
const boardId = _courseId.boardId
const courseId = _courseId.coursesId
this.props.history.push(`/classrooms/${courseId}/boards/${boardId}/messages/${topicId}`)
} else {
this.props.history.push(`/classrooms/${_courseId}/boards/${boardId}/messages/${topicId}`)
}
}
toEditPage = (_courseId, boardId, topicId) => {
if (typeof _courseId == "object") {
const topicId = _courseId.topicId
const boardId = _courseId.boardId
const courseId = _courseId.coursesId
this.props.history.push(`/classrooms/${courseId}/boards/${boardId}/messages/${topicId}/edit`)
} else {
this.props.history.push(`/classrooms/${_courseId}/boards/${boardId}/messages/${topicId}/edit`)
}
}
toNewPage = (courseId, boardId) => {
this.props.history.push(`/classrooms/${courseId}/boards/${boardId}/messages/new`)
}
toListPage = (_courseId, boardId) => {
if (typeof _courseId == "object") {
const boardId = _courseId.boardId
const courseId = _courseId.coursesId
this.props.history.push(`/classrooms/${courseId}/boards/${boardId}`)
} else {
this.props.history.push(`/classrooms/${_courseId}/boards${boardId ? '/' + boardId : ''}`)
}
}
render() {
const { snackbarOpen} = this.state;
return (
<React.Fragment>
<WrappedComponent {...this.props}
toDetailPage={this.toDetailPage}
toEditPage={this.toEditPage}
toNewPage={this.toNewPage}
toListPage={this.toListPage}
>
</WrappedComponent>
</React.Fragment>
)
}
}
}
}

View File

@ -1,437 +0,0 @@
import React, { Component } from "react";
import { Input, Checkbox, Pagination, Spin } from "antd";
import BoardsListItem from './BoardsListItem'
import Titlesearchsection from '../common/titleSearch/TitleSearchSection'
import ColorCountText from '../common/titleSearch/ColorCountText'
import SendToCourseModal from '../coursesPublic/modal/SendToCourseModal'
import NoneData from "../coursesPublic/NoneData"
import axios from 'axios'
import _ from 'lodash'
import './board.css'
import '../css/members.css'
import { RouteHOC } from './common.js'
import { trigger, WordsBtn } from 'educoder'
class Boards extends Component {
constructor(props) {
super(props);
this.state = {
searchValue: '',
checkAllValue: false,
checkBoxValues: [],
pagination: {
page: 1,
page_size: 15,
total_count: 0
},
messages: [
],
sort_type: 'time',
boardid: undefined,
isSpin: false
}
}
fetchAll = (searchText, page) => {
this.setState({
isSpin: true
})
const _serachText = searchText || this.state.searchValue
const _page = page || this.state.pagination.page
const bid = this.props.match.params.boardId
//
// hot
const sort_type = this.state.sort_type
// page_size
const url = `/boards/${bid}/messages.json?page_size=15&search=${_serachText || ''}&page=${_page}&sort=0&sort_type=${sort_type}`
axios.get(encodeURI(url)).then((response) => {
if (response.data.status == 0 && response.data.data) {
let _newBoards = response.data.data.messages
this.setState({
messages: _newBoards,
boardName: response.data.data.name,
boardid: response.data.data.id,
parent_id: response.data.data.parent_id,
pagination: response.data.pagination || Object.assign({}, this.state.pagination
, { page: _page, total_count: response.data.data.total_count }),
isSpin: false
})
}
})
.catch(function (error) {
console.log(error);
this.setState({
isSpin: false
})
});
}
fetchBoards = () => {
const boardId = this.props.match.params.boardId
const boardsUrl = `/courses/board_list.json?board_id=${boardId}`
axios.get(boardsUrl, {})
.then((response) => {
if (response.data.status == 0) {
this.setState({
boards: response.data.data.boards,
course_id: response.data.data.course_id
})
}
})
.catch(function (error) {
console.log(error);
});
}
componentDidMount = () => {
this.setState({
isSpin: true
})
this.fetchBoards()
this.fetchAll()
}
updateNavSuccess = () => {
this.fetchBoards()
if (this.props.match.params.boardId == this.state.boardid) {
this.fetchAll()
}
}
componentDidUpdate = (prevProps) => {
if (prevProps.match.params.boardId !== this.props.match.params.boardId) {
this.setState({
isSpin: true
})
this.clearAllCheck()
this.fetchAll(null, 1)
}
}
moveTo = (board) => {
const len = this.state.checkBoxValues.length
if (len == 0) {
this.props.showNotification('请先在列表中选择要移动的帖子')
return;
}
const bid = this.props.match.params.boardId
const checkBoxValues = this.state.checkBoxValues
const url = `/boards/${bid}/messages/bulk_move.json`
axios.put(url, {
ids: checkBoxValues,
to_board_id: board.id
})
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('帖子移动成功')
this.props.updataleftNavfun()
this.clearAllCheck()
this.fetchAll()
}
})
.catch(function (error) {
console.log(error);
});
}
onDelete = () => {
const len = this.state.checkBoxValues.length
if (len == 0) {
this.props.showNotification('请先选择要删除的帖子')
return;
}
this.props.confirm({
content: `是否确认删除?`,
onOk: () => {
const bid = this.props.match.params.boardId
const url = `/boards/${bid}/messages/bulk_delete.json`
axios.delete(url, {
data: {
ids: this.state.checkBoxValues
}
})
.then((response) => {
if (response.data.status == 0) {
this.clearAllCheck()
this.fetchAll(null, 1)
this.props.updataleftNavfun()
}
})
.catch(function (error) {
console.log(error);
});
}
})
}
onSticky = (message) => {
const cid = this.props.match.params.coursesId
const url = `/messages/${message.id}/sticky_top.json`
axios.put(url, {
course_id: cid,
})
.then((response) => {
if (response.data.status == 0) {
this.fetchAll()
}
})
.catch(function (error) {
console.log(error);
});
}
onItemClick = (item) => {
const checkBoxValues = this.state.checkBoxValues.slice(0);
const index = checkBoxValues.indexOf(item.id);
if (index != -1) {
_.remove(checkBoxValues, (listItem) => listItem === item.id)
} else {
checkBoxValues.push(item.id)
}
this.onCheckBoxChange(checkBoxValues)
}
onPressEnter = (e) => {
clearTimeout(this.timeoutHandler)
this.timeoutHandler = null;
this.fetchAll(this.state.searchValue, 1)
}
onInputSearchChange = (e) => {
this.setState({
searchValue: e.target.value
})
if (this.timeoutHandler) {
clearTimeout(this.timeoutHandler)
this.timeoutHandler = null;
}
this.timeoutHandler = setTimeout(() => {
this.fetchAll(this.state.searchValue, 1)
}, 1200)
}
addDir = () => {
let { boardid } = this.state;
trigger('boardAdd', parseInt(boardid))
}
renameDir = () => {
const boardId = this.props.match.params.boardId
trigger('boardRename', { category_id: parseInt(boardId), category_name: this.state.boardName })
}
onToBoardsNew = () => {
const courseId = this.state.course_id
const boardId = this.props.match.params.boardId
this.props.toNewPage(courseId, boardId)
}
onCheckAll = (e) => {
this.setState({
checkAllValue: e.target.checked
})
const values = this.state.messages.map(item => {
return item.id
})
if (e.target.checked) {
const concated = this.state.checkBoxValues.concat(values);
const sortedUniqed = _.uniq(concated)
this.setState({
checkBoxValues: sortedUniqed
})
} else {
this.setState({
checkBoxValues: _.difference(this.state.checkBoxValues, values)
})
}
}
clearAllCheck = () => {
this.setState({
checkBoxValues: [],
checkAllValue: false
})
}
onCheckBoxChange = (checkedValues) => {
this.setState({
checkBoxValues: checkedValues,
checkAllValue: checkedValues.length == this.state.messages.length
})
console.log('checked = ', checkedValues);
}
onPageChange = (pageNumber) => {
let { checkAllValue } = this.state;
if (checkAllValue === true) {
this.setState({
checkBoxValues: [],
checkAllValue: false
})
} else {
this.setState({
checkBoxValues: []
})
}
this.fetchAll(null, pageNumber)
}
onSendToOtherCourse = () => {
const len = this.state.checkBoxValues.length
if (len == 0) {
this.props.showNotification('请先在列表中选择要发送的帖子')
return;
}
this.refs.sendToCourseModal.setVisible(true)
}
onSetToOpen = () => {
const { checkBoxValues } = this.state;
if (checkBoxValues.length == 0) {
this.props.showNotification('请先在列表中选择要公开的帖子')
return;
}
const boardId = this.props.match.params.boardId
const url = `/boards/${boardId}/messages/bulk_public.json`
axios.put(url, {
ids: checkBoxValues
})
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('操作成功')
this.fetchAll()
}
})
.catch(function (error) {
console.log(error);
});
}
onSortTypeChange = (sort_type) => {
this.setState({ sort_type }, () => {
this.fetchAll()
})
}
render() {
const isAdmin = this.props.isAdmin()
const isCourseEnd = this.props.isCourseEnd()
const isAdminOrStudent = this.props.isAdminOrStudent()
let { boardName, searchValue, boards, messages, checkBoxValues,
checkAllValue, pagination, sort_type, parent_id } = this.state;
const { coursedata } = this.props;
const bid = this.props.match.params.boardId
return (
<React.Fragment >
<SendToCourseModal
ref="sendToCourseModal"
{...this.props}
moduleName="帖子"
selectedMessageIds={checkBoxValues}
></SendToCourseModal>
<Titlesearchsection
title={boardName || "帖子列表"}
searchValue={searchValue}
onInputSearchChange={this.onInputSearchChange}
allowClearonChange={this.onInputSearchChange}
showSearchInput={messages.length >= 10}
searchPlaceholder={'请输入帖子名称进行搜索'}
firstRowRight={
<React.Fragment>
{!isCourseEnd && isAdmin && !parent_id && <WordsBtn style="blue" className="mr30" onClick={() => this.addDir()}>新建目录</WordsBtn>}
{isAdmin && !!parent_id && <WordsBtn style="blue" className="mr30" onClick={() => this.renameDir()}>目录重命名</WordsBtn>}
{!isCourseEnd && isAdminOrStudent && <WordsBtn style="blue" className="" onClick={() => this.onToBoardsNew()}>我要发贴</WordsBtn>}
</React.Fragment>
}
secondRowLeft={
pagination ? <ColorCountText count={pagination.total_count} name="个帖子"></ColorCountText> : ''
}
onPressEnter={this.onPressEnter}
></Titlesearchsection>
{messages && messages.length == 0 ? "" : isAdmin && <div className="mt20 edu-back-white padding20-30">
<div className="clearfix">
{isAdmin && <Checkbox className="fl" onChange={this.onCheckAll} checked={checkAllValue}>已选 {checkBoxValues.length} 不支持跨页勾选</Checkbox>}
<div className="studentList_operation_ul">
{!!isAdmin &&
<React.Fragment>
<li className="li_line"><a className="color-grey-9" onClick={this.onDelete}>删除</a></li>
<li className="li_line"><a className="color-grey-9" onClick={this.onSendToOtherCourse}>发送</a></li>
{coursedata && !!coursedata.course_public && <li className="li_line"><a className="color-grey-9" onClick={this.onSetToOpen}>设为公开</a></li>}
<li className="li_line drop_down">
移动到目录<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_menu"
style={{ "right": "0px", "left": "unset", maxHeight: '318px', overflowY: 'auto', minWidth: '200px' }}>
{boards && boards.length > 10 && <p className="drop_down_search">
<Input placeholder="搜索" value={this.state.dirSearchValue} onChange={(e) => { this.setState({ dirSearchValue: e.target.value }) }} />
</p>}
{
boards && boards.filter((item) => {
return item.id != bid && (!this.state.dirSearchValue || item.name.indexOf(this.state.dirSearchValue) != -1)
}).map((item, index) => {
return <li key={`i_${index}`} onClick={() => this.moveTo(item)} title={item.name}>{item.name}</li>
})
}
{isAdmin && !isCourseEnd &&
<p className="drop_down_btn">
<a className="color-grey-6"
onClick={() => this.addDir()}
>新建目录...</a>
</p>
}
</ul>
</li>
</React.Fragment>
}
<li className="drop_down">
{sort_type == 'time' ? '时间排序' : '热度排序'}<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_normal">
<li onClick={() => this.onSortTypeChange('time')}>时间排序</li>
<li onClick={() => this.onSortTypeChange('hot')}>热度排序</li>
</ul>
</li>
</div>
</div>
</div>
}
<style>{`
.panel-inner-fourm {
border-bottom: none;
}
.panel-inner-fourm:hover {
background: #fff;
}
`}</style>
<Spin size="large" spinning={this.state.isSpin}>
<div className="clearfix stu_table">
<Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}>
{messages.map((item, index) => {
return (
<div className="mt20 edu-back-white padding02010" key={`d_${index}`}>
<BoardsListItem
{...this.props}
discussMessage={item}
checkBox={isAdmin ? <Checkbox value={item.id} key={item.id}></Checkbox> : ''}
onItemClick={this.onItemClick}
onSticky={this.onSticky}
></BoardsListItem>
</div>
)
})
}
</Checkbox.Group>
</div>
</Spin>
{
(!this.state.isSpin && (!messages || messages.length == 0)) && <NoneData></NoneData>
}
{pagination.total_count > 15 && <Pagination className="coursePagination"
current={pagination.page}
showQuickJumper pageSize={15} total={pagination.total_count} onChange={this.onPageChange} />}
</React.Fragment>
)
}
}
export default RouteHOC()(Boards);

View File

@ -1,275 +0,0 @@
import React,{ Component } from "react";
import { Modal,Checkbox,notification} from "antd";
import axios from 'axios';
class Ecerciseallbackagain extends Component{
constructor(props){
super(props);
this.state={
data:undefined,
limit:10,
page:1,
datalist:undefined,
group_ids:undefined
}
}
componentDidMount() {
let url="/exercises/"+this.props.match.params.Id+"/redo_modal.json";
axios.get(url,{params:{
limit:10,
page:1,
}
}).then((response) => {
this.setState({
data:response.data,
datalist:response.data.exercise_users
})
}).catch((error) => {
this.props.callback()
console.log(error)
});
}
//勾选实训
shixunhomeworkedit=(checkedValues)=>{
let{datalist}=this.state;
if(checkedValues.length===datalist.length){
this.setState({
onChangetype:true,
group_ids:checkedValues
})
}else{
this.setState({
group_ids:checkedValues,
onChangetype:false
})
}
}
contentViewScroll=(e)=>{
//滑动到底判断
let newscrollTop=parseInt(e.currentTarget.scrollTop);
let allclientHeight=e.currentTarget.clientHeight+newscrollTop;
if(e.currentTarget.scrollHeight-allclientHeight===0||e.currentTarget.scrollHeight-allclientHeight===1||e.currentTarget.scrollHeight-allclientHeight===-1){
let {page,limit,datalist}=this.state;
let newpage=page+1;
let newdata=datalist;
let url="/exercises/"+this.props.match.params.Id+"/redo_modal.json";
axios.get(url,{params:{
limit:limit,
page:newpage,
}
}).then((response) => {
response.data.exercise_users.map((item,key)=>{
newdata.push(item)
})
this.setState({
datalist:newdata,
page:newpage
})
}).catch((error) => {
console.log(error)
});
}
}
onChange=(e)=>{
let{datalist}=this.state;
if(e.target.checked===true){
let id=[]
datalist.map((item,key)=>{
id.push(item.user_id)
})
this.setState({
group_ids:id,
onChangetype:e.target.checked
})
}else{
this.setState({
group_ids:[],
onChangetype:e.target.checked
})
}
}
isSave=()=>{
let{group_ids}=this.state;
if(group_ids===undefined||group_ids.length===0){
notification.open({
message:"提示",
description:"请先选择学生"
});
return
}
let url="/exercises/"+this.props.match.params.Id+"/redo_exercise.json";
axios.post(url, {
user_ids: group_ids,
})
.then((response) => {
if (response.data.status === 0) {
this.props.callback(1)
notification.open({
message:"提示",
description:response.data.message
});
}
// else if(response.data.status === -1){
// notification.open({
// message: '参数错误',
// });
// }else if(response.data.status === -2){
// notification.open({
// message: '当前作业不支持查重',
// });
// }else if(response.data.status === -3){
// notification.open({
// message: '正在查重中',
// });
// }else if(response.data.status === -4){
// notification.open({
// message: '查重异常',
// });
// }
})
.catch(function (error) {
console.log(error);
});
}
issCancel=()=>{
this.props.callback()
}
render(){
let {datalist,group_ids,onChangetype}=this.state;
console.log()
return(
<div>
<style>
{
`
@media (max-width: 2000px) {
.newupload_select_box{
height: 265px !important;
}
}
@media (max-width: 1350px) {
.HomeworkModal{
top:10px !important;
}
.newupload_select_box{
height: 220px !important;
}
}
@media (max-width: 1250px) {
.HomeworkModal{
top:0px !important;
}
.newupload_select_box{
height: 150px !important;
}
}
.eerxisbox:hover {
background: #e4eaf6;
}
.upload_select_box li:hover {
background:transparent;
}
`
}
</style>
<Modal
className={"HomeworkModal"}
title={this.props.modalname}
visible={this.props.visible}
closable={false}
footer={null}
keyboard={false}
destroyOnClose={true}
>
<div className="task-popup-content">
<style>{`
.greybackHead{
padding:0px 30px;
}
.fontlefts{text-align: left;}
`}</style>
<div className="clearfix edu-txt-center mb10" style={{color:"#333333",fontSize: '15px'}}>学生将得到一次重新答题的机会现有的答题情况将被清空</div>
<ul className="clearfix edu-txt-center ml35">
<li className="fl paddingleft22 fontlefts" style={{width:'160px'}}>姓名</li>
<li className="fl edu-txt-left" style={{width:'124px'}}>学号</li>
<li className="fr" style={{width:'170px'}}>成绩</li>
</ul>
{datalist===undefined?"":
<ul className="upload_select_box fl clearfix mt10 mb10 newupload_select_box" style={{"overflow-y":"auto"}}
id="search_not_members_list"
onScroll={this.contentViewScroll}
>
<Checkbox.Group style={{ width: '100%' }} onChange={this.shixunhomeworkedit} value={group_ids}>
{ datalist.map((item,key)=>{
return(
<div className="clearfix edu-txt-center lineh-40 eerxisbox" key={key}>
<li className="fl" style={{width: '158px'}}>
<Checkbox
className="fl task-hide edu-txt-left"
name="shixun_homework[]"
value={item.user_id}
key={item.user_id}
>
<a style={{"textAlign": "left"}}
className="task-hide color-grey-name"
href={`/users/${item.user_id}/classrooms`}
target={'_blank'}
title={item.user_name}
>{item.user_name}</a>
</Checkbox>
</li>
<li className="fl" style={{width: '150px'}}>
{item.student_id}
</li>
<li className="fr" style={{width: '170px',color:'#FF6800'}}>
{item.user_score}
</li>
</div>
)
})}
</Checkbox.Group>
</ul>
}
<div className={"clearfix mt5 ml10"}>
<Checkbox checked={onChangetype} onChange={this.onChange}>{onChangetype===true?"清除":"全选"}</Checkbox>
</div>
<div className="clearfix edu-txt-center">
<a className="task-btn color-white mr30" onClick={this.issCancel}>取消</a>
<a className="task-btn task-btn-orange" onClick={this.isSave}>确认</a>
</div>
</div>
</Modal>
</div>
)
}
}
export default Ecerciseallbackagain;

View File

@ -1,247 +0,0 @@
import React,{Component} from "react";
import { Form, Select, Input, Button,Checkbox,DatePicker} from "antd";
import locale from 'antd/lib/date-picker/locale/zh_CN';
import "../css/Courses.css";
import CoursesListType from '../coursesPublic/CoursesListType';
const { Option } = Select;
const CheckboxGroup = Checkbox.Group;
class Ecercisemount extends Component{
constructor(props){
super(props)
this.state={
}
}
componentDidMount(){
}
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFields((err, values) => {
if (!err) {
console.log('Received values of form: ', values);
}
});
}
handleSelectChange = (value) => {
console.log(value);
this.props.form.setFieldsValue({
note: `Hi, ${value === 'male' ? 'man' : 'lady'}!`,
});
}
render(){
const { getFieldDecorator } = this.props.form;
const dateFormat = 'YYYY-MM-DD HH:mm:ss';
return(
<React.Fragment>
<div>
<div className="newMain clearfix">
<div className={"educontent mb20"}>
<div style={{ width:'100%',height:'70px'}} >
<p className="ml15 fl color-black mt30 summaryname">Java语言之控制语句</p>
<CoursesListType
typelist={["已开启补交"]}
typesylename={"mt28"}
/>
<a onClick={()=>this.props.history.goBack()} className="color-grey-6 fr font-16 ml20 mt18 mr20">返回</a>
<a href="/student_work?homework=16737" className="color-grey-6 fr font-16 ml30 mt18 " target={"_blank"}>实训详情</a>
</div>
<div className="stud-class-set bor-bottom-greyE">
<div className="mt10 clearfix edu-back-white poll_list pl20">
<a className="active">答题列表</a>
<a>统计结果</a>
<a>问卷预览</a>
<a>配置</a>
<a className={"fr color-blue font-16"}>导出成绩</a>
<a className={"fr color-blue font-16"}>导出空白试卷</a>
</div>
</div>
<Form onSubmit={this.handleSubmit} className={"edu-back-white newcourses exercise"}>
{/*内容*/}
<div className="stud-class-set bor-bottom-greyE pd20 exerciselist">
<Form.Item label="发布设置" hasFeedback>
{getFieldDecorator("TestingProfile")(
<Checkbox id="TestingProfile" value={""} className="fl ml40">统一设置</Checkbox>
)}
<span className={"coursesselect"}>选中则所有分班使用相同的发布设置否则各个分班单独设置</span>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40" style={{minWidth: '70px'}}>发布时间</span>
<span className="fl mt5">
{getFieldDecorator("startTime")(
<DatePicker
showTime
showToday={false}
locale={locale}
format={dateFormat}
placeholder="请选择发布时间"
id={"startTime"}
width={"210px"}
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
)}
<span className={"exerciseselect"}>发布之前学生不会收到问卷</span>
</span>
</div>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40" style={{minWidth: '70px'}}>截止时间</span>
<span className="fl mt5">
{getFieldDecorator("endTime")(
<DatePicker
showTime
showToday={false}
locale={locale}
format={dateFormat}
placeholder="请选择截止时间"
id={"endTime"}
width={"210px"}
// value={opening_time===null||opening_time===""?"":moment(opening_time, dateFormat)}
// onChange={this.onChangeTimePicker}
/>
)}
<span className={"exerciseselect"}>截止时间点系统将自动提交所有学生的答题学生将不能继续答题</span>
</span>
</div>
</Form.Item>
</div>
<div className="stud-class-set bor-bottom-greyE pd20 exercisetime">
<Form.Item label="答题设置" hasFeedback>
<div className={"clearfix"}>
<span className="color-grey-6 mt5 fl ml40 font-16" style={{minWidth: '70px'}}>答题时长</span>
{getFieldDecorator("TestingProfile"
, {
rules: [{
pattern: /^[1-9]\d*$/,
message: '答题时长必须为正整数',
}],
})(
<Input id="TestingProfile" className={"greyInput mt10 mr10"} style={{width:'108px',marginLeft:'0px'}} />
)}
<span className={"mr10"}>分钟</span>
<span className={"coursesselect"}>选中则所有分班使用相同的发布设置否则各个分班单独设置</span>
</div>
</Form.Item>
<Form.Item hasFeedback>
<div className={"clearfix pd60"}>
{getFieldDecorator("subject", {
valuePropName: 'checked',
})(
<Checkbox id="subject" className="fl">题目顺序随机打乱</Checkbox>
)}
<span className={"coursesselect"}>选中则学生答题时题目顺序按照题型随机显示</span>
</div>
<div className={"clearfix pd60"}>
{getFieldDecorator("options", {
valuePropName: 'checked',
})(
<Checkbox id="options" className="fl">选项顺序随机打乱</Checkbox>
)}
<span className={"coursesselect"}>选中则学生答题时选项顺序随机显示</span>
</div>
</Form.Item>
</div>
<div className="stud-class-set pd20 coursenavbox">
<Form.Item
label="公开设置"
hasFeedback
>
<div className={"clearfix pd28"}>
{getFieldDecorator("opergrdee", {
valuePropName: 'checked',
})(
<Checkbox id="opergrdee" className="fl">公开成绩</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开所有成绩否则不公开</span>
</div>
<div className={"clearfix pd28"}>
{getFieldDecorator("openanswer", {
valuePropName: 'checked',
})(
<Checkbox id="openanswer" className="fl">公开答案</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开试卷题目的答案否则不公开</span>
</div>
<div className={"clearfix pd28"}>
{getFieldDecorator("openstatisticss", {
valuePropName: 'checked',
})(
<Checkbox id="openstatisticss" className="fl">公开统计</Checkbox>
)}
<span className={"coursesselect"}>选中则在截止时间之后对提交答题的课堂成员公开答题统计否则不公开</span>
</div>
</Form.Item>
</div>
<Form.Item wrapperCol={{ span: 12, offset: 5 }} >
<div className="clearfix mt30 mb30">
<Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">
提交
</Button>
{/*<a className="defalutSubmitbtn fl mr20">提交</a>*/}
<a className="defalutCancelbtn fl">取消</a>
</div>
</Form.Item>
</Form>
</div>
</div>
</div>
</React.Fragment>
)
}
}
const EcercisemountApp = Form.create({ name: 'coursesNew' })(Ecercisemount);
export default EcercisemountApp;

View File

@ -1,597 +0,0 @@
import React,{ Component } from "react";
import {Checkbox, Pagination,Menu,Spin } from "antd";
import ExerciseListItem from './ExerciseListItem'
import axios from 'axios';
import Modals from '../../modals/Modals';
import '../css/members.css'
import { WordsBtn,on, publicSearchs } from 'educoder'
import '../css/busyWork.css'
import _ from 'lodash';
import moment from 'moment'
import UseBank from "../busyWork/UseBank";
import ImmediatelyPublish from "../poll/pollPublicBtn/ImmediatelyPublish";
import ImmediatelyEnd from "../poll/pollPublicBtn/ImmediatelyEnd";
import NoneData from "../coursesPublic/NoneData";
import HomeworkModal from "../coursesPublic/HomeworkModal";
class Exercise extends Component{
constructor(props){
super(props);
this.state={
modalname:undefined,
modaltype:undefined,
modalsBottomval:undefined,
visible:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
StudentList_value:undefined,
addname:undefined,
addnametype:false,
addnametab:undefined,
addcanner:undefined,
addsave:undefined,
type:undefined,
search:undefined,
page:1,
limit:15,
checkBoxValues:[],
Exercisetype:"exercise",
isSpin:false
}
}
// 加载列表
componentDidMount(){
this.reloadList();
on('updateNavSuccess', this.updateNavSuccess)
}
updateNavSuccess=()=>{
this.reloadList();
}
reloadList=()=>{
this.setState({
isSpin:true
})
let{type,search,page,limit}=this.state
this.InitList(type,search,page,limit);
}
// 获取列表数据
InitList=(type,search,page,limit)=>{
this.setState({
isSpin:true
})
let coursesId=this.props.match.params.coursesId;
let url='/courses/'+coursesId+'/exercises.json';
axios.get(url,
{
params: {
type:type,
search: search,
page: page,
limit: limit
}
}
).then((result)=>{
this.setState({
exercises_counts:result.data.exercises_counts,
course_types:result.data.course_types,
exercises:result.data.exercises,
checkAllValue:false,
checkBoxValues:[],
isSpin:false,
page:page
})
}).catch((error)=>{
this.setState({
isSpin:false,
})
})
}
inputStudent=(e)=>{
this.setState({
StudentList_value:e.target.value,
})
}
// 搜索
searchInfo=(value)=>{
this.setState({
type:undefined,
page:1,
StudentList_value:value
})
let{type,limit}=this.state;
this.InitList(type,value,1,limit)
}
changeType=(e)=>{
this.setState({
type:e.key==="0"?undefined:e.key,
page:1,
checkAllValue:false,
checkBoxValues:[]
})
let{StudentList_value,page,limit}=this.state;
this.InitList(e.key==="0"?undefined:e.key,StudentList_value,1,limit)
}
//切换分页
changePage=(pageNumber)=>{
this.setState({
page:pageNumber,
checkBoxValues:[]
})
let{type,StudentList_value,limit}=this.state
this.InitList(type,StudentList_value,pageNumber,limit);
}
onselectfifteen = () => {
this.setState({
Modalstype:true,
Modalstopval:"选择条数不能大于15条",
ModalSave:this.cancelmodel,
modalsBottomval:"",
Loadtype:true
})
}
cancelmodel=()=>{
this.setState({
Modalstype:false,
Loadtype:false,
Modalstopval:"",
modalsBottomval:"",
ModalCancel:"",
ModalSave:"",
})
}
onCheckBoxChange = (checkedValues) => {
let {exercises}=this.state;
if( checkedValues.length>15){
this.onselectfifteen()
return
}
this.setState({
checkBoxValues: checkedValues,
checkAllValue: checkedValues.length == exercises.length
})
}
onItemClick = (item) => {
const checkBoxValues = this.state.checkBoxValues.slice(0);
const index = checkBoxValues.indexOf(item.id);
if (index != -1) {
_.remove(checkBoxValues, (listItem)=> listItem === item.id)
} else {
checkBoxValues.push(item.id)
}
this.onCheckBoxChange(checkBoxValues)
}
// 全选or反选
onCheckAll = (e) => {
this.setState({
checkAllValue: e.target.checked
})
const values = this.state.exercises.map(item => {
return item.id
})
if (e.target.checked) {
const concated = this.state.checkBoxValues.concat(values);
const uniq=_.uniq(concated)
this.setState({
checkBoxValues: uniq
})
} else {
this.setState({
checkBoxValues: _.difference(this.state.checkBoxValues, values)
})
}
}
// 题库选用成功后刷新页面
useBankSuccess=(checkValue,value)=>{
let{type,StudentList_value,page,limit}=this.state;
let coursesId=this.props.match.params.coursesId;
let url=`/courses/${coursesId}/exercises/publish_modal.json`;
axios.get(url,{
params:{
check_ids:value
}
}).then((response) => {
if(response.status===200){
let list=[];
if(response.data.course_info){
for(var i=0;i<response.data.course_info.length;i++){
list.push({
id:response.data.course_info[i].course_group_id,
name:response.data.course_info[i].course_group_name,
})
}
}
this.setState({
modalname:"立即发布",
modaltype:response.data.un_publish > 0 ? 1 : 2,
visible:true,
Topval:"学生将立即收到试卷",
// Botvalleft:"暂不发布",
Botval:`本操作只对"未发布"的试卷有效`,
starttime:"发布时间:"+moment(moment(new Date())).format("YYYY-MM-DD HH:mm"),
starttimes:this.props.getNowFormatDates(1),
endtime:"截止时间:"+this.props.getNowFormatDates(2),
Cancelname:"暂不发布",
Savesname:"立即发布",
Cancel:this.homeworkhide,
Saves:this.homeworkstartend,
course_groups:list,
checkBoxValues:value
})
}
}).catch((error) => {
console.log(error)
});
}
//删除或者设为公开
ActionPoll=(value)=>{
let CourseId=this.props.match.params.coursesId;
let{type,StudentList_value,page,limit}=this.state;
//判断是否有选中数据
if(this.state.checkBoxValues.length==0){
// this.setState({
// Modalstype:true,
// Modalstopval:"请先在列表中选择数据",
// Loadtype:true,
// ModalSave:this.cancelmodel,
// })
this.props.showNotification("请先在列表中选择数据");
}else{
if(value != "bank"){
this.setState({
Modalstype:true,
Modalstopval:value=="delete"?"已提交作品将全部被删除,不可恢复":"公开后非课堂成员也可以访问查看",
modalsBottomval:value=="delete"?"是否确认删除?":"是否确认公开?",
Loadtype:false,
boxType:value,
ModalSave:this.ModalAction
})
}else{
//加入题库
let url=`/courses/${CourseId}/exercises/join_exercise_banks.json`;
axios.post((url), {
check_ids: this.state.checkBoxValues
})
.then((result)=>{
if(result.data.status==0){
this.props.showNotification(`${result.data.message}`);
this.setState({
Modalstype:false,
Modalstopval:"",
modalsBottomval:"",
Loadtype:false,
checkBoxValues:[]
})
this.InitList(type,StudentList_value,page,limit)
this.props.updataleftNavfun()
}
}).catch((error)=>{
console.log(error);
})
}
}
}
//确定删除或者设为公开
ModalAction=()=>{
let CourseId=this.props.match.params.coursesId;
let{type,StudentList_value,page,limit}=this.state;
this.setState({
Modalstypeloding:true
})
if(this.state.checkBoxValues.length==0){
this.setState({
Modalstype:false,
Modalstopval:"",
modalsBottomval:"",
Loadtype:false,
checkBoxValues:[],
Modalstypeloding:false
})
}else{
if(this.state.boxType=="delete"){
//删除
let url=`/courses/${CourseId}/exercises/destroys.json`;
axios.post((url), {
check_ids: this.state.checkBoxValues
})
.then((result)=>{
if(result.data.status==0){
this.props.showNotification(`${result.data.message}`);
this.setState({
Modalstype:false,
Modalstopval:"",
modalsBottomval:"",
Loadtype:false,
checkBoxValues:[],
Modalstypeloding:false
})
this.InitList(type,StudentList_value,page,limit);
this.props.updataleftNavfun();
}
}).catch((error)=>{
console.log(error);
})
}else if(this.state.boxType=="public"){
//设为公开
let url=`/courses/${CourseId}/exercises/set_public.json`;
axios.post((url), {
check_ids: this.state.checkBoxValues
})
.then((result)=>{
if(result.data.status==0){
this.props.showNotification(`${result.data.message}`);
this.setState({
Modalstype:false,
Modalstopval:"",
modalsBottomval:"",
Loadtype:false,
checkBoxValues:[]
})
let{type,StudentList_value}=this.state
this.InitList(type,StudentList_value,1);
}
}).catch((error)=>{
console.log(error);
})
}
}
}
//暂不发布
homeworkhide=()=>{
let {type,StudentList_value,page,limit}=this.state;
this.setState({
modalname:undefined,
modaltype:undefined,
visible:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
StudentList_value:undefined,
addname:undefined,
addnametype:false,
addnametab:undefined
})
this.InitList(type,StudentList_value,page,limit)
}
getcourse_groupslist=(id)=>{
this.setState({
chooseId:id
})
}
// 确定立即发布
homeworkstartend=(idss,endtime)=> {
let {chooseId,checkBoxValues,type,StudentList_value,page,limit} = this.state;
let coursesId = this.props.match.params.coursesId;
let url = `/courses/${coursesId}/exercises/publish.json`
axios.post(url, {
check_ids: checkBoxValues,
group_ids: chooseId,
end_time:endtime
}).then((result) => {
if (result) {
this.props.showNotification(result.data.message);
this.homeworkhide();
// 调用父级公共头部的接口刷新
// this.props.action()
this.InitList(type,StudentList_value,page,limit)
}
}).catch((error) => {
console.log(error);
})
}
render(){
let {
checkAllValue,
StudentList_value,
exercises_counts,
course_types,
exercises,
checkBoxValues,
pageSize,
page,
}=this.state;
let {child}=this.props;
return(
<React.Fragment>
{/* 公用的提示弹框 */}
<Modals
modalsType={this.state.Modalstype}
modalsTopval={this.state.Modalstopval}
modalsBottomval={this.state.modalsBottomval}
loadtype={this.state.Loadtype}
modalCancel={this.cancelmodel}
modalSave={this.state.ModalSave}
antIcon={this.state.Modalstypeloding}
></Modals>
<HomeworkModal
modaltype={this.state.modaltype}
modalname={this.state.modalname}
visible={this.state.visible}
Topval={this.state.Topval}
Topvalright={this.state.Topvalright}
Botvalleft={this.state.Botvalleft}
Botval={this.state.Botval}
starttime={this.state.starttime}
starttimes={this.state.starttimes}
endtime={this.state.endtime}
Cancelname={this.state.Cancelname}
Savesname={this.state.Savesname}
Cancel={this.state.Cancel}
Saves={this.state.Saves}
course_groups={this.state.course_groups}
getcourse_groupslist={(id)=>this.getcourse_groupslist(id)}
/>
<div className="edu-back-white">
<p className="clearfix padding30 bor-bottom-greyE">
<span className="font-18 fl color-dark-21">{exercises_counts && exercises_counts.left_banner_name}</span>
{
this.props.isAdmin()===true?
<li className="fr">
<p className="fl"><UseBank {...this.props} {...this.state} object_type={"exercise"} useBankSuccess={this.useBankSuccess}></UseBank></p>
{course_types&&course_types.course_status===0?<WordsBtn style="blue" className="font-16" to={`/classrooms/${this.props.match.params.coursesId}/exercises/new`}>新建</WordsBtn>:""}
</li>:""
}
</p>
<div className="clearfix pl30 pr30">
<p className="fl font-14" style={{"marginTop":"27px"}}>
<span className="mr20">{exercises_counts && exercises_counts.exercises_total_counts}个试卷</span>
<span className="mr20">已发布{exercises_counts && exercises_counts.exercises_published_counts}</span>
<span>未发布{exercises_counts && exercises_counts.exercises_unpublish_counts}</span>
</p>
<div className="fr mt16 mb16 searchView">
{publicSearchs("请输入名称进行搜索",this.searchInfo,this.inputStudent,this.inputStudent)}
</div>
</div>
<div className="task_menu_ul pl30 pr30">
<Menu mode="horizontal" defaultSelectedKeys="0" onClick={this.changeType}>
<Menu.Item key="0">全部</Menu.Item>
<Menu.Item key="2">考试中</Menu.Item>
{this.props.isAdmin()?<Menu.Item key="1">未发布</Menu.Item>:""}
<Menu.Item key="3">已截止</Menu.Item>
</Menu>
</div>
</div>
<Spin size="large" spinning={this.state.isSpin}>
{this.props.isAdmin()?exercises && exercises.length ===0?"":<div className="mt20 mb20 edu-back-white padding20-30">
<div className="clearfix">
<Checkbox className="fl" onChange={this.onCheckAll} checked={checkAllValue}>已选 {checkBoxValues.length} 不支持跨页勾选</Checkbox>
<div className="studentList_operation_ul">
<li className="li_line"><a className="color-grey-9" onClick={()=>this.ActionPoll("delete")}>删除</a></li>
<li className="li_line">
<ImmediatelyPublish
{...this.props}
{...this.state}
style="grey"
checkBoxValues={this.state.checkBoxValues}
action={this.reloadList}
></ImmediatelyPublish>
</li>
<li className="li_line">
<ImmediatelyEnd
{...this.props}
{...this.state}
style="grey"
single={true}
checkBoxValues={this.state.checkBoxValues}
action={this.reloadList}
></ImmediatelyEnd>
</li>
{
course_types && course_types.course_is_public == 1 && <li className="li_line"><a className="color-grey-9" onClick={()=>this.ActionPoll("public")}>设为公开</a></li>
}
{this.props.user&&this.props.user.main_site===true?<li className="li_line"><a className="color-grey-9" onClick={()=>this.ActionPoll("bank")}>加入题库</a></li>:""}
</div>
</div>
</div>:<div className="mt20"></div>}
<style>{`
.workList_Item:hover {
box-shadow: 0px 2px 6px rgba(51,51,51,0.09);
opacity: 1;
border-radius: 2px;
}
`}</style>
{
exercises && exercises.length > 0 &&
<Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}>
<div className="workList">
{
exercises && exercises.map((item,key)=>{
return(
<ExerciseListItem
{...this.props}
{...this.state}
item={item}
index={key}
onItemClick={this.onItemClick}
checkBox={<Checkbox value={item.id} key={item.id}
></Checkbox>}
></ExerciseListItem>
)
})
}
</div>
</Checkbox.Group>
}
</Spin>
{
exercises && exercises.length ===0 && <NoneData></NoneData>
}
{
exercises_counts && exercises_counts.exercises_all_counts > 15 ?
<div className="mb20 edu-txt-center pt30">
<Pagination showQuickJumper current={page} total={exercises_counts && exercises_counts.exercises_all_counts} pageSize={15} onChange={this.changePage}></Pagination>
</div>
:
""
}
</React.Fragment>
)
}
}
export default Exercise;

View File

@ -1,182 +0,0 @@
import React,{ Component } from "react";
import axios from 'axios'
import SingleDisplay from './new/SingleDisplay'
import JudgeDisplay from './new/JudgeDisplay'
import NullDisplay from './new/NullDisplay'
import MainDisplay from './new/MainDisplay'
import ShixunDisplay from './new/ShixunDisplay'
import ShixunProgramming from './new/ShixunProgramming'
import './new/common.css'
class ExerciseDisplay extends Component{
constructor(props){
super(props);
this.state = {
exercise_questions: [],
exercise_group_id:[],
page:1,
limit:10,
searchtext:"",
order: "end_at",
is_md:false
}
}
_getRequestParams() {
const { order, exercise_group_id,searchtext, page ,limit} = this.state
return {
page,
search:searchtext,
order,
limit: limit,
group_id:exercise_group_id,
}
}
componentDidMount = () => {
const Id = this.props.match.params.Id
if (Id) {
const url = `/${this.props.urlPath || 'exercises'}/${Id}.json`
axios.get(url)
.then((response) => {
if (response.data.exercise) {
response.data.exercise.exercise_description = response.data.exercise.exercise_description || response.data.exercise.description
response.data.exercise.exercise_name = response.data.exercise.exercise_name || response.data.exercise.name
response.data.exercise.exercise_status = response.data.exercise.exercise_status == undefined ? 1 : response.data.exercise.exercise_status
this.setState({...response.data})
this.setState({
is_md:response.data.exercise.is_md
})
this.props.detailFetchCallback && this.props.detailFetchCallback(response);
} else {
this.props.detailFetchCallback && this.props.detailFetchCallback(response);
}
})
.catch(function (error) {
console.log(error);
});
}
try {
this.props.triggerRef(this);
}catch (e) {
}
}
_getRequestParams() {
const { order, exercise_group_id,searchtext, page ,limit} = this.state
return {
page,
search:searchtext,
order,
limit: limit,
group_id:exercise_group_id,
}
}
render() {
const { exercise_questions,exercise,exercise_types} = this.state;
const commonHandler = {}
return(
<div className="edu-back-white">
<div className={" padding20-30"}>
<style>
{
`
.center{
text-align: center;
}
.edu-back-white>.bor-bottom-greyE:last-child {
border-bottom: none !important;
}
`
}
</style>
<div className={"font-18 center"}>{exercise&&exercise.exercise_name}</div>
<div className={"font-14 color-grey-9"}>{exercise&&exercise.exercise_description}</div>
</div>
<div className={" padding20-30 newContainer"}>
<p className=" clearfix">
{
exercise_types && exercise_types.q_singles > 0 &&
<span className="color-grey-9 mr15 fl">单选题 {exercise_types.q_singles} , {exercise_types && exercise_types.q_singles_scores} </span>
}
{
exercise_types && exercise_types.q_doubles > 0 &&
<span className="color-grey-9 mr15 fl">多选题 {exercise_types.q_doubles} , {exercise_types && exercise_types.q_doubles_scores} </span>
}
{
exercise_types && exercise_types.q_judges > 0 &&
<span className="color-grey-9 mr15 fl">判断题 {exercise_types.q_judges} , {exercise_types && exercise_types.q_judges_scores} </span>
}
{
exercise_types && exercise_types.q_nulls > 0 &&
<span className="color-grey-9 mr15 fl">填空题 {exercise_types.q_nulls} , {exercise_types && exercise_types.q_nulls_scores} </span>
}
{
exercise_types && exercise_types.q_mains > 0 &&
<span className="color-grey-9 mr15 fl">简答题 {exercise_types.q_mains} , {exercise_types && exercise_types.q_mains_scores} </span>
}
{
exercise_types && exercise_types.q_shixuns > 0 &&
<span className="color-grey-9 mr15 fl">实训题 {exercise_types.q_shixuns} , {exercise_types && exercise_types.q_shixuns_scores} </span>
}
{
exercise_types && exercise_types.q_pros > 0 &&
<span className="color-grey-9 mr15 fl">编程题 {exercise_types.q_pros} , {exercise_types && exercise_types.q_pros_scores} </span>
}
<span className="color-grey-3 fr"><span className="color-orange-tip"> {exercise_types &&exercise_types.q_scores} </span></span>
<span className="color-grey-3 fr">合计<span className="color-blue"> {exercise_types &&exercise_types.q_counts} </span></span>
</p>
</div>
{ exercise_questions.map((item, index) => {
if (item.question_type == 0 || item.question_type == 1) {
return <SingleDisplay {...this.props} {...item} index={index} {...commonHandler} {...this.state}
displayCount={exercise_questions.length} showActionButton={false} key={index}
></SingleDisplay>
} else if (item.question_type == 2) {
return <JudgeDisplay
showActionButton={false} key={index} {...this.state}
{...this.props} {...item} index={index} {...commonHandler} ></JudgeDisplay>
} else if (item.question_type == 3) {
return <NullDisplay
showActionButton={false} key={index} {...this.state}
{...this.props} {...item} index={index} {...commonHandler} ></NullDisplay>
} else if (item.question_type == 4) {
//
return <MainDisplay
showActionButton={false} key={index} {...this.state}
{...this.props} {...item} index={index} {...commonHandler} ></MainDisplay>
} else if (item.question_type == 5) {
return <ShixunDisplay Testpapersettinghomepage
showActionButton={false} key={index} {...this.state}
{...this.props} {...item} index={index} {...commonHandler} ></ShixunDisplay>
}else if (item.question_type == 6) {
return <ShixunProgramming Testpapersettinghomepage
showActionButton={false} key={index} {...this.state}
{...this.props} {...item} index={index} {...commonHandler} ></ShixunProgramming>
}else{
return <div></div>
}
})}
</div>
)
}
}
// RouteHOC()
export default (ExerciseDisplay);

View File

@ -1,268 +0,0 @@
import React,{ Component } from "react";
import {Link} from 'react-router-dom';
import moment from 'moment';
import {Tooltip} from 'antd';
import Modals from '../../modals/Modals';
import CoursesListType from '../coursesPublic/CoursesListType';
import { formatDuring ,handleDateString} from 'educoder';
import '../css/members.css';
import '../css/busyWork.css';
import CourseLayoutcomponent from "./Exercise";
const dataformat="YYYY-MM-DD HH:mm";
const polls_status={1:"未发布",2:"提交中",3:"已截止",4:"已结束"}
class ExerciseListItem extends Component{
constructor(props){
super(props);
this.state={
Modalstype:false
}
}
setgameexercise=(url)=>{
let{item}=this.props;
if(item.time>0){
this.setState({
Modalstype:true,
ModalSave:()=>this.props.history.push(url),
Modalstopval:`答题时长限制${item.time}分钟,从首次答题开始实行不间断计时`,
modalsBottomval:'请确认是否有充足的答题时间?',
});
}else{
this.setState({
Modalstype:true,
ModalSave:()=>this.props.history.push(url),
Modalstopval:"是否确认开始答题?",
modalsBottomval:' ',
})
}
}
cancelmodel=()=>{
this.setState({
Modalstype:false,
ModalSave:' ',
Modalstopval:' ',
modalsBottomval:' ',
Loadtype:false
})
}
toDetailPage=(url)=>{
if(this.props.checkIfLogin()===false){
this.props.showLoginDialog()
return
}
// if(this.props.checkIfProfileCompleted()===false){
// this.setState({
// AccountProfiletype:true
// })
// return
// }
// if(this.props.checkIfProfessionalCertification()===false){
// this.props.showProfileCompleteDialog()
// return
// }
this.props.history.push(url);
}
render(){
let{item,checkBox,index}=this.props;
let {coursesId,Id}=this.props.match.params
const IsAdmin =this.props.isAdmin();
const isAssistant=this.props.isAssistant();
const IsStudent =this.props.isStudent();
return(
<div className="workList_Item" style={{cursor : IsAdmin ? "pointer" : "default",padding:"30px" }} onClick={() => window.$(`.exerciseitem${index} input`).click() }>
{
IsAdmin &&
<span className={`exerciseitem${index} fl mr12`}>
{checkBox}
</span>
}
{/* 公用的提示弹框 */}
{this.state.Modalstype===true?<Modals
modalsType={this.state.Modalstype}
modalsTopval={this.state.Modalstopval}
modalsBottomval={this.state.modalsBottomval}
loadtype={this.state.Loadtype}
modalCancel={this.cancelmodel}
modalSave={this.state.ModalSave}
antIcon={this.state.Modalstypeloding}
></Modals>:""}
<style>
{
`
.comnonwidth580{
max-width: 580px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.homepagePostSetting {
position: absolute;
}
`
}
</style>
<div className="flex1 pr">
<p className="clearfix mb20">
{/*<Link to={`/classrooms/${coursesId}/exercises/${item.id}/exercises/student_exercise_list?tab=0`} className="fl font-16 font-bd mt2 color-grey-3 task-hide" style={{"maxWidth":"600px"}}>{item.exercise_name}</Link>*/}
{
this.props.isAdmin()? <a className="fl font-16 font-bd mt2 color-grey-3 task-hide comnonwidth580 pointer"
title={item.exercise_name}
onClick={()=>this.toDetailPage(`/classrooms/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`)}>{item.exercise_name}</a>:""
}
{
this.props.isStudent()?
<a className="fl font-16 font-bd mt2 color-grey-3 task-hide comnonwidth580 pointer" title={item.exercise_name} onClick={()=>this.toDetailPage(`/classrooms/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`)}>{item.exercise_name}</a>:""
}
{
this.props.isNotMember()? item.lock_status === 0 ?
<span className="fl mt3 font-16 font-bd color-dark comnonwidth580 pointer" title={"私有属性,非课堂成员不能访问"}>{item.exercise_name}</span>
: <a className="fl font-16 font-bd mt2 color-grey-3 task-hide comnonwidth580 pointer" title={item.exercise_name} onClick={()=>this.toDetailPage(`/classrooms/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`)}>{item.exercise_name}</a>:""
}
{
item.lock_status === 0 ?
<Tooltip title={"私有属性,非课堂成员不能访问"} placement="bottom">
<i className="iconfont icon-guansuo color-grey-c ml10 font-16 fl"></i>
</Tooltip>
:""
}
{/*<CoursesListType typelist={[polls_status[`${item.exercise_status}`]]} typesylename={""}></CoursesListType>*/}
<CoursesListType typelist={ item.exercise_tips } typesylename={""}></CoursesListType>
{/*未发布、提交中、补交中、已开启补交、未开启补交、评阅中、已结束*/}
{/*<li className="fr drop_down">*/}
{/*<i className="iconfont icon-caidan font-16 color-grey-c"></i>*/}
{/*<ul className="drop_down_normal">*/}
{/*<li>编辑</li>*/}
{/*<li>设置</li>*/}
{/*</ul>*/}
{/*</li>*/}
</p>
<p className="color-grey-9 clearfix">
{ item.author && <span className="mr20 fl">{item.author}</span> }
{item.exercise_status===2||item.exercise_status===3?<span className="mr20 fl">已提交人数{item&&item.exercise_answer}/{item&&item.exercise_users}</span> :""}
{item.exercise_status===2?<span className="mr20 fl">考试中人数{item&&item.exercise_answerings}</span> :""}
{item.exercise_status===2||item.exercise_status===3?<span className="mr20 fl">待评阅试卷{item&&item.unreview_count}</span> :""}
{
item.exercise_status ===2?
<Tooltip title="考试剩余时间" placement="bottom">
<span className="mr20 fl">{"考试剩余时间:"+item.exercise_left_time}</span>
</Tooltip>:""
}
{/* {item.exercise_status===1?"":<span className="mr20 fl">{item.exercise_answer} </span>}
{item.exercise_status===1?"":<span className="mr20 fl">{item.exercise_unanswer} 未答</span>}
{item.unreview_count===null||item.exercise_status===1?"":<span className="mr20 fl">{item.unreview_count} 未评数</span> } */}
{
item.exercise_status ===1? item.publish_time ===null?
<span className="mr20 fl"> 创建于{moment(item.created_at).fromNow()} </span>
: <span className="mr20 fl"> 将发布于{
moment(item.publish_time).format('YYYY-MM-DD HH:mm')
} </span>:""
}
{
item.exercise_left_time===null?"":item.exercise_status ===3?
<Tooltip title="截止剩余时间" placement="bottom">
<span className="mr20 fl">{"截止剩余时间:"+item.exercise_left_time}</span>
</Tooltip>:""
}
{/*{*/}
{/*item.exercise_status ==2?"":*/}
{/*<span className="mr20 fl"> 发布于{moment(item.exercise_left_time).fromNow()} </span>*/}
{/*}*/}
{ IsAdmin &&<div className="homepagePostSetting" style={{"right":"-17px","top":"46px","display":"block","width":"200px"}}>
{
isAssistant===true?
(
item&&item.assistant_auth===true?
<a className="btn colorblue font-16 ml20" onClick={()=>this.toDetailPage(`/classrooms/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`)}>查看详情</a>
:
<a className="btn colorblue font-16 " style={{
marginLeft: "73px"
}} onClick={()=>this.toDetailPage(`/classrooms/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`)}>查看详情</a>
)
:
<a className="btn colorblue font-16 ml20" onClick={()=>this.toDetailPage(`/classrooms/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`)}>查看详情</a>
}
{
isAssistant===true?
(
item&&item.assistant_auth===true?
<Link className="btn colorblue font-16 ml20" to={`/classrooms/${coursesId}/exercises/${item.id}/edit`}>编辑</Link>
:
""
)
:
<Link className="btn colorblue font-16 ml20" to={`/classrooms/${coursesId}/exercises/${item.id}/edit`}>编辑</Link>
}
<Link className="btn colorblue ml20 font-16" to={`/classrooms/${coursesId}/exercises/${item.id}/student_exercise_list?tab=3`}>设置</Link>
</div> }
</p>
{/*{*/}
{/*IsAdmin &&*/}
{/*<div className="homepagePostSetting" style={{"right":"0px","top":"-5px","position":"absolute","display":"block"}}>*/}
{/*<ul>*/}
{/*<li className="edu-position edu-position-hidebox">*/}
{/*<i className="fa fa-bars color-grey-b"></i>*/}
{/*<ul className="edu-position-hide undis">*/}
{/*<li> <Link className="" to={`/classrooms/${coursesId}/exercises/${item.id}/edit`}>编辑</Link></li>*/}
{/*<li> <a className="" href={`*/}
{/*/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=3`*/}
{/*}>设置</a></li>*/}
{/*</ul>*/}
{/*</li>*/}
{/*</ul>*/}
{/*</div>*/}
{/*}*/}
{
IsStudent &&
<div className="homepagePostSetting" style={{"right":"0px","top":"46px","position":"absolute","display":"block"}}>
<li className={"fl"}> <a className="btn colorblue font-16" onClick={()=>this.toDetailPage(`/classrooms/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`)}>查看详情</a></li>
{item.current_status ===0&&item.exercise_status>1? <li className={"fl ml20"}> <Link className="btn colorblue font-16" to={`/classrooms/${coursesId}/exercises/${item.id}/users/${this.props.current_user.login}`}>继续答题</Link></li>:
item.current_status ===1&&item.exercise_status>1? <li className={"fl ml20"}> <a className="btn colorblue font-16" target="_blank" href={`/classrooms/${coursesId}/exercises/${item.id}/users/${this.props.current_user.login}`}>查看答题</a></li>:
item.current_status ===2&&item.exercise_status>1? <li className={"fl ml20"}s> <a className="btn colorblue font-16" onClick={()=>this.setgameexercise(`/classrooms/${coursesId}/exercises/${item.id}/users/${this.props.current_user.login}`)}>开始答题</a></li>:""}
</div>
}
{
this.props.isNotMember()? item.lock_status === 0 ?
""
: <div className="homepagePostSetting" style={{"right":"0px","top":"42px","position":"absolute","display":"block"}}>
<li> <a className="btn colorblue font-16" onClick={()=>this.toDetailPage(`/classrooms/${coursesId}/exercises/${item.id}/student_exercise_list?tab=0`)}>查看详情</a></li>
</div>:""
}
</div>
</div>
)
}
}
export default ExerciseListItem

View File

@ -1,57 +0,0 @@
import React, { Component } from "react";
import { CBreadcrumb } from 'educoder';
import './new/common.css'
import '../css/Courses.css'
import ExerciseNewCommon from './ExerciseNewCommon'
class ExerciceNew extends Component {
constructor(props) {
super(props);
this.state = {
left_banner_id: null
}
}
initData = (data) => {
this.setState({ left_banner_id: data.left_banner_id })
}
componentDidMount() {
document.title = this.props.coursedata && this.props.coursedata.name;
}
render() {
let { left_banner_id } = this.state;
const { current_user } = this.props
const courseId = this.props.match.params.coursesId;
let pramsids = this.props.match.params.Id;
return (
<div className="newMain exerciseNew">
<div className="edu-class-container edu-position courseForm">
{current_user && <CBreadcrumb items={[
{ to: current_user && current_user.first_category_url, name: this.props.coursedata ? this.props.coursedata.name : '' },
{ to: `/classrooms/${courseId}/exercises/${left_banner_id}`, name: '试卷列表' },
{ name: pramsids && pramsids ? '编辑试卷' : '新建试卷' }
]}></CBreadcrumb>}
<p className="clearfix mt20 mb20">
<span className="fl font-24 color-grey-3">{pramsids && pramsids ? "编辑" : "新建"}试卷</span>
<a className="color-grey-6 fr font-16 mr2"
onClick={() => this.props.history.push(`/classrooms/${courseId}/exercises/${left_banner_id}`)}>
返回
</a>
</p>
<ExerciseNewCommon
{...this.props}
{...this.state}
isEdit={this.isEdit}
initData={this.initData}
></ExerciseNewCommon>
</div>
</div>
)
}
}
export default ExerciceNew;

View File

@ -1,553 +0,0 @@
import React, { Component } from "react";
import { Tooltip } from 'antd'
import { Q_TYPE_SINGLE, Q_TYPE_JUDGE, Q_TYPE_NULL, Q_TYPE_MAIN, Q_TYPE_SHIXUN } from './new/common'
import axios from 'axios'
import "../common/formCommon.css"
import { ActionBtn } from 'educoder';
import SingleEditor from './new/SingleEditor'
import SingleDisplay from './new/SingleDisplay'
import JudgeEditor from './new/JudgeEditor'
import JudgeDisplay from './new/JudgeDisplay'
import NullEditor from './new/NullEditor'
import NullDisplay from './new/NullDisplay'
import MainEditor from './new/MainEditor'
import MainDisplay from './new/MainDisplay'
import ShixunEditor from './new/ShixunEditor'
import ShixunDisplay from './new/ShixunDisplay'
import ShixunProgramming from './new/ShixunProgramming'
import ShixunChooseModal from '../coursesPublic/ShixunChooseModal'
import ExerciseForm from './exercise-new-form'
import update from 'immutability-helper'
import './new/common.css'
import '../css/Courses.css'
const $ = window.$
class ExerciseNewCommon extends Component {
constructor(props) {
super(props);
this.state = {
exercise_questions: [],
exercise_name: '',
is_md: true,
exercise_description: '',
exercise_types: {},
editMode: !this.props.match.params.Id,
}
}
// 已发布试卷编辑保存的确认弹框
changeScore = (question_id, answerArray) => {
this.props.confirm({
content: '修改了标准答案',
subContent: "是否重新计算学生答题的成绩?",
onOk: () => {
this.sureChangeScore(question_id, answerArray)
},
onCancel: () => {
this.addSuccess();
}
})
}
// 已发布试卷修改答案确认修改分数
sureChangeScore = (question_id, answerArray) => {
let url = `/exercise_questions/${question_id}/update_scores.json`
axios.post((url), {
standard_answers: answerArray
}).then((result) => {
if (result) {
this.props.showNotification(`${result.data.message}`);
this.addSuccess();
}
}).catch((error) => {
console.log(error);
})
}
fetchExercise = () => {
const Id = this.props.match.params.Id
this.isEdit = this.props.isEdit || !!Id
if (this.isEdit) {
const url = this.props.exercise_url ? `/${this.props.exercise_url}/${Id}.json` : `/exercises/${Id}/edit.json`
axios.get(url)
.then((response) => {
if (response.data.exercise) {
const { exercise, ...others } = response.data
this.setState({
...exercise,
...others,
editMode: false
})
this.props.initData && this.props.initData(response.data)
}
})
.catch(function (error) {
console.log(error);
});
} else {
const courseId = this.props.match.params.coursesId;
const newUrl = `/courses/${courseId}/exercises/new.json`
axios.get(newUrl)
.then((response) => {
if (response.data.status == 0) {
this.setState({
...response.data
})
}
})
.catch(function (error) {
console.log(error);
});
}
}
componentDidMount = () => {
this.fetchExercise()
}
onSaveExercise = (data) => {
const exercise_id = this.props.match.params.Id
const courseId = this.props.match.params.coursesId
if (this.isEdit) {
const editUrl = `/${this.props.exercise_url ? this.props.exercise_url : 'exercises'}/${exercise_id}.json`
axios.put(editUrl, { ...data })
.then((response) => {
if (response.data.status == 0) {
this.setState({ ...data, editMode: false })
this.props.showNotification('试卷编辑成功')
}
})
.catch(function (error) {
console.log(error);
});
} else {
const url = `/courses/${courseId}/exercises.json`
axios.post(url, {
...data
})
.then((response) => {
if (response.data.status == 0) {
this.setState({ ...data, editMode: false })
this.props.showNotification('试卷新建成功')
const exercise_id = response.data.data.exercise_id;
this.isEdit = true;
this.props.history.replace(`/classrooms/${courseId}/exercises/${exercise_id}/edit`);
}
})
.catch(function (error) {
console.log(error);
});
}
}
exercise_name_change = (e) => {
this.setState({ exercise_name: e.target.value })
}
exercise_description_change = (e) => {
this.setState({ exercise_description: e.target.value })
}
// #问题的类型0为单选题1为多选题2为判断题3为填空题4为主观题5为实训题
_checkIsEditing = () => {
if (this.editingId && $(this.editingId).length) {
this.props.showNotification('请先保存或取消当前正在编辑的问题。')
$("html").animate({ scrollTop: $(this.editingId).offset().top - 100 })
return true
}
return false
}
onEditorCancel = () => {
this.editingId = null;
// 找到编辑或新建的item新建就删掉item编辑就isNew改为false
const { exercise_questions } = this.state
let index = -1;
for (let i = 0; i < exercise_questions.length; i++) {
if (exercise_questions[i].isNew == true) {
index = i;
break;
}
}
if (exercise_questions[index].question_id) { // 编辑
this.setState(
(prevState) => ({
exercise_questions: update(prevState.exercise_questions, { [index]: { isNew: { $set: false } } })
// update(prevState.exercise_questions, {$splice: [[index, 1]]})
})
)
} else { // 新建
this.setState(
(prevState) => ({
exercise_questions: update(prevState.exercise_questions, { $splice: [[index, 1]] })
})
)
}
}
addQuestion = (question_id_to_insert_after, type) => {
if (!this.isEdit) {
this.props.showNotification('请先输入试卷标题,并保存试卷')
return;
}
if (this._checkIsEditing()) {
return;
}
if (type == Q_TYPE_SHIXUN) {
this.addShixun(question_id_to_insert_after)
} else {
this.addEditingQuestion(type, question_id_to_insert_after)
}
}
chooseShixun = (array) => {
this.addEditingQuestion(Q_TYPE_SHIXUN, this.question_id_to_insert_after, {
shixun_id: array[0]
})
}
chooseShixunSuccess = () => {
this.refs.shixunChooseModal.setVisible(false)
}
addShixun = (question_id_to_insert_after) => {
if (!this.isEdit) {
this.props.showNotification('请先输入试卷标题,并保存试卷')
return;
}
// TODO 弹框选择实训
if (this._checkIsEditing()) {
return;
}
this.refs.shixunChooseModal.setVisible(true)
this.question_id_to_insert_after = question_id_to_insert_after;
return;
}
editQestion = (index, nprops) => {
// console.log(nprops.match.params.coursesId)
// console.log(nprops.match.params.Id)
if (nprops) {
if (this._checkIsEditing()) {
return;
} else {
if (nprops.question_type === 6) {
this.props.history.push(`/problems/${nprops.hack_identifier}/edit?classrooms=${nprops.match.params.coursesId}&exercises=${nprops.match.params.Id}`)
} else {
this.editingId = `#question_${index}`
this.setState(
(prevState) => ({
exercise_questions: update(prevState.exercise_questions, { [index]: { isNew: { $set: true } } })
})
)
}
}
} else {
if (this._checkIsEditing()) {
return;
}
this.editingId = `#question_${index}`
this.setState(
(prevState) => ({
exercise_questions: update(prevState.exercise_questions, { [index]: { isNew: { $set: true } } })
})
)
}
}
onSort = (index, question_id, isUp) => {
if (this._checkIsEditing()) {
return;
}
const url = `/${this.props.exercise_url_questions || 'exercise_questions'}/${question_id}/up_down.json`
axios.post(url, { opr: isUp ? 'up' : 'down' })
.then((response) => {
if (response.data.status == 0) {
// this.props.showNotification('移动成功')
this.fetchExercise()
}
})
.catch(function (error) {
console.log(error);
});
}
onSortDown = (index, question_id) => {
this.onSort(index, question_id, false)
}
onSortUp = (index, question_id) => {
this.onSort(index, question_id, true)
}
getInitScore = (question_type, question_id_to_insert_after) => {
/**
1.每个题型的首个题目默认值规则如下
选择题5 01
判断题2 2
填空题2 3
简答题10 4
实训题每个关卡5分 5
*/
let init_question_score = 0;
if (question_type == 0 || question_type == 1) {
init_question_score = 5
} else if (question_type == 2) {
init_question_score = 2
} else if (question_type == 3) {
init_question_score = 2
} else if (question_type == 4) {
init_question_score = 10
} else if (question_type == 5) {
init_question_score = 5
}
const _indexBefore = question_id_to_insert_after ? this.findIndexById(question_id_to_insert_after) : this.state.exercise_questions.length - 1
for (let i = _indexBefore; i >= 0; i--) {
if (this.state.exercise_questions[i].question_type == question_type) {
init_question_score = this.state.exercise_questions[i].question_score
break;
}
}
return init_question_score;
}
addEditingQuestion = (question_type, question_id_to_insert_after, otherAttributes) => {
let init_question_score = this.getInitScore(question_type, question_id_to_insert_after)
let questionObj = {
question_type: question_type, // 需要这个通过类型判断
init_question_score: init_question_score,
isNew: true, // 新建或编辑用是否有id区分是新建还是编辑
question_id_to_insert_after,
...otherAttributes
}
const { exercise_questions } = this.state;
let new_exercise_questions = exercise_questions.slice(0)
let newIndex = new_exercise_questions.length;
if (question_id_to_insert_after) {
const _indexBefore = this.findIndexById(question_id_to_insert_after)
new_exercise_questions.splice(_indexBefore + 1, 0, questionObj)
newIndex = _indexBefore + 1
} else {
new_exercise_questions.push(questionObj)
}
this.editingId = `#question_${newIndex}`
this.setState({ exercise_questions: new_exercise_questions }, () => {
setTimeout(() => {
$(this.editingId).length && $("html").animate({ scrollTop: $(this.editingId).offset().top - 100 })
}, 500)
})
}
findIndexById = (id) => {
const { exercise_questions } = this.state
for (let i = 0; i < exercise_questions.length; i++) {
if (exercise_questions[i].question_id == id) {
return i;
}
}
}
onQestionDelete = (question_id) => {
this.props.confirm({
content: `确认要删除这个问题吗?`,
onOk: () => {
const url = `/${this.props.exercise_url_questions || 'exercise_questions'}/${question_id}.json`
axios.delete(url)
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('删除成功')
this.fetchExercise()
}
})
.catch(function (error) {
console.log(error);
});
}
})
}
addSuccess = () => {
this.editingId = null;
this.fetchExercise()
}
goToPreview = () => {
const exercise_id = this.props.match.params.Id
const courseId = this.props.match.params.coursesId
this.props.history.push(`/classrooms/${courseId}/exercises/${exercise_id}/student_exercise_list?tab=2`)
}
getAddQuestionUrl = () => {
const Id = this.props.match.params.Id
const url = this.props.exercise_url_questions ? `/${this.props.exercise_url_questions}.json` : `/exercises/${Id}/exercise_questions.json`
return url;
}
getEditQuestionUrl = (question_id) => {
const editUrl = this.props.exercise_url_questions ? `/${this.props.exercise_url_questions}/${question_id}.json` : `/exercise_questions/${question_id}.json`
return editUrl;
}
onCancel = () => {
this.setState({
editMode: false
})
}
render() {
let { exercise_name, exercise_description, exercise_types, exercise_questions, is_md, editMode } = this.state;
const { q_counts, q_scores, q_doubles, q_doubles_scores, q_judges, q_judges_scores,
q_mains, q_mains_scores, q_nulls, q_nulls_scores, q_shixuns, q_shixuns_scores, q_singles, q_singles_scores, q_pros, q_pros_scores } = exercise_types;
const exerciseFormOpt = {
exercise_name,
exercise_description,
is_md,
onCancel: this.onCancel,
isEdit: this.isEdit,
onSaveHandler: this.onSaveExercise
}
const exercise_id = this.props.match.params.Id
const commonHandler = {
onQestionDelete: this.onQestionDelete,
addSuccess: this.addSuccess,
addQuestion: this.addQuestion,
onEditorCancel: this.onEditorCancel,
changeScore: this.changeScore,
editQestion: this.editQestion,
onSortDown: this.onSortDown,
onSortUp: this.onSortUp,
displayCount: exercise_questions.length,
exercise_status: this.state.exercise_status,
exerciseIsPublish: this.state.exercise_status >= 2,
getAddQuestionUrl: this.getAddQuestionUrl,
getEditQuestionUrl: this.getEditQuestionUrl,
exercise_url: this.props.exercise_url
}
return (
<React.Fragment>
<ShixunChooseModal
ref="shixunChooseModal"
chooseShixun={this.chooseShixun}
{...this.props}
singleChoose={true}
shixunsUrl={this.props.shixunsUrl}
></ShixunChooseModal>
<style>{`
.courseForm .formBlock {
padding: 20px 30px 30px 30px;
border-bottom: 1px solid #EDEDED;
margin-bottom: 0px;
background: #fff;
}
.exerciseNew .markdown-body {
max-width: 1128px;
}
`}</style>
{!this.state.editMode && <div style={{ background: '#fff', padding: '20px 30px', minHeight: 100 }}>
<div className="displayTitle font-16">
<span>{exercise_name}</span>
<a className="fr mr6" onClick={() => { this.setState({ editMode: true }) }} style={{ lineHeight: '40px' }}>
<Tooltip title="编辑"><i className="iconfont icon-bianjidaibeijing font-20 color-green"></i></Tooltip>
</a>
</div>
<div className="displayDescription color-grey-9" dangerouslySetInnerHTML={{ __html: exercise_description }}
style={{ whiteSpace: 'pre-wrap' }}
></div>
</div>}
{this.state.editMode && <ExerciseForm {...exerciseFormOpt} />}
<p className="clearfix padding20-30 color-grey-9">
<span className="fl">
{!!q_singles && <span className="mr20">单选题{q_singles}{q_singles_scores}</span>}
{!!q_doubles && <span className="mr20">多选题{q_doubles}{q_doubles_scores}</span>}
{!!q_judges && <span className="mr20">判断题{q_judges}{q_judges_scores}</span>}
{!!q_nulls && <span className="mr20">填空题{q_nulls}{q_nulls_scores}</span>}
{!!q_mains && <span className="mr20">简答题{q_mains}{q_mains_scores}</span>}
{!!q_shixuns && <span className="mr20">实训题{q_shixuns}{q_shixuns_scores}</span>}
{!!q_pros && <span className="mr20">编程题{q_pros}{q_pros_scores}</span>}
</span>
<span className="fr">
{!!q_counts &&
<span>
合计 <span className="color-blue">{q_counts}</span>
<span className={`${q_scores > 100 ? 'color-red font-bd' : 'color-orange'}`}>{q_scores}</span>
</span>
}
</span>
</p>
<div className="edu-back-white">
{exercise_questions.map((item, index) => {
if (item.question_type == 0 || item.question_type == 1) {
if (item.isNew) {
return <SingleEditor key={index} {...this.props} {...this.state} {...item} index={index} {...commonHandler}></SingleEditor>
} else {
return <SingleDisplay key={index}{...this.props} {...this.state} {...item} index={index} {...commonHandler}
displayCount={exercise_questions.length}
></SingleDisplay>
}
} else if (item.question_type == 2) {
if (item.isNew) {
return <JudgeEditor key={index}{...this.props} {...this.state} {...item} index={index} {...commonHandler}></JudgeEditor>
} else {
return <JudgeDisplay key={index}{...this.props} {...this.state} {...item} index={index} {...commonHandler} ></JudgeDisplay>
}
} else if (item.question_type == 3) {
if (item.isNew) {
return <NullEditor key={index}{...this.props} {...this.state} {...item} index={index} {...commonHandler}></NullEditor>
} else {
return <NullDisplay key={index}{...this.props} {...this.state} {...item} index={index} {...commonHandler} ></NullDisplay>
}
} else if (item.question_type == 4) {
if (item.isNew) {
return <MainEditor key={index}{...this.props} {...this.state} {...item} index={index} {...commonHandler} ></MainEditor>
} else {
return <MainDisplay key={index}{...this.props} {...this.state} {...item} index={index} {...commonHandler} ></MainDisplay>
}
} else if (item.question_type == 5) {
if (item.isNew) {
return <ShixunEditor key={index}{...this.props} {...this.state} {...item} index={index} {...commonHandler}
chooseShixunSuccess={this.chooseShixunSuccess}
></ShixunEditor>
} else {
return <ShixunDisplay key={index}{...this.props} {...this.state} {...item} index={index} {...commonHandler} ></ShixunDisplay>
}
} else if (item.question_type == 6) {
if (item.isNew) {
return <ShixunProgramming key={index}{...this.props} {...this.state} {...item} index={index} {...commonHandler}
chooseShixunSuccess={this.chooseShixunSuccess}></ShixunProgramming>
} else {
return <ShixunProgramming key={index}{...this.props} {...this.state} {...item} index={index} {...commonHandler} ></ShixunProgramming>
}
}
return <div></div>
})}
{!commonHandler.exerciseIsPublish && <div className="problemShow padding30">
<ActionBtn style="green" className="mr20" onClick={() => this.addQuestion(null, Q_TYPE_SINGLE)}>
<i className="iconfont icon-tianjiafangda color-white font-14 mr5" style={{ marginTop: '-1px', display: 'inline-block' }}></i>
</ActionBtn>
<ActionBtn style="green" className="mr20" onClick={() => this.addQuestion(null, Q_TYPE_JUDGE)}>
<i className="iconfont icon-tianjiafangda color-white font-14 mr5" style={{ marginTop: '-1px', display: 'inline-block' }}></i>
</ActionBtn>
<ActionBtn style="green" className="mr20" onClick={() => this.addQuestion(null, Q_TYPE_NULL)}>
<i className="iconfont icon-tianjiafangda color-white font-14 mr5" style={{ marginTop: '-1px', display: 'inline-block' }}></i>
</ActionBtn>
<ActionBtn style="green" className="mr20" onClick={() => this.addQuestion(null, Q_TYPE_MAIN)}>
<i className="iconfont icon-tianjiafangda color-white font-14 mr5" style={{ marginTop: '-1px', display: 'inline-block' }}></i>
</ActionBtn>
<ActionBtn style="green" className="mr20" onClick={() => this.addShixun(null)}>
<i className="iconfont icon-tianjiafangda color-white font-14 mr5" style={{ marginTop: '-1px', display: 'inline-block' }}></i>
</ActionBtn>
{exercise_id && !this.props.hidePreviewButton && <ActionBtn style="blue" className="fr" onClick={() => this.goToPreview()}>
试卷预览
</ActionBtn>}
{this.props.bottomSection && this.props.bottomSection}
</div>}
</div>
</React.Fragment>
)
}
}
export default ExerciseNewCommon;

File diff suppressed because it is too large Load Diff

View File

@ -1,918 +0,0 @@
import React,{ Component } from "react";
import {Form,Checkbox,DatePicker,Button,Input,Select,Tooltip} from "antd";
import { handleDateString } from 'educoder';
import PollDetailTabForthRules from '../poll/PollDetailTabForthRules';
import '../css/members.css';
import '../css/busyWork.css';
import '../poll/pollStyle.css';
import moment from 'moment';
import locale from 'antd/lib/date-picker/locale/zh_CN';
import axios from 'axios';
import Modals from '../../modals/Modals';
const Search=Input.Search;
const Option=Select.Option;
function range(start, end) {
const result = [];
for (let i = start; i < end; i++) {
result.push(i);
}
return result;
}
function disabledDateTime() {
return {
// disabledHours: () => range(0, 24).splice(4, 20),
disabledMinutes: () => range(1, 30).concat(range(31, 60)),
// disabledSeconds: () => [0, 60],
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
const dataformat="YYYY-MM-DD HH:mm";
class Exercisesetting extends Component{
constructor(props){
super(props);
this.state={
flagPageEdit:undefined,
flagPublic:undefined,
flagRealName:undefined,
unified_list:undefined,
course_group:undefined,
end_time:undefined,
publish_time:undefined,
unit_p_tip:"",
unit_e_tip:"",
rules:undefined,
p_flag:true,
e_flag:true,
polls:undefined,
//公用提示弹框相关
modalsType:false,
modalsTopval:"",
loadtype:false,
modalSave:undefined,
firstSetting:true,
score_open:false,
answer_open:false,
unified_setting:true,
show_statistic:false,
question_random:true,
choice_random:true,
time:0,
publish_timetype:false,
end_timetype:false,
exercise_group_id:[],
page:1,
limit:10,
searchtext:"",
order: "end_at",
assistant_auth:false
}
// console.log("Exercisesetting");
// console.log("69");
// console.log(props);
}
_getRequestParams() {
const { order, exercise_group_id,searchtext, page ,limit} = this.state
return {
page,
search:searchtext,
order,
limit: limit,
group_id:exercise_group_id,
}
}
//加载
componentDidMount=()=>{
this.setState({
assistant_auth:this.props.assistant_auth,
})
this.getSettingInfo();
// window.addEventListener('click', this.handleClick);
try {
this.props.triggerRef(this);
}catch (e) {
}
if(this.props.Commonheadofthetestpaper!=undefined){
this.editSetting()
}
if(this.props.isAdmin() === false){
this.cancelEdit()
}
try {
//是否为助教
if(this.props.isAssistant()===true){
//如果是助教是否有权限
if(this.props.assistant_auth===true){
this.setState({
flagPageEdit:true
})
}else{
this.setState({
flagPageEdit:false
})
}
}
}catch (e) {
}
}
componentDidUpdate = (prevProps) => {
if(prevProps.Commonheadofthetestpaper!= this.props.Commonheadofthetestpaper){
this.editSetting()
}
if(prevProps.assistant_auth!= this.props.assistant_auth){
this.setState({
assistant_auth:this.props.assistant_auth,
})
}
}
_getRequestParams() {
const { order, exercise_group_id,searchtext, page ,limit} = this.state
return {
page,
search:searchtext,
order,
limit: limit,
group_id:exercise_group_id,
}
}
// handleClick=(e)=>{
// console.log(e);
// }
// 已有设置数据的查询
getSettingInfo=(type)=>{
if(type!=1){
this.props.Commonheadofthetestpapers()
}
let Id=this.props.match.params.Id;
let url=`/exercises/${Id}/exercise_setting.json`;
axios.get(url).then((result)=>{
if(result.status==200){
this.props.form.setFieldsValue({
time:result.data.exercise.time===-1?"":result.data.exercise.time,
});
this.setState({
polls:result.data.exercise,
flagPublic:result.data.exercise.is_public,
flagRealName:result.data.exercise.un_anonymous,
unified_list:result.data.published_course_groups,
course_group:result.data.course_groups,
publish_time:result.data.exercise.publish_time,
end_time:result.data.exercise.end_time,
firstSetting:result.data.published_course_groups.length==0 && result.data.exercise.publish_time == null && result.data.exercise.end_time==null,
score_open:result.data.exercise.score_open,
answer_open:result.data.exercise.answer_open,
unified_setting:result.data.exercise.unified_setting,
show_statistic:result.data.exercise.show_statistic,
question_random:result.data.exercise.question_random,
choice_random:result.data.exercise.choice_random,
time:result.data.exercise.time,
...result.data.exercise
})
if(result.data.exercise.unified_setting == true && moment(result.data.exercise.publish_time) <= moment()){
// if(this.props.isSuperAdmin()===true){
// this.setState({
// publish_timetype:false
// })
// }else{
//发布后谁都不能改
this.setState({
publish_timetype:true
})
// }
}
if(result.data.exercise.unified_setting == true && moment(result.data.exercise.end_time) <= moment()){
this.setState({
end_timetype:true
})
}
let group=result.data.published_course_groups;
if(group.length==0){
let list= [{
course_group_id:[],
course_group_name:[],
publish_time:undefined,
end_time:undefined,
publish_flag:"",
end_flag:"",
class_flag:"",
course_search:"",
poll_status:0,
open:false
}]
this.setState({
rules:list
})
}else{
let array=[];
for(var i=0;i<group.length;i++){
array.push({
course_group_id:group[i].course_group_id,
course_group_name:group[i].course_group_name,
publish_time:group[i].course_publish_time,
end_time:group[i].course_end_time,
poll_status:result.data.exercise.exercise_status,
publish_flag:"",
end_flag:"",
class_flag:"",
course_search:"",
open:false
})
}
this.setState({
rules:array
})
}
}
}).catch((error)=>{
console.log(error);
})
}
//提交form表单
handleSubmit = (e) => {
e.preventDefault();
// if(this.props&&this.props.Commonheadofthetestpaper.exercise_status){
// console.log("190");
// console.log(this.props.Commonheadofthetestpaper.exercise_status);
// }
this.props.form.validateFieldsAndScroll((err, values) => {
if(!err){
// 第一次进行问卷设置或者勾选了统一设置
let{unified_setting}=this.state
if(unified_setting==true){
console.log("统一设置");
this.UnifiedSetting( );
}else{
console.log("非统一设置");
this.NotUnifiedSetting( );
}
}
})
}
//跳转道描点的地方
scrollToAnchor = (anchorName) => {
if (anchorName) {
// 找到锚点
let anchorElement = document.getElementById(anchorName);
// 如果对应id的锚点存在就跳转到锚点
if(anchorElement) { anchorElement.scrollIntoView(); }
}
}
UnifiedSetting=()=>{
let { unit_e_tip , unit_p_tip , publish_time , end_time ,course_group }=this.state
// 如果两个时间都没有填写或者只选择了截止时间则先保存设置然后弹出立即发布弹框
if ( publish_time === undefined ||publish_time === null ){
this.setState({
unit_p_tip:"不能为空"
})
this.scrollToAnchor("publishtimeid");
return
// if(moment(end_time,dataformat)<=moment()){
// this.setState({
// unit_e_tip:"截止时间不能小于当前时间"
// })
// }else{
// this.setState({
// unit_e_tip:""
// })
// let list=[];
// let group=course_group;
// if(group.length>0){
// for(var i=0;i<group.length;i++){
// list.push({
// id:group[i].course_group_id,
// name:group[i].course_group_name,
// })
// }
// }
// this.setState({
// modalname:"立即发布",
// modaltype:list.length > 0 ? 1 : 2,
// visible:true,
// Topval:"本操作只对“未发布”的对象生效",
// Botvalleft:"暂不发布",
// Botval:"则通过后续手动设置,定时发布",
// starttime:"发布时间:"+this.props.getNowFormatDates(1),
// endtime:"截止时间:" + moment(end_time == "" || end_time ==undefined ? this.props.getNowFormatDates(2):end_time).format(dataformat),
// Cancelname:"暂不发布",
// Savesname:"立即发布",
// Cancel:this.homeworkhide,
// Saves:this.homeworkstartend,
// publishCourse:list,
// publish_time:this.props.getNowFormatDates(1)
// })
// }
}else{
if(this.state.publish_timetype === false){
if(moment(publish_time,dataformat) < moment() ){
this.setState({
unit_p_tip:"发布时间不能小于当前时间"
})
return;
}else{
this.setState({
unit_p_tip:""
})
}
}
if(this.state.end_timetype === false||this.props.isAdmin()==true){
if(moment(end_time,dataformat) <= moment(publish_time,dataformat)){
this.setState({
unit_e_tip:"截止时间不能小于发布时间"
})
return;
}else if(moment(end_time,dataformat)<=moment()){
this.setState({
unit_e_tip:"截止时间不能小于当前时间"
})
return;
}else{
this.setState({
unit_e_tip:""
})
}
}
this.commitSetting((result)=>{
console.log(result)
if(result.status===200){
this.props.showNotification(`${result.data.message}`);
this.getSettingInfo(1);
this.cancelEdit();
try {
this.props.assistantauthoritys(this.state.assistant_auth);
}catch (e) {
}
}
})
}
}
// 非统一设置提交
NotUnifiedSetting=()=>{
const result = this.refs.pollDetailTabForthRules.exerciseSettingCheck(this.state.rules);
this.setState({
rules: result.rules
})
if(result.validate==false){
return;
}
this.commitSetting((result)=>{
console.log(result)
if(result.status==200){
this.props.showNotification(`${result.data.message}`);
this.cancelEdit();
this.getSettingInfo(1);
try {
this.props.assistantauthoritys(this.state.assistant_auth);
}catch (e) {
}
}
});
}
commitSetting=(callback)=>{
let exercise_id=this.props.match.params.Id;
let url=`/exercises/${exercise_id}/commit_setting.json`;
let params=[];
if(this.state.unified_setting){
params={
unified_setting:this.state.unified_setting,
publish_time:this.state.publish_time,
end_time:this.state.end_time,
show_statistic:this.state.show_statistic,
choice_random:this.state.choice_random,
score_open:this.state.score_open,
answer_open:this.state.answer_open,
question_random:this.state.question_random,
time:this.state.time,
assistant_auth:this.state.assistant_auth,
}
}else{
let list=this.state.rules;
let lists=[]
list.map((item,key)=>{
let newlist={
course_group_id:item.course_group_id,
publish_time:item.publish_time,
end_time:item.end_time
}
lists.push(newlist)
})
params={
unified_setting:this.state.unified_setting,
show_statistic:this.state.show_statistic,
question_random:this.state.question_random,
choice_random:this.state.choice_random,
score_open:this.state.score_open,
answer_open:this.state.answer_open,
publish_time_groups:lists,
time:this.state.time,
assistant_auth:this.state.assistant_auth,
}
}
axios.post((url),params).then((result)=>{
callback(result);
}).catch((error)=>{
console.log(error);
})
}
rulesCheckInfo=(rules)=>{
this.setState({
rules
})
}
cancelBox=()=>{
this.setState({
modalsType:false,
modalsTopval:"",
loadtype:false,
})
}
// 是否统一设置
changeUnit=(e)=>{
this.setState({
unified_setting:e.target.checked
})
}
//是否公开统计
ChangeFlagPublic=(e)=>{
this.setState({
score_open:e.target.checked
})
}
//是否实名问卷
ChangeFlagName=(e)=>{
this.setState({
answer_open:e.target.checked
})
}
//题目顺序随机打乱
questionrandom=(e)=>{
this.setState({
question_random:e.target.checked
})
}
//选项顺序随机打乱
choicerandom=(e)=>{
this.setState({
choice_random:e.target.checked
})
}
//答题时间
funlatepenalty=(e)=>{
let value= parseInt(e.target.value);
if(isNaN(value)){
value=0
}
this.setState({
time:value
})
}
showstatistic=(e)=>{
this.setState({
show_statistic:e.target.checked
})
}
assistantauthority=(e)=>{
this.setState({
assistant_auth:e.target.checked
})
}
onChangeTimepublish=(date, dateString)=>{
if(date===null){
this.setState({
publish_time: null,
end_time:null
})
}else{
if(moment(handleDateString(dateString),"YYYY-MM-DD HH:mm") <= moment()){
this.setState({
unit_p_tip:"发布时间不能早于当前时间",
p_flag:true
})
}else{
this.setState({
unit_p_tip:"",
p_flag:false
})
}
this.setState({
publish_time: handleDateString(dateString),
end_time:moment(moment(handleDateString(dateString)).add(1, 'months')).format("YYYY-MM-DD HH:mm")
})
}
}
onChangeTimeEnd=(date, dateString)=>{
if(date===null){
this.setState({
end_time:null
})
}else{
if(dateString<=moment().format('YYYY-MM-DD HH:mm')){
this.setState({
unit_e_tip:"截止时间不能早于当前时间",
e_flag:true
})
}else if(moment(date,"YYYY-MM-DD HH:mm") <= moment(this.state.publish_time,"YYYY-MM-DD HH:mm")){
this.setState({
unit_e_tip:"截止时间不能早于发布时间",
e_flag:true
})
}else{
this.setState({
unit_e_tip:"",
e_flag:false
})
}
this.setState({
end_time: handleDateString(dateString)
})
}
}
//编辑
editSetting = () => {
if(this.props.Commonheadofthetestpaper.course_is_end==true){
this.setState({
modalsType:true,
modalsTopval:"课堂已结束不能再修改!",
loadtype:true,
modalSave:this.cancelBox
})
}else{
if(this.props.isAdmin()===true){
try {
//是否为助教
if(this.props.isAssistant()===true){
//如果是助教是否有权限
if(this.props.assistant_auth===true){
this.setState({
flagPageEdit:true
})
}else{
this.setState({
flagPageEdit:false
})
}
}else{
//是老师
this.setState({
flagPageEdit:true
})
}
}catch (e) {
this.setState({
flagPageEdit:true
})
}
}
}
}
//取消编辑
cancelEdit=()=>{
this.getSettingInfo(1);
this.setState({
flagPageEdit:false
})
}
render(){
let{flagPageEdit,end_time,publish_time,course_group,rules,
unit_p_tip,
unit_e_tip,
modalsType,
modalsTopval,
loadtype,
modalSave,
score_open,
answer_open,
unified_setting,
show_statistic,
question_random,
choice_random,
time,
polls,
publish_timetype,
end_timetype
}=this.state
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
// sm: { span: 8 },
sm: { span: 24 },
},
wrapperCol: {
xs: { span: 24 },
// sm: { span: 16 },
sm: { span: 24 },
},
};
// console.log(flagPageEdit===true?polls&&polls.exercise_status===1?3:2:1)
// console.log("asdasdasda");
// console.log(this.props);
// console.log(this.props.Commonheadofthetestpaper);
return(
<div>
<Modals
modalsType={modalsType}
modalsTopval={modalsTopval}
loadtype={loadtype}
modalSave={modalSave}
></Modals>
<Form {...formItemLayout} onSubmit={this.handleSubmit}>
<div className="edu-back-white">
<div className="bor-bottom-greyE" style={{padding: "20px 30px 0px 30px"}}>
<p className="mb30 clearfix">
<span className="font-16 fl">发布设置<span className="color-grey-c font-14"></span></span>
{
!flagPageEdit&&this.props.isAdmin()===true ?
(
this.props.isAssistant()===true?
(
this.props.assistant_auth===true?
<a className="fr mr6 white-btn edu-blueline-btn lineh-24" onClick={this.editSetting}>
编辑设置
</a>
:
""
)
:
<a className="fr mr6 white-btn edu-blueline-btn lineh-24" onClick={this.editSetting}>
编辑设置
</a>
)
:""
}
</p>
<div className="pl25">
{course_group&&course_group.length>1?<p className="clearfix mb20">
<Form.Item className="fl pollForm">
{getFieldDecorator('unified_setting')
(
<Checkbox disabled={this.props.isAdmin()===true?flagPageEdit===true?polls&&polls.exercise_status===1?false:true:true:true} className="mr15 font-16 color-grey-6"
checked={unified_setting?true:false}
onChange={this.changeUnit}>统一设置</Checkbox>
)}
</Form.Item>
<span className="color-grey-c">(选中则所有分班使用相同的发布设置仅课堂管理员可修改否则各个分班允许单独设置)</span>
</p>:""}
{
unified_setting===true ?
<div>
<div className="clearfix" id={"publishtimeid"}>
<span className="font-16 mr15 fl mt6">发布时间</span>
<div className="fl">
<Tooltip placement="bottom" title={publish_timetype===true?this.props.isAdmin()? "发布时间已过,不能再修改":"":""}>
<DatePicker
dropdownClassName="hideDisable"
placeholder="请选择发布时间"
className={unit_p_tip && unit_p_tip != "" ? "noticeTip winput-240-40":"winput-240-40" }
showTime={{ format: 'HH:mm' }}
locale={locale}
format="YYYY-MM-DD HH:mm"
showToday={false}
disabledTime={disabledDateTime}
disabledDate={disabledDate}
onChange={this.onChangeTimepublish}
value={publish_time && moment(publish_time,"YYYY-MM-DD HH:mm")}
disabled={ this.props.isAdmin()===true?publish_timetype===true?true:!flagPageEdit:true}
></DatePicker>
</Tooltip>
<p className="color-red lineh-25 clearfix" style={{height:"25px"}}>
{
unit_p_tip !="" ? <span className="fl">{unit_p_tip}</span>:""
}
</p>
</div>
<span className="color-grey-c ml20 fl mt10">(学生收到试卷的时间)</span>
</div>
<div className="clearfix">
<span className="mr15 fl mt10 font-16">截止时间</span>
<div className="fl">
<Tooltip placement="bottom" title={end_timetype===true ? this.props.isAdmin()?"":"截止时间已过,不能再修改":""}>
<DatePicker
dropdownClassName="hideDisable"
placeholder="请选择截止时间"
className={unit_e_tip && unit_e_tip != "" ? "noticeTip winput-240-40 mr20":"winput-240-40 mr20" }
showTime={{ format: 'HH:mm' }}
locale={locale}
showToday={false}
width={"240px"}
format="YYYY-MM-DD HH:mm"
disabledTime={disabledDateTime}
disabledDate={disabledDate}
onChange={this.onChangeTimeEnd}
value={end_time && moment(end_time,"YYYY-MM-DD HH:mm")}
disabled={ this.props.isAdmin()===true? end_timetype===true?this.props.isAdmin()?!flagPageEdit:true:!flagPageEdit:true}
>
</DatePicker>
</Tooltip>
<p className="color-red lineh-25 clearfix" style={{height:"25px"}}>
{
unit_e_tip && unit_e_tip != "" ? <span className="fl">{ unit_e_tip }</span>:""
}
</p>
</div>
<span className="color-grey-c ml20 fl mt10">(学生可以答题的时间截点)</span>
</div>
</div>
:
<PollDetailTabForthRules
{...this.props}
{...this.state}
ref="pollDetailTabForthRules"
rules={rules}
type={"Exercise"}
course_group={course_group}
flagPageEdit={flagPageEdit}
rulesCheckInfo={(info)=>this.rulesCheckInfo(info)}
Commonheadofthetestpaper={this.props.Commonheadofthetestpaper}
></PollDetailTabForthRules>
}
</div>
</div>
<div className="bor-bottom-greyE padding20-30">
<p className="mb30 clearfix font-16">答题设置</p>
<div className="pl25">
<p className="mb20" style={{height:"20px"}}>
<div className={"h21 mb30"}>
<span className={"fl mb10 mt5 mr10 font-16 color-grey-6"}>答题时长</span>
<Form.Item className="fl pollForm">
{getFieldDecorator('time')
(
<Input disabled={this.props.isAdmin()===true?!flagPageEdit:true} className="mr10" style={{width:"100px",height:"35px" }}
value={time===-1?"":time}
onInput={this.funlatepenalty}/>
)}
</Form.Item>
<span className={"fl mb10 mt5 mr10 font-16 color-grey-6"}>分钟</span>
<span className={"fl mb10 mt5 mr10 color-grey-c"}>(空值代表不限时长非空值代表限制时长从学生首次答题开始持续计时)</span>
</div>
</p>
<p className="">
<div className={"h21"}>
<div className={" mb10 mt5 mr10 font-16 color-grey-6"}>答题显示</div>
<p className="clearfix mb20 mt20 pl33">
<Form.Item className="fl pollForm">
{getFieldDecorator('question_random')
(
<Checkbox disabled={this.props.isAdmin()===true?!flagPageEdit:true} className="mr15 font-16 color-grey-6" checked={question_random} onChange={this.questionrandom}>题目顺序随机打乱</Checkbox>
)}
</Form.Item>
<span className="color-grey-c">(选中则学生答题时题目顺序按照题型随机显示</span>
</p>
<p className="clearfix pl33">
<Form.Item className="fl pollForm">
{getFieldDecorator('choice_random')
(
<Checkbox disabled={this.props.isAdmin()===true?!flagPageEdit:true} className="mr15 font-16 color-grey-6" checked={choice_random} onChange={this.choicerandom}>选项顺序随机打乱</Checkbox>
)}
</Form.Item>
<span className="color-grey-c">(选中则学生答题时选项顺序随机显示</span>
</p>
</div>
</p>
</div>
</div>
<div className="padding20-30">
<p className="mb30 clearfix font-16">属性设置</p>
<div className="pl33">
<p className="mb20">
<Form.Item className="fl pollForm">
{getFieldDecorator('score_open')
(
<Checkbox disabled={this.props.isAdmin()===true?!flagPageEdit:true} className="mr15 font-16 color-grey-6" checked={score_open} onChange={this.ChangeFlagPublic}>公开成绩</Checkbox>
)}
</Form.Item>
<span className="color-grey-c">(选中则在试卷截止时间之后已提交答题的学生可以查看其它学生的成绩否则只能查看自己的成绩)</span>
</p>
<p className="clearfix mb20">
<Form.Item className="fl pollForm">
{getFieldDecorator('answer_open')
(
<Checkbox disabled={this.props.isAdmin()===true?!flagPageEdit:true} className="mr15 font-16 color-grey-6" checked={answer_open} onChange={this.ChangeFlagName}>公开答案</Checkbox>
)}
</Form.Item>
<span className="color-grey-c">(选中则在试卷截止时间之后已提交答题的学生可以查看试卷题目的答案否则不能查看)</span>
</p>
<p className="clearfix mb20">
<Form.Item className="fl pollForm">
{getFieldDecorator('show_statistic')
(
<Checkbox disabled={this.props.isAdmin()===true?!flagPageEdit:true} className="mr15 font-16 color-grey-6" checked={show_statistic} onChange={this.showstatistic}>公开统计</Checkbox>
)}
</Form.Item>
<span className="color-grey-c">(选中则在试卷截止时间之后已提交答题的学生可以查看答题统计否则不能查看)</span>
</p>
<p className="clearfix mb5">
<Form.Item className="fl pollForm">
{getFieldDecorator('assistantauthority')
(
<Checkbox disabled={this.props.isAdmin()===true?!flagPageEdit:true} className="mr15 font-16 color-grey-6" checked={this.state.assistant_auth} onChange={this.assistantauthority}>助教权限</Checkbox>
)}
</Form.Item>
<span className="color-grey-c">(选中则允许助教查看答案)</span>
</p>
</div>
</div>
</div>
{
flagPageEdit&&this.props.isAdmin()===true ?
<div className="clearfix mt30 ml40" style={{paddingBottom:'40px'}}>
<Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">提交</Button>
<a className="defalutCancelbtn fl" onClick={this.cancelEdit}>取消</ a>
</div>
:""
}
</Form>
</div>
)
}
}
const WrappedExercisesetting = Form.create({ name: 'exercisesetting' })(Exercisesetting);
export default WrappedExercisesetting;

View File

@ -1,367 +0,0 @@
import React, {Component} from "react";
import {MarkdownToHtml,mdJSONParse} from 'educoder';
import {Checkbox,Pagination} from "antd";
import axios from 'axios';
import Exercisetablesmubu from './Exercisetablesmubu';
import Exercisestatisticalresulttabel from './Exercisestatisticalresulttabel';
import '../css/members.css';
import '../css/busyWork.css';
import '../poll/pollStyle.css';
const CheckboxGroup = Checkbox.Group;
const $ = window.$
function createMarkup(value) { return {__html:value} };
class Exercisestatisticalresult extends Component {
constructor(props) {
super(props);
this.state = {
data:undefined,
sort:"asc",
exercise_group_id:[],
page:1,
limit:10,
searchtext:"",
order: "end_at",
}
}
componentDidMount() {
let{sort,exercise_group_id,page,limit}=this.state;
this.updatefun(sort,exercise_group_id,page,limit);
try {
this.props.triggerRef(this);
}catch (e) {
}
}
_getRequestParams() {
const { order, exercise_group_id,searchtext, page ,limit} = this.state
return {
page,
search:searchtext,
order,
limit: limit,
group_id:exercise_group_id,
}
}
updatefun=(sort,exercise_group_id,page,limit)=>{
let ExerciseId=this.props.match.params.Id;
let url = `/exercises/`+ExerciseId+`/exercise_result.json`;
axios.get(url,{
params:{
sort:sort,
exercise_group_id:exercise_group_id,
page:page,
limit:limit
}
}).then((result) => {
this.setState({
data:result.data
})
}).catch((error) => {
console.log(error)
})
}
onSortTypeChange=()=>{
let{exercise_group_id,page,limit,sort}=this.state;
let newdesc="asc";
if(sort==="desc"){
newdesc="asc"
}else{
newdesc="desc"
}
this.setState({
sort:newdesc
})
this.updatefun(newdesc,exercise_group_id,page,limit)
}
funtaskstatustwo=(checkedValues,list)=>{
let{sort,page,limit}=this.state;
// if(checkedValues.length===list.length){
// this.setState({
// exercise_group_id:[]
// })
// }else{
//
// }
this.setState({
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;
this.setState({
page:pageNumber
})
$('html').animate({
scrollTop: 10
}, 1000);
this.updatefun(sort,exercise_group_id,pageNumber,limit)
}
render() {
let{data,sort,page,limit} =this.state;
let choicetype=["满分作答","部分得分作答","零分作答","未批"]
return (
<div className=" ">
<style>
{`
div{
color: rgba(0, 0, 0, 0.65);
}
`}
</style>
<div className={"educontent mb30" } >
{data&&data.course_groups.length===0?"":<div className="stud-class-set">
<div className="clearfix edu-back-white">
<ul className="clearfix" style={{padding:'20px'}}>
<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"}
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) => {
return (
<span key={key}>
<Checkbox value={item.exercise_group_id}
key={item.exercise_group_id}
// checked={course_group_info === undefined ? false : course_group_info[key].course_group_id === item.course_group_id ? true : false}
className="fl ">{item.exercise_group_name}
<span>({item.exercise_group_students})</span>
</Checkbox>
</span>
)
})}
</CheckboxGroup>
</li>
</ul>
</div>
</div>}
<div className="stud-class-set">
<div className="clearfix edu-back-white exerciseTable ">
<Exercisestatisticalresulttabel
data={data}
/>
</div>
</div>
<style>
{`
.fafafa{
background: #fafafa;
height:50px;
}
.drop_down_normal li{
text-align: center;
}
.mr33{
margin-right: 33px;
}
.fiilssort{
position: absolute;
top: -9px;
}
`}
</style>
<div className="stud-class-set fafafa">
<li className="fl mt10 cursor zexercisetitle">统计详情</li>
<li className="drop_down fr mt10 cursor zexercisetitle" onClick={() => this.onSortTypeChange()}>
{/*{sort==="percent"?"正确率":sort==="type"?"题型":sort==="position"?"题序":""}*/}
{/*<i className="iconfont icon-xiajiantou font-12 ml2"></i>*/}
{/*<ul className="drop_down_normal">*/}
{/*{sort==='percent'?"":<li onClick={() => this.onSortTypeChange('percent')}>正确率</li>}*/}
{/*{sort==='type'?"":<li onClick={() => this.onSortTypeChange('type')}>题型</li>}*/}
{/*{sort==='position'?"":<li onClick={() => this.onSortTypeChange('position')}>题序</li>}*/}
{/*</ul>*/}
正确率
<sapn className="relativef ml5"style={{"top":"3px"}} >
<i className={sort==="asc"?
"iconfont icon-sanjiaoxing-up font-12 color-blue fiilssort" :"iconfont icon-sanjiaoxing-up font-12 fiilssort"}></i>
<i className={sort==="desc"?
"iconfont icon-sanjiaoxing-down font-12 yslbottomsj color-blue":"iconfont icon-sanjiaoxing-down font-12 yslbottomsj"}></i>
</sapn>
</li>
</div>
<style>
{`
.CACFF{
color:#4CACFF;
}
.C3333{
color:#333;
}
.bor-greyE{
border: 1px solid #EEEEEE!important;
}
.padtop24{
padding-top: 24px;
}
.exerciseTable .shixunreporttitle{
padding:0px!important;
}
.exerciseTable .ant-table-thead > tr > th,.exerciseTable .ant-table-tbody > tr > td{
padding:16px 20px!important;
}
.exerciseTable .editormd-html-preview{
width:100%!important;
}
`}
</style>
{/* 从子组件将样式提出来,不然会循环多次 */}
<style>{`
// .ant-table-thead > tr > th{
// text-align: center;
// }
.tasknamebox{
width: 50px;
height: 24px;
border: 1px solid rgba(221,23,23,1);
border-radius: 12px;
color: rgba(221,23,23,1);
display: inline-block;
line-height: 24px;
text-align: center;
}
.tasknameboxs{
color: #666666 !important;
background:rgba(237,237,237,1) !important;
}
.ant-table-tbody > tr > td{
font-size:14px;
}
.task-hide{
max-width: 345px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
// .ant-table-tbody > tr{
// height:64px;
// text-align: center;
// }
.ant-progress-success-bg, .ant-progress-bg{
background-color: #29BD8B !important;
}
.ant-table-thead > tr > th:nth-child(1){
text-align: left;
}
.ant-table-tbody > tr > td:nth-child(1){
text-align: left;
}
.Exermubu .ant-table-tbody > tr:nth-last-child(1) > td{
border:1px solid transparent;
}
.Exermubu .editormd-html-preview, .Exermubu .editormd-preview-container {
background: transparent;
}
`}
</style>
{data&&data.commit_results.map((item,key)=>{
return(
<div className="stud-class-set mb20 exerciseTable" key={key}>
<div className="clearfix edu-back-white poll_list" style={{padding: '20px'}}>
<div className="font-16 shixunreporttitle fl" style={{width:"1050px"}}>
<span
className="C3333">{item.ques_position + "."}{item.ques_type === 0 ? "单选" : item.ques_type === 1 ? "多选" : item.ques_type === 2 ? "判断" : item.ques_type === 3 ? "填空" : item.ques_type === 4 ? "主观" : item.ques_type === 5 ? "实训" :item.ques_type === 6 ? "编程" : ""}</span>
<div>
{/*Q{item.ques_position}*/}
{/* <div className={"markdown-body"} dangerouslySetInnerHTML={{__html: markdownToHTML1(item.ques_title).replace(/▁/g,"▁▁▁")}}></div> */}
<MarkdownToHtml content={mdJSONParse(item.ques_title)} selector={'ques_title_' + key}
className=""
></MarkdownToHtml>
{/*<span className="markdown-body" dangerouslySetInnerHTML={createMarkup(item.ques_title)}></span>*/}
</div>
</div>
<div className="fr shixunreporttitles mt3">正确率<span style={{color:'#FF6800'}}> {item.right_percent}%</span></div>
</div>
{item.ques_type===5?
item.ques_details.map((ite,k)=>{
return(
<div>
<div className="clearfix edu-back-white poll_list mb10" style={{padding: '0px 20px'}}>
<div className="font-16 shixunreporttitle fl pt20 pb20">
<span>{ite.challenge_position}{ite.challenge_name}</span>
</div>
<div className="fr shixunreporttitles">正确率<span style={{color:'#FF6800'}}> {ite.challenge_percent}%</span></div>
</div>
<Exercisetablesmubu
{...this.state}
tableNum={`${key}${k}`}
datass={ite.challenge_details}
type={item.ques_type}
effictive_counts={item.effictive_counts}
choicetype={choicetype}
/>
</div>
)
}):
<Exercisetablesmubu
{...this.state}
tableNum={key}
datass={item.ques_details}
type={item.ques_type}
effictive_counts={item.effictive_counts}
choicetype={choicetype}
/>}
</div>
)
})}
</div>
{
data && data.questions_count > 10 &&
<div className="mb40 edu-txt-center padding20-30">
<Pagination
showQuickJumper
defaultCurrent={1}
pageSize={limit}
total={ data && data.questions_count }
current={page}
onChange={this.PaginationCourse}
/>
</div>
}
</div>
)
}
}
export default Exercisestatisticalresult;

View File

@ -1,190 +0,0 @@
import React, {Component} from "react";
import {Table} from "antd";
class OfficialAcademicTranscript extends Component {
constructor(props) {
super(props);
this.state = {
loadingstate:true,
datas:undefined
}
}
componentDidMount() {
}
render() {
let {data}=this.props;
let datas=[];
// data&&data.exercise_counts.forEach((item,key)=>{ })
datas.push({
commit_percent:data&&data.exercise_counts.commit_percent,
min_score:data&&data.exercise_counts.min_score,
max_score:data&&data.exercise_counts.max_score,
average_score:data&&data.exercise_counts.average_score,
fail_counts:data&&data.exercise_counts.fail_counts,
pass_counts:data&&data.exercise_counts.pass_counts,
good_counts:data&&data.exercise_counts.good_counts,
best_counts:data&&data.exercise_counts.best_counts,
})
let columns=[{
title: '提交率',
dataIndex: 'commit_percent',
key: 'commit_percent',
render: (text, record) => (
<span style={{color:'#333333'}}>
{record.commit_percent===0?0:(record.commit_percent*100).toFixed(2)}<span className={"font-size12"}>%</span>
</span>
),
}, {
title: '最低分',
dataIndex: 'min_score',
key: 'min_score',
render: (text, record) => (
<span>
<span style={{color:'#333333'}}>{record.min_score}<span className={"font-size12"}></span></span>
</span>
),
}, {
title: '最高分',
dataIndex: 'max_score',
key: 'max_score',
render: (text, record) => (
<span style={{color:'#FF6800'}}>
{record.max_score}<span className={"font-size12"}></span>
</span>
),
}, {
title: '平均分',
key: 'average_score',
dataIndex: 'average_score',
render: (text, record) => (
<span style={{color:'#333333'}}>
{record.average_score}<span className={"font-size12"}></span>
</span>
),
}, {
title: '不及格(得分 低于60%',
key: 'fail_counts',
dataIndex: 'fail_counts',
render: (text, record) => (
<span style={{color:'#333333'}}>
{record.fail_counts}<span className={"font-size12"}></span>
</span>
),
}, {
title: '及格(得分 60%~70%',
key: 'pass_counts',
dataIndex: 'pass_counts',
render: (text, record) => (
<span style={{color:'#333333'}}>
{record.pass_counts}<span className={"font-size12"}></span>
</span>
),
}, {
title: '良好(得分 70%~90%',
key: 'good_counts',
dataIndex: 'good_counts',
render: (text, record) => (
<span>
<span style={{color:'#333333'}}>{record.good_counts}<span className={"font-size12"}></span></span>
</span>
),
}, {
title: '优秀(得分 90%~100%',
key: 'best_counts',
dataIndex: 'best_counts',
render: (text, record) => (
<span>
<span style={{color:'#FF6800'}}>{record.best_counts}<span className={"font-size12"}></span></span>
</span>
),
}];
// {
// title: '调分',
// key: 'adjustmentminute',
// dataIndex: 'adjustmentminute',
//
// render: (text, record) => (
// <span>
// <a>6小时 50分钟 6秒</a>
// </span>
// ),
// },
return (
<div>
{/*{data===undefined?"":""}*/}
<style>{`
.ant-table-thead > tr > th{
text-align: center;
}
.tasknamebox{
width: 50px;
height: 24px;
border: 1px solid rgba(221,23,23,1);
border-radius: 12px;
color: rgba(221,23,23,1);
display: inline-block;
line-height: 24px;
text-align: center;
}
.tasknameboxs{
color: #666666 !important;
background:rgba(237,237,237,1) !important;
}
.ant-table-tbody > tr > td{
font-size:14px;
}
.task-hide{
max-width: 345px;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ant-table-tbody > tr{
height:64px;
text-align: center;
}
.exerctabel .ant-table-tbody > tr >td{
border:1px solid transparent;
}
.exerctabel .ant-table-thead > tr > th {
background: #fff !important;
border-top: 1px solid #F4F4F4;
border-bottom: 1px solid #F4F4F4 !important;
}
`}
</style>
{datas===undefined?"":<Table
className={"exerctabel"}
dataSource={datas}
columns={columns}
pagination={false}
// loading={loadingstate}
// onChange={this.TablePagination}
/>}
</div>
)
}
}
export default OfficialAcademicTranscript;

View File

@ -1,142 +0,0 @@
import React, {Component} from "react";
import {MarkdownToHtml} from 'educoder';
import {Table,Progress} from "antd";
const tagArray = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]
class Exercisetablesmubus extends Component {
constructor(props) {
super(props);
this.state = {
loadingstate:true,
}
}
componentDidMount() {
}
render() {
let {datass,type,effictive_counts,choicetype, tableNum}=this.props;
let list=[];
datass&&datass.forEach((item,key)=>{
list.push({
commit_percent:{
num:item.choice_position,
value:type===4||type===5?choicetype[item.choice_text-1]:item.choice_text,
type:item.choice_right_boolean,
_type: type
},
min_score:{value:item.choice_users_count,type:item.choice_right_boolean},
max_score:item.choice_percent,
})
})
list.push({
commit_percent: {num:null,value:"有效填写量"},
min_score:{value:effictive_counts},
})
let columns=[]
if(list.length!=0){
columns=[{
title: '选项',
dataIndex: 'commit_percent',
key: 'commit_percent',
render: (text, record, index) => {
const _content = <span style={{color:text.type===true? "#29BD8B":'#333333', width: '100%'}}>
{text.value>0&&text.value!="有效填写量"&&text.value!="wrong"||!text.value&&text.value!="有效填写量"&&text.value!="wrong"?
text.value===1?"满分":text.value===2?"部分得分":text.value===3?"零分":text.value:text.value!="有效填写量"&&text.value!="wrong"&&<MarkdownToHtml content={text.value} selector={(tableNum+1) + '' + (index+1)}></MarkdownToHtml>
}
{text.value==="wrong" && "填写了错误答案" }
{text.value==="有效填写量" && "有效填写量" }
</span>
return (
(text._type === 0 || text._type === 1) ? <div style={{ display: 'flex'}}>
{<span style={{ 'margin-right': '4px', 'margin-top': '-2px'}}>{tagArray[index]}.</span>}
{_content}
</div> : <React.Fragment>{_content}</React.Fragment>
)
},
}, {
title: '小计',
dataIndex: 'min_score',
key: 'min_score',
align: 'center',
width:'200px',
render: (text, record) => (
<span>
<span style={{color:text.type===true? "#29BD8B":'#333333'}}>{text.value}</span>
</span>
),
}, {
title: '百分比',
dataIndex: 'max_score',
key: 'max_score',
align: 'center',
width:'300px',
render: (text, record) => (
<span style={{color:'#FF6800'}}>
{record.max_score===undefined?"":<span>
<div style={{
float: 'left',
width: '220px'
}}><Progress
strokeColor={{
'0%': '#29BD8B',
'100%': '#29BD8B',
}}
percent={(record.max_score*100).toFixed()} showInfo={false}/></div><div className={"fr"}>{(record.max_score*100).toFixed()}%</div></span>}
</span>
),
}];
}
return (
<div>
<style>{`
.Exermubu .ant-table-thead > tr > th {
background: #fff !important;
border-bottom: 1px solid #F4F4F4 !important;
}
.Exermubu .ant-table-thead .ant-table-column-title{
color:#999999;
}
.Exermubu .ant-table-tbody> tr > td{
border-bottom: transparent;
}
`}
</style>
{list===undefined?"":<Table
className={"Exermubu"}
dataSource={list}
columns={columns}
pagination={false}
// loading={loadingstate}
// onChange={this.TablePagination}
/>}
</div>
)
}
}
export default Exercisetablesmubus;

File diff suppressed because it is too large Load Diff

View File

@ -1,532 +0,0 @@
import React,{ Component } from "react";
import {Checkbox,Input,Table, Pagination,Menu,Spin} from "antd";
import {Link,NavLink} from 'react-router-dom';
import { WordsBtn ,getRandomNumber,queryString,getRandomcode} from 'educoder';
import CoursesListType from '../coursesPublic/CoursesListType';
import '../css/members.css';
import '../css/busyWork.css';
import axios from 'axios';
import Modals from '../../modals/Modals';
import DownloadMessageysl from "../../modals/DownloadMessageysl";
import Studentshavecompletedthelist from './Studentshavecompletedthelist';
import WrappedExercisesetting from './Exercisesetting';
import ExerciseDisplay from './ExerciseDisplay'
import Exercisestatisticalresult from './Exercisestatisticalresult';
import ImmediatelyPublish from "../poll/pollPublicBtn/ImmediatelyPublish";
import ImmediatelyEnd from "../poll/pollPublicBtn/ImmediatelyEnd";
import Ecerciseallbackagain from './Ecerciseallbackagain';
const polls_status={1:"未发布",2:"考试中",3:"已截止",4:"已结束"}
const start_Value={0:"继续答题",1:"查看答题",2:"开始答题"}
const qs = require('qs');
//试卷主要设置页面
class Testpapersettinghomepage extends Component{
constructor(props) {
super(props);
this.state={
tab:["0"],
searchtext:"",
Commonheadofthetestpaper:undefined,
visible:false,
groupyslsval:"",
current_status:undefined,
DownloadType:false,
DownloadMessageval:undefined,
donwloading:false,
exercise_status:3,
assistant_auth:false, //设置助教
}
}
//切换tab
changeTab=(e)=>{
this.setState({
tab:e.key
})
// this.props.history.push(`/classrooms/${this.props.match.params.coursesId}/exercises/${this.props.match.params.Id}/student_exercise_list?tab=`+e.key)
}
componentDidMount(){
const query =this.props.location.search;
const type = query.split('?tab=');
let sum = []
sum.push(type[1])
// console.log("componentDidMountcomponentDidMount");
// console.log(sum);
this.setState({
tab:sum,
})
this.Commonheadofthetestpaper();
}
//试卷公用头部
Commonheadofthetestpaper=()=>{
// console.log("Commonheadofthetestpaper 试卷公用头部");
var exercise_id = this.props.match.params.Id;
var url = `/exercises/${exercise_id}/common_header.json`;
axios.get(url).then((response) => {
// console.log(JSON.stringify(response));
try {
if(response.status === 200){
this.setState({
Commonheadofthetestpaper:response.data,
current_status:response.data.user_permission.current_status,
exercise_status:response.data.exercise_status,
assistant_auth:response.data.assistant_auth,
})
// console.log(JSON.stringify(response.data.show_statistic));
}
}catch (e) {
}
}).catch((error) => {
console.log(error)
});
}
assistantauthoritys=(bool)=>{
this.setState({
assistant_auth:bool,
})
}
Ecerciseacallagain=()=>{
this.setState({
visible:true
})
}
callback=(val)=>{
this.setState({
visible:false
})
if(val===1){
window.location.reload()
}
}
moveTos=(val)=>{
if(val===0){
}
}
setcourse_groupysls=(val)=>{
let list="";
val.map((item,key)=>{
if(item!=undefined){
list=list+"&exercise_group_id[]="+item
}
})
this.setState({
groupyslsval:list
})
}
// experiment=(url)=>{
//
// axios.get(url).then((response) => {
// console.log(response);
// if(response.data.status&&response.data.status===-1){
//
// }else if(response.data.status&&response.data.status===-2){
// if(response.data.messages === "100"){
// // 已超出文件导出的上限数量100 ),建议:
// this.setState({
// DownloadType:true,
// DownloadMessageval:100
// })
// }else {
// //因附件资料超过500M
// this.setState({
// DownloadType:true,
// DownloadMessageval:500
// })
// }
// }else {
// window.open("/api"+url, '_blank');
// }
// }).catch((error) => {
// console.log(error)
// });
//
// }
setgameexercise=(url)=>{
let{Commonheadofthetestpaper}=this.state;
if(Commonheadofthetestpaper.time>0){
this.setState({
Modalstype:true,
ModalSave:()=>this.props.history.push(url),
Modalstopval:`答题时长限制${Commonheadofthetestpaper.time}分钟,从首次答题开始实行不间断计时`,
modalsBottomval:'请确认是否有充足的答题时间?',
});
}else{
this.setState({
Modalstype:true,
ModalSave:()=>this.props.history.push(url),
Modalstopval:"是否确认开始答题?",
modalsBottomval:' ',
})
}
}
//打开pdf
confpdf = (url) =>{
window.open(url);
}
/// 确认是否下载
confirmysl(url,child){
let params ={}
if(child!=undefined){
params =child._getRequestParams()!==undefined?child._getRequestParams():{};
}
const urll=url+`?${queryString.stringify(params)}`;
axios.get(urll+ '&export=true').then((response) => {
if(response===undefined){
return
}
if(response.data.status&&response.data.status===-1){
}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
})
}
}else {
this.props.slowDownload(getRandomcode(urll))
// this.setState({ donwloading: true })
// downloadFile({
// url: urll,
// successCallback: (url) => {
// this.setState({ donwloading: false })
// console.log('successCallback')
// },
// failCallback: (responseHtml, url) => {
// this.setState({ donwloading: false })
// console.log('failCallback')
// }
// })
// this.props.showNotification(`正在下载中`);
// window.open("/api"+url+`?${queryString.stringify(params)}`+ '&export=true', '_blank');
}
}).catch((error) => {
console.log(error)
});
}
Downloadcal=()=>{
this.setState({
DownloadType:false,
DownloadMessageval:undefined
})
}
cancelmodel=()=>{
this.setState({
Modalstype:false,
ModalSave:' ',
Modalstopval:' ',
modalsBottomval:' ',
Loadtype:false
})
}
// DownloadType=()=>{
// this.setState({
// DownloadType:false,
// DownloadMessageval:undefined
// })
// }
// Downloadcal=()=>{
// this.setState({
// DownloadType:false,
// DownloadMessageval:undefined
// })
// }
getsetdata =()=>{
// console.log("Testpapersettinghomepage");
// console.log("getsetdatassssss");
let{tab}=this.state;
try {
if(tab[0]==="0"){
this.child.Teacherliststudentlist();
}
if(tab[0]==="1"){
this.child.Teacherliststudentlist();
}
if(tab[0]==="2"){
this.child.Teacherliststudentlist();
}
if(tab[0]==="3"){
this.child.getSettingInfo();
}
}catch (e) {
}
}
bindRef = ref => { this.child = ref };
goback=()=>{
// let {datalist}=this.state;
// let courseId=this.props.match.params.coursesId;
// let category_id=this.props.match.params.category_id;
//
// window.location.href="/classrooms/"+courseId+"/graduation_tasks/"+datalist.graduation_id;
// let courseId=this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/classrooms");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
this.props.history.goBack()
}
render(){
let {tab,visible,Commonheadofthetestpaper,exercise_status,assistant_auth}=this.state;
const isAdmin =this.props.isAdmin();
const isAssistant=this.props.isAssistant();
const isStudent = this.props.isStudent();
// TODO
//console.log(Commonheadofthetestpaper.exercise_status);
document.title=this.props.coursedata&&this.props.coursedata.name;
return(
<div className="newMain clearfix ">
{/*<DownloadMessage*/}
{/* {...this.props}*/}
{/* value={this.state.DownloadMessageval}*/}
{/* modalCancel={this.Downloadcal}*/}
{/* modalsType={this.DownloadType}*/}
{/*/>*/}
<div className={"educontent mb20"} style={{width:"1200px"}}>
{/* 公用的提示弹框 */}
{this.state.Modalstype===true?<Modals
modalsType={this.state.Modalstype}
modalsTopval={this.state.Modalstopval}
modalsBottomval={this.state.modalsBottomval}
loadtype={this.state.Loadtype}
modalCancel={this.cancelmodel}
modalSave={this.state.ModalSave}
antIcon={this.state.Modalstypeloding}
></Modals>:""}
{visible===true?<Ecerciseallbackagain
{...this.props}
modalname={"打回重做"}
visible={visible}
callback={this.callback}
/>:""}
<div className="educontent mb20" style={{width:"1200px"}}>
<p className="clearfix mb20 mt10">
<Link className=" btn colorgrey fl hovercolorblue " to = {`/classrooms/${this.props.match.params.coursesId}`} >{this.props.coursedata.name}</Link>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<Link className=" btn colorgrey fl hovercolorblue " to={`/classrooms/${this.props.match.params.coursesId}/exercises/${Commonheadofthetestpaper&&Commonheadofthetestpaper.user_permission.left_banner_id}`} >试卷</Link>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<WordsBtn className="fl">试卷详情</WordsBtn>
</p>
</div>
<style>
{`
.summaryname{
line-height: 23px;
cursor: pointer;
}
`}
</style>
<div className="educontent" style={{width:"1200px"}}>
<p className=" fl color-black summaryname ">
{Commonheadofthetestpaper === undefined?"":Commonheadofthetestpaper.exercise_name}
</p>
<CoursesListType
typelist={[`${polls_status[Commonheadofthetestpaper && Commonheadofthetestpaper.exercise_status]}`]}
/>
<Link className="color-grey-6 fr font-16 summaryname mr30" to={`/classrooms/${this.props.match.params.coursesId}/exercises/${Commonheadofthetestpaper&&Commonheadofthetestpaper.user_permission.left_banner_id}`}>返回</Link>
<p className="color-grey-6 fr font-16"> </p>
</div>
<div className="edu-back-white mt10" >
<div className="stud-class-set bor-bottom-greyE ">
<div className=" clearfix edu-back-white pl30 pr30">
<div className="fl task_menu_ul">
{isAssistant===true?
(
assistant_auth===true?
<Menu mode="horizontal" selectedKeys={tab} onClick={this.changeTab}>
<Menu.Item key="0" className={"exercisesafonts"}>答题列表</Menu.Item>
<Menu.Item key="1" className={"exercisesafonts"}>统计结果</Menu.Item>
<Menu.Item key="2" className={"exercisesafonts"}>试卷预览</Menu.Item>
<Menu.Item key="3" className={"exercisesafonts"}>设置</Menu.Item>
</Menu>
:
<Menu mode="horizontal" selectedKeys={tab} onClick={this.changeTab}>
<Menu.Item key="0" className={"exercisesafonts"}>答题列表</Menu.Item>
{Commonheadofthetestpaper&&Commonheadofthetestpaper.show_statistic===true?
Commonheadofthetestpaper && Commonheadofthetestpaper.exercise_status===3?
<Menu.Item key="1" className={"exercisesafonts"}>统计结果</Menu.Item>:"":""}
<Menu.Item key="3" className={"exercisesafonts"}>设置</Menu.Item>
</Menu>
)
:
this.props.isAdmin()===true?
<Menu mode="horizontal" selectedKeys={tab} onClick={this.changeTab}>
<Menu.Item key="0" className={"exercisesafonts"}>答题列表</Menu.Item>
<Menu.Item key="1" className={"exercisesafonts"}>统计结果</Menu.Item>
<Menu.Item key="2" className={"exercisesafonts"}>试卷预览</Menu.Item>
<Menu.Item key="3" className={"exercisesafonts"}>设置</Menu.Item>
</Menu>
:
<Menu mode="horizontal" selectedKeys={tab} onClick={this.changeTab}>
<Menu.Item key="0" className={"exercisesafonts"}>答题列表</Menu.Item>
{Commonheadofthetestpaper&&Commonheadofthetestpaper.show_statistic===true?
Commonheadofthetestpaper && Commonheadofthetestpaper.exercise_status===3?
<Menu.Item key="1" className={"exercisesafonts"}>统计结果</Menu.Item>:"":""}
<Menu.Item key="3" className={"exercisesafonts"}>设置</Menu.Item>
</Menu>
}
</div>
{/*导出这块应该是下拉 因为需要前端导出,目前就只导出学生成绩*/}
{/*{isAdmin === true? <WordsBtn className="fr color-blue font-16">导出成绩</WordsBtn>:""}*/}
<style>
{ `
.drop_down_menu{
height: 118px;
left:0px;
width: 121px;
}
.drop_down_menu li {
overflow: visible;
width: 121px;
}
.drop_down_menu li a{
padding: 0px;
font-size: 14px;
}
.mt19{
margin-top:19px;
}
.drop_down_menu, .drop_down_normal{
padding-top: 10px;
padding-bottom: 8px;
}
.exercisesafonts:hover {
color:#1A0B00 !important;
}
`}
</style>
<div className={"studentList_operation_ul mt23"}>
{isAdmin === true? <Spin spinning={this.state.donwloading} style={{ }}><li className="li_line drop_down fr color-blue font-15" style={{"paddingLeft":"0px"}}>
导出<i className="iconfont icon-xiajiantou font-12 ml2"></i>
<ul className="drop_down_menu" style={{"right":"-34px","left":"unset","height":"auto"}}>
<li><a onClick={()=>this.confirmysl(`/exercises/${this.props.match.params.Id}/exercise_lists.xlsx`,this.child)}>学生成绩</a></li>
{/* <li><a onClick={()=>this.confpdf(`/api/exercises/${this.props.match.params.Id}/export_exercise`)} >空白试卷</a></li> */}
<li><a href={getRandomcode(`/api/exercises/${this.props.match.params.Id}/export_exercise`)} target="_blank">空白试卷</a></li>
{/*<li><a onClick={()=>this.confirmysl(`/zip/export_exercises?exercise_id=${this.props.match.params.Id}${this.state.groupyslsval===null||this.state.groupyslsval===undefined?null:this.state.groupyslsval}`)}>学生答题试卷</a></li>*/}
</ul>
</li></Spin>:""}
</div>
{
isAdmin === true &&Commonheadofthetestpaper && Commonheadofthetestpaper.user_permission.user_commit_counts>0&&Commonheadofthetestpaper.exercise_status===2?
<a className="fr color-blue font-16 mt20 mr20" onClick={this.Ecerciseacallagain}>打回重做</a>:""
}
{isAdmin === true? Commonheadofthetestpaper!==undefined&&Commonheadofthetestpaper.user_permission.exercise_publish_count>0? <ImmediatelyEnd
{...this.props}
{...this.state}
className={"btn fr color-blue font-16 mt20 mr20"}
checkBoxValues={[parseInt(this.props.match.params.Id)]}
Exercisetype={"exercise"}
// single={true}
action={this.Commonheadofthetestpaper}
></ImmediatelyEnd>:"":""}
{isAdmin === true?Commonheadofthetestpaper!==undefined&&Commonheadofthetestpaper.user_permission.exercise_unpublish_count>0? <ImmediatelyPublish
{...this.props}
{...this.state}
className={"btn fr color-blue font-16 mt20 mr20"}
checkBoxValues={[parseInt(this.props.match.params.Id)]}
Exercisetype={"exercise"}
pushtype={true}
action={this.Commonheadofthetestpaper}
single={true}
getsetdata={this.getsetdata}
></ImmediatelyPublish>
:"":""}
{/*const isAdminOrTeacher*/}
{/*assistant_auth===true*/}
{/**/}
{isAdmin === true?
(
isAssistant===true?
(
assistant_auth===true?
<Link className="fr color-blue font-16 mt20 mr20" to={`/classrooms/${this.props.match.params.coursesId}/exercises/${this.props.match.params.Id}/edit`}>编辑试卷</Link>
:
""
)
:
<Link className="fr color-blue font-16 mt20 mr20" to={`/classrooms/${this.props.match.params.coursesId}/exercises/${this.props.match.params.Id}/edit`}>编辑试卷</Link>
)
:""}
{isAdmin === false && this.props.current_user !== undefined?
Commonheadofthetestpaper&&Commonheadofthetestpaper.user_permission.current_status===2?
<a className="fr color-blue font-16 mt20" onClick={()=>this.setgameexercise(`/classrooms/${this.props.match.params.coursesId}/exercises/${this.props.match.params.Id}/users/${this.props.current_user.login}`)}>开始答题</a>:
<Link className="fr color-blue font-16 mt20"
to={`/classrooms/${this.props.match.params.coursesId}/exercises/${this.props.match.params.Id}/users/${this.props.current_user.login}`}>
{exercise_status===2?start_Value[Commonheadofthetestpaper&&Commonheadofthetestpaper.user_permission.current_status]:exercise_status===3?"":exercise_status===4?"":start_Value[Commonheadofthetestpaper&&Commonheadofthetestpaper.user_permission.current_status]}
</Link>
:""}
</div>
</div>
</div>
<DownloadMessageysl
{...this.props}
value={this.state.DownloadMessageval}
modalCancel={this.Downloadcal}
modalsType={this.state.DownloadType}
/>
{
// 教师列表
parseInt(tab[0])==0 ? <Studentshavecompletedthelist {...this.props} {...this.state} assistant_auth={assistant_auth} triggerRef={this.bindRef} setcourse_groupysls={(value)=>this.setcourse_groupysls(value)} current_status = {this.state.current_status} Commonheadofthetestpaper={this.state.Commonheadofthetestpaper} yslstustate={[`${polls_status[Commonheadofthetestpaper && Commonheadofthetestpaper.exercise_status]}`]}></Studentshavecompletedthelist>:""
}
{/*统计结果*/}
{
parseInt(tab[0])==1 ? <Exercisestatisticalresult {...this.props} {...this.state} assistant_auth={assistant_auth} triggerRef={this.bindRef}></Exercisestatisticalresult>:""
}
{
parseInt(tab[0])==2 ? <ExerciseDisplay {...this.props} {...this.state} assistant_auth={assistant_auth} triggerRef={this.bindRef}></ExerciseDisplay>:""
}
{
parseInt(tab[0])==3 ? <WrappedExercisesetting Commonheadofthetestpaper={this.state.Commonheadofthetestpaper} {...this.props} {...this.state} assistant_auth={assistant_auth} triggerRef={this.bindRef} Commonheadofthetestpapers={this.Commonheadofthetestpaper} assistantauthoritys={(bool)=>this.assistantauthoritys(bool)}></WrappedExercisesetting>:""
}
</div>
</div>
)
}
}
export default Testpapersettinghomepage;

View File

@ -1,64 +0,0 @@
import React, { useState } from 'react'
import { Input, Form, Button } from 'antd'
import './index.scss'
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 24 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 24 },
},
}
const { TextArea } = Input
const TITLE_MAX_LENGTH = 60
export default ({ exercise_name = '', exercise_description, is_md, onSaveHandler, isEdit, onCancel }) => {
const [data, setData] = useState({
exercise_name,
exercise_description,
is_md
})
function onChange(prop, value) {
setData({ ...data, [prop]: value })
}
function onNameChange(e) {
onChange('exercise_name', e.target.value)
}
function onDescChange(e) {
onChange('exercise_description', e.target.value)
}
function onSave() {
onSaveHandler(data)
}
return (
<Form {...formItemLayout}>
<div className='exercise-new-form'>
<Form.Item label="试卷标题" required className="topicTitle " >
<Input placeholder={`请输入试卷标题,最大限制${TITLE_MAX_LENGTH}个字符`} maxLength={TITLE_MAX_LENGTH} className="mt5 exercicenewinputysl" value={data.exercise_name}
onChange={onNameChange} addonAfter={`${data.exercise_name.length}/${TITLE_MAX_LENGTH}`}
/>
</Form.Item>
<Form.Item label="&nbsp;&nbsp;试卷须知" >
<TextArea placeholder="请在此输入本次试卷答题的相关说明最大限制100个字符" maxLength={100} className="mt5" style={{ height: "120px" }} value={data.exercise_description} onChange={onDescChange} />
</Form.Item>
<Form.Item>
<div className="btn-group">
<Button size='default' type='primary' style={{ marginRight: 12 }} onClick={onSave}>保存</Button>
{isEdit ? null : <Button size='default' type='ghost' onClick={onCancel}>取消</Button>}
</div>
</Form.Item>
</div>
</Form >
)
}

View File

@ -1,43 +0,0 @@
.exercise-new-form {
padding: 20px 30px 2px 30px;
background: #fff;
.ant-input {
border-right: none;
height: 40px;
}
.task-btn-orange {
height: 30px;
width: 70px;
}
.btn-group {
text-align: right;
}
.editor-tip {
font-size: 16px;
font-family: PingFangSC-Semibold, PingFang SC;
font-weight: 600;
color: rgba(51, 51, 51, 1);
padding-left: 12px;
line-height: 22px;
span {
font-size: 14px;
font-weight: normal;
font-family: MicrosoftYaHei;
color: rgba(136, 136, 136, 1);
line-height: 19px;
}
}
.ant-form-item label {
overflow: hidden;
}
.ant-form-item-label {
height: 40px;
}
}

View File

@ -1,44 +0,0 @@
import React, { Component } from "react";
import { Radio } from 'antd';
import QestionDisplayHeader from './QestionDisplayHeader'
import RenderHtml from "../../../../components/render-html";
class JudgeDisplay extends Component {
render() {
let { question_choices, question_id, index, is_md } = this.props;
const qNumber = `question_${index}`;
return (
<div className="bor-bottom-greyE padding20-30" id={qNumber} _id={question_id}>
<style>{`
.optionMdEditor {
flex: 0 0 800px
}
.optionRow {
margin: 2px;
}
.actionBtns {
height: 28px
}
`}</style>
<QestionDisplayHeader {...this.props}></QestionDisplayHeader>
<div className="options clearfix">
{question_choices.map((item, optionIndex) => {
return (
<div key={optionIndex} className="fl mr30 df">
<Radio disabled className="lineh-25" checked={item.standard_boolean}></Radio>
<RenderHtml value={item.choice_text} is_md={is_md} />
</div>)
})}
</div>
</div>
)
}
}
// RouteHOC()
export default (JudgeDisplay);

View File

@ -1,197 +0,0 @@
import React, { Component } from "react";
import { InputNumber, Radio } from 'antd';
import CustomEditor from "../../../../common/components/custom-editor"
import axios from 'axios'
import { qNameArray } from './common'
import { ActionBtn, validateLength } from 'educoder';
const RadioGroup = Radio.Group;
class SingleEditor extends Component {
constructor(props) {
super(props);
/**
choice_id: 32076
choice_position: 1
choice_text: "1"
standard_boolean: true
*/
const { question_choices } = this.props;
let _standard_answers = undefined;
let _question_choices = undefined;
if (question_choices) {
_standard_answers = []
_question_choices = []
question_choices.forEach((item, index) => {
_standard_answers.push(item.standard_boolean)
_question_choices.push(item.choice_text)
})
}
this.state = {
question_choices: _question_choices || ['对', '错'],
standard_answers: _standard_answers || [false, true],
question_title: this.props.question_title || '',
question_type: this.props.question_type || 2,
question_score: this.props.question_score || this.props.init_question_score,
question_title_error: false
}
}
onSave = () => {
const { question_title, question_score, question_choices, standard_answers } = this.state;
const { question_id_to_insert_after, question_id } = this.props
// TODO check
const answerArray = standard_answers.map((item, index) => { return item == true ? index + 1 : -1 }).filter(item => item != -1);
if (!question_title || !validateLength(question_title, 10000)) {
this.setState({
question_title_error: true
})
this.props.showNotification(!question_title ? '题目:不能为空' : '题目不能超10000字符');
return;
}
const intScore = parseFloat(question_score)
if (intScore == 0) {
this.props.showNotification('分值必须大于0'); return;
} else if (!question_score || intScore == NaN) {
this.props.showNotification('分值:不能为空'); return;
}
if (!answerArray || answerArray.length == 0) {
this.props.showNotification('必须设置标准答案'); return;
}
/**
{
"question_title":"现在在下雨",
"question_type":2,
"question_score":5,
"question_choices":["正确","错误"],
"standard_answers":[1]
}
}*/
const Id = this.props.match.params.Id
if (question_id) {
const editUrl = this.props.getEditQuestionUrl(question_id);
axios.put(editUrl, {
question_title,
question_type: 2,
question_score,
question_choices,
standard_answers: answerArray,
insert_id: question_id_to_insert_after || undefined
}).then((response) => {
if (response.data.status == 0) {
this.props.addSuccess()
} else if (response.data.status == 3) {
// 已发布试卷编辑保存
this.props.changeScore(question_id, answerArray);
}
})
.catch(function (error) {
console.log(error);
});
} else {
const url = this.props.getAddQuestionUrl();
axios.post(url, {
exercise_bank_id: Id,
question_title,
question_type: 2,
question_score,
question_choices,
standard_answers: answerArray,
insert_id: question_id_to_insert_after || undefined
})
.then((response) => {
if (response.data.status == 0) {
this.props.addSuccess()
}
})
.catch(function (error) {
console.log(error);
});
}
}
onCancel = () => {
this.props.onEditorCancel()
}
componentDidMount = () => {
}
onOptionClick = (e) => {
const value = e.target.value;
if (value) {
this.setState({ standard_answers: [true, false] })
} else {
this.setState({ standard_answers: [false, true] })
}
}
on_question_score_change = (e) => {
this.setState({ question_score: e })
}
onSetQuestionTitle = (value) => {
this.setState({
question_title: value,
question_title_error: false
})
}
render() {
let { question_title, question_score, question_type, standard_answers, question_title_error } = this.state;
let { index, exerciseIsPublish, is_md } = this.props;
const qNumber = `question_${index}`;
return (
<div className="padding20-30 bor-bottom-greyE" id={qNumber}>
<style>{`
.optionMdEditor {
flex: 0 0 800px
}
.optionRow {
margin: 2px;
}
`}</style>
<p className="mb10 clearfix">
<span className="color-blue font-16 mr20 fl">{qNameArray[question_type]}</span>
<span className="color-grey-9 font-12 fl">客观题由系统自动评分请设置标准答案</span>
</p>
<CustomEditor is_md={is_md} height={is_md ? 155 : 109}
placeholder="请您输入题目"
value={question_title}
isShowEditor={true}
isError={question_title_error}
autoFocus={true}
onChange={this.onSetQuestionTitle}
/>
<div>
<RadioGroup onChange={this.onOptionClick} value={standard_answers[0]}>
<Radio value={true} >正确</Radio>
<Radio value={false} >错误</Radio>
</RadioGroup>
{!exerciseIsPublish && <span style={{ color: '#FF6800' }}>温馨提示点击选项可以直接设置标准答案</span>}
</div>
<div>
分值
<InputNumber step={0.1} precision={1} min={0} max={100} style={{ width: 100 }} value={question_score} onChange={this.on_question_score_change}
disabled={exerciseIsPublish}
></InputNumber>
<span className="fr">
<ActionBtn style="greyBack" className="middle mr20" onClick={this.onCancel}
>取消</ActionBtn>
<ActionBtn style="blue" className="middle" onClick={this.onSave}>保存</ActionBtn>
</span>
</div>
</div>
)
}
}
export default SingleEditor

View File

@ -1,42 +0,0 @@
import React, { Component } from "react";
import QestionDisplayHeader from './QestionDisplayHeader'
import RenderHtml from "../../../../components/render-html";
class MainDisplay extends Component {
render() {
let { standard_answer, question_id, index, is_md } = this.props;
const qNumber = `question_${index}`;
return (
<div className="bor-bottom-greyE padding20-30" id={qNumber} _id={question_id}>
<style>{`
.optionMdEditor {
flex: 0 0 800px
}
.optionRow {
margin: 2px;
}
.actionBtns {
height: 28px
}
`}</style>
<QestionDisplayHeader {...this.props}></QestionDisplayHeader>
{standard_answer[0] &&
<React.Fragment>
<div style={{ color: '#05101A' }} className="font-16 mb5 font-bd">参考答案</div>
<RenderHtml is_md={is_md} value={standard_answer[0]} />
</React.Fragment>
}
</div>
)
}
}
export default (MainDisplay);

View File

@ -1,189 +0,0 @@
import React, { Component } from "react"
import { InputNumber } from 'antd'
import CustomEditor from "../../../../common/components/custom-editor"
import axios from 'axios'
import { qNameArray } from './common'
import { ActionBtn, validateLength } from 'educoder'
class MainEditor extends Component {
constructor(props) {
super(props);
/**
choice_id: 32076
choice_position: 1
choice_text: "1"
standard_boolean: true
*/
const { standard_answer } = this.props;
let _standard_answers = undefined;
if (standard_answer) {
_standard_answers = standard_answer
}
this.state = {
standard_answers: _standard_answers || [''],
question_title: this.props.question_title || '',
question_type: this.props.question_type || 2,
question_score: this.props.question_score || this.props.init_question_score,
question_title_error: false,
standard_answers_error: false
}
}
onSave = () => {
const { question_title, question_score, standard_answers } = this.state;
const { question_id_to_insert_after, question_id } = this.props
const answerArray = standard_answers
if (!question_title || !validateLength(question_title, 10000)) {
this.setState({ question_title_error: true })
this.props.showNotification(!question_title ? '题目:不能为空' : '题目不能超过10000字符');
return;
}
if (!validateLength(standard_answers[0], 10000)) {
this.setState({ standard_answers_error: true })
this.props.showNotification('参考答案不能超过10000字符');
return;
}
const intScore = parseFloat(question_score)
if (intScore == 0) {
this.props.showNotification('分值必须大于0'); return;
} else if (!question_score || intScore == NaN) {
this.props.showNotification('分值:不能为空'); return;
}
/**
{
"question_title":"社会主义核心价值观是?.",
"question_type":4,
"question_score":5,
"standard_answers":["富强,民主,自由。。。"]
}
}*/
const Id = this.props.match.params.Id
if (question_id) {
const editUrl = this.props.getEditQuestionUrl(question_id);
axios.put(editUrl, {
question_title,
question_type: 4,
question_score,
standard_answers: answerArray,
insert_id: question_id_to_insert_after || undefined
})
.then((response) => {
if (response.data.status == 0) {
this.props.addSuccess()
}
})
.catch(function (error) {
console.log(error);
});
} else {
const url = this.props.getAddQuestionUrl();
axios.post(url, {
exercise_bank_id: Id,
question_title,
question_type: 4,
question_score,
standard_answers: answerArray,
insert_id: question_id_to_insert_after || undefined
})
.then((response) => {
if (response.data.status == 0) {
this.props.addSuccess()
}
})
.catch(function (error) {
console.log(error);
});
}
}
onCancel = () => {
this.props.onEditorCancel()
}
on_question_score_change = (e) => {
this.setState({ question_score: e })
}
onSetQuestionTitle = (value) => {
this.setState({
question_title: value,
question_title_error: false
})
}
onSetAnswer = (value) => {
this.setState({
standard_answers: [value],
standard_answers_error: false
})
}
render() {
let { question_title, question_score, question_type, standard_answers, standard_answers_error, question_title_error } = this.state;
let { index, exerciseIsPublish, is_md } = this.props;
const qNumber = `question_${index}`;
return (
<div className="padding20-30 bor-bottom-greyE" id={qNumber}>
<style>{`
.optionMdEditor {
flex: 0 0 800px
}
.optionRow {
margin: 2px;
}
`}</style>
<p className="mb10 clearfix">
{/*!question_id ? '新建' : '编辑'*/}
<span className="color-blue font-16 mr20 fl">{qNameArray[question_type]}</span>
<span className="color-grey-9 font-12 fl">主观题未作答的情况下自动评为零分</span>
</p>
<CustomEditor is_md={is_md} height={is_md ? 155 : 109}
placeholder="请您输入题目"
value={question_title}
isShowEditor={true}
md_id='question-editor-1'
isError={question_title_error}
autoFocus={true}
onChange={this.onSetQuestionTitle}
/>
<div>
<div className="mb10 font-16">参考答案</div>
<CustomEditor is_md={is_md} height={is_md ? 155 : 109}
placeholder="请您输入参考答案(可选)"
value={standard_answers[0] || ''}
md_id='answer-editor'
isShowEditor={true}
isError={standard_answers_error}
autoFocus={true}
onChange={this.onSetAnswer}
/>
</div>
<div className="mt10">
分值
<InputNumber step={0.1} precision={1} min={0} max={100} style={{ width: 100 }} value={question_score} onChange={this.on_question_score_change}
disabled={exerciseIsPublish}
></InputNumber>
<span className="fr">
<ActionBtn style="greyBack" className="middle mr20" onClick={this.onCancel}
>取消</ActionBtn>
<ActionBtn style="blue" className="middle" onClick={this.onSave}>保存</ActionBtn>
</span>
</div>
</div>
)
}
}
// RouteHOC()
export default (MainEditor);

View File

@ -1,55 +0,0 @@
import React, { Component } from "react";
import { Tooltip, Input } from 'antd';
const { TextArea } = Input
class NullChildEditor extends Component {
render() {
let { index, onAnswerChange, addChildAnswer, exerciseIsPublish, answers, activeOptionErrorIndex } = this.props;
return (
<div className="df" >
<div className="color-grey-6 mb5 mt6" style={{ flex: '0 0 90px' }}>答案(填空{index + 1}):</div>
<div className="df flex1" style={{ flexDirection: 'column' }}>
{
answers.map((item, itemIndex) => {
let cid = `${index}-${itemIndex}`
return <div className="df flex1" key={itemIndex} >
<div className="flex1" style={{ flex: '0 0 1000px' }}>
<div className={cid === activeOptionErrorIndex ? 'text-area-editor error' : 'text-area-editor'}>
<TextArea rows={4} value={item || ''} defaultValue={`请输入参考答案${itemIndex == 0 ? '' : '(可选)'}`} onChange={
event => onAnswerChange(index, itemIndex, event.target.value)
} />
</div>
</div>
{!exerciseIsPublish &&
<React.Fragment>
{itemIndex != 0 && <Tooltip title="删除">
<i className="iconfont icon-htmal5icon19 font-18 color-grey-c ml10"
onClick={() => this.props.deleteChildAnswer(index, itemIndex)}
style={{ float: 'right' }}
></i>
</Tooltip>}
{itemIndex === 0 && <Tooltip title="删除">
<i className="iconfont icon-htmal5icon19 font-18 color-grey-c ml10"
onClick={() => this.props.deleteChildAnswermain(index, itemIndex)}
style={{ float: 'right' }}
></i>
</Tooltip>}
{<Tooltip title={`新增参考答案`}>
<i className="color-green font-16 iconfont icon-roundaddfill ml6"
onClick={() => addChildAnswer(index)}
style={{ float: 'right', visibility: itemIndex == answers.length - 1 ? '' : 'hidden', marginTop: '2px' }}
></i>
</Tooltip>}
</React.Fragment>
}
</div>
})
}
</div>
</div>
)
}
}
export default NullChildEditor;

View File

@ -1,40 +0,0 @@
import React, { Component } from "react";
import QestionDisplayHeader from './QestionDisplayHeader'
class NullDisplay extends Component {
render() {
let { standard_answer, question_id, index, } = this.props;
const qNumber = `question_${index}`;
/**
is_ordered: true
multi_count: 3
question_id: 10444
question_number: 6
question_score: 2
question_title: "_2323_↵↵_"
question_type: 3
standard_answer: [{choice_id: 1, answer_text: ["2", "22"]}]
*/
return (
<div className="bor-bottom-greyE padding20-30" id={qNumber} _id={question_id}>
<QestionDisplayHeader {...this.props}></QestionDisplayHeader>
<div className="options">
{
standard_answer.map((answers, _index) => {
return <div className="answer-row" key={_index}>
<span className="lineh-40">答案填空{_index + 1}</span>
<div className="answer-pref lineh-40"> {answers.answer_text.map(item => <p className='null-answer-container'>{item}</p>)}</div>
</div>
})
}
</div>
</div>
)
}
}
// RouteHOC()
export default (NullDisplay);

View File

@ -1,367 +0,0 @@
import React, { Component } from "react";
import { InputNumber, Checkbox } from 'antd';
import axios from 'axios'
import update from 'immutability-helper'
import { qNameArray } from './common'
import NullMDEditor from './NullMDEditor'
import NullChildEditor from './NullChildEditor'
import { ActionBtn, validateLength } from 'educoder';
class NullEditor extends Component {
constructor(props) {
super(props);
/**
choice_id: 32076
choice_position: 1
choice_text: "1"
standard_boolean: true
standard_answer: [{choice_id: 1, answer_text: ["2", "22"]}]
*/
const { standard_answer } = this.props;
let _standard_answers = undefined;
if (standard_answer) {
_standard_answers = []
standard_answer.forEach((answers, index) => {
_standard_answers.push([])
answers.answer_text.forEach((item, itemIndex) => {
_standard_answers[index].push(item)
})
})
}
this.state = {
standard_answers: _standard_answers || [],
question_title: this.props.question_title || '',
question_type: this.props.question_type || 3,
question_score: this.props.question_score || this.props.init_question_score,
is_ordered: !!this.props.is_ordered,
activeOptionErrorIndex: null,
question_title_error: false
}
}
on_is_ordered_change = (e) => {
this.setState({ is_ordered: e.target.checked })
}
onSave = () => {
const { question_title, question_score, question_choices, standard_answers, is_ordered } = this.state;
const { question_id_to_insert_after, question_id, is_md, showNotification } = this.props
let newis_ordered = is_ordered;
if (newis_ordered === true) {
if (standard_answers.length === 1) {
newis_ordered = false
}
}
// TODO check
// const answerArray = standard_answers.map((item, index) => { return item == true ? index+1 : -1 }).filter(item => item != -1);
let answerArray = []
if (!question_title || !validateLength(question_title, 10000)) {
is_md ? this.refs['titleEditor'].showError() : this.setState({ question_title_error: true })
showNotification(!question_title ? '题目:不能为空' : '题目不能超过10000字符'); return;
}
const intScore = parseFloat(question_score)
if (intScore == 0) {
showNotification('分值必须大于0'); return;
} else if (!question_score || intScore == NaN) {
showNotification('分值:不能为空'); return;
}
let isEmpty = false;
standard_answers.forEach((answers, index) => {
answerArray.push({
"choice_id": index + 1,
"answer_text": []
})
answers.forEach((item, itemIndex) => {
answerArray[index].answer_text.push(item)
if (!item || !validateLength(item, 10000)) {
this.setState({
activeOptionErrorIndex: `${index}-${itemIndex}`
})
showNotification(!item ? `答案:不能为空` : '答案不能超过10000字符');
isEmpty = true;
}
})
})
if (isEmpty == true) {
return;
}
/**
{
"question_title":"社会主义核心价值观(),(),()...",
"question_type":3,
"question_score":5,
"standard_answers":[
{"choice_id":1,
"answer_text":["abbc","xxx","sssss"]
},
{"choice_id":2,
"answer_text":["abbc","xxx","sssss"]
}
]
"is_ordered":true
}
}*/
const Id = this.props.match.params.Id
if (question_id) {
const editUrl = this.props.getEditQuestionUrl(question_id);
axios.put(editUrl, {
question_title,
question_type: 3,
question_score,
question_choices,
standard_answers: answerArray,
insert_id: question_id_to_insert_after || undefined,
is_ordered: newis_ordered,
}).then((response) => {
if (response.data.status == 0) {
this.props.addSuccess()
} else if (response.data.status == 3) {
// 已发布试卷编辑保存
this.props.changeScore(question_id, answerArray);
}
})
.catch(function (error) {
console.log(error);
});
} else {
const url = this.props.getAddQuestionUrl();
axios.post(url, {
exercise_bank_id: Id,
question_title,
question_type: 3,
question_score,
question_choices,
standard_answers: answerArray,
insert_id: question_id_to_insert_after || undefined,
is_ordered: newis_ordered,
})
.then((response) => {
if (response.data.status == 0) {
this.props.addSuccess()
}
})
.catch(function (error) {
console.log(error);
});
}
}
onCancel = () => {
this.props.onEditorCancel()
}
on_question_score_change = (e) => {
this.setState({ question_score: e })
}
// placeholderCountInRange 被删除的个数
onPlaceholderChange = (placeholderCountBefore, placeholderCountInRange, totalPlaceholderCount) => {
const { standard_answers } = this.state;
const new_standard_answers = standard_answers.slice()
if (placeholderCountInRange) {
new_standard_answers.splice(placeholderCountBefore, placeholderCountInRange)
}
if (totalPlaceholderCount) {
for (let i = 0; i < totalPlaceholderCount; i++) {
new_standard_answers.splice(placeholderCountBefore + i, 0, [""])
}
}
this.setState({ standard_answers: new_standard_answers }, () => {
if (this.mdReactObject) {
this.mdReactObject.toShowMode()
}
})
}
onAnswerChange = (index, itemIndex, val) => {
try {
this.setState(
(prevState) => ({
standard_answers: update(prevState.standard_answers
, { [index]: { $splice: [[itemIndex, 1, val]] } }),
})
)
if (this.state.activeOptionErrorIndex === `${index}-${itemIndex}`) {
this.setState({ activeOptionErrorIndex: null })
}
} catch (error) {
console.log(error, index, itemIndex, val)
}
}
addChildAnswer = (index) => {
this.setState(
(prevState) => ({
standard_answers: update(prevState.standard_answers
, { [index]: { $push: [''] } }),
})
)
}
deleteChildAnswermain = (index, childIndex) => {
let newstandard_answers = this.state.standard_answers
this.props.confirm({
content: `确认要删除这个参考答案吗?`,
onOk: () => {
newstandard_answers.splice(index, 1)
this.setState({
standard_answers: newstandard_answers
})
}
})
}
deleteChildAnswer = (index, childIndex) => {
if (!this.state.standard_answers[index][childIndex]) {
this.setState(
(prevState) => ({
standard_answers: update(prevState.standard_answers,
{
[index]:
{ $splice: [[childIndex, 1]] }
}
)
})
)
return;
}
this.props.confirm({
content: `确认要删除这个参考答案吗?`,
onOk: () => {
this.setState(
(prevState) => ({
standard_answers: update(prevState.standard_answers,
{
[index]:
{ $splice: [[childIndex, 1]] }
}
)
})
)
}
})
}
onSetQuestionTitle = (value, html) => {
this.setState({
question_title: html,
question_title_error: false
})
}
onAddFill = (index) => {
const standard_answers = this.state.standard_answers.slice(0)
standard_answers.splice(index, 0, [""])
this.setState({
standard_answers
})
}
onDeleteFill = (index, delCount) => {
const standard_answers = this.state.standard_answers.slice(0)
standard_answers.splice(index, delCount)
this.setState({
standard_answers
})
}
render() {
let { question_title, question_score, question_type, standard_answers
, is_ordered, activeOptionErrorIndex, question_title_error } = this.state;
let { question_id, index, exerciseIsPublish, is_md } = this.props;
const qNumber = `question_${index}`;
return (
<div className="padding20-30 bor-bottom-greyE" id={qNumber}>
<style>{`
.optionMdEditor {
flex: 0 0 800px
}
.optionRow {
margin: 2px;
}
.editorWrapDiv .content_editorMd_show {
background: #EAEAEA;
margin-bottom: 6px;
width: 97%;
display: inline-block;
}
.content_editorMd_show {
display: flex;
maxWidth: 1000px;
}
`}</style>
<p className="mb10 clearfix">{/*!question_id ? '新建' : '编辑'*/}
<span className="color-blue font-16 mr20 fl">{qNameArray[question_type]}</span>
<span className="color-grey-9 font-12 fl">客观题由系统自动评分允许手动调分请设置标准答案 支持最多5个空每空得分按照本题的总分平均计算</span>
</p>
{is_md ?
<NullMDEditor {...this.props} mdID={`question_${question_id}`} placeholder="请您输入题目" height={155}
initValue={question_title} onChange={(val) => this.setState({ question_title: val })}
onPlaceholderChange={this.onPlaceholderChange} showNullButton={exerciseIsPublish ? false : true}
ref="titleEditor"
></NullMDEditor> : null
}
<div className="clearfix">
{
standard_answers.map((answers, index) => {
return <NullChildEditor key={index}
ref={`nullChildEditor${index}`}
{...this.props}
answers={answers}
index={index}
is_md={is_md}
activeOptionErrorIndex={activeOptionErrorIndex}
onAnswerChange={this.onAnswerChange}
addChildAnswer={this.addChildAnswer}
deleteChildAnswer={this.deleteChildAnswer}
deleteChildAnswermain={this.deleteChildAnswermain}
></NullChildEditor>
})
}
</div>
<div className="clearfix ">
{standard_answers.length > 1 ?
<span>
<Checkbox checked={is_ordered} onChange={this.on_is_ordered_change} className="color-grey-3">多个填空的答案有顺序要求</Checkbox>
<span className="color-grey-9 font-12">选中每个填空的答案顺序必须与参考答案一致</span></span>
: ""}
</div>
<div className="clearfix mt20">
分值
<InputNumber step={0.1} precision={1} min={0} max={100} style={{ width: 100 }} value={question_score} onChange={this.on_question_score_change}
disabled={exerciseIsPublish} placeholder="请填写分数"
></InputNumber >
<span className="fr">
<ActionBtn style="greyBack" className="middle mr20" onClick={this.onCancel}
>取消</ActionBtn>
<ActionBtn style="blue" className="middle" onClick={this.onSave}>保存</ActionBtn>
</span>
</div>
</div>
)
}
}
// RouteHOC()
export default (NullEditor);

View File

@ -1,58 +0,0 @@
import React, {Component} from 'react'
import TPMMDEditor from '../../../tpm/challengesnew/tpm-md-editor'
const NULL_CH = '▁'
export default class NullMDEditor extends Component {
getChCountBeforeCursor = (cm, cursor) => {
const currentLine = cursor.line;
let placeholderCountBefore = 0
for(let _line = 0; _line < currentLine; _line++) {
placeholderCountBefore += cm.getLine(_line).split(NULL_CH).length - 1;
}
const currentLineStringBeforeCursor = cm.getLine(currentLine).substring(0, cursor.ch)
placeholderCountBefore += currentLineStringBeforeCursor.split(NULL_CH).length - 1;
return placeholderCountBefore;
}
onCMBeforeChange = (cm, change) => {
const rangeText = cm.getRange(change.from, change.to)
let totalPlaceholderCount = 0
change.text.forEach(item => {
totalPlaceholderCount += item.split(NULL_CH).length - 1
})
if (rangeText && rangeText.indexOf(NULL_CH) != -1) {
const placeholderCountInRange = rangeText.split(NULL_CH).length - 1;
const placeholderCountBefore = this.getChCountBeforeCursor(cm, change.from)
console.log(`删除${placeholderCountInRange}个, 之前有${placeholderCountBefore}个,新增${totalPlaceholderCount}`)
const ret = window.confirm(`确认要删除第${placeholderCountInRange == 1 ? placeholderCountBefore + 1
: `${placeholderCountBefore + 1}-${placeholderCountBefore + placeholderCountInRange}` }个空吗`)
if (ret) {
this.props.onPlaceholderChange
&& this.props.onPlaceholderChange(placeholderCountBefore, placeholderCountInRange, totalPlaceholderCount)
} else {
change.cancel()
}
} else if (totalPlaceholderCount) {
const placeholderCountBefore = this.getChCountBeforeCursor(cm, change.from)
console.log(`新增${totalPlaceholderCount}个,之前有${placeholderCountBefore}`)
this.props.onPlaceholderChange
&& this.props.onPlaceholderChange(placeholderCountBefore, 0, totalPlaceholderCount)
}
}
render() {
return (
<TPMMDEditor {...this.props}
onCMBeforeChange={this.onCMBeforeChange}
>
</TPMMDEditor>
)
}
}

View File

@ -1,67 +0,0 @@
import React, { Component } from "react";
import { Tooltip } from 'antd';
import { qNameArray } from './common'
import RenderHtml from "../../../../components/render-html";
class QestionDisplayHeader extends Component {
render() {
let { question_title, question_score, question_type,
question_id, index, displayCount, is_md,
topRight, showActionButton, exerciseIsPublish
} = this.props;
const qName = qNameArray[question_type]
return (
<React.Fragment>
<div className="new_li">
<style>{`
.actionBtns {
height: 28px
}
`}</style>
<div className="font-16 fl">
<span className="color-blue">{index + 1}{qName}</span>
<span className="color-grey-9">{question_score}</span>
</div>
<div className="fr actionBtns">
{topRight}
{showActionButton != false && <React.Fragment>
{!exerciseIsPublish && <a className="mr30" onClick={() => this.props.onQestionDelete(question_id)}>
<Tooltip title="删除">
<i className="color-grey-cd font-16 iconfont icon-shanchu"></i>
</Tooltip>
</a>}
{index === 0 ? "" :
<a className="mr30" onClick={() => this.props.onSortUp(index, question_id)}>
<Tooltip title="上移">
<i className="color-green font-18 iconfont icon-xiangshangyi"></i>
</Tooltip>
</a>}
{index === displayCount - 1 ? "" :
<a className="mr30" onClick={() => this.props.onSortDown(index, question_id)}>
<Tooltip title="下移">
<i className="color-green font-18 iconfont icon-xiangxiayi"></i>
</Tooltip>
</a>}
{!exerciseIsPublish && this.props.question_type != 6 && <a className="mr30" onClick={() => this.props.addQuestion(question_id, question_type)}>
<Tooltip title={`(向下插入${qName})`}>
<i className="color-green font-18 iconfont icon-roundaddfill"></i>
</Tooltip>
</a>}
<a onClick={() => this.props.editQestion(index, this.props)}>
<Tooltip title="编辑"><i className="color-green font-18 iconfont icon-bianjidaibeijing"></i></Tooltip>
</a>
</React.Fragment>}
</div>
</div>
{question_title ? <RenderHtml is_md={is_md} className='question-title-container' value={question_title} /> : null}
</React.Fragment>
)
}
}
// RouteHOC()
export default (QestionDisplayHeader);

View File

@ -1,106 +0,0 @@
import React, { Component } from "react";
import QestionDisplayHeader from './QestionDisplayHeader'
import RenderHtml from "../../../../components/render-html";
class ShixunDisplay extends Component {
render() {
let { question_title,
question_id, index,
shixun_name, shixun, shixun_identifier, is_md
} = this.props;
const qNumber = `question_${index}`;
/**
{ #实训题
"question_id": 7294,
"question_number": 3,
"question_title": "独立完成数据库知识",
"question_type": 5,
"exercise_id": 763,
"question_score": 35,
"shixun_id": 41,
"shixun_name": "MySQL数据库编程开发实训基础篇",
"shixun": [
{
"challenge_id": 69,
"challenge_position": 1,
"challenge_name": "数据库连接与数据库实例创建",
"challenge_score": 5
},
{
"challenge_id": 70,
"challenge_position": 2,
"challenge_name": "数据表的创建",
"challenge_score": 5
},
{
"challenge_id": 71,
"challenge_position": 3,
"challenge_name": "数据查询操作",
"challenge_score": 5
},
{
"challenge_id": 72,
"challenge_position": 4,
"challenge_name": "数据库的插入操作",
"challenge_score": 5
},
{
"challenge_id": 73,
"challenge_position": 5,
"challenge_name": "数据表的删除操作",
"challenge_score": 5
},
{
"challenge_id": 74,
"challenge_position": 6,
"challenge_name": "数据表的更新操作",
"challenge_score": 5
},
{
"challenge_id": 75,
"challenge_position": 7,
"challenge_name": "数据库的应用",
"challenge_score": 5
}
]
}
*/
// let length = 5;
// const qName = qNameArray[question_type]
return (
<div className="bor-bottom-greyE padding20-30" id={qNumber} _id={question_id}>
<style>{`
.mainQuestionDisplay {
margin-bottom:15px;
}
`}</style>
<QestionDisplayHeader {...this.props} question_title={shixun_name}
topRight={
<a target="_blank" href={`/shixuns/${shixun_identifier}/challenges`} className="mr30"
style={{ color: '#4CACFF' }}
>实训详情</a>
}
></QestionDisplayHeader>
<RenderHtml className="mainQuestionDisplay color-grey-9 markdown-body" is_md={is_md} value={question_title} />
{shixun.map((ch, index) => {
return <div>
{`${index + 1}`} {ch.challenge_name} {ch.challenge_score}
</div>
})}
</div>
)
}
}
// RouteHOC()
export default (ShixunDisplay);

View File

@ -1,288 +0,0 @@
import React, { Component } from "react";
import { Input, InputNumber } from 'antd';
import CustomEditor from "../../../../common/components/custom-editor"
import axios from 'axios'
import update from 'immutability-helper'
import { qNameArray } from './common'
import { ActionBtn, validateLength } from 'educoder';
class ShixunEditor extends Component {
constructor(props) {
super(props);
/**
{ #实训题
"question_id": 7294,
"question_number": 3,
"question_title": "独立完成数据库知识",
"question_type": 5,
"exercise_id": 763,
"question_score": 35,
"shixun_id": 41,
"shixun_name": "MySQL数据库编程开发实训基础篇",
"shixun": [
{
"challenge_id": 69,
"challenge_position": 1,
"challenge_name": "数据库连接与数据库实例创建",
"challenge_score": 5
},
{
"challenge_id": 70,
"challenge_position": 2,
"challenge_name": "数据表的创建",
"challenge_score": 5
},
{
"challenge_id": 71,
"challenge_position": 3,
"challenge_name": "数据查询操作",
"challenge_score": 5
},
{
"challenge_id": 72,
"challenge_position": 4,
"challenge_name": "数据库的插入操作",
"challenge_score": 5
},
{
"challenge_id": 73,
"challenge_position": 5,
"challenge_name": "数据表的删除操作",
"challenge_score": 5
},
{
"challenge_id": 74,
"challenge_position": 6,
"challenge_name": "数据表的更新操作",
"challenge_score": 5
},
{
"challenge_id": 75,
"challenge_position": 7,
"challenge_name": "数据库的应用",
"challenge_score": 5
}
]
}
*/
const { shixun } = this.props;
const question_scores = shixun ? shixun.map(item => item.challenge_score) : []
this.state = {
question_title: this.props.question_title || '',
question_type: this.props.question_type || 2,
question_scores: question_scores || '0',
challenges: [],
}
}
onSave = () => {
const { question_title, question_scores, shixun_name } = this.state;
const { question_id_to_insert_after, question_id
, shixun_id } = this.props
for (let _i = 0; _i < question_scores.length; _i++) {
if (!question_scores[_i] || question_scores[_i] == '0') {
this.props.showNotification(`${_i + 1}题的分值必须大于0`); return;
}
}
if (!validateLength(question_title, 10000)) {
this.props.showNotification('实训题完成要求不能超过10000字符!');
return;
}
/**
{
"question_title":"社会主义核心价值观是?.",
"question_type":5,
"question_scores":[5,5,5],
"shixun_id":555
}
}*/
const Id = this.props.match.params.Id
if (question_id) {
const editUrl = this.props.getEditQuestionUrl(question_id);
axios.put(editUrl, {
question_title,
question_type: 5,
question_scores,
shixun_id,
insert_id: question_id_to_insert_after || undefined,
shixun_name,
})
.then((response) => {
if (response.data.status == 0) {
this.props.addSuccess()
}
})
.catch(function (error) {
console.log(error);
});
} else {
const url = this.props.getAddQuestionUrl();
axios.post(url, {
exercise_bank_id: Id,
question_title,
question_type: 5,
question_scores,
shixun_id,
insert_id: question_id_to_insert_after || undefined,
shixun_name,
})
.then((response) => {
if (response.data.status == 0) {
this.props.addSuccess()
}
})
.catch(function (error) {
console.log(error);
});
}
}
onCancel = () => {
this.props.onEditorCancel()
}
componentDidMount = () => {
const { shixun_id, exercise_url } = this.props;
// shixun_id
const Id = this.props.match.params.Id
const url = `/${exercise_url || 'exercises'}/${Id}/commit_shixun.json`
axios.get(url, {
params: {
shixun_id
}
})
.then((response) => {
if (response.data.challenges) {
/**
challenge_counts
shixun_name shixun_id
challenges [ {challenge_name: "链表节点的初始化"} ]
*/
const question_scores = this.state.question_scores
let chLen = response.data.challenges.length;
if (chLen == 0) {
this.onCancel()
this.props.showNotification('这个实训没有关卡,请选择其他实训')
this.props.chooseShixunFail && this.props.chooseShixunFail()
return
}
this.props.chooseShixunSuccess && this.props.chooseShixunSuccess()
// 新建的时候初始化数组
// question_scores.length = chLen
let newArray = [];
if (question_scores && question_scores.length && question_scores[0]) {
newArray = question_scores;
} else {
while (chLen--) {
newArray.push(5)
}
}
this.setState({ ...response.data, question_scores: newArray })
}
})
.catch(function (error) {
console.log(error);
});
}
on_question_score_change = (e, index) => {
const value = e
this.setState(
(prevState) => ({
question_scores: update(prevState.question_scores
, { [index]: { $set: value } })
})
)
// this.setState({ question_score: e })
}
onSetQuestionTitle = (value) => {
this.setState({
question_title: value,
})
}
render() {
let { question_title, question_type,
shixun_name, challenges, question_scores } = this.state;
let { index, is_md, exerciseIsPublish, } = this.props;
if (!challenges || challenges.length == 0) {
return ''
}
const qNumber = `question_${index}`;
const blackColor = '#05101A'
return (
<div className="padding20-30 bor-bottom-greyE" id={qNumber}>
<style>{`
.optionMdEditor {
flex: 0 0 800px
}
.optionRow {
margin: 2px;
}
.df_left_right {
display: flex;
justify-content: space-between;
margin: 0 6px;
margin-bottom: 20px;
}
`}</style>
<p className="mb10 clearfix">
{/*!question_id ? '新建' : '编辑'*/}
<span className="color-blue font-16 mr20 fl">{qNameArray[question_type]}</span>
<span className="color-grey-9 font-12 fl">客观题由系统自动评分允许手动调分</span>
</p>
<Input value={shixun_name} onChange={(e) => this.setState({ shixun_name: e.target.value })}
style={{ marginBottom: '10px' }}
></Input>
<CustomEditor is_md={is_md} height={is_md ? 155 : 109}
placeholder="请输入实训题完成要求"
value={question_title}
isShowEditor={true}
isError={false}
autoFocus={true}
onChange={this.onSetQuestionTitle}
/>
<div>
<div className="df_left_right">
<div className="color-grey-9">关卡</div>
<div className="color-grey-9" style={{ flex: '0 0 76px' }}>分值</div>
</div>
{challenges.map((challenge, index) => {
return <div className="df_left_right" key={index}>
<div style={{ color: blackColor }} className="lineh-30">
{index + 1}.{challenge.challenge_name}
</div>
<div>
<InputNumber step={0.1} precision={1} min={0} max={100}
style={{ width: 100 }} value={question_scores[index]}
placeholder="请填写分数" disabled={exerciseIsPublish}
onChange={(e) => this.on_question_score_change(e, index)}></InputNumber>
</div>
</div>
})}
</div>
<div style={{ height: '40px', marginTop: '10px' }}>
<span className="fr">
<ActionBtn style="greyBack" className="middle mr20" onClick={this.onCancel}
>取消</ActionBtn>
<ActionBtn style="blue" className="middle" onClick={this.onSave}>保存</ActionBtn>
</span>
</div>
</div>
)
}
}
// RouteHOC()
export default (ShixunEditor);

View File

@ -1,94 +0,0 @@
import React, { Component } from "react";
import { InputNumber } from 'antd'
import { ActionBtn } from 'educoder';
import QestionDisplayHeader from './QestionDisplayHeader'
import axios from 'axios'
import RenderHtml from "../../../../components/render-html";
class ShixunProgramming extends Component {
constructor(props) {
super(props);
this.state = {
question_scores: null,
edits: false
}
}
on_question_score_change = (e, index) => {
const value = e
this.setState({ question_scores: value, edits: true })
}
onSave = () => {
const { question_scores, edits } = this.state;
const { index, question_id, question_score, is_md } = this.props
if (edits) {
if (!question_scores || question_scores == '0') {
this.props.showNotification(`${index + 1}道编程题调整的分值必须大于0`);
return
}
} else {
if (!question_score || question_score == '0') {
this.props.showNotification(`${index + 1}道编程题调整的分值必须大于0`);
return
}
}
const url = `/exercise_questions/${question_id}/update_question_score.json`;
axios.post(url, {
question_score: question_scores ? question_scores : question_score
})
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification(`调分成功`);
this.props.addSuccess()
}
})
.catch(function (error) {
console.log(error);
});
}
render() {
let { description, question_title, exerciseIsPublish,
question_id, index, is_md, question_score,exercise_status
} = this.props;
let { question_scores } = this.state;
const isAdmin = this.props.isAdmin()
const qNumber = `question_${index}`
return (
<div className="bor-bottom-greyE padding20-30" id={qNumber} _id={question_id}>
<style>{`
.mainQuestionDisplay {
margin-bottom:15px;
}
`}</style>
<QestionDisplayHeader {...this.props} question_title={question_title}
></QestionDisplayHeader>
{description && <RenderHtml value={description} is_md={is_md} />}
{exerciseIsPublish && isAdmin && <div className={"mt20"}>
分值
<InputNumber step={0.1} precision={1} min={0} max={100} style={{ width: 100 }}
value={question_scores ? question_scores : question_score}
onChange={this.on_question_score_change}
disabled={exercise_status===1===false}
></InputNumber>&nbsp;
{exercise_status === 1 ? <span className="fr">
<ActionBtn style="blue" className="middle"
onClick={this.onSave}
>保存</ActionBtn>
</span> : ""}
</div>}
</div>
)
}
}
export default ShixunProgramming;

View File

@ -1,60 +0,0 @@
import React, { Component } from "react";
import { Radio, Checkbox } from 'antd';
import QestionDisplayHeader from './QestionDisplayHeader'
import RenderHtml from "../../../../components/render-html";
const tagArray = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]
class SingleDisplay extends Component {
render() {
let { question_type, question_choices,
question_id, index, is_md
} = this.props;
const qNumber = `question_${index}`;
return (
<div className="bor-bottom-greyE padding20-30 singleDisplay" id={qNumber} _id={question_id}>
<style>{`
.optionMdEditor {
flex: 0 0 800px
}
.optionRow {
margin: 2px;
}
.actionBtns {
height: 28px
}
`}</style>
<QestionDisplayHeader {...this.props}></QestionDisplayHeader>
{/* 单选 or 多选 */}
<div className="options">
{question_choices.map((item, optionIndex) => {
let prefix = `${tagArray[optionIndex]}.`
return (
<div className="mb10 clearfix " style={{
display: "flex",
flexDirection: "row",
}} key={optionIndex}>
{question_type == 0 ? <Radio disabled className="fl lineh-25 w50" checked={item.standard_boolean}>{prefix}</Radio> : <Checkbox disabled className="fl lineh-25 w50" checked={item.standard_boolean}>{prefix}</Checkbox>}
<RenderHtml value={item.choice_text} is_md={is_md} />
</div>)
})}
</div>
</div>
)
}
}
export default (SingleDisplay);

View File

@ -1,321 +0,0 @@
import React, { Component } from "react"
import { InputNumber, Tooltip } from 'antd'
import axios from 'axios'
import update from 'immutability-helper'
import { ActionBtn, ConditionToolTip, validateLength } from 'educoder'
import CustomEditor from "../../../../common/components/custom-editor"
const tagArray = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]
class SingleEditor extends Component {
constructor(props) {
super(props);
/**
choice_id: 32076
choice_position: 1
choice_text: "1"
standard_boolean: true
*/
const { question_choices } = this.props;
let _standard_answers = undefined;
let _question_choices = undefined;
if (question_choices) {
_standard_answers = []
_question_choices = []
question_choices.forEach((item, index) => {
_standard_answers.push(item.standard_boolean)
_question_choices.push(item.choice_text)
})
}
this.state = {
question_choices: _question_choices || ['', '', '', ''],
standard_answers: _standard_answers || [false, false, false, false],
question_title: this.props.question_title || '',
question_type: this.props.question_type || 0,
question_score: this.props.question_score || this.props.init_question_score,
activeOptionIndex: null,
question_title_error: false,
activeOptionErrorIndex: null
}
}
addOption = () => {
const { question_choices, standard_answers } = this.state;
question_choices.push('')
standard_answers.push(false)
this.setState({ question_choices, standard_answers })
}
deleteOption = (index) => {
let { question_choices } = this.state;
if (question_choices[index] === "") {
// repeat code
this.setState(
(prevState) => ({
question_choices: update(prevState.question_choices, { $splice: [[index, 1]] }),
standard_answers: update(prevState.standard_answers, { $splice: [[index, 1]] })
})
)
} else {
this.props.confirm({
content: `确认要删除这个选项吗?`,
onOk: () => {
this.setState(
(prevState) => ({
question_choices: update(prevState.question_choices, { $splice: [[index, 1]] }),
standard_answers: update(prevState.standard_answers, { $splice: [[index, 1]] })
})
)
}
})
}
}
onSave = () => {
const { question_title, question_score, question_choices, standard_answers } = this.state;
const { question_id_to_insert_after, question_id } = this.props
// TODO check
const answerArray = standard_answers.map((item, index) => { return item == true ? index + 1 : -1 }).filter(item => item != -1);
if (!question_title) {
this.setState({
question_title_error: true
})
this.props.showNotification('题目:不能为空')
return
}
if (!validateLength(question_title, 10000)) {
this.setState({
question_title_error: true
})
this.props.showNotification('题干不能超过10000字符')
return
}
const intScore = parseFloat(question_score)
if (intScore == 0) {
this.props.showNotification('分值必须大于0'); return;
} else if (!question_score || intScore == NaN) {
this.props.showNotification('分值:不能为空'); return;
}
if (!answerArray || answerArray.length == 0) {
this.props.showNotification('请先点击选择本选择题的正确选项'); return;
}
for (let i = 0; i < question_choices.length; i++) {
if (!question_choices[i] || !validateLength(question_choices[i], 5000)) {
this.setState({
activeOptionErrorIndex: i
})
this.props.showNotification(!question_choices[i] ? `请先输入 ${tagArray[i]} 选项的内容` : '选项内容不能超过5000字符');
return;
}
}
/**
{
"question_title":"同学朋友间常用的沟通工具是什么?",
"question_type":1,
"question_score":5,
"question_choices":["a答案","b答案","c答案","d答案"],
"standard_answers":[1]
}*/
const Id = this.props.match.params.Id
if (question_id) {
const editUrl = this.props.getEditQuestionUrl(question_id);
axios.put(editUrl, {
question_title,
question_type: answerArray.length > 1 ? 1 : 0,
question_score,
question_choices,
standard_answers: answerArray,
insert_id: question_id_to_insert_after || undefined
}).then((response) => {
if (response.data.status == 0) {
this.props.addSuccess()
} else if (response.data.status == 3) {
// 已发布试卷编辑保存
this.props.changeScore(question_id, answerArray);
}
})
.catch(function (error) {
console.log(error);
});
} else {
const url = this.props.getAddQuestionUrl();
axios.post(url, {
exercise_bank_id: Id,
question_title,
question_type: answerArray.length > 1 ? 1 : 0,
question_score,
question_choices,
standard_answers: answerArray,
insert_id: question_id_to_insert_after || undefined
})
.then((response) => {
if (response.data.status == 0) {
this.props.addSuccess()
}
})
.catch(function (error) {
console.log(error);
});
}
}
onCancel = () => {
this.props.onEditorCancel()
}
onOptionClick = (index) => {
let standard_answers = this.state.standard_answers.slice(0)
standard_answers[index] = !standard_answers[index]
this.setState({ standard_answers })
}
onOptionContentChange = (value, index) => {
if (index >= this.state.question_choices.length) {
// TODO 新建然后删除CD选项再输入题干会调用到这里且index是3
return
}
let question_choices = this.state.question_choices.slice(0)
question_choices[index] = value
if (this.state.activeOptionErrorIndex === index) {
this.setState({ question_choices, activeOptionErrorIndex: null })
} else {
this.setState({ question_choices })
}
}
on_question_score_change = (e) => {
this.setState({ question_score: e })
}
onSetQuestionTitle = (value) => {
this.setState({
question_title: value,
question_title_error: false
})
}
onActiveOption = (index) => {
this.setState({
activeOptionIndex: index
})
}
render() {
let { question_title, question_score, question_choices, standard_answers, activeOptionIndex, question_title_error, activeOptionErrorIndex } = this.state;
let { index, exerciseIsPublish, is_md } = this.props;
const qNumber = `question_${index}`;
const answerTagArray = standard_answers.map((item, index) => { return item == true ? tagArray[index] : -1 }).filter(item => item != -1);
return (
<div className="padding20-30 bor-bottom-greyE signleEditor" id={qNumber}>
<style>{`
.optionMdEditor {
flex:1
}
.optionRow {
margin:0px!important;
}
.signleEditor .content_editorMd_show{
display: flex;
margin-top:0px!important;
border-radius:2px;
max-width: 1056px;
word-break:break-all;
}
.editor_area{
display: inline-block;
float: right;
}
.editor_txt{
margin-right: 10px;
font-size: 12px;
color: #999;
}
.radio_style{
display: inline-block;
vertical: center;
}
`}</style>
<p className="mb10 clearfix">
<span className="color-blue font-16 mr20 fl">选择题</span>
<span className="color-grey-9 font-12 fl">客观题由系统自动评分请设置标准答案</span>
</p>
<CustomEditor is_md={is_md} height={is_md ? 155 : 109}
placeholder="请您输入题目"
value={question_title}
md_id='single-editor-container'
isShowEditor={true}
isError={question_title_error}
autoFocus={true}
onChange={this.onSetQuestionTitle}
/>
{question_choices.map((item, index) => {
const bg = standard_answers[index] ? 'check-option-bg' : ''
return <div className="df optionRow " key={index} >
{/* 点击设置答案 */}
<span className={`option-item fr mr10 color-grey select-choice ${bg} `}
name="option_span" onClick={() => this.onOptionClick(index)} style={{ flex: '0 0 38px' }}>
<ConditionToolTip title={standard_answers[index] ? '点击取消标准答案设置' : '点击设置为标准答案'} placement="left" condition={true}>
<div style={{ width: '100%', height: '100%' }}>{tagArray[index]}</div>
</ConditionToolTip>
</span>
<div style={{ flex: '0 0 1038px' }}>
<CustomEditor md_id={'single-editor' + index} height={is_md ? 155 : 109} is_md={is_md} value={item || ''} placeholder='' isShowEditor={activeOptionIndex === index} className={'optionMdEditor'} index={index} isError={activeOptionErrorIndex === index} onChange={this.onOptionContentChange} onActiveOption={this.onActiveOption} />
</div>
{exerciseIsPublish || index === 0 ?
<i className=" font-18 ml15 mr20"></i>
: <Tooltip title="删除">
<i className="iconfont icon-htmal5icon19 font-18 color-grey-c ml15" onClick={() => this.deleteOption(index)}></i>
</Tooltip>}
{!exerciseIsPublish && <Tooltip title={`新增参考答案`}>
<i className="color-green font-16 iconfont icon-roundaddfill ml6"
onClick={() => this.addOption()}
style={{ float: 'right', visibility: index == question_choices.length - 1 ? '' : 'hidden', marginTop: '2px' }}
></i>
</Tooltip>}
</div>
})}
<div className="mb20">
<span
style={{ color: '#FF6800' }}>{'温馨提示:点击选项输入框可设置答案;选中的选项即为正确答案,选择多个答案即为多选题'}</span>
{answerTagArray && !!answerTagArray.length ?
<React.Fragment>
<span className="fr color-orange">{answerTagArray.join(' ')}</span>
<span className="fr">标准答案</span>
</React.Fragment>
:
""
}
</div>
<div>
分值
<InputNumber step={0.1} precision={1} min={0} max={100} style={{ width: 100 }} value={question_score} onChange={this.on_question_score_change}
disabled={exerciseIsPublish}
></InputNumber>&nbsp;
<span className="fr">
<ActionBtn style="greyBack" className="middle mr20" onClick={this.onCancel}
>取消</ActionBtn>
<ActionBtn style="blue" className="middle" onClick={this.onSave}>保存</ActionBtn>
</span>
</div>
</div>
)
}
}
export default SingleEditor

View File

@ -1,77 +0,0 @@
.editorWrapDiv {
border: 1px solid #4CACFF;
padding: 6px 10px;
}
.questionSection {
border-bottom: 1px solid #EAEAEA;
padding: 8px 0px;
}
.questionSection:last-child {
border-bottom: none;
}
/* 判断题编辑器item样式 */
.judge-item.option-item {
display: inline-block;
margin-bottom: 8px;
width: 52px;
}
/* 填空题新增按钮 */
.addAnswerButton {
background: rgba(248, 248, 248, 1);
text-align: center;
color: #4CACFF;
height: 40px;
line-height: 40px;
cursor: pointer;
}
.nullChildEditor {
width: 100%;
display: inline-block;
}
.singleDisplay .options .markdown-body {
max-width: 1116px;
}
.singleDisplay .ant-radio-wrapper span:last-child,
.singleDisplay .ant-checkbox-wrapper span:last-child {
padding-right: 0px;
}
.text-area-editor .ant-input {
height: auto !important;
}
.question-title-container {
margin: 10px 0 15px;
width: 100%;
font-size: 16px;
overflow: hidden;
}
.answer-row {
display: flex;
flex-flow: row wrap;
align-items: center;
}
.answer-pref {
max-width: 100%;
flex: 1 0 auto;
}
.null-answer-container {
display: block;
padding: 10px;
line-height: 20px;
min-height: 40px;
width: 100%;
background-color: #f5f5f5;
cursor: default;
margin-bottom: 10px !important;
}

View File

@ -1,17 +0,0 @@
export const Q_TYPE_SINGLE = 0 // 单选
export const Q_TYPE_MULTI = 1 // 多选
export const Q_TYPE_JUDGE = 2 // 判断
export const Q_TYPE_NULL = 3 // 填空
export const Q_TYPE_MAIN = 4 // 填空
export const Q_TYPE_SHIXUN = 5 // 实训
export const Q_TYPE_SHIXUN_BIANCHENG = 6 // 编程题
export const qNameArray = [
'单选题',
'多选题',
'判断题',
'填空题',
'简答题',
'实训题',
'编程题'
]

View File

@ -1,58 +0,0 @@
import React, { Component } from "react";
import ShowProgramming from "./ShowProgramming";
import RenderHtml from "../../../../components/render-html";
class Progques extends Component {
render() {
let {
questionType,
exercise,
user_exercise_status,
is_md
} = this.props
let item = questionType;
let mydescription = item.description
return (
<div className="pl30 pr30">
<style>{`
.emptyPanel div#content_editorMd_show{
width: 100%;
border-radius: 4px;
// height: 35px;
margin-top:0px;
background-color:#fafafa;
color:#999;
// line-height:25px;
}
.answerStyle{
background:#f5f5f5;
border-radius:4px;
border: 1px solid #eaeaea;
padding:5px;
min-height:35px;
box-sizing:border-box;
}
.emptyPanel .ql-editor{
overflow: unset !important;
padding:0px !important;
}
.emptyPanel .quill_editor_for_react_area{
width: 100% !important;
}
`}</style>
<li className="break_word mt15 mb15 pl30 pr30">
<RenderHtml style={{ wordBreak: "break-word", fontWeight: "bold" }} value={mydescription} is_md={is_md} />
</li>
{exercise && ((exercise.student_commit_status && exercise.student_commit_status != 0) || (exercise.user_exercise_status && exercise.user_exercise_status != 0)) ?
<ShowProgramming
{...this.props}
{...this.state}
questionType={item}
></ShowProgramming> : ""}
</div>
)
}
}
export default Progques

View File

@ -1,91 +0,0 @@
import React,{ Component } from "react";
import {Table} from "antd";
import { Base64 } from 'js-base64';
class ShixunProgrDetail extends Component{
constructor(props){
super(props);
}
render(){
let { challenge ,questionType}=this.props;
let columns=[{
title: '评测次数',
dataIndex: 'number',
width:"127px",
key: 'number',
className:"edu-txt-center",
render: (text, record) => (
<span>
{/*{ record.status===-1?"测试用例结果不匹配":record.status===0?"评测通过":record.status===2?"评测超时":record.status===3?*/}
{/* "创建pod失败":record.status===4?"编译失败":record.status===5?"执行失败":""}*/}
{record.key}
</span>
),
}, {
title: '详细信息',
dataIndex: 'name',
key: 'name',
className:challenge && challenge.length > 0 ? "" : "edu-txt-center",
render: (text, record) => (
<span>
{ record.error_msg==="--"?"--":Base64.decode(record.error_msg)}
</span>
),
}];
let datas=[];
// challenge && challenge.length > 0 ? challenge.map((item,key)=>{
// datas.push({
// number: item.position || "--",
// name: item.output_detail || "--"
// })
// })
// :
// datas.push({
// number:"--",
// name:"--"
// })
if(questionType.evaluate_codes){
if(questionType.evaluate_codes.length>0){
questionType.evaluate_codes.map((item,key)=>{
item.key=key+1
datas.push(item)
})
}else{
datas.push({
key:"--",
error_msg:"--"
})
}
}else{
datas.push({
key:"--",
error_msg:"--"
})
}
return (
<div>
<style>{`
.ant-table-thead > tr > th{
text-align: center;
}
`}</style>
{
datas ?
<Table
bordered
dataSource={datas}
columns={columns}
pagination={false}
/>:""
}
</div>
)
}
}
export default ShixunProgrDetail;

View File

@ -1,146 +0,0 @@
import React,{ Component } from "react";
import { Base64 } from 'js-base64';
import {UnControlled as CodeMirror} from 'react-codemirror2';
import ShixunProgrDetail from './ShixunProgrDetail'
const $ = window.$;
class ShowProgramming extends Component{
constructor(props){
super(props);
this.state={
scoreList:[],
data:[],
challenge:[],
dataCopy:[]
}
}
componentDidUpdate =(prevState)=>{
if(this.props.questionType && !prevState.questionType && prevState.questionType !=this.props.questionType ){
this.showInfo();
}
}
componentDidMount =()=>{
this.showInfo();
}
showInfo=()=>{
let data =[];
let challenge=[];
let details = this.props.questionType.shixun_details;
if(details){
for(var i=0;i<details.length;i++){
for(var j=0;j<details[i].stage_list.length;j++){
data.push({
part:details[i].stage_list[j].position,
shixunName:details[i].stage_list[j].name,
testCount:details[i].stage_list[j].evaluate_count,
endTime:details[i].stage_list[j].finished_time,
needTime:details[i].stage_list[j].time_consuming,
my_exp:details[i].stage_list[j].myself_experience,
total_exp:details[i].stage_list[j].experience,
my_score:details[i].stage_list[j].user_score,
total_score:details[i].stage_list[j].game_score,
input_score:details[i].stage_list[j].user_score,
operation:details[i].shixun_detail && details[i].shixun_detail[0].game_identifier,
id:details[i].shixun_challenge_id
})
}
if(details[i].shixun_detail){
challenge.push(details[i].shixun_detail);
}
}
}
this.setState({
data:data,
dataCopy:data,
challenge:challenge
})
// console.log(challenge);
}
scrollToAnchor=(index)=>{
let name="challenge_"+index;
if (index) {
// let anchorElement = document.getElementById(name);
// if(anchorElement) { anchorElement.scrollIntoView(); }
$("html").animate({ scrollTop: $("#challenge_"+index).offset().top - 150 })
}
}
render(){
let {
questionType ,
}=this.props
let isAdmin= this.props.isAdmin();
let isStudent = this.props.isStudent();
return(
<div>
<style>
{`
.resetTableStyle .ant-table-tbody > tr > td{
padding:10px 5px!important;
}
.resetCodeMirrorStyle .CodeMirror{
height:auto!important;
}
`}
</style>
<div>
<div>
<div className="pl15 pr15">
<ShixunProgrDetail
{...this.props}
{...this.state}
></ShixunProgrDetail>
{questionType.user_answer.length>0? <div className="font-16 color-dark-21">
<div className="bor-grey-e mt15">
<p className="clearfix pt5 pb5 pl15 pr15 back-f6-grey codebox">
<span className="fl">最近通过的代码</span>
{/*<span className="fr codeboxright">{item[0].path}</span>*/}
</p>
<div className="test-code bor-top-greyE">
<li className="clearfix resetCodeMirrorStyle">
<CodeMirror
value={questionType.user_answer[0]?Base64.decode(questionType.user_answer[0]):""}
options={{
// mode: 'xml',
theme: 'default',
lineNumbers: true,
// extraKeys: {"Ctrl-Q": "autocomplete"}, // 快捷键
indentUnit: 4, //代码缩进为一个tab的距离
matchBrackets: true,
autoRefresh: true,
smartIndent: true,//智能换行
styleActiveLine: true,
lint: true,
readOnly: "nocursor"
}}
/>
</li>
</div>
</div>
</div>:""}
</div>
</div>
</div>
</div>
)
}
}
export default ShowProgramming

View File

@ -1,153 +0,0 @@
import React, { Component } from "react";
import { Input } from "antd";
import axios from 'axios'
const { TextArea } = Input
class fillEmpty extends Component {
constructor(props) {
super(props);
let { questionType } = this.props;
let array = [];
for (var i = 0; i < questionType.multi_count; i++) {
let item = "";
if (questionType.user_answer.length > 0) {
if (questionType.user_answer[i]) {
item = questionType.user_answer[i].answer_text;
}
}
array.push({
value: item,
q_id: questionType.question_number
})
}
this.state = {
array
}
}
onOptionContentChange = (value, index) => {
let array = this.state.array.slice(0);
array[index].value = value;
this.setState({ array })
}
onBlurEmpty = (index, number, event) => {
let { questionType, changeQuestionStatus } = this.props
let array = this.state.array.slice(0);
let v = event.target.value;
let question_id = questionType.question_id;
let url = `/exercise_questions/${question_id}/exercise_answers.json`
axios.post((url), {
exercise_choice_id: parseInt(index) + 1,
answer_text: v
}).then((result) => {
if (result.status == 200) {
let count = 0;
for (var i = 0; i < array.length; i++) {
if (array[i].value == "") { count++; }
}
let k = count == array.length ? 0 : 1;
changeQuestionStatus && changeQuestionStatus(parseInt(questionType.q_position) - 1, k);
}
}).catch((error) => {
console.log(error);
})
}
render() {
let {
questionType,
user_exercise_status,
} = this.props
let {
array
} = this.state
return (
<div className="pl30 pr30">
<style>{`
.emptyPanel div#content_editorMd_show{
width: 100%;
border-radius: 4px;
// height: 35px;
margin-top:0px;
background-color:#fafafa;
color:#999;
// line-height:25px;
}
.answerStyle{
background:#f5f5f5;
border-radius:4px;
border: 1px solid #eaeaea;
padding:5px;
min-height:35px;
box-sizing:border-box;
}
.pd10{
padding: 10px;
}
.min40{
min-height:40px;
}
`}</style>
{
array.map((item, key) => {
return (
<li className="df mb10 emptyPanel">
<span className="mr10 lineh-35 font-16">答案填空{key + 1}:</span>
{
user_exercise_status == 1 ? <div className="flex1 lineh-40 new_li">
<p key={key}
style={{ backgroundColor: "#F5F5F5" }}
className="new_li answers lineh-40 pd10 min40 newcontent_editorMd_show" >
{item.value}
</p>
</div>
:
<div className="flex1">
<div className='text-area-editor' >
<TextArea rows={4} value={item.value} defaultValue={`输入填空${key + 1}的答案`} onBlur={(event) => this.onBlurEmpty(key, questionType.q_position, event)} onChange={
event => this.onOptionContentChange(event.target.value, key)
} />
</div>
</div>
}
</li>
)
})
}
{
// 答案公开,且试卷已经截止
questionType.standard_answer &&
<div>
<p className="bor-top-greyE pt20 mt20 font-16 mb10">参考答案</p>
{questionType.standard_answer && questionType.standard_answer.map((item, k) => {
return (
<ul className="df font-16">
<span className="mr10">答案填空{k + 1}:</span>
<li className="flex1 answers lineh-40 new_li">
{
item.answer_text && item.answer_text.map((i, index) => {
return (
<p key={index}
style={{ backgroundColor: "#F5F5F5" }}
className="new_li answers lineh-40 pd10 min40 newcontent_editorMd_show" >
{i}
</p>
)
})
}
</li>
</ul>
)
})
}
</div>
}
</div>
)
}
}
export default fillEmpty

View File

@ -1,94 +0,0 @@
import React, { Component } from "react";
import { Checkbox } from "antd";
import axios from 'axios'
import RenderHtml from "../../../../components/render-html";
const tagArray = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]
class Multiple extends Component {
constructor(props) {
super(props);
}
saveId = (value) => {
let question_id = this.props.questionType.question_id;
let url = `/exercise_questions/${question_id}/exercise_answers.json`;
let { index } = this.props;
axios.post((url), {
exercise_choice_id: value
}).then((result) => {
if (result.status == 200) {
let k = 0;
if (value.length > 0) {
k = 1;
} else {
k = 0;
}
this.props.changeOption && this.props.changeOption(index, value);
this.props.changeQuestionStatus && this.props.changeQuestionStatus(parseInt(this.props.questionType.q_position) - 1, k);
}
}).catch((error) => {
console.log(error);
})
}
render() {
let {
questionType,
exercise,
user_exercise_status,
is_md
} = this.props
let isStudent = this.props.isStudent();
return (
<div className="pl30 pr30 singleDisplay">
<style>
{
`
.multiple .ql-editor {
overflow: unset !important;
padding:0px !important;
}
.multiple .ql-editor p{
line-height: 25px !important;
}
`
}
</style>
<Checkbox.Group className="with100" disabled={user_exercise_status == 1 ? true : false} onChange={this.saveId} value={questionType.user_answer}>
{
questionType.question_choices && questionType.question_choices.map((item, key) => {
let prefix = `${tagArray[key]}.`
let titename = item.choice_text;
return (
<p className="clearfix mb15 df">
<Checkbox className="lineh-15 df mr8 setRadioStyle multiple" value={item.choice_id}>
<span className="fl mr3 lineh-25">{prefix}</span>
<RenderHtml className="flex1" style={{ display: "inline-block" }} value={titename} is_md={is_md} />
</Checkbox>
</p>
)
})
}
</Checkbox.Group>
{
// 答案公开,且试卷已经截止
isStudent && exercise && exercise.answer_open == true && exercise.exercise_status == 3 &&
<p className="bor-top-greyE pt20 mt10 font-16">参考答案
{questionType.standard_answer.map((i, k) => {
return (
<span value={k}>{tagArray[parseInt(i) - 1]}</span>
)
})
}
</p>
}
</div>
)
}
}
export default Multiple

View File

@ -1,339 +0,0 @@
import React, { Component } from "react";
import { InputNumber, Table, Tooltip } from "antd";
import { Link } from 'react-router-dom';
import { UnControlled as CodeMirror } from 'react-codemirror2';
import axios from 'axios'
import update from 'immutability-helper'
import ShixunAnswerDetail from './shixunAnswerDetail'
import RenderHtml from "../../../../components/render-html";
const $ = window.$;
class shixunAnswer extends Component {
constructor(props) {
super(props);
this.state = {
scoreList: [],
data: [],
challenge: [],
dataCopy: []
}
}
componentDidUpdate = (prevState) => {
if (this.props.questionType && !prevState.questionType && prevState.questionType != this.props.questionType) {
this.showInfo();
}
}
componentDidMount = () => {
this.showInfo();
}
showInfo = () => {
let data = [];
let challenge = [];
let details = this.props.questionType.shixun_details;
if (details) {
for (let i = 0; i < details.length; i++) {
for (let j = 0; j < details[i].stage_list.length; j++) {
let item = details[i].stage_list[j]
data.push({
part: item.position,
shixunName: item.name,
testCount: item.evaluate_count,
endTime: item.finished_time,
needTime: item.time_consuming,
view_answer: item.view_answer,
my_exp: item.myself_experience,
total_exp: item.experience,
my_score: item.user_score,
total_score: item.game_score,
input_score: item.user_score,
operation: details[i].shixun_detail && details[i].shixun_detail[0].game_identifier,
id: details[i].shixun_challenge_id
})
}
if (details[i].shixun_detail) {
challenge.push(details[i].shixun_detail);
}
}
}
this.setState({
data: data,
dataCopy: data,
challenge: challenge
})
}
changeThis = (value, index) => {
this.setState(
(prevState) => ({
data: update(prevState.data, { [index]: { input_score: { $set: value } } })
})
)
}
changeThisScore = (e, c_id, key) => {
let url = `/exercise_questions/${this.props.questionType.question_id}/adjust_score.json`
let value = e.target.value
const list = Object.assign({}, this.state.dataCopy[key])
if (parseInt(value) == parseInt(list.my_score)) {
return;
}
axios.post((url), {
score: value,
user_id: this.props.id,
shixun_challenge_id: c_id
}).then((result) => {
if (result) {
this.props.showNotification('调分成功');
this.setState(
(prevState) => ({
data: update(prevState.data, { [key]: { my_score: { $set: value } } }),
dataCopy: update(prevState.dataCopy, { [key]: { my_score: { $set: value } } })
})
)
}
}).catch((error) => {
console.log(error);
})
}
scrollToAnchor = (index) => {
if (index) {
$("html").animate({ scrollTop: $("#challenge_" + index).offset().top - 150 })
}
}
render() {
let {
questionType,
exercise,
user_exercise_status,
} = this.props
let {
data,
challenge,
scoreList,
} = this.state
let isAdmin = this.props.isAdmin();
let isStudent = this.props.isStudent();
// 表格
let columns = [{
title: '关卡',
dataIndex: 'part',
key: 'part',
className: "edu-txt-center"
}, {
title: '任务名称',
dataIndex: 'shixunName',
key: 'shixunName',
className: "edu-txt-left with22 ",
render: (shixunName, item, index) => {
return (
<span className="overflowHidden1" style={{ maxWidth: '400px' }}
title={shixunName && shixunName.length > 25 ? shixunName : ''}
>{shixunName}</span>
)
}
}, {
title: '评测次数',
dataIndex: 'testCount',
key: 'testCount',
className: "edu-txt-center",
render: (testCount, item, index) => {
return (
<span>{item.testCount ? item.testCount : <span className="color-grey-9">--</span>}</span>
)
}
}, {
title: '完成时间',
key: 'endTime',
dataIndex: 'endTime',
className: "edu-txt-center",
render: (endTime, item, index) => {
return (
<span>{item.endTime ? item.endTime : <span className="color-grey-9">--</span>}</span>
)
}
}, {
title: '耗时',
dataIndex: 'needTime',
key: 'needTime',
className: "edu-txt-center",
render: (needTime, item, index) => {
return (
<span>{item.needTime ? item.needTime : <span className="color-grey-9">--</span>}</span>
)
}
}, {
title: '查看答案',
dataIndex: 'view_answer',
key: 'view_answer',
className: "edu-txt-center",
render: (exp, item, index) => {
return (
<span>{item.view_answer ? "已查看" : "未查看"}</span>
)
}
}, {
title: '经验值',
dataIndex: 'exp',
key: 'exp',
className: "edu-txt-center",
render: (exp, item, index) => {
return (
<span><span className="color-green">{item.my_exp}</span>/{item.total_exp}</span>
)
}
}, {
title: '得分/满分',
dataIndex: 'score',
key: 'score',
className: (isAdmin || (isStudent && exercise && exercise.exercise_status == 3)) ? "edu-txt-center" : "edu-txt-center none",
render: (score, item, index) => {
//issues#29409 2
if(this.props.questionType.is_invalid){
return <Tooltip title={'在开始答题前开启的实训题计0分'}><span className="color-orange-tip">{item.my_score}</span>/{item.total_score}</Tooltip>
}
return (
<span><span className="color-orange-tip">{item.my_score}</span>/{item.total_score}</span>
)
}
}, {
title: isAdmin ? <span><i className="color-red mr5">*</i></span> : '',
dataIndex: 'operation',
key: 'operation',
className: isAdmin ? "edu-txt-left" : "edu-txt-center",
render: (operation, item, index) => {
return (
<span>
{
this.props.isAdmin() ?
<InputNumber
min={0}
max={item.total_score}
step={0.1}
precision={1}
value={item.input_score}
style={{ width: "60px", marginLeft: "5px" }}
placeholder="请输入分数"
onChange={(value) => { this.changeThis(value, index) }}
onBlur={(event) => this.changeThisScore(event, item.id, index)}
className="greyInput"
></InputNumber>
: ""
}
{
item.operation ?
<a className={isAdmin ? "color-blue mt5 fr" : "color-blue"} href='javascript:void(0)' onClick={() => this.scrollToAnchor(`${questionType.question_id}${index + 1}`)}>查看</a>
:
<span className={isAdmin ? "color-grey-9 mt5 fr" : "color-grey-9"} >--</span>
}
</span>
)
}
}];
return (
<div>
<style>
{`
.resetTableStyle .ant-table-tbody > tr > td{
padding:10px 5px!important;
}
.resetCodeMirrorStyle .CodeMirror{
height:auto!important;
}
`}
</style>
{exercise && ((exercise.student_commit_status && exercise.student_commit_status != 0) || (exercise.user_exercise_status && exercise.user_exercise_status != 0)) ?
<div>
<p className="padding20-30 font-16 color-grey-6 pl30">阶段成绩</p>
<div className={challenge && challenge.length > 0 ? "pl30 pr30 resetTableStyle" : "pl30 pr30 resetTableStyle stageTable"}>
{data && data.length > 0 ? <Table columns={columns} dataSource={data} pagination={false}></Table> : ""}
</div>
{
challenge && challenge.length > 0 &&
<div>
<p className="mt20 pr30 font-16 color-grey-6 pl30">实训详情</p>
{
challenge.map((item, key) => {
return (
<div className="pl30 pr30 mt20" id={`challenge_${questionType.question_id}${key + 1}`}>
<p className="clearfix mb20">
<span className="panel-inner-icon mr15 fl mt3 backgroud4CACFF">
<i className="fa fa-code font-16 color_white"></i>
</span>
<span className="fl mt3 font-16">
<span className="font-bd mr15">{item[0].position}</span>
<Link to={"/tasks/" + item[0].game_identifier} style={{ "cursor": "pointer" }}>
<span className={"font-16"}>{item[0].name}</span>
</Link>
</span>
</p>
<ShixunAnswerDetail
{...this.props} {...this.state} challenge={item[0].outputs}
></ShixunAnswerDetail>
{item[0].st === 0 ? <div className="font-16 color-dark-21">
<div className="bor-grey-e mt15">
<p className="clearfix pt5 pb5 pl15 pr15 back-f6-grey codebox">
<span className="fl">最近通过的代码</span>
<span className="fr codeboxright">{item[0].path}</span>
</p>
<div className="test-code bor-top-greyE">
<li className="clearfix resetCodeMirrorStyle">
<CodeMirror
value={item[0].passed_code}
options={{
// mode: 'xml',
theme: 'default',
lineNumbers: true,
// extraKeys: {"Ctrl-Q": "autocomplete"}, // 快捷键
indentUnit: 4, //代码缩进为一个tab的距离
matchBrackets: true,
autoRefresh: true,
smartIndent: true,//智能换行
styleActiveLine: true,
lint: true,
readOnly: "nocursor"
}}
/>
</li>
</div>
</div>
</div> : ""}
</div>
)
})
}
</div>
}
</div>
:
<div className="pl30 pr30">
{
isStudent ? <RenderHtml className="color-grey-9 mt20 mb20" value={questionType.question_title} /> : null
}
{
questionType && questionType.shixun && questionType.shixun.map((item, key) => {
return (
<p key={key} className="font-16 color-grey-6 mb5">
<span className="mr20">{item.challenge_position} {item.challenge_name}</span>
<span>{item.challenge_score}</span>
</p>
)
})
}
</div>
}
</div>
)
}
}
export default shixunAnswer

View File

@ -1,70 +0,0 @@
import React, { Component } from "react";
import { Table } from "antd";
class shixunAnswerDetail extends Component {
constructor(props) {
super(props);
}
render() {
let { challenge } = this.props;
let columns = [{
title: '评测次数',
dataIndex: 'number',
width: "127px",
key: 'number',
className: "edu-txt-center",
render: (text, record) => (
<span>
{record.number || "--"}
</span>
),
}, {
title: '详细信息',
dataIndex: 'name',
key: 'name',
className: challenge && challenge.length > 0 ? "" : "edu-txt-center",
render: (text, record) => (
<span>
{record.name || "--"}
</span>
),
}];
let datas = [];
challenge && challenge.length > 0 ? challenge.map((item, key) => {
datas.push({
number: item.position || "--",
name: item.output_detail || "--"
})
})
:
datas.push({
number: "--",
name: "--"
})
return (
<div>
<style>{`
.ant-table-thead > tr > th{
text-align: center;
}
`}</style>
{
datas ?
<Table
bordered
dataSource={datas}
columns={columns}
pagination={false}
/> : ""
}
</div>
)
}
}
export default shixunAnswerDetail;

View File

@ -1,88 +0,0 @@
import React, { Component } from "react";
import TPMMDEditor from '../../../../modules/tpm/challengesnew/TPMMDEditor'
import axios from 'axios'
import RenderHtml from "../../../../components/render-html";
class simpleAnswer extends Component {
constructor(props) {
super(props);
this.mdRef = React.createRef();
this.state = {
simpleValue: undefined
}
}
onChange = (value) => {
this.setState({
simpleValue: value
})
}
onSimpleBlur = () => {
let { simpleValue } = this.state
let question_id = this.props.questionType.question_id;
let url = `/exercise_questions/${question_id}/exercise_answers.json`;
axios.post((url), {
answer_text: simpleValue
}).then((result) => {
if (result.status == 200) {
let k = simpleAnswer == "" ? 0 : 1;
this.props.changeQuestionStatus && this.props.changeQuestionStatus(parseInt(this.props.questionType.q_position) - 1, k);
}
}).catch((error) => {
console.log(error);
})
}
showAndHide = (flag) => {
this.props.changeA_flag && this.props.changeA_flag(this.props.index, flag);
}
render() {
let {
questionType,
exercise,
user_exercise_status,
} = this.props
let isAdmin = this.props.isAdmin();
let isStudent = this.props.isStudent();
return (
<div className="pl30 pr30">
<li className="with100">
{
user_exercise_status == 1 ?
<RenderHtml value={questionType.user_answer.length > 0 ? questionType.user_answer[0] : ""} className="answerStyle" />
:
<div>
<TPMMDEditor ref={this.mdRef} initValue={questionType.user_answer.length > 0 ? questionType.user_answer[0] : ''} mdID={'simpleEditor' + questionType.question_id} placeholder="请输入你的答案"
height={150} onChange={this.onChange} onCMBlur={this.onSimpleBlur}></TPMMDEditor>
</div>
}
</li>
{
// 答案公开,且试卷已经截止
isAdmin &&
<div className="bor-top-greyE pt20 mt20">
{
exercise.answer_status == 1 || questionType.a_flag ?
<div className="standardAnswer">
<p className="mb10 font-16">参考答案</p>
<RenderHtml value={questionType.standard_answer && questionType.standard_answer[0]} className="answerStyle" />
<p className="mt15"><a className="color-blue font-16" onClick={() => this.showAndHide(false)}>隐藏参考答案</a></p>
</div>
:
<a className="color-blue font-16" onClick={() => this.showAndHide(true)}>显示参考答案</a>
}
</div>
}
{
isStudent && questionType.standard_answer ?
<div className="bor-top-greyE pt20 mt20 standardAnswer">
<p className="mb10 font-16">参考答案</p>
<RenderHtml value={questionType.standard_answer && questionType.standard_answer[0]} className="answerStyle" />
</div> : ""
}
</div>
)
}
}
export default simpleAnswer

View File

@ -1,93 +0,0 @@
import React, { Component } from "react";
import { Radio } from "antd";
import axios from 'axios'
import RenderHtml from "../../../../components/render-html";
const tagArray = [
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I',
'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R',
'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
]
class single extends Component {
constructor(props) {
super(props);
}
changeItem = (e) => {
let choiceId = e.target.value;
let question_id = this.props.questionType.question_id;
let { index } = this.props;
let url = `/exercise_questions/${question_id}/exercise_answers.json`;
axios.post((url), {
exercise_choice_id: choiceId
}).then((result) => {
if (result) {
this.props.changeOption && this.props.changeOption(index, [choiceId]);
this.props.changeQuestionStatus && this.props.changeQuestionStatus(parseInt(this.props.questionType.q_position) - 1, 1);
}
}).catch((error) => {
console.log(error);
})
}
render() {
let {
questionType,
exercise,
user_exercise_status,
is_md
} = this.props
let isStudent = this.props.isStudent();
let isJudge = questionType.question_type == 2
return (
<div className="pl30 pr30 singleDisplay">
<style>
{
`
.single .ql-editor{
overflow: unset !important;
padding:0px !important;
}
.single .ql-editor p{
line-height: 25px !important;
}
.single {
white-space: inherit !important;
}
`
}
</style>
<Radio.Group className="with100" disabled={user_exercise_status == 1 ? true : false} value={questionType.user_answer[0]} onChange={this.changeItem}>
{
questionType.question_choices && questionType.question_choices.map((item, key) => {
let prefix = isJudge ? undefined : `${tagArray[key]}.`
let titename = item.choice_text;
return (
<p key={item.choice_id} className={parseInt(questionType.question_type) == 0 ? "clearfix mb15" : "fl mr40"}>
<Radio className="df lineh-25 setRadioStyle single" value={item.choice_id}>
<span className="fl mr3 lineh-25">{prefix}</span>
<RenderHtml value={titename} className="flex1" style={{ display: "inline-block" }} />
</Radio>
</p>
)
})
}
</Radio.Group>
{
// 答案公开,且试卷已经截止
isStudent && exercise && exercise.answer_open == true && (exercise.exercise_status == 3 || user_exercise_status == 1) &&
<p className="bor-top-greyE pt20 mt10 font-16">参考答案
{questionType.standard_answer.map((i, k) => {
return (
<span key={k} value={k}>{tagArray[parseInt(i) - 1]}</span>
)
})
}
</p>
}
</div>
)
}
}
export default single

View File

@ -1,62 +0,0 @@
.maxnamewidth100{
max-width: 100px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
cursor: default;
}
.maxnamewidth110{
max-width: 100px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
cursor: default;
}
.maxnamewidth200{
max-width: 200px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
cursor: default;
}
.maxnamewidth145{
max-width: 145px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
cursor: default;
}
.maxnamewidth215{
max-width: 215px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
cursor: default;
}
.maxnamewidth255{
max-width: 255px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
cursor: default;
}
.maxnamewidth175{
max-width: 175px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap;
cursor: default;
}
.maxnamewidth260 {
max-width: 260px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
cursor: default;
}
.columnstwoachievement{
width: 199px;
text-align: right !important;
padding-right: 97px !important;
}

View File

@ -1,631 +0,0 @@
import React,{ Component } from "react";
import {Checkbox, Pagination,Menu ,Spin} from "antd";
import {WordsBtn, on, off, publicSearchs } from 'educoder';
import HomeworkModal from "../coursesPublic/HomeworkModal";
import AddcoursesNav from "../coursesPublic/AddcoursesNav";
import ImmediatelyPublish from './pollPublicBtn/ImmediatelyPublish';
import ImmediatelyEnd from './pollPublicBtn/ImmediatelyEnd';
import PollListItem from './PollListItem';
import NoneData from '../coursesPublic/NoneData';
import UseBank from '../busyWork/UseBank';
import _ from 'lodash';
import '../css/members.css';
import '../css/busyWork.css';
import Modals from '../../modals/Modals';
import axios from 'axios';
import moment from 'moment';
class Poll extends Component{
constructor(props){
super(props);
this.state={
modalname:undefined,
modaltype:undefined,
visible:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
StudentList_value:undefined,
addname:undefined,
addnametype:false,
addnametab:undefined,
addcanner:undefined,
addsave:undefined,
course_groups:[],
chooseId:undefined,
// 列表相关
checkBoxValues:[],
checkAllValue:false,
pollsList:undefined,
course_types:undefined,
page:1,
pageSize:15,
type:0,
polls_counts:undefined,
//公用提示弹框相关
modalsType:false,
modalsTopval:"",
modalsBottomval:"",
loadtype:false,
boxType:"delete",
isSpin:false
}
}
inputStudent=(e)=>{
this.setState({
StudentList_value:e.target.value,
})
}
// 题库选用
selectBlank=(type)=>{
if(type===2){
this.setState({
addname:"新建目录",
addnametype:true,
addnametab:type,
addcanner:this.homeworkhide,
addsave:undefined
})
}else if(type===4){
this.setState({
addname:"移动到目录",
addnametype:true,
addnametab:type,
addcanner:this.homeworkhide,
addsave:undefined
})
}
}
// 切换菜单选项
changeType=(e)=>{
this.setState({
type:e.key,
page:1,
checkBoxValues:[],
checkAllValue:false
})
let{StudentList_value,page}=this.state;
this.InitList(e.key,StudentList_value,1);
}
// 获取列表数据
InitList=(type,search,page,bank_checkValue)=>{
this.setState({
isSpin:true
})
let { pageSize,checkBoxValues }=this.state
let coursesId=this.props.match.params.coursesId;
let url='/courses/'+coursesId+'/polls.json?limit='+pageSize+'&page='+page
if(type!="0"){
url+="&type="+type
}
if(search!=""&&search!=undefined){
url+="&search="+search
}
url=encodeURI(url);//IE11传参为乱码search
axios.get(url).then((result)=>{
if(result){
this.setState({
pollsList:result.data.polls,
course_types:result.data.course_types,
polls_counts:result.data.polls_counts,
isSpin:false,
checkBoxValues: bank_checkValue ? bank_checkValue : [],
page:page
})
}
}).catch((error)=>{
console.log(error);
})
}
// 加载列表
componentDidMount(){
this.setState({
isSpin:true
})
let{type,StudentList_value,page}=this.state
this.InitList(type,StudentList_value,page);
on('updateNavSuccess', this.updateNavSuccess)
}
updateNavSuccess=()=>{
this.setState({
isSpin:true
})
let{type,StudentList_value,page}=this.state
this.InitList(type,StudentList_value,page);
}
//切换分页
changePage=(pageNumber)=>{
let{type,StudentList_value,checkAllValue}=this.state;
if(checkAllValue===true){
this.setState({
page:pageNumber,
checkBoxValues:[],
checkAllValue:false
})
}else{
this.setState({
page:pageNumber,
checkBoxValues:[]
})
}
this.InitList(type,StudentList_value,pageNumber);
}
// 搜索
searchInfo=(value)=>{
this.setState({
page:1,
StudentList_value:value
})
let{type}=this.state;
this.InitList(type,value,1)
}
// checkbox
onItemClick = (item) => {
const checkBoxValues = this.state.checkBoxValues.slice(0);
const index = checkBoxValues.indexOf(item.id);
if (index != -1) {
_.remove(checkBoxValues, (listItem)=> listItem === item.id)
} else {
checkBoxValues.push(item.id);
}
this.onCheckBoxChange(checkBoxValues)
}
// 全选or反选
onCheckAll = (e) => {
this.setState({
checkAllValue: e.target.checked
})
const values = this.state.pollsList.map(item => {
return item.id
})
if (e.target.checked) {
const concated = this.state.checkBoxValues.concat(values);
const uniq=_.uniq(concated)
this.setState({
checkBoxValues: uniq
})
} else {
this.setState({
checkBoxValues: _.difference(this.state.checkBoxValues, values)
})
}
}
onCheckBoxChange = (checkedValues) => {
this.setState({
checkBoxValues: checkedValues,
checkAllValue: checkedValues.length == this.state.pollsList.length
})
}
//删除或者设为公开
ActionPoll=(value)=>{
let CourseId=this.props.match.params.coursesId;
//判断是否有选中数据
if(this.state.checkBoxValues.length==0){
this.props.showNotification("请先在列表中选择数据");
}else{
if(value != "bank"){
this.setState({
modalsType:true,
modalsTopval:value=="delete"?"已提交作品将全部被删除,不可恢复":"公开后非课堂成员也可以访问查看",
modalsBottomval:value=="delete"?"您确定要删除吗?":"是否确认公开?",
loadtype:false,
boxType:value
})
}else{
//加入题库
let url=`/courses/${CourseId}/polls/join_poll_banks.json`;
axios.post((url), {
check_ids: this.state.checkBoxValues
})
.then((result)=>{
if(result){
this.props.showNotification(`${result.data.message}`);
this.setState({
modalsType:false,
modalsTopval:"",
modalsBottomval:"",
loadtype:false,
checkBoxValues:[],
checkAllValue:false
})
let{type,StudentList_value}=this.state
this.InitList(type,StudentList_value,1);
}
}).catch((error)=>{
console.log(error);
})
}
}
}
//取消删除或者设为公开
modalCancel=()=>{
this.setState({
modalsType:false,
modalsTopval:"",
modalsBottomval:"",
loadtype:false
})
}
//确定删除或者设为公开
ModalAction=()=>{
let CourseId=this.props.match.params.coursesId;
if(this.state.checkBoxValues.length==0){
this.setState({
modalsType:false,
modalsTopval:"",
loadtype:false,
checkBoxValues:[]
})
}else{
if(this.state.boxType=="delete"){
//删除
let url=`/courses/${CourseId}/polls/destroys.json`;
axios.post((url), {
check_ids: this.state.checkBoxValues
})
.then((result)=>{
if(result){
this.props.showNotification(`${result.data.message}`);
this.setState({
modalsType:false,
modalsTopval:"",
modalsBottomval:"",
loadtype:false,
checkBoxValues:[]
})
let{type,StudentList_value}=this.state
this.InitList(type,StudentList_value,1);
this.props.updataleftNavfun();
}
}).catch((error)=>{
console.log(error);
})
}else if(this.state.boxType=="public"){
//设为公开
let url=`/courses/${CourseId}/polls/set_public.json`;
axios.post((url), {
check_ids: this.state.checkBoxValues
})
.then((result)=>{
if(result){
this.props.showNotification(`${result.data.message}`);
this.setState({
modalsType:false,
modalsTopval:"",
loadtype:false,
checkBoxValues:[]
})
let{type,StudentList_value}=this.state
this.InitList(type,StudentList_value,1);
}
}).catch((error)=>{
console.log(error);
})
}
}
}
successFun=()=>{
let{type,StudentList_value,page}=this.state
this.InitList(type,StudentList_value,page)
}
// 题库选用成功后,立即发布,刷新页面
useBankSuccess=(checkValue,value)=>{
;
this.setState({
isSpin:true
})
let{type,StudentList_value,page}=this.state
this.InitList(type,StudentList_value,page,value);
let coursesId=this.props.match.params.coursesId;
let url=`/courses/${coursesId}/polls/publish_modal.json`;
axios.get(url,{
params:{
check_ids:value
}
}).then((response) => {
if(response){
let list=[];
if(response.data.course_info){
for(var i=0;i<response.data.course_info.length;i++){
list.push({
id:response.data.course_info[i].course_group_id,
name:response.data.course_info[i].course_group_name,
})
}
}
this.setState({
modalname:"立即发布",
modaltype:response.data.un_publish > 0 ? 1 : 2,
visible:true,
Topval:"本操作只对“未发布”的对象生效",
Botvalleft:"暂不发布",
Botval:"则通过后续手动设置,定时发布",
starttime:"发布时间:"+moment(moment(new Date())).format("YYYY-MM-DD HH:mm"),
starttimes:this.props.getNowFormatDates(1),
endtime:"截止时间:"+this.props.getNowFormatDates(2),
Cancelname:"暂不发布",
Savesname:"立即发布",
Cancel:this.homeworkhide,
Saves:this.homeworkstartend,
course_groups:list,
checkBoxValues:value
})
}
}).catch((error) => {
console.log(error)
});
}
getcourse_groupslist=(id)=>{
this.setState({
chooseId:id
})
}
// 确定立即发布
homeworkstartend=(value,endtime)=>{
let {checkBoxValues}=this.state;
let coursesId=this.props.match.params.coursesId;
let url=`/courses/${coursesId}/polls/publish.json`
axios.post(url,{
check_ids:checkBoxValues,
group_ids:value,
end_time:endtime
}).then((result)=>{
if(result){
let{type,StudentList_value,page}=this.state
this.InitList(type,StudentList_value,page);
this.props.showNotification(result.data.message);
this.homeworkhide();
}
}).catch((error)=>{
console.log(error);
})
}
//暂不发布
homeworkhide=()=>{
this.setState({
modalname:undefined,
modaltype:undefined,
visible:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
StudentList_value:undefined,
addname:undefined,
addnametype:false,
addnametab:undefined,
// checkBoxValues:[]
})
}
render(){
let {
modalname,
modaltype,
visible,
Topval,
Topvalright,
Botvalleft,
Botval,
starttime,
endtime,
Cancelname,
Savesname,
Cancel,
Saves,
StudentList_value,
addname,
addnametype,
addnametab,
addcanner,
addsave,
course_groups,
checkAllValue,
checkBoxValues,
course_types,
pollsList,
page,
pageSize,
polls_counts,
modalsType,
modalsTopval,
modalsBottomval,
loadtype
}=this.state;
// console.log(this.props);
let {child}=this.props;
let {coursesId,Id}=this.props.match.params
const isAdmin = this.props.isAdmin()
const isStudent=this.props.isStudent();
// console.log(child)
return(
<React.Fragment >
{visible===true?<HomeworkModal
modaltype={modaltype}
modalname={modalname}
visible={visible}
Topval={Topval}
Topvalright={Topvalright}
Botvalleft={Botvalleft}
Botval={Botval}
starttime={starttime}
starttimes={this.state.starttimes}
endtime={endtime}
Cancelname={Cancelname}
Savesname={Savesname}
Cancel={Cancel}
Saves={Saves}
course_groups={course_groups}
getcourse_groupslist={(id)=>this.getcourse_groupslist(id)}
/>:""}
{/*添加目录/选择目录*/}
<AddcoursesNav
addname={addname}
addnametype={addnametype}
addnametab={addnametab}
addcanner={addcanner}
addsave={addsave}
/>
{/* 公用的提示弹框 */}
<Modals
modalsType={modalsType}
modalsTopval={modalsTopval}
modalsBottomval={modalsBottomval}
loadtype={loadtype}
modalCancel={this.modalCancel}
modalSave={this.ModalAction}
></Modals>
<div className="edu-back-white">
<p className="clearfix padding30 bor-bottom-greyE">
<span className="font-18 fl color-dark-21">{polls_counts&&polls_counts.left_banner_name}</span>
{
isAdmin &&
<li className="fr">
<p className="fl"><UseBank {...this.props} {...this.state} object_type={"poll"} useBankSuccess={this.useBankSuccess}></UseBank></p>
<WordsBtn style="blue" className="font-16" to={`/classrooms/${coursesId}/polls/${Id}/${"new"}`}>新建</WordsBtn>
</li>
}
</p>
<div className="clearfix pl30 pr30">
<p className="fl font-14" style={{"marginTop":"27px"}}>
<span className="mr20">{polls_counts && polls_counts.polls_total_counts}个问卷</span>
<span className="mr20">已发布{polls_counts && polls_counts.polls_published_counts}</span>
<span>未发布{polls_counts && polls_counts.polls_unpublish_counts}</span>
</p>
<div className="fr mt16 mb16 searchView">
{publicSearchs("请输入名称进行搜索",this.searchInfo,this.inputStudent,this.inputStudent)}
{/*<Search*/}
{/* value={StudentList_value}*/}
{/* placeholder="请输入名称进行搜索"*/}
{/* onInput={this.inputStudent}*/}
{/* onSearch={this.searchInfo}*/}
{/*></Search>*/}
</div>
</div>
<div className="task_menu_ul pl30 pr30">
<Menu mode="horizontal" defaultSelectedKeys="0" onClick={this.changeType}>
<Menu.Item key="0">全部</Menu.Item>
{ course_types && course_types.user_permission == 1 && <Menu.Item key="1">未发布</Menu.Item> }
<Menu.Item key="2">提交中</Menu.Item>
<Menu.Item key="3">已截止</Menu.Item>
</Menu>
</div>
</div>
<Spin size="large" spinning={this.state.isSpin}>
{
pollsList && pollsList.length > 0 && isAdmin &&
<div className="mt20 edu-back-white padding20-30">
<div className="clearfix">
<Checkbox className="fl" onChange={this.onCheckAll} checked={checkAllValue}>已选 {checkBoxValues.length} 不支持跨页勾选</Checkbox>
<div className="studentList_operation_ul">
<li className="li_line"><a className="color-grey-9" onClick={()=>this.ActionPoll("delete")}>删除</a></li>
<li className="li_line">
<ImmediatelyPublish
{...this.props}
{...this.state}
style="grey"
checkBoxValues={this.state.checkBoxValues}
action={this.successFun}
></ImmediatelyPublish>
</li>
<li className="li_line">
<ImmediatelyEnd
{...this.props}
{...this.state}
style="grey"
single={true}
checkBoxValues={this.state.checkBoxValues}
action={this.successFun}
></ImmediatelyEnd>
</li>
{
course_types && course_types.course_is_public == 1 && <li className="li_line"><a className="color-grey-9" onClick={()=>this.ActionPoll("public")}>设为公开</a></li>
}
{this.props.user&&this.props.user.main_site===true?<li className="li_line"><a className="color-grey-9" onClick={()=>this.ActionPoll("bank")}>加入题库</a></li>:""}
</div>
</div>
</div>
}
{
pollsList && pollsList.length > 0 &&
<Checkbox.Group style={{ width: '100%' }} onChange={this.onCheckBoxChange} value={checkBoxValues}>
<div className="workList mt20">
{
pollsList && pollsList.map((item,key)=>{
return(
<PollListItem
{...this.props}
{...this.state}
courseType={course_types}
item={item}
index={key}
onItemClick={this.onItemClick}
checkBox={<Checkbox value={item.id} key={item.id} onClick={() => this.onItemClick(item)}></Checkbox>}
></PollListItem>
)
})
}
</div>
</Checkbox.Group>
}
</Spin>
{
pollsList && pollsList.length==0 && <NoneData></NoneData>
}
{
course_types && polls_counts.polls_all_counts > pageSize ?
<div className="mt30 edu-txt-center pb30">
<Pagination showQuickJumper current={page} total={polls_counts && polls_counts.polls_all_counts} pageSize={pageSize} onChange={this.changePage}></Pagination>
</div>
:
""
}
</React.Fragment>
)
}
}
export default Poll;

View File

@ -1,306 +0,0 @@
import React,{ Component } from "react";
import {Menu} from "antd";
import CoursesListType from '../coursesPublic/CoursesListType';
import { WordsBtn,getRandomcode } from 'educoder'
import PollTabFirst from './PollDetailTabFirst'
import PollTabSecond from './PollDetailTabSecond'
import PollTabThird from './PollDetailTabThird'
import PollTabForth from './PollDetailTabForth'
import DownloadMessageysl from "../../modals/DownloadMessageysl";
import ImmediatelyPublish from './pollPublicBtn/ImmediatelyPublish'
import ImmediatelyEnd from './pollPublicBtn/ImmediatelyEnd'
import CancelPublish from './pollPublicBtn/CancelPublish'
import '../css/members.css'
import '../css/busyWork.css'
import axios from 'axios'
import Itembankstop from "../../question/component/Itembankstop";
const map={1:"未发布",2:"提交中",3:"已截止",4:"已结束"}
class PollDetailIndex extends Component{
constructor(props){
super(props);
this.pollssubcomRef = React.createRef();
this.state={
tab:["0"],
pollDetail:undefined,
user_permission:undefined,
DownloadType:false,
DownloadMessageval:undefined,
polls_status:3,
}
}
getpollssubcomRef = (Ref) => {
this.pollssubcomRef = Ref;
}
getPollInfo=()=>{
// console.log(this.props);
let pollId=this.props.match.params.pollId;
let url=`/polls/${pollId}/common_header.json`
axios.get(url).then((result)=>{
if(result.status==200){
this.setState({
pollDetail:result.data,
user_permission:result.data.user_permission,
polls_status:result.data.polls_status,
})
}
}).catch((error)=>{
console.log(error);
})
let{tab}=this.state;
try {
if(tab[0]==="0"){
this.child.Teacherliststudentlist();
}
if(tab[0]==="1"){
this.child.Teacherliststudentlist();
}
if(tab[0]==="2"){
this.child.Teacherliststudentlist();
}
if(tab[0]==="3"){
this.child.getSettingInfo();
}
}catch (e) {
}
this.gettables();
}
gettables=()=>{
try {
this.pollssubcomRef.searchInfo();
}catch (e) {
}
}
newgetPollInfo=()=>{
// console.log(this.props);
let pollId=this.props.match.params.pollId;
let url=`/polls/${pollId}/common_header.json`
axios.get(url).then((result)=>{
if(result.status==200){
this.setState({
pollDetail:result.data,
user_permission:result.data.user_permission,
polls_status:result.data.polls_status,
})
}
}).catch((error)=>{
console.log(error);
})
}
componentDidMount(){
const query =this.props.location.search;
if(query.indexOf("?")!=-1){
const type = query.split('?');
let name = type[1].split("tab=");
name = String(name).split(",");
name = decodeURI(name[1]);
if(name!=undefined && name!="" && name!="undefined"){
this.setState({
tab:[name]
})
}
}
this.getPollInfo();
}
//切换tab
changeTab=(e)=>{
this.setState({
tab:e.key
})
}
/// 确认是否下载
confirmysl(url){
axios.get(url + '&export=true' ).then((response) => {
if(response.data.status&&response.data.status===-1){
}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
})
}
}else {
this.props.slowDownload(getRandomcode(url))
// this.props.showNotification(`正在下载中`);
// window.open("/api"+url, '_blank');
}
}).catch((error) => {
console.log(error)
});
}
Downloadcal=()=>{
this.setState({
DownloadType:false,
DownloadMessageval:undefined
})
}
bindRef = ref => { this.child = ref };
render(){
let {tab,pollDetail,user_permission,polls_status}=this.state;
const { current_user } = this.props;
const isAdmin =this.props.isAdmin();
const isStudent = this.props.isStudent();
document.title=this.props.coursedata&&this.props.coursedata.name;
return(
<div className="newMain">
<DownloadMessageysl
{...this.props}
value={this.state.DownloadMessageval}
modalCancel={this.Downloadcal}
modalsType={this.state.DownloadType}
/>
<div className="educontent mt10 mb50">
<p className="clearfix mb20">
<WordsBtn style="grey" className="fl" to={current_user && current_user.first_category_url}>{this.props.coursedata.name}</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<WordsBtn style="grey" className="fl" to={`/classrooms/${this.props.match.params.coursesId}/polls/${user_permission && user_permission.left_banner_id}`}>问卷</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<span>问卷详情</span>
</p>
<p className="clearfix mb20 lineh-25">
<span className="color-grey-3 font-24 fl task-hide break-word" style={{maxWidth:"900px",lineHeight:"25px"}} title={`${pollDetail && pollDetail.polls_name}`}>{pollDetail && pollDetail.polls_name}</span>
<span className="mt3 fl" style={{height:"25px"}}>
<CoursesListType typelist={[`${map[pollDetail && pollDetail.polls_status]}`]} typesylename={""} />
</span>
<WordsBtn className="fr font-16 mt2" style="grey" to={`/classrooms/${this.props.match.params.coursesId}/polls/${user_permission && user_permission.left_banner_id}`}>返回</WordsBtn>
</p>
<div>
<div className="clearfix edu-back-white pl30 pr30 bor-bottom-greyE">
<div className="fl task_menu_ul">
<Menu mode="horizontal" selectedKeys={tab} onClick={this.changeTab}>
<Menu.Item key="0">答题列表</Menu.Item>
{
(isAdmin || (isStudent && pollDetail && pollDetail.show_result == 1 && pollDetail.polls_status == 3 && user_permission && user_permission.current_status==1)) && <Menu.Item key="1">统计结果</Menu.Item>
}
{ isAdmin && <Menu.Item key="2">问卷预览</Menu.Item> }
<Menu.Item key="3">设置</Menu.Item>
</Menu>
</div>
{
isAdmin &&
<span className="fr mt22">
<WordsBtn style="blue" to={`/classrooms/${this.props.match.params.coursesId}/polls/${this.props.match.params.pollId}/edit`} className="fl mr20 font-16">编辑问卷</WordsBtn>
{/* 立即发布 */}
{
user_permission && user_permission.poll_unpublish_count > 0 ?
<li className="fl mr20">
<ImmediatelyPublish
{...this.props}
{...this.state}
style="blue"
className={"font-16"}
checkBoxValues={[this.props.match.params.pollId]}
action={this.getPollInfo}
pushtype={true}
single={true}
></ImmediatelyPublish>
</li>
:""
}
{/* 立即截止、撤销发布 */}
{
user_permission && user_permission.poll_publish_count > 0 ?
<li className="fl mr20">
<ImmediatelyEnd
{...this.props}
{...this.state}
style="blue"
className={"font-16"}
checkBoxValues={[this.props.match.params.pollId]}
action={this.getPollInfo}
// single={true}
></ImmediatelyEnd>
</li>
:""
}
{/* {
user_permission && user_permission.poll_publish_count>0 ?
<li className="fl mr20">
<CancelPublish
{...this.props}
{...this.state}
style="blue"
checkBoxValues={[this.props.match.params.pollId]}
action={this.getPollInfo}
></CancelPublish>
</li>
:""
} */}
<a className="fl color-blue font-16" onClick={(url)=>this.confirmysl(`/polls/${this.props.match.params.pollId}/commit_result.xlsx`)} href="javascript:void(0);">导出统计</a>
</span>
}
{
isStudent &&
<span className="fr mt22 font-16">
{
user_permission && user_permission.current_status!=3 ?
<WordsBtn style="blue" to={`/classrooms/${this.props.match.params.coursesId}/polls/${this.props.match.params.pollId}/users/${this.props.current_user.login}`}>
{ user_permission && user_permission.current_status ==0 ? "继续答题" :
user_permission.current_status == 1 ?
(polls_status===1?"":"查看答题")
:user_permission.current_status == 2 ?(polls_status===3?"":polls_status===4?"":"开始答题"):""
}
</WordsBtn>
:""
}
</span>
}
</div>
{
// 答题列表
parseInt(tab[0])==0 && <PollTabFirst
{...this.props}
{...this.state}
getpollssubcomRef={(ref) => this.getpollssubcomRef(ref)}
></PollTabFirst>
}
{
// 统计结果
parseInt(tab[0])==1 && <PollTabSecond {...this.props} {...this.state}></PollTabSecond>
}
{
//问卷预览
parseInt(tab[0])==2 && <PollTabThird {...this.props} {...this.state}></PollTabThird>
}
{
//设置
parseInt(tab[0])==3 && <PollTabForth {...this.props} {...this.state} triggerRef={this.bindRef} user_permission={user_permission} getPollInfo={this.getPollInfo} newgetPollInfo={this.newgetPollInfo}></PollTabForth>
}
</div>
</div>
</div>
)
}
}
export default PollDetailIndex

View File

@ -1,422 +0,0 @@
import React,{ Component } from "react";
import {Checkbox,Input,Table, Pagination} from "antd";
import {WordsBtn, sortDirections} from 'educoder'
import moment from 'moment';
import CheckAllGroup from '../common/button/CheckAllGroup'
import NoneData from "../coursesPublic/NoneData"
import '../css/members.css'
import '../css/busyWork.css'
import './pollStyle.css'
import axios from 'axios'
const Search=Input.Search;
function formatDuring(mss){
var days = parseInt(mss / (1000 * 60 * 60 * 24));
var hours = parseInt((mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
var minutes = parseInt((mss % (1000 * 60 * 60)) / (1000 * 60));
try {
days = Math.abs(days);
} catch (e) {
}
try {
hours = Math.abs(hours);
} catch (e) {
}
try {
minutes = Math.abs(minutes);
} catch (e) {
}
return days + "天" + hours + "小时" + minutes + "分";
}
class PollDetailTabFirst extends Component{
constructor(props){
super(props);
this.state={
order:"end_at",
search:undefined,
commit_status:[],
poll_group_id:[],
page:1,
limit:20,
dataInfo:undefined,
data:undefined,
poll_types:undefined,
course_groups:undefined,
options_Class:[],
poll_end_at: "",
order_type: "desc"
}
}
// 搜索框搜索
inputStudent=(e)=>{
this.setState({
search:e.target.value
})
}
searchInfo=()=>{
let {order, search, commit_status, poll_group_id, page, order_type} = this.state;
this.setState({
page:1
})
this.getTableList(order, search, commit_status, poll_group_id, 1, order_type);
}
// 获取接口数据
getTableList = (order, search, commit_status, poll_group_id, page, order_type) => {
let pollId=this.props.match.params.pollId;
let courseid=this.props.match.params.coursesId;
let url=`/polls/${pollId}/poll_lists.json`;
axios.get((url),{
params:{
limit:this.state.limit,
order:order,
search:search,
commit_status:commit_status,
poll_group_id:poll_group_id,
page: page,
order_type: order_type
}
}).then((result)=>{
if(result){
let list=[];
let users=result.data.poll_users;
let{page,limit}=this.state;
if(users.length!=0){
for(var i=0;i<users.length;i++){
list.push({
No:(parseInt(page)-1)*parseInt(limit)+(i+1),
name:users[i].user_name,
StudentNo:users[i].student_id,
classes:users[i].user_group_name,
status:users[i].commit_status ,
time:users[i].end_at ,
operation:users[i].commit_status,
login:users[i].login
})
}
}
let classes=[];
let groups=result.data.course_groups;
if(groups){
for(var i=0;i<groups.length;i++){
classes.push({
value:groups[i].course_group_id,
label:groups[i].group_group_name+"("+groups[i].count+")"
})
}
}
let endTime=result.data.poll_types.poll_end_time;
if(endTime!=undefined && endTime!=""){
let t= moment(endTime,'YYYY-MM-DD HH:mm') - moment();
endTime=t > 0 ? formatDuring(t) : "0";
}
this.setState({
poll_end_at:endTime,
dataInfo:result.data.poll_users,
data:list,
poll_types:result.data.poll_types,
course_groups:result.data.course_groups,
options_Class:classes
})
}
}).catch((error)=>{
console.log(error);
})
}
componentDidMount(){
let {order, search, commit_status, poll_group_id, page, order_type} = this.state;
this.getTableList(order, search, commit_status, poll_group_id, page, order_type);
try {
this.props.getpollssubcomRef(this);
} catch (e) {
}
}
// 翻页
changePage=(pageNumber)=>{
this.setState({
page:pageNumber
})
let {order, search, commit_status, poll_group_id, order_type} = this.state;
this.getTableList(order, search, commit_status, poll_group_id, pageNumber, order_type);
}
//排序
changeOrder = (order, order_type) => {
this.setState({
order:order
})
let {search,commit_status,poll_group_id,page}=this.state;
this.getTableList(order, search, commit_status, poll_group_id, page, order_type);
}
//选择分班情况
classOptionsChange = (values,all) => {
let status= all == false ? values : [];
this.setState({
poll_group_id:status
})
let {order, search, commit_status, page, order_type} = this.state;
this.getTableList(order, search, commit_status, status, page, order_type);
}
//选择提交状态
statusOptionChange=(values,all)=>{
let status= all == false ? values : [];
this.setState({
commit_status:status
})
let {order, search, poll_group_id, page, order_type} = this.state;
this.getTableList(order, search, status, poll_group_id, page, order_type);
}
//问卷table 列表塞选数据
table1handleChange = (pagination, filters, sorter) => {
//"ascend" 升序
//"descend" 降序
if (JSON.stringify(sorter) === "{}") {
//没有选择
} else {
try {
//学生学号排序
if (sorter.columnKey === "StudentNo") {
if (sorter.order === "ascend") {
//升序
this.setState({
order_type: "asc",
order: "student_id",
loadingstate: true,
});
this.changeOrder("student_id", "asc");
} else if (sorter.order === "descend") {
//降序
this.setState({
order_type: "desc",
order: "student_id",
loadingstate: true,
})
this.changeOrder("student_id", "desc");
}
}
} catch (e) {
}
try {
//提交时间排序
if (sorter.columnKey === "time") {
if (sorter.order === "ascend") {
//升序
this.setState({
order_type: "asc",
order: "end_at",
loadingstate: true,
})
this.changeOrder("end_at", "asc");
} else if (sorter.order === "descend") {
//降序
this.setState({
order_type: "desc",
order: "end_at",
loadingstate: true,
})
this.changeOrder("end_at", "desc");
}
}
} catch (e) {
}
}
}
render(){
let {order,search,data,page,limit,course_groups,poll_types,options_Class,dataInfo,poll_end_at}=this.state;
const isAdmin =this.props.isAdmin();
const isStudent = this.props.isStudent();
//分班
const options_status = [
{ label: `未提交(${poll_types && poll_types.unanswer_users})`, value: '0' },
{ label: `按时提交(${poll_types && poll_types.answer_users})`, value: '1' }
];
// 表格
let columns = [{
title: '序号',
dataIndex: 'No',
key: 'No',
className:"edu-txt-center",
width:120
}, {
title: '姓名',
dataIndex: 'name',
key: 'name',
className:"edu-txt-center",
width:170
}, {
title: '学号',
dataIndex: 'StudentNo',
key: 'StudentNo',
className:"edu-txt-center",
sorter: true,
sortDirections: sortDirections,
render:(StudentNo,item,index)=>{
return(
item.StudentNo ? <span>{item.StudentNo}</span> : "--"
)
}
}, {
title: '分班',
key: 'classes',
dataIndex: 'classes',
width:220,
className:poll_types && poll_types.groups_count > 0 ? "edu-txt-center":"edu-txt-center none",
render:(classes,item,index)=>{
return(
item.classes ? <span style={{maxWidth:'208px',display:"block"}} title={item.classes} className="task-hide">{item.classes}</span> : <span className="color-grey-9">--</span>
)
}
}, {
title: '提交状态',
dataIndex: 'status',
key: 'status',
className:"edu-txt-center",
width:170,
render:(status,item,index)=>{
return(
item.status == 1 ?<span className='color-green'>按时提交</span>:<span></span>
)
}
}, {
title: '提交时间',
dataIndex: 'time',
key: 'time',
className:"edu-txt-center",
width:170,
sorter: true,
defaultSortOrder: 'descend',
sortDirections: sortDirections,
render:(time,item,index)=>{
return(
item.time == null ? <span className="color-grey-9">--</span> : moment(item.time).format('YYYY-MM-DD HH:mm')
)
}
},{
title: '操作',
dataIndex: 'operation',
key: 'operation',
className:"edu-txt-center",
width:120,
render:(operation,item,index)=>{
return(
item.status == 1 ? <WordsBtn style="blue" targets={"_blank"} to={`/classrooms/${this.props.match.params.coursesId}/polls/${this.props.match.params.pollId}/users/${item.login}`}>查看</WordsBtn>:<span className="color-grey-9">--</span>
)
}
}];
// 非课堂成员不显示学号列
let isNotMember =this.props.isNotMember();
if(isNotMember){
columns.some((item,key)=> {
if (item.title === "学号") {
columns.splice(key, 1)
return true
}
}
)
}
// un_anonymous true为实名问卷显示操作列否则隐藏
if(poll_types && (isNotMember || poll_types.un_anonymous == false)){
columns.some((item,key)=> {
if (item.title === "操作") {
columns.splice(key, 1)
return true
}
}
)
}
console.log(this.props.pollDetail&&this.props.pollDetail.polls_status)
return(
<div>
{
isAdmin ?
this.props.pollDetail&&this.props.pollDetail.polls_status===undefined||this.props.pollDetail&&this.props.pollDetail.polls_status===1?"":<div className="pt30 pl30 clearfix edu-back-white">
<div className="pr30 clearfix">
<p className="fl mt5">
<CheckAllGroup options={options_status} label={'答题状态:'} onChange={this.statusOptionChange}></CheckAllGroup>
</p>
<div className="fr searchView height30">
<Search
value={search}
placeholder="请输入姓名或学号搜索"
onInput={this.inputStudent}
onSearch={this.searchInfo}
></Search>
</div>
</div>
{
course_groups && course_groups.length > 1 ?
<div className="mt15">
<CheckAllGroup options={options_Class} label={'分班情况:'} onChange={this.classOptionsChange}></CheckAllGroup>
</div>
:""
}
</div>:""
}
{this.props.pollDetail&&this.props.pollDetail.polls_status===undefined||this.props.pollDetail&&this.props.pollDetail.polls_status===1?"":<div className="clearfix padding20-30 edu-back-white">
{
isAdmin ? <span className="fl color-grey-3 font-12"><span className="color-orange-tip">{poll_types && poll_types.total_users}</span>{poll_types && poll_types.poll_users_count} </span> :""
}
{
isStudent ?
<span className="fl color-grey-3 font-12">
{poll_types && poll_types.answer_users===undefined?"":<span className="mr15"><span className="color-orange-tip">{poll_types && poll_types.answer_users}</span> </span>}
{poll_types && poll_types.unanswer_users===undefined?"":<span className="mr15">{poll_types && poll_types.unanswer_users} 未交</span>}
{
poll_end_at != "0" ?
<span className="color-grey-9"> 剩余提交时间<span className="color-orange-tip">{poll_end_at}</span></span>
: ""
}
</span>
: ""
}
{/*{*/}
{/* isAdmin && */}
{/* <div className="fr">*/}
{/* <li className="drop_down">*/}
{/* <span className="color-grey-9 font-12">{order=="end_at"?"提交时间":"学生学号"}</span><i className="iconfont icon-xiajiantou font-12 ml2 color-grey-6"></i>*/}
{/* <ul className="drop_down_normal">*/}
{/* <li onClick={()=>this.changeOrder("end_at")}>提交时间</li>*/}
{/* <li onClick={()=>this.changeOrder("student_id")}>学生学号</li>*/}
{/* </ul>*/}
{/* </li>*/}
{/* </div>*/}
{/*}*/}
</div>}
<div className="edu-table edu-back-white minH-560 pollResultList">
{
data && data.length > 0 ? <Table columns={columns} dataSource={data} pagination={false}
onChange={this.table1handleChange}></Table> : <NoneData></NoneData>
}
</div>
{
poll_types && poll_types.total_users && poll_types.total_users > limit ?
<div className="edu-txt-center mt30 mb50">
<Pagination showQuickJumper current={page} onChange={this.changePage} pageSize={limit} total={poll_types.total_users}></Pagination>
</div>:""
}
</div>
)
}
}
export default PollDetailTabFirst;

View File

@ -1,681 +0,0 @@
import React,{ Component } from "react";
import {Form,Checkbox,DatePicker,Button,Input,Select,Tooltip} from "antd";
import { handleDateString,ConditionToolTip } from 'educoder';
import PollDetailTabForthRules from './PollDetailTabForthRules'
import HomeworkModal from "../coursesPublic/HomeworkModal";
import '../css/members.css'
import '../css/busyWork.css'
import './pollStyle.css'
import moment from 'moment'
import locale from 'antd/lib/date-picker/locale/zh_CN';
import axios from 'axios'
import Modals from '../../modals/Modals'
import { mapProps } from "recompose";
const Search=Input.Search;
const Option=Select.Option;
function range(start, end) {
const result = [];
for (let i = start; i < end; i++) {
result.push(i);
}
return result;
}
function disabledDateTime() {
return {
// disabledHours: () => range(0, 24).splice(4, 20),
disabledMinutes: () => range(1, 30).concat(range(31, 60)),
// disabledSeconds: () => [55, 56],
};
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
const dataformat="YYYY-MM-DD HH:mm";
class PollDetailTabForth extends Component{
constructor(props){
super(props);
this.state={
modalname:undefined,
modaltype:undefined,
visible:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
chooseId:undefined,
publishCourse:undefined,
flagPageEdit:undefined,
unitSetting:true,
flagPublic:false,
flagRealName:undefined,
course_group:undefined,
end_time:undefined,
publish_time:undefined,
unit_p_tip:undefined,
unit_e_tip:undefined,
rules:undefined,
p_flag:undefined,
e_flag:undefined,
polls:undefined,
un_change_unified:false,
un_change_end:false,
//公用提示弹框相关
modalsType:false,
modalsTopval:"",
loadtype:false,
modalSave:undefined,
firstSetting:true
}
}
//加载
componentDidMount=()=>{
this.getSettingInfo();
//window.addEventListener('click', this.handleClick);
if(this.props.pollDetail!=undefined){
this.editSetting();
}
if(this.props.isAdmin() === false){
this.cancelEdit()
}
try {
this.props.triggerRef(this);
}catch (e) {
}
}
componentDidUpdate = (prevProps) => {
if(prevProps.pollDetail!= this.props.pollDetail){
this.editSetting();
}
}
handleClick=(e)=>{
console.log(e);
}
// 已有设置数据的查询
getSettingInfo=(type)=>{
if(type!=1){
this.props.newgetPollInfo();
}
let pollId=this.props.match.params.pollId;
let url=`/polls/${pollId}/poll_setting.json`;
axios.get(url).then((result)=>{
if(result){
this.setState({
polls:result.data.poll,
unitSetting:result.data.poll.unified_setting,
flagPublic:result.data.poll.show_result,
flagRealName:result.data.poll.un_anonymous,
course_group:result.data.course_groups,
publish_time:result.data.poll.publish_time,
end_time:result.data.poll.end_time,
firstSetting:result.data.published_course_groups.length==0 && result.data.poll.publish_time == null && result.data.poll.end_time==null,
})
// 统一设置时如果已发布则不能修改统一设置和发布时间,已截止不能修改结束时间
if(result.data.poll.unified_setting == true && moment(result.data.poll.publish_time) <= moment()){
this.setState({
un_change_unified:true
})
}
if(result.data.poll.unified_setting == true && moment(result.data.poll.end_time) <= moment()){
this.setState({
un_change_end:true
})
}
let publish_count = 0;
let group=result.data.published_course_groups;
if(group.length==0){
let list= [{
course_group_id:[],
course_group_name:[],
publish_time:undefined,
end_time:undefined,
publish_flag:"",
end_flag:"",
class_flag:"",
course_search:"",
poll_status:0,
p_timeflag:false,
e_timeflag:false
}]
this.setState({
rules:list
})
}else{
let array=[];
for(var i=0;i<group.length;i++){
array.push({
course_group_id:group[i].course_group_id,
course_group_name:group[i].course_group_name,
publish_time:group[i].course_publish_time,
end_time:group[i].course_end_time,
publish_flag:"",
end_flag:"",
class_flag:"",
course_search:"",
poll_status:result.data.poll.polls_status,
p_timeflag:moment(group[i].course_publish_time) <= moment() ,
e_timeflag:moment(group[i].course_end_time) <= moment()
})
if(moment(group[i].course_publish_time) <= moment()){
publish_count++;
}
}
this.setState({
rules:array,
un_change_unified: publish_count > 0
})
}
}
}).catch((error)=>{
console.log(error);
})
}
//提交form表单
handleSubmit = (e) => {
e.preventDefault();
this.props.form.validateFieldsAndScroll((err, values) => {
if(!err){
// 第一次进行问卷设置或者勾选了统一设置
let{unitSetting}=this.state
if(unitSetting==true){
console.log("统一设置");
this.UnifiedSetting();
}else{
console.log("非统一设置");
this.NotUnifiedSetting();
}
}
})
}
UnifiedSetting=()=>{
let { unit_e_tip , unit_p_tip , publish_time , end_time ,course_group }=this.state
if( this.state.un_change_unified == false){
if ( !publish_time ){
this.setState({
unit_p_tip:"请选择发布时间"
})
return;
}else if( moment(publish_time,dataformat) < moment() ){
this.setState({
unit_p_tip:"发布时间不能小于当前时间"
})
return;
}else{
this.setState({
unit_p_tip:""
})
}
}
if(this.state.un_change_end == false){
if(!end_time){
this.setState({
unit_e_tip:"请输入截止时间"
})
return;
}else if(moment(end_time,dataformat) <= moment(publish_time,dataformat)){
this.setState({
unit_e_tip:"截止时间不能小于发布时间"
})
return;
}else if(moment(end_time,dataformat)<=moment()){
this.setState({
unit_e_tip:"截止时间不能小于当前时间"
})
return;
}else{
this.setState({
unit_e_tip:""
})
}
}
this.commitSetting((result)=>{
if(result.status==200){
this.props.showNotification(`${result.data.message}`);
this.getSettingInfo(1);
this.setState({
flagPageEdit:false
})
}
})
}
// 非统一设置提交
NotUnifiedSetting=()=>{
const result = this.refs.pollDetailTabForthRules.notUnifiedSettingCheck(this.state.rules);
this.setState({
rules: result.rules
})
if(result.validate==false){
return;
}
this.commitSetting((result)=>{
if(result.status==200){
this.props.showNotification(`${result.data.message}`);
this.getSettingInfo(1);
this.setState({
flagPageEdit:false
})
}
});
}
//暂不发布
homeworkhide=()=>{
this.setState({
modalname:undefined,
modaltype:undefined,
visible:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
StudentList_value:undefined,
addname:undefined,
addnametype:false,
addnametab:undefined,
publish_time:undefined
})
}
// 确定立即发布(只要保存设置就可以)
homeworkstartend=()=>{
let {chooseId}=this.state;
let pollId=this.props.match.params.pollId;
let coursesId=this.props.match.params.coursesId;
console.log(chooseId);
this.commitSetting((result)=>{
if(result.status==200){
let url=`/courses/${coursesId}/polls/publish.json`;
axios.post((url),{
check_ids:[pollId],
group_ids:chooseId
}).then((Response)=>{
if(Response.status == 200){
this.props.showNotification(`${Response.data.message}`);
this.homeworkhide();
this.setState({
flagPageEdit:false
})
this.getSettingInfo();
this.props.getPollInfo();
}
}).catch((error)=>{
console.log(error);
})
}
})
}
getcourse_groupslist=(id)=>{
this.setState({
chooseId:id
})
}
commitSetting=(callback)=>{
let pollId=this.props.match.params.pollId;
let url=`/polls/${pollId}/commit_setting.json`;
let params=[];
if(this.state.unitSetting){
params={
unified_setting:this.state.unitSetting,
publish_time:this.state.publish_time,
end_time:this.state.end_time,
show_result:this.state.flagPublic,
un_anonymous:this.state.flagRealName
}
}else{
params={
unified_setting:this.state.unitSetting,
show_result:this.state.flagPublic,
un_anonymous:this.state.flagRealName,
publish_time_groups:this.state.rules
}
}
axios.post((url),params).then((result)=>{
callback(result);
}).catch((error)=>{
console.log(error);
})
}
rulesCheckInfo=(rules)=>{
console.log(rules);
this.setState({
rules
})
}
cancelBox=()=>{
this.setState({
modalsType:false,
modalsTopval:"",
loadtype:false,
})
}
// 是否统一设置
changeUnit=(e)=>{
this.setState({
unitSetting:e.target.checked
})
}
//是否公开统计
ChangeFlagPublic=(e)=>{
this.setState({
flagPublic:e.target.checked
})
}
//是否实名问卷
ChangeFlagName=(e)=>{
this.setState({
flagRealName:e.target.checked
})
}
onChangeTimepublish=(date, dateString)=>{
if(date!=null && date!="" && date != undefined && moment(date,dataformat)>moment()){
this.setState({
unit_p_tip:""
})
}
let { end_time }=this.state;
if(!end_time){
end_time = moment(handleDateString(dateString)).add(1, 'months');
}
this.setState({
publish_time: handleDateString(dateString),
end_time:end_time
})
}
onChangeTimeEnd=(date, dateString)=>{
if( date && moment(date,dataformat)>moment(this.state.publish_time,dataformat) && moment(date,dataformat) > moment()){
this.setState({
unit_e_tip:""
})
}
this.setState({
end_time: handleDateString(dateString)
})
}
//编辑
editSetting = () => {
if(this.props.pollDetail.course_is_end==true){
this.setState({
modalsType:true,
modalsTopval:"课堂已结束不能再修改!",
loadtype:true,
modalSave:this.cancelBox
})
}else{
this.setState({
flagPageEdit:this.props.isAdmin()?true:false
})
}
}
//取消编辑
cancelEdit=()=>{
this.setState({
flagPageEdit:false
})
this.getSettingInfo(1);
}
render(){
let{
modalname,
modaltype,
visible,
Topval,
Topvalright,
Botvalleft,
Botval,
starttime,
endtime,
Cancelname,
Savesname,
Cancel,
Saves,
publishCourse,
un_change_unified,
un_change_end,
flagPageEdit,unitSetting,flagPublic,flagRealName,end_time,publish_time,course_group,rules,
unit_p_tip,
unit_e_tip,
modalsType,
modalsTopval,
loadtype,
modalSave,
firstSetting
}=this.state
let { pollDetail } = this.props;
const { getFieldDecorator } = this.props.form;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
// sm: { span: 8 },
sm: { span: 24 },
},
wrapperCol: {
xs: { span: 24 },
// sm: { span: 16 },
sm: { span: 24 },
},
};
let isAdmin = this.props.isAdmin();
let isStudent = this.props.isStudent();
return(
<div>
<HomeworkModal
modaltype={modaltype}
modalname={modalname}
visible={visible}
Topval={Topval}
Topvalright={Topvalright}
Botvalleft={Botvalleft}
Botval={Botval}
starttime={starttime}
endtime={endtime}
Cancelname={Cancelname}
Savesname={Savesname}
Cancel={Cancel}
Saves={Saves}
course_groups={publishCourse}
getcourse_groupslist={(id)=>this.getcourse_groupslist(id)}
/>
<Modals
modalsType={modalsType}
modalsTopval={modalsTopval}
loadtype={loadtype}
modalSave={modalSave}
></Modals>
<Form {...formItemLayout} onSubmit={this.handleSubmit}>
<div className="edu-back-white">
<div className="bor-bottom-greyE padding30">
<p className="mb30 clearfix">
<span className="font-16 fl">发布设置
{/* <span className="color-grey-c font-14">(课堂管理员、教师、助教拥有发布设置权限)</span> */}
</span>
{
!flagPageEdit && isAdmin ?
<a className="fr white-btn edu-blueline-btn lineh-24" onClick={this.editSetting}>
编辑设置
{/*<Tooltip title="编辑"><i className="iconfont icon-bianjidaibeijing font-20 color-green"></i></Tooltip>*/}
</a>
:""
}
</p>
<div className="pl25">
{
course_group && course_group.length > 0 &&
<p className="clearfix mb20">
<Form.Item className="fl pollForm">
{getFieldDecorator('unitSet')
(
<Checkbox disabled={un_change_unified == true ? true : !flagPageEdit}
className="mr15 font-16 color-grey-6" checked={ unitSetting }
onChange={this.changeUnit}>统一设置</Checkbox>
)}
</Form.Item>
<span className="color-grey-c font-14">选中则所有分班使用相同的发布设置仅课堂管理员可修改否则各个分班允许单独设置</span>
</p>
}
{
unitSetting ?
<div>
<div className="clearfix mb5">
<span className="font-16 mr15 fl mt6">发布时间</span>
<div className="fl">
<Tooltip placement="bottom" title={un_change_unified == true?this.props.isAdmin()? "发布时间已过,不能再修改":"":""}>
<span>
<DatePicker
showToday={false}
dropdownClassName="hideDisable"
showTime={{ format: 'HH:mm' }}
placeholder="请选择发布时间"
locale={locale}
className={unit_p_tip && unit_p_tip != "" ?"noticeTip winput-240-40":"winput-240-40" }
style={{"height":"42px"}}
format="YYYY-MM-DD HH:mm"
disabledTime={disabledDateTime}
onChange={this.onChangeTimepublish}
value={publish_time && moment(publish_time,dataformat)}
disabled={un_change_unified == true ? true : !flagPageEdit }
></DatePicker>
</span>
</Tooltip>
<p className="color-red lineh-25 clearfix" style={{height:"25px"}}>
{
unit_p_tip && unit_p_tip != "" ? <span className="fl">{ unit_p_tip }</span>:""
}
</p>
</div>
<span className="color-grey-c ml20 fl mt10 font-14">学生收到问卷的时间</span>
</div>
<div className="clearfix">
<span className="mr15 fl mt10 font-16">截止时间</span>
<div className="fl">
<Tooltip placement="bottom" title={un_change_end ? this.props.isAdmin()?"":"截止时间已过,不能再修改":""}>
<span>
<DatePicker
showToday={false}
dropdownClassName="hideDisable"
showTime={{ format: 'HH:mm' }}
locale={locale}
placeholder="请选择截止时间"
style={{"height":"42px"}}
className={unit_e_tip && unit_e_tip != "" ? "noticeTip winput-240-40 mr20":"winput-240-40 mr20" }
width={"240px"}
format="YYYY-MM-DD HH:mm"
disabledTime={disabledDateTime}
disabledDate={disabledDate}
onChange={this.onChangeTimeEnd}
value={ end_time && moment(end_time,dataformat) }
// disabled={un_change_end == true ?true : !flagPageEdit }
disabled={un_change_end == true ? this.props.isAdmin()?!flagPageEdit:true : !flagPageEdit }
>
</DatePicker>
</span>
</Tooltip>
<p className="color-red lineh-25 clearfix" style={{height:"25px"}}>
{
unit_e_tip && unit_e_tip != "" ? <span className="fl">{ unit_e_tip }</span>:""
}
</p>
</div>
<span className="color-grey-c ml20 fl mt10 font-14">学生可以答题的时间截点</span>
</div>
</div>
:
<PollDetailTabForthRules
{...this.props}
{...this.state}
ref="pollDetailTabForthRules"
rules={rules}
type={"polls"}
course_group={course_group}
flagPageEdit={flagPageEdit}
rulesCheckInfo={(info)=>this.rulesCheckInfo(info)}
></PollDetailTabForthRules>
}
</div>
</div>
<div className="padding30">
<p className="mb30 clearfix font-16">公开设置</p>
<div className="pl25">
<p className="mb20">
<Form.Item className="fl pollForm">
{getFieldDecorator('public')
(
<Checkbox disabled={!flagPageEdit} className="mr15 font-16 color-grey-6" checked={flagPublic} onChange={this.ChangeFlagPublic}>公开统计</Checkbox>
)}
</Form.Item>
<span className="color-grey-c font-14">选中则在问卷截止时间之后已提交问卷题的学生可以查看统计结果否则不能查看</span>
</p>
<p className="clearfix">
<Form.Item className="fl pollForm">
{getFieldDecorator('real')
(
<Checkbox disabled={!flagPageEdit} className="mr15 font-16 color-grey-6" checked={flagRealName} onChange={this.ChangeFlagName}>实名问卷</Checkbox>
)}
</Form.Item>
<span className="color-grey-c font-14">选中则学生答题后老师可以查看学生的问卷</span>
</p>
</div>
</div>
</div>
{
flagPageEdit&& this.props.isAdmin() === true ?
<div className="clearfix mt30 mb30">
<Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">提交</Button>
<a className="defalutCancelbtn fl" onClick={this.cancelEdit}>取消</ a>
</div>:""
}
</Form>
</div>
)
}
}
const WrappedPollSet = Form.create({ name: 'pollSetting' })(PollDetailTabForth);
export default WrappedPollSet;

View File

@ -1,534 +0,0 @@
import React,{ Component } from "react";
import {DatePicker,Select,Tooltip,Input} from "antd";
import { handleDateString } from 'educoder';
import '../css/members.css';
import '../css/busyWork.css';
import './pollStyle.css';
import moment from 'moment';
import locale from 'antd/lib/date-picker/locale/zh_CN';
const Search=Input.Search;
const Option=Select.Option;
const dataformat="YYYY-MM-DD HH:mm"
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(1,60)
}
}
function disabledDate(current) {
return current && current < moment().endOf('day').subtract(1, 'days');
}
class PollDetailTabForthRules extends Component{
constructor(props){
super(props);
let list= [{
course_group_id:[],
course_group_name:[],
publish_time:undefined,
end_time:undefined,
publish_flag:"",
end_flag:"",
class_flag:"",
course_search:"",
poll_status:0,
p_timeflag:false,
e_timeflag:false
}]
this.state={
rules: this.props.rules && this.props.rules.length == 0 ? list : this.props.rules,
course_group:this.props.course_group,
selectedCourse:[],
flagPageEdit:this.props.flagPageEdit
}
}
componentDidUpdate(prevProps) {
if (JSON.stringify(this.props.rules) != JSON.stringify(prevProps.rules) ) {
this.setState({rules:this.props.rules});
this.unitChoose(this.props.rules);
}
if(this.props.flagPageEdit != prevProps.flagPageEdit){
this.setState({flagPageEdit: this.props.flagPageEdit})
}
}
componentDidMount=()=>{
this.unitChoose(this.props.rules);
}
// 添加发布规则
AddRules=()=>{
let {rules}=this.state;
let newrules=rules;
let list= {
course_group_id:[],
course_group_name:[],
publish_time:undefined,
end_time:undefined,
publish_flag:"",
end_flag:"",
class_flag:"",
course_search:"",
poll_status:0,
e_timeflag:false,
p_timeflag:false
}
newrules.push(list)
this.setState({
rules:newrules
})
this.props.rulesCheckInfo && this.props.rulesCheckInfo(rules)
}
//删除发布规则
removeRules=(index)=>{
let { rules }=this.state;
var lists= rules;
let num=parseInt(index);
lists.splice(num,1);
this.setState({
rules:lists
})
this.unitChoose(lists);
this.props.rulesCheckInfo && this.props.rulesCheckInfo(lists)
}
//修改发布规则里面的结束时间
changeRuleEndTime=(e,date,index)=>{
let arr=Object.assign({}, this.state.rules[parseInt(index)]);
arr.end_time=handleDateString(date);
if(date!="" && date!=undefined && moment(date,dataformat)>moment() && moment(date,dataformat)>moment(arr.publish_time,dataformat)){
arr.end_flag=""
}
let rules=this.state.rules;
rules[index]=arr;
this.setState({
rules
})
this.props.rulesCheckInfo && this.props.rulesCheckInfo(rules)
}
//修改发布规则里面的发布时间
changeRulePublishTime=(e,date,index)=>{
let arr=Object.assign({}, this.state.rules[parseInt(index)]);
arr.publish_time=date=== ""?"":moment(handleDateString(date)).format("YYYY-MM-DD HH:mm");
if(!arr.end_time){
if(e!=null){
arr.end_time = moment(moment(handleDateString(date)).add(1, 'months')).format("YYYY-MM-DD HH:mm")
}
}
if(date!="" && date !=undefined && moment(date,dataformat)>moment()){
arr.publish_flag=""
}
let rules=this.state.rules;
rules[index]=arr;
this.setState({
rules
})
this.props.rulesCheckInfo && this.props.rulesCheckInfo(rules)
}
// changeOpen=(e,index)=>{
// let arr=Object.assign({}, this.state.rules[parseInt(index)]);
// arr.open= true;
// let rules=this.state.rules;
// rules[index]=arr;
// this.setState({
// rules
// })
// }
// changeClose=(e,index)=>{
// let arr=Object.assign({}, this.state.rules[parseInt(index)]);
// arr.open= false;
// let rules=this.state.rules;
// rules[index]=arr;
// this.setState({
// rules
// })
// }
// 选择分班
changeClasses=(value,option,index)=>{
let arr=Object.assign({}, this.state.rules[parseInt(index)]);
arr.course_group_id=value;
arr.class_flag="";
let rules=this.state.rules;
rules[index]=arr;
//修改选择分班下拉选项(是否被选中)
//let course_group = this.state.course_group;
this.unitChoose(rules);
this.setState({
rules:rules,
//course_group:course_group
})
this.props.rulesCheckInfo && this.props.rulesCheckInfo(rules)
}
//整合所有已经选择了的course_group_id
unitChoose=(rules)=>{
let arr = [];
if(rules){
rules.forEach(ele => {
let Arraytype=Array.isArray(ele.course_group_id);
if(Arraytype===true){
ele.course_group_id.forEach(e=>{
arr.push(e)
})
}else{
arr.push(ele.course_group_id)
}
});
}
let course_group =this.state.course_group;
course_group.forEach(ele=>{
if(arr.indexOf(ele.course_group_id) != -1){
ele.course_choosed = 1
}else{
ele.course_choosed = 0
}
})
this.setState({
course_group
})
}
fouceThis=(e)=>{
e.preventDefault();
}
// 输入搜索分班
inputSearchCourse=(e,index)=>{
this.inputSearch(e,index);
}
//搜索
ActionSearchCourse=(e,index)=>{
this.inputSearch(e,index);
}
inputSearch=(e,index)=>{
let arr=Object.assign({}, this.state.rules[parseInt(index)]);
arr.course_search=e.target.value;
let rules=this.state.rules;
rules[index]=arr;
this.setState({
rules
})
}
notUnifiedSettingCheck=(rules) => {
let flag,flag1,flag2 = true;
let myRules = []
if (rules.length == 0) {
myRules = this.state.rules.slice(0);
} else {
myRules = rules;
}
for(var i=0;i<myRules.length;i++){
let arr=Object.assign({}, myRules[parseInt(i)]);
if(arr.poll_status < 2){
if(arr.course_group_id===undefined || arr.course_group_id.length==0){
arr.class_flag="请选择分班"
flag1=false;
}else{
flag1=true;
}
if(arr.publish_time===undefined||arr.publish_time===null||arr.publish_time===""){
arr.publish_flag="请选择发布时间"
flag1=false;
}
else if(!arr.p_timeflag && moment(arr.publish_time,dataformat) <= moment()){
arr.publish_flag="发布时间不能早于当前时间"
flag1=false;
}
if(arr.end_time===undefined||arr.end_time===null||arr.end_time===""){
arr.end_flag="请选择截止时间"
flag1=false;
}
else if(!arr.e_timeflag && moment(arr.end_time,dataformat) <= moment()){
if(this.props.type==="Shixun"){
}else{
arr.end_flag="截止时间不能早于当前时间"
flag1=false;
}
}else if(!arr.e_timeflag && moment(arr.end_time,dataformat) <= moment(arr.publish_time,dataformat)){
arr.end_flag="截止时间不能早于发布时间"
flag1=false;
}else{
flag1=true;
}
myRules[i]=arr
}
}
return {
validate: flag1,
rules: myRules
};
}
exerciseSettingCheck=(rules) => {
let flag,flag1,flag2 = true;
let myRules = []
if (rules.length == 0) {
myRules = this.state.rules.slice(0);
} else {
myRules = rules;
}
for(var i=0;i<myRules.length;i++){
let arr=Object.assign({}, this.state.rules[parseInt(i)]);
if(arr.poll_status < 2){
if(arr.course_group_id===undefined || arr.course_group_id.length===0){
arr.class_flag="请选择分班"
flag=false;
}else{
flag=true;
}
if(arr.publish_time==undefined||arr.publish_time===null||arr.publish_time===""){
arr.publish_flag="请选择发布时间"
flag1=false;
}
else if(moment(arr.publish_time,dataformat) <= moment()){
arr.publish_flag="发布时间不能早于当前时间"
flag1=false;
}
if(arr.end_time===undefined||arr.end_time===null||arr.end_time===""){
arr.end_flag="请选择截止时间"
flag2=false;
}
else if(moment(arr.end_time,dataformat) <= moment()){
if(this.props.type==="Shixun"){
}else{
arr.end_flag="截止时间不能早于当前时间"
flag2=false;
}
}else if(moment(arr.end_time,dataformat) <= moment(arr.publish_time,dataformat)){
arr.end_flag="截止时间不能早于发布时间"
flag2=false;
}else{
flag2=true;
}
myRules[i]=arr
}
}
if(flag===false ||flag1===false ||flag2===false){
return {
validate: false,
rules: myRules
};
}else{
return {
validate: true,
rules: myRules
};
}
}
render(){
let {rules,course_group,flagPageEdit}=this.state
let isAdmin=this.props.isAdmin();
// console.log(flagPageEdit)
return(
<div className="bor-top-greyE pt20">
<p className="clearfix mb10">
<span className="fl with40 pr20">&nbsp;</span>
<span className="fl pr20 color-grey-c with25">(学生收到{this.props.moduleName || (this.props.type==="Exercise"?"试卷":"问卷")}的时间)</span>
<span className="fl color-grey-c">({this.props.moduleName == '作业' ? '学生“按时”提交作品的时间截点' : '学生可以答题的时间截点'})</span>
</p>
{/* item宽度超长 */}
<style>{`
.setInfo .ant-select-selection--multiple .ant-select-selection__choice__content {
max-width:280px;
}
`}</style>
{
rules && rules.length > 0 && rules.map((rule,r)=>{
const courseGroup = rule.course_search != "" ?
course_group.filter( item => item.course_group_name.indexOf(rule.course_search) != -1)
:course_group
return(
<div className="clearfix mb5" key={r}>
{
flagPageEdit===undefined?"":
flagPageEdit===true?
<style>
{
`
.yskspickersy
.ant-input, .ant-input .ant-input-suffix{
background-color: #fff !important;
}
`
}
</style>
:""
}
<div className="with40 fl pr20 df">
<span className="font-16 pr20 fl mt8">发布规则{r+1}</span>
<div className="flex1">
<style>
{
`.ant-select{
min-width:200px,
}
`
}
</style>
<Select
placeholder="请选择分班名称"
className={rule.class_flag && rule.class_flag!=""?"noticeTip setInfo":"setInfo" }
mode="multiple"
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
value={rule.course_group_id}
onChange={(value,option)=>this.changeClasses(value,option,r)}
disabled={this.props.isAdmin()===true?rule.p_timeflag===undefined?moment(rule.publish_time,dataformat) <= moment()?true:!flagPageEdit: rule.e_timeflag ===undefined?rule.publish_time===null?false:!flagPageEdit:rule.p_timeflag == true ? true : !flagPageEdit:true}
>
{
courseGroup && courseGroup.length > 0 && courseGroup.map((team,t)=>{
return(
<Option value={team.course_group_id} key={t} style={{display:`${team.course_choosed==0 ? "" : "none"}`}}>{team.course_group_name}</Option>
)
})
}
</Select>
<p className="color-orange-tip lineh-25 clearfix" style={{height:"25px"}}>
{
rule.class_flag && rule.class_flag!=""?<span className="fl color-red">{rule.class_flag}</span>:""
}
</p>
</div>
</div>
<div className="fl pr20 with25 yskspickersy">
<Tooltip placement="bottom" title={
rule.p_timeflag===undefined?moment(rule.publish_time,dataformat) <= moment()?isAdmin===true?"发布时间已过,不能再修改":"":"": rule.e_timeflag ===undefined?rule.publish_time===null?"":!flagPageEdit:rule.p_timeflag == true ? isAdmin===true?"发布时间已过,不能再修改":"" : ""
}>
<span>
<DatePicker
showToday={false}
dropdownClassName="hideDisable"
placeholder="请选择发布时间"
locale={locale}
className={rule.publish_flag && rule.publish_flag!=""?"noticeTip winput-240-40":"winput-240-40"}
value={rule.publish_time && moment(rule.publish_time,dataformat)}
onChange={(e, date)=>this.changeRulePublishTime(e, date,r)}
showTime={{ format: 'HH:mm' }}
format="YYYY-MM-DD HH:mm"
disabledTime={disabledDateTime}
disabledDate={disabledDate}
disabled={ this.props.isAdmin()===true?rule.p_timeflag===undefined?moment(rule.publish_time,dataformat) <= moment()?true:!flagPageEdit: rule.e_timeflag ===undefined?rule.publish_time===null?false:!flagPageEdit:rule.p_timeflag == true ? true : !flagPageEdit:true}
style={{"height":"42px",width:'100%'}}
></DatePicker>
</span>
</Tooltip>
<p className="color-orange-tip lineh-25 clearfix" style={{height:"25px"}}>
{
rule.publish_flag && rule.publish_flag!=""?<span className="fl color-red mt10">{rule.publish_flag}</span>:""
}
</p>
</div>
<div className="fl mr20 yskspickersy">
<Tooltip placement="bottom" title={rule.e_timeflag ? this.props.isAdmin()?"":"截止时间已过,不能再修改":""}>
<span>
<DatePicker
showToday={false}
dropdownClassName="hideDisable"
placeholder="请选择截止时间"
locale={locale}
className={rule.end_flag && rule.end_flag !="" ? "noticeTip winput-240-40":"winput-240-40" }
value={rule.end_time && moment(rule.end_time,dataformat)}
onChange={(e, date)=>this.changeRuleEndTime(e, date,r)}
showTime={{ format: 'HH:mm' }}
format="YYYY-MM-DD HH:mm"
disabledTime={disabledDateTime}
disabledDate={disabledDate}
disabled={
this.props.isAdmin()===true?this.props.type==="Shixun"?!flagPageEdit:
this.props.type==="Exercise"||this.props.type==="polls"?
rule.e_timeflag === undefined ? rule.publish_time === null ? false : moment(rule.end_time, dataformat) <= moment() ?this.props.isAdmin()?!flagPageEdit: true : !flagPageEdit : rule.e_timeflag == true ? this.props.isAdmin()?!flagPageEdit :true : !flagPageEdit:
rule.e_timeflag === undefined ? rule.publish_time === null ? false : moment(rule.end_time, dataformat) <= moment() ? true : !flagPageEdit : rule.e_timeflag == true ? true : !flagPageEdit:true
}
style={{"height":"42px"}}
></DatePicker>
</span>
</Tooltip>
<p className="color-orange-tip lineh-25 clearfix" style={{height:"25px"}}>
{
rule.end_flag && rule.end_flag!=""?<span className="fl color-red mt10">{rule.end_flag}</span>:""
}
</p>
</div>
{
flagPageEdit ?this.props.isAdmin()?
<li className="fl pt5">
{rule.p_timeflag===undefined?r > 0&&rule.publish_time===null?<Tooltip title="删除">
<a className="mr20" onClick={()=>this.removeRules(`${r}`)}><i className="iconfont icon-shanchu color-grey-9 font-18"></i></a>
</Tooltip>
:(
this.props.Commonheadofthetestpaper?
(this.props.Commonheadofthetestpaper.exercise_status===1&&r > 0?
<Tooltip title="删除">
<a className="mr20" onClick={()=>this.removeRules(`${r}`)}><i className="iconfont icon-shanchu color-grey-9 font-18"></i></a>
</Tooltip>
:"")
:this.props.teacherdatapage?
(
this.props.teacherdatapage.homework_status[0]==="未发布"&&r > 0?
<Tooltip title="删除">
<a className="mr20" onClick={()=>this.removeRules(`${r}`)}><i className="iconfont icon-shanchu color-grey-9 font-18"></i></a>
</Tooltip>
:""
):
""
):
r > 0 && rule.p_timeflag == false ?
<Tooltip title="删除">
<a className="mr20" onClick={()=>this.removeRules(`${r}`)}><i className="iconfont icon-shanchu color-grey-9 font-18"></i></a>
</Tooltip>
:""
}
<Tooltip title="新增"><a className="mt6" onClick={this.AddRules}><i className="iconfont icon-tianjiafangda color-green font-18"></i></a> </Tooltip>
</li>
:"":""
}
</div>
)
})
}
</div>
)
}
}
export default PollDetailTabForthRules;

View File

@ -1,197 +0,0 @@
import React,{ Component } from "react";
import { Pagination , Spin } from "antd";
import NoneData from "../coursesPublic/NoneData"
import '../css/members.css'
import '../css/busyWork.css'
import './pollStyle.css'
import update from 'immutability-helper'
import axios from 'axios'
const map={1:"单选题",2:"多选题",3:"主观题",4:"主观题"}
class PollDetailTabSecond extends Component{
constructor(props){
super(props);
this.state={
page:1,
limit:10,
questions:undefined,
questionsInfo:undefined,
isSpin:false
}
}
getInfo=(page)=>{
this.setState({
isSpin:true
})
let pollId=this.props.match.params.pollId;
let url=`/polls/${pollId}/commit_result.json?page=${page}`;
axios.get(url).then((result)=>{
if(result){
this.setState({
page: page,
questions:result.data.questions,
questionsInfo:result.data.question_types,
isSpin:false
})
}
}).catch((error)=>{
console.log(error);
})
}
componentDidMount=()=>{
let{page}=this.state;
this.getInfo(page);
}
//翻页
changePage=(pageNumber)=>{
this.getInfo(pageNumber);
}
changeTxtStatus=(index,flag)=>{
console.log(index+" "+flag)
this.setState(
(prevState) => ({
questions:update(prevState.questions, {[index]:{question:{ txt_status: {$set: !flag} }}})
})
)
console.log(this.state.questions[index].question)
}
render(){
let {page, limit, questions, questionsInfo , isSpin} = this.state;
return(
<Spin size="large" spinning={ isSpin }>
<React.Fragment>
{
questions && questions.length>0 && questions.map((item,key)=>{
return(
<div className="edu-back-white mb10">
<div className="pt20 pl30 pr30 pb10">
<span className="font-16 clearfix">
<span className="color-blue fl">{parseInt(page-1)*parseInt(limit)+(key+1)}{map[item.question.question_type]}</span>
{ item.question.is_necessary==1 ? <span className="mustAnswer fl ml10 mr10 mt6">必答</span>:"" }
{ item.question.question_type == 2 && item.question.min_choices && item.question.max_choices ?
<span className="color-grey-9">
{
item.question.min_choices == item.question.max_choices ? "可选"+item.question.max_choices+"项" :
"可选"+item.question.min_choices+"-"+item.question.max_choices+"项"
}
</span>:""
}
</span>
<p className="mt10 font-16">
<span className=" flex1" style={{
"white-space": "pre-wrap",
"word-break": "break-all",
"word-wrap": "break-word"
}}>
{item.question.question_title}
</span>
</p>
</div>
<div className="countList">
<p className="countHeader">
{
item.question.question_type==3?
<ul className="clearfix df">
<span style={{width:"6%"}}>编号</span>
<span style={{width:"50%",textAlign:"left"}}>文本答案</span>
</ul>
:
<ul className="clearfix">
<span>选项</span>
<span>小计</span>
<span>百分比</span>
</ul>
}
</p>
{/* 主观题 */}
{
item.question.question_type == 3 && item.question.vote_text &&
<React.Fragment>
{
item.question.vote_text.map((txt,t)=>{
return(
<div className="countBody">
<ul className="clearfix df">
<span style={{width:"6%"}} className="pl8">{t+1}</span>
<span className="color-grey-3 break-word edu-txt-left flex1">
<li>{txt}</li>
</span>
</ul>
</div>
)
})
}
</React.Fragment>
}
{/* 单选和多选 */}
{
item.question.question_type != 3 && item.question.answers && item.question.answers.map((options,k)=>{
return(
<div className="countBody">
<ul className="clearfix">
<span className="color-grey-3 break-word">
{ options.answer_text=="其他" ? "其他" : options.answer_text }
{
options.answer_text=="其他" && item.question.vote_text && item.question.vote_text.length > 0 ?
<a className="ml40 color-orange-tip" onClick={()=>this.changeTxtStatus(key,item.question.txt_status)}>{!item.question.txt_status ?"隐藏":"显示"}文本回答</a>
:""
}
</span>
<span className="color-green">{options.answer_users_count}</span>
<span>
<p className="percentForm fl mr15">
<span className="percentValue" style={{"width":`${(options.answer_percent * 100).toFixed(1)}%`}}></span>
</p>
<font className="color-grey-9">{(options.answer_percent * 100).toFixed(1)}%</font>
</span>
</ul>
{
options.answer_text=="其他" && (!item.question.txt_status || !item.question.txt_status ==true) && item.question.vote_text && item.question.vote_text.length>0 &&
<div className="answerTxt">
{
item.question.vote_text.map((i,j)=>{
return(
<p className="font-16 mb5">{j+1}.{i}</p>
)
})
}
</div>
}
</div>
)
})
}
<div className="countBody">
<ul className="clearfix">
<span className="color-grey-6">有效填写量</span>
<span className="color-grey-3">{item.question.commit_users_count}</span>
</ul>
</div>
</div>
</div>
)
})
}
{
questions && questions.length == 0 && <div className="edu-back-white"><NoneData></NoneData></div>
}
{
questionsInfo && questionsInfo.q_counts > limit &&
<div className="edu-txt-center mt20 mb50">
<Pagination showQuickJumper current={page} total={questionsInfo.q_counts} pageSize={limit}
onChange={this.changePage}></Pagination>
</div>
}
</React.Fragment>
</Spin>
)
}
}
export default PollDetailTabSecond;

View File

@ -1,58 +0,0 @@
import React,{ Component } from "react";
import { Spin } from 'antd';
import '../css/members.css'
import '../css/busyWork.css'
import './pollStyle.css'
import PollDetailTabThirdInfo from './PollDetailTabThirdInfo'
import axios from 'axios';
class PollDetailTabThird extends Component{
constructor(props){
super(props);
this.state={
pollDetail:undefined,
isSpin:false
}
}
getPollInfo=()=>{
this.setState({
isSpin:true
})
let pollId=this.props.match.params.pollId;
let url=`/polls/${pollId}.json`;
axios.get(url).then((result)=>{
if(result.status==200){
if (result.data.status === 401) {
//未登入
this.setState({
pollDetail: undefined,
isSpin:false
})
return
}
this.setState({
pollDetail:result.data,
isSpin:false
})
}
}).catch((error)=>{
console.log(error);
})
}
componentDidMount=()=>{
this.getPollInfo();
}
render(){
let {pollDetail , isSpin}=this.state;
return(
<div>
<Spin size="large" spinning={isSpin}>
<PollDetailTabThirdInfo {...this.props} {...this.state} pollDetail = {pollDetail}></PollDetailTabThirdInfo>
</Spin>
</div>
)
}
}
export default PollDetailTabThird

View File

@ -1,138 +0,0 @@
import React,{ Component } from "react";
import {Checkbox,Radio} from "antd";
import NoneData from "../coursesPublic/NoneData"
import '../css/members.css'
import '../css/busyWork.css'
import './pollStyle.css'
const map={1:"单选题",2:"多选题",3:"主观题",4:"主观题"}
class PollDetailTabThirdInfo extends Component{
constructor(props){
super(props);
}
render(){
let { pollDetail }=this.props;
console.log("pollDetailpollDetail");
console.log(pollDetail);
return(
<div>
{
pollDetail !== undefined ?
<div className="edu-back-white">
{
pollDetail !== pollDetail.poll.polls_description &&
<p style={{whiteSpace:"pre-wrap"}} className="color-grey-3 padding20-30">{ pollDetail.poll.polls_description }</p>
}
{
pollDetail && pollDetail.questions && pollDetail.questions.length > 0 &&
<p className="padding20-30 clearfix edu-txt-left" style={{background:"#fafafa"}}>
{ !pollDetail || !pollDetail.question_types || pollDetail.question_types.q_counts===0 ? "" :
<span className="color-grey-3">
{
pollDetail && pollDetail.question_types && pollDetail.question_types.q_counts > 0 &&
<span>合计{pollDetail.question_types && pollDetail.question_types.q_counts}</span>
}
{
pollDetail && pollDetail.question_types.q_singles > 0 &&
<span className="mr15 color-grey-9">单选题{pollDetail.question_types.q_singles}</span>
}
{
pollDetail && pollDetail.question_types.q_doubles > 0 &&
<span className="mr15 color-grey-9">多选题{pollDetail.question_types.q_doubles}</span>
}
{
pollDetail && pollDetail.question_types.q_mains > 0 &&
<span className="color-grey-9">主观题{pollDetail.question_types.q_mains}</span>
}
</span>
}
</p>
}
{
pollDetail && pollDetail.questions && pollDetail.questions.length > 0 && pollDetail.questions.map((item,key)=>{
return(
<div className="previewList">
<p className="pl30 pr30 pt30 pb15 font-16 clearfix">
<span className="color-blue mr8 fl">{item.question.question_number}{map[item.question.question_type]}</span>
{ item.question.is_necessary==1 ? <span className="mustAnswer fl ml10 mr10">必答</span>:<span className="mustAnswer fl ml10 mr10"></span> }
{ item.question.question_type == 2 && item.question.min_choices != undefined && item.question.min_choices != null && item.question.max_choices != undefined && item.question.max_choices != null ?
<span className="color-grey-9 font-14 fl mt2">
{
item.question.min_choices == item.question.max_choices ? "可选"+item.question.max_choices+"项" :
"可选"+item.question.min_choices+"-"+item.question.max_choices+"项"
}
</span>:""
}
</p>
<p className="pl30 pr30 pb15"><span className="font-14 flex1" style={{
"white-space": "pre-wrap",
"word-break": "break-all",
"word-wrap": "break-word"
}}>{item.question.question_title}</span></p>
{
// 单选题
item.question.question_type==1 &&
<Radio.Group className="answerList" disabled>
{
item.question.answers.map((index,k)=>{
return(
<li className="df">
<Radio className="fl" value={index.answer_id}></Radio>
<span className={index.answer_text=="其他"?"break-word":"break-word flex1"}>{index.answer_text}</span>
{
index.answer_text=="其他" ? <p className="textLine"></p>:""
}
</li>
)
})
}
</Radio.Group>
}
{
// 多选题
item.question.question_type==2 &&
<Checkbox.Group className="answerList" disabled>
{
item.question.answers.map((index,k)=>{
return(
<li className="df" key={k}>
<Checkbox className="fl mr8" value={index.answer_id} key={index.answer_id}></Checkbox>
<span className={index.answer_text=="其他"?"break-word":"break-word flex1"}>{index.answer_text}</span>
{
index.answer_text=="其他" ? <p className="textLine"></p>:""
}
</li>
)
})
}
</Checkbox.Group>
}
{
// 主观题
item.question.question_type == 3 &&
<div className="pl30 pr30 pb20">
<textarea placeholder="在此填入答案" readOnly className="winput-100-130"></textarea>
</div>
}
</div>
)
})
}
{
pollDetail && pollDetail.questions && pollDetail.questions.length == 0 && <NoneData></NoneData>
}
</div>
: ""
}
</div>
)
}
}
export default PollDetailTabThirdInfo

View File

@ -1,519 +0,0 @@
import React,{ Component } from "react";
import {Checkbox,Radio, Input} from "antd";
import '../css/members.css'
import '../css/busyWork.css'
import './pollStyle.css'
import moment from 'moment'
import { WordsBtn } from 'educoder'
import Modals from '../../modals/Modals'
import CoursesListType from '../coursesPublic/CoursesListType';
import axios from 'axios';
const map={1:"单选题",2:"多选题",3:"主观题"}
const statudmap={1:"未发布",2:"提交中",3:"已截止"}
class PollInfo extends Component{
constructor(props){
super(props);
this.state={
courseName:undefined,
poll:undefined,
question_answered:undefined,
question_types:undefined,
questions:undefined,
inputArray:[],
modalsType:false,
modalsTopval:undefined,
modalsBottomval:undefined,
loadtype:true,
modalSave:undefined,
questionPanelFixed:false,
pollAnswerList:[]
}
}
componentDidUpdate (prevProps) {
// 需要等get_user_info执行完才能getInfo
if (!prevProps.current_user && this.props.current_user) {
this.getInfo()
}
}
componentDidMount(){
if(this.props.current_user){
this.getInfo();
}
//window.addEventListener('scroll', this.handleScroll);
}
// 滚动定位
handleScroll=()=>{
if(parseInt(window.scrollY)>230){
this.setState({
questionPanelFixed:true
})
}else{
this.setState({
questionPanelFixed:false
})
}
}
scrollToAnchor=(index)=>{
let name="Anchor_"+index;
if (index) {
let anchorElement = document.getElementById(name);
if(anchorElement) { anchorElement.scrollIntoView(); }
}
}
getInfo=()=>{
this.setState({
courseName:this.props.current_user.course_name
})
let pollId=this.props.match.params.pollId;
let user_id=this.props.match.params.login;
let url=`/polls/${pollId}/start_answer.json?login=${user_id}`
axios.get(url).then((result)=>{
if(result.status==200){
this.setState({
poll:result.data.poll,
question_answered:result.data.question_answered,
question_types:result.data.question_types,
questions:result.data.questions
})
let list=[];
for(var i=0;i<result.data.questions.length;i++){
list.push({
id:result.data.questions[i].question.id,
text:result.data.questions[i].question.poll_vote_texts || "",
is_necessary:result.data.questions[i].question.is_necessary,
answers:result.data.questions[i].question.poll_answer_ids,
answersList:result.data.questions[i].question.answers
})
}
this.setState({
inputArray:list
})
}
}).catch((error)=>{
console.log(error);
})
}
//选中选择题(单选题)选项保存
ChangeOptionSingle=(item)=>{
let arr=item.target.name
let txt=Object.assign({}, this.state.inputArray[parseInt(arr[1])]);
let ids=item.target.value;
let list=txt.answersList.filter(element => element.answer_id == ids);
this.postAnswer(arr[0],ids,list[0].answer_text=="其他"?txt.text:"",arr[1]);
}
//选中选择题(多选题)选项保存
ChangeOptionMuntil=(a_id,q_id,key)=>{
let ind=Object.assign({}, this.state.inputArray[parseInt(key)]);
let count=0;
a_id.forEach(element => {
let list=ind.answersList.filter(item=>item.answer_id==element);
if(list[0].answer_text=="其他"){
count++;
}
});
this.postAnswer(q_id,a_id,count > 0 ? ind.text : "",key);
}
postAnswer=(q_id,a_id,text,key)=>{
let url=`/poll_questions/${q_id}/poll_votes.json`;
console.log(text);
axios.post(url,{
poll_answer_id:a_id,
vote_text:text
}).then((result)=>{
if(result){
const answer=Object.assign({}, this.state.question_answered[parseInt(key)]);
answer.ques_status=result.data.poll_vote.question_status;
const question_answered=this.state.question_answered;
question_answered[parseInt(key)]=answer
const inputs=Object.assign({}, this.state.inputArray[parseInt(key)]);
inputs.answers=a_id;
const inputArray=this.state.inputArray;
inputArray[parseInt(key)]=inputs;
this.setState({
question_answered,
inputArray
})
}
}).catch((error)=>{
console.log(error);
})
}
//输入其它--内容
blurTxt=(e)=>{
let index=parseInt(e.target.name)
const list = Object.assign({}, this.state.inputArray[index])
list.text=e.target.value;
const inputArray=this.state.inputArray;
inputArray[index]=list
this.setState({
inputArray
})
}
//输入其它--内容后重新保存
saveInputAndAnswer=(e,a_id,q_id,key,type)=>{
const inputs=Object.assign({}, this.state.inputArray[parseInt(key)]);
let answers=inputs.answers;
let flag=true;
if(answers.length){
flag=answers.indexOf(a_id) > -1?true:false;
answers= type == 1 ? answers[0] : answers;
}else{
flag = answers==a_id?true:false;
}
if(answers && (answers.length>0 || answers !="")){
this.postAnswer(q_id,answers,flag ? inputs.text : "",key);
}
}
//提交主观题
commitText=(key,q_id)=>{
const text = Object.assign({}, this.state.inputArray[key]).text;
let url='/poll_questions/'+q_id+'/poll_votes.json?';
const ans=Object.assign({}, this.state.question_answered[key]);
ans.ques_status=text ? 1 : 0 ;
const questionAnswered=this.state.question_answered;
questionAnswered[key]=ans
this.setState({
question_answered:questionAnswered
})
if(text!=undefined){
axios.post((url),{
vote_text:text
}).then((result)=>{
if(result.status==200){
const answer=Object.assign({}, this.state.question_answered[key]);
answer.ques_status=result.data.poll_vote.question_status;
const question_answered=this.state.question_answered;
question_answered[key]=answer
this.setState({
question_answered
})
}
}).catch((error)=>{
console.log(error);
})
}
}
// 提交
submitPoll=()=>{
let {inputArray,question_answered}=this.state;
let must=0;
let may=0;
for(var j=0;j<question_answered.length;j++){
if(question_answered[j].ques_status==0){
if(inputArray[j].is_necessary==1){
must++;
}else{
may++;
}
}
}
if(must>0){
this.setState({
modalsType:true,
modalsTopval:"有 "+must+" 题必答题未答,无法提交 ",
modalsBottomval:"请完成全部必答题后再提交",
loadtype:true,
modalSave:this.cancelSubmit
})
return;
}
if(may >= 0){
this.setState({
modalsType:true,
modalsTopval: may>0 ? "有 "+may+" 题未答":"",
modalsBottomval:"提交后无法再修改答题,是否确认提交?",
loadtype:false,
modalSave:this.sureSubmit
})
}
}
cancelSubmit=()=>{
this.setState({
modalsType:false,
modalsTopval:"",
modalsBottomval:""
})
}
sureSubmit=()=>{
let pollId=this.props.match.params.pollId;
let url=`/polls/${pollId}/commit_poll.json`
axios.post(url).then((result)=>{
if(result.status == 200){
this.props.showNotification(result.data.message)
this.setState({
modalsType:false,
modalsTopval:"",
modalsBottomval:""
})
window.location.href=`/classrooms/${this.props.match.params.coursesId}/polls/${pollId}/detail`
}
}).catch((error)=>{
console.log(error);
})
}
render(){
let coursesId=this.props.match.params.coursesId;
let{poll,question_answered,question_types,questions,courseName,
inputArray,
modalsType,
modalsTopval,
loadtype,
modalsBottomval,
modalSave,
questionPanelFixed
}=this.state;
const { current_user } = this.props
let isAdmin=this.props.isAdmin();
let isStudent=this.props.isStudent();
document.title=courseName&&courseName;
return(
<div className="newMain" style={{paddingTop:"0px"}}>
{/*<p style={{height:"60px"}}></p>*/}
<Modals
modalsType={modalsType}
modalsTopval={modalsTopval}
modalsBottomval={modalsBottomval}
loadtype={loadtype}
modalCancel={this.cancelSubmit}
modalSave={modalSave}
></Modals>
<div className="educontent mt10 mb50">
<p className="clearfix mb20">
<WordsBtn style="grey" className="fl" to={current_user && current_user.first_category_url}>{courseName}</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<WordsBtn style="grey" className="fl" to={`/classrooms/${this.props.match.params.coursesId}/polls/${poll && poll.left_banner_id}`}>问卷</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<WordsBtn style="grey" to={`/classrooms/${coursesId}/polls/${this.props.match.params.pollId}/detail`} className="fl mr3">问卷详情</WordsBtn>&gt;
<span className="ml3">{question_types&&question_types.user_name}</span>
</p>
<p className="clearfix mb20">
<span className="color-grey-3 font-24 fl task-hide break-word" style={{maxWidth:"900px",lineHeight:"30px"}}>{poll && poll.polls_name}</span>
<CoursesListType typelist={[`${statudmap[poll && poll.poll_status]}`]} typesylename={""} />
{
isAdmin || (poll && poll.user_poll_status == 1) ? <WordsBtn className="fr font-16 mt5" style="grey" to={`/classrooms/${coursesId}/polls/${this.props.match.params.pollId}/detail`}>返回</WordsBtn> :''
}
</p>
{
poll && poll.polls_description &&
<p style={{backgroundColor:"#F2F9FF",whiteSpace:"pre-wrap"}} className="color-blue pl30 pr30 pt15 pb15">{poll.polls_description}</p>
}
<div className="edu-back-white">
<p className="padding20-30 bor-bottom-greyE">
{
question_types && question_types.q_counts > 0 &&
<span className="color-grey-3">合计{question_types.q_counts}</span>
}
{
question_types && question_types.q_singles > 0 &&
<span className="color-grey-9 mr15">单选题{question_types.q_singles}</span>
}
{
question_types && question_types.q_doubles > 0 &&
<span className="color-grey-9 mr15">多选题{ question_types && question_types.q_doubles }</span>
}
{
question_types && question_types.q_mains > 0 &&
<span className="color-grey-9">主观题{question_types &&question_types.q_mains}</span>
}
</p>
<div className={ questionPanelFixed==true ? "questionsfixed":"questionsNo"}>
<p className="clearfix pl20">
<span className="mr40 answered">已答</span>
<span className="unanswer">未答</span>
<span className="color-grey-9 fr">截止时间 {poll && moment(poll.end_time).format("YYYY-MM-DD HH:mm")}</span>
</p>
<ul className="clearfix leaderNav">
{
question_answered && question_answered.map((item,key)=>{
return(
<React.Fragment>
{
<a className={item.ques_status==1? "acted" : ""} onClick={()=>this.scrollToAnchor(`${key}`)}>{item.ques_number}</a>
}
</React.Fragment>
)
})
}
</ul>
</div>
<div>
{
questions && questions.map((item,key)=>{
return(
<div className="previewList" id={'Anchor_'+`${key}`}>
<div className="pl30 pr30 mt30 mb10 clearfix">
<span className="color-blue fl font-16">{item.question.question_number}{map[item.question.question_type]}</span>
{ item.question.is_necessary==1 ? <span className="mustAnswer fl ml10 mr10 mt5">必答</span>:<span className="mustAnswer fl ml10 mr10 mt5"></span> }
{ item.question.question_type == 2 && item.question.min_choices && item.question.max_choices ?
<span className="color-grey-9 font-14 fl mt2">
{
item.question.min_choices == item.question.max_choices ? "可选"+item.question.max_choices+"项" :
"可选"+item.question.min_choices+"-"+item.question.max_choices+"项"
}
</span>:""
}
</div>
<p className="pl30 pr30 mb10 "><span className="font-14 flex1" style={{
"white-space": "pre-wrap",
"word-break": "break-all",
"word-wrap": "break-word"
}}>{item.question.question_title}</span></p>
{
//单选
item.question.question_type==1 &&
<Radio.Group disabled={isAdmin || (isStudent && poll && poll.user_poll_status == 1)?true:false} className="answerList" defaultValue={item.question.poll_answer_ids[0]} name={[item.question.id,key]} onChange={this.ChangeOptionSingle}>
{
item.question.answers && item.question.answers.map((i,k)=>{
return(
<li className={i.answer_text=="其他"?"df clearfix":"clearfix"}>
<Radio name={[item.question.id,key]} className="fl" value={i.answer_id} ></Radio>
<span className="break-word fl" style={{maxWidth:"1116px"}}>{i.answer_text}</span>
{
i.answer_text=="其他" ?
<React.Fragment>
{
inputArray && inputArray.map((j,k)=>{
return(
<React.Fragment>
{
j.id == item.question.id ?
<Input type="text" className="otherTxt" autoComplete="off" value={j.text && j.text} name={key}
onInput={this.blurTxt}
onBlur={(e)=>this.saveInputAndAnswer(e,i.answer_id,item.question.id,key,item.question.question_type)}
/>
: ""
}
</React.Fragment>
)
})
}
</React.Fragment>
: ""
}
</li>
)
})
}
</Radio.Group>
}
{
//多选
item.question.question_type==2 &&
<Checkbox.Group
onChange={(value)=>this.ChangeOptionMuntil(value,item.question.id,key)}
disabled={isAdmin || (isStudent && poll && poll.user_poll_status == 1)?true:false}
defaultValue={item.question.poll_answer_ids}
className="answerList"
name={key}>
{
item.question.answers && item.question.answers.map((i,k)=>{
return(
<li className={i.answer_text=="其他"?"df clearfix":"clearfix"}>
<Checkbox className="fl mr8" value={i.answer_id} key={i.answer_id}></Checkbox>
<span className="break-word fl" style={{maxWidth:"1116px"}}>{i.answer_text}</span>
{
i.answer_text=="其他"?
<React.Fragment>
{
inputArray && inputArray.map((j,k)=>{
return(
<React.Fragment>
{
j.id == item.question.id ?
<Input type="text" className="otherTxt" autoComplete="off" value={j.text && j.text} name={key}
onInput={this.blurTxt}
onBlur={(e)=>this.saveInputAndAnswer(e,i.answer_id,item.question.id,key,item.question.question_type)}
/>
: ""
}
</React.Fragment>
)
})
}
</React.Fragment>
:""
}
</li>
)
})
}
</Checkbox.Group>
}
{
//主观题
item.question.question_type==3 &&
<div className="mt10 pl30 pr30 pb20">
{
inputArray && inputArray.map((j,k)=>{
return(
<React.Fragment>
{
j.id == item.question.id ?
<textarea placeholder="在此填入答案" disabled={isAdmin || (isStudent && poll && poll.user_poll_status == 1) ? true:false} value={j.text && j.text} className="winput-100-130" name={key} onInput={this.blurTxt} onBlur={()=>this.commitText(key,item.question.id)}></textarea>
: ""
}
</React.Fragment>
)
})
}
</div>
}
</div>
)
})
}
</div>
</div>
{
isStudent && poll && poll.user_poll_status == 0 ?
<div className="mt30 mb50">
<a type="primary" className="defalutSubmitbtn" onClick={this.submitPoll}>提交</a>
</div>
:""
}
</div>
</div>
)
}
}
export default PollInfo;

View File

@ -1,133 +0,0 @@
import React,{ Component } from "react";
import {Tooltip} from 'antd';
import {Link} from 'react-router-dom';
import moment from 'moment';
import CoursesListType from '../coursesPublic/CoursesListType';
import { WordsBtn,formatDuring } from 'educoder';
import '../css/members.css';
import '../css/busyWork.css';
const polls_status={1:"未发布",2:"提交中",3:"已截止",4:"已结束"}
const dataformat="YYYY-MM-DD HH:mm";
class PollListItem extends Component{
constructor(props){
super(props);
}
toDetailPage=(url)=>{
if(this.props.checkIfLogin()===false){
this.props.showLoginDialog()
return
}
// if(this.props.checkIfProfileCompleted()===false){
// this.setState({
// AccountProfiletype:true
// })
// return
// }
// if(this.props.checkIfProfessionalCertification()===false){
// this.props.showProfileCompleteDialog()
// return
// }
this.props.history.push(url);
}
render(){
let{item,checkBox,courseType,index}=this.props;
let {coursesId}=this.props.match.params;
const IsAdmin =this.props.isAdmin();
const isStudent = this.props.isStudent();
const isNotMember = this.props.isNotMember();
const isAdminOrStudent = this.props.isAdminOrStudent();
let t= item.end_time ? moment(item.end_time) - moment() : 0;
let canNotLink = !isAdminOrStudent && item.lock_status == 0
return(
<div className="workList_Item polllisthover" style={{cursor : IsAdmin ? "pointer" : "default",padding:"30px" }} onClick={() => window.$(`.pollitem${index} input`).click() }>
{
IsAdmin &&
<span className={`pollitem${index} fl mr12`}>
{checkBox}
</span>
}
<div className="flex1 pr">
<p className="clearfix mb30">
{ canNotLink ?
<span className="fl font-16 font-bd mt2 color-grey-3 task-hide pointer" style={{"maxWidth":"600px"}} title={courseType.user_permission == 0?"私有属性,非课堂成员不能访问":item.polls_name}>{item.polls_name}</span>
:
<a onClick={()=>this.toDetailPage(`/classrooms/${coursesId}/polls/${item.id}/detail`)} className="fl font-16 font-bd mt2 color-grey-3 task-hide pointer" style={{"maxWidth":"600px"}} title={item.polls_name}>{item.polls_name}</a>
}
{
item.lock_status === 0 ?
<Tooltip title={"私有属性,非课堂成员不能访问"} placement="bottom">
<i className="iconfont icon-guansuo color-grey-c ml10 font-16 fl"></i>
</Tooltip>
:""
}
<CoursesListType typelist={[polls_status[`${item.polls_status}`]]} typesylename={""}></CoursesListType>
{
isStudent && ((item.polls_status == 1 && (item.current_status ==0 ||item.current_status ==2)) || (item.polls_status==3 && item.current_status==2)) ?
<span className="edu-filter-btn edu-filter-btn-84B6EB ml15 fl typestyle">未提交</span>:""
}
</p>
<p className="color-grey-9 clearfix">
{ item.author && <span className="mr20 fl mt3">{item.author}</span> }
{
item.polls_status !=1 &&
<span className="fl mt3">
<span className="mr20">{item.poll_answer} 已答</span>
<span className="mr20">{item.poll_unanswer} 未答</span>
</span>
}
{
item.polls_status ==1 && item.publish_time ==null && item.created_at &&
<span className="mr20 fl mt3">创建于{moment(item.created_at).fromNow()}</span>
}
{
item.polls_status ==1 && item.publish_time !=null &&
<span className="mr20 fl mt3">将发布于{moment(item.publish_time).format(dataformat)}</span>
}
{
item.polls_status ==2 && item.publish_time !=null &&
<Tooltip title="提交剩余时间">
<span className="mr20 fl mt3">{"提交剩余时间:"+formatDuring(t)}</span>
</Tooltip>
}
{
isStudent ? <WordsBtn style="blue" targets={item.current_status == 2||item.current_status == 0?undefined:'_blank'} className="fr font-16 ml20" to={`/classrooms/${coursesId}/polls/${item.id}/users/${this.props.current_user.login}`}>
{
item.current_status == 0 && "继续答题"
}
{
item.current_status == 1 && "查看答题"
}
{
item.current_status == 2 && "开始答题"
}
</WordsBtn>:""
}
{ isStudent ?canNotLink ?"": <WordsBtn style="blue" className="font-16 fr " onClick={()=>this.toDetailPage(`/classrooms/${coursesId}/polls/${item.id}/detail`)} >查看详情</WordsBtn>:""}
{
IsAdmin &&
<ul className="fr">
{ canNotLink ?"": <WordsBtn style="blue" className="font-16" onClick={()=>this.toDetailPage(`/classrooms/${coursesId}/polls/${item.id}/detail`)} >查看详情</WordsBtn>}
<WordsBtn style="blue" className="font-16 ml20" to={`/classrooms/${coursesId}/polls/${item.id}/${"edit"}`}>编辑</WordsBtn>
<WordsBtn style="blue" className="ml20 font-16" to={`/classrooms/${coursesId}/polls/${item.id}/detail?tab=3`}>设置</WordsBtn>
</ul>
}
</p>
</div>
</div>
)
}
}
export default PollListItem

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,205 +0,0 @@
import React,{ Component } from "react";
import Modals from '../../../modals/Modals'
import { WordsBtn } from 'educoder'
import HomeworkModal from "../../coursesPublic/HomeworkModal";
import axios from 'axios'
import moment from 'moment';
class CancelPublish extends Component{
constructor(props){
super(props)
this.state={
modalname:undefined,
modaltype:undefined,
visible:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
course_groups:undefined,
modalsType:false,
modalsTopval:"",
loadtype:false,
chooseId:undefined
}
}
//撤销发布
homeworkstart=()=>{
let {checkBoxValues}=this.props
if(checkBoxValues.length==0){
this.props.showNotification("请先在列表中选择数据");
// this.setState({
// modalsType:true,
// modalsTopval:"请先在列表中选择数据",
// loadtype:true
// })
}else{
let pollId=this.props.match.params.pollId;
let url=`/polls/${pollId}/cancel_publish_modal.json`;
axios.get(url,{
params:{
check_ids:checkBoxValues
}
}).then((response) => {
if(response.status===200){
let list=[];
if(response.data.course_info){
for(var i=0;i<response.data.course_info.length;i++){
list.push({
id:response.data.course_info[i].course_group_id,
name:response.data.course_info[i].course_group_name,
})
}
}
this.setState({
course_groups:list,
})
this.setState({
modalname:"撤销发布",
modaltype:response.data.on_commiting > 0 ? 1 : 2,
visible:true,
Topval:"将删除学生已提交的全部作品及其评阅记录",
// Botvalleft:"",
Botval:"删除的作品记录无法恢复",
// starttime:"发布时间:"+getNowFormatDate(1),
// endtime:"截止时间:"+getNowFormatDate(2),
Cancelname:"暂不撤销",
Savesname:"立即撤销",
Cancel:this.homeworkhide,
Saves:this.homeworkstartend,
})
}
}).catch((error) => {
console.log(error)
});
}
}
//取消提示弹框
modalCancel=()=>{
this.setState({
modalsType:false,
modalsTopval:"",
loadtype:false
})
}
//暂不发布
homeworkhide=()=>{
this.setState({
modalname:undefined,
modaltype:undefined,
visible:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
StudentList_value:undefined,
addname:undefined,
addnametype:false,
addnametab:undefined
})
}
// 确定撤销发布
homeworkstartend=()=>{
let {checkBoxValues}=this.props
let {chooseId}=this.state;
let pollId=this.props.match.params.pollId;
let url=`/polls/${pollId}/cancel_publish.json`
axios.post(url,{
check_ids:checkBoxValues,
group_ids:chooseId
}).then((result)=>{
if(result.status==200){
this.props.showNotification(result.data.message);
this.homeworkhide();
// 调用父级公共头部的接口刷新
this.props.action()
}
}).catch((error)=>{
console.log(error);
})
}
getcourse_groupslist=(id)=>{
this.setState({
chooseId:id
})
}
render(){
let{
modalname,
modaltype,
visible,
Topval,
Topvalright,
Botvalleft,
Botval,
starttime,
endtime,
Cancelname,
Savesname,
Cancel,
Saves,
course_groups,
modalsType,
modalsTopval,
loadtype,
}=this.state
return(
<React.Fragment>
<HomeworkModal
modaltype={modaltype}
modalname={modalname}
visible={visible}
Topval={Topval}
Topvalright={Topvalright}
Botvalleft={Botvalleft}
Botval={Botval}
starttime={starttime}
endtime={endtime}
Cancelname={Cancelname}
Savesname={Savesname}
Cancel={Cancel}
Saves={Saves}
course_groups={course_groups}
getcourse_groupslist={(id)=>this.getcourse_groupslist(id)}
/>
{/* 公用的提示弹框 */}
<Modals
modalsType={modalsType}
modalsTopval={modalsTopval}
modalsBottomval=""
loadtype={loadtype}
modalCancel={this.modalCancel}
modalSave={this.ModalAction}
></Modals>
<WordsBtn style={this.props.style} className={this.props.className} onClick={this.homeworkstart}>撤销发布</WordsBtn>
</React.Fragment>
)
}
}
export default CancelPublish

View File

@ -1,269 +0,0 @@
import React,{ Component } from "react";
import Modals from '../../../modals/Modals'
import { WordsBtn } from 'educoder'
import HomeworkModal from "../../coursesPublic/HomeworkModal";
import axios from 'axios'
import moment from 'moment';
class ImmediatelyEnd extends Component{
constructor(props){
super(props)
this.state={
modalname:undefined,
modaltype:undefined,
visible:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
course_groups:undefined,
modalsType:false,
modalsTopval:"",
loadtype:false,
chooseId:undefined
}
}
//立即截止
homeworkstart=()=>{
let {checkBoxValues}=this.props
if(checkBoxValues.length==0){
this.props.showNotification("请先在列表中选择数据");
// this.setState({
// modalsType:true,
// modalsTopval:"请先在列表中选择数据",
// loadtype:true
// })
}else{
let coursesId=this.props.match.params.coursesId;
if(this.props.Exercisetype==="exercise"){
let url=`/courses/${coursesId}/exercises/end_modal.json`;
axios.get(url,{
params:{
check_ids:checkBoxValues
}
}).then((response) => {
if(response.status===200){
let list=[];
if(response.data.course_info){
for(var i=0;i<response.data.course_info.length;i++){
list.push({
id:response.data.course_info[i].course_group_id,
name:response.data.course_info[i].course_group_name,
})
}
}
this.setState({
course_groups:list,
})
this.setState({
modalname:"立即截止",
modaltype:response.data.on_commiting > 0 ? 1 : 2,
visible:true,
Topval:this.props.Exercisetype==="exercise"?"学生将不能再提交试卷":"学生将不能再提交问卷",
// Botvalleft:"暂不截止",
Botval:this.props.single ?this.props.Exercisetype==="exercise"?`本操作只对"提交中"的试卷有效`:`本操作只对"提交中"的问卷有效`:"",
// starttime:"发布时间:"+getNowFormatDate(1),
// endtime:"截止时间:"+getNowFormatDate(2),
Cancelname:"暂不截止",
Savesname:"立即截止",
Cancel:this.homeworkhide,
Saves:this.homeworkstartend,
})
}
}).catch((error) => {
console.log(error)
});
}else{
let url=`/courses/${coursesId}/polls/end_poll_modal.json`;
axios.get(url,{
params:{
check_ids:checkBoxValues
}
}).then((response) => {
if(response.status===200){
let list=[];
if(response.data.course_info){
for(var i=0;i<response.data.course_info.length;i++){
list.push({
id:response.data.course_info[i].course_group_id,
name:response.data.course_info[i].course_group_name,
})
}
}
this.setState({
course_groups:list,
})
this.setState({
modalname:"立即截止",
modaltype:response.data.on_commiting > 0 ? 1 : 2,
visible:true,
Topval:this.props.Exercisetype==="exercise"?"学生将不能再提交试卷":"学生将不能再提交问卷",
// Botvalleft:"暂不截止",
Botval:this.props.single ?this.props.Exercisetype==="exercise"?`本操作只对"提交中"的试卷有效`:`本操作只对"提交中"的问卷有效`:"",
// starttime:"发布时间:"+getNowFormatDate(1),
// endtime:"截止时间:"+getNowFormatDate(2),
Cancelname:"暂不截止",
Savesname:"立即截止",
Cancel:this.homeworkhide,
Saves:this.homeworkstartend,
})
}
}).catch((error) => {
console.log(error)
});
}
}
}
//取消提示弹框
modalCancel=()=>{
this.setState({
modalsType:false,
modalsTopval:"",
loadtype:false
})
}
//暂不发布
homeworkhide=()=>{
this.setState({
modalname:undefined,
modaltype:undefined,
visible:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
StudentList_value:undefined,
addname:undefined,
addnametype:false,
addnametab:undefined
})
}
// 确定立即截止
homeworkstartend=()=>{
let {checkBoxValues}=this.props
let {chooseId}=this.state;
let coursesId=this.props.match.params.coursesId;
if(this.props.Exercisetype==="exercise"){
let url=`/courses/${coursesId}/exercises/end_exercise.json`
axios.post(url,{
check_ids:checkBoxValues,
group_ids:chooseId
}).then((result)=>{
if(result){
this.props.showNotification(result.data.message);
this.homeworkhide();
// 调用父级公共头部的接口刷新
this.props.action()
}
}).catch((error)=>{
console.log(error);
})
}else{
let url=`/courses/${coursesId}/polls/end_poll.json`
axios.post(url,{
check_ids:checkBoxValues,
group_ids:chooseId
}).then((result)=>{
if(result){
this.props.showNotification(result.data.message);
this.homeworkhide();
// 调用父级公共头部的接口刷新
this.props.action()
}
}).catch((error)=>{
console.log(error);
})
}
}
getcourse_groupslist=(id)=>{
this.setState({
chooseId:id
})
}
render(){
let{
modalname,
modaltype,
visible,
Topval,
Topvalright,
Botvalleft,
Botval,
starttime,
endtime,
Cancelname,
Savesname,
Cancel,
Saves,
course_groups,
modalsType,
modalsTopval,
loadtype,
}=this.state
return(
<React.Fragment>
<HomeworkModal
modaltype={modaltype}
typs={"end"}
modalname={modalname}
visible={visible}
Topval={Topval}
Topvalright={Topvalright}
Botvalleft={Botvalleft}
Botval={Botval}
starttime={starttime}
endtime={endtime}
Cancelname={Cancelname}
Savesname={Savesname}
Cancel={Cancel}
Saves={Saves}
course_groups={course_groups}
getcourse_groupslist={(id)=>this.getcourse_groupslist(id)}
/>
{/* 公用的提示弹框 */}
<Modals
modalsType={modalsType}
modalsTopval={modalsTopval}
modalsBottomval=""
loadtype={loadtype}
modalCancel={this.modalCancel}
modalSave={this.modalCancel}
></Modals>
<WordsBtn style={this.props.style} className={this.props.className} onClick={this.homeworkstart}>立即截止</WordsBtn>
</React.Fragment>
)
}
}
export default ImmediatelyEnd

View File

@ -1,413 +0,0 @@
import React,{ Component } from "react";
import Modals from '../../../modals/Modals'
import { WordsBtn } from 'educoder'
import HomeworkModal from "../../coursesPublic/HomeworkModal";
import OneSelfOrderModal from "../../coursesPublic/OneSelfOrderModal";
import axios from 'axios'
import moment from 'moment';
class Immediatelypublish extends Component{
constructor(props){
super(props)
this.state={
modalname:undefined,
modaltype:undefined,
visible:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
starttimes:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
course_groups:undefined,
modalsType:false,
modalsTopval:"",
loadtype:false,
chooseId:undefined,
immediatelyopen:false
}
}
//立即发布
homeworkstart=()=>{
let {checkBoxValues,pushtype}=this.props
if(pushtype===true){
if(checkBoxValues.length==0){
this.props.showNotification("请先在列表中选择数据");
// this.setState({
// modalsType:true,
// modalsTopval:"请先在列表中选择数据",
// loadtype:true
// })
}else{
let coursesId=this.props.match.params.coursesId;
if(this.props.Exercisetype==="exercise"){
let url=`/exercises/${this.props.match.params.Id}/publish_groups.json`;
axios.get(url).then((response) => {
if (response.data) {
let starttimesend=response.data.end_time === undefined || response.data.end_time === null || response.data.end_time === "" ? undefined : response.data.end_time;
this.setState({
modalname:"立即发布",
modaltype:response.data.course_groups===null||response.data.course_groups.length===0?2:1,
Topval:this.props.Exercisetype==="exercise"?"学生将立即收到试卷":"学生将立即收到问卷",
// Botvalleft:"暂不发布",
Botval:this.props.single ? "":this.props.Exercisetype==="exercise"?`本操作只对"未发布"的试卷有效`:`本操作只对"未发布"的问卷有效`,
starttime:moment(moment(new Date())).format("YYYY-MM-DD HH:mm"),
starttimes:this.props.getNowFormatDates(1),
endtime:"截止时间:"+this.props.getNowFormatDates(2),
Cancelname:"暂不发布",
Savesname:"立即发布",
Cancel:this.homeworkhide,
Saves:this.homeworkstartend,
course_groups:response.data.course_groups,
starttimesend:starttimesend,
immediatelyopen:response.data.course_groups===null||response.data.course_groups.length===0?false:true,
OneSelftype:true,
})
}
}).catch((error) => {
console.log(error)
});
}else{
let url=`/polls/${this.props.match.params.pollId}/publish_groups.json`;
axios.get(url).then((response) => {
if (response.data) {
let starttimesend=response.data.end_time === undefined || response.data.end_time === null || response.data.end_time === "" ? undefined : response.data.end_time;
this.setState({
modalname:"立即发布",
modaltype:response.data.course_groups===null||response.data.course_groups.length===0?2:1,
Topval:this.props.Exercisetype==="exercise"?"学生将立即收到试卷":"学生将立即收到问卷",
// Botvalleft:"暂不发布",
Botval:this.props.single ? "":this.props.Exercisetype==="exercise"?`本操作只对"未发布"的试卷有效`:`本操作只对"未发布"的问卷有效`,
starttime:"发布时间:"+moment(moment(new Date())).format("YYYY-MM-DD HH:mm"),
starttimes:this.props.getNowFormatDates(1),
endtime:"截止时间:"+this.props.getNowFormatDates(2),
Cancelname:"暂不发布",
Savesname:"立即发布",
Cancel:this.homeworkhide,
Saves:this.homeworkstartend,
course_groups:response.data.course_groups,
starttimesend:starttimesend,
immediatelyopen:response.data.course_groups===null||response.data.course_groups.length===0?false:true,
OneSelftype:true,
})
}
}).catch((error) => {
console.log(error)
});
}
}
}else{
if(checkBoxValues.length==0){
this.props.showNotification("请先在列表中选择数据");
// this.setState({
// modalsType:true,
// modalsTopval:"请先在列表中选择数据",
// loadtype:true
// })
}else{
let coursesId=this.props.match.params.coursesId;
if(this.props.Exercisetype==="exercise"){
let url=`/courses/${coursesId}/exercises/publish_modal.json`;
axios.get(url,{
params:{
check_ids:checkBoxValues
}
}).then((response) => {
if(response.status===200){
let list=[];
if(response.data.course_info){
for(var i=0;i<response.data.course_info.length;i++){
list.push({
id:response.data.course_info[i].course_group_id,
name:response.data.course_info[i].course_group_name,
})
}
}
this.setState({
course_groups:list,
})
this.setState({
modalname:"立即发布",
modaltype:response.data.un_publish > 0 ? 1 : 2,
visible:true,
Topval:this.props.Exercisetype==="exercise"?"学生将立即收到试卷":"学生将立即收到问卷",
// Botvalleft:"暂不发布",
Botval:this.props.single ? "":this.props.Exercisetype==="exercise"?`本操作只对"未发布"的试卷有效`:`本操作只对"未发布"的问卷有效`,
starttime:"发布时间:"+moment(moment(new Date())).format("YYYY-MM-DD HH:mm"),
starttimes:this.props.getNowFormatDates(1),
endtime:"截止时间:"+this.props.getNowFormatDates(2),
Cancelname:"暂不发布",
Savesname:"立即发布",
Cancel:this.homeworkhide,
Saves:this.homeworkstartend,
})
}
}).catch((error) => {
console.log(error)
});
}else{
let url=`/courses/${coursesId}/polls/publish_modal.json`;
axios.get(url,{
params:{
check_ids:checkBoxValues
}
}).then((response) => {
if(response){
let list=[];
if(response.data.course_info){
for(var i=0;i<response.data.course_info.length;i++){
list.push({
id:response.data.course_info[i].course_group_id,
name:response.data.course_info[i].course_group_name,
})
}
}
this.setState({
course_groups:list,
})
this.setState({
modalname:"立即发布",
modaltype:response.data.un_publish > 0 ? 1 : 2,
visible:true,
Topval:this.props.Exercisetype==="exercise"?"学生将立即收到试卷":"学生将立即收到问卷",
// Botvalleft:"暂不发布",
Botval:this.props.single ? "":this.props.Exercisetype==="exercise"?`本操作只对"未发布"的试卷有效`:`本操作只对"未发布"的问卷有效`,
starttime:"发布时间:"+moment(moment(new Date())).format("YYYY-MM-DD HH:mm"),
starttimes:this.props.getNowFormatDates(1),
endtime:"截止时间:"+this.props.getNowFormatDates(2),
Cancelname:"暂不发布",
Savesname:"立即发布",
Cancel:this.homeworkhide,
Saves:this.homeworkstartend,
})
}
}).catch((error) => {
console.log(error)
});
}
}
}
}
//取消提示弹框
modalCancel=()=>{
this.setState({
modalsType:false,
modalsTopval:"",
loadtype:false
})
}
//暂不发布
homeworkhide=()=>{
this.setState({
modalname:undefined,
modaltype:undefined,
visible:false,
OneSelftype:false,
Topval:undefined,
Topvalright:undefined,
Botvalleft:undefined,
Botval:undefined,
starttime:undefined,
starttimes:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
StudentList_value:undefined,
addname:undefined,
addnametype:false,
addnametab:undefined
})
}
// 确定立即发布
homeworkstartend=(ids,endtime)=>{
let {checkBoxValues,pushtype}=this.props
let {chooseId}=this.state;
let coursesId=this.props.match.params.coursesId;
let data={};
if(pushtype===true){
if(ids.length===0){
data = {
check_ids:checkBoxValues,
end_time: endtime,
}
}else{
data={
check_ids: checkBoxValues,
group_ids: ids,
group_end_times:endtime,
detail:true
}
}
}else{
data={
check_ids:checkBoxValues,
group_ids:chooseId,
end_time:endtime
}
}
if(this.props.Exercisetype==="exercise"){
let url=`/courses/${coursesId}/exercises/publish.json`
axios.post(url,data).then((result)=>{
if(result){
this.props.showNotification(result.data.message);
this.homeworkhide();
// 调用父级公共头部的接口刷新
try {
this.props.action();
}catch (e) {
}
// 调用父级刷新数据的接口刷新
try {
this.props.getsetdata()
}catch (e) {
}
}
}).catch((error)=>{
console.log(error);
})
}else{
let url=`/courses/${coursesId}/polls/publish.json`
axios.post(url,data).then((result)=>{
if(result){
this.props.showNotification(result.data.message);
this.homeworkhide();
// 调用父级公共头部的接口刷新
this.props.action()
}
}).catch((error)=>{
console.log(error);
})
}
}
getcourse_groupslist=(id)=>{
this.setState({
chooseId:id
})
}
render(){
let{
modalname,
modaltype,
visible,
Topval,
Topvalright,
Botvalleft,
Botval,
starttime,
starttimes,
endtime,
Cancelname,
Savesname,
Cancel,
Saves,
course_groups,
modalsType,
modalsTopval,
loadtype,
}=this.state
return(
<React.Fragment>
<HomeworkModal
modaltype={modaltype}
modalname={modalname}
visible={visible}
Topval={Topval}
Topvalright={Topvalright}
Botvalleft={Botvalleft}
Botval={Botval}
starttime={starttime}
starttimes={starttimes}
endtime={endtime}
Cancelname={Cancelname}
Savesname={Savesname}
Cancel={Cancel}
Saves={Saves}
course_groups={course_groups}
getcourse_groupslist={(id)=>this.getcourse_groupslist(id)}
/>
{/*立即发布*/}
{this.state.OneSelftype===true?<OneSelfOrderModal
modaltype={this.state.modaltype}
modalname={this.state.modalname}
OneSelftype={this.state.OneSelftype}
Topval={this.state.Topval}
Topvalright={this.state.Topvalright}
Botvalleft={this.state.Botvalleft}
Botval={this.state.Botval}
starttime={this.state.starttime}
endtime={this.state.endtime}
Cancelname={this.state.Cancelname}
Savesname={this.state.Savesname}
Cancel={this.state.Cancel}
Saves={this.state.Saves}
course_groups={this.state.course_groups}
getcourse_groupslist={(id) => this.getcourse_groupslist(id)}
starttimes={this.state.starttimes}
starttimesend={this.state.starttimesend}
typs={this.state.typs}
immediatelyopen={this.state.immediatelyopen}
/>:""}
{/* 公用的提示弹框 */}
<Modals
modalsType={modalsType}
modalsTopval={modalsTopval}
modalsBottomval=""
loadtype={loadtype}
modalCancel={this.modalCancel}
modalSave={this.modalCancel}
></Modals>
<WordsBtn style={this.props.style} className={this.props.className} onClick={()=>this.homeworkstart()}>立即发布</WordsBtn>
</React.Fragment>
)
}
}
export default Immediatelypublish

View File

@ -1,382 +0,0 @@
/* 单选或多选 */
.ant-form{
color:#05101A;
}
.ant-radio-disabled + span,.ant-checkbox-disabled + span{
color: #666!important;
cursor: default
}
.ant-radio-wrapper {
color: #666!important;
}
.ant-checkbox-wrapper + .ant-checkbox-wrapper{
margin-left: 0px!important;
}
/* 下拉 */
.ant-select-selection,.ant-select-selection-selected-value{
min-height: 40px;
min-line-height: 40px;
}
.ml61{
margin-left: 61px;
}
.w64{
width: 64px;
}
.w55{
width: 55px!important;
}
.max1010{
width: 1010px !important;
max-width: 1010px !important;
}
.yw18{
min-width: 18px;
}
/* 选答 */
.chooseAnswer{
display: inline-block;
width: 68px;
text-align: center;
height: 24px;
line-height: 24px;
background: #EDEDED;
color: #666;
margin-left: 10px;
border-radius: 12px;
}
.problemShow{
padding:30px;
border-bottom: 1px solid #eee;
}
.problemShow:last-child{
border-bottom: none;
}
.invite-tipysls{position: absolute;top: -8px;right: 140px;color: #fff; box-sizing: border-box;width: 170px;text-align: center;border-radius: 2px;background-color: rgba(5,16,26,0.6)}
.yslinvitetip{display: block;border-width: 8px;position: absolute;top: 10px;right: -16px;border-style: dashed solid dashed dashed;border-color: transparent transparent transparent rgba(5,16,26,0.6);font-size: 0;line-height: 0;}
.right-black-trangle{border-width: 8px;position: absolute;top: 10px;left: -16px;border-style: dashed solid dashed dashed;border-color: transparent transparent transparent rgba(5,16,26,0.6);font-size: 0;line-height: 0;}
.right-black-trangles{border-width: 8px;position: absolute;top: 10px;left: -16px;border-style: dashed solid dashed dashed;border-color: transparent rgba(5,16,26,0.6) transparent transparent;font-size: 0;line-height: 0;}
.top-black-trangle{border-width: 8px;position: absolute;top: -16px;right: 4px;border-style: dashed solid dashed dashed;border-color: transparent transparent rgba(5,16,26,0.6) transparent;font-size: 0;line-height: 0;}
.invite-tipysl{color: #999999; box-sizing: border-box;text-align: center;border-radius: 2px;font-size: 14px}
.edu-position-hideysl li a:hover{ background:#F1F1F1; color:#05101A;}
.to-back-left {
width: 0;
height: 0;
margin-top: 27px;
border-right: 15px solid #FAFAFA;
border-top: 10px solid transparent;
border-bottom: 10px solid transparent;
}
/* 问卷详情 */
/* 答题列表 */
.unlimit{
height: 24px;
line-height: 24px;
padding:0px 10px;
border-radius: 12px;
cursor: pointer;
border:1px solid #cdcdcd;
color:#666;
}
.unlimit.active{
background-color: #4CACFF;
border:1px solid #4CACFF;
color: #fff;
}
.edu-table thead th,.edu-table tbody tr:last-child td{
border-bottom: none!important;
}
.edu-table tbody tr:hover td{
background-color: #fff!important;
}
/* 统计结果 */
.countList p.countHeader{
background-color: #f8f8f8;
color: #666;
height: 38px;
font-size: 16px;
justify-content: center;
align-items: center;
display: -webkit-flex;
}
.countList p.countHeader ul{
width: 100%;
padding:0px 30px
}
.countList p.countHeader span,.countList div.countBody span{
float: left;
}
.countList div.countBody{
margin:0px 30px;
border-bottom:1px solid #EBEBEB;
padding:12px 0px;
}
.countList div.countBody:last-child{
border-bottom: none;
}
.countList p.countHeader span:nth-child(1),.countList div.countBody span:nth-child(1){
width: 50%;
text-align: left;
}
.countList p.countHeader span:nth-child(2),.countList div.countBody span:nth-child(2){
width:15%;
text-align: center;
}
.countList p.countHeader span:nth-child(3),.countList div.countBody span:nth-child(3){
width:35%;
text-align: left;
}
.percentForm{
width: 330px;
height: 11px;
background: #F5F5F5;
border-radius: 6px;
position: relative;
margin-top: 7px;
}
.percentValue{
position: absolute;
top:0px;
left: 0px;
height: 11px;
background: #29BD8B;
border-radius: 6px;
}
.answerTxt{
max-height: 500px;
background-color: #F2F9FF;
width: 100%;
margin-top: 10px;
padding:10px;
box-sizing: border-box;
color: #4c4c4c;
}
.otherTxt{
border:none!important;
border-bottom: 1px solid #eee!important;
background: transparent!important;
flex:1;
height: 20px!important;
line-height: 20px!important;
}
.otherTxt.ant-input:hover,.otherTxt.ant-input:focus{
border:none!important;
border-bottom: 1px solid #eee!important;
background: #F8F8F8!important;
}
/* 必答 */
.mustAnswer{
padding:0px 10px;
border-radius: 15px;
height: 22px;
line-height: 22px;
background: #eaeaea;
color: #999;
font-size: 14px;
}
/* 问卷内容 */
.previewList{
border-bottom: 1px solid #ebebeb;
}
.previewList:last-child{
border-bottom:none;
}
.textLine{
flex: 1;
height:22px;
border-bottom: 1px solid #ebebeb;
}
.answerList{
box-sizing: border-box;
width: 100%;
margin-bottom: 20px;
}
.answerList li{
padding:10px 30px;
box-sizing: border-box;
line-height:20px;
width: 100%;
}
.answerList li:hover{
background: #F0F8FF;
}
textarea:read-only{
background: #f3f3f3;
}
.ant-calendar-picker-input{
height: 40px;
}
/* 问卷答题 */
.questionsNo{
position: relative;
padding: 30px;
border-bottom: 1px solid #ebebeb;
}
.questionsfixed{
position: fixed;
padding: 30px;
z-index: 12;
top: 60px;
width: 1200px;
background: #fff;
}
.answered,.unanswer,.answerTure,.answerFalse,.answerHalf{
position: relative;
}
.answered::after{
position: absolute;
right:35px;
top:4px;
width: 12px;
height: 12px;
border-radius: 50%;
background: #CBCBCB;
content: "";
}
.unanswer::after{
position: absolute;
right:35px;
top:4px;
width: 12px;
height: 12px;
border-radius: 50%;
background: #fff;
content: "";
border:1px solid rgba(203,203,203,1);
}
.answerTure::after{
position: absolute;
right:35px;
top:4px;
width: 20px;
height: 10px;
border-radius: 5px;
background: #29BD8B;
content: "";
}
.answerFalse::after{
position: absolute;
right:35px;
top:4px;
width: 20px;
height: 10px;
border-radius: 5px;
background: #FF3756;
content: "";
}
.color-red{color: #FF3756!important}
.answerHalf::after{
position: absolute;
left:-25px;
top:4px;
width: 20px;
height: 10px;
border-radius: 5px;
background: #FF6800;
content: "";
}
.leaderNav,.leaderMainNav{
margin-top: 20px;
}
.leaderNav a,.leaderMainNav a{
display: block;
float: left;
margin-right: 10px;
border-radius: 50%;
border:1px solid #CBCBCB;
height: 40px;
line-height: 40px;
width: 40px;
text-align: center;
color: #999999;
cursor: pointer;
margin-bottom: 5px;
}
.leaderMainNav a{
background: #FF3756;
color: #fff;
border:1px solid #FF3756;
}
.leaderNav a.acted{
background:rgba(203,203,203,1);
color: #fff;
}
.leaderMainNav a.acted{
background-color: #29BD8B;
color: #fff;
border:1px solid #29BD8B;
}
.leaderMainNav a.half{
background-color: #FF6800;
color: #fff;
border:1px solid #FF6800;
}
/* 问卷设置 */
.pollForm .ant-form-item-control{
line-height: 20px;
}
.pollForm.ant-form-item{
margin-bottom: 0px
}
.setInfo .ant-select-selection__rendered{
line-height: 40px;
}
/* 下拉搜索框 */
.ant-select-dropdown-menu .ant-select-dropdown-menu-item{
padding:5px 15px;
}
.ant-select-dropdown.ant-select-dropdown--multiple .ant-select-dropdown-menu-item .ant-select-selected-icon{
right: 15px;
}
.noticeTip{
border:1px solid #FF0000;
border-radius: 5px;
}
.pollResultList .ant-table-thead > tr > th,.pollResultList .ant-table-tbody > tr > td{
padding:15px 6px;
}
/* 试卷 */
.setScoreInput{
width: 60px!important;height: 30px!important;box-sizing: border-box;
text-align: center!important;
background: #F8F8F8;
color:#666;
}
.setScoreInput:focus{
background: #fff;
color:#FF6800
}
.standardAnswer p{
line-height: 20px!important;
}
/* 倒计时 */
.remainingTime li{
float: left;
width: 40px;
line-height: 40px;
background-color: #111C24;
color: #fff;
border-radius: 4px;
text-align: center
}
.remainingTime span{
float: left;
width: 20px;
line-height: 40px;
text-align: center;
}
.myyslwidth {
min-width:1200px
}
.zexercisetitle {
font-size: 16px;
color: rgba(51, 51, 51, 1);
min-width: 95px;
}