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 {
 			      			 
 					      	测评
 					    }
-				
+				
-			  	
-	      		
-				  	{!!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) && 
}
-	      	
-					上一关
-				
-					: ''}
-
-				{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) && 
}
+	      	
+					上一关
+				
+					: ''}
+
+				{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)
     }