From 46655abd16a0ce2ddb58fcc517673ce7aac57a76 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 7 Sep 2019 10:09:51 +0800 Subject: [PATCH 01/11] =?UTF-8?q?=E9=A2=98=E5=BA=93=E7=9A=84=E5=BC=95?= =?UTF-8?q?=E7=94=A8=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/question_banks_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/question_banks_controller.rb b/app/controllers/question_banks_controller.rb index e7be8b395..b4e98e05f 100644 --- a/app/controllers/question_banks_controller.rb +++ b/app/controllers/question_banks_controller.rb @@ -265,6 +265,7 @@ class QuestionBanksController < ApplicationController # exercise.update_column(:quotes, exercise.quotes+1) # end new_exercise if new_exercise.save! + exercise.update_column(:quotes, exercise.quotes+1) end end @@ -292,6 +293,7 @@ class QuestionBanksController < ApplicationController # poll.update_column(:quotes, poll.quotes+1) # end new_poll if new_poll.save! + poll.update_column(:quotes, poll.quotes+1) end end From a4fc1222d3cad9b64162862b21546207dd178cdf Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Sat, 7 Sep 2019 10:32:03 +0800 Subject: [PATCH 02/11] =?UTF-8?q?=20=E6=89=93=E5=8D=B0=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/shixuns_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 180c269b5..79e182fef 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -448,6 +448,7 @@ class ShixunsController < ApplicationController ShixunMirrorRepository.create(:shixun_id => @shixun.id, :mirror_repository_id => mirror) end end + logger.info("#########shixun_params#{shixun_params}") @shixun.update_attributes(shixun_params) logger.info("##########shixun_info_params: #{shixun_info_params}") logger.info("##########params[:shixun_info][:evaluate_script]: #{params[:shixun_info][:evaluate_script]}") From 4c6a2d596d6eb9c0012fcc206f16ad4b9db7f959 Mon Sep 17 00:00:00 2001 From: daiao <358551898@qq.com> Date: Sat, 7 Sep 2019 11:01:43 +0800 Subject: [PATCH 03/11] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88VNC=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/controllers/games_controller.rb | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb index ac72577e0..916f09430 100644 --- a/app/controllers/games_controller.rb +++ b/app/controllers/games_controller.rb @@ -67,13 +67,19 @@ class GamesController < ApplicationController uri = "#{shixun_tomcat}/bridge/vnc/getvnc" params = {tpiID: @myshixun.id, :containers => "#{Base64.urlsafe_encode64(shixun_container_limit(@shixun))}"} res = uri_post uri, params + logger.info("###############---- ") if res && res['code'].to_i != 0 raise("实训云平台繁忙(繁忙等级:99)") end - # 无域名版本 - #@vnc_url = "http://#{service_host}:#{res['port']}/vnc_lite.html?password=headless" - # 有域名版本 - @vnc_url = "https://#{res['port']}.#{service_host}/vnc_lite.html?password=headless" + + if request.subdomain == "pre-newweb" + # 无域名版本 + @vnc_url = "http://#{service_host}:#{res['port']}/vnc_lite.html?password=headless" + else + # 有域名版本 + @vnc_url = "https://#{res['port']}.#{service_host}/vnc_lite.html?password=headless" + end + @vnc_evaluate = @shixun.vnc_evaluate rescue Exception => e Rails.logger.error(e.message) From 906f455cf8a0c4d7bc9347de390755449265f5ab Mon Sep 17 00:00:00 2001 From: hjm <63528605@qq.com> Date: Sat, 7 Sep 2019 11:17:14 +0800 Subject: [PATCH 04/11] (!shixun.vnc || shixun.vnc_evaluate) --- public/react/src/modules/page/main/ActionView.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/public/react/src/modules/page/main/ActionView.js b/public/react/src/modules/page/main/ActionView.js index 4933ba0ac..e475b999c 100644 --- a/public/react/src/modules/page/main/ActionView.js +++ b/public/react/src/modules/page/main/ActionView.js @@ -150,7 +150,7 @@ class ActionView extends Component { -
+ {(!shixun.vnc || shixun.vnc_evaluate) &&
{ st === 1 && game.status === 2 ? @@ -174,7 +174,7 @@ class ActionView extends Component { 测评 } -
+
} ); /* From b952f5c290c2ee484f2ba38126f67f0b5be43f2d Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 7 Sep 2019 11:21:45 +0800 Subject: [PATCH 05/11] =?UTF-8?q?=E8=BF=81=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/gtopic_bank.rb | 4 +-- ...0190907021100_migrate_bank_reference_id.rb | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) create mode 100644 db/migrate/20190907021100_migrate_bank_reference_id.rb diff --git a/app/models/gtopic_bank.rb b/app/models/gtopic_bank.rb index af5b267a6..609219711 100644 --- a/app/models/gtopic_bank.rb +++ b/app/models/gtopic_bank.rb @@ -1,7 +1,7 @@ class GtopicBank < ApplicationRecord belongs_to :user - belongs_to :graduation_topic - belongs_to :course_list + belongs_to :graduation_topic, optional: true + belongs_to :course_list, optional: true has_many :attachments, as: :container, dependent: :destroy has_many :graduation_topics, dependent: :nullify diff --git a/db/migrate/20190907021100_migrate_bank_reference_id.rb b/db/migrate/20190907021100_migrate_bank_reference_id.rb new file mode 100644 index 000000000..c71034167 --- /dev/null +++ b/db/migrate/20190907021100_migrate_bank_reference_id.rb @@ -0,0 +1,31 @@ +class MigrateBankReferenceId < ActiveRecord::Migration[5.2] + def change + HomeworkBank.all.each do |bank| + if bank.homework_common + bank.homework_common.update_column("homework_bank_id", bank.id) if bank.homework_common.homework_bank_id.nil? + end + end + + GtopicBank.all.each do |bank| + if bank.graduation_topic + bank.graduation_topic.update_column("gtopic_bank_id", bank.id) if bank.graduation_topic.gtopic_bank_id.nil? + end + end + + GtaskBank.all.each do |bank| + if bank.graduation_task + bank.graduation_task.update_column("gtask_bank_id", bank.id) if bank.graduation_task.gtask_bank_id.nil? + end + end + + ExerciseBank.all.each do |bank| + if bank.container_type == 'Exercise' + exercise = Exercise.find_by(id: bank.container_id) + exercise.update_column("exercise_bank_id", bank.id) if exercise && exercise.exercise_bank_id.nil? + elsif bank.container_type == 'Poll' + poll = Poll.find_by(id: bank.container_id) + poll.update_column("exercise_bank_id", bank.id) if poll && poll.exercise_bank_id.nil? + end + end + end +end From cdf5e97033f025d820b600a99594d1853f6f3847 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 7 Sep 2019 11:27:46 +0800 Subject: [PATCH 06/11] =?UTF-8?q?=E6=8A=80=E6=9C=AF=E5=B9=B3=E5=8F=B0?= =?UTF-8?q?=E6=90=9C=E7=B4=A2=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/react/src/modules/tpm/TPMsettings/TPMsettings.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/public/react/src/modules/tpm/TPMsettings/TPMsettings.js b/public/react/src/modules/tpm/TPMsettings/TPMsettings.js index 1ee36f488..a8917fd02 100644 --- a/public/react/src/modules/tpm/TPMsettings/TPMsettings.js +++ b/public/react/src/modules/tpm/TPMsettings/TPMsettings.js @@ -1653,8 +1653,6 @@ export default class TPMsettings extends Component { // onMouseEnter={operateauthority?this.bigopen:""} onSelect={operateauthority?this.bigopens:""} // open={opers} - - showSearch optionFilterProp="children" filterOption={(input, option) => option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0 From d1b732abe8fca399a60629d6195a75bf812815dd Mon Sep 17 00:00:00 2001 From: p31729568 Date: Sat, 7 Sep 2019 13:41:45 +0800 Subject: [PATCH 07/11] admins: fix md editor style --- app/assets/javascripts/common.js | 1 + 1 file changed, 1 insertion(+) diff --git a/app/assets/javascripts/common.js b/app/assets/javascripts/common.js index fa7bef244..dc0818b64 100644 --- a/app/assets/javascripts/common.js +++ b/app/assets/javascripts/common.js @@ -1,5 +1,6 @@ function createMDEditor(element, opts){ var defaults = { + height: 600, path: '/editormd/lib/', syncScrolling: "single", tex: true, From e3b153ed7565263aa02ee148107010d5ee67a297 Mon Sep 17 00:00:00 2001 From: caicai8 <1149225589@qq.com> Date: Sat, 7 Sep 2019 13:55:43 +0800 Subject: [PATCH 08/11] =?UTF-8?q?issue-=E6=95=99=E5=B8=88=E5=88=97?= =?UTF-8?q?=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/courses/members/CourseGroupChooser.js | 2 +- .../courses/members/modal/CourseGroupChooserModal.js | 11 ++++++++--- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/public/react/src/modules/courses/members/CourseGroupChooser.js b/public/react/src/modules/courses/members/CourseGroupChooser.js index ba9c64bb1..f57874872 100644 --- a/public/react/src/modules/courses/members/CourseGroupChooser.js +++ b/public/react/src/modules/courses/members/CourseGroupChooser.js @@ -41,7 +41,7 @@ function CourseGroupChooser({ course_groups, isAdminOrCreator = true, item, inde console.log('arg_course_groups', arg_course_groups) - const urlStyle = {"lef":"tunset", minWidth: '262px'}; + const urlStyle = {"left":"unset", minWidth: '262px'}; if (alwaysShow == true) { urlStyle.display = 'block' } diff --git a/public/react/src/modules/courses/members/modal/CourseGroupChooserModal.js b/public/react/src/modules/courses/members/modal/CourseGroupChooserModal.js index 2f08d08a1..59883c77b 100644 --- a/public/react/src/modules/courses/members/modal/CourseGroupChooserModal.js +++ b/public/react/src/modules/courses/members/modal/CourseGroupChooserModal.js @@ -70,17 +70,22 @@ function CourseGroupChooserModal({ course_groups = [], isAdminOrCreator, item, i text-align: center; margin-bottom: 20px; } - .courseGroupChooserModal .drop_down_menu { + .courseGroupChooserModal .drop_down_menu { position: relative; top: auto; box-shadow: none; + padding-top: 12px; + } + .courseGroupChooserModal .drop_down_menu .mainGroup{ + background: #f2f9ff; padding: 0 20px; + } + .courseGroupChooserModal .drop_down_menu li:hover,.courseGroupChooserModal .drop_down_normal li:hover{ background: #f2f9ff; - padding-top: 12px; } .courseGroupChooserModal .drop_down_menu .mainGroup.ant-checkbox-group { width: 100%; - max-height: 300px + height: 300px; } .courseGroupChooserModal .drop_down_search { margin: 0; From 78d7ad5f74eb9d9eaf398fe79ab6ab4d1f227515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 7 Sep 2019 13:57:17 +0800 Subject: [PATCH 09/11] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/modules/user/usersInfo/InfosTopics.js | 51 +++++++++---------- 1 file changed, 24 insertions(+), 27 deletions(-) diff --git a/public/react/src/modules/user/usersInfo/InfosTopics.js b/public/react/src/modules/user/usersInfo/InfosTopics.js index 565f42a3d..db96818e5 100644 --- a/public/react/src/modules/user/usersInfo/InfosTopics.js +++ b/public/react/src/modules/user/usersInfo/InfosTopics.js @@ -84,36 +84,33 @@ class InfosTopics extends Component{ if(user_id===undefined){ - user_id=this.props.match.params&&this.props.match.params.username; + user_id=1 } - - if(user_id!=undefined){ - let {per_page}=this.state; - let url=`/users/${user_id}/question_banks.json`; - - axios.get(encodeURI(url),{params:{ - type, - object_type:category, - course_list_id, - sort_by, - sort_direction, - page, - per_page - } - }).then((response) => { - this.setState({ - data:response.data, - checkBoxValues:[], - isSpin:false - }) - }).catch((error) => { - this.setState({ - isSpin:false - }) - }); - } + let {per_page}=this.state; + let url=`/users/${user_id}/question_banks.json`; + + axios.get(encodeURI(url),{params:{ + type, + object_type:category, + course_list_id, + sort_by, + sort_direction, + page, + per_page + } + }).then((response) => { + this.setState({ + data:response.data, + checkBoxValues:[], + isSpin:false + }) + }).catch((error) => { + this.setState({ + isSpin:false + }) + }); } From 478e23d7393cd8bd5ed8f125489b00ba4c9e15e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=A8=E6=A0=91=E6=98=8E?= <775174143@qq.com> Date: Sat, 7 Sep 2019 14:08:41 +0800 Subject: [PATCH 10/11] =?UTF-8?q?=E8=B0=83=E6=95=B4=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../react/src/modules/page/main/ActionView.js | 410 ++++++------ .../page/main/CodeRepositoryViewContainer.js | 621 +++++++++--------- 2 files changed, 518 insertions(+), 513 deletions(-) diff --git a/public/react/src/modules/page/main/ActionView.js b/public/react/src/modules/page/main/ActionView.js index e475b999c..0fa4dd267 100644 --- a/public/react/src/modules/page/main/ActionView.js +++ b/public/react/src/modules/page/main/ActionView.js @@ -1,204 +1,206 @@ -import React, { Component } from 'react'; -import { Link } from 'react-router-dom' - -import { withStyles } from 'material-ui/styles'; -import Button from 'material-ui/Button'; - -import Tooltip from 'material-ui/Tooltip'; - -import './ActionView.css' - -/* - - color: #1B4061 !important; - background-color: transparent; - border: 1px solid #1B4061 !important; - */ -const styles = theme => ({ - button: { - margin: theme.spacing.unit, - border: '1px solid #1B4061', - color: '#1B4061', - height: '30px', - padding: '0 16px', - '&:hover': { - color: '#4CACFF', - border: '1px solid #4CACFF' - } - }, - hoverButton: { - margin: theme.spacing.unit, - height: '30px', - padding: '0 16px', - - color: '#4CACFF', - border: '1px solid #4CACFF' - }, - buttonText: { - color: '#1B4061 !important', - '&:hover': { - color: '#1B4061', - } - } -}); - -class ActionView extends Component { - - constructor(props) { - super(props) - - } - - componentDidMount() { - // request - window._tpiWidthResize = () => { - const _w = window.$('#actionView').width(); - // if (_w < 446) { - // window.$('#time-consuming').hide() - // // window.$('#time-consuming').hide() - // } else if (_w < 746) { - // // 文字放出来之前是 580 - // window.$('#time-consuming').show() - // window.$('.time_limit').hide() - // } else { - // window.$('#time-consuming').show() - // window.$('.time_limit').show() - // } - } - } - - showWebDisplay(challenge) { - window.open(challenge.webDisplayUrl, '_blank'); - } - /*耗时:0 天 3 小时 11 分钟 57 秒 */ - render() { - const { onRunCodeTest, onShowPrevStage, onShowNextStage, gameBuilding - , game, classes, st, shixun, record, challenge, time_limit, real_time_limit } = this.props; - return ( -
- - - {!!time_limit && - {`本关最大执行时间:${real_time_limit}秒`} - {!gameBuilding && record && } - } - {!gameBuilding && record ? - // - 本次评测耗时(编译、运行总时间):{ record } 秒 - - : ""} - - - {/*将第一个按钮改为visibility方式隐藏,不然加载时测评按钮会出现没有垂直居中的情况*/} - - - - - { - !gameBuilding && - (game && !!game.prev_game) ? - - - - : ''} - - {/*未发布的都能跳转*/} - { !gameBuilding && - ((game && (game.status === 2 || shixun.status < 2) || shixun && shixun.task_pass ) && !!game.next_game) ? - - - - : ''} - - - - {(!shixun.vnc || shixun.vnc_evaluate) &&
- { - st === 1 && game.status === 2 ? - - - - 测评 - - - : - gameBuilding ? - - - - 测评 - - : - - - 测评 - } -
} -
- ); - /* - 离开 - - 下一关 - - onclick="training_task_submmit();" - - - {game && !!game.prev_game ? -
- 上一关 -
- : ''} - - {game && !!game.next_game ? -
- 下一关 -
- : ''} - */ - } -} - -export default withStyles(styles)( ActionView ); +import React, { Component } from 'react'; +import { Link } from 'react-router-dom' + +import { withStyles } from 'material-ui/styles'; +import Button from 'material-ui/Button'; + +import Tooltip from 'material-ui/Tooltip'; + +import './ActionView.css' + +/* + + color: #1B4061 !important; + background-color: transparent; + border: 1px solid #1B4061 !important; + */ +const styles = theme => ({ + button: { + margin: theme.spacing.unit, + border: '1px solid #1B4061', + color: '#1B4061', + height: '30px', + padding: '0 16px', + '&:hover': { + color: '#4CACFF', + border: '1px solid #4CACFF' + } + }, + hoverButton: { + margin: theme.spacing.unit, + height: '30px', + padding: '0 16px', + + color: '#4CACFF', + border: '1px solid #4CACFF' + }, + buttonText: { + color: '#1B4061 !important', + '&:hover': { + color: '#1B4061', + } + } +}); + +class ActionView extends Component { + + constructor(props) { + super(props) + + } + + componentDidMount() { + // request + window._tpiWidthResize = () => { + const _w = window.$('#actionView').width(); + // if (_w < 446) { + // window.$('#time-consuming').hide() + // // window.$('#time-consuming').hide() + // } else if (_w < 746) { + // // 文字放出来之前是 580 + // window.$('#time-consuming').show() + // window.$('.time_limit').hide() + // } else { + // window.$('#time-consuming').show() + // window.$('.time_limit').show() + // } + } + } + + showWebDisplay(challenge) { + window.open(challenge.webDisplayUrl, '_blank'); + } + /*耗时:0 天 3 小时 11 分钟 57 秒 */ + render() { + const { onRunCodeTest, onShowPrevStage, onShowNextStage, gameBuilding + , game, classes, st, shixun, record, challenge, time_limit, real_time_limit } = this.props; + + console.log(shixun) + return ( +
+ + + {!!time_limit && + {`本关最大执行时间:${real_time_limit}秒`} + {!gameBuilding && record && } + } + {!gameBuilding && record ? + // + 本次评测耗时(编译、运行总时间):{ record } 秒 + + : ""} + + + {/*将第一个按钮改为visibility方式隐藏,不然加载时测评按钮会出现没有垂直居中的情况*/} + + + + + { + !gameBuilding && + (game && !!game.prev_game) ? + + + + : ''} + + {/*未发布的都能跳转*/} + { !gameBuilding && + ((game && (game.status === 2 || shixun.status < 2) || shixun && shixun.task_pass ) && !!game.next_game) ? + + + + : ''} + + + + {(shixun&&shixun.vnc || shixun&&shixun.vnc_evaluate) &&
+ { + st === 1 && game.status === 2 ? + + + + 测评 + + + : + gameBuilding ? + + + + 测评 + + : + + + 测评 + } +
} +
+ ); + /* + 离开 + + 下一关 + + onclick="training_task_submmit();" + + + {game && !!game.prev_game ? +
+ 上一关 +
+ : ''} + + {game && !!game.next_game ? +
+ 下一关 +
+ : ''} + */ + } +} + +export default withStyles(styles)( ActionView ); diff --git a/public/react/src/modules/page/main/CodeRepositoryViewContainer.js b/public/react/src/modules/page/main/CodeRepositoryViewContainer.js index 0a5be59e0..5d6be306f 100644 --- a/public/react/src/modules/page/main/CodeRepositoryViewContainer.js +++ b/public/react/src/modules/page/main/CodeRepositoryViewContainer.js @@ -1,309 +1,312 @@ - -import React, { Component } from 'react'; - -import CodeRepositoryView from './CodeRepositoryView' - -import axios from 'axios' - -import './CodeRepositoryView.css' - -// 自己处理path,加上父节点的path, 这里是处理树节点了,所以是set key -function addPrePath(treeData, parentNodePath) { - return treeData.map(item => { - return { - ...item, - key: `${parentNodePath}/${item.name}` - } - }) -} -function getNewTreeData(treeData, curKey, child, level) { - const loop = (data) => { - data.forEach((item) => { - // 这里不能用indexOf 同一级可能出现test目录和test.py文件 - if (item.key == curKey) { - child = addPrePath(child, curKey); - item.children = child; - } else { - if (item.children) { - loop(item.children); - } - } - }); - }; - loop(treeData); -} - -function fileData2TreeData(repoFilesData) { - const fileTreeData = []; - repoFilesData.forEach((item) => { - if (item.kind === 'file') { - fileTreeData.push({ - key: item.path, - name: item.name, - isLeaf: true - }) - } else { - fileTreeData.push({ - key: item.path, - name: item.name, - // isLeaf: false - }) - } - }) - return fileTreeData; -} - -class CodeRepositoryViewContainer extends Component { - - constructor(props) { - super(props) - - this.showFilesDrawer = this.showFilesDrawer.bind(this) - this.onRepositoryViewExpand = this.onRepositoryViewExpand.bind(this) - - this.state = { - drawerOpen: false, - loadingFirstRepoFiles: false, - fileTreeData: "", - fileTreeSelectedKeys: [], - codeRepositoryViewExpanded: false, - tabIndex: 0, - - settingDrawerOpen: false - } - } - showSettingDrawer = (open) => { - this.setState({settingDrawerOpen: open}) - } - tabIndexChange = (index) => { - this.setState({tabIndex: index}); - } - onRepositoryViewExpand() { - window.repository_extend_and_zoom(); - this.setState({ - evaluateViewExpanded: !this.state.evaluateViewExpanded - }, () => { - setTimeout(()=>{ - window.__tpiOnResize() - }, 300) - }) - } - - showFilesDrawer(open) { - if (this.props.loading === true) { - return; - } - if (!this.state.fileTreeData) { - this.fetchRepoFiles(); - } - - this.setState({ - drawerOpen: open, - }) - } - loadRepoFiles = () => { - if (!this.state.fileTreeData) { - this.fetchRepoFiles(); - } - } - - componentWillReceiveProps(newProps, oldProps) { - - } - componentDidMount() { - - } - - componentDidUpdate(prevProps, prevState, snapshot) { - const { game, challenge } = this.props - if (this.props.game && (!prevProps.game || prevProps.game.identifier !== this.props.game.identifier) ) { - this.setState({ - fileTreeSelectedKeys: [ challenge.multiPath ? challenge.path[0] : challenge.path ] - }) - // 初始化 - } else if (this.state.fileTreeSelectedKeys.length === 0 && challenge && challenge.path) { - this.setState({ - fileTreeSelectedKeys: [ challenge.multiPath ? challenge.path[0] : challenge.path ] - }) - } else if (challenge && prevProps && prevProps.challenge - && challenge.pathIndex != prevProps.challenge.pathIndex - && challenge.pathIndex !== -1) { - this.setState({ - fileTreeSelectedKeys: [ challenge.multiPath ? challenge.path[challenge.pathIndex] : challenge.path ] - }) - } - } - - handleDialogClose() { - this.setState({ - dialogOpen: false - }) - } - onLoadData = (treeNode) => { - if (treeNode.props.children && treeNode.props.children.length) { - return new Promise((resolve) => { - resolve(); - }); - } - return new Promise((resolve, reject) => { - this.fetchRepoFiles(treeNode, resolve, reject) - }); - } - map2OldData = (treeData) => { - if (!treeData || treeData.length === 0) return treeData; - treeData = treeData.map(item => { - return { - kind: item.type == "blob" ? "file" : "dir", // blob->file tree->dir - path: item.name, - name: item.name - } - }) - return treeData; - } - - fetchRepoFiles(treeNode, resolve, reject) { - // http://localhost:3000/api/v1/games/829al3mst4fy/entries?path=src/step1&rev=master - if (!this.props.challenge || !this.props.game) { - return; - } - // var ar = this.props.challenge.path.split('/'); - // ar.length = ar.length - 2; - // var _path = ar.join('/'); - var _path = treeNode ? treeNode.props.eventKey : '' ; - if (_path.charAt(0) === '/') { - _path = _path.substring(1) - } - // var url = `/api/v1/games/${this.props.game.identifier}/entries?path=${_path}&rev=master&gpid=${this.props.myshixun.gpid}` - let url = `/myshixuns/${this.props.myshixun.identifier}/repository.json` - - - if (!this.state.fileTreeData || this.state.fileTreeData.length === 0) { - this.setState({ - loadingFirstRepoFiles: true, - }) - } - var that = this; - axios.post(url, { - path: _path - // withCredentials: true, - }) - .then((response) => { - const repoFilesData = this.map2OldData(response.data.trees) - if (!this.state.fileTreeData || this.state.fileTreeData.length === 0) { // 还没树节点,没加载过 - - const fileTreeData = fileData2TreeData(repoFilesData) - this.setState({ - fileTreeData, - loadingFirstRepoFiles: false, - }); - } else { - var _treeNode = treeNode; - var _eventKey = _treeNode.props.eventKey; - - const fileTreeData = that.state.fileTreeData; - // 新的数组放置到treenode下 - - const tempFileTreeData = fileData2TreeData(repoFilesData) - - getNewTreeData(fileTreeData, _eventKey, tempFileTreeData, 2); - this.setState({ - fileTreeData, - }) - } - - resolve && resolve(); - - }) - .catch(function (error) { - console.log(error); - reject && reject(); - }); - } - onTreeSelect = (selectedKeys, info) => { - const isLeaf = info.node.props.isLeaf; - if (isLeaf) { // 叶子节点 - selectedKeys.length && this.setState({ - fileTreeSelectedKeys: selectedKeys - }) - const { fetchRepositoryCode, onPathChange, showSnackbar, challenge } = this.props; - - const nodePath = info.node.props.eventKey; - // 设置pathIndex为-1,那么代码文件下拉可以切回可编辑的文件 - if (!challenge.multiPath) { // 单path任务 多path任务 path是数组 - if (challenge.path.trim() == nodePath.trim()) { - if (challenge.pathIndex === 0) { - showSnackbar(`当前编辑文件已经是${nodePath}`) - } else { - onPathChange(0) - } - return; - } else { - onPathChange(-1) - } - } else { - let isCurrentFile = false; - let cur_index = -1; - if (challenge.path && challenge.path.forEach) { - challenge.path.forEach((item, index) => { - if (nodePath == item) { - isCurrentFile = true; - cur_index = index; - } - }) - } - if (isCurrentFile) { - onPathChange(cur_index) - showSnackbar(`当前编辑文件已经是${nodePath}`) - } else { - onPathChange(-1) - } - } - if (nodePath) { - const filetype = nodePath.split('.').pop().toLowerCase(); - if (filetype == 'jpg' || filetype == 'png' || filetype == 'gif' || filetype == 'jpeg' - || filetype == 'jar' - || filetype == 'doc' || filetype == 'pdf' || filetype == 'xsl' || filetype == 'ppt') { - showSnackbar(`不支持加载${filetype}类型的文件。`) - return; - } - fetchRepositoryCode(null, nodePath, 1); - } else { - console.error('no eventKey:', info.node) - } - } - } -// /shixuns/mnf6b7z3/shixun_discuss?challenge_id=88 - render() { - - return ( - - {this.props.isOnlyContainer == true ? - React.Children.map(this.props.children, child => { - if(!child) { - return '' - } - return React.cloneElement(child, Object.assign({...this.state}, { - loadRepoFiles: this.loadRepoFiles, - onTreeSelect: this.onTreeSelect, - onLoadData: this.onLoadData, - })) - }) - - : - - } - - ); - } -} - -export default CodeRepositoryViewContainer; + +import React, { Component } from 'react'; + +import CodeRepositoryView from './CodeRepositoryView' + +import axios from 'axios' + +import './CodeRepositoryView.css' + +// 自己处理path,加上父节点的path, 这里是处理树节点了,所以是set key +function addPrePath(treeData, parentNodePath) { + return treeData.map(item => { + return { + ...item, + key: `${parentNodePath}/${item.name}` + } + }) +} +function getNewTreeData(treeData, curKey, child, level) { + const loop = (data) => { + data.forEach((item) => { + // 这里不能用indexOf 同一级可能出现test目录和test.py文件 + if (item.key == curKey) { + child = addPrePath(child, curKey); + item.children = child; + } else { + if (item.children) { + loop(item.children); + } + } + }); + }; + loop(treeData); +} + +function fileData2TreeData(repoFilesData) { + if(repoFilesData!=null){ + const fileTreeData = []; + repoFilesData.forEach((item) => { + if (item.kind === 'file') { + fileTreeData.push({ + key: item.path, + name: item.name, + isLeaf: true + }) + } else { + fileTreeData.push({ + key: item.path, + name: item.name, + // isLeaf: false + }) + } + }) + return fileTreeData; + } + +} + +class CodeRepositoryViewContainer extends Component { + + constructor(props) { + super(props) + + this.showFilesDrawer = this.showFilesDrawer.bind(this) + this.onRepositoryViewExpand = this.onRepositoryViewExpand.bind(this) + + this.state = { + drawerOpen: false, + loadingFirstRepoFiles: false, + fileTreeData: "", + fileTreeSelectedKeys: [], + codeRepositoryViewExpanded: false, + tabIndex: 0, + + settingDrawerOpen: false + } + } + showSettingDrawer = (open) => { + this.setState({settingDrawerOpen: open}) + } + tabIndexChange = (index) => { + this.setState({tabIndex: index}); + } + onRepositoryViewExpand() { + window.repository_extend_and_zoom(); + this.setState({ + evaluateViewExpanded: !this.state.evaluateViewExpanded + }, () => { + setTimeout(()=>{ + window.__tpiOnResize() + }, 300) + }) + } + + showFilesDrawer(open) { + if (this.props.loading === true) { + return; + } + if (!this.state.fileTreeData) { + this.fetchRepoFiles(); + } + + this.setState({ + drawerOpen: open, + }) + } + loadRepoFiles = () => { + if (!this.state.fileTreeData) { + this.fetchRepoFiles(); + } + } + + componentWillReceiveProps(newProps, oldProps) { + + } + componentDidMount() { + + } + + componentDidUpdate(prevProps, prevState, snapshot) { + const { game, challenge } = this.props + if (this.props.game && (!prevProps.game || prevProps.game.identifier !== this.props.game.identifier) ) { + this.setState({ + fileTreeSelectedKeys: [ challenge.multiPath ? challenge.path[0] : challenge.path ] + }) + // 初始化 + } else if (this.state.fileTreeSelectedKeys.length === 0 && challenge && challenge.path) { + this.setState({ + fileTreeSelectedKeys: [ challenge.multiPath ? challenge.path[0] : challenge.path ] + }) + } else if (challenge && prevProps && prevProps.challenge + && challenge.pathIndex != prevProps.challenge.pathIndex + && challenge.pathIndex !== -1) { + this.setState({ + fileTreeSelectedKeys: [ challenge.multiPath ? challenge.path[challenge.pathIndex] : challenge.path ] + }) + } + } + + handleDialogClose() { + this.setState({ + dialogOpen: false + }) + } + onLoadData = (treeNode) => { + if (treeNode.props.children && treeNode.props.children.length) { + return new Promise((resolve) => { + resolve(); + }); + } + return new Promise((resolve, reject) => { + this.fetchRepoFiles(treeNode, resolve, reject) + }); + } + map2OldData = (treeData) => { + if (!treeData || treeData.length === 0) return treeData; + treeData = treeData.map(item => { + return { + kind: item.type == "blob" ? "file" : "dir", // blob->file tree->dir + path: item.name, + name: item.name + } + }) + return treeData; + } + + fetchRepoFiles(treeNode, resolve, reject) { + // http://localhost:3000/api/v1/games/829al3mst4fy/entries?path=src/step1&rev=master + if (!this.props.challenge || !this.props.game) { + return; + } + // var ar = this.props.challenge.path.split('/'); + // ar.length = ar.length - 2; + // var _path = ar.join('/'); + var _path = treeNode ? treeNode.props.eventKey : '' ; + if (_path.charAt(0) === '/') { + _path = _path.substring(1) + } + // var url = `/api/v1/games/${this.props.game.identifier}/entries?path=${_path}&rev=master&gpid=${this.props.myshixun.gpid}` + let url = `/myshixuns/${this.props.myshixun.identifier}/repository.json` + + + if (!this.state.fileTreeData || this.state.fileTreeData.length === 0) { + this.setState({ + loadingFirstRepoFiles: true, + }) + } + var that = this; + axios.post(url, { + path: _path + // withCredentials: true, + }) + .then((response) => { + const repoFilesData = this.map2OldData(response.data.trees) + if (!this.state.fileTreeData || this.state.fileTreeData.length === 0) { // 还没树节点,没加载过 + + const fileTreeData = fileData2TreeData(repoFilesData) + this.setState({ + fileTreeData, + loadingFirstRepoFiles: false, + }); + } else { + var _treeNode = treeNode; + var _eventKey = _treeNode.props.eventKey; + + const fileTreeData = that.state.fileTreeData; + // 新的数组放置到treenode下 + + const tempFileTreeData = fileData2TreeData(repoFilesData) + + getNewTreeData(fileTreeData, _eventKey, tempFileTreeData, 2); + this.setState({ + fileTreeData, + }) + } + + resolve && resolve(); + + }) + .catch(function (error) { + console.log(error); + reject && reject(); + }); + } + onTreeSelect = (selectedKeys, info) => { + const isLeaf = info.node.props.isLeaf; + if (isLeaf) { // 叶子节点 + selectedKeys.length && this.setState({ + fileTreeSelectedKeys: selectedKeys + }) + const { fetchRepositoryCode, onPathChange, showSnackbar, challenge } = this.props; + + const nodePath = info.node.props.eventKey; + // 设置pathIndex为-1,那么代码文件下拉可以切回可编辑的文件 + if (!challenge.multiPath) { // 单path任务 多path任务 path是数组 + if (challenge.path.trim() == nodePath.trim()) { + if (challenge.pathIndex === 0) { + showSnackbar(`当前编辑文件已经是${nodePath}`) + } else { + onPathChange(0) + } + return; + } else { + onPathChange(-1) + } + } else { + let isCurrentFile = false; + let cur_index = -1; + if (challenge.path && challenge.path.forEach) { + challenge.path.forEach((item, index) => { + if (nodePath == item) { + isCurrentFile = true; + cur_index = index; + } + }) + } + if (isCurrentFile) { + onPathChange(cur_index) + showSnackbar(`当前编辑文件已经是${nodePath}`) + } else { + onPathChange(-1) + } + } + if (nodePath) { + const filetype = nodePath.split('.').pop().toLowerCase(); + if (filetype == 'jpg' || filetype == 'png' || filetype == 'gif' || filetype == 'jpeg' + || filetype == 'jar' + || filetype == 'doc' || filetype == 'pdf' || filetype == 'xsl' || filetype == 'ppt') { + showSnackbar(`不支持加载${filetype}类型的文件。`) + return; + } + fetchRepositoryCode(null, nodePath, 1); + } else { + console.error('no eventKey:', info.node) + } + } + } +// /shixuns/mnf6b7z3/shixun_discuss?challenge_id=88 + render() { + + return ( + + {this.props.isOnlyContainer == true ? + React.Children.map(this.props.children, child => { + if(!child) { + return '' + } + return React.cloneElement(child, Object.assign({...this.state}, { + loadRepoFiles: this.loadRepoFiles, + onTreeSelect: this.onTreeSelect, + onLoadData: this.onLoadData, + })) + }) + + : + + } + + ); + } +} + +export default CodeRepositoryViewContainer; From 08a21cb577a1685b384cb5cd4671cf5c402162d8 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Sat, 7 Sep 2019 14:10:58 +0800 Subject: [PATCH 11/11] =?UTF-8?q?=E6=90=9C=E7=B4=A2=E8=AF=BE=E5=A0=82?= =?UTF-8?q?=E7=9A=84=E6=88=90=E5=91=98=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/models/searchable/course.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/searchable/course.rb b/app/models/searchable/course.rb index 5060d9ddd..794dec0e2 100644 --- a/app/models/searchable/course.rb +++ b/app/models/searchable/course.rb @@ -24,7 +24,7 @@ module Searchable::Course author_name: teacher&.real_name, author_school_name: teacher&.school_name, visits_count: visits, - members_count: members_count, + members_count: course_members_count, is_public: is_public == 1, first_category_url: ApplicationController.helpers.module_url(none_hidden_course_modules.first, self) }