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.

757 lines
33 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 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