parent
82a2401795
commit
896ca84c72
@ -0,0 +1,28 @@
|
||||
class Competitions::CompetitionModulesController < Competitions::BaseController
|
||||
skip_before_action :require_login, only: [:index, :show]
|
||||
|
||||
before_action :require_business, only: [:update]
|
||||
|
||||
def index
|
||||
@modules = current_competition.unhidden_competition_modules.order(position: :asc)
|
||||
end
|
||||
|
||||
def show
|
||||
@module = current_module
|
||||
end
|
||||
|
||||
def update
|
||||
md = current_module.competition_module_md_content || current_module.build_competition_module_md_content
|
||||
md.name = params[:md_name]
|
||||
md.content = params[:md_content]
|
||||
md.save!
|
||||
|
||||
render_ok
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def current_module
|
||||
@_current_module ||= current_competition.unhidden_competition_modules.find(params[:id])
|
||||
end
|
||||
end
|
@ -0,0 +1,49 @@
|
||||
class Competitions::CompetitionTeamsController < Competitions::BaseController
|
||||
def index
|
||||
admin_or_business? ? all_competition_teams : user_competition_teams
|
||||
end
|
||||
|
||||
def create
|
||||
team = current_competition.competition_teams.new(user: current_user)
|
||||
Competitions::SaveTeamService.call(team, save_params)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def update
|
||||
team = current_competition.competition_teams.where(user: current_user).find(params[:id])
|
||||
Competitions::SaveTeamService.call(team, save_params)
|
||||
render_ok
|
||||
end
|
||||
|
||||
def join
|
||||
Competitions::JoinTeamService.call(current_competition, current_user, params)
|
||||
render_ok
|
||||
rescue Competitions::JoinTeamService::Error => ex
|
||||
render_error(ex.message)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def all_competition_teams
|
||||
teams = current_competition.competition_teams
|
||||
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.present?
|
||||
teams = teams.joins(users: { user_extension: :school }).where('schools.name LIKE ?', "%#{keyword}%")
|
||||
end
|
||||
|
||||
@count = teams.count
|
||||
@teams = paginate(teams.includes(:user, users: :user_extension))
|
||||
end
|
||||
|
||||
def user_competition_teams
|
||||
teams = current_competition.competition_teams
|
||||
teams = teams.joins(:team_members).where(team_members: { user_id: current_user.id })
|
||||
@teams = teams.includes(:user, users: :user_extension).to_a
|
||||
@count = @teams.size
|
||||
end
|
||||
|
||||
def save_params
|
||||
params.permit(:name, teacher_ids: [], member_ids: [])
|
||||
end
|
||||
end
|
@ -0,0 +1,22 @@
|
||||
class Competitions::StudentsController < Competitions::BaseController
|
||||
def index
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.blank?
|
||||
@students = []
|
||||
return
|
||||
end
|
||||
|
||||
students = User.joins(:user_extension).where(status: 1, user_extensions: { identity: 1 })
|
||||
students = students.where.not(id: params[:student_ids]) if params[:student_ids].present?
|
||||
students = students.where('LOWER(CONCAT(lastname, firstname, login, nickname)) LIKE ?', "%#{keyword}%")
|
||||
@students = students.includes(user_extension: :school).limit(20)
|
||||
|
||||
# 队员多次报名限制
|
||||
if current_competition.member_multiple_limited?
|
||||
ids = @students.map(&:id)
|
||||
members = current_competition.team_members.where(user_id: ids)
|
||||
members = members.where.not(competition_team_id: params[:team_id]) if params[:team_id].present?
|
||||
@enrolled_map = members.group(:user_id).count
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,22 @@
|
||||
class Competitions::TeachersController < Competitions::BaseController
|
||||
def index
|
||||
keyword = params[:keyword].to_s.strip
|
||||
if keyword.blank?
|
||||
@teachers = []
|
||||
return
|
||||
end
|
||||
|
||||
teachers = User.joins(:user_extension).where(status: 1, user_extensions: { identity: 0 })
|
||||
teachers = teachers.where.not(id: params[:teacher_ids]) if params[:teacher_ids].present?
|
||||
teachers = teachers.where('LOWER(CONCAT(lastname, firstname, login, nickname)) LIKE ?', "%#{keyword}%")
|
||||
@teachers = teachers.includes(user_extension: :school).limit(10)
|
||||
|
||||
# 老师多次报名限制
|
||||
if current_competition.teacher_multiple_limited?
|
||||
ids = @teachers.map(&:id)
|
||||
members = current_competition.team_members.where(user_id: ids)
|
||||
members = members.where.not(competition_team_id: params[:team_id]) if params[:team_id].present?
|
||||
@enrolled_map = members.group(:user_id).count
|
||||
end
|
||||
end
|
||||
end
|
@ -1,8 +1,33 @@
|
||||
class CompetitionTeam < ApplicationRecord
|
||||
|
||||
CODE_CHARS = %W(2 3 4 5 6 7 8 9 a b c f e f g h i j k l m n o p q r s t u v w x y z).freeze
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :competition
|
||||
|
||||
has_many :team_members, dependent: :destroy
|
||||
has_many :users, through: :team_members, source: :user
|
||||
has_many :members, -> { without_teachers }, class_name: 'TeamMember'
|
||||
has_many :teachers, -> { only_teachers }, class_name: 'TeamMember'
|
||||
|
||||
def group_team_type?
|
||||
team_type.zero?
|
||||
end
|
||||
|
||||
def personal_team_type?
|
||||
team_type == 1
|
||||
end
|
||||
|
||||
def en_team_type
|
||||
group_team_type? ? 'group' : 'personal'
|
||||
end
|
||||
|
||||
def generate_invite_code
|
||||
code = CODE_CHARS.sample(6).join
|
||||
while self.class.exists?(invite_code: code)
|
||||
code = CODE_CHARS.sample(6).join
|
||||
end
|
||||
self.code = code
|
||||
code
|
||||
end
|
||||
end
|
@ -0,0 +1,35 @@
|
||||
class Competitions::JoinTeamService < ApplicationService
|
||||
Error = Class.new(StandardError)
|
||||
|
||||
attr_reader :competition, :user, :params
|
||||
|
||||
def initialize(competition, user, params)
|
||||
@competition = competition
|
||||
@user = user
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
invite_code = params[:invite_code].to_s.strip
|
||||
raise Error, '战队邀请码不能为空' if invite_code.blank?
|
||||
|
||||
is_teacher = user.is_teacher?
|
||||
raise Error, '本竞赛的参赛者限定为:学生' if is_teacher && competition.teacher_enroll_forbidden?
|
||||
raise Error, '本竞赛的参赛者限定为:教师' if !is_teacher && competition.member_enroll_forbidden?
|
||||
|
||||
team = competition.competition_teams.find_by(invite_code: invite_code)
|
||||
raise Error, '战队邀请码无效' if team.blank?
|
||||
raise Error, '您已加入该战队' if team.team_members.exists?(user_id: user.id)
|
||||
|
||||
enrolled = competition.team_members.exists?(user_id: user.id)
|
||||
if enrolled && (is_teacher && competition.teacher_multiple_limited?) || (!is_teacher && competition.member_multiple_limited?)
|
||||
raise Error, '您已加入其它战队'
|
||||
end
|
||||
|
||||
raise Error, '该战队教师人数已满' if is_teacher && team.teachers.count == competition.teacher_staff.maximum
|
||||
raise Error, '该战队队员人数已满' if !is_teacher && team.members.count == competition.member_staff.maximum
|
||||
|
||||
role = is_teacher ? 3 : 2
|
||||
team.team_members.create!(competition_id: competition.id, user_id: user, role: role, is_teacher: is_teacher)
|
||||
end
|
||||
end
|
@ -0,0 +1,70 @@
|
||||
class Competitions::SaveTeamService < ApplicationService
|
||||
attr_reader :competition, :team, :creator, :params
|
||||
|
||||
TEAM_MEMBER_ATTRIBUTES = %i[competition_id competition_team_id user_id role is_teacher created_at updated_at]
|
||||
|
||||
def initialize(team, params)
|
||||
@team = team
|
||||
@competition = team.competition
|
||||
@creator = team.user
|
||||
@params = params
|
||||
end
|
||||
|
||||
def call
|
||||
Competitions::SaveTeamForm.new(form_params).validate!
|
||||
|
||||
new_record = team.new_record?
|
||||
is_teacher = team.user.is_teacher?
|
||||
ActiveRecord::Base.transaction do
|
||||
team.generate_invite_code if new_record
|
||||
team.name = params[:name].to_s.strip
|
||||
team.save!
|
||||
|
||||
# 创建者
|
||||
team.team_members.create!(user_id: creator.id, competition_id: competition.id, role: 1, is_teacher: is_teacher) if new_record
|
||||
|
||||
update_teacher_team_members!
|
||||
update_member_team_members!
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_teacher_team_members!
|
||||
teacher_ids = Array.wrap(params[:teacher_ids]).map(:to_i)
|
||||
old_teacher_ids = team.team_members.where(role: 3).pluck(:user_id)
|
||||
|
||||
destroy_teacher_ids = old_teacher_ids - teacher_ids
|
||||
team.team_members.where(role: 3).where(user_id: destroy_teacher_ids).delete_all
|
||||
|
||||
new_teacher_ids = teacher_ids - old_teacher_ids
|
||||
TeamMember.bulk_insert(*TEAM_MEMBER_ATTRIBUTES) do |worker|
|
||||
base_attr = { competition_id: competition.id, competition_team_id: team.id, role: 3, is_teacher: true }
|
||||
new_teacher_ids.each do |teacher_id|
|
||||
next if teacher_id == creator.id
|
||||
worker.add(base_attr.merge(user_id: teacher_id))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def update_member_team_members!
|
||||
member_ids = Array.wrap(params[:member_ids]).map(:to_i)
|
||||
old_member_ids = team.team_members.where(role: 2).pluck(:user_id)
|
||||
|
||||
destroy_member_ids = old_member_ids - member_ids
|
||||
team.team_members.where(role: 2).where(user_id: destroy_member_ids).delete_all
|
||||
|
||||
new_member_ids = member_ids - old_member_ids
|
||||
TeamMember.bulk_insert(*TEAM_MEMBER_ATTRIBUTES) do |worker|
|
||||
base_attr = { competition_id: competition.id, competition_team_id: team.id, role: 2, is_teacher: false }
|
||||
new_member_ids.each do |member_id|
|
||||
next if member_id == creator.id
|
||||
worker.add(base_attr.merge(user_id: member_id))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def form_params
|
||||
params.merge(competition: competition, team: team, creator: creator)
|
||||
end
|
||||
end
|
@ -0,0 +1,7 @@
|
||||
|
||||
json.modules do
|
||||
json.array! @modules.each do |m|
|
||||
json.extract! m, :id, :name, :position, :url
|
||||
end
|
||||
end
|
||||
json.count @modules.size
|
@ -0,0 +1,8 @@
|
||||
json.extract! @module, :id, :name, :position, :url, :md_edit
|
||||
|
||||
md = @module.competition_module_md_content
|
||||
if md.present?
|
||||
json.md_name md.name
|
||||
json.md_content md.content
|
||||
json.created_at md.created_at.strftime('%Y-%m-%d %H:%M:%S')
|
||||
end
|
@ -0,0 +1,23 @@
|
||||
json.count @count
|
||||
json.competition_teams do
|
||||
json.array! @teams.each do |team|
|
||||
json.extract! team, :id, :name, :invite_code
|
||||
json.team_type team.en_team_type
|
||||
json.school_name team.user.school_name
|
||||
|
||||
json.manage_permission current_user.id == team.user_id
|
||||
|
||||
json.creator do
|
||||
json.partial! 'users/user_simple', user: team.user
|
||||
json.role team.team_members.find(&:creator?).en_role
|
||||
end
|
||||
|
||||
json.team_members do
|
||||
json.array! team.team_members.each do |member|
|
||||
json.partial! 'users/user_simple', user: member.user
|
||||
json.user_id member.user_id
|
||||
json.role member.en_role
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -0,0 +1,9 @@
|
||||
json.teachers do
|
||||
json.array! @students.each do |student|
|
||||
json.id student.id
|
||||
json.name student.full_name
|
||||
json.student_id student.student_id
|
||||
json.school_name student.school_name
|
||||
json.enrollable !current_competition.member_multiple_limited? || !@enrolled_map.key?(student.id)
|
||||
end
|
||||
end
|
@ -0,0 +1,9 @@
|
||||
json.teachers do
|
||||
json.array! @teachers.each do |teacher|
|
||||
json.id teacher.id
|
||||
json.name teacher.full_name
|
||||
json.identity teacher.identity
|
||||
json.school_name teacher.school_name
|
||||
json.enrollable !current_competition.teacher_multiple_limited? || !@enrolled_map.key?(teacher.id)
|
||||
end
|
||||
end
|
@ -0,0 +1,8 @@
|
||||
'zh-CN':
|
||||
activerecord:
|
||||
models:
|
||||
competition_module_md_content: ''
|
||||
attributes:
|
||||
competition_module_md_content:
|
||||
name: '标题'
|
||||
content: '内容'
|
@ -0,0 +1,25 @@
|
||||
'zh-CN':
|
||||
activemodel:
|
||||
attributes:
|
||||
competitions/save_team_form:
|
||||
competition: ''
|
||||
name: '战队名称'
|
||||
creator: ''
|
||||
teacher_ids: ''
|
||||
member_ids: ''
|
||||
errors:
|
||||
models:
|
||||
competitions/save_team_form:
|
||||
attributes:
|
||||
creator:
|
||||
teacher_enroll_forbidden: "本竞赛的参赛者限定为:学生"
|
||||
member_enroll_forbidden: "本竞赛的参赛者限定为:教师"
|
||||
teacher_ids:
|
||||
enroll_forbidden: "本竞赛的参赛者限定为:学生"
|
||||
invalid_count: "教师数量应为%{minimum}~%{maximum}人"
|
||||
enrolled: "教师 ${names} 已加入其它战队了"
|
||||
member_ids:
|
||||
enroll_forbidden: "本竞赛的参赛者限定为:教师"
|
||||
invalid_count: "队员数量应为%{minimum}~%{maximum}人"
|
||||
enrolled: "队员 ${names} 已加入其它战队了"
|
||||
|
Loading…
Reference in new issue