class Competition < ApplicationRecord belongs_to :laboratory, optional: true has_many :competition_modules, dependent: :destroy has_many :unhidden_competition_modules, -> { where(hidden: false) }, class_name: 'CompetitionModule' has_many :competition_stages, dependent: :destroy has_many :competition_stage_sections, dependent: :destroy has_one :current_stage_section, -> { where('end_time > NOW()') }, class_name: 'CompetitionStageSection' has_many :competition_teams, dependent: :destroy has_many :team_members, dependent: :destroy has_many :chart_rules, dependent: :destroy has_many :competition_scores, dependent: :destroy has_many :competition_staffs, dependent: :destroy has_one :teacher_staff, -> { where(category: :teacher) }, class_name: 'CompetitionStaff' has_one :member_staff, -> { where.not(category: :teacher) }, class_name: 'CompetitionStaff' has_one :competition_mode_setting, dependent: :destroy has_many :informs, as: :container, dependent: :destroy has_many :attachments, as: :container, dependent: :destroy has_many :competition_awards, dependent: :destroy has_many :competition_schools, dependent: :destroy has_many :sponsor_schools, -> { where(source: :sponsor) }, class_name: 'CompetitionSchool' # 主办方 has_many :region_schools, -> { where(source: :region) }, class_name: 'CompetitionSchool' # 开放范围 has_many :competition_managers, dependent: :destroy has_many :managers, through: :competition_managers, source: :user has_many :competition_prizes, dependent: :destroy has_many :competition_prize_users, dependent: :destroy validates :introduction, length: { maximum: 500, too_long: "不能超过500个字符" } before_save :set_laboratory after_create :create_competition_modules def mode_type case mode when 1 "实训" when 2 "课堂" when 3 "教学" when 4 "托管" else "--" end end # 报名数 def team_member_count course = competition_mode_setting&.course if mode == 2 course ? course.students.count : team_members.count end def sponsor_schools_name sponsor_schools.map{|sponsor| sponsor.school.name} end def region_schools_name region_schools.map{|region| region.school.name} end def competition_status if !status com_status = "nearly_published" elsif end_time.nil? || end_time > Time.now com_status = "progressing" else com_status = "ended" end com_status end def teacher_staff_num teacher_staff ? "#{teacher_staff.minimum}~#{teacher_staff.maximum}" : "--" end def member_staff_num member_staff ? "#{member_staff.minimum}~#{member_staff.maximum}" : "--" end # 是否上架 def published? status? end # 即将发布 def nearly_published? !published? && published_at.present? end # 是否为个人赛 def personal? competition_staffs.sum(:maximum).to_i == 1 || (competition_staffs.nil? && max_num == 1) end # 报名是否结束 def enroll_ended? enroll_end_time.blank? || enroll_end_time < Time.now end # 是否已经报名 def enrolled?(user) team_members.exists?(user_id: user.id) end # 是否开放 def open?(user) user_school_id = user.user_extension&.school_id.to_i region_schools.size == 0 || region_schools.exists?(school_id: user_school_id) end # 是否禁止教师报名 def teacher_enroll_forbidden? teacher_staff.blank? || teacher_staff.maximum.zero? end # 是否禁止学生报名 def member_enroll_forbidden? member_staff.blank? || member_staff.maximum.zero? end # 老师是否能多次报名 def teacher_multiple_limited? teacher_staff&.mutiple_limited? end # 队员是否能多次报名 def member_multiple_limited? member_staff&.mutiple_limited? end def max_min_stage_time CompetitionStageSection.find_by_sql("SELECT MAX(end_time) as max_end_time, MIN(start_time) as min_start_time, competition_stage_id FROM competition_stage_sections WHERE competition_id = #{id} GROUP BY competition_stage_id order by competition_stage_id") end def all_module_types %w[home enroll inform chart resource certificate] end def max_stage_end_time competition_stages.map(&:max_end_time).max end def charts_count competition_prizes&.pluck(:num).sum.to_i > 0 ? competition_prizes&.pluck(:num).sum.to_i : awards_count end def manager?(user) user && competition_managers.exists?(user_id: user.id) end def finished? end_time.blank? || end_time < Time.now end private def get_module_name type case type when 'home' then '赛制介绍' when 'enroll' then '报名' when 'inform' then '通知公告' when 'chart' then '排行榜' when 'resource' then '资料下载' when 'certificate' then '获奖证书' else '' end end def create_competition_modules CompetitionModule.bulk_insert(*%i[competition_id module_type name position created_at updated_at]) do |worker| all_module_types.each_with_index do |type, index| worker.add(competition_id: id, module_type: type, name: get_module_name(type), position: index + 1, ) end end end def set_laboratory return unless new_record? self.laboratory = Laboratory.current if laboratory_id.blank? end end