diff --git a/public/react/src/context/TPIContextProvider.js b/public/react/src/context/TPIContextProvider.js
index d5d8715f5..881a596e1 100644
--- a/public/react/src/context/TPIContextProvider.js
+++ b/public/react/src/context/TPIContextProvider.js
@@ -1,867 +1,867 @@
-import React, { Component } from 'react';
-import ReactDOM from 'react-dom';
-
-import axios from 'axios';
-import Snackbar from 'material-ui/Snackbar';
-import Fade from 'material-ui/transitions/Fade';
-
-import update from 'immutability-helper'
-
-import Dialog, {
- DialogActions,
- DialogContent,
- DialogContentText,
- DialogTitle,
-} from 'material-ui/Dialog';
-
-import Button from 'material-ui/Button';
-
-import EvaluateSuccessEffectDisplay from './EvaluateSuccessEffectDisplay'
-
-import _ from 'lodash'
-
-/*
- 若干js库
- http://inorganik.github.io/countUp.js/
-
-*/
-/*
- 切下一关需要更新:
- LeftViewContainer state.gameAnswer
-*/
-
-import TPIContext from './TPIContext'
-import { EDU_ADMIN, EDU_SHIXUN_MANAGER, EDU_SHIXUN_MEMBER, EDU_CERTIFICATION_TEACHER
- , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL} from 'educoder'
-import { MuiThemeProvider, createMuiTheme, withStyles } from 'material-ui/styles';
-import MUIDialogStyleUtil from '../modules/page/component/MUIDialogStyleUtil'
-
-const styles = MUIDialogStyleUtil.getTwoButtonStyle()
-
-// 主题自定义
-const theme = createMuiTheme({
- palette: {
- primary: {
- main: '#4CACFF',
- contrastText: 'rgba(255, 255, 255, 0.87)'
- },
- secondary: { main: '#4CACFF' }, // This is just green.A700 as hex.
- },
-});
-
-const testSetsExpandedArrayInitVal = [false, false, false, false, false,
- false, false, false, false, false,
- false, false, false, false, false,
- false, false, false, false, false]
-window.__fetchAllFlag = false; // 是否调用过fetchAll TODO 如何多次使用provider?
-class TPIContextProvider extends Component {
- constructor(props) {
- super(props)
- this.onRunCodeTestFinish = this.onRunCodeTestFinish.bind(this)
- this.onRunChooseTestFinish = this.onRunChooseTestFinish.bind(this)
- this.testSetUnlock = this.testSetUnlock.bind(this)
-
- this.onTestSetHeaderClick = this.onTestSetHeaderClick.bind(this)
-
- this.onShowPrevStage = this.onShowPrevStage.bind(this)
- this.onShowNextStage = this.onShowNextStage.bind(this)
-
- this.readGameAnswer = this.readGameAnswer.bind(this)
- this.praisePlus = this.praisePlus.bind(this)
-
- this.onGamePassed = this.onGamePassed.bind(this)
-
- this.onPathChange = this.onPathChange.bind(this)
-
- this.showSnackbar = this.showSnackbar.bind(this)
- this.showDialog = this.showDialog.bind(this)
-
- this.onShowUpdateDialog = this.onShowUpdateDialog.bind(this)
- this.updateDialogClose = this.updateDialogClose.bind(this)
-
- // this.showEffectDisplay();
-
- this.state = {
- loading: true, // 正在加载数据
- gDialogOpen: false,
- currentGamePassed: false, // 当前game评测通过
- currentPassedGameGainGold: 0, // 当前通过的game获得的金币数
- currentPassedGameGainExperience: 0, // 当前通过的game获得的经验数
-
- user: {},
- challenge: {},
- shixun_name: '',
- hide_code: false,
-
- showUpdateDialog: false,
-
- testSetsExpandedArray: testSetsExpandedArrayInitVal.slice(0),
- }
- }
-
- showEffectDisplay = (data) => {
- const dom = document.getElementById('picture_display');
- window.$(dom).show();
- ReactDOM.render(, dom);
- }
-
- onShowUpdateDialog() {
- this.setState({showUpdateDialog: true})
- }
- // updateNowSuccess true 立即更新成功
- // TODO updateDialogClose方法名不对, 改为updateDialogCallback
- updateDialogClose(nextUpdateSuccess, updateNowSuccess) {
- const { myshixun } = this.state;
- if (nextUpdateSuccess) {
- myshixun.system_tip = true;
- }
- let { tpm_cases_modified, tpm_modified, tpm_script_modified } = this.state;
- if (updateNowSuccess) {
- tpm_cases_modified = false;
- tpm_modified = false;
- tpm_script_modified = false;
- }
- this.setState({
- myshixun,
- tpm_cases_modified,
- tpm_modified,
- tpm_script_modified,
- showUpdateDialog: false
- })
- }
-
- componentWillUnmount() {
- this.costTimeInterval && window.clearInterval(this.costTimeInterval)
- }
- componentDidMount() {
-
- // TODO 登录状态的判断?
- // request
- // var shixunId = this.props.match.params.shixunId;
- var stageId = this.props.match.params.stageId;
-
- window.__fetchAllFlag = false;
- this.fetchAll(stageId);
-
- this.costTimeInterval = window.setInterval(()=> {
- const { game } = this.state;
- if (!game || game.status === 2) { // 已完成的任务不需要计时
- return;
- }
- if (game.cost_time || game.cost_time === 0) {
- // game.cost_time += 1;
- this.setState({
- game: update(game, {cost_time: { $set: (game.cost_time+1) }})
- })
- }
- }, 1000)
-
- // 页面离开时存下用户的任务耗时
-
- window.$(window).unload( ()=>{
- this._updateCostTime();
- });
- }
- // force 评测通过后,异步执行该方法,强制同步costTime到服务端
- _updateCostTime(async = false, force) {
- const { game, loading } = this.state;
- // TODO 还有一种情况,通关后cost_time计时停止,没法通过这个判断
- if (!force && (loading || !game || game.status === 2)) {
- return; // 已完成的任务不需要处理
- }
- let testPath = ''
- if (window.location.port == 3007) {
- testPath = 'https://testeduplus2.educoder.net'
- }
- // var url = `${testPath}/api/v1/games/${ game.identifier }/cost_time`
- var url = `${testPath}/api/tasks/${ game.identifier }/cost_time`
- window.$.ajax({
- type: 'get',
- url: url,
- async: async, //IMPORTANT, the call will be synchronous
- data: {
- time: game.cost_time
- }
- }).done((data) => {
- console.log('complete');
- });
- }
-
- onGamePassed(passed) {
- const { game } = this.state
- // 随便给个分,以免重新评测时又出现评星组件(注意:目前game.star没有显示在界面上,如果有则不能这么做)
- // game.star = 6;
- this.setState({
- game: update(game, {star: { $set: 6 }}),
- currentGamePassed: !!passed
- })
- }
- onTestSetHeaderClick(index) {
- // let { testSetsExpandedArray } = this.state;
- let testSetsExpandedArray;
- // 一次只打开一个
- if (this.state.testSetsExpandedArray[index] === false) {
- testSetsExpandedArray = testSetsExpandedArrayInitVal.slice(0);
- } else {
- testSetsExpandedArray = this.state.testSetsExpandedArray.slice(0);
- }
- testSetsExpandedArray[index] = !testSetsExpandedArray[index];
- this.setState({
- testSetsExpandedArray,
- })
- }
-
- onShowPrevStage() {
-
- }
- onShowNextStage() {
- window.__fetchAllFlag = false;
- console.log('onShowNextStage.........')
- // this.fetchAll('vznhx7mctwfq')
- }
-
- componentWillReceiveProps(newProps, oldProps) {
- var newStageId = newProps.match.params.stageId;
- if (!this.props || newStageId !== this.props.match.params.stageId) {
- window.__fetchAllFlag = false;
- this.fetchAll(newStageId)
- }
- }
-
-
- // praise_tread/praise_plus?obj_id=569&obj_type=Challenge&horizontal=true&game_praise=true
- /*
- TODO 旧的接口在未登录时的返回值
- //获取登录页面地址
-var signinPath = '/';
-var htmlvalue = '
';
-pop_box_new(htmlvalue, 480, 182);
- */
- praisePlus() {
- const { challenge, game } = this.state;
- let praise = true;
- const url = `/tasks/${game.identifier}/plus_or_cancel_praise.json`
- // const url = `/praise_tread/praise_plus?obj_id=${challenge.id}&obj_type=Challenge&horizontal=${praise}&game_praise=true`
- axios.post(url)
- .then((response) => {
-
- if (response.data) {
- const { praise_count, praise } = response.data;
- // challenge.praise_count = praise_tread_count;
- // challenge.user_praise = praise;
- this.setState({ challenge: update(challenge,
- {
- praise_count: { $set: praise_count },
- user_praise: { $set: praise },
- })
- })
- }
-
- })
- .catch(function (error) {
- console.log(error);
- });
- }
-
- onPathChange(index) {
- let { challenge } = this.state;
- // challenge = Object.assign({}, challenge)
- // challenge.pathIndex = index;
- this.setState({
- challenge: update(challenge, {pathIndex: { $set: index }}),
- })
- // TODO load new path content
- }
-
- updateChallengePath = (path) => {
- const challenge = this.state.challenge;
- if (challenge.path === path) {
- return;
- }
- const { myshixun } = this.state;
- // myshixun.system_tip = false;
-
-
- challenge.path = path;
- const newChallenge = this.handleChallengePath(challenge);
- this.setState({ challenge: newChallenge,
- myshixun: update(myshixun, {system_tip: { $set: false }}),
- })
- }
-
- handleChallengePath(challenge) {
- if (challenge.path && typeof challenge.path === "string") { // 多path的处理
- let path = challenge.path.split(';');
- _.remove(path, (item)=> !item)
- if (path.length > 1) {
- challenge.path = path;
- challenge.multiPath = true;
- } else {
- challenge.path = challenge.path.replace(';', '').trim() // 多path 改为单path 出现了 aaa.java;的情况
- challenge.multiPath = false;
- }
- }
- challenge.pathIndex = 0;
- return challenge;
- }
-
- newResData2OldResData(newResData) {
- newResData.latest_output = newResData.last_compile_output
- // newResData.power
- newResData.record = newResData.record_onsume_time
-
- // 老版用的hide_code
- newResData.hide_code = newResData.shixun.hide_code;
-
- newResData.image_url = newResData.user.image_url
- newResData.grade = newResData.user.grade
- newResData.user_url = newResData.user.user_url
- newResData.username = newResData.user.name
-
- newResData.output_sets = {}
- // newResData.output_sets.had_test_count = newResData.test_sets_count
- newResData.output_sets.test_sets = newResData.test_sets // JSON.stringify()
- newResData.output_sets.test_sets_count = newResData.test_sets_count
- // newResData.output_sets.had_passed_testsests_error_count = newResData.sets_error_count
- newResData.output_sets.had_passed_testsests_error_count = newResData.test_sets_count
- - newResData.sets_error_count
- // allowed_hidden_testset
- // sets_error_count
- // test_sets_count
- // test_sets
- // had_passed_testsests_error_count
- // test_sets
- // test_sets
-
- return newResData
- }
- // 将若干数据重新组织一下
- _handleResponseData(resData_arg) {
- const resData = this.newResData2OldResData(Object.assign({}, resData_arg))
- let challenge = resData.challenge;
- challenge.isHtml = false;
- challenge.isWeb = false;
- challenge.isAndroid = false;
- challenge.showLanguagePictrue = false;
- challenge.hasAnswer = resData.has_answer;
-
- let output_sets = resData.output_sets;
- if (resData.st === 0) { // 代码题
- challenge = this.handleChallengePath(challenge)
-
- const mirror_name = (resData.mirror_name && resData.mirror_name.join)
- ? resData.mirror_name.join(';') : (resData.mirror_name || '');
- if (mirror_name.indexOf('Html') !== -1) {
- challenge.isHtml = true;
- challenge.showLanguagePictrue = true;
- } else if (mirror_name.indexOf('Web') !== -1 || mirror_name.indexOf('JFinal') !== -1) {
- challenge.isWeb = true;
- } else if (mirror_name.indexOf('Android') !== -1) {
- challenge.isAndroid = true;
- }
-
- if (output_sets && output_sets.test_sets && typeof output_sets.test_sets == 'string') {
- const test_sets_array = JSON.parse("[" + output_sets.test_sets + "]");
- output_sets.test_sets_array = test_sets_array;
- } else {
- output_sets.test_sets_array = output_sets.test_sets
- }
-
- } else { // 选择题
- // 选择题题干markdown初始化
- const $ = window.$
- window.setTimeout(()=>{
- var lens = $("#choiceRepositoryView textarea").length;
-
- for(var i = 1; i <= lens; i++){
- window.editormd.markdownToHTML("choose_subject_" + i, {
- htmlDecode: "style,script,iframe", // you can filter tags decode
- taskList: true,
- tex: true, // 数学公式
- // flowChart: true, // 默认不解析
- // sequenceDiagram: true // 默认不解析
- });
- }
- }, 400)
- }
- challenge.user_praise = resData.user_praise;
- challenge.praise_count = resData.praise_count;
- challenge.showWebDisplayButton = false;
- resData.challenge = challenge;
-
- // 将一些属性写到game上
- let game = resData.game;
- game.prev_game = resData.prev_game;
- game.next_game = resData.next_game;
- resData.game = game;
-
- const { tpm_cases_modified, tpm_modified, tpm_script_modified, myshixun } = resData;
- if (myshixun.system_tip) {
- // system_tip为true的时候 不弹框提示用户更新
- resData.showUpdateDialog = false
- } else {
- let needUpdateScript = (tpm_modified || tpm_script_modified) && challenge.st === 0;
- resData.showUpdateDialog = needUpdateScript || tpm_cases_modified
- }
-
- /**
- email: "721773699@qq.com"
- grade: 213996
- identity: 1
- image_url: "avatars/User/1"
- login: "innov"
- name: "Coder"
- user_url: "/users/innov"
- */
- let user = resData.user;
- user.username = resData.user.name;
- user.user_url = `/user/${resData.user.login}`;
- // user.image_url = resData.image_url;
- user.is_teacher = resData.is_teacher;
- resData.user = user;
- this._handleUserAuthor(resData)
- // TODO 测试
- // resData.power = 0;
-
- this.setState({
- ...resData,
-
- currentGamePassed: false,
- loading: false,
- testSetsExpandedArray: testSetsExpandedArrayInitVal.slice(0),
- })
-
- window.document.title = resData.shixun.name
-
- window.__myshixun = resData.myshixun; // tpi_html_show需要用到
- }
- _handleUserAuthor(resData) {
- // tpi tpm权限控制
- // const EDU_ADMIN = 1 // 超级管理员
- // const EDU_SHIXUN_MANAGER = 2 // 实训管理员
- // const EDU_SHIXUN_MEMBER = 3 // 实训成员
- // const EDU_CERTIFICATION_TEACHER = 4 // 平台认证的老师
- // const EDU_GAME_MANAGER = 5 // TPI的创建者
- // const EDU_TEACHER = 6 // 平台老师,但是未认证
- // const EDU_NORMAL = 7 // 普通用户
-
- // myshixun_manager power is_teacher
- resData.power = 0
- resData.myshixun_manager = false
- resData.is_teacher = false
-
- if (resData.user.identity === EDU_ADMIN) {
- resData.power = 1
- resData.myshixun_manager = true
- } else if (resData.user.identity === EDU_SHIXUN_MANAGER) {
- resData.power = 1
- resData.myshixun_manager = true
- } else if (resData.user.identity === EDU_SHIXUN_MEMBER) {
- resData.power = 1
- resData.myshixun_manager = true
- } else if (resData.user.identity === EDU_CERTIFICATION_TEACHER) {
- resData.power = 1
- resData.is_teacher = true
-
- } else if (resData.user.identity === EDU_TEACHER) {
- resData.is_teacher = true
- } else if (resData.user.identity === EDU_NORMAL) {
-
- }
- return resData
- }
-
- fetchAll(stageId) {
-
- if (window.__fetchAllFlag == true ) {
- console.log('TPIContextProvider call fetchAll repeatly!')
- return;
- }
- // 切换关卡的时候,同步costTime
- this._updateCostTime(true);
-
- if (!stageId) {
- // stageId = 'zl6kx8f7vfpo';
- // http://localhost:3000/myshixuns/so5w6iap97/stages/zl6kx8f7vfpo
- }
-
- // var url = `/api/v1/games/${stageId}`
- var url = `/tasks/${stageId}.json`
-
- // {"status":1,"message":"undefined method `authenticate!' for #"}
- window.__fetchAllFlag = true;
-
-
- this.setState({
- loading: true,
- currentGamePassed: false, // 切换game时重置passed字段
- })
-
- axios.get(url, {
- // https://stackoverflow.com/questions/48861290/the-value-of-the-access-control-allow-origin-header-in-the-response-must-not-b
- // withCredentials: true,
- })
- .then((response) => {
- // {"status":1,"message":"Unauthorized. \u7528\u6237\u8ba4\u8bc1\u5931\u8d25."}
-
- if (response.data.status == 403) {
- window.location.href = "/403";
- return;
- }
- if (response.data.status == 404) {
- window.location.href = '/myshixuns/not_found'
- return;
- }
-
- this._handleResponseData(response.data)
-
- })
- .catch(function (error) {
- console.log(error);
- });
-
- }
-
- readGameAnswer(resData) {
- // game.final_score = resData.final_score;
- if (resData.final_score) {
- var game = this.state.game;
- this.setState({
- game: update(game, {final_score: { $set: resData.final_score }}),
- grade: resData.grade
- })
- } else {
- this.setState({
- grade: resData.grade
- })
- }
-
- }
- closeTaskResultLayer() {
- this.setState({
- currentGamePassed: false
- })
- }
- onRunChooseTestFinish(response) {
- const { test_sets, challenge_chooses_count, choose_correct_num, grade, experience, gold, had_submmit, next_game } = response;
- response.had_submmit = true; // 是否已提交
- const { game } = this.state;
- let currentGamePassed = false
- if (challenge_chooses_count === choose_correct_num) {
- game.status = 2;
- game.next_game = next_game;
-
- currentGamePassed = true;
-
-
- this._updateCostTime(true, true);
- }
- this.setState({
- choose_test_cases: response,
- grade: grade,
-
- game,
- next_game,
- currentGamePassed: currentGamePassed,
- currentPassedGameGainGold: gold,
- currentPassedGameGainExperience: experience,
- })
- }
- language_display(data) {
- const { game, tomcat_url } = this.state;
- const $ = window.$;
- const challenge = Object.assign({}, this.state.challenge)
- if(challenge.isWeb && data.port != -1) {
- // var $result = $("#php_display");
- challenge.showWebDisplayButton = true; // ActionView处是否出现查看效果按钮
- const path = challenge.web_route || challenge.path
- const webDisplayUrl = `${tomcat_url}:${data.port}/${path}`
- challenge.webDisplayUrl = webDisplayUrl
- challenge.showLanguagePictrue = true; // 评测通过弹出层是否出现查看效果按钮
- }
- // else if(challenge.isAndroid && data.picture != 0){
- // // https://www.educoder.net/shixuns/qrcode?game_id=218589&_=1525571882782
- // $.ajax({
- // url: `/shixuns/qrcode?game_id=${game.id}`,
- // dataType: 'script'
- // });
- // challenge.showLanguagePictrue = true;
- // }
- else if(data.picture != 0){
- // 对应服务端erb文件为 _picture_display.html.erb
- // $.ajax({
- // url: "/users/picture_show?game_id="+data.picture,
- // cache: false,
- // dataType: 'script'
- // });
-
- /**
- {
- "type": "image",
- "orignal_picture": [],
- "user_picture": [],
- "answer_picture": []
- }
- */
- const url = `/tasks/${game.identifier}/picture_display.json`
- axios.get(url)
- .then((response) => {
- // response.data.type qrcode_str
- this.showEffectDisplay(response.data)
- })
-
- challenge.showLanguagePictrue = true;
- }
- this.setState({
- challenge
- })
- }
- onRunCodeTestFinish(response) {
- console.log('onRunCodeTestFinish', response)
- const { test_sets, test_sets_count, test_sets_hidden_count, test_sets_public_count
- , had_test_count, had_passed_testsests_error_count, had_passed_testsests_hidden_count
- , had_passed_testsests_public_count, final_score, gold, experience, latest_output, status
- , had_done, score, tag_count, power, record, next_game, grade, picture,
- sets_error_count, last_compile_output, record_consume_time} = response;
-
- const { game } = this.state;
-
- const currentGamePassed = this.props.game !== 2 && status === 2
-
- currentGamePassed && this.language_display(response);
-
- // 评测通过了,立即同步costTime
- currentGamePassed && this._updateCostTime(true, true);
-
- if (currentGamePassed) {
- game.status = 2;
- game.next_game = next_game;
-
- } else {
- this.showDialog({
- contentText: ,
- isSingleButton: true
- })
- }
-
- const output_sets = {
- "test_sets": test_sets,
- "test_sets_array": test_sets,
- "had_test_count": had_test_count || test_sets_count,
- "test_sets_count": test_sets_count,
- // "had_passed_testsests_error_count": had_passed_testsests_error_count,
- "had_passed_testsests_error_count": test_sets_count - sets_error_count,
- "test_sets_hidden_count": test_sets_hidden_count,
- "test_sets_public_count": test_sets_public_count,
- "had_passed_testsests_hidden_count": had_passed_testsests_hidden_count,
- "had_passed_testsests_public_count": had_passed_testsests_public_count
- };
- // if (output_sets && output_sets.test_sets) {
- // const test_sets_array = JSON.parse("[" + output_sets.test_sets + "]");
- // output_sets.test_sets_array = test_sets_array;
- // }
-
-
- this.setState({
- testSetsExpandedArray: testSetsExpandedArrayInitVal.slice(0), // 重置测试集展开状态
- currentGamePassed,
- currentPassedGameGainGold: gold,
- currentPassedGameGainExperience: experience,
-
- output_sets,
- game,
- next_game,
-
- latest_output: last_compile_output,
- record: record_consume_time,
- grade,
- had_done,
-
- })
- }
- resetTestSetsExpandedArray = () => {
- this.setState({
- testSetsExpandedArray: testSetsExpandedArrayInitVal.slice(0), // 重置测试集展开状态
- })
- }
-
- testSetUnlock() {
- const { game } = this.state;
- const url = `/v1/games/${game.identifier}/check_test_sets.json`
- axios.get(url, {
- withCredentials: true,
- })
- .then((response) => {
- // TODO status -2 重复操作,直接解锁
- if (response.data.test_sets == -1) {
- console.error('testSetUnlock失败!')
- this.showSnackbar(response.data.message)
- return;
- } else {
- // 被扣除的金币,是负数
- const deltaScore = response.data.score;
- // output_sets
- let { output_sets } = this.state;
- output_sets = Object.assign({}, output_sets);
- const test_sets_array = JSON.parse("[" + response.data.test_sets + "]");
- output_sets.test_sets_array = test_sets_array;
- this.setState({
- output_sets: output_sets,
- grade: this.state.grade + deltaScore,
- game : update(game, {test_sets_view: { $set: true }}),
- testSetsExpandedArray: testSetsExpandedArrayInitVal.slice(0)
- })
- this.handleGdialogClose();
- }
-
- })
- .catch(function (error) {
- console.log(error);
- });
- }
-
- handleSnackbarClose() {
- this.setState({
- snackbarOpen: false,
- snackbarVertical: '',
- snackbarHorizontal: '',
- })
- }
- // 全局的snackbar this.props.showSnackbar调用即可
- showSnackbar(text, vertical, horizontal) {
- this.setState({
- snackbarOpen: true,
- snackbarText: text,
- snackbarVertical: vertical,
- snackbarHorizontal: horizontal,
- })
- }
-
- /*
- TODO 写成HOC组件,更好复用
- 全局的Dialog this.props.showDialog调用即可
- @param contentText dialog显示的提示文本
- @param callback 确定按钮回调方法
- @param moreButtonsRender 除了“确定”、“取消”按钮外的其他按钮
- @param okButtonText “确定”按钮显示文本,如 继续查看
- */
- showDialog(params) {
- const { contentText, callback, moreButtonsRender, okButtonText, isSingleButton } = params;
-
- this.dialogOkCallback = callback;
- this.moreButtonsRender = moreButtonsRender
- this.okButtonText = okButtonText;
- this.isSingleButton = isSingleButton;
- this.setState({
- gDialogOpen: true,
- gDialogContentText: contentText
- })
- }
- onGdialogOkBtnClick() {
-
- this.dialogOkCallback && this.dialogOkCallback();
- // this.setState({
- // gDialogOpen: true
- // })
- }
- handleGdialogClose = () => {
- this.setState({
- gDialogOpen: false
- })
- }
- render() {
- const { classes } = this.props;
- return (
- this.closeTaskResultLayer(),
-
- onPathChange: this.onPathChange,
- updateChallengePath: this.updateChallengePath,
-
- showSnackbar: this.showSnackbar,
- showDialog: this.showDialog,
- handleGdialogClose: () => this.handleGdialogClose(),
-
- onShowUpdateDialog: this.onShowUpdateDialog,
- updateDialogClose: this.updateDialogClose,
-
- match: this.props.match
- }}
- >
-
-
- this.handleSnackbarClose()}
- transition={Fade}
- SnackbarContentProps={{
- 'aria-describedby': 'message-id',
- }}
- resumeHideDuration={2000}
- message={{this.state.snackbarText}}
- />
- {this.props.children}
-
- )
- }
-}
-
-export default withStyles(styles) (TPIContextProvider);
-
-
-
+import React, { Component } from 'react';
+import ReactDOM from 'react-dom';
+
+import axios from 'axios';
+import Snackbar from 'material-ui/Snackbar';
+import Fade from 'material-ui/transitions/Fade';
+
+import update from 'immutability-helper'
+
+import Dialog, {
+ DialogActions,
+ DialogContent,
+ DialogContentText,
+ DialogTitle,
+} from 'material-ui/Dialog';
+
+import Button from 'material-ui/Button';
+
+import EvaluateSuccessEffectDisplay from './EvaluateSuccessEffectDisplay'
+
+import _ from 'lodash'
+
+/*
+ 若干js库
+ http://inorganik.github.io/countUp.js/
+
+*/
+/*
+ 切下一关需要更新:
+ LeftViewContainer state.gameAnswer
+*/
+
+import TPIContext from './TPIContext'
+import { EDU_ADMIN, EDU_SHIXUN_MANAGER, EDU_SHIXUN_MEMBER, EDU_CERTIFICATION_TEACHER
+ , EDU_GAME_MANAGER, EDU_TEACHER, EDU_NORMAL} from 'educoder'
+import { MuiThemeProvider, createMuiTheme, withStyles } from 'material-ui/styles';
+import MUIDialogStyleUtil from '../modules/page/component/MUIDialogStyleUtil'
+
+const styles = MUIDialogStyleUtil.getTwoButtonStyle()
+
+// 主题自定义
+const theme = createMuiTheme({
+ palette: {
+ primary: {
+ main: '#4CACFF',
+ contrastText: 'rgba(255, 255, 255, 0.87)'
+ },
+ secondary: { main: '#4CACFF' }, // This is just green.A700 as hex.
+ },
+});
+
+const testSetsExpandedArrayInitVal = [false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false,
+ false, false, false, false, false]
+window.__fetchAllFlag = false; // 是否调用过fetchAll TODO 如何多次使用provider?
+class TPIContextProvider extends Component {
+ constructor(props) {
+ super(props)
+ this.onRunCodeTestFinish = this.onRunCodeTestFinish.bind(this)
+ this.onRunChooseTestFinish = this.onRunChooseTestFinish.bind(this)
+ this.testSetUnlock = this.testSetUnlock.bind(this)
+
+ this.onTestSetHeaderClick = this.onTestSetHeaderClick.bind(this)
+
+ this.onShowPrevStage = this.onShowPrevStage.bind(this)
+ this.onShowNextStage = this.onShowNextStage.bind(this)
+
+ this.readGameAnswer = this.readGameAnswer.bind(this)
+ this.praisePlus = this.praisePlus.bind(this)
+
+ this.onGamePassed = this.onGamePassed.bind(this)
+
+ this.onPathChange = this.onPathChange.bind(this)
+
+ this.showSnackbar = this.showSnackbar.bind(this)
+ this.showDialog = this.showDialog.bind(this)
+
+ this.onShowUpdateDialog = this.onShowUpdateDialog.bind(this)
+ this.updateDialogClose = this.updateDialogClose.bind(this)
+
+ // this.showEffectDisplay();
+
+ this.state = {
+ loading: true, // 正在加载数据
+ gDialogOpen: false,
+ currentGamePassed: false, // 当前game评测通过
+ currentPassedGameGainGold: 0, // 当前通过的game获得的金币数
+ currentPassedGameGainExperience: 0, // 当前通过的game获得的经验数
+
+ user: {},
+ challenge: {},
+ shixun_name: '',
+ hide_code: false,
+
+ showUpdateDialog: false,
+
+ testSetsExpandedArray: testSetsExpandedArrayInitVal.slice(0),
+ }
+ }
+
+ showEffectDisplay = (data) => {
+ const dom = document.getElementById('picture_display');
+ window.$(dom).show();
+ ReactDOM.render(, dom);
+ }
+
+ onShowUpdateDialog() {
+ this.setState({showUpdateDialog: true})
+ }
+ // updateNowSuccess true 立即更新成功
+ // TODO updateDialogClose方法名不对, 改为updateDialogCallback
+ updateDialogClose(nextUpdateSuccess, updateNowSuccess) {
+ const { myshixun } = this.state;
+ if (nextUpdateSuccess) {
+ myshixun.system_tip = true;
+ }
+ let { tpm_cases_modified, tpm_modified, tpm_script_modified } = this.state;
+ if (updateNowSuccess) {
+ tpm_cases_modified = false;
+ tpm_modified = false;
+ tpm_script_modified = false;
+ }
+ this.setState({
+ myshixun,
+ tpm_cases_modified,
+ tpm_modified,
+ tpm_script_modified,
+ showUpdateDialog: false
+ })
+ }
+
+ componentWillUnmount() {
+ this.costTimeInterval && window.clearInterval(this.costTimeInterval)
+ }
+ componentDidMount() {
+
+ // TODO 登录状态的判断?
+ // request
+ // var shixunId = this.props.match.params.shixunId;
+ var stageId = this.props.match.params.stageId;
+
+ window.__fetchAllFlag = false;
+ this.fetchAll(stageId);
+
+ this.costTimeInterval = window.setInterval(()=> {
+ const { game } = this.state;
+ if (!game || game.status === 2) { // 已完成的任务不需要计时
+ return;
+ }
+ if (game.cost_time || game.cost_time === 0) {
+ // game.cost_time += 1;
+ this.setState({
+ game: update(game, {cost_time: { $set: (game.cost_time+1) }})
+ })
+ }
+ }, 1000)
+
+ // 页面离开时存下用户的任务耗时
+
+ window.$(window).unload( ()=>{
+ this._updateCostTime();
+ });
+ }
+ // force 评测通过后,异步执行该方法,强制同步costTime到服务端
+ _updateCostTime(async = false, force) {
+ const { game, loading } = this.state;
+ // TODO 还有一种情况,通关后cost_time计时停止,没法通过这个判断
+ if (!force && (loading || !game || game.status === 2)) {
+ return; // 已完成的任务不需要处理
+ }
+ let testPath = ''
+ if (window.location.port == 3007) {
+ testPath = 'https://testeduplus2.educoder.net'
+ }
+ // var url = `${testPath}/api/v1/games/${ game.identifier }/cost_time`
+ var url = `${testPath}/api/tasks/${ game.identifier }/cost_time`
+ window.$.ajax({
+ type: 'get',
+ url: url,
+ async: async, //IMPORTANT, the call will be synchronous
+ data: {
+ time: game.cost_time
+ }
+ }).done((data) => {
+ console.log('complete');
+ });
+ }
+
+ onGamePassed(passed) {
+ const { game } = this.state
+ // 随便给个分,以免重新评测时又出现评星组件(注意:目前game.star没有显示在界面上,如果有则不能这么做)
+ // game.star = 6;
+ this.setState({
+ game: update(game, {star: { $set: 6 }}),
+ currentGamePassed: !!passed
+ })
+ }
+ onTestSetHeaderClick(index) {
+ // let { testSetsExpandedArray } = this.state;
+ let testSetsExpandedArray;
+ // 一次只打开一个
+ if (this.state.testSetsExpandedArray[index] === false) {
+ testSetsExpandedArray = testSetsExpandedArrayInitVal.slice(0);
+ } else {
+ testSetsExpandedArray = this.state.testSetsExpandedArray.slice(0);
+ }
+ testSetsExpandedArray[index] = !testSetsExpandedArray[index];
+ this.setState({
+ testSetsExpandedArray,
+ })
+ }
+
+ onShowPrevStage() {
+
+ }
+ onShowNextStage() {
+ window.__fetchAllFlag = false;
+ console.log('onShowNextStage.........')
+ // this.fetchAll('vznhx7mctwfq')
+ }
+
+ componentWillReceiveProps(newProps, oldProps) {
+ var newStageId = newProps.match.params.stageId;
+ if (!this.props || newStageId !== this.props.match.params.stageId) {
+ window.__fetchAllFlag = false;
+ this.fetchAll(newStageId)
+ }
+ }
+
+
+ // praise_tread/praise_plus?obj_id=569&obj_type=Challenge&horizontal=true&game_praise=true
+ /*
+ TODO 旧的接口在未登录时的返回值
+ //获取登录页面地址
+var signinPath = '/';
+var htmlvalue = '';
+pop_box_new(htmlvalue, 480, 182);
+ */
+ praisePlus() {
+ const { challenge, game } = this.state;
+ let praise = true;
+ const url = `/tasks/${game.identifier}/plus_or_cancel_praise.json`
+ // const url = `/praise_tread/praise_plus?obj_id=${challenge.id}&obj_type=Challenge&horizontal=${praise}&game_praise=true`
+ axios.post(url)
+ .then((response) => {
+
+ if (response.data) {
+ const { praise_count, praise } = response.data;
+ // challenge.praise_count = praise_tread_count;
+ // challenge.user_praise = praise;
+ this.setState({ challenge: update(challenge,
+ {
+ praise_count: { $set: praise_count },
+ user_praise: { $set: praise },
+ })
+ })
+ }
+
+ })
+ .catch(function (error) {
+ console.log(error);
+ });
+ }
+
+ onPathChange(index) {
+ let { challenge } = this.state;
+ // challenge = Object.assign({}, challenge)
+ // challenge.pathIndex = index;
+ this.setState({
+ challenge: update(challenge, {pathIndex: { $set: index }}),
+ })
+ // TODO load new path content
+ }
+
+ updateChallengePath = (path) => {
+ const challenge = this.state.challenge;
+ if (challenge.path === path) {
+ return;
+ }
+ const { myshixun } = this.state;
+ // myshixun.system_tip = false;
+
+
+ challenge.path = path;
+ const newChallenge = this.handleChallengePath(challenge);
+ this.setState({ challenge: newChallenge,
+ myshixun: update(myshixun, {system_tip: { $set: false }}),
+ })
+ }
+
+ handleChallengePath(challenge) {
+ if (challenge.path && typeof challenge.path === "string") { // 多path的处理
+ let path = challenge.path.split(';');
+ _.remove(path, (item)=> !item)
+ if (path.length > 1) {
+ challenge.path = path;
+ challenge.multiPath = true;
+ } else {
+ challenge.path = challenge.path.replace(';', '').trim() // 多path 改为单path 出现了 aaa.java;的情况
+ challenge.multiPath = false;
+ }
+ }
+ challenge.pathIndex = 0;
+ return challenge;
+ }
+
+ newResData2OldResData(newResData) {
+ newResData.latest_output = newResData.last_compile_output
+ // newResData.power
+ newResData.record = newResData.record_onsume_time
+
+ // 老版用的hide_code
+ newResData.hide_code = newResData.shixun.hide_code;
+
+ newResData.image_url = newResData.user.image_url
+ newResData.grade = newResData.user.grade
+ newResData.user_url = newResData.user.user_url
+ newResData.username = newResData.user.name
+
+ newResData.output_sets = {}
+ // newResData.output_sets.had_test_count = newResData.test_sets_count
+ newResData.output_sets.test_sets = newResData.test_sets // JSON.stringify()
+ newResData.output_sets.test_sets_count = newResData.test_sets_count
+ // newResData.output_sets.had_passed_testsests_error_count = newResData.sets_error_count
+ newResData.output_sets.had_passed_testsests_error_count = newResData.test_sets_count
+ - newResData.sets_error_count
+ // allowed_hidden_testset
+ // sets_error_count
+ // test_sets_count
+ // test_sets
+ // had_passed_testsests_error_count
+ // test_sets
+ // test_sets
+
+ return newResData
+ }
+ // 将若干数据重新组织一下
+ _handleResponseData(resData_arg) {
+ const resData = this.newResData2OldResData(Object.assign({}, resData_arg))
+ let challenge = resData.challenge;
+ challenge.isHtml = false;
+ challenge.isWeb = false;
+ challenge.isAndroid = false;
+ challenge.showLanguagePictrue = false;
+ challenge.hasAnswer = resData.has_answer;
+
+ let output_sets = resData.output_sets;
+ if (resData.st === 0) { // 代码题
+ challenge = this.handleChallengePath(challenge)
+
+ const mirror_name = (resData.mirror_name && resData.mirror_name.join)
+ ? resData.mirror_name.join(';') : (resData.mirror_name || '');
+ if (mirror_name.indexOf('Html') !== -1) {
+ challenge.isHtml = true;
+ challenge.showLanguagePictrue = true;
+ } else if (mirror_name.indexOf('Web') !== -1 || mirror_name.indexOf('JFinal') !== -1) {
+ challenge.isWeb = true;
+ } else if (mirror_name.indexOf('Android') !== -1) {
+ challenge.isAndroid = true;
+ }
+
+ if (output_sets && output_sets.test_sets && typeof output_sets.test_sets == 'string') {
+ const test_sets_array = JSON.parse("[" + output_sets.test_sets + "]");
+ output_sets.test_sets_array = test_sets_array;
+ } else {
+ output_sets.test_sets_array = output_sets.test_sets
+ }
+
+ } else { // 选择题
+ // 选择题题干markdown初始化
+ const $ = window.$
+ window.setTimeout(()=>{
+ var lens = $("#choiceRepositoryView textarea").length;
+
+ for(var i = 1; i <= lens; i++){
+ window.editormd.markdownToHTML("choose_subject_" + i, {
+ htmlDecode: "style,script,iframe", // you can filter tags decode
+ taskList: true,
+ tex: true, // 数学公式
+ // flowChart: true, // 默认不解析
+ // sequenceDiagram: true // 默认不解析
+ });
+ }
+ }, 400)
+ }
+ challenge.user_praise = resData.user_praise;
+ challenge.praise_count = resData.praise_count;
+ challenge.showWebDisplayButton = false;
+ resData.challenge = challenge;
+
+ // 将一些属性写到game上
+ let game = resData.game;
+ game.prev_game = resData.prev_game;
+ game.next_game = resData.next_game;
+ resData.game = game;
+
+ const { tpm_cases_modified, tpm_modified, tpm_script_modified, myshixun } = resData;
+ if (myshixun.system_tip) {
+ // system_tip为true的时候 不弹框提示用户更新
+ resData.showUpdateDialog = false
+ } else {
+ let needUpdateScript = (tpm_modified || tpm_script_modified) && challenge.st === 0;
+ resData.showUpdateDialog = needUpdateScript || tpm_cases_modified
+ }
+
+ /**
+ email: "721773699@qq.com"
+ grade: 213996
+ identity: 1
+ image_url: "avatars/User/1"
+ login: "innov"
+ name: "Coder"
+ user_url: "/users/innov"
+ */
+ let user = resData.user;
+ user.username = resData.user.name;
+ user.user_url = `/user/${resData.user.login}`;
+ // user.image_url = resData.image_url;
+ user.is_teacher = resData.is_teacher;
+ resData.user = user;
+ this._handleUserAuthor(resData)
+ // TODO 测试
+ // resData.power = 0;
+
+ this.setState({
+ ...resData,
+
+ currentGamePassed: false,
+ loading: false,
+ testSetsExpandedArray: testSetsExpandedArrayInitVal.slice(0),
+ })
+
+ window.document.title = resData.shixun.name
+
+ window.__myshixun = resData.myshixun; // tpi_html_show需要用到
+ }
+ _handleUserAuthor(resData) {
+ // tpi tpm权限控制
+ // const EDU_ADMIN = 1 // 超级管理员
+ // const EDU_SHIXUN_MANAGER = 2 // 实训管理员
+ // const EDU_SHIXUN_MEMBER = 3 // 实训成员
+ // const EDU_CERTIFICATION_TEACHER = 4 // 平台认证的老师
+ // const EDU_GAME_MANAGER = 5 // TPI的创建者
+ // const EDU_TEACHER = 6 // 平台老师,但是未认证
+ // const EDU_NORMAL = 7 // 普通用户
+
+ // myshixun_manager power is_teacher
+ resData.power = 0
+ resData.myshixun_manager = false
+ resData.is_teacher = false
+
+ if (resData.user.identity === EDU_ADMIN) {
+ resData.power = 1
+ resData.myshixun_manager = true
+ } else if (resData.user.identity === EDU_SHIXUN_MANAGER) {
+ resData.power = 1
+ resData.myshixun_manager = true
+ } else if (resData.user.identity === EDU_SHIXUN_MEMBER) {
+ resData.power = 1
+ resData.myshixun_manager = true
+ } else if (resData.user.identity === EDU_CERTIFICATION_TEACHER) {
+ resData.power = 1
+ resData.is_teacher = true
+
+ } else if (resData.user.identity === EDU_TEACHER) {
+ resData.is_teacher = true
+ } else if (resData.user.identity === EDU_NORMAL) {
+
+ }
+ return resData
+ }
+
+ fetchAll(stageId) {
+
+ if (window.__fetchAllFlag == true ) {
+ console.log('TPIContextProvider call fetchAll repeatly!')
+ return;
+ }
+ // 切换关卡的时候,同步costTime
+ this._updateCostTime(true);
+
+ if (!stageId) {
+ // stageId = 'zl6kx8f7vfpo';
+ // http://localhost:3000/myshixuns/so5w6iap97/stages/zl6kx8f7vfpo
+ }
+
+ // var url = `/api/v1/games/${stageId}`
+ var url = `/tasks/${stageId}.json`
+
+ // {"status":1,"message":"undefined method `authenticate!' for #"}
+ window.__fetchAllFlag = true;
+
+
+ this.setState({
+ loading: true,
+ currentGamePassed: false, // 切换game时重置passed字段
+ })
+
+ axios.get(url, {
+ // https://stackoverflow.com/questions/48861290/the-value-of-the-access-control-allow-origin-header-in-the-response-must-not-b
+ // withCredentials: true,
+ })
+ .then((response) => {
+ // {"status":1,"message":"Unauthorized. \u7528\u6237\u8ba4\u8bc1\u5931\u8d25."}
+
+ if (response.data.status == 403) {
+ window.location.href = "/403";
+ return;
+ }
+ if (response.data.status == 404) {
+ window.location.href = '/myshixuns/not_found'
+ return;
+ }
+
+ this._handleResponseData(response.data)
+
+ })
+ .catch(function (error) {
+ console.log(error);
+ });
+
+ }
+
+ readGameAnswer(resData) {
+ // game.final_score = resData.final_score;
+ if (resData.final_score) {
+ var game = this.state.game;
+ this.setState({
+ game: update(game, {final_score: { $set: resData.final_score }}),
+ grade: resData.grade
+ })
+ } else {
+ this.setState({
+ grade: resData.grade
+ })
+ }
+
+ }
+ closeTaskResultLayer() {
+ this.setState({
+ currentGamePassed: false
+ })
+ }
+ onRunChooseTestFinish(response) {
+ const { test_sets, challenge_chooses_count, choose_correct_num, grade, experience, gold, had_submmit, next_game } = response;
+ response.had_submmit = true; // 是否已提交
+ const { game } = this.state;
+ let currentGamePassed = false
+ if (challenge_chooses_count === choose_correct_num) {
+ game.status = 2;
+ game.next_game = next_game;
+
+ currentGamePassed = true;
+
+
+ this._updateCostTime(true, true);
+ }
+ this.setState({
+ choose_test_cases: response,
+ grade: grade,
+
+ game,
+ next_game,
+ currentGamePassed: currentGamePassed,
+ currentPassedGameGainGold: gold,
+ currentPassedGameGainExperience: experience,
+ })
+ }
+ language_display(data) {
+ const { game, tomcat_url } = this.state;
+ const $ = window.$;
+ const challenge = Object.assign({}, this.state.challenge)
+ if(challenge.isWeb && data.port != -1) {
+ // var $result = $("#php_display");
+ challenge.showWebDisplayButton = true; // ActionView处是否出现查看效果按钮
+ const path = challenge.web_route || challenge.path
+ const webDisplayUrl = `${tomcat_url}:${data.port}/${path}`
+ challenge.webDisplayUrl = webDisplayUrl
+ challenge.showLanguagePictrue = true; // 评测通过弹出层是否出现查看效果按钮
+ }
+ // else if(challenge.isAndroid && data.picture != 0){
+ // // https://www.educoder.net/shixuns/qrcode?game_id=218589&_=1525571882782
+ // $.ajax({
+ // url: `/shixuns/qrcode?game_id=${game.id}`,
+ // dataType: 'script'
+ // });
+ // challenge.showLanguagePictrue = true;
+ // }
+ else if(data.picture != 0){
+ // 对应服务端erb文件为 _picture_display.html.erb
+ // $.ajax({
+ // url: "/users/picture_show?game_id="+data.picture,
+ // cache: false,
+ // dataType: 'script'
+ // });
+
+ /**
+ {
+ "type": "image",
+ "orignal_picture": [],
+ "user_picture": [],
+ "answer_picture": []
+ }
+ */
+ const url = `/tasks/${game.identifier}/picture_display.json`
+ axios.get(url)
+ .then((response) => {
+ // response.data.type qrcode_str
+ this.showEffectDisplay(response.data)
+ })
+
+ challenge.showLanguagePictrue = true;
+ }
+ this.setState({
+ challenge
+ })
+ }
+ onRunCodeTestFinish(response) {
+ console.log('onRunCodeTestFinish', response)
+ const { test_sets, test_sets_count, test_sets_hidden_count, test_sets_public_count
+ , had_test_count, had_passed_testsests_error_count, had_passed_testsests_hidden_count
+ , had_passed_testsests_public_count, final_score, gold, experience, latest_output, status
+ , had_done, score, tag_count, power, record, next_game, grade, picture,
+ sets_error_count, last_compile_output, record_consume_time} = response;
+
+ const { game } = this.state;
+
+ const currentGamePassed = this.props.game !== 2 && status === 2
+
+ currentGamePassed && this.language_display(response);
+
+ // 评测通过了,立即同步costTime
+ currentGamePassed && this._updateCostTime(true, true);
+
+ if (currentGamePassed) {
+ game.status = 2;
+ game.next_game = next_game;
+
+ } else {
+ this.showDialog({
+ contentText: ,
+ isSingleButton: true
+ })
+ }
+
+ const output_sets = {
+ "test_sets": test_sets,
+ "test_sets_array": test_sets,
+ "had_test_count": had_test_count || test_sets_count,
+ "test_sets_count": test_sets_count,
+ // "had_passed_testsests_error_count": had_passed_testsests_error_count,
+ "had_passed_testsests_error_count": test_sets_count - sets_error_count,
+ "test_sets_hidden_count": test_sets_hidden_count,
+ "test_sets_public_count": test_sets_public_count,
+ "had_passed_testsests_hidden_count": had_passed_testsests_hidden_count,
+ "had_passed_testsests_public_count": had_passed_testsests_public_count
+ };
+ // if (output_sets && output_sets.test_sets) {
+ // const test_sets_array = JSON.parse("[" + output_sets.test_sets + "]");
+ // output_sets.test_sets_array = test_sets_array;
+ // }
+
+
+ this.setState({
+ testSetsExpandedArray: testSetsExpandedArrayInitVal.slice(0), // 重置测试集展开状态
+ currentGamePassed,
+ currentPassedGameGainGold: gold,
+ currentPassedGameGainExperience: experience,
+
+ output_sets,
+ game,
+ next_game,
+
+ latest_output: last_compile_output,
+ record: record_consume_time,
+ grade,
+ had_done,
+
+ })
+ }
+ resetTestSetsExpandedArray = () => {
+ this.setState({
+ testSetsExpandedArray: testSetsExpandedArrayInitVal.slice(0), // 重置测试集展开状态
+ })
+ }
+
+ testSetUnlock() {
+ const { game } = this.state;
+ const url = `/v1/games/${game.identifier}/check_test_sets.json`
+ axios.get(url, {
+ withCredentials: true,
+ })
+ .then((response) => {
+ // TODO status -2 重复操作,直接解锁
+ if (response.data.test_sets == -1) {
+ console.error('testSetUnlock失败!')
+ this.showSnackbar(response.data.message)
+ return;
+ } else {
+ // 被扣除的金币,是负数
+ const deltaScore = response.data.score;
+ // output_sets
+ let { output_sets } = this.state;
+ output_sets = Object.assign({}, output_sets);
+ const test_sets_array = JSON.parse("[" + response.data.test_sets + "]");
+ output_sets.test_sets_array = test_sets_array;
+ this.setState({
+ output_sets: output_sets,
+ grade: this.state.grade + deltaScore,
+ game : update(game, {test_sets_view: { $set: true }}),
+ testSetsExpandedArray: testSetsExpandedArrayInitVal.slice(0)
+ })
+ this.handleGdialogClose();
+ }
+
+ })
+ .catch(function (error) {
+ console.log(error);
+ });
+ }
+
+ handleSnackbarClose() {
+ this.setState({
+ snackbarOpen: false,
+ snackbarVertical: '',
+ snackbarHorizontal: '',
+ })
+ }
+ // 全局的snackbar this.props.showSnackbar调用即可
+ showSnackbar(text, vertical, horizontal) {
+ this.setState({
+ snackbarOpen: true,
+ snackbarText: text,
+ snackbarVertical: vertical,
+ snackbarHorizontal: horizontal,
+ })
+ }
+
+ /*
+ TODO 写成HOC组件,更好复用
+ 全局的Dialog this.props.showDialog调用即可
+ @param contentText dialog显示的提示文本
+ @param callback 确定按钮回调方法
+ @param moreButtonsRender 除了“确定”、“取消”按钮外的其他按钮
+ @param okButtonText “确定”按钮显示文本,如 继续查看
+ */
+ showDialog(params) {
+ const { contentText, callback, moreButtonsRender, okButtonText, isSingleButton } = params;
+
+ this.dialogOkCallback = callback;
+ this.moreButtonsRender = moreButtonsRender
+ this.okButtonText = okButtonText;
+ this.isSingleButton = isSingleButton;
+ this.setState({
+ gDialogOpen: true,
+ gDialogContentText: contentText
+ })
+ }
+ onGdialogOkBtnClick() {
+
+ this.dialogOkCallback && this.dialogOkCallback();
+ // this.setState({
+ // gDialogOpen: true
+ // })
+ }
+ handleGdialogClose = () => {
+ this.setState({
+ gDialogOpen: false
+ })
+ }
+ render() {
+ const { classes } = this.props;
+ return (
+ this.closeTaskResultLayer(),
+
+ onPathChange: this.onPathChange,
+ updateChallengePath: this.updateChallengePath,
+
+ showSnackbar: this.showSnackbar,
+ showDialog: this.showDialog,
+ handleGdialogClose: () => this.handleGdialogClose(),
+
+ onShowUpdateDialog: this.onShowUpdateDialog,
+ updateDialogClose: this.updateDialogClose,
+
+ match: this.props.match
+ }}
+ >
+
+
+ this.handleSnackbarClose()}
+ transition={Fade}
+ SnackbarContentProps={{
+ 'aria-describedby': 'message-id',
+ }}
+ resumeHideDuration={2000}
+ message={{this.state.snackbarText}}
+ />
+ {this.props.children}
+
+ )
+ }
+}
+
+export default withStyles(styles) (TPIContextProvider);
+
+
+
diff --git a/public/react/src/modules/courses/coursesPublic/Startshixuntask.js b/public/react/src/modules/courses/coursesPublic/Startshixuntask.js
index 064ec645a..9a9a98f8f 100644
--- a/public/react/src/modules/courses/coursesPublic/Startshixuntask.js
+++ b/public/react/src/modules/courses/coursesPublic/Startshixuntask.js
@@ -1,163 +1,163 @@
-import React,{ Component } from "react";
-import { WordsBtn } from 'educoder';
-import {Tooltip,message,Modal} from 'antd';
-import {Link} from 'react-router-dom';
-import axios from 'axios';
-import Modals from '../../modals/Modals';
-
-
-
-class Startshixuntask extends Component{
- constructor(props){
- super(props);
- this.state = {
- startbtn:false
- }
-
- }
-
- componentDidMount() {
-
- }
-
- taskoperationId=(list)=>{
- this.setState({
- startbtn:true,
- })
- let url= list+".json";
- axios.get(url).then((response) => {
-
- if(response.status===200){
- if(response.data.status===-2){
-
- this.setState({
- startbtn:false,
- shixunsreplace:true,
- hidestartshixunsreplacevalue:response.data.message+".json"
- })
- }else if(response.data.status===-1){
- console.log(response)
- }else if(response.data.status===-3){
- this.setState({
- shixunsmessage:response.data.message,
- startshixunCombattype:true,
- startbtn:false
- })
- }else{
-
- if(response.data.status!=401&&response.data.status!=403){
- window.location.href = "/tasks/"+response.data.game_identifier;
- }
-
- }
- }
- }).catch((error) => {
- this.setState({
- startbtn:false
- })
- });
-
- }
-
- hidestartshixunsreplace=(url)=>{
- axios.get(url).then((response) => {
- if(response.status===200){
-
- this.setState({
- shixunsreplace:false
- })
- message.success('重置成功,正在进入实训!');
- let path="/shixuns/"+response.data.shixun_identifier+"/challenges";
- this.props.history.push(path);
-
- }}
- ).catch((error) => {
- this.setState({
- startbtn:false,
- shixunsreplace:false
- })
- });
-
- }
-
- hidestartshixunCombattype=()=>{
- this.setState({
- startshixunCombattype:false
- })
- }
-
- render(){
- let {
- Modalstype,
- Modalstopval,
- Modalsbottomval,
- cardsModalcancel,
- cardsModalsavetype,
- loadtype,
- shixunsreplace,
- hidestartshixunsreplacevalue,
- startshixunCombattype,
- shixunsmessage,
- startbtn
- } = this.state;
-
- return(
-
-
-
-
-
-
-
-
-
-
-
本实训的开启时间:{shixunsmessage}
开启时间之前不能挑战
-
-
-
- {/**/}
- {/*知道了*/}
- {/*
*/}
-
-
- {this.props.isStudent?
-
- {this.props.data.task_operation&&this.props.data.task_operation?startbtn===false?this.taskoperationId( this.props.data.task_operation[1])}>
- {this.props.data.task_operation[0]}
- :"开启中":""}
- :""
- }
-
-
- )
- }
-}
+import React,{ Component } from "react";
+import { WordsBtn } from 'educoder';
+import {Tooltip,message,Modal} from 'antd';
+import {Link} from 'react-router-dom';
+import axios from 'axios';
+import Modals from '../../modals/Modals';
+
+
+
+class Startshixuntask extends Component{
+ constructor(props){
+ super(props);
+ this.state = {
+ startbtn:false
+ }
+
+ }
+
+ componentDidMount() {
+
+ }
+
+ taskoperationId=(list)=>{
+ this.setState({
+ startbtn:true,
+ })
+ let url= list+".json";
+ axios.get(url).then((response) => {
+
+ if(response.status===200){
+ if(response.data.status===-2){
+
+ this.setState({
+ startbtn:false,
+ shixunsreplace:true,
+ hidestartshixunsreplacevalue:response.data.message+".json"
+ })
+ }else if(response.data.status===-1){
+ console.log(response)
+ }else if(response.data.status===-3){
+ this.setState({
+ shixunsmessage:response.data.message,
+ startshixunCombattype:true,
+ startbtn:false
+ })
+ }else{
+
+ if(response.data.status!=401&&response.data.status!=403){
+ window.location.href = "/tasks/"+response.data.game_identifier;
+ }
+
+ }
+ }
+ }).catch((error) => {
+ this.setState({
+ startbtn:false
+ })
+ });
+
+ }
+
+ hidestartshixunsreplace=(url)=>{
+ axios.get(url).then((response) => {
+ if(response.status===200){
+
+ this.setState({
+ shixunsreplace:false
+ })
+ message.success('重置成功,正在进入实训!');
+ let path="/shixuns/"+response.data.shixun_identifier+"/challenges";
+ this.props.history.push(path);
+
+ }}
+ ).catch((error) => {
+ this.setState({
+ startbtn:false,
+ shixunsreplace:false
+ })
+ });
+
+ }
+
+ hidestartshixunCombattype=()=>{
+ this.setState({
+ startshixunCombattype:false
+ })
+ }
+
+ render(){
+ let {
+ Modalstype,
+ Modalstopval,
+ Modalsbottomval,
+ cardsModalcancel,
+ cardsModalsavetype,
+ loadtype,
+ shixunsreplace,
+ hidestartshixunsreplacevalue,
+ startshixunCombattype,
+ shixunsmessage,
+ startbtn
+ } = this.state;
+
+ return(
+
+
+
+
+
+
+
+
+
+
+
本实训的开启时间:{shixunsmessage}
开启时间之前不能挑战
+
+
+
+ {/**/}
+ {/*知道了*/}
+ {/*
*/}
+
+
+ {this.props.isStudent?
+
+ {this.props.data.task_operation&&this.props.data.task_operation?startbtn===false?this.taskoperationId( this.props.data.task_operation[1])}>
+ {this.props.data.task_operation[0]}
+ :"开启中":""}
+ :""
+ }
+
+
+ )
+ }
+}
export default Startshixuntask;
\ No newline at end of file
diff --git a/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js b/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js
index 8ad70753f..272ac6418 100644
--- a/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js
+++ b/public/react/src/modules/courses/shixunHomework/ShixunhomeWorkItem.js
@@ -210,7 +210,7 @@ class ShixunhomeWorkItem extends Component{
{
- var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
- var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
- var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
- var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
- if(isIE) {
- var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
- reIE.test(userAgent);
- var fIEVersion = parseFloat(RegExp["$1"]);
- if(fIEVersion == 7) {
- return 7;
- } else if(fIEVersion == 8) {
- return 8;
- } else if(fIEVersion == 9) {
- return 9;
- } else if(fIEVersion == 10) {
- return 10;
- } else {
- return 6;//IE版本<=7
- }
- } else if(isEdge) {
- return 'edge';//edge
- } else if(isIE11) {
- return 11; //IE11
- }else{
- return -1;//不是ie浏览器
- }
- }
- componentDidMount() {
- let thiisie=this.IEVersion();
- if(thiisie!=-1){
- this.setState({
- isIE:true
- })
- }else{
- this.setState({
- isIE:false
- })
- }
- }
- /*
- * Fork
- * */
- copyForkvisible = () => {
- let {shixunsDetails} = this.props;
- if (shixunsDetails.can_fork === null) {
- this.setState({
- Forkvisible: true
- })
- } else {
- this.setState({
- Forkvisible: false,
- Forkauthentication: true,
- can_fork: shixunsDetails.can_fork.can_fork,
- certi_url: shixunsDetails.can_fork.certi_url,
- })
- }
-
- }
-
- hideForkvisible = () => {
- this.setState({
- Forkvisible: false,
- Forkauthentication:false
- })
- }
-
- addForkvisible = () => {
- this.setState({
- Forkvisibletype: true,
- })
- let id = this.props.match.params.shixunId;
- let url = "/shixuns/" + id + "/copy.json";
- axios.post(url).then((response) => {
- if(response.data.status===401){
-
- }else{
- this.setState({
- Forkvisible: false,
- Forkauthentication: false,
- // Forkvisibletype:false
- })
- window.location.href = "/shixuns/" + response.data.shixun + "/challenges";
- }
-
- }).catch((error) => {
- console.log(error)
- });
-
- }
- /*
- * 发送至按钮
- * */
- Senttothe=()=>{
- let id = this.props.match.params.shixunId;
- let url="/shixuns/" + id +"/search_user_courses.json";
- this.setState({
- Senttothetype:true
- })
-
- axios.get(url, {
- params: {
- page:1,
- limit:10
- }}).then((response) => {
- this.setState({
- courses_count:response.data.courses_count,
- course_list:response.data.course_list
- })
- }).catch((error) => {
- console.log(error)
- });
- }
-
- SenttotheSearch=(value)=>{
- let id = this.props.match.params.shixunId;
- let url="/shixuns/" + id +"/search_user_courses.json?search="+value;
- axios.get(url, {
- params: {
- page:1,
- limit:10
- }}).then((response) => {
- this.setState({
- courses_count:response.data.courses_count,
- course_list:response.data.course_list,
- pages:1,
- Searchvalue:value
- })
- }).catch((error) => {
- console.log(error)
- });
- }
-
- onChangeSenttothevcalue=(e)=>{
- this.setState({
- Senttothevcalue:e.target.value
- })
- }
- onChangesendeSenttothe=(pageNumber)=>{
- let{Searchvalue}=this.state;
- let id = this.props.match.params.shixunId;
- let url="/shixuns/" + id +"/search_user_courses.json?search="+Searchvalue;
- axios.get(url, {
- params: {
- page:pageNumber,
- limit:10
- }}).then((response) => {
- this.setState({
- courses_count:response.data.courses_count,
- course_list:response.data.course_list,
- pagenum: pageNumber,
- pages: pageNumber
- })
- }).catch((error) => {
- console.log(error)
- });
- }
- sendeSenttothevcalue=()=>{
- let {Senttothevcalue}=this.state;
- let id = this.props.match.params.shixunId;
- let url="/shixuns/" + id +"/send_to_course.json";
- axios.post(url,{
- course_id:Senttothevcalue
- }).then((response) => {
- this.props.showSnackbar(response.data.message);
- this.setState({
- Senttothetype:false,
- Searchvalue:"",
- pages:1
- })
- window.location.href = response.data.url;
-
- }).catch((error) => {
- console.log(error)
- });
-
- }
-
- hideSenttothevcalue=()=>{
- this.setState({
- Senttothetype:false,
- Searchvalue:"",
- pages:1
- })
-
-
- }
-
- /*
- * 撤销发布按钮
- * */
- cancel_publish=()=>{
-
- let id = this.props.match.params.shixunId;
- let url="/shixuns/" + id +"/cancel_publish.json";
- axios.get(url).then((response) => {
- this.props.showSnackbar(response.data.message);
- window.location.reload()
- }).catch((error) => {
- console.log(error)
- });
- }
-
-
- /*
- * 申请发布按钮
- * */
- applyrelease=()=>{
- let id = this.props.match.params.shixunId;
- let url="/shixuns/" + id +"/publish.json";
- axios.get(url).then((response) => {
- let evaluation_set_position
- if(response.data.evaluation_set_position===null){
- evaluation_set_position=[]
- }else{
- evaluation_set_position=response.data.evaluation_set_position
- }
- this.setState({
- Issuevisible:true,
- tag_position:response.data.tag_position,
- evaluation_set_position:evaluation_set_position,
- publishboxstatus:response.data.status,
- })
- }).catch((error) => {
- console.log(error)
- });
- };
-
- hiddenIssuevisible=(val)=>{
- this.setState({
- Issuevisible:false
- })
- if(val===0||val===1){
- window.location.reload()
- }
-
- }
-
- //重置按钮
- // resetshixunCombat=(id)=>{
- // let zrl="/myshixuns/"+id+"/reset_my_game.json";
- // axios.get(zrl).then((response) => {
- // window.location.href = "/shixuns/" + response.data.shixun_identifier + "/challenges";
- // message.success('重置成功');
- // }).catch((error) => {
- // console.log(error)
- // });
- // }
-
- hidestartshixunsreplace=(url)=>{
- axios.get(url).then((response) => {
- if(response.status===200){
- let path="/shixuns/"+response.data.shixun_identifier+"/challenges";
- this.props.history.push(path);
- this.setState({
- shixunsreplace:false
- })
- message.success('重置成功,正在进入实训!');
- this.startshixunCombat();
- }}
- ).catch((error) => {
- this.setState({
- startbtn:false,
- shixunsreplace:false
- })
- });
-
- }
- //开始实战按钮
- startshixunCombat=()=>{
- let {shixunsDetails} = this.props
- if( shixunsDetails.status>1){
- this.setState({
- startbtn:true,
- hidestartshixunsreplacevalue:""
- })
- }else{
- this.setState({
- hidestartshixunsreplacevalue:""
- })
- }
-
-
- let id = this.props.match.params.shixunId;
- let url="/shixuns/"+id+"/shixun_exec.json";
- axios.get(url).then((response) => {
- if(response.status===200){
- if(response.data.status===-2){
- // this.resetshixunCombat(response.data.message);
- this.setState({
- startbtn:false,
- shixunsreplace:true,
- hidestartshixunsreplacevalue:response.data.message+".json"
- })
- }else if(response.data.status===-1){
- console.log(response)
- }else if(response.data.status===-3){
- this.setState({
- shixunsmessage:response.data.message,
- startshixunCombattype:true,
- startbtn:false
- })
- }else{
- // let path="/tasks/"+response.data.game_identifier;
- // this.props.history.push(path);
-
-
- // this.context.router.history.push(path);
- if(response.data.status!=401){
- window.location.href = "/tasks/"+response.data.game_identifier;
- }
-
- }
- }
- }).catch((error) => {
- this.setState({
- startbtn:false
- })
- });
- }
-
- tocertification=()=>{
- let{certi_url}=this.state;
- this.setState({
- Forkauthentication:false
- })
- window.location.href=certi_url;
- }
-
- SenttotheValue=(e)=>{
- this.setState({
- Searchvalue:e.target.value
- })
- }
-
- hidestartshixunCombattype=()=>{
- this.setState({
- startshixunCombattype:false
- })
- }
-
-
-
- render() {
- let {
- Forkvisible,
- Senttothetype,
- Senttothevcalue,
- evaluation_set_position,
- Forkauthentication,
- can_fork,
- certi_url,
- tag_position,
- courses_count,
- course_list,
- Issuevisible,
- publishboxstatus,
- showradios,
- startbtn,
- Searchvalue,
- startshixunCombattype,
- shixunsmessage,
- pages,
- shixunsreplace,
- hidestartshixunsreplacevalue,
- Forkvisibletype,
- isIE} = this.state;
- let {shixunsDetails, shixunId, star_info, star_infos} = this.props;
- let challengeBtnTipText = '';
- let challengeBtnText = '模拟实战';
- // let star_info=[]
- // if (shixunsDetails.status === 0) {
- //
- // } else if (shixunsDetails.status === 1) {
- //
- // } else if (shixunsDetails.status === 2) {
- // challengeBtnTipText = '开始学习并完成实战任务'
- //
- // }
- if(shixunsDetails!=undefined){
- if (shixunsDetails.status === 0 ) {
- challengeBtnText = '继续实战'
- } else if (shixunsDetails.status === 1) {
- challengeBtnText = '查看实战'
- } else if (shixunsDetails.status === 3) {
- challengeBtnText = '继续实战'
- }else{
- challengeBtnText = "开始实战"
- }
- }
-
-
- // let list=shixunsDetails.task_operation;
- // if(list!=undefined){
- // if (shixunsDetails.status === 0 ) {
- // for(var i=0; i{
- $("#ratePanel").show();
- this.setState({
- showradios:true
- })
- },()=>{
- $("#ratePanel").hide();
- this.setState({
- showradios:false
- })
- })
-
- const radioStyle = {
- display: 'block',
- height: '30px',
- lineHeight: '30px',
- };
-
-
- return (
-
- shixunsDetails===undefined?"":
-
-
-
-
-
- {shixunsDetails.name}
- {
- shixunsDetails.fork_from === undefined || shixunsDetails.fork_from === null ? "" :
-
-
-
- }
-
-
-
-
- -
- 学习人数
- {shixunsDetails.stu_num}
-
- {/*- */}
- {/*经验值*/}
- {/*{shixunsDetails.experience}*/}
- {/*
*/}
- -
- 难度系数
- {shixunsDetails.diffcult}
-
-
-
-
-
-
- {
- startbtn === false ?
-
-
- {shixunsDetails.task_operation === undefined ? "" : shixunsDetails.status > 1 ? shixunsDetails.task_operation[0] : "模拟实战"}
-
-
- : ""
- }
-
-
-
-
本实训的开启时间:{shixunsmessage}
开启时间之前不能挑战
-
-
-
- {/**/}
- {/*知道了*/}
- {/*
*/}
-
-
-
-
-
-
-
-
-
-
-
- {
- startbtn === true ?
-
开启中 : ""
- }
-
- {/*{*/}
- {/*shixunsDetails.status=== 3 && shixunsDetails.task_operation[0]==="开始实战"?*/}
- {/*
{shixunsDetails.task_operation===undefined?"":shixunsDetails.task_operation[0]}:""*/}
- {/*}*/}
-
- {shixunsDetails.status === 0 && this.props.identity < 4 ?
-
申请发布 : ""
- }
-
-
- {
- publishboxstatus === 0 ?
-
- 发布申请已提交,请等待管理员的审核
-
-
: publishboxstatus === 1 ?
-
-
- 发布申请已提交,请等待管理员的审核
- • 我们将在1-2个工作日内完成审核
-
-
: publishboxstatus === 2 ?
-
- 第
- {
- evaluation_set_position.map((item, key) => {
- return (
- {item},
- )
- })
- }
- 关评测设置尚未完成,无法申请发布
-
-
: publishboxstatus === 3 ?
-
-
- 每一个关卡至少需要一个技能标签
- 第
- {
- tag_position.map((item, key) => {
- return (
- {item},
- )
- })
- }
- 关尚未设置技能标签,请补充
-
-
:
-
- }
-
-
-
-
- {shixunsDetails.status === 1 && this.props.identity < 4 ?
-
撤销发布 : ""
- }
-
- {
-
-
- 发送至
-
-
- }
-
-
-
-
-
-
- 选择的实训将会发送到指定课堂
-
-
-
- this.SenttotheSearch(value)}
- style={{width: '100%'}}
- />
-
-
-
12?"cdefault mb20":"cdefault mb50"}>
-
-
-
- {
- course_list === undefined ? "" : course_list.map((item, key) => {
- return (
- {item.name}
- )
- })
- }
-
-
-
-
-
-
-
12 ? "block" : "none"}}
- showQuickJumper defaultCurrent={1} current={pages} pageSize={12}
- total={courses_count} onChange={this.onChangesendeSenttothe}/>
-
- 确定
-
- 取消
-
-
-
-
-
-
- {shixunsDetails.status === 3 &&
-
已关闭
- }
-
-
-
-
- Fork
-
-
-
-
- {Forkvisibletype===true?
-
- :
-
-
复制将在后台执行
平台将为你创建一个新的同名实训和内容,请问是否继续?
-
-
-
- }
-
-
-
-
-
-
-
-
- {!!shixunsDetails.fork_num &&
-
- {shixunsDetails.fork_num}
-
- }
-
-
-
-
-
-
-
-
-
正在等待管理员的审核。在审核通过前,可以随时撤销发布
-
-
- );
- }
-}
-
-export default TPMBanner;
-
+import React, { Component } from 'react';
+
+import { Redirect } from 'react-router';
+
+import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
+
+import PropTypes from 'prop-types';
+
+import {Modal,Input,Radio,Pagination,message,Spin,Icon,Tooltip} from 'antd';
+
+import 'antd/lib/pagination/style/index.css';
+
+import axios from 'axios';
+
+// import { Rating,Progress } from '@icedesign/base';
+
+import Rating from '@icedesign/base/lib/rating';
+
+import Progress from '@icedesign/base/lib/progress';
+
+// 引入业务组件样式
+import '@icedesign/base/lib/rating/style.js';
+
+import '@icedesign/base/lib/progress/style.js';
+
+import './shixuns/css/TPMBanner.css';
+
+let $ = window.$;
+
+const Search = Input.Search;
+
+const RadioGroup = Radio.Group;
+
+class TPMBanner extends Component {
+ constructor(props) {
+ super(props)
+ this.state={
+ Forkvisible: false,
+ Senttothetype:false,
+ Senttothevcalue:1,
+ courses_count:1,
+ course_list:[],
+ pagenum:1,
+ publishbox:"",
+ publishboxstatus:0,
+ pages:1,
+ Issuevisible:false,
+ evaluation_set_position:[],
+ tag_position:[],
+ Forkauthentication:false,
+ can_fork:undefined,
+ certi_url:undefined,
+ showradios:false,
+ startbtn:false,
+ Searchvalue:"",
+ startshixunCombattype:false,
+ shixunsmessage:"",
+ shixunsreplace:false,
+ hidestartshixunsreplacevalue:"",
+ isIE:false,
+ Forkvisibletype: false,
+ }
+ }
+
+ // star_info:[0, 0, 0, 0, 0, 0],
+ // star_infos:[0, 0, 0, 0, 0, 0],
+ // shixunsDetails:{},
+ // shixunId: undefined,
+ // componentWillReceiveProps(newProps, newContext){
+ // this.setState({
+ // shixunsDetails: newProps.shixunsDetails
+ // });
+ // }
+
+ IEVersion=()=>{
+ var userAgent = navigator.userAgent; //取得浏览器的userAgent字符串
+ var isIE = userAgent.indexOf("compatible") > -1 && userAgent.indexOf("MSIE") > -1; //判断是否IE<11浏览器
+ var isEdge = userAgent.indexOf("Edge") > -1 && !isIE; //判断是否IE的Edge浏览器
+ var isIE11 = userAgent.indexOf('Trident') > -1 && userAgent.indexOf("rv:11.0") > -1;
+ if(isIE) {
+ var reIE = new RegExp("MSIE (\\d+\\.\\d+);");
+ reIE.test(userAgent);
+ var fIEVersion = parseFloat(RegExp["$1"]);
+ if(fIEVersion == 7) {
+ return 7;
+ } else if(fIEVersion == 8) {
+ return 8;
+ } else if(fIEVersion == 9) {
+ return 9;
+ } else if(fIEVersion == 10) {
+ return 10;
+ } else {
+ return 6;//IE版本<=7
+ }
+ } else if(isEdge) {
+ return 'edge';//edge
+ } else if(isIE11) {
+ return 11; //IE11
+ }else{
+ return -1;//不是ie浏览器
+ }
+ }
+ componentDidMount() {
+ let thiisie=this.IEVersion();
+ if(thiisie!=-1){
+ this.setState({
+ isIE:true
+ })
+ }else{
+ this.setState({
+ isIE:false
+ })
+ }
+ }
+ /*
+ * Fork
+ * */
+ copyForkvisible = () => {
+ let {shixunsDetails} = this.props;
+ if (shixunsDetails.can_fork === null) {
+ this.setState({
+ Forkvisible: true
+ })
+ } else {
+ this.setState({
+ Forkvisible: false,
+ Forkauthentication: true,
+ can_fork: shixunsDetails.can_fork.can_fork,
+ certi_url: shixunsDetails.can_fork.certi_url,
+ })
+ }
+
+ }
+
+ hideForkvisible = () => {
+ this.setState({
+ Forkvisible: false,
+ Forkauthentication:false
+ })
+ }
+
+ addForkvisible = () => {
+ this.setState({
+ Forkvisibletype: true,
+ })
+ let id = this.props.match.params.shixunId;
+ let url = "/shixuns/" + id + "/copy.json";
+ axios.post(url).then((response) => {
+ if(response.data.status===401){
+
+ }else{
+ this.setState({
+ Forkvisible: false,
+ Forkauthentication: false,
+ // Forkvisibletype:false
+ })
+ window.location.href = "/shixuns/" + response.data.shixun + "/challenges";
+ }
+
+ }).catch((error) => {
+ console.log(error)
+ });
+
+ }
+ /*
+ * 发送至按钮
+ * */
+ Senttothe=()=>{
+ let id = this.props.match.params.shixunId;
+ let url="/shixuns/" + id +"/search_user_courses.json";
+ this.setState({
+ Senttothetype:true
+ })
+
+ axios.get(url, {
+ params: {
+ page:1,
+ limit:10
+ }}).then((response) => {
+ this.setState({
+ courses_count:response.data.courses_count,
+ course_list:response.data.course_list
+ })
+ }).catch((error) => {
+ console.log(error)
+ });
+ }
+
+ SenttotheSearch=(value)=>{
+ let id = this.props.match.params.shixunId;
+ let url="/shixuns/" + id +"/search_user_courses.json?search="+value;
+ axios.get(url, {
+ params: {
+ page:1,
+ limit:10
+ }}).then((response) => {
+ this.setState({
+ courses_count:response.data.courses_count,
+ course_list:response.data.course_list,
+ pages:1,
+ Searchvalue:value
+ })
+ }).catch((error) => {
+ console.log(error)
+ });
+ }
+
+ onChangeSenttothevcalue=(e)=>{
+ this.setState({
+ Senttothevcalue:e.target.value
+ })
+ }
+ onChangesendeSenttothe=(pageNumber)=>{
+ let{Searchvalue}=this.state;
+ let id = this.props.match.params.shixunId;
+ let url="/shixuns/" + id +"/search_user_courses.json?search="+Searchvalue;
+ axios.get(url, {
+ params: {
+ page:pageNumber,
+ limit:10
+ }}).then((response) => {
+ this.setState({
+ courses_count:response.data.courses_count,
+ course_list:response.data.course_list,
+ pagenum: pageNumber,
+ pages: pageNumber
+ })
+ }).catch((error) => {
+ console.log(error)
+ });
+ }
+ sendeSenttothevcalue=()=>{
+ let {Senttothevcalue}=this.state;
+ let id = this.props.match.params.shixunId;
+ let url="/shixuns/" + id +"/send_to_course.json";
+ axios.post(url,{
+ course_id:Senttothevcalue
+ }).then((response) => {
+ this.props.showSnackbar(response.data.message);
+ this.setState({
+ Senttothetype:false,
+ Searchvalue:"",
+ pages:1
+ })
+ window.location.href = response.data.url;
+
+ }).catch((error) => {
+ console.log(error)
+ });
+
+ }
+
+ hideSenttothevcalue=()=>{
+ this.setState({
+ Senttothetype:false,
+ Searchvalue:"",
+ pages:1
+ })
+
+
+ }
+
+ /*
+ * 撤销发布按钮
+ * */
+ cancel_publish=()=>{
+
+ let id = this.props.match.params.shixunId;
+ let url="/shixuns/" + id +"/cancel_publish.json";
+ axios.get(url).then((response) => {
+ this.props.showSnackbar(response.data.message);
+ window.location.reload()
+ }).catch((error) => {
+ console.log(error)
+ });
+ }
+
+
+ /*
+ * 申请发布按钮
+ * */
+ applyrelease=()=>{
+ let id = this.props.match.params.shixunId;
+ let url="/shixuns/" + id +"/publish.json";
+ axios.get(url).then((response) => {
+ let evaluation_set_position
+ if(response.data.evaluation_set_position===null){
+ evaluation_set_position=[]
+ }else{
+ evaluation_set_position=response.data.evaluation_set_position
+ }
+ this.setState({
+ Issuevisible:true,
+ tag_position:response.data.tag_position,
+ evaluation_set_position:evaluation_set_position,
+ publishboxstatus:response.data.status,
+ })
+ }).catch((error) => {
+ console.log(error)
+ });
+ };
+
+ hiddenIssuevisible=(val)=>{
+ this.setState({
+ Issuevisible:false
+ })
+ if(val===0||val===1){
+ window.location.reload()
+ }
+
+ }
+
+ //重置按钮
+ // resetshixunCombat=(id)=>{
+ // let zrl="/myshixuns/"+id+"/reset_my_game.json";
+ // axios.get(zrl).then((response) => {
+ // window.location.href = "/shixuns/" + response.data.shixun_identifier + "/challenges";
+ // message.success('重置成功');
+ // }).catch((error) => {
+ // console.log(error)
+ // });
+ // }
+
+ hidestartshixunsreplace=(url)=>{
+ axios.get(url).then((response) => {
+ if(response.status===200){
+ // let path="/shixuns/"+response.data.shixun_identifier+"/challenges";
+ // this.props.history.push(path);
+ this.setState({
+ shixunsreplace:false
+ })
+ message.success('重置成功,正在进入实训!');
+ this.startshixunCombat();
+ }}
+ ).catch((error) => {
+ this.setState({
+ startbtn:false,
+ shixunsreplace:false
+ })
+ });
+
+ }
+ //开始实战按钮
+ startshixunCombat=()=>{
+ let {shixunsDetails} = this.props
+ if( shixunsDetails.status>1){
+ this.setState({
+ startbtn:true,
+ hidestartshixunsreplacevalue:""
+ })
+ }else{
+ this.setState({
+ hidestartshixunsreplacevalue:""
+ })
+ }
+
+
+ let id = this.props.match.params.shixunId;
+ let url="/shixuns/"+id+"/shixun_exec.json";
+ axios.get(url).then((response) => {
+ if(response.status===200){
+ if(response.data.status===-2){
+ // this.resetshixunCombat(response.data.message);
+ this.setState({
+ startbtn:false,
+ shixunsreplace:true,
+ hidestartshixunsreplacevalue:response.data.message+".json"
+ })
+ }else if(response.data.status===-1){
+ console.log(response)
+ }else if(response.data.status===-3){
+ this.setState({
+ shixunsmessage:response.data.message,
+ startshixunCombattype:true,
+ startbtn:false
+ })
+ }else{
+ // let path="/tasks/"+response.data.game_identifier;
+ // this.props.history.push(path);
+
+
+ // this.context.router.history.push(path);
+ if(response.data.status!=401){
+ window.location.href = "/tasks/"+response.data.game_identifier;
+ }
+
+ }
+ }
+ }).catch((error) => {
+ this.setState({
+ startbtn:false
+ })
+ });
+ }
+
+ tocertification=()=>{
+ let{certi_url}=this.state;
+ this.setState({
+ Forkauthentication:false
+ })
+ window.location.href=certi_url;
+ }
+
+ SenttotheValue=(e)=>{
+ this.setState({
+ Searchvalue:e.target.value
+ })
+ }
+
+ hidestartshixunCombattype=()=>{
+ this.setState({
+ startshixunCombattype:false
+ })
+ }
+
+
+
+ render() {
+ let {
+ Forkvisible,
+ Senttothetype,
+ Senttothevcalue,
+ evaluation_set_position,
+ Forkauthentication,
+ can_fork,
+ certi_url,
+ tag_position,
+ courses_count,
+ course_list,
+ Issuevisible,
+ publishboxstatus,
+ showradios,
+ startbtn,
+ Searchvalue,
+ startshixunCombattype,
+ shixunsmessage,
+ pages,
+ shixunsreplace,
+ hidestartshixunsreplacevalue,
+ Forkvisibletype,
+ isIE} = this.state;
+ let {shixunsDetails, shixunId, star_info, star_infos} = this.props;
+ let challengeBtnTipText = '';
+ let challengeBtnText = '模拟实战';
+ // let star_info=[]
+ // if (shixunsDetails.status === 0) {
+ //
+ // } else if (shixunsDetails.status === 1) {
+ //
+ // } else if (shixunsDetails.status === 2) {
+ // challengeBtnTipText = '开始学习并完成实战任务'
+ //
+ // }
+ if(shixunsDetails!=undefined){
+ if (shixunsDetails.status === 0 ) {
+ challengeBtnText = '继续实战'
+ } else if (shixunsDetails.status === 1) {
+ challengeBtnText = '查看实战'
+ } else if (shixunsDetails.status === 3) {
+ challengeBtnText = '继续实战'
+ }else{
+ challengeBtnText = "开始实战"
+ }
+ }
+
+
+ // let list=shixunsDetails.task_operation;
+ // if(list!=undefined){
+ // if (shixunsDetails.status === 0 ) {
+ // for(var i=0; i{
+ $("#ratePanel").show();
+ this.setState({
+ showradios:true
+ })
+ },()=>{
+ $("#ratePanel").hide();
+ this.setState({
+ showradios:false
+ })
+ })
+
+ const radioStyle = {
+ display: 'block',
+ height: '30px',
+ lineHeight: '30px',
+ };
+
+
+ return (
+
+ shixunsDetails===undefined?"":
+
+
+
+
+
+ {shixunsDetails.name}
+ {
+ shixunsDetails.fork_from === undefined || shixunsDetails.fork_from === null ? "" :
+
+
+
+ }
+
+
+
+
+ -
+ 学习人数
+ {shixunsDetails.stu_num}
+
+ {/*- */}
+ {/*经验值*/}
+ {/*{shixunsDetails.experience}*/}
+ {/*
*/}
+ -
+ 难度系数
+ {shixunsDetails.diffcult}
+
+
+
+
+
+
+ {
+ startbtn === false ?
+
+
+ {shixunsDetails.task_operation === undefined ? "" : shixunsDetails.status > 1 ? shixunsDetails.task_operation[0] : "模拟实战"}
+
+
+ : ""
+ }
+
+
+
+
本实训的开启时间:{shixunsmessage}
开启时间之前不能挑战
+
+
+
+ {/**/}
+ {/*知道了*/}
+ {/*
*/}
+
+
+
+
+
+
+
+
+
+
+
+ {
+ startbtn === true ?
+
开启中 : ""
+ }
+
+ {/*{*/}
+ {/*shixunsDetails.status=== 3 && shixunsDetails.task_operation[0]==="开始实战"?*/}
+ {/*
{shixunsDetails.task_operation===undefined?"":shixunsDetails.task_operation[0]}:""*/}
+ {/*}*/}
+
+ {shixunsDetails.status === 0 && this.props.identity < 4 ?
+
申请发布 : ""
+ }
+
+
+ {
+ publishboxstatus === 0 ?
+
+ 发布申请已提交,请等待管理员的审核
+
+
: publishboxstatus === 1 ?
+
+
+ 发布申请已提交,请等待管理员的审核
+ • 我们将在1-2个工作日内完成审核
+
+
: publishboxstatus === 2 ?
+
+ 第
+ {
+ evaluation_set_position.map((item, key) => {
+ return (
+ {item},
+ )
+ })
+ }
+ 关评测设置尚未完成,无法申请发布
+
+
: publishboxstatus === 3 ?
+
+
+ 每一个关卡至少需要一个技能标签
+ 第
+ {
+ tag_position.map((item, key) => {
+ return (
+ {item},
+ )
+ })
+ }
+ 关尚未设置技能标签,请补充
+
+
:
+
+ }
+
+
+
+
+ {shixunsDetails.status === 1 && this.props.identity < 4 ?
+
撤销发布 : ""
+ }
+
+ {
+
+
+ 发送至
+
+
+ }
+
+
+
+
+
+
+ 选择的实训将会发送到指定课堂
+
+
+
+ this.SenttotheSearch(value)}
+ style={{width: '100%'}}
+ />
+
+
+
12?"cdefault mb20":"cdefault mb50"}>
+
+
+
+ {
+ course_list === undefined ? "" : course_list.map((item, key) => {
+ return (
+ {item.name}
+ )
+ })
+ }
+
+
+
+
+
+
+
12 ? "block" : "none"}}
+ showQuickJumper defaultCurrent={1} current={pages} pageSize={12}
+ total={courses_count} onChange={this.onChangesendeSenttothe}/>
+
+ 确定
+
+ 取消
+
+
+
+
+
+
+ {shixunsDetails.status === 3 &&
+
已关闭
+ }
+
+
+
+
+ Fork
+
+
+
+
+ {Forkvisibletype===true?
+
+ :
+
+
复制将在后台执行
平台将为你创建一个新的同名实训和内容,请问是否继续?
+
+
+
+ }
+
+
+
+
+
+
+
+
+ {!!shixunsDetails.fork_num &&
+
+ {shixunsDetails.fork_num}
+
+ }
+
+
+
+
+
+
+
+
+
正在等待管理员的审核。在审核通过前,可以随时撤销发布
+
+
+ );
+ }
+}
+
+export default TPMBanner;
+
diff --git a/public/react/src/modules/tpm/shixunchild/Challenges/Challenges.js b/public/react/src/modules/tpm/shixunchild/Challenges/Challenges.js
index 38584c793..73dcb0b49 100644
--- a/public/react/src/modules/tpm/shixunchild/Challenges/Challenges.js
+++ b/public/react/src/modules/tpm/shixunchild/Challenges/Challenges.js
@@ -529,7 +529,7 @@ class Challenges extends Component {
实训已经更新了,正在为您重置!