You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
pgfqe6ch8/app/controllers/exercise_controller.rb

1653 lines
75 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#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 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