diff --git a/app/controllers/admins/mirror_repositories_controller.rb b/app/controllers/admins/mirror_repositories_controller.rb
index aed8dc09e..63e4667d1 100644
--- a/app/controllers/admins/mirror_repositories_controller.rb
+++ b/app/controllers/admins/mirror_repositories_controller.rb
@@ -87,7 +87,6 @@ class Admins::MirrorRepositoriesController < Admins::BaseController
   end
 
   def check_shixun_mirrors!
-    return
     return unless request.format.html?
 
     Admins::CheckShixunMirrorsService.call
diff --git a/app/controllers/admins/shixun_settings_controller.rb b/app/controllers/admins/shixun_settings_controller.rb
index 9919c7daa..d635ae8df 100644
--- a/app/controllers/admins/shixun_settings_controller.rb
+++ b/app/controllers/admins/shixun_settings_controller.rb
@@ -1,8 +1,7 @@
 class Admins::ShixunSettingsController < Admins::BaseController
 
   def index
-    params[:sort_by] = params[:sort_by].presence || 'created_on'
-    params[:sort_direction] = params[:sort_direction].presence || 'desc'
+    default_sort('created_at', 'desc')
 
     shixun_settings = Admins::ShixunSettingsQuery.call(params)
     @editing_shixuns = shixun_settings.where(status:0).size
diff --git a/app/controllers/oauth/base_controller.rb b/app/controllers/oauth/base_controller.rb
index e2eb26a2a..a9c3f9fe4 100644
--- a/app/controllers/oauth/base_controller.rb
+++ b/app/controllers/oauth/base_controller.rb
@@ -1,9 +1,14 @@
 class Oauth::BaseController < ActionController::Base
   include RenderHelper
   include LoginHelper
+  include ControllerRescueHandler
 
   skip_before_action :verify_authenticity_token
 
+  def auth_failure
+    render_error(params[:message])
+  end
+
   private
 
   def session_user_id
diff --git a/app/services/admins/check_shixun_mirrors_service.rb b/app/services/admins/check_shixun_mirrors_service.rb
index 868fab042..8334df485 100644
--- a/app/services/admins/check_shixun_mirrors_service.rb
+++ b/app/services/admins/check_shixun_mirrors_service.rb
@@ -77,10 +77,11 @@ class Admins::CheckShixunMirrorsService < ApplicationService
     @_bridge_images ||= begin
       url = EduSetting.get('cloud_bridge')
       res = Faraday.get(url)
+      res_body = JSON.parse(res.body)
 
-      raise Error, '拉取镜像信息异常' if res && res['code'].nonzero?
+      raise Error, '拉取镜像信息异常' if res_body && res_body['code'].to_i != 0
 
-      res
+      res_body
     rescue => e
       Rails.logger.error("get response failed ! #{e.message}")
       raise Error, '实训云平台繁忙(繁忙等级:84)'
diff --git a/config/initializers/omniauth.rb b/config/initializers/omniauth.rb
index 27ade9ed4..3eed48c20 100644
--- a/config/initializers/omniauth.rb
+++ b/config/initializers/omniauth.rb
@@ -1,4 +1,8 @@
 OmniAuth.config.add_camelization 'qq', 'QQ'
+OmniAuth.config.logger = Rails.logger
+OmniAuth.config.on_failure = Proc.new { |env|
+  OmniAuth::FailureEndpoint.new(env).redirect_to_failure
+}
 
 oauth_config = {}
 begin
@@ -13,5 +17,5 @@ rescue => ex
 end
 
 Rails.application.config.middleware.use OmniAuth::Builder do
-  provider :qq, oauth_config['appid'], oauth_config['secret']
+  provider :qq, oauth_config['appid'], oauth_config['secret'], { provider_ignores_state: true }
 end
diff --git a/config/routes.rb b/config/routes.rb
index e6d7add91..796d1d989 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -6,6 +6,8 @@ Rails.application.routes.draw do
 
   get 'attachments/download/:id', to: 'attachments#show'
   get 'attachments/download/:id/:filename', to: 'attachments#show'
+  get 'auth/qq/callback', to: 'oauth/qq#create'
+  get 'auth/failure', to: 'oauth/base#auth_failure'
 
   resources :edu_settings
   scope '/api' do
@@ -289,6 +291,7 @@ Rails.application.routes.draw do
         post :down_member_position
         get :right_banner
         post :appointment
+        post :update_team_title
       end
 
       collection do
@@ -1077,7 +1080,6 @@ Rails.application.routes.draw do
         post :cancel_homepage_show
         post :excellent
         post :cancel_excellent
-        post :update_team_title
       end
     end
   end
diff --git a/public/react/config/webpack.config.dev.js b/public/react/config/webpack.config.dev.js
index f335f1705..743b3685c 100644
--- a/public/react/config/webpack.config.dev.js
+++ b/public/react/config/webpack.config.dev.js
@@ -32,7 +32,7 @@ module.exports = {
   // See the discussion in https://github.com/facebookincubator/create-react-app/issues/343.s
 	// devtool: "cheap-module-eval-source-map",
   // 开启调试
-	devtool: "source-map",  // 开启调试
+	// devtool: "source-map",  // 开启调试
   // These are the "entry points" to our application.
   // This means they will be the "root" imports that are included in JS bundle.
   // The first two entry points enable "hot" CSS and auto-refreshes for JS.
diff --git a/public/react/public/js/readme.txt b/public/react/public/js/readme.txt
index 348460500..35c0dc858 100755
--- a/public/react/public/js/readme.txt
+++ b/public/react/public/js/readme.txt
@@ -14,4 +14,9 @@ http://codemirror.net
 diff_match_patch
 codemirror merge.js
 
-从 edu_tpi.js 挪过来的js
\ No newline at end of file
+从 edu_tpi.js 挪过来的js
+
+
+修改过的地方:
+Raphaël 2.1.3
+Element= -> __Element=          Element=  替换成了 __Element=
\ No newline at end of file
diff --git a/public/react/scripts/build.js b/public/react/scripts/build.js
index b874ed6b6..e3350c5be 100644
--- a/public/react/scripts/build.js
+++ b/public/react/scripts/build.js
@@ -173,7 +173,7 @@ function copyPublicFolder() {
   });
 }
 
-
+// 给build脚本增加的方法,对其生成的index.html做一些文本替换,以及cdn处理
 function generateNewIndexJsp() {
   // var combinedStream = CombinedStream.create();
   var filePath = paths.appBuild + '/index.html';
diff --git a/public/react/scripts/readme-cdn.txt b/public/react/scripts/readme-cdn.txt
new file mode 100644
index 000000000..7d090ee7a
--- /dev/null
+++ b/public/react/scripts/readme-cdn.txt
@@ -0,0 +1,16 @@
+目前是判断域名的方式动态访问对应的cdn资源
+静态资源处理在build.js中,如下代码:
+if (window.location.host == 'pre-newweb.educoder.net') {
+    _host = 'https://testali-cdn.educoder.net/react/build/'
+} else if (window.location.host == 'www.educoder.net') {
+    _host = 'https://ali-cdn.educoder.net/react/build/'
+}
+
+只对预上线和正式版做了处理
+
+动态的chunk资源处理在public-path.js中,如下代码:
+if ( window.location.host == 'pre-newweb.educoder.net') {
+    __webpack_public_path__ = 'https://testali-cdn.educoder.net/react/build/'
+} else if ( window.location.host == 'www.educoder.net') {
+    __webpack_public_path__ = 'https://ali-cdn.educoder.net/react/build/'
+}
\ No newline at end of file
diff --git a/public/react/src/modules/paths/PathDetail/Modifytext.js b/public/react/src/modules/paths/PathDetail/Modifytext.js
new file mode 100644
index 000000000..ca12659a9
--- /dev/null
+++ b/public/react/src/modules/paths/PathDetail/Modifytext.js
@@ -0,0 +1,169 @@
+import React, {Component} from 'react';
+import {Button, Layout, Input, Form} from 'antd';
+import axios from 'axios';
+import {getImageUrl} from 'educoder';
+
+
+class Modifytext extends Component {
+	constructor(props) {
+		super(props)
+		this.state = {}
+	}
+
+	componentDidMount() {
+
+	}
+
+	//重新输入教学模式
+	Modifytext = () => {
+		this.props.form.validateFieldsAndScroll((err, values) => {
+			if (!err) {
+				const url = `/paths/${this.props.pathid}/update_team_title.json`;
+				axios.post(url, {
+					team_title: values.teachingteam
+				}).then((response) => {
+					console.log(response);
+					if (response) {
+						if (response.data) {
+							if (response.data.status === 0) {
+								try {
+									this.props.showNotification("修改成功!");
+								} catch (e) {
+
+								}
+								try {
+									this.props.modifysy(2);
+								} catch (e) {
+
+								}
+
+
+							}
+						}
+					}
+
+				}).catch((error) => {
+					console.log(error)
+
+				})
+
+
+			}
+		})
+
+
+	}
+
+
+	render() {
+		const {getFieldDecorator} = this.props.form;
+		return (
+			<div>
+				<div className="ml38">
+					<style>{`
+
+            .flexRow {
+              padding: 20px 0;
+            }
+              .flexRow .name {
+                margin-left: 12px;
+                color: #666666;
+
+                text-align: center;
+                flex: 0 0 100px;
+              }
+              .flexRow .description {
+                margin-left: 10px;
+                flex: 1;
+                color: #CDCDCD;
+              }
+                .description span {
+                  margin-right: 20px;
+                  color: #05101A;
+                }
+              .flexRow .status {
+                width: 100px;
+                color: #28AC7F;
+                text-align: right;
+              }
+            .flexTable .flexTable {
+              border-bottom: 1px solid #EBEBEB;
+            }
+            
+            .settingFormsy label{
+              color: #666666;
+              font-size: 14px !important ; 
+            
+            }
+            .settingFormsy input {
+              width: 275px;
+                  height: 32px;
+            }
+            .settingFormsy input.validateInput  {
+              width: 220px;
+            }
+            .settingFormsy .formItemInline button {
+              width: 110px;
+              margin-left: 10px;
+            }
+            .settingFormsy .ant-form-item-label {
+              width: 60px;
+              text-align: left;
+            }
+            .formItemInline .ant-form-explain{
+              position:absolute;
+              bottom:-22px;
+              left:0px;
+              width:100%;
+            }
+            .yslzxueshi .ant-input{
+											height: 40px !important;
+											width: 276px !important
+											}
+											
+											// class="ant-col ant-form-item-label"
+          `}</style>
+					<div className="settingFormsy">
+						<React.Fragment>
+							<Form>
+								<div style={{
+									display: "flex",
+									flexDirection: "initial",
+									lineHeight: " 51px",
+								}}>
+									<Form.Item
+										label=""
+										className="formItemInline hideRequireTag mb20 mt20"
+									>
+										{getFieldDecorator('teachingteam', {
+											rules: [{
+												// initialValue: this.state.cityDefaultValue,
+												required: true,
+												message: '请输入模式',
+											}],
+										})(
+											<Input placeholder={`例如:教学团队`}></Input>
+										)}
+									</Form.Item>
+									<div className="flexdirections yslzxueshi ml38 ">
+										<p className="fontcolorsyslhui1 font-14  myysllineheight myyslminwidth"></p>
+										<div className=" flexdirections ml10">
+											{/*<div  className="buttongo mycompitcursor" onClick={()=>this.yhBanksfalse()}><p className="fontwenzi mycompitcursor" >取消</p></div>*/}
+											<Button type="primary" onClick={() => this.Modifytext()}>确定</Button>
+										</div>
+									</div>
+								</div>
+							</Form>
+						</React.Fragment>
+					</div>
+
+				</div>
+			</div>
+		)
+	}
+}
+
+const Modifytexts = Form.create({name: 'Modifytext'})(Modifytext);
+
+export default Modifytexts;
+
diff --git a/public/react/src/modules/paths/PathDetail/PathDetailIndex.js b/public/react/src/modules/paths/PathDetail/PathDetailIndex.js
index ca52cd9d1..b393d1bb6 100644
--- a/public/react/src/modules/paths/PathDetail/PathDetailIndex.js
+++ b/public/react/src/modules/paths/PathDetail/PathDetailIndex.js
@@ -12,7 +12,7 @@ import Modals from '../../modals/Modals';
 import axios from 'axios';
 import TPMRightSection from "../../tpm/component/TPMRightSection";
 import styled from "styled-components";
-
+import Modifytext from './Modifytext';
 const getItemStyle = (isDragging, draggableStyle) => ({
 	// change background colour if dragging
 	background: isDragging ? '#dceeff' : '',
@@ -87,7 +87,9 @@ class PathDetailIndex extends Component{
 			dataquerys:{},
 			MenuItemsindex:1,
 			MenuItemsindextype:0,
-			qrcode_img:null
+			qrcode_img: null,
+			team_title: "教学团队",
+			modify: false,
 		}
 		this.onDragEnd = this.onDragEnd.bind(this);
 
@@ -256,6 +258,7 @@ class PathDetailIndex extends Component{
 				progress:result.data.progress,
 				members:result.data.members,
 				items:  getItems(result.data.members.length),
+				team_title: result.data.team_title
 			})
 
 		}).catch((error)=>{
@@ -321,6 +324,7 @@ class PathDetailIndex extends Component{
 				progress:result.data.progress,
 				members:result.data.members,
 				items:  getItems(result.data.members.length),
+				team_title: result.data.team_title
 			})
 
 		}).catch((error)=>{
@@ -458,6 +462,50 @@ class PathDetailIndex extends Component{
 			console.log(error)
 		})
 	}
+
+
+	modifysy = (i) => {
+		if (i === 1) {
+			this.setState({
+				modify: true
+			})
+		} else if (i === 2) {
+			this.setState({
+				modify: false
+			})
+			let righturl = "/paths/" + this.props.match.params.pathId + "/right_banner.json";
+			axios.get(righturl).then((result) => {
+				if (result.data.status === 407 || result.data.status === 401) {
+					debugger
+					return;
+				}
+
+				if (result.data.status === 403) {
+					debugger
+					// window.location.href = "/403";
+					return;
+				}
+
+				this.setState({
+					// detailInfoList:result.data,
+					tags: result.data.tags,
+					progress: result.data.progress,
+					members: result.data.members,
+					items: getItems(result.data.members.length),
+					team_title: result.data.team_title
+				})
+
+			}).catch((error) => {
+				console.log(error);
+			})
+		}
+	}
+
+	setteam_title(name) {
+		this.setState({
+			team_title: name
+		})
+	}
 	render(){
 
 		this.updatamakedown("shixuns_propaedeutics");
@@ -475,7 +523,9 @@ class PathDetailIndex extends Component{
 			tags,
 			qrcode_img,
 			MenuItemsindex,
-			MenuItemsindextype
+			MenuItemsindextype,
+			team_title,
+			modify
 		} = this.state
 
 
@@ -613,7 +663,19 @@ class PathDetailIndex extends Component{
 							{
 								members ===undefined ?"":members === null ?"":
 									<div className="teacherTeam edu-back-white clearfix" id="subject_members">
-										<p className="font-16 clearfix">教学团队</p>
+										{
+											detailInfoList === undefined ? "" : detailInfoList.allow_add_member === true ?
+												(
+													modify === false ?
+														<p className="font-16 clearfix" onDoubleClick={() => this.modifysy(1)}>{team_title}</p>
+														:
+														<Modifytext {...this.props} {...this.state} pathid={this.props.match.params.pathId}
+																				modifysy={(i) => this.modifysy(i)}
+																				setteam_title={(name) => this.setteam_title(name)}></Modifytext>
+												)
+
+												: ""
+										}
 
 										{ members===undefined?
 											members && members.map((item,key)=>{
@@ -712,4 +774,4 @@ class PathDetailIndex extends Component{
 		)
 	}
 }
-export default PathDetailIndex;
\ No newline at end of file
+export default PathDetailIndex;
diff --git a/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js b/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js
index 2e6184428..11b88a037 100644
--- a/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js
+++ b/public/react/src/modules/tpm/challengesnew/TPMMDEditor.js
@@ -132,6 +132,7 @@ function create_editorMD(id, width, high, placeholder, imageUrl, callback, initV
             // Or return editormd.toolbarModes[name]; // full, simple, mini
             // Using "||" set icons align right.
             const icons = ["bold", "italic", "|", "list-ul", "list-ol", "|", "code", "code-block", "link", "|", "testIcon", "testIcon1", '|', "image", "table", '|', "watch", "clear"];
+            // 试卷处用到的填空题新增按钮
             if (__that.props.showNullButton) {
                 icons.push('nullBtton')
             }
@@ -228,12 +229,14 @@ export default class TPMMDEditor extends Component {
         const imageUrl = `/api/attachments.json`;
         // 创建editorMd
         let react_id = `react_${_id}`;
+        // 将实例存到了window
         window[react_id] = this
         const answers_editormd = create_editorMD(_id, '100%', this.props.height, _placeholder, imageUrl, (_editorName) => {
             const __editorName = _editorName;
             react_id = `react_${__editorName.id}`;
             const that = window[react_id]
-
+            
+            // 一个延迟的recreate或resize,不加这段代码,md初始化可能会出现样式问题
             setTimeout(() => {
                 if (that.props.needRecreate == true) {
                     __editorName.recreate() // 注意 必须在setValue之前触发,不然会清空
@@ -268,6 +271,7 @@ export default class TPMMDEditor extends Component {
                 that.props.onCMBeforeChange(cm,change)
             })
             that.answers_editormd = __editorName;
+            // 这里应该可以去掉了,方便调试加的
             window[__editorName.id+'_'] = __editorName;
         }, initValue, this.onEditorChange,this.props.watch, {
             noStorage: this.props.noStorage,
@@ -276,6 +280,7 @@ export default class TPMMDEditor extends Component {
         }, this);
         
     }
+    // 用在form里时,validate失败时出现一个红色边框
     showError = () => {
         this.setState({showError: true})
     }
diff --git a/public/react/src/modules/user/usersInfo/InfosCourse.js b/public/react/src/modules/user/usersInfo/InfosCourse.js
index 14046d495..8e2478510 100644
--- a/public/react/src/modules/user/usersInfo/InfosCourse.js
+++ b/public/react/src/modules/user/usersInfo/InfosCourse.js
@@ -151,6 +151,17 @@ class InfosCourse extends Component{
     return(
       <div className="educontent">
         <Spin size="large" spinning={isSpin}>
+          <style>
+            {
+              `
+              .white-panel li.active {
+                  border-radius: 24px;
+                  border: 0px solid #4CACFF;
+                  color: #4CACFF;
+              }
+              `
+            }
+          </style>
         <div className="white-panel edu-back-white pt20 pb20 clearfix ">
           <li className={category ? "" : "active"}><a href="javascript:void(0)" onClick={()=>this.changeCategory()}>全部</a></li>
           <li className={category=="manage" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("manage")}>{is_current ? "我":"TA"}管理的</a></li>
diff --git a/public/react/src/modules/user/usersInfo/InfosPackage.js b/public/react/src/modules/user/usersInfo/InfosPackage.js
index 4b2c655c3..207d32480 100644
--- a/public/react/src/modules/user/usersInfo/InfosPackage.js
+++ b/public/react/src/modules/user/usersInfo/InfosPackage.js
@@ -168,6 +168,17 @@ class InfosPackage extends Component{
 					modalSave={this.state.ModalSave}
 				/>
 				<Spin size="large" spinning={isSpin}>
+					<style>
+						{
+							`
+              .white-panel li.active {
+                  border-radius: 24px;
+                  border: 0px solid #4CACFF;
+                  color: #4CACFF;
+              }
+              `
+						}
+					</style>
 					<div className="white-panel edu-back-white pt20 pb20 clearfix ">
 						<li className={category ? "" : "active"}><a onClick={()=>this.changeCategory()}>全部</a></li>
 						<li className={category=="manage" ? "active" : ""}><a onClick={()=>this.changeCategory("manage")}>{is_current ? "我":"TA"}管理的</a></li>
@@ -289,4 +300,4 @@ class InfosPackage extends Component{
 		)
 	}
 }
-export default InfosPackage;
\ No newline at end of file
+export default InfosPackage;
diff --git a/public/react/src/modules/user/usersInfo/InfosPath.js b/public/react/src/modules/user/usersInfo/InfosPath.js
index 0b1437f40..429495cf1 100644
--- a/public/react/src/modules/user/usersInfo/InfosPath.js
+++ b/public/react/src/modules/user/usersInfo/InfosPath.js
@@ -160,6 +160,17 @@ class InfosPath extends Component{
     return(
       <div className="educontent">
         <Spin size="large" spinning={isSpin}>
+					<style>
+						{
+							`
+              .white-panel li.active {
+                  border-radius: 24px;
+                  border: 0px solid #4CACFF;
+                  color: #4CACFF;
+              }
+              `
+						}
+					</style>
         <div className="white-panel edu-back-white pt20 pb20 clearfix ">
           <li className={category ? "" : "active"}><a href="javascript:void(0)" onClick={()=>this.changeCategory()}>全部</a></li>
           <li className={category=="manage" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("manage")}>{is_current ? "我":"TA"}管理的</a></li>
diff --git a/public/react/src/modules/user/usersInfo/InfosProject.js b/public/react/src/modules/user/usersInfo/InfosProject.js
index 302d6def1..ee2cc13b0 100644
--- a/public/react/src/modules/user/usersInfo/InfosProject.js
+++ b/public/react/src/modules/user/usersInfo/InfosProject.js
@@ -162,6 +162,17 @@ class InfosProject extends Component{
     return(
       <div className="educontent">
         <Spin size="large" spinning={isSpin}>
+					<style>
+						{
+							`
+              .white-panel li.active {
+                  border-radius: 24px;
+                  border: 0px solid #4CACFF;
+                  color: #4CACFF;
+              }
+              `
+						}
+					</style>
         <div className="white-panel edu-back-white pt20 pb20 clearfix ">
           <li className={category ? "" : "active"}><a href="javascript:void(0)" onClick={()=>this.changeCategory()}>全部</a></li>
           <li className={category=="manage" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("manage")}>{is_current ? "我":"TA"}管理的</a></li>
diff --git a/public/react/src/modules/user/usersInfo/InfosShixun.js b/public/react/src/modules/user/usersInfo/InfosShixun.js
index cad70e716..0b6a33571 100644
--- a/public/react/src/modules/user/usersInfo/InfosShixun.js
+++ b/public/react/src/modules/user/usersInfo/InfosShixun.js
@@ -160,6 +160,17 @@ class InfosShixun extends Component{
     return(
       <div className="educontent">
         <Spin size="large" spinning={isSpin}>
+					<style>
+						{
+							`
+              .white-panel li.active {
+                  border-radius: 24px;
+                  border: 0px solid #4CACFF;
+                  color: #4CACFF;
+              }
+              `
+						}
+					</style>
         <div className="white-panel edu-back-white pt20 pb20 clearfix ">
           <li className={category ? "" : "active"}><a href="javascript:void(0)" onClick={()=>this.changeCategory()}>全部</a></li>
           <li className={category=="manage" ? "active" : ""}><a href="javascript:void(0)" onClick={()=>this.changeCategory("manage")}>{is_current ? "我":"TA"}管理的</a></li>