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