|
|
class Admins::CreateCompetitionPrizeUsersService < ApplicationService
|
|
|
attr_reader :competition
|
|
|
|
|
|
def initialize(competition)
|
|
|
@competition = competition
|
|
|
end
|
|
|
|
|
|
def call
|
|
|
raise Error, '竞赛还未结束' unless competition.finished?
|
|
|
raise Error, '请勿重复生成' if competition.competition_prize_users.exists?
|
|
|
raise Error, '请先设置奖项' if prizes.blank?
|
|
|
raise Error, '无获奖队伍' if prize_teams.blank?
|
|
|
|
|
|
ActiveRecord::Base.transaction do
|
|
|
columns = %i[competition_id competition_team_id competition_prize_id user_id
|
|
|
status rank leader created_at updated_at]
|
|
|
|
|
|
CompetitionPrizeUser.bulk_insert(*columns) do |worker|
|
|
|
prize_teams.each_with_index do |team, index|
|
|
|
rank = index + 1
|
|
|
prize = team_prize(rank) # 根据排名获取当前队伍奖项
|
|
|
|
|
|
team.team_members.each do |member|
|
|
|
attr = {
|
|
|
competition_id: competition.id,
|
|
|
competition_team_id: team.id,
|
|
|
competition_prize_id: prize.id,
|
|
|
user_id: member.user_id,
|
|
|
leader: member.creator?,
|
|
|
status: :pending,
|
|
|
rank: rank
|
|
|
}
|
|
|
|
|
|
worker.add(attr)
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
end
|
|
|
|
|
|
private
|
|
|
|
|
|
def prizes
|
|
|
@_prizes ||= competition.competition_prizes.order(id: :asc).to_a
|
|
|
end
|
|
|
|
|
|
def team_prize(rank)
|
|
|
current = 0
|
|
|
prizes.each do |prize|
|
|
|
return prize if rank > current && rank <= current + prize.num
|
|
|
|
|
|
current += prize.num
|
|
|
end
|
|
|
end
|
|
|
|
|
|
def prize_teams
|
|
|
@_prize_teams ||= begin
|
|
|
prize_num_total = prizes.sum(&:num)
|
|
|
|
|
|
# 只有一个阶段,则成绩为该阶段成绩,否则为stage ID为0的总成绩
|
|
|
stage_id = competition.competition_stages.count == 1 ? competition.competition_stages.first.id : 0
|
|
|
|
|
|
competition.competition_teams.joins(:competition_scores)
|
|
|
.where(competition_scores: { competition_stage_id: stage_id })
|
|
|
.order("competition_scores.score desc, competition_scores.cost_time desc")
|
|
|
.includes(:team_members)
|
|
|
.limit(prize_num_total)
|
|
|
end
|
|
|
end
|
|
|
end |