diff --git a/public/react/config/webpack.config.dev.js b/public/react/config/webpack.config.dev.js index 4e28af31f..d1092894a 100644 --- a/public/react/config/webpack.config.dev.js +++ b/public/react/config/webpack.config.dev.js @@ -30,7 +30,7 @@ const env = getClientEnvironment(publicUrl); module.exports = { // You may want 'eval' instead if you prefer to see the compiled output in DevTools. // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s - devtool: "cheap-module-eval-source-map", + //devtool: "cheap-module-eval-source-map", // 开启调试 //devtool: "source-map", // 开启调试 // These are the "entry points" to our application. diff --git a/public/react/public/css/edu-all.css b/public/react/public/css/edu-all.css index 0b7f126be..7bda233fe 100644 --- a/public/react/public/css/edu-all.css +++ b/public/react/public/css/edu-all.css @@ -397,9 +397,9 @@ label.infolabel{display: block;float: left;width: 56px;text-align: right;margin- .task-colspan{min-width:25%;text-align: left;display: block;float: left;color: #999; } .colspan-grey{border-radius: 12px;background-color: #E6E6E6;padding: 3px 10px;color: #747A7F} /*新建任务*/ -.challenge_nav{padding: 40px 20px 0px 20px;border-bottom: 1px solid #eee;} -.challenge_nav li{width: auto;float: left;margin-right: 40px;position: relative} -.challenge_nav li.active:after{position: absolute;content: '';width: 50%;background-color: #4CACFF;height: 3px;border-radius: 2px;left: 25%;bottom: 0px;} +.challenge_nav{padding: 20px 20px 0px 20px;border-bottom: 1px solid #eee;} +.challenge_nav li{width: auto;float: left;margin-right: 20px;position: relative} +.challenge_nav li.active:after{position: absolute;content: '';width: 76%;background-color: #4CACFF;height: 3px;border-radius: 2px;left: 25%;bottom: 0px;} .challenge_nav li a{display: block;width: 100%;padding-bottom: 20px;} .add_choose_type{width: 60px;height: 20px;line-height: 19px;border-radius: 2px;background-color: #eaeaea;color: #999!important;display: block;float: left;text-align: center;margin-top: 4px;} diff --git a/public/react/src/modules/developer/studentStudy/leftpane/taskDescription/index.js b/public/react/src/modules/developer/studentStudy/leftpane/taskDescription/index.js index f99d59092..ebc42b9a4 100644 --- a/public/react/src/modules/developer/studentStudy/leftpane/taskDescription/index.js +++ b/public/react/src/modules/developer/studentStudy/leftpane/taskDescription/index.js @@ -4,7 +4,7 @@ * @Github: * @Date: 2019-11-27 09:49:30 * @LastEditors : tangjiang - * @LastEditTime : 2019-12-25 14:50:37 + * @LastEditTime : 2019-12-27 18:42:59 */ import '../index.scss'; import React from 'react'; @@ -18,7 +18,7 @@ const {tagBackground, diffText} = CONST; const TaskDescription = (props) => { - const { hack = {} } = props; + const { hack = {}, userInfo = {} } = props; const {language, difficult, time_limit, username, description} = hack; return (
@@ -37,7 +37,7 @@ const TaskDescription = (props) => {

出题者: - {username} + {username}

@@ -52,8 +52,10 @@ const TaskDescription = (props) => { const mapStateToProps = (state) => { const { hack } = state.ojForUserReducer; + const { userInfo } = state.userReducer; return { - hack + hack, + userInfo } } diff --git a/public/react/src/modules/tpm/TPMBanner.js b/public/react/src/modules/tpm/TPMBanner.js index 14981c363..f79301be0 100644 --- a/public/react/src/modules/tpm/TPMBanner.js +++ b/public/react/src/modules/tpm/TPMBanner.js @@ -130,16 +130,19 @@ class TPMBanner extends Component { if(this.props.status===0&&this.props.openknows===false){ if(this.props.shixunsDetails&&this.props.shixunsDetails.shixun_status === 0 && this.props.identity < 5){ - if(shixunopenprocess===undefined||shixunopenprocess===false||shixunopenprocess===null){ - this.setState({ - openknow:true - }) - }else{ - this.setState({ - openknow:false - }) + if(this.props.user&&this.props.user.user_id){ + if(shixunopenprocess===undefined||shixunopenprocess===false||shixunopenprocess===null){ + this.setState({ + openknow:true + }) + }else{ + this.setState({ + openknow:false + }) + } } - } + } + }else{ this.setState({ openknow:false @@ -150,14 +153,16 @@ class TPMBanner extends Component { if(this.props.public===0&&this.props.status>1&&this.props.openknows===false){ if(this.props.shixunsDetails&&this.props.shixunsDetails.shixun_status === 2 && this.props.shixunsDetails&&this.props.shixunsDetails.public===0 && this.props.identity < 5){ - if(openopenpublictype===undefined||openopenpublictype===false||openopenpublictype===null){ - this.setState({ - openshowpublictype:true - }) - }else{ - this.setState({ - openshowpublictype:false - }) + if(this.props.user&&this.props.user.user_id) { + if (openopenpublictype === undefined || openopenpublictype === false || openopenpublictype === null) { + this.setState({ + openshowpublictype: true + }) + } else { + this.setState({ + openshowpublictype: false + }) + } } } }else{ diff --git a/public/react/src/modules/tpm/TPMIndex.js b/public/react/src/modules/tpm/TPMIndex.js index f7f73eabc..86d0e9637 100644 --- a/public/react/src/modules/tpm/TPMIndex.js +++ b/public/react/src/modules/tpm/TPMIndex.js @@ -87,6 +87,11 @@ const TPMchallengesnew = Loadable({ loader: () => import('./challengesnew/TPMchallengesnew'), loading: Loading, }) +//新建实训 +// const TPMchallengesnew = Loadable({ +// loader: () => import('./challengesnew/TpmTask/TpmTaskIndex'), +// loading: Loading, +// }) //新建tab2 const TPMevaluation = Loadable({ @@ -383,6 +388,7 @@ class TPMIndex extends Component { let url = window.location.href; let flag = url.indexOf("add_file")>-1; + return (
{/*头部*/} diff --git a/public/react/src/modules/tpm/TPMIndexHOC.js b/public/react/src/modules/tpm/TPMIndexHOC.js index fe760f372..01d617c78 100644 --- a/public/react/src/modules/tpm/TPMIndexHOC.js +++ b/public/react/src/modules/tpm/TPMIndexHOC.js @@ -35,14 +35,14 @@ if (!window['indexHOCLoaded']) { // $('head').append($('') // .attr('href', `${_url_origin}/stylesheets/educoder/antd.min.css?1525440977`)); $('head').append($('') - .attr('href', `${_url_origin}/stylesheets/css/edu-common.css?8`)); + .attr('href', `${_url_origin}/stylesheets/css/edu-common.css?2020`)); $('head').append($('') - .attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?8`)); + .attr('href', `${_url_origin}/stylesheets/educoder/edu-main.css?2020`)); // index.html有加载 $('head').append($('') - .attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?8`)); + .attr('href', `${_url_origin}/stylesheets/educoder/edu-all.css?2020`)); // $('head').append($('') @@ -635,6 +635,18 @@ export function TPMIndexHOC(WrappedComponent) { } } + //跳转道描点的地方 + scrollToAnchor = (anchorName) => { + if (anchorName) { + // 找到锚点 + let anchorElement = document.getElementById(anchorName); + // 如果对应id的锚点存在,就跳转到锚点 + if (anchorElement) { + anchorElement.scrollIntoView(); + } + } + } + render() { let{Headertop,Footerdown, isRender, AccountProfiletype,AccountPhoneemailtype}=this.state; const common = { @@ -670,7 +682,8 @@ export function TPMIndexHOC(WrappedComponent) { hideGlobalLoading: this.hideGlobalLoading, yslslowCheckresults:this.yslslowCheckresults, yslslowCheckresultsNo:this.yslslowCheckresultsNo, - MdifHasAnchorJustScorll:this.MdifHasAnchorJustScorll + MdifHasAnchorJustScorll:this.MdifHasAnchorJustScorll, + scrollToAnchor:this.scrollToAnchor }; // console.log("this.props.mygetHelmetapi"); diff --git a/public/react/src/modules/tpm/challengesnew/TPManswer2.js b/public/react/src/modules/tpm/challengesnew/TPManswer2.js index dfdc58db4..596dcc910 100644 --- a/public/react/src/modules/tpm/challengesnew/TPManswer2.js +++ b/public/react/src/modules/tpm/challengesnew/TPManswer2.js @@ -1,48 +1,21 @@ import React, {Component} from 'react'; -import {Input, InputNumber, Select, Radio, Checkbox, Popconfirm, message, Modal, Tooltip} from 'antd'; +import {Input, InputNumber, Button, Tooltip} from 'antd'; import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom"; -// import "antd/dist/antd.css"; - -import { getImageUrl, toPath, getUrl } from 'educoder'; - import axios from 'axios'; -import './css/TPMchallengesnew.css'; - import TPMMDEditor from './TPMMDEditor'; +import Bottomsubmit from "../../modals/Bottomsubmit"; -let origin = getUrl(); - -let path = getUrl("/editormd/lib/") +import './css/TPMchallengesnew.css'; const $ = window.$; -let timeout; - -let currentValue; -const Option = Select.Option; -const RadioGroup = Radio.Group; - -// const testAnswers = [{ -// "id": 4337, -// "name": "解题思路1", -// "contents": "答案的解题思路1", -// "level": 1, -// "score": 25 -// }, -// { -// "id": 4338, -// "name": "解题思路2", -// "contents": "答案的解题思路2", -// "level": 2, -// "score": 25 -// }] export default class TPManswer extends Component { constructor(props) { super(props) @@ -94,7 +67,7 @@ export default class TPManswer extends Component { } } this.setState({ - answer:response.data.answer, + answer:response.data.answer, power: response.data.power, choice_url: newchoice_url, // 导航中的新建选择题url practice_url: newpractice_url, //string 导航中新建实践题url @@ -102,10 +75,11 @@ export default class TPManswer extends Component { position: response.data.position, //int 关卡位置,导航栏中的第几关 prev_challenge: newprev_challenge, next_challenge: next_challenge, + responsedata:response.data, }) if(response.data.power===false){ - this.props.showSnackbar("没有权限修改"); + this.props.showNotification("没有权限修改"); } // if(response.data.answer===undefined||response.data.answer===null){ // this.answerMD("", "answerMD"); @@ -133,7 +107,7 @@ export default class TPManswer extends Component { // this.refs.md0 const { answers } = this.state; const answersParams = answers.slice(0) - console.log(answersParams) + // console.log(answersParams) let isValidate = true; let totalScore = 0; answersParams.forEach( (item, index) => { @@ -147,10 +121,10 @@ export default class TPManswer extends Component { totalScore += item.score; delete item.id; if (!item.name) { - this.props.showSnackbar("请先填写参考答案名称"); + this.props.showNotification("请先填写参考答案名称"); isValidate = false; } else if (!mdContnet) { - this.props.showSnackbar("请先填写参考答案内容"); + this.props.showNotification("请先填写参考答案内容"); isValidate = false; } if (!isValidate) { @@ -161,7 +135,7 @@ export default class TPManswer extends Component { return; } if (answersParams.length != 0 && totalScore != 100) { - this.props.showSnackbar("请先保证占比和为100%"); + this.props.showNotification("请先保证占比和为100%"); return; } let id = this.props.match.params.shixunId; @@ -174,7 +148,7 @@ export default class TPManswer extends Component { ).then((response) => { if (response.data) { if (response.data.message) { - this.props.showSnackbar(response.data.message); + this.props.showNotification(response.data.message); } if (response.data.status == 1) { window.location.href=`/shixuns/${id}/challenges`; @@ -233,12 +207,16 @@ export default class TPManswer extends Component { } }) } + + gotocheckpoint=(url)=>{ + this.props.history.replace(url); + } render() { let { choice_url, practice_url, - go_back_url, + responsedata, position, task_pass_default, submit_url, @@ -256,60 +234,51 @@ export default class TPManswer extends Component { return (
-
- - - - 第{position}关 - 返回 - - {prev_challenge === undefined ? "" : - 上一关 - } - - {next_challenge === undefined ? "" : - 下一关 - } - - + 实践类型 - + 选择题类型 - +
+ 第{position}关:{responsedata&&responsedata.st === 0 ?"实践题":responsedata&&responsedata.st === 1?"选择题":""} + {this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"": + } + {this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"": + } + {next_challenge===undefined?"": + } + {prev_challenge===undefined?"": + }
-
  • - 本关任务 + 1、本关任务
  • - + {tab2url === "" ? "":
  • >
  • }
  • - 评测设置 + 2、评测设置
  • - + {tab3url === "" ? "":
  • >
  • }
  • - 参考答案 + 3、参考答案
  • -

    - 可以将参考答案分级设置,让学员自行选择级别,每级查看后按照比例扣分值(学员已完成任务再查看,则不影响原因已获得的成绩) +

    + 可以将参考答案分级设置,让学员自行选择级别,每级查看后按照比例扣分值(学员已完成任务再查看,则不影响学员已获得的成绩)

    -

    - 示例:级别1,扣减分值占比25%;级别2,扣减分值占比35%;级别3,扣减分值占比40%;则学员选择查看级别1的答案,将被扣减25%的分值; - 选择查看级别2的答案,将被扣减60%的分值;选择查看级别3的答案,将被扣减100%的分值。 +

    +

    示例:级别1,扣减分值占比25%;级别2,扣减分值占比35%;级别3,扣减分值占比40%;
    +
    若学员选择查看级别1的答案,将被扣减25%的分值;选择查看级别2的答案,将被扣减60%的分值;选择查看级别3的答案,将被扣减100%的分值。

    + + watch={true} className="courseMessageMD" initValue={this.state.exercisememoMDRefval} height={800}>

    -
    + {this.state.tpmcourseMessageMDType===true?
    必填项:不能为空
    :""} +
    -
    -

    难度系数

    -
    - +
    +

    + * + 难度系数: + 简单 中等 困难 - -

    -

    奖励经验值

    -
    - * - - triggerNode.parentNode} > {options} - -

    - 如果学员答题错误,则不能得到相应的经验值
    - 如果学员成功得到经验值,那么将同时获得等值的金币奖励,如:+10经验值、+10金币 -

    - - 必填项 + {this.state.onshixunsmarkvaluetype===true?
    + 必选项:不能为空
    :""}
    -
    -

    技能标签

    -
    - * +
    +

    *技能标签: (学员答题正确将获得技能,否则不能获得技能)

    +
    - {/*+ 添加*/} -
    学员答题正确将获得技能,否则不能获得技能
    +
    (回车添加标签)
    - { shixunsskillvaluelist===undefined?"":shixunsskillvaluelist.length === 0 ? "" : shixunsskillvaluelist.map((itme, key) => { return ( -
  • {itme} - this.delshixunsskilllist(key)}>× -
  • +
  • + this.delshixunsskilllist(key)}> + + +
  • ) }) } - -
    - - 必填项 +
    必选项:不能为空
    -
    -

    服务配置

    -
    - * - -
    - -
    - 必填项 -
    -
    -
    - -
    4||this.props.identity===undefined?"none":'block'}} - > - {checkpointId===undefined?提交: - 提交} - 取消 -
    + {/*
    */} + {/*

    * 服务配置:评测时限(S)

    */} + {/*
    */} + {/*
    */} + {/* /!**!/*/} + {/* */} + {/*
    */} + {/* 必填项:不能为空
    */} + {/*
    */} + {/*
    */} + +
    + {this.props.identity>4||this.props.identity===undefined?"":
    4||this.props.identity===undefined?"none":'block'}} + > + {/*{checkpointId===undefined?提交:*/} + {/*提交}*/} + {/*取消*/} + {/*取消*/} + this.CreatePracticesend():()=>this.editPracticesend()} + loadings={CreatePracticesendtype===true?true:editPracticesendtype===true?true:false}/> +
    } ) } diff --git a/public/react/src/modules/tpm/challengesnew/TPMevaluation.js b/public/react/src/modules/tpm/challengesnew/TPMevaluation.js index 34eb1a075..7ff0942cc 100644 --- a/public/react/src/modules/tpm/challengesnew/TPMevaluation.js +++ b/public/react/src/modules/tpm/challengesnew/TPMevaluation.js @@ -1,97 +1,32 @@ import React, {Component} from 'react'; -import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal,Button,Icon,Tooltip} from 'antd'; +import {Input, Select, Radio, Checkbox, Modal,Button,Tooltip} from 'antd'; -import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom"; - -// import "antd/dist/antd.css"; +import { Link} from "react-router-dom"; import axios from 'axios'; -import { getImageUrl, toPath } from 'educoder'; - -import './css/TPMchallengesnew.css'; +import Bottomsubmit from "../../modals/Bottomsubmit"; -import {getUrl} from 'educoder'; +import { getImageUrl } from 'educoder'; -let origin = getUrl(); - -let path = getUrl("/editormd/lib/") +import './css/TPMchallengesnew.css'; const $ = window.$; -let timeout; - -let currentValue; - const Option = Select.Option; const RadioGroup = Radio.Group; const { TextArea } = Input; -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 - 3); - editorName.cm.focus(); - }); - $("[type=\"inline\"]").attr("title", "行内公式"); - $("[type=\"latex\"]").attr("title", "多行公式"); - - window.md_elocalStorage(editorName, `exercise__${id}`, "Memochallengesnew"); - - callback && callback() - } - }); - return editorName; +function isNulltpm( str ){ + if ( str == "" ) return true; + var regu = "^[ ]+$"; + var re = new RegExp(regu); + return re.test(str); } - export default class TPMevaluation extends Component { constructor(props) { super(props) @@ -127,39 +62,11 @@ export default class TPMevaluation extends Component { scorevalue:false, markvalue:true, scoretype:undefined, - web_route:null + web_route:null, + exec_time: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; @@ -193,8 +100,7 @@ export default class TPMevaluation extends Component { let newevaluationlist=[] if(response.data.test_sets.length===0){ let newlist=[ - {hidden:0,input:"",output:"",score:50}, - {hidden:0,input:"",output:"",score:50} + {hidden:0,input:"",output:"",score:100}, ] newevaluationlist=newlist }else{ @@ -219,18 +125,16 @@ export default class TPMevaluation extends Component { scorevalue:response.data.test_set_score, markvalue:response.data.test_set_average, web_route:response.data.web_route, - has_web_route:response.data.has_web_route + has_web_route:response.data.has_web_route, + responsedata:response.data, + exec_time:response.data.exec_time, }) 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"); + this.props.showNotification("你没有权限修改"); } + }).catch((error) => { console.log(error) }); @@ -249,7 +153,7 @@ export default class TPMevaluation extends Component { addevaluationon=()=>{ let {evaluationlist,markvalue}=this.state; let newevaluationlist=evaluationlist; - newevaluationlist.push({hidden:0,input:"",output:"",score:0}); + newevaluationlist.push({hidden:0,input:"",output:"",score:0,match_rule:"full"}); newevaluationlist=this.oneditevaluationlist(newevaluationlist,markvalue); this.setevaluationlist(newevaluationlist); } @@ -379,34 +283,6 @@ export default class TPMevaluation extends Component { } - - - - - // delesavegetfilepath=(value)=>{ - // let {selectpatharr} = this.state - // let newarr =selectpatharr; - // let newselectpath=""; - // for(var i=0; i{ let {selectpath,saveshixunfilepath,pathtype} = this.state @@ -438,30 +314,6 @@ export default class TPMevaluation extends Component { }) } - // 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{ @@ -505,12 +357,6 @@ export default class TPMevaluation extends Component { }else{ newtype=1; } - // newevaluationlist[key].is_public=newtype; - // for(var i=0; i{ - let{evaluationlist,shixunfilepath,shixunfilepathplay,shixunfileexpectpicturepath,shixunfilestandardpicturepath,shixunfilepicturepath,pathoptionvalue,scorevalue,markvalue,web_route}=this.state; + let{exec_time,evaluationlist,shixunfilepath,shixunfilepathplay,shixunfileexpectpicturepath,shixunfilestandardpicturepath,shixunfilepicturepath,pathoptionvalue,scorevalue,markvalue,web_route}=this.state; let newscorevalue; @@ -610,7 +456,7 @@ export default class TPMevaluation extends Component { let sum=0; for(var i=0; i100){ - this.props.showSnackbar("测试集的评分占比不能大于100"); + this.props.showNotification("测试集的评分占比不能大于100"); this.setState({ scoretype:i }) @@ -620,36 +466,52 @@ export default class TPMevaluation extends Component { } if(sum>100||sum<100){ - this.props.showSnackbar("测试集的评分占比之和必须等于100"); + this.props.showNotification("测试集的评分占比之和必须等于100"); return } } + + + if(exec_time===null||exec_time===undefined||exec_time === ""){ + this.setState({ + shixunExec_timeType:true, + }) + this.props.scrollToAnchor("exec_timeid"); + return + } + + if (isNulltpm(exec_time)) { + this.props.showNotification("评测时长,请勿输入空格"); + this.setState({ + shixunExec_timeType:true, + }) + this.props.scrollToAnchor("exec_timeid"); + return + } + if(shixunfilepath===undefined||shixunfilepath===""||shixunfilepath===null){ - this.props.showSnackbar("学员任务文件路径为空"); + // this.props.showSnackbar("学员任务文件路径为空"); this.setState({ StudentTaskPapers:true }) - $('html').animate({ - scrollTop: 120 - }, 1000); + this.props.scrollToAnchor("Studenttaskfile"); return } if(shixunfilepathplay===undefined||shixunfilepathplay===""||shixunfilepathplay===null){ - this.props.showSnackbar("评测执行文件路径为空"); + // this.props.showSnackbar("评测执行文件路径为空"); this.setState({ StudentTaskDocs:true }) - $('html').animate({ - scrollTop: 130 - }, 1000); + this.props.scrollToAnchor("Benchmarkexecutable"); return } if(evaluationlist.length===0){ this.props.showSnackbar("测试集不能为空"); + this.props.scrollToAnchor("Thetestset"); return } let id = this.props.match.params.shixunId; @@ -664,7 +526,8 @@ export default class TPMevaluation extends Component { picture_path:pathoptionvalue===-1?undefined:shixunfilepicturepath===undefined?null:shixunfilepicturepath, test_set_score:newscorevalue, test_set_average:markvalue, - web_route:web_route===null?undefined:web_route + web_route:web_route===null?undefined:web_route, + exec_time:exec_time } axios.put(url,{ tab:1, @@ -672,7 +535,7 @@ export default class TPMevaluation extends Component { test_set:evaluationlist } ).then((response) => { - this.props.showSnackbar(response.data.messages); + this.props.showNotification(response.data.messages); window.location.href=`/shixuns/${id}/challenges/${response.data.challenge_id}/tab=3`; // if(response.data.status===1){ // window.location.href = "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=3" @@ -681,16 +544,7 @@ export default class TPMevaluation extends Component { console.log(error) }); } - handpathoptionvalues=()=>{ - this.setState({ - handpathopt:true - }) - } - handpathoptionvaluess=()=>{ - this.setState({ - handpathopt:false - }) - } + saveselectpath=(e)=>{ this.setState({ @@ -768,6 +622,24 @@ export default class TPMevaluation extends Component { web_route:e.target.value }) } + + gotocheckpoint=(url)=>{ + this.props.history.replace(url); + } + + setexec_time=(e)=>{ + if(e.target.value===null||e.target.value===undefined||e.target.value === ""||e.target.value.match(/^[ ]*$/)){ + + }else{ + this.setState({ + shixunExec_timeType:false, + }) + } + this.setState({ + exec_time:e.target.value + }) + } + render() { let { @@ -799,7 +671,8 @@ export default class TPMevaluation extends Component { scorevalue, markvalue, scoretype, - has_web_route + has_web_route, + responsedata } = this.state; let tab1url="/shixuns/" + shixunId + "/challenges/"+checkpointId+"/editcheckpoint"; @@ -812,64 +685,115 @@ export default class TPMevaluation extends Component { lineHeight: '30px', marginLeft: '20px', }; + return (
    -
    - - - - 第{position}关 - 返回 - - {prev_challenge === undefined ? "" : - 上一关 - } - - {next_challenge === undefined ? "" : - 下一关 - } - - 4||this.props.identity===undefined||this.props.status===2||this.props.status===1? "none":'block'}} - data-tip-down="新增代码编辑类型的任务">+ 实践类型 - 4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"none":'block'}} - data-tip-down="新增选择题类型的任务">+ 选择题类型 - +
    + 第{position}关:{responsedata&&responsedata.st === 0 ?"实践题":responsedata&&responsedata.st === 1?"选择题":""} + {this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"": + } + {this.props.identity>4||this.props.identity===undefined||this.props.status===2||this.props.status===1?"": + } + {next_challenge===undefined?"": + } + {prev_challenge===undefined?"": + }
    -
  • - 本关任务 + 1、本关任务
  • - + {tab2url === "" ? "":
  • >
  • }
  • - 评测设置 + 2、评测设置
  • - + {tab3url === "" ? "":
  • >
  • }
  • - 参考答案 + 3、参考答案
  • -

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

    +

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

    +
    +

    * 评测时长限制(程序评测运行时间限制时长,单位:秒)

    +
    +
    + +
    +
    必填项:不能为空
    +
    +
    -
    -
    -

    学员任务文件

    -
    - * -
    - +
    +

    * 评测效果展现方式(学员评测本关任务时,查看效果页上需要展现的文件类型)

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

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

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

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

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

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

    +

    +

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

    +
    +
    +
    +
    + + +
    +
    +

    * 学员任务文件(该文件将直接显示给学生,需要学生在其中填写代码)

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

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

    -
    - 必填项 +
    + 必选项:不能为空
    + + + : this.savegetfilepath(path+item.name,item.type)}>{path+item.name} - {/**/} - {/*this.delesavegetfilepath(path+item.name)}/>*/} - {/**/} }
    @@ -942,13 +864,12 @@ export default class TPMevaluation extends Component {
    -
    -
    -

    评测执行文件

    -
    - * -
    - +
    +

    *评测执行文件(若执行平台脚本,请输入学员任务文件路径;若使用自己设计的脚本测试学生代码,请输入设计的脚本文件路径)

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

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

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

    效果展现方式

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

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

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

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

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

    -

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

    +
    + + 必选项:不能为空 +
    -

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

    - {pathoptionvalue===4&&web_route!=null||pathoptionvalue===4&&has_web_route===true?
    -
    -

    Web路由

    + {pathoptionvalue===4&&web_route!=null||pathoptionvalue===4&&has_web_route===true?
    +
    +

    Web路由(请注意将服务器程序的端口号映射到8080端口)

    :""} - {pathoptionvalue===1||pathoptionvalue===5||pathoptionvalue===6?
    -
    -

    待处理文件路径

    + {pathoptionvalue===1||pathoptionvalue===5||pathoptionvalue===6?
    +
    +

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

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

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

    @@ -1043,9 +921,9 @@ export default class TPMevaluation extends Component {
    :""} - {pathoptionvalue===1||pathoptionvalue===5||pathoptionvalue===6?
    -
    -

    标准答案文件路径

    + {pathoptionvalue===1||pathoptionvalue===5||pathoptionvalue===6?
    +
    +

    标准答案文件路径(该路径下的文件将在学员评测本关任务时,作为参考答案显示在查看效果页,供学员参考;请注意与程序文件所在文件夹分开)

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

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

    @@ -1065,9 +940,9 @@ export default class TPMevaluation extends Component {
    :""} - {pathoptionvalue===-1?"":
    -
    -

    学员答案文件路径

    + {pathoptionvalue===-1?"":
    +
    +

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

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

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

    @@ -1086,10 +958,10 @@ export default class TPMevaluation extends Component {
    } -
    -
    +
    +
    {/*

    测试集

    */} -

    测试集和系统评分规则

    +

    测试集和系统评分规则

    @@ -1132,9 +1004,9 @@ export default class TPMevaluation extends Component { {evaluationlist===undefined?"":evaluationlist.length===0?"":evaluationlist.map((item,key)=>{ return( -

    +

    - * + * 组{key+1} {/*checked={item.is_public===1?false:true}*/} @@ -1143,19 +1015,19 @@ export default class TPMevaluation extends Component { style={{width: '25%',display:scorevalue===true?'inline-block':'none'}} onInput={(e)=>this.editpercentage(e,key)} value={item.score} /> - % - this.evaluationonChange(item.hidden,key)} checked={item.hidden===1?true:false}>隐藏 + this.evaluationonChange(item.hidden,key)} checked={item.hidden===1?true:false}>隐藏(选中则对学员隐藏本测试集内容) - this.del_test_array(key)}> - - + +

    -
    +
    匹配规则: this.changeEvaluationRule(e,key)}> - 完全匹配 - 末尾匹配 + 完全匹配(实际输出与预期输出完全相同) + 末尾匹配(实际输出的末尾内容与预期输出完全相同)
    @@ -1189,23 +1061,28 @@ export default class TPMevaluation extends Component {

    - - 新增测试集 - +

    -

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

    + +

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

    - -
    4||this.props.identity===undefined||power===false?"none":"block"}}> - 提交 - 取消 -
    - -
    + + {this.props.identity>4||this.props.identity===undefined||power===false?"":
    + {/*提交*/} + {/*/!*取消*!/*/} + {/*取消*/} + +
    } ) } diff --git a/public/react/src/modules/tpm/challengesnew/TpmQuestionEdit.js b/public/react/src/modules/tpm/challengesnew/TpmQuestionEdit.js index d0e6f98bd..5e90c1f3d 100644 --- a/public/react/src/modules/tpm/challengesnew/TpmQuestionEdit.js +++ b/public/react/src/modules/tpm/challengesnew/TpmQuestionEdit.js @@ -212,9 +212,9 @@ export default class TpmQuestionEdit extends Component {
    4||this.props.identity===undefined||this.props.power===false?"none":"block"}}> this.props.answer_subit()}>提交 - 取消 - + {/*取消*/} + 取消 this.delecbtns()} className="delectshixuncdbtn fr">删除
    diff --git a/public/react/src/modules/tpm/challengesnew/TpmQuestionMain.js b/public/react/src/modules/tpm/challengesnew/TpmQuestionMain.js index 614842ab8..c4008f89c 100644 --- a/public/react/src/modules/tpm/challengesnew/TpmQuestionMain.js +++ b/public/react/src/modules/tpm/challengesnew/TpmQuestionMain.js @@ -69,9 +69,9 @@ export default class TpmQuestionMain extends Component { style={{display: this.props.identity > 4 || this.props.identity === undefined || this.props.power === false ? "none" : "block"}}> 提交 - 取消 - + {/*取消*/} + 取消
    diff --git a/public/react/src/modules/tpm/challengesnew/TpmQuestionNew.js b/public/react/src/modules/tpm/challengesnew/TpmQuestionNew.js index 861c4f879..c808fea61 100644 --- a/public/react/src/modules/tpm/challengesnew/TpmQuestionNew.js +++ b/public/react/src/modules/tpm/challengesnew/TpmQuestionNew.js @@ -205,8 +205,10 @@ export default class TpmQuestionNew extends Component {
    4||this.props.identity===undefined||this.props.power===false?"none":"block"}}> 提交 - 取消 + 取消 + {/*取消*/}
    diff --git a/public/react/src/modules/tpm/challengesnew/TpmTask/TpmTaskIndex.js b/public/react/src/modules/tpm/challengesnew/TpmTask/TpmTaskIndex.js new file mode 100644 index 000000000..5a64daf9e --- /dev/null +++ b/public/react/src/modules/tpm/challengesnew/TpmTask/TpmTaskIndex.js @@ -0,0 +1,55 @@ +import React, {Component} from 'react'; + +import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom"; + +import Loadable from 'react-loadable'; + +import Loading from "../../../../Loading"; + +import Bottomsubmit from "../../../modals/Bottomsubmit"; + + +const TPMchallengestask = Loadable({ + loader: () => import('../../challengesnew/TPMchallengesnew'), + loading: Loading, +}) + +export default class TpmTaskIndex extends Component { + constructor(props) { + super(props) + this.state = { + + } + } + + + componentDidMount() { + + } + + + render() { + // console.log(a.indexOf("vnc")) + // console.log(b.indexOf("vnc")) + + return ( + +
    + + {/*新建关卡*/} + () + }> + + {/*编辑关卡*/} + () + }> + +
    + + ); + } +} + + diff --git a/public/react/src/modules/tpm/challengesnew/css/TPMchallengesnew.css b/public/react/src/modules/tpm/challengesnew/css/TPMchallengesnew.css index 37a65ef97..a65c3b7fa 100644 --- a/public/react/src/modules/tpm/challengesnew/css/TPMchallengesnew.css +++ b/public/react/src/modules/tpm/challengesnew/css/TPMchallengesnew.css @@ -266,4 +266,66 @@ a{ height: 32px; line-height: 20px; font-family: "微软雅黑","宋体"; +} + +.borderbottomf4{ + border-bottom:1px solid #F4F4F4; +} + +.TPMchallengesnewtitles{ + height: 76px; + line-height: 56px; + padding: 10px 20px; +} + +.newpadding1020{ + padding: 20px 20px 20px; + box-sizing: border-box; +} +.newpadding02020{ + padding: 0px 20px 20px; +} +.mb10 { + margin-bottom: 10px !important; +} + +.tpmpointer{ + cursor: pointer; +} +.text-centers{text-align:center} +.bor25510211{ + width: 1180px; + height: 34px; + border: 1px solid rgba(255,102,1,1); + line-height: 34px; +} + +.padding1020tpms{ + padding: 10px 20px; + box-sizing: border-box; +} + +.bortopeeetpm{ + border-top: 1px solid #eee; +} + +.borbottomeeetpm { + border-bottom: 1px solid #eee; +} + +.height40pxtpm{ + height:40px +} + +.ml41{ + margin-left: 41px; +} + +.wind500height45{ + width: 500px; + height: 45px; +} + +.newaddswermargin{ + margin: 0 auto; } \ No newline at end of file diff --git a/public/react/src/modules/tpm/challengesnew/TPManswer.js b/public/react/src/modules/tpm/challengesnew/old/TPManswer.js similarity index 98% rename from public/react/src/modules/tpm/challengesnew/TPManswer.js rename to public/react/src/modules/tpm/challengesnew/old/TPManswer.js index 9187e09b0..7d090c607 100644 --- a/public/react/src/modules/tpm/challengesnew/TPManswer.js +++ b/public/react/src/modules/tpm/challengesnew/old/TPManswer.js @@ -10,7 +10,7 @@ import { getImageUrl, toPath, getUrl } from 'educoder'; import axios from 'axios'; -import './css/TPMchallengesnew.css'; +import '../css/TPMchallengesnew.css'; let origin = getUrl(); @@ -355,7 +355,8 @@ export default class TPManswer extends Component {
    4||this.props.identity===undefined||power===false?"none":"block"}}> 提交 - 取消 + {/*取消*/} + 取消
    diff --git a/public/react/src/modules/tpm/challengesnew/old/TPMchallengesnew.js b/public/react/src/modules/tpm/challengesnew/old/TPMchallengesnew.js new file mode 100644 index 000000000..6dfc04eef --- /dev/null +++ b/public/react/src/modules/tpm/challengesnew/old/TPMchallengesnew.js @@ -0,0 +1,617 @@ +import React, {Component} from 'react'; + +import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal} from 'antd'; + +import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom"; + +// import "antd/dist/antd.css"; + +import TPMMDEditor from '../TPMMDEditor'; + +import axios from 'axios'; + +import '../css/TPMchallengesnew.css'; + +import { getImageUrl, toPath } from 'educoder'; + +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; + +export default class TPMchallengesnew extends Component { + constructor(props) { + super(props) + this.exercisememoMDRef=React.createRef(); + this.state = { + choice_url: undefined, + practice_url: undefined, + go_back_url: undefined, + task_pass_default: undefined, + submit_url: undefined, + shixunCreatePracticeGroup: 1, + optionsums:[100,200], + activetype:0, + setopen: false, + shixunCreatePractice: undefined, + onshixunsmarkvalue: 100, + shixunsskillvalue: undefined, + shixunsskillvaluelist: [], + tab2url: "", + tab3url: "", + prev_challenge:undefined, + next_challenge:undefined, + power: false, + shixunCreatePracticetype: false, + shixunsskillvaluelisttype: false, + marktype:false, + editPracticesendtype:false, + CreatePracticesendtype:false, + exec_time:20, + shixunExec_timeType:false + } + } + + + componentDidMount() { + let id = this.props.match.params.shixunId; + let checkpointId=this.props.match.params.checkpointId; + + let newchoice_url= "/shixuns/"+id+"/challenges/newquestion"; + let newpractice_url= "/shixuns/"+id+"/challenges/new"; + let newgo_back_url="/shixuns/"+id+"/challenges" + if(checkpointId===undefined){ + //新建模式 + let url = "/shixuns/" + id + "/challenges/new.json" + axios.get(url).then((response) => { + this.setState({ + choice_url: newchoice_url, + practice_url: newpractice_url, + go_back_url: newgo_back_url, + position: response.data.position, + task_pass_default: response.data.task_pass_default, + submit_url: response.data.submit_url, + checkpointId:checkpointId, + exercisememoMDRefval:response.data.task_pass_default + }) + + this.exercisememoMDRef.current.setValue(response.data.task_pass_default||'') + }).catch((error) => { + console.log(error) + }); + }else{ + //编辑模式 + let url="/shixuns/"+id+"/challenges/"+checkpointId+".json?tab=0"; + axios.get(url).then((response) => { + + let optionsum; + if(response.data.difficulty===1){ + optionsum=[100,200]; + }else if(response.data.difficulty===2){ + optionsum=[300,400,500,600]; + }else if(response.data.difficulty===3){ + optionsum=[700,800,900,1000] + } + 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"; + } + } + this.setState({ + power: response.data.power, + prev_challenge:newprev_challenge, + next_challenge:next_challenge, + choice_url: newchoice_url, + practice_url: newpractice_url, + go_back_url: newgo_back_url, + shixunCreatePractice:response.data.subject, + position:response.data.position, + shixunCreatePracticeGroup:response.data.difficulty, + optionsums:optionsum, + onshixunsmarkvalue:response.data.score, + shixunsskillvaluelist:response.data.tags, + checkpointId:checkpointId, + exec_time:response.data.exec_time, + tab2url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=2", + tab3url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=3", + exercisememoMDRefval:response.data.task_pass + }) + if(response.data.power===false){ + this.props.showSnackbar("你没有权限修改"); + } + + this.exercisememoMDRef.current.setValue(response.data.task_pass||'') + }).catch((error) => { + console.log(error) + }); + + } + + } + + onshixunCreatePracticeChange = (e) => { + let optionsum; + let onshixunsmark; + if(e.target.value===1){ + optionsum=[100,200]; + onshixunsmark=100; + }else if(e.target.value===2){ + optionsum=[300,400,500,600]; + onshixunsmark=300; + }else if(e.target.value===3){ + optionsum=[700,800,900,1000] + onshixunsmark=700; + } + this.setState({ + shixunCreatePracticeGroup: e.target.value, + optionsums:optionsum, + onshixunsmarkvalue:onshixunsmark + }) + } + + shixunCreatePractice = (e) => { + this.setState({ + shixunCreatePractice: e.target.value + }) + } + + CreatePracticesend = () => { + + + this.setState({ + CreatePracticesendtype:true + }) + + if(this.props.status===2){ + this.props.showSnackbar("该实训已经发布不能新建") + this.setState({ + CreatePracticesendtype:false + }) + return + } + let {shixunCreatePractice, shixunCreatePracticeGroup, onshixunsmarkvalue, shixunsskillvaluelist,exec_time} = this.state; + if (shixunCreatePractice === undefined||shixunCreatePractice=="") { + this.setState({ + shixunCreatePracticetype: true + }) + this.props.showSnackbar("任务名称为空") + $('html').animate({ + scrollTop: 10 + }, 1000); + + this.setState({ + CreatePracticesendtype:false + }) + return + } + + if (shixunsskillvaluelist.length === 0) { + this.setState({ + shixunsskillvaluelisttype: true, + CreatePracticesendtype:false + }) + this.props.showSnackbar("技能标签为空") + return + } + if(exec_time===null||exec_time===undefined||exec_time===""){ + + this.setState({ + shixunExec_timeType:false + }) + return + } + + const exercise_editormdvalue = this.exercisememoMDRef.current.getValue().trim(); + let id = this.props.match.params.shixunId; + + let url = "/shixuns/" + id + "/challenges.json"; + + axios.post(url, { + identifier:id, + subject: shixunCreatePractice, + task_pass: exercise_editormdvalue, + difficulty: shixunCreatePracticeGroup, + score: onshixunsmarkvalue, + challenge_tag: shixunsskillvaluelist, + st: 0, + exec_time:exec_time + }).then((response) => { + if (response.data.status === 1) { + // $("html").animate({ scrollTop: 0 }) + //window.location.href=`/shixuns/${id}/challenges/${response.data.challenge_id}/editcheckpoint?tab=2`; + window.location.href=`/shixuns/${id}/challenges/${response.data.challenge_id}/tab=2`; + // this.setState({ + // setopen: true, + // CreatePracticesendtype:false, + // tab2url: "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=2", + // tab3url: "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=3", + // }) + + } + // this.props.showSnackbar(response.data.messages); + }).catch((error) => { + console.log(error) + }); + + + + } + + onshixunsmark = (value) => { + this.setState({ + onshixunsmarkvalue: value + }) + } + + shixunsskill = (e) => { + this.setState({ + shixunsskillvalue: e.target.value + }) + } + + clickshixunsskill = () => { + + let {shixunsskillvalue, shixunsskillvaluelist} = this.state; + if (shixunsskillvalue === "") { + return + } else if (shixunsskillvalue === undefined) { + return + } + + if(shixunsskillvalue == "" || shixunsskillvalue == undefined || shixunsskillvalue == null || (shixunsskillvalue.length>0 && shixunsskillvalue.trim().length == 0)){ + message.error("输入为空,不能保存!"); + return + } + + let list = shixunsskillvaluelist; + list.push(shixunsskillvalue); + this.setState({ + shixunsskillvaluelist: list, + shixunsskillvalue: "" + }) + } + + delshixunsskilllist = (key) => { + let {shixunsskillvaluelist} = this.state; + let newshixunsskillvaluelist = shixunsskillvaluelist; + newshixunsskillvaluelist.splice(key, 1); + this.setState({ + shixunsskillvaluelist: newshixunsskillvaluelist + }) + } + + editPracticesend=()=>{ + + this.setState({ + editPracticesendtype:true + }) + + let {shixunCreatePractice, shixunCreatePracticeGroup, onshixunsmarkvalue, shixunsskillvaluelist,checkpointId,exec_time} = this.state; + + const exercise_editormdvalue = this.exercisememoMDRef.current.getValue().trim(); + + let id = this.props.match.params.shixunId; + + let url = "/shixuns/"+id+"/challenges/"+checkpointId+".json"; + + if (shixunCreatePractice === undefined||shixunCreatePractice=="") { + // this.setState({ + // shixunCreatePracticetype: true + // }) + this.props.showSnackbar("任务名称为空") + $('html').animate({ + scrollTop: 10 + }, 1000); + this.setState({ + editPracticesendtype:false + }) + return + } + + if (shixunsskillvaluelist.length === 0) { + // this.setState({ + // shixunsskillvaluelisttype: true + // }) + this.props.showSnackbar("技能标签为空") + this.setState({ + editPracticesendtype:false + }) + return + } + + if(exec_time===null||exec_time===undefined||exec_time===""){ + + this.setState({ + shixunExec_timeType:false + }) + return + } + axios.put(url, { + tab:0, + identifier:id, + id:checkpointId, + challenge:{ + subject: shixunCreatePractice, + task_pass: exercise_editormdvalue, + difficulty: shixunCreatePracticeGroup, + score: onshixunsmarkvalue, + exec_time:exec_time + }, + challenge_tag:shixunsskillvaluelist + }).then((response) => { + this.props.showSnackbar(response.data.messages); + if (response.data.status === 1) { + window.location.href=`/shixuns/${id}/challenges/${checkpointId}/tab=2`; + this.setState({ + setopen: true, + editPracticesendtype:false, + tab2url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=2", + tab3url: "/shixuns/" + id + "/challenges/"+checkpointId+"/tab=3", + }) + // window.location.href = "/shixuns/" + id + "/challenges/"+response.data.challenge_id+"/tab=2" + } + }).catch((error) => { + console.log(error) + }); + + + } + + onshixunsmarks=()=> { + this.setState({ + marktype:true + }) + } + + onshixunsmarkss=()=> { + this.setState({ + marktype:false + }) + } + + setexec_time=(e)=>{ + this.setState({ + exec_time:e.target.value + }) + } + render() { + + let shixuntype = this.props.match.params.type; + + + let {marktype, + shixunCreatePracticetype, shixunsskillvaluelisttype, + choice_url, practice_url, go_back_url, position, task_pass_default, submit_url, setopen,checkpointId,prev_challenge,next_challenge,power, + shixunCreatePractice, shixunCreatePracticeGroup, onshixunsmarkvalue, shixunsskillvalue, shixunsskillvaluelist, tab2url, tab3url,optionsums, + CreatePracticesendtype,editPracticesendtype + } = this.state; + + let options; + if(optionsums!=undefined){ + options = optionsums.map((d, k) => { + return ( + + ) + }) + } + + return ( + +
    + + +
    + +
  • + 本关任务 +
  • + +
  • + {tab2url === "" ? 评测设置 : 评测设置} +
  • + +
  • + {tab3url === "" ? 参考答案 : 参考答案} + +
  • +
    + +
    +
    +

    任务名称

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

    过关任务

    + + + +

    +

    +
    + + +
    +

    难度系数

    +
    + + + 简单 + 中等 + 困难 + + +
    +

    奖励经验值

    +
    + * + + + +

    + 如果学员答题错误,则不能得到相应的经验值
    + 如果学员成功得到经验值,那么将同时获得等值的金币奖励,如:+10经验值、+10金币 +

    + + 必填项 +
    +
    + + +
    +

    技能标签

    +
    + * +
    + + {/*+ 添加*/} +
    学员答题正确将获得技能,否则不能获得技能
    +
    + + { + shixunsskillvaluelist===undefined?"":shixunsskillvaluelist.length === 0 ? "" : shixunsskillvaluelist.map((itme, key) => { + return ( +
  • {itme} + this.delshixunsskilllist(key)}>× +
  • + ) + }) + } + + +
    +
    + + 必填项 +
    +
    + +
    +

    服务配置

    +
    + * + +
    + +
    + 必填项 +
    +
    +
    + +
    4||this.props.identity===undefined?"none":'block'}} + > + {checkpointId===undefined?提交: + 提交} + {/*取消*/} + 取消 +
    +
    +
    + ) + } +} + + diff --git a/public/react/src/modules/tpm/jupyter/index.js b/public/react/src/modules/tpm/jupyter/index.js index 25f82ef94..702ae2b71 100644 --- a/public/react/src/modules/tpm/jupyter/index.js +++ b/public/react/src/modules/tpm/jupyter/index.js @@ -279,9 +279,13 @@ function JupyterTPI (props) { }; // 分页处理 - const handleChangePage = (page) => { - - handlePageChange(page); + const handleChangePage = (e) => { + //滑动到底判断 + let newscrollTop=parseInt(e.currentTarget.scrollTop); + let allclientHeight=e.currentTarget.clientHeight+newscrollTop; + if(e.currentTarget.scrollHeight-allclientHeight===0||e.currentTarget.scrollHeight-allclientHeight===1||e.currentTarget.scrollHeight-allclientHeight===-1){ + handlePageChange(pagination.page+1); + } } // const listCtx = ; useEffect(() => { @@ -310,7 +314,7 @@ function JupyterTPI (props) { }); const oUl = ( -
      +
        handleChangePage(event)} > { oList }
      ); @@ -420,18 +424,18 @@ function JupyterTPI (props) {
    - { renderCtx } -
    - {total<20?"":} -
    - + { renderCtx } + {/*
    */} + {/* {total<20?"":}*/} + {/*
    */}
    +
    diff --git a/public/react/src/modules/tpm/jupyter/index.scss b/public/react/src/modules/tpm/jupyter/index.scss index e6a95406a..57f833437 100644 --- a/public/react/src/modules/tpm/jupyter/index.scss +++ b/public/react/src/modules/tpm/jupyter/index.scss @@ -124,11 +124,17 @@ padding: 0px; } .ant-drawer-wrapper-body{ + overflow: hidden !important; padding-top: 60px; background: #070F1A; padding-bottom: 40px; } + .jupyter_data_list{ + height:500px; + overflow: auto; + } + .ant-pagination{ color:#fff !important; } diff --git a/public/react/src/redux/actions/ojForm.js b/public/react/src/redux/actions/ojForm.js index 9cd4e8228..094257f42 100644 --- a/public/react/src/redux/actions/ojForm.js +++ b/public/react/src/redux/actions/ojForm.js @@ -4,7 +4,7 @@ * @Github: * @Date: 2019-11-20 16:35:46 * @LastEditors : tangjiang - * @LastEditTime : 2019-12-27 14:18:02 + * @LastEditTime : 2019-12-27 18:50:22 */ import types from './actionTypes'; import CONST from '../../constants'; @@ -297,6 +297,9 @@ export const validateOjForm = (props, type, cb) => { type: types.SAVE_OJ_FORM_ID, payload: identifier }); + if (paramsObj['submitType'] === 'add' && identifier) { + props.history.push(`/problems/${identifier}/edit`) + }; } // 保存或更新后,调用start接口 // linkToDev(dispatch, props); diff --git a/public/react/src/redux/reducers/jupyterReducer.js b/public/react/src/redux/reducers/jupyterReducer.js index 75c9d374f..4b117b453 100644 --- a/public/react/src/redux/reducers/jupyterReducer.js +++ b/public/react/src/redux/reducers/jupyterReducer.js @@ -26,9 +26,13 @@ const JupyterReducer = (state = initState, action) => { switch (action.type) { case types.GET_JUPYTER_DATA_SETS: const { data_sets, data_sets_count,folder_name} = action.payload; + let newjupyter_data_set=state.jupyter_data_set; + data_sets.map((item,key)=>{ + newjupyter_data_set.push(item) + }) return { ...state, - jupyter_data_set: data_sets, + jupyter_data_set: newjupyter_data_set, jupyter_data_set_count: data_sets_count, jupyter_folder_name:folder_name, } diff --git a/public/stylesheets/educoder/edu-all.css b/public/stylesheets/educoder/edu-all.css index 154be61be..4b663de87 100644 --- a/public/stylesheets/educoder/edu-all.css +++ b/public/stylesheets/educoder/edu-all.css @@ -401,9 +401,9 @@ label.infolabel{display: block;float: left;width: 56px;text-align: right;margin- .task-colspan{min-width:25%;text-align: left;display: block;float: left;color: #999; } .colspan-grey{border-radius: 12px;background-color: #E6E6E6;padding: 3px 10px;color: #747A7F} /*新建任务*/ -.challenge_nav{padding: 40px 20px 0px 20px;border-bottom: 1px solid #eee;} -.challenge_nav li{width: auto;float: left;margin-right: 40px;position: relative} -.challenge_nav li.active:after{position: absolute;content: '';width: 50%;background-color: #4CACFF;height: 3px;border-radius: 2px;left: 25%;bottom: 0px;} +.challenge_nav{padding: 20px 20px 0px 20px;border-bottom: 1px solid #eee;} +.challenge_nav li{width: auto;float: left;margin-right: 20px;position: relative} +.challenge_nav li.active:after{position: absolute;content: '';width:76%;background-color: #4CACFF;height: 3px;border-radius: 2px;left: 25%;bottom: 0px;} .challenge_nav li a{display: block;width: 100%;padding-bottom: 20px;} .add_choose_type{width: 60px;height: 20px;line-height: 19px;border-radius: 2px;background-color: #eaeaea;color: #999!important;display: block;float: left;text-align: center;margin-top: 4px;}