Merge branch 'dev_aliyun' of https://bdgit.educoder.net/Hjqreturn/educoder into dev_aliyun
@ -0,0 +1,42 @@
|
|||||||
|
.admins-competition-settings-index-page {
|
||||||
|
.competition-mode-container {
|
||||||
|
.row {
|
||||||
|
height: 35px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.des-row {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-control {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
//.mode-input {
|
||||||
|
// input {
|
||||||
|
// width: 40%;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
.col-md-label{
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
flex: 0 0 10%;
|
||||||
|
max-width: 10%;
|
||||||
|
min-width: 30px;
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 15px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.col-md-label-s{
|
||||||
|
-webkit-box-flex: 0;
|
||||||
|
flex: 0 0 30px;
|
||||||
|
padding-right: 15px;
|
||||||
|
padding-left: 15px;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
.setBtn_s{
|
||||||
|
height: 35px;
|
||||||
|
line-height: 5px;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,83 @@
|
|||||||
|
class Admins::CompetitionStagesController < Admins::BaseController
|
||||||
|
|
||||||
|
def create
|
||||||
|
if @competition.competition_stages.exists?(name: params[:stage_name])
|
||||||
|
render_error "已存在同名的阶段"
|
||||||
|
else
|
||||||
|
@competition.competition_stages << CompetitionStage.new(name: params[:stage_name])
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
current_stage.update_attributes!(name: params[:stage_name], score_rate: params[:score_rate])
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
current_stage.destroy!
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_stage_section
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
new_section = CompetitionStageSection.create!(competition_id: current_stage.competition_id, competition_stage_id: current_stage.id,
|
||||||
|
start_time: params[:new_start_time], end_time: params[:new_end_time],
|
||||||
|
entry: params[:entry], mission_count: params[:mission_count], score_source: params[:score_source])
|
||||||
|
unless params[:shixun_identifiers].blank?
|
||||||
|
params[:shixun_identifiers].each do |identifier|
|
||||||
|
new_section.competition_entries << CompetitionEntry.new(competition_stage_id: current_stage.id, shixun_identifier: identifier)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_stage_section
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
section = current_stage.competition_stage_sections.find_by!(id: params[:section_id])
|
||||||
|
if section.present?
|
||||||
|
section_entries = section.competition_entries
|
||||||
|
if !params[:shixun_identifiers]
|
||||||
|
section_entries.destroy_all
|
||||||
|
else
|
||||||
|
if params[:shixun_identifiers].length < section_entries.size
|
||||||
|
section_entries[params[:shixun_identifiers].length, section_entries.size - 1].each(&:destroy)
|
||||||
|
end
|
||||||
|
|
||||||
|
params[:shixun_identifiers].each_with_index do |identifier, index|
|
||||||
|
entry = section_entries[index]
|
||||||
|
if entry.present?
|
||||||
|
entry.update_attributes!(shixun_identifier: identifier)
|
||||||
|
else
|
||||||
|
section.competition_entries << CompetitionEntry.new(competition_stage_id: current_stage.id, shixun_identifier: identifier)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
section.update_attributes!(start_time: params[:new_start_time], end_time: params[:new_end_time],
|
||||||
|
entry: params[:entry], mission_count: params[:mission_count], score_source: params[:score_source])
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy_stage_section
|
||||||
|
section = current_stage.competition_stage_sections.find_by!(id: params[:section_id])
|
||||||
|
section.destroy!
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def calculate_stage_score
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def current_competition
|
||||||
|
@_current_competition ||= Competition.find(params[:competition_id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_stage
|
||||||
|
@_current_stage ||= CompetitionStage.find_by!(competition_id: params[:competition_id], id: params[:stage_id])
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,38 @@
|
|||||||
|
class Weapps::CheckAccountsController < Weapps::BaseController
|
||||||
|
def create
|
||||||
|
params[:type] == 'register' ? check_can_register : check_can_bind
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def check_can_bind
|
||||||
|
if params[:login] =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/
|
||||||
|
user = User.find_by(mail: params[:login])
|
||||||
|
return render_error('该邮箱尚未注册') if user.blank?
|
||||||
|
elsif params[:login] =~ /^1\d{10}$/
|
||||||
|
user = User.find_by(phone: params[:login])
|
||||||
|
return render_error('该手机号尚未注册') if user.blank?
|
||||||
|
else
|
||||||
|
user = User.find_by(login: params[:login])
|
||||||
|
return render_error('该账号尚未注册') if user.blank?
|
||||||
|
end
|
||||||
|
|
||||||
|
return render_error('该账号已经绑定') if user.wechat_open_user.present?
|
||||||
|
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_can_register
|
||||||
|
if params[:login] =~ /^[a-zA-Z0-9]+([._\\]*[a-zA-Z0-9])*@([a-z0-9]+[-a-z0-9]*[a-z0-9]+.){1,63}[a-z0-9]+$/
|
||||||
|
user = User.find_by(mail: params[:login])
|
||||||
|
return render_error('该邮箱已注册') if user.present?
|
||||||
|
elsif params[:login] =~ /^1\d{10}$/
|
||||||
|
user = User.find_by(phone: params[:login])
|
||||||
|
return render_error('该手机号已注册') if user.present?
|
||||||
|
else
|
||||||
|
return render_error('请输入正确的邮箱或手机号')
|
||||||
|
end
|
||||||
|
|
||||||
|
render_ok
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,2 @@
|
|||||||
|
module LimitForbidControl
|
||||||
|
end
|
@ -0,0 +1,56 @@
|
|||||||
|
class LimitForbidControl::Base
|
||||||
|
def initialize
|
||||||
|
end
|
||||||
|
|
||||||
|
def cache_key
|
||||||
|
raise 'Please overwrite method :cache_Key'
|
||||||
|
end
|
||||||
|
|
||||||
|
def forbid_cache_key
|
||||||
|
"#{cache_key}:forbid"
|
||||||
|
end
|
||||||
|
|
||||||
|
def allow_times
|
||||||
|
5
|
||||||
|
end
|
||||||
|
|
||||||
|
def cumulative_expires
|
||||||
|
1.days
|
||||||
|
end
|
||||||
|
|
||||||
|
def forbid_expires
|
||||||
|
1.hours
|
||||||
|
end
|
||||||
|
|
||||||
|
def forbid?
|
||||||
|
Rails.cache.read(forbid_cache_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
def increment!
|
||||||
|
value = Rails.cache.read(cache_key)
|
||||||
|
value = value.to_i + 1
|
||||||
|
|
||||||
|
# 锁定
|
||||||
|
if value >= allow_times.to_i
|
||||||
|
Rails.cache.write(forbid_cache_key, true, expires_in: forbid_expires)
|
||||||
|
Rails.cache.delete(cache_key)
|
||||||
|
else
|
||||||
|
Rails.cache.write(cache_key, value, expires_in: cumulative_expires)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def clear
|
||||||
|
Rails.cache.delete(forbid_cache_key)
|
||||||
|
Rails.cache.delete(cache_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def redis_cache?
|
||||||
|
Rails.cache.is_a?(ActiveSupport::Cache::RedisStore)
|
||||||
|
end
|
||||||
|
|
||||||
|
def day
|
||||||
|
Time.current.strftime('%Y%m%d')
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,25 @@
|
|||||||
|
class LimitForbidControl::SendEmailCode < LimitForbidControl::Base
|
||||||
|
attr_reader :email
|
||||||
|
|
||||||
|
def initialize(email)
|
||||||
|
super()
|
||||||
|
@email = email
|
||||||
|
end
|
||||||
|
|
||||||
|
def allow_times
|
||||||
|
EduSetting.get('daily_send_email_code_times').presence || 5
|
||||||
|
end
|
||||||
|
|
||||||
|
def forbid_expires
|
||||||
|
num = EduSetting.get('daily_send_email_code_forbid_time').presence.to_i
|
||||||
|
num.zero? ? 10.minutes : num.to_i.hours
|
||||||
|
end
|
||||||
|
|
||||||
|
def cumulative_expires
|
||||||
|
1.hours
|
||||||
|
end
|
||||||
|
|
||||||
|
def cache_key
|
||||||
|
@_cache_key ||= "limit_forbid_control:#{day}:send_email_code:#{email}"
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,25 @@
|
|||||||
|
class LimitForbidControl::UserLogin < LimitForbidControl::Base
|
||||||
|
attr_reader :user
|
||||||
|
|
||||||
|
def initialize(user)
|
||||||
|
super()
|
||||||
|
@user = user
|
||||||
|
end
|
||||||
|
|
||||||
|
def allow_times
|
||||||
|
EduSetting.get('daily_error_password_times').presence || 5
|
||||||
|
end
|
||||||
|
|
||||||
|
def forbid_expires
|
||||||
|
num = EduSetting.get('daily_error_password_forbid_time').presence.to_i
|
||||||
|
num.zero? ? 1.hours : num.to_i.hours
|
||||||
|
end
|
||||||
|
|
||||||
|
def cumulative_expires
|
||||||
|
1.days
|
||||||
|
end
|
||||||
|
|
||||||
|
def cache_key
|
||||||
|
@_cache_key ||= "limit_forbid_control:#{day}:user_login:#{user.id}"
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,39 @@
|
|||||||
|
class Admins::CompetitionBasicSettingService < ApplicationService
|
||||||
|
attr_reader :competition, :params
|
||||||
|
|
||||||
|
def initialize(competition, params)
|
||||||
|
@params = params
|
||||||
|
@competition = competition
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
competition.name = strip params[:name]
|
||||||
|
competition.sub_title = strip params[:sub_title]
|
||||||
|
competition.start_time = params[:start_time]
|
||||||
|
competition.end_time = params[:end_time]
|
||||||
|
competition.mode = params[:mode]
|
||||||
|
competition.identifier = strip params[:identifier]
|
||||||
|
competition.bonus = params[:bonus]
|
||||||
|
competition.awards_count = params[:awards_count]
|
||||||
|
competition.description = strip params[:description]
|
||||||
|
|
||||||
|
competition.save!
|
||||||
|
|
||||||
|
if competition.mode == 1 || competition.mode == 4
|
||||||
|
competition.competition_mode_setting.destroy
|
||||||
|
else
|
||||||
|
setting = competition.competition_mode_setting || CompetitionModeSetting.create!(competition_id: competition.id)
|
||||||
|
if competition.mode == 2
|
||||||
|
setting.course_id = params[:course_id]
|
||||||
|
elsif competition.mode == 3
|
||||||
|
setting.start_time = params[:teach_start_time]
|
||||||
|
setting.end_time = params[:teach_end_time]
|
||||||
|
end
|
||||||
|
setting.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
competition
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,36 @@
|
|||||||
|
class Admins::CompetitionNavSettingService < ApplicationService
|
||||||
|
attr_reader :competition, :params
|
||||||
|
|
||||||
|
def initialize(competition, params)
|
||||||
|
@params = params
|
||||||
|
@competition = competition
|
||||||
|
end
|
||||||
|
|
||||||
|
def call
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
competition.competition_modules.where(module_type: 'md').destroy_all
|
||||||
|
|
||||||
|
# hidden_module_type = competition.all_module_types - params[:module_type]
|
||||||
|
# competition.competition_modules.where(module_type: hidden_module_type).update_all(hidden: 1)
|
||||||
|
|
||||||
|
params[:nav_module].each do |nav|
|
||||||
|
module_type = nav["module_type"]
|
||||||
|
if competition.all_module_types.include?(module_type)
|
||||||
|
com_module = competition.competition_modules.find_by(module_type: module_type)
|
||||||
|
else
|
||||||
|
com_module = CompetitionModule.create!(competition_id: competition.id, module_type: 'md')
|
||||||
|
end
|
||||||
|
com_module.update_attributes!(hidden: nav["hidden"] ? 0 : 1, position: nav["position"], name: nav["name"], url: nav["url"])
|
||||||
|
end
|
||||||
|
|
||||||
|
if params[:competition_staffs].present?
|
||||||
|
competition.competition_staffs.delete_all
|
||||||
|
params[:competition_staffs].each_with_index do |staff_params, index|
|
||||||
|
competition.competition_staffs.create!(staff_params.merge(position: index + 1))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
competition
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,284 @@
|
|||||||
|
<%
|
||||||
|
define_admin_breadcrumbs do
|
||||||
|
add_admin_breadcrumb('竞赛列表', admins_competitions_path)
|
||||||
|
add_admin_breadcrumb(@competition.name)
|
||||||
|
end
|
||||||
|
%>
|
||||||
|
|
||||||
|
<div class="card mb-5">
|
||||||
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
|
<span class="flex-1">基础设置</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body row">
|
||||||
|
<%= form_tag(basic_setting_admins_competition_competition_settings_path(@competition), method: :post, class: 'basic-setting-form flex-1', remote: true) do %>
|
||||||
|
<div class="container competition-mode-container">
|
||||||
|
<div class="row align-items-center mb-1">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
主标题
|
||||||
|
</div>
|
||||||
|
<div class="col-5 text-left">
|
||||||
|
<%= text_field_tag(:name, @competition.name, autocomplete: 'off', class: 'form-control', placeholder: '竞赛标题') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row align-items-center mb-1">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
副标题
|
||||||
|
</div>
|
||||||
|
<div class="col-5 text-left">
|
||||||
|
<%= text_field_tag(:sub_title, @competition.sub_title, autocomplete: 'off', class: 'form-control', placeholder: '竞赛副标题') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row align-items-center mb-1">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
起止时间
|
||||||
|
</div>
|
||||||
|
<div class="col-5 competition-start-end-date d-flex">
|
||||||
|
<%= text_field_tag :start_time, @competition.start_time&.strftime('%Y-%m-%d'), autocomplete: 'off', class: 'form-control start-date mx-0 mr-2', placeholder: '竞赛开始时间' %>
|
||||||
|
<%= text_field_tag :end_time, @competition.end_time&.strftime('%Y-%m-%d'), autocomplete: 'off', class: 'form-control end-date mx-0', placeholder: '竞赛截止时间' %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row align-items-center mb-1">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
竞赛模式
|
||||||
|
</div>
|
||||||
|
<div class="col-5 text-left">
|
||||||
|
<%= radio_button_tag(:mode, 1, @competition.mode == 1, class: 'form-radio-input') %>
|
||||||
|
<label class="form-radio-label mb-0" for="mode_1">实训模式(参赛者报名参赛,挑战实训,系统评审)</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row align-items-center mb-1">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
</div>
|
||||||
|
<div class="col-5 text-left">
|
||||||
|
<%= radio_button_tag(:mode, 2, @competition.mode == 2, class: 'form-radio-input') %>
|
||||||
|
<label class="form-radio-label mb-0" for="mode_2">课堂模式(参赛者加入课堂,提交作品,评委评审)</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6">
|
||||||
|
<%= text_field_tag(:course_id, @competition.competition_mode_setting&.course_id, autocomplete: 'off', class: 'form-control', placeholder: '课堂id') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row align-items-center mb-1">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
</div>
|
||||||
|
<div class="col-5 text-left">
|
||||||
|
<%= radio_button_tag(:mode, 3, @competition.mode == 3, class: 'form-radio-input') %>
|
||||||
|
<label class="form-radio-label mb-0" for="mode_3">教学模式(参赛者报名参赛,统计战队课堂和实训数据)</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-6 teaching-mode-date d-flex">
|
||||||
|
<%= text_field_tag :teach_start_time, @competition.competition_mode_setting&.start_time, autocomplete: 'off', class: 'form-control start-date mx-0 mr-2', placeholder: '统计数据的开始时间' %>
|
||||||
|
<%= text_field_tag :teach_end_time, @competition.competition_mode_setting&.end_time, autocomplete: 'off', class: 'form-control end-date mx-0', placeholder: '统计数据的结束时间' %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row align-items-center mb-2">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
</div>
|
||||||
|
<div class="col-5 text-left">
|
||||||
|
<%= radio_button_tag(:mode, 4, @competition.mode == 4, class: 'form-radio-input') %>
|
||||||
|
<label class="form-radio-label mb-0" for="mode_4">托管模式(参赛者报名参赛,在其他平台完成任务)</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row align-items-center mb-2">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
URL
|
||||||
|
</div>
|
||||||
|
<div class="col-5 text-left mode-input">
|
||||||
|
<%= text_field_tag(:identifier, @competition.identifier, autocomplete: 'off', class: 'form-control', placeholder: '请输入url赛事网址') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row align-items-center mb-2">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
主办方
|
||||||
|
</div>
|
||||||
|
<div class="col-5 text-left">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row align-items-center mb-2">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
奖金
|
||||||
|
</div>
|
||||||
|
<div class="col-5 text-left input-group">
|
||||||
|
<div class="input-group-prepend">
|
||||||
|
<div class="input-group-text">¥</div>
|
||||||
|
</div>
|
||||||
|
<%= number_field_tag(:bonus, @competition.bonus, autocomplete: 'off', step: 1, min: 0, class: 'form-control', placeholder: '请输入总奖金额') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row align-items-center mb-2">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
奖项数
|
||||||
|
</div>
|
||||||
|
<div class="col-5 text-left">
|
||||||
|
<%= number_field_tag(:awards_count, @competition.awards_count, autocomplete: 'off', step: 1, min: 0, class: 'form-control', placeholder: '请输入奖项数') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row des-row align-items-center mb-2">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
描述
|
||||||
|
</div>
|
||||||
|
<div class="col-11 text-left">
|
||||||
|
<%= text_area_tag(:description, @competition.description, class: 'form-control', placeholder: '请输入赛事简介') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="error my-2 danger text-danger"></div>
|
||||||
|
|
||||||
|
<div class="row des-row align-items-center mb-2">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
</div>
|
||||||
|
<div class="col-5 text-left">
|
||||||
|
<%= javascript_void_link '保存', class: 'btn btn-primary submit-btn' %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="card mb-5">
|
||||||
|
<div class="card-header d-flex justify-content-between align-items-center">
|
||||||
|
<span class="flex-1">导航设置</span>
|
||||||
|
</div>
|
||||||
|
<div class="card-body row">
|
||||||
|
<div class="container competition-mode-container">
|
||||||
|
<% @competition.competition_modules.each do |com_module| %>
|
||||||
|
<% case com_module.module_type %>
|
||||||
|
<% when 'home' %>
|
||||||
|
<div id="MD_typeFrom">
|
||||||
|
<div class="row MD_type">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
<label class="checkbox checkbox-primary mt-1">
|
||||||
|
<%= check_box_tag('navbar[][hidden]', 0, !com_module.hidden, id: nil, class: 'font-16') %>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-4">
|
||||||
|
<%= text_field_tag('navbar[][name]', com_module.name, id: nil, class: 'form-control', placeholder: '首页') %>
|
||||||
|
<input type="hidden" value="<%= com_module.module_type %>" name="navbar[][module_type]">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-1">
|
||||||
|
<%= text_field_tag('navbar[][position]', com_module.position, id: nil, class: 'form-control', placeholder: '位置') %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
<label class="checkbox checkbox-primary mt-1">
|
||||||
|
<input id="checkbox2" type="checkbox">
|
||||||
|
<label for="checkbox2"> </label>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-8 color-blue mt-1">
|
||||||
|
报名
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-1 text-right"> </div>
|
||||||
|
<div class="col-1 text-left" style="max-width: 120px;flex: 0 0 120px;">
|
||||||
|
报名截止时间
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3"><input type="text" class="form-control" /></div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-1 text-right"> </div>
|
||||||
|
<div class="col-1 text-left mt-1">
|
||||||
|
报名要求
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<button class="btn btn-primary waves-effect waves-light btn-xs setBtn_s" id="addRequireBtn">+</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="requireForm">
|
||||||
|
<div class="row mt-2 mb-4 requireForm_item">
|
||||||
|
<div class="col-1 text-right"> </div>
|
||||||
|
<div class="col-1 text-left mt-1">
|
||||||
|
<input type="text" class="form-control" name="min_1" />
|
||||||
|
</div>
|
||||||
|
<span class="mt-2">~</span>
|
||||||
|
<div class="col-1 mt-1">
|
||||||
|
<input type="text" class="form-control" name="max_1" />
|
||||||
|
</div>
|
||||||
|
<span class="mt-2">人</span>
|
||||||
|
<div class="col-2 mt-1">
|
||||||
|
<select class="form-control" name="choice_1" >
|
||||||
|
<option>不限</option>
|
||||||
|
<option>教师</option>
|
||||||
|
<option>学生</option>
|
||||||
|
<option>专业人士</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
<div class="col-2 mt-1">
|
||||||
|
<label class="radio checkbox-primary mt-1" value="require_1_1">
|
||||||
|
<input id="require_1_1" name="require_1" type="radio">
|
||||||
|
<label for="require_1_1">可多次报名</label>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-2 mt-1">
|
||||||
|
<label class="radio checkbox-primary mt-1" value="require_1_2">
|
||||||
|
<input id="require_1_2" name="require_1" type="radio">
|
||||||
|
<label for="require_1_2">不可多次报名</label>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
<label class="checkbox checkbox-primary mt-1">
|
||||||
|
<input id="checkbox2" type="checkbox">
|
||||||
|
<label for="checkbox2"> </label>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-label mt-2">排行榜</div>
|
||||||
|
<div class="col-md-1 mt-1"><input type="text" class="form-control"></div>
|
||||||
|
</div>
|
||||||
|
<div id="linkForm">
|
||||||
|
<div class="row mt-2 linkFormItem">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
<label class="checkbox checkbox-primary mt-1">
|
||||||
|
<input id="link_1" type="checkbox" name="link_1" />
|
||||||
|
<label for="link_1"> </label>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-label mt-2">资料下载</div>
|
||||||
|
<div class="col-md-1 mt-1"><input type="text" name="link_index_1" class="form-control"></div>
|
||||||
|
<div class="col-md-3 mt-1"><input type="text" name="link_info_1" class="form-control"></div>
|
||||||
|
<button class="mt-1 btn btn-primary waves-effect waves-light btn-xs setBtn_s add_linkBtn">+</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="row mt-2">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
<label class="checkbox checkbox-primary mt-1">
|
||||||
|
<input id="checkbox2" type="checkbox">
|
||||||
|
<label for="checkbox2"> </label>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-label mt-2">获奖证书</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row mt-2 mb-4">
|
||||||
|
<div class="col-1 text-right">
|
||||||
|
</div>
|
||||||
|
<div class="col-md-label mt-2"><%= javascript_void_link '保存', class: 'btn btn-primary submit-btn' %></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
@ -1,16 +0,0 @@
|
|||||||
<%
|
|
||||||
define_admin_breadcrumbs do
|
|
||||||
add_admin_breadcrumb('竞赛列表', admins_competitions_path)
|
|
||||||
add_admin_breadcrumb(@competition.name)
|
|
||||||
end
|
|
||||||
%>
|
|
||||||
|
|
||||||
<div class="card mb-5">
|
|
||||||
<div class="card-header d-flex justify-content-between align-items-center">
|
|
||||||
<span class="flex-1">基础设置</span>
|
|
||||||
</div>
|
|
||||||
<div class="card-body row">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
|||||||
|
wb = xlsx_package.workbook
|
||||||
|
wb.add_worksheet(name: '报名列表') do |sheet|
|
||||||
|
sheet.add_row %w(序号 战队ID 战队名称 创建者 指导老师 队员姓名 职业 手机号 邮箱 学号 实名认证 职业认证 队员学校 地区 报名时间 排名)
|
||||||
|
|
||||||
|
@enroll_lists.each_with_index do |member, index|
|
||||||
|
team = member.competition_team
|
||||||
|
member_user = member.user
|
||||||
|
rank = @competition_scores.length > 0 ? @competition_scores.index(member.competition_team_id).to_i + 1 : "--"
|
||||||
|
data = [
|
||||||
|
index + 1,
|
||||||
|
member.competition_team_id,
|
||||||
|
@personal ? "--" : team.name,
|
||||||
|
team.user.real_name,
|
||||||
|
@personal ? "--" : team.teachers_info,
|
||||||
|
member_user.real_name,
|
||||||
|
member_user.identity,
|
||||||
|
member_user.phone,
|
||||||
|
member_user.mail,
|
||||||
|
member_user.student_id,
|
||||||
|
member_user.authentication ? "√" : "",
|
||||||
|
member_user.professional_certification ? "√" : "",
|
||||||
|
member_user.school_name,
|
||||||
|
member_user.school_province,
|
||||||
|
member.created_at.strftime('%Y-%m-%d %H:%M'),
|
||||||
|
rank
|
||||||
|
]
|
||||||
|
sheet.add_row(data)
|
||||||
|
end
|
||||||
|
end
|
@ -1 +1 @@
|
|||||||
json.content content
|
json.content content_safe(content)
|
@ -1,6 +1,6 @@
|
|||||||
json.partial! "messages/message_simple", message: message
|
json.partial! "messages/message_simple", message: message
|
||||||
json.partial! "commons/like", message: message
|
json.partial! "commons/like", message: message
|
||||||
json.content message.message_detail.try(:content)
|
json.content content_safe(message.message_detail.try(:content))
|
||||||
json.author do
|
json.author do
|
||||||
json.partial! "users/user_simple", user: message.author
|
json.partial! "users/user_simple", user: message.author
|
||||||
end
|
end
|
@ -0,0 +1,3 @@
|
|||||||
|
json.user do
|
||||||
|
json.partial! 'weapps/shared/user', locals: { user: current_user }
|
||||||
|
end
|
@ -0,0 +1,3 @@
|
|||||||
|
json.user do
|
||||||
|
json.partial! 'weapps/shared/user', locals: { user: current_user }
|
||||||
|
end
|
@ -0,0 +1,14 @@
|
|||||||
|
json.username user.full_name
|
||||||
|
json.real_name user.real_name
|
||||||
|
json.login user.login
|
||||||
|
json.user_id user.id
|
||||||
|
json.image_url url_to_avatar(user)
|
||||||
|
json.admin user.admin?
|
||||||
|
json.business user.business?
|
||||||
|
json.is_teacher user.user_extension&.teacher?
|
||||||
|
json.user_identity user.identity
|
||||||
|
json.tidding_count 0
|
||||||
|
json.user_phone_binded user.phone.present?
|
||||||
|
json.phone user.phone
|
||||||
|
json.profile_completed user.profile_completed?
|
||||||
|
json.professional_certification user.professional_certification
|
@ -0,0 +1,418 @@
|
|||||||
|
/*!
|
||||||
|
* Datetimepicker for Bootstrap
|
||||||
|
*
|
||||||
|
* Copyright 2012 Stefan Petre
|
||||||
|
* Improvements by Andrew Rowls
|
||||||
|
* Licensed under the Apache License v2.0
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
.datetimepicker {
|
||||||
|
padding: 4px;
|
||||||
|
margin-top: 1px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
direction: ltr;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-inline {
|
||||||
|
width: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.datetimepicker-rtl {
|
||||||
|
direction: rtl;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.datetimepicker-rtl table tr td span {
|
||||||
|
float: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown, .datetimepicker-dropdown-left {
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=" datetimepicker-dropdown"]:before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
border-left: 7px solid transparent;
|
||||||
|
border-right: 7px solid transparent;
|
||||||
|
border-bottom: 7px solid #cccccc;
|
||||||
|
border-bottom-color: rgba(0, 0, 0, 0.2);
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=" datetimepicker-dropdown"]:after {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-bottom: 6px solid #ffffff;
|
||||||
|
position: absolute;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=" datetimepicker-dropdown-top"]:before {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
border-left: 7px solid transparent;
|
||||||
|
border-right: 7px solid transparent;
|
||||||
|
border-top: 7px solid #cccccc;
|
||||||
|
border-top-color: rgba(0, 0, 0, 0.2);
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
[class*=" datetimepicker-dropdown-top"]:after {
|
||||||
|
content: '';
|
||||||
|
display: inline-block;
|
||||||
|
border-left: 6px solid transparent;
|
||||||
|
border-right: 6px solid transparent;
|
||||||
|
border-top: 6px solid #ffffff;
|
||||||
|
border-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-bottom-left:before {
|
||||||
|
top: -7px;
|
||||||
|
right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-bottom-left:after {
|
||||||
|
top: -6px;
|
||||||
|
right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-bottom-right:before {
|
||||||
|
top: -7px;
|
||||||
|
left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-bottom-right:after {
|
||||||
|
top: -6px;
|
||||||
|
left: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-top-left:before {
|
||||||
|
bottom: -7px;
|
||||||
|
right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-top-left:after {
|
||||||
|
bottom: -6px;
|
||||||
|
right: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-top-right:before {
|
||||||
|
bottom: -7px;
|
||||||
|
left: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker-dropdown-top-right:after {
|
||||||
|
bottom: -6px;
|
||||||
|
left: 7px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker > div {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.minutes div.datetimepicker-minutes {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.hours div.datetimepicker-hours {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.days div.datetimepicker-days {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.months div.datetimepicker-months {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker.years div.datetimepicker-years {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker td,
|
||||||
|
.datetimepicker th {
|
||||||
|
text-align: center;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.table-striped .datetimepicker table tr td,
|
||||||
|
.table-striped .datetimepicker table tr th {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.minute:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.hour:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.day:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.old,
|
||||||
|
.datetimepicker table tr td.new {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.disabled,
|
||||||
|
.datetimepicker table tr td.disabled:hover {
|
||||||
|
background: none;
|
||||||
|
color: #999999;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.today,
|
||||||
|
.datetimepicker table tr td.today:hover,
|
||||||
|
.datetimepicker table tr td.today.disabled,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover {
|
||||||
|
background-color: #fde19a;
|
||||||
|
background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a));
|
||||||
|
background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: -o-linear-gradient(top, #fdd49a, #fdf59a);
|
||||||
|
background-image: linear-gradient(to bottom, #fdd49a, #fdf59a);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0);
|
||||||
|
border-color: #fdf59a #fdf59a #fbed50;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.today:hover,
|
||||||
|
.datetimepicker table tr td.today:hover:hover,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover:hover,
|
||||||
|
.datetimepicker table tr td.today:active,
|
||||||
|
.datetimepicker table tr td.today:hover:active,
|
||||||
|
.datetimepicker table tr td.today.disabled:active,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td.today.active,
|
||||||
|
.datetimepicker table tr td.today:hover.active,
|
||||||
|
.datetimepicker table tr td.today.disabled.active,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover.active,
|
||||||
|
.datetimepicker table tr td.today.disabled,
|
||||||
|
.datetimepicker table tr td.today:hover.disabled,
|
||||||
|
.datetimepicker table tr td.today.disabled.disabled,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover.disabled,
|
||||||
|
.datetimepicker table tr td.today[disabled],
|
||||||
|
.datetimepicker table tr td.today:hover[disabled],
|
||||||
|
.datetimepicker table tr td.today.disabled[disabled],
|
||||||
|
.datetimepicker table tr td.today.disabled:hover[disabled] {
|
||||||
|
background-color: #fdf59a;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.today:active,
|
||||||
|
.datetimepicker table tr td.today:hover:active,
|
||||||
|
.datetimepicker table tr td.today.disabled:active,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td.today.active,
|
||||||
|
.datetimepicker table tr td.today:hover.active,
|
||||||
|
.datetimepicker table tr td.today.disabled.active,
|
||||||
|
.datetimepicker table tr td.today.disabled:hover.active {
|
||||||
|
background-color: #fbf069;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.active,
|
||||||
|
.datetimepicker table tr td.active:hover,
|
||||||
|
.datetimepicker table tr td.active.disabled,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover {
|
||||||
|
background-color: #006dcc;
|
||||||
|
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||||
|
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: linear-gradient(to bottom, #0088cc, #0044cc);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||||
|
border-color: #0044cc #0044cc #002a80;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||||
|
color: #ffffff;
|
||||||
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.active:hover,
|
||||||
|
.datetimepicker table tr td.active:hover:hover,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover:hover,
|
||||||
|
.datetimepicker table tr td.active:active,
|
||||||
|
.datetimepicker table tr td.active:hover:active,
|
||||||
|
.datetimepicker table tr td.active.disabled:active,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td.active.active,
|
||||||
|
.datetimepicker table tr td.active:hover.active,
|
||||||
|
.datetimepicker table tr td.active.disabled.active,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover.active,
|
||||||
|
.datetimepicker table tr td.active.disabled,
|
||||||
|
.datetimepicker table tr td.active:hover.disabled,
|
||||||
|
.datetimepicker table tr td.active.disabled.disabled,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover.disabled,
|
||||||
|
.datetimepicker table tr td.active[disabled],
|
||||||
|
.datetimepicker table tr td.active:hover[disabled],
|
||||||
|
.datetimepicker table tr td.active.disabled[disabled],
|
||||||
|
.datetimepicker table tr td.active.disabled:hover[disabled] {
|
||||||
|
background-color: #0044cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td.active:active,
|
||||||
|
.datetimepicker table tr td.active:hover:active,
|
||||||
|
.datetimepicker table tr td.active.disabled:active,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td.active.active,
|
||||||
|
.datetimepicker table tr td.active:hover.active,
|
||||||
|
.datetimepicker table tr td.active.disabled.active,
|
||||||
|
.datetimepicker table tr td.active.disabled:hover.active {
|
||||||
|
background-color: #003399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span {
|
||||||
|
display: block;
|
||||||
|
width: 23%;
|
||||||
|
height: 54px;
|
||||||
|
line-height: 54px;
|
||||||
|
float: left;
|
||||||
|
margin: 1%;
|
||||||
|
cursor: pointer;
|
||||||
|
-webkit-border-radius: 4px;
|
||||||
|
-moz-border-radius: 4px;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker .datetimepicker-hours span {
|
||||||
|
height: 26px;
|
||||||
|
line-height: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker .datetimepicker-hours table tr td span.hour_am,
|
||||||
|
.datetimepicker .datetimepicker-hours table tr td span.hour_pm {
|
||||||
|
width: 14.6%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker .datetimepicker-hours fieldset legend,
|
||||||
|
.datetimepicker .datetimepicker-minutes fieldset legend {
|
||||||
|
margin-bottom: inherit;
|
||||||
|
line-height: 30px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker .datetimepicker-minutes span {
|
||||||
|
height: 26px;
|
||||||
|
line-height: 26px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span.disabled,
|
||||||
|
.datetimepicker table tr td span.disabled:hover {
|
||||||
|
background: none;
|
||||||
|
color: #999999;
|
||||||
|
cursor: default;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span.active,
|
||||||
|
.datetimepicker table tr td span.active:hover,
|
||||||
|
.datetimepicker table tr td span.active.disabled,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover {
|
||||||
|
background-color: #006dcc;
|
||||||
|
background-image: -moz-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -ms-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));
|
||||||
|
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: -o-linear-gradient(top, #0088cc, #0044cc);
|
||||||
|
background-image: linear-gradient(to bottom, #0088cc, #0044cc);
|
||||||
|
background-repeat: repeat-x;
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0);
|
||||||
|
border-color: #0044cc #0044cc #002a80;
|
||||||
|
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);
|
||||||
|
color: #ffffff;
|
||||||
|
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25);
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span.active:hover,
|
||||||
|
.datetimepicker table tr td span.active:hover:hover,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover:hover,
|
||||||
|
.datetimepicker table tr td span.active:active,
|
||||||
|
.datetimepicker table tr td span.active:hover:active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td span.active.active,
|
||||||
|
.datetimepicker table tr td span.active:hover.active,
|
||||||
|
.datetimepicker table tr td span.active.disabled.active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover.active,
|
||||||
|
.datetimepicker table tr td span.active.disabled,
|
||||||
|
.datetimepicker table tr td span.active:hover.disabled,
|
||||||
|
.datetimepicker table tr td span.active.disabled.disabled,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover.disabled,
|
||||||
|
.datetimepicker table tr td span.active[disabled],
|
||||||
|
.datetimepicker table tr td span.active:hover[disabled],
|
||||||
|
.datetimepicker table tr td span.active.disabled[disabled],
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover[disabled] {
|
||||||
|
background-color: #0044cc;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span.active:active,
|
||||||
|
.datetimepicker table tr td span.active:hover:active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover:active,
|
||||||
|
.datetimepicker table tr td span.active.active,
|
||||||
|
.datetimepicker table tr td span.active:hover.active,
|
||||||
|
.datetimepicker table tr td span.active.disabled.active,
|
||||||
|
.datetimepicker table tr td span.active.disabled:hover.active {
|
||||||
|
background-color: #003399;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker table tr td span.old {
|
||||||
|
color: #999999;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker th.switch {
|
||||||
|
width: 145px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker th span.glyphicon {
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker thead tr:first-child th,
|
||||||
|
.datetimepicker tfoot th {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.datetimepicker thead tr:first-child th:hover,
|
||||||
|
.datetimepicker tfoot th:hover {
|
||||||
|
background: #eeeeee;
|
||||||
|
}
|
||||||
|
|
||||||
|
.input-append.date .add-on i,
|
||||||
|
.input-prepend.date .add-on i,
|
||||||
|
.input-group.date .input-group-addon span {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 14px;
|
||||||
|
height: 14px;
|
||||||
|
}
|
@ -0,0 +1,7 @@
|
|||||||
|
class MigrateCompetitionScoreStageId < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
change_column_default :competition_scores, :competition_stage_id, 0
|
||||||
|
|
||||||
|
CompetitionScore.where("competition_stage_id is null").update_all(competition_stage_id: 0)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,6 @@
|
|||||||
|
class MigrateCompetitionModeDefault < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
change_column_default :competitions, :mode, from: 0, to: 1
|
||||||
|
Competition.all.update_all(mode: 1)
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,5 @@
|
|||||||
|
class AddAwardsCountToCompetition < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :competitions, :awards_count, :integer, default: 0
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,28 @@
|
|||||||
|
class MigrateCompetitionModuleType < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
add_column :competition_modules, :module_type, :string
|
||||||
|
|
||||||
|
Competition.all.each do |competition|
|
||||||
|
competition.competition_modules.each do |com_module|
|
||||||
|
mod_type = ""
|
||||||
|
case com_module.name
|
||||||
|
when '首页'
|
||||||
|
mod_type = "home"
|
||||||
|
when '报名'
|
||||||
|
mod_type = "enroll"
|
||||||
|
when '通知公告'
|
||||||
|
mod_type = "inform"
|
||||||
|
when '参赛手册'
|
||||||
|
mod_type = "manual"
|
||||||
|
when '排行榜'
|
||||||
|
mod_type = "chart"
|
||||||
|
when '资料下载 '
|
||||||
|
mod_type = "resource"
|
||||||
|
else
|
||||||
|
mod_type = "md"
|
||||||
|
end
|
||||||
|
com_module.update_attributes!(module_type: mod_type)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -0,0 +1,10 @@
|
|||||||
|
class AddColumnToStageSections < ActiveRecord::Migration[5.2]
|
||||||
|
def change
|
||||||
|
def change
|
||||||
|
add_column :competition_stage_sections, :mission_count, :integer, default: 0
|
||||||
|
add_column :competition_stage_sections, :score_source, :integer, default: 0
|
||||||
|
|
||||||
|
add_column :competition_entries, :shixun_identifier, :string
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
After Width: | Height: | Size: 3.1 KiB |
After Width: | Height: | Size: 4.4 KiB |
Before Width: | Height: | Size: 169 KiB After Width: | Height: | Size: 169 KiB |
After Width: | Height: | Size: 3.2 KiB |
After Width: | Height: | Size: 4.7 KiB |
After Width: | Height: | Size: 3.6 KiB |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 137 KiB |
Before Width: | Height: | Size: 294 KiB After Width: | Height: | Size: 303 KiB |
@ -0,0 +1,50 @@
|
|||||||
|
import React, {Component} from 'react';
|
||||||
|
import {
|
||||||
|
BrowserRouter as Router,
|
||||||
|
Route,
|
||||||
|
Switch
|
||||||
|
} from 'react-router-dom';
|
||||||
|
import axios from 'axios';
|
||||||
|
import moment from 'moment';
|
||||||
|
import competition from './comcss/competition.css';
|
||||||
|
import {Checkbox, Table, Pagination, Menu, Icon} from "antd";
|
||||||
|
import {getImageUrl} from 'educoder';
|
||||||
|
// 团队竞赛报名无报名子组件团队 在线竞赛 > 全国高校计算机大赛-项目挑战>
|
||||||
|
class RegisListview extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<div className="reglistviewdivs">
|
||||||
|
<div className="reglistviewdivss " style={{
|
||||||
|
width: "100%",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: " space-around",
|
||||||
|
alignItems: "center",
|
||||||
|
background: `url(${getImageUrl(`images/educoder/competitions/Rectanglex.png`)})`,
|
||||||
|
height: "50px",
|
||||||
|
backgroundPosition: "center",
|
||||||
|
backgroundSize: "110% 100%",
|
||||||
|
}}>
|
||||||
|
<p className=" "
|
||||||
|
style={{fontSize: "16px", color: "#05101A", width: "79px", textAlign: "center"}}>创建者</p>
|
||||||
|
<p className=" "
|
||||||
|
style={{fontSize: "16px", color: "#05101A", width: "160px", textAlign: "center"}}>战队名称</p>
|
||||||
|
<p className=" "
|
||||||
|
style={{fontSize: "16px", color: "#05101A", width: "487px", textAlign: "center"}}>战队成员</p>
|
||||||
|
<p className=" "
|
||||||
|
style={{fontSize: "16px", color: "#05101A", width: "134px", textAlign: "center"}}>学校</p>
|
||||||
|
<p className=" "
|
||||||
|
style={{fontSize: "16px", color: "#05101A", width: "151px", textAlign: "center"}}>时间</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RegisListview;
|
@ -0,0 +1,144 @@
|
|||||||
|
import React, {Component} from 'react';
|
||||||
|
import {
|
||||||
|
BrowserRouter as Router,
|
||||||
|
Route,
|
||||||
|
Switch
|
||||||
|
} from 'react-router-dom';
|
||||||
|
import axios from 'axios';
|
||||||
|
import moment from 'moment';
|
||||||
|
import {SnackbarHOC, WordsBtn, getImageUrl} from 'educoder';
|
||||||
|
import {TPMIndexHOC} from '../tpm/TPMIndexHOC';
|
||||||
|
import competition from './comcss/competition.css';
|
||||||
|
import {Button} from 'antd';
|
||||||
|
|
||||||
|
// 团队竞赛报名无报名子组件团队 竞赛报名-已创建战队
|
||||||
|
class RegisListviewdata extends React.Component {
|
||||||
|
constructor(props) {
|
||||||
|
super(props)
|
||||||
|
this.state = {
|
||||||
|
item: undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
////console.log("RegisListviewdata");
|
||||||
|
////console.log(this.props.item)
|
||||||
|
this.setState({
|
||||||
|
item: this.props.item
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
||||||
|
render() {
|
||||||
|
const {item} = this.props;
|
||||||
|
return (
|
||||||
|
|
||||||
|
<div>
|
||||||
|
{
|
||||||
|
item !== undefined ?
|
||||||
|
<div className={"yslborderbottom"}>
|
||||||
|
<div className="regitem22">
|
||||||
|
|
||||||
|
<div className="regitemimg1 ">
|
||||||
|
<img className="regitemimg2" src={getImageUrl("images/" + item.creator.image_url)}>
|
||||||
|
|
||||||
|
</img>
|
||||||
|
<p style={{
|
||||||
|
color: "#999999", fontSize: "14px",
|
||||||
|
width: "78px",
|
||||||
|
textAlign: "center"
|
||||||
|
}}>{item.creator.name}</p>
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
marginTop: "29px",
|
||||||
|
marginLeft: "37px"
|
||||||
|
}}>
|
||||||
|
<p className="maxnamewidth160" style={{
|
||||||
|
color: "#05101A",
|
||||||
|
fontSize: "16px",
|
||||||
|
width: "160px",
|
||||||
|
textAlign: "center"
|
||||||
|
}}>{item.name}</p>
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
marginLeft: "37px",
|
||||||
|
display: "flex",
|
||||||
|
flexDirection: "initial",
|
||||||
|
width: "487px"
|
||||||
|
}}>
|
||||||
|
|
||||||
|
{
|
||||||
|
item && item.team_members.map((item, index) => {
|
||||||
|
return (
|
||||||
|
|
||||||
|
index === 0 ?
|
||||||
|
<img className="regitemimgs" src={getImageUrl("images/" + item.image_url)}>
|
||||||
|
|
||||||
|
</img>
|
||||||
|
: index === 1 ?
|
||||||
|
<img className="regitemimgs2" src={getImageUrl("images/" + item.image_url)}>
|
||||||
|
|
||||||
|
</img>
|
||||||
|
: index === 2 ?
|
||||||
|
<img className="regitemimgs2" src={getImageUrl("images/" + item.image_url)}>
|
||||||
|
|
||||||
|
</img>
|
||||||
|
: index === 3 ?
|
||||||
|
<img className="regitemimgs2" src={getImageUrl("images/" + item.image_url)}>
|
||||||
|
|
||||||
|
</img>
|
||||||
|
: index === 4 ?
|
||||||
|
<img className="regitemimgs2" src={getImageUrl("images/" + item.image_url)}>
|
||||||
|
|
||||||
|
</img>
|
||||||
|
: index === 5 ?
|
||||||
|
<div>
|
||||||
|
<img className="regitemimgs2" src={getImageUrl("images/" + item.image_url)}>
|
||||||
|
|
||||||
|
</img>
|
||||||
|
<img className="regitemimgs22"
|
||||||
|
src={getImageUrl(`images/educoder/competitions/pexjiazai.png`)}>
|
||||||
|
</img>
|
||||||
|
</div>
|
||||||
|
: ""
|
||||||
|
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
marginLeft: "41px",
|
||||||
|
width: "134px",
|
||||||
|
marginTop: "29px",
|
||||||
|
}}>
|
||||||
|
<p className="maxnamewidth134" style={{
|
||||||
|
color: "#05101A",
|
||||||
|
fontSize: "16px",
|
||||||
|
textAlign: "center"
|
||||||
|
}}>{item.school_name}</p>
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
marginLeft: "37px",
|
||||||
|
width: "151px",
|
||||||
|
marginTop: "29px",
|
||||||
|
|
||||||
|
}}>
|
||||||
|
<p style={{
|
||||||
|
color: "#999999",
|
||||||
|
fontSize: "16px",
|
||||||
|
textAlign: "center"
|
||||||
|
}}>{item.created_at}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
: ""
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RegisListviewdata;
|