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 ) . count #已提交的用户数
end
@ex_status = @exercise . get_exercise_status ( current_user )
exercise_id_array = [ @exercise . id ]
@exercise_publish_count = get_user_permission_course ( exercise_id_array , 2 ) . count #是否存在已发布的
@exercise_unpublish_count = get_user_permission_course ( exercise_id_array , 1 ) . count #是否存在未发布的
if ( @exercise_publish_count == 0 ) && ( @exercise_unpublish_count == 0 ) #即表示没有分班
if @ex_status == 1
@exercise_unpublish_count = 1 #试卷未发布,且课堂没有分班的时候
elsif @ex_status == 2
@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 != 5 #不为实训题时,试卷选项加入试题答案库
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 , 2 ) . count #判断当前用户是否有试卷已发布的分班,用于显示立即截止/撤销发布
@exercise_unpublish_count = get_user_permission_course ( exercise_ids , 1 ) . 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 == 1 && 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 != 1 ) && ( @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_end_time = t[:end_time].present? ? t[:end_time].to_time : nil
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 == 2
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
ActiveRecord :: Base . transaction do
begin
check_ids = Exercise . where ( id : params [ :check_ids ] )
ex_end_time = params [ :end_time ] || Time . at ( ( ( 1 . month . since . to_i ) / 3600 . 0 ) . ceil * 3600 )
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
# course_groups = @course.teacher_course_groups.get_user_groups(current_user.id)
#
# if course_groups.blank?
# user_course_groups = @course.course_groups.present? ? @course.course_groups.pluck(:id) : []
# else
# user_course_groups = course_groups.pluck(:course_group_id).reject(&:blank?).uniq
# end
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
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 ]
end
else
exercise . exercise_group_settings . destroy_all
ex_unified = true
end
if exercise . end_time . blank?
e_time = ex_end_time
elsif exercise . exercise_group_settings . end_time_no_null . count > 0 # 该试卷分组有结束时间为空的
e_time = exercise . exercise_group_settings . end_time_no_null . map ( & :end_time ) . max
else
e_time = exercise . 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 , group_ids )
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 == 2 #跳过已截止的或未发布的
g_course = params [ :group_ids ]
if g_course . present?
# user_course_groups= @course.teacher_course_groups.get_user_groups(current_user.id)
# if user_course_groups.present?
# teacher_course_group_ids = user_course_groups.pluck(:course_group_id)
# else
# teacher_course_group_ids = @course.course_groups.pluck(:id)
# end
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 ) == 2 #用户已提交且试卷提交中
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
@exercise_user_current = @exercise . exercise_users . exercise_commit_users ( @exercise_current_user_id ) & . first
if @exercise_user_current . blank?
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
else
if @exercise_user_current . start_at . blank?
@exercise_user_current . update_attribute ( " start_at " , Time . now )
end
end
# ex_time = @exercise.time
# if ex_time > 0
# time_mill = ex_time * 60 #转为秒
# exercise_end_time = @exercise.end_time.present? ? @exercise.end_time.to_i : 0
# exercise_user_start = @exercise_user_current.present? ? @exercise_user_current.start_at.to_i : 0
# if (exercise_user_start + time_mill) > exercise_end_time
# time_mill = exercise_end_time - exercise_user_start #如果开始答题时间加试卷的限时长大于试卷的截止时间,则以试卷的截止时间到开始答题时间为试卷的限时
# end
# exercise_user_left_time = Time.now.to_i - exercise_user_start #用户已回答的时间
# @user_left_time = (time_mill < exercise_user_left_time) ? nil : (time_mill - exercise_user_left_time) #当前用户对试卷的回答剩余时间
# 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 ) ||
( @exercise_user_current . present? && @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 . includes ( :exercise_shixun_challenges ,
:exercise_shixun_answers ,
:exercise_answers ,
:exercise_standard_answers )
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_stand_answers , :exercise_answers , :exercise_shixun_answers )
if @t_user_exercise_status == 3
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 == 5 #当为实训题时
user_myshixun = q . shixun . myshixuns . search_myshixun_user ( current_user . id )
if user_myshixun . blank? || user_myshixun . first . status != 1 #当前用户的实训是否做完
@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_answerer = User.find_by(id:@exercise_current_user_id) #试卷回答者
@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 )
if @ex_user . present? && @is_teacher_or == 0
if get_exercise_status == 2 #当前用户已提交,且试卷未截止
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 == 1
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 == 3 #勾选了成绩公开且试卷已截止的
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 . exists? && @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 . first ( 30 ) } " , 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' ) } "
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 , 2 ) . count #判断是否有已发布的分班
@exercise_unpublish_count = get_user_permission_course ( exercise_ids , 1 ) . count #判断是否有未发布的分班
@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 )
# @exercise_course_groups = @exercise.get_ex_published_course(current_user.id)
@exercise_users_list = @exercise . all_exercise_users ( current_user . id )
@course_all_members_count = @exercise_users_list . size
#班级的选择
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 )
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 . count #试卷的已提交用户人数
@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 . count
@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 " , 0 )
@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 " , 1 )
@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 " , 2 )
@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 " , 3 )
@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 " , 4 )
@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 " , 5 )
@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 :: ENDED #未发布的情况
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 :: ENDED
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 ) == 1 #试卷未发布,且当前用户不为老师/管理员
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 ) != 2
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 == 1
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 ) == 3 && 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 != 3
ques_number = index + 1
else
ques_number = q . question_number
end
if q . question_type != 5
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 == 5
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 < = 2 #选择题和判断题的时候,需要有选项,才算回答
if vote_answer_id . size > 0
ques_status = 1
question_answered += 1
end
elsif q . question_type == 3 #填空题的时候,需要有选项和内容,才算回答
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