Merge remote-tracking branch 'origin/master'

dev_forum
杨树明 6 years ago
commit d7b964d5d8

@ -97,13 +97,6 @@ class CommonWorkItem extends Component{
setupdate = () => { setupdate = () => {
} }
toCreateProject = () => {
if (window.location.port == 3007) {
window.location.href = '/testbdweb.educoder.net/projects/new'
} else {
window.location.href = '/projects/new'
}
}
render(){ render(){
let { mainList,workType }=this.props; let { mainList,workType }=this.props;
const { aModalVisible, fileList, revise_reason } = this.state const { aModalVisible, fileList, revise_reason } = this.state

@ -85,13 +85,6 @@ class ConnectProject extends Component{
console.log(error); console.log(error);
}) })
} }
toCreateProject = () => {
if (window.location.port == 3007) {
window.location.href = '/testbdweb.educoder.net/projects/new'
} else {
window.location.href = '/projects/new'
}
}
//关联项目 //关联项目
openConnectionProject=(work)=>{ openConnectionProject=(work)=>{
this.work = work; this.work = work;
@ -175,7 +168,7 @@ class ConnectProject extends Component{
{ {
(!haveProjects) && (!haveProjects) &&
<div className="edu-txt-center"> <div className="edu-txt-center">
您当前尚未管理任何项目请先<WordsBtn style="blue" className="" onClick={this.toCreateProject}>创建项目</WordsBtn> 您当前尚未管理任何项目请先<WordsBtn style="blue" className="" onClick={this.props.toCreateProject}>创建项目</WordsBtn>
</div> </div>
} }

@ -477,7 +477,7 @@ class NewWork extends Component{
<span className="ml15 mr15">~</span> <span className="ml15 mr15">~</span>
{/* min={has_commit ? init_max_num : (min_num == undefined ? 2 : min_num + 1) } */} {/* min={has_commit ? init_max_num : (min_num == undefined ? 2 : min_num + 1) } */}
<ConditionToolTip condition={has_commit} title={'已有提交作品,人数范围只能扩大'}> <ConditionToolTip condition={has_commit} title={'已有提交作品,人数范围只能扩大'}>
<InputNumber className="winput-240-40" placeholder="请填写每组最大人数" value={max_num} <InputNumber className="winput-240-40" placeholder="请填写每组最大人数" value={max_num} max={10}
onChange={this.max_num_change} style={{width:'180px'}} /> onChange={this.max_num_change} style={{width:'180px'}} />
</ConditionToolTip> </ConditionToolTip>
<label className="color-grey-9 ml20 font-14">项目管理员角色的成员都可以提交作品提交作品时需要关联同组成员组内成员作品共享</label> <label className="color-grey-9 ml20 font-14">项目管理员角色的成员都可以提交作品提交作品时需要关联同组成员组内成员作品共享</label>

@ -187,7 +187,13 @@ class UseBank extends Component{
display: -webkit-flex; display: -webkit-flex;
} }
.setImgW .edu-nodata-img{ .setImgW .edu-nodata-img{
width:218px!important; width:218px !important;
}
.bankwidth{
width:29% !important;
overflow:hidden;
text-overflow:ellipsis;
white-space:nowrap
} }
`}</style> `}</style>
@ -269,7 +275,10 @@ class UseBank extends Component{
<span className="fl with65"> <span className="fl with65">
<label className="task-hide fl" title={item.name && item.name.length > 30 ? item.name:""} style={{"maxWidth":"100%"}}>{item.name}</label> <label className="task-hide fl" title={item.name && item.name.length > 30 ? item.name:""} style={{"maxWidth":"100%"}}>{item.name}</label>
</span> </span>
<span title={item.course_list_name && item.course_list_name.length > 14 && item.course_list_name} className={nav_my==='myself'?"fl with30 color-grey-6 task-hide pl5":"fl with30 color-grey-6 task-hide pl5"}>{item.course_list_name}</span> <span title={item.course_list_name && item.course_list_name.length > 14 && item.course_list_name}
className={nav_my==='myself'?"fl with30 color-grey-6 task-hide pl5 bankwidth":"fl with30 color-grey-6 task-hide pl5 bankwidth"}
>{item.course_list_name}</span>
{ {
nav_my==='public' && nav_my==='public' &&
<span className="fl with16 color-grey-6 task-hide pl10">{item.username}</span> <span className="fl with16 color-grey-6 task-hide pl10">{item.username}</span>

@ -17,6 +17,13 @@ export function RouteHOC(options = {}) {
} }
} }
toCreateProject = () => {
if (window.location.port == 3007) {
window.location.href = '/testbdweb.educoder.net/projects/new'
} else {
window.location.href = '/projects/new'
}
}
// common_homework group_homework // common_homework group_homework
// 是否是分组作业 // 是否是分组作业
isGroup = () => { isGroup = () => {
@ -156,7 +163,7 @@ export function RouteHOC(options = {}) {
toWorkQuestionPage={this.toWorkQuestionPage} toWorkQuestionPage={this.toWorkQuestionPage}
toWorkSettingPage={this.toWorkSettingPage} toWorkSettingPage={this.toWorkSettingPage}
toCreateProject={this.toCreateProject}
isGroup={this.isGroup} isGroup={this.isGroup}
getModuleName={this.getModuleName} getModuleName={this.getModuleName}

@ -272,9 +272,11 @@ class Coursesleftnav extends Component{
debugger debugger
let {url}=this.state; let {url}=this.state;
if(urls!=url){ if(urls!=url){
debugger
this.props.history.replace(urls); this.props.history.replace(urls);
this.props.updataleftNavfun(); this.props.updataleftNavfun();
}else{ }else{
debugger
if (key === this.props.indexs) { if (key === this.props.indexs) {
this.props.unlocationNavfun(undefined) this.props.unlocationNavfun(undefined)
} else { } else {

@ -1,5 +1,5 @@
import React,{ Component } from "react"; import React,{ Component } from "react";
import { Modal,Checkbox,Input} from "antd"; import { Modal,Checkbox,Input, Spin, Icon } from "antd";
import axios from 'axios'; import axios from 'axios';
import Modals from '../../modals/Modals'; import Modals from '../../modals/Modals';
const CheckboxGroup = Checkbox.Group; const CheckboxGroup = Checkbox.Group;
@ -23,6 +23,7 @@ class Addcourses extends Component{
modalsType:false, modalsType:false,
modalsTopval:undefined, modalsTopval:undefined,
modalSave:undefined, modalSave:undefined,
isSpin:false
} }
} }
@ -144,17 +145,22 @@ class Addcourses extends Component{
} }
submittojoinclass=()=>{ submittojoinclass=()=>{
this.setState({
isSpin:true
})
let {invite_code,professor,assistant_professor,student}=this.state; let {invite_code,professor,assistant_professor,student}=this.state;
if(invite_code===undefined||invite_code===""){ if(invite_code===undefined||invite_code===""){
this.setState({ this.setState({
invite_codetype:true, invite_codetype:true,
invite_codevalue:"邀请码不能为空" invite_codevalue:"邀请码不能为空",
spinning:false
}) })
return return
}else{ }else{
this.setState({ this.setState({
invite_codetype:false, invite_codetype:false,
invite_codevalue:" " invite_codevalue:" ",
spinning:false
}) })
} }
@ -178,7 +184,12 @@ class Addcourses extends Component{
// // modalSave:this.submitasyn, // // modalSave:this.submitasyn,
// course_id:response.data.course_id // course_id:response.data.course_id
// }) // })
this.submitasyn(response.data.course_id) if(response.data.course_id!=undefined){
this.submitasyn(response.data.course_id)
}
this.props.hideAddcoursestype();
this.props.showNotification(response.data.message);
}else{ }else{
this.setState({ this.setState({
Addcoursestype:false Addcoursestype:false
@ -193,8 +204,15 @@ class Addcourses extends Component{
// course_id:undefined // course_id:undefined
// }) // })
} }
this.setState({
spinning:false
})
}).catch((error) => { }).catch((error) => {
console.log(error) console.log(error)
this.setState({
spinning:false
})
}) })
// if(value===0){ // if(value===0){
@ -258,7 +276,7 @@ class Addcourses extends Component{
modalsTopval, modalsTopval,
modalSave modalSave
}=this.state; }=this.state;
const antIcon = <Icon type="loading" style={{ fontSize: 24 }} spin />;
return( return(
<div> <div>
<Modals <Modals
@ -277,6 +295,7 @@ class Addcourses extends Component{
footer={null} footer={null}
destroyOnClose={true} destroyOnClose={true}
> >
<Spin indicator={antIcon} spinning={this.state.isSpin}>
<div className="task_popup_con ml30"> <div className="task_popup_con ml30">
<div className="mr15"> <div className="mr15">
<ul> <ul>
@ -331,6 +350,7 @@ class Addcourses extends Component{
</ul> </ul>
</div> </div>
</div> </div>
</Spin>
</Modal> </Modal>
</div> </div>
) )

@ -69,20 +69,23 @@ class ExerciseDisplay extends Component{
return( return(
<div className="edu-back-white"> <div className="edu-back-white">
<div className={"bor-bottom-greyE padding20-30"}> <div className={" padding20-30"}>
<style> <style>
{ {
` `
.center{ .center{
text-align: center; text-align: center;
}
.edu-back-white>.bor-bottom-greyE:last-child {
border-bottom: none !important;
} }
` `
} }
</style> </style>
<div className={"font-18 center"}>{exercise&&exercise.exercise_name}</div> <div className={"font-18 center"}>{exercise&&exercise.exercise_name}</div>
<div className={"font-14 center color-grey-9"}>{exercise&&exercise.exercise_description}</div> <div className={"font-14 color-grey-9"}>{exercise&&exercise.exercise_description}</div>
</div> </div>
<div className={"bor-bottom-greyE padding20-30 newContainer"}> <div className={" padding20-30 newContainer"}>
<p className=" clearfix"> <p className=" clearfix">
{ {
exercise_types && exercise_types.q_singles > 0 && exercise_types && exercise_types.q_singles > 0 &&

@ -167,7 +167,7 @@ class ExerciseListItem extends Component{
{ IsAdmin &&<div className="homepagePostSetting" style={{"right":"-17px","top":"51px","display":"block","width":"100px"}}> { IsAdmin &&<div className="homepagePostSetting" style={{"right":"-17px","top":"51px","display":"block","width":"100px"}}>
<a className="btn colorblue font-16" href={`/courses/${coursesId}/exercises/${item.id}/edit`} target={"_blank"}>编辑</a> <a className="btn colorblue font-16" href={`/courses/${coursesId}/exercises/${item.id}/edit`}>编辑</a>
<a className="btn colorblue ml20 font-16" href={`/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=3`}>设置</a> <a className="btn colorblue ml20 font-16" href={`/courses/${coursesId}/exercises/${item.id}/student_exercise_list?tab=3`}>设置</a>
</div> } </div> }

@ -342,6 +342,11 @@ class ExerciceNew extends Component{
this.editingId = null; this.editingId = null;
this.fetchExercise() 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`)
}
render() { render() {
let { exercise_name, exercise_description, course_id, exercise_types, let { exercise_name, exercise_description, course_id, exercise_types,
exercise_questions, left_banner_id } = this.state; exercise_questions, left_banner_id } = this.state;
@ -366,6 +371,8 @@ class ExerciceNew extends Component{
const isAdmin = this.props.isAdmin() const isAdmin = this.props.isAdmin()
const courseId=this.props.match.params.coursesId; const courseId=this.props.match.params.coursesId;
const exercise_id = this.props.match.params.Id
const isEdit = this.isEdit const isEdit = this.isEdit
const commonHandler = { const commonHandler = {
onQestionDelete: this.onQestionDelete, onQestionDelete: this.onQestionDelete,
@ -395,7 +402,7 @@ class ExerciceNew extends Component{
background: #fff; background: #fff;
} }
.exerciseNew .markdown-body { .exerciseNew .markdown-body {
max-width: 1088px; max-width: 1128px;
} }
`}</style> `}</style>
<div className="edu-class-container edu-position courseForm"> <div className="edu-class-container edu-position courseForm">
@ -546,6 +553,11 @@ class ExerciceNew extends Component{
<ActionBtn style="green" className="mr20" onClick={() => this.addShixun(null)}> <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> <i className="iconfont icon-tianjiafangda color-white font-14 mr5" style={{ marginTop: '-1px', display: 'inline-block'}}></i>
</ActionBtn> </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>}
</div> </div>

@ -39,14 +39,14 @@ class NullChildEditor extends Component{
let { question_title, question_score, question_type, question_choices, standard_answers } = this.state; let { question_title, question_score, question_type, question_choices, standard_answers } = this.state;
let { question_id, index, onAnswerChange, addChildAnswer, toMDMode, exerciseIsPublish, let { question_id, index, onAnswerChange, addChildAnswer, toMDMode, exerciseIsPublish,
answers } = this.props; answers } = this.props;
// marginTop: '18px'
return( return(
<div className="df" style={{ marginTop: '18px'}}> <div className="df" style={{ }}>
<div className="color-grey-6 mb5 mt6" style={{ flex: '0 0 90px'}}>答案(填空{index + 1}):</div> <div className="color-grey-6 mb5 mt6" style={{ flex: '0 0 90px'}}>答案(填空{index + 1}):</div>
<div className="df flex1" style={{flexDirection: 'column'}}> <div className="df flex1" style={{flexDirection: 'column'}}>
{ {
answers.map((item, itemIndex) => { answers.map((item, itemIndex) => {
return <div className="df mb20 flex1" > return <div className="df flex1" >
<div className="flex1" style={{ flex: '0 0 1000px'}}> <div className="flex1" style={{ flex: '0 0 1000px'}}>
<DMDEditor <DMDEditor
className={'nullChildEditor'} className={'nullChildEditor'}

@ -80,12 +80,14 @@ class NullDisplay extends Component{
.answers .answer { .answers .answer {
background: #EDEDED; background: #EDEDED;
color: #C5C5C5; color: #C5C5C5;
width: 100%;
display: inline-block; display: inline-block;
line-height: 16px; line-height: 16px;
padding:12px 10px; padding:12px 10px;
margin-bottom:10px; margin-bottom:10px;
border-radius:2px; border-radius:2px;
max-width: 1024px;
word-break: break-all;
} }
.answerRow { .answerRow {
padding: 1px 0; padding: 1px 0;

@ -282,7 +282,7 @@ class NullEditor extends Component{
display: inline-block; display: inline-block;
} }
.content_editorMd_show { .content_editorMd_show {
display: flex;
maxWidth: 1000px; maxWidth: 1000px;
} }
`}</style> `}</style>

@ -71,7 +71,7 @@ class SingleDisplay extends Component{
let length = 5; let length = 5;
const qName = qNameArray[question_type] const qName = qNameArray[question_type]
return( return(
<div className="bor-bottom-greyE padding20-30" id={qNumber} _id={question_id}> <div className="bor-bottom-greyE padding20-30 singleDisplay" id={qNumber} _id={question_id}>
<style>{` <style>{`
.optionMdEditor { .optionMdEditor {
flex: 0 0 800px flex: 0 0 800px

@ -219,9 +219,10 @@ class SingleEditor extends Component{
} }
.optionRow { .optionRow {
margin:0px!important; margin:0px!important;
margin-bottom: 20px!important; /* margin-bottom: 20px!important; */
} }
.signleEditor .content_editorMd_show{ .signleEditor .content_editorMd_show{
display: flex;
margin-top:0px!important; margin-top:0px!important;
border-radius:2px; border-radius:2px;
max-width: 1056px; max-width: 1056px;

@ -29,4 +29,8 @@
.nullChildEditor { .nullChildEditor {
width: 100%; width: 100%;
display: inline-block; display: inline-block;
}
.singleDisplay .options .markdown-body {
max-width: 1116px;
} }

@ -504,7 +504,7 @@ class GraduationTasksSubmitedit extends Component{
`}</style> `}</style>
<Form.Item <Form.Item
label="内容" label="内容"
className="mdInForm"
> >
{getFieldDecorator('description', { {getFieldDecorator('description', {
rules: [{ rules: [{

@ -31,7 +31,8 @@ class GraduationTasksSubmitnew extends Component{
minmaxtype:false, minmaxtype:false,
selectobjct:undefined, selectobjct:undefined,
Loadtype:false, Loadtype:false,
spinnings:false spinnings:false,
shixunsreplace:false
} }
} }
@ -88,111 +89,11 @@ class GraduationTasksSubmitnew extends Component{
if(fileList.length === 0){ if(fileList.length === 0){
this.setState({ this.setState({
Modalstype:true, tshixunsreplace:true,
Modalstopval:'请上传附件!',
Loadtype:true,
ModalSave:this.cancelAttachment,
}) })
return return
} }
this.Commoninterface(fileList,selectmemberslist,workslist);
let userids=[];
for(var list of selectmemberslist){
if(list.user_id!=undefined&&list.user_id!=null){
userids.push(list.user_id)
}
}
if(workslist.task_type===1){
userids=undefined
}
let listid=[];
for(var list of fileList){
listid.push(list.response.id)
}
// e.preventDefault();
if( GraduationTasksnewtype===true){
this.props.form.validateFields((err, values) => {
if (!err) {
console.log(values.description);
// console.log(fileList);
if(values.description===undefined||values.description===""){
return
}
if(workslist&&workslist.task_type===2){
if(userids!=undefined){
if(userids.length<2){
this.setState({
minvalue:2,
setvalue:"小于",
minmaxtype:true
})
return
}else if(userids.length>5){
this.setState({
minvalue:5,
setvalue:"大于",
minmaxtype:true
})
return
}
}
}
this.setState({
spinnings:true
})
let id=this.props.match.params.task_Id;
let url="/graduation_tasks/"+id+"/graduation_works.json";
axios.post(url, {
description:values.description,
attachment_ids:listid,
user_ids:userids
}
).then((response) => {
this.setState({
spinnings:false
})
if(response.status===200) {
GraduationTasksnewtype=false;
if(response.data.status===0){
// this.setState({
// Modalstype:true,
// Modalstopval:response.data.message,
// ModalSave:()=>this.setedit(response.data.work_id),
// Loadtype:true
// })
this.setedit(response.data.work_id)
}else{
GraduationTasksnewtype=true;
}
}
}).catch((error) => {
console.log(error)
})
}
});
}
// setTimeout(function () {
// GraduationTasksnewtype=true
// },10000)
} }
handleSelectChange = (value) => { handleSelectChange = (value) => {
@ -433,10 +334,116 @@ class GraduationTasksSubmitnew extends Component{
window.history.go(-1) window.history.go(-1)
} }
//公用数据
Commoninterface = (fileList,selectmemberslist,workslist)=>{
let userids=[];
for(var list of selectmemberslist){
if(list.user_id!=undefined&&list.user_id!=null){
userids.push(list.user_id)
}
}
if(workslist.task_type===1){
userids=undefined
}
let listid=[];
for(var list of fileList){
listid.push(list.response.id)
}
// e.preventDefault();
if( GraduationTasksnewtype===true){
this.props.form.validateFields((err, values) => {
if (!err) {
console.log(values.description);
// console.log(fileList);
if(values.description===undefined||values.description===""){
return
}
if(workslist&&workslist.task_type===2){
if(userids!=undefined){
if(userids.length<2){
this.setState({
minvalue:2,
setvalue:"小于",
minmaxtype:true
})
return
}else if(userids.length>5){
this.setState({
minvalue:5,
setvalue:"大于",
minmaxtype:true
})
return
}
}
}
this.setState({
spinnings:true
})
let id=this.props.match.params.task_Id;
let url="/graduation_tasks/"+id+"/graduation_works.json";
axios.post(url, {
description:values.description,
attachment_ids:listid,
user_ids:userids
}
).then((response) => {
this.setState({
spinnings:false
})
if(response.status===200) {
GraduationTasksnewtype=false;
if(response.data.status===0){
// this.setState({
// Modalstype:true,
// Modalstopval:response.data.message,
// ModalSave:()=>this.setedit(response.data.work_id),
// Loadtype:true
// })
this.setedit(response.data.work_id)
}else{
GraduationTasksnewtype=true;
}
}
}).catch((error) => {
console.log(error)
})
}
});
}
}
//确认
hidestartshixunsreplace=()=>{
let {fileList,selectmemberslist,workslist}=this.state;
this.Commoninterface(fileList,selectmemberslist,workslist);
}
//取消
hidestartshixunsreplacetwo=()=>{
this.setState({
shixunsreplace:false,
})
}
render(){ render(){
const { getFieldDecorator } = this.props.form; const { getFieldDecorator } = this.props.form;
let {search,fileList, workslist,setvalue,minvalue,minmaxtype,Loadtype, let {search,fileList, workslist,setvalue,minvalue,minmaxtype,Loadtype,
Modalstype,Modalstopval,ModalCancel,ModalSave,memberslist,task_status,selectmemberslist} =this.state; Modalstype,Modalstopval,ModalCancel,ModalSave,memberslist,task_status,selectmemberslist,shixunsreplace} =this.state;
let courseId=this.props.match.params.coursesId; let courseId=this.props.match.params.coursesId;
let category_id=this.props.match.params.category_id; let category_id=this.props.match.params.category_id;
@ -481,6 +488,24 @@ render(){
modalSave={ModalSave} modalSave={ModalSave}
loadtype={Loadtype} loadtype={Loadtype}
/> />
<Modal
keyboard={false}
title="提示"
visible={shixunsreplace}
closable={false}
footer={null}
>
<div className="task-popup-content">
<p className="task-popup-text-center font-16 ">还未上传附件</p>
<p className="task-popup-text-center font-16 pb20">是否确认提交作品?</p>
</div>
<div className="task-popup-submit clearfix">
<a className="task-btn task-btn-orange fr "
onClick={() => this.hidestartshixunsreplace()}>确认</a>
<a className="task-btn fr mr50"
onClick={() => this.hidestartshixunsreplacetwo()}>取消</a>
</div>
</Modal>
<div className="newMain clearfix"> <div className="newMain clearfix">
<div className={"educontent mb20"}> <div className={"educontent mb20"}>
@ -520,13 +545,10 @@ render(){
.upload_1 .ant-upload-list { .upload_1 .ant-upload-list {
width: 350px; width: 350px;
} }
.contentbox{
margin-bottom:0px !important;
}
`}</style> `}</style>
<Form.Item <Form.Item
label="内容" label="内容"
className={"contentbox"} className={"contentbox mdInForm"}
> >
{getFieldDecorator('description', { {getFieldDecorator('description', {
rules: [{ rules: [{
@ -583,7 +605,7 @@ render(){
{workslist&&workslist.task_type===1?"": {workslist&&workslist.task_type===1?"":
<div className="stud-class-set pd20 coursenavbox edu-back-white" <div className="stud-class-set pd20 coursenavbox edu-back-white"
style={{borderTop:'1px solid #ccc'}} style={{borderTop:'0.5px solid #ccc'}}
> >
<Form.Item <Form.Item
label="小组成员" label="小组成员"

@ -344,10 +344,11 @@ class GraduationTasksedit extends Component{
.upload_1 .ant-upload-list { .upload_1 .ant-upload-list {
width: 350px; width: 350px;
} }
`}</style> `}</style>
<Form.Item <Form.Item
label="内容" label="内容"
className="mdInForm"
style={{marginBottom:'0px'}} style={{marginBottom:'0px'}}
> >
{getFieldDecorator('description', { {getFieldDecorator('description', {

@ -339,9 +339,11 @@ class GraduationTasksnew extends Component {
.ant-form-item{ .ant-form-item{
margin-bottom:0px margin-bottom:0px
} }
`}</style> `}</style>
<Form.Item <Form.Item
label="内容" label="内容"
className="mdInForm "
> >
{getFieldDecorator('description', { {getFieldDecorator('description', {

@ -1,425 +1,426 @@
import React,{ Component } from "react"; import React,{ Component } from "react";
import { import {
Form, Input, InputNumber, Switch, Radio, Form, Input, InputNumber, Switch, Radio,
Slider, Button, Upload, Icon, Rate, Checkbox, message, Slider, Button, Upload, Icon, Rate, Checkbox, message,
Row, Col, Select, Modal Row, Col, Select, Modal
} from 'antd'; } from 'antd';
import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor'; import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor';
import axios from 'axios' import axios from 'axios'
import {getUrl} from 'educoder'; import {getUrl} from 'educoder';
import "../../common/formCommon.css" import "../../common/formCommon.css"
// import './board.css' // import './board.css'
// import { RouteHOC } from './common.js' // import { RouteHOC } from './common.js'
const confirm = Modal.confirm; const confirm = Modal.confirm;
const $ = window.$ const $ = window.$
const { Option } = Select; const { Option } = Select;
// 提交作品 // 提交作品
// https://lanhuapp.com/web/#/item/project/board/detail?pid=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&project_id=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&image_id=c6d9b36f-7701-4035-afdb-62404681108c // https://lanhuapp.com/web/#/item/project/board/detail?pid=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&project_id=a3bcd4b1-99ce-4e43-8ead-5b8b0a410807&image_id=c6d9b36f-7701-4035-afdb-62404681108c
class GraduateTopicPostWorksNew extends Component{ class GraduateTopicPostWorksNew extends Component{
constructor(props){ constructor(props){
super(props); super(props);
this.mdRef = React.createRef(); this.mdRef = React.createRef();
this.state = { this.state = {
fileList: [], fileList: [],
boards: [] boards: []
} }
} }
componentDidMount = () => { componentDidMount = () => {
const topicId = this.props.match.params.topicId const topicId = this.props.match.params.topicId
const cid = this.props.match.params.coursesId const cid = this.props.match.params.coursesId
const boardsUrl = `/courses/${cid}/get_all_boards.json` const boardsUrl = `/courses/${cid}/get_all_boards.json`
axios.get(boardsUrl, { }) axios.get(boardsUrl, { })
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
this.setState({ this.setState({
boards: response.data.data boards: response.data.data
}) })
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
const isEdit = !!topicId const isEdit = !!topicId
this.isEdit = isEdit this.isEdit = isEdit
if (isEdit) { if (isEdit) {
const url = `/messages/${topicId}.json` const url = `/messages/${topicId}.json`
axios.get(url, { axios.get(url, {
}) })
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
const { id, data } = response.data; const { id, data } = response.data;
if (data) { if (data) {
this.editTopic = data; this.editTopic = data;
this.props.form.setFieldsValue({ this.props.form.setFieldsValue({
content: data.content, content: data.content,
subject: data.subject, subject: data.subject,
board_id: data.board_id board_id: data.board_id
}); });
this.mdRef.current.setValue(data.content) this.mdRef.current.setValue(data.content)
const _fileList = data.attachments.map(item => { const _fileList = data.attachments.map(item => {
return { return {
id: item.id, id: item.id,
uid: item.id, uid: item.id,
name: item.title, name: item.title,
url: item.url, url: item.url,
status: 'done' status: 'done'
} }
}) })
this.setState({ fileList: _fileList}) this.setState({ fileList: _fileList})
} }
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} else { } else {
const boardId = this.props.match.params.boardId const boardId = this.props.match.params.boardId
this.props.form.setFieldsValue({ this.props.form.setFieldsValue({
board_id: parseInt(boardId) board_id: parseInt(boardId)
}); });
} }
} }
handleSubmit = (e) => { handleSubmit = (e) => {
e.preventDefault(); e.preventDefault();
const cid = this.props.match.params.coursesId const cid = this.props.match.params.coursesId
const boardId = this.props.match.params.boardId const boardId = this.props.match.params.boardId
this.props.form.validateFieldsAndScroll((err, values) => { this.props.form.validateFieldsAndScroll((err, values) => {
if (!err) { if (!err) {
console.log('Received values of form: ', values); console.log('Received values of form: ', values);
if (this.isEdit == true) { if (this.isEdit == true) {
const editTopic = this.editTopic const editTopic = this.editTopic
const editUrl = `/messages/${editTopic.id}.json` const editUrl = `/messages/${editTopic.id}.json`
let attachment_ids = undefined let attachment_ids = undefined
if (this.state.fileList) { if (this.state.fileList) {
attachment_ids = this.state.fileList.map(item => { attachment_ids = this.state.fileList.map(item => {
return item.response ? item.response.id : item.id return item.response ? item.response.id : item.id
}) })
} }
axios.put(editUrl, { axios.put(editUrl, {
subject: values.subject, subject: values.subject,
board_id: values.board_id, board_id: values.board_id,
content: values.content, content: values.content,
sticky: values.sticky, sticky: values.sticky,
attachment_ids, attachment_ids,
// board_id: 3779, // board_id: 3779,
}) })
.then((response) => { .then((response) => {
if (response.data.status == 0) { if (response.data.status == 0) {
const { id } = response.data; const { id } = response.data;
console.log('--- success') console.log('--- success')
this.props.toDetailPage(cid, values.board_id, editTopic.id) this.props.toDetailPage(cid, values.board_id, editTopic.id)
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} else { } else {
const url = `/messages.json` const url = `/messages.json`
let attachment_ids = undefined let attachment_ids = undefined
if (this.state.fileList) { if (this.state.fileList) {
attachment_ids = this.state.fileList.map(item => { attachment_ids = this.state.fileList.map(item => {
return item.response.id return item.response.id
}) })
} }
axios.post(url, { axios.post(url, {
...values, ...values,
course_id: cid, course_id: cid,
board_id: boardId, board_id: boardId,
attachment_ids, attachment_ids,
}) })
.then((response) => { .then((response) => {
if (response.data) { if (response.data) {
const { id } = response.data; const { id } = response.data;
if (id) { if (id) {
console.log('--- success') console.log('--- success')
} }
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
} else { } else {
$("html").animate({ scrollTop: $('html').scrollTop() - 100 }) $("html").animate({ scrollTop: $('html').scrollTop() - 100 })
} }
}); });
} }
// 附件相关 START // 附件相关 START
handleChange = (info) => { handleChange = (info) => {
let fileList = info.fileList; let fileList = info.fileList;
this.setState({ fileList }); this.setState({ fileList });
} }
onAttachmentRemove = (file) => { onAttachmentRemove = (file) => {
confirm({ confirm({
title: '确定要删除这个附件吗?', title: '确定要删除这个附件吗?',
okText: '确定', okText: '确定',
cancelText: '取消', cancelText: '取消',
// content: 'Some descriptions', // content: 'Some descriptions',
onOk: () => { onOk: () => {
this.deleteAttachment(file) this.deleteAttachment(file)
}, },
onCancel() { onCancel() {
console.log('Cancel'); console.log('Cancel');
}, },
}); });
return false; return false;
} }
deleteAttachment = (file) => { deleteAttachment = (file) => {
const url = `/attachments/${file.id}.json` const url = `/attachments/${file.id}.json`
axios.delete(url, { axios.delete(url, {
}) })
.then((response) => { .then((response) => {
if (response.data) { if (response.data) {
const { status } = response.data; const { status } = response.data;
if (status == 0) { if (status == 0) {
console.log('--- success') console.log('--- success')
this.setState((state) => { this.setState((state) => {
const index = state.fileList.indexOf(file); const index = state.fileList.indexOf(file);
const newFileList = state.fileList.slice(); const newFileList = state.fileList.slice();
newFileList.splice(index, 1); newFileList.splice(index, 1);
return { return {
fileList: newFileList, fileList: newFileList,
}; };
}); });
} }
} }
}) })
.catch(function (error) { .catch(function (error) {
console.log(error); console.log(error);
}); });
} }
// 附件相关 ------------ END // 附件相关 ------------ END
render() { render() {
let { addGroup, fileList } = this.state; let { addGroup, fileList } = this.state;
const { getFieldDecorator } = this.props.form; const { getFieldDecorator } = this.props.form;
const formItemLayout = { const formItemLayout = {
labelCol: { labelCol: {
xs: { span: 24 }, xs: { span: 24 },
// sm: { span: 8 }, // sm: { span: 8 },
sm: { span: 24 }, sm: { span: 24 },
}, },
wrapperCol: { wrapperCol: {
xs: { span: 24 }, xs: { span: 24 },
// sm: { span: 16 }, // sm: { span: 16 },
sm: { span: 24 }, sm: { span: 24 },
}, },
}; };
const tailFormItemLayout = { const tailFormItemLayout = {
wrapperCol: { wrapperCol: {
xs: { xs: {
span: 24, span: 24,
offset: 0, offset: 0,
}, },
sm: { sm: {
span: 16, span: 16,
offset: 8, offset: 8,
}, },
}, },
}; };
const uploadProps = { const uploadProps = {
width: 600, width: 600,
fileList, fileList,
multiple: true, multiple: true,
// https://github.com/ant-design/ant-design/issues/15505 // https://github.com/ant-design/ant-design/issues/15505
// showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。 // showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。
// showUploadList: false, // showUploadList: false,
action: `${getUrl()}/api/attachments.json`, action: `${getUrl()}/api/attachments.json`,
onChange: this.handleChange, onChange: this.handleChange,
onRemove: this.onAttachmentRemove, onRemove: this.onAttachmentRemove,
beforeUpload: (file) => { beforeUpload: (file) => {
console.log('beforeUpload', file.name); console.log('beforeUpload', file.name);
const isLt150M = file.size / 1024 / 1024 < 150; const isLt150M = file.size / 1024 / 1024 < 150;
if (!isLt150M) { if (!isLt150M) {
message.error('文件大小必须小于150MB!'); message.error('文件大小必须小于150MB!');
} }
return isLt150M; return isLt150M;
}, },
}; };
return( return(
<div className="newMain "> <div className="newMain ">
<style>{` <style>{`
.courseForm .ant-form { .courseForm .ant-form {
} }
`}</style> `}</style>
<div className="edu-class-container edu-position courseForm"> <div className="edu-class-container edu-position courseForm">
<div style={{ width:'100%',height:'70px'}} > <div style={{ width:'100%',height:'70px'}} >
<p className="ml15 fl color-black mt30 summaryname">提交作品</p> <p className="ml15 fl color-black mt30 summaryname">提交作品</p>
<a href="/student_work?homework=16737" className="color-grey-6 fr font-16 ml30 mt18 mr20">返回</a> <a href="/student_work?homework=16737" className="color-grey-6 fr font-16 ml30 mt18 mr20">返回</a>
</div> </div>
<Form {...formItemLayout} onSubmit={this.handleSubmit}> <Form {...formItemLayout} onSubmit={this.handleSubmit}>
<div className="formBlock" style={{paddingBottom: '0px'}}> <div className="formBlock" style={{paddingBottom: '0px'}}>
<Form.Item <Form.Item
label="标题" label="标题"
> >
{getFieldDecorator('subject', { {getFieldDecorator('subject', {
rules: [{ rules: [{
required: true, message: '请输入标题', required: true, message: '请输入标题',
}, { }, {
max: 20, message: '最大限制为20个字符', max: 20, message: '最大限制为20个字符',
}], }],
})( })(
<Input placeholder="请输入帖子标题最大限制20个字符" /> <Input placeholder="请输入帖子标题最大限制20个字符" />
)} )}
</Form.Item> </Form.Item>
</div> </div>
<style>{` <style>{`
.courseMessageMD { .courseMessageMD {
width: 1140px; width: 1140px;
} }
.uploadBtn.ant-btn { .uploadBtn.ant-btn {
border: none; border: none;
color: #4CACFF; color: #4CACFF;
box-shadow: none; box-shadow: none;
background: transparent; background: transparent;
padding: 0 6px; padding: 0 6px;
} }
.upload_1 .ant-upload-list { .upload_1 .ant-upload-list {
width: 350px; width: 350px;
} }
`}</style> `}</style>
<div className="formBlock"> <div className="formBlock">
<Form.Item <Form.Item
label="内容" label="内容"
> className="mdInForm"
{getFieldDecorator('content', { >
rules: [{ {getFieldDecorator('content', {
required: true, message: '请输入帖子内容', rules: [{
}, { required: true, message: '请输入帖子内容',
max: 10000, message: '最大限制为10000个字符', }, {
}], max: 10000, message: '最大限制为10000个字符',
})( }],
<TPMMDEditor ref={this.mdRef} placeholder={'请在此输入帖子详情最大限制为10000个字符'} })(
mdID={'courseMessageMD'} initValue={this.editTopic ? this.editTopic.content : ''} className="courseMessageMD"></TPMMDEditor> <TPMMDEditor ref={this.mdRef} placeholder={'请在此输入帖子详情最大限制为10000个字符'}
)} mdID={'courseMessageMD'} initValue={this.editTopic ? this.editTopic.content : ''} className="courseMessageMD"></TPMMDEditor>
</Form.Item> )}
</Form.Item>
<Upload {...uploadProps} className="upload_1">
<Button className="uploadBtn"> <Upload {...uploadProps} className="upload_1">
<Icon type="upload" /> 上传附件 <Button className="uploadBtn">
</Button> <Icon type="upload" /> 上传附件
(单个文件150M以内) </Button>
</Upload> (单个文件150M以内)
</div> </Upload>
</div>
<style>{`
.courseForm .flexBlock.formBlock { <style>{`
align-items: flex-end; .courseForm .flexBlock.formBlock {
display: flex; align-items: flex-end;
flex-wrap: wrap; display: flex;
} flex-wrap: wrap;
.courseForm .flexBlock .tag { }
margin-left: 8px; .courseForm .flexBlock .tag {
margin-right: 6px; margin-left: 8px;
margin-bottom: 16px; margin-right: 6px;
} margin-bottom: 16px;
.flexBlock .ant-row.ant-form-item { }
margin-bottom: 6px; .flexBlock .ant-row.ant-form-item {
} margin-bottom: 6px;
`}</style> }
<div className="formBlock flexBlock" style={{ }} > `}</style>
<Form.Item <div className="formBlock flexBlock" style={{ }} >
label="分组设置" <Form.Item
className=" " label="分组设置"
style={{ display: 'inline-block', marginLeft: "14px" }} className=" "
> style={{ display: 'inline-block', marginLeft: "14px" }}
{getFieldDecorator('min', { >
rules: [{ {getFieldDecorator('min', {
required: true, message: '请输入每组最小人数', rules: [{
}], required: true, message: '请输入每组最小人数',
})( }],
<Input placeholder="请填写每组最小人数" /> })(
)} <Input placeholder="请填写每组最小人数" />
</Form.Item> )}
</Form.Item>
<span className="tag">~</span>
<span className="tag">~</span>
<Form.Item
label="" <Form.Item
className=" " label=""
style={{ }} className=" "
> style={{ }}
{getFieldDecorator('max', { >
rules: [{ {getFieldDecorator('max', {
// required: true, message: '请输入每组最大人数', rules: [{
}], // required: true, message: '请输入每组最大人数',
})( }],
<Input placeholder="请填写每组最大人数" /> })(
)} <Input placeholder="请填写每组最大人数" />
</Form.Item> )}
</Form.Item>
<span className="tag color-grey9 ">(项目管理员角色的成员都可以提交作品提交作品时需要关联同组成员组内成员作品共享)</span>
<Form.Item <span className="tag color-grey9 ">(项目管理员角色的成员都可以提交作品提交作品时需要关联同组成员组内成员作品共享)</span>
label="" <Form.Item
className=" " label=""
style={{ marginLeft: "14px" }} className=" "
> style={{ marginLeft: "14px" }}
{getFieldDecorator('c', { >
rules: [], {getFieldDecorator('c', {
})( rules: [],
<Checkbox >基于项目实施</Checkbox> })(
)} <Checkbox >基于项目实施</Checkbox>
</Form.Item> )}
<span className="tag color-grey9 ">(勾选后各小组必须在educoder平台创建项目教师可随时观察平台对各小组最小进展的实时统计)</span> </Form.Item>
</div> <span className="tag color-grey9 ">(勾选后各小组必须在educoder平台创建项目教师可随时观察平台对各小组最小进展的实时统计)</span>
</div>
<div className="formBlock">
<Form.Item <div className="formBlock">
label="参考答案" <Form.Item
> label="参考答案"
{getFieldDecorator('answer', { >
rules: [{ {getFieldDecorator('answer', {
required: true, message: '请输入帖子内容', rules: [{
}, { required: true, message: '请输入帖子内容',
max: 10000, message: '最大限制为10000个字符', }, {
}], max: 10000, message: '最大限制为10000个字符',
})( }],
<TPMMDEditor ref={this.mdRef} placeholder={'请在此输入参考答案最大限制为5000个字符'} })(
mdID={'courseAnswerMD'} initValue={this.editTopic ? this.editTopic.content : ''} className="courseMessageMD"></TPMMDEditor> <TPMMDEditor ref={this.mdRef} placeholder={'请在此输入参考答案最大限制为5000个字符'}
)} mdID={'courseAnswerMD'} initValue={this.editTopic ? this.editTopic.content : ''} className="courseMessageMD"></TPMMDEditor>
</Form.Item> )}
</div> </Form.Item>
</div>
<Form.Item>
<div className="clearfix mt30 mb30"> <Form.Item>
<Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">提交</Button> <div className="clearfix mt30 mb30">
<a className="defalutCancelbtn fl">取消</ a> <Button type="primary" htmlType="submit" className="defalutSubmitbtn fl mr20">提交</Button>
</div> <a className="defalutCancelbtn fl">取消</ a>
</Form.Item> </div>
</Form> </Form.Item>
</div> </Form>
</div> </div>
) </div>
} )
} }
}
const WrappedGraduateTopicPostWorksNew = Form.create({ name: 'topicPostWorksNew' })(GraduateTopicPostWorksNew);
// RouteHOC() const WrappedGraduateTopicPostWorksNew = Form.create({ name: 'topicPostWorksNew' })(GraduateTopicPostWorksNew);
// RouteHOC()
export default (WrappedGraduateTopicPostWorksNew); export default (WrappedGraduateTopicPostWorksNew);

@ -811,7 +811,7 @@ submittojoinclass=(value)=>{
closable={false} closable={false}
footer={null} footer={null}
> >
<div className="task_popup_con ml30"> <div className="task_popup_con">
<div className="mr15"> <div className="mr15">
<ul> <ul>
<li className="clearfix mb10"> <li className="clearfix mb10">

@ -123,13 +123,13 @@ export function TPMIndexHOC(WrappedComponent) {
componentDidMount() { componentDidMount() {
if(this.props.match.path==="/"){ if(this.props.match.path==="/"){
document.title="创新源于实践"; document.title="创新源于实践";
}else if(this.props.match.path==="/403"){ }else if(this.props.match.path==="/403"){
document.title="你没有权限访问"; document.title="你没有权限访问";
}else if(this.props.match.path==="/nopage"){ }else if(this.props.match.path==="/nopage"){
document.title="没有找到该页面"; document.title="没有找到该页面";
}else if(this.props.match.path==="/shixuns"){ }else if(this.props.match.path==="/shixuns"){
document.title="开发社区"; document.title="开发社区";
}else if(this.props.match.path==="/paths"){ }else if(this.props.match.path==="/paths"){
document.title="实训课程"; document.title="实训课程";
}else if(this.props.match.path==="/courses"){ }else if(this.props.match.path==="/courses"){

@ -80,8 +80,15 @@ function md_elocalStorage(editor,mdu,id){
md_add_data("content",mdu,editor.getValue()); md_add_data("content",mdu,editor.getValue());
var id1 = "#e_tip_"+id; var id1 = "#e_tip_"+id;
var id2 = "#e_tips_"+id; var id2 = "#e_tips_"+id;
$(id2).html(" 数据已于 " + h + ':' + m + ':' + s +" 保存 "); var textStart = " 数据已于 "
var text = textStart + h + ':' + m + ':' + s +" 保存 ";
// 占位符
if ($(id2).html() && $(id2).html() != ' ' && $(id2).html().startWith(textStart) == false) {
$(id2).html( $(id2).html().split(' (')[0] + ` (${text})`);
} else {
$(id2).html(text);
}
// $(id2).html(""); // $(id2).html("");
} }
},10000); },10000);

Loading…
Cancel
Save