-
标准答案文件路径
+ {pathoptionvalue===1||pathoptionvalue===5||pathoptionvalue===6?
+
+
标准答案文件路径(该路径下的文件将在学员评测本关任务时,作为参考答案显示在查看效果页,供学员参考;请注意与程序文件所在文件夹分开)
@@ -1065,9 +940,9 @@ export default class TPMevaluation extends Component {
:""}
- {pathoptionvalue===-1?"":
-
-
学员答案文件路径
+ {pathoptionvalue===-1?"":
+
+
学员答案文件路径(学员评测本关任务时生成的文件将保存在该路径下,并作为实际输出显示在查看效果页,供学员确认;请注意与程序文件所在文件夹分开)
@@ -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 {
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) {