diff --git a/public/images/course/guide/1-1.png b/public/images/course/guide/1-1.png new file mode 100644 index 000000000..c59467c5d Binary files /dev/null and b/public/images/course/guide/1-1.png differ diff --git a/public/images/course/guide/1-2.png b/public/images/course/guide/1-2.png new file mode 100644 index 000000000..1a4f26f38 Binary files /dev/null and b/public/images/course/guide/1-2.png differ diff --git a/public/images/course/guide/1-3.png b/public/images/course/guide/1-3.png new file mode 100644 index 000000000..f54250747 Binary files /dev/null and b/public/images/course/guide/1-3.png differ diff --git a/public/images/course/guide/1-4.png b/public/images/course/guide/1-4.png new file mode 100644 index 000000000..6ecd3bfb7 Binary files /dev/null and b/public/images/course/guide/1-4.png differ diff --git a/public/images/course/guide/1-5.png b/public/images/course/guide/1-5.png new file mode 100644 index 000000000..c4205496d Binary files /dev/null and b/public/images/course/guide/1-5.png differ diff --git a/public/images/course/guide/1-6.png b/public/images/course/guide/1-6.png new file mode 100644 index 000000000..5d5f76f7f Binary files /dev/null and b/public/images/course/guide/1-6.png differ diff --git a/public/images/course/guide/1-7.png b/public/images/course/guide/1-7.png new file mode 100644 index 000000000..65cadf0c7 Binary files /dev/null and b/public/images/course/guide/1-7.png differ diff --git a/public/react/src/context/TPIContextProvider.js b/public/react/src/context/TPIContextProvider.js index 60d63a1bd..0b764202f 100644 --- a/public/react/src/context/TPIContextProvider.js +++ b/public/react/src/context/TPIContextProvider.js @@ -462,7 +462,7 @@ pop_box_new(htmlvalue, 480, 182); // myshixun_manager power is_teacher resData.power = 0 resData.myshixun_manager = false - resData.is_teacher = false + // resData.is_teacher = false if (resData.user.identity === EDU_ADMIN) { resData.power = 1 @@ -513,6 +513,14 @@ pop_box_new(htmlvalue, 480, 182); loading: true, currentGamePassed: false, // 切换game时重置passed字段 }) + + // test + // var data = {"st":0,"discusses_count":12,"game_count":6,"record_onsume_time":5.303,"prev_game":"q67plhfjaogy","next_game":"lfrwm2ohiate","praise_count":0,"user_praise":false,"time_limit":180,"tomcat_url":"http://47.98.226.234","is_teacher":true,"myshixun_manager":false,"game":{"id":1964918,"myshixun_id":510423,"user_id":73892,"created_at":"2019-06-24T11:22:58.000+08:00","updated_at":"2019-06-25T11:15:48.000+08:00","status":0,"final_score":0,"challenge_id":573,"open_time":"2019-06-24T11:22:58.000+08:00","identifier":"yrsxolqk6zcp","answer_open":0,"end_time":null,"retry_status":0,"resubmit_identifier":null,"test_sets_view":false,"picture_path":null,"accuracy":null,"modify_time":null,"star":0,"cost_time":3966,"evaluate_count":1,"answer_deduction":0},"challenge":{"id":573,"shixun_id":186,"subject":"应用模型做预测","position":4,"task_pass":"####本关任务\r\n本关卡学习如何应用机器学习模型来做预测。\r\n\r\n####相关知识\r\n在前一关卡中,我们一起探讨了机器学习的一般原理,并建立了一个非常简单的电影评分模型Model 0:\r\n\r\n评分 = **大众对电影的平均评分** + **用户个人的给分偏好** + **电影的评分偏好**\r\n\r\n针对这个模型,我们设计了一个非常朴素的预测模型Baseline,直接从数据集中统计得到上述三个参数的值。\r\n\r\n在本关卡中,我们将应用这个模型对用户和电影的评分做出预测。\r\n\r\n####编程要求\r\n回顾Model 0的预测评分公式:\r\n```latex\r\nf(u,m)=g+\\alpha(u)+\\beta(m)\r\n```\r\n\r\n我们的Baseline模型得到了$$g$$、$$\\alpha$$和$$\\beta$$三种参数,下面我们实现predict函数,来对测试数据集中未知的用户电影评分进行预测,需要填充的代码块如下:\r\n```python\r\n# -*- coding:utf-8 -*-\r\n\r\ndef predict(g, alpha, beta, test_data):\r\n\t\"\"\"预测用户对电影的评分\r\n\t参数:\r\n\t\tg - 浮点数,模型参数平均电影评分\r\n\t\talpha - 浮点数组,用户评分偏差参数数组\r\n\t\tbeta - 浮点数组,电影评分偏差参数数组\r\n\t\ttest_data - Pandas的DataFrame对象,有两列'user','movie',是测试数据集\r\n\t返回值:\r\n\t\tret - 浮点数数组,预测的评分数组,举例ret[10],表示第10组用户和电影对的评分值\r\n\t\"\"\"\t\r\n\tret = []\r\n\tN = len(alpha)\r\n\tM = len(beta)\r\n\t\r\n\t# 请在此添加实现代码\r\n\t#********** Begin *********#\r\n\t\r\n\t#********** End *********#\r\n\t\r\n\treturn ret\r\n```\r\n\r\n####本关任务\r\n本关卡的测试数据来自内置测试文件,平台将比对您所编写函数的预测评分与正确评分,只有所有数据全部计算正确才能进入下一关。","score":500,"path":"src/step4/doprediction.py","st":0,"web_route":null,"modify_time":null},"shixun":{"id":186,"name":"理解机器学习基本概念:从电影评分预测讲起","user_id":24758,"gpid":3676,"visits":622,"created_at":"2017-08-25T18:07:41.000+08:00","updated_at":"2019-06-02T11:05:20.000+08:00","status":2,"language":"MachineLearning","authentication":false,"identifier":"58DRWG63","trainee":3,"major_id":635,"webssh":0,"homepage_show":false,"hidden":false,"fork_from":null,"can_copy":true,"modify_time":"2017-09-29T21:42:16.000+08:00","reset_time":"2017-09-29T21:42:16.000+08:00","publish_time":"2017-09-29T10:58:13.000+08:00","closer_id":null,"end_time":null,"git_url":"educoder/58drwg63","vnc":false,"myshixuns_count":318,"challenges_count":6,"use_scope":0,"mirror_script_id":0,"image_text":null,"code_hidden":false,"task_pass":false,"exec_time":180,"test_set_permission":true,"sigle_training":false,"hide_code":false,"multi_webssh":false,"excute_time":null,"repo_name":"educoder/58drwg63","averge_star":4.9,"opening_time":null,"users_count":10,"forbid_copy":false,"pod_life":0},"myshixun":{"id":510423,"shixun_id":186,"is_public":true,"user_id":73892,"gpid":null,"created_at":"2019-06-24T11:22:55.000+08:00","updated_at":"2019-06-24T13:56:40.000+08:00","status":0,"identifier":"7pkwxim9eh","commit_id":"ff7c6652fdfdf62eaa1316d39400ebdbd6cb81fb","modify_time":"2017-09-29T21:42:16.000+08:00","reset_time":"2017-09-29T21:42:16.000+08:00","system_tip":false,"git_url":null,"onclick_time":"2019-06-24T11:22:55.000+08:00","repo_name":"p35840769/7pkwxim9eh20190624112255"},"user":{"user_id":73892,"login":"p35840769","name":"韩半安","grade":6895,"image_url":"avatars/User/b","school":"国防科技大学","identity":6},"tpm_modified":false,"tpm_cases_modified":false,"mirror_name":["MachineLearning"],"has_answer":true,"test_sets":[{"is_public":true,"result":false,"input":"771 253 360 99 8 759 976 387 873 829 437 53 854 148 447 179 246 810 158 653 583 929 691 892 263 230 637 221 7 652 127 965 767","output":"3.577 -0.329 2.648 4.727 4.351 2.616 3.496 3.059 3.470 3.166 3.064 2.716 3.712 4.003 3.064 3.462 4.004 2.067 3.860 0.121 3.807 3.735 4.230 3.137 4.431 2.468 4.018 5.218 4.351 4.121 4.050 4.587 3.777","actual_output":"Traceback (most recent call last):\r\n File \"src/step4/main.py\", line 3, in \u003cmodule\u003e\r\n from doprediction import predict\r\nImportError: cannot import name 'predict'\r\n","compile_success":1},{"is_public":false,"result":false,"compile_success":1}],"allowed_unlock":true,"last_compile_output":"共有2组测试集,其中有2组测试结果不匹配。详情如下:","test_sets_count":2,"sets_error_count":2} + // data.shixun.vnc = true + // data.vnc_url= "http://47.96.157.89:54144/vnc_lite.html?password=headless" + + // this._handleResponseData(data) + // return axios.get(url, { // https://stackoverflow.com/questions/48861290/the-value-of-the-access-control-allow-origin-header-in-the-response-must-not-b @@ -835,7 +843,8 @@ pop_box_new(htmlvalue, 480, 182); {this.state.gDialogContentText} - + {/* mb20 加了有样式问题 */} + { this.isSingleButton ?
+
{ usingAntdModal ? { + this.setState({ + inputValue: e.target.value + }) + } + open = () => { + this.setState({ visible: true, inputValue: '' }) + } + onSave = () => { + let coursesId = this.props.match.params.coursesId; + const url = `/courses/${coursesId}/boards.json` + let { inputValue } = this.state; + + axios.post(url,{ + name: inputValue + }).then((response)=>{ + if (response.data.status == 0) { + this.onCancel() + this.props.showNotification('添加成功') + this.props.addSuccess && this.props.addSuccess() + } + }).catch((error)=>{ + console.log(error) + }) + } + onCancel = () => { + this.setState({ visible: false, inputValue: '' }) + } + render(){ + let { inputValue, visible } = this.state; + const { title } = this.props; + return( + +
+
{this.props.label}:
+ +
+ + {/* {this.state.NavmodalValuetype===true? + {this.state.NavmodalValues} + :""} */} + + {/* this.state.NavmodalValuetype===true?"clearfix mt20 edu-txt-center": */} +
+ 取消 + 确定 +
+ + ) + } +} +export default AddDirModal; \ No newline at end of file diff --git a/public/react/src/modules/courses/boards/BoardsNew.js b/public/react/src/modules/courses/boards/BoardsNew.js index cf530aba5..97d9436a6 100644 --- a/public/react/src/modules/courses/boards/BoardsNew.js +++ b/public/react/src/modules/courses/boards/BoardsNew.js @@ -3,13 +3,13 @@ import React,{ Component } from "react"; import { Form, Input, InputNumber, Switch, Radio, Slider, Button, Upload, Icon, Rate, Checkbox, message, - Row, Col, Select, Modal + Row, Col, Select, Modal, Divider } from 'antd'; import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor'; import axios from 'axios' import './board.css' import "../common/formCommon.css" - +import AddDirModal from './AddDirModal' import { RouteHOC } from './common.js' import CBreadcrumb from '../common/CBreadcrumb' import {getUploadActionUrl, bytesToSize, uploadNameSizeSeperator, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll} from 'educoder'; @@ -29,14 +29,14 @@ class BoardsNew extends Component{ boards: [] } } - componentDidMount = () => { - - const topicId = this.props.match.params.topicId - + addSuccess = () => { + this.fetchBoards() + } + fetchBoards = () => { + const isEdit = this.isEdit const boardId = this.props.match.params.boardId - const boardsUrl = `/courses/board_list.json?board_id=${boardId}` - const isEdit = !!topicId + const boardsUrl = `/courses/board_list.json?board_id=${boardId}` axios.get(boardsUrl, { }) .then((response) => { if (response.data.status == 0) { @@ -57,8 +57,17 @@ class BoardsNew extends Component{ .catch(function (error) { console.log(error); }); - + } + componentDidMount = () => { + + const topicId = this.props.match.params.topicId + const isEdit = !!topicId this.isEdit = isEdit + + const boardId = this.props.match.params.boardId + + this.fetchBoards() + if (isEdit) { const url = `/messages/${topicId}.json` axios.get(url, { @@ -260,6 +269,12 @@ class BoardsNew extends Component{ return(
+ {/* bor-bottom-greyE */}
{ window.location.href = "/courses/" + this.props.match.params.coursesId + "/settings"; } - render() { - let { Addcoursestypes, coursedata, modalsType, modalsTopval, loadtype,modalsBottomval,antIcon} = this.state; + let { Addcoursestypes, coursedata, modalsType, modalsTopval, loadtype,modalsBottomval,antIcon,is_guide} = this.state; return (
- + { + is_guide && + } + { coursedata === undefined || coursedata.status===401?
:
diff --git a/public/react/src/modules/courses/coursesDetail/CoursesGuide.js b/public/react/src/modules/courses/coursesDetail/CoursesGuide.js new file mode 100644 index 000000000..b47998d9d --- /dev/null +++ b/public/react/src/modules/courses/coursesDetail/CoursesGuide.js @@ -0,0 +1,44 @@ +import React, {Component} from 'react'; +import '../css/Courses.css'; +import {setImagesUrl} from 'educoder'; + + +class CoursesGuide extends Component { + constructor(props) { + super(props) + this.state={ + step:1 + } + } + render(){ + let {step} = this.state; + return( +
+ +
+ { + step ==1 && +
+

+

+

+ + +

+

+ + + +

+
+ } +
+
+ ) + } +} +export default CoursesGuide; \ No newline at end of file diff --git a/public/react/src/modules/courses/coursesPublic/Associationmodel.js b/public/react/src/modules/courses/coursesPublic/Associationmodel.js index 9af795931..d263a933b 100644 --- a/public/react/src/modules/courses/coursesPublic/Associationmodel.js +++ b/public/react/src/modules/courses/coursesPublic/Associationmodel.js @@ -59,15 +59,18 @@ class Associationmodel extends Component{ goback=()=>{ + debugger this.setState({ Modalstype:false, }) - this.props.funlist() this.props.Cancel() + this.props.funlist() + } setSaves=()=>{ + debugger let {projectvalue}=this.state; let taskid=this.props.taskid; let url="/graduation_tasks/"+taskid+"/graduation_works/relate_project.json"; @@ -76,19 +79,14 @@ class Associationmodel extends Component{ project_id: projectvalue }).then((result)=>{ - if(result.status===200){ - if(result.data.status===0){ - + this.goback() // this.setState({ // Modalstype:true, // Modalstopval:result.data.message, // ModalSave:this.goback, // loadtype:true // }) - this.goback - } - } }).catch((error)=>{ console.log(error) @@ -115,7 +113,7 @@ class Associationmodel extends Component{ project_id: projectvalue } }).then((result)=>{ - if(result.status===200){ + if(result.data.is_relate===false){ this.setSaves() }else{ @@ -126,7 +124,7 @@ class Associationmodel extends Component{ loadtype:true }) } - } + }).catch((error)=>{ console.log(error) }) diff --git a/public/react/src/modules/courses/coursesPublic/CoursesListType.js b/public/react/src/modules/courses/coursesPublic/CoursesListType.js index c8f38fca5..67d39a649 100644 --- a/public/react/src/modules/courses/coursesPublic/CoursesListType.js +++ b/public/react/src/modules/courses/coursesPublic/CoursesListType.js @@ -1,90 +1,91 @@ -import React, { Component } from 'react'; -import {Tooltip} from 'antd'; -class CoursesListType extends Component { - constructor(props) { - super(props); - this.state={ - // typelist:[], - // typesylename:"", - // tipval:"" - } - - } - - componentDidMount() { - // let{typelist,typesylename,tipval}=this.props; - // - // this.setState({ - // typelist:typelist, - // typesylename:typesylename, - // tipval:tipval - // }) - // console.log("CoursesListType") - // console.log(typelist) - } - - render() { - let {typelist,typesylename,tipval}=this.props; - - return( - - { - typelist===undefined?"":typelist.map((item,key)=>{ - return( - document.querySelector('.TabsWarp')}> - - {item==="公开"?公开:""} - {item==="已开启补交"?已开启补交:""} - {item==="未开启补交"?未开启补交:""} - {item==="匿名作品"?匿名作品:""} - {item==="已选择"?已选择:""} - {item==="已结束"?已结束:""} - {item==="提交中"?提交中:""} - {item==="匿评中"?匿评中:""} - {item==="申诉中"?申诉中:""} - {item==="补交中"?补交中:""} - {item==="评阅中"?评阅中:""} - {item==="待选中"?待选中:""} - {item==="交叉评阅中"?交叉评阅中:""} - {item==="已开启交叉评阅"?已开启交叉评阅:""} - {item==="待确认"?待确认:""} - {item==="待处理"?待处理:""} - {item==="未发布"?未发布:""} - {item==="私有"?私有:""} - {item==="未提交"?未提交:""} - {item==="已确认"?已确认:""} - {item==="已截止"?已截止:""} - - - ) - }) - } - - ) - } -} -export default CoursesListType; - - -// let typelist=["公开", -// "已开启补交", -// "未开启补交", -// "匿名作品", -// "已选择", -// "已结束", -// "提交中", -// "匿评中", -// "申诉中", -// "补交中", -// "评阅中", -// "待选中", -// "交叉评阅中", -// "已开启交叉评阅", -// "待确认", -// "待处理", -// "未发布", -// "私有", -// "未提交", -// "已确认", -// "已截止", +import React, { Component } from 'react'; +import {Tooltip} from 'antd' +import '../css/Courses.css'; +class CoursesListType extends Component { + constructor(props) { + super(props); + this.state={ + // typelist:[], + // typesylename:"", + // tipval:"" + } + + } + + componentDidMount() { + // let{typelist,typesylename,tipval}=this.props; + // + // this.setState({ + // typelist:typelist, + // typesylename:typesylename, + // tipval:tipval + // }) + // console.log("CoursesListType") + // console.log(typelist) + } + + render() { + let {typelist,typesylename,tipval}=this.props; + + return( + + { + typelist===undefined?"":typelist.map((item,key)=>{ + return( + document.querySelector('.TabsWarp')}> + + {item==="公开"?公开:""} + {item==="已开启补交"?已开启补交:""} + {item==="未开启补交"?未开启补交:""} + {item==="匿名作品"?匿名作品:""} + {item==="已选择"?已选择:""} + {item==="已结束"?已结束:""} + {item==="提交中"?提交中:""} + {item==="匿评中"?匿评中:""} + {item==="申诉中"?申诉中:""} + {item==="补交中"?补交中:""} + {item==="评阅中"?评阅中:""} + {item==="待选中"?待选中:""} + {item==="交叉评阅中"?交叉评阅中:""} + {item==="已开启交叉评阅"?已开启交叉评阅:""} + {item==="待确认"?待确认:""} + {item==="待处理"?待处理:""} + {item==="未发布"?未发布:""} + {item==="私有"?私有:""} + {item==="未提交"?未提交:""} + {item==="已确认"?已确认:""} + {item==="已截止"?已截止:""} + + + ) + }) + } + + ) + } +} +export default CoursesListType; + + +// let typelist=["公开", +// "已开启补交", +// "未开启补交", +// "匿名作品", +// "已选择", +// "已结束", +// "提交中", +// "匿评中", +// "申诉中", +// "补交中", +// "评阅中", +// "待选中", +// "交叉评阅中", +// "已开启交叉评阅", +// "待确认", +// "待处理", +// "未发布", +// "私有", +// "未提交", +// "已确认", +// "已截止", // ] \ No newline at end of file diff --git a/public/react/src/modules/courses/coursesPublic/SelectSetting.js b/public/react/src/modules/courses/coursesPublic/SelectSetting.js index 0bb06fccb..2b4b935ba 100644 --- a/public/react/src/modules/courses/coursesPublic/SelectSetting.js +++ b/public/react/src/modules/courses/coursesPublic/SelectSetting.js @@ -613,7 +613,7 @@ class Selectsetting extends Component{ {item.name} - {item.response===undefined?"":isNaN(this.props.bytesToSize(item.response.filesize))?"":this.props.bytesToSize(item.response.filesize)} + {item.response===undefined?"":isNaN(this.props.bytesToSize(item.response.filesize))?"123":this.props.bytesToSize(item.response.filesize)} { if(result.data.status===0){ - this.setState({ - Modalstype:true, - Modalstopval:result.data.message, - cardsModalsavetype:this.cannerassocition, - loadtype:true - }) + // this.setState({ + // Modalstype:true, + // Modalstopval:result.data.message, + // cardsModalsavetype:this.cannerassocition, + // loadtype:true + // }) this.props.funlist() } @@ -224,11 +224,11 @@ class GraduateTaskItem extends Component{ {/* {discussMessage.author.name} */} - {discussMessage.commit_count===undefined?"":{discussMessage.commit_count} 已交} - {discussMessage.uncommit_count===undefined?"":{discussMessage.uncommit_count} 未交} + {discussMessage.commit_count===undefined?"":{discussMessage.commit_count} 已交} + {discussMessage.uncommit_count===undefined?"":{discussMessage.uncommit_count} 未交} {/*{discussMessage.replies_count} 3 未评*/} - {discussMessage.status_time} + {discussMessage.status_time} {/* { discussMessage.replies_count != 0 && {discussMessage.replies_count} 回复 } diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js index a4202b6da..1ba465dfe 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksSubmitedit.js @@ -2,7 +2,7 @@ import React,{Component} from "React"; import { Form, Select, Input, Button,Checkbox,Upload,Icon,message,Modal,Spin,Tooltip} from "antd"; import {Link} from 'react-router-dom'; import TPMMDEditor from '../../../tpm/challengesnew/TPMMDEditor'; -import { WordsBtn,getUrl } from 'educoder'; +import { WordsBtn,getUrl ,bytesToSize} from 'educoder'; import axios from 'axios'; import Modals from '../../../modals/Modals'; const Search = Input.Search; @@ -577,7 +577,7 @@ class GraduationTasksSubmitedit extends Component{ {item.name} - {item.response===undefined?"":isNaN(this.props.bytesToSize(item.response.filesize))?"":this.props.bytesToSize(item.response.filesize)} + {item.response===undefined?"":bytesToSize(item.size)} { - const url = `/attachments/${file.response ? file.response.id : file.uid}.json` + const url = `/attachments/${file}.json` axios.delete(url, { }) .then((response) => { @@ -446,7 +446,7 @@ render(){ multiple: true, // https://github.com/ant-design/ant-design/issues/15505 // showUploadList={false},然后外部拿到 fileList 数组自行渲染列表。 - // showUploadList: false, + showUploadList: false, action: `${getUrl()}/api/attachments.json`, onChange: this.handleChange, onRemove: this.onAttachmentRemove, @@ -545,7 +545,39 @@ render(){ (单个文件150M以内) -
+ + {this.state.fileList.length===0?"":this.state.fileList.map((item,key)=>{ + return( +

+ + + + + {item.name} + + + {item.response===undefined?"":bytesToSize(item.size)} + + +

+ ) + })} + +
diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js index f7f843feb..ce7822d97 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js @@ -135,7 +135,7 @@ class GraduationTasksappraise extends Component{ let category_id=this.props.match.params.category_id; let graduation_id=datalist===undefined?"":datalist.graduation_id; let task_id=datalist===undefined?"":datalist.task_id; - console.log(datalist); + // console.log(datalist); return( @@ -197,7 +197,7 @@ class GraduationTasksappraise extends Component{
-
+
内容 @@ -249,8 +249,8 @@ class GraduationTasksappraise extends Component{
{firelistdata===undefined?"":firelistdata.length===0?"":firelistdata.revise_attachments.length===0?"": -
-
+
+
补交附件
@@ -258,7 +258,7 @@ class GraduationTasksappraise extends Component{
-
+
{firelistdata===undefined?"":firelistdata.length===0?"":firelistdata.revise_attachments.map((item,key)=>{ return( @@ -291,7 +291,7 @@ class GraduationTasksappraise extends Component{
} {datalist&&datalist.project_info===undefined?"": -
+
关联项目
@@ -301,7 +301,7 @@ class GraduationTasksappraise extends Component{
} {/*{*/} { datalist === undefined?"": datalist && datalist.task_type===undefined ?"" : datalist.task_type===1? "": datalist && datalist.work_members && datalist.work_members.length == 0 ?"": -
+
其他组员
diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js index 24da98576..b4aec1355 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssetting.js @@ -317,73 +317,59 @@ class GraduationTaskssettingapp extends Component{ } funcrosscomment=(e)=>{ - let {latetime,end_time}=this.state; + + let {latetime,end_time,allowlate}=this.state; let newtime; - if(latetime!=null&&end_time!=null){ - if(e.target.checked===true){ - if(moment(latetime)>moment(end_time)){ - newtime=moment(latetime)+604800000; - newtime=new Date(newtime) - }else if(moment(latetime){ diff --git a/public/react/src/modules/courses/members/studentsList.js b/public/react/src/modules/courses/members/studentsList.js index cd97c6cfa..d997592ef 100644 --- a/public/react/src/modules/courses/members/studentsList.js +++ b/public/react/src/modules/courses/members/studentsList.js @@ -550,7 +550,7 @@ class studentsList extends Component{ { - total_count > 0 ? + total_count > 0 || this.state.isSpin == true ?
{isAdmin && 已选 {checkBoxValues.length} 个} diff --git a/public/react/src/modules/courses/members/teacherList.js b/public/react/src/modules/courses/members/teacherList.js index 15afd4bee..19bb74d44 100644 --- a/public/react/src/modules/courses/members/teacherList.js +++ b/public/react/src/modules/courses/members/teacherList.js @@ -33,6 +33,7 @@ function buildColumns(that) { const { course_groups } = that.state const columns = [{ title: '序号', + width: 28, // dataIndex: 'name', key: 'index', render: (content, item, index) => { @@ -40,12 +41,13 @@ function buildColumns(that) { } },{ title: '用户ID', + width: 82, dataIndex: 'login', key: 'login' }, { title: '姓名', dataIndex: 'name', - width: 160, + width: 140, key: 'name', render: (name, record) => { return {name} @@ -57,7 +59,7 @@ function buildColumns(that) { }] that.state.course_groups && that.state.course_groups.length && columns.push({ title: 管理权限, - width: 230, + // width: 230, key: 'course_groups', dataIndex: 'course_groups', // onClick={() => that.joinCourseGroup(item.id)} @@ -113,6 +115,7 @@ function buildColumns(that) { if (hasGraduationModule) { columns.push({ title: '答辩组', + width: 74, key: 'graduation_group', dataIndex: 'graduation_group', render: text => ( @@ -126,6 +129,7 @@ function buildColumns(that) { columns.push({ title: '操作', key: 'action', + width: 150, align:'center', render: (text, record) => { if (record.application_id) { diff --git a/public/react/src/modules/forums/MemoDetailMDEditor.js b/public/react/src/modules/forums/MemoDetailMDEditor.js index e1811ed8a..6fd650cea 100644 --- a/public/react/src/modules/forums/MemoDetailMDEditor.js +++ b/public/react/src/modules/forums/MemoDetailMDEditor.js @@ -148,13 +148,13 @@ class MemoDetailMDEditor extends Component { margin-right: 0px !important; } .commentInput { - border-bottom: 1px solid #EEEEEE; } .commentInput .editormd{ width:100%!important; } `} -
+
diff --git a/public/react/src/modules/forums/RightSection.css b/public/react/src/modules/forums/RightSection.css index bce57c68a..f151585c8 100644 --- a/public/react/src/modules/forums/RightSection.css +++ b/public/react/src/modules/forums/RightSection.css @@ -7,7 +7,7 @@ width:237px!important; height: 30px; margin-bottom: 30px; - margin-right: 35px; + /*margin-right: 35px;*/ } .search-newysl { width:237px!important; diff --git a/public/react/src/modules/page/MainContent.js b/public/react/src/modules/page/MainContent.js index bb1cd11fc..3fcaa55fd 100644 --- a/public/react/src/modules/page/MainContent.js +++ b/public/react/src/modules/page/MainContent.js @@ -33,7 +33,7 @@ class MainContent extends Component { } render() { const { challenge, output_sets, onRunCodeTest, latest_output, record, st, readRepoTimeout, - onTestSetHeaderClick, loading, codeLoading, shixun} = this.props + onTestSetHeaderClick, loading, codeLoading, shixun, vnc_url} = this.props // if (output_sets && output_sets.test_sets) { // const test_sets_array = JSON.parse("[" + output_sets.test_sets + "]"); @@ -86,9 +86,11 @@ class MainContent extends Component {
*/} - {/* { showIframeContent && vnc_url ? */} + > + : +
@@ -143,6 +145,9 @@ class MainContent extends Component {
+ + + }
diff --git a/public/react/src/modules/page/VNCDisplay.js b/public/react/src/modules/page/VNCDisplay.js index b8840fe02..1e443ed1d 100644 --- a/public/react/src/modules/page/VNCDisplay.js +++ b/public/react/src/modules/page/VNCDisplay.js @@ -1,154 +1,154 @@ -// import React, { Component } from 'react'; +import React, { Component } from 'react'; -// import RFB from '@novnc/novnc/lib/rfb.js'; +import RFB from '@novnc/novnc/lib/rfb.js'; -// const $ = window.$; -// // const showIframeContent = window.location.search.indexOf('vnc=1') != -1; -// class VNCDisplay extends Component { -// componentDidMount() { -// console.log(RFB) +const $ = window.$; +// const showIframeContent = window.location.search.indexOf('vnc=1') != -1; +class VNCDisplay extends Component { + componentDidMount() { + console.log(RFB) -// let rfb; -// let desktopName; -// // When this function is called we have -// // successfully connected to a server -// function connectedToServer(e) { -// status("Connected to " + desktopName); -// } -// // This function is called when we are disconnected -// function disconnectedFromServer(e) { -// if (e.detail.clean) { -// status("Disconnected"); -// } else { -// status("Something went wrong, connection is closed"); -// } -// } -// // When this function is called, the server requires -// // credentials to authenticate -// function credentialsAreRequired(e) { -// const password = prompt("Password Required:"); -// rfb.sendCredentials({ password: password }); -// } -// // When this function is called we have received -// // a desktop name from the server -// function updateDesktopName(e) { -// desktopName = e.detail.name; -// } -// // Since most operating systems will catch Ctrl+Alt+Del -// // before they get a chance to be intercepted by the browser, -// // we provide a way to emulate this key sequence. -// function sendCtrlAltDel() { -// rfb.sendCtrlAltDel(); -// return false; -// } -// // Show a status text in the top bar -// function status(text) { -// document.getElementById('status').textContent = text; -// } -// // This function extracts the value of one variable from the -// // query string. If the variable isn't defined in the URL -// // it returns the default value instead. -// function readQueryVariable(name, defaultValue) { -// // A URL with a query parameter can look like this: -// // https://www.example.com?myqueryparam=myvalue -// // -// // Note that we use location.href instead of location.search -// // because Firefox < 53 has a bug w.r.t location.search -// const re = new RegExp('.*[?&]' + name + '=([^&#]*)'), -// match = document.location.href.match(re); -// if (typeof defaultValue === 'undefined') { defaultValue = null; } -// if (match) { -// // We have to decode the URL since want the cleartext value -// return decodeURIComponent(match[1]); -// } -// return defaultValue; -// } -// document.getElementById('sendCtrlAltDelButton') -// .onclick = sendCtrlAltDel; -// // Read parameters specified in the URL query string -// // By default, use the host and port of server that served this file + let rfb; + let desktopName; + // When this function is called we have + // successfully connected to a server + function connectedToServer(e) { + status("Connected to " + desktopName); + } + // This function is called when we are disconnected + function disconnectedFromServer(e) { + if (e.detail.clean) { + status("Disconnected"); + } else { + status("Something went wrong, connection is closed"); + } + } + // When this function is called, the server requires + // credentials to authenticate + function credentialsAreRequired(e) { + const password = prompt("Password Required:"); + rfb.sendCredentials({ password: password }); + } + // When this function is called we have received + // a desktop name from the server + function updateDesktopName(e) { + desktopName = e.detail.name; + } + // Since most operating systems will catch Ctrl+Alt+Del + // before they get a chance to be intercepted by the browser, + // we provide a way to emulate this key sequence. + function sendCtrlAltDel() { + rfb.sendCtrlAltDel(); + return false; + } + // Show a status text in the top bar + function status(text) { + document.getElementById('status').textContent = text; + } + // This function extracts the value of one variable from the + // query string. If the variable isn't defined in the URL + // it returns the default value instead. + function readQueryVariable(name, defaultValue) { + // A URL with a query parameter can look like this: + // https://www.example.com?myqueryparam=myvalue + // + // Note that we use location.href instead of location.search + // because Firefox < 53 has a bug w.r.t location.search + const re = new RegExp('.*[?&]' + name + '=([^&#]*)'), + match = document.location.href.match(re); + if (typeof defaultValue === 'undefined') { defaultValue = null; } + if (match) { + // We have to decode the URL since want the cleartext value + return decodeURIComponent(match[1]); + } + return defaultValue; + } + document.getElementById('sendCtrlAltDelButton') + .onclick = sendCtrlAltDel; + // Read parameters specified in the URL query string + // By default, use the host and port of server that served this file -// // const host = readQueryVariable('host', window.location.hostname); -// // let port = readQueryVariable('port', window.location.port); -// // const password = readQueryVariable('password', ''); + // const host = readQueryVariable('host', window.location.hostname); + // let port = readQueryVariable('port', window.location.port); + // const password = readQueryVariable('password', ''); -// const { vnc_url } = this.props; -// // http://117.50.12.63:43149/vnc_lite.html?password=headless -// let _ar1 = vnc_url.split('/'); -// let ipAndPort = _ar1[2].split(':') -// let passwordAr = _ar1[3].split('password=') -// const host = ipAndPort[0] -// let port = ipAndPort[1] -// const password = passwordAr[1].split('&')[0] + const { vnc_url } = this.props; + // http://117.50.12.63:43149/vnc_lite.html?password=headless + let _ar1 = vnc_url.split('/'); + let ipAndPort = _ar1[2].split(':') + let passwordAr = _ar1[3].split('password=') + const host = ipAndPort[0] + let port = ipAndPort[1] + const password = passwordAr[1].split('&')[0] -// const path = readQueryVariable('path', 'websockify'); -// // | | | | | | -// // | | | Connect | | | -// // v v v v v v -// status("Connecting"); -// // Build the websocket URL used to connect -// let url; -// if (vnc_url.indexOf("https:") != -1) { -// url = 'wss'; -// } else { -// url = 'ws'; -// } -// url += '://' + host; -// if(port) { -// url += ':' + port; -// } -// url += '/' + path; -// // Creating a new RFB object will start a new connection -// rfb = new RFB(document.getElementById('screen'), url, -// { credentials: { password: password } }); -// // Add listeners to important events from the RFB module -// rfb.addEventListener("connect", connectedToServer); -// rfb.addEventListener("disconnect", disconnectedFromServer); -// rfb.addEventListener("credentialsrequired", credentialsAreRequired); -// rfb.addEventListener("desktopname", updateDesktopName); -// // Set parameters that can be changed on an active connection -// rfb.viewOnly = readQueryVariable('view_only', false); -// rfb.scaleViewport = readQueryVariable('scale', false); -// } + const path = readQueryVariable('path', 'websockify'); + // | | | | | | + // | | | Connect | | | + // v v v v v v + status("Connecting"); + // Build the websocket URL used to connect + let url; + if (vnc_url.indexOf("https:") != -1) { + url = 'wss'; + } else { + url = 'ws'; + } + url += '://' + host; + if(port) { + url += ':' + port; + } + url += '/' + path; + // Creating a new RFB object will start a new connection + rfb = new RFB(document.getElementById('screen'), url, + { credentials: { password: password } }); + // Add listeners to important events from the RFB module + rfb.addEventListener("connect", connectedToServer); + rfb.addEventListener("disconnect", disconnectedFromServer); + rfb.addEventListener("credentialsrequired", credentialsAreRequired); + rfb.addEventListener("desktopname", updateDesktopName); + // Set parameters that can be changed on an active connection + rfb.viewOnly = readQueryVariable('view_only', false); + rfb.scaleViewport = readQueryVariable('scale', false); + } -// render() { -// const { challenge, vnc_url } = this.props + render() { + const { challenge, vnc_url } = this.props -// return ( -//
-// -//
-//
Loading
-//
Send CtrlAltDel
-//
-//
-//
-// ); -// } -// } + return ( +
+ +
+
Loading
+
Send CtrlAltDel
+
+
+
+ ); + } +} -// export default VNCDisplay; +export default VNCDisplay; diff --git a/public/react/src/modules/page/main/CodeEvaluateView.js b/public/react/src/modules/page/main/CodeEvaluateView.js index b2e83c41b..8f28a8c63 100644 --- a/public/react/src/modules/page/main/CodeEvaluateView.js +++ b/public/react/src/modules/page/main/CodeEvaluateView.js @@ -192,16 +192,23 @@ class CodeEvaluateView extends Component {
{`已经过职业认证的教师可以免金币查看隐藏测试集。`}
{`解锁本关所有测试集需要扣除${challenge.score*5}金币,确定要解锁吗?`}
+
this.goToCertification()} style={{color: '#4CACFF', cursor: 'pointer', 'text-decoration': 'underline' + , 'margin-top': '12px'}}>立即认证
: - `解锁本关所有测试集需要扣除${challenge.score*5}金币,确定要解锁吗?` + +
{`解锁本关所有测试集需要扣除${challenge.score*5}金币`}
+
{`确定要解锁吗?`}
+
const moreButtonsRender = () => { - return (power === 0 && user.is_teacher) ? ( - - ) : '' + return '' + // ${this.props.classes.button} + // return (power === 0 && user.is_teacher) ? ( + // + // ) : '' } testSetsComponentArray.push(
diff --git a/public/react/src/modules/page/tpiPage.css b/public/react/src/modules/page/tpiPage.css index 34274907e..4fc4e3062 100644 --- a/public/react/src/modules/page/tpiPage.css +++ b/public/react/src/modules/page/tpiPage.css @@ -229,6 +229,9 @@ body>div[role=dialog]>div { /* padding-bottom: 10px; */ } /* tpi 窗口宽度*/ +#tpi-dialog>div[role=document] { + border-radius: 10px; +} body>div[role=dialog] div[role=document] { min-width: 400px; } diff --git a/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js b/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js index 4af26d698..e86923cbc 100644 --- a/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js +++ b/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js @@ -7,6 +7,7 @@ import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom"; // import "antd/dist/antd.css"; import { getImageUrl, toPath, getUrl } from 'educoder'; +import '../../courses/css/Courses.css' import axios from 'axios';