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

196 lines
7.8 KiB

This file contains ambiguous Unicode characters!

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

class Exercise < ApplicationRecord
belongs_to :course, counter_cache: true
belongs_to :exercise_bank, optional: true
belongs_to :user
has_many :exercise_users, -> { where("is_delete = 0") }, :dependent => :delete_all
has_many :score_exercise_users, -> { where("is_delete = 0 and commit_status != 0").order("score desc") }, class_name: "ExerciseUser"
has_many :exercise_questions, :dependent => :delete_all
has_many :exercise_group_settings, :dependent => :delete_all
has_many :published_settings, -> { exercise_group_published }, class_name: "ExerciseGroupSetting"
has_many :tidings, as: :container
has_many :course_acts, class_name: 'CourseActivity', as: :course_act, :dependent => :delete_all
scope :is_exercise_published, -> { where("exercise_status > ? ",1)}
scope :unified_setting, -> { where("unified_setting = ?",true) }
scope :exercise_by_ids, lambda { |ids| where(id: ids) unless ids.blank? }
scope :exercise_by_status, lambda { |s| where(exercise_status: s) unless s.blank? }
scope :exercise_search, lambda { |keywords|
where("exercise_name LIKE ?", "%#{keywords}%") unless keywords.blank?}
validates :exercise_name, length: { maximum: 60, too_long: "60 characters is the maximum allowed" }
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: 一次性为所有学生创建数据是否存在问题?
self.course.students.find_each do |student|
str += "," if str != ""
str += "(#{student.user_id}, #{self.id}, 0, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
end
if str != ""
sql = "insert into exercise_users (user_id, exercise_id, commit_status, created_at, updated_at) values" + str
ActiveRecord::Base.connection.execute sql
end
end
#获取学生视角的试卷用户
def get_stu_exercise_users
if unified_setting #试卷统一设置
exercise_users
else
ex_group_setting_ids = published_settings.pluck(:course_group_id)
exercise_users.joins("join course_members on exercise_users.user_id=course_members.user_id").
where(course_members: {course_group_id: ex_group_setting_ids})
end
end
def get_exercise_end_time(user_id)
if unified_setting
self&.end_time
else
user_course_group = course.course_members.find_by(user_id: user_id)&.course_group_id
exercise_group_settings.find_by(course_group_id:user_course_group)&.end_time
end
end
# 根据是否统一发布获取作业的作品列表
def all_works
ex_users = unified_setting ? exercise_users :
exercise_users.joins("join course_members on exercise_users.user_id=course_members.user_id").
where(course_members: {course_group_id: published_settings.pluck(:course_group_id)})
end
# 分班权限的老师可见的作品列表
def all_exercise_users user_id
# member = course.course_member(user_id)
teacher_course_groups = course.teacher_course_groups.get_user_groups(user_id)
ex_users = self.all_works
# 有分班权限的统计管理的分班且已发布的学生情况
if teacher_course_groups.exists?
group_ids = teacher_course_groups.pluck(:course_group_id)
ex_users = ex_users.joins("join course_members on exercise_users.user_id=course_members.user_id").
where(course_members: {course_group_id: group_ids})
end
ex_users
end
# #统一设置,为当前老师有权限的分班学生,分班设置,也为当前老师有权限的分班的学生
# def all_exercise_users(user_id)
# ex_users = exercise_users
# group_ids = common_published_ids(user_id)
# if group_ids.present?
# ex_users = ex_users.joins("join course_members on exercise_users.user_id=course_members.user_id").
# where(course_members: {course_group_id: group_ids})
# end
# ex_users
# end
#当前用户已发布的班级id和试卷分组已发布的班级id的交集
def common_published_ids(user_id)
current_user_groups = course.teacher_course_ids(user_id)
if unified_setting
published_group_ids = current_user_groups
else
ex_group_setting = exercise_group_settings.select(:course_group_id).pluck("course_group_id").uniq
common_all_ids = ex_group_setting & current_user_groups #当前用户有权限的已发布的分班id #非统一设置时为当前用户有权限的且已发布分班的id
published_group_ids = common_all_ids.uniq
end
published_group_ids
end
#判断用户是否属于试卷分班的学生中
def check_user_in_course(user_id,user_identity)
ex_group_settings = exercise_group_settings.pluck(:course_group_id)
member = course.course_members.course_find_by_ids("user_id",user_id)
member_group_id = member.pluck(:course_group_id).uniq
((member_group_id & ex_group_settings).size > 0 || user_identity < Course::STUDENT) ? true : false
end
#判断是否为分班,如果分班,试卷的截止时间为当前分班时间,否则为试卷的截止时间
def get_exercise_status(user)
return Exercise::UNPUBLISHED if user.nil?
if user.student_of_course?(course) #当为学生的时候,需根据分班来判断试卷状态
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 = Exercise::PUBLISHED
elsif ed_time.present? && ed_time <= Time.now
status = Exercise::ENDED
else
status = Exercise::UNPUBLISHED
end
else
status = exercise_status #当为老师的时候,则为试卷的总状态
end
status
end
#获取试卷的发布时间和截止时间。teacher 为boolean,当为true时表示的是当前为老师
def get_exercise_times(user_id,teacher)
if unified_setting || teacher #当试卷为统一设置或当前为老师的时候
pb_time = publish_time
en_time = end_time
if (exercise_status != 3) && en_time.present? && (en_time <= Time.now)
update_column("exercise_status",3)
end
else
ex_group_setting = exercise_group_settings
user_group = course.students.where(user_id:user_id).select(:course_group_id)
if user_group.exists?
user_group_id = user_group.first&.course_group_id
user_ex_group_setting = ex_group_setting.where(course_group_id:user_group_id).select(:publish_time,:end_time)
pb_time = user_ex_group_setting.first&.publish_time
en_time = user_ex_group_setting.first&.end_time
else
pb_time = nil
en_time = nil
end
end
{
"publish_time":pb_time,
"end_time":en_time
}
end
#判断当前用户的答题状态
def check_user_answer_status(user)
ex_answer_user = exercise_users.where(user_id: user.id).select(:start_at,:end_at,:commit_status)
user_ex_status = get_exercise_status(user)
user_status = 2
if ex_answer_user.exists? && (ex_answer_user.first&.start_at.present? || ex_answer_user.first&.end_at.present?) #学生有过答题的,或者立即截止,但学生未做试卷的
user_status = ex_answer_user.first.commit_status
end
if ex_answer_user.exists? && ex_answer_user.first&.start_at.blank? && user_ex_status == 3
user_status = 4
end
user_status
end
end