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.
341 lines
17 KiB
341 lines
17 KiB
class HomeworksService
|
|
|
|
# 创建实训作业
|
|
def create_homework shixun, course, category, current_user
|
|
ActiveRecord::Base.transaction do
|
|
homework = HomeworkCommon.new(name: shixun.name, description: shixun.description, homework_type: 4,
|
|
user_id: current_user.id, course_id: course.id,
|
|
course_second_category_id: category.try(:id).to_i)
|
|
|
|
homework_detail_manual = HomeworkDetailManual.new
|
|
homework.homework_detail_manual = homework_detail_manual
|
|
|
|
if homework.save!
|
|
homework_detail_manual.save! if homework_detail_manual
|
|
HomeworkCommonsShixun.create!(homework_common_id: homework.id, shixun_id: shixun.id)
|
|
HomeworksService.new.create_shixun_homework_cha_setting(homework, shixun)
|
|
HomeworksService.new.create_works_list(homework, course)
|
|
end
|
|
homework
|
|
end
|
|
end
|
|
|
|
#更新实训作业的状态
|
|
def update_shixun_work_status homework
|
|
shixun = homework.shixuns.first
|
|
student_works = homework.student_works.unfinished
|
|
homework_challenge_settings = homework.homework_challenge_settings
|
|
challeng_ids = homework_challenge_settings.map(&:challenge_id)
|
|
# 取已发布的作品
|
|
if homework.unified_setting
|
|
student_works = student_works
|
|
else
|
|
setting = homework.homework_group_settings.group_published
|
|
if setting.blank?
|
|
student_works = student_works.none
|
|
else
|
|
users = homework.course.course_members.course_find_by_ids("course_group_id",setting.map(&:course_group_id))
|
|
student_works = student_works.homework_by_user(users.map(&:user_id))
|
|
end
|
|
end
|
|
# 已发布作品且状态为未提交的作品 如果有开启过实训则更新状态
|
|
myshixuns = Myshixun.where(:shixun_id => shixun.id, :user_id => student_works.map(&:user_id))
|
|
myshixuns.each do |myshixun|
|
|
work = student_works.homework_by_user(myshixun.user_id).first
|
|
setting_time = homework.homework_group_setting myshixun.user_id
|
|
games = myshixun.games.where(:challenge_id => challeng_ids)
|
|
myshixun_endtime = games.select{|game| game.status == 2}.size == games.size ? games.map(&:end_time).max : nil
|
|
compelete_status = 0
|
|
if myshixun_endtime.present? && myshixun_endtime < setting_time.end_time
|
|
if myshixun_endtime < setting_time.publish_time
|
|
compelete_status = 2
|
|
else
|
|
compelete_status = 1
|
|
end
|
|
end
|
|
if setting_time.end_time > Time.now
|
|
work.update_attributes(:work_status => 1, :late_penalty => 0, :commit_time => myshixun.updated_at, :update_time => myshixun.updated_at, :myshixun_id => myshixun.id, :compelete_status => compelete_status)
|
|
else
|
|
work.update_attributes(:work_status => ((myshixun.is_complete? && (myshixun.done_time < setting_time.end_time)) ? 1 : 2), :late_penalty => (myshixun.is_complete? && (myshixun.done_time < setting_time.end_time) ? 0 : homework.late_penalty), :commit_time => myshixun.updated_at, :update_time => myshixun.updated_at, :myshixun_id => myshixun.id, :compelete_status => compelete_status)
|
|
end
|
|
set_shixun_final_score work
|
|
end
|
|
# 更新所有学生的效率分
|
|
HomeworksService.new.update_student_eff_score HomeworkCommon.where(:id => homework.id).first
|
|
end
|
|
|
|
# 实训作业的评分
|
|
def set_shixun_final_score student_work
|
|
homework = student_work.homework_common
|
|
answer_open_evaluation = homework.homework_detail_manual.answer_open_evaluation
|
|
myshixun = student_work.myshixun
|
|
if student_work.work_status != 0 && myshixun.present?
|
|
final_score = 0
|
|
compelete = true
|
|
max_endtime = ""
|
|
user_total_score = 0
|
|
pass_consume_time = 0
|
|
homework.homework_challenge_settings.each do |setting|
|
|
game = myshixun.games.find_by(challenge_id: setting.challenge_id, status: 2)
|
|
unless game.nil?
|
|
pass_consume_time += (game.cost_time / 60.0).to_f
|
|
user_total_score += game.final_score.to_i < 0 ? 0 : game.challenge.score.to_i
|
|
adjust_score = student_work.challenge_work_scores.where(challenge_id: setting.challenge_id).last
|
|
final_score += adjust_score.present? ? adjust_score.score : (answer_open_evaluation ? setting.score : (game.final_score > 0 ? game.real_score(setting.score) : 0))
|
|
max_endtime = max_endtime == "" ? game.end_time : (game.end_time > max_endtime ? game.end_time : max_endtime)
|
|
else
|
|
compelete = false
|
|
end
|
|
end
|
|
|
|
if compelete && max_endtime != ""
|
|
homework = student_work.homework_common
|
|
setting_time = homework.homework_group_setting student_work.user_id
|
|
if setting_time.publish_time.present? && setting_time.end_time.present?
|
|
if max_endtime < setting_time.publish_time
|
|
student_work.compelete_status = 2
|
|
else
|
|
if max_endtime < setting_time.end_time || (homework.allow_late && (homework.course.end_date.nil? ||
|
|
max_endtime < homework.course.end_date.end_of_day))
|
|
student_work.compelete_status = 1
|
|
student_work.cost_time = max_endtime.to_i - setting_time.publish_time.to_i
|
|
else
|
|
student_work.compelete_status = 0
|
|
end
|
|
end
|
|
end
|
|
|
|
efficiency = (pass_consume_time == 0 ? 0 : Math.log((user_total_score / pass_consume_time.to_f) + 1.0))
|
|
student_work.efficiency = efficiency < 0 ? 0 : format("%.2f", efficiency)
|
|
|
|
if homework.work_efficiency
|
|
if homework.max_efficiency < student_work.efficiency
|
|
# homework.max_efficiency = student_work.efficiency
|
|
homework.update_column("max_efficiency", student_work.efficiency)
|
|
end
|
|
# eff_score = homework.max_efficiency == 0 ? 0 : student_work.efficiency / homework.max_efficiency * homework.eff_score
|
|
# student_work.eff_score = format("%.2f", eff_score)
|
|
# else
|
|
# student_work.eff_score = 0
|
|
end
|
|
elsif !compelete
|
|
student_work.compelete_status = 0
|
|
end
|
|
student_work.final_score = format("%.2f", final_score.to_f)
|
|
student_work.late_penalty = student_work.work_status == 1 ? 0 : homework.late_penalty
|
|
score = student_work.final_score + student_work.eff_score - student_work.late_penalty
|
|
student_work.work_score = format("%.2f", score < 0 ? 0 : score.to_f) unless student_work.ultimate_score
|
|
student_work.save!
|
|
end
|
|
end
|
|
|
|
# 计算实训作品学生的效率分
|
|
def update_student_eff_score homework
|
|
if homework.work_efficiency && homework.max_efficiency != 0
|
|
homework.student_works.where("compelete_status != 0").each do |student_work|
|
|
eff_score = student_work.efficiency / homework.max_efficiency * homework.eff_score
|
|
student_work.eff_score = format("%.2f", eff_score)
|
|
student_work.late_penalty = student_work.work_status == 1 ? 0 : homework.late_penalty
|
|
unless student_work.ultimate_score
|
|
work_score = student_work.final_score.to_f + student_work.eff_score - student_work.late_penalty
|
|
student_work.work_score = format("%.2f", work_score < 0 ? 0 : work_score)
|
|
end
|
|
student_work.save!
|
|
end
|
|
else
|
|
homework.student_works.where("compelete_status != 0").each do |student_work|
|
|
student_work.eff_score = 0
|
|
student_work.late_penalty = student_work.work_status == 1 ? 0 : homework.late_penalty
|
|
unless student_work.ultimate_score
|
|
work_score = student_work.final_score.to_f + student_work.eff_score - student_work.late_penalty
|
|
student_work.work_score = format("%.2f", work_score < 0 ? 0 : work_score)
|
|
end
|
|
student_work.save!
|
|
end
|
|
end
|
|
end
|
|
|
|
# 用户评测时更新实训作业成绩
|
|
def update_myshixun_work_score_old myshixun
|
|
ActiveRecord::Base.transaction do
|
|
student_works = myshixun.student_works.where(user_id: myshixun.user_id)
|
|
#logger.info("#############student_works_count: #{student_works.count}")
|
|
if student_works.count > 0
|
|
student_works.each do |work|
|
|
homework = work.homework_common
|
|
#logger.info("#############member_course_group_id: #{member.try(:course_group_id)}")
|
|
setting_time = homework.homework_group_setting work.user_id
|
|
if setting_time.end_time.present? && (setting_time.end_time > Time.now || (homework.allow_late && homework.late_time && homework.late_time > Time.now))
|
|
#logger.info("#############setting_time: #{setting_time.end_time}")
|
|
|
|
user_total_score = 0
|
|
pass_consume_time = 0
|
|
final_score = 0
|
|
homework.homework_challenge_settings.each do |setting|
|
|
game = myshixun.games.where(:challenge_id => setting.challenge_id, :status => 2).first
|
|
unless game.nil?
|
|
pass_consume_time += (game.cost_time / 60.0).to_f
|
|
user_total_score += game.final_score.to_i < 0 ? 0 : game.challenge.score.to_i
|
|
adjust_score = work.challenge_work_scores.where(:challenge_id => setting.challenge_id).last
|
|
final_score += adjust_score.present? ? adjust_score.score : (homework.homework_detail_manual.answer_open_evaluation ? setting.score : (game.final_score > 0 ? game.real_score(setting.score) : 0))
|
|
end
|
|
end
|
|
if work.work_status == 0
|
|
is_complete = myshixun.is_complete? && (myshixun.done_time < setting_time.end_time)
|
|
work.work_status = setting_time.end_time > Time.now ? 1 : (is_complete ? 1 : 2)
|
|
work.late_penalty = setting_time.end_time > Time.now ? 0 : (is_complete ? 0 : homework.late_penalty)
|
|
work.commit_time = myshixun.created_at > setting_time.publish_time ? setting_time.publish_time : myshixun.created_at
|
|
work.myshixun_id = myshixun.id
|
|
end
|
|
|
|
games = myshixun.games.where(:challenge_id => homework.homework_challenge_settings.map(&:challenge_id))
|
|
myshixun_endtime = games.select{|game| game.status == 2}.size == games.size ? games.map(&:end_time).max : nil
|
|
if myshixun_endtime.present?
|
|
min_efficiency_changed = min_efficiency_changed.present? ? min_efficiency_changed : false
|
|
work.compelete_status = 1
|
|
work.cost_time = myshixun_endtime.to_i - setting_time.publish_time.to_i
|
|
|
|
efficiency = (pass_consume_time == 0 ? 0 : Math.log((user_total_score / pass_consume_time.to_f) + 1.0))
|
|
work.efficiency = format("%.2f", efficiency)
|
|
|
|
# 如果作业的最大效率值有变更则更新所有作品的效率分
|
|
if homework.work_efficiency && homework.max_efficiency < work.efficiency
|
|
homework.update_column("max_efficiency", work.efficiency)
|
|
end
|
|
end
|
|
|
|
work.update_time = Time.now
|
|
|
|
work.final_score = final_score
|
|
score = work.final_score + work.eff_score - work.late_penalty
|
|
work.work_score = format("%.2f",(score < 0 ? 0 : score).to_f) unless work.ultimate_score
|
|
#logger.info("#############work_score: #{score}")
|
|
work.save!
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# 用户开启实训时更新作品状态
|
|
def update_myshixun_work_status myshixun
|
|
student_works = StudentWork.find_by_sql("SELECT sw.* FROM student_works sw, homework_commons_shixuns hcs WHERE
|
|
sw.user_id = #{myshixun.user_id} AND sw.`homework_common_id` = hcs.`homework_common_id`
|
|
AND hcs.`shixun_id` = #{myshixun.shixun_id} and sw.work_status = 0")
|
|
Rails.logger.info("#############student_works_count: #{student_works.count}")
|
|
if student_works.count > 0
|
|
student_works.each do |work|
|
|
homework = work.homework_common
|
|
setting_time = homework.homework_group_setting work.user_id
|
|
if setting_time.end_time.present? &&
|
|
(setting_time.end_time > Time.now || (homework.allow_late && homework.late_time && homework.late_time > Time.now))
|
|
|
|
work.work_status = setting_time.end_time > Time.now ? 1 : 2
|
|
work.late_penalty = setting_time.end_time > Time.now ? 0 : homework.late_penalty
|
|
work.update_time = Time.now
|
|
work.commit_time = Time.now
|
|
work.myshixun_id = myshixun.id
|
|
work.save!
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
# 实训作业的关卡设置
|
|
def create_shixun_homework_cha_setting homework, shixun
|
|
if shixun.present?
|
|
sum_score = 0
|
|
shixun.challenges.each_with_index do |challeng, index|
|
|
if index < shixun.challenges.length - 1
|
|
score = ((100.0 / shixun.challenges.length) * 100).floor / 100.0
|
|
sum_score += score
|
|
else
|
|
score = 100 - sum_score
|
|
end
|
|
HomeworkChallengeSetting.create!(homework_common_id: homework.id, challenge_id: challeng.id,
|
|
shixun_id: shixun.id, score: score)
|
|
end
|
|
end
|
|
end
|
|
|
|
# 为课堂学生创建作品
|
|
def create_works_list homework, course
|
|
if course.present? && CourseMember.students(course).size > 0
|
|
str = ""
|
|
CourseMember.students(course).each do |student|
|
|
str += "," if str != ""
|
|
str += "(#{homework.id},#{student.user_id}, '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}', '#{Time.now.strftime('%Y-%m-%d %H:%M:%S')}')"
|
|
end
|
|
if str != ""
|
|
sql = "insert into student_works (homework_common_id, user_id, created_at, updated_at) values" + str
|
|
ActiveRecord::Base.connection.execute sql
|
|
end
|
|
end
|
|
end
|
|
|
|
# 计算实训作品成绩
|
|
def update_myshixun_work_score work, myshixun, games, homework, challenge_settings
|
|
user_total_score = 0
|
|
pass_consume_time = 0
|
|
final_score = 0
|
|
setting_time = homework.homework_group_setting myshixun.user_id
|
|
homework_end_or_late_time = homework.allow_late ? homework.late_time : setting_time.end_time
|
|
games.each do |game|
|
|
# 在截止时间前通关的关卡才考虑得分
|
|
if game.status == 2 && game.end_time <= homework_end_or_late_time
|
|
challenge_setting = challenge_settings.select{|setting| setting.challenge_id == game.challenge_id}.first
|
|
pass_consume_time += (game.cost_time / 60.0).to_f
|
|
user_total_score += game.final_score.to_i < 0 ? 0 : game.challenge.score.to_i
|
|
adjust_score = work.challenge_work_scores.select{|work_score| work_score.challenge_id == game.challenge_id}.last
|
|
final_score += if adjust_score.present?
|
|
adjust_score.score
|
|
elsif homework.homework_detail_manual.answer_open_evaluation
|
|
challenge_setting.score
|
|
elsif game.final_score > 0
|
|
game.real_score(challenge_setting.score)
|
|
else
|
|
0
|
|
end
|
|
end
|
|
end
|
|
|
|
myshixun_endtime = games.select{|game| game.status == 2}.size == games.size ? games.map(&:end_time).max : nil
|
|
|
|
if work.work_status == 0
|
|
is_complete = myshixun_endtime && (myshixun_endtime < setting_time.end_time)
|
|
if is_complete || (myshixun.created_at < setting_time.end_time && (!homework.allow_late || setting_time.end_time >= Time.now))
|
|
work.work_status = 1
|
|
elsif homework.allow_late && myshixun.created_at < homework.late_time
|
|
work.work_status = 2
|
|
end
|
|
end
|
|
|
|
if work.work_status != 0
|
|
if myshixun_endtime.present?
|
|
work.cost_time = myshixun_endtime.to_i - setting_time.publish_time.to_i
|
|
|
|
efficiency = (pass_consume_time == 0 ? 0 : Math.log((user_total_score / pass_consume_time.to_f) + 1.0))
|
|
work.efficiency = format("%.2f", efficiency)
|
|
|
|
if myshixun_endtime <= homework_end_or_late_time
|
|
work.compelete_status = myshixun_endtime < setting_time.publish_time ? 2 : 1
|
|
|
|
# 如果作业的最大效率值有变更则更新所有作品的效率分
|
|
homework.update_column("max_efficiency", work.efficiency) if homework.work_efficiency && homework.max_efficiency < work.efficiency
|
|
end
|
|
end
|
|
|
|
work.late_penalty = work.work_status == 2 ? homework.late_penalty : 0
|
|
work.commit_time = myshixun.created_at > setting_time.publish_time ? setting_time.publish_time : myshixun.created_at
|
|
work.myshixun_id = myshixun.id
|
|
work.update_time = myshixun.updated_at
|
|
|
|
work.final_score = final_score
|
|
score = work.final_score + work.eff_score - work.late_penalty
|
|
work.work_score = format("%.2f",(score < 0 ? 0 : score).to_f) unless work.ultimate_score
|
|
#logger.info("#############work_score: #{score}")
|
|
work.calculation_time = Time.now
|
|
work.save!
|
|
end
|
|
end
|
|
end |