Merge branches 'dev_aliyun', 'dev_item_bank' and 'new_shixuns_repository' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_item_bank
	
		
	
				
					
				
			
						commit
						7522bc9b5a
					
				| @ -0,0 +1,124 @@ | |||||||
|  | $(document).on('turbolinks:load', function() { | ||||||
|  |   if ($('body.admins-disciplines-index-page').length > 0) { | ||||||
|  | 
 | ||||||
|  |     // ============== 新建 ===============
 | ||||||
|  |     var $modal = $('.modal.admin-create-discipline-modal'); | ||||||
|  |     var $form = $modal.find('form.admin-create-discipline-form'); | ||||||
|  |     var $nameInput = $form.find('input[name="name"]'); | ||||||
|  | 
 | ||||||
|  |     $form.validate({ | ||||||
|  |       errorElement: 'span', | ||||||
|  |       errorClass: 'danger text-danger', | ||||||
|  |       rules: { | ||||||
|  |         name: { | ||||||
|  |           required: true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // modal ready fire
 | ||||||
|  |     $modal.on('show.bs.modal', function () { | ||||||
|  |         $nameInput.val(''); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     $modal.on('click', '.submit-btn', function(){ | ||||||
|  |       $form.find('.error').html(''); | ||||||
|  | 
 | ||||||
|  |       if ($form.valid()) { | ||||||
|  |         var url = $form.data('url'); | ||||||
|  | 
 | ||||||
|  |         $.ajax({ | ||||||
|  |           method: 'POST', | ||||||
|  |           dataType: 'json', | ||||||
|  |           url: url, | ||||||
|  |           data: $form.serialize(), | ||||||
|  |           success: function(){ | ||||||
|  |             $.notify({ message: '创建成功' }); | ||||||
|  |             $modal.modal('hide'); | ||||||
|  | 
 | ||||||
|  |             setTimeout(function(){ | ||||||
|  |               window.location.reload(); | ||||||
|  |             }, 500); | ||||||
|  |           }, | ||||||
|  |           error: function(res){ | ||||||
|  |             var data = res.responseJSON; | ||||||
|  |             $form.find('.error').html(data.message); | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |       $(".discipline-list-container").on("change", '.discipline-source-form', function () { | ||||||
|  |           var s_id = $(this).attr("data-id"); | ||||||
|  |           var s_value = $(this).val(); | ||||||
|  |           var s_name = $(this).attr("name"); | ||||||
|  |           var json = {}; | ||||||
|  |           json[s_name] = s_value; | ||||||
|  |           $.ajax({ | ||||||
|  |               url: "/admins/disciplines/" + s_id, | ||||||
|  |               type: "PUT", | ||||||
|  |               dataType:'script', | ||||||
|  |               data: json | ||||||
|  |           }); | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       // 导入学生
 | ||||||
|  |       var $importDisciplineModal = $('.modal.admin-import-discipline-modal'); | ||||||
|  |       var $importDisciplineForm = $importDisciplineModal.find('form.admin-import-discipline-form'); | ||||||
|  | 
 | ||||||
|  |       $importDisciplineModal.on('show.bs.modal', function(){ | ||||||
|  |           resetFileInputFunc($importDisciplineModal.find('.upload-file-input')); | ||||||
|  |           $importDisciplineModal.find('.file-names').html('选择文件'); | ||||||
|  |           $importDisciplineModal.find('.upload-file-input').trigger('click'); | ||||||
|  |       }); | ||||||
|  |       $importDisciplineModal.on('change', '.upload-file-input', function(e){ | ||||||
|  |           var file = $(this)[0].files[0]; | ||||||
|  |           $importDisciplineModal.find('.file-names').html(file ? file.name : '请选择文件'); | ||||||
|  |       }); | ||||||
|  | 
 | ||||||
|  |       var importDisciplineFormValid = function(){ | ||||||
|  |           if($importDisciplineForm.find('input[name="file"]').val() == undefined || $importDisciplineForm.find('input[name="file"]').val().length == 0){ | ||||||
|  |               $importDisciplineForm.find('.error').html('请选择文件'); | ||||||
|  |               return false; | ||||||
|  |           } | ||||||
|  | 
 | ||||||
|  |           return true; | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|  |       var buildResultMessage = function(data){ | ||||||
|  |           var messageHtml = "<div>导入结果:成功" + data.success + "条,失败"+ data.fail.length + "条</div>"; | ||||||
|  | 
 | ||||||
|  |           return messageHtml; | ||||||
|  |       }; | ||||||
|  | 
 | ||||||
|  |       $importDisciplineModal.on('click', '.submit-btn', function(){ | ||||||
|  |           $importDisciplineForm.find('.error').html(''); | ||||||
|  | 
 | ||||||
|  |           if (importDisciplineFormValid()) { | ||||||
|  |               $('body').mLoading({ text: '正在导入...' }); | ||||||
|  | 
 | ||||||
|  |               $.ajax({ | ||||||
|  |                   method: 'POST', | ||||||
|  |                   dataType: 'json', | ||||||
|  |                   url: '/admins/import_disciplines', | ||||||
|  |                   data: new FormData($importDisciplineForm[0]), | ||||||
|  |                   processData: false, | ||||||
|  |                   contentType: false, | ||||||
|  |                   success: function(data){ | ||||||
|  |                       $('body').mLoading('destroy'); | ||||||
|  |                       $importDisciplineModal.modal('hide'); | ||||||
|  | 
 | ||||||
|  |                       showMessageModal(buildResultMessage(data), function(){ | ||||||
|  |                           window.location.reload(); | ||||||
|  |                       }); | ||||||
|  |                   }, | ||||||
|  |                   error: function(res){ | ||||||
|  |                       $('body').mLoading('destroy'); | ||||||
|  |                       var data = res.responseJSON; | ||||||
|  |                       $importDisciplineForm.find('.error').html(data.message); | ||||||
|  |                   } | ||||||
|  |               }); | ||||||
|  |           } | ||||||
|  |       }); | ||||||
|  |   } | ||||||
|  | }); | ||||||
| @ -0,0 +1,31 @@ | |||||||
|  | $(document).on('turbolinks:load', function() { | ||||||
|  |   $('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-discipline-modal', function(){ | ||||||
|  |     var $modal = $('.modal.admin-edit-discipline-modal'); | ||||||
|  |     var $form = $modal.find('form.admin-edit-discipline-form'); | ||||||
|  | 
 | ||||||
|  |     $form.validate({ | ||||||
|  |       errorElement: 'span', | ||||||
|  |       errorClass: 'danger text-danger', | ||||||
|  |       rules: { | ||||||
|  |         'discipline[name]': { | ||||||
|  |           required: true, | ||||||
|  |           maxlength: 20 | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     $modal.on('click', '.submit-btn', function(){ | ||||||
|  |       $form.find('.error').html(''); | ||||||
|  |       var url = $form.attr('action'); | ||||||
|  | 
 | ||||||
|  |       if ($form.valid()) { | ||||||
|  |         $.ajax({ | ||||||
|  |             method: 'PATCH', | ||||||
|  |             dataType: 'script', | ||||||
|  |             url: url, | ||||||
|  |             data: $form.serialize() | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -0,0 +1,31 @@ | |||||||
|  | $(document).on('turbolinks:load', function() { | ||||||
|  |   $('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-sub-discipline-modal', function(){ | ||||||
|  |     var $modal = $('.modal.admin-edit-sub-discipline-modal'); | ||||||
|  |     var $form = $modal.find('form.admin-edit-sub-discipline-form'); | ||||||
|  | 
 | ||||||
|  |     $form.validate({ | ||||||
|  |       errorElement: 'span', | ||||||
|  |       errorClass: 'danger text-danger', | ||||||
|  |       rules: { | ||||||
|  |         'sub_discipline[name]': { | ||||||
|  |           required: true, | ||||||
|  |           maxlength: 20 | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     $modal.on('click', '.submit-btn', function(){ | ||||||
|  |       $form.find('.error').html(''); | ||||||
|  |       var url = $form.attr('action'); | ||||||
|  | 
 | ||||||
|  |       if ($form.valid()) { | ||||||
|  |         $.ajax({ | ||||||
|  |             method: 'PATCH', | ||||||
|  |             dataType: 'script', | ||||||
|  |             url: url, | ||||||
|  |             data: $form.serialize() | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -0,0 +1,31 @@ | |||||||
|  | $(document).on('turbolinks:load', function() { | ||||||
|  |   $('.admin-modal-container').on('show.bs.modal', '.modal.admin-edit-tag-discipline-modal', function(){ | ||||||
|  |     var $modal = $('.modal.admin-edit-tag-discipline-modal'); | ||||||
|  |     var $form = $modal.find('form.admin-edit-tag-discipline-form'); | ||||||
|  | 
 | ||||||
|  |     $form.validate({ | ||||||
|  |       errorElement: 'span', | ||||||
|  |       errorClass: 'danger text-danger', | ||||||
|  |       rules: { | ||||||
|  |         'tag_discipline[name]': { | ||||||
|  |           required: true, | ||||||
|  |           maxlength: 20 | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     $modal.on('click', '.submit-btn', function(){ | ||||||
|  |       $form.find('.error').html(''); | ||||||
|  |       var url = $form.attr('action'); | ||||||
|  | 
 | ||||||
|  |       if ($form.valid()) { | ||||||
|  |         $.ajax({ | ||||||
|  |             method: 'PATCH', | ||||||
|  |             dataType: 'script', | ||||||
|  |             url: url, | ||||||
|  |             data: $form.serialize() | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  |   }); | ||||||
|  | }); | ||||||
| @ -0,0 +1,65 @@ | |||||||
|  | $(document).on('turbolinks:load', function() { | ||||||
|  |   if ($('body.admins-sub-disciplines-index-page').length > 0) { | ||||||
|  | 
 | ||||||
|  |     // ============== 新建 ===============
 | ||||||
|  |     var $modal = $('.modal.admin-create-sub-discipline-modal'); | ||||||
|  |     var $form = $modal.find('form.admin-create-sub-discipline-form'); | ||||||
|  |     var $nameInput = $form.find('input[name="name"]'); | ||||||
|  | 
 | ||||||
|  |     $form.validate({ | ||||||
|  |       errorElement: 'span', | ||||||
|  |       errorClass: 'danger text-danger', | ||||||
|  |       rules: { | ||||||
|  |         name: { | ||||||
|  |           required: true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // modal ready fire
 | ||||||
|  |     $modal.on('show.bs.modal', function () { | ||||||
|  |         $nameInput.val(''); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     $modal.on('click', '.submit-btn', function(){ | ||||||
|  |       $form.find('.error').html(''); | ||||||
|  | 
 | ||||||
|  |       if ($form.valid()) { | ||||||
|  |         var url = $form.data('url'); | ||||||
|  | 
 | ||||||
|  |         $.ajax({ | ||||||
|  |           method: 'POST', | ||||||
|  |           dataType: 'json', | ||||||
|  |           url: url, | ||||||
|  |           data: $form.serialize(), | ||||||
|  |           success: function(){ | ||||||
|  |             $.notify({ message: '创建成功' }); | ||||||
|  |             $modal.modal('hide'); | ||||||
|  | 
 | ||||||
|  |             setTimeout(function(){ | ||||||
|  |               window.location.reload(); | ||||||
|  |             }, 500); | ||||||
|  |           }, | ||||||
|  |           error: function(res){ | ||||||
|  |             var data = res.responseJSON; | ||||||
|  |             $form.find('.error').html(data.message); | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |       $(".sub-discipline-list-container").on("change", '.sub-discipline-source-form', function () { | ||||||
|  |           var s_id = $(this).attr("data-id"); | ||||||
|  |           var s_value = $(this).val(); | ||||||
|  |           var s_name = $(this).attr("name"); | ||||||
|  |           var json = {}; | ||||||
|  |           json[s_name] = s_value; | ||||||
|  |           $.ajax({ | ||||||
|  |               url: "/admins/sub_disciplines/" + s_id, | ||||||
|  |               type: "PUT", | ||||||
|  |               dataType:'script', | ||||||
|  |               data: json | ||||||
|  |           }); | ||||||
|  |       }); | ||||||
|  |   } | ||||||
|  | }); | ||||||
| @ -0,0 +1,65 @@ | |||||||
|  | $(document).on('turbolinks:load', function() { | ||||||
|  |   if ($('body.admins-tag-disciplines-index-page').length > 0) { | ||||||
|  | 
 | ||||||
|  |     // ============== 新建 ===============
 | ||||||
|  |     var $modal = $('.modal.admin-create-tag-discipline-modal'); | ||||||
|  |     var $form = $modal.find('form.admin-create-tag-discipline-form'); | ||||||
|  |     var $nameInput = $form.find('input[name="name"]'); | ||||||
|  | 
 | ||||||
|  |     $form.validate({ | ||||||
|  |       errorElement: 'span', | ||||||
|  |       errorClass: 'danger text-danger', | ||||||
|  |       rules: { | ||||||
|  |         name: { | ||||||
|  |           required: true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     // modal ready fire
 | ||||||
|  |     $modal.on('show.bs.modal', function () { | ||||||
|  |         $nameInput.val(''); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     $modal.on('click', '.submit-btn', function(){ | ||||||
|  |       $form.find('.error').html(''); | ||||||
|  | 
 | ||||||
|  |       if ($form.valid()) { | ||||||
|  |         var url = $form.data('url'); | ||||||
|  | 
 | ||||||
|  |         $.ajax({ | ||||||
|  |           method: 'POST', | ||||||
|  |           dataType: 'json', | ||||||
|  |           url: url, | ||||||
|  |           data: $form.serialize(), | ||||||
|  |           success: function(){ | ||||||
|  |             $.notify({ message: '创建成功' }); | ||||||
|  |             $modal.modal('hide'); | ||||||
|  | 
 | ||||||
|  |             setTimeout(function(){ | ||||||
|  |               window.location.reload(); | ||||||
|  |             }, 500); | ||||||
|  |           }, | ||||||
|  |           error: function(res){ | ||||||
|  |             var data = res.responseJSON; | ||||||
|  |             $form.find('.error').html(data.message); | ||||||
|  |           } | ||||||
|  |         }); | ||||||
|  |       } | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |       $(".tag-discipline-list-container").on("change", '.tag-discipline-source-form', function () { | ||||||
|  |           var s_id = $(this).attr("data-id"); | ||||||
|  |           var s_value = $(this).val(); | ||||||
|  |           var s_name = $(this).attr("name"); | ||||||
|  |           var json = {}; | ||||||
|  |           json[s_name] = s_value; | ||||||
|  |           $.ajax({ | ||||||
|  |               url: "/admins/tag_disciplines/" + s_id, | ||||||
|  |               type: "PUT", | ||||||
|  |               dataType:'script', | ||||||
|  |               data: json | ||||||
|  |           }); | ||||||
|  |       }); | ||||||
|  |   } | ||||||
|  | }); | ||||||
| @ -0,0 +1,49 @@ | |||||||
|  | class Admins::DisciplinesController < Admins::BaseController | ||||||
|  | 
 | ||||||
|  |   def index | ||||||
|  |     @disciplines = Discipline.all | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def create | ||||||
|  |     name = params[:name].to_s.strip | ||||||
|  |     return render_error('名称重复') if Discipline.where(name: name).exists? | ||||||
|  |     Discipline.create!(name: name) | ||||||
|  |     render_ok | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def edit | ||||||
|  |     @discipline = current_discipline | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def update | ||||||
|  |     if params[:discipline] && params[:discipline][:name].present? | ||||||
|  |       name = params[:discipline][:name].to_s.strip | ||||||
|  |       current_discipline.update_attributes!(name: name) | ||||||
|  |     else | ||||||
|  |       ActiveRecord::Base.transaction do | ||||||
|  |         current_discipline.update_attributes!(setting_params) | ||||||
|  |         current_discipline.sub_disciplines.each do |sub| | ||||||
|  |           sub.tag_disciplines.each do |tag| | ||||||
|  |             tag.update_attributes!(setting_params) | ||||||
|  |           end | ||||||
|  |           sub.update_attributes!(setting_params) | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     @disciplines = Discipline.all | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def destroy | ||||||
|  |     @discipline_id = params[:id] | ||||||
|  |     current_discipline.destroy! | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  |   def current_discipline | ||||||
|  |     @_current_discipline = Discipline.find params[:id] | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def setting_params | ||||||
|  |     params.permit(:shixun, :subject, :question) | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,10 @@ | |||||||
|  | class Admins::ImportDisciplinesController < Admins::BaseController | ||||||
|  |   def create | ||||||
|  |     return render_error('请上传正确的文件') if params[:file].blank? || !params[:file].is_a?(ActionDispatch::Http::UploadedFile) | ||||||
|  | 
 | ||||||
|  |     result = Admins::ImportDisciplineService.call(params[:file].to_io) | ||||||
|  |     render_ok(result) | ||||||
|  |   rescue Admins::ImportDisciplineService::Error => ex | ||||||
|  |     render_error(ex) | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,52 @@ | |||||||
|  | class Admins::SubDisciplinesController < Admins::BaseController | ||||||
|  | 
 | ||||||
|  |   def index | ||||||
|  |     @discipline = current_discipline | ||||||
|  |     @sub_disciplines = current_discipline.sub_disciplines | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def create | ||||||
|  |     name = params[:name].to_s.strip | ||||||
|  |     return render_error('名称重复') if current_discipline.sub_disciplines.where(name: name).exists? | ||||||
|  |     SubDiscipline.create!(name: name, discipline_id: current_discipline.id) | ||||||
|  |     render_ok | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def edit | ||||||
|  |     @sub_discipline = current_sub_discipline | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def update | ||||||
|  |     if params[:sub_discipline] && params[:sub_discipline][:name].present? | ||||||
|  |       name = params[:sub_discipline][:name].to_s.strip | ||||||
|  |       current_sub_discipline.update_attributes!(name: name) | ||||||
|  |     else | ||||||
|  |       ActiveRecord::Base.transaction do | ||||||
|  |         current_sub_discipline.update_attributes!(setting_params) | ||||||
|  |         current_sub_discipline.tag_disciplines.each do |tag| | ||||||
|  |           tag.update_attributes!(setting_params) | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     @sub_disciplines = current_sub_discipline.discipline&.sub_disciplines | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def destroy | ||||||
|  |     @sub_discipline_id = params[:id] | ||||||
|  |     current_sub_discipline.destroy! | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  | 
 | ||||||
|  |   def current_sub_discipline | ||||||
|  |     @_current_sub_discipline = SubDiscipline.find params[:id] | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def current_discipline | ||||||
|  |     @_current_discipline = Discipline.find params[:discipline_id] | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def setting_params | ||||||
|  |     params.permit(:shixun, :subject, :question) | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,47 @@ | |||||||
|  | class Admins::TagDisciplinesController < Admins::BaseController | ||||||
|  | 
 | ||||||
|  |   def index | ||||||
|  |     @sub_discipline = current_sub_discipline | ||||||
|  |     @tag_disciplines = current_sub_discipline.tag_disciplines | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def create | ||||||
|  |     name = params[:name].to_s.strip | ||||||
|  |     return render_error('名称重复') if current_sub_discipline.tag_disciplines.where(name: name).exists? | ||||||
|  |     TagDiscipline.create!(name: name, sub_discipline_id: current_sub_discipline.id, user_id: current_user.id) | ||||||
|  |     render_ok | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def edit | ||||||
|  |     @tag_discipline = current_tag_discipline | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def update | ||||||
|  |     if params[:tag_discipline] && params[:tag_discipline][:name].present? | ||||||
|  |       name = params[:tag_discipline][:name].to_s.strip | ||||||
|  |       current_tag_discipline.update_attributes!(name: name) | ||||||
|  |     else | ||||||
|  |       current_tag_discipline.update_attributes!(setting_params) | ||||||
|  |     end | ||||||
|  |     @tag_disciplines = current_tag_discipline.sub_discipline&.tag_disciplines | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def destroy | ||||||
|  |     @tag_discipline_id = params[:id] | ||||||
|  |     current_tag_discipline.destroy! | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  | 
 | ||||||
|  |   def current_sub_discipline | ||||||
|  |     @_current_sub_discipline = SubDiscipline.find params[:sub_discipline_id] | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def current_tag_discipline | ||||||
|  |     @_current_tag_discipline = TagDiscipline.find params[:id] | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def setting_params | ||||||
|  |     params.permit(:shixun, :subject, :question) | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,6 @@ | |||||||
|  | class DisciplinesController < ApplicationController | ||||||
|  | 
 | ||||||
|  |   def index | ||||||
|  | 
 | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,77 @@ | |||||||
|  | class ExaminationBanksController < ApplicationController | ||||||
|  |   include PaginateHelper | ||||||
|  |   before_action :require_login | ||||||
|  |   before_action :find_exam, except: [:index, :create] | ||||||
|  |   before_action :edit_auth, only: [:update, :destroy, :set_public] | ||||||
|  | 
 | ||||||
|  |   def index | ||||||
|  |     exams = ExaminationBankQuery.call(params) | ||||||
|  |     @exams_count = exams.size | ||||||
|  |     @exams = paginate exams.includes(:user, :examination_items) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def show | ||||||
|  | 
 | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def create | ||||||
|  |     ActiveRecord::Base.transaction do | ||||||
|  |       exam = ExaminationBank.new(user: current_user) | ||||||
|  |       # 保存试卷基础信息 | ||||||
|  |       exam = ExaminationBanks::SaveExaminationBankService.call(exam, form_params) | ||||||
|  | 
 | ||||||
|  |       # 将试题篮中的试题发送到试卷,试卷的题目与试题独立 | ||||||
|  |       current_user.item_baskets.includes(:item_bank).each do |basket| | ||||||
|  |         item = basket.item_bank | ||||||
|  |         if item.present? | ||||||
|  |           new_item = ExaminationItem.new(examination_bank: exam, item_bank: item, name: item.name, item_type: item.item_type, | ||||||
|  |                                          difficulty: item.difficulty, score: basket.score, position: basket.position) | ||||||
|  |           if new_item.save! | ||||||
|  |             item.increment!(:quotes) | ||||||
|  |             if item.item_choices.present? | ||||||
|  |               item.item_choices.each do |choice| | ||||||
|  |                 new_item.examination_item_choices << ExaminationItemChoice.new(choice_text: choice.choice_text, is_answer: choice.is_answer) | ||||||
|  |               end | ||||||
|  |             end | ||||||
|  |           end | ||||||
|  |         end | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       current_user.item_baskets.destroy_all | ||||||
|  |     end | ||||||
|  |     render_ok | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def edit | ||||||
|  | 
 | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def update | ||||||
|  | 
 | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def destroy | ||||||
|  |     @exam.destroy! | ||||||
|  |     render_ok | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def set_public | ||||||
|  |     tip_exception(-1, "该试卷已公开") if @exam.public? | ||||||
|  |     @exam.update_attributes!(public: 1) | ||||||
|  |     render_ok | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  | 
 | ||||||
|  |   def form_params | ||||||
|  |     params.permit(:discipline_id, :sub_discipline_id, :difficulty, :name, :duration, tag_discipline_id: []) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def find_exam | ||||||
|  |     @exam = ExaminationBank.find_by!(id: params[:id]) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def edit_auth | ||||||
|  |     current_user.admin_or_business? || @exam.user == current_user | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -1,14 +1,58 @@ | |||||||
| class LibrariesController < ApplicationController | class ItemBanksController < ApplicationController | ||||||
|   include PaginateHelper |   include PaginateHelper | ||||||
|  |   before_action :require_login | ||||||
|  |   before_action :find_item, except: [:index, :create] | ||||||
|  |   before_action :edit_auth, only: [:update, :destroy, :set_public] | ||||||
| 
 | 
 | ||||||
|   def index |   def index | ||||||
|     default_sort('updated_at', 'desc') |     items = ItemBankQuery.call(params) | ||||||
| 
 |     @items_count = items.size | ||||||
|     @items = ItemBankQuery.call(params) |     @items = paginate items.includes(:item_analysis, :user) | ||||||
|     @items = paginate courses.includes(:school, :students, :attachments, :homework_commons, teacher: :user_extension) |     @item_basket_ids = current_user.item_baskets.pluck(:item_bank_id) | ||||||
|   end |   end | ||||||
| 
 | 
 | ||||||
|   def create |   def create | ||||||
|  |     item = ItemBank.new(user: current_user) | ||||||
|  |     ItemBanks::SaveItemService.call(item, form_params) | ||||||
|  |     render_ok | ||||||
|  |   rescue ApplicationService::Error => ex | ||||||
|  |     render_error(ex.message) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def edit | ||||||
|  | 
 | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def update | ||||||
|  |     ItemBanks::SaveItemService.call(@item, form_params) | ||||||
|  |     render_ok | ||||||
|  |   rescue ApplicationService::Error => ex | ||||||
|  |     render_error(ex.message) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def destroy | ||||||
|  |     @item.destroy! | ||||||
|  |     render_ok | ||||||
|  |   end | ||||||
| 
 | 
 | ||||||
|  |   def set_public | ||||||
|  |     tip_exception(-1, "该试题已公开") if @item.public? | ||||||
|  |     @item.update_attributes!(public: 1) | ||||||
|  |     render_ok | ||||||
|   end |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  | 
 | ||||||
|  |   def find_item | ||||||
|  |     @item = ItemBank.find_by!(id: params[:id]) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def edit_auth | ||||||
|  |     current_user.admin_or_business? || @item.user == current_user | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def form_params | ||||||
|  |     params.permit(:discipline_id, :sub_discipline_id, :item_type, :difficulty, :name, :analysis, tag_discipline_id: [], choices: %i[choice_text is_answer]) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
| end | end | ||||||
| @ -0,0 +1,90 @@ | |||||||
|  | class ItemBasketsController < ApplicationController | ||||||
|  |   before_action :require_login | ||||||
|  |   before_action :validate_score, only: [:set_score, :batch_set_score] | ||||||
|  |   helper_method :current_basket | ||||||
|  | 
 | ||||||
|  |   def index | ||||||
|  |     @item_baskets = current_user.item_baskets | ||||||
|  |     @single_questions = @item_baskets.where(item_type: "SINGLE") | ||||||
|  |     @multiple_questions = @item_baskets.where(item_type: "MULTIPLE") | ||||||
|  |     @judgement_questions = @item_baskets.where(item_type: "JUDGMENT") | ||||||
|  |     @program_questions = @item_baskets.where(item_type: "PROGRAM") | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def basket_list | ||||||
|  |     @single_questions_count = current_user.item_baskets.where(item_type: "SINGLE").count | ||||||
|  |     @multiple_questions_count = current_user.item_baskets.where(item_type: "MULTIPLE").count | ||||||
|  |     @judgement_questions_count = current_user.item_baskets.where(item_type: "JUDGMENT").count | ||||||
|  |     @completion_questions_count = current_user.item_baskets.where(item_type: "COMPLETION").count | ||||||
|  |     @subjective_questions_count = current_user.item_baskets.where(item_type: "SUBJECTIVE").count | ||||||
|  |     @practical_questions_count = current_user.item_baskets.where(item_type: "PRACTICAL").count | ||||||
|  |     @program_questions_count = current_user.item_baskets.where(item_type: "PROGRAM").count | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def create | ||||||
|  |     ItemBaskets::SaveItemBasketService.call(current_user, create_params) | ||||||
|  |     render_ok | ||||||
|  |   rescue ApplicationService::Error => ex | ||||||
|  |     render_error(ex.message) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def destroy | ||||||
|  |     item = current_user.item_baskets.find_by!(item_bank_id: params[:id]) | ||||||
|  |     ActiveRecord::Base.transaction do | ||||||
|  |       current_user.item_baskets.where(item_type: item.item_type).where("position > #{item.position}").update_all("position = position -1") | ||||||
|  |       item.destroy! | ||||||
|  |     end | ||||||
|  |     render_ok | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def delete_item_type | ||||||
|  |     baskets = ItemBasket.where(item_type: params[:item_type]) | ||||||
|  |     baskets.destroy_all | ||||||
|  |     render_ok | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def set_score | ||||||
|  |     current_basket.update_attributes!(score: params[:score]) | ||||||
|  |     @questions_score = current_user.item_baskets.where(item_type: current_basket.item_type).pluck(:score).sum | ||||||
|  |     @all_score = current_user.item_baskets.pluck(:score).sum | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def batch_set_score | ||||||
|  |     current_user.item_baskets.where(item_type: params[:item_type]).update_all(score: params[:score]) | ||||||
|  |     @questions_score = current_user.item_baskets.where(item_type: params[:item_type]).pluck(:score).sum | ||||||
|  |     @all_score = current_user.item_baskets.pluck(:score).sum | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def adjust_position | ||||||
|  |     same_items = current_user.item_baskets.where(item_type: current_basket.item_type) | ||||||
|  |     max_position = same_items.size | ||||||
|  |     tip_exception("position超出范围") unless params[:position].present? && params[:position].to_i <= max_position && params[:position].to_i >= 1 | ||||||
|  |     ActiveRecord::Base.transaction do | ||||||
|  |       if params[:position].to_i > current_basket.position | ||||||
|  |         same_items.where("position > #{current_basket.position} and position <= #{params[:position].to_i}").update_all("position=position-1") | ||||||
|  |         current_basket.update_attributes!(position: params[:position]) | ||||||
|  |       elsif params[:position].to_i < current_basket.position | ||||||
|  |         same_items.where("position < #{current_basket.position} and position >= #{params[:position].to_i}").update_all("position=position+1") | ||||||
|  |         current_basket.update_attributes!(position: params[:position]) | ||||||
|  |       else | ||||||
|  |         return normal_status(-1, "排序无变化") | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     render_ok | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  | 
 | ||||||
|  |   def create_params | ||||||
|  |     params.permit(item_ids: []) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def current_basket | ||||||
|  |     @_current_basket = current_user.item_baskets.find_by!(id: params[:id]) | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def validate_score | ||||||
|  |     tip_exception("分值不能为空") unless params[:score].present? | ||||||
|  |     tip_exception("分值需大于0") unless params[:score].to_f > 0 | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | class ExaminationBanks::SaveExamForm | ||||||
|  |   include ActiveModel::Model | ||||||
|  | 
 | ||||||
|  |   attr_accessor :discipline_id, :sub_discipline_id, :difficulty, :name, :duration, :tag_discipline_id | ||||||
|  | 
 | ||||||
|  |   validates :discipline_id, presence: true | ||||||
|  |   validates :sub_discipline_id, presence: true | ||||||
|  |   validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true } | ||||||
|  |   validates :name, presence: true, length: { maximum: 60 } | ||||||
|  |   validate :validate_duration | ||||||
|  | 
 | ||||||
|  |   def validate_duration | ||||||
|  |     raise '时长应为大于0的整数' if duration.present? && duration.to_i < 1 | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | class ItemBanks::SaveItemForm | ||||||
|  |   include ActiveModel::Model | ||||||
|  | 
 | ||||||
|  |   attr_accessor :discipline_id, :sub_discipline_id, :item_type, :difficulty, :name, :analysis, :tag_discipline_id, :choices | ||||||
|  | 
 | ||||||
|  |   validates :discipline_id, presence: true | ||||||
|  |   validates :sub_discipline_id, presence: true | ||||||
|  |   validates :item_type, presence: true, inclusion: {in: %W(SINGLE MULTIPLE JUDGMENT COMPLETION SUBJECTIVE PRACTICAL PROGRAM)} | ||||||
|  |   validates :difficulty, presence: true, inclusion: {in: 1..3}, numericality: { only_integer: true } | ||||||
|  |   validates :name, presence: true, length: { maximum: 1000 } | ||||||
|  |   validates :analysis, length: { maximum: 1000 } | ||||||
|  | 
 | ||||||
|  |   def validate! | ||||||
|  |     super | ||||||
|  |     return unless errors.blank? | ||||||
|  |     choices.each { |item| SubForm.new(item).validate! } if  %W(SINGLE MULTIPLE JUDGMENT).include?(item_type) | ||||||
|  |     return unless errors.blank? | ||||||
|  |     if [0, 2].include?(item_type) && choices.pluck(:is_answer).select{|item| item == 1}.length > 1 | ||||||
|  |       raise("正确答案只能有一个") | ||||||
|  |     elsif item_type == 1 && choices.pluck(:is_answer).select{|item| item == 1}.length <= 1 | ||||||
|  |       raise("多选题至少有两个正确答案") | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   class SubForm | ||||||
|  |     include ActiveModel::Model | ||||||
|  | 
 | ||||||
|  |     attr_accessor :choice_text, :is_answer | ||||||
|  | 
 | ||||||
|  |     validates :choice_text, presence: true, length: { maximum: 100 } | ||||||
|  |     validates :is_answer, presence: true, inclusion: {in: 0..1}, numericality: { only_integer: true } | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,16 @@ | |||||||
|  | class Admins::ImportDisciplineExcel < BaseImportXlsx | ||||||
|  |   DisciplineData = Struct.new(:discipline_name, :sub_discipline_name) | ||||||
|  | 
 | ||||||
|  |   def read_each(&block) | ||||||
|  |     sheet.each_row_streaming(pad_cells: true, offset: 2) do |row| | ||||||
|  |       data = row.map(&method(:cell_value))[1..2] | ||||||
|  |       block.call DisciplineData.new(*data) | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  | 
 | ||||||
|  |   def cell_value(obj) | ||||||
|  |     obj&.cell_value | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | class Discipline < ApplicationRecord | ||||||
|  |   has_many :sub_disciplines, dependent: :destroy | ||||||
|  | 
 | ||||||
|  |   has_many :shixun_sub_disciplines, -> { where("shixun = 1") }, class_name: "SubDiscipline" | ||||||
|  |   has_many :subject_sub_disciplines, -> { where("subject = 1") }, class_name: "SubDiscipline" | ||||||
|  |   has_many :question_sub_disciplines, -> { where("question = 1") }, class_name: "SubDiscipline" | ||||||
|  | end | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | class ExaminationBank < ApplicationRecord | ||||||
|  |   belongs_to :user | ||||||
|  |   belongs_to :sub_discipline | ||||||
|  | 
 | ||||||
|  |   has_many :tag_discipline_containers, as: :container, dependent: :destroy | ||||||
|  |   has_many :tag_disciplines, through: :tag_discipline_containers | ||||||
|  | 
 | ||||||
|  |   has_many :examination_items, dependent: :destroy | ||||||
|  | 
 | ||||||
|  |   def question_count | ||||||
|  |     examination_items.size | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def total_score | ||||||
|  |     examination_items.pluck(:score).sum | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,6 @@ | |||||||
|  | class ExaminationItem < ApplicationRecord | ||||||
|  |   belongs_to :examination_bank, touch: true | ||||||
|  |   belongs_to :item_bank, optional: true | ||||||
|  | 
 | ||||||
|  |   has_many :examination_item_choices, dependent: :destroy | ||||||
|  | end | ||||||
| @ -0,0 +1,3 @@ | |||||||
|  | class ExaminationItemChoice < ApplicationRecord | ||||||
|  |   belongs_to :examination_item | ||||||
|  | end | ||||||
| @ -1,11 +1,18 @@ | |||||||
| class ItemBank < ApplicationRecord | class ItemBank < ApplicationRecord | ||||||
|   # difficulty:  1 简单  2 适中  3 困难 |   # difficulty:  1 简单  2 适中  3 困难 | ||||||
|   # item_type:  0 单选  1 多选  2 判断  3 填空  4 简答  5 实训 6 编程 |  | ||||||
|   enum item_type: { SINGLE: 0, MULTIPLE: 1, JUDGMENT: 2, COMPLETION: 3, SUBJECTIVE: 4, PRACTICAL: 5, PROGRAM: 6 } |   enum item_type: { SINGLE: 0, MULTIPLE: 1, JUDGMENT: 2, COMPLETION: 3, SUBJECTIVE: 4, PRACTICAL: 5, PROGRAM: 6 } | ||||||
|  |   # item_type:  0 单选  1 多选  2 判断  3 填空  4 简答  5 实训 6 编程 | ||||||
| 
 | 
 | ||||||
|   belongs_to :user |   belongs_to :user | ||||||
|  |   belongs_to :sub_discipline | ||||||
| 
 | 
 | ||||||
|   has_one :item_analysis, dependent: :destroy |   has_one :item_analysis, dependent: :destroy | ||||||
|   has_many :item_choices, dependent: :destroy |   has_many :item_choices, dependent: :destroy | ||||||
|   has_many :item_baskets, dependent: :destroy |   has_many :item_baskets, dependent: :destroy | ||||||
|  |   has_many :tag_discipline_containers, as: :container, dependent: :destroy | ||||||
|  |   has_many :tag_disciplines, through: :tag_discipline_containers | ||||||
|  | 
 | ||||||
|  |   def analysis | ||||||
|  |     item_analysis&.analysis | ||||||
|  |   end | ||||||
| end | end | ||||||
|  | |||||||
| @ -1,4 +1,14 @@ | |||||||
| class ItemBasket < ApplicationRecord | class ItemBasket < ApplicationRecord | ||||||
|  |   enum item_type: { SINGLE: 0, MULTIPLE: 1, JUDGMENT: 2, COMPLETION: 3, SUBJECTIVE: 4, PRACTICAL: 5, PROGRAM: 6 } | ||||||
|  | 
 | ||||||
|   belongs_to :item_bank |   belongs_to :item_bank | ||||||
|   belongs_to :user |   belongs_to :user | ||||||
|  | 
 | ||||||
|  |   def all_score | ||||||
|  |     User.current.item_baskets.map(&:score).sum | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def question_count | ||||||
|  |     User.current.item_baskets.size | ||||||
|  |   end | ||||||
| end | end | ||||||
|  | |||||||
| @ -0,0 +1,9 @@ | |||||||
|  | class SubDiscipline < ApplicationRecord | ||||||
|  |   belongs_to :discipline | ||||||
|  |   has_many :tag_disciplines, dependent: :destroy | ||||||
|  |   has_one :hack | ||||||
|  | 
 | ||||||
|  |   has_many :shixun_tag_disciplines, -> { where("shixun = 1") }, class_name: "TagDiscipline" | ||||||
|  |   has_many :subject_tag_disciplines, -> { where("subject = 1") }, class_name: "TagDiscipline" | ||||||
|  |   has_many :question_tag_disciplines, -> { where("question = 1") }, class_name: "TagDiscipline" | ||||||
|  | end | ||||||
| @ -0,0 +1,9 @@ | |||||||
|  | class TagDiscipline < ApplicationRecord | ||||||
|  |   belongs_to :sub_discipline | ||||||
|  |   belongs_to :user | ||||||
|  |   has_many :tag_discipline_containers, dependent: :destroy | ||||||
|  | 
 | ||||||
|  |   def discipline | ||||||
|  |     sub_discipline&.discipline | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,5 @@ | |||||||
|  | class TagDisciplineContainer < ApplicationRecord | ||||||
|  |   belongs_to :tag_discipline | ||||||
|  | 
 | ||||||
|  |   belongs_to :container, polymorphic: true, optional: true | ||||||
|  | end | ||||||
| @ -0,0 +1,32 @@ | |||||||
|  | class ExaminationBankQuery < ApplicationQuery | ||||||
|  |   include CustomSortable | ||||||
|  |   attr_reader :params | ||||||
|  | 
 | ||||||
|  |   sort_columns :updated_at, default_by: :updated_at, default_direction: :desc, default_table: 'examination_banks' | ||||||
|  | 
 | ||||||
|  |   def initialize(params) | ||||||
|  |     @params = params | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def call | ||||||
|  |     if params[:public].to_i == 1 | ||||||
|  |       exams = ExaminationBank.where(public: 1) | ||||||
|  |     elsif params[:public].to_i == 0 | ||||||
|  |       exams = ExaminationBank.where(user_id: User.current.id) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     if params[:tag_discipline_id].present? | ||||||
|  |       exams = exams.joins(:tag_discipline_containers).where(tag_discipline_containers: {tag_discipline_id: params[:tag_discipline_id]}) | ||||||
|  |     elsif params[:sub_discipline_id].present? | ||||||
|  |       exams = exams.where(sub_discipline_id: params[:sub_discipline_id]) | ||||||
|  |     elsif params[:discipline_id].present? | ||||||
|  |       exams = exams.joins(:sub_discipline).where(sub_disciplines: {discipline_id: params[:discipline_id]}) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     exams = exams.where(difficulty: params[:difficulty].to_i) if params[:difficulty].present? | ||||||
|  | 
 | ||||||
|  |     exams = exams.where("name like ?", "%#{params[:keyword].strip}%") if params[:keyword].present? | ||||||
|  | 
 | ||||||
|  |     custom_sort(exams, params[:sort_by], params[:sort_direction]) | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | class ItemBankQuery < ApplicationQuery | ||||||
|  |   include CustomSortable | ||||||
|  |   attr_reader :params | ||||||
|  | 
 | ||||||
|  |   sort_columns :updated_at, default_by: :updated_at, default_direction: :desc, default_table: 'item_banks' | ||||||
|  | 
 | ||||||
|  |   def initialize(params) | ||||||
|  |     @params = params | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def call | ||||||
|  |     if params[:public].to_i == 1 | ||||||
|  |       items = ItemBank.where(public: 1) | ||||||
|  |     elsif params[:public].to_i == 0 | ||||||
|  |       items = ItemBank.where(user_id: User.current.id) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     if params[:tag_discipline_id].present? | ||||||
|  |       items = items.joins(:tag_discipline_containers).where(tag_discipline_containers: {tag_discipline_id: params[:tag_discipline_id]}) | ||||||
|  |     elsif params[:sub_discipline_id].present? | ||||||
|  |       items = items.where(sub_discipline_id: params[:sub_discipline_id]) | ||||||
|  |     elsif params[:discipline_id].present? | ||||||
|  |       items = items.joins(:sub_discipline).where(sub_disciplines: {discipline_id: params[:discipline_id]}) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     items = items.where(item_type: params[:item_type].to_i) if params[:item_type].present? | ||||||
|  |     items = items.where(difficulty: params[:difficulty].to_i) if params[:difficulty].present? | ||||||
|  | 
 | ||||||
|  |     items = items.where("name like ?", "%#{params[:keyword].strip}%") if params[:keyword].present? | ||||||
|  | 
 | ||||||
|  |     custom_sort(items, params[:sort_by], params[:sort_direction]) | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,52 @@ | |||||||
|  | class Admins::ImportDisciplineService < ApplicationService | ||||||
|  |   Error = Class.new(StandardError) | ||||||
|  | 
 | ||||||
|  |   attr_reader :file, :result | ||||||
|  | 
 | ||||||
|  |   def initialize(file) | ||||||
|  |     @file   = file | ||||||
|  |     @result = { success: 0, fail: [] } | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def call | ||||||
|  |     raise Error, '文件不存在' if file.blank? | ||||||
|  | 
 | ||||||
|  |     excel = Admins::ImportDisciplineExcel.new(file) | ||||||
|  |     excel.read_each(&method(:save_discipline)) | ||||||
|  | 
 | ||||||
|  |     result | ||||||
|  |   rescue ApplicationImport::Error => ex | ||||||
|  |     raise Error, ex.message | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  | 
 | ||||||
|  |   def save_discipline(data) | ||||||
|  |     count = 0 | ||||||
|  |     discipline_name = data.discipline_name.to_s.strip | ||||||
|  |     sub_discipline_name = data.sub_discipline_name.to_s.strip | ||||||
|  | 
 | ||||||
|  |     return unless discipline_name.present? | ||||||
|  |     discipline = Discipline.find_by(name: discipline_name) | ||||||
|  |     if discipline.blank? | ||||||
|  |       discipline = Discipline.create!(name: discipline_name) | ||||||
|  |       count += 1 | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     if sub_discipline_name.present? | ||||||
|  |       sub_discipline = SubDiscipline.find_by(name: discipline_name, discipline: discipline) | ||||||
|  |       if sub_discipline.blank? | ||||||
|  |         SubDiscipline.create!(name: sub_discipline_name, discipline: discipline) | ||||||
|  |         count += 1 | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     result[:success] += count | ||||||
|  |   rescue Exception => ex | ||||||
|  |     fail_data = data.as_json | ||||||
|  |     fail_data[:data] = fail_data.values.join(',') | ||||||
|  |     fail_data[:message] = ex.message | ||||||
|  | 
 | ||||||
|  |     result[:fail] << fail_data | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,30 @@ | |||||||
|  | class ExaminationBanks::SaveExaminationBankService < ApplicationService | ||||||
|  |   attr_reader :exam, :params | ||||||
|  | 
 | ||||||
|  |   def initialize(exam, params) | ||||||
|  |     @exam = exam | ||||||
|  |     @params = params | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def call | ||||||
|  |     ExaminationBanks::SaveExamForm.new(params).validate! | ||||||
|  | 
 | ||||||
|  |     exam.name = params[:name].to_s.strip | ||||||
|  |     exam.difficulty = params[:difficulty] | ||||||
|  |     exam.duration = params[:duration].present? ? params[:duration].to_i : nil | ||||||
|  |     exam.sub_discipline_id = params[:sub_discipline_id] | ||||||
|  |     exam.save! | ||||||
|  | 
 | ||||||
|  |     # 知识点的创建 | ||||||
|  |     new_tag_discipline_ids = params[:tag_discipline_id] || [] | ||||||
|  |     old_tag_discipline_ids = exam.tag_discipline_containers.pluck(:tag_discipline_id) | ||||||
|  |     delete_tag_discipline_ids = old_tag_discipline_ids - new_tag_discipline_ids | ||||||
|  |     create_tag_discipline_ids = new_tag_discipline_ids - old_tag_discipline_ids | ||||||
|  |     exam.tag_discipline_containers.where(tag_discipline_id: delete_tag_discipline_ids).destroy_all | ||||||
|  |     create_tag_discipline_ids.each do |tag_id| | ||||||
|  |       exam.tag_discipline_containers << TagDisciplineContainer.new(tag_discipline_id: tag_id) | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     exam | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,58 @@ | |||||||
|  | class ItemBanks::SaveItemService < ApplicationService | ||||||
|  |   attr_reader :item, :params | ||||||
|  | 
 | ||||||
|  |   def initialize(item, params) | ||||||
|  |     @item = item | ||||||
|  |     @params = params | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def call | ||||||
|  |     new_record = item.new_record? | ||||||
|  |     raise("不能更改题型") if !new_record && item.item_type != params[:item_type] | ||||||
|  |     ItemBanks::SaveItemForm.new(params).validate! | ||||||
|  | 
 | ||||||
|  |     ActiveRecord::Base.transaction do | ||||||
|  |       item.item_type = params[:item_type] if new_record | ||||||
|  |       item.difficulty = params[:difficulty] | ||||||
|  |       item.sub_discipline_id = params[:sub_discipline_id] | ||||||
|  |       item.name = params[:name].to_s.strip | ||||||
|  |       item.save! | ||||||
|  | 
 | ||||||
|  |       analysis = item.item_analysis || ItemAnalysis.new(item_bank_id: item.id) | ||||||
|  |       analysis.analysis = params[:analysis].blank? ? nil : params[:analysis].strip | ||||||
|  |       analysis.save | ||||||
|  | 
 | ||||||
|  |       # 知识点的创建 | ||||||
|  |       new_tag_discipline_ids = params[:tag_discipline_id] | ||||||
|  |       old_tag_discipline_ids = item.tag_discipline_containers.pluck(:tag_discipline_id) | ||||||
|  |       delete_tag_discipline_ids = old_tag_discipline_ids - new_tag_discipline_ids | ||||||
|  |       create_tag_discipline_ids = new_tag_discipline_ids - old_tag_discipline_ids | ||||||
|  |       item.tag_discipline_containers.where(tag_discipline_id: delete_tag_discipline_ids).destroy_all | ||||||
|  |       create_tag_discipline_ids.each do |tag_id| | ||||||
|  |         item.tag_discipline_containers << TagDisciplineContainer.new(tag_discipline_id: tag_id) | ||||||
|  |       end | ||||||
|  | 
 | ||||||
|  |       # 选项的创建 | ||||||
|  |       if %W(SINGLE MULTIPLE JUDGMENT).include?(item.item_type) | ||||||
|  |         old_choices = item.item_choices | ||||||
|  |         new_choices = params[:choices] | ||||||
|  | 
 | ||||||
|  |         new_choices.each_with_index do |choice, index| | ||||||
|  |           choice_item = old_choices[index] || ItemChoice.new(item_bank_id: item.id) | ||||||
|  |           choice_item.choice_text = choice[:choice_text] | ||||||
|  |           choice_item.is_answer = choice[:is_answer] | ||||||
|  |           choice_item.save! | ||||||
|  |         end | ||||||
|  | 
 | ||||||
|  |         if old_choices.length > new_choices.length | ||||||
|  |           old_choices[new_choices.length..(old_choices.length-1)].each do |old_choice| | ||||||
|  |             old_choice.destroy | ||||||
|  |           end | ||||||
|  |         end | ||||||
|  | 
 | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     item | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,47 @@ | |||||||
|  | class ItemBaskets::SaveItemBasketService < ApplicationService | ||||||
|  |   attr_reader :user, :params | ||||||
|  | 
 | ||||||
|  |   def initialize(user, params) | ||||||
|  |     @user = user | ||||||
|  |     @params = params | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def call | ||||||
|  |     raise("请选择试题") if params[:item_ids].blank? | ||||||
|  | 
 | ||||||
|  |     # 只能选用公共题库或是自己的题库 | ||||||
|  |     items = ItemBank.where(public: 1).or(ItemBank.where(user_id: user.id)) | ||||||
|  | 
 | ||||||
|  |     # 已选到过试题篮的不重复选用 | ||||||
|  |     item_ids = params[:item_ids] - user.item_baskets.pluck(:item_bank_id) | ||||||
|  |     items.where(id: item_ids).each do |item| | ||||||
|  |       new_item = ItemBasket.new(user_id: user.id, item_bank_id: item.id, item_type: item.item_type) | ||||||
|  |       new_item.score = item_score item.item_type | ||||||
|  |       new_item.position = item_position item.item_type | ||||||
|  |       new_item.save! | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   private | ||||||
|  | 
 | ||||||
|  |   def item_score item_type | ||||||
|  |     if user.item_baskets.where(item_type: item_type).last.present? | ||||||
|  |       score = user.item_baskets.where(item_type: item_type).last.score | ||||||
|  |     else | ||||||
|  |       score = | ||||||
|  |         case item_type | ||||||
|  |         when 0, 1, 2 | ||||||
|  |           5 | ||||||
|  |         when 6 | ||||||
|  |           10 | ||||||
|  |         else | ||||||
|  |           5 | ||||||
|  |         end | ||||||
|  |     end | ||||||
|  |     score | ||||||
|  |   end | ||||||
|  | 
 | ||||||
|  |   def item_position item_type | ||||||
|  |     user.item_baskets.where(item_type: item_type).last&.position.to_i + 1 | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,2 @@ | |||||||
|  | $.notify({ message: '删除成功' }); | ||||||
|  | $(".discipline-item-<%= @discipline_id %>").remove(); | ||||||
| @ -0,0 +1,2 @@ | |||||||
|  | $('.admin-modal-container').html("<%= j( render partial: 'admins/disciplines/shared/edit_discipline_modal', locals: { discipline: @discipline } ) %>"); | ||||||
|  | $('.modal.admin-edit-discipline-modal').modal('show'); | ||||||
| @ -0,0 +1,17 @@ | |||||||
|  | <% define_admin_breadcrumbs do %> | ||||||
|  |   <% add_admin_breadcrumb('课程方向', admins_disciplines_path) %> | ||||||
|  | <% end %> | ||||||
|  | 
 | ||||||
|  | <div class="box search-form-container discipline-list-form rig"> | ||||||
|  |   <div class="flex-1"> | ||||||
|  |     <%= javascript_void_link '新增', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-discipline-modal' } %> | ||||||
|  |   </div> | ||||||
|  |   <%= javascript_void_link '导入数据', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-import-discipline-modal'} %> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <div class="box admin-list-container discipline-list-container"> | ||||||
|  |   <%= render(partial: 'admins/disciplines/shared/list') %> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <%= render 'admins/disciplines/shared/create_discipline_modal' %> | ||||||
|  | <%= render partial: 'admins/disciplines/shared/import_discipline_modal' %> | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | <div class="modal fade admin-create-discipline-modal" tabindex="-1" role="dialog" aria-hidden="true"> | ||||||
|  |   <div class="modal-dialog modal-dialog-centered" role="document"> | ||||||
|  |     <div class="modal-content"> | ||||||
|  |       <div class="modal-header"> | ||||||
|  |         <h5 class="modal-title">新建课程方向</h5> | ||||||
|  |         <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||||
|  |           <span aria-hidden="true">×</span> | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-body"> | ||||||
|  |         <form class="admin-create-discipline-form" data-url="<%= admins_disciplines_path %>"> | ||||||
|  |           <div class="form-group d-flex"> | ||||||
|  |             <label for="new_mirror_id" class="col-form-label">名称:</label> | ||||||
|  |             <div class="w-75 d-flex flex-column"> | ||||||
|  |               <%= text_field_tag(:name, nil, class: 'form-control', placeholder: '请输入名称') %> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  | 
 | ||||||
|  |           <div class="error text-danger"></div> | ||||||
|  |         </form> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-footer"> | ||||||
|  |         <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> | ||||||
|  |         <button type="button" class="btn btn-primary submit-btn">确认</button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
| @ -0,0 +1,23 @@ | |||||||
|  | <div class="modal fade admin-edit-discipline-modal" tabindex="-1" role="dialog" aria-hidden="true"> | ||||||
|  |   <div class="modal-dialog modal-dialog-centered" role="document"> | ||||||
|  |     <div class="modal-content"> | ||||||
|  |       <div class="modal-header"> | ||||||
|  |         <h5 class="modal-title">编辑课程方向</h5> | ||||||
|  |         <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||||
|  |           <span aria-hidden="true">×</span> | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-body"> | ||||||
|  |         <%= simple_form_for([:admins, discipline], html: { class: 'admin-edit-discipline-form' }, defaults: { wrapper_html: { class: 'offset-md-1 col-md-10' } }) do |f| %> | ||||||
|  |           <%= f.input :name, as: :string, label: '名称' %> | ||||||
|  | 
 | ||||||
|  |           <div class="error text-danger"></div> | ||||||
|  |         <% end %> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-footer"> | ||||||
|  |         <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> | ||||||
|  |         <button type="button" class="btn btn-primary submit-btn">确认</button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
| @ -0,0 +1,30 @@ | |||||||
|  | <div class="modal fade admin-import-discipline-modal" tabindex="-1" role="dialog" aria-hidden="true"> | ||||||
|  |   <div class="modal-dialog modal-dialog-centered" role="document"> | ||||||
|  |     <div class="modal-content"> | ||||||
|  |       <div class="modal-header"> | ||||||
|  |         <h5 class="modal-title">导入数据</h5> | ||||||
|  |         <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||||
|  |           <span aria-hidden="true">×</span> | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-body"> | ||||||
|  |         <form class="admin-import-discipline-form" enctype="multipart/form-data"> | ||||||
|  |           <div class="input-group"> | ||||||
|  |             <div class="input-group-prepend"> | ||||||
|  |               <span class="input-group-text">文件</span> | ||||||
|  |             </div> | ||||||
|  |             <div class="custom-file"> | ||||||
|  |               <input type="file" name="file" class="upload-file-input" id="import-discipline-input" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"> | ||||||
|  |               <label class="custom-file-label file-names" for="import-discipline-input">选择文件</label> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  |           <div class="error text-danger"></div> | ||||||
|  |         </form> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-footer"> | ||||||
|  |         <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> | ||||||
|  |         <button type="button" class="btn btn-primary submit-btn">确认</button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | <table class="table table-hover text-center discipline-list-table"> | ||||||
|  |   <thead class="thead-light"> | ||||||
|  |   <tr> | ||||||
|  |     <th width="6%">序号</th> | ||||||
|  |     <th width="54%" class="text-left">课程方向</th> | ||||||
|  |     <th width="8%">实践课程</th> | ||||||
|  |     <th width="8%">实训</th> | ||||||
|  |     <th width="8%">题库</th> | ||||||
|  |     <th width="16%">操作</th> | ||||||
|  |   </tr> | ||||||
|  |   </thead> | ||||||
|  |   <tbody> | ||||||
|  |   <% if @disciplines.present? %> | ||||||
|  |     <% @disciplines.each_with_index do |discipline, index| %> | ||||||
|  |       <tr class="discipline-item discipline-item-<%= discipline.id %>"> | ||||||
|  |         <td><%= index + 1 %></td> | ||||||
|  |         <td class="text-left"> | ||||||
|  |           <span><%= link_to discipline.name, admins_sub_disciplines_path(discipline_id: discipline), :title => discipline.name %></span> | ||||||
|  |         </td> | ||||||
|  |         <td><%= check_box_tag :subject,!discipline.subject,discipline.subject,remote:true,data:{id:discipline.id},class:"discipline-source-form" %></td> | ||||||
|  |         <td><%= check_box_tag :shixun,!discipline.shixun,discipline.shixun,remote:true,data:{id:discipline.id},class:"discipline-source-form" %></td> | ||||||
|  |         <td><%= check_box_tag :question,!discipline.question,discipline.question,remote:true,data:{id:discipline.id},class:"discipline-source-form" %></td> | ||||||
|  |         <td> | ||||||
|  |           <%= link_to '编辑', edit_admins_discipline_path(discipline), remote: true, class: 'action' %> | ||||||
|  |           <%= delete_link '删除', admins_discipline_path(discipline, element: ".discipline-item-#{discipline.id}"), class: 'delete-discipline-action' %> | ||||||
|  |         </td> | ||||||
|  |       </tr> | ||||||
|  |     <% end %> | ||||||
|  |   <% else %> | ||||||
|  |     <%= render 'admins/shared/no_data_for_table' %> | ||||||
|  |   <% end %> | ||||||
|  |   </tbody> | ||||||
|  | </table> | ||||||
| @ -0,0 +1,2 @@ | |||||||
|  | $('.modal.admin-edit-discipline-modal').modal("hide"); | ||||||
|  | $(".discipline-list-container").html("<%= j(render :partial => 'admins/disciplines/shared/list') %>"); | ||||||
| @ -0,0 +1,2 @@ | |||||||
|  | $.notify({ message: '删除成功' }); | ||||||
|  | $(".sub-discipline-item-<%= @sub_discipline_id %>").remove(); | ||||||
| @ -0,0 +1,2 @@ | |||||||
|  | $('.admin-modal-container').html("<%= j( render partial: 'admins/sub_disciplines/shared/edit_sub_discipline_modal', locals: { sub_discipline: @sub_discipline } ) %>"); | ||||||
|  | $('.modal.admin-edit-sub-discipline-modal').modal('show'); | ||||||
| @ -0,0 +1,14 @@ | |||||||
|  | <% define_admin_breadcrumbs do %> | ||||||
|  |   <% add_admin_breadcrumb('课程方向', admins_disciplines_path) %> | ||||||
|  |   <% add_admin_breadcrumb(@discipline.name) %> | ||||||
|  | <% end %> | ||||||
|  | 
 | ||||||
|  | <div class="box search-form-container sub-discipline-list-form"> | ||||||
|  |   <%= javascript_void_link '新增', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-sub-discipline-modal' } %> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <div class="box admin-list-container sub-discipline-list-container"> | ||||||
|  |   <%= render(partial: 'admins/sub_disciplines/shared/list') %> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <%= render 'admins/sub_disciplines/shared/create_sub_discipline_modal' %> | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | <div class="modal fade admin-create-sub-discipline-modal" tabindex="-1" role="dialog" aria-hidden="true"> | ||||||
|  |   <div class="modal-dialog modal-dialog-centered" role="document"> | ||||||
|  |     <div class="modal-content"> | ||||||
|  |       <div class="modal-header"> | ||||||
|  |         <h5 class="modal-title">新建课程</h5> | ||||||
|  |         <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||||
|  |           <span aria-hidden="true">×</span> | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-body"> | ||||||
|  |         <form class="admin-create-sub-discipline-form" data-url="<%= admins_sub_disciplines_path(discipline_id: @discipline) %>"> | ||||||
|  |           <div class="form-group d-flex"> | ||||||
|  |             <label for="new_mirror_id" class="col-form-label">名称:</label> | ||||||
|  |             <div class="w-75 d-flex flex-column"> | ||||||
|  |               <%= text_field_tag(:name, nil, class: 'form-control', placeholder: '请输入名称') %> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  | 
 | ||||||
|  |           <div class="error text-danger"></div> | ||||||
|  |         </form> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-footer"> | ||||||
|  |         <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> | ||||||
|  |         <button type="button" class="btn btn-primary submit-btn">确认</button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
| @ -0,0 +1,23 @@ | |||||||
|  | <div class="modal fade admin-edit-sub-discipline-modal" tabindex="-1" role="dialog" aria-hidden="true"> | ||||||
|  |   <div class="modal-dialog modal-dialog-centered" role="document"> | ||||||
|  |     <div class="modal-content"> | ||||||
|  |       <div class="modal-header"> | ||||||
|  |         <h5 class="modal-title">编辑课程</h5> | ||||||
|  |         <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||||
|  |           <span aria-hidden="true">×</span> | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-body"> | ||||||
|  |         <%= simple_form_for([:admins, sub_discipline], html: { class: 'admin-edit-sub-discipline-form' }, defaults: { wrapper_html: { class: 'offset-md-1 col-md-10' } }) do |f| %> | ||||||
|  |           <%= f.input :name, as: :string, label: '名称' %> | ||||||
|  | 
 | ||||||
|  |           <div class="error text-danger"></div> | ||||||
|  |         <% end %> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-footer"> | ||||||
|  |         <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> | ||||||
|  |         <button type="button" class="btn btn-primary submit-btn">确认</button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | <table class="table table-hover text-center sub-discipline-list-table"> | ||||||
|  |   <thead class="thead-light"> | ||||||
|  |   <tr> | ||||||
|  |     <th width="6%">序号</th> | ||||||
|  |     <th width="54%" class="text-left">课程</th> | ||||||
|  |     <th width="8%">实践课程</th> | ||||||
|  |     <th width="8%">实训</th> | ||||||
|  |     <th width="8%">题库</th> | ||||||
|  |     <th width="16%">操作</th> | ||||||
|  |   </tr> | ||||||
|  |   </thead> | ||||||
|  |   <tbody> | ||||||
|  |   <% if @sub_disciplines.present? %> | ||||||
|  |     <% @sub_disciplines.each_with_index do |sub, index| %> | ||||||
|  |       <tr class="sub-discipline-item sub-discipline-item-<%= sub.id %>"> | ||||||
|  |         <td><%= index + 1 %></td> | ||||||
|  |         <td class="text-left"> | ||||||
|  |           <span><%= link_to sub.name, admins_tag_disciplines_path(sub_discipline_id: sub), :title => sub.name %></span> | ||||||
|  |         </td> | ||||||
|  |         <td><%= check_box_tag :subject,!sub.subject,sub.subject,disabled:!sub.discipline&.subject,remote:true,data:{id:sub.id},class:"sub-discipline-source-form" %></td> | ||||||
|  |         <td><%= check_box_tag :shixun,!sub.shixun,sub.shixun,disabled:!sub.discipline&.shixun,remote:true,data:{id:sub.id},class:"sub-discipline-source-form" %></td> | ||||||
|  |         <td><%= check_box_tag :question,!sub.question,sub.question,disabled:!sub.discipline&.question,remote:true,data:{id:sub.id},class:"sub-discipline-source-form" %></td> | ||||||
|  |         <td> | ||||||
|  |           <%= link_to '编辑', edit_admins_sub_discipline_path(sub), remote: true, class: 'action' %> | ||||||
|  |           <%= delete_link '删除', admins_sub_discipline_path(sub, element: ".sub-discipline-item-#{sub.id}"), class: 'delete-sub-discipline-action' %> | ||||||
|  |         </td> | ||||||
|  |       </tr> | ||||||
|  |     <% end %> | ||||||
|  |   <% else %> | ||||||
|  |     <%= render 'admins/shared/no_data_for_table' %> | ||||||
|  |   <% end %> | ||||||
|  |   </tbody> | ||||||
|  | </table> | ||||||
| @ -0,0 +1,2 @@ | |||||||
|  | $('.modal.admin-edit-sub-discipline-modal').modal("hide"); | ||||||
|  | $(".sub-discipline-list-container").html("<%= j(render :partial => 'admins/sub_disciplines/shared/list') %>"); | ||||||
| @ -0,0 +1,2 @@ | |||||||
|  | $.notify({ message: '删除成功' }); | ||||||
|  | $(".tag-discipline-item-<%= @tag_discipline_id %>").remove(); | ||||||
| @ -0,0 +1,2 @@ | |||||||
|  | $('.admin-modal-container').html("<%= j( render partial: 'admins/tag_disciplines/shared/edit_tag_discipline_modal', locals: { tag_discipline: @tag_discipline } ) %>"); | ||||||
|  | $('.modal.admin-edit-tag-discipline-modal').modal('show'); | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | <% define_admin_breadcrumbs do %> | ||||||
|  |   <% add_admin_breadcrumb('课程方向', admins_disciplines_path) %> | ||||||
|  |   <% add_admin_breadcrumb(@sub_discipline&.discipline&.name, admins_sub_disciplines_path(discipline_id: @sub_discipline&.discipline_id)) %> | ||||||
|  |   <% add_admin_breadcrumb(@sub_discipline.name) %> | ||||||
|  | <% end %> | ||||||
|  | 
 | ||||||
|  | <div class="box search-form-container tag-discipline-list-form"> | ||||||
|  |   <%= javascript_void_link '新增', class: 'btn btn-primary', data: { toggle: 'modal', target: '.admin-create-tag-discipline-modal' } %> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <div class="box admin-list-container tag-discipline-list-container"> | ||||||
|  |   <%= render(partial: 'admins/tag_disciplines/shared/list') %> | ||||||
|  | </div> | ||||||
|  | 
 | ||||||
|  | <%= render 'admins/tag_disciplines/shared/create_tag_discipline_modal' %> | ||||||
| @ -0,0 +1,28 @@ | |||||||
|  | <div class="modal fade admin-create-tag-discipline-modal" tabindex="-1" role="dialog" aria-hidden="true"> | ||||||
|  |   <div class="modal-dialog modal-dialog-centered" role="document"> | ||||||
|  |     <div class="modal-content"> | ||||||
|  |       <div class="modal-header"> | ||||||
|  |         <h5 class="modal-title">新建知识点</h5> | ||||||
|  |         <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||||
|  |           <span aria-hidden="true">×</span> | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-body"> | ||||||
|  |         <form class="admin-create-tag-discipline-form" data-url="<%= admins_tag_disciplines_path(sub_discipline_id: @sub_discipline) %>"> | ||||||
|  |           <div class="form-group d-flex"> | ||||||
|  |             <label for="new_mirror_id" class="col-form-label">名称:</label> | ||||||
|  |             <div class="w-75 d-flex flex-column"> | ||||||
|  |               <%= text_field_tag(:name, nil, class: 'form-control', placeholder: '请输入名称') %> | ||||||
|  |             </div> | ||||||
|  |           </div> | ||||||
|  | 
 | ||||||
|  |           <div class="error text-danger"></div> | ||||||
|  |         </form> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-footer"> | ||||||
|  |         <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> | ||||||
|  |         <button type="button" class="btn btn-primary submit-btn">确认</button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
| @ -0,0 +1,23 @@ | |||||||
|  | <div class="modal fade admin-edit-tag-discipline-modal" tabindex="-1" role="dialog" aria-hidden="true"> | ||||||
|  |   <div class="modal-dialog modal-dialog-centered" role="document"> | ||||||
|  |     <div class="modal-content"> | ||||||
|  |       <div class="modal-header"> | ||||||
|  |         <h5 class="modal-title">编辑知识点</h5> | ||||||
|  |         <button type="button" class="close" data-dismiss="modal" aria-label="Close"> | ||||||
|  |           <span aria-hidden="true">×</span> | ||||||
|  |         </button> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-body"> | ||||||
|  |         <%= simple_form_for([:admins, tag_discipline], html: { class: 'admin-edit-tag-discipline-form' }, defaults: { wrapper_html: { class: 'offset-md-1 col-md-10' } }) do |f| %> | ||||||
|  |           <%= f.input :name, as: :string, label: '名称' %> | ||||||
|  | 
 | ||||||
|  |           <div class="error text-danger"></div> | ||||||
|  |         <% end %> | ||||||
|  |       </div> | ||||||
|  |       <div class="modal-footer"> | ||||||
|  |         <button type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> | ||||||
|  |         <button type="button" class="btn btn-primary submit-btn">确认</button> | ||||||
|  |       </div> | ||||||
|  |     </div> | ||||||
|  |   </div> | ||||||
|  | </div> | ||||||
| @ -0,0 +1,48 @@ | |||||||
|  | <table class="table table-hover text-center tag-discipline-list-table"> | ||||||
|  |   <thead class="thead-light"> | ||||||
|  |   <tr> | ||||||
|  |     <th width="6%">序号</th> | ||||||
|  |     <th width="42%" class="text-left">知识点</th> | ||||||
|  |     <th width="12%">创建者</th> | ||||||
|  |     <th width="8%">实践课程</th> | ||||||
|  |     <th width="8%">实训</th> | ||||||
|  |     <th width="8%">题库</th> | ||||||
|  |     <th width="16%">操作</th> | ||||||
|  |   </tr> | ||||||
|  |   </thead> | ||||||
|  |   <tbody> | ||||||
|  |   <% if @tag_disciplines.present? %> | ||||||
|  |     <% @tag_disciplines.each_with_index do |tag, index| %> | ||||||
|  |       <tr class="tag-discipline-item tag-discipline-item-<%= tag.id %>"> | ||||||
|  |         <td><%= index + 1 %></td> | ||||||
|  |         <td class="text-left"><%= tag.name %></td> | ||||||
|  |         <td> | ||||||
|  |           <% if tag.user.present? %> | ||||||
|  |             <%= link_to tag.user.real_name, user_path(tag.user), :target => "_blank" %> | ||||||
|  |           <% else %> | ||||||
|  |             -- | ||||||
|  |           <% end %> | ||||||
|  |         </td> | ||||||
|  |         <td> | ||||||
|  |           <% disabled = !(tag.sub_discipline&.subject && tag.discipline&.subject) %> | ||||||
|  |           <%= check_box_tag :subject,!tag.subject,tag.subject,disabled:disabled,remote:true,data:{id:tag.id},class:"tag-discipline-source-form" %> | ||||||
|  |         </td> | ||||||
|  |         <td> | ||||||
|  |           <% disabled = !(tag.sub_discipline&.shixun && tag.discipline&.shixun) %> | ||||||
|  |           <%= check_box_tag :shixun,!tag.shixun,tag.shixun,disabled:disabled,remote:true,data:{id:tag.id},class:"tag-discipline-source-form" %> | ||||||
|  |         </td> | ||||||
|  |         <td> | ||||||
|  |           <% disabled = !(tag.sub_discipline&.question && tag.discipline&.question) %> | ||||||
|  |           <%= check_box_tag :question,!tag.question,tag.question,disabled:disabled,remote:true,data:{id:tag.id},class:"tag-discipline-source-form" %> | ||||||
|  |         </td> | ||||||
|  |         <td> | ||||||
|  |           <%= link_to '编辑', edit_admins_tag_discipline_path(tag), remote: true, class: 'action' %> | ||||||
|  |           <%= delete_link '删除', admins_tag_discipline_path(tag, element: ".tag-discipline-item-#{tag.id}"), class: 'delete-tag-discipline-action' %> | ||||||
|  |         </td> | ||||||
|  |       </tr> | ||||||
|  |     <% end %> | ||||||
|  |   <% else %> | ||||||
|  |     <%= render 'admins/shared/no_data_for_table' %> | ||||||
|  |   <% end %> | ||||||
|  |   </tbody> | ||||||
|  | </table> | ||||||
| @ -0,0 +1,2 @@ | |||||||
|  | $('.modal.admin-edit-tag-discipline-modal').modal("hide"); | ||||||
|  | $(".tag-discipline-list-container").html("<%= j(render :partial => 'admins/tag_disciplines/shared/list') %>"); | ||||||
| @ -0,0 +1,35 @@ | |||||||
|  | case params[:source] | ||||||
|  | when 'subject' | ||||||
|  |   disciplines = Discipline.where(subject: 1).includes(subject_sub_disciplines: :subject_tag_disciplines) | ||||||
|  |   json.disciplines disciplines do |dis| | ||||||
|  |     json.(dis, :id, :name) | ||||||
|  |     json.sub_disciplines dis.subject_sub_disciplines do |sub| | ||||||
|  |       json.(sub, :id, :name) | ||||||
|  |       json.tag_disciplines sub.subject_tag_disciplines do |tag| | ||||||
|  |         json.(tag, :id, :name) | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | when 'shixun' | ||||||
|  |   disciplines = Discipline.where(shixun: 1).includes(shixun_sub_disciplines: :shixun_tag_disciplines) | ||||||
|  |   json.disciplines disciplines do |dis| | ||||||
|  |     json.(dis, :id, :name) | ||||||
|  |     json.sub_disciplines dis.shixun_sub_disciplines do |sub| | ||||||
|  |       json.(sub, :id, :name) | ||||||
|  |       json.tag_disciplines sub.shixun_tag_disciplines do |tag| | ||||||
|  |         json.(tag, :id, :name) | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |     end | ||||||
|  | when 'question' | ||||||
|  |   disciplines = Discipline.where(question: 1).includes(question_sub_disciplines: :question_tag_disciplines) | ||||||
|  |   json.disciplines disciplines do |dis| | ||||||
|  |     json.(dis, :id, :name) | ||||||
|  |     json.sub_disciplines dis.question_sub_disciplines do |sub| | ||||||
|  |       json.(sub, :id, :name) | ||||||
|  |       json.tag_disciplines sub.question_tag_disciplines do |tag| | ||||||
|  |         json.(tag, :id, :name) | ||||||
|  |       end | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | json.exams @exams.each do |exam| | ||||||
|  |   json.(exam, :id, :name, :difficulty, :quotes) | ||||||
|  |   json.question_count exam.question_count | ||||||
|  |   json.total_score exam.total_score | ||||||
|  |   json.update_time exam.updated_at&.strftime("%Y-%m-%d %H:%M") | ||||||
|  |   json.author do | ||||||
|  |     json.login exam.user&.login | ||||||
|  |     json.name exam.user&.full_name | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | json.exam_count @exams_count | ||||||
| @ -0,0 +1,6 @@ | |||||||
|  | json.(item, :name, :item_type, :difficulty, :public, :quotes) | ||||||
|  | json.analysis item.analysis | ||||||
|  | json.choices item.item_choices do |choice| | ||||||
|  |   json.choice_text choice.choice_text | ||||||
|  |   json.is_answer choice.is_answer | ||||||
|  | end | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | json.discipline do | ||||||
|  |   json.(@item.sub_discipline&.discipline, :id, :name) | ||||||
|  | end | ||||||
|  | json.sub_discipline do | ||||||
|  |   json.(@item.sub_discipline, :id, :name) | ||||||
|  | end | ||||||
|  | json.tag_disciplines @item.tag_disciplines do |tag| | ||||||
|  |   json.(tag, :id, :name) | ||||||
|  | end | ||||||
|  | json.(@item, :id, :name, :item_type, :difficulty) | ||||||
|  | json.analysis @item.analysis | ||||||
|  | json.choices @item.item_choices do |choice| | ||||||
|  |   json.choice_text choice.choice_text | ||||||
|  |   json.is_answer choice.is_answer | ||||||
|  | end | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | json.items @items.each do |item| | ||||||
|  |   json.id item.id | ||||||
|  |   json.partial! "item_banks/item", locals: {item: item} | ||||||
|  |   json.update_time item.updated_at&.strftime("%Y-%m-%d %H:%M") | ||||||
|  |   json.choosed @item_basket_ids.include?(item.id) | ||||||
|  |   json.author do | ||||||
|  |     json.login item.user&.login | ||||||
|  |     json.name item.user&.full_name | ||||||
|  |   end | ||||||
|  | end | ||||||
|  | json.items_count @items_count | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | json.single_questions_count @single_questions_count | ||||||
|  | json.multiple_questions_count @multiple_questions_count | ||||||
|  | json.judgement_questions_count @judgement_questions_count | ||||||
|  | json.completion_questions_count @completion_questions_count | ||||||
|  | json.subjective_questions_count @subjective_questions_count | ||||||
|  | json.practical_questions_count @practical_questions_count | ||||||
|  | json.program_questions_count @program_questions_count | ||||||
| @ -0,0 +1,3 @@ | |||||||
|  | json.status 0 | ||||||
|  | json.questions_score @questions_score | ||||||
|  | json.all_score @all_score | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | json.single_questions do | ||||||
|  |   json.questions @single_questions.each do |question| | ||||||
|  |     json.(question, :id, :position, :score, :item_type) | ||||||
|  |     json.partial! "item_banks/item", locals: {item: question.item_bank} | ||||||
|  |   end | ||||||
|  |   json.questions_score @single_questions.map(&:score).sum | ||||||
|  |   json.questions_count @single_questions.size | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | json.multiple_questions do | ||||||
|  |   json.questions @multiple_questions.each do |question| | ||||||
|  |     json.(question, :id, :position, :score, :item_type) | ||||||
|  |     json.partial! "item_banks/item", locals: {item: question.item_bank} | ||||||
|  |   end | ||||||
|  |   json.questions_score @multiple_questions.map(&:score).sum | ||||||
|  |   json.questions_count @multiple_questions.size | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | json.judgement_questions do | ||||||
|  |   json.questions @judgement_questions.each do |question| | ||||||
|  |     json.(question, :id, :position, :score, :item_type) | ||||||
|  |     json.partial! "item_banks/item", locals: {item: question.item_bank} | ||||||
|  |   end | ||||||
|  |   json.questions_score @judgement_questions.map(&:score).sum | ||||||
|  |   json.questions_count @judgement_questions.size | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | json.program_questions do | ||||||
|  |   json.questions @program_questions.each do |question| | ||||||
|  |     json.(question, :id, :position, :score, :item_type) | ||||||
|  |     json.partial! "item_banks/item", locals: {item: question.item_bank} | ||||||
|  |   end | ||||||
|  |   json.questions_score @program_questions.map(&:score).sum | ||||||
|  |   json.questions_count @program_questions.size | ||||||
|  | end | ||||||
|  | 
 | ||||||
|  | json.all_score @item_baskets.map(&:score).sum | ||||||
|  | json.all_questions_count @item_baskets.size | ||||||
| @ -0,0 +1,3 @@ | |||||||
|  | json.status 0 | ||||||
|  | json.questions_score @questions_score | ||||||
|  | json.all_score @all_score | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | class MigrateItemBankColumn < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     remove_column :item_banks, :curriculum_id | ||||||
|  |     remove_column :item_banks, :curriculum_direction_id | ||||||
|  |     add_column :item_banks, :sub_repertoire_id, :integer, index: true | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | class ChangeItemBankPublicDefault < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     change_column_default :item_banks, :public, 0 | ||||||
|  |     change_column_default :item_banks, :quotes, 0 | ||||||
|  |     change_column_default :item_banks, :difficulty, 1 | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,7 @@ | |||||||
|  | class AddPositionScoreToBasket < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     add_column :item_baskets, :position, :integer, default: 0 | ||||||
|  |     add_column :item_baskets, :score, :float, default: 0 | ||||||
|  |     add_column :item_baskets, :item_type, :integer, default: 0 | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,12 @@ | |||||||
|  | class CreateDisciplines < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     create_table :disciplines do |t| | ||||||
|  |       t.string :name | ||||||
|  |       t.boolean :subject | ||||||
|  |       t.boolean :shixun | ||||||
|  |       t.boolean :question | ||||||
|  | 
 | ||||||
|  |       t.timestamps | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | class CreateSubDisciplines < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     create_table :sub_disciplines do |t| | ||||||
|  |       t.references :discipline, index: true | ||||||
|  |       t.string :name | ||||||
|  |       t.boolean :subject | ||||||
|  |       t.boolean :shixun | ||||||
|  |       t.boolean :question | ||||||
|  | 
 | ||||||
|  |       t.timestamps | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | class CreateTagDisciplines < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     create_table :tag_disciplines do |t| | ||||||
|  |       t.references :sub_discipline, index: true | ||||||
|  |       t.string :name | ||||||
|  |       t.boolean :subject | ||||||
|  |       t.boolean :shixun | ||||||
|  |       t.boolean :question | ||||||
|  | 
 | ||||||
|  |       t.timestamps | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,6 @@ | |||||||
|  | class MigrateItemBankTagColumn < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     remove_column :item_banks, :sub_repertoire_id | ||||||
|  |     add_column :item_banks, :sub_discipline_id, :integer, index: true | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,13 @@ | |||||||
|  | class CreateTagDisciplineContainers < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     create_table :tag_discipline_containers do |t| | ||||||
|  |       t.references :tag_discipline, index: true | ||||||
|  |       t.integer :container_id | ||||||
|  |       t.string :container_type | ||||||
|  | 
 | ||||||
|  |       t.timestamps | ||||||
|  |     end | ||||||
|  | 
 | ||||||
|  |     add_index :tag_discipline_containers, [:container_type, :container_id], name: "index_on_container" | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | class MigrateDisciplinesDefault < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     change_column_default :disciplines, :subject, from: nil, to: 1 | ||||||
|  |     change_column_default :disciplines, :shixun, from: nil, to: 1 | ||||||
|  |     change_column_default :disciplines, :question, from: nil, to: 1 | ||||||
|  | 
 | ||||||
|  |     change_column_default :sub_disciplines, :subject, from: nil, to: 1 | ||||||
|  |     change_column_default :sub_disciplines, :shixun, from: nil, to: 1 | ||||||
|  |     change_column_default :sub_disciplines, :question, from: nil, to: 1 | ||||||
|  | 
 | ||||||
|  |     change_column_default :tag_disciplines, :subject, from: nil, to: 1 | ||||||
|  |     change_column_default :tag_disciplines, :shixun, from: nil, to: 1 | ||||||
|  |     change_column_default :tag_disciplines, :question, from: nil, to: 1 | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | class CreateExaminationBanks < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     create_table :examination_banks do |t| | ||||||
|  |       t.string :name | ||||||
|  |       t.integer :difficulty, default: 1 | ||||||
|  |       t.references :user, index: true | ||||||
|  |       t.boolean :public, default: 0 | ||||||
|  |       t.integer :quotes, default: 0 | ||||||
|  |       t.references :sub_discipline, index: true | ||||||
|  |       t.integer :duration | ||||||
|  | 
 | ||||||
|  |       t.timestamps | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,15 @@ | |||||||
|  | class CreateExaminationItems < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     create_table :examination_items do |t| | ||||||
|  |       t.references :examination_bank, index: true | ||||||
|  |       t.references :item_bank, index: true | ||||||
|  |       t.string :name | ||||||
|  |       t.integer :item_type, default: 0 | ||||||
|  |       t.integer :difficulty, default: 1 | ||||||
|  |       t.float :score, default: 0 | ||||||
|  |       t.integer :position, default: 0 | ||||||
|  | 
 | ||||||
|  |       t.timestamps | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,11 @@ | |||||||
|  | class CreateExaminationItemChoices < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     create_table :examination_item_choices do |t| | ||||||
|  |       t.references :examination_item, index: true | ||||||
|  |       t.text :choice_text | ||||||
|  |       t.boolean :is_answer, default: 0 | ||||||
|  | 
 | ||||||
|  |       t.timestamps | ||||||
|  |     end | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,5 @@ | |||||||
|  | class AddSubDisciplineIdForHacks < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     add_column :hacks, :sub_discipline_id, :integer | ||||||
|  |   end | ||||||
|  | end | ||||||
| @ -0,0 +1,5 @@ | |||||||
|  | class AddUserIdToTagDiscipline < ActiveRecord::Migration[5.2] | ||||||
|  |   def change | ||||||
|  |     add_column :tag_disciplines, :user_id, :integer | ||||||
|  |   end | ||||||
|  | end | ||||||
											
												
													File diff suppressed because one or more lines are too long
												
											
										
									
								
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												
													File diff suppressed because one or more lines are too long
												
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								
											
												Binary file not shown.
											
										
									
								
											
												
													File diff suppressed because it is too large
													Load Diff
												
											
										
									
								
											
												Binary file not shown.
											
										
									
								Some files were not shown because too many files have changed in this diff Show More
					Loading…
					
					
				
		Reference in new issue