commit
d1511241b2
@ -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
|
@ -1,10 +0,0 @@
|
|||||||
module ErrorCommon
|
|
||||||
extend ActiveSupport::Concern
|
|
||||||
|
|
||||||
included do
|
|
||||||
rescue_from Exception do |e|
|
|
||||||
logger.error e
|
|
||||||
render json: {status: -1, message: e.message}
|
|
||||||
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