Merge branches 'dev_aliyun' and 'topic_bank' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun

dev_hss
杨树明 5 years ago
commit 9f9532eb69

@ -83,6 +83,7 @@ a.edu-txt-w80,.edu-txt-w80{ width:80px; display: inline-block;text-align: center
.font-20{ font-size: 20px!important;}
.font-22{ font-size: 22px!important;}
.font-24{ font-size: 24px!important;}
.font-25{ font-size: 25px!important;}
.font-26{ font-size: 26px!important;}
.font-28{ font-size: 28px!important;}
.font-30{ font-size: 30px!important;}

@ -0,0 +1,5 @@
class ModifyIsTestForUser < ActiveRecord::Migration[5.2]
def change
change_column :users, :is_test, :integer, :limit => 1
end
end

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

@ -103,6 +103,7 @@ a:hover.link-color-grey03{color:#3498db!important;}
.font-18{ font-size: 18px!important;}
.font-20{ font-size: 20px!important;}
.font-22{ font-size: 22px!important;}
.font-25{ font-size: 25px!important;}
.font-24{ font-size: 24px!important;}
.font-28{ font-size: 28px!important;}
.font-30{ font-size: 30px!important;}

@ -103,6 +103,7 @@ a:hover.link-color-grey03{color:#3498db!important;}
.font-18{ font-size: 18px!important;}
.font-20{ font-size: 20px!important;}
.font-22{ font-size: 22px!important;}
.font-25{ font-size: 25px!important;}
.font-24{ font-size: 24px!important;}
.font-28{ font-size: 28px!important;}
.font-30{ font-size: 30px!important;}

@ -222,6 +222,12 @@ const InfosIndex = Loadable({
loader: () => import('./modules/user/usersInfo/InfosIndex'),
loading: Loading,
})
// 题库
const BanksIndex = Loadable({
loader: () => import('./modules/user/usersInfo/banks/BanksIndex'),
loading: Loading,
})
// 教学案例
const MoopCases = Loadable({
@ -245,6 +251,11 @@ const Messagerouting= Loadable({
loader: () => import('./modules/message/js/Messagerouting'),
loading: Loading,
})
const Topicbank= Loadable({
loader: () => import('./modules/topic_bank/Topic_bank'),
loading: Loading,
})
class App extends Component {
constructor(props) {
super(props)
@ -403,6 +414,15 @@ class App extends Component {
<Router>
<Switch>
{/*题库*/}
<Route path="/topicbank/:username/:topicstype"
render={
(props) => {
return (<Topicbank {...this.props} {...props} {...this.state} />)
}
}></Route>
{/*众包创新*/}
<Route path={"/crowdsourcing"} component={ProjectPackages}/>
{/*认证*/}
@ -431,6 +451,13 @@ class App extends Component {
}
}></Route>
<Route path="/banks"
render={
(props) => {
return (<BanksIndex {...this.props} {...props} {...this.state} />)
}
}></Route>
<Route
path="/changepassword" component={EducoderLogin}
/>

@ -48,7 +48,17 @@ export function SnackbarHOC(options = {}) {
snackbarHorizontal: horizontal,
})
}
//个别情况需要走
showNotification = (description, message = "提示", icon) => {
const data = {
message,
description
}
if (icon) {
data.icon = icon;
}
notification.open(data);
}
render() {
const { snackbarOpen, snackbarText, snackbarHorizontal, snackbarVertical } = this.state;
@ -70,7 +80,7 @@ export function SnackbarHOC(options = {}) {
resumeHideDuration={2000}
message={<span id="message-id">{this.state.snackbarText}</span>}
/>
<WrappedComponent {...this.props} showSnackbar={ this.showSnackbar } >
<WrappedComponent {...this.props} showSnackbar={ this.showSnackbar } showNotification= { this.showNotification } >
</WrappedComponent>
</React.Fragment>

@ -232,7 +232,7 @@ const GraduationTasksquestions= Loadable({
//毕设任务列表
const GraduationTaskssettinglist= Loadable({
loader: () => import('./graduation/tasks/GraduationTaskssettinglist'),
loader: () => import('./graduation/tasks/GraduationTaskDetail'),
loading: Loading,
})
@ -264,34 +264,12 @@ const GraduationTasksSubmiteditApp=Loadable({
loader: () => import('./graduation/tasks/GraduationTasksSubmitedit'),
loading: Loading,
})
//普通作业题库详情
const Generaljobbankdetails =Loadable({
loader: () => import('../../modules/courses/questionbank/Generaljobbankdetails'),
loading: Loading,
});
//分组作业题库详情
const GroupjobbankPage =Loadable({
loader: () => import('../../modules/courses/groupjobbank/GroupjobbankPage'),
loading: Loading,
});
//毕设选题详情
const CompletetopicdePage =Loadable({
loader: () => import('../../modules/courses/comtopicdetails/CompletetopicdePage'),
loading: Loading,
});
//毕设任务详情
const Completetaskpage =Loadable({
loader: () => import('../../modules/courses/completetaskdetails/Completetaskpage'),
loading: Loading,
});
//排序
const Ordering=Loadable({
loader: () => import('../../modules/courses/ordering/Ordering'),
loading: Loading,
});
class CoursesIndex extends Component{
constructor(props) {
super(props)
@ -478,37 +456,12 @@ class CoursesIndex extends Component{
// console.log(commons)
return (
<Switch {...this.props}>
{/*排序*/}
<Route path="/courses/:coursesId/ordering/:ordering_type/:main_id"
render={
(props) => (<Ordering {...this.props} {...props} {...this.state} />)
}
></Route>
{/*毕设任务题库详情*/}
<Route path="/banks/gtopic_topics/:workid"
render={
(props) => (<Completetaskpage {...this.props} {...props} {...this.state} {...common}/>)
}
></Route>
{/*毕设内容题库详情*/}
<Route path="/banks/gtask_topics/:workid"
render={
(props) => (<CompletetopicdePage {...this.props} {...props} {...this.state} {...common}/>)
}
></Route>
{/*分组作业题库详情*/}
<Route path="/banks/group_topics/:workid"
render={
(props) => (<GroupjobbankPage {...this.props} {...props} {...this.state} {...common}/>)
}
></Route>
{/* 普通作业题库详情*/}
<Route path="/banks/normal_topics/:workid"
render={
(props) => (<Generaljobbankdetails {...this.props} {...props} {...this.state} {...common}/>)
}
></Route>
{/*排序*/}
<Route path="/courses/:coursesId/ordering/:ordering_type/:main_id"
render={
(props) => (<Ordering {...this.props} {...props} {...this.state} />)
}
></Route>
{/* 资源列表页 */}
<Route path="/courses/:coursesId/file/:Id" exact
render={
@ -589,7 +542,7 @@ class CoursesIndex extends Component{
{/* 设置毕设任务 https://www.trustie.net/issues/19981 */}
<Route path="/courses/:coursesId/graduation_tasks/:category_id/:task_Id/setting"
{/* <Route path="/courses/:coursesId/graduation_tasks/:category_id/:task_Id/setting"
render={
(props) => (<GraduationTaskssetting {...this.props} {...props} {...this.state} {...common}/>)
}
@ -597,19 +550,18 @@ class CoursesIndex extends Component{
<Route path="/courses/:coursesId/graduation_tasks/:category_id/:task_Id/questions"
render={
(props) => (<GraduationTasksquestions {...this.props} {...props} {...this.state} {...common}/>)
}></Route>
render={
(props) => (<GraduationTasksquestions {...this.props} {...props} {...this.state} />)
}></Route> */}
<Route path="/courses/:coursesId/graduation_tasks/:category_id/:task_Id/list"
<Route path="/courses/:coursesId/graduation_tasks/:category_id/:task_Id"
render={
(props) => (<GraduationTaskssettinglist {...this.props} {...props} {...this.state} {...common}/>)
}
></Route>
{/* 修改毕设任务 https://www.trustie.net/issues/19981 */}
<Route path="/courses/:coursesId/graduation_tasks/:category_id/edit"
render={

@ -4,250 +4,125 @@ import axios from 'axios'
import '../css/busyWork.css'
import '../css/Courses.css'
import { WordsBtn, getUrl, ConditionToolTip, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll
, getUploadActionUrl } from 'educoder'
, getUploadActionUrl } from 'educoder'
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import CBreadcrumb from '../common/CBreadcrumb'
import NewWorkForm from './NewWorkForm'
const confirm = Modal.confirm;
const $ = window.$
const MAX_TITLE_LENGTH = 60;
class NewWork extends Component{
constructor(props){
super(props);
this.contentMdRef = React.createRef();
this.answerMdRef = React.createRef();
this.state={
title_value:"",
title_num: 0,
contentFileList: [],
answerFileList: [],
workLoaded: false,
base_on_project: true,
category: {},
min_num: 2,
max_num: 10,
}
}
componentDidMount () {
let {typeId, coursesId, pageType, workId}=this.props.match.params;
const isEdit = pageType === "edit"
this.isEdit = isEdit;
if (isEdit) {
this.fetchWork(workId)
} else {
this.fetchCourseData(coursesId)
}
}
fetchCourseData = (courseId) => {
const isGroup = this.props.isGroup()
const url = `/courses/${courseId}/homework_commons/new.json?type=${isGroup ? 3 : 1}`
axios.get(url, {
})
.then((response) => {
if (response.data.course_name) {
const data = response.data;
this.setState({
course_id: data.course_id,
course_name: data.course_name,
category: data.category,
})
}
})
.catch(function (error) {
console.log(error);
});
}
fetchWork = (workId) => {
const url = `/homework_commons/${workId}/edit.json`
axios.get(url, {
})
.then((response) => {
if (response.data.name) {
const data = response.data;
const contentFileList = data.attachments.map(item => {
return {
id: item.id,
uid: item.id,
name: appendFileSizeToUploadFile(item),
url: item.url,
filesize: item.filesize,
status: 'done'
}
})
const answerFileList = data.ref_attachments.map(item => {
return {
id: item.id,
uid: item.id,
name: appendFileSizeToUploadFile(item),
url: item.url,
filesize: item.filesize,
status: 'done'
}
})
this.setState({
...data,
// course_id: data.course_id,
// course_name: data.course_name,
// category: data.category,
title_num: parseInt(data.name.length),
workLoaded: true,
init_min_num: data.min_num,
init_max_num: data.max_num,
// description: data.description,
reference_answer: data.reference_answer,
contentFileList,
answerFileList,
}, () => {
setTimeout(() => {
this.contentMdRef.current.setValue(data.description || '')
this.answerMdRef.current.setValue(data.reference_answer || '')
}, 2000)
this.props.form.setFieldsValue({
title: data.name,
description: data.description || '',
reference_answer: data.reference_answer || '',
});
})
}
})
.catch(function (error) {
console.log(error);
});
}
// 输入title
changeTitle=(e)=>{
console.log(e.target.value.length);
this.setState({
title_num: parseInt(e.target.value.length)
})
}
handleSubmit = () => {
const courseId = this.state.course_id || this.props.match.params.coursesId ;
this.props.form.validateFieldsAndScroll((err, values) => {
console.log(values)
const mdContnet = this.contentMdRef.current.getValue().trim();
console.log(mdContnet)
values.description = mdContnet;
// return;
{/* max={has_commit ? init_min_num : null } */}
{/* min={has_commit ? init_max_num : (min_num == undefined ? 2 : min_num + 1) } */}
// 已有提交作品,人数范围只能扩大
const { has_commit, max_num, init_max_num, min_num, init_min_num } = this.state;
if (has_commit) {
if (max_num < init_max_num || min_num > init_min_num) {
this.props.showNotification(`已有提交作品,人数范围只能扩大(原设置为:${init_min_num} - ${init_max_num})`)
return;
}
}
// const errKeys = Object.keys(err); // || errKeys.length == 1 && errKeys[0] == 'content' && mdContnet
if (!err) {
if (this.isEdit) {
this.doEdit(courseId, values)
} else {
this.doNew(courseId, values)
}
} else {
$("html").animate({ scrollTop: $('html').scrollTop() - 100 })
}
})
}
doEdit = (courseId, values) => {
const workId = this.props.match.params.workId
const newUrl = `/homework_commons/${workId}.json`
let attachment_ids = this.state.contentFileList.map(item => {
return item.response ? item.response.id : item.id
})
let reference_attachment_ids = this.state.answerFileList.map(item => {
return item.response ? item.response.id : item.id
})
const { min_num, max_num, base_on_project, category } = this.state
const isGroup = this.props.isGroup()
axios.put(newUrl, {
type: isGroup ? 3 : 1,
name: values.title,
description: values.description,
reference_answer: values.reference_answer,
attachment_ids,
reference_attachment_ids,
min_num,
max_num,
base_on_project
})
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('保存成功')
this.props.toWorkListPage(this.props.match.params, workId)
}
})
.catch(function (error) {
console.log(error);
});
}
doNew = (courseId, values) => {
const newUrl = `/courses/${courseId}/homework_commons.json`
let attachment_ids = this.state.contentFileList.map(item => {
return item.response ? item.response.id : item.id
})
let reference_attachment_ids = this.state.answerFileList.map(item => {
return item.response ? item.response.id : item.id
})
const isGroup = this.props.isGroup()
const { min_num, max_num, base_on_project, category } = this.state
axios.post(newUrl, {
type: isGroup ? 3 : 1,
name: values.title,
description: values.description,
reference_answer: values.reference_answer,
attachment_ids,
reference_attachment_ids,
min_num,
max_num,
base_on_project
})
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('保存成功')
this.props.toWorkListPage(this.props.match.params, response.data.homework_id)
}
})
.catch(function (error) {
console.log(error);
});
}
constructor(props){
super(props);
this.contentMdRef = React.createRef();
this.answerMdRef = React.createRef();
this.state={
category: {},
course_name: ''
}
}
componentDidMount () {
let {typeId, coursesId, pageType, workId}=this.props.match.params;
const isEdit = pageType === "edit"
this.isEdit = isEdit;
if (isEdit) {
this.fetchWork(workId)
} else {
this.fetchCourseData(coursesId)
}
}
fetchCourseData = (courseId) => {
const isGroup = this.props.isGroup()
const url = `/courses/${courseId}/homework_commons/new.json?type=${isGroup ? 3 : 1}`
axios.get(url, {
})
.then((response) => {
if (response.data.course_name) {
const data = response.data;
this.setState({
course_id: data.course_id,
course_name: data.course_name,
category: data.category,
})
}
})
.catch(function (error) {
console.log(error);
});
}
fetchWork = (workId) => {
const url = `/homework_commons/${workId}/edit.json`
axios.get(url, {
})
.then((response) => {
if (response.data.name) {
const data = response.data;
data.isEdit = this.isEdit
this.setState({
course_id: data.course_id,
course_name: data.course_name,
category: data.category,
})
this.newWorkFormRef.initValue(response.data)
}
})
.catch(function (error) {
console.log(error);
});
}
onCancel = () => {
this.props.toListPage(this.props.match.params, this.state.category.category_id)
}
doEdit = (params) => {
const workId = this.props.match.params.workId
const newUrl = `/homework_commons/${workId}.json`
axios.put(newUrl, params)
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('保存成功')
this.props.toWorkListPage(this.props.match.params, workId)
}
})
.catch(function (error) {
console.log(error);
});
}
doNew = (params) => {
const coursesId = this.props.match.params.coursesId
const newUrl = `/courses/${coursesId}/homework_commons.json`
axios.post(newUrl, params)
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('保存成功')
this.props.toWorkListPage(this.props.match.params, response.data.homework_id)
}
})
.catch(function (error) {
console.log(error);
});
}
handleContentUploadChange = (info) => {
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
let contentFileList = info.fileList;
this.setState({ contentFileList: appendFileSizeToUploadFileAll(contentFileList) });
}
}
handleAnswerUploadChange = (info) => {
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
let answerFileList = info.fileList;
this.setState({ answerFileList: appendFileSizeToUploadFileAll(answerFileList) });
}
}
handleContentUploadChange = (info) => {
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
let contentFileList = info.fileList;
this.setState({ contentFileList: appendFileSizeToUploadFileAll(contentFileList) });
}
}
handleAnswerUploadChange = (info) => {
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
let answerFileList = info.fileList;
this.setState({ answerFileList: appendFileSizeToUploadFileAll(answerFileList) });
}
}
onAttachmentRemove = (file, stateName) => {
onAttachmentRemove = (file, stateName) => {
if(!file.percent || file.percent == 100){
this.props.confirm({
content: '是否确认删除?',
@ -264,293 +139,69 @@ class NewWork extends Component{
return false;
}
}
deleteAttachment = (file, stateName) => {
// 初次上传不能直接取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[stateName].indexOf(file);
const newFileList = state[stateName].slice();
newFileList.splice(index, 1);
return {
[stateName]: newFileList,
};
});
}
}
})
.catch(function (error) {
console.log(error);
});
}
max_num_change = (val) => {
if (val < 2) {
this.setState({
max_num: 2,
})
return;
}
const { min_num } = this.state;
this.setState({
max_num: val,
min_num: val <= min_num ? val - 1 : min_num
})
}
min_num_change = (val) => {
this.setState({ min_num: val })
}
base_on_project_change = () => {
this.setState({ base_on_project: !this.state.base_on_project })
}
render(){
let {typeId,coursesId,pageType}=this.props.match.params;
render(){
let {typeId,coursesId,pageType}=this.props.match.params;
const { getFieldDecorator } = this.props.form;
const isGroup = this.props.isGroup()
const moduleName = !isGroup? "普通作业":"分组作业";
const moduleEngName = this.props.getModuleName()
let{
title_value, contentFileList, answerFileList, max_num, min_num, base_on_project,
init_max_num, init_min_num,
title_num, course_name, category, has_commit, has_project
}=this.state
const { current_user } = this.props
const isGroup = this.props.isGroup()
const moduleName = !isGroup? "普通作业":"分组作业";
const moduleEngName = this.props.getModuleName()
let{
course_name, category
}=this.state
const { current_user } = this.props
const courseId = this.state.course_id || this.props.match.params.coursesId ;
const isEdit = this.isEdit;
if ((isEdit == undefined || isEdit) && !this.state.workLoaded) {
return ''
}
const uploadProps = {
width: 600,
fileList: contentFileList,
multiple: true,
// https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false,
action: `${getUploadActionUrl()}`,
onChange: this.handleContentUploadChange,
onRemove: (file) => this.onAttachmentRemove(file, 'contentFileList'),
beforeUpload: (file) => {
console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) {
this.props.showNotification('文件大小必须小于150MB!');
}
return isLt150M;
},
};
const answerUploadProps = {
width: 600,
fileList: answerFileList,
multiple: true,
// https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false,
action: `${getUrl()}/api/attachments.json`,
onChange: this.handleAnswerUploadChange,
onRemove: (file) => this.onAttachmentRemove(file, 'answerFileList'),
beforeUpload: (file) => {
console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) {
this.props.showNotification('文件大小必须小于150MB!');
}
return isLt150M;
},
};
const courseId = this.state.course_id || coursesId ;
const isEdit = this.isEdit;
return(
<div className="newMain">
<div className="educontent mt20 mb50">
{/* <p className="clearfix">
<WordsBtn style="grey" className="fl">{course_name}</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<WordsBtn style="grey" className="fl">{typeId==1 ?"普通作业":"分组作业"}</WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<span>{pageType==="new"?"新建":"编辑"}</span>
</p> */}
<CBreadcrumb items={[
{ to: current_user && current_user.first_category_url, name: this.state.course_name},
{ to: `/courses/${courseId}/${moduleEngName}/${category && category.category_id ? category.category_id : ''}`
, name: category && category.category_name },
{ name: `${ this.isEdit ? '编辑' : '新建'}` }
]}></CBreadcrumb>
const common = {
onCancel:this.onCancel,
isGroup: this.props.isGroup,
doNew: this.doNew,
doEdit: this.doEdit,
}
<p className="clearfix mt20 mb20">
<span className="fl font-24 color-grey-3">{this.isEdit ?"编辑":"新建"}{ moduleName }</span>
{/* history.goBack()
this.props.toListPage(this.props.match.params, category.category_id)}
*/}
<a href="javascript:void(0)" className="color-grey-6 fr font-16 mr2"
onClick={() => this.props.history.goBack()}>
返回
</a>
</p>
<div>
{/* onSubmit={this.handleSubmit} */}
<style>
{
`
return(
<div className="newMain">
<div className="educontent mt20 mb50">
<CBreadcrumb items={[
{ to: current_user && current_user.first_category_url, name: this.state.course_name},
{ to: `/courses/${courseId}/${moduleEngName}/${category && category.category_id ? category.category_id : ''}`
, name: category && category.category_name },
{ name: `${ this.isEdit ? '编辑' : '新建'}` }
]}></CBreadcrumb>
<p className="clearfix mt20 mb20">
<span className="fl font-24 color-grey-3">{this.isEdit ?"编辑":"新建"}{ moduleName }</span>
<a href="javascript:void(0)" className="color-grey-6 fr font-16 mr2"
onClick={() => this.props.history.goBack()}>
返回
</a>
</p>
<div>
<style>
{
`
.yslnewworkinputaddonAfter .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Form className="courseForm">
<Form.Item
label="标题"
className="AboutInputForm"
>
{getFieldDecorator('title', {
rules: [{
required: true, message: '请输入标题'
}],
})(
<Input placeholder="请输入作业标题最大限制60个字符" onInput={this.changeTitle} className="searchView yslnewworkinputaddonAfter searchViewAfter" style={{"width":"100%"}} maxLength={MAX_TITLE_LENGTH} addonAfter={`${String(title_num)}/${MAX_TITLE_LENGTH}`}/>
)}
</Form.Item>
<style>{`
.uploadBtn.ant-btn {
border: none;
color: #4CACFF;
box-shadow: none;
background: transparent;
padding: 0 6px;
}
.ant-upload-list-item:hover .ant-upload-list-item-info{
background-color:#fff;
}
.upload_1 .ant-upload-list {
width: 350px;
}
.ant-input-number {
height: 40px;
line-height: 40px;
}
.workContent.AboutInputForm.ant-form-item {
border-bottom: none;
padding-bottom: 0px !important;
}
.newWorkUpload {
padding: 0px 30px 30px 30px!important;
background: #fff;
width: 100%;
display: inline-block;
border-bottom: 1px solid #EDEDED;
}
`}</style>
{/* TpmQuestionEdit 这个没出现抖动 */}
{ <Form.Item
label="内容"
className="AboutInputForm workContent mdInForm"
>
{getFieldDecorator('description', {
rules: [{
required: true, message: '请输入作业内容和要求'
}],
})(
<TPMMDEditor ref={this.contentMdRef} placeholder="请在此输入作业内容和要求,最大限制5000个字符" mdID={'courseContentMD'} refreshTimeout={1500}
className="courseMessageMD" initValue={this.state.description}></TPMMDEditor>
)}
</Form.Item> }
<Upload {...uploadProps} className="upload_1 newWorkUpload">
<Button className="uploadBtn">
<Icon type="upload" /> 上传附件
</Button>
(单个文件150M以内)
</Upload>
{ isGroup &&
<Form.Item
label="分组设置"
className="AboutInputForm"
>
{getFieldDecorator('personNum', {
rules: [{
required: false
// required: true, message: '请输入最小人数和最大人数'
}],
})(
<div>
<p className="clearfix">
<ConditionToolTip condition={has_commit} title={'已有提交作品,人数范围只能扩大'}>
{/* max={has_commit ? init_min_num : null } */}
<InputNumber placeholder="请填写每组最小人数" min={1} className="winput-240-40" value={min_num}
onChange={this.min_num_change} style={{width:'180px'}} />
</ConditionToolTip>
<span className="ml15 mr15">~</span>
{/* min={has_commit ? init_max_num : (min_num == undefined ? 2 : min_num + 1) } */}
<ConditionToolTip condition={has_commit} title={'已有提交作品,人数范围只能扩大'}>
<InputNumber className="winput-240-40" placeholder="请填写每组最大人数" value={max_num} max={10}
onChange={this.max_num_change} style={{width:'180px'}} />
</ConditionToolTip>
<label className="color-grey-9 ml20 font-14">项目管理员角色的成员都可以提交作品提交作品时需要关联同组成员组内成员作品共享</label>
</p>
<p className="mt20">
<ConditionToolTip condition={has_commit || has_project} title={'已有关联项目或作品,不能修改'}>
<Checkbox checked={base_on_project} onChange={this.base_on_project_change}
disabled={has_project || has_commit}
>基于项目实施</Checkbox>
</ConditionToolTip>
<label className="color-grey-9 ml12 font-14">勾选后各小组必须在educoder平台创建项目教师可随时观察平台对各小组最新进展的实时统计</label>
</p>
</div>
)}
</Form.Item>
}
<Form.Item
label="参考答案"
className="AboutInputForm"
style={{"borderBottom":"none"}}
>
{getFieldDecorator('reference_answer', {
rules: [{
required: false
}],
})(
<TPMMDEditor ref={this.answerMdRef} placeholder="请在此输入作业的参考答案,最大限制5000个字符" mdID={'workAnswerMD'}
className="courseMessageMD" refreshTimeout={1500} initValue={this.state.reference_answer || ''}></TPMMDEditor>
)}
<Upload {...answerUploadProps} className="upload_1">
<Button className="uploadBtn">
<Icon type="upload" /> 上传附件
</Button>
(单个文件150M以内)
</Upload>
</Form.Item>
<Form.Item>
<div className="clearfix mt30 mb30">
{/* htmlType="submit" */}
<Button type="primary" onClick={this.handleSubmit} className="defalutSubmitbtn fl mr20">提交</Button>
<a className="defalutCancelbtn fl" onClick={() => this.props.toListPage(this.props.match.params, category.category_id)}>取消</ a>
</div>
</Form.Item>
</Form>
</div>
</div>
</div>
)
}
}
</style>
<NewWorkForm
{...this.props}
{...this.state}
{...common}
wrappedComponentRef={(ref) => {this.newWorkFormRef = ref}}
></NewWorkForm>
</div>
</div>
</div>
)
}
}
const WrappedBoardsNew = Form.create({ name: 'NewWork' })(NewWork);
export default WrappedBoardsNew;
export default NewWork;

@ -0,0 +1,523 @@
import React,{ Component } from "react";
import { Input, InputNumber, Form, Button, Checkbox, Upload, Icon, message, Modal } from "antd";
import axios from 'axios'
import '../css/busyWork.css'
import '../css/Courses.css'
import { WordsBtn, getUrl, ConditionToolTip, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll } from 'educoder'
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import CBreadcrumb from '../common/CBreadcrumb'
const confirm = Modal.confirm;
const $ = window.$
const MAX_TITLE_LENGTH = 60;
/**
需要注意的props
isGroup
*/
class NewWorkForm extends Component{
constructor(props){
super(props);
this.contentMdRef = React.createRef();
this.answerMdRef = React.createRef();
this.state={
title_value:"",
title_num: 0,
contentFileList: [],
answerFileList: [],
workLoaded: false,
base_on_project: true,
category: {},
min_num: 2,
max_num: 10,
}
}
initValue = (data) => {
if (data.isEdit) {
const contentFileList = data.attachments.map(item => {
return {
id: item.id,
uid: item.id,
name: appendFileSizeToUploadFile(item),
url: item.url,
filesize: item.filesize,
status: 'done'
}
})
const answerFileList = data.ref_attachments.map(item => {
return {
id: item.id,
uid: item.id,
name: appendFileSizeToUploadFile(item),
url: item.url,
filesize: item.filesize,
status: 'done'
}
})
this.setState({
...data,
// course_id: data.course_id,
// course_name: data.course_name,
// category: data.category,
title_num: parseInt(data.name.length),
workLoaded: true,
init_min_num: data.min_num,
init_max_num: data.max_num,
// description: data.description,
reference_answer: data.reference_answer,
contentFileList,
answerFileList,
}, () => {
setTimeout(() => {
this.contentMdRef.current.setValue(data.description || '')
this.answerMdRef.current.setValue(data.reference_answer || '')
}, 2000)
this.props.form.setFieldsValue({
title: data.name,
description: data.description || '',
reference_answer: data.reference_answer || '',
});
})
} else { // new
}
}
// 输入title
changeTitle=(e)=>{
console.log(e.target.value.length);
this.setState({
title_num: parseInt(e.target.value.length)
})
}
handleSubmit = () => {
const courseId = this.state.course_id || this.props.match.params.coursesId ;
this.props.form.validateFieldsAndScroll((err, values) => {
console.log(values)
const mdContnet = this.contentMdRef.current.getValue().trim();
console.log(mdContnet)
values.description = mdContnet;
// return;
{/* max={has_commit ? init_min_num : null } */}
{/* min={has_commit ? init_max_num : (min_num == undefined ? 2 : min_num + 1) } */}
// 已有提交作品,人数范围只能扩大
const { has_commit, max_num, init_max_num, min_num, init_min_num } = this.state;
if (!min_num) {
this.props.showNotification('最小人数不能为空');
return;
} else if (min_num < 1) {
this.props.showNotification('最小人数不能小于1');
return;
} else if (!max_num) {
this.props.showNotification('最大人数不能为空');
return;
} else if (max_num < min_num) {
this.props.showNotification('最大人数不能小于最小人数');
return;
}
if (has_commit) {
if (max_num < init_max_num || min_num > init_min_num) {
this.props.showNotification(`已有提交作品,人数范围只能扩大(原设置为:${init_min_num} - ${init_max_num})`)
return;
}
}
// const errKeys = Object.keys(err); // || errKeys.length == 1 && errKeys[0] == 'content' && mdContnet
if (!err) {
if (this.state.isEdit) {
this.doEdit(courseId, values)
} else {
this.doNew(courseId, values)
}
} else {
$("html").animate({ scrollTop: $('html').scrollTop() - 100 })
}
})
}
doEdit = (courseId, values) => {
let attachment_ids = this.state.contentFileList.map(item => {
return item.response ? item.response.id : item.id
})
let reference_attachment_ids = this.state.answerFileList.map(item => {
return item.response ? item.response.id : item.id
})
const { min_num, max_num, base_on_project, category } = this.state
const isGroup = this.props.isGroup()
const params = {
type: isGroup ? 3 : 1,
name: values.title,
description: values.description,
reference_answer: values.reference_answer,
attachment_ids,
reference_attachment_ids,
min_num,
max_num,
base_on_project
}
this.props.doEdit && this.props.doEdit(params)
}
doNew = (courseId, values) => {
let attachment_ids = this.state.contentFileList.map(item => {
return item.response ? item.response.id : item.id
})
let reference_attachment_ids = this.state.answerFileList.map(item => {
return item.response ? item.response.id : item.id
})
const isGroup = this.props.isGroup()
const { min_num, max_num, base_on_project, category } = this.state
const params = {
type: isGroup ? 3 : 1,
name: values.title,
description: values.description,
reference_answer: values.reference_answer,
attachment_ids,
reference_attachment_ids,
min_num,
max_num,
base_on_project
}
this.props.doNew && this.props.doNew(params)
}
handleContentUploadChange = (info) => {
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
let contentFileList = info.fileList;
this.setState({ contentFileList: appendFileSizeToUploadFileAll(contentFileList) });
}
}
handleAnswerUploadChange = (info) => {
if (info.file.status === 'uploading' || info.file.status === 'done' || info.file.status === 'removed') {
let answerFileList = info.fileList;
this.setState({ answerFileList: appendFileSizeToUploadFileAll(answerFileList) });
}
}
onAttachmentRemove = (file, stateName) => {
if(!file.percent || file.percent == 100){
this.props.confirm({
content: '是否确认删除?',
onOk: () => {
this.deleteAttachment(file, stateName)
},
onCancel() {
console.log('Cancel');
},
});
}
return false;
}
deleteAttachment = (file, stateName) => {
// 初次上传不能直接取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[stateName].indexOf(file);
const newFileList = state[stateName].slice();
newFileList.splice(index, 1);
return {
[stateName]: newFileList,
};
});
}
}
})
.catch(function (error) {
console.log(error);
});
}
max_num_change = (val) => {
if (val < 2) {
// this.setState({
// max_num: 2,
// })
return;
}
const { min_num } = this.state;
this.setState({
max_num: val,
min_num: val <= min_num ? val - 1 : min_num
})
}
personNumValidator = (rule, value, callback) => {
const { min_num, max_num } = this.state;
const form = this.props.form;
if (!min_num) {
callback('最小人数不能为空');
} else if (min_num < 1) {
callback('最小人数不能小于1');
} else if (!max_num) {
callback('最大人数不能为空');
} else if (max_num < min_num) {
callback('最大人数不能小于最小人数');
} else {
callback();
}
}
min_num_change = (val) => {
this.setState({ min_num: val })
}
base_on_project_change = () => {
this.setState({ base_on_project: !this.state.base_on_project })
}
componentDidMount() {
window.$('.groupSetting .ant-form-item-label > label').addClass('ant-form-item-required')
}
render(){
let {typeId,coursesId,pageType}=this.props.match.params;
const { getFieldDecorator } = this.props.form;
const isGroup = this.props.isGroup()
let{
title_value, contentFileList, answerFileList, max_num, min_num, base_on_project,
init_max_num, init_min_num,
title_num, course_name, category, has_commit, has_project,
isEdit
}=this.state
const { current_user } = this.props
const courseId = this.state.course_id || this.props.match.params.coursesId ;
if ((isEdit) && !this.state.workLoaded) {
return ''
}
const uploadProps = {
width: 600,
fileList: contentFileList,
multiple: true,
// https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false,
action: `${getUrl()}/api/attachments.json`,
onChange: this.handleContentUploadChange,
onRemove: (file) => this.onAttachmentRemove(file, 'contentFileList'),
beforeUpload: (file) => {
console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) {
this.props.showNotification('文件大小必须小于150MB!');
}
return isLt150M;
},
};
const answerUploadProps = {
width: 600,
fileList: answerFileList,
multiple: true,
// https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false,
action: `${getUrl()}/api/attachments.json`,
onChange: this.handleAnswerUploadChange,
onRemove: (file) => this.onAttachmentRemove(file, 'answerFileList'),
beforeUpload: (file) => {
console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) {
this.props.showNotification('文件大小必须小于150MB!');
}
return isLt150M;
},
};
return(
<React.Fragment>
<style>
{
`
.yslnewworkinputaddonAfter .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Form className="courseForm">
<Form.Item
label="标题"
className="AboutInputForm"
>
{getFieldDecorator('title', {
rules: [{
required: true, message: '请输入标题'
}],
})(
<Input placeholder="请输入作业标题最大限制60个字符" onInput={this.changeTitle} className="searchView yslnewworkinputaddonAfter searchViewAfter" style={{"width":"100%"}} maxLength={MAX_TITLE_LENGTH} addonAfter={`${String(title_num)}/${MAX_TITLE_LENGTH}`}/>
)}
</Form.Item>
<style>{`
.uploadBtn.ant-btn {
border: none;
color: #4CACFF;
box-shadow: none;
background: transparent;
padding: 0 6px;
}
.ant-upload-list-item:hover .ant-upload-list-item-info{
background-color:#fff;
}
.upload_1 .ant-upload-list {
width: 350px;
}
.ant-input-number {
height: 40px;
line-height: 40px;
}
.workContent.AboutInputForm.ant-form-item {
border-bottom: none;
padding-bottom: 0px !important;
}
.newWorkUpload {
padding: 0px 30px 30px 30px!important;
background: #fff;
width: 100%;
display: inline-block;
border-bottom: 1px solid #EDEDED;
}
.courseForm .AboutInputForm.clearPaddingBottom{
padding-bottom:0px!important;
}
.clearPaddingBottom .ant-form-explain{
position:absolute;
bottom:0px;
left:0px
}
.resetNewWorkUpload{
border-bottom:none!important;
}
`}</style>
{ <Form.Item
label="内容"
className="AboutInputForm workContent mdInForm"
>
{getFieldDecorator('description', {
rules: [{
required: true, message: '请输入作业内容和要求',
},{
max: 5000 , message:'最大限制5000个字符'
}],
})(
<TPMMDEditor ref={this.contentMdRef} placeholder="请在此输入作业内容和要求,最大限制5000个字符" mdID={'courseContentMD'} refreshTimeout={1500}
className="courseMessageMD" initValue={this.state.description}></TPMMDEditor>
)}
</Form.Item> }
<Upload {...uploadProps} className="upload_1 newWorkUpload">
<Button className="uploadBtn">
<Icon type="upload" /> 上传附件
</Button>
(单个文件150M以内)
</Upload>
{ isGroup &&
<Form.Item
label="分组设置"
className="AboutInputForm groupSetting"
>
{getFieldDecorator('personNum', {
rules: [{
// required: true,
// message: '人数不能为空'
// validator: this.personNumValidator
// required: true, message: '请输入最小人数和最大人数'
}],
})(
<div>
<p className="clearfix">
<ConditionToolTip condition={has_commit} title={'已有提交作品,人数范围只能扩大'}>
{/* max={has_commit ? init_min_num : null } */}
<InputNumber placeholder="请填写每组最小人数" min={1} className="winput-240-40" value={min_num}
onChange={this.min_num_change} style={{width:'180px'}} />
</ConditionToolTip>
<span className="ml15 mr15">~</span>
{/* min={has_commit ? init_max_num : (min_num == undefined ? 2 : min_num + 1) } */}
<ConditionToolTip condition={has_commit} title={'已有提交作品,人数范围只能扩大'}>
<InputNumber className="winput-240-40" placeholder="请填写每组最大人数" value={max_num} max={10}
onChange={this.max_num_change} style={{width:'180px'}} />
</ConditionToolTip>
<label className="color-grey-9 ml20 font-14">项目管理员角色的成员都可以提交作品提交作品时需要关联同组成员组内成员作品共享</label>
</p>
<p className="mt20">
<ConditionToolTip condition={has_commit || has_project} title={'已有关联项目或作品,不能修改'}>
<Checkbox checked={base_on_project} onChange={this.base_on_project_change}
disabled={has_project || has_commit}
>基于项目实施</Checkbox>
</ConditionToolTip>
<label className="color-grey-9 ml12 font-14">勾选后各小组必须在educoder平台创建项目教师可随时观察平台对各小组最新进展的实时统计</label>
</p>
</div>
)}
</Form.Item>
}
<div className="edu-back-white">
<Form.Item
label="参考答案"
className="AboutInputForm clearPaddingBottom pr"
style={{"borderBottom":"none"}}
>
{getFieldDecorator('reference_answer', {
rules: [{
max: 5000 , message:'最大限制5000个字符'
}],
})(
<TPMMDEditor ref={this.answerMdRef} placeholder="请在此输入作业的参考答案,最大限制5000个字符" mdID={'workAnswerMD'}
className="courseMessageMD" refreshTimeout={1500} initValue={this.state.reference_answer || ''}></TPMMDEditor>
)}
</Form.Item>
<Upload {...answerUploadProps} className="upload_1 newWorkUpload resetNewWorkUpload">
<Button className="uploadBtn">
<Icon type="upload" /> 上传附件
</Button>
(单个文件150M以内)
</Upload>
</div>
<Form.Item>
<div className="clearfix mt30 mb30">
{/* htmlType="submit" */}
<Button type="primary" onClick={this.handleSubmit} className="defalutSubmitbtn fl mr20">提交</Button>
<a className="defalutCancelbtn fl" onClick={() => this.props.onCancel()}>取消</ a>
</div>
</Form.Item>
</Form>
</React.Fragment>
)
}
}
const WrappedWorkForm = Form.create({ name: 'NewWorkForm' })(NewWorkForm);
export default WrappedWorkForm;

@ -1,5 +1,6 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import { WordsBtn,on, off, trigger,MarkdownToHtml,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
@ -13,6 +14,9 @@ import {
import './completetaskdetails.css';
import GroupPackage from "../groupjobbank/GroupPackage";
import GroupPackage2 from "../groupjobbank/GroupPackage2";
import AttachmentsList from "../../../common/components/attachment/AttachmentList";
import NoneData from '../../courses/coursesPublic/NoneData'
class Groupjobbandetails extends Component {
@ -57,20 +61,24 @@ class Groupjobbandetails extends Component {
render() {
let{datas}=this.props;
return (
<div className=" clearfix edu-back-white" ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className=" clearfix edu-back-white " ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
{
datas.description===null||datas.description==="null"||datas.description===""?
""
:
<MarkdownToHtml content={datas.description} selector="work_content" className="mb10 yslquesHeigth"></MarkdownToHtml>
}
<div className="mt24">
{datas.attachments === undefined || datas.attachments === null || datas.attachments === ""? "" :
<AttachmentsList {...this.state} {...this.props} attachments={datas.attachments} ></AttachmentsList>}
<GroupPackage2 datas={datas} bool={false}></GroupPackage2>
</div>
<GroupPackage></GroupPackage>
<GroupPackage2></GroupPackage2>
</div>

@ -1,34 +1,43 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn} from 'educoder';
import {BrowserRouter as Router,Route,Switch,Link, NavLin} from 'react-router-dom';
import {WordsBtn, ActionBtn,getImageUrl} from 'educoder';
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form } from "antd";
import axios from 'axios';
import {
notification
} from "antd";
import CoursesListType from '../coursesPublic/CoursesListType';
import Completetaskdetails from './Completetaskdetails';
import BanksMenu from '../../user/usersInfo/banks/banksMenu'
import Loadable from 'react-loadable';
import Loading from '../../../Loading';
import '../css/members.css';
import "../common/formCommon.css";
import '../css/Courses.css';
import '../css/busyWork.css';
import '../poll/pollStyle.css';
const Completetaskdetails = Loadable({
loader: () => import('./Completetaskdetails'),
loading: Loading,
})
class Completetaskpage extends Component {
//分组作业内容详情
constructor(props) {
super(props);
// this.answerMdRef = React.createRef();
this.setState({
this.state={
workid:1,
isSpin:false,
datas:[],
})
visible:false,
banksMenu:undefined
}
}
componentDidMount() {
// console.log("父组件加载框");
this.getonedata();
}
getonedata(){
if( this.props.match.params.workid){
this.setState({
workid: this.props.match.params.workid,
@ -47,14 +56,41 @@ class Completetaskpage extends Component {
this.setState({
isSpin:true,
})
let url = `/homework_banks/${workids}.json`;
let url = `/task_banks/${workids}.json`;
//
axios.get(url).then((response) => {
if(response){
if(response.data){
this.setState({
datas:response.data.informs,
})
datas:response.data,
});
try {
const crumbData={
title:response && response.data && response.data.name,
is_public:response && response.data && response.data.is_public,
crumbArray:[
{content:'详情'}
]
};
const menuData={
tab:'0',//tab选中的index
menuArray:[//tab以及tab路由
{to:`/banks/gtask/${workids}/${this.props.match.params.type}?tab=0`,content:'内容详情'},
],
category:'gtask',//毕设选题
tos:`/banks/gtask/${workids}/edit/${this.props.match.params.type}`,
id:workids,
is_public:response && response.data && response.data.is_public,
type:this.props.match.params.type,
authorize:response && response.data && response.data.authorize,
}
this.setState({
banksMenu:menuData
})
this.props.initPublic(crumbData);
}catch (e) {
}
}else {
this.setState({
datas:[],
@ -79,60 +115,35 @@ class Completetaskpage extends Component {
})
});
}
bindRef = ref => { this.child = ref }
///////////////教师截止
render() {
const isAdmin = this.props.isAdmin();
// console.log(119)
let {datas} = this.state;
let{
banksMenu
}=this.state;
return (
<div className="newMain clearfix ">
<div className={"educontent mt10 mb20"} style={{width: "1200px"}}>
<div className="educontent mb20">
<p className="clearfix mb20 mt10">
<a className="btn colorgrey fl hovercolorblue ">题库</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<a
className=" btn colorgrey fl hovercolorblue "
>详情</a>
</p>
</div>
<div className="educontent mb20">
<p className=" fl color-black summaryname" style={{heigth: "33px"}}>
MySQL数据库编程开发实训基础篇
</p>
<CoursesListType
typelist={["公开"]}
/>
</div>
<div className="edu-back-white ">
<div className="stud-class-set bor-bottom-greyE ">
<div className=" clearfix edu-back-white poll_list">
<a className={"active ml12"}>内容详情</a>
<a className="fr color-blue font-16" >发送</a>
<a className="fr color-blue font-16" >编辑</a>
<a className="fr color-blue font-16" >删除</a>
</div>
</div>
</div>
<Completetaskdetails/>
<React.Fragment>
<div className="pd30">
{
banksMenu &&
<BanksMenu
banksMenu={banksMenu}
{...this.props}
{...this.state}
></BanksMenu>
}
<Switch {...this.props}>
<Route path={`/banks/gtask/:workid/${this.props.match.params.type}`}
render={
(props) => {
return (<Completetaskdetails {...this.props} {...props} {...this.state} datas={datas} />)
}
}></Route>
</Switch>
</div>
</div>
</React.Fragment>
)
}
}
export default Completetaskpage;

@ -1,16 +1,18 @@
.yslquestionbank1{
padding-top: 30px !important;
padding-right: 30px !important;
padding-left: 30px !important;
min-height: 500px !important;
}
.yslquesHeigth{
min-height: 500px !important;
width: 100% !important;
}
.yslquesmarkdowntext{
font-size: 16px;
color: #707070;
}
.yslquesmat26{
margin-top: 26px;
@ -56,3 +58,12 @@
color: #666666;
font-size: 14px;
}
.pad20{
padding-bottom: 20px !important;
}
.mt24{
margin-top: 24px !important ;
}
.pd30{
margin-bottom: 30px;
}

@ -1,29 +1,32 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn} from 'educoder';
import {BrowserRouter as Router,Route,Switch,Link, NavLin} from 'react-router-dom';
import {WordsBtn, ActionBtn,getImageUrl} from 'educoder';
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form } from "antd";
import axios from 'axios';
import {
notification
} from "antd";
import CoursesListType from '../coursesPublic/CoursesListType';
import Completetopicdetails from './Completetopicdetails';
import BanksMenu from '../../user/usersInfo/banks/banksMenu'
import Loadable from 'react-loadable';
import Loading from '../../../Loading';
import '../css/members.css';
import "../common/formCommon.css";
import '../css/Courses.css';
import '../css/busyWork.css';
import '../poll/pollStyle.css';
const Completetopicdetails = Loadable({
loader: () => import('./Completetopicdetails'),
loading: Loading,
})
class CompletetopicdePage extends Component {
//毕设选题内容详情
constructor(props) {
super(props);
// this.answerMdRef = React.createRef();
this.setState({
this.state={
workid:1,
isSpin:false,
datas:[],
})
visible:false,
banksMenu:undefined
}
}
@ -48,14 +51,41 @@ class CompletetopicdePage extends Component {
this.setState({
isSpin:true,
})
let url = `/homework_banks/${workids}.json`;
let url = `/gtopic_banks/${workids}.json`;
//
axios.get(url).then((response) => {
if(response){
if(response.data){
this.setState({
datas:response.data.informs,
})
datas:response.data,
});
try {
const crumbData={
title:response && response.data && response.data.name,
is_public:response && response.data && response.data.is_public,
crumbArray:[
{content:'详情'}
]
}
const menuData={
tab:'0',//tab选中的index
menuArray:[//tab以及tab路由
{to:`/banks/gtopic/${workids}/${this.props.match.params.type}?tab=0`,content:'内容详情'},
],
category:'gtopic',//毕设选题
tos:`/banks/gtopic/${workids}/edit/${this.props.match.params.type}`,
id:workids,
is_public:response && response.data && response.data.is_public,
type:this.props.match.params.type,
authorize:response && response.data && response.data.authorize,
}
this.setState({
banksMenu:menuData
})
this.props.initPublic(crumbData);
}catch (e) {
}
}else {
this.setState({
datas:[],
@ -81,58 +111,37 @@ class CompletetopicdePage extends Component {
});
}
/// 确认是否下载
bindRef = ref => { this.child = ref }
///////////////教师截止
render() {
let {tab,datas,visible} = this.state;
const isAdmin = this.props.isAdmin();
// console.log(119)
let{
banksMenu
}=this.state
//
// const common={
// initPublic:this.initPublic,
// }
return (
<div className="newMain clearfix ">
<div className={"educontent mt10 mb20"} style={{width: "1200px"}}>
<div className="educontent mb20">
<p className="clearfix mb20 mt10">
<a className="btn colorgrey fl hovercolorblue ">题库</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<a
className=" btn colorgrey fl hovercolorblue "
>详情</a>
</p>
</div>
<div className="educontent mb20">
<p className=" fl color-black summaryname" style={{heigth: "33px"}}>
MySQL数据库编程开发实训基础篇
</p>
<CoursesListType
typelist={["公开"]}
/>
</div>
<div className="edu-back-white ">
<div className="stud-class-set bor-bottom-greyE ">
<div className=" clearfix edu-back-white poll_list">
<a className="active ml12" >内容详情</a>
<a className="fr color-blue font-16" >发送</a>
<a className="fr color-blue font-16" >编辑</a>
<a className="fr color-blue font-16" >删除</a>
</div>
</div>
</div>
<Completetopicdetails/>
{/*{parseInt(tab) === 1 ? <Completetopicdeswer/>:""}*/}
<React.Fragment>
<div className="pd30">
{
banksMenu &&
<BanksMenu
banksMenu={banksMenu}
{...this.props}
{...this.state}
></BanksMenu>
}
<Switch {...this.props}>
<Route path={`/banks/gtopic/:workid/${this.props.match.params.type}`}
render={
(props) => {
return (<Completetopicdetails {...this.props} {...props} {...this.state} datas={datas} />)
}
}></Route>
</Switch>
</div>
</div>
</React.Fragment>
)
}
}

@ -1,5 +1,5 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import { WordsBtn,on, off, trigger,MarkdownToHtml,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
@ -12,6 +12,8 @@ import {
} from "antd";
import GroupPackage from '../groupjobbank/GroupPackage'
import './completetopicde.css';
import AttachmentsList from "../../../common/components/attachment/AttachmentList";
import NoneData from '../../courses/coursesPublic/NoneData'
class Completetopicdetails extends Component {
@ -56,52 +58,81 @@ class Completetopicdetails extends Component {
render() {
let{datas}=this.props;
return (
<div className=" clearfix edu-back-white " ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="bor-bottom-greyE">
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
<GroupPackage></GroupPackage>
{
datas.description===null?
""
:datas.description==="null"?
""
:
datas.description===""?
""
:
<MarkdownToHtml content={datas.description} selector="work_content" className="mb10 yslquesHeigth"></MarkdownToHtml>
}
{datas.attachment_list === undefined ?
(datas.description===undefined || datas.description===null||datas.description===""?
<NoneData></NoneData>
:
""
)
:
datas.attachment_list === null ?
(datas.description===undefined || datas.description===null||datas.description===""?
<NoneData></NoneData>
:
""
)
:
datas.attachment_list.length === 0 ?
(datas.description===undefined || datas.description===null||datas.description===""?
<NoneData></NoneData>
:
""
)
:
<div className="mb29px">
<AttachmentsList {...this.state} {...this.props} attachments={datas.attachment_list} ></AttachmentsList>
</div>
}
</div>
</div>
<div style={{width:"100%", padding: "36px"}}>
<div className="yslboomdivs">
<p>
<span className="yslboomdivsy">课题类型</span>
<span className="yslboomdivsys">设计</span>
<span className="yslboomdivsys">{datas&&datas.topic_type===1?"设计":datas&&datas.topic_type===2?"论文":datas&&datas.topic_type===3?"创作":"无"}</span>
</p>
<p>
<span className="yslboomdivsy">课题来源</span>
<span className="yslboomdivsys">生产/社会实践</span>
<span className="yslboomdivsys">{datas&&datas.topic_source===1?"生产/社会实际":datas&&datas.topic_source===2?"结合科研":datas&&datas.topic_source===3?"其它":"无"}</span>
</p>
<p>
<span className="yslboomdivsy">课题性质1</span>
<span className="yslboomdivsys">设计</span>
<span className="yslboomdivsys">{datas&&datas.topic_property_first===1?"真题":datas&&datas.topic_property_first===2?"模拟题":"无"}</span>
</p>
<p>
<span className="yslboomdivsy">课题性质2</span>
<span className="yslboomdivsys">设计</span>
<span className="yslboomdivsys">{datas&&datas.topic_property_second===1?"纵向课题":datas&&datas.topic_property_second===2?"横向课题":datas&&datas.topic_property_second===3?"自选":"无"}</span>
</p>
</div>
<div className="yslboomdivs">
<div className="yslboomdivs mt7">
<p>
<span className="yslboomdivsy">课题重复情况 </span>
<span className="yslboomdivsys">新需求</span>
<span className="yslboomdivsys">{datas&&datas.topic_repeat===1?"新题":datas&&datas.topic_repeat===2?"往届题,有新要求":datas&&datas.topic_repeat===3?"往届题,无新要求":"无"}</span>
</p>
<p>
<span className="yslboomdivsy">调研或实习地点</span>
<span className="yslboomdivsys">长沙</span>
<span className="yslboomdivsys">{datas&&datas.province}{datas&&datas.city}</span>
</p>
<p style={{width:"564px"}}>
<span className="yslboomdivsy">课题单位来源</span>
<span className="yslboomdivsys">湖南省据C++创始人Stroustrup有限公司</span>
<span className="yslboomdivsys">{datas&&datas.source_unit===undefined?"无":datas&&datas.source_unit===null?"无":datas&&datas.source_unit===""?"无":datas&&datas.source_unit==="null"?"无":datas.source_unit}</span>
</p>
</div>
</div>

@ -2,10 +2,10 @@
padding-top: 30px !important;
padding-right: 30px !important;
padding-left: 30px !important;
min-height: 500px !important;
}
.yslquesHeigth{
min-height: 500px !important;
width: 100% !important;
}
.yslquesmarkdowntext{
font-size: 16px;
@ -56,3 +56,10 @@
color: #666666;
font-size: 14px;
}
.mb29px{
padding-top: 14px !important;
margin-bottom: 29px !important;
}
.pd30{
margin-bottom: 30px;
}

@ -94,7 +94,6 @@ class AppraiseModal extends Component{
width: 48px;
height: 16px;
font-size: 16px;
font-family: PingFangSC;
font-weight: 400;
color: rgba(5,16,26,1);
line-height: 16px;
@ -102,7 +101,6 @@ class AppraiseModal extends Component{
.newfont{
height: 16px;
font-size: 16px;
font-family: PingFangSC;
font-weight: 400;
color: rgba(5,16,26,1);
line-height: 16px;

@ -37,7 +37,7 @@ class ShixunChooseModal extends Component{
hometypepvisible:loading
})
let coursesId=this.props.match.params.coursesId;
let url ="/courses/"+coursesId+"/homework_commons/shixuns.json";
let url = this.props.shixunsUrl || "/courses/"+coursesId+"/homework_commons/shixuns.json";
axios.get(url, {
params: {
@ -76,7 +76,7 @@ class ShixunChooseModal extends Component{
})
let coursesId=this.props.match.params.coursesId;
let url ="/courses/"+coursesId+"/homework_commons/shixuns.json";
let url = this.props.shixunsUrl || "/courses/"+coursesId+"/homework_commons/shixuns.json";
axios.get(url).then((result)=>{
if(result.status===200){

@ -25,7 +25,7 @@ class ShixunModal extends Component{
hometypepvisible:true,
})
let coursesId=this.props.match.params.coursesId;
let url ="/courses/"+coursesId+"/homework_commons/shixuns.json";
let url = this.props.shixunsUrl || "/courses/"+coursesId+"/homework_commons/shixuns.json";
axios.get(url).then((result)=>{
if(result.status===200){
@ -51,7 +51,7 @@ class ShixunModal extends Component{
hometypepvisible:loading
})
let coursesId=this.props.match.params.coursesId;
let url ="/courses/"+coursesId+"/homework_commons/shixuns.json";
let url = this.props.shixunsUrl || "/courses/"+coursesId+"/homework_commons/shixuns.json";
axios.get(url, {
params: {

@ -1220,6 +1220,28 @@ samp {
color: #FE4F4C;
}
/* 毕设任务 */
.graduationTaskMenu a{
display: block;
position: relative;
line-height: 72px;
font-size: 16px;
margin-right: 30px;
float: left;
}
.graduationTaskMenu a.active:after{
position: absolute;
left: 0px;
height: 2px;
width: 100%;
content: '';
background: #4CACFF;
bottom: 0px;
font-weight:400;
}
.graduationTaskMenu a.active{
color: #4CACFF!important;
}
/* end */
/* form表单包含多个item时 */

@ -359,23 +359,23 @@ class Elearning extends Component{
{/*简介*/}
<div className="clearfix pl30 pr30" style={{paddingBottom:"22px"}}>
<div style={{textAlign: "left",marginTop:"10px",paddingBottom: "10px"}}>
<span className=" color-dark-21 " style={{textAlign: "center",fontSize:"19px"}}>简介</span>
</div>
<div className="edu-back-white new_li editormd-html-preview " >
<p className="markdown-body fonttext " dangerouslySetInnerHTML={{__html: markdownToHTML(description).replace(/▁/g,"▁▁▁")}}>
</p>
</div>
{/*<div className="clearfix pl30 pr30" style={{paddingBottom:"22px"}}>*/}
{/* <div style={{textAlign: "left",marginTop:"10px",paddingBottom: "10px"}}>*/}
{/* <span className=" color-dark-21 " style={{textAlign: "center",fontSize:"19px"}}>简介</span>*/}
{/* </div>*/}
{/* <div className="edu-back-white new_li editormd-html-preview " >*/}
{/* <p className="markdown-body fonttext " dangerouslySetInnerHTML={{__html: markdownToHTML(description).replace(/▁/g,"▁▁▁")}}>*/}
{/* </p>*/}
{/* </div>*/}
</div>
{/*</div>*/}
</div>
<Spin size="large" spinning={isSpin} id={"cdiv"}>
<div className=" clearfix" style={{marginTop:"20px"}}>
<div className=" clearfix" style={this.props.isAdmin()===true?{marginTop:"0px"}:{marginTop:"20px"}}>
{
stages===undefined||stages===JSON.stringify("[]")||stages.length===0?
<NoneData></NoneData>

@ -338,7 +338,8 @@ class Exercise extends Component{
checkBoxValues:[],
Modalstypeloding:false
})
this.InitList(type,StudentList_value,page,limit)
this.InitList(type,StudentList_value,page,limit);
this.props.updataleftNavfun();
}
}).catch((error)=>{
console.log(error);

@ -53,11 +53,15 @@ class ExerciseDisplay extends Component{
componentDidMount = () => {
const Id = this.props.match.params.Id
if (Id) {
const url = `/exercises/${Id}.json`
const url = `/${this.props.urlPath || 'exercises'}/${Id}.json`
axios.get(url)
.then((response) => {
if (response.data.status == 0) {
this.setState({...response.data})
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.props.detailFetchCallback && this.props.detailFetchCallback(response);
}
})
.catch(function (error) {

@ -5,440 +5,63 @@ import {
Slider, Button, Upload, Icon, Rate, Checkbox, message,
Row, Col, Select, Modal, Tooltip
} from 'antd';
import { Q_TYPE_SINGLE, Q_TYPE_MULTI, Q_TYPE_JUDGE, Q_TYPE_NULL, Q_TYPE_MAIN, Q_TYPE_SHIXUN } from './new/common'
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import axios from 'axios'
// import './board.css'
import "../common/formCommon.css"
// import "../common/formCommon.css"
// import { RouteHOC } from './common.js'
import CBreadcrumb from '../common/CBreadcrumb'
import {getUrl, 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 { Q_TYPE_SINGLE, Q_TYPE_MULTI, Q_TYPE_JUDGE, Q_TYPE_NULL, Q_TYPE_MAIN, Q_TYPE_SHIXUN } from './new/common'
// import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
// import CBreadcrumb from '../common/CBreadcrumb'
import {getUrl, ActionBtn, CBreadcrumb} 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 ShixunChooseModal from '../coursesPublic/ShixunChooseModal'
import update from 'immutability-helper'
import './new/common.css'
import '../css/Courses.css'
import ExerciseNewCommon from './ExerciseNewCommon'
const { TextArea } = Input;
const confirm = Modal.confirm;
const $ = window.$
const { Option } = Select;
const TITLE_MAX_LENGTH = 60;
class ExerciceNew extends Component{
constructor(props){
super(props);
this.state = {
exercise_questions: [],
exercise_name: '',
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 = !!Id
if (Id) {
const url = `/exercises/${Id}/edit.json`
axios.get(url)
.then((response) => {
if (response.data.status == 0) {
const { exercise, ...others } = response.data
this.setState({
...exercise,
...others,
editMode: false
})
}
})
.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()
}
handleSubmit = (e) => {
}
onSaveExercise = () => {
const { exercise_name, exercise_description } = this.state;
const exercise_id = this.props.match.params.Id
const courseId = this.props.match.params.coursesId
if (this.isEdit) {
const editUrl = `/exercises/${exercise_id}.json`
axios.put(editUrl, {
exercise_name,
exercise_description
})
.then((response) => {
if (response.data.status == 0) {
this.setState({editMode: false})
this.props.showNotification('试卷编辑成功')
}
})
.catch(function (error) {
console.log(error);
});
} else {
const url = `/courses/${courseId}/exercises.json`
axios.post(url, {
exercise_name,
exercise_description
})
.then((response) => {
if (response.data.status == 0) {
this.setState({editMode: false})
this.props.showNotification('试卷新建成功')
const exercise_id = response.data.data.exercise_id;
this.isEdit = true;
this.props.history.replace(`/courses/${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;
// 拉取实训items
this.addEditingQuestion(Q_TYPE_SHIXUN, question_id_to_insert_after, {
shixun_id: 50
})
}
editQestion = (index) => {
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 = `/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 = `/exercise_questions/${question_id}.json`
axios.delete(url)
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('删除成功')
this.fetchExercise()
// const { exercise_questions } = this.state
// const index = this.findIndexById(question_id)
// this.setState(
// (prevState) => ({
// exercise_questions : update(prevState.exercise_questions, {$splice: [[index, 1]]})
// })
// )
}
})
.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(`/courses/${courseId}/exercises/${exercise_id}/student_exercise_list?tab=2`)
initData = (data) => {
this.setState({left_banner_id: data.left_banner_id})
}
render() {
let { exercise_name, exercise_description, course_id, exercise_types,
exercise_questions, left_banner_id } = this.state;
// if (this.isEdit && !exercise_types) {
// return ''
// }
// const { getFieldDecorator } = this.props.form;
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} = exercise_types;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
// sm: { span: 8 },
sm: { span: 24 },
},
wrapperCol: {
xs: { span: 24 },
// sm: { span: 16 },
sm: { span: 24 },
},
};
let { left_banner_id } = this.state;
const { current_user } = this.props
const isAdmin = this.props.isAdmin()
const courseId=this.props.match.params.coursesId;
const exercise_id = this.props.match.params.Id
const isEdit = this.isEdit
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
}
return(
<div className="newMain exerciseNew">
<ShixunChooseModal
ref="shixunChooseModal"
chooseShixun={this.chooseShixun}
{...this.props}
singleChoose={true}
></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>
<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 : ''},
@ -455,160 +78,12 @@ class ExerciceNew extends Component{
</a>
</p>
{!this.state.editMode && <div className="padding20-30" style={{ background: '#fff'}}>
<div className="displayTitle font-16">
<span>{exercise_name}</span>
<a className="fr mr6" onClick={() => { this.setState({editMode: true}) }} style={{ lineHeight: '32px'}}>
<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 && <Form {...formItemLayout} onSubmit={this.handleSubmit}>
<div className="formBlock" style={{paddingBottom: '2px',borderBottom:"none"}}>
<Form.Item
label="试卷标题"
required
className="topicTitle "
>
{/* {getFieldDecorator('subject', {
rules: [{
required: true, message: '请输入标题',
}, {
max: 20, message: '最大限制为20个字符',
}],
})( */}
<style>
{
`
.exercicenewinputysl .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Input placeholder={`请输入试卷标题,最大限制${TITLE_MAX_LENGTH}个字符`} maxLength={TITLE_MAX_LENGTH} className="mt5 exercicenewinputysl" value={exercise_name}
onChange={this.exercise_name_change} addonAfter={`${exercise_name ? exercise_name.length : 0}/${TITLE_MAX_LENGTH}`}
/>
{/* )} */}
</Form.Item>
<Form.Item
label="&nbsp;&nbsp;试卷须知"
>
{/* {getFieldDecorator('select_board_id', {
// initialValue: '3779',
})( */}
<TextArea placeholder="请在此输入本次试卷答题的相关说明最大限制100个字符" className="mt5" style={{height:"120px"}} value={exercise_description}
onChange={this.exercise_description_change}
/>
{/* )} */}
</Form.Item>
<Form.Item>
{/* defalutSubmitbtn */}
<a className="task-btn task-btn-orange fr mt4" style={{height: '30px', width: '70px'}}
onClick={this.onSaveExercise}
>保存</a>
{ this.isEdit && <a onClick={() => this.setState({editMode: false})} className="defalutCancelbtn fr mt4"
style={{height: '30px', width: '70px', fontSize: '14px', lineHeight: '30px', marginRight: '16px'}}>取消</a>}
{/* <Button type="primary" onClick={this.onSaveExercise} className="fr">保存</Button> */}
</Form.Item>
</div>
{/* <div className="clearfix mt30 mb30">
<a className="defalutCancelbtn fl" onClick={() => {}}>取消</ a>
</div> */}
</Form>}
<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> }
</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 {...this.props} {...item} index={index} {...commonHandler}></SingleEditor>
} else {
return <SingleDisplay {...this.props} {...item} index={index} {...commonHandler}
displayCount={exercise_questions.length}
></SingleDisplay>
}
} else if (item.question_type == 2) {
if (item.isNew) {
return <JudgeEditor {...this.props} {...item} index={index} {...commonHandler}></JudgeEditor>
} else {
return <JudgeDisplay {...this.props} {...item} index={index} {...commonHandler} ></JudgeDisplay>
}
} else if (item.question_type == 3) {
if (item.isNew) {
return <NullEditor {...this.props} {...item} index={index} {...commonHandler}></NullEditor>
} else {
return <NullDisplay {...this.props} {...item} index={index} {...commonHandler} ></NullDisplay>
}
} else if (item.question_type == 4) {
if (item.isNew) {
return <MainEditor {...this.props} {...item} index={index} {...commonHandler} ></MainEditor>
} else {
return <MainDisplay {...this.props} {...item} index={index} {...commonHandler} ></MainDisplay>
}
} else if (item.question_type == 5) {
if (item.isNew) {
return <ShixunEditor {...this.props} {...item} index={index} {...commonHandler}
chooseShixunSuccess={this.chooseShixunSuccess}
></ShixunEditor>
} else {
return <ShixunDisplay {...this.props} {...item} index={index} {...commonHandler} ></ShixunDisplay>
}
}
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 && <ActionBtn style="blue" className="fr" onClick={() => this.goToPreview()}>
{/* <i className="iconfont icon-tianjiafangda color-white font-14 mr5" style={{ marginTop: '-1px', display: 'inline-block'}}></i> */}
试卷预览
</ActionBtn>}
</div>}
</div>
<ExerciseNewCommon
{...this.props}
{...this.state}
isEdit={this.isEdit}
initData={this.initData}
></ExerciseNewCommon>
</div>
</div>
)

@ -0,0 +1,623 @@
import React,{ Component } from "react";
import {
Form, Input, InputNumber, Switch, Radio,
Slider, Button, Upload, Icon, Rate, Checkbox, message,
Row, Col, Select, Modal, Tooltip
} from 'antd';
import { Q_TYPE_SINGLE, Q_TYPE_MULTI, Q_TYPE_JUDGE, Q_TYPE_NULL, Q_TYPE_MAIN, Q_TYPE_SHIXUN } from './new/common'
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import axios from 'axios'
// import './board.css'
import "../common/formCommon.css"
// import { RouteHOC } from './common.js'
import CBreadcrumb from '../common/CBreadcrumb'
import {getUrl, 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 ShixunChooseModal from '../coursesPublic/ShixunChooseModal'
import update from 'immutability-helper'
import './new/common.css'
import '../css/Courses.css'
const { TextArea } = Input;
const confirm = Modal.confirm;
const $ = window.$
const { Option } = Select;
const TITLE_MAX_LENGTH = 60;
class ExerciseNewCommon extends Component{
constructor(props){
super(props);
this.state = {
exercise_questions: [],
exercise_name: '',
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
exercise.exercise_name = exercise.exercise_name || exercise.name
exercise.exercise_description = exercise.exercise_description || exercise.description
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()
}
handleSubmit = (e) => {
}
onSaveExercise = () => {
const { exercise_name, exercise_description } = this.state;
const exercise_id = this.props.match.params.Id
const courseId = this.props.match.params.coursesId
if (this.isEdit) {
// /exercise_banks/:id.json
const editUrl = `/${this.props.exercise_url ? this.props.exercise_url : 'exercises'}/${exercise_id}.json`
axios.put(editUrl, {
exercise_name,
exercise_description
})
.then((response) => {
if (response.data.status == 0) {
this.setState({editMode: false})
this.props.showNotification('试卷编辑成功')
}
})
.catch(function (error) {
console.log(error);
});
} else {
const url = `/courses/${courseId}/exercises.json`
axios.post(url, {
exercise_name,
exercise_description
})
.then((response) => {
if (response.data.status == 0) {
this.setState({editMode: false})
this.props.showNotification('试卷新建成功')
const exercise_id = response.data.data.exercise_id;
this.isEdit = true;
this.props.history.replace(`/courses/${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;
// 拉取实训items
this.addEditingQuestion(Q_TYPE_SHIXUN, question_id_to_insert_after, {
shixun_id: 50
})
}
editQestion = (index) => {
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()
// const { exercise_questions } = this.state
// const index = this.findIndexById(question_id)
// this.setState(
// (prevState) => ({
// exercise_questions : update(prevState.exercise_questions, {$splice: [[index, 1]]})
// })
// )
}
})
.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(`/courses/${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;
}
render() {
let { exercise_name, exercise_description, course_id, exercise_types,
exercise_questions, left_banner_id } = this.state;
// if (this.isEdit && !exercise_types) {
// return ''
// }
// const { getFieldDecorator } = this.props.form;
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} = exercise_types;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
// sm: { span: 8 },
sm: { span: 24 },
},
wrapperCol: {
xs: { span: 24 },
// sm: { span: 16 },
sm: { span: 24 },
},
};
const { current_user } = this.props
const isAdmin = this.props.isAdmin()
const courseId=this.props.match.params.coursesId;
const exercise_id = this.props.match.params.Id
const isEdit = this.isEdit
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 className="padding20-30" style={{ background: '#fff'}}>
<div className="displayTitle font-16">
<span>{exercise_name}</span>
<a className="fr mr6" onClick={() => { this.setState({editMode: true}) }} style={{ lineHeight: '32px'}}>
<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 && <Form {...formItemLayout} onSubmit={this.handleSubmit}>
<div className="formBlock" style={{paddingBottom: '2px',borderBottom:"none"}}>
<Form.Item
label="试卷标题"
required
className="topicTitle "
>
{/* {getFieldDecorator('subject', {
rules: [{
required: true, message: '请输入标题',
}, {
max: 20, message: '最大限制为20个字符',
}],
})( */}
<style>
{
`
.exercicenewinputysl .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Input placeholder={`请输入试卷标题,最大限制${TITLE_MAX_LENGTH}个字符`} maxLength={TITLE_MAX_LENGTH} className="mt5 exercicenewinputysl" value={exercise_name}
onChange={this.exercise_name_change} addonAfter={`${exercise_name ? exercise_name.length : 0}/${TITLE_MAX_LENGTH}`}
/>
{/* )} */}
</Form.Item>
<Form.Item
label="&nbsp;&nbsp;试卷须知"
>
{/* {getFieldDecorator('select_board_id', {
// initialValue: '3779',
})( */}
<TextArea placeholder="请在此输入本次试卷答题的相关说明最大限制100个字符" className="mt5" style={{height:"120px"}} value={exercise_description}
onChange={this.exercise_description_change}
/>
{/* )} */}
</Form.Item>
<Form.Item>
{/* defalutSubmitbtn */}
<a className="task-btn task-btn-orange fr mt4" style={{height: '30px', width: '70px'}}
onClick={this.onSaveExercise}
>保存</a>
{ this.isEdit && <a onClick={() => this.setState({editMode: false})} className="defalutCancelbtn fr mt4"
style={{height: '30px', width: '70px', fontSize: '14px', lineHeight: '30px', marginRight: '16px'}}>取消</a>}
{/* <Button type="primary" onClick={this.onSaveExercise} className="fr">保存</Button> */}
</Form.Item>
</div>
{/* <div className="clearfix mt30 mb30">
<a className="defalutCancelbtn fl" onClick={() => {}}>取消</ a>
</div> */}
</Form>}
<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> }
</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 {...this.props} {...item} index={index} {...commonHandler}></SingleEditor>
} else {
return <SingleDisplay {...this.props} {...item} index={index} {...commonHandler}
displayCount={exercise_questions.length}
></SingleDisplay>
}
} else if (item.question_type == 2) {
if (item.isNew) {
return <JudgeEditor {...this.props} {...item} index={index} {...commonHandler}></JudgeEditor>
} else {
return <JudgeDisplay {...this.props} {...item} index={index} {...commonHandler} ></JudgeDisplay>
}
} else if (item.question_type == 3) {
if (item.isNew) {
return <NullEditor {...this.props} {...item} index={index} {...commonHandler}></NullEditor>
} else {
return <NullDisplay {...this.props} {...item} index={index} {...commonHandler} ></NullDisplay>
}
} else if (item.question_type == 4) {
if (item.isNew) {
return <MainEditor {...this.props} {...item} index={index} {...commonHandler} ></MainEditor>
} else {
return <MainDisplay {...this.props} {...item} index={index} {...commonHandler} ></MainDisplay>
}
} else if (item.question_type == 5) {
if (item.isNew) {
return <ShixunEditor {...this.props} {...item} index={index} {...commonHandler}
chooseShixunSuccess={this.chooseShixunSuccess}
></ShixunEditor>
} else {
return <ShixunDisplay {...this.props} {...item} index={index} {...commonHandler} ></ShixunDisplay>
}
}
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()}>
{/* <i className="iconfont icon-tianjiafangda color-white font-14 mr5" style={{ marginTop: '-1px', display: 'inline-block'}}></i> */}
试卷预览
</ActionBtn>}
{this.props.bottomSection && this.props.bottomSection}
</div>}
</div>
</React.Fragment>
)
}
}
// RouteHOC()
export default (ExerciseNewCommon);

@ -38,7 +38,6 @@ class ExerciseReviewAndAnswer extends Component{
super(props);
this.state={
data:undefined,
userName:undefined,
questionPanelFixed:false,
e_ReviewInfo:undefined,
e_AnswerInfo:undefined,
@ -166,7 +165,6 @@ class ExerciseReviewAndAnswer extends Component{
getInfo=()=>{
this.setState({
courseName:this.props.current_user.course_name,
userName:this.props.current_user.username,
isSpin:true
})
@ -493,7 +491,6 @@ class ExerciseReviewAndAnswer extends Component{
let{
data,
questionPanelFixed,
userName,
courseName,
exercise,
exercise_types,

@ -86,7 +86,7 @@ class JudgeDisplay extends Component{
// 单选
return (
<div key={optionIndex} className="fl mr30 df">
<Radio disabled checked={item.standard_boolean}></Radio>
<Radio disabled className="lineh-25" checked={item.standard_boolean}></Radio>
{/* <span>{item.choice_text}</span> */}
<MarkdownToHtml content={item.choice_text} selector={'judge_' + (index + 1) + optionIndex}
className=""

@ -85,7 +85,7 @@ class SingleEditor extends Component{
}*/
const Id = this.props.match.params.Id
if (question_id) {
const editUrl = `/exercise_questions/${question_id}.json`
const editUrl = this.props.getEditQuestionUrl(question_id);
axios.put(editUrl, {
question_title,
question_type: 2,
@ -105,9 +105,10 @@ class SingleEditor extends Component{
console.log(error);
});
} else {
const url = `/exercises/${Id}/exercise_questions.json`
const url = this.props.getAddQuestionUrl();
axios.post(url, {
exercise_bank_id: Id,
question_title,
question_type: 2,
question_score,

@ -70,7 +70,7 @@ class MainEditor extends Component{
}*/
const Id = this.props.match.params.Id
if (question_id) {
const editUrl = `/exercise_questions/${question_id}.json`
const editUrl = this.props.getEditQuestionUrl(question_id);
axios.put(editUrl, {
question_title,
question_type: 4,
@ -88,9 +88,10 @@ class MainEditor extends Component{
console.log(error);
});
} else {
const url = `/exercises/${Id}/exercise_questions.json`
const url = this.props.getAddQuestionUrl();
axios.post(url, {
exercise_bank_id: Id,
question_title,
question_type: 4,
question_score,

@ -92,6 +92,9 @@ class NullDisplay extends Component{
.answerRow {
padding: 1px 0;
}
.answers .markdown-body > p{
line-height:20px;
}
`}</style>
<QestionDisplayHeader {...this.props}></QestionDisplayHeader>

@ -124,7 +124,7 @@ class NullEditor extends Component{
}*/
const Id = this.props.match.params.Id
if (question_id) {
const editUrl = `/exercise_questions/${question_id}.json`
const editUrl = this.props.getEditQuestionUrl(question_id);
axios.put(editUrl, {
question_title,
question_type: 3,
@ -145,9 +145,10 @@ class NullEditor extends Component{
console.log(error);
});
} else {
const url = `/exercises/${Id}/exercise_questions.json`
const url = this.props.getAddQuestionUrl();
axios.post(url, {
exercise_bank_id: Id,
question_title,
question_type: 3,
question_score,

@ -113,7 +113,7 @@ class ShixunEditor extends Component{
}*/
const Id = this.props.match.params.Id
if (question_id) {
const editUrl = `/exercise_questions/${question_id}.json`
const editUrl = this.props.getEditQuestionUrl(question_id);
axios.put(editUrl, {
question_title,
question_type: 5,
@ -131,9 +131,10 @@ class ShixunEditor extends Component{
console.log(error);
});
} else {
const url = `/exercises/${Id}/exercise_questions.json`
const url = this.props.getAddQuestionUrl();
axios.post(url, {
exercise_bank_id: Id,
question_title,
question_type: 5,
question_scores,
@ -155,10 +156,10 @@ class ShixunEditor extends Component{
this.props.onEditorCancel()
}
componentDidMount = () => {
const { shixun_id } = this.props;
const { shixun_id, exercise_url } = this.props;
// shixun_id
const Id = this.props.match.params.Id
const url = `/exercises/${Id}/commit_shixun.json`
const url = `/${exercise_url || 'exercises'}/${Id}/commit_shixun.json`
axios.get(url, {
params: {
shixun_id

@ -99,7 +99,7 @@ class SingleDisplay extends Component{
if (question_type == 0) { // 单选
return (
<div className="mb10 clearfix" key={optionIndex}>
<Radio disabled className="fl lineh-20" checked={item.standard_boolean}>{prefix}</Radio>
<Radio disabled className="fl lineh-25" checked={item.standard_boolean}>{prefix}</Radio>
<MarkdownToHtml content={item.choice_text} selector={'single_' + (index + 1) + '' + (optionIndex + 1)} style={{ float: 'left', display: 'inline-block' }}
></MarkdownToHtml>
@ -110,7 +110,7 @@ class SingleDisplay extends Component{
return (
<div className="mb10 clearfix" key={optionIndex}>
<Checkbox disabled className="fl lineh-20" checked={item.standard_boolean}>{prefix}</Checkbox>
<Checkbox disabled className="fl lineh-25 mr8" checked={item.standard_boolean}>{prefix}</Checkbox>
<MarkdownToHtml content={item.choice_text} selector={'single_' + (index + 1)+ '' + (optionIndex + 1)} style={{ float: 'left', display: 'inline-block' }}
></MarkdownToHtml>

@ -123,7 +123,7 @@ class SingleEditor extends Component{
}*/
const Id = this.props.match.params.Id
if (question_id) {
const editUrl = `/exercise_questions/${question_id}.json`
const editUrl = this.props.getEditQuestionUrl(question_id);
axios.put(editUrl, {
question_title,
question_type: answerArray.length > 1 ? 1 : 0,
@ -143,9 +143,10 @@ class SingleEditor extends Component{
console.log(error);
});
} else {
const url = `/exercises/${Id}/exercise_questions.json`
const url = this.props.getAddQuestionUrl();
axios.post(url, {
exercise_bank_id: Id,
question_title,
question_type: answerArray.length > 1 ? 1 : 0,
question_score,

@ -215,14 +215,14 @@ class GraduateTaskItem extends Component{
<h6>
{
this.props.isAdmin?<a href={"/courses/"+coursesId+"/graduation_tasks/"+categoryid+"/"+taskid+"/list"}
this.props.isAdmin?<Link to={"/courses/"+coursesId+"/graduation_tasks/"+categoryid+"/"+taskid+"/list"}
title={discussMessage.name}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.name}</a>:""
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.name}</Link>:""
}
{
this.props.isStudent? <a href={"/courses/"+coursesId+"/graduation_tasks/"+categoryid+"/"+taskid+"/list"}
this.props.isStudent? <Link to={"/courses/"+coursesId+"/graduation_tasks/"+categoryid+"/"+taskid+"/list"}
title={discussMessage.name}
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.name}</a>:""
className="fl mt3 font-16 font-bd color-dark maxwidth580">{discussMessage.name}</Link>:""
}
{

@ -0,0 +1,449 @@
import React, { Component } from 'react';
import {Link} from 'react-router-dom';
import {Tooltip,Menu} from 'antd';
import Loadable from 'react-loadable';
import Loading from '../../../../Loading';
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
import axios from 'axios';
import HomeworkModal from "../../coursesPublic/HomeworkModal";
import AccessoryModal from "../../coursesPublic/AccessoryModal";
import Associationmodel from '../../coursesPublic/Associationmodel';
import CoursesListType from '../../coursesPublic/CoursesListType';
import moment from 'moment';
import "../../css/members.css"
import "../../css/Courses.css"
import Modals from '../../../modals/Modals';
//毕设描述
const GraduationTasksquestions= Loadable({
loader: () => import('./GraduationTaskssettingquestions'),
loading: Loading,
})
//毕设任务设置
const GraduationTaskssetting=Loadable({
loader: () => import('./GraduationTaskssetting'),
loading: Loading,
})
//毕设任务列表
const GraduationTaskslist=Loadable({
loader: () => import('./GraduationTaskssettinglist'),
loading: Loading,
})
class GraduationTaskDetail extends Component{
constructor(props){
super(props);
this.state={
modalname:undefined,
visible:false,
Topval:undefined,
starttime:undefined,
starttimes:undefined,
typs:undefined,
endtime:undefined,
Cancelname:undefined,
Savesname:undefined,
Cancel:undefined,
Saves:undefined,
Topvalright:undefined,
Botvalleft:undefined,
course_groupslist:undefined,
course_groups:undefined,
questionslist:undefined,
tab:"list",
visibles:undefined,
Modalstype:undefined,
Modalstopval:undefined,
ModalCancel:undefined,
ModalSave:undefined
}
}
componentDidMount(){
this.getdatas()
}
getdatas=()=>{
const task_Id = this.props.match.params.task_Id;
let url="/graduation_tasks/"+task_Id+".json";
axios.get(url).then((result)=>{
if(result.status===200){
this.setState({
questionslist:result.data
})
}
}).catch((error)=>{
console.log(error)
})
}
//返回
goback=()=>{
// let courseId=this.props.match.params.coursesId;
// let category_id=this.props.match.params.category_id;
// window.location.href="/courses/"+courseId+"/graduation_tasks/"+category_id;
// let courseId = this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
// this.props.history.goBack()
this.props.history.replace(`/courses/${this.state.questionslist.course_id}/graduation_tasks/${this.state.questionslist.graduation_id}`);
}
//立即发布
publish=()=>{
let starttime= this.props.getNowFormatDates(1,1);
let endtime=this.props.getNowFormatDates(2,1);
// this.homeworkstart()
this.setState({
modalname:"立即发布",
visible:true,
Topval:"学生将立即收到毕设任务",
// Botvalleft:"点击修改",
// Botval:`本操作只对"未发布"的分班有效`,
starttime:moment(moment(new Date())).format("YYYY-MM-DD HH:mm") ,
starttimes:this.props.getNowFormatDates(1),
typs:"start",
endtime:endtime,
Cancelname:"暂不发布",
Savesname:"立即发布",
Cancel:this.cancelmodel,
Saves:this.homepublish,
})
}
// 确定立即发布
homepublish=(ids,endtime)=>{
this.cancelmodel();
let task_Id=this.props.match.params.task_Id;
const cid = this.props.match.params.coursesId;
// let url = `/courses/${cid}/graduation_tasks/publish_task.json`;
let url="/courses/"+cid+"/graduation_tasks/publish_task.json"
axios.post(url,{
task_ids:[task_Id],
group_ids: this.state.course_groupslist,
end_time:endtime,
}).then((response)=>{
if (response.data.status == 0) {
this.getdatas()
this.props.showNotification(response.data.message);
this.setState({
// Modalstopval:response.data.message,
// ModalSave:this.cancelmodel,
// Loadtype:true,
course_groupslist:[],
checkAllValue:false
})
}
}).catch((error)=>{
})
}
// 刷新
resetList=()=>{
this.getdatas();
this.child && this.child.searchValue();
}
// 立即截止
end=()=>{
// this.homeworkstart()
this.setState({
modalname:"立即截止",
visible:true,
Topval:"学生将不能再提交作品",
// Botvalleft:"暂不截止",
// Botval:`本操作只对"提交中"的分班有效`,
Cancelname:"暂不截止",
Savesname:"立即截止",
Cancel:this.cancelmodel,
Saves:this.coursetaskend,
typs:"end",
})
}
// 取消
cancelmodel=()=>{
this.setState({
Modalstype:false,
Loadtype:false,
visible:false,
Modulationtype:false,
Allocationtype:false,
Modalstopval:"",
ModalCancel:"",
ModalSave:"",
})
}
getcourse_groupslist=(id)=>{
this.setState({
course_groupslist:id
})
}
setTab = (tab) =>{
this.setState({
tab
})
}
// 关联项目
AssociationItems=()=>{
this.setState({
visibles:true
})
}
Cancel=()=>{
this.setState({
visibles:false
})
}
// 取消关联
cannelAssociation=()=>{
this.setState({
Modalstype:true,
Modalstopval:"确定要取消该项目关联?",
ModalCancel:this.cannerassocition,
ModalSave:this.savetassociton
})
}
savetassociton=()=>{
this.cannerassocition();
let {questionslist}=this.state;
let url = "/graduation_tasks/"+questionslist.task_id+"/graduation_works/cancel_relate_project.json";
console.log(url)
axios.get(url).then((result)=>{
if(result.data.status===0){
this.resetList();
}
}).catch((error)=>{
console.log(error)
})
}
cannerassocition=()=>{
this.setState({
Modalstype:false,
Modalstopval:"",
ModalCancel:"",
ModalSave:"",
loadtype:false,
visibles:false
})
}
// 补交附件
handaccessory=()=>{
// let {taskslistdata}=this.state;
// let courseId=this.props.match.params.coursesId;
//
// let url="/courses/"+courseId+"/graduation_tasks/"+taskslistdata.work_id+"/appraise"
//
// window.location.href=url;
this.setState({
avisible:true
})
}
Cancelvisible=()=>{
this.setState({
avisible:false
})
}
bindRef = ref => { this.child = ref } ;
render(){
let courseId=this.props.match.params.coursesId;
let category_id=this.props.match.params.category_id;
let task_Id=this.props.match.params.task_Id;
let {
questionslist ,
tab ,
visibles ,
Modalstype,
Modalstopval,
ModalCancel,
ModalSave
} = this.state
const commom = {
setTab:this.setTab
}
return(
<div className="newMain clearfix">
{
questionslist &&
<div className={"educontent mb20"}>
<HomeworkModal
starttimes={this.state.starttimes}
typs={this.state.typs}
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}
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}
modaltype={this.state.modaltype}
getcourse_groupslist={(id) => this.getcourse_groupslist(id)}
/>
{/*关联项目*/}
{visibles===true?
<Associationmodel
modalname={"关联项目"}
visible={visibles}
Cancel={()=>this.Cancel()}
taskid={ questionslist && questionslist.task_id }
funlist={this.resetList}
/>
:""}
{this.state.avisible===true?<AccessoryModal
{...this.props}
modalname={"补交附件"}
visible={this.state.avisible}
Cancelname={"取消"}
Savesname={"确认"}
Cancel={this.Cancelvisible}
categoryid={questionslist.work_id}
setupdate={this.resetList}
/>:""}
{/*提示*/}
<Modals
modalsType={Modalstype}
modalsTopval={Modalstopval}
modalCancel={ModalCancel}
modalSave={ModalSave}
closable={false}
footer={null}
destroyOnClose={true}
centered={true}
/>
<p className="clearfix mt10">
<a onClick={this.goback} className="color-grey-9 fl">{questionslist.course_name}</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<Link to={`/courses/${courseId}/graduation_tasks/${category_id}`} className="color-grey-9 fl">{questionslist.graduation_name}</Link>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<span className="color-grey-6">任务详情</span>
</p>
<div className="clearfix mt20 mb20 lineh-25 linbox">
<p className=" fl color-black summaryname">
<Link to={`/courses/${courseId}/graduation_tasks/${category_id}`} className="color-grey-3">{questionslist.task_name}</Link>
</p>
<CoursesListType
typelist={questionslist.task_status}
/>
<a className="color-grey-3 fr font-16 ml30 mr20" onClick={this.goback}>返回</a>
</div>
<div className="stud-class-set bor-bottom-greyE">
<div className="clearfix edu-back-white pl30 pr30 graduationTaskMenu">
<Link className={tab && tab == "list" ? "active" : ""} to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/list"}>任务列表</Link>
<Link className={tab && tab == "questions" ? "active" : ""} to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/questions"}>毕设描述</Link>
<Link className={tab && tab == "setting" ? "active" : ""} to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/setting?tab=3"}>设置</Link>
{/*<a className={"fr color-blue font-16"}>导出成绩</a>*/}
{/*{this.props.isAdmin()?<a href={"/api/graduation_tasks/"+task_Id+"/tasks_list.xls"} className={"fr color-blue font-16"}>导出成绩</a>:""}*/}
{/*{this.props.isAdmin()?<a href={"/api/graduation_tasks/"+task_Id+"/tasks_list.zip"} className={"fr color-blue font-16"}>导出作品附件</a>:""}*/}
<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;
}
.drop_down_menu li .color-dark{
color: #666 !important;
}
.linbox{
height: 26px;
}
`}
</style>
{this.props.isAdmin()? <li className="li_line drop_down fr color-blue font-16 mt20" 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("/graduation_tasks/"+task_Id+"/tasks_list.xlsx")} className="color-dark">导出成绩</a></li>
<li><a onClick={()=>this.confirmysl("/graduation_tasks/"+task_Id+"/tasks_list.zip")} className="color-dark">导出作品附件</a></li>
</ul>
</li>:""}
{questionslist.work_status===undefined||questionslist.work_status===null||questionslist.work_status.length===0?"":questionslist.work_status.map((item,key)=>{
return(
<span key={key}>
{item==="提交作品"?<a className={"fr color-blue font-16"} href={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/works/new"}>提交作品</a>:""}
{item==="补交作品"?<a className={"fr color-blue font-16"} href={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/works/new"}>补交作品</a>:""}
{item==="修改作品"?<a className={"fr color-blue font-16"} href={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+questionslist.work_id+"/works/edit"}>修改作品</a>:""}
{item==="查看作品"?<a className={"fr color-blue font-16"} href={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+questionslist.work_id+"/works/edit"}>查看作品</a> :""}
{item==="创建项目"?<a className={"fr color-blue font-16"} href={'/projects/new'} target="_blank">创建项目</a>:""}
{item==="关联项目"?<a className={"fr color-blue font-16"} onClick={this.AssociationItems}>关联项目</a>:""}
{item==="取消关联"?<a className={"fr color-blue font-16"} onClick={this.cannelAssociation}>取消关联</a>:""}
{item==="补交附件"?<a className={"fr color-blue font-16"} onClick={this.handaccessory}>补交附件</a>:""}
</span>
)
})}
{/*<a className={"fr color-blue font-16"}>项目在线质量检测</a>*/}
{ this.props.isAdmin() ? questionslist.status===1 ? <a className={"fr color-blue font-16 mr20"} onClick={() => { this.end()} }>立即截止</a> : "" : "" }
{ this.props.isAdmin() ? questionslist.status===0 ? <a className={"fr color-blue font-16 mr20"} onClick={() => { this.publish()} }>立即发布</a> : "" : "" }
{ this.props.isAdmin() ? <a className={"fr color-blue font-16"} href={"/courses/"+courseId+"/graduation_tasks/"+task_Id+"/edit"}>编辑任务</a> : "" }
</div>
</div>
<Switch {...this.props}>
<Route exact path="/courses/:coursesId/graduation_tasks/:category_id/:task_Id/list"
render={
(props) => (<GraduationTaskslist {...this.props} {...props} {...this.state} {...commom} triggerRef={this.bindRef} tab={`list`}/>)
}
></Route>
<Route exact path="/courses/:coursesId/graduation_tasks/:category_id/:task_Id/setting"
render={
(props) => (<GraduationTaskssetting {...this.props} {...props} {...this.state} {...commom} tab={`setting`}/>)
}
></Route>
<Route exact path="/courses/:coursesId/graduation_tasks/:category_id/:task_Id/questions"
render={
(props) => (<GraduationTasksquestions {...this.props} {...props} {...this.state} {...commom} tab={`questions`}/>)
}></Route>
</Switch>
</div>
}
</div>
)
}
}
// CNotificationHOC() ( SnackbarHOC() ( TPMIndexHOC))
export default (GraduationTaskDetail) ;

@ -290,6 +290,13 @@ class GraduationTasksedit extends Component{
shixunsreplace:false,
})
}
checkContent = (rule, value, callback) => {
if(value.length>5000){
callback('最大限制为5000个字符');
}else{
callback();
}
}
render(){
const { getFieldDecorator } = this.props.form;
let {title_num,pageType,name,description,Loadtype,attachments,fileList,
@ -437,9 +444,9 @@ class GraduationTasksedit extends Component{
>
{getFieldDecorator('description', {
rules: [{
required: true, message: '请输入帖子内容',
}, {
max: 10000, message: '最大限制为10000个字符',
required: true, message: '请输入内容',
},{
max:5000,message:'最大限制5000个字符'
}],
})(
<TPMMDEditor ref={this.mdRef} placeholder={'请输入任务内容说明最大限制5000个字符'} {...this.state} {...this.props}

@ -266,6 +266,18 @@ class GraduationTasksnew extends Component {
})
}
checkContent = (rule, value, callback) => {
if (value == "") {
callback('请输入内容');
}else if(value.length>5000){
callback('最大限制为5000个字符');
}else{
callback();
}
}
render() {
const {getFieldDecorator} = this.props.form;
let {
@ -448,9 +460,9 @@ class GraduationTasksnew extends Component {
{getFieldDecorator('description', {
rules: [{
required: true, message: '请输入内容',
}, {
max: 5000, message: '最大限制为5000个字符',
}],
},{
max:5000,message:'最大限制5000个字符'
}]
})(
<TPMMDEditor ref={this.mdRef} placeholder={'请输入任务内容说明最大限制5000个字符'}
mdID={'courseMessageMD'} className="courseMessageMD"></TPMMDEditor>

@ -50,6 +50,7 @@ class GraduationTaskssettingapp extends Component{
baseonproject:false,
minnum:2,
maxnum:5,
firstTimes:true,
publish_time:null,
end_time:null,
allowlate:1,
@ -114,6 +115,7 @@ class GraduationTaskssettingapp extends Component{
max_nums: result.data.max_num,
task_type: result.data.task_type,
baseonproject: result.data.base_on_project,
firstTimes:!result.data.publish_time && !result.data.end_time,
publish_time:result.data.publish_time===null||result.data.publish_time=== ""?"":moment(moment(handleDateString(result.data.publish_time))).format("YYYY-MM-DD HH:mm"),
end_time:result.data.end_time===null||result.data.end_time=== ""?"":moment(moment(handleDateString(result.data.end_time))).format("YYYY-MM-DD HH:mm"),
allowlate: result.data.allow_late,
@ -149,7 +151,11 @@ class GraduationTaskssettingapp extends Component{
this.getsettings();
if(this.props.isAdmin()===true&&isNaN(id)){
this.editSetting()
}
}
let tab = this.props.tab;
this.props.setTab && this.props.setTab(tab);
}
@ -199,41 +205,43 @@ class GraduationTaskssettingapp extends Component{
maxnum:parseInt(e.target.value)
})
}
}
}
onChangeTimepublish= (date, dateString) => {
let endtime;
if(date===null){
this.setState({
publish_time:null,
end_time:null,
latetime:null
})
}else{
endtime= moment(moment(handleDateString(dateString))).add(1, 'months').format("YYYY-MM-DD HH:mm")
let {allowlate}=this.state;
if(allowlate===true||allowlate===1){
this.setState({
publish_time:moment(moment(handleDateString(dateString))).format("YYYY-MM-DD HH:mm"),
end_time:endtime,
latetime:moment(moment(handleDateString(endtime))).add(1, 'months').format("YYYY-MM-DD HH:mm"),
})
}else{
this.setState({
publish_time:moment(moment(handleDateString(dateString))).format("YYYY-MM-DD HH:mm"),
end_time:endtime
})
}
}
let endtime;
if(date===null){
this.setState({
publish_time:null,
end_time:null,
latetime:null
})
}else{
let { firstTimes } = this.state;
// 判断是否是第一次设置
this.setState({
publish_time:moment(moment(handleDateString(dateString))).format("YYYY-MM-DD HH:mm"),
publishTimetypes:false
})
if(firstTimes){
endtime= moment(moment(handleDateString(dateString))).add(1, 'months').format("YYYY-MM-DD HH:mm")
let {allowlate}=this.state;
this.setState({
firstTimes:undefined
})
if(allowlate===true||allowlate===1){
this.setState({
end_time:endtime,
latetime:moment(moment(handleDateString(endtime))).add(1, 'months').format("YYYY-MM-DD HH:mm"),
})
}else{
this.setState({
end_time:endtime
})
}
}
}
}
@ -245,21 +253,24 @@ class GraduationTaskssettingapp extends Component{
latetime:null
})
}else{
let {allowlate}=this.state;
if(allowlate===true||allowlate===1){
this.setState({
end_time:moment(moment(handleDateString(dateString))).format("YYYY-MM-DD HH:mm"),
latetime:moment(moment(handleDateString(dateString))).add(1, 'months').format("YYYY-MM-DD HH:mm"),
})
}else{
let { firstTimes } = this.state;
this.setState({
end_time:moment(moment(handleDateString(dateString))).format("YYYY-MM-DD HH:mm"),
endTimetypes:false
})
// 判断是否是第一次设置
if(firstTimes){
this.setState({
end_time:moment(moment(handleDateString(dateString))).format("YYYY-MM-DD HH:mm"),
firstTimes:undefined
})
let {allowlate}=this.state;
if(allowlate===true||allowlate===1){
this.setState({
latetime:moment(moment(handleDateString(dateString))).add(1, 'months').format("YYYY-MM-DD HH:mm"),
})
}
}
}
}
onChangeTimelatetime=(date, dateString)=>{
@ -399,46 +410,6 @@ class GraduationTaskssettingapp extends Component{
opergrade:e.target.checked
})
}
//立即发布
publish=()=>{
let starttime= this.props.getNowFormatDates(1,1);
let endtime=this.props.getNowFormatDates(2,1);
// this.homeworkstart()
this.setState({
modalname:"立即发布",
visibles:true,
Topval:"学生将立即收到毕设任务",
// Botvalleft:"点击修改",
// Botval:`本操作只对"未发布"的分班有效`,
starttime:moment(moment(new Date())).format("YYYY-MM-DD HH:mm") ,
starttimes:this.props.getNowFormatDates(1),
typs:"start",
endtime:endtime,
Cancelname:"暂不发布",
Savesname:"立即发布",
Cancel:this.cancelmodel,
Saves:this.homepublish,
})
}
//立即发布
homeworkstart=()=>{
let coursesId=this.props.match.params.coursesId;
let url="/courses/"+coursesId+"/all_course_groups.json";
axios.get(url).then((response) => {
if(response.status===200){
this.setState({
modaltype:response.data.course_groups===null||response.data.course_groups.length===0?2:1,
course_groups:response.data.course_groups,
})
}
}).catch((error) => {
console.log(error)
});
}
homepublish=(ids,endtime)=>{
let task_Id=this.props.match.params.task_Id;
@ -764,43 +735,12 @@ class GraduationTaskssettingapp extends Component{
})
}
goback=()=>{
// let courseId=this.props.match.params.coursesId;
// if(courseId===undefined){
// this.props.history.push("/courses");
// }else{
// this.props.history.push(this.props.current_user.first_category_url);
// }
// this.props.history.goBack()
// this.props.history.replace(this.props.current_user.first_category_url);
this.props.history.replace(`/courses/${this.state.settingdata.course_id}/graduation_tasks/${this.state.settingdata.graduation_id}`);
}
isgoback=()=>{
this.getsettings();
this.setState({
flagPageEdit: false,
})
}
end=()=>{
this.setState({
modalname:"立即截止",
visibles:true,
Topval:"学生将不能再提交作品",
// Botvalleft:"暂不截止",
// Botval:`本操作只对"提交中"的分班有效`,
Cancelname:"暂不截止",
Savesname:"立即截止",
Cancel:this.cancelmodel,
Saves:this.coursetaskend,
typs:"end",
})
// this.homeworkstart()
}
cancelmodel=()=>{
this.setState({
@ -989,7 +929,7 @@ class GraduationTaskssettingapp extends Component{
return(
<React.Fragment>
{settingdata&&settingdata? <div>
{ settingdata && settingdata ? <div>
{/*提示*/}
<Modals
modalsType={Modalstype}
@ -998,24 +938,6 @@ class GraduationTaskssettingapp extends Component{
modalSave={ModalSave}
loadtype={Loadtype}
/>
{/*/!*立即发布*!/*/}
{/*<PublishModals*/}
{/*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}*/}
{/*skipTop={this.skipTop}*/}
{/*/>*/}
<DownloadMessageysl
{...this.props}
value={this.state.DownloadMessageval}
@ -1049,97 +971,8 @@ class GraduationTaskssettingapp extends Component{
.ant-input{
height:40px;
}
.linbox{
height: 26px;
}
`
}</style>
<div className="newMain clearfix">
<div className={"educontent mb20"}>
<p className="clearfix mt10">
<a onClick={this.goback} className="color-grey-9 fl">{coursename}</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<Link to={"/courses/"+courseId+"/graduation_tasks/"+settingdata.graduation_id} className="color-grey-9 fl">毕设任务</Link>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
{/*{taskname===""?"":*/}
{/*<WordsBtn style="grey" className="fl">*/}
{/*<Link to={"/courses/"+courseId+"/graduation"+"/graduation_tasks/"} className="color-grey-6">{taskname}</Link>*/}
{/*<span className="color-grey-c ml3 mr3">&gt;</span>*/}
{/*</WordsBtn>*/}
{/*}*/}
<span className="color-grey-6">任务详情</span>
</p>
<div className="clearfix mt20 mb20 lineh-25 linbox">
<p className=" fl color-black lineh-25 summaryname">
<Link to={"/courses/"+courseId+"/graduation"+"/graduation_tasks/"} className="color-grey-3">{taskname}</Link>
</p>
<CoursesListType
typelist={task_status}
/>
<a className="color-grey-3 fr font-16 ml30 mr20" onClick={this.goback}>返回</a>
</div>
<div className="stud-class-set bor-bottom-greyE" id={"publishtimestart"}>
<div className="mt10 clearfix edu-back-white poll_list pl20" id={"publishtimeend"}>
<Link to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/list"}>任务列表</Link>
<Link to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/questions"}>毕设描述</Link>
<Link className="active"
style={{paddingLeft:'38px'}}
to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/setting?tab=3"}>设置</Link>
{/*<a className={"fr color-blue font-16"}>导出</a>*/}
<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;
}
.drop_down_menu li .color-dark{
color: #666 !important;
}
`}
</style>
{this.props.isAdmin()? <li className="li_line drop_down fr color-blue font-16 mr20 mt20" 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("/graduation_tasks/"+task_Id+"/tasks_list.xlsx")} className="color-dark">导出成绩</a></li>
<li><a onClick={()=>this.confirmysl("/graduation_tasks/"+task_Id+"/tasks_list.zip")} className="color-dark">导出作品附件</a></li>
</ul>
</li>:""}
{/*{this.props.isAdmin()?<a href={"/api/graduation_tasks/"+task_Id+"/tasks_list.xls"} className={"fr color-blue font-16"}>导出成绩</a>:""}*/}
{/*{this.props.isAdmin()?<a href={"/api/graduation_tasks/"+task_Id+"/tasks_list.zip"} className={"fr color-blue font-16"}>导出作品附件</a>:""}*/}
{/*<a className={"fr color-blue font-16"}>项目在线质量检测</a>*/}
{this.props.isAdmin()?settingdata.status===1?<a className={"fr color-blue font-16 mr20"} onClick={() => { this.end()} }>立即截止</a>:"":""}
{this.props.isAdmin()?settingdata.status===0?<a className={"fr color-blue font-16 mr20"} onClick={() => { this.publish()} }>立即发布</a>:"":""}
{this.props.isAdmin()?<a className={"fr color-blue font-16"} href={"/courses/"+courseId+"/graduation_tasks/"+task_Id+"/edit"}>编辑任务</a>:""}
</div>
</div>
<Form id={"starttime"}>
{
!flagPageEdit && this.props.isAdmin() === true ?
@ -1175,7 +1008,7 @@ class GraduationTaskssettingapp extends Component{
<div className={"h20 mb30 ml30"} >
<div className={"ml30"} >
<span>发布时间</span>
<Tooltip placement="bottom" title={this.props.isAdmin()===true?starttimetype===true?"时间已过,不能再修改":"":""}>
<span>
@ -1213,7 +1046,7 @@ class GraduationTaskssettingapp extends Component{
{this.state.publishTimetypesval}
</div>:""}
<div className={"h20 mb30 ml30"} >
<div className={"mt10 ml30"} >
<span>截止时间</span>
<Tooltip placement="bottom" title={this.props.isSuperAdmin()===true?"":this.props.isAdmin()===true?endtimetype===true?"时间已过,不能再修改":"":""}>
<span>
@ -1306,11 +1139,6 @@ class GraduationTaskssettingapp extends Component{
</div>
{/*<div className="stud-class-set bor-bottom-greyE pd20 edu-back-white pl36">*/}
{/*<div className={" font-16 color-dark h20 mb20"}>项目质量检测 </div>*/}
{/*</div>*/}
<div className="stud-class-set bor-bottom-greyE pd20 edu-back-white pl36">
<div className={" font-16 color-dark h20 mb20"}>评分设置 </div>
@ -1437,14 +1265,8 @@ class GraduationTaskssettingapp extends Component{
{/*<Link to={"/courses/"+courseId+"/graduation_tasks/"+position+"/"+category_id+coursesearch} className="defalutCancelbtn fl">取消</Link>*/}
<a onClick={this.isgoback} className="defalutCancelbtn fl">取消</a>
</div>:"":""}
</div>
</div>
</div>:""}
</React.Fragment>
)

@ -1,7 +1,7 @@
import React,{Component} from "React";
import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal,Pagination, Table, Divider, Tag,Tooltip} from "antd";
import {Link} from 'react-router-dom';
import { getImageUrl,WordsBtn } from 'educoder';
import { getImageUrl , NoneData } from 'educoder';
import axios from 'axios';
import moment from 'moment';
import HomeworkModal from "../../coursesPublic/HomeworkModal";
@ -13,6 +13,7 @@ import AllocationModal from "../../coursesPublic/AllocationModal";
import Associationmodel from '../../coursesPublic/Associationmodel';
import AccessoryModal from "../../coursesPublic/AccessoryModal";
const CheckboxGroup = Checkbox.Group;
const Search = Input.Search;
const qs = require('qs');
@ -54,8 +55,18 @@ class GraduationTaskssettinglist extends Component{
}
componentDidMount(){
let tab = this.props.tab;
this.props.setTab && this.props.setTab(tab);
let{teacher_comment,task_status,course_group,cross_comment,order,b_order,search}=this.state;
this.seacthdata(teacher_comment,task_status,course_group,cross_comment,order,b_order,search,this.state.page);
try{
this.props.triggerRef(this)
}catch(e){
}
}
goback=()=>{
@ -837,36 +848,22 @@ class GraduationTaskssettinglist extends Component{
<div>
{this.props.isAdmin()?operation.map((tag,key) => {
return(
<div key={key}>
{/*<Tooltip placement="bottom" title={tag.name==="分配"?"指定该作品的交叉评阅人":tag.name==="调分"?<pre>调整学生最终成绩<br/>*/}
{/*其它历史评分将全部失效</pre>:""}>*/}
{/*{tag.name==="评阅"?tag.status===0?"--":<a style={{color:'#4CACFF'}} href={"/courses/"+courseId+"/graduation_tasks/"+tag.id+"/appraise"} >*/}
{/*{tag.name}*/}
{/*</a>*/}
{/*:*/}
{/*<a style={{color:tag.name==="调分"?"#000":'#4CACFF'}}*/}
{/*onClick={tag.name==="调分"?()=>this.showModulationtype(tag.id):tag.name==="分配"?()=>this.showAllocationModal(tag.id):""}>*/}
{/*{tag.status===0?"":tag.name}*/}
{/*</a>*/}
{/*}*/}
{/*</Tooltip>*/}
<Tooltip placement="bottom" title={tag.name==="分配"?"指定该作品的交叉评阅人":tag.name==="调分"?<pre>调整学生最终成绩<br/>
其它历史评分将全部失效</pre>:""}>
{tag.name==="评阅"?<a style={{color:'#4CACFF'}} href={"/courses/"+courseId+"/graduation_tasks/"+tag.id+"/appraise"} >
{tag.name}
</a>
:
<a style={{color:tag.name==="调分"?"#000":'#4CACFF'}}
onClick={tag.name==="调分"?()=>this.showModulationtype(tag.id):tag.name==="分配"?()=>this.showAllocationModal(tag.id):""}>
{tag.name}
</a>
}
</Tooltip>
</div>
<React.Fragment>
{
tag.name &&
<Tooltip key={key} placement="bottom" title={tag.name==="分配"?"指定该作品的交叉评阅人":tag.name==="调分"?<pre>调整学生最终成绩<br/>其它历史评分将全部失效</pre>:""}>
{tag.name==="评阅"?<a style={{color:'#4CACFF',padding:"0px 5px"}} href={"/courses/"+courseId+"/graduation_tasks/"+tag.id+"/appraise"} >
{tag.name}
</a>
:
<a style={{color:tag.name==="调分"?"#000":'#4CACFF',padding:"0px 5px"}}
onClick={tag.name==="调分"?()=>this.showModulationtype(tag.id):tag.name==="分配"?()=>this.showAllocationModal(tag.id):""}>
{tag.name}
</a>
}
</Tooltip>
}
</React.Fragment>
)
}):""}
{
@ -963,9 +960,6 @@ class GraduationTaskssettinglist extends Component{
text-overflow: ellipsis;
white-space: nowrap;
}
.linbox{
height: 26px;
}
.ant-table-tbody>tr>td, .ant-table-thead>tr>th{
padding: 16px 10px
}
@ -1090,99 +1084,12 @@ class GraduationTaskssettinglist extends Component{
/>
{taskslistdata&&taskslistdata?
{ taskslistdata && taskslistdata ?
// 教师列表
this.props.isAdmin()?<div className="newMain clearfix">
<div className={"educontent mb20"}>
<p className="clearfix mt10">
<a className="color-grey-9 fl" onClick={this.goback}>{taskslistdata.course_name}</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<Link className="color-grey-9 fl" to={"/courses/"+courseId+"/graduation_tasks/"+taskslistdata.graduation_id}>{taskslistdata.graduation_name}</Link>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<span className="color-grey-6 fl">任务详情</span>
</p>
<div className="clearfix lineh-25 mt20 mb20 linbox">
<p className=" fl color-black summaryname lineh-25 "> <Link to={"/courses/"+courseId+"/graduation_tasks/"+category_id} className="color-grey-3">{taskslistdata.task_name}</Link></p>
<CoursesListType
typelist={taskslistdata.task_status}
/>
<a className="color-grey-3 fr font-16 ml30 mr20" onClick={this.goback}>返回</a>
</div>
<div className="stud-class-set bor-bottom-greyE">
<div className="mt10 clearfix edu-back-white poll_list pl20">
{/*<a href={"/api/graduation_tasks/"+task_Id+"/tasks_list.xls"} className={"fr color-blue font-16"}>导出成绩</a>*/}
{/*<a href={"/api/graduation_tasks/"+task_Id+"/tasks_list.zip"} className={"fr color-blue font-16"}>导出作品附件</a>*/}
<Link className="active" to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/list"}>任务列表</Link>
<Link to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/questions"}>毕设描述</Link>
<Link style={{paddingLeft:'38px'}}
to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/setting?tab=3"}>设置</Link>
{/*<a className={"fr color-blue font-16"} href={"/courses/"+courseId+"/graduation_tasks/"+task_Id+"/edit"}>编辑任务</a>*/}
{/*<a className={"fr color-blue font-16"} onClick={this.end}>立即截止</a>*/}
{/*<a className={"fr color-blue font-16"}>导出作品附件</a>*/}
<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;
}
.drop_down_menu li .color-dark{
color: #666 !important;
}
`}
</style>
{this.props.isAdmin()? <li className="li_line drop_down fr color-blue font-16 mr20 mt20" 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("/graduation_tasks/"+task_Id+"/tasks_list.xlsx")} className="color-dark">学生成绩</a></li>
<li><a onClick={()=>this.confirmysl("/graduation_tasks/"+task_Id+"/tasks_list.zip")} className="color-dark">作品附件</a></li>
</ul>
</li>:""}
{/*<a className={"fr color-blue font-16"}>项目在线质量检测</a>*/}
{taskslistdata.status===1? <a className={"fr color-blue font-16 mr20"} onClick={() => { this.end()} }>立即截止</a>:""}
{taskslistdata.status===0?<a className={"fr color-blue font-16 mr20"} onClick={() => { this.publish()} }>立即发布</a>:""}
<a className={"fr color-blue font-16"} href={"/courses/"+courseId+"/graduation_tasks/"+task_Id+"/edit"}>编辑任务</a>
</div>
</div>
this.props.isAdmin() ?
<div className="stud-class-set">
<div className="clearfix edu-back-white" >
{/*提示*/}
{/*<Modals*/}
{/*modalsType={Modalstype}*/}
{/*modalsTopval={Modalstopval}*/}
{/*modalCancel={ModalCancel}*/}
{/*modalSave={ModalSave}*/}
{/*/>*/}
<ul className="clearfix" style={{padding:'20px 40px 10px 40px'}}>
<ul className="clearfix" style={{padding:'20px 30px 10px 30px'}}>
<li className="clearfix">
<span className="fl mr10 color-grey-8">教师评阅</span>
@ -1201,7 +1108,7 @@ class GraduationTaskssettinglist extends Component{
)
})}
</CheckboxGroup>
<div className="fr mr5 search-new" style={{marginBottom:'1px'}}>
<div className="fr mr5 search-new" style={{marginBottom:'1px',marginRight:"0px"}}>
<Search
placeholder="请输入姓名或学号搜索"
id="subject_search_input"
@ -1273,10 +1180,10 @@ class GraduationTaskssettinglist extends Component{
{taskslistdata.search_assistants&&taskslistdata.search_assistants.cross_comment.map((item,key)=>{
return(
<span key={key}>
<Checkbox value={item.id} className="fl" checked={parseInt(cross_comment)===item.id?true:false} onClick={this.funcross_comment}>{item.name}
<span>({item.count})</span>
</Checkbox>
</span>
<Checkbox value={item.id} className="fl" checked={parseInt(cross_comment)===item.id?true:false} onClick={this.funcross_comment}>{item.name}
<span>({item.count})</span>
</Checkbox>
</span>
)
})}
@ -1284,23 +1191,21 @@ class GraduationTaskssettinglist extends Component{
</ul>
<div id="graduation_work_list" style={{padding:'0px 40px 10px 40px'}}>
<div id="graduation_work_list" style={{padding:'0px 30px 10px 30px'}}>
<style>
{
`
{`
.edu-menu-lists li:hover {
background: #f0f0f0 !important;
}
.edu-menu-lists li:hover a{
color: #666 !important;
}
`
}
background: #f0f0f0 !important;
}
.edu-menu-lists li:hover a{
color: #666 !important;
}
`}
</style>
<div className="clearfix">
{this.props.isAdmin()===true?<span className="fl color-grey-6 font-12">
<span className="color-orange-tip">{taskslistdata&&taskslistdata.work_count}</span>
个检索结果{taskslistdata&&taskslistdata.work_count} 学生 </span>:""}
个检索结果{taskslistdata&&taskslistdata.work_count} 学生</span>:""}
{this.props.isAdmin()===true?<div className="fr color-grey-6 edu-menu-panel">
<p>
<a data-remote="true" class="color-grey-6 font-12">
@ -1339,23 +1244,17 @@ class GraduationTaskssettinglist extends Component{
{
JSON.stringify(data)==="[]" ?
<div id="forum_list" className="forum_table">
<div className="mh650 edu-back-white">
<div className="edu-tab-con-box clearfix edu-txt-center">
<img className="edu-nodata-img mb20" src={getImageUrl("images/educoder/nodata.png")}/>
<p className="edu-nodata-p mb30">暂时还没有相关数据哦</p>
</div>
</div>
</div>
<NoneData></NoneData>
:
<div className={"justify break_full_word new_li edu-back-white"} style={{minHeight: "480px"}}>
<style>{`
.ant-spin-nested-loading > div > .ant-spin .ant-spin-dot {
top: 72%;}
<style>
{`
.ant-spin-nested-loading > div > .ant-spin .ant-spin-dot {
top: 72%;
}
}
`}</style>
`}
</style>
<div className="edu-table edu-back-white ">
{data===undefined?"":<Table
dataSource={data}
@ -1385,73 +1284,15 @@ class GraduationTaskssettinglist extends Component{
: ""
}
</div>
</div>
</div>:
:
// 学生列表
this.props.isStudent()||this.props.isNotMember()?
<div className="newMain clearfix">
<div className={"educontent mb20"}>
<p className="clearfix mt10">
<WordsBtn style="grey" className="fl"> <Link to={"/courses/"+courseId+"/graduation_tasks/"+taskslistdata.graduation_id}>{taskslistdata.course_name}</Link></WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<WordsBtn style="grey" className="fl"> <Link to={"/courses/"+courseId+"/graduation_tasks/"+taskslistdata.graduation_id}className="color-grey-6">{taskslistdata.graduation_name}</Link></WordsBtn>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<span>任务详情</span>
</p>
<div style={{ width:'100%',height:'75px'}} >
<p className=" fl color-black mt25 summaryname"> <Link to={"/courses/"+courseId+"/graduation_tasks/"+category_id} className="color-grey-6">{taskslistdata.task_name}</Link></p>
<CoursesListType
typelist={taskslistdata.task_status}
typesylename={"mt22"}
/>
<a className="color-grey-6 fr font-16 ml30 mt10 mr20" onClick={this.goback}>返回</a>
</div>
<div className="stud-class-set bor-bottom-greyE">
<div className="mt10 clearfix edu-back-white poll_list pl20">
<Link className="active" to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/list"}>任务列表</Link>
<Link to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/questions"}>毕设描述</Link>
<Link style={{paddingLeft:'38px'}}
to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/setting"}>设置</Link>
{taskslistdata.work_status===undefined||taskslistdata.work_status===null||taskslistdata.work_status.length===0?"":taskslistdata.work_status.map((item,key)=>{
return(
<span key={key}>
{item==="提交作品"?<a className={"fr color-blue font-16"} href={"/courses/"+this.props.match.params.coursesId+"/graduation_tasks/"+category_id+"/"+task_Id+"/works/new"}>提交作品</a>:""}
{item==="补交作品"?<a className={"fr color-blue font-16"} href={"/courses/"+this.props.match.params.coursesId+"/graduation_tasks/"+category_id+"/"+task_Id+"/works/new"}>补交作品</a>:""}
{item==="修改作品"?<a className={"fr color-blue font-16"} href={"/courses/"+this.props.match.params.coursesId+"/graduation_tasks/"+category_id+"/"+taskslistdata.work_id+"/works/edit"}>修改作品</a>:""}
{item==="查看作品"?<a className={"fr color-blue font-16"} href={"/courses/"+this.props.match.params.coursesId+"/graduation_tasks/"+category_id+"/"+taskslistdata.work_id+"/works/edit"}>查看作品</a> :""}
{item==="创建项目"?<a className={"fr color-blue font-16"} href={'/projects/new'} target="_blank">创建项目</a>:""}
{item==="关联项目"?<a className={"fr color-blue font-16"} onClick={this.AssociationItems}>关联项目</a>:""}
{item==="取消关联"?<a className={"fr color-blue font-16"} onClick={this.cannelAssociation}>取消关联</a>:""}
{item==="补交附件"?<a className={"fr color-blue font-16"} onClick={this.handaccessory}>补交附件</a>:""}
</span>
)
})}
{/*<a className={"fr color-blue font-16"} onClick={this.handaccessory}>补交附件</a>*/}
{/*<a className={"fr color-blue font-16"} href={"/courses/"+courseId+"/graduation/graduation_tasks/"+task_Id+"/edit"}>编辑任务</a>*/}
{/*<a className={"fr color-blue font-16"}>立即截止</a>*/}
{/*<a className={"fr color-blue font-16"}>导出作品附件</a>*/}
{/*<a className={"fr color-blue font-16"}>导出成绩</a>*/}
</div>
</div>
<div className="stud-class-set ">
<div className="clearfix edu-back-white" >
{this.props.isNotMember()?<ul className="clearfix" style={{padding:'20px 40px 10px 40px'}}>
{this.props.isNotMember()?<ul className="clearfix" style={{padding:'20px 30px 10px 30px'}}>
<li className="clearfix">
<span className="fl mr10 color-grey-8">教师评阅</span>
@ -1554,7 +1395,6 @@ class GraduationTaskssettinglist extends Component{
<div id="graduation_work_list" style={{ padding: '18px 40px 10px',height: '56px'}}>
{this.props.isAdmin()===true?
<div className="clearfix">
<span className="fl color-grey-6 font-12">
@ -1576,8 +1416,6 @@ class GraduationTaskssettinglist extends Component{
</div>
</div>
:""}
{this.props.isStudent()===true?
<div className="clearfix">
<span className="mr15 color-grey9">
@ -1595,12 +1433,7 @@ class GraduationTaskssettinglist extends Component{
</Tooltip>}
</div>
:""}
</div>
{
JSON.stringify(data) === "[]" ?
@ -1652,12 +1485,6 @@ class GraduationTaskssettinglist extends Component{
: ""
}
</div>
</div>
</div>
:""
:""}

@ -32,8 +32,10 @@ class GraduationTasksquestions extends Component{
}
componentDidMount(){
let tab = this.props.tab;
this.props.setTab && this.props.setTab(tab);
this.getdatas()
this.getdatas()
}
getdatas=()=>{
const task_Id = this.props.match.params.task_Id;
@ -295,19 +297,10 @@ class GraduationTasksquestions extends Component{
modaltype={this.state.modaltype}
getcourse_groupslist={(id) => this.getcourse_groupslist(id)}
/>
<style>
{
`
.linbox{
height: 26px;
}
`
}
</style>
{questionslist&&questionslist?<div className="newMain clearfix">
<div className={"educontent mb20"}>
<p className="clearfix mt10">
{/* <p className="clearfix mt10">
<a onClick={this.goback} className="color-grey-9 fl">{questionslist.course_name}</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<Link to={"/courses/"+courseId+"/graduation_tasks/"+questionslist.graduation_id} className="color-grey-9 fl">{questionslist.graduation_name}</Link>
@ -323,22 +316,22 @@ class GraduationTasksquestions extends Component{
typelist={questionslist.task_status}
/>
<a className="color-grey-3 fr font-16 ml30 mr20" onClick={this.goback}>返回</a>
</div>
</div> */}
<div className="stud-class-set bor-bottom-greyE">
<div className="mt10 clearfix edu-back-white poll_list pl20">
{/* <div className="stud-class-set bor-bottom-greyE">
<div className="mt10 clearfix edu-back-white poll_list pl20"> */}
<Link to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/list"}>任务列表</Link>
{/* <Link to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/list"}></Link>
<Link className="active" to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/questions"}>毕设描述</Link>
<Link style={{paddingLeft:'38px'}}
to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/setting?tab=3"}>设置</Link>
to={"/courses/"+courseId+"/graduation_tasks/"+category_id+"/"+task_Id+"/setting?tab=3"}>设置</Link> */}
{/*<a className={"fr color-blue font-16"}>导出成绩</a>*/}
{/*{this.props.isAdmin()?<a href={"/api/graduation_tasks/"+task_Id+"/tasks_list.xls"} className={"fr color-blue font-16"}>导出成绩</a>:""}*/}
{/*{this.props.isAdmin()?<a href={"/api/graduation_tasks/"+task_Id+"/tasks_list.zip"} className={"fr color-blue font-16"}>导出作品附件</a>:""}*/}
<style>
{/* <style>
{ `
.drop_down_menu{
height: 118px;
@ -371,14 +364,14 @@ class GraduationTasksquestions extends Component{
<li><a onClick={()=>this.confirmysl("/graduation_tasks/"+task_Id+"/tasks_list.xlsx")} className="color-dark">导出成绩</a></li>
<li><a onClick={()=>this.confirmysl("/graduation_tasks/"+task_Id+"/tasks_list.zip")} className="color-dark">导出作品附件</a></li>
</ul>
</li>:""}
</li>:""} */}
{/*<a className={"fr color-blue font-16"}>项目在线质量检测</a>*/}
{this.props.isAdmin()?questionslist.status===1? <a className={"fr color-blue font-16 mr20"} onClick={() => { this.end()} }>立即截止</a>:"":""}
{/* {this.props.isAdmin()?questionslist.status===1? <a className={"fr color-blue font-16 mr20"} onClick={() => { this.end()} }></a>:"":""}
{this.props.isAdmin()?questionslist.status===0? <a className={"fr color-blue font-16 mr20"} onClick={() => { this.publish()} }>立即发布</a>:"":""}
{this.props.isAdmin()?<a className={"fr color-blue font-16"} href={"/courses/"+courseId+"/graduation_tasks/"+task_Id+"/edit"}>编辑任务</a>:""}
</div>
</div>
</div> */}

@ -469,7 +469,9 @@ class GraduationTasks extends Component{
checkAllValue:false
})
this.publishcanner();
this.useBankSuccess();
debugger
let {search,page,order} = this.state
this.fetchAll(search,page,order);
}
}).catch((error)=>{
@ -565,6 +567,12 @@ class GraduationTasks extends Component{
let {search,page,order,all_count} = this.state;
this.fetchAll(search,page,order,all_count)
this.setState({
checkBoxValues:object_ids
})
// 立即发布
this.publish();
}
getcourse_groupslist=(id)=>{

@ -449,7 +449,7 @@ class GraduateTopicNew extends Component{
rules: [{
required: true, message: '请输入选题简介',
}, {
max: 10000, message: '最大限制为10000个字符',
max: 5000, message: '最大限制为5000个字符',
}],
})(
<TPMMDEditor ref={this.mdRef} placeholder={'请简要说明选题内容最大限制5000个字符'}

@ -0,0 +1,520 @@
import React,{ Component } from "react";
import {
Form, Input, Button, Upload, Icon , message, Select
} from 'antd';
import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor';
import axios from 'axios'
import { City , getUploadActionUrl , appendFileSizeToUploadFileAll } from 'educoder';
const $ = window.$;
const NAME_COUNT=60;
const { Option} = Select;
class GraduateTopicNewForm extends Component{
constructor(props){
super(props);
this.mdRef = React.createRef();
this.state = {
fileList: [],
teacherList:[],
topic_property_first:[],
topic_property_second:[],
topic_repeat:[],
topic_source:[],
topic_type:[],
addonAfter:0,
cityDefaultValue:undefined
}
}
// init编辑信息
initValue=(result)=>{
this.setState({
teacherList:result.data.teacher_list,
topic_property_first:result.data.topic_property_first,
topic_property_second:result.data.topic_property_second,
topic_repeat:result.data.topic_repeat,
topic_source:result.data.topic_source,
topic_type:result.data.topic_type,
addonAfter:parseInt(result.data.selected_data.name.length)
})
this.props.form.setFieldsValue({
tea_id:result.data.selected_data.tea_id,
name:result.data.selected_data.name,
city: [result.data.selected_data.province,result.data.selected_data.city],
topic_type:result.data.selected_data.topic_type || undefined,
topic_source:result.data.selected_data.topic_source || undefined,
topic_property_first:result.data.selected_data.topic_property_first || undefined,
topic_property_second:result.data.selected_data.topic_property_second || undefined,
source_unit:result.data.selected_data.source_unit,
topic_repeat:result.data.selected_data.topic_repeat || undefined
});
this.mdRef.current.setValue(result.data.selected_data.description)
const _fileList = result.data.attachments.map(item => {
return {
id: item.id,
uid: item.id,
name: item.title,
url: item.url,
status: 'done'
}
})
this.setState({ fileList: _fileList, cityDefaultValue: [result.data.selected_data.province,result.data.selected_data.city] })
}
//init新建信息
initNewInfo=(result)=>{
this.setState({
teacherList:result.data.teacher_list,
topic_property_first:result.data.topic_property_first,
topic_property_second:result.data.topic_property_second,
topic_repeat:result.data.topic_repeat,
topic_source:result.data.topic_source,
topic_type:result.data.topic_type
})
this.props.form.setFieldsValue({
tea_id:this.props.current_user && this.props.current_user.user_id
})
}
// 附件相关 START
handleChange = (info) => {
if (info.file.status === 'done' || info.file.status === 'uploading') {
let contentFileList = info.fileList;
// this.setState({ fileList: appendFileSizeToUploadFileAll(contentFileList)});
// let list = appendFileSizeToUploadFileAll(contentFileList);
// let arr = list.map(item=>{
// return ( item.response && item.response.id )
// })
this.setState({
fileList:contentFileList
});
}
}
onAttachmentRemove = (file) => {
this.props.confirm({
content: '确定要删除这个附件吗?',
onOk: () => {
this.deleteAttachment(file)
},
onCancel() {
console.log('Cancel');
},
});
return false;
}
deleteAttachment = (file) => {
console.log(file);
let id=file.response ==undefined ? file.id : file.response.id
const url = `/attachments/${id}.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);
});
}
changeTopicName=(e)=>{
// let num= 60 - parseInt(e.target.value.length);
this.setState({
addonAfter:e.target.value.length
})
}
handleSubmit = (e) => {
e.preventDefault();
const topicId = this.props.topicId
this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) {
if (topicId !=undefined) {
// 编辑
// const editTopic = this.editTopic
let attachment_ids = undefined
if (this.state.fileList) {
attachment_ids = this.state.fileList.map(item => {
return item.response ? item.response.id : item.id
})
}
const param = {
...values,
province: values.city==undefined?"":values.city[0],
city: values.city==undefined?"":values.city[1],
}
this.props.editSave && this.props.editSave(param,attachment_ids,topicId);
} else {
// 新建
let attachment_ids = undefined
if (this.state.fileList) {
attachment_ids = this.state.fileList.map(item => {
return item.response.id
})
}
const param ={
...values,
province: values.city==undefined?"":values.city[0],
city: values.city==undefined?"":values.city[1],
}
this.props.newSubmit && this.props.newSubmit(param,attachment_ids,topicId);
}
} else {
$("html").animate({ scrollTop: $('html').scrollTop() - 100 })
}
});
}
// 附件相关 ------------ END
render(){
let{
fileList,
teacherList,
topic_property_first,
topic_property_second,
topic_repeat,
topic_source,
topic_type,
addonAfter,
cityDefaultValue
}=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 uploadProps = {
width: 600,
fileList,
multiple: true,
action: `${getUploadActionUrl()}`,
onChange: this.handleChange,
onRemove: this.onAttachmentRemove,
beforeUpload: (file) => {
const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) {
//message.error('文件大小必须小于150MB!');
this.props.define({
title:'提示',
content:"该文件无法上传。超过文件大小限制(150MB),建议上传到百度云等其它共享工具里然后再txt文档里给出链接以及共享密码并上传"
})
return isLt150M;
}
}
};
let { topicId , teacherName }=this.props;
return(
<React.Fragment>
<Form {...formItemLayout} onSubmit={this.handleSubmit}>
<div className="createPage">
{
teacherName &&
<Form.Item
label="指导老师"
>
{getFieldDecorator('tea_id', {
rules: [{
required: true, message: '请选择指导老师'
}],
})(
<Select style={{"width":"20%"}} placeholder="请选择指导老师">
{
teacherList && teacherList.map((item,key)=>{
return(
<Option value={item.id} id={key}>{item.name}</Option>
)
})
}
</Select>
)}
</Form.Item>
}
<style>
{
`
.exercicenewinputysl .ant-input{
border-right: none !important;
height: 40px !important;
}
`
}
</style>
<Form.Item
label="选题名称"
className="mt15"
>
{getFieldDecorator('name', {
rules: [{
required: true, message: '请输入选题名称',
}, {
max: 60, message: '最大限制为60个字符',
}],
})(
<Input placeholder="请输入帖子选题名称最大限制60个字符" maxLength="60" onInput={this.changeTopicName} autoComplete="off" addonAfter={`${String(addonAfter)}/${NAME_COUNT}`} className="searchViewAfter exercicenewinputysl" />
)}
</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;
margin-bottom:10px;
}
.ant-upload-list-item{
margin-top:0px!important;
}
.ant-form-item-children{
position:unset
}
.rememberTip{
position:absolute;
right:0px;
bottom:-10px;
}
.chooseDes .ant-form-explain{
position:absolute;
bottom:-10px;
left:0px;
}
.setUploadStyle .uploadBtn{
height:20px;
line-height:20px;
}
.setUploadStyle .ant-form-item-control{
margin-top:15px!important;
line-height:22px!important;
}
.setUploadStyle .ant-upload-list{
margin-top:5px;
}
`}</style>
<div className="createPage">
<Form.Item
label="选题简介"
style={{"borderBottom":'none'}}
className="chooseDes pr"
>
{getFieldDecorator('description', {
rules: [{
required: true, message: '请输入选题简介',
}, {
max: 10000, message: '最大限制为10000个字符',
}],
})(
// initValue={this.editTopic ? this.editTopic.content : ''}
<TPMMDEditor ref={this.mdRef} placeholder={'请简要说明选题内容最大限制5000个字符'}
mdID={'courseMessageMD'} className="courseMessageMD"></TPMMDEditor>
)}
</Form.Item>
<Form.Item
className="setUploadStyle"
>
{
getFieldDecorator('file',{
rules:[{
required:false
}]
})(
<Upload {...uploadProps} className="upload_1 ">
<Button className="uploadBtn">
<Icon type="upload" /> 上传附件
</Button>
<span className="color-grey-c">(单个文件150M以内)</span>
</Upload>
)
}
</Form.Item>
<div className="clearfix">
<Form.Item className="fl mr20 with20" style={{"marginRight":"20px"}}>
{getFieldDecorator('topic_type', {
rules: [{
required: false, message: '',
}],
})(
<Select placeholder="请选择选题类型">
{
topic_type && topic_type.map((item,key)=>{
return(
<Option value={item.id} key={key}>{item.name}</Option>
)
})
}
</Select>
)}
</Form.Item>
<Form.Item className="fl mr20 with20" style={{"marginRight":"20px"}}>
{getFieldDecorator('topic_source', {
rules: [{
required: false, message: '',
}],
})(
<Select placeholder="请输入选题来源">
{
topic_source && topic_source.map((item,key)=>{
return(
<Option value={item.id} key={key}>{item.name}</Option>
)
})
}
</Select>
)}
</Form.Item>
<Form.Item className="fl mr20 with20" style={{"marginRight":"20px"}}>
{getFieldDecorator('topic_property_first', {
rules: [{
required: false, message: '',
}],
})(
<Select placeholder="请输入选题性质1">
{
topic_property_first && topic_property_first.map((item,key)=>{
return(
<Option value={item.id} key={key}>{item.name}</Option>
)
})
}
</Select>
)}
</Form.Item>
<Form.Item className="fl mr20 with20" style={{"marginRight":"20px"}}>
{getFieldDecorator('topic_property_second', {
rules: [{
required: false, message: '',
}],
})(
<Select placeholder="请输入选题性质2">
{
topic_property_second && topic_property_second.map((item,key)=>{
return(
<Option value={item.id} key={key}>{item.name}</Option>
)
})
}
</Select>
)}
</Form.Item>
</div>
</div>
<style>{`
.courseForm .flexBlock.formBlock {
align-items: flex-end;
display: flex;
flex-wrap: wrap;
}
.courseForm .flexBlock .tag {
margin-left: 8px;
margin-right: 6px;
margin-bottom: 16px;
}
.flexBlock .ant-row.ant-form-item {
margin-bottom: 6px;
}
.ant-cascader-menu{
min-width:125px!important;
}
`}</style>
<div className="createPage" style={{"borderBottom":"none"}}>
<Form.Item
label="选题来源单位"
className="with22"
>
{getFieldDecorator('source_unit', {
rules: [{
required: false, message: '',
}],
})(
<Input placeholder="请填写来源单位" autoComplete="off" className="searchView"/>
)}
</Form.Item>
<Form.Item
label="选择重复情况"
className="mt15 with22"
>
{getFieldDecorator('topic_repeat', {
rules: [{
required: false, message: '',
}],
})(
<Select placeholder="请选择选题重复情况">
{
topic_repeat && topic_repeat.map((item,key)=>{
return(
<Option value={item.id} key={key}>{item.name}</Option>
)
})
}
</Select>
)}
</Form.Item>
<Form.Item
label="调研或实习地点"
className="mt15 with22 setAreaStyle"
>
{getFieldDecorator('city', {
rules: [{
initialValue: cityDefaultValue,
type: 'array',
required: false, message: '',
}],
})(
<City ></City>
)}
</Form.Item>
</div>
<Form.Item>
<div className="clearfix mt30 mb30">
<Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">{topicId==undefined?"提交":"保存"}</Button>
<a className="defalutCancelbtn fl" onClick={this.props.editCancel}>取消</ a>
</div>
</Form.Item>
</Form>
</React.Fragment>
)
}
}
const WrappedGraduateTopicNewForm = Form.create({ name: 'topicPostWorksNew' })(GraduateTopicNewForm);
// RouteHOC()
export default (WrappedGraduateTopicNewForm);

@ -1,3 +1,4 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import {
@ -21,7 +22,9 @@ class GroupPackage extends Component {
}
}
DownloadOpenPdf=(type,url)=>{
type===true?window.open(url):window.location.href=url;
}
componentDidMount() {
console.log("Groupjobquesanswer");
console.log("componentDidMount");
@ -34,7 +37,6 @@ class GroupPackage extends Component {
}
// 获取数据地方
getTrainingjobsetting = () => {
@ -54,9 +56,9 @@ class GroupPackage extends Component {
render() {
let{attachments}=this.props;
return (
<div className="color-grey df yslquesmat26" key={0} style={{ lineHeight: '17px'}}>
<div className="color-grey df yslquesmat26" key={this.props.key} style={{ lineHeight: '17px'}}>
<a className="color-grey ">
<i className="font-14 color-green iconfont icon-fujian mr8" aria-hidden="true"></i>
</a>
@ -73,11 +75,11 @@ class GroupPackage extends Component {
`
}
</style>
<a href={"/"} title={''}
<a onClick={()=>this.DownloadOpenPdf(attachments.is_pdf,attachments.url)} title={attachments&&attachments.title}
className="mr12 yslahover overflowHidden1" length="58" style={{maxWidth:'480px',fontSize:"16px",}}>
<span>清除浏览器缓存或换个浏览器操作指南更新版本.zip</span>
<span>{attachments&&attachments.title}</span>
</a>
<span className="color656565 color-grey-6 font-12 mr8">{2}</span>
<span className="color656565 color-grey-6 font-12 mr8">{attachments&&attachments.filesize}</span>
</div>
)

@ -54,18 +54,42 @@ class GroupPackage extends Component {
render() {
let{datas,bool}=this.props;
return (
<div className="ml47text">
<p>
<span className="ysltextcolor66">分组要求</span>
<span className="ysltextcolor05">2~ 5学生提交作品时需要关联同组成员组内成员作品共享</span>
</p>
<p>
<span className="ysltextcolor66">基于项目实施</span>
<span className="ysltextcolor05">学生必须在本平台创建项目项目管理员可以提交作品</span>
</p>
</div>
bool===true?
<div className="ml47text">
{
datas===undefined?"":datas.min_num===undefined||datas.max_num===undefined?"":datas.min_num===null||datas.max_num===null?"":
<p>
<span className="ysltextcolor66">分组要求</span>
<span className="ysltextcolor05">{datas&&datas.min_num}~ {datas&&datas.max_num} 学生提交作品时需要关联同组成员组内成员作品共享</span>
</p>
}
<p>
<span className="ysltextcolor66">基于项目实施</span>
<span className="ysltextcolor05">学生必须在本平台创建项目项目管理员可以提交作品</span>
</p>
</div>
:<div className="ml47text">
{
datas===undefined?"":datas.group_info===undefined?"":datas.group_info.min_number===undefined||datas.group_info.max_number===undefined?"":
datas.group_info.min_number===null||datas.group_info.max_number===null?"":
<p>
<span className="ysltextcolor66">分组要求</span>
<span className="ysltextcolor05">{datas&&datas.group_info&&datas.group_info.min_number}~ {datas&&datas.group_info&&datas.group_info.max_number} 学生提交作品时需要关联同组成员组内成员作品共享</span>
</p>
}
{
datas&&datas.group_info&&datas.group_info.base_on_project?
<p>
<span className="ysltextcolor66">基于项目实施</span>
<span className="ysltextcolor05">学生必须在本平台创建项目项目管理员可以提交作品</span>
</p>
:""
}
</div>
)
}
}

@ -1,5 +1,6 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import { WordsBtn,on, off, trigger,MarkdownToHtml,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
@ -12,6 +13,9 @@ import {
} from "antd";
import './questionbanks.css';
import GroupPackage from "./GroupPackage";
import AttachmentsList from "../../../common/components/attachment/AttachmentList";
import NoneData from '../../courses/coursesPublic/NoneData'
import GroupPackage2 from "./GroupPackage2";
@ -57,20 +61,62 @@ class Groupjobbandetails extends Component {
render() {
let{datas}=this.props;
return (
<div className=" clearfix edu-back-white" ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className=" clearfix edu-back-white " ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
<GroupPackage></GroupPackage>
<GroupPackage2></GroupPackage2>
{
datas.description===null?
""
:datas.description==="null"?
""
:
datas.description===""?
""
:
<MarkdownToHtml content={datas.description} selector="work_content" className="mb10 yslquesHeigth"></MarkdownToHtml>
// <div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML(datas.description).replace(/▁/g, "▁▁▁")}}/>
}
{/*<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML(datas&&(datas.description===null?"无":datas.description==="null"?"无":datas.description)).replace(/▁/g, "▁▁▁")}}/>*/}
{/*{datas.attachments === undefined ? "" : datas.attachments.map((item, key) => {*/}
{/* return (*/}
{/* <GroupPackage key={key} attachments={item}></GroupPackage>*/}
{/* )*/}
{/*})}*/}
{datas.attachments === undefined ?
(datas.description === undefined || datas.description === undefined || datas.description === "" ?
<NoneData></NoneData>
:
""
)
:
datas.attachments=== "" ?
(datas.description === undefined || datas.description === undefined || datas.description === "" ?
<NoneData></NoneData>
:
""
)
:
datas.attachments=== null ?
(datas.description === undefined || datas.description === undefined || datas.description === "" ?
<NoneData></NoneData>
:
""
)
:
datas.attachments.length === 0 ?
(datas.description === undefined || datas.description === undefined || datas.description === "" ?
<NoneData></NoneData>
:
""
)
:
<div className="mt24">
<AttachmentsList {...this.state} {...this.props} attachments={datas.attachments} ></AttachmentsList>
</div>
}
<GroupPackage2 datas={datas} bool={true}></GroupPackage2>
</div>

@ -1,20 +1,26 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn} from 'educoder';
import {BrowserRouter as Router,Route,Switch,Link, NavLin} from 'react-router-dom';
import {WordsBtn, ActionBtn,getImageUrl} from 'educoder';
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form } from "antd";
import axios from 'axios';
import {
notification
} from "antd";
import CoursesListType from '../coursesPublic/CoursesListType';
import Groupjobbandetails from './Groupjobbandetails';
import Groupjobquesanswer from './Groupjobquesanswer';
import BanksMenu from '../../user/usersInfo/banks/banksMenu'
import Loadable from 'react-loadable';
import Loading from '../../../Loading';
import '../css/members.css';
import "../common/formCommon.css";
import '../css/Courses.css';
import '../css/busyWork.css';
import '../poll/pollStyle.css';
// 问卷内容
const Groupjobbandetails = Loadable({
loader: () => import('./Groupjobbandetails'),
loading: Loading,
})
// 试卷详情
const Groupjobquesanswer = Loadable({
loader: () => import('./Groupjobquesanswer'),
loading: Loading,
});
class GroupjobbankPage extends Component {
//分组作业内容详情
constructor(props) {
@ -25,53 +31,25 @@ class GroupjobbankPage extends Component {
workid:1,
isSpin:false,
datas:[],
visible:false,
banksMenu:undefined
}
}
//切换tab
ChangeTab = (e) => {
// console.log(e);
this.setState({
tab: e
})
try {
var currenturl = window.location.href;
var newUrl = (currenturl.split("?"))[0];
window.history.pushState('','',newUrl+'?tab='+e);
}catch (e) {
console.log(e);
console.log("44");
}
componentDidMount() {
this.getonedata();
}
componentDidMount() {
// console.log("父组件加载框");
const query = this.props.location.search;
const type = query.split('?tab=');
// let sum = []
// sum.push(type[1])
// console.log("componentDidMountcomponentDidMount");
// console.log(type);
this.setState({
tab: type[1],
})
let querys = this.props.location.pathname;
const types = querys.split('/');
// console.log(types);
this.setState({
shixuntypes: types[3]
})
getonedata=()=>{
if( this.props.match.params.workid){
this.setState({
workid: this.props.match.params.workid,
})
}
this.getdata(this.props.match.params.workid);
}
///获取数据的地方
};
//获取数据的地方
getdata=(workid)=>{
var workids= workid;
if(workids){
@ -88,8 +66,36 @@ class GroupjobbankPage extends Component {
if(response){
if(response.data){
this.setState({
datas:response.data.informs,
datas:response.data,
})
try {
const crumbData={
title:response && response.data && response.data.name,
is_public:response && response.data && response.data.is_public,
crumbArray:[
{content:'详情'}
]
};
const menuData={
tab:'0',//tab选中的index
menuArray:[//tab以及tab路由
{to:`/banks/group/${workids}/${this.props.match.params.type}?tab=0`,content:'内容详情'},
{to:`/banks/group/${workids}/${this.props.match.params.type}/answer?tab=1`,content:'参考答案'}
],
category:'group',//毕设选题
tos:`/banks/group/${workids}/edit/${this.props.match.params.type}`,
id:workids,
is_public:response && response.data && response.data.is_public,
type:this.props.match.params.type,
authorize:response && response.data && response.data.authorize,
}
this.setState({
banksMenu:menuData
})
this.props.initPublic(crumbData);
}catch (e) {
}
}else {
this.setState({
datas:[],
@ -113,63 +119,55 @@ class GroupjobbankPage extends Component {
isSpin:false,
})
});
}
bindRef = ref => { this.child = ref }
///////////////教师截止
};
// initPublic = (crumbData,menuData) =>{
// this.setState({
// banksMenu:menuData
// })
// this.props.initPublic(crumbData);
// }
render() {
let {tab} = this.state;
const isAdmin = this.props.isAdmin();
// console.log(119)
let {tab,datas,visible} = this.state;
let{
banksMenu
}=this.state
//
// const common={
// initPublic:this.initPublic,
// }
return (
<div className="newMain clearfix ">
<div className={"educontent mt10 mb20"} style={{width: "1200px"}}>
<div className="educontent mb20">
<p className="clearfix mb20 mt10">
<a className="btn colorgrey fl hovercolorblue ">题库</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<a
className=" btn colorgrey fl hovercolorblue "
>详情</a>
</p>
</div>
<div className="educontent mb20">
<p className=" fl color-black summaryname" style={{heigth: "33px"}}>
MySQL数据库编程开发实训基础篇
</p>
<CoursesListType
typelist={["公开"]}
/>
</div>
<div className="edu-back-white ">
<div className="stud-class-set bor-bottom-greyE ">
<div className=" clearfix edu-back-white poll_list">
<a className={parseInt(tab) === 0 ? "active ml12" : "ml12"} onClick={(e) => this.ChangeTab(0)}>内容详情</a>
<a className={parseInt(tab) === 1 ? "active ml12" : "ml12"} onClick={(e) => this.ChangeTab(1)}>参考答案</a>
<a className="fr color-blue font-16" >发送</a>
<a className="fr color-blue font-16" >编辑</a>
<a className="fr color-blue font-16" >删除</a>
</div>
</div>
</div>
<Spin size="large" spinning={this.state.isSpin} id={"cdiv"}>
{parseInt(tab) === 0 ? <Groupjobbandetails/>:""}
{parseInt(tab) === 1 ? <Groupjobquesanswer/>:""}
</Spin>
</div>
</div>
<React.Fragment>
<div className="pd30">
{
banksMenu &&
<BanksMenu
banksMenu={banksMenu}
{...this.props}
{...this.state}
></BanksMenu>
}
<Switch {...this.props}>
<Route path={`/banks/group/:workid/${this.props.match.params.type}/answer`}
render={
(props) => {
return (<Groupjobquesanswer {...this.props} {...props} {...this.state} datas={datas} />)
}
}></Route>
<Route path={`/banks/group/:workid/${this.props.match.params.type}`}
render={
(props) => {
return (<Groupjobbandetails {...this.props} {...props} {...this.state} datas={datas} />)
}
}></Route>
</Switch>
</div>
</React.Fragment>
)
}
}
export default GroupjobbankPage;

@ -1,5 +1,6 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import { WordsBtn,on, off, trigger,MarkdownToHtml,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
@ -10,8 +11,10 @@ import {
Tooltip,
notification,
} from "antd";
import AttachmentsList from '../../../common/components/attachment/AttachmentList'
import GroupPackage from './GroupPackage';
import GroupPackage2 from './GroupPackage2';
import NoneData from '../../courses/coursesPublic/NoneData'
import './questionbanks.css';
class Groupjobquesanswer extends Component {
@ -56,23 +59,54 @@ class Groupjobquesanswer extends Component {
render() {
let{datas}=this.props;
return (
<div className=" clearfix edu-back-white" ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className=" clearfix edu-back-white " ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
<GroupPackage></GroupPackage>
<GroupPackage2></GroupPackage2>
{
datas.reference_answer===null?
""
:datas.reference_answer==="null"?
"" :
datas.reference_answer===""?
""
:
<MarkdownToHtml content={datas.reference_answer} selector="work_content" className="mb10 yslquesHeigth"></MarkdownToHtml>
}
{datas.reference_attachments === undefined ?
(datas.reference_answer===undefined || datas.reference_answer===null|| datas.reference_answer===""?
<NoneData></NoneData>
:
""
)
:
datas.reference_attachments === "" ?
(datas.reference_answer===undefined || datas.reference_answer===null|| datas.reference_answer===""?
<NoneData></NoneData>
:
""
)
:
datas.reference_attachments === null ?
(datas.reference_answer===undefined || datas.reference_answer===null|| datas.reference_answer===""?
<NoneData></NoneData>
:
""
)
:
datas.reference_attachments.length === 0 ?
(datas.reference_answer===undefined || datas.reference_answer===null|| datas.reference_answer===""?
<NoneData></NoneData>
:
""
)
:
<div className="mt24">
<AttachmentsList {...this.state} {...this.props} attachments={datas.reference_attachments} ></AttachmentsList>
</div>
}
</div>
</div>
)

@ -2,9 +2,11 @@
padding-top: 30px !important;
padding-right: 30px !important;
padding-left: 30px !important;
min-height: 500px !important;
}
.yslquesHeigth{
min-height: 500px !important;
width: 100% !important;
}
.yslquesmarkdowntext{
@ -30,6 +32,7 @@
}
.ml47text{
margin-left: 17px;
margin-top: 33px;
padding-bottom: 37px;
}
.ysltextcolor99999{
@ -39,3 +42,9 @@
.yslahover {
color: #999999 ;
}
.mt24{
margin-top: 24px !important ;
}
.pd30{
margin-bottom: 30px;
}

@ -443,7 +443,9 @@ class CoursesNew extends Component {
};
handleSearchschool=(value)=>{
this.setState({
smallspinning:true
})
if(value!="") {
// this.props.form.setFieldsValue({
// // school: value,
@ -452,10 +454,13 @@ class CoursesNew extends Component {
this.setState({
fetching: true,
school: value,
smallspinning:true
})
this.getschool(value)
}else{
this.setState({
smallspinning:false
})
}
};

@ -563,7 +563,9 @@ class Goldsubject extends Component {
};
handleSearchschool=(value)=>{
this.setState({
smallspinning:true
})
if(value!="") {
// this.props.form.setFieldsValue({
// // school: value,
@ -572,9 +574,12 @@ class Goldsubject extends Component {
this.setState({
fetching: true,
school: value,
smallspinning:true
})
this.getschool(value)
}else{
this.setState({
smallspinning:false
})
}
};

@ -57,7 +57,7 @@ class PollDetailTabForth extends Component{
flagPageEdit:undefined,
unitSetting:true,
flagPublic:true,
flagPublic:false,
flagRealName:undefined,
course_group:undefined,
end_time:undefined,

@ -1,14 +1,13 @@
import React,{ Component } from "react";
import {Checkbox,Radio} from "antd";
import '../css/members.css'
import '../css/busyWork.css'
import './pollStyle.css'
import PollDetailTabThirdInfo from './PollDetailTabThirdInfo'
import axios from 'axios';
const map={1:"单选题",2:"多选题",3:"主观题",4:"主观题"}
class PollDetailTabThird extends Component{
constructor(props){
super(props);
@ -36,105 +35,7 @@ class PollDetailTabThird extends Component{
let {pollDetail}=this.state;
return(
<div>
{
pollDetail && pollDetail.poll.polls_description &&
<p style={{backgroundColor:"#F2F9FF",whiteSpace:"pre-wrap"}} className="color-blue pt15 pb15 pl30 pr30">{ pollDetail.poll.polls_description }</p>
}
<div className="edu-back-white">
<p className="padding20-30 clearfix bor-bottom-greyE edu-txt-left">
{ pollDetail && pollDetail.question_types.q_counts===0 ? "" :
<span className="color-grey-3">
{
pollDetail && pollDetail.question_types.q_counts > 0 &&
<span>合计{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.map((item,key)=>{
console.log("ddd");
console.log(item.question.min_choices);
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>
<li className="pl30 pr30 pb15">{item.question.question_title}</li>
{
// 单选题
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="mt10 pl30 pr30 pb20">
<textarea placeholder="在此填入答案" readOnly className="winput-100-130"></textarea>
</div>
}
</div>
)
})
}
</div>
<PollDetailTabThirdInfo {...this.props} {...this.state} pollDetail = {pollDetail}></PollDetailTabThirdInfo>
</div>
)
}

@ -0,0 +1,117 @@
import React,{ Component } from "react";
import {Checkbox,Radio} from "antd";
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;
return(
<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>
}
<p className="padding20-30 clearfix edu-txt-left" style={{background:"#fafafa"}}>
{ pollDetail && pollDetail.question_types.q_counts===0 ? "" :
<span className="color-grey-3">
{
pollDetail && pollDetail.question_types.q_counts > 0 &&
<span>合计{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.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>
<li className="pl30 pr30 pb15">{item.question.question_title}</li>
{
// 单选题
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>
)
})
}
</div>
)
}
}
export default PollDetailTabThirdInfo

@ -19,7 +19,6 @@ class PollInfo extends Component{
super(props);
this.state={
courseName:undefined,
userName:undefined,
poll:undefined,
question_answered:undefined,
question_types:undefined,
@ -73,8 +72,7 @@ class PollInfo extends Component{
getInfo=()=>{
this.setState({
courseName:this.props.current_user.course_name,
userName:this.props.current_user.username
courseName:this.props.current_user.course_name
})
let pollId=this.props.match.params.pollId;
let user_id=this.props.match.params.login;
@ -291,7 +289,7 @@ class PollInfo extends Component{
render(){
let coursesId=this.props.match.params.coursesId;
let{poll,question_answered,question_types,questions,courseName,userName,
let{poll,question_answered,question_types,questions,courseName,
inputArray,
modalsType,
modalsTopval,

@ -71,6 +71,7 @@ class PollNew extends Component {
first_category_url:"",
left_banner_id:"",
publishtimeid_int:0,
boolneweied:undefined,
}
// console.log("试卷新建和编辑");
// console.log(JSON.stringify(props));
@ -380,6 +381,7 @@ class PollNew extends Component {
}
this.setState({
Newdisplay:true,
boolneweied:true,
})
var Insertposition = this.state.poll_questions.length;
// console.log(JSON.stringify(this.state.poll_questions));
@ -409,6 +411,7 @@ class PollNew extends Component {
}
this.setState({
Newdisplay:true,
boolneweied:true,
})
var Insertposition = this.state.poll_questions.length;
// console.log(JSON.stringify(this.state.poll_questions));
@ -432,6 +435,7 @@ class PollNew extends Component {
}
this.setState({
Newdisplay:true,
boolneweied:true,
})
var Insertposition = this.state.poll_questions.length;
// console.log(JSON.stringify(this.state.poll_questions));
@ -451,15 +455,24 @@ class PollNew extends Component {
adddomedit = (object,indexysl) => {
// console.log("adddomedit 76");
if (this.state.q_countst > 0) {
if(this.state.boolneweied !== undefined){
if(this.state.boolneweied===true){
this.scrollToAnchor("publishtimeids");
}else{
this.scrollToAnchor("publishtimeid"+this.state.publishtimeid_int);
}
}else{
this.scrollToAnchor("publishtimeids");
}
this.props.showNotification(`不能同时编辑两题`);
this.scrollToAnchor("publishtimeids");
return;
}
var anserbool = false;
this.setState({
q_countst: 1,
bindingid:object.question.id,
publishtimeid_int:indexysl
publishtimeid_int:indexysl,
boolneweied:false,
})
// window.scrollTo(0, this.refs.targetElement.offsetTops)
let {adddom} = this.state;
@ -617,11 +630,19 @@ class PollNew extends Component {
// console.log(pollid)
// console.log(Insertposition)
// console.log(Whether)
console.log("addMytopic");
console.log(id);
// console.log("addMytopic");
// console.log(id);
if (this.state.q_countst > 0) {
if(Whether===true){
this.scrollToAnchor("publishtimeids");
if(this.state.boolneweied !== undefined){
if(this.state.boolneweied===true){
this.scrollToAnchor("publishtimeids");
}else{
this.scrollToAnchor("publishtimeid"+this.state.publishtimeid_int);
}
}else{
this.scrollToAnchor("publishtimeids");
}
}
this.props.showNotification(`不能同时编辑两题`);
return;
@ -639,6 +660,7 @@ class PollNew extends Component {
this.setState({
Insertposition: Insertposition,
q_countst: 1,
boolneweied:false,
})
// window.scrollTo(0, this.refs.targetElement.offsetTop)
var arrr = this.state.adddom;
@ -847,6 +869,7 @@ class PollNew extends Component {
bindingid:undefined,
Newdisplay:false,
newoption: false,
boolneweied:undefined
})
}else{
@ -857,6 +880,7 @@ class PollNew extends Component {
problemtopicbool: false,
Newdisplay:false,
newoption: false,
boolneweied:undefined
})
}
@ -1008,7 +1032,7 @@ class PollNew extends Component {
if(object.question.max_choices){
if(object.question.max_choices>0){
if (object.question.max_choices < object.question.min_choices) {
this.props.showNotification(`可选的最大限制不能小于最小限制`);
this.props.showNotification(`可选:最小和最大限制须同时为数值或者“--"`);
return;
}
}
@ -1228,7 +1252,7 @@ class PollNew extends Component {
if(object.question.max_choices){
if(object.question.max_choices>0){
if (object.question.max_choices < object.question.min_choices) {
this.props.showNotification(`可选的最大限制不能小于最小限制`);
this.props.showNotification(`可选:最小和最大限制须同时为数值或者“--"`);
return;
}
}
@ -1405,6 +1429,7 @@ class PollNew extends Component {
adddom: newarr,
problemtopic: null,
problemtopicbool: false,
boolneweied:undefined
// mysingles: this.state.mysingles,
// mydoubles: this.state.mydoubles,
// mymainsint: this.state.mymainsint
@ -1548,7 +1573,7 @@ class PollNew extends Component {
if(object.question.max_choices){
if(object.question.max_choices>0){
if (object.question.max_choices < object.question.min_choices) {
this.props.showNotification(`可选的最大限制不能小于最小限制`);
this.props.showNotification(`可选:最小和最大限制须同时为数值或者“--"`);
return;
}
}
@ -1759,7 +1784,7 @@ class PollNew extends Component {
if(object.question.max_choices){
if(object.question.max_choices>0){
if (object.question.max_choices < object.question.min_choices) {
this.props.showNotification(`可选的最大限制不能小于最小限制`);
this.props.showNotification(`可选:最小和最大限制须同时为数值或者“--"`);
return;
}
}
@ -1923,6 +1948,9 @@ class PollNew extends Component {
}
this.Deleteadddom(indexo);
// console.log(indexo)
this.setState({
boolneweied:undefined
})
}
@ -2771,10 +2799,10 @@ class PollNew extends Component {
{
this.props.match.params.news === "new" ?
<a href={`/courses/${this.props.match.params.coursesId}/polls/${this.props.match.params.pollid}`}
className=" fr font-16">返回</a>
className=" fr font-16"></a>
:
<a href={`/courses/${this.props.match.params.coursesId}/polls/${left_banner_id}`}
className=" fr font-16">返回</a>
className=" fr font-16"></a>
}
</div>

File diff suppressed because it is too large Load Diff

@ -17,7 +17,22 @@
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;
@ -185,7 +200,7 @@
width: 100%;
}
.answerList li:hover{
background: #F8F8F8;
background: #F0F8FF;
}
textarea:read-only{
background: #f3f3f3;

@ -1,5 +1,5 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import { WordsBtn,on, off, trigger,MarkdownToHtml,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
@ -12,6 +12,8 @@ import {
} from "antd";
import GroupPackage from '../groupjobbank/GroupPackage'
import './questionbank.css';
import AttachmentsList from '../../../common/components/attachment/AttachmentList';
import NoneData from '../../courses/coursesPublic/NoneData'
class Generaljobanswer extends Component {
@ -28,7 +30,7 @@ class Generaljobanswer extends Component {
console.log("componentDidMount");
// let query = this.props.location.pathname;
// const type = query.split('/');
// this.setState({
// this.setState({n
// shixuntypes:type[3]
// })
// this.props.triggerRef(this);
@ -55,18 +57,77 @@ class Generaljobanswer extends Component {
render() {
let{datas}=this.props;
console.log("Generaljobanswer");
console.log(datas.reference_attachments);
console.log(datas.reference_answer);
return (
<div className=" clearfix edu-back-white" ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className=" clearfix edu-back-white " ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
<GroupPackage></GroupPackage>
{/*{*/}
{/* datas&&(datas.reference_answer===null?*/}
{/* <NoneData></NoneData>*/}
{/* :datas.reference_answer==="null"?*/}
{/* <NoneData></NoneData>*/}
{/* :*/}
{/* datas.reference_answer===""?*/}
{/* <NoneData></NoneData>*/}
{/* :*/}
{/* <MarkdownToHtml content={datas.reference_answer} selector="work_content" className="mb10 yslquesHeigth "></MarkdownToHtml>*/}
{/* // <div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML(datas.reference_answer).replace(/▁/g, "▁▁▁")}}/>*/}
{/* )*/}
{/*}*/}
{/*/!*<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML(datas&&(datas.reference_answer===null?"无":datas.reference_answer==="null"?"无":datas.reference_answer)).replace(/▁/g, "▁▁▁")}}/>*!/*/}
{/*<div className="mt16px">*/}
{/*{datas.reference_attachments === undefined ? "" :*/}
{/* <AttachmentsList {...this.state} {...this.props} attachments={datas.reference_attachments} ></AttachmentsList>}*/}
{/*</div>*/}
{
datas.reference_answer===null?
""
:datas.reference_answer==="null"?
"" :
datas.reference_answer===""?
""
:
<MarkdownToHtml content={datas.reference_answer} selector="work_content" className="mb10 yslquesHeigth "></MarkdownToHtml>
}
{datas.reference_attachments === undefined ?
(datas.reference_answer===undefined || datas.reference_answer===undefined|| datas.reference_answer===""?
<NoneData></NoneData>
:
""
)
:
datas.reference_attachments === "" ?
(datas.reference_answer===undefined || datas.reference_answer===undefined|| datas.reference_answer===""?
<NoneData></NoneData>
:
""
)
:
datas.reference_attachments === null ?
(datas.reference_answer===undefined || datas.reference_answer===undefined|| datas.reference_answer===""?
<NoneData></NoneData>
:
""
)
:
datas.reference_attachments.length === 0 ?
(datas.reference_answer===undefined || datas.reference_answer===undefined|| datas.reference_answer===""?
<NoneData></NoneData>
:
""
)
:
<div className="mt24">
<AttachmentsList {...this.state} {...this.props} attachments={datas.reference_attachments} ></AttachmentsList>
</div>
}
</div>

@ -1,20 +1,26 @@
import React, {Component} from "react";
import {Link, NavLink} from 'react-router-dom';
import {WordsBtn, ActionBtn} from 'educoder';
import {BrowserRouter as Router,Route,Switch,Link, NavLin} from 'react-router-dom';
import {WordsBtn, ActionBtn,getImageUrl} from 'educoder';
import { Input,Checkbox,Table, Pagination, Modal,Menu, Tooltip,Spin,Button,Form } from "antd";
import axios from 'axios';
import {
notification
} from "antd";
import CoursesListType from '../coursesPublic/CoursesListType';
import Generaljobdetails from './Generaljobdetails';
import Generaljobanswer from './Generaljobanswer';
import BanksMenu from '../../user/usersInfo/banks/banksMenu'
import Loadable from 'react-loadable';
import Loading from '../../../Loading';
import '../css/members.css';
import "../common/formCommon.css";
import '../css/Courses.css';
import '../css/busyWork.css';
import '../poll/pollStyle.css';
// 问卷内容
const Generaljobdetails = Loadable({
loader: () => import('./Generaljobdetails'),
loading: Loading,
})
// 试卷详情
const Generaljobanswer = Loadable({
loader: () => import('./Generaljobanswer'),
loading: Loading,
});
class Generaljobbankdetails extends Component {
//普通作业内容详情
constructor(props) {
@ -25,50 +31,24 @@ class Generaljobbankdetails extends Component {
workid:1,
isSpin:false,
datas:[],
visible:false,
banksMenu:undefined
}
}
//切换tab
ChangeTab = (e) => {
// console.log(e);
this.setState({
tab: e
})
try {
var currenturl = window.location.href;
var newUrl = (currenturl.split("?"))[0];
window.history.pushState('','',newUrl+'?tab='+e);
}catch (e) {
console.log(e);
console.log("44");
}
}
componentDidMount() {
// console.log("父组件加载框");
const query = this.props.location.search;
const type = query.split('?tab=');
// let sum = []
// sum.push(type[1])
// console.log("componentDidMountcomponentDidMount");
// console.log(type);
this.setState({
tab: type[1],
});
this.getonedata();
}
console.log("Generaljobbankdetails");
console.log(this.props);
getonedata=()=>{
if( this.props.match.params.workid){
this.setState({
workid: this.props.match.params.workid,
})
}
this.getdata(this.props.match.params.workid);
}
};
//获取数据的地方
getdata=(workid)=>{
var workids= workid;
@ -86,8 +66,37 @@ class Generaljobbankdetails extends Component {
if(response){
if(response.data){
this.setState({
datas:response.data.informs,
datas:response.data,
})
try {
const crumbData={
title:response && response.data && response.data.name,
is_public:response && response.data && response.data.is_public,
crumbArray:[
{content:'详情'}
]
};
const menuData={
tab:'0',//tab选中的index
menuArray:[//tab以及tab路由
{to:`/banks/normal/${workids}/${this.props.match.params.type}?tab=0`,content:'内容详情'},
{to:`/banks/normal/${workids}/${this.props.match.params.type}/answer?tab=1`,content:'参考答案'}
],
category:'normal',//毕设选题
tos:`/banks/normal/${workids}/edit/${this.props.match.params.type}`,
id:workids,
is_public:response && response.data && response.data.is_public,
type:this.props.match.params.type,
authorize:response && response.data && response.data.authorize,
}
this.setState({
banksMenu:menuData
})
this.props.initPublic(crumbData);
}catch (e) {
}
}else {
this.setState({
datas:[],
@ -111,63 +120,51 @@ class Generaljobbankdetails extends Component {
isSpin:false,
})
});
}
bindRef = ref => { this.child = ref }
///////////////教师截止
};
// initPublic = (crumbData,menuData) =>{
// this.setState({
// banksMenu:menuData
// })
// this.props.initPublic(crumbData);
// }
render() {
let {tab} = this.state;
const isAdmin = this.props.isAdmin();
// console.log(119)
let {tab,datas,visible} = this.state;
let{
banksMenu
}=this.state
return (
<div className="newMain clearfix ">
<div className={"educontent mt10 mb20"} style={{width: "1200px"}}>
<div className="educontent mb20">
<p className="clearfix mb20 mt10">
<a className="btn colorgrey fl hovercolorblue ">题库</a>
<span className="color-grey-9 fl ml3 mr3">&gt;</span>
<a
className=" btn colorgrey fl hovercolorblue "
>详情</a>
</p>
</div>
<div className="educontent mb20">
<p className=" fl color-black summaryname" style={{heigth: "33px"}}>
MySQL数据库编程开发实训基础篇
</p>
<CoursesListType
typelist={["公开"]}
/>
<React.Fragment>
<div className="pd30">
{
banksMenu &&
<BanksMenu
banksMenu={banksMenu}
{...this.props}
{...this.state}
></BanksMenu>
}
<Switch {...this.props}>
<Route path={`/banks/normal/:workid/${this.props.match.params.type}/answer`}
render={
(props) => {
return (<Generaljobanswer {...this.props} {...props} {...this.state} datas={datas} />)
}
}></Route>
<Route path={`/banks/normal/:workid/${this.props.match.params.type}`}
render={
(props) => {
return (<Generaljobdetails {...this.props} {...props} {...this.state} datas={datas} />)
}
}></Route>
</Switch>
</div>
<div className="edu-back-white ">
<div className="stud-class-set bor-bottom-greyE ">
<div className=" clearfix edu-back-white poll_list">
<a className={parseInt(tab) === 0 ? "active ml12" : "ml12"} onClick={(e) => this.ChangeTab(0)}>内容详情</a>
<a className={parseInt(tab) === 1 ? "active ml12" : "ml12"} onClick={(e) => this.ChangeTab(1)}>参考答案</a>
<a className="fr color-blue font-16" >发送</a>
<a className="fr color-blue font-16" >编辑</a>
<a className="fr color-blue font-16" >删除</a>
</div>
</div>
</div>
<Spin size="large" spinning={this.state.isSpin} id={"cdiv"}>
{parseInt(tab) === 0 ? <Generaljobdetails {...this.props} {...this.state}/> :""}
{parseInt(tab) === 1 ? <Generaljobanswer{...this.props} {...this.state}/>:""}
</Spin>
</div>
</div>
</React.Fragment>
)
}
}
export default Generaljobbankdetails;

@ -1,5 +1,6 @@
import React, {Component} from "react";
import { WordsBtn,on, off, trigger,markdownToHTML,getImageUrl} from 'educoder';
import { WordsBtn,on, off, trigger,markdownToHTML, MarkdownToHtml ,getImageUrl} from 'educoder';
import {
Button,
Checkbox,
@ -12,15 +13,15 @@ import {
} from "antd";
import GroupPackage from '../groupjobbank/GroupPackage'
import './questionbank.css';
import AttachmentsList from "../../../common/components/attachment/AttachmentList";
import NoneData from '../../courses/coursesPublic/NoneData'
//内容详情
class Generaljobdetails extends Component {
constructor(props) {
super(props);
this.state = {
}
}
@ -56,21 +57,56 @@ class Generaljobdetails extends Component {
render() {
let{datas}=this.props;
return (
<div className=" clearfix edu-back-white" ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className=" clearfix edu-back-white " ref='targetElementTrainingjobsetting' style={{margin: "auto", minWidth:"1200px"}}>
<div className="yslquestionbank1">
<div id="MakedownHTML"className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML("C++是C语言的面向对象扩展是C语言的一个超集同时也是历史最悠久、最受欢迎的程序设计语言之一。根据C++创始人Stroustrup的自述C++是一个“更好的C语言”。\n" +
"\n" +
"输入输出是计算机程序的基本功能。程序本质上是对数据进行处理的一系列操作,一般程序都可以分解为:“数据输入”、“数据处理”和“数据输出”三个步骤。标准输入输出(键盘输入和显示器输出)是程序的重要组成部分。\n" +
"\n" +
"本实训项目的主要目标是学习和掌握C++程序的基本结构和基本输入输出主要内容包括标准C语言自有的单个字符的输入输出、格式化的输入输出以及C++扩展的使用流对象的输入输出").replace(/▁/g, "▁▁▁")}}/>
<GroupPackage></GroupPackage>
{
datas.description===null?
""
:datas.description==="null"?
""
:datas&&datas.description===""?
""
:
<MarkdownToHtml content={datas.description} selector="work_content" className="mb10 yslquesHeigth"></MarkdownToHtml>
// <div id="MakedownHTML "className="markdown-body yslquesHeigth yslquesmarkdowntext" dangerouslySetInnerHTML={{__html: markdownToHTML(datas.description).replace(/▁/g, "▁▁▁")}}/>
}
{datas.attachments === undefined ?
(datas.description === undefined || datas.description === undefined || datas.description === "" ?
<NoneData></NoneData>
:
""
)
:
datas.attachments=== "" ?
(datas.description === undefined || datas.description === undefined || datas.description === "" ?
<NoneData></NoneData>
:
""
)
:
datas.attachments=== null ?
(datas.description === undefined || datas.description === undefined || datas.description === "" ?
<NoneData></NoneData>
:
""
)
:
datas.attachments.length === 0 ?
(datas.description === undefined || datas.description === undefined || datas.description === "" ?
<NoneData></NoneData>
:
""
)
:
<div className="mt16px">
<AttachmentsList {...this.state} {...this.props}
attachments={datas.attachments}></AttachmentsList>
</div>
}
</div>
</div>

@ -2,10 +2,10 @@
padding-top: 30px !important;
padding-right: 30px !important;
padding-left: 30px !important;
min-height: 500px !important;
}
.yslquesHeigth{
min-height: 500px !important;
width: 100% !important;
}
.yslquesmarkdowntext{
font-size: 16px;
@ -24,3 +24,10 @@
color: #999999;
font-size: 16px;
}
.mt16px{
margin-top: 16px;
padding-bottom: 30px;
}
.pd30{
padding-bottom: 30px;
}

@ -2504,6 +2504,15 @@ class Listofworksstudentone extends Component {
// console.log(this.props.isAdmin());
let course_is_end = this.props.current_user&&this.props.current_user.course_is_end;
// if(this.props.isAdmin() === false){
// if(teacherdata.student_works!==undefined){
// if(teacherdata.student_works.length>0){
//
//
// }
// }
//
// }
return (
this.props.isAdmin() === true ?
(
@ -3035,6 +3044,7 @@ class Listofworksstudentone extends Component {
:
// 学生能查看别人的
<div className=" clearfix " style={{margin: "auto" , minWidth:"1200px"}}>
{/*双层*/}
<DownloadMessageysl
{...this.props}
value={this.state.DownloadMessageval}

@ -323,7 +323,6 @@ class ShixunWorkReport extends Component {
.back_font{
height: 18px;
font-size: 18px;
font-family: PingFangSC;
font-weight: 400;
color: rgba(51,51,51,1);
line-height: 18px;

@ -1,6 +1,6 @@
import React,{ Component } from "react";
import CoursesListType from '../coursesPublic/CoursesListType';
import { WordsBtn, getTaskUrlById } from 'educoder';
import { WordsBtn, getTaskUrlById , ConditionToolTip } from 'educoder';
import {Tooltip,message,Modal} from 'antd';
import {Link} from 'react-router-dom';
import axios from 'axios';
@ -330,7 +330,7 @@ class ShixunhomeWorkItem extends Component{
<div className="cl"></div>
<p className="color-grey panel-lightgrey mt16 fl">
<span className="mr50">
<span className="mr50 df">
{/* <a href="/users/innov" className="panel-name-small hide fl mr15 mr30 color-grey3">{discussMessage.author.name}</a> */}
{ discussMessage.author && <span className="mr15 color-grey-3">{discussMessage.author}</span> }
{discussMessage.commit_count===undefined?"":<span className="mr15 color-grey9">{discussMessage.commit_count} 已交</span>}
@ -357,6 +357,15 @@ class ShixunhomeWorkItem extends Component{
:
<span className="mr15 color-grey9">{discussMessage.status_time}</span>
}
{
discussMessage && discussMessage.upper_category_name &&
<ConditionToolTip title={discussMessage.upper_category_name} condition={ discussMessage.upper_category_name.length > 22 }>
{ <span className="mr15 color-grey9 task-hide" style={{"maxWidth":"272px"}}>{discussMessage.upper_category_name}</span>}
</ConditionToolTip>
}
{/* { discussMessage.replies_count != 0 && <span className="mr15 color-grey9">{discussMessage.replies_count} </span> }
{ discussMessage.praise_num != 0 && <span className="mr15 color-grey9">{discussMessage.praise_num} 点赞</span> }
@ -378,7 +387,7 @@ class ShixunhomeWorkItem extends Component{
`
}
</style>
{this.props.isAdmin?<div onClick={(event)=>this.stopPro(event)} className={this.props.isAdminOrCreator()?"homepagePostSetting homepagePostSettingname":"homepagePostSetting homepagePostSettingbox"} style={{"right":"-2px","top":"44px","display":"block"}}>
{this.props.isAdmin?<div onClick={(event)=>this.stopPro(event)} className={this.props.isAdminOrCreator()?"homepagePostSetting homepagePostSettingname":"homepagePostSetting homepagePostSettingbox"} style={{"right":"-2px","top":"46px","display":"block"}}>
<Link className="btn colorblue font-16" to={"/shixuns/"+discussMessage.shixun_identifier+"/challenges"} target={"_blank"}>实训详情</Link>
{this.props.isAdminOrCreator()?<a onClick={(event)=>this.editname(discussMessage.name,discussMessage.homework_id,event)} className={"btn colorblue ml20 font-16"}>重命名</a>:""}
{/*<WordsBtn className="btn colorblue ml20 font-16" to={`/courses/${this.props.match.params.coursesId}/${this.state.shixuntypes}/${discussMessage.homework_id}/settings?tab=3`} > 设置</WordsBtn>*/}

@ -862,19 +862,19 @@ class Trainingjobsetting extends Component {
var exams = parseFloat(Proportion.toFixed(1));
var intk = srorelength*exams;
intkk=oushution - intk;
console.log("奇数");
console.log(srorelength);//3
console.log(oushution);//79
console.log(exams);//26.3
console.log(intk);//78.9
console.log(intkk);
// console.log("奇数");
// console.log(srorelength);//3
// console.log(oushution);//79
// console.log(exams);//26.3
// console.log(intk);//78.9
// console.log(intkk);
}else {
// 偶数
var examsy =parseFloat(Proportion.toFixed(1));
intkks=oushution - (examsy*srorelength);
console.log("偶数");
console.log(oushution);
console.log((examsy*srorelength));
// console.log("偶数");
// console.log(oushution);
// console.log((examsy*srorelength));
}
var mact=0;

@ -0,0 +1,177 @@
import React,{ Component } from "react";
import { Modal,Radio,Input,Tooltip,Checkbox,Select, Row,Col ,Spin} from "antd";
import axios from 'axios';
const { Search } = Input;
class SendTopics extends Component{
constructor(props){
super(props);
this.state={
courses:[],
search:null,
Radiolist:undefined,
showcheck:false,
smallisSpin:false
}
}
componentDidMount(){
let{search}=this.state;
this.onupdatalist(search)
}
onupdatalist=(search)=>{
let url="/question_banks/my_courses.json";
axios.get(url,{params:{
search
}
}).then((result)=>{
this.setState({
courses:result.data.courses
})
}).catch((error)=>{
console.log(error);
})
}
onSearchChange=(e)=>{
this.setState({
search:e.target.value
})
// this.onupdatalist(e.target.value)
}
onSearch=(search)=>{
this.onupdatalist(search)
}
onChange=(e)=>{
this.setState({
Radiolist:e.target.value
})
}
submitInfo=()=>{
this.setState({
smallisSpin:true
})
let{Radiolist}=this.state;
let url=`/question_banks/send_to_course.json`;
let object_id=this.props.checkBoxValues;
let object_type=this.props.category;
if(Radiolist===undefined){
this.setState({
showcheck:true,
smallisSpin:false
})
}else{
axios.post(url,{
object_id: object_id,
object_type:object_type,
course_id:Radiolist
}
).then((result)=>{
this.setState({
smallisSpin:false
})
if(result.data.status===0){
this.props.showNotification(result.data.message)
this.props.topicscancelmodel()
this.props.updataslist()
}else{
this.props.showNotification(result.data.message)
}
}).catch((error)=>{
console.log(error)
this.setState({
smallisSpin:false
})
})
}
}
render(){
let{courses,Radiolist,showcheck,smallisSpin}= this.state;
const radioStyle = {
display: 'block',
height: '30px',
lineHeight: '30px',
};
return(
<div>
<style>
{
`
.ant-modal-body{
padding:20px 40px;
}
.onSearchtopics input{
height:40px;
}
.over221{
height:221px;
overflow-y: auto;
}
`
}
</style>
<Modal
keyboard={false}
title="发送至课堂"
visible={this.props.visible}
closable={false}
footer={null}
destroyOnClose={true}
width={600}
>
<div className="newupload_conbox">
<div className="mb15 font-14 edu-txt-center color-orange-tip">
温馨提示选择的题将会发送到指定课堂
</div>
<div className="mb5"
// onMouseLeave={this.closeList}
>
<Search
className="mb14 onSearchtopics"
placeholder="请输入课堂名称进行搜索"
onChange={this.onSearchChange}
onSearch={this.onSearch}
></Search>
</div>
<div className="edu-back-skyblue pl15 pr15 clearfix over221 pt5">
<Radio.Group onChange={this.onChange} value={Radiolist}>
{
courses && courses.map((item,key)=>{
return(
<div className="mt5" key={key}>
<Radio style={radioStyle} value={item.course_id} key={item.course_id}>
{item.course_name}
</Radio>
</div>
)
})
}
</Radio.Group>
</div>
{showcheck===true?<div className={"color-red mt10"}>请先选择课堂</div>:""}
<div className="mt20 clearfix edu-txt-center" >
<a onClick={()=>this.props.topicscancelmodel()} className="pop_close task-btn mr30 ">取消</a>
<a className="task-btn task-btn-orange" onClick={()=>this.submitInfo()}>确定</a>
</div>
</div>
</Modal>
</div>
)
}
}
export default SendTopics;

@ -244,7 +244,10 @@ class CaseNew extends Component{
// 选择标签
changeType=(type)=>{
// console.log(this.state.casesTags);
// debugger
let tags = [];
if(this.state.casesTags.indexOf(type) > -1){
tags = this.state.casesTags.filter(item => item != type);
}else{

@ -1,5 +1,5 @@
import React, { Component } from 'react';
import {getImageUrl} from 'educoder';
import { getImageUrl , setImagesUrl } from 'educoder';
import { BrowserRouter as Router, Route, Link } from "react-router-dom";
import { Tooltip } from 'antd';
import axios from 'axios';
@ -22,51 +22,49 @@ class ShixunPathCard extends Component{
pathList && pathList.map((item,key)=>{
return(
<div className="square-Item" id={"item_"+key}>
{
item.tag_name === null ? "" :
<div className="tag-green">
<span className="tag-name">{item.tag_name}</span>
{/*<img src={getImageUrl('images/educoder/tag2.png')}/>*/}
</div>
}
<div className="squareCard" id={"item_"+key}>
{/* item.tag_name === null ? "" :
<div className="tag-green">
<span className="tag-name">{item.tag_name}</span>
<img src={getImageUrl('images/educoder/tag2.png')}/>
</div> */}
{
item.excellent === false ? "" :
<div className="tag-orange">
<span className="tag-name">开放课程</span>
</div>
<div className="tag_open">
<span className="tag_open_name">开放课程</span>
</div>
}
<div className={item.allow_visit=== false ? "closeSquare" : "none"}>
{/* <div className={item.allow_visit=== false ? "closeSquare" : "none"}>
<img src={getImageUrl("images/educoder/icon/lockclose.svg")}
className="mt80 mb25"/>
<p className="font-14 color-white">非试用内容需要授权</p>
</div>
<Link to={"/paths/"+item.id} className="square-img" >
</div> */}
<Link to={"/paths/"+item.id} className="squareImg" >
{/*target="_blank"*/}
<img alt="详情图片" src={"/"+item.image_url} style={{"display":"block"}}/>
<img alt="详情图片" src={setImagesUrl(item.image_url)}/>
</Link>
<div className="square-main">
<p className="task-hide">
<Link to={"/paths/"+item.id} className="justify color-grey-name" >{item.name}</Link>
<div className="mt20" style={{marginLeft:"1px"}}>
<p className="task-hide mb10">
<Link to={"/paths/"+item.id} className="justify cardName">{item.name}</Link>
{/*target="_blank"*/}
</p>
<p className="clearfix mt8 font-12 color-grey-B4">
<p className="clearfix squareInfo">
<Tooltip placement="bottom" title={"章节"}>
<span className="mr10 fl squareIconSpan"><i className="iconfont icon-shixun fl mr3"></i>{item.stages_count}</span>
</Tooltip>
{/* <Tooltip placement="bottom" title={"章节"}> */}
{/* <i className="iconfont icon-shixun fl mr3"></i> */}
<span className="fl pr squareLine mr20">章节: {item.stages_count}</span>
{/* </Tooltip> */}
{/*<Tooltip placement="bottom" title={"经验值"}>*/}
{/*<span className="mr10 fl squareIconSpan"><i className="iconfont icon-jingyan fl mr3"></i>{item.shixuns_count}</span>*/}
{/*</Tooltip>*/}
<Tooltip placement="bottom" title={"学习人数"}>
<span className="mr10 fl squareIconSpan"><i className="iconfont icon-chengyuan fl mr3"></i>{item.members_count}</span>
</Tooltip>
{/* <Tooltip placement="bottom" title={"学习人数"}> */}
{/* <i className="iconfont icon-chengyuan fl mr3"></i> */}
<span className="fl">学习人数: {item.members_count}</span>
{/* </Tooltip> */}
</p>
</div>
</div>

@ -7,8 +7,8 @@ import Pagination from '@icedesign/base/lib/pagination';
import '@icedesign/base/lib/pagination/style.js';
import './ShixunPaths.css';
import path from '../../images/path/path.png';
const Search = Input.Search;
class ShixunPathSearch extends Component{
constructor(props) {
@ -122,9 +122,12 @@ class ShixunPathSearch extends Component{
{this.state.updata===undefined?"":<UpgradeModals
{...this.state}
/>}
<div className="path-head pr">
<div className="edu-txt-center pathNavLine">
<div className="inline path-nav">
<div className="pr">
<div className="pathImg">
<img src={path} width="100%"/>
</div>
<div className="edu-back-white padding20 pathIndexNav">
<ul className="educontent clearfix">
<li className={select > 0 ? "" : "active"}><a onClick={()=>this.changeSelect(null)}>全部</a></li>
{
sortList && sortList.map((item,key)=>{
@ -133,14 +136,14 @@ class ShixunPathSearch extends Component{
)
})
}
</div>
</ul>
</div>
</div>
<div className="mt20 educontent mb20 clearfix">
<div className="mt20 educontent mb20 clearfix mainPageArray">
{/*<a href="javascript:void(0)" className={ order == "publish_time" ? "fl mr20 font-16 bestChoose active" : "fl mr20 font-16 bestChoose"} onClick={ () => this.changeStatus("publish_time")}>全部</a>*/}
{/*<a href="javascript:void(0)" className={ order == "mine" ? "fl mr20 font-16 bestChoose active" : "fl mr20 font-16 bestChoose"} onClick={ () => this.changeStatus("mine")}>我的</a>*/}
<span className={ order == "updated_at" ? "fl mr20 font-16 bestChoose active pointer" : "fl mr20 font-16 bestChoose pointer"} onClick={ () => this.changeStatus("updated_at")}>最新</span>
<span className={ order == "myshixun_count" ? "fl mr20 font-16 bestChoose active pointer" : "fl mr20 font-16 bestChoose pointer"} onClick={ () => this.changeStatus("myshixun_count")}>最热</span>
<span className={ order == "updated_at" ? "active" : ""} onClick={ () => this.changeStatus("updated_at")}>最新</span>
<span className={ order == "myshixun_count" ? "active" : ""} onClick={ () => this.changeStatus("myshixun_count")}>最热</span>
{/*<div className="fr mr5 search-new">*/}
{/*/!* <Search*/}
{/*placeholder="请输入路径名称进行搜索"*/}

@ -1,3 +1,123 @@
.pathImg{
background: #4CACFF
}
.pathIndexNav{
box-shadow:0px 4px 8px 0px rgba(0,0,0,0.04);
}
.pathIndexNav ul li{
float: left;
margin-right: 10px;
}
.pathIndexNav ul li a{
display: block;
font-size: 15px;
color: #333333;
padding:0px 20px;
border-radius:18px;
height: 32px;
line-height: 32px;
margin:5px 0px;
}
.pathIndexNav ul li.active a{
background: #DDECF9;
color: #4CACFF
}
/* 首页-最新最热 */
.mainPageArray span{
font-size: 14px;
float: left;
background: #EBEBEB;
padding: 0px 16px;
height: 30px;
line-height: 30px;
color: #666666;
margin-right: 20px;
cursor: pointer;
border-radius: 15px;
}
.mainPageArray span.active{
background: #4CACFF;
color: #fff;
}
/* path-card */
.squareCard{
position: relative;
width: 280px;
margin-right: 26px;
margin-bottom: 40px;
float: left;
border-radius: 6px;
}
.squareCard:nth-child(4n){
margin-right: 0px;
}
.squareCard .squareImg{
height: 175px;
width: 280px;
overflow: hidden;
display: block;
border-radius: 6px;
}
.squareCard .squareImg img{
transition: all 0.6s;
-webkit-transition: all 0.6s;
-o-transition: all 0.6s;
width: 100%;
}
.squareCard .squareImg img:hover{
transform: scale(1.2);
}
/* card info */
.cardName{
font-size: 16px;
font-weight: 600;
height: 20px;
line-height: 20px;
margin-bottom: 10px;
}
.squareLine:after{
position: absolute;
width: 1px;
height: 10px;
background: #adadad;
content: '';
right: -10px;
top:4px;
}
.squareInfo{
color: #777;
font-size: 12px;
font-weight: 400;
height: 18px;
line-height: 18px;
}
/* tag-开放课程 */
.tag_open {
position: absolute;
left: 0px;
top: 12px;
z-index: 1;
}
.tag_open .tag_open_name {
display: block;
width: auto;
background-color: #FF6800;
background-size: 100% 100%;
padding: 0px 8px;
color: #fff;
display: block;
height: 28px;
line-height: 28px;
border-radius: 0px 15px 15px 0px;
}
.paragraph:hover .status_li a{
display: block;
}

@ -295,11 +295,11 @@
.topsj{
position: absolute;
top: -6px;
top: -3px;
}
.bottomsj{
position: absolute;
bottom: -6px;
bottom: -5px;
}
.touchSelect .ant-spin-dot-spin{
margin-top: 30% !important;

@ -0,0 +1,45 @@
import React, { Component } from 'react';
import { Redirect } from 'react-router';
import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom";
import Loading from '../../Loading'
import Loadable from 'react-loadable';
import { TPMIndexHOC } from '../tpm/TPMIndexHOC'
import { SnackbarHOC } from 'educoder'
const PackageIndex = Loadable({
loader: () => import('../user/usersInfo/InfosTopics'),
loading: Loading,
})
class Topic_bank extends Component {
constructor(props) {
super(props)
}
componentDidMount(){
}
render() {
return (
<div className="newMain clearfix">
<Switch>
<Route path="/topicbank/:username/:topicstype"
render={
(props) => (<PackageIndex {...this.props} {...props} {...this.state} />)
}
></Route>
</Switch>
</div>
);
}
}
export default SnackbarHOC() (TPMIndexHOC (Topic_bank)) ;

@ -2,7 +2,7 @@ import React, { Component } from "react";
import { message, Icon, Input, Form, Upload} from "antd";
import axios from 'axios'
import ModalWrapper from "../../courses/common/ModalWrapper"
import { City, getUploadActionUrl, getImageUrl, ImageLayerHook } from 'educoder'
import { City, getUploadActionUrl, getImageUrl, ImageLayerHook, getUploadActionUrlOfAuth } from 'educoder'
import '../account/common.css'
import authImg from '../../../images/account/auth.png'
@ -125,14 +125,14 @@ class RealNameCertificationModal extends Component{
const { moduleName } = this.props
const { getFieldDecorator } = this.props.form;
let {certification}=this.props;
// /api/users/accounts/${this.props.current_user.login}/auth_attachment.json
const uploadProps2 = {
name: 'image',
data:{type:certification == 1 ? "real_name" : "professional"},
multiple: true,
showUploadList: false,
// https://newweb.educoder.net
action: this.props.current_user ? `/api/users/accounts/${this.props.current_user.login}/auth_attachment.json` : '',
action: this.props.current_user ? `${getUploadActionUrlOfAuth(this.props.current_user.login)}` : '',
className: 'idPic-uploader',
onChange: this.handleChange2,
};

@ -43,7 +43,10 @@ const InfosVideo = Loadable({
loader: () => import('./video/InfosVideo'),
loading:Loading,
})
const InfosTopics=Loadable({
loader: () => import('./InfosTopics'),
loading:Loading,
})
const $ = window.$;
class Infos extends Component{
@ -258,13 +261,10 @@ class Infos extends Component{
<Switch {...this.props}>
{/* --------------------------------------------------------------------- */}
{/* 众包 */}
{/* http://localhost:3007/courses/1309/homework/9300/setting */}
<Route exact path="/users/:username/package"
{/* 题库 */}
<Route exact path="/users/:username/topics/:topicstype"
render={
(props) => (<InfosPackage {...this.props} {...props} {...this.state} {..._commonProps}/>)
(props) => (<InfosTopics {...this.props} {...props} {...this.state} {..._commonProps}/>)
}
></Route>
@ -297,7 +297,15 @@ class Infos extends Component{
}
></Route>
{/* 项目 */}
{/* 众包 */}
{/* http://localhost:3007/courses/1309/homework/9300/setting */}
<Route exact path="/users/:username/package"
render={
(props) => (<InfosPackage {...this.props} {...props} {...this.state} {..._commonProps}/>)
}
></Route>
{/* 视频 */}
<Route exact path="/users/:username/videos"
render={
(props) => (<InfosVideo {...this.props} {...props} {...this.state} {..._commonProps}/>)
@ -305,6 +313,7 @@ class Infos extends Component{
></Route>
<Route exact path="/users/:username"
render={
(props) => (<InfosCourse {...this.props} {...props} {...this.state} {..._commonProps}/>)

@ -27,6 +27,14 @@ class InfosBanner extends Component{
let {pathname}=this.props.location;
moduleName=pathname.split("/")[3];
let user_id=this.props.current_user&&this.props.current_user.user_id;
let user_type=this.props.current_user&&this.props.current_user.user_identity;
let targetuserid=this.props.data&&this.props.data.id;
// console.log(is_current)
// console.log(current_user)
// console.log(current_user.is_teacher)
// console.log(current_user.admin)
return(
<div className="bannerPanel mb60">
<div className="educontent">
@ -115,6 +123,14 @@ class InfosBanner extends Component{
to={`/users/${username}/videos`}>视频</Link>
</li>}
{/*自己的主页且不是学生显示题库按钮*/}
{((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin)
&&<li className={`${moduleName == 'topics' ? 'active' : '' }`}>
<Link
onClick={() => this.setState({moduleName: 'topics'})}
to={`/users/${username}/topics/personal`}>题库</Link>
</li>}
</div>
</div>
</div>

@ -125,6 +125,7 @@ class InfosCourse extends Component{
<span className="fr color-grey-9">时间最新</span>
</p>
<div className="square-list clearfix">
{/* 289 */}
{
page == 1 && is_current && !category &&
this.props.current_user && this.props.current_user.user_identity != "学生" ? <Create href={"/courses/new"} name={"新建课堂"} index="1"></Create> : ""
@ -135,7 +136,7 @@ class InfosCourse extends Component{
{
data && data.courses && data.courses.map((item,key)=>{
return(
<div className="square-Item" onClick={()=>this.turnToCourses(`${item.first_category_url}`,item.can_visited)} style={{"cursor": "pointer"}}>
<div className="square-Item" onClick={()=>this.turnToCourses(`${item.first_category_url}`,item.can_visited)} style={{"cursor": "pointer",height:"289px"}}>
{
item.is_public == 1 &&
<React.Fragment>

@ -147,6 +147,7 @@ class InfosPath extends Component{
<span className="fr color-grey-9">时间最新</span>
</div>
<div className="square-list clearfix">
{/* 295 */}
{
page == 1 && is_current && !category &&
this.props.current_user && this.props.current_user.user_identity != "学生" ? <Create href={"/paths/new"} name={"新建实践课程"} index="3"></Create>:""

@ -120,6 +120,7 @@ class InfosProject extends Component{
<span className="fr color-grey-9">时间最新</span>
</p>
<div className="square-list clearfix">
{/* 289 */}
{
page == 1 && is_current && this.props.current_user && !category && this.props.current_user.user_identity != "学生" ?
<Create href={`${this.props.Headertop && this.props.Headertop.old_url}/projects/new`} name={"新建开发项目"} index="4"></Create>:""
@ -130,7 +131,7 @@ class InfosProject extends Component{
{
data && data.projects && data.projects.map((item,key)=>{
return(
<div className="square-Item" onClick={()=>this.turnToCourses(`/projects/${item.id}`,item.can_visited)} style={{"cursor": "pointer"}}>
<div className="square-Item" onClick={()=>this.turnToCourses(`/projects/${item.id}`,item.can_visited)} style={{"cursor": "pointer","height":"289px"}}>
{
item.is_public==1 &&
<React.Fragment>

@ -153,6 +153,7 @@ class InfosShixun extends Component{
</div>
</div>
<div className="square-list clearfix">
{/* 298 */}
{
page == 1 && is_current && !category && this.props.current_user && this.props.current_user.user_identity != "学生" ?
<Create href={"/shixuns/new"} name={"新建实训"} index="2"></Create>:""
@ -163,7 +164,7 @@ class InfosShixun extends Component{
{
data && data.shixuns && data.shixuns.map((item,key)=>{
return(
<div className="square-Item" onClick={()=>this.turnToCourses(`/shixuns/${item.identifier}/challenges`)}>
<div className="square-Item" style={{"height":"298px"}} onClick={()=>this.turnToCourses(`/shixuns/${item.identifier}/challenges`)}>
{
item.tag && <div className="tag-green"><span className="tag-name">{item.tag}</span><img className="fl" src={setImagesUrl("images/educoder/tag2.png")}/></div>
}

@ -0,0 +1,589 @@
import React, { Component } from 'react';
import { SnackbarHOC } from 'educoder';
import {BrowserRouter as Router,Route,Switch,Link} from 'react-router-dom';
import {Tooltip,Menu,Pagination,Spin, Dropdown,Checkbox} from 'antd';
import axios from 'axios';
import {getImageUrl,WordsBtn} from 'educoder';
import moment from 'moment';
import Modals from '../../modals/Modals';
import SendTopics from '../../modals/SendTopics'
import NoneData from '../../courses/coursesPublic/NoneData';
import "./usersInfo.css";
import Withoutpermission from './Withoutpermission.png';
class InfosTopics extends Component{
constructor(props){
super(props);
this.state={
isSpin:false,
category:"normal",
course_list_id:undefined,
sort_by:"updated_at",
sort_direction:"desc",
page:1,
data:undefined,
checkBoxValues:[],
per_page:15,
isshowprofes:false
}
}
componentDidMount(){
let types=this.props.match.params.topicstype;
let professional_certification=this.props.current_user&&this.props.current_user.professional_certification;
if(professional_certification===false&&types==="publicly"){
this.setState({
isshowprofes:true
})
}else{
this.updataslist()
}
}
componentDidUpdate(prevProps) {
if(prevProps.current_user!=this.props.current_user){
let types=this.props.match.params.topicstype;
let professional_certification=this.props.current_user&&this.props.current_user.professional_certification;
console.log(professional_certification)
if(professional_certification===false&&types==="publicly"){
this.setState({
isshowprofes:true
})
}else{
this.updataslist()
}
}
}
updataslist=()=>{
let types=this.props.match.params.topicstype;
let { category,course_list_id,sort_by,sort_direction,page}=this.state;
this.searchAlldata(types,category,course_list_id,sort_by,sort_direction,page)
}
searchAlldata=(type,category,course_list_id,sort_by,sort_direction,page)=>{
// if(this.props.current_user.login!=this.props.match.params.username){
// return
// }else{
//
// }
this.setState({
isSpin:true
})
let types=this.props.match.params.topicstype;
let user_id="";
if(types==="publicly"){
user_id=this.props.current_user&&this.props.current_user.login;
}else{
user_id=this.props.match.params&&this.props.match.params.username;
}
if(user_id!=undefined){
console.log(user_id)
let {per_page}=this.state;
let url=`/users/${user_id}/question_banks.json`;
axios.get(encodeURI(url),{params:{
type,
object_type:category,
course_list_id,
sort_by,
sort_direction,
page,
per_page
}
}).then((response) => {
this.setState({
data:response.data,
checkBoxValues:[],
isSpin:false
})
}).catch((error) => {
this.setState({
isSpin:false
})
});
}
}
searchCategory=(type)=>{
this.setState({
category:type,
course_list_id:undefined,
})
let types=this.props.match.params.topicstype;
let { category,course_list_id,sort_by,sort_direction,page}=this.state;
this.searchAlldata(types,type,undefined,sort_by,sort_direction,page)
}
searchCourselistid=(id)=>{
this.setState({
course_list_id:id
})
let types=this.props.match.params.topicstype;
let { category,course_list_id,sort_by,sort_direction,page}=this.state;
this.searchAlldata(types,category,id,sort_by,sort_direction,page)
}
onCheckBoxChange=(checkedValues)=>{
if(checkedValues.length>15){
this.props.showNotification("选择条数不能大于15条")
}else{
this.setState({
checkBoxValues:checkedValues
})
}
}
updatedlist=(updatedtype)=>{
let types=this.props.match.params.topicstype;
let { category,course_list_id,sort_by,sort_direction,page}=this.state;
if(updatedtype===sort_by){
if(sort_direction==="desc"){
this.setState({
sort_direction:"asc",
sort_by:updatedtype
})
this.searchAlldata(types,category,course_list_id,updatedtype,"asc",page)
}else{
this.setState({
sort_direction:"desc",
sort_by:updatedtype
})
this.searchAlldata(types,category,course_list_id,updatedtype,"desc",page)
}
}else{
this.setState({
sort_direction:"desc",
sort_by:updatedtype
})
this.searchAlldata(types,category,course_list_id,updatedtype,"desc",page)
}
}
changePage=(pageNumber)=>{
let types=this.props.match.params.topicstype;
let { category,course_list_id,sort_by,sort_direction,page}=this.state;
this.searchAlldata(types,category,course_list_id,sort_by,sort_direction,pageNumber)
this.setState({
page:pageNumber,
checkBoxValues:[]
})
}
deletecheckBoxValues=()=>{
let {checkBoxValues}=this.state;
if(checkBoxValues.length===0){
this.props.showNotification("请选择题库")
}else{
this.setState({
Modalstype:true,
Modalstopval:"是否确认删除?",
ModalCancel:this.topicscancelmodel,
ModalSave:this.topicssavedelete,
})
}
}
topicssavedelete=()=>{
let {checkBoxValues,category}=this.state;
const url = `/question_banks/multi_delete.json`;
axios.delete(url, { data: {
object_id: checkBoxValues,
object_type:category
}})
.then((response) => {
if(response.data.status===0){
this.updataslist()
this.props.showNotification(response.data.message)
}else{
this.props.showNotification(response.data.message)
}
})
.catch(function (error) {
console.log(error);
});
this.topicscancelmodel()
}
topicscancelmodel=()=>{
this.setState({
Modalstype:false,
Loadtype:false,
visible:false,
Modalstopval:"",
ModalCancel:"",
ModalSave:"",
checkBoxValues:[],
checkedtype:false
})
}
openTopics=(id)=>{
this.setState({
Modalstype:true,
Modalstopval:"公开后不能重设为私有",
ModalsBottomval:"是否确认设为公开?",
ModalCancel:this.topicscancelmodel,
ModalSave:()=>this.topicssaveonOpen(id),
})
}
topicssaveonOpen=(id)=>{
let {category}=this.state;
const url = `/question_banks/multi_public.json`;
axios.post(url,{
object_id:[id],
object_type:category
}).then((response) => {
if(response.data.status===0){
this.updataslist()
this.props.showNotification(response.data.message)
}else{
this.props.showNotification(response.data.message)
}
}).catch(function (error) {
console.log(error);
});
this.topicscancelmodel()
}
sendTopics=()=>{
let {checkBoxValues}=this.state;
if(checkBoxValues.length===0){
this.props.showNotification("请选择题库")
}else{
this.setState({
visible:true
})
}
}
render(){
let{
category,
course_list_id,
isSpin,
data,
page,
sort_direction,
sort_by,
checkBoxValues,
Modalstype,
visible,
isshowprofes
} = this.state;
let {
is_current,
current_user,
}=this.props;
let categorylist=[
{val:"普通作业",type:"normal"},
{val:"分组作业",type:"group"},
{val:"毕设选题",type:"gtopic"},
{val:"毕设任务",type:"gtask"},
{val:"试卷",type:"exercise"},
{val:"问卷",type:"poll"},
]
let types=this.props.match.params.topicstype;
let username=this.props.match.params.username;
//types===publicly 公共
//types===personal 私有
let user_id=this.props.current_user&&this.props.current_user.user_id;
let user_type=this.props.current_user&&this.props.current_user.user_identity;
let targetuserid=this.props.data&&this.props.data.id;
// console.log(is_current)
// console.log(current_user)
// console.log(current_user.is_teacher)
// console.log(current_user.admin)
const menu = (
<Menu>
<Menu.Item onClick={()=>this.updatedlist("updated_at")}>
最近更新
</Menu.Item>
<Menu.Item onClick={()=>this.updatedlist("name")}>
题目名称
</Menu.Item>
{types==="publicly"?<Menu.Item onClick={()=>this.updatedlist("contributor")}>
贡献者
</Menu.Item>:""}
</Menu>
);
return(
<div className="educontent mb50 mt40">
{/*提示*/}
<style>
{
`
.mt40{
margin-top: 40px !important;
}
`
}
</style>
{Modalstype&&Modalstype===true?<Modals
modalsType={this.state.Modalstype}
modalsTopval={this.state.Modalstopval}
modalCancel={this.state.ModalCancel}
modalSave={this.state.ModalSave}
modalsBottomval={this.state.ModalsBottomval}
loadtype={this.state.Loadtype}
/>:""}
{/*发送至弹窗*/}
{
visible&&visible===true?
<SendTopics
{...this.state}
{...this.props}
visible={visible}
updataslist={()=>this.updataslist()}
topicscancelmodel={()=>this.topicscancelmodel()}
/>:""
}
<style>
{
`
::-webkit-scrollbar-thumb {
background-color: #cde5fe;
box-shadow: 0px 0px black;
}
::-webkit-scrollbar-track {
-webkit-box-shadow: inset 0 0 6px rgba(0, 0, 0, 0);
background-color: #fff;
}
.shaiContent li.shaiItem {
padding: 0px 9px;
float: left;
border-radius: 4px;
cursor: pointer;
margin-right: 15px !important;
display: block;
margin-bottom: 2px;
color: #666;
}
.maxwidth900{
max-width: 900px;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap
}
.homepagePostSettingname{
width:192px !important;
}
.homepagePostSettingbox{
width:139px !important;
}
.marright0{
margin-right: 0px !important;
}
.gongkais{
min-width: 50px;
height: 22px !important;
line-height: 22px !important;
color: #fff !important;
margin-top: 4px;
}
`
}
</style>
<Spin size="large" spinning={isSpin}>
<div className="clearfix topicsbox">
{types==="publicly"?<div className={"topcschild"}>
<a className={types==="personal"?"topicstopfont fr ":"topicstopfont fr topcsactive"}
href={`/users/${this.props.current_user&&this.props.current_user.login}/topics/personal`}>我的题库</a>
<div className={types==="publicly"?"topicstopfont fl ":"topicstopfont fl topcsactive"}
>公共题库</div>
</div>:<div className={"topcschild"}>
<div className={types==="personal"?"topicstopfont fl ":"topicstopfont fl topcsactive"}
>我的题库</div>
<a className={types==="publicly"?"topicstopfont fr ":"topicstopfont fr topcsactive"}
href={`/topicbank/${this.props.current_user&&this.props.current_user.login}/publicly`}
>公共题库</a>
</div>}
{isshowprofes===false?
<div>
<div className={"topcsmid"}>
{categorylist.map((item,key)=>{
return(
<span key={key} className={category===item.type?"topicsmidfont fl mr30 topcsactive":"topicsmidfont fl mr30"} onClick={()=>this.searchCategory(item.type)}>{item.val}</span>
)
})}
</div>
{data&&data.count===undefined?"":data&&data.count===0?"":<div className={data===undefined?"":data.course_list===undefined||data.course_list.length===0?"shaiContent mb45":"shaiContent"}>
<li className={course_list_id===undefined?"shaiItem shixun_repertoire active fl":"shaiItem shixun_repertoire fl"} onClick={()=>this.searchCourselistid(undefined)}>全部</li>
<div className="fl pr topicsItem mb20">
{data===undefined?"":data.course_list===undefined||data.course_list.length===0?"":data.course_list.map((item,key)=>{
return(
<li key={key} className={course_list_id===item.id?"shaiItem shixun_repertoire active marright0":"shaiItem shixun_repertoire marright0"} onClick={()=>this.searchCourselistid(item.id)}>{item.name}</li>
)
})}
</div>
</div>}
</div>:<div className={"professional_certificationbox"}>
<p className="clearfix ">
<div className={"stud-class-set pd115200 coursenavbox edu-back-white"}>
<div className={"sumbtongs mb10"}><img className={"topicsItemimg"} src={Withoutpermission}/></div>
<div className={"terraces mb5 topicsItemfont"}>通过职业认证的教师才能访问公共题库</div>
<div className="clearfix mt30 mb30 padding251">
<a className="defalutSubmitbtn fl ml60 defalutSubmitbtns" target="_blank" href="/account/certification">立即认证</a>
</div>
</div>
</p>
</div>}
</div>
{isshowprofes===false?data&&data.count===undefined?"":data&&data.count===0?"":<div className="clearfix font-12 mt20">
<p className="font-12 ml5 fl">
<span className="fl color-grey-9 mr20"> <span className={"color-orange"}>{data&&data.count===undefined?0:data&&data.count}</span> </span>
<span className="fr color-grey-9">已选择 <span className={"color-orange"}>{checkBoxValues.length}</span> ()</span>
</p>
<p className="font-12 alltopiscright ml25 fr">
<style>
{
`
.yslbottomsj{
position: absolute;
bottom: -8px;
}
`
}
</style>
<Dropdown overlay={menu}>
<span className="fr color-grey-9 mr10 pointer ">
<span>{sort_by==="updated_at"?'最近更新':sort_by==="name"?'题目名称':sort_by==="contributor"?"贡献者":""}</span>
<sapn className="relativef ml10" onClick={()=>this.updatedlist(sort_by)}>
<i className={sort_direction==="asc"?
"iconfont icon-sanjiaoxing-up font-12 topsj color-blue" :"iconfont icon-sanjiaoxing-up font-12 topsj"}></i>
<i className={sort_direction==="desc"?
"iconfont icon-sanjiaoxing-down font-12 yslbottomsj color-blue":"iconfont icon-sanjiaoxing-down font-12 yslbottomsj"}></i>
</sapn>
</span>
</Dropdown>
{user_type!="学生"?<span className="fr mr30 topcsactive pointer" onClick={()=>this.sendTopics()}>发送</span>:""}
{types==="personal"?((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin)
&&<span className="fr mr30 topcsactive pointer" onClick={()=>this.deletecheckBoxValues()}>删除</span>:""}
</p>
</div>:""}
{isshowprofes===true?"":data===undefined?<NoneData></NoneData>:data.question_banks===undefined||data.question_banks.length===0?<NoneData></NoneData>:
<Checkbox.Group style={{ width: '100%' ,minHeight:'297px'}} onChange={this.onCheckBoxChange} value={checkBoxValues}>
{data.question_banks.map((item,key)=>{
return(
<div className="mt20 edu-back-white pd1323 relativef" key={key} >
<div className="clearfix">
<div className="item-body">
<div className="clearfix ds pr pt10 contentSection" >
{user_type!="学生"?<Checkbox value={item.id} key={item.id} className={"fl mt5"}></Checkbox>:""}
<a title={item.name.length>55?item.name:""} className="ml10 fl mt3 font-16 color-dark maxwidth900" href={
category==="normal"?`/banks/normal/${item.id}/${types}?tab=0`:
category==="group"?`/banks/group/${item.id}/${types}?tab=0`:
category==="poll"?`/banks/poll/${item.id}/${types}`:
category==="exercise"?`/banks/exercise/${item.id}/${types}`:
category==="gtask"?`/banks/gtask/${item.id}/${types}`:
category==="gtopic"?`/banks/gtopic/${item.id}/${types}`:""
}
>
{item.name}
</a>
{item.is_public===true?types==="publicly"?"":<span className="edu-filter-btn edu-filter-btn-4CACFF ml15 fl gongkais">公开</span>:""}
<div className="cl"></div>
<p className="color-grey panel-lightgrey mt16 fl">
<span className={"topicswidth600"}>
{types==="publicly"?<span className="topsics135 color-grey9 mr50">{item.creator_name}</span>:""}
<span className="mr50 color-grey9">{item.quotes_count} 次引用</span>
<span className="mr50 color-grey9">{item.solve_count} 次答题</span>
<span className="mr50 color-grey9">{moment(item.updated_at).fromNow()}</span>
</span>
{item.course_list_name===null?"":<span className={"topsicrelative topsicinline"} title={item.course_list_name}>
<div className={types==="personal"?"topicsbtn topsicsmax550":"topsicsmax550 topicsbtn"}>{item.course_list_name}</div>
</span>}
</p>
<div className="homepagePostSetting homepagePostSettingname topscisright">
{types==="personal"?((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin)
&&<a className="btn colorblue mr25 font-16 fr"
href={category==="normal"?`/banks/normal/${item.id}/edit/${types}`:
category==="group"?`/banks/group/${item.id}/edit/${types}`:
category==="poll"?`/banks/poll/${item.id}/edit/${types}`:
category==="exercise"?`/banks/exercise/${item.id}/edit/${types}`:
category==="gtask"?`/banks/gtask/${item.id}/edit/${types}`:
category==="gtopic"?`/banks/gtopic/${item.id}/edit/${types}`:""
}
>编辑</a>
:""}
{types==="personal"&&item.is_public===false?((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin)
&&<a className="btn colorblue mr25 fr font-16" onClick={()=>this.openTopics(item.id)}>设为公开</a>:""}
</div>
</div>
</div>
</div>
</div>
)})}
</Checkbox.Group>
}
{
isshowprofes===true?"":data&&data.count >15 &&
<div className="mt30 mb50 edu-txt-center">
<Pagination showQuickJumper total={data&&data.count} onChange={this.changePage} pageSize={15} current={page}/>
</div>
}
</Spin>
</div>
)
}
}
export default InfosTopics;

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

@ -72,16 +72,32 @@ class BanksIndex extends Component{
constructor(props){
super(props);
this.state={
crumbData:undefined
crumbData:undefined,
publicly:undefined
}
}
componentDidMount = () =>{
let pathname = this.props.location.pathname;
this.setState({
publicly:pathname.indexOf("/publicly") > -1
})
}
initPublic = (crumbData) =>{
this.setState({
crumbData
})
}
componentDidUpdate=()=>{
let { publicly }=this.state
if(this.props.current_user && this.props.current_user.professional_certification == false && publicly){
this.props.history.push(`/topicbank/${this.props.current_user.login}/publicly`);
}
}
render(){
let { crumbData }=this.state
const common = {
@ -93,7 +109,7 @@ class BanksIndex extends Component{
{
crumbData &&
<Breadcrumb separator=">" className="breadcrumb mt22">
<Breadcrumb.Item href="/users/innov/topics/personal">题库</Breadcrumb.Item>
<Breadcrumb.Item href={crumbData && crumbData.is_public == true ?`/topicbank/${this.props.current_user && this.props.current_user.login}/publicly`:`/users/${this.props.current_user && this.props.current_user.login}/topics/personal`}>{ crumbData && crumbData.is_public == true ? '公共' : '我的' }题库</Breadcrumb.Item>
{
crumbData.crumbArray && crumbData.crumbArray.map((item,key)=>{
return(
@ -105,23 +121,26 @@ class BanksIndex extends Component{
}
{
crumbData &&
<p className="clearfix mt10 mb10 ">
<span className="fl font-24 color-grey-3 task-hide lineh-30" style={{maxWidth:'800px'}}>{crumbData && crumbData.title}</span>
<span className="bank_is_public">{crumbData.is_public == true ? '公开':'私有'}</span>
</p>
}
crumbData &&<p className="clearfix mt15 mb10 ">
<span className="fl font-24 color-grey-3 task-hide lineh-30" style={{maxWidth:'800px'}}>{crumbData && crumbData.title}</span>
{ crumbData.is_public == true ?
<span className="bank_is_public">公开</span>
:
<span className="bank_is_private">私有</span>
}
</p> }
<Switch {...this.props}>
{/*毕设任务编辑*/}
<Route path='/banks/gtask/:workId/edit'
<Route path='/banks/gtask/:workId/edit/:type'
render={
(props) => {
return (<GtaskBanksEdit {...this.props} {...props} {...this.state} {...common}/>)
}
}></Route>
<Route path='/banks/normal/:workId/edit'
<Route path='/banks/normal/:workId/edit/:type'
render={
(props) => {
return (<HomeworkBanksEdit {...this.props} {...props} {...this.state} {...common}
@ -130,7 +149,7 @@ class BanksIndex extends Component{
}
}></Route>
<Route path='/banks/group/:workId/edit'
<Route path='/banks/group/:workId/edit/:type'
render={
(props) => {
return (<HomeworkBanksEdit {...this.props} {...props} {...this.state} {...common}
@ -139,7 +158,7 @@ class BanksIndex extends Component{
}
}></Route>
<Route path='/banks/exercise/:Id/edit'
<Route path='/banks/exercise/:Id/edit/:type'
render={
(props) => {
return (<ExerciseBanksEdit {...this.props} {...props} {...this.state} {...common}
@ -147,7 +166,8 @@ class BanksIndex extends Component{
}
}></Route>
<Route path='/banks/gtopic/:bankId/edit'
<Route path='/banks/gtopic/:bankId/edit/:type'
render={
(props) => {
return (<GtopicBanksEdit {...this.props} {...props} {...this.state} {...common}/>)
@ -156,40 +176,46 @@ class BanksIndex extends Component{
{/*题库问卷编辑详情*/}
<Route path="/banks/poll/:workid/edit"
<Route path="/banks/poll/:workid/edit/:type"
render={
(props) => (<PollNewQuestbank {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
<Route path='/banks/poll/:bankId'
<Route path='/banks/poll/:bankId/:type'
render={
(props) => {
return (<BanksTabIndex {...this.props} {...props} {...this.state} {...common} />)
}
}></Route>
{/*毕设任务题库详情*/}
<Route path="/banks/gtask/:workid"
<Route path='/banks/exercise/:Id/:type'
render={
(props) => {
return (<BanksTabIndex {...this.props} {...props} {...this.state} {...common}
/>)
}
}></Route>
{/*毕设任务题库详情*/}
<Route path="/banks/gtask/:workid/:type"
render={
(props) => (<Completetaskpage {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/*毕设内容题库详情*/}
<Route path="/banks/gtopic/:workid"
<Route path="/banks/gtopic/:workid/:type"
render={
(props) => (<CompletetopicdePage {...this.props} {...props} {...this.state} {...common}/>)
}
></Route>
{/*分组作业题库详情*/}
<Route path="/banks/group/:workid"
<Route path="/banks/group/:workid/:type"
render={
(props) => (<GroupjobbankPage {...this.props} {...props} {...this.state} {...common} />)
}
></Route>
{/* 普通作业题库详情*/}
<Route path="/banks/normal/:workid"
<Route path="/banks/normal/:workid/:type"
render={
(props) => (<Generaljobbankdetails {...this.props} {...props} {...this.state} {...common} />)
}

@ -0,0 +1,90 @@
import React, { Component } from 'react';
import {BrowserRouter as Router,Route,Switch} from 'react-router-dom';
import Loadable from 'react-loadable';
import Loading from '../../../../Loading';
import BanksMenu from './banksMenu'
// 毕设选题
const GtopicBanks = Loadable({
loader: () => import('./GtopicBanks'),
loading: Loading,
})
// 问卷内容
const PollBanks = Loadable({
loader: () => import('./PollBanksContent'),
loading: Loading,
})
// 试卷详情
const ExerciseBanksDetail = Loadable({
loader: () => import('./ExerciseBanksDetail'),
loading: Loading,
});
class BanksTabIndex extends Component{
constructor(props){
super(props);
this.state={
banksMenu:undefined
}
}
initPublic = (crumbData,menuData) =>{
this.setState({
banksMenu:menuData
})
this.props.initPublic(crumbData);
}
render(){
let{
banksMenu
}=this.state
const common={
initPublic:this.initPublic,
};
console.log("BanksTabIndex");
console.log(banksMenu);
console.log(this.props);
return(
<React.Fragment>
{
banksMenu &&
<BanksMenu
banksMenu={banksMenu}
{...this.props}
{...this.state}
{...common}
></BanksMenu>
}
<Switch {...this.props}>
<Route path={`/banks/exercise/:Id/:type`}
render={
(props) => {
return (<ExerciseBanksDetail {...this.props} {...props} {...this.state} {...common}
/>)
}
}></Route>
<Route path={`/banks/gtopic/:bankId/:type`}
render={
(props) => {
return (<GtopicBanks {...this.props} {...props} {...this.state} {...common} />)
}
}></Route>
<Route path={`/banks/poll/:bankId/:type`}
render={
(props) => {
return (<PollBanks {...this.props} {...props} {...this.state} {...common} />)
}
}></Route>
</Switch>
</React.Fragment>
)
}
}
export default (BanksTabIndex);

@ -0,0 +1,56 @@
import React, { Component } from 'react';
import axios from 'axios'
import ExerciseDisplay from '../../../courses/exercise/ExerciseDisplay'
class ExerciseBanksDetail extends Component{
constructor(props){
super(props);
this.state={
}
}
componentDidMount = () =>{
}
detailFetchCallback = (result) => {
let Id=this.props.match.params.Id;
const crumbData={
title: result.data.exercise && result.data.exercise.name,
is_public: result.data.exercise && result.data.exercise.is_public,
crumbArray:[
{content:'详情'},
]
}
const menuData={
tab:'0',//tab选中的index
menuArray:[//tab以及tab路由
{to:`/banks/exercise/${Id}/${this.props.match.params.type}?tab=0`,content:'内容详情'}
],
category:'exercise',//
tos: `/banks/exercise/${Id}/edit/${this.props.match.params.type}`,
id: Id,
is_public: result.data.exercise && result.data.exercise.is_public,
type:this.props.match.params.type,
authorize:result && result.data && result.data.authorize,
}
this.props.initPublic(crumbData,menuData);
}
render(){
let { pollDetail } = this.state
return(
<div>
<ExerciseDisplay {...this.props} {...this.state}
urlPath = {'exercise_banks'}
detailFetchCallback={this.detailFetchCallback}
>
</ExerciseDisplay>
</div>
)
}
}
export default ExerciseBanksDetail

@ -0,0 +1,71 @@
import React, { Component } from 'react';
import axios from 'axios'
import { ActionBtn } from 'educoder'
import ExerciseNewCommon from '../../../courses/exercise/ExerciseNewCommon'
class ExerciseBanksEdit extends Component {
constructor(props){
super(props);
this.state = {
isPublic: undefined,
// isGroup: false
}
}
componentDidMount = () =>{
}
initData = (responseData) =>{
const Id = this.props.match.params.Id;
const crumbData={
title:'编辑',
is_public: responseData && responseData.data && responseData.data.exercise.is_public,
crumbArray:[
{to:`/banks/exercise/${Id}/${this.props.match.params.type}`,content:'详情'},
{content:'编辑'}
]
}
this.props.initPublic(crumbData);
}
render(){
let { Id, type } = this.props.match.params
const common = {
// onCancel:this.onCancel,
// isGroup: this.isGroup,
// doNew: this.doNew,
// doEdit: this.doEdit,
initData: this.initData
}
return(
<div className="courseForm">
<style>
{`
.courseForm .ant-col-sm-24{
text-align:left;
}
`}
</style>
<ExerciseNewCommon
{...this.props}
{...this.state}
{...common}
hidePreviewButton={true}
wrappedComponentRef={(ref) => this.exerciseNewCommonRef = ref}
isEdit={true}
shixunsUrl={`/exercise_banks/choose_shixun.json`}
exercise_url={'exercise_banks'}
exercise_url_questions={'exercise_bank_questions'}
bottomSection={<ActionBtn style="blue" className="fr" to={`/banks/exercise/${Id}/${this.props.match.params.type}`}>
完成
</ActionBtn>}
></ExerciseNewCommon>
</div>
)
}
}
export default ExerciseBanksEdit;

@ -0,0 +1,99 @@
import React, { Component } from 'react';
import axios from 'axios'
import NewGtaskForm from './NewGtaskForm';
import NewWorkForm from "./HomeworkBanksEdit";
class GtaskBanksEdit extends Component {
constructor(props){
super(props);
this.state = {
isPublic: undefined,
isGroup: false
}
}
componentDidMount = () =>{
let workId = this.props.match.params.workId;
this.initData(workId);
}
initData = (workId) =>{
let url = `/task_banks/${workId}.json`;
axios.get(url).then((result)=>{
if(result){
const crumbData={
title:'编辑',
is_public:result && result.data && result.data.is_public,
crumbArray:[
{to:`/banks/gtask/${workId}/${this.props.match.params.type}?tab=0`,content:'详情'},
{content:'编辑'}
]
}
this.props.initPublic(crumbData);
result.data.isEdit = true;
this.setState({ data:result.data})
this.newWorkFormRef.initValue(result.data);
}
}).catch((error)=>{
console.log(error)
})
}
doNew = () => {
}
doEdit = (params) => {
const workId = this.props.match.params.workId
const newUrl = `/homework_banks/${workId}.json`
// const isGroup = this.props.isGroup()
axios.put(newUrl, params)
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('保存成功')
this.toWorkDetail()
}
})
.catch(function (error) {
console.log(error);
});
}
toWorkDetail = () => {
this.props.history.push(`/banks/gtask/${this.props.match.params.workId}/${this.props.match.params.type}`);
this.props.initPublic(undefined);
}
onCancel = () => {
this.toWorkDetail()
}
isGroup = () => {
return this.state.isGroup;
}
render(){
const common = {
onCancel:this.onCancel,
isGroup: this.isGroup,
doNew: this.doNew,
doEdit: this.doEdit,
}
return(
<div className="courseForm">
<style>
{`
.courseForm .ant-col-sm-24{
text-align:left;
}
`}
</style>
<NewGtaskForm
{...this.props}
{...this.state}
{...common}
wrappedComponentRef={(ref) => this.newWorkFormRef = ref}
topicId={this.props.match.params.workId}
></NewGtaskForm>
</div>
)
}
}
export default GtaskBanksEdit;

@ -0,0 +1,37 @@
import React, { Component } from 'react';
class GtopicBanks extends Component{
constructor(props){
super(props);
}
componentDidMount = () =>{
let bankId = this.props.match.params.bankId
const crumbData={
title:'MySQL数据库编程开发实训基础篇111',
is_public:true,
crumbArray:[
{content:'详情'},
]
}
const menuData={
tab:'0',//tab选中的index
menuArray:[//tab以及tab路由
{to:'/banks/gtopic/1',content:'内容详情'},
// {to:'/banks/gtopic/1/answer',content:'参考答案'},
],
category:'topic',//毕设选题
id:bankId,
is_public:true,
}
this.props.initPublic(crumbData,menuData);
}
render(){
return(
<div>
</div>
)
}
}
export default GtopicBanks;

@ -0,0 +1,89 @@
import React, { Component } from 'react';
import axios from 'axios'
import GraduateTopicNewFrom from '../../../courses/graduation/topics/GraduateTopicNewFrom'
class GtopicBanksEdit extends Component{
constructor(props){
super(props);
this.state = {
isPublic:undefined
}
}
componentDidMount = () =>{
let bankId = this.props.match.params.bankId;
this.initData(bankId);
}
initData = (bankId) =>{
let url = `/gtopic_banks/${bankId}/edit.json`;
axios.get(url).then((result)=>{
if(result){
const crumbData={
title:'编辑',
is_public:result && result.data.selected_data && result.data.selected_data.is_public,
crumbArray:[
{to:`/banks/gtopic/${bankId}/${this.props.match.params.type}?tab=0`,content:'详情'},
{content:'编辑'}
]
}
this.props.initPublic(crumbData);
this.GraduateTopicNewFromRef.initValue(result);
}
}).catch((error)=>{
console.log(error)
})
}
// 编辑保存
editSave = (param,attachments,bankId) =>{
const url = `/gtopic_banks/${bankId}.json`;
let params = {
gtopic_bank:param,
attachment_ids:attachments
}
axios.put(url,params).then((result)=>{
if(result){
this.props.showNotification('保存成功!');
this.props.history.push(`/banks/gtopic/${bankId}/${this.props.match.params.type}`);
}
}).catch((error)=>{
console.log(error);
})
}
// 取消
editCancel = () =>{
this.props.history.push(`/banks/gtopic/${this.props.match.params.bankId}/${this.props.match.params.type}`);
this.props.initPublic(undefined);
}
render(){
let { bankId } = this.props.match.params
const common = {
editSave:this.editSave,
editCancel:this.editCancel
}
return(
<div className="courseForm">
<style>
{`
.courseForm .ant-col-sm-24{
text-align:left;
}
`}
</style>
<GraduateTopicNewFrom
{...this.props}
{...this.state}
{...common}
wrappedComponentRef={(ref) => this.GraduateTopicNewFromRef = ref}
topicId={bankId}
></GraduateTopicNewFrom>
</div>
)
}
}
export default GtopicBanksEdit;

@ -0,0 +1,103 @@
import React, { Component } from 'react';
import axios from 'axios'
import NewWorkForm from '../../../courses/busyWork/NewWorkForm'
class HomeworkBanksEdit extends Component {
constructor(props){
super(props);
this.state = {
isPublic: undefined,
// isGroup: false
}
}
componentDidMount = () =>{
let workId = this.props.match.params.workId;
this.initData(workId);
}
initData = (workId) =>{
let url = `/homework_banks/${workId}.json`;
axios.get(url).then((result)=>{
if(result){
const crumbData={
title:'编辑',
is_public:result && result.data && result.data.is_public,
crumbArray:[
{to:`/banks/${this.getModuleName()}/${workId}/${this.props.match.params.type}?tab=0`,content:'详情'},
{content:'编辑'}
]
}
this.props.initPublic(crumbData);
result.data.isEdit = true;
result.data.ref_attachments = result.data.reference_attachments
// this.setState({ isGroup: result.data.min_num || result.data.max_num })
this.newWorkFormRef.initValue(result.data);
}
}).catch((error)=>{
console.log(error)
})
}
doNew = () => {
}
doEdit = (params) => {
const workId = this.props.match.params.workId
const newUrl = `/homework_banks/${workId}.json`
// const isGroup = this.props.isGroup()
axios.put(newUrl, params)
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('保存成功')
this.toWorkDetail()
}
})
.catch(function (error) {
console.log(error);
});
}
getModuleName = () => {
return this.props.isGroup ? 'group' : 'normal'
}
toWorkDetail = () => {
this.props.history.push(`/banks/${this.getModuleName()}/${this.props.match.params.workId}/${this.props.match.params.type}`)
this.props.initPublic(undefined);
}
onCancel = () => {
this.toWorkDetail()
}
isGroup = () => {
return this.props.isGroup;
}
render(){
let { bankId } = this.props.match.params
const common = {
onCancel:this.onCancel,
isGroup: this.isGroup,
doNew: this.doNew,
doEdit: this.doEdit,
}
return(
<div className="courseForm">
<style>
{`
.courseForm .ant-col-sm-24{
text-align:left;
}
`}
</style>
<NewWorkForm
{...this.props}
{...this.state}
{...common}
wrappedComponentRef={(ref) => this.newWorkFormRef = ref}
></NewWorkForm>
</div>
)
}
}
export default HomeworkBanksEdit;

@ -0,0 +1,357 @@
import React,{ Component } from "react";
import { Input, InputNumber, Form, Button, Checkbox, Upload, Icon, message, Modal } from "antd";
import axios from 'axios'
import { WordsBtn, getUrl, ConditionToolTip, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll } from 'educoder'
import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor';
const $ = window.$;
const MAX_TITLE_LENGTH = 60;
class NewGtaskForms extends Component{
constructor(props){
super(props);
this.contentMdRef = React.createRef();
this.state={
title_num:0,
description:"",
contentFileList: [],
}
}
initValue = (data) => {
if (data.isEdit) {
const contentFileList = data.attachments.map(item => {
return {
id: item.id,
uid: item.id,
name: appendFileSizeToUploadFile(item),
url: item.url,
filesize: item.filesize,
status: 'done'
}
})
this.setState({
...data,
base_on_project: data.group_info.base_on_project,
title_num: parseInt(data.name.length),
min_num: data.group_info.min_number,
max_num: data.group_info.max_number,
contentFileList,
}, () => {
setTimeout(() => {
this.contentMdRef.current.setValue(data.description || '')
}, 2000)
this.props.form.setFieldsValue({
title: data.name,
description: data.description || '',
});
})
} else { // new
}
}
// 输入title
changeTitle=(e)=>{
console.log(e.target.value.length);
this.setState({
title_num: parseInt(e.target.value.length)
})
}
handleContentUploadChange = (info) => {
let contentFileList = info.fileList;
this.setState({ contentFileList: appendFileSizeToUploadFileAll(contentFileList) });
}
deleteAttachment = (file, stateName) => {
// 初次上传不能直接取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[stateName].indexOf(file);
const newFileList = state[stateName].slice();
newFileList.splice(index, 1);
return {
[stateName]: newFileList,
};
});
}
}
})
.catch(function (error) {
console.log(error);
});
}
onAttachmentRemove = (file, stateName) => {
if(file.response!=undefined){
this.props.confirm({
content: '是否确认删除?',
onOk: () => {
this.deleteAttachment(file, stateName)
},
onCancel() {
console.log('Cancel');
},
});
return false;
}
}
handleSubmit = () => {
let {contentFileList,min_num,max_num,base_on_project}=this.state;
let {data}=this.props;
let task_type=data.task_type
let topicId=this.props.topicId
this.props.form.validateFieldsAndScroll((err, values) => {
const mdContnet = this.contentMdRef.current.getValue().trim();
values.description = mdContnet;
if (!err) {
if (this.state.isEdit) {
let url="/task_banks/"+topicId+".json";
axios.put(url, {
gtask_bank: {
name: values.title,
description: values.description,
min_num:task_type===1?undefined:min_num,
max_num:task_type===1?undefined:max_num,
base_on_project: task_type===1?undefined:base_on_project===true?1:0
},
attachment_ids:contentFileList
}
).then((response) => {
if(response.data.status===0){
this.props.showNotification(response.data.message)
}else{
this.props.showNotification(response.data.message)
}
}).catch((error) => {
console.log(error)
})
} else {
}
} else {
$("html").animate({ scrollTop: $('html').scrollTop() - 100 })
}
})
}
max_num_change = (val) => {
if (val < 2) {
this.setState({
max_num: 2,
})
return;
}
const { min_num } = this.state;
this.setState({
max_num: val,
min_num: val <= min_num ? val - 1 : min_num
})
}
min_num_change = (val) => {
this.setState({ min_num: val })
}
base_on_project_change = () => {
this.setState({ base_on_project: !this.state.base_on_project })
}
render(){
const { getFieldDecorator } = this.props.form;
let{
title_value, contentFileList, answerFileList, max_num, min_num, base_on_project,
init_max_num, init_min_num,
title_num, course_name, category, has_commit, has_project,
isEdit
}=this.state
const uploadProps = {
width: 600,
fileList: contentFileList,
multiple: true,
// https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false,
action: `${getUrl()}/api/attachments.json`,
onChange: this.handleContentUploadChange,
onRemove: (file) => this.onAttachmentRemove(file, 'contentFileList'),
beforeUpload: (file) => {
console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) {
message.error('文件大小必须小于150MB!');
}
return isLt150M;
},
};
return(
<div>
<style>
{
`
.newAboutInputForm.ant-form-item, .newAboutInputForm .ant-form-item{padding:20px 30px 20px 30px!important}
.margin0{margin: 0px!important}
.tasktypes{width:64px;
height:22px;
font-size:16px;
font-family:Microsoft YaHei;
font-weight:400;
line-height:25px;
color:rgba(51,51,51,1);
opacity:1;}
`
}
</style>
<Form className="courseForm">
<div className={"ant-row ant-form-item AboutInputForm newAboutInputForm "}>
<div className="ant-col ant-form-item-label margin0">
<label htmlFor="coursesNew_course" className="ant-form-item-required ">类型</label> <span className={"tasktypes"}>{this.props.data&&this.props.data.task_type===1?"":this.props.data&&this.props.data.task_type===2?"":""}</span>
</div>
</div>
<Form.Item
label="标题"
className="AboutInputForm"
>
{getFieldDecorator('title', {
rules: [{
required: true, message: '请输入标题'
}],
})(
<Input placeholder="请输入毕设任务标题最大限制60个字符"
onInput={this.changeTitle}
className="searchView yslnewworkinputaddonAfter searchViewAfter"
style={{"width":"100%"}}
maxLength={MAX_TITLE_LENGTH} addonAfter={`${String(title_num)}/${MAX_TITLE_LENGTH}`}
/>
)}
</Form.Item>
<style>{`
.uploadBtn.ant-btn {
border: none;
color: #4CACFF;
box-shadow: none;
background: transparent;
padding: 0 6px;
}
.ant-upload-list-item:hover .ant-upload-list-item-info{
background-color:#fff;
}
.upload_1 .ant-upload-list {
width: 350px;
}
.ant-input-number {
height: 40px;
line-height: 40px;
}
.workContent.AboutInputForm.ant-form-item {
border-bottom: none;
padding-bottom: 0px !important;
}
.newWorkUpload {
padding: 0px 30px 30px 30px!important;
background: #fff;
width: 100%;
display: inline-block;
border-bottom: 1px solid #EDEDED;
}
`}</style>
{ <Form.Item
label="内容"
className="AboutInputForm workContent mdInForm"
>
{getFieldDecorator('description', {
rules: [{
required: true, message: '请输入任务内容说明'
}],
})(
<TPMMDEditor ref={this.contentMdRef} placeholder="请输入任务内容说明最大限制5000个字符" mdID={'courseContentMD'} refreshTimeout={1500}
className="courseMessageMD" initValue={this.state.description}></TPMMDEditor>
)}
</Form.Item> }
<Upload {...uploadProps} className="upload_1 newWorkUpload">
<Button className="uploadBtn">
<Icon type="upload" /> 上传附件
</Button>
(单个文件150M以内)
</Upload>
{this.props.data&&this.props.data.task_type===2?
<Form.Item
label="分组设置"
className="AboutInputForm"
>
{getFieldDecorator('personNum', {
rules: [{
required: false
// required: true, message: '请输入最小人数和最大人数'
}],
})(
<div>
<p className="clearfix">
<ConditionToolTip condition={has_commit} title={'已有提交作品,人数范围只能扩大'}>
{/* max={has_commit ? init_min_num : null } */}
每组最小人数<InputNumber placeholder="请填写每组最小人数" min={1} className="winput-240-40 mr10" value={min_num}
onChange={this.min_num_change} style={{width:'180px'}} />
</ConditionToolTip>
<span className="ml15 mr15"></span>
{/* min={has_commit ? init_max_num : (min_num == undefined ? 2 : min_num + 1) } */}
<ConditionToolTip condition={has_commit} title={'已有提交作品,人数范围只能扩大'}>
每组最大人数<InputNumber className="winput-240-40 mr10" placeholder="请填写每组最大人数" value={max_num} max={10}
onChange={this.max_num_change} style={{width:'180px'}} />
</ConditionToolTip>
<div className="color-grey-9 mt20 font-14">学生提交作品时需要关联同组成员组内成员作品共享</div>
</p>
<p className="mt20">
<ConditionToolTip condition={has_commit || has_project} title={'已有关联项目或作品,不能修改'}>
<Checkbox checked={base_on_project} onChange={this.base_on_project_change}
disabled={has_project || has_commit}
className="color-grey-9 font-14"
>基于项目选中则必须在本平台创建项目项目管理员可以提交作品不选中无需在平台创建项目任意小组成员均可以提交作品</Checkbox>
</ConditionToolTip>
</p>
</div>
)}
</Form.Item>:""
}
<Form.Item>
<div className="clearfix mt30 mb30">
{/* htmlType="submit" */}
<Button type="primary" onClick={this.handleSubmit} className="defalutSubmitbtn fl mr20">提交</Button>
<a className="defalutCancelbtn fl" onClick={() => this.props.onCancel()}>取消</ a>
</div>
</Form.Item>
</Form>
</div>
)
}
}
const NewGtaskForm = Form.create({ name: 'NewGtaskForm' })(NewGtaskForms);
export default NewGtaskForm;

@ -0,0 +1,69 @@
import React, { Component } from 'react';
import axios from 'axios'
import PollDetailTabThirdInfo from '../../../courses/poll/PollDetailTabThirdInfo'
class PollBanksContent extends Component{
constructor(props){
super(props);
this.state={
pollDetail:undefined
}
}
componentDidMount = () =>{
console.log("PollBanksContent");
console.log(this.props)
let bankId=this.props.match.params.bankId;
let url = `/exercise_banks/${bankId}.json`
axios.get(url).then((result)=>{
if(result){
let pollDetail = {
poll:{
id: result.data.poll && result.data.poll.id ,
polls_description: result.data.poll && result.data.poll.description,
polls_name: result.data.poll && result.data.poll.name,
is_public:result.data.poll && result.data.poll.is_public
},
question_types:result.data.question_types,
questions:result.data.questions,
}
const crumbData={
title:result.data.poll && result.data.poll.name,
is_public:result.data.poll && result.data.poll.is_public,
crumbArray:[
{content:'详情'},
]
}
const menuData={
tab:'0',//tab选中的index
menuArray:[//tab以及tab路由
{to:`/banks/poll/${bankId}/${this.props.match.params.type}`,content:'内容详情'}
],
category:'poll',//毕设选题
tos:`/banks/poll/${bankId}/edit/${this.props.match.params.type}`,
id:bankId,
is_public:result.data.poll && result.data.poll.is_public,
type:this.props.match.params.type,
authorize:result && result.data && result.data.authorize,
}
this.props.initPublic(crumbData,menuData);
this.setState({
pollDetail
})
}
}).catch((error)=>{
console.log(error);
})
}
render(){
let { pollDetail } = this.state
return(
<div>
<PollDetailTabThirdInfo {...this.props} {...this.state} pollDetail = {pollDetail}></PollDetailTabThirdInfo>
</div>
)
}
}
export default PollBanksContent

@ -0,0 +1,196 @@
import React, { Component } from 'react';
import { Menu } from 'antd'
import { Link } from 'react-router-dom'
import { WordsBtn } from 'educoder'
import "../usersInfo.css"
import "../../../courses/css/Courses.css"
import "../../../courses/css/busyWork.css"
import SendTopics from '../../../modals/SendTopics';
import Modals from '../../../modals/Modals';
import axios from 'axios';
class BanksMenu extends Component{
constructor(props){
super(props);
this.state={
visible:false,
tab:['0'],
}
}
//发送至相关
sendTopics=()=>{
this.setState({
visible:true
})
}
componentDidMount() {
debugger
try {
const query = this.props.location.search;
const type = query.split('?tab=');
if(type[1]===undefined){
this.setState({
tab:['0'],
});
}else{
if(type[1]==="0"){
this.setState({
tab:['0'],
});
}else if(type[1]==="1"){
this.setState({
tab:['1'],
});
}
}
}catch (e) {
this.setState({
tab:['0'],
});
}
}
topicscancelmodel=()=>{
this.setState({
Modalstype:false,
Loadtype:false,
visible:false,
Modalstopval:"",
ModalCancel:"",
ModalSave:"",
checkBoxValues:[],
checkedtype:false
})
}
//删除相关
deletecheckBoxValues=(id,type)=>{
this.setState({
Modalstype:true,
Modalstopval:"是否确认删除?",
ModalCancel:this.topicscancelmodel,
ModalSave:()=>this.topicssavedelete(id,type),
})
}
topicssavedelete=(id,type)=>{
console.log("删除了");
console.log(id);
console.log(type);
const url = `/question_banks/multi_delete.json`;
axios.delete(url, { data: {
object_id: [id],
object_type:type
}})
.then((response) => {
console.log(response);
if(response){
if(response.data){
if(response.data.status===0){
this.props.showNotification(response.data.message)
window.location.href=`/users/${this.props.current_user.login}/topics/personal`;
}else{
this.props.showNotification(response.data.message)
}
}
}
})
.catch(function (error) {
console.log(error);
});
this.topicscancelmodel()
}
changeTab=(e)=>{
this.setState({
tab:e.key
})
console.log(e.key);
// if(e.key === 0){
//
// }else{
//
//
// }
}
render(){
let { banksMenu} = this.props;
let {visible,tab}=this.state;
// console.log("问卷预览");
// console.log(visible);
let user_id=this.props.current_user&&this.props.current_user.user_id;
let user_type=this.props.current_user&&this.props.current_user.user_identity;
let targetuserid=this.props.data&&this.props.data.id;
// console.log("_____________________________");
// console.log(this.props);
// console.log("++++++++++++++++=");
// console.log("banksMenubanksMenubanksMenubanksMenu");
// console.log(banksMenu);
return(
<div className="clearfix bor-bottom-greyE edu-back-white" style={{padding:"0px 30px"}}>
{this.state.Modalstype&&this.state.Modalstype===true?<Modals
modalsType={this.state.Modalstype}
modalsTopval={this.state.Modalstopval}
modalCancel={this.state.ModalCancel}
modalSave={this.state.ModalSave}
modalsBottomval={this.state.ModalsBottomval}
loadtype={this.state.Loadtype}
/>:""}
{/*发送至弹窗*/}
{
visible&&visible===true?
<SendTopics
{...this.state}
{...this.props}
visible={visible}
category={banksMenu&&banksMenu.category}
checkBoxValues={[banksMenu&&banksMenu.id]}
topicscancelmodel={()=>this.topicscancelmodel()}
/>:""
}
{
banksMenu &&
<div className="task_menu_ul fl">
<Menu mode="horizontal" selectedKeys={tab} onClick={this.changeTab}>
{
banksMenu.menuArray && banksMenu.menuArray.map((item,key)=>{
console.log("BanksMenu");
console.log(item);
return(
<Menu.Item key={key}><Link to={`${item.to}`}>{item.content}</Link></Menu.Item>
)
})
}
</Menu>
</div>
}
{
banksMenu===undefined?
<span className="fr mt18">
<WordsBtn onClick={()=>this.deletecheckBoxValues(banksMenu&&banksMenu.id,banksMenu&&banksMenu.category)}style="blue" className="ml20 font-16">删除</WordsBtn>
<WordsBtn to={ banksMenu.tos ? banksMenu.tos:""} style="blue" className="ml20 font-16">编辑</WordsBtn>
<WordsBtn onClick={()=>this.sendTopics()} style="blue" className="ml20 font-16">发送</WordsBtn>
</span>
:banksMenu.authorize===true?
<span className="fr mt18">
<WordsBtn onClick={()=>this.deletecheckBoxValues(banksMenu&&banksMenu.id,banksMenu&&banksMenu.category)}style="blue" className="ml20 font-16">删除</WordsBtn>
<WordsBtn to={ banksMenu.tos ? banksMenu.tos:""} style="blue" className="ml20 font-16">编辑</WordsBtn>
<WordsBtn onClick={()=>this.sendTopics()} style="blue" className="ml20 font-16">发送</WordsBtn>
</span>
:
<span className="fr mt18">
<WordsBtn onClick={()=>this.sendTopics()} style="blue" className="ml20 font-16">发送</WordsBtn>
</span>
}
</div>
)
}
}
export default BanksMenu;

@ -17,7 +17,7 @@ class publicCreateNew extends Component{
render() {
let {href,name,index}=this.props;
return (
<div className="square-Item" style={{"height":`${index=="2"?"298":index=="3"?"295":"289"}px`}}>
<div className="square-Item" style={{"height":`${index=="1"?"289":index=="2"?"298":index=="3"?"295":"289"}px`}}>
<div className="substance substancepad">
<a href={`${href}`}>
<div className="substancenenew">

@ -227,3 +227,210 @@
left:0px;
background: #4CACFF;
}
.square-Item{
height: 295px;
}
/* 题库相关 */
.breadcrumb{
height: 18px;
line-height: 18px;
margin:10px 0px 0px;
}
.breadcrumb .ant-breadcrumb a:hover{
color: #459BE5 !important;
}
.breadcrumb .ant-breadcrumb-separator{
margin:0px 2px!important;
}
.breadcrumb span.ant-breadcrumb-link{
cursor: default;
}
.bank_is_public{
background: #84B6EB;
float: left;
height: 24px;
line-height: 24px;
padding:0px 20px;
color: #fff;
font-size: 16px;
margin-left: 10px;
border-radius:20px;
margin-top:3px;
}
.breadcrumb.ant-breadcrumb > span:last-child a{
color: #05101A
}
.breadcrumb.ant-breadcrumb a{
color:#999;
}
.bank_is_private{
background: #56B998;
float: left;
height: 24px;
line-height: 24px;
padding:0px 20px;
color: #fff;
font-size: 16px;
margin-left: 10px;
border-radius:20px;
margin-top:3px;
}
.topicsbox{
width: 1200px;
/*min-height: 216px;*/
background: rgba(255,255,255,1);
padding: 0px 30px 0px 40px;
}
.topicstopfont{
width:64px;
height:16px;
font-size:16px;
font-weight:400;
color: #666 !important;
}
.topcschild{
width:1128px;
height:55px;
line-height: 54px;
border-bottom:1px solid rgba(235,235,235,1);
}
.topcsmid{
width:1128px;
height:55px;
line-height: 55px;
}
.topcsactive{
color: #4CACFF !important;
cursor: pointer;
}
.topicsmidfont{
max-width: 56px;
height: 55px;
font-size: 14px;
font-weight: 400;
cursor: pointer;
line-height: 55px;
color: #666;
}
.alltopisc{
width:230px;
height:20px;
font-size:14px;
font-weight:400;
color:rgba(153,153,153,1);
line-height:20px;
}
.alltopiscright{
/* width: 141px; */
height: 20px;
font-size: 14px;
font-weight: 400;
color: rgba(153,153,153,1);
line-height: 20px;
}
.topicsbtn{
padding: 0px 15px;
border-radius: 2px;
/*color: #4C4C4C;*/
cursor: pointer;
display: inline-block;
/*background-color: #4CACFF!important;*/
/*color: #fff!important;*/
border-radius: 11px;
border: 1px solid rgba(76,172,255,1);
color: rgba(76,172,255,1);
}
.pd1323{
padding: 10px 6px 25px 40px;
/*cursor: pointer;*/
}
.pd1323:hover {
box-shadow: 0px 2px 6px rgba(51,51,51,0.09);
opacity: 1;
border-radius: 2px;
}
.topicswidth600{
mac-width: 600px;
display: inline-block;
}
.topicswidth300{
width: 300px;
display: inline-block;
}
.topiscfilterbtn{
font-size: 14px;
color: #4CACFF !important;
border-radius: 5px;
border: 1px solid #4CACFF !important;
line-height: 23px !important;
}
.topscisright{
right: 0px;
top: 45px;
display: block;
position: absolute;
}
.topsics135{
max-width: 135px;
display: inline-block;
}
.professional_certificationbox{
height:431px;
background:rgba(255,255,255,1);
}
.pd115200{
padding: 55px 200px 0px 200px;
}
.topicsItemimg{
width:150px;
}
.topicsItemfont{
font-size: 18px;
font-family: PingFang-SC;
font-weight: 400;
color: rgba(51,51,51,1);
line-height: 35px;
}
.topicsItem{
max-width: 1068px;
max-height: 115px;
overflow-y: auto;
}
.mb45{
margin-bottom: 45px!important;
}
.topsicsmax550{
max-width: 550px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
position: absolute;
top: -16px;
}
.topsicrelative{
position: relative;
}
.topsicinline{
display: inline-block;
}

@ -108,6 +108,7 @@ a:hover.link-color-grey03{color:#3498db!important;}
.font-18{ font-size: 18px!important;}
.font-20{ font-size: 20px!important;}
.font-22{ font-size: 22px!important;}
.font-25{ font-size: 25px!important;}
.font-24{ font-size: 24px!important;}
.font-28{ font-size: 28px!important;}
.font-30{ font-size: 30px!important;}

@ -3761,8 +3761,3 @@ a.singlepublishtwo{
/*width: auto !important;*/
/*max-width: 600px !important;*/
/*}*/
.topicsItem{
max-width: 1138px;
max-height: 110px;
overflow-y: auto;
}

@ -82,6 +82,7 @@ a.edu-txt-w80,.edu-txt-w80{ width:80px; display: inline-block;text-align: center
.font-18{ font-size: 18px!important;}
.font-20{ font-size: 20px!important;}
.font-22{ font-size: 22px!important;}
.font-25{ font-size: 25px!important;}
.font-24{ font-size: 24px!important;}
.font-26{ font-size: 26px!important;}
.font-28{ font-size: 28px!important;}
@ -103,6 +104,9 @@ a.decoration{text-decoration: underline}
.mb0{margin-bottom: 0px!important;}.mb3{ margin-bottom: 3px;}.mb5{ margin-bottom: 5px;}.mb7{ margin-bottom: 7px;}.mb10{ margin-bottom: 10px;}.mb11{ margin-bottom: 11px;}.mb14{ margin-bottom: 14px;}.mb15{ margin-bottom: 15px;}.mb16{ margin-bottom: 16px;}.mb20{ margin-bottom: 20px!important;}.mb25{ margin-bottom: 25px;}.mb26{ margin-bottom: 26px;}.mb28{ margin-bottom: 28px;}.mb30{ margin-bottom: 30px!important;}.mb40{ margin-bottom: 40px!important;}.mb50{ margin-bottom: 50px!important;}.mb60{ margin-bottom: 60px!important;}.mb70{ margin-bottom: 70px!important;}.mb80{ margin-bottom: 80px!important;}.mb90{ margin-bottom: 90px!important;}.mb100{ margin-bottom: 100px!important;}.mb110{ margin-bottom: 110px;}
.ml-3{ margin-left: -3px;}.ml1{margin-left: 1px;}.ml2{margin-left: 2px;}.ml3{margin-left: 3px;}.ml4{margin-left: 4px;}.ml5{ margin-left: 5px;}.ml6{ margin-left: 6px;}.ml10{ margin-left: 10px;}.ml12{ margin-left:12px!important;}.ml13{ margin-left:13px!important;}.ml15{ margin-left: 15px;}.ml18{ margin-left: 18px;}.ml20{ margin-left: 20px;}.ml22{ margin-left: 22px;}.ml25{ margin-left: 25px;}.ml29{margin-left: 29px;}.ml30{ margin-left: 30px;}.ml33{ margin-left: 33px;}.ml35{ margin-left:35px;}.ml40{margin-left:40px;}.ml42{margin-left:42px;}.ml45{ margin-left: 45px;}.ml50{ margin-left: 50px;}.ml55{ margin-left: 55px;}.ml60{ margin-left: 60px;}.ml72{ margin-left: 72px;}.ml73{ margin-left: 73px;}.ml75{ margin-left: 75px;}.ml80{ margin-left: 80px;}.ml85{margin-left:85px;}.ml95{ margin-left: 95px;}.ml115{margin-left: 115px}.ml123{ margin-left: 123px;}.ml150{ margin-left: 150px;}.ml180{ margin-left: 180px;}.ml230{ margin-left: 230px;}.ml240{margin-left: 240px;}.ml250{ margin-left: 250px;}.ml290{ margin-left: 290px;}
.mr3{margin-right: 3px}.mr4{margin-right: 4px}.mr5{ margin-right: 5px;}.mr8{ margin-right: 8px;}.mr10{ margin-right: 10px;}.mr12{ margin-right:12px!important;}.mr15{ margin-right: 15px;}.mr18{ margin-right: 18px;}.mr20{ margin-right: 20px;}.mr24{ margin-right: 24px;}.mr25{ margin-right: 25px;}.mr30{ margin-right:30px;}.mr35{margin-right:35px;}.mr40{margin-right:40px;}.mr45{margin-right:45px;}.mr50{ margin-right: 50px;}.mr60{ margin-right:60px;}.mr70{ margin-right: 70px;}.mr75{ margin-right: 75px;}.mr80{ margin-right:80px;}.mr90{ margin-right:90px;}.mr100{ margin-right: 100px;}.mr110{ margin-right:110px;}.mr350{ margin-right:350px;}
.ml61{
margin-left: 61px;
}
.pt1{ padding-top:1px;}.pt3{ padding-top:3px!important;}.pt5{ padding-top:5px!important;}.pt10{ padding-top:10px;}.pt15{ padding-top:15px;}.pt17{ padding-top:17px;}.pt20{ padding-top:20px!important;}.pt25{ padding-top:25px;}.pt30{ padding-top:30px;}.pt35{ padding-top:35px;}.pt37{ padding-top:37px;}.pt40{ padding-top:40px;}.pt47{ padding-top:47px;}.pt49{ padding-top:49px;}.pt50{ padding-top:50px;}.pt60{ padding-top:60px;}.pt70{ padding-top:70px;}.pt80{ padding-top:80px;}.pt90{ padding-top:90px;}.pt100{padding-top:100px;}.pt110{ padding-top:110px;}.pt120{ padding-top:120px;}.pt130{padding-top:130px;}
.pb3{ padding-bottom:3px!important;}.pb5{ padding-bottom:5px!important;}.pb10{ padding-bottom:10px;}.pb15{ padding-bottom:15px;}.pb20{ padding-bottom:20px;}.pb25{ padding-bottom:20px;}.pb25{ padding-bottom:20px;}.pb30{ padding-bottom:30px;}.pb35{ padding-bottom:35px;}.pb40{ padding-bottom:40px;}.pb47{ padding-bottom:47px;}.pb50{ padding-bottom:50px;}.pb60{ padding-bottom:60px;}.pb70{ padding-bottom:70px;}.pb80{ padding-bottom:80px;}.pb90{ padding-bottom:90px;}.pb100{ padding-bottom:100px;}.pb110{ padding-bottom:110px;}.pb155{ padding-bottom:155px;}
@ -111,7 +115,6 @@ a.decoration{text-decoration: underline}
.pl0{ padding-left:0px!important;}.pl2{ padding-left:2px;}.pl5{ padding-left:5px;}.pl7{ padding-left:7px;}.pl8{ padding-left:8px;}.pl10{ padding-left:10px;}.pl15{ padding-left:15px;}.pl20{ padding-left:20px;}.pl22{ padding-left:22px;}.pl25{ padding-left:25px;}.pl28{ padding-left:28px;}.pl30{ padding-left:30px !important;}.pl33{padding-left: 33px}.pl35{ padding-left:35px;}.pl40{ padding-left:40px;}.pl42{ padding-left:42px;}.pl45{ padding-left:45px;}.pl50{ padding-left:50px;}.pl60{ padding-left:60px;}.pl70{padding-left:70px;}.pl75{padding-left:75px;}.pl80{padding-left:80px;}.pl88{ padding-left:88px;}.pl92{padding-left:92px;}.pl100{ padding-left:100px;}
.pr2{ paddding-right:2px;}.pr5{ padding-right:5px;}.pr7{ padding-right:7px;}.pr10{ padding-right:10px;}.pr15{ padding-right:15px;}.pr20{ padding-right:20px!important;}.pr25{ padding-right:25px!important;}.pr30{ padding-right:30px!important;}.pr40{ padding-right:40px;}.pr42{ padding-right:42px;}.pr45{ padding-right:45px;}.pr60{padding-right:60px;}.pr75{padding-right:75px;}
.padding5-10{padding:5px 10px;box-sizing: border-box}
.padding5-20{padding:5px 20px;box-sizing: border-box}
.padding10{padding: 10px;box-sizing: border-box}
@ -170,7 +173,7 @@ input::-ms-clear{display:none;}
.newContainer{ min-height:100%; height: auto !important; height: 100%; /*IE6不识别min-height*/position: relative;}
.educontent{width: 1200px;margin:0px auto;box-sizing: border-box}/*中间部分宽度固定为1200*/
.newMain{ margin: 0 auto; padding-bottom: 235px; min-width:1200px;}/*padding-bottom根据底部的高度而定*/
.newMain{ padding-bottom: 120px !important; }
.newMain{ padding-bottom: 124px !important; }
/*高度*/
.height-100{height: 100%;}

Loading…
Cancel
Save