class HomeworkCommon < ApplicationRecord # homework_type 1:普通作业 2:编程作业(弃用) 3:分组作业 4:实训作业 enum homework_type: { normal: 1, program: 2, group: 3, practice: 4 }, _suffix: true has_many :homework_group_settings, dependent: :destroy has_many :published_settings, -> { group_published }, class_name: "HomeworkGroupSetting" has_many :student_works, -> { where("is_delete = 0") } has_many :score_student_works, -> { where("is_delete = 0 and work_status != 0").order("work_score desc") }, class_name: "StudentWork" has_one :homework_detail_manual, dependent: :destroy # 分组作业的设置 has_one :homework_detail_group, dependent: :destroy belongs_to :course, counter_cache: true belongs_to :homework_bank, optional: true has_many :homework_challenge_settings, dependent: :destroy has_one :homework_commons_shixun, dependent: :destroy has_and_belongs_to_many :shixuns, through: :homework_commons_shixun # attachtype: 1(描述的附件), 2(参考答案的附件) has_many :attachments, as: :container, dependent: :destroy # 作业的评论 has_many :journals_for_messages, as: :jour, dependent: :destroy # 二级目录 belongs_to :course_second_category, optional: true # 课堂动态 has_many :course_acts, class_name: 'CourseActivity', as: :course_act, dependent: :destroy has_many :tidings, as: :container, dependent: :destroy # 实训作业的分班查重记录 has_many :homework_group_reviews, :dependent => :destroy # 学生的查重情况 has_many :homework_review_results, :dependent => :destroy validates :name, length: { maximum: 60 } validates :description, length: { maximum: 10000 } validates :reference_answer, length: { maximum: 5000 } # after_update :update_activity before_destroy :update_homework_bank_quotes #1已发布的课堂作业 scope :homework_published, -> {where("homework_commons.publish_time IS NOT NULL AND homework_commons.publish_time <= ? ",Time.now)} scope :published_no_end, -> {where("homework_commons.publish_time IS NOT NULL AND homework_commons.publish_time < ? and homework_commons.end_time > ?", Time.now, Time.now)} scope :search_homework_type, lambda {|num| where(homework_type:num)} scope :unified_setting, -> {where("unified_setting = ? ", 1)} # 是否显示参考答案 def view_answer identity, user_id identity < Course::STUDENT || (identity == Course::STUDENT && answer_public && self.end_or_late && self.user_work(user_id).try(:work_status).to_i > 0) end # 申诉阶段 def appeal_duration self.anonymous_appeal && [3, 4].include?(homework_detail_manual.comment_status) end # 作业对应的子目录/父目录名称 def category_info case self.homework_type when 'normal' {category_id: course.common_course_modules.first.try(:id), category_name: course.common_course_modules.first.try(:module_name)} when 'group' {category_id: course.group_course_modules.first.try(:id), category_name: course.group_course_modules.first.try(:module_name)} when 'practice' if self.course_second_category.present? {category_id: self.course_second_category.try(:id), category_name: self.course_second_category.try(:name)} else {category_id: course.shixun_course_modules.take.try(:id), category_name: course.shixun_course_modules.take.try(:module_name)} end end end # 根据是否统一发布获取作业的作品列表 def all_works student_works = self.unified_setting ? self.student_works : self.student_works.joins("join course_members on student_works.user_id=course_members.user_id"). where(course_members: {course_group_id: self.published_settings.pluck(:course_group_id)}) end # 分班权限的老师可见的作品列表 def teacher_works member # member = course.course_member(user_id) teacher_course_groups = member.try(:teacher_course_groups) all_student_works = self.all_works # 有分班权限的统计管理的分班且已发布的学生情况 if member.present? && teacher_course_groups.exists? group_ids = teacher_course_groups.pluck(:course_group_id) all_student_works = all_student_works.joins("join course_members on student_works.user_id=course_members.user_id"). where(course_members: {course_group_id: group_ids}) end all_student_works end def user_work user_id work = self.student_works.find_by_user_id(user_id) end # 是否在补交阶段内 def late_duration homework_setting = self.homework_group_setting(User.current.id) !course.is_end && self.publish_time && self.publish_time < Time.now && homework_setting.end_time && homework_setting.end_time < Time.now && self.allow_late && (self.late_time.nil? || self.late_time > Time.now) end # 作业是否补交截止或者不允许补交且提交截止 def end_or_late status = false if self.course.is_end || (self.allow_late && self.late_time && self.late_time < Time.now) status = true elsif !self.allow_late homework_setting = self.homework_group_setting(User.current.id) status = homework_setting.end_time && homework_setting.end_time < Time.now end status end # 作业是否补交截止或者不允许补交且提交截止(不考虑分班) def end_or_late_none_group course.is_end || (allow_late && late_time < Time.now) || (!allow_late && end_time < Time.now) end # 作业是否可以查重 def code_review self.homework_type == 'practice' && self.publish_time.present? && self.publish_time < Time.now && self.homework_group_reviews.count == 0 end # 作业能否立即发布 def publish_immediately user homework_detail_manual.try(:comment_status) == 0 || homework_group_settings.where(course_group_id: course.charge_group_ids(user)). none_published.count > 0 end # 作业能否立即截止 def end_immediately user (unified_setting && homework_detail_manual.try(:comment_status) == 1 && end_time > Time.now) || homework_group_settings. where(course_group_id: course.charge_group_ids(user)).published_no_end.count > 0 end # 学生是否提交了作品 def user_has_commit_work user_id work = self.student_works.find_by_user_id(user_id) work.present? && work.work_status != 0 end # 是否有学生提交过作品 def has_commit_work student_works.has_committed.count > 0 end # 是否有学生关联了项目 def has_relate_project homework_type == "group" && student_works.where("project_id != 0").count > 0 end # 作业描述的附件 def des_attachments attachments.where(attachtype: 1) end # 参考答案的附件 def ref_attachments attachments.where(attachtype: 2) end def update_activity course_activity = CourseActivity.find_by_course_act_type_and_course_act_id(self.class.to_s, self.id) course_activity.update_attributes(updated_at: Time.now) if course_activity end #删除时更新题库中的引用数 def update_homework_bank_quotes old_bank = self.homework_bank old_bank.update_attributes(quotes: (old_bank.quotes - 1) > 0 ? (old_bank.quotes - 1) : 0, homework_common_id: nil) if old_bank.present? end # 查重是否有新结果 def code_reviews_new_results? self.homework_group_reviews.where(status: 0).count > 0 end # 任务已评数 user_id: 对应老师的id def comment_count(user_id) course = self.course # 如果有分班,则取此老师对应分班的已评数,没有分班,则取所有的 course_group_ids = course.group_course_power(user_id) sql = if course_group_ids.count > 0 %Q{ SELECT count(distinct sw.id) cnt FROM student_works sw JOIN student_works_scores sws on sws.student_work_id = sw.id WHERE reviewer_role IN(1,2) AND sw.id IN (SELECT id FROM student_works WHERE homework_common_id = #{self.id} AND user_id IN (SELECT user_id FROM course_members WHERE role = 4 AND course_group_id IN (#{course_group_ids.join(",")}) ) ) } else %Q{ SELECT COUNT(distinct sw.id) cnt FROM student_works sw JOIN student_works_scores sws ON sw.id = sws.student_work_id WHERE reviewer_role IN(1,2) AND sw.homework_common_id = #{self.id} } end StudentWorksScore.find_by_sql(sql).first.try(:cnt).to_i end # 任务未评数 def uncomment_count(user_id) user_ids = course.teacher_group_user_ids user_id self.student_works.where(user_id: user_ids).count - self.comment_count(user_id) end # 作品未提交数 def unfinished_count member self.teacher_works(member).unfinished.count end # 任务按时提交数 def finished_count member self.teacher_works(member).finished.count end def delay_finished_count member self.teacher_works(member).delay_finished.count end # 分组作业的最大分组id def max_group_id self.student_works.has_committed.maximum(:group_id).to_i + 1 end # 作业的分班设置时间 def homework_group_setting user_id if unified_setting homework_setting = self else member = course.course_member(user_id) group_setting = self.homework_group_settings.find_by_course_group_id(member.try(:course_group_id)) homework_setting = group_setting.present? ? group_setting : self end homework_setting end def min_group_publish_time #HomeworkGroupSetting.where("homework_common_id = #{self.id} and publish_time is not null").pluck(:publish_time).min # 可以使用includes self.homework_group_settings.where("publish_time is not null").pluck(:publish_time).min end def max_group_end_time #HomeworkGroupSetting.where("homework_common_id = #{self.id} and end_time is not null").pluck(:end_time).max # 可以使用includes self.homework_group_settings.where("end_time is not null").pluck(:end_time).max end def challenge_score challenge_id homework_challenge_settings.find_by(challenge_id: challenge_id)&.score.to_f end end