#encoding: utf-8
class ExerciseController < ApplicationController
layout " base_courses "
# before_filter :check_authentication, :except => []
before_filter :find_exercise_and_course , :only = > [ :create_exercise_question , :edit , :update , :show , :destroy , :statistics_result ,
:commit_exercise , :commit_answer , :publish_exercise , :publish_notice , :end_notice , :end_exercise , :republish_exercise ,
:student_exercise_list , :update_question_num , :cancel_publish ,
:send_to_course , :get_student_uncomplete_question , :edit_question_score , :setting , :set_public ,
:ex_setting , :add_to_exercise_bank , :choose_shixuns , :shixun_question , :back_to_answer , :export_blank_exercise , :export_student_result ,
:choose_student , :redo_exercise , :cancel_commit_confirm , :cancel_commit ]
before_filter :find_course , :only = > [ :index , :new , :create ]
before_filter :teacher_of_course , :only = > [ :new , :create , :edit , :update , :destroy , :create_exercise_question , :publish_exercise , :publish_notice , :end_exercise , :cancel_publish ,
:update_question_num , :send_to_course , :edit_question_score , :set_public , :ex_setting , :export_blank_exercise , :export_student_result ]
before_filter :require_login , :only = > [ :student_exercise_list , :show ]
include ExerciseHelper
include ApplicationHelper
if RUBY_PLATFORM =~ / linux /
require 'pdfkit'
end
def index
if @course . is_public == 0 && ! ( User . current . member_of_course? ( @course ) || User . current . admin? )
render_403
return
end
@is_teacher = User . current . allowed_to? ( :as_teacher , @course ) || User . current . admin?
if @is_teacher
exercises = @course . exercises . order ( " IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC " )
elsif User . current . member_of_course? ( @course )
member = @course . members . where ( :user_id = > User . current . id ) . first
if member . try ( :course_group_id ) . to_i == 0
exercises = @course . exercises . where ( " publish_time <= ' #{ Time . now } ' and unified_setting = 1 " ) . order ( " IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC " )
else
not_exercise_ids = @course . exercise_group_settings . where ( " course_group_id = #{ member . try ( :course_group_id ) } and (publish_time > ' #{ Time . now } ' or publish_time is null) " )
not_exercise_ids = not_exercise_ids . blank? ? " (-1) " : " ( " + not_exercise_ids . map ( & :exercise_id ) . join ( " , " ) + " ) "
exercises = @course . exercises . where ( " publish_time <= ' #{ Time . now } ' and id not in #{ not_exercise_ids } " ) . order ( " IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC " )
end
else
exercises = @course . exercises . where ( " publish_time <= ' #{ Time . now } ' " ) . order ( " IF(ISNULL(publish_time),0,1),publish_time DESC, created_at DESC " )
end
if params [ :type ]
@type = params [ :type ]
exercises = exercises . where ( :exercise_status = > params [ :type ] )
end
@search = params [ :search ] ? params [ :search ] . to_s . strip : " "
if params [ :search ]
exercises = exercises . where ( " exercise_name like '% #{ @search } %' " )
end
@exercises = paginateHelper exercises , 15 #分页
@left_nav_type = 4
respond_to do | format |
format . js
format . html
end
end
def show
unless User . current . member_of_course? ( @course ) || User . current . admin?
render_403
return
end
# @exercise.course_messages.each do |message|
# if User.current.id == message.user_id && message.viewed == 0
# message.update_attributes(:viewed => true) if message.viewed == 0
# end
# end
@is_teacher = User . current . allowed_to? ( :as_teacher , @course ) || User . current . admin?
unless @is_teacher
@exercise_user = ExerciseUser . where ( " user_id=? and exercise_id=? " , User . current . id , @exercise . id ) . first
if @exercise_user . nil?
@exercise_user = ExerciseUser . create ( :user_id = > User . current . id , :exercise_id = > @exercise . id , :start_at = > Time . now , :status = > false , :commit_status = > 0 )
# @exercise_user = ExerciseUser.where("user_id=? and exercise_id=?", User.current.id, @exercise.id).first
elsif @exercise_user . start_at . nil?
@exercise_user . update_attributes ( :start_at = > Time . now )
end
@can_edit_excercise = can_edit_exercise @exercise , @exercise_user
if ! @can_edit_excercise && ! @exercise_user . status
time = ( @exercise_user . start_at . to_i + @exercise . time . to_i * 60 ) > @exercise . end_time . to_i ? @exercise . end_time : Time . at ( @exercise_user . start_at . to_i + @exercise . time . to_i * 60 )
s_score = calculate_student_score ( @exercise , @exercise_user . user )
sub_score = @exercise_user . user . exercise_answer . where ( :exercise_question_id = > @exercise . exercise_questions . where ( :question_type = > 4 ) . map ( & :id ) ) . empty? ? 0 : @exercise_user . subjective_score
total_score = s_score + ( sub_score && sub_score > 0 ? sub_score : 0 )
@exercise_user . update_attributes ( :status = > true , :end_at = > time , :commit_status = > 1 , :objective_score = > s_score ,
:subjective_score = > sub_score , :score = > total_score )
end
if @exercise_user . commit_status == 1 && @exercise . end_time > Time . now
if @exercise . time == - 1
@cancel_commit = true
else
@cancel_commit = ( Time . now . to_i - @exercise_user . start_at . to_i ) < @exercise . time . to_i * 60
end
end
#score = calculate_student_score(@exercise, User.current)
#@exercise_user.update_attributes(:objective_score => score, :score => (score + (@exercise_user.subjective_score > 0 ? @exercise_user.subjective_score : 0)))
else
@exercise_user = ExerciseUser . where ( " user_id=? and exercise_id=? " , params [ :user_id ] , @exercise . id ) . first
@can_edit_excercise = false
end
Rails . logger . info ( " # # # # # # # # # # # can_edit_excercise: #{ @can_edit_excercise } " )
# @percent = get_percent(@exercise,User.current)
#@exercise_questions = @exercise.exercise_questions
respond_to do | format |
format . html { render :layout = > 'base_edu' }
end
#end
end
def new
# option = {
# :exercise_name => "",
# :course_id => @course.id,
# :exercise_status => 1,
# :user_id => User.current.id,
# :time => "",
# :end_time => "",
# :publish_time => "",
# :exercise_description => "",
# :show_result => 1
# }
@exercise = Exercise . new
respond_to do | format |
format . html { render :layout = > 'base_edu' }
end
end
def choose_shixuns
search = params [ :search ]
@quest_id = params [ :quest_id ]
# 去掉对 当前用户所在单位 不公开的实训
if User . current . admin?
none_shixun_ids = [ - 1 ]
else
none_shixun_ids = ShixunSchool . where ( " school_id != #{ User . current . user_extensions . try ( :school_id ) } " ) . pluck ( :shixun_id )
end
@shixuns = Shixun . where ( " status = 2 and id not in ( #{ none_shixun_ids . join ( " , " ) } ) " ) . where ( " name like ? " , " % #{ search } % " ) . select { | shixun | shixun . challenges . where ( :st = > 1 ) . count == 0 }
@limit = 8
@shixuns = paginateHelper @shixuns , @limit
respond_to do | format |
format . js
end
end
def shixun_question
@shixun = Shixun . find params [ :shixun_exercise ]
end
def create
if params [ :exercise ]
exercise = Exercise . new
exercise . exercise_name = params [ :exercise ] [ :exercise_name ]
exercise . exercise_description = params [ :exercise ] [ :exercise_description ]
exercise . user_id = User . current . id
exercise . course_id = params [ :course_id ]
exercise . time = - 1
exercise . exercise_status = 1
if exercise . save
create_exercises_list exercise
@exercise = exercise
respond_to do | format |
format . js
end
end
end
end
def edit
@is_teacher = User . current . allowed_to? ( :as_teacher , @course ) || User . current . admin?
@ques_id = params [ :ques_id ] if params [ :ques_id ]
respond_to do | format |
format . html { render :layout = > 'base_edu' }
end
end
def update
@exercise . exercise_name = params [ :exercise ] [ :exercise_name ]
@exercise . exercise_description = params [ :exercise ] [ :exercise_description ]
if @exercise . save
respond_to do | format |
format . js
end
else
render_404
end
end
def destroy
@is_teacher = User . current . allowed_to? ( :as_teacher , @course ) || User . current . admin?
if @exercise && @exercise . destroy
redirect_to exercise_index_path ( :course_id = > @course . id )
end
end
def setting
@is_teacher = User . current . allowed_to? ( :as_teacher , @course ) || User . current . admin?
@is_new = params [ :is_new ] ? true : false
respond_to do | format |
format . html { render :layout = > 'base_edu' }
end
end
def ex_setting
if @exercise . exercise_status == 1 && @course . course_groups . count > 1
@exercise . unified_setting = params [ :unified_setting ] ? true :false
end
if @exercise . unified_setting
params_publish_time = params [ :exercise_publish_time ]
params_end_time = params [ :exercise_end_time ]
min_publish_time = params_publish_time
max_end_time = params_end_time
else
# 获取最小发布时间和最大截止时间, 赋值给homework
params_publish_time = params [ :exercise_publish_time_group ]
params_end_time = params [ :exercise_end_time_group ]
min_publish_time = @exercise . publish_time ? ( format_time @exercise . publish_time ) . to_s : " "
max_end_time = @exercise . end_time ? ( format_time @exercise . end_time ) . to_s : " "
if params [ :exercise_end_time_group ]
max_end_time = " "
params [ :exercise_end_time_group ] . each_with_index do | end_time , index |
if end_time != " "
if max_end_time == " "
max_end_time = end_time
end
if end_time > max_end_time
max_end_time = end_time
end
end
end
end
if params [ :exercise_publish_time_group ]
params [ :exercise_publish_time_group ] . each_with_index do | publish_time , index |
if publish_time != " "
if min_publish_time == " "
min_publish_time = publish_time
end
if publish_time < min_publish_time
min_publish_time = publish_time
end
end
end
end
end
if params_publish_time && min_publish_time != " "
@exercise . publish_time = min_publish_time
@exercise . end_time = max_end_time
if @exercise . publish_time < Time . now and @exercise . exercise_status == 1
@exercise . exercise_status = 2
create_exercise_user = 1
if @exercise . course_acts . size == 0
@exercise . course_acts << CourseActivity . new ( :user_id = > @exercise . user_id , :course_id = > @exercise . course_id )
end
end
elsif params_publish_time && min_publish_time == " "
@exercise . exercise_status = 2
create_exercise_user = 1
@exercise . publish_time = Time . now
@exercise . end_time = Time . at ( ( ( 1 . month . since . to_i ) / 3600 . 0 ) . ceil * 3600 )
if @exercise . course_acts . size == 0
@exercise . course_acts << CourseActivity . new ( :user_id = > @exercise . user_id , :course_id = > @exercise . course_id )
end
else
@exercise . end_time = max_end_time if params_end_time
end
# 不统一设置且分班数大于一则更新分组设置
if ! @exercise . unified_setting && @course . course_groups . count > 1
@course . course_groups . each_with_index do | group , index |
exercise_group_setting = @exercise . exercise_group_settings . where ( :course_group_id = > group . id ) . first
unless exercise_group_setting
exercise_group_setting = ExerciseGroupSetting . create ( :exercise_id = > @exercise . id , :course_group_id = > group . id , :course_id = > @course . id )
end
end
group_id = [ ]
@exercise . exercise_group_settings . where ( " publish_time is null or publish_time > ' #{ Time . now } ' " ) . joins ( :course_group ) . reorder ( " CONVERT(course_groups.name USING gbk) COLLATE gbk_chinese_ci ASC " ) . each_with_index do | setting , index |
if params [ :exercise_publish_time_group ] && min_publish_time != " "
if params [ :exercise_publish_time_group ] [ index ] && params [ :exercise_publish_time_group ] [ index ] != " "
setting . update_column ( :publish_time , params [ :exercise_publish_time_group ] [ index ] )
end
elsif params [ :exercise_publish_time_group ] && min_publish_time == " "
setting . update_column ( :publish_time , Time . now )
group_id << setting . course_group_id
end
end
@exercise . exercise_group_settings . joins ( :course_group ) . reorder ( " CONVERT(course_groups.name USING gbk) COLLATE gbk_chinese_ci ASC " ) . each_with_index do | setting , index |
if params [ :exercise_end_time_group ] && max_end_time != " "
if params [ :exercise_end_time_group ] [ index ] && params [ :exercise_end_time_group ] [ index ] != " "
setting . update_column ( :end_time , params [ :exercise_end_time_group ] [ index ] )
end
elsif params [ :exercise_end_time_group ] && max_end_time == " "
setting . update_column ( :end_time , Time . at ( ( ( 1 . month . since . to_i ) / 3600 . 0 ) . ceil * 3600 ) )
end
end
# 统一设置则删除分组设置
elsif @exercise . unified_setting
@exercise . exercise_group_settings . destroy_all
end
if @exercise . end_time < = Time . now && @exercise . exercise_status < 3
@exercise . exercise_status = 3
@exercise . exercise_users . each do | exercise_user |
if exercise_user . commit_status == 0 && ! exercise_user . start_at . nil?
s_score = calculate_student_score ( @exercise , exercise_user . user )
sub_score = exercise_user . user . exercise_answer . where ( :exercise_question_id = > @exercise . exercise_questions . where ( :question_type = > 4 ) . map ( & :id ) ) . empty? ? 0 : exercise_user . subjective_score
total_score = s_score + ( sub_score && sub_score > 0 ? sub_score : 0 )
exercise_user . update_attributes ( :commit_status = > 1 , :end_at = > params [ :exercise_end_time ] , :status = > true , :objective_score = > s_score ,
:subjective_score = > sub_score , :score = > total_score )
end
end
elsif @exercise . end_time > Time . now && @exercise . exercise_status == 3
@exercise . exercise_status = 2
end
@exercise . time = ( params [ :time ] . strip == " " ? - 1 : params [ :time ] ) if params [ :time ]
@exercise . question_random = params [ :question_random ] ? 1 : 0
@exercise . choice_random = params [ :choice_random ] ? 1 : 0
@exercise . score_open = params [ :score_open ] ? 1 : 0
@exercise . answer_open = params [ :answer_open ] ? 1 : 0
@exercise . show_statistic = params [ :show_statistic ] ? 1 : 0
if @exercise . save
if create_exercise_user . present?
if group_id . present? && group_id . size != 0
if group_id . size == @course . course_groups . count
create_exercises_tiding @exercise , @course . student
else
members = @course . members . where ( :course_group_id = > group_id )
create_exercises_tiding @exercise , members
end
else
create_exercises_tiding @exercise , @course . student
end
end
redirect_to student_exercise_list_exercise_path ( @exercise )
end
end
def set_public
if User . current . admin? || User . current . allowed_to? ( :as_teacher , @course )
@exercise . update_attributes ( :is_public = > true )
end
end
# 统计结果
def statistics_result
exercise_questions = @exercise . exercise_questions
@user_ids = @exercise . exercise_users . where ( :commit_status = > 1 ) . map ( & :user_id )
@user_ids_str = @user_ids . length == 0 ? " (-1) " : " ( " + @user_ids . join ( " , " ) + " ) "
@exercise_questions = paginateHelper exercise_questions , 10
respond_to do | format |
format . js
end
end
# 添加题目
# question_type 1: 单选 2: 多选 3: 填空题
def create_exercise_question
question_title = params [ :question_title ] . nil? || params [ :question_title ] . empty? ? l ( :label_enter_single_title ) : params [ :question_title ]
option = {
:question_title = > question_title ,
:question_type = > params [ :question_type ] || 1 ,
:question_number = > @exercise . exercise_questions . count + 1 ,
:question_score = > params [ :question_type ] == '5' ? 0 : params [ :question_score ] ,
:shixun_id = > params [ :shixun ]
}
@exercise_questions = @exercise . exercise_questions . new option
# params[:question_answer] 题目选项
if params [ :question_answer ]
for i in 1 .. params [ :question_answer ] . count
answer = ( params [ :question_answer ] . values [ i - 1 ] . nil? || params [ :question_answer ] . values [ i - 1 ] . empty? ) ? l ( :label_new_answer ) : params [ :question_answer ] . values [ i - 1 ]
question_option = {
:choice_position = > i ,
:choice_text = > answer . strip
}
@exercise_questions . exercise_choices . new question_option
end
end
# 如果是插入的话, 那么从插入的这个id以后的question_num都将要+1
if params [ :quest_id ] != " 0 "
@is_insert = true
insert_que = ExerciseQuestion . find params [ :quest_id ]
if insert_que
@exercise . exercise_questions . where ( " question_number>? " , insert_que . question_number ) . update_all ( " question_number = question_number + 1 " )
@exercise_questions . question_number = insert_que . question_number + 1
end
end
if @exercise_questions . save
# params[:exercise_choice] 标准答案参数
# 问答题标准答案有三个,单独处理
if @exercise_questions . question_type == 5
shixun = Shixun . find params [ :shixun ]
question_score = 0
shixun . challenges . each_with_index do | challenge , index |
ex_shixun_challenge = ExerciseShixunChallenge . new ( :challenge_id = > challenge . id , :shixun_id = > shixun . id , :exercise_question_id = > @exercise_questions . id ,
:question_score = > params [ :question_score ] [ index ] , :position = > index + 1 )
ex_shixun_challenge . save
question_score += ex_shixun_challenge . question_score
end
@exercise_questions . update_attributes ( :question_score = > question_score )
elsif @exercise_questions . question_type == 3
for i in 1 .. params [ :exercise_choice ] . count
standart_answer = ExerciseStandardAnswer . new
standart_answer . exercise_question_id = @exercise_questions . id
standart_answer . answer_text = params [ :exercise_choice ] . values [ i - 1 ] . strip
standart_answer . save
end
elsif @exercise_questions . question_type == 4
unless params [ :exercise_choice ] == " "
standart_answer = ExerciseStandardAnswer . new
standart_answer . exercise_question_id = @exercise_questions . id
standart_answer . answer_text = params [ :exercise_choice ] . strip
standart_answer . save
end
else
standart_answer = ExerciseStandardAnswer . new
standart_answer . exercise_question_id = @exercise_questions . id
if @exercise_questions . question_type == 1
standart_answer . exercise_choice_id = sigle_selection_standard_answer ( params [ :exercise_choice ] )
elsif @exercise_questions . question_type == 2
standart_answer . exercise_choice_id = multiselect_standard_answer ( params [ :exercise_choice ] )
end
standart_answer . save
end
redirect_to edit_exercise_path ( @exercise , :ques_id = > @exercise_questions . id )
= begin
respond_to do | format |
format . js
end
= end
end
end
# 修改题目
# params[:exercise_question] The id of exercise_question
# params[:question_answer] eg:A、B、C选项
def update_exercise_question
@exercise_question = ExerciseQuestion . find params [ :exercise_question ]
@exercise_question . question_title = params [ :question_title ] . nil? || params [ :question_title ] . empty? ? l ( :label_enter_single_title ) : params [ :question_title ]
@exercise_question . question_score = params [ :question_score ] if @exercise_question . question_type != 5
# 处理选项:如果选了某个选项,那么则要删除之前的选项
if params [ :question_answer ]
@exercise_question . exercise_choices . each do | answer |
answer . destroy unless params [ :question_answer ] . keys . include? answer . id . to_s
end
for i in 1 .. params [ :question_answer ] . count
question = @exercise_question . exercise_choices . find_by_id params [ :question_answer ] . keys [ i - 1 ]
answer = ( params [ :question_answer ] . values [ i - 1 ] . nil? || params [ :question_answer ] . values [ i - 1 ] . empty? ) ? l ( :label_new_answer ) : params [ :question_answer ] . values [ i - 1 ]
if question
question . choice_position = i
question . choice_text = answer
question . save
else
question_option = {
:choice_position = > i ,
:choice_text = > answer
}
@exercise_question . exercise_choices . new question_option
end
end
end
# 更新标准答案
if params [ :exercise_choice ]
if @exercise_question . question_type == 3
# 删除不合理的选项
@exercise_question . exercise_standard_answers . each do | answer |
answer . destroy unless params [ :exercise_choice ] . keys . include? answer . id . to_s
end
for i in 1 .. params [ :exercise_choice ] . count
# 找到对应的标准答案
question_standart = @exercise_question . exercise_standard_answers . find_by_id params [ :exercise_choice ] . keys [ i - 1 ]
# 标准答案值
answer_standart = ( params [ :exercise_choice ] . values [ i - 1 ] . nil? || params [ :exercise_choice ] . values [ i - 1 ] . empty? ) ? l ( :label_new_answer ) : params [ :exercise_choice ] . values [ i - 1 ]
if question_standart
question_standart . answer_text = answer_standart
question_standart . save
else
standart_answer_option = {
:answer_text = > answer_standart
}
@exercise_question . exercise_standard_answers . new standart_answer_option
end
end
elsif @exercise_question . question_type == 4
answer_standart = @exercise_question . exercise_standard_answers . empty? ? nil : @exercise_question . exercise_standard_answers . first
if params [ :exercise_choice ] == " " && ! answer_standart . nil?
answer_standart . destroy
elsif params [ :exercise_choice ] != " " && ! answer_standart . nil?
answer_standart . answer_text = params [ :exercise_choice ]
answer_standart . save
elsif params [ :exercise_choice ] != " " && answer_standart . nil?
standart_answer_option = {
:answer_text = > params [ :exercise_choice ]
}
@exercise_question . exercise_standard_answers . new standart_answer_option
end
else
answer_standart = @exercise_question . exercise_standard_answers . first
answer_standart . exercise_choice_id = @exercise_question . question_type == 1 ? sigle_selection_standard_answer ( params [ :exercise_choice ] ) : multiselect_standard_answer ( params [ :exercise_choice ] )
answer_standart . save
end
end
if @exercise_question . question_type == 5
question_score = 0
@exercise_question . exercise_shixun_challenges . each_with_index do | challenge , index |
challenge . question_score = params [ :question_score ] [ index ]
challenge . save
question_score += challenge . question_score
end
@exercise_question . question_score = question_score
end
@exercise_question . save
@exercise = @exercise_question . exercise
redirect_to edit_exercise_path ( @exercise , :ques_id = > @exercise_question . id )
= begin
respond_to do | format |
format . js
end
= end
end
# 删除题目
def delete_exercise_question
@exercise_question = ExerciseQuestion . find params [ :exercise_question ]
@exercise = @exercise_question . exercise
@exercise . exercise_questions . where ( " question_number>? " , params [ :quest_num ] . to_i ) . update_all ( " question_number = question_number - 1 " )
# if @exercise_question.question_type == 1
# ExerciseQuestion.where("question_number>? and question_type=?",params[:quest_num].to_i, 1).update_all(" question_number = question_number - 1")
# #@exercise.exercise_questions.where("question_number > #{params[:quest_num].to_i} and question_type == 1").update_all(" question_number = question_number + 1")
# elsif @exercise_question.question_type == 2
# ExerciseQuestion.where("question_number>? and question_type=?",params[:quest_num].to_i, 2).update_all(" question_number = question_number - 1")
# elsif @exercise_question.question_type == 3
# ExerciseQuestion.where("question_number>? and question_type=?",params[:quest_num].to_i, 3).update_all(" question_number = question_number - 1")
# else
# ExerciseQuestion.where("question_number>? and question_type=?",params[:quest_num].to_i, 4).update_all(" question_number = question_number - 1")
# end
# @exercise_question_num = params[:quest_num].to_i
# @exercise_questions.question_number = params[:quest_num].to_i - 1
#
# exercise_questions = @exercise.exercise_questions.where("question_number > #{@exercise_question.question_number}")
# exercise_questions.each do |question|
# question.question_number -= 1
# question.save
# end
if @exercise_question && @exercise_question . destroy
respond_to do | format |
format . js
end
end
end
#题目上移/下移
def update_question_num
@exercise_question = ExerciseQuestion . find params [ :ques_id ]
exercise_questions = @exercise . exercise_questions
if @exercise_question
if params [ :opr ] == 'up' && @exercise_question . question_number > 1
@before_que = exercise_questions . where ( " question_number = #{ @exercise_question . question_number - 1 } " ) . first
if @before_que && @exercise_question . update_attribute ( 'question_number' , @exercise_question . question_number - 1 )
@before_que . update_attribute ( 'question_number' , @before_que . question_number + 1 )
end
elsif params [ :opr ] == 'down' && @exercise_question . question_number < exercise_questions . count
@after_que = exercise_questions . where ( " question_number = #{ @exercise_question . question_number + 1 } " ) . first
if @after_que && @exercise_question . update_attribute ( 'question_number' , @exercise_question . question_number + 1 )
@after_que . update_attribute ( 'question_number' , @after_que . question_number - 1 )
end
end
respond_to do | format |
format . js
end
end
end
# 发送试卷
def send_to_course
params [ :course_ids ] . each do | course |
option = {
:exercise_name = > @exercise . exercise_name ,
:exercise_status = > 1 ,
:user_id = > User . current . id ,
:show_result = > 1 ,
:course_id = > course . to_i ,
:time = > @exercise . time ,
:exercise_description = > @exercise . exercise_description
}
exercise = Exercise . create option
@exercise . exercise_questions . each do | q |
option = {
:question_title = > q [ :question_title ] ,
:question_type = > q [ :question_type ] || 1 ,
:question_number = > q [ :question_number ] ,
:question_score = > q [ :question_score ]
}
exercise_question = exercise . exercise_questions . new option
for i in 1 .. q . exercise_choices . count
choice_option = {
:choice_position = > i ,
:choice_text = > q . exercise_choices [ i - 1 ] [ :choice_text ]
}
exercise_question . exercise_choices . new choice_option
end
for i in 1 .. q . exercise_standard_answers . count
standard_answer_option = {
:exercise_choice_id = > q . exercise_standard_answers [ i - 1 ] [ :exercise_choice_id ] ,
:answer_text = > q . exercise_standard_answers [ i - 1 ] [ :answer_text ]
}
exercise_question . exercise_standard_answers . new standard_answer_option
end
end
exercise . save
end
respond_to do | format |
format . js
end
end
# 搜索当前用户任教的班级(不包含该试卷所在的班级)
def search_courses
@user = User . current
if ! params [ :name ] . nil?
search = " % #{ params [ :name ] . to_s . strip . downcase } % "
@courses = @user . courses . not_deleted . where ( " courses.id != #{ params [ :course ] . to_i } and ( #{ Course . table_name } .id = #{ params [ :search ] . to_i } or #{ Course . table_name } .name like :p) " , :p = > search ) . reorder ( " created_at desc " ) . select { | course | @user . allowed_to? ( :as_teacher , course ) }
else
@courses = @user . courses . not_deleted . where ( " courses.id != #{ params [ :course ] . to_i } " ) . reorder ( " created_at desc " ) . select { | course | @user . allowed_to? ( :as_teacher , course ) }
end
respond_to do | format |
format . js
end
end
def cancel_publish
ActiveRecord :: Base . transaction do
@exercise . exercise_users . destroy_all
ExerciseAnswer . where ( :exercise_question_id = > @exercise . exercise_questions . pluck ( :id ) ) . destroy_all
ExerciseShixunAnswer . where ( :exercise_question_id = > @exercise . exercise_questions . pluck ( :id ) ) . destroy_all
@exercise . update_attributes ( :exercise_status = > 1 , :publish_time = > nil , :end_time = > nil , :unified_setting = > 1 )
@exercise . exercise_group_settings . destroy_all
@exercise . course_acts . destroy_all
@exercise . tidings . destroy_all
create_exercises_list @exercise
end
redirect_to student_exercise_list_exercise_path ( @exercise )
end
def publish_notice
if @exercise . publish_time
@status = 1
else
@status = 0
end
if @course . course_groups . count > 1
if @exercise . unified_setting
@groups = @course . course_groups
else
@groups = @course . course_groups . where ( :id = > @exercise . exercise_group_settings . where ( " publish_time is null or publish_time > ' #{ Time . now } ' " ) . map ( & :course_group_id ) )
end
@all_groups = @groups
@groups = paginateHelper @groups , 5
end
end
# 发布试卷
def publish_exercise
if @exercise . exercise_status == 1
if params [ :group_ids ]
if @course . course_groups . where ( :id = > params [ :group_ids ] . split ( " , " ) ) . count == @course . course_groups . count
@exercise . exercise_group_settings . destroy_all
@exercise . update_attribute ( " unified_setting " , true )
# 发消息
create_exercises_tiding @exercise , @course . student
else
@exercise . update_attribute ( " unified_setting " , false )
@course . course_groups . each do | group |
exercise_group_setting = @exercise . exercise_group_settings . where ( :course_group_id = > group . id ) . first
unless exercise_group_setting
ExerciseGroupSetting . create ( :exercise_id = > @exercise . id , :course_group_id = > group . id , :course_id = > @course . id , :publish_time = > @exercise . publish_time , :end_time = > @exercise . end_time )
end
end
@exercise . exercise_group_settings . where ( :course_group_id = > params [ :group_ids ] . split ( " , " ) ) . update_all ( :publish_time = > Time . now )
@exercise . exercise_group_settings . where ( :course_group_id = > params [ :group_ids ] . split ( " , " ) , :end_time = > nil ) . update_all ( :end_time = > Time . at ( ( ( 1 . month . since . to_i ) / 3600 . 0 ) . ceil * 3600 ) )
# 发消息
members = @course . members . where ( :course_group_id = > params [ :group_ids ] . split ( " , " ) )
create_exercises_tiding @exercise , members
end
else
@exercise . exercise_group_settings . destroy_all
# 发消息
create_exercises_tiding @exercise , @course . student
end
@exercise . exercise_status = 2
@exercise . publish_time = Time . now
if @exercise . end_time . nil?
@exercise . end_time = Time . at ( ( ( 1 . month . since . to_i ) / 3600 . 0 ) . ceil * 3600 )
elsif ExerciseGroupSetting . where ( " exercise_id = #{ @exercise . id } and end_time is not null " ) . count > 0
@exercise . update_attribute ( " end_time " , ExerciseGroupSetting . where ( " exercise_id = #{ @exercise . id } and end_time is not null " ) . map ( & :end_time ) . max )
end
if @exercise . save
# create_exercises_list @exercise
if @exercise . course_acts . size == 0
@exercise . course_acts << CourseActivity . new ( :user_id = > @exercise . user_id , :course_id = > @exercise . course_id )
end
end
else
@exercise . exercise_group_settings . where ( :course_group_id = > params [ :group_ids ] . split ( " , " ) ) . update_all ( :publish_time = > Time . now )
@exercise . exercise_group_settings . where ( :course_group_id = > params [ :group_ids ] . split ( " , " ) , :end_time = > nil ) . update_all ( :end_time = > Time . at ( ( ( 1 . month . since . to_i ) / 3600 . 0 ) . ceil * 3600 ) )
if ExerciseGroupSetting . where ( " exercise_id = #{ @exercise . id } and end_time is not null " ) . count > 0
@exercise . update_attribute ( " end_time " , ExerciseGroupSetting . where ( " exercise_id = #{ @exercise . id } and end_time is not null " ) . map ( & :end_time ) . max )
end
members = @course . members . where ( :course_group_id = > params [ :group_ids ] . split ( " , " ) )
create_exercises_tiding @exercise , members
end
if @exercise . end_time > Time . now && @exercise . exercise_status > 2
@exercise . update_attribute ( " exercise_status " , 2 )
end
redirect_to student_exercise_list_exercise_path ( @exercise )
end
def end_notice
if @course . course_groups . count > 1
unless @exercise . unified_setting
@groups = @course . course_groups . where ( :id = > @exercise . exercise_group_settings . where ( " publish_time < ' #{ Time . now } ' and end_time > ' #{ Time . now } ' " ) . map ( & :course_group_id ) )
@all_groups = @groups
@groups = paginateHelper @groups , 5
end
end
end
def end_exercise
time = Time . now
exercise_users = @exercise . exercise_users . where ( " 0=1 " )
#if @exercise.exercise_status == 2 && @exercise.end_time > Time.now
if params [ :group_ids ]
# @exercise.exercise_group_settings.where(:course_group_id => params[:group_id]).where("publish_time > '#{Time.now}' or publish_time is null").update_all(:publish_time => time)
@exercise . exercise_group_settings . where ( :course_group_id = > params [ :group_ids ] . split ( " , " ) ) . update_all ( :end_time = > time )
exercise_users = @exercise . exercise_users . where ( :user_id = > @course . members . where ( :course_group_id = > params [ :group_ids ] . split ( " , " ) ) . map ( & :user_id ) )
@exercise . update_attribute ( " end_time " , ExerciseGroupSetting . where ( " exercise_id = #{ @exercise . id } and end_time is not null " ) . map ( & :end_time ) . max )
if @exercise . end_time > Time . now && @exercise . exercise_status > 2
@exercise . update_attribute ( " exercise_status " , 2 )
elsif @exercise . end_time < = Time . now && @exercise . exercise_status == 2
@exercise . update_attribute ( " exercise_status " , 3 )
end
elsif @exercise . unified_setting
exercise_users = @exercise . exercise_users
@exercise . update_attributes ( :exercise_status = > 3 , :end_time = > time )
end
exercise_users . each do | exercise_user |
if exercise_user . commit_status == 0 && ! exercise_user . start_at . nil?
time = ( exercise_user . start_at . to_i + @exercise . time . to_i * 60 ) > @exercise . end_time . to_i ? @exercise . end_time : Time . at ( exercise_user . start_at . to_i + @exercise . time . to_i * 60 )
s_score = calculate_student_score ( @exercise , exercise_user . user )
sub_score = exercise_user . user . exercise_answer . where ( :exercise_question_id = > @exercise . exercise_questions . where ( :question_type = > 4 ) . map ( & :id ) ) . empty? ? 0 : exercise_user . subjective_score
exercise_user . update_attributes ( :status = > 1 , :commit_status = > 1 , :end_at = > time , :objective_score = > s_score , :subjective_score = > sub_score ,
:score = > ( s_score + ( exercise_user . subjective_score && exercise_user . subjective_score > 0 ? exercise_user . subjective_score : 0 ) ) )
end
end
#end
redirect_to student_exercise_list_exercise_path ( @exercise )
end
# 重新发布试卷
# 重新发布的时候会删除所有的答题
def republish_exercise
@is_teacher = User . current . allowed_to? ( :as_teacher , @course )
@index = params [ :index ]
@exercise . exercise_questions . each do | exercise_question |
exercise_question . exercise_answers . destroy_all
end
@exercise . course_messages . destroy_all
@exercise . exercise_users . destroy_all
@exercise . exercise_status = 1
@exercise . publish_time = nil
@exercise . save
respond_to do | format |
format . js
end
end
def student_exercise_list
@order , @b_sort , @name , @group , @comment , @status = params [ :order ] || " end_at " , params [ :sort ] || " desc " , params [ :name ] . to_s . strip || " " , params [ :ex_group ] , params [ :ex_comment ] , params [ :ex_status ]
@is_teacher = User . current . allowed_to? ( :as_teacher , @course ) || User . current . admin?
@member = @course . members . where ( :user_id = > User . current . id ) . first
# 判断学生是否有权限查看(试卷未发布、试卷已发布但不是统一设置的未分班学生、分班设置的试卷未发布)
if User . current . member_of_course? ( @course ) && ! @is_teacher
if @exercise . publish_time . nil? || @exercise . publish_time > Time . now || ( ! @exercise . unified_setting && ( @member . course_group_id == 0 ||
@exercise . exercise_group_settings . where ( " course_group_id = #{ @member . try ( :course_group_id ) } and (publish_time > ' #{ Time . now } ' or publish_time is null) " ) . count > 0 ) )
render_403
return
end
end
student_id = @course . student . blank? ? " (-1) " : " ( " + @course . student . map { | student | student . student_id } . join ( " , " ) + " ) "
if @exercise . exercise_status < 2
@exercise_users_list = @exercise . exercise_users . where ( " 0=1 " )
elsif @exercise . unified_setting
@exercise_users_list = @exercise . exercise_users
else
user_ids = @course . members . where ( :course_group_id = > @exercise . exercise_group_settings . where ( " publish_time < ' #{ Time . now } ' " ) . pluck ( :course_group_id ) ) . map ( & :user_id )
@exercise_users_list = @exercise . exercise_users . where ( :user_id = > user_ids )
end
if @exercise . time != - 1
@exercise . exercise_users . where ( " start_at is not null and end_at is null " ) . each do | exercise_user |
member = @course . members . where ( :user_id = > exercise_user . user_id ) . first
setting_time = exercise_group_setting @exercise , member . try ( :course_group )
if ( ( Time . now . to_i - exercise_user . start_at . to_i ) > @exercise . time . to_i * 60 ) || setting_time . end_time < Time . now
time = ( exercise_user . start_at . to_i + @exercise . time . to_i * 60 ) > setting_time . end_time . to_i ? setting_time . end_time : Time . at ( exercise_user . start_at . to_i + @exercise . time . to_i * 60 )
s_score = calculate_student_score ( @exercise , exercise_user . user )
sub_score = exercise_user . user . exercise_answer . where ( :exercise_question_id = > @exercise . exercise_questions . where ( :question_type = > 4 ) . map ( & :id ) ) . empty? ? 0 : exercise_user . subjective_score
total_score = s_score + ( sub_score && sub_score > 0 ? sub_score : 0 )
exercise_user . update_attributes ( :commit_status = > 1 , :end_at = > time , :status = > true , :objective_score = > s_score ,
:subjective_score = > sub_score , :score = > total_score )
end
end
end
@exercise . exercise_users . where ( " commit_status = 1 and score is null " ) . each do | exercise_user |
s_score = calculate_student_score ( @exercise , exercise_user . user )
sub_score = exercise_user . user . exercise_answer . where ( :exercise_question_id = > @exercise . exercise_questions . where ( :question_type = > 4 ) . map ( & :id ) ) . empty? ? 0 : exercise_user . subjective_score
total_score = s_score + ( sub_score && sub_score > 0 ? sub_score : 0 )
exercise_user . update_attributes ( :objective_score = > s_score , :subjective_score = > sub_score , :score = > total_score )
end
@group_teacher = @is_teacher && @member . present? && @member . teacher_course_groups . count > 0
if @group || @group_teacher
group_ids = @group || @member . teacher_course_groups . pluck ( :course_group_id )
group_students = @course . members . where ( :course_group_id = > group_ids ) . joins ( " join users on members.user_id = users.id " ) . select { | m | m . roles . to_s . include? ( " Student " ) }
if group_students . empty?
student_in_group = '(-1)'
else
student_in_group = '(' + group_students . map { | member | member . user_id } . join ( ',' ) + ')'
end
@exercise_users_list = @exercise_users_list . where ( " exercise_users.user_id in #{ student_in_group } " )
else
if @is_teacher || ( ! @exercise_users_list . where ( " exercise_users.user_id = #{ User . current . id } and commit_status = 1 " ) . empty? && @exercise . score_open && @exercise . end_time < = Time . now )
@exercise_users_list = @exercise_users_list . where ( " exercise_users.user_id in #{ student_id } " )
@show_all = true
elsif User . current . member_of_course? ( @course )
@exercise_users_list = @exercise_users_list . where ( " exercise_users.user_id = ? and exercise_users.user_id in #{ student_id } " , User . current . id )
else
@exercise_users_list = [ ]
end
end
unless @comment . blank?
if @comment . include? ( '0' )
@exercise_users_list = @exercise_users_list . where ( :subjective_score = > - 1 )
else
@exercise_users_list = @exercise_users_list . where ( " subjective_score != -1 " )
end
end
unless @status . blank?
@exercise_users_list = @exercise_users_list . where ( :commit_status = > @status )
end
if @exercise_users_list . size != 0
if @order == " student_id "
@exercise_users_list = @exercise_users_list . includes ( :user = > { :user_extensions = > [ ] } ) . order ( " user_extensions.student_id #{ @b_sort } " )
else
@exercise_users_list = @exercise_users_list . includes ( :user = > { :user_extensions = > [ ] } ) . order ( " #{ @order } #{ @b_sort } " )
end
end
@exercise_users_list = search_work_member @exercise_users_list , @name
@tab = params [ :tab ] . nil? ? 1 : params [ :tab ] . to_i
@score = @b_sort == " desc " ? " asc " : " desc "
@is_new = params [ :is_new ] ? true : false
@all_exercise_user_lists = @exercise_users_list
@exercise_count = @exercise_users_list . count
@has_commit_count = @exercise . exercise_users . where ( :commit_status = > 1 ) . count
@no_group_count = @course . members . where ( :course_group_id = > 0 ) . select { | m | m . roles . to_s . include? ( " Student " ) } . count
@limit = 50
@is_remote = true
@page = ( params [ 'page' ] || 1 ) . to_i
@exercise_pages = Paginator . new @exercise_count , @limit , @page
@offset || = @exercise_pages . offset
@exercise_users_list = paginateHelper @exercise_users_list , @limit
respond_to do | format |
format . js
format . html { render :layout = > 'base_edu' }
format . xls {
filename = " #{ @course . teacher . show_real_name . to_s } _ #{ @course . name } _ #{ @exercise . exercise_name } #{ l ( :excel_exercise_list ) } .xls "
send_data ( exercise_to_xls ( @all_exercise_user_lists ) , :type = > " text/excel;charset=utf-8; header=present " ,
:filename = > filename_for_content_disposition ( filename ) )
}
end
end
def export_student_result
url = Setting . protocol + " :// " + Setting . host_name + " /exercise/ " + @exercise . id . to_s + " /show_student_result?pdf=1&user_id= #{ params [ :user_id ] } "
logger . info ( " ----------------- #{ url } " )
kit = PDFKit . new ( url , :page_size = > " A4 " )
file_name = @exercise . exercise_name + " .pdf "
send_data ( kit . to_pdf , :filename = > file_name , :type = > " application/pdf;charset=utf-8 " )
return
end
def export_blank_exercise
url = Setting . protocol + " :// " + Setting . host_name + " /exercise/ " + @exercise . id . to_s + " /blank_exercise "
# url = "https://testbdweb.trustie.net/student_work/235992/shixun_work_report"
logger . info ( " ----------------- #{ url } " )
# url = "https://www.educoder.net"
kit = PDFKit . new ( url , :page_size = > " A4 " )
# kit.stylesheets << "#{Rails.root}/app/assets/assets/stylesheets/pdf.css" # 用url时就不可以用css样式了。
# kit.to_pdf # inline PDF
file_name = @exercise . exercise_name + " .pdf "
#kit.to_file(file_name)
send_data ( kit . to_pdf , :filename = > filename_for_content_disposition ( file_name ) , :type = > " application/pdf;charset=utf-8 " )
return
end
def blank_exercise
@exercise = Exercise . find params [ :id ]
respond_to do | format |
format . html { render :layout = > 'pdf' }
end
end
def cancel_commit_confirm
exercise_user = @exercise . exercise_users . where ( :user_id = > User . current . id ) . first
if exercise_user . present? && exercise_user . commit_status == 1 && @exercise . end_time > Time . now
if @exercise . time == - 1
@end_time = @exercise . end_time . strftime ( " %Y-%m-%d %H:%M " )
elsif ( Time . now . to_i - exercise_user . start_at . to_i ) < @exercise . time . to_i * 60
time = Time . at ( exercise_user . start_at . to_i + @exercise . time . to_i * 60 ) > @exercise . end_time ? @exercise . end_time : Time . at ( exercise_user . start_at . to_i + @exercise . time . to_i * 60 )
@end_time = time . strftime ( " %Y-%m-%d %H:%M " )
end
end
end
def cancel_commit
exercise_user = @exercise . exercise_users . where ( :user_id = > User . current . id ) . first
if exercise_user . present? && exercise_user . commit_status == 1 && @exercise . end_time > Time . now
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 = > - 1 , :subjective_score = > - 1 )
exercise_user . user . exercise_shixun_answers . where ( :exercise_question_id = > @exercise . exercise_questions . map ( & :id ) ) . destroy_all
exercise_answers = exercise_user . user . exercise_answer . where ( :exercise_question_id = > @exercise . exercise_questions . map ( & :id ) )
exercise_answers . update_all ( :score = > - 1 )
ExerciseAnswerComment . where ( :exercise_question_id = > @exercise . exercise_questions . map ( & :id ) , :exercise_answer_id = > exercise_answers . pluck ( :id ) ) . destroy_all
end
end
redirect_to student_exercise_list_exercise_path ( @exercise )
end
# 学生提交答卷,选中答案的过程中提交
def commit_answer
eq = ExerciseQuestion . find ( params [ :exercise_question_id ] )
# 已提交过的且是限时的则不允许答题
exercise_user = ExerciseUser . where ( :exercise_id = > @exercise . id , :user_id = > User . current . id ) . first
if ( exercise_user && exercise_user . commit_status == 1 ) || @exercise . end_time < Time . now
render :json = > { :text = > " Over " }
return
end
if eq . question_type == 1
# 单选题
ea = ExerciseAnswer . find_by_exercise_question_id_and_user_id ( params [ :exercise_question_id ] , User . current . id )
if ea . nil?
# 尚未答该题,添加答案
ea = ExerciseAnswer . new
ea . user_id = User . current . id
ea . exercise_question_id = params [ :exercise_question_id ]
end
#修改该题对应答案
ea . exercise_choice_id = params [ :exercise_choice_id ]
if ea . save
# 保存成功返回成功信息及当前以答题百分比
uncomplete_question = get_uncomplete_question ( @exercise , User . current )
if uncomplete_question . count < 1
complete = 1 ;
else
complete = 0 ;
end
@percent = get_percent ( @exercise , User . current )
render :json = > { :text = > " ok " , :complete = > complete , :percent = > format ( " %.2f " , @percent ) }
else
#返回失败信息
render :json = > { :text = > " failure " }
end
elsif eq . question_type == 2
#多选题
ea = ExerciseAnswer . find_by_exercise_choice_id_and_user_id ( params [ :exercise_choice_id ] , User . current . id )
if ea . nil?
#尚未答该题,添加答案
ea = ExerciseAnswer . new
ea . user_id = User . current . id
ea . exercise_question_id = params [ :exercise_question_id ]
ea . exercise_choice_id = params [ :exercise_choice_id ]
if ea . save
uncomplete_question = get_uncomplete_question ( @exercise , User . current )
if uncomplete_question . count < 1
complete = 1 ;
else
complete = 0 ;
end
is_answer = User . current . exercise_answer . where ( :exercise_question_id = > params [ :exercise_question_id ] . to_i ) . count > 0
@percent = get_percent ( @exercise , User . current )
render :json = > { :text = > " ok " , :complete = > complete , :percent = > format ( " %.2f " , @percent ) , :is_answer = > is_answer }
else
render :json = > { :text = > " failure " }
end
else
#pv不为空, 则当前选项之前已被选择, 再次点击则是不再选择该项, 故删除该答案
if ea . delete
is_answer = User . current . exercise_answer . where ( :exercise_question_id = > params [ :exercise_question_id ] . to_i ) . count > 0
@percent = get_percent ( @exercise , User . current )
render :json = > { :text = > " false " , :percent = > format ( " %.2f " , @percent ) , :is_answer = > is_answer }
else
render :json = > { :text = > " failure " }
end
end
elsif eq . question_type == 3 || eq . question_type == 4
#单行文本,多行文本题
ea = ExerciseAnswer . find_by_exercise_question_id_and_user_id ( params [ :exercise_question_id ] , User . current . id )
if ea . nil?
# ea为空之前尚未答题, 添加答案
if params [ :answer_text ] . nil? || params [ :answer_text ] . blank?
#用户提交空答案,视作不作答
@percent = get_percent ( @exercise , User . current )
render :json = > { :text = > " " , :percent = > format ( " %.2f " , @percent ) }
else
#添加答案
ea = ExerciseAnswer . new
ea . user_id = User . current . id
ea . exercise_question_id = params [ :exercise_question_id ]
ea . answer_text = params [ :answer_text ]
if ea . save
uncomplete_question = get_uncomplete_question ( @exercise , User . current )
if uncomplete_question . count < 1
complete = 1 ;
else
complete = 0 ;
end
@percent = get_percent ( @exercise , User . current )
render :json = > { :text = > ea . answer_text , :complete = > complete , :percent = > format ( " %.2f " , @percent ) }
else
render :json = > { :text = > " failure " }
end
end
else
# ea不为空说明用户之前已作答
if params [ :answer_text ] . nil? || params [ :answer_text ] . blank?
# 用户提交空答案,视为删除答案
if ea . delete
@percent = get_percent ( @exercise , User . current )
render :json = > { :text = > " " , :percent = > format ( " %.2f " , @percent ) }
else
render :json = > { :text = > " failure " }
end
else
#用户修改答案
ea . answer_text = params [ :answer_text ]
if ea . save
@percent = get_percent ( @exercise , User . current )
render :json = > { :text = > ea . answer_text , :percent = > format ( " %.2f " , @percent ) }
else
render :json = > { :text = > " failure " }
end
end
end
else
render :json = > { :text = > " failure " }
end
end
# 提交问卷
def commit_exercise
# 老师不需要提交
if User . current . allowed_to? ( :as_teacher , @course )
# if @exercise.publish_time.nil? || @exercise.publish_time <= Time.now
# @exercise.update_attributes(:exercise_status => 2)
# @exercise.update_attributes(:publish_time => Time.now)
# course = @exercise.course
# course.members.each do |m|
# @exercise.course_messages << CourseMessage.new(:user_id => m.user_id, :course_id => course.id, :viewed => false, :status => 2)
# end
# redirect_to exercise_url(@exercise)
# return
# elsif @exercise.publish_time > Time.now
# redirect_to exercise_url(@exercise)
# return
# end
# redirect_to exercise_url(@exercise)
# REDO: 提示提交成功
else
# 更新提交状态
cur_exercise_user = ExerciseUser . where ( " user_id =? and exercise_id=? " , User . current , @exercise . id ) . first
# 试卷未截止且试卷未提交过才能提交
if @exercise . exercise_status == 2 && cur_exercise_user . present? && cur_exercise_user . commit_status == 0
#if @exercise.time && @exercise.time != -1
score = calculate_student_score ( @exercise , User . current )
sub_score = User . current . exercise_answer . where ( :exercise_question_id = > @exercise . exercise_questions . where ( :question_type = > 4 ) . map ( & :id ) ) . empty? ? 0 : cur_exercise_user . subjective_score
total_score = score + ( sub_score && sub_score > 0 ? sub_score : 0 )
cur_exercise_user . update_attributes ( :status = > 1 , :commit_status = > 1 , :end_at = > Time . now , :objective_score = > score ,
:subjective_score = > sub_score , :score = > total_score )
# 提交后给老师和助教发消息
tid_str = " "
member = @course . members . where ( :user_id = > User . current . id ) . first
teachers = tiding_teachers @course , member
teachers . find_each do | mem |
tid_str += " , " if tid_str != " "
tid_str += " ( #{ mem . user_id } , #{ User . current . id } , #{ @exercise . id } , 'Exercise', #{ @exercise . id } , 'CommitExercise', #{ @course . id } , 'Course', 0, 'Exercise', ' #{ Time . now . strftime ( '%Y-%m-%d %H:%M:%S' ) } ', ' #{ Time . now . strftime ( '%Y-%m-%d %H:%M:%S' ) } ') "
end
tid_sql = " insert into tidings (user_id, trigger_user_id, container_id, container_type, parent_container_id, parent_container_type, belong_container_id, belong_container_type, viewed, tiding_type, created_at, updated_at) values " + tid_str
ActiveRecord :: Base . connection . execute tid_sql
end
#end
# 答题过程中需要统计完成量
#@uncomplete_question = get_uncomplete_question(@exercise, User.current)
# 获取改学生的考试得分
#@score = calculate_student_score(@exercise, User.current)
# @score = 100
# if @uncomplete_question.count < 1
# # 查看是否有已提交记录
# cur_exercise_user.score = @score
# if cur_exercise_user.save
# #redirect_to poll_index_path(:polls_group_id => @course.id,:polls_type => 'Course')
# @status = 0 #提交成功
# else
# @status = 2 #未知错误
# end
# else
# @status = 1 #有未做得必答题
# end
# @save = params[:save].to_i if params[:save]
respond_to do | format |
format . js
end
end
end
# 获取学生未答情况
def get_student_uncomplete_question
time_limit = @exercise . time == - 1 || @exercise . time . nil?
uncomplete_count = get_uncomplete_question ( @exercise , User . current ) . count
uncomplete_shixun = get_uncomplete_shixun ( @exercise , User . current ) . count
render :json = > { :time_limit = > time_limit , :uncomplete_count = > uncomplete_count , :uncomplete_shixun = > uncomplete_shixun }
end
def adjust_question_score
@exercise_question = ExerciseQuestion . where ( :id = > params [ :question ] ) . first
if @exercise_question . present? && @exercise_question . question_type == 3
@exercise_answer = @exercise_question . exercise_answers . where ( :id = > params [ :answer ] ) . first
else
@exercise_answer = @exercise_question . exercise_shixun_answers . where ( :id = > params [ :answer ] ) . first
end
end
# 主观题打分
def edit_question_score
exercise_user = @exercise . exercise_users . where ( :user_id = > params [ :user_id ] . to_i ) . first
@exercise_question = ExerciseQuestion . where ( :id = > params [ :exercise_question_id ] . to_i ) . first
if exercise_user . present? && @exercise_question . present?
# 分数是否在分值范围内
unless params [ :score ] . to_i > @exercise_question . question_score || params [ :score ] . to_i < 0
@score = params [ :score ] . to_i
if @exercise_question . question_type == 3 || @exercise_question . question_type == 4
@exercise_answer = ExerciseAnswer . where ( :id = > params [ :answer_id ] ) . first
else
@exercise_answer = ExerciseShixunAnswer . where ( :id = > params [ :answer_id ] ) . first
end
if @exercise_answer . present?
@total_score = exercise_user . score
@exercise_answer . update_attributes ( :score = > @score )
# 简答题打分更新主观题分数 其他则更新客观题分数
if @exercise_question . question_type == 4
exercise_user . subjective_score = calculate_subjective_score ( @exercise , exercise_user . user )
exercise_user . objective_score = exercise_user . objective_score > 0 ? exercise_user . objective_score : 0
else
exercise_user . subjective_score = exercise_user . subjective_score > 0 ? exercise_user . subjective_score : 0
exercise_user . objective_score = calculate_objective_score ( @exercise , exercise_user . user )
end
exercise_user . score = exercise_user . subjective_score + exercise_user . objective_score
exercise_user . save
if @exercise . tidings . where ( :user_id = > exercise_user . user_id , :trigger_user_id = > User . current , :parent_container_type = > " ExerciseScore " ) . count == 0
@exercise . tidings << Tiding . create ( :user_id = > exercise_user . user_id , :trigger_user_id = > User . current . id , :parent_container_id = > @exercise . id , :parent_container_type = > " ExerciseScore " , :belong_container_id = > @exercise . course_id , :belong_container_type = > " Course " , :viewed = > 0 , :tiding_type = > " Exercise " )
end
@exercise_answer . exercise_answer_comments << ExerciseAnswerComment . new ( :user_id = > User . current . id , :exercise_question_id = > @exercise_question . id ,
:comment = > params [ :comment ] [ 0 , 1000 ] , :score = > @score )
@total_score = exercise_user . score
if @exercise_question . question_type == 5
@answer_score = @score
@score = shixun_question_score ( @exercise_question , exercise_user . user )
end
end
else
@status = 2
@score = @exercise_question . question_score
end
end
end
#查看学生的答卷情况
def show_student_result
unless params [ :pdf ]
if ! User . current . logged?
redirect_to signin_url ( :back_url = > request . original_url )
return false
end
end
@exercise = Exercise . find params [ :id ]
@course = @exercise . course
@is_teacher = params [ :pdf ] ? true : User . current . allowed_to? ( :as_teacher , @course ) || User . current . admin?
if @is_teacher || ( User . current . member_of_course? ( @exercise . course ) && @exercise . exercise_status > 2 )
@user = User . find params [ :user_id ]
@exercise_questions = @exercise . exercise_questions
@exercise_user = ExerciseUser . where ( " user_id =? and exercise_id=? " , @user . id , @exercise . id ) . first
respond_to do | format |
if params [ :pdf ]
format . html { render :layout = > " pdf " }
else
format . html { render :layout = > " base_edu " }
end
end
else
render_403
end
end
def back_to_answer
exercise_user = ExerciseUser . where ( :user_id = > params [ :user_id ] , :exercise_id = > @exercise . id ) . first
if exercise_user
exercise_user . update_attributes ( :score = > nil , :start_at = > nil , :end_at = > nil , :status = > nil , :commit_status = > 0 , :objective_score = > - 1 , :subjective_score = > - 1 )
exercise_user . user . exercise_answer . where ( :exercise_question_id = > @exercise . exercise_questions . map ( & :id ) ) . destroy_all
exercise_user . user . exercise_shixun_answers . where ( :exercise_question_id = > @exercise . exercise_questions . map ( & :id ) ) . destroy_all
end
redirect_to student_exercise_list_exercise_path ( @exercise )
end
def choose_student
@sort = params [ :sort ] ? params [ :sort ] : " asc "
if @exercise . exercise_status == 3 || @exercise . end_time < Time . now
@status = 0
else
member = @course . members . where ( :user_id = > User . current . id ) . first
if member . present? && member . teacher_course_groups . count > 0
user_ids = @course . members . where ( :course_group_id = > member . teacher_course_groups . pluck ( :course_group_id ) ) . map ( & :user_id )
exercise_users = @exercise . exercise_users . where ( :commit_status = > 1 , :user_id = > user_ids )
else
exercise_users = @exercise . exercise_users . where ( :commit_status = > 1 )
end
@exercise_users = exercise_users . includes ( :user = > [ :user_extensions ] ) . order ( " score #{ @sort } " )
if @exercise_users . size == 0
@status = 2
end
if params [ :name ] || params [ :student_id ]
@name = params [ :name ]
@student_id = params [ :student_id ]
@exercise_users = @exercise_users . where ( " LOWER(concat(users.lastname, users.firstname)) like '% #{ params [ :name ] } %' and user_extensions.student_id like '% #{ params [ :student_id ] } %' " )
end
end
end
def redo_exercise
if params [ :user_id ]
@exercise . exercise_users . where ( :user_id = > params [ :user_id ] ) . update_all ( :score = > nil , :start_at = > nil , :end_at = > nil , :status = > nil , :commit_status = > 0 , :objective_score = > - 1 , :subjective_score = > - 1 )
ExerciseAnswer . where ( :user_id = > params [ :user_id ] , :exercise_question_id = > @exercise . exercise_questions . pluck ( :id ) ) . destroy_all
ExerciseShixunAnswer . where ( :user_id = > params [ :user_id ] , :exercise_question_id = > @exercise . exercise_questions . pluck ( :id ) ) . destroy_all
end
redirect_to student_exercise_list_exercise_path ( @exercise )
end
# 计算学生得分
def calculate_student_score ( exercise , user )
score = 0
score1 = 0
score2 = 0
score3 = 0
score4 = 0
exercise_qustions = exercise . exercise_questions
exercise_qustions . each do | question |
if question . question_type != 5
answer = get_user_answer ( question , user )
standard_answer = get_user_standard_answer ( question , user )
unless answer . empty?
# 问答题有多个答案
if question . question_type == 3 && ! standard_answer . empty?
if standard_answer . include? ( answer . first . answer_text . strip . downcase )
score1 = score1 + question . question_score unless question . question_score . nil?
end
elsif question . question_type == 1 && ! standard_answer . nil?
if answer . first . exercise_choice . choice_position == standard_answer . exercise_choice_id
score2 = score2 + question . question_score unless question . question_score . nil?
end
elsif question . question_type == 2 && ! standard_answer . nil?
arr = get_mulscore ( question , user )
if arr . to_i == standard_answer . exercise_choice_id
score3 = score3 + question . question_score unless question . question_score . nil?
end
end
end
else
question . exercise_shixun_challenges . each do | exercise_cha |
game = Game . where ( :user_id = > user . id , :challenge_id = > exercise_cha . challenge_id ) . first
if game . present?
exercise_cha_score = 0
answer_status = 0
challeng_path = challenge_path exercise_cha . challenge . path
if game . status == 2 && game . final_score > = 0
exercise_cha_score = exercise_cha . question_score
answer_status = 1
end
if exercise_cha . exercise_shixun_answers . where ( :user_id = > user . id ) . empty?
if GameCode . where ( :game_id = > game . try ( :id ) , :path = > challeng_path ) . first . present?
game_code = GameCode . where ( :game_id = > game . try ( :id ) , :path = > challeng_path ) . first
code = game_code . try ( :new_code )
else
begin
g = Gitlab . client
Rails . logger . info " commit_exercise_path---- #{ challeng_path } "
if game . present?
code = g . files ( game . myshixun . gpid , challeng_path , " master " ) . try ( :content )
else
code = g . files ( question . shixun . gpid , challeng_path , " master " ) . try ( :content )
end
code = tran_base64_decode64 ( code )
rescue Exception = > e
@error_messages = e . message
Rails . logger . info " commit_exercise---- #{ @error_messages } "
end
end
ExerciseShixunAnswer . create ( :exercise_question_id = > question . id , :exercise_shixun_challenge_id = > exercise_cha . id , :user_id = > user . id ,
:score = > exercise_cha_score , :answer_text = > code , :status = > answer_status )
end
score4 += exercise_cha_score
end
end
end
end
score = score1 + score2 + score3 + score4
end
# 计算客观题总分
def calculate_objective_score exercise , user
score = 0
score1 = 0
score2 = 0
score3 = 0
score4 = 0
exercise_qustions = exercise . exercise_questions
exercise_qustions . each do | question |
if question . question_type != 5
answer = get_user_answer ( question , user )
standard_answer = get_user_standard_answer ( question , user )
unless answer . empty?
# 问答题有多个答案
if question . question_type == 3 && ! standard_answer . empty?
if answer . first . score . nil? || answer . first . score == - 1
if standard_answer . include? ( answer . first . answer_text . strip . downcase )
score1 = score1 + question . question_score unless question . question_score . nil?
end
else
score1 = score1 + answer . first . score . to_f
end
elsif question . question_type == 1 && ! standard_answer . nil?
if answer . first . exercise_choice . choice_position == standard_answer . exercise_choice_id
score2 = score2 + question . question_score unless question . question_score . nil?
end
elsif question . question_type == 2 && ! standard_answer . nil?
arr = get_mulscore ( question , user )
if arr . to_i == standard_answer . exercise_choice_id
score3 = score3 + question . question_score unless question . question_score . nil?
end
end
end
else
question . exercise_shixun_answers . where ( :user_id = > user . id ) . each do | answer |
score4 += answer . score
end
end
end
score = score1 + score2 + score3 + score4
end
# 计算主观题总分
def calculate_subjective_score exercise , user
score = 0
exercise_questions = exercise . exercise_questions . where ( :question_type = > 4 )
exercise_answers = user . exercise_answer . where ( :exercise_question_id = > exercise_questions . map ( & :id ) )
exercise_answers . each do | ea |
if ea . score != - 1
score += ea . score
end
end
score
end
#导入试卷的弹框
def other_exercise
# 查作者是我的试卷 进行导入
#@order,@b_sort = params[:order] || "created_at",params[:sort] || "desc"
#@r_sort = @b_sort == "desc" ? "asc" : "desc"
@search = params [ :search ] ? params [ :search ] . to_s . strip . downcase : " "
if ( params [ :type ] . blank? || params [ :type ] == " 1 " ) #我的题库
@exercises = User . current . exercise_banks . where ( :container_type = > " Exercise " )
elsif params [ :type ] == " 2 " #公共题库
@exercises = ExerciseBank . where ( :container_type = > " Exercise " , :is_public = > true )
end
@type = params [ :type ] || " 1 "
if @search . present?
course_list_ids = CourseList . where ( " name like '% #{ @search } %' " ) . map ( & :id )
course_list_ids = course_list_ids . length == 0 ? " (-1) " : " ( " + course_list_ids . join ( " , " ) + " ) "
@exercises = @exercises . where ( " name like '% #{ @search } %' or course_list_id in #{ course_list_ids } " ) . reorder ( " created_at desc " )
else
@exercises = @exercises . reorder ( " created_at desc " )
end
@course_id = params [ :course_id ]
@is_remote = true
@page = params [ :page ] . nil? ? 1 : params [ 'page' ] . to_i
ex_count = @exercises . count
@total_pages = ( ex_count / 8 . 0 ) . ceil
@exercises = paginateHelper @exercises , 8
respond_to do | format |
format . js
format . json {
render json : exercise_bank_json_data ( @exercises )
}
end
end
#搜索导入页面的试卷
def search_exercises
@order , @b_sort = params [ :order ] || " created_at " , params [ :sort ] || " desc "
@r_sort = @b_sort == " desc " ? " asc " : " desc "
search = params [ :name ] . to_s . strip . downcase
courses = User . current . courses . not_deleted . select { | course | User . current . allowed_to? ( :as_teacher , course ) }
course_ids = courses . empty? ? " (-1) " : " ( " + courses . map { | course | course . id } . join ( ',' ) + " ) "
@exercises = Exercise . where ( " (user_id = #{ User . current . id } or course_id in #{ course_ids } ) and course_id != #{ params [ :course_id ] . to_i } and exercise_name like '% #{ search } %' " ) . order ( " #{ @order } #{ @b_sort } " )
@is_remote = true
@ex_count = @exercises . count
@ex_pages = Paginator . new @ex_count , 10 , params [ 'page' ] || 1
@offset || = @ex_pages . offset
@exercises = paginateHelper @exercises , 10
@course_id = params [ :course_id ]
respond_to do | format |
format . js
end
end
#将选择的试卷导入到班级
def import_other_exercise
course_id = params [ :course_id ]
course = Course . find ( course_id )
if params [ :exercise_id ]
exercise = ExerciseBank . find ( params [ :exercise_id ] )
@exercise = quote_exercise_bank exercise , course
if @exercise
@exercise . exercise_questions . where ( :question_type = > [ 1 , 2 , 3 ] ) . each do | eq |
if eq . exercise_standard_answers . count == 0
@status = 1
break
end
end
end
end
end
def add_to_exercise_bank
exercise_bank = User . current . exercise_banks . where ( :container_id = > @exercise . id , :container_type = > " Exercise " ) . first
if exercise_bank . present?
exercise_bank . update_attributes ( :name = > @exercise . exercise_name , :description = > @exercise . exercise_description , :course_list_id = > @exercise . course . try ( :course_list_id ) )
question_bank = QuestionBank . where ( :container_id = > exercise_bank . id , :container_type = > exercise_bank . container_type ) . first
question_bank . update_attributes ( :name = > exercise_bank . name , :course_list_id = > exercise_bank . course_list_id ) if question_bank . present?
exercise_bank . exercise_bank_questions . destroy_all
else
exercise_bank = ExerciseBank . new ( :name = > @exercise . exercise_name , :description = > @exercise . exercise_description , :user_id = > User . current . id , :is_public = > 0 ,
:course_list_id = > @exercise . course . try ( :course_list_id ) , :container_id = > @exercise . id , :container_type = > " Exercise " , :quotes = > 1 )
if exercise_bank . save
QuestionBank . create ( :name = > exercise_bank . name , :container_id = > exercise_bank . id , :container_type = > exercise_bank . container_type ,
:quotes = > exercise_bank . quotes , :user_id = > exercise_bank . user_id , :is_public = > exercise_bank . is_public , :course_list_id = > exercise_bank . course_list_id )
end
end
@exercise . exercise_questions . each do | q |
option = {
:question_title = > q [ :question_title ] ,
:question_type = > q [ :question_type ] || 1 ,
:question_number = > q [ :question_number ] ,
:question_score = > q [ :question_score ] ,
:shixun_id = > q [ :shixun_id ]
}
exercise_bank_question = exercise_bank . exercise_bank_questions . new option
if q . question_type != 5
for i in 1 .. q . exercise_choices . count
choice_option = {
:choice_position = > i ,
:choice_text = > q . exercise_choices [ i - 1 ] [ :choice_text ]
}
exercise_bank_question . exercise_bank_choices . new choice_option
end
for i in 1 .. q . exercise_standard_answers . count
standard_answer_option = {
:exercise_bank_choice_id = > q . exercise_standard_answers [ i - 1 ] [ :exercise_choice_id ] ,
:answer_text = > q . exercise_standard_answers [ i - 1 ] [ :answer_text ]
}
exercise_bank_question . exercise_bank_standard_answers . new standard_answer_option
end
else
for i in 1 .. q . exercise_shixun_challenges . count
challenge_option = {
:position = > i ,
:challenge_id = > q . exercise_shixun_challenges [ i - 1 ] [ :challenge_id ] ,
:shixun_id = > q . exercise_shixun_challenges [ i - 1 ] [ :shixun_id ] ,
:question_score = > q . exercise_shixun_challenges [ i - 1 ] [ :question_score ]
}
exercise_bank_question . exercise_bank_shixun_challenges . new challenge_option
end
end
end
exercise_bank . save
end
private
#测验列表转换为excel
def exercise_to_xls items
xls_report = StringIO . new
book = Spreadsheet :: Workbook . new
sheet1 = book . create_worksheet :name = > " exercise "
blue = Spreadsheet :: Format . new :color = > :blue , :weight = > :bold , :size = > 10
sheet1 . row ( 0 ) . default_format = blue
sheet1 . row ( 0 ) . concat ( [ l ( :excel_user_id ) , l ( :excel_user_name ) , l ( :excel_nickname ) , l ( :excel_student_id ) , l ( :excel_course_group ) , l ( :excel_mail ) , l ( :excel_objective_score ) , l ( :excel_subjective_score ) , l ( :excel_f_score ) , l ( :excel_answer_time ) ] )
count_row = 1
members = @exercise . course . members
items . each do | exercise |
sheet1 [ count_row , 0 ] = exercise . user . id
sheet1 [ count_row , 1 ] = exercise . user . show_real_name
sheet1 [ count_row , 2 ] = exercise . user . login
sheet1 [ count_row , 3 ] = exercise . user . user_extensions . student_id
sheet1 [ count_row , 4 ] = member_group_name members , exercise . user . id
sheet1 [ count_row , 5 ] = exercise . user . mail
sheet1 [ count_row , 6 ] = exercise . objective_score == - 1 ? " 0.0 " : format ( " %.1f " , exercise . objective_score )
sheet1 [ count_row , 7 ] = exercise . subjective_score == - 1 ? " 0.0 " : format ( " %.1f " , exercise . subjective_score )
sheet1 [ count_row , 8 ] = exercise . score
sheet1 [ count_row , 9 ] = exercise . commit_status == 0 ? l ( :excel_no_answer ) : format_time ( exercise . start_at )
count_row += 1
end
book . write xls_report
xls_report . string
end
# ExerciseUser记录用户是否已提交问卷有对应的记录则已提交, 没有则新建一个
def get_exercise_user exercise_id , user_id
eu = ExerciseUser . find_by_exercise_id_and_user_id ( exercise_id , user_id )
if eu . nil?
eu = ExerciseUser . new
end
eu
end
# 获取当前学生回答问题的答案
def get_user_answer ( question , user )
# user_answer = ExerciseAnswer.where("user_id=? and exercise_question_id=?", user.id, question.id).first
user_answer = question . exercise_answers . where ( " #{ ExerciseAnswer . table_name } .user_id = #{ user . id } " )
user_answer
end
# 获取问题的标准答案
def get_user_standard_answer ( question , user )
if question . question_type == 3
standard_answer = [ ]
question . exercise_standard_answers . each do | answer |
standard_answer << answer . answer_text . strip . downcase
end
else
standard_answer = question . exercise_standard_answers . first
end
standard_answer
end
# 是否完成了答题
def get_complete_question ( exercise , user )
questions = exercise . exercise_questions . includes ( :exercise_answers )
complete_question = [ ]
questions . each do | question |
answers = question . exercise_answers . select { | e | e . user_id == user . id }
if ! ( answers . nil? || answers . count < 1 )
complete_question << question
end
end
complete_question
end
# 获取答题百分比
def get_percent exercise , user
complete_count = get_complete_question ( exercise , user ) . count
if exercise . exercise_questions . count == 0
return 0
else
return ( complete_count . to_f / exercise . exercise_questions . count . to_f ) * 100
end
end
def remove_invalid_exercise ( course )
exercises = course . exercises . where ( " exercise_name=? " , " " )
unless exercises . empty?
exercises . each do | exercise |
if exercise . exercise_questions . empty?
exercise . destroy
end
end
end
end
def find_exercise_and_course
@exercise = Exercise . find params [ :id ]
@course = Course . find @exercise . course_id
rescue Exception = > e
render_404
end
def find_course
@course = Course . find params [ :course_id ]
rescue Exception = > e
render_404
end
#是不是课程的老师
def teacher_of_course
render_403 unless User . current . allowed_to? ( :as_teacher , @course ) || User . current . admin?
end
end