From 5e4bd66c56138dd1b66e257269dc1f29aecb63bc Mon Sep 17 00:00:00 2001 From: p31729568 Date: Tue, 27 Aug 2019 16:42:09 +0800 Subject: [PATCH] admins: shixun mirror manage feature --- app/assets/javascripts/admin.js | 5 +- .../admins/mirror_repositories/edit.js | 19 ++++ .../admins/mirror_repositories/index.js | 4 + .../modals/admin-choose-mirror-modal.js | 32 +++++++ .../modals/admin-replace-mirror-modal.js | 89 +++++++++++++++++ app/assets/stylesheets/admin.scss | 7 +- .../choose_mirror_repositories_controller.rb | 11 +++ .../admins/mirror_repositories_controller.rb | 96 +++++++++++++++++++ .../concerns/admins/render_helper.rb | 8 +- .../admins/mirror_repositories_helper.rb | 23 +++++ app/models/mirror_operation_record.rb | 7 ++ app/models/mirror_repository.rb | 4 + .../admins/check_shixun_mirrors_service.rb | 89 +++++++++++++++++ app/services/admins/choose_mirror_service.rb | 21 ++++ .../admins/save_mirror_repository_service.rb | 37 +++++++ .../choose_mirror_repositories/create.js.erb | 5 + .../choose_mirror_repositories/new.js.erb | 2 + .../admins/mirror_repositories/edit.html.erb | 8 ++ .../admins/mirror_repositories/index.html.erb | 23 +++++ .../admins/mirror_repositories/index.js.erb | 1 + .../admins/mirror_repositories/merge.js.erb | 5 + .../admins/mirror_repositories/new.html.erb | 8 ++ .../shared/_choose_mirror_modal.html.erb | 42 ++++++++ .../mirror_repositories/shared/_form.html.erb | 42 ++++++++ .../mirror_repositories/shared/_list.html.erb | 54 +++++++++++ .../shared/_replace_mirror_modal.html.erb | 33 +++++++ app/views/admins/shared/500.html.erb | 2 +- app/views/admins/shared/_paginate.html.erb | 2 +- app/views/admins/shared/_sidebar.html.erb | 6 ++ app/views/admins/users/edit.html.erb | 2 +- config/routes.rb | 7 ++ 31 files changed, 685 insertions(+), 9 deletions(-) create mode 100644 app/assets/javascripts/admins/mirror_repositories/edit.js create mode 100644 app/assets/javascripts/admins/mirror_repositories/index.js create mode 100644 app/assets/javascripts/admins/modals/admin-choose-mirror-modal.js create mode 100644 app/assets/javascripts/admins/modals/admin-replace-mirror-modal.js create mode 100644 app/controllers/admins/choose_mirror_repositories_controller.rb create mode 100644 app/controllers/admins/mirror_repositories_controller.rb create mode 100644 app/helpers/admins/mirror_repositories_helper.rb create mode 100644 app/models/mirror_operation_record.rb create mode 100644 app/services/admins/check_shixun_mirrors_service.rb create mode 100644 app/services/admins/choose_mirror_service.rb create mode 100644 app/services/admins/save_mirror_repository_service.rb create mode 100644 app/views/admins/choose_mirror_repositories/create.js.erb create mode 100644 app/views/admins/choose_mirror_repositories/new.js.erb create mode 100644 app/views/admins/mirror_repositories/edit.html.erb create mode 100644 app/views/admins/mirror_repositories/index.html.erb create mode 100644 app/views/admins/mirror_repositories/index.js.erb create mode 100644 app/views/admins/mirror_repositories/merge.js.erb create mode 100644 app/views/admins/mirror_repositories/new.html.erb create mode 100644 app/views/admins/mirror_repositories/shared/_choose_mirror_modal.html.erb create mode 100644 app/views/admins/mirror_repositories/shared/_form.html.erb create mode 100644 app/views/admins/mirror_repositories/shared/_list.html.erb create mode 100644 app/views/admins/mirror_repositories/shared/_replace_mirror_modal.html.erb 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..3ff17412e 100644 --- a/app/controllers/concerns/admins/render_helper.rb +++ b/app/controllers/concerns/admins/render_helper.rb @@ -25,11 +25,11 @@ module Admins::RenderHelper end alias_method :render_error, :render_unprocessable_entity - def internal_server_error + def internal_server_error(message = '系统错误') respond_to do |format| - format.html { render 'admins/shared/500' } - format.js { render_js_error('系统错误') } - format.json { render status: 500, json: { message: '系统错误' } } + format.html { render partail: 'admins/shared/500', locals: { message: message } } + format.js { render_js_error(message) } + format.json { render status: 500, json: { message: message } } end end 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/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/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 @@ + \ 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 @@ + + + + + + + + + + + + + + + + <% if mirrors.present? %> + <% mirrors.each do |mirror| %> + + + + + + + + + + + + <% end %> + <% else %> + <%= render 'admins/shared/no_data_for_table' %> + <% end %> + +
ID类别镜像别名镜像名称镜像描述修改时间脚本状态操作
<%= 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 %> +
+ +<%= 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..bdcf58a75 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/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 认证回调