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.
301 lines
12 KiB
301 lines
12 KiB
class Competitions::CompetitionsController < Competitions::BaseController
|
|
include CompetitionsHelper
|
|
|
|
skip_before_action :require_login
|
|
before_action :allow_visit, except: [:index]
|
|
before_action :require_admin, only: [:update, :update_inform]
|
|
before_action :chart_visible, only: [:charts, :chart_rules]
|
|
before_action :check_manager_permission!, only: [:update_md_content]
|
|
|
|
def index
|
|
# 已上架 或者 即将上架
|
|
competitions = current_laboratory.competitions
|
|
competitions = competitions.where(status: true).or(competitions.where.not(published_at: nil))
|
|
|
|
competitions =
|
|
case params[:category]
|
|
when 'nearly_published' then competitions.where(status: false)
|
|
when 'progressing' then competitions.where('status = 1 and end_time > NOW()')
|
|
when 'ended' then competitions.where('end_time < NOW()')
|
|
else competitions
|
|
end
|
|
|
|
@count = competitions.count
|
|
|
|
competitions = competitions.order(published_at: :desc, online_time: :desc)
|
|
@competitions = paginate(competitions.includes(:competition_mode_setting, sponsor_schools: :school, current_stage_section: :competition_stage))
|
|
|
|
ids = @competitions.map(&:id)
|
|
@member_count_map = TeamMember.where(competition_id: ids).group(:competition_id).count
|
|
@stage_count_map = CompetitionStage.where(competition_id: ids).group(:competition_id).count
|
|
end
|
|
|
|
def show
|
|
@competition = current_competition
|
|
|
|
current_competition.increment!(:visits)
|
|
end
|
|
|
|
def update
|
|
@competition.update_attributes!(introduction: params[:introduction])
|
|
Attachment.associate_container(params[:attachment_ids], @competition.id, @competition.class) if params[:attachment_ids]
|
|
normal_status("更新成功")
|
|
end
|
|
|
|
def common_header
|
|
@competition = current_competition
|
|
@competition_modules = @competition.unhidden_competition_modules
|
|
|
|
# 未登录、未获奖用户,不展示获奖证书栏目
|
|
if !current_user.logged? || !current_competition.finished? || (!current_competition.competition_prize_users.exists?(user: current_user) && !current_user.admin_or_business?)
|
|
@competition_modules = @competition_modules.select { |mod| mod.name != '获奖证书' }
|
|
end
|
|
|
|
@user = current_user
|
|
|
|
current_competition.increment!(:visits)
|
|
end
|
|
|
|
def informs
|
|
status = params[:status] || 1
|
|
@informs = current_competition.informs.where(status: status)
|
|
end
|
|
|
|
def update_inform
|
|
tip_exception("标题和内容不能为空") if params[:name].blank? || params[:description].blank?
|
|
tip_exception("status参数有误") if params[:status].blank? || ![1, 2].include?(params[:status].to_i)
|
|
ActiveRecord::Base.transaction do
|
|
if params[:inform_id]
|
|
inform = current_competition.informs.find_by!(id: params[:inform_id])
|
|
inform.update_attributes!(name: params[:name], description: params[:description])
|
|
else
|
|
inform = current_competition.informs.create!(name: params[:name], description: params[:description], status: params[:status])
|
|
end
|
|
Attachment.associate_container(params[:attachment_ids], inform.id, inform.class) if params[:attachment_ids]
|
|
normal_status("更新成功")
|
|
end
|
|
end
|
|
|
|
def md_content
|
|
@md_content = CompetitionModuleMdContent.find_by!(id: params[:md_content_id])
|
|
end
|
|
|
|
def update_md_content
|
|
tip_exception("内容不能为空") if params[:content].blank?
|
|
tip_exception("缺少competition_module_id") if params[:competition_module_id].blank?
|
|
ActiveRecord::Base.transaction do
|
|
com_module = current_competition.competition_modules.find_by!(id: params[:competition_module_id])
|
|
if params[:md_content_id]
|
|
md_content = CompetitionModuleMdContent.find_by!(id: params[:md_content_id], competition_module_id: com_module.id)
|
|
md_content.update_attributes!(name: params[:name], content: params[:content])
|
|
else
|
|
stage = current_competition.competition_stages.find_by(id: params[:stage_id]) if params[:stage_id]
|
|
md_content = CompetitionModuleMdContent.create!(name: params[:name], content: params[:content], competition_module_id: com_module.id, competition_stage_id: stage&.id.to_i)
|
|
end
|
|
Attachment.associate_container(params[:attachment_ids], md_content.id, md_content.class) if params[:attachment_ids]
|
|
normal_status("更新成功")
|
|
end
|
|
end
|
|
|
|
def chart_rules
|
|
@competition = current_competition
|
|
com_module = @competition.competition_modules.find_by(module_type: "chart")
|
|
@rule_contents = com_module&.competition_module_md_contents
|
|
end
|
|
|
|
def update_chart_rules
|
|
tip_exception("内容不能为空") if params[:content].blank?
|
|
@competition = current_competition
|
|
@stage = @competition.competition_stages.find_by!(id: params[:stage_id]) if params[:stage_id]
|
|
chart_rule = @competition.chart_rules.where(competition_stage_id: @stage&.id).first
|
|
if chart_rule
|
|
chart_rule.update_attributes!(content: params[:content])
|
|
else
|
|
@competition.chart_rules.create!(competition_stage_id: @stage&.id, content: params[:content])
|
|
end
|
|
normal_status("更新成功")
|
|
end
|
|
|
|
def charts
|
|
@competition = current_competition
|
|
if params[:stage_id]
|
|
@stage = @competition.competition_stages.find_by(id: params[:stage_id])
|
|
elsif @competition.competition_stages.count == 1
|
|
@stage = @competition.competition_stages.take
|
|
end
|
|
|
|
@all_records = @competition.competition_teams.joins(:competition_scores).where(competition_scores: {competition_stage_id: @stage&.id.to_i})
|
|
.select("competition_teams.*, score, cost_time").order("score desc, cost_time asc")
|
|
|
|
current_team_ids = @competition.team_members.where(user_id: current_user.id).pluck(:competition_team_id).uniq
|
|
@user_ranks = @all_records.select{|com_team| current_team_ids.include?(com_team.id)}
|
|
@records = @all_records.where("score > 0")
|
|
@record_ids = @records.pluck(:id)
|
|
if params[:format] == "xlsx"
|
|
@records = @records.includes(user: [user_extension: :school], team_members: :user)
|
|
respond_to do |format|
|
|
format.xlsx{
|
|
set_export_cookies
|
|
chart_to_xlsx(@all_records, @competition)
|
|
exercise_export_name = "#{@competition.name}比赛成绩"
|
|
render xlsx: "#{exercise_export_name.strip}",template: "competitions/competitions/chart_list.xlsx.axlsx",locals:
|
|
{table_columns: @competition_head_cells, chart_lists: @competition_cells_column}
|
|
}
|
|
end
|
|
else
|
|
@records = @records.includes(:team_members, competition_prize_users: :competition_prize, user: :user_extension).limit(@competition.charts_count)
|
|
end
|
|
end
|
|
|
|
def export_extra_course_statistics
|
|
@competition = current_competition
|
|
@all_records = @competition.competition_teams.joins(:competition_scores, user: [user_extension: :school])
|
|
.select("competition_teams.*, competition_scores.score, cost_time").order("score desc, cost_time desc")
|
|
|
|
respond_to do |format|
|
|
format.xlsx{
|
|
extra_chart_to_xlsx(@all_records)
|
|
exercise_export_name = "#{@competition.name}比赛成绩"
|
|
render xlsx: "#{exercise_export_name.strip}",template: "competitions/competitions/chart_list.xlsx.axlsx",locals:
|
|
{table_columns: @competition_head_cells, chart_lists: @competition_cells_column}
|
|
}
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def current_competition
|
|
@_current_competition ||= Competition.find_by!(identifier: params[:id])
|
|
end
|
|
|
|
def allow_visit
|
|
return if current_competition.published? || admin_or_business?
|
|
return if current_competition.manager?(current_user)
|
|
|
|
render_forbidden
|
|
end
|
|
|
|
def chart_visible
|
|
chart_module = current_competition.competition_modules.find_by(name: "排行榜")
|
|
render_forbidden unless (chart_module.present? && !chart_module.hidden) || admin_or_business?
|
|
end
|
|
|
|
def check_manager_permission!
|
|
return if current_user.admin_or_business?
|
|
return if current_competition.manager?(current_user)
|
|
|
|
render_forbidden
|
|
end
|
|
|
|
# 竞赛成绩导出
|
|
def chart_to_xlsx records, competition
|
|
@competition_head_cells = []
|
|
@competition_cells_column = []
|
|
|
|
personal = competition.personal?
|
|
if personal # 个人赛
|
|
@competition_head_cells = %w(序号 姓名 学校 学号)
|
|
else # 战队赛
|
|
@competition_head_cells = %w(序号 战队名 指导老师 队员 学校)
|
|
end
|
|
|
|
statistic_stages = competition.competition_stages.where("score_rate > 0")
|
|
statistic_stages.each do |stage|
|
|
@competition_head_cells += ["#{stage.name}得分", "#{stage.name}用时"]
|
|
end
|
|
@competition_head_cells += ["总得分", "总用时"] if statistic_stages.size > 1
|
|
competition_scores = competition.competition_scores
|
|
|
|
records.each_with_index do |record, index|
|
|
row_cells_column = []
|
|
row_cells_column << index + 1
|
|
record_user = record.user
|
|
if personal
|
|
row_cells_column << record_user.real_name
|
|
row_cells_column << record_user.school_name
|
|
row_cells_column << (record_user.student_id.present? ? (record_user.student_id.to_s + "\t") : "--")
|
|
else
|
|
row_cells_column << record.name
|
|
row_cells_column << record.teachers_name
|
|
row_cells_column << record.members_name
|
|
row_cells_column << chart_school_str(record.team_members.select{|member| !member.is_teacher}.pluck(:user_id))
|
|
end
|
|
|
|
statistic_stages.each do |stage|
|
|
stage_score = competition_scores.select{|score| score.competition_stage_id == stage.id && score.competition_team_id == record.id}.first
|
|
row_cells_column << stage_score&.score.to_f.round(2)
|
|
row_cells_column << com_spend_time(stage_score&.cost_time.to_i)
|
|
end
|
|
|
|
if statistic_stages.size > 1
|
|
row_cells_column << record&.score.to_f.round(2)
|
|
row_cells_column << com_spend_time(record&.cost_time.to_i)
|
|
end
|
|
|
|
@competition_cells_column.push(row_cells_column)
|
|
end
|
|
end
|
|
|
|
def extra_chart_to_xlsx records
|
|
@competition_head_cells = []
|
|
@competition_cells_column = []
|
|
|
|
@competition_head_cells = %w(序号 姓名 id 学校 实训数 学习人数 被fork发布的学习人数 实训有效作品数 实训应用值 课堂数 学生数量 发布的实训作业数 有效作品数 课堂应用值 总分)
|
|
|
|
records.each_with_index do |record, index|
|
|
row_cells_column = []
|
|
row_cells_column << index + 1
|
|
record_user = record.user
|
|
row_cells_column << record_user.real_name
|
|
row_cells_column << record_user.login
|
|
row_cells_column << record_user.school_name
|
|
|
|
total_score = 0
|
|
shixun_count = 0
|
|
shixun_member_count = 0
|
|
shixun_fork_member_count = 0
|
|
shixun_valid_count = 0
|
|
shixun_score = 0
|
|
shixun_records = record.competition_course_records.where(type: 'CompetitionCourseShixunRecord')
|
|
shixun_records.each do |shixun|
|
|
shixun_count += 1
|
|
shixun_member_count += shixun.snapshot['myshixuns_count'].to_i
|
|
shixun_fork_member_count += shixun.snapshot['forked_myshixun_count'].to_i
|
|
shixun_valid_count += shixun.snapshot['valid_myshixun_count'].to_i
|
|
shixun_score += shixun.score.to_i
|
|
end
|
|
|
|
row_cells_column << shixun_count
|
|
row_cells_column << shixun_member_count
|
|
row_cells_column << shixun_fork_member_count
|
|
row_cells_column << shixun_valid_count
|
|
row_cells_column << shixun_score
|
|
total_score += shixun_score
|
|
|
|
course_count = 0
|
|
course_member_count = 0
|
|
course_homework_count = 0
|
|
course_valid_count = 0
|
|
course_score = 0
|
|
course_records = record.competition_course_records.where(type: 'CompetitionCourseCourseRecord')
|
|
course_records.each do |course|
|
|
course_count += 1
|
|
course_member_count += course.snapshot['members_count'].to_i
|
|
course_homework_count += course.snapshot['shixun_homework_count'].to_i
|
|
course_valid_count += course.snapshot['valid_myshixun_count'].to_i
|
|
course_score += course.score.to_i
|
|
end
|
|
|
|
row_cells_column << course_count
|
|
row_cells_column << course_member_count
|
|
row_cells_column << course_homework_count
|
|
row_cells_column << course_valid_count
|
|
row_cells_column << course_score
|
|
|
|
total_score += course_score
|
|
row_cells_column << total_score
|
|
|
|
@competition_cells_column.push(row_cells_column)
|
|
end
|
|
end
|
|
end |