project_pack
hjm 5 years ago
commit 045105830f

@ -1,7 +1,7 @@
class CompetitionTeamsController < ApplicationController class CompetitionTeamsController < ApplicationController
include ApplicationHelper include ApplicationHelper
before_filter :find_team, :except => [:new, :create, :join_team, :search_non_user, :personal_enroll, :check_team_identity, :search_teacher] before_filter :find_team, :except => [:new, :create, :join_team, :search_non_user, :personal_enroll, :check_team_identity, :search_teacher]
before_filter :find_competition, :only => [:new, :create, :join_team, :search_non_user, :personal_enroll] before_filter :find_competition, :only => [:new, :create, :join_team, :search_teacher, :search_non_user, :personal_enroll]
before_filter :require_login before_filter :require_login
skip_before_filter :verify_authenticity_token, :only => [:edit_rule] skip_before_filter :verify_authenticity_token, :only => [:edit_rule]
layout 'base_competition' layout 'base_competition'
@ -12,7 +12,38 @@ class CompetitionTeamsController < ApplicationController
@team_user = User.current @team_user = User.current
end end
def show
return render_404 if @competition.identifier != 'gcc-course-2019'
@team_user_ids = @team.team_members.pluck(:user_id)
shixuns = Shixun.where(user_id: @team_user_ids, status: 2)
shixuns = shixuns.joins('left join shixuns forked_shixuns on forked_shixuns.fork_from = shixuns.id and forked_shixuns.status = 2')
shixuns = shixuns.joins('left join myshixuns on myshixuns.shixun_id = shixuns.id and exists(select 1 from games where games.myshixun_id = myshixuns.id and games.status = 2)')
shixuns = shixuns.select('shixuns.id, shixuns.identifier, shixuns.user_id, shixuns.myshixuns_count, shixuns.name, shixuns.fork_from, sum(forked_shixuns.myshixuns_count) forked_myshixun_count')
@shixuns = shixuns.group('shixuns.id').order('shixuns.myshixuns_count desc').includes(:creator)
@myshixun_count_map = Myshixun.where(shixun_id: @shixuns.map(&:id))
.where('exists(select 1 from games where games.myshixun_id = myshixuns.id and games.status = 2)')
.group('shixun_id').count
course_ids = Course.joins('join members on members.course_id = courses.id')
.joins('join member_roles on member_roles.member_id = members.id and member_roles.role_id in (3,7,9)')
.where(members: { user_id: @team_user_ids }).pluck(:id)
courses = Course.where(id: course_ids).joins(:shixun_homework_commons)
@courses = courses.select('courses.id, courses.name, courses.members_count, count(*) shixun_homework_count')
.group('courses.id').order('shixun_homework_count desc')
@course_myshixun_map = Myshixun.joins(student_works: :homework_common)
.where(homework_commons: { course_id: @courses.map(&:id) })
.where('exists(select 1 from games where games.myshixun_id = myshixuns.id and games.status = 2)')
.group('homework_commons.course_id').count
end
def search_teacher def search_teacher
if params[:team] && params[:team] != ""
@team = @competition.competition_teams.where(:id => params[:team]).first
end
condition = "%#{params[:search].strip}%".gsub(" ","") condition = "%#{params[:search].strip}%".gsub(" ","")
@teachers = User.joins(:user_extensions).where("status = 1 and LOWER(concat(lastname, firstname, login, nickname)) LIKE '#{condition}' and user_extensions.identity = 0") @teachers = User.joins(:user_extensions).where("status = 1 and LOWER(concat(lastname, firstname, login, nickname)) LIKE '#{condition}' and user_extensions.identity = 0")
end end
@ -38,9 +69,13 @@ class CompetitionTeamsController < ApplicationController
end end
def create def create
teacher_limited = @competition.teacher_enroll_mutiple_limited
member_limited = @competition.member_enroll_mutiple_limited
# 判断用户是否已创建过战队 # 判断用户是否已创建过战队
if @competition.competition_teams.where(:user_id => User.current.id).count > 0 && !User.current.is_teacher if @competition.team_members.where(user_id: User.current.id).count > 0 &&
@status, @message = -1, '您已创建过战队,不能重复创建' ((User.current.is_teacher && teacher_limited) || (!User.current.is_teacher && member_limited))
@status, @message = -1, '您已经在战队中了'
return return
end end
@ -52,6 +87,11 @@ class CompetitionTeamsController < ApplicationController
is_teacher = User.current.user_extensions.identity == 0 is_teacher = User.current.user_extensions.identity == 0
return unless member_and_teacher_count_valid?(is_teacher) return unless member_and_teacher_count_valid?(is_teacher)
# 检查老师多次报名限制
return unless check_teacher_enroll_limited?(@competition, (params[:teacher_ids].presence || []).map(&:to_i) - [User.current.id])
# 检查成员多次报名限制
return unless check_member_enroll_limited?(@competition, (params[:member_ids].presence || []).map(&:to_i) - [User.current.id])
ActiveRecord::Base.transaction do ActiveRecord::Base.transaction do
invite_code = generate_team_code invite_code = generate_team_code
new_team = CompetitionTeam.create(:competition_id => @competition.id, :name => params[:name], new_team = CompetitionTeam.create(:competition_id => @competition.id, :name => params[:name],
@ -104,8 +144,12 @@ class CompetitionTeamsController < ApplicationController
# 删除的成员 # 删除的成员
delete_member_ids = team_member_ids - new_member_ids delete_member_ids = team_member_ids - new_member_ids
@team.team_members.where(role: 2, user_id: delete_member_ids).delete_all @team.team_members.where(role: 2, user_id: delete_member_ids).delete_all
# 新增加的成员 # 新增加的成员
(new_member_ids - team_member_ids).each do |user_id| ids = new_member_ids - team_member_ids
raise @message unless check_member_enroll_limited?(@competition, ids) # 有成员已经加入其他战队,并且只能一次报名
ids.each do |user_id|
next if user_id.to_i == @team.user_id next if user_id.to_i == @team.user_id
@team.team_members.create!(user_id: user_id, role: 2, competition_id: @competition.id) @team.team_members.create!(user_id: user_id, role: 2, competition_id: @competition.id)
end end
@ -117,12 +161,19 @@ class CompetitionTeamsController < ApplicationController
# 删除的老师 # 删除的老师
delete_teacher_ids = teacher_ids - new_teacher_ids delete_teacher_ids = teacher_ids - new_teacher_ids
@team.team_members.where(role: 3, user_id: delete_teacher_ids).delete_all @team.team_members.where(role: 3, user_id: delete_teacher_ids).delete_all
# 新增加的老师 # 新增加的老师
(new_teacher_ids - teacher_ids).each do |user_id| ids = new_teacher_ids - teacher_ids
raise @message unless check_teacher_enroll_limited?(@competition, ids) # 有老师已经加入其他战队,并且只能一次报名
ids.each do |user_id|
next if user_id.to_i == @team.user_id next if user_id.to_i == @team.user_id
@team.team_members.create!(user_id: user_id, role: 3, competition_id: @competition.id, is_teacher: true) @team.team_members.create!(user_id: user_id, role: 3, competition_id: @competition.id, is_teacher: true)
end end
end end
rescue => ex
@status = -1
@message = ex.message
end end
# @status:提示语标志0加入成功1邀请码错误2已经加入了其他队, 3超过人数限制4已有指导老师5只有学生和老师身份的用户才能加入战队 # @status:提示语标志0加入成功1邀请码错误2已经加入了其他队, 3超过人数限制4已有指导老师5只有学生和老师身份的用户才能加入战队
@ -133,7 +184,8 @@ class CompetitionTeamsController < ApplicationController
return return
end end
if TeamMember.where(:user_id => User.current.id, :competition_team_id => @competition.competition_teams.map(&:id), :is_teacher => 0).count > 0 enroll_limited = (User.current.is_teacher ? @competition.teacher_enroll_mutiple_limited : @competition.member_enroll_mutiple_limited)
if enroll_limited && @competition.team_members.exists?(user_id: User.current.id)
@status, @message = -1, '您已加入战队,不能重复加' @status, @message = -1, '您已加入战队,不能重复加'
return return
end end
@ -243,4 +295,30 @@ class CompetitionTeamsController < ApplicationController
true true
end end
def check_teacher_enroll_limited?(competition, user_ids)
teacher_limited = competition.teacher_enroll_mutiple_limited
return true unless teacher_limited && user_ids.present?
repeat_teachers = competition.team_members.where(user_id: user_ids).includes(:user).to_a
if repeat_teachers.size > 0
@status, @message = -1, "导师#{repeat_teachers.map{|t| t.user.show_real_name}.join('')}已经加入其它战队了"
return false
end
true
end
def check_member_enroll_limited?(competition, user_ids)
member_limited = competition.member_enroll_mutiple_limited
return true unless member_limited && user_ids.present?
repeat_members = competition.team_members.where(user_id: user_ids).includes(:user).to_a
if repeat_members.size > 0
@status, @message = -1, "成员#{repeat_members.map{|t| t.user.show_real_name}.join('')}已经加入其它战队了"
return false
end
true
end
end end

@ -4,7 +4,7 @@ class CompetitionsController < ApplicationController
:edit_md_content, :update_md_content, :edit_md_content, :update_md_content,
:new_competition_stage, :new_stage_section, :update_competition_stage] :new_competition_stage, :new_stage_section, :update_competition_stage]
before_filter :find_inform, :only => [:edit_inform, :update_inform] before_filter :find_inform, :only => [:edit_inform, :update_inform]
before_filter :require_login, :only => [:enroll_portal] before_filter :require_login, :only => [:enroll_portal, :publish]
skip_before_filter :verify_authenticity_token, :only => [:edit_rule] skip_before_filter :verify_authenticity_token, :only => [:edit_rule]
layout 'base_competition' layout 'base_competition'
@ -25,7 +25,7 @@ class CompetitionsController < ApplicationController
end end
def index def index
@competitions = Competition.where(:status => 1).reorder("online_time desc") @competitions = Competition.where('status = 1 or published_at is not null').reorder("published_at desc, online_time desc")
respond_to do |format| respond_to do |format|
format.html { render :layout => "base_edu"} format.html { render :layout => "base_edu"}
format.js format.js
@ -111,6 +111,7 @@ class CompetitionsController < ApplicationController
@search_teams_count = @teams.count @search_teams_count = @teams.count
@team_members_count = TeamMember.where(:competition_team_id => @teams.pluck(:id)).count @team_members_count = TeamMember.where(:competition_team_id => @teams.pluck(:id)).count
@can_enroll = !(@user.is_teacher ? @competition.teacher_enroll_mutiple_limited : @competition.member_enroll_mutiple_limited) || !@competition.team_members.exists?(user_id: User.current.id)
@is_enroll = CompetitionTeam.where(:id => TeamMember.where(:user_id => @user, :competition_team_id => @competition.competition_teams.map(&:id)).pluck(:competition_team_id)).reorder("created_at desc") @is_enroll = CompetitionTeam.where(:id => TeamMember.where(:user_id => @user, :competition_team_id => @competition.competition_teams.map(&:id)).pluck(:competition_team_id)).reorder("created_at desc")
@show_notice = (@competition.identifier == "gcc-dev-2018" || @competition.identifier == "gcc-annotation-2018") && @show_notice = (@competition.identifier == "gcc-dev-2018" || @competition.identifier == "gcc-annotation-2018") &&
@competition.competition_teams.joins(:team_members).where(:user_id => User.current.id).group('competition_teams.id').sum('IF(team_members.is_teacher=1, 1, 0)').values.any?(&:zero?) @competition.competition_teams.joins(:team_members).where(:user_id => User.current.id).group('competition_teams.id').sum('IF(team_members.is_teacher=1, 1, 0)').values.any?(&:zero?)
@ -437,10 +438,10 @@ class CompetitionsController < ApplicationController
def online_switch def online_switch
if @competition.present? if @competition.present?
if @competition.status if @competition.status
@competition.update_attributes(:status => 0) @competition.update_attributes(status: false, published_at: nil)
@btn_html = "上架" @btn_html = "上架"
else else
@competition.update_attributes(:status => 1, :online_time => Time.now) @competition.update_attributes(status: true, online_time: Time.now, published_at: nil)
@btn_html = "下架" @btn_html = "下架"
end end
end end
@ -580,7 +581,7 @@ class CompetitionsController < ApplicationController
section_entries.destroy_all section_entries.destroy_all
else else
if params[:entry_name].length < section_entries.size if params[:entry_name].length < section_entries.size
section_entries[params[:entry_name].length, section_entries.size - 1].destroy_all section_entries[params[:entry_name].length, section_entries.size - 1].each(&:destroy)
end end
params[:entry_name].each_with_index do |name, index| params[:entry_name].each_with_index do |name, index|
@ -600,6 +601,12 @@ class CompetitionsController < ApplicationController
@competition.competition_stage_sections.where(:id => params[:section_id]).destroy_all @competition.competition_stage_sections.where(:id => params[:section_id]).destroy_all
end end
def publish
return render_403 unless admin_or_business?
@competition.update_column(:published_at, Time.now)
end
private private
def chart_exp_score_mo myshixuns, s_time, e_time def chart_exp_score_mo myshixuns, s_time, e_time

@ -32,4 +32,12 @@ class Competition < ActiveRecord::Base
def member_count def member_count
self.team_members.count == 0 ? 0 : self.team_members.count + 268 self.team_members.count == 0 ? 0 : self.team_members.count + 268
end end
def teacher_enroll_mutiple_limited
competition_staffs.where(category: 'teacher').first.try(:mutiple_limited)
end
def member_enroll_mutiple_limited
competition_staffs.where(category: 'student').first.try(:mutiple_limited)
end
end end

@ -1,7 +1,7 @@
class CompetitionStaff < ActiveRecord::Base class CompetitionStaff < ActiveRecord::Base
default_scope order: 'position asc' default_scope order: 'position asc'
attr_accessible :minimum, :maximum, :category, :position attr_accessible :minimum, :maximum, :category, :position, :mutiple_limited
belongs_to :competition belongs_to :competition

@ -314,6 +314,7 @@ module ZipService
rename_zipfile = zip_name_refer ||= "#{Time.now.to_i.to_s}.zip" rename_zipfile = zip_name_refer ||= "#{Time.now.to_i.to_s}.zip"
# 文件名过长 # 文件名过长
index = 1
if rename_zipfile.size > MAX_PATH if rename_zipfile.size > MAX_PATH
rename_zipfile = rename_zipfile[0,rename_zipfile.size-4][0,MAX_PATH-4] + rename_zipfile[-4,4] rename_zipfile = rename_zipfile[0,rename_zipfile.size-4][0,MAX_PATH-4] + rename_zipfile[-4,4]
end end
@ -329,7 +330,10 @@ module ZipService
begin begin
zipfile.add(rename_file, filename) zipfile.add(rename_file, filename)
rescue Exception => e rescue Exception => e
zipfile.get_output_stream('FILE_NOTICE.txt'){|os| os.write l(:label_file_exist)} rename_file = rename_same_file(rename_file, index)
index += 1
zipfile.add(rename_file, filename)
# zipfile.get_output_stream('FILE_NOTICE.txt'){|os| os.write l(:label_file_exist)}
next next
end end
end end
@ -376,4 +380,11 @@ module ZipService
attach = Attachment.find_by_disk_filename(name) attach = Attachment.find_by_disk_filename(name)
attach.filename attach.filename
end end
def rename_same_file(name, index)
basename = File.basename(name, ".*")
new_basename = basename + "_" + index.to_s
extname = File.extname(name)
new_basename + extname
end
end end

@ -24,13 +24,12 @@
<div class="df pl20 pr20"> <div class="df pl20 pr20">
<label class="ml10 mt3">导师:</label> <label class="ml10 mt3">导师:</label>
<div class="flex1 pr search-new"> <div class="flex1 pr search-new">
<input type="text" class="input-100-35 fl" <%= @team_user.user_extensions.identity == 0 ? "disabled" : "" %> autocomplete="off" placeholder="请您输入老师姓名进行搜索;可以后续再添加导师" id="teacher_search_input" <input type="text" class="input-100-35 fl" autocomplete="off" placeholder="请您输入老师姓名进行搜索;可以后续再添加导师" id="teacher_search_input" value="">
value="<%= @team.try(:id).present? ? @team.teacher.try(:show_name) : (@team_user.user_extensions.identity == 0 ? @team_user.show_name : "") %>">
<input type="hidden" id="teacher_id" data-select="0" value="<%= @team.try(:id).present? ? @team.try(:teacher_id) : (@team_user.user_extensions.identity == 0 ? @team_user.id : "") %>"> <input type="hidden" id="teacher_id" data-select="0" value="<%= @team.try(:id).present? ? @team.try(:teacher_id) : (@team_user.user_extensions.identity == 0 ? @team_user.id : "") %>">
<input type="hidden" id="teacher_name" value="<%= @team.try(:id).present? ? @team.teacher.try(:show_name) : (@team_user.user_extensions.identity == 0 ? @team_user.show_name : "") %>"> <input type="hidden" id="teacher_name" value="<%= @team.try(:id).present? ? @team.teacher.try(:show_name) : (@team_user.user_extensions.identity == 0 ? @team_user.show_name : "") %>">
<input type="hidden" id="teacher_school"> <input type="hidden" id="teacher_school">
<input type="hidden" id="teacher_title"> <input type="hidden" id="teacher_title">
<a class="fl searchicon" style="top:0px;" onclick="<%= @team_user.user_extensions.identity == 0 ? '' : 'search_teacher_user()' %>"><i class="iconfont icon-sousuo fl"></i></a> <a class="fl searchicon" style="top:0px;" onclick="search_teacher_user()"><i class="iconfont icon-sousuo fl"></i></a>
<ul class="pointerTeacher none" id="pointerTeacher"> <ul class="pointerTeacher none" id="pointerTeacher">
</ul> </ul>
</div> </div>
@ -247,8 +246,8 @@
function search_teacher_user(){ function search_teacher_user(){
if($("#teacher_search_input").val().trim() != ""){ if($("#teacher_search_input").val().trim() != ""){
$.post("<%= search_teacher_competition_teams_path() %>", $.post("<%= search_teacher_competition_teams_path(:com_id => @competition.id) %>",
{"search": $("#teacher_search_input").val().trim()}); {"search": $("#teacher_search_input").val().trim(), "team": $("#team_id").val()});
} }
} }

@ -1,5 +1,5 @@
<% @users.each do |user| %> <% @users.each do |user| %>
<% has_enroll = @team.present? ? @competition.team_members.where("user_id = '#{user.id}' and id != #{@team.id}").count > 0 : @competition.team_members.where("user_id = '#{user.id}'").count > 0 %> <% has_enroll = @competition.member_enroll_mutiple_limited && (@team.present? ? @competition.team_members.where("user_id = '#{user.id}' and id != #{@team.id}").count > 0 : @competition.team_members.where("user_id = '#{user.id}'").count > 0) %>
<li class="clearfix <%= has_enroll ? 'added' : 'unadded' %>"> <li class="clearfix <%= has_enroll ? 'added' : 'unadded' %>">
<input type="hidden" value="<%= user.id %>"> <input type="hidden" value="<%= user.id %>">
<span class="pt-s task-hide"><%= user.show_name %></span> <span class="pt-s task-hide"><%= user.show_name %></span>

@ -1,10 +1,15 @@
<p class="pl30 color-orange-tip mt5 pb5 bor-bottom-greyE">请选择指导老师,允许修改</p> <p class="pl30 color-orange-tip mt5 pb5 bor-bottom-greyE">请选择指导老师,允许修改</p>
<% @teachers.each do |teacher| %> <% @teachers.each do |teacher| %>
<li class="clearfix"> <% has_enroll = @competition.teacher_enroll_mutiple_limited && (@team.present? ? @competition.team_members.where("user_id = '#{teacher.id}' and id != #{@team.id}").count > 0 : @competition.team_members.where("user_id = '#{teacher.id}'").count > 0) %>
<li class="clearfix <%= has_enroll ? 'added' : 'unadded' %>">
<input type="hidden" value="<%= teacher.id %>"> <input type="hidden" value="<%= teacher.id %>">
<span class="pt-s task-hide"><%= teacher.show_name %></span> <span class="pt-s task-hide"><%= teacher.show_name %></span>
<span class="pt-s-n task-hide"><%= teacher.identity %></span> <span class="pt-s-n task-hide"><%= teacher.identity %></span>
<span class="pt-l task-hide"><%= teacher.school_name %></span> <span class="pt-l task-hide"><%= teacher.school_name %></span>
<% if has_enroll %>
<span class="pt-s color-orange-tip task-hide">已加入其他战队</span>
<% end %>
</li> </li>
<% end %> <% end %>
@ -14,7 +19,7 @@
e.stopPropagation(); e.stopPropagation();
}); });
/*从下拉列表中选择指导老师*/ /*从下拉列表中选择指导老师*/
$("#pointerTeacher li").click(function(e){ $("#pointerTeacher li.unadded").click(function(e){
var name=$(this).find(".pt-s").html().trim(); var name=$(this).find(".pt-s").html().trim();
$("#pointerTeacher").siblings("#teacher_search_input").val(name); $("#pointerTeacher").siblings("#teacher_search_input").val(name);
$("#pointerTeacher").siblings("#teacher_id").val($(this).find("input").val().trim()); $("#pointerTeacher").siblings("#teacher_id").val($(this).find("input").val().trim());

@ -0,0 +1,118 @@
<div class="educontent mb50">
<p class="edu-back-white mb20 padding30 mt10 clearfix lineh-20">
<span class="color-grey-3 font-18 fl">战队详情</span>
<%= link_to '返回', enroll_competition_path(@competition), class: 'color-grey-9 fr' %>
</p>
<div class="edu-back-white mb20">
<p class="pt20 pb20 font-16"><span class="modalTitle">实训项目</span></p>
<table width="100%" class="tBodyScroll edu-txt-center" cellpadding="0" cellspacing="0">
<thead class="lastPart">
<tr>
<th width="10%">创建者</th>
<th width="40%" class="edu-txt-left">名称</th>
<th width="10%">学习人数</th>
<th width="15%">fork版的学习人数</th>
<th width="10%">有效作品数</th>
<th width="15%">经验值</th>
</tr>
</thead>
<tbody>
<%
total_myshixun_count = 0
total_forked_myshixun_count = 0
%>
<% @shixuns.each do |shixun| %>
<%
total_myshixun_count += shixun.myshixuns_count
total_forked_myshixun_count += shixun['forked_myshixun_count'].to_i
%>
<tr>
<td width="10%"><%= shixun.creator.show_real_name %></td>
<td width="40%" class="edu-txt-left">
<%= link_to shixun_path(shixun), target: '_blank' do %>
<span class="task-hide fl" style="max-width: 410px;"><%= shixun.name %></span>
<% end %>
<% if shixun.fork_from.blank? %>
<span class="connectTag ml10">原创</span>
<% end %>
</td>
<td width="10%"><%= shixun.myshixuns_count.to_i.zero? ? '--' : shixun.myshixuns_count.to_i %></td>
<td width="15%"><%= shixun['forked_myshixun_count'].to_i.zero? ? '--' : shixun['forked_myshixun_count'].to_i %></td>
<th width="10%"><%= @myshixun_count_map.fetch(shixun.id, '--') %></th>
<td width="15%">--</td>
</tr>
<% end %>
</tbody>
<tfoot class="tfootLastPart">
<tr class="color-orange font-16">
<th width="10%" class="color-grey-6">合计</th>
<th width="40%" class="edu-txt-left"><%= @shixuns.size %></th>
<th width="10%"><%= total_myshixun_count %></th>
<th width="15%"><%= total_forked_myshixun_count %></th>
<th width="10%"><%= @myshixun_count_map.values.reduce(:+) %></th>
<th width="15%">--</th>
</tr>
</tfoot>
</table>
</div>
<div class="edu-back-white mb20">
<p class="pt20 pb20 font-16"><span class="modalTitle">翻转课堂</span></p>
<table width="100%" class="tBodyScroll edu-txt-center" cellpadding="0" cellspacing="0">
<thead class="lastPart">
<tr>
<th width="10%">创建者</th>
<th width="40%" class="edu-txt-left">名称</th>
<th width="10%">学生数量</th>
<th width="15%">发布的实训作业数量</th>
<th width="10%">有效作品数</th>
<th width="15%">经验值</th>
</tr>
</thead>
<tbody>
<%
total_members_count = 0
total_shixun_homework_count = 0
%>
<% @courses.each do |course| %>
<%
total_members_count += course.members_count.to_i
total_shixun_homework_count += course['shixun_homework_count'].to_i
%>
<tr>
<td width="10%"><%= course.teachers.where(user_id: @team_user_ids).first.user.show_real_name %></td>
<td width="40%" class="edu-txt-left">
<span class="task-hide fl" style="max-width: 480px;"><%= course.name %></span>
</td>
<td width="10%"><%= course.members_count %></td>
<td width="15%"><%= course['shixun_homework_count'].presence || '--' %></td>
<th width="10%"><%= @course_myshixun_map.fetch(course.id, '--') %></th>
<td width="15%">--</td>
</tr>
<% end %>
</tbody>
<tfoot class="tfootLastPart">
<tr class="color-orange font-16">
<th width="10%" class="color-grey-6">合计</th>
<th width="40%" class="edu-txt-left"><%= @courses.size %></th>
<th width="10%"><%= total_members_count %></th>
<th width="15%"><%= total_shixun_homework_count %></th>
<th width="10%"><%= @course_myshixun_map.values.reduce(:+) %></th>
<th width="15%">--</th>
</tr>
</tfoot>
</table>
</div>
</div>
<script>
$(function(){
if($(".tBodyScroll tbody").get(0).scrollHeight > 420){
$(".tBodyScroll thead").addClass("lastPart");
$(".tBodyScroll tfoot").addClass("tfootLastPart");
}else{
$(".tBodyScroll thead").removeClass("lastPart");
$(".tBodyScroll tfoot").removeClass("tfootLastPart");
}
})
</script>

@ -46,7 +46,7 @@
<a href="<%= charts_competition_path(@competition) %>" >排行榜</a> <a href="<%= charts_competition_path(@competition) %>" >排行榜</a>
</li> </li>
<% when '报名' %> <% when '报名' %>
<li class="<%= params[:action] == 'enroll' ? 'active' : '' %>"> <li class="<%= params[:action] == 'enroll' || params[:action] == 'show' ? 'active' : '' %>">
<a href="<%= enroll_competition_path(@competition) %>">报名</a> <a href="<%= enroll_competition_path(@competition) %>">报名</a>
</li> </li>
<% else %> <% else %>

@ -14,15 +14,15 @@
is_start = Time.now > first_section.start_time is_start = Time.now > first_section.start_time
%> %>
<div class="second_course_5" style="background: url('<%= named_attachment_path(@images[index], @images[index].try(:filename)) %>') no-repeat top center;"> <div class="second_course_5" style="background: url('<%= named_attachment_path(@images[index], @images[index].try(:filename)) %>') no-repeat top center;">
<div class="enter_panel" style="height: 500px"> <div class="enter_panel" style="height: 437px">
<div class="course_competition_panel"> <div class="course_competition_panel">
<a href="<%= is_start ? first_section.competition_entries[0].url : 'javascript:void(0)'%>" <a href="<%= is_start ? first_section.competition_entries[0].url : 'javascript:void(0)'%>"
class="<%= is_start ? 'active' : '' %>" target="_blank"><%= first_section.competition_entries[0].name %></a> class="<%= is_start ? 'active' : '' %>" target="_blank"><%= first_section.competition_entries[0].name %></a>
<a href="<%= is_start ? first_section.competition_entries[1].url : 'javascript:void(0)'%>" <a href="<%= is_start ? first_section.competition_entries[1].url : 'javascript:void(0)'%>"
class="<%= is_start ? 'active' : '' %>" target="_blank"><%= first_section.competition_entries[1].name %></a> class="<%= is_start ? 'active' : '' %>" target="_blank"><%= first_section.competition_entries[1].name %></a>
</div> </div>
<a href="<%= is_start ? first_section.competition_entries[2].url : 'javascript:void(0)'%>" <!--<a href="<%#= is_start ? first_section.competition_entries[2].url : 'javascript:void(0)'%>"-->
class="ex_submit"><%= first_section.competition_entries[2].name %></a> <!--class="ex_submit"><%#= first_section.competition_entries[2].name %></a>-->
</div> </div>
</div> </div>
<% index += 1 %> <% index += 1 %>

@ -2,14 +2,14 @@
<div class="enroll-t" style="background:url('/images/educoder/competition/anon.png') no-repeat top center;"> <div class="enroll-t" style="background:url('/images/educoder/competition/anon.png') no-repeat top center;">
<div class="educontent edu-txt-center"> <div class="educontent edu-txt-center">
<p class="main_title"><%= @competition.name %></p> <p class="main_title"><%= @competition.name %></p>
<% if @minimum_staff > 1 %> <% if @maximum_staff > 1 %>
<p class="sub_title"><%= @competition.sub_title %></p> <p class="sub_title"><%= @competition.sub_title %></p>
<p class="edu-txt-right inline mt20"> <p class="edu-txt-right inline mt20">
<% unless User.current.logged? %> <% unless User.current.logged? %>
<%= link_to "创建战队", signin_path, :remote => true, :class => "enroll-in-b enroll-in-b-green fr" %> <%= link_to "创建战队", signin_path, :remote => true, :class => "enroll-in-b enroll-in-b-green fr" %>
<% else %> <% else %>
<% unless @competition.enroll_end_time.present? && @competition.enroll_end_time < Time.now %> <% unless @competition.enroll_end_time.present? && @competition.enroll_end_time < Time.now %>
<% if @is_enroll.present? && !@user.is_teacher %> <% if !@can_enroll %>
<a onclick="notice_box('您已经加入了战队,不能再创建')" class="enroll-in-b enroll-in-b-green fr">创建战队</a> <a onclick="notice_box('您已经加入了战队,不能再创建')" class="enroll-in-b enroll-in-b-green fr">创建战队</a>
<% else %> <% else %>
<a href="<%= new_competition_team_path(:com_id => @competition.id) %>" data-remote="true" class="enroll-in-b enroll-in-b-green fr">创建战队</a> <a href="<%= new_competition_team_path(:com_id => @competition.id) %>" data-remote="true" class="enroll-in-b enroll-in-b-green fr">创建战队</a>
@ -23,7 +23,7 @@
<%= link_to "加入战队", signin_path, :remote => true, :class => "enroll-in-b fr" %> <%= link_to "加入战队", signin_path, :remote => true, :class => "enroll-in-b fr" %>
<% else %> <% else %>
<% unless @competition.enroll_end_time.present? && @competition.enroll_end_time < Time.now %> <% unless @competition.enroll_end_time.present? && @competition.enroll_end_time < Time.now %>
<% if @is_enroll.present? && !@user.is_teacher %> <% if !@can_enroll %>
<a onclick="notice_box('您已经加入了战队,不能重复加入')" class="enroll-in-b fr">加入战队</a> <a onclick="notice_box('您已经加入了战队,不能重复加入')" class="enroll-in-b fr">加入战队</a>
<% else %> <% else %>
<a class="enroll-in-b fr" onclick="joinTeam();">加入战队</a> <a class="enroll-in-b fr" onclick="joinTeam();">加入战队</a>
@ -40,7 +40,7 @@
<% else %> <% else %>
<p class="edu-txt-right inline mt20"> <p class="edu-txt-right inline mt20">
<% unless @competition.enroll_end_time.present? && @competition.enroll_end_time < Time.now %> <% unless @competition.enroll_end_time.present? && @competition.enroll_end_time < Time.now %>
<% if @is_enroll.present? %> <% if !@can_enroll %>
<a href="javascript:void(0)" onclick="notice_box('您已报名')" class="enroll-in-b enroll-in-b-green fr">立即报名</a> <a href="javascript:void(0)" onclick="notice_box('您已报名')" class="enroll-in-b enroll-in-b-green fr">立即报名</a>
<% else %> <% else %>
<%= link_to "立即报名", personal_enroll_competition_teams_path(:com_id => @competition.id), :remote => true, :class => "enroll-in-b enroll-in-b-green fr" %> <%= link_to "立即报名", personal_enroll_competition_teams_path(:com_id => @competition.id), :remote => true, :class => "enroll-in-b enroll-in-b-green fr" %>
@ -97,6 +97,10 @@
<a href="javascript:void(0)" class="font-16 color-grey-c fl mt12" onclick="delete_confirm_box('<%= exit_team_competition_team_path(team) %>', '是否确认退出战队')">退出</a> <a href="javascript:void(0)" class="font-16 color-grey-c fl mt12" onclick="delete_confirm_box('<%= exit_team_competition_team_path(team) %>', '是否确认退出战队')">退出</a>
<% end %> <% end %>
<% end %> <% end %>
<% if @competition.identifier == 'gcc-course-2019' %>
<%= link_to '战队详情', competition_team_path(id: team.id), class: 'fl mt13 ml10' %>
<% end %>
</li> </li>
<% end %> <% end %>
</div> </div>

@ -2,6 +2,7 @@
<% if @competitions.count > 0 %> <% if @competitions.count > 0 %>
<div class="clearfix competitionsList"> <div class="clearfix competitionsList">
<% @competitions.each do |competition| %> <% @competitions.each do |competition| %>
<% if competition.status? %>
<div class="competitionsList-item mb20"> <div class="competitionsList-item mb20">
<div class="edu-back-white"> <div class="edu-back-white">
<a href="<%= competition_path(competition) %>" class="competition-Img" target="_blank"> <a href="<%= competition_path(competition) %>" class="competition-Img" target="_blank">
@ -67,6 +68,23 @@
</p> </p>
</div> </div>
</div> </div>
<% elsif competition.published_at.present? %>
<div class="competitionsList-item mb20">
<div class="edu-back-white">
<a href="javascript:void(0)" class="competition-Img">
<%= image_tag(url_to_avatar(competition), :width => "100%", :height => "100%") %>
</a>
<div class="pt20 pl20 mb10 clearfix">
<a href="javascript:void(0)" style="max-width: 400px;" class="font-16 task-hide fl"><%= [competition.name, competition.sub_title.presence].compact.join('——') %></a>
<div class="fr status-orange">
<img src="/images/educoder/competition/home/orange.png" class="fl">
<span class="status-tag fl">即将发布</span>
</div>
</div>
<p class="color-grey-B3 clearfix pl20 pr20 pb20"></p>
</div>
</div>
<% end %>
<% end %> <% end %>
</div> </div>
<% else %> <% else %>

@ -0,0 +1 @@
notice_box_redirect('<%= competition_managements_path %>', '发布成功')

@ -65,6 +65,10 @@
<a href="javascript:void(0)" class="mr10 none" onclick="cancel_edit(this)">取消</a> <a href="javascript:void(0)" class="mr10 none" onclick="cancel_edit(this)">取消</a>
<a href="javascript:void(0)" class="mr10 none" onclick="update_competition(<%= competition.id %>)">保存</a> <a href="javascript:void(0)" class="mr10 none" onclick="update_competition(<%= competition.id %>)">保存</a>
<a id="competition_status_<%= competition.id %>" data-remote="true" href="<%= online_switch_competition_path(competition) %>" class="mr10"><%= competition.status ? "下架" : "上架" %></a> <a id="competition_status_<%= competition.id %>" data-remote="true" href="<%= online_switch_competition_path(competition) %>" class="mr10"><%= competition.status ? "下架" : "上架" %></a>
<% if !competition.status? && competition.published_at.blank? %>
<%= link_to '发布', publish_competition_path(competition), class: 'mr10', method: :post, remote: true %>
<% end %>
</td> </td>
</tr> </tr>
<% end %> <% end %>

@ -78,12 +78,24 @@
<div class="competition-staff-settings mb10 ml30"> <div class="competition-staff-settings mb10 ml30">
<% @competition.competition_staffs.each do |staff| %> <% @competition.competition_staffs.each do |staff| %>
<div class="competition-staff-row mb10"> <div class="competition-staff-row mb10">
<%= select_tag('competition_staffs[][category]', options_for_select(CompetitionStaff.category_options, staff.category), class: 'winput-120-30') %> <div class="fl">
<input type="text" autocomplete="off" class="Other_boxinput" name="competition_staffs[][minimum]" value="<%= staff.minimum %>"/> <%= select_tag('competition_staffs[][category]', options_for_select(CompetitionStaff.category_options, staff.category), class: 'winput-120-30') %>
&nbsp;&nbsp;~&nbsp;&nbsp; <input type="text" autocomplete="off" class="Other_boxinput" name="competition_staffs[][minimum]" value="<%= staff.minimum %>"/>
<input type="text" autocomplete="off" class="Other_boxinput" name="competition_staffs[][maximum]" value="<%= staff.maximum %>"/> &nbsp;&nbsp;~&nbsp;&nbsp;
<input type="text" autocomplete="off" class="Other_boxinput" name="competition_staffs[][maximum]" value="<%= staff.maximum %>"/>
<span class="competition-staff-operate ml10">
</div>
<div class="radio-check fl mt10 ml20" style="width: 120px;">
<input <%= staff.mutiple_limited? ? '' : 'checked="checked"' %> name="competition_staffs[][mutiple_limited]" class="mutiple-limited-radio" type="checkbox" value="false">
<label class="mr20">可多次报名</label>
</div>
<div class="radio-check fl mt10" style="width: 120px;">
<input <%= staff.mutiple_limited? ? 'checked="checked"' : '' %> name="competition_staffs[][mutiple_limited]" class="mutiple-limited-radio" type="checkbox" value="true">
<label class="mr20">仅一次报名</label>
</div>
<span class="competition-staff-operate fl ml10">
<i class="fa fa-trash-o ml5 font-16 delete-icon"></i> <i class="fa fa-trash-o ml5 font-16 delete-icon"></i>
<i class="fa fa-plus-circle color-green font-16 ml10 add-icon"></i> <i class="fa fa-plus-circle color-green font-16 ml10 add-icon"></i>
</span> </span>
@ -167,15 +179,27 @@
<div class="competition-staff-row-example" style="display: none"> <div class="competition-staff-row-example" style="display: none">
<div class="competition-staff-row mb10"> <div class="competition-staff-row mb10">
<%= select_tag('competition_staffs[][category]', options_for_select(CompetitionStaff.category_options, ''), class: 'winput-120-30') %> <div class="fl">
<input type="text" autocomplete="off" class="Other_boxinput" name="competition_staffs[][minimum]" value="1"/> <%= select_tag('competition_staffs[][category]', options_for_select(CompetitionStaff.category_options, ''), class: 'winput-120-30') %>
&nbsp;&nbsp;~&nbsp;&nbsp; <input type="text" autocomplete="off" class="Other_boxinput" name="competition_staffs[][minimum]" value="1"/>
<input type="text" autocomplete="off" class="Other_boxinput" name="competition_staffs[][maximum]" value="1"/> &nbsp;&nbsp;~&nbsp;&nbsp;
<input type="text" autocomplete="off" class="Other_boxinput" name="competition_staffs[][maximum]" value="1"/>
<span class="competition-staff-operate ml10">
<i class="fa fa-trash-o ml5 font-16 delete-icon"></i> </div>
<i class="fa fa-plus-circle color-green font-16 ml10 add-icon"></i>
</span> <div class="radio-check fl mt10 ml20" style="width: 120px;">
<input checked="checked" name="competition_staffs[][mutiple_limited]" class="mutiple-limited-radio" type="checkbox" value="false">
<label class="mr20">可多次报名</label>
</div>
<div class="radio-check fl mt10" style="width: 120px;">
<input name="competition_staffs[][mutiple_limited]" type="checkbox" class="mutiple-limited-radio" value="true">
<label class="mr20">仅一次报名</label>
</div>
<span class="competition-staff-operate fl ml10">
<i class="fa fa-trash-o ml5 font-16 delete-icon"></i>
<i class="fa fa-plus-circle color-green font-16 ml10 add-icon"></i>
</span>
</div> </div>
</div> </div>
@ -546,5 +570,14 @@
$('.competition-staff-settings').on('click', '.delete-icon', function(){ $('.competition-staff-settings').on('click', '.delete-icon', function(){
$(this).parents('.competition-staff-row').remove(); $(this).parents('.competition-staff-row').remove();
}); });
$('.competition-staff-settings').on('click', '.mutiple-limited-radio', function(){
var radio = $(this);
if (radio.is(':checked')) {
radio.parent().siblings().find('.mutiple-limited-radio').attr('checked', false)
} else {
radio.parent().siblings().find('.mutiple-limited-radio').attr('checked', true)
}
})
}) })
</script> </script>

@ -3,8 +3,8 @@
<div class="task_popup_con"> <div class="task_popup_con">
<div class="clearfix mb10 bor-bottom-greyE pb10"> <div class="clearfix mb10 bor-bottom-greyE pb10">
<p class="fl mt5"> <p class="fl mt5">
<%= link_to @shixun.owner.try(:show_real_name), user_path(@shixun.owner), :class => "color-grey3 fl", :target => "_blank" %> <%#= link_to @shixun.owner.try(:show_real_name), user_path(@shixun.owner), :class => "color-grey3 fl", :target => "_blank" %>
<span class="fl mr5 ml3">/</span> <!-- <span class="fl mr5 ml3">/</span>-->
<%= link_to @shixun.name, shixun_path(@shixun), :class => "edu-info-dark fl task-hide",:style=>"max-width:300px", :target => "_blank" %> <%= link_to @shixun.name, shixun_path(@shixun), :class => "edu-info-dark fl task-hide",:style=>"max-width:300px", :target => "_blank" %>
</p> </p>
<% if User.current.has_teacher_role(@homework.course) || User.current.admin? || @work.user == User.current %> <% if User.current.has_teacher_role(@homework.course) || User.current.admin? || @work.user == User.current %>

@ -260,6 +260,7 @@ RedmineApp::Application.routes.draw do ## oauth相关
get 'send_message' get 'send_message'
get 'export_chart_score' get 'export_chart_score'
post 'competition_images' post 'competition_images'
post 'publish'
end end
collection do collection do
post 'new_competition' post 'new_competition'

@ -0,0 +1,5 @@
class AddMultipleLimitedToCompetitionStaffs < ActiveRecord::Migration
def change
add_column :competition_staffs, :mutiple_limited, :boolean, default: false
end
end

@ -0,0 +1,5 @@
class AddPublishedAtToCompetitions < ActiveRecord::Migration
def change
add_column :competitions, :published_at, :datetime
end
end

@ -0,0 +1,35 @@
#coding=utf-8
namespace :competition_notice do
require 'simple_xlsx_reader'
task :send_message => :environment do
puts "--------------------------------competition_notice send_message start"
attachment = Attachment.where(id: 375091).first
if attachment.present?
path = attachment.disk_directory
name = attachment.disk_filename
if name.split(".").last == "xlsx"
doc = SimpleXlsxReader.open("files/#{path}/#{name}")
sheet = doc.sheets.first
lists = sheet.rows
lists.each_with_index do |list, index|
if index > 0
puts "--------------------------------user_name:#{list[0]}, user_phone:#{list[1]}"
user_name = list[0]
user_phone = list[1]
if user_name.present? && user_phone.present?
begin
status = Trustie::Sms.send(mobile: user_phone, send_type:'competition_notice' , name: user_name)
rescue => e
puts "--------------------------------发送验证码出错: #{user_name}---#{user_phone}"
end
end
end
end
else
puts "--------------------------------只支持xlsx文件"
end
end
end
end

@ -31,6 +31,8 @@ module Trustie
params['text'] = "" params['text'] = ""
if send_type.nil? if send_type.nil?
params['text'] = "【Edu实训】" + code + "(手机验证码)。如非本人操作,请忽略。" params['text'] = "【Edu实训】" + code + "(手机验证码)。如非本人操作,请忽略。"
elsif send_type == "competition_notice"
params['text'] = "【Edu实训】亲爱的#{name}你参与的全国绿色计算大赛2019于7月1日开始请及时完善信息详戳→http://opengcc.org.cn/"
elsif send_type == "teacher_register" elsif send_type == "teacher_register"
params['text'] = "【Edu实训】亲爱的#{user_name},有新的老师#{name}注册啦,请尽快处理" params['text'] = "【Edu实训】亲爱的#{user_name},有新的老师#{name}注册啦,请尽快处理"
elsif send_type == 'competition_start' elsif send_type == 'competition_start'

@ -711,7 +711,7 @@ li.challenge_box:last-child{
.second_course_2{min-height: 823px;} .second_course_2{min-height: 823px;}
.second_course_3{min-height: 690px;} .second_course_3{min-height: 690px;}
.second_course_4{min-height: 514px;} .second_course_4{min-height: 514px;}
.second_course_5{min-height: 737px;padding-top: 190px;box-sizing: border-box;position: relative} .second_course_5{min-height: 627px;padding-top: 190px;box-sizing: border-box;position: relative}
.second_course_6{min-height: 1225px;} .second_course_6{min-height: 1225px;}
.course_competition_panel{ .course_competition_panel{
margin:30px 40px 40px;border:1px solid #ABDCF1;background: #F1F8FD;justify-content: center;align-items: center;display: -webkit-flex; margin:30px 40px 40px;border:1px solid #ABDCF1;background: #F1F8FD;justify-content: center;align-items: center;display: -webkit-flex;
@ -728,6 +728,47 @@ li.challenge_box:last-child{
width: 360px;height: 70px;background: #2CDAD4;color: #fff!important;font-size: 30px;line-height: 70px;text-align: center; width: 360px;height: 70px;background: #2CDAD4;color: #fff!important;font-size: 30px;line-height: 70px;text-align: center;
margin:0px auto;display: block; margin:0px auto;display: block;
} }
table.tBodyScroll tbody tr td{
padding:6px 5px;box-sizing: border-box;font-size: 16px;color: #05101A;font-weight: normal;
}
table.tBodyScroll tbody {
display:block;
max-height:420px;
overflow-y:auto;
}
.connectTag{
display: inline-block;background: #4CACFF;border-radius: 12px;height: 24px;line-height: 24px;color: #fff;
padding:0px 12px;font-size: 14px;
}
table.tBodyScroll thead,table.tBodyScroll tfoot,table.tBodyScroll tbody tr {
display:table;
width:100%;
table-layout:fixed;
}
table.tBodyScroll thead,table.tBodyScroll tfoot {
width:100%;
}
table.tBodyScroll tfoot tr th{
padding:10px 5px;box-sizing: border-box;border-top: 1px solid #eaeaea;font-weight: normal!important;
}
.lastPart,.tfootLastPart{
width: calc( 100% - 1em )!important;
}
.lastPart tr th:last-child,.tfootLastPart tr th:last-child{position: relative;}
.tfootLastPart tr th:last-child:after{
content: '';width: 1em;height: 100%;position: absolute;right: -1em;top:0px;border-top: 1px solid #eaeaea;
}
.lastPart tr th:last-child:after{
content: '';background: #F5F5F5;width: 1em;height: 100%;position: absolute;right: -1em;top:0px
}
table.tBodyScroll thead th{
background: #F5F5F5;color: #656565;padding:10px 5px;box-sizing: border-box;
}
.modalTitle{display: block;padding: 0px 30px;position: relative;line-height: 20px}
.modalTitle:before{
position: absolute;height: 100%;width: 2px;content: '';background: #4cacff;left: 0px;top: 0px;
}

@ -918,3 +918,53 @@ html>body #ajax-indicator { position: fixed; }
min-width: 1200px; min-width: 1200px;
padding-top: 60px; padding-top: 60px;
} }
/* css3 radio */
.radio-check {
position: relative;
height: 35px;
}
.radio-check > input {
position: absolute;
left: 0;
top: 0;
width: 14px;
height: 14px;
opacity: 0;
z-index: 100;
}
.radio-check > label {
position: absolute;
left: 20px;
line-height: 14px;
top: 0px;
}
.radio-check > label:before {
content: '';
position: absolute;
left: -20px;
top: 0px;
display: inline-block;
width: 14px;
height: 14px;
border-radius: 50%;
border: 1px solid #ddd;
}
.radio-check > label:after {
content: '';
position: absolute;
left: -20px;
top: 0px;
display: inline-block;
width: 8px;
height: 8px;
border-radius: 50%;
margin-top: 4px;
margin-left: 4px;
}
.radio-check input[type='checkbox']:checked + label:before {
border-color: #29BD8B;
}
.radio-check input[type='checkbox']:checked + label:after {
background: #29BD8B;
}

Loading…
Cancel
Save