#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_name => params[:question_type] == '5' ? params[:shixun_name] : nil, :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 @exercise_question.shixun_name = params[:shixun_name].strip if !params[:shixun_name].blank? 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], :shixun_name => q[:shixun_name] } 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