class ExaminationBanksController < ApplicationController include PaginateHelper include CoursesHelper before_action :require_login before_action :certi_identity_auth, only: [:edit, :revoke_item] before_action :find_exam, except: [:index, :create, :create_random_exam, :cancel_items] before_action :edit_auth, only: [:update, :set_public, :destroy] before_action :identity_auth, only: [:index] before_action :check_account, only: [:index] before_action :check_contents_and_score_setting, only: [:create_random_exam, :update_random_exam] # 创建随机组卷 def create_random_exam ActiveRecord::Base.transaction do examination_bank = current_user.examination_banks.build( random_exam_params.slice(:name, :difficulty, :time, :source, :sub_discipline_id).merge(is_random: true) ) if examination_bank.save! # 1.保存随机规则设置 # "contents": [ # { # "question_type": "MULTIPLE", # "difficulty": 1, # "sub_discipline_id": 1, # "sub_discipline_name": null, # "size": 1 # }, # { # "question_type": "SINGLE", # "difficulty": 1, # "sub_discipline_id": 81, # "sub_discipline_name": null, # "size": 1 # } # ] random_exam_params[:contents].each do |random_setting| examination_bank.examination_bank_random_settings.create!( item_type: random_setting[:item_type], sub_discipline_id: random_setting[:sub_discipline_id], difficulty: random_setting[:difficulty], quanlity: random_setting[:items_count] ) end # 2.保存赋分设置 # [ # { # item_type: "SINGLE", # score: 1 # } # ] random_exam_params[:score_settings].each do |score_setting| examination_bank.examination_bank_score_settings.create!( item_type: score_setting[:item_type], score: score_setting[:score] ) end end render_ok({examination_bank_id: examination_bank.id}) end rescue Exception => ex render_error(ex.message) end # 编辑随机组卷 def edit_random_exam @examination_bank_score_settings = @exam.examination_bank_score_settings @examination_bank_random_settings = @exam.examination_bank_random_settings.includes(:sub_discipline=>[:discipline]) # 按照题型-课程-难度进行分组 # @contents = [] # item_types = @examination_bank_random_settings.pluck(:item_type).uniq # item_types.each do |item_type| # hash = {item_type: item_type, items_by_item_type: []} # items_by_item_type = @examination_bank_random_settings.where(item_type: item_type) # # 该题型下各个课程类的题目集合 # sub_disciplines = items_by_item_type.joins(:sub_discipline=>[:discipline]).pluck(:sub_discipline_id, "sub_disciplines.name name", :discipline_id, "disciplines.name discipline_name").uniq # sub_disciplines.each_with_index do |sub_discipline, index| # hash[:items_by_item_type] << { # sub_discipline_id: sub_discipline[0], sub_discipline_name: sub_discipline[1], discipline_id: sub_discipline[2], discipline_name: sub_discipline[3], # items_by_item_type_and_sub_discipline: [] # } # items_by_item_type_and_sub_discipline = items_by_item_type.where(sub_discipline_id: sub_discipline[0]) # difficulties = items_by_item_type_and_sub_discipline.pluck(:difficulty).uniq # difficulties.each do |difficulty| # items_by_item_type_and_sub_discipline_and_difficulty = items_by_item_type_and_sub_discipline.where(difficulty: difficulty).select(:id) # hash[:items_by_item_type][index][:items_by_item_type_and_sub_discipline] << {difficulty: difficulty, items_count: items_by_item_type_and_sub_discipline_and_difficulty.size} # end # end # @contents << hash # end # 赋分设置 @score_settings = [] @examination_bank_score_settings.each do |examination_bank_score_setting| @score_settings << { item_type: examination_bank_score_setting.item_type, score: examination_bank_score_setting.score } end end # 更新随机组卷 def update_random_exam ActiveRecord::Base.transaction do # 更新时直接删除原有配置重新建立 @exam.examination_bank_score_settings.destroy_all @exam.examination_bank_random_settings.destroy_all @exam.update!(random_exam_params.slice(:name, :difficulty, :time, :source).merge(is_random: true)) if @exam.save! # 1.保存随机规则设置 # "contents": [ # { # "question_type": "MULTIPLE", # "difficulty": 1, # "sub_discipline_id": 1, # "sub_discipline_name": null, # "size": 1 # }, # { # "question_type": "SINGLE", # "difficulty": 1, # "sub_discipline_id": 81, # "sub_discipline_name": null, # "size": 1 # } # ] random_exam_params[:contents].each do |random_setting| @exam.examination_bank_random_settings.create!( item_type: random_setting[:item_type], sub_discipline_id: random_setting[:sub_discipline_id], difficulty: random_setting[:difficulty], quanlity: random_setting[:items_count] ) end # 2.保存赋分设置 # [ # { # item_type: "SINGLE", # score: 1 # } # ] random_exam_params[:score_settings].each do |score_setting| @exam.examination_bank_score_settings.create!( item_type: score_setting[:item_type], score: score_setting[:score] ) end end render_ok end rescue Exception => ex render_error(ex.message) end def index exams = ExaminationBankQuery.call(params) @exams_count = exams.size @exams = paginate exams.includes(:user, :examination_items) @current_user = current_user @role = current_user.admin_or_business? || current_user.is_teacher? || current_user.is_shixun_marker? end def show @items = @exam.examination_items # TODO: 由于Jbuilder层公用了item_bank,里面有根据用户的权限判断,因此,这边需要加上一个user_id @single_questions = @items.where(item_type: "SINGLE") .joins(:examination_bank).select("examination_items.*, examination_banks.user_id") @multiple_questions = @items.where(item_type: "MULTIPLE") .joins(:examination_bank).select("examination_items.*, examination_banks.user_id") @judgement_questions = @items.where(item_type: "JUDGMENT") .joins(:examination_bank).select("examination_items.*, examination_banks.user_id") @completion_questions = @items.where(item_type: "COMPLETION") .joins(:examination_bank).select("examination_items.*, examination_banks.user_id") @subjective_questions = @items.where(item_type: "SUBJECTIVE") .joins(:examination_bank).select("examination_items.*, examination_banks.user_id") @program_questions = @items.where(item_type: "PROGRAM") .joins(:examination_bank).select("examination_items.*, examination_banks.user_id") 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 new_item.new_item(item, exam, basket.score, basket.position) end end current_user.item_baskets.destroy_all render_ok({exam_id: exam.id}) end rescue ApplicationService::Error => ex render_error(ex.message) 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 tip_exception(403, "无权限") unless current_user.admin? || @exam.user == current_user ActiveRecord::Base.transaction do ApplyAction.where(container_type: "ExaminationBank", container_id: @exam.id).destroy_all @exam.destroy! render_ok end end def set_public tip_exception(-1, "该试卷已公开") if @exam.public? tip_exception(-1, "请勿重复提交申请") if ApplyAction.where(container_id: @exam.id, container_type: "ExaminationBank", status: 0).exists? ApplyAction.create!(container_id: @exam.id, container_type: "ExaminationBank", user_id: current_user.id) # @exam.update_attributes!(public: 1) render_ok end def set_private tip_exception(-1, "该试卷已私有") unless @exam.public? ActiveRecord::Base.transaction do @exam.update_attributes!(public: 0) ApplyAction.where(container_id: @exam.id, container_type: 'ExaminationBank', status: 0).update_all(status: 3) end render_ok end def revoke_item item = @exam.examination_items.find_by!(item_bank_id: params[:item_id]) 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 cancel_items tip_exception(403, "无权限") unless current_user.admin_or_business? || current_user.item_baskets.where(item_bank_id: params[:item_ids]).size == params[:item_ids].size current_user.item_baskets.where(item_bank_id: params[:item_ids]).destroy_all render_ok end def send_to_course tip_exception(403, "无权限") unless @exam.public || @exam.user == current_user course = Course.find params[:course_id] exercise = Exercise.new(user_id: current_user.id, course_id: course.id) exercise = ExaminationBanks::SendToCourseService.call(@exam, exercise) render_ok({exercise_id: exercise.id, first_category_url: module_url(course.exercise_course_modules.first, course)}) 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 tip_exception(403, "无权限") unless current_user.admin_or_business? || @exam.user == current_user end def random_exam_params result = params.permit( :name, :difficulty, :source, :time, :sub_discipline_id, contents: [ :item_type, :sub_discipline_id, :difficulty, :items_count ], score_settings: [ :item_type, :score ] ) result end def check_contents_and_score_setting raise Educoder::TipException.new("随机规则设置不得为空或者题目数量不能为0") if random_exam_params[:contents].blank? || random_exam_params[:contents].all?{|content| content[:items_count].to_i == 0} raise Educoder::TipException.new("内容设置和赋分设置的题型数量不一致") if random_exam_params[:contents].collect{|content| content[:item_type]}.uniq.size != random_exam_params[:score_settings].collect{|setting| setting[:item_type]}.uniq.size end end