diff --git a/public/images/edu_user/EWM.jpg b/public/images/edu_user/EWM.jpg new file mode 100644 index 000000000..3b79aca8b Binary files /dev/null and b/public/images/edu_user/EWM.jpg differ diff --git a/public/react/src/common/UrlTool.js b/public/react/src/common/UrlTool.js index 6a6bb348d..71eb8e32a 100644 --- a/public/react/src/common/UrlTool.js +++ b/public/react/src/common/UrlTool.js @@ -3,7 +3,7 @@ export function getImageUrl(path) { // https://www.educoder.net // https://testbdweb.trustie.net // const local = 'http://localhost:3000' - const local = 'https://testeduplus2.educoder.net' + const local = 'http://47.96.87.25:48080' if (isDev) { return `${local}/${path}` } diff --git a/public/react/src/context/TPIContextProvider.js b/public/react/src/context/TPIContextProvider.js index 51769b605..ae88bf865 100644 --- a/public/react/src/context/TPIContextProvider.js +++ b/public/react/src/context/TPIContextProvider.js @@ -171,7 +171,7 @@ class TPIContextProvider extends Component { } let testPath = '' if (window.location.port == 3007) { - testPath = 'https://testeduplus2.educoder.net' + testPath = 'http://47.96.87.25:48080' } // var url = `${testPath}/api/v1/games/${ game.identifier }/cost_time` var url = `${testPath}/api/tasks/${ game.identifier }/cost_time` diff --git a/public/react/src/modules/courses/Resource/Fileslistitem.js b/public/react/src/modules/courses/Resource/Fileslistitem.js index 1165eae5a..a20dcf9c3 100644 --- a/public/react/src/modules/courses/Resource/Fileslistitem.js +++ b/public/react/src/modules/courses/Resource/Fileslistitem.js @@ -169,7 +169,8 @@ class Fileslistitem extends Component{ margin-top: 0px; } `} - {checkBox} + +
- + + {checkBox} + { this.props.isAdmin ? {discussMessage.course_groups.length===0?"": -

+

{discussMessage.course_groups.map((item,key)=>{ return(

@@ -275,7 +278,7 @@ class Fileslistitem extends Component{

} -

+

{discussMessage.author.login} 大小 {discussMessage.filesize} @@ -290,7 +293,7 @@ class Fileslistitem extends Component{ {this.props.isAdmin ||this.props.current_user.login===discussMessage.author.login? - + - - {/**/} - -

资源描述 :{discussMessage.description===null?"暂无描述":discussMessage.description}
- - {/*{this.props.isAdmin ?this.settingList()}>:""}*/} - +

+

资源描述 :{discussMessage.description===null?"暂无描述":discussMessage.description}
+ {/**/} + {/*/!**!/*/} + {/**/} + + {/**/} + {/*/!*{this.props.isAdmin ?this.settingList()}>:""}*!/*/} + {/**/}

diff --git a/public/react/src/modules/courses/busyWork/CommonWorkItem.js b/public/react/src/modules/courses/busyWork/CommonWorkItem.js index 2ac4761e1..f30e43d21 100644 --- a/public/react/src/modules/courses/busyWork/CommonWorkItem.js +++ b/public/react/src/modules/courses/busyWork/CommonWorkItem.js @@ -97,13 +97,6 @@ class CommonWorkItem extends Component{ setupdate = () => { } - toCreateProject = () => { - if (window.location.port == 3007) { - window.location.href = '/testbdweb.educoder.net/projects/new' - } else { - window.location.href = '/projects/new' - } - } render(){ let { mainList,workType }=this.props; const { aModalVisible, fileList, revise_reason } = this.state diff --git a/public/react/src/modules/courses/busyWork/ConnectProject.js b/public/react/src/modules/courses/busyWork/ConnectProject.js index 73a4da8f8..c1fd4185c 100644 --- a/public/react/src/modules/courses/busyWork/ConnectProject.js +++ b/public/react/src/modules/courses/busyWork/ConnectProject.js @@ -85,13 +85,6 @@ class ConnectProject extends Component{ 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)=>{ this.work = work; @@ -175,7 +168,7 @@ class ConnectProject extends Component{ { (!haveProjects) &&
- 您当前尚未管理任何项目,请先创建项目再关联 + 您当前尚未管理任何项目,请先创建项目再关联
} diff --git a/public/react/src/modules/courses/busyWork/NewWork.js b/public/react/src/modules/courses/busyWork/NewWork.js index a6fc93c92..c30832c8f 100644 --- a/public/react/src/modules/courses/busyWork/NewWork.js +++ b/public/react/src/modules/courses/busyWork/NewWork.js @@ -477,7 +477,7 @@ class NewWork extends Component{ ~ {/* min={has_commit ? init_max_num : (min_num == undefined ? 2 : min_num + 1) } */} - diff --git a/public/react/src/modules/courses/busyWork/UseBank.js b/public/react/src/modules/courses/busyWork/UseBank.js index 7bddb9979..142c65c5c 100644 --- a/public/react/src/modules/courses/busyWork/UseBank.js +++ b/public/react/src/modules/courses/busyWork/UseBank.js @@ -187,7 +187,13 @@ class UseBank extends Component{ display: -webkit-flex; } .setImgW .edu-nodata-img{ - width:218px!important; + width:218px !important; + } + .bankwidth{ + width:29% !important; + overflow:hidden; + text-overflow:ellipsis; + white-space:nowrap } `} @@ -269,7 +275,10 @@ class UseBank extends Component{ - 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} + 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} { nav_my==='public' && {item.username} diff --git a/public/react/src/modules/courses/busyWork/common.js b/public/react/src/modules/courses/busyWork/common.js index 61bd7fcee..9eb901d9d 100644 --- a/public/react/src/modules/courses/busyWork/common.js +++ b/public/react/src/modules/courses/busyWork/common.js @@ -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 // 是否是分组作业 isGroup = () => { @@ -156,7 +163,7 @@ export function RouteHOC(options = {}) { toWorkQuestionPage={this.toWorkQuestionPage} toWorkSettingPage={this.toWorkSettingPage} - + toCreateProject={this.toCreateProject} isGroup={this.isGroup} getModuleName={this.getModuleName} diff --git a/public/react/src/modules/courses/coursesDetail/CoursesBanner.js b/public/react/src/modules/courses/coursesDetail/CoursesBanner.js index f4f097a33..3389951f5 100644 --- a/public/react/src/modules/courses/coursesDetail/CoursesBanner.js +++ b/public/react/src/modules/courses/coursesDetail/CoursesBanner.js @@ -454,10 +454,19 @@ class CoursesBanner extends Component {
+
} diff --git a/public/react/src/modules/courses/coursesPublic/SelectSetting.js b/public/react/src/modules/courses/coursesPublic/SelectSetting.js index 2b4b935ba..61cbecf11 100644 --- a/public/react/src/modules/courses/coursesPublic/SelectSetting.js +++ b/public/react/src/modules/courses/coursesPublic/SelectSetting.js @@ -475,7 +475,7 @@ class Selectsetting extends Component{ `}
  • - {datalist&&datalist.title} + {datalist&&datalist.title} {datalist&&datalist.attachment_histories.length===0?"":当前版本}
  • - {item.title} + {item.title} {/*当前版本*/}
  • -
    +
    {exercise&&exercise.exercise_name}
    -
    {exercise&&exercise.exercise_description}
    +
    {exercise&&exercise.exercise_description}
    -
    +

    { exercise_types && exercise_types.q_singles > 0 && diff --git a/public/react/src/modules/courses/exercise/ExerciseListItem.js b/public/react/src/modules/courses/exercise/ExerciseListItem.js index eb0377022..70df3f577 100644 --- a/public/react/src/modules/courses/exercise/ExerciseListItem.js +++ b/public/react/src/modules/courses/exercise/ExerciseListItem.js @@ -167,7 +167,7 @@ class ExerciseListItem extends Component{ { IsAdmin &&

    } diff --git a/public/react/src/modules/courses/exercise/ExerciseNew.js b/public/react/src/modules/courses/exercise/ExerciseNew.js index 8bc7ed6ae..0e1489c72 100644 --- a/public/react/src/modules/courses/exercise/ExerciseNew.js +++ b/public/react/src/modules/courses/exercise/ExerciseNew.js @@ -342,6 +342,11 @@ class ExerciceNew extends Component{ 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`) + } render() { let { exercise_name, exercise_description, course_id, exercise_types, exercise_questions, left_banner_id } = this.state; @@ -366,6 +371,8 @@ class ExerciceNew extends Component{ 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, @@ -395,7 +402,7 @@ class ExerciceNew extends Component{ background: #fff; } .exerciseNew .markdown-body { - max-width: 1088px; + max-width: 1128px; } `}
    @@ -546,6 +553,11 @@ class ExerciceNew extends Component{ this.addShixun(null)}> 实训题 + + {exercise_id && this.goToPreview()}> + {/* */} + 试卷预览 + }
    }
    diff --git a/public/react/src/modules/courses/exercise/new/NullChildEditor.js b/public/react/src/modules/courses/exercise/new/NullChildEditor.js index a78028b20..434211f1d 100644 --- a/public/react/src/modules/courses/exercise/new/NullChildEditor.js +++ b/public/react/src/modules/courses/exercise/new/NullChildEditor.js @@ -39,14 +39,14 @@ class NullChildEditor extends Component{ let { question_title, question_score, question_type, question_choices, standard_answers } = this.state; let { question_id, index, onAnswerChange, addChildAnswer, toMDMode, exerciseIsPublish, answers } = this.props; - + // marginTop: '18px' return( -
    +
    答案(填空{index + 1}):
    { answers.map((item, itemIndex) => { - return
    + return
    diff --git a/public/react/src/modules/courses/exercise/new/SingleDisplay.js b/public/react/src/modules/courses/exercise/new/SingleDisplay.js index 8973d53db..453cce229 100644 --- a/public/react/src/modules/courses/exercise/new/SingleDisplay.js +++ b/public/react/src/modules/courses/exercise/new/SingleDisplay.js @@ -71,7 +71,7 @@ class SingleDisplay extends Component{ let length = 5; const qName = qNameArray[question_type] return( -
    +
    }
    + {this.props.isAdmin?
    实训详情 {this.props.isClassManagement?this.editname(discussMessage.name,discussMessage.homework_id)} className={"btn colorblue ml20 font-16"}>重命名:""} 设置 diff --git a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js index 12d21fb53..5d9d2d200 100644 --- a/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js +++ b/public/react/src/modules/courses/shixunHomework/Trainingjobsetting.js @@ -1708,7 +1708,7 @@ class Trainingjobsetting extends Component { 立即发布 : "": ""} {this.props.isAdmin()? - this.state.code_review===true?代码查重 + this.state.code_review===false?代码查重 : "":""}
    diff --git a/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js b/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js index 35b9d7de7..fe6d68c77 100644 --- a/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js +++ b/public/react/src/modules/courses/shixunHomework/Workquestionandanswer.js @@ -421,7 +421,7 @@ class Workquestionandanswer extends Component { {this.props.isAdmin()? - this.state.code_review===true? + this.state.code_review===false? 代码查重 :"":""} diff --git a/public/react/src/modules/courses/shixunHomework/shixunHomework.js b/public/react/src/modules/courses/shixunHomework/shixunHomework.js index c3be53486..e9c6103e1 100644 --- a/public/react/src/modules/courses/shixunHomework/shixunHomework.js +++ b/public/react/src/modules/courses/shixunHomework/shixunHomework.js @@ -753,7 +753,7 @@ class ShixunHomework extends Component{ }) this.props.showNotification(response.data.message) this.homeworkupdatalist(Coursename,page,order); - + this.props.updataleftNavfun() } }) .catch(function (error) { @@ -782,7 +782,7 @@ class ShixunHomework extends Component{ this.setState({ Modalstype:true, - Modalstopval:"已提交作品将全部被删除,不可恢复,", + Modalstopval:"已提交作品将全部被删除,不可恢复", ModalsBottomval:"是否确认删除?", ModalCancel:this.cancelmodel, ModalSave:this.savedelete, @@ -1074,7 +1074,7 @@ class ShixunHomework extends Component{ {/*this.editname(datas&&datas.main_category_name)} className={"mr30"}>目录重命名*/} : this.editDir(datas&&datas.category_name)} className={"mr30 font-16"}>目录重命名:""} - {this.props.isAdmin()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null?选用实训课程:"":""} + {this.props.isAdmin()===true?datas&&datas.category_name===undefined||datas&&datas.category_name===null?选用实训课程:"":""} {this.props.isAdmin()===true?this.createCommonWork()}>选用实训:""}
  • @@ -1085,7 +1085,7 @@ class ShixunHomework extends Component{
    共 {datas&&datas.all_count}个实训作业 已发布:{datas&&datas.published_count}个 - {this.props.isAdmin()?未发布: {datas&&datas.unpublished_count}个:""} + 未发布: {datas&&datas.unpublished_count}个

    diff --git a/public/react/src/modules/courses/shixunHomework/shixunreport/ConclusionEvaluation.js b/public/react/src/modules/courses/shixunHomework/shixunreport/ConclusionEvaluation.js index ec9bf974b..5e922d7eb 100644 --- a/public/react/src/modules/courses/shixunHomework/shixunreport/ConclusionEvaluation.js +++ b/public/react/src/modules/courses/shixunHomework/shixunreport/ConclusionEvaluation.js @@ -1,103 +1,109 @@ -import React, {Component} from "react"; -import {WordsBtn} from 'educoder'; -import {Table} from "antd"; -import {Link,Switch,Route,Redirect} from 'react-router-dom'; - -class ConclusionEvaluation extends Component { - - constructor(props) { - super(props); - this.state = { - } - } - - componentDidMount() { - - } - - render() { - let {data}=this.props; - let columns=[{ - title: '总评', - dataIndex: 'type', - key: 'type', - render: (text, record) => ( - {record.type} - ), - }, { - title: '获得经验值', - dataIndex: 'empirical', - key: 'empirical', - render: (text, record) => ( - - {record.empirical.minute}/{record.empirical.total} - - ), - }, { - title: '作业成绩', - dataIndex: 'grade', - key: 'grade', - render: (text, record) => ( - - {record.grade.minute}/{record.grade.minute} - - ), - }, { - title: '耗时', - key: 'elapsed', - dataIndex: 'elapsed', - - render: (text, record) => ( - - {record.elapsed} - - ), - }, { - title: '评测次数', - key: 'time', - dataIndex: 'time', - render: (text, record) => ( - - {record.time} - - ), - }]; - - let datas=[]; - - datas.push({ - type: data&&data.overall_appraisal, - empirical: {minute:data&&data.myself_experience,total:data&&data.total_experience}, - grade: {minute:data&&data.work_score,total:data&&data.all_work_score}, - elapsed: data&&data.time_consuming, - time:data&&data.evaluate_count - }) - return ( -
    - {/*{data===undefined?"":""}*/} - - - - - ) - } -} - +import React, {Component} from "react"; +import {WordsBtn} from 'educoder'; +import {Table,Tooltip,} from "antd"; +import {Link,Switch,Route,Redirect} from 'react-router-dom'; + +class ConclusionEvaluation extends Component { + + constructor(props) { + super(props); + this.state = { + } + } + + componentDidMount() { + + } + + render() { + let {data}=this.props; + let columns=[{ + title: '总评', + dataIndex: 'type', + key: 'type', + render: (text, record) => ( + {record.type} + ), + }, { + title: '获得经验值', + dataIndex: 'empirical', + key: 'empirical', + render: (text, record) => ( + + {record.empirical.minute}/{record.empirical.total} + + ), + }, { + title: '作业成绩', + dataIndex: 'grade', + key: 'grade', + render: (text, record) => ( + + + 分数:{record.grade.minute}/总分:{record.grade.total} + + }> + {record.grade.minute}/{record.grade.total} + + + ), + }, { + title: '耗时', + key: 'elapsed', + dataIndex: 'elapsed', + + render: (text, record) => ( + + {record.elapsed} + + ), + }, { + title: '评测次数', + key: 'time', + dataIndex: 'time', + render: (text, record) => ( + + {record.time} + + ), + }]; + + let datas=[]; + + datas.push({ + type: data&&data.overall_appraisal, + empirical: {minute:data&&data.myself_experience,total:data&&data.total_experience}, + grade: {minute:data&&data.work_score,total:data&&data.all_work_score}, + elapsed: data&&data.time_consuming, + time:data&&data.evaluate_count + }) + return ( +
    + {/*{data===undefined?"":""}*/} + +
    + + + ) + } +} + export default ConclusionEvaluation; \ No newline at end of file diff --git a/public/react/src/modules/courses/shixunHomework/shixunreport/Coursesshixundetails.js b/public/react/src/modules/courses/shixunHomework/shixunreport/Coursesshixundetails.js index 56b3ff9a2..529a4646b 100644 --- a/public/react/src/modules/courses/shixunHomework/shixunreport/Coursesshixundetails.js +++ b/public/react/src/modules/courses/shixunHomework/shixunreport/Coursesshixundetails.js @@ -1,73 +1,74 @@ -import React, {Component} from "react"; -import {WordsBtn} from 'educoder'; -import {Table} from "antd"; -import {Link,Switch,Route,Redirect} from 'react-router-dom'; - -class Coursesshixundetails extends Component { - - constructor(props) { - super(props); - this.state = { - loadingstate:true - } - } - - componentDidMount() { - - } - - render() { - let {data}=this.props; - let columns=[{ - title: '评测次数', - dataIndex: 'number', - width:"127px", - key: 'number', - render: (text, record) => ( - - {record.number} - - ), - }, { - title: '详细信息', - dataIndex: 'name', - key: 'name', - render: (text, record) => ( - - {record.name} - - ), - }]; - - let datas=[]; - data&&data.forEach((item,key)=>{ - datas.push({ - number: item.position, - name: item.output_detail - - }) - }) - - return ( -
    - - {data&&data?
    :""} - - - ) - } -} - +import React, {Component} from "react"; +import {WordsBtn} from 'educoder'; +import {Table} from "antd"; +import {Link,Switch,Route,Redirect} from 'react-router-dom'; + +class Coursesshixundetails extends Component { + + constructor(props) { + super(props); + this.state = { + loadingstate:true + } + } + + componentDidMount() { + + } + + render() { + let {data}=this.props; + // console.log(data) + let columns=[{ + title: '评测次数', + dataIndex: 'number', + width:"127px", + key: 'number', + render: (text, record) => ( + + {record.number} + + ), + }, { + title: '详细信息', + dataIndex: 'name', + key: 'name', + render: (text, record) => ( + + {record.name} + + ), + }]; + + let datas=[]; + data&&data.forEach((item,key)=>{ + datas.push({ + number: item.position, + name: item.output_detail + + }) + }) + + return ( +
    + + {data&&data? data.length===0?"":
    :""} + + + ) + } +} + export default Coursesshixundetails; \ No newline at end of file diff --git a/public/react/src/modules/courses/shixunHomework/shixunreport/Shixunechart.js b/public/react/src/modules/courses/shixunHomework/shixunreport/Shixunechart.js index 99b9d5748..dcb10a301 100644 --- a/public/react/src/modules/courses/shixunHomework/shixunreport/Shixunechart.js +++ b/public/react/src/modules/courses/shixunHomework/shixunreport/Shixunechart.js @@ -61,7 +61,7 @@ function startechart(data){ yAxis: [ { type : "value", - name : " 实训总得分/实训总耗时", + name : " 实训总得分/实训总耗时", nameGap: 20, nameTextStyle: { color: '#000', diff --git a/public/react/src/modules/tpm/NewHeader.js b/public/react/src/modules/tpm/NewHeader.js index f43991599..a2ddb242a 100644 --- a/public/react/src/modules/tpm/NewHeader.js +++ b/public/react/src/modules/tpm/NewHeader.js @@ -787,7 +787,7 @@ submittojoinclass=(value)=>{
  • 新建课堂
  • 新建实训
  • 新建实训课程
  • -
  • 新建项目
  • +
  • 新建项目
    • @@ -811,7 +811,7 @@ submittojoinclass=(value)=>{ closable={false} footer={null} > -
      +
      • diff --git a/public/react/src/modules/tpm/TPMIndexHOC.js b/public/react/src/modules/tpm/TPMIndexHOC.js index 1ae9e34fb..fff1ce231 100644 --- a/public/react/src/modules/tpm/TPMIndexHOC.js +++ b/public/react/src/modules/tpm/TPMIndexHOC.js @@ -123,13 +123,13 @@ export function TPMIndexHOC(WrappedComponent) { componentDidMount() { if(this.props.match.path==="/"){ - document.title="创新源于实践"; + document.title="创新源于实践"; }else if(this.props.match.path==="/403"){ - document.title="你没有权限访问"; + document.title="你没有权限访问"; }else if(this.props.match.path==="/nopage"){ document.title="没有找到该页面"; }else if(this.props.match.path==="/shixuns"){ - document.title="开发社区"; + document.title="开发社区"; }else if(this.props.match.path==="/paths"){ document.title="实训课程"; }else if(this.props.match.path==="/courses"){ diff --git a/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js b/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js index 0f00d1c25..47efccf74 100644 --- a/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js +++ b/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js @@ -80,8 +80,15 @@ function md_elocalStorage(editor,mdu,id){ md_add_data("content",mdu,editor.getValue()); var id1 = "#e_tip_"+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(""); } },10000); diff --git a/public/react/src/modules/tpm/challengesnew/TPMevaluation.js b/public/react/src/modules/tpm/challengesnew/TPMevaluation.js index 1c55700ae..73262de74 100644 --- a/public/react/src/modules/tpm/challengesnew/TPMevaluation.js +++ b/public/react/src/modules/tpm/challengesnew/TPMevaluation.js @@ -1,1112 +1,1115 @@ -import React, {Component} from 'react'; - -import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal,Button,Icon,Tooltip} from 'antd'; - -import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom"; - -// import "antd/dist/antd.css"; - -import axios from 'axios'; - -import { getImageUrl, toPath } from 'educoder'; - -import './css/TPMchallengesnew.css'; - -import {getUrl} from 'educoder'; - -let origin = getUrl(); - -let path = getUrl("/editormd/lib/") - -const $ = window.$; - -let timeout; - -let currentValue; - -const Option = Select.Option; - -const RadioGroup = Radio.Group; - -function create_editorMD(id, width, high, placeholder, imageUrl, callback) { - var editorName = window.editormd(id, { - width: width, - height: high, - path: path, // "/editormd/lib/" - - syncScrolling: "single", - tex: true, - tocm: true, - emoji: true, - taskList: true, - codeFold: true, - searchReplace: true, - htmlDecode: "style,script,iframe", - sequenceDiagram: true, - autoFocus: false, - toolbarIcons: function () { - // Or return editormd.toolbarModes[name]; // full, simple, mini - // Using "||" set icons align right. - return ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"] - }, - toolbarCustomIcons: { - testIcon: "
        ", - testIcon1: "
        " - }, - //这个配置在simple.html中并没有,但是为了能够提交表单,使用这个配置可以让构造出来的HTML代码直接在第二个隐藏的textarea域中,方便post提交表单。 - saveHTMLToTextarea: true, - // 用于增加自定义工具栏的功能,可以直接插入HTML标签,不使用默认的元素创建图标 - dialogMaskOpacity: 0.6, - placeholder: placeholder, - imageUpload: true, - imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"], - imageUploadURL: imageUrl,//url - onload: function () { - // this.previewing(); - $("#" + id + " [type=\"latex\"]").bind("click", function () { - editorName.cm.replaceSelection("```latex"); - editorName.cm.replaceSelection("\n"); - editorName.cm.replaceSelection("\n"); - editorName.cm.replaceSelection("```"); - var __Cursor = editorName.cm.getDoc().getCursor(); - editorName.cm.setCursor(__Cursor.line - 1, 0); - }); - - $("#" + id + " [type=\"inline\"]").bind("click", function () { - editorName.cm.replaceSelection("$$$$"); - var __Cursor = editorName.cm.getDoc().getCursor(); - editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2); - editorName.cm.focus(); - }); - $("[type=\"inline\"]").attr("title", "行内公式"); - $("[type=\"latex\"]").attr("title", "多行公式"); - - window.md_elocalStorage(editorName, `exercise__${id}`, "Memochallengesnew"); - - callback && callback() - } - }); - return editorName; -} - - -export default class TPMevaluation extends Component { - constructor(props) { - super(props) - this.state = { - choice_url: undefined, - practice_url: undefined, - go_back_url: undefined, - task_pass_default: undefined, - submit_url: undefined, - value: 1, - evaluationlist:[], - shixunId:undefined, - power:false, - shixunfilepath:undefined, - evaluationvisible:false, - trees:undefined, - path:"", - main:[], - saveshixunfilepath:undefined, - selectpath:undefined, - shixunfilepathplay:undefined, - shixunfileexpectpicturepath:undefined, - shixunfilestandardpicturepath:undefined, - shixunfilepicturepath:undefined, - pathoptionvalue:-1, - showrepositoryurltiptype: false, - prev_challenge: undefined, - next_challenge: undefined, - StudentTaskPapers:false, - StudentTaskDocs:false, - selectpatharr:[], - handpathopt:false, - scorevalue:false, - markvalue:true, - scoretype:undefined - } - } - - - exerciseMD(initValue, id) { - - this.contentChanged = false; - const placeholder = ""; -// amp; -// 编辑时要传memoId - const imageUrl = `/api/attachments.json`; -// 创建editorMd - - const exercise_editormd = create_editorMD(id, '100%', 400, placeholder, imageUrl, () => { - setTimeout(() => { - exercise_editormd.resize() - exercise_editormd.cm && exercise_editormd.cm.refresh() - }, 500) - - if (initValue != undefined) { - exercise_editormd.setValue(initValue) - } - exercise_editormd.cm.on("change", (_cm, changeObj) => { - console.log('....contentChanged') - this.contentChanged = true; - }) - }); - this.exercise_editormd = exercise_editormd; - window.exercise_editormd = exercise_editormd; - - } - - componentDidMount() { - let id = this.props.match.params.shixunId; - let checkpointId=this.props.match.params.checkpointId; - this.setState({ - shixunId:id, - checkpointId:checkpointId - }) - let newchoice_url= "/shixuns/"+id+"/challenges/newquestion"; - let newpractice_url= "/shixuns/"+id+"/challenges/new"; - let newgo_back_url="/shixuns/"+id+"/challenges"; - - let url = "/shixuns/" + id + "/challenges/" + checkpointId + "/edit.json?tab=1"; - axios.get(url).then((response) => { - let newprev_challenge = response.data.prev_challenge; - let next_challenge = response.data.next_challenge; - if (newprev_challenge != undefined) { - if(newprev_challenge.st===0){ - newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editcheckpoint"; - }else{ - newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editquestion"; - } - } - if (next_challenge != undefined) { - - if(next_challenge.st===0){ - next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editcheckpoint"; - }else{ - next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editquestion"; - } - } - let newevaluationlist=[] - if(response.data.test_sets.length===0){ - let newlist=[ - {hidden:0,input:"",output:"",score:50}, - {hidden:1,input:"",output:"",score:50} - ] - newevaluationlist=newlist - }else{ - newevaluationlist=response.data.test_sets - } - - this.setState({ - power: response.data.power, - evaluationlist:newevaluationlist, - shixunfilepath:response.data.path, - shixunfilepathplay:response.data.exec_path, - pathoptionvalue:response.data.show_type, - shixunfileexpectpicturepath:response.data.original_picture_path, - shixunfilestandardpicturepath:response.data.expect_picture_path, - shixunfilepicturepath:response.data.picture_path, - prev_challenge: newprev_challenge, - next_challenge: next_challenge, - choice_url: newchoice_url, // 导航中的新建选择题url - practice_url: newpractice_url, //string 导航中新建实践题url - go_back_url: newgo_back_url, //string 导航中的返回url - position: response.data.position, //int 关卡位置,导航栏中的第几关 - scorevalue:response.data.test_set_score, - markvalue:response.data.test_set_average, - }) - this.evaluationoninputvalueonload(); - if(response.data.power===false){ - this.props.showSnackbar("你没有权限修改"); - } - if(response.data.answer===undefined){ - this.answerMD("", "answerMD"); - }else{ - this.answerMD(response.data.answer, "answerMD"); - } - - }).catch((error) => { - console.log(error) - }); - - } - - - setevaluationlist=(newevaluationlist)=>{ - this.setState({ - evaluationlist:newevaluationlist - }) - } - - - addevaluationon=()=>{ - let {evaluationlist,markvalue}=this.state; - let newevaluationlist=evaluationlist; - newevaluationlist.push({hidden:0,input:"",output:"",score:0}); - newevaluationlist=this.oneditevaluationlist(newevaluationlist,markvalue); - this.setevaluationlist(newevaluationlist); - } - - del_test_array=(key)=>{ - let {evaluationlist,markvalue}=this.state; - let newevaluationlist=evaluationlist; - newevaluationlist.splice(key,1); - newevaluationlist=this.oneditevaluationlist(newevaluationlist,markvalue); - this.setevaluationlist(newevaluationlist); - } - - getfilepath=(e,shixunfilepath)=>{ - this.setState({ - evaluationvisible: true, - selectpath:e.target.value, - selectpatharr:[], - }); - let id = this.props.match.params.shixunId; - let url ="/shixuns/"+id+"/repository.json"; - axios.post(url,{ - path: "" - }).then((response) => { - if (response.data.status === 403||response.data.status === 401||response.data.status === 500) { - - }else{ - this.setState({ - trees:response.data.trees, - saveshixunfilepath:shixunfilepath, - path:"", - main:[], - }) - } - - }).catch((error) => { - console.log(error) - }); - } - - sendgetfilepath=(newpath,type)=>{ - let id = this.props.match.params.shixunId; - let{path,main}=this.state; - let ary=main; - let paths=path; - - this.setState({ - selectpatharr:[], - }) - if(paths===""&&type==="tree"){ - newpath=newpath+"/"; - paths=""; - if(main.length===0){ - ary.push({val:"根目录/",path:""},{val:newpath,path:paths+newpath}) - }else{ - ary.push({val:newpath,path:paths+newpath}) - } - - }else if(paths!=""&&type==="tree"){ - newpath=newpath+"/"; - ary.push({val:newpath,path:paths+newpath}) - } - - - let url ="/shixuns/"+id+"/repository.json"; - if(type==="tree"){ - - axios.post(url,{ - path: paths+newpath - }).then((response) => { - if (response.data.status === 403||response.data.status === 401||response.data.status === 500) { - - }else{ - this.setState({ - trees:response.data.trees, - path:paths+newpath, - main:ary, - // selectpath:"" - }) - } - - }).catch((error) => { - console.log(error) - }); - } - - } - - goblakepath=(path,key)=>{ - let {main,selectpath} =this.state; - let newmain=[] - for(var i=0;i<=key;i++){ - newmain.push(main[i]) - } - let id = this.props.match.params.shixunId; - let url ="/shixuns/"+id+"/repository.json"; - axios.post(url,{ - path: path - }).then((response) => { - if (response.data.status === 403||response.data.status === 401||response.data.status === 500) { - - }else { - this.setState({ - trees: response.data.trees, - path: path, - main: newmain, - // selectpath:selectpath - }) - } - }).catch((error) => { - console.log(error) - }); - } - // delesavegetfilepath=(value)=>{ - // let {selectpatharr} = this.state - // let newarr =selectpatharr; - // let newselectpath=""; - // for(var i=0; i{ - let {selectpath} = this.state - // let newarr =selectpatharr; - // let arrtype=false; - // let arrsum=0; - // let newselectpath=""; - // newarr.push(value) - // if(newarr.length>1&&arrtype===false){ - // for(var i=0; i{ - let {saveshixunfilepath,selectpath}=this.state; - this.setState({ - evaluationvisible: false, - [saveshixunfilepath]:selectpath - }); - } - evaluationhideModal=()=>{ - this.setState({ - evaluationvisible: false, - }); - } - handpathoptionvalue=(value)=>{ - this.setState({ - pathoptionvalue:value - }) - } - showrepositoryurltip=(type)=>{ - if(type===1){ - this.setState({ - showrepositoryurltiptype:true - }) - }else{ - this.setState({ - showrepositoryurltiptype:false - }) - } - } - - evaluationonChange=(e,key)=>{ - let {evaluationlist}=this.state; - let newevaluationlist=evaluationlist; - let newtype; - if(e===1){ - newtype=0; - }else{ - newtype=1; - } - // newevaluationlist[key].is_public=newtype; - // for(var i=0; i{ - let {evaluationlist,scoretype}=this.state; - - if(scoretype===key){ - this.setState({ - scoretype:undefined - }) - } - let newevaluationlist=evaluationlist; - let sum =parseInt(e.target.value); - if(isNaN(sum)){ - sum=0 - } - newevaluationlist[key].score=sum; - - this.setState({ - evaluationlist:newevaluationlist, - markvalue:false - }) - this.setevaluationlist(newevaluationlist); - } - - evaluationoninputvalue=(e,key,type)=>{ - $.fn.autoHeight = function(){ - function autoHeight(elem){ - elem.style.height = 'auto'; - elem.style.maxHeight = '140px'; - elem.scrollTop = 0; //防抖动 - elem.style.height = elem.scrollHeight + 'px'; - } - this.each(function(){ - autoHeight(this); - $(this).on('keyup', function(){ - autoHeight(this); - }); - }); - } - $('textarea[autoHeight]').autoHeight(); - - let {evaluationlist}=this.state; - let newevaluationlist=evaluationlist; - if(type==="sr"){ - newevaluationlist[key].input=e.target.value - }else if(type==="yq"){ - newevaluationlist[key].output=e.target.value - } - this.setevaluationlist(newevaluationlist); - } - - - evaluationoninputvalueonload=()=>{ - $.fn.autoHeight = function(){ - function autoHeight(elem){ - elem.style.height = 'auto'; - elem.style.maxHeight = '140px'; - elem.scrollTop = 0; //防抖动 - elem.style.height = elem.scrollHeight + 'px'; - } - this.each(function(){ - autoHeight(this); - $(this).on('keyup', function(){ - autoHeight(this); - }); - }); - } - $('textarea[autoHeight]').autoHeight(); - } - submitarbitrationevaluation=()=>{ - let{evaluationlist,shixunfilepath,shixunfilepathplay,shixunfileexpectpicturepath,shixunfilestandardpicturepath,shixunfilepicturepath,pathoptionvalue,scorevalue,markvalue}=this.state; - - - let newscorevalue; - if(scorevalue===false){ - newscorevalue=false - }else{ - //判断占比 - newscorevalue=true - - let sum=0; - for(var i=0; i100){ - this.props.showSnackbar("测试集的评分占比不能大于100"); - this.setState({ - scoretype:i - }) - return - } - sum=sum+evaluationlist[i].score - } - - if(sum>100||sum<100){ - this.props.showSnackbar("测试集的评分占比之和必须等于100"); - return - } - - - } - if(shixunfilepath===undefined||shixunfilepath===""||shixunfilepath===null){ - this.props.showSnackbar("学员任务文件路径为空"); - this.setState({ - StudentTaskPapers:true - }) - $('html').animate({ - scrollTop: 120 - }, 1000); - return - } - - if(shixunfilepathplay===undefined||shixunfilepathplay===""||shixunfilepathplay===null){ - this.props.showSnackbar("评测执行文件路径为空"); - this.setState({ - StudentTaskDocs:true - }) - $('html').animate({ - scrollTop: 130 - }, 1000); - return - } - - if(evaluationlist.length===0){ - this.props.showSnackbar("测试集不能为空"); - return - } - let id = this.props.match.params.shixunId; - let{checkpointId}=this.state; - let url = "/shixuns/"+id+"/challenges/"+checkpointId+".json"; - axios.put(url,{ - tab:1, - challenge:{ - path:shixunfilepath, - exec_path:shixunfilepathplay, - show_type:pathoptionvalue, - original_picture_path:shixunfileexpectpicturepath, - expect_picture_path:shixunfilestandardpicturepath, - picture_path:shixunfilepicturepath, - test_set_score:newscorevalue, - test_set_average:markvalue - }, - test_set:evaluationlist - } - ).then((response) => { - this.props.showSnackbar(response.data.messages); - // if(response.data.status===1){ - // window.location.href = "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=3" - // } - }).catch((error) => { - console.log(error) - }); - } - handpathoptionvalues=()=>{ - this.setState({ - handpathopt:true - }) - } - handpathoptionvaluess=()=>{ - this.setState({ - handpathopt:false - }) - } - saveselectpath=(e)=>{ - - this.setState({ - selectpath:e.target.value - }) - } - updatepath=(e,name)=>{ - this.setState({ - [name]:e.target.value - }) - } - - - oneditevaluationlist=(newevaluationlist,markvalue)=>{ - - if(markvalue===true){ - if(100%newevaluationlist.length===0){ - let sum=100/newevaluationlist.length; - for(var i=0; i{ - - let {markvalue,evaluationlist}=this.state; - let newevaluationlist=evaluationlist; - - if(e.target.value===true){ - newevaluationlist=this.oneditevaluationlist(newevaluationlist,markvalue) - } - - this.setState({ - scorevalue: e.target.value, - evaluationlist:newevaluationlist - }); - - this.setevaluationlist(newevaluationlist); - } - - //均匀比例 - onChangemarkvalue=(e)=>{ - let {evaluationlist}=this.state; - - if(e.target.value===true){ - let newevaluationlist=evaluationlist; - newevaluationlist=this.oneditevaluationlist(newevaluationlist,e.target.value); - this.setevaluationlist(newevaluationlist); - } - - this.setState({ - markvalue: e.target.value, - }); - - } - render() { - - let { - choice_url, - practice_url, - go_back_url, - position, - evaluationlist, - shixunId, - checkpointId, - power, - shixunfileexpectpicturepath, - shixunfilestandardpicturepath, - shixunfilepicturepath, - shixunfilepath, - evaluationvisible, - trees, - path, - main, - selectpath, - shixunfilepathplay, - pathoptionvalue, - showrepositoryurltiptype, - prev_challenge, - next_challenge, - StudentTaskPapers, - StudentTaskDocs, - handpathopt, - scorevalue, - markvalue, - scoretype - } = this.state; - - let tab1url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/editcheckpoint"; - let tab2url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/tab=2"; - let tab3url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/tab=3"; - // console.log(this.props) - const radioStyle = { - display: 'block', - height: '30px', - lineHeight: '30px', - marginLeft: '20px', - }; - return ( - -
        -
        - - - - 第{position}关 - 返回 - - {prev_challenge === undefined ? "" : - 上一关 - } - - {next_challenge === undefined ? "" : - 下一关 - } - - 3||this.props.identity===undefined||this.props.status===2||this.props.status===1? "none":'block'}} - data-tip-down="新增代码编辑类型的任务">+ 实践类型 - 3||this.props.identity===undefined||this.props.status===2||this.props.status===1?"none":'block'}} - data-tip-down="新增选择题类型的任务">+ 选择题类型 - -
        - -
        - -
      • - 本关任务 -
      • - -
      • - 评测设置 -
      • - -
      • - 参考答案 -
      • -
      - -

      - 请先上传本关任务的所有代码文件、标准图片等所有必要的文件到 - 版本库 -

      - - -
      -
      -

      学员任务文件

      -
      - * -
      - this.updatepath(e,"shixunfilepath")} - onClick={(e)=>this.getfilepath(e,"shixunfilepath")} - /> -

      该文件将直接显示给学生,需要学生在其中填写代码

      -
      -
      - 必填项 -
      -
      -
      -
      - -
      -
      - -
      - - this.saveselectpath(e)} - value={selectpath}/> -
      - - this.evaluationenter()}>确定 - this.evaluationhideModal()}>取消 -
      -
      -
      - -
      -
      -

      评测执行文件

      -
      - * -
      - this.updatepath(e,"shixunfilepathplay")} - onClick={(e)=>this.getfilepath(e,"shixunfilepathplay")} - /> -

      该文件由平台执行,用来测试平台学员代码是否正确

      -
      -
      - 必填项 -
      -
      -
      -
      - - -
      -
      -

      效果展现方式

      -
      - - this.showrepositoryurltip(1)}> -
      - -
      -

      - 图片:处理或输出图片类型的任务,请选题此项
      - 可以通过设置图片路径和学员答案文件路径,展示代码对应的图片效果

      - apk/exe:写可执行文件的任务,请选填此项
      - 可以通过设置学员答案文件路径,展示二维码以供扫码下载

      - txt:输出txt文档类型的任务,请选填此项
      - 可以通过学员答案文件路径设置,展示txt文件内容

      - html:web类型的任务,请选填此项
      - 可以通过Web路由设置,展示html效果预览页 -

      -

      this.showrepositoryurltip(2)} - >知道了 -

      -
      -
      -

      该选项用来配置学员评测本关任务时,查看效果页上需要展现的文件类型

      -
      -
      - - -
      -
      -

      待处理图片路径

      -
      -
      - this.updatepath(e,"shixunfileexpectpicturepath")} - onClick={(e)=>this.getfilepath(e,"shixunfileexpectpicturepath")} - /> -

      - 该路径下的文件将在学员评测本关任务时,作为原始图片显示在查看效果页,供学员参考,任务为图片处理时请指定该路径,并注意与程序文件所在文件夹分开 -

      -
      -
      -
      -
      -
      - - -
      -
      -

      标准答案图片路径

      -
      -
      - this.updatepath(e,"shixunfilestandardpicturepath")} - onClick={(e)=>this.getfilepath(e,"shixunfilestandardpicturepath")} - /> -

      - 该路径下的文件将在学员评测本关任务时,作为参考答案显示在查看效果页,供学员参考任务输出结果为文件时请指定该路径,并注意与程序文件所在文件夹分开 -

      -
      -
      -
      -
      -
      - - -
      -
      -

      学员答案文件路径

      -
      -
      - this.updatepath(e,"shixunfilepicturepath")} - onClick={(e)=>this.getfilepath(e,"shixunfilepicturepath")} - placeholder="请在版本库中指定用来保存学员代码实际输出结果的路径。例:src/step1/outputimages"/> -

      - 学员评测本关任务时生成的文件将保存在该路径下,并作为实际输出显示在查看效果页,供学员确认任务输出结果为文件时请指定该路径,并注意与程序文件所在文件夹分开 -

      -
      -
      -
      -
      -
      - - -
      -
      - {/*

      测试集

      */} -

      测试集和系统评分规则

      -

      - 得分规范: - - - 通过全部测试集 - (学员评测,仅当所有测试集都正确时,才获得一次性奖励) - - - 通过部分测试集 - (学员评测,当至少有一组测试集正确时,即可获得其对应比例的奖励) - -

      - -

      - - 系统评分占比: - - 均分比例 - 自定义比例 - - - -

      - -
      -
      - -
      - - {evaluationlist===undefined?"":evaluationlist.length===0?"":evaluationlist.map((item,key)=>{ - return( -
      -

      - * - 组{key+1} - - {/*checked={item.is_public===1?false:true}*/} - - this.editpercentage(e,key)} - value={item.score} /> - % - - - this.evaluationonChange(item.hidden,key)} checked={item.hidden===1?true:false}>隐藏 - - - - this.del_test_array(key)}> - - - -

      - - -
      - ) - })} - -
      -
      - -

      - - 新增测试集 - -

      -

      温馨提示:建议公开测试集和隐藏测试集结合使用,降低作弊的几率;隐藏测试集,在“提交评测”时也将被自动检测

      -
      -
      -
      - - -
      3||this.props.identity===undefined||power===false?"none":"block"}}> - 提交 - 取消 -
      - - -
      - - ) - } -} - - +import React, {Component} from 'react'; + +import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal,Button,Icon,Tooltip} from 'antd'; + +import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom"; + +// import "antd/dist/antd.css"; + +import axios from 'axios'; + +import { getImageUrl, toPath } from 'educoder'; + +import './css/TPMchallengesnew.css'; + +import {getUrl} from 'educoder'; + +let origin = getUrl(); + +let path = getUrl("/editormd/lib/") + +const $ = window.$; + +let timeout; + +let currentValue; + +const Option = Select.Option; + +const RadioGroup = Radio.Group; + +function create_editorMD(id, width, high, placeholder, imageUrl, callback) { + var editorName = window.editormd(id, { + width: width, + height: high, + path: path, // "/editormd/lib/" + + syncScrolling: "single", + tex: true, + tocm: true, + emoji: true, + taskList: true, + codeFold: true, + searchReplace: true, + htmlDecode: "style,script,iframe", + sequenceDiagram: true, + autoFocus: false, + toolbarIcons: function () { + // Or return editormd.toolbarModes[name]; // full, simple, mini + // Using "||" set icons align right. + return ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"] + }, + toolbarCustomIcons: { + testIcon: "
      ", + testIcon1: "
      " + }, + //这个配置在simple.html中并没有,但是为了能够提交表单,使用这个配置可以让构造出来的HTML代码直接在第二个隐藏的textarea域中,方便post提交表单。 + saveHTMLToTextarea: true, + // 用于增加自定义工具栏的功能,可以直接插入HTML标签,不使用默认的元素创建图标 + dialogMaskOpacity: 0.6, + placeholder: placeholder, + imageUpload: true, + imageFormats: ["jpg", "jpeg", "gif", "png", "bmp", "webp", "JPG", "JPEG", "GIF", "PNG", "BMP", "WEBP"], + imageUploadURL: imageUrl,//url + onload: function () { + // this.previewing(); + $("#" + id + " [type=\"latex\"]").bind("click", function () { + editorName.cm.replaceSelection("```latex"); + editorName.cm.replaceSelection("\n"); + editorName.cm.replaceSelection("\n"); + editorName.cm.replaceSelection("```"); + var __Cursor = editorName.cm.getDoc().getCursor(); + editorName.cm.setCursor(__Cursor.line - 1, 0); + }); + + $("#" + id + " [type=\"inline\"]").bind("click", function () { + editorName.cm.replaceSelection("$$$$"); + var __Cursor = editorName.cm.getDoc().getCursor(); + editorName.cm.setCursor(__Cursor.line, __Cursor.ch - 2); + editorName.cm.focus(); + }); + $("[type=\"inline\"]").attr("title", "行内公式"); + $("[type=\"latex\"]").attr("title", "多行公式"); + + window.md_elocalStorage(editorName, `exercise__${id}`, "Memochallengesnew"); + + callback && callback() + } + }); + return editorName; +} + + +export default class TPMevaluation extends Component { + constructor(props) { + super(props) + this.state = { + choice_url: undefined, + practice_url: undefined, + go_back_url: undefined, + task_pass_default: undefined, + submit_url: undefined, + value: 1, + evaluationlist:[], + shixunId:undefined, + power:false, + shixunfilepath:undefined, + evaluationvisible:false, + trees:undefined, + path:"", + main:[], + saveshixunfilepath:undefined, + selectpath:undefined, + shixunfilepathplay:undefined, + shixunfileexpectpicturepath:undefined, + shixunfilestandardpicturepath:undefined, + shixunfilepicturepath:undefined, + pathoptionvalue:-1, + showrepositoryurltiptype: false, + prev_challenge: undefined, + next_challenge: undefined, + StudentTaskPapers:false, + StudentTaskDocs:false, + selectpatharr:[], + handpathopt:false, + scorevalue:false, + markvalue:true, + scoretype:undefined + } + } + + + exerciseMD(initValue, id) { + + this.contentChanged = false; + const placeholder = ""; +// amp; +// 编辑时要传memoId + const imageUrl = `/api/attachments.json`; +// 创建editorMd + + const exercise_editormd = create_editorMD(id, '100%', 400, placeholder, imageUrl, () => { + setTimeout(() => { + exercise_editormd.resize() + exercise_editormd.cm && exercise_editormd.cm.refresh() + }, 500) + + if (initValue != undefined) { + exercise_editormd.setValue(initValue) + } + exercise_editormd.cm.on("change", (_cm, changeObj) => { + console.log('....contentChanged') + this.contentChanged = true; + }) + }); + this.exercise_editormd = exercise_editormd; + window.exercise_editormd = exercise_editormd; + + } + + componentDidMount() { + let id = this.props.match.params.shixunId; + let checkpointId=this.props.match.params.checkpointId; + this.setState({ + shixunId:id, + checkpointId:checkpointId + }) + let newchoice_url= "/shixuns/"+id+"/challenges/newquestion"; + let newpractice_url= "/shixuns/"+id+"/challenges/new"; + let newgo_back_url="/shixuns/"+id+"/challenges"; + + let url = "/shixuns/" + id + "/challenges/" + checkpointId + "/edit.json?tab=1"; + axios.get(url).then((response) => { + let newprev_challenge = response.data.prev_challenge; + let next_challenge = response.data.next_challenge; + if (newprev_challenge != undefined) { + if(newprev_challenge.st===0){ + newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editcheckpoint"; + }else{ + newprev_challenge = "/shixuns/" + id + "/challenges/" + newprev_challenge.id + "/editquestion"; + } + } + if (next_challenge != undefined) { + + if(next_challenge.st===0){ + next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editcheckpoint"; + }else{ + next_challenge = "/shixuns/" + id + "/challenges/" + next_challenge.id+ "/editquestion"; + } + } + let newevaluationlist=[] + if(response.data.test_sets.length===0){ + let newlist=[ + {hidden:0,input:"",output:"",score:50}, + {hidden:1,input:"",output:"",score:50} + ] + newevaluationlist=newlist + }else{ + newevaluationlist=response.data.test_sets + } + + this.setState({ + power: response.data.power, + evaluationlist:newevaluationlist, + shixunfilepath:response.data.path, + shixunfilepathplay:response.data.exec_path, + pathoptionvalue:response.data.show_type, + shixunfileexpectpicturepath:response.data.original_picture_path, + shixunfilestandardpicturepath:response.data.expect_picture_path, + shixunfilepicturepath:response.data.picture_path, + prev_challenge: newprev_challenge, + next_challenge: next_challenge, + choice_url: newchoice_url, // 导航中的新建选择题url + practice_url: newpractice_url, //string 导航中新建实践题url + go_back_url: newgo_back_url, //string 导航中的返回url + position: response.data.position, //int 关卡位置,导航栏中的第几关 + scorevalue:response.data.test_set_score, + markvalue:response.data.test_set_average, + }) + this.evaluationoninputvalueonload(); + if(response.data.power===false){ + this.props.showSnackbar("你没有权限修改"); + } + if(response.data.answer===undefined){ + this.answerMD("", "answerMD"); + }else{ + this.answerMD(response.data.answer, "answerMD"); + } + + }).catch((error) => { + console.log(error) + }); + + } + + + setevaluationlist=(newevaluationlist)=>{ + this.setState({ + evaluationlist:newevaluationlist + }) + } + + + addevaluationon=()=>{ + let {evaluationlist,markvalue}=this.state; + let newevaluationlist=evaluationlist; + newevaluationlist.push({hidden:0,input:"",output:"",score:0}); + newevaluationlist=this.oneditevaluationlist(newevaluationlist,markvalue); + this.setevaluationlist(newevaluationlist); + } + + del_test_array=(key)=>{ + let {evaluationlist,markvalue}=this.state; + let newevaluationlist=evaluationlist; + newevaluationlist.splice(key,1); + newevaluationlist=this.oneditevaluationlist(newevaluationlist,markvalue); + this.setevaluationlist(newevaluationlist); + } + + getfilepath=(e,shixunfilepath)=>{ + this.setState({ + evaluationvisible: true, + selectpath:e.target.value, + selectpatharr:[], + }); + let id = this.props.match.params.shixunId; + let url ="/shixuns/"+id+"/repository.json"; + axios.post(url,{ + path: "" + }).then((response) => { + if (response.data.status === 403||response.data.status === 401||response.data.status === 500) { + + }else{ + this.setState({ + trees:response.data.trees, + saveshixunfilepath:shixunfilepath, + path:"", + main:[], + }) + } + + }).catch((error) => { + console.log(error) + }); + } + + sendgetfilepath=(newpath,type)=>{ + let id = this.props.match.params.shixunId; + let{path,main}=this.state; + let ary=main; + let paths=path; + + this.setState({ + selectpatharr:[], + }) + if(paths===""&&type==="tree"){ + newpath=newpath+"/"; + paths=""; + if(main.length===0){ + ary.push({val:"根目录/",path:""},{val:newpath,path:paths+newpath}) + }else{ + ary.push({val:newpath,path:paths+newpath}) + } + + }else if(paths!=""&&type==="tree"){ + newpath=newpath+"/"; + ary.push({val:newpath,path:paths+newpath}) + } + + + let url ="/shixuns/"+id+"/repository.json"; + if(type==="tree"){ + + axios.post(url,{ + path: paths+newpath + }).then((response) => { + if (response.data.status === 403||response.data.status === 401||response.data.status === 500) { + + }else{ + this.setState({ + trees:response.data.trees, + path:paths+newpath, + main:ary, + // selectpath:"" + }) + } + + }).catch((error) => { + console.log(error) + }); + } + + } + + goblakepath=(path,key)=>{ + let {main,selectpath} =this.state; + let newmain=[] + for(var i=0;i<=key;i++){ + newmain.push(main[i]) + } + let id = this.props.match.params.shixunId; + let url ="/shixuns/"+id+"/repository.json"; + axios.post(url,{ + path: path + }).then((response) => { + if (response.data.status === 403||response.data.status === 401||response.data.status === 500) { + + }else { + this.setState({ + trees: response.data.trees, + path: path, + main: newmain, + // selectpath:selectpath + }) + } + }).catch((error) => { + console.log(error) + }); + } + // delesavegetfilepath=(value)=>{ + // let {selectpatharr} = this.state + // let newarr =selectpatharr; + // let newselectpath=""; + // for(var i=0; i{ + let {selectpath} = this.state + // let newarr =selectpatharr; + // let arrtype=false; + // let arrsum=0; + // let newselectpath=""; + // newarr.push(value) + // if(newarr.length>1&&arrtype===false){ + // for(var i=0; i{ + let {saveshixunfilepath,selectpath}=this.state; + this.setState({ + evaluationvisible: false, + [saveshixunfilepath]:selectpath + }); + } + evaluationhideModal=()=>{ + this.setState({ + evaluationvisible: false, + }); + } + handpathoptionvalue=(value)=>{ + this.setState({ + pathoptionvalue:value + }) + } + showrepositoryurltip=(type)=>{ + if(type===1){ + this.setState({ + showrepositoryurltiptype:true + }) + }else{ + this.setState({ + showrepositoryurltiptype:false + }) + } + } + + evaluationonChange=(e,key)=>{ + let {evaluationlist}=this.state; + let newevaluationlist=evaluationlist; + let newtype; + if(e===1){ + newtype=0; + }else{ + newtype=1; + } + // newevaluationlist[key].is_public=newtype; + // for(var i=0; i{ + let {evaluationlist,scoretype}=this.state; + + if(scoretype===key){ + this.setState({ + scoretype:undefined + }) + } + let newevaluationlist=evaluationlist; + let sum =parseInt(e.target.value); + if(isNaN(sum)){ + sum=0 + } + newevaluationlist[key].score=sum; + + this.setState({ + evaluationlist:newevaluationlist, + markvalue:false + }) + this.setevaluationlist(newevaluationlist); + } + + evaluationoninputvalue=(e,key,type)=>{ + $.fn.autoHeight = function(){ + function autoHeight(elem){ + elem.style.height = 'auto'; + elem.style.maxHeight = '140px'; + elem.scrollTop = 0; //防抖动 + elem.style.height = elem.scrollHeight + 'px'; + } + this.each(function(){ + autoHeight(this); + $(this).on('keyup', function(){ + autoHeight(this); + }); + }); + } + $('textarea[autoHeight]').autoHeight(); + + let {evaluationlist}=this.state; + let newevaluationlist=evaluationlist; + if(type==="sr"){ + newevaluationlist[key].input=e.target.value + }else if(type==="yq"){ + newevaluationlist[key].output=e.target.value + } + this.setevaluationlist(newevaluationlist); + } + + + evaluationoninputvalueonload=()=>{ + $.fn.autoHeight = function(){ + function autoHeight(elem){ + elem.style.height = 'auto'; + elem.style.maxHeight = '140px'; + elem.scrollTop = 0; //防抖动 + elem.style.height = elem.scrollHeight + 'px'; + } + this.each(function(){ + autoHeight(this); + $(this).on('keyup', function(){ + autoHeight(this); + }); + }); + } + $('textarea[autoHeight]').autoHeight(); + } + submitarbitrationevaluation=()=>{ + let{evaluationlist,shixunfilepath,shixunfilepathplay,shixunfileexpectpicturepath,shixunfilestandardpicturepath,shixunfilepicturepath,pathoptionvalue,scorevalue,markvalue}=this.state; + + + let newscorevalue; + if(scorevalue===false){ + newscorevalue=false + }else{ + //判断占比 + newscorevalue=true + + let sum=0; + for(var i=0; i100){ + this.props.showSnackbar("测试集的评分占比不能大于100"); + this.setState({ + scoretype:i + }) + return + } + sum=sum+evaluationlist[i].score + } + + if(sum>100||sum<100){ + this.props.showSnackbar("测试集的评分占比之和必须等于100"); + return + } + + + } + if(shixunfilepath===undefined||shixunfilepath===""||shixunfilepath===null){ + this.props.showSnackbar("学员任务文件路径为空"); + this.setState({ + StudentTaskPapers:true + }) + $('html').animate({ + scrollTop: 120 + }, 1000); + return + } + + if(shixunfilepathplay===undefined||shixunfilepathplay===""||shixunfilepathplay===null){ + this.props.showSnackbar("评测执行文件路径为空"); + this.setState({ + StudentTaskDocs:true + }) + $('html').animate({ + scrollTop: 130 + }, 1000); + return + } + + if(evaluationlist.length===0){ + this.props.showSnackbar("测试集不能为空"); + return + } + let id = this.props.match.params.shixunId; + let{checkpointId}=this.state; + let url = "/shixuns/"+id+"/challenges/"+checkpointId+".json"; + axios.put(url,{ + tab:1, + challenge:{ + path:shixunfilepath, + exec_path:shixunfilepathplay, + show_type:pathoptionvalue, + original_picture_path:shixunfileexpectpicturepath, + expect_picture_path:shixunfilestandardpicturepath, + picture_path:shixunfilepicturepath, + test_set_score:newscorevalue, + test_set_average:markvalue + }, + test_set:evaluationlist + } + ).then((response) => { + this.props.showSnackbar(response.data.messages); + // if(response.data.status===1){ + // window.location.href = "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=3" + // } + }).catch((error) => { + console.log(error) + }); + } + handpathoptionvalues=()=>{ + this.setState({ + handpathopt:true + }) + } + handpathoptionvaluess=()=>{ + this.setState({ + handpathopt:false + }) + } + saveselectpath=(e)=>{ + + this.setState({ + selectpath:e.target.value + }) + } + updatepath=(e,name)=>{ + this.setState({ + [name]:e.target.value + }) + } + + + oneditevaluationlist=(newevaluationlist,markvalue)=>{ + + if(markvalue===true){ + if(100%newevaluationlist.length===0){ + let sum=100/newevaluationlist.length; + for(var i=0; i{ + + let {markvalue,evaluationlist}=this.state; + let newevaluationlist=evaluationlist; + + if(e.target.value===true){ + newevaluationlist=this.oneditevaluationlist(newevaluationlist,markvalue) + } + + this.setState({ + scorevalue: e.target.value, + evaluationlist:newevaluationlist + }); + + this.setevaluationlist(newevaluationlist); + } + + //均匀比例 + onChangemarkvalue=(e)=>{ + let {evaluationlist}=this.state; + + if(e.target.value===true){ + let newevaluationlist=evaluationlist; + newevaluationlist=this.oneditevaluationlist(newevaluationlist,e.target.value); + this.setevaluationlist(newevaluationlist); + } + + this.setState({ + markvalue: e.target.value, + }); + + } + render() { + + let { + choice_url, + practice_url, + go_back_url, + position, + evaluationlist, + shixunId, + checkpointId, + power, + shixunfileexpectpicturepath, + shixunfilestandardpicturepath, + shixunfilepicturepath, + shixunfilepath, + evaluationvisible, + trees, + path, + main, + selectpath, + shixunfilepathplay, + pathoptionvalue, + showrepositoryurltiptype, + prev_challenge, + next_challenge, + StudentTaskPapers, + StudentTaskDocs, + handpathopt, + scorevalue, + markvalue, + scoretype + } = this.state; + + let tab1url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/editcheckpoint"; + let tab2url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/tab=2"; + let tab3url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/tab=3"; + // console.log(this.props) + const radioStyle = { + display: 'block', + height: '30px', + lineHeight: '30px', + marginLeft: '20px', + }; + return ( + +
      +
      + + + + 第{position}关 + 返回 + + {prev_challenge === undefined ? "" : + 上一关 + } + + {next_challenge === undefined ? "" : + 下一关 + } + + 3||this.props.identity===undefined||this.props.status===2||this.props.status===1? "none":'block'}} + data-tip-down="新增代码编辑类型的任务">+ 实践类型 + 3||this.props.identity===undefined||this.props.status===2||this.props.status===1?"none":'block'}} + data-tip-down="新增选择题类型的任务">+ 选择题类型 + +
      + +
      + +
    • + 本关任务 +
    • + +
    • + 评测设置 +
    • + +
    • + 参考答案 +
    • +
      + +

      + 请先上传本关任务的所有代码文件、标准图片等所有必要的文件到 + 版本库 +

      + + +
      +
      +

      学员任务文件

      +
      + * +
      + this.updatepath(e,"shixunfilepath")} + onClick={(e)=>this.getfilepath(e,"shixunfilepath")} + /> +

      该文件将直接显示给学生,需要学生在其中填写代码

      +
      +
      + 必填项 +
      +
      +
      +
      + +
      +
      + +
      + + this.saveselectpath(e)} + value={selectpath}/> +
      + + this.evaluationenter()}>确定 + this.evaluationhideModal()}>取消 +
      +
      +
      + +
      +
      +

      评测执行文件

      +
      + * +
      + this.updatepath(e,"shixunfilepathplay")} + onClick={(e)=>this.getfilepath(e,"shixunfilepathplay")} + /> +

      该文件由平台执行,用来测试平台学员代码是否正确

      +
      +
      + 必填项 +
      +
      +
      +
      + + +
      +
      +

      效果展现方式

      +
      + + this.showrepositoryurltip(1)}> +
      + +
      +

      + 图片:处理或输出图片类型的任务,请选题此项
      + 可以通过设置图片路径和学员答案文件路径,展示代码对应的图片效果

      + apk/exe:写可执行文件的任务,请选填此项
      + 可以通过设置学员答案文件路径,展示二维码以供扫码下载

      + txt:输出txt文档类型的任务,请选填此项
      + 可以通过学员答案文件路径设置,展示txt文件内容

      + html:web类型的任务,请选填此项
      + 可以通过Web路由设置,展示html效果预览页 +

      +

      this.showrepositoryurltip(2)} + >知道了 +

      +
      +
      +

      该选项用来配置学员评测本关任务时,查看效果页上需要展现的文件类型

      +
      +
      + + +
      +
      +

      待处理图片路径

      +
      +
      + this.updatepath(e,"shixunfileexpectpicturepath")} + onClick={(e)=>this.getfilepath(e,"shixunfileexpectpicturepath")} + /> +

      + 该路径下的文件将在学员评测本关任务时,作为原始图片显示在查看效果页,供学员参考,任务为图片处理时请指定该路径,并注意与程序文件所在文件夹分开 +

      +
      +
      +
      +
      +
      + + +
      +
      +

      标准答案图片路径

      +
      +
      + this.updatepath(e,"shixunfilestandardpicturepath")} + onClick={(e)=>this.getfilepath(e,"shixunfilestandardpicturepath")} + /> +

      + 该路径下的文件将在学员评测本关任务时,作为参考答案显示在查看效果页,供学员参考任务输出结果为文件时请指定该路径,并注意与程序文件所在文件夹分开 +

      +
      +
      +
      +
      +
      + + +
      +
      +

      学员答案文件路径

      +
      +
      + this.updatepath(e,"shixunfilepicturepath")} + onClick={(e)=>this.getfilepath(e,"shixunfilepicturepath")} + placeholder="请在版本库中指定用来保存学员代码实际输出结果的路径。例:src/step1/outputimages"/> +

      + 学员评测本关任务时生成的文件将保存在该路径下,并作为实际输出显示在查看效果页,供学员确认任务输出结果为文件时请指定该路径,并注意与程序文件所在文件夹分开 +

      +
      +
      +
      +
      +
      + + +
      +
      + {/*

      测试集

      */} +

      测试集和系统评分规则

      +

      + 得分规范: + + + 通过全部测试集 + (学员评测,仅当所有测试集都正确时,才获得一次性奖励) + + + 通过部分测试集 + (学员评测,当至少有一组测试集正确时,即可获得其对应比例的奖励) + +

      + +

      + + 系统评分占比: + + 均分比例 + 自定义比例 + + + +

      + +
      +
      + +
      + + {evaluationlist===undefined?"":evaluationlist.length===0?"":evaluationlist.map((item,key)=>{ + return( +
      +

      + * + 组{key+1} + + {/*checked={item.is_public===1?false:true}*/} + + this.editpercentage(e,key)} + value={item.score} /> + % + + + this.evaluationonChange(item.hidden,key)} checked={item.hidden===1?true:false}>隐藏 + + + + this.del_test_array(key)}> + + + +

      + + +
      + ) + })} + +
      +
      + +

      + + 新增测试集 + +

      +

      温馨提示:建议公开测试集和隐藏测试集结合使用,降低作弊的几率;隐藏测试集,在“提交评测”时也将被自动检测

      +
      +
      +
      + + +
      3||this.props.identity===undefined||power===false?"none":"block"}}> + 提交 + 取消 +
      + + +
      +
      + ) + } +} + +