class ExercisesController < ApplicationController before_action :require_login, :check_auth, except: [:index] before_action :find_course,only: [:index,:new,:create,:my_exercises,:public_exercises,:set_public,:destroys, :join_exercise_banks,:publish_modal,:publish,:end_modal,:end_exercise] #需要有课堂id参数的 before_action :get_exercise,except: [:index,:new,:create,:my_exercises,:public_exercises,:set_public,:destroys, :join_exercise_banks,:publish_modal,:publish,:end_modal,:end_exercise] before_action :user_course_identity before_action :is_course_teacher,except: [:index,:start_answer,:exercise_setting,:commit_exercise,:exercise_lists,:review_exercise, :exercise_result,:common_header,:cancel_exercise,:begin_commit] before_action :get_left_banner_id,only:[:common_header,:start_answer,:review_exercise,:index,:new,:edit] before_action :validates_exercise_params,only: [:create,:update] before_action :get_exercise_question_counts,only: [:show,:edit,:start_answer,:review_exercise,:blank_exercise,:export_exercise] before_action :validate_publish_time,only: [:commit_setting] #提交设置时,需判断时间是否符合 before_action :check_course_public,only: [:set_public] before_action :check_user_on_answer,only: [:show,:start_answer,:exercise_lists] #判断当前用户在试卷的权限/老师是否属于分班的权限 before_action :only_student_in,only: [:start_answer] before_action :check_user_id_start_answer,only: [:start_answer,:review_exercise] # before_action :commit_user_exercise,only: [:start_answer,:exercise_lists,:review_exercise] #已有定时的任务 before_action :check_exercise_time,only: [:commit_exercise] #提交试卷时,判断时间是否超过 before_action :check_exercise_status,only: [:redo_modal,:redo_exercise] before_action :check_exercise_is_end, only: [:review_exercise] before_action :check_exercise_public,only: [:exercise_result] #试卷是否为公开 before_action :commit_shixun_present,only: [:commit_shixun] include ExportHelper include ExercisesHelper def index ActiveRecord::Base.transaction do begin # 按发布时间或创建时间排序 @exercises_all = @course.exercises member_show_exercises = @exercises_all.is_exercise_published #已发布的或已截止的试卷 @current_user_ = current_user # 课堂的学生人数 @course_all_members = @course.students #当前课堂的全部学生 @current_student = @course_all_members.course_find_by_ids("user_id",current_user.id) #当前用户是否为课堂的学生 # exercises的不同用户群体的显示 if @user_course_identity < Course::STUDENT # @is_teacher_or 1为老师/管理员/助教 @is_teacher_or = 1 @exercises = @exercises_all #老师能看到全部的试卷,不管是已发布的/未发布的/已截止的/统一设置的/私有设置的(看到内容不同) elsif @user_course_identity == Course::STUDENT # 2为课堂成员,能看到统一设置的和自己班级的 @is_teacher_or = 2 @member_group_id = @current_student.first.try(:course_group_id).to_i # 成员的分班id,默认为0 if @member_group_id == 0 #表示是课堂的未分班成员,只能查看统一设置的试卷(已发布的/已截止的) @exercises = member_show_exercises.exists? ? member_show_exercises.unified_setting : [] else #已分班级的成员,可以查看统一设置和单独设置(试卷是发布在该班级)试卷 # 已发布 当前用户班级分组的 试卷id not_exercise_ids = @course.exercise_group_settings.exercise_group_not_published.where("course_group_id = #{@member_group_id}").pluck(:exercise_id) @exercises = member_show_exercises.where.not(id: not_exercise_ids) end else #用户未登陆或不是该课堂成员,仅显示统一设置的(已发布的/已截止的),如有公开,则不显示锁,不公开,则显示锁 @is_teacher_or = 0 @exercises = member_show_exercises.unified_setting end if @exercises.size > 0 if params[:type].present? choose_type = params[:type].to_i ex_setting_ids = [] if @is_teacher_or != 2 @exercises = @exercises.where("exercise_status = #{choose_type}") else case choose_type when 1 ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_not_published.pluck(:exercise_id) when 2 ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}") .where("publish_time is not null and publish_time <= ? and end_time > ?",Time.now,Time.now).pluck(:exercise_id) when 3 ex_setting_ids = @course.exercise_group_settings.where("course_group_id = #{@member_group_id}").exercise_group_ended.pluck(:exercise_id) end unified_setting_ids = @exercises.unified_setting.where("exercise_status = #{choose_type}").pluck(:id) ex_ids = (ex_setting_ids + unified_setting_ids).uniq @exercises = @exercises.where(id: ex_ids) end end if params[:search].present? search_type = params[:search].to_s.strip @exercises = @exercises.exercise_search(search_type) end @exercises_select_count = @exercises.size # 全部页面,需返回 @exercises = @exercises.distinct.order( "IF(ISNULL(publish_time),0,1), publish_time DESC,created_at DESC") #出现错误 # 分页 @page = params[:page] || 1 @limit = params[:limit] || 15 @exercises = @exercises.page(@page).per(@limit) @exercises = @exercises&.includes(:published_settings) else @exercises = [] end @course_all_members_count = @course_all_members.size #当前课堂的学生数 @exercises_count = @exercises_all.size # 全部页面,需返回 @exercises_unpublish_counts = @exercises_all.exercise_by_status(1).size #未发布的试卷数 @exercises_published_counts = @exercises_count - @exercises_unpublish_counts # 已发布的试卷数,包含已截止的 rescue Exception => e uid_logger_error(e.message) tip_exception(e.message) raise ActiveRecord::Rollback end end end def new ActiveRecord::Base.transaction do begin @exercise = Exercise.new rescue Exception => e uid_logger_error(e.message) tip_exception("试卷创建失败!") raise ActiveRecord::Rollback end end end def create ActiveRecord::Base.transaction do begin ex_name = params[:exercise_name] ex_desc = params[:exercise_description] exercise_options = { :exercise_name => ex_name, :exercise_description => ex_desc, :user_id => current_user.id, :course_id => @course.id, :time => -1, :exercise_status => 1 } @exercise = Exercise.create(exercise_options) rescue Exception => e uid_logger_error(e.message) tip_exception("试卷创建失败!") raise ActiveRecord::Rollback end end end #试卷的内容,及试题/答案的内容编辑 def edit ActiveRecord::Base.transaction do begin @exercise_questions = @exercise.exercise_questions.order("question_number ASC") rescue Exception => e uid_logger_error(e.message) tip_exception("试卷创建失败!") raise ActiveRecord::Rollback end end end def update ActiveRecord::Base.transaction do begin ex_name = params[:exercise_name] ex_desc = params[:exercise_description] exercise_options = { :exercise_name => ex_name, :exercise_description => ex_desc, } @exercise.update_attributes(exercise_options) normal_status(0,"试卷更新成功!") rescue Exception => e uid_logger_error(e.message) tip_exception("试卷创建失败!") raise ActiveRecord::Rollback end end end def show ActiveRecord::Base.transaction do begin if @user_course_identity < Course::STUDENT @is_teacher_or = 1 #为老师/助教/管理员 else @is_teacher_or = 0 #为学生 end @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices,:exercise_shixun_challenges,:exercise_standard_answers).order("question_number ASC") rescue Exception => e uid_logger_error(e.message) tip_exception("试卷创建失败!") raise ActiveRecord::Rollback end end end #试卷的公用头部 def common_header ActiveRecord::Base.transaction do begin @user_left_time = nil if @user_course_identity > Course::ASSISTANT_PROFESSOR @is_teacher_or = 0 @user_exercise_answer = @exercise.check_user_answer_status(current_user) @user_commit_counts = 0 @user_left_time = get_exercise_left_time(@exercise,current_user) else @is_teacher_or = 1 @user_exercise_answer = 3 #教师页面 @user_commit_counts = @exercise.exercise_users.where(commit_status:1).size #已提交的用户数 end @ex_status = @exercise.get_exercise_status(current_user) exercise_id_array = [@exercise.id] @exercise_publish_count = get_user_permission_course(exercise_id_array,Exercise::PUBLISHED).size #是否存在已发布的 @exercise_unpublish_count = get_user_permission_course(exercise_id_array,Exercise::UNPUBLISHED).size #是否存在未发布的 if (@exercise_publish_count == 0) && (@exercise_unpublish_count == 0) #即表示没有分班 if @ex_status == Exercise::UNPUBLISHED @exercise_unpublish_count = 1 #试卷未发布,且课堂没有分班的时候 elsif @ex_status == Exercise::PUBLISHED @exercise_publish_count = 1 #试卷未发布,且课堂没有分班的时候 end end rescue Exception => e uid_logger_error(e.message) tip_exception("没有权限") raise ActiveRecord::Rollback end end end #实训题目的选用 def choose_shixun ActiveRecord::Base.transaction do begin search = params[:search] if @user_course_identity > Course::ADMIN #当不为管理员的时候 user_school_id = current_user.school_id #当前用户的学校id if user_school_id.present? none_shixun_ids = ShixunSchool.where("school_id != #{user_school_id}").pluck(:shixun_id) @publish_shixuns = Shixun.where.not(id: none_shixun_ids).unhidden end else @publish_shixuns = Shixun.unhidden end if search.present? @publish_shixuns = @publish_shixuns.search_by_name(search) end @shixuns = @publish_shixuns.joins(:challenges).where("challenges.st != 0").distinct # 全部页面,需返回 @shixuns_count = @shixuns.count # 分页 @page = params[:page] || 1 @limit = params[:limit] || 8 @shixuns = @shixuns.page(@page).per(@limit) rescue Exception => e uid_logger_error(e.message) tip_exception("实训选择失败!") end end end #确认实训的选择 def commit_shixun ActiveRecord::Base.transaction do begin @shixun_challenges = @shixun.challenges @shixun_challenges_count = @shixun_challenges.size rescue Exception => e uid_logger_error(e.message) tip_exception("页面调用失败!") raise ActiveRecord::Rollback end end end # 首页批量或单独删除 def destroys ActiveRecord::Base.transaction do begin check_ids = Exercise.where(id: params[:check_ids]) check_ids.destroy_all normal_status(0, "试卷已删除成功!") rescue Exception => e uid_logger_error(e.message) tip_exception("试卷删除失败!") raise ActiveRecord::Rollback end end end # 设为公开 def set_public ActiveRecord::Base.transaction do begin check_ids = Exercise.where(id: params[:check_ids]) check_ids.each do |exercise| exercise.update_attribute('is_public', true) end normal_status(0, "试卷已设为公开!") rescue Exception => e uid_logger_error(e.message) tip_exception("试卷设为公开失败!") raise ActiveRecord::Rollback end end end ## 加入题库 def join_exercise_banks ActiveRecord::Base.transaction do begin check_ids = Exercise.where(id: params[:check_ids]) check_ids.each do |exercise| current_ex_bank = current_user.exercise_banks.find_by_container(exercise.id,"Exercise")&.first if current_ex_bank.present? #当前用户的选择试卷是否已加入习题库,存在则更新习题库和问题库,否则新建习题库和问题库 ex_params = { :name => exercise.exercise_name, :description => exercise.exercise_description, :course_list_id => exercise.course.try(:course_list_id) } current_ex_bank.update_attributes(ex_params) # question_bank = QuestionBank.ques_by_container(current_ex_bank.id,current_ex_bank.container_type).first #该习题库是否存在于问题库里 # ques_params = { # :name => current_ex_bank.name, # :course_list_id => current_ex_bank.course_list_id # } # question_bank.update_attributes(ques_params) if question_bank.present? current_ex_bank.exercise_bank_questions.destroy_all # 更新后,习题库的问题全部删除,后续重新再建 else ex_params = { :name => exercise.exercise_name, :description => exercise.exercise_description, :user_id => current_user.id, :is_public => 0, :course_list_id => exercise.course.try(:course_list_id), :container_id => exercise.id, :container_type => "Exercise", :quotes => 1 } current_ex_bank= ExerciseBank.new ex_params current_ex_bank.save! #如果习题库保存成功,则会创建问题库question_bank # if current_ex_bank.save # ques_params = { # :name => current_ex_bank.name, # :container_id => current_ex_bank.id, # :container_type => current_ex_bank.container_type, # :quotes => current_ex_bank.quotes, # :user_id => current_ex_bank.user_id, # :is_public => current_ex_bank.is_public, # :course_list_id => current_ex_bank.course_list_id # } # question_bank = QuestionBank.new ques_params # question_bank.save # end end # 试卷的问题的输入 exercise.exercise_questions.each do |q| option = { :question_title => q.question_title, :question_type => q.question_type, :question_number => q.question_number, :question_score => q.question_score, :shixun_id => q.shixun_id, :shixun_name => q.shixun_name } exercise_bank_question = current_ex_bank.exercise_bank_questions.new option exercise_bank_question.save ## 试卷选项的输入 if q.question_type != Exercise::PRACTICAL #不为实训题时,试卷选项加入试题答案库 ex_choices = q.exercise_choices ex_standard = q.exercise_standard_answers ex_choices.each do |c| choice_option = { :choice_position => c.choice_position, :choice_text =>c.choice_text } ex_bank_choice = exercise_bank_question.exercise_bank_choices.new choice_option ex_bank_choice.save end ex_standard.each do |s| ex_stand = { :exercise_bank_choice_id => s.exercise_choice_id, :answer_text => s.answer_text } ex_stand_bank = exercise_bank_question.exercise_bank_standard_answers.new ex_stand ex_stand_bank.save end else #当为实训题时 shixun_challenges = q.exercise_shixun_challenges shixun_challenges.each do |c| challenge_option = { :position => c.position, :challenge_id => c.challenge_id, :shixun_id => q.shixun_id, :question_score => c.question_score } shixun_challenge_bank = exercise_bank_question.exercise_bank_shixun_challenges.new challenge_option shixun_challenge_bank.save end end end current_ex_bank.save end normal_status(0, "题库更新成功!") rescue Exception => e uid_logger_error(e.message) tip_exception("题库更新失败!") raise ActiveRecord::Rollback end end end #试卷的设置页面 def exercise_setting ActiveRecord::Base.transaction do begin @user_permission = 2 @user_course_groups = @course.teacher_group(current_user.id) #当前老师的分班 @being_setting_course_ids = @exercise.common_published_ids(current_user.id) #当前用户已发布的班级的id @user_published_setting = @exercise.exercise_group_settings .find_in_exercise_group("course_group_id",@being_setting_course_ids) #当前用户已发布班级的试卷设置 exercise_ids = [@exercise.id] @exercise_publish_count = get_user_permission_course(exercise_ids,Exercise::PUBLISHED).count #判断当前用户是否有试卷已发布的分班,用于显示立即截止/撤销发布 @exercise_unpublish_count = get_user_permission_course(exercise_ids,Exercise::UNPUBLISHED).count #判断当前用户是否有试卷未发布的分班,用户显示立即发布 @exercise_users_count = @exercise.exercise_users.commit_exercise_by_status(1).count #判断当前试卷是否有已提交的 # ## 需添加发送消息的接口,稍后添加 rescue Exception => e uid_logger_error(e.message) tip_exception("页面调用失败!") raise ActiveRecord::Rollback end end end #试卷的提交设置 def commit_setting ActiveRecord::Base.transaction do begin error_count = 0 # 判断循环里是否有已发布/已截止的,且时间更改了的分班。 # course_group_ids = @course.teacher_course_group_ids(current_user.id) #当前老师的班级id数组 course_group_ids = @course.charge_group_ids(current_user) #当前老师的班级id数组 exercise_status = @exercise.get_exercise_status(current_user) if exercise_status == Exercise::UNPUBLISHED && course_group_ids.size > 0 # 试卷未发布,且老师的分班大于1 ,才可以修改统一设置,否则按试卷默认的来处理 unified_setting = params[:unified_setting] else unified_setting = @exercise.unified_setting end show_statistic = params[:show_statistic] ? true :false exercise_time = params[:time].blank? ? -1 : params[:time] question_random = params[:question_random] ? true :false #问题是否随机,0为不随机,1为随机 choice_random = params[:choice_random] ? true :false score_open = params[:score_open] ? true : false #分数是否公开 answer_open = params[:answer_open] ? true : false #答案是否公开 # 统一设置或者分班为0,则更新试卷,并删除试卷分组 if unified_setting || (course_group_ids.size == 0) params_publish_time = params[:publish_time].blank? ? nil : params[:publish_time].to_time params_end_time = nil if params[:end_time].blank? if params_publish_time.present? params_end_time = params_publish_time + 30.days end else params_end_time = params[:end_time].to_time end if (exercise_status != Exercise::UNPUBLISHED) && (@exercise.publish_time != params_publish_time) normal_status(-1,"已发布/已截止,不允许修改发布时间") elsif params_publish_time.present? && params_end_time.present? && params_end_time < params_publish_time normal_status(-1,"截止时间不能小于发布时间") else #发布时间小于当前时间,则试卷显示为未发布,当截止时间大于当前时间,则显示为已截止 exercise_status_n = set_exercise_status(params_publish_time,params_end_time) exercise_params = { :unified_setting => unified_setting, :show_statistic => show_statistic, :time => exercise_time, :question_random => question_random, :choice_random => choice_random, :score_open => score_open, :answer_open => answer_open, :exercise_status => exercise_status_n, :publish_time => params_publish_time, :end_time => params_end_time } @exercise.update_attributes(exercise_params) @exercise.exercise_group_settings.destroy_all normal_status(0, "试卷设置成功!") end else params_times = params[:publish_time_groups] #分班返回的json数组{"publish_time_groups":[{"course_group_id":"1","publish_time":"xx","end_time":"xxx"}]} exercise_groups = @exercise.exercise_group_settings.find_in_exercise_group("course_id",@course.id) #试卷的全部分班信息 exercise_groups_ids = exercise_groups.pluck(:course_group_id) #问卷的全部分班id total_common = params_times.map{|k| k[:course_group_id]}.sum.uniq #传入的所有分组的分班id total_common_group = exercise_groups_ids & total_common #传入的分班与问卷已存在的分班的交集 old_exercise_groups = exercise_groups_ids - total_common_group #后来传入的分班里,没有了的班级,即需要删除 params_times.each do |t| course_id = t[:course_group_id] exercise_publish_time = t[:publish_time].present? ? t[:publish_time].to_time : nil exercise_end_time = nil if t[:end_time].blank? if exercise_publish_time.present? exercise_end_time = exercise_publish_time + 30.days end else exercise_end_time = t[:end_time].to_time end exercise_group = exercise_groups.find_in_exercise_group("course_group_id",course_id) #判断该分班是否存在 if exercise_group.present? && (exercise_group.first.publish_time < Time.now) && (exercise_publish_time != exercise_group.first.publish_time) error_count += 1 end if error_count == 0 common_group = exercise_groups_ids & course_id #传入的班级与问卷已存在的班级的交集,即表示已有分班的 new_group_ids = course_id - common_group #新传入的班级id if common_group.count > 0 #判断试卷的分班设置是否存在,存在则更新,负责则新建 ex_group_params = { :publish_time => exercise_publish_time, :end_time => exercise_end_time } exercise_group_sets = exercise_groups.find_in_exercise_group("course_group_id",common_group) the_group_setting = exercise_group_sets.first if the_group_setting.present? the_group_setting_status = set_exercise_status(the_group_setting.publish_time,the_group_setting.end_time) if the_group_setting_status == 2 ex_group_params = { :publish_time => the_group_setting.publish_time, :end_time => exercise_end_time } elsif the_group_setting_status == 3 ex_group_params = { :publish_time => the_group_setting.publish_time, :end_time => the_group_setting.end_time } end end exercise_group_sets.update_all(ex_group_params) end if new_group_ids.size > 0 new_group_ids.each do |c| exercise_group_params = { :exercise_id => @exercise.id, :course_group_id => c, :course_id => @course.id, :publish_time => exercise_publish_time, :end_time => exercise_end_time } new_exercise_group = ExerciseGroupSetting.new(exercise_group_params) new_exercise_group.save end end end end if error_count > 0 error_count == 0 normal_status(-1,"已发布/已截止的试卷不允许修改时间") else if old_exercise_groups.size > 0 old_all_ex_groups = exercise_groups.find_in_exercise_group("course_group_id",old_exercise_groups) old_all_ex_groups.destroy_all end #试卷更新为exercise_group_setting的发布时间最小,截止时间最大 e_time_present = exercise_groups.end_time_no_null.map(&:end_time) p_time_present = exercise_groups.publish_time_no_null.map(&:publish_time) e_time = e_time_present.size > 0 ? e_time_present.max : nil p_time = p_time_present.size > 0 ? p_time_present.min : nil exercise_status = 1 if p_time.nil? #发布时间为空,则表示问卷未发布 exercise_status = 1 elsif p_time.present? && e_time.present? exercise_status = set_exercise_status(p_time,e_time) end exercise_params = { :unified_setting => unified_setting, :show_statistic => show_statistic, :time => exercise_time, :question_random => question_random, :choice_random => choice_random, :score_open => score_open, :answer_open => answer_open, :exercise_status => exercise_status, :publish_time => p_time, :end_time => e_time } @exercise.update_attributes(exercise_params) if @exercise.exercise_status == Exercise::PUBLISHED if @exercise.course_acts.size == 0 @exercise.course_acts << CourseActivity.new(:user_id => @exercise.user_id,:course_id => @exercise.course_id) end end normal_status(0, "试卷设置成功!") end end rescue Exception => e uid_logger_error(e.message) tip_exception("提交出现错误!") raise ActiveRecord::Rollback end end end #我的题库 def my_exercises ActiveRecord::Base.transaction do begin ## 我的试卷题库 @current_user_exercises = current_user.exercise_banks.find_by_c_type("Exercise") if @current_user_exercises.present? if params[:search].present? search_type = params[:search].to_s.strip @current_user_exercises = @current_user_exercises.exercise_bank_search(search_type) end page = params[:page] || 1 limit = params[:limit] || 15 @my_exercises_count = @current_user_exercises.size @current_user_exercises = @current_user_exercises.page(page).per(limit) else @current_user_exercises = [] end rescue Exception => e uid_logger_error(e.message) tip_exception("页面调用失败!") raise ActiveRecord::Rollback end end end # 公共题库 def public_exercises ActiveRecord::Base.transaction do begin if current_user.is_certification_teacher @user_certification = 1 #用户已通过认证 @public_exercises = ExerciseBank.find_by_c_type("Exercise").public_exercises if @public_exercises.present? if params[:search].present? search_type = params[:search].to_s.strip @public_exercises = @public_exercises.exercise_bank_search(search_type) end page = params[:page] || 1 limit = params[:limit] || 15 @public_exercises_count = @public_exercises.size @public_exercises = @public_exercises.page(page).per(limit) else @public_exercises_count = 0 @public_exercises = [] end else @user_certification = 0 #用户未通过认证 @public_exercises_count = 0 @public_exercises = [] end rescue Exception => e uid_logger_error(e.message) tip_exception("题库调用失败!") raise ActiveRecord::Rollback end end end #立即发布的弹窗内容 def publish_modal ActiveRecord::Base.transaction do begin exercise_ids = params[:check_ids] if exercise_ids.count > 0 @course_groups = get_user_permission_course(exercise_ids,1) else @course_groups = [] end rescue Exception => e uid_logger_error(e.message) tip_exception("没有权限") raise ActiveRecord::Rollback end end end #首页批量或单独 立即发布,应是跳出弹窗,设置开始时间和截止时间。 def publish tip_exception("缺少截止时间参数") if params[:end_time].blank? tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now) tip_exception("截止时间不能晚于课堂结束时间") if @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) ActiveRecord::Base.transaction do begin check_ids = Exercise.where(id: params[:check_ids]) ex_end_time = params[:end_time].blank? ? Time.at(((1.month.since.to_i)/3600.0).ceil * 3600) : params[:end_time].to_time check_ids.each do |exercise| if exercise.present? if exercise.unified_setting ex_status = exercise.exercise_status #则为试卷的状态 else ex_status = exercise.exercise_group_settings.find_in_exercise_group("course_group_id",params[:group_ids]) .exercise_group_not_published.present? ? 1 : 0 end if ex_status == 1 #如果试卷存在已发布的,或者是已截止的,那么则直接跳过 g_course = params[:group_ids] #表示是否传入分班参数,如果传入分班的参数,那么试卷的统一设置需修改 if g_course user_course_groups = @course.charge_group_ids(current_user) if g_course.map(&:to_i).sort == user_course_groups.sort # 如果是设置为全部班级,则试卷不用分组,且试卷设定为统一设置,否则则分组设置 exercise.exercise_group_settings.destroy_all ex_unified = true e_time = ex_end_time else ex_unified = false g_course.each do |i| exercise_group_setting = exercise.exercise_group_settings.find_in_exercise_group("course_group_id",i).first #根据课堂分班的id,寻找试卷所在的班级 if exercise_group_setting #如果该试卷分组存在,则更新,否则新建 exercise_group_setting.update_attributes(publish_time:Time.now,end_time:ex_end_time) else p_course_group = { :exercise_id => exercise.id, :course_group_id => i, :course_id => exercise.course.id, :publish_time => Time.now, :end_time => ex_end_time, } new_exercise_group = exercise.exercise_group_settings.new p_course_group new_exercise_group.save end end # group_ids = params[:group_ids] e_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time).max end else exercise.exercise_group_settings.destroy_all ex_unified = true e_time = ex_end_time end ex_status = set_exercise_status(Time.now,e_time) exercise_params = { :publish_time => Time.now, :end_time => e_time, :exercise_status => ex_status, :unified_setting => ex_unified } exercise.update_attributes(exercise_params) if exercise.course_acts.size == 0 exercise.course_acts << CourseActivity.new(:user_id => exercise.user_id,:course_id => exercise.course_id) end ExercisePublishNotifyJob.perform_later(exercise.id, g_course) end end end normal_status(0, "试卷发布成功!") rescue Exception => e uid_logger_error(e.message) tip_exception("试卷发布失败") raise ActiveRecord::Rollback end end end #立即截止的弹窗内容 def end_modal ActiveRecord::Base.transaction do begin exercise_ids = params[:check_ids] if exercise_ids.count > 0 @course_groups = get_user_permission_course(exercise_ids,3) else @course_groups = [] end rescue Exception => e uid_logger_error(e.message) tip_exception("没有权限") raise ActiveRecord::Rollback end end end # 首页批量或单独 立即截止,截止时间为当前时间 def end_exercise ActiveRecord::Base.transaction do begin check_ids = Exercise.where(id:params[:check_ids]) course_students = @course.students #课堂的全部学生数 check_ids.each do |exercise| exercise_status= exercise.get_exercise_status(current_user) if exercise_status == Exercise::PUBLISHED #跳过已截止的或未发布的 g_course = params[:group_ids] if g_course.present? teacher_course_group_ids = @course.charge_group_ids(current_user) if g_course.map(&:to_i).sort == teacher_course_group_ids.sort #开始为统一设置 exercise.exercise_group_settings.destroy_all new_ex_status = set_exercise_status(exercise.publish_time,Time.now) exercise.update_attributes(:end_time => Time.now,:unified_setting => true,:exercise_status => new_ex_status) exercise_users = exercise.exercise_users else course_members_ids = course_students.course_find_by_ids("course_group_id",g_course).pluck(:user_id).uniq #该班级的全部学生 exercise_users = exercise.exercise_users.exercise_commit_users(course_members_ids) #参与答题的学生数 ex_group_setting = exercise.exercise_group_settings old_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id",g_course) #试卷的分组设置 left_course_groups = teacher_course_group_ids - g_course left_exercise_groups = ex_group_setting.find_in_exercise_group("course_group_id",left_course_groups) if left_exercise_groups.blank? && exercise.unified_setting if left_course_groups.size > 0 #开始为统一设置,但是立即截止为分班。则创建没有立即截止的班级的exercise_group_setting left_course_groups.each do |g| ex_group_options = { :exercise_id => exercise.id, :course_group_id => g, :course_id => @course.id, :publish_time => exercise.publish_time, :end_time => exercise.end_time } ExerciseGroupSetting.create(ex_group_options) end end end if old_exercise_groups.present? old_exercise_groups.update_all(:end_time => Time.now) else g_course.each do |g| ex_group_options = { :exercise_id => exercise.id, :course_group_id => g, :course_id => @course.id, :publish_time => exercise.publish_time, :end_time => Time.now } ExerciseGroupSetting.create(ex_group_options) end end new_end_time = exercise.exercise_group_settings.end_time_no_null.map(&:end_time) # 试卷结束时间不为空的 new_end_time_s = new_end_time.count > 0 ? new_end_time.max : Time.now new_ex_status = set_exercise_status(exercise.publish_time,new_end_time_s) exercise.update_attributes(:end_time => new_end_time_s,:exercise_status => new_ex_status,:unified_setting => false) end else exercise_users = exercise.exercise_users exercise.update_attributes(:exercise_status => 3, :end_time => Time.now,:unified_setting => true) end exercise_users.each do |user| if user.commit_status == 0 && user.start_at.present? objective_score = calculate_student_score(exercise,user.user)[:total_score] user_sub_score = user.subjective_score subjective_score = user_sub_score < 0.0 ? 0.0 : user_sub_score total_score = objective_score + subjective_score commit_option = { :status => 1, :commit_status => 1, :end_at => Time.now, :objective_score => objective_score, :score => total_score, :subjective_score => user_sub_score } user.update_attributes(commit_option) end end end end normal_status(0, "试卷截止成功!") rescue Exception => e uid_logger_error(e.message) tip_exception("立即截止失败!") raise ActiveRecord::Rollback end end end #学生撤销回答 def cancel_exercise ActiveRecord::Base.transaction do begin ex_question_ids = @exercise.exercise_questions.pluck(:id) exercise_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first if exercise_user.present? if exercise_user.commit_status == 1 && @exercise.get_exercise_status(current_user) == Exercise::PUBLISHED #用户已提交且试卷提交中 if @exercise.time == -1 || ((Time.now.to_i - exercise_user.start_at.to_i) < @exercise.time.to_i * 60) exercise_user.update_attributes(:score => nil, :end_at => nil, :status => nil, :commit_status => 0, :objective_score => 0.0, :subjective_score => -1.0) exercise_user.user.exercise_shixun_answers.search_shixun_answers("exercise_question_id",ex_question_ids).destroy_all exercise_answers = exercise_user.user.exercise_answers.search_answer_users("exercise_question_id",ex_question_ids) exercise_answers.update_all(:score => -1.0) all_answer_comment = ExerciseAnswerComment.search_answer_comments("exercise_question_id",ex_question_ids) .search_answer_comments("exercise_answer_id",exercise_answers.pluck(:id)) all_answer_comment.destroy_all normal_status(0,"撤销回答成功") else normal_status(-1,"用户答题时间已到") end else normal_status(-1,"用户未提交/试卷不是提交中") end else normal_status(-1,"当前用户未答题") end rescue Exception => e uid_logger_error(e.message) tip_exception("页面调用失败") raise ActiveRecord::Rollback end end end #打回重做modal def redo_modal ActiveRecord::Base.transaction do begin #搜索 if params[:realname].present? search_name = params[:realname] #搜索用户的nickname,如果存在则返回,否则继续查询用户的真实姓名或学生号 @exercise_users = @exercise_users.includes(:user).where("LOWER(concat(users.lastname, users.firstname)) like ?", "%#{search_name}%") end if params[:student_id].present? search_st_id = params[:student_id].to_i @exercise_users = @exercise_users.includes(user: [:user_extension]) .where('user_extensions.student_id like ?',"%#{search_st_id}%") end sort = params[:sort] ? params[:sort] : "asc" @exercise_users = @exercise_users.order("score #{sort}") @exercise_users_size = @exercise_users.size # 分页 page = params[:page] || 1 limit = params[:limit] || 15 @exercise_users = @exercise_users.page(page).per(limit) rescue Exception => e uid_logger_error(e.message) tip_exception("没有权限") raise ActiveRecord::Rollback end end end #打回重做确认 def redo_exercise ActiveRecord::Base.transaction do begin user_ids = params[:user_ids] if user_ids.present? redo_option = { :score => 0.0, :start_at => nil, :end_at => nil, :status => nil, :commit_status => 0, :objective_score => 0.0, :subjective_score => -1.0 } redo_exercise_users = @exercise_users.exercise_commit_users(user_ids) redo_exercise_users.update_all(redo_option) exercise_question_ids = @exercise.exercise_questions.pluck(:id).uniq ExerciseAnswer.search_answer_users("user_id",user_ids) .search_answer_users("exercise_question_id",exercise_question_ids).destroy_all ExerciseShixunAnswer.search_shixun_answers("user_id",user_ids) .search_shixun_answers("exercise_question_id",exercise_question_ids).destroy_all normal_status(0,"已成功打回重做!") else normal_status(-1,"请选择学生!") end rescue Exception => e uid_logger_error(e.message) tip_exception("没有权限") raise ActiveRecord::Rollback end end end #学生开始答题页面 def start_answer ActiveRecord::Base.transaction do begin ex_users_current = ExerciseUser.where(user_id:@exercise_current_user_id,exercise_id:@exercise.id) #不能用@exercise.exercise_users,因为exercise_users删除时,只是状态改变,未删除 @exercise_user_current = ex_users_current&.first if ex_users_current.exists? if @exercise_user_current.start_at.blank? @exercise_user_current.update_attribute("start_at",Time.now) end else if @user_course_identity > Course::ASSISTANT_PROFESSOR #当为老师的时候,不创建exercise_user表,理论上老师是不能进入答题的 exercise_user_params = { :user_id => @exercise_current_user_id, :exercise_id => @exercise.id, :start_at => Time.now } exercise_user_current = ExerciseUser.new(exercise_user_params) exercise_user_current.save end end @t_user_exercise_status = @exercise.get_exercise_status(current_user) @user_left_time = nil if @user_course_identity < Course::STUDENT || (@t_user_exercise_status == 3) || (ex_users_current.exists? && @exercise_user_current.commit_status == 1) @user_exercise_status = 1 #当前用户为老师/试卷已截止/试卷已提交不可编辑 else @user_left_time = get_exercise_left_time(@exercise,current_user) @user_exercise_status = 0 #可编辑 end @exercise_questions = @exercise.exercise_questions if @exercise.question_random @exercise_questions = @exercise_questions.order("RAND()") else @exercise_questions = @exercise_questions.order("question_number ASC") end # 判断问题是否已回答还是未回答 @exercise_questions = @exercise_questions.includes(:exercise_shixun_challenges, :exercise_shixun_answers, :exercise_answers, :exercise_standard_answers) if @t_user_exercise_status == Exercise::DEADLINE get_each_student_exercise(@exercise.id,@exercise_questions,@exercise_current_user_id) end get_user_answer_status(@exercise_questions,@exercise_current_user_id,@exercise,@t_user_exercise_status) rescue Exception => e uid_logger_error(e.message) tip_exception("页面调用失败!") raise ActiveRecord::Rollback end end end #提交试卷前的弹窗 def begin_commit ActiveRecord::Base.transaction do begin if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 @exercise_questions = @exercise.exercise_questions @shixun_undo = 0 @ques_undo = 0 ex_answer_time = @exercise.time.to_i @ex_end_time = @exercise.get_exercise_end_time(current_user.id) if ex_answer_time > 0 exercise_end_time = @exercise.exercise_users.exercise_commit_users(current_user.id) if exercise_end_time.present? ex_end_times = exercise_end_time.first.start_at.nil? ? Time.now : exercise_end_time.first.start_at @ex_end_time = ex_end_times + ex_answer_time.minutes end end @exercise_questions.each do |q| if q.question_type == Exercise::PRACTICAL #当为实训题时 user_myshixun = q.shixun.myshixuns.search_myshixun_user(current_user.id) if user_myshixun.blank? || user_myshixun.first.status != Exercise::UNPUBLISHED #当前用户的实训是否做完 @shixun_undo += 1 end else ques_vote = q.exercise_answers.search_exercise_answer("user_id",current_user.id) if ques_vote.blank? @ques_undo += 1 end end end end rescue Exception => e uid_logger_error(e.message) tip_exception("试卷提交失败!") raise ActiveRecord::Rollback end end end # 学生提交试卷 def commit_exercise ActiveRecord::Base.transaction do begin if @user_course_identity > Course::ASSISTANT_PROFESSOR #为学生时 objective_score = calculate_student_score(@exercise,current_user)[:total_score] subjective_score = @answer_committed_user.subjective_score total_score_subjective_score = subjective_score < 0.0 ? 0.0 : subjective_score total_score = objective_score + total_score_subjective_score commit_option = { :status => 1, :commit_status => 1, :end_at => Time.now, :objective_score => objective_score, :score => total_score, :subjective_score => subjective_score } @answer_committed_user.update_attributes(commit_option) normal_status(0,"试卷提交成功!") end rescue Exception => e uid_logger_error(e.message) tip_exception("试卷提交失败!") raise ActiveRecord::Rollback end end end #教师评阅试卷 及学生查看试卷 def review_exercise ActiveRecord::Base.transaction do begin # 1 老师权限,0 学生权限 @is_teacher_or = (@user_course_identity < Course::STUDENT) ? 1 : 0 @student_status = 2 @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges,:exercise_standard_answers,:exercise_answers,:exercise_shixun_answers).order("question_number ASC") @question_status = [] get_exercise_status = @exercise.get_exercise_status(current_user) #当前用户的试卷状态 @ex_answer_status = @exercise.get_exercise_status(@ex_user&.user) #当前试卷用户的试卷状态 if @ex_user.present? && @is_teacher_or == 0 if get_exercise_status == Exercise::PUBLISHED #当前用户已提交,且试卷未截止 if @ex_user.commit_status == 0 #学生未提交,且当前为学生 @student_status = 0 else @student_status = 1 get_user_answer_status(@exercise_questions,@exercise_current_user_id,@exercise,get_exercise_status) end end end if @student_status == 2 get_each_student_exercise(@exercise.id,@exercise_questions,@exercise_current_user_id) end rescue Exception => e uid_logger_error(e.message) tip_exception("没有权限") raise ActiveRecord::Rollback end end end #答题列表 def exercise_lists ActiveRecord::Base.transaction do begin @current_user_id = current_user.id exercise_ids = [@exercise.id] @exercise_status = @exercise.get_exercise_status(current_user) @course_all_members = @course.students @c_group_counts = @course.course_groups_count question_types = @exercise.exercise_questions.pluck(:question_type).uniq @exercise_publish_count = get_user_permission_course(exercise_ids,Exercise::PUBLISHED).count #判断是否有已发布的分班 @exercise_unpublish_count = get_user_permission_course(exercise_ids,Exercise::UNPUBLISHED).count #判断是否有未发布的分班 if (question_types.size > 1) && question_types.include?(Exercise::SUBJECTIVE) #是否包含主观题,或者是否大于1 @subjective_type = 1 else @subjective_type = 0 end #初始化值 @exercise_users_list = [] #答题用户列表 @exercise_course_groups = [] #当前用户有权限的班级 @exercise_unanswers = 0 # 未答用户数 @exercise_answers = 0 #已答用户数 @exercise_users_count = 0 #全部用户数 @teacher_review_count = 0 #已评数 @teacher_unreview_count = 0 #未评数 #试卷的答题列表页的显示用户 if @user_course_identity < Course::STUDENT #当前为老师,而且老师只能查看自己班级的/课堂的试卷 @exercise_current_user_status = 0 unless @exercise_status == Exercise::UNPUBLISHED ex_common_ids = @exercise.common_published_ids(current_user.id) @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) @exercise_users_list = @exercise.all_exercise_users(current_user.id) #当前老师所在班级的全部学生 get_exercise_answers(@exercise_users_list, @exercise_status) end else #当前为学生或者有过答题的 @ex_user_end_time = @exercise.get_exercise_end_time(current_user.id) #当前用户所看到的剩余时间 @exercise_all_users = @exercise.get_stu_exercise_users get_exercise_answers(@exercise_all_users, @exercise_status) # 未答和已答的 exercise_current_user = @exercise_all_users.exercise_commit_users(current_user.id) if exercise_current_user.exists? #表示为课堂学生或已回答的 @exercise_current_user_status = 1 if @exercise.score_open && @exercise_status == Exercise::DEADLINE #勾选了成绩公开且试卷已截止的 all_user_ids = @exercise_all_users.pluck(:user_id) all_user_ids.delete(current_user.id) #删除了当前用户的ID @exercise_users_list = @exercise_all_users.exercise_commit_users(all_user_ids).distinct @current_user_ex_answers = exercise_current_user #当前用户的回答 else @exercise_users_list = exercise_current_user end else #表示为未回答的,或未非课堂成员的 @exercise_current_user_status = 2 #当前用户非课堂成员 end end if @exercise_unanswers < 0 @exercise_unanswers = 0 end #筛选/分类,排序 order = params[:order] if @exercise_users_list.present? && @exercise_users_list.size > 0 @exercise_users_count = @exercise_users_list.size #当前显示的全部成员数量 teacher_reviews = @exercise_users_list.exercise_review teacher_unreviews = @exercise_users_list.exercise_unreview @teacher_review_count = teacher_reviews.size #已评阅 @teacher_unreview_count = teacher_unreviews.size #未评阅 #是否评阅 if params[:review].present? review_type = params[:review].first.to_i #已评,则数据为1,未评,则数据为0,前端传过来的为数组 if review_type == 1 @exercise_users_list = teacher_reviews else @exercise_users_list = teacher_unreviews end end #答题状态的选择 if params[:commit_status].present? choose_type = params[:commit_status] @exercise_users_list = @exercise_users_list.commit_exercise_by_status(choose_type) end #班级的选择 if params[:exercise_group_id].present? group_id = params[:exercise_group_id] exercise_students = @course_all_members.course_find_by_ids("course_group_id",group_id) #试卷所分班的全部人数 user_ids = exercise_students.pluck(:user_id).reject(&:blank?) @exercise_users_list = @exercise_users_list.exercise_commit_users(user_ids) end #搜索 if params[:search].present? @exercise_users_list = @exercise_users_list.joins(user: :user_extension).where("CONCAT(lastname, firstname) like ? OR student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%") end exercise_user_joins = @exercise_users_list.joins(user: :user_extension) if order == "student_id" @exercise_users_list = exercise_user_joins.order("user_extensions.student_id DESC") elsif order == "score" @exercise_users_list = exercise_user_joins.order("#{order} DESC") else @exercise_users_list = exercise_user_joins.order("end_at DESC, start_at DESC") end @export_ex_users = @exercise_users_list @exercise_users_size = @exercise_users_list.size # 分页 @page = params[:page] || 1 @limit = params[:limit] || 20 @exercise_users_list = @exercise_users_list.page(@page).per(@limit) else @exercise_users_list = [] @export_ex_users = @exercise_users_list @exercise_users_size = 0 end if params[:format] == "xlsx" if @user_course_identity > Course::ASSISTANT_PROFESSOR tip_exception(403,"无权限操作") elsif @exercise_status == Exercise::UNPUBLISHED normal_status(-1,"试卷未发布") elsif (@exercise_users_size == 0) || ( @export_ex_users&.exercise_user_committed.size == 0) normal_status(-1,"暂无用户提交") else respond_to do |format| format.xlsx{ get_export_users(@exercise,@course,@export_ex_users) exercise_export_name_ = "#{current_user.real_name}_#{@course.name}_#{@exercise.exercise_name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" render xlsx: "#{exercise_export_name_.strip}",template: "exercises/exercise_lists.xlsx.axlsx",locals: {table_columns:@table_columns,exercise_users:@user_columns} } end end end rescue Exception => e uid_logger_error(e.message) tip_exception("页面调用失败!") raise ActiveRecord::Rollback end end end #导出空白试卷 def export_exercise @request_url = request.base_url @exercise_questions = @exercise.exercise_questions.includes(:exercise_choices).order("question_number ASC") filename_ = "#{@exercise.user.real_name}_#{@course.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}.pdf" stylesheets = "#{Rails.root}/app/templates/exercise_export/exercise_export.css" render pdf: 'exercise_export/blank_exercise', filename: filename_, stylesheets: stylesheets end #空白试卷预览页面,仅供测试使用,无其他任何用途 # def blank_exercise # ActiveRecord::Base.transaction do # begin # @exercise_questions = @exercise.exercise_questions.order("question_number ASC") # challenge_ids = @exercise_questions.joins(:exercise_shixun_challenges).pluck("exercise_shixun_challenges.challenge_id") # get_each_student_exercise(@exercise.id,@exercise_questions,31798) # @games = @exercise_user.user.games.ch_games(challenge_ids) # respond_to do |format| # format.html # end # rescue Exception => e # uid_logger_error(e.message) # tip_exception("没有权限") # raise ActiveRecord::Rollback # end # end # end #学生的统计结果 def exercise_result ActiveRecord::Base.transaction do begin exercise_ids = [@exercise.id] @exercise_publish_count = get_user_permission_course(exercise_ids,Exercise::PUBLISHED).size #判断是否有已发布的分班 @exercise_unpublish_count = get_user_permission_course(exercise_ids,Exercise::UNPUBLISHED).size #判断是否有未发布的分班 @course_all_members = @course.students #课堂的全部学生 @exercise_all_users = @exercise.exercise_users ex_common_ids = @exercise.common_published_ids(current_user.id) @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) #班级的选择 if params[:exercise_group_id].present? group_id = params[:exercise_group_id] exercise_students = @course_all_members.course_find_by_ids("course_group_id",group_id) # 试卷所分班的全部人数 user_ids = exercise_students.pluck(:user_id).reject(&:blank?) @exercise_all_users = @exercise.exercise_users.exercise_commit_users(user_ids) @course_all_members_count = @exercise_all_users.size else @exercise_users_list = @exercise.all_exercise_users(current_user.id) @course_all_members_count = @exercise_users_list.size end @exercise_commit_users = @exercise_all_users.commit_exercise_by_status(1) #试卷的已提交用户 @exercise_commit_user_ids = @exercise_commit_users.pluck(:user_id).uniq #已提交试卷的全部用户id @exercise_commit_user_counts = @exercise_commit_users.size #试卷的已提交用户人数 @exercise_status = @exercise.get_exercise_status(current_user) #提交率 if @course_all_members_count == 0 commit_percent = 0.00 min_score = 0.0 max_score = 0.0 average_score = 0.0 fail_counts = 0 pass_counts = 0 good_counts = 0 best_counts = 0 else commit_percent = (@exercise_commit_user_counts / @course_all_members_count.to_f).round(3) exercise_scores = @exercise_commit_users.pluck(:score).reject(&:blank?) min_score = exercise_scores.min.present? ? exercise_scores.min : 0.0 max_score = exercise_scores.max.present? ? exercise_scores.max : 0.0 total_score = exercise_scores.sum.present? ? exercise_scores.sum : 0.0 average_score = @exercise_commit_user_counts > 0 ? (total_score / @exercise_commit_user_counts).round(1) : 0.0 fail_counts = exercise_scores.count{|a| a < 60.0} pass_counts = exercise_scores.count{|a| a < 70.0 && a >= 60.0} good_counts = exercise_scores.count{|a| a < 90.0 && a >= 70.0} best_counts = exercise_scores.count{|a| a >= 90.0 && a <= 100.0} end @counts_array = { :commit_percent => commit_percent, :min_score => min_score.to_s, :max_score => max_score.to_s, :average_score => average_score.to_s, :fail_counts => fail_counts, :pass_counts => pass_counts, :good_counts => good_counts, :best_counts => best_counts, } @exercise_questions = @exercise.exercise_questions&.includes(:exercise_choices,:exercise_answers,:exercise_standard_answers,:exercise_shixun_challenges,:exercise_shixun_answers) @paging_type = "percent" # 按题型排序 if params[:sort].present? @paging_type = params[:sort].to_s end ques_result_all = exercise_commit_result(@exercise_questions,@exercise_commit_user_ids) if @paging_type == "percent" @question_result_hash = ques_result_all.sort_by{|s| s[:percent]} else @question_result_hash = ques_result_all.sort_by{|s| s[:"#{@paging_type}"]} end @exercise_questions_count = @exercise_questions.size @page = params[:page] || 1 @limit = params[:limit] || 10 @question_result_hash = Kaminari.paginate_array(@question_result_hash).page(@page).per(@limit) rescue Exception => e uid_logger_error(e.message) tip_exception("没有权限") raise ActiveRecord::Rollback end end end private def exercise_params params.require(:exercise).permit(:exercise_name, :exercise_description, :course_id, :exercise_status, :user_id, :time, :publish_time, :end_time, :show_result, :question_random, :choice_random, :is_public, :score_open, :answer_open, :exercise_bank_id, :unified_setting, :show_statistic) end def is_course_teacher unless @user_course_identity < Course::STUDENT #为老师/助教/管理员 normal_status(403, "...") end end #检查传入的参数内容是否符合 def validates_exercise_params normal_status(-1, "试卷标题不能为空!") if params[:exercise_name].blank? normal_status(-1, "试卷标题不能超过60个字符") if (params[:exercise_name].length > 60) normal_status(-1, "试卷须知不能超过100个字符") if (params[:exercise_description].present? && params[:exercise_description].length > 100) end #判断设置的时间是否合理 def validate_publish_time # 截止时间存在,且截止时间必须大于当前时间或发布时间 unified_setting = params[:unified_setting] publish_course = params[:publish_time_groups] if @course.is_end normal_status(-1,"课堂已结束不能再修改") elsif unified_setting ex_group_settings = @exercise.exercise_group_settings if ex_group_settings.present? p_time_present = ex_group_settings.publish_time_no_null.map(&:publish_time).min if p_time_present < Time.now normal_status(-1,"设置失败,存在已发布的分班") end elsif params[:publish_time].blank? normal_status(-1,"发布时间不允许为空") end elsif unified_setting.present? && !unified_setting #非统一设置,分班不能为空 if publish_course.present? course_ids = publish_course.map{|a| a[:course_group_id]}.sum publish_t = publish_course.map{|a| a[:publish_time]} if course_ids.include?(nil) || course_ids.count == 0 normal_status(-1,"请选择分班") elsif publish_t.include?(nil) || publish_t.count == 0 normal_status(-1,"发布时间不允许为空") end else normal_status(-1,"请选择分班") end end end def get_exercise @exercise = Exercise.find_by(id:params[:id]) if @exercise.blank? normal_status(404,"试卷不存在") else @course = @exercise.course normal_status(404,"课堂不存在") if @course.blank? end end def get_exercise_question_counts #获取试卷的问题数及总分数 exercise_questions = @exercise.exercise_questions @exercise_ques_count = exercise_questions.size # 全部的题目数 @exercise_ques_scores = exercise_questions.pluck(:question_score).sum #单选题的数量及分数 exercise_single_ques = exercise_questions.find_by_custom("question_type",Exercise::SINGLE) @exercise_single_ques_count = exercise_single_ques.size @exercise_single_ques_scores = exercise_single_ques.pluck(:question_score).sum #多选题的数量及分数 exercise_double_ques = exercise_questions.find_by_custom("question_type",Exercise::MULTIPLE) @exercise_double_ques_count = exercise_double_ques.size @exercise_double_ques_scores = exercise_double_ques.pluck(:question_score).sum # 判断题数量及分数 exercise_ques_judge = exercise_questions.find_by_custom("question_type",Exercise::JUDGMENT) @exercise_ques_judge_count = exercise_ques_judge.size @exercise_ques_judge_scores = exercise_ques_judge.pluck(:question_score).sum #填空题数量及分数 exercise_ques_null = exercise_questions.find_by_custom("question_type",Exercise::COMPLETION) @exercise_ques_null_count = exercise_ques_null.size @exercise_ques_null_scores = exercise_ques_null.pluck(:question_score).sum #简答题数量及分数 exercise_ques_main = exercise_questions.find_by_custom("question_type",Exercise::SUBJECTIVE) @exercise_ques_main_count = exercise_ques_main.size @exercise_ques_main_scores = exercise_ques_main.pluck(:question_score).sum #实训题数量及分数 exercise_ques_shixun = exercise_questions.find_by_custom("question_type",Exercise::PRACTICAL) @exercise_ques_shixun_count = exercise_ques_shixun.size @exercise_ques_shixun_scores = exercise_ques_shixun.pluck(:question_score).sum @exercise_questions = @exercise_questions&.includes(:exercise_choices,:exercise_shixun_challenges,:exercise_answers,:exercise_shixun_answers,:exercise_answer_comments,:exercise_standard_answers) end #获取用户有权限的分班 def get_user_permission_course(exercise_ids,status) exercise_status = status.to_i #传入的试卷发布状态 unpublish_group = [] course_groups = [] user_groups_id = @course.charge_group_ids(current_user) exercises_all = Exercise.includes(:exercise_group_settings).where(id:exercise_ids) exercises_all.each do |exercise| if exercise.present? if exercise.unified_setting #统一设置只有两种情况,全部发布,全部截止 exercise_user_status = exercise.get_exercise_status(current_user) #当前用户的能看到的试卷 if (exercise_user_status == exercise_status) || exercise_status == Exercise::DEADLINE #未发布的情况 unpublish_group = unpublish_group + user_groups_id end else ex_all_group_settings = exercise.exercise_group_settings ex_group_settings = ex_all_group_settings.exercise_group_published.pluck(:course_group_id).uniq #问卷设置的班级 if exercise_status == Exercise::UNPUBLISHED unpublish_group = user_groups_id - ex_group_settings elsif exercise_status == Exercise::DEADLINE ex_ended_groups = ex_all_group_settings.exercise_group_ended.pluck(:course_group_id).uniq ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 unpublish_group = unpublish_group + ex_and_user - ex_ended_groups #已发布的全部班级减去截止的全部班级 else ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 unpublish_group = unpublish_group + ex_and_user end end end end unpublish_group = unpublish_group.uniq if unpublish_group.count > 0 course_groups = CourseGroup.by_group_ids(unpublish_group) end course_groups end def set_exercise_status(publish_time,end_time) time_now_i = Time.now if publish_time.present? && (publish_time <= time_now_i) && (end_time > time_now_i) 2 elsif publish_time.nil? || (publish_time.present? && publish_time > time_now_i) 1 elsif end_time.present? && (end_time <= time_now_i) 3 elsif end_time.present? && publish_time.present? && (end_time < publish_time) normal_status(-1,"时间设置错误!") else 1 end end def check_course_public unless @course.is_public == 1 # 0为私有,1为公开 normal_status(403,"...") end end def check_user_id_start_answer #判断用户在开始答题时,是否有用户id传入,如果为老师,则id必需,否则为当前用户的id user_login = params[:login] # exercise_current_user_id = params[:user_id] if user_login.blank? && @user_course_identity < Course::STUDENT #id不存在,且当前为老师/管理员等 normal_status(-1,"请输入学生登陆名!") else @ex_answerer = User.find_by(login: user_login) #回答者 if @ex_answerer.blank? normal_status(404,"答题用户不存在") else @exercise_current_user_id = @ex_answerer.id || current_user.id end end end ## 判断开始答题页面的用户权限 def check_user_on_answer if @user_course_identity == Course::STUDENT && @exercise.get_exercise_status(current_user) == Exercise::UNPUBLISHED #试卷未发布,且当前用户不为老师/管理员 normal_status(-1, "未发布试卷!") elsif @user_course_identity > Course::STUDENT && (!@exercise.is_public || (@exercise.is_public && !@exercise.unified_setting)) ##不为课堂成员,且试卷不为公开的,或试卷公开,但不是统一设置的 normal_status(-1, "试卷暂未公开!") end end def check_exercise_time @answer_committed_user = @exercise.exercise_users.exercise_commit_users(current_user.id)&.first if @answer_committed_user.blank? normal_status(404,"答题用户不存在") end end #打回重做时的初步判断 def check_exercise_status @exercise_users = @exercise.all_exercise_users(current_user.id).commit_exercise_by_status(1) #当前教师所在分班的全部已提交的学生数 if @exercise.get_exercise_status(current_user) != Exercise::PUBLISHED normal_status(-1,"非提交中的试卷不允许打回重做!") elsif @exercise_users.count < 1 normal_status(-1,"暂无人提交试卷!") end end #查看试题页面,当为学生时,除非试卷已截止,或已提交才可以查看 def check_exercise_is_end ex_status = @exercise.get_exercise_status(current_user) @ex_user = @exercise.exercise_users.find_by(user_id:@exercise_current_user_id) #该试卷的回答者 if @user_course_identity > Course::ASSISTANT_PROFESSOR if ex_status == Exercise::UNPUBLISHED normal_status(-1,"试卷未发布") elsif @ex_user.present? && @ex_user.commit_status == 0 normal_status(-1,"试卷未提交") elsif params[:user_id].present? && current_user.id != params[:user_id] normal_status(-1,"不能查看他人的试卷") end end end #查看试卷是否选择为公开统计 def check_exercise_public if @user_course_identity > Course::ASSISTANT_PROFESSOR #当前为学生,试卷公开统计,且已截止,且已提交 ex_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first unless @exercise.get_exercise_status(current_user) == Exercise::DEADLINE && ex_user.present? && ex_user.commit_status == 1 && @exercise.show_statistic normal_status(-1,"学生暂不能查看") end end end def get_left_banner_id left_banner_content = @course.course_modules.search_by_module_type("exercise") if left_banner_content.present? @left_banner_id = left_banner_content.first.id @left_banner_name = left_banner_content.first.module_name else normal_status(404,"左侧导航不存在") end end def get_user_answer_status(exercise_questions,user_id,exercise,exercise_user_status) @question_status = [] @exercise_all_questions = [] ex_question_random = exercise.question_random question_answered = 0 exercise_questions.each_with_index do |q,index| if ex_question_random && exercise_user_status != Exercise::DEADLINE ques_number = index + 1 else ques_number = q.question_number end if q.question_type != Exercise::PRACTICAL ques_vote = q.exercise_answers.search_exercise_answer("user_id",user_id) else ques_vote = q.exercise_shixun_answers.search_shixun_answers("user_id",user_id) end ques_status = 0 if ques_vote.present? if q.question_type == Exercise::PRACTICAL if ques_vote.pluck(:exercise_shixun_challenge_id).sort == q.exercise_shixun_challenges.pluck(:id).sort #用户的总得分等于问题的分数 ques_status = 1 #全部回答了,才算已答 question_answered += 1 end else #其他题目,需回答的有内容,才会为已答,否则如内容为空,视为未答 vote_answer_id = ques_vote.pluck(:exercise_choice_id).reject(&:blank?) vote_text_count = ques_vote.pluck(:answer_text).reject(&:blank?).size if q.question_type <= Exercise::JUDGMENT #选择题和判断题的时候,需要有选项,才算回答 if vote_answer_id.size > 0 ques_status = 1 question_answered += 1 end elsif q.question_type == Exercise::COMPLETION #填空题的时候,需要有选项和内容,才算回答 if vote_answer_id.uniq.sort == q.exercise_standard_answers.pluck(:exercise_choice_id).uniq.sort ques_status = 1 question_answered += 1 end else if vote_text_count > 0 #主观题,必选有内容,才算回答 ques_status = 1 question_answered += 1 end end end end question_status = { :ques_id => q.id, :ques_number => ques_number, #仅问题的显示位置变化,但是问题的question_number 不会变化,与之相关的choice/standard_answer/answer不会变化 :ques_status => ques_status, } question_options = { :question => q, :ques_number => ques_number, } @question_status = @question_status.push(question_status).sort_by {|k| k[:ques_number]} @exercise_all_questions = @exercise_all_questions.push(question_options).sort_by {|k| k[:ques_number]} end end #下一步也有check_on_users再进行判断 def only_student_in if @user_course_identity < Course::STUDENT normal_status(-1,"老师身份不允许进入") end end #判断实训是否已选择 def commit_shixun_present question_shixun_ids = @exercise.exercise_questions.pluck(:shixun_id).reject(&:blank?) shixun_id = params[:shixun_id] @shixun = Shixun.find_by(id: shixun_id) if shixun_id.present? && question_shixun_ids.include?(shixun_id) normal_status(-1,"该实训已选择!") elsif @shixun.blank? normal_status(-1,"该实训不存在!") end end end