diff --git a/Gemfile b/Gemfile index 0473e221e..3450c06e8 100644 --- a/Gemfile +++ b/Gemfile @@ -89,3 +89,5 @@ gem 'sinatra' # batch insert gem 'bulk_insert' +# elasticsearch +# gem 'searchkick' diff --git a/app/controllers/exercise_questions_controller.rb b/app/controllers/exercise_questions_controller.rb index 3d488c7b0..65fd77d98 100644 --- a/app/controllers/exercise_questions_controller.rb +++ b/app/controllers/exercise_questions_controller.rb @@ -47,7 +47,7 @@ class ExerciseQuestionsController < ApplicationController if @exercise_question.save #为选择题(包括单选和多选)的时候,创建问题选项 ques_type = @exercise_question.question_type - if ques_type <= 1 + if ques_type <= Exercise::MULTIPLE choices_array = params[:question_choices] choices_count= choices_array.count standard_answer = params[:standard_answers] #为数组格式,因为可能会有单选和多选,标准答案,已提前判断不能为空, @@ -70,13 +70,13 @@ class ExerciseQuestionsController < ApplicationController } question_standard_answer = ExerciseStandardAnswer.new(standard_option) question_standard_answer.save - if standard_answer.count > 1 && ques_type == 0 #当标准答案数大于1,且不为多选时,修改为多选 - @exercise_question.update_attribute("question_type",1) - elsif standard_answer.count == 1 && ques_type == 1 - @exercise_question.update_attribute("question_type",0) + if standard_answer.count > 1 && ques_type == Exercise::SINGLE #当标准答案数大于1,且不为多选时,修改为多选 + @exercise_question.update_attribute("question_type",Exercise::MULTIPLE) + elsif standard_answer.count == 1 && ques_type == Exercise::MULTIPLE + @exercise_question.update_attribute("question_type",Exercise::SINGLE) end end - elsif ques_type == 2 #这个为判断题 + elsif ques_type == Exercise::JUDGMENT #这个为判断题 choices_array = params[:question_choices] #判断的选项,对/错等等 choices_count= choices_array.count (1..choices_count).each do |c| @@ -95,7 +95,7 @@ class ExerciseQuestionsController < ApplicationController } question_standard_answer = ExerciseStandardAnswer.new(standard_option) question_standard_answer.save - elsif ques_type == 3 #填空题,每空的参考答案有多个,那么以位置对应 + elsif ques_type == Exercise::COMPLETION #填空题,每空的参考答案有多个,那么以位置对应 standard_answer = params[:standard_answers] standard_answer.each do |a| null_choice_id = a[:choice_id] @@ -110,7 +110,7 @@ class ExerciseQuestionsController < ApplicationController question_standard_answer.save end end - elsif ques_type == 4 #简答题 + elsif ques_type == Exercise::SUBJECTIVE #简答题 if params[:standard_answers].present? && params[:standard_answers].reject(&:blank?).count > 0 standard_answer = params[:standard_answers] standard_answer.each do |a| @@ -122,7 +122,7 @@ class ExerciseQuestionsController < ApplicationController question_standard_answer.save end end - elsif ques_type == 5 #实训题 + elsif ques_type == Exercise::PRACTICAL #实训题 shixun = Shixun.find_by(id: params[:shixun_id]) shixun_scores = params[:question_scores] #试卷有多个的分值有多个分数表,所以为分数的数组 shixun_name = params[:shixun_name] || shixun.name @@ -225,7 +225,7 @@ class ExerciseQuestionsController < ApplicationController #试卷未发布时,当标准答案存在时,可修改标准答案内容,可增删标准答案,否则只能修改标准答案,不能增删标准答案 @exercise_answers_array = @exercise_question.exercise_standard_answers #问卷的全部标准答案 if standard_answer.present? - if @exercise_question.question_type <= 2 #选择题/判断题,标准答案为一个或多个 + if @exercise_question.question_type <= Exercise::JUDGMENT #选择题/判断题,标准答案为一个或多个 exercise_standard_choices = @exercise_answers_array.pluck(:exercise_choice_id) #问题以前的全部标准答案选项位置 common_standard_choices = standard_answer & exercise_standard_choices # 传入的标准答案的选项位置和以前的并集,即表示不用做更改的 old_left_standard_choices = exercise_standard_choices - common_standard_choices # 以前的差集共同的,剩余的表示需要删掉 @@ -244,12 +244,12 @@ class ExerciseQuestionsController < ApplicationController end end - if standard_answer.count > 1 && @exercise_question.question_type == 0 #当标准答案数大于1,且不为多选时,修改为多选 - @exercise_question.update_attribute("question_type",1) - elsif standard_answer.count == 1 && @exercise_question.question_type == 1 - @exercise_question.update_attribute("question_type",0) + if standard_answer.count > 1 && @exercise_question.question_type == Exercise::SINGLE #当标准答案数大于1,且不为多选时,修改为多选 + @exercise_question.update_attribute("question_type",Exercise::MULTIPLE) + elsif standard_answer.count == 1 && @exercise_question.question_type == Exercise::MULTIPLE + @exercise_question.update_attribute("question_type",Exercise::SINGLE) end - elsif @exercise_question.question_type == 3 #填空题 + elsif @exercise_question.question_type == Exercise::COMPLETION #填空题 old_ex_answer = @exercise_question.exercise_standard_answers #当前问题的全部标准答案 old_ex_answer_choice_ids = old_ex_answer.pluck(:exercise_choice_id).uniq #全部的答案数组序号 new_ex_answer_choice_ids = standard_answer.map {|a| a[:choice_id]}.uniq #新传入的答案数组序号 @@ -321,7 +321,7 @@ class ExerciseQuestionsController < ApplicationController end end end - if @exercise_question.question_type == 4 #主观题 + if @exercise_question.question_type == Exercise::SUBJECTIVE #主观题 main_standard_answer = standard_answer.present? ? standard_answer.first : nil if @exercise_answers_array.present? @exercise_answers_array.first.update_attribute("answer_text",main_standard_answer) @@ -333,7 +333,7 @@ class ExerciseQuestionsController < ApplicationController question_standard_answer = ExerciseStandardAnswer.new(standard_option) question_standard_answer.save end - elsif @exercise_question.question_type == 5 + elsif @exercise_question.question_type == Exercise::PRACTICAL question_score = 0 shixun_name = params[:shixun_name] || @exercise_question.shixun_name @exercise_question.exercise_shixun_challenges.each_with_index do |challenge, index| @@ -347,7 +347,7 @@ class ExerciseQuestionsController < ApplicationController #当试卷已发布时(试卷的总状态),当标准答案修改时,如有已提交的学生,需重新计算分数. - if @exercise.exercise_status == 2 + if @exercise.exercise_status == Exercise::PUBLISHED ex_users_committed = @exercise.exercise_users.exercise_user_committed if ex_users_committed.size > 0 ex_users_committed.each do |ex_user| @@ -375,7 +375,7 @@ class ExerciseQuestionsController < ApplicationController begin opr = params[:opr] current_q_p = @exercise_question.question_number.to_i #问题的当前位置 - if @exercise.exercise_status.to_i == 1 + if @exercise.exercise_status.to_i == Exercise::UNPUBLISHED if opr.present? if opr.to_s == "up" last_q_p = @exercise.exercise_questions.find_by(question_number: (current_q_p - 1)) # 当前问题的前一个问题 @@ -457,7 +457,7 @@ class ExerciseQuestionsController < ApplicationController ex_obj_score = @exercise_current_user.objective_score #全部客观题得分 ex_subj_score = @exercise_current_user.subjective_score < 0.0 ? 0.0 : @exercise_current_user.subjective_score #全部主观题得分 ex_answers = @exercise_question.exercise_answers.search_answer_users("user_id",@user_id) #当前用户答案的得分 - if @exercise_question.question_type == 3 #当为填空题,更新问题的总分, + if @exercise_question.question_type == Exercise::COMPLETION #当为填空题,更新问题的总分, ex_answer_old = ex_answers.score_reviewed.pluck(:score).sum #每一关的得分总和 each_right_score = (@c_score / ex_answers.count.to_f) #调分后,平均每关的分数 new_obj_score = ex_obj_score - ex_answer_old + @c_score @@ -468,8 +468,8 @@ class ExerciseQuestionsController < ApplicationController } @exercise_current_user.update_attributes(ex_scores) ex_answers.update_all(:score => each_right_score) #所有的正确选项需重新更新 - elsif @exercise_question.question_type == 4 #当为主观题时 - if ex_answers.present? + elsif @exercise_question.question_type == Exercise::SUBJECTIVE #当为主观题时 + if ex_answers.exists? ex_answers_old_score = ex_answers.first.score > 0.0 ? ex_answers.first.score : 0.0 #原分数小于0,取0 new_sub_score = ex_subj_score - ex_answers_old_score + @c_score #原全部主观题总分减去原该主观题得分再加调分后的分数,即为当前全部主观题得分 ex_answers.first.update_attribute("score",@c_score) @@ -481,7 +481,7 @@ class ExerciseQuestionsController < ApplicationController :answer_text => "" } ExerciseAnswer.create(answer_option) - new_sub_score = @c_score + new_sub_score = ex_subj_score + @c_score end total_scores = ex_obj_score + new_sub_score ex_scores = { @@ -490,8 +490,7 @@ class ExerciseQuestionsController < ApplicationController } @exercise_current_user.update_attributes(ex_scores) - elsif @exercise_question.question_type == 5 - # ex_answers = @exercise_question.exercise_shixun_answers.search_shixun_answers("user_id",@user_id).search_shixun_answers("exercise_shixun_challenge_id",@shixun_a_id) + elsif @exercise_question.question_type == Exercise::PRACTICAL ex_answers = @exercise_question.exercise_shixun_answers.where(user_id:@user_id,exercise_shixun_challenge_id:@shixun_a_id) if ex_answers.present? #当为实训题时 @@ -622,13 +621,13 @@ class ExerciseQuestionsController < ApplicationController end def check_exercise_status - normal_status(-1,"不能更改试卷问题!") if @exercise.exercise_status != 1 + normal_status(-1,"不能更改试卷问题!") if @exercise.exercise_status != Exercise::UNPUBLISHED end #更新时不能修改的内容 def cannot_change_column #已发布的/已截止的/评阅中的状态时,不能修改分数,不能增删问题和答案,不能修改标准答案,可以修改选项内容/题目内容,这里仅指单个问题 - if @exercise.exercise_status != 1 + if @exercise.exercise_status != Exercise::UNPUBLISHED question_score = @exercise_question.question_score #原来的分数 update_question_score = params[:question_score].to_f.round(1) #传入的分数 choices_count = @exercise_question.exercise_choices.size #原来的选项个数 @@ -641,12 +640,12 @@ class ExerciseQuestionsController < ApplicationController elsif update_choices_count != choices_count #选项个数有修改 normal_status(-1,"已发布/已截止,不允许增删答案!") elsif standard_answer.present? - if @exercise_question.question_type == 3 + if @exercise_question.question_type == Exercise::COMPLETION exercise_answers_text = standard_answer.map{|a| a[:answer_text]}.sum.uniq unless (standard_answer.count == exercise_choice_ids.count) && (standard_answers_text.count == exercise_answers_text.count) normal_status(-1,"已发布/已截止,不允许增删标准答案!") end - elsif @exercise_question.question_type == 4 + elsif @exercise_question.question_type == Exercise::SUBJECTIVE unless standard_answers_text.count == standard_answer.count normal_status(-1,"已发布/已截止,不允许增删标准答案!") end @@ -663,13 +662,13 @@ class ExerciseQuestionsController < ApplicationController normal_status(-1,"用户不存在!") elsif @c_score.blank? normal_status(-1,"分数不能为空!") - elsif @exercise_question.question_type <= 1 || @exercise_question.question_type == 2 + elsif @exercise_question.question_type <= Exercise::JUDGMENT normal_status(-1,"选择题/判断题不能调分!") elsif params[:comment].present? && params[:comment].length > 100 normal_status(-1,"评语不能超过100个字符!") else @shixun_a_id = params[:shixun_challenge_id] - if @exercise_question.question_type == 5 #当为实训题时,为关卡的分数 + if @exercise_question.question_type == Exercise::PRACTICAL #当为实训题时,为关卡的分数 @shixun_challenge = @exercise_question.exercise_shixun_challenges.cha_id_find(@shixun_a_id) if @shixun_challenge.present? @old_ques_score = @shixun_challenge.first.question_score diff --git a/app/controllers/exercises_controller.rb b/app/controllers/exercises_controller.rb index 862166f00..c02bdccec 100644 --- a/app/controllers/exercises_controller.rb +++ b/app/controllers/exercises_controller.rb @@ -1005,19 +1005,6 @@ class ExercisesController < ApplicationController @exercise_user_current.update_attribute("start_at",Time.now) end end - - # ex_time = @exercise.time - # if ex_time > 0 - # time_mill = ex_time * 60 #转为秒 - # exercise_end_time = @exercise.end_time.present? ? @exercise.end_time.to_i : 0 - # exercise_user_start = @exercise_user_current.present? ? @exercise_user_current.start_at.to_i : 0 - # if (exercise_user_start + time_mill) > exercise_end_time - # time_mill = exercise_end_time - exercise_user_start #如果开始答题时间加试卷的限时长大于试卷的截止时间,则以试卷的截止时间到开始答题时间为试卷的限时 - # end - # exercise_user_left_time = Time.now.to_i - exercise_user_start #用户已回答的时间 - # @user_left_time = (time_mill < exercise_user_left_time) ? nil : (time_mill - exercise_user_left_time) #当前用户对试卷的回答剩余时间 - # end - @t_user_exercise_status = @exercise.get_exercise_status(current_user) @user_left_time = nil @@ -1029,10 +1016,7 @@ class ExercisesController < ApplicationController @user_exercise_status = 0 #可编辑 end - @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges, - :exercise_shixun_answers, - :exercise_answers, - :exercise_standard_answers) + @exercise_questions = @exercise.exercise_questions if @exercise.question_random @exercise_questions = @exercise_questions.order("RAND()") @@ -1040,7 +1024,10 @@ class ExercisesController < ApplicationController @exercise_questions = @exercise_questions.order("question_number ASC") end # 判断问题是否已回答还是未回答 - @exercise_questions = @exercise_questions.includes(:exercise_stand_answers,:exercise_answers,:exercise_shixun_answers) + @exercise_questions = @exercise_questions.includes(:exercise_shixun_challenges, + :exercise_shixun_answers, + :exercise_answers, + :exercise_standard_answers) if @t_user_exercise_status == 3 get_each_student_exercise(@exercise.id,@exercise_questions,@exercise_current_user_id) @@ -1127,14 +1114,14 @@ class ExercisesController < ApplicationController ActiveRecord::Base.transaction do begin # 1 老师权限,0 学生权限 - @is_teacher_or = @user_course_identity < Course::STUDENT ? 1 : 0 + @is_teacher_or = (@user_course_identity < Course::STUDENT) ? 1 : 0 @student_status = 2 - # @exercise_answerer = User.find_by(id:@exercise_current_user_id) #试卷回答者 @exercise_questions = @exercise.exercise_questions.includes(:exercise_shixun_challenges,:exercise_standard_answers,:exercise_answers,:exercise_shixun_answers).order("question_number ASC") @question_status = [] - get_exercise_status = @exercise.get_exercise_status(current_user) + get_exercise_status = @exercise.get_exercise_status(current_user) #当前用户的试卷状态 + @ex_answer_status = @exercise.get_exercise_status(@ex_user) #当前试卷用户的试卷状态 if @ex_user.present? && @is_teacher_or == 0 - if get_exercise_status == 2 #当前用户已提交,且试卷未截止 + if get_exercise_status == Exercise::PUBLISHED #当前用户已提交,且试卷未截止 if @ex_user.commit_status == 0 #学生未提交,且当前为学生 @student_status = 0 else @@ -1164,69 +1151,65 @@ class ExercisesController < ApplicationController @course_all_members = @course.students @c_group_counts = @course.course_groups_count question_types = @exercise.exercise_questions.pluck(:question_type).uniq - @exercise_publish_count = get_user_permission_course(exercise_ids,2).count #判断是否有已发布的分班 - @exercise_unpublish_count = get_user_permission_course(exercise_ids,1).count #判断是否有未发布的分班 + @exercise_publish_count = get_user_permission_course(exercise_ids,Exercise::PUBLISHED).count #判断是否有已发布的分班 + @exercise_unpublish_count = get_user_permission_course(exercise_ids,Exercise::UNPUBLISHED).count #判断是否有未发布的分班 - if (question_types.size > 1) && question_types.include?(4) #是否包含主观题,或者是否大于1 + if (question_types.size > 1) && question_types.include?(Exercise::SUBJECTIVE) #是否包含主观题,或者是否大于1 @subjective_type = 1 else @subjective_type = 0 end + #初始化值 + @exercise_users_list = [] #答题用户列表 + @exercise_course_groups = [] #当前用户有权限的班级 + @exercise_unanswers = 0 # 未答用户数 + @exercise_answers = 0 #已答用户数 + @exercise_users_count = 0 #全部用户数 + @teacher_review_count = 0 #已评数 + @teacher_unreview_count = 0 #未评数 + + #试卷的答题列表页的显示用户 if @user_course_identity < Course::STUDENT #当前为老师,而且老师只能查看自己班级的/课堂的试卷 @exercise_current_user_status = 0 - if @exercise_status == 1 - @exercise_users_list = [] - @exercise_course_groups = [] - @exercise_unanswers = 0 - @exercise_answers = 0 - else + unless @exercise_status == 1 ex_common_ids = @exercise.common_published_ids(current_user.id) @exercise_course_groups = @course.get_ex_published_course(ex_common_ids) @exercise_users_list = @exercise.all_exercise_users(current_user.id) #当前老师所在班级的全部学生 get_exercise_answers(@exercise_users_list, @exercise_status) end - elsif @user_course_identity > Course::ASSISTANT_PROFESSOR #当前为学生或者有过答题的(提交/未提交) + else #当前为学生或者有过答题的 @ex_user_end_time = @exercise.get_exercise_end_time(current_user.id) #当前用户所看到的剩余时间 @exercise_all_users = @exercise.get_stu_exercise_users get_exercise_answers(@exercise_all_users, @exercise_status) # 未答和已答的 - exercise_current_user = @exercise_all_users.exercise_commit_users(current_user.id) #当前用户是否开始做试卷(提交/未提交/没做) - if exercise_current_user.present? - @exercise_current_user_status = 1 #当前用户的状态,为学生 - if @exercise.score_open && @exercise_status == 3 && exercise_current_user.present? #勾选了成绩公开且试卷已截止的 + exercise_current_user = @exercise_all_users.exercise_commit_users(current_user.id) + if exercise_current_user.exists? #表示为课堂学生或已回答的 + @exercise_current_user_status = 1 + if @exercise.score_open && @exercise_status == 3 #勾选了成绩公开且试卷已截止的 all_user_ids = @exercise_all_users.pluck(:user_id) all_user_ids.delete(current_user.id) #删除了当前用户的ID @exercise_users_list = @exercise_all_users.exercise_commit_users(all_user_ids).distinct @current_user_ex_answers = exercise_current_user #当前用户的回答 else - @exercise_users_list = exercise_current_user.present? ? exercise_current_user.distinct : [] + @exercise_users_list = exercise_current_user end - else - @exercise_all_users = @exercise.get_stu_exercise_users - get_exercise_answers(@exercise_all_users, @exercise_status) # 未答和已答的 + else #表示为未回答的,或未非课堂成员的 @exercise_current_user_status = 2 #当前用户非课堂成员 - @exercise_users_list = [] end end - if @exercise_users_list.present? && @exercise_users_list.count > 0 - @exercise_users_count = @exercise_users_list.count #当前显示的全部成员数量 - else - @exercise_users_count = 0 - end if @exercise_unanswers < 0 @exercise_unanswers = 0 end - @teacher_review_count = 0 - @teacher_unreview_count = 0 #筛选/分类,排序 order = params[:order] - if @exercise_users_list.present? && @exercise_users_list.size > 0 + if @exercise_users_list.exists? && @exercise_users_list.size > 0 + @exercise_users_count = @exercise_users_list.size #当前显示的全部成员数量 teacher_reviews = @exercise_users_list.exercise_review teacher_unreviews = @exercise_users_list.exercise_unreview - @teacher_review_count = teacher_reviews.count #已评阅 - @teacher_unreview_count = teacher_unreviews.count #未评阅 + @teacher_review_count = teacher_reviews.size #已评阅 + @teacher_unreview_count = teacher_unreviews.size #未评阅 #是否评阅 if params[:review].present? @@ -1284,7 +1267,7 @@ class ExercisesController < ApplicationController if params[:format] == "xlsx" if @user_course_identity > Course::ASSISTANT_PROFESSOR tip_exception(403,"无权限操作") - elsif @exercise_status == 1 + elsif @exercise_status == Exercise::UNPUBLISHED normal_status(-1,"试卷未发布") elsif (@exercise_users_size == 0) || ( @export_ex_users&.exercise_user_committed.size == 0) normal_status(-1,"暂无用户提交") @@ -1530,30 +1513,22 @@ class ExercisesController < ApplicationController def get_user_permission_course(exercise_ids,status) exercise_status = status.to_i #传入的试卷发布状态 unpublish_group = [] - # g_course_ids = @course.teacher_course_groups.get_user_groups(current_user.id).pluck(:course_group_id).reject(&:blank?).uniq #当前用户有权限的分班 - # #用户的班级,理论上用户的班级要大于等于试卷设置的班级 - # if g_course_ids.blank? || g_course_ids.include?(0) - # user_groups_id = @course.course_groups.pluck(:id) - # else - # user_groups_id = g_course_ids - # end + course_groups = [] user_groups_id = @course.charge_group_ids(current_user) - exercises_all = Exercise.where(id:exercise_ids) + exercises_all = Exercise.includes(:exercise_group_settings).where(id:exercise_ids) exercises_all.each do |exercise| if exercise.present? if exercise.unified_setting #统一设置只有两种情况,全部发布,全部截止 exercise_user_status = exercise.get_exercise_status(current_user) #当前用户的能看到的试卷 - if (exercise_user_status == exercise_status) || exercise_status == 3 #未发布的情况 + if (exercise_user_status == exercise_status) || exercise_status == Exercise::ENDED #未发布的情况 unpublish_group = unpublish_group + user_groups_id - else - unpublish_group = [] end else ex_all_group_settings = exercise.exercise_group_settings ex_group_settings = ex_all_group_settings.exercise_group_published.pluck(:course_group_id).uniq #问卷设置的班级 - if exercise_status == 1 + if exercise_status == Exercise::UNPUBLISHED unpublish_group = user_groups_id - ex_group_settings - elsif exercise_status == 3 + elsif exercise_status == Exercise::ENDED ex_ended_groups = ex_all_group_settings.exercise_group_ended.pluck(:course_group_id).uniq ex_and_user = user_groups_id & ex_group_settings #用户已设置的分班 unpublish_group = unpublish_group + ex_and_user - ex_ended_groups #已发布的全部班级减去截止的全部班级 @@ -1567,8 +1542,6 @@ class ExercisesController < ApplicationController unpublish_group = unpublish_group.uniq if unpublish_group.count > 0 course_groups = CourseGroup.by_group_ids(unpublish_group) - else - course_groups = [] end course_groups end @@ -1641,7 +1614,7 @@ class ExercisesController < ApplicationController ex_status = @exercise.get_exercise_status(current_user) @ex_user = @exercise.exercise_users.find_by(user_id:@exercise_current_user_id) #该试卷的回答者 if @user_course_identity > Course::ASSISTANT_PROFESSOR - if ex_status == 1 + if ex_status == Exercise::UNPUBLISHED normal_status(-1,"试卷未发布") elsif @ex_user.present? && @ex_user.commit_status == 0 normal_status(-1,"试卷未提交") @@ -1655,7 +1628,7 @@ class ExercisesController < ApplicationController def check_exercise_public if @user_course_identity > Course::ASSISTANT_PROFESSOR #当前为学生,试卷公开统计,且已截止,且已提交 ex_user = @exercise.exercise_users.exercise_commit_users(current_user.id).first - unless @exercise.get_exercise_status(current_user) == 3 && ex_user.present? && ex_user.commit_status == 1 && + unless @exercise.get_exercise_status(current_user) == Exercise::ENDED && ex_user.present? && ex_user.commit_status == 1 && @exercise.show_statistic normal_status(-1,"学生暂不能查看") end @@ -1678,19 +1651,19 @@ class ExercisesController < ApplicationController ex_question_random = exercise.question_random question_answered = 0 exercise_questions.each_with_index do |q,index| - if ex_question_random && exercise_user_status != 3 + if ex_question_random && exercise_user_status != Exercise::ENDED ques_number = index + 1 else ques_number = q.question_number end - if q.question_type != 5 + if q.question_type != Exercise::PRACTICAL ques_vote = q.exercise_answers.search_exercise_answer("user_id",user_id) else ques_vote = q.exercise_shixun_answers.search_shixun_answers("user_id",user_id) end ques_status = 0 if ques_vote.present? - if q.question_type == 5 + if q.question_type == Exercise::PRACTICAL if ques_vote.pluck(:exercise_shixun_challenge_id).sort == q.exercise_shixun_challenges.pluck(:id).sort #用户的总得分等于问题的分数 ques_status = 1 #全部回答了,才算已答 question_answered += 1 @@ -1698,12 +1671,12 @@ class ExercisesController < ApplicationController else #其他题目,需回答的有内容,才会为已答,否则如内容为空,视为未答 vote_answer_id = ques_vote.pluck(:exercise_choice_id).reject(&:blank?) vote_text_count = ques_vote.pluck(:answer_text).reject(&:blank?).size - if q.question_type <= 2 #选择题和判断题的时候,需要有选项,才算回答 + if q.question_type <= Exercise::JUDGMENT #选择题和判断题的时候,需要有选项,才算回答 if vote_answer_id.size > 0 ques_status = 1 question_answered += 1 end - elsif q.question_type == 3 #填空题的时候,需要有选项和内容,才算回答 + elsif q.question_type == Exercise::COMPLETION #填空题的时候,需要有选项和内容,才算回答 if vote_answer_id.uniq.sort == q.exercise_standard_answers.pluck(:exercise_choice_id).uniq.sort ques_status = 1 question_answered += 1 diff --git a/app/controllers/homework_commons_controller.rb b/app/controllers/homework_commons_controller.rb index bbae7ba75..969296539 100644 --- a/app/controllers/homework_commons_controller.rb +++ b/app/controllers/homework_commons_controller.rb @@ -410,10 +410,8 @@ class HomeworkCommonsController < ApplicationController homework_detail_group = @homework.homework_detail_group param_min = params[:min_num].to_i param_max = params[:max_num].to_i - homework_detail_group.min_num = @homework.has_commit_work ? (param_min > homework_detail_group.min_num ? homework_detail_group.min_num : - param_min) : param_min - homework_detail_group.max_num = @homework.has_commit_work ? (param_max < homework_detail_group.max_num ? homework_detail_group.max_num : - param_max) : param_max + homework_detail_group.min_num = @homework.has_commit_work ? [param_min, homework_detail_group.min_num].min : param_min + homework_detail_group.max_num = @homework.has_commit_work ? [param_max, homework_detail_group.max_num].max : param_max homework_detail_group.base_on_project = params[:base_on_project] unless @homework.has_relate_project homework_detail_group.save! end diff --git a/app/controllers/searchs_controller.rb b/app/controllers/searchs_controller.rb new file mode 100644 index 000000000..1ea1c5d05 --- /dev/null +++ b/app/controllers/searchs_controller.rb @@ -0,0 +1,10 @@ +class SearchsController < ApplicationController + def index + @results = SearchService.call(search_params) + end + + private + def search_params + params.permit(:keyword, :type, :page, :per_page) + end +end \ No newline at end of file diff --git a/app/controllers/shixuns_controller.rb b/app/controllers/shixuns_controller.rb index 2d708bfa8..019b690b5 100644 --- a/app/controllers/shixuns_controller.rb +++ b/app/controllers/shixuns_controller.rb @@ -1,4 +1,7 @@ class ShixunsController < ApplicationController + include ShixunsHelper + include ApplicationHelper + before_action :require_login, :check_auth, except: [:download_file, :index, :menus] before_action :check_auth, except: [:download_file, :index, :menus] @@ -14,9 +17,6 @@ class ShixunsController < ApplicationController before_action :special_allowed, only: [:send_to_course, :search_user_courses] - include ShixunsHelper - include ApplicationHelper - ## 获取课程列表 def index ## 我的实训 @@ -59,7 +59,7 @@ class ShixunsController < ApplicationController end ## 筛选 难度 - if params[:diff].present? && params[:diff].to_i != 0 + if params[:diff].present? && params[:diff].to_i != 0 @shixuns = @shixuns.where(trainee: params[:diff]) end @@ -84,6 +84,12 @@ class ShixunsController < ApplicationController limit = params[:limit] || 16 @shixuns = @shixuns.includes(:tag_repertoires, :challenges).page(page).per(limit) + + @tag_name_map = TagRepertoire.joins(:shixun_tag_repertoires) + .where(shixun_tag_repertoires: { shixun_id: @shixuns.map(&:id) }) + .group('shixun_tag_repertoires.shixun_id') + .select('shixun_id, tag_repertoires.name') + .each_with_object({}) { |r, obj| obj[r.shixun_id] = r.name } end ## 获取顶部菜单 diff --git a/app/helpers/exercises_helper.rb b/app/helpers/exercises_helper.rb index 314a90403..71a520cef 100644 --- a/app/helpers/exercises_helper.rb +++ b/app/helpers/exercises_helper.rb @@ -4,7 +4,7 @@ module ExercisesHelper #获取每个学生对每个题的答案状态 def get_each_student_exercise(exercise_id,exercise_questions,user_id) - @exercise_user = ExerciseUser.current_exercise_user(user_id,exercise_id).first + @exercise_user = ExerciseUser.current_exercise_user(user_id,exercise_id)&.first exercise_obj_status = exercise_questions.find_objective_questions @ex_obj_array = [] exercise_obj_status.each do |q| @@ -259,10 +259,9 @@ module ExercisesHelper #获取试卷的已答/未答人数 def get_exercise_answers(ex_users, status) - if status == 1 - @exercise_answers = 0 - @exercise_unanswers = 0 - else + @exercise_answers = 0 + @exercise_unanswers = 0 + unless status == Exercise::UNPUBLISHED @exercise_answers = ex_users.commit_exercise_by_status(1).size #表示已经提交了的用户 course_all_members_count = ex_users.size @exercise_unanswers = (course_all_members_count - @exercise_answers) diff --git a/app/libs/util.rb b/app/libs/util.rb index 3485bebd7..7839b2304 100644 --- a/app/libs/util.rb +++ b/app/libs/util.rb @@ -33,4 +33,12 @@ module Util Rails.logger.error(exception.message) exception.backtrace.each { |message| Rails.logger.error(message) } end + + def map_or_pluck(relation, name) + relation.is_a?(Array) || relation.loaded? ? relation.map(&name.to_sym) : relation.pluck(name) + end + + def extract_content(str) + str.gsub(/<\/?.*?>/, '').gsub(/[\n\t\r]/, '').gsub(/ /, '') + end end \ No newline at end of file diff --git a/app/models/challenge.rb b/app/models/challenge.rb index 4d136a718..0bea54eb4 100644 --- a/app/models/challenge.rb +++ b/app/models/challenge.rb @@ -116,5 +116,4 @@ class Challenge < ApplicationRecord end # 关卡评测文件 - end diff --git a/app/models/challenge_tag.rb b/app/models/challenge_tag.rb index 83b743adc..b68e1792c 100644 --- a/app/models/challenge_tag.rb +++ b/app/models/challenge_tag.rb @@ -1,4 +1,6 @@ class ChallengeTag < ApplicationRecord + # TODO: ES feature + # include Searchable::Dependents::ChallengeTag belongs_to :challenge, counter_cache: true belongs_to :challenge_choose, optional: true diff --git a/app/models/course.rb b/app/models/course.rb index 06090f236..77ff6c46d 100644 --- a/app/models/course.rb +++ b/app/models/course.rb @@ -1,4 +1,7 @@ class Course < ApplicationRecord + # TODO: ES feature + # include Searchable::Course + has_many :boards, dependent: :destroy belongs_to :teacher, class_name: 'User', foreign_key: :tea_id # 定义一个方法teacher,该方法通过tea_id来调用User表 @@ -22,6 +25,8 @@ class Course < ApplicationRecord has_many :graduation_groups, dependent: :destroy has_many :course_members, dependent: :destroy + has_many :teacher_course_members, -> { teachers_and_admin }, class_name: 'CourseMember' + has_many :teacher_users, through: :teacher_course_members, source: :user has_many :course_messages, dependent: :destroy has_many :homework_commons, dependent: :destroy has_many :homework_group_settings diff --git a/app/models/exercise.rb b/app/models/exercise.rb index 3a4414ff9..10c7ab6d1 100644 --- a/app/models/exercise.rb +++ b/app/models/exercise.rb @@ -23,6 +23,21 @@ class Exercise < ApplicationRecord after_create :create_exercise_list + # 试卷的问题类型 + SINGLE = 0 #单选题 + MULTIPLE = 1 #多选题 + JUDGMENT = 2 #判断题 + COMPLETION = 3 # 填空题 + SUBJECTIVE = 4 # 主观题 + PRACTICAL = 5 #实训题 + + # 试卷的状态 + UNPUBLISHED = 1 #未发布 + PUBLISHED = 2 #已发布 + DEADLINE = 3 #已截止 + ENDED = 4 #课堂已结束 + + def create_exercise_list str = "" # TODO: 一次性为所有学生创建数据是否存在问题? @@ -93,8 +108,6 @@ class Exercise < ApplicationRecord def common_published_ids(user_id) current_user_groups = course.teacher_course_ids(user_id) if unified_setting - # un_group_ids = (course.none_group_count > 0) ? [0] : [] - # published_group_ids = (current_user_groups + un_group_ids).uniq #统一设置时,为当前用户的分班id及未分班 published_group_ids = current_user_groups else ex_group_setting = exercise_group_settings.select(:course_group_id).pluck("course_group_id").uniq @@ -118,13 +131,12 @@ class Exercise < ApplicationRecord ex_time = get_exercise_times(user_id,false) pb_time = ex_time[:publish_time] ed_time = ex_time[:end_time] - if pb_time.present? && ed_time.present? && pb_time <= Time.now && ed_time > Time.now - status = 2 + status = Exercise::PUBLISHED elsif ed_time.present? && ed_time <= Time.now - status = 3 + status = Exercise::ENDED else - status = 1 + status = Exercise::UNPUBLISHED end else status = exercise_status #当为老师的时候,则为试卷的总状态 diff --git a/app/models/memo.rb b/app/models/memo.rb index 524c37a96..3cb074a78 100644 --- a/app/models/memo.rb +++ b/app/models/memo.rb @@ -1,4 +1,6 @@ class Memo < ApplicationRecord + # TODO: ES feature + # include Searchable::Memo has_many :memo_tag_repertoires, :dependent => :destroy has_many :tag_repertoires, :through => :memo_tag_repertoires @@ -9,6 +11,9 @@ class Memo < ApplicationRecord belongs_to :author, class_name: 'User', foreign_key: 'author_id' belongs_to :parent, class_name: 'Memo', foreign_key: 'parent_id' + has_many :descendants, foreign_key: :root_id, class_name: 'Memo' + has_many :children, foreign_key: :parent_id, class_name: 'Memo' + scope :field_for_list, lambda{ select([:id, :subject, :author_id, :sticky, :updated_at, :language, :reward, :all_replies_count, :viewed_count, :forum_id]) } diff --git a/app/models/searchable.rb b/app/models/searchable.rb new file mode 100644 index 000000000..b8649a75c --- /dev/null +++ b/app/models/searchable.rb @@ -0,0 +1,3 @@ +module Searchable + MAXIMUM_LENGTH = 10922 # 最大字节数为32766 ,一个汉字3个字节 +end \ No newline at end of file diff --git a/app/models/searchable/course.rb b/app/models/searchable/course.rb new file mode 100644 index 000000000..93c69c9e8 --- /dev/null +++ b/app/models/searchable/course.rb @@ -0,0 +1,37 @@ +module Searchable::Course + extend ActiveSupport::Concern + + included do + searchkick language: 'chinese', callbacks: :async + + scope :search_import, -> { includes(:teacher_users, teacher: { user_extension: :school } ) } + end + + def searchable_title + name + end + + def search_data + { + name: name, + author_name: teacher&.real_name + } + end + + def to_searchable_json + { + id: id, + author_name: teacher.real_name, + author_school_name: teacher.school_name, + visits_count: visits, + members_count: members_count, + is_public: is_public == 1 + } + end + + module ClassMethods + def searchable_includes + { teacher: { user_extension: :school } } + end + end +end diff --git a/app/models/searchable/dependents.rb b/app/models/searchable/dependents.rb new file mode 100644 index 000000000..66751a475 --- /dev/null +++ b/app/models/searchable/dependents.rb @@ -0,0 +1,2 @@ +module Searchable::Dependents +end diff --git a/app/models/searchable/dependents/challenge_tag.rb b/app/models/searchable/dependents/challenge_tag.rb new file mode 100644 index 000000000..fdec79d1b --- /dev/null +++ b/app/models/searchable/dependents/challenge_tag.rb @@ -0,0 +1,16 @@ +module Searchable::Dependents::ChallengeTag + extend ActiveSupport::Concern + + included do + after_create_commit :check_searchable_dependents + after_update_commit :check_searchable_dependents + end + + private + + def check_searchable_dependents + if new_record? || name_previously_changed? + challenge.shixun.reindex(:searchable_challenge_data) + end + end +end \ No newline at end of file diff --git a/app/models/searchable/dependents/stage.rb b/app/models/searchable/dependents/stage.rb new file mode 100644 index 000000000..262ddd36f --- /dev/null +++ b/app/models/searchable/dependents/stage.rb @@ -0,0 +1,15 @@ +module Searchable::Dependents::Stage + extend ActiveSupport::Concern + + included do + after_update_commit :check_searchable_dependents + end + + private + + def check_searchable_dependents + if name_previously_changed? || description_previously_changed? + subject.reindex(:searchable_stages_data) + end + end +end \ No newline at end of file diff --git a/app/models/searchable/dependents/user.rb b/app/models/searchable/dependents/user.rb new file mode 100644 index 000000000..761704d06 --- /dev/null +++ b/app/models/searchable/dependents/user.rb @@ -0,0 +1,22 @@ +module Searchable::Dependents::User + extend ActiveSupport::Concern + + included do + after_update_commit :check_searchable_dependents + end + + private + + def check_searchable_dependents + if firstname_previously_changed? || lastname_previously_changed? || user_extension.school_id_previously_changed? + # reindex shixun + created_shixuns.each{ |shixun| shixun.reindex(:searchable_user_data) } + + # reindex course + manage_courses.each(&:reindex) + + # reindex subject + created_subjects.each { |subject| subject.reindex(:searchable_user_data) } + end + end +end \ No newline at end of file diff --git a/app/models/searchable/memo.rb b/app/models/searchable/memo.rb new file mode 100644 index 000000000..5aa9d5fe2 --- /dev/null +++ b/app/models/searchable/memo.rb @@ -0,0 +1,46 @@ +module Searchable::Memo + extend ActiveSupport::Concern + + included do + searchkick language: 'chinese', callbacks: :async + + scope :search_import, -> { includes(:descendants) } + end + + def searchable_title + subject + end + + def should_index? + hidden.zero? && root_id.blank? && parent_id.blank? + end + + def search_data + { + name: subject, + content: Util.extract_content(content)[0..Searchable::MAXIMUM_LENGTH], + }.merge!(searchable_descendants_data) + end + + def searchable_descendants_data + { + descendants_contents: Util.map_or_pluck(descendants, :content) + .map { |content| Util.extract_content(content)[0..Searchable::MAXIMUM_LENGTH] } + } + end + + def to_searchable_json + { + id: id, + author_name: author.full_name, + visits_count: viewed_count, + all_replies_count: all_replies_count + } + end + + module ClassMethods + def searchable_includes + [:author] + end + end +end diff --git a/app/models/searchable/shixun.rb b/app/models/searchable/shixun.rb new file mode 100644 index 000000000..1f39dcd76 --- /dev/null +++ b/app/models/searchable/shixun.rb @@ -0,0 +1,58 @@ +module Searchable::Shixun + extend ActiveSupport::Concern + + included do + searchkick language: 'chinese'#, callbacks: :async + + scope :search_import, -> { includes(:shixun_info, :challenges, :challenge_tags, :users, user: { user_extension: :school }) } + end + + def searchable_title + name + end + + def search_data + { + name: name, + description: Util.extract_content(description)[0..Searchable::MAXIMUM_LENGTH] + }.merge!(searchable_user_data) + .merge!(searchable_challenge_data) + end + + def searchable_user_data + { + author_name: user.real_name, + author_school_name: user.school_name, + } + end + + def searchable_challenge_data + challenge_names = Util.map_or_pluck(challenges, :subject) + .each_with_index.map { |subject, index| "第#{index + 1}关 #{subject}" } + + { + challenge_names: challenge_names, + challenge_tag_names: Util.map_or_pluck(challenge_tags, :name).uniq.join(' ') + } + end + + def should_index? + status == 2 # published + end + + def to_searchable_json + { + id: id, + author_name: user.real_name, + author_school_name: user.school_name, + visits_count: visits, + challenges_count: challenges_count + } + end + + module ClassMethods + def searchable_includes + { user: { user_extension: :school } } + end + end +end \ No newline at end of file diff --git a/app/models/searchable/subject.rb b/app/models/searchable/subject.rb new file mode 100644 index 000000000..feec41a3c --- /dev/null +++ b/app/models/searchable/subject.rb @@ -0,0 +1,61 @@ +module Searchable::Subject + extend ActiveSupport::Concern + + included do + searchkick language: 'chinese', callbacks: :async + + scope :search_import, -> { includes(:users, :stages, user: { user_extension: :school }) } + end + + def searchable_title + name + end + + def should_index? + !hidden? && status == 2 # published + end + + def search_data + { + name: name, + description: Util.extract_content(description)[0..Searchable::MAXIMUM_LENGTH] + }.merge!(searchable_user_data) + .merge!(searchable_stages_data) + end + + def searchable_user_data + { + author_name: user.real_name, + author_school_name: user.school_name, + } + end + + def searchable_stages_data + subject_stages = + stages.map do |stage| + { + name: stage.name, + description: Util.extract_content(stage.description)[0..Searchable::MAXIMUM_LENGTH] + } + end + + { subject_stages: subject_stages} + end + + def to_searchable_json + { + id: id, + author_name: user.real_name, + author_school_name: user.school_name, + visits_count: visits, + stage_count: stages_count, + stage_shixuns_count: stage_shixuns_count + } + end + + module ClassMethods + def searchable_includes + { user: { user_extension: :school } } + end + end +end diff --git a/app/models/shixun.rb b/app/models/shixun.rb index afad10397..0925f4fa0 100644 --- a/app/models/shixun.rb +++ b/app/models/shixun.rb @@ -1,8 +1,12 @@ class Shixun < ApplicationRecord + # TODO: ES feature + # include Searchable::Shixun + # status: 0:编辑 1:申请发布 2:正式发布 3:关闭 -1:软删除 # hide_code: 隐藏代码窗口 # code_hidden: 隐藏代码目录 has_many :challenges, dependent: :destroy + has_many :challenge_tags, through: :challenges has_many :myshixuns, :dependent => :destroy has_many :shixun_members, dependent: :destroy has_many :users, through: :shixun_members @@ -35,7 +39,6 @@ class Shixun < ApplicationRecord # 实训服务配置 has_many :shixun_service_configs, :dependent => :destroy - scope :search_by_name, ->(keyword) { where("name like ? or description like ? ", "%#{keyword}%", "%#{keyword}%") } diff --git a/app/models/stage.rb b/app/models/stage.rb index 7c80c4f9c..ee4e969dd 100644 --- a/app/models/stage.rb +++ b/app/models/stage.rb @@ -1,4 +1,7 @@ class Stage < ApplicationRecord + # TODO: ES feature + # include Searchable::Dependents::Stage + belongs_to :subject, counter_cache: true has_many :stage_shixuns, -> { order("stage_shixuns.position ASC") }, dependent: :destroy diff --git a/app/models/subject.rb b/app/models/subject.rb index 66ac41c40..d0b3e7aed 100644 --- a/app/models/subject.rb +++ b/app/models/subject.rb @@ -2,6 +2,9 @@ # 可以在初始创建的时候 class Subject < ApplicationRecord + # TODO: ES feature + # include Searchable::Subject + #status :0 编辑中 1 审核中 2 发布 belongs_to :repertoire belongs_to :user diff --git a/app/models/user.rb b/app/models/user.rb index 523df045d..f2ea635c4 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,5 +1,8 @@ class User < ApplicationRecord include Watchable + # TODO: ES feature + # include Searchable::Dependents::User + # Account statuses STATUS_ANONYMOUS = 0 STATUS_ACTIVE = 1 @@ -28,6 +31,7 @@ class User < ApplicationRecord accepts_nested_attributes_for :user_extension, update_only: true has_many :memos, foreign_key: 'author_id' + has_many :created_shixuns, class_name: 'Shixun' has_many :shixun_members, :dependent => :destroy has_many :shixuns, :through => :shixun_members has_many :myshixuns, :dependent => :destroy @@ -55,6 +59,7 @@ class User < ApplicationRecord has_many :tidings, :dependent => :destroy has_many :games, :dependent => :destroy + has_many :created_subjects has_many :subjects, :through => :subject_members has_many :subject_members, :dependent => :destroy has_many :grades, :dependent => :destroy diff --git a/app/models/user_extension.rb b/app/models/user_extension.rb index 49fca7c71..458d31989 100644 --- a/app/models/user_extension.rb +++ b/app/models/user_extension.rb @@ -2,7 +2,7 @@ class UserExtension < ApplicationRecord # identity 0: 教师教授 1: 学生, 2: 专业人士, 3: 开发者 enum identity: { teacher: 0, student: 1, professional: 2, developer: 3 } - belongs_to :user + belongs_to :user, touch: true belongs_to :school belongs_to :department, optional: true diff --git a/app/services/concerns/elasticsearch_able.rb b/app/services/concerns/elasticsearch_able.rb new file mode 100644 index 000000000..e1c33ed4a --- /dev/null +++ b/app/services/concerns/elasticsearch_able.rb @@ -0,0 +1,41 @@ +module ElasticsearchAble + extend ActiveSupport::Concern + + private + + def default_options + { + debug: Rails.env.development?, + highlight: highlight_options, + body_options: body_options, + page: page, + per_page: per_page + } + end + + def keyword + params[:keyword].to_s.strip.presence || '*' + end + + def highlight_options + { + fragment_size: EduSetting.get('es_highlight_fragment_size') || 30, + tag: '' + } + end + + def body_options + { + min_score: EduSetting.get('es_min_score') || 10 + } + end + + def per_page + per_page = params[:per_page].to_s.strip.presence || params[:limit].to_s.strip.presence + per_page.to_i <= 0 ? 20 : per_page.to_i + end + + def page + params[:page].to_i <= 0 ? 1 : params[:page].to_i + end +end \ No newline at end of file diff --git a/app/services/search_service.rb b/app/services/search_service.rb new file mode 100644 index 000000000..7cd1857bd --- /dev/null +++ b/app/services/search_service.rb @@ -0,0 +1,39 @@ +class SearchService < ApplicationService + include ElasticsearchAble + + attr_reader :params + + def initialize(params) + @params = params + end + + def call + Searchkick.search(keyword, search_options) + end + + private + + def search_options + { + index_name: index_names, + model_includes: model_includes + }.merge(default_options) + end + + def index_names + @_index_names ||= + case params[:type].to_s.strip + when 'shixun' then [Shixun] + when 'course' then [Course] + when 'subject' then [Subject] + when 'memo' then [Memo] + else [Shixun, Course, Subject, Memo] + end + end + + def model_includes + index_names.each_with_object({}) do |klass, obj| + obj[klass] = klass.searchable_includes + end + end +end \ No newline at end of file diff --git a/app/services/search_shixun_service.rb b/app/services/search_shixun_service.rb new file mode 100644 index 000000000..2e77e82d8 --- /dev/null +++ b/app/services/search_shixun_service.rb @@ -0,0 +1,96 @@ +class SearchShixunService < ApplicationService + include ElasticsearchAble + + attr_reader :user, :params + + def initialize(user, params) + @user = user + @params = params + end + + def call + Shixun.search(keyword, + fields: search_fields, + where: where_clauses, + order: order_clauses, + includes: includes_clauses, + page: page, + per_page: per_page) + end + + private + + def tag_filter_shixun_ids + return [] if params[:tag_level].to_i == 0 || params[:tag_id].blank? + + case params[:tag_level].to_i + when 1 then + Repertoire.find(params[:tag_id]).tag_repertoires.joins(:shixun_tag_repertoires) + .pluck('shixun_tag_repertoires.shixun_id') + when 2 then + SubRepertoire.find(params[:tag_id]).tag_repertoires.joins(:shixun_tag_repertoires) + .pluck('shixun_tag_repertoires.shixun_id') + when 3 then + TagRepertoire.find(params[:tag_id]).shixun_tag_repertoires.pluck(:shixun_id) + else + [] + end + end + + def user_filter_shixun_ids + return [] if params[:order_by] != 'mine' + + user.shixun_members.pluck(:shixun_id) + user.myshixuns.pluck(:shixun_id) + end + + def keyword + params[:keyword].to_s.strip.presence || '*' + end + + def search_fields + %w(name^10 author_name challenge_names description challenge_tag_names) + end + + def where_clauses + hash = {} + + ids = user_filter_shixun_ids + tag_filter_shixun_ids + hash[:id] = ids if ids.present? + + if params[:order_by] == 'mine' + hash[:status] = { not: -1 } + else + hash.merge!(hidden: false, status: 2) + end + + unless params[:status].to_i.zero? + params[:status] = [0, 1] if params[:status].to_i == 1 + hash[:status] = params[:status] + end + + hash[:trainee] = params[:diff].to_i unless params[:diff].to_i.zero? + + hash + end + + def includes_clauses + [] + end + + def order_clauses + hash = { _score: :desc } + publish_order = { type: 'number', order: :desc, script: 'doc["status"].value=="2" ? 1 : 0' } + + sort = params[:sort].to_s.strip == 'asc' ? 'asc' : 'desc' + clauses = + case params[:order_by].presence + when 'new' then { _script: publish_order, created_at: sort } + when 'hot' then { _script: publish_order, myshixuns_count: sort } + when 'mine' then { created_at: sort } + else { _script: publish_order, publish_time: sort } + end + hash.merge!(clauses) + + hash + end +end \ No newline at end of file diff --git a/app/views/exercises/_user_exercise_info.json.jbuilder b/app/views/exercises/_user_exercise_info.json.jbuilder index 9acb18326..e690f4867 100644 --- a/app/views/exercises/_user_exercise_info.json.jbuilder +++ b/app/views/exercises/_user_exercise_info.json.jbuilder @@ -36,10 +36,10 @@ elsif student_status == 1 json.question_status question_status end -exercise_status = exercise.get_exercise_status(ex_answerer) +# exercise_status = exercise.get_exercise_status(ex_answerer) #当前为老师,或为学生,但在试卷截止后且答案选择公开的 -if is_teacher_or == 1 || (exercise_status == 3 && exercise.answer_open) +if is_teacher_or == 1 || (ex_answer_status == Exercise::ENDED && exercise.answer_open) ex_type = 4 else ex_type = 3 @@ -47,7 +47,7 @@ end json.exercise_questions do json.array! exercise_questions do |q| - user_ques_answers = user_question_answers(q,ex_answerer.id,student_status,is_teacher_or,exercise_status,q.question_type,ex_type) + user_ques_answers = user_question_answers(q,ex_answerer.id,student_status,is_teacher_or,ex_answer_status,q.question_type,ex_type) user_ques_comments = user_ques_answers[:question_comment] if all_question_status.size > 0 this_ques_status = all_question_status.detect {|f| f[:q_id] == q.id} diff --git a/app/views/exercises/review_exercise.json.jbuilder b/app/views/exercises/review_exercise.json.jbuilder index 5d2ac875d..638324256 100644 --- a/app/views/exercises/review_exercise.json.jbuilder +++ b/app/views/exercises/review_exercise.json.jbuilder @@ -8,5 +8,6 @@ json.partial! "exercises/user_exercise_info",locals:{exercise:@exercise, ex_sub_array:@ex_sub_array, exercise_questions:@exercise_questions, student_status:@student_status, - question_status:@question_status + question_status:@question_status, + ex_answer_status:@ex_answer_status } diff --git a/app/views/exercises/students_exercises.json.jbuilder b/app/views/exercises/students_exercises.json.jbuilder deleted file mode 100644 index 25c85be88..000000000 --- a/app/views/exercises/students_exercises.json.jbuilder +++ /dev/null @@ -1,18 +0,0 @@ -json.total_counts @total_exercise_counts - -json.total_user_exercises do - json.array! @all_exercise_stu_array do |a| - json.student_exercise do - json.partial! "exercises/user_exercise_info",locals:{exercise:@exercise, - is_teacher_or:a[:is_teacher], - ex_answerer:a[:ex_answerer], - exercise_user:a[:ex_user], - ex_obj_array:a[:ex_obj_array], - ex_sub_array:a[:ex_sub_array], - exercise_questions:@exercise_questions, - student_status:@student_status, - question_status:@question_status - } - end - end -end diff --git a/app/views/searchs/index.json.jbuilder b/app/views/searchs/index.json.jbuilder new file mode 100644 index 000000000..a36edb5bd --- /dev/null +++ b/app/views/searchs/index.json.jbuilder @@ -0,0 +1,10 @@ +json.count @results.total_count +json.results do + json.array! @results.with_highlights(multiple: true) do |obj, highlights| + json.merge! obj.to_searchable_json + json.type obj.class.name.downcase + + json.title highlights.delete(:name)&.join('...') || obj.searchable_title + json.description highlights.values[0,5].each { |arr| arr.is_a?(Array) ? arr.join('...') : arr }.join('
') + end +end \ No newline at end of file diff --git a/app/views/shixuns/_shixun.json.jbuilder b/app/views/shixuns/_shixun.json.jbuilder index ebc0c520d..f5ff0358b 100644 --- a/app/views/shixuns/_shixun.json.jbuilder +++ b/app/views/shixuns/_shixun.json.jbuilder @@ -15,7 +15,7 @@ json.array! shixuns do |shixun| json.status shixun.status json.power (current_user.shixun_permission(shixun)) # 现在首页只显示已发布的实训 # REDO: 局部缓存 - json.tag_name shixun.tag_repertoires.first.try(:name) + json.tag_name @tag_name_map&.fetch(shixun.id) || shixun.tag_repertoires.first.try(:name) json.myshixuns_count shixun.myshixuns_count json.stu_num shixun.myshixuns_count json.score_info shixun.averge_star diff --git a/app/views/user_mailer/register_email.html.erb b/app/views/user_mailer/register_email.html.erb index 24ae606b7..6f88177c5 100644 --- a/app/views/user_mailer/register_email.html.erb +++ b/app/views/user_mailer/register_email.html.erb @@ -28,7 +28,7 @@
- +
diff --git a/config/routes.rb b/config/routes.rb index d9e10e4cc..676954600 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,6 +9,8 @@ Rails.application.routes.draw do get 'home/index' get 'home/search' + get 'search', to: 'searchs#index' + post 'praise_tread/like', to: 'praise_tread#like' delete 'praise_tread/unlike', to: 'praise_tread#unlike'