import React, { Component } from 'react'; import PropTypes from 'prop-types'; // import getMuiTheme from 'material-ui/styles/getMuiTheme' import Dialog, { DialogActions, DialogContent, DialogContentText, DialogTitle, } from 'material-ui/Dialog'; import Button from 'material-ui/Button'; import MainContent from './MainContent' import UpdateDrawer from './component/UpdateDrawer' import axios from 'axios' import _ from 'lodash' const CancelToken = axios.CancelToken; let locationPath = window.location.pathname; let readingRepoTimes = 0; function updateCodeMirror () { // (TODO 这里的处理方式比较蹩脚,css没搞定)总高度减去页签头高度 window.$('#games_repository_contents .CodeMirror').height(window.$('#games_repository_contents').height() - 40) // 为了解决这个问题:一开始进入TPI,代码框的内容显示不全,需要点击一下代码框才会显示全 $('#games_repository_valuation .CodeMirror .CodeMirror-scroll').scrollTop('2') // 选择题切换到编程题会出现codemirror没初始化成功的问题,加下refresh window.editor_CodeMirror && window.editor_CodeMirror.refresh() } // ============================ ============================ ============================ ============================ // 老版本的评测等待通知代码 // ============================ ============================ ============================ ============================ const $ = window.$; let next_game = null; function getRandom(min, max){ var r = Math.random() * (max - min); var re = Math.round(r + min); re = Math.max(Math.min(re, max), min); return re; } function tipContent(flag, num, mintes, second, first){ console.log("第几次查询get_waiting_time:" + first); var random = getRandom(15, 120); var mintes = parseInt((second - random) / 60); var html=tip_half(flag, num, mintes, second); $("#update_game_tip").html(html); if(first == 1){ show_tip_content(); } } // 显示右侧评测等待通知 function show_tip_content(){ var $tip = $(".tip-panel-animate"); $(".update_back_main").show(); $tip.addClass("animate-tip").show(); setTimeout(function(){$tip.removeClass("animate-tip")}, 700); } //隐藏右侧评测等待通知 function hide_tip_content(){ var $tip = $(".tip-panel-animate"); $tip.addClass("animate-tip-hide"); $(".-task-title").hide(); setTimeout(function(){ $tip.hide().removeClass("animate-tip-hide animate-tip"); check_hide(); }, 700); } window.hide_tip_content = hide_tip_content; //判断是否所有的提示信息都已经隐藏 function check_hide(){ var dis = true; var $tipLeft = $(".tip-panel-animate-left"); for(var i = 0; i < $tipLeft.length; i++){ if($tipLeft.eq(i).css("display") == "block"){ dis = false; return; } } if($(".tip-panel-animate").css("display") == "block"){ dis = false; } if(dis){ $(".update_back_main").hide(); $('#info_tip_tab').removeClass('leftnav-active');//去除系统通知的选中状态 $('#current_task_tab').addClass('leftnav-active');//选中当前任务 } } /*评测等待通知*/ function tip_half(flag, num, mintes, second){ var htmlvalue=""; htmlvalue+="

评测等待通知

"; if(flag == 0){ htmlvalue+="

目前有" + num + "人正在等待评测,还需等待约" + (mintes > 0 ? mintes + "分钟" : second + "秒") + "。您可以先完成“下一关”任务。

"; }else{ htmlvalue+="

目前有超过" + num*10 + "人正在等待评测,请您稍后再试。您可以先完成其他关卡

"; } htmlvalue+="
"; if(flag == 0){ htmlvalue+="继续等待"; if (next_game) { htmlvalue+="下一关"; } else { htmlvalue+="已经是最后一关啦" } }else{ htmlvalue+="知道啦"; if (next_game) { htmlvalue+="下一关"; } else { htmlvalue+="已经是最后一关啦" } } htmlvalue+="
"; return htmlvalue; } /*更新通知*/ function tip_half_update(){ var htmlvalue=""; htmlvalue+="

本次更新设计以下几个步骤,预计需要花费几分钟时间,请耐心等待~

"; htmlvalue+="
    "; htmlvalue+="
  1. 更新版本库
  2. "; htmlvalue+="
  3. 同步评测机制
"; htmlvalue+="
"; htmlvalue+="知道啦"; htmlvalue+="
"; return htmlvalue; } // ============================ ============================ ============================ ============================ // ============================ ============================ ============================ ============================ const UPDATED = 0; const SAVING = 1; const SAVED = 2; const SAVE_FAILED = 3; class MainContentContainer extends Component { constructor(props) { super(props) this.onRepositoryCodeUpdate = this.onRepositoryCodeUpdate.bind(this) this.onRunCodeTest = this.onRunCodeTest.bind(this) this.codemirrorDidMount = this.codemirrorDidMount.bind(this) this.fetchRepositoryCode = this.fetchRepositoryCode.bind(this) this.showResetCodeDialog = this.showResetCodeDialog.bind(this) this.showResetPassedCodeDialog = this.showResetPassedCodeDialog.bind(this) this.oldRepositoryCode = ''; this.state = { repositoryCode: '', open: false, // 繁忙等级等提示用Dialog,考虑重构封装到根组件 gameBuilding: false, // 评测中标志 codeStatus: SAVED, // 0 已修改 1 保存中 2 已保存 3 保存失败 codeLoading: true, // code加载中 readRepoTimeout: false, // 加载代码轮训超时 resetCodeDialogOpen: false, // 考虑重构封装到根组件 resetPassedCodeDialogOpen: false, // 考虑重构封装到根组件 isEditablePath: true } } // ------------------------------------------------ // static childContextTypes = { // muiTheme: PropTypes.object // } // getChildContext() { // return { // muiTheme: getMuiTheme() // } // } // ------------------------------------------------ handleClose = () => { this.setState({open: false}); }; shouldComponentUpdate(nextProps, nextState) { // _.isEqual(this.props, nextProps) if (JSON.stringify(nextProps) !== JSON.stringify(this.props) || !_.isEqual(this.state, nextState)) { return true } else { return false } } componentWillReceiveProps(newProps, nContext) { // 编程题才需要拿代码 if (newProps.game && newProps.st === 0) { if (!this.props || !this.props.game || ( newProps.game.identifier !== this.props.game.identifier ) ) { setTimeout(this.fetchRepositoryCode( newProps), 1500); } else if ( this.props.challenge.pathIndex != newProps.challenge.pathIndex && newProps.challenge.pathIndex !== -1) { // 切换到只读文件 // pathIndex切换 setTimeout(this.fetchRepositoryCode( newProps), 1500); } } if (newProps.myshixun) { var stageId = newProps.match.params.stageId; var shixunId = newProps.myshixun.identifier; // locationPath = `/myshixuns/${shixunId}/stages/${stageId}` locationPath = `/api/v1/games/${newProps.game.identifier}`; next_game = newProps.next_game; } } componentDidUpdate(prevProps, prevState, snapshot) { const { game } = this.props if (game && prevProps.game && prevProps.game.identifier !== game.identifier) { // 切换关卡时,停止轮训 this.oldGameIdentifier = prevProps.game.identifier; } } // arg_path 点击文件目录树时,传入的点击节点对应的path fetchRepositoryCode( props, arg_path, type, isRetry) { const { challenge, showSnackbar, game, shixun, myshixun, hide_code } = props ? props : this.props; if (shixun.vnc == true) { // vnc模式下不需要加载代码 return true; } if ( // true || hide_code) { // 隐藏code的实训 this.setState({ codeLoading: false }); return; } const stageId = game.identifier let path; let isEditablePath = false; if (arg_path) { path = arg_path; if (challenge.multiPath) { challenge.path.forEach(item => { if (path == item) { isEditablePath = true; } }) } else if (path == challenge.path) { isEditablePath = true; } } else { isEditablePath = true; path = challenge.multiPath ? challenge.path[challenge.pathIndex] : challenge.path; } if (readingRepoTimes === 0) { this.setState({ readRepoTimeout: false }) } // http://localhost:3000/api/v1/games/zl6kx8f7vfpo/rep_content let status = type ? type : 0; // type 1 目录树点击 默认 0: 正常代码加载 // const fetchRepoCodeUrl = `/api/v1/games/${stageId}/rep_content?path=${path}&shixun_gpid=${shixun.gpid}&status=${status}&retry=${isRetry ? 1 : 0}` const fetchRepoCodeUrl = `/tasks/${game.identifier}/rep_content.json?path=${path}&status=${status}&retry=${isRetry ? 1 : 0}` // ?path=${path}&shixun_gpid=${shixun.gpid}&status=${status}&retry=${isRetry ? 1 : 0} if (this.state.codeLoading === true && this._cancel) { // 多次请求,则cancel掉前面的请求 // bug cancel掉第一次请求后,第二次请求也没法发出,先注释掉了 // this._cancel(); // this._cancel = null; } const that = this; this.setState({ gameBuilding: false, codeLoading: true }); axios.get(fetchRepoCodeUrl, { // path: path // withCredentials: true, // cancelToken: new CancelToken(function executor(c) { // // An executor function receives a cancel function as a parameter // that._cancel = c; // }) }).then((fetchRepositoryCodeResponse) => { // 空字符串还是正常切换 if (fetchRepositoryCodeResponse.data.status == 0) { readingRepoTimes = readingRepoTimes + 1; if(readingRepoTimes > 9) { this.setState({ readRepoTimeout: true }) readingRepoTimes = 0; showSnackbar(`网络异常,请稍后重试。`); return }else{ if (status === 0) { // 轮训后点击切换关卡的话,停止上一关的轮训 if (game.identifier == this.oldGameIdentifier) { this.oldGameIdentifier = null; return; } setTimeout(() => { this.fetchRepositoryCode(props,arg_path,type) }, 1500); } } }else if (fetchRepositoryCodeResponse.data && fetchRepositoryCodeResponse.data.status === -1) { this.setState({ codeLoading: false }) console.error('`获取代码失败!') showSnackbar(`获取代码失败:${fetchRepositoryCodeResponse.data.message}`) }else if (fetchRepositoryCodeResponse.data.status === -3) { readingRepoTimes = readingRepoTimes + 1; if(readingRepoTimes > 9) { this.setState({ readRepoTimeout: true }) readingRepoTimes = 0; showSnackbar(`网络异常,请稍后重试。`); return }else{ if (status === 0) { // 轮训后点击切换关卡的话,停止上一关的轮训 if (game.identifier == this.oldGameIdentifier) { this.oldGameIdentifier = null; return; } // 重试调用的这个 this.props.fetchRepositoryCode(this.props, null, null, true) setTimeout(() => { this.fetchRepositoryCode(props, arg_path, type, 1) }, 1500); } } } else if (fetchRepositoryCodeResponse.data.status === -4) { // 异常 直接重试 this.fetchRepositoryCode(props, null, null, true) } else{ this.setState({ isEditablePath, currentPath: path }); this.oldRepositoryCode = fetchRepositoryCodeResponse.data.content || ''; this.updateRepositoryCode(this.oldRepositoryCode, updateCodeMirror) } }).catch(error =>{ console.log(error) this.setState({ codeLoading: false }); showSnackbar(`服务端异常,请联系管理员!`); }) } componentDidMount() { window.$(window.documents).bind("submitChoose",function(){ alert("hello world!"); }); } doFileUpdateRequestOnCodeMirrorBlur = () => { var fileUpdatePromise = this.doFileUpdateRequest(true) if (fileUpdatePromise) { fileUpdatePromise.then((resData) => { if (resData.status === -1) { // 保存文件出现异常 this.setState({ codeStatus: SAVE_FAILED }) return; } this.setState({ codeStatus: SAVED }) }).catch((e) => { console.log(e) this.setState({ codeStatus: SAVE_FAILED }) }) } } componentWillUnmount() { this.autoSaveInterval && clearInterval(this.autoSaveInterval); } onEditorBlur = () => { if (this.autoSaveInterval) { clearInterval(this.autoSaveInterval); this.autoSaveInterval = null; } this.doFileUpdateRequestOnCodeMirrorBlur() } onEditorFocus = () => { if (this.autoSaveInterval) { return; } this.autoSaveInterval = setInterval( () => { // code变化时,,每30秒保存到数据库,没变化则不处理 var autoSave = true var fileUpdatePromise = this.doFileUpdateRequest(true) if (fileUpdatePromise) { fileUpdatePromise.then((resData) => { // TODO 保存失败的处理 this.setState({ codeStatus: SAVED }) }).catch((e) => { console.log(e) }) } }, 30000); } codemirrorDidMount() { var editor_CodeMirror = window.editor_CodeMirror; var editor_monaco = window.editor_monaco; // 失去焦点终止保存事件 // editor_CodeMirror && editor_CodeMirror.on('blur', this.onEditorBlur); // editor_monaco && editor_monaco.onDidBlurEditorText(this.onEditorBlur) // 每60秒钟保存一次 editor_CodeMirror && editor_CodeMirror.on('focus', this.onEditorFocus); editor_monaco && editor_monaco.onDidFocusEditorText(this.onEditorFocus) } _refreshHtmlIframe(newCode) { // TODO 是否是html的code const isHtmlCode = this.props.challenge.isHtml; if (isHtmlCode) { // TODO 参考 _code_actions.html.erb 做link script标签替换 // var $iframe = window.$('#htmlIframe'); // $iframe.ready( () => { // $iframe.contents().find("body").html(newCode || this.state.repositoryCode); // }); window.tpi_html_show(newCode) } } updateRepositoryCode(newCode, callback) { this.setState({ codeLoading: false, repositoryCode: newCode, }, () => { callback && callback() }); this._refreshHtmlIframe(newCode) } onRepositoryCodeUpdate(newCode) { if (this.refreshHtmlTimeout) { clearTimeout(this.refreshHtmlTimeout) } // 每2s刷新一次 this.setState({ codeStatus: UPDATED }) this.refreshHtmlTimeout = setTimeout(()=>{ // this.setState({ // // codeStatus: UPDATED, // repositoryCode: newCode // }); this._refreshHtmlIframe(newCode) this.refreshHtmlTimeout = null; }, 1500) } // forTest true 是评测时触发的file_update doFileUpdateRequest(checkIfCodeChanged, forTest) { const { codeStatus } = this.state; if (!forTest && codeStatus !== UPDATED) { // 已修改状态才能保存 return; } // TODO 连着2次请求服务端会报500 // if (forTest == true) { // if (this.state.codeStatus != UPDATED) { // return; // } // } let codeContent = this.state.repositoryCode; if (window['editor_CodeMirror']) { codeContent = window.editor_CodeMirror.getValue(); } else if (window.editor_monaco) { codeContent = window.editor_monaco.getValue() } if (checkIfCodeChanged === true && this.oldRepositoryCode == codeContent) { // console.log('code not changed'); this.setState({ codeStatus: SAVED }) return null; } const { challenge, output_sets, onRunCodeTestFinish, myshixun } = this.props // var url = `${locationPath}/file_update?path=${encodeURIComponent(challenge.path)}` var url = `/myshixuns/${myshixun.identifier}/update_file.json` this.setState({ codeStatus: SAVING }) this.oldRepositoryCode = codeContent; let argPath; if (challenge.pathIndex === -1) { // 当前是只读文件 argPath = challenge.multiPath === true ? challenge.path[0] : challenge.path } else { argPath = challenge.multiPath === true ? challenge.path[challenge.pathIndex] : challenge.path } // 跨域请求时会多一个options请求 // https://github.com/axios/axios/issues/475 return axios.post(url, { content: codeContent, // 评测的时候传1,其它情况不用传,主要是为了区分是用户自己提交还是自动提交 // type: forTest === true ? 1 : 0, evaluate: forTest === true ? 1 : 0, game_id : this.props.game.id, path: argPath }, { // withCredentials: true } ) } onRunChooseTest() { const { st, game, onRunChooseTestFinish, showSnackbar } = this.props; // 获取form表单值 var value = this.refs.mainContent.refs.chooseQ.getForm().getFieldsValue(); var valueArray = []; // map转array var unSelectOptionIndexArray = [] // 自己做未选提示 for(var key in value) { if (!value[key] || (_.isArray(value[key]) && !value[key].join('')[0])) { unSelectOptionIndexArray.push(key) break; // 为空处理 } // TODO array判断 valueArray[parseInt(key)] = _.isArray(value[key]) ? value[key].join('') : value[key] ; } if (unSelectOptionIndexArray.length) { var unSelectOptionIndex = unSelectOptionIndexArray[0] var _unSelectOptionDom = window.$('#games_repository_contents #choice' + unSelectOptionIndex )[0] _unSelectOptionDom.scrollIntoView() showSnackbar(`请先给第${parseInt(unSelectOptionIndex)+1}题选择一个答案。`) // , 'top', 'center' // 有未选择的题 return; } // TODO 未选提示、props.onRunChooseTest console.log(unSelectOptionIndexArray) console.log('valueArray', valueArray) var url = `/api/v1/games/${game.identifier}/choose_build` this.setState({ gameBuilding: true, }) axios.post(url, { answer: valueArray }, { withCredentials: true, // headers: { // 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', // } } ).then((response) => { if (response.data.test_sets) { // 评测完成 onRunChooseTestFinish(response.data); this.setState({ gameBuilding: false, }) } console.log(response) }).catch((error) => { console.log(error) this.setState({ gameBuilding: false, }) }) } setGameBuildFalse() { this.setState({ gameBuilding: false }) } onRunCodeTest() { // tipContent(0, 100, 30, 360, 1) // return; // for test const { st, challenge, output_sets, onRunCodeTestFinish, loading, showDialog, handleGdialogClose, onPathChange } = this.props const { isEditablePath } = this.state; if (isEditablePath === false) { showDialog({ contentText: '需要先切回可编辑的文件才可评测,确认要现在切换吗?', callback: () => { onPathChange(0) handleGdialogClose(); } }) return; } if (loading === true) { return; // 还在加载中 } if (st === 1) { // 选择题 this.onRunChooseTest(); return; } // ---------------------- 以下是编程题处理 ---------------------- console.log('onRunCodeTest onRunCodeTest') // http://localhost:3000/myshixuns/so5w6iap97/stages/zl6kx8f7vfpo/file_update?path=src%2Fstep6%2FLinkedList.java // var url = `${locationPath}/file_update?path=${encodeURIComponent(challenge.path)}` // var timeOut = parseInt(<%= @myshixun.main_mirror.try(:time_limit) %>); // 超时参数 this.setEvaluateMiddleStatusText('') this.setState({ gameBuilding: true }) this.doFileUpdateRequest(null, true) .then((fileUpdateResponse) => { console.log(fileUpdateResponse); if (fileUpdateResponse.data.status === -1) { // 保存文件出现异常 this.setGameBuildFalse() this.setState({ codeStatus: SAVE_FAILED }) return; } this.setState({ codeStatus: SAVED }) this.gameBuild(fileUpdateResponse, 1) }) .catch( (fileUpdateError) => { console.log(fileUpdateError); this.setGameBuildFalse() }); } setEvaluateMiddleStatusText = (msg) => { window.$('#evaluateMiddleStatusText').html(msg) } // 之前的task_commit方法 gameBuild(fileUpdateResponse, first) { const { st, challenge, output_sets, onRunCodeTestFinish, resetTestSetsExpandedArray, showSnackbar, time_limit, game } = this.props const { resubmit, content_modified, sec_key } = fileUpdateResponse.data; const timeOut = time_limit; // http://localhost:3000/myshixuns/so5w6iap97/stages/zl6kx8f7vfpo/game_build?first=1&resubmit=GDBEX741_1993 // const game_build_url = `${locationPath}/game_build?first=${first}&resubmit=${resubmit}&content_modified=${content_modified}` const game_build_url = `/tasks/${game.identifier}/game_build.json?first=${first}&resubmit=${resubmit}&content_modified=${!!content_modified ? 1 : 0}&sec_key=${sec_key}` // var timeOut = parseInt(<%= @myshixun.main_mirror.try(:time_limit) %>); // 超时参数 resetTestSetsExpandedArray(); axios.get(game_build_url, { // withCredentials: true, }).then((gameBuildResponse) => { console.log(gameBuildResponse); // D:\Code\trustieplus\app\views\games\_code_actions.html.erb let { port, ableToCreate, waitNum, waitingTime, had_done } = gameBuildResponse.data; // http://localhost:3000/myshixuns/so5w6iap97/stages/zl6kx8f7vfpo/game_status?resubmit=GDBEX741_1993&port=50241&time_out=false // TODO dead code 往下走 // if (ableToCreate == 1) { if (gameBuildResponse.data.status == -1) { return } let timeOutFlag = false; const intervalDuring = 1000; let requestTimes = 0; var gameStatusIntervalId = setInterval(()=>{ // let game_status_url = `${locationPath}/game_status?port=${port}&resubmit=${resubmit||""}&time_out=${timeOutFlag}` let game_status_url = `/tasks/${game.identifier}/game_status.json?port=${port}&resubmit=${resubmit||""}&time_out=${timeOutFlag}&sec_key=${sec_key}` axios.get(game_status_url, { // withCredentials: true, }).then((gameStatusResponse) => { requestTimes++; const { status, running_code_message } = gameStatusResponse.data; if(!gameStatusResponse.data || !status && status !== 0) { if(requestTimes >= timeOut - 1){ // 最后一次参数改为true timeOutFlag = true; } if (running_code_message) { this.setEvaluateMiddleStatusText(running_code_message) } return; } if (timeOutFlag === false && (status === 2 || status === 0)) { // 网络太慢或服务处理较慢的情况下,可能这里会执行第二次 console.log('clearIntervalclearIntervalclearIntervalclearInterval status2 0') clearInterval(gameStatusIntervalId); onRunCodeTestFinish(gameStatusResponse.data) this.setGameBuildFalse() timeOutFlag = true; // 用这个处理重复的获取status为2或0的状态 } // 超时处理 if(timeOutFlag === true) { // clearInterval(gameStatusIntervalId); console.log('超时处理返回值') this._refreshHtmlIframe(); this.setGameBuildFalse() return; } if(requestTimes >= timeOut - 1){ // 最后一次参数改为true timeOutFlag = true; } }).catch((gameStatusError) => { console.log(gameStatusError); }) if (timeOutFlag === true) { clearInterval(gameStatusIntervalId); this.setState({ open: true, gameBuilding: false }) } }, intervalDuring) window.gameStatusIntervalId = gameStatusIntervalId; // } else if(ableToCreate === 0) { // 排队等待,重新执行gameBuild // const mintes = parseInt((waitNum * 120) / 60); // 等待时间 = 等待人数 * (15(秒)---3分钟的随机数); // tipContent(ableToCreate, waitNum, mintes, waitNum * 180, first); // setTimeout(()=>{ // this.gameBuild(fileUpdateResponse, first + 1) // }, 10000) // this.setGameBuildFalse() // } else if(ableToCreate == -1) { // 排队人数过多,建议先玩下一关 // tipContent(ableToCreate, waitNum, 0, 0, first); // this.setGameBuildFalse() // } else { // showSnackbar("实训云平台繁忙(繁忙等级:94),请稍后刷新并重试") // this.setGameBuildFalse() // } }).catch((gameBuildError) => { console.log(gameBuildError); this.setGameBuildFalse() }) } handleResetCodeDialogClose() { this.setState({ resetCodeDialogOpen: false }) } showResetCodeDialog() { this.setState({ resetCodeDialogOpen: true }) } doResetCode() { const { game, challenge, showSnackbar } = this.props; this.handleResetCodeDialogClose(); let path = challenge.path if (challenge.multiPath) { path = path[challenge.pathIndex] } // const url = `/api/v1/games/${game.identifier}/reset_original_code?path=${path}`; const url = `/tasks/${game.identifier}/reset_original_code.json?path=${path}`; this.setState({ codeLoading: true }) axios.get(url, { // withCredentials: true, }).then((res) => { this.handleResetCodeDialogClose(); if (res.data.status === -1) { console.error('代码重置失败!'); this.setState({ codeLoading: false }) showSnackbar(res.data.message || '加载初始的代码失败') return; } // this.setState({ // codeLoading: false // }) this.updateRepositoryCode(res.data.content, updateCodeMirror) }).catch(error =>{ this.setState({ codeLoading: false }) }) } handleResetPassedCodeDialogClose() { this.setState({ resetPassedCodeDialogOpen: false }) } showResetPassedCodeDialog() { this.setState({ resetPassedCodeDialogOpen: true }) } doResetPassedCode() { this.handleResetPassedCodeDialogClose(); const { game, challenge, showSnackbar } = this.props; let path = challenge.path if (challenge.multiPath) { path = path[challenge.pathIndex] } // const url = `/api/v1/games/${game.identifier}/reset_passed_code?path=${path}`; const url = `/tasks/${game.identifier}/reset_passed_code.json?path=${path}`; this.setState({ codeLoading: true }) axios.get(url // , { // withCredentials: true, // } ).then((res) => { this.handleResetPassedCodeDialogClose(); if (res.data.status === -1) { console.error('passed代码重置失败!') this.setState({ codeLoading: false }) showSnackbar(res.data.message || '加载上次通过的代码失败') return; } // 注意,最好是合并到一个setState, 这里分两次setState的话,触发了2次重新渲染 // this.setState({ // codeLoading: false // }) this.updateRepositoryCode(res.data.content, updateCodeMirror) }).catch(error =>{ this.setState({ codeLoading: false }) }) } render() { const { challenge, output_sets, time_limit } = this.props; // TODO 这里直接写死了,game_status在超时时也会返回这句话 let msg = (
{`代码评测超时!本关限定时间为:${time_limit}s,`}

请检查代码是否存在死循环或其他耗时操作
) return ( {"提示"} { msg } this.handleResetCodeDialogClose()} > {"提示"}
你在本文件中修改的内容将丢失

是否确定重新加载初始代码?
this.handleResetPassedCodeDialogClose()} > {"提示"}
你在本关中修改的内容将丢失

是否确定重新加载上次通过的代码?
); } } export default MainContentContainer;