From 9ddd5f6f75c47178c18740d601386da3af0fbc57 Mon Sep 17 00:00:00 2001 From: cxt <853663049@qq.com> Date: Wed, 15 Jan 2020 15:35:38 +0800 Subject: [PATCH] =?UTF-8?q?=E8=AF=95=E5=8D=B7=E5=8A=A0=E7=B4=A2=E5=BC=95?= =?UTF-8?q?=E3=80=81=E6=9B=B4=E6=94=B9=E7=AE=97=E5=88=86=E8=A7=84=E5=88=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exercise_answers_controller.rb | 7 ++- app/helpers/exercise_questions_helper.rb | 10 ++-- app/helpers/exercises_helper.rb | 56 +++++++++++-------- ...30_add_choice_index_to_exercise_answers.rb | 17 ++++++ ...ce_index_uniq_index_to_exercise_answers.rb | 13 +++++ 5 files changed, 75 insertions(+), 28 deletions(-) create mode 100644 db/migrate/20200115020230_add_choice_index_to_exercise_answers.rb create mode 100644 db/migrate/20200115030135_add_choice_index_uniq_index_to_exercise_answers.rb diff --git a/app/controllers/exercise_answers_controller.rb b/app/controllers/exercise_answers_controller.rb index 158628475..31df2291e 100644 --- a/app/controllers/exercise_answers_controller.rb +++ b/app/controllers/exercise_answers_controller.rb @@ -26,6 +26,7 @@ class ExerciseAnswersController < ApplicationController end elsif q_type == Exercise::MULTIPLE #多选题的 choice_ids = params[:exercise_choice_id].present? ? params[:exercise_choice_id] : [] + question_choice_ids = @exercise_question.exercise_choices.pluck(:id) ea_ids = ea.pluck(:exercise_choice_id) common_answer_ids = choice_ids & ea_ids #已经存在的试卷选项id @@ -37,7 +38,8 @@ class ExerciseAnswersController < ApplicationController :user_id => current_user.id, :exercise_question_id => @exercise_question.id, :exercise_choice_id => e, - :answer_text => "" + :answer_text => "", + :choice_index => question_choice_ids.index(e).to_i + 1 # choice的序号 } ex_a = ExerciseAnswer.new(answer_option) ex_a.save! @@ -52,7 +54,8 @@ class ExerciseAnswersController < ApplicationController :user_id => current_user.id, :exercise_question_id => @exercise_question.id, :exercise_choice_id => choice_id, - :answer_text => answer_text + :answer_text => answer_text, + :choice_index => choice_id } ea_answer = ea.search_answer_users("exercise_choice_id",choice_id) if ea.present? && ea_answer.present? diff --git a/app/helpers/exercise_questions_helper.rb b/app/helpers/exercise_questions_helper.rb index 69dee034f..1cc613bc6 100644 --- a/app/helpers/exercise_questions_helper.rb +++ b/app/helpers/exercise_questions_helper.rb @@ -2,9 +2,11 @@ module ExerciseQuestionsHelper def get_exercise_question_info(question,exercise,ex_user,ex_answerer_id) answered_content = [] exercise_answers = question.exercise_answers.search_exercise_answer("user_id",ex_answerer_id) #试卷用户的回答 - if question.question_type <= 2 + if question.question_type == Exercise::SINGLE || question.question_type == Exercise::JUDGMENT + answered_content << exercise_answers.last&.exercise_choice_id if exercise_answers.present? + elsif question.question_type == Exercise::MULTIPLE answered_content = exercise_answers.pluck(:exercise_choice_id) - elsif question.question_type == 3 + elsif question.question_type == Exercise::COMPLETION exercise_answers.each do |a| u_answer = { "choice_id": a.exercise_choice_id, @@ -12,10 +14,10 @@ module ExerciseQuestionsHelper } answered_content.push(u_answer) end - elsif question.question_type == 4 + elsif question.question_type == Exercise::SUBJECTIVE answered_content = exercise_answers.pluck(:answer_text) end - if question.question_type == 5 && ex_user.present? && ex_user.commit_status == 1 #存在实训题,且用户已提交了的,如果实训题只做了一半就关闭,则相当于不要了 + if question.question_type == Exercise::PRACTICAL && ex_user.present? && ex_user.commit_status == 1 #存在实训题,且用户已提交了的,如果实训题只做了一半就关闭,则相当于不要了 if exercise.exercise_status == 3 #如果试卷已截止,则可以看到分数,否则不能查看分数 shixun_type = 2 else diff --git a/app/helpers/exercises_helper.rb b/app/helpers/exercises_helper.rb index 513f980d8..0ec1f6cb3 100644 --- a/app/helpers/exercises_helper.rb +++ b/app/helpers/exercises_helper.rb @@ -16,8 +16,8 @@ module ExercisesHelper end if q_type <= Exercise::JUDGMENT - if answers_content.present? #学生有回答时,分数已经全部存到exercise_answer 表,所以可以直接取第一个值 - ques_score = answers_content.first.score + if answers_content.present? #学生有回答时,分数已经全部存到exercise_answer 表,多选题直接取第一个值,单选题和判断题选最后一个值(考虑并发) + ques_score = q_type == Exercise::MULTIPLE ? answers_content.first.score : answers_content.last.score ques_score = ques_score < 0 ? 0.0 : ques_score # answer_choice_array = [] # answers_content.each do |a| @@ -441,30 +441,42 @@ module ExercisesHelper end if q.question_type <= 2 #为选择题或判断题时 if answers_content.present? #学生有回答时 - answer_choice_array = [] - answers_content.each do |a| - answer_choice_array.push(a.exercise_choice.choice_position) #学生答案的位置 - end - user_answer_content = answer_choice_array.sort - standard_answer = q.exercise_standard_answers.pluck(:exercise_choice_id).sort #该问题的标准答案,可能有多个 - - #TODO: 旧版多选题的标准答案是放在一个里面的,新版又做成了一个题有多个标准答案(exercise_choice_id存放的是标准答案的位置..) - if q.question_type == 1 && standard_answer.size == 1 - standard_answer = standard_answer.first.to_s.split("").map(&:to_i).sort - end - - if user_answer_content == standard_answer #答案一致,多选或单选才给分,答案不对不给分 - if standard_answer.size > 0 + if q.question_type == 0 || q.question_type == 2 ## 单选、判断题的算分与多选题分开计算 + user_answer = answers_content.last.exercise_choice.choice_position + standard_answer = q.exercise_standard_answers.first&.exercise_choice_id + if standard_answer.present? && user_answer == standard_answer q_score_1 = q.question_score - # q_score_1 = (q.question_score.to_f / standard_answer.count) #当多选答案正确时,每个answer的分数均摊。 + score1 = score1 + q.question_score else - q_score_1 = 0.0 + q_score_1 = -1.0 end - answers_content.update_all(:score => q_score_1) - score1 = score1 + q.question_score + answers_content.last.update!(score: q_score_1) else - answers_content.update_all(:score => -1.0) - score1 += 0.0 + answer_choice_array = [] + answers_content.each do |a| + answer_choice_array.push(a.exercise_choice.choice_position) #学生答案的位置 + end + user_answer_content = answer_choice_array.sort + standard_answer = q.exercise_standard_answers.pluck(:exercise_choice_id).sort #该问题的标准答案,可能有多个 + + #TODO: 旧版多选题的标准答案是放在一个里面的,新版又做成了一个题有多个标准答案(exercise_choice_id存放的是标准答案的位置..) + if q.question_type == 1 && standard_answer.size == 1 + standard_answer = standard_answer.first.to_s.split("").map(&:to_i).sort + end + + if user_answer_content == standard_answer #答案一致,多选或单选才给分,答案不对不给分 + if standard_answer.size > 0 + q_score_1 = q.question_score + # q_score_1 = (q.question_score.to_f / standard_answer.count) #当多选答案正确时,每个answer的分数均摊。 + else + q_score_1 = 0.0 + end + answers_content.update_all(:score => q_score_1) + score1 = score1 + q.question_score + else + answers_content.update_all(:score => -1.0) + score1 += 0.0 + end end else score1 += 0.0 diff --git a/db/migrate/20200115020230_add_choice_index_to_exercise_answers.rb b/db/migrate/20200115020230_add_choice_index_to_exercise_answers.rb new file mode 100644 index 000000000..cb518bb42 --- /dev/null +++ b/db/migrate/20200115020230_add_choice_index_to_exercise_answers.rb @@ -0,0 +1,17 @@ +class AddChoiceIndexToExerciseAnswers < ActiveRecord::Migration[5.2] + def change + add_column :exercise_answers, :choice_index, :integer, default: 1 + + multi_questions = ExerciseQuestion.where(question_type: 1) + multi_questions.includes(:exercise_choices, :exercise_answers).find_each do |question| + exercise_answers = question.exercise_answers + exercise_answers.find_each do |answer| + choice_index = question.exercise_choices.pluck(:id).index(answer.exercise_choice_id).to_i + 1 + answer.update_column('choice_index', choice_index) + end + puts "multi_questions: #{question.id}" + end + + ExerciseAnswer.joins(:exercise_question).where(exercise_questions: {question_type: 3}).update_all("choice_index = exercise_choice_id") + end +end diff --git a/db/migrate/20200115030135_add_choice_index_uniq_index_to_exercise_answers.rb b/db/migrate/20200115030135_add_choice_index_uniq_index_to_exercise_answers.rb new file mode 100644 index 000000000..d870fba7f --- /dev/null +++ b/db/migrate/20200115030135_add_choice_index_uniq_index_to_exercise_answers.rb @@ -0,0 +1,13 @@ +class AddChoiceIndexUniqIndexToExerciseAnswers < ActiveRecord::Migration[5.2] + def change + sql = %Q(delete from exercise_answers where (exercise_question_id, user_id, choice_index) in + (select * from (select exercise_question_id, user_id, choice_index from exercise_answers group by exercise_question_id, user_id, choice_index having count(*) > 1) a) + and id not in (select * from (select max(id) from exercise_answers group by exercise_question_id, user_id, choice_index having count(*) > 1 order by id) b)) + ActiveRecord::Base.connection.execute sql + + add_index :exercise_answers, [:exercise_question_id, :user_id, :choice_index], name: 'exercise_user_choice_index', unique: true + + remove_index :exercise_answers, name: :exercise_choice_index + + end +end