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>