diff --git a/README.md b/README.md
index 8dcb6d131..90f519de4 100644
--- a/README.md
+++ b/README.md
@@ -1,69 +1,70 @@
-# README
-
-This README would normally document whatever steps are necessary to get the
-application up and running.
-
-Things you may want to cover:
-
-* Ruby version
-
-* System dependencies
-
-* Configuration
-
-* Database creation
-
-* Database initialization
-
-* How to run the test suite
-
-* Services (job queues, cache servers, search engines, etc.)
-
-* Deployment instructions
-
-* ...
-#### Jbuilder介绍
-Jbuilder: https://github.com/rails/jbuilder
-
-#### Rails5 介绍
-rails guide: https://ruby-china.github.io/rails-guides/v5.0/
-
-#### API设计文档
-doc for api: https://www.showdoc.cc/web/#/127895880302646?page_id=729221359592009
-user:Hjqreturn PW:12345678
-
-#### 测试版访问地址:https://testeduplus2.educoder.net
-
-#### 实训平台繁忙
- 仓库异常:繁忙等级(81)
-
-#### 新版域名跳转规则
-新版域名要求总结:testeduplus2.educoder.net/(主要提供实训、实训课堂等业务)
-目前有两个域名testbdweb.educoder.net(老版:主要提供课堂、项目、个人主页、后台等服务)
-
-要求:
-1、两服务域名都应该启动‘提供服务
-
-2、如果请求链接包含以下的形式,则域名跳至testeduplus2.educoder.net
-testeduplus2.educoder.net/shixuns
-testeduplus2.educoder.net/shixuns/*
-testeduplus2.educoder.net/paths
-testeduplus2.educoder.net/paths/*
-testeduplus2.educoder.net/myshixuns/
-testeduplus2.educoder.net/tasks/*
-testeduplus2.educoder.net/games/*
-
-如果不满足上述需求的,域名全部跳转至testbdweb.educoder.net
-比如:门户首页,如果访问:testeduplus2.educoder.net 应为没包含上述链接。则调制testbdweb.educoder.net
-在比如:testeduplus2.educoder.net /users/Hjqreturn没包含上述规则,则跳转到testbdweb.educoder.net/users/Hjqreturn
-
-
-# 需要重构user_extensions 相关sql语句的地方标记 REDO:Extention
-
-# 文件上传:ActiveStorage
-# 新能:bootsnap
-
-# 注意事项:
-# 第一次部署需要执行一些rake任务
-# 配置redis地址
+# README
+https://www.trustie.net/issues/24719
+[云上实验室] Logo、导航、底部备案信息定制化
+This README would normally document whatever steps are necessary to get the
+application up and running.
+
+Things you may want to cover:
+
+* Ruby version
+
+* System dependencies
+
+* Configuration
+
+* Database creation
+
+* Database initialization
+
+* How to run the test suite
+
+* Services (job queues, cache servers, search engines, etc.)
+
+* Deployment instructions
+
+* ...
+#### Jbuilder介绍
+Jbuilder: https://github.com/rails/jbuilder
+
+#### Rails5 介绍
+rails guide: https://ruby-china.github.io/rails-guides/v5.0/
+
+#### API设计文档
+doc for api: https://www.showdoc.cc/web/#/127895880302646?page_id=729221359592009
+user:Hjqreturn PW:12345678
+
+#### 测试版访问地址:https://testeduplus2.educoder.net
+
+#### 实训平台繁忙
+ 仓库异常:繁忙等级(81)
+
+#### 新版域名跳转规则
+新版域名要求总结:testeduplus2.educoder.net/(主要提供实训、实训课堂等业务)
+目前有两个域名testbdweb.educoder.net(老版:主要提供课堂、项目、个人主页、后台等服务)
+
+要求:
+1、两服务域名都应该启动‘提供服务
+
+2、如果请求链接包含以下的形式,则域名跳至testeduplus2.educoder.net
+testeduplus2.educoder.net/shixuns
+testeduplus2.educoder.net/shixuns/*
+testeduplus2.educoder.net/paths
+testeduplus2.educoder.net/paths/*
+testeduplus2.educoder.net/myshixuns/
+testeduplus2.educoder.net/tasks/*
+testeduplus2.educoder.net/games/*
+
+如果不满足上述需求的,域名全部跳转至testbdweb.educoder.net
+比如:门户首页,如果访问:testeduplus2.educoder.net 应为没包含上述链接。则调制testbdweb.educoder.net
+在比如:testeduplus2.educoder.net /users/Hjqreturn没包含上述规则,则跳转到testbdweb.educoder.net/users/Hjqreturn
+
+
+# 需要重构user_extensions 相关sql语句的地方标记 REDO:Extention
+
+# 文件上传:ActiveStorage
+# 新能:bootsnap
+
+# 注意事项:
+# 第一次部署需要执行一些rake任务
+# 配置redis地址
# 配置gitlab/intializers/gitlab_config.yml
\ No newline at end of file
diff --git a/app/controllers/admins/competitions_controller.rb b/app/controllers/admins/competitions_controller.rb
new file mode 100644
index 000000000..3d6bef819
--- /dev/null
+++ b/app/controllers/admins/competitions_controller.rb
@@ -0,0 +1,15 @@
+class Admins::CompetitionsController < Admins::BaseController
+
+ def index
+ params[:sort_by] = params[:sort_by].presence || 'created_on'
+ params[:sort_direction] = params[:sort_direction].presence || 'desc'
+ @competitions = custom_sort Competition.all, params[:sort_by], params[:sort_direction]
+ @params_page = params[:page] || 1
+ @competitions = paginate @competitions
+
+ respond_to do |format|
+ format.js
+ format.html
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/boards_controller.rb b/app/controllers/boards_controller.rb
index 1081a82ce..2bcc8d8f6 100644
--- a/app/controllers/boards_controller.rb
+++ b/app/controllers/boards_controller.rb
@@ -2,7 +2,7 @@ class BoardsController < ApplicationController
before_action :require_login, :check_auth
before_action :find_course, only: [:create]
before_action :set_board, except: [:create]
- before_action :teacher_or_admin_allowed
+ before_action :teacher_allowed
def index
@boards = @course.boards.includes(messages: [:last_reply, :author])
diff --git a/app/controllers/course_groups_controller.rb b/app/controllers/course_groups_controller.rb
index 0e16d1bac..bfdb959b4 100644
--- a/app/controllers/course_groups_controller.rb
+++ b/app/controllers/course_groups_controller.rb
@@ -2,7 +2,7 @@ class CourseGroupsController < ApplicationController
before_action :require_login, :check_auth
before_action :set_group, except: [:create]
before_action :find_course, only: [:create]
- before_action :teacher_or_admin_allowed
+ before_action :teacher_allowed
def create
tip_exception("分班名称不能为空") if params[:name].blank?
diff --git a/app/controllers/course_modules_controller.rb b/app/controllers/course_modules_controller.rb
index fccc28f6d..0bef519fd 100644
--- a/app/controllers/course_modules_controller.rb
+++ b/app/controllers/course_modules_controller.rb
@@ -2,7 +2,8 @@ class CourseModulesController < ApplicationController
before_action :require_login, :check_auth
before_action :set_module, except: [:unhidden_modules]
before_action :find_course, only: [:unhidden_modules]
- before_action :teacher_or_admin_allowed
+ before_action :teacher_or_admin_allowed, except: [:add_second_category]
+ before_action :teacher_allowed, only: [:add_second_category]
# 模块置顶
def sticky_module
diff --git a/app/controllers/course_second_categories_controller.rb b/app/controllers/course_second_categories_controller.rb
index e5c3366cd..2de1637f2 100644
--- a/app/controllers/course_second_categories_controller.rb
+++ b/app/controllers/course_second_categories_controller.rb
@@ -1,7 +1,7 @@
class CourseSecondCategoriesController < ApplicationController
before_action :require_login, :check_auth
before_action :set_category
- before_action :teacher_or_admin_allowed
+ before_action :teacher_allowed
# 目录重命名
def rename_category
diff --git a/app/models/attachment.rb b/app/models/attachment.rb
index 9c60317bd..8b7034ab9 100644
--- a/app/models/attachment.rb
+++ b/app/models/attachment.rb
@@ -98,7 +98,7 @@ class Attachment < ApplicationRecord
def become_history
history = self.attachment_histories.first
- new_attachment_history = AttachmentHistory.new(self.attributes.except("id", "resource_bank_id", "unified_setting", "course_second_category_id").merge(
+ new_attachment_history = AttachmentHistory.new(self.attributes.except("id", "resource_bank_id", "unified_setting", "course_second_category_id", "delay_publish").merge(
attachment_id: self.id,
version: history.nil? ? 1 : history.version + 1,
))
@@ -106,7 +106,7 @@ class Attachment < ApplicationRecord
end
def copy_attributes_from_new_attachment(new_attachment)
- self.attributes = new_attachment.attributes.dup.except("id","container_id","container_type","is_public","downloads", "quotes",'is_publish','publish_time')
+ self.attributes = new_attachment.attributes.dup.except("id","container_id","container_type","is_public","downloads", "quotes",'is_publish','publish_time', "delay_publish")
end
def set_public(is_public)
diff --git a/app/models/competition_mode_setting.rb b/app/models/competition_mode_setting.rb
new file mode 100644
index 000000000..b6bafa7c3
--- /dev/null
+++ b/app/models/competition_mode_setting.rb
@@ -0,0 +1,3 @@
+class CompetitionModeSetting < ApplicationRecord
+ belongs_to :course
+end
diff --git a/app/views/admins/competitions/index.html.erb b/app/views/admins/competitions/index.html.erb
new file mode 100644
index 000000000..8fa238181
--- /dev/null
+++ b/app/views/admins/competitions/index.html.erb
@@ -0,0 +1,7 @@
+<% define_admin_breadcrumbs do %>
+ <% add_admin_breadcrumb('竞赛列表', admins_competitions_path) %>
+<% end %>
+
+
+ <%= render partial: 'admins/shixuns/shared/list', locals: { shixuns: @shixuns } %>
+
diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb
index 145910928..ca6fb2a46 100644
--- a/app/views/admins/shared/_sidebar.html.erb
+++ b/app/views/admins/shared/_sidebar.html.erb
@@ -66,6 +66,8 @@
<% end %>
+ <%= sidebar_item(admins_competitions_path, '竞赛', icon: 'trophy', controller: 'admins-competitions') %>
+
<%= sidebar_item_group('#setting-submenu', '网站建设', icon: 'cogs') do %>
<%= sidebar_item(admins_carousels_path, '轮播图', icon: 'image', controller: 'admins-carousels') %>
diff --git a/app/views/competitions/competitions/index.json.jbuilder b/app/views/competitions/competitions/index.json.jbuilder
index f0d70f69e..400f17379 100644
--- a/app/views/competitions/competitions/index.json.jbuilder
+++ b/app/views/competitions/competitions/index.json.jbuilder
@@ -20,7 +20,7 @@ json.competitions do
if section
json.current_stage do
- json.name = section.competition_stage.name
+ json.name section.competition_stage.name
json.start_time section.display_start_time
json.end_time section.display_end_time
end
diff --git a/app/views/courses/mine.json.jbuilder b/app/views/courses/mine.json.jbuilder
index 41368d883..fc6a5becc 100644
--- a/app/views/courses/mine.json.jbuilder
+++ b/app/views/courses/mine.json.jbuilder
@@ -1,5 +1,6 @@
json.partial! "commons/success"
-json.data do
- json.array! @courses, :id, :name, :updated_at, :created_at, :end_date
+json.data @courses do |course|
+ json.(course, :id, :name, :updated_at, :end_date)
+ json.created_at course.created_at.strftime("%Y-%m-%d")
end
diff --git a/config/routes.rb b/config/routes.rb
index 32725e8e9..f6f8db066 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -980,6 +980,8 @@ Rails.application.routes.draw do
resource :laboratory_setting, only: [:show, :update]
resource :laboratory_user, only: [:create, :destroy]
end
+
+ resources :competitions, only: [:index, :destroy]
end
resources :colleges, only: [] do
diff --git a/db/migrate/20191015013924_add_new_column_to_competitions.rb b/db/migrate/20191015013924_add_new_column_to_competitions.rb
new file mode 100644
index 000000000..616a46059
--- /dev/null
+++ b/db/migrate/20191015013924_add_new_column_to_competitions.rb
@@ -0,0 +1,6 @@
+class AddNewColumnToCompetitions < ActiveRecord::Migration[5.2]
+ def change
+ add_column :competitions, :bonus, :integer, default: 0
+ add_column :competitions, :mode, :integer, default: 0
+ end
+end
diff --git a/db/migrate/20191015015723_create_competition_mode_settings.rb b/db/migrate/20191015015723_create_competition_mode_settings.rb
new file mode 100644
index 000000000..5d170eeab
--- /dev/null
+++ b/db/migrate/20191015015723_create_competition_mode_settings.rb
@@ -0,0 +1,11 @@
+class CreateCompetitionModeSettings < ActiveRecord::Migration[5.2]
+ def change
+ create_table :competition_mode_settings do |t|
+ t.references :course
+ t.datetime :start_time
+ t.datetime :end_time
+
+ t.timestamps
+ end
+ end
+end
diff --git a/public/react/public/index.html b/public/react/public/index.html
index f6eef196a..9b757d2c4 100755
--- a/public/react/public/index.html
+++ b/public/react/public/index.html
@@ -13,7 +13,7 @@
-
+
- EduCoder
+
+
diff --git a/public/react/src/App.js b/public/react/src/App.js
index 34b5d1a4f..fd945914a 100644
--- a/public/react/src/App.js
+++ b/public/react/src/App.js
@@ -9,7 +9,7 @@ import {
Route,
Switch
} from 'react-router-dom';
-
+import axios from 'axios';
import '@icedesign/base/dist/ICEDesignBase.css';
import '@icedesign/base/index.scss';
@@ -287,6 +287,7 @@ class App extends Component {
Addcoursestypes:false,
mydisplay:false,
occupation:0,
+ mygetHelmetapi:undefined,
}
}
@@ -327,7 +328,6 @@ class App extends Component {
}
componentDidMount() {
this.disableVideoContextMenu();
-
// force an update if the URL changes
history.listen(() => {
this.forceUpdate()
@@ -336,7 +336,8 @@ class App extends Component {
$("html").animate({ scrollTop: $('html').scrollTop() - 0 })
});
- initAxiosInterceptors(this.props)
+ initAxiosInterceptors(this.props);
+ this.getAppdata();
//
// axios.interceptors.response.use((response) => {
// // console.log("response"+response);
@@ -362,15 +363,78 @@ class App extends Component {
this.setState({
isRender:false,
})
- }
-
- render() {
+ };
+ //获取当前定制信息
+ getAppdata=()=>{
+ let url = "/setting.json";
+ axios.get(url).then((response) => {
+ // console.log("app.js开始请求/setting.json");
+ // console.log("获取当前定制信息");
+ if(response){
+ if(response.data){
+ this.setState({
+ mygetHelmetapi:response.data.setting
+ });
+ document.title = response.data.setting.name;
+ var link = document.createElement('link'),
+ oldLink = document.getElementById('dynamic-favicon');
+ link.id = 'dynamic-favicon';
+ link.rel = 'shortcut icon';
+ link.href = '/'+response.data.setting.tab_logo_url;
+ if (oldLink) {
+ document.head.removeChild(oldLink);
+ }
+ document.head.appendChild(link);
+ }else {
+ document.title = "EduCoder";
+ var link = document.createElement('link'),
+ oldLink = document.getElementById('dynamic-favicon');
+ link.id = 'dynamic-favicon';
+ link.rel = 'shortcut icon';
+ link.href = "/react/build/./favicon.ico";
+ if (oldLink) {
+ document.head.removeChild(oldLink);
+ }
+ document.head.appendChild(link);
+ }
+
+ }else{
+ document.title = "EduCoder";
+ var link = document.createElement('link'),
+ oldLink = document.getElementById('dynamic-favicon');
+ link.id = 'dynamic-favicon';
+ link.rel = 'shortcut icon';
+ link.href = "/react/build/./favicon.ico";
+ if (oldLink) {
+ document.head.removeChild(oldLink);
+ }
+ document.head.appendChild(link);
+ }
+ }).catch((error) => {
+ document.title = "EduCoder";
+ var link = document.createElement('link'),
+ oldLink = document.getElementById('dynamic-favicon');
+ link.id = 'dynamic-favicon';
+ link.rel = 'shortcut icon';
+ link.href = "/react/build/./favicon.ico";
+ if (oldLink) {
+ document.head.removeChild(oldLink);
+ }
+ document.head.appendChild(link);
+ });
+ };
+ render() {
+ let{mygetHelmetapi}=this.state;
+ // console.log("appappapp");
+ // console.log(mygetHelmetapi);
return (
+
+
this.Modifyloginvalue()}>
@@ -413,10 +477,22 @@ class App extends Component {
{
+
+ return ()
+ }
+ }
/>
{
+
+ return ()
+ }
+ }
/>
{
+
+ return ()
+ }
+ }
/>
{/*课堂*/}
-
+
{/*
*/}
@@ -502,7 +584,12 @@ class App extends Component {
render={
(props)=>()
}/>
-
+ ()
+ }
+ />
@@ -625,4 +712,4 @@ moment.defineLocale('zh-cn', {
doy: 4 // The week that contains Jan 4th is the first week of the year.
}
});
-export default SnackbarHOC()(App);
\ No newline at end of file
+export default SnackbarHOC()(App) ;
\ No newline at end of file
diff --git a/public/react/src/AppConfig.js b/public/react/src/AppConfig.js
index e1d5da561..9cf68503d 100644
--- a/public/react/src/AppConfig.js
+++ b/public/react/src/AppConfig.js
@@ -94,9 +94,15 @@ export function initAxiosInterceptors(props) {
}
}
- if (requestMap[config.url] === true) { // 避免重复的请求
+ if (config.method === "post") {
+ if (requestMap[config.url] === true) { // 避免重复的请求 导致页面f5刷新 也会被阻止 显示这个方法会影响到定制信息定制信息是get 请求
+ // console.log(config);
+ // console.log(JSON.parse(config));
+ // console.log(config.url);
+ // console.log("被阻止了是重复请求=================================");
return false;
}
+ }
// 非file_update请求
if (config.url.indexOf('update_file') === -1) {
requestMap[config.url] = true;
diff --git a/public/react/src/modules/courses/exercise/Studentshavecompletedthelist.js b/public/react/src/modules/courses/exercise/Studentshavecompletedthelist.js
index 438c07aeb..e1a1f17f9 100644
--- a/public/react/src/modules/courses/exercise/Studentshavecompletedthelist.js
+++ b/public/react/src/modules/courses/exercise/Studentshavecompletedthelist.js
@@ -2663,6 +2663,9 @@ class Studentshavecompletedthelist extends Component {
.ant-spin-nested-loading > div > .ant-spin .ant-spin-dot {
top: 72%;}
}
+ .ysltableows2 .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
+ padding: 9px;
+ }
`}
{data === undefined ? "" :
div > .ant-spin .ant-spin-dot {
top: 72%;}
}
+ .ysltableows2 .ant-table-thead > tr > th, .ant-table-tbody > tr > td {
+ padding: 9px;
+ }
`}
-
+
{datas === undefined ? "" :
{
- // console.log("Commonheadofthetestpaper");
+ console.log("Commonheadofthetestpaper 试卷公用头部");
var exercise_id = this.props.match.params.Id;
var url = `/exercises/${exercise_id}/common_header.json`;
axios.get(url).then((response) => {
@@ -249,6 +249,19 @@ class Testpapersettinghomepage extends Component{
// DownloadMessageval:undefined
// })
// }
+ getsetdata =()=>{
+ // console.log("Testpapersettinghomepage");
+ // console.log("getsetdatassssss");
+ let{tab}=this.state;
+ try {
+ if(tab[0]==="0"){
+ this.child.Teacherliststudentlist();
+ }
+ }catch (e) {
+
+ }
+
+ }
bindRef = ref => { this.child = ref };
goback=()=>{
// let {datalist}=this.state;
@@ -410,6 +423,7 @@ class Testpapersettinghomepage extends Component{
Exercisetype={"exercise"}
action={this.Commonheadofthetestpaper}
single={true}
+ getsetdata={this.getsetdata}
>
:"":""}
{isAdmin === true? 编辑试卷:""}
diff --git a/public/react/src/modules/courses/members/ChangeRolePop.js b/public/react/src/modules/courses/members/ChangeRolePop.js
index 455e851ee..adc4fa26a 100644
--- a/public/react/src/modules/courses/members/ChangeRolePop.js
+++ b/public/react/src/modules/courses/members/ChangeRolePop.js
@@ -6,7 +6,7 @@ import axios from 'axios'
/**
角色数组, CREATOR: 创建者, PROFESSOR: 教师, ASSISTANT_PROFESSOR: 助教, STUDENT: 学生
*/
-function ChangeRolePop({ member_roles = [], record, courseId, onChangeRoleSuccess, showNotification, getUserId, fetchUser }) {
+function ChangeRolePop({ member_roles = [], record, courseId, onChangeRoleSuccess, showNotification, getUserId, fetchUser, style }) {
const [checkBoxRoles, setCheckBoxRoles] = useState(member_roles)
// useEffect(() => {
// if (checkBoxRoles.length != member_roles.length) { // 死循环
@@ -75,7 +75,7 @@ function ChangeRolePop({ member_roles = [], record, courseId, onChangeRoleSucces
}
>
- 修改角色
+ 修改角色
)
}
diff --git a/public/react/src/modules/courses/members/studentsList.js b/public/react/src/modules/courses/members/studentsList.js
index 1f6bf9096..a63509c59 100644
--- a/public/react/src/modules/courses/members/studentsList.js
+++ b/public/react/src/modules/courses/members/studentsList.js
@@ -320,6 +320,9 @@ class studentsList extends Component{
isAdmin && on('updateNavSuccess', this.updateNavSuccess)
}
componentWillUnmount() {
+ if (this.clipboard) {
+ this.clipboard.destroy()
+ }
const isAdmin = this.props.isAdmin()
if (isAdmin) {
off('addStudentSuccess', this.addStudentSuccessListener)
@@ -420,12 +423,14 @@ class studentsList extends Component{
invite_code: result.data.invite_code,
isSpin:false
}, () => {
- if (!this.clipboard) {
- const clipboard = new ClipboardJS('.copybtn');
- clipboard.on('success', (e) => {
- this.props.showNotification('复制成功')
- });
- this.clipboard = clipboard
+ if (course_group_id) {
+ if (!this.clipboard) {
+ const clipboard = new ClipboardJS('.copybtn');
+ clipboard.on('success', (e) => {
+ this.props.showNotification('复制成功')
+ });
+ this.clipboard = clipboard
+ }
}
})
}
@@ -598,7 +603,7 @@ class studentsList extends Component{
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification('删除成功')
- this.props.history.push(`/courses/${coursesId}/course_groups`)
+ this.props.history.push(`/courses/${courseId}/course_groups`)
}
})
.catch(function (error) {
@@ -706,7 +711,7 @@ class studentsList extends Component{
- { this.props.history.push(`/courses/${coursesids}/course_groups`)}}
+ { this.props.history.push(`/courses/${courseId}/course_groups`)}}
style={{color: '#212121', verticalAlign: 'initial', marginRight: '14px' }}
>
{course_group_name || '未分班'}
@@ -751,7 +756,7 @@ class studentsList extends Component{
!isStudentPage && !isCourseEnd && isAdmin && this.addDir()}>新建分班 }
{
- !isStudentPage && isStudent && !isParent && course_group_id != 0 && this.addToDir()}>加入分班 }
+ !isStudentPage && isStudent && !isParent && course_group_id != 0 && this.addToDir()}>加入分班 }
-
- {/*<%= link_to image_tag("/images/educoder/logo.png", alt:"高校智能化教学与实训平台", className:"logoimg"), home_path %>*/}
+ {
+ mygetHelmetapi2!==undefined&&mygetHelmetapi2.navbar!==null&&mygetHelmetapi2.navbar!==undefined&&mygetHelmetapi2.navbar.length>0?
+
+
+
+ // :mygetHelmetapi2===undefined||mygetHelmetapi2.navbar===null||mygetHelmetapi2.navbar===undefined||mygetHelmetapi2.navbar.length===0?
+ //
+ //
+ //
+ //
+ :
+
+
+
+
+ }
-
-
-
-
-
-