From ed5c3c8a1a173cf109cc6c509e76f7a9a94ac3d5 Mon Sep 17 00:00:00 2001 From: hjm <63528605@qq.com> Date: Tue, 25 Jun 2019 11:07:06 +0800 Subject: [PATCH 01/15] vnc --- public/react/src/modules/page/MainContent.js | 11 +- public/react/src/modules/page/VNCDisplay.js | 288 +++++++++---------- 2 files changed, 152 insertions(+), 147 deletions(-) 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; From 7645300243db26eb3e5653e0a4e20beb9aed40fc Mon Sep 17 00:00:00 2001 From: hjm <63528605@qq.com> Date: Tue, 25 Jun 2019 14:06:13 +0800 Subject: [PATCH 02/15] =?UTF-8?q?=E7=AB=8B=E5=8D=B3=E8=AE=A4=E8=AF=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/context/TPIContextProvider.js | 9 +++++++-- .../src/modules/page/main/CodeEvaluateView.js | 16 ++++++++++------ 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/public/react/src/context/TPIContextProvider.js b/public/react/src/context/TPIContextProvider.js index 60d63a1bd..da8ddc724 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 @@ -514,6 +514,10 @@ pop_box_new(htmlvalue, 480, 182); currentGamePassed: false, // 切换game时重置passed字段 }) + 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} + 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 // withCredentials: true, @@ -835,7 +839,8 @@ pop_box_new(htmlvalue, 480, 182); {this.state.gDialogContentText} - + {/* mb20 加了有样式问题 */} + { this.isSingleButton ?
{`已经过职业认证的教师可以免金币查看隐藏测试集。`}
{`解锁本关所有测试集需要扣除${challenge.score*5}金币,确定要解锁吗?`}
+
this.goToCertification()} style={{color: '#4CACFF', cursor: 'pointer', 'text-decoration': 'underline' + , 'margin-top': '12px'}}>立即认证
: `解锁本关所有测试集需要扣除${challenge.score*5}金币,确定要解锁吗?` const moreButtonsRender = () => { - return (power === 0 && user.is_teacher) ? ( - - ) : '' + return '' + // ${this.props.classes.button} + // return (power === 0 && user.is_teacher) ? ( + // + // ) : '' } testSetsComponentArray.push(
From 24fe9413f8d963f19f6365394d83b7afc4c32431 Mon Sep 17 00:00:00 2001 From: hjm <63528605@qq.com> Date: Tue, 25 Jun 2019 14:11:02 +0800 Subject: [PATCH 03/15] test --- public/react/src/context/TPIContextProvider.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/public/react/src/context/TPIContextProvider.js b/public/react/src/context/TPIContextProvider.js index da8ddc724..6db04f1b8 100644 --- a/public/react/src/context/TPIContextProvider.js +++ b/public/react/src/context/TPIContextProvider.js @@ -513,10 +513,11 @@ pop_box_new(htmlvalue, 480, 182); loading: true, currentGamePassed: false, // 切换game时重置passed字段 }) - - 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} - this._handleResponseData(data) - return + + // 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} + // 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 From d6496418b2994cefc0e75bae63aa26bfdb5f7ef5 Mon Sep 17 00:00:00 2001 From: hjm <63528605@qq.com> Date: Tue, 25 Jun 2019 14:19:05 +0800 Subject: [PATCH 04/15] radius --- public/react/src/modules/page/main/CodeEvaluateView.js | 5 ++++- public/react/src/modules/page/tpiPage.css | 3 +++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/public/react/src/modules/page/main/CodeEvaluateView.js b/public/react/src/modules/page/main/CodeEvaluateView.js index 8466b63c7..8f28a8c63 100644 --- a/public/react/src/modules/page/main/CodeEvaluateView.js +++ b/public/react/src/modules/page/main/CodeEvaluateView.js @@ -195,7 +195,10 @@ class CodeEvaluateView extends Component {
this.goToCertification()} style={{color: '#4CACFF', cursor: 'pointer', 'text-decoration': 'underline' , 'margin-top': '12px'}}>立即认证
: - `解锁本关所有测试集需要扣除${challenge.score*5}金币,确定要解锁吗?` + +
{`解锁本关所有测试集需要扣除${challenge.score*5}金币`}
+
{`确定要解锁吗?`}
+
const moreButtonsRender = () => { return '' 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; } From 3ddcabf116fe0c96c202209997cf406094f77b73 Mon Sep 17 00:00:00 2001 From: hjm <63528605@qq.com> Date: Tue, 25 Jun 2019 14:59:07 +0800 Subject: [PATCH 05/15] 24px --- public/react/src/modules/comment/Comment.css | 1 + 1 file changed, 1 insertion(+) diff --git a/public/react/src/modules/comment/Comment.css b/public/react/src/modules/comment/Comment.css index f7b52366d..2f85846b6 100644 --- a/public/react/src/modules/comment/Comment.css +++ b/public/react/src/modules/comment/Comment.css @@ -106,6 +106,7 @@ position: absolute; top: -30px; left: -30px; + left: -24px; z-index: 999; } From 66ea00a7def21d437ae62ea85259d5881e46574e Mon Sep 17 00:00:00 2001 From: hjm <63528605@qq.com> Date: Tue, 25 Jun 2019 15:02:45 +0800 Subject: [PATCH 06/15] test --- public/react/src/context/TPIContextProvider.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/public/react/src/context/TPIContextProvider.js b/public/react/src/context/TPIContextProvider.js index 6db04f1b8..0b764202f 100644 --- a/public/react/src/context/TPIContextProvider.js +++ b/public/react/src/context/TPIContextProvider.js @@ -516,6 +516,9 @@ pop_box_new(htmlvalue, 480, 182); // 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 From 321e902baf12ed84acd2f0a23951cea5297f64a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Tue, 25 Jun 2019 16:22:36 +0800 Subject: [PATCH 07/15] =?UTF-8?q?=20=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../courses/coursesPublic/SelectSetting.js | 2 +- .../tasks/GraduationTasksSubmitedit.js | 4 +- .../tasks/GraduationTasksSubmitnew.js | 40 ++++++- .../tasks/GraduationTasksappraise.js | 2 +- .../tasks/GraduationTaskssetting.js | 113 ++++++++---------- .../react/src/modules/forums/RightSection.css | 2 +- 6 files changed, 90 insertions(+), 73 deletions(-) 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)} - {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..28955e268 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js @@ -258,7 +258,7 @@ class GraduationTasksappraise extends Component{ -
+
{firelistdata===undefined?"":firelistdata.length===0?"":firelistdata.revise_attachments.map((item,key)=>{ return( 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) Date: Tue, 25 Jun 2019 16:32:36 +0800 Subject: [PATCH 08/15] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E7=9B=AE=E5=BD=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/courses/boards/AddDirModal.js | 78 +++++++++++++++++++ .../src/modules/courses/boards/BoardsNew.js | 45 ++++++++--- .../modules/courses/members/teacherList.js | 8 +- 3 files changed, 119 insertions(+), 12 deletions(-) create mode 100644 public/react/src/modules/courses/boards/AddDirModal.js diff --git a/public/react/src/modules/courses/boards/AddDirModal.js b/public/react/src/modules/courses/boards/AddDirModal.js new file mode 100644 index 000000000..89ff6dfeb --- /dev/null +++ b/public/react/src/modules/courses/boards/AddDirModal.js @@ -0,0 +1,78 @@ +import React,{ Component } from "react"; +import {Tooltip, Modal, Input } from 'antd' +import moment from 'moment' +import { getUrl, WordsBtn } from 'educoder' +import axios from 'axios' +class AddDirModal extends Component{ + constructor(props){ + super(props); + this.state = { + + } + } + onInput = (e) => { + 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 */}
-
+
From 71bb54550709a0b059af193dd4ea24b6c6436703 Mon Sep 17 00:00:00 2001 From: caishi <1149225589@qq.com> Date: Tue, 25 Jun 2019 17:11:33 +0800 Subject: [PATCH 11/15] =?UTF-8?q?=E6=96=B0=E8=AF=BE=E5=A0=82=E6=8C=87?= =?UTF-8?q?=E5=BC=95=E7=AC=AC=E4=B8=80=E9=A1=B5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/images/course/guide/1-1.png | Bin 0 -> 10691 bytes public/images/course/guide/1-2.png | Bin 0 -> 14301 bytes public/images/course/guide/1-3.png | Bin 0 -> 9862 bytes public/images/course/guide/1-4.png | Bin 0 -> 24857 bytes public/images/course/guide/1-5.png | Bin 0 -> 2660 bytes public/images/course/guide/1-6.png | Bin 0 -> 2689 bytes public/images/course/guide/1-7.png | Bin 0 -> 1267 bytes .../courses/coursesDetail/CoursesBanner.js | 10 ++-- .../courses/coursesDetail/CoursesGuide.js | 44 ++++++++++++++++++ .../react/src/modules/courses/css/Courses.css | 20 ++++++++ .../graduation/tasks/GraduateTaskItem.js | 6 +-- .../modules/tpm/challengesnew/TPMMDEditor.js | 1 + 12 files changed, 75 insertions(+), 6 deletions(-) create mode 100644 public/images/course/guide/1-1.png create mode 100644 public/images/course/guide/1-2.png create mode 100644 public/images/course/guide/1-3.png create mode 100644 public/images/course/guide/1-4.png create mode 100644 public/images/course/guide/1-5.png create mode 100644 public/images/course/guide/1-6.png create mode 100644 public/images/course/guide/1-7.png create mode 100644 public/react/src/modules/courses/coursesDetail/CoursesGuide.js diff --git a/public/images/course/guide/1-1.png b/public/images/course/guide/1-1.png new file mode 100644 index 0000000000000000000000000000000000000000..c59467c5d5daa4c8a69bbe0d6bc97a5c37cee942 GIT binary patch literal 10691 zcmV;!DLmGRP)gNtzuED zb*Z(j^r^VD3L-8@tO~M}B_LbOW&$Lf`^@srdFMSd=bR63`#jfj{z$&>oH;Y^yz~3L z%gmhf1;CD$mX?w2?d_KbK`;&g{#0CCe4{AR*w}b606fHsKU7>?eCgind-d}L!bd9r ztPR6(L4JPzz1_Qae~)55z%OAKc4=yAx*Gtd005rfONhM&;osRH?goIfii?YXk35mY zsI9H-)W3iK=K?bfZ^eE{$ud3kxK6crWKeo+;&w_kfTkW~X=7zRNQgwBvm zoZPf&Q(2!reKyY+Jb6fdL8sdT2>ufw><;3VAP*oEAMkz?&FT8Y_W&RiUQB!xpT!5O zy>wY);)(j`N#AE(wUki@mH3&qD*J+EiRiRj_}O*8tUJ^q>5Alct`E|vxD?ZcE>Gn# z@iEhz)TI%MRqRqJ%Ev2DkWp5XWvm=!Tsln~Y19cF3qCHES!WfxL=`#`x-xw+ir3gg zY*2mjdc$S_m>=#8ZoGc;+?9B>xw-ksf`Wp^m6AL+ZMvEG1squ zbVXxh<75C35!g?ImX?;Ix_0gQaS#LzqMDfpUGp>q;aLio+H1rt4;>H}8Tfr#JKp|~ z3(`Um3u##m)VR1#22_^O*Ni1kv!*f2l0l1mQe?N{xD-ctY5c6ud#m)wA2Se1W;l!2 zKwUdLZ!X=9jg!7PD@Tz)u6n59vb=3B0`5WCFnp$Z{lgO*8XArXf?$zI_k+g9#+?AL zPg`4CQCV48^UR@FH$nhKk#})5M3iii3AIDQ4LY7)FuRz9KqG{-LP8>!bL~ybC5lQw1DjM?*h&WHY4sYMc=^;1oM^Z?^MTm*ZS(n9w zq$(`F)Fos@xm_|*2jj~}tbRLmvq!T}|6~#*Vb0QrmV*=9JGR7{T2V+GbJgn~P9e;Y zt1_An$H2P;q@8xwOnXi(Co%PO(av6Yjf6;(I*AwltpvIE)Oe=Z3PXJDm81yx8A*{~OMUj&)h;&>9)p2|X>4qKNrq%G z4>ROSqNyaGg~=hV>U$JyolXJ|USt1dGL7fN>{-S|Gb_=|B3stc%(a}y3i~`S^%lG- zIUFwU-~o{rKn#%1oPry&lzzKN#Eqqt-*M6qgY_>Lua^s1Xjf9mPY5HWbmTBshS6Gq zkb;_{1dAoA^BPC0d{-d^L6UXlVHjFvEuR!E&CPfQ-MTMN7osvJfh9wm9D4{5#E&bI zqtzn$6Fnf8gIX32)GVaWKp4KDNXf7#W04f$W)b^gqs&f7JWD@AeUaVBPbh%7V&a$%Iab{D{D)2TS|vPrkZ0gwa;W|&M- zLISFOa~Z@*E*!Y@;Px3ry9w$0d=;gX#?` z>Gv;O4!%5Uh7#IpoP=f`!xGzC;c_Ta6mEg(ckWrzd@hm$y`rd#5yrWTnzA8-NAM1W z>w*j9K1=B{cbrHmNbp^D8UP|6j)wsz>N`QMm=R1Hqm0+BgyWG2gn>jRV*okOurbW>lESkzAhPQeZ^pV)nFt9i{kyC+ z*DobK@vg3Dz!5egVXzjiLYO(|@-XsxG!){a!y9)f!L&j^AwO!OIQ6PM0@Z~T`shVe zQza5u*NGm4u3Q_PVY}#o90JgGT?=61mOS#Tk2RCSLB>HPz(z^!2yL9t)ns9Y4=5-@ z!gXqtsmFKOf>@+L7qxkR`C|+OGcm6q?&SpF9?o~2_c7_a)mhRTw~nhf{MzD(gD_L< zJF|?HY*u%M4!8w4T2aFOFf(8t#z+f;3wgMs7bhe5bg4M6yC|zmAdE|oG2^dK_!h_v z9!UJ|;t&TN?maW%qRVo62Eyn#Hk58N&--brB@bVjJcKNmraq_R@fzlIicVtU6CGqB zZjMe(6}MRHtN{t*Uxyi}3FE@6Yi+}TN4F=prK2I`gG_h*l527hDVP&_Z-Jg$B|5-F z9#b8*DgM)~_M{#&aGobd<#qHD89|!MVDhAyKQbVjCo@49R=LVKy#cZE+=J5cM$fqj zk7a$~LDIMq2SbAw3L&qPL}QHxjd=1T@iE#-&>bO+EFE8mLBhy}7~suU2Q!W3($`e= zqz(#J1hf8+tM{e@`d-T^u`TvkHTPmDhh>$By!1M?wisHOodk{fE6 zQz4mumP`=FSUFa!um1=N1iW|Un0g-61YeM3S~P8<^;khA?I!suJ5fA31Xh@S#?P%MjN*C~BoY(E-svhQb z(+M+RvT7RpMU9*|hZRaew3J5Q`hycAtVgn_P^Q@Kg5eQ0q+GEsckh|&cUe)22@}RR z28cH6wQgx7px1rm@p)<8C!=R3MC>Ia=%pR;ijN1e(3o`)Wxe)at*)xe0gc< zwU3ZDimjeUQK2sSpVBCoKNJ9*?<=GsVGrA%ZLX>N!31%Ej89iQxG)l?nVf^bb{V!8@ zIt-wd(-`ZeCABPggcbhCf9Js^F!IOe!Mgcx!MX<*%7TIv1>Fl_;KXsTZvGNz+uR84 z&23Qs$|@Kz^*HD;w4Wjjvl^cf)TAwuYRbblCe$#`$Q3#LA3 zZ8EKzC0{-X?>zJu*#71^n~VU^^XLO$#3f&rWfn|*Knm0I=yDiw$%It2w>5nRuif~V zEZ610ePQI)C&AETN1FR~G=B!mp8YG-)-13M4ggfmy3ASsCx2f9wKXr=dZ8s_4miy+ z0F;b45C&f}9y*nDbGEs&z6Dm!egW#=USnT(?Mk*}VMLK*8HJD48P{$j?n%>Y=E##1wsb))TPgHuJ_*CD)=FZy)~t!W;0Xi)MMR zn+x8sm+oZ*7rd!(jU zyVZhTU0~$TE`;s1YhcZ0aic$SEygK3QEQdvdW8aP8@ZAdDpT7(u2LE-qTi4+64;s?E)ibOoG)< z{SCIf@PRzvzNHlgTzi5f_u@&vuCnfK>d z|7vGz>x_h1q<}a7)(3%J!yDs-`BVaW@To_cx(^zEGz=PjIPf-GKW&DUk1As{ZpOLL zxwxzLWNW3DI{ofx(0f2XNuYa&PdD{Z!YrKo2WVKgSzg0-l)QrAQD5wia$NB+O_Ywx zjD6}G^7hxy7O($~A7h`oF7bNo4qtx93L;_r>oENDp@5k?VXWs)!Vs!vPm$h35C%O;V#C@KkGkn} zIDY!qWzm|^Q*FPHHp-(CSCm3#TWvznd{2EI z`!pd8UCW}Kq!U)wc>^WA!88ImA&fj3UxyKdp~7?e&?#pJwc>-Ii9!`c@Kn&dGgQvG z92Q?KT&X$^IPVwR-+$KX!jKzJf^G-&wg}Vtpq?;t#)YtA?hCNx_rlY8 z4ju;RwkxKJ5b846y1EV?8g~O(h>X{hN|+F!VrmqA)f}Ti%|aavx3&tB>JUsTz;2W# z#}LA(Zwtbl13Ow;;hrH=%qxJq92kXUk}x$YR8;2`!57Z`BfNIgZ~Xd^S2R9MG^4;# zGGYJ>o;pE>VZy7#2*a>9_G#^bCf-H573CsktmT;NKV~8UPqNfQB>fxH)?vyoiSFY0 zN@CZEr?JY}gc<(xN&0FCB8Oz%f^{Y0)hWQ^vQ}vo$A`!Pd zj7YxCp{8@KkPHb!n+*b}s<|xkFk`OIBy+!$4}%HcyBK;8><2O@xlrX&;*dmsL*+1v zFfYn;C;a##IBfhel3@2&RU3~a3mQD>4~Cq2ah6Q$j=Fz}$yr{Xco*1&Aopw7S=YUj zZgd%fMgimCT3L@yzSlpxD3-sZp`z)-jnKAy z8yxbZGok0O0ao$4SKgEPi6BhF@(n6i(MRbS6_PNEuN2`MhK6aaMc0uq{EiK^AH%CZ zdjd8*|92-ag?I2B0@UI#9)=aHnynK0xQDR|j=TL_7<%joc@pd7WD(aWVNfnCFY=ui z?wAKFA9;gGfgr_%TU>Upr9}j|Q`Rx|>2J#auTNCp)e(U{x~@Hp6()(Ybgx|Oc3mBD z%X({2^`=MVN&iZ}Bn*qm5<@Q*d`g~?9mm))5?5jvwqouA=r*uSOCQQGOdMh@MjSh~ zG(h=RDq-VGOQCGcp|E+O2+v+8Rv2LTEDGoVhTNn=sI+70R5e3aa^es;blR!%v+ywD zkR;S35riq|TnO!LVwNmAy6xW!gcodCzZE{7A%0pX`yr=%FICgP;^?t|Z<&ybLxAn! zQ@?BH3fhuqX~7Ui4ohV8vJwW%(Y6F3{&LG)FOgkx3G)AL@}0JaiGkR0r}i>7VMLC? zLM|G2L+BxtsGpLQwC74QX{e@et={;EJnLVF>36YW0A1j+`lYv~7&6iX3Mc_|bR+FyHzR#{$zZK8hk7{;sIwEzZu!#|18y}UQ%cPWIW z*F3D-q8193#&!XFHu_PoBW9gmyCGT|p`p*p=fos~t>3|?jWScnHOE{7t^W{H(l#Qh z=IEqf(dr^^D^<0{UrSHYvegAoE=8c z1OP}FY?Gyi05khtq-$iCsKvr$2|I1=J;S|W_EcYrd2rz zV>c>i$tLQMEGdU!)8ZnBn)2fRNCMbIwh2S!8h6KeFy>VR946 z%sooU$bm3q+IZM!U(dqj_GVZ)djZtHt#Z)#!Kbl#33uXCy-9hP1j1aX5MrKdq2*cr z;(f6Joh@L3h5!X+YFbv#GClh~lwUp;%0?dw+ul>16<$Dih&6Y=1pA+V6b$_8m!Q3E zCv1M>Lo1gMWg~ElSsIn3yFw`Ju((!O(j69Gq4SRbz~m%X+$(buK?LEoTGnjVQ4L?q z4WQ|Rjd1XFr|cPF;`osD*n|-)_F~ql*s|m{VU!oCm|6uVeNQb?)>LW_LnD9?plZ(L z*$Cr+np3X+#V~boSqN+*7>l40*2X@gL$I^%jO{S+Fd}|B>G1_qnx!AiGm{*~ z^Io#P!owgjJR?g*GeroQeDR^)^e8>dy-1i^mRJkWE5L4h{UbQ^n`glGWvgMw)&?j) zxe`8@^&Hf{h~6WJCFMw<^^dA;H>xYqEXV=pkA}X-9ia%L*K*{n*Ci8RF(Hh|P0Efw z*gH1D8}>M;A9S?tfZA_8?jJ*JpT^u$KlU!|!IO@Gvwo`95?;RN30QKgn%?d*VBcsq z>XrvU0uy6xZLlh)scC9On5oeEk9sW+_FJ#ROgvE~{bQ=_SXGbV;0um{mGc%`d(Zlv zG7Qdp@H<+r$6?8>YPDZ_J|xU7VwNoOd=r0n0}L8{gqn&TEPi8{9GO52F!mXpIfB^hVa=TyEY58f zM1OkG_L4<+NHDE<=`Cpcv;}(fFN2X^t&(An1oUXJRYkRD5k^ek-Xq$wksvL)@i1Z? z=F_PA`bCIUb0)(GB+O_rt!#UKB*3ag%V6!BA3$3}GxR7ggNjqeLQ!eYh-f+tSDsIW z$g38;2MrsyL19r>C?7slmKTQ%;jUM?m;${6(fGh2yEN)oSEO!*kvYqy_u2JQ{QIIX zEBc~NAx@rbgrOaD5|BSt$*JsTZ9!>Q7t>fgKyZ5!+5dWP^0;t*in^!&Rp z8FI@Mm7jw`l|aRY55_N_dnlszm`jhCa0CP zT)ez625&#PK$9ijfAxq6k6!S*Dqk{k01TNn0rv52w%pbXE9blb^>5Klwd^-_T!e9C z7{t2Rm=Q_8&SCu1%6%@-$Z*9~gh{@K%tVm{(hi@ka*U-nJPHFYKTd`{jjQUQdEHhc zw@CQgoAqW#0O&SwKWj`Hmi+_j7p#Dis-bY`w9}*)TJ^}wl1R$q5UVegKYobZKq*GL z*U>{&(l5fV&1wy$^vntwlF3O201!Kz#qMTKgz_uLL4H?J4?ySM#j>8&PyQ7)&Rb#= z%BYSR4tYM5USrs#^Z2@jx-1AGj+M_X(KBE+M1^+{GiBm%O$vzf zJuCY|-^!sN_l|km5efdV3y*^y{nS){TT=^cdT%wX{PiMY#iKq|Os|SfNVR_2;;A2% zqW{w;TP0>RXkuQ7(J@O%M;~H~(Vuy`~XO4>bbJcA>TO#c5H2gb@#qzO;J|->|7`w)K``flMo`e`uMg#DY0qf zM&CAT9x+BMVq4PKV*y?za3m#-v=4RoxN}xb>vFMog!xdIfM#7!Sj1A#TGOd;KM*E5{2dWR>*oA*=^JFD>gP7p>cD zA`9@huGmP#k-m)?qBj7!{OtmDW)0MI(aXpu`?@@_~~+rARxT zW@6c^i<}QudD^s=1ISp&CLR5@>Zb37!yJ~pVkrg}`V-(O1oZ_o^t_Q#>&F?zq_t@! zFM9PKWh3>XE@ViiR{B|~=)}zZbVx=$DAlL@?D;)(i!>blv{~P^EcdwH4C6>BWic^- zq55m=+}( z*WLC{J63;^MwqhmnYLZZ<9t)M_=d^IoMyzZpa+xII8s7eY;b_wI5kBSBoc1R#&c@B z5ngx0(huDv3*)j+ye3ztxkA|Fmf1BxEvLT6H5jg8i#fEIS!aaT6% zw?<@Q^~w8ab!(9)P zmIctmc$0oX7*%hi1&7VnNK&i}L%nn(t+RIOvKIBtasVt$5@me)w&9>^q23_2(Lmx3 z$?nUcGN4ZjoMiK@TD%IfS35G1$3nJ4)+|YGhA!GcDvlM7djb)YJQuyqyBCqyjb1|h zryAlWo07>jG6-At0!B&#&py7`tS%8F2f~O{B~&4b{%?as2^eaDWOrp*rF`3Jr~l$a zY?mZ9X29rjS&>AXbhLdhe&TL46V!N0BK7NILy}b{twmlj3nD3aaxw3|?r}wUEI^WF z000SoNklQzh2z{9CSWn6oo9;5=AZrAO=G$*zDv4KUrX|a>4T(HrV?oRNdg7$bKIW=SO#p4#5|Q5nMNSF5R(xhBW)ff z5|1o6=6u(46p?C^8o3;+vHV>0MZEx37)+T7T1J7ljCbWQ2u=?~fNy|oz{7rBOw7t* zoJ!pogIE1=!g0mA#)WQQ;$AY1B<4DqprAj`;WC_r&Bkdn$i#k`omv29>)d&;Z)!bB(LT`T zGB_E4Z>mEh>@wc2Hk0ahy%ty1kxH1`bq>R=4{t7;^ChKZ1s3!*YJDB1Epn7Nj0&#? zJy4DmcVQeoAoqT;>3<4v6SZh}$lVqh)A+VLTf0&dIpI$0j6zk&MO)srsuon`ipn>oB+VJ}0V~46+%2j|1ci=BhMX$}FoH zd9f%Yu$zz8Ya)f4M4#kUzBMr#&iVW!PGq<}bs+OE(VyLhgnAc&Sg{Jo4^j|MW%S{( z2R;LYzpZ4+LdKt&98*j+6L)c@`7ne$WF7N3(eF7$Qbl_ql7LP-mm_(cjO1GJ)lWkL z%#G;=&KUaQosdQN3pnC^AcRqN3m0UHi;HFHANTq?M{E|;;1-DYi|@-!sX1D831rS< z#@X7LqZ$#wr52x8o#eR9%wmEe$Js)h@9<8y#G6>Rl zEB~mcCX7}pwOQt~^#e#Y6rNG5s0zzQ$q7iMco;%Ipo z%Ue+Im79HV5eM@uDGgbhQjAx6vDU1t8A$DG$%1eUN36Wd7}y?4c}dl@(si`Q&f`mn ze*79qZ8^FX<4U}RVv|}4+L$kjGWR+PNU~U!>l$^#Xf2!`ZVx=n4@x2r6RoM}wHLzy z;<`!0vF2!8Vv_YZ#MK$w9m#IXJ{nq?jw=qJOet1N-z960%^a$G?HVEz;aeE?0?1T^ zgF|aaYmj|X$9Of?AU|)B(jlC00iU*{Ry)(!(OxRJqvN#wird=fS<~AXPNFr-z$mBR=!)lZ`=JN6u z?6qebi#7V##|)7IH9)aP9_ahUxN#(ek#G^;>9n**&*FI)zP-Ppq2byf2>KKi72Og9 zLF;$+J-aav@`~v5A@sSD7}lsqb+)TQ0ksmYLjeqr5R6(^Xu;#ELt^L<$|^umkHEF` z6&1GjU~8{ozaLAHPfa#pu3sre%ND9J@EQSmDCR5Y=#ebSm5A1eJZc~#3|&tAETm~tdl^}^et(|nj4m(k+Z{Aj zZ+onmN+4#*#LsXY5r$!9j~+eVyrJl8&*bHWXPU~bSdcEIXz-G!@+cr(-M2Rw>iew- zmfVHr8p(#BBhvFn0MOMcT}BF3Q5mvQ>5VSRn)0#@0&q`ML!7TEVHrOYPNM(QB#N;k zqTlBMdiuR$7LokcuVa#d*MSj0(gKjEGq(jIS1Z)mr1!)wLA8!i1&J=CzR3^y8VkUt z2_-p5n2?tTyYus)H9!BEo7c~sxPANfBl7d}|0^#q@A;sipw>^#@VN6I_zj*?MthxnxMk<+INIc4cP(DaCgW2_KuDlfBEs;mG$-YBMJ%% zUJt{tQ(j))QL?+}Wx_CA*U{1OrJg-|iWg(;J@#tg-&zCB&CSDi@810f@f%+NaDQ=e z@#T^*b#--JyLIdKY!C#UmoHy_;;2!hcH#NHef#GA11SI2YTn!VFNy{*zXyO<8X6i- zE-x={HPJ|IZEdFm4?M6(QBjfnoro|D#e_gp5Cqoi(mOgjN=iyfqphuN|FW{OO&Z^)2SHG^b?ep}1`Zt9h6#YvAZ*#PrEg(jq4?4BefAO} p(!gGW@P#)B14~Lu1n!;3{{lk#X3i{L8Z-a^002ovPDHLkV1gy*G|>P6 literal 0 HcmV?d00001 diff --git a/public/images/course/guide/1-2.png b/public/images/course/guide/1-2.png new file mode 100644 index 0000000000000000000000000000000000000000..1a4f26f3802df4069f22258d2bd3bfe04e3478db GIT binary patch literal 14301 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

jk*NPHEta;ceoFwUIy6 zGc0T)Uhs6YCTy!I2>Q~1KTTJ6Qxex3I~$VTlCx%_0rUR3{kcP+&h9jMc5SzdZJ7=(IidE6A(iF5XP{%sHNpQ1XbQr;r` F{{t9)MIQhF literal 0 HcmV?d00001 diff --git a/public/images/course/guide/1-3.png b/public/images/course/guide/1-3.png new file mode 100644 index 0000000000000000000000000000000000000000..f54250747b8f64d48098424f4a0a14e3d896310b GIT binary patch literal 9862 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 N*38DV^rYv_{|8Op!IA&~ literal 0 HcmV?d00001 diff --git a/public/images/course/guide/1-4.png b/public/images/course/guide/1-4.png new file mode 100644 index 0000000000000000000000000000000000000000..6ecd3bfb7b3b7619c6137b95d4be236f24dcb742 GIT binary patch literal 24857 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 literal 0 HcmV?d00001 diff --git a/public/images/course/guide/1-5.png b/public/images/course/guide/1-5.png new file mode 100644 index 0000000000000000000000000000000000000000..c4205496df9adf5890d32a28ce270e1064b16039 GIT binary patch literal 2660 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 literal 0 HcmV?d00001 diff --git a/public/images/course/guide/1-7.png b/public/images/course/guide/1-7.png new file mode 100644 index 0000000000000000000000000000000000000000..65cadf0c7605d424f366860f3338cabd11aca483 GIT binary patch literal 1267 zcmVZhxkf@?F>6Zo!Ew=6Li5q#asor%)(dplY?+ zPNme=VzIbqe0=h?u*c(mthrsVCVX!LOEC4zNIAh4kiXrpWkhJ~C zrT}pW{|X#3jXMW4aG!X>`Y}kOJ_~?006T`9j5rRjACk5o*`vTYz)QfJ5rDn}4o4U~ z0sPsIY25lO06GhJyvM-BbH2`e_koVtA1U&^yY0lCdz5}PfO_>M-u~Z`9z>L1762V- zPS*i9o65U^Q9Ei^14y1_dN#j zQ`*~HUNz`7Ks4$DKpeMezD0EnfngSbXx6@A2nVIfD?oDi9%m-;GawGbZz7WtW8wTk zCmLyY0C>ZEdw575LiRTBc?|l#q_CxEV%}p6ah%U znKg!lTmb|`*(y^lM*~12fU;THat}(n+zVW6?p^N!FB^Fq zRlWth2c)6JN1UGpX!%?dM`^UQjWHl`f}a4L0K!oh3lLlc+;7eu@vTYlj2I+hEc`KQ zK%)KS37{-xAqIiCZAQ9%4KiU1&>&LEu#E*ML*Wn7wFPJpDP`DZ1)xyiqBtQlu~;&c zLteZ7SKy-fr#6m_jm^5QYeRo?09iEjw-Y?Cl-g4+mu>KT4gm5zZ?o2VIe6ZtpX30M z&=6X!*3{C{k_6YR>!hDZU9DEzrIfl|o|;Rgl1<>s2s7XJr<%>?gTOxtTrw7$0+|sa z%iXS|Kn6ju2^iB_@2gg;SFfZ%hCs4O#F=76?{ 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( + + ) + } +} +export default CoursesGuide; \ No newline at end of file diff --git a/public/react/src/modules/courses/css/Courses.css b/public/react/src/modules/courses/css/Courses.css index a5c42cd69..8a84fc402 100644 --- a/public/react/src/modules/courses/css/Courses.css +++ b/public/react/src/modules/courses/css/Courses.css @@ -1520,3 +1520,23 @@ input.ant-input-number-input:focus { border-bottom: 1px solid transparent !important; } + +/* 指引 */ +.guidePanel{ + position: fixed; + top:0px; + left: 0px; + width: 100%; + height: 100%; + background: rgba(0,0,0,0.7); + z-index: 10000; +} +.guideFirstRight{ + position: absolute; + right: -90px; +} +.guideFirstLeft{ + position: absolute; + left: -95px; + top:120px; +} \ No newline at end of file diff --git a/public/react/src/modules/courses/graduation/tasks/GraduateTaskItem.js b/public/react/src/modules/courses/graduation/tasks/GraduateTaskItem.js index 4d6c6777b..06523bb38 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduateTaskItem.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduateTaskItem.js @@ -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/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'; From 5684b99c8a043e81841cbbe7e2e4c03e8901b86b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Tue, 25 Jun 2019 17:21:38 +0800 Subject: [PATCH 12/15] =?UTF-8?q?=20=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../courses/coursesPublic/Associationmodel.js | 16 +++++++--------- .../courses/graduation/tasks/GraduateTaskItem.js | 12 ++++++------ .../graduation/tasks/GraduationTasksappraise.js | 8 ++++---- .../tasks/GraduationTaskssettinglist.js | 12 ++++++------ 4 files changed, 23 insertions(+), 25 deletions(-) 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/graduation/tasks/GraduateTaskItem.js b/public/react/src/modules/courses/graduation/tasks/GraduateTaskItem.js index 4d6c6777b..b2a28110d 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduateTaskItem.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduateTaskItem.js @@ -59,12 +59,12 @@ class GraduateTaskItem extends Component{ axios.get(url).then((result)=>{ 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() } diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js index 28955e268..98983ba9b 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js @@ -249,8 +249,8 @@ class GraduationTasksappraise extends Component{
{firelistdata===undefined?"":firelistdata.length===0?"":firelistdata.revise_attachments.length===0?"": -
-
+
+
补交附件
@@ -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/GraduationTaskssettinglist.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js index ebb221902..229a8399a 100644 --- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js +++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js @@ -544,12 +544,12 @@ class GraduationTaskssettinglist extends Component{ if(result.data.status===0){ this.searchValue() - this.setState({ - Modalstype:true, - Modalstopval:result.data.message, - ModalSave:this.cannerassocition, - loadtype:true - }) + // this.setState({ + // Modalstype:true, + // Modalstopval:result.data.message, + // ModalSave:this.cannerassocition, + // loadtype:true + // }) } }).catch((error)=>{ From b9f6336e9a29016f524d71076e12e92c7f42220c Mon Sep 17 00:00:00 2001 From: hjm <63528605@qq.com> Date: Tue, 25 Jun 2019 17:22:40 +0800 Subject: [PATCH 13/15] spin --- public/react/src/modules/courses/members/studentsList.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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} 个} From 026dc5e4d5c804d1248614141676494f07e7772d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Tue, 25 Jun 2019 17:35:37 +0800 Subject: [PATCH 14/15] =?UTF-8?q?=20=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../courses/coursesPublic/CoursesListType.js | 179 +++++++++--------- .../tasks/GraduationTasksappraise.js | 6 +- public/stylesheets/educoder/edu-main.css | 2 +- 3 files changed, 94 insertions(+), 93 deletions(-) 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/graduation/tasks/GraduationTasksappraise.js b/public/react/src/modules/courses/graduation/tasks/GraduationTasksappraise.js index 98983ba9b..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,7 +249,7 @@ class GraduationTasksappraise extends Component{
{firelistdata===undefined?"":firelistdata.length===0?"":firelistdata.revise_attachments.length===0?"": -
+
补交附件
diff --git a/public/stylesheets/educoder/edu-main.css b/public/stylesheets/educoder/edu-main.css index 074c4ed89..c5883692c 100644 --- a/public/stylesheets/educoder/edu-main.css +++ b/public/stylesheets/educoder/edu-main.css @@ -727,7 +727,7 @@ html>body #ajax-indicator { position: fixed; } .btn-cir-grey{background: #e1e1e1;color: #8c8c8c;font-weight: normal;border: 1px solid #e1e1e1} /*动态标签*/ -.edu-filter-btn{cursor: default;display: inline-block; padding:0px 9px; color:#666; background:#fff; text-align: center; border-radius:10px; font-size:12px; height:18px; line-height:18px;} +.edu-filter-btn{cursor: default;display: inline-block; padding:0px 9px; color:#666; text-align: center; border-radius:10px; font-size:12px; height:18px; line-height:18px;} .edu-filter-btn-blue{border:1px solid #3498db; color:#3498db;} .edu-filter-btn-orange{border:1px solid #ff6800; color:#ff6800!important;}/*提交中、评阅中*/ .edu-filter-btn-red{border:1px solid #DD1717; color:#DD1717;}/*已截止、未开启补交*/ From 712ba99281bef5e950c00eaab894b312dfd230cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Tue, 25 Jun 2019 17:40:07 +0800 Subject: [PATCH 15/15] =?UTF-8?q?=20=E8=B0=83=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/modules/courses/css/Courses.css | 18 +++++++++--------- public/stylesheets/educoder/edu-main.css | 2 +- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/public/react/src/modules/courses/css/Courses.css b/public/react/src/modules/courses/css/Courses.css index f79800f28..8720dd860 100644 --- a/public/react/src/modules/courses/css/Courses.css +++ b/public/react/src/modules/courses/css/Courses.css @@ -849,31 +849,31 @@ a.white-btn.use_scope-btn:hover{ .edu-filter-btn-028d01{ /*border: 1px solid #ff6800;*/ /*color: #ff6800!important;*/ - background: #028d01; + background: #028d01 !important; } .edu-filter-btn-CC317C{ - background:#CC317C; + background:#CC317C !important; } .edu-filter-btn-006B75{ - background:#006B75; + background:#006B75 !important; } .edu-filter-btn-E99695{ - background:#E99695; + background:#E99695 !important; } .edu-filter-btn-EDEDED{ - background:#EDEDED; + background:#EDEDED !important; } .edu-filter-btn-4CACFF{ - background:#4CACFF; + background:#4CACFF !important; } .edu-filter-btn-84B6EB{ - background:#84B6EB; + background:#84B6EB !important; } .edu-filter-btn-5E5FB9{ - background:#5E5FB9; + background:#5E5FB9 !important; } .edu-filter-btn-FC2B6A{ - background:#FC2B6A; + background:#FC2B6A !important; } .color666666{ color:#666666 !important; diff --git a/public/stylesheets/educoder/edu-main.css b/public/stylesheets/educoder/edu-main.css index c5883692c..074c4ed89 100644 --- a/public/stylesheets/educoder/edu-main.css +++ b/public/stylesheets/educoder/edu-main.css @@ -727,7 +727,7 @@ html>body #ajax-indicator { position: fixed; } .btn-cir-grey{background: #e1e1e1;color: #8c8c8c;font-weight: normal;border: 1px solid #e1e1e1} /*动态标签*/ -.edu-filter-btn{cursor: default;display: inline-block; padding:0px 9px; color:#666; text-align: center; border-radius:10px; font-size:12px; height:18px; line-height:18px;} +.edu-filter-btn{cursor: default;display: inline-block; padding:0px 9px; color:#666; background:#fff; text-align: center; border-radius:10px; font-size:12px; height:18px; line-height:18px;} .edu-filter-btn-blue{border:1px solid #3498db; color:#3498db;} .edu-filter-btn-orange{border:1px solid #ff6800; color:#ff6800!important;}/*提交中、评阅中*/ .edu-filter-btn-red{border:1px solid #DD1717; color:#DD1717;}/*已截止、未开启补交*/