diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js
index 72a2ff118..196404300 100644
--- a/app/assets/javascripts/admin.js
+++ b/app/assets/javascripts/admin.js
@@ -32,8 +32,11 @@ $(document).on('turbolinks:load', function(){
// flash alert提示框自动关闭
if($('.admin-alert-container .alert').length > 0){
setTimeout(function(){
- $('.admin-alert-container .alert').alert('close');
+ $('.admin-alert-container .alert:not(.alert-danger)').alert('close');
}, 2000);
+ setTimeout(function(){
+ $('.admin-alert-container .alert.alert-danger').alert('close');
+ }, 5000);
}
});
diff --git a/app/assets/javascripts/admins/mirror_repositories/edit.js b/app/assets/javascripts/admins/mirror_repositories/edit.js
new file mode 100644
index 000000000..7fb3ad10d
--- /dev/null
+++ b/app/assets/javascripts/admins/mirror_repositories/edit.js
@@ -0,0 +1,19 @@
+$(document).on('turbolinks:load', function() {
+ if ($('body.admins-mirror-repositories-edit-page, body.admins-mirror-repositories-update-page').length > 0) {
+ var $form = $('form.edit-mirror');
+
+ $form.validate({
+ errorElement: 'span',
+ errorClass: 'danger text-danger',
+ rules: {
+ "mirror_repository[type_name]": {
+ required: true
+ }
+ }
+ });
+
+ $form.submit(function(e){
+ if(!$form.valid()){ e.preventDefault(); }
+ });
+ }
+});
\ No newline at end of file
diff --git a/app/assets/javascripts/admins/mirror_repositories/index.js b/app/assets/javascripts/admins/mirror_repositories/index.js
new file mode 100644
index 000000000..2e30bdd94
--- /dev/null
+++ b/app/assets/javascripts/admins/mirror_repositories/index.js
@@ -0,0 +1,4 @@
+$(document).on('turbolinks:load', function() {
+ if ($('body.admins-mirror-repositories-index-page').length > 0) {
+ }
+});
\ No newline at end of file
diff --git a/app/assets/javascripts/admins/modals/admin-choose-mirror-modal.js b/app/assets/javascripts/admins/modals/admin-choose-mirror-modal.js
new file mode 100644
index 000000000..6111b2401
--- /dev/null
+++ b/app/assets/javascripts/admins/modals/admin-choose-mirror-modal.js
@@ -0,0 +1,32 @@
+$(document).on('turbolinks:load', function() {
+ $('.admin-modal-container').on('show.bs.modal', '.modal.admin-choose-mirror-modal', function(){
+ var $modal = $('.modal.admin-choose-mirror-modal');
+ var $form = $modal.find('form.admin-choose-mirror-form');
+
+ var validateForm = function(){
+ var checkedValue = $form.find('input[name="mirror_number"]:checked').val();
+
+ if(checkedValue == undefined){
+ $modal.find('.error').html('必须选择一种镜像保存!');
+ return false;
+ }
+ return true;
+ }
+
+ $modal.on('click', '.submit-btn', function(){
+ $form.find('.error').html('');
+ var url = $form.attr('action');
+
+ if (validateForm()) {
+ $.ajax({
+ method: 'POST',
+ dataType: 'script',
+ url: url,
+ data: $form.serialize(),
+ }).done(function(){
+ $modal.modal('hide');
+ });
+ }
+ });
+ })
+});
\ No newline at end of file
diff --git a/app/assets/javascripts/admins/modals/admin-replace-mirror-modal.js b/app/assets/javascripts/admins/modals/admin-replace-mirror-modal.js
new file mode 100644
index 000000000..8b7a129a6
--- /dev/null
+++ b/app/assets/javascripts/admins/modals/admin-replace-mirror-modal.js
@@ -0,0 +1,89 @@
+$(document).on('turbolinks:load', function() {
+ var $modal = $('.modal.admin-replace-mirror-modal');
+ if ($modal.length > 0) {
+ var $form = $modal.find('form.admin-replace-mirror-form');
+ var $mirrorIdInput = $modal.find('.modal-body input[name="mirror_id"]');
+ var $mirrorSelect = $modal.find('.new-mirror-select');
+
+ var setMirror = function(id, name){
+ $mirrorIdInput.val(id);
+ $form.find('.mirror-id-container').html(id);
+ $form.find('.mirror-name-container').html(name);
+ }
+
+ $form.validate({
+ errorElement: 'span',
+ errorClass: 'danger text-danger',
+ rules: {
+ new_mirror_id: {
+ required: true
+ },
+ },
+ messages: {
+ new_mirror_id: {
+ required: '请选择新镜像'
+ }
+ }
+ });
+
+ // modal ready fire
+ $modal.on('show.bs.modal', function (event) {
+ var $link = $(event.relatedTarget);
+
+ var mirrorId = $link.data('id');
+ var mirrorName = $link.data('name');
+
+ setMirror(mirrorId, mirrorName);
+ $mirrorSelect.select2('val', ' ');
+ });
+ $modal.on('hide.bs.modal', function () {
+ setMirror('', '');
+ $mirrorSelect.select2('val', ' ');
+ $('#new_mirror_id-error').remove();
+ });
+
+ $mirrorSelect.select2({
+ theme: 'bootstrap4',
+ placeholder: '输入要合并的镜像名',
+ minimumInputLength: 1,
+ ajax: {
+ url: '/admins/mirror_repositories/for_select',
+ dataType: 'json',
+ data: function(params){
+ return { keyword: params.term };
+ },
+ processResults: function(data){
+ return { results: data.mirrors }
+ }
+ },
+ templateResult: function (item) {
+ if(!item.id || item.id === '') return item.text;
+ return item.name;
+ },
+ templateSelection: function(item){
+ if (item.id) {
+ $('#new_mirror_id-error').remove();
+ $('#new_mirror_id').val(item.id);
+ }
+ return item.name || item.text;
+ }
+ });
+
+ $modal.on('click', '.submit-btn', function(){
+ $form.find('.error').html('');
+
+ if ($form.valid()) {
+ var url = $form.data('url');
+
+ $.ajax({
+ method: 'POST',
+ dataType: 'script',
+ url: url,
+ data: $form.serialize(),
+ }).done(function(){
+ $modal.modal('hide');
+ });
+ }
+ });
+ }
+});
\ No newline at end of file
diff --git a/app/assets/stylesheets/admin.scss b/app/assets/stylesheets/admin.scss
index 0aa1329ca..36f1e537f 100644
--- a/app/assets/stylesheets/admin.scss
+++ b/app/assets/stylesheets/admin.scss
@@ -47,4 +47,9 @@ label.error {
.flex-1 {
flex: 1;
-}
\ No newline at end of file
+}
+
+.font-12 { font-size: 12px !important; }
+.font-14 { font-size: 14px !important; }
+.font-16 { font-size: 16px !important; }
+.font-18 { font-size: 18px !important; }
\ No newline at end of file
diff --git a/app/controllers/admins/choose_mirror_repositories_controller.rb b/app/controllers/admins/choose_mirror_repositories_controller.rb
new file mode 100644
index 000000000..c178e0d76
--- /dev/null
+++ b/app/controllers/admins/choose_mirror_repositories_controller.rb
@@ -0,0 +1,11 @@
+class Admins::ChooseMirrorRepositoriesController < Admins::BaseController
+ def new
+ @mirror = MirrorRepository.find(params[:mirror_id])
+ @new_mirror = MirrorOperationRecord.where(mirror_repository_id: @mirror.id, status: 1, user_id: -1).first
+ end
+
+ def create
+ mirror = MirrorRepository.find(params[:mirror_id])
+ Admins::ChooseMirrorService.call(mirror, current_user, params[:mirror_number])
+ end
+end
\ No newline at end of file
diff --git a/app/controllers/admins/mirror_repositories_controller.rb b/app/controllers/admins/mirror_repositories_controller.rb
new file mode 100644
index 000000000..63e4667d1
--- /dev/null
+++ b/app/controllers/admins/mirror_repositories_controller.rb
@@ -0,0 +1,96 @@
+class Admins::MirrorRepositoriesController < Admins::BaseController
+ before_action :check_shixun_mirrors!, only: [:index]
+
+ def index
+ mirrors = MirrorRepository.all
+ mirrors = mirrors.reorder(status: :desc, main_type: :desc, type_name: :asc)
+
+ @mirrors = paginate mirrors.includes(:mirror_scripts)
+ @error_mirror_names = MirrorRepository.where(status: 5).pluck(:name)
+ end
+
+ def new
+ @mirror = MirrorRepository.new
+ end
+
+ def create
+ @mirror = MirrorRepository.new
+ Admins::SaveMirrorRepositoryService.call(@mirror, current_user, form_params)
+
+ flash[:success] = '保存成功'
+ redirect_to edit_admins_mirror_repository_path(@mirror)
+ rescue ActiveRecord::RecordInvalid
+ flash.now[:danger] = '保存失败'
+ render 'new'
+ rescue Admins::SaveMirrorRepositoryService::Error => ex
+ flash.now[:danger] = ex.message
+ render 'new'
+ end
+
+ def edit
+ @mirror = current_mirror
+ end
+
+ def update
+ @mirror = current_mirror
+
+ Admins::SaveMirrorRepositoryService.call(current_mirror, current_user, form_params)
+
+ flash[:success] = '保存成功'
+ redirect_to edit_admins_mirror_repository_path(current_mirror)
+ rescue ActiveRecord::RecordInvalid
+ flash.now[:danger] = '保存失败'
+ render 'edit'
+ rescue Admins::SaveMirrorRepositoryService::Error => ex
+ flash.now[:danger] = ex.message
+ render 'edit'
+ end
+
+ def destroy
+ return render_js_error('该状态下不允许删除') unless current_mirror.deletable?
+
+ current_mirror.destroy!
+
+ render_delete_success
+ end
+
+ def for_select
+ mirrors = MirrorRepository.all
+
+ keyword = params[:keyword].to_s.strip
+ mirrors = mirrors.where('name LIKE ?', "%#{keyword}%") if keyword.present?
+
+ @mirrors = paginate mirrors
+
+ render_ok(count: @mirrors.total_count, mirrors: @mirrors.as_json(only: %i[id name]))
+ end
+
+ def merge
+ origin_mirror = MirrorRepository.find(params[:mirror_id])
+ mirror = MirrorRepository.find(params[:new_mirror_id])
+
+ ActiveRecord::Base.transaction do
+ origin_mirror.update!(name: mirror.name, mirrorID: mirror.mirrorID)
+ mirror.destroy!
+ end
+ end
+
+ private
+
+ def current_mirror
+ @_current_mirror ||= MirrorRepository.find(params[:id])
+ end
+
+ def form_params
+ columns = %i[type_name main_type time_limit resource_limit cpu_limit memory_limit description status]
+ params.require(:mirror_repository).permit(*columns)
+ end
+
+ def check_shixun_mirrors!
+ return unless request.format.html?
+
+ Admins::CheckShixunMirrorsService.call
+ rescue Admins::CheckShixunMirrorsService::Error => e
+ internal_server_error(e.message)
+ end
+end
diff --git a/app/controllers/concerns/admins/render_helper.rb b/app/controllers/concerns/admins/render_helper.rb
index 0ccc16a09..80f008b08 100644
--- a/app/controllers/concerns/admins/render_helper.rb
+++ b/app/controllers/concerns/admins/render_helper.rb
@@ -1,36 +1,34 @@
module Admins::RenderHelper
extend ActiveSupport::Concern
+ def render_by_format(hash)
+ format = request.format.symbol
+ hash.key?(format) ? hash[format].call : hash[:html].call
+ end
+
def render_forbidden
- respond_to do |format|
- format.html { redirect_to '/403' }
- format.json { super }
- end
+ render_by_format(html: -> { redirect_to '/403' },
+ json: -> { render status: 403, json: { messages: I18n.t('error.forbidden') } } )
end
def render_not_found
- respond_to do |format|
- format.html { render 'admins/shared/404' }
- format.js { render_js_error('资源未找到') }
- format.json { render status: 404, json: { message: '资源未找到' } }
- end
+ render_by_format(html: -> { render 'admins/shared/404' },
+ js: -> { render_js_error('资源未找到') },
+ json: -> { render status: 404, json: { message: '资源未找到' } })
end
def render_unprocessable_entity(message)
- respond_to do |format|
- format.html { render 'admins/shared/422' }
- format.js { render_js_error(message) }
- format.json { render status: 422, json: { message: message } }
- end
+ render_by_format(html: -> { render 'admins/shared/422' },
+ js: -> { render_js_error(message) },
+ json: -> { render status: 422, json: { message: message } })
end
alias_method :render_error, :render_unprocessable_entity
- def internal_server_error
- respond_to do |format|
- format.html { render 'admins/shared/500' }
- format.js { render_js_error('系统错误') }
- format.json { render status: 500, json: { message: '系统错误' } }
- end
+ def internal_server_error(message = '系统错误')
+ @message = message
+ render_by_format(html: -> { render 'admins/shared/500' },
+ js: -> { render_js_error(message) },
+ json: -> { render status: 500, json: { message: message } })
end
def render_js_template(template, **opts)
diff --git a/app/controllers/files_controller.rb b/app/controllers/files_controller.rb
index a916f5351..a6eafe0f3 100644
--- a/app/controllers/files_controller.rb
+++ b/app/controllers/files_controller.rb
@@ -171,6 +171,7 @@ class FilesController < ApplicationController
begin
attachment_ids.each do |attachment_id|
ori = Attachment.find_by_id(attachment_id)
+ # 同一个资源可以多次发送到课堂
@course.attachments.each do |att|
@exist = false
if att.id == ori.id || (!att.copy_from.nil? && !ori.copy_from.nil? && att.copy_from == ori.copy_from) || att.copy_from == ori.id || att.id == ori.copy_from
diff --git a/app/controllers/games_controller.rb b/app/controllers/games_controller.rb
index 4e8c729ce..0064914d3 100644
--- a/app/controllers/games_controller.rb
+++ b/app/controllers/games_controller.rb
@@ -765,7 +765,7 @@ class GamesController < ApplicationController
testset_detail max_query_index.to_i, game_challenge
# 处理生成图片类型文件
- picture = (@game.picture_path.nil? ? 0 : @game.id)
+ picture = (game_challenge.show_type.to_i == -1 || @game.picture_path.nil?) ? 0 : @game.id
# 针对web类型的实训
web_route = game_challenge.try(:web_route)
diff --git a/app/controllers/subjects_controller.rb b/app/controllers/subjects_controller.rb
index 5b926ee48..2f3bbd21c 100644
--- a/app/controllers/subjects_controller.rb
+++ b/app/controllers/subjects_controller.rb
@@ -270,7 +270,7 @@ class SubjectsController < ApplicationController
page = params[:page] || 1
member_ids = @subject.subject_members.map(&:user_id).join(',')
condition = "%#{params[:search].strip}%".gsub(" ","")
- @users = User.where("id not in (?) and status = 1 and LOWER(concat(lastname, firstname, login, mail)) LIKE ?", member_ids, "#{condition}")
+ @users = User.where("id not in (?) and status = 1 and LOWER(concat(lastname, ifnull(firstname, ''), login)) LIKE ?", member_ids, "#{condition}")
@users = @users.page(page).per(10)
@users = @users.includes(:user_extension)
diff --git a/app/helpers/admins/mirror_repositories_helper.rb b/app/helpers/admins/mirror_repositories_helper.rb
new file mode 100644
index 000000000..d62494e24
--- /dev/null
+++ b/app/helpers/admins/mirror_repositories_helper.rb
@@ -0,0 +1,23 @@
+module Admins::MirrorRepositoriesHelper
+ def mirror_type_tag(mirror)
+ case mirror.main_type
+ when '1' then ' '.html_safe
+ when '0' then ' '.html_safe
+ end
+ end
+
+ def mirror_status_tag(mirror)
+ case mirror.status
+ when 0
+ ' '.html_safe
+ when 1
+ ' '.html_safe
+ when 2, 3
+ ' '.html_safe
+ when 4
+ ' '.html_safe
+ when 5
+ ' '.html_safe
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/models/challenge.rb b/app/models/challenge.rb
index adb54fae9..8087fd6ab 100644
--- a/app/models/challenge.rb
+++ b/app/models/challenge.rb
@@ -40,16 +40,18 @@ class Challenge < ApplicationRecord
## 选择题总分
def choose_score
- self.challenge_chooses.pluck(:score).sum
+ self.score
+ #self.challenge_chooses.pluck(:score).sum
end
# 关卡总分
def all_score
- if self.st == 1
- self.choose_score
- else
- self.score
- end
+ self.score
+ # if self.st == 1
+ # self.choose_score
+ # else
+ # self.score
+ # end
end
# 开启挑战
diff --git a/app/models/game.rb b/app/models/game.rb
index d81b794a5..d7c68dd5f 100644
--- a/app/models/game.rb
+++ b/app/models/game.rb
@@ -31,7 +31,7 @@ class Game < ApplicationRecord
# 根据得分比例来算实际得分(试卷、实训作业)
def real_score score
- ((final_score < 0 ? 0 : final_score).to_f / challenge.all_score) * score
+ ((final_score < 0 ? 0 : final_score).to_f / challenge.score) * score
end
# 判断实训是否全部通关
diff --git a/app/models/mirror_operation_record.rb b/app/models/mirror_operation_record.rb
new file mode 100644
index 000000000..39e352a0f
--- /dev/null
+++ b/app/models/mirror_operation_record.rb
@@ -0,0 +1,7 @@
+# status: 0 创建镜像; 1 修改镜像ID; 2 修改镜像name 3 删除镜像 4.从主节点同步镜像到子节点(子节点发生异常), 5. 修改镜像别名, 6. 修改镜像的状态
+# user_id: -1时,证明是非人为因素造成,中间层异常导致
+class MirrorOperationRecord < ActiveRecord::Base
+ default_scope { order(created_at: :desc) }
+
+ belongs_to :mirror_repository
+end
diff --git a/app/models/mirror_repository.rb b/app/models/mirror_repository.rb
index be26b5ad1..e29b008ad 100644
--- a/app/models/mirror_repository.rb
+++ b/app/models/mirror_repository.rb
@@ -8,4 +8,8 @@ class MirrorRepository < ApplicationRecord
scope :published_mirror, -> { where(status: 1) }
scope :published_main_mirror, -> { published_mirror.where(main_type: 1) }
scope :published_small_mirror, -> { published_mirror.where(main_type: 0) }
+
+ def deletable?
+ status != 1 && !shixun_mirror_repositories.exists?
+ end
end
diff --git a/app/models/shixun.rb b/app/models/shixun.rb
index 81b444c0a..d61ba45b9 100644
--- a/app/models/shixun.rb
+++ b/app/models/shixun.rb
@@ -192,11 +192,7 @@ class Shixun < ApplicationRecord
# 实训关卡的总分(由于大部分是实践题,因此没关联查choose表)
# 提前加载问题:由于选择题比较少,所以几乎不会触发选择题的查询,所以没必要提前载入choose_score
def all_score
- sum = 0
- challenges.each do |challenge|
- sum += challenge.st == 0 ? challenge.score : challenge.choose_score
- end
- sum
+ self.challenges.pluck(:score).sum
end
### fork 数量
diff --git a/app/services/admins/check_shixun_mirrors_service.rb b/app/services/admins/check_shixun_mirrors_service.rb
new file mode 100644
index 000000000..868fab042
--- /dev/null
+++ b/app/services/admins/check_shixun_mirrors_service.rb
@@ -0,0 +1,89 @@
+class Admins::CheckShixunMirrorsService < ApplicationService
+ Error = Class.new(StandardError)
+
+ def call
+ bridge_images
+
+ ActiveRecord::Base.transaction do
+ check_sync_mirrors!
+
+ check_mirrors!
+ end
+ end
+
+ private
+
+ def mirrors
+ bridge_images['images']
+ end
+
+ def sync_mirrors
+ bridge_images['imagesNotSync']
+ end
+
+ def check_mirrors!
+ return if mirrors.blank?
+ image_names = []
+
+ mirrors.each do |data|
+ mirror = JSON.parse(data)
+
+ name_repository = MirrorRepository.find_by(name: mirror['imageName'])
+ id_repository = MirrorRepository.find_by(mirrorID: mirror['imageID'])
+
+ image_names << mirror['imageName']
+
+ if name_repository.blank? && id_repository.present? # 镜像名称被修改
+ id_repository.update_column(:status, 2)
+ MirrorOperationRecord.create!(mirror_repository_id: id_repository.id, mirror_id: mirror['imageID'],
+ mirror_name: mirror['imageName'], status: 2, user_id: -1)
+ elsif name_repository.blank? # 镜像不存在、创建镜像
+ new_repository = MirrorRepository.create!(mirrorID: mirror['imageID'], name: mirror['imageName'])
+ MirrorOperationRecord.create!(mirror_repository_id: new_repository.id, mirror_id: mirror['imageID'],
+ mirror_name: mirror['imageName'], status: 0, user_id: -1)
+ elsif name_repository.mirrorID != mirror['imageID'] # 镜像ID被修改
+ name_repository.update_column(:status, 2)
+ MirrorOperationRecord.create!(mirror_repository_id: name_repository.id, mirror_id: mirror['imageID'],
+ mirror_name: mirror['imageName'], status: 1, user_id: -1)
+ end
+ end
+
+ # 判断中间层镜像是否被删除
+ MirrorRepository.find_each do |mirror|
+ next if mirror&.name.blank? || image_names.index(mirror.name)
+
+ mirror.update_column(:status, 4)
+ MirrorOperationRecord.create!(mirror_repository_id: mirror.id, mirror_id: mirror&.mirrorID,
+ mirror_name: mirror.name, status: 3, user_id: -1)
+ end
+ end
+
+ def check_sync_mirrors!
+ return if sync_mirrors.blank?
+
+ sync_mirrors.each do |data|
+ mirror = JSON.parse(data)
+
+ repository = MirrorRepository.find_by(name: mirror['imageName'])
+ next if repository.blank? || repository.status != 1
+
+ repository.update_column(:status, 5)
+ MirrorOperationRecord.create!(mirror_repository_id: repository.id, mirror_id: mirror['imageID'],
+ mirror_name: mirror['imageName'], status: 4, user_id: -1)
+ end
+ end
+
+ def bridge_images
+ @_bridge_images ||= begin
+ url = EduSetting.get('cloud_bridge')
+ res = Faraday.get(url)
+
+ raise Error, '拉取镜像信息异常' if res && res['code'].nonzero?
+
+ res
+ rescue => e
+ Rails.logger.error("get response failed ! #{e.message}")
+ raise Error, '实训云平台繁忙(繁忙等级:84)'
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/services/admins/choose_mirror_service.rb b/app/services/admins/choose_mirror_service.rb
new file mode 100644
index 000000000..77d187884
--- /dev/null
+++ b/app/services/admins/choose_mirror_service.rb
@@ -0,0 +1,21 @@
+class Admins::ChooseMirrorService < ApplicationService
+ attr_reader :mirror, :user, :number
+
+ def initialize(mirror, user, mirror_number)
+ @mirror = mirror
+ @user = user
+ @number = mirror_number
+ end
+
+ def call
+ if mirror.mirrorID == number
+ mirror.update_column(:status, 1)
+ return
+ end
+
+ old_number = mirror.mirrorID
+ mirror.update!(mirrorID: number, status: 1)
+ MirrorOperationRecord.create!(mirror_repository_id: mirror.id, mirror_id: number, mirror_name: mirror.name,
+ status: 1, user_id: user.id, old_tag: old_number, new_tag: mirror.mirrorID)
+ end
+end
\ No newline at end of file
diff --git a/app/services/admins/save_mirror_repository_service.rb b/app/services/admins/save_mirror_repository_service.rb
new file mode 100644
index 000000000..4aff64f66
--- /dev/null
+++ b/app/services/admins/save_mirror_repository_service.rb
@@ -0,0 +1,37 @@
+class Admins::SaveMirrorRepositoryService < ApplicationService
+ Error = Class.new(StandardError)
+
+ attr_reader :mirror, :user, :params
+
+ def initialize(mirror, user, params)
+ @mirror = mirror
+ @user = user
+ @params = params
+ end
+
+ def call
+ mirror.assign_attributes(params)
+
+ raise Error, '镜像别名重复' if MirrorRepository.where.not(id: mirror.id).exists?(type_name: params[:type_name])
+
+ ActiveRecord::Base.transaction do
+ record_operation! if mirror.persisted?
+
+ mirror.save!
+ end
+ end
+
+ private
+
+ def record_operation!
+ if mirror.type_name_changed?
+ MirrorOperationRecord.create!(mirror_repository_id: mirror.id, status: 5,
+ user_id: user.id, old_tag: mirror.type_name_in_database,
+ new_tag: mirror.type_name)
+ elsif mirror.status_changed?
+ MirrorOperationRecord.create!(mirror_repository_id: mirror.id, status: 5,
+ user_id: user.id, old_tag: mirror.status_in_database,
+ new_tag: mirror.status)
+ end
+ end
+end
\ No newline at end of file
diff --git a/app/views/admins/choose_mirror_repositories/create.js.erb b/app/views/admins/choose_mirror_repositories/create.js.erb
new file mode 100644
index 000000000..585ecb1af
--- /dev/null
+++ b/app/views/admins/choose_mirror_repositories/create.js.erb
@@ -0,0 +1,5 @@
+$.notify({ message: '操作成功' },{ type: 'success' });
+
+setTimeout(function(){
+ window.location.reload();
+}, 500)
\ No newline at end of file
diff --git a/app/views/admins/choose_mirror_repositories/new.js.erb b/app/views/admins/choose_mirror_repositories/new.js.erb
new file mode 100644
index 000000000..8603011ab
--- /dev/null
+++ b/app/views/admins/choose_mirror_repositories/new.js.erb
@@ -0,0 +1,2 @@
+$('.admin-modal-container').html("<%= j( render partial: 'admins/mirror_repositories/shared/choose_mirror_modal', locals: { mirror: @mirror, new_mirror: @new_mirror } ) %>");
+$('.modal.admin-choose-mirror-modal').modal('show');
\ No newline at end of file
diff --git a/app/views/admins/mirror_repositories/edit.html.erb b/app/views/admins/mirror_repositories/edit.html.erb
new file mode 100644
index 000000000..7df580c96
--- /dev/null
+++ b/app/views/admins/mirror_repositories/edit.html.erb
@@ -0,0 +1,8 @@
+<%
+ define_admin_breadcrumbs do
+ add_admin_breadcrumb('镜像管理', admins_mirror_repositories_path)
+ add_admin_breadcrumb('镜像详情')
+ end
+%>
+
+<%= render partial: 'admins/mirror_repositories/shared/form', locals: { mirror: @mirror, form_action: 'update' } %>
\ No newline at end of file
diff --git a/app/views/admins/mirror_repositories/index.html.erb b/app/views/admins/mirror_repositories/index.html.erb
new file mode 100644
index 000000000..ac384408f
--- /dev/null
+++ b/app/views/admins/mirror_repositories/index.html.erb
@@ -0,0 +1,23 @@
+<% define_admin_breadcrumbs do %>
+ <% add_admin_breadcrumb('镜像管理') %>
+<% end %>
+
+
+
+ <%= link_to '新建', new_admins_mirror_repository_path, class: 'btn btn-primary' %>
+
+
+<% if @error_mirror_names.present? %>
+
+ 以下镜像异常:
+ <% @error_mirror_names.each do |mirror_name| %>
+ <%= mirror_name %>
+ <% end %>
+
+<% end %>
+
+
+ <%= render partial: 'admins/mirror_repositories/shared/list', locals: { mirrors: @mirrors } %>
+
+
+<%= render 'admins/mirror_repositories/shared/replace_mirror_modal' %>
\ No newline at end of file
diff --git a/app/views/admins/mirror_repositories/index.js.erb b/app/views/admins/mirror_repositories/index.js.erb
new file mode 100644
index 000000000..58ccb1ef8
--- /dev/null
+++ b/app/views/admins/mirror_repositories/index.js.erb
@@ -0,0 +1 @@
+$('.mirror-repository-list-container').html("<%= j( render partial: 'admins/mirror_repositories/shared/list', locals: { mirrors: @mirrors } ) %>");
\ No newline at end of file
diff --git a/app/views/admins/mirror_repositories/merge.js.erb b/app/views/admins/mirror_repositories/merge.js.erb
new file mode 100644
index 000000000..585ecb1af
--- /dev/null
+++ b/app/views/admins/mirror_repositories/merge.js.erb
@@ -0,0 +1,5 @@
+$.notify({ message: '操作成功' },{ type: 'success' });
+
+setTimeout(function(){
+ window.location.reload();
+}, 500)
\ No newline at end of file
diff --git a/app/views/admins/mirror_repositories/new.html.erb b/app/views/admins/mirror_repositories/new.html.erb
new file mode 100644
index 000000000..792fe0857
--- /dev/null
+++ b/app/views/admins/mirror_repositories/new.html.erb
@@ -0,0 +1,8 @@
+<%
+ define_admin_breadcrumbs do
+ add_admin_breadcrumb('镜像管理', admins_mirror_repositories_path)
+ add_admin_breadcrumb('新建镜像')
+ end
+%>
+
+<%= render partial: 'admins/mirror_repositories/shared/form', locals: { mirror: @mirror, form_action: 'create' } %>
\ No newline at end of file
diff --git a/app/views/admins/mirror_repositories/shared/_choose_mirror_modal.html.erb b/app/views/admins/mirror_repositories/shared/_choose_mirror_modal.html.erb
new file mode 100644
index 000000000..99c846c70
--- /dev/null
+++ b/app/views/admins/mirror_repositories/shared/_choose_mirror_modal.html.erb
@@ -0,0 +1,42 @@
+
+
+
+
+
+ <%= form_tag(admins_choose_mirror_repositories_path(mirror_id: mirror.id), method: :post, class: 'admin-choose-mirror-form') do %>
+
+
+
+
+ <% end %>
+
+
+
+
+
\ No newline at end of file
diff --git a/app/views/admins/mirror_repositories/shared/_form.html.erb b/app/views/admins/mirror_repositories/shared/_form.html.erb
new file mode 100644
index 000000000..c8ab2a186
--- /dev/null
+++ b/app/views/admins/mirror_repositories/shared/_form.html.erb
@@ -0,0 +1,42 @@
+
+ <%= simple_form_for([:admins, mirror], url: { action: form_action }, html: { class: 'edit-mirror col-md-12' }, defaults: { wrapper_html: { class: 'col-md-4' } }) do |f| %>
+ <% unless mirror.new_record? %>
+
+ <%= f.input :mirrorID, label: '镜像ID', input_html: { readonly: true, class: 'form-control-plaintext' } %>
+ <%= f.input :name, label: '镜像名称', input_html: { readonly: true, class: 'form-control-plaintext' } %>
+
+ <% end %>
+
+
+ <%= f.input :type_name, as: :string, label: '镜像别名 *' %>
+
+
+ <%= f.label :main_type, label: '类别' %>
+ <%= f.select :main_type, [['主类别', 1],['小类别', 0]], {}, class: 'form-control optional' %>
+
+
+
+
+ <%= f.input :time_limit, as: :integer, label: '评测时限(S)' %>
+ <%= f.input :resource_limit, as: :integer, label: '磁盘限制(K)' %>
+
+
+
+ <%= f.input :cpu_limit, as: :integer, label: 'CPU限制(核)' %>
+ <%= f.input :memory_limit, as: :integer, label: '内存限制(M)' %>
+
+
+
+ <%= f.input :description, as: :text, label: '描述', wrapper_html: { class: 'col-md-8' } %>
+
+
+
+ <%= f.input :status, as: :radio_buttons, label: '状态', collection: [%w(未发布 0), %w(已发布 1)], wrapper_html: { class: 'col-md-4' } %>
+
+
+
+ <%= f.button :submit, value: '保存', class: 'btn-primary mr-3 px-4', 'data-disable-with': '保存中...' %>
+ <%= link_to '取消', admins_mirror_repositories_path, class: 'btn btn-secondary px-4' %>
+
+ <% end %>
+
\ No newline at end of file
diff --git a/app/views/admins/mirror_repositories/shared/_list.html.erb b/app/views/admins/mirror_repositories/shared/_list.html.erb
new file mode 100644
index 000000000..b4c2df70e
--- /dev/null
+++ b/app/views/admins/mirror_repositories/shared/_list.html.erb
@@ -0,0 +1,54 @@
+
+
+
+ ID
+ 类别
+ 镜像别名
+ 镜像名称
+ 镜像描述
+ 修改时间
+ 脚本
+ 状态
+ 操作
+
+
+
+ <% if mirrors.present? %>
+ <% mirrors.each do |mirror| %>
+
+ <%= mirror.id %>
+ <%= mirror_type_tag(mirror) %>
+ <%= display_text(mirror.type_name) %>
+ <%= overflow_hidden_span mirror.name, width: 150 %>
+ <%= overflow_hidden_span mirror.description, width: 240 %>
+ <%= mirror.updated_at.strftime('%Y-%m-%d %H:%M') %>
+
+ <% if mirror.main_type == "1" %>
+ <%= link_to "/users/modify_script?mirror_id=#{mirror.id}", target: '_blank' do %>
+
+ <% end %>
+ <% end %>
+
+ <%= mirror_status_tag mirror %>
+
+ <%= link_to '编辑', edit_admins_mirror_repository_path(mirror), class: 'action edit-action' %>
+
+ <% if mirror.status == 2 %>
+ <%= link_to '同步', new_admins_choose_mirror_repository_path(mirror_id: mirror.id), remote: true, class: 'action sync-action' %>
+ <% end %>
+
+ <%= javascript_void_link '替换', class: 'action replace-action', data: { toggle: 'modal', target: '.admin-replace-mirror-modal', id: mirror.id, name: mirror.name } %>
+
+ <% if mirror.deletable? %>
+ <%= delete_link '删除', admins_mirror_repository_path(mirror, element: ".mirror-repository-item-#{mirror.id}"), class: 'delete-mirror-repository-action' %>
+ <% end %>
+
+
+ <% end %>
+ <% else %>
+ <%= render 'admins/shared/no_data_for_table' %>
+ <% end %>
+
+
+
+<%= render partial: 'admins/shared/paginate', locals: { objects: mirrors } %>
\ No newline at end of file
diff --git a/app/views/admins/mirror_repositories/shared/_replace_mirror_modal.html.erb b/app/views/admins/mirror_repositories/shared/_replace_mirror_modal.html.erb
new file mode 100644
index 000000000..f2b2d20c8
--- /dev/null
+++ b/app/views/admins/mirror_repositories/shared/_replace_mirror_modal.html.erb
@@ -0,0 +1,33 @@
+
\ No newline at end of file
diff --git a/app/views/admins/shared/500.html.erb b/app/views/admins/shared/500.html.erb
index f053f58ec..b1488d6ff 100644
--- a/app/views/admins/shared/500.html.erb
+++ b/app/views/admins/shared/500.html.erb
@@ -2,5 +2,5 @@
500
- 系统错误
+ <%= @message %>
\ No newline at end of file
diff --git a/app/views/admins/shared/_paginate.html.erb b/app/views/admins/shared/_paginate.html.erb
index b7e40e879..5c15f762c 100644
--- a/app/views/admins/shared/_paginate.html.erb
+++ b/app/views/admins/shared/_paginate.html.erb
@@ -1,5 +1,5 @@
- <% if objects.size.nonzero? %>
+ <% if objects && objects.size.nonzero? %>
<%= page_entries_info objects %>
<% end %>
<%= paginate objects, views_prefix: 'admins', remote: true %>
diff --git a/app/views/admins/shared/_sidebar.html.erb b/app/views/admins/shared/_sidebar.html.erb
index ab30e8bd3..8c995ec45 100644
--- a/app/views/admins/shared/_sidebar.html.erb
+++ b/app/views/admins/shared/_sidebar.html.erb
@@ -20,6 +20,12 @@
<% end %>
+
+ <%= sidebar_item_group('#shixun-submenu', '实训管理', icon: 'window-restore') do %>
+ <%= sidebar_item(admins_mirror_repositories_path, '镜像管理', icon: 'cubes', controller: 'admins-mirror_repositories') %>
+ <% end %>
+
+
<%#= sidebar_item_group('#course-submenu', '课堂+', icon: 'mortar-board') do %>
diff --git a/app/views/admins/users/edit.html.erb b/app/views/admins/users/edit.html.erb
index 3f9d71b96..22ac1f18e 100644
--- a/app/views/admins/users/edit.html.erb
+++ b/app/views/admins/users/edit.html.erb
@@ -131,7 +131,7 @@
<%= f.button :submit, value: '保存', class: 'btn-primary mr-3 px-4' %>
- <%= link_to '取消', 'javascript:history.go(-1)', class: 'btn btn-secondary px-4' %>
+ <%= link_to '取消', admins_users_path, class: 'btn btn-secondary px-4' %>
<% end %>
\ No newline at end of file
diff --git a/app/views/challenges/index.json.jbuilder b/app/views/challenges/index.json.jbuilder
index a542b8119..37ce94305 100644
--- a/app/views/challenges/index.json.jbuilder
+++ b/app/views/challenges/index.json.jbuilder
@@ -13,7 +13,7 @@ if @challenges.present?
json.position challenge.position
json.st challenge.st
json.name challenge.subject
- json.score challenge.all_score
+ json.score challenge.score
json.passed_count challenge.user_passed_count
json.playing_count challenge.playing_count
json.name_url shixun_challenge_path(challenge, shixun_identifier: @shixun.identifier)
diff --git a/config/routes.rb b/config/routes.rb
index 7e2cf72f3..285bb7e1a 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -786,6 +786,13 @@ Rails.application.routes.draw do
post :refuse
end
end
+ resources :mirror_repositories, only: [:index, :new, :create, :edit, :update, :destroy] do
+ collection do
+ post :merge
+ get :for_select
+ end
+ end
+ resources :choose_mirror_repositories, only: [:new, :create]
end
#git 认证回调
diff --git a/db/migrate/20190827055814_modify_challnege_score_for_choose.rb b/db/migrate/20190827055814_modify_challnege_score_for_choose.rb
new file mode 100644
index 000000000..7b96877e3
--- /dev/null
+++ b/db/migrate/20190827055814_modify_challnege_score_for_choose.rb
@@ -0,0 +1,10 @@
+class ModifyChallnegeScoreForChoose < ActiveRecord::Migration[5.2]
+ def change
+ challenges = Challenge.where(st: 1)
+ challenges.find_each do |c|
+ puts(c.id)
+ score = c.challenge_chooses.sum(:score)
+ c.update_column(:score, score)
+ end
+ end
+end
diff --git a/public/assets/.sprockets-manifest-1c370772f16743f825981ab0e5c94237.json b/public/assets/.sprockets-manifest-1c370772f16743f825981ab0e5c94237.json
index 5f5a55fd7..da6cf8633 100644
--- a/public/assets/.sprockets-manifest-1c370772f16743f825981ab0e5c94237.json
+++ b/public/assets/.sprockets-manifest-1c370772f16743f825981ab0e5c94237.json
@@ -1 +1 @@
-{"files":{"admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js":{"logical_path":"admin.js","mtime":"2019-08-26T15:21:11+08:00","size":907839,"digest":"6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d","integrity":"sha256-ZXXxOZlT+xk1wDenuL0oxK/we3C+2bQfr2iZqJr0tX0="},"admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css":{"logical_path":"admin.css","mtime":"2019-08-26T15:21:47+08:00","size":655571,"digest":"8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5","integrity":"sha256-iisDy4oFXcY/RUQ7MEyudzgjMb66VbFXCz08iqQkQtU="},"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot":{"logical_path":"font-awesome/fontawesome-webfont.eot","mtime":"2019-08-14T17:22:43+08:00","size":165742,"digest":"7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979","integrity":"sha256-e/yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk="},"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2":{"logical_path":"font-awesome/fontawesome-webfont.woff2","mtime":"2019-08-14T17:22:43+08:00","size":77160,"digest":"2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe","integrity":"sha256-Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8/4="},"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff":{"logical_path":"font-awesome/fontawesome-webfont.woff","mtime":"2019-08-14T17:22:43+08:00","size":98024,"digest":"ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07","integrity":"sha256-ugxZ3rVFD1y0Gz+TYJ7i0NmVQVh33foiPoqKdTNHTwc="},"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf":{"logical_path":"font-awesome/fontawesome-webfont.ttf","mtime":"2019-08-14T17:22:43+08:00","size":165548,"digest":"aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8","integrity":"sha256-qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg="},"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg":{"logical_path":"font-awesome/fontawesome-webfont.svg","mtime":"2019-08-14T17:22:43+08:00","size":444379,"digest":"ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4","integrity":"sha256-rWFXkmwWIrpOHQPUePFUE2hSS/xG9R5C/g2UX37zI+Q="},"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png":{"logical_path":"logo.png","mtime":"2019-08-21T15:10:12+08:00","size":2816,"digest":"7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423","integrity":"sha256-f/ESVocJv5f5iY/ockm3qPIA/x9I1TfYWvhyFfGHBCM="},"application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js":{"logical_path":"application.js","mtime":"2019-08-26T15:21:11+08:00","size":1042232,"digest":"a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533","integrity":"sha256-o6TzVJ1oZwVyuwdwDIWprBHlNu3HP+9udIlyO/U15TM="},"application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css":{"logical_path":"application.css","mtime":"2019-08-26T15:21:47+08:00","size":1182859,"digest":"a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46","integrity":"sha256-p1CLiOtqaaWzAWAr3cFHRc7AmFPqfZHG+uhWuW54j0Y="}},"assets":{"admin.js":"admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js","admin.css":"admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css","font-awesome/fontawesome-webfont.eot":"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot","font-awesome/fontawesome-webfont.woff2":"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2","font-awesome/fontawesome-webfont.woff":"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff","font-awesome/fontawesome-webfont.ttf":"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf","font-awesome/fontawesome-webfont.svg":"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg","logo.png":"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png","application.js":"application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js","application.css":"application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css"}}
\ No newline at end of file
+{"files":{"admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js":{"logical_path":"admin.js","mtime":"2019-08-26T15:21:11+08:00","size":907839,"digest":"6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d","integrity":"sha256-ZXXxOZlT+xk1wDenuL0oxK/we3C+2bQfr2iZqJr0tX0="},"admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css":{"logical_path":"admin.css","mtime":"2019-08-26T15:21:47+08:00","size":655571,"digest":"8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5","integrity":"sha256-iisDy4oFXcY/RUQ7MEyudzgjMb66VbFXCz08iqQkQtU="},"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot":{"logical_path":"font-awesome/fontawesome-webfont.eot","mtime":"2019-08-14T17:22:43+08:00","size":165742,"digest":"7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979","integrity":"sha256-e/yrbbmdXPvxcFygU23ceFhUMsxfpBu9etDwCQM7KXk="},"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2":{"logical_path":"font-awesome/fontawesome-webfont.woff2","mtime":"2019-08-14T17:22:43+08:00","size":77160,"digest":"2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe","integrity":"sha256-Kt78vAQefRj88tQXh53FoJmXqmTWdbejxLbOM9oT8/4="},"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff":{"logical_path":"font-awesome/fontawesome-webfont.woff","mtime":"2019-08-14T17:22:43+08:00","size":98024,"digest":"ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07","integrity":"sha256-ugxZ3rVFD1y0Gz+TYJ7i0NmVQVh33foiPoqKdTNHTwc="},"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf":{"logical_path":"font-awesome/fontawesome-webfont.ttf","mtime":"2019-08-14T17:22:43+08:00","size":165548,"digest":"aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8","integrity":"sha256-qljzPyOaD7AvXHpsRcBD16msmgkzNYBmlOzW1O3A1qg="},"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg":{"logical_path":"font-awesome/fontawesome-webfont.svg","mtime":"2019-08-14T17:22:43+08:00","size":444379,"digest":"ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4","integrity":"sha256-rWFXkmwWIrpOHQPUePFUE2hSS/xG9R5C/g2UX37zI+Q="},"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png":{"logical_path":"logo.png","mtime":"2019-08-21T15:10:12+08:00","size":2816,"digest":"7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423","integrity":"sha256-f/ESVocJv5f5iY/ockm3qPIA/x9I1TfYWvhyFfGHBCM="},"application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js":{"logical_path":"application.js","mtime":"2019-08-26T15:21:11+08:00","size":1042232,"digest":"a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533","integrity":"sha256-o6TzVJ1oZwVyuwdwDIWprBHlNu3HP+9udIlyO/U15TM="},"application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css":{"logical_path":"application.css","mtime":"2019-08-26T15:21:47+08:00","size":1182859,"digest":"a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46","integrity":"sha256-p1CLiOtqaaWzAWAr3cFHRc7AmFPqfZHG+uhWuW54j0Y="},"admin-7859f34e107ec35880c203a6c71fbd0b6b9dfdd007b9b8741db3c5fafb22d7a5.js":{"logical_path":"admin.js","mtime":"2019-08-27T16:36:09+08:00","size":912415,"digest":"7859f34e107ec35880c203a6c71fbd0b6b9dfdd007b9b8741db3c5fafb22d7a5","integrity":"sha256-eFnzThB+w1iAwgOmxx+9C2ud/dAHubh0HbPF+vsi16U="},"admin-e9352b40346e2c36c1d4de8f6e80405102647430dac1f81e6ad8ef9935505909.css":{"logical_path":"admin.css","mtime":"2019-08-27T10:22:33+08:00","size":655943,"digest":"e9352b40346e2c36c1d4de8f6e80405102647430dac1f81e6ad8ef9935505909","integrity":"sha256-6TUrQDRuLDbB1N6PboBAUQJkdDDawfgeatjvmTVQWQk="},"application-a4d6c5155da5a1dfbb7291faf09f555d557ee42ed9eb2c0c094d10898e35c687.js":{"logical_path":"application.js","mtime":"2019-08-27T16:36:09+08:00","size":1046808,"digest":"a4d6c5155da5a1dfbb7291faf09f555d557ee42ed9eb2c0c094d10898e35c687","integrity":"sha256-pNbFFV2lod+7cpH68J9VXVV+5C7Z6ywMCU0QiY41xoc="},"application-3d0740554f7108bba10d79d34f0cc47dca1a74fa0a1c423fffd5def99c386e17.css":{"logical_path":"application.css","mtime":"2019-08-27T10:22:33+08:00","size":1183231,"digest":"3d0740554f7108bba10d79d34f0cc47dca1a74fa0a1c423fffd5def99c386e17","integrity":"sha256-PQdAVU9xCLuhDXnTTwzEfcoadPoKHEI//9Xe+Zw4bhc="}},"assets":{"admin.js":"admin-7859f34e107ec35880c203a6c71fbd0b6b9dfdd007b9b8741db3c5fafb22d7a5.js","admin.css":"admin-e9352b40346e2c36c1d4de8f6e80405102647430dac1f81e6ad8ef9935505909.css","font-awesome/fontawesome-webfont.eot":"font-awesome/fontawesome-webfont-7bfcab6db99d5cfbf1705ca0536ddc78585432cc5fa41bbd7ad0f009033b2979.eot","font-awesome/fontawesome-webfont.woff2":"font-awesome/fontawesome-webfont-2adefcbc041e7d18fcf2d417879dc5a09997aa64d675b7a3c4b6ce33da13f3fe.woff2","font-awesome/fontawesome-webfont.woff":"font-awesome/fontawesome-webfont-ba0c59deb5450f5cb41b3f93609ee2d0d995415877ddfa223e8a8a7533474f07.woff","font-awesome/fontawesome-webfont.ttf":"font-awesome/fontawesome-webfont-aa58f33f239a0fb02f5c7a6c45c043d7a9ac9a093335806694ecd6d4edc0d6a8.ttf","font-awesome/fontawesome-webfont.svg":"font-awesome/fontawesome-webfont-ad6157926c1622ba4e1d03d478f1541368524bfc46f51e42fe0d945f7ef323e4.svg","logo.png":"logo-7ff112568709bf97f9898fe87249b7a8f200ff1f48d537d85af87215f1870423.png","application.js":"application-a4d6c5155da5a1dfbb7291faf09f555d557ee42ed9eb2c0c094d10898e35c687.js","application.css":"application-3d0740554f7108bba10d79d34f0cc47dca1a74fa0a1c423fffd5def99c386e17.css"}}
\ No newline at end of file
diff --git a/public/assets/admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js b/public/assets/admin-7859f34e107ec35880c203a6c71fbd0b6b9dfdd007b9b8741db3c5fafb22d7a5.js
similarity index 99%
rename from public/assets/admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js
rename to public/assets/admin-7859f34e107ec35880c203a6c71fbd0b6b9dfdd007b9b8741db3c5fafb22d7a5.js
index 2ff813ff4..e96beedb5 100644
--- a/public/assets/admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js
+++ b/public/assets/admin-7859f34e107ec35880c203a6c71fbd0b6b9dfdd007b9b8741db3c5fafb22d7a5.js
@@ -27721,6 +27721,7 @@ $(document).on('turbolinks:load', function(){
$(document).on('turbolinks:load', function() {
if ($('body.admins-identity-authentications-index-page').length > 0) {
var $searchFrom = $('.identity-authentication-list-form');
+ $searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@@ -27732,14 +27733,160 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
+ $searchFrom.find('select[name="status"]').val('pending');
}
});
}
})
;
+$(document).on('turbolinks:load', function() {
+ if ($('body.admins-mirror-repositories-edit-page, body.admins-mirror-repositories-update-page').length > 0) {
+ var $form = $('form.edit-mirror');
+
+ $form.validate({
+ errorElement: 'span',
+ errorClass: 'danger text-danger',
+ rules: {
+ "mirror_repository[type_name]": {
+ required: true
+ }
+ }
+ });
+
+ $form.submit(function(e){
+ if(!$form.valid()){ e.preventDefault(); }
+ });
+ }
+});
+$(document).on('turbolinks:load', function() {
+ if ($('body.admins-mirror-repositories-index-page').length > 0) {
+ }
+});
+$(document).on('turbolinks:load', function() {
+ $('.admin-modal-container').on('show.bs.modal', '.modal.admin-choose-mirror-modal', function(){
+ var $modal = $('.modal.admin-choose-mirror-modal');
+ var $form = $modal.find('form.admin-choose-mirror-form');
+
+ var validateForm = function(){
+ var checkedValue = $form.find('input[name="mirror_number"]:checked').val();
+
+ if(checkedValue == undefined){
+ $modal.find('.error').html('必须选择一种镜像保存!');
+ return false;
+ }
+ return true;
+ }
+
+ $modal.on('click', '.submit-btn', function(){
+ $form.find('.error').html('');
+ var url = $form.attr('action');
+
+ if (validateForm()) {
+ $.ajax({
+ method: 'POST',
+ dataType: 'script',
+ url: url,
+ data: $form.serialize(),
+ }).done(function(){
+ $modal.modal('hide');
+ });
+ }
+ });
+ })
+});
+$(document).on('turbolinks:load', function() {
+ var $modal = $('.modal.admin-replace-mirror-modal');
+ if ($modal.length > 0) {
+ var $form = $modal.find('form.admin-replace-mirror-form');
+ var $mirrorIdInput = $modal.find('.modal-body input[name="mirror_id"]');
+ var $mirrorSelect = $modal.find('.new-mirror-select');
+
+ var setMirror = function(id, name){
+ $mirrorIdInput.val(id);
+ $form.find('.mirror-id-container').html(id);
+ $form.find('.mirror-name-container').html(name);
+ }
+
+ $form.validate({
+ errorElement: 'span',
+ errorClass: 'danger text-danger',
+ rules: {
+ new_mirror_id: {
+ required: true
+ },
+ },
+ messages: {
+ new_mirror_id: {
+ required: '请选择新镜像'
+ }
+ }
+ });
+
+ // modal ready fire
+ $modal.on('show.bs.modal', function (event) {
+ var $link = $(event.relatedTarget);
+
+ var mirrorId = $link.data('id');
+ var mirrorName = $link.data('name');
+
+ setMirror(mirrorId, mirrorName);
+ $mirrorSelect.select2('val', ' ');
+ });
+ $modal.on('hide.bs.modal', function () {
+ setMirror('', '');
+ $mirrorSelect.select2('val', ' ');
+ $('#new_mirror_id-error').remove();
+ });
+
+ $mirrorSelect.select2({
+ theme: 'bootstrap4',
+ placeholder: '输入要合并的镜像名',
+ minimumInputLength: 1,
+ ajax: {
+ url: '/admins/mirror_repositories/for_select',
+ dataType: 'json',
+ data: function(params){
+ return { keyword: params.term };
+ },
+ processResults: function(data){
+ return { results: data.mirrors }
+ }
+ },
+ templateResult: function (item) {
+ if(!item.id || item.id === '') return item.text;
+ return item.name;
+ },
+ templateSelection: function(item){
+ if (item.id) {
+ $('#new_mirror_id-error').remove();
+ $('#new_mirror_id').val(item.id);
+ }
+ return item.name || item.text;
+ }
+ });
+
+ $modal.on('click', '.submit-btn', function(){
+ $form.find('.error').html('');
+
+ if ($form.valid()) {
+ var url = $form.data('url');
+
+ $.ajax({
+ method: 'POST',
+ dataType: 'script',
+ url: url,
+ data: $form.serialize(),
+ }).done(function(){
+ $modal.modal('hide');
+ });
+ }
+ });
+ }
+});
$(document).on('turbolinks:load', function() {
if ($('body.admins-professional-authentications-index-page').length > 0) {
var $searchFrom = $('.professional-authentication-list-form');
+ $searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@@ -27751,6 +27898,7 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
+ $searchFrom.find('select[name="status"]').val('pending');
}
});
}
@@ -27905,6 +28053,7 @@ $(document).on('turbolinks:load', function() {
$(document).on('turbolinks:load', function() {
if ($('body.admins-shixun-authorizations-index-page').length > 0) {
var $searchFrom = $('.shixun-authorization-list-form');
+ $searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@@ -27916,6 +28065,7 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
+ $searchFrom.find('select[name="status"]').val('pending');
}
});
}
@@ -27940,6 +28090,7 @@ $(document).on('turbolinks:load', function(){
$(document).on('turbolinks:load', function() {
if ($('body.admins-subject-authorizations-index-page').length > 0) {
var $searchFrom = $('.subject-authorization-list-form');
+ $searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@@ -27951,6 +28102,7 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
+ $searchFrom.find('select[name="status"]').val('pending');
}
});
}
@@ -28267,8 +28419,11 @@ $(document).on('turbolinks:load', function(){
// flash alert提示框自动关闭
if($('.admin-alert-container .alert').length > 0){
setTimeout(function(){
- $('.admin-alert-container .alert').alert('close');
+ $('.admin-alert-container .alert:not(.alert-danger)').alert('close');
}, 2000);
+ setTimeout(function(){
+ $('.admin-alert-container .alert.alert-danger').alert('close');
+ }, 5000);
}
});
diff --git a/public/assets/admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js.gz b/public/assets/admin-7859f34e107ec35880c203a6c71fbd0b6b9dfdd007b9b8741db3c5fafb22d7a5.js.gz
similarity index 93%
rename from public/assets/admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js.gz
rename to public/assets/admin-7859f34e107ec35880c203a6c71fbd0b6b9dfdd007b9b8741db3c5fafb22d7a5.js.gz
index dc9ae6dba..1f8df17c9 100644
Binary files a/public/assets/admin-6575f1399953fb1935c037a7b8bd28c4aff07b70bed9b41faf6899a89af4b57d.js.gz and b/public/assets/admin-7859f34e107ec35880c203a6c71fbd0b6b9dfdd007b9b8741db3c5fafb22d7a5.js.gz differ
diff --git a/public/assets/admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css b/public/assets/admin-e9352b40346e2c36c1d4de8f6e80405102647430dac1f81e6ad8ef9935505909.css
similarity index 99%
rename from public/assets/admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css
rename to public/assets/admin-e9352b40346e2c36c1d4de8f6e80405102647430dac1f81e6ad8ef9935505909.css
index cfd303453..25449185a 100644
--- a/public/assets/admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css
+++ b/public/assets/admin-e9352b40346e2c36c1d4de8f6e80405102647430dac1f81e6ad8ef9935505909.css
@@ -18403,3 +18403,23 @@ label.error {
-webkit-box-flex: 1;
flex: 1;
}
+
+/* line 52, app/assets/stylesheets/admin.scss */
+.font-12 {
+ font-size: 12px !important;
+}
+
+/* line 53, app/assets/stylesheets/admin.scss */
+.font-14 {
+ font-size: 14px !important;
+}
+
+/* line 54, app/assets/stylesheets/admin.scss */
+.font-16 {
+ font-size: 16px !important;
+}
+
+/* line 55, app/assets/stylesheets/admin.scss */
+.font-18 {
+ font-size: 18px !important;
+}
diff --git a/public/assets/admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css.gz b/public/assets/admin-e9352b40346e2c36c1d4de8f6e80405102647430dac1f81e6ad8ef9935505909.css.gz
similarity index 60%
rename from public/assets/admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css.gz
rename to public/assets/admin-e9352b40346e2c36c1d4de8f6e80405102647430dac1f81e6ad8ef9935505909.css.gz
index 682386081..d54280d98 100644
Binary files a/public/assets/admin-8a2b03cb8a055dc63f45443b304cae77382331beba55b1570b3d3c8aa42442d5.css.gz and b/public/assets/admin-e9352b40346e2c36c1d4de8f6e80405102647430dac1f81e6ad8ef9935505909.css.gz differ
diff --git a/public/assets/application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css b/public/assets/application-3d0740554f7108bba10d79d34f0cc47dca1a74fa0a1c423fffd5def99c386e17.css
similarity index 99%
rename from public/assets/application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css
rename to public/assets/application-3d0740554f7108bba10d79d34f0cc47dca1a74fa0a1c423fffd5def99c386e17.css
index 0a6d821b6..71cce1a19 100644
--- a/public/assets/application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css
+++ b/public/assets/application-3d0740554f7108bba10d79d34f0cc47dca1a74fa0a1c423fffd5def99c386e17.css
@@ -18403,6 +18403,26 @@ label.error {
-webkit-box-flex: 1;
flex: 1;
}
+
+/* line 52, app/assets/stylesheets/admin.scss */
+.font-12 {
+ font-size: 12px !important;
+}
+
+/* line 53, app/assets/stylesheets/admin.scss */
+.font-14 {
+ font-size: 14px !important;
+}
+
+/* line 54, app/assets/stylesheets/admin.scss */
+.font-16 {
+ font-size: 16px !important;
+}
+
+/* line 55, app/assets/stylesheets/admin.scss */
+.font-18 {
+ font-size: 18px !important;
+}
@charset "UTF-8";
/* line 1, app/assets/stylesheets/admins/common.scss */
.admin-body-container {
diff --git a/public/assets/application-3d0740554f7108bba10d79d34f0cc47dca1a74fa0a1c423fffd5def99c386e17.css.gz b/public/assets/application-3d0740554f7108bba10d79d34f0cc47dca1a74fa0a1c423fffd5def99c386e17.css.gz
new file mode 100644
index 000000000..f6679e254
Binary files /dev/null and b/public/assets/application-3d0740554f7108bba10d79d34f0cc47dca1a74fa0a1c423fffd5def99c386e17.css.gz differ
diff --git a/public/assets/application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js b/public/assets/application-a4d6c5155da5a1dfbb7291faf09f555d557ee42ed9eb2c0c094d10898e35c687.js
similarity index 99%
rename from public/assets/application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js
rename to public/assets/application-a4d6c5155da5a1dfbb7291faf09f555d557ee42ed9eb2c0c094d10898e35c687.js
index 268928474..cde5193e8 100644
--- a/public/assets/application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js
+++ b/public/assets/application-a4d6c5155da5a1dfbb7291faf09f555d557ee42ed9eb2c0c094d10898e35c687.js
@@ -27721,6 +27721,7 @@ $(document).on('turbolinks:load', function(){
$(document).on('turbolinks:load', function() {
if ($('body.admins-identity-authentications-index-page').length > 0) {
var $searchFrom = $('.identity-authentication-list-form');
+ $searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@@ -27732,14 +27733,160 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
+ $searchFrom.find('select[name="status"]').val('pending');
}
});
}
})
;
+$(document).on('turbolinks:load', function() {
+ if ($('body.admins-mirror-repositories-edit-page, body.admins-mirror-repositories-update-page').length > 0) {
+ var $form = $('form.edit-mirror');
+
+ $form.validate({
+ errorElement: 'span',
+ errorClass: 'danger text-danger',
+ rules: {
+ "mirror_repository[type_name]": {
+ required: true
+ }
+ }
+ });
+
+ $form.submit(function(e){
+ if(!$form.valid()){ e.preventDefault(); }
+ });
+ }
+});
+$(document).on('turbolinks:load', function() {
+ if ($('body.admins-mirror-repositories-index-page').length > 0) {
+ }
+});
+$(document).on('turbolinks:load', function() {
+ $('.admin-modal-container').on('show.bs.modal', '.modal.admin-choose-mirror-modal', function(){
+ var $modal = $('.modal.admin-choose-mirror-modal');
+ var $form = $modal.find('form.admin-choose-mirror-form');
+
+ var validateForm = function(){
+ var checkedValue = $form.find('input[name="mirror_number"]:checked').val();
+
+ if(checkedValue == undefined){
+ $modal.find('.error').html('必须选择一种镜像保存!');
+ return false;
+ }
+ return true;
+ }
+
+ $modal.on('click', '.submit-btn', function(){
+ $form.find('.error').html('');
+ var url = $form.attr('action');
+
+ if (validateForm()) {
+ $.ajax({
+ method: 'POST',
+ dataType: 'script',
+ url: url,
+ data: $form.serialize(),
+ }).done(function(){
+ $modal.modal('hide');
+ });
+ }
+ });
+ })
+});
+$(document).on('turbolinks:load', function() {
+ var $modal = $('.modal.admin-replace-mirror-modal');
+ if ($modal.length > 0) {
+ var $form = $modal.find('form.admin-replace-mirror-form');
+ var $mirrorIdInput = $modal.find('.modal-body input[name="mirror_id"]');
+ var $mirrorSelect = $modal.find('.new-mirror-select');
+
+ var setMirror = function(id, name){
+ $mirrorIdInput.val(id);
+ $form.find('.mirror-id-container').html(id);
+ $form.find('.mirror-name-container').html(name);
+ }
+
+ $form.validate({
+ errorElement: 'span',
+ errorClass: 'danger text-danger',
+ rules: {
+ new_mirror_id: {
+ required: true
+ },
+ },
+ messages: {
+ new_mirror_id: {
+ required: '请选择新镜像'
+ }
+ }
+ });
+
+ // modal ready fire
+ $modal.on('show.bs.modal', function (event) {
+ var $link = $(event.relatedTarget);
+
+ var mirrorId = $link.data('id');
+ var mirrorName = $link.data('name');
+
+ setMirror(mirrorId, mirrorName);
+ $mirrorSelect.select2('val', ' ');
+ });
+ $modal.on('hide.bs.modal', function () {
+ setMirror('', '');
+ $mirrorSelect.select2('val', ' ');
+ $('#new_mirror_id-error').remove();
+ });
+
+ $mirrorSelect.select2({
+ theme: 'bootstrap4',
+ placeholder: '输入要合并的镜像名',
+ minimumInputLength: 1,
+ ajax: {
+ url: '/admins/mirror_repositories/for_select',
+ dataType: 'json',
+ data: function(params){
+ return { keyword: params.term };
+ },
+ processResults: function(data){
+ return { results: data.mirrors }
+ }
+ },
+ templateResult: function (item) {
+ if(!item.id || item.id === '') return item.text;
+ return item.name;
+ },
+ templateSelection: function(item){
+ if (item.id) {
+ $('#new_mirror_id-error').remove();
+ $('#new_mirror_id').val(item.id);
+ }
+ return item.name || item.text;
+ }
+ });
+
+ $modal.on('click', '.submit-btn', function(){
+ $form.find('.error').html('');
+
+ if ($form.valid()) {
+ var url = $form.data('url');
+
+ $.ajax({
+ method: 'POST',
+ dataType: 'script',
+ url: url,
+ data: $form.serialize(),
+ }).done(function(){
+ $modal.modal('hide');
+ });
+ }
+ });
+ }
+});
$(document).on('turbolinks:load', function() {
if ($('body.admins-professional-authentications-index-page').length > 0) {
var $searchFrom = $('.professional-authentication-list-form');
+ $searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@@ -27751,6 +27898,7 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
+ $searchFrom.find('select[name="status"]').val('pending');
}
});
}
@@ -27905,6 +28053,7 @@ $(document).on('turbolinks:load', function() {
$(document).on('turbolinks:load', function() {
if ($('body.admins-shixun-authorizations-index-page').length > 0) {
var $searchFrom = $('.shixun-authorization-list-form');
+ $searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@@ -27916,6 +28065,7 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
+ $searchFrom.find('select[name="status"]').val('pending');
}
});
}
@@ -27940,6 +28090,7 @@ $(document).on('turbolinks:load', function(){
$(document).on('turbolinks:load', function() {
if ($('body.admins-subject-authorizations-index-page').length > 0) {
var $searchFrom = $('.subject-authorization-list-form');
+ $searchFrom.find('select[name="status"]').val('pending');
$searchFrom.on('click', '.search-form-tab', function(){
var $link = $(this);
@@ -27951,6 +28102,7 @@ $(document).on('turbolinks:load', function() {
$searchFrom.find('.status-filter').show();
} else {
$searchFrom.find('.status-filter').hide();
+ $searchFrom.find('select[name="status"]').val('pending');
}
});
}
@@ -28267,8 +28419,11 @@ $(document).on('turbolinks:load', function(){
// flash alert提示框自动关闭
if($('.admin-alert-container .alert').length > 0){
setTimeout(function(){
- $('.admin-alert-container .alert').alert('close');
+ $('.admin-alert-container .alert:not(.alert-danger)').alert('close');
}, 2000);
+ setTimeout(function(){
+ $('.admin-alert-container .alert.alert-danger').alert('close');
+ }, 5000);
}
});
diff --git a/public/assets/application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js.gz b/public/assets/application-a4d6c5155da5a1dfbb7291faf09f555d557ee42ed9eb2c0c094d10898e35c687.js.gz
similarity index 80%
rename from public/assets/application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js.gz
rename to public/assets/application-a4d6c5155da5a1dfbb7291faf09f555d557ee42ed9eb2c0c094d10898e35c687.js.gz
index 120f1b4fd..32521705d 100644
Binary files a/public/assets/application-a3a4f3549d68670572bb07700c85a9ac11e536edc73fef6e7489723bf535e533.js.gz and b/public/assets/application-a4d6c5155da5a1dfbb7291faf09f555d557ee42ed9eb2c0c094d10898e35c687.js.gz differ
diff --git a/public/assets/application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css.gz b/public/assets/application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css.gz
deleted file mode 100644
index d437dd106..000000000
Binary files a/public/assets/application-a7508b88eb6a69a5b301602bddc14745cec09853ea7d91c6fae856b96e788f46.css.gz and /dev/null differ
diff --git a/public/react/src/common/UrlTool.js b/public/react/src/common/UrlTool.js
index e1c9f0c74..12505186a 100644
--- a/public/react/src/common/UrlTool.js
+++ b/public/react/src/common/UrlTool.js
@@ -1,10 +1,10 @@
const isDev = window.location.port == 3007;
-export const TEST_HOST = "http://pre-newweb.educoder.net"
+export const TEST_HOST = "https://pre-newweb.educoder.net"
export function getImageUrl(path) {
// https://www.educoder.net
// https://testbdweb.trustie.net
// const local = 'http://localhost:3000'
- const local = 'http://pre-newweb.educoder.net'
+ const local = 'https://pre-newweb.educoder.net'
if (isDev) {
return `${local}/${path}`
}
@@ -12,7 +12,7 @@ export function getImageUrl(path) {
}
export function setImagesUrl(path){
- const local = 'http://pre-newweb.educoder.net'
+ const local = 'https://pre-newweb.educoder.net'
let firstStr=path.substr(0,1);
// console.log(firstStr);
if(firstStr=="/"){
@@ -31,7 +31,7 @@ export function getUrl(path, goTest) {
// testbdweb.educoder.net testbdweb.trustie.net
// const local = goTest ? 'https://testeduplus2.educoder.net' : 'http://localhost:3000'
// const local = 'https://testeduplus2.educoder.net'
- const local = 'http://pre-newweb.educoder.net'
+ const local = 'https://pre-newweb.educoder.net'
if (isDev) {
return `${local}${path?path:''}`
}
diff --git a/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js b/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js
index ae40fedda..f29204563 100644
--- a/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js
+++ b/public/react/src/modules/courses/busyWork/CommonWorkAppraise.js
@@ -271,15 +271,19 @@ class CommonWorkAppraise extends Component{
{work_members.map((item, index) => {
return
{isAdmin ?
- this.props.toWorkDetailPage(this.props.match.params, null, item.work_id)}
>
{item.user_name}
- : {item.user_name} }
+ : {item.user_name} }
{item.is_leader && }
})}
+ {isAdmin &&
+ 温馨提示:
+ 点击其他组员的姓名,可以快速评阅TA的作品
+
}
diff --git a/public/react/src/modules/courses/busyWork/CommonWorkList.js b/public/react/src/modules/courses/busyWork/CommonWorkList.js
index ca550a965..d6c3d8946 100644
--- a/public/react/src/modules/courses/busyWork/CommonWorkList.js
+++ b/public/react/src/modules/courses/busyWork/CommonWorkList.js
@@ -563,7 +563,7 @@ class CommonWorkList extends Component{
late_penalty, absence_penalty, appeal_penalty
,end_immediately ,publish_immediately
- , homework_id, visible, work_group, project_info
+ , homework_id, visible, work_group, project_info, is_leader
} =this.state;
@@ -610,7 +610,7 @@ class CommonWorkList extends Component{
}else{
StudentData=isStudent ? [{ id, user_name, user_login, student_id, group_name, work_status, update_time, teacher_score, teaching_asistant_score, student_score,
ultimate_score, work_score, student_comment_count, appeal_all_count, appeal_deal_count,
- late_penalty, absence_penalty, appeal_penalty, project_info,
+ late_penalty, absence_penalty, appeal_penalty, project_info, is_leader,
work_group, isMine: true }] : []
}
const columns = buildColumns(this, student_works, StudentData)
@@ -695,8 +695,8 @@ class CommonWorkList extends Component{
- {options_course_group.length > 1 && }
{isGroup && }
+ {options_course_group.length > 1 && }
{/* value={search} */}
diff --git a/public/react/src/modules/courses/busyWork/CommonWorkPost.js b/public/react/src/modules/courses/busyWork/CommonWorkPost.js
index 84ce51fad..1859d6b70 100644
--- a/public/react/src/modules/courses/busyWork/CommonWorkPost.js
+++ b/public/react/src/modules/courses/busyWork/CommonWorkPost.js
@@ -4,7 +4,7 @@ import {Link} from 'react-router-dom';
import axios from 'axios';
import _ from 'lodash'
-import { WordsBtn, getUploadActionUrl, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll } from 'educoder';
+import { WordsBtn, getUploadActionUrl, appendFileSizeToUploadFile, appendFileSizeToUploadFileAll, ConditionToolTip } from 'educoder';
import Modals from '../../modals/Modals';
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
import LeaderIcon from './common/LeaderIcon'
@@ -724,21 +724,25 @@ render(){
-
{members.map((item,key)=>{
return(
{item.user_name}
-
{item.group_name}
-
{item.student_id}
+
9 ? item.group_name : ''}
+ >{item.group_name}
+
12 ? item.student_id : ''}
+ >{item.student_id}
{item.commit_status===true?已提交 :""}
)
@@ -757,23 +761,32 @@ render(){
}
.members .leaderIcon {
}
+ .workPost.members {
+ width: 452px;
+ }
`}
-
+
{selectmemberslist&&selectmemberslist.map((item,key)=>{
+ const _is_leader = (item.is_leader || !this.isEdit && key==0)
return(
-
-
- {item.user_name}{ (item.is_leader || !this.isEdit && key==0) &&
}
+
5}>
+ 5 && _is_leader ? '#4CACFF' : 'inherit'}`}}>
+ {item.user_name}{ item.user_name.length <= 5 && _is_leader && }
-
- {item.group_name}
- {item.student_id}
+
+
+
9 ? item.group_name : ''}
+ >{item.group_name}
+
12 ? item.student_id : ''}
+ >{item.student_id}
{item.user_id != this.props.current_user.user_id ?
this.delecttask_status(item.user_id)}>
:""}
diff --git a/public/react/src/modules/courses/busyWork/common/LeaderIcon.js b/public/react/src/modules/courses/busyWork/common/LeaderIcon.js
index 20ecce43f..7d56d1b24 100644
--- a/public/react/src/modules/courses/busyWork/common/LeaderIcon.js
+++ b/public/react/src/modules/courses/busyWork/common/LeaderIcon.js
@@ -8,13 +8,14 @@ export default function LeaderIcon(props = {}) {
icon =
组长
} else {
- icon =
组长
+ icon =
组长
}
return icon
diff --git a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js
index 9718de28a..1b25a5717 100644
--- a/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js
+++ b/public/react/src/modules/courses/graduation/tasks/GraduationTaskssettinglist.js
@@ -711,8 +711,12 @@ class GraduationTaskssettinglist extends Component{
title: '姓名',
dataIndex: 'name',
key: 'name',
-
- className:'edu-txt-center'
+ className:'edu-txt-center',
+ render: (text, record) => (
+
+ {record.name}
+
+ ),
}, {
title: '学号',
dataIndex: 'stduynumber',
@@ -720,7 +724,7 @@ class GraduationTaskssettinglist extends Component{
className:'edu-txt-center',
render: (text, record) => (
- {record.stduynumber}
+ {record.stduynumber}
),
}, {
@@ -935,6 +939,7 @@ class GraduationTaskssettinglist extends Component{
if(taskslistdata&&taskslistdata.have_grouping===false){
+
columns.some((item,key)=> {
if (item.title === "分组") {
columns.splice(key, 1)
@@ -961,10 +966,38 @@ class GraduationTaskssettinglist extends Component{
.linbox{
height: 26px;
}
+ .ant-table-tbody>tr>td, .ant-table-thead>tr>th{
+ padding: 16px 10px
+ }
+
`
}
+ {taskslistdata&&taskslistdata.have_grouping===true||
+ taskslistdata&&taskslistdata.have_project===true||
+ taskslistdata&&taskslistdata.cross_comment===true?:""}
{/*提示*/}
分班情况:
+
+
+
+
+ this.groupgroup(e,taskslistdata.search_assistants&&taskslistdata.search_assistants.course_group_info.length)} style={{width: '1000px', paddingTop: '4px'}}>
+
+
+ {taskslistdata.search_assistants&&taskslistdata.search_assistants.course_group_info.map((item,key)=>{
+ return(
+
+ {item.group_group_name}
+ ({item.count})
+
+
+ )
+ })}
+
+
- this.groupgroup(e,taskslistdata.search_assistants&&taskslistdata.search_assistants.course_group_info.length)} style={{width: '1000px', paddingTop: '4px'}}>
-
-
-
-
- {taskslistdata.search_assistants&&taskslistdata.search_assistants.course_group_info.map((item,key)=>{
- return(
-
- {item.group_group_name}
- ({item.count})
-
-
- )
- })}
-
:""}
diff --git a/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js b/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js
index d5e77da9d..9b3d72e00 100644
--- a/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js
+++ b/public/react/src/modules/courses/members/modal/CreateGroupByImportModal.js
@@ -45,6 +45,7 @@ class CreateGroupByImportModal extends Component{
.then((response) => {
if (response.data.status == 0) {
this.props.showNotification(response.data.message)
+ this.props.createGroupImportSuccess && this.props.createGroupImportSuccess()
this.setVisible(false)
} else {
diff --git a/public/react/src/modules/courses/members/studentsList.js b/public/react/src/modules/courses/members/studentsList.js
index cc7485101..3462438f8 100644
--- a/public/react/src/modules/courses/members/studentsList.js
+++ b/public/react/src/modules/courses/members/studentsList.js
@@ -234,6 +234,9 @@ class studentsList extends Component{
off('updateNavSuccess', this.updateNavSuccess)
}
}
+ createGroupImportSuccess = () => {
+ this.props.updataleftNavfun()
+ }
updateNavSuccess = () => {
this.fetchCourseGroups()
}
@@ -556,7 +559,9 @@ class studentsList extends Component{
firstRowRight={
{ isSuperAdmin &&
-
+
this.refs['createGroupByImportModal'].setVisible(true)}>导入创建分班
}
{ isAdmin && isParent && this.addDir()}>添加分班 }
diff --git a/public/react/src/modules/courses/members/teacherList.js b/public/react/src/modules/courses/members/teacherList.js
index 06dbe74a8..e3fd4a98d 100644
--- a/public/react/src/modules/courses/members/teacherList.js
+++ b/public/react/src/modules/courses/members/teacherList.js
@@ -42,6 +42,7 @@ function buildColumns(that) {
title: '序号',
dataIndex: 'name',
key: 'index',
+ width: 78,
render: (content, item, index) => {
return index + 1
// return item.isApply == true ? '' : {(that.state.page - 1) * 20 + index + 1
@@ -74,6 +75,7 @@ function buildColumns(that) {
dataIndex: 'role',
key: 'role',
sorter: showSorter,
+ width: 86,
// 'ascend' | 'descend'
defaultSortOrder: 'ascend',
sortDirections: sortDirections,
@@ -160,16 +162,16 @@ function buildColumns(that) {
},
})
}
- if(isAdminOrTeacher && hasGraduationModule) {
- columns.unshift({
- title: '',
- dataIndex: 'course_member_id',
- key: 'course_member_id',
- render: (content, item, index) => {
- return content ? : ''
- }
- })
- }
+ // if(isAdminOrTeacher && hasGraduationModule) {
+ // columns.unshift({
+ // title: '',
+ // dataIndex: 'course_member_id',
+ // key: 'course_member_id',
+ // render: (content, item, index) => {
+ // return content ? : ''
+ // }
+ // })
+ // }
return columns
}
diff --git a/public/react/src/modules/tpm/challengesnew/TPMquestion.js b/public/react/src/modules/tpm/challengesnew/TPMquestion.js
index 82d94f787..8fc2b1133 100644
--- a/public/react/src/modules/tpm/challengesnew/TPMquestion.js
+++ b/public/react/src/modules/tpm/challengesnew/TPMquestion.js
@@ -411,9 +411,7 @@ export default class TPMquestion extends Component {
window.location.href = '/shixuns/'+this.props.match.params.shixunId+'/challenges/'+this.props.match.params.checkpointId+'/editquestion';
}
questionadd=()=>{
- $('html').animate({
- scrollTop: 10
- }, 200);
+
let{questionaddarray}=this.state;
let questionaddsums=questionaddarray.length;
@@ -431,15 +429,13 @@ export default class TPMquestion extends Component {
}
})
-
-
questionaddarrays.push({type:0,choose_id:0});
this.setState({
activetype:0,
questionaddarray:questionaddarrays,
questionaddtype:true,
+ editquestionaddtype:false,
newquestionaddtype:true,
- editquestionaddtype:false,
questionlists:[{str:"A",val:"",type:false},{str:"B",val:"",type:false},{str:"C",val:"",type:false},{str:"D",val:"",type:false}],
answeshixunsGroup: 1,
answeoptions:[10,20],
@@ -447,17 +443,17 @@ export default class TPMquestion extends Component {
shixunssanswerkillvalue:"",
shixunsskillanswerlist:[],
contentMdRefval:"",
- newquestioMDMdContval:""
+ newquestioMDMdContval:"",
})
- // setTimeout(() => {
- // this.newquestioMDMdCont.current.setValue('')
- // this.newquestioMDMdRef.current.setValue('')
- //
- // }, 2000)
-
- this.shixunsautoHeight()
+ setTimeout(() => {
+ this.newquestioMDMdRef.current.setValue('')
+ }, 1000)
+ setTimeout(() => {
+ this.newquestioMDMdCont.current.setValue('')
+ }, 1500)
+ // this.shixunsautoHeight()
}
editquestionlists=(newquestionlists)=>{
@@ -592,6 +588,10 @@ export default class TPMquestion extends Component {
}
answer_subit=(sumtype,challenge_choose_id)=>{
+ $('html').animate({
+ scrollTop:10
+ }, 500);
+
let {challenge_id,questionlists,shixunsskillanswerlist,answeonshixunsmark,answeshixunsGroup,questionaddarray} =this.state;
if(challenge_id===undefined){
message.error("关卡id为空");
@@ -679,6 +679,7 @@ export default class TPMquestion extends Component {
let id = this.props.match.params.shixunId;
+ let checkpointId=this.props.match.params.checkpointId
let url;
if(sumtype==="edit"){
let newquestioMDvalue = this.neweditanswerRef.current.getValue().trim();
@@ -781,7 +782,9 @@ export default class TPMquestion extends Component {
description:
'新建成功,请点击右侧加号继续添加',
});
- // this.getanswer_subitlist()
+ window.location.href=`/shixuns/${id}/challenges/${checkpointId}/editquestion/${response.data.challenge_choose_id}`;
+
+ // this.getanswer_subitlist()
// this.gochooseid("/shixuns/"+this.props.match.params.shixunId+"/challenges/"+this.props.match.params.checkpointId+"/editquestion"+"/"+response.data.challenge_choose_id)
}).catch((error) => {
console.log(error)
@@ -817,7 +820,8 @@ export default class TPMquestion extends Component {
neweditanswerRefval:'',
editanswersRefval:''
})
-
+ this.newquestioMDMdRef.current.setValue('')
+ this.newquestioMDMdCont.current.setValue('')
}else{
let id = this.props.match.params.shixunId;
let url ='/shixuns/'+id+'/challenges/'+challenge_id+'/edit_choose_question.json?choose_id='+challenge_choose_id;
@@ -920,6 +924,7 @@ export default class TPMquestion extends Component {
{d}
)
})
+
return (
diff --git a/public/react/src/modules/tpm/challengesnew/TpmQuestionEdit.js b/public/react/src/modules/tpm/challengesnew/TpmQuestionEdit.js
index 32b56aae1..d0e6f98bd 100644
--- a/public/react/src/modules/tpm/challengesnew/TpmQuestionEdit.js
+++ b/public/react/src/modules/tpm/challengesnew/TpmQuestionEdit.js
@@ -4,6 +4,8 @@ import {Input, Select, Radio, Checkbox, Popconfirm, message, Modal,Tooltip} from
import {BrowserRouter as Router, Route, Link, Switch} from "react-router-dom";
+import axios from 'axios';
+
import TPMMDEditor from '../../tpm/challengesnew/TPMMDEditor';
const Option = Select.Option;
@@ -21,7 +23,17 @@ export default class TpmQuestionEdit extends Component {
componentDidMount() {
}
-
+ delecbtns=()=>{
+ let url=`/shixuns/${this.props.match.params.shixunId}/challenges/${this.props.match.params.checkpointId}/destroy_challenge_choose.json`;
+ axios.delete((url), { data: {
+ choose_id:this.props.match.params.choose_id
+ }})
+ .then((result)=>{
+ if(result.data.status===1){
+ window.location.href=`/shixuns/${this.props.match.params.shixunId}/challenges/${this.props.match.params.checkpointId}/editquestion`;
+ }
+ })
+ }
render() {
@@ -202,6 +214,9 @@ export default class TpmQuestionEdit extends Component {
onClick={()=>this.props.answer_subit()}>提交
取消
+
+
this.delecbtns()}
+ className="delectshixuncdbtn fr">删除
diff --git a/public/react/src/modules/tpm/challengesnew/TpmQuestionNew.js b/public/react/src/modules/tpm/challengesnew/TpmQuestionNew.js
index 855f6ce53..861c4f879 100644
--- a/public/react/src/modules/tpm/challengesnew/TpmQuestionNew.js
+++ b/public/react/src/modules/tpm/challengesnew/TpmQuestionNew.js
@@ -35,7 +35,7 @@ export default class TpmQuestionNew extends Component {
*
+ needRecreate={true} watch={true} className="courseMessageMD" initValue={this.props.contentMdRefval}>
@@ -108,7 +108,7 @@ export default class TpmQuestionNew extends Component {
+ needRecreate={true} watch={true} className="courseMessageMD" initValue={this.props.newquestioMDMdContval}>
必填项
diff --git a/public/react/src/modules/user/usersInfo/InfosBanner.js b/public/react/src/modules/user/usersInfo/InfosBanner.js
index 08bea57ed..3aa329ec9 100644
--- a/public/react/src/modules/user/usersInfo/InfosBanner.js
+++ b/public/react/src/modules/user/usersInfo/InfosBanner.js
@@ -1,122 +1,124 @@
-import React, { Component } from 'react';
-
-import {Link} from 'react-router-dom';
-import {Tooltip,Menu} from 'antd';
-import {getImageUrl} from 'educoder';
-
-import "./usersInfo.css"
-import "../../courses/css/members.css"
-import "../../courses/css/Courses.css"
-
-import { LinkAfterLogin } from 'educoder'
-
-class InfosBanner extends Component{
- constructor(props){
- super(props);
- }
- render(){
- let {
- data ,
- id,
- login,
- moduleName,
- current_user,
- }=this.props;
- let is_current=this.props.is_current;
- let {username}= this.props.match.params;
- let {pathname}=this.props.location;
- moduleName=pathname.split("/")[3];
- return(
-
-
-
-
-
-
- {data && data.name}
- {
- data && is_current == false && data.identity =="学生" ? "" :
- {data && data.identity}
- }
-
-
-
-
-
-
-
-
-
-
-
-
-
- {
- is_current ?
-
- {
- data && data.attendance_signed ?
- 已签到
- :
- 签到
- }
-
- :
-
-
- 私信
-
-
- }
-
-
-
-
- this.setState({moduleName: 'courses'})}
- to={`/users/${username}/courses`}>翻转课堂
-
-
- this.setState({moduleName: 'shixuns'})}
- to={`/users/${username}/shixuns`}>开发社区
-
-
- this.setState({moduleName: 'paths'})}
- to={`/users/${username}/paths`}>实践课程
-
-
- this.setState({moduleName: 'projects'})}
- to={`/users/${username}/projects`}>项目
-
-
- this.setState({moduleName: 'package'})}
- to={`/users/${username}/package`}>众包
-
- {((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin)
- &&
- this.setState({moduleName: 'videos'})}
- to={`/users/${username}/videos`}>视频
- }
-
-
-
- )
- }
-}
+import React, { Component } from 'react';
+
+import {Link} from 'react-router-dom';
+import {Tooltip,Menu} from 'antd';
+import {getImageUrl} from 'educoder';
+
+import "./usersInfo.css"
+import "../../courses/css/members.css"
+import "../../courses/css/Courses.css"
+
+import { LinkAfterLogin } from 'educoder'
+
+class InfosBanner extends Component{
+ constructor(props){
+ super(props);
+ }
+ render(){
+ let {
+ data ,
+ id,
+ login,
+ moduleName,
+ current_user,
+ }=this.props;
+ let is_current=this.props.is_current;
+ let {username}= this.props.match.params;
+ let {pathname}=this.props.location;
+ moduleName=pathname.split("/")[3];
+
+ return(
+
+
+
+
+
+
+ {data && data.name}
+ {
+ data && is_current == false && data.identity =="学生" ? "" :
+ {data && data.identity}
+ }
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {
+ is_current ?
+
+ {
+ data && data.attendance_signed ?
+ 已签到
+ :
+ 签到
+ }
+
+ :
+
+
+ 私信
+
+
+ }
+
+
+
+
+ this.setState({moduleName: 'courses'})}
+ to={`/users/${username}/courses`}>翻转课堂
+
+
+ this.setState({moduleName: 'shixuns'})}
+ to={`/users/${username}/shixuns`}>实训项目
+
+
+ this.setState({moduleName: 'paths'})}
+ to={`/users/${username}/paths`}>实践课程
+
+
+ this.setState({moduleName: 'projects'})}
+ to={`/users/${username}/projects`}>开发项目
+
+
+ this.setState({moduleName: 'package'})}
+ to={`/users/${username}/package`}>众包
+
+ {((is_current && current_user && current_user.is_teacher ) || current_user && current_user.admin)
+ &&
+ this.setState({moduleName: 'videos'})}
+ to={`/users/${username}/videos`}>视频
+ }
+
+
+
+
+ )
+ }
+}
export default InfosBanner;
\ No newline at end of file
diff --git a/public/stylesheets/educoder/edu-main.css b/public/stylesheets/educoder/edu-main.css
index f59827f45..c66453b4c 100644
--- a/public/stylesheets/educoder/edu-main.css
+++ b/public/stylesheets/educoder/edu-main.css
@@ -538,6 +538,27 @@ a.edu-greyline-btn:hover,a.edu-greyshallowline-btn:hover{border:1px solid #B2B2B
font-weight: 400;
color: rgba(255,255,255,1);
}
+
+/*删除按钮*/
+.delectshixuncdbtn{
+ display: block;
+ border: 1px solid #CDCDCD;
+ background-color: #fafafa;
+ color: #999!important;
+ width: 120px;
+ text-align: center;
+ height: 30px;
+ line-height: 30px;
+ border-radius: 2px;
+ width: 130px;
+ height: 40px;
+ background: rgba(77,124,254,0);
+ border-radius: 4px;
+ line-height: 40px;
+ font-size: 16px;
+ font-family: MicrosoftYaHei;
+ font-weight: 400;
+}
.defalutSubmitbtn:hover{background-color: #459BE6;border: 1px solid #459BE6;}
/*-------------------------------------------公用按钮:以white-btn(或者edu-default-btn无padding)为基础,宽度和高度可以用padding填充,颜色用edu-color-btn,end-----------------------------------------*/