From 8680714720837eea5b58d1cfc26d4fbed8b479e7 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Fri, 3 Jan 2020 11:57:58 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E7=9A=84=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../examination_banks_controller.rb | 27 ++---- .../examination_items_controller.rb | 84 +++++++++++++++++++ app/models/examination_item.rb | 18 ++++ .../examination_items/save_item_service.rb | 50 +++++++++++ config/routes.rb | 12 +++ 5 files changed, 173 insertions(+), 18 deletions(-) create mode 100644 app/controllers/examination_items_controller.rb create mode 100644 app/services/examination_items/save_item_service.rb diff --git a/app/controllers/examination_banks_controller.rb b/app/controllers/examination_banks_controller.rb index e5e9ca4ca..96767c21b 100644 --- a/app/controllers/examination_banks_controller.rb +++ b/app/controllers/examination_banks_controller.rb @@ -28,34 +28,25 @@ class ExaminationBanksController < ApplicationController 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) - new_item.save! - item.increment!(:quotes) - - if item.item_type == "PROGRAM" - new_hack = item.container.fork - new_item.update_attributes!(container: new_hack) - else - new_item.examination_item_analysis.create!(analysis: item.analysis) - 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 + new_item = ExaminationItem.new + new_item.new_item(item, exam, basket.score, basket.position) end end current_user.item_baskets.destroy_all end render_ok + rescue ApplicationService::Error => ex + render_error(ex.message) end - def edit - - end + def edit; end def update - + ExaminationBanks::SaveExaminationBankService.call(@exam, form_params) + render_ok + rescue ApplicationService::Error => ex + render_error(ex.message) end def destroy diff --git a/app/controllers/examination_items_controller.rb b/app/controllers/examination_items_controller.rb new file mode 100644 index 000000000..ee7a27c59 --- /dev/null +++ b/app/controllers/examination_items_controller.rb @@ -0,0 +1,84 @@ +class ExaminationItemsController < ApplicationController + before_action :require_login + before_action :validate_score, only: [:set_score, :batch_set_score] + before_action :find_exam, only: [:create, :batch_set_score, :delete_item_type] + before_action :find_item, except: [:create, :batch_set_score, :delete_item_type] + before_action :edit_auth + + def create + ExaminationItems::SaveItemService.call(current_user, create_params, @exam) + render_ok + rescue ApplicationService::Error => ex + render_error(ex.message) + end + + def destroy + ActiveRecord::Base.transaction do + @exam.examination_items.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 + items = @exam.examination_items.where(item_type: params[:item_type]) + items.destroy_all + render_ok + end + + def set_score + @item.update_attributes!(score: params[:score]) + @questions_score = @exam.examination_items.where(item_type: @item.item_type).pluck(:score).sum + @all_score = @exam.examination_items.pluck(:score).sum + render_ok({questions_score: @questions_score, all_score: @all_score}) + end + + def batch_set_score + @exam.examination_items.where(item_type: params[:item_type]).update_all(score: params[:score]) + @questions_score = @exam.examination_items.where(item_type: params[:item_type]).pluck(:score).sum + @all_score = @exam.examination_items.pluck(:score).sum + render_ok({questions_score: @questions_score, all_score: @all_score}) + end + + def adjust_position + same_items = @exam.examination_items.where(item_type: @item.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 > @item.position + same_items.where("position > #{@item.position} and position <= #{params[:position].to_i}").update_all("position=position-1") + @item.update_attributes!(position: params[:position]) + elsif params[:position].to_i < @item.position + same_items.where("position < #{@item.position} and position >= #{params[:position].to_i}").update_all("position=position+1") + @item.update_attributes!(position: params[:position]) + else + return normal_status(-1, "排序无变化") + end + end + render_ok + end + + private + + def find_exam + @exam = ExaminationBank.find_by!(id: params[:exam_id]) + end + + def create_params + params.permit(item_ids: []) + end + + def find_item + @item = ExaminationItem.find_by!(id: params[:id]) + @exam = @item.examination_bank + end + + def validate_score + tip_exception("分值不能为空") unless params[:score].present? + tip_exception("分值需大于0") unless params[:score].to_f > 0 + end + + def edit_auth + current_user.admin_or_business? || @exam.user == current_user + end +end \ No newline at end of file diff --git a/app/models/examination_item.rb b/app/models/examination_item.rb index 0cc515cae..bfd1d6376 100644 --- a/app/models/examination_item.rb +++ b/app/models/examination_item.rb @@ -24,4 +24,22 @@ class ExaminationItem < ApplicationRecord 0 end + # 题库复制 + def new_item item, exam, score, position + attributes = {examination_bank: exam, item_bank: item, name: item.name, item_type: item.item_type, + difficulty: item.difficulty, score: score, position: position} + self.update!(attributes) + item.increment!(:quotes) + + if item.item_type == "PROGRAM" + new_hack = item.container.fork + self.update!(container: new_hack) + else + ExaminationItemAnalysis.create!(analysis: item.analysis, examination_item_id: self.id) + item.item_choices.each do |choice| + examination_item_choices << ExaminationItemChoice.new(choice_text: choice.choice_text, is_answer: choice.is_answer) + end + end + end + end diff --git a/app/services/examination_items/save_item_service.rb b/app/services/examination_items/save_item_service.rb new file mode 100644 index 000000000..34d5262a8 --- /dev/null +++ b/app/services/examination_items/save_item_service.rb @@ -0,0 +1,50 @@ +class ExaminationItems::SaveItemService < ApplicationService + attr_reader :user, :params, :exam + + def initialize(user, params, exam) + @user = user + @params = params + @exam = exam + 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] - exam.examination_items.pluck(:item_bank_id) + items.where(id: item_ids).each do |item| + ActiveRecord::Base.transaction do + item_score = item_score item.item_type + item_position = item_position item.item_type + new_item = ExaminationItem.new + new_item.new_item(item, exam, item_score, item_position) + end + end + end + + private + + def item_score item_type + if exam.examination_items.where(item_type: item_type).last.present? + score = exam.examination_items.where(item_type: item_type).last.score + else + score = + case item_type + when "SINGLE", "MULTIPLE", "JUDGMENT" + 5 + when "PROGRAM" + 10 + else + 5 + end + end + score + end + + def item_position item_type + exam.examination_items.where(item_type: item_type).last&.position.to_i + 1 + end +end \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 77ffdfc2c..2409a8883 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -83,6 +83,18 @@ Rails.application.routes.draw do end end + resources :examination_items do + collection do + delete :delete_item_type + post :batch_set_score + end + + member do + post :set_score + post :adjust_position + end + end + resources :hacks, path: :problems, param: :identifier do collection do get :unpulished_list