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.
educoder/app/controllers/homework_commons_controller.rb

1609 lines
77 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 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.where(course_second_category_id: 0)
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 @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,"暂无用户提交!")
else
respond_to do |format|
format.xlsx{
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.first(30)}",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
respond_to do |format|
format.zip{
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
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语言的查重<br/>其他语言正在规划中,敬请期待")
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