class HomeworkCommonsController < ApplicationController include HomeworkCommonsHelper include ApplicationHelper include ExportHelper before_action :require_login, :check_auth, except: [:index, :choose_category] before_action :find_course, only: [:index, :create, :new, :shixuns, :subjects, :create_shixun_homework, :publish_homework, :end_homework, :set_public, :choose_category, :move_to_category, :choose_category, :create_subject_homework, :multi_destroy, :add_to_homework_bank] before_action :find_homework, only: [:edit, :show, :update, :group_list, :homework_code_repeat, :code_review_results, :code_review_detail, :show_comment, :settings, :works_list, :update_settings, :reference_answer, :publish_groups, :end_groups, :alter_name, :update_explanation, :update_score, :update_student_score] before_action :user_course_identity before_action :homework_publish, only: [:show, :works_list, :code_review_results, :show_comment, :settings, :reference_answer, :update_student_score] before_action :teacher_allowed, only: [:new, :edit, :create, :update, :shixuns, :subjects, :create_shixun_homework, :publish_homework, :end_homework, :set_public, :choose_category, :move_to_category, :choose_category, :create_subject_homework, :multi_destroy, :group_list, :homework_code_repeat, :code_review_results, :code_review_detail, :update_explanation, :update_settings, :add_to_homework_bank, :publish_groups, :end_groups] before_action :require_id_params, only: [:set_public, :multi_destroy, :publish_homework, :end_homework, :move_to_category, :add_to_homework_bank] before_action :course_manager, only: [:alter_name] def index tip_exception("type参数有误") if params[:type] && ![1, 3, 4].include?(params[:type].to_i) @user = current_user search = "#{params[:search].to_s.strip.downcase}" if params[:search] order = params[:order] page = params[:page] ? params[:page].to_i : 1 @homework_type = params[:type] ? params[:type].to_i : 4 module_type = @homework_type == 4 ? "shixun_homework" : @homework_type == 1 ? "common_homework" : "group_homework" @homework_commons = @course.homework_commons.where(homework_type: @homework_type) @main_category = @course.course_modules.find_by(module_type: module_type) if @homework_type == 4 && !params[:category].blank? @category = @main_category.course_second_categories.find_by(id: params[:category]) tip_exception("子目录id有误") if !@category.present? @homework_commons = @homework_commons.where(course_second_category_id: params[:category]) elsif @homework_type == 4 @homework_commons = @homework_commons end @all_count = @homework_commons.size @member = @course.course_members.find_by(user_id: current_user.id, is_active: 1) # 老师显示所有的作业、未分班学生显示统一设置的且已发布、否则对学生所在分班已发布的作业 if @user_course_identity < Course::STUDENT @homework_commons = @homework_commons elsif @user_course_identity == Course::STUDENT if @member.try(:course_group_id).to_i == 0 @homework_commons = @homework_commons.homework_published.unified_setting else not_homework_ids = @course.homework_group_settings.none_published.where("course_group_id = #{@member.try(:course_group_id)}").pluck(:homework_common_id) @homework_commons = @homework_commons.where.not(id: not_homework_ids).homework_published end else @homework_commons = @homework_commons.homework_published.unified_setting end @published_count = @user_course_identity < Course::STUDENT ? @homework_commons.homework_published.size : @homework_commons.size unless search.blank? @homework_commons = @homework_commons.where("homework_commons.name like ?", "%#{search}%") end unless order.blank? case order when '1' sql_str = %Q(homework_detail_manuals.comment_status = #{order} and homework_commons.end_time > '#{Time.now}') when '2' sql_str = %Q(allow_late = 1 and homework_commons.end_time < '#{Time.now}' and (late_time is null or late_time > '#{Time.now}')) when '3' sql_str = %Q(homework_detail_manuals.comment_status = #{order} and homework_detail_manuals.evaluation_end > '#{Time.now}') when '4' sql_str = %Q((homework_detail_manuals.comment_status = #{order} and homework_detail_manuals.appeal_time > '#{Time.now}')) when '5' sql_str = %Q((homework_detail_manuals.comment_status = #{order} or (anonymous_comment = 0 and homework_commons.end_time <= '#{Time.now}'))) else sql_str = %Q(homework_detail_manuals.comment_status = #{order}) end @homework_commons = @homework_commons.joins(:homework_detail_manual).where(sql_str) end @task_count = @homework_commons.size @homework_commons = @homework_commons.order("IF(ISNULL(homework_commons.publish_time),0,1), homework_commons.publish_time DESC, homework_commons.created_at DESC").page(page).per(15) if @homework_type == 4 @homework_commons = @homework_commons.includes(:homework_detail_manual, :published_settings, :shixuns) elsif @homework_type == 3 @homework_commons = @homework_commons.includes(:homework_detail_manual, :published_settings, :homework_detail_group) else @homework_commons = @homework_commons.includes(:homework_detail_manual, :published_settings) end end def works_list @current_user = current_user @member = @course.course_member(@current_user.id) @shixun = @homework.shixuns.take if @homework.homework_type == "practice" student_works = @homework.all_works @all_member_count = student_works.size if @homework.publish_time.blank? || (@homework.publish_time > Time.now) @student_works = [] if (params[:format] == "xlsx") || (params[:format] == "zip") normal_status(-1,"作业未发布") end else if @user_course_identity == Course::STUDENT @work = @homework.user_work(current_user.id) # 学生访问列表时计算个人成绩 if @homework.homework_type == "practice" myshixun = Myshixun.find_by(shixun_id: @shixun.id, user_id: current_user.id) if @work && myshixun challenge_settings = @homework.homework_challenge_settings games = myshixun.games.where(challenge_id: challenge_settings.pluck(:challenge_id)) HomeworksService.new.update_myshixun_work_score @work, myshixun, games, @homework, challenge_settings end end # 学生已提交作品且补交(提交)已截止、作品公开、非匿评阶段 if @work&.work_status.to_i > 0 && (@homework.work_public || @homework.score_open) && ((!@homework.anonymous_comment && @homework.end_or_late) || (@homework_detail_manual.comment_status > 4 && @homework.end_or_late)) @student_works = student_works.where("user_id != #{@work.user_id}") # 匿评、申诉阶段只能看到分配给自己的匿评作品 elsif @work&.work_status.to_i > 0 && @homework.anonymous_comment && @homework_detail_manual.comment_status > 2 && @homework_detail_manual.comment_status <= 4 @is_evaluation = true @student_works = student_works.joins(:student_works_evaluation_distributions).where( "student_works_evaluation_distributions.user_id = #{@current_user.id}") else @student_works = [] end @score_open = @homework.score_open && @work&.work_status.to_i > 0 elsif @user_course_identity < Course::STUDENT @student_works = @homework.teacher_works(@member) @all_member_count = @student_works.size @score_open = true elsif @user_course_identity > Course::STUDENT && @homework.work_public @student_works = student_works @score_open = false else @student_works = [] end if @student_works.size > 0 # 教师评阅搜索 0: 未评, 1 已评 unless params[:teacher_comment].blank? student_work_ids = StudentWorksScore.where(student_work_id: @student_works.map(&:id)).pluck(:student_work_id) if params[:teacher_comment].to_i == 0 @student_works = @student_works.where.not(id: student_work_ids) elsif params[:teacher_comment].to_i == 1 @student_works = @student_works.where(id: student_work_ids) end end # 作品状态 0: 未提交, 1 按时提交, 2 延迟提交 unless params[:work_status].blank? @student_works = @student_works.where(work_status: params[:work_status]) end # 分班情况 unless params[:course_group].blank? group_user_ids = @course.students.where(course_group_id: params[:course_group]).pluck(:user_id) # 有分组只可能是老师身份查看列表 @student_works = @student_works.where(user_id: group_user_ids) end # 输入姓名和学号搜索 # TODO user_extension 如果修改 请调整 unless params[:search].blank? @student_works = @student_works.joins(user: :user_extension).where("concat(lastname, firstname) like ? or student_id like ?", "%#{params[:search]}%", "%#{params[:search]}%") end @work_count = @student_works.size @work_excel = @student_works.where("work_status > 0") # 排序 rorder = params[:order].blank? ? "update_time" : params[:order] b_order = params[:b_order].blank? ? "desc" : params[:b_order] if rorder == "update_time" || rorder == "work_score" @student_works = @student_works.order("student_works.#{rorder} #{b_order}") elsif rorder == "student_id" @student_works = @student_works.joins(user: :user_extension).order("user_extensions.#{rorder} #{b_order}") end # 分页参数 page = params[:page] || 1 limit = params[:limit] || 20 @student_works = @student_works.page(page).per(limit) @students = @course.students.where(user_id: @student_works.pluck(:user_id)).preload(:course_group) if @homework.homework_type == "practice" @student_works = @student_works.includes(:student_works_scores, user: :user_extension, myshixun: :games) else @student_works = @student_works.includes(:student_works_scores, :project, user: :user_extension) end end if params[:format] == "xlsx" if @user_course_identity >= Course::STUDENT tip_exception(403, "无权限操作") elsif @work_excel.blank? || @work_excel.size == 0 normal_status(-1,"暂无用户提交!") elsif params[:export].present? && params[:export] normal_status(0,"正在下载中") else respond_to do |format| format.xlsx{ set_export_cookies student_work_to_xlsx(@work_excel,@homework) exercise_export_name = "#{current_user.real_name}_#{@course.name}_#{@homework.name}_#{Time.now.strftime('%Y%m%d_%H%M%S')}" render xlsx: "#{exercise_export_name.strip}",template: "homework_commons/works_list.xlsx.axlsx",locals: {table_columns: @work_head_cells,task_users: @work_cells_column} } end end elsif params[:format] == "zip" if @user_course_identity >= Course::STUDENT tip_exception(403, "无权限操作") else if @work_excel.present? zip_works = @work_excel&.where("work_status > 0") status = checkfileSize(zip_works) else status = -1 end if status == 0 if params[:export].present? && params[:export] normal_status(0,"正在下载中") else respond_to do |format| format.zip{ set_export_cookies zipfile = zip_homework_common @homework, zip_works file = decode64(zipfile[0][:base64file]) send_file "#{OUTPUT_FOLDER}/#{file}", filename: filename_for_content_disposition(file), type: 'application/zip' } end end else normal_status(status, status == -2 ? "500M" : "无附件可下载") end end end end end def update_score tip_exception("作业还未发布,暂不能计算成绩") if @homework.publish_time.nil? || @homework.publish_time > Time.now begin if @homework.unified_setting student_works = @homework.student_works user_ids = @course.students.pluck(:user_id) else user_ids = @course.students.where(course_group_id: @homework.published_settings.pluck(:course_group_id)).pluck(:user_id) student_works = @homework.student_works.where(user_id: user_ids) end student_works = student_works.includes(:challenge_work_scores) challenge_settings = @homework.homework_challenge_settings challenge_setting_ids = challenge_settings.pluck(:challenge_id) myshixuns = Myshixun.where(shixun_id: @homework.homework_commons_shixun&.shixun_id, user_id: user_ids).includes(:games) myshixuns.find_each(batch_size: 100) do |myshixun| work = student_works.select{|work| work.user_id == myshixun.user_id}.first if work && myshixun games = myshixun.games.select{|game| challenge_setting_ids.include?(game.challenge_id)} HomeworksService.new.update_myshixun_work_score work, myshixun, games, @homework, challenge_settings end end HomeworksService.new.update_student_eff_score @homework if (@homework.allow_late && @homework.late_time < Time.now) || (!@homework.allow_late && @homework.end_time < Time.now) @homework.update_attribute('calculation_time', Time.now) normal_status("更新成功") rescue Exception => e uid_logger(e.message) tip_exception(e.message) raise ActiveRecord::Rollback end end def update_student_score work = @homework.student_works.find_by(user_id: current_user.id) myshixun = Myshixun.find_by(shixun_id: params[:shixun_id], user_id: current_user.id) ActiveRecord::Base.transaction do begin if work && myshixun challenge_settings = @homework.homework_challenge_settings games = myshixun.games.where(challenge_id: challenge_settings.pluck(:challenge_id)) HomeworksService.new.update_myshixun_work_score work, myshixun, games, @homework, challenge_settings normal_status("更新成功") else normal_status("还开启挑战,暂不能更新成绩") end rescue Exception => e uid_logger(e.message) tip_exception(e.message) raise ActiveRecord::Rollback end end end def alter_name tip_exception("作业名称不能为空") if params[:name].blank? @homework.update_attributes(name: params[:name].strip) normal_status("更新成功") end def show @user = current_user @attachments = @homework.attachments.where(attachtype: 1) @work = @homework.user_work(current_user.id) if @user_course_identity == Course::STUDENT end # 评论列表接口、 包含一级和二级评论的获取 def show_comment @page = params[:page] || 1 @limit = params[:limit] || 10 @parent = params[:parent_id] @current_user = current_user @messages = @homework.journals_for_messages @messages_count = @messages.size @parent_messages_count = @messages.parent_comment.size if @parent @messages = @messages.where(m_parent_id: @parent) else @messages = @messages.parent_comment end @messages = @messages.page(@page).per(@limit).order("created_on desc") end def reference_answer # 只有课堂老师 或 作业设置了“公开答案”,则在作业截止时间后(若开启了补交,则补交截止后),提交了作品的学生 才能访问 if @homework.view_answer(@user_course_identity, current_user.id) @attachments = @homework.attachments.where(attachtype: 2) else normal_status(403, "无权限访问") end @current_user = current_user @work = @homework.user_work(current_user.id) if @user_course_identity == Course::STUDENT end def update_explanation @homework.update_attributes(explanation: params[:explanation]) normal_status(0, "更新成功") end def new tip_exception("type参数有误") if params[:type].blank? || ![1, 3].include?(params[:type].to_i) @homework_type = params[:type].to_i end def create tip_exception("type参数有误") if params[:type].blank? || ![1, 3].include?(params[:type].to_i) @homework_type = params[:type].to_i if @homework_type == 3 validate_min_max_num tip_exception("base_on_project参数不能为空") if params[:base_on_project].nil? end ActiveRecord::Base.transaction do begin @homework = HomeworkCommon.new(homework_params) @homework.homework_type = @homework_type @homework.user_id = current_user.id @homework.course_id = @course.id homework_detail_manual = HomeworkDetailManual.new @homework.homework_detail_manual = homework_detail_manual homework_detail_manual.te_proportion = 0.7 homework_detail_manual.ta_proportion = 0.3 if @homework_type == 3 homework_detail_group = HomeworkDetailGroup.new(min_num: params[:min_num].to_i, max_num: params[:max_num].to_i, base_on_project: params[:base_on_project]) @homework.homework_detail_group = homework_detail_group end if @homework.save! homework_detail_manual.save! if homework_detail_manual homework_detail_group.save! if homework_detail_group # 作业描述的附件 Attachment.associate_container(params[:attachment_ids], @homework.id, @homework.class) if params[:attachment_ids] # 作业参考答案的附件 Attachment.associate_container(params[:reference_attachment_ids], @homework.id, @homework.class, 2) if params[:reference_attachment_ids] HomeworksService.new.create_works_list(@homework, @course) else tip_exception("创建失败") end rescue Exception => e uid_logger(e.message) tip_exception(e.message) raise ActiveRecord::Rollback end end end def edit end def update if @homework.homework_type == "group" validate_min_max_num tip_exception("base_on_project参数不能为空") if !@homework.has_relate_project && params[:base_on_project].nil? end ActiveRecord::Base.transaction do begin @homework.update_attributes(homework_params) if @homework.homework_type == "group" homework_detail_group = @homework.homework_detail_group param_min = params[:min_num].to_i param_max = params[:max_num].to_i homework_detail_group.min_num = @homework.has_commit_work ? [param_min, homework_detail_group.min_num].min : param_min homework_detail_group.max_num = @homework.has_commit_work ? [param_max, homework_detail_group.max_num].max : param_max homework_detail_group.base_on_project = params[:base_on_project] unless @homework.has_relate_project homework_detail_group.save! end # 作业描述的附件 Attachment.associate_container(params[:attachment_ids], @homework.id, @homework.class) if params[:attachment_ids] # 作业参考答案的附件 Attachment.associate_container(params[:reference_attachment_ids], @homework.id, @homework.class, 2) if params[:reference_attachment_ids] normal_status(0, "更新成功") rescue Exception => e uid_logger(e.message) tip_exception(e.message) raise ActiveRecord::Rollback end end end def settings @user = current_user @work = @homework.user_work(current_user.id) if @user_course_identity == Course::STUDENT end def update_settings begin # 课堂结束后不能再更新 unless @course.is_end # 作业未发布时,unified_setting参数不能为空 if @homework.publish_time.nil? || @homework.publish_time > Time.now tip_exception("缺少统一设置的参数") if params[:unified_setting].nil? if params[:unified_setting] || @course.course_groups_count == 0 tip_exception("发布时间不能为空") if params[:publish_time].blank? tip_exception("截止时间不能为空") if params[:end_time].blank? tip_exception("发布时间不能早于当前时间") if params[:publish_time] <= Time.now.strftime("%Y-%m-%d %H:%M:%S") tip_exception("截止时间不能早于当前时间") if params[:end_time] <= Time.now.strftime("%Y-%m-%d %H:%M:%S") tip_exception("截止时间不能早于发布时间") if params[:publish_time] > params[:end_time] tip_exception("截止时间不能晚于课堂结束时间") if @course.end_date.present? && params[:end_time] > @course.end_date.end_of_day @homework.unified_setting = 1 @homework.homework_group_settings.destroy_all @homework.publish_time = params[:publish_time] # 截止时间为空时取发布时间后一个月 @homework.end_time = params[:end_time] else tip_exception("分班发布设置不能为空") if params[:group_settings].blank? # 创建作业的分班设置 create_homework_group_settings @homework setting_group_ids = [] params[:group_settings].each do |setting| tip_exception("分班id不能为空") if setting[:group_id].length == 0 tip_exception("发布时间不能为空") if setting[:publish_time].blank? tip_exception("截止时间不能为空") if setting[:end_time].blank? tip_exception("发布时间不能早于当前时间") if setting[:publish_time] <= strf_time(Time.now) tip_exception("截止时间不能早于当前时间") if setting[:end_time] <= strf_time(Time.now) tip_exception("截止时间不能早于发布时间") if setting[:publish_time] > setting[:end_time] tip_exception("截止时间不能晚于课堂结束时间") if @course.end_date.present? && setting[:end_time] > @course.end_date.end_of_day publish_time = setting[:publish_time] == "" ? Time.now : setting[:publish_time] # 截止时间为空时取发布时间后一个月 end_time = setting[:end_time] == "" ? Time.at(publish_time.to_time.to_i+30*24*3600) : setting[:end_time] HomeworkGroupSetting.where(homework_common_id: @homework.id, course_group_id: setting[:group_id]). update_all(publish_time: publish_time, end_time: end_time) setting_group_ids << setting[:group_id] end # 未设置的分班:发布时间和截止时间都为nil HomeworkGroupSetting.where.not(course_group_id: setting_group_ids).where(homework_common_id: @homework.id). update_all(publish_time: nil, end_time: nil) # 记录已发布需要发消息的分班 publish_group_ids = HomeworkGroupSetting.where(homework_common_id: @homework.id).group_published.pluck(:course_group_id) @homework.unified_setting = 0 @homework.publish_time = @homework.min_group_publish_time @homework.end_time = @homework.max_group_end_time end # 如果作业立即发布则更新状态、发消息 if @homework.publish_time <= Time.now and @homework_detail_manual.comment_status == 0 @homework_detail_manual.comment_status = 1 send_tiding = true end # 作业在"提交中"状态时 else if @homework.end_time > Time.now && @homework.unified_setting tip_exception("截止时间不能为空") if params[:end_time].blank? tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now) tip_exception("截止时间不能晚于课堂结束时间") if @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) @homework.end_time = params[:end_time] elsif !@homework.unified_setting create_homework_group_settings @homework tip_exception("分班发布设置不能为空") if params[:group_settings].blank? params[:group_settings].each do |setting| group_settings = HomeworkGroupSetting.where(homework_common_id: @homework.id, course_group_id: setting[:group_id]) tip_exception("分班id不能为空") if setting[:group_id].length == 0 tip_exception("发布时间不能为空") if setting[:publish_time].blank? tip_exception("截止时间不能为空") if setting[:end_time].blank? # 如果该发布规则 没有已发布的分班则需判断发布时间 tip_exception("发布时间不能早于等于当前时间") if setting[:publish_time] <= strf_time(Time.now) && group_settings.group_published.count == 0 tip_exception("截止时间不能早于等于当前时间") if setting[:end_time] <= strf_time(Time.now) tip_exception("截止时间不能早于发布时间") if setting[:publish_time] > setting[:end_time] tip_exception("截止时间不能晚于课堂结束时间") if @course.end_date.present? && setting[:end_time] > strf_time(@course.end_date.end_of_day) group_settings.none_published.update_all(publish_time: setting[:publish_time]) group_settings.none_end.update_all(end_time: setting[:end_time]) end @homework.end_time = @homework.max_group_end_time end end # 补交设置 tip_exception("缺少allow_late参数") if params[:allow_late].nil? tip_exception("缺少late_penalty参数") if params[:allow_late] && params[:late_penalty].blank? tip_exception("缺少late_time参数") if params[:allow_late] && params[:late_time].blank? current_late_penalty = @homework.late_penalty if params[:allow_late] tip_exception("补交结束时间必须晚于截止时间") if params[:late_time] <= strf_time(@homework.end_time) tip_exception("补交结束时间不能晚于课堂结束时间") if @course.end_date.present? && params[:late_time] > strf_time(@course.end_date.end_of_day) tip_exception("迟交扣分不能小于0") if params[:late_penalty] && params[:late_penalty].to_i < 0 @homework.allow_late = true @homework.late_time = params[:late_time] @homework.late_penalty = params[:late_penalty].to_i else @homework.allow_late = false @homework.late_penalty = 0 @homework.late_time = nil end # 迟交扣分有变动则更新迟交学生的成绩 late_penalty_change = @homework.late_penalty != current_late_penalty if @homework.homework_type == "practice" # 实训作业的评分设置 tip_exception("缺少answer_open_evaluation参数") if params[:answer_open_evaluation].nil? tip_exception("缺少work_efficiency参数") if params[:work_efficiency].nil? tip_exception("缺少eff_score参数") if params[:work_efficiency] && params[:eff_score].blank? tip_exception("效率分不能小于等于0") if params[:eff_score] && params[:eff_score].to_i <= 0 tip_exception("缺少shixun_evaluation参数") if params[:shixun_evaluation].blank? tip_exception("缺少challenge_settings参数") if params[:challenge_settings].blank? # tip_exception("缺少challenge_id参数") if params[:challenge_settings][:challenge_id].blank? # tip_exception("缺少challenge_score参数") if params[:challenge_settings][:challenge_score].blank? # tip_exception("challenge_id参数的长度与challenge_score参数的长度不匹配") if # params[:challenge_settings][:challenge_score].length != params[:challenge_settings][:challenge_id].length current_eff_score = @homework.eff_score @homework.work_efficiency = params[:work_efficiency] @homework.eff_score = params[:work_efficiency] ? params[:eff_score].to_i : 0 update_eff_score = current_eff_score != @homework.eff_score if @homework_detail_manual.answer_open_evaluation != params[:answer_open_evaluation] @homework_detail_manual.answer_open_evaluation = params[:answer_open_evaluation] score_change = true end @homework_detail_manual.shixun_evaluation = params[:shixun_evaluation].to_i if params[:challenge_settings] params[:challenge_settings].each do |challenge| setting = @homework.homework_challenge_settings.find_by(challenge_id: challenge[:challenge_id]) score = challenge[:challenge_score] if setting && setting.score != score score_change = true setting.update_attributes(score: score) elsif setting.blank? score_change = true HomeworkChallengeSetting.create!(homework_common_id: @homework.id, challenge_id: challenge[:challenge_id], shixun_id: @homework.homework_commons_shixun.try(:shixun_id), score: score) end end if @homework.homework_challenge_settings.where.not(challenge_id: params[:challenge_settings].pluck(:challenge_id)).count > 0 score_change = true @homework.homework_challenge_settings.where.not(challenge_id: params[:challenge_settings].pluck(:challenge_id)).destroy_all end end # 公开设置 tip_exception("缺少score_open参数") if params[:score_open].nil? @homework.score_open = params[:score_open] @homework.save! # if score_change # @homework.student_works.has_committed.each do |student_work| # HomeworksService.new.set_shixun_final_score student_work # end # end # 更新所有学生的效率分(作业允许补交且补交已截止 或者 作业不允许补交且提交已截止) if update_eff_score && @homework.end_or_late_none_group HomeworksService.new.update_student_eff_score HomeworkCommon.find_by(id: @homework.id) end # 更新迟交扣分 if !(score_change || update_eff_score) && late_penalty_change @homework.student_works.where(work_status: 2).each do |work| work.late_penalty = @homework.late_penalty work.save! end end unless @homework.allow_late @homework.student_works.where(work_status: 2).update_all(work_status: 1) end @homework_detail_manual.save! @homework.save! else # 普通和分组作业的匿评设置 current_absence_penalty = @homework_detail_manual.absence_penalty current_appeal_penalty = @homework_detail_manual.appeal_penalty # 匿评未开启前可以更新:是否开启匿评、匿评开始时间、匿评数 if @homework_detail_manual.comment_status < 3 tip_exception("缺少anonymous_comment参数") if params[:anonymous_comment].nil? # anonymous_comment :true 是启用,false 是不启用 if params[:anonymous_comment] tip_exception("匿评开启时间不能为空") if params[:evaluation_start].blank? tip_exception("匿评开启时间不能早于截止时间") if params[:evaluation_start] < strf_time(@homework.end_time) tip_exception("匿评结束时间不能为空") if params[:evaluation_end].blank? tip_exception("匿评截止时间必须晚于匿评开启时间") if params[:evaluation_end] <= params[:evaluation_start] tip_exception("匿评截止时间不能晚于课堂结束时间") if @course.end_date.present? && params[:evaluation_end] > strf_time(@course.end_date.end_of_day) tip_exception("匿评数必须为正整数") if params[:evaluation_num].blank? || params[:evaluation_num].to_i < 1 tip_exception("缺评扣分不能为空") if params[:absence_penalty].blank? tip_exception("缺评扣分不能小于0") if params[:absence_penalty].to_i < 0 tip_exception("缺评扣分不能大于100") if params[:absence_penalty].to_i > 100 end @homework.anonymous_comment = params[:anonymous_comment] @homework_detail_manual.evaluation_start = !@homework.anonymous_comment ? nil : params[:evaluation_start] @homework_detail_manual.evaluation_num = !@homework.anonymous_comment ? 0 : params[:evaluation_num] # 不启用匿评时还原申诉设置和教师、助教的评分比例 unless @homework.anonymous_comment @homework.anonymous_appeal = false @homework_detail_manual.appeal_time = nil @homework_detail_manual.appeal_penalty = 0 @homework_detail_manual.te_proportion = 1 @homework_detail_manual.ta_proportion = 0 end end # 匿评未截止时可以更新匿评结束时间 if @homework_detail_manual.comment_status < 4 tip_exception("匿评结束时间不能为空") if @homework.anonymous_comment && params[:evaluation_end].blank? tip_exception("匿评截止时间必须晚于匿评开启时间") if @homework.anonymous_comment && params[:evaluation_end] <= strf_time(@homework_detail_manual.evaluation_start) tip_exception("匿评截止时间不能晚于课堂结束时间") if @homework.anonymous_comment && @course.end_date.present? && params[:evaluation_end] > strf_time(@course.end_date.end_of_day) @homework_detail_manual.evaluation_end = !@homework.anonymous_comment ? nil : params[:evaluation_end] end # 作业未结束可以更新缺评扣分 tip_exception("缺评扣分不能为空") if @homework.anonymous_comment && params[:absence_penalty].blank? tip_exception("缺评扣分不能小于0") if @homework.anonymous_comment && params[:absence_penalty].to_i < 0 tip_exception("缺评扣分不能大于100") if @homework.anonymous_comment && params[:absence_penalty].to_i > 100 @homework_detail_manual.absence_penalty = !@homework.anonymous_comment ? 0 : params[:absence_penalty].to_i # 匿评申诉设置 # 匿评申诉未开启前可以更新:是否启用匿评申诉 if @homework_detail_manual.comment_status < 4 && @homework.anonymous_comment tip_exception("缺少anonymous_appeal参数") if params[:anonymous_appeal].nil? @homework.anonymous_appeal = params[:anonymous_appeal] end # 匿评申诉未结束前可以更新:匿评申诉结束时间 if @homework_detail_manual.comment_status < 5 tip_exception("匿评申诉结束时间不能为空") if @homework.anonymous_appeal && params[:appeal_time].blank? tip_exception("匿评开启时间不能早于匿评截止时间") if @homework.anonymous_appeal && params[:appeal_time] <= strf_time(@homework_detail_manual.evaluation_end) tip_exception("匿评申诉结束不能晚于课堂结束时间") if @homework.anonymous_appeal && @course.end_date.present? && params[:appeal_time] > strf_time(@course.end_date.end_of_day) @homework_detail_manual.appeal_time = @homework.anonymous_appeal ? params[:appeal_time] : nil end # 作业未结束可以更新违规匿评扣分 tip_exception("违规匿评扣分不能为空") if @homework.anonymous_appeal && params[:appeal_penalty].blank? tip_exception("违规匿评扣分不能小于0") if @homework.anonymous_appeal && params[:appeal_penalty].to_i < 0 tip_exception("违规匿评扣分不能大于100") if @homework.anonymous_appeal && params[:appeal_penalty].to_i > 100 @homework_detail_manual.appeal_penalty = @homework.anonymous_appeal ? params[:appeal_penalty].to_i : 0 # 如果缺评扣分的设置有变更且匿评已截止 absence_penalty_change = current_absence_penalty != @homework_detail_manual.absence_penalty && @homework_detail_manual.comment_status >= 4 # 如果违规匿评扣分的设置有变更且匿评已截止 appeal_penalty_change = current_appeal_penalty != @homework_detail_manual.appeal_penalty && @homework_detail_manual.comment_status >= 4 # 评分设置 tip_exception("助教评分模式不能为空") if params[:ta_mode].blank? # 助教评分模式的变更 ta_mode_change = @homework_detail_manual.ta_mode != params[:ta_mode].to_i @homework_detail_manual.ta_mode = params[:ta_mode].to_i # 最终成绩组成 tip_exception("最终成绩组成模式不能为空") if params[:final_mode].nil? final_mode_change = @homework_detail_manual.final_mode != params[:final_mode] @homework_detail_manual.final_mode = params[:final_mode] if !@homework_detail_manual.final_mode tip_exception("教师评分比例不能为空") if params[:te_proportion].blank? te_proportion = params[:te_proportion].to_f.round(2) tip_exception("教师评分比例不能小于0") if te_proportion < 0 tip_exception("助教评分比例不能为空") if params[:ta_proportion].blank? ta_proportion = params[:ta_proportion].to_f.round(2) tip_exception("助教评分比例不能小于0") if ta_proportion < 0 if !@homework.anonymous_comment tip_exception("评分比例之和不能大于100") if (te_proportion + ta_proportion) > 1.0 else tip_exception("学生评分比例不能为空") if params[:st_proportion].blank? st_proportion = params[:st_proportion].to_f.round(2) tip_exception("学生评分比例不能小于0") if st_proportion < 0 tip_exception("评分比例之和不能大于100") if (te_proportion + ta_proportion + st_proportion) > 1.0 end proportion_change = @homework_detail_manual.te_proportion.round(2) != te_proportion || @homework_detail_manual.ta_proportion.round(2) != ta_proportion @homework_detail_manual.te_proportion = te_proportion @homework_detail_manual.ta_proportion = ta_proportion else @homework_detail_manual.te_proportion = 1 @homework_detail_manual.ta_proportion = 0 end # 公开属性设置 tip_exception("缺少work_public参数") if params[:work_public].nil? tip_exception("缺少score_open参数") if params[:score_open].nil? tip_exception("缺少answer_public参数") if params[:answer_public].nil? @homework.work_public = params[:work_public] @homework.score_open = params[:score_open] @homework.answer_public = params[:answer_public] @homework_detail_manual.save! @homework.save! # 迟交扣分、缺评扣分、违规匿评扣分、助教评分模式变更、最终成绩组成、评分比例变更都需要更新学生成绩 if late_penalty_change || absence_penalty_change || appeal_penalty_change || ta_mode_change || final_mode_change || proportion_change student_works = @homework.student_works.has_committed work_ids = student_works.pluck(:id) student_works.each do |student_work| # 迟交扣分 student_work.late_penalty = student_work.work_status == 1 ? 0 : @homework.late_penalty # 缺评扣分的更新 如果之前的作业缺评扣分为0,则需重新计算缺评次数 if absence_penalty_change absence_penalty_count = current_absence_penalty == 0 ? student_work.absence_count : (student_work.absence_penalty / current_absence_penalty).to_i student_work.absence_penalty = absence_penalty_count * @homework_detail_manual.absence_penalty end # 违规匿评扣分 如果之前的作业违规扣分为0,则需重新计算违规匿评次数 if appeal_penalty_change appeal_penalty_count = current_appeal_penalty == 0 ? student_work.appeal_count : (student_work.appeal_penalty / current_appeal_penalty).to_i student_work.appeal_penalty = appeal_penalty_count * @homework_detail_manual.appeal_penalty end # 助教模式变更且有助教评分记录时才更新 if ta_mode_change && student_work.student_works_scores.where("reviewer_role = 2 AND score IS NOT NULL").count > 0 student_work.teaching_asistant_score = student_work.ta_score @homework_detail_manual.ta_mode end student_work.save! end end end HomeworkCommonPushNotifyJob.perform_later(@homework.id, publish_group_ids) if send_tiding normal_status(0, "更新成功") else tip_exception("课堂已结束不能再更新") end rescue Exception => e uid_logger(e.backtrace) tip_exception(e.message) raise ActiveRecord::Rollback end end # 选用实训 def shixuns @main_catrgory = @course.course_modules.where(module_type: "shixun_homework") @homework_category = @main_catrgory.take.course_second_categories search = params[:search] type = params[:type] # 超级管理员用户显示所有未隐藏的实训、非管理员显示所有已发布的实训(对本单位公开且未隐藏未关闭) if current_user.admin? @shixuns = Shixun.unhidden else none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id) @shixuns = Shixun.where.not(id: none_shixun_ids).unhidden end # 实训的所有标签 @tags = TagRepertoire.select([:id, :name]).joins(:shixuns).where(shixuns: {id: @shixuns}).distinct if params[:search] && params[:search].strip != "" @shixuns = @shixuns.joins(:user).where("shixuns.name like ? or concat(users.lastname, users.firstname) like ?", "%#{search}%", "%#{search}%").distinct end unless type.blank? || type == "all" @shixuns = @shixuns.joins(:shixun_tag_repertoires).where(shixun_tag_repertoires: {tag_repertoire_id: type}).distinct end @shixuns = @shixuns.select([:id, :name, :status, :myshixuns_count, :identifier, :user_id, :trainee]) @total_count = @shixuns.size ## 分页参数 page = params[:page] || 1 @shixuns = @shixuns.reorder("shixuns.created_at desc").includes(:challenges, user: [user_extension: :school]).page(page).per(10) # 新版用下面的代码 # ## 我的实训 # @shixuns = # if params[:order_by] == 'mine' # current_user.my_shixuns.unhidden # else # if current_user.admin? # Shixun.unhidden # else # none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id) # # @shixuns = Shixun.where.not(id: none_shixun_ids).unhidden # end # end # # ## 方向 # if params[:tag_level].present? && params[:tag_id].present? # @shixuns = @shixuns.filter_tag(params[:tag_level].to_i, params[:tag_id].to_i) # case params[:tag_level].to_i # when 1 #大类 # @search_tags = Repertoire.find(params[:tag_id].to_i).name # when 2 #子类 # @search_tags = SubRepertoire.find(params[:tag_id].to_i).name # when 3 #tag # tag = TagRepertoire.find(params[:tag_id].to_i) # @search_tags = "#{tag.sub_repertoire.name} / #{tag.name}" # end # end # # ## 搜索关键字创建者、实训名称、院校名称 # if params[:keyword].present? # keyword = params[:keyword].strip # @shixuns = @shixuns.joins(user: [user_extenison: :school]). # where("schools.name like '%#{keyword}%' # or concat(lastname, firstname) like '%#{keyword}%' # or shixuns.name like '%#{keyword.split(" ").join("%")}%'").distinct # end # # ## 筛选 难度 # if params[:diff].present? && params[:diff].to_i != 0 # @shixuns = @shixuns.where(trainee: params[:diff]) # end # # ## 排序参数 # bsort = params[:sort] || 'desc' # case params[:order_by] || 'hot' # when 'hot' # @shixuns = @shixuns.order("myshixuns_count #{bsort}") # when 'mine' # @shixuns = @shixuns.order("shixuns.created_at #{bsort}") # else # @shixuns = @shixuns.order("myshixuns_count #{bsort}") # end # # @total_count = @shixuns.count # # ## 分页参数 # page = params[:page] || 1 # limit = params[:limit] || 15 # # @shixuns = @shixuns.includes(:challenges, user: [user_extension: :school]).page(page).per(limit) # end def create_shixun_homework tip_exception("请至少选择一个实训") if params[:shixun_ids].blank? shixuns = Shixun.where(id: params[:shixun_ids]).reorder("id desc") @homework_ids = [] unless params[:category_id].blank? @category = @course.course_second_categories.find_by(id: params[:category_id], category_type: "shixun_homework") end ActiveRecord::Base.transaction do begin shixuns.each do |shixun| homework = HomeworksService.new.create_homework shixun, @course, @category, current_user @homework_ids << homework.id end rescue Exception => e uid_logger(e.message) tip_exception("创建失败") raise ActiveRecord::Rollback end end end # 选用实训课程 def subjects @tags = Repertoire.where(nil).order("updated_at desc") # select = params[:select] # 路径导航类型 select = params[:type] # 路径导航类型 reorder = params[:order] || "myshixun_count" sort = params[:sort] || "desc" search = params[:search] ## 分页参数 page = params[:page] || 1 limit = params[:limit] || 15 offset = (page.to_i-1) * limit # 最热排序 if reorder == "myshixun_count" if select && select != "all" @subjects = Subject.find_by_sql("SELECT subjects.id, subjects.user_id, subjects.name, subjects.stages_count, subjects.repertoire_id, subjects.status, subjects.shixuns_count, sum(shixuns.myshixuns_count) AS myshixun_member_count FROM subjects join stage_shixuns on stage_shixuns.subject_id = subjects.id join shixuns on shixuns.id = stage_shixuns.shixun_id where subjects.hidden = 0 AND subjects.status = 2 AND subjects.name like '%#{search}%' AND subjects.repertoire_id = #{select} GROUP BY subjects.id ORDER BY myshixun_member_count #{sort}") else @subjects = Subject.find_by_sql("SELECT subjects.id, subjects.user_id, subjects.name, subjects.stages_count, subjects.repertoire_id, subjects.status, subjects.shixuns_count, sum(shixuns.myshixuns_count) AS myshixun_member_count FROM subjects join stage_shixuns on stage_shixuns.subject_id = subjects.id join shixuns on shixuns.id = stage_shixuns.shixun_id where subjects.hidden = 0 AND subjects.status = 2 AND subjects.name like '%#{search}%' GROUP BY subjects.id ORDER BY myshixun_member_count #{sort}") end else # 我的路径 if reorder == "mine" mine_subject_id = StageShixun.find_by_sql("select DISTINCT(subject_id) from stage_shixuns where shixun_id in (select distinct(shixun_id) from myshixuns where user_id=#{current_user.id})").map(&:subject_id) manage_subject_id = SubjectMember.where(user_id: current_user.id).pluck(:subject_id) total_subject_id = (mine_subject_id + manage_subject_id).uniq @subjects = Subject.where(id: total_subject_id) end # 类型 if select && select != "all" @subjects = @subjects.where(repertoire_id: select) end if search.present? @subjects = @subjects.where("name like ?", "%#{search}%") end # 排序 order_str = "updated_at #{sort}" @subjects = @subjects.reorder(order_str) end @total_count = @subjects.size if reorder != "myshixun_count" @subjects = @subjects.page(page).per(limit).includes(:shixuns, user: [user_extension: :school]) else @subjects = @subjects[offset, limit] unless @subjects.blank? subject_ids = @subjects.pluck(:id) order_ids = subject_ids.size > 0 ? subject_ids.join(',') : -1 @subjects = Subject.where(id: subject_ids).order("field(id,#{order_ids})").includes(:shixuns, user: [user_extension: :school]) end end end def create_subject_homework tip_exception("请至少选择一个实训课程") if params[:subject_ids].blank? subjects = Subject.where(id: params[:subject_ids], status: 2).includes(stages: :shixuns).reorder("id desc") @homework_ids = [] none_shixun_ids = ShixunSchool.where("school_id != #{current_user.school_id}").pluck(:shixun_id) course_module = @course.course_modules.find_by(module_type: "shixun_homework") ActiveRecord::Base.transaction do begin subjects.each do |subject| subject.stages.each do |stage| # 为实训作业创建与stage同名的子目录 category = CourseSecondCategory.find_by(name: stage.name, course_id: @course.id, category_type: "shixun_homework") || CourseSecondCategory.create!(name: stage.name, course_id: @course.id, category_type: "shixun_homework", course_module_id: course_module.id, position: course_module.course_second_categories.count + 1) # 去掉不对当前用户的单位公开的实训,已发布的实训 stage.shixuns.where.not(shixuns: {id: none_shixun_ids}).unhidden.each do |shixun| homework = HomeworksService.new.create_homework shixun, @course, category, current_user @homework_ids << homework.id end end end rescue Exception => e uid_logger(e.message) tip_exception("创建失败") raise ActiveRecord::Rollback end end end def publish_groups @current_user = current_user if @homework.publish_immediately @current_user # 可立即发布的分班:当前用户管理的分班去除已发布的分班 group_ids = @course.charge_group_ids(@current_user) - @homework.homework_group_settings.group_published.pluck(:course_group_id) @course_groups = @course.course_groups.where(id: group_ids) else tip_exception("没有可发布的分班") end end def publish_homework tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0 tip_exception("缺少截止时间参数") if params[:end_time].blank? tip_exception("截止时间不能早于当前时间") if params[:end_time] <= strf_time(Time.now) tip_exception("截止时间不能晚于课堂结束时间") if @course.end_date.present? && params[:end_time] > strf_time(@course.end_date.end_of_day) homeworks = @course.homework_commons.where(id: params[:homework_ids]) homeworks = homeworks.includes(:homework_group_settings, :homework_detail_manual) charge_group_ids = @course.charge_group_ids(current_user) publish_groups = charge_group_ids & params[:group_ids] if params[:group_ids] ActiveRecord::Base.transaction do begin homeworks.each do |homework| # 作业未发布时 if homework.homework_detail_manual.try(:comment_status) == 0 if !params[:group_ids].blank? # 全选即统一设置,unified_setting为true if @course.course_groups.where(id: publish_groups).size == @course.course_groups.size homework.homework_group_settings.destroy_all homework.unified_setting = true homework.end_time = params[:end_time] else homework.unified_setting = false # 创建作业分班设置:homework_group_setting create_homework_group_settings(homework) # 选中的分班设置的发布时间改为当前时间,截止时间改为传的截止时间参数 homework.homework_group_settings.where(course_group_id: publish_groups).update_all(publish_time: Time.now, end_time: params[:end_time]) # 发消息 tiding_group_ids = publish_groups end else homework.homework_group_settings.destroy_all # students = @course.students end homework.publish_time = Time.now # 截止时间的处理 if homework.end_time.nil? homework.end_time = params[:end_time] elsif homework.max_group_end_time homework.end_time = homework.max_group_end_time end homework.homework_detail_manual.update_attribute('comment_status', 1) if homework.course_acts.size == 0 homework.course_acts << CourseActivity.new(user_id: homework.user_id, course_id: homework.course_id) end # 发消息 HomeworkCommonPushNotifyJob.perform_later(homework.id, tiding_group_ids) else create_homework_group_settings(homework) none_publish_settings = homework.homework_group_settings.where(course_group_id: publish_groups).none_published none_publish_settings.update_all(publish_time: Time.now, end_time: params[:end_time]) if homework.max_group_end_time homework.end_time = homework.max_group_end_time end HomeworkCommonPushNotifyJob.perform_later(homework.id, none_publish_settings.pluck(:course_group_id)) end if homework.end_time > Time.now && homework.homework_detail_manual.try(:comment_status) > 1 homework.homework_detail_manual.update_attribute("comment_status", 1) end # 补交结束时间 homework.late_time = Time.at(homework.end_time.to_i + 30*24*3600) if homework.allow_late && homework.late_time.nil? homework.save! # 更新学生状态及成绩(手动点击计算) # HomeworkPublishUpdateWorkStatusJob.perform_later(tiding_group_ids, homework.id) end normal_status(0, "发布成功") rescue Exception => e uid_logger(e.message) tip_exception("发布失败") raise ActiveRecord::Rollback end end end def end_groups @current_user = current_user if @homework.end_immediately @current_user # 可立即截止的分班:统一设置则是用户管理的所有分班,否则是当前用户管理的分班中已发布且未截止的 charge_group_ids = @course.charge_group_ids(@current_user) # 当前用户管理的分班 group_ids = @homework.unified_setting ? charge_group_ids : @homework.homework_group_settings.where(course_group_id: charge_group_ids).none_end.pluck(:course_group_id) @course_groups = @course.course_groups.where(id: group_ids) else tip_exception("没有可截止的分班") end end def end_homework tip_exception("请至少选择一个分班") if params[:group_ids].blank? && @course.course_groups.size != 0 time = Time.now.strftime("%Y-%m-%d %H:%M:%S") # 已发布且未截止的作业才能立即截止 homeworks = @course.homework_commons.where(id: params[:homework_ids]) homeworks = homeworks.published_no_end.includes(:homework_group_settings, :homework_detail_manual, :homework_challenge_settings) course_students = @course.students charge_group_ids = @course.charge_group_ids(current_user) end_groups = charge_group_ids & params[:group_ids] if params[:group_ids] ActiveRecord::Base.transaction do begin homeworks.each do |homework| homework_detail_manual = homework.homework_detail_manual # 分组设置 if !params[:group_ids].blank? # 确保之前是统一设置或者有新创建的分班的数据一致性 create_homework_group_settings(homework) homework.unified_setting = false if homework.unified_setting && end_groups.length != @course.course_groups_count # 已发布且未截止的分班 none_end_settings = homework.homework_group_settings.where(course_group_id: end_groups).published_no_end none_end_settings.update_all(end_time: time) student_works = homework.student_works.where(user_id: course_students.where(course_group_id: none_end_settings. pluck(:course_group_id)).pluck(:user_id)).has_committed if homework.homework_type == "practice" homework.end_time = homework.max_group_end_time if homework.end_time > time && homework_detail_manual.try(:comment_status) > 1 homework_detail_manual.update_attribute("comment_status", 1) end # 统一设置 elsif homework.unified_setting student_works = homework.student_works.has_committed if homework.homework_type == "practice" homework.end_time = time end homework_detail_manual.update_attribute("comment_status", 2) if homework.end_time <= time # 实训作业的作品需要计算是否迟交 if homework.homework_type == "practice" # shixun = homework.shixuns.first # homework_challenge_settings = homework.homework_challenge_settings unless student_works.blank? student_works.joins(:myshixun).where("myshixuns.status != 1").update_all(late_penalty: homework.late_penalty) if homework.allow_late =begin student_works.where("work_status != 0").includes(:myshixun).each do |student_work| unless student_work.myshixun.is_complete? student_work.update_attributes(work_status: 2, late_penalty: homework.late_penalty) student_work.late_penalty = homework.late_penalty end HomeworksService.new.set_shixun_final_score student_work, student_work.myshixun, homework_detail_manual.answer_open_evaluation, homework_challenge_settings end student_works.where("work_status = 0").each do |student_work| myshixun = Myshixun.where(shixun_id: shixun.id, user_id: student_work.user_id).first if myshixun.present? student_work.update_attributes(work_status: (myshixun.is_complete? ? 1 : 2), late_penalty: myshixun.is_complete? ? 0 : homework.late_penalty, commit_time: myshixun.created_at, myshixun_id: myshixun.id) student_work.late_penalty = myshixun.is_complete? ? 0 : homework.late_penalty HomeworksService.new.set_shixun_final_score student_work, myshixun, homework_detail_manual.answer_open_evaluation, homework_challenge_settings end end =end # 更新所有学生的效率分(重新取homework确保是更新后的) HomeworkEndUpdateScoreJob.perform_later(homework.id) if !homework.allow_late && homework.end_time <= time end end homework.save! end normal_status(0, "更新成功") rescue Exception => e uid_logger(e.message) tip_exception("操作失败") raise ActiveRecord::Rollback end end end def set_public tip_exception("仅公开课堂才能公开作业") if @course.is_public == 0 homeworks = @course.homework_commons.where(id: params[:homework_ids]) homeworks.update_all(is_public: 1) normal_status(0, "更新成功") end def choose_category @main_catrgory = @course.course_modules.where(module_type: "shixun_homework") @homework_category = @main_catrgory.take.course_second_categories end # 实训作业移动到目录 def move_to_category tip_exception("请选择要移动的目录") if params[:new_category_id].blank? category = @course.course_second_categories.find_by(id: params[:new_category_id]) if params[:new_category_id].to_i == 0 || category.present? homeworks = @course.homework_commons.where(id: params[:homework_ids]) homeworks.update_all(course_second_category_id: params[:new_category_id]) normal_status(0, "更新成功") else normal_status(-1, "目录不存在") end end # 删除多个作业 def multi_destroy ActiveRecord::Base.transaction do begin homeworks = @course.homework_commons.where(id: params[:homework_ids]) homeworks.destroy_all # 这些写是因为model中的关联删除无法删除is_delete=0的作品 StudentWork.where(homework_common_id: homeworks.pluck(:id)).destroy_all normal_status(0, "删除成功") rescue Exception => e uid_logger(e.message) tip_exception("删除失败") raise ActiveRecord::Rollback end end end #加入到题库 def add_to_homework_bank homeworks = @course.homework_commons.where(id: params[:homework_ids]) homeworks.each do |homework| ActiveRecord::Base.transaction do begin homework_bank = current_user.homework_banks.find_by(homework_common_id: homework.id) if homework_bank.present? # 如果作业加入过题库则更新参数 if homework_bank.homework_type == 1 homework_bank.update_attributes(name: homework.name, description: homework.description, reference_answer: homework.reference_answer, course_list_id: @course.course_list_id) elsif homework_bank.homework_type == 3 homework_detail_group = homework.homework_detail_group homework_bank.update_attributes(name: homework.name, description: homework.description, reference_answer: homework.reference_answer, course_list_id: @course.course_list_id, min_num: homework_detail_group.min_num, max_num: homework_detail_group.max_num, base_on_project: homework_detail_group.base_on_project) end # 附件的更新 homework_bank.attachments.destroy_all homework.attachments.each do |attachment| att = attachment.copy att.author_id = homework_bank.user_id att.copy_from = attachment.id homework_bank.attachments << att end else new_homework_bank = add_to_homework_bank_f homework new_homework_bank.save! end rescue Exception => e uid_logger(e.message) tip_exception("删除失败") raise ActiveRecord::Rollback end end end normal_status(0, "加入成功") end # 代码查重分班列表 def group_list @page = params[:page] || 1 @limit = params[:limit] || 10 @course_groups = @course.course_groups.page(@page).per(@limit) @ungroup_user_ids = @course.course_members.ungroup_students.pluck(:user_id) end # 班级作品查重 def homework_code_repeat tip_exception(-1,"分班id不能为空!") if params[:group_ids].nil? shixun = @homework.shixuns.take # 通过代码文件来判断语言 language = shixun.challenges.practice_type.pluck(:path).first language = language.split(";")[0].split(".")[1].downcase if language.present? user_lists = [] if language.present? && (language == "java" || language == "py") user_ids = @course.course_members.where(course_group_id: params[:group_ids]).distinct(:user_id).pluck(:user_id) challenge_ids = @homework.homework_challenge_settings.pluck(:challenge_id) challenge_ids = challenge_ids.size == 0 ? "(-1)" : "(#{challenge_ids.join(",")})" user_ids.each do |user_id| code_infos = [] games = Game.find_by_sql("select games.* from games right join myshixuns ms on games.myshixun_id = ms.id where games.user_id = #{user_id} and games.status = 2 and ms.shixun_id = #{shixun.id} and games.challenge_id in #{challenge_ids}") games.each do |game| game.game_codes.each do |game_code| code_infos << { path: game_code.path, content: Base64.urlsafe_encode64(game_code.new_code.to_s, padding: false), passed_time: game.end_time.try(:strftime, '%Y-%m-%d %H:%M:%S') } end end if code_infos.size != 0 user_lists << { user_id: user_id, code_info: code_infos } end end result = ReviewService.check(user_lists, language == "py" ? "python" : "java") if result.status == 0 params[:group_ids].each do |group_id| @homework.homework_group_reviews << HomeworkGroupReview.new(:course_group_id => group_id, :user_id => current_user.id, :query_id => result.query_id) end normal_status("代码查重成功") else if result.status == 1 tip_exception(-4,"代码查重异常,请稍后重试") else tip_exception(-3,"正在查重,请在几分钟后刷新页面查看结果") end end else tip_exception(-2,"平台目前支持java、python语言的查重
其他语言正在规划中,敬请期待") end end # 代码查重届结果 def code_review_results # 如果有未获取结果的查重操作 则先读取结果 get_new_code_reviews_result @homework @current_user = current_user # 列表数据 rorder = params[:order] || "code_rate" sort = params[:sort] || "desc" page = params[:page] || 1 limit = params[:limit] || 15 student_works = @homework.student_works.where("work_status > 0") # 按分班id搜索 user_ids = if params[:group_ids] # 筛选了分班 group_student_ids = @course.course_members.where(course_group_id: params[:group_ids]).pluck(:user_id) student_works.where(:user_id => group_student_ids).pluck(:user_id) else # 如果当前用户有分班 显示分班内的学生,没有则显示全部 user_ids = @course.user_group_students(current_user.id).pluck(:user_id) if user_ids.present? student_works.where(:user_id => user_ids).pluck(:user_id) else student_works.pluck(:user_id) end end # 查询作品数总数 @all_reviews_count = user_ids.count @users_reviews = @homework.homework_review_results.where("code_rate >= 50.0") .where(:user_id => user_ids).joins(user: :user_extension) # 按学号和姓名搜索 if params[:search] @users_reviews = @users_reviews.where("concat(lastname, firstname) like :keyword or student_id like :keyword", keyword: "%#{params[:search]}%") end # 抄袭作品数 @copy_reviews_count = @users_reviews.count # 排序搜索 @users_reviews = @users_reviews.order("#{rorder} #{sort}").page(page).per(limit) # 获取所有查重过的分班 @course_groups = @course.course_groups.where(id: @homework.homework_group_reviews.pluck(:course_group_id).uniq) # 如果未分班被查重过,则显示未分班列 @non_course_group = if @homework.homework_group_reviews.where(course_group_id: 0).count > 0 @course.course_members.where(role: 4, course_group_id: 0).count end # 最新一次的查重时间 @last_review_time = format_time @homework.homework_group_reviews.last.try(:created_at) end # 代码查重代码的详情 def code_review_detail @student_work = @homework.student_works.find_by(user_id: params[:user_id]) @user = @student_work.user tip_exception("当前用户无作品可以显示") if @student_work.nil? # 查询最新一次的查重标识query_id group_id = @course.course_members.where(user_id: params[:user_id]).pluck(:course_group_id).first query_id = @homework.homework_group_reviews.where(:course_group_id => group_id).last.try(:query_id) results = ReviewService.query_result({user_id: params[:user_id], query_id: query_id}) @shixun = @homework.shixuns.take if results.status == 0 code_info = results.code_info homework_challenge_settings = @homework.homework_challenge_settings @challenges = @shixun.challenges.where(id: homework_challenge_settings.pluck(:challenge_id), st: 0) @challenges = @challenges.map do |challenge| code_rate = 0 game_codes = results.code_info.select {|info| challenge.path.split(";").include?(info.origin_path)} # 先判断用户该关卡是否查重了 取多个待补充文件的平均值 if game_codes.count > 0 code_rate += game_codes.map(&:rate).sum / challenge.path.split(";").length end target = game_codes.count > 0 ? game_codes[0].target_user_id : nil # 作品完成时间 game = challenge.games.find_by(user_id: @user.id) end_time = game.end_time # 用户关卡的得分 all_score = homework_challenge_settings.find_by(challenge_id: challenge.id).try(:score).to_f final_score = @student_work.work_challenge_score game, all_score # 抄袭用户 copy_user = User.find_by_id(game_codes[0].target_user_id) copy_end_time = copy_user.games.find_by(challenge_id: challenge.id).try(:end_time) if copy_user.present? # 代码部分 code_list = [] challenge.path.split(";").each do |path| if code_info.select{|info| path == info.origin_path}.size > 0 info = code_info.select{|info| path == info.origin_path}[0] code_list << {path: path, origin_content: info.origin_content, target_content: info.target_content} end end {code_rate: code_rate, copy_user_id: copy_user.try(:id), end_time: end_time, final_score: final_score, all_score: all_score, copy_end_time: copy_end_time, copy_username: copy_user.try(:full_name), username: game.user.full_name, code_list: code_list, subject: challenge.subject, position: challenge.position, id: challenge.id} end else if results.status == 1 tip_exception(-1, "代码查重异常,请稍后重试") else tip_exception(-2, "代码查重正在执行中,请稍后") end end end private def find_homework begin @homework = HomeworkCommon.find(params[:id]) @course = @homework.course @homework_detail_manual = @homework.homework_detail_manual rescue Exception => e uid_logger(e.message) tip_exception("id不存在") end end def homework_params tip_exception("name参数不能为空") if params[:name].blank? tip_exception("description参数不能为空") if params[:description].blank? params.require(:homework_common).permit(:name, :description, :reference_answer) end def require_id_params tip_exception("请至少选择一个作业") if params[:homework_ids].blank? tip_exception("批量设置不能超过15个") if params[:homework_ids].length > 15 end def validate_min_max_num tip_exception("min_num参数不能为空") if params[:min_num].blank? tip_exception("max_num参数不能为空") if params[:max_num].blank? tip_exception("最小人数不能小于1") if params[:min_num].to_i < 1 tip_exception("最大人数不能小于最小人数") if params[:max_num].to_i < params[:min_num].to_i end def validate_absence_penalty end def create_homework_group_settings homework if homework.homework_group_settings.size != @course.course_groups.size @course.course_groups.where.not(id: homework.homework_group_settings.pluck(:course_group_id)).each do |group| homework.homework_group_settings << HomeworkGroupSetting.new(course_group_id: group.id, course_id: @course.id, publish_time: homework.publish_time, end_time: homework.end_time) end end end def get_new_code_reviews_result homework if homework.code_reviews_new_results? # 获取最新的查询id query_id = homework.homework_group_reviews.where(status: 0).last.try(:query_id) results = ReviewService.query_result({query_id: query_id}) if results.status == 0 shixun = homework.shixuns.take challenges = shixun.challenges.where(id: homework.homework_challenge_settings.pluck(:challenge_id), st: 0) challenge_count = challenges.count Rails.logger.info("#####results_user_list: #{results.user_lists.to_json}") results.user_lists.map(&:user_id).uniq.each do |user| user_rate = 0 # 计算每个关卡的相似度 challenges.each do |challenge| game_codes = results.user_lists.select{|user_list| user_list.user_id == user && challenge.path.split(";").include?(user_list.origin_path)} # 先判断用户该关卡是否查重了 取多个待补充文件的平均值 if game_codes.count > 0 user_rate += game_codes.map(&:rate).sum / challenge.path.split(";").length end end user_rate = challenge_count == 0 ? 0 : user_rate / challenge_count # 如果用户已有查重记录则更新相似度 否则新建一条记录 user_review = homework.homework_review_results.find_by(:user_id => user) if user_review.present? user_review.update_attributes(:code_rate => user_rate) else homework.homework_review_results.create(:user_id => user, :code_rate => user_rate) end end nuser_ids = results.user_lists.map(&:user_id).uniq homework.homework_review_results.where.not(user_id: nuser_ids).destroy_all homework.homework_group_reviews.where(status: 0).update_all(status: 1) elsif results.status == 2 tip_exception(-2, "代码查重正在执行中,请稍后") else tip_exception(-1, "代码查重异常,请稍后重试") end end end def add_to_homework_bank_f homework homework_bank = HomeworkBank.new(name: homework.name, description: homework.description, user_id: current_user.id, homework_type: homework.homework_type == "normal" ? 1 : 3, quotes: 1, is_public: 0, homework_common_id: homework.id, reference_answer: homework.reference_answer, course_list_id: @course.course_list_id) if homework.homework_type == "group" && homework.homework_detail_group homework_bank.min_num = homework.homework_detail_group.min_num homework_bank.max_num = homework.homework_detail_group.max_num homework_bank.base_on_project = homework.homework_detail_group.base_on_project end homework.attachments.each do |attachment| att = attachment.copy att.author_id = homework_bank.user_id att.copy_from = attachment.id att.attachtype = attachment.attachtype || 1 homework_bank.attachments << att end homework_bank end end