parent
							
								
									a2832d44a1
								
							
						
					
					
						commit
						7df20dfa79
					
				| @ -0,0 +1,11 @@ | ||||
| class Competitions::BaseController < ApplicationController | ||||
|   include PaginateHelper | ||||
| 
 | ||||
|   before_action :require_login | ||||
| 
 | ||||
|   helper_method :current_competition | ||||
| 
 | ||||
|   def current_competition | ||||
|     @_current_competition ||= Competition.find_by!(identifier: params[:competition_id].presence || params[:id]) | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,4 @@ | ||||
| class Competitions::CompetitionStaffsController < Competitions::BaseController | ||||
|   def show | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,32 @@ | ||||
| class Competitions::CompetitionsController < Competitions::BaseController | ||||
|   skip_before_action :require_login | ||||
| 
 | ||||
|   def index | ||||
|     # 已上架 或者 即将上架 | ||||
|     competitions = Competition.where(status: true).or(Competition.where.not(published_at: nil)) | ||||
| 
 | ||||
|     competitions = | ||||
|       case params[:category] | ||||
|       when 'nearly_published' then competitions.where(status: false) | ||||
|       when 'progressing' then competitions.where('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(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 | ||||
|     unless current_competition.published? || admin_or_business? | ||||
|       render_forbidden | ||||
|       return | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,8 @@ | ||||
| module PaginateHelper | ||||
|   def paginate(objs, **opts) | ||||
|     page     = params[:page].to_i <= 0 ? 1 : params[:page].to_i | ||||
|     per_page = params[:per_page].to_i > 0 ? params[:per_page].to_i : 20 | ||||
| 
 | ||||
|     Kaminari.paginate_array(objs).page(page).per(per_page) | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,9 @@ | ||||
| module ApplicationDecorator | ||||
|   def display_time_method(*columns, format: '%Y-%m-%d %H:%M:%S') | ||||
|     columns.each do |column_name| | ||||
|       define_method "display_#{column_name}" do | ||||
|         public_send(column_name)&.strftime(format) | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,6 @@ | ||||
| module CompetitionDecorator | ||||
|   extend ApplicationDecorator | ||||
| 
 | ||||
|   display_time_method :start_time, :end_time, :enroll_end_time | ||||
| 
 | ||||
| end | ||||
| @ -0,0 +1,5 @@ | ||||
| module CompetitionStageSectionDecorator | ||||
|   extend ApplicationDecorator | ||||
| 
 | ||||
|   display_time_method :start_time, :end_time | ||||
| end | ||||
| @ -0,0 +1,40 @@ | ||||
| class Competition < ApplicationRecord | ||||
| 
 | ||||
|   has_many :competition_modules, dependent: :destroy | ||||
|   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 :team_members, 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_many :attachments, as: :container | ||||
| 
 | ||||
|   after_create :create_competition_modules | ||||
| 
 | ||||
|   # 是否上架 | ||||
|   def published? | ||||
|     status? | ||||
|   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 | ||||
| 
 | ||||
|   private | ||||
| 
 | ||||
|   def create_competition_modules | ||||
|     CompetitionModule.bulk_insert(*%i[competition_id name position]) do |worker| | ||||
|       %w(首页 报名 通知公告 排行榜 资料下载).each_with_index do |name, index| | ||||
|         worker.add(competition_id: id, name: name, position: index + 1) | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,4 @@ | ||||
| class CompetitionEntry < ApplicationRecord | ||||
|   belongs_to :competition_stage | ||||
|   belongs_to :competition_stage_section | ||||
| end | ||||
| @ -0,0 +1,7 @@ | ||||
| class CompetitionModule < ApplicationRecord | ||||
|   default_scope { order('position ASC') } | ||||
| 
 | ||||
|   belongs_to :competition | ||||
| 
 | ||||
|   has_one :competition_module_md_content, dependent: :destroy | ||||
| end | ||||
| @ -0,0 +1,5 @@ | ||||
| class CompetitionModuleMdContent < ApplicationRecord | ||||
|   belongs_to :competition_module | ||||
| 
 | ||||
|   has_many :attachments, as: :container, dependent: :destroy | ||||
| end | ||||
| @ -0,0 +1,3 @@ | ||||
| class CompetitionStaff < ApplicationRecord | ||||
|   belongs_to :competition | ||||
| end | ||||
| @ -0,0 +1,7 @@ | ||||
| class CompetitionStage < ApplicationRecord | ||||
|   belongs_to :competition | ||||
| 
 | ||||
|   has_many :competition_stage_sections, dependent: :destroy | ||||
|   has_many :competition_entries, dependent: :destroy | ||||
| 
 | ||||
| end | ||||
| @ -0,0 +1,6 @@ | ||||
| class CompetitionStageSection < ApplicationRecord | ||||
|   belongs_to :competition | ||||
|   belongs_to :competition_stage | ||||
| 
 | ||||
|   has_many :competition_entries, dependent: :destroy | ||||
| end | ||||
| @ -0,0 +1,8 @@ | ||||
| class CompetitionTeam < ApplicationRecord | ||||
|   belongs_to :user | ||||
|   belongs_to :competition | ||||
| 
 | ||||
|   has_many :team_members, dependent: :destroy | ||||
|   has_many :members, -> { without_teachers }, class_name: 'TeamMember' | ||||
|   has_many :teachers, -> { only_teachers }, class_name: 'TeamMember' | ||||
| end | ||||
| @ -0,0 +1,8 @@ | ||||
| class TeamMember < ApplicationRecord | ||||
|   belongs_to :user | ||||
|   belongs_to :competition | ||||
|   belongs_to :competition_team | ||||
| 
 | ||||
|   scope :only_teachers, -> { where(is_teacher: true) } | ||||
|   scope :without_teachers, -> { where(is_teacher: false) } | ||||
| end | ||||
| @ -0,0 +1,26 @@ | ||||
| competition = current_competition | ||||
| 
 | ||||
| json.enroll_ended competition.enroll_ended? | ||||
| json.enrolled competition.enrolled?(current_user) | ||||
| 
 | ||||
| # 教师报名设置 | ||||
| if competition.teacher_staff.present? | ||||
|   json.teacher_staff do | ||||
|     json.minimum competition.teacher_staff.minimum | ||||
|     json.maximum competition.teacher_staff.maximum | ||||
|     json.mutiple_limited competition.teacher_staff.mutiple_limited | ||||
|   end | ||||
| else | ||||
|   json.teacher_staff nil | ||||
| end | ||||
| 
 | ||||
| # 教师报名设置 | ||||
| if competition.member_staff.present? | ||||
|   json.member_staff do | ||||
|     json.minimum competition.member_staff.minimum | ||||
|     json.maximum competition.member_staff.maximum | ||||
|     json.mutiple_limited competition.member_staff.mutiple_limited | ||||
|   end | ||||
| else | ||||
|   json.member_staff nil | ||||
| end | ||||
| @ -0,0 +1,29 @@ | ||||
| json.count @count | ||||
| json.competitions do | ||||
|   json.array! @competitions.each do |competition| | ||||
|     json.extract! competition, :id, :identifier, :name, :sub_title | ||||
| 
 | ||||
|     json.visits_count competition.visits | ||||
|     member_count = @member_count_map&.fetch(competition.id, 0) || competition.team_members.count | ||||
|     json.member_count member_count.zero? ? 268 : member_count | ||||
| 
 | ||||
|     json.image url_to_avatar(competition) | ||||
|     json.published competition.published? | ||||
|     json.nearly_published competition.published_at.present? | ||||
|     json.single_stage (@stage_count_map&.fetch(competition.id, 0) || competition.competition_stages.count) == 1 | ||||
| 
 | ||||
|     json.start_time competition.display_start_time | ||||
|     json.end_time competition.display_end_time | ||||
|     json.enroll_end_time competition.display_enroll_end_time | ||||
| 
 | ||||
|     section = competition.current_stage_section | ||||
|     if section | ||||
|       json.current_stage do | ||||
| 
 | ||||
|         json.name = section.competition_stage.name | ||||
|         json.start_time section.display_start_time | ||||
|         json.end_time section.display_end_time | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
| @ -0,0 +1,36 @@ | ||||
| competition = current_competition | ||||
| json.extract! competition, :id, :name, :sub_title, :identifier | ||||
| 
 | ||||
| json.start_time competition.display_start_time | ||||
| json.end_time competition.display_end_time | ||||
| json.enroll_end_time competition.display_enroll_end_time | ||||
| 
 | ||||
| json.images do | ||||
|   json.array! competition.attachments, partial: 'attachments/attachment_simple', as: :attachment | ||||
| end | ||||
| 
 | ||||
| json.competition_stages do | ||||
|   stages = competition.competition_stages.includes(competition_stage_sections: :competition_entries) | ||||
|   json.array! stages.each do |stage| | ||||
|     json.extract! stage, :id, :name | ||||
| 
 | ||||
|     json.sections do | ||||
|       json.array! stage.competition_stage_sections.each do |section| | ||||
|         json.extract! section, :id, :name | ||||
| 
 | ||||
|         decorator_section = ActiveDecorator::Decorator.instance.decorate(section) | ||||
|         json.start_time decorator_section.display_start_time | ||||
|         json.end_time decorator_section.display_end_time | ||||
| 
 | ||||
|         is_start = section.start_time > Time.now | ||||
|         json.entries do | ||||
|           json.array! section.competition_entries.each do |entry| | ||||
|             json.extract! entry, :id, :name | ||||
| 
 | ||||
|             json.url is_start ? entry.url : '' | ||||
|           end | ||||
|         end | ||||
|       end | ||||
|     end | ||||
|   end | ||||
| end | ||||
					Loading…
					
					
				
		Reference in new issue