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 ? 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", homework.max_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 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.course.is_end)) #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 ? 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", homework.max_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 end