class StudentWork < ApplicationRecord #学生提交作品表 #work_status :0 未提交 1 已提交 2 迟交 -1重做中 # compelete_status 实训作业完成状态: -1重做中 0未开启 1未通关 2按时通关 3迟交通关 4是截止通关 module WORK_STATUS UNSUBMITTED = 0 SUBMITTED = 1 LATE_SUBMITTED = 2 REDO = -1 end belongs_to :user belongs_to :commit_user, class_name: 'User', foreign_key: :commit_user_id, optional: true belongs_to :update_user, class_name: 'User', foreign_key: :update_user_id, optional: true belongs_to :homework_common #, touch: true belongs_to :myshixun, optional: true has_many :score_details, dependent: :destroy has_many :student_works_evaluation_distributions, dependent: :destroy has_many :student_works_scores, dependent: :destroy has_many :shixun_work_comments, dependent: :destroy has_many :student_work_hacks, dependent: :destroy has_many :my_hacks, through: :student_work_hacks, source: :hack #问题反馈 has_many :student_work_feedbacks has_many :histories, class_name: 'StudentWorkHistory', dependent: :destroy COMPLETE_STATUS_STR_TO_NUM = { '未开启' => 0, '未通关' => 1, '按时通关' => 2, '迟交通关' => 3, '截止后通关' => 4 } WORK_STATUS_STR_TO_NUM = { '未提交' => 0, '按时提交' => 1, '延时提交' => 2} def hack_user_codes HackUserCode.without_description.where(user_id: self.user_id, homework_common_id: self.homework_common_id) end def teacher_score_details homework_common.score_detail_names.map do |name| score_details.where(name: name, reviewer_role: 1).first.try(:score) || "未评分" end end def teaching_asistant_score_details homework_common.score_detail_names.map do |name| score_details.where(name: name, reviewer_role: 2).first.try(:score) || "未评分" end end def student_score_details homework_common.score_detail_names.map do |name| score_details.where(name: name, reviewer_role: 3).first.try(:score) || "未评分" end end def deal_score_details(reviewer_role, score_details_params) # reviewer_role 1:老师 2:助教 3:学生 # create_table :score_details do |t| # t.float :score, comment: '分数' # t.name :string, content: '评分项' # t.float :score_percent, comment: '分数百分比' # t.integer :reviewer_role, comment: '评分项类型 1教师,2助教,3学生' # t.integer :parent_id # t.integer :user_id # t.integer :homework_common_id # t.integer :student_work_id # # t.timestamps # end score_details_params = score_details_params.is_a?(Array) ? score_details_params : Array(score_details_params) score_details_params = score_details_params.compact score_details.where(reviewer_role: reviewer_role).destroy_all score_details_params.each do |score_detail| score_details.create( score: score_detail[:score], name: score_detail[:name], reviewer_role: reviewer_role, user_id: User.current.id ) end end def score_details_with_settings_change(total_score, score_details_params, create_box) score_details_params = score_details_params.is_a?(Array) ? score_details_params : Array(score_details_params) score_details_params = score_details_params.compact teacher_score = self.teacher_score.to_f teaching_asistant_score = self.teaching_asistant_score.to_f student_score = self.student_score.to_f # score_details.delete_all if teacher_score > 0 get_score = 0 score_details_params.each_with_index do |score_detail, index| score = if index == score_details_params.size - 1 teacher_score - get_score else (score_detail[:score].to_f / total_score * teacher_score).round(2) end get_score += score create_box << score_details.new( score: score, name: score_detail[:name], reviewer_role: 1, user_id: User.current.id ) end end if teaching_asistant_score > 0 get_score = 0 score_details_params.each_with_index do |score_detail, index| score = if index == score_details_params.size - 1 teaching_asistant_score - get_score else (score_detail[:score].to_f / total_score * teaching_asistant_score).round(2) end get_score += score create_box << score_details.new( score: score, name: score_detail[:name], reviewer_role: 2, user_id: User.current.id ) end end if student_score > 0 get_score = 0 score_details_params.each_with_index do |score_detail, index| score = if index == score_details_params.size - 1 student_score - get_score else (score_detail[:score].to_f / total_score * student_score).round(2) end get_score += score create_box << score_details.new( score: score, name: score_detail[:name], reviewer_role: 3, user_id: User.current.id ) end end StudentWorksScore.unscoped.where(student_work: self).each do |sw| create_box = sw.score_details_with_settings_change(total_score, score_details_params, create_box) end create_box end def deal_score_details_with_settings(reviewer_role, score_details_params) create_box = [] t_score = case reviewer_role when 1 self.teacher_score.to_f when 2 self.teaching_asistant_score.to_f when 3 self.student_score.to_f end score_details.where(reviewer_role: reviewer_role).delete_all get_score = 0 score_details_params.each_with_index do |score_detail, index| score = if index == score_details_params.size - 1 t_score - get_score else (score_detail[:score].to_f / 100 * t_score).round(2) end get_score += score create_box << score_details.create( score: score, name: score_detail[:name], reviewer_role: reviewer_role, user_id: User.current.id ) end end belongs_to :project, optional: true # attachtype: 1(正常提交的附件), 7(补交的附件), 8(打回重做的附件) has_many :attachments, as: :container, dependent: :destroy has_many :tidings, as: :container, dependent: :destroy has_many :challenge_work_scores, dependent: :destroy before_save :set_work_score validates :description, length: { maximum: 65535, too_long: "不能超过65535个字符" } scope :has_committed, lambda { where("work_status > 0") } # 重做 scope :redoing, -> {where(work_status: -1)} # 未提交 scope :unfinished, -> {where(work_status: 0)} # 按时提交 scope :finished, -> {where(work_status: 1)} # 延迟提交 scope :delay_finished, -> {where(work_status: 2)} # 有效(未被删除的)学生用户 scope :undeletes, -> { where(is_delete: 0) } #按用户id查找 scope :homework_by_user, lambda{|ids| where(user_id: ids)} #根据homework_common_id查找 scope :find_by_homework, lambda{|ids| where(homework_common_id: ids)} def is_unfinish? work_status == 0 end def is_redoing? work_status == -1 end def is_delay_finished? work_status == 2 end def is_finished? work_status == 1 end def is_commit? work_status > 0 end def myshixun_consume self.myshixun && self.myshixun.passed_count > 0 ? self.myshixun.total_spend_time : "--" end def myshixun_consume_second self.myshixun && self.myshixun.passed_count > 0 ? self.myshixun.total_spend_time_second : 0 end # 助教评分次数 def ta_comment_count self.student_works_scores.select{|score| score.reviewer_role == 2}.group_by(&:user_id).count end # 匿评次数(被别人评阅) def student_comment_num homework_common.homework_detail_manual.comment_status > 0 && work_status > 0 ? self.student_works_scores.select{|score| score.reviewer_role == 3}.group_by(&:user_id).size : 0 end # 学生评阅作品数(评阅别人,按作品) def user_comment_num if homework_common.homework_detail_manual.comment_status > 0 && work_status > 0 count = homework_common.student_works_scores.select{|score| score.reviewer_role == 3 && score.user_id == user_id}.group_by(&:student_work_id).size else count = 0 end count end # 分配匿评总数 def anonymous_comment_count self.student_works_evaluation_distributions.count end # 匿评用户ids def anonymous_comment_users self.student_works_evaluation_distributions.pluck("student_works_evaluation_distributions.user_id").uniq end # 匿评申诉总条数 def appeal_all_count homework_common.homework_detail_manual.comment_status >= 3 ? self.student_works_scores. select{|score| score.reviewer_role == 3 && score.appeal_status != 0}.group_by(&:user_id).count : 0 end # 匿评申诉待处理条数 def appeal_deal_count homework_common.homework_detail_manual.comment_status >= 3 ? self.student_works_scores. select{|score| score.reviewer_role == 3 && score.appeal_status == 1}.group_by(&:user_id).count : 0 end # 当前用户对该作业的评语数量 def my_comment_all_count user_id student_works_scores.select{|score| score.reviewer_role == 3 && score.user_id == user_id}.size end # 当前用户对该作业的申诉状态 def my_appeal_status user_id last_score = student_works_scores.joins(:student_works_scores_appeal).select{|score| score.reviewer_role == 3 && score.is_invalid = 0 && score.user_id == user_id}.last last_score.nil? ? -1 : last_score.appeal_status end # 当前用户对该作业是否采用整组同评(旧评语数据展示"--") def group_comment user_id old_time = "2024-05-10 00:00:00".to_time last_comment = student_works_scores.select{|score| score.reviewer_role == 3 && score.is_invalid = 0 && score.user_id == user_id }.last last_comment.nil? || (last_comment.created_at < old_time) ? '--' : (last_comment.group_comment ? "是" : "否") end # 当前用户该作品的匿评申诉总条数 def my_appeal_all_count user_id student_works_scores.select{|score| score.reviewer_role == 3 && score.appeal_status != 0 && score.user_id == user_id}.size end # 当前用户该作品的匿评申诉总条数 def my_appeal_deal_count user_id student_works_scores.select{|score| score.reviewer_role == 3 && score.appeal_status == 1 && score.user_id == user_id}.size end def new_appeal_all_count student_works_scores.joins(:student_works_scores_appeal).select{|score| score.reviewer_role == 3 }.length end def new_appeal_deal_count student_works_scores.joins(:student_works_scores_appeal).select{|score| score.reviewer_role == 3 && score.appeal_status == 1 }.length end # 代码差异行数 def diff_code_count(challenge) return 0 if self.diff_code_json.blank? return 0 if challenge.path.blank? paths = challenge.path.split(";") data = JSON.parse(self.diff_code_json) details = data["details"].select { |d| paths.include?(d["path"]) } details.map{|d| d["totalLines"]}.sum end # 分组名 def work_group_name self.group_id == 0 ? "--" : "分组#{self.group_id}" end # 助教评分 def ta_score ta_mode if ta_mode == 1 ts_score = StudentWorksScore.find_by_sql("SELECT AVG(score) AS score FROM (SELECT * FROM (SELECT * FROM student_works_scores WHERE student_work_id = #{self.id} AND reviewer_role = 2 AND score IS NOT NULL ORDER BY created_at DESC) AS t GROUP BY user_id) AS a") score = ts_score.first.score.nil? ? nil : ts_score.first.score.to_f.try(:round, 2) else score = StudentWorksScore.where("student_work_id = #{self.id} AND reviewer_role = 2 AND score IS NOT NULL").last.try(:score) end end # 缺评次数 def absence_count absence_penalty_count = self.user.student_works_evaluation_distributions.joins(:student_work). where("homework_common_id = #{self.homework_common_id}").count - self.user.student_works_scores.joins(:student_work).where("homework_common_id = #{self.homework_common_id} and reviewer_role = 3").select("distinct student_work_id").count absence_penalty_count = absence_penalty_count < 0 ? 0 : absence_penalty_count end # 违规匿评次数 def appeal_count appeal_count = self.user.student_works_scores.joins(:student_work).where("student_works.homework_common_id = #{self.homework_common_id} and appeal_status = 3").select("distinct student_work_id").count end def delete_atta atta last_score = student_works_scores.last (atta.author_id == User.current.id) && (last_score.blank? || last_score.try(:created_at) < atta.created_on) end # 作品总体评价 def overall_appraisal return "--" if work_status <= 0 case (self.work_score.to_f / homework_common.total_score).round(2) when (0.90..1.00) '优秀' when (0.70...0.90) '良好' when (0.60...0.70) '及格' when (0.00...0.60) '不及格' end end # 实训作业的作品状态 0:未提交,1:未通关,2:按时通关(提交截止前通关),3:迟交通关(提交截止-补交截止间通关) def real_work_status status = work_status if status > 0 && myshixun if myshixun.status != 1 status = 1 else homework_end_time = homework_common.homework_group_setting(user_id)&.end_time if homework_end_time.present? && homework_end_time > myshixun.passed_time status = 2 elsif homework_end_time.present? && homework_common.allow_late && homework_common.late_time > myshixun.passed_time status = 3 else status = 1 end end end status end # 更新作品成绩 def set_work_score if work_status > 0 && homework_common && !homework_common.is_export_type? case homework_common.homework_type when "normal", "group" #如果是图文jupyter实训作业 tea_ass_proportion = homework_common.homework_detail_manual.ta_proportion tea_proportion = homework_common.homework_detail_manual.te_proportion gr_leader_proportion = 0 gr_leader_proportion = homework_common.homework_detail_manual.gr_proportion if homework_common.homework_detail_manual.is_group_grade? #是否有评分设置 教师、助教、学生评分 # teacher_score_setting = tea_proportion.to_f > 0 ? !student_work.teacher_score.nil? : false # teaching_asistant_score_setting = tea_ass_proportion.to_f > 0 ? !student_work.teaching_asistant_score.nil? : false # student_score_setting = (1 - tea_proportion - tea_ass_proportion) > 0 ? !student_work.student_score.nil? : false # is_score_setting = (teacher_score_setting || teaching_asistant_score_setting || student_score_setting) ? true : false # return if homework_common.homework_type == "normal" && HomeworkCommonsShixun.exists?(homework_common_id: homework_common.id) && self.ultimate_score if !homework_common&.homework_detail_manual&.final_mode if self.teacher_score if self.teaching_asistant_score.nil? if self.group_leader_score.nil? if self.student_score.nil? #只有老师评分 self.final_score = self.teacher_score else #有老师、学生评分 没有组长、助教 te_proportion = tea_proportion + (tea_ass_proportion + gr_leader_proportion) / 2 final_te_score = BigDecimal.new("#{self.teacher_score}") * BigDecimal.new("#{te_proportion}") final_s_score = BigDecimal.new("#{self.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{te_proportion}")) final_score = final_te_score + final_s_score self.final_score = format("%.2f", final_score.to_f) end else if self.student_score.nil? #有老师 和 组长评分 没有助教 学生 te_proportion = tea_proportion + (tea_ass_proportion) / 2 gr_proportion = gr_leader_proportion + (tea_ass_proportion) / 2 final_te_score = BigDecimal.new("#{self.teacher_score}") * BigDecimal.new("#{te_proportion}") final_gr_score = BigDecimal.new("#{self.group_leader_score}") * BigDecimal.new("#{gr_proportion}") final_score = final_te_score + final_gr_score self.final_score = format("%.2f",final_score.to_f) else #有老师、组长、学生评分 没有助教 te_proportion = tea_proportion + (tea_ass_proportion) / 3 gr_proportion = gr_leader_proportion + (tea_ass_proportion) / 3 final_te_score = BigDecimal.new("#{self.teacher_score}") * BigDecimal.new("#{te_proportion}") final_gr_score = BigDecimal.new("#{self.group_leader_score}") * BigDecimal.new("#{gr_proportion}") final_s_score = BigDecimal.new("#{self.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{te_proportion}") - BigDecimal.new("#{gr_proportion}")) final_score = final_te_score + final_gr_score + final_s_score self.final_score = format("%.2f",final_score.to_f) end end else if self.group_leader_score.nil? if self.student_score.nil? #有老师、助教评分 没有组长、学生 te_proportion = tea_proportion + (1.0 - tea_proportion - tea_ass_proportion) / 2 final_te_score = BigDecimal.new("#{self.teacher_score}") * BigDecimal.new("#{te_proportion}") final_ta_score = BigDecimal.new("#{self.teaching_asistant_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{te_proportion}")) final_score = final_te_score + final_ta_score self.final_score = format("%.2f",final_score.to_f) else #有老师、助教、学生评分 没有组长 te_proportion = tea_proportion + (gr_leader_proportion) / 3 ta_proportion = tea_ass_proportion + (gr_leader_proportion) / 3 final_te_score = BigDecimal.new("#{self.teacher_score}") * BigDecimal.new("#{te_proportion}") final_ta_score = BigDecimal.new("#{self.teaching_asistant_score}") * BigDecimal.new("#{ta_proportion}") final_s_score = BigDecimal.new("#{self.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{te_proportion}") - BigDecimal.new("#{ta_proportion}")) final_score = final_te_score + final_ta_score + final_s_score self.final_score = format("%.2f",final_score.to_f) end else if self.student_score.nil? #有老师、助教、组长评分 没有学生 te_proportion = tea_proportion + (1.0 - tea_proportion - tea_ass_proportion - gr_leader_proportion) / 3 ta_proportion = tea_ass_proportion + (1.0 - tea_proportion - tea_ass_proportion - gr_leader_proportion) / 3 gr_proportion = gr_leader_proportion + (1.0 - tea_proportion - tea_ass_proportion - gr_leader_proportion) / 3 final_te_score = BigDecimal.new("#{self.teacher_score}") * BigDecimal.new("#{te_proportion}") final_ta_score = BigDecimal.new("#{self.teaching_asistant_score}") * BigDecimal.new("#{ta_proportion}") final_gr_score = BigDecimal.new("#{self.group_leader_score}") * BigDecimal.new("#{gr_proportion}") final_score = final_te_score + final_ta_score + final_gr_score self.final_score = format("%.2f",final_score.to_f) else #有老师、助教、组长、学生评分 final_te_score = BigDecimal.new("#{self.teacher_score}") * BigDecimal.new("#{tea_proportion}") final_ta_score = BigDecimal.new("#{self.teaching_asistant_score}") * BigDecimal.new("#{tea_ass_proportion}") final_gr_score = BigDecimal.new("#{self.group_leader_score}") * BigDecimal.new("#{gr_leader_proportion}") final_s_score = BigDecimal.new("#{self.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{tea_proportion}") - BigDecimal.new("#{tea_ass_proportion}") - BigDecimal.new("#{gr_leader_proportion}")) final_score = final_te_score + final_ta_score + final_gr_score + final_s_score self.final_score = format("%.2f",final_score.to_f) end end end else if self.teaching_asistant_score.nil? if self.group_leader_score.nil? #没有老师、助教、组长 self.final_score = self.student_score elsif self.student_score.nil? #没有老师、助教、学生、有组长 self.final_score = self.group_leader_score else #没有老师、助教 有组长、学生 gr_proportion = gr_leader_proportion + (tea_proportion + tea_ass_proportion) / 2 final_gr_score = BigDecimal.new("#{self.group_leader_score}") * BigDecimal.new("#{gr_proportion}") final_s_score = BigDecimal.new("#{self.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{gr_proportion}")) final_score = final_gr_score + final_s_score self.final_score = format("%.2f", final_score.to_f) end elsif self.group_leader_score.nil? if self.student_score.nil? #有助教 没有老师、组长、学生 self.final_score = self.teaching_asistant_score else #有助教、学生 没有老师、组长 tea_proportion = tea_ass_proportion + (tea_proportion + gr_leader_proportion) / 2 final_tea_score = BigDecimal.new("#{self.teaching_asistant_score}") * BigDecimal.new("#{tea_proportion}") final_s_score = BigDecimal.new("#{self.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{tea_proportion}")) final_score = final_tea_score + final_s_score self.final_score = format("%.2f", final_score.to_f) end elsif self.student_score.nil? #有助教、组长 没有老师 学生 tea_proportion = tea_ass_proportion + (1.0 - tea_ass_proportion - gr_leader_proportion) / 2 gr_proportion = gr_leader_proportion + (1.0 - tea_ass_proportion - gr_leader_proportion) / 2 final_tea_score = BigDecimal.new("#{self.teaching_asistant_score}") * BigDecimal.new("#{tea_proportion}") final_gr_score = BigDecimal.new("#{self.group_leader_score}") * BigDecimal.new("#{gr_proportion}") final_score = final_tea_score + final_gr_score self.final_score = format("%.2f", final_score.to_f) else #有助教、组长、学生 没有老师 tea_proportion = tea_ass_proportion + (tea_proportion) / 3 gr_proportion = gr_leader_proportion + (tea_proportion) / 3 final_tea_score = BigDecimal.new("#{self.teaching_asistant_score}") * BigDecimal.new("#{tea_proportion}") final_gr_score = BigDecimal.new("#{self.group_leader_score}") * BigDecimal.new("#{gr_proportion}") final_s_score = BigDecimal.new("#{self.student_score}") * (BigDecimal.new('1.0') - BigDecimal.new("#{tea_proportion}") - BigDecimal.new("#{gr_proportion}")) final_score = final_tea_score + final_gr_score + final_s_score self.final_score = format("%.2f", final_score.to_f) end end else self.final_score = self.teacher_score ? self.teacher_score : (self.teaching_asistant_score ? self.teaching_asistant_score : (self.group_leader_score ? self.group_leader_score : self.student_score) ) end # 作品最终得分work_score 等于作品得分 - 缺评扣分 - 迟交扣分 - 申诉扣分 if self.final_score score = self.final_score.to_f - self.absence_penalty.to_f - self.late_penalty.to_f - self.appeal_penalty.to_f score = score - self.repeat_minus_score.to_f if homework_common.is_repeat_minus else score = nil end self.work_score = score ? format("%.2f", (score < 0 ? 0 : score).to_f) : nil when "practice" # 作品最终得分work_score 等于作品关卡得分 + 效率分 - 迟交扣分 if self.final_score work_score = self.final_score + self.eff_score.to_f - self.late_penalty.to_f work_score = work_score - self.repeat_minus_score.to_f if homework_common.is_repeat_minus? else work_score = nil end self.work_score = work_score ? format("%.2f", work_score < 0 ? 0 : work_score) : nil end end end # 实训作品是否已被评阅过 def shixun_has_comment? shixun_work_comments.present? || student_works_scores.select{|item| item.is_invalid }.present? || challenge_work_scores.present? end #编程作业是否已被评阅 #app/models/student_work.rb:365 编程作业 has_comment的值 def hack_has_comment? shixun_work_comments.size > 0 end # 普通/分组作品是否已被评阅过(只统计老师是否评阅过) def work_has_comment? student_works_scores.where(is_invalid: 0).select{|score| score.reviewer_role < 3}.size > 0 end # 普通/分组作品是否已被评阅过(老师、学生任一角色评阅过的都算) def work_has_comment_all_role? student_works_scores.where(is_invalid: 0).size > 0 end def scored? student_works_scores.where(is_invalid: 0).where.not(reviewer_role: 3, score: nil).exists? end def work_challenge_score game, score, challenge_id game_score = 0 adjust_score = challenge_work_scores.select{|t|t.challenge_id == challenge_id}.last if adjust_score.present? game_score = adjust_score.score elsif game.present? setting = homework_common.homework_group_setting game.user_id group_late_setting = homework_common.home_group_late_settings_export game.user_id if game.status == 2 && ((game.end_time && setting.end_time && game.end_time < setting.end_time) || (homework_common.allow_late && group_late_setting.late_time && game.end_time && game.end_time < group_late_setting.late_time)) answer_open_evaluation = homework_common.homework_detail_manual.answer_open_evaluation percentage = homework_common.homework_detail_manual.game_deduct_score_percentage game_score = answer_open_evaluation ? (game.view_answer ? Util::UUID.custom_deduct_percentage(score, percentage) : score ) : (game.final_score > 0 ? game.real_score(score) : 0) elsif game.final_score > 0 && ((game.end_time && setting.end_time && game.end_time < setting.end_time) || (homework_common.allow_late && group_late_setting.late_time && game.end_time && game.end_time < group_late_setting.late_time)) game_score = game.real_score(score) end end game_score end def work_challenge_score_for_export game, score, challenge_id, homework_group_setting game_score = 0 adjust_score = challenge_work_scores.select{|t|t.challenge_id == challenge_id}.last if adjust_score.present? game_score = adjust_score.score elsif game.present? setting = homework_group_setting group_late_setting = homework_common.home_group_late_settings_export game.user_id if game.status == 2 && ((game.end_time && setting.end_time && game.end_time < setting.end_time) || (homework_common.allow_late && group_late_setting.late_time && game.end_time && game.end_time < group_late_setting.late_time)) answer_open_evaluation = homework_common.homework_detail_manual.answer_open_evaluation percentage = homework_common.homework_detail_manual.game_deduct_score_percentage game_score = answer_open_evaluation ? (game.view_answer ? Util::UUID.custom_deduct_percentage(score, percentage) : score ) : (game.final_score > 0 ? game.real_score(score) : 0) elsif game.final_score > 0 && ((game.end_time && setting.end_time && game.end_time < setting.end_time) || (homework_common.allow_late && group_late_setting.late_time && game.end_time && game.end_time < group_late_setting.late_time)) game_score = game.real_score(score) end end game_score end #是否通关 def has_passed? compelete_status == 2 || compelete_status == 3 || compelete_status == 4 end def unstart? compelete_status == 0 end # 是否E为截止通关 def deadline_passed? compelete_status == 4 end # def my_hacks # Hack.where(id: self.student_work_hacks.pluck(:hack_id)) # end def hacks if homework_common.send_type == 1 return self.my_hacks if self.my_hacks.present? hack_ids = [] hacks = homework_common.hacks settings_arr = homework_common.difficult_settings return Hack.none if settings_arr.blank? # index = Random.new(self.id).rand(self.user_id) arr = hacks.select { |d| d.difficult == 1 }.pluck(:id).uniq hack_ids << arr.sample(settings_arr[0].to_i) arr = hacks.select { |d| d.difficult == 2 }.pluck(:id).uniq hack_ids << arr.sample(settings_arr[1].to_i) arr = hacks.select { |d| d.difficult == 3 }.pluck(:id).uniq hack_ids << arr.sample(settings_arr[2].to_i) hacks = Hack.where(id: hack_ids.flatten) self.my_hacks = hacks hacks else homework_common.hacks end end # 分组作业学生端使用 # 学生创建的issue数量 def statistical_issues_count return "" if self.project.blank? self.project.issues.where("author_id = ? OR assigned_to_id= ?", self.user_id, self.user_id).size end def pull_requests_count return "--" if self.work_status == 0 return "--" if self.project.blank? self.project.pull_requests_count end # 分组作业使用 # 获取关联项目相关信息,如提交代码数量、代码行数等 # params code_stats def get_code_lines_count(code_stats) return "" if self.project_id.blank? || self.project_id == 0 || code_stats.blank? || code_stats[self.project_id].blank? project_user = self.user result = code_stats[self.project_id]["authors"]&.select {|item| item["name"] == project_user.login || item["name"] == project_user.lastname || item["email"] == project_user.mail}&.first result.present? ? result['additions'] : "" end def update_code_time(code_line) return if project.blank? if code_line.present? && code_lines_count != code_line.to_i project.code_update_time = Time.now self.code_lines_count = code_line.to_i project.save self.save # 兼容之前的 elsif code_line.present? && code_lines_count == code_line.to_i && project.code_update_time.blank? project.code_update_time = project.updated_on project.save end project.code_update_time end # 提交次数 def submit_size #return 0 if homework_common.submit_num.blank? || homework_common.submit_num.zero? # 这里加一的原因是 第一次提交不创建历史记录s if self.histories.blank? && work_status == 0 return 0 end size = 1 histories&.size.to_i + size end # 提交批次 def submit_num(history_id) return 0 if history_id.to_i == 0 histories.where("id < #{history_id}").size + 1 end # 判断学生是否能提交作品 用于图文作业和分组作业 def can_submit? # 是否开启提交限制 if self.homework_common.can_submit # 没有提交记录代表可以提交 return true if self.histories.blank? # 这里加一的原因是 第一次提交不创建历史记录 size = 0 size = 1 if self.homework_common.late_duration # 如果在补交阶段 (homework_common.submit_num + size) > self.histories.size + 1 else true end end # 每次提交时,增加一条记录 def create_history! if project.present? && project.code_update_time.present? && work_status == 0 history_work_status = 3 else history_work_status = work_status end student_work_history = StudentWorkHistory.new(self.attributes.except('id').merge( student_work_id: self.id, attachment_ids: self.attachments.pluck(:id), work_status: history_work_status )) student_work_history.save! self.update_user_id = User.current&.id self.update_time = Time.now self.save! end end